diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java index 675737542..c9f73d2da 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java @@ -1,13 +1,17 @@ package com.cf.imes.module.report.controller.admin.datasource; +import com.bstek.common.config.DataSourceConfig; +import com.bstek.common.utils.MultipleJdbcTemplate; +import com.bstek.datasource.bean.DataSourceInfo; +import com.bstek.datasource.bean.PreviewParams; +import com.bstek.datasource.service.DataSourceService; +import com.bstek.ureport.definition.dataset.Field; import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.common.util.object.BeanUtils; -import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceRespVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO; -import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO; import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO; import com.cf.imes.module.report.service.datasource.ReportDatasourceService; import io.swagger.v3.oas.annotations.Operation; @@ -22,6 +26,7 @@ import javax.validation.Valid; import java.util.List; import java.util.Map; +import java.util.Objects; import static com.cf.imes.framework.common.pojo.CommonResult.error; import static com.cf.imes.framework.common.pojo.CommonResult.success; @@ -41,6 +46,12 @@ public class ReportDatasourceController { @Resource private ReportDatasourceService datasourceService; + @Resource + private DataSourceConfig dataSourceConfig; + + @Resource + private DataSourceService ureportDataSourceService; + @PutMapping("/datasource") @Operation(summary = "创建报表数据源") // @PreAuthorize("@ss.hasPermission('report:datasource:create')") @@ -98,29 +109,35 @@ public class ReportDatasourceController { @GetMapping("/buildin/datasources") @Operation(summary = "获取内置数据源") // @PreAuthorize("@ss.hasPermission('report:datasource:query')") - public CommonResult> getBuildinDatasources() { - return success(BeanUtils.toBean(datasourceService.getBuildinDatasources(), ReportDatasourceRespVO.class)); + public CommonResult> getBuildinDatasources() { + return CommonResult.success(dataSourceConfig.getDatasource()); } @PostMapping("/datasource/connect") @Operation(summary = "测试数据源连接") // @PreAuthorize("@ss.hasPermission('report:datasource:query')") - public CommonResult testDatasourceConnect(@RequestBody ReportDatasourceTestConnReqVO reqVO) { - boolean connResult = datasourceService.testConnect(reqVO); - return connResult ? success(true) : error(DATASOURCE_CONNECT_FAIL); + public CommonResult testDatasourceConnect(@RequestBody DataSourceInfo info) { + String success = MultipleJdbcTemplate.testConnection(info); + return Objects.equals("success", success) ? success(true) : error(DATASOURCE_CONNECT_FAIL); } @PostMapping("/datasource/tables") @Operation(summary = "获取数据源表列表") // @PreAuthorize("@ss.hasPermission('report:datasource:query')") - public CommonResult>> getDatasourceTables(@RequestBody ReportDatasourceTestConnReqVO reqVO) { - return success(datasourceService.getDatasourceTables(reqVO)); + public CommonResult>> getDatasourceTables(@RequestBody DataSourceInfo info) { + return success(ureportDataSourceService.selectTableList(info)); } @PostMapping("/datasource/table/fields") @Operation(summary = "获取数据源表字段") // @PreAuthorize("@ss.hasPermission('report:datasource:query')") - public CommonResult> getDatasourceTableFields(@RequestBody ReportDatasourceTestConnReqVO reqVO) { - return success(datasourceService.getTableFields(reqVO)); + public CommonResult> getDatasourceTableFields(@RequestBody PreviewParams previewParams) { + return success(datasourceService.getTableFields(previewParams)); + } + + @PostMapping("/datasource/preview") + @Operation(summary = "数据源预览") + public CommonResult> previewData(@RequestBody PreviewParams previewParams) { + return success(ureportDataSourceService.previewData(previewParams)); } } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java index c2d36a457..a87036e9b 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java @@ -1,15 +1,14 @@ package com.cf.imes.module.report.service.datasource; -import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO; +import com.bstek.datasource.bean.PreviewParams; +import com.bstek.ureport.definition.dataset.Field; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO; -import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO; import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO; import javax.validation.Valid; import java.util.List; -import java.util.Map; /** * 报表数据源 Service 接口 @@ -63,12 +62,6 @@ public interface ReportDatasourceService { */ List getBeanDatasourceList(); - /** - * 获取内置数据源列表 - * @return - */ - List getBuildinDatasources(); - /** * 获取bean方法 * @@ -77,27 +70,13 @@ public interface ReportDatasourceService { */ List loadBeanMethods(String beanId); - /** - * 测试数据源连接 - * - * @param reqVO 连接信息请求 - * @return - */ - boolean testConnect(ReportDatasourceTestConnReqVO reqVO); - - /** - * 获取数据源表列表 - * - * @param reqVO 连接信息请求 - * @return - */ - List> getDatasourceTables(ReportDatasourceTestConnReqVO reqVO); - /** * 获取数据源表字段 * - * @param reqVO 连接信息请求 + * @param previewParams 连接信息请求 * @return */ - List getTableFields(ReportDatasourceTestConnReqVO reqVO); + List getTableFields(PreviewParams previewParams); + + } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java index 8edf3ecf9..41c87841c 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java @@ -4,6 +4,9 @@ import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils; +import com.bstek.common.utils.MultipleJdbcTemplate; +import com.bstek.datasource.bean.DataSourceInfo; +import com.bstek.datasource.bean.PreviewParams; import com.bstek.ureport.definition.dataset.Field; import com.bstek.ureport.definition.dataset.Parameter; import com.bstek.ureport.definition.dataset.SqlDatasetDefinition; @@ -11,19 +14,14 @@ import com.bstek.ureport.utils.ProcedureUtils; import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.util.object.BeanUtils; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; -import com.cf.imes.framework.organ.core.aop.OrganIgnore; -import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetFieldVO; -import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetParameterVO; import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetReqVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO; import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO; -import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceTestConnReqVO; import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO; import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO; import com.cf.imes.module.report.dal.mysql.dataset.ReportDatasetMapper; import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper; -import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum; import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource; import com.cf.imes.module.report.service.dataset.ReportDatasetService; import com.cf.imes.module.report.util.SqlInjectionUtil; @@ -41,11 +39,7 @@ import javax.annotation.Resource; import javax.sql.DataSource; import java.lang.reflect.Method; import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; import java.sql.ResultSetMetaData; -import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -160,21 +154,6 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { return beanDatasourceRespVOList; } - @Override - @OrganIgnore - public List getBuildinDatasources() { - List reportDatasourceDOS = datasourceMapper.selectList(new LambdaQueryWrapperX() - .eqIfPresent(ReportDatasourceDO::getType, ReportTemplateTypeEnum.SYSTEM) - .orderByDesc(ReportDatasourceDO::getCreateTime)); - // 查询数据集 - if (CollUtil.isNotEmpty(reportDatasourceDOS)) { - reportDatasourceDOS.forEach(reportDatasourceDO -> { - queryDatasetInSource(reportDatasourceDO); - }); - } - return reportDatasourceDOS; - } - @Override public List loadBeanMethods(String beanId) { Object obj = applicationContext.getBean(beanId); @@ -205,71 +184,25 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { } @Override - public boolean testConnect(ReportDatasourceTestConnReqVO reqVO) { + public List getTableFields(PreviewParams previewParams) { Connection conn = null; + String sql = previewParams.getSql(); + List parameters = previewParams.getParameters(); + DataSourceInfo info = previewParams.getInfo(); try { - // 获取数据库连接 - conn = buildConn(reqVO); - } catch (Exception ex) { - log.error("[testConnect][报表数据源测试连接失败:{}]", ex.getMessage()); - return false; - } finally { - JdbcUtils.closeConnection(conn); - } - return true; - } - - @Override - public List> getDatasourceTables(ReportDatasourceTestConnReqVO reqVO) { - Connection conn = null; - ResultSet rs = null; - List> tables = new ArrayList>(); - try { - // 获取数据库连接 - conn = buildConn(reqVO); - DatabaseMetaData metaData = conn.getMetaData(); - String url = metaData.getURL(); - String schema = null; - if (url.toLowerCase().contains("oracle")) { - schema = metaData.getUserName(); - } - - rs = metaData.getTables(conn.getCatalog(), schema, null, new String[]{"TABLE", "VIEW"}); - // 轮询获取表信息 - while (rs.next()) { - Map table = new HashMap(); - table.put("name", rs.getString("TABLE_NAME")); - table.put("type", rs.getString("TABLE_TYPE")); - tables.add(table); - } - } catch (Exception ex) { - log.error("[testConnect][报表数据源库表失败:{}]", ex.getMessage()); - } finally { - JdbcUtils.closeResultSet(rs); - JdbcUtils.closeConnection(conn); - } - return tables; - } - - @Override - public List getTableFields(ReportDatasourceTestConnReqVO reqVO) { - Connection conn = null; - String sql = reqVO.getSql(); - List parameters = reqVO.getParameters(); - try { - if(StringUtils.isEmpty(sql)) { + if (StringUtils.isEmpty(sql)) { throw exception(DATASET_SQL_REQUIRED); } // 获取数据库连接 - conn = buildConn(reqVO); + conn = MultipleJdbcTemplate.buildConnection(info); // 自定义工具校验sql if (SqlInjectionUtil.checkEditSql(sql)) { throw exception(DATASET_SQL_ILLEGAL); } // 检查参数sql注入 - for (ReportDatasetParameterVO parameterVO : parameters) { + for (Parameter parameter : parameters) { // mybatis-plus util检查参数 - if (SqlInjectionUtils.check(parameterVO.getDefaultValue())) { + if (SqlInjectionUtils.check(parameter.getDefaultValue())) { throw exception(DATASET_SQL_INJECTION_RISK); } } @@ -282,19 +215,18 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { Map pmap = sqlDatasetDefinition.buildParameters(params); String sqlForUse = sqlDatasetDefinition.parseSql(pmap); if (ProcedureUtils.isProcedure(sqlForUse)) { - List fields = ProcedureUtils.procedureColumnsQuery(sqlForUse, pmap, conn); - return BeanUtils.toBean(fields, ReportDatasetFieldVO.class); + return ProcedureUtils.procedureColumnsQuery(sqlForUse, pmap, conn); } DataSource dataSource = new SingleConnectionDataSource(conn, false); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - final List fields = new ArrayList<>(); + final List fields = new ArrayList<>(); jdbcTemplate.query(sqlForUse, pmap, (ResultSetExtractor) rs -> { ResultSetMetaData metadata = rs.getMetaData(); List metadataList = new ArrayList<>(); for (int i = 1; i <= metadata.getColumnCount(); i++) { String columnName = metadata.getColumnLabel(i); metadataList.add(columnName); - fields.add(new ReportDatasetFieldVO(columnName)); + fields.add(new Field(columnName)); } return null; }); @@ -309,31 +241,6 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService { } } - /** - * 构建数据库连接 - * 有数据源id从库里查数据源信息 - * 没有数据源id用请求中的driver等连接 - * @param reqVO - * @return - * @throws ClassNotFoundException - * @throws SQLException - */ - private Connection buildConn(ReportDatasourceTestConnReqVO reqVO) throws ClassNotFoundException, SQLException { - Long datasourceId = reqVO.getDatasourceId(); - Connection conn = null; - if (ObjectUtil.isNotNull(datasourceId)) { - ReportDatasourceDO datasourceDO = datasourceMapper.selectById(datasourceId); - if (ObjectUtil.isNotNull(datasourceDO)) { - Class.forName(datasourceDO.getDriver()); - conn = DriverManager.getConnection(datasourceDO.getUrl(), datasourceDO.getUsername(), datasourceDO.getPassword()); - } - } else { - Class.forName(reqVO.getDriver()); - conn = DriverManager.getConnection(reqVO.getUrl(), reqVO.getUserName(), reqVO.getPassword()); - } - return conn; - } - /** * 查询数据源下的数据集 * diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/permission/MenuController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/permission/MenuController.java index 8ed922c89..1a6ea7b3b 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/permission/MenuController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/permission/MenuController.java @@ -108,8 +108,9 @@ public class MenuController { @Operation(summary = "获取菜单精简信息列表", description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + "在多组织的场景下,会只返回组织所在套餐有的菜单") public CommonResult> getSimpleMenuList() { + // status:0 开启 visiable:1 显示 List list = menuService.getMenuListByOrgan( - new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setVisiable(CommonStatusEnum.ENABLE.getStatus())); + new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setVisiable(CommonStatusEnum.DISABLE.getStatus())); list.sort(Comparator.comparing(MenuDO::getSort)); return success(BeanUtils.toBean(list, MenuSimpleRespVO.class)); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/user/vo/user/UserSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/user/vo/user/UserSaveReqVO.java index 7bf06d769..857adafe1 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/user/vo/user/UserSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/user/vo/user/UserSaveReqVO.java @@ -17,11 +17,6 @@ public class UserSaveReqVO { @Schema(description = "用户编号", example = "1024") private Long id; - @Schema(description = "a", requiredMode = Schema.RequiredMode.REQUIRED, example = "chenfeng") - @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户名由 数字、字母 组成") - @Size(min = 4, max = 30, message = "用户名长度为 4-30 个字符") - private String username; - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "晨丰") @Size(max = 30, message = "用户昵称长度不能超过30个字符") private String nickname; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/user/AdminUserMapper.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/user/AdminUserMapper.java index c8663d8c3..cc79ad4c7 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/user/AdminUserMapper.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/user/AdminUserMapper.java @@ -15,6 +15,7 @@ import com.cf.imes.module.system.controller.admin.user.vo.user.UserPageReqVO; import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; import java.time.LocalDate; import java.time.LocalDateTime; @@ -162,4 +163,13 @@ public interface AdminUserMapper extends BaseMapperX { .eq(AdminUserDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) .between(AdminUserDO::getLoginDate, startTime, endTIme))); } + + /** + * 数据库锁id下的数据,注意使用 + * + * @param id + * @return + */ + @Select("SELECT username FROM system_users WHERE id = #{id} FOR UPDATE") + AdminUserDO selectByIdForUpdate(@Param("id") Long id); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java index e432885c1..b4200ba4a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/user/AdminUserServiceImpl.java @@ -130,13 +130,14 @@ public class AdminUserServiceImpl implements AdminUserService { throw ServiceExceptionUtil.exception(ErrorCodeConstants.USER_COUNT_MAX, organ.getAccountCount()); } }); - // 改造:手机号直接当做用户名 - createReqVO.setUsername(createReqVO.getMobile()); + // 校验正确性 - validateUserForCreateOrUpdate(null, createReqVO.getUsername(), + validateUserForCreateOrUpdate(null, createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds(), null, organId); // 插入用户 AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class); + // 改造:手机号直接当做用户名 + user.setUsername(createReqVO.getMobile()); user.setOrganId(createReqVO.getOrganId()); String pinyinFull = PinYinUtils.convertToPinyin(user.getNickname()); if (StringUtils.isNotBlank(pinyinFull)) { @@ -157,10 +158,11 @@ public class AdminUserServiceImpl implements AdminUserService { @Transactional(rollbackFor = Exception.class) public void updateUser(UserSaveReqVO updateReqVO) { Long organId = updateReqVO.getOrganId() == null ? OrganContextHolder.getOrganId(): updateReqVO.getOrganId(); + String mobile = updateReqVO.getMobile(); // 不允许关闭自身状态 checkCurrentWhenOperateStatus(updateReqVO.getId(), updateReqVO.getStatus()); // 校验正确性 - validateUserForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getUsername(), + validateUserForCreateOrUpdate(updateReqVO.getId(), mobile, updateReqVO.getEmail(), updateReqVO.getDeptId(), updateReqVO.getPostIds(), null, organId); // 更新用户 AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class); @@ -174,7 +176,16 @@ public class AdminUserServiceImpl implements AdminUserService { updateObj.setPinyinFull(pinyinFull); updateObj.setPinyinInitial(PinYinUtils.convertFirstChar(updateReqVO.getNickname())); } - + Long id = updateObj.getId(); + if (ObjectUtil.isNotNull(id)) { + AdminUserDO adminUserDO = userMapper.selectByIdForUpdate(id); + // 当手机号(账号)发生改变时,清空密码 + if (ObjectUtil.isNotNull(adminUserDO) && !Objects.equals(adminUserDO.getUsername(), mobile)) { + // 清空密码 + updateObj.setPassword(""); + updateObj.setUsername(mobile); + } + } userMapper.updateById(updateObj); // 更新岗位 updateUserPost(updateReqVO, updateObj);