diff --git a/src/components/Apps/AssetSelect/dialog.vue b/src/components/Apps/AssetSelect/dialog.vue
index f2b27afe0..1e2af1143 100644
--- a/src/components/Apps/AssetSelect/dialog.vue
+++ b/src/components/Apps/AssetSelect/dialog.vue
@@ -17,6 +17,7 @@
:table-config="tableConfig"
:tree-url="`${baseNodeUrl}children/tree/`"
:url="baseUrl"
+ :tree-setting="treeSetting"
class="tree-table"
v-bind="$attrs"
/>
@@ -52,6 +53,10 @@ export default {
disabled: {
type: [Boolean, Function],
default: false
+ },
+ treeSetting: {
+ type: Object,
+ default: () => ({})
}
},
data() {
diff --git a/src/components/Apps/AssetSelect/index.vue b/src/components/Apps/AssetSelect/index.vue
index 52f638248..780f55a75 100644
--- a/src/components/Apps/AssetSelect/index.vue
+++ b/src/components/Apps/AssetSelect/index.vue
@@ -13,6 +13,7 @@
ref="dialog"
:base-node-url="baseNodeUrl"
:base-url="baseUrl"
+ :tree-setting="treeSetting"
:tree-url-query="treeUrlQuery"
:value="value"
:visible.sync="dialogVisible"
@@ -48,6 +49,10 @@ export default {
value: {
type: Array,
default: () => []
+ },
+ treeSetting: {
+ type: Object,
+ default: () => ({})
}
},
data() {
diff --git a/src/components/Apps/AssetTreeTable/index.vue b/src/components/Apps/AssetTreeTable/index.vue
index 4ba02a04c..5164802a5 100644
--- a/src/components/Apps/AssetTreeTable/index.vue
+++ b/src/components/Apps/AssetTreeTable/index.vue
@@ -60,6 +60,7 @@ export default {
const showAssets = this.treeSetting?.showAssets || this.showAssets
const treeUrlQuery = this.setTreeUrlQuery()
const assetTreeUrl = `${this.treeUrl}?assets=${showAssets ? '1' : '0'}&${treeUrlQuery}`
+ const vm = this
return {
treeTabConfig: {
@@ -81,7 +82,13 @@ export default {
nodeUrl: this.nodeUrl,
treeUrl: assetTreeUrl,
callback: {
- onSelected: (event, treeNode) => this.getAssetsUrl(treeNode)
+ onSelected: (event, treeNode) => this.getAssetsUrl(treeNode),
+ beforeRefresh: () => {
+ const query = { ...this.$route.query, node_id: '', asset_id: '' }
+ setTimeout(() => {
+ vm.$router.replace({ query: query })
+ }, 100)
+ }
},
...this.treeSetting
}
diff --git a/src/components/Form/AutoDataForm/utils.js b/src/components/Form/AutoDataForm/utils.js
index 0a3311edb..346e32eee 100644
--- a/src/components/Form/AutoDataForm/utils.js
+++ b/src/components/Form/AutoDataForm/utils.js
@@ -5,9 +5,9 @@ import Switcher from '@/components/Form/FormFields/Switcher.vue'
import rules from '@/components/Form/DataForm/rules'
import BasicTree from '@/components/Form/FormFields/BasicTree.vue'
import JsonEditor from '@/components/Form/FormFields/JsonEditor.vue'
-import TransferSelect from '@/components/Form/FormFields/TransferSelect.vue'
import { assignIfNot } from '@/utils/common'
import TagInput from '@/components/Form/FormFields/TagInput.vue'
+import TransferSelect from '@/components/Form/FormFields/TransferSelect.vue'
export class FormFieldGenerator {
constructor(emit) {
@@ -45,7 +45,7 @@ export class FormFieldGenerator {
break
case 'field':
type = ''
- field.component = TransferSelect
+ field.component = ObjectSelect2
if (fieldRemoteMeta.required) {
field.el.clearable = false
}
@@ -76,7 +76,7 @@ export class FormFieldGenerator {
field.component = ObjectSelect2
break
case 'm2m_related_field':
- field.component = TransferSelect
+ field.component = ObjectSelect2
field.el.label = field.label
break
case 'nested object':
@@ -134,6 +134,9 @@ export class FormFieldGenerator {
case 'comment':
field.el.type = 'textarea'
break
+ case 'users':
+ field.component = TransferSelect
+ field.el.label = field.label
}
return field
}
diff --git a/src/components/Form/FormFields/WeekCronSelect.vue b/src/components/Form/FormFields/WeekCronSelect.vue
index 92becf968..e08efb2db 100644
--- a/src/components/Form/FormFields/WeekCronSelect.vue
+++ b/src/components/Form/FormFields/WeekCronSelect.vue
@@ -204,7 +204,12 @@ export default {
},
formatWeektime(col) {
const timeStamp = 1542384000000 // '2018-11-17 00:00:00'
- const beginStamp = timeStamp + col * 1800000 // col * 30 * 60 * 1000
+ const timezone = 8
+ const offsetGMT = new Date().getTimezoneOffset() // 本地时间和格林威治的时间差,单位为分钟
+ const nowDate = new Date(timeStamp).getTime()
+ const targetStamp = new Date(nowDate + offsetGMT * 60 * 1000 + timezone * 60 * 60 * 1000).getTime()
+
+ const beginStamp = targetStamp + col * 1800000 // col * 30 * 60 * 1000
const endStamp = beginStamp + 1800000
const begin = this.formatDate(new Date(beginStamp), 'hh:mm')
diff --git a/src/components/Table/AutoDataSearch/index.vue b/src/components/Table/AutoDataSearch/index.vue
index 22e686211..b4adcae91 100644
--- a/src/components/Table/AutoDataSearch/index.vue
+++ b/src/components/Table/AutoDataSearch/index.vue
@@ -3,7 +3,7 @@
-
+
@@ -68,6 +68,9 @@ export default {
},
methods: {
handleTagSearch(tags) {
+ if (_.isEqual(tags, this.tags)) {
+ return
+ }
this.tags = tags
if (tags.length === 0) {
this.manualSearch = false
diff --git a/src/components/Table/ListTable/TableAction/LeftSide.vue b/src/components/Table/ListTable/TableAction/LeftSide.vue
index 0b86f4d4c..48c48d618 100644
--- a/src/components/Table/ListTable/TableAction/LeftSide.vue
+++ b/src/components/Table/ListTable/TableAction/LeftSide.vue
@@ -104,7 +104,7 @@ export default {
title: this.$t('common.BatchUpdate'),
name: 'actionUpdateSelected',
has: this.hasBulkUpdate,
- icon: 'fa fa-refresh',
+ fa: 'batch-update',
can: function({ selectedRows }) {
let canBulkUpdate = vm.canBulkUpdate
if (typeof canBulkUpdate === 'function') {
diff --git a/src/components/Table/ListTable/index.vue b/src/components/Table/ListTable/index.vue
index 125203418..2696dd508 100644
--- a/src/components/Table/ListTable/index.vue
+++ b/src/components/Table/ListTable/index.vue
@@ -173,12 +173,14 @@ export default {
this.dataTable.getList()
},
search(attrs) {
+ this.$log.debug('ListTable: search table', attrs)
this.$emit('TagSearch', attrs)
- return this.dataTable?.search(attrs, true)
+ this.$refs.dataTable?.$refs.dataTable?.search(attrs, true)
},
filter(attrs) {
this.$emit('TagFilter', attrs)
- this.$refs.dataTable.$refs.dataTable.search(attrs, true)
+ this.$log.debug('ListTable: found filter change', attrs)
+ this.search(attrs)
},
hasActionPerm(action) {
const permRequired = this.permissions[action]
diff --git a/src/components/Table/TagSearch/index.vue b/src/components/Table/TagSearch/index.vue
index a5ff67bff..9da5bcc5c 100644
--- a/src/components/Table/TagSearch/index.vue
+++ b/src/components/Table/TagSearch/index.vue
@@ -10,14 +10,14 @@
{{ v.label + ':' }}
{{ v.valueLabel }}
@@ -27,14 +27,14 @@
@@ -122,6 +122,12 @@ export default {
},
deep: true
},
+ filterTags: {
+ handler() {
+ this.$emit('tag-search', this.filterMaps)
+ },
+ deep: true
+ },
filterValue(newValue, oldValue) {
if (newValue === '' && oldValue !== '') {
this.emptyCount = 1
@@ -210,11 +216,6 @@ export default {
...asFilterTags,
...routeFilter
}
- if (Object.keys(this.filterTags).length > 0) {
- setTimeout(() => {
- return this.$emit('tagSearch', this.filterMaps)
- }, 400)
- }
},
getValueLabel(key, value) {
for (const field of this.options) {
@@ -252,7 +253,7 @@ export default {
if (this.getUrlQuery) {
this.checkUrlFields(evt)
}
- this.$emit('tagSearch', this.filterMaps)
+ // this.$emit('tagSearch', this.filterMaps)
return true
},
handleDelete() {
@@ -284,7 +285,7 @@ export default {
valueLabel: this.valueLabel
}
this.$set(this.filterTags, this.filterKey, tag)
- this.$emit('tagSearch', this.filterMaps)
+ // this.$emit('tagSearch', this.filterMaps)
// 修改查询参数时改变url中保存的参数
if (this.getUrlQuery) {
diff --git a/src/components/Tree/DataZTree/components/ZTree/index.vue b/src/components/Tree/DataZTree/components/ZTree/index.vue
index dfaadc653..34665402d 100644
--- a/src/components/Tree/DataZTree/components/ZTree/index.vue
+++ b/src/components/Tree/DataZTree/components/ZTree/index.vue
@@ -167,6 +167,9 @@ export default {
},
async refresh() {
this.treeSearchValue = ''
+ if (this.treeSetting?.callback?.beforeRefresh) {
+ this.treeSetting.callback.beforeRefresh()
+ }
if (this.treeSetting?.callback?.refresh) {
await this.treeSetting.callback.refresh()
}
diff --git a/src/i18n/langs/en.json b/src/i18n/langs/en.json
index 507ba31d8..684f73afb 100644
--- a/src/i18n/langs/en.json
+++ b/src/i18n/langs/en.json
@@ -969,29 +969,30 @@
"LoginCount": "Login count",
"LoginOverview": "Sessions overview",
"LoginTo": "Login to",
- "LoginUsers": "Active accounts",
+ "ActiveUsers": "Active users",
"Monthly": "Monthly",
"CurrentConnections": "Current connections",
- "TodayFailedConnections": "Connections failed today",
+ "CurrentConnectionUsers": "Current connection users",
+ "TodayFailedConnections": "Number of failed sessions today",
"OnlineSessions": "Online sessions",
"OnlineUserDevices": "Online user devices",
"RealTimeData": "Real-time data",
- "UserAssetActivity": "Account/Asset activity",
- "UserData": "Account data",
+ "UserAssetActivity": "User/asset activity status",
+ "UserData": "User data",
"LoginUserToday": "Login account today",
"AssetData": "Asset data",
- "LoginAssetToday": "Active assets today",
+ "LoginAssetToday": "Active asset today",
"WeekAdd": "New this week",
"ProportionOfAssetTypes": "Proportion of asset types",
"Proportion": "Proportion",
- "LoginUserRanking": "Login account ranking",
- "ActiveAssetRanking": "Login asset ranking",
+ "LoginUserRanking": "Session user ranking",
+ "ActiveAssetRanking": "Session asset Ranking",
"AssetName": "Asset name",
"NumberOfVisits": "Number of visits",
"ranking": "Ranking",
"Today": "Today",
- "Last7Days": "Last 7 days",
- "Last30Days": "Last30 days",
+ "Last7Days": "Last 7d",
+ "Last30Days": "Last 30d",
"OnlineUsers": "Online accounts",
"ConnectUsers": "Connect accounts",
"Num": "Num",
@@ -1009,13 +1010,14 @@
"BatchCommandNotExecuted": "Batch command not executed",
"ExecuteFailedCommand": "Execute failed command",
"SessionTrend": "Session trend",
+ "SessionConnectTrend": "Session connection trends",
"UserLoginTrend": "Account login trend",
"TimesWeekUnit": "times/week",
"TopAssetsOfWeek": "Top assets of week",
"TopUsersOfWeek": "Top user of week",
"User": "User",
"UserRatio": "User Ratio",
- "UsersTotal": "Accounts total",
+ "UsersTotal": "User total",
"Weekly": "Weekly",
"TotalJobFailed": "Total job failed",
"TotalJobRunning": "Total job running",
@@ -2002,7 +2004,7 @@
"Account": "Account",
"Existing": "Existing",
"UserInformation": "User information",
- "Authentication": "Account",
+ "Authentication": "Authentication",
"Comment": "Comment",
"ConfirmPassword": "Confirm password",
"DateExpired": "Date expired",
diff --git a/src/i18n/langs/ja.json b/src/i18n/langs/ja.json
index ec640a813..28324286d 100644
--- a/src/i18n/langs/ja.json
+++ b/src/i18n/langs/ja.json
@@ -971,22 +971,23 @@
"LoginCount": "ログイン回数",
"LoginOverview": "セッション統計",
"LoginTo": "ログインしました",
- "LoginUsers": "アクティブなアカウント",
+ "ActiveUsers": "アクティブユーザー",
"Monthly": "月ごと",
"CurrentConnections": "現在の接続数",
- "TodayFailedConnections": "今日の接続に失敗しました",
+ "CurrentConnectionUsers": "現在のセッションユーザーの数",
+ "TodayFailedConnections": "今日の失敗したセッションの数",
"OnlineSessions": "オンラインセッション",
"RealTimeData": "リアルタイムデータ",
- "UserAssetActivity": "アカウント/資産のアクティブ化",
- "UserData": "アカウントデータ",
- "LoginUserToday": "今日のログインアカウント数",
+ "UserAssetActivity": "ユーザー/アセットのアクティビティステータス",
+ "UserData": "ユーザーデータ",
+ "LoginUserToday": "今日のログインユーザー数",
"AssetData": "資産データ",
"LoginAssetToday": "今日のアクティブ資産数",
"WeekAdd": "今週の追加",
"ProportionOfAssetTypes": "資産タイプの割合",
"Proportion": "占有率",
- "LoginUserRanking": "ログインアカウントランキング",
- "ActiveAssetRanking": "ログイン資産ランキング",
+ "LoginUserRanking": "セッションユーザーランキング",
+ "ActiveAssetRanking": "セッションアセットランキング",
"AssetName": "資産名",
"NumberOfVisits": "アクセス回数",
"ranking": "ランキング",
@@ -1010,13 +1011,14 @@
"BatchCommandNotExecuted": "未実行コマンド",
"ExecuteFailedCommand": "失敗コマンドの実行",
"SessionTrend": "セッショントレンド",
+ "SessionConnectTrend": "セッション接続の傾向",
"UserLoginTrend": "アカウントログイントレンド",
"TimesWeekUnit": "回/週",
"TopAssetsOfWeek": "週間資産TOP10",
"TopUsersOfWeek": "週ユーザーTOP10",
"User": "ユーザー",
"UserRatio": "ユーザー比率統計",
- "UsersTotal": "アカウント総数",
+ "UsersTotal": "総ユーザー数",
"Weekly": "週ごと"
},
"ops": {
diff --git a/src/i18n/langs/zh.json b/src/i18n/langs/zh.json
index 8e40dd9c7..0742bfca1 100644
--- a/src/i18n/langs/zh.json
+++ b/src/i18n/langs/zh.json
@@ -960,22 +960,23 @@
"LoginCount": "登录次数",
"LoginOverview": "会话统计",
"LoginTo": "登录了",
- "LoginUsers": "活跃账号",
+ "ActiveUsers": "活跃用户",
"Monthly": "按月",
"CurrentConnections": "当前连接数",
- "TodayFailedConnections": "今日连接失败数",
+ "CurrentConnectionUsers": "当前会话用户数",
+ "TodayFailedConnections": "今日会话失败数",
"OnlineSessions": "在线会话数",
"RealTimeData": "实时数据",
- "UserAssetActivity": "账号/资产活跃情况",
- "UserData": "账号数据",
- "LoginUserToday": "今日登录账号数",
+ "UserAssetActivity": "用户/资产活跃情况",
+ "UserData": "用户数据",
+ "LoginUserToday": "今日登录用户数",
"AssetData": "资产数据",
"LoginAssetToday": "今日活跃资产数",
"WeekAdd": "本周新增",
"ProportionOfAssetTypes": "资产类型占比",
"Proportion": "占比",
- "LoginUserRanking": "登录账号排名",
- "ActiveAssetRanking": "登录资产排名",
+ "LoginUserRanking": "会话用户排名",
+ "ActiveAssetRanking": "会话资产排名",
"AssetName": "资产名称",
"NumberOfVisits": "访问次数",
"ranking": "排名",
@@ -999,13 +1000,13 @@
"BatchCommandNotExecuted": "未执行批量命令",
"ExecuteFailedCommand": "执行失败命令",
"SessionTrend": "会话趋势",
- "UserLoginTrend": "账号登录趋势",
+ "SessionConnectTrend": "会话连接趋势",
"TimesWeekUnit": "次/周",
"TopAssetsOfWeek": "周资产 TOP10",
"TopUsersOfWeek": "周用户 TOP10",
"User": "用户",
"UserRatio": "用户占比统计",
- "UsersTotal": "账号总数",
+ "UsersTotal": "用户总数",
"Weekly": "按周"
},
"ops": {
diff --git a/src/icons/svg/batch-update.svg b/src/icons/svg/batch-update.svg
index 1e29b7fca..841d8a769 100644
--- a/src/icons/svg/batch-update.svg
+++ b/src/icons/svg/batch-update.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/src/layout/components/Page/index.vue b/src/layout/components/Page/index.vue
index 52858e407..61083de04 100644
--- a/src/layout/components/Page/index.vue
+++ b/src/layout/components/Page/index.vue
@@ -71,6 +71,11 @@ export default {
height: calc(100vh - 50px);
overflow-y: auto;
overflow-x: hidden;
+
+ .el-alert {
+ margin-top: -10px;
+ margin-bottom: 10px;
+ }
}
.go-back {
diff --git a/src/utils/startup.js b/src/utils/startup.js
index 8022861ba..6efe9e084 100644
--- a/src/utils/startup.js
+++ b/src/utils/startup.js
@@ -8,6 +8,8 @@ import orgUtil from '@/utils/org'
import orgs from '@/api/orgs'
import { getPropView, isViewHasOrgs } from '@/utils/jms'
import request from '@/utils/request'
+import i18n from '@/i18n/i18n'
+import { MessageBox } from 'element-ui'
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
@@ -39,12 +41,30 @@ async function checkLogin({ to, from, next }) {
return reject('No session mark found in cookie')
} else if (sessionExpire === 'close') {
let startTime = new Date().getTime()
+ this.newLoginHasOpen = false
const intervalId = setInterval(() => {
const endTime = new Date().getTime()
const delta = (endTime - startTime)
startTime = endTime
Vue.$log.debug('Set session expire: ', delta)
- if (!isRenewalExpired(120)) {
+ const currentTimeStamp = Math.floor(endTime / 1000)
+ const sessionExpireTimestamp = VueCookie.get('jms_session_expire_timestamp')
+ if (currentTimeStamp >= parseInt(sessionExpireTimestamp, 10)) {
+ if (!this.newLoginHasOpen) {
+ this.newLoginHasOpen = true
+ MessageBox.confirm(
+ i18n.t('auth.LoginRequiredMsg'),
+ i18n.t('common.Info'),
+ {
+ confirmButtonText: i18n.t('auth.ReLogin'),
+ cancelButtonText: i18n.t('common.Cancel'),
+ type: 'warning'
+ }).finally(() => {
+ window.location = '/core/auth/logout/'
+ clearInterval(intervalId)
+ })
+ }
+ } else if (!isRenewalExpired(120)) {
VueCookie.set('jms_session_expire', 'close', { expires: '2m' })
} else {
clearInterval(intervalId)
diff --git a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
index 6c77af0a3..751ff554f 100644
--- a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
+++ b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
@@ -1,5 +1,5 @@
-
+