Member.php 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  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 addon\memberregister\model\Register as RegisterModel;
  12. use app\model\BaseModel;
  13. use app\model\message\Sms;
  14. use app\model\system\Stat;
  15. use app\model\upload\Upload;
  16. use app\model\system\Address;
  17. use think\facade\Cache;
  18. use think\facade\Db;
  19. use addon\wechat\model\Fans;
  20. /**
  21. * 会员管理
  22. */
  23. class Member extends BaseModel
  24. {
  25. /**
  26. * 添加会员(注意等级名称)
  27. * @param $data
  28. * @return array
  29. */
  30. public function addMember($data)
  31. {
  32. if ($data[ 'username' ]) {
  33. $count = model('member')->getCount([
  34. [ 'username', '=', $data[ 'username' ] ],
  35. [ 'site_id', '=', $data[ 'site_id' ] ],
  36. [ 'is_delete', '=', 0 ]
  37. ]);
  38. if ($count > 0) {
  39. return $this->error('', 'USERNAME_EXISTED');
  40. }
  41. }
  42. if ($data[ 'mobile' ]) {
  43. $count = model('member')->getCount([
  44. [ 'mobile', '=', $data[ 'mobile' ] ],
  45. [ 'site_id', '=', $data[ 'site_id' ] ],
  46. [ 'is_delete', '=', 0 ]
  47. ]);
  48. if ($count > 0) {
  49. return $this->error('', 'MOBILE_EXISTED');
  50. }
  51. }
  52. if ($data[ 'email' ]) {
  53. $count = model('member')->getCount([
  54. [ 'email', '=', $data[ 'email' ] ],
  55. [ 'site_id', '=', $data[ 'site_id' ] ],
  56. [ 'is_delete', '=', 0 ]
  57. ]);
  58. if ($count > 0) {
  59. return $this->error('', 'EMAIL_EXISTED');
  60. }
  61. }
  62. $register_model = new RegisterModel();
  63. $register_config = $register_model->getConfig($data[ 'site_id' ])[ 'data' ];
  64. if ($register_config[ 'is_use' ]) {
  65. $data[ 'can_receive_registergift' ] = 1;
  66. }
  67. if ($data['member_level']) {
  68. $data['is_member'] = 1;
  69. $data['member_time'] = time();
  70. }
  71. $res = model('member')->add($data);
  72. if ($res === false) {
  73. return $this->error('', 'RESULT_ERROR');
  74. }
  75. //添加统计
  76. $stat = new Stat();
  77. $stat->switchStat([ 'type' => 'add_member', 'data' => [ 'member_count' => 1, 'site_id' => $data[ 'site_id' ] ] ]);
  78. // $stat->addShopStat([ 'member_count' => 1, 'site_id' => $data['site_id'] ]);
  79. return $this->success($res);
  80. }
  81. /**
  82. * 修改会员(注意标签与等级名称)
  83. * @param $data
  84. * @param $condition
  85. * @return array
  86. */
  87. public function editMember($data, $condition)
  88. {
  89. if (isset($data[ 'mobile' ]) && $data[ 'mobile' ] != '') {
  90. $check_condition = array_column($condition, 2, 0);
  91. $site_id = isset($check_condition[ 'site_id' ]) ? $check_condition[ 'site_id' ] : 0;
  92. $member_id = isset($check_condition[ 'member_id' ]) ? $check_condition[ 'member_id' ] : 0;
  93. $mobile_is_exist = model('member')->getCount([ [ 'mobile', '=', $data[ 'mobile' ] ], [ 'member_id', '<>', $member_id ], [ 'site_id', '=', $site_id ], [ 'is_delete', '=', 0 ] ]);
  94. if ($mobile_is_exist > 0) return $this->error('', 'MOBILE_EXISTED');
  95. }
  96. $res = model('member')->update($data, $condition);
  97. if ($res === false) {
  98. return $this->error('', 'SAVE_FAIL');
  99. }
  100. return $this->success($res);
  101. }
  102. /**
  103. * 修改用户名
  104. * @param $member_id
  105. * @param $username
  106. */
  107. public function editUsername($member_id, $site_id, $username)
  108. {
  109. $member_info = model('member')->getInfo([ [ 'member_id', '=', $member_id ] ], 'username,is_edit_username');
  110. if (empty($member_info)) return $this->error('', '未查找到该用户');
  111. if ($member_info[ 'username' ] == $username) return $this->error('', '与原用户名一致,无需修改');
  112. if (!$member_info[ 'is_edit_username' ]) return $this->error('', '用户名不可进行修改');
  113. $count = model('member')->getCount([ [ 'username', '=', $username ], [ 'site_id', '=', $site_id ] ], 'member_id');
  114. if ($count != 0) return $this->error('', '该用户名已存在');
  115. model('member')->update([ 'username' => $username, 'is_edit_username' => 0 ], [ [ 'member_id', '=', $member_id ] ]);
  116. return $this->success();
  117. }
  118. /**
  119. * 修改会员状态
  120. * @param $status
  121. * @param $condition
  122. * @return array
  123. */
  124. public function modifyMemberStatus($status, $condition)
  125. {
  126. $res = model('member')->update([
  127. 'status' => $status
  128. ], $condition);
  129. if ($res === false) {
  130. return $this->error('', 'RESULT_ERROR');
  131. }
  132. $check_condition = array_column($condition, 2, 0);
  133. $site_id = isset($check_condition[ 'site_id' ]) ? $check_condition[ 'site_id' ] : 0;
  134. Cache::set('member_blacklist_' . $site_id, null);
  135. return $this->success($res);
  136. }
  137. /**
  138. * 修改会员标签
  139. * @param $label_ids
  140. * @param $condition
  141. * @return array
  142. */
  143. public function modifyMemberLabel($label_ids, $condition)
  144. {
  145. //查询会员标签
  146. $label_list = model("member_label")->getList([ [ 'label_id', 'in', $label_ids ] ], 'label_id,label_name');
  147. $label_ids = '';
  148. $label_names = '';
  149. if (!empty($label_list)) {
  150. foreach ($label_list as $k => $v) {
  151. $label_ids = $label_ids . $v[ 'label_id' ] . ',';
  152. $label_names = $label_names . $v[ 'label_name' ] . ',';
  153. }
  154. }
  155. $res = model('member')->update([
  156. 'member_label' => $label_ids,
  157. 'member_label_name' => $label_names
  158. ], $condition);
  159. if ($res === false) {
  160. return $this->error('', 'RESULT_ERROR');
  161. }
  162. return $this->success($res);
  163. }
  164. /**
  165. * 重置密码
  166. * @param string $password
  167. * @param $condition
  168. * @return array
  169. */
  170. public function resetMemberPassword($password, $condition)
  171. {
  172. $res = model('member')->update([
  173. 'password' => data_md5($password)
  174. ], $condition);
  175. if ($res === false) {
  176. return $this->error('', 'RESULT_ERROR');
  177. }
  178. return $this->success($res);
  179. }
  180. /**
  181. * 修改密码
  182. * @param $member_id
  183. * @param $old_password
  184. * @param $new_password
  185. * @return array
  186. */
  187. public function modifyMemberPassword($member_id, $old_password, $new_password)
  188. {
  189. $res = model('member')->getCount([
  190. [ 'password', '=', data_md5($old_password) ],
  191. [ 'member_id', '=', $member_id ],
  192. ]);
  193. if ($res > 0) {
  194. $res = model('member')->update([
  195. 'password' => data_md5($new_password)
  196. ], [ [ 'member_id', '=', $member_id ] ]);
  197. if ($res === false) {
  198. return $this->error('', 'RESULT_ERROR');
  199. }
  200. return $this->success($res);
  201. } else {
  202. return $this->error('', 'PASSWORD_ERROR');
  203. }
  204. }
  205. /**
  206. * 删除会员(应用后台)
  207. * @param $condition
  208. * @return array
  209. */
  210. public function deleteMember($condition)
  211. {
  212. $res = model('member')->delete($condition);
  213. if ($res === false) {
  214. return $this->error('', 'RESULT_ERROR');
  215. }
  216. return $this->success($res);
  217. }
  218. /**
  219. * 获取会员信息
  220. * @param array $condition
  221. * @param string $field
  222. * @return array
  223. */
  224. public function getMemberInfo($condition = [], $field = '*')
  225. {
  226. $condition[] = [ 'is_delete', '=', 0 ];
  227. $member_info = model('member')->setIsCache(0)->getInfo($condition, $field);
  228. if (!empty($member_info) && empty($member_info[ 'wx_openid' ]) && !empty($member_info[ 'wx_unionid' ])) {
  229. $fans_model = new Fans();
  230. $fans_condition[] = [ "unionid", "=", $member_info[ 'wx_unionid' ] ];
  231. $fans_info = $fans_model->getFansInfo($fans_condition);
  232. if (!empty($fans_info[ 'data' ])) {
  233. $member_info[ 'wx_openid' ] = $fans_info[ 'data' ][ 'openid' ];
  234. }
  235. }
  236. return $this->success($member_info);
  237. }
  238. /**
  239. * 获取会员信息
  240. * @param int $member_id
  241. * @return array
  242. */
  243. public function getMemberDetail($member_id, $site_id)
  244. {
  245. $field = 'member_id,source_member,username,nickname,mobile,email,status,headimg,member_level,member_level_name,member_label,member_label_name,qq,realname,sex,location,birthday,reg_time,point,balance,growth,balance_money,account5,pay_password,member_level_type,store_id';
  246. $member_info = model('member')->getInfo([ [ 'member_id', '=', $member_id ], [ 'site_id', '=', $site_id ] ], $field);
  247. if (!empty($member_info)) {
  248. $member_info[ 'balance_total' ] = $member_info[ 'balance' ] + $member_info[ 'balance_money' ];
  249. return $this->success($member_info);
  250. }
  251. return $this->error();
  252. }
  253. public function getMemberDetailstore($member_id, $site_id,$store_id)
  254. {
  255. $field = 'member_id,source_member,username,nickname,mobile,email,status,headimg,member_level,member_level_name,member_label,member_label_name,qq,realname,sex,location,birthday,reg_time,point,balance,growth,balance_money,account5,pay_password,member_level_type';
  256. $member_info = model('member')->getInfo([ [ 'member_id', '=', $member_id ], [ 'site_id', '=', $site_id ] ], $field);
  257. if (!empty($member_info)) {
  258. $member_info[ 'balance_total' ] = $member_info[ 'balance' ] + $member_info[ 'balance_money' ];
  259. // $member_info['balance_total'] = model('member_account')->getSum([['member_id','=',$member_id],['store_id','=',$store_id],['account_type','=','balance']], 'account_data', '', null);
  260. return $this->success($member_info);
  261. }
  262. return $this->error();
  263. }
  264. /**
  265. * 获取会员数量
  266. * @param array $condition
  267. * @return array
  268. */
  269. public function getMemberCount($condition = [])
  270. {
  271. $condition[] = [ 'is_delete', '=', 0 ];
  272. $member_info = model('member')->getCount($condition);
  273. return $this->success($member_info);
  274. }
  275. /**
  276. * 获取会员字段总和
  277. * @param array $condition
  278. * @return array
  279. */
  280. public function getMemberSum($condition, $field)
  281. {
  282. $member_info = model('member')->getSum($condition, $field);
  283. return $this->success($member_info);
  284. }
  285. /**
  286. * 获取会员分页列表
  287. * @param array $condition
  288. * @param int $page
  289. * @param int $page_size
  290. * @param string $order
  291. * @param string $field
  292. * @return array
  293. */
  294. public function getMemberPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  295. {
  296. $condition[] = [ 'is_delete', '=', 0 ];
  297. $list = model('member')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
  298. return $this->success($list);
  299. }
  300. /**
  301. * 获取会员列表
  302. * @param array $where
  303. * @param bool $field
  304. * @param string $order
  305. * @param string $alias
  306. * @param array $join
  307. * @param string $group
  308. * @param null $limit
  309. * @return array
  310. */
  311. public function getMemberList($where = [], $field = true, $order = '', $alias = 'a', $join = [], $group = '', $limit = null)
  312. {
  313. $where[] = [ 'is_delete', '=', 0 ];
  314. $res = model('member')->getList($where, $field, $order, $alias, $join, $group, $limit);
  315. return $this->success($res);
  316. }
  317. /**
  318. * 客户设置成会员
  319. * @param $member_id
  320. */
  321. public function makeMember($member_id)
  322. {
  323. $res = model('member')->update(['is_member' => 1, 'member_time' => time()], [['member_id', '=', $member_id]] );
  324. return $res;
  325. }
  326. /**
  327. * 检测成为会员条件
  328. * @param $member_id
  329. */
  330. public function checkMember($member_id)
  331. {
  332. $member_info = model('member')->getInfo([['member_id', '=', $member_id]], 'member_level');
  333. if(empty($member_info))
  334. {
  335. return false;
  336. }
  337. if($member_info['member_level'] == 0)
  338. {
  339. return false;
  340. }
  341. return true;
  342. }
  343. /**
  344. * 检测当前的memberid是否是有效会员
  345. * @param $member_id
  346. * @param $site_id
  347. */
  348. public function checkMemberByMemberId($member_id, $site_id)
  349. {
  350. //检测会员是否以被删除
  351. $member_info = model('member')->getInfo([[ 'member_id', '=', $member_id ], [ 'is_delete', '=', 0 ],['status', '<>', 0], [ 'site_id', '=', $site_id ]], 'member_id');
  352. $check_member_id = $member_info['member_id'] ?? 0;
  353. if(empty($check_member_id))
  354. {
  355. return false;
  356. }
  357. return true;
  358. }
  359. /**
  360. * 绑定发送验证码
  361. * @param $data
  362. * @return array|mixed|void
  363. */
  364. public function bindCode($data)
  365. {
  366. //发送短信
  367. $sms_model = new Sms();
  368. $var_parse = array (
  369. "code" => $data[ "code" ],//验证码
  370. );
  371. $data[ "sms_account" ] = $data[ "mobile" ] ?? '';//手机号
  372. $data[ "var_parse" ] = $var_parse;
  373. $sms_result = $sms_model->sendMessage($data);
  374. if ($sms_result[ "code" ] < 0)
  375. return $sms_result;
  376. return $this->success();
  377. }
  378. /**
  379. * 找回密码发送验证码
  380. * @param $data
  381. * @return array|mixed|void
  382. */
  383. public function findCode($data)
  384. {
  385. //发送短信
  386. $sms_model = new Sms();
  387. $var_parse = array (
  388. "code" => $data[ "code" ],//验证码
  389. );
  390. $data[ "sms_account" ] = $data[ "mobile" ] ?? '';//手机号
  391. $data[ "var_parse" ] = $var_parse;
  392. $sms_result = $sms_model->sendMessage($data);
  393. if ($sms_result[ "code" ] < 0)
  394. return $sms_result;
  395. return $this->success();
  396. }
  397. /**
  398. * 设置会员交易密码
  399. * @param unknown $member_id
  400. * @param unknown $old_password
  401. * @param unknown $new_password
  402. */
  403. public function modifyMemberPayPassword($member_id, $password)
  404. {
  405. $res = model('member')->update([
  406. 'pay_password' => data_md5($password)
  407. ], [ [ 'member_id', '=', $member_id ] ]);
  408. if ($res === false) {
  409. return $this->error('', 'RESULT_ERROR');
  410. }
  411. return $this->success($res);
  412. }
  413. /**
  414. * 会员是否已设置支付密码
  415. * @param unknown $member_id
  416. */
  417. public function memberIsSetPayPassword($member_id)
  418. {
  419. $info = model('member')->getInfo([ [ 'member_id', '=', $member_id ] ], 'pay_password');
  420. if (empty($info[ 'pay_password' ])) return $this->success(0);
  421. else return $this->success(1);
  422. }
  423. /**
  424. * 检测会员支付密码是否正确
  425. * @param $member_id
  426. * @param $pay_password
  427. * @return array
  428. */
  429. public function checkPayPassword($member_id, $pay_password)
  430. {
  431. $res = model('member')->getCount([
  432. [ 'pay_password', '=', data_md5($pay_password) ],
  433. [ 'member_id', '=', $member_id ]
  434. ]);
  435. if ($res > 0) {
  436. return $this->success($res);
  437. } else {
  438. return $this->error('', 'PAY_PASSWORD_ERROR');
  439. }
  440. }
  441. /**
  442. * 找回密码发送验证码
  443. * @param $data
  444. * @return array|mixed|void
  445. */
  446. public function paypasswordCode($data)
  447. {
  448. //发送短信
  449. $sms_model = new Sms();
  450. $var_parse = array (
  451. "code" => $data[ "code" ],//验证码
  452. );
  453. $member_info_result = $this->getMemberInfo([ [ "member_id", "=", $data[ "member_id" ] ] ], "mobile");
  454. $member_info = $member_info_result[ "data" ];
  455. $data[ "sms_account" ] = $member_info[ "mobile" ] ?? '';//通过member_id获得手机号
  456. $data[ "var_parse" ] = $var_parse;
  457. $sms_result = $sms_model->sendMessage($data);
  458. if ($sms_result[ "code" ] < 0)
  459. return $sms_result;
  460. return $this->success();
  461. }
  462. /**
  463. * 拉取用户头像到本地
  464. * @param unknown $token
  465. */
  466. public function pullHeadimg($member_id)
  467. {
  468. $member_info = model("member")->getInfo([ [ 'member_id', '=', $member_id ] ], 'headimg');
  469. if (!empty($member_info[ 'headimg' ]) && is_url($member_info[ 'headimg' ])) {
  470. $upload = new Upload();
  471. $res = $upload->setPath("headimg/" . date("Ymd") . '/')->remotePull($member_info[ 'headimg' ]);
  472. if ($res[ 'code' ] >= 0) {
  473. model("member")->update([ 'headimg' => $res[ 'data' ][ 'pic_path' ] ], [ [ 'member_id', '=', $member_id ] ]);
  474. }
  475. }
  476. }
  477. /**
  478. * 获取店铺会员数量
  479. * @param array $condition
  480. * @param string $alias
  481. * @param unknown $join
  482. */
  483. public function getMemberAreaCount($condition, $alias = 'a', $join = [], $group = null)
  484. {
  485. $db = Db::name('member')->where($condition);
  486. if (!empty($join)) {
  487. $db = $this->parseJoin($db->alias($alias), $join);
  488. }
  489. if (!empty($group)) {
  490. $db = $db->group($group);
  491. }
  492. $count = $db->count();
  493. return $this->success($count);
  494. }
  495. /**
  496. * 按地域分布查询会员数量
  497. * @param unknown $site_id
  498. * @param string $handle
  499. */
  500. public function getMemberCountByArea($site_id, $handle = false)
  501. {
  502. $total_count = $this->getMemberAreaCount([ [ 'site_id', '=', $site_id ], [ 'is_delete', '=', 0 ] ]);
  503. $address = new Address();
  504. $list = $address->getAreaList([ [ 'pid', '=', 0 ] ], 'id,shortname', 'sort asc');
  505. $data = [];
  506. if ($total_count[ 'data' ]) {
  507. foreach ($list[ 'data' ] as $item) {
  508. $count = $this->getMemberAreaCount([ [ 'site_id', '=', $site_id ], [ 'province_id', '=', $item[ 'id' ] ], [ 'is_delete', '=', 0 ] ]);
  509. if ($handle) {
  510. if ($count[ 'data' ] > 0) {
  511. array_push($data, [
  512. 'name' => $item[ 'shortname' ],
  513. 'value' => $count[ 'data' ],
  514. 'ratio' => $count[ 'data' ] > 0 ? sprintf("%.2f", $count[ 'data' ] / $total_count[ 'data' ] * 100) : 0
  515. ]);
  516. }
  517. } else {
  518. array_push($data, [
  519. 'name' => $item[ 'shortname' ],
  520. 'value' => $count[ 'data' ],
  521. 'ratio' => $count[ 'data' ] > 0 ? sprintf("%.2f", $count[ 'data' ] / $total_count[ 'data' ] * 100) : 0
  522. ]);
  523. }
  524. }
  525. }
  526. if ($handle) {
  527. array_multisort(array_column($data, 'value'), SORT_DESC, $data);
  528. }
  529. return $this->success([
  530. 'page_count' => 1,
  531. 'count' => $total_count[ 'data' ],
  532. 'list' => $data
  533. ]);
  534. }
  535. /**
  536. * 处理表连接
  537. * @param unknown $db_obj
  538. * @param unknown $join
  539. */
  540. protected function parseJoin($db_obj, $join)
  541. {
  542. foreach ($join as $item) {
  543. list($table, $on, $type) = $item;
  544. $type = strtolower($type);
  545. switch ( $type ) {
  546. case "left":
  547. $db_obj = $db_obj->leftJoin($table, $on);
  548. break;
  549. case "inner":
  550. $db_obj = $db_obj->join($table, $on);
  551. break;
  552. case "right":
  553. $db_obj = $db_obj->rightjoin($table, $on);
  554. break;
  555. case "full":
  556. $db_obj = $db_obj->fulljoin($table, $on);
  557. break;
  558. default:
  559. break;
  560. }
  561. }
  562. return $db_obj;
  563. }
  564. /**
  565. *
  566. */
  567. public function getMemberImportLogList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
  568. {
  569. $list = model('member_import_log')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
  570. if (!empty($list[ 'list' ])) {
  571. foreach ($list[ 'list' ] as $key => $val) {
  572. $list[ 'list' ][ $key ][ "create_time" ] = date('Y-m-d H:i:s', $val[ 'create_time' ]);
  573. }
  574. }
  575. return $this->success($list);
  576. }
  577. /**
  578. * @param $param
  579. * @param $site_id
  580. * @return array
  581. * @throws \PHPExcel_Exception
  582. * @throws \PHPExcel_Reader_Exception
  583. * @throws \think\exception\PDOException
  584. */
  585. public function importMember($param, $site_id)
  586. {
  587. $PHPReader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
  588. //载入文件
  589. $PHPExcel = $PHPReader->load($param[ 'path' ]);
  590. //获取表中的第一个工作表,如果要获取第二个,把0改为1,依次类推
  591. $currentSheet = $PHPExcel->getSheet(0);
  592. //获取总行数
  593. $allRow = $currentSheet->getHighestRow();
  594. if ($allRow < 2) {
  595. return $this->error('', '导入了一个空文件');
  596. }
  597. $index = $param[ 'index' ];
  598. //每次导入100条
  599. $length = $index * 100;
  600. if ($index == 1) {
  601. $num = 2;
  602. $success_num = 0;
  603. $error_num = 0;
  604. $data_record = [
  605. "member_num" => ( $allRow - 1 ),
  606. "success_num" => 0,
  607. "error_num" => 0,
  608. "create_time" => time(),
  609. "status_name" => "等待导入"
  610. ];
  611. $record = model('member_import_record')->add($data_record);
  612. } else {
  613. $num = ( ( $index - 1 ) * 100 ) + 1;
  614. $success_num = $param[ 'success_num' ];
  615. $error_num = $param[ 'error_num' ];
  616. $record = $param[ 'record' ];
  617. }
  618. $type_num = 0;
  619. model('member')->startTrans();
  620. try {
  621. for ($i = $num; $i <= $length; $i++) {
  622. if ($i > $allRow) {
  623. break;
  624. }
  625. $type_num = $i;
  626. //用户名
  627. $username = $PHPExcel->getActiveSheet()->getCell('A' . $i)->getValue();
  628. $username = trim($username, ' ');
  629. //手机号
  630. $mobile = $PHPExcel->getActiveSheet()->getCell('B' . $i)->getValue();
  631. $mobile = trim($mobile, ' ');
  632. //昵称
  633. $nickname = $PHPExcel->getActiveSheet()->getCell('C' . $i)->getValue();
  634. $nickname = trim($nickname, ' ');
  635. //密码(明文)
  636. $password = $PHPExcel->getActiveSheet()->getCell('D' . $i)->getValue();
  637. $password = trim($password, ' ');
  638. //微信公众号openid
  639. $wx_openid = $PHPExcel->getActiveSheet()->getCell('E' . $i)->getValue();
  640. $wx_openid = trim($wx_openid, ' ');
  641. //微信小程序openid
  642. $weapp_openid = $PHPExcel->getActiveSheet()->getCell('F' . $i)->getValue();
  643. $weapp_openid = trim($weapp_openid, ' ');
  644. //真实姓名
  645. $realname = $PHPExcel->getActiveSheet()->getCell('G' . $i)->getValue();
  646. $realname = trim($realname, ' ');
  647. //积分
  648. $point = $PHPExcel->getActiveSheet()->getCell('H' . $i)->getValue();
  649. $point = trim($point, ' ');
  650. //成长值
  651. $growth = $PHPExcel->getActiveSheet()->getCell('I' . $i)->getValue();
  652. $growth = trim($growth, ' ');
  653. //余额(可提现)
  654. $balance_money = $PHPExcel->getActiveSheet()->getCell('J' . $i)->getValue();
  655. $balance_money = trim($balance_money, ' ');
  656. //余额(不可提现)
  657. $balance = $PHPExcel->getActiveSheet()->getCell('K' . $i)->getValue();
  658. $balance = trim($balance, ' ');
  659. //会员等级(id)
  660. $membeer_level_id = $PHPExcel->getActiveSheet()->getCell('L' . $i)->getValue();
  661. $membeer_level_id = trim($membeer_level_id, ' ');
  662. $not_data = [
  663. "username" => $username,
  664. "mobile" => $mobile,
  665. "nickname" => $nickname,
  666. "password" => $password,
  667. "wx_openid" => $wx_openid,
  668. "weapp_openid" => $weapp_openid,
  669. "realname" => $realname,
  670. "create_time" => time(),
  671. "record_id" => $record
  672. ];
  673. if ($username == "" && $mobile == "") {
  674. $not_data[ 'content' ] = "失败,用户名或手机号必须存在一个";
  675. model('member_import_log')->add($not_data);
  676. $error_num++;
  677. continue;
  678. }
  679. if (!empty($mobile) && !preg_match('/^\d{11}$/ims', $mobile)) {
  680. $not_data[ 'content' ] = "失败,手机号格式错误";
  681. model('member_import_log')->add($not_data);
  682. $error_num++;
  683. continue;
  684. }
  685. if ($nickname == "") {
  686. $not_data[ 'content' ] = "失败,用户昵称不能为空";
  687. model('member_import_log')->add($not_data);
  688. $error_num++;
  689. continue;
  690. }
  691. if ($password == "") {
  692. $not_data[ 'content' ] = "失败,用户密码不能为空";
  693. model('member_import_log')->add($not_data);
  694. $error_num++;
  695. continue;
  696. }
  697. if ($username) {
  698. $username_res = model("member")->getInfo([ 'username' => $username ]);//根据用户名查找
  699. if ($username_res) {
  700. $not_data[ 'content' ] = "失败,已存在相同的用户名";
  701. model('member_import_log')->add($not_data);
  702. $error_num++;
  703. continue;
  704. }
  705. }
  706. if ($mobile) {
  707. $mobile_res = model("member")->getInfo([ 'mobile' => $mobile ]);//根据手机号查找
  708. if ($mobile_res) {
  709. $not_data[ 'content' ] = "失败,已存在相同的手机号";
  710. model('member_import_log')->add($not_data);
  711. $error_num++;
  712. continue;
  713. }
  714. }
  715. if ($wx_openid) {
  716. $wx_openid_res = model("member")->getInfo([ 'wx_openid' => $wx_openid ]);//根据微信公众号ID查找
  717. if ($wx_openid_res) {
  718. $not_data[ 'content' ] = "失败,已存在相同的公众号openid";
  719. model('member_import_log')->add($not_data);
  720. $error_num++;
  721. continue;
  722. }
  723. }
  724. if ($weapp_openid) {
  725. $weapp_openid_res = model("member")->getInfo([ 'weapp_openid' => $weapp_openid ]);//根据小程序ID查找
  726. if ($weapp_openid_res) {
  727. $not_data[ 'content' ] = "失败,已存在相同的小程序openid";
  728. model('member_import_log')->add($not_data);
  729. $error_num++;
  730. continue;
  731. }
  732. }
  733. if ($membeer_level_id == "") {
  734. $is_member = 0;
  735. } else {
  736. $is_member = 1;
  737. $member_level_info = model('member_level')->getInfo([ 'level_name' => $membeer_level_id ]);
  738. if (empty($member_level_info)) {
  739. $not_data[ 'content' ] = "失败,未查到该会员等级";
  740. model('member_import_log')->add($not_data);
  741. $error_num++;
  742. break;
  743. }
  744. }
  745. $data = [
  746. "username" => isset($username) ? $username : '',
  747. "mobile" => isset($mobile) ? $mobile : '',
  748. "nickname" => $nickname,
  749. "password" => data_md5($password),
  750. "member_level" => $member_level_info[ 'level_id' ] ?? "",
  751. "wx_openid" => isset($wx_openid) ? $wx_openid : '',
  752. "weapp_openid" => isset($weapp_openid) ? $weapp_openid : '',
  753. "realname" => isset($realname) ? $realname : '',
  754. 'member_level_name' => $member_level_info[ 'level_name' ] ?? "",
  755. 'point' => isset($point) ? $point : 0,
  756. 'growth' => isset($growth) ? $growth : 0,
  757. 'balance_money' => isset($balance_money) ? $balance_money : 0.00,
  758. 'balance' => isset($balance) ? $balance : 0.00,
  759. 'reg_time' => time(),
  760. 'login_time' => time(),
  761. 'last_login_time' => time(),
  762. 'site_id' => 1,
  763. 'is_member' => $is_member,
  764. 'member_code' => isset($mobile) ? $mobile : ''
  765. ];
  766. model('member')->add($data);
  767. $not_data[ 'content' ] = "成功";
  768. model('member_import_log')->add($not_data);
  769. $success_num++;
  770. }
  771. model('member')->commit();
  772. if ($success_num + $error_num == ( $allRow - 1 )) {
  773. $data_record = [
  774. "member_num" => ( $allRow - 1 ),
  775. "success_num" => $success_num,
  776. "error_num" => $error_num,
  777. "create_time" => time(),
  778. "status_name" => "导入成功"
  779. ];
  780. model('member_import_record')->update($data_record, [ 'id' => $record ]);
  781. }
  782. return $this->success([
  783. "allRow" => $allRow,
  784. "num" => $type_num,
  785. "path" => $param[ 'path' ],
  786. "name" => $param[ 'filename' ],
  787. "success_num" => $success_num,
  788. "error_num" => $error_num,
  789. "record" => $record
  790. ]);
  791. } catch (\Exception $e) {
  792. model('member')->rollback();
  793. return $this->error('', $e->getMessage());
  794. }
  795. }
  796. /**
  797. * 获取用户黑名单
  798. * @return array
  799. */
  800. public function getMemberBlacklist($site_id)
  801. {
  802. $cache = Cache::get('member_blacklist_' . $site_id);
  803. if (!empty($cache)) return $this->success($cache);
  804. $blacklist = model('member')->getColumn([ [ 'status', '=', 0 ] ], 'member_id');
  805. Cache::set('member_blacklist_' . $site_id, $blacklist);
  806. return $this->success($blacklist);
  807. }
  808. /**
  809. * 获取会员导入记录列表
  810. */
  811. public function getMemberImportRecordList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = '*')
  812. {
  813. $list = model('member_import_record')->pageList($condition, $field, $order, $page, $page_size, '', '', '');
  814. if (!empty($list[ 'list' ])) {
  815. foreach ($list[ 'list' ] as $key => $val) {
  816. $list[ 'list' ][ $key ][ "create_time" ] = date('Y-m-d H:i:s', $val[ 'create_time' ]);
  817. }
  818. }
  819. return $this->success($list);
  820. }
  821. /**
  822. * 获取导入记录单条数据
  823. */
  824. public function getMemberImportRecordInfo($id)
  825. {
  826. $info = model('member_import_record')->getInfo([ 'id' => $id ]);
  827. return $this->success($info);
  828. }
  829. //更改
  830. public function alterShareRelation($member_id, $share_member, $site_id)
  831. {
  832. $member_info = model('member')->getInfo([
  833. [ 'member_id', '=', $member_id ],
  834. [ 'site_id', '=', $site_id ],
  835. ]);
  836. if (empty($member_info)) {
  837. return $this->error(null, '会员数据有误');
  838. }
  839. //只有普通会员 并且没有绑定上级才修改关系
  840. if ($member_info[ 'is_fenxiao' ] == 0 && $member_info[ 'fenxiao_id' ] == 0) {
  841. model('member')->update([
  842. 'share_member' => $share_member,
  843. ], [
  844. [ 'member_id', '=', $member_id ],
  845. [ 'site_id', '=', $site_id ],
  846. ]);
  847. event('AlterShareRelation', [ 'site_id' => $site_id, 'member_id' => $member_id ]);
  848. }
  849. return $this->success();
  850. }
  851. /**
  852. * 更新会员最后访问时间
  853. * @param $member_id
  854. */
  855. public static function modifyLastVisitTime($member_id)
  856. {
  857. $res = model("member")->update([ 'last_visit_time' => time() ], [ 'member_id' => $member_id ]);
  858. return $res;
  859. }
  860. /**
  861. * 更新会员最后消费时间
  862. * @param $member_id
  863. */
  864. public static function modifyLastConsumTime($member_id)
  865. {
  866. $res = model("member")->update([ 'last_consum_time' => time() ], [ 'member_id' => $member_id ]);
  867. return $res;
  868. }
  869. /**
  870. * 获取用户可用余额
  871. * @param $site_id
  872. * @param $member_id
  873. * @return array
  874. */
  875. public function getMemberUsableBalance($site_id, $member_id)
  876. {
  877. $member_info = model('member')->getInfo([
  878. [ 'site_id', '=', $site_id ], [ 'member_id', '=', $member_id ], [ 'is_delete', '=', 0 ]
  879. ], 'balance - balance_lock as balance,balance_money - balance_money_lock as balance_money');
  880. if (empty($member_info)) {
  881. return $this->error('', '未获取到用户信息');
  882. }
  883. //获取当前用户门店的所有余额总额
  884. $member_info[ 'balance' ] = $member_info[ 'balance' ] < 0 ? 0 : $member_info[ 'balance' ];
  885. $member_info[ 'balance_money' ] = $member_info[ 'balance_money' ] < 0 ? 0 : $member_info[ 'balance_money' ];
  886. $member_info[ 'usable_balance' ] = round($member_info[ 'balance' ] + $member_info[ 'balance_money' ], 2);
  887. return $this->success($member_info);
  888. }
  889. public function getMemberUsableBalancenew($site_id, $member_id,$storeid = 0)
  890. {
  891. $member_info = model('member')->getInfo([
  892. [ 'site_id', '=', $site_id ], [ 'member_id', '=', $member_id ], [ 'is_delete', '=', 0 ],['store_id','=',$storeid]
  893. ], 'balance - balance_lock as balance,balance_money - balance_money_lock as balance_money');
  894. if (empty($member_info)) {
  895. return $this->error('', '未获取到用户信息');
  896. }
  897. $member_info[ 'balance' ] = $member_info[ 'balance' ] < 0 ? 0 : $member_info[ 'balance' ];
  898. $member_info[ 'balance_money' ] = $member_info[ 'balance_money' ] < 0 ? 0 : $member_info[ 'balance_money' ];
  899. $member_info[ 'usable_balance' ] = round($member_info[ 'balance' ] + $member_info[ 'balance_money' ], 2);
  900. return $this->success($member_info);
  901. }
  902. /**
  903. * 生成随机数
  904. * @param int $length
  905. * @return string
  906. */
  907. public function memberCode($length)
  908. {
  909. $pattern = array(
  910. '1','2','3','4','5','6','7','8','9','0'
  911. );
  912. $keys = array_rand($pattern, $length);
  913. $key = '';
  914. for ($i = 0; $i < $length; $i++) {
  915. $key .= $pattern[$keys[$i]]; //生成php随机数
  916. }
  917. return $key;
  918. }
  919. /**
  920. * 办理会员
  921. * @param $data
  922. */
  923. public function handleMember($data)
  924. {
  925. model('member')->startTrans();
  926. try {
  927. $member_info = model('member')->getInfo([ ['member_id', '=', $data['member_id']], ['site_id', '=', $data['site_id']] ]);
  928. if($member_info['is_member'] == 1){
  929. return $this->success();
  930. }
  931. $level_info = model('member_level')->getInfo([ ['site_id', '=', $data['site_id']], ['level_id', '=', $data['level_id']] ], 'level_id, sort, growth, level_name');
  932. $growth = $level_info['growth'] - $member_info['growth'];
  933. $save_data = ['is_member' => 1];
  934. $member_code = $data['member_code'] ?? '';
  935. if($member_code){
  936. $member_count = model('member')->getInfo([ ['site_id', '=', $data['site_id']],['member_code', '=', $member_code], ['member_id', '<>', $data['member_id']] ]);
  937. if($member_count) return $this->error('', '当前会员编码已存在,请重新设置');
  938. $save_data['member_code'] = $member_code;
  939. }else{
  940. $member_code = $member_info['mobile'] ? $member_info['mobile'] : $this->memberCode(11);
  941. $save_data['member_code'] = $member_code;
  942. }
  943. model('member')->update($save_data, [
  944. ['member_id', '=', $data['member_id']],
  945. ['site_id', '=', $data['site_id']],
  946. ]);
  947. if($growth > 0) {
  948. $account = new MemberAccount();
  949. $res = $account->addMemberAccount($data['site_id'], $data['member_id'], 'growth', $growth, 'adjust', '等级调整', '管理员调整客户等级', 0);
  950. if($res['code'] < 0) return $res;
  951. }
  952. model('member')->commit();
  953. return $this->success();
  954. } catch (\Exception $e) {
  955. model('member')->rollback();
  956. return $this->error($e->getMessage() . $e->getFile() . $e->getLine());
  957. }
  958. }
  959. }