Merge branch 'master' into chufang-5-8
This commit is contained in:
@@ -480,6 +480,11 @@ export function prescriptionOrderLogs(params: { id: number }) {
|
||||
return request.get({ url: '/tcm.prescriptionOrder/logs', params })
|
||||
}
|
||||
|
||||
/** 修改订单金额 */
|
||||
export function prescriptionOrderUpdateAmount(params: { id: number; amount: number }) {
|
||||
return request.post({ url: '/tcm.prescriptionOrder/updateAmount', params })
|
||||
}
|
||||
|
||||
// ========== 处方库 ==========
|
||||
|
||||
// 处方库列表
|
||||
|
||||
@@ -2138,6 +2138,22 @@ const rxOutPelletText = computed(() => {
|
||||
|
||||
function computeOutPellet(v: any): string {
|
||||
if (!v) return ''
|
||||
if ((v.prescription_type || '浓缩水丸') === '浓缩水丸') {
|
||||
const days = Number(v.medication_days ?? v.usage_days ?? v.dose_count)
|
||||
const times = Number(v.times_per_day)
|
||||
const doseG = Number(v.dosage_amount)
|
||||
const bags = Number(v.dosage_bag_count) > 0 ? Number(v.dosage_bag_count) : 1
|
||||
if (
|
||||
Number.isFinite(days) &&
|
||||
Number.isFinite(times) &&
|
||||
Number.isFinite(doseG) &&
|
||||
days > 0 &&
|
||||
times > 0 &&
|
||||
doseG > 0
|
||||
) {
|
||||
return formatNum(days * times * doseG * bags)
|
||||
}
|
||||
}
|
||||
const explicit = v.out_pellet || v.total_weight
|
||||
if (explicit && Number(explicit) > 0) return formatNum(Number(explicit))
|
||||
const list = slipHerbsList.value
|
||||
@@ -3150,9 +3166,14 @@ const handleEdit = async (row: any) => {
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate()
|
||||
|
||||
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
} catch {
|
||||
// Element Plus:校验失败会 reject,表单项已展示错误,勿再向外抛成 Uncaught
|
||||
return
|
||||
}
|
||||
|
||||
// 验证药材
|
||||
if (!editForm.herbs || editForm.herbs.length === 0) {
|
||||
feedback.msgError('请至少添加一味药材')
|
||||
|
||||
@@ -667,7 +667,19 @@
|
||||
<el-row :gutter="16" class="mb-5">
|
||||
<el-col :xs="12" :sm="6">
|
||||
<el-card shadow="never" class="stat-card border border-gray-100 bg-gray-50/50">
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">总金额</div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="stat-title text-gray-500 text-xs">总金额</div>
|
||||
<el-button
|
||||
v-if="canUpdateAmount(detailData)"
|
||||
v-perms="['tcm.prescriptionOrder/updateAmount']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
@click="openUpdateAmount"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="stat-value text-red-500 font-bold text-xl">¥{{ detailData.amount }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -1223,6 +1235,48 @@
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog
|
||||
v-model="updateAmountVisible"
|
||||
title="修改订单金额"
|
||||
width="420px"
|
||||
destroy-on-close
|
||||
:close-on-click-modal="false"
|
||||
@closed="resetUpdateAmountDialog"
|
||||
>
|
||||
<el-form
|
||||
ref="updateAmountFormRef"
|
||||
:model="updateAmountForm"
|
||||
:rules="updateAmountRules"
|
||||
label-width="96px"
|
||||
class="pr-2"
|
||||
@submit.prevent="submitUpdateAmount"
|
||||
>
|
||||
<el-form-item label="当前金额">
|
||||
<div class="text-sm text-gray-700 font-medium">¥{{ formatMoney(detailData?.amount) }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="新金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="updateAmountForm.amount"
|
||||
:min="0.01"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w-full"
|
||||
placeholder="请输入新金额"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="text-xs text-gray-400 pl-[96px] -mt-1 leading-relaxed">
|
||||
已完成或已取消订单不可修改。提交成功后会刷新详情与操作日志。
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="updateAmountVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="updateAmountSaving" @click="submitUpdateAmount">
|
||||
确认修改
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 编辑(分步向导与「创建业务订单」弹窗统一) -->
|
||||
<el-dialog
|
||||
v-model="editVisible"
|
||||
@@ -2332,6 +2386,7 @@ import {
|
||||
prescriptionOrderLogisticsTrace,
|
||||
prescriptionOrderShip,
|
||||
prescriptionOrderLogs,
|
||||
prescriptionOrderUpdateAmount,
|
||||
prescriptionOrderAddPayOrder,
|
||||
prescriptionOrderComplete,
|
||||
prescriptionOrderRevokeRxAudit,
|
||||
@@ -3107,6 +3162,12 @@ function canQuickTrackRow(row: { fulfillment_status?: number }) {
|
||||
return fs === 5 || fs === 6
|
||||
}
|
||||
|
||||
function canUpdateAmount(row: { id?: number; fulfillment_status?: number } | null | undefined) {
|
||||
if (!row?.id) return false
|
||||
const fs = Number(row.fulfillment_status)
|
||||
return fs !== 3 && fs !== 4
|
||||
}
|
||||
|
||||
function canUploadGancaoRow(row: {
|
||||
prescription_audit_status?: number
|
||||
gancao_reciperl_order_no?: string
|
||||
@@ -3388,6 +3449,29 @@ const logisticsTracePayload = ref<Record<string, any> | null>(null)
|
||||
const logisticsTracePhoneTail = ref('')
|
||||
|
||||
const detailLogs = ref<any[]>([])
|
||||
const updateAmountVisible = ref(false)
|
||||
const updateAmountSaving = ref(false)
|
||||
const updateAmountFormRef = ref<FormInstance>()
|
||||
const updateAmountForm = reactive({
|
||||
id: 0,
|
||||
amount: undefined as number | undefined
|
||||
})
|
||||
const updateAmountRules: FormRules = {
|
||||
amount: [
|
||||
{ required: true, message: '请输入订单金额', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule, value, callback) => {
|
||||
const num = Number(value)
|
||||
if (!Number.isFinite(num) || num <= 0) {
|
||||
callback(new Error('订单金额必须大于0'))
|
||||
return
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function canViewPrescriptionOrderLogs() {
|
||||
const p = userStore.perms || []
|
||||
@@ -3423,6 +3507,7 @@ function logActionText(act: string) {
|
||||
revoke_pay_audit: '撤回支付审核',
|
||||
gancao_submit: '甘草下单',
|
||||
patch_rx_patient: '处方患者信息',
|
||||
update_amount: '修改订单金额',
|
||||
complete: '完成订单'
|
||||
}
|
||||
return m[act] || act
|
||||
@@ -3507,6 +3592,24 @@ function resetPatchRxPatientForm() {
|
||||
patchRxPatientForm.phone = ''
|
||||
}
|
||||
|
||||
function resetUpdateAmountDialog() {
|
||||
updateAmountForm.id = 0
|
||||
updateAmountForm.amount = undefined
|
||||
updateAmountFormRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
function openUpdateAmount() {
|
||||
const row = detailData.value
|
||||
if (!canUpdateAmount(row)) {
|
||||
feedback.msgWarning('当前订单状态不允许修改金额')
|
||||
return
|
||||
}
|
||||
updateAmountForm.id = Number(row?.id) || 0
|
||||
updateAmountForm.amount = Number(row?.amount) || undefined
|
||||
updateAmountVisible.value = true
|
||||
nextTick(() => updateAmountFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
async function refreshCurrentPrescriptionOrderDetail() {
|
||||
const id = detailData.value?.id
|
||||
if (!id) return
|
||||
@@ -3546,6 +3649,37 @@ async function submitPatchRxPatient() {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitUpdateAmount() {
|
||||
const form = updateAmountFormRef.value
|
||||
if (!form) return
|
||||
try {
|
||||
await form.validate()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
if (!canUpdateAmount(detailData.value)) {
|
||||
feedback.msgWarning('当前订单状态不允许修改金额')
|
||||
return
|
||||
}
|
||||
const orderId = updateAmountForm.id
|
||||
updateAmountSaving.value = true
|
||||
try {
|
||||
await prescriptionOrderUpdateAmount({
|
||||
id: orderId,
|
||||
amount: Number(updateAmountForm.amount)
|
||||
})
|
||||
feedback.msgSuccess('修改成功')
|
||||
updateAmountVisible.value = false
|
||||
await refreshCurrentPrescriptionOrderDetail()
|
||||
await fetchLogs(orderId)
|
||||
getLists()
|
||||
} catch {
|
||||
/* 拦截器已提示 */
|
||||
} finally {
|
||||
updateAmountSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function openDetail(id: number) {
|
||||
// 修复 Bug:显式彻底清空缓存,防止前一次弹窗的数据残留
|
||||
detailData.value = null
|
||||
@@ -4567,13 +4701,14 @@ const slipPerBagDosageText = computed(() => {
|
||||
const slipPillGrams = computed(() => {
|
||||
const d = prescriptionViewData.value
|
||||
if (!d || (d.prescription_type || '浓缩水丸') !== '浓缩水丸') return null
|
||||
/** 用药疗程以业务订单 medication_days 为准,缺省时回退处方 usage_days / 剂数 */
|
||||
/** 用药疗程以业务订单 medication_days 为准,缺省时回退处方 usage_days / 剂数;出丸 = 每袋用量×袋数×每天次数×服用天数 */
|
||||
const days = Number(d.medication_days ?? d.usage_days ?? d.dose_count)
|
||||
const times = Number(d.times_per_day)
|
||||
const doseG = Number(d.dosage_amount)
|
||||
const bags = Number(d.dosage_bag_count) > 0 ? Number(d.dosage_bag_count) : 1
|
||||
if (!Number.isFinite(days) || !Number.isFinite(times) || !Number.isFinite(doseG)) return null
|
||||
if (days <= 0 || times <= 0 || doseG <= 0) return null
|
||||
return days * times * doseG
|
||||
return days * times * doseG * bags
|
||||
})
|
||||
|
||||
/* ============================================================
|
||||
@@ -4684,7 +4819,7 @@ const rxUsageText = computed(() => {
|
||||
return seg.join(', ')
|
||||
})
|
||||
|
||||
/** 出丸:优先用 slipPillGrams(按医嘱天数·次数·每包克数),否则按药材总量×剂数 */
|
||||
/** 出丸:优先用 slipPillGrams(每袋用量×袋数×每天次数×服用天数),否则按药材总量×剂数 */
|
||||
const rxOutPelletGrams = computed(() => {
|
||||
const pill = slipPillGrams.value
|
||||
if (typeof pill === 'number' && isFinite(pill) && pill > 0) return formatNum(pill)
|
||||
|
||||
@@ -677,7 +677,19 @@
|
||||
<el-row :gutter="16" class="mb-5">
|
||||
<el-col :xs="12" :sm="6">
|
||||
<el-card shadow="never" class="stat-card border border-gray-100 bg-gray-50/50">
|
||||
<div class="stat-title text-gray-500 text-xs mb-1">总金额</div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<div class="stat-title text-gray-500 text-xs">总金额</div>
|
||||
<el-button
|
||||
v-if="canUpdateAmount(detailData)"
|
||||
v-perms="['tcm.prescriptionOrder/updateAmount']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
@click="openUpdateAmount"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="stat-value text-red-500 font-bold text-xl">¥{{ detailData.amount }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -1221,6 +1233,47 @@
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog
|
||||
v-model="updateAmountVisible"
|
||||
title="修改订单金额"
|
||||
width="92%"
|
||||
destroy-on-close
|
||||
:close-on-click-modal="false"
|
||||
@closed="resetUpdateAmountDialog"
|
||||
>
|
||||
<el-form
|
||||
ref="updateAmountFormRef"
|
||||
:model="updateAmountForm"
|
||||
:rules="updateAmountRules"
|
||||
label-width="84px"
|
||||
@submit.prevent="submitUpdateAmount"
|
||||
>
|
||||
<el-form-item label="当前金额">
|
||||
<div class="text-sm text-gray-700 font-medium">¥{{ formatMoney(detailData?.amount) }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="新金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="updateAmountForm.amount"
|
||||
:min="0.01"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w-full"
|
||||
placeholder="请输入新金额"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="text-xs text-gray-400 pl-[84px] -mt-1 leading-relaxed">
|
||||
已完成或已取消订单不可修改。提交成功后会刷新详情与操作日志。
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="updateAmountVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="updateAmountSaving" @click="submitUpdateAmount">
|
||||
确认修改
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 编辑(分步向导与「创建业务订单」弹窗统一) -->
|
||||
<el-dialog
|
||||
v-model="editVisible"
|
||||
@@ -2342,6 +2395,7 @@ import {
|
||||
prescriptionOrderLogisticsTrace,
|
||||
prescriptionOrderShip,
|
||||
prescriptionOrderLogs,
|
||||
prescriptionOrderUpdateAmount,
|
||||
prescriptionOrderAddPayOrder,
|
||||
prescriptionOrderComplete,
|
||||
prescriptionOrderRevokeRxAudit,
|
||||
@@ -3133,6 +3187,12 @@ function handleCardMoreCommand(cmd: string, row: Record<string, any>) {
|
||||
else if (cmd === 'withdraw') confirmWithdraw(row as any)
|
||||
}
|
||||
|
||||
function canUpdateAmount(row: { id?: number; fulfillment_status?: number } | null | undefined) {
|
||||
if (!row?.id) return false
|
||||
const fs = Number(row.fulfillment_status)
|
||||
return fs !== 3 && fs !== 4
|
||||
}
|
||||
|
||||
const detailVisible = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
const detailData = ref<Record<string, any> | null>(null)
|
||||
@@ -3344,6 +3404,29 @@ const logisticsTracePayload = ref<Record<string, any> | null>(null)
|
||||
const logisticsTracePhoneTail = ref('')
|
||||
|
||||
const detailLogs = ref<any[]>([])
|
||||
const updateAmountVisible = ref(false)
|
||||
const updateAmountSaving = ref(false)
|
||||
const updateAmountFormRef = ref<FormInstance>()
|
||||
const updateAmountForm = reactive({
|
||||
id: 0,
|
||||
amount: undefined as number | undefined
|
||||
})
|
||||
const updateAmountRules: FormRules = {
|
||||
amount: [
|
||||
{ required: true, message: '请输入订单金额', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule, value, callback) => {
|
||||
const num = Number(value)
|
||||
if (!Number.isFinite(num) || num <= 0) {
|
||||
callback(new Error('订单金额必须大于0'))
|
||||
return
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function canViewPrescriptionOrderLogs() {
|
||||
const p = userStore.perms || []
|
||||
@@ -3379,6 +3462,7 @@ function logActionText(act: string) {
|
||||
revoke_pay_audit: '撤回支付审核',
|
||||
gancao_submit: '甘草下单',
|
||||
patch_rx_patient: '处方患者信息',
|
||||
update_amount: '修改订单金额',
|
||||
complete: '完成订单'
|
||||
}
|
||||
return m[act] || act
|
||||
@@ -3463,6 +3547,24 @@ function resetPatchRxPatientForm() {
|
||||
patchRxPatientForm.phone = ''
|
||||
}
|
||||
|
||||
function resetUpdateAmountDialog() {
|
||||
updateAmountForm.id = 0
|
||||
updateAmountForm.amount = undefined
|
||||
updateAmountFormRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
function openUpdateAmount() {
|
||||
const row = detailData.value
|
||||
if (!canUpdateAmount(row)) {
|
||||
feedback.msgWarning('当前订单状态不允许修改金额')
|
||||
return
|
||||
}
|
||||
updateAmountForm.id = Number(row?.id) || 0
|
||||
updateAmountForm.amount = Number(row?.amount) || undefined
|
||||
updateAmountVisible.value = true
|
||||
nextTick(() => updateAmountFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
async function refreshCurrentPrescriptionOrderDetail() {
|
||||
const id = detailData.value?.id
|
||||
if (!id) return
|
||||
@@ -3502,6 +3604,37 @@ async function submitPatchRxPatient() {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitUpdateAmount() {
|
||||
const form = updateAmountFormRef.value
|
||||
if (!form) return
|
||||
try {
|
||||
await form.validate()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
if (!canUpdateAmount(detailData.value)) {
|
||||
feedback.msgWarning('当前订单状态不允许修改金额')
|
||||
return
|
||||
}
|
||||
const orderId = updateAmountForm.id
|
||||
updateAmountSaving.value = true
|
||||
try {
|
||||
await prescriptionOrderUpdateAmount({
|
||||
id: orderId,
|
||||
amount: Number(updateAmountForm.amount)
|
||||
})
|
||||
feedback.msgSuccess('修改成功')
|
||||
updateAmountVisible.value = false
|
||||
await refreshCurrentPrescriptionOrderDetail()
|
||||
await fetchLogs(orderId)
|
||||
getLists()
|
||||
} catch {
|
||||
/* 拦截器已提示 */
|
||||
} finally {
|
||||
updateAmountSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function openDetail(id: number) {
|
||||
// 修复 Bug:显式彻底清空缓存,防止前一次弹窗的数据残留
|
||||
detailData.value = null
|
||||
@@ -4520,13 +4653,14 @@ const slipPerBagDosageText = computed(() => {
|
||||
const slipPillGrams = computed(() => {
|
||||
const d = prescriptionViewData.value
|
||||
if (!d || (d.prescription_type || '浓缩水丸') !== '浓缩水丸') return null
|
||||
/** 用药疗程以业务订单 medication_days 为准,缺省时回退处方 usage_days / 剂数 */
|
||||
/** 用药疗程以业务订单 medication_days 为准,缺省时回退处方 usage_days / 剂数;出丸 = 每袋用量×袋数×每天次数×服用天数 */
|
||||
const days = Number(d.medication_days ?? d.usage_days ?? d.dose_count)
|
||||
const times = Number(d.times_per_day)
|
||||
const doseG = Number(d.dosage_amount)
|
||||
const bags = Number(d.dosage_bag_count) > 0 ? Number(d.dosage_bag_count) : 1
|
||||
if (!Number.isFinite(days) || !Number.isFinite(times) || !Number.isFinite(doseG)) return null
|
||||
if (days <= 0 || times <= 0 || doseG <= 0) return null
|
||||
return days * times * doseG
|
||||
return days * times * doseG * bags
|
||||
})
|
||||
|
||||
/* ============================================================
|
||||
@@ -4637,7 +4771,7 @@ const rxUsageText = computed(() => {
|
||||
return seg.join(', ')
|
||||
})
|
||||
|
||||
/** 出丸:优先用 slipPillGrams(按医嘱天数·次数·每包克数),否则按药材总量×剂数 */
|
||||
/** 出丸:优先用 slipPillGrams(每袋用量×袋数×每天次数×服用天数),否则按药材总量×剂数 */
|
||||
const rxOutPelletGrams = computed(() => {
|
||||
const pill = slipPillGrams.value
|
||||
if (typeof pill === 'number' && isFinite(pill) && pill > 0) return formatNum(pill)
|
||||
|
||||
Reference in New Issue
Block a user