This commit is contained in:
Your Name
2026-04-21 18:02:27 +08:00
parent a1d2ab4649
commit d899e0fe0a
301 changed files with 1937 additions and 344 deletions
+210 -7
View File
@@ -110,6 +110,19 @@
<el-tag type="info" size="small">{{ row.prescription_type || '—' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="来源" min-width="92" align="center">
<template #default="{ row }">
<el-tag
v-if="Number(row.is_system_auto) === 1"
type="warning"
size="small"
effect="plain"
>
系统代开
</el-tag>
<span v-else class="text-gray-400 text-sm">手工</span>
</template>
</el-table-column>
<el-table-column label="患者信息" min-width="110">
<template #default="{ row }">
<div class="font-medium">{{ row.patient_name || '—' }}</div>
@@ -237,6 +250,13 @@
<div class="cf-slip-header">
<h2 class="cf-slip-title">{{ SLIP_HOSPITAL_NAME }}处方笺</h2>
<div class="cf-slip-type">
<el-tag
v-if="Number(slipView.is_system_auto) === 1"
type="warning"
size="small"
class="mr-1"
effect="plain"
>系统代开</el-tag>
<el-tag v-if="Number(slipView.void_status) === 1" type="danger" size="small">已作废</el-tag>
<el-tag
v-else-if="Number(slipView.business_prescription_audit_rejected) === 1"
@@ -364,6 +384,14 @@
:rules="rules"
label-width="120px"
>
<el-alert
v-if="editMode === 'edit' && Number(editForm.is_system_auto) === 1"
type="warning"
:closable="false"
show-icon
class="mb-4"
title="本处方为系统自动生成(如挂号完成),默认无药材配方,请补充药材与诊断等信息后再保存。"
/>
<el-alert
v-if="editMode === 'edit'"
type="info"
@@ -505,6 +533,9 @@
<el-button type="primary" size="small" @click="addHerb">
添加药材
</el-button>
<el-button type="success" size="small" class="ml-2" @click="openLibraryDialog">
从处方库导入
</el-button>
<el-table :data="editForm.herbs" class="mt-2" border>
<el-table-column label="序号" type="index" width="60" />
<el-table-column label="药材名称" min-width="150">
@@ -816,9 +847,9 @@
<span class="create-order-rx-card__patient">{{ createOrderPrescription.patient_name || '—' }}</span>
</div>
</div>
<el-tooltip :content="createOrderHerbSummary" placement="bottom" :show-after="300">
<!-- <el-tooltip :content="createOrderHerbSummary" placement="bottom" :show-after="300">
<div class="create-order-rx-card__herbs">{{ createOrderHerbSummary }}</div>
</el-tooltip>
</el-tooltip> -->
</div>
<el-steps
@@ -1118,6 +1149,69 @@
</template>
</el-dialog>
<!-- 从处方库导入(与诊间 tcm-prescription 一致,按当前处方开方医师 creator_id 筛选) -->
<el-dialog
v-model="showLibraryDialog"
title="从处方库导入"
width="800px"
:close-on-click-modal="false"
>
<div class="mb-4">
<el-input
v-model="librarySearchName"
placeholder="请输入处方名称搜索"
clearable
@keyup.enter="searchLibrary"
@clear="searchLibrary"
>
<template #append>
<el-button :icon="Search" @click="searchLibrary" />
</template>
</el-input>
</div>
<el-table
v-loading="libraryLoading"
:data="libraryList"
height="400"
style="cursor: pointer"
@row-click="handleSelectLibraryRow"
>
<el-table-column label="处方名称" prop="prescription_name" min-width="150" show-overflow-tooltip />
<el-table-column label="药材数量" width="100">
<template #default="{ row }">
{{ row.herbs?.length || 0 }}味
</template>
</el-table-column>
<el-table-column label="药材明细" min-width="300" show-overflow-tooltip>
<template #default="{ row }">
<span v-if="row.herbs && row.herbs.length > 0">
{{ row.herbs.map((h: any) => `${h.name} ${h.dosage}g`).join('、') }}
</span>
<span v-else class="text-gray-400">暂无药材</span>
</template>
</el-table-column>
<el-table-column label="创建人" prop="creator_name" width="100" />
<el-table-column label="操作" width="100" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click.stop="handleImportLibrary(row)">导入</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<el-pagination
v-model:current-page="libraryPage"
v-model:page-size="libraryPageSize"
:total="libraryTotal"
:page-sizes="[10, 15, 20, 50]"
layout="total, sizes, prev, pager, next"
@current-change="loadLibraryList"
@size-change="loadLibraryList"
/>
</div>
</el-dialog>
<el-dialog v-model="auditDialogVisible" title="处方审核" width="480px" destroy-on-close @closed="auditRemark = ''">
<p class="text-sm text-gray-600 mb-3">
通过:处方保持有效。驳回:将同时作废此处方(与诊间「驳回/作废处方」一致)。
@@ -1153,7 +1247,8 @@ import {
prescriptionDetail,
prescriptionOrderCreate,
prescriptionOrderPaidPayOrders,
getDoctors
getDoctors,
prescriptionLibraryLists
} from '@/api/tcm'
import { searchPatients as searchPatientsAPI } from '@/api/order'
import { getDictData } from '@/api/app'
@@ -1163,6 +1258,7 @@ import useUserStore from '@/stores/modules/user'
import feedback from '@/utils/feedback'
import type { FormInstance, FormRules } from 'element-plus'
import DaterangePicker from '@/components/daterange-picker/index.vue'
import { Search } from '@element-plus/icons-vue'
import { computed, onMounted, reactive, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
@@ -1783,6 +1879,10 @@ const editForm = reactive({
audit_by_name: '',
audit_remark: '',
diagnosis_id: 0,
/** 开方医师 admin id(处方库导入按此医生筛选) */
creator_id: 0,
/** 1=系统自动生成(如挂号完成) */
is_system_auto: 0,
/** 列表带入:业务订单「处方审核」驳回(消费者处方本身可能仍为已通过) */
business_prescription_audit_rejected: 0,
business_prescription_audit_remark: '',
@@ -1938,7 +2038,7 @@ function resetParams() {
dateQuickTab.value = 'all'
formData.patient_name = ''
formData.creator_ids = []
formData.audit_filter = userCanAudit() ? 'pending' : 'all'
formData.audit_filter = 'all'
formData.start_time = ''
formData.end_time = ''
syncingDateTab = false
@@ -2103,6 +2203,108 @@ async function loadRoleOptions() {
}
}
// —— 处方库导入(与 components/tcm-prescription 一致,按 creator_id 拉取该医师库内处方)——
const showLibraryDialog = ref(false)
const libraryLoading = ref(false)
const libraryList = ref<any[]>([])
const librarySearchName = ref('')
const libraryPage = ref(1)
const libraryPageSize = ref(15)
const libraryTotal = ref(0)
/** 当前用于检索处方库的开方医师 ID:编辑用处方 creator_id,新增用当前登录账号 */
const libraryDoctorId = computed(() => {
const cid = Number(editForm.creator_id)
if (cid > 0) return cid
const uid = Number(userStore.userInfo?.id)
return uid > 0 ? uid : 0
})
function normalizeHerbNameLocal(s: string) {
return String(s || '')
.trim()
.toLowerCase()
}
function findDuplicateHerbNamesLocal(): string[] {
const map = new Map<string, number>()
for (const h of editForm.herbs) {
const key = normalizeHerbNameLocal(h?.name)
if (!key) continue
map.set(key, (map.get(key) ?? 0) + 1)
}
return [...map.entries()]
.filter(([, c]) => c > 1)
.map(([name]) => name)
}
const loadLibraryList = async () => {
const doctorId = libraryDoctorId.value
if (!doctorId) {
feedback.msgWarning('无法确定开方医师,无法加载处方库')
libraryList.value = []
libraryTotal.value = 0
return
}
libraryLoading.value = true
try {
const res: any = await prescriptionLibraryLists({
page_no: libraryPage.value,
page_size: libraryPageSize.value,
prescription_name: librarySearchName.value,
is_public: '',
creator_id: doctorId
})
libraryList.value = res?.lists || []
libraryTotal.value = res?.count || 0
} catch (e) {
console.error(e)
feedback.msgError('加载处方库失败')
} finally {
libraryLoading.value = false
}
}
const searchLibrary = () => {
libraryPage.value = 1
loadLibraryList()
}
const openLibraryDialog = () => {
const doctorId = libraryDoctorId.value
if (!doctorId) {
feedback.msgWarning('无法确定开方医师,无法从处方库导入')
return
}
showLibraryDialog.value = true
}
const handleSelectLibraryRow = (row: any) => {
handleImportLibrary(row)
}
const handleImportLibrary = (row: any) => {
if (!row.herbs || row.herbs.length === 0) {
feedback.msgWarning('该处方没有药材信息')
return
}
const imported = JSON.parse(JSON.stringify(row.herbs)) as Array<{ name: string; dosage: number }>
editForm.herbs = imported
if (findDuplicateHerbNamesLocal().length) {
feedback.msgWarning('导入的处方中存在重复药名,请合并剂量或删除多余行')
}
feedback.msgSuccess(`已导入处方「${row.prescription_name}」,共${imported.length}味药材`)
showLibraryDialog.value = false
}
watch(showLibraryDialog, (open) => {
if (open) {
librarySearchName.value = ''
libraryPage.value = 1
loadLibraryList()
}
})
// 添加药材
const addHerb = () => {
editForm.herbs.push({
@@ -2147,6 +2349,8 @@ const resetForm = () => {
editForm.audit_by_name = ''
editForm.audit_remark = ''
editForm.diagnosis_id = 0
editForm.creator_id = Number(userStore.userInfo?.id) || 0
editForm.is_system_auto = 0
editForm.business_prescription_audit_rejected = 0
editForm.business_prescription_audit_remark = ''
}
@@ -2249,6 +2453,8 @@ const handleEdit = (row: any) => {
editForm.audit_by_name = row.audit_by_name || ''
editForm.audit_remark = row.audit_remark || ''
editForm.diagnosis_id = row.diagnosis_id ?? 0
editForm.creator_id = Number(row.creator_id) > 0 ? Number(row.creator_id) : 0
editForm.is_system_auto = Number(row.is_system_auto) === 1 ? 1 : 0
editForm.business_prescription_audit_rejected = Number(row.business_prescription_audit_rejected) === 1 ? 1 : 0
editForm.business_prescription_audit_remark = String(row.business_prescription_audit_remark || '')
@@ -2336,9 +2542,6 @@ onMounted(async () => {
} catch {
/* 已登录页仍可无用户信息,保持默认筛选 */
}
if (userCanAudit()) {
formData.audit_filter = 'pending'
}
getLists()
})
</script>