更新
This commit is contained in:
@@ -500,6 +500,11 @@ export function prescriptionOrderUpdateAmount(params: { id: number; amount: numb
|
|||||||
return request.post({ url: '/tcm.prescriptionOrder/updateAmount', params })
|
return request.post({ url: '/tcm.prescriptionOrder/updateAmount', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 设置发货类型:gancao 甘草药房 / direct 洛阳药房 */
|
||||||
|
export function prescriptionOrderSetShipMode(params: { id: number; ship_mode: 'gancao' | 'direct' }) {
|
||||||
|
return request.post({ url: '/tcm.prescriptionOrder/setShipMode', params })
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 处方库 ==========
|
// ========== 处方库 ==========
|
||||||
|
|
||||||
// 处方库列表
|
// 处方库列表
|
||||||
|
|||||||
@@ -562,6 +562,28 @@
|
|||||||
round
|
round
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
>甘草 {{ detailData.gancao_reciperl_order_no }}</el-tag>
|
>甘草 {{ detailData.gancao_reciperl_order_no }}</el-tag>
|
||||||
|
<div v-if="detailData" class="flex items-center gap-2 ml-4 shrink-0">
|
||||||
|
<span class="text-sm text-gray-500">发货类型</span>
|
||||||
|
<el-radio-group
|
||||||
|
v-perms="['tcm.prescriptionOrder/setShipMode']"
|
||||||
|
:model-value="normalizeShipMode(detailData.ship_mode)"
|
||||||
|
size="small"
|
||||||
|
:disabled="shipModeSaving || !canEditShipMode(detailData)"
|
||||||
|
@change="onDetailShipModeChange"
|
||||||
|
>
|
||||||
|
<el-radio-button label="gancao">甘草药房</el-radio-button>
|
||||||
|
<el-radio-button
|
||||||
|
label="direct"
|
||||||
|
:disabled="isShipModeLockedToGancao(detailData)"
|
||||||
|
>洛阳药房</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-tag
|
||||||
|
v-if="!hasSetShipModePerm"
|
||||||
|
:type="normalizeShipMode(detailData.ship_mode) === 'direct' ? 'warning' : 'success'"
|
||||||
|
effect="plain"
|
||||||
|
round
|
||||||
|
>{{ shipModeLabel(detailData.ship_mode) }}</el-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="detailData" class="flex items-center gap-2 mr-6">
|
<div v-if="detailData" class="flex items-center gap-2 mr-6">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -1925,10 +1947,12 @@
|
|||||||
/>
|
/>
|
||||||
<el-form v-loading="shipSaving" label-width="90px" class="pr-2" @submit.prevent="submitShip">
|
<el-form v-loading="shipSaving" label-width="90px" class="pr-2" @submit.prevent="submitShip">
|
||||||
<el-form-item label="发货方式">
|
<el-form-item label="发货方式">
|
||||||
<el-radio-group v-model="shipForm.ship_mode">
|
<el-tag
|
||||||
<el-radio label="gancao">甘草药房直发</el-radio>
|
:type="normalizeShipMode(shipForm.ship_mode) === 'direct' ? 'warning' : 'success'"
|
||||||
<el-radio label="direct">洛阳药房直发</el-radio>
|
effect="plain"
|
||||||
</el-radio-group>
|
size="default"
|
||||||
|
>{{ shipDialogModeDisplay }}</el-tag>
|
||||||
|
<span class="text-xs text-gray-400 ml-2">请在订单详情顶部「发货类型」中设置,此处不可修改</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="承运商">
|
<el-form-item label="承运商">
|
||||||
<el-select v-model="shipForm.express_company" class="w-full">
|
<el-select v-model="shipForm.express_company" class="w-full">
|
||||||
@@ -2571,6 +2595,7 @@ import {
|
|||||||
prescriptionOrderShip,
|
prescriptionOrderShip,
|
||||||
prescriptionOrderLogs,
|
prescriptionOrderLogs,
|
||||||
prescriptionOrderUpdateAmount,
|
prescriptionOrderUpdateAmount,
|
||||||
|
prescriptionOrderSetShipMode,
|
||||||
prescriptionOrderAddPayOrder,
|
prescriptionOrderAddPayOrder,
|
||||||
prescriptionOrderComplete,
|
prescriptionOrderComplete,
|
||||||
prescriptionOrderRevokeRxAudit,
|
prescriptionOrderRevokeRxAudit,
|
||||||
@@ -3364,6 +3389,70 @@ function canShipRow(row: { fulfillment_status?: number }) {
|
|||||||
return Number(row.fulfillment_status) === 2
|
return Number(row.fulfillment_status) === 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShipMode = 'gancao' | 'direct'
|
||||||
|
|
||||||
|
const hasSetShipModePerm = computed(() => {
|
||||||
|
const p = userStore.perms || []
|
||||||
|
return p.includes('*') || p.includes('tcm.prescriptionOrder/setShipMode')
|
||||||
|
})
|
||||||
|
|
||||||
|
function normalizeShipMode(v: unknown): ShipMode {
|
||||||
|
return String(v || '').toLowerCase() === 'direct' ? 'direct' : 'gancao'
|
||||||
|
}
|
||||||
|
|
||||||
|
function shipModeLabel(v: unknown): string {
|
||||||
|
return normalizeShipMode(v) === 'direct' ? '洛阳药房' : '甘草药房'
|
||||||
|
}
|
||||||
|
|
||||||
|
function isShipModeLockedToGancao(row: { gancao_reciperl_order_no?: string | null }) {
|
||||||
|
return String(row.gancao_reciperl_order_no || '').trim() !== ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function canEditShipMode(row: { fulfillment_status?: number }) {
|
||||||
|
const fs = Number(row.fulfillment_status)
|
||||||
|
return fs !== 3 && fs !== 4
|
||||||
|
}
|
||||||
|
|
||||||
|
const shipModeSaving = ref(false)
|
||||||
|
|
||||||
|
function isSamePrescriptionOrderId(a: unknown, b: unknown) {
|
||||||
|
const na = Number(a)
|
||||||
|
const nb = Number(b)
|
||||||
|
return na > 0 && na === nb
|
||||||
|
}
|
||||||
|
|
||||||
|
const shipDialogModeDisplay = computed(() => {
|
||||||
|
return normalizeShipMode(shipForm.ship_mode) === 'direct' ? '洛阳药房直发' : '甘草药房直发'
|
||||||
|
})
|
||||||
|
|
||||||
|
async function onDetailShipModeChange(mode: string | number | boolean | undefined) {
|
||||||
|
const row = detailData.value
|
||||||
|
if (!row?.id) return
|
||||||
|
const next = normalizeShipMode(mode)
|
||||||
|
const prev = normalizeShipMode(row.ship_mode)
|
||||||
|
if (next === prev) return
|
||||||
|
if (!canEditShipMode(row)) {
|
||||||
|
feedback.msgWarning('当前订单状态不可修改发货类型')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
shipModeSaving.value = true
|
||||||
|
try {
|
||||||
|
await prescriptionOrderSetShipMode({ id: row.id, ship_mode: next })
|
||||||
|
if (detailData.value) detailData.value.ship_mode = next
|
||||||
|
if (shipVisible.value && isSamePrescriptionOrderId(shipRowId.value, row.id)) {
|
||||||
|
shipForm.ship_mode = next
|
||||||
|
}
|
||||||
|
await refreshCurrentPrescriptionOrderDetail()
|
||||||
|
feedback.msgSuccess('发货类型已保存')
|
||||||
|
getLists()
|
||||||
|
void fetchLogs(row.id)
|
||||||
|
} catch {
|
||||||
|
/* 拦截器已提示 */
|
||||||
|
} finally {
|
||||||
|
shipModeSaving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function canAddPayOrderRow(row: { fulfillment_status?: number }) {
|
function canAddPayOrderRow(row: { fulfillment_status?: number }) {
|
||||||
// 已发货(5) / 已签收(6) 状态可补齐支付单
|
// 已发货(5) / 已签收(6) 状态可补齐支付单
|
||||||
const fs = Number(row.fulfillment_status)
|
const fs = Number(row.fulfillment_status)
|
||||||
@@ -4745,14 +4834,31 @@ const shipForm = reactive({
|
|||||||
tracking_number: ''
|
tracking_number: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function resolveShipModeForRow(row: { id: number; ship_mode?: unknown }) {
|
||||||
|
if (isSamePrescriptionOrderId(detailData.value?.id, row.id)) {
|
||||||
|
return normalizeShipMode(detailData.value!.ship_mode)
|
||||||
|
}
|
||||||
|
return normalizeShipMode(row.ship_mode)
|
||||||
|
}
|
||||||
|
|
||||||
function openShip(row: { id: number; express_company?: unknown; tracking_number?: unknown; ship_mode?: unknown }) {
|
function openShip(row: { id: number; express_company?: unknown; tracking_number?: unknown; ship_mode?: unknown }) {
|
||||||
shipRowId.value = row.id
|
shipRowId.value = Number(row.id)
|
||||||
shipForm.ship_mode = String(row.ship_mode || 'gancao') || 'gancao'
|
shipForm.ship_mode = resolveShipModeForRow(row)
|
||||||
shipForm.express_company = String(row.express_company || 'auto') || 'auto'
|
shipForm.express_company = String(row.express_company || 'auto') || 'auto'
|
||||||
shipForm.tracking_number = String(row.tracking_number || '')
|
shipForm.tracking_number = String(row.tracking_number || '')
|
||||||
shipVisible.value = true
|
shipVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => detailData.value?.ship_mode,
|
||||||
|
(v) => {
|
||||||
|
if (!shipVisible.value || !shipRowId.value || !isSamePrescriptionOrderId(detailData.value?.id, shipRowId.value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
shipForm.ship_mode = normalizeShipMode(v)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
async function submitShip() {
|
async function submitShip() {
|
||||||
if (!shipForm.tracking_number.trim()) {
|
if (!shipForm.tracking_number.trim()) {
|
||||||
feedback.msgError('请先填写快递单号再确认发货')
|
feedback.msgError('请先填写快递单号再确认发货')
|
||||||
@@ -4762,7 +4868,7 @@ async function submitShip() {
|
|||||||
try {
|
try {
|
||||||
await prescriptionOrderShip({
|
await prescriptionOrderShip({
|
||||||
id: shipRowId.value,
|
id: shipRowId.value,
|
||||||
ship_mode: shipForm.ship_mode === 'direct' ? 'direct' : 'gancao',
|
ship_mode: normalizeShipMode(shipForm.ship_mode),
|
||||||
express_company: shipForm.express_company || 'auto',
|
express_company: shipForm.express_company || 'auto',
|
||||||
tracking_number: shipForm.tracking_number.trim()
|
tracking_number: shipForm.tracking_number.trim()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -124,6 +124,25 @@ class PrescriptionOrderController extends BaseAdminController
|
|||||||
return $this->success('修改成功');
|
return $this->success('修改成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置发货类型(甘草 / 洛阳)
|
||||||
|
*/
|
||||||
|
public function setShipMode()
|
||||||
|
{
|
||||||
|
$params = (new PrescriptionOrderValidate())->post()->goCheck('setShipMode');
|
||||||
|
$result = PrescriptionOrderLogic::setShipMode(
|
||||||
|
(int) $params['id'],
|
||||||
|
(string) ($params['ship_mode'] ?? 'gancao'),
|
||||||
|
$this->adminId,
|
||||||
|
$this->adminInfo
|
||||||
|
);
|
||||||
|
if ($result === false) {
|
||||||
|
return $this->fail(PrescriptionOrderLogic::getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->success('已保存', $result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改关联处方的患者姓名与手机号(订单详情场景)
|
* 修改关联处方的患者姓名与手机号(订单详情场景)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -677,9 +677,10 @@ class PrescriptionOrderLogic
|
|||||||
$rows = Order::whereIn('id', $ids)->whereNull('delete_time')
|
$rows = Order::whereIn('id', $ids)->whereNull('delete_time')
|
||||||
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt'])
|
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark', 'is_exempt'])
|
||||||
->order('id', 'asc')
|
->order('id', 'asc')
|
||||||
|
->where('status', 2)
|
||||||
->select()
|
->select()
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
$creatorIds = array_values(array_unique(array_filter(array_map('intval', array_column($rows, 'creator_id')))));
|
$creatorIds = array_values(array_unique(array_filter(array_map('intval', array_column($rows, 'creator_id')))));
|
||||||
$creatorNames = [];
|
$creatorNames = [];
|
||||||
if ($creatorIds !== []) {
|
if ($creatorIds !== []) {
|
||||||
@@ -1664,6 +1665,7 @@ class PrescriptionOrderLogic
|
|||||||
|
|
||||||
$order->express_company = self::normalizeExpressCompany($expressCompany);
|
$order->express_company = self::normalizeExpressCompany($expressCompany);
|
||||||
$order->tracking_number = $trackingNumber;
|
$order->tracking_number = $trackingNumber;
|
||||||
|
$order->ship_mode = $shipMode;
|
||||||
// 仅履约中(2)时才推进到已发货(5),已发货(5)则只更新快递信息保持状态
|
// 仅履约中(2)时才推进到已发货(5),已发货(5)则只更新快递信息保持状态
|
||||||
$isFirstShip = false;
|
$isFirstShip = false;
|
||||||
if ((int) $order->fulfillment_status === 2) {
|
if ((int) $order->fulfillment_status === 2) {
|
||||||
@@ -2425,7 +2427,7 @@ class PrescriptionOrderLogic
|
|||||||
$linkedPayPaidTotal += (float) ($o['amount'] ?? 0);
|
$linkedPayPaidTotal += (float) ($o['amount'] ?? 0);
|
||||||
}
|
}
|
||||||
$linkedPayPaidTotal = round($linkedPayPaidTotal, 2);
|
$linkedPayPaidTotal = round($linkedPayPaidTotal, 2);
|
||||||
|
|
||||||
if ($targetFulfillmentStatus === 3) {
|
if ($targetFulfillmentStatus === 3) {
|
||||||
$order->fulfillment_status = 3;
|
$order->fulfillment_status = 3;
|
||||||
$order->paid = $linkedPayPaidTotal;
|
$order->paid = $linkedPayPaidTotal;
|
||||||
@@ -3267,6 +3269,72 @@ class PrescriptionOrderLogic
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置发货类型(甘草 / 洛阳),与确认发货选项一致
|
||||||
|
*
|
||||||
|
* @return array<string,mixed>|false
|
||||||
|
*/
|
||||||
|
public static function setShipMode(int $id, string $shipMode, int $adminId, array $adminInfo)
|
||||||
|
{
|
||||||
|
self::$error = '';
|
||||||
|
|
||||||
|
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||||
|
if (!$order) {
|
||||||
|
self::$error = '订单不存在';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!self::canAccessOrder($order, $adminId, $adminInfo)) {
|
||||||
|
self::$error = '无权限操作';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$fs = (int) $order->fulfillment_status;
|
||||||
|
if ($fs === 3 || $fs === 4) {
|
||||||
|
self::$error = '已完成或已取消的订单不可修改发货类型';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$shipMode = self::normalizeShipMode($shipMode);
|
||||||
|
if ($shipMode === 'direct' && trim((string) $order->gancao_reciperl_order_no) !== '') {
|
||||||
|
self::$error = '已上传甘草药方,发货类型须为甘草药房';
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldMode = self::normalizeShipMode((string) ($order->ship_mode ?? 'gancao'));
|
||||||
|
if ($oldMode === $shipMode) {
|
||||||
|
$out = $order->toArray();
|
||||||
|
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||||
|
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||||
|
self::attachLinkedPayOrders($out);
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order->ship_mode = $shipMode;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$order->save();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
self::$error = $e->getMessage();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oldText = $oldMode === 'direct' ? '洛阳药房' : '甘草药房';
|
||||||
|
$newText = $shipMode === 'direct' ? '洛阳药房' : '甘草药房';
|
||||||
|
self::writeLog($id, $adminId, $adminInfo, 'set_ship_mode', '发货类型:' . $oldText . ' → ' . $newText);
|
||||||
|
|
||||||
|
$out = $order->toArray();
|
||||||
|
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||||
|
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||||
|
self::attachLinkedPayOrders($out);
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改订单金额
|
* 修改订单金额
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class PrescriptionOrderValidate extends BaseValidate
|
|||||||
'previewGancaoRecipel' => ['id'],
|
'previewGancaoRecipel' => ['id'],
|
||||||
'patchPrescriptionPatient' => ['id', 'patient_name', 'phone'],
|
'patchPrescriptionPatient' => ['id', 'patient_name', 'phone'],
|
||||||
'updateAmount' => ['id', 'amount'],
|
'updateAmount' => ['id', 'amount'],
|
||||||
|
'setShipMode' => ['id', 'ship_mode'],
|
||||||
];
|
];
|
||||||
|
|
||||||
public function updateAmount(): PrescriptionOrderValidate
|
public function updateAmount(): PrescriptionOrderValidate
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- 处方业务订单:设置发货类型(甘草 / 洛阳)
|
||||||
|
-- 执行前确认表前缀为 zyt_;若已有相同 perms 则跳过。
|
||||||
|
|
||||||
|
SET @po_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists' LIMIT 1);
|
||||||
|
|
||||||
|
INSERT INTO zyt_system_menu (
|
||||||
|
pid, type, name, icon, sort, perms, paths, component,
|
||||||
|
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
@po_menu_id, 'A', '设置发货类型', '', 61,
|
||||||
|
'tcm.prescriptionOrder/setShipMode', '', '',
|
||||||
|
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||||
|
FROM DUAL
|
||||||
|
WHERE @po_menu_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/setShipMode');
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
-- 业务订单:发货药方(甘草 / 洛阳),与确认发货 ship_mode 一致
|
||||||
|
-- 执行前确认表前缀为 zyt_;若列已存在可跳过。
|
||||||
|
|
||||||
|
ALTER TABLE `zyt_tcm_prescription_order`
|
||||||
|
ADD COLUMN `ship_mode` varchar(16) NOT NULL DEFAULT 'gancao'
|
||||||
|
COMMENT '发货药方:gancao=甘草药房 direct=洛阳药房'
|
||||||
|
AFTER `express_company`;
|
||||||
Reference in New Issue
Block a user