Compare commits
3 Commits
b42b9cd78a
...
61d152a6e8
| Author | SHA1 | Date |
|---|---|---|
|
|
61d152a6e8 | 5 days ago |
|
|
65ce40b5dd | 5 days ago |
|
|
620ef2fce9 | 5 days ago |
4 changed files with 614 additions and 323 deletions
@ -0,0 +1,277 @@ |
||||
<template> |
||||
<el-dialog |
||||
:visible.sync="visible" |
||||
title="会诊病例数统计" |
||||
width="420px" |
||||
:show-close="false" |
||||
:close-on-click-modal="false" |
||||
append-to-body |
||||
custom-class="stats-case-dialog" |
||||
> |
||||
<div class="stats-form"> |
||||
<div class="stats-row"> |
||||
<div class="stats-label">总病例数</div> |
||||
<el-input |
||||
v-model.number="form.total_patients" |
||||
type="number" |
||||
min="0" |
||||
class="stats-input" |
||||
/> |
||||
<span class="stats-unit">人</span> |
||||
</div> |
||||
<div class="stats-row"> |
||||
<div class="stats-label">阳性病例数</div> |
||||
<el-input |
||||
v-model.number="form.positive_patients" |
||||
type="number" |
||||
min="0" |
||||
class="stats-input" |
||||
/> |
||||
<span class="stats-unit">人</span> |
||||
</div> |
||||
<div class="stats-row"> |
||||
<div class="stats-label">转诊病例数</div> |
||||
<el-input |
||||
v-model.number="form.transfer_patients" |
||||
type="number" |
||||
min="0" |
||||
class="stats-input" |
||||
/> |
||||
<span class="stats-unit">人</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<div slot="footer" class="dialog-footer"> |
||||
<el-button |
||||
:class="isFormValid ? 'btn-confirm-valid' : 'btn-confirm-disabled'" |
||||
:disabled="!isFormValid" |
||||
@click="handleConfirm" |
||||
>确定</el-button> |
||||
<el-button class="btn-close" @click="handleClose">关闭</el-button> |
||||
</div> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script> |
||||
import Vue from 'vue'; |
||||
import { postConsultationPatients } from '@/api/videoCommunication'; |
||||
|
||||
const ConsultationCaseStatsDialog = { |
||||
name: 'ConsultationCaseStatsDialog', |
||||
data() { |
||||
return { |
||||
visible: false, |
||||
consultation_id: null, |
||||
submitting: false, // 提交中防重复点击 |
||||
form: { |
||||
total_patients: 0, |
||||
positive_patients: 0, |
||||
transfer_patients: 0, |
||||
}, |
||||
}; |
||||
}, |
||||
computed: { |
||||
// 总病例数 >= 阳性 + 转诊 时表单才有效 |
||||
isFormValid() { |
||||
const { total_patients, positive_patients, transfer_patients } = this.form; |
||||
return total_patients >= positive_patients + transfer_patients; |
||||
}, |
||||
}, |
||||
methods: { |
||||
show(consultationId) { |
||||
this.consultation_id = consultationId; |
||||
this.form = { |
||||
total_patients: 0, |
||||
positive_patients: 0, |
||||
transfer_patients: 0, |
||||
}; |
||||
this.visible = true; |
||||
}, |
||||
async handleConfirm() { |
||||
if (!this.isFormValid || this.submitting) return; |
||||
this.submitting = true; |
||||
try { |
||||
await postConsultationPatients({ |
||||
consultation_id: this.consultation_id, |
||||
total_patients: this.form.total_patients, |
||||
positive_patients: this.form.positive_patients, |
||||
transfer_patients: this.form.transfer_patients, |
||||
}); |
||||
this.$message?.success('提交成功'); |
||||
this.$emit('confirm', { ...this.form }); |
||||
this.visible = false; |
||||
} catch (e) { |
||||
this.$message?.error('提交失败'); |
||||
} finally { |
||||
this.submitting = false; |
||||
} |
||||
}, |
||||
handleClose() { |
||||
this.visible = false; |
||||
this.$emit('close'); |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
// 编程式打开弹窗(组件实例独立于调用方生命周期,路由跳转后仍存活) |
||||
ConsultationCaseStatsDialog.open = function (consultationId) { |
||||
const DialogCtor = Vue.extend(ConsultationCaseStatsDialog); |
||||
const instance = new DialogCtor().$mount(); |
||||
document.body.appendChild(instance.$el); |
||||
instance.$nextTick(() => { |
||||
instance.show(consultationId); |
||||
}); |
||||
|
||||
const cleanup = () => { |
||||
setTimeout(() => { |
||||
if (instance.$el && instance.$el.parentNode) { |
||||
instance.$el.parentNode.removeChild(instance.$el); |
||||
} |
||||
instance.$destroy(); |
||||
}, 500); |
||||
}; |
||||
|
||||
// 接管按钮事件,关闭时自动清理 DOM 和实例 |
||||
const origConfirm = instance.handleConfirm; |
||||
const origClose = instance.handleClose; |
||||
instance.handleConfirm = function () { |
||||
origConfirm.call(this); |
||||
cleanup(); |
||||
}; |
||||
instance.handleClose = function () { |
||||
origClose.call(this); |
||||
cleanup(); |
||||
}; |
||||
|
||||
return instance; |
||||
}; |
||||
|
||||
export default ConsultationCaseStatsDialog; |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
.stats-case-dialog { |
||||
.el-dialog__header { |
||||
padding: 20px 20px 10px; |
||||
border-bottom: none; |
||||
} |
||||
|
||||
.el-dialog__title { |
||||
display: flex; |
||||
align-items: center; |
||||
font-size: 16px; |
||||
font-weight: 500; |
||||
color: #333; |
||||
line-height: 1; |
||||
|
||||
&::before { |
||||
content: ''; |
||||
display: inline-block; |
||||
width: 3px; |
||||
height: 16px; |
||||
background-color: #009688; |
||||
border-radius: 2px; |
||||
margin-right: 8px; |
||||
} |
||||
} |
||||
|
||||
.el-dialog__body { |
||||
padding: 10px 30px 20px; |
||||
} |
||||
|
||||
.el-dialog__footer { |
||||
padding: 10px 20px 20px; |
||||
border-top: none; |
||||
text-align: center; |
||||
} |
||||
|
||||
.stats-form { |
||||
display: flex; |
||||
flex-direction: column; |
||||
gap: 16px; |
||||
} |
||||
|
||||
.stats-row { |
||||
display: flex; |
||||
align-items: center; |
||||
gap: 10px; |
||||
} |
||||
|
||||
.stats-label { |
||||
width: 84px; |
||||
height: 36px; |
||||
line-height: 36px; |
||||
text-align: center; |
||||
background-color: #009688; |
||||
color: #fff; |
||||
font-size: 14px; |
||||
border-radius: 4px; |
||||
flex-shrink: 0; |
||||
} |
||||
|
||||
.stats-input { |
||||
flex: 1; |
||||
|
||||
.el-input__inner { |
||||
height: 36px; |
||||
line-height: 36px; |
||||
border-radius: 4px; |
||||
border-color: #009688; |
||||
text-align: left; |
||||
padding-left: 12px; |
||||
|
||||
&:focus { |
||||
border-color: #009688; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.stats-unit { |
||||
width: 20px; |
||||
font-size: 14px; |
||||
color: #333; |
||||
flex-shrink: 0; |
||||
} |
||||
|
||||
.dialog-footer { |
||||
display: flex; |
||||
justify-content: center; |
||||
gap: 20px; |
||||
|
||||
.btn-confirm-disabled { |
||||
width: 90px; |
||||
height: 36px; |
||||
background-color: #ccc; |
||||
border-color: #ccc; |
||||
color: #fff; |
||||
cursor: not-allowed; |
||||
} |
||||
|
||||
.btn-confirm-valid { |
||||
width: 90px; |
||||
height: 36px; |
||||
background-color: #009688; |
||||
border-color: #009688; |
||||
color: #fff; |
||||
|
||||
&:hover { |
||||
background-color: #00897b; |
||||
border-color: #00897b; |
||||
} |
||||
} |
||||
|
||||
.btn-close { |
||||
width: 90px; |
||||
height: 36px; |
||||
background-color: #009688; |
||||
border-color: #009688; |
||||
color: #fff; |
||||
|
||||
&:hover { |
||||
background-color: #00897b; |
||||
border-color: #00897b; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue