block_medical/ui/src/pages/doctor/log.vue
2025-05-18 23:08:33 +08:00

496 lines
13 KiB
Vue

<template>
<div>
<!--查交易记录的按钮-->
<!-- <el-button type="primary" round @click="openAddDialog" size="small">添加</el-button>-->
<el-row>
<el-col :span="24">
<el-form :inline="true" :model="state.query" class="demo-form-inline">
<el-form-item label="患者名称:">
<el-input v-model="state.query.userName" placeholder="请输患者名称" clearable @input="init" />
</el-form-item>
</el-form>
</el-col>
</el-row>
<!--表格-->
<el-row>
<el-col :span="24">
<el-tabs v-model="state.query.orderStatus" @tab-click="handleClick">
<el-tab-pane v-for="item in state.getOrderStatus" :label="item.name" :name="item.status">
<el-table v-loading="loading" :data="state.getList">
<!-- 列表结开始-->
<el-table-column prop="userDTO.nickName" label="姓名" align="center"/>
<el-table-column prop="age" label="年龄" align="center"/>
<el-table-column prop="sex" label="性别" align="center" >
<template #default="{ row }">
{{ row.sex === 1? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="appointmentTime" label="预约时间" align="center"/>
<el-table-column prop="remark" label="备注" align="center"/>
<!--列表结束-->
<el-table-column label="操作" align="center" >
<template #default="scope">
<el-button v-if="item.status == 0" @click="edit(scope.row)" size="small">开具病例</el-button>
<!-- <el-button v-if="item.status ==1" @click="view(scope.row.content)" size="small">查看病例</el-button>-->
<!-- <el-button v-if="item.status ==1" @click="view(scope.row.content)" size="small">查看病例</el-button>-->
<el-button v-if="item.status == 2" @click="del(scope.row.id)" type="danger" size="small">删除</el-button>
</template>
</el-table-column>
<template v-slot:empty>
<el-empty description="数据去外太空了~" />
</template>
</el-table>
</el-tab-pane>
</el-tabs>
<!-- 分页控件 -->
<el-pagination
v-if="state.query.total > 0"
:current-page="state.query.page"
:page-size="state.query.limit"
:total="state.query.total"
background layout="prev, pager, next"
@current-change="handlePageChange"
/>
</el-col>
</el-row>
<!-- 新增/编辑对话框 -->
<el-dialog v-model="state.dialogVisible" title="新增" width="80%">
<el-form
:model="state.formData"
ref="formRef"
label-width="100px"
>
<!-- 患者基本信息 -->
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="预约编号" prop="id" :rules="[{ required: true, message: '请输入预约编号', trigger: 'blur' }]">
<el-input disabled v-model="state.formData.id"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="姓名" prop="nickName">
<el-input v-model="state.formData.nickName"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="年龄" prop="age" :rules="[{ required: true, message: '请输入年龄', trigger: 'blur' }]">
<el-input v-model="state.formData.age"/>
</el-form-item>
</el-col>
</el-row>
<!-- 病例编辑 -->
<el-form-item label="开具病例" prop="content" :rules="[{ required: true, message: '请编写病例', trigger: 'blur' }]">
<e-editor :content="state.formData.content" @update:content="handlemsg" />
</el-form-item>
<!-- 药品选择 -->
<el-form-item label="开具药品" prop="medicines">
<div class="medicine-selector">
<!-- 药品搜索和添加 -->
<el-row :gutter="10">
<el-col :span="18">
<el-select
v-model="state.formData.medicineId"
filterable
remote
reserve-keyword
placeholder="请输入药品名称搜索"
:remote-method="searchMedicine"
:loading="state.medicineLoading"
@change="handleMedicineSelect"
>
<el-option
v-for="item in state.medicineOptions"
:key="item.id"
:label="`${item.medicineName} (${item.specification}) - 库存:${item.stockQuantity}`"
:value="item.id"
>
<span style="float: left">{{ item.medicineName }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">
{{ item.specification }} | 库存:{{ item.stockQuantity }} | ¥{{ item.unitPrice.toFixed(2) }}
</span>
</el-option>
</el-select>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="addMedicine" :disabled="!state.formData.medicineId">添加药品</el-button>
</el-col>
</el-row>
<!-- 已选择药品表格 -->
<el-table
:data="state.formData.medicines"
border
style="width: 100%"
v-if="state.formData.medicines && state.formData.medicines.length > 0"
>
<el-table-column prop="medicineName" label="药品名称" width="180"/>
<el-table-column prop="specification" label="规格" width="120"/>
<el-table-column label="单价" width="100">
<template #default="{row}">
¥{{ row.unitPrice.toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="数量" width="150">
<template #default="{row, $index}">
<el-input-number
v-model="row.quantity"
:min="1"
:max="row.stockQuantity"
@change="calculateTotal"
size="small"
/>
</template>
</el-table-column>
<el-table-column label="用法用量" width="200">
<template #default="{row, $index}">
<el-input
v-model="row.usage"
placeholder="如:一日三次,每次一片"
size="small"
/>
</template>
</el-table-column>
<el-table-column label="小计" width="120">
<template #default="{row}">
¥{{ (row.unitPrice * row.quantity).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="{$index}">
<el-button
type="danger"
size="small"
@click="removeMedicine($index)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 药品总计 -->
<div class="total-price" v-if="state.formData.medicines && state.formData.medicines.length > 0">
<span class="label">药品总价:</span>
<span class="value">¥{{ state.totalMedicinePrice.toFixed(2) }}</span>
</div>
</div>
</el-form-item>
<!-- 诊断结果 -->
<el-form-item label="诊断结果" prop="diagnosis" :rules="[{ required: true, message: '请输入诊断结果', trigger: 'blur' }]">
<el-input
v-model="state.formData.diagnosis"
type="textarea"
:rows="3"
placeholder="请输入诊断结果"
/>
</el-form-item>
<!-- 医嘱 -->
<el-form-item label="医嘱" prop="medicalAdvice">
<el-input
v-model="state.formData.medicalAdvice"
type="textarea"
:rows="3"
placeholder="请输入医嘱"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="state.dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveTransaction(formRef)">保存</el-button>
</div>
</el-dialog>
<el-dialog v-model="state.dialogVisibleView" title="查看病例" width="50%">
<div v-html="state.content"></div>
<div slot="footer" class="dialog-footer">
<el-button @click="state.dialogVisibleView = false">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import type { FormInstance, TabsPaneContext } from 'element-plus'
interface FormData {
id?: string
nickName?: string
age?: number
content?: string
diagnosis?: string
medicalAdvice?: string
medicines?: any[]
medicineId?: number | null
orderStatus?: number
}
const formRef = ref<FormInstance>()
const loading = ref(true)
const user = userStore().doctorUserInfo
const state = reactive({
route: "api/order",
content: "",
getOrderStatus: [
{name: "已预约", status: 0},
{name: "已完成", status: 1},
{name: "已取消", status: 2}
],
dialogVisible: false,
dialogVisibleView: false,
getList: [] as any[], // 获取数据
medicineOptions: [] as any[],
medicineLoading: false,
totalMedicinePrice: 0,
query: {
total: 0, // 总记录数
page: 1, // 当前页码
limit: 5, // 每页显示的记录数
itemId: user.id,
orderStatus: 0,
userName: ""
},
formData: {
medicines: [],
medicineId: null
} as FormData
})
// 处理病例内容更新
function handlemsg(content: string) {
state.formData.content = content
}
// 标签页切换
const handleClick = (tab: TabsPaneContext) => {
const selectedStatus = state.getOrderStatus[tab.index].status
state.query.orderStatus = selectedStatus
init()
}
// 获取预约记录
const init = () => {
loading.value = true
frontRequest.get(`${state.route}/log`, {
params: state.query
}).then((res: any) => {
state.getList = res.data.list
state.query.total = res.data.total
}).finally(() => {
loading.value = false
})
}
// 打开新增对话框
const openAddDialog = () => {
state.formData = {
medicines: [],
medicineId: null,
sort: 1
}
state.dialogVisible = true
}
// 编辑预约记录
const edit = async (row: any) => {
try {
loading.value = true
// 获取预约详情,包括已开具的药品
const res = await frontRequest.get(`${state.route}/${row.id}`)
state.formData = {
...res.data,
nickName: row.userDTO.nickName,
orderStatus: 1,
medicines: res.data.medicines || [],
medicineId: null
}
// 计算药品总价
calculateTotal()
state.dialogVisible = true
} catch (error) {
ElMessage.error('获取预约详情失败')
console.error(error)
} finally {
loading.value = false
}
}
// 药品选择处理
const handleMedicineSelect = (id: number) => {
state.formData.medicineId = id
}
// 添加药品
const addMedicine = async () => {
if (!state.formData.medicineId) return
try {
// 获取药品详情
const res = await frontRequest.get(`/api/management/${state.formData.medicineId}`)
const medicine = res.data
if (medicine) {
// 检查是否已添加过该药品
const exists = state.formData.medicines?.some(item => item.id === medicine.id)
if (exists) {
ElMessage.warning('该药品已添加')
return
}
// 初始化药品数组如果不存在
if (!state.formData.medicines) {
state.formData.medicines = []
}
// 添加药品到列表
state.formData.medicines.push({
...medicine,
quantity: 1,
usage: '一日三次,每次一片' // 默认用法
})
console.log(state.formData.medicines)
state.formData.medicineId = null
state.medicineOptions = []
calculateTotal()
}
} catch (error) {
ElMessage.error('获取药品信息失败')
console.error(error)
}
}
// 移除药品
const removeMedicine = (index: number) => {
if (state.formData.medicines) {
state.formData.medicines.splice(index, 1)
calculateTotal()
}
}
// 计算药品总价
const calculateTotal = () => {
if (state.formData.medicines) {
state.totalMedicinePrice = state.formData.medicines.reduce(
(sum, item) => sum + (item.unitPrice * item.quantity), 0
)
} else {
state.totalMedicinePrice = 0
}
}
// 查看病例
function view(content: string) {
state.dialogVisibleView = true
state.content = content
}
// 搜索药品
const searchMedicine = async (query: string) => {
if (query) {
state.medicineLoading = true
try {
const res = await frontRequest.get('/api/management/page', {
params: {
limit: 999,
medicineName: query
}
})
state.medicineOptions = res.data.list
} catch (error) {
console.error('搜索药品失败', error)
ElMessage.error('搜索药品失败')
} finally {
state.medicineLoading = false
}
}
}
// 保存记录
const saveTransaction = async (formEl: FormInstance | undefined) => {
if (!formEl) return
try {
const isValid = await formEl.validate()
if (!isValid) return
// 准备提交数据
const submitData = {
price:state.totalMedicinePrice,
...state.formData,
// 确保只提交必要的药品字段
medicines: JSON.stringify(state.formData.medicines)
}
if (state.formData.id) {
submitData.orderId = submitData.id
delete submitData.id
await frontRequest.post(`/api/case`, submitData)
ElMessage.success("提交成功")
}
state.dialogVisible = false
init()
} catch (error) {
console.error(error)
ElMessage.error("提交失败")
}
}
// 删除记录
const del = async (id: number) => {
try {
await ElMessageBox.confirm('确定要删除该记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await frontRequest.delete(`${state.route}/${id}`)
ElMessage.success("删除成功")
init()
} catch (error) {
if (error !== 'cancel') {
ElMessage.error("删除失败")
}
}
}
// 分页处理
const handlePageChange = (page: number) => {
state.query.page = page
init()
}
onMounted(() => {
init()
})
</script>
<style scoped>
.mb-10 {
margin-bottom: 10px;
}
.total-price {
margin-top: 15px;
text-align: right;
font-size: 16px;
font-weight: bold;
}
.total-price .label {
color: #606266;
}
.total-price .value {
color: #f56c6c;
margin-left: 10px;
}
.dialog-footer {
text-align: right;
}
</style>
<route lang="json">
{
"meta": {
"layout": "doctor"
}
}
</route>