MemberAccount.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\member;
  11. use app\model\BaseModel;
  12. use app\model\message\Message;
  13. use app\model\message\Sms;
  14. use addon\wechat\model\Message as WechatMessage;
  15. use app\model\member\Member as MemberModel;
  16. use addon\weapp\model\Message as WeappMessage;
  17. use think\facade\Db;
  18. /**
  19. * 会员账户
  20. */
  21. class MemberAccount extends BaseModel
  22. {
  23. //账户类型
  24. private $account_type = [
  25. 'balance' => '储值余额',
  26. 'balance_money' => '现金余额',
  27. 'point' => '积分',
  28. 'growth' => '成长值'
  29. ];
  30. //来源类型
  31. private $from_type = [];
  32. public function __construct()
  33. {
  34. $event_from_type = event('MemberAccountFromType', '');
  35. $from_type = [];
  36. foreach ($event_from_type as $info) {
  37. if (isset($info[ 'balance' ])) {
  38. $balance = array_keys($info[ 'balance' ]);
  39. $from_type[ 'balance' ][ $balance[ 0 ] ] = $info[ 'balance' ][ $balance[ 0 ] ];
  40. }
  41. if (isset($info[ 'point' ])) {
  42. $point = array_keys($info[ 'point' ]);
  43. $from_type[ 'point' ][ $point[ 0 ] ] = $info[ 'point' ][ $point[ 0 ] ];
  44. }
  45. if (isset($info[ 'growth' ])) {
  46. $growth = array_keys($info[ 'growth' ]);
  47. $from_type[ 'growth' ][ $growth[ 0 ] ] = $info[ 'growth' ][ $growth[ 0 ] ];
  48. }
  49. if (isset($info[ 'balance_money' ])) {
  50. $balance_money = array_keys($info[ 'balance_money' ]);
  51. $from_type[ 'balance_money' ][ $balance_money[ 0 ] ] = $info[ 'balance_money' ][ $balance_money[ 0 ] ];
  52. }
  53. }
  54. $from_type[ 'balance' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
  55. $from_type[ 'balance_money' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
  56. $from_type[ 'balance' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
  57. $from_type[ 'balance_money' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
  58. $from_type[ 'point' ][ 'order' ] = [ 'type_name' => '消费', 'type_url' => '' ];
  59. $from_type[ 'point' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
  60. $from_type[ 'growth' ][ 'adjust' ] = [ 'type_name' => '调整', 'type_url' => '' ];
  61. $from_type[ 'balance' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
  62. $from_type[ 'balance_money' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
  63. $from_type[ 'balance' ][ 'membercode' ] = [ 'type_name' => '会员码扣款', 'type_url' => '' ];
  64. $from_type[ 'balance_money' ][ 'membercode' ] = [ 'type_name' => '会员码扣款', 'type_url' => '' ];
  65. $from_type[ 'point' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
  66. $from_type[ 'growth' ][ 'upgrade' ] = [ 'type_name' => '升级', 'type_url' => '' ];
  67. $from_type[ 'balance' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
  68. $from_type[ 'balance_money' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
  69. $from_type[ 'point' ][ 'refund' ] = [ 'type_name' => '退还', 'type_url' => '' ];
  70. $from_type[ 'point' ][ 'pointexchangerefund' ] = [ 'type_name' => '积分兑换退还', 'type_url' => '' ];
  71. $from_type[ 'balance' ][ 'presale_deposit_refund' ] = [ 'type_name' => '预售定金退还', 'type_url' => '' ];
  72. $from_type[ 'balance' ][ 'presale_refund' ] = [ 'type_name' => '预售订单退还', 'type_url' => '' ];
  73. $from_type[ 'balance' ][ 'memberlevel' ] = [ 'type_name' => '开卡', 'type_url' => '' ];
  74. $from_type[ 'point' ][ 'memberlevel' ] = [ 'type_name' => '开卡', 'type_url' => '' ];
  75. $from_type[ 'balance_money' ][ 'birthdaygift' ] = [ 'type_name' => '生日有礼', 'type_url' => '' ];
  76. $from_type[ 'balance' ][ 'birthdaygift' ] = [ 'type_name' => '生日有礼', 'type_url' => '' ];
  77. $from_type[ 'point' ][ 'birthdaygift' ] = [ 'type_name' => '生日有礼', 'type_url' => '' ];
  78. $from_type[ 'balance_money' ][ 'scenefestival' ] = [ 'type_name' => '节日有礼', 'type_url' => '' ];
  79. $from_type[ 'balance' ][ 'scenefestival' ] = [ 'type_name' => '节日有礼', 'type_url' => '' ];
  80. $from_type[ 'point' ][ 'scenefestival' ] = [ 'type_name' => '节日有礼', 'type_url' => '' ];
  81. $from_type[ 'balance_money' ][ 'pinfan' ] = [ 'type_name' => '拼团返利', 'type_url' => '' ];
  82. $from_type[ 'balance' ][ 'pinfan' ] = [ 'type_name' => '拼团返利', 'type_url' => '' ];
  83. $from_type[ 'point' ][ 'pinfan' ] = [ 'type_name' => '拼团返利', 'type_url' => '' ];
  84. $from_type[ 'balance_money' ][ 'withdraw' ] = [ 'type_name' => '提现', 'type_url' => '' ];
  85. $from_type[ 'balance' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
  86. $from_type[ 'balance_money' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
  87. $from_type[ 'point' ][ 'giftcard' ] = [ 'type_name' => '礼品卡', 'type_url' => '' ];
  88. $from_type[ 'balance' ][ 'hongbao' ] = [ 'type_name' => '裂变红包', 'type_url' => '' ];
  89. $from_type[ 'balance_money' ][ 'hongbao' ] = [ 'type_name' => '裂变红包', 'type_url' => '' ];
  90. $from_type[ 'point' ][ 'point_expire' ] = [ 'type_name' => '积分到期', 'type_url' => '' ];
  91. $from_type[ 'point' ][ 'point_set_zero' ] = [ 'type_name' => '积分清零', 'type_url' => '' ];
  92. $this->from_type = $from_type;
  93. }
  94. /**
  95. * 获取账户类型
  96. */
  97. public function getAccountType()
  98. {
  99. return $this->account_type;
  100. }
  101. /**
  102. * 获取来源类型
  103. */
  104. public function getFromType()
  105. {
  106. return $this->from_type;
  107. }
  108. /**
  109. * 添加会员账户数据
  110. * @param int $site_id
  111. * @param int $member_id
  112. * @param int $account_type
  113. * @param float $account_data
  114. * @param string $relate_url
  115. * @param string $remark
  116. */
  117. public function addMemberAccount($site_id, $member_id, $account_type, $account_data, $from_type, $relate_tag, $remark, $related_id = 0)
  118. {
  119. model('member_account')->startTrans();
  120. try {
  121. //账户检测
  122. $member_account = Db::name("member")->where([
  123. [ 'member_id', '=', $member_id ],
  124. [ 'site_id', '=', $site_id ]
  125. ])->field($account_type . ', username, mobile, nickname, email')->lock(true)->find();
  126. $account_new_data = round((float) $member_account[ $account_type ] + (float) $account_data, 2);
  127. if($from_type == "point_expire" && $account_new_data < 0){
  128. $account_data = -$member_account[ $account_type ];
  129. $remark = "积分到期:".$member_account[ $account_type ];
  130. $account_new_data = 0;
  131. }else if ((float) $account_new_data < 0) {
  132. model('member_account')->rollback();
  133. $msg = '';
  134. if ($account_type == 'balance') {
  135. $msg = '账户余额不足';
  136. } elseif ($account_type == 'point') {
  137. $msg = '账户积分不足';
  138. } elseif ($account_type == 'growth') {
  139. $msg = '账户成长值不足';
  140. }
  141. return $this->error('', $msg);
  142. }
  143. //添加记录
  144. $type_info = $this->from_type[ $account_type ][ $from_type ];
  145. $data = array (
  146. 'site_id' => $site_id,
  147. 'member_id' => $member_id,
  148. 'account_type' => $account_type,
  149. 'account_data' => $account_data,
  150. 'from_type' => $from_type,
  151. 'type_name' => $type_info[ 'type_name' ],
  152. 'type_tag' => $relate_tag,
  153. 'create_time' => time(),
  154. 'username' => $member_account[ 'username' ],
  155. 'mobile' => $member_account[ 'mobile' ],
  156. 'email' => $member_account[ 'email' ],
  157. 'remark' => $remark,
  158. 'related_id'=>$related_id,
  159. );
  160. model('member_account')->add($data);
  161. //账户更新
  162. model('member')->update([
  163. $account_type => $account_new_data
  164. ], [
  165. 'member_id' => $member_id
  166. ]);
  167. event("AddMemberAccount", $data);
  168. model('member_account')->commit();
  169. //发送消息通知(余额变动通知)
  170. if($account_type == 'balance' || $account_type == 'balance_money'){
  171. $data['keywords'] = 'USER_BALANCE_CHANGE_NOTICE';
  172. $message_model = new Message();
  173. $message_model->sendMessage($data);
  174. }
  175. return $this->success([ 'member_id' => $member_id, $account_type => sprintf("%.2f", $account_new_data) ]);
  176. } catch (\Exception $e) {
  177. model('member_account')->rollback();
  178. return $this->error('', $e->getMessage());
  179. }
  180. }
  181. public function addMemberAccountnew($site_id, $member_id, $account_type, $account_data, $from_type, $relate_tag, $remark, $related_id = 0,$store_id = 0)
  182. {
  183. model('member_account')->startTrans();
  184. try {
  185. //账户检测
  186. $member_account = Db::name("member")->where([
  187. [ 'member_id', '=', $member_id ],
  188. [ 'site_id', '=', $site_id ]
  189. ])->field($account_type . ', username, mobile, nickname, email')->lock(true)->find();
  190. $account_new_data = round((float) $member_account[ $account_type ] + (float) $account_data, 2);
  191. if($from_type == "point_expire" && $account_new_data < 0){
  192. $account_data = -$member_account[ $account_type ];
  193. $remark = "积分到期:".$member_account[ $account_type ];
  194. $account_new_data = 0;
  195. }else if ((float) $account_new_data < 0) {
  196. model('member_account')->rollback();
  197. $msg = '';
  198. if ($account_type == 'balance') {
  199. $msg = '账户余额不足';
  200. } elseif ($account_type == 'point') {
  201. $msg = '账户积分不足';
  202. } elseif ($account_type == 'growth') {
  203. $msg = '账户成长值不足';
  204. }
  205. return $this->error('', $msg);
  206. }
  207. //添加记录
  208. $type_info = $this->from_type[ $account_type ][ $from_type ];
  209. $data = array (
  210. 'site_id' => $site_id,
  211. 'member_id' => $member_id,
  212. 'account_type' => $account_type,
  213. 'account_data' => $account_data,
  214. 'from_type' => $from_type,
  215. 'type_name' => $type_info[ 'type_name' ],
  216. 'type_tag' => $relate_tag,
  217. 'create_time' => time(),
  218. 'username' => $member_account[ 'username' ],
  219. 'mobile' => $member_account[ 'mobile' ],
  220. 'email' => $member_account[ 'email' ],
  221. 'remark' => $remark,
  222. 'related_id'=>$related_id,
  223. 'store_id'=>$store_id,
  224. );
  225. model('member_account')->add($data);
  226. //账户更新
  227. //查询用户store_id是否已经绑定门店
  228. $membermodel = new MemberModel();
  229. $mDetail = $membermodel->getMemberDetail($member_id,$site_id);
  230. if($mDetail['data']['store_id'] != 0){
  231. model('member')->update([
  232. $account_type => $account_new_data,
  233. ], [
  234. 'member_id' => $member_id
  235. ]);
  236. }else{
  237. model('member')->update([
  238. $account_type => $account_new_data,
  239. 'store_id' => $store_id
  240. ], [
  241. 'member_id' => $member_id
  242. ]);
  243. }
  244. event("AddMemberAccount", $data);
  245. model('member_account')->commit();
  246. //发送消息通知(余额变动通知)
  247. if($account_type == 'balance' || $account_type == 'balance_money'){
  248. $data['keywords'] = 'USER_BALANCE_CHANGE_NOTICE';
  249. $message_model = new Message();
  250. $message_model->sendMessage($data);
  251. }
  252. return $this->success([ 'member_id' => $member_id, $account_type => sprintf("%.2f", $account_new_data) ]);
  253. } catch (\Exception $e) {
  254. model('member_account')->rollback();
  255. return $this->error('', $e->getMessage());
  256. }
  257. }
  258. /**
  259. * 获取账户分页列表
  260. * @param array $condition
  261. * @param int $page
  262. * @param int $page_size
  263. * @param string $order
  264. * @param string $field
  265. * @return array|\multitype
  266. */
  267. public function getMemberAccountPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc,id desc', $field = '*', $alias = 'a', $join = [])
  268. {
  269. $list = model('member_account')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
  270. return $this->success($list);
  271. }
  272. /**
  273. * 获取账户列表
  274. * @param array $condition
  275. * @param string $field
  276. * @param string $order
  277. * @param null $limit
  278. * @return array|\multitype
  279. */
  280. public function getMemberAccountList($condition = [], $field = '*', $order = '', $limit = null)
  281. {
  282. $list = model('member_account')->getList($condition, $field, $order, '', '', '', $limit);
  283. return $this->success($list);
  284. }
  285. /**
  286. * 获取账户总额
  287. * @param array $where
  288. * @param string $field
  289. * @param string $alias
  290. * @param null $join
  291. * @return array
  292. */
  293. public function getMemberAccountSum($where = [], $field = '', $alias = 'a', $join = null)
  294. {
  295. $sum = model('member_account')->getSum($where, $field, $alias, $join);
  296. return $this->success($sum);
  297. }
  298. /**
  299. * 会员账户余额变动通知
  300. * @param $data
  301. */
  302. public function messageAccountChangeNotice($data)
  303. {
  304. //发送短信
  305. $sms_model = new Sms();
  306. $member_model = new MemberModel();
  307. $member_info_result = $member_model->getMemberInfo([["member_id", "=", $data["member_id"]]]);
  308. $member_info = $member_info_result["data"];
  309. $remark = $data['remark'] == '' ? $data['type_name'] : $data['remark'];
  310. preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $remark, $matches);
  311. $username = empty($member_info["nickname"]) ? $member_info["mobile"] : $member_info["nickname"];
  312. $username = !empty($username) ? $username : $member_info["username"];
  313. $var_parse = array(
  314. 'username' => str_replace(' ','', $username),//会员名
  315. 'balance' => $member_info['balance'],
  316. 'balance_money' => $member_info['balance_money']
  317. );
  318. $data["sms_account"] = $member_info["mobile"];//手机号
  319. $data["var_parse"] = $var_parse;
  320. $sms_model->sendMessage($data);
  321. //绑定微信公众号才发送
  322. if (!empty($member_info) && !empty($member_info["wx_openid"])) {
  323. $money = abs($data['account_data']);
  324. $wechat_model = new WechatMessage();
  325. $data["openid"] = $member_info["wx_openid"];
  326. $data["template_data"] = [
  327. 'keyword1' => $data['type_name'],
  328. 'keyword2' => $data['account_data'] > 0 ? '+¥'.$money : '-¥'.$money,
  329. 'keyword3' => '¥'.($member_info['balance'] + $member_info['balance_money']),
  330. 'remark' => $data['remark'],
  331. ];
  332. $data["page"] = "";
  333. $wechat_model->sendMessage($data);
  334. }
  335. //发送订阅消息
  336. if (!empty($member_info) && !empty($member_info["weapp_openid"])) {
  337. $weapp_model = new WeappMessage();
  338. $data["openid"] = $member_info["weapp_openid"];
  339. $data["template_data"] = [
  340. 'amount6' => [
  341. 'value' => $data['account_data']
  342. ],
  343. 'phrase7' => [
  344. 'value' => $data['type_name']
  345. ],
  346. 'time8' => [
  347. 'value' => time_to_date(time())
  348. ]
  349. ];
  350. $data["page"] = "";
  351. $weapp_model->sendMessage($data);
  352. }
  353. }
  354. }