SysMessageRepository.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <?php
  2. /**
  3. * 系统消息.
  4. *
  5. * @author jim <jim458734573@gmail.com>
  6. * @date 2020-01-31 10:39:38
  7. */
  8. declare(strict_types=1);
  9. namespace App\Repositories;
  10. use App\Constants\SysMessageConstant;
  11. use App\Model\Mongo\MessageModel;
  12. use App\Model\SysMessageModel;
  13. use Carbon\Carbon;
  14. use KZ2\Repositories\Model\Repository;
  15. use Psr\SimpleCache\CacheInterface;
  16. class SysMessageRepository extends Repository
  17. {
  18. public function model()
  19. {
  20. return SysMessageModel::class;
  21. }
  22. public function getTopLists()
  23. {
  24. $cacheRepo = make(CacheInterface::class);
  25. $cacheSeconds = 3 * 60 * 60;
  26. $arrItems = $cacheRepo->remember(
  27. SysMessageConstant::CACHE_KEY_LAST_TOP,
  28. $cacheSeconds,
  29. function () {
  30. $nowDate = Carbon::now()->subMinutes(15)->toDateTimeString();
  31. $arrItems = [];
  32. $lists = SysMessageModel::query()
  33. ->whereDate('expired_at', '>=', $nowDate)
  34. // 排序是升序,主要方便逐步insert到用户消息集合里.
  35. ->orderBy('created_at', 'ASC')
  36. ->take(SysMessageConstant::LAST_TOP_NUM)->get();
  37. if ($lists->count()) {
  38. $arrItems = $lists->toArray();
  39. }
  40. return $arrItems;
  41. });
  42. return $arrItems;
  43. }
  44. /**
  45. * 针对单个用户初始化他的系统消息.
  46. * @param $userCode
  47. * @return bool
  48. */
  49. public function initForUser($userCode)
  50. {
  51. $nowDate = toMongoIsoDate(Carbon::now());
  52. $arrSys = $this->getTopLists();
  53. if (!empty($arrSys)) {
  54. foreach ($arrSys as $item) {
  55. $filters = [
  56. // 有索引,必须是这个顺序.
  57. 'receive_uid' => $userCode,
  58. 'from_type' => 'sys',
  59. 'sys_msg_uid' => $item['uid'],
  60. ];
  61. $options = [];
  62. $msgObj = make(MessageModel::class)->db()->findOne($filters, $options);
  63. if (empty($msgObj)) {
  64. $sysCreatedAt = Carbon::parse($item['created_at']);
  65. $createdAt = toMongoIsoDate($sysCreatedAt);
  66. // 没有则创建, 系统消息是不能删除的.
  67. $setarr = [
  68. 'subject' => $item['subject'],
  69. 'struct_type' => $item['struct_type'],
  70. 'receive_uid' => $userCode,
  71. 'receive_type' => 'user',
  72. 'from_uid' => '',
  73. 'from_type' => 'sys',
  74. 'sys_msg_uid' => $item['uid'],
  75. 'content' => $item['content'],
  76. 'created_at' => $createdAt,
  77. 'updated_at' => $nowDate,
  78. 'read_at' => null, // null代表未阅读
  79. ];
  80. make(MessageModel::class)->db()->insertOne($setarr);
  81. }
  82. }
  83. }
  84. return true;
  85. }
  86. /**
  87. * 用户的系统消息分页.
  88. * @param string $userCode 用户UID
  89. * @param int $page 当前页
  90. * @param int $pageSize 分页尺码
  91. * @return array
  92. */
  93. public function getSysPagesByUserCode($userCode, $page = 1, $pageSize = 20)
  94. {
  95. $page = format_page($page);
  96. $pageSize = intval($pageSize);
  97. $filters = [
  98. 'receive_uid' => $userCode,
  99. 'from_type' => 'sys',
  100. ];
  101. $optionsBase = [
  102. 'sort' => [
  103. 'created_at' => -1, // 时间降序
  104. ],
  105. ];
  106. $countOptions = $optionsBase;
  107. $pagesOptions = $optionsBase;
  108. $pagesOptions['limit'] = $pageSize;
  109. $result = [
  110. 'total' => 0,
  111. 'data' => [],
  112. 'current_page' => $page,
  113. 'per_page' => $pageSize,
  114. ];
  115. $count = make(MessageModel::class)->db()->countDocuments($filters, $countOptions);
  116. $cursor = make(MessageModel::class)->db()->find($filters, $pagesOptions);
  117. if ($count > 0) {
  118. $result['data'] = $cursor->toArray();
  119. }
  120. $result['total'] = $count;
  121. return $result;
  122. }
  123. /**
  124. * 创建一个系统消息
  125. * @param array $setarr
  126. * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model
  127. */
  128. public function createOne(array $setarr)
  129. {
  130. if (empty($setarr['expired_at'])) {
  131. $exipredAt = Carbon::now()->addMonths(1)->toDateTimeString();
  132. } else {
  133. $exipredAt = $setarr['expired_at'];
  134. }
  135. $item = [
  136. 'subject' => data_get($setarr, 'subject', ''),
  137. 'struct_type' => data_get($setarr, 'struct_type', 'text'),
  138. 'content' => data_get($setarr, 'content', []),
  139. 'expired_at' => $exipredAt,
  140. ];
  141. $obj = SysMessageModel::query()->create($item);
  142. if ($obj) {
  143. $this->clearTopCache();
  144. }
  145. return $obj;
  146. }
  147. /**
  148. * 更新一个系统消息.
  149. * @param string $uid
  150. * @param array $setarr
  151. * @return mixed|array
  152. */
  153. public function updateOne(string $uid, array $setarr)
  154. {
  155. $resultInfo = [
  156. 'is_ok' => true,
  157. 'old' => null,
  158. 'new' => null,
  159. ];
  160. $item = SysMessageModel::query()->where(['uid' => $uid])->firstOrFail();
  161. $resultInfo['old'] = clone $item;
  162. if (isset($setarr['subject'])) {
  163. $item->subject = $setarr['subject'];
  164. }
  165. if (isset($setarr['struct_type'])) {
  166. $item->struct_type = $setarr['struct_type'];
  167. }
  168. if (isset($setarr['content'])) {
  169. $item->content = $setarr['content'];
  170. }
  171. if (isset($setarr['expired_at'])) {
  172. $item->expired_at = $setarr['expired_at'];
  173. }
  174. $result = $item->save();
  175. if ($result) {
  176. $resultInfo['new'] = $item;
  177. $this->clearTopCache();
  178. } else {
  179. $resultInfo['is_ok'] = false;
  180. }
  181. return $resultInfo;
  182. }
  183. /**
  184. * 删除一个系统消息.
  185. * @param string $uid
  186. * @return bool|int|mixed|null
  187. * @throws mixed|array
  188. */
  189. public function deleteOne(string $uid)
  190. {
  191. $resultInfo = [
  192. 'is_ok' => true,
  193. 'old' => null,
  194. 'new' => null,
  195. ];
  196. $item = SysMessageModel::query()->where(['uid' => $uid])->firstOrFail();
  197. $resultInfo['old'] = clone $item;
  198. $result = $item->delete();
  199. if ($result) {
  200. $this->clearTopCache();
  201. } else {
  202. $resultInfo['is_ok'] = false;
  203. }
  204. return $resultInfo;
  205. }
  206. /**
  207. * 删除多个系统消息, 但是用户消息集合会保留.
  208. * @param mixed $uids
  209. * @return array
  210. * @throws \Psr\SimpleCache\InvalidArgumentException
  211. */
  212. public function deleteMulti($uids)
  213. {
  214. $result = [
  215. 'total' => 0,
  216. 'success_uids' => [],
  217. 'fail_uids' => [],
  218. ];
  219. $arrIds = $uids;
  220. if (is_string($uids)) {
  221. $arrIds = [$uids];
  222. }
  223. $result['total'] = count($arrIds);
  224. if (!empty($arrIds)) {
  225. foreach ($arrIds as $uid) {
  226. $item = SysMessageModel::query()->where(['uid' => $uid])->first();
  227. if ($item) {
  228. if ($item->delete()) {
  229. $result['success_uids'][] = $uid;
  230. }
  231. } else {
  232. $result['fail_uids'][] = $uid;
  233. }
  234. }
  235. }
  236. $this->clearTopCache();
  237. return $result;
  238. }
  239. /**
  240. * 清除靠前的系统消息缓存.
  241. * @return bool
  242. * @throws \Psr\SimpleCache\InvalidArgumentException
  243. */
  244. public function clearTopCache()
  245. {
  246. $cacheRepo = make(CacheInterface::class);
  247. $cacheRepo->delete(SysMessageConstant::CACHE_KEY_LAST_TOP);
  248. return true;
  249. }
  250. }