* @date 2020-01-31 10:39:38 */ declare(strict_types=1); namespace App\Repositories; use App\Constants\SysMessageConstant; use App\Model\Mongo\MessageModel; use App\Model\SysMessageModel; use Carbon\Carbon; use KZ2\Repositories\Model\Repository; use Psr\SimpleCache\CacheInterface; class SysMessageRepository extends Repository { public function model() { return SysMessageModel::class; } public function getTopLists() { $cacheRepo = make(CacheInterface::class); $cacheSeconds = 3 * 60 * 60; $arrItems = $cacheRepo->remember( SysMessageConstant::CACHE_KEY_LAST_TOP, $cacheSeconds, function () { $nowDate = Carbon::now()->subMinutes(15)->toDateTimeString(); $arrItems = []; $lists = SysMessageModel::query() ->whereDate('expired_at', '>=', $nowDate) // 排序是升序,主要方便逐步insert到用户消息集合里. ->orderBy('created_at', 'ASC') ->take(SysMessageConstant::LAST_TOP_NUM)->get(); if ($lists->count()) { $arrItems = $lists->toArray(); } return $arrItems; }); return $arrItems; } /** * 针对单个用户初始化他的系统消息. * @param $userCode * @return bool */ public function initForUser($userCode) { $nowDate = toMongoIsoDate(Carbon::now()); $arrSys = $this->getTopLists(); if (!empty($arrSys)) { foreach ($arrSys as $item) { $filters = [ // 有索引,必须是这个顺序. 'receive_uid' => $userCode, 'from_type' => 'sys', 'sys_msg_uid' => $item['uid'], ]; $options = []; $msgObj = make(MessageModel::class)->db()->findOne($filters, $options); if (empty($msgObj)) { $sysCreatedAt = Carbon::parse($item['created_at']); $createdAt = toMongoIsoDate($sysCreatedAt); // 没有则创建, 系统消息是不能删除的. $setarr = [ 'subject' => $item['subject'], 'struct_type' => $item['struct_type'], 'receive_uid' => $userCode, 'receive_type' => 'user', 'from_uid' => '', 'from_type' => 'sys', 'sys_msg_uid' => $item['uid'], 'content' => $item['content'], 'created_at' => $createdAt, 'updated_at' => $nowDate, 'read_at' => null, // null代表未阅读 ]; make(MessageModel::class)->db()->insertOne($setarr); } } } return true; } /** * 用户的系统消息分页. * @param string $userCode 用户UID * @param int $page 当前页 * @param int $pageSize 分页尺码 * @return array */ public function getSysPagesByUserCode($userCode, $page = 1, $pageSize = 20) { $page = format_page($page); $pageSize = intval($pageSize); $filters = [ 'receive_uid' => $userCode, 'from_type' => 'sys', ]; $optionsBase = [ 'sort' => [ 'created_at' => -1, // 时间降序 ], ]; $countOptions = $optionsBase; $pagesOptions = $optionsBase; $pagesOptions['limit'] = $pageSize; $result = [ 'total' => 0, 'data' => [], 'current_page' => $page, 'per_page' => $pageSize, ]; $count = make(MessageModel::class)->db()->countDocuments($filters, $countOptions); $cursor = make(MessageModel::class)->db()->find($filters, $pagesOptions); if ($count > 0) { $result['data'] = $cursor->toArray(); } $result['total'] = $count; return $result; } /** * 创建一个系统消息 * @param array $setarr * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model */ public function createOne(array $setarr) { if (empty($setarr['expired_at'])) { $exipredAt = Carbon::now()->addMonths(1)->toDateTimeString(); } else { $exipredAt = $setarr['expired_at']; } $item = [ 'subject' => data_get($setarr, 'subject', ''), 'struct_type' => data_get($setarr, 'struct_type', 'text'), 'content' => data_get($setarr, 'content', []), 'expired_at' => $exipredAt, ]; $obj = SysMessageModel::query()->create($item); if ($obj) { $this->clearTopCache(); } return $obj; } /** * 更新一个系统消息. * @param string $uid * @param array $setarr * @return mixed|array */ public function updateOne(string $uid, array $setarr) { $resultInfo = [ 'is_ok' => true, 'old' => null, 'new' => null, ]; $item = SysMessageModel::query()->where(['uid' => $uid])->firstOrFail(); $resultInfo['old'] = clone $item; if (isset($setarr['subject'])) { $item->subject = $setarr['subject']; } if (isset($setarr['struct_type'])) { $item->struct_type = $setarr['struct_type']; } if (isset($setarr['content'])) { $item->content = $setarr['content']; } if (isset($setarr['expired_at'])) { $item->expired_at = $setarr['expired_at']; } $result = $item->save(); if ($result) { $resultInfo['new'] = $item; $this->clearTopCache(); } else { $resultInfo['is_ok'] = false; } return $resultInfo; } /** * 删除一个系统消息. * @param string $uid * @return bool|int|mixed|null * @throws mixed|array */ public function deleteOne(string $uid) { $resultInfo = [ 'is_ok' => true, 'old' => null, 'new' => null, ]; $item = SysMessageModel::query()->where(['uid' => $uid])->firstOrFail(); $resultInfo['old'] = clone $item; $result = $item->delete(); if ($result) { $this->clearTopCache(); } else { $resultInfo['is_ok'] = false; } return $resultInfo; } /** * 删除多个系统消息, 但是用户消息集合会保留. * @param mixed $uids * @return array * @throws \Psr\SimpleCache\InvalidArgumentException */ public function deleteMulti($uids) { $result = [ 'total' => 0, 'success_uids' => [], 'fail_uids' => [], ]; $arrIds = $uids; if (is_string($uids)) { $arrIds = [$uids]; } $result['total'] = count($arrIds); if (!empty($arrIds)) { foreach ($arrIds as $uid) { $item = SysMessageModel::query()->where(['uid' => $uid])->first(); if ($item) { if ($item->delete()) { $result['success_uids'][] = $uid; } } else { $result['fail_uids'][] = $uid; } } } $this->clearTopCache(); return $result; } /** * 清除靠前的系统消息缓存. * @return bool * @throws \Psr\SimpleCache\InvalidArgumentException */ public function clearTopCache() { $cacheRepo = make(CacheInterface::class); $cacheRepo->delete(SysMessageConstant::CACHE_KEY_LAST_TOP); return true; } }