更新
This commit is contained in:
@@ -132,9 +132,42 @@ class AuthMiddleware
|
||||
return true;
|
||||
}
|
||||
|
||||
// 处方库列表:消费者开方页/处方库页导入共用,复用开方或处方库菜单权限
|
||||
if ($accessUri === 'tcm.prescriptionlibrary/lists'
|
||||
&& $this->matchPrescriptionLibraryListsPermission($adminUris)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方库 lists:与开方、处方库维护菜单权限互通(避免开方页「从处方库导入」403)
|
||||
*/
|
||||
private function matchPrescriptionLibraryListsPermission(array $adminUris): bool
|
||||
{
|
||||
$aliases = [
|
||||
'tcm.prescriptionlibrary/lists',
|
||||
'tcm.prescription/lists',
|
||||
'tcm.prescription/add',
|
||||
'tcm.prescription/edit',
|
||||
'tcm.prescription/detail',
|
||||
'cf.prescription/lists',
|
||||
'cf.prescription/add',
|
||||
'cf.prescription/edit',
|
||||
'cf.prescription/read',
|
||||
'cf.prescription/del',
|
||||
'cf.prescription/audit',
|
||||
'wcf.prescription/lists',
|
||||
'wcf.prescription/read',
|
||||
'wcf.prescription/add',
|
||||
'wcf.prescription/edit',
|
||||
'wcf.prescription/delete',
|
||||
];
|
||||
|
||||
return count(array_intersect($aliases, $adminUris)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 面诊进度专用:auth.admin/lists、doctor.appointment/lists + progress_board=1,不校验菜单权限
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@ class PrescriptionLibraryLists extends BaseAdminDataLists implements ListsSearch
|
||||
{
|
||||
return [
|
||||
'%like%' => ['prescription_name'],
|
||||
'=' => ['is_public', 'creator_id']
|
||||
'=' => ['is_public', 'creator_id', 'formula_type']
|
||||
];
|
||||
}
|
||||
|
||||
@@ -34,6 +34,16 @@ class PrescriptionLibraryLists extends BaseAdminDataLists implements ListsSearch
|
||||
return $query;
|
||||
}
|
||||
|
||||
// 开方页导入专用参数(勿与搜索项 creator_id 混用,否则无法 OR 出他人公开模板)
|
||||
$prescribingCreatorId = (int) ($this->params['prescribing_creator_id'] ?? 0);
|
||||
if ($prescribingCreatorId > 0
|
||||
&& PrescriptionLibraryLogic::canListLibraryForCreator($this->adminId, $this->adminInfo, $prescribingCreatorId)) {
|
||||
return $query->where(function ($q) use ($prescribingCreatorId) {
|
||||
$q->where('creator_id', $prescribingCreatorId)
|
||||
->whereOr('is_public', 1);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->where(function ($q) {
|
||||
$q->where('creator_id', $this->adminId)
|
||||
->whereOr('is_public', 1);
|
||||
@@ -46,7 +56,7 @@ class PrescriptionLibraryLists extends BaseAdminDataLists implements ListsSearch
|
||||
public function lists(): array
|
||||
{
|
||||
$field = [
|
||||
'id', 'prescription_name', 'herbs', 'is_public',
|
||||
'id', 'prescription_name', 'formula_type', 'herbs', 'is_public',
|
||||
'creator_id', 'creator_name', 'create_time', 'update_time'
|
||||
];
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\tcm;
|
||||
|
||||
use app\common\cache\AdminAuthCache;
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\auth\AdminRole;
|
||||
use app\common\model\tcm\PrescriptionLibrary;
|
||||
@@ -33,12 +34,64 @@ class PrescriptionLibraryLogic extends BaseLogic
|
||||
return count(array_intersect($myRoles, $allowRoles)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 是否具备消费者/诊间开方相关菜单权限(用于处方库列表鉴权别名)
|
||||
*/
|
||||
public static function hasPrescriptionOperatePermission(int $adminId): bool
|
||||
{
|
||||
$cache = new AdminAuthCache($adminId);
|
||||
$uris = $cache->getAdminUri() ?? [];
|
||||
$normalized = array_map(static fn ($item) => strtolower((string) $item), $uris);
|
||||
$allowed = [
|
||||
'tcm.prescription/lists',
|
||||
'tcm.prescription/add',
|
||||
'tcm.prescription/edit',
|
||||
'tcm.prescription/detail',
|
||||
'cf.prescription/lists',
|
||||
'cf.prescription/add',
|
||||
'cf.prescription/edit',
|
||||
'cf.prescription/read',
|
||||
'cf.prescription/del',
|
||||
'cf.prescription/audit',
|
||||
'wcf.prescription/lists',
|
||||
'wcf.prescription/read',
|
||||
'wcf.prescription/add',
|
||||
'wcf.prescription/edit',
|
||||
'wcf.prescription/delete',
|
||||
'tcm.prescriptionlibrary/lists',
|
||||
];
|
||||
|
||||
return count(array_intersect($allowed, $normalized)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 开方页按医师 creator_id 拉取处方库:本人 / 超管角色 / 有开方菜单权限(医助代开方)
|
||||
*/
|
||||
public static function canListLibraryForCreator(int $adminId, array $adminInfo, int $targetCreatorId): bool
|
||||
{
|
||||
if ($targetCreatorId <= 0) {
|
||||
return false;
|
||||
}
|
||||
if ($targetCreatorId === $adminId) {
|
||||
return true;
|
||||
}
|
||||
if (self::canManageAllPrescriptions($adminId, $adminInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return self::hasPrescriptionOperatePermission($adminId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 添加处方库
|
||||
*/
|
||||
public static function add(array $params): ?int
|
||||
{
|
||||
try {
|
||||
$params['formula_type'] = in_array($params['formula_type'] ?? '', ['主方', '辅方'], true)
|
||||
? $params['formula_type']
|
||||
: '主方';
|
||||
|
||||
// 处理药材数据
|
||||
if (isset($params['herbs']) && is_array($params['herbs'])) {
|
||||
$params['herbs'] = json_encode($params['herbs'], JSON_UNESCAPED_UNICODE);
|
||||
@@ -69,6 +122,12 @@ class PrescriptionLibraryLogic extends BaseLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($params['formula_type'])) {
|
||||
$params['formula_type'] = in_array($params['formula_type'], ['主方', '辅方'], true)
|
||||
? $params['formula_type']
|
||||
: '主方';
|
||||
}
|
||||
|
||||
// 处理药材数据
|
||||
if (isset($params['herbs']) && is_array($params['herbs'])) {
|
||||
$params['herbs'] = json_encode($params['herbs'], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
@@ -159,6 +159,35 @@ class PrescriptionLogic
|
||||
return $ts ? date('Y-m-d', $ts) : date('Y-m-d');
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 辅方用法 JSON(与主方 dosage/times/days 字段结构一致)
|
||||
*/
|
||||
private static function normalizeAuxUsage(array $params): ?array
|
||||
{
|
||||
$raw = $params['aux_usage'] ?? null;
|
||||
if ($raw === null || $raw === '' || $raw === []) {
|
||||
return null;
|
||||
}
|
||||
if (is_string($raw)) {
|
||||
$decoded = json_decode($raw, true);
|
||||
$raw = is_array($decoded) ? $decoded : null;
|
||||
}
|
||||
if (!is_array($raw)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'dosage_amount' => isset($raw['dosage_amount']) && $raw['dosage_amount'] !== ''
|
||||
? (float) $raw['dosage_amount']
|
||||
: null,
|
||||
'dosage_bag_count' => self::normalizeDosageBagCount($raw['dosage_bag_count'] ?? 1),
|
||||
'need_decoction' => (int) ($raw['need_decoction'] ?? 0),
|
||||
'bags_per_dose' => isset($raw['bags_per_dose']) ? (int) $raw['bags_per_dose'] : 1,
|
||||
'times_per_day' => (int) ($raw['times_per_day'] ?? 3),
|
||||
'usage_days' => (int) ($raw['usage_days'] ?? 7),
|
||||
];
|
||||
}
|
||||
|
||||
private static function normalizeDosageBagCount($raw): int
|
||||
{
|
||||
$count = (int) $raw;
|
||||
@@ -273,6 +302,7 @@ class PrescriptionLogic
|
||||
'dose_unit' => $params['dose_unit'] ?? '剂',
|
||||
'usage_days' => (int)($params['usage_days'] ?? 7),
|
||||
'times_per_day' => (int)($params['times_per_day'] ?? 2),
|
||||
'aux_usage' => self::normalizeAuxUsage($params),
|
||||
'usage_instruction' => $params['usage_instruction'] ?? '水煎服一日二次',
|
||||
'usage_time' => $params['usage_time'] ?? '饭前',
|
||||
'usage_way' => $params['usage_way'] ?? '温水送服',
|
||||
@@ -398,6 +428,9 @@ class PrescriptionLogic
|
||||
'dose_unit' => $params['dose_unit'] ?? $prescription->dose_unit,
|
||||
'usage_days' => (int)($params['usage_days'] ?? $prescription->usage_days),
|
||||
'times_per_day' => (int)($params['times_per_day'] ?? $prescription->times_per_day ?? 2),
|
||||
'aux_usage' => array_key_exists('aux_usage', $params)
|
||||
? self::normalizeAuxUsage($params)
|
||||
: $prescription->aux_usage,
|
||||
'usage_instruction' => $params['usage_instruction'] ?? $prescription->usage_instruction,
|
||||
'usage_time' => $params['usage_time'] ?? $prescription->usage_time,
|
||||
'usage_way' => $params['usage_way'] ?? $prescription->usage_way,
|
||||
|
||||
@@ -1413,6 +1413,7 @@ class PrescriptionOrderLogic
|
||||
|
||||
$payload['official_urls'] = ExpressTrackService::officialUrls($num);
|
||||
$payload['tracking_number'] = $num;
|
||||
$payload['order_id'] = $id;
|
||||
$payload['express_company_used'] = $ec;
|
||||
|
||||
return $payload;
|
||||
@@ -2556,7 +2557,7 @@ class PrescriptionOrderLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出用:诊单医助在 admin_dept 中的部门路径(多部门「;」、路径内「 / 」)
|
||||
* 导出用:管理员在 admin_dept 中的部门路径(多部门「;」、路径内「 / 」;业务订单导出取 creator_id)
|
||||
*/
|
||||
public static function formatAssistantDeptPathForExport(int $assistantAdminId): string
|
||||
{
|
||||
@@ -2846,21 +2847,21 @@ class PrescriptionOrderLogic
|
||||
$item['export_patient_gender'] = $g === 1 ? '男' : '女';
|
||||
$item['export_patient_age'] = (string) ($dg['age'] ?? '');
|
||||
$item['export_patient_phone'] = (string) ($dg['phone'] ?? '');
|
||||
$rxAst = \is_array($rx) ? (int) ($rx['assistant_id'] ?? 0) : 0;
|
||||
$diagAst = (int) ($dg['assistant_id'] ?? 0);
|
||||
$astId = self::resolveAssistantAdminIdForPrescriptionOrderRow($rxAst, $diagAst);
|
||||
if ($astId > 0) {
|
||||
if (!isset($assistantDeptCache[$astId])) {
|
||||
$assistantDeptCache[$astId] = self::formatAssistantDeptPathForExport($astId);
|
||||
}
|
||||
$item['export_assistant_dept'] = $assistantDeptCache[$astId];
|
||||
} else {
|
||||
$item['export_assistant_dept'] = '';
|
||||
}
|
||||
} else {
|
||||
$item['export_patient_gender'] = '';
|
||||
$item['export_patient_age'] = '';
|
||||
$item['export_patient_phone'] = '';
|
||||
}
|
||||
|
||||
// 导出「医助名字 / 医助部门」:与详情 order_creator 一致,按业务订单 creator_id(非诊单二诊 assistant_id)
|
||||
$creatorId = (int) ($item['creator_id'] ?? 0);
|
||||
$item['assistant_name'] = (string) ($item['creator_name'] ?? '');
|
||||
if ($creatorId > 0) {
|
||||
if (!isset($assistantDeptCache[$creatorId])) {
|
||||
$assistantDeptCache[$creatorId] = self::formatAssistantDeptPathForExport($creatorId);
|
||||
}
|
||||
$item['export_assistant_dept'] = $assistantDeptCache[$creatorId];
|
||||
} else {
|
||||
$item['export_assistant_dept'] = '';
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
protected $rule = [
|
||||
'id' => 'require|number',
|
||||
'prescription_name' => 'require|max:100',
|
||||
'formula_type' => 'in:主方,辅方',
|
||||
'herbs' => 'require|array',
|
||||
'is_public' => 'in:0,1'
|
||||
];
|
||||
@@ -23,6 +24,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
'id.number' => '处方ID必须为数字',
|
||||
'prescription_name.require' => '处方名称不能为空',
|
||||
'prescription_name.max' => '处方名称最多100个字符',
|
||||
'formula_type.in' => '处方类型只能是主方或辅方',
|
||||
'herbs.require' => '药材列表不能为空',
|
||||
'herbs.array' => '药材列表格式错误',
|
||||
'is_public.in' => '是否公开参数错误'
|
||||
@@ -33,7 +35,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
*/
|
||||
public function sceneAdd()
|
||||
{
|
||||
return $this->only(['prescription_name', 'herbs', 'is_public']);
|
||||
return $this->only(['prescription_name', 'formula_type', 'herbs', 'is_public']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +43,7 @@ class PrescriptionLibraryValidate extends BaseValidate
|
||||
*/
|
||||
public function sceneEdit()
|
||||
{
|
||||
return $this->only(['id', 'prescription_name', 'herbs', 'is_public']);
|
||||
return $this->only(['id', 'prescription_name', 'formula_type', 'herbs', 'is_public']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ class PrescriptionValidate extends BaseValidate
|
||||
'patient_name', 'gender', 'age',
|
||||
'visit_no', 'prescription_date', 'tongue', 'tongue_image', 'pulse',
|
||||
'pulse_condition', 'clinical_diagnosis', 'herbs', 'dose_count', 'dose_unit',
|
||||
'usage_days', 'times_per_day', 'usage_instruction', 'usage_time', 'usage_way', 'dietary_taboo',
|
||||
'usage_days', 'times_per_day', 'aux_usage', 'usage_instruction', 'usage_time', 'usage_way', 'dietary_taboo',
|
||||
'usage_notes', 'doctor_name', 'is_shared', 'visible_role_ids',
|
||||
'diagnosis_id', 'appointment_id', 'audit_status',
|
||||
]);
|
||||
@@ -54,7 +54,7 @@ class PrescriptionValidate extends BaseValidate
|
||||
'patient_name', 'gender', 'age',
|
||||
'visit_no', 'prescription_date', 'tongue', 'tongue_image', 'pulse',
|
||||
'pulse_condition', 'clinical_diagnosis', 'herbs', 'dose_count', 'dose_unit',
|
||||
'usage_days', 'times_per_day', 'usage_instruction', 'usage_time', 'usage_way', 'dietary_taboo',
|
||||
'usage_days', 'times_per_day', 'aux_usage', 'usage_instruction', 'usage_time', 'usage_way', 'dietary_taboo',
|
||||
'usage_notes', 'doctor_name', 'is_shared', 'visible_role_ids', 'diagnosis_id',
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user