Coupon.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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\service\User as UserService;
  14. use app\common\exception\BaseException;
  15. use app\common\library\helper;
  16. use app\common\model\Coupon as CouponModel;
  17. use app\common\model\GoodsCategoryRel;
  18. use think\Db;
  19. /**
  20. * 优惠券模型
  21. * Class Coupon
  22. * @package app\api\model
  23. */
  24. class Coupon extends CouponModel
  25. {
  26. /**
  27. * 隐藏字段
  28. * @var array
  29. */
  30. protected $hidden = [
  31. 'receive_num',
  32. 'is_delete',
  33. 'create_time',
  34. 'update_time',
  35. ];
  36. /**
  37. * 获取优惠券列表
  38. * @param int|null $limit 获取的数量
  39. * @param bool $onlyReceive 只显示可领取
  40. * @param int $is_limit_hour
  41. * @return \think\Collection
  42. * @throws BaseException
  43. * @throws \think\db\exception\DataNotFoundException
  44. * @throws \think\db\exception\DbException
  45. * @throws \think\db\exception\ModelNotFoundException
  46. */
  47. public function getLimitList(int $limit = null, bool $onlyReceive = false,int $is_limit_hour = 0)
  48. {
  49. // 查询构造器
  50. $query = $this->getNewQuery();
  51. // 只显示可领取(未过期,未发完)的优惠券
  52. if ($onlyReceive) {
  53. $query->where('IF ( `limit_total_type` = 10,`receive_num` <= `total_num`, `total_num`=0 )');
  54. }
  55. //限时券有公开券和领券中心类的券
  56. $query->where('public_lev','<',2);
  57. // 查询数量
  58. $limit > 0 && $query->limit($limit);
  59. // 优惠券列表
  60. $now = Date("Y-m-d H:i:s",time());
  61. $couponList = $query->where('receive_type','=',10)
  62. ->where('send_type','=',10)
  63. ->where('is_delete', '=', 0)
  64. ->where('audit_status','=',10)
  65. ->where('status','=',1)
  66. ->whereIn('is_show_position',[1,2])
  67. ->where('start_time','<',$now)
  68. ->where("end_time",">",$now)
  69. ->where('is_limit_hour','=',$is_limit_hour)
  70. ->where('activity_type','=',0)
  71. ->order(['start_hour'=>'asc','coupon_type'=>'asc','reduce_price'=>'desc', 'discount'=>'asc'])//'coupon_type'=>'asc','reduce_price'=>'desc', 'discount'=>'asc',
  72. ->select();
  73. // 获取用户已领取的优惠券
  74. return $this->setIsReceive($couponList);
  75. }
  76. /**
  77. * 获取优惠券列表
  78. * @param int|null $limit 获取的数量
  79. * @param bool $onlyReceive 只显示可领取
  80. * @param int $is_limit_hour
  81. * @param null $couponType
  82. * @param int $public_lev
  83. * @return \think\Collection
  84. * @throws BaseException
  85. * @throws \think\db\exception\DataNotFoundException
  86. * @throws \think\db\exception\DbException
  87. * @throws \think\db\exception\ModelNotFoundException
  88. */
  89. public function getList(int $limit = null, bool $onlyReceive = false,int $is_limit_hour = 0,$couponType = null,$public_lev=0,$source_id=0)
  90. {
  91. // 查询构造器
  92. $query = $this->getNewQuery();
  93. // 只显示可领取(未过期,未发完)的优惠券
  94. if ($onlyReceive) {
  95. $query->where('IF ( `limit_total_type` = 10,`receive_num` <= `total_num`, `total_num`=0 )');
  96. }
  97. //v1.4.0- 补充1.4.1添加开会员定向发放,不显示到领券中心
  98. if ($couponType){
  99. $query->where('coupon_type',$couponType);
  100. }else{
  101. $query->where('coupon_type','<',self::MEMBER_COUPON);
  102. }
  103. //1.4.41版本加入券是否公开类型
  104. if ($public_lev == 1 || $public_lev == 2){
  105. $query->whereIn('public_lev',[0,$public_lev]);
  106. }else{
  107. $query->where('public_lev',$public_lev);
  108. }
  109. if($source_id==1){
  110. $query->whereIn('is_show_position',[1,3]);
  111. }
  112. if($source_id==0){
  113. $query->whereIn('is_show_position',[1,2]);
  114. }
  115. // 查询数量
  116. $limit > 0 && $query->limit($limit);
  117. // 优惠券列表
  118. $now = Date("Y-m-d H:i:s",time());
  119. $couponList = $query->where('receive_type','=',10)
  120. ->where('send_type','=',10)
  121. ->where('is_delete', '=', 0)
  122. ->where('audit_status','=',10)
  123. ->where('status','=',1)
  124. ->where(function ($query) use ($now){//去除已失效的券
  125. $query->where('expire_type',10)->whereOr(function ($q) use ($now){
  126. $q->where([['expire_type','=',20],['expire_time','>',$now]]);
  127. });
  128. })
  129. ->where('start_time','<',$now)
  130. ->where("end_time",">",$now)
  131. ->where('is_limit_hour','=',$is_limit_hour)
  132. ->where('activity_type','=',0)
  133. ->field('* , IF(
  134. expire_type = 20,
  135. yoshop_coupon.expire_time,
  136. DATE_ADD( now(), INTERVAL yoshop_coupon.expire_day DAY )
  137. ) as tmp_expire_time ')
  138. ->order(['coupon_type'=>'asc','reduce_price'=>'desc','discount'=>'asc','tmp_expire_time' =>'asc', 'end_time'=>'asc'])
  139. ->select();
  140. // 获取用户已领取的优惠券
  141. return $this->setIsReceive($couponList);
  142. }
  143. /**
  144. * 获取优惠券落地页数据
  145. *
  146. * @param $couponId
  147. * @return mixed
  148. */
  149. public static function getDetail($couponId)
  150. {
  151. $now = Date("Y-m-d H:i:s",time());
  152. $data = self::where('coupon_id', $couponId)
  153. ->where('is_show_position','<>',4)
  154. // ->where('receive_type','=',10)
  155. // ->where('send_type','=',10)
  156. // ->where('is_delete', '=', 0)
  157. // ->where('audit_status','=',10)
  158. // ->where('status','=',1)
  159. // ->where(function ($query) use ($now){//去除已失效的券
  160. // $query->where('expire_type',10)->whereOr(function ($q) use ($now){
  161. // $q->where([['expire_type','=',20],['expire_time','>',$now]]);
  162. // });
  163. // })
  164. // ->where('start_time','<',$now)
  165. // ->where("end_time",">",$now)
  166. // ->where('activity_type','=',0)
  167. ->field('* ,IF(
  168. expire_type = 20,
  169. yoshop_coupon.expire_time,
  170. DATE_ADD( now(), INTERVAL yoshop_coupon.expire_day DAY )
  171. ) as tmp_expire_time ')
  172. ->find();
  173. if (empty($data)) {
  174. return [];
  175. }
  176. // 获取用户已领取的优惠券
  177. $userInfo = UserService::getCurrentLoginUser();
  178. $data['user_coupon_id'] = 0;
  179. $data['is_receive'] = false;
  180. if ($userInfo !== false) {
  181. $UserCouponModel = new UserCoupon;
  182. $userCouponIds = $UserCouponModel->getUserCouponIds($userInfo['user_id']);
  183. $userTodayCouponIds = $UserCouponModel->getTodayUserCouponIds($userInfo['user_id']);
  184. $data['user_coupon_id'] = 0;
  185. //如果是会员生日礼券,需要找到这张券
  186. if ($data['coupon_type'] == self::MEMBER_BIRTH_COUPON){
  187. $uc = $UserCouponModel->getUserCouponId($userInfo['user_id'],$data['coupon_id']);
  188. $data['user_coupon_id'] = $uc['user_coupon_id']??0;
  189. $data['is_receive'] = boolval($uc);
  190. }else{
  191. if($data['limit_receive_type']==10){
  192. $data['is_receive'] = in_array($data['coupon_id'], $userCouponIds);
  193. }else{
  194. $data['is_receive'] = in_array($data['coupon_id'], $userTodayCouponIds);
  195. }
  196. }
  197. }
  198. return $data;
  199. }
  200. public function getListTwo(int $limit = null, bool $onlyReceive = false)
  201. {
  202. // 只显示可领取(未过期,未发完)的优惠券
  203. if ($onlyReceive) {
  204. $this->where(function($query){
  205. $query->where([
  206. ['limit_total_type','=',10],
  207. ['receive_num', 'exp', Db::raw('<=total_num')]
  208. ])->whereOr([
  209. ['limit_total_type','=',20],
  210. ['total_num','=',0]
  211. ]);
  212. });
  213. }
  214. // 查询数量
  215. $limit > 0 && $this->limit($limit);
  216. // 优惠券列表
  217. $now = Date("Y-m-d H:i:s",time());
  218. $couponList = $this->where('receive_type','=',10)
  219. ->where('send_type','=',10)
  220. ->where('is_delete', '=', 0)
  221. ->where('audit_status','=',10)
  222. ->where('status','=',1)
  223. ->whereIn('is_show_position',[1,2])
  224. ->where('start_time','<',$now)
  225. ->where("end_time",">",$now)
  226. ->order(['reduce_price'=>'desc', 'create_time' => 'desc'])
  227. ->select();
  228. // 获取用户已领取的优惠券
  229. return $this->setIsReceive($couponList);
  230. }
  231. /**
  232. * 获取用户已领取的优惠券
  233. * @param $couponList
  234. * @return mixed
  235. * @throws BaseException
  236. */
  237. private function setIsReceive($couponList) {
  238. // 获取用户已领取的优惠券
  239. $userInfo = UserService::getCurrentLoginUser();
  240. if ($userInfo !== false) {
  241. $UserCouponModel = new UserCoupon;
  242. $userCouponIds = $UserCouponModel->getUserCouponIds($userInfo['user_id']);
  243. $userTodayCouponIds = $UserCouponModel->getTodayUserCouponIds($userInfo['user_id']);
  244. foreach ($couponList as $key => $item) {
  245. $couponList[$key]['user_coupon_id'] = 0;
  246. //如果是会员生日礼券,需要找到这张券
  247. if ($item['coupon_type'] == self::MEMBER_BIRTH_COUPON){
  248. $uc = $UserCouponModel->getUserCouponId($userInfo['user_id'],$item['coupon_id']);
  249. $couponList[$key]['user_coupon_id'] = $uc['user_coupon_id']??0;
  250. $couponList[$key]['is_receive'] = boolval($uc);
  251. }else{
  252. if($item['limit_receive_type']==10){
  253. $couponList[$key]['is_receive'] = in_array($item['coupon_id'], $userCouponIds);
  254. }else{
  255. $couponList[$key]['is_receive'] = in_array($item['coupon_id'], $userTodayCouponIds);
  256. }
  257. }
  258. }
  259. }
  260. return $couponList;
  261. }
  262. //查找优惠券中哪些是新用户自动领取的
  263. public function checkCouponIdBySendType(array $coupon_id_arr = [],int $send_type =20){
  264. $couponIdArray = $this->where('send_type','=',$send_type)
  265. ->where('coupon_id','in',$coupon_id_arr)
  266. ->column('coupon_id');
  267. return $couponIdArray;
  268. }
  269. // /**
  270. // * 优惠券状态 (是否可领取)
  271. // * @param $value
  272. // * @param $data
  273. // * @return array
  274. // */
  275. public function getStateAttr($value, $data)
  276. {
  277. if (isset($data['limit_total_type'])&&$data['limit_total_type']==10&&isset($data['total_num'])&&$data['total_num'] > -1 && $data['receive_num'] >= $data['total_num']) {
  278. return ['text' => '领完啦', 'value' => -1];
  279. }
  280. if (isset($data['is_receive']) && $data['is_receive']) {
  281. //看下是否存在
  282. $userInfo = UserService::getCurrentLoginUser();
  283. if($userInfo!=false){
  284. $userCouponModel = new UserCoupon;
  285. if($data['limit_receive_type']==10){ //限制总数
  286. $userCouponIds = $userCouponModel->getUserCouponIds($userInfo['user_id']);
  287. }
  288. if($data['limit_receive_type']==20){ //限制每天总数
  289. $userCouponIds = $userCouponModel->getTodayUserCouponIds($userInfo['user_id']);
  290. }
  291. $ac = array_count_values($userCouponIds);
  292. $coupon_id = $data['coupon_id'];
  293. if(isset($ac[$coupon_id])){
  294. if($data['limit_receive_cnt']>$ac[$coupon_id]){
  295. if($data['is_limit_hour']==0){
  296. return ['text' => '正常', 'value' => 1];
  297. }
  298. if($data['is_limit_hour']==1){
  299. $now = Date("Y-m-d H:i:s",time());
  300. $today_start = Date("Y-m-d",time())." ".$data['start_hour'].":00:00";
  301. $today_end = Date("Y-m-d",time())." ".$data['end_hour'].":00:00";
  302. if($now > $today_start&&$now < $today_end){
  303. return ['text'=>'正常','value'=>1];
  304. }
  305. if($today_start>$now){
  306. return ['text'=>'即将开始','value'=>-2];
  307. }
  308. }
  309. }
  310. return ['text' => '已领取', 'value' => 0];
  311. }
  312. }else{
  313. return ['text' => '已领取', 'value' => 0];
  314. }
  315. }
  316. if (!isset($data['is_limit_hour'])){
  317. return ['text' => '领完啦', 'value' => -1];
  318. }
  319. if(isset($data['is_limit_hour']) && $data['is_limit_hour']==0){
  320. return ['text' => '正常', 'value' => 1];
  321. }
  322. if(isset($data['is_limit_hour']) && $data['is_limit_hour'] == 1){
  323. $now = Date("Y-m-d H:i:s",time());
  324. $today_start = Date("Y-m-d",time())." ".$data['start_hour'].":00:00";
  325. $today_end = Date("Y-m-d",time())." ".$data['end_hour'].":00:00";
  326. if($now > $today_start&&$now < $today_end){
  327. return ['text'=>'正常','value'=>1];
  328. }
  329. if($today_start > $now){
  330. return ['text'=>'即将开始','value'=>-2];
  331. }
  332. }
  333. }
  334. /**
  335. * 验证优惠券是否可领取
  336. * @return bool
  337. */
  338. public function checkReceive()
  339. {
  340. //10 限制优惠券总数量 20 不限制总数量
  341. if ($this['limit_total_type']==10&&$this['total_num'] > -1 && $this['receive_num'] >= $this['total_num']) {
  342. $this->error = '优惠券已发完';
  343. return false;
  344. }
  345. return true;
  346. }
  347. /**
  348. * 累计已领取数量 同时减可用数量
  349. * @return mixed
  350. */
  351. public function setIncReceiveNum()
  352. {
  353. $this->setInc($this['coupon_id'], 'receive_num', 1);
  354. if($this['limit_total_type']==10){
  355. $this->setDec($this['coupon_id'], 'avaiable_num', 1);
  356. }
  357. }
  358. public static function showDetail($couponId){
  359. return Coupon::where('coupon_id',$couponId)
  360. ->field('coupon_id,name,reduce_price,min_price,status,audit_status,is_limit_hour,expire_time')->find();
  361. }
  362. //获取开通会员礼包优惠券列表
  363. public function getMemList(){
  364. $filter[] = ['is_delete','=',0];
  365. $filter[] = ['end_time','>',date('Y-m-d H:i:s')];
  366. $filter[] = ['start_time','<',date('Y-m-d H:i:s')];
  367. $filter[] = ['status','=',1];
  368. $filter[] = ['audit_status','=',10];
  369. $filter[] = ['receive_type','=',20];
  370. $filter[] = ['expire_type','=',10];
  371. $filter[] = ['coupon_type','=',Coupon::MEMBER_COUPON];
  372. $list = Coupon::where($filter)->select();
  373. return $list;
  374. }
  375. }