This commit is contained in:
Your Name
2026-08-05 11:08:02 +08:00
parent 57a7c415a1
commit c2b7018a22
429 changed files with 13316 additions and 350 deletions
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\firstvisit;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\auth\AuthLogic;
use app\adminapi\logic\firstvisit\FirstVisitConversionLogic;
class ConversionController extends BaseAdminController
{
private const PAGE_PERMISSION = 'firstvisit.conversion/overview';
public function overview()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法查看综合数据转化');
}
@set_time_limit(120);
return $this->data(FirstVisitConversionLogic::overview(
$this->request->get(),
$this->adminId,
$this->adminInfo
));
}
private function hasPagePermission(): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array(self::PAGE_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true);
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\firstvisit;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\auth\AuthLogic;
use app\adminapi\logic\firstvisit\FirstVisitDoctorDashboardLogic;
class DoctorDashboardController extends BaseAdminController
{
private const PAGE_PERMISSION = 'firstvisit.doctorDashboard/overview';
public function overview()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法查看医生看板');
}
@set_time_limit(120);
return $this->data(FirstVisitDoctorDashboardLogic::overview(
$this->request->get(),
$this->adminId,
$this->adminInfo
));
}
private function hasPagePermission(): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array(self::PAGE_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true);
}
}
@@ -0,0 +1,392 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\firstvisit;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\lists\firstvisit\MyPatientLists;
use app\adminapi\lists\firstvisit\MyPatientOrderLists;
use app\adminapi\lists\firstvisit\MyPatientProgressLists;
use app\adminapi\logic\auth\AuthLogic;
use app\adminapi\logic\doctor\AppointmentLogic;
use app\adminapi\logic\firstvisit\MyPatientLogic;
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
use app\adminapi\validate\doctor\AppointmentValidate;
use app\adminapi\validate\tcm\PrescriptionOrderValidate;
use app\common\model\doctor\Appointment;
use app\common\model\tcm\PrescriptionOrder;
class MyPatientController extends BaseAdminController
{
private const LIST_PERMISSION = 'firstvisit.myPatient/lists';
private string $orderGuardError = '订单不存在或无权操作';
public function lists()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法访问我的患者');
}
return $this->dataLists(new MyPatientLists());
}
/** 当前角色/部门患者范围内的处方业务订单。 */
public function orders()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法查看患者订单');
}
return $this->dataLists(new MyPatientOrderLists());
}
/** 当前角色/部门患者范围内的挂号面诊进度。 */
public function progress()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法查看面诊进度');
}
return $this->dataLists(new MyPatientProgressLists());
}
/** 当前患者范围内的订单详情;仍要求原订单详情权限。 */
public function orderDetail()
{
$params = (new PrescriptionOrderValidate())->get()->goCheck('detail');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/detail') === null) {
return $this->fail($this->orderGuardError);
}
$detail = PrescriptionOrderLogic::detail((int) $params['id'], $this->adminId, $this->adminInfo);
if ($detail === null) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->data($detail);
}
/** 编辑当前患者范围内的订单,参数只允许原编辑表单支持的字段。 */
public function orderEdit()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('edit');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/edit') === null) {
return $this->fail($this->orderGuardError);
}
if ((float) ($params['amount'] ?? 0) < 0) {
return $this->fail('订单金额不能为负数');
}
$params = $this->onlyParams($params, [
'id', 'recipient_name', 'recipient_phone', 'shipping_province', 'shipping_city',
'shipping_district', 'shipping_address', 'is_follow_up', 'medication_days',
'dose_unit', 'dose_count', 'prev_staff', 'service_channel', 'service_package',
'tracking_number', 'express_company', 'fee_type', 'amount', 'remark_extra',
'remark_assistant', 'pay_order_ids', 'internal_cost',
]);
$result = PrescriptionOrderLogic::edit($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('保存成功', $result);
}
public function orderAuditPrescription()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPrescription');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPrescription') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::auditPrescription(
(int) $params['id'],
(string) $params['action'],
(string) ($params['remark'] ?? ''),
$this->adminId,
$this->adminInfo
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('操作成功', $result);
}
public function orderRevokeRxAudit()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('detail');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPrescription') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::revokeRxAudit((int) $params['id'], $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('处方审核已撤回', $result);
}
public function orderAuditPayment()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('auditPayment');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPayment') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::auditPaymentSlip(
(int) $params['id'],
(string) $params['action'],
(string) ($params['remark'] ?? ''),
$this->adminId,
$this->adminInfo
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('操作成功', $result);
}
public function orderRevokePayAudit()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('detail');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPayment') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::revokePayAudit((int) $params['id'], $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('支付单审核已撤回', $result);
}
public function orderDdcode()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('ddcode');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/ddcode') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::ddcode(
(int) $params['id'],
(string) ($params['express_company'] ?? 'auto'),
(string) $params['tracking_number'],
$this->adminId,
$this->adminInfo
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('快递单号已保存', $result);
}
public function orderShip()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('ship');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/ship') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::ship(
(int) $params['id'],
(string) ($params['express_company'] ?? 'auto'),
(string) ($params['tracking_number'] ?? ''),
(string) ($params['ship_mode'] ?? 'gancao'),
$this->adminId,
$this->adminInfo
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('发货成功', $result);
}
public function orderAddPayOrder()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('addPayOrder');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/addPayOrder') === null) {
return $this->fail($this->orderGuardError);
}
$params = $this->onlyParams($params, [
'id', 'order_type', 'pay_amount', 'pay_remark', 'completion_request', 'pay_create_type',
]);
$result = PrescriptionOrderLogic::addPayOrder($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('新增支付单成功', $result);
}
public function orderComplete()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('complete');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/complete') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::complete(
(int) $params['id'],
$this->adminId,
$this->adminInfo,
(int) $params['fulfillment_status']
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('操作成功', $result);
}
public function orderRefund()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('refund');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/refund') === null) {
return $this->fail($this->orderGuardError);
}
$rawRefundAmount = $params['refund_amount'] ?? null;
$refundAmount = ($rawRefundAmount === null || $rawRefundAmount === '')
? null
: round((float) $rawRefundAmount, 2);
$result = PrescriptionOrderLogic::refund(
(int) $params['id'],
(string) ($params['reason'] ?? ''),
$this->adminId,
$this->adminInfo,
$refundAmount
);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('退款成功', $result);
}
public function orderWithdraw()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('withdraw');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/withdraw') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::withdraw((int) $params['id'], $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('已撤回', $result);
}
public function orderUploadToPharmacy()
{
$params = (new PrescriptionOrderValidate())->post()->goCheck('uploadToPharmacy');
if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/uploadToPharmacy') === null) {
return $this->fail($this->orderGuardError);
}
$result = PrescriptionOrderLogic::uploadToPharmacy((int) $params['id'], $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(PrescriptionOrderLogic::getError());
}
return $this->success('药方上传成功', $result);
}
/** 从“我的患者”页面创建挂号,写操作复用原逻辑但先做患者行级校验。 */
public function createAppointment()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法创建挂号');
}
$params = (new AppointmentValidate())->post()->goCheck('create');
$diagnosisId = (int) ($params['patient_id'] ?? 0);
if (!MyPatientLogic::canAccessDiagnosis($diagnosisId, $this->adminId, $this->adminInfo)) {
return $this->fail('患者不存在或无权操作');
}
$params['assistant_id'] = $this->adminId;
$result = AppointmentLogic::create($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(AppointmentLogic::getError());
}
return $this->success('挂号成功', $result);
}
/** 从“我的患者”页面取消挂号,按挂号所属诊单再次校验数据范围。 */
public function cancelAppointment()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法取消挂号');
}
$params = (new AppointmentValidate())->post()->goCheck('cancel');
$appointment = Appointment::findOrEmpty((int) ($params['id'] ?? 0));
if ($appointment->isEmpty()) {
return $this->fail('挂号记录不存在');
}
if (!MyPatientLogic::canAccessDiagnosis((int) $appointment->patient_id, $this->adminId, $this->adminInfo)) {
return $this->fail('患者不存在或无权操作');
}
$result = AppointmentLogic::cancel($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(AppointmentLogic::getError());
}
return $this->success('取消挂号成功');
}
private function hasPagePermission(): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array(self::LIST_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true);
}
private function hasOriginalPermission(string $permission): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array($permission, AuthLogic::getAuthByAdminId($this->adminId), true);
}
private function guardOrder(int $orderId, string $permission): ?PrescriptionOrder
{
$this->orderGuardError = '订单不存在或无权操作';
if (!$this->hasPagePermission() || !$this->hasOriginalPermission($permission) || $orderId <= 0) {
return null;
}
$order = PrescriptionOrder::where('id', $orderId)->whereNull('delete_time')->find();
if ($order === null) {
return null;
}
if (!MyPatientLogic::canAccessDiagnosis((int) $order->diagnosis_id, $this->adminId, $this->adminInfo)) {
return null;
}
return $order;
}
/** @param array<string,mixed> $params @param array<int,string> $keys */
private function onlyParams(array $params, array $keys): array
{
return array_intersect_key($params, array_flip($keys));
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\firstvisit;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\auth\AuthLogic;
use app\adminapi\logic\firstvisit\FirstVisitRegistrationStatsLogic;
class RegistrationStatsController extends BaseAdminController
{
private const PAGE_PERMISSION = 'firstvisit.registrationStats/overview';
public function overview()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法查看挂号统计');
}
@set_time_limit(120);
return $this->data(FirstVisitRegistrationStatsLogic::overview(
$this->request->get(),
$this->adminId,
$this->adminInfo
));
}
private function hasPagePermission(): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array(self::PAGE_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true);
}
}
@@ -0,0 +1,141 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\firstvisit;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\auth\AuthLogic;
use app\adminapi\logic\firstvisit\WecomPromotionLogic;
class WecomPromotionController extends BaseAdminController
{
private const PAGE_PERMISSION = 'firstvisit.wecomPromotion/overview';
public function overview()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足,无法访问企业微信推广助手');
}
return $this->run(fn () => $this->data(WecomPromotionLogic::overview(
$this->adminId,
$this->adminInfo,
$this->request->domain()
)));
}
public function authorizationUrl()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
return $this->run(fn () => $this->data(WecomPromotionLogic::authorizationUrl(
$this->adminId,
$this->adminInfo,
$this->request->domain()
)));
}
public function verifyAccount()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
$id = (int) $this->request->post('id', 0);
return $this->run(fn () => $this->success('凭证验证成功', WecomPromotionLogic::verifyAccount(
$id,
$this->adminId,
$this->adminInfo
)));
}
public function savePool()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
return $this->run(fn () => $this->success('分流方案已保存', WecomPromotionLogic::savePool(
$this->request->post(),
$this->adminId,
$this->adminInfo
)));
}
public function deletePool()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
$id = (int) $this->request->post('id', 0);
return $this->run(function () use ($id) {
WecomPromotionLogic::deletePool($id, $this->adminId, $this->adminInfo);
return $this->success('分流方案已删除');
});
}
public function saveLink()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
return $this->run(fn () => $this->success('推广链接已保存', WecomPromotionLogic::saveLink(
$this->request->post(),
$this->adminId,
$this->adminInfo
)));
}
public function toggleLink()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
$id = (int) $this->request->post('id', 0);
$status = (int) $this->request->post('status', 0);
return $this->run(function () use ($id, $status) {
WecomPromotionLogic::toggleLink($id, $status, $this->adminId, $this->adminInfo);
return $this->success('状态已更新');
});
}
public function deleteLink()
{
if (!$this->hasPagePermission()) {
return $this->fail('权限不足');
}
$id = (int) $this->request->post('id', 0);
return $this->run(function () use ($id) {
WecomPromotionLogic::deleteLink($id, $this->adminId, $this->adminInfo);
return $this->success('推广链接已删除');
});
}
private function run(callable $callback)
{
try {
return $callback();
} catch (\Throwable $e) {
return $this->fail($e->getMessage());
}
}
private function hasPagePermission(): bool
{
if ((int) ($this->adminInfo['root'] ?? 0) === 1) {
return true;
}
return in_array(self::PAGE_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true);
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\stats;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\stats\PerformanceDashboardLogic;
/**
* 角色数据驾驶舱。
*
* 所有数据在服务端按当前管理员的数据范围聚合,前端不参与权限裁剪。
*/
class PerformanceDashboardController extends BaseAdminController
{
public function overview()
{
@set_time_limit(120);
return $this->data(PerformanceDashboardLogic::overview($this->adminId, $this->adminInfo));
}
}