|
@@ -43,18 +43,22 @@
|
|
|
<span class="sort-header" @click.stop="onSortClick('normalRange', $event)">正常范围<span v-if="sortIndex('normalRange') !== null" class="sort-index" :class="sortClass('normalRange') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('normalRange') }}</span>{{ sortIcon('normalRange') }}</span>
|
|
<span class="sort-header" @click.stop="onSortClick('normalRange', $event)">正常范围<span v-if="sortIndex('normalRange') !== null" class="sort-index" :class="sortClass('normalRange') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('normalRange') }}</span>{{ sortIcon('normalRange') }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column prop="description" label="说明" min-width="260" show-overflow-tooltip>
|
|
|
|
|
|
|
+ <el-table-column prop="description" label="说明" min-width="260">
|
|
|
<template slot="header">
|
|
<template slot="header">
|
|
|
<span class="sort-header" @click.stop="onSortClick('description', $event)">说明<span v-if="sortIndex('description') !== null" class="sort-index" :class="sortClass('description') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('description') }}</span>{{ sortIcon('description') }}</span>
|
|
<span class="sort-header" @click.stop="onSortClick('description', $event)">说明<span v-if="sortIndex('description') !== null" class="sort-index" :class="sortClass('description') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('description') }}</span>{{ sortIcon('description') }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
+ <template slot-scope="{ row }">
|
|
|
|
|
+ <span class="desc-ellipsis">{{ (row.description || '').slice(0, 120) }}{{ (row.description || '').length > 120 ? '…' : '' }}</span>
|
|
|
|
|
+ </template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column prop="source" label="来源" width="120" show-overflow-tooltip>
|
|
<el-table-column prop="source" label="来源" width="120" show-overflow-tooltip>
|
|
|
<template slot="header">
|
|
<template slot="header">
|
|
|
<span class="sort-header" @click.stop="onSortClick('source', $event)">来源<span v-if="sortIndex('source') !== null" class="sort-index" :class="sortClass('source') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('source') }}</span>{{ sortIcon('source') }}</span>
|
|
<span class="sort-header" @click.stop="onSortClick('source', $event)">来源<span v-if="sortIndex('source') !== null" class="sort-index" :class="sortClass('source') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('source') }}</span>{{ sortIcon('source') }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" width="130" fixed="right">
|
|
|
|
|
|
|
+ <el-table-column label="操作" width="200" fixed="right">
|
|
|
<template slot-scope="{ row }">
|
|
<template slot-scope="{ row }">
|
|
|
|
|
+ <el-button type="text" @click="showDetail(row)">详情</el-button>
|
|
|
<el-button type="text" @click="editRow(row)">编辑</el-button>
|
|
<el-button type="text" @click="editRow(row)">编辑</el-button>
|
|
|
<el-button type="text" style="color:#f56c6c" @click="deleteRow(row)">删除</el-button>
|
|
<el-button type="text" style="color:#f56c6c" @click="deleteRow(row)">删除</el-button>
|
|
|
</template>
|
|
</template>
|
|
@@ -88,6 +92,22 @@
|
|
|
<el-button type="primary" @click="saveDialog" size="small" :loading="dialog.saving">保存</el-button>
|
|
<el-button type="primary" @click="saveDialog" size="small" :loading="dialog.saving">保存</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 详情弹窗:完整展示文章/条目全文(菌群文章最长 71K 字符) -->
|
|
|
|
|
+ <el-dialog :visible.sync="detail.visible" :title="detail.row ? detail.row.itemName : '详情'" width="820px" :close-on-click-modal="true">
|
|
|
|
|
+ <div v-if="detail.row">
|
|
|
|
|
+ <div class="detail-meta">
|
|
|
|
|
+ <el-tag v-if="detail.row.category" size="small">{{ detail.row.category }}</el-tag>
|
|
|
|
|
+ <span class="detail-meta-item">来源:{{ detail.row.source || '-' }}</span>
|
|
|
|
|
+ <span class="detail-meta-item">ID:{{ detail.row.id }}</span>
|
|
|
|
|
+ <span class="detail-meta-item">正文 {{ (detail.row.description || '').length }} 字符</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-content">{{ detail.row.description || '(无正文)' }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div slot="footer">
|
|
|
|
|
+ <el-button @click="detail.visible = false" size="small">关闭</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -108,6 +128,7 @@ export default {
|
|
|
sortableColumns: { id: 'ID', itemName: '指标名称', category: '分类', normalRange: '正常范围', description: '说明', source: '来源' },
|
|
sortableColumns: { id: 'ID', itemName: '指标名称', category: '分类', normalRange: '正常范围', description: '说明', source: '来源' },
|
|
|
filters: { name: '', category: '' },
|
|
filters: { name: '', category: '' },
|
|
|
categories: ['维生素', '氨基酸', '微量元素', '短链脂肪酸', '神经递质与激素', '肠道屏障与代谢物', '抗生素风险评估'],
|
|
categories: ['维生素', '氨基酸', '微量元素', '短链脂肪酸', '神经递质与激素', '肠道屏障与代谢物', '抗生素风险评估'],
|
|
|
|
|
+ detail: { visible: false, row: null },
|
|
|
dialog: { visible: false, isEdit: false, saving: false, form: {} }
|
|
dialog: { visible: false, isEdit: false, saving: false, form: {} }
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
@@ -132,6 +153,12 @@ export default {
|
|
|
if (this.filters.category) {
|
|
if (this.filters.category) {
|
|
|
rows = rows.filter(function(r) { return r.category === this.filters.category }.bind(this))
|
|
rows = rows.filter(function(r) { return r.category === this.filters.category }.bind(this))
|
|
|
}
|
|
}
|
|
|
|
|
+ // 动态合并数据中的分类(菌群文章等外部来源的分类可能不在硬编码列表内)
|
|
|
|
|
+ var cats = this.categories.slice()
|
|
|
|
|
+ rows.forEach(function(r) {
|
|
|
|
|
+ if (r.category && cats.indexOf(r.category) < 0) cats.push(r.category)
|
|
|
|
|
+ })
|
|
|
|
|
+ this.categories = cats
|
|
|
this.list = rows
|
|
this.list = rows
|
|
|
}
|
|
}
|
|
|
}).finally(() => { this.loading = false })
|
|
}).finally(() => { this.loading = false })
|
|
@@ -142,6 +169,9 @@ export default {
|
|
|
editRow(row) {
|
|
editRow(row) {
|
|
|
this.dialog = { visible: true, isEdit: true, saving: false, form: { id: row.id, itemName: row.itemName, category: row.category, normalRange: row.normalRange, description: row.description, source: row.source } }
|
|
this.dialog = { visible: true, isEdit: true, saving: false, form: { id: row.id, itemName: row.itemName, category: row.category, normalRange: row.normalRange, description: row.description, source: row.source } }
|
|
|
},
|
|
},
|
|
|
|
|
+ showDetail(row) {
|
|
|
|
|
+ this.detail = { visible: true, row: row }
|
|
|
|
|
+ },
|
|
|
saveDialog() {
|
|
saveDialog() {
|
|
|
if (!this.dialog.form.itemName || !this.dialog.form.category) {
|
|
if (!this.dialog.form.itemName || !this.dialog.form.category) {
|
|
|
this.$message.warning('指标名称和分类不能为空'); return
|
|
this.$message.warning('指标名称和分类不能为空'); return
|
|
@@ -184,6 +214,10 @@ export default {
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
.knowledge-page { padding: 20px; }
|
|
.knowledge-page { padding: 20px; }
|
|
|
|
|
+.desc-ellipsis { display: inline; }
|
|
|
|
|
+.detail-meta { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid #ebeef5; font-size: 12px; color: #606266; }
|
|
|
|
|
+.detail-meta-item { color: #909399; }
|
|
|
|
|
+.detail-content { max-height: 62vh; overflow-y: auto; padding: 10px 12px; background: #fafafa; border-radius: 4px; white-space: pre-wrap; word-break: break-word; font-size: 13px; line-height: 1.75; color: #303133; }
|
|
|
.sort-header {
|
|
.sort-header {
|
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
|
user-select: none;
|
|
user-select: none;
|