SignServer.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <?php
  2. namespace App\Servers;
  3. use App\Models\MemberCoupon;
  4. use App\Models\MemberSign;
  5. use App\Models\MemberSignRecord;
  6. use App\Models\Sign;
  7. use App\Models\SignSelect;
  8. use App\Servers\Coupon\CouponServer;
  9. use Carbon\Carbon;
  10. use Illuminate\Support\Facades\DB;
  11. /**
  12. * 签到发放
  13. */
  14. class SignServer
  15. {
  16. private $type_arr = [
  17. 1 => '签到发放',
  18. ];
  19. /**
  20. * 发放类型
  21. * @var string[]
  22. */
  23. private $grantType_arr = [
  24. 1 => '仅发放一次',
  25. 2 => '每次触发即发放',
  26. 3 => '自然月循环发放',
  27. ];
  28. /**
  29. * 状态
  30. * @var string[]
  31. */
  32. private $status_arr = [
  33. 1 => '进行中',
  34. 2 => '未开始',
  35. 3 => '已结束',
  36. ];
  37. static private $server = '';
  38. private function __construct()
  39. {
  40. }
  41. /**
  42. * 创建对象
  43. * @return SignServer
  44. */
  45. static function creatServer()
  46. {
  47. if (empty(self::$server)) {
  48. self::$server = new SignServer();
  49. }
  50. return self::$server;
  51. }
  52. /**
  53. * 获取优惠券类型
  54. * @param $type
  55. * @return array|string
  56. */
  57. public function getTypeStr($type)
  58. {
  59. return empty($this->type_arr[$type]) ? '' : $this->type_arr[$type];
  60. }
  61. /**
  62. * 获取优惠券发放类型
  63. * @param $type
  64. * @return array|string
  65. */
  66. public function getGrantTypeStr($type)
  67. {
  68. return empty($this->grantType_arr[$type]) ? '' : $this->grantType_arr[$type];
  69. }
  70. /**
  71. * 获取状态
  72. * @param $status
  73. * @return string
  74. */
  75. public function getStatusArr($status)
  76. {
  77. return empty($this->status_arr[$status]) ? '' : $this->status_arr[$status];
  78. }
  79. /**
  80. * 获取签到发放规则
  81. * @param $info
  82. * @return string
  83. */
  84. public function getRuleStr($info)
  85. {
  86. if($info->{'rule'} == 1){
  87. $info->{'rule_str'} = '累计签到'.$info->{'day'}.'天可领'.$info->{'num'}.'张';
  88. }elseif ($info->{'rule'} == 2){
  89. $info->{'rule_str'} = '连续签到'.$info->{'day'}.'天可领'.$info->{'num'}.'张';
  90. }elseif ($info->{'rule'} == 3){
  91. $info->{'rule_str'} = date('Y.n.d',strtotime($info->{'date_time'})).'可领'.$info->{'num'}.'张';
  92. }elseif ($info->{'rule'} == 4){
  93. $week = ['日','一','二','三','四','五','六'];
  94. $info->{'rule_str'} = '周'.$week[$info->{'week'}].'签到可领'.$info->{'num'}.'张';
  95. }
  96. return $info;
  97. }
  98. function saveInfo($signInfo,$couponList){
  99. DB::beginTransaction();
  100. if (empty($signInfo['id'])) {
  101. $signInfo = Sign::create($signInfo);
  102. if (empty($signInfo->{'id'})) {
  103. DB::rollBack();
  104. return false;
  105. }
  106. } else {
  107. $res = Sign::where('id', $signInfo['id'])->first()->update($signInfo);
  108. if (empty($res)) {
  109. DB::rollBack();
  110. return false;
  111. }
  112. }
  113. //记录优惠券信息
  114. foreach ($couponList as $coupon) {
  115. $couponData = [
  116. 'sign_id' => $signInfo['id'],
  117. 'coupon_id' => $coupon['id'],
  118. 'num' => 1,
  119. ];
  120. $selectInfo = SignSelect::where('sign_id', $couponData['sign_id'])->where('coupon_id', $coupon['id'])->first();
  121. if (empty($selectInfo)) {
  122. $couponData['receive_num'] = 0;
  123. $couponData['use_num'] = 0;
  124. SignSelect::create($couponData);
  125. } else {
  126. $selectInfo->update($couponData);
  127. }
  128. }
  129. DB::commit();
  130. return true;
  131. }
  132. /**
  133. * 获取签到活动详情
  134. * @param $id
  135. * @return mixed
  136. */
  137. function getInfo($id)
  138. {
  139. //查询数据条件
  140. $where = [['id', $id], ['is_del', 0]];
  141. $info = Sign::where($where)
  142. ->select(['id', 'name', 'type', 'start_time', 'end_time', 'rule', 'status', 'day', 'num', 'date_time', 'week', 'grant_type'])
  143. ->first();
  144. $info['type_str'] = $this->getTypeStr($info->{'type'});
  145. $info['grant_type_str'] = $this->getGrantTypeStr($info->{'grant_type'});
  146. $info = $this->getRuleStr($info);
  147. return $info;
  148. }
  149. /**
  150. * 获取领取、使用数量
  151. * @param $sign_id
  152. * @return mixed
  153. */
  154. function NumStatistics($sign_id)
  155. {
  156. $where = [['sign_id', '=', $sign_id]];
  157. $list = SignSelect::where($where)->select('receive_num', 'use_num', 'coupon_id')->get();
  158. $data = [
  159. 'receive_num' => 0,
  160. 'use_num' => 0,
  161. ];
  162. $data['coupon_ids'] = [];
  163. foreach ($list as $value) {
  164. $data['receive_num'] += $value['receive_num'];
  165. $data['use_num'] += $value['use_num'];
  166. $data['coupon_ids'][] = $value['coupon_id'];
  167. }
  168. return $data;
  169. }
  170. /**
  171. * 处理签到
  172. * @param $m_id
  173. * @param array $signInfo
  174. * @return array
  175. */
  176. function MemberSign($m_id,$signInfo=[]){
  177. $time = date('Y-m-d');
  178. $start_month = Carbon::now()->startOfMonth()->timestamp;
  179. DB::beginTransaction();
  180. if($signInfo){
  181. $last_time = date('Y-m-d',strtotime($signInfo['last_time']));
  182. //获取前一天日期;比对是否是连续签到
  183. $yesterday = date('Y-m-d',strtotime("-1 day"));
  184. if($last_time == $yesterday){
  185. $series_count = $signInfo['series_count'] + 1;
  186. }else{
  187. $series_count = 1;
  188. }
  189. if($time == date('Y-m-d',$start_month)){//破月重置累计.连续签到
  190. $series_count = 1;
  191. $sign_count = 1;
  192. }else{
  193. //累计签到天数加1
  194. $sign_count = $signInfo['sign_count'] + 1;
  195. }
  196. $info = [
  197. 'm_id' => $m_id,
  198. 'last_time' => $time,
  199. 'sign_count' => $sign_count,
  200. 'series_count' => $series_count,
  201. ];
  202. //更新数据
  203. $res = $signInfo::where('m_id',$m_id)->update($info);
  204. }else{
  205. $sign_count = 1;
  206. $series_count = 1;
  207. $info = [
  208. 'm_id' => $m_id,
  209. 'last_time' => $time,
  210. 'sign_count' => $sign_count,
  211. 'series_count' => $series_count,
  212. ];
  213. $res = MemberSign::create($info);
  214. }
  215. if($res){
  216. //存入详细记录
  217. $record = MemberSignRecord::create([
  218. 'm_id' => $m_id,
  219. 'sign_time' => $time,
  220. ]);
  221. $coupon = [];
  222. //获取可领取优惠卷
  223. $date = date('Y-m-d');
  224. $week = date('w') == 0 ? 7 : date('w');
  225. //获取今日可领优惠卷
  226. $list = $this->getCouponList($m_id,$sign_count,$series_count,$date,$week);
  227. if($list){
  228. //领取优惠卷
  229. foreach ($list as $value){
  230. CouponServer::creatServer()->handleReceive($m_id,$value);
  231. }
  232. $count = count($list);
  233. $coupon['num'] = $count;
  234. $coupon['full_type'] = $list[0]['full_type'];
  235. $coupon['full_money'] = $list[0]['full_money'];
  236. $coupon['money'] = $list[0]['money'];
  237. }
  238. $info['is_sign'] = 1;
  239. $data['info'] = $info;
  240. $data['coupon'] = $coupon;
  241. if($record){
  242. DB::commit();
  243. return ['code'=>1,'data'=>$data];
  244. }else{
  245. DB::rollBack();
  246. return ['code'=>0,'data'=>[]];
  247. }
  248. }else{
  249. DB::rollBack();
  250. return ['code'=>0,'data'=>[]];
  251. }
  252. }
  253. /**
  254. * 获取可领取的优惠卷
  255. * @param $m_id
  256. * @param $sign_count
  257. * @param $series_count
  258. * @param $date
  259. * @param $week
  260. * @return array
  261. */
  262. function getCouponList($m_id,$sign_count,$series_count,$date,$week){
  263. $time = date('Y-m-d H:i:s');
  264. //获取开启活动的优惠卷
  265. $list = Sign::from('signs as g')
  266. ->leftJoin('sign_selects as s', 'g.id', '=', 's.sign_id')
  267. ->leftJoin('coupons as c', 'c.id', '=', 's.coupon_id')
  268. ->where('g.on_off',1)
  269. ->where('g.status',1)
  270. ->where('g.end_time','>=',$time)
  271. ->where('c.status','<>',3)
  272. ->orderBy('c.money','desc')
  273. ->select(['s.id', 's.num', 's.sign_id', 'c.name', 'c.type', 'c.desc', 'c.money', 'c.full_money', 'c.time_type',
  274. 'c.start_time', 'c.end_time', 'c.valid_day', 'c.wait_day', 'c.is_share', 'c.no_range', 'c.full_type',
  275. 'c.range_rule', 's.coupon_id', 'g.grant_type', 'g.rule', 'g.day', 'g.date_time', 'g.week'])
  276. ->get();
  277. $data = [];
  278. foreach ($list as $value){
  279. $res = false;
  280. if($value['rule'] == 3 && $date == date('Y-m-d',strtotime($value['date_time']))){//指定日期发放
  281. $res = $this->checkCanCoupon($m_id,$value);
  282. }elseif ($value['rule'] == 4 && $week == $value['week']){//指定周几发放
  283. $res = $this->checkCanCoupon($m_id,$value);
  284. }elseif ($value['rule'] == 2 && $series_count == $value['day']){//连续签到
  285. $res = $this->checkCanCoupon($m_id,$value);
  286. }elseif ($value['rule'] == 1 && $sign_count == $value['day']){//累计签到
  287. $res = $this->checkCanCoupon($m_id,$value);
  288. }
  289. if($res){
  290. $data[] = $value;
  291. }
  292. }
  293. return $data;
  294. }
  295. /**
  296. * 检查可领取的优惠卷是否符合发放标准
  297. * @param $m_id
  298. * @param $value
  299. * @return bool
  300. */
  301. function checkCanCoupon($m_id,$value){
  302. if($value['grant_type'] == 1){//仅触发一次就检查该用户领取过没有
  303. $where = [['m_id',$m_id], ['coupon_id',$value['coupon_id']], ['select_id',$value['id']], ['sign_id',$value['sign_id']]];
  304. $find = MemberCoupon::where($where)->select(['id'])->first();
  305. if(!$find){//没有领取过就可领
  306. return true;
  307. }
  308. }elseif ($value['grant_type'] == 2){//每次触发就领取
  309. return true;
  310. }elseif ($value['grant_type'] == 3){//每月触发一次
  311. //获取每月开头时间和结束时间
  312. $start = Carbon::now()->startOfMonth();
  313. $end = Carbon::now()->endOfMonth();
  314. $where = [['m_id',$m_id], ['coupon_id',$value['coupon_id']], ['select_id',$value['id']], ['sign_id',$value['sign_id']]];
  315. $find = MemberCoupon::where($where)->where('created_at','>=',$start)->where('created_at','<=',$end)->select(['id'])->first();
  316. if(!$find){//没有领取过就可领
  317. return true;
  318. }
  319. }
  320. return false;
  321. }
  322. }