diff --git a/backend/pom.xml b/backend/pom.xml index f26f78c70a..160cf502c7 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -100,7 +100,7 @@ com.github.pagehelper pagehelper - 5.3.0 + 5.3.1 org.apache.shiro diff --git a/backend/src/main/java/io/dataease/auth/entity/AccountLockStatus.java b/backend/src/main/java/io/dataease/auth/entity/AccountLockStatus.java index fbd62da94a..8555d2c381 100644 --- a/backend/src/main/java/io/dataease/auth/entity/AccountLockStatus.java +++ b/backend/src/main/java/io/dataease/auth/entity/AccountLockStatus.java @@ -10,4 +10,6 @@ public class AccountLockStatus { private String username; private Long unlockTime; + + private Integer relieveTimes; } diff --git a/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/backend/src/main/java/io/dataease/auth/server/AuthServer.java index 6cb82b4968..e4282473a2 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -72,7 +72,7 @@ public class AuthServer implements AuthApi { AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 1); if (accountLockStatus.getLocked()) { String msg = Translator.get("I18N_ACCOUNT_LOCKED"); - msg = String.format(msg, username); + msg = String.format(msg, username, accountLockStatus.getRelieveTimes().toString()); DataEaseException.throwException(msg); } LdapXpackService ldapXpackService = SpringContextUtil.getBean(LdapXpackService.class); @@ -112,7 +112,7 @@ public class AuthServer implements AuthApi { AccountLockStatus accountLockStatus = authUserService.lockStatus(username, 0); if (accountLockStatus.getLocked()) { String msg = Translator.get("I18N_ACCOUNT_LOCKED"); - msg = String.format(msg, username); + msg = String.format(msg, username, accountLockStatus.getRelieveTimes().toString()); DataEaseException.throwException(msg); } @@ -155,6 +155,7 @@ public class AuthServer implements AuthApi { result.put("token", token); ServletUtils.setToken(token); DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, user.getUserId(), null, null, null); + authUserService.unlockAccount(username, ObjectUtils.isEmpty(loginType) ? 0 : loginType); authUserService.clearCache(user.getUserId()); return result; } diff --git a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java index 564d7cc2fd..fdacc9c541 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/AuthUserServiceImpl.java @@ -298,6 +298,7 @@ public class AuthUserServiceImpl implements AuthUserService { if (needLock) { long unlockTime = now + (longRelieveTimes * 60L * 1000L); accountLockStatus.setUnlockTime(unlockTime); + accountLockStatus.setRelieveTimes(relieveTimes); } } diff --git a/backend/src/main/resources/db/migration/V40__1.15.sql b/backend/src/main/resources/db/migration/V40__1.15.sql index a6e5edda74..f4e4faee31 100644 --- a/backend/src/main/resources/db/migration/V40__1.15.sql +++ b/backend/src/main/resources/db/migration/V40__1.15.sql @@ -126,4 +126,86 @@ INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_typ INSERT INTO `sys_auth_detail` (`id`, `auth_id`, `privilege_name`, `privilege_type`, `privilege_value`, `privilege_extend`, `remark`, `create_user`, `create_time`, `update_time`, `copy_from`, `copy_id`) VALUES ('d55c4d88-3b0a-11ed-8009-0242ac130005', '379c3124-7a30-4c1b-8ae4-de23eaf34b71', 'i18n_auth_use', 1, 1, 'use', '基础权限-使用', 'admin', 1663915323000, NULL, NULL, NULL); INSERT INTO `sys_auth` (`id`, `auth_source`, `auth_source_type`, `auth_target`, `auth_target_type`, `auth_time`, `auth_details`, `auth_user`, `update_time`, `copy_from`, `copy_id`) VALUES ('379c3124-7a30-4c1b-8ae4-de23eaf34b71', 'bdfcc324-1181-46a6-b681-a453517c4ffa', 'dataset', '2', 'user', 1663915323123, NULL, 'admin', NULL, NULL, NULL); -DELETE from `sys_menu` where `menu_id` = 50; \ No newline at end of file +DELETE from `sys_menu` where `menu_id` = 50; + + + +-- ---------------------------- +-- Function structure for GET_V_AUTH_MODEL_WITH_CHILDREN +-- ---------------------------- +DROP FUNCTION IF EXISTS `GET_V_AUTH_MODEL_WITH_CHILDREN`; +delimiter ;; +CREATE FUNCTION `GET_V_AUTH_MODEL_WITH_CHILDREN`(parentId longtext,modelType varchar(255)) + RETURNS longtext CHARSET utf8mb4 + READS SQL DATA +BEGIN + +DECLARE oTemp longtext; + +DECLARE oTempChild longtext; + +DECLARE levelCount INTEGER; + +SET levelCount = 0; + +SET oTemp = ''; + +SET oTempChild = CAST(parentId AS CHAR CHARACTER set utf8mb4) COLLATE utf8mb4_general_ci; + +WHILE oTempChild IS NOT NULL and levelCount < 15 + +DO + +SET oTemp = CONCAT(oTemp,',',oTempChild); + +SET levelCount = 0; + +SELECT GROUP_CONCAT(id) INTO oTempChild FROM V_AUTH_MODEL WHERE FIND_IN_SET(pid,oTempChild) > 0 and V_AUTH_MODEL.model_type=modelType order by id asc; + +END WHILE; + +RETURN oTemp; + +END +;; +delimiter ; + +-- ---------------------------- +-- Function structure for GET_V_AUTH_MODEL_WITH_PARENT +-- ---------------------------- +DROP FUNCTION IF EXISTS `GET_V_AUTH_MODEL_WITH_PARENT`; +delimiter ;; +CREATE FUNCTION `GET_V_AUTH_MODEL_WITH_PARENT`(childrenId longtext,modelType varchar(255)) + RETURNS longtext CHARSET utf8mb4 + READS SQL DATA +BEGIN + +DECLARE oTemp longtext; + +DECLARE oTempParent longtext; + +DECLARE levelCount INTEGER; + +SET levelCount = 0; + +SET oTemp = ''; + +SET oTempParent = CAST(childrenId AS CHAR CHARACTER set utf8mb4) COLLATE utf8mb4_general_ci; + +WHILE oTempParent IS NOT NULL and levelCount < 15 + +DO + +SET oTemp = CONCAT(oTemp,',',oTempParent); + +SET levelCount = levelCount + 1; + +SELECT GROUP_CONCAT(distinct pid) INTO oTempParent FROM V_AUTH_MODEL WHERE FIND_IN_SET(id,oTempParent) > 0 and V_AUTH_MODEL.model_type=modelType order by pid asc; + +END WHILE; + +RETURN oTemp; + +END +;; +delimiter ; diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index f7592ca718..4577f24e93 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -233,7 +233,7 @@ I18N_DS_INVALID_TABLE=Datasource has invalid tables -I18N_ACCOUNT_LOCKED=Account\u3010%s\u3011is locked\uFF01 +I18N_ACCOUNT_LOCKED=Account\u3010%s\u3011is locked(Please contact the administrator to unlock or try again in %s minutes) I18N_PANEL_EXIST=The current panel name already exists under this directory I18N_DATASET_GROUP_EXIST=The current dataset grouping name already exists under this directory diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 946d37a153..c427e12348 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -233,7 +233,7 @@ I18N_DS_INVALID_TABLE=\u6570\u636E\u6E90\u4E2D\u6709\u65E0\u6548\u7684\u8868 -I18N_ACCOUNT_LOCKED=\u8D26\u53F7\u3010%s\u3011\u5DF2\u9501\u5B9A\uFF01 +I18N_ACCOUNT_LOCKED=\u8D26\u53F7\u3010%s\u3011\u5DF2\u9501\u5B9A(\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u89E3\u9501\u6216%s\u5206\u949F\u540E\u91CD\u8BD5) I18N_PANEL_EXIST=\u5F53\u524D\u4EEA\u8868\u677F\u540D\u79F0\u5728\u8BE5\u76EE\u5F55\u4E0B\u9762\u5DF2\u7ECF\u5B58\u5728 I18N_DATASET_GROUP_EXIST=\u5F53\u524D\u6570\u636E\u96C6\u5206\u7EC4\u540D\u79F0\u5728\u8BE5\u76EE\u5F55\u4E0B\u9762\u5DF2\u7ECF\u5B58\u5728 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index eddffe3e99..ba91a4e5f4 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -229,7 +229,7 @@ I18N_DS_INVALID_TABLE=\u6578\u64DA\u6E90\u4E2D\u6709\u7121\u6548\u7684\u8868 -I18N_ACCOUNT_LOCKED=\u8CEC\u865F\u3010%s\u3011\u5DF2\u9396\u5B9A\uFF01 +I18N_ACCOUNT_LOCKED=\u8CEC\u865F\u3010%s\u3011\u5DF2\u9396\u5B9A(\u8ACB\u806F\u7CFB\u7BA1\u7406\u54E1\u89E3\u9396\u6216%s\u5206\u9418\u5F8C\u91CD\u8A66) I18N_PANEL_EXIST=\u7576\u524D\u5100\u9336\u95C6\u540D\u7A31\u5728\u8A72\u76EE\u9304\u4E0B\u9762\u5DF2\u7D93\u5B58\u5728 I18N_DATASET_GROUP_EXIST=\u7576\u524D\u6578\u64DA\u96C6\u5206\u7D44\u540D\u7A31\u5728\u8A72\u76EE\u9304\u4E0B\u9762\u5DF2\u7D93\u5B58\u5728 diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 32bfa17da4..f14fe50959 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -916,6 +916,7 @@ export default { margin_model_absolute: 'Absolute', margin_model_relative: 'Relative', margin_placeholder: 'Please enter a number from 0-100', + margin_absolute_placeholder: 'Please enter a number from 0-40', rich_text_view_result_tips: 'The rich text view selects only the first result', rich_text_view: 'Rich Text View', view_reset: 'View Reset', @@ -2167,7 +2168,8 @@ export default { homeLink: 'Home Link', defaultHomeLink: 'Default is the system built-in home page', showFoot: 'Show login page footer', - footContent: 'Foot content' + footContent: 'Foot content', + webFormat: 'Please enter the correct URL starting with [https:// or http://]' }, auth: { no_item_selected: 'Please select organization、user or role on the left', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 5a2d70312d..212c7e7b65 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -916,6 +916,7 @@ export default { margin_model_absolute: '絕對', margin_model_relative: '相對', margin_placeholder: '請輸入0-100數字', + margin_absolute_placeholder: '請輸入0-40數字', rich_text_view_result_tips: '富文本只选取第一条结果', rich_text_view: '富文本视图', view_reset: '視圖重置', @@ -2168,7 +2169,8 @@ export default { homeLink: '首頁鏈接', defaultHomeLink: '默認為系統內置首頁', showFoot: '顯示登錄頁腳', - footContent: '頁腳內容' + footContent: '頁腳內容', + webFormat: '請輸入以[https://或http://]開頭的正確網址' }, auth: { no_item_selected: '请在左侧选择组织、角色或用户', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index f2c22f1988..c1ba56582b 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -915,6 +915,7 @@ export default { margin_model_absolute: '绝对', margin_model_relative: '相对', margin_placeholder: '请输入0-100数字', + margin_absolute_placeholder: '请输入0-40数字', rich_text_view_result_tips: '富文本只选取第一条结果', rich_text_view: '富文本视图', view_reset: '视图重置', @@ -2168,7 +2169,8 @@ export default { homeLink: '首页链接', defaultHomeLink: '默认为系统内置首页', showFoot: '显示登录页脚', - footContent: '页脚内容' + footContent: '页脚内容', + webFormat: '请输入以[https://或http://]开头的正确网址' }, auth: { no_item_selected: '请在左侧选择组织、角色或用户', diff --git a/frontend/src/views/chart/chart/util.js b/frontend/src/views/chart/chart/util.js index 006a267362..55678128c7 100644 --- a/frontend/src/views/chart/chart/util.js +++ b/frontend/src/views/chart/chart/util.js @@ -1538,17 +1538,10 @@ export const TYPE_CONFIGS = [ properties: [ 'color-selector', 'size-selector', - 'title-selector', - 'margin-selector' + 'title-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'quotaColor', 'dimensionColor' @@ -1590,17 +1583,10 @@ export const TYPE_CONFIGS = [ properties: [ 'color-selector', 'size-selector', - 'title-selector', - 'margin-selector' + 'title-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'quotaColor', 'dimensionColor' @@ -1643,17 +1629,10 @@ export const TYPE_CONFIGS = [ 'color-selector', 'size-selector', 'label-selector', - 'title-selector', - 'margin-selector' + 'title-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2316,17 +2295,10 @@ export const TYPE_CONFIGS = [ 'label-selector', 'tooltip-selector', 'title-selector', - 'legend-selector', - 'margin-selector' + 'legend-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2382,17 +2354,10 @@ export const TYPE_CONFIGS = [ 'label-selector', 'tooltip-selector', 'title-selector', - 'legend-selector', - 'margin-selector' + 'legend-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2450,17 +2415,10 @@ export const TYPE_CONFIGS = [ 'tooltip-selector', 'split-selector', 'title-selector', - 'legend-selector', - 'margin-selector' + 'legend-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2521,17 +2479,10 @@ export const TYPE_CONFIGS = [ 'size-selector', 'label-selector', 'tooltip-selector', - 'title-selector', - 'margin-selector' + 'title-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2664,17 +2615,10 @@ export const TYPE_CONFIGS = [ 'label-selector', 'tooltip-selector', 'title-selector', - 'legend-selector', - 'margin-selector' + 'legend-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', @@ -2727,17 +2671,10 @@ export const TYPE_CONFIGS = [ 'color-selector', 'label-selector', 'tooltip-selector', - 'title-selector', - 'margin-selector' + 'title-selector' ], propertyInner: { - 'margin-selector': [ - 'marginModel', - 'marginTop', - 'marginBottom', - 'marginLeft', - 'marginRight' - ], + 'color-selector': [ 'value', 'custom', diff --git a/frontend/src/views/chart/components/component-style/MarginSelector.vue b/frontend/src/views/chart/components/component-style/MarginSelector.vue index fc7d8ee65b..41ebf2aa2a 100644 --- a/frontend/src/views/chart/components/component-style/MarginSelector.vue +++ b/frontend/src/views/chart/components/component-style/MarginSelector.vue @@ -3,7 +3,7 @@ - + {{ $t('chart.margin_model_auto') }} {{ $t('chart.margin_model_absolute') }} {{ $t('chart.margin_model_relative') }} @@ -11,25 +11,25 @@
- + - + - + - + @@ -84,6 +84,15 @@ export default { computed: { unitSuffix() { return getMarginUnit(this.marginForm) + }, + placeholder() { + if (this.marginForm.marginModel === 'absolute') { + return this.$t('chart.margin_placeholder') + } else if (this.marginForm.marginModel === 'relative') { + return this.$t('chart.margin_absolute_placeholder') + } else { + return null + } } }, watch: { @@ -113,6 +122,20 @@ export default { }, changeMarginStyle(value, modifyName) { + if (modifyName === 'marginModel') { + if (value === 'absolute') { + this.marginForm.marginTop = JSON.parse(JSON.stringify(DEFAULT_MARGIN_STYLE)).marginTop + this.marginForm.marginBottom = JSON.parse(JSON.stringify(DEFAULT_MARGIN_STYLE)).marginBottom + this.marginForm.marginLeft = JSON.parse(JSON.stringify(DEFAULT_MARGIN_STYLE)).marginLeft + this.marginForm.marginRight = JSON.parse(JSON.stringify(DEFAULT_MARGIN_STYLE)).marginRight + } + if (value === 'relative') { + this.marginForm.marginTop = 15 + this.marginForm.marginBottom = 15 + this.marginForm.marginLeft = 5 + this.marginForm.marginRight = 5 + } + } this.marginForm['modifyName'] = modifyName this.$emit('onMarginChange', this.marginForm) }, @@ -124,9 +147,14 @@ export default { callBack() return } - if (value < 0 || value > 100) { + if (this.marginForm.marginModel === 'absolute' && (value < 0 || value > 100)) { callBack(new Error(this.$t('chart.margin_placeholder'))) this.marginForm[rule.field] = 0 + } else if (this.marginForm.marginModel === 'relative' && (value < 0 || value > 40)) { + callBack(new Error(this.$t('chart.margin_absolute_placeholder'))) + this.marginForm[rule.field] = 0 + } else { + callBack() } } } diff --git a/frontend/src/views/panel/template/index.vue b/frontend/src/views/panel/template/index.vue index a9874ec1aa..15c99a174c 100644 --- a/frontend/src/views/panel/template/index.vue +++ b/frontend/src/views/panel/template/index.vue @@ -24,7 +24,7 @@ ref="templateList" :template-type="currentTemplateType" :template-list="templateList" - @templateDelete="templateDelete" + @templateDelete="templateFolderDelete" @templateEdit="templateEdit" @showCurrentTemplate="showCurrentTemplate" @templateImport="templateImport" @@ -253,6 +253,14 @@ export default { }); } }, + templateFolderDelete(id) { + if (id) { + templateDelete(id).then((response) => { + this.openMessageSuccess("commons.delete_success"); + this.getTree() + }); + } + }, templateDelete(id) { if (id) { templateDelete(id).then((response) => { diff --git a/frontend/src/views/system/SysParam/BasicSetting.vue b/frontend/src/views/system/SysParam/BasicSetting.vue index 82897bb59d..369608b71b 100644 --- a/frontend/src/views/system/SysParam/BasicSetting.vue +++ b/frontend/src/views/system/SysParam/BasicSetting.vue @@ -152,18 +152,11 @@ export default { } ], limitTimes: [ - { - pattern: '^([1-9]|[1-9]\\d|100)$', - message: this.$t('system_parameter_setting.limit_times_error'), - trigger: 'blur' - } + + { validator: this.validateNumber, trigger: 'blur' } ], relieveTimes: [ - { - pattern: '^([1-9]|[1-9]\\d|100)$', - message: this.$t('system_parameter_setting.relieve_times_error'), - trigger: 'blur' - } + { validator: this.validateNumber, trigger: 'blur' } ] }, originLoginType: null @@ -193,6 +186,17 @@ export default { this.query() }, methods: { + validateNumber(rule, value, callback) { + if (value != null && value !== '') { + const reg = new RegExp('^([1-9]|[1-9]\\d|100)$') + if (!reg.test(value)) { + const msg = this.$t('system_parameter_setting.relieve_times_error') + callback(new Error(msg)) + return + } + } + callback() + }, query() { basicInfo().then((response) => { this.formInline = response.data