496 lines
13 KiB
Vue
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>
|