Comment.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace app\api\model;
  13. use app\api\model\Order as OrderModel;
  14. use app\common\model\Comment as CommentModel;
  15. use app\api\model\OrderGoods as OrderGoodsModel;
  16. use app\api\service\User as UserService;
  17. use app\common\library\helper;
  18. use app\common\exception\BaseException;
  19. use app\common\model\CommentPraise;
  20. /**
  21. * 商品评价模型
  22. * Class Comment
  23. * @package app\api\model
  24. */
  25. class Comment extends CommentModel
  26. {
  27. /**
  28. * 隐藏字段
  29. * @var array
  30. */
  31. protected $hidden = [
  32. 'status',
  33. 'sort',
  34. 'order_id',
  35. 'goods_id',
  36. 'order_goods_id',
  37. 'is_delete',
  38. 'update_time'
  39. ];
  40. /**
  41. * 获取指定商品评价列表
  42. * @param int $goodsId 商品ID
  43. * @param int|null $scoreType 评分 (1-5)
  44. * @return \think\Paginator
  45. * @throws \think\db\exception\DbException
  46. */
  47. public function getCommentList(int $goodsId, int $scoreType = null, $sortType = 0)
  48. {
  49. $filter = $this->getFilter($goodsId, $scoreType);
  50. $sort = ['sort' => 'asc', 'content_type' => 'desc', 'praise_num' => 'desc'];
  51. if ($sortType == 1) {
  52. // 时间倒序
  53. $sort = ['sort' => 'asc', 'content_type' => 'desc', 'comment_id' => 'desc'];
  54. }
  55. $user = UserService::getCurrentLoginUser();
  56. return $this->with(['user.avatar', 'orderGoods', 'images.file'])
  57. ->field("*, IF(LENGTH(content)=0,0,1) as content_type")
  58. ->where($filter)
  59. ->order($sort)
  60. ->paginate(15)
  61. ->each(function ($item) use ($user) {
  62. $item->is_praised = false;
  63. if ($user) {
  64. $item->is_praised = CommentPraise::checkPraise($user->user_id, $item->comment_id);
  65. }
  66. $item->create_time_date = !empty($item->create_time) ? date("Y-m-d", strtotime($item->create_time)) : '';
  67. if (!empty($item->images)) {
  68. foreach ($item->images as $v) {
  69. $v->image_url = config('chef.sso_domain_text').$v->file_path;
  70. unset($v->file_path);
  71. }
  72. }
  73. });
  74. }
  75. /**
  76. * 获取指定商品评价列表 (限制数量, 不分页)
  77. * @param int $goodsId 商品ID
  78. * @param int $limit 限制的数量
  79. * @return \think\Collection
  80. * @throws \think\db\exception\DataNotFoundException
  81. * @throws \think\db\exception\DbException
  82. * @throws \think\db\exception\ModelNotFoundException
  83. */
  84. public function listRows(int $goodsId, int $limit = 5)
  85. {
  86. $filter = $this->getFilter($goodsId);
  87. $list = $this->with(['user.avatar', 'images.file'])
  88. ->field("*, IF(LENGTH(content)=0,0,1) as content_type")
  89. ->where($filter)
  90. ->order(['sort' => 'asc', 'content_type' => 'desc', 'comment_id' => 'desc'])
  91. ->limit($limit)
  92. ->select();
  93. $user = UserService::getCurrentLoginUser();
  94. if (!empty($list)) {
  95. foreach ($list as &$item) {
  96. $item['is_praised'] = false;
  97. if ($user) {
  98. $item['is_praised'] = CommentPraise::checkPraise($user->user_id, $item['comment_id']);
  99. }
  100. $item['create_time_date'] = !empty($item['create_time']) ? date("Y-m-d", strtotime($item['create_time'])) : '';
  101. if (!empty($item->images)) {
  102. foreach ($item->images as $v) {
  103. $v->image_url = config('chef.sso_domain_text').$v->file_path;
  104. unset($v->file_path);
  105. }
  106. }
  107. }
  108. }
  109. return $list;
  110. }
  111. /**
  112. * 获取指定商品评价总数量
  113. * @param int $goodsId
  114. * @return int
  115. */
  116. public function rowsTotal(int $goodsId)
  117. {
  118. $filter = $this->getFilter($goodsId);
  119. return $this->where($filter)->count();
  120. }
  121. /**
  122. * 获取查询条件
  123. * @param int $goodsId 商品ID
  124. * @param int|null $scoreType 评分 (1-5)
  125. * @return array[]
  126. */
  127. private function getFilter(int $goodsId, int $scoreType = null)
  128. {
  129. // 筛选条件
  130. $filter = [
  131. ['goods_id', '=', $goodsId],
  132. ['status', '=', 1],
  133. ['is_delete', '=', 0],
  134. ];
  135. // 评分
  136. $scoreType > 0 && $filter[] = ['score', '=', $scoreType];
  137. return $filter;
  138. }
  139. /**
  140. * 获取指定评分总数
  141. * @param int $goodsId
  142. * @return array|null|\think\Model
  143. * @throws \think\db\exception\DataNotFoundException
  144. * @throws \think\db\exception\DbException
  145. * @throws \think\db\exception\ModelNotFoundException
  146. */
  147. public function getTotal(int $goodsId)
  148. {
  149. return $this->field([
  150. 'count(comment_id) AS `all`',
  151. 'count(score = 10 OR NULL) AS `praise`',
  152. 'count(score = 20 OR NULL) AS `review`',
  153. 'count(score = 30 OR NULL) AS `negative`',
  154. ])->where([
  155. 'goods_id' => $goodsId,
  156. 'is_delete' => 0,
  157. 'status' => 1
  158. ])->find();
  159. }
  160. /**
  161. * 验证订单是否允许评价
  162. * @param OrderModel $order
  163. * @return boolean
  164. */
  165. public function checkOrderAllowComment(OrderModel $order)
  166. {
  167. // 验证订单是否已完成
  168. if ($order['order_status'] != 30) {
  169. $this->error = '该订单未完成,无法评价';
  170. return false;
  171. }
  172. // 验证订单是否已评价
  173. if ($order['is_comment'] == 1) {
  174. $this->error = '该订单已完成评价';
  175. return false;
  176. }
  177. return true;
  178. }
  179. /**
  180. * 根据已完成订单商品 添加评价
  181. * @param OrderModel $order
  182. * @param $goodsList
  183. * @param array $data
  184. * @return boolean
  185. * @throws BaseException
  186. */
  187. public function increased(OrderModel $order, $goodsList, array $data)
  188. {
  189. // 生成 formData
  190. $formData = $this->formatFormData($data);
  191. // 生成评价数据
  192. $data = $this->createCommentData($order['order_id'], $goodsList, $formData);
  193. if (empty($data)) {
  194. $this->error = '没有输入评价内容';
  195. return false;
  196. }
  197. return $this->transaction(function () use ($order, $goodsList, $formData, $data) {
  198. // 记录评价内容
  199. $result = $this->addAll($data);
  200. // 记录评价图片`
  201. $this->saveAllImages($result, $formData);
  202. // 更新订单评价状态
  203. $isComment = count($goodsList) === count($data);
  204. $this->updateOrderIsComment($order, $isComment, $result);
  205. return true;
  206. });
  207. }
  208. /**
  209. * 更新订单评价状态
  210. * @param OrderModel $order
  211. * @param $isComment
  212. * @param $commentList
  213. * @return array|false
  214. * @throws \Exception
  215. */
  216. private function updateOrderIsComment(OrderModel $order, $isComment, $commentList)
  217. {
  218. // 更新订单商品
  219. $orderGoodsData = [];
  220. foreach ($commentList as $comment) {
  221. $orderGoodsData[] = [
  222. 'where' => [
  223. 'order_goods_id' => $comment['order_goods_id'],
  224. ],
  225. 'data' => [
  226. 'is_comment' => 1
  227. ]
  228. ];
  229. }
  230. // 更新订单
  231. $isComment && $order->save(['is_comment' => 1]);
  232. return (new OrderGoods)->updateAll($orderGoodsData);
  233. }
  234. /**
  235. * 生成评价数据
  236. * @param int $orderId
  237. * @param $goodsList
  238. * @param array $formData
  239. * @return array
  240. * @throws BaseException
  241. */
  242. private function createCommentData(int $orderId, $goodsList, array $formData)
  243. {
  244. $userInfo = UserService::getCurrentLoginUser(true);
  245. $data = [];
  246. foreach ($goodsList as $goods) {
  247. if($goods['goods_type']==20){
  248. continue;
  249. }
  250. if (!isset($formData[$goods['order_goods_id']])) {
  251. throwError('提交的数据不合法');
  252. }
  253. $commentItem = $formData[$goods['order_goods_id']];
  254. // $commentItem['content'] = trim($commentItem['content']);
  255. $data[$goods['order_goods_id']] = [
  256. 'score' => $commentItem['score'],
  257. 'content' => $commentItem['content'],
  258. 'is_picture' => !empty($commentItem['uploaded']),
  259. 'sort' => 100,
  260. 'status' => 0,
  261. 'user_id' => $userInfo->user_id,
  262. 'order_id' => $orderId,
  263. 'goods_id' => $commentItem['goods_id'],
  264. 'order_goods_id' => $commentItem['order_goods_id'],
  265. 'store_id' => self::$storeId,
  266. 'is_public' => $commentItem['is_public'] ?? 0,
  267. 'nick_name' => $userInfo->nick_name
  268. ];
  269. }
  270. return $data;
  271. }
  272. /**
  273. * 格式化 formData
  274. * @param array $data
  275. * @return array
  276. */
  277. private function formatFormData(array $data)
  278. {
  279. return helper::arrayColumn2Key($data, 'order_goods_id');
  280. }
  281. /**
  282. * 记录评价图片
  283. * @param $commentList
  284. * @param $formData
  285. * @return bool
  286. */
  287. private function saveAllImages($commentList, $formData)
  288. {
  289. // 生成评价图片数据
  290. $imageData = [];
  291. foreach ($commentList as $comment) {
  292. $item = $formData[$comment['order_goods_id']];
  293. foreach ($item['uploaded'] as $imageId) {
  294. $imageData[] = [
  295. 'comment_id' => $comment['comment_id'],
  296. 'image_id' => $imageId,
  297. 'store_id' => self::$storeId
  298. ];
  299. }
  300. }
  301. $model = new CommentImage;
  302. return !empty($imageData) && $model->addAll($imageData) !== false;
  303. }
  304. }