mirror of
https://github.com/kuaifan/dootask.git
synced 2026-06-25 08:42:14 +00:00
- composer: framework ^13.0、php ^8.3、laravel-s ~3.8.0、predis ^2.3、 phpunit ^11.5、tinker ^3、excel ^3.1.69、captcha ^3.5、avatar ^6.5、 ldaprecord-laravel ^4、pinyin ^5.3、notify 锁 ~1.28.0; 移除 fideloper/proxy、fruitcake/laravel-cors、facade/ignition、 laravel/sail、madnest/madzipper、手动钉的 symfony/mailer; symfony/console 锁 ^7.4(LaravelS Portal 与 console 8 的 configure(): void 类型断言不兼容) - $dates 移除:AbstractModel 改 getCasts() 合并默认 datetime 列, 3 个子模型改 $casts - Carbon 3:4 处 diffInSeconds 补 absolute 参数并取整 - LdapRecord v4:config use_ssl/use_tls→use_tls/use_starttls(env 变量名不变), LdapUser::$objectClasses 补类型声明 - Madzipper→原生 ZipArchive(Base::zipAddFiles,4 处调用) - pinyin v5 静态 API(Base::getFirstCharter/cn2pinyin) - laravolt/avatar 6.5:PatchedAvatar 修上游纵向对齐 bug (intervention 4.1.3 枚举无 middle),avatar 响应改 response()->file() - TrustProxies 改框架内置基类,CORS 改 Illuminate\Http\Middleware\HandleCors - Symfony Console 8 兼容:ManticoreSyncLock::handleSignal 新签名, pcntl 回调解耦 - 非 Swoole 运行时守卫:AbstractTask::task / PushTask::push / AbstractData(swoole table),artisan/测试上下文不再炸 Target class [swoole] does not exist - Laravel 11+ change() 丢修饰符:2023_12_07 与 2025_08_10 迁移重申 nullable/default/comment(修复 fresh 安装) - Setting/Ihttp 缺键访问加 ?? 守卫(PHP 8 警告在测试中转异常) - phpunit.xml 迁移 11 schema;UserImportParseTest 改为自建部门数据 验证:8.4 容器内 migrate:fresh --seed 213 全过;php artisan test 145 passed/1 skipped;LaravelS(Swoole 6.2.1) /health 200、登录、 token 认证、WebSocket 握手、Task 投递、头像、图片裁剪冒烟全过 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
139 lines
4.3 KiB
PHP
139 lines
4.3 KiB
PHP
<?php
|
||
|
||
namespace App\Models;
|
||
|
||
use Carbon\Carbon;
|
||
|
||
/**
|
||
* App\Models\UserTaskBrowse
|
||
*
|
||
* @property int $id
|
||
* @property int|null $userid 用户ID
|
||
* @property int|null $task_id 任务ID
|
||
* @property \Illuminate\Support\Carbon|null $browsed_at 浏览时间
|
||
* @property \Illuminate\Support\Carbon|null $created_at
|
||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||
* @property-read \App\Models\ProjectTask|null $task
|
||
* @property-read \App\Models\User|null $user
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelAppend()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel cancelHidden()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel change($array)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse newModelQuery()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse newQuery()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse query()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel remove()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereBrowsedAt($value)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereCreatedAt($value)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereId($value)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereTaskId($value)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereUpdatedAt($value)
|
||
* @method static \Illuminate\Database\Eloquent\Builder|UserTaskBrowse whereUserid($value)
|
||
* @mixin \Eloquent
|
||
*/
|
||
class UserTaskBrowse extends AbstractModel
|
||
{
|
||
protected $fillable = [
|
||
'userid',
|
||
'task_id',
|
||
'browsed_at',
|
||
];
|
||
|
||
protected $casts = [
|
||
'browsed_at' => 'datetime',
|
||
];
|
||
|
||
/**
|
||
* 关联用户
|
||
*/
|
||
public function user()
|
||
{
|
||
return $this->belongsTo(User::class, 'userid', 'userid');
|
||
}
|
||
|
||
/**
|
||
* 关联任务
|
||
*/
|
||
public function task()
|
||
{
|
||
return $this->belongsTo(ProjectTask::class, 'task_id', 'id');
|
||
}
|
||
|
||
/**
|
||
* 记录用户浏览任务
|
||
* @param int $userid 用户ID
|
||
* @param int $task_id 任务ID
|
||
* @return UserTaskBrowse
|
||
*/
|
||
public static function recordBrowse($userid, $task_id)
|
||
{
|
||
$record = self::updateOrCreate(
|
||
[
|
||
'userid' => $userid,
|
||
'task_id' => $task_id,
|
||
],
|
||
[
|
||
'browsed_at' => Carbon::now(),
|
||
]
|
||
);
|
||
|
||
UserRecentItem::record(
|
||
$userid,
|
||
UserRecentItem::TYPE_TASK,
|
||
$task_id,
|
||
UserRecentItem::SOURCE_PROJECT,
|
||
0
|
||
);
|
||
|
||
return $record;
|
||
}
|
||
|
||
/**
|
||
* 获取用户浏览历史
|
||
* @param int $userid 用户ID
|
||
* @param int $limit 获取数量
|
||
* @return \Illuminate\Database\Eloquent\Collection
|
||
*/
|
||
public static function getUserBrowseHistory($userid, $limit = 20)
|
||
{
|
||
return self::with(['task' => function ($query) {
|
||
$query->select([
|
||
'id', 'name', 'project_id', 'column_id', 'parent_id',
|
||
'flow_item_id', 'flow_item_name',
|
||
'complete_at', 'archived_at'
|
||
]);
|
||
}])
|
||
->whereUserid($userid)
|
||
->whereHas('task', function ($query) {
|
||
// 只获取存在且未被删除的任务
|
||
$query->whereNull('archived_at');
|
||
})
|
||
->orderByDesc('browsed_at')
|
||
->limit($limit)
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* 清理用户浏览历史
|
||
* @param int $userid 用户ID
|
||
* @param int $keepCount 保留数量,0表示全部删除
|
||
* @return int 删除的记录数
|
||
*/
|
||
public static function cleanUserBrowseHistory($userid, $keepCount = 100)
|
||
{
|
||
if ($keepCount === 0) {
|
||
return self::whereUserid($userid)->delete();
|
||
}
|
||
|
||
$keepIds = self::whereUserid($userid)
|
||
->orderByDesc('browsed_at')
|
||
->limit($keepCount)
|
||
->pluck('id');
|
||
|
||
return self::whereUserid($userid)
|
||
->whereNotIn('id', $keepIds)
|
||
->delete();
|
||
}
|
||
}
|