diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js
index 98d04316..5dadb0d8 100644
--- a/frontend/.eslintrc.js
+++ b/frontend/.eslintrc.js
@@ -13,5 +13,8 @@ module.exports = {
},
parserOptions: {
parser: 'babel-eslint'
+ },
+ globals: {
+ '_hmt': 1
}
}
diff --git a/frontend/index.html b/frontend/index.html
index 98cf9b85..59f3bbb9 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1,15 +1,18 @@
-
+
+
Crawlab
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/frontend/package.json b/frontend/package.json
index 5b533470..701463a3 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -23,6 +23,7 @@
"nprogress": "0.2.0",
"path": "^0.12.7",
"vue": "^2.5.22",
+ "vue-ba": "^1.2.5",
"vue-codemirror-lite": "^1.0.4",
"vue-i18n": "^8.9.0",
"vue-router": "^3.0.1",
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 38d6c19d..2a86e532 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -10,8 +10,45 @@ import DialogView from './components/Common/DialogView'
export default {
name: 'App',
+ data () {
+ return {
+ msgPopup: undefined
+ }
+ },
components: {
DialogView
+ },
+ computed: {
+ useStats () {
+ return localStorage.getItem('useStats')
+ }
+ },
+ methods: {},
+ mounted () {
+ window.setUseStats = (value) => {
+ localStorage.setItem('useStats', value)
+ document.querySelector('.el-message__closeBtn').click()
+ if (value === 1) {
+ _hmt.push(['_trackPageview', '/allow_stats'])
+ } else {
+ _hmt.push(['_trackPageview', '/disallow_stats'])
+ }
+ }
+
+ // first-time user
+ if (this.useStats === undefined || this.useStats === null) {
+ this.$message({
+ type: 'info',
+ dangerouslyUseHTMLString: true,
+ showClose: true,
+ duration: 0,
+ message: this.$t('Do you allow us to collect some statistics to improve Crawlab?
' +
+ '' +
+ '' +
+ '' +
+ '
')
+ })
+ }
}
}
@@ -52,4 +89,31 @@ export default {
.el-form .el-form-item {
margin-bottom: 10px;
}
+
+ .message-btn {
+ margin: 0 5px;
+ padding: 5px 10px;
+ background: transparent;
+ color: #909399;
+ font-size: 12px;
+ border-radius: 4px;
+ cursor: pointer;
+ }
+
+ .message-btn:hover {
+ opacity: 0.8;
+ text-decoration: underline;
+ }
+
+ .message-btn.success {
+ background: #67c23a;
+ border-color: #67c23a;
+ color: #fff;
+ }
+
+ .message-btn.danger {
+ background: #f56c6c;
+ border-color: #f56c6c;
+ color: #fff;
+ }
diff --git a/frontend/src/main.js b/frontend/src/main.js
index d90e7bcf..721f0f63 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -12,6 +12,8 @@ import 'font-awesome/scss/font-awesome.scss'// FontAwesome
import 'codemirror/lib/codemirror.css'
+// import ba from 'vue-ba'
+
import App from './App'
import store from './store'
import router from './router'
@@ -24,8 +26,23 @@ import i18n from './i18n'
Vue.use(ElementUI, { locale })
+// Vue.use(ba, 'c35e3a563a06caee2524902c81975add')
+// Vue.use(ba, {
+// siteId: 'c35e3a563a06caee2524902c81975add'
+// })
+
Vue.config.productionTip = false
+// 百度统计
+window._hmt = window._hmt || [];
+(function () {
+ let hm = document.createElement('script')
+ hm.src = 'https://hm.baidu.com/hm.js?c35e3a563a06caee2524902c81975add'
+ let s = document.getElementsByTagName('script')[0]
+ s.parentNode.insertBefore(hm, s)
+})()
+
+// inject request api
Vue.prototype.$request = request
const app = new Vue({
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index bf96c11b..4eddc102 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -222,4 +222,12 @@ router.beforeEach((to, from, next) => {
next()
})
+router.afterEach((to, from, next) => {
+ if (to.path) {
+ if (localStorage.getItem('useStats') !== '0') {
+ window._hmt.push(['_trackPageview', to.path])
+ }
+ }
+})
+
export default router
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
index 57fb5065..d21e0b74 100644
--- a/frontend/src/store/index.js
+++ b/frontend/src/store/index.js
@@ -12,6 +12,7 @@ import file from './modules/file'
import schedule from './modules/schedule'
import lang from './modules/lang'
import site from './modules/site'
+import stats from './modules/stats'
import getters from './getters'
Vue.use(Vuex)
@@ -29,7 +30,9 @@ const store = new Vuex.Store({
file,
schedule,
lang,
- site
+ site,
+ // 百度统计
+ stats
},
getters
})
diff --git a/frontend/src/store/modules/stats.js b/frontend/src/store/modules/stats.js
new file mode 100644
index 00000000..0a0bbe16
--- /dev/null
+++ b/frontend/src/store/modules/stats.js
@@ -0,0 +1,14 @@
+const state = {}
+const getters = {
+ useStats () {
+ return localStorage.getItem('useStats')
+ }
+}
+const mutations = {}
+const actions = {}
+export default {
+ state,
+ getters,
+ mutations,
+ actions
+}
diff --git a/frontend/src/views/home/Home.vue b/frontend/src/views/home/Home.vue
index e721a95c..c46c2431 100644
--- a/frontend/src/views/home/Home.vue
+++ b/frontend/src/views/home/Home.vue
@@ -85,6 +85,9 @@ export default {
this.dailyTasks = response.data.daily_tasks
this.initEchartsDailyTasks()
})
+ },
+ mounted () {
+ // this.$ba.trackPageview('/')
}
}
diff --git a/frontend/src/views/layout/components/TagsView.vue b/frontend/src/views/layout/components/TagsView.vue
index 406ed45c..e97c8dc8 100644
--- a/frontend/src/views/layout/components/TagsView.vue
+++ b/frontend/src/views/layout/components/TagsView.vue
@@ -2,15 +2,15 @@
+ v-for="tag in visitedViews"
+ ref="tag"
+ :class="isActive(tag)?'active':''"
+ :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
+ :key="tag.path"
+ tag="span"
+ class="tags-view-item"
+ @click.middle.native="closeSelectedTag(tag)"
+ @contextmenu.prevent.native="openMenu(tag,$event)">
{{ $t(generateTitle(tag.title)) }}
@@ -47,7 +47,7 @@ export default {
return this.$store.state.tagsView.visitedViews
},
routers () {
- return this.$store.state.permission.routers
+ return this.$store.state.permission ? this.$store.state.permission.routers : []
}
},
watch: {
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 159ea9c1..75d4b025 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -8401,6 +8401,14 @@ vm-browserify@0.0.4:
dependencies:
indexof "0.0.1"
+vue-ba@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.npm.taobao.org/vue-ba/download/vue-ba-1.2.5.tgz#fef30732ee749a65a81a4f47113527ee41fda64b"
+ integrity sha1-/vMHMu50mmWoGk9HETUn7kH9pks=
+ dependencies:
+ deep-equal "^1.0.1"
+ vue "^2.3.3"
+
vue-codemirror-lite@^1.0.4:
version "1.0.4"
resolved "http://registry.npm.taobao.org/vue-codemirror-lite/download/vue-codemirror-lite-1.0.4.tgz#48a5cd7d17c0914503c8cd9d9b56b438e49c3410"
@@ -8485,6 +8493,11 @@ vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.8.2:
version "1.8.2"
resolved "http://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.8.2.tgz#dd73e80ba58bb65dd7a8aa2aeef6089cf6116f2a"
+vue@^2.3.3:
+ version "2.6.10"
+ resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
+ integrity sha1-pysaQqTYKnIepDjRtr9V5mGVxjc=
+
vue@^2.5.17, vue@^2.5.22:
version "2.6.6"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.6.tgz#dde41e483c11c46a7bf523909f4f2f816ab60d25"