Compare commits
30 Commits
dev
...
dev-24.01-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c4993cf12 | ||
|
|
b8ee685230 | ||
|
|
30b1328576 | ||
|
|
740e7bbae6 | ||
|
|
f020fe33b5 | ||
|
|
75b47d7ba7 | ||
|
|
a26b0c848d | ||
|
|
d2ad042cf9 | ||
|
|
a844d44d1d | ||
|
|
ad603339de | ||
|
|
08f0cd4522 | ||
|
|
0c20757d07 | ||
|
|
2c7c7293b4 | ||
|
|
d035677c2f | ||
|
|
50cdbde8bf | ||
|
|
d27738b9ec | ||
|
|
85456c1e47 | ||
|
|
327cbde233 | ||
|
|
cbf71eb1b9 | ||
|
|
4e0eb3f143 | ||
|
|
a17c68bb26 | ||
|
|
d1ae513124 | ||
|
|
91915996c0 | ||
|
|
8f17647752 | ||
|
|
29a319609e | ||
|
|
08ae827e31 | ||
|
|
854a846296 | ||
|
|
42aa7671a3 | ||
|
|
fb89134f95 | ||
|
|
584ad8d538 |
162
src/Login.vue
162
src/Login.vue
@@ -22,15 +22,39 @@
|
|||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button
|
<el-button :disabled="licenseStatus !== 0"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
type="primary"
|
type="primary"
|
||||||
class="login--input login--button"
|
class="login--input login--button"
|
||||||
|
:class="{'login-btn__license-error':licenseStatus !== 0}"
|
||||||
@click="login"
|
@click="login"
|
||||||
@keyup.enter="login"
|
@keyup.enter="login"
|
||||||
style="font-size: 16px;"
|
style="font-size: 16px;"
|
||||||
>Login</el-button
|
>Login
|
||||||
>
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="licenseStatus !== 0">
|
||||||
|
<div class="license-error-msg">{{licenseStatusErrMsg}}</div>
|
||||||
|
<div class="license-file">
|
||||||
|
<button style="position: relative;" class="license__btn margin-r-20" @click.prevent="downloadFile" @keyup.enter="login">
|
||||||
|
<i class="cn-icon-download1 cn-icon margin-r-6"></i><span>Download c2v file</span>
|
||||||
|
</button>
|
||||||
|
<el-upload :action="`${baseUrl}sys/license/upload`"
|
||||||
|
ref="licenseUpload"
|
||||||
|
id="licenseUpload"
|
||||||
|
:multiple="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:accept="fileTypeLimit"
|
||||||
|
:file-list="fileList"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-change="fileChange"
|
||||||
|
:on-success="uploadSuccess"
|
||||||
|
:on-error="uploadError">
|
||||||
|
<button style="position: relative;" class="license__btn" @click.prevent="">
|
||||||
|
<i class="cn-icon-upload1 cn-icon margin-r-6"></i><span>Upload license</span>
|
||||||
|
</button>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,6 +70,7 @@ import { api } from '@/utils/api'
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import utc from 'dayjs/plugin/utc'
|
import utc from 'dayjs/plugin/utc'
|
||||||
|
import { ref } from 'vue'
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -55,7 +80,11 @@ export default {
|
|||||||
loading: false,
|
loading: false,
|
||||||
username: '',
|
username: '',
|
||||||
pin: '',
|
pin: '',
|
||||||
language: ''
|
language: '',
|
||||||
|
licenseStatus: 1,
|
||||||
|
licenseStatusErrMsg: '',
|
||||||
|
downloadC2vUrl: api.downloadLicenseC2v,
|
||||||
|
supportID: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -69,6 +98,9 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (this.licenseStatus !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
axios.post(api.login, { username: this.username, pin: this.pin }).then(
|
axios.post(api.login, { username: this.username, pin: this.pin }).then(
|
||||||
res => {
|
res => {
|
||||||
@@ -103,6 +135,72 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
downloadFile () {
|
||||||
|
axios.get(this.downloadC2vUrl, { responseType: 'blob' }).then(res => {
|
||||||
|
const disposition = res.headers['content-disposition']
|
||||||
|
const fileName = decodeURI(disposition.split('filename=')[1])
|
||||||
|
if (window.navigator.msSaveOrOpenBlob) {
|
||||||
|
// 兼容ie11
|
||||||
|
const blobObject = new Blob([res.data])
|
||||||
|
window.navigator.msSaveOrOpenBlob(blobObject, fileName)
|
||||||
|
} else {
|
||||||
|
const url = URL.createObjectURL(new Blob([res.data]))
|
||||||
|
const a = document.createElement('a')
|
||||||
|
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.target = '_blank'
|
||||||
|
a.click()
|
||||||
|
a.remove() // 将a标签移除
|
||||||
|
}
|
||||||
|
}, error => {
|
||||||
|
const $self = this
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = function (event) {
|
||||||
|
const responseText = reader.result
|
||||||
|
const exception = JSON.parse(responseText)
|
||||||
|
if (exception.message) {
|
||||||
|
$self.$message.error(exception.message)
|
||||||
|
} else {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsText(error.response.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fileChange (file, fileList) {
|
||||||
|
if (file.status !== 'ready') return
|
||||||
|
if (!_.endsWith(file.name, '.xml')) {
|
||||||
|
this.fileList = []
|
||||||
|
this.$message.error('Only support '+ this.fileTypeLimit + ' files')
|
||||||
|
} else {
|
||||||
|
this.fileList = fileList.slice(-1)
|
||||||
|
this.$refs.licenseUpload.submit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadSuccess (response) {
|
||||||
|
this.$message.success('Success')
|
||||||
|
this.licenseStatus = 0
|
||||||
|
},
|
||||||
|
uploadError (error) {
|
||||||
|
let errorMsg
|
||||||
|
if (error.message) {
|
||||||
|
errorMsg = JSON.parse(error.message).message
|
||||||
|
} else {
|
||||||
|
errorMsg = 'error'
|
||||||
|
}
|
||||||
|
this.licenseStatus = 1
|
||||||
|
this.$message.error('Upload failed: ' + errorMsg)
|
||||||
|
},
|
||||||
|
checkLicenseStatus () {
|
||||||
|
axios.get(api.licenseStatus).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.licenseStatus = res.data.data.status
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
this.licenseStatusErrMsg = this.errorMsgHandler(e)
|
||||||
|
})
|
||||||
|
},
|
||||||
queryAppearance () {
|
queryAppearance () {
|
||||||
axios.get(api.appearance).then(res => {
|
axios.get(api.appearance).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
@@ -128,13 +226,17 @@ export default {
|
|||||||
localStorage.setItem(storageKey.sysLogo, data.system_logo)
|
localStorage.setItem(storageKey.sysLogo, data.system_logo)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
async mounted () {
|
||||||
this.queryAppearance()
|
this.queryAppearance()
|
||||||
|
this.checkLicenseStatus()
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
const { currentRoute } = useRouter()
|
const { currentRoute } = useRouter()
|
||||||
return {
|
return {
|
||||||
loginSuccessPath: currentRoute.value.query.redirect
|
loginSuccessPath: currentRoute.value.query.redirect,
|
||||||
|
baseUrl: BASE_CONFIG.baseUrl,
|
||||||
|
fileTypeLimit: '.xml',
|
||||||
|
fileList: ref([])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +283,7 @@ export default {
|
|||||||
}
|
}
|
||||||
.inside {
|
.inside {
|
||||||
width: 414px;
|
width: 414px;
|
||||||
height: 524px;
|
height: fit-content;/*524*/
|
||||||
background: #0B325C;
|
background: #0B325C;
|
||||||
border: 1px solid rgba(103,179,245,0.65);
|
border: 1px solid rgba(103,179,245,0.65);
|
||||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.38);
|
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.38);
|
||||||
@@ -198,6 +300,7 @@ export default {
|
|||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: 65px;
|
margin-top: 65px;
|
||||||
|
margin-bottom: 44px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.title > img {
|
.title > img {
|
||||||
@@ -208,6 +311,39 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
.is-disabled {
|
||||||
|
background: #21B4ED;
|
||||||
|
color: #FFFFFF;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.license-error-msg {
|
||||||
|
color:#c73249;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
height:40px;
|
||||||
|
}
|
||||||
|
.license-file {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
.license__btn {
|
||||||
|
height: 40px;
|
||||||
|
padding-left:10px;
|
||||||
|
padding-right:10px;
|
||||||
|
min-width: 74px;
|
||||||
|
color: white;
|
||||||
|
background-color: #21B4ED;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
outline: none;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color linear .2s, color linear .1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep .el-form-item {
|
:deep .el-form-item {
|
||||||
width: 334px;
|
width: 334px;
|
||||||
@@ -220,9 +356,8 @@ export default {
|
|||||||
width: 17px;
|
width: 17px;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
}
|
}
|
||||||
.login__box .el-form-item:nth-of-type(3) {
|
.login__box .el-form-item:nth-child(3){
|
||||||
margin-top: 25px;
|
margin-bottom: 0px;
|
||||||
margin-bottom: 65px;
|
|
||||||
}
|
}
|
||||||
.login--button {
|
.login--button {
|
||||||
background: #21B4ED;
|
background: #21B4ED;
|
||||||
@@ -234,5 +369,12 @@ export default {
|
|||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
width: 334px;
|
width: 334px;
|
||||||
height: 52px;
|
height: 52px;
|
||||||
|
margin-top: 25px;
|
||||||
|
margin-bottom:65px;
|
||||||
|
}
|
||||||
|
.login-btn__license-error {
|
||||||
|
margin-top: 25px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height:40px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
|
|
||||||
@import 'views/administration/AdministrationTabs';
|
@import 'views/administration/AdministrationTabs';
|
||||||
@import 'views/administration/Appearance.scss';
|
@import 'views/administration/Appearance.scss';
|
||||||
|
@import 'views/administration/License.scss';
|
||||||
|
|
||||||
@import 'views/system/Plugin';
|
@import 'views/system/Plugin';
|
||||||
|
|
||||||
|
|||||||
61
src/assets/css/components/views/administration/License.scss
Normal file
61
src/assets/css/components/views/administration/License.scss
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
.license{
|
||||||
|
height: 100%;
|
||||||
|
.license-form {
|
||||||
|
padding-top:40px;
|
||||||
|
padding-left:100px;
|
||||||
|
background-color: white;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
.license-file {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 3px;
|
||||||
|
.license__btn {
|
||||||
|
height: 30px;
|
||||||
|
min-width: 74px;
|
||||||
|
color: white;
|
||||||
|
background-color: #38ACD2;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
outline: none;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color linear .2s, color linear .1s;
|
||||||
|
}
|
||||||
|
.license__btn:hover:not(.footer__btn--disabled) {
|
||||||
|
background-color: lighten(#38ACD2, 10%);
|
||||||
|
}
|
||||||
|
.license__btn--light {
|
||||||
|
background-color: #F5F6F7;
|
||||||
|
border: 1px solid $--border-color-primary;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.license__btn.license__btn--light:hover:not(.license__btn--disabled) {
|
||||||
|
background-color: white;
|
||||||
|
border-color: lighten(#38ACD2, 40%);
|
||||||
|
color: #38ACD2;
|
||||||
|
}
|
||||||
|
.license__btn--disabled {
|
||||||
|
opacity: .6;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form .el-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding:4px 0;
|
||||||
|
font-size: 14px!important;
|
||||||
|
.el-form-item__label {
|
||||||
|
color: #262626 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.el-form-item__content {
|
||||||
|
color: #262626 !important;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
color: #046ECA;
|
color: #046ECA;
|
||||||
box-shadow: 0 2px 4px 0 rgba(51,51,51,0.02);
|
box-shadow: 0 2px 4px 0 rgba(51,51,51,0.02);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
margin-right:10px;
|
||||||
}
|
}
|
||||||
.plugin-name {
|
.plugin-name {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "cn-icon"; /* Project id 2614877 */
|
font-family: "cn-icon"; /* Project id 2614877 */
|
||||||
src: url('iconfont.woff2?t=1703561754372') format('woff2'),
|
src: url('iconfont.woff2?t=1706606024800') format('woff2'),
|
||||||
url('iconfont.woff?t=1703561754372') format('woff'),
|
url('iconfont.woff?t=1706606024800') format('woff'),
|
||||||
url('iconfont.ttf?t=1703561754372') format('truetype');
|
url('iconfont.ttf?t=1706606024800') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-icon {
|
.cn-icon {
|
||||||
@@ -13,6 +13,26 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cn-icon-license:before {
|
||||||
|
content: "\e666";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-base-station:before {
|
||||||
|
content: "\e6cf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-home:before {
|
||||||
|
content: "\e6d0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-company:before {
|
||||||
|
content: "\e6d1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cn-icon-pedestrian:before {
|
||||||
|
content: "\e6d2";
|
||||||
|
}
|
||||||
|
|
||||||
.cn-icon-system:before {
|
.cn-icon-system:before {
|
||||||
content: "\e6cc";
|
content: "\e6cc";
|
||||||
}
|
}
|
||||||
@@ -373,7 +393,7 @@
|
|||||||
content: "\e7b4";
|
content: "\e7b4";
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-icon-a-GeneralSettings:before {
|
.cn-icon-general-setting:before {
|
||||||
content: "\e7b5";
|
content: "\e7b5";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1135,12 +1135,12 @@ export default class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return returnObj
|
return returnObj
|
||||||
} else if (q.indexOf(' LIKE ') > -1 || q.indexOf(' like ') > -1) {
|
} else if (q.toLowerCase().indexOf(' like ') > -1) {
|
||||||
return {
|
return {
|
||||||
key: q,
|
key: q,
|
||||||
isKey: true
|
isKey: true
|
||||||
}
|
}
|
||||||
} else if (q.indexOf(' IN ') > -1 || q.indexOf(' in ') > -1) {
|
} else if (q.toLowerCase().indexOf(' in ') > -1) {
|
||||||
return {
|
return {
|
||||||
key: q,
|
key: q,
|
||||||
isKey: true
|
isKey: true
|
||||||
@@ -1154,15 +1154,79 @@ export default class Parser {
|
|||||||
return { key: '[' + key + ']', isKey: false }
|
return { key: '[' + key + ']', isKey: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (q && (q.indexOf(' IN ') > -1 || q.indexOf(' in ') > -1 || q.indexOf(' LIKE ') > -1 || q.indexOf(' like ') > -1)) {
|
} else if (q && (q.toLowerCase().indexOf(' in ') > -1 || q.toLowerCase().indexOf(' like ') > -1 || q.toLowerCase().indexOf('has(') > -1)) {
|
||||||
return {
|
const lowerQ = q.toLowerCase()
|
||||||
key: q,
|
if (lowerQ.indexOf(' and ') > -1) {
|
||||||
isKey: true
|
if (this.checkStrIncludeAnd(q)) {
|
||||||
|
q = q.replace(/ and /g, ' AND ')
|
||||||
|
}
|
||||||
|
const arr = q.split(' AND ')
|
||||||
|
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
const item = arr[i].toLowerCase()
|
||||||
|
if (item.indexOf(' like ') > -1) {
|
||||||
|
const key = item.substring(0, item.indexOf(' like '))
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||||
|
if (!obj) {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else if (item.indexOf(' in ') > -1) {
|
||||||
|
const key = q.substring(0, q.indexOf(' in '))
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||||
|
if (!obj) {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else if (item.indexOf('has(') > -1) {
|
||||||
|
const key = item.substring(0, 4)
|
||||||
|
if (key === 'has(') {
|
||||||
|
const label = item.substring(4, item.indexOf(','))
|
||||||
|
if (label) {
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === label.toLowerCase())
|
||||||
|
if (!obj) {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { key: 'in index ' + q.indexOf('has('), isKey: false }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { key: 'in index ' + q.indexOf('has('), isKey: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { key: q, isKey: true }
|
||||||
|
} else if (lowerQ.indexOf(' like ') > -1) {
|
||||||
|
const key = q.substring(0, q.indexOf(' like '))
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||||
|
if (obj) {
|
||||||
|
return { key: obj.label + q.substring(lowerQ.indexOf(' like '), q.length), isKey: true }
|
||||||
|
} else {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else if (lowerQ.indexOf(' in ') > -1) {
|
||||||
|
const key = lowerQ.substring(0, lowerQ.indexOf(' in '))
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||||
|
if (obj) {
|
||||||
|
return { key: obj.label + q.substring(lowerQ.indexOf(' in '), q.length), isKey: true }
|
||||||
|
} else {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else if (lowerQ.indexOf('has(') > -1) {
|
||||||
|
const key = lowerQ.substring(0, 4)
|
||||||
|
if (key === 'has(') {
|
||||||
|
const label = lowerQ.substring(4, lowerQ.indexOf(','))
|
||||||
|
if (label) {
|
||||||
|
const obj = this.columnList.find(t => t.label.toLowerCase() === label.toLowerCase())
|
||||||
|
if (obj) {
|
||||||
|
return { key: 'has(' + obj.label + q.substring(lowerQ.indexOf(','), lowerQ.length), isKey: true }
|
||||||
|
} else {
|
||||||
|
return { key: '[' + key + ']', isKey: false }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { key: 'in index 5', isKey: false }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return { key: 'in index 5', isKey: false }
|
||||||
}
|
}
|
||||||
} else if (q && (q.indexOf('has(') > -1)) {
|
|
||||||
return {
|
|
||||||
key: q,
|
|
||||||
isKey: true
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@@ -1257,6 +1321,10 @@ export default class Parser {
|
|||||||
})
|
})
|
||||||
return str
|
return str
|
||||||
} else if (!result) {
|
} else if (!result) {
|
||||||
|
// 此处为不能识别的字段,不能当成app处理
|
||||||
|
if (str.indexOf('=') > -1 || str.toLowerCase().indexOf(' in ') > -1 || str.toLowerCase().indexOf(' like ') > -1 || str.toLowerCase().indexOf('has(') > -1) {
|
||||||
|
return str
|
||||||
|
}
|
||||||
const regex = /^["']|["']$/
|
const regex = /^["']|["']$/
|
||||||
// 去除两侧引号,如'1.1.1.1',避免校验时被当作app
|
// 去除两侧引号,如'1.1.1.1',避免校验时被当作app
|
||||||
if (regex.test(str)) {
|
if (regex.test(str)) {
|
||||||
|
|||||||
@@ -190,6 +190,7 @@
|
|||||||
:format="dateFormat"
|
:format="dateFormat"
|
||||||
prefix-icon="cn-icon cn-icon-shijian"
|
prefix-icon="cn-icon cn-icon-shijian"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
|
@change="onChangeSchedulerStart"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -206,6 +207,7 @@
|
|||||||
:format="dateFormat"
|
:format="dateFormat"
|
||||||
prefix-icon="cn-icon cn-icon-shijian"
|
prefix-icon="cn-icon cn-icon-shijian"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
|
@change="onChangeSchedulerEnd"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,7 +244,7 @@
|
|||||||
placeholder=" "
|
placeholder=" "
|
||||||
filterable
|
filterable
|
||||||
:disabled="!!editObject.id"
|
:disabled="!!editObject.id"
|
||||||
popper-class="right-box-select-dropdown right-box-select-report "
|
popper-class="search-select right-box-select-dropdown right-box-select-report "
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
@@ -276,7 +278,7 @@ import { storageKey, report } from '@/utils/constants'
|
|||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { dateFormat, getMillisecond } from '@/utils/date-util'
|
import { dateFormat, getMillisecond, millTimestampDiffFromTz } from '@/utils/date-util'
|
||||||
import { ref, getCurrentInstance } from 'vue'
|
import { ref, getCurrentInstance } from 'vue'
|
||||||
import i18n from '@/i18n'
|
import i18n from '@/i18n'
|
||||||
export default {
|
export default {
|
||||||
@@ -292,10 +294,12 @@ export default {
|
|||||||
const startTime = ref('')
|
const startTime = ref('')
|
||||||
const endTime = ref('')
|
const endTime = ref('')
|
||||||
function endTimeChange (val) {
|
function endTimeChange (val) {
|
||||||
endTime.value = val
|
// endTime.value = val + millTimestampDiffFromTz()
|
||||||
|
endTime.value = getMillisecond(val) + millTimestampDiffFromTz()
|
||||||
}
|
}
|
||||||
function startTimeChang (val) {
|
function startTimeChang (val) {
|
||||||
startTime.value = val
|
// startTime.value = val + millTimestampDiffFromTz()
|
||||||
|
startTime.value = getMillisecond(val) + millTimestampDiffFromTz()
|
||||||
}
|
}
|
||||||
const endDisabledDate = (time) => {
|
const endDisabledDate = (time) => {
|
||||||
if (time.getTime() > new Date()) {
|
if (time.getTime() > new Date()) {
|
||||||
@@ -332,7 +336,7 @@ export default {
|
|||||||
}
|
}
|
||||||
const startTimeValidator = (rule, value, callback) => {
|
const startTimeValidator = (rule, value, callback) => {
|
||||||
const form = proxy.$refs.reportForm
|
const form = proxy.$refs.reportForm
|
||||||
if (form.model.config.endTime) {
|
if (form.model && form.model.config && form.model.config.endTime) {
|
||||||
form.validateField('config.endTime', () => null)
|
form.validateField('config.endTime', () => null)
|
||||||
}
|
}
|
||||||
callback()
|
callback()
|
||||||
@@ -352,9 +356,6 @@ export default {
|
|||||||
categoryId: [
|
categoryId: [
|
||||||
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' }
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' }
|
||||||
],
|
],
|
||||||
schedulerStart: [
|
|
||||||
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' }
|
|
||||||
],
|
|
||||||
'config.startTime': [
|
'config.startTime': [
|
||||||
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' },
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' },
|
||||||
{ validator: startTimeValidator, trigger: 'change' }
|
{ validator: startTimeValidator, trigger: 'change' }
|
||||||
@@ -368,15 +369,53 @@ export default {
|
|||||||
{ validator: paramValidator, message: i18n.global.t('validate.required'), trigger: 'blur' }
|
{ validator: paramValidator, message: i18n.global.t('validate.required'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
const mySchedulerStart = ref('')
|
||||||
|
const mySchedulerEnd = ref('')
|
||||||
|
const onChangeSchedulerStart = (val) => {
|
||||||
|
mySchedulerStart.value = getMillisecond(val) + millTimestampDiffFromTz()
|
||||||
|
}
|
||||||
|
const onChangeSchedulerEnd = (val) => {
|
||||||
|
mySchedulerEnd.value = getMillisecond(val) + millTimestampDiffFromTz()
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
endDisabledDate,
|
endDisabledDate,
|
||||||
startDisabledDate,
|
startDisabledDate,
|
||||||
startTimeChang,
|
startTimeChang,
|
||||||
endTimeChange,
|
endTimeChange,
|
||||||
rules
|
rules,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
mySchedulerStart,
|
||||||
|
mySchedulerEnd,
|
||||||
|
onChangeSchedulerStart,
|
||||||
|
onChangeSchedulerEnd
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
const schedulerStartTimeValidator = (rule, value, callback) => {
|
||||||
|
if (this.editObject.schedulerEnd) {
|
||||||
|
if (this.$refs.reportForm) {
|
||||||
|
this.$refs.reportForm.validateField('schedulerEnd')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const schedulerEndTimeValidator = (rule, value, callback) => {
|
||||||
|
if (value && this.editObject.schedulerStart && (getMillisecond(this.editObject.schedulerStart) >= getMillisecond(value))) {
|
||||||
|
callback(new Error(this.$t('config.user.timeVerification')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rules.schedulerStart = [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' },
|
||||||
|
{ validator: schedulerStartTimeValidator, trigger: 'change' }
|
||||||
|
]
|
||||||
|
this.rules.schedulerEnd = [
|
||||||
|
{ validator: schedulerEndTimeValidator, trigger: 'change' }
|
||||||
|
]
|
||||||
return {
|
return {
|
||||||
url: api.reportTemp,
|
url: api.reportTemp,
|
||||||
|
|
||||||
@@ -403,7 +442,9 @@ export default {
|
|||||||
monthWeekdayCheckedAll: false,
|
monthWeekdayCheckedAll: false,
|
||||||
monthWeekdayIsIndeterminate: false,
|
monthWeekdayIsIndeterminate: false,
|
||||||
|
|
||||||
paramsOptions: []
|
paramsOptions: [],
|
||||||
|
newParamsOptions: [],
|
||||||
|
rangeNumber: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -414,6 +455,7 @@ export default {
|
|||||||
scheduleChecked (n) {
|
scheduleChecked (n) {
|
||||||
this.editObject.config.isScheduler = n ? 1 : 0
|
this.editObject.config.isScheduler = n ? 1 : 0
|
||||||
this.cleanScheduleConfig()
|
this.cleanScheduleConfig()
|
||||||
|
this.initDateCalendarPreIcon()
|
||||||
},
|
},
|
||||||
monthScheduleType (n) {
|
monthScheduleType (n) {
|
||||||
this.cleanScheduleConfig()
|
this.cleanScheduleConfig()
|
||||||
@@ -495,6 +537,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n.config) {
|
||||||
|
if (n.config.startTime) {
|
||||||
|
this.editObject.config.startTime = getMillisecond(n.config.startTime) - millTimestampDiffFromTz()
|
||||||
|
}
|
||||||
|
if (n.config.endTime) {
|
||||||
|
this.editObject.config.endTime = getMillisecond(n.config.endTime) - millTimestampDiffFromTz()
|
||||||
|
}
|
||||||
|
}
|
||||||
if (n.schedulerStart) {
|
if (n.schedulerStart) {
|
||||||
this.editObject.schedulerStart = dateFormat(this.editObject.schedulerStart, this.dateFormat)
|
this.editObject.schedulerStart = dateFormat(this.editObject.schedulerStart, this.dateFormat)
|
||||||
}
|
}
|
||||||
@@ -521,10 +571,24 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initDateCalendarPreIcon()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initDateCalendarPreIcon () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const datePrefixIcon = document.getElementsByClassName('el-input__prefix-inner')
|
||||||
|
if (datePrefixIcon && datePrefixIcon.length > 0) {
|
||||||
|
Array.prototype.forEach.call(datePrefixIcon, function (element) {
|
||||||
|
element.innerHTML = '<i class="el-input__icon cn-icon cn-icon-shijian"></i>'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
loadParamOptions () {
|
loadParamOptions () {
|
||||||
if (_.isArray(this.editObject.categoryParams) && !_.isEmpty(this.editObject.categoryParams)) {
|
if (_.isArray(this.editObject.categoryParams) && !_.isEmpty(this.editObject.categoryParams)) {
|
||||||
this.editObject.categoryParams.forEach(param => {
|
this.editObject.categoryParams.forEach(param => {
|
||||||
|
// this.paramsOptions = _.cloneDeep(this.newParamsOptions)
|
||||||
if (!this.paramsOptions.some(p => p.key === param.key)) {
|
if (!this.paramsOptions.some(p => p.key === param.key)) {
|
||||||
axios.get(api.dict, { params: { type: param.key, pageSize: -1 } }).then(response => {
|
axios.get(api.dict, { params: { type: param.key, pageSize: -1 } }).then(response => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
@@ -532,6 +596,7 @@ export default {
|
|||||||
key: param.key,
|
key: param.key,
|
||||||
options: response.data.data.list.map(d => d.value)
|
options: response.data.data.list.map(d => d.value)
|
||||||
})
|
})
|
||||||
|
// this.newParamsOptions = this.paramsOptions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -569,6 +634,7 @@ export default {
|
|||||||
if (val === 'customize') {
|
if (val === 'customize') {
|
||||||
this.scheduleChecked = false
|
this.scheduleChecked = false
|
||||||
}
|
}
|
||||||
|
this.initDateCalendarPreIcon()
|
||||||
},
|
},
|
||||||
scheduleTypeChange (val) {
|
scheduleTypeChange (val) {
|
||||||
this.scheduleType = val
|
this.scheduleType = val
|
||||||
@@ -584,10 +650,12 @@ export default {
|
|||||||
let schedulerStart = ''
|
let schedulerStart = ''
|
||||||
let schedulerEnd = ''
|
let schedulerEnd = ''
|
||||||
if (this.editObject.config && this.editObject.config.startTime) {
|
if (this.editObject.config && this.editObject.config.startTime) {
|
||||||
startTime = getMillisecond(this.editObject.config.startTime)
|
// startTime = getMillisecond(this.editObject.config.startTime)
|
||||||
|
startTime = this.startTime ? this.startTime : this.object.config.startTime
|
||||||
}
|
}
|
||||||
if (this.editObject.config && this.editObject.config.endTime) {
|
if (this.editObject.config && this.editObject.config.endTime) {
|
||||||
endTime = getMillisecond(this.editObject.config.endTime)
|
// endTime = getMillisecond(this.editObject.config.endTime)
|
||||||
|
endTime = this.endTime ? this.endTime : this.object.config.endTime
|
||||||
}
|
}
|
||||||
if (this.editObject.config && this.editObject.config.schedulerConfig) {
|
if (this.editObject.config && this.editObject.config.schedulerConfig) {
|
||||||
if (['day', 'week', 'month'].indexOf(this.editObject.config.schedulerConfig.type) > -1) {
|
if (['day', 'week', 'month'].indexOf(this.editObject.config.schedulerConfig.type) > -1) {
|
||||||
@@ -597,10 +665,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.editObject.schedulerStart) {
|
if (this.editObject.schedulerStart) {
|
||||||
schedulerStart = getMillisecond(this.editObject.schedulerStart)
|
// schedulerStart = getMillisecond(this.editObject.schedulerStart)
|
||||||
|
schedulerStart = this.mySchedulerStart ? this.mySchedulerStart : this.object.schedulerStart
|
||||||
}
|
}
|
||||||
if (this.editObject.schedulerEnd) {
|
if (this.editObject.schedulerEnd) {
|
||||||
schedulerEnd = getMillisecond(this.editObject.schedulerEnd)
|
// schedulerEnd = getMillisecond(this.editObject.schedulerEnd)
|
||||||
|
schedulerEnd = this.mySchedulerEnd ? this.mySchedulerEnd : this.object.schedulerEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyObject = _.cloneDeep(this.editObject)
|
const copyObject = _.cloneDeep(this.editObject)
|
||||||
@@ -721,6 +791,36 @@ export default {
|
|||||||
const checkedCount = val.length
|
const checkedCount = val.length
|
||||||
this.monthWeekdayCheckedAll = checkedCount === this.weekdayList.length
|
this.monthWeekdayCheckedAll = checkedCount === this.weekdayList.length
|
||||||
this.monthWeekdayIsIndeterminate = checkedCount > 0 && checkedCount < this.weekdayList.length
|
this.monthWeekdayIsIndeterminate = checkedCount > 0 && checkedCount < this.weekdayList.length
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* params的option筛选方法,组件自带的方法在paramsOptions的options长度超过1512后会保留部分值
|
||||||
|
* @param filterVal
|
||||||
|
*/
|
||||||
|
filterMethod (filterVal) {
|
||||||
|
const key = this.editObject.categoryParams[0].key
|
||||||
|
if (filterVal) {
|
||||||
|
const obj = this.newParamsOptions.find(d => d.key === key)
|
||||||
|
if (_.isString(filterVal) && obj) {
|
||||||
|
const filterArr = _.cloneDeep(obj.options).filter(d => d.toLowerCase().includes(filterVal.toLowerCase()))
|
||||||
|
const paramsOptionsObj = this.paramsOptions.find(d => d.key === key)
|
||||||
|
paramsOptionsObj.options = filterArr
|
||||||
|
} else if (_.isNumber(filterVal) && obj) {
|
||||||
|
const filterArr = _.cloneDeep(obj.options).filter(d => d.toLowerCase().includes(filterVal))
|
||||||
|
const paramsOptionsObj = this.paramsOptions.find(d => d.key === key)
|
||||||
|
paramsOptionsObj.options = filterArr
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.paramsOptions = _.cloneDeep(this.newParamsOptions)
|
||||||
|
this.rangeNumber = 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadMore () {
|
||||||
|
this.rangeNumber += 10
|
||||||
|
},
|
||||||
|
onVisibleChange (flag) {
|
||||||
|
if (!flag) {
|
||||||
|
this.rangeNumber = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,19 +37,19 @@
|
|||||||
</el-switch>
|
</el-switch>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'type'">
|
<template v-else-if="item.prop === 'type'">
|
||||||
<span class="type-tag">{{typeText(scope.row['id'])}}</span>
|
<span class="type-tag" v-for="type in scope.row.type">{{type}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'name'">
|
<template v-else-if="item.prop === 'name'">
|
||||||
<div class="plugin-name">
|
<div class="plugin-name">
|
||||||
<div class="icon-background"><img class="plugin-name-icon" :src="getIconUrl(scope.row['id'])"/></div>
|
<div class="icon-background"><img class="plugin-name-icon" :src="scope.row['iconUrl']"/></div>
|
||||||
{{getName(scope.row['id'])}}
|
{{scope.row['name']}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'description'">
|
<template v-else-if="item.prop === 'description'">
|
||||||
<div class="two-line" :title="getDescription(scope.row['id'])">{{getDescription(scope.row['id'])}}</div>
|
<div class="two-line" :title="$t(scope.row['desc'])">{{$t(scope.row['desc'])}}</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'schedule'">
|
<template v-else-if="item.prop === 'schedule'">
|
||||||
<div class="two-line" >{{scheduleText(scope.row['id'])}}</div>
|
<div class="two-line" >{{$t(scope.row['schedule'])}}</div>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{scope.row[item.prop] || '-'}}</span>
|
<span v-else>{{scope.row[item.prop] || '-'}}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -110,36 +110,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
typeText () {
|
|
||||||
return function (id) {
|
|
||||||
const t = pluginBasicInfo.find(t => t.id === id)
|
|
||||||
return t ? t.type : 'Unknown Tag'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scheduleText () {
|
|
||||||
return function (id) {
|
|
||||||
const basicInfo = pluginBasicInfo.find(bi => bi.id === id)
|
|
||||||
return basicInfo ? this.$t(basicInfo.schedule) : ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getIconUrl () {
|
|
||||||
return function (id) {
|
|
||||||
const basicInfo = pluginBasicInfo.find(bi => bi.id === id)
|
|
||||||
return basicInfo ? basicInfo.iconUrl : ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getDescription () {
|
|
||||||
return function (id) {
|
|
||||||
const basicInfo = pluginBasicInfo.find(bi => bi.id === id)
|
|
||||||
return basicInfo ? this.$t(basicInfo.desc) : '-'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getName () {
|
|
||||||
return function (id) {
|
|
||||||
const basicInfo = pluginBasicInfo.find(bi => bi.id === id)
|
|
||||||
return basicInfo ? this.$t(basicInfo.name) : '-'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
statusChange (plugin) {
|
statusChange (plugin) {
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ export function handleComponent (code) {
|
|||||||
return () => import('@/views/administration/OperationLog')
|
return () => import('@/views/administration/OperationLog')
|
||||||
case 'appearance':
|
case 'appearance':
|
||||||
return () => import('@/views/administration/Appearance')
|
return () => import('@/views/administration/Appearance')
|
||||||
|
case 'license':
|
||||||
|
return () => import('@/views/administration/License')
|
||||||
case 'I18N':
|
case 'I18N':
|
||||||
return () => import('@/views/administration/I18n')
|
return () => import('@/views/administration/I18n')
|
||||||
case 'system':
|
case 'system':
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ export const api = {
|
|||||||
logout: '/logout',
|
logout: '/logout',
|
||||||
pin: 'sys/user/pin',
|
pin: 'sys/user/pin',
|
||||||
appearance: '/sys/appearance',
|
appearance: '/sys/appearance',
|
||||||
|
license: '/sys/license/detail',
|
||||||
|
licenseStatus: '/sys/license/status',
|
||||||
|
downloadLicenseC2v: '/sys/license/download',
|
||||||
permissions: '/sys/user/permissions',
|
permissions: '/sys/user/permissions',
|
||||||
operationLog: '/sys/log',
|
operationLog: '/sys/log',
|
||||||
login: '/sys/login',
|
login: '/sys/login',
|
||||||
|
|||||||
@@ -1883,116 +1883,84 @@ export const performanceMetricMapping = {
|
|||||||
|
|
||||||
export const pluginBasicInfo = [
|
export const pluginBasicInfo = [
|
||||||
{
|
{
|
||||||
id: 110,
|
id: 109,
|
||||||
|
name: 'Psiphon3 VPN',
|
||||||
|
type: ['IP'],
|
||||||
|
schedule: 'plugin.hourly',
|
||||||
|
desc: 'knowledgeBase.desc.psiphon3',
|
||||||
|
iconUrl: 'images/knowledge-base-logo/psiphon3-vpn.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 111,
|
||||||
name: 'HotSpot VPN',
|
name: 'HotSpot VPN',
|
||||||
type: 'IP',
|
type: ['IP'],
|
||||||
schedule: 'plugin.daily',
|
schedule: 'plugin.hourly',
|
||||||
desc: 'knowledgeBase.desc.hotSpot',
|
desc: 'knowledgeBase.desc.hotSpot',
|
||||||
iconUrl: 'images/knowledge-base-logo/hotspot-vpn.png'
|
iconUrl: 'images/knowledge-base-logo/hotspot-vpn.png'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 111,
|
id: 112,
|
||||||
name: 'IpVanish VPN',
|
name: 'IpVanish VPN',
|
||||||
type: 'Domain',
|
type: ['IP', 'Domain'],
|
||||||
schedule: 'plugin.hourly',
|
schedule: 'plugin.hourly',
|
||||||
desc: 'knowledgeBase.desc.ipVanishDomain',
|
desc: 'knowledgeBase.desc.ipVanishDomain',
|
||||||
iconUrl: 'images/knowledge-base-logo/ip-vanish.png'
|
iconUrl: 'images/knowledge-base-logo/ip-vanish.png'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 112,
|
|
||||||
name: 'IpVanish VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.ipVanishIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/ip-vanish.png'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 113,
|
id: 113,
|
||||||
name: 'CyberGhost VPN',
|
|
||||||
type: 'Domain',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.cyberGhostDomain',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/cyber-ghost.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 114,
|
|
||||||
name: 'CyberGhost VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.cyberGhostIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/cyber-ghost.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 115,
|
|
||||||
name: 'Gecko VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.geckoIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/gecko.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 116,
|
|
||||||
name: 'Ivacy VPN',
|
name: 'Ivacy VPN',
|
||||||
type: 'Domain',
|
type: ['IP', 'Domain'],
|
||||||
schedule: 'plugin.hourly',
|
schedule: 'plugin.daily',
|
||||||
desc: 'knowledgeBase.desc.ivacyDomain',
|
desc: 'knowledgeBase.desc.ivacyDomain',
|
||||||
iconUrl: 'images/knowledge-base-logo/ivacy.png'
|
iconUrl: 'images/knowledge-base-logo/ivacy.png'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 117,
|
id: 114,
|
||||||
name: 'Ivacy VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.ivacyIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/ivacy.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 118,
|
|
||||||
name: 'Turbo VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.turboIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/turbo.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 119,
|
|
||||||
name: 'Vpnunlimited',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.vpnunlimited',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/vpnunlimited.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 120,
|
|
||||||
name: 'Windscribe VPN',
|
|
||||||
type: 'Domain',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.windscribeDomain',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/windscribe.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 121,
|
|
||||||
name: 'Windscribe VPN',
|
|
||||||
type: 'IP',
|
|
||||||
schedule: 'plugin.hourly',
|
|
||||||
desc: 'knowledgeBase.desc.windscribeIp',
|
|
||||||
iconUrl: 'images/knowledge-base-logo/windscribe.png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 122,
|
|
||||||
name: 'Proton VPN',
|
name: 'Proton VPN',
|
||||||
type: 'IP',
|
type: ['IP'],
|
||||||
schedule: 'plugin.hourly',
|
schedule: 'plugin.hourly',
|
||||||
desc: 'knowledgeBase.desc.protonvpn',
|
desc: 'knowledgeBase.desc.protonvpn',
|
||||||
iconUrl: 'images/knowledge-base-logo/protonvpn.png'
|
iconUrl: 'images/knowledge-base-logo/protonvpn.png'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 109,
|
id: 115,
|
||||||
name: 'Psiphon3 VPN',
|
name: 'CyberGhost VPN',
|
||||||
type: 'IP',
|
type: ['IP', 'Domain'],
|
||||||
schedule: 'plugin.always',
|
schedule: 'plugin.daily',
|
||||||
desc: 'knowledgeBase.desc.psiphon3',
|
desc: 'knowledgeBase.desc.cyberGhostDomain',
|
||||||
iconUrl: 'images/knowledge-base-logo/psiphon3-vpn.png'
|
iconUrl: 'images/knowledge-base-logo/cyber-ghost.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 116,
|
||||||
|
name: 'Windscribe VPN',
|
||||||
|
type: ['IP', 'Domain'],
|
||||||
|
schedule: 'plugin.hourly',
|
||||||
|
desc: 'knowledgeBase.desc.windscribeDomain',
|
||||||
|
iconUrl: 'images/knowledge-base-logo/windscribe.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 117,
|
||||||
|
name: 'Turbo VPN',
|
||||||
|
type: ['IP'],
|
||||||
|
schedule: 'plugin.hourly',
|
||||||
|
desc: 'knowledgeBase.desc.turboIp',
|
||||||
|
iconUrl: 'images/knowledge-base-logo/turbo.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 118,
|
||||||
|
name: 'Gecko VPN',
|
||||||
|
type: ['IP'],
|
||||||
|
schedule: 'plugin.hourly',
|
||||||
|
desc: 'knowledgeBase.desc.geckoIp',
|
||||||
|
iconUrl: 'images/knowledge-base-logo/gecko.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 119,
|
||||||
|
name: 'Vpnunlimited',
|
||||||
|
type: ['IP'],
|
||||||
|
schedule: 'plugin.hourly',
|
||||||
|
desc: 'knowledgeBase.desc.vpnunlimited',
|
||||||
|
iconUrl: 'images/knowledge-base-logo/vpnunlimited.png'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ axios.interceptors.request.use(config => {
|
|||||||
err => Promise.reject(err)
|
err => Promise.reject(err)
|
||||||
)
|
)
|
||||||
const accountErrorCode = [518003, 518004, 518005, 518006, 518007, 518008] // 账号锁定等
|
const accountErrorCode = [518003, 518004, 518005, 518006, 518007, 518008] // 账号锁定等
|
||||||
const licenceErrorCode = [711001]
|
const licenceErrorCode = [715001]
|
||||||
|
|
||||||
// 若get请求的url中带问号,则将url上的参数截取,改为对象形式传参
|
// 若get请求的url中带问号,则将url上的参数截取,改为对象形式传参
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
|
|||||||
159
src/views/administration/License.vue
Normal file
159
src/views/administration/License.vue
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
<template>
|
||||||
|
<div class="license" :class="from">
|
||||||
|
<div class="license-form">
|
||||||
|
<el-form ref="licenseForm" :model="licenseObject" label-position="left" label-width="134px" size="small">
|
||||||
|
<el-form-item :label="`${$t('license.type')}:`" prop="type">
|
||||||
|
{{licenseObject.type}}
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`${$t('license.organization')}:`" prop="organization">
|
||||||
|
<div class="">{{licenseObject.organization}}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`${$t('license.supportId')}:`" prop="supportID">
|
||||||
|
<div class="">{{licenseObject.supportID}}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`${$t('license.dateIssued')}:`" prop="dateIssued">
|
||||||
|
<div class="">{{licenseObject.dateIssued}}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`${$t('license.dateExpires')}:`" prop="dateExpires">
|
||||||
|
<div class="">{{licenseObject.dateExpires}}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`${$t('license.licenseFile')}:`" >
|
||||||
|
<div class="license-file">
|
||||||
|
<button style="position: relative;" class="license__btn margin-r-20" @click.prevent="downloadFile">
|
||||||
|
<i class="cn-icon-download1 cn-icon margin-r-6"></i><span>{{$t('license.download')}}</span>
|
||||||
|
</button>
|
||||||
|
<el-upload :action="`${baseUrl}sys/license/upload`"
|
||||||
|
ref="licenseUpload"
|
||||||
|
id="licenseUpload"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:multiple="false"
|
||||||
|
:show-file-list="false"
|
||||||
|
:accept="fileTypeLimit"
|
||||||
|
:file-list="fileList"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-change="fileChange"
|
||||||
|
:on-success="uploadSuccess"
|
||||||
|
:on-error="uploadError">
|
||||||
|
<button style="position: relative;" class="license__btn" @click.prevent="">
|
||||||
|
<i class="cn-icon-upload1 cn-icon margin-r-6"></i><span>{{$t('license.upload')}}</span>
|
||||||
|
</button>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import { storageKey } from '@/utils/constants'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { dateFormat } from '@/utils/date-util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'License',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
url: api.license,
|
||||||
|
downloadC2vUrl: api.downloadLicenseC2v,
|
||||||
|
licenseObject: { // 对象
|
||||||
|
type: '',
|
||||||
|
organization: '',
|
||||||
|
supportID: '',
|
||||||
|
dateIssued: '',
|
||||||
|
dateExpires: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initData () {
|
||||||
|
axios.get(this.url, { pageSize: -1 }).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.licenseObject = response.data.data.license
|
||||||
|
this.licenseObject.dateExpires = dateFormat(new Date(this.licenseObject.hasp.feature.license.exp_date * 1000))
|
||||||
|
this.licenseObject.dateIssued = dateFormat(new Date(this.licenseObject.hasp.production_date * 1000))
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
fileChange (file, fileList) {
|
||||||
|
if (file.status !== 'ready') return
|
||||||
|
if (!_.endsWith(file.name, '.xml')) {
|
||||||
|
this.fileList = []
|
||||||
|
this.$message.error(this.$t('validate.fileTypeLimit', { types: this.fileTypeLimit }))
|
||||||
|
} else {
|
||||||
|
this.fileList = fileList.slice(-1)
|
||||||
|
this.$refs.licenseUpload.submit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadSuccess (response) {
|
||||||
|
this.initData()
|
||||||
|
this.$message.success(this.$t('tip.success'))
|
||||||
|
},
|
||||||
|
uploadError (error) {
|
||||||
|
let errorMsg
|
||||||
|
if (error.message) {
|
||||||
|
errorMsg = JSON.parse(error.message).message
|
||||||
|
} else {
|
||||||
|
errorMsg = 'error'
|
||||||
|
}
|
||||||
|
this.$message.error(this.$t('tip.uploadFailed', { msg: errorMsg }))
|
||||||
|
},
|
||||||
|
downloadFile () {
|
||||||
|
axios.get(this.downloadC2vUrl, { responseType: 'blob' }).then(res => {
|
||||||
|
let fileName = ''
|
||||||
|
if(res.headers['content-disposition']) {
|
||||||
|
fileName = res.headers['content-disposition'].split(';')[1].split('filename=')[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.navigator.msSaveOrOpenBlob) {
|
||||||
|
// 兼容ie11
|
||||||
|
const blobObject = new Blob([res.data])
|
||||||
|
window.navigator.msSaveOrOpenBlob(blobObject, fileName)
|
||||||
|
} else {
|
||||||
|
const url = URL.createObjectURL(new Blob([res.data]))
|
||||||
|
const a = document.createElement('a')
|
||||||
|
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.target = '_blank'
|
||||||
|
a.click()
|
||||||
|
a.remove() // 将a标签移除
|
||||||
|
}
|
||||||
|
}, error => {
|
||||||
|
const $self = this
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = function (event) {
|
||||||
|
const responseText = reader.result
|
||||||
|
const exception = JSON.parse(responseText)
|
||||||
|
if (exception.message) {
|
||||||
|
$self.$message.error(exception.message)
|
||||||
|
} else {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsText(error.response.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
return {
|
||||||
|
baseUrl: BASE_CONFIG.baseUrl,
|
||||||
|
apiVersion: BASE_CONFIG.apiVersion,
|
||||||
|
uploadHeaders: {
|
||||||
|
'Cn-Authorization': localStorage.getItem(storageKey.token)
|
||||||
|
},
|
||||||
|
fileTypeLimit: '.xml',
|
||||||
|
fileList: ref([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -239,13 +239,7 @@ export default {
|
|||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
item.totalBitsRate = item.outBitsRate + item.inBitsRate
|
item.totalBitsRate = item.outBitsRate + item.inBitsRate
|
||||||
linkConfig.filter(info => info.interfaceName === item.interfaceName).forEach(info => {
|
linkConfig.filter(info => info.interfaceName === item.interfaceName).forEach(info => {
|
||||||
if (info.direction === 0) {
|
|
||||||
item.outLinkId = info.linkId
|
|
||||||
} else if (info.direction === 1) {
|
|
||||||
item.inLinkId = info.linkId
|
|
||||||
} else if (info.direction === 2) {
|
|
||||||
item.linkId = info.linkId
|
item.linkId = info.linkId
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -389,7 +383,7 @@ export default {
|
|||||||
return width
|
return width
|
||||||
},
|
},
|
||||||
drillLinkId (item) {
|
drillLinkId (item) {
|
||||||
const queryCondition = `out_link_id = ${item.outLinkId} or in_link_id = ${item.inLinkId}`
|
const queryCondition = `out_link_id = ${item.linkId} or in_link_id = ${item.linkId}`
|
||||||
beforeRouterPush()
|
beforeRouterPush()
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
query: {
|
query: {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ export default {
|
|||||||
if (tab === 0) {
|
if (tab === 0) {
|
||||||
result.forEach(t => {
|
result.forEach(t => {
|
||||||
this.cnLinkInfo.forEach(e => {
|
this.cnLinkInfo.forEach(e => {
|
||||||
if (parseInt(t.commonInLinkId) === e.linkId) {
|
if (parseInt(t.inLinkId) === e.linkId) {
|
||||||
t.linkId = e.interfaceName
|
t.linkId = e.interfaceName
|
||||||
t.linkDirection = e.peerCity
|
t.linkDirection = e.peerCity
|
||||||
t.bandwidth = e.bandwidth
|
t.bandwidth = e.bandwidth
|
||||||
@@ -182,7 +182,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
result.forEach(t => {
|
result.forEach(t => {
|
||||||
this.cnLinkInfo.forEach(e => {
|
this.cnLinkInfo.forEach(e => {
|
||||||
if (parseInt(t.commonOutLinkId) === e.linkId) {
|
if (parseInt(t.outLinkId) === e.linkId) {
|
||||||
t.linkId = e.interfaceName
|
t.linkId = e.interfaceName
|
||||||
t.bandwidth = e.bandwidth
|
t.bandwidth = e.bandwidth
|
||||||
t.linkDirection = e.peerCity
|
t.linkDirection = e.peerCity
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="explorer-top-tools explorer-detection-top-tools">
|
<div class="explorer-top-tools explorer-detection-top-tools">
|
||||||
<div class="explorer-top-tools-title">{{$t('overall.detections')}}</div>
|
<div class="explorer-top-tools-title">{{$t('overall.detections')}}</div>
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<div class="explorer-top-tools-block" @click="jumpNewDetetion" v-if="hasPermission('detectionPolicy')">
|
<div class="explorer-top-tools-block" @click="jumpNewDetetion" v-if="false">
|
||||||
<i class="cn-icon cn-icon-configure-policies detection-icon-setting"></i>
|
<i class="cn-icon cn-icon-configure-policies detection-icon-setting"></i>
|
||||||
<span>{{$t('config.detections.configurePolicies')}}</span>
|
<span>{{$t('config.detections.configurePolicies')}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ export default {
|
|||||||
for (let i = 0; i < response.data.data.list.length; i++) {
|
for (let i = 0; i < response.data.data.list.length; i++) {
|
||||||
response.data.data.list[i].status = response.data.data.list[i].status + ''
|
response.data.data.list[i].status = response.data.data.list[i].status + ''
|
||||||
}
|
}
|
||||||
|
this.tableData = []
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.tableData = response.data.data.list.map(item => {
|
this.tableData = response.data.data.list.map(item => {
|
||||||
return {
|
return {
|
||||||
@@ -316,11 +317,18 @@ export default {
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
} else {
|
} else {
|
||||||
const curRecord = this.batchDeleteObjs[0]
|
axios.get(`${api.reportTemp}/${this.batchDeleteObjs[0].id}`).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
const curRecord = response.data.data
|
||||||
|
if (curRecord.config) {
|
||||||
|
curRecord.config = JSON.parse(curRecord.config)
|
||||||
|
}
|
||||||
this.initConfig(curRecord)
|
this.initConfig(curRecord)
|
||||||
this.object = curRecord
|
this.object = curRecord
|
||||||
this.rightBox.show = true
|
this.rightBox.show = true
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
initConfig (u) {
|
initConfig (u) {
|
||||||
if (!u.config) {
|
if (!u.config) {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
response.data.data.list[i].triggerStatus = response.data.data.list[i].triggerStatus + ''
|
response.data.data.list[i].triggerStatus = response.data.data.list[i].triggerStatus + ''
|
||||||
const basicInfo = pluginBasicInfo.find(plugin => plugin.id === response.data.data.list[i].id)
|
const basicInfo = pluginBasicInfo.find(plugin => plugin.id === response.data.data.list[i].id)
|
||||||
if (basicInfo) {
|
if (basicInfo) {
|
||||||
filterDataList.push(response.data.data.list[i])
|
filterDataList.push(Object.assign({},basicInfo,response.data.data.list[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.tableData = filterDataList
|
this.tableData = filterDataList
|
||||||
|
|||||||
Reference in New Issue
Block a user