diff --git a/backend/src/main/java/io/dataease/auth/api/AuthApi.java b/backend/src/main/java/io/dataease/auth/api/AuthApi.java index c4d6230f8c..e4b2df95b5 100644 --- a/backend/src/main/java/io/dataease/auth/api/AuthApi.java +++ b/backend/src/main/java/io/dataease/auth/api/AuthApi.java @@ -72,8 +72,8 @@ public interface AuthApi { boolean isOpenDingtalk(); @ApiOperation("是否开启飞书") - @PostMapping("/isOpenFark") - boolean isOpenFark(); + @PostMapping("/isOpenLark") + boolean isOpenLark(); @ApiIgnore @PostMapping("/isPluginLoaded") 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 bd7334851b..046015a14f 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -305,12 +305,12 @@ public class AuthServer implements AuthApi { } @Override - public boolean isOpenFark() { + public boolean isOpenLark() { Boolean licValid = PluginUtils.licValid(); if (!licValid) return false; - return authUserService.supportFark(); + return authUserService.supportLark(); } @Override diff --git a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java index 483bab6553..d6a885b960 100644 --- a/backend/src/main/java/io/dataease/auth/service/AuthUserService.java +++ b/backend/src/main/java/io/dataease/auth/service/AuthUserService.java @@ -36,7 +36,7 @@ public interface AuthUserService { Boolean supportDingtalk(); - Boolean supportFark(); + Boolean supportLark(); Boolean pluginLoaded(); 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 9fdb6c807c..825dd7ff03 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 @@ -16,6 +16,7 @@ import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.util.PluginUtils; import io.dataease.plugins.xpack.cas.service.CasXpackService; import io.dataease.plugins.xpack.dingtalk.service.DingtalkXpackService; +import io.dataease.plugins.xpack.lark.service.LarkXpackService; import io.dataease.plugins.xpack.ldap.service.LdapXpackService; import io.dataease.plugins.xpack.oidc.service.OidcXpackService; @@ -187,8 +188,12 @@ public class AuthUserServiceImpl implements AuthUserService { } @Override - public Boolean supportFark() { - return false; + public Boolean supportLark() { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LarkXpackService.class)); + if (beansOfType.keySet().size() == 0) return false; + LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + if (ObjectUtils.isEmpty(larkXpackService)) return false; + return larkXpackService.isOpen(); } @Override diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java index 5cf3f896ba..4df99ceb75 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java @@ -83,7 +83,7 @@ public class ShiroServiceImpl implements ShiroService { filterChainDefinitionMap.put("/api/auth/isOpenOidc", ANON); filterChainDefinitionMap.put("/api/auth/isOpenWecom", ANON); filterChainDefinitionMap.put("/api/auth/isOpenDingtalk", ANON); - filterChainDefinitionMap.put("/api/auth/isOpenFark", ANON); + filterChainDefinitionMap.put("/api/auth/isOpenLark", ANON); filterChainDefinitionMap.put("/api/auth/getPublicKey", ANON); filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON); filterChainDefinitionMap.put("/api/pluginCommon/staticInfo/**", ANON); @@ -94,8 +94,8 @@ public class ShiroServiceImpl implements ShiroService { filterChainDefinitionMap.put("/plugin/wecom/getQrParam", ANON); filterChainDefinitionMap.put("/plugin/dingtalk/callBack*", ANON); filterChainDefinitionMap.put("/plugin/dingtalk/getQrParam", ANON); - filterChainDefinitionMap.put("/plugin/fark/callBack*", ANON); - filterChainDefinitionMap.put("/plugin/fark/getQrParam", ANON); + filterChainDefinitionMap.put("/plugin/lark/callBack*", ANON); + filterChainDefinitionMap.put("/plugin/lark/getQrParam", ANON); filterChainDefinitionMap.put("/cas/reset/**", ANON); filterChainDefinitionMap.put("/unauth", ANON); diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java index d10bff43ad..b01b6bea37 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java @@ -11,10 +11,10 @@ import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.response.DataSetDetail; import io.dataease.dto.dataset.DataSetTableDTO; import io.dataease.dto.dataset.ExcelFileData; -import io.dataease.dto.dataset.SqlVariableDetails; import io.dataease.plugins.common.base.domain.DatasetTable; import io.dataease.plugins.common.base.domain.DatasetTableField; import io.dataease.plugins.common.base.domain.DatasetTableIncrementalConfig; +import io.dataease.plugins.common.dto.dataset.SqlVariableDetails; import io.dataease.plugins.common.dto.datasource.TableField; import io.dataease.service.dataset.DataSetTableService; import io.swagger.annotations.*; @@ -211,8 +211,8 @@ public class DataSetTableController { } @ApiOperation("根据仪表板视图ID查询数据集变量") - @PostMapping("/paramsWithIds") - List paramsWithIds(@RequestBody List viewIds){ - return dataSetTableService.paramsWithIds(viewIds); + @PostMapping("/paramsWithIds/{type}") + List paramsWithIds(@PathVariable String type, @RequestBody List viewIds){ + return dataSetTableService.paramsWithIds(type, viewIds); }; } diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartSeniorAssistDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartSeniorAssistDTO.java new file mode 100644 index 0000000000..20b362e863 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/chart/ChartSeniorAssistDTO.java @@ -0,0 +1,20 @@ +package io.dataease.dto.chart; + +import io.dataease.plugins.common.base.domain.DatasetTableField; +import lombok.Data; + +/** + * @Author Junjun + */ +@Data +public class ChartSeniorAssistDTO { + private String name; + private String field; + private String fieldId; + private String summary; + private String axis; + private String value; + private String lineType; + private String color; + private DatasetTableField curField; +} diff --git a/backend/src/main/java/io/dataease/dto/dataset/SqlVariableDetails.java b/backend/src/main/java/io/dataease/dto/dataset/SqlVariableDetails.java deleted file mode 100644 index 93a2301ef0..0000000000 --- a/backend/src/main/java/io/dataease/dto/dataset/SqlVariableDetails.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.dataease.dto.dataset; - -import lombok.Data; - -import java.util.List; - -@Data -public class SqlVariableDetails { - private String variableName; - private String alias; - private List type; - private String details; - private String defaultValue; - -} diff --git a/backend/src/main/java/io/dataease/plugins/server/XDingtalkServer.java b/backend/src/main/java/io/dataease/plugins/server/XDingtalkServer.java index cc5603e1b0..baa5927cf9 100644 --- a/backend/src/main/java/io/dataease/plugins/server/XDingtalkServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/XDingtalkServer.java @@ -88,7 +88,7 @@ public class XDingtalkServer { DEException.throwException("未开启钉钉"); } DingUserEntity dingUserEntity = dingtalkXpackService.userInfo(code); - String username = dingUserEntity.getUserId(); + String username = dingUserEntity.getUserid(); String unionid = dingUserEntity.getUnionid(); SysUserEntity sysUserEntity = authUserService.getUserBySub(unionid, 5); if (null == sysUserEntity) { diff --git a/backend/src/main/java/io/dataease/plugins/server/XLarkServer.java b/backend/src/main/java/io/dataease/plugins/server/XLarkServer.java new file mode 100644 index 0000000000..c6ce08472d --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/server/XLarkServer.java @@ -0,0 +1,134 @@ +package io.dataease.plugins.server; + +import io.dataease.auth.entity.SysUserEntity; +import io.dataease.auth.entity.TokenInfo; +import io.dataease.auth.service.AuthUserService; +import io.dataease.auth.util.JWTUtils; +import io.dataease.commons.constants.SysLogConstants; +import io.dataease.commons.exception.DEException; +import io.dataease.commons.utils.DeLogUtils; +import io.dataease.commons.utils.LogUtil; +import io.dataease.commons.utils.ServletUtils; +import io.dataease.plugins.config.SpringContextUtil; + +import io.dataease.plugins.xpack.display.dto.response.SysSettingDto; +import io.dataease.plugins.xpack.lark.dto.entity.LarkQrResult; +import io.dataease.plugins.xpack.lark.dto.entity.LarkUserInfo; +import io.dataease.plugins.xpack.lark.dto.response.LarkInfo; +import io.dataease.plugins.xpack.lark.service.LarkXpackService; +import io.dataease.service.sys.SysUserService; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import springfox.documentation.annotations.ApiIgnore; + +import javax.annotation.Resource; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +@ApiIgnore +@RequestMapping("/plugin/lark") +@Controller +public class XLarkServer { + + + @Resource + private AuthUserService authUserService; + @Resource + private SysUserService sysUserService; + + @ResponseBody + @GetMapping("/info") + public LarkInfo getLarkInfo() { + LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + return larkXpackService.info(); + } + + @ResponseBody + @RequiresPermissions("sysparam:read") + @PostMapping("/save") + public void save(@RequestBody List settings) { + LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + larkXpackService.save(settings); + } + + @ResponseBody + @PostMapping("/testConn") + public void testConn(@RequestBody LarkInfo larkInfo) { + LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + try { + larkXpackService.testConn(larkInfo); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @ResponseBody + @PostMapping("/getQrParam") + public LarkQrResult getQrParam() { + LarkXpackService larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + return larkXpackService.getQrParam(); + } + + @GetMapping("/callBack") + public ModelAndView callBack(@RequestParam("code") String code, @RequestParam("state") String state) { + ModelAndView modelAndView = new ModelAndView("redirect:/"); + HttpServletResponse response = ServletUtils.response(); + LarkXpackService larkXpackService = null; + try { + Map beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((LarkXpackService.class)); + if (beansOfType.keySet().size() == 0) { + DEException.throwException("缺少飞书插件"); + } + larkXpackService = SpringContextUtil.getBean(LarkXpackService.class); + Boolean isOpen = larkXpackService.isOpen(); + if (!isOpen) { + DEException.throwException("未开启飞书"); + } + LarkUserInfo larkUserInfo = larkXpackService.userInfo(code, state); + String username = larkUserInfo.getUser_id(); + String sub = larkUserInfo.getSub(); + SysUserEntity sysUserEntity = authUserService.getUserBySub(sub, 6); + if (null == sysUserEntity) { + String email = StringUtils.isNotBlank(larkUserInfo.getEmail()) ? larkUserInfo.getEmail() : "demo@lark.work"; + sysUserService.validateExistUser(username, larkUserInfo.getName(), email); + sysUserService.saveLarkCUser(larkUserInfo, email); + sysUserEntity = authUserService.getUserBySub(sub, 6); + } + TokenInfo tokenInfo = TokenInfo.builder().userId(sysUserEntity.getUserId()).username(sysUserEntity.getUsername()).build(); + String realPwd = sysUserEntity.getPassword(); + String token = JWTUtils.sign(tokenInfo, realPwd); + ServletUtils.setToken(token); + + DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, sysUserEntity.getUserId(), null, null, null); + + Cookie cookie_token = new Cookie("Authorization", token); + cookie_token.setPath("/"); + + response.addCookie(cookie_token); + } catch (Exception e) { + + String msg = e.getMessage(); + if (null != e.getCause()) { + msg = e.getCause().getMessage(); + } + try { + msg = URLEncoder.encode(msg, "UTF-8"); + LogUtil.error(e); + Cookie cookie_error = new Cookie("LarkError", msg); + cookie_error.setPath("/"); + + return modelAndView; + } catch (UnsupportedEncodingException e1) { + e.printStackTrace(); + } + } + return modelAndView; + } +} 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 0e162ff399..4516b139c0 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -1,6 +1,7 @@ package io.dataease.service.chart; import cn.hutool.core.lang.Assert; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -16,14 +17,10 @@ import io.dataease.commons.utils.LogUtil; import io.dataease.controller.request.chart.*; import io.dataease.controller.response.ChartDetail; import io.dataease.controller.response.DataSetDetail; -import io.dataease.dto.chart.ChartDimensionDTO; -import io.dataease.dto.chart.ChartGroupDTO; -import io.dataease.dto.chart.ChartViewDTO; -import io.dataease.dto.chart.ViewOption; +import io.dataease.dto.chart.*; import io.dataease.dto.dataset.DataSetTableDTO; import io.dataease.dto.dataset.DataSetTableUnionDTO; import io.dataease.dto.dataset.DataTableInfoDTO; -import io.dataease.dto.dataset.SqlVariableDetails; import io.dataease.exception.DataEaseException; import io.dataease.ext.ExtChartGroupMapper; import io.dataease.ext.ExtChartViewMapper; @@ -33,11 +30,13 @@ import io.dataease.listener.util.CacheUtils; import io.dataease.plugins.common.base.domain.*; import io.dataease.plugins.common.base.mapper.ChartViewCacheMapper; import io.dataease.plugins.common.base.mapper.ChartViewMapper; +import io.dataease.plugins.common.base.mapper.DatasetTableFieldMapper; import io.dataease.plugins.common.base.mapper.PanelViewMapper; import io.dataease.plugins.common.constants.DatasetType; import io.dataease.plugins.common.dto.chart.ChartFieldCompareDTO; import io.dataease.plugins.common.dto.chart.ChartFieldCustomFilterDTO; import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO; +import io.dataease.plugins.common.dto.dataset.SqlVariableDetails; import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; import io.dataease.plugins.common.request.datasource.DatasourceRequest; import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; @@ -112,6 +111,8 @@ public class ChartViewService { private ChartViewFieldService chartViewFieldService; @Resource private PermissionsTreeService permissionsTreeService; + @Resource + private DatasetTableFieldMapper datasetTableFieldMapper; //默认使用非公平 @@ -459,7 +460,7 @@ public class ChartViewService { } } else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.SQL.name())) { String sql = dataTableInfoDTO.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())) : dataTableInfoDTO.getSql(); - sql = handleVariable(sql, requestList, qp); + sql = handleVariable(sql, requestList, qp, table); if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(sql, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { @@ -658,8 +659,7 @@ public class ChartViewService { } boolean hasParameters = false; if (StringUtils.isNotEmpty(table.getSqlVariableDetails())) { - List sqlVariables = new Gson().fromJson(table.getSqlVariableDetails(), new TypeToken>() { - }.getType()); + List sqlVariables = new Gson().fromJson(table.getSqlVariableDetails(), new TypeToken>() {}.getType()); for (String parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) { if (sqlVariables.stream().map(SqlVariableDetails::getVariableName).collect(Collectors.toList()).contains(parameter)) { hasParameters = true; @@ -804,6 +804,20 @@ public class ChartViewService { Provider datasourceProvider = ProviderFactory.getProvider(ds.getType()); List data = new ArrayList<>(); + // senior dynamic assist + DatasourceRequest datasourceAssistRequest = new DatasourceRequest(); + datasourceAssistRequest.setDatasource(ds); + List assistData = new ArrayList<>(); + List dynamicAssistFields = getDynamicAssistFields(view); + List assistFields = null; + if (StringUtils.containsIgnoreCase(view.getType(), "bar") + || StringUtils.containsIgnoreCase(view.getType(), "line") + || StringUtils.containsIgnoreCase(view.getType(), "area") + || StringUtils.containsIgnoreCase(view.getType(), "scatter") + || StringUtils.containsIgnoreCase(view.getType(), "mix") + ) { + assistFields = getAssistFields(dynamicAssistFields); + } // 如果是插件视图 走插件内部的逻辑 if (ObjectUtils.isNotEmpty(view.getIsPlugin()) && view.getIsPlugin()) { @@ -824,7 +838,7 @@ public class ChartViewService { Map mapChart = pluginViewResult(pluginViewParam, view, data, isDrill); Map mapTableNormal = ChartDataBuild.transTableNormal(fieldMap, view, data, desensitizationList); - return uniteViewResult(datasourceRequest.getQuery(), mapChart, mapTableNormal, view, isDrill, drillFilters); + return uniteViewResult(datasourceRequest.getQuery(), mapChart, mapTableNormal, view, isDrill, drillFilters, dynamicAssistFields, assistData); // 如果是插件到此结束 } @@ -852,9 +866,12 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQL(dataTableInfoDTO.getTable(), xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view)); } + if (CollectionUtils.isNotEmpty(assistFields)) { + datasourceAssistRequest.setQuery(qp.getSQLSummary(dataTableInfoDTO.getTable(), assistFields, null, null, null, view, ds)); + } } else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.SQL.name())) { String sql = dataTableInfoDTO.isBase64Encryption() ? new String(java.util.Base64.getDecoder().decode(dataTableInfoDTO.getSql())) : dataTableInfoDTO.getSql(); - sql = handleVariable(sql, requestList, qp); + sql = handleVariable(sql, requestList, qp, table); if (StringUtils.equalsIgnoreCase("text", view.getType()) || StringUtils.equalsIgnoreCase("gauge", view.getType()) || StringUtils.equalsIgnoreCase("liquid", view.getType())) { datasourceRequest.setQuery(qp.getSQLSummaryAsTmp(sql, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); } else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) { @@ -866,6 +883,9 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); } + if (CollectionUtils.isNotEmpty(assistFields)) { + datasourceAssistRequest.setQuery(qp.getSQLSummaryAsTmp(sql, assistFields, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); + } } else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.CUSTOM.name())) { DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class); List list = dataSetTableUnionService.listByTableId(dt.getList().get(0).getTableId()); @@ -881,6 +901,9 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); } + if (CollectionUtils.isNotEmpty(assistFields)) { + datasourceAssistRequest.setQuery(qp.getSQLSummaryAsTmp(sql, assistFields, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); + } } else if (StringUtils.equalsIgnoreCase(table.getType(), DatasetType.UNION.name())) { DataTableInfoDTO dt = gson.fromJson(table.getInfo(), DataTableInfoDTO.class); Map sqlMap = dataSetTableService.getUnionSQLDatasource(dt, ds); @@ -897,8 +920,14 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQLAsTmp(sql, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); } + if (CollectionUtils.isNotEmpty(assistFields)) { + datasourceAssistRequest.setQuery(qp.getSQLSummaryAsTmp(sql, assistFields, fieldCustomFilter, rowPermissionsTree, extFilterList, view)); + } } data = datasourceProvider.getData(datasourceRequest); + if (CollectionUtils.isNotEmpty(assistFields)) { + assistData = datasourceProvider.getData(datasourceAssistRequest); + } } else if (table.getMode() == 1) {// 抽取 // 连接doris,构建doris数据源查询 datasourceRequest.setDatasource(ds); @@ -916,6 +945,10 @@ public class ChartViewService { } else { datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, fieldCustomFilter, rowPermissionsTree, extFilterList, ds, view)); } + if (CollectionUtils.isNotEmpty(assistFields)) { + datasourceAssistRequest.setQuery(qp.getSQLSummary(tableName, assistFields, fieldCustomFilter, rowPermissionsTree, extFilterList, view, ds)); + assistData = datasourceProvider.getData(datasourceAssistRequest); + } // 仪表板有参数不使用缓存 if (!cache || CollectionUtils.isNotEmpty(requestList.getFilter()) || CollectionUtils.isNotEmpty(requestList.getLinkageFilters()) @@ -1065,7 +1098,7 @@ public class ChartViewService { } // table组件,明细表,也用于导出数据 Map mapTableNormal = ChartDataBuild.transTableNormal(xAxis, yAxis, view, data, extStack, desensitizationList); - return uniteViewResult(datasourceRequest.getQuery(), mapChart, mapTableNormal, view, isDrill, drillFilters); + return uniteViewResult(datasourceRequest.getQuery(), mapChart, mapTableNormal, view, isDrill, drillFilters, dynamicAssistFields, assistData); } // 对结果排序 @@ -1110,7 +1143,7 @@ public class ChartViewService { return res; } - public ChartViewDTO uniteViewResult(String sql, Map chartData, Map tabelData, ChartViewDTO view, Boolean isDrill, List drillFilters) { + public ChartViewDTO uniteViewResult(String sql, Map chartData, Map tabelData, ChartViewDTO view, Boolean isDrill, List drillFilters, List dynamicAssistFields, List assistData) { Map map = new HashMap<>(); map.putAll(chartData); @@ -1118,6 +1151,9 @@ public class ChartViewService { List sourceFields = dataSetTableFieldsService.getFieldsByTableId(view.getTableId()); map.put("sourceFields", sourceFields); + // merge assist result + mergeAssistField(dynamicAssistFields, assistData); + map.put("dynamicAssistLines", dynamicAssistFields); ChartViewDTO dto = new ChartViewDTO(); BeanUtils.copyBean(dto, view); @@ -1525,7 +1561,10 @@ public class ChartViewService { chartViewMapper.updateByPrimaryKeySelective(chartView); } - private String handleVariable(String sql, ChartExtRequest requestList, QueryProvider qp) throws Exception { + private String handleVariable(String sql, ChartExtRequest requestList, QueryProvider qp, DataSetTableDTO table) throws Exception { + + List sqlVariables = new Gson().fromJson(table.getSqlVariableDetails(), new TypeToken>() {}.getType()); + if (requestList != null && CollectionUtils.isNotEmpty(requestList.getFilter())) { for (ChartExtFilterRequest chartExtFilterRequest : requestList.getFilter()) { if (CollectionUtils.isEmpty(chartExtFilterRequest.getValue())) { @@ -1535,9 +1574,13 @@ public class ChartViewService { continue; } - String filter = qp.transFilter(chartExtFilterRequest); for (String parameter : chartExtFilterRequest.getParameters()) { - sql = sql.replace("${" + parameter + "}", filter); + List parameters = sqlVariables.stream().filter(item -> item.getVariableName().equalsIgnoreCase(parameter)).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(parameters)) { + String filter = qp.transFilter(chartExtFilterRequest,parameters.get(0)); + sql = sql.replace("${" + parameter + "}", filter); + } + } } } @@ -1610,4 +1653,56 @@ public class ChartViewService { } return list; } + + private List getDynamicAssistFields(ChartViewDTO view) { + String senior = view.getSenior(); + JSONObject jsonObject = JSONObject.parseObject(senior); + JSONArray assistLine = jsonObject.getJSONArray("assistLine"); + List assistLines = gson.fromJson(assistLine.toJSONString(), new TypeToken>() { + }.getType()); + + List list = new ArrayList<>(); + for (ChartSeniorAssistDTO dto : assistLines) { + if (StringUtils.equalsIgnoreCase(dto.getField(), "0")) { + continue; + } + String fieldId = dto.getFieldId(); + String summary = dto.getSummary(); + if (StringUtils.isEmpty(fieldId) || StringUtils.isEmpty(summary)) { + continue; + } + DatasetTableFieldExample datasetTableFieldExample = new DatasetTableFieldExample(); + datasetTableFieldExample.createCriteria().andTableIdEqualTo(view.getTableId()).andIdEqualTo(fieldId); + List fieldList = datasetTableFieldMapper.selectByExample(datasetTableFieldExample); + if (CollectionUtils.isEmpty(fieldList)) { + continue; + } + dto.setCurField(fieldList.get(0)); + list.add(dto); + } + return list; + } + + private List getAssistFields(List list) { + List res = new ArrayList<>(); + for (ChartSeniorAssistDTO dto : list) { + DatasetTableField curField = dto.getCurField(); + ChartViewFieldDTO chartViewFieldDTO = new ChartViewFieldDTO(); + BeanUtils.copyBean(chartViewFieldDTO, curField); + chartViewFieldDTO.setSummary(dto.getSummary()); + res.add(chartViewFieldDTO); + } + return res; + } + + private void mergeAssistField(List dynamicAssistFields, List assistData) { + if (CollectionUtils.isEmpty(assistData)) { + return; + } + String[] strings = assistData.get(0); + for (int i = 0; i < dynamicAssistFields.size(); i++) { + ChartSeniorAssistDTO chartSeniorAssistDTO = dynamicAssistFields.get(i); + chartSeniorAssistDTO.setValue(strings[i]); + } + } } 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 48c16ad86a..ebc68f3e43 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -31,6 +31,7 @@ import io.dataease.plugins.common.base.domain.*; import io.dataease.plugins.common.base.mapper.*; import io.dataease.plugins.common.constants.DatasetType; import io.dataease.plugins.common.constants.DatasourceTypes; +import io.dataease.plugins.common.dto.dataset.SqlVariableDetails; import io.dataease.plugins.common.dto.datasource.DataSourceType; import io.dataease.plugins.common.dto.datasource.TableField; import io.dataease.plugins.common.request.datasource.DatasourceRequest; @@ -930,10 +931,14 @@ public class DataSetTableService { return map; } - public List paramsWithIds(List viewIds) { + public List paramsWithIds(String type, List viewIds) { if (CollectionUtils.isEmpty(viewIds)) { return new ArrayList<>(); } + + if(!Arrays.asList("DATE", "TEXT", "NUM").contains(type)){ + return new ArrayList<>(); + } ChartViewExample chartViewExample = new ChartViewExample(); chartViewExample.createCriteria().andIdIn(viewIds); List datasetIds = chartViewMapper.selectByExample(chartViewExample).stream().map(ChartView::getTableId).collect(Collectors.toList()); @@ -946,11 +951,9 @@ public class DataSetTableService { if (CollectionUtils.isEmpty(datasetTables)) { return new ArrayList<>(); } - - List sqlVariableDetails = new ArrayList<>(); List sqlVariableNames = new ArrayList<>(); - datasetTables.forEach(datasetTable -> { + for (DatasetTable datasetTable : datasetTables) { if (StringUtils.isNotEmpty(datasetTable.getSqlVariableDetails())) { List sqlVariables = new Gson().fromJson(datasetTable.getSqlVariableDetails(), new TypeToken>() { }.getType()); @@ -961,7 +964,27 @@ public class DataSetTableService { } } } - }); + } + switch (type){ + case "DATE": + sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("DATETIME")).collect(Collectors.toList()); + sqlVariableDetails.forEach(item -> { + if(item.getType().size()> 1){ + item.setAlias(item.getVariableName() + "[" + item.getType().get(1) + "]"); + }else { + item.setAlias(item.getVariableName()); + } + }); + break; + case "TEXT": + sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("TEXT")).collect(Collectors.toList()); + sqlVariableDetails.forEach(item -> {item.setAlias(item.getVariableName());}); + break; + case "NUM": + sqlVariableDetails = sqlVariableDetails.stream().filter(item -> item.getType().get(0).contains("LONG") || item.getType().get(0).contains("DOUBLE")).collect(Collectors.toList()); + sqlVariableDetails.forEach(item -> {item.setAlias(item.getVariableName());}); + break; + } return sqlVariableDetails; } 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 a361c5b4b2..f9189d80f0 100644 --- a/backend/src/main/java/io/dataease/service/sys/SysUserService.java +++ b/backend/src/main/java/io/dataease/service/sys/SysUserService.java @@ -20,6 +20,7 @@ import io.dataease.plugins.common.base.mapper.SysUserMapper; import io.dataease.plugins.common.base.mapper.SysUsersRolesMapper; import io.dataease.plugins.common.entity.XpackLdapUserEntity; import io.dataease.plugins.xpack.dingtalk.dto.response.DingUserEntity; +import io.dataease.plugins.xpack.lark.dto.entity.LarkUserInfo; import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo; import org.apache.commons.collections4.CollectionUtils; @@ -147,13 +148,7 @@ public class SysUserService { sysUser.setIsAdmin(false); sysUser.setSub(userId); sysUserMapper.insert(sysUser); - SysUser dbUser = findOne(sysUser); - if (null != dbUser && null != dbUser.getUserId()) { - // 默认角色是普通员工 - List roleIds = new ArrayList(); - roleIds.add(2L); - saveUserRoles( dbUser.getUserId(), roleIds); - } + } @Transactional @@ -161,7 +156,7 @@ public class SysUserService { long now = System.currentTimeMillis(); SysUser sysUser = new SysUser(); - sysUser.setUsername(dingUserEntity.getUserId()); + sysUser.setUsername(dingUserEntity.getUserid()); sysUser.setNickName(dingUserEntity.getName()); sysUser.setEmail(email); sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); @@ -175,12 +170,29 @@ public class SysUserService { sysUser.setSub(dingUserEntity.getUnionid()); sysUser.setPhone(dingUserEntity.getMobile()); sysUserMapper.insert(sysUser); - SysUser dbUser = findOne(sysUser); - /*if (null != dbUser && null != dbUser.getUserId()) { - List roleIds = new ArrayList(); - roleIds.add(2L); - saveUserRoles( dbUser.getUserId(), roleIds); - }*/ + + } + + @Transactional + public void saveLarkCUser(LarkUserInfo larkUserInfo, String email) { + long now = System.currentTimeMillis(); + SysUser sysUser = new SysUser(); + + sysUser.setUsername(larkUserInfo.getUser_id()); + sysUser.setNickName(larkUserInfo.getName()); + sysUser.setEmail(email); + sysUser.setPassword(CodingUtil.md5(DEFAULT_PWD)); + sysUser.setCreateTime(now); + sysUser.setUpdateTime(now); + + sysUser.setEnabled(1L); + sysUser.setLanguage("zh_CN"); + sysUser.setFrom(6); + sysUser.setIsAdmin(false); + sysUser.setSub(larkUserInfo.getSub()); + sysUser.setPhone(larkUserInfo.getMobile()); + sysUserMapper.insert(sysUser); + } @Transactional 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 484c3cc94d..72412330b6 100644 --- a/backend/src/main/resources/db/migration/V40__1.15.sql +++ b/backend/src/main/resources/db/migration/V40__1.15.sql @@ -34,3 +34,5 @@ CREATE TABLE `panel_app_template` ( `create_user` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO `sys_menu` VALUES (800, 0, 0, 1, '数据集表单', 'dataset-form', 'dataset/form', 999, NULL, '/dataset-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); diff --git a/frontend/src/api/panel/view.js b/frontend/src/api/panel/view.js index e1c74e633c..2a03aa0823 100644 --- a/frontend/src/api/panel/view.js +++ b/frontend/src/api/panel/view.js @@ -17,9 +17,9 @@ export function viewsWithIds(data) { }) } -export function paramsWithIds(data) { +export function paramsWithIds(type, data) { return request({ - url: '/dataset/table/paramsWithIds', + url: '/dataset/table/paramsWithIds/' + type, method: 'post', loading: true, data diff --git a/frontend/src/api/user.js b/frontend/src/api/user.js index b8f1680b90..6899c6726d 100644 --- a/frontend/src/api/user.js +++ b/frontend/src/api/user.js @@ -114,9 +114,9 @@ export function dingtalkStatus() { }) } -export function farkStatus() { +export function larkStatus() { return request({ - url: '/api/auth/isOpenFark', + url: '/api/auth/isOpenLark', method: 'post' }) } diff --git a/frontend/src/assets/fark.png b/frontend/src/assets/lark.png similarity index 100% rename from frontend/src/assets/fark.png rename to frontend/src/assets/lark.png diff --git a/frontend/src/components/widget/serviceImpl/TimeDateServiceImpl.js b/frontend/src/components/widget/serviceImpl/TimeDateServiceImpl.js index bac5546a24..d9ce3365ad 100644 --- a/frontend/src/components/widget/serviceImpl/TimeDateServiceImpl.js +++ b/frontend/src/components/widget/serviceImpl/TimeDateServiceImpl.js @@ -17,6 +17,7 @@ const dialogPanel = { placeholder: 'dedate.placeholder', viewIds: [], fieldId: '', + parameters: [], dragItems: [], default: { isDynamic: false, diff --git a/frontend/src/components/widget/serviceImpl/TimeMonthServiceImpl.js b/frontend/src/components/widget/serviceImpl/TimeMonthServiceImpl.js index a8c3e195e0..c8defe995a 100644 --- a/frontend/src/components/widget/serviceImpl/TimeMonthServiceImpl.js +++ b/frontend/src/components/widget/serviceImpl/TimeMonthServiceImpl.js @@ -15,6 +15,7 @@ const dialogPanel = { placeholder: 'deyearmonth.placeholder', viewIds: [], fieldId: '', + parameters: [], dragItems: [], default: { isDynamic: false, diff --git a/frontend/src/components/widget/serviceImpl/TimeQuarterServiceImpl.js b/frontend/src/components/widget/serviceImpl/TimeQuarterServiceImpl.js index a3bcd9535d..89f0b4dfd0 100644 --- a/frontend/src/components/widget/serviceImpl/TimeQuarterServiceImpl.js +++ b/frontend/src/components/widget/serviceImpl/TimeQuarterServiceImpl.js @@ -13,6 +13,7 @@ const dialogPanel = { }, value: '' }, + parameters: [], defaultClass: 'time-filter', component: 'de-quarter' } diff --git a/frontend/src/components/widget/serviceImpl/TimeYearServiceImpl.js b/frontend/src/components/widget/serviceImpl/TimeYearServiceImpl.js index 1e4b50c2fa..54bbfac589 100644 --- a/frontend/src/components/widget/serviceImpl/TimeYearServiceImpl.js +++ b/frontend/src/components/widget/serviceImpl/TimeYearServiceImpl.js @@ -15,6 +15,7 @@ const dialogPanel = { placeholder: 'deyear.placeholder', viewIds: [], fieldId: '', + parameters: [], dragItems: [], default: { isDynamic: false, diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 58e78076af..22a63382fd 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1326,7 +1326,9 @@ export default { dynamic: 'Dynamic', gauge_size_field_delete: 'Dynamic field changed,please edit again', chart_group: 'Sub Type', - chart_bar_group: 'Bar Group' + chart_bar_group: 'Bar Group', + field_dynamic: 'Dynamic', + aggregation: 'Aggregation' }, dataset: { parse_filed: 'Parse Field', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index c086f2c762..cf0edff647 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1326,7 +1326,9 @@ export default { dynamic: '動態值', gauge_size_field_delete: '動態值中字段發生變更,請重新編輯', chart_group: '子類別', - chart_bar_group: '分組柱狀圖' + chart_bar_group: '分組柱狀圖', + field_dynamic: '動態值', + aggregation: '聚合方式' }, dataset: { parse_filed: '解析字段', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index f54236e6cc..82590b4080 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1326,7 +1326,9 @@ export default { dynamic: '动态值', gauge_size_field_delete: '动态值中字段发生变更,请重新编辑', chart_group: '子类别', - chart_bar_group: '分组柱状图' + chart_bar_group: '分组柱状图', + field_dynamic: '动态值', + aggregation: '聚合方式' }, dataset: { parse_filed: '解析字段', diff --git a/frontend/src/store/modules/permission.js b/frontend/src/store/modules/permission.js index b39b50c358..0b8a18edd3 100644 --- a/frontend/src/store/modules/permission.js +++ b/frontend/src/store/modules/permission.js @@ -29,7 +29,7 @@ const actions = { commit('SET_CURRENT_PATH', path) } } -export const fullScreenRouters = ['XpackThemeForm', 'system/datasource/DsForm'] +export const fullScreenRouters = ['XpackThemeForm', 'system/datasource/DsForm', 'dataset/form'] export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由字符串,转换为组件对象 return routers.map(router => { if (!fullScreenRouters.includes(router.component) && router.type === 1 && router.pid === 0 && router.component && router.component !== 'Layout') { diff --git a/frontend/src/views/chart/chart/table/table-info.js b/frontend/src/views/chart/chart/table/table-info.js index 39fdc804fd..ffa5ac370b 100644 --- a/frontend/src/views/chart/chart/table/table-info.js +++ b/frontend/src/views/chart/chart/table/table-info.js @@ -145,7 +145,7 @@ export function baseTableInfo(s2, container, chart, action, tableData) { export function baseTableNormal(s2, container, chart, action, tableData) { const containerDom = document.getElementById(container) - if(!containerDom) return + if (!containerDom) return // fields const fields = chart.data.fields diff --git a/frontend/src/views/chart/components/shape-attr/TotalCfg.vue b/frontend/src/views/chart/components/shape-attr/TotalCfg.vue index 774111cc97..b29c7b8e2c 100644 --- a/frontend/src/views/chart/components/shape-attr/TotalCfg.vue +++ b/frontend/src/views/chart/components/shape-attr/TotalCfg.vue @@ -16,6 +16,11 @@ + + + + + @@ -31,6 +36,11 @@ + + + + + {{ $t('chart.col_cfg') }} @@ -47,6 +57,11 @@ + + + + + @@ -62,6 +77,11 @@ + + + + + @@ -88,7 +108,13 @@ export default { }, data() { return { - totalForm: JSON.parse(JSON.stringify(DEFAULT_TOTAL)) + totalForm: JSON.parse(JSON.stringify(DEFAULT_TOTAL)), + aggregations: [ + { name: this.$t('chart.sum'), value: 'SUM' }, + { name: this.$t('chart.avg'), value: 'AVG' }, + { name: this.$t('chart.max'), value: 'MAX' }, + { name: this.$t('chart.min'), value: 'MIN' } + ] } }, computed: { @@ -190,4 +216,8 @@ span{font-size: 12px} font-weight: 400; padding: 0 10px; } + +.form-item-select{ + width:160px!important; +} diff --git a/frontend/src/views/dataset/add/AddSQL.vue b/frontend/src/views/dataset/add/AddSQL.vue index 2f408f6edb..327f6e2196 100644 --- a/frontend/src/views/dataset/add/AddSQL.vue +++ b/frontend/src/views/dataset/add/AddSQL.vue @@ -249,35 +249,35 @@ export default { { label: this.$t('dataset.text'), value: 'TEXT' }, { label: this.$t('dataset.value'), value: 'LONG' }, { label: this.$t('dataset.value') + '(' + this.$t('dataset.float') + ')', value: 'DOUBLE' }, - // { label: this.$t('dataset.time_year'), value: 'DATETIME-YEAR' }, - // { label: this.$t('dataset.time_year_month'), value: 'DATETIME-YEAR-MONTH', - // children: [{ - // value: 'yyyy-MM', - // label: 'YYYY-MM' - // }, { - // value: 'yyyy/MM', - // label: 'YYYY/MM' - // }] - // }, - // { label: this.$t('dataset.time_year_month_day'), value: 'DATETIME-YEAR-MONTH-DAY', - // children: [{ - // value: 'yyyy-MM-dd', - // label: 'YYYY-MM-DD' - // }, { - // value: 'yyyy/MM/dd', - // label: 'YYYY/MM/DD' - // }] - // }, - // { label: this.$t('dataset.time_all'), value: 'DATETIME', - // children: [{ - // value: 'yyyy-MM-dd HH:mm:ss', - // label: 'YYYY-MM-DD HH:MI:SS' - // }, { - // value: 'yyyy/MM/dd HH:mm:ss', - // label: 'YYYY/MM/DD HH:MI:SS' - // } - // ] - // } + { label: this.$t('dataset.time_year'), value: 'DATETIME-YEAR' }, + { label: this.$t('dataset.time_year_month'), value: 'DATETIME-YEAR-MONTH', + children: [{ + value: 'yyyy-MM', + label: 'YYYY-MM' + }, { + value: 'yyyy/MM', + label: 'YYYY/MM' + }] + }, + { label: this.$t('dataset.time_year_month_day'), value: 'DATETIME-YEAR-MONTH-DAY', + children: [{ + value: 'yyyy-MM-dd', + label: 'YYYY-MM-DD' + }, { + value: 'yyyy/MM/dd', + label: 'YYYY/MM/DD' + }] + }, + { label: this.$t('dataset.time_all'), value: 'DATETIME', + children: [{ + value: 'yyyy-MM-dd HH:mm:ss', + label: 'YYYY-MM-DD HH:MI:SS' + }, { + value: 'yyyy/MM/dd HH:mm:ss', + label: 'YYYY/MM/DD HH:MI:SS' + } + ] + } ], } }, diff --git a/frontend/src/views/dataset/form.vue b/frontend/src/views/dataset/form.vue new file mode 100644 index 0000000000..ca322a2443 --- /dev/null +++ b/frontend/src/views/dataset/form.vue @@ -0,0 +1,17 @@ + + + diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index 6835a93753..7681a713f3 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -58,16 +58,16 @@
- + - +
@@ -89,7 +89,7 @@