diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1193bd4..72746e6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -70,4 +70,4 @@ jobs:
run: |
docker buildx imagetools create \
--tag registry.cn-shanghai.aliyuncs.com/clklog/accesslog-ui:${{ steps.set-tag.outputs.tag }} \
- zcunsoft/accesslog-ui:${{ steps.set-tag.outputs.tag }}
+ zcunsoft/accesslog-ui:${{ steps.set-tag.outputs.tag }}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index eb3b923..c680021 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
-FROM nginx:alpine
+FROM nginx:1.20-alpine
ARG HTML_DIR
-COPY ${HTML_DIR} /usr/share/nginx/html
\ No newline at end of file
+COPY ${HTML_DIR} /usr/share/nginx/html
diff --git a/mock/role/index.js b/mock/role/index.js
index 8730e22..7b504c7 100644
--- a/mock/role/index.js
+++ b/mock/role/index.js
@@ -6,33 +6,11 @@ const routes = deepClone([...constantRoutes, ...asyncRoutes])
const roles = [
{
- key: 'admin',
- name: 'admin',
- description: 'Super Administrator. Have Tracking to view all pages.',
+ key: 'accesslog',
+ name: 'accesslog',
+ description: 'Accesslog Administrator. Have Tracking to view all pages.',
routes: routes
},
- {
- key: 'editor',
- name: 'editor',
- description: 'Normal Editor. Can see all pages except permission page',
- routes: routes.filter(i => i.path !== '/permission')// just a mock
- },
- {
- key: 'visitor',
- name: 'visitor',
- description: 'Just a visitor. Can only see the home page and the document page',
- routes: [{
- path: '',
- redirect: 'dashboard',
- children: [
- {
- path: 'dashboard',
- name: 'Dashboard',
- meta: { title: 'dashboard', icon: 'dashboard' }
- }
- ]
- }]
- }
]
module.exports = [
diff --git a/mock/role/routes.js b/mock/role/routes.js
index d33f162..2c3ce9c 100644
--- a/mock/role/routes.js
+++ b/mock/role/routes.js
@@ -81,7 +81,7 @@ const asyncRoutes = [
meta: {
title: 'Permission',
icon: 'lock',
- roles: ['admin', 'editor']
+ roles: ['accesslog']
},
children: [
{
@@ -90,7 +90,7 @@ const asyncRoutes = [
name: 'PagePermission',
meta: {
title: 'Page Permission',
- roles: ['admin']
+ roles: ['accesslog']
}
},
{
@@ -107,7 +107,7 @@ const asyncRoutes = [
name: 'RolePermission',
meta: {
title: 'Role Permission',
- roles: ['admin']
+ roles: ['accesslog']
}
}
]
diff --git a/mock/user.js b/mock/user.js
index 6ac1e9e..7e03cb6 100644
--- a/mock/user.js
+++ b/mock/user.js
@@ -1,25 +1,16 @@
const tokens = {
- admin: {
+ accesslog: {
token: 'admin-token'
- },
- editor: {
- token: 'editor-token'
}
}
const users = {
'admin-token': {
- roles: ['admin'],
+ roles: ['accesslog'],
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
- },
- 'editor-token': {
- roles: ['editor'],
- introduction: 'I am an editor',
- avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
- name: 'Normal Editor'
}
}
@@ -36,7 +27,7 @@ module.exports = [
if (!token) {
return {
code: 60204,
- message: 'Account and password are incorrect.'
+ message: '当前账号不存在'
}
}
diff --git a/package-lock.json b/package-lock.json
index be9ebbd..415ce52 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4622,7 +4622,8 @@
"dev": true,
"optional": true,
"requires": {
- "bindings": "^1.5.0"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
}
},
"glob-parent": {
@@ -10302,7 +10303,8 @@
"dev": true,
"optional": true,
"requires": {
- "bindings": "^1.5.0"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
}
},
"normalize-path": {
@@ -11945,6 +11947,11 @@
"commander": "*"
}
},
+ "moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="
+ },
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -11997,6 +12004,13 @@
"thenify-all": "^1.0.0"
}
},
+ "nan": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmmirror.com/nan/-/nan-2.19.0.tgz",
+ "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==",
+ "dev": true,
+ "optional": true
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmmirror.com/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -18006,7 +18020,8 @@
"dev": true,
"optional": true,
"requires": {
- "bindings": "^1.5.0"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
}
},
"glob-parent": {
@@ -18327,7 +18342,8 @@
"dev": true,
"optional": true,
"requires": {
- "bindings": "^1.5.0"
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
}
},
"glob-parent": {
diff --git a/package.json b/package.json
index b48e244..208cafd 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"js-cookie": "2.2.0",
"jsonlint": "1.6.3",
"jszip": "3.2.1",
+ "moment": "^2.30.1",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
diff --git a/src/api/trackingapi/abnormal.js b/src/api/trackingapi/abnormal.js
index f31e333..41a4527 100644
--- a/src/api/trackingapi/abnormal.js
+++ b/src/api/trackingapi/abnormal.js
@@ -25,11 +25,11 @@ export function getExceptionIpApi(params) {
data: params
})
}
-// 状态码详情
-export function getStatusDetailApi(params) {
- return request({
- url: '/accesslog/status/getStatusDetail',
- method: 'post',
- data: params
- })
-}
+// // 状态码详情
+// export function getStatusDetailApi(params) {
+// return request({
+// url: '/accesslog/status/getStatusDetail',
+// method: 'post',
+// data: params
+// })
+// }
diff --git a/src/api/trackingapi/accessLog.js b/src/api/trackingapi/accessLog.js
index 9475022..f1ceea1 100644
--- a/src/api/trackingapi/accessLog.js
+++ b/src/api/trackingapi/accessLog.js
@@ -35,23 +35,6 @@ export function getFlowTrendApi(params) {
})
}
-// 获取耗时TOP10数据
-export function getRequestTimeTop10Api(params) {
- return request({
- url: '/accesslog/getRequestTimeTop10',
- method: 'post',
- data: params
- })
-}
-
-// 获取访问TOP10数据
-export function getUriTop10Api(params) {
- return request({
- url: '/accesslog/getUriTop10',
- method: 'post',
- data: params
- })
-}
// 获取IP访问量TOP10数据
export function getIpTop10Api(params) {
return request({
@@ -103,14 +86,9 @@ export function getIpByProvinceApi(params) {
})
}
-
-
-// ------------------------------------------------------
-
// 按应用流量指标概览
export function getHostOverviewApi(params) {
return request({
- // url: '/accesslog/getHostOverview',
url: '/getHostOverview',
method: 'post',
data: params
@@ -119,7 +97,6 @@ export function getHostOverviewApi(params) {
// 指标概览
export function getOverviewApi(params) {
return request({
- // url: '/accesslog/getOverview',
url: '/getOverview',
method: 'post',
data: params
@@ -133,11 +110,29 @@ export function getPerformanceDetailApi(params) {
data: params
})
}
-//状态码分析
-// export function getStatusApi(params) {
-// return request({
-// url: '/getStatus',
-// method: 'post',
-// data: params
-// })
-// }
+//获取ip列表
+export function getIpListApi(params) {
+ return request({
+ url: '/accesslog/ip/getIpList',
+ method: 'post',
+ data: params
+ })
+}
+
+//按地域获取IP分布统计数据
+export function getIpByAreaApi(params) {
+ return request({
+ url: '/accesslog/ip/getIpByArea',
+ method: 'post',
+ data: params
+ })
+}
+
+//获取ip详情列表
+export function getIpDetailListApi(params) {
+ return request({
+ url: '/accesslog/ip/getIpDetailList',
+ method: 'post',
+ data: params
+ })
+}
diff --git a/src/api/trackingapi/performance.js b/src/api/trackingapi/performance.js
index 2a7b2a5..01b02d3 100644
--- a/src/api/trackingapi/performance.js
+++ b/src/api/trackingapi/performance.js
@@ -9,10 +9,18 @@ export function getRequestimeGt100msApi(params) {
data: params
})
}
-// 性能分析详情
+// 性能分析详情弃用
+// export function getPerformanceDetailApi(params) {
+// return request({
+// url: '/accesslog/performance/getPerformanceDetail',
+// method: 'post',
+// data: params
+// })
+// }
+// 获取Uri列表
export function getPerformanceDetailApi(params) {
return request({
- url: '/accesslog/performance/getPerformanceDetail',
+ url: '/accesslog/uri/getUriList',
method: 'post',
data: params
})
diff --git a/src/api/trackingapi/status.js b/src/api/trackingapi/status.js
index 5ef2373..34d504b 100644
--- a/src/api/trackingapi/status.js
+++ b/src/api/trackingapi/status.js
@@ -1,14 +1,4 @@
import request from '@/utils/request'
-
-
-// 状态码数据图表
-export function getStatusApi(params) {
- return request({
- url: '/accesslog/status/getStatus',
- method: 'post',
- data: params
- })
-}
// 状态码列表
export function getStatusListApi(params) {
return request({
@@ -26,10 +16,10 @@ export function getStatusFlowTrendApi(params) {
})
}
// 状态码详情
-export function getStatusDetailApi(params) {
- return request({
- url: '/accesslog/status/getStatusDetail',
- method: 'post',
- data: params
- })
-}
\ No newline at end of file
+// export function getStatusDetailApi(params) {
+// return request({
+// url: '/accesslog/status/getStatusDetail',
+// method: 'post',
+// data: params
+// })
+// }
\ No newline at end of file
diff --git a/src/assets/images/qrcode.jpg b/src/assets/images/qrcode.jpg
new file mode 100644
index 0000000..b78b90e
Binary files /dev/null and b/src/assets/images/qrcode.jpg differ
diff --git a/src/assets/images/qrcode.png b/src/assets/images/qrcode.png
deleted file mode 100644
index 92c36c5..0000000
Binary files a/src/assets/images/qrcode.png and /dev/null differ
diff --git a/src/components/Charts/LineMarker.vue b/src/components/Charts/LineMarker.vue
index 5e5dafb..3e46171 100644
--- a/src/components/Charts/LineMarker.vue
+++ b/src/components/Charts/LineMarker.vue
@@ -143,7 +143,12 @@ export default {
this.initChart();
},
initChart() {
- this.chart = echarts.init(document.getElementById(this.id));
+ const chartDom = document.getElementById(this.id);
+ if (!chartDom) {
+ console.warn(`Chart DOM element with id ${this.id} not found`);
+ return;
+ }
+ this.chart = echarts.init(chartDom);
this.chart.setOption({
backgroundColor: "#fff",
diff --git a/src/components/Charts/pieMarker.vue b/src/components/Charts/pieMarker.vue
index 2777435..9fbad11 100644
--- a/src/components/Charts/pieMarker.vue
+++ b/src/components/Charts/pieMarker.vue
@@ -55,7 +55,12 @@ export default {
this.initChart();
},
initChart() {
- this.chart = echarts.init(document.getElementById(this.id));
+ const chartDom = document.getElementById(this.id);
+ if (!chartDom) {
+ console.warn(`图表DOM元素(id: ${this.id})不存在,跳过ECharts初始化`);
+ return;
+ }
+ this.chart = echarts.init(chartDom);
this.chart.setOption({
title: {
left: "center",
diff --git a/src/filters/index.js b/src/filters/index.js
index aa1916a..ebb56ea 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -375,3 +375,59 @@ export function toThousandFilter(num) {
export function uppercaseFirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
+// 当前日期
+export function formatDateToday() {
+ const currentDate = new Date();
+ const year = currentDate.getFullYear();
+ const month = String(currentDate.getMonth() + 1).padStart(2, "0"); // 月份是从0开始计数的,需要加1
+ const day = String(currentDate.getDate()).padStart(2, "0");
+ const formattedDate = `${year}-${month}-${day}`;
+ return formattedDate;
+}
+// 获取当前小时的方式
+export function getCurrentHour() {
+ const currentDate = new Date();
+ let currentHour = currentDate.getHours();
+
+ // 如果当前小时小于 10,则在前面添加 0
+ currentHour = currentHour < 10 ? "0" + currentHour : currentHour;
+
+ return currentHour;
+}
+export function formatTimeTable(seconds) {
+ if (seconds) {
+ seconds = Math.floor(seconds);
+ var hours = Math.floor(seconds / 3600);
+ var minutes = Math.floor((seconds - hours * 3600) / 60);
+ var seconds = seconds - hours * 3600 - minutes * 60;
+
+ if (hours < 10) {
+ hours = "0" + hours;
+ }
+ if (minutes < 10) {
+ minutes = "0" + minutes;
+ }
+ if (seconds < 10) {
+ seconds = "0" + seconds;
+ }
+ return hours + ":" + minutes + ":" + seconds;
+ } else {
+ return 0;
+ }
+}
+// 获取当前日期年月日------
+export function todateFunc() {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = today.getMonth() + 1;
+ const day = today.getDate();
+ return `${year}-${month < 10 ? '0' + month : month }-${day < 10 ? '0' + day : day}`;
+}
+// 时间戳转换为年月日---------
+export function timeStampFunc(timestamp) {
+ const date = new Date(timestamp);
+ const year = date.getFullYear();
+ const month = (date.getMonth() + 1).toString().padStart(2, "0");
+ const day = date.getDate().toString().padStart(2, "0");
+ return `${year}-${month}-${day}`;
+}
\ No newline at end of file
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index a4f6dc6..643d199 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -121,7 +121,7 @@ export default {
if (res.code == 200) {
const originalArray = res.data;
this.options = originalArray.map((item) => {
- return { ["label"]: "application-name:" + item, ["value"]: item };
+ return { ["label"]: "应用名称:" + item, ["value"]: item };
});
if (this.options.length > 0) {
this.serveValue = this.options[0].value;
@@ -181,7 +181,7 @@ export default {
height: 50px;
margin-left: 20px;
.custom_select {
- width: 230px;
+ width: 180px;
::v-deep {
.el-select .el-input.is-focus .el-input__inner {
background-color: #fff !important;
diff --git a/src/layout/components/filterBar/dialogBar.vue b/src/layout/components/filterBar/dialogBar.vue
new file mode 100644
index 0000000..09cdbeb
--- /dev/null
+++ b/src/layout/components/filterBar/dialogBar.vue
@@ -0,0 +1,1174 @@
+
+
+
+
+
+ 时间:
+
+ 今日
+ 昨日
+ 近7天
+ 近30天
+
+
+
+
+
+
+
+
+
+
地域
+
+
+
+
+ {{ item.provinceName }}
+
+
X
+
+
+ {{ areaValue }}
+
+
+
+
+
+
+
+
+
+ {{
+ checkLabel
+ }}
+
+
+
+
+
+
+
+
+ 按时
+ 按日
+ 按周
+ 按月
+
+
+
+
+ {{ item.label }}
+
+
+
+
+ 时间:
+
+ {{ item.label }}
+
+
+
+
+
+
+ 渠道:
+
+ {{ item.label }}
+
+
+
+ 访客:
+
+ 全部
+ 新访客
+ 老访客
+
+
+
+
+ 分析维度:
+
+ 流失
+ 留存
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/filterBar/index copy.vue b/src/layout/components/filterBar/index copy.vue
deleted file mode 100644
index a408ebb..0000000
--- a/src/layout/components/filterBar/index copy.vue
+++ /dev/null
@@ -1,1075 +0,0 @@
-
-
-
-
-
-
- 时间:
-
- 今日
- 本周
- 本月
-
-
-
-
- 按日:
-
-
-
-
-
- 按月:
-
-
-
-
-
- 时间:
-
- 今日
- 昨日
- 近7天
- 近30天
-
-
-
-
-
-
- 用户证件号:
-
-
-
-
-
-
-
-
-
-
-
-
- 查询
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 按时
- 按日
- 按周
- 按月
-
-
-
-
-
-
地域
-
-
-
-
-
- {{ item.provinceName }}
-
-
X
-
-
- {{ areaValue }}
-
-
-
-
-
-
-
-
-
-
-
-
- 渠道:
-
- {{ item.label }}
-
-
-
- 访客:
-
- 全部
- 新访客
- 老访客
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/layout/components/filterBar/index.vue b/src/layout/components/filterBar/index.vue
index 1b9f934..4023cfb 100644
--- a/src/layout/components/filterBar/index.vue
+++ b/src/layout/components/filterBar/index.vue
@@ -50,6 +50,7 @@
v-model="timeFlag"
class="checkBoxStyle"
@change="handleChange"
+ :disabled="!indexCanClick"
>
今日
昨日
@@ -73,7 +74,12 @@
+
+
+
+ {{
+ checkLabel
+ }}
+
+
+
+
+
+
+
-
-
+
+
+ 按时
+ 按日
+ 按周
+ 按月
+
+
-
-
-
- 按时
- 按日
- 按周
- 按月
-
-
-
-
-
@@ -283,7 +319,7 @@ import { blobDownloads } from "@/utils/localDownloadUtil.js";
import { string } from "clipboard";
import { province } from "@/utils/province";
import { getHostApi } from "@/api/trackingapi/accessLog.js";
-
+import { copyObj } from "@/utils/copy";
export default {
props: {
byTimeType: {
@@ -334,9 +370,15 @@ export default {
type: Boolean,
default: false,
},
+ ByContrast: {
+ type: Boolean,
+ default: false,
+ },
},
data() {
return {
+ //indexCanClick: this.$store.getters.indexCanClick,
+ checked: false,
checkMonth: "",
checkDay: "",
segmentTime: "Day",
@@ -540,7 +582,6 @@ export default {
},
],
},
-
showBtn: true,
dateRange: null, //日期范围
isIndeterminate: false,
@@ -575,38 +616,22 @@ export default {
hostData: [],
hostValue: "all",
segmentTimeList: this.$options.filters.formatToday(), //默认今日日期
- // whoId: "31010619611113281x", //证件号
whoId: "", //证件号
blurFlag: false,
timeSlotList: [],
toDate: [],
+ checkLabel: "对比时间段", //对比
+ contrastValue: "",
+ contrastFlag: "",
};
},
mounted() {
this.handleAdd();
- // 暂定30天 有数值
- // let date = new Date();
- // let toData =
- // new Date(new Date().toLocaleDateString()).getTime() + 8 * 3600 * 1000;
- // let dateTime =
- // date.getFullYear() +
- // "-" +
- // (date.getMonth() + 1 < 10
- // ? "0" + (date.getMonth() + 1)
- // : date.getMonth() + 1) +
- // "-" +
- // date.getDate();
- // this.timeDifference = toData - 29 * 3600 * 24 * 1000;
- // this.timestampToTime(this.timeDifference);
- // this.currentTime = [this.checkDateTime, dateTime];
- // this.startTime = this.currentTime[0];
- // this.endTime = this.currentTime[1];
- // ------------------end
this.getHostList();
// 初始值调用
if (this.$route.path == "/business/monitorPanel") {
this.$emit("setFilterBarParams", this.commonParams);
- }else if (this.$route.path == "/business/globalTopology") {
+ } else if (this.$route.path == "/business/globalTopology") {
this.$emit("setFilterBarParams", this.commonParams);
}
},
@@ -614,6 +639,9 @@ export default {
applicationCode() {
return this.$store.getters.applicationCode;
},
+ indexCanClick() {
+ return this.$store.getters.indexCanClick;
+ },
channel() {
if (this.channelValue) {
return [this.channelValue];
@@ -635,7 +663,6 @@ export default {
return province;
},
defaultParams() {
- // const { startTime, endTime,segmentTimeList,segmentTime } = this;
const { startTime, endTime, segmentTimeList, timeSlotList } = this;
if (this.BySegment) {
return {
@@ -663,10 +690,14 @@ export default {
httpHost,
timeValue,
timeSlot,
+ contrastValue,
} = this;
if (this.ByArea) {
obj = Object.assign(obj, { province });
}
+ if (this.ByData) {
+ obj = Object.assign(obj, { timeType });
+ }
if (this.ByHost) {
obj = Object.assign(obj, { httpHost });
}
@@ -679,24 +710,32 @@ export default {
if (this.ByTimeSlot) {
obj = Object.assign(obj, { timeValue, timeSlot });
}
-
+ // 对比的时间
+ if (this.ByContrast) {
+ obj = Object.assign(obj, { contrastValue });
+ }
return obj;
},
},
watch: {
- commonParams(val) {
- // console.log(this.$route.path, "route.path");
- if (
-
- this.$route.path != "/business/railwayTrack" &&
- this.$route.path != "/business/monitorPanel" &&
- this.$route.path != "/business/globalTopology"
- ) {
- this.setTopFilterParams(val);
- this.commonData = val;
- }
+ commonParams: {
+ deep: false,
+ immediate: false,
+ handler(newVal, oldVal) {
+ if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
+ this.$nextTick(() => {
+ if (
+ this.$route.path != "/business/railwayTrack" &&
+ this.$route.path != "/business/monitorPanel" &&
+ this.$route.path != "/business/globalTopology"
+ ) {
+ this.setTopFilterParams(newVal);
+ this.commonData = newVal;
+ }
+ });
+ }
+ },
},
-
applicationCode: {
handler(newValue, oldValue) {
this.hostValue = "all";
@@ -706,6 +745,69 @@ export default {
},
},
methods: {
+ changeByDateValue() {
+ if (this.startTime == this.endTime) {
+ this.timeType = "hour";
+ } else {
+ let timeDiff = Date.parse(this.endTime) - Date.parse(this.startTime);
+ // 选择日期进行按时按日自动刷选
+ if (timeDiff == 0) {
+ this.timeType = "hour";
+ } else if (timeDiff > 0 && timeDiff < 2592000000) {
+ this.timeType = "day";
+ } else if (timeDiff >= 2592000000 && timeDiff < 7776000000) {
+ this.timeType = "week";
+ } else {
+ this.timeType = "month";
+ }
+ }
+ },
+ handleRadioEvent() {
+ // this.clearEvent();
+ },
+ clearEvent() {
+ this.checked = false;
+ this.contrastFlag = false;
+ this.checkLabel = "对比时间段";
+ this.contrastValue = "";
+ },
+ checkTimeSlot(val) {
+ switch (val) {
+ case true:
+ this.checkLabel = "对比";
+ this.contrastValue = "";
+ break;
+ case false:
+ this.checkLabel = "对比时间段";
+ this.contrastValue = "";
+ this.dateFlag = null;
+ break;
+ }
+ this.contrastFlag = val;
+ },
+ // 对比日期2
+ checkContrast(val) {
+ this.dateFlag = 2;
+ let copyDate = copyObj(this.contrastValue);
+ const dateOne =
+ Date.parse(this.currentTime[1]) - Date.parse(this.currentTime[0]); // 日期一的时间差值
+ const toDate = this.$options.filters.todateFunc(); //当日
+ const rangeDate = Date.parse(toDate) - Date.parse(this.contrastValue[0]); //日期二的时间差值
+
+ if (rangeDate >= dateOne) {
+ const dateTwoEndtimeStamp = Date.parse(this.contrastValue[0]) + dateOne;
+ let automaticDate =
+ this.$options.filters.timeStampFunc(dateTwoEndtimeStamp);
+ this.contrastValue[1] = automaticDate;
+ } else {
+ // 没有这个范围进行逆向取值
+ const reverseDate = Date.parse(this.contrastValue[0]) - dateOne;
+ let automaticDate = this.$options.filters.timeStampFunc(reverseDate);
+ this.contrastValue[0] = automaticDate;
+ this.contrastValue[1] = copyDate[1];
+ }
+ console.log(this.contrastValue, "contrastValue----");
+ },
// 增加时间段传值
segmentTimeEvent(val) {
switch (val) {
@@ -763,9 +865,6 @@ export default {
this.$store.dispatch("tracking/setDate", val);
},
handleTimeValue(val) {},
- checkTimeSlot(val) {
- },
-
numberEvent(val) {
let path = this.$route.path;
if (path == "/business/railwayTrack") {
@@ -777,7 +876,7 @@ export default {
let obj = {};
obj = Object.assign(params, this.defaultParams);
this.setTopFilterParams(obj);
- }else if(path == "/business/globalTopology"){
+ } else if (path == "/business/globalTopology") {
this.setTopFilterParams(this.commonParams);
}
},
@@ -842,6 +941,7 @@ export default {
},
checkDateEvnet(val) {
+ this.clearEvent();
this.timeFlag = "";
this.startTime = val[0];
this.endTime = val[1];
@@ -863,6 +963,7 @@ export default {
}
let result = (endTime - startTime) / (3600 * 24 * 1000);
this.dateTimeCount(result);
+ this.changeByDateValue();
},
// 日期计算
dateTimeCount(result) {
@@ -919,7 +1020,7 @@ export default {
: date.getMonth() + 1) +
"-" +
// date.getDate();
- (date.getDate() < 10 ? "0" + date.getDate() : date.getDate())
+ (date.getDate() < 10 ? "0" + date.getDate() : date.getDate());
this.currentTime = [dateTime, dateTime];
this.timeSlot = dateTime;
this.initDate(this.currentTime); //默认日期
@@ -927,6 +1028,7 @@ export default {
// 单选切换时间
handleChange(val) {
+ this.clearEvent();
var date = new Date();
let dateTime =
date.getFullYear() +
@@ -936,31 +1038,36 @@ export default {
: date.getMonth() + 1) +
"-" +
// date.getDate();
- (date.getDate() < 10 ? "0" + date.getDate() : date.getDate())
+ (date.getDate() < 10 ? "0" + date.getDate() : date.getDate());
let toData =
new Date(new Date().toLocaleDateString()).getTime() + 8 * 3600 * 1000;
if (val == "day") {
this.currentTime = [dateTime, dateTime];
this.dateTimeCount(1);
+ this.timeType = "hour";
} else if (val == "previous") {
this.timeDifference = toData - 3600 * 24 * 1000;
this.timestampToTime(this.timeDifference);
this.currentTime = [this.checkDateTime, this.checkDateTime];
this.dateTimeCount(1);
+ this.timeType = "hour";
} else if (val == "week") {
this.timeDifference = toData - 6 * 3600 * 24 * 1000;
this.timestampToTime(this.timeDifference);
this.currentTime = [this.checkDateTime, dateTime];
this.dateTimeCount(6);
+ this.timeType = "day";
} else {
this.timeDifference = toData - 29 * 3600 * 24 * 1000;
this.timestampToTime(this.timeDifference);
this.currentTime = [this.checkDateTime, dateTime];
+ this.timeType = "week";
this.dateTimeCount(29);
}
this.startTime = this.currentTime[0];
this.endTime = this.currentTime[1];
this.$store.dispatch("tracking/setDate", val);
+ this.changeByDateValue();
},
// 时间戳转换器
timestampToTime(timestamp) {
@@ -994,23 +1101,35 @@ export default {
diff --git a/src/views/ip-analysis/components/ipTable.vue b/src/views/ip-analysis/components/ipTable.vue
new file mode 100644
index 0000000..b6b26a2
--- /dev/null
+++ b/src/views/ip-analysis/components/ipTable.vue
@@ -0,0 +1,684 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.ip }}
+
+
+
+
+
+
+
+ {{ row.country }}
+
+
+
+
+ {{ row.province }}
+
+
+
+
+ {{ row.city }}
+
+
+
+
+ {{ row.pv }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择要排除的文件类型:
+
+
+
+ js文件
+ css文件
+ 图片文件(jgp;png;gif;jpeg;tiff;tif)
+
+
+
+
+ 其他类型文件
+
+
+
+
+
+
+ 请选择页面响应时间范围:
+
+
+ 超过一秒
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.uri }}
+
+
+
+
+ {{ row.pv }}
+
+
+
+
+ {{ row.slowPv }}
+
+
+
+
+ {{ row.maxVisitTime }}
+
+
+
+
+ {{ row.pvRate }}
+
+
+
+
+ {{ row.avgVisitTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ip-analysis/index.vue b/src/views/ip-analysis/index.vue
new file mode 100644
index 0000000..1ddc187
--- /dev/null
+++ b/src/views/ip-analysis/index.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
diff --git a/src/views/log-analysis/abnormal/components/fiveError.vue b/src/views/log-analysis/abnormal/components/fiveError.vue
index 6855920..26fe449 100644
--- a/src/views/log-analysis/abnormal/components/fiveError.vue
+++ b/src/views/log-analysis/abnormal/components/fiveError.vue
@@ -14,6 +14,7 @@
style="width: 100%"
:cell-style="tableHeaderColor"
border
+ v-loading="loading"
>
{
if (res.code == 200) {
+ this.loading = false;
this.tableData = res.data.rows;
this.total = res.data.total;
+ } else {
+ this.loading = false;
}
});
},
diff --git a/src/views/log-analysis/abnormal/components/fourError.vue b/src/views/log-analysis/abnormal/components/fourError.vue
index b8cdc7d..e14ded0 100644
--- a/src/views/log-analysis/abnormal/components/fourError.vue
+++ b/src/views/log-analysis/abnormal/components/fourError.vue
@@ -14,6 +14,7 @@
style="width: 100%"
:cell-style="tableHeaderColor"
border
+ v-loading="loading"
>
{
if (res.code == 200) {
+ this.loading = false;
this.tableData = res.data.rows;
this.total = res.data.total;
+ } else {
+ this.loading = false;
}
});
},
diff --git a/src/views/log-analysis/abnormal/components/visitError.vue b/src/views/log-analysis/abnormal/components/visitError.vue
index 14ebb14..6bb7fe0 100644
--- a/src/views/log-analysis/abnormal/components/visitError.vue
+++ b/src/views/log-analysis/abnormal/components/visitError.vue
@@ -95,7 +95,12 @@ export default {
},
// echarts图表
initEcharts() {
- this.ipEchart = echarts.init(document.getElementById("ipEchart"));
+ const ipEchartDom = document.getElementById("ipEchart");
+ if (!ipEchartDom) {
+ console.warn("ipEchart DOM元素不存在,跳过ECharts初始化");
+ return;
+ }
+ this.ipEchart = echarts.init(ipEchartDom);
const option = {
tooltip: {
trigger: "axis",
diff --git a/src/views/log-analysis/data-overview/components/IPTop.vue b/src/views/log-analysis/data-overview/components/IPTop.vue
index d4fa388..91b3a0d 100644
--- a/src/views/log-analysis/data-overview/components/IPTop.vue
+++ b/src/views/log-analysis/data-overview/components/IPTop.vue
@@ -1,13 +1,26 @@
-
+
IP访问量Top10
-
-
@@ -24,33 +37,42 @@ export default {
xDataList: [],
yDataList: [],
ipList: [],
+ loading: false,
};
},
mounted() {},
methods: {
- toPageEvent(){
- this.$router.push('/logAnalysis/abnormal')
+ setLoading(val) {
+ this.loading = val;
+ },
+ toPageEvent() {
+ this.$router.push("/logAnalysis/abnormal");
},
- getIpTop10(commonParams) {
- getIpTop10Api(commonParams).then((res) => {
- if (res.code == 200) {
+ async getIpTop10(commonParams) {
+ this.loading = true;
+ this.ipList = [];
+ await getIpTop10Api(commonParams).then((res) => {
+ if (res.code == 200 && res.data.length > 0) {
this.xDataList = [];
this.yDataList = [];
this.ipList = res.data.slice(0, 10).reverse();
this.ipList.map((item, index) => {
if (item.ip) {
this.yDataList.push(item.ip);
- }else{
+ } else {
this.yDataList.push("");
}
if (item.pv) {
this.xDataList.push(item.pv);
- }else{
+ } else {
this.yDataList.push(0);
}
});
// console.log(this.xDataList, this.yDataList);
this.initIpEcharts();
+ this.loading = false;
+ } else {
+ this.loading = false;
}
});
},
@@ -63,21 +85,21 @@ export default {
},
legend: {
data: ["访问量(PV)"],
- right:'5%',
+ right: "5%",
},
-
+
grid: {
left: "20%",
- top:'12%',
- bottom:"10%",
+ top: "12%",
+ bottom: "10%",
},
yAxis: [
{
type: "category",
data: this.yDataList,
axisLabel: {
- interval: 0,
- rotate: "0",
+ interval: 0,
+ rotate: "0",
},
axisTick: {
show: false,
@@ -96,8 +118,8 @@ export default {
alignWithLabel: true,
},
axisLabel: {
- interval: 0,
- rotate: "26",
+ interval: 0,
+ rotate: "26",
},
},
],
@@ -126,7 +148,7 @@ export default {
itemStyle: {
color: "#2c7be5",
},
-
+
barWidth: 10,
label: {
show: true,
@@ -141,7 +163,6 @@ export default {
if (this.ipEchart) {
this.ipEchart.resize();
}
-
});
},
},
diff --git a/src/views/log-analysis/data-overview/components/apiUi.vue b/src/views/log-analysis/data-overview/components/apiUi.vue
index aefd1d4..8d4031e 100644
--- a/src/views/log-analysis/data-overview/components/apiUi.vue
+++ b/src/views/log-analysis/data-overview/components/apiUi.vue
@@ -1,5 +1,5 @@
-
+
-
-
@@ -64,21 +79,30 @@ export default {
yDataList: [],
checkValue: "TOP10",
UAListData: [],
+ loading: false,
};
},
mounted() {
- this.uiApiEcharts();
+ if (this.uAList.length > 0) {
+ this.uiApiEcharts();
+ }
},
methods: {
+ setLoading(val) {
+ this.loading = val;
+ },
changeEchartEvent(val) {
- if (val == 'TOP10') {
+ if (val == "TOP10" && this.uAList.length > 0) {
this.uiApiEcharts();
}
},
// getUaApi
- getUa(commonParams) {
- getUaApi(commonParams).then((res) => {
- if (res.code == 200) {
+ async getUa(commonParams) {
+ this.loading = true;
+ this.UAListData = [];
+ this.uAList = [];
+ await getUaApi(commonParams).then((res) => {
+ if (res.code == 200 && res.data.length > 0) {
this.UAListData = res.data;
this.xDataList = [];
this.yDataList = [];
@@ -97,11 +121,19 @@ export default {
});
// console.log(this.xDataList, this.yDataList);
this.uiApiEcharts();
+ this.loading = false;
+ } else {
+ this.loading = false;
}
});
},
uiApiEcharts() {
- this.uiChart = echarts.init(document.getElementById("uiCharts"));
+ const uiChartsDom = document.getElementById("uiCharts");
+ if (!uiChartsDom) {
+ console.warn("uiCharts DOM元素不存在,跳过ECharts初始化");
+ return;
+ }
+ this.uiChart = echarts.init(uiChartsDom);
const option = {
tooltip: {
trigger: "axis",
@@ -109,7 +141,7 @@ export default {
},
legend: {
// data: ["访问量(PV)"],
- right:'5%',
+ right: "5%",
},
grid: {
left: "35%",
diff --git a/src/views/log-analysis/data-overview/components/dataTrend copy.vue b/src/views/log-analysis/data-overview/components/dataTrend copy.vue
deleted file mode 100644
index a480dbe..0000000
--- a/src/views/log-analysis/data-overview/components/dataTrend copy.vue
+++ /dev/null
@@ -1,487 +0,0 @@
-
-
-
-
-
趋势图
-
- 按时
- 按日
- 按周
- 按月
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/log-analysis/data-overview/components/dataTrend.vue b/src/views/log-analysis/data-overview/components/dataTrend.vue
index 5812358..814d077 100644
--- a/src/views/log-analysis/data-overview/components/dataTrend.vue
+++ b/src/views/log-analysis/data-overview/components/dataTrend.vue
@@ -1,13 +1,14 @@
-
-
-
+
+
+
趋势图
按时
按日
@@ -15,6 +16,13 @@
按月
+
+

+
@@ -52,19 +60,27 @@ export default {
},
myChart: [],
oldCommonParams: {},
+ loading: false,
};
},
computed: {
httpHost() {
return this.$store.getters.httpHost;
},
+ indexCanClick() {
+ return this.$store.getters.indexCanClick;
+ },
},
watch: {},
methods: {
+ setLoading(val) {
+ this.loading = val;
+ },
changeDateEvent() {
this.getFlowTrendEvent(this.oldCommonParams, "check");
},
- getFlowTrendEvent(commonParams, event) {
+ async getFlowTrendEvent(commonParams, event) {
+ this.loading = true;
this.oldCommonParams = commonParams;
let copyParams = JSON.parse(JSON.stringify(commonParams));
if (!event) {
@@ -75,15 +91,17 @@ export default {
//月 2476800000
let timeDiff =
Date.parse(copyParams.endTime) - Date.parse(copyParams.startTime);
- if (timeDiff > 489600000 && timeDiff != 604800000) {
+ // 选择日期进行按时按日自动刷选
+ if (timeDiff == 0) {
+ copyParams.timeType = "hour";
+ this.timeType = "hour";
+ } else if (timeDiff > 0 && timeDiff < 2592000000) {
+ copyParams.timeType = "day";
+ this.timeType = "day";
+ } else if (timeDiff >= 2592000000 && timeDiff < 7776000000) {
copyParams.timeType = "week";
this.timeType = "week";
} else {
- copyParams.timeType = "day";
- this.timeType = "day";
- }
- // 大于三个月按月标准
- if (timeDiff > 7776000000) {
copyParams.timeType = "month";
this.timeType = "month";
}
@@ -91,7 +109,7 @@ export default {
} else {
copyParams.timeType = this.timeType;
}
- getFlowTrendApi(copyParams).then((res) => {
+ await getFlowTrendApi(copyParams).then((res) => {
if (res.code == 200) {
this.xLineList = [];
this.bodySentBytesList = [];
@@ -123,12 +141,20 @@ export default {
this.pvMax = this.pvList;
this.initFlowEchart(); //line chart
this.initVisitEchart(); //双线图
+ this.loading = false;
+ }else{
+ this.loading = false;
}
});
},
// 双线图
initVisitEchart() {
- this.chart = echarts.init(document.querySelector(".visitEchart"));
+ const visitEchartDom = document.querySelector(".visitEchart");
+ if (!visitEchartDom) {
+ console.warn('Visit chart DOM element not found');
+ return;
+ }
+ this.chart = echarts.init(visitEchartDom);
this.chart.setOption({
tooltip: {
trigger: "axis",
@@ -188,6 +214,18 @@ export default {
},
type: "value",
min: 0,
+ axisLabel: {
+ rotate: 45, // 旋转角度
+ fontSize: 10,
+ //超过1万显示单位万
+ formatter: function (value) {
+ if (value >= 10000) {
+ return value / 10000 + "万";
+ } else {
+ return value;
+ }
+ },
+ },
// max: this.uvMax,
},
{
@@ -198,6 +236,18 @@ export default {
axisTick: {
show: false,
},
+ axisLabel: {
+ rotate: 45, // 旋转角度
+ fontSize: 10,
+ //超过1万显示单位万
+ formatter: function (value) {
+ if (value >= 10000) {
+ return value / 10000 + "万";
+ } else {
+ return value;
+ }
+ },
+ },
},
],
series: [
@@ -245,7 +295,12 @@ export default {
// 折现图
initFlowEchart() {
- this.flowEchart = echarts.init(document.querySelector(".flowEchart"));
+ const flowEchartDom = document.querySelector(".flowEchart");
+ if (!flowEchartDom) {
+ console.warn('Flow chart DOM element not found');
+ return;
+ }
+ this.flowEchart = echarts.init(flowEchartDom);
this.flowEchart.setOption({
// backgroundColor: "#fff",
// tooltip: {
@@ -329,12 +384,24 @@ export default {
type: "value",
nameTextStyle: {
fontWeight: 400,
- fontSize: 13,
+ fontSize: 12,
color: "#2c7be5",
},
axisTick: {
show: false,
},
+ axisLabel: {
+ rotate: 45, // 旋转角度
+ fontSize: 10,
+ //超过1万显示单位万
+ formatter: function (value) {
+ if (value >= 10000) {
+ return value / 10000 + "万";
+ } else {
+ return value;
+ }
+ },
+ },
},
],
series: [
diff --git a/src/views/log-analysis/data-overview/components/echartsLog.vue b/src/views/log-analysis/data-overview/components/echartsLog.vue
index 613908b..8ee6f55 100644
--- a/src/views/log-analysis/data-overview/components/echartsLog.vue
+++ b/src/views/log-analysis/data-overview/components/echartsLog.vue
@@ -64,9 +64,7 @@ export default {
},
tooltip: {
trigger: "item",
- // formatter: "{a}
{c} ({d}%)",
formatter: (params) => {
- // console.log(params);
let htmlStr;
if (params.data.flag) {
// 平均时长的展示
@@ -105,13 +103,9 @@ export default {
// },
series: [
{
- // name: "日志分析",
type: "pie",
- // radius: "40%",
- radius: ["40%", "55%"],
- // center: ["30%", "40%"],
+ radius: ["30%", "45%"],
avoidLabelOverlap: true,
- // 自定义颜色
itemStyle: {
normal: {
color: (item) => {
@@ -119,13 +113,11 @@ export default {
},
},
},
-
label: {
normal: {
show: true,
padding: [20, 0],
- position: "outside", // 标签位于饼图外部
- // formatter: "({d}%)",
+ position: "outside",
formatter: (params) => {
if (params.data.flag) {
return params.value;
@@ -139,23 +131,9 @@ export default {
emphasis: {
show: true,
},
- // emphasis: {
- // label: {
- // show: true,
- // fontSize: "30",
- // fontWeight: "bold",
- // },
- // },
},
- // labelLine: {
- // minTurnAngle: 0,
- // },
labelLine: {
- // length: 10, // 引导线起点到文字的距离
- // length2: 30, // 引导线终点到饼图边缘的距离
- // smooth: true, // 弯曲程度
- // position: "outside", // 标签位于饼图外部
- // show: true,
+ length: 10, // 引导线起点到文字的距离
lineStyle: {
color: "rgba(255, 255, 255, 0.3)",
},
@@ -185,7 +163,6 @@ export default {
}
});
});
- // console.log(this.chartData,"this.chartData-------");
},
},
};
diff --git a/src/views/log-analysis/data-overview/components/funApi.vue b/src/views/log-analysis/data-overview/components/funApi.vue
index a264660..ec5bdd5 100644
--- a/src/views/log-analysis/data-overview/components/funApi.vue
+++ b/src/views/log-analysis/data-overview/components/funApi.vue
@@ -1,11 +1,25 @@
-
+
@@ -18,13 +32,19 @@ export default {
return {
funApis: null,
funList: [],
+ loading: false,
};
},
mounted() {},
methods: {
- getRequestMethod(commonParams) {
- getRequestMethodApi(commonParams).then((res) => {
- if (res.code == 200) {
+ setLoading(val) {
+ this.loading = val;
+ },
+ async getRequestMethod(commonParams) {
+ this.loading = true;
+ this.funList = [];
+ await getRequestMethodApi(commonParams).then((res) => {
+ if (res.code == 200 && res.data.length > 0) {
this.funList = res.data;
this.funList.map((item) => {
item.value = item.pvRate;
@@ -32,11 +52,21 @@ export default {
});
// console.log(this.funList,"funList----");
this.funApiEcharts();
+ this.loading = false;
+ } else {
+ this.loading = false;
+ this.funApis = null;
+ this.funApiEcharts();
}
});
},
funApiEcharts() {
- this.funApis = echarts.init(document.getElementById("funApiEchart"));
+ const funApiEchartDom = document.getElementById("funApiEchart");
+ if (!funApiEchartDom) {
+ console.warn("funApiEchart DOM元素不存在,跳过ECharts初始化");
+ return;
+ }
+ this.funApis = echarts.init(funApiEchartDom);
const COLORS = [
"#2c7be5",
"#80bdef",
@@ -57,12 +87,14 @@ export default {
let htmlStr;
htmlStr = `
-
请求方式: ${params.data.requestMethod}
+
请求方式: ${
+ params.data.requestMethod
+ }
占比: ${
params.percent + "%"
}
总量: ${
- params.data.pv
+ params.data.pv
}
diff --git a/src/views/log-analysis/data-overview/components/ipDistribution.vue b/src/views/log-analysis/data-overview/components/ipDistribution.vue
index cfa8f5b..2243962 100644
--- a/src/views/log-analysis/data-overview/components/ipDistribution.vue
+++ b/src/views/log-analysis/data-overview/components/ipDistribution.vue
@@ -1,20 +1,28 @@
-
-
-
+
+
+
IP分布
地图
列表
-
-
+
+
@@ -69,7 +77,8 @@
-
-
diff --git a/src/views/log-analysis/statuCode-analysis/components/statuEcharts.vue b/src/views/log-analysis/statuCode-analysis/components/statuEcharts.vue
index b8b2459..80f7516 100644
--- a/src/views/log-analysis/statuCode-analysis/components/statuEcharts.vue
+++ b/src/views/log-analysis/statuCode-analysis/components/statuEcharts.vue
@@ -1,7 +1,21 @@
-
+
请求状态占比
-
+
+ 暂无数据
+
+
@@ -13,7 +27,7 @@
+
+
diff --git a/src/views/trend-analysis/components/index.js b/src/views/trend-analysis/components/index.js
new file mode 100644
index 0000000..6ad2541
--- /dev/null
+++ b/src/views/trend-analysis/components/index.js
@@ -0,0 +1,6 @@
+export { default as trendEchart } from './trendEchart'
+export { default as trendTable } from './trendTable'
+export { default as dataTrend } from './dataTrend'
+
+
+
diff --git a/src/views/trend-analysis/components/trendEchart.vue b/src/views/trend-analysis/components/trendEchart.vue
new file mode 100644
index 0000000..912fcf0
--- /dev/null
+++ b/src/views/trend-analysis/components/trendEchart.vue
@@ -0,0 +1,575 @@
+
+
+
+
+
趋势图
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/trend-analysis/components/trendTable.vue b/src/views/trend-analysis/components/trendTable.vue
new file mode 100644
index 0000000..309578b
--- /dev/null
+++ b/src/views/trend-analysis/components/trendTable.vue
@@ -0,0 +1,316 @@
+
+
+
+
+
+
+
+
+
+ {{ scope.row.statTime }}
+
+ {{ commonParams.timeType == "hour" ? "时" : "" }}
+
+
+
+
+
+
+
+ {{ row.uv }}
+
+
+
+
+ {{ row.pv }}
+
+
+
+
+ {{ row.bodySentBytes | conver }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ commonParams.startTime }}
+
+ {{ scope.row.children.statTime }}
+ {{ commonParams.timeType == "hour" ? "时" : "" }}
+
+
+
+
+
+ {{ contrastValue[0] }}
+
+ {{ scope.row.children.statTime }}
+ {{ commonParams.timeType == "hour" ? "时" : "" }}
+
+
+
+
+ 变化率
+
+
+
+
+
+
+ {{ commonParams.startTime }} ~ {{ commonParams.endTime }}
+
+ {{ scope.row.children.statTime }}
+ {{ commonParams.timeType == "hour" ? "时" : "" }}
+
+
+
+
+
+ {{ contrastValue[0] }} ~ {{ contrastValue[1] }}
+
+ {{ scope.row.children.statTime }}
+ {{ commonParams.timeType == "hour" ? "时" : "" }}
+
+
+
+
+
+
+
+
+ {{ scope.row.statTime }}
+
+
+
+
+ {{ scope.row.children.statTime || 0 }}
+
+
+
+
变化率
+
+
+
+
+
+
+ {{ scope.row.uv || 0 }}
+ {{ scope.row.children.uv || 0 }}
+
+ {{ changeRateEvent(scope.row.uv, scope.row.children.uv) }}%
+
+
+
+
+
+
+ {{ scope.row.pv || 0 }}
+ {{ scope.row.children.pv || 0 }}
+
+ {{ changeRateEvent(scope.row.pv, scope.row.children.pv) }}%
+
+
+
+
+
+
+
+
+ {{ scope.row.bodySentBytes | conver }}
+
+
+ {{ scope.row.children.bodySentBytes | conver }}
+
+
+ {{
+ changeRateEvent(
+ scope.row.bodySentBytes,
+ scope.row.children.bodySentBytes
+ )
+ }}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/trend-analysis/index.vue b/src/views/trend-analysis/index.vue
new file mode 100644
index 0000000..2556f22
--- /dev/null
+++ b/src/views/trend-analysis/index.vue
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
diff --git a/vue.config.js b/vue.config.js
index 86c0125..504b1ee 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -23,12 +23,12 @@ module.exports = {
// outputDir: "dist",
// assetsDir: "static",
- //绝对路径
+ //绝对路径(发布生产环境)
publicPath: "/",
outputDir: "dist",
assetsDir: "static",
- // 使用相对路径
+ // 使用相对路径(发布到测试环境)
// assetsDir: "./assets",
// publicPath: "",