MemberLevel.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和使用。
  9. * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
  10. * =========================================================
  11. */
  12. namespace app\model\member;
  13. use addon\coupon\model\Coupon;
  14. use app\model\system\Cron;
  15. use think\facade\Cache;
  16. use app\model\BaseModel;
  17. use addon\coupon\model\CouponType;
  18. /**
  19. * 会员等级
  20. */
  21. class MemberLevel extends BaseModel
  22. {
  23. public $level_change_type = [
  24. 'upgrade' => '自动升级',
  25. 'buy' => '付费购卡',
  26. 'adjust' => '商家调整',
  27. 'expire' => '到期降级'
  28. ];
  29. public $level_time = [
  30. 'week' => '一周',
  31. 'month' => '一月',
  32. 'quarter' => '一季',
  33. 'year' => '一年',
  34. ];
  35. /**
  36. * 添加会员等级
  37. *
  38. * @param array $data
  39. */
  40. public function addMemberLevel($data)
  41. {
  42. $res = model('member_level')->add($data);
  43. Cache::tag("member_level")->clear();
  44. return $this->success($res);
  45. }
  46. /**
  47. * 修改会员等级(不允许批量处理)
  48. *
  49. * @param array $data
  50. * @param array $condition
  51. */
  52. public function editMemberLevel($data, $condition)
  53. {
  54. $res = model('member_level')->update($data, $condition);
  55. $check_condition = array_column($condition, 2, 0);
  56. $level_id = isset($check_condition[ 'level_id' ]) ? $check_condition[ 'level_id' ] : 0;
  57. if (!empty($level_id) && isset($data['level_name'])) {
  58. model('member')->update([ 'member_level_name' => $data['level_name'] ], [ ['member_level', '=', $level_id] ]);
  59. }
  60. Cache::tag("member_level")->clear();
  61. return $this->success();
  62. }
  63. /**
  64. * 更新会员等级
  65. * @param $site_id
  66. */
  67. public function startlevel($site_id)
  68. {
  69. $cron = new Cron();
  70. $cron->addCron(1, 0, "会员等级更新", "MemberLevelUpdate", time(), 0);
  71. return $this->success();
  72. }
  73. /**
  74. * 刷新会员等级排序
  75. */
  76. private function refreshSort($site_id)
  77. {
  78. $list = model('member_level')->getList([['site_id', '=', $site_id]], 'level_id, growth', 'growth asc');
  79. foreach ($list as $k => $v) {
  80. model('member_level')->update(['sort' => $k], [['level_id', '=', $v['level_id']]]);
  81. }
  82. }
  83. /**
  84. * 刷新会员等级
  85. */
  86. private function refreshLevel($site_id)
  87. {
  88. model('member_level')->update(['is_default' => 0], [['is_default', '=', 1], ['site_id', '=', $site_id]]);
  89. }
  90. /**
  91. * 删除会员等级
  92. * @param array $condition
  93. */
  94. public function deleteMemberLevel($level_id, $site_id)
  95. {
  96. $count = model('member')->getCount([ ['member_level', '=', $level_id], ['is_delete', '=', 0] ]);
  97. if ($count > 0) return $this->error('', '有会员正持有该等级不可删除');
  98. $condition = [
  99. ['level_id', '=', $level_id],
  100. ['site_id', '=', $site_id],
  101. ];
  102. $res = model('member_level')->delete($condition);
  103. Cache::tag("member_level")->clear();
  104. return $this->success($res);
  105. }
  106. /**
  107. * 获取一条等级
  108. * @param $condition
  109. * @param string $field
  110. * @param string $order
  111. * @return array
  112. */
  113. public function getFirstMemberLevel($condition, $field = '*', $order = ""){
  114. $data = model('member_level')->getFirstData($condition, $field, $order);
  115. return $this->success($data);
  116. }
  117. /**
  118. * 获取会员等级信息
  119. *
  120. * @param array $condition
  121. * @param string $field
  122. */
  123. public function getMemberLevelInfo($condition = [], $field = '*')
  124. {
  125. $data = json_encode([$condition, $field]);
  126. $cache = Cache::get("member_level_getMemberLevelInfo_" . $data);
  127. if (!empty($cache)) {
  128. return $this->success($cache);
  129. }
  130. $info = model('member_level')->getInfo($condition, $field);
  131. if ($info) {
  132. //获取优惠券信息
  133. if (isset($info['send_coupon']) && !empty($info['send_coupon'])) {
  134. //优惠券字段
  135. $coupon_field = 'coupon_type_id,type,coupon_name,image,money,discount,validity_type,fixed_term,status,is_limit,at_least,count,lead_count,end_time';
  136. $model = new CouponType();
  137. $coupon = $model->getCouponTypeList([['coupon_type_id', 'in', $info['send_coupon']]], $coupon_field);
  138. $info['coupon_list'] = $coupon;
  139. }
  140. }
  141. Cache::tag("member_level")->set("member_level_getMemberLevelInfo_" . $data, $info);
  142. return $this->success($info);
  143. }
  144. /**
  145. * 获取会员等级列表
  146. *
  147. * @param array $condition
  148. * @param string $field
  149. * @param string $order
  150. * @param string $limit
  151. */
  152. public function getMemberLevelList($condition = [], $field = '*', $order = 'sort asc, level_id asc', $limit = null)
  153. {
  154. $data = json_encode([$condition, $field, $order, $limit]);
  155. $cache = Cache::get("member_level_getMemberLevelList_" . $data);
  156. if (!empty($cache)) {
  157. return $this->success($cache);
  158. }
  159. $list = model('member_level')->getList($condition, $field, $order, '', '', '', $limit);
  160. Cache::tag("member_level")->set("member_level_getMemberLevelList_" . $data, $list);
  161. return $this->success($list);
  162. }
  163. /**
  164. * 获取会员等级分页列表
  165. *
  166. * @param array $condition
  167. * @param number $page
  168. * @param string $page_size
  169. * @param string $order
  170. * @param string $field
  171. */
  172. public function getMemberLevelPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'sort asc, level_id asc', $field = '*')
  173. {
  174. $data = json_encode([$condition, $field, $order, $page, $page_size]);
  175. $cache = Cache::get("member_level_getMemberLevelPageList_" . $data);
  176. if (!empty($cache)) {
  177. return $this->success($cache);
  178. }
  179. $list = model('member_level')->pageList($condition, $field, $order, $page, $page_size);
  180. Cache::tag("member_level")->set("member_level_getMemberLevelPageList_" . $data, $list);
  181. return $this->success($list);
  182. }
  183. /**
  184. * 添加会员卡变更记录
  185. * @param $member_id 变更会员
  186. * @param $site_id 站点id
  187. * @param $after_level 变更之后的会员卡
  188. * @param $action_uid 操作人
  189. * @param $action_type 操作人类型
  190. * @param $action_name 操作人昵称
  191. * @param string $action_desc 描述
  192. */
  193. public function addMemberLevelChangeRecord($member_id, $site_id, $after_level, $expire_time, $change_type, $action_uid, $action_type, $action_name, $action_desc = ''){
  194. model('member_level_records')->startTrans();
  195. try {
  196. $member_info = model('member')->getInfo([ ['member_id', '=', $member_id] ], 'member_level,member_level_name,member_level_type,level_expire_time,is_member');
  197. $level_info = model('member_level')->getInfo([ ['level_id', '=', $after_level], ['site_id', '=', $site_id] ], 'level_id,level_name,level_type');
  198. if ($member_info['member_level'] == $level_info['level_id']) {
  199. model('member_level_records')->rollback();
  200. return $this->success('', '会员卡未发生变更');
  201. }
  202. $prev_record = model('member_level_records')->getFirstData([ ['member_id', '=', $member_id] ], 'id', 'change_time desc');
  203. // 添加变更记录
  204. $data = [
  205. 'member_id' => $member_id,
  206. 'site_id' => $site_id,
  207. 'before_level_id' => $member_info['member_level'],
  208. 'before_level_name' => $member_info['member_level_name'],
  209. 'before_level_type' => $member_info['member_level_type'],
  210. 'before_expire_time' => $member_info['level_expire_time'],
  211. 'after_level_id' => $level_info['level_id'],
  212. 'after_level_name' => $level_info['level_name'],
  213. 'after_level_type' => $level_info['level_type'],
  214. 'prev_id' => $prev_record['id'] ?? 0,
  215. 'change_time' => time(),
  216. 'action_uid' => $action_uid,
  217. 'action_type' => $action_type,
  218. 'action_name' => $action_name,
  219. 'action_desc' => $action_desc,
  220. 'change_type' => $change_type,
  221. 'change_type_name' => $this->level_change_type[$change_type]
  222. ];
  223. model('member_level_records')->add($data);
  224. // 变更会员等级
  225. $edit_memeber_data = [
  226. 'member_level' => $level_info['level_id'],
  227. 'member_level_name' => $level_info['level_name'],
  228. 'member_level_type' => $level_info['level_type'],
  229. 'level_expire_time' => $level_info['level_type'] == 0 ? 0 : $expire_time
  230. ];
  231. if (!$member_info['is_member']) {
  232. $edit_memeber_data['is_member'] = 1;
  233. $edit_memeber_data['member_time'] = time();
  234. }
  235. model('member')->update($edit_memeber_data, [ ['member_id','=',$member_id] ]);
  236. $cron = new Cron();
  237. $cron->deleteCron([ ['event', '=', 'MemberLevelAutoExpire'], ['relate_id', '=', $member_id ] ]);
  238. if ($level_info['level_type']) {
  239. $cron->addCron(1, 0, "会员卡自动过期", "MemberLevelAutoExpire", $expire_time, $member_id);
  240. }
  241. Cache::tag("member_level_records")->clear();
  242. model('member_level_records')->commit();
  243. return $this->success();
  244. } catch (\Exception $e) {
  245. model('member_level_records')->rollback();
  246. return $this->error('', $e->getMessage());
  247. }
  248. }
  249. /**
  250. * 获取会员会员卡变更记录
  251. * @param array $condition
  252. * @param int $page
  253. * @param int $list_rows
  254. * @param string $field
  255. * @param string $order
  256. * @param string $alias
  257. * @param array $join
  258. * @param null $group
  259. * @return array
  260. */
  261. public function getMemberLevelRecordPageList($condition = [], $page = 1, $list_rows = PAGE_LIST_ROWS, $field = '*', $order = 'change_time desc', $alias = 'a', $join = [], $group = null){
  262. $data = json_encode([$condition, $field, $order, $page, $list_rows, $alias, $join, $group]);
  263. $cache = Cache::get("getMemberLevelRecordPageList" . $data);
  264. if (!empty($cache)) {
  265. return $this->success($cache);
  266. }
  267. $list = model('member_level_records')->pageList($condition, $field, $order, $page, $list_rows, $alias, $join, $group);
  268. Cache::tag("member_level_records")->set("getMemberLevelRecordPageList" . $data, $list);
  269. return $this->success($list);
  270. }
  271. /**
  272. * 会员卡过期
  273. * @param $member_id
  274. */
  275. public function memberLevelExpire($member_id){
  276. $member_info = model('member')->getInfo([ ['member_id', '=', $member_id] ], 'member_id,site_id,nickname,member_level,level_expire_time,growth');
  277. if (!empty($member_info) && !empty($member_info['level_expire_time']) && $member_info['level_expire_time'] < time()) {
  278. $alias = 'mlr';
  279. $join = [
  280. ['member_level ml', 'ml.level_id = mlr.before_level_id', 'inner']
  281. ];
  282. // 如果会员还存在未过期的付费会员卡
  283. $level_info = model('member_level_records')->getFirstDataView([ ['before_expire_time', '>', time()], ['member_id', '=', $member_id] ], 'mlr.*', 'change_time desc', $alias, $join);
  284. if (!empty($level_info)) {
  285. $this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['before_level_id'], $level_info['before_expire_time'], 'expire', $member_id, 'member', $member_info['nickname']);
  286. } else {
  287. // 如果之前免费卡还存在
  288. $level_info = model('member_level_records')->getFirstDataView([ ['before_level_type', '=', 0], ['member_id', '=', $member_id] ], 'mlr.*', 'change_time desc', $alias, $join);
  289. if (!empty($level_info)) {
  290. $this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['before_level_id'], $level_info['before_expire_time'], 'expire', $member_id, 'member', $member_info['nickname']);
  291. event("AddMemberAccount", ['account_type' => 'growth', 'member_id' => $member_id, 'site_id' => $member_info['site_id']]);
  292. } else {
  293. // 如果之前的免费卡不存在
  294. $level_info = model('member_level')->getFirstData([ ['site_id', '=', $member_info['site_id']], ['level_type', '=', 0], ['growth', '<=', $member_info['growth']] ], '*', 'growth desc');
  295. if (!empty($level_info)) {
  296. $this->addMemberLevelChangeRecord($member_id, $member_info['site_id'], $level_info['level_id'], 0, 'expire', $member_id, 'member', $member_info['nickname']);
  297. $member_account = new MemberAccount();
  298. //赠送红包
  299. if ($level_info['send_balance'] > 0) {
  300. $member_account->addMemberAccount($member_info['site_id'], $member_info['member_id'], 'balance', $level_info['send_balance'], 'upgrade', '会员升级得红包' . $level_info['send_balance'], '会员等级升级奖励');
  301. }
  302. //赠送积分
  303. if ($level_info['send_point'] > 0) {
  304. $member_account->addMemberAccount($member_info['site_id'], $member_info['member_id'], 'point', $level_info['send_point'], 'upgrade', '会员升级得积分' . $level_info['send_point'], '会员等级升级奖励');
  305. }
  306. //给用户发放优惠券
  307. if (!empty($level_info['send_coupon'])) {
  308. $coupon_array = explode(',', $level_info['send_coupon']);
  309. $coupon_model = new Coupon();
  310. $coupon_array = array_map(function ($value){
  311. return ['coupon_type_id' => $value, 'num' => 1];
  312. }, $coupon_array);
  313. $coupon_model->giveCoupon($coupon_array, $member_info['site_id'], $member_info['member_id'], 3);
  314. }
  315. }
  316. }
  317. }
  318. }
  319. }
  320. }