block_medical/ui/src/pages/doctor/case.vue
18796357645 363710926d 上传
2025-05-13 22:00:55 +08:00

251 lines
6.9 KiB
Vue

<template>
<div class="blockchain-case-system">
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>区块链病例管理系统</span>
</div>
</template>
<!-- 病例列表 -->
<el-table :data="state.caseList" v-loading="state.loading" style="width: 100%">
<el-table-column prop="id" label="病例ID" align="center" />
<el-table-column prop="user.nickName" label="患者姓名" align="center" />
<el-table-column prop="createdTime" label="预约时间" align="center" />
<el-table-column prop="amount" label="预约金额" align="center" />
<el-table-column label="操作" align="center">
<template #default="{row}">
<el-button
v-if="!row.accessGranted"
type="primary"
size="small"
@click="requestAccess(row)"
>
申请查看
</el-button>
<el-button
v-else
type="success"
size="small"
@click="viewCase(row)"
>
查看病例
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 查看病例对话框 -->
<el-dialog
v-model="state.dialogVisible"
:title="`病例详情 - ${state.selectedCase?.patientName}`"
width="70%"
>
<div class="case-content">
<h3>诊断结果: {{ state.selectedCase?.diagnosis }}</h3>
<div class="case-details">
<!-- 这里显示实际的病例内容 -->
<p>这是一份加密存储的区块链病例,只有获得授权的医生可以查看完整内容。</p>
<p>病例ID: {{ state.selectedCase?.id }}</p>
<p>区块链哈希: 0x8923a7b8c5d6e4f2a1b9c8d7e6f5a4b3c2d1e0f</p>
</div>
</div>
</el-dialog>
<!-- 申请查看对话框 -->
<el-dialog v-model="state.requestDialogVisible" title="申请查看病例" width="50%">
<el-form :model="state.requestForm" ref="formRef" label-width="100px">
<el-form-item label="病例ID">
<el-input v-model="state.requestForm.orderId" disabled />
</el-form-item>
<el-form-item label="患者姓名">
<el-input :value="state.selectedCase?.nickName" disabled />
</el-form-item>
<el-form-item label="申请目的" prop="purpose"
:rules="[{ required: true, message: '请输入申请目的', trigger: 'blur' }]">
<el-input
v-model="state.requestForm.purpose"
type="textarea"
:rows="3"
placeholder="请输入申请查看该病例的目的"
/>
</el-form-item>
<!-- <el-form-item label="有效天数" prop="duration"-->
<!-- :rules="[{ required: true, message: '请选择有效天数', trigger: 'change' }]">-->
<!-- <el-select v-model="state.requestForm.duration" placeholder="请选择">-->
<!-- <el-option label="1天" :value="1" />-->
<!-- <el-option label="3天" :value="3" />-->
<!-- <el-option label="7天" :value="7" />-->
<!-- <el-option label="30天" :value="30" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
</el-form>
<template #footer>
<el-button @click="state.requestDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitRequest" :loading="state.loading">提交申请</el-button>
</template>
</el-dialog>
<!-- 患者授权对话框 -->
<el-dialog v-model="state.authDialogVisible" title="授权查看病例" width="50%">
<el-form :model="state.authForm" label-width="100px">
<el-form-item label="病例ID">
<el-input v-model="state.authForm.orderId" disabled />
</el-form-item>
<el-form-item label="患者私钥" prop="privateKey"
:rules="[{ required: true, message: '请输入您的私钥', trigger: 'blur' }]">
<el-input
v-model="state.authForm.privateKey"
type="password"
placeholder="请输入您的区块链私钥以授权"
show-password
/>
</el-form-item>
<el-form-item>
<el-alert type="warning" show-icon>
请注意:私钥是您访问区块链病例的唯一凭证,请勿泄露给他人
</el-alert>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="state.authDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitAuth" :loading="state.loading">授权</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
const formRef = ref<FormInstance>()
const user = userStore().doctorUserInfo
// 状态管理
const state = reactive({
loading: false,
caseList: [] as any[], // 病例列表
selectedCase: null as any, // 选中的病例
dialogVisible: false, // 查看病例对话框
requestDialogVisible: false, // 申请查看对话框
authDialogVisible: false, // 授权对话框
requestForm: {
orderId: '',
purpose: '',
duration: 1 // 默认1天
},
authForm: {
privateKey: '',
orderId: ''
}
})
// 模拟获取病例列表
const getCaseList = async () => {
state.loading = true
try {
// 这里替换为实际的API调用
const res = await frontRequest.get('/api/order/list',{params:{limit:999}})
state.caseList = res.data
} catch (error) {
ElMessage.error('获取病例列表失败')
} finally {
state.loading = false
}
}
// 申请查看病例
const requestAccess = (caseItem: any) => {
state.selectedCase = caseItem.user
state.requestForm.orderId = caseItem.id
state.requestDialogVisible = true
}
// 提交查看申请
const submitRequest = async () => {
try {
state.loading = true
state.requestForm.itemId = user.id
state.requestForm.userId = state.selectedCase.id
await frontRequest.post('api/audit', state.requestForm)
ElMessage.success('查看申请已提交,等待患者授权')
state.requestDialogVisible = false
} catch (error) {
} finally {
state.loading = false
}
}
// 查看病例(已授权)
const viewCase = (caseItem: any) => {
if (caseItem.encrypted && !caseItem.accessGranted) {
requestAccess(caseItem)
return
}
state.selectedCase = caseItem
state.dialogVisible = true
}
// 患者授权查看
const grantAccess = (caseItem: any) => {
state.authDialogVisible = true
state.authForm.orderId = caseItem.id
}
// 提交授权
const submitAuth = async () => {
try {
state.loading = true
// 这里替换为实际的区块链API调用
// await blockchainApi.post('/access/grant', state.authForm)
ElMessage.success('授权成功')
state.authDialogVisible = false
// 刷新病例列表
getCaseList()
} catch (error) {
ElMessage.error('授权失败,请检查私钥是否正确')
} finally {
state.loading = false
}
}
// 初始化加载
onMounted(() => {
getCaseList()
})
</script>
<style scoped>
.blockchain-case-system {
padding: 20px;
}
.card-header {
font-size: 18px;
font-weight: bold;
}
.case-content {
padding: 20px;
}
.case-details {
margin-top: 20px;
padding: 15px;
background-color: #f5f7fa;
border-radius: 4px;
}
</style>
<route lang="json">
{
"meta": {
"layout": "doctor"
}
}
</route>