MovieReview.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. namespace App\Models\Movie;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Support\Facades\DB;
  5. use App\Models\DTO\SearchData;
  6. use App\Http\Traits\PagingTrait;
  7. class MovieReview extends Model
  8. {
  9. use PagingTrait;
  10. protected $table = 'tb_movie_review';
  11. protected $primaryKey = 'id';
  12. public $keyType = 'int';
  13. public $incrementing = true;
  14. public $timestamps = true;
  15. const CREATED_AT = 'created_at';
  16. const UPDATED_AT = 'updated_at';
  17. const DELETED_AT = null;
  18. protected $guarded = [];
  19. /**
  20. * 평균 평점 조회
  21. */
  22. public function getAvgRate(string $movieCd): int|float|null
  23. {
  24. $sql = "SELECT ROUND(AVG(`rate`), 1) AS rate FROM tb_movie_review WHERE movie_cd = ?;";
  25. return DB::selectOne($sql, [$movieCd])->rate;
  26. }
  27. /**
  28. * 최근 영화 평점 및 후기 목록
  29. */
  30. public function latest(string $movieCd, int $userID): object
  31. {
  32. $params = new SearchData();
  33. $params->movieCd = $movieCd;
  34. $where = $this->buildWhereQuery($params);
  35. // 개수 조회
  36. $sql = sprintf("
  37. SELECT
  38. COUNT(*) AS total
  39. FROM tb_movie_review MRV
  40. JOIN tb_movie MVI ON MVI.movie_cd = MRV.movie_cd
  41. JOIN users USR ON USR.id = MRV.user_id
  42. WHERE TRUE %s;
  43. ", $where);
  44. $total = DB::selectOne($sql)->total;
  45. $sql = sprintf("
  46. SELECT
  47. MRV.id, MRV.movie_cd, MRV.user_id, MRV.content, MRV.rate, MRV.like, MRV.dislike, MRV.created_at
  48. , USR.id, USR.sid, USR.name, USR.thumb
  49. FROM tb_movie_review MRV
  50. JOIN tb_movie MVI ON MVI.movie_cd = MRV.movie_cd
  51. JOIN users USR ON USR.id = MRV.user_id
  52. WHERE TRUE %s
  53. ORDER BY
  54. FIELD(user_id, ?) DESC, MRV.created_at DESC, MRV.id DESC
  55. LIMIT 4;
  56. ", $where);
  57. $list = DB::select($sql, [$userID]);
  58. return (object)[
  59. 'total' => $total,
  60. 'list' => $list
  61. ];
  62. }
  63. /**
  64. * 영화 평점 및 후기 목록
  65. */
  66. public function list(SearchData $params): object
  67. {
  68. $where = $this->buildWhereQuery($params);
  69. $sql = sprintf("
  70. SELECT
  71. COUNT(*) AS total
  72. FROM tb_movie_review MRV
  73. JOIN tb_movie MVI ON MVI.movie_cd = MRV.movie_cd
  74. LEFT JOIN tb_movie_detail MVD ON MVD.movie_cd = MVI.movie_cd
  75. JOIN users USR ON USR.id = MRV.user_id
  76. WHERE TRUE %s;
  77. ", $where);
  78. $total = DB::selectOne($sql)->total;
  79. $orderBy = $this->sortQuery($params->sort);
  80. $sql = sprintf("
  81. SELECT
  82. MRV.id, MRV.movie_cd, MRV.user_id, MRV.content, MRV.rate, MRV.like, MRV.dislike, MRV.created_at
  83. , USR.sid, USR.name, USR.thumb
  84. , MVI.movie_nm, MVI.movie_nm_en, MVD.thumb_img
  85. FROM tb_movie_review MRV
  86. JOIN tb_movie MVI ON MVI.movie_cd = MRV.movie_cd
  87. LEFT JOIN tb_movie_detail MVD ON MVI.movie_cd = MVD.movie_cd
  88. JOIN users USR ON USR.id = MRV.user_id
  89. WHERE TRUE %s
  90. ORDER BY %s
  91. LIMIT ?, ?;
  92. ", $where, $orderBy);
  93. $list = $this->getPaginator(
  94. DB::select($sql, [$params->offset, $params->perPage]),
  95. $total, $params->perPage, $params->page, $params->path
  96. );
  97. $rows = $list->count();
  98. return (object)[
  99. 'total' => $total,
  100. 'rows' => $rows,
  101. 'list' => $list
  102. ];
  103. }
  104. /**
  105. * where 조건 생성
  106. */
  107. private function buildWhereQuery(SearchData $params): string
  108. {
  109. $where = "";
  110. if($params->movieCd) {
  111. $where .= sprintf(" AND MRV.movie_cd = '%s'", $params->movieCd);
  112. }
  113. return $where;
  114. }
  115. /**
  116. * 평점·후기 정렬 방법
  117. */
  118. private function sortQuery(int $sort): string
  119. {
  120. switch($sort) {
  121. default:case 1: // 공감순
  122. return 'MRV.like DESC, MRV.id DESC';
  123. case 2: // 최신순
  124. return 'MRV.created_at DESC, MRV.id DESC';
  125. case 3: // 평점 높은 순
  126. return 'MRV.rate DESC, MRV.id DESC';
  127. case 4: // 평점 낮은 순
  128. return 'MRV.rate DESC, MRV.id DESC';
  129. }
  130. }
  131. /**
  132. * 영화 평점 이미 등록했는지
  133. */
  134. public function isAlready(string $movieCd, int $userID): bool
  135. {
  136. return $this->where([
  137. ['movie_cd', $movieCd],
  138. ['user_id', $userID]
  139. ])->exists();
  140. }
  141. /**
  142. * 내가 등록한 후기 인가?
  143. */
  144. public function isExists(int $reviewID, int $userID): bool
  145. {
  146. return $this->where([
  147. ['id', $reviewID],
  148. ['user_id', $userID]
  149. ])->exists();
  150. }
  151. /**
  152. * 평점·후기 공감/비공감
  153. */
  154. public function setLike(string $movieCd, int $reviewID, int $userID, int $type): mixed
  155. {
  156. return DB::transaction(function() use($movieCd, $reviewID, $userID, $type) {
  157. $typeStr = MAP_LIKE_TYPE[$type];
  158. $this->where([
  159. ['movie_cd', $movieCd],
  160. ['id', $reviewID],
  161. ['user_id', $userID]
  162. ])->increment($typeStr);
  163. (new MovieLike)->insert([
  164. 'movie_cd' => $movieCd,
  165. 'movie_review_id' => $reviewID,
  166. 'user_id' => $userID,
  167. 'type' => $type,
  168. 'ip_address' => IP_ADDRESS,
  169. 'user_agent' => USER_AGENT,
  170. 'created_at' => now()
  171. ]);
  172. return $this->where([
  173. ['movie_cd', $movieCd],
  174. ['id', $reviewID]
  175. ])->value($typeStr);
  176. });
  177. }
  178. /**
  179. * 평점·후기 신고하기
  180. */
  181. public function setBlame(string $movieCd, int $reviewID, int $userID, int $type, string $reason): mixed
  182. {
  183. return DB::transaction(function() use($movieCd, $reviewID, $userID, $type, $reason) {
  184. $this->where([
  185. ['movie_cd', $movieCd],
  186. ['id', $reviewID],
  187. ['user_id', $userID]
  188. ])->increment('blame');
  189. (new MovieBlame)->insert([
  190. 'movie_cd' => $movieCd,
  191. 'movie_review_id' => $reviewID,
  192. 'user_id' => $userID,
  193. 'type' => $type,
  194. 'reason' => $reason,
  195. 'ip_address' => IP_ADDRESS,
  196. 'user_agent' => USER_AGENT,
  197. 'status' => 0,
  198. 'memo' => null,
  199. 'updated_at' => null,
  200. 'created_at' => now()
  201. ]);
  202. });
  203. }
  204. }