mirror of
https://github.com/jumpserver/lina.git
synced 2025-08-31 06:34:13 +00:00
[Merge]
This commit is contained in:
146
src/components/ListTable/formatters/ConnectFormatter.vue
Normal file
146
src/components/ListTable/formatters/ConnectFormatter.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<ActionsGroup :size="'mini'" :actions="actions" :more-actions="moreActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ActionsGroup from '@/components/ActionsGroup/index'
|
||||
import BaseFormatter from './base'
|
||||
|
||||
const defaultPerformDelete = function({ row, col }) {
|
||||
const id = row.id
|
||||
const url = `${this.url}${id}/`
|
||||
return this.$axios.delete(url)
|
||||
}
|
||||
const defaultUpdateCallback = function({ row, col }) {
|
||||
const id = row.id
|
||||
const routeName = this.colActions.updateRoute
|
||||
this.$router.push({ name: routeName, params: { id: id }})
|
||||
}
|
||||
|
||||
const defaultDeleteCallback = function({ row, col, cellValue, reload }) {
|
||||
const msg = this.$t('common.deleteWarningMsg') + ' "' + row.name + '"'
|
||||
const title = this.$t('common.Info')
|
||||
const performDelete = this.colActions.performDelete
|
||||
this.$alert(msg, title, {
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger',
|
||||
showCancelButton: true,
|
||||
beforeClose: async(action, instance, done) => {
|
||||
if (action !== 'confirm') return done()
|
||||
instance.confirmButtonLoading = true
|
||||
try {
|
||||
await performDelete.bind(this)({ row: row, col: col })
|
||||
done()
|
||||
reload()
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
} catch (error) {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg' + ' ' + error))
|
||||
} finally {
|
||||
instance.confirmButtonLoading = false
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
/* 取消*/
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'ActionsFormatter',
|
||||
components: { ActionsGroup },
|
||||
extends: BaseFormatter,
|
||||
props: {
|
||||
actionsDefault: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
hasUpdate: true, // can set function(row, value)
|
||||
canUpdate: true, // can set function(row, value)
|
||||
hasDelete: true, // can set function(row, value)
|
||||
canDelete: true,
|
||||
updateRoute: this.$route.name.replace('List', 'Update'),
|
||||
performDelete: defaultPerformDelete,
|
||||
onUpdate: defaultUpdateCallback,
|
||||
onDelete: defaultDeleteCallback,
|
||||
extraActions: [] // format see defaultActions
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const colActions = Object.assign(this.actionsDefault, this.col, this.col.actions)
|
||||
const defaultActions = [
|
||||
{
|
||||
name: 'update',
|
||||
fa: 'fa-terminal',
|
||||
type: 'primary',
|
||||
has: colActions.hasUpdate,
|
||||
can: colActions.canUpdate,
|
||||
callback: colActions.onUpdate
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
type: 'info',
|
||||
fa: 'fa-star-o',
|
||||
has: colActions.hasDelete,
|
||||
can: colActions.canDelete,
|
||||
callback: colActions.onDelete
|
||||
}
|
||||
]
|
||||
return {
|
||||
colActions: colActions,
|
||||
defaultActions: defaultActions,
|
||||
extraActions: colActions.extraActions
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cleanedActions() {
|
||||
let actions = [...this.defaultActions, ...this.extraActions]
|
||||
actions = _.cloneDeep(actions)
|
||||
actions = actions.map((v) => {
|
||||
v.has = this.cleanBoolean(v, 'has')
|
||||
v.can = this.cleanBoolean(v, 'can')
|
||||
v.callback = this.cleanCallback(v)
|
||||
return v
|
||||
})
|
||||
actions = actions.filter((v) => v.has)
|
||||
return actions
|
||||
},
|
||||
actions() {
|
||||
if (this.cleanedActions.length <= 3) {
|
||||
return this.cleanedActions
|
||||
}
|
||||
return this.cleanedActions.slice(0, 2)
|
||||
},
|
||||
moreActions() {
|
||||
if (this.cleanedActions.length <= 3) {
|
||||
return []
|
||||
}
|
||||
return this.cleanedActions.slice(2, this.cleanedActions.length)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
cleanBoolean(item, attr) {
|
||||
const ok = item[attr]
|
||||
if (typeof ok !== 'function') {
|
||||
return ok === undefined ? true : ok
|
||||
}
|
||||
return ok(this.row, this.cellValue)
|
||||
},
|
||||
cleanCallback(item) {
|
||||
const callback = item.callback
|
||||
const attrs = {
|
||||
reload: this.reload,
|
||||
row: this.row,
|
||||
col: this.col,
|
||||
cellValue: this.cellValue,
|
||||
tableData: this.tableData
|
||||
}
|
||||
return () => { return callback.bind(this)(attrs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
40
src/components/ListTable/formatters/SystemUserFormatter.vue
Normal file
40
src/components/ListTable/formatters/SystemUserFormatter.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<span v-if="systemuser.length===0"><a style="color: #1c84c6;" @click="showSystemUser">{{ this.$t('显示') }}</a></span>
|
||||
<span v-else>{{ this.systemuser.toString() }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseFormatter from './base'
|
||||
export default {
|
||||
name: 'SystemUserFormatter',
|
||||
extends: BaseFormatter,
|
||||
data() {
|
||||
return {
|
||||
systemuser: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
showSystemUser() {
|
||||
const id = (this.row.id)
|
||||
this.$axios.get(
|
||||
`/api/v1/perms/users/assets/${id}/system-users/?cache_policy=1`
|
||||
).then(res => {
|
||||
res.forEach((v, i) => {
|
||||
this.systemuser.push(v.name)
|
||||
})
|
||||
console.log(this.systemuser)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -11,6 +11,8 @@ import ExpandAssetPermissionFormatter from './ExpandAssetPermissionFormatter'
|
||||
import CustomActionsFormatter from './CustomActionsFormatter'
|
||||
import DeleteActionFormatter from './DeleteActionFormatter'
|
||||
import DateFormatter from './DateFormatter'
|
||||
import ConnectFormatter from './ConnectFormatter'
|
||||
import SystemUserFormatter from './SystemUserFormatter'
|
||||
|
||||
export default {
|
||||
DetailFormatter,
|
||||
@@ -25,7 +27,9 @@ export default {
|
||||
ExpandAssetPermissionFormatter,
|
||||
CustomActionsFormatter,
|
||||
DeleteActionFormatter,
|
||||
DateFormatter
|
||||
DateFormatter,
|
||||
ConnectFormatter,
|
||||
SystemUserFormatter
|
||||
}
|
||||
|
||||
export {
|
||||
@@ -41,5 +45,7 @@ export {
|
||||
ExpandAssetPermissionFormatter,
|
||||
CustomActionsFormatter,
|
||||
DeleteActionFormatter,
|
||||
DateFormatter
|
||||
DateFormatter,
|
||||
ConnectFormatter,
|
||||
SystemUserFormatter
|
||||
}
|
||||
|
@@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<el-upload
|
||||
v-bind="$attrs"
|
||||
@input="onInput"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
|
||||
</el-upload>
|
||||
<div>
|
||||
<input type="file" @change="Onchange">
|
||||
<div v-if="tip !== ''">{{ tip }}</div>
|
||||
<div>
|
||||
<img :src="src" v-bind="$attrs">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -15,16 +14,28 @@ export default {
|
||||
value: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
tip: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
src() {
|
||||
return `${process.env.VUE_APP_BASE_API}${this.value}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(value) {
|
||||
this.$emit('customEvent', value, 'message')
|
||||
this.$emit('customEvent', value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onInput(val) {
|
||||
this.$emit('input', 'my-input: ' + val)
|
||||
this.$emit('input', 'upload-field: ' + val)
|
||||
},
|
||||
Onchange(e) {
|
||||
this.$emit('fileChange', e.target.files[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -760,5 +760,19 @@
|
||||
"InActiveAsset": "近期未被登录",
|
||||
"ActiveAsset": "近期被登录过",
|
||||
"DisabledAsset": "禁用的"
|
||||
},
|
||||
"xpack": {
|
||||
"InterfaceSettings": "界面设置",
|
||||
"loginTitle": "登录页面标题",
|
||||
"loginImage": "登录页面图片",
|
||||
"favicon": "网站图标",
|
||||
"logoIndex": "管理页面logo",
|
||||
"logoLogout": "退出页面logo",
|
||||
"RestoreButton": "恢复默认",
|
||||
"GatherUserList": "收集用户",
|
||||
"GatherUserTaskList": "任务列表",
|
||||
"GatherUserTaskCreate": "创建任务",
|
||||
"Timer": "定时执行",
|
||||
"GatherUserTaskUpdate": "更新任务"
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
<script>
|
||||
import GenericTreeListPage from '@/layout/components/GenericTreeListPage/index'
|
||||
import { DetailFormatter, ActionsFormatter, BooleanFormatter } from '@/components/ListTable/formatters'
|
||||
import { DetailFormatter, ConnectFormatter, SystemUserFormatter } from '@/components/ListTable/formatters'
|
||||
export default {
|
||||
components: {
|
||||
GenericTreeListPage
|
||||
@@ -20,7 +20,13 @@ export default {
|
||||
// ?assets=0不显示资产. =1显示资产
|
||||
treeUrl: '/api/v1/perms/users/nodes/children/tree/?cache_policy=2',
|
||||
callback: {
|
||||
refresh: () => {}
|
||||
refresh: () => {},
|
||||
onSelected: function(event, treeNode) {
|
||||
if (treeNode.meta.type === 'node') {
|
||||
const currentNodeId = treeNode.meta.node.id
|
||||
this.tableConfig.url = `/api/v1/perms/users/nodes/${currentNodeId}/assets/?cache_policy=1`
|
||||
}
|
||||
}.bind(this)
|
||||
}
|
||||
},
|
||||
tableConfig: {
|
||||
@@ -41,8 +47,9 @@ export default {
|
||||
sortable: 'custom'
|
||||
},
|
||||
{
|
||||
prop: 'hardware_info',
|
||||
prop: 'SystemUsers',
|
||||
align: 'center',
|
||||
formatter: SystemUserFormatter,
|
||||
label: this.$t('assets.SystemUsers')
|
||||
},
|
||||
{
|
||||
@@ -53,14 +60,15 @@ export default {
|
||||
{
|
||||
prop: 'id',
|
||||
align: 'center',
|
||||
formatter: ActionsFormatter,
|
||||
formatter: ConnectFormatter,
|
||||
width: '200px',
|
||||
label: this.$t('common.action'),
|
||||
actions: {
|
||||
performDelete: ({ row, col }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/assets/assets/${id}/`
|
||||
return this.$axios.delete(url)
|
||||
onDelete: function({ row, col, cellValue, reload }) {
|
||||
alert('接口错误:获取不到对应的资产状态')
|
||||
},
|
||||
onUpdate: function({ row, col, cellValue, reload }) {
|
||||
window.open(`/luna/?login_to=${cellValue}`, '_blank')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<RunInfoCard type="primary" v-bind="RunSuccessConfig" />
|
||||
<RunInfoCard type="info" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
<RunInfoCard type="danger" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -32,23 +32,18 @@ export default {
|
||||
RunSuccessConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunSuccessHosts'),
|
||||
content: [
|
||||
{
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据,api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据,api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
},
|
||||
RunFailedConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunFailedHosts'),
|
||||
headerColor: 'danger',
|
||||
content: [
|
||||
{
|
||||
hostname: 'window',
|
||||
result: 'api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'window',
|
||||
result: 'api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -5,7 +5,7 @@
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<RunInfoCard type="primary" v-bind="RunSuccessConfig" />
|
||||
<RunInfoCard type="info" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
<RunInfoCard type="danger" style="margin-top: 15px" v-bind="RunFailedConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -32,23 +32,18 @@ export default {
|
||||
RunSuccessConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunSuccessHosts'),
|
||||
content: [
|
||||
{
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据==api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据==api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
},
|
||||
RunFailedConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunFailedHosts'),
|
||||
headerColor: 'danger',
|
||||
content: [
|
||||
{
|
||||
hostname: 'window',
|
||||
result: 'api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据==api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -32,23 +32,18 @@ export default {
|
||||
RunSuccessConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunSuccessHosts'),
|
||||
content: [
|
||||
{
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据==api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'linux',
|
||||
result: 'api没有该数据==api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
},
|
||||
RunFailedConfig: {
|
||||
icon: 'fa-info',
|
||||
title: this.$t('jobcenter.lastRunFailedHosts'),
|
||||
headerColor: 'danger',
|
||||
content: [
|
||||
{
|
||||
hostname: 'window',
|
||||
result: 'api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
]
|
||||
content: {
|
||||
hostname: 'window',
|
||||
result: 'api没有该数据api没有该数据api没有该数据api没有该数据api没有该数据'
|
||||
}
|
||||
},
|
||||
taskData: {}
|
||||
}
|
||||
|
@@ -1,13 +1,11 @@
|
||||
<template>
|
||||
<IBox :fa="icon" :type="type" :title="title" v-bind="$attrs">
|
||||
<el-table class="el-table" style="width: 100%" :data="content" :show-header="false">
|
||||
<el-table-column width="150px" prop="hostname" />
|
||||
<el-table-column prop="result">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.result }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<table class="run-info">
|
||||
<tr>
|
||||
<td>{{ content.hostname }}</td>
|
||||
<td>{{ content.result }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</IBox>
|
||||
</template>
|
||||
|
||||
@@ -29,8 +27,8 @@ export default {
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
@@ -45,5 +43,13 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.run-info {
|
||||
line-height: 1.43;
|
||||
padding: 8px;
|
||||
vertical-align: top;
|
||||
font-size: 13px;
|
||||
}
|
||||
.run-info > tr:first-child > td:first-child {
|
||||
width: 150px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<GenericTreeListPage :table-config="tableConfig" :tree-setting="treeSetting" />
|
||||
<GenericTreeListPage :table-config="tableConfig" :tree-setting="treeSetting" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -28,8 +28,29 @@ export default {
|
||||
],
|
||||
columnsMeta: {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
hasImport: false,
|
||||
hasRefresh: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'gather-user-tasks',
|
||||
title: '收集用户任务',
|
||||
type: 'primary',
|
||||
has: true,
|
||||
can: true,
|
||||
callback: this.onGatherUserTasks
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onGatherUserTasks() {
|
||||
this.$router.push({ name: 'GatherUserTaskList' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
48
src/views/xpack/GatheredUser/TaskCreateUpdate.vue
Normal file
48
src/views/xpack/GatheredUser/TaskCreateUpdate.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage v-bind="$data" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name', 'nodes']],
|
||||
[this.$t('xpack.Timer'), ['is_periodic', 'crontab', 'interval']],
|
||||
[this.$t('common.Others'), ['comment']]
|
||||
],
|
||||
url: '/api/v1/xpack/gathered-user/tasks/',
|
||||
fieldsMeta: {
|
||||
nodes: {
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
processResults(data) {
|
||||
const results = data.results.map((item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
const more = !!data.next
|
||||
return { results: results, pagination: more, total: data.count }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'is_periodic': {
|
||||
type: 'switch'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
35
src/views/xpack/GatheredUser/TaskList.vue
Normal file
35
src/views/xpack/GatheredUser/TaskList.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListPage from '@/layout/components/GenericListPage'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericListPage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/xpack/gathered-user/tasks/',
|
||||
columns: [
|
||||
'name', 'nodes', 'periodic_display', 'executed_times', 'actions'
|
||||
],
|
||||
columnsMeta: {}
|
||||
},
|
||||
headerActions: {
|
||||
hasBulkDelete: false,
|
||||
hasImport: false,
|
||||
hasRefresh: false,
|
||||
hasExport: false,
|
||||
createRoute: 'GatherUserTaskCreate'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@@ -1,11 +1,14 @@
|
||||
<template>
|
||||
<TabPage :submenu="submenu" :active-menu="activemenu">
|
||||
<IBox>
|
||||
<TabPage :submenu="submenu" :active-menu="activeMenu">
|
||||
<IBox v-if="!loading">
|
||||
<GenericCreateUpdateForm
|
||||
:fields="fields"
|
||||
:url="url"
|
||||
:initial="interfaceInfo"
|
||||
:update-success-next-route="successUrl"
|
||||
:fields-meta="fieldsMeta"
|
||||
:on-submit="submitForm"
|
||||
:more-buttons="moreButtons"
|
||||
/>
|
||||
</IBox>
|
||||
</TabPage>
|
||||
@@ -13,9 +16,9 @@
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import { IBox } from '@/components'
|
||||
import { IBox, UploadField } from '@/components'
|
||||
import GenericCreateUpdateForm from '@/layout/components/GenericCreateUpdateForm'
|
||||
import { UploadField } from '@/components'
|
||||
import { getInterfaceInfo, postInterface, restoreInterface } from '@/views/xpack/api'
|
||||
|
||||
export default {
|
||||
name: 'InterfaceSettings',
|
||||
@@ -26,10 +29,13 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activemenu: 'interface',
|
||||
loading: true,
|
||||
files: {},
|
||||
interfaceInfo: {},
|
||||
activeMenu: 'interface',
|
||||
submenu: [
|
||||
{
|
||||
title: 'interface-settings',
|
||||
title: this.$t('xpack.InterfaceSettings'),
|
||||
name: 'interface'
|
||||
}
|
||||
],
|
||||
@@ -43,40 +49,112 @@ export default {
|
||||
],
|
||||
fieldsMeta: {
|
||||
login_title: {
|
||||
label: 'login_title'
|
||||
label: this.$t('xpack.loginTitle'),
|
||||
helpText: '提示:将会显示在企业版用户登录页面(eg: 欢迎使用JumpServer开源堡垒机)'
|
||||
},
|
||||
login_image: {
|
||||
label: 'login_image'
|
||||
component: UploadField,
|
||||
label: this.$t('xpack.loginImage'),
|
||||
el: {
|
||||
width: '10%',
|
||||
height: '10%',
|
||||
tip: '提示:将会显示在企业版用户登录页面(建议图片大小为: 492*472px)'
|
||||
},
|
||||
on: {
|
||||
fileChange: ([value], updateForm) => {
|
||||
console.log(value)
|
||||
this.files['login_image'] = value
|
||||
}
|
||||
}
|
||||
},
|
||||
favicon: {
|
||||
label: 'favicon'
|
||||
component: UploadField,
|
||||
label: this.$t('xpack.favicon'),
|
||||
el: {
|
||||
width: '5%',
|
||||
height: '5%',
|
||||
tip: '提示:网站图标(建议图片大小为: 16px*16px)'
|
||||
},
|
||||
on: {
|
||||
fileChange: ([value], updateForm) => {
|
||||
this.files['favicon'] = value
|
||||
}
|
||||
}
|
||||
},
|
||||
logo_index: {
|
||||
label: 'logo_index'
|
||||
component: UploadField,
|
||||
label: this.$t('xpack.logoIndex'),
|
||||
el: {
|
||||
width: '10%',
|
||||
height: '10%',
|
||||
tip: '提示:将会显示在管理页面左上方(建议图片大小为: 185px*55px)'
|
||||
},
|
||||
on: {
|
||||
fileChange: ([value], updateForm) => {
|
||||
this.files['logo_index'] = value
|
||||
}
|
||||
}
|
||||
},
|
||||
logo_logout: {
|
||||
component: UploadField,
|
||||
label: 'logo_logout',
|
||||
label: this.$t('xpack.logoLogout'),
|
||||
el: {
|
||||
action: '/api/v1/xpack/interface/setting/',
|
||||
autoUpload: false,
|
||||
name: 'logo_logout',
|
||||
onChange: function(file, fileList) {
|
||||
console.log(file, fileList)
|
||||
}
|
||||
width: '5%',
|
||||
height: '5%',
|
||||
tip: '提示:将会显示在企业版用户退出页面(建议图片大小为:82px*82px)'
|
||||
},
|
||||
on: {
|
||||
focus: ([event], updateForm) => {
|
||||
console.log(event.target.value) // output: input value
|
||||
},
|
||||
customEvent: ([value, msg], updateForm) => {
|
||||
console.log(msg) // output: 'message'
|
||||
fileChange: ([value], updateForm) => {
|
||||
this.files['logo_logout'] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/xpack/interface/setting'
|
||||
url: '/api/v1/xpack/interface/setting',
|
||||
moreButtons: [
|
||||
{
|
||||
title: this.$t('xpack.RestoreButton'),
|
||||
callback: function(value, form) {
|
||||
this.$confirm('您确定要恢复默认初始化吗?', '你确认吗?', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
restoreInterface().then(res => {
|
||||
this.$message.success(res.success)
|
||||
location.reload()
|
||||
}).catch(errMsg => {
|
||||
this.$message.error(errMsg.response.data.error)
|
||||
})
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
getInterfaceInfo().then(data => {
|
||||
this.interfaceInfo = data
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
submitForm(values) {
|
||||
const form = new FormData()
|
||||
const ImageKeys = ['favicon', 'login_image', 'logo_logout', 'logo_index']
|
||||
ImageKeys.forEach((value, index) => {
|
||||
if (this.files[value] !== undefined) {
|
||||
form.append(value, this.files[value])
|
||||
}
|
||||
})
|
||||
if (values['login_title'] !== undefined) {
|
||||
form.append('login_title', values['login_title'])
|
||||
}
|
||||
postInterface(form).then(res => {
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
25
src/views/xpack/api.js
Normal file
25
src/views/xpack/api.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function postInterface(formData) {
|
||||
return request({
|
||||
url: '/api/v1/xpack/interface/setting',
|
||||
method: 'put',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
export function getInterfaceInfo() {
|
||||
return request({
|
||||
url: '/api/v1/xpack/interface/setting',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function restoreInterface() {
|
||||
return request({
|
||||
url: '/xpack/interface/restore/default',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
import Layout from '@/layout/index'
|
||||
import i18n from '@/i18n/i18n'
|
||||
|
||||
export default {
|
||||
path: '/xpack',
|
||||
@@ -11,7 +12,7 @@ export default {
|
||||
path: 'interface-setting',
|
||||
component: () => import('@/views/xpack/InterfaceSettings.vue'),
|
||||
name: 'InterfaceSetting',
|
||||
meta: { title: 'InterfaceSetting' }
|
||||
meta: { title: i18n.t('xpack.InterfaceSettings') }
|
||||
},
|
||||
{
|
||||
path: 'license',
|
||||
@@ -21,9 +22,30 @@ export default {
|
||||
},
|
||||
{
|
||||
path: 'gathered-users',
|
||||
component: () => import('@/views/xpack/GatherUser'),
|
||||
name: 'GatherUser',
|
||||
meta: { title: 'GatherUser' }
|
||||
component: () => import('@/views/xpack/GatheredUser/GatheredUserList'),
|
||||
name: 'GatherUserList',
|
||||
meta: { title: i18n.t('xpack.GatherUserList') }
|
||||
},
|
||||
{
|
||||
path: 'gathered-users/tasks',
|
||||
component: () => import('@/views/xpack/GatheredUser/TaskList'),
|
||||
name: 'GatherUserTaskList',
|
||||
meta: { title: i18n.t('xpack.GatherUserTaskList') },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'gathered-users/tasks/create',
|
||||
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
|
||||
name: 'GatherUserTaskCreate',
|
||||
meta: { title: i18n.t('xpack.GatherUserTaskCreate') },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'gathered-users/tasks/update',
|
||||
component: () => import('@/views/xpack/GatheredUser/TaskCreateUpdate'),
|
||||
name: 'GatherUserTaskUpdate',
|
||||
meta: { title: i18n.t('xpack.GatherUserTaskUpdate'), action: 'update' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user