Visit.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace app\model\system;
  11. use think\facade\Cache;
  12. use think\Session;
  13. use think\facade\Db;
  14. use app\model\BaseModel;
  15. /**
  16. * 访问统计
  17. */
  18. class Visit extends BaseModel
  19. {
  20. /**
  21. * 获取访问信息(以日为基本单位)
  22. * @param $condition
  23. * @return \multitype
  24. */
  25. public function getVisitInfo($condition)
  26. {
  27. $site_id = isset($condition["site_id"]) ? $condition["site_id"] : 0;
  28. $cache = Cache::get("visit_info_" . $site_id . "_" . $condition["type"] . "_" . $condition["module"] . "_" . $condition["addon"] . "_" . $condition["date"]);
  29. if (!empty($cache)) {
  30. return $this->success($cache);
  31. }
  32. $visit_model = model("nc_visit");//访问统计记录表
  33. $info = $visit_model->getInfo($condition);
  34. Cache::tag("visit_info" . $condition["date"])->set("visit_info_" . $site_id . "_" . $condition["type"] . "_" . $condition["module"] . "_" . $condition["addon"] . "_" . $condition["date"], $info);
  35. return $this->success($info);
  36. }
  37. /**
  38. * 获取访问ip信息(以日为基本单位)
  39. * @param $condition
  40. * @return \multitype
  41. */
  42. public function getVisitIpInfo($condition)
  43. {
  44. $site_id = isset($condition["site_id"]) ? $condition["site_id"] : 0;
  45. $cache = Cache::get("visit_ip_info_" . $site_id . "_" . $condition["type"] . "_" . $condition["module"] . "_" . $condition["addon"] . "_" . $condition["ip"] . "_" . $condition["date"]);
  46. if (!empty($cache)) {
  47. return $this->success($cache);
  48. }
  49. $visit_ip_model = model("nc_visit_ip");//访问统计记录表
  50. $info = $visit_ip_model->getInfo($condition);
  51. Cache::tag("visit_ip_info" . $condition["date"])->set("visit_ip_info_" . $site_id . "_" . $condition["type"] . "_" . $condition["module"] . "_" . $condition["addon"] . "_" . $condition["ip"] . "_" . $condition["date"], $info);
  52. return $this->success($info);
  53. }
  54. /**
  55. * 获取用户访问记录
  56. * @param $condition
  57. * @return \multitype
  58. */
  59. public function getVisitUserInfo($condition)
  60. {
  61. $site_id = isset($condition["site_id"]) ? $condition["site_id"] : 0;
  62. $cache = Cache::get("visit_user_info_" . $site_id . "_" . $condition["uid"] . "_" . $condition["module"] . "_" . $condition["addon"]);
  63. if (!empty($cache)) {
  64. return $this->success($cache);
  65. }
  66. $visit_user_model = model("nc_visit_user");//用户访问记录表
  67. $info = $visit_user_model->getInfo($condition);
  68. Cache::tag("visit_user_info" . $condition["site_id"])->set("visit_user_info_" . $site_id . "_" . $condition["uid"] . "_" . $condition["module"] . "_" . $condition["addon"], $info);
  69. return $this->success($info);
  70. }
  71. /**
  72. * 当日的访问数据写入
  73. * @param array $param
  74. */
  75. public function todayVisit($param = [])
  76. {
  77. //加入防止写入过多无效访问
  78. $now_time = time();
  79. $today_date = date("Ymd");
  80. $expire_time = 1800;//过期的周期时长
  81. $visit_session_name = "visit_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $today_date;
  82. if (!empty(Session::get($visit_session_name)) && (Session::get($visit_session_name) + $expire_time) > $now_time) {
  83. return $this->success();
  84. }
  85. Session::set($visit_session_name, $now_time);//设置访问记录,存入时间
  86. $yesterday = date("Ymd", strtotime('-1 days'));
  87. Cache::clear("visit_info" . $yesterday);//清理昨天的缓存
  88. Cache::clear("visit_ip_info" . $yesterday);//清理昨天的缓存
  89. $visit_model = model("nc_visit");//访问统计记录表
  90. $visit_ip_model = model("nc_visit_ip");//ip访问记录表
  91. $visit_user_model = model("nc_visit_user");//用户模块访问记录表
  92. // 启动事务
  93. $ip_count = 0;
  94. //ip访问记录
  95. $ip = ip2long(getip());
  96. $vivit_ip_condition = array(
  97. "date" => $today_date,
  98. "site_id" => $param["site_id"],
  99. "type" => $param["type"],
  100. "module" => $param["module"],
  101. "ip" => $ip,
  102. "addon" => $param["addon"]
  103. );
  104. $visit_ip_result = $this->getVisitIpInfo($vivit_ip_condition);
  105. $visit_ip_info = $visit_ip_result["data"];
  106. $ip_data = array(
  107. "date" => $today_date,
  108. "site_id" => $param["site_id"],
  109. "type" => $param["type"],
  110. "module" => $param["module"],
  111. "ip" => $ip,
  112. "addon" => $param["addon"]
  113. );
  114. if (empty($visit_ip_info)) {
  115. $ip_count += 1;
  116. $ip_data["ip_count"] = 1;
  117. $visit_ip_res = $visit_ip_model->add($ip_data);
  118. } else {
  119. $ip_data["ip_count"] = $visit_ip_info["ip_count"] + 1;
  120. $visit_ip_res = $visit_ip_model->update($ip_data, $vivit_ip_condition);
  121. }
  122. Cache::tag("visit_ip_info" . $today_date)->set("visit_ip_info_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $ip["ip"] . "_" . $today_date, $ip_data);
  123. //用户模块访问记录
  124. if ($param["uid"] > 0) {
  125. $visit_user_condition = array(
  126. "uid" => $param["uid"],
  127. "site_id" => $param["site_id"],
  128. "module" => $param["module"],
  129. "addon" => $param["addon"]
  130. );
  131. $visit_user_result = $this->getVisitUserInfo($visit_user_condition);
  132. $visit_user_info = $visit_user_result["data"];
  133. $visit_user_data = array(
  134. "uid" => $param["uid"],
  135. "site_id" => $param["site_id"],
  136. "module" => $param["module"],
  137. "addon" => $param["addon"]
  138. );
  139. if (empty($visit_user_info)) {
  140. $visit_user_data["create_time"] = time();
  141. $visit_user_result = $visit_user_model->add($visit_user_data);
  142. } else {
  143. $visit_user_data["update_time"] = time();
  144. $visit_user_result = $visit_user_model->update($visit_user_data, $visit_user_condition);
  145. }
  146. Cache::tag("visit_user_info" . $param["site_id"])->set("visit_user_info_" . $param["site_id"] . "_" . $param["uid"] . "_" . $param["module"] . "_" . $param["addon"], $visit_user_data);
  147. }
  148. //访问记录
  149. $vivit_condition = array(
  150. "date" => $today_date,
  151. "site_id" => $param["site_id"],
  152. "type" => $param["type"],
  153. "module" => $param["module"],
  154. "addon" => $param["addon"]
  155. );
  156. $visit_result = $this->getVisitInfo($vivit_condition);
  157. $visit_info = $visit_result["data"];
  158. //如果当前日不存在访问统计数据,则需要创建
  159. $data = array(
  160. "date" => $today_date,
  161. "site_id" => $param["site_id"],
  162. "type" => $param["type"],
  163. "module" => $param["module"],
  164. "addon" => $param["addon"]
  165. );
  166. if (empty($visit_info)) {
  167. $data["count"] = 1;
  168. $data["ip_count"] = $ip_count;
  169. $res = $visit_model->add($data);
  170. } else {
  171. $data["count"] = $visit_info["count"] + 1;
  172. $data["ip_count"] = $visit_info["ip_count"] + $ip_count;
  173. $res = $visit_model->update($data, $vivit_condition);
  174. }
  175. Cache::tag("visit_info" . $today_date)->set("visit_info_" . $param["site_id"] . "_" . $param["type"] . "_" . $param["module"] . "_" . $param["addon"] . "_" . $today_date, $data);
  176. return $res;
  177. }
  178. /**
  179. * 查询统计 访问数据
  180. * @param array $param
  181. */
  182. public function getVisitStatisticsData($param = [])
  183. {
  184. $visit_model = model("nc_visit");//访问统计记录表
  185. $date_range = isset($param["date_range"]) ? $param["date_range"] : [];//时间范围
  186. $date_type = $param["date_type"];//日期类型 用于查询方式
  187. $type = $param["type"];//访问类型查询
  188. if (empty($type) && !in_array($type, array('HOME', 'APP', 'API', 'ALL'))) {
  189. $type = "ALL";
  190. }
  191. $condition = array();
  192. switch ($type) {
  193. case "HOME":
  194. $condition["type"] = ["in", ["admin", "sitehome"]];
  195. break;
  196. case "APP":
  197. $condition["type"] = ["in", ["wap", "web"]];
  198. break;
  199. case "API":
  200. $condition["type"] = ["in", ["api"]];
  201. break;
  202. }
  203. //站点id
  204. if (!empty($param["site_id"])) {
  205. $condition["site_id"] = $param["site_id"];
  206. }
  207. $today_date = date('Ymd');//当前日日期
  208. $today_time = strtotime($today_date);
  209. switch ($date_type) {
  210. case 'today':
  211. $date_condition = $today_date;
  212. $date_x = periodGroup($today_time, $today_time);
  213. break;
  214. case 'yesterday':
  215. $yesterday = strtotime(date("Ymd", strtotime('-1 days')));
  216. $date_condition = date('Ymd', $yesterday);
  217. $date_x = periodGroup($yesterday, $yesterday);
  218. break;
  219. case 'week':
  220. $week = strtotime(date("Ymd", strtotime('-6 days')));
  221. $date_condition = ["between", [date('Ymd', $week), $today_date]];
  222. $date_x = periodGroup($week, $today_date);
  223. break;
  224. case 'month':
  225. $month = strtotime(date("Ymd", strtotime('-29 days')));
  226. $date_condition = ["between", [date('Ymd', $month), $today_date]];
  227. $date_x = periodGroup($month, $today_time);
  228. break;
  229. case 'daterange':
  230. $start_time = strtotime($date_range['start_date']);
  231. $end_time = strtotime($date_range['end_date']);
  232. $start_date = date('Ymd', $start_time);//开始日期
  233. $end_date = date('Ymd', $end_time);//结束日期
  234. $date_x = periodGroup($start_time, $end_time);
  235. $date_condition = ["between", [$start_date, $end_date]];
  236. break;
  237. }
  238. if (!empty($date_condition)) {
  239. $condition["date"] = $date_condition;
  240. }
  241. $data1 = $visit_model->getList($condition, "*,sum(count) as visit_count", '', '', '', "date");
  242. $visit_ip_model = model("nc_visit_ip");//访问统计记录表
  243. $data2 = $visit_ip_model->getList($condition, "*,count( DISTINCT ip ) as visit_ip_count", '', '', '', "date");
  244. $visit_data = [];
  245. $ip_visit_data = [];
  246. foreach ($date_x as $k => $v) {
  247. $visit_count = 0;
  248. $visit_ip_count = 0;
  249. foreach ($data1 as $data1_k => $data1_v) {
  250. if ($data1_v["date"] == $v) {
  251. $visit_count = $data1_v["visit_count"];
  252. continue;
  253. }
  254. }
  255. foreach ($data2 as $data2_k => $data2_v) {
  256. if ($data2_v["date"] == $v) {
  257. $visit_ip_count = $data2_v["visit_ip_count"];
  258. continue;
  259. }
  260. }
  261. $visit_data[] = $visit_count;
  262. $ip_visit_data[] = $visit_ip_count;
  263. }
  264. $data = array(
  265. "date" => $date_x,
  266. "data" => array(
  267. "count_data" => $visit_data,
  268. "ip_count_data" => $ip_visit_data,
  269. )
  270. );
  271. return $this->success($data);
  272. }
  273. /**
  274. * 统计一段时间内的总访问量
  275. * @param $param
  276. * @return \multitype
  277. */
  278. public function getVisitCountData($param)
  279. {
  280. $visit_model = Db::table("nc_visit");//访问统计记录表
  281. $date_range = isset($param["date_range"]) ? $param["date_range"] : [];//时间范围
  282. $date_type = $param["date_type"];//日期类型 用于查询方式
  283. $type = isset($param["type"]) ? $param["type"] : '';//访问类型查询
  284. if (empty($type) && !in_array($type, array('HOME', 'APP', 'API', 'ALL'))) {
  285. $type = "ALL";
  286. }
  287. $condition = array();
  288. if ($type != "ALL") {
  289. $condition["type"] = $type;
  290. $visit_model = $visit_model->where("type", $type);
  291. }
  292. //站点id
  293. if (!empty($param["site_id"])) {
  294. $condition["site_id"] = $param["site_id"];
  295. $visit_model = $visit_model->where("site_id", $param["site_id"]);
  296. }
  297. $today_date = date('Ymd');//当前日日期
  298. switch ($date_type) {
  299. case 'today':
  300. $visit_model = $visit_model->where("date", $today_date);
  301. break;
  302. case 'yesterday':
  303. $visit_model = $visit_model->where("date", strtotime('-1 days'));
  304. break;
  305. case 'week':
  306. $visit_model = $visit_model->whereBetween("date", date('Ymd', strtotime('-6 days')), $today_date);
  307. break;
  308. case 'month':
  309. $visit_model = $visit_model->whereBetween("date", date('Ymd', strtotime('-29 days')), $today_date);
  310. break;
  311. case 'daterange':
  312. $start_date = date('Ymd', strtotime($date_range['start_date']));//开始日期
  313. $end_date = date('Ymd', strtotime($date_range['end_date']));//结束日期
  314. $visit_model = $visit_model->whereBetween("date", $start_date, $end_date);
  315. break;
  316. }
  317. $visit_count = $visit_model->count();
  318. $visit_ip_model = model("nc_visit_ip");//访问统计记录表
  319. $visit_ip_result = $visit_ip_model->getInfo($condition, "count( DISTINCT ip ) as ip_count");
  320. $visit_ip_count = $visit_ip_result["ip_count"];
  321. $data = array(
  322. "visit_count" => $visit_count,
  323. "visit_ip_count" => $visit_ip_count
  324. );
  325. return $this->success($data);
  326. }
  327. public function test()
  328. {
  329. $arr = array('HOME', 'APP', 'API');
  330. for ($i = 0; $i <= 100; $i++) {
  331. $param["type"] = $arr[array_rand($arr)];
  332. $param["site_id"] = rand(11111, 12000);
  333. $param["module"] = "";
  334. $num = sprintf("%02d", rand(1, 30));
  335. $today_date = date("Ym" . $num);
  336. $visit_model = model("nc_visit");//访问统计记录表
  337. $visit_ip_model = model("nc_visit_ip");//ip访问记录表
  338. // 启动事务
  339. $ip_count = 0;
  340. //ip访问记录
  341. $ip = ip2long($this->get_rand_ip());
  342. $vivit_ip_condition = array(
  343. "date" => $today_date,
  344. "site_id" => $param["site_id"],
  345. "type" => $param["type"],
  346. "module" => $param["module"],
  347. "ip" => $ip
  348. );
  349. $visit_ip_info = $visit_ip_model->getInfo($vivit_ip_condition);
  350. if (empty($visit_ip_info)) {
  351. $ip_count += 1;
  352. $ip_data = array(
  353. "date" => $today_date,
  354. "site_id" => $param["site_id"],
  355. "type" => $param["type"],
  356. "module" => $param["module"],
  357. "ip" => $ip,
  358. "ip_count" => 1
  359. );
  360. $visit_ip_res = $visit_ip_model->add($ip_data);
  361. } else {
  362. $ip_data = array(
  363. "ip_count" => $visit_ip_info["ip_count"] + 1
  364. );
  365. $visit_ip_res = $visit_ip_model->update($ip_data, $vivit_ip_condition);
  366. }
  367. //访问记录
  368. $vivit_condition = array(
  369. "date" => $today_date,
  370. "site_id" => $param["site_id"],
  371. "type" => $param["type"],
  372. "module" => $param["module"]
  373. );
  374. $visit_info = $visit_model->getInfo($vivit_condition);
  375. //如果当前日不存在访问统计数据,则需要创建
  376. if (empty($visit_info)) {
  377. $data = array(
  378. "date" => $today_date,
  379. "site_id" => $param["site_id"],
  380. "type" => $param["type"],
  381. "module" => $param["module"],
  382. "count" => 1,
  383. "ip_count" => $ip_count
  384. );
  385. $res = $visit_model->add($data);
  386. } else {
  387. $data = array(
  388. "count" => $visit_info["count"] + 1,
  389. "ip_count" => $visit_info["ip_count"] + $ip_count
  390. );
  391. $visit_model->update($data, $vivit_condition);
  392. }
  393. }
  394. }
  395. function get_rand_ip()
  396. {
  397. $arr_1 = array("218", "218", "66", "66", "218", "218", "60", "60", "202", "204", "66", "66", "66", "59", "61", "60", "222", "221", "66", "59", "60", "60", "66", "218", "218", "62", "63", "64", "66", "66", "122", "211");
  398. $randarr = mt_rand(0, count($arr_1));
  399. // $ip1id = $arr_1[$randarr];
  400. $ip1id = "218";
  401. $ip2id = 600000 / 10000;
  402. $ip3id = 2550000 / 10000;
  403. $ip4id = 2550000 / 10000 - rand(0, 10);
  404. return $ip1id . "." . $ip2id . "." . $ip3id . "." . $ip4id;
  405. }
  406. /**
  407. * 获取时间段内分组
  408. */
  409. public function periodGroup($srart_time, $end_time)
  410. {
  411. $type_time = 3600 * 24;
  412. $format = 'Ymd';
  413. $data = [];
  414. for ($i = $srart_time; $i <= $end_time; $i += $type_time) {
  415. $data[] = date($format, $i);
  416. }
  417. return $data;
  418. }
  419. /**
  420. * 删除站点
  421. * @param unknown $site_id
  422. */
  423. public function deleteSite($site_id)
  424. {
  425. $visit_model = model("nc_visit");//访问统计记录表
  426. $visit_ip_model = model("nc_visit_ip");//ip访问记录表
  427. $visit_user_model = model("nc_visit_user");//用户模块访问记录表
  428. $visit_model->delete(['site_id' => $site_id]);
  429. $visit_ip_model->delete(['site_id' => $site_id]);
  430. $visit_user_model->delete(['site_id' => $site_id]);
  431. return $this->success();
  432. }
  433. }