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
@@ -98,9 +98,16 @@
v-for="(herb, index) in formData.herbs"
:key="'herb-' + index"
class="herb-editor-card"
:class="{ 'herb-editor-card--dup': isDuplicateHerbName(index) }"
>
<div class="herb-editor-card__title">中药 {{ index + 1 }}</div>
<MedicineNameSelect v-model="herb.name" class="herb-editor-card__select" />
<div
v-if="isDuplicateHerbName(index)"
class="herb-editor-card__dup-hint text-amber-600 text-xs mb-1"
>
该药名与其他行重复请合并剂量或删除多余行
</div>
<div class="herb-editor-card__row">
<el-input-number
v-model="herb.dosage"
@@ -547,15 +554,24 @@
<el-icon><Document /></el-icon>
下载PDF
</el-button>
<el-button
<el-tooltip
v-if="savedPrescription.void_status !== 1 && !approvedPreviewOnly"
type="danger"
plain
:loading="voiding"
@click="handleVoid"
:disabled="!hasPrescriptionOrderBlockVoid"
content="该处方已存在业务订单,无法作废,请前往已开处方里修改"
placement="top"
>
作废处方
</el-button>
<span class="inline-block">
<el-button
type="danger"
plain
:disabled="hasPrescriptionOrderBlockVoid"
:loading="voiding"
@click="handleVoid"
>
作废处方
</el-button>
</span>
</el-tooltip>
<el-button v-if="!approvedPreviewOnly" @click="handleNewPrescription">新建处方</el-button>
<el-button @click="handleClose">关闭</el-button>
</div>
@@ -714,6 +730,13 @@ const approvedPreviewOnly = computed(() => {
return Number(s.audit_status) === 1 && Number(s.void_status) !== 1
})
/** 已有关联业务订单(与列表 has_prescription_order 一致)则禁止作废 */
const hasPrescriptionOrderBlockVoid = computed(() => {
const s = savedPrescription.value
if (!s) return false
return Number(s.has_prescription_order) === 1
})
const drawerTitle = computed(() => (approvedPreviewOnly.value ? '查看处方' : '中医处方单'))
// 处方库相关
@@ -1084,6 +1107,33 @@ const initSignatureCanvas = () => {
ctx.lineJoin = 'round'
}
/** 药名去首尾空格后比较,避免「 黄芪 」与「黄芪」判成不同 */
function normalizeHerbName(name: string | undefined): string {
return (name ?? '').trim()
}
/** 当前行药名是否与其他行重复(非空且出现次数大于 1) */
function isDuplicateHerbName(index: number): boolean {
const herbs = formData.herbs
const key = normalizeHerbName(herbs[index]?.name)
if (!key) return false
let count = 0
for (let i = 0; i < herbs.length; i++) {
if (normalizeHerbName(herbs[i]?.name) === key) count++
}
return count > 1
}
function findDuplicateHerbNames(): string[] {
const map = new Map<string, number>()
for (const h of formData.herbs) {
const key = normalizeHerbName(h?.name)
if (!key) continue
map.set(key, (map.get(key) ?? 0) + 1)
}
return [...map.entries()].filter(([, c]) => c > 1).map(([name]) => name)
}
const handleAddHerb = () => {
formData.herbs.push({ name: '', dosage: 6 })
}
@@ -1132,6 +1182,10 @@ const handleImportLibrary = (row: any) => {
const importedHerbs = JSON.parse(JSON.stringify(row.herbs))
formData.herbs = importedHerbs
if (findDuplicateHerbNames().length) {
feedback.msgWarning('导入的处方中存在重复药名,请合并剂量或删除多余行')
}
feedback.msgSuccess(`已导入处方「${row.prescription_name}」,共${importedHerbs.length}味药材`)
showLibraryDialog.value = false
}
@@ -1174,6 +1228,11 @@ const handleSave = async () => {
feedback.msgWarning('请至少添加一味中药')
return
}
const dupNames = findDuplicateHerbNames()
if (dupNames.length) {
feedback.msgWarning(`存在重复药名:${dupNames.join('、')},请合并剂量或删除多余行后再保存`)
return
}
for (const h of formData.herbs) {
if (!h.name?.trim()) {
feedback.msgWarning('请填写中药名称')
@@ -1252,6 +1311,10 @@ const formatVoidTime = (ts: number | null | undefined) => {
const handleVoid = async () => {
const id = savedPrescription.value?.id
if (!id) return
if (Number(savedPrescription.value?.has_prescription_order) === 1) {
feedback.msgWarning('该处方已存在业务订单,无法作废')
return
}
try {
await feedback.confirm('确定要作废该处方吗?作废后不可恢复。')
voiding.value = true
@@ -1453,6 +1516,11 @@ defineExpose({
border-radius: 6px;
}
.herb-editor-card--dup {
border-color: var(--el-color-warning);
background: var(--el-color-warning-light-9);
}
.herb-editor-card__title {
font-size: 12px;
color: #909399;