DefaultController.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <?php
  2. namespace addons\TeamData\backend\controllers;
  3. use addons\Agent\common\enums\AgentEnum;
  4. use addons\TeamData\common\enums\TeamDataEnum;
  5. use common\enums\AddonsEnum;
  6. use common\enums\DownloadEnum;
  7. use addons\TeamData\common\models\MallUser;
  8. use common\enums\StatusEnum;
  9. use common\enums\UserWalletEnum;
  10. use common\helpers\csv\CsvExportHelper;
  11. use common\models\common\CapitalLog;
  12. use common\models\common\Download;
  13. use common\models\common\MallSetting;
  14. use common\models\mall\MallAddons;
  15. use common\models\order\Order;
  16. use common\models\order\OrderDetail;
  17. use common\models\statistics\UserStatisticsTotal;
  18. use common\models\user\User;
  19. use common\models\user\UserLevel;
  20. use common\models\user\UserPartitionRelationship;
  21. use common\models\user\UserTeamStatistics;
  22. use common\models\user\UserWallet;
  23. use Yii;
  24. use common\controllers\AddonsController;
  25. use Exception;
  26. use function Clue\StreamFilter\fun;
  27. /**
  28. * 默认控制器
  29. *
  30. * Class DefaultController
  31. * @package addons\TeamData\backend\controllers
  32. */
  33. class DefaultController extends BaseController
  34. {
  35. public $enableCsrfValidation = false;
  36. /**
  37. * 首页
  38. *
  39. * @return string
  40. */
  41. public function actionIndex()
  42. {
  43. $retuest = Yii::$app->request;
  44. if ($retuest->isAjax) {
  45. if ($retuest->isGet) {
  46. $get = Yii::$app->request->get();
  47. // 检查提交的参数
  48. $res = Yii::$app->services->validate->validate($get,[
  49. [['id','mobile'], 'integer'],
  50. ]);
  51. if($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  52. $where = $list = $frozen_money_arr = $total_pay_arr = [];
  53. $where[] = ['=', 'mall_id', $this->mall_id];
  54. !empty($get['id']) && $where[] = ['=', 'id', $get['id']];
  55. if (!empty($get['mobile'])) {
  56. $user_id = User::find()->select('id')->where(['mall_id' => $this->mall_id, 'mobile' => $get['mobile'], 'status' => StatusEnum::ENABLED])->scalar();
  57. if (empty($user_id)) return $this->error('手机号码不存在');
  58. $where[] = ['=', 'id', $user_id];
  59. }
  60. $where[] = ['=', 'status', StatusEnum::ENABLED];
  61. $with = ['parent' => function($query){
  62. $query->select('id,nickname,mobile,avatar_url');
  63. }, 'userTeamStatistics' => function($query){
  64. $query->select('user_id,user_team_total')->where(['status' => StatusEnum::ENABLED]);
  65. }, 'userWallet' => function($query){
  66. $query->select('user_id,commission');
  67. }];
  68. $select = "id,nickname,mobile,avatar_url,parent_id";
  69. $order = 'created_at desc';
  70. $params = array('where' => $where, 'order'=>$order, 'with' => $with, 'select' => $select, 'limit' => $get['limit']);
  71. $list = User::listPage($params, false, true);
  72. if ($list['list']) {
  73. $user_ids = array_column($list['list'], 'id');
  74. // 获取用户累计消费金额
  75. $total_pay_arr = $this->getUserStatisticsTotal($user_ids);
  76. $frozen_money_arr = $this->getUserFrozenMoney($user_ids);
  77. }
  78. return $this->success('获取成功', compact('list','total_pay_arr', 'frozen_money_arr'));
  79. }
  80. } else {
  81. return $this->render($this->action->id);
  82. }
  83. }
  84. /**
  85. * 团队数据
  86. *
  87. * @param int $user_id
  88. * @param int $status 1:直推客户-下级 2:间推客户-下级的下级 3:我的团队-全部下级 4:推荐人-全部上级
  89. * @param string $keyword 关键字
  90. * @param int $search_type 1:会员ID 2:会员昵称 3:手机号码
  91. * @param int $page
  92. * @return mixed|array|void
  93. */
  94. public function actionMyCustomer()
  95. {
  96. ini_set('memory_limit', '512M'); // 将内存限制设置为512M
  97. if (!Yii::$app->request->isAjax) {
  98. $user_id = Yii::$app->request->get('user_id');
  99. if (!$user_id) throw new \Exception('用户不存在');
  100. $where[] = ['=', 'u.id', $user_id];
  101. $join = [['LEFT JOIN', User::tableName() . ' as p', 'u.parent_id = p.id']];
  102. $select = ['u.id', 'u.nickname', 'u.mobile', 'u.parent_id','u.avatar_url', 'u.created_at', 'p.nickname p_nickname'];
  103. $params = [
  104. 'where' => $where,
  105. 'alias' => 'u',
  106. 'select' => $select,
  107. 'join' => $join
  108. ];
  109. $model = User::find();
  110. User::paramPack($params, $model);
  111. $user_info = $model->asArray()->one();
  112. if (empty($user_info)) throw new \Exception('用户不存在');
  113. // 团队用户数据统计
  114. $statistics = UserTeamStatistics::find()->select('user_team_total,user_direct_total,user_indirect_total')->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  115. $user_info['team_num'] = $statistics['user_team_total'] ?: 0;
  116. $user_info['first_num'] = $statistics['user_direct_total'] ?: 0;
  117. $user_info['second_num'] = $statistics['user_indirect_total'] ?: 0;
  118. //累计消费
  119. $user_info['pay_money'] = UserStatisticsTotal::find()->where(['user_id' => $user_id])->sum('pay_money');
  120. $sum_field = 'pay_goods_num';
  121. if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_AGENT) > 0){
  122. //读取插件配置
  123. $more_setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_AGENT, 'more');
  124. $compute_type = $more_setting['compute_type'] ?? 1;
  125. $sum_field = $compute_type == 0 ? 'finish_goods_num' : 'pay_goods_num';
  126. }
  127. //团队购买数量
  128. $child_ids = UserPartitionRelationship::getChildIdArr($user_id);
  129. $child_ids[] = $user_id;
  130. $user_info['pay_goods_num'] = UserStatisticsTotal::find()->where(['user_id' => $child_ids])->sum($sum_field) ?? 0;
  131. // CapitalLog::$capitalType = 'commission_frozen';
  132. //累计佣金
  133. // $user_info['commission'] = CapitalLog::find()->where(['user_id' => $user_id, 'change_type' => CapitalLog::CHANGE_TYPE_ADD])->sum('change_num');
  134. //未结算
  135. // $user_info['not_income'] = CapitalLog::find()->where(['user_id' => $user_id, 'change_type' => CapitalLog::CHANGE_TYPE_ADD, 'status' => CapitalLog::STATUS_WAIT_SEND])->sum('change_num');
  136. // 获取用户钱包
  137. $wallet = UserWallet::find()->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  138. $user_info['commission'] = empty($wallet) ? 0 : $wallet['total_commission'] + $wallet['frozen_commission'];// 累计佣金 = 累计可用+待结算
  139. $user_info['not_income'] = $wallet['frozen_commission'] ?: 0;// 冻结佣金
  140. $user_info['created_at'] = date('Y-m-d H:i:s', $user_info['created_at']);
  141. $user_info['pay_money'] = bcadd( $user_info['pay_money'],0,2);
  142. $user_info['commission'] = bcadd( $user_info['commission'],0,2);
  143. $user_info['not_income'] = bcadd( $user_info['not_income'],0,2);
  144. return $this->render('my-customer', ['user_info' => json_encode($user_info)]);
  145. }
  146. $get = Yii::$app->request->get();
  147. $res = Yii::$app->services->validate->validate($get, [
  148. [['user_id'], 'required'],
  149. [['user_id', 'status', 'page'], 'integer'],
  150. [['keyword', 'search_type'],'safe']
  151. ]);
  152. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  153. $user_id = $get['user_id'];
  154. $status = $get['status'] ?? 1;
  155. $keyword = $get['keyword'] ?? '';
  156. $search_type = $get['search_type'] ?? 1;
  157. $page = $get['page'] ?? 1;
  158. switch ($status) {
  159. case '1':
  160. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1, 1);
  161. break;
  162. case '2':
  163. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1, 2);
  164. break;
  165. case '3':
  166. $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 1);
  167. break;
  168. case '4':
  169. // 避免空搜索查询
  170. // if ($search_type == 1 && $keyword) {
  171. // $parent_id = User::find()->select('id')->where(['parent_id' => $keyword, 'status' => StatusEnum::ENABLED])->scalar();
  172. // if ($parent_id != $keyword) return $this->success('操作成功', ['list' => [], 'page_count' => 0]);
  173. // }
  174. // $user_relations = UserPartitionRelationship::getRelationship($user_id, $page, $keyword, $search_type, 2,3);
  175. $parent_ids = UserPartitionRelationship::getParentIdArr($user_id);
  176. if ($parent_ids) $parent_ids = array_reverse($parent_ids);
  177. // 搜索
  178. if ($parent_ids && $search_type > 0 && $keyword !== '') {
  179. $userSearchModel = User::find()
  180. ->select('id')
  181. ->where(['id' => $parent_ids]);
  182. if ($search_type == 1) {
  183. $userSearchModel->andWhere(['=', 'id', $keyword]);
  184. } elseif ($search_type == 2) {
  185. $userSearchModel->andWhere(['=', 'nickname', $keyword]);
  186. } elseif ($search_type == 3) {
  187. $userSearchModel->andWhere(['=', 'mobile', $keyword]);
  188. } elseif ($search_type == 4) {
  189. $userSearchModel->andWhere(['=', 'level', $keyword]);
  190. }
  191. $parent_ids = array_intersect($parent_ids, $userSearchModel->column());
  192. }
  193. $page_parent_ids = array_slice($parent_ids, ($page - 1) * 10, 10);
  194. if ($page_parent_ids) {
  195. $temp_user_relations = [];
  196. foreach ($page_parent_ids as $uid) {
  197. $temp_user_relations[$uid] = $uid;
  198. }
  199. $user_relations['list'] = $temp_user_relations;
  200. $user_relations['count'] = count($parent_ids);
  201. }
  202. break;
  203. }
  204. if (empty($user_relations)) return $this->success('操作成功', ['list' => [], 'page_count' => 0]);
  205. $user_list = $user_relations['list'];
  206. $user_ids = array_keys($user_list);
  207. $where[] = ['in', 'u.id', $user_ids];
  208. $select = ['u.id', 'u.nickname', 'u.mobile', 'u.level', 'u.avatar_url', 'ust.user_id', 'ust.pay_money', 'ust.pay_num','ust.pay_goods_num','ust.finish_goods_num'];
  209. $join = [['LEFT JOIN', UserStatisticsTotal::tableName() . ' as ust', 'u.id=ust.user_id']];
  210. //需要查询父级
  211. if (in_array($status, [2,3])) {
  212. array_push($select, 'p.id p_id', 'p.avatar_url p_avatar_url', 'p.nickname p_nickname');
  213. array_push($join, ['LEFT JOIN', USER::tableName() . ' as p', 'p.id=u.parent_id']);
  214. }
  215. $params = [
  216. 'alias' => 'u',
  217. 'where' => $where,
  218. 'select' => $select,
  219. 'join' => $join
  220. ];
  221. if ($user_ids) $params['order'] = ["FIELD(`u`.`id`,".implode(',', $user_ids).")" => true];
  222. $model = User::find();
  223. User::paramPack($params, $model);
  224. $list = $model->asArray()->all();
  225. $sum_field = 'pay_goods_num';
  226. if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_AGENT) > 0){
  227. //读取插件配置
  228. $more_setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_AGENT, 'more');
  229. $compute_type = $more_setting['compute_type'] ?? 1;
  230. $sum_field = $compute_type == 0 ? 'finish_goods_num' : 'pay_goods_num';
  231. }
  232. $levels = UserLevel::getListIndexByLevelColumn($this->mall_id, [StatusEnum::ENABLED,StatusEnum::DISABLED]);
  233. $defaultLevelName = MallSetting::getDefaultLevelName($this->mall_id);
  234. foreach ($list as &$val) {
  235. $val['pay_money'] = $val['pay_money'] ?? 0;
  236. $val['pay_num'] = $val['pay_num'] ?? 0;
  237. $val['pay_goods_num'] = $val[$sum_field] ?? 0;
  238. $val['bind_time'] = isset($user_list[$val['id']]) ? $user_list[$val['id']] : '暂无';
  239. $val['level_text'] = $levels[$val['level']] ?? $defaultLevelName;
  240. }
  241. $export = MallUser::getExportList();
  242. $data = ['list' => $list, 'export' => $export, 'page_count' => ceil($user_relations['count'] / 10)];
  243. return $this->success('操作成功', $data);
  244. }
  245. /**
  246. * 获取用户的累计消费金额
  247. * @param $user_ids
  248. * @return array
  249. */
  250. private function getUserStatisticsTotal($user_ids)
  251. {
  252. $data = [];
  253. $list = UserStatisticsTotal::find()->select('user_id,pay_money')->where(['user_id' => $user_ids, 'status' => StatusEnum::ENABLED])->asArray()->all();
  254. if ($list) {
  255. foreach ($list as $item) {
  256. $data[$item['user_id']] = $item['pay_money'];
  257. }
  258. }
  259. return $data;
  260. }
  261. /**
  262. * 获取用户的累计消费金额
  263. * @param $user_ids
  264. * @return array
  265. */
  266. private function getUserFrozenMoney($user_ids)
  267. {
  268. $data = [];
  269. CapitalLog::$capitalType = 'commission_frozen';
  270. $statistics_list = CapitalLog::find()->where(['mall_id' => $this->mall_id, 'user_id' => $user_ids, 'status' => 0])->asArray()->all();
  271. if ($statistics_list) {
  272. foreach ($statistics_list as $val) {
  273. if ($val['change_type'] == 'add') $data[$val['user_id']] += $val['change_num'];
  274. if ($val['change_type'] == 'sub') $data[$val['user_id']] -= $val['change_num'];
  275. }
  276. }
  277. return $data;
  278. }
  279. /**
  280. * 佣金类型
  281. * @Author: lun
  282. * @DateTime: 2022/6/29 0029 19:54
  283. * @Copyright: copyright (c) 2021 广东七件事集团
  284. * @return array|mixed|void
  285. */
  286. public function actionMyCommission()
  287. {
  288. $user_id = Yii::$app->request->get('user_id');
  289. if (!$user_id) return [];
  290. $params = Yii::$app->request->get();
  291. CapitalLog::$capitalType = 'commission';
  292. $where[] = ['user_id'=>$user_id];
  293. $where[] = ['mall_id'=>$this->mall_id];
  294. if (Yii::$app->request->get('id')) $where[] = ['>', 'id', Yii::$app->request->get('id')];
  295. if (Yii::$app->request->get('capital_type')) $where[] = ['=', 'capital_type', Yii::$app->request->get('capital_type')];
  296. $capital_type = UserWalletEnum::getCapitalTypeMapByCommission();
  297. $params['where'] = $where;
  298. $params['select'] = 'change_type,change_num,current_num,created_at,from_type,capital_type,id,desc';
  299. $params['order'] = 'id desc';
  300. $params['limit'] = 10;
  301. $list = CapitalLog::listPage($params);
  302. $list['capital_type'] = $capital_type;
  303. return $this->success('操作成功', $list);
  304. }
  305. /**
  306. * 导出我的团队
  307. *
  308. * @return string
  309. */
  310. public function actionExport()
  311. {
  312. if ($this->request->isPost) {
  313. $data = Yii::$app->request->post();
  314. $data['mall_id'] = $this->mall_id;
  315. $filename = '我的团队-' . date('YmdHis') . '_' . rand(10000, 99999);
  316. $res = CsvExportHelper::exportDownLoadCenter(
  317. $this->mall_id,
  318. $filename,
  319. DownloadEnum::TYPE_AGENT,
  320. MallUser::class,
  321. 'exportHandle',
  322. $data
  323. );
  324. if ($res === false) return $this->error('加入导出任务失败' . CsvExportHelper::getStaticError());
  325. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  326. }
  327. }
  328. public function actionOrder()
  329. {
  330. if (Yii::$app->request->isAjax) {
  331. if (Yii::$app->request->isGet) {
  332. $get = Yii::$app->request->get();
  333. $res = Yii::$app->services->validate->validate($get, [
  334. [['user_id'], 'required'],
  335. [['user_id', 'limit', 'page'], 'integer'],
  336. [['keyword', 'order_no', 'start_date', 'end_date'],'string']
  337. ]);
  338. if ($res === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  339. $where = [
  340. ['mall_id' => $this->mall_id],
  341. ['user_id' => $get['user_id']],
  342. ['status' => StatusEnum::ENABLED]
  343. ];
  344. if (!empty($get['start_date'])) $where[] = ['>=', 'created_at', strtotime($get['start_date'])];
  345. if (!empty($get['end_date'])) $where[] = ['<=', 'created_at', strtotime($get['end_date'])];
  346. if (!empty($get['keyword'])) {
  347. $details = OrderDetail::listPage([
  348. 'where' => array_merge($where, [[
  349. 'or', ['like', 'goods_id', $get['keyword']], ['like', 'goods_name', $get['keyword']]
  350. ]]),
  351. 'limit' => $get['limit'] ?? 10,
  352. 'order' => 'id desc',
  353. 'select'=> 'order_id',
  354. 'group' => 'order_id',
  355. ]);
  356. if (empty($details['list'])) return [];
  357. $where[] = ['id' => array_column($details['list'], 'order_id')];
  358. }
  359. if (!empty($get['order_no'])) $where[] = ['like', 'order_no', $get['order_no']];
  360. $ret = Order::listPage([
  361. 'where' => $where,
  362. 'limit' => $get['limit'] ?? 10,
  363. 'order' => 'id desc',
  364. 'with' => ['detail'],
  365. ]);
  366. if (!empty(OrderDetail::getStaticError())) return $this->error(OrderDetail::getStaticError());
  367. $ret['export_list'] = Order::fieldsList();
  368. $ret['export_where'] = $where;
  369. $down = Download::getOne([
  370. ['mall_id'=>$this->mall_id],
  371. ['type'=>DownloadEnum::TYPE_ORDERS],
  372. ['like','name','订单列表'.'%',false]
  373. ],true,[],'id desc');
  374. if(!empty($down)){
  375. $down['params'] = json_decode($down['params'],true);
  376. $ret['fields'] = $down['params']['fields'];
  377. }
  378. return $this->success('获取成功', $ret);
  379. } elseif (Yii::$app->request->isPost) {
  380. $post = \Yii::$app->request->post();
  381. $post['mall_id'] = $this->mall_id;
  382. $post['flag'] = 'EXPORT';
  383. $post['child_orders'] = true;
  384. if (!empty($post['page'])) unset($post['page']);
  385. $filename = '团队数据-订单列表-' . date('YmdHis').'_'.rand(10000,99999);
  386. $res = CsvExportHelper::exportDownLoadCenter($this->mall_id,$filename,DownloadEnum::TYPE_ORDERS,
  387. Order::class,'exportHandle', $post);
  388. if ($res === false) return $this->error('加入导出任务失败'.CsvExportHelper::getStaticError());
  389. return $this->success('添加导出任务成功,任务完成后请在下载中心进行下载!');
  390. }
  391. }
  392. return $this->render($this->action->id);
  393. }
  394. public function actionSetting()
  395. {
  396. $request = Yii::$app->request;
  397. if ($request->isAjax) {
  398. try {
  399. if ($request->isGet) {
  400. $setting = \Yii::$app->services->setting->addons->get($this->mall_id, TeamDataEnum::ADDONS_NAME, 'basic');
  401. return $this->success('获取成功', ['basic' => $setting]);
  402. }
  403. if ($request->isPost) {
  404. $post = $request->post();
  405. $res = Yii::$app->services->validate->validate($post, [
  406. [['settle_type', 'is_sub_refund'], 'integer'],
  407. ]);
  408. if (!$res) throw new Exception(Yii::$app->services->validate->getErrorMessage());
  409. $res = \Yii::$app->services->setting->addons->set($this->mall_id, TeamDataEnum::ADDONS_NAME, ['basic' => $post]);
  410. return $this->success('操作成功');
  411. }
  412. } catch (\Exception $e) {
  413. return $this->error($e->getMessage());
  414. }
  415. }
  416. return $this->render($this->action->id);
  417. }
  418. }