PostVisitRecordInsight.cshtml 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. @model Masuit.MyBlogs.Core.Models.Entity.Post
  2. @{
  3. Layout = null;
  4. }
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <meta charset="utf-8">
  9. <title>文章《@Model.Title》洞察分析</title>
  10. <meta content="webkit" name="renderer">
  11. <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
  12. <meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
  13. <link href="/Assets/layui/css/layui.min.css" media="all" rel="stylesheet">
  14. <link href="https://cdn.jsdelivr.net/gh/abodelot/jquery.json-viewer@master/json-viewer/jquery.json-viewer.css" media="all" rel="stylesheet">
  15. <style>
  16. .mp-results.mp-bottomleft {
  17. top: unset !important;
  18. bottom: 0;
  19. }
  20. </style>
  21. </head>
  22. <body style="overflow-x: hidden">
  23. <h3 align="center">文章《@Model.Title》洞察分析</h3>
  24. <div class="searchTable">
  25. <div class="layui-inline">
  26. <input class="layui-input" name="kw" id="kw">
  27. </div>
  28. <button class="layui-btn" data-type="reload">搜索</button>
  29. </div>
  30. <table class="layui-hide" id="table" lay-filter="tableEvent"></table>
  31. <div id="chart" style="height: 500px"></div>
  32. <mini-profiler max-traces="5" />
  33. </body>
  34. </html>
  35. <script type="text/html" id="actionButton">
  36. <a class="layui-btn layui-btn-xs" lay-event="showjson">查看</a>
  37. </script>
  38. <script src="https://cdn.staticfile.org/jquery/3.6.0/jquery.min.js"></script>
  39. <script src="/Assets/layui/layui.js"></script>
  40. <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js" type="text/javascript"></script>
  41. <script src="https://cdn.jsdelivr.net/gh/abodelot/jquery.json-viewer@master/json-viewer/jquery.json-viewer.js" type="text/javascript"></script>
  42. <script>
  43. layui.use('table', function() {
  44. var table = layui.table;
  45. table.render({
  46. elem: '#table',
  47. url: '/@Model.Id/records',
  48. cellMinWidth: 80, //全局定义常规单元格的最小宽度,layui 2.2.1 新增
  49. cols: [
  50. [
  51. { field: 'IP', title: 'IP', align: 'center', event: 'tool-ip', width:320 },
  52. { field: 'Location', title: '位置和网络', align: 'center'},
  53. { field: 'RequestUrl', title: '请求URL', align: 'center' },
  54. { field: 'Referer', title: '页面来源', align: 'center', event: 'visit' },
  55. { field: 'Time', title: '访问时间', align: 'center',width:180 },
  56. { title:'请求头', toolbar: '#actionButton',width:80 }
  57. ]
  58. ],
  59. page: true,
  60. limit:20,
  61. request: {
  62. limitName: 'size' //每页数据量的参数名,默认:limit
  63. },
  64. parseData: function(res) { //res 即为原始返回的数据
  65. return {
  66. "code": res.TotalCount > 0 ? 0 : 1, //解析接口状态
  67. "msg": "暂无数据", //解析提示文本
  68. "count": res.TotalCount, //解析数据长度
  69. "data": res.Data //解析数据列表
  70. };
  71. }
  72. });
  73. table.on('tool(tableEvent)', function(obj){
  74. var data = obj.data;
  75. if(obj.event === 'tool-ip'){
  76. window.open("/tools/ip/"+data.IP);
  77. }
  78. if(obj.event === 'visit'){
  79. window.open(data.Referer);
  80. }
  81. if(obj.event === 'showjson'){
  82. layer.open({
  83. type: 1,
  84. area: ['600px', '80%'], //宽高
  85. content: ""+data.RequestHeader
  86. });
  87. $('.layui-layer-content').jsonViewer(eval("("+data.RequestHeader+")"), {withQuotes: true, withLinks: true});
  88. $('.layui-layer-content').css("word-wrap"," break-word");
  89. }
  90. });
  91. var $ = layui.$;
  92. $('.searchTable .layui-btn').on('click', function () {
  93. table.reload('table', {
  94. page: {
  95. curr: 1
  96. },
  97. where: {
  98. kw: $('#kw').val()
  99. }
  100. });
  101. });
  102. });
  103. window.fetch("/@Model.Id/records-chart", {
  104. credentials: 'include',
  105. method: 'GET',
  106. mode: 'cors'
  107. }).then(function(response) {
  108. return response.json();
  109. }).then(function(res) {
  110. var data = [];
  111. for (let item of res) {
  112. data.push([Date.parse(item.Date), item.Count]);
  113. }
  114. var chartDom = document.getElementById('chart');
  115. var myChart = echarts.init(chartDom);
  116. var option = {
  117. tooltip: {
  118. trigger: 'axis',
  119. position: function(pt) {
  120. return [pt[0], '10%'];
  121. }
  122. },
  123. title: {
  124. left: 'center',
  125. text: '最近90天访问趋势,日均:' + (res.reduce((acr, cur) => acr + cur.Count, 0) / (new Date() - new Date(res[0].Date)) * (1000 * 60 * 60 * 24)).toFixed(2)
  126. },
  127. xAxis: {
  128. type: 'time',
  129. axisLabel: {
  130. formatter:function (value){
  131. var dt=new Date(value);
  132. return dt.toLocaleDateString();
  133. }
  134. }
  135. },
  136. yAxis: {
  137. type: 'value'
  138. },
  139. series: [
  140. {
  141. name: '访问量',
  142. type: 'line',
  143. smooth: true,
  144. symbol: 'none',
  145. areaStyle: {},
  146. data: data,
  147. markPoint: {
  148. data: [
  149. { type: 'max', name: '最大值' },
  150. { type: 'min', name: '最小值' }
  151. ]
  152. },
  153. markLine: {
  154. data: [
  155. { type: 'average', name: '平均值' }
  156. ]
  157. }
  158. }
  159. ]
  160. };
  161. myChart.setOption(option);
  162. });
  163. </script>