PkDateStatistic.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <?php
  2. namespace addons\Pk\common\models;
  3. use addons\Pk\common\enums\PkEnum;
  4. use common\enums\StatusEnum;
  5. use common\models\user\User;
  6. use Yii;
  7. /**
  8. * This is the model class for table "{{%addons_pk_date_statistic}}".
  9. *
  10. * @property int $id
  11. * @property int $mall_id
  12. * @property int $status 状态[1启用 0禁用 -1删除]
  13. * @property int $join_user_num 参与活动人数
  14. * @property int $new_user_num 拉新人数
  15. * @property int $activity_num 新增活动数量
  16. * @property float $order_money_num 业绩总额
  17. * @property int $share_num 分享次数
  18. * @property int $share_visit 分享访问次数
  19. * @property string $date 日期(格式是:2020-06-01)
  20. * @property int $created_at 创建时间
  21. * @property int $updated_at 修改时间
  22. */
  23. class PkDateStatistic extends \common\models\base\BaseActiveRecord
  24. {
  25. /**
  26. * {@inheritdoc}
  27. */
  28. public static function tableName()
  29. {
  30. return '{{%addons_pk_date_statistic}}';
  31. }
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function rules()
  36. {
  37. return [
  38. [['mall_id', 'status', 'join_user_num', 'new_user_num', 'activity_num', 'share_num', 'share_visit', 'created_at', 'updated_at'], 'integer'],
  39. [['order_money_num'], 'number'],
  40. [['date'], 'required'],
  41. [['date'], 'safe'],
  42. ];
  43. }
  44. /**
  45. * {@inheritdoc}
  46. */
  47. public function attributeLabels()
  48. {
  49. return [
  50. 'id' => 'ID',
  51. 'mall_id' => 'Mall ID',
  52. 'status' => '状态[1启用 0禁用 -1删除]',
  53. 'join_user_num' => '参与活动人数',
  54. 'new_user_num' => '拉新人数',
  55. 'activity_num' => '新增活动数量',
  56. 'order_money_num' => '业绩总额',
  57. 'share_num' => '分享次数',
  58. 'share_visit' => '分享访问次数',
  59. 'date' => '日期(格式是:2020-06-01)',
  60. 'created_at' => '创建时间',
  61. 'updated_at' => '修改时间',
  62. ];
  63. }
  64. public static function setData($params)
  65. {
  66. try {
  67. if (empty($params['mall_id']) || empty($params['date'])) return false;
  68. $model = self::findOne(['mall_id' => $params['mall_id'], 'date' => $params['date'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]);
  69. if (empty($model)) {
  70. $model = new self();
  71. $model->date = $params['date'];
  72. $model->mall_id = $params['mall_id'];
  73. $model->loadDefaultValues();
  74. }
  75. if (!empty($params['join_user_num'])) $model->join_user_num += $params['join_user_num'];
  76. if (!empty($params['new_user_num'])) $model->new_user_num += $params['new_user_num'];
  77. if (!empty($params['activity_num'])) $model->activity_num += $params['activity_num'];
  78. if (!empty($params['order_money_num'])) $model->order_money_num += $params['order_money_num'];
  79. if (!empty($params['share_num'])) $model->share_num += $params['share_num'];
  80. if (!empty($params['share_visit'])) $model->share_visit += $params['share_visit'];
  81. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  82. return $model;
  83. } catch (\Exception $e) {
  84. self::$static_error = $e->getMessage();
  85. return false;
  86. }
  87. }
  88. /**
  89. * 指定时间内活动数量统计 返回总数
  90. * @param $mall_id
  91. * @param $start 开始时间戳
  92. * @param $end 结束时间戳
  93. * @param $field
  94. * @return int|mixed
  95. */
  96. public static function pkAcitivityNumCount($mall_id, $start, $end, $field = 'activity_num')
  97. {
  98. $start = date("Y-m-d", $start);
  99. $end = date("Y-m-d", $end);
  100. $number = PkDateStatistic::find()
  101. ->where(array('status' => StatusEnum::ENABLED))
  102. ->where(array('mall_id' => $mall_id))
  103. ->andWhere(array('>=', 'date', $start))
  104. ->andWhere(array('<=', 'date', $end))
  105. ->sum($field);
  106. return (float) $number;
  107. }
  108. /**
  109. * 指定时间内活动数量统计 返回指定时间段内统计列表
  110. * @param $mall_id
  111. * @param $start
  112. * @param $end
  113. * @param $field
  114. * @return array
  115. */
  116. public static function pkActivityNumCountList($mall_id, $start, $end, $field)
  117. {
  118. $start_date = date("Y-m-d", $start);
  119. $end_date = date("Y-m-d", $end);
  120. $select = ["$field as number", "date"];
  121. $data = PkDateStatistic::find()
  122. ->where(array('status' => StatusEnum::ENABLED))
  123. ->where(array('mall_id' => $mall_id))
  124. ->andFilterWhere(array('>=', 'date', $start_date))
  125. ->andFilterWhere(array('<=', 'date', $end_date))
  126. ->select($select)
  127. ->asArray()->all();
  128. $day_key_list = array_column($data, 'number','date');
  129. return self::dealDaytimeData($day_key_list, $start, $end);
  130. }
  131. // 指定时间内活动数量统计 返回指定时间段内列表
  132. public static function pkActivityNumList($mall_id, $start, $end, $field)
  133. {
  134. $start = date("Y-m-d", $start);
  135. $end = date("Y-m-d", $end);
  136. $select = "$field as num,date";
  137. $data = PkDateStatistic::find()
  138. ->where(array('status' => StatusEnum::ENABLED))
  139. ->where(array('mall_id' => $mall_id))
  140. ->andFilterWhere(array('>=', 'date', $start))
  141. ->andFilterWhere(array('<=', 'date', $end))
  142. ->select($select)
  143. ->asArray()->all();
  144. $day_by_day_list = self::_getNewDayByDayData($data, $start, $end, 'invite');
  145. return array(
  146. 'personal' => array('keys' => array_keys($day_by_day_list), 'values' => array_values($day_by_day_list)),
  147. );
  148. }
  149. /**
  150. * 指定时间内拉新数
  151. * @param $mall_id
  152. * @param int $activity_type 个人PK为 1
  153. * @param int $start 开始时间戳
  154. * @param int $end 结束时间戳
  155. * @param bool $is_day_by_day 是否逐天统计
  156. * @return array|int|null|string
  157. */
  158. public static function pkInvitedNewUserNum($mall_id, $activity_type = 1, $start, $end, $is_day_by_day = false)
  159. {
  160. $query = PkInviteLog::find()
  161. ->where(array('status' => StatusEnum::ENABLED, 'mall_id' => $mall_id, 'activity_type' => $activity_type))
  162. ->andWhere(array('between', 'created_at', $start, $end));
  163. if ($is_day_by_day) {
  164. if ($start == 0 || $end == 0) return array('keys' => [], 'values' => []);
  165. $query = $query->select(["from_unixtime(created_at, '%Y-%m-%d') as daytime", "count(id) as number"]);
  166. //逐天统计,按天分组
  167. $invite_list = $query->asArray()->groupBy(["daytime"])->all();
  168. $day_key_list = array_column($invite_list, 'number','daytime');
  169. return self::dealDaytimeData($day_key_list, $start, $end);
  170. } else {
  171. //统计总数
  172. return (int) $query->count();
  173. }
  174. }
  175. /**
  176. * 指定时间内销售业绩
  177. * @param $mall_id
  178. * @param $activity_type
  179. * @param $start 开始时间戳
  180. * @param $end 结束时间戳
  181. * @param bool $is_day_by_day
  182. * @return array|int|mixed
  183. */
  184. public static function pkPerformanceNum($mall_id, $activity_type, $start, $end, $is_day_by_day = false)
  185. {
  186. $query = PkPerformanceLog::find()
  187. ->where(array('status' => StatusEnum::ENABLED, 'mall_id' => $mall_id, 'activity_type' => $activity_type))
  188. ->andWhere(array('between', 'created_at', $start, $end));
  189. if ($is_day_by_day) {
  190. if ($start == 0 || $end == 0) return array('keys' => [], 'values' => []);
  191. $query = $query->select(["from_unixtime(created_at, '%Y-%m-%d') as daytime", "sum(money) as number"]);
  192. //逐天统计,按天分组
  193. $performance_list = $query->asArray()->groupBy(["daytime"])->all();
  194. $day_key_list = array_column($performance_list, 'number','daytime');
  195. return self::dealDaytimeData($day_key_list, $start, $end);
  196. } else {
  197. //统计总数
  198. return (float) $query->sum('money');
  199. }
  200. }
  201. /**
  202. * 处理按天统计的数据,变成 echart 的数据格式
  203. * @param $data [ ['2022-06-11' => '888'], ['2022-06-12' => '999'] ]
  204. * @param $start 开始时间戳
  205. * @param $end 结束时间戳
  206. * @return array
  207. */
  208. public static function dealDaytimeData($data, $start, $end)
  209. {
  210. $keys = $values = [];
  211. $current_time = $start;
  212. do {
  213. $day = date('Y-m-d', $current_time);
  214. $keys[] = $day;
  215. $values[] = $data[$day] ?? 0;
  216. $next_day_time = strtotime("+1 day", $current_time);
  217. $current_time = $next_day_time;
  218. } while ($current_time <= $end && $end > $start);
  219. return compact('keys', 'values');
  220. }
  221. //根据日期获取逐天统计
  222. private static function _getNewDayByDayData($list, $start, $end, $secen = 'invite')
  223. {
  224. $day_by_day_list = array();
  225. if (!empty($list)) {
  226. foreach ($list as $val) {
  227. $key = $val['date'];
  228. $performance = $val['num'];
  229. if (!isset($day_by_day_list[$key])) {
  230. $day_by_day_list[$key] = $performance;
  231. } else {
  232. $day_by_day_list[$key] += $performance;
  233. }
  234. }
  235. }
  236. //补足不存在的天
  237. $no_start_date = date('Ymd', strtotime($start));
  238. $no_end_date = date('Ymd', strtotime($end));
  239. for ($no_start_date; $no_start_date <= $no_end_date; $no_start_date++) {
  240. $date = date('Y-m-d', strtotime($no_start_date));
  241. if (!isset($day_by_day_list[$date])) $day_by_day_list[$date] = 0;
  242. }
  243. ksort($day_by_day_list);
  244. return $day_by_day_list;
  245. }
  246. //获取概况数据
  247. public static function getGeneralSituation($mall_id, $type, $start, $end)
  248. {
  249. return array(
  250. 'activity_num' => self::pkAcitivityNumCount($mall_id, $start, $end, 'activity_num'),
  251. 'invited_new_user_num' => self::pkAcitivityNumCount($mall_id, $start, $end, 'new_user_num'),
  252. 'sale_performance_num' => self::pkAcitivityNumCount($mall_id, $start, $end, 'order_money_num'),
  253. 'participate_user_num' => self::pkAcitivityNumCount($mall_id, $start, $end, 'join_user_num'),
  254. 'share_times' => self::pkAcitivityNumCount($mall_id, $start, $end, 'share_num'),
  255. 'share_link_visit_num' => self::pkAcitivityNumCount($mall_id, $start, $end, 'share_visit'),
  256. );
  257. }
  258. // 按天统计PK拉新数量
  259. public static function pkInvitedNewUserCountByDay($mall_id, $start, $end)
  260. {
  261. return array(
  262. // 'personal' => self::pkInvitedNewUserNum($mall_id, PkEnum::ACTIVITY_TYPE_PERSON, $start, $end, true),
  263. 'personal' => self::pkActivityNumList($mall_id, $start, $end, 'new_user_num'),
  264. );
  265. }
  266. // 按天统计PK业绩
  267. public static function pkPerformanceCountByDay($mall_id, $start, $end)
  268. {
  269. return array(
  270. // 'personal' => self::pkPerformanceNum($mall_id, PkEnum::ACTIVITY_TYPE_PERSON, $start, $end, true),
  271. 'personal' => self::pkAcitivityNumCount($mall_id, $start, $end, 'new_user_num'),
  272. );
  273. }
  274. // 获取指定活动业绩排名TOPN
  275. public static function getPerformanceRank($mall_id, $activity_id, $topn)
  276. {
  277. $activity = PkActivity::find()->where(array('id' => $activity_id))->asArray()->one();
  278. if (empty($activity)) return [];
  279. $where = [];
  280. $with = ['user'];
  281. $where[] = ['=', 'mall_id', $mall_id];
  282. $where[] = ['=', 'activity_id', $activity_id];
  283. $where[] = ['>=', 'status', StatusEnum::DISABLED];
  284. if($activity['performance_type'] == PkEnum::NEW_ACTIVE){
  285. $order = 'new_user_num desc,id asc';
  286. $where[] = ['>', 'new_user_num', 0];
  287. }else{
  288. $order = 'order_money_num desc,id asc';
  289. $where[] = ['>', 'order_money_num', 0];
  290. }
  291. $params = array('where' => $where, 'with' => $with, 'order' => $order, 'limit' => $topn);
  292. $list = PkActivityStatistic::listPage($params, false, true);
  293. return $list['list'] ?? [];
  294. }
  295. /**
  296. * 获取平台数据
  297. * @param $params
  298. * @return array
  299. */
  300. public static function getPkPanelData($params)
  301. {
  302. $scene = $params['scene'] ?: 'all';
  303. $mall_id = $params['mall_id'] ?? 0;
  304. $general_situation_personal_start = $params['general_situation_personal_start'] ?? 0;
  305. $general_situation_personal_end = $params['general_situation_personal_end'] ?? 0;
  306. $pk_statistics_invited_new_start = $params['pk_statistics_invited_new_start'] ?? 0;
  307. $pk_statistics_invited_new_end = $params['pk_statistics_invited_new_end'] ?? 0;
  308. $pk_statistics_performance_start = $params['pk_statistics_performance_start'] ?? 0;
  309. $pk_statistics_performance_end = $params['pk_statistics_performance_end'] ?? 0;
  310. $personal_activity_id = $params['personal_activity_id'] ?? 0;
  311. $topn = $params['topn'] ?? 10;
  312. $return = array();
  313. switch ($scene) {
  314. case 'all':
  315. //概况
  316. $return['general_situation'] = array(
  317. // 个人PK概况 22
  318. 'personal' => self::getGeneralSituation($mall_id, PkEnum:: ACTIVITY_TYPE_PERSON, $general_situation_personal_start, $general_situation_personal_end),
  319. 'team' => []
  320. );
  321. //业绩pk
  322. $return['pk_statistics'] = array(
  323. // 拉新数据报表 22
  324. // 'invited_new_user_chart' => self::pkInvitedNewUserCountByDay($mall_id, $pk_statistics_invited_new_start, $pk_statistics_invited_new_end),
  325. 'invited_new_user_chart' => self::pkActivityNumList($mall_id, $pk_statistics_invited_new_start, $pk_statistics_invited_new_end, 'new_user_num'),
  326. // 业绩数据报表 22
  327. // 'performance_chart' => self::pkPerformanceCountByDay($mall_id, $pk_statistics_performance_start, $pk_statistics_performance_end),
  328. 'performance_chart' => self::pkActivityNumList($mall_id, $pk_statistics_invited_new_start, $pk_statistics_invited_new_end, 'order_money_num'),
  329. );
  330. // //TOP 10排行榜
  331. // $return['rank'] = array(
  332. // 'personal' => self::getPerformanceRank($mall_id,$personal_activity_id,$topn),
  333. // 'team' => self::getPerformanceRank($mall_id,$team_activity_id,$topn),
  334. // );
  335. break;
  336. case 'general_situation' :
  337. $return['general_situation'] = array(
  338. // 个人PK概况 22
  339. 'personal' => self::getGeneralSituation($mall_id, PkEnum:: ACTIVITY_TYPE_PERSON, $general_situation_personal_start, $general_situation_personal_end),
  340. 'team' => []
  341. );
  342. break;
  343. case 'general_situation.personal' :
  344. $return['general_situation'] = array(
  345. // 个人PK概况 22
  346. 'personal' => self::getGeneralSituation($mall_id, PkEnum:: ACTIVITY_TYPE_PERSON, $general_situation_personal_start, $general_situation_personal_end),
  347. );
  348. break;
  349. case 'pk_statistics' :
  350. $return['pk_statistics'] = array(
  351. // 拉新数据报表 22
  352. 'invited_new_user_chart' => self::pkInvitedNewUserCountByDay($mall_id, $pk_statistics_invited_new_start, $pk_statistics_invited_new_end),
  353. // 业绩数据报表 22
  354. 'performance_chart' => self::pkPerformanceCountByDay($mall_id, $pk_statistics_performance_start, $pk_statistics_performance_end),
  355. );
  356. break;
  357. case 'pk_statistics.invited_new_user_chart' :
  358. $return['pk_statistics'] = array(
  359. // 拉新数据报表 22
  360. 'invited_new_user_chart' => self::pkInvitedNewUserCountByDay($mall_id, $pk_statistics_invited_new_start, $pk_statistics_invited_new_end),
  361. );
  362. break;
  363. case 'pk_statistics.performance_chart' :
  364. $return['pk_statistics'] = array(
  365. // 业绩数据报表 22
  366. 'performance_chart' => self::pkPerformanceCountByDay($mall_id, $pk_statistics_performance_start, $pk_statistics_performance_end),
  367. );
  368. break;
  369. case 'rank' :
  370. $return['rank'] = array(
  371. 'personal' => self::getPerformanceRank($mall_id, $personal_activity_id, $topn),
  372. 'team' => [],
  373. );
  374. break;
  375. }
  376. return $return;
  377. }
  378. }