Merge branch '20260604-long'
This commit is contained in:
@@ -56,7 +56,7 @@ class PrescriptionLibraryLists extends BaseAdminDataLists implements ListsSearch
|
||||
public function lists(): array
|
||||
{
|
||||
$field = [
|
||||
'id', 'prescription_name', 'formula_type', 'herbs', 'is_public',
|
||||
'id', 'prescription_name', 'formula_type', 'herbs', 'is_public', 'disable_edit',
|
||||
'creator_id', 'creator_name', 'create_time', 'update_time'
|
||||
];
|
||||
|
||||
|
||||
@@ -778,6 +778,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
'export_channel' => '渠道',
|
||||
'export_guahao_channel_source' => '自媒体渠道(挂号渠道来源)',
|
||||
'export_medication_form' => '药品形态',
|
||||
'export_prescription_name' => '药方名称',
|
||||
'export_service_package' => '服务套餐',
|
||||
'export_medication_days' => '天数',
|
||||
'export_amount' => '总金额',
|
||||
|
||||
@@ -11,6 +11,7 @@ use app\common\model\Order;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\DiagnosisAssignLog;
|
||||
use app\common\model\tcm\Prescription;
|
||||
use app\common\model\tcm\PrescriptionLibrary;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderLog;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
@@ -3116,7 +3117,7 @@ class PrescriptionOrderLogic
|
||||
$rxById = [];
|
||||
if ($rxIdList !== []) {
|
||||
$rxRows = Prescription::whereIn('id', $rxIdList)->whereNull('delete_time')
|
||||
->field(['id', 'prescription_type', 'need_decoction', 'dose_unit', 'assistant_id', 'appointment_id'])
|
||||
->field(['id', 'prescription_type', 'need_decoction', 'dose_unit', 'assistant_id', 'appointment_id', 'prescription_name', 'aux_usage', 'herbs', 'creator_id'])
|
||||
->select()
|
||||
->toArray();
|
||||
foreach ($rxRows as $xr) {
|
||||
@@ -3124,6 +3125,10 @@ class PrescriptionOrderLogic
|
||||
}
|
||||
}
|
||||
|
||||
// 药方名称反查:处方库(开方医师 creator_id + 公开模板),按 formula_type + 药材集合匹配,
|
||||
// 复刻前端 resolveSlipAuxLibraryName 口径(主方/辅方均如此;处方记录 prescription_name 仅做兜底)。
|
||||
[$libByDoctor, $libPublic] = self::buildPrescriptionLibraryNameIndexForExport($rxById);
|
||||
|
||||
if ($needGuahaoChannel) {
|
||||
$yejiChannelHighlightByDiag = [];
|
||||
if (
|
||||
@@ -3329,6 +3334,22 @@ class PrescriptionOrderLogic
|
||||
}
|
||||
|
||||
$item['export_medication_form'] = self::formatMedicationFormForExport(\is_array($rx) ? $rx : []);
|
||||
|
||||
// 药方名称:主方/辅方均反查处方库取名称(与处方笺一致),带标签;甘草/无匹配留空
|
||||
[$mainRxName, $auxRxName] = self::resolvePrescriptionNamesForExport(
|
||||
\is_array($rx) ? $rx : [],
|
||||
$libByDoctor,
|
||||
$libPublic
|
||||
);
|
||||
$rxNameParts = [];
|
||||
if ($mainRxName !== '') {
|
||||
$rxNameParts[] = '主方:' . $mainRxName;
|
||||
}
|
||||
if ($auxRxName !== '') {
|
||||
$rxNameParts[] = '辅方:' . $auxRxName;
|
||||
}
|
||||
$item['export_prescription_name'] = implode(' ', $rxNameParts);
|
||||
|
||||
$item['export_service_package'] = self::formatServicePackageForExport(
|
||||
$item['service_package'] ?? '',
|
||||
$packageNameByValue
|
||||
@@ -3401,6 +3422,186 @@ class PrescriptionOrderLogic
|
||||
unset($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出药方名称反查:批量加载相关开方医师处方库(creator_id 命中 + 公开模板),
|
||||
* 建立 [creator_id][formula_type][herbKey] => name 与 公开 [formula_type][herbKey] => name 两级索引。
|
||||
*
|
||||
* @param array<int, array> $rxById 处方 id => 处方行(需含 herbs / creator_id)
|
||||
*
|
||||
* @return array{0: array<int, array<string, array<string, string>>>, 1: array<string, array<string, string>>}
|
||||
*/
|
||||
private static function buildPrescriptionLibraryNameIndexForExport(array $rxById): array
|
||||
{
|
||||
$libByDoctor = [];
|
||||
$libPublic = [];
|
||||
if ($rxById === []) {
|
||||
return [$libByDoctor, $libPublic];
|
||||
}
|
||||
|
||||
$doctorIds = [];
|
||||
foreach ($rxById as $rx) {
|
||||
$cid = (int) ($rx['creator_id'] ?? 0);
|
||||
if ($cid > 0) {
|
||||
$doctorIds[$cid] = true;
|
||||
}
|
||||
}
|
||||
$doctorIdList = array_keys($doctorIds);
|
||||
|
||||
try {
|
||||
$libRows = PrescriptionLibrary::whereNull('delete_time')
|
||||
->where(function ($q) use ($doctorIdList) {
|
||||
if ($doctorIdList !== []) {
|
||||
$q->whereIn('creator_id', $doctorIdList)->whereOr('is_public', 1);
|
||||
} else {
|
||||
$q->where('is_public', 1);
|
||||
}
|
||||
})
|
||||
->field(['prescription_name', 'formula_type', 'herbs', 'creator_id', 'is_public'])
|
||||
->select()
|
||||
->toArray();
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('buildPrescriptionLibraryNameIndexForExport failed: ' . $e->getMessage());
|
||||
|
||||
return [$libByDoctor, $libPublic];
|
||||
}
|
||||
|
||||
foreach ($libRows as $lib) {
|
||||
$name = trim((string) ($lib['prescription_name'] ?? ''));
|
||||
if ($name === '') {
|
||||
continue;
|
||||
}
|
||||
$herbsRaw = $lib['herbs'] ?? null;
|
||||
if (\is_string($herbsRaw) && $herbsRaw !== '') {
|
||||
$decoded = json_decode($herbsRaw, true);
|
||||
$herbsRaw = \is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
if (!\is_array($herbsRaw) || $herbsRaw === []) {
|
||||
continue;
|
||||
}
|
||||
$key = self::herbSetMatchKeyForExport($herbsRaw);
|
||||
if ($key === '') {
|
||||
continue;
|
||||
}
|
||||
$ft = ((string) ($lib['formula_type'] ?? '')) === '辅方' ? '辅方' : '主方';
|
||||
|
||||
if ((int) ($lib['is_public'] ?? 0) === 1) {
|
||||
$libPublic[$ft][$key] ??= $name;
|
||||
}
|
||||
$cid = (int) ($lib['creator_id'] ?? 0);
|
||||
if ($cid > 0) {
|
||||
$libByDoctor[$cid][$ft][$key] ??= $name;
|
||||
}
|
||||
}
|
||||
|
||||
return [$libByDoctor, $libPublic];
|
||||
}
|
||||
|
||||
/**
|
||||
* 反查单张处方的主方 / 辅方名称(与处方笺展示一致):
|
||||
* - 主方:主方药材集合匹配开方医师/公开处方库(formula_type=主方);兜底取处方 prescription_name。
|
||||
* - 辅方:优先 aux_usage.prescription_name / library_name,否则辅方药材集合匹配(formula_type=辅方)。
|
||||
*
|
||||
* @param array $rx 处方行(含 herbs / creator_id / prescription_name / aux_usage)
|
||||
* @param array<int, array<string, array<string, string>>> $libByDoctor
|
||||
* @param array<string, array<string, string>> $libPublic
|
||||
*
|
||||
* @return array{0: string, 1: string} [主方名称, 辅方名称]
|
||||
*/
|
||||
private static function resolvePrescriptionNamesForExport(array $rx, array $libByDoctor, array $libPublic): array
|
||||
{
|
||||
if ($rx === []) {
|
||||
return ['', ''];
|
||||
}
|
||||
|
||||
$doctorId = (int) ($rx['creator_id'] ?? 0);
|
||||
|
||||
$herbs = $rx['herbs'] ?? null;
|
||||
if (\is_string($herbs) && $herbs !== '') {
|
||||
$decoded = json_decode($herbs, true);
|
||||
$herbs = \is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
if (!\is_array($herbs)) {
|
||||
$herbs = [];
|
||||
}
|
||||
|
||||
$mainHerbs = [];
|
||||
$auxHerbs = [];
|
||||
foreach ($herbs as $h) {
|
||||
if (!\is_array($h)) {
|
||||
continue;
|
||||
}
|
||||
if (((string) ($h['formula_type'] ?? '')) === '辅方') {
|
||||
$auxHerbs[] = $h;
|
||||
} else {
|
||||
$mainHerbs[] = $h;
|
||||
}
|
||||
}
|
||||
|
||||
$lookup = static function (string $ft, array $hs) use ($doctorId, $libByDoctor, $libPublic): string {
|
||||
if ($hs === []) {
|
||||
return '';
|
||||
}
|
||||
$key = self::herbSetMatchKeyForExport($hs);
|
||||
if ($key === '') {
|
||||
return '';
|
||||
}
|
||||
if ($doctorId > 0 && isset($libByDoctor[$doctorId][$ft][$key])) {
|
||||
return $libByDoctor[$doctorId][$ft][$key];
|
||||
}
|
||||
|
||||
return (string) ($libPublic[$ft][$key] ?? '');
|
||||
};
|
||||
|
||||
// 主方
|
||||
$mainName = $lookup('主方', $mainHerbs);
|
||||
if ($mainName === '') {
|
||||
$mainName = trim((string) ($rx['prescription_name'] ?? ''));
|
||||
}
|
||||
|
||||
// 辅方:先读持久化字段
|
||||
$auxName = '';
|
||||
$auxUsage = $rx['aux_usage'] ?? null;
|
||||
if (\is_string($auxUsage) && $auxUsage !== '') {
|
||||
$decodedAux = json_decode($auxUsage, true);
|
||||
$auxUsage = \is_array($decodedAux) ? $decodedAux : null;
|
||||
}
|
||||
if (\is_array($auxUsage)) {
|
||||
$auxName = trim((string) ($auxUsage['prescription_name'] ?? ($auxUsage['library_name'] ?? '')));
|
||||
}
|
||||
if ($auxName === '') {
|
||||
$auxName = $lookup('辅方', $auxHerbs);
|
||||
}
|
||||
|
||||
return [$mainName, $auxName];
|
||||
}
|
||||
|
||||
/**
|
||||
* 药材集合匹配 key:每味 name:dosage(dosage 规整去尾零)排序后拼接,与处方库反查双方同口径。
|
||||
*/
|
||||
private static function herbSetMatchKeyForExport(array $herbs): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($herbs as $h) {
|
||||
if (!\is_array($h)) {
|
||||
continue;
|
||||
}
|
||||
$name = trim((string) ($h['name'] ?? ''));
|
||||
if ($name === '') {
|
||||
continue;
|
||||
}
|
||||
$dosage = (float) ($h['dosage'] ?? 0);
|
||||
if (floor($dosage) === $dosage) {
|
||||
$dStr = (string) (int) $dosage;
|
||||
} else {
|
||||
$dStr = rtrim(rtrim(number_format($dosage, 4, '.', ''), '0'), '.');
|
||||
}
|
||||
$parts[] = $name . ':' . $dStr;
|
||||
}
|
||||
sort($parts);
|
||||
|
||||
return implode('|', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成订单时把关联诊单的 assistant_id 清空,让患者回到「待分配」状态
|
||||
* 仅当该患者没有其它进行中的处方订单且无指派日志时才清空,避免误覆盖
|
||||
|
||||
@@ -16,7 +16,8 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
'prescription_name' => 'require|max:100',
|
||||
'formula_type' => 'in:主方,辅方',
|
||||
'herbs' => 'require|array',
|
||||
'is_public' => 'in:0,1'
|
||||
'is_public' => 'in:0,1',
|
||||
'disable_edit' => 'in:0,1'
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -27,7 +28,8 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
'formula_type.in' => '处方类型只能是主方或辅方',
|
||||
'herbs.require' => '药材列表不能为空',
|
||||
'herbs.array' => '药材列表格式错误',
|
||||
'is_public.in' => '是否公开参数错误'
|
||||
'is_public.in' => '是否公开参数错误',
|
||||
'disable_edit.in' => '禁用修改参数错误'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -35,7 +37,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
*/
|
||||
public function sceneAdd()
|
||||
{
|
||||
return $this->only(['prescription_name', 'formula_type', 'herbs', 'is_public']);
|
||||
return $this->only(['prescription_name', 'formula_type', 'herbs', 'is_public', 'disable_edit']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +45,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
*/
|
||||
public function sceneEdit()
|
||||
{
|
||||
return $this->only(['id', 'prescription_name', 'formula_type', 'herbs', 'is_public']);
|
||||
return $this->only(['id', 'prescription_name', 'formula_type', 'herbs', 'is_public', 'disable_edit']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user