更新
This commit is contained in:
@@ -248,7 +248,7 @@
|
|||||||
</el-col> -->
|
</el-col> -->
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="用法" prop="usage_instruction">
|
<el-form-item label="用法" prop="usage_instruction">
|
||||||
<el-input v-model="formData.usage_instruction" placeholder="例如:水煎服,一日二次" maxlength="200" show-word-limit />
|
<el-input v-model="formData.usage_instruction" placeholder="" maxlength="200" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|||||||
@@ -1076,16 +1076,10 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<span class="text-xs text-gray-400">ID: {{ editForm.prescription_id || '—' }}</span>
|
<span class="text-xs text-gray-400">ID: {{ editForm.prescription_id || '—' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 诊单创建人及所在部门(tcm_diagnosis.admin_id;接口为「全角;」多部门、每路径「父 / 子 / …」含上级) -->
|
<!-- 创建人所属部门:优先业务订单 creator_id,无则诊单 admin_id;非处方开方人;「;」多部门、路径内「/」含上级 -->
|
||||||
<div class="mt-2 space-y-2 text-xs sm:text-sm">
|
<div class="mt-2 space-y-1.5 text-xs sm:text-sm">
|
||||||
<div class="flex flex-wrap items-baseline gap-x-2 gap-y-0.5">
|
|
||||||
<span class="text-gray-500 shrink-0">诊单创建人</span>
|
|
||||||
<span class="text-gray-800 font-medium">
|
|
||||||
{{ editForm.diagnosis_creator_name || '—' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="editDiagnosisCreatorDeptBreadcrumbs.length" class="space-y-1.5">
|
<div v-if="editDiagnosisCreatorDeptBreadcrumbs.length" class="space-y-1.5">
|
||||||
<div class="text-gray-500">所在部门(含上级)</div>
|
<div class="text-gray-500">创建人所属部门</div>
|
||||||
<div
|
<div
|
||||||
v-for="(segments, idx) in editDiagnosisCreatorDeptBreadcrumbs"
|
v-for="(segments, idx) in editDiagnosisCreatorDeptBreadcrumbs"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
@@ -1105,12 +1099,7 @@
|
|||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else class="text-gray-400">创建人所属部门:—</div>
|
||||||
v-else
|
|
||||||
class="text-gray-400"
|
|
||||||
>
|
|
||||||
所在部门:—
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="8">
|
<el-col :xs="24" :sm="8">
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
@click="handleDateTabClick(tab.value)"
|
@click="handleDateTabClick(tab.value)"
|
||||||
>
|
>
|
||||||
{{ tab.label }}
|
{{ tab.label }}
|
||||||
<em v-if="tab.value && dateCounts[tab.value] !== undefined">{{ dateCounts[tab.value] }}</em>
|
<em v-if="dateCounts[tab.value] !== undefined">{{ dateCounts[tab.value] }}</em>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
:class="['chip', 'chip-pending-booking', { active: formData.pending_booking === '1' }]"
|
:class="['chip', 'chip-pending-booking', { active: formData.pending_booking === '1' }]"
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
<span
|
<span
|
||||||
:class="['chip', 'chip-pending', { active: formData.pending_assign === '1' }]"
|
:class="['chip', 'chip-pending', { active: formData.pending_assign === '1' }]"
|
||||||
@click="handlePendingAssignTabClick"
|
@click="handlePendingAssignTabClick"
|
||||||
v-perms="['tcm.diagnosis/assign']"
|
|
||||||
>
|
>
|
||||||
待分配医助
|
待分配医助
|
||||||
<em v-if="pendingAssignCount !== undefined">{{ pendingAssignCount }}</em>
|
<em v-if="pendingAssignCount !== undefined">{{ pendingAssignCount }}</em>
|
||||||
@@ -230,10 +229,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="260" fixed="right" align="left">
|
<el-table-column label="操作" width="300" fixed="right" align="left">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="action-cell">
|
<div class="action-cell">
|
||||||
<el-button type="primary" link size="small" @click="handleEdit(row.id)" v-perms="['tcm.diagnosis/edit']">诊单</el-button>
|
<el-button type="primary" link size="small" @click="handleEdit(row.id)" v-perms="['tcm.diagnosis/edit']">诊单</el-button>
|
||||||
|
<el-button
|
||||||
|
v-perms="['tcm.diagnosis/kaifang']"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handlePrescription(row)"
|
||||||
|
>
|
||||||
|
{{ prescriptionActionLabel(row) }}
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-perms="['tcm.diagnosis/guahao']"
|
v-perms="['tcm.diagnosis/guahao']"
|
||||||
type="success"
|
type="success"
|
||||||
@@ -241,6 +249,7 @@
|
|||||||
size="small"
|
size="small"
|
||||||
@click="handleAppointment(row)"
|
@click="handleAppointment(row)"
|
||||||
>预约</el-button>
|
>预约</el-button>
|
||||||
|
|
||||||
<el-button
|
<el-button
|
||||||
v-perms="['tcm.diagnosis/edit']"
|
v-perms="['tcm.diagnosis/edit']"
|
||||||
type="warning"
|
type="warning"
|
||||||
@@ -273,6 +282,7 @@
|
|||||||
|
|
||||||
<edit-popup ref="editRef" @success="refreshListAfterPopupSave" />
|
<edit-popup ref="editRef" @success="refreshListAfterPopupSave" />
|
||||||
<detail-popup ref="detailRef" />
|
<detail-popup ref="detailRef" />
|
||||||
|
<tcm-prescription ref="prescriptionRef" @success="onPrescriptionSuccess" />
|
||||||
<appointment-popup ref="appointmentRef" @success="refreshListAfterPopupSave" />
|
<appointment-popup ref="appointmentRef" @success="refreshListAfterPopupSave" />
|
||||||
<assistant-watch-call-dialog
|
<assistant-watch-call-dialog
|
||||||
v-model="watchCallVisible"
|
v-model="watchCallVisible"
|
||||||
@@ -569,6 +579,7 @@ import dayjs from 'dayjs'
|
|||||||
|
|
||||||
const EditPopup = defineAsyncComponent(() => import('./edit.vue'))
|
const EditPopup = defineAsyncComponent(() => import('./edit.vue'))
|
||||||
const DetailPopup = defineAsyncComponent(() => import('./detail.vue'))
|
const DetailPopup = defineAsyncComponent(() => import('./detail.vue'))
|
||||||
|
const TcmPrescription = defineAsyncComponent(() => import('@/components/tcm-prescription/index.vue'))
|
||||||
const AppointmentPopup = defineAsyncComponent(() => import('./appointment.vue'))
|
const AppointmentPopup = defineAsyncComponent(() => import('./appointment.vue'))
|
||||||
const AssistantWatchCallDialog = defineAsyncComponent(() => import('./components/AssistantWatchCallDialog.vue'))
|
const AssistantWatchCallDialog = defineAsyncComponent(() => import('./components/AssistantWatchCallDialog.vue'))
|
||||||
|
|
||||||
@@ -654,6 +665,8 @@ const doSearch = () => {
|
|||||||
|
|
||||||
// 重点:当天/明天/后天挂号 Tab
|
// 重点:当天/明天/后天挂号 Tab
|
||||||
const dateTabs = computed(() => [
|
const dateTabs = computed(() => [
|
||||||
|
{ label: '昨天挂号', value: yesterdayStr.value },
|
||||||
|
{ label: '前天挂号', value: dayBeforeStr.value },
|
||||||
{ label: '当天挂号', value: todayStr.value },
|
{ label: '当天挂号', value: todayStr.value },
|
||||||
{ label: '明天挂号', value: tomorrowStr.value },
|
{ label: '明天挂号', value: tomorrowStr.value },
|
||||||
{ label: '后天挂号', value: dayAfterStr.value },
|
{ label: '后天挂号', value: dayAfterStr.value },
|
||||||
@@ -711,21 +724,27 @@ const handlePendingAssignTabClick = async () => {
|
|||||||
fetchDateCounts()
|
fetchDateCounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取各日期挂号数量 + 待预约 + 已完成 + 待分配医助数量
|
// 获取各日期挂号数量 + 全部 + 待预约 + 已完成 + 待分配医助数量
|
||||||
const fetchDateCounts = async () => {
|
const fetchDateCounts = async () => {
|
||||||
try {
|
try {
|
||||||
const [today, tomorrow, dayAfter, noApt, doneVisit, pending] = await Promise.all([
|
const [yesterday, dayBefore, today, tomorrow, dayAfter, all, noApt, doneVisit, pending] = await Promise.all([
|
||||||
|
tcmDiagnosisLists({ appointment_date: yesterdayStr.value, page_no: 1, page_size: 1 }),
|
||||||
|
tcmDiagnosisLists({ appointment_date: dayBeforeStr.value, page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ appointment_date: todayStr.value, page_no: 1, page_size: 1 }),
|
tcmDiagnosisLists({ appointment_date: todayStr.value, page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ appointment_date: tomorrowStr.value, page_no: 1, page_size: 1 }),
|
tcmDiagnosisLists({ appointment_date: tomorrowStr.value, page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ appointment_date: dayAfterStr.value, page_no: 1, page_size: 1 }),
|
tcmDiagnosisLists({ appointment_date: dayAfterStr.value, page_no: 1, page_size: 1 }),
|
||||||
|
tcmDiagnosisLists({ page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ has_appointment: 0, page_no: 1, page_size: 1 }),
|
tcmDiagnosisLists({ has_appointment: 0, page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ completed_appointment: 1, page_no: 1, page_size: 1 }),
|
tcmDiagnosisLists({ completed_appointment: 1, page_no: 1, page_size: 1 }),
|
||||||
tcmDiagnosisLists({ pending_assign: 1, page_no: 1, page_size: 1 })
|
tcmDiagnosisLists({ pending_assign: 1, page_no: 1, page_size: 1 })
|
||||||
])
|
])
|
||||||
dateCounts.value = {
|
dateCounts.value = {
|
||||||
|
[yesterdayStr.value]: yesterday?.count ?? 0,
|
||||||
|
[dayBeforeStr.value]: dayBefore?.count ?? 0,
|
||||||
[todayStr.value]: today?.count ?? 0,
|
[todayStr.value]: today?.count ?? 0,
|
||||||
[tomorrowStr.value]: tomorrow?.count ?? 0,
|
[tomorrowStr.value]: tomorrow?.count ?? 0,
|
||||||
[dayAfterStr.value]: dayAfter?.count ?? 0
|
[dayAfterStr.value]: dayAfter?.count ?? 0,
|
||||||
|
'': all?.count ?? 0
|
||||||
}
|
}
|
||||||
pendingBookingCount.value = noApt?.count ?? 0
|
pendingBookingCount.value = noApt?.count ?? 0
|
||||||
completedVisitCount.value = doneVisit?.count ?? 0
|
completedVisitCount.value = doneVisit?.count ?? 0
|
||||||
@@ -771,6 +790,16 @@ const dayAfterStr = computed(() => {
|
|||||||
t.setDate(t.getDate() + 2)
|
t.setDate(t.getDate() + 2)
|
||||||
return `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}`
|
return `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}`
|
||||||
})
|
})
|
||||||
|
const yesterdayStr = computed(() => {
|
||||||
|
const t = new Date()
|
||||||
|
t.setDate(t.getDate() - 1)
|
||||||
|
return `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}`
|
||||||
|
})
|
||||||
|
const dayBeforeStr = computed(() => {
|
||||||
|
const t = new Date()
|
||||||
|
t.setDate(t.getDate() - 2)
|
||||||
|
return `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())}`
|
||||||
|
})
|
||||||
|
|
||||||
// Tab 切换
|
// Tab 切换
|
||||||
const handleTabChange = (tabName: string | number) => {
|
const handleTabChange = (tabName: string | number) => {
|
||||||
@@ -881,6 +910,7 @@ const getRowClassName = ({ row }: { row: any }) => {
|
|||||||
|
|
||||||
const editRef = ref()
|
const editRef = ref()
|
||||||
const detailRef = ref()
|
const detailRef = ref()
|
||||||
|
const prescriptionRef = ref()
|
||||||
const appointmentRef = ref()
|
const appointmentRef = ref()
|
||||||
/** 从路由带 id 进入时,诊单弹窗为异步组件,需在 ref 就绪后再 open */
|
/** 从路由带 id 进入时,诊单弹窗为异步组件,需在 ref 就绪后再 open */
|
||||||
const pendingRouteDiagnosisId = ref<number | null>(null)
|
const pendingRouteDiagnosisId = ref<number | null>(null)
|
||||||
@@ -1149,6 +1179,34 @@ const handleEdit = (id: number) => {
|
|||||||
editRef.value.open('edit', id)
|
editRef.value.open('edit', id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 与预约列表开方一致:已通过且未作废 → 查看,否则开方 */
|
||||||
|
function prescriptionActionLabel(row: any) {
|
||||||
|
if (
|
||||||
|
row?.prescription_audit_status === 1 &&
|
||||||
|
Number(row?.prescription_void_status) !== 1
|
||||||
|
) {
|
||||||
|
return '查看'
|
||||||
|
}
|
||||||
|
return '开方'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePrescription = (row: any) => {
|
||||||
|
if (!row?.id) {
|
||||||
|
feedback.msgWarning('诊单信息不完整')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prescriptionRef.value?.open({
|
||||||
|
...row,
|
||||||
|
diagnosis_id: row.id,
|
||||||
|
id: row.appointment_id || 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPrescriptionSuccess = () => {
|
||||||
|
getLists()
|
||||||
|
;(editRef.value as { refreshCaseList?: () => void } | undefined)?.refreshCaseList?.()
|
||||||
|
}
|
||||||
|
|
||||||
const handleDetail = (id: number) => {
|
const handleDetail = (id: number) => {
|
||||||
detailRef.value.open(id)
|
detailRef.value.open(id)
|
||||||
}
|
}
|
||||||
@@ -1560,6 +1618,7 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.date-chips {
|
.date-chips {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
||||||
.chip {
|
.chip {
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
|||||||
if ($diagnosisIds !== []) {
|
if ($diagnosisIds !== []) {
|
||||||
$rxAll = Prescription::whereIn('diagnosis_id', $diagnosisIds)
|
$rxAll = Prescription::whereIn('diagnosis_id', $diagnosisIds)
|
||||||
->whereNull('delete_time')
|
->whereNull('delete_time')
|
||||||
->field(['id', 'diagnosis_id', 'doctor_name', 'creator_id', 'prescription_date', 'create_time', 'void_status'])
|
->field(['id', 'diagnosis_id', 'doctor_name', 'creator_id', 'prescription_date', 'create_time', 'void_status', 'audit_status'])
|
||||||
->order('id', 'desc')
|
->order('id', 'desc')
|
||||||
->select()
|
->select()
|
||||||
->toArray();
|
->toArray();
|
||||||
@@ -339,6 +339,8 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
|||||||
'time_text' => $this->formatPrescriptionFollowupTime($rx),
|
'time_text' => $this->formatPrescriptionFollowupTime($rx),
|
||||||
'doctor_name' => $doctorName !== '' ? $doctorName : '—',
|
'doctor_name' => $doctorName !== '' ? $doctorName : '—',
|
||||||
'voided' => (int) ($rx['void_status'] ?? 0) !== 0,
|
'voided' => (int) ($rx['void_status'] ?? 0) !== 0,
|
||||||
|
'void_status' => (int) ($rx['void_status'] ?? 0),
|
||||||
|
'audit_status' => (int) ($rx['audit_status'] ?? -1),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,6 +350,8 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
|
|||||||
$item['followup_time_text'] = ($item['has_prescription'] && $fu) ? ($fu['time_text'] ?? '') : '';
|
$item['followup_time_text'] = ($item['has_prescription'] && $fu) ? ($fu['time_text'] ?? '') : '';
|
||||||
$item['followup_doctor_name'] = ($item['has_prescription'] && $fu) ? ($fu['doctor_name'] ?? '—') : '';
|
$item['followup_doctor_name'] = ($item['has_prescription'] && $fu) ? ($fu['doctor_name'] ?? '—') : '';
|
||||||
$item['followup_rx_voided'] = ($item['has_prescription'] && $fu && !empty($fu['voided'])) ? 1 : 0;
|
$item['followup_rx_voided'] = ($item['has_prescription'] && $fu && !empty($fu['voided'])) ? 1 : 0;
|
||||||
|
$item['prescription_audit_status'] = ($item['has_prescription'] && $fu) ? (int) ($fu['audit_status'] ?? -1) : -1;
|
||||||
|
$item['prescription_void_status'] = ($item['has_prescription'] && $fu) ? (int) ($fu['void_status'] ?? 0) : 0;
|
||||||
// 开方次数即复诊次数:1 张处方 = 第 1 次复诊,以此类推
|
// 开方次数即复诊次数:1 张处方 = 第 1 次复诊,以此类推
|
||||||
$item['followup_prescription_count'] = (int) ($rxCountByDiag[$did] ?? 0);
|
$item['followup_prescription_count'] = (int) ($rxCountByDiag[$did] ?? 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -809,8 +809,8 @@ class PrescriptionLogic
|
|||||||
'dose_unit' => '剂',
|
'dose_unit' => '剂',
|
||||||
'usage_days' => 7,
|
'usage_days' => 7,
|
||||||
'times_per_day' => 2,
|
'times_per_day' => 2,
|
||||||
'usage_instruction' => '水煎服,一日二次',
|
'usage_instruction' => '',
|
||||||
'usage_time' => '饭前',
|
'usage_time' => '饭后',
|
||||||
'usage_way' => '温水送服',
|
'usage_way' => '温水送服',
|
||||||
'dietary_taboo' => '',
|
'dietary_taboo' => '',
|
||||||
'usage_notes' => '',
|
'usage_notes' => '',
|
||||||
|
|||||||
@@ -13,11 +13,10 @@ use app\common\model\tcm\PrescriptionOrder;
|
|||||||
use app\common\model\tcm\PrescriptionOrderLog;
|
use app\common\model\tcm\PrescriptionOrderLog;
|
||||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||||
use app\common\model\auth\Admin;
|
use app\common\model\auth\Admin;
|
||||||
use app\common\model\auth\AdminDept;
|
|
||||||
use app\common\model\dept\Dept;
|
|
||||||
use app\common\service\ExpressTrackService;
|
use app\common\service\ExpressTrackService;
|
||||||
use app\common\service\gancao\GancaoScmRecipelService;
|
use app\common\service\gancao\GancaoScmRecipelService;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
|
use think\facade\Db;
|
||||||
use think\facade\Log;
|
use think\facade\Log;
|
||||||
|
|
||||||
class PrescriptionOrderLogic
|
class PrescriptionOrderLogic
|
||||||
@@ -36,6 +35,7 @@ class PrescriptionOrderLogic
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门自底向上链式名称,含父级(如:总部 / 华东 / 上海门诊)
|
* 部门自底向上链式名称,含父级(如:总部 / 华东 / 上海门诊)
|
||||||
|
* 使用 Db 直查 zyt_dept:避免 Dept 软删除全局作用域导致有 dept_id 仍拼不出路径
|
||||||
*/
|
*/
|
||||||
private static function buildDeptPath(int $deptId): string
|
private static function buildDeptPath(int $deptId): string
|
||||||
{
|
{
|
||||||
@@ -45,13 +45,13 @@ class PrescriptionOrderLogic
|
|||||||
$names = [];
|
$names = [];
|
||||||
$id = $deptId;
|
$id = $deptId;
|
||||||
for ($i = 0; $i < 50; $i++) {
|
for ($i = 0; $i < 50; $i++) {
|
||||||
$row = Dept::where('id', $id)->whereNull('delete_time')->field(['id', 'name', 'pid'])->find();
|
$row = Db::name('dept')->where('id', $id)->field(['id', 'name', 'pid'])->find();
|
||||||
if ($row === null) {
|
if (empty($row)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$data = $row->toArray();
|
$r = is_array($row) ? $row : $row->toArray();
|
||||||
array_unshift($names, (string) ($data['name'] ?? ''));
|
array_unshift($names, (string) ($r['name'] ?? ''));
|
||||||
$pid = (int) ($data['pid'] ?? 0);
|
$pid = (int) ($r['pid'] ?? 0);
|
||||||
if ($pid <= 0) {
|
if ($pid <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -66,6 +66,27 @@ class PrescriptionOrderLogic
|
|||||||
return implode(' / ', $names);
|
return implode(' / ', $names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员在 zyt_admin_dept 中的部门路径(多部门用「;」、含父级「 / 」)
|
||||||
|
*/
|
||||||
|
private static function buildAdminDeptPathJoined(int $adminId): string
|
||||||
|
{
|
||||||
|
if ($adminId <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$deptIds = Db::name('admin_dept')->where('admin_id', $adminId)->column('dept_id');
|
||||||
|
$pathSegmentsC = [];
|
||||||
|
foreach ($deptIds as $didC) {
|
||||||
|
$pc = self::buildDeptPath((int) $didC);
|
||||||
|
if ($pc !== '') {
|
||||||
|
$pathSegmentsC[] = $pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$pathSegmentsC = array_values(array_unique($pathSegmentsC));
|
||||||
|
|
||||||
|
return $pathSegmentsC === [] ? '' : implode(';', $pathSegmentsC);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $allowRoleIds
|
* @param int[] $allowRoleIds
|
||||||
*/
|
*/
|
||||||
@@ -641,7 +662,7 @@ class PrescriptionOrderLogic
|
|||||||
unset($arr['prescription']['herbs']);
|
unset($arr['prescription']['herbs']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 诊单医助 / 诊单创建人 及部门(多部门、含父级路径用「;」与「 / 」分隔);创建人为 tcm_diagnosis.admin_id
|
// 诊单医助 / 诊单创建人姓名(tcm_diagnosis.admin_id);部门见下方:优先业务订单 creator_id
|
||||||
$arr['assistant_id'] = 0;
|
$arr['assistant_id'] = 0;
|
||||||
$arr['assistant_name'] = '';
|
$arr['assistant_name'] = '';
|
||||||
$arr['assistant_dept_path'] = '';
|
$arr['assistant_dept_path'] = '';
|
||||||
@@ -659,7 +680,7 @@ class PrescriptionOrderLogic
|
|||||||
if ($astId > 0) {
|
if ($astId > 0) {
|
||||||
$an = Admin::where('id', $astId)->whereNull('delete_time')->value('name');
|
$an = Admin::where('id', $astId)->whereNull('delete_time')->value('name');
|
||||||
$arr['assistant_name'] = $an !== null && (string) $an !== '' ? (string) $an : '';
|
$arr['assistant_name'] = $an !== null && (string) $an !== '' ? (string) $an : '';
|
||||||
$deptIds = AdminDept::where('admin_id', $astId)->column('dept_id');
|
$deptIds = Db::name('admin_dept')->where('admin_id', $astId)->column('dept_id');
|
||||||
$pathSegments = [];
|
$pathSegments = [];
|
||||||
foreach ($deptIds as $did) {
|
foreach ($deptIds as $did) {
|
||||||
$p = self::buildDeptPath((int) $did);
|
$p = self::buildDeptPath((int) $did);
|
||||||
@@ -675,19 +696,18 @@ class PrescriptionOrderLogic
|
|||||||
if ($creId > 0) {
|
if ($creId > 0) {
|
||||||
$cn = Admin::where('id', $creId)->whereNull('delete_time')->value('name');
|
$cn = Admin::where('id', $creId)->whereNull('delete_time')->value('name');
|
||||||
$arr['diagnosis_creator_name'] = $cn !== null && (string) $cn !== '' ? (string) $cn : '';
|
$arr['diagnosis_creator_name'] = $cn !== null && (string) $cn !== '' ? (string) $cn : '';
|
||||||
$deptIdsC = AdminDept::where('admin_id', $creId)->column('dept_id');
|
|
||||||
$pathSegmentsC = [];
|
|
||||||
foreach ($deptIdsC as $didC) {
|
|
||||||
$pc = self::buildDeptPath((int) $didC);
|
|
||||||
if ($pc !== '') {
|
|
||||||
$pathSegmentsC[] = $pc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$pathSegmentsC = array_values(array_unique($pathSegmentsC));
|
|
||||||
$arr['diagnosis_creator_dept_path'] = $pathSegmentsC === [] ? '' : implode(';', $pathSegmentsC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 「创建人所属部门」:优先 zyt_tcm_prescription_order.creator_id;无部门时再试诊单 admin_id(非处方开方人)
|
||||||
|
$deptPath = self::buildAdminDeptPathJoined((int) ($arr['creator_id'] ?? 0));
|
||||||
|
if ($deptPath === '') {
|
||||||
|
$dgAdmin = (int) ($arr['diagnosis_creator_id'] ?? 0);
|
||||||
|
if ($dgAdmin > 0) {
|
||||||
|
$deptPath = self::buildAdminDeptPathJoined($dgAdmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$arr['diagnosis_creator_dept_path'] = $deptPath;
|
||||||
|
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace app\api\controller;
|
namespace app\api\controller;
|
||||||
|
|
||||||
|
use app\common\model\Order;
|
||||||
use app\common\model\tcm\PrescriptionOrder;
|
use app\common\model\tcm\PrescriptionOrder;
|
||||||
use app\common\model\tcm\PrescriptionOrderLog;
|
use app\common\model\tcm\PrescriptionOrderLog;
|
||||||
|
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
use think\facade\Log;
|
use think\facade\Log;
|
||||||
use think\Response;
|
use think\Response;
|
||||||
@@ -237,11 +239,66 @@ class GancaoCallbackController extends BaseApiController
|
|||||||
* 11 系统审核通过
|
* 11 系统审核通过
|
||||||
* 110 订单药房流转制作中(ext: flow_name, supplier)
|
* 110 订单药房流转制作中(ext: flow_name, supplier)
|
||||||
* 20 物流中(ext: shipping_name, nu, supplier)
|
* 20 物流中(ext: shipping_name, nu, supplier)
|
||||||
* 30 完成 - 终态(ext: shipping_name, nu, supplier)
|
* 30 完成 - 终态。fulfillment 见 resolveFulfilmentOnGancaoState30(与 zyt_order 已付/关联合计对比业务订单 amount)
|
||||||
* 90 拦截 - 可恢复
|
* 90 拦截 - 可恢复
|
||||||
* 91 主动撤单 - 终态(退费)
|
* 91 主动撤单 - 终态(退费)
|
||||||
* 92 驳回 - 终态(无法制作并退费)
|
* 92 驳回 - 终态(无法制作并退费)
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* 甘草 state=30:返回 fulfillment_status 3=已完成 或 6=已签收
|
||||||
|
* 1) 已支付金额(zyt_order.status=2 的 amount 合计)与业务订单 amount 一致 → 3
|
||||||
|
* 2) 否则已关联订单金额合计(全部关联单 amount)与业务订单 amount 一致 → 3
|
||||||
|
* 3) 否则 → 6(含:已支付与总金额不一致且关联合计也不一致)
|
||||||
|
* 无关联 zyt_order:仅甘草完成则 3
|
||||||
|
*/
|
||||||
|
private function resolveFulfilmentOnGancaoState30(PrescriptionOrder $order): int
|
||||||
|
{
|
||||||
|
$poId = (int) $order->id;
|
||||||
|
if ($poId <= 0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
$payIds = PrescriptionOrderPayOrder::where('prescription_order_id', $poId)
|
||||||
|
->column('pay_order_id');
|
||||||
|
$payIds = array_values(array_filter(
|
||||||
|
array_map('intval', is_array($payIds) ? $payIds : []),
|
||||||
|
static fn (int $id): bool => $id > 0
|
||||||
|
));
|
||||||
|
if ($payIds === []) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderAmt = round((float) ($order->amount ?? 0), 2);
|
||||||
|
$sumAll = round(
|
||||||
|
(float) Order::whereIn('id', $payIds)->whereNull('delete_time')->sum('amount'),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
$sumPaid = round(
|
||||||
|
(float) Order::whereIn('id', $payIds)
|
||||||
|
->whereNull('delete_time')
|
||||||
|
->where('status', 2)
|
||||||
|
->sum('amount'),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
if (abs($sumPaid - $orderAmt) <= 0.02) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (abs($sumAll - $orderAmt) <= 0.02) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::warning('Gancao 完成回调:已支付(status=2)与关联合计均未与业务订单金额对齐,标已签收(6)', [
|
||||||
|
'prescription_order_id' => $poId,
|
||||||
|
'order_no' => (string) ($order->order_no ?? ''),
|
||||||
|
'tcm_order_amount' => $orderAmt,
|
||||||
|
'sum_paid_status2' => $sumPaid,
|
||||||
|
'sum_linked_all' => $sumAll,
|
||||||
|
'linked_pay_order_ids' => $payIds,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
private function updateOrderStatus(PrescriptionOrder $order, int $state, array $ext): void
|
private function updateOrderStatus(PrescriptionOrder $order, int $state, array $ext): void
|
||||||
{
|
{
|
||||||
$order->gancao_order_state = $state;
|
$order->gancao_order_state = $state;
|
||||||
@@ -262,7 +319,7 @@ class GancaoCallbackController extends BaseApiController
|
|||||||
case 30:
|
case 30:
|
||||||
$this->handleShipping($order, $ext);
|
$this->handleShipping($order, $ext);
|
||||||
if ((int) $order->fulfillment_status !== 4) {
|
if ((int) $order->fulfillment_status !== 4) {
|
||||||
$order->fulfillment_status = 3; // 已完成
|
$order->fulfillment_status = $this->resolveFulfilmentOnGancaoState30($order);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user