| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- <template>
- <view class="page">
- <view class="nav-bar">
- <view class="nav-back" @tap="goBack">
- <text class="back-text">‹ 返回</text>
- </view>
- <text class="nav-title">疾病风险</text>
- <text class="nav-edit" @tap="toggleEdit">{{ isEditing ? '完成' : '编辑' }}</text>
- </view>
- <scroll-view class="content" scroll-y>
- <view class="section-label">重要风险</view>
- <view class="risk-card" v-for="(item, idx) in importantRisks" :key="idx"
- :class="'risk-level-' + (item._cssClass || 'low')">
- <view class="risk-header">
- <text class="risk-name" @tap="showKnowledge('disease', item.diseaseName)">{{ item.diseaseName }}</text>
- <text class="risk-badge" :class="'badge-' + (item._cssClass || 'low')">
- {{ riskBadgeText(item.riskLevel) }}
- </text>
- </view>
- <view class="risk-detail-row" v-if="!isEditing">
- <text class="risk-value">风险值: {{ item.riskValue || '--' }}</text>
- <text class="risk-level-text">等级: {{ item.riskLevel || '--' }}</text>
- </view>
- <view class="risk-edit-row" v-if="isEditing">
- <text class="edit-label">风险值:</text>
- <input class="edit-input" type="text" v-model="item.riskValue" />
- <text class="edit-label">等级:</text>
- <picker :value="riskLevelIndex(item.riskLevel)" :range="riskLevels" @change="onRiskLevelChange($event, item)">
- <text class="edit-picker">{{ item.riskLevel || '请选择' }}</text>
- </picker>
- </view>
- </view>
- <view class="section-label">其它风险</view>
- <view class="risk-card" v-for="(item, idx) in normalRisks" :key="idx"
- :class="'risk-level-' + (item._cssClass || 'low')">
- <view class="risk-header">
- <text class="risk-name" @tap="showKnowledge('disease', item.diseaseName)">{{ item.diseaseName }}</text>
- <text class="risk-badge" :class="'badge-' + (item._cssClass || 'low')">
- {{ riskBadgeText(item.riskLevel) }}
- </text>
- </view>
- <view class="risk-detail-row" v-if="!isEditing">
- <text class="risk-value">风险值: {{ item.riskValue || '--' }}</text>
- <text class="risk-level-text">等级: {{ item.riskLevel || '--' }}</text>
- </view>
- <view class="risk-edit-row" v-if="isEditing">
- <text class="edit-label">风险值:</text>
- <input class="edit-input" type="text" v-model="item.riskValue" />
- <text class="edit-label">等级:</text>
- <picker :value="riskLevelIndex(item.riskLevel)" :range="riskLevels" @change="onRiskLevelChange($event, item)">
- <text class="edit-picker">{{ item.riskLevel || '请选择' }}</text>
- </picker>
- </view>
- </view>
- <view class="empty-hint" v-if="risks.length === 0">暂无疾病风险评估</view>
- <view class="bottom-spacer"></view>
- </scroll-view>
- <health-knowledge-popup :visible="knowledgeVisible" :data="knowledgeData" @close="closeKnowledge" />
- <view class="bottom-bar" v-if="isEditing">
- <view class="btn-cancel" @tap="cancelEdit">取消</view>
- <view class="btn-save" @tap="saveEdit">保存</view>
- </view>
- </view>
- </template>
- <script>
- import { getReportDetail, editHealthReport, queryKnowledgeBase, queryIndicatorKnowledge } from '../../utils/api.js'
- import HealthKnowledgePopup from '../../components/health-knowledge-popup.vue'
- export default {
- components: { HealthKnowledgePopup },
- data() {
- return {
- reportId: null,
- reportData: null,
- risks: [],
- isEditing: false,
- editRisks: [],
- riskLevels: ['低风险', '需注意', '高风险', '异常'],
- knowledgeVisible: false,
- knowledgeData: {}
- }
- },
- computed: {
- importantRisks: function() {
- return this.getRisks().filter(function(item) {
- var level = item.riskLevel || ''
- return level === '需注意' || level === '高风险' || level === '异常'
- })
- },
- normalRisks: function() {
- return this.getRisks().filter(function(item) {
- var level = item.riskLevel || ''
- return level !== '需注意' && level !== '高风险' && level !== '异常'
- })
- }
- },
- onLoad: function(options) {
- this.reportId = options.reportId ? parseInt(options.reportId) : null
- if (this.reportId) {
- this.loadData()
- }
- },
- methods: {
- goBack: function() { uni.navigateBack() },
- /** 中文风险等级 → CSS安全英文 */
- _cssForRiskLevel: function(level) {
- var map = { '低风险': 'low', '需注意': 'warning', '高风险': 'high', '异常': 'abnormal' }
- return map[level] || 'low'
- },
- getRisks: function() {
- return this.isEditing ? this.editRisks : this.risks
- },
- loadData: function() {
- var self = this
- getReportDetail(this.reportId).then(function(res) {
- if (res.code === 200 && res.data) {
- self.reportData = res.data
- self.risks = (res.data.diseaseRisks || []).map(function(item) {
- item._cssClass = self._cssForRiskLevel(item.riskLevel)
- return item
- })
- }
- })
- },
- toggleEdit: function() {
- this.isEditing = true
- this.editRisks = JSON.parse(JSON.stringify(this.risks))
- },
- cancelEdit: function() {
- this.isEditing = false
- this.editRisks = []
- },
- saveEdit: function() {
- var self = this
- editHealthReport(self.reportId, { diseaseRisks: self.editRisks }, 0).then(function(res) {
- if (res.code === 200) {
- uni.showToast({ title: '已保存', icon: 'success' })
- self.isEditing = false
- self.loadData()
- } else {
- uni.showToast({ title: res.message || '保存失败', icon: 'none' })
- }
- })
- },
- riskBadgeText: function(level) {
- var map = { '低风险': '✓ 低', '需注意': '⚠ 注意', '高风险': '⚠ 高', '异常': '⚠ 异常' }
- return map[level] || level || ''
- },
- riskLevelIndex: function(level) {
- var idx = this.riskLevels.indexOf(level)
- return idx >= 0 ? idx : 0
- },
- onRiskLevelChange: function(e, item) {
- item.riskLevel = this.riskLevels[e.detail.value]
- },
- showKnowledge: function(type, name) {
- var self = this
- // 优先使用 KB v3 查询指标调整建议
- queryIndicatorKnowledge(name).then(function(res) {
- if (res.code === 200 && res.data) {
- var v3 = res.data
- var high = v3['偏高影响'] || ''
- var low = v3['偏低影响'] || ''
- self.knowledgeData = {
- itemName: v3['名称'] || name,
- category: v3['说明'] || '',
- description: (high ? '偏高影响:' + high + '\n' : '') + (low ? '偏低影响:' + low : ''),
- suggestion: v3['调整建议'] || ''
- }
- self.knowledgeVisible = true
- } else {
- // 回退旧版 DB 查询
- self.queryOldKnowledgeBase(type, name)
- }
- }).catch(function() {
- self.queryOldKnowledgeBase(type, name)
- })
- },
- queryOldKnowledgeBase: function(type, name) {
- var self = this
- queryKnowledgeBase(type, name).then(function(res) {
- if (res.code === 200 && res.data) {
- self.knowledgeData = res.data
- self.knowledgeVisible = true
- } else {
- self.knowledgeData = { itemName: name }
- self.knowledgeVisible = true
- }
- })
- },
- closeKnowledge: function() {
- this.knowledgeVisible = false
- this.knowledgeData = {}
- }
- }
- }
- </script>
- <style scoped>
- .page { min-height: 100vh; background: #f8f8f8; }
- .nav-bar { display: flex; align-items: center; padding: 20rpx 30rpx; background: #fff; position: relative; }
- .nav-back { padding: 10rpx 0; }
- .back-text { font-size: 28rpx; color: #4A9BD7; }
- .nav-title { flex: 1; text-align: center; font-size: 32rpx; font-weight: 600; }
- .nav-edit { font-size: 28rpx; color: #4A9BD7; padding: 10rpx 0; }
- .content { padding: 20rpx 30rpx; height: calc(100vh - 100rpx); }
- .section-label { font-size: 26rpx; color: #999; margin: 10rpx 0 16rpx; padding-left: 8rpx; }
- .risk-card { background: #fff; border-radius: 16rpx; padding: 24rpx; margin-bottom: 16rpx; border-left: 8rpx solid #10B981; }
- .risk-level-warning { border-left-color: #F59E0B; }
- .risk-level-high { border-left-color: #C62828; }
- .risk-level-abnormal { border-left-color: #C62828; }
- .risk-header { display: flex; align-items: center; margin-bottom: 12rpx; }
- .risk-name { font-size: 30rpx; font-weight: 600; color: #333; flex: 1; }
- .risk-badge { padding: 4rpx 16rpx; border-radius: 20rpx; font-size: 22rpx; }
- .badge-low { background: #E8F5E9; color: #2E7D32; }
- .badge-warning { background: #FFF3E0; color: #E65100; }
- .badge-high { background: #FFEBEE; color: #C62828; }
- .badge-abnormal { background: #FFEBEE; color: #C62828; }
- .risk-detail-row { display: flex; gap: 24rpx; }
- .risk-value, .risk-level-text { font-size: 24rpx; color: #999; }
- .risk-edit-row { display: flex; align-items: center; gap: 12rpx; flex-wrap: wrap; }
- .edit-label { font-size: 26rpx; color: #666; }
- .edit-input { border: 1rpx solid #ddd; border-radius: 8rpx; padding: 8rpx 12rpx; font-size: 26rpx; width: 120rpx; }
- .edit-picker { border: 1rpx solid #ddd; border-radius: 8rpx; padding: 8rpx 12rpx; font-size: 26rpx; color: #333; }
- .empty-hint { text-align: center; color: #ccc; padding: 60rpx 0; font-size: 28rpx; }
- .bottom-bar { position: fixed; bottom: 0; left: 0; right: 0; display: flex; padding: 20rpx 30rpx; background: #fff; border-top: 1rpx solid #eee; gap: 20rpx; }
- .btn-cancel { flex: 1; padding: 20rpx; border: 1rpx solid #ddd; border-radius: 12rpx; text-align: center; font-size: 28rpx; color: #666; }
- .btn-save { flex: 1; padding: 20rpx; background: #4A9BD7; border-radius: 12rpx; text-align: center; font-size: 28rpx; color: #fff; }
- .bottom-spacer { height: 40rpx; }
- </style>
|