diff --git a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java index 259ac06695..5b877e9327 100644 --- a/backend/src/main/java/io/dataease/controller/sys/SysUserController.java +++ b/backend/src/main/java/io/dataease/controller/sys/SysUserController.java @@ -3,6 +3,8 @@ package io.dataease.controller.sys; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; +import io.dataease.auth.api.dto.CurrentUserDto; +import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.Pager; import io.dataease.controller.sys.base.BaseGridRequest; @@ -73,4 +75,18 @@ public class SysUserController { public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){ sysUserService.adminUpdatePwd(request); } + + + @ApiOperation("个人信息") + @PostMapping("/personInfo") + public CurrentUserDto personInfo() { + CurrentUserDto user = AuthUtils.getUser(); + return user; + } + + @ApiOperation("更新个人信息") + @PostMapping("/updatePersonInfo") + public void updatePersonInfo(@RequestBody SysUserCreateRequest request){ + sysUserService.updatePersonInfo(request); + } } diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java index a3aab7eedf..6725720bdb 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java @@ -36,4 +36,6 @@ public class ChartViewFieldDTO implements Serializable { private String sort; private List filter; + + private Integer deExtractType; } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 40dbe882fb..ef7b44a338 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -157,7 +157,7 @@ public class ChartViewService { datasourceRequest.setDatasource(ds); String tableName = "ds_" + table.getId().replaceAll("-", "_"); datasourceRequest.setTable(tableName); - datasourceRequest.setQuery(getSQL(ds.getType(), tableName, xAxis, yAxis, extFilterList)); + datasourceRequest.setQuery(transDorisSQL(tableName, xAxis, yAxis, extFilterList)); data = datasourceProvider.getData(datasourceRequest); } @@ -231,9 +231,14 @@ public class ChartViewService { continue; } DatasetTableField field = request.getDatasetTableField(); - filter.append(" AND ") - .append(field.getDataeaseName()) - .append(" ") + if (field.getDeType() == 1 && field.getDeExtractType() != 1) { + filter.append(" AND FROM_UNIXTIME(cast(") + .append(field.getDataeaseName()) + .append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') "); + } else { + filter.append(" AND ").append(field.getDataeaseName()); + } + filter.append(" ") .append(transMysqlFilterTerm(request.getOperator())) .append(" "); if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { @@ -258,24 +263,36 @@ public class ChartViewService { } } - public String transMysqlSQL(String table, List xAxis, List yAxis, List extFilterRequestList) { + public String transDorisSQL(String table, List xAxis, List yAxis, List extFilterRequestList) { // 字段汇总 排序等 String[] field = yAxis.stream().map(y -> { StringBuilder f = new StringBuilder(); if (StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*")) { f.append(y.getSummary()).append("(").append(y.getDataeaseName()).append(")"); } else { - f.append(y.getSummary()).append("(").append("CAST(").append(y.getDataeaseName()).append(" AS ").append(y.getDeType() == 2 ? "DECIMAL(20,0)" : "DECIMAL(20,2)").append("))"); + f.append("ROUND(") + .append(y.getSummary()).append("(") + .append("CAST(").append(y.getDataeaseName()).append(" AS ").append(y.getDeType() == 2 ? "DECIMAL(20,0)" : "DECIMAL(20,2)").append(")") + .append("),2").append(")"); } f.append(" AS _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()); return f.toString(); }).toArray(String[]::new); String[] groupField = xAxis.stream().map(x -> { StringBuilder stringBuilder = new StringBuilder(); - if (x.getDeType() == 1) { - stringBuilder.append("FROM_UNIXTIME(cast(").append(x.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(x.getDataeaseName()); + // 如果原始类型为时间 + if (x.getDeExtractType() == 1) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + stringBuilder.append("unix_timestamp(").append(x.getDataeaseName()).append(")*1000 as ").append(x.getDataeaseName()); + } else { + stringBuilder.append(x.getDataeaseName()); + } } else { - stringBuilder.append(x.getDataeaseName()); + if (x.getDeType() == 1) { + stringBuilder.append("FROM_UNIXTIME(cast(").append(x.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(x.getDataeaseName()); + } else { + stringBuilder.append(x.getDataeaseName()); + } } return stringBuilder.toString(); }).toArray(String[]::new); @@ -291,14 +308,21 @@ public class ChartViewService { .map(x -> { String[] s = x.getFilter().stream().map(f -> { StringBuilder filter = new StringBuilder(); - filter.append(" AND ").append(x.getDataeaseName()).append(transMysqlFilterTerm(f.getTerm())); + if (x.getDeType() == 1 && x.getDeExtractType() != 1) { + filter.append(" AND FROM_UNIXTIME(cast(") + .append(x.getDataeaseName()) + .append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') "); + } else { + filter.append(" AND ").append(x.getDataeaseName()); + } + filter.append(transMysqlFilterTerm(f.getTerm())); if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) { } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')"); } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { filter.append("%").append(f.getValue()).append("%"); } else { - filter.append(f.getValue()); + filter.append("'" + f.getValue() + "'"); } return filter.toString(); }).toArray(String[]::new); @@ -320,14 +344,139 @@ public class ChartViewService { .map(y -> { String[] s = y.getFilter().stream().map(f -> { StringBuilder filter = new StringBuilder(); - filter.append(" AND _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()).append(transMysqlFilterTerm(f.getTerm())); + if (y.getDeType() == 1 && y.getDeExtractType() != 1) { + filter.append(" AND FROM_UNIXTIME(cast(_") + .append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()) + .append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') "); + } else { + filter.append(" AND _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()); + } + filter.append(transMysqlFilterTerm(f.getTerm())); if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) { } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')"); } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { filter.append("%").append(f.getValue()).append("%"); } else { - filter.append(f.getValue()); + filter.append("'" + f.getValue() + "'"); + } + return filter.toString(); + }).toArray(String[]::new); + return StringUtils.join(s, " "); + }).toArray(String[]::new); + if (resultFilter.length == 0) { + return sql; + } else { + String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1}", + "(" + sql + ") AS tmp", + StringUtils.join(resultFilter, " ")); + return filterSql; + } + } + + public String transMysqlSQL(String table, List xAxis, List yAxis, List extFilterRequestList) { + // 字段汇总 排序等 + String[] field = yAxis.stream().map(y -> { + StringBuilder f = new StringBuilder(); + if (StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*")) { + f.append(y.getSummary()).append("(").append(y.getDataeaseName()).append(")"); + } else { + if (StringUtils.equalsIgnoreCase(y.getSummary(), "avg") || StringUtils.containsIgnoreCase(y.getSummary(), "pop")) { + f.append("CAST(") + .append(y.getSummary()).append("(") + .append("CAST(").append(y.getDataeaseName()).append(" AS ").append(y.getDeType() == 2 ? "DECIMAL(20,0)" : "DECIMAL(20,2)").append(")") + .append(") AS DECIMAL(20,2)").append(")"); + } else { + f.append(y.getSummary()).append("(") + .append("CAST(").append(y.getDataeaseName()).append(" AS ").append(y.getDeType() == 2 ? "DECIMAL(20,0)" : "DECIMAL(20,2)").append(")") + .append(")"); + } + } + f.append(" AS _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()); + return f.toString(); + }).toArray(String[]::new); + String[] groupField = xAxis.stream().map(x -> { + StringBuilder stringBuilder = new StringBuilder(); + // 如果原始类型为时间 + if (x.getDeExtractType() == 1) { + if (x.getDeType() == 2 || x.getDeType() == 3) { + stringBuilder.append("unix_timestamp(").append(x.getDataeaseName()).append(")*1000 as ").append(x.getDataeaseName()); + } else { + stringBuilder.append(x.getDataeaseName()); + } + } else { + if (x.getDeType() == 1) { + stringBuilder.append("FROM_UNIXTIME(cast(").append(x.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(x.getDataeaseName()); + } else { + stringBuilder.append(x.getDataeaseName()); + } + } + return stringBuilder.toString(); + }).toArray(String[]::new); + String[] group = xAxis.stream().map(ChartViewFieldDTO::getDataeaseName).toArray(String[]::new); + String[] xOrder = xAxis.stream().filter(f -> StringUtils.isNotEmpty(f.getSort()) && !StringUtils.equalsIgnoreCase(f.getSort(), "none")) + .map(f -> f.getDataeaseName() + " " + f.getSort()).toArray(String[]::new); + String[] yOrder = yAxis.stream().filter(f -> StringUtils.isNotEmpty(f.getSort()) && !StringUtils.equalsIgnoreCase(f.getSort(), "none")) + .map(f -> "_" + f.getSummary() + "_" + (StringUtils.equalsIgnoreCase(f.getDataeaseName(), "*") ? "" : f.getDataeaseName()) + " " + f.getSort()).toArray(String[]::new); + String[] order = Arrays.copyOf(xOrder, xOrder.length + yOrder.length); + System.arraycopy(yOrder, 0, order, xOrder.length, yOrder.length); + + String[] xFilter = xAxis.stream().filter(x -> CollectionUtils.isNotEmpty(x.getFilter()) && x.getFilter().size() > 0) + .map(x -> { + String[] s = x.getFilter().stream().map(f -> { + StringBuilder filter = new StringBuilder(); + if (x.getDeType() == 1 && x.getDeExtractType() != 1) { + filter.append(" AND FROM_UNIXTIME(cast(") + .append(x.getDataeaseName()) + .append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') "); + } else { + filter.append(" AND ").append(x.getDataeaseName()); + } + filter.append(transMysqlFilterTerm(f.getTerm())); + if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) { + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')"); + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + filter.append("%").append(f.getValue()).append("%"); + } else { + filter.append("'").append(f.getValue()).append("'"); + } + return filter.toString(); + }).toArray(String[]::new); + return StringUtils.join(s, " "); + }).toArray(String[]::new); + + String sql = MessageFormat.format("SELECT {0},{1} FROM {2} WHERE 1=1 {3} GROUP BY {4} ORDER BY null,{5}", + StringUtils.join(groupField, ","), + StringUtils.join(field, ","), + table, + xFilter.length > 0 ? StringUtils.join(xFilter, " ") : "" + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter + StringUtils.join(group, ","), + StringUtils.join(order, ",")); + if (sql.endsWith(",")) { + sql = sql.substring(0, sql.length() - 1); + } + // 如果是对结果字段过滤,则再包裹一层sql + String[] resultFilter = yAxis.stream().filter(y -> CollectionUtils.isNotEmpty(y.getFilter()) && y.getFilter().size() > 0) + .map(y -> { + String[] s = y.getFilter().stream().map(f -> { + StringBuilder filter = new StringBuilder(); + // 原始类型不是时间,在de中被转成时间的字段做处理 + if (y.getDeType() == 1 && y.getDeExtractType() != 1) { + filter.append(" AND FROM_UNIXTIME(cast(_") + .append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()) + .append(" AS decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') "); + } else { + filter.append(" AND _").append(y.getSummary()).append("_").append(StringUtils.equalsIgnoreCase(y.getDataeaseName(), "*") ? "" : y.getDataeaseName()); + } + filter.append(transMysqlFilterTerm(f.getTerm())); + if (StringUtils.containsIgnoreCase(f.getTerm(), "null")) { + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "in")) { + filter.append("('").append(StringUtils.join(f.getValue(), "','")).append("')"); + } else if (StringUtils.containsIgnoreCase(f.getTerm(), "like")) { + filter.append("%").append(f.getValue()).append("%"); + } else { + filter.append("'").append(f.getValue()).append("'"); } return filter.toString(); }).toArray(String[]::new); diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index 0f1280528d..02cbd816bc 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -516,8 +516,9 @@ public class DataSetTableService { datasetTableField.setDeType(transFieldType(filed.getFieldType())); datasetTableField.setDeExtractType(transFieldType(filed.getFieldType())); } else { - datasetTableField.setDeType(transFieldType(ds.getType(), filed.getFieldType())); - datasetTableField.setDeExtractType(transFieldType(ds.getType(), filed.getFieldType())); + Integer fieldType = transFieldType(ds.getType(), filed.getFieldType()); + datasetTableField.setDeType(fieldType == 4 ? 2 : fieldType); + datasetTableField.setDeExtractType(fieldType); } datasetTableField.setSize(filed.getFieldSize()); datasetTableField.setChecked(true); @@ -555,10 +556,19 @@ public class DataSetTableService { public String createQuerySQL(String type, String table, List fields) { String[] array = fields.stream().map(f -> { StringBuilder stringBuilder = new StringBuilder(); - if (f.getDeType() == 1) { - stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getDataeaseName()); + // 如果原始类型为时间 + if (f.getDeExtractType() == 1) { + if (f.getDeType() == 2 || f.getDeType() == 3) { + stringBuilder.append("unix_timestamp(").append(f.getDataeaseName()).append(")*1000 as ").append(f.getDataeaseName()); + } else { + stringBuilder.append(f.getDataeaseName()); + } } else { - stringBuilder.append(f.getDataeaseName()); + if (f.getDeType() == 1) { + stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getDataeaseName()); + } else { + stringBuilder.append(f.getDataeaseName()); + } } return stringBuilder.toString(); }).toArray(String[]::new); diff --git a/backend/src/main/java/io/dataease/service/sys/SysUserService.java b/backend/src/main/java/io/dataease/service/sys/SysUserService.java index 096eb96511..9f6e448efc 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -1,5 +1,6 @@ package io.dataease.service.sys; +import io.dataease.auth.api.dto.CurrentUserDto; import io.dataease.base.domain.SysUser; import io.dataease.base.domain.SysUserExample; import io.dataease.base.domain.SysUsersRolesExample; @@ -9,6 +10,7 @@ import io.dataease.base.mapper.SysUsersRolesMapper; import io.dataease.base.mapper.ext.ExtSysUserMapper; import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.commons.constants.AuthConstants; +import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.CodingUtil; import io.dataease.controller.sys.base.BaseGridRequest; @@ -89,6 +91,22 @@ public class SysUserService { deleteUserRoles(user.getUserId());//先删除用户角色关联 saveUserRoles(user.getUserId(), request.getRoleIds());//再插入角色关联 return sysUserMapper.updateByPrimaryKey(user); + + } + + /** + * 用户修改个人信息 + * @param request + * @return + */ + @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId") + @Transactional + public int updatePersonInfo(SysUserCreateRequest request){ + SysUser user = BeanUtils.copyBean(new SysUser(), request); + long now = System.currentTimeMillis(); + user.setUpdateTime(now); + return sysUserMapper.updateByPrimaryKeySelective(user); + } @@ -107,20 +125,16 @@ public class SysUserService { */ @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId") public int updatePwd(SysUserPwdRequest request) { - if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){ - throw new RuntimeException("两次密码不一致"); - } - SysUser temp = new SysUser(); - temp.setUserId(request.getUserId()); - SysUser user = findOne(temp); + CurrentUserDto user = AuthUtils.getUser(); + if (ObjectUtils.isEmpty(user)) { throw new RuntimeException("用户不存在"); } - if (!StringUtils.equals(request.getPassword(), user.getPassword())){ + if (!StringUtils.equals(CodingUtil.md5(request.getPassword()), user.getPassword())){ throw new RuntimeException("密码错误"); } SysUser sysUser = new SysUser(); - sysUser.setUserId(request.getUserId()); + sysUser.setUserId(user.getUserId()); sysUser.setPassword(CodingUtil.md5(request.getNewPassword())); return sysUserMapper.updateByPrimaryKeySelective(sysUser); } diff --git a/backend/src/main/resources/db/migration/V8__system.sql b/backend/src/main/resources/db/migration/V8__system.sql index b2ca5d69a9..2645f831bb 100644 --- a/backend/src/main/resources/db/migration/V8__system.sql +++ b/backend/src/main/resources/db/migration/V8__system.sql @@ -99,6 +99,8 @@ INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', '角色表单', 'sys INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', '数据源表单', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', '模板管理', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620444227389); INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', '权限管理', 'system/permission/index', 14, 'password', 'system/permission/index', b'0', b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620447312657); +INSERT INTO `sys_menu` VALUES (50, 0, 0, 1, '个人信息', '个人信息', 'system/user/privateForm', 999, NULL, '/person-info', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); +INSERT INTO `sys_menu` VALUES (51, 0, 0, 1, '重置密码', '重置密码', 'system/user/personPwd', 999, NULL, '/person-pwd', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); COMMIT; SET FOREIGN_KEY_CHECKS = 1; diff --git a/frontend/src/api/system/user.js b/frontend/src/api/system/user.js index 228fc1152f..fc23d2b260 100644 --- a/frontend/src/api/system/user.js +++ b/frontend/src/api/system/user.js @@ -1,5 +1,8 @@ import request from '@/utils/request' const pathMap = { + userUpdatePwdPath: '/api/user/updatePwd/', + personInfoPath: '/api/user/personInfo/', + piupdatePath: '/api/user/updatePersonInfo/', queryPath: '/api/user/userGrid/', deletePath: '/api/user/delete/', createPath: '/api/user/create', @@ -55,4 +58,27 @@ export const editStatus = (data) => { }) } -export default { editPassword, delUser, editUser, addUser, userLists, editStatus } +export const persionInfo = () => { + return request({ + url: pathMap.personInfoPath, + method: 'post' + }) +} + +export const updatePerson = (data) => { + return request({ + url: pathMap.piupdatePath, + method: 'post', + data + }) +} + +export const updatePersonPwd = (data) => { + return request({ + url: pathMap.userUpdatePwdPath, + method: 'post', + data + }) +} + +export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd } diff --git a/frontend/src/icons/svg/gauge.svg b/frontend/src/icons/svg/gauge.svg new file mode 100644 index 0000000000..c21c854d1b --- /dev/null +++ b/frontend/src/icons/svg/gauge.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/scatter.svg b/frontend/src/icons/svg/scatter.svg new file mode 100644 index 0000000000..a07462aac1 --- /dev/null +++ b/frontend/src/icons/svg/scatter.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/icons/svg/text.svg b/frontend/src/icons/svg/text.svg new file mode 100644 index 0000000000..178eb0bf2c --- /dev/null +++ b/frontend/src/icons/svg/text.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index f1b64aa19d..5a78e62623 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -395,7 +395,7 @@ export default { special_characters_are_not_supported: '不支持特殊字符', mobile_number_format_is_incorrect: '手机号码格式不正确', email_format_is_incorrect: '邮箱格式不正确', - password_format_is_incorrect: '有效密码:8-30位,英文大小写字母+数字+特殊字符(可选)', + password_format_is_incorrect: '有效密码:6-30位,英文大小写字母+数字+特殊字符(可选)', old_password: '旧密码', new_password: '新密码', repeat_password: '确认密码', @@ -640,7 +640,20 @@ export default { table_header_bg: '表头背景', table_item_bg: '表格背景', table_item_font_color: '字体颜色', - stripe: '斑马纹' + stripe: '斑马纹', + start_angle: '起始角度', + end_angle: '结束角度', + style_priority: '样式优先级', + dashboard: '仪表盘', + dimension_color: '维度颜色', + quota_color: '指标颜色', + dimension_font_size: '维度字体大小', + quota_font_size: '指标字体大小', + space_split: '维度/指标间隔', + only_one_quota: '仅支持1个指标', + only_one_result: '仅显示第1个计算结果', + dimension_show: '维度显示', + quota_show: '指标显示' }, dataset: { datalist: '数据集', diff --git a/frontend/src/layout/components/Topbar.vue b/frontend/src/layout/components/Topbar.vue index edd91a3092..07ea10fd2b 100644 --- a/frontend/src/layout/components/Topbar.vue +++ b/frontend/src/layout/components/Topbar.vue @@ -37,9 +37,46 @@ - + + + + {{ name }} + + + + + 个人信息 + + + 重置密码 + + + + Docs + + + + 关于 + + + 退出 + + + + + @@ -113,7 +150,8 @@ export default { }, ...mapGetters([ 'avatar', - 'permission_routes' + 'permission_routes', + 'name' ]) }, @@ -222,5 +260,21 @@ export default { } diff --git a/frontend/src/styles/topbar.scss b/frontend/src/styles/topbar.scss index ec107d7126..7ec0df9ab1 100644 --- a/frontend/src/styles/topbar.scss +++ b/frontend/src/styles/topbar.scss @@ -87,6 +87,14 @@ height: 40px; border-radius: 10px; } + .de-user-avatar { + cursor: pointer; + height: 40px; + border-radius: 10px; + span { + color: #ffffff; + } + } .el-icon-caret-bottom { cursor: pointer; diff --git a/frontend/src/views/chart/chart/chart.js b/frontend/src/views/chart/chart/chart.js index a9efd53629..819d0c471c 100644 --- a/frontend/src/views/chart/chart/chart.js +++ b/frontend/src/views/chart/chart/chart.js @@ -5,7 +5,9 @@ export const DEFAULT_COLOR_CASE = { tableHeaderBgColor: '#4e81bb', tableItemBgColor: '#c6d9f0', tableFontColor: '#000000', - tableStripe: true + tableStripe: true, + dimensionColor: '#000000', + quotaColor: '#000000' } export const DEFAULT_SIZE = { barDefault: true, @@ -24,14 +26,24 @@ export const DEFAULT_SIZE = { funnelWidth: 80, radarShape: 'polygon', tableTitleFontSize: 12, - tableItemFontSize: 12 + tableItemFontSize: 12, + gaugeMin: 0, + gaugeMax: 100, + gaugeStartAngle: 225, + gaugeEndAngle: -45, + dimensionFontSize: 18, + quotaFontSize: 18, + spaceSplit: 10, + dimensionShow: true, + quotaShow: true } export const DEFAULT_LABEL = { show: false, position: 'top', color: '#909399', fontSize: '10', - formatter: '{c}' + formatter: '{c}', + gaugeFormatter: '{value}' } export const DEFAULT_TOOLTIP = { show: true, @@ -297,3 +309,39 @@ export const BASE_RADAR = { data: [] }] } + +export const BASE_GAUGE = { + title: { + text: '' + }, + // grid: { + // containLabel: true + // }, + tooltip: {}, + legend: { + show: true, + type: 'scroll', + itemWidth: 10, + itemHeight: 10, + icon: 'rect' + }, + series: [ + { + name: '', + type: 'gauge', + startAngle: 225, + endAngle: -45, + min: 0, + max: 100, + progress: { + show: true + }, + detail: { + show: true, + valueAnimation: true, + formatter: '{value}' + }, + data: [] + } + ] +} diff --git a/frontend/src/views/chart/chart/gauge/gauge.js b/frontend/src/views/chart/chart/gauge/gauge.js new file mode 100644 index 0000000000..325288ec1e --- /dev/null +++ b/frontend/src/views/chart/chart/gauge/gauge.js @@ -0,0 +1,56 @@ +import { componentStyle } from '../common/common' +import { hexColorToRGBA } from '@/views/chart/chart/util' + +export function baseGaugeOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + tooltip.formatter = tooltip.formatter.replace(reg, '
') + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + if (chart.data.series.length > 0) { + chart_option.series[0].name = chart.data.series[0].name + // size + if (customAttr.size) { + chart_option.series[0].min = customAttr.size.gaugeMin + chart_option.series[0].max = customAttr.size.gaugeMax + chart_option.series[0].startAngle = customAttr.size.gaugeStartAngle + chart_option.series[0].endAngle = customAttr.size.gaugeEndAngle + } + // detail + if (customAttr.label) { + const label = JSON.parse(JSON.stringify(customAttr.label)) + chart_option.series[0].detail.show = label.show + chart_option.series[0].detail.fontSize = label.fontSize + chart_option.series[0].detail.color = label.color + chart_option.series[0].detail.formatter = label.gaugeFormatter + } + chart_option.series[0].type = 'gauge' + // color + chart_option.series[0].itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[0], customAttr.color.alpha) + } + // data只取第一个 + const y = { + name: chart.data.x[0], + value: chart.data.series[0].data[0] + } + chart_option.series[0].data.push(y) + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} diff --git a/frontend/src/views/chart/chart/line/line.js b/frontend/src/views/chart/chart/line/line.js index ff1bce7272..ec7d326199 100644 --- a/frontend/src/views/chart/chart/line/line.js +++ b/frontend/src/views/chart/chart/line/line.js @@ -36,7 +36,9 @@ export function baseLineOption(chart_option, chart) { type: customAttr.size.lineType } y.smooth = customAttr.size.lineSmooth - customAttr.size.lineArea ? y.areaStyle = { opacity: 0.6 } : { opacity: 0 } + y.areaStyle = { + opacity: customAttr.size.lineArea ? 0.6 : 0 + } } // label if (customAttr.label) { diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index f4d98672ed..50eb574f26 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -5,12 +5,13 @@ + + diff --git a/frontend/src/views/chart/components/shape-attr/ColorSelector.vue b/frontend/src/views/chart/components/shape-attr/ColorSelector.vue index ba29343078..33417a2d64 100644 --- a/frontend/src/views/chart/components/shape-attr/ColorSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/ColorSelector.vue @@ -9,7 +9,7 @@
- +
@@ -19,6 +19,13 @@ + + + + + + +
@@ -35,7 +42,7 @@
- + diff --git a/frontend/src/views/chart/components/shape-attr/LabelSelector.vue b/frontend/src/views/chart/components/shape-attr/LabelSelector.vue index 1c7b8bafde..e9289037dc 100644 --- a/frontend/src/views/chart/components/shape-attr/LabelSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/LabelSelector.vue @@ -7,7 +7,7 @@ trigger="click" > - + {{ $t('chart.show') }} @@ -43,6 +43,28 @@ + + + + {{ $t('chart.show') }} + + + + + + + + + + + + + {{ $t('chart.content_formatter') }} + + + + + {{ $t('chart.label') }} diff --git a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue index b14f014e00..2b7a2df6b4 100644 --- a/frontend/src/views/chart/components/shape-attr/SizeSelector.vue +++ b/frontend/src/views/chart/components/shape-attr/SizeSelector.vue @@ -98,6 +98,43 @@
+ + + + + + + + + + + + + + + + + + + {{ $t('chart.show') }} + + + + + + + + {{ $t('chart.show') }} + + + + + + + + + + {{ $t('chart.size') }} diff --git a/frontend/src/views/chart/components/table/TableNormal.vue b/frontend/src/views/chart/components/table/TableNormal.vue index 924f8ce7f3..cebae77206 100644 --- a/frontend/src/views/chart/components/table/TableNormal.vue +++ b/frontend/src/views/chart/components/table/TableNormal.vue @@ -1,5 +1,5 @@