Files
zyt/server/app/api/logic/tcm/DailyFamilyLikeLogic.php
T
2026-05-27 15:50:54 +08:00

251 lines
7.7 KiB
PHP

<?php
namespace app\api\logic\tcm;
use app\common\model\tcm\DailyFamilyLike;
use app\common\model\tcm\DailyShareInvite;
/**
* 家人点赞(邀请观看页 → 患者日常页展示)
*/
class DailyFamilyLikeLogic
{
protected static string $error = '';
/** @var string[] */
protected static array $praisePool = [
'坚持得很好,为您点赞!',
'每天记录真棒,继续保持!',
'您的自律让人佩服!',
'加油,家人一直支持您!',
'稳糖路上,您并不孤单!',
'好习惯正在养成,真为您高兴!',
];
public static function getError(): string
{
return self::$error;
}
protected static function setError(string $msg): bool
{
self::$error = $msg;
return false;
}
/**
* 校验当日邀请码
*
* @return array{diagnosis_id:int,invite_code:string}|false
*/
protected static function resolveInvite(string $inviteCode): array|false
{
$inviteCode = strtoupper(trim($inviteCode));
if ($inviteCode === '') {
return self::setError('邀请码不能为空') ? false : false;
}
$row = DailyShareInvite::where('invite_code', $inviteCode)->find();
if (!$row) {
return self::setError('邀请码无效或已失效') ? false : false;
}
$today = date('Y-m-d');
if ((string) $row['invite_date'] !== $today) {
return self::setError('邀请码已过期,仅可在分享当天点赞') ? false : false;
}
return [
'diagnosis_id' => (int) $row['diagnosis_id'],
'invite_code' => $inviteCode,
];
}
protected static function normalizeViewerKey(string $viewerKey): string
{
$viewerKey = preg_replace('/[^\w\-]/', '', trim($viewerKey)) ?? '';
if (strlen($viewerKey) < 8) {
return '';
}
return substr($viewerKey, 0, 64);
}
protected static function normalizeNickname(string $nickname): string
{
$nickname = trim($nickname);
if ($nickname === '') {
return '家人';
}
$nickname = mb_substr($nickname, 0, 8, 'UTF-8');
return $nickname !== '' ? $nickname : '家人';
}
public static function countToday(int $diagnosisId, ?string $likeDate = null): int
{
$likeDate = $likeDate ?: date('Y-m-d');
return (int) DailyFamilyLike::where('diagnosis_id', $diagnosisId)
->where('like_date', $likeDate)
->count();
}
public static function likedByViewer(int $diagnosisId, string $viewerKey, ?string $likeDate = null): bool
{
$viewerKey = self::normalizeViewerKey($viewerKey);
if ($viewerKey === '') {
return false;
}
$likeDate = $likeDate ?: date('Y-m-d');
return DailyFamilyLike::where('diagnosis_id', $diagnosisId)
->where('like_date', $likeDate)
->where('viewer_key', $viewerKey)
->find() !== null;
}
/**
* 邀请预览附加点赞信息
*/
public static function metaForInvite(string $inviteCode, string $viewerKey = ''): array
{
$resolved = self::resolveInvite($inviteCode);
if ($resolved === false) {
return [
'like_count' => 0,
'liked_by_me' => false,
];
}
$diagnosisId = $resolved['diagnosis_id'];
$viewerKey = self::normalizeViewerKey($viewerKey);
return [
'like_count' => self::countToday($diagnosisId),
'liked_by_me' => $viewerKey !== '' && self::likedByViewer($diagnosisId, $viewerKey),
];
}
/**
* 家人点赞(无需登录)
*/
public static function addLike(string $inviteCode, string $viewerKey, string $nickname = ''): array|false
{
self::$error = '';
$resolved = self::resolveInvite($inviteCode);
if ($resolved === false) {
return false;
}
$viewerKey = self::normalizeViewerKey($viewerKey);
if ($viewerKey === '') {
return self::setError('设备标识无效,请重试') ? false : false;
}
$diagnosisId = $resolved['diagnosis_id'];
$likeDate = date('Y-m-d');
$nickname = self::normalizeNickname($nickname);
$exists = DailyFamilyLike::where('diagnosis_id', $diagnosisId)
->where('like_date', $likeDate)
->where('viewer_key', $viewerKey)
->find();
if ($exists) {
return [
'already_liked' => true,
'like_count' => self::countToday($diagnosisId, $likeDate),
'praise_message' => '您今天已经点过赞啦,谢谢您的鼓励',
'nickname' => (string) ($exists['nickname'] ?? '家人'),
];
}
$todayCount = self::countToday($diagnosisId, $likeDate);
if ($todayCount >= 50) {
return self::setError('今日点赞已满,明天再来吧') ? false : false;
}
DailyFamilyLike::create([
'diagnosis_id' => $diagnosisId,
'like_date' => $likeDate,
'invite_code' => $resolved['invite_code'],
'viewer_key' => $viewerKey,
'nickname' => $nickname,
'create_time' => time(),
]);
$likeCount = self::countToday($diagnosisId, $likeDate);
$idx = $likeCount > 0 ? ($likeCount - 1) % count(self::$praisePool) : 0;
return [
'already_liked' => false,
'like_count' => $likeCount,
'praise_message' => self::$praisePool[$idx],
'nickname' => $nickname,
];
}
/**
* 患者查看今日家人点赞(需登录且拥有诊单)
*/
public static function summaryForPatient(int $userId, int $diagnosisId): array|false
{
self::$error = '';
if ($userId <= 0) {
return self::setError('请先登录') ? false : false;
}
if ($diagnosisId <= 0) {
return self::setError('诊单ID不能为空') ? false : false;
}
$owned = \think\facade\Db::name('diagnosis_view_records')
->where('user_id', $userId)
->where('diagnosis_id', $diagnosisId)
->where('delete_time', null)
->find();
if (!$owned) {
return self::setError('无权查看该诊单') ? false : false;
}
$likeDate = date('Y-m-d');
$count = self::countToday($diagnosisId, $likeDate);
$rows = DailyFamilyLike::where('diagnosis_id', $diagnosisId)
->where('like_date', $likeDate)
->order('id', 'desc')
->limit(8)
->select()
->toArray();
$recent = [];
foreach ($rows as $r) {
$recent[] = [
'nickname' => (string) ($r['nickname'] ?? '家人'),
'time_label' => self::timeLabel((int) ($r['create_time'] ?? 0)),
];
}
$summaryLine = $count > 0
? "今日有 {$count} 位家人为您点赞,继续加油!"
: '分享战报给家人,邀请他们为您点赞鼓劲';
return [
'like_count' => $count,
'summary_line' => $summaryLine,
'recent' => $recent,
];
}
protected static function timeLabel(int $ts): string
{
if ($ts <= 0) {
return '刚刚';
}
$diff = time() - $ts;
if ($diff < 60) {
return '刚刚';
}
if ($diff < 3600) {
return (int) floor($diff / 60) . '分钟前';
}
return date('H:i', $ts);
}
}