Vipagentreferral.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: wanggb
  5. * Date: 2018/11/24
  6. * Time: 18:31
  7. */
  8. namespace app\admin\controller\referral;
  9. use app\common\controller\Backend;
  10. use app\main\helper\ArrayHelper;
  11. use app\main\service\ReferralService;
  12. use app\main\service\VisitLimitService;
  13. use think\Exception;
  14. use app\common\library\Ssdb;
  15. use app\common\library\Redis;
  16. use app\main\constants\CacheConstants;
  17. use think\Config;
  18. use think\Log;
  19. class Vipagentreferral extends Backend
  20. {
  21. /**
  22. * @var \app\common\model\Referral
  23. */
  24. protected $model = null;
  25. /**
  26. * @var \app\common\model\VipAdminBind
  27. */
  28. protected $vipAdminBindModel = null;
  29. /**
  30. * @var \app\common\model\Guide
  31. */
  32. protected $guideModel = null;
  33. /**
  34. * @var \app\common\model\Entryhost
  35. */
  36. protected $entryhostModel = null;
  37. public function _initialize()
  38. {
  39. parent::_initialize();
  40. $this->model = model('Referral');
  41. $this->vipAdminBindModel = model('VipAdminBind');
  42. $this->guideModel = model('Guide');
  43. $this->entryhostModel = model('Entryhost');
  44. }
  45. /**
  46. * @throws \think\db\exception\DataNotFoundException
  47. * @throws \think\db\exception\ModelNotFoundException
  48. * @throws \think\exception\DbException
  49. * @author 李聪聪
  50. */
  51. public function export()
  52. {
  53. if (!in_array($this->group, [7, 8])) {
  54. $this->error('当前用户不是vip也不是vip运营');
  55. }
  56. ini_set('memory_limit', '256M'); //内存限制
  57. $columns = [
  58. '渠道商ID',
  59. '渠道商账号',
  60. '渠道商昵称',
  61. '公众号',
  62. '推广ID',
  63. '推广链接',
  64. '入口页面',
  65. '代理商账号',
  66. '派单渠道', //new
  67. '累计阅读人数',
  68. '今日阅读人数',
  69. '累计关注人数', //new
  70. '今日关注人数', //new
  71. '累计净关注人数', //new
  72. '今日净关注人数', //new
  73. '累计充值金额',
  74. '今日充值金额',
  75. '推广成本', //new
  76. '创建时间'
  77. ];
  78. $redis = Redis::instance();
  79. header('Content-Description: File Transfer');
  80. header('Content-Type: application/vnd.ms-excel');
  81. header('Content-Disposition: attachment; filename="代理商推广链接统计数据-' . date('YmdHis', time()) . '.csv"');
  82. header('Expires: 0');
  83. header('Cache-Control: must-revalidate');
  84. header('Pragma: public');
  85. $fp = fopen('php://output', 'a');//打开output流
  86. mb_convert_variables('GBK', 'UTF-8', $columns);
  87. fputcsv($fp, $columns);//将数据格式化为CSV格式并写入到output流中
  88. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  89. $channelIds = $this->vipAdminBindModel->getChannelIds($this->auth->id);
  90. if (empty($channelIds)) {
  91. fclose($fp);
  92. exit();
  93. }
  94. //获取所有代理商
  95. $allAgentIds = $this->vipAdminBindModel->getAllAgentIds($channelIds);
  96. try {
  97. $condition['referral.admin_id'] = ['in', $allAgentIds];
  98. $countFetchObj = $this->getFetchObj($where, $condition);
  99. $total = $countFetchObj->count();
  100. if ($total == 0) {
  101. fclose($fp);
  102. exit();
  103. }
  104. } catch (Exception $exception) {
  105. Log::info($countFetchObj->getLastSql());
  106. $exception->getMessage();
  107. }
  108. $limit = 100;
  109. $migrate = VisitLimitService::instance()->checkMigratedV2();
  110. $pages = ceil($total / $limit);
  111. for ($i = 1; $i <= $pages; $i++) {
  112. $offset = ($i - 1) * $limit;
  113. $listFetchObj = $this->getFetchObj($where, $condition);
  114. $list = $listFetchObj
  115. ->limit($offset, $limit)
  116. ->select();
  117. $distributeList = $this->filterDataByDistribute($list);
  118. $migrateCollectList = [];
  119. if ($migrate) {
  120. $referralIds = array_column($list, 'id');
  121. $migrateCollectList = ReferralService::instance()->getReferralCollectFromApi($referralIds)->data;
  122. }
  123. foreach ($list as $k => $v) {
  124. $channelId = $v['qds_id'];
  125. //获取当前书籍的默认关注章节
  126. if (empty($v['guide_chapter_idx']) && !empty($v['book_id'])) {
  127. $list[$k]['guide_chapter_idx'] = $this->guideModel->getGuideChapter($v['admin_id'], $v['book_id'], 0, $channelId);
  128. }
  129. if ($v['distribute'] === '0') {
  130. $urlReferral = Config::get('site.scheme') . '://' . $distributeList[$v['qds_id']]['appid'] . '.' . $distributeList[$v['qds_id']]['host'];
  131. } else {
  132. $urlReferral = Config::get('site.scheme') . '://' . $v['appid'] . '.' . $v['host'];
  133. }
  134. $list[$k]['url_referral'] = $urlReferral . '/t/' . $v['id'];
  135. if ($migrate) {
  136. if (array_key_exists($v['id'], $migrateCollectList)) {
  137. $list[$k] = array_merge($list[$k]->getData(), $migrateCollectList[$v['id']]);
  138. }
  139. } else {
  140. $dayMTkey = "M-T:".$v['id'].":".date("d"); //今日充值金额key
  141. $list[$k]['dayuv'] = (int)Redis::instance()->get(CacheConstants::getReadOfReferralIdKey($v['id']));
  142. $list[$k]['dayut'] = (int)Redis::instance()->get(CacheConstants::getSubscribeOfReferralIdKey($v['id'])); //今日关注人数
  143. $list[$k]['daymt'] = (int)Redis::instance()->get($dayMTkey)? round(Redis::instance()->get($dayMTkey) / 100, 2) :0; //今日充值金额
  144. $list[$k]['dayjt'] = (int)Redis::instance()->get(CacheConstants::getSubscribeOfPureReferralIdKey($v['id'])); //今日净关注人数
  145. $list[$k]['dayqt'] = (int)Redis::instance()->get(CacheConstants::getUnsubscribeOfReferralIdKey($v['id'])); //今日取消关注人数
  146. $list[$k]['net_follow_num'] = (int)$list[$k]['net_follow_num'];
  147. if ($list[$k]['uv'] < $list[$k]['dayuv']) {
  148. $list[$k]['uv'] = $list[$k]['dayuv'];
  149. }
  150. if ($list[$k]['follow'] < $list[$k]['dayut']) {
  151. $list[$k]['follow'] = $list[$k]['dayut'];
  152. }
  153. if ($list[$k]['net_follow_num'] < $list[$k]['dayjt']) {
  154. $list[$k]['net_follow_num'] = $list[$k]['dayjt'];
  155. }
  156. }
  157. if (!empty($v['book_id'])) {
  158. $isLimited = model('BookLimit')->backendHasLimit(0, $v['admin_id'], $v['book_id']);
  159. if ($isLimited) {
  160. $list[$k]['limited'] = 1;
  161. }
  162. }
  163. $list[$k]['short_url'] = replaceShortDomain($list[$k]['url_referral'], $v['short_id']);
  164. if (isset($v['wx_json'])) {
  165. $adminJson = json_decode($v['wx_json'], true);
  166. if (isset($adminJson['authorizer_info']['nick_name'])) {
  167. $list[$k]['wx_nickname'] = $adminJson['authorizer_info']['nick_name'];
  168. } else {
  169. $list[$k]['wx_nickname'] = '';
  170. }
  171. } else {
  172. $list[$k]['wx_nickname'] = '';
  173. }
  174. $entry_page = '';
  175. if (isset($v['type'])) {
  176. if ($v['type'] == 1) {
  177. if (isset($v['book_name']) && isset($v['chapter_name'])) {
  178. $entry_page .= $v['book_name'];
  179. $entry_page .= '--' . $v['chapter_name'];
  180. if (isset($list[$k]['guide_chapter_idx']) && !empty($list[$k]['guide_chapter_idx'])) {
  181. $entry_page .= '--关注章节:' . $list[$k]['guide_chapter_idx'];
  182. } else {
  183. $entry_page .= '--关注章节:默认';
  184. }
  185. } else {
  186. $entry_page = '未知';
  187. }
  188. } elseif ($v['type'] == 3) {
  189. $entry_page .= '落地页推广';
  190. if (isset($v['book_name']) && isset($v['chapter_name'])) {
  191. $entry_page .= '--' . $v['book_name'];
  192. $entry_page .= '--' . $v['chapter_name'];
  193. }
  194. if (isset($list[$k]['guide_chapter_idx']) && !empty($list[$k]['guide_chapter_idx'])) {
  195. $entry_page .= '--关注章节:' . $list[$k]['guide_chapter_idx'];
  196. } else {
  197. $entry_page .= '--关注章节:默认';
  198. }
  199. } else {
  200. $entry_page .= '书城首页推广';
  201. }
  202. } else {
  203. $entry_page = '未知';
  204. }
  205. //获取每列数据,转换处理成需要导出的数据
  206. $rowData = [
  207. $list[$k]['qds_id'] ?? 0,
  208. $list[$k]['qds_username'] ?? '',
  209. $list[$k]['qds_nickname'] ?? '',
  210. $list[$k]['wx_nickname'] ?? '',
  211. $list[$k]['id'] ?? 0,
  212. $list[$k]['url_referral'] ?? '',
  213. $entry_page ?? 0,
  214. $list[$k]['username'] ?? 0,
  215. $list[$k]['name'] ?? '',
  216. $list[$k]['uv'] ?? 0,
  217. $list[$k]['dayuv'] ?? 0,
  218. $list[$k]['follow'] ?? 0,
  219. $list[$k]['dayut'] ?? 0,
  220. $list[$k]['net_follow_num'] ?? '',
  221. $list[$k]['dayjt'] ?? '',
  222. $list[$k]['money'] ?? '',
  223. $list[$k]['daymt'] ?? '',
  224. $list[$k]['cost'] ?? '',
  225. empty($list[$k]['createtime']) ? '无': date('Y-m-d H:i:s', $list[$k]['createtime'])
  226. ];
  227. //需要格式转换,否则会乱码
  228. mb_convert_variables('GBK', 'UTF-8', $rowData);
  229. fputcsv($fp, $rowData);
  230. }
  231. fclose($fp);
  232. exit();
  233. }
  234. }
  235. public function index()
  236. {
  237. if (!in_array($this->group, [7, 8])) {
  238. $this->error('当前用户不是vip也不是vip运营');
  239. }
  240. if ($this->request->isAjax()) {
  241. //如果发送的来源是Selectpage,则转发到Selectpage
  242. if ($this->request->request('pkey_name')) {
  243. return $this->selectpage();
  244. }
  245. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  246. $channelIds = $this->vipAdminBindModel->getChannelIds($this->auth->id);
  247. if (empty($channelIds)) {
  248. $this->error('当前vip或vip运营下没有绑定渠道商');
  249. }
  250. #获取所有代理商
  251. $allAgentIds = $this->vipAdminBindModel->getAllAgentIds($channelIds);
  252. try{
  253. $condition['referral.admin_id'] = ['in', $allAgentIds];
  254. $countFetchObj = $this->getFetchObj($where, $condition);
  255. $total = $countFetchObj->count();
  256. }catch (Exception $exception){
  257. Log::info($countFetchObj->getLastSql());
  258. $exception->getMessage();
  259. }
  260. try{
  261. $listFetchObj = $this->getFetchObj($where, $condition);
  262. $list = $listFetchObj
  263. ->limit($offset, $limit)
  264. ->select();
  265. }catch (Exception $exception){
  266. Log::info($listFetchObj->getLastSql());
  267. $exception->getMessage();
  268. }
  269. //
  270. $distributeList = $this->filterDataByDistribute($list);
  271. $migrate = VisitLimitService::instance()->checkMigratedV2();
  272. $migrateCollectList = [];
  273. if ($migrate) {
  274. $referralIds = array_column($list, 'id');
  275. $migrateCollectList = ReferralService::instance()->getReferralCollectFromApi($referralIds)->data;
  276. }
  277. foreach ($list as $k => $v) {
  278. $channelId = $v['qds_id'];
  279. //获取当前书籍的默认关注章节
  280. if (empty($v['guide_chapter_idx']) && !empty($v['book_id'])) {
  281. $list[$k]['guide_chapter_idx'] = $this->guideModel->getGuideChapter($v['admin_id'], $v['book_id'], 0, $channelId);
  282. }
  283. if($v['distribute'] === '0'){
  284. $urlReferral = Config::get('site.scheme') . '://' . $distributeList[$v['qds_id']]['appid'] . '.' . $distributeList[$v['qds_id']]['host'];
  285. }else{
  286. $urlReferral = Config::get('site.scheme') . '://' . $v['appid'] . '.' . $v['host'];
  287. }
  288. $list[$k]['url_referral'] = $urlReferral . '/t/' . $v['id'];
  289. if ($migrate) {
  290. if (array_key_exists($v['id'], $migrateCollectList)) {
  291. $list[$k] = array_merge($list[$k]->getData(), $migrateCollectList[$v['id']]);
  292. }
  293. } else {
  294. $dayMTkey = "M-T:".$v['id'].":".date("d"); //今日充值金额key
  295. $list[$k]['dayuv'] = (int)Redis::instance()->get(CacheConstants::getReadOfReferralIdKey($v['id']));
  296. $list[$k]['dayut'] = (int)Redis::instance()->get(CacheConstants::getSubscribeOfReferralIdKey($v['id'])); //今日关注人数
  297. $list[$k]['daymt'] = (int)Redis::instance()->get($dayMTkey)? round(Redis::instance()->get($dayMTkey) / 100, 2) :0; //今日充值金额
  298. $list[$k]['dayjt'] = (int)Redis::instance()->get(CacheConstants::getSubscribeOfPureReferralIdKey($v['id'])); //今日净关注人数
  299. $list[$k]['dayqt'] = (int)Redis::instance()->get(CacheConstants::getUnsubscribeOfReferralIdKey($v['id'])); //今日取消关注人数
  300. $list[$k]['net_follow_num'] = (int)$list[$k]['net_follow_num'];
  301. if ($list[$k]['uv'] < $list[$k]['dayuv']) {
  302. $list[$k]['uv'] = $list[$k]['dayuv'];
  303. }
  304. if ($list[$k]['follow'] < $list[$k]['dayut']) {
  305. $list[$k]['follow'] = $list[$k]['dayut'];
  306. }
  307. if ($list[$k]['net_follow_num'] < $list[$k]['dayjt']) {
  308. $list[$k]['net_follow_num'] = $list[$k]['dayjt'];
  309. }
  310. $dayMTNkey = "M-T-N:".$v['id'].":".date("d"); //今日充值笔数key
  311. $list[$k]['order_nums'] = (int)$list[$k]['orders_num'];
  312. $list[$k]['day_order_nums'] = (int)Redis::instance()->get($dayMTNkey);
  313. }
  314. if (!empty($v['book_id'])) {
  315. $isLimited = model('BookLimit')->backendHasLimit(0, $v['admin_id'], $v['book_id']);
  316. if ($isLimited) {
  317. $list[$k]['limited'] = 1;
  318. }
  319. }
  320. $list[$k]['short_url'] = replaceShortDomain($list[$k]['url_referral'], $v['short_id']);
  321. $adminJson = json_decode($v['wx_json'], true);
  322. $list[$k]['wx_nickname'] = $adminJson['authorizer_info']['nick_name'];
  323. unset($v['wx_json']);
  324. }
  325. $result = array("total" => $total, "rows" => $list);
  326. return json($result);
  327. }
  328. return $this->view->fetch();
  329. }
  330. private function getFetchObj($where, $condition)
  331. {
  332. $fetchObj = $this->model->join(['admin' => 'dls_admin'], 'admin.id = referral.admin_id')
  333. ->join('admin_config', 'admin.id = admin_config.admin_id', 'left')
  334. ->join('book', 'referral.book_id = book.id', 'left')
  335. ->join('ophost', 'admin_config.ophost_id = ophost.id', 'left')
  336. ->join('admin_extend', 'admin.id = admin_extend.admin_id', 'INNER')
  337. ->join(['admin' => 'qds_admin'], 'admin_extend.create_by = qds_admin.id', 'INNER')
  338. ->field([
  339. 'admin_extend.create_by' => 'p_admin_id',
  340. 'qds_admin.username' => 'qds_username',
  341. 'qds_admin.nickname' => 'qds_nickname',
  342. 'qds_admin.id' => 'qds_id',
  343. 'referral.*',
  344. 'book.name' => 'book_name',
  345. 'admin.id' => 'dls_id',
  346. 'admin.username',
  347. 'admin.nickname',
  348. 'admin_config.json' => 'wx_json',
  349. 'admin_config.entryhost_id',
  350. 'admin_config.appid',
  351. 'ophost.host',
  352. 'admin_extend.distribute' => 'distribute'
  353. ])
  354. ->where($where)
  355. ->where($condition)
  356. ->order('referral.state', 'desc')
  357. ->order('referral.createtime', 'desc');
  358. return $fetchObj;
  359. }
  360. private function filterDataByDistribute($list){
  361. $qds_arr = [];
  362. foreach ($list as $k => $v)
  363. {
  364. if($v['distribute'] == '0'){
  365. $qds_arr[] = $v['qds_id'];
  366. }
  367. }
  368. $qds_str = implode(',', $qds_arr);
  369. $data = model('admin_config')
  370. ->join('ophost', 'admin_config.ophost_id = ophost.id', 'left')
  371. ->field([
  372. 'admin_config.admin_id',
  373. 'admin_config.appid',
  374. 'ophost.host'
  375. ])
  376. ->where('admin_id','in', $qds_str)
  377. ->select();
  378. $arr = [];
  379. foreach ($data as $key => $item){
  380. $arr[$item['admin_id']] = $item;
  381. }
  382. return $arr;
  383. }
  384. }