代办任务
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\controller\tcm;
|
||||
|
||||
use app\adminapi\controller\BaseAdminController;
|
||||
use app\adminapi\lists\tcm\DiagnosisTodoLists;
|
||||
use app\adminapi\logic\tcm\DiagnosisTodoLogic;
|
||||
use app\adminapi\validate\tcm\DiagnosisTodoValidate;
|
||||
|
||||
/**
|
||||
* 诊单待办事项控制器
|
||||
*
|
||||
* 职责:仅 lists / add / cancel / detail;编辑能力故意不开放(要改 = 取消重建)
|
||||
*
|
||||
* @package app\adminapi\controller\tcm
|
||||
*/
|
||||
class DiagnosisTodoController extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @notes 待办列表(按 diagnosis_id)
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
(new DiagnosisTodoValidate())->goCheck('list');
|
||||
|
||||
return $this->dataLists(new DiagnosisTodoLists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 新增待办
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->post()->goCheck('add');
|
||||
$result = DiagnosisTodoLogic::add($params, $this->adminId, $this->adminInfo);
|
||||
if (!$result) {
|
||||
return $this->fail(DiagnosisTodoLogic::getError() ?: '创建失败');
|
||||
}
|
||||
|
||||
return $this->success('创建成功', [], 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 取消待办(仅 status=0 可取消,仅创建人/超管)
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->post()->goCheck('cancel');
|
||||
$result = DiagnosisTodoLogic::cancel((int) $params['id'], $this->adminId);
|
||||
if (!$result) {
|
||||
return $this->fail(DiagnosisTodoLogic::getError() ?: '取消失败');
|
||||
}
|
||||
|
||||
return $this->success('已取消', [], 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 待办详情
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$params = (new DiagnosisTodoValidate())->goCheck('detail');
|
||||
$result = DiagnosisTodoLogic::detail((int) $params['id'], $this->adminId);
|
||||
|
||||
return $this->data($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\lists\tcm;
|
||||
|
||||
use app\adminapi\lists\BaseAdminDataLists;
|
||||
use app\adminapi\logic\tcm\DiagnosisTodoLogic;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\tcm\DiagnosisTodo;
|
||||
|
||||
/**
|
||||
* 诊单待办事项列表
|
||||
*
|
||||
* 默认按 remind_time desc 排序;按 diagnosis_id 过滤。
|
||||
*
|
||||
* @package app\adminapi\lists\tcm
|
||||
*/
|
||||
class DiagnosisTodoLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
public function setSearch(): array
|
||||
{
|
||||
return [
|
||||
'=' => ['diagnosis_id', 'status', 'creator_id'],
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$lists = DiagnosisTodo::where($this->searchWhere)
|
||||
->field([
|
||||
'id', 'diagnosis_id', 'patient_id', 'content', 'remind_time',
|
||||
'status', 'creator_id', 'creator_name', 'notified_at', 'error',
|
||||
'cancelled_at', 'cancelled_by', 'create_time', 'update_time',
|
||||
])
|
||||
->append([
|
||||
'status_text',
|
||||
'remind_time_text',
|
||||
'notified_at_text',
|
||||
'cancelled_at_text',
|
||||
])
|
||||
->order('remind_time', 'desc')
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
// 业务态:是否能被「我」取消(前端按钮显隐用)
|
||||
$adminId = (int) $this->adminId;
|
||||
foreach ($lists as &$item) {
|
||||
$item['can_cancel'] = DiagnosisTodoLogic::canCancel($item, $adminId);
|
||||
}
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return DiagnosisTodo::where($this->searchWhere)->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\logic\tcm;
|
||||
|
||||
use app\common\logic\BaseLogic;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\auth\AdminRole;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\DiagnosisTodo;
|
||||
|
||||
/**
|
||||
* 诊单待办事项逻辑
|
||||
*
|
||||
* 状态机:
|
||||
* add() → status=0 (待执行)
|
||||
* cron → status=1 (已发送) / status=3 (失败)
|
||||
* cancel() → status=2 (已取消,仅 status=0 可取消)
|
||||
*
|
||||
* 鉴权:
|
||||
* add:诊单需存在;数据权限交由路由层「tcm.diagnosisTodo/add」节点 + 前端 tab disabled 控制。
|
||||
* cancel:仅创建人本人或超级管理员 (role_id=1) 可取消,且仅 status=0 时。
|
||||
*
|
||||
* @package app\adminapi\logic\tcm
|
||||
*/
|
||||
class DiagnosisTodoLogic extends BaseLogic
|
||||
{
|
||||
/**
|
||||
* @notes 新增待办
|
||||
*
|
||||
* @param array<string,mixed> $params 已通过 sceneAdd 验证
|
||||
* @param int $adminId 当前 admin id
|
||||
* @param array<string,mixed> $adminInfo request->adminInfo
|
||||
*/
|
||||
public static function add(array $params, int $adminId, array $adminInfo): bool
|
||||
{
|
||||
try {
|
||||
$diagnosisId = (int) ($params['diagnosis_id'] ?? 0);
|
||||
$diagnosis = Diagnosis::findOrEmpty($diagnosisId);
|
||||
if ($diagnosis->isEmpty()) {
|
||||
self::setError('诊单不存在');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$remindTime = (int) ($params['remind_time'] ?? 0);
|
||||
if ($remindTime <= time()) {
|
||||
self::setError('提醒时间必须晚于当前时间');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$creatorName = trim((string) ($adminInfo['name'] ?? ''));
|
||||
if ($creatorName === '' && $adminId > 0) {
|
||||
$creatorName = (string) Admin::where('id', $adminId)->value('name');
|
||||
}
|
||||
|
||||
DiagnosisTodo::create([
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'patient_id' => (int) ($diagnosis->getAttr('patient_id') ?? 0),
|
||||
'content' => trim((string) ($params['content'] ?? '')),
|
||||
'remind_time' => $remindTime,
|
||||
'status' => DiagnosisTodo::STATUS_PENDING,
|
||||
'creator_id' => $adminId,
|
||||
'creator_name' => $creatorName,
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
self::setError($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 取消待办(人工)
|
||||
*/
|
||||
public static function cancel(int $id, int $adminId): bool
|
||||
{
|
||||
try {
|
||||
$todo = DiagnosisTodo::findOrEmpty($id);
|
||||
if ($todo->isEmpty()) {
|
||||
self::setError('待办不存在');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$status = (int) $todo->getAttr('status');
|
||||
if ($status !== DiagnosisTodo::STATUS_PENDING) {
|
||||
self::setError('该待办已不是「待执行」状态,无法取消');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$creatorId = (int) $todo->getAttr('creator_id');
|
||||
$isSuper = self::isSuperAdmin($adminId);
|
||||
if ($creatorId !== $adminId && !$isSuper) {
|
||||
self::setError('仅创建人或超级管理员可取消');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$todo->save([
|
||||
'status' => DiagnosisTodo::STATUS_CANCELLED,
|
||||
'cancelled_at' => time(),
|
||||
'cancelled_by' => $adminId,
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
self::setError($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 详情
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public static function detail(int $id, int $adminId = 0): array
|
||||
{
|
||||
$todo = DiagnosisTodo::findOrEmpty($id);
|
||||
if ($todo->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
$arr = $todo->append([
|
||||
'status_text',
|
||||
'remind_time_text',
|
||||
'notified_at_text',
|
||||
'cancelled_at_text',
|
||||
])->toArray();
|
||||
|
||||
// 业务态:是否能被「我」取消(前端按钮显隐用)
|
||||
$arr['can_cancel'] = self::canCancel($todo->toArray(), $adminId);
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否超管:role_id=1
|
||||
*/
|
||||
public static function isSuperAdmin(int $adminId): bool
|
||||
{
|
||||
if ($adminId <= 0) {
|
||||
return false;
|
||||
}
|
||||
$roleIds = AdminRole::where('admin_id', $adminId)->column('role_id');
|
||||
|
||||
return in_array(1, array_map('intval', $roleIds), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务判定:当前 admin 能否取消该待办
|
||||
*
|
||||
* @param array<string,mixed> $todoRow
|
||||
*/
|
||||
public static function canCancel(array $todoRow, int $adminId): bool
|
||||
{
|
||||
if ((int) ($todoRow['status'] ?? -1) !== DiagnosisTodo::STATUS_PENDING) {
|
||||
return false;
|
||||
}
|
||||
if ($adminId <= 0) {
|
||||
return false;
|
||||
}
|
||||
if ((int) ($todoRow['creator_id'] ?? 0) === $adminId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return self::isSuperAdmin($adminId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeadmin快速开发前后端分离管理后台(PHP版)
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
|
||||
// | github下载:https://github.com/likeshop-github/likeadmin
|
||||
// | 访问官网:https://www.likeadmin.cn
|
||||
// | likeadmin团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeadminTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\adminapi\validate\tcm;
|
||||
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\DiagnosisTodo;
|
||||
use app\common\validate\BaseValidate;
|
||||
|
||||
/**
|
||||
* 诊单待办事项验证
|
||||
* Class DiagnosisTodoValidate
|
||||
* @package app\adminapi\validate\tcm
|
||||
*/
|
||||
class DiagnosisTodoValidate extends BaseValidate
|
||||
{
|
||||
protected $rule = [
|
||||
'id' => 'require|number',
|
||||
'diagnosis_id' => 'require|number|gt:0|checkDiagnosis',
|
||||
'content' => 'require|length:1,500',
|
||||
'remind_time' => 'require|number|checkRemindFuture',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'id.require' => '参数缺失',
|
||||
'diagnosis_id.require' => '诊单 id 不能为空',
|
||||
'diagnosis_id.gt' => '诊单 id 非法',
|
||||
'content.require' => '请输入提醒内容',
|
||||
'content.length' => '提醒内容长度需在 1-500 字',
|
||||
'remind_time.require' => '请选择提醒时间',
|
||||
'remind_time.number' => '提醒时间格式错误',
|
||||
];
|
||||
|
||||
public function sceneAdd()
|
||||
{
|
||||
return $this->only(['diagnosis_id', 'content', 'remind_time']);
|
||||
}
|
||||
|
||||
public function sceneCancel()
|
||||
{
|
||||
return $this->only(['id']);
|
||||
}
|
||||
|
||||
public function sceneDetail()
|
||||
{
|
||||
return $this->only(['id']);
|
||||
}
|
||||
|
||||
public function sceneList()
|
||||
{
|
||||
return $this->only(['diagnosis_id'])
|
||||
->append('diagnosis_id', 'require|number|gt:0');
|
||||
}
|
||||
|
||||
/**
|
||||
* 诊单存在校验
|
||||
*/
|
||||
protected function checkDiagnosis($value): bool|string
|
||||
{
|
||||
$diagnosis = Diagnosis::findOrEmpty((int) $value);
|
||||
if ($diagnosis->isEmpty()) {
|
||||
return '诊单不存在';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提醒时间必须在当前时间之后(至少 30 秒),避免立刻就过期
|
||||
*/
|
||||
protected function checkRemindFuture($value): bool|string
|
||||
{
|
||||
$ts = (int) $value;
|
||||
if ($ts <= time() + 30) {
|
||||
return '提醒时间必须晚于当前时间';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user