更新
This commit is contained in:
@@ -16,9 +16,14 @@ namespace app\api\controller;
|
||||
|
||||
use app\adminapi\logic\tcm\DiagnosisLogic;
|
||||
use app\adminapi\logic\tcm\TrackingNoteLogic;
|
||||
use app\api\logic\tcm\DailyGamifyLogic;
|
||||
use app\api\logic\tcm\DailyFamilyLikeLogic;
|
||||
use app\api\logic\tcm\DailyShareLogic;
|
||||
use app\adminapi\logic\ConfigLogic;
|
||||
use app\common\model\tcm\Diagnosis;
|
||||
use app\common\model\tcm\BloodRecord;
|
||||
use app\common\model\tcm\DietRecord;
|
||||
use app\common\model\tcm\ExerciseRecord;
|
||||
|
||||
/**
|
||||
* 中医诊断控制器(供小程序调用)
|
||||
@@ -31,7 +36,7 @@ class TcmController extends BaseApiController
|
||||
* @notes 不需要登录的方法
|
||||
* @var array
|
||||
*/
|
||||
public array $notNeedLogin = ['getPatientSignature', 'diagnosisDetail', 'getDict', 'confirmDiagnosis', 'getCardList', 'getOrderByNo', 'patientHangupVideo', 'dailyTrackingWindow', 'dailyTrackingNotes'];
|
||||
public array $notNeedLogin = ['getPatientSignature', 'diagnosisDetail', 'getDict', 'confirmDiagnosis', 'getCardList', 'getOrderByNo', 'patientHangupVideo', 'dailySharePreview', 'dailyFamilyLike'];
|
||||
|
||||
/**
|
||||
* @notes 获取患者签名(供小程序调用)
|
||||
@@ -350,16 +355,13 @@ class TcmController extends BaseApiController
|
||||
$startDate = (string) $this->request->get('start_date', '');
|
||||
$endDate = (string) $this->request->get('end_date', '');
|
||||
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
$diagnosis = $check['diagnosis'];
|
||||
|
||||
try {
|
||||
// 患者端越权校验:诊单必须存在;如传入 patient_id 则须与诊单匹配
|
||||
$diagnosis = Diagnosis::where('id', $diagnosisId)->find();
|
||||
if (!$diagnosis) {
|
||||
return $this->fail('诊单不存在');
|
||||
}
|
||||
if ($patientId > 0 && (int) $diagnosis['patient_id'] !== $patientId) {
|
||||
return $this->fail('无权查看该诊单的日常记录');
|
||||
}
|
||||
@@ -393,15 +395,13 @@ class TcmController extends BaseApiController
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
$patientId = (int) $this->request->get('patient_id', 0);
|
||||
|
||||
if ($diagnosisId <= 0) {
|
||||
return $this->fail('诊单ID不能为空');
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
$diagnosis = $check['diagnosis'];
|
||||
|
||||
try {
|
||||
$diagnosis = Diagnosis::where('id', $diagnosisId)->find();
|
||||
if (!$diagnosis) {
|
||||
return $this->fail('诊单不存在');
|
||||
}
|
||||
if ($patientId > 0 && (int) $diagnosis['patient_id'] !== $patientId) {
|
||||
return $this->fail('无权查看该诊单的跟踪备注');
|
||||
}
|
||||
@@ -413,6 +413,28 @@ class TcmController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析小程序 form-urlencoded 提交的 JSON 字段
|
||||
*
|
||||
* @param mixed $raw
|
||||
* @param string $arrayKey ThinkPHP 数组字段名,如 badges/a
|
||||
* @return array
|
||||
*/
|
||||
private function decodeJsonPostField($raw, string $arrayKey): array
|
||||
{
|
||||
if (is_string($raw) && $raw !== '') {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (is_array($decoded)) {
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
if (is_array($raw)) {
|
||||
return $raw;
|
||||
}
|
||||
$arr = $this->request->post($arrayKey, []);
|
||||
return is_array($arr) ? $arr : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 校验当前登录患者是否拥有指定诊单(通过 diagnosis_view_records 关联)
|
||||
* @param int $diagnosisId
|
||||
@@ -630,6 +652,328 @@ class TcmController extends BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 获取稳糖乐园状态(积分、今日任务、可领取积分)
|
||||
*
|
||||
* 路由:GET /api/tcm/dailyGetGamify?diagnosis_id=:id
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailyGetGamify()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
$result = DailyGamifyLogic::getState((int) $this->userId, $diagnosisId);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyGamifyLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 给小树浇水(领取今日已完成任务的积分,服务端校验)
|
||||
*
|
||||
* 路由:POST /api/tcm/dailyWaterTree
|
||||
* 必填:diagnosis_id
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailyWaterTree()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->post('diagnosis_id', 0);
|
||||
$result = DailyGamifyLogic::waterTree((int) $this->userId, $diagnosisId);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyGamifyLogic::getError());
|
||||
}
|
||||
// 统一走 success,保证 msg 与 data 同时返回,前端可提示且刷新状态
|
||||
return $this->success($result['message'] ?? '操作成功', $result, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 日常记录-获取今日饮食记录
|
||||
*
|
||||
* 路由:GET /api/tcm/dailyTodayDietRecord?diagnosis_id=:id
|
||||
*/
|
||||
public function dailyTodayDietRecord()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
|
||||
try {
|
||||
$todayStart = strtotime(date('Y-m-d 00:00:00'));
|
||||
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
|
||||
$record = DietRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('record_date', '>=', $todayStart)
|
||||
->where('record_date', '<=', $todayEnd)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
|
||||
if (!$record) {
|
||||
return $this->data(['record' => null, 'today' => date('Y-m-d')]);
|
||||
}
|
||||
|
||||
$data = $record->toArray();
|
||||
$data['record_date'] = date('Y-m-d', (int) $data['record_date']);
|
||||
return $this->data(['record' => $data, 'today' => date('Y-m-d')]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 日常记录-保存今日饮食
|
||||
*
|
||||
* 路由:POST /api/tcm/dailySaveDietRecord
|
||||
*/
|
||||
public function dailySaveDietRecord()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->post('diagnosis_id', 0);
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
$diagnosis = $check['diagnosis'];
|
||||
|
||||
$breakfast = trim((string) $this->request->post('breakfast_foods', ''));
|
||||
$lunch = trim((string) $this->request->post('lunch_foods', ''));
|
||||
$dinner = trim((string) $this->request->post('dinner_foods', ''));
|
||||
$note = trim((string) $this->request->post('note', ''));
|
||||
|
||||
if ($breakfast === '' && $lunch === '' && $dinner === '') {
|
||||
return $this->fail('请至少填写一餐饮食');
|
||||
}
|
||||
|
||||
try {
|
||||
$todayStart = strtotime(date('Y-m-d 00:00:00'));
|
||||
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
|
||||
$existing = DietRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('record_date', '>=', $todayStart)
|
||||
->where('record_date', '<=', $todayEnd)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
|
||||
$payload = [
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'patient_id' => (int) $diagnosis['patient_id'],
|
||||
'record_date' => $todayStart,
|
||||
'breakfast_foods' => $breakfast,
|
||||
'lunch_foods' => $lunch,
|
||||
'dinner_foods' => $dinner,
|
||||
'note' => $note,
|
||||
];
|
||||
|
||||
if ($existing) {
|
||||
$payload['id'] = $existing['id'];
|
||||
DietRecord::update($payload);
|
||||
return $this->success('已更新今日饮食', ['id' => $existing['id']]);
|
||||
}
|
||||
|
||||
$created = DietRecord::create($payload);
|
||||
return $this->success('饮食记录已保存', ['id' => $created->id]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 日常记录-获取今日运动记录
|
||||
*
|
||||
* 路由:GET /api/tcm/dailyTodayExerciseRecord?diagnosis_id=:id
|
||||
*/
|
||||
public function dailyTodayExerciseRecord()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
|
||||
try {
|
||||
$todayStart = strtotime(date('Y-m-d 00:00:00'));
|
||||
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
|
||||
$record = ExerciseRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('record_date', '>=', $todayStart)
|
||||
->where('record_date', '<=', $todayEnd)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
|
||||
if (!$record) {
|
||||
return $this->data(['record' => null, 'today' => date('Y-m-d')]);
|
||||
}
|
||||
|
||||
$data = $record->toArray();
|
||||
$data['record_date'] = date('Y-m-d', (int) $data['record_date']);
|
||||
return $this->data(['record' => $data, 'today' => date('Y-m-d')]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 日常记录-保存今日运动
|
||||
*
|
||||
* 路由:POST /api/tcm/dailySaveExerciseRecord
|
||||
*/
|
||||
public function dailySaveExerciseRecord()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->post('diagnosis_id', 0);
|
||||
$check = $this->ensurePatientOwnsDiagnosis($diagnosisId);
|
||||
if (!$check['ok']) {
|
||||
return $this->fail($check['error']);
|
||||
}
|
||||
$diagnosis = $check['diagnosis'];
|
||||
|
||||
$exerciseType = trim((string) $this->request->post('exercise_type', ''));
|
||||
$durationRaw = $this->request->post('duration', '');
|
||||
$intensity = (int) $this->request->post('intensity', 2);
|
||||
$note = trim((string) $this->request->post('note', ''));
|
||||
|
||||
$duration = null;
|
||||
if ($durationRaw !== '' && $durationRaw !== null && is_numeric($durationRaw)) {
|
||||
$d = (int) $durationRaw;
|
||||
if ($d > 0) {
|
||||
$duration = $d;
|
||||
}
|
||||
}
|
||||
|
||||
if ($exerciseType === '' && $duration === null) {
|
||||
return $this->fail('请填写运动类型或时长');
|
||||
}
|
||||
|
||||
if ($intensity < 1 || $intensity > 3) {
|
||||
$intensity = 2;
|
||||
}
|
||||
|
||||
try {
|
||||
$todayStart = strtotime(date('Y-m-d 00:00:00'));
|
||||
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
|
||||
$existing = ExerciseRecord::where('diagnosis_id', $diagnosisId)
|
||||
->where('record_date', '>=', $todayStart)
|
||||
->where('record_date', '<=', $todayEnd)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
|
||||
$payload = [
|
||||
'diagnosis_id' => $diagnosisId,
|
||||
'patient_id' => (int) $diagnosis['patient_id'],
|
||||
'record_date' => $todayStart,
|
||||
'exercise_type' => $exerciseType,
|
||||
'duration' => $duration,
|
||||
'intensity' => $intensity,
|
||||
'note' => $note,
|
||||
];
|
||||
|
||||
if ($existing) {
|
||||
$payload['id'] = $existing['id'];
|
||||
ExerciseRecord::update($payload);
|
||||
return $this->success('已更新今日运动', ['id' => $existing['id']]);
|
||||
}
|
||||
|
||||
$created = ExerciseRecord::create($payload);
|
||||
return $this->success('运动记录已保存', ['id' => $created->id]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 保存稳糖分 / 勋章 / 任务领奖状态
|
||||
*
|
||||
* 路由:POST /api/tcm/dailySaveGamify
|
||||
* 参数:diagnosis_id, points, badges(数组), task_awards(对象)
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailySaveGamify()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->post('diagnosis_id', 0);
|
||||
$points = (int) $this->request->post('points', 0);
|
||||
$badges = $this->decodeJsonPostField($this->request->post('badges', ''), 'badges/a');
|
||||
$taskAwards = $this->decodeJsonPostField($this->request->post('task_awards', ''), 'task_awards/a');
|
||||
|
||||
$result = DailyGamifyLogic::saveState((int) $this->userId, $diagnosisId, $points, $badges, $taskAwards);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyGamifyLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 生成日常记录分享邀请码(仅当天有效)
|
||||
*
|
||||
* 路由:POST /api/tcm/dailyCreateShareInvite
|
||||
* 必填:diagnosis_id
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailyCreateShareInvite()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->post('diagnosis_id', 0);
|
||||
$result = DailyShareLogic::createInvite((int) $this->userId, $diagnosisId);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyShareLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 凭邀请码查看分享战报(无需登录,含近7日血糖/血压记录)
|
||||
*
|
||||
* 路由:GET /api/tcm/dailySharePreview?invite_code=XXXXXXXX
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailySharePreview()
|
||||
{
|
||||
$inviteCode = (string) $this->request->get('invite_code', '');
|
||||
$viewerKey = (string) $this->request->get('viewer_key', '');
|
||||
$result = DailyShareLogic::previewByInviteCode($inviteCode, $viewerKey);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyShareLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 家人点赞(邀请观看页,无需登录)
|
||||
*
|
||||
* 路由:POST /api/tcm/dailyFamilyLike
|
||||
* 必填:invite_code, viewer_key
|
||||
* 可选:nickname(家人/亲友/老伴 等)
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailyFamilyLike()
|
||||
{
|
||||
$inviteCode = (string) $this->request->post('invite_code', '');
|
||||
$viewerKey = (string) $this->request->post('viewer_key', '');
|
||||
$nickname = (string) $this->request->post('nickname', '');
|
||||
$result = DailyFamilyLikeLogic::addLike($inviteCode, $viewerKey, $nickname);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyFamilyLikeLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 患者查看今日家人点赞汇总
|
||||
*
|
||||
* 路由:GET /api/tcm/dailyFamilyLikeSummary?diagnosis_id=
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dailyFamilyLikeSummary()
|
||||
{
|
||||
$diagnosisId = (int) $this->request->get('diagnosis_id', 0);
|
||||
$result = DailyFamilyLikeLogic::summaryForPatient((int) $this->userId, $diagnosisId);
|
||||
if ($result === false) {
|
||||
return $this->fail(DailyFamilyLikeLogic::getError());
|
||||
}
|
||||
return $this->data($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notes 根据订单号获取订单详情(供小程序支付页调用)
|
||||
* @return \think\response\Json
|
||||
|
||||
Reference in New Issue
Block a user