diff --git a/backend/src/main/java/io/dataease/controller/handler/GlobalExceptionHandler.java b/backend/src/main/java/io/dataease/controller/handler/GlobalExceptionHandler.java index 942ba92278..5fd2170072 100644 --- a/backend/src/main/java/io/dataease/controller/handler/GlobalExceptionHandler.java +++ b/backend/src/main/java/io/dataease/controller/handler/GlobalExceptionHandler.java @@ -1,6 +1,8 @@ package io.dataease.controller.handler; import io.dataease.controller.ResultHolder; +import io.dataease.controller.handler.annotation.I18n; +import io.dataease.i18n.Translator; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; import org.springframework.boot.web.servlet.error.ErrorAttributes; @@ -66,7 +68,8 @@ public class GlobalExceptionHandler implements ErrorController { errorMessage = "The server responds " + code + " but no detailed message."; } } - return ResultHolder.error(errorMessage); + + return ResultHolder.error(Translator.get(errorMessage)); } protected Map getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index 1da183efbe..8526143f3b 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -239,7 +239,7 @@ i18n_processing_data=Processing data now, Refresh later i18n_union_already_exists=Union relation already exists i18n_union_field_exists=The same field can't in two dataset i18n_cron_time_error=Start time can't greater then end time -i18n_auth_source_be_canceled=This Auth Resource Already Be Canceled +i18n_auth_source_be_canceled=This Auth Resource Already Be Canceled,Please Connect Admin i18n_username_exists=ID is already exists i18n_ds_name_exists=Datasource name used i18n_sync_job_exists=There is already a synchronization task running, please try again later diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 32c16a21b7..75459b9951 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -239,7 +239,7 @@ i18n_processing_data=正在处理数据,稍后刷新 i18n_union_already_exists=关联关系已存在 i18n_union_field_exists=两个数据集之间关联不能出现多次相同字段 i18n_cron_time_error=开始时间不能大于结束时间 -i18n_auth_source_be_canceled=当前资源授权权限已经被取消 +i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员 i18n_username_exists=用户 ID 已存在 i18n_ds_name_exists=数据源名称已被使用 i18n_sync_job_exists=已经有同步任务在运行,稍后重试 diff --git a/backend/src/main/resources/i18n/messages_zh_TW.properties b/backend/src/main/resources/i18n/messages_zh_TW.properties index 7b65513ca1..94d480cab4 100644 --- a/backend/src/main/resources/i18n/messages_zh_TW.properties +++ b/backend/src/main/resources/i18n/messages_zh_TW.properties @@ -241,7 +241,7 @@ i18n_processing_data=正在處理數據,稍後刷新 i18n_union_already_exists=關聯關系已存在 i18n_union_field_exists=兩個數據集之間關聯不能出現多次相同字段 i18n_cron_time_error=開始時間不能大於結束時間 -i18n_auth_source_be_canceled=當前資源授權權限已經被取消 +i18n_auth_source_be_canceled=本用户当前资源所有授权权限已经被取消,如需再次开通,请联系管理员 i18n_username_exists=用戶ID已存在 i18n_ds_name_exists=數據源名稱已被使用 i18n_sync_job_exists=已經有同步任務在運行,稍後重試 diff --git a/frontend/src/components/DeDrag/index.vue b/frontend/src/components/DeDrag/index.vue new file mode 100644 index 0000000000..1be67c4dba --- /dev/null +++ b/frontend/src/components/DeDrag/index.vue @@ -0,0 +1,1597 @@ + + + + diff --git a/frontend/src/components/DeDrag/option.js b/frontend/src/components/DeDrag/option.js new file mode 100644 index 0000000000..3d1a10d8f2 --- /dev/null +++ b/frontend/src/components/DeDrag/option.js @@ -0,0 +1,26 @@ +export const events = { + mouse: { + start: 'mousedown', + move: 'mousemove', + stop: 'mouseup' + }, + touch: { + start: 'touchstart', + move: 'touchmove', + stop: 'touchend' + } +} +// 禁止用户选取 +export const userSelectNone = { + userSelect: 'none', + MozUserSelect: 'none', + WebkitUserSelect: 'none', + MsUserSelect: 'none' +} +// 用户选中自动 +export const userSelectAuto = { + userSelect: 'auto', + MozUserSelect: 'auto', + WebkitUserSelect: 'auto', + MsUserSelect: 'auto' +} diff --git a/frontend/src/components/canvas/components/Editor/Grid.vue b/frontend/src/components/canvas/components/Editor/Grid.vue index 60c1f06c4e..a12b6d9313 100644 --- a/frontend/src/components/canvas/components/Editor/Grid.vue +++ b/frontend/src/components/canvas/components/Editor/Grid.vue @@ -1,18 +1,18 @@ + + diff --git a/frontend/src/components/canvas/components/Toolbar.vue b/frontend/src/components/canvas/components/Toolbar.vue index 57a9300788..048e5c2d86 100644 --- a/frontend/src/components/canvas/components/Toolbar.vue +++ b/frontend/src/components/canvas/components/Toolbar.vue @@ -2,6 +2,11 @@
+
+ + 矩阵设计 +
+
自适应画布区域 diff --git a/frontend/src/components/canvas/store/layer.js b/frontend/src/components/canvas/store/layer.js index fac44172eb..a5554be878 100644 --- a/frontend/src/components/canvas/store/layer.js +++ b/frontend/src/components/canvas/store/layer.js @@ -2,41 +2,41 @@ import { swap } from '@/components/canvas/utils/utils' import toast from '@/components/canvas/utils/toast' export default { - mutations: { - upComponent({ componentData, curComponentIndex }) { - // 上移图层 index,表示元素在数组中越往后 - if (curComponentIndex < componentData.length - 1) { - swap(componentData, curComponentIndex, curComponentIndex + 1) - } else { - toast('已经到顶了') - } - }, - - downComponent({ componentData, curComponentIndex }) { - // 下移图层 index,表示元素在数组中越往前 - if (curComponentIndex > 0) { - swap(componentData, curComponentIndex, curComponentIndex - 1) - } else { - toast('已经到底了') - } - }, - - topComponent({ componentData, curComponentIndex }) { - // 置顶 - if (curComponentIndex < componentData.length - 1) { - swap(componentData, curComponentIndex, componentData.length - 1) - } else { - toast('已经到顶了') - } - }, - - bottomComponent({ componentData, curComponentIndex }) { - // 置底 - if (curComponentIndex > 0) { - swap(componentData, curComponentIndex, 0) - } else { - toast('已经到底了') - } - }, + mutations: { + upComponent({ componentData, curComponentIndex }) { + // 上移图层 index,表示元素在数组中越往后 + if (curComponentIndex < componentData.length - 1) { + swap(componentData, curComponentIndex, curComponentIndex + 1) + } else { + toast('已经到顶了') + } }, + + downComponent({ componentData, curComponentIndex }) { + // 下移图层 index,表示元素在数组中越往前 + if (curComponentIndex > 0) { + swap(componentData, curComponentIndex, curComponentIndex - 1) + } else { + toast('已经到底了') + } + }, + + topComponent({ componentData, curComponentIndex }) { + // 置顶 + if (curComponentIndex < componentData.length - 1) { + swap(componentData, curComponentIndex, componentData.length - 1) + } else { + toast('已经到顶了') + } + }, + + bottomComponent({ componentData, curComponentIndex }) { + // 置底 + if (curComponentIndex > 0) { + swap(componentData, curComponentIndex, 0) + } else { + toast('已经到底了') + } + } + } } diff --git a/frontend/src/components/canvas/store/snapshot.js b/frontend/src/components/canvas/store/snapshot.js index 13a4078d4e..d3ca59984d 100644 --- a/frontend/src/components/canvas/store/snapshot.js +++ b/frontend/src/components/canvas/store/snapshot.js @@ -25,6 +25,7 @@ export default { }, recordSnapshot(state) { + console.log('recordSnapshot') // 添加新的快照 state.snapshotData[++state.snapshotIndex] = deepCopy(state.componentData) state.snapshotStyleData[state.snapshotIndex] = deepCopy(state.canvasStyleData) diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 4542e1f208..2a2a42c68e 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -952,6 +952,7 @@ export default { close_aided_design: 'Close Component Aided Design', open_style_design: 'Open Style Design', close_style_design: 'Close Style Design', + matrix_design: 'Matrix Design', left: 'X-Axis', top: 'Y-Axis', height: 'Height', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 87b36e018b..deb4b2a023 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -952,6 +952,7 @@ export default { close_aided_design: '关闭组件辅助设计', open_style_design: '打开样式设计', close_style_design: '关闭样式设计', + matrix_design: '矩阵设计', left: 'x 坐标', top: 'y 坐标', height: '高', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 4ac04da602..1bafe36a32 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -952,6 +952,7 @@ export default { close_aided_design: '关闭组件辅助设计', open_style_design: '打开样式设计', close_style_design: '关闭样式设计', + matrix_design: '矩阵设计', left: 'x 坐标', top: 'y 坐标', height: '高', diff --git a/frontend/src/main.js b/frontend/src/main.js index 2bef70b47d..3bc86b2f67 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -27,6 +27,7 @@ Vue.use(VueClipboard) Vue.use(widgets) Vue.prototype.$api = api + import * as echarts from 'echarts' Vue.prototype.$echarts = echarts diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 7d91bf307c..7f9e237152 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -72,7 +72,7 @@ const data = { }, setCurComponent(state, { component, index }) { - // console.log('curComponent' + JSON.stringify(component)) + console.log('curComponent' + JSON.stringify(component)) state.curComponent = component state.curComponentIndex = index }, @@ -82,12 +82,12 @@ const data = { }, setShapeStyle({ curComponent, canvasStyleData, curCanvasScale }, { top, left, width, height, rotate }) { - if (top) curComponent.style.top = parseInt(canvasStyleData.selfAdaption ? (top * 100 / curCanvasScale.scaleHeight) : top) - if (left) curComponent.style.left = parseInt(canvasStyleData.selfAdaption ? (left * 100 / curCanvasScale.scaleWidth) : left) - if (width) curComponent.style.width = parseInt(canvasStyleData.selfAdaption ? (width * 100 / curCanvasScale.scaleWidth) : width) - if (height) curComponent.style.height = parseInt(canvasStyleData.selfAdaption ? (height * 100 / curCanvasScale.scaleHeight) : height) - if (rotate) curComponent.style.rotate = rotate - // console.log('setShapeStyle' + JSON.stringify(curComponent)) + if (top || top === 0) curComponent.style.top = parseInt(canvasStyleData.selfAdaption ? (top * 100 / curCanvasScale.scaleHeight) : top) + if (left || left === 0) curComponent.style.left = parseInt(canvasStyleData.selfAdaption ? (left * 100 / curCanvasScale.scaleWidth) : left) + if (width || width === 0) curComponent.style.width = parseInt(canvasStyleData.selfAdaption ? (width * 100 / curCanvasScale.scaleWidth) : width) + if (height || height === 0) curComponent.style.height = parseInt(canvasStyleData.selfAdaption ? (height * 100 / curCanvasScale.scaleHeight) : height) + if (rotate || rotate === 0) curComponent.style.rotate = rotate + // console.log('setShapeStyle:curComponent' + 'top:' + top + ';left:' + left + '====' + JSON.stringify(curComponent)) }, setShapeSingleStyle({ curComponent }, { key, value }) { diff --git a/frontend/src/utils/dom.js b/frontend/src/utils/dom.js new file mode 100644 index 0000000000..19799743f6 --- /dev/null +++ b/frontend/src/utils/dom.js @@ -0,0 +1,60 @@ +import { isFunction } from './fns' + +// 将选择器与父元素匹配 +export function matchesSelectorToParentElements(el, selector, baseNode) { + let node = el + + const matchesSelectorFunc = [ + 'matches', + 'webkitMatchesSelector', + 'mozMatchesSelector', + 'msMatchesSelector', + 'oMatchesSelector' + ].find(func => isFunction(node[func])) + + if (!isFunction(node[matchesSelectorFunc])) return false + + do { + if (node[matchesSelectorFunc](selector)) return true + if (node === baseNode) return false + node = node.parentNode + } while (node) + + return false +} + +export function getComputedSize($el) { + const style = window.getComputedStyle($el) + + return [ + parseFloat(style.getPropertyValue('width'), 10), + parseFloat(style.getPropertyValue('height'), 10) + ] +} +// 添加事件 +export function addEvent(el, event, handler) { + if (!el) { + return + } + if (el.attachEvent) { + el.attachEvent('on' + event, handler) + } else if (el.addEventListener) { + el.addEventListener(event, handler, true) + } else { + el['on' + event] = handler + } +} + +// 删除事件 +export function removeEvent(el, event, handler) { + if (!el) { + return + } + if (el.detachEvent) { + el.detachEvent('on' + event, handler) + } else if (el.removeEventListener) { + el.removeEventListener(event, handler, true) + } else { + el['on' + event] = null + } +} diff --git a/frontend/src/utils/fns.js b/frontend/src/utils/fns.js new file mode 100644 index 0000000000..0516ed58cc --- /dev/null +++ b/frontend/src/utils/fns.js @@ -0,0 +1,60 @@ +export function isFunction(func) { + return (typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]') +} + +// 对齐栅格 +export function snapToGrid(grid, pendingX, pendingY, scale = 1) { + const x = Math.round((pendingX / scale) / grid[0]) * grid[0] + const y = Math.round((pendingY / scale) / grid[1]) * grid[1] + return [x, y] +} + +// 获取rect模型 +export function getSize(el) { + const rect = el.getBoundingClientRect() + return [ + parseInt(rect.width), + parseInt(rect.height) + ] +} + +export function computeWidth(parentWidth, left, right) { + return parentWidth - left - right +} + +export function computeHeight(parentHeight, top, bottom) { + return parentHeight - top - bottom +} + +export function restrictToBounds(value, min, max) { + if (min !== null && value < min) { + return min + } + + if (max !== null && max < value) { + return max + } + + return value +} + +// 返回相对于参考点旋转后的坐标 +export function rotatedPoint(originX, originY, offsetX, offsetY, rotate) { + const rad = (Math.PI / 180) * rotate + const cos = Math.cos(rad) + const sin = Math.sin(rad) + const x = offsetX - originX + const y = offsetY - originY + return { + x: x * cos - y * sin + originX, + y: x * sin + y * cos + originY + } +} + +// 根据相对坐标返回角度,正方形为顺时针 +export function getAngle(x, y) { + let theta = Math.atan2(y, x) // 正切转弧度 + theta = Math.round((180 / Math.PI) * theta) // 弧度转角度 + if (theta < 0) theta = 360 + theta // 控制角度在0~360度 + return theta // 返回角度 +} diff --git a/frontend/src/views/panel/SubjectSetting/PanelStyle/ComponentGap.vue b/frontend/src/views/panel/SubjectSetting/PanelStyle/ComponentGap.vue index 88076927fe..31753bb155 100644 --- a/frontend/src/views/panel/SubjectSetting/PanelStyle/ComponentGap.vue +++ b/frontend/src/views/panel/SubjectSetting/PanelStyle/ComponentGap.vue @@ -7,8 +7,8 @@ trigger="click" > - {{ $t('panel.gap') }} - {{ $t('panel.no_gap') }} + {{ $t('panel.gap') }} + {{ $t('panel.no_gap') }} {{ $t('panel.component_gap') }} @@ -18,18 +18,32 @@