更新
This commit is contained in:
@@ -799,50 +799,50 @@
|
||||
<el-dialog
|
||||
v-model="createOrderVisible"
|
||||
title="创建业务订单"
|
||||
width="850px"
|
||||
width="940px"
|
||||
top="4vh"
|
||||
:close-on-click-modal="false"
|
||||
@closed="resetCreateOrderForm"
|
||||
class="create-order-dialog"
|
||||
>
|
||||
<!-- 关联处方信息卡片 -->
|
||||
<div v-if="createOrderPrescription" class="mb-4 rounded-lg border border-blue-100 bg-blue-50 p-3">
|
||||
<div class="flex items-start gap-2">
|
||||
<div class="flex-shrink-0 mt-0.5">
|
||||
<svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="text-xs font-medium text-blue-900 mb-0.5">关联处方</div>
|
||||
<div class="text-xs text-blue-700">
|
||||
ID {{ createOrderPrescription.id }}
|
||||
<span v-if="createOrderPrescription.sn"> · {{ createOrderPrescription.sn }}</span>
|
||||
· {{ createOrderPrescription.patient_name || '—' }}
|
||||
</div>
|
||||
<div class="text-xs text-blue-600 mt-1 line-clamp-1">
|
||||
{{ createOrderHerbSummary }}
|
||||
<div class="create-order-dialog__inner">
|
||||
<!-- 关联处方:卡片式信息区,层次更清晰 -->
|
||||
<div v-if="createOrderPrescription" class="create-order-rx-card">
|
||||
<div class="create-order-rx-card__head">
|
||||
<span class="create-order-rx-card__badge">关联处方</span>
|
||||
<div class="create-order-rx-card__meta">
|
||||
<span class="create-order-rx-card__id">#{{ createOrderPrescription.id }}</span>
|
||||
<span v-if="createOrderPrescription.sn" class="create-order-rx-card__sn">{{ createOrderPrescription.sn }}</span>
|
||||
<span class="create-order-rx-card__patient">{{ createOrderPrescription.patient_name || '—' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-tooltip :content="createOrderHerbSummary" placement="bottom" :show-after="300">
|
||||
<div class="create-order-rx-card__herbs">{{ createOrderHerbSummary }}</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form
|
||||
ref="createOrderFormRef"
|
||||
:model="createOrderForm"
|
||||
:rules="createOrderRules"
|
||||
label-width="90px"
|
||||
class="create-order-form"
|
||||
>
|
||||
<!-- 患者与收货信息 -->
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
<span>患者与收货</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<el-row :gutter="16">
|
||||
<el-steps
|
||||
:active="createOrderStep"
|
||||
finish-status="success"
|
||||
align-center
|
||||
class="create-order-steps"
|
||||
>
|
||||
<el-step title="患者与收货" description="诊单与物流地址" />
|
||||
<el-step title="服务与支付单" description="套餐与关联收款" />
|
||||
<el-step title="金额与确认" description="费用与备注" />
|
||||
</el-steps>
|
||||
|
||||
<p class="create-order-step-lead">{{ createOrderStepLead }}</p>
|
||||
|
||||
<el-form
|
||||
ref="createOrderFormRef"
|
||||
:model="createOrderForm"
|
||||
:rules="createOrderRules"
|
||||
label-width="108px"
|
||||
class="create-order-form"
|
||||
>
|
||||
<div v-show="createOrderStep === 0" class="create-order-step-panel">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="诊单患者" prop="patient_id">
|
||||
<el-select
|
||||
@@ -866,12 +866,12 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货人" prop="recipient_name">
|
||||
<el-input v-model="createOrderForm.recipient_name" placeholder="收货人姓名" maxlength="50" />
|
||||
<el-input v-model="createOrderForm.recipient_name" placeholder="姓名" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="收货手机" prop="recipient_phone">
|
||||
<el-input v-model="createOrderForm.recipient_phone" placeholder="用于物流联系" maxlength="20" />
|
||||
<el-input v-model="createOrderForm.recipient_phone" placeholder="物流联系" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
@@ -880,7 +880,7 @@
|
||||
v-model="createOrderForm.region"
|
||||
:options="regionOptions"
|
||||
:props="{ value: 'name', label: 'name', children: 'children', emitPath: true, checkStrictly: false }"
|
||||
placeholder="请选择省/市/区"
|
||||
placeholder="省 / 市 / 区"
|
||||
clearable
|
||||
filterable
|
||||
class="w-full"
|
||||
@@ -893,45 +893,39 @@
|
||||
<el-input
|
||||
v-model="createOrderForm.shipping_address"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入街道、门牌号等详细地址"
|
||||
:rows="3"
|
||||
placeholder="街道、小区、门牌号等详细地址"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 服务信息 -->
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
||||
</svg>
|
||||
<span>服务信息</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否复诊">
|
||||
<div v-show="createOrderStep === 1" class="create-order-step-panel">
|
||||
<el-row :gutter="20">
|
||||
<el-col :xs="24" :sm="8">
|
||||
<el-form-item label="复诊">
|
||||
<el-switch v-model="createOrderForm.is_follow_up" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="用药疗程">
|
||||
<el-input-number
|
||||
v-model="createOrderForm.medication_days"
|
||||
:min="1"
|
||||
:max="999"
|
||||
:step="1"
|
||||
placeholder="天数"
|
||||
class="w-full"
|
||||
/>
|
||||
<el-col :xs="24" :sm="8">
|
||||
<el-form-item label="疗程" class="create-order-form-item--inline-num">
|
||||
<div class="flex items-center gap-1 w-full">
|
||||
<el-input-number
|
||||
v-model="createOrderForm.medication_days"
|
||||
:min="1"
|
||||
:max="999"
|
||||
:step="1"
|
||||
controls-position="right"
|
||||
class="flex-1 min-w-0"
|
||||
/>
|
||||
<span class="create-order-unit-suffix">天</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :xs="24" :sm="8">
|
||||
<el-form-item label="上次医生">
|
||||
<el-input v-model="createOrderForm.prev_staff" placeholder="可选" maxlength="100" />
|
||||
</el-form-item>
|
||||
@@ -943,121 +937,98 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务套餐">
|
||||
<el-input v-model="createOrderForm.service_package" placeholder="可选" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 物流信息 -->
|
||||
<!-- <div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
||||
</svg>
|
||||
<span>物流信息</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="快递公司">
|
||||
<el-select v-model="createOrderForm.express_company" placeholder="查物流用" class="w-full">
|
||||
<el-option label="自动识别" value="auto" />
|
||||
<el-option label="顺丰速运" value="sf" />
|
||||
<el-option label="京东快递" value="jd" />
|
||||
<el-option label="极兔速递" value="jt" />
|
||||
<el-select
|
||||
v-model="createOrderForm.service_package"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择服务套餐"
|
||||
clearable
|
||||
class="w-full"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in servicePackageOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="快递单号">
|
||||
<el-input v-model="createOrderForm.tracking_number" placeholder="可创建后补录" maxlength="80" />
|
||||
<el-col :span="24">
|
||||
<el-form-item label="关联支付单" prop="pay_order_ids">
|
||||
<el-select
|
||||
v-model="createOrderForm.pay_order_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
:placeholder="
|
||||
createOrderDepositMin > 0
|
||||
? '请至少选择一笔本诊单支付单(已开启门槛)'
|
||||
: '多选本诊单支付单(可选)'
|
||||
"
|
||||
:loading="createOrderPaidOrdersLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="o in createOrderPaidOrders"
|
||||
:key="o.id"
|
||||
:label="`${o.order_no} · ¥${o.amount} · ${formatPoCategory(o.order_type)}`"
|
||||
:value="o.id"
|
||||
class="!h-auto py-1.5"
|
||||
>
|
||||
<div class="flex flex-col gap-0.5" style="line-height: normal;">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium text-[13px] text-gray-800">{{ o.order_no }}</span>
|
||||
<span class="text-orange-500 font-medium ml-4">¥{{ o.amount }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs text-gray-400 mt-1">
|
||||
<span class="truncate pr-2">{{ formatPoCategory(o.order_type) }}<template v-if="o.remark"> · {{ o.remark }}</template></span>
|
||||
<span class="shrink-0">{{ String(o.create_time || '').substring(0, 16) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="create-order-pay-hint text-gray-500">
|
||||
<template v-if="createOrderDepositMin > 0">
|
||||
<span class="text-amber-600 font-medium">当前已开启关联支付门槛(¥{{ formatPoDepositMoney(createOrderDepositMin) }}),须至少选择一笔支付单。</span>
|
||||
<span class="mx-1"> </span>
|
||||
</template>
|
||||
主管/本诊单医助可见全部支付单;否则仅本人收款单。已被占用的支付单不列出。
|
||||
<el-tooltip
|
||||
content="主管或本诊单医助可见该诊单全部支付单(待支付/已支付),否则仅本人创建的收款单。已被其他有效业务订单占用的支付单不会出现在此列表。"
|
||||
placement="top"
|
||||
>
|
||||
<span class="text-primary cursor-help ml-0.5">详情</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 关联收款 -->
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
<span>关联收款</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<el-form-item label="关联支付单">
|
||||
<el-select
|
||||
v-model="createOrderForm.pay_order_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="多选本诊单下的支付单"
|
||||
:loading="createOrderPaidOrdersLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="o in createOrderPaidOrders"
|
||||
:key="o.id"
|
||||
:label="`${o.order_no} · ¥${o.amount} · ${formatPoCategory(o.order_type)}`"
|
||||
:value="o.id"
|
||||
class="!h-auto py-1.5"
|
||||
>
|
||||
<div class="flex flex-col gap-0.5" style="line-height: normal;">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium text-[13px] text-gray-800">{{ o.order_no }}</span>
|
||||
<span class="text-orange-500 font-medium ml-4">¥{{ o.amount }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs text-gray-400 mt-1">
|
||||
<span class="truncate pr-2">{{ formatPoCategory(o.order_type) }}<template v-if="o.remark"> · {{ o.remark }}</template></span>
|
||||
<span class="shrink-0">{{ String(o.create_time || '').substring(0, 16) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="text-xs text-gray-500 mt-1.5 leading-relaxed">
|
||||
主管或本诊单医助可见该诊单全部支付单(待支付/已支付),否则仅本人创建的收款单。已被其他有效业务订单占用的支付单不会出现在此列表。
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 金额信息 -->
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span>金额信息</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<!-- 金额概览卡片 -->
|
||||
<div class="mb-3 rounded-lg border border-gray-200 bg-gray-50 p-3">
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<div class="text-xs text-gray-500 mb-0.5">定金门槛</div>
|
||||
<div class="text-base font-semibold text-gray-900">
|
||||
¥{{ formatPoDepositMoney(createOrderDepositMin) }}
|
||||
</div>
|
||||
<div class="text-xs text-gray-400 mt-0.5">
|
||||
{{ createOrderDepositMin > 0 ? '订单和支付单总金额须 ≥ 此值' : '未设置' }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs text-gray-500 mb-0.5">已选收款单</div>
|
||||
<div class="text-base font-semibold" :class="createOrderLinkedPaidTotal >= createOrderDepositMin ? 'text-green-600' : 'text-red-600'">
|
||||
¥{{ formatPoDepositMoney(createOrderLinkedPaidTotal) }}
|
||||
</div>
|
||||
<div class="text-xs mt-0.5" :class="createOrderLinkedPaidTotal >= createOrderDepositMin ? 'text-green-600' : 'text-red-600'">
|
||||
{{ createOrderLinkedPaidTotal >= createOrderDepositMin ? '✓ 已达标' : '✗ 未达标' }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="createOrderStep === 2" class="create-order-step-panel">
|
||||
<!-- 横向概览,一屏内更省高度 -->
|
||||
<div
|
||||
class="create-order-deposit-bar"
|
||||
:class="createOrderLinkedPaidTotal >= createOrderDepositMin ? 'is-ok' : 'is-warn'"
|
||||
>
|
||||
<div class="create-order-deposit-bar__cell">
|
||||
<span class="create-order-deposit-bar__label">定金门槛</span>
|
||||
<strong>¥{{ formatPoDepositMoney(createOrderDepositMin) }}</strong>
|
||||
<span class="create-order-deposit-bar__sub">{{ createOrderDepositMin > 0 ? '须 ≥ 此值' : '未设置' }}</span>
|
||||
</div>
|
||||
<div class="create-order-deposit-bar__sep" />
|
||||
<div class="create-order-deposit-bar__cell">
|
||||
<span class="create-order-deposit-bar__label">已选收款</span>
|
||||
<strong>¥{{ formatPoDepositMoney(createOrderLinkedPaidTotal) }}</strong>
|
||||
<span class="create-order-deposit-bar__sub">
|
||||
{{ createOrderLinkedPaidTotal >= createOrderDepositMin ? '已达标' : '未达标' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-row :gutter="20" class="create-order-step-panel__row-after-bar">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="费用类别" prop="fee_type">
|
||||
<el-select v-model="createOrderForm.fee_type" placeholder="请选择" class="w-full">
|
||||
@@ -1072,14 +1043,15 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="订单总金额" prop="amount">
|
||||
<el-form-item label="总金额" prop="amount">
|
||||
<el-input-number
|
||||
v-model="createOrderForm.amount"
|
||||
:min="createOrderAmountInputMin"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
class="w-full"
|
||||
placeholder="业务订单金额(元)"
|
||||
controls-position="right"
|
||||
placeholder="元"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -1091,47 +1063,54 @@
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
class="w-full"
|
||||
placeholder="仅财务角色可见"
|
||||
controls-position="right"
|
||||
placeholder="财务可见"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="createOrderForm.remark_extra"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="选填,对内说明"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 备注 -->
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
|
||||
</svg>
|
||||
<span>备注说明</span>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<el-form-item label="备注补充">
|
||||
<el-input
|
||||
v-model="createOrderForm.remark_extra"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="其他说明(可选)"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xs text-gray-500">
|
||||
<span v-if="createOrderDepositMin > 0" class="text-amber-600">
|
||||
提示:订单金额和关联支付单总金额须 ≥ ¥{{ formatPoDepositMoney(createOrderDepositMin) }}
|
||||
<div class="create-order-footer">
|
||||
<div class="create-order-footer__hint">
|
||||
<span class="create-order-footer__step">第 {{ createOrderStep + 1 }} / 3 步</span>
|
||||
<span v-if="createOrderStep === 2 && createOrderDepositMin > 0" class="create-order-footer__warn">
|
||||
订单金额与关联支付单合计须 ≥ ¥{{ formatPoDepositMoney(createOrderDepositMin) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<el-button @click="createOrderVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="createOrderSubmitLoading" @click="submitCreateOrderFromPrescription">
|
||||
<div class="create-order-footer__actions">
|
||||
<el-button size="large" @click="createOrderVisible = false">取消</el-button>
|
||||
<el-button v-if="createOrderStep > 0" size="large" @click="goCreateOrderPrevStep">上一步</el-button>
|
||||
<el-button
|
||||
v-if="createOrderStep < 2"
|
||||
type="primary"
|
||||
size="large"
|
||||
@click="goCreateOrderNextStep"
|
||||
>
|
||||
下一步
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="createOrderStep === 2"
|
||||
type="primary"
|
||||
size="large"
|
||||
:loading="createOrderSubmitLoading"
|
||||
@click="submitCreateOrderFromPrescription"
|
||||
>
|
||||
创建业务订单
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -1177,6 +1156,7 @@ import {
|
||||
getDoctors
|
||||
} from '@/api/tcm'
|
||||
import { searchPatients as searchPatientsAPI } from '@/api/order'
|
||||
import { getDictData } from '@/api/app'
|
||||
import { roleAll } from '@/api/perms/role'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
@@ -1239,6 +1219,21 @@ const auditLoading = ref(false)
|
||||
|
||||
/** 从消费者处方创建订单 */
|
||||
const createOrderVisible = ref(false)
|
||||
/** 创建订单分步向导:0 患者与收货 / 1 服务与支付单 / 2 金额与确认 */
|
||||
const createOrderStep = ref(0)
|
||||
|
||||
const createOrderStepLead = computed(() => {
|
||||
const texts = [
|
||||
'请核对诊单患者并填写完整收货信息,便于发货与物流联系。',
|
||||
'按需填写服务相关信息,并选择本诊单下需要关联的支付单。',
|
||||
'确认费用类别与订单金额;提交前请对照定金门槛是否已满足。'
|
||||
]
|
||||
return texts[createOrderStep.value] ?? ''
|
||||
})
|
||||
|
||||
/** 第 1 步:患者与收货(分步校验) */
|
||||
const CREATE_ORDER_STEP0_FIELDS = ['patient_id', 'recipient_name', 'recipient_phone', 'region', 'shipping_address'] as const
|
||||
|
||||
const createOrderPrescription = ref<any>(null)
|
||||
const createOrderFormRef = ref<FormInstance>()
|
||||
const createOrderSubmitLoading = ref(false)
|
||||
@@ -1276,7 +1271,7 @@ const createOrderForm = reactive({
|
||||
medication_days: undefined as number | undefined,
|
||||
prev_staff: '',
|
||||
service_channel: '',
|
||||
service_package: '',
|
||||
service_package: [] as string[],
|
||||
express_company: 'auto',
|
||||
tracking_number: '',
|
||||
fee_type: 3,
|
||||
@@ -1289,6 +1284,9 @@ const createOrderForm = reactive({
|
||||
// 省市区数据(简化版,实际项目中应该从 API 获取或使用完整的省市区数据)
|
||||
const regionOptions = ref([])
|
||||
|
||||
/** 服务套餐(字典 server_order,与业务订单编辑一致) */
|
||||
const servicePackageOptions = ref<Array<{ name: string; value: string }>>([])
|
||||
|
||||
// 转换省市区数据格式
|
||||
const transformRegionData = (data: any[]) => {
|
||||
return data.map((province: any) => ({
|
||||
@@ -1418,6 +1416,15 @@ const loadRegionData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadServicePackageOptions = async () => {
|
||||
try {
|
||||
const data = await getDictData({ type: 'server_order' })
|
||||
servicePackageOptions.value = (data?.server_order || []).filter((item: { status?: number }) => item.status !== 0)
|
||||
} catch {
|
||||
servicePackageOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 处理省市区选择变化
|
||||
const handleRegionChange = (value: string[]) => {
|
||||
console.log('选择的省市区:', value)
|
||||
@@ -1444,29 +1451,46 @@ const createOrderAmountInputMin = computed(() => {
|
||||
return 0
|
||||
})
|
||||
|
||||
const createOrderRules: FormRules = {
|
||||
patient_id: [{ required: true, message: '请选择诊单患者', trigger: 'change' }],
|
||||
recipient_name: [{ required: true, message: '请输入收货人', trigger: 'blur' }],
|
||||
recipient_phone: [{ required: true, message: '请输入收货手机', trigger: 'blur' }],
|
||||
region: [{ required: true, message: '请选择省/市/区', trigger: 'change', type: 'array' }],
|
||||
shipping_address: [{ required: true, message: '请输入收货地址', trigger: 'blur' }],
|
||||
fee_type: [{ required: true, message: '请选择费用类别', trigger: 'change' }],
|
||||
amount: [
|
||||
{ required: true, message: '请输入订单金额', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule, v, cb) => {
|
||||
const min = createOrderDepositMin.value
|
||||
const num = Number(v)
|
||||
if (min > 0 && (!Number.isFinite(num) || num < min)) {
|
||||
cb(new Error(`订单金额须大于等于定金门槛 ¥${formatPoDepositMoney(min)}`))
|
||||
return
|
||||
}
|
||||
cb()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
const createOrderRules = computed<FormRules>(() => {
|
||||
const rules: FormRules = {
|
||||
patient_id: [{ required: true, message: '请选择诊单患者', trigger: 'change' }],
|
||||
recipient_name: [{ required: true, message: '请输入收货人', trigger: 'blur' }],
|
||||
recipient_phone: [{ required: true, message: '请输入收货手机', trigger: 'blur' }],
|
||||
region: [{ required: true, message: '请选择省/市/区', trigger: 'change', type: 'array' }],
|
||||
shipping_address: [{ required: true, message: '请输入收货地址', trigger: 'blur' }],
|
||||
fee_type: [{ required: true, message: '请选择费用类别', trigger: 'change' }],
|
||||
amount: [
|
||||
{ required: true, message: '请输入订单金额', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule, v, cb) => {
|
||||
const min = createOrderDepositMin.value
|
||||
const num = Number(v)
|
||||
if (min > 0 && (!Number.isFinite(num) || num < min)) {
|
||||
cb(new Error(`订单金额须大于等于定金门槛 ¥${formatPoDepositMoney(min)}`))
|
||||
return
|
||||
}
|
||||
cb()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
// 与 .env PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT 一致(接口 deposit_min_amount)
|
||||
// 勿在 el-form-item 上设 required,否则会多出一条默认英文「pay_order_ids is required」
|
||||
if (createOrderDepositMin.value > 0) {
|
||||
const depMsg = `已开启关联支付门槛(¥${formatPoDepositMoney(createOrderDepositMin.value)}),请至少选择一笔支付单`
|
||||
rules.pay_order_ids = [
|
||||
{
|
||||
type: 'array',
|
||||
required: true,
|
||||
min: 1,
|
||||
message: depMsg,
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
}
|
||||
return rules
|
||||
})
|
||||
|
||||
const createOrderHerbSummary = computed(() => {
|
||||
const row = createOrderPrescription.value
|
||||
@@ -1477,6 +1501,7 @@ const createOrderHerbSummary = computed(() => {
|
||||
})
|
||||
|
||||
function resetCreateOrderForm() {
|
||||
createOrderStep.value = 0
|
||||
createOrderForm.patient_id = ''
|
||||
createOrderForm.recipient_name = ''
|
||||
createOrderForm.recipient_phone = ''
|
||||
@@ -1485,7 +1510,7 @@ function resetCreateOrderForm() {
|
||||
createOrderForm.medication_days = undefined
|
||||
createOrderForm.prev_staff = ''
|
||||
createOrderForm.service_channel = ''
|
||||
createOrderForm.service_package = ''
|
||||
createOrderForm.service_package = []
|
||||
createOrderForm.express_company = 'auto'
|
||||
createOrderForm.tracking_number = ''
|
||||
createOrderForm.fee_type = 3
|
||||
@@ -1617,8 +1642,32 @@ function onCreateOrderPatientChange(id: number | string) {
|
||||
}
|
||||
}
|
||||
|
||||
function goCreateOrderPrevStep() {
|
||||
if (createOrderStep.value > 0) {
|
||||
createOrderStep.value -= 1
|
||||
}
|
||||
}
|
||||
|
||||
async function goCreateOrderNextStep() {
|
||||
const form = createOrderFormRef.value
|
||||
if (!form) return
|
||||
try {
|
||||
if (createOrderStep.value === 0) {
|
||||
await form.validateField([...CREATE_ORDER_STEP0_FIELDS])
|
||||
} else if (createOrderStep.value === 1 && createOrderDepositMin.value > 0) {
|
||||
await form.validateField(['pay_order_ids'])
|
||||
}
|
||||
if (createOrderStep.value < 2) {
|
||||
createOrderStep.value += 1
|
||||
}
|
||||
} catch {
|
||||
/* 校验未通过,留在当前步 */
|
||||
}
|
||||
}
|
||||
|
||||
async function submitCreateOrderFromPrescription() {
|
||||
if (!createOrderFormRef.value || !createOrderPrescription.value) return
|
||||
if (createOrderStep.value !== 2) return
|
||||
try {
|
||||
await createOrderFormRef.value.validate()
|
||||
createOrderSubmitLoading.value = true
|
||||
@@ -1632,7 +1681,10 @@ async function submitCreateOrderFromPrescription() {
|
||||
is_follow_up: createOrderForm.is_follow_up,
|
||||
prev_staff: createOrderForm.prev_staff || '',
|
||||
service_channel: createOrderForm.service_channel || '',
|
||||
service_package: createOrderForm.service_package || '',
|
||||
service_package:
|
||||
Array.isArray(createOrderForm.service_package) && createOrderForm.service_package.length > 0
|
||||
? createOrderForm.service_package.join(',')
|
||||
: '',
|
||||
express_company: createOrderForm.express_company || 'auto',
|
||||
tracking_number: createOrderForm.tracking_number || '',
|
||||
fee_type: createOrderForm.fee_type,
|
||||
@@ -2268,6 +2320,7 @@ const handleDelete = async (id: number) => {
|
||||
onMounted(async () => {
|
||||
await loadRoleOptions()
|
||||
await loadRegionData()
|
||||
await loadServicePackageOptions()
|
||||
try {
|
||||
const list = await getDoctors()
|
||||
doctorOptions.value = Array.isArray(list) ? list : []
|
||||
@@ -2614,52 +2667,276 @@ onMounted(async () => {
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
/* 创建订单表单样式 */
|
||||
/* 创建业务订单弹窗:宽松留白、默认字号、卡片化信息区 */
|
||||
.create-order-dialog {
|
||||
:deep(.el-dialog__header) {
|
||||
padding: 20px 24px 12px;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__title) {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 8px 24px 20px;
|
||||
max-height: calc(100vh - 200px);
|
||||
overflow-y: auto;
|
||||
padding: 16px 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__footer) {
|
||||
padding: 16px 24px 20px;
|
||||
border-top: 1px solid var(--el-border-color-lighter);
|
||||
background: var(--el-fill-color-blank);
|
||||
}
|
||||
}
|
||||
|
||||
.create-order-form {
|
||||
.form-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.create-order-dialog__inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.create-order-rx-card {
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--el-color-primary-light-5);
|
||||
background: linear-gradient(135deg, var(--el-color-primary-light-9) 0%, var(--el-fill-color-blank) 100%);
|
||||
padding: 16px 18px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
|
||||
}
|
||||
|
||||
.create-order-rx-card__head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.create-order-rx-card__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
background: var(--el-color-primary);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.create-order-rx-card__meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px 12px;
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
|
||||
.create-order-rx-card__id {
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.create-order-rx-card__sn {
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--el-fill-color);
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.create-order-rx-card__patient {
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.create-order-rx-card__herbs {
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
color: var(--el-text-color-secondary);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.create-order-steps {
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 12px 4px;
|
||||
|
||||
:deep(.el-step__title) {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
|
||||
:deep(.el-step__description) {
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
line-height: 1.35;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
:deep(.el-step__head) {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-step.is-horizontal .el-step__line) {
|
||||
top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.create-order-step-lead {
|
||||
margin: 0 0 20px;
|
||||
padding: 12px 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--el-text-color-secondary);
|
||||
background: var(--el-fill-color-light);
|
||||
border-radius: 8px;
|
||||
border-left: 3px solid var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.create-order-step-panel {
|
||||
max-height: min(56vh, 480px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 4px 8px 12px 4px;
|
||||
margin-right: -4px;
|
||||
}
|
||||
|
||||
.create-order-step-panel__row-after-bar {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.create-order-unit-suffix {
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.create-order-footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.create-order-footer__hint {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.create-order-footer__step {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
|
||||
.create-order-footer__warn {
|
||||
color: var(--el-color-warning);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.create-order-footer__actions {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.create-order-deposit-bar {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
|
||||
}
|
||||
|
||||
.create-order-deposit-bar__cell {
|
||||
flex: 1;
|
||||
padding: 16px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
background: var(--el-fill-color-light);
|
||||
|
||||
strong {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
|
||||
svg {
|
||||
color: var(--el-color-primary);
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.section-content {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.create-order-deposit-bar__label {
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.create-order-deposit-bar__sub {
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
|
||||
.create-order-deposit-bar__sep {
|
||||
width: 1px;
|
||||
background: var(--el-border-color-lighter);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.create-order-deposit-bar.is-ok .create-order-deposit-bar__cell:last-child strong {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
|
||||
.create-order-deposit-bar.is-warn .create-order-deposit-bar__cell:last-child strong {
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
.create-order-pay-hint {
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
margin-top: 8px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.create-order-form {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
:deep(.el-input__inner),
|
||||
:deep(.el-textarea__inner) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.create-order-form-item--inline-num {
|
||||
:deep(.el-form-item__content) {
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user