diff --git a/src/api/sessions.js b/src/api/sessions.js new file mode 100644 index 000000000..3451b0f9d --- /dev/null +++ b/src/api/sessions.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function terminateSession(data) { + return request({ + url: '/api/v1/terminal/tasks/kill-session/', + method: 'post', + data: data + }) +} diff --git a/src/components/DataTable/index.vue b/src/components/DataTable/index.vue index a57d7cb0e..323e67a5d 100644 --- a/src/components/DataTable/index.vue +++ b/src/components/DataTable/index.vue @@ -1,7 +1,5 @@ + + diff --git a/src/components/ListTable/formatters/base.vue b/src/components/ListTable/formatters/base.vue index 17a47d822..6be97cc96 100644 --- a/src/components/ListTable/formatters/base.vue +++ b/src/components/ListTable/formatters/base.vue @@ -19,7 +19,7 @@ export default { default: () => ({}) }, cellValue: { - type: [String, Boolean, Number, Object], + type: [String, Boolean, Number, Object, Array], default: null }, tableData: { diff --git a/src/components/ListTable/formatters/index.js b/src/components/ListTable/formatters/index.js index d23db4cd5..d92f9ba0f 100644 --- a/src/components/ListTable/formatters/index.js +++ b/src/components/ListTable/formatters/index.js @@ -3,3 +3,4 @@ export { default as DisplayFormatter } from './DisplayFormatter' export { default as BooleanFormatter } from './ChoicesFormatter' export { default as ActionsFormatter } from './ActionsFormatter' export { default as ExpandPreFormatter } from './ExpandPreFormatter' +export { default as LengthFormatter } from './LengthFormatter' diff --git a/src/components/ListTable/index.vue b/src/components/ListTable/index.vue index a88458c03..43dc9cb28 100644 --- a/src/components/ListTable/index.vue +++ b/src/components/ListTable/index.vue @@ -3,35 +3,35 @@ - + -

{{ $d(new Date(), 'short') }}

导出全部 仅导出选中项 - 仅导出搜索项 +
- + - - 导出全部 - 仅导出选中项 - 仅导出搜索项 + + 导入新资产 + 更新资产 -
+
下载导入的模板或使用导出的csv格式 下载导入模板
+
下载更新的模板或使用导出的csv格式 下载更新模板
+ +
点击上传 -
只能上传jpg/png文件,且不超过500kb
+
只能上传CSV文件
@@ -81,7 +81,13 @@ export default { return this.selectedRows.length > 0 }, upLoadUrl() { - return process.env.VUE_APP_BASE_API + this.tableConfig.url + return this.tableConfig.url + }, + importtitle() { + if (this.importOption === '1') { return this.$tc('Import') } else { return this.$tc('Update') } + }, + downloadImportTempUrl() { + return process.env.VUE_APP_BASE_API + this.tableConfig.url + '?format=csv&template=import&limit=1' } }, mounted() { @@ -93,6 +99,15 @@ export default { }) }, methods: { + upload(item) { + console.log(item) + this.$axios.put( + this.upLoadUrl, + item.file + ).then((res) => + console.log(res) + ) + }, downloadCsv(url) { const a = document.createElement('a') a.href = url @@ -103,16 +118,16 @@ export default { this.selectedRows = val }, reloadTable() { - this.$refs.dataTable.getList() + this.$refs.dataTable.$refs.dataTable.getList() }, search(attrs) { - return this.$refs.dataTable.search(attrs) + return this.$refs.dataTable.$refs.dataTable.search(attrs) }, async handleExport() { let data var resources = [] if (this.exportOption === '1') { - data = this.$refs.dataTable.getData() + data = this.$refs.dataTable.$refs.dataTable.getData() } else if (this.exportOption === '2') { data = this.selectedRows } else { @@ -127,6 +142,16 @@ export default { }, handleImport() { + }, + async downloadUpdateTempUrl() { + var resources = [] + const data = this.$refs.dataTable.$refs.dataTable.getData() + for (let index = 0; index < data.length; index++) { + resources.push(data[index].id) + } + const spm = await createSourceIdCache(resources) + const url = process.env.VUE_APP_BASE_API + `${this.tableConfig.url}?format=csv&template=update&spm=` + spm.spm + return this.downloadCsv(url) }, async handleDialogConfirm(val) { switch (val) { diff --git a/src/i18n/langs/cn.js b/src/i18n/langs/cn.js index 945aa6f73..fc12efae1 100644 --- a/src/i18n/langs/cn.js +++ b/src/i18n/langs/cn.js @@ -52,6 +52,12 @@ const cn = { 'Reset': '重置', 'This field is required': '这个字段是必填项', 'Validity': '有效性', + 'confirm': '确认', + 'Confirm': '确认', + 'Cancel': '取消', + 'cancel': '取消', + 'Import': '导入', + 'Export': '导出', 'Other': '其它' }, route: { @@ -73,8 +79,11 @@ const cn = { 'DatabaseApp': '数据库应用', 'Perms': '权限管理', 'AssetPermission': '资产授权', + 'AssetPermissionCreate': '创建资产授权规则', 'RemoteAppPermission': '远程应用授权', + 'RemoteAppPermissionCreate': '创建远程应用授权规则', 'DatabaseAppPermission': '数据库应用授权', + 'DatabaseAppPermissionCreate': '创建数据库应用授权规则', 'Sessions': '会话管理', 'SessionOnline': '在线会话', 'SessionOffline': '历史会话', @@ -339,20 +348,14 @@ const cn = { 'active': '激活中', 'users_and_user_groups': '用户或用户组', 'assets_and_node': '资产或节点', + 'Basic': '基本', + 'User': '用户', + 'Asset': '资产', + 'Actions': '动作', // 'RemoteApp': '远程应用', - 'remote_app_permission_list': '远程应用授权列表', - 'remote_app_permission_detail': '远程应用授权详情', - 'create_remote_app_permission': '创建远程应用授权规则', - 'update_remote_app_permission': '更新远程应用授权规则', - 'remote_app_count': '远程应用数量', // - 'DatabaseApp': '数据库应用', - 'database_app_permission_list': '数据库应用授权列表', - 'database_app_permission_detail': '数据库应用授权详情', - 'create_database_app_permission': '创建数据库应用授权规则', - 'update_database_app_permission': '更新数据库应用授权规则', - 'database_app_count': '数据库应用数量' + 'DatabaseApp': '数据库应用' }, sessions: { 'id': 'ID', @@ -376,7 +379,8 @@ const cn = { 'addr': '地址', 'active': '激活中', 'alive': '在线', - 'StorageConfiguration': '存储配置' + 'StorageConfiguration': '存储配置', + 'join': '加入' }, jobcenter: { 'RunTimes': '执行次数', diff --git a/src/i18n/langs/en.js b/src/i18n/langs/en.js index 33c589744..1c8d7d64c 100644 --- a/src/i18n/langs/en.js +++ b/src/i18n/langs/en.js @@ -288,7 +288,8 @@ const en = { 'quick_modify': 'Quick modify', 'terminate_session': 'Terminate session', 'confirm': 'Confirm', - 'commands': 'Commands' + 'commands': 'Commands', + 'join': 'join' }, setting: { 'setting': 'System Setting', diff --git a/src/router/index.js b/src/router/index.js index 201dd5dd4..f2d37a8be 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -214,17 +214,38 @@ export const constantRoutes = [ component: () => import('@/views/perms/AssetPermissionList'), meta: { title: 'AssetPermission' } }, + { + path: 'asset-permissions/create', + component: () => import('@/views/perms/AssetPermissionCreateUpdate'), // Parent router-view + name: 'AssetPermissionCreate', + hidden: true, + meta: { title: 'AssetPermissionCreate', activeMenu: '/perms/asset-permissions' } + }, { path: 'remote-app-permissions', name: 'RemoteAppPermissionList', component: () => import('@/views/perms/RemoteAppPermissionList'), meta: { title: 'RemoteAppPermission' } }, + { + path: 'remote-app-permissions/create', + component: () => import('@/views/perms/RemoteAppPermissionCreateUpdate'), // Parent router-view + name: 'RemoteAppPermissionCreate', + hidden: true, + meta: { title: 'RemoteAppPermissionCreate', activeMenu: '/perms/remote-app-permissions' } + }, { path: 'database-app-permissions', name: 'DatabaseAppPermissionList', component: () => import('@/views/perms/DatabaseAppPermissionList'), meta: { title: 'DatabaseAppPermission' } + }, + { + path: 'database-app-permissions/create', + component: () => import('@/views/perms/DatabaseAppPermissionCreateUpdate'), // Parent router-view + name: 'DatabaseAppPermissionCreate', + hidden: true, + meta: { title: 'DatabaseAppPermissionCreate', activeMenu: '/perms/database-app-permissions' } } ] }, diff --git a/src/utils/common.js b/src/utils/common.js new file mode 100644 index 000000000..b540d5366 --- /dev/null +++ b/src/utils/common.js @@ -0,0 +1,78 @@ +function getTimeUnits(u) { + const units = { + 'd': '天', + 'h': '时', + 'm': '分', + 's': '秒' + } + if (getUserLang() === 'zh-CN') { + return units[u] + } + return u +} + +export function timeOffset(a, b) { + const start = safeDate(a) + const end = safeDate(b) + const offset = (end - start) / 1000 + return readableSecond(offset) +} + +function readableSecond(offset) { + const days = offset / 3600 / 24 + const hours = offset / 3600 + const minutes = offset / 60 + const seconds = offset + + if (days > 1) { + return days.toFixed(1) + ' ' + getTimeUnits('d') + } else if (hours > 1) { + return hours.toFixed(1) + ' ' + getTimeUnits('h') + } else if (minutes > 1) { + return minutes.toFixed(1) + ' ' + getTimeUnits('m') + } else if (seconds > 1) { + return seconds.toFixed(1) + ' ' + getTimeUnits('s') + } + return '' +} + +function getUserLang() { + const userLangEN = document.cookie.indexOf('django_language=en') + if (userLangEN === -1) { + return 'zh-CN' + } else { + return 'en-US' + } +} + +function safeDate(s) { + s = cleanDateStr(s) + return new Date(s) +} + +function cleanDateStr(d) { + for (let i = 0; i < 3; i++) { + if (!isNaN(Date.parse(d))) { + return d + } + if (!isNaN(Number(d))) { + return d + } + switch (i) { + case 0: + d = d.replaceAll('-', '/') + break + case 1: + d = d.split('+')[0].trimRight() + break + } + } + return null +} + +export function toSafeLocalDateStr(d) { + const date = safeDate(d) + // var date_s = date.toLocaleString(getUserLang(), {hour12: false}); + const date_s = date.toLocaleString(getUserLang(), { hourCycle: 'h23' }) + return date_s.split('/').join('-') +} diff --git a/src/views/perms/AssetPermissionCreateUpdate.vue b/src/views/perms/AssetPermissionCreateUpdate.vue new file mode 100644 index 000000000..ef50ed92b --- /dev/null +++ b/src/views/perms/AssetPermissionCreateUpdate.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/src/views/perms/AssetPermissionList.vue b/src/views/perms/AssetPermissionList.vue index cad36f5e6..9a95c2c1e 100644 --- a/src/views/perms/AssetPermissionList.vue +++ b/src/views/perms/AssetPermissionList.vue @@ -4,7 +4,7 @@ + + diff --git a/src/views/perms/DatabaseAppPermissionList.vue b/src/views/perms/DatabaseAppPermissionList.vue index dd75828e0..754413cec 100644 --- a/src/views/perms/DatabaseAppPermissionList.vue +++ b/src/views/perms/DatabaseAppPermissionList.vue @@ -4,8 +4,7 @@ + + diff --git a/src/views/perms/RemoteAppPermissionList.vue b/src/views/perms/RemoteAppPermissionList.vue index c2575ee92..115865f90 100644 --- a/src/views/perms/RemoteAppPermissionList.vue +++ b/src/views/perms/RemoteAppPermissionList.vue @@ -4,7 +4,7 @@