Member.php 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\shop\controller;
  11. use addon\fenxiao\model\Fenxiao;
  12. use addon\supermember\model\MemberCard;
  13. use app\model\member\Member as MemberModel;
  14. use app\model\member\MemberAddress as MemberAddressModel;
  15. use app\model\member\MemberLabel as MemberLabelModel;
  16. use app\model\member\MemberLevel as MemberLevelModel;
  17. use app\model\member\MemberAccount as MemberAccountModel;
  18. use app\model\member\Config as ConfigModel;
  19. use app\model\store\Store;
  20. use app\model\system\Stat;
  21. use app\model\system\UserGroup;
  22. use Carbon\Carbon;
  23. use think\facade\Db;
  24. use phpoffice\phpexcel\Classes\PHPExcel;
  25. use phpoffice\phpexcel\Classes\PHPExcel\Writer\Excel2007;
  26. use app\model\upload\Upload as UploadModel;
  27. use app\model\member\MemberCluster as MemberClusterModel;
  28. use think\facade\Config;
  29. use addon\coupon\model\Coupon as CouponModel;
  30. /**
  31. * 会员管理 控制器
  32. */
  33. class Member extends BaseShop
  34. {
  35. /*
  36. * 会员概况
  37. */
  38. public function index()
  39. {
  40. $member = new MemberModel();
  41. $condition[] = [ 'site_id', '=', $this->site_id ];
  42. $store_model = new Store();
  43. $store_id_arr = [];
  44. $userGroupModel = new UserGroup();
  45. $userInfo = $this->user_info;
  46. $userGroupWhere['uid'] = $userInfo['uid'];
  47. $userGroupList = $userGroupModel->getUserList($userGroupWhere,'uid,store_id');
  48. $store_id_arr = array_column($userGroupList['data'],'store_id');
  49. if(!empty($store_id_arr) && !$userInfo['is_admin']){
  50. $condition[] = [ "store_id", "in", $store_id_arr];
  51. }
  52. // 累计会员数
  53. $total_count = $member->getMemberCount($condition);
  54. // 今日新增数
  55. $new_condition = $condition;
  56. $new_condition[]=[ 'reg_time', 'between', [ date_to_time(date('Y-m-d 00:00:00')), time() ] ];
  57. $newadd_count = $member->getMemberCount($new_condition);
  58. // 已购会员数
  59. $condition[] = [ 'order_num', '>', 0 ];
  60. $buyed_count = $member->getMemberCount($condition);
  61. $this->assign('data', [
  62. 'total_count' => $total_count[ 'data' ],
  63. 'newadd_count' => $newadd_count[ 'data' ],
  64. 'buyed_count' => $buyed_count[ 'data' ]
  65. ]);
  66. $stat_shop_model = new Stat();
  67. $today = Carbon::now();
  68. $yesterday = Carbon::yesterday();
  69. $stat_today = $stat_shop_model->getStatShop($this->site_id, $today->year, $today->month, $today->day)[ 'data' ];
  70. $stat_yesterday = $stat_shop_model->getStatShop($this->site_id, $yesterday->year, $yesterday->month, $yesterday->day)[ 'data' ];
  71. $this->assign('today', $stat_today);
  72. $this->assign('yesterday', $stat_yesterday);
  73. return $this->fetch('member/index');
  74. }
  75. /**
  76. * 获取区域会员数量
  77. */
  78. public function areaCount()
  79. {
  80. if (request()->isAjax()) {
  81. $member = new MemberModel();
  82. $handle = input('handle', false);
  83. $res = $member->getMemberCountByArea($this->site_id, $handle);
  84. return $res;
  85. }
  86. }
  87. /**
  88. * 会员列表
  89. */
  90. public function memberList()
  91. {
  92. //判断分销是否存在
  93. $is_exit_fenxiao = addon_is_exit('fenxiao');
  94. $cluster_id = input('cluster_id', '');//获取会员群体
  95. $member_cluster_model = new MemberClusterModel();
  96. if (request()->isAjax()) {
  97. $page = input('page', 1);
  98. $page_size = input('page_size', PAGE_LIST_ROWS);
  99. $search_text = input('search_text', '');
  100. $search_text_type = input('search_text_type', 'username');//可以传username mobile email
  101. $level_id = input('level_id', 0);
  102. $label_id = input('label_id', 0);
  103. $reg_start_date = input('reg_start_date', '');
  104. $reg_end_date = input('reg_end_date', '');
  105. $status = input('status', '');
  106. $cluster_id = input('cluster_id', '');//获取会员群体
  107. $last_login_time_start = input('last_login_time_start', '');//上次登录时间
  108. $last_login_time_end = input('last_login_time_end', '');
  109. $start_order_complete_num = input('start_order_complete_num', '');//成交次数
  110. $end_order_complete_num = input('end_order_complete_num', '');
  111. $start_order_complete_money = input('start_order_complete_money', '');//消费金额
  112. $end_order_complete_money = input('end_order_complete_money', '');
  113. $start_point = input('start_point', '');//积分
  114. $end_point = input('end_point', '');
  115. $start_balance = input('start_balance', '');//余额
  116. $end_balance = input('end_balance', '');
  117. $start_growth = input('start_growth', '');//成长值
  118. $end_growth = input('end_growth', '');
  119. $login_type = input('login_type', '');//来源渠道
  120. $is_member = input('is_member', '');
  121. $condition[] = [ 'site_id', '=', $this->site_id ];
  122. //下拉选择
  123. $condition[] = [ $search_text_type, 'like', "%" . $search_text . "%" ];
  124. //会员等级
  125. if ($level_id != 0) {
  126. $condition[] = [ 'member_level', '=', $level_id ];
  127. }
  128. //会员标签
  129. if ($label_id != 0) {
  130. //raw方法变为public类型 需要实例化以后调用
  131. $condition[] = [ "", 'exp', Db::raw("FIND_IN_SET({$label_id}, member_label)") ];
  132. }
  133. //注册时间
  134. if ($reg_start_date != '' && $reg_end_date != '') {
  135. $condition[] = [ 'reg_time', 'between', [ strtotime($reg_start_date), strtotime($reg_end_date) ] ];
  136. } else if ($reg_start_date != '' && $reg_end_date == '') {
  137. $condition[] = [ 'reg_time', '>=', strtotime($reg_start_date) ];
  138. } else if ($reg_start_date == '' && $reg_end_date != '') {
  139. $condition[] = [ 'reg_time', '<=', strtotime($reg_end_date) ];
  140. }
  141. //会员状态
  142. if ($status != '') {
  143. $condition[] = [ 'status', '=', $status ];
  144. }
  145. //会员群体
  146. if ($cluster_id != '') {
  147. //获取会员群体的member_id值
  148. $member_cluster_info = $member_cluster_model->getMemberClusterInfo([ "cluster_id" => $cluster_id ], 'member_ids');
  149. if (!empty($member_cluster_info[ 'data' ][ 'member_ids' ])) {
  150. $condition[] = [ 'member_id', 'in', $member_cluster_info[ 'data' ][ 'member_ids' ] ];
  151. }
  152. }
  153. //上次访问时间
  154. if ($last_login_time_start != '' && $last_login_time_end != '') {
  155. $condition[] = [ 'last_login_time', 'between', [ strtotime($last_login_time_start), strtotime($last_login_time_end) ] ];
  156. } else if ($last_login_time_start != '' && $last_login_time_end == '') {
  157. $condition[] = [ 'last_login_time', '>=', strtotime($last_login_time_start) ];
  158. } else if ($last_login_time_start == '' && $last_login_time_end != '') {
  159. $condition[] = [ 'last_login_time', '<=', strtotime($last_login_time_end) ];
  160. }
  161. //成交次数
  162. if ($start_order_complete_num != '' && $end_order_complete_num != '') {
  163. $condition[] = [ 'order_complete_num', 'between', [ $start_order_complete_num, $end_order_complete_num ] ];
  164. } else if ($start_order_complete_num != '' && $end_order_complete_num == '') {
  165. $condition[] = [ 'order_complete_num', '>=', $start_order_complete_num ];
  166. } else if ($start_order_complete_num == '' && $end_order_complete_num != '') {
  167. $condition[] = [ 'order_complete_num', '<=', $end_order_complete_num ];
  168. }
  169. //消费金额
  170. if ($start_order_complete_money != '' && $end_order_complete_money != '') {
  171. $condition[] = [ 'order_complete_money', 'between', [ $start_order_complete_money, $end_order_complete_money ] ];
  172. } else if ($start_order_complete_money != '' && $end_order_complete_money == '') {
  173. $condition[] = [ 'order_complete_money', '>=', $start_order_complete_money ];
  174. } else if ($start_order_complete_money == '' && $end_order_complete_money != '') {
  175. $condition[] = [ 'order_complete_money', '<=', $end_order_complete_money ];
  176. }
  177. //积分
  178. if ($start_point != '' && $end_point != '') {
  179. $condition[] = [ 'point', 'between', [ $start_point, $end_point ] ];
  180. } else if ($start_point != '' && $end_point == '') {
  181. $condition[] = [ 'point', '>=', $start_point ];
  182. } else if ($start_point == '' && $end_point != '') {
  183. $condition[] = [ 'point', '<=', $end_point ];
  184. }
  185. //余额
  186. if ($start_balance != '' && $end_balance != '') {
  187. $condition[] = [ '', 'exp', Db::raw("(balance + balance_money) between {$start_balance} and {$end_balance}") ];
  188. } else if ($start_balance != '' && $end_balance == '') {
  189. $condition[] = [ '', 'exp', Db::raw("(balance + balance_money) >= {$start_balance}") ];
  190. } else if ($start_balance == '' && $end_balance != '') {
  191. $condition[] = [ '', 'exp', Db::raw("(balance + balance_money) <= {$end_balance}") ];
  192. }
  193. //成长值
  194. if ($start_growth != '' && $end_growth != '') {
  195. $condition[] = [ 'growth', 'between', [ $start_growth, $end_growth ] ];
  196. } else if ($start_growth != '' && $end_growth == '') {
  197. $condition[] = [ 'growth', '>=', $start_growth ];
  198. } else if ($start_growth == '' && $end_growth != '') {
  199. $condition[] = [ 'growth', '<=', $end_growth ];
  200. }
  201. //来源渠道
  202. if ($login_type != '') {
  203. $condition[] = [ 'login_type', '=', $login_type ];
  204. }
  205. if ($is_member != '') $condition[] = [ 'is_member', '=', $is_member ];
  206. $order = 'last_visit_time desc';
  207. $field = '*';
  208. $store_id_arr = [];
  209. $userGroupModel = new UserGroup();
  210. $userInfo = $this->user_info;
  211. $userGroupWhere['uid'] = $userInfo['uid'];
  212. $userGroupList = $userGroupModel->getUserList($userGroupWhere,'uid,store_id');
  213. $store_id_arr = array_column($userGroupList['data'],'store_id');
  214. if(!empty($store_id_arr) && !$userInfo['is_admin']){
  215. $condition[] = [ "store_id", "in", $store_id_arr];
  216. }
  217. $member_model = new MemberModel();
  218. $result = $member_model->getMemberPageList($condition, $page, $page_size, $order, $field);
  219. $member_label_model = new MemberLabelModel();
  220. $label_list = $member_label_model->getMemberLabelList([], 'label_id, label_name');
  221. if (!empty($label_list[ 'data' ])) {
  222. //格式化标签
  223. $format_label_list = array_column($label_list[ 'data' ], 'label_name', 'label_id');
  224. }
  225. $list = $result[ 'data' ][ 'list' ];
  226. if (!empty($list)) {
  227. if ($is_exit_fenxiao == 1) {
  228. $fenxiao_model = new Fenxiao();
  229. }
  230. foreach ($list as $k => $v) {
  231. if ($is_exit_fenxiao == 1) {
  232. if ($v[ 'is_fenxiao' ] == 1) {
  233. $parent_fenxiao_name = $fenxiao_model->getParentFenxiaoName($v[ 'fenxiao_id' ], 2);
  234. } else {
  235. $parent_fenxiao_name = $fenxiao_model->getParentFenxiaoName($v[ 'fenxiao_id' ], 1);
  236. }
  237. $list[ $k ][ 'parent_fenxiao_name' ] = $parent_fenxiao_name;
  238. }
  239. $list[ $k ][ 'member_label_name' ] = '';
  240. $member_label_name = '';
  241. if (!empty($v[ 'member_label' ]) && !empty($label_list[ 'data' ])) {
  242. $member_labels = explode(',', $v[ 'member_label' ]);
  243. foreach ($member_labels as $kk => $vv) {
  244. if (isset($format_label_list[ $vv ])) {
  245. $member_label_name .= ',' . $format_label_list[ $vv ];
  246. }
  247. }
  248. $member_label_name = ltrim($member_label_name, ',');
  249. }
  250. $list[ $k ][ 'member_label_name' ] = $member_label_name;
  251. }
  252. }
  253. $result[ 'data' ][ 'list' ] = $list;
  254. return $result;
  255. } else {
  256. //会员等级
  257. $member_level_model = new MemberLevelModel();
  258. $member_level_list = $member_level_model->getMemberLevelList([ [ 'site_id', '=', $this->site_id ] ], 'level_id, level_name, level_type,status', 'growth asc');
  259. $this->assign('member_level_list', $member_level_list[ 'data' ]);
  260. //会员标签
  261. $member_label_model = new MemberLabelModel();
  262. $member_label_list = $member_label_model->getMemberLabelList([ [ 'site_id', '=', $this->site_id ] ], 'label_id, label_name', 'sort asc');
  263. $this->assign('member_label_list', $member_label_list[ 'data' ]);
  264. /*奖励规则*/
  265. //积分
  266. $point = event('MemberAccountRule', [ 'account' => 'point', 'site_id' => $this->site_id ]);
  267. $this->assign('point', $point);
  268. //余额
  269. $balance = event('MemberAccountRule', [ 'account' => 'balance', 'site_id' => $this->site_id ]);
  270. $this->assign('balance', $balance);
  271. //成长值
  272. $growth = event('MemberAccountRule', [ 'account' => 'growth', 'site_id' => $this->site_id ]);
  273. $this->assign('growth', $growth);
  274. $this->assign('is_exit_fenxiao', $is_exit_fenxiao);
  275. //会员群体
  276. $member_cluster_list = $member_cluster_model->getMemberClusterList([ [ 'site_id', '=', $this->site_id ] ], 'cluster_id, cluster_name', 'create_time desc');
  277. $this->assign('member_cluster_list', $member_cluster_list[ 'data' ]);
  278. $this->assign('cluster_id', $cluster_id);
  279. //订单来源 (支持端口)
  280. $order_from = Config::get("app_type");
  281. $this->assign('order_from_list', $order_from);
  282. $this->assign('supermember_is_exit', addon_is_exit('supermember', $this->site_id));
  283. return $this->fetch('member/member_list');
  284. }
  285. }
  286. /**
  287. * 会员添加
  288. */
  289. public function addMember()
  290. {
  291. if (request()->isAjax()) {
  292. $data = [
  293. 'site_id' => $this->site_id,
  294. 'username' => input('username', ''),
  295. 'mobile' => input('mobile', ''),
  296. 'email' => input('email', ''),
  297. 'password' => data_md5(input('password', '')),
  298. 'status' => input('status', 1),
  299. 'headimg' => input('headimg', ''),
  300. 'member_level' => input('member_level', ''),
  301. 'member_level_name' => input('member_level_name', ''),
  302. 'nickname' => input('nickname', ''),
  303. 'sex' => input('sex', 0),
  304. 'birthday' => input('birthday', '') ? strtotime(input('birthday', '')) : 0,
  305. 'realname' => input('realname', ''),
  306. 'reg_time' => time(),
  307. ];
  308. $member_model = new MemberModel();
  309. $this->addLog("添加会员" . $data[ 'username' ] . $data[ 'mobile' ]);
  310. return $member_model->addMember($data);
  311. } else {
  312. //会员等级
  313. $member_level_model = new MemberLevelModel();
  314. $member_level_list = $member_level_model->getMemberLevelList([ [ 'site_id', '=', $this->site_id ], [ 'level_type', '=', 0 ] ], 'level_id, level_name', 'growth asc');
  315. $this->assign('member_level_list', $member_level_list[ 'data' ]);
  316. $this->assign('type', input('type', 'member'));
  317. return $this->fetch('member/add_member');
  318. }
  319. }
  320. /**
  321. * 会员编辑
  322. */
  323. public function editMember()
  324. {
  325. if (request()->isAjax()) {
  326. $input = input();
  327. $data = [];
  328. if (isset($input[ 'nickname' ])) $data[ 'nickname' ] = $input[ 'nickname' ];
  329. if (isset($input[ 'realname' ])) $data[ 'realname' ] = $input[ 'realname' ];
  330. if (isset($input[ 'sex' ])) $data[ 'sex' ] = $input[ 'sex' ];
  331. if (isset($input[ 'birthday' ])) $data[ 'birthday' ] = $input[ 'birthday' ] ? strtotime($input[ 'birthday' ]) : 0;
  332. if (isset($input[ 'mobile' ])) $data[ 'mobile' ] = $input[ 'mobile' ];
  333. if (isset($input[ 'province_id' ])) $data[ 'province_id' ] = $input[ 'province_id' ];
  334. if (isset($input[ 'city_id' ])) $data[ 'city_id' ] = $input[ 'city_id' ];
  335. if (isset($input[ 'district_id' ])) $data[ 'district_id' ] = $input[ 'district_id' ];
  336. if (isset($input[ 'address' ])) $data[ 'address' ] = $input[ 'address' ];
  337. if (isset($input[ 'full_address' ])) $data[ 'full_address' ] = $input[ 'full_address' ];
  338. $member_id = input('member_id', 0);
  339. $member_model = new MemberModel();
  340. $this->addLog("编辑会员:id" . $member_id, $data);
  341. return $member_model->editMember($data, [ [ 'member_id', '=', $member_id ], [ 'site_id', '=', $this->site_id ] ]);
  342. } else {
  343. //会员信息
  344. $member_id = input('member_id', 0);
  345. $member_model = new MemberModel();
  346. $member_info = $member_model->getMemberInfo([ [ 'site_id', '=', $this->site_id ], [ 'member_id', '=', $member_id ] ]);
  347. if (empty($member_info[ 'data' ])) $this->error('未获取到会员数据', addon_url('shop/member/memberlist'));
  348. $this->assign('member_info', $member_info);
  349. //会员等级
  350. $member_level_model = new MemberLevelModel();
  351. $member_level_list = $member_level_model->getMemberLevelList([ [ 'site_id', '=', $this->site_id ] ], 'level_id,level_name,level_type,is_free_shipping,consume_discount,point_feedback,charge_rule', 'level_type asc,growth asc');
  352. $this->assign('member_level_list', $member_level_list[ 'data' ]);
  353. //账户类型和来源类型
  354. $member_account_model = new MemberAccountModel();
  355. $account_type_arr = $member_account_model->getAccountType();
  356. $this->assign('account_type_arr', $account_type_arr);
  357. $supermember_is_exit = addon_is_exit('supermember', $this->site_id);
  358. $this->assign('supermember_is_exit', $supermember_is_exit);
  359. $this->assign('level_time', $member_level_model->level_time);
  360. return $this->fetch('member/edit_member');
  361. }
  362. }
  363. /**
  364. * 会员删除
  365. */
  366. public function deleteMember()
  367. {
  368. $member_ids = input('member_ids', '');
  369. $member_model = new MemberModel();
  370. $this->addLog("删除会员:id" . $member_ids);
  371. return $member_model->deleteMember([ [ 'member_id', 'in', $member_ids ], [ 'site_id', '=', $this->site_id ] ]);
  372. }
  373. /**
  374. * 修改会员标签
  375. */
  376. public function modifyLabel()
  377. {
  378. $member_ids = input('member_ids', '');
  379. $label_ids = input('label_ids', '');
  380. $member_model = new MemberModel();
  381. return $member_model->modifyMemberLabel($label_ids, [ [ 'member_id', 'in', $member_ids ] ]);
  382. }
  383. /**
  384. * 修改会员状态
  385. */
  386. public function modifyStatus()
  387. {
  388. $member_ids = input('member_ids', '');
  389. $status = input('status', 0);
  390. $member_model = new MemberModel();
  391. return $member_model->modifyMemberStatus($status, [ [ 'member_id', 'in', $member_ids ], [ 'site_id', '=', $this->site_id ] ]);
  392. }
  393. /**
  394. * 修改会员密码
  395. */
  396. public function modifyPassword()
  397. {
  398. $member_ids = input('member_ids', '');
  399. $password = input('password', '123456');
  400. $member_model = new MemberModel();
  401. return $member_model->resetMemberPassword($password, [ [ 'member_id', 'in', $member_ids ] ]);
  402. }
  403. /**
  404. * 账户详情
  405. */
  406. public function accountDetail()
  407. {
  408. $account_type = input('account_type', '');
  409. if (request()->isAjax()) {
  410. $page = input('page', 1);
  411. $page_size = input('page_size', PAGE_LIST_ROWS);
  412. $from_type = input('from_type', '');
  413. $start_date = input('start_date', '');
  414. $end_date = input('end_date', '');
  415. $member_id = input('member_id', 0);
  416. $condition[] = [ 'site_id', '=', $this->site_id ];
  417. $condition[] = [ 'member_id', '=', $member_id ];
  418. //账户类型
  419. if ($account_type != '') {
  420. $condition[] = [ 'account_type', 'in', $account_type ];
  421. }
  422. //来源类型
  423. if ($from_type != '') {
  424. $condition[] = [ 'from_type', '=', $from_type ];
  425. }
  426. //发生时间
  427. if ($start_date != '' && $end_date != '') {
  428. $condition[] = [ 'create_time', 'between', [ strtotime($start_date), strtotime($end_date) ] ];
  429. } else if ($start_date != '' && $end_date == '') {
  430. $condition[] = [ 'create_time', '>=', strtotime($start_date) ];
  431. } else if ($start_date == '' && $end_date != '') {
  432. $condition[] = [ 'create_time', '<=', strtotime($end_date) ];
  433. }
  434. $member_account_model = new MemberAccountModel();
  435. $res = $member_account_model->getMemberAccountPageList($condition, $page, $page_size);
  436. $account_type_arr = $member_account_model->getAccountType();
  437. foreach ($res[ 'data' ][ 'list' ] as $key => $val) {
  438. $res[ 'data' ][ 'list' ][ $key ][ 'account_type_name' ] = $account_type_arr[ $val[ 'account_type' ] ];
  439. }
  440. return $res;
  441. } else {
  442. $member_id = input('member_id', 0);
  443. //会员信息
  444. $member_model = new MemberModel();
  445. $member_info = $member_model->getMemberDetail($member_id, $this->site_id);
  446. if (empty($member_info[ 'data' ])) $this->error('未获取到会员数据', addon_url('shop/member/memberlist'));
  447. $this->assign('member_info', $member_info[ 'data' ]);
  448. //账户类型和来源类型
  449. $member_account_model = new MemberAccountModel();
  450. $account_type_arr = $member_account_model->getAccountType();
  451. $from_type_arr = $member_account_model->getFromType();
  452. $this->assign('account_type_arr', $account_type_arr);
  453. $this->assign('from_type_arr', $from_type_arr[$account_type] ?? []);
  454. $this->assign('account_type', $account_type);
  455. $this->assign('member_id', $member_id);
  456. return $this->fetch('member/account_detail');
  457. }
  458. }
  459. /**
  460. * 余额调整(不可提现)
  461. */
  462. public function adjustBalance()
  463. {
  464. $member_id = input('member_id', 0);
  465. $adjust_num = input('adjust_num', 0);
  466. $remark = input('remark', '商家调整');
  467. $this->addLog("会员余额调整id:" . $member_id . "金额" . $adjust_num);
  468. $member_account_model = new MemberAccountModel();
  469. return $member_account_model->addMemberAccount($this->site_id, $member_id, 'balance', $adjust_num, 'adjust', 0, $remark ? $remark : '商家调整');
  470. }
  471. /**
  472. * 积分调整
  473. */
  474. public function adjustPoint()
  475. {
  476. $member_id = input('member_id', 0);
  477. $adjust_num = input('adjust_num', 0);
  478. $remark = input('remark', '商家调整');
  479. $this->addLog("会员积分调整id:" . $member_id . "数量" . $adjust_num);
  480. $member_account_model = new MemberAccountModel();
  481. return $member_account_model->addMemberAccount($this->site_id, $member_id, 'point', $adjust_num, 'adjust', 0, $remark ? $remark : '商家调整');
  482. }
  483. /**
  484. * 成长值调整
  485. */
  486. public function adjustGrowth()
  487. {
  488. $member_id = input('member_id', 0);
  489. $adjust_num = input('adjust_num', 0);
  490. $remark = input('remark', '商家调整');
  491. $this->addLog("会员成长值调整id:" . $member_id . "数量" . $adjust_num);
  492. $member_account_model = new MemberAccountModel();
  493. return $member_account_model->addMemberAccount($this->site_id, $member_id, 'growth', $adjust_num, 'adjust', 0, $remark ? $remark : '商家调整');
  494. }
  495. /**
  496. * 注册协议
  497. */
  498. public function regAgreement()
  499. {
  500. if (request()->isAjax()) {
  501. //设置注册协议
  502. $title = input('title', '');
  503. $content = input('content', '');
  504. $config_model = new ConfigModel();
  505. return $config_model->setRegisterDocument($title, $content, $this->site_id, 'shop');
  506. } else {
  507. $this->forthMenu();
  508. //获取注册协议
  509. $config_model = new ConfigModel();
  510. $document_info = $config_model->getRegisterDocument($this->site_id, 'shop');
  511. $this->assign('document_info', $document_info);
  512. return $this->fetch('member/reg_agreement');
  513. }
  514. }
  515. /**
  516. * 注册设置
  517. */
  518. public function regConfig()
  519. {
  520. $config_model = new ConfigModel();
  521. if (request()->isAjax()) {
  522. //设置注册设置
  523. $data = array (
  524. 'login' => input('login', ''),
  525. 'register' => input('register', ''),
  526. 'pwd_len' => input('pwd_len', 6),
  527. 'pwd_complexity' => input('pwd_complexity', 'number,letter,upper_case,symbol'),
  528. 'third_party' => input('third_party', 0),
  529. 'bind_mobile' => input('bind_mobile', 0),
  530. );
  531. return $config_model->setRegisterConfig($data, $this->site_id, 'shop');
  532. } else {
  533. $this->forthMenu();
  534. //获取注册设置
  535. $config_info = $config_model->getRegisterConfig($this->site_id, 'shop');
  536. $value = $config_info[ 'data' ][ 'value' ];
  537. if (!empty($value)) {
  538. $value[ 'pwd_complexity_arr' ] = explode(',', $value[ 'pwd_complexity' ]);
  539. $value[ 'login' ] = explode(',', $value[ 'login' ]);
  540. $value[ 'register' ] = explode(',', $value[ 'register' ]);
  541. }
  542. $this->assign('value', $value);
  543. return $this->fetch('member/reg_config');
  544. }
  545. }
  546. /**
  547. * 注销协议
  548. */
  549. public function cancelAgreement()
  550. {
  551. if (request()->isAjax()) {
  552. //设置注销协议
  553. $title = input('title', '');
  554. $content = input('content', '');
  555. $config_model = new ConfigModel();
  556. return $config_model->setCancelDocument($title, $content, $this->site_id, 'shop');
  557. } else {
  558. //获取注销协议
  559. $config_model = new ConfigModel();
  560. $document_info = $config_model->getCancelDocument($this->site_id, 'shop');
  561. $this->assign('document_info', $document_info);
  562. return $this->fetch('member/cancel_agreement');
  563. }
  564. }
  565. /**
  566. * 注销设置
  567. */
  568. public function cancelConfig()
  569. {
  570. $config_model = new ConfigModel();
  571. if (request()->isAjax()) {
  572. //设置注册设置
  573. $data = array (
  574. 'is_enable' => input('is_enable', 0),
  575. 'is_audit' => input('is_audit', 1),
  576. );
  577. return $config_model->setCancelConfig($data, $this->site_id, 'shop');
  578. } else {
  579. //获取注册设置
  580. $config_info = $config_model->getCancelConfig($this->site_id, 'shop');
  581. $value = $config_info[ 'data' ][ 'value' ];
  582. $this->assign('value', $value);
  583. return $this->fetch('member/cancel_config');
  584. }
  585. }
  586. /**
  587. * 搜索会员
  588. * 不是菜单 不入权限
  589. */
  590. public function searchMember()
  591. {
  592. $search_text = input('search_text', '');
  593. $member_model = new MemberModel();
  594. $member_info = $member_model->getMemberInfo([ [ 'username|mobile', '=', $search_text ], [ 'site_id', '=', $this->site_id ] ]);
  595. return $member_info;
  596. }
  597. /**
  598. * 导出会员信息
  599. */
  600. public function exportMember()
  601. {
  602. //获取会员信息
  603. $search_text = input('search_text', '');
  604. $search_text_type = input('search_text_type', 'username');//可以传username mobile email
  605. $level_id = input('level_id', 0);
  606. $label_id = input('label_id', 0);
  607. $reg_start_date = input('reg_start_date', '');
  608. $reg_end_date = input('reg_end_date', '');
  609. $status = input('status', '');
  610. $cluster_id = input('cluster_id', '');//获取会员群体
  611. $last_login_time_start = input('last_login_time_start', '');//上次登录时间
  612. $last_login_time_end = input('last_login_time_end', '');
  613. $start_order_complete_num = input('start_order_complete_num', '');//成交次数
  614. $end_order_complete_num = input('end_order_complete_num', '');
  615. $start_order_complete_money = input('start_order_complete_money', '');//消费金额
  616. $end_order_complete_money = input('end_order_complete_money', '');
  617. $start_point = input('start_point', '');//积分
  618. $end_point = input('end_point', '');
  619. $start_balance = input('start_balance', '');//余额
  620. $end_balance = input('end_balance', '');
  621. $start_growth = input('start_growth', '');//成长值
  622. $end_growth = input('end_growth', '');
  623. $login_type = input('login_type', '');//来源渠道
  624. $condition[] = [ 'site_id', '=', $this->site_id ];
  625. //下拉选择
  626. $condition[] = [ $search_text_type, 'like', "%" . $search_text . "%" ];
  627. //会员等级
  628. if ($level_id != 0) {
  629. $condition[] = [ 'member_level', '=', $level_id ];
  630. }
  631. //会员标签
  632. if ($label_id != 0) {
  633. //raw方法变为public类型 需要实例化以后调用
  634. $condition[] = [ "", 'exp', Db::raw("FIND_IN_SET({$label_id}, member_label)") ];
  635. }
  636. //注册时间
  637. if ($reg_start_date != '' && $reg_end_date != '') {
  638. $condition[] = [ 'reg_time', 'between', [ strtotime($reg_start_date), strtotime($reg_end_date) ] ];
  639. } else if ($reg_start_date != '' && $reg_end_date == '') {
  640. $condition[] = [ 'reg_time', '>=', strtotime($reg_start_date) ];
  641. } else if ($reg_start_date == '' && $reg_end_date != '') {
  642. $condition[] = [ 'reg_time', '<=', strtotime($reg_end_date) ];
  643. }
  644. //会员状态
  645. if ($status != '') {
  646. $condition[] = [ 'status', '=', $status ];
  647. }
  648. //会员群体
  649. $member_cluster_model = new MemberClusterModel();
  650. if ($cluster_id != '') {
  651. //获取会员群体的member_id值
  652. $member_cluster_info = $member_cluster_model->getMemberClusterInfo([ "cluster_id" => $cluster_id ], 'member_ids');
  653. if (!empty($member_cluster_info[ 'data' ][ 'member_ids' ])) {
  654. $condition[] = [ 'member_id', 'in', $member_cluster_info[ 'data' ][ 'member_ids' ] ];
  655. }
  656. }
  657. //上次访问时间
  658. if ($last_login_time_start != '' && $last_login_time_end != '') {
  659. $condition[] = [ 'last_login_time', 'between', [ strtotime($last_login_time_start), strtotime($last_login_time_end) ] ];
  660. } else if ($last_login_time_start != '' && $last_login_time_end == '') {
  661. $condition[] = [ 'last_login_time', '>=', strtotime($last_login_time_start) ];
  662. } else if ($last_login_time_start == '' && $last_login_time_end != '') {
  663. $condition[] = [ 'last_login_time', '<=', strtotime($last_login_time_end) ];
  664. }
  665. //成交次数
  666. if ($start_order_complete_num != '' && $end_order_complete_num != '') {
  667. $condition[] = [ 'order_complete_num', 'between', [ $start_order_complete_num, $end_order_complete_num ] ];
  668. } else if ($start_order_complete_num != '' && $end_order_complete_num == '') {
  669. $condition[] = [ 'order_complete_num', '>=', $start_order_complete_num ];
  670. } else if ($start_order_complete_num == '' && $end_order_complete_num != '') {
  671. $condition[] = [ 'order_complete_num', '<=', $end_order_complete_num ];
  672. }
  673. //消费金额
  674. if ($start_order_complete_money != '' && $end_order_complete_money != '') {
  675. $condition[] = [ 'order_complete_num', 'between', [ $start_order_complete_money, $end_order_complete_money ] ];
  676. } else if ($start_order_complete_money != '' && $end_order_complete_money == '') {
  677. $condition[] = [ 'order_complete_num', '>=', $start_order_complete_money ];
  678. } else if ($start_order_complete_money == '' && $end_order_complete_money != '') {
  679. $condition[] = [ 'order_complete_num', '<=', $end_order_complete_money ];
  680. }
  681. //积分
  682. if ($start_point != '' && $end_point != '') {
  683. $condition[] = [ 'point', 'between', [ $start_point, $end_point ] ];
  684. } else if ($start_point != '' && $end_point == '') {
  685. $condition[] = [ 'point', '>=', $start_point ];
  686. } else if ($start_point == '' && $end_point != '') {
  687. $condition[] = [ 'point', '<=', $end_point ];
  688. }
  689. //余额
  690. if ($start_balance != '' && $end_balance != '') {
  691. $condition[] = [ 'balance', 'between', [ $start_balance, $end_balance ] ];
  692. } else if ($start_balance != '' && $end_balance == '') {
  693. $condition[] = [ 'balance', '>=', $start_balance ];
  694. } else if ($start_balance == '' && $end_balance != '') {
  695. $condition[] = [ 'balance', '<=', $end_balance ];
  696. }
  697. //成长值
  698. if ($start_growth != '' && $end_growth != '') {
  699. $condition[] = [ 'growth', 'between', [ $start_growth, $end_growth ] ];
  700. } else if ($start_growth != '' && $end_growth == '') {
  701. $condition[] = [ 'growth', '>=', $start_growth ];
  702. } else if ($start_growth == '' && $end_growth != '') {
  703. $condition[] = [ 'growth', '<=', $end_growth ];
  704. }
  705. //来源渠道
  706. if ($login_type != '') {
  707. $condition[] = [ 'login_type', '=', $login_type ];
  708. }
  709. $order = 'reg_time desc';
  710. $field = 'username,nickname,realname,mobile,sex,birthday,email,member_level_name,member_label_name,
  711. qq,location,balance,balance_money,point,growth,reg_time,last_login_ip,last_login_time,is_fenxiao,fenxiao_id';
  712. $member_model = new MemberModel();
  713. $list = $member_model->getMemberList($condition, $field, $order);
  714. $is_exit_fenxiao = addon_is_exit('fenxiao');
  715. if ($is_exit_fenxiao == 1) {
  716. if (!empty($list[ 'data' ])) {
  717. $fenxiao_model = new Fenxiao();
  718. foreach ($list[ 'data' ] as $k => $v) {
  719. if ($v[ 'is_fenxiao' ] == 1) {
  720. $parent_fenxiao_name = $fenxiao_model->getParentFenxiaoName($v[ 'fenxiao_id' ], 2);
  721. } else {
  722. $parent_fenxiao_name = $fenxiao_model->getParentFenxiaoName($v[ 'fenxiao_id' ], 1);
  723. }
  724. $list[ 'data' ][ $k ][ 'parent_fenxiao_name' ] = $parent_fenxiao_name;
  725. }
  726. }
  727. }
  728. // 实例化excel
  729. $phpExcel = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  730. $phpExcel->getProperties()->setTitle("会员信息");
  731. $phpExcel->getProperties()->setSubject("会员信息");
  732. // 对单元格设置居中效果
  733. $phpExcel->getActiveSheet()->getStyle('A')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  734. $phpExcel->getActiveSheet()->getStyle('B')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  735. $phpExcel->getActiveSheet()->getStyle('C')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  736. $phpExcel->getActiveSheet()->getStyle('D')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  737. $phpExcel->getActiveSheet()->getStyle('E')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  738. $phpExcel->getActiveSheet()->getStyle('F')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  739. $phpExcel->getActiveSheet()->getStyle('G')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  740. $phpExcel->getActiveSheet()->getStyle('H')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  741. $phpExcel->getActiveSheet()->getStyle('I')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  742. $phpExcel->getActiveSheet()->getStyle('J')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  743. $phpExcel->getActiveSheet()->getStyle('K')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  744. $phpExcel->getActiveSheet()->getStyle('L')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  745. $phpExcel->getActiveSheet()->getStyle('M')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  746. $phpExcel->getActiveSheet()->getStyle('N')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  747. $phpExcel->getActiveSheet()->getStyle('O')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  748. $phpExcel->getActiveSheet()->getStyle('P')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  749. $phpExcel->getActiveSheet()->getStyle('Q')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  750. //单独添加列名称
  751. $phpExcel->setActiveSheetIndex(0);
  752. $phpExcel->getActiveSheet()->setCellValue('A1', '会员账号');//可以指定位置
  753. $phpExcel->getActiveSheet()->setCellValue('B1', '会员昵称');
  754. $phpExcel->getActiveSheet()->setCellValue('C1', '真实姓名');
  755. $phpExcel->getActiveSheet()->setCellValue('D1', '手机号');
  756. $phpExcel->getActiveSheet()->setCellValue('E1', '性别');
  757. $phpExcel->getActiveSheet()->setCellValue('F1', '生日');
  758. $phpExcel->getActiveSheet()->setCellValue('G1', '会员等级');
  759. $phpExcel->getActiveSheet()->setCellValue('H1', '会员标签');
  760. $phpExcel->getActiveSheet()->setCellValue('I1', 'qq');
  761. $phpExcel->getActiveSheet()->setCellValue('J1', '地址');
  762. $phpExcel->getActiveSheet()->setCellValue('K1', '余额');
  763. $phpExcel->getActiveSheet()->setCellValue('L1', '积分');
  764. $phpExcel->getActiveSheet()->setCellValue('M1', '成长值');
  765. $phpExcel->getActiveSheet()->setCellValue('N1', '上次登录时间');
  766. $phpExcel->getActiveSheet()->setCellValue('O1', '上次登录ip');
  767. $phpExcel->getActiveSheet()->setCellValue('P1', '注册时间');
  768. $phpExcel->getActiveSheet()->setCellValue('Q1', '上级分销商');
  769. //循环添加数据(根据自己的逻辑)
  770. $sex = [ '保密', '男', '女' ];
  771. foreach ($list[ 'data' ] as $k => $v) {
  772. $i = $k + 2;
  773. $phpExcel->getActiveSheet()->setCellValue('A' . $i, $v[ 'username' ] . ' ');
  774. $phpExcel->getActiveSheet()->setCellValue('B' . $i, $v[ 'nickname' ] . ' ');
  775. $phpExcel->getActiveSheet()->setCellValue('C' . $i, $v[ 'realname' ] . ' ');
  776. $phpExcel->getActiveSheet()->setCellValue('D' . $i, $v[ 'mobile' ] . ' ');
  777. $phpExcel->getActiveSheet()->setCellValue('E' . $i, $sex[ $v[ 'sex' ] ]);
  778. $phpExcel->getActiveSheet()->setCellValue('F' . $i, date('Y-m-d', $v[ 'birthday' ]));
  779. $phpExcel->getActiveSheet()->setCellValue('G' . $i, $v[ 'member_level_name' ]);
  780. $phpExcel->getActiveSheet()->setCellValue('H' . $i, $v[ 'member_label_name' ]);
  781. $phpExcel->getActiveSheet()->setCellValue('I' . $i, $v[ 'qq' ]);
  782. $phpExcel->getActiveSheet()->setCellValue('J' . $i, $v[ 'location' ]);
  783. $phpExcel->getActiveSheet()->setCellValue('K' . $i, $v[ 'balance' ] + $v[ 'balance_money' ]);
  784. $phpExcel->getActiveSheet()->setCellValue('L' . $i, $v[ 'point' ]);
  785. $phpExcel->getActiveSheet()->setCellValue('M' . $i, $v[ 'growth' ]);
  786. $phpExcel->getActiveSheet()->setCellValue('N' . $i, date('Y-m-d H:i:s', $v[ 'last_login_time' ]));
  787. $phpExcel->getActiveSheet()->setCellValue('O' . $i, $v[ 'last_login_ip' ]);
  788. $phpExcel->getActiveSheet()->setCellValue('P' . $i, date('Y-m-d H:i:s', $v[ 'reg_time' ]));
  789. $phpExcel->getActiveSheet()->setCellValue('Q' . $i, !empty($v[ 'parent_fenxiao_name' ]) ? $v[ 'parent_fenxiao_name' ] . ' ' : '');
  790. }
  791. // 重命名工作sheet
  792. $phpExcel->getActiveSheet()->setTitle('会员信息');
  793. // 设置第一个sheet为工作的sheet
  794. $phpExcel->setActiveSheetIndex(0);
  795. // 保存Excel 2007格式文件,保存路径为当前路径,名字为export.xlsx
  796. $objWriter = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($phpExcel, 'Xlsx');
  797. $file = date('Y年m月d日-会员信息表', time()) . '.xlsx';
  798. $objWriter->save($file);
  799. header("Content-type:application/octet-stream");
  800. $filename = basename($file);
  801. header("Content-Disposition:attachment;filename = " . $filename);
  802. header("Accept-ranges:bytes");
  803. header("Accept-length:" . filesize($file));
  804. readfile($file);
  805. unlink($file);
  806. exit;
  807. }
  808. /**
  809. * 订单管理
  810. */
  811. public function order()
  812. {
  813. $member_id = input("member_id", 0);//会员id
  814. $this->assign('member_id', $member_id);
  815. //会员详情四级菜单
  816. $this->forthMenu([ 'member_id' => $member_id ]);
  817. return $this->fetch('member/order');
  818. }
  819. /**
  820. * 会员地址
  821. */
  822. public function addressDetail()
  823. {
  824. if (request()->isAjax()) {
  825. $page = input('page', 1);
  826. $page_size = input('page_size', PAGE_LIST_ROWS);
  827. $member_id = input('member_id', 0);
  828. $condition[] = [ 'site_id', '=', $this->site_id ];
  829. $condition[] = [ 'member_id', '=', $member_id ];
  830. //会员地址
  831. $member_address_model = new MemberAddressModel();
  832. $res = $member_address_model->getMemberAddressPageList($condition, $page, $page_size);
  833. return $res;
  834. } else {
  835. $member_id = input('member_id', 0);
  836. $this->assign('member_id', $member_id);
  837. //会员详情四级菜单
  838. $this->forthMenu([ 'member_id' => $member_id ]);
  839. return $this->fetch('member/address_detail');
  840. }
  841. }
  842. /**
  843. * 会员领取优惠卷
  844. */
  845. public function memberCoupon()
  846. {
  847. $coupon_model = new CouponModel();
  848. if (request()->isAjax()) {
  849. $page = input('page', 1);
  850. $page_size = input('page_size', PAGE_LIST_ROWS);
  851. $member_id = input('member_id', 0);
  852. $condition[] = [ 'site_id', '=', $this->site_id ];
  853. $condition[] = [ 'member_id', '=', $member_id ];
  854. //查询会员领取的优惠券
  855. $res = $coupon_model->getCouponPageList($condition, $page, $page_size);
  856. return $res;
  857. } else {
  858. $member_id = input('member_id', 0);
  859. $this->assign('member_id', $member_id);
  860. //会员详情四级菜单
  861. $this->forthMenu([ 'member_id' => $member_id ]);
  862. $this->assign('get_type', $coupon_model->getCouponGetType());
  863. return $this->fetch('member/member_coupon');
  864. }
  865. }
  866. /**
  867. * 根据账户类型获取来源类型
  868. * @return array
  869. */
  870. public function getFromType()
  871. {
  872. $type = input('type', '');
  873. $model = new MemberAccountModel();
  874. $res = $model->getFromType();
  875. return $res[ $type ];
  876. }
  877. /**
  878. * 会员导入列表页
  879. */
  880. public function memberImport()
  881. {
  882. if (request()->isAjax()) {
  883. $member_model = new MemberModel();
  884. $page = input('page', 1);
  885. $page_size = input('page_size', PAGE_LIST_ROWS);
  886. $condition = [];
  887. $result = $member_model->getMemberImportRecordList($condition, $page, $page_size);
  888. return $result;
  889. }
  890. return $this->fetch('member/memberImport');
  891. }
  892. /**
  893. * 下载会员导入模板
  894. */
  895. public function downloadMemberFile()
  896. {
  897. // 实例化excel
  898. $phpExcel = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  899. $phpExcel->getProperties()->setTitle("会员导入模板");
  900. $phpExcel->getProperties()->setSubject("会员导入模板");
  901. // 对单元格设置居中效果
  902. $phpExcel->getActiveSheet()->getStyle('A')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  903. $phpExcel->getActiveSheet()->getStyle('B')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  904. $phpExcel->getActiveSheet()->getStyle('C')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  905. $phpExcel->getActiveSheet()->getStyle('D')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  906. $phpExcel->getActiveSheet()->getStyle('E')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  907. $phpExcel->getActiveSheet()->getStyle('F')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  908. $phpExcel->getActiveSheet()->getStyle('G')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  909. $phpExcel->getActiveSheet()->getStyle('H')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  910. $phpExcel->getActiveSheet()->getStyle('I')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  911. $phpExcel->getActiveSheet()->getStyle('J')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  912. $phpExcel->getActiveSheet()->getStyle('K')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  913. $phpExcel->getActiveSheet()->getStyle('L')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
  914. //单独添加列名称
  915. $phpExcel->setActiveSheetIndex(0);
  916. $phpExcel->getActiveSheet()->setCellValue('A1', '用户名');//可以指定位置
  917. $phpExcel->getActiveSheet()->setCellValue('B1', '手机号');
  918. $phpExcel->getActiveSheet()->setCellValue('C1', '昵称');
  919. $phpExcel->getActiveSheet()->setCellValue('D1', '密码(明文)');
  920. $phpExcel->getActiveSheet()->setCellValue('E1', '微信公众号openid');
  921. $phpExcel->getActiveSheet()->setCellValue('F1', '微信小程序openid');
  922. $phpExcel->getActiveSheet()->setCellValue('G1', '真实姓名');
  923. $phpExcel->getActiveSheet()->setCellValue('H1', '积分');
  924. $phpExcel->getActiveSheet()->setCellValue('I1', '成长值');
  925. $phpExcel->getActiveSheet()->setCellValue('J1', '余额(可提现)');
  926. $phpExcel->getActiveSheet()->setCellValue('K1', '余额(不可提现)');
  927. $phpExcel->getActiveSheet()->setCellValue('L1', '会员等级(名称)');
  928. // 设置第一个sheet为工作的sheet
  929. $phpExcel->setActiveSheetIndex(0);
  930. // 保存Excel 2007格式文件,保存路径为当前路径,名字为export.xlsx
  931. $objWriter = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($phpExcel, 'Xlsx');
  932. $file = date('Y年m月d日-会员导入模板', time()) . '.xlsx';
  933. $objWriter->save($file);
  934. header("Content-type:application/octet-stream");
  935. $filename = basename($file);
  936. header("Content-Disposition:attachment;filename = " . $filename);
  937. header("Accept-ranges:bytes");
  938. header("Accept-length:" . filesize($file));
  939. readfile($file);
  940. unlink($file);
  941. exit;
  942. }
  943. /**
  944. * 上传文件
  945. */
  946. public function file()
  947. {
  948. $upload_model = new UploadModel($this->site_id);
  949. $param = array (
  950. "name" => "file",
  951. 'extend_type' => [ 'xlsx' ]
  952. );
  953. $result = $upload_model->setPath("common/member/member_import/" . date("Ymd") . '/')->file($param);
  954. return $result;
  955. }
  956. /**
  957. * 导入
  958. */
  959. public function import()
  960. {
  961. if (request()->isAjax()) {
  962. $filename = input('filename', '');
  963. $path = input('path', '');
  964. $index = input('index', '');
  965. $success_num = input('success_num', 0);
  966. $error_num = input('error_num', 0);
  967. $record = input('record', 0);
  968. $member_model = new MemberModel();
  969. $params = [
  970. 'filename' => $filename,
  971. 'path' => $path,
  972. 'index' => $index,
  973. 'success_num' => $success_num,
  974. "error_num" => $error_num,
  975. "record" => $record
  976. ];
  977. $res = $member_model->importMember($params, $this->site_id);
  978. return $res;
  979. }
  980. }
  981. /**
  982. * 黑名单
  983. * @return mixed
  984. */
  985. public function blacklist()
  986. {
  987. if (request()->isAjax()) {
  988. $page = input('page', 1);
  989. $page_size = input('page_size', PAGE_LIST_ROWS);
  990. $search_text = input('search_text', '');
  991. $search_text_type = input('search_text_type', 'username');//可以传username mobile email
  992. $condition[] = [ 'status', '=', 0 ];
  993. $condition[] = [ 'site_id', '=', $this->site_id ];
  994. //下拉选择
  995. $condition[] = [ $search_text_type, 'like', "%" . $search_text . "%" ];
  996. $order = 'reg_time desc';
  997. $field = '*';
  998. $member_model = new MemberModel();
  999. $result = $member_model->getMemberPageList($condition, $page, $page_size, $order, $field);
  1000. return $result;
  1001. }
  1002. return $this->fetch('member/blacklist');
  1003. }
  1004. /*
  1005. * 会员导入记录
  1006. */
  1007. public function memberimportlist()
  1008. {
  1009. if (request()->isAjax()) {
  1010. $member_model = new MemberModel();
  1011. $id = input("id", 0);
  1012. $page = input('page', 1);
  1013. $page_size = input('page_size', PAGE_LIST_ROWS);
  1014. $condition[ 'record_id' ] = $id;
  1015. $list = $member_model->getMemberImportLogList($condition, $page, $page_size);
  1016. return $list;
  1017. }
  1018. $id = request()->get("id", 0);
  1019. $member_model = new MemberModel();
  1020. $info = $member_model->getMemberImportRecordInfo($id);
  1021. if (empty($info[ 'data' ])) $this->error('未获取到导入数据', addon_url('shop/member/memberimport'));
  1022. $this->assign('info', $info);
  1023. $this->assign('id', $id);
  1024. return $this->fetch('member/import_log');
  1025. }
  1026. /**
  1027. * 变更会员会员卡
  1028. */
  1029. public function changeMemberLevel()
  1030. {
  1031. if (request()->isAjax()) {
  1032. $member_id = input('member_id', 0);
  1033. $level_id = input('level_id', 0);
  1034. $period_unit = input('period_unit', '');
  1035. $expire_time = 0;
  1036. switch ($period_unit) {
  1037. case 'week':
  1038. $expire_time = strtotime('+1 week');
  1039. break;
  1040. case 'month':
  1041. $expire_time = strtotime('+1 month');
  1042. break;
  1043. case 'quarter':
  1044. $expire_time = strtotime('+3 month');
  1045. break;
  1046. case 'year':
  1047. $expire_time = strtotime('+1 year');
  1048. break;
  1049. }
  1050. $member_level = new MemberLevelModel();
  1051. $res = $member_level->addMemberLevelChangeRecord($member_id, $this->site_id, $level_id, $expire_time, 'adjust', $this->user_info[ 'uid' ], 'user', $this->user_info[ 'username' ]);
  1052. return $res;
  1053. }
  1054. }
  1055. /**
  1056. * 获取各渠道会员数量
  1057. * @return array
  1058. */
  1059. public function getRegisterChannelMemberNum()
  1060. {
  1061. if (request()->isAjax()) {
  1062. $app_type = Config::get("app_type");
  1063. $member_model = new MemberModel();
  1064. $data = [];
  1065. foreach ($app_type as $k => $v) {
  1066. array_push($data, [
  1067. 'name' => $v[ 'name' ],
  1068. 'member_num' => $member_model->getMemberCount([ [ 'login_type', '=', $k ], [ 'is_delete', '=', 0 ] ])[ 'data' ]
  1069. ]);
  1070. }
  1071. return success(0, '', $data);
  1072. }
  1073. }
  1074. /**
  1075. * 办理会员
  1076. */
  1077. public function handleMember()
  1078. {
  1079. if (request()->isAjax()) {
  1080. $member_id = input('member_id', 0);
  1081. $level_id = input('level_id', 0);
  1082. $member_code = input('member_code', '');
  1083. $member_model = new MemberModel();
  1084. $res = $member_model->handleMember([
  1085. 'member_id' => $member_id,
  1086. 'level_id' => $level_id,
  1087. 'member_code' => $member_code,
  1088. 'site_id' => $this->site_id
  1089. ]);
  1090. return $res;
  1091. }
  1092. }
  1093. }