UserDynamic.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.thinkphp.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: thinkphp <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\api\model;
  13. use app\api\validate\user\Dynamic;
  14. use app\common\model\UserDynamic as UserDynamicModel;
  15. use think\facade\Cache;
  16. /**
  17. * 用户动态模型类
  18. * Class UserDynamic
  19. * @package app\api\model
  20. */
  21. class UserDynamic extends UserDynamicModel
  22. {
  23. protected $globalScope = [''];
  24. /**
  25. * 隐藏字段
  26. * @var array
  27. */
  28. protected $hidden = [
  29. 'update_time'
  30. ];
  31. /**
  32. * 获取列表
  33. * @param array $param
  34. * @param int $listRows
  35. * @return mixed
  36. * @throws \think\db\exception\DbException
  37. */
  38. public function getList(array $param = [], int $listRows = 15)
  39. {
  40. // 整理查询参数
  41. $params = array_merge($param, ['status' => 1]);
  42. // 获取商品列表
  43. $list = parent::getList($params, $listRows);
  44. if ($list->isEmpty()) {
  45. return $list;
  46. }
  47. // 隐藏冗余的字段
  48. $list->hidden(array_merge($this->hidden, ['status']));
  49. // 整理列表数据并返回
  50. return $this->setListDataFromApi($list, $param);
  51. }
  52. /**
  53. * 获取列表
  54. * @param array $param
  55. * @param int $listRows
  56. * @return mixed
  57. * @throws \think\db\exception\DbException
  58. */
  59. public function getIndexList(int $userId, array $param = [], int $listRows = 15)
  60. {
  61. // 排序
  62. $sort = "views desc,like_num desc,collect_num desc";
  63. if($this->getNewCount($userId)){
  64. $sort = "create_time desc,views desc, id desc";
  65. }
  66. // 获取商品列表
  67. $list = parent::alias($this->name)
  68. ->leftJoin('user u','u.user_id='.$this->name.'.user_id')
  69. ->leftJoin('user_info ui','ui.user_id='.$this->name.'.user_id')
  70. ->where([$this->name.'.status'=> 1])
  71. ->where(function($query) use($userId){
  72. // 访问权限
  73. if($userId>0){
  74. // 获取粉丝用户ID,并验证
  75. $query->where(function($query) use($userId){
  76. // 粉丝只能看公开或好友可看
  77. $query->whereIn($this->name.'.user_id', \app\api\model\UserFans::getFansUid($userId))
  78. ->whereIn($this->name.'.look_type',[1,2]);
  79. })->whereOr(function($query) use ($userId){
  80. // 用户自己所有
  81. $query->where([$this->name.'.user_id'=> $userId]);
  82. })->whereOr(function($query){
  83. // 公开对所有
  84. $query->where([$this->name.'.look_type'=> 1]);
  85. });
  86. }
  87. })
  88. ->where(function($query) use($param){
  89. if(!empty($param['keyword'])){
  90. $query->where(function($query) use($param){
  91. $query->where($this->name.'.content','like',"%{$param['keyword']}%")
  92. ->whereOr('u.nick_name','like', "%{$param['keyword']}%");
  93. });
  94. }
  95. if(!empty($param['school_id'])){
  96. $query->where('ui.school_id','=', intval($param['school_id']));
  97. }
  98. })
  99. ->field($this->name.'.*,u.user_type,u.avatar_id,u.nick_name,u.user_type,ui.school_id,ui.admission_year')
  100. ->order($sort)
  101. ->paginate($listRows);
  102. if ($list->isEmpty()) {
  103. return $list;
  104. }
  105. // 隐藏冗余的字段
  106. $list->hidden(array_merge($this->hidden, ['status']));
  107. // 整理列表数据并返回
  108. $param['access_user_id'] = $userId;
  109. return $this->setListDataFromApi($list, $param);
  110. }
  111. /**
  112. * 验证是否最新发布有动态,以便于优先推送
  113. * @param $userId
  114. * @return int|mixed
  115. */
  116. private function getNewCount($userId)
  117. {
  118. if($userId<=0){
  119. return false;
  120. }
  121. $cacheKey = "caches:dynamic:news:{$userId}";
  122. if($data = Cache::get($cacheKey)){
  123. return $data;
  124. }
  125. $data = $this->where(['user_id'=> $userId,'status'=> 1])
  126. ->where('create_time','>=', time() - 60)
  127. ->order('create_time desc, id desc')
  128. ->count('id');
  129. if($data){
  130. Cache::set($cacheKey, ['user_id'=> $userId,'count'=> $data], rand(30, 60));
  131. }
  132. return $data;
  133. }
  134. /**
  135. * 设置展示的数据 api模块
  136. * @param $info
  137. * @return mixed
  138. */
  139. private function setListDataFromApi($info, $params = [])
  140. {
  141. return $this->setListData($info, function ($data) use($params){
  142. // 访问用户粉丝状态
  143. $userId = isset($params['access_user_id'])? $params['access_user_id'] : 0;
  144. if($userId>0){
  145. $data['fans_status'] = UserFans::checkFans($data['user_id'], $userId);
  146. }
  147. // 整理数据 api模块
  148. $this->setDataFromApi($data);
  149. $this->hidden(['update_time','avatar_id']);
  150. });
  151. }
  152. /**
  153. * 整理数据 api模块
  154. * @param $info
  155. * @return mixed
  156. */
  157. private function setDataFromApi($info)
  158. {
  159. return $this->setData($info, function ($data) {
  160. // logo封面
  161. $data['image'] = $data['image']? getPreview($data['image']) : '';
  162. $data['file_url'] = $data['file_url']? getPreview($data['file_url']) : '';
  163. $data['create_time_text'] = $data['create_time']? getTimeText(strtotime($data['create_time'])) : '';
  164. if(isset($data['avatar_id'])){
  165. $uploadData = $data['avatar_id']? UploadFile::detail($data['avatar_id']) : [];
  166. $data['avatar_url'] = isset($uploadData['preview_url'])? $uploadData['preview_url'] : '';
  167. }
  168. // 学校名称
  169. if(isset($data['user_type'])){
  170. $userType = intval($data['user_type']);
  171. $admissionYear = isset($data['admission_year'])? $data['admission_year'] : '';
  172. $position = isset($data['position'])? $data['position'] : '';
  173. $data['school_name'] = '';
  174. $data['user_type_text'] = $userType==3? ($position==1? '科任老师' :'招生老师') : ($admissionYear? $admissionYear.'级' :'学生');
  175. if($userType == 3){
  176. $data['school_name'] = $data['school_id']? School::getSchoolField($data['school_id']) : '';
  177. }else{
  178. $data['school_name'] = $data['school_id']? SourceShool::getSchoolField($data['school_id']) : '';
  179. }
  180. }
  181. // 点赞喜欢数
  182. if(!is_null($data['like_num'])){
  183. $data['like_num'] = $data['like_num']? ($data['like_num']<10000? "{$data['like_num']}" : round($data['like_num']/10000,1).'w') :'';
  184. }
  185. // 收藏数
  186. if(!is_null($data['collect_num'])){
  187. $data['collect_num'] = $data['collect_num']? ($data['collect_num']<10000? "{$data['collect_num']}" : round($data['collect_num']/10000,1).'w') :'';
  188. }
  189. // 浏览数
  190. if(!is_null($data['views'])){
  191. $data['views'] = $data['views']? ($data['views']<10000? "{$data['views']}" : round($data['views']/10000,1).'w') :'';
  192. }
  193. });
  194. }
  195. /**
  196. * 获取详情信息
  197. * @param $where
  198. * @param array $with
  199. * @return static|array|false|null
  200. */
  201. public static function detail($where, array $with = [])
  202. {
  203. $filter = [];
  204. if (is_array($where)) {
  205. $filter = array_merge($filter, $where);
  206. } else {
  207. $filter['id'] = (int)$where;
  208. }
  209. return static::get($filter, $with);
  210. }
  211. /**
  212. * 获取学校动态列表
  213. * @param int $schoolId
  214. * @param array $param
  215. * @param int $listRows
  216. * @return mixed
  217. */
  218. public function getListBySchool(int $schoolId,int $userId = 0, array $param = [], int $listRows = 15)
  219. {
  220. // 整理查询参数
  221. $params = array_merge($param, [$this->name.'.status' => 1, 'ui.school_id'=> $schoolId]);
  222. // 获取商品列表
  223. $list = parent::getListBySchool($schoolId, $userId, $params, $listRows);
  224. if ($list->isEmpty()) {
  225. return $list;
  226. }
  227. // 隐藏冗余的字段
  228. $list->hidden(array_merge($this->hidden, ['status']));
  229. // 整理列表数据并返回
  230. return $this->setListDataFromApi($list);
  231. }
  232. /**
  233. * 发布动态
  234. * @param $params
  235. * @return bool
  236. * @throws \cores\exception\BaseException
  237. */
  238. public function publish($params)
  239. {
  240. // 表单参数验证
  241. $validate = new Dynamic();
  242. if(!$validate->check($params)){
  243. throwError($validate->getError());
  244. }
  245. $userInfo = \app\api\service\User::getCurrentLoginUser(true);
  246. if($userInfo['status'] != 1){
  247. $this->error = '用户已冻结';
  248. return false;
  249. }
  250. $data = [
  251. 'user_id'=> $userInfo['user_id'],
  252. 'name'=> isset($params['name'])? $params['name'] : '用户动态',
  253. 'content'=> isset($params['content'])? $params['content'] : '',
  254. 'image'=> isset($params['image'])? $params['image'] : '',
  255. 'type'=> isset($params['type'])? $params['type'] : 1,
  256. 'file_url'=> isset($params['file_url'])? $params['file_url'] : '',
  257. 'look_type'=> isset($params['look_type'])? intval($params['look_type']) : 1,
  258. 'latitude'=> isset($params['latitude'])? $params['latitude'] : 0,
  259. 'longitude'=> isset($params['longitude'])? $params['longitude'] : 0,
  260. 'address'=> isset($params['address'])? $params['address'] : '',
  261. 'create_time'=> time(),
  262. 'update_time'=> time(),
  263. 'status'=> 1,
  264. ];
  265. return $this->save($data);
  266. }
  267. /**
  268. * 获取详情信息
  269. * @param $where
  270. * @param array $with
  271. * @return static|array|false|null
  272. */
  273. public static function getDetail($id, array $with = [])
  274. {
  275. $data = static::alias('a')
  276. ->leftJoin('user u','u.user_id=a.user_id')
  277. ->leftJoin('user_info ui','ui.user_id=a.user_id')
  278. ->where(['a.status'=> 1,'a.id'=> $id])
  279. ->field('a.*,u.user_type,u.avatar_id,u.nick_name,u.user_type,ui.school_id,ui.admission_year,ui.position')
  280. ->find();
  281. if(empty($data)){
  282. throwError('动态信息不存在或已删除');
  283. }
  284. // 权限验证
  285. $userInfo = \app\api\service\User::getCurrentLoginUser(true);
  286. if($data['look_type']==3 && $userInfo['user_id'] != $data['user_id']){
  287. throwError('该作品已被设置为仅作者可看');
  288. }
  289. // 好友作品,我是对方粉丝时可看
  290. if($data['look_type']==2 && UserFans::checkFans($data['user_id'], $userInfo['user_id'])){
  291. throwError('该作品已被设置为仅好友可看');
  292. }
  293. // 粉丝状态
  294. $data['fans_status'] = UserFans::checkFans($data['user_id'], $userInfo['user_id']);
  295. // 访问量
  296. $cacheKey = "caches:dynamic:views:{$userInfo['user_id']}_{$data['id']}";
  297. if(!Cache::get($cacheKey)){
  298. self::setIncViews($id);
  299. // 半年内同用户只记一次
  300. Cache::set($cacheKey, ['id'=> $id, 'user_id'=> $userInfo['user_id'],'date'=>date('Y-m-d H:i:s')], rand(3*30*24*3600,6*30*24*3600));
  301. }
  302. return (new static())->setDataFromApi($data);
  303. }
  304. /**
  305. * 访问量
  306. * @param $id
  307. */
  308. public static function setIncViews($id){
  309. (new static())->setInc(['id'=> $id], 'views', 1);
  310. }
  311. /**
  312. * 统计综合数量
  313. * @param $userId
  314. * @return array
  315. */
  316. public static function getCountsByUser($userId)
  317. {
  318. return [
  319. 'public'=> (int)static::where(['user_id'=> $userId, 'status'=> 1])->whereIn('look_type',[1,2])->count('id'),
  320. 'private'=> (int)static::where(['user_id'=> $userId, 'status'=> 1,'look_type'=> 3])->count('id'),
  321. 'collect'=> (int)UserDynamicCollect::getCountsByType($userId, 1),
  322. 'liked'=> (int)UserDynamicCollect::getCountsByType($userId, 2),
  323. ];
  324. }
  325. }