201 lines
7.1 KiB
PHP
201 lines
7.1 KiB
PHP
<?php
|
||
|
||
namespace app\api\logic\tcm;
|
||
|
||
use app\adminapi\logic\tcm\DiagnosisLogic;
|
||
use app\common\model\DiagnosisViewRecord;
|
||
use app\common\model\tcm\Diagnosis;
|
||
use app\common\model\user\User;
|
||
|
||
/**
|
||
* 日常血糖:手机号快捷建档(无完整就诊卡时)
|
||
*/
|
||
class DailyPhoneLogic
|
||
{
|
||
/** 小程序完整建档(edit_card) */
|
||
public const CREATE_SOURCE_MNP = 'mnp';
|
||
|
||
/** 小程序手机号快捷建档(日常血糖) */
|
||
public const CREATE_SOURCE_MNP_DAILY = 'mnp_daily';
|
||
|
||
/**
|
||
* 用户 sex(1男2女) → 诊单 gender(1男0女)
|
||
*/
|
||
public static function mapUserSexToDiagnosisGender($sex): int
|
||
{
|
||
$sex = (int) $sex;
|
||
if ($sex === 2) {
|
||
return 0;
|
||
}
|
||
if ($sex === 1) {
|
||
return 1;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* 已绑定手机号则返回可用诊单;无卡时自动创建轻量档案
|
||
*
|
||
* @param array{sex?:int|null} $options sex: 用户表 1男2女,授权手机号时可传入
|
||
* @return array{ok:bool,need_mobile?:bool,error?:string,created?:bool,diagnosis_id?:int,patient_id?:int,patient_name?:string,gender?:int,age?:int,mobile?:string,create_source?:string}
|
||
*/
|
||
public static function ensureDailyContext(int $userId, array $options = []): array
|
||
{
|
||
if ($userId <= 0) {
|
||
return ['ok' => false, 'need_mobile' => false, 'error' => '请先登录'];
|
||
}
|
||
|
||
$user = User::where('id', $userId)
|
||
->field('id,nickname,real_name,mobile,sex,age')
|
||
->find();
|
||
if (!$user) {
|
||
return ['ok' => false, 'need_mobile' => false, 'error' => '用户不存在'];
|
||
}
|
||
|
||
$mobile = trim((string) ($user['mobile'] ?? ''));
|
||
if ($mobile === '') {
|
||
return ['ok' => false, 'need_mobile' => true, 'error' => '请先授权手机号'];
|
||
}
|
||
|
||
if (array_key_exists('sex', $options) && $options['sex'] !== null && $options['sex'] !== '') {
|
||
$sex = (int) $options['sex'];
|
||
if (in_array($sex, [1, 2], true) && (int) ($user['sex'] ?? 0) !== $sex) {
|
||
User::update(['id' => $userId, 'sex' => $sex]);
|
||
$user['sex'] = $sex;
|
||
}
|
||
}
|
||
|
||
$cardList = DiagnosisLogic::getCardList($userId);
|
||
if ($cardList === false) {
|
||
return [
|
||
'ok' => false,
|
||
'need_mobile' => false,
|
||
'error' => DiagnosisLogic::getError() ?: '获取就诊卡失败',
|
||
];
|
||
}
|
||
|
||
if (!empty($cardList)) {
|
||
$card = $cardList[0];
|
||
return self::buildContextOk($card, $mobile, false, false);
|
||
}
|
||
|
||
// 该手机号已在诊单库建档:关联查看记录,禁止重复创建轻量档案
|
||
$existing = Diagnosis::where('phone', $mobile)
|
||
->where('delete_time', null)
|
||
->order('id', 'desc')
|
||
->find();
|
||
if ($existing && (int) ($existing['show_card'] ?? 1) !== 1) {
|
||
return [
|
||
'ok' => false,
|
||
'need_mobile' => false,
|
||
'error' => '该手机号对应就诊卡因隐私设置已隐藏,请联系医生',
|
||
];
|
||
}
|
||
if ($existing) {
|
||
if (!self::ensureUserViewRecord($userId, (int) $existing['id'], (int) $existing['patient_id'])) {
|
||
return [
|
||
'ok' => false,
|
||
'need_mobile' => false,
|
||
'error' => '该手机号已建档,暂无法关联到当前账号',
|
||
];
|
||
}
|
||
return self::buildContextOk([
|
||
'id' => (int) $existing['id'],
|
||
'patient_id' => (int) $existing['patient_id'],
|
||
'patient_name' => (string) ($existing['patient_name'] ?? ''),
|
||
'gender' => (int) ($existing['gender'] ?? 0),
|
||
'age' => (int) ($existing['age'] ?? 0),
|
||
'create_source' => (string) ($existing['create_source'] ?? ''),
|
||
], $mobile, false, true);
|
||
}
|
||
|
||
$displayName = trim((string) (($user['real_name'] ?? '') ?: ($user['nickname'] ?? '')));
|
||
if ($displayName === '') {
|
||
$displayName = '用户' . substr($mobile, -4);
|
||
}
|
||
|
||
$gender = self::mapUserSexToDiagnosisGender($user['sex'] ?? 1);
|
||
|
||
$result = DiagnosisLogic::addCard([
|
||
'user_id' => $userId,
|
||
'patient_name' => $displayName,
|
||
'phone' => $mobile,
|
||
'gender' => $gender,
|
||
'age' => max(0, (int) ($user['age'] ?? 0)),
|
||
'diagnosis_date' => time(),
|
||
'create_source' => self::CREATE_SOURCE_MNP_DAILY,
|
||
'remark' => '小程序手机号快捷建档(日常血糖)',
|
||
]);
|
||
|
||
if ($result === false) {
|
||
return [
|
||
'ok' => false,
|
||
'need_mobile' => false,
|
||
'error' => DiagnosisLogic::getError() ?: '创建档案失败',
|
||
];
|
||
}
|
||
|
||
return self::buildContextOk([
|
||
'id' => (int) $result['id'],
|
||
'patient_id' => (int) $result['patient_id'],
|
||
'patient_name' => $displayName,
|
||
'gender' => $gender,
|
||
'age' => max(0, (int) ($user['age'] ?? 0)),
|
||
'create_source' => self::CREATE_SOURCE_MNP_DAILY,
|
||
], $mobile, true, false);
|
||
}
|
||
|
||
/**
|
||
* @param array{id:int,patient_id:int,patient_name?:string,gender?:int,age?:int,create_source?:string} $card
|
||
*/
|
||
private static function buildContextOk(array $card, string $mobile, bool $created, bool $linkedExisting): array
|
||
{
|
||
return [
|
||
'ok' => true,
|
||
'need_mobile' => false,
|
||
'created' => $created,
|
||
'linked_existing' => $linkedExisting,
|
||
'diagnosis_id' => (int) $card['id'],
|
||
'patient_id' => (int) $card['patient_id'],
|
||
'patient_name' => (string) ($card['patient_name'] ?? ''),
|
||
'gender' => (int) ($card['gender'] ?? 0),
|
||
'age' => (int) ($card['age'] ?? 0),
|
||
'mobile' => $mobile,
|
||
'create_source' => (string) ($card['create_source'] ?? ''),
|
||
];
|
||
}
|
||
|
||
/** 将已有诊单挂到当前小程序用户(diagnosis_view_records) */
|
||
private static function ensureUserViewRecord(int $userId, int $diagnosisId, int $patientId): bool
|
||
{
|
||
if ($userId <= 0 || $diagnosisId <= 0) {
|
||
return false;
|
||
}
|
||
try {
|
||
$exists = DiagnosisViewRecord::where('user_id', $userId)
|
||
->where('diagnosis_id', $diagnosisId)
|
||
->where('delete_time', null)
|
||
->find();
|
||
if ($exists) {
|
||
return true;
|
||
}
|
||
$now = time();
|
||
DiagnosisViewRecord::create([
|
||
'user_id' => $userId,
|
||
'diagnosis_id' => $diagnosisId,
|
||
'patient_id' => $patientId,
|
||
'share_user_id' => 0,
|
||
'view_count' => 1,
|
||
'first_view_time' => $now,
|
||
'last_view_time' => $now,
|
||
'is_confirmed' => 0,
|
||
'create_time' => $now,
|
||
'update_time' => $now,
|
||
]);
|
||
return true;
|
||
} catch (\Throwable $e) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|