UserSignRepository.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\user;
  12. use app\common\dao\user\UserSignDao;
  13. use app\common\repositories\BaseRepository;
  14. use app\common\repositories\system\groupData\GroupDataRepository;
  15. use app\common\repositories\system\groupData\GroupRepository;
  16. use think\exception\ValidateException;
  17. use think\facade\Db;
  18. class UserSignRepository extends BaseRepository
  19. {
  20. /**
  21. * @var UserSignDao
  22. */
  23. protected $dao;
  24. /**
  25. * UserSignRepository constructor.
  26. * @param UserSignDao $dao
  27. */
  28. public function __construct(UserSignDao $dao)
  29. {
  30. $this->dao = $dao;
  31. }
  32. /**
  33. * 获取指定日期 用户的连续签到数
  34. * @param int $uid
  35. * @param string $day
  36. * @return array
  37. * @author Qinii
  38. * @day 6/8/21
  39. */
  40. public function getSign(int $uid,string $day)
  41. {
  42. return $this->dao->getSearch(['uid' => $uid,'day' => $day])->value('sign_num');
  43. }
  44. /**
  45. * 根据传入的天数获取签到配置中对应天的奖励信息。
  46. *
  47. * 此方法用于根据用户签到的天数,返回对应天数的签到奖励配置。如果传入的天数大于7,
  48. * 则计算该天数对应的一周内的某一天(循环),如果小于等于7,则直接返回对应天数的配置。
  49. * 如果配置不存在,则返回默认的无签到奖励配置。
  50. *
  51. * @param int $num 签到的天数,从1开始计数。
  52. * @return array 返回包含签到天数和积分奖励的数组。
  53. * @throws ValidateException 如果签到配置未开启,则抛出异常。
  54. */
  55. public function getDay(int $num)
  56. {
  57. // 当签到天数大于7时,计算该天数在一周内对应的实际天数
  58. if($num > 7) {
  59. $yu = ($num % 7);
  60. $num = ($yu == 0) ? 6 : $yu - 1;
  61. } else {
  62. // 当签到天数小于等于7时,直接使用传入的天数,如果天数为0,则调整为0
  63. $num = (($num -1) < 0) ? 0 : ($num -1);
  64. }
  65. // 加载签到配置
  66. $title = $this->signConfig();
  67. // 如果签到配置为空,则抛出异常
  68. if(empty($title)) throw new ValidateException('未开启签到功能');
  69. // 尝试获取传入天数对应的签到奖励配置
  70. if (isset($title[$num]['value'])) {
  71. $dat = $title[$num]['value'];
  72. } else {
  73. // 如果不存在对应的签到奖励配置,则返回默认的无签到奖励配置
  74. $dat = [
  75. 'sign_day' => '无',
  76. 'sign_integral' => 0,
  77. ];
  78. }
  79. return $dat;
  80. }
  81. /**
  82. * 签到操作
  83. * @param int $uid
  84. * @author Qinii
  85. * @day 6/8/21
  86. */
  87. public function create(int $uid)
  88. {
  89. /**
  90. * 用户昨天的签到情况,如果有就是连续签到,如果没有就是第一天签到
  91. * 根据签到天数计算签到积分等操作
  92. * 计算用户剩余积分
  93. *
  94. */
  95. $yesterday = date("Y-m-d",strtotime("-1 day"));
  96. $sign_num = ($this->getSign($uid,$yesterday) ?: 0) + 1;
  97. //签到规则计算
  98. $sign_task = $this->getDay($sign_num);
  99. $user = app()->make(UserRepository::class)->get($uid);
  100. $integral = $sign_task['sign_integral'];
  101. if ($user->is_svip > 0) {
  102. $makeInteres = app()->make(MemberinterestsRepository::class);
  103. $integral = $integral * $makeInteres->getSvipInterestVal($makeInteres::HAS_TYPE_SIGN);;
  104. }
  105. $user_make = app()->make(UserRepository::class);
  106. $user = $user_make->get($uid);
  107. $integral_ = $user['integral'] + $integral;
  108. $data = [
  109. 'uid' => $uid,
  110. 'sign_num' => $sign_num,
  111. 'number' => $integral,
  112. 'integral' => $integral_,
  113. 'title' => '签到',
  114. ];
  115. //增加记录
  116. $arr = [
  117. 'status' => 1,
  118. 'mark' => '签到,获得积分'. $integral,
  119. 'number' => $integral,
  120. 'balance'=> $integral_,
  121. ];
  122. return Db::transaction(function() use($uid,$data,$user_make,$sign_task,$arr,$integral){
  123. $ret = $this->dao->create($data);
  124. $user_make->incIntegral($uid,$integral,'签到'.$sign_task['sign_day'],'sign_integral',$arr);
  125. app()->make(UserBrokerageRepository::class)->incMemberValue($uid, 'member_sign_num', $ret->sign_id);
  126. return compact('integral');
  127. });
  128. }
  129. /**
  130. * 获取列表数据
  131. *
  132. * 根据给定的条件数组、页码和每页的记录数,从数据库中检索并返回列表数据。
  133. * 这个方法主要用于处理数据的分页查询,支持根据条件进行筛选。
  134. *
  135. * @param array $where 查询条件数组,用于构建SQL查询的WHERE子句。
  136. * @param int $page 当前页码,用于计算查询的起始记录。
  137. * @param int $limit 每页的记录数,用于限制查询返回的记录数量。
  138. * @return array 返回包含 'count' 和 'list' 两个元素的数组,'count' 表示总记录数,'list' 表示当前页的记录列表。
  139. */
  140. public function getList(array $where,int $page,int $limit)
  141. {
  142. // 构建查询条件,根据创建时间降序排序
  143. $query = $this->dao->getSearch($where)->order('create_time DESC');
  144. // 计算满足条件的总记录数
  145. $count = $query->count();
  146. // 根据当前页码和每页的记录数,从查询结果中获取当前页的记录列表
  147. $list = $query->page($page,$limit)->select();
  148. // 将总记录数和当前页的记录列表作为一个数组返回
  149. return compact('count','list');
  150. }
  151. /**
  152. * 连续签到日期展示 1 - 7天
  153. * 是否签到
  154. * 累计签到数
  155. */
  156. public function info(int $uid)
  157. {
  158. $ret = $this->signStatus($uid);
  159. $is_sign = $ret['is_sign'];
  160. $sign_num = $ret['sign_num'];
  161. $title = $this->signConfig();
  162. $userInfo = app()->make(UserRepository::class)->getWhere(['uid' => $uid],'uid,avatar,nickname,integral');
  163. $count = $this->dao->getSearch(['uid' => $uid])->count('*');
  164. return compact('userInfo','is_sign','sign_num','count','title');
  165. }
  166. /**
  167. * 获取签名配置
  168. *
  169. * 本函数用于获取签到配置的相关信息,特别是针对一周内每一天的签到标题。
  170. * 它首先通过依赖注入的方式创建了一个GroupRepository的实例,用于后续获取签到天数的配置。
  171. * 接着,利用GroupDataRepository来查询具体的签到标题数据,这些数据是根据签到天数配置来获取的,并且只包含状态为1(有效)的数据。
  172. * 最后,将查询结果转换为数组并返回,这个结果包含了签到标题在内的相关信息,而一些敏感或不必要的信息(如ID、创建时间等)被隐藏。
  173. *
  174. * @return array 返回包含签到配置信息的数组,特别是每一天的签到标题。
  175. */
  176. public function signConfig(){
  177. // 通过依赖注入创建GroupRepository实例,用于查询签到天数配置
  178. $group_make = app()->make(GroupRepository::class);
  179. // 根据ID获取签到天数配置
  180. $sign_day_config = $group_make->keyById('sign_day_config');
  181. // 通过依赖注入创建GroupDataRepository实例,用于查询签到标题数据
  182. $title = app()->make(GroupDataRepository::class)
  183. // 根据签到天数配置查询签到标题数据,并限制查询结果为最近7天
  184. ->getGroupDataWhere(0,$sign_day_config)
  185. // 筛选出状态为有效的数据
  186. ->where('status',1)
  187. // 限制查询结果数量为7条
  188. ->limit(7)
  189. // 隐藏某些字段
  190. ->hidden(['group_data_id','group_id','create_time','mer_id'])
  191. // 执行查询并转换为数组形式返回
  192. ->select()->toArray();
  193. // 返回查询结果
  194. return $title;
  195. }
  196. /**
  197. * 连续签到 获取 1- 7 天
  198. * @param $uid
  199. * @return array
  200. * @author Qinii
  201. * @day 6/10/21
  202. */
  203. public function signStatus($uid)
  204. {
  205. $day = date('Y-m-d',time());
  206. $sign_num = 0;
  207. $sign_num = $this->getSign($uid,$day);
  208. $is_sign = $sign_num ? 1 : 0;
  209. if($sign_num > 7){
  210. $sign_num = ($sign_num % 7);
  211. if(!$sign_num) $sign_num = 7;
  212. }
  213. if(!$is_sign){
  214. $yesterday = date("Y-m-d",strtotime("-1 day"));
  215. $sign_num = $this->getSign($uid,$yesterday) ?: 0;
  216. if($sign_num > 7){
  217. $sign_num = ($sign_num % 7);
  218. }
  219. }
  220. return compact('is_sign','sign_num');
  221. }
  222. /**
  223. * 按月显示签到记录
  224. * @param array $where
  225. * @return array
  226. * @author Qinii
  227. * @day 6/10/21
  228. */
  229. public function month(array $where)
  230. {
  231. $group = $this->dao->getSearch($where)->field('FROM_UNIXTIME(unix_timestamp(create_time),"%Y-%m") as time')
  232. ->order('time DESC')->group('time')->select();
  233. $ret = [];
  234. foreach ($group as $k => $item){
  235. $ret[$k]['month'] = $item['time'];
  236. $query = $this->dao->getSearch($where)->field('title,number,create_time')->whereMonth('create_time',$item['time']);
  237. $ret[$k]['list'] = $query->order('create_time DESC')->select();
  238. }
  239. return $ret;
  240. }
  241. }