MyScene.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. namespace app\main\service;
  3. use app\common\library\Redis;
  4. use app\common\service\CampaignService;
  5. use app\main\constants\CampaignConstants;
  6. use app\main\InternalInterface\Multiton;
  7. use think\Exception;
  8. use think\Log;
  9. /**
  10. * 我的场次
  11. * Created by: PhpStorm
  12. * User: lytian
  13. * Date: 2019/10/31
  14. * Time: 14:31
  15. */
  16. class MyScene extends Multiton
  17. {
  18. private $flushState = 0;
  19. protected $attributes = [];
  20. /**
  21. * MyScene constructor.
  22. * @param $user_id 用户ID
  23. * @param $id 场次ID
  24. */
  25. public function __construct($user_id, $id = null, $is_force = false)
  26. {
  27. $this->user_id = $user_id;
  28. $this->match_id = $id;
  29. $this->init($is_force);
  30. $this->checkStatus();
  31. }
  32. /**
  33. * 初始化数据
  34. * @throws Exception
  35. */
  36. private function init($is_force = false)
  37. {
  38. $redisKey = CampaignConstants::getUserMatchKey($this->user_id);
  39. if (!$is_force) {
  40. $data = Redis::instance()->hGetAll($redisKey);
  41. if (!!!$data) $is_force = true;
  42. }
  43. if ($is_force) {
  44. //@todo 需要处理 先给默认值了
  45. $maps = [
  46. 'user_id' => $this->user_id,
  47. ];
  48. if (!is_null($this->match_id)) {
  49. $maps['match_id'] = ['eq', $this->match_id];
  50. }
  51. $dbRow = model("CampaignUserMatch")->setConnect($this->user_id)
  52. ->where($maps)
  53. ->order("id desc")
  54. ->find();
  55. if (!$dbRow) {
  56. throw new Exception("您还没报名", 20001);
  57. }
  58. $data = $dbRow->toArray();
  59. Redis::instance()->hMSet($redisKey, $data);
  60. Redis::instance()->expire($redisKey, 86400);
  61. }
  62. //更新字段进入
  63. foreach ($data as $k=>$v) {
  64. $this->$k = $v;
  65. }
  66. }
  67. /**
  68. * 打卡
  69. */
  70. public function sign()
  71. {
  72. $this->getSignState();
  73. if ($this->today_sign_status == 0) {
  74. //进行打卡
  75. $campKey = CampaignConstants::getUserMatchReadKey($this->user_id);
  76. $campVal = Redis::instance()->get($campKey);
  77. $readNumber = Redis::instance()->hGet(CampaignConstants::getCampaignRedisKey($this->active_id),'read_number');
  78. //$todo 打卡条件后续验证 看完指定章节数才可以哦 不满足返回201
  79. if ($campVal === false || $campVal < $readNumber) {
  80. return ['code' => 201, 'msg' => '您还没完成前置条件'];
  81. }
  82. try {
  83. $update['num'] = ['exp', 'num+1'];
  84. $this->num++;
  85. if ($this->num == $this->period) {
  86. $update['status'] = 3;
  87. $this->status = 3;
  88. }
  89. $todaySignNum = 0;
  90. //更新我的打卡状态 场次信息
  91. if (model("CampaignUserMatch")->setConnect($this->user_id)->update($update, ['id' => $this->id])) {
  92. $matchUpdate = [
  93. 'puncher_num' => ['exp', "puncher_num + 1"]
  94. ];
  95. if ($this->status == 3) {
  96. //完成 更新成功人数
  97. $matchUpdate['success_num'] = ['exp', "success_num + 1"];
  98. }
  99. if (model("CampaignMatch")->update($matchUpdate, ['id' => $this->match_id])) {
  100. //每日签到数据
  101. $dayCollectRow = model("MatchDayCollect")->where('match_id', 'eq', $this->match_id)->where('createdate', 'eq', date("Ymd"))->find();
  102. if ($dayCollectRow) {
  103. model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd")]);
  104. } else {
  105. model("MatchDayCollect")->insert(['match_id' => $this->match_id, 'createdate' => date("Ymd"), 'uv' => 0, 'num' => 1, 'updatetime' => time(), 'createtime' => time()]);
  106. }
  107. //更新打卡人数
  108. $todaySignNum = CampaignService::instance()->setSignNumToday($this->match_id);
  109. } else {
  110. throw new Exception('打卡失败', 208);
  111. }
  112. $result = ['code' => 200, 'msg' => '本次打卡成功', 'today_sign_num' => $todaySignNum];
  113. $this->flushState = 1;
  114. } else {
  115. throw new Exception('打卡失败', 207);
  116. }
  117. } catch (Exception $e) {
  118. Log::error('打卡失败:--msg:'.$e->getMessage()."--code:".$e->getCode() . '--line:'.$e->getLine());
  119. $result = ['code' => 202, 'msg' => '打卡失败'];
  120. }
  121. } else {
  122. if ($this->today_sign_status == 1) {
  123. $result = ['code' => 203, 'msg' => '今日已打卡'];
  124. } else if ($this->today_sign_status == 2) {
  125. $result = ['code' => 204, 'msg' => '需补卡'];
  126. } else if ($this->today_sign_status == -1) {
  127. $result = ['code' => 205, 'msg' => '报名成功,明日可打卡'];
  128. } else {
  129. $result = ['code' => 206, 'msg' => '活动失败'];
  130. }
  131. }
  132. return $result;
  133. }
  134. /**
  135. * 补卡
  136. */
  137. public function cSign()
  138. {
  139. $this->getSignState();
  140. if ($this->today_sign_status == 2 && $this->is_again ==0) {
  141. //可进行签到
  142. //$todo 支付才可以哦 微支付 返回201 需要先支付
  143. $cSignKey = CampaignConstants::getUserClickCSignKey($this->user_id);
  144. $uOrderKey = CampaignConstants::getUserPayOrderKey($this->user_id);
  145. $uOrderVal = Redis::instance()->get($uOrderKey);
  146. if ($uOrderVal === false) {
  147. //未支付
  148. if (Redis::instance()->setnx($cSignKey, time())) {
  149. Redis::instance()->expire($cSignKey, 86400);
  150. }
  151. return ['code' => 201, 'msg' => '请先充值'];
  152. }
  153. try {
  154. $update = [
  155. 'is_again' => 1,
  156. 'num' => ['exp', 'num+1'],
  157. ];
  158. $this->is_again = 1;
  159. $this->num++;
  160. if ($this->num == $this->period) {
  161. $update['status'] = 3;
  162. $this->status = 3;
  163. }
  164. if (model("CampaignUserMatch")->setConnect($this->user_id)->update($update, ['id' => $this->id])) {
  165. $result = ['code' => 200, 'msg' => '补卡成功'];
  166. $matchUpdate = [
  167. 'puncher_num' => ['exp', "puncher_num + 1"]
  168. ];
  169. if ($this->status == 3) {
  170. //完成 更新成功人数
  171. $matchUpdate['success_num'] = ['exp', "success_num + 1"];
  172. }
  173. if (model("CampaignMatch")->update($matchUpdate, ['id' => $this->match_id])) {
  174. //每日签到数据
  175. model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days"))]);
  176. //每日签到数据
  177. $yestdayCollectRow = model("MatchDayCollect")->where('match_id', 'eq', $this->match_id)->where('createdate', 'eq', date("Ymd", strtotime("-1 days")))->find();
  178. if ($yestdayCollectRow) {
  179. model("MatchDayCollect")->update(['num' => ['exp', "num+1"]], ['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days"))]);
  180. } else {
  181. model("MatchDayCollect")->insert(['match_id' => $this->match_id, 'createdate' => date("Ymd", strtotime("-1 days")), 'uv' => 0, 'num' => 1, 'updatetime' => time(), 'createtime' => time()]);
  182. }
  183. } else {
  184. throw new Exception('补卡失败', 207);
  185. }
  186. $this->flushState = 1;
  187. } else {
  188. throw new Exception('补卡失败', 208);
  189. }
  190. } catch (Exception $e) {
  191. Log::error('补卡失败:--msg:'.$e->getMessage()."--code:".$e->getCode() . '--line:'.$e->getLine());
  192. $result = ['code' => 202, 'msg' => '补卡失败'];
  193. }
  194. } else {
  195. $result = ['code' => 203, 'msg' => '不满足补卡条件'];
  196. }
  197. return $result;
  198. }
  199. /**
  200. * 检测当前状态 有变动需更新
  201. */
  202. public function checkStatus()
  203. {
  204. if (in_array($this->status, [1, 2, 3])) {
  205. $today = strtotime(date("Ymd"));
  206. //当前第几天
  207. $days = ceil(($today-strtotime($this->match_date))/86400);
  208. //差几天
  209. $day = $days - $this->num;
  210. if ($this->status == 1) {
  211. if ($day == 1 || $day == 2) {
  212. //更新为打卡中
  213. $status = 2;
  214. } else if ($day > 2) {
  215. //更新为失败
  216. $status = 5;
  217. }
  218. } elseif ($this->status == 2) {
  219. //打卡中 更新为失败
  220. if ($this->is_again == 1) {
  221. //已补卡
  222. if ($day > 1) {
  223. //更新为失败
  224. $status = 5;
  225. }
  226. } else {
  227. if ($day > 2) {
  228. //更新为失败
  229. $status = 5;
  230. }
  231. }
  232. }
  233. if (isset($status)) {
  234. //更新
  235. if (model("CampaignUserMatch")->setConnect($this->user_id)->update(['status' => $status], ['id' => $this->id])) {
  236. $this->status = $status;
  237. $this->flushState = 1;
  238. $this->getSignState();
  239. } else {
  240. throw new Exception("我的场次信息更新失败", 20002);
  241. }
  242. }
  243. }
  244. }
  245. /**
  246. * 获取当前打卡状态
  247. * @return array
  248. */
  249. public function getSignState()
  250. {
  251. //我的场次状态
  252. $matchStatus = $this->getState();
  253. switch ($matchStatus['status']) {
  254. case 1:
  255. $this->today_sign_status = -1; //报名状态 不可打卡
  256. break;
  257. case 2:
  258. $today = strtotime(date("Ymd"));
  259. //当前第几天
  260. $days = ceil(($today-strtotime( $this->match_date ) )/86400);
  261. $day = $days - $this->num;
  262. if ($day == 0) {
  263. $this->today_sign_status = 1; //今日已打卡
  264. } elseif ($day == 1) {
  265. $this->today_sign_status = 0; //今日未打卡
  266. } elseif ($day == 2) {
  267. $this->today_sign_status = 2; //今日未打卡 昨日也未打卡
  268. } else {
  269. $this->today_sign_status = -2;//失败状态 不可打卡 理论上不存在
  270. }
  271. break;
  272. default:
  273. $this->today_sign_status = -2; //失败状态 不可打卡
  274. }
  275. return $this->today_sign_status;
  276. }
  277. /**
  278. * 获取场次状态
  279. */
  280. public function getState()
  281. {
  282. switch ($this->status) {
  283. case 1:
  284. $state = ['status' => 1, 'state' => '报名状态'];
  285. break;
  286. case 2:
  287. $state = ['status' => 2, 'state' => '打卡中'];
  288. break;
  289. case 3:
  290. $state = ['status' => 3, 'state' => '挑战成功'];
  291. break;
  292. case 4:
  293. $state = ['status' => 4, 'state' => '领奖'];
  294. break;
  295. case 5:
  296. $state = ['status' => 5, 'state' => '失败'];
  297. break;
  298. default:
  299. $state = ['status' => 5, 'state' => '失败'];
  300. }
  301. return $state;
  302. }
  303. public function __destruct()
  304. {
  305. // TODO: Implement __destruct() method.
  306. //将变动写入redis
  307. if ($this->flushState == 1) {
  308. $redisKey = CampaignConstants::getUserMatchKey($this->user_id, $this->match_id);
  309. Redis::instance()->hMSet($redisKey, $this->attributes);
  310. Redis::instance()->expire($redisKey, 86400);
  311. }
  312. }
  313. public function __set($name, $value)
  314. {
  315. // TODO: Implement __set() method.
  316. $this->attributes[$name] = $value;
  317. }
  318. public function __get($name)
  319. {
  320. // TODO: Implement __get() method.
  321. return $this->attributes[$name];
  322. }
  323. }