Merge branch 'master' of gitee.com:zhijiantianya/ruoyi-vue-pro into feature/ut-job
This commit is contained in:
commit
08bc389ba5
|
@ -0,0 +1,4 @@
|
||||||
|
config.stopBubbling = true
|
||||||
|
lombok.tostring.callsuper=true
|
||||||
|
lombok.equalsandhashcode.callsuper=true
|
||||||
|
lombok.accessors.chain=true
|
|
@ -8,3 +8,19 @@ export function exportHtml() {
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function exportWord() {
|
||||||
|
return request({
|
||||||
|
url: '/infra/db-doc/export-word',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function exportMarkdown() {
|
||||||
|
return request({
|
||||||
|
url: '/infra/db-doc/export-markdown',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -25,7 +25,10 @@ import {
|
||||||
download,
|
download,
|
||||||
handleTree,
|
handleTree,
|
||||||
downloadExcel,
|
downloadExcel,
|
||||||
downloadZip
|
downloadWord,
|
||||||
|
downloadZip,
|
||||||
|
downloadHtml,
|
||||||
|
downloadMarkdown,
|
||||||
} from "@/utils/ruoyi";
|
} from "@/utils/ruoyi";
|
||||||
import Pagination from "@/components/Pagination";
|
import Pagination from "@/components/Pagination";
|
||||||
// 自定义表格工具扩展
|
// 自定义表格工具扩展
|
||||||
|
@ -48,6 +51,9 @@ Vue.prototype.getDictDataLabel = getDictDataLabel
|
||||||
Vue.prototype.DICT_TYPE = DICT_TYPE
|
Vue.prototype.DICT_TYPE = DICT_TYPE
|
||||||
Vue.prototype.download = download
|
Vue.prototype.download = download
|
||||||
Vue.prototype.downloadExcel = downloadExcel
|
Vue.prototype.downloadExcel = downloadExcel
|
||||||
|
Vue.prototype.downloadWord = downloadWord
|
||||||
|
Vue.prototype.downloadHtml = downloadHtml
|
||||||
|
Vue.prototype.downloadMarkdown = downloadMarkdown
|
||||||
Vue.prototype.downloadZip = downloadZip
|
Vue.prototype.downloadZip = downloadZip
|
||||||
Vue.prototype.handleTree = handleTree
|
Vue.prototype.handleTree = handleTree
|
||||||
|
|
||||||
|
|
|
@ -120,11 +120,26 @@ export function downloadExcel(data, fileName) {
|
||||||
download0(data, fileName, 'application/vnd.ms-excel');
|
download0(data, fileName, 'application/vnd.ms-excel');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下载 Word 方法
|
||||||
|
export function downloadWord(data, fileName) {
|
||||||
|
download0(data, fileName, 'application/msword');
|
||||||
|
}
|
||||||
|
|
||||||
// 下载 Zip 方法
|
// 下载 Zip 方法
|
||||||
export function downloadZip(data, fileName) {
|
export function downloadZip(data, fileName) {
|
||||||
download0(data, fileName, 'application/zip');
|
download0(data, fileName, 'application/zip');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下载 Html 方法
|
||||||
|
export function downloadHtml(data, fileName) {
|
||||||
|
download0(data, fileName, 'text/html');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载 Markdown 方法
|
||||||
|
export function downloadMarkdown(data, fileName) {
|
||||||
|
download0(data, fileName, 'text/markdown');
|
||||||
|
}
|
||||||
|
|
||||||
function download0(data, fileName, mineType) {
|
function download0(data, fileName, mineType) {
|
||||||
// 创建 blob
|
// 创建 blob
|
||||||
let blob = new Blob([data], {type: mineType});
|
let blob = new Blob([data], {type: mineType});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" :style="'height:'+ height">
|
<div class="app-container">
|
||||||
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportHtml">导出 HTML</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportWord">导出 Word</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportMarkdown">导出 Markdown</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 展示文档 -->
|
||||||
|
<div v-loading="loading" :style="'height:'+ height">
|
||||||
|
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {exportHtml} from "@/api/infra/dbDoc";
|
import { exportHtml, exportWord, exportMarkdown} from "@/api/infra/dbDoc";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DBDoc",
|
name: "DBDoc",
|
||||||
|
@ -25,10 +36,31 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
// 加载 Html,进行预览
|
||||||
exportHtml().then(response => {
|
exportHtml().then(response => {
|
||||||
// var blob = new Blob(['<a id="a"><b id="b">hey!</b></a>'], {type : 'text/html'});
|
let blob = new Blob([response], {type : 'text/html'});
|
||||||
this.src = window.URL.createObjectURL(response);
|
this.src = window.URL.createObjectURL(blob);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
/** 处理导出 HTML */
|
||||||
|
handleExportHtml() {
|
||||||
|
exportHtml().then(response => {
|
||||||
|
this.downloadHtml(response, '数据库文档.html');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 处理导出 Word */
|
||||||
|
handleExportWord() {
|
||||||
|
exportWord().then(response => {
|
||||||
|
this.downloadWord(response, '数据库文档.doc');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 处理导出 Markdown */
|
||||||
|
handleExportMarkdown() {
|
||||||
|
exportMarkdown().then(response => {
|
||||||
|
this.downloadMarkdown(response, '数据库文档.md');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service;
|
||||||
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO;
|
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 访问日志 Framework Service 接口
|
* API 访问日志 Framework Service 接口
|
||||||
|
@ -15,7 +16,8 @@ public interface ApiAccessLogFrameworkService {
|
||||||
* 创建 API 访问日志
|
* 创建 API 访问日志
|
||||||
*
|
*
|
||||||
* @param createDTO 创建信息
|
* @param createDTO 创建信息
|
||||||
|
* @return 是否创建成功
|
||||||
*/
|
*/
|
||||||
void createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO);
|
Future<Boolean> createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service;
|
||||||
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO;
|
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 错误日志 Framework Service 接口
|
* API 错误日志 Framework Service 接口
|
||||||
|
@ -15,7 +16,8 @@ public interface ApiErrorLogFrameworkService {
|
||||||
* 创建 API 错误日志
|
* 创建 API 错误日志
|
||||||
*
|
*
|
||||||
* @param createDTO 创建信息
|
* @param createDTO 创建信息
|
||||||
|
* @return 是否创建成功
|
||||||
*/
|
*/
|
||||||
void createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO);
|
Future<Boolean> createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package cn.iocoder.dashboard.modules.infra.controller.doc;
|
package cn.iocoder.dashboard.modules.infra.controller.doc;
|
||||||
|
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.iocoder.dashboard.util.servlet.ServletUtils;
|
||||||
import cn.smallbun.screw.core.Configuration;
|
import cn.smallbun.screw.core.Configuration;
|
||||||
import cn.smallbun.screw.core.engine.EngineConfig;
|
import cn.smallbun.screw.core.engine.EngineConfig;
|
||||||
import cn.smallbun.screw.core.engine.EngineFileType;
|
import cn.smallbun.screw.core.engine.EngineFileType;
|
||||||
|
@ -10,18 +12,18 @@ import cn.smallbun.screw.core.process.ProcessConfig;
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.IOException;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@Api(tags = "数据库文档")
|
@Api(tags = "数据库文档")
|
||||||
|
@ -34,36 +36,79 @@ public class InfDbDocController {
|
||||||
|
|
||||||
private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator
|
private static final String FILE_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator
|
||||||
+ "db-doc";
|
+ "db-doc";
|
||||||
private static final EngineFileType FILE_OUTPUT_TYPE = EngineFileType.HTML; // 可以设置 Word 或者 Markdown 格式
|
|
||||||
private static final String DOC_FILE_NAME = "数据库文档";
|
private static final String DOC_FILE_NAME = "数据库文档";
|
||||||
private static final String DOC_VERSION = "1.0.0";
|
private static final String DOC_VERSION = "1.0.0";
|
||||||
private static final String DOC_DESCRIPTION = "文档描述";
|
private static final String DOC_DESCRIPTION = "文档描述";
|
||||||
|
|
||||||
@Resource
|
|
||||||
private DataSource dataSource;
|
|
||||||
|
|
||||||
@GetMapping("/export-html")
|
@GetMapping("/export-html")
|
||||||
public synchronized void exportHtml(HttpServletResponse response) throws FileNotFoundException {
|
@ApiOperation("导出 html 格式的数据文档")
|
||||||
|
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||||
|
public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
doExportFile(EngineFileType.HTML, deleteFile, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-word")
|
||||||
|
@ApiOperation("导出 word 格式的数据文档")
|
||||||
|
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||||
|
public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
doExportFile(EngineFileType.WORD, deleteFile, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-markdown")
|
||||||
|
@ApiOperation("导出 markdown 格式的数据文档")
|
||||||
|
@ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
|
||||||
|
public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
doExportFile(EngineFileType.MD, deleteFile, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doExportFile(EngineFileType fileOutputType, Boolean deleteFile,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
String docFileName = DOC_FILE_NAME + "_" + IdUtil.fastSimpleUUID();
|
||||||
|
String filePath = doExportFile(fileOutputType, docFileName);
|
||||||
|
String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
|
||||||
|
try {
|
||||||
|
// 读取,返回
|
||||||
|
ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
|
||||||
|
} finally {
|
||||||
|
handleDeleteFile(deleteFile, filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出文件,返回文件路径
|
||||||
|
*
|
||||||
|
* @param fileOutputType 文件类型
|
||||||
|
* @param fileName 文件名, 无需 ".docx" 等文件后缀
|
||||||
|
* @return 生成的文件所在路径
|
||||||
|
*/
|
||||||
|
private String doExportFile(EngineFileType fileOutputType, String fileName) {
|
||||||
try (HikariDataSource dataSource = buildDataSource()) {
|
try (HikariDataSource dataSource = buildDataSource()) {
|
||||||
// 创建 screw 的配置
|
// 创建 screw 的配置
|
||||||
Configuration config = Configuration.builder()
|
Configuration config = Configuration.builder()
|
||||||
.version(DOC_VERSION) // 版本
|
.version(DOC_VERSION) // 版本
|
||||||
.description(DOC_DESCRIPTION) // 描述
|
.description(DOC_DESCRIPTION) // 描述
|
||||||
.dataSource(dataSource) // 数据源
|
.dataSource(dataSource) // 数据源
|
||||||
.engineConfig(buildEngineConfig()) // 引擎配置
|
.engineConfig(buildEngineConfig(fileOutputType, fileName)) // 引擎配置
|
||||||
.produceConfig(buildProcessConfig()) // 处理配置
|
.produceConfig(buildProcessConfig()) // 处理配置
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 执行 screw,生成数据库文档
|
// 执行 screw,生成数据库文档
|
||||||
new DocumentationExecute(config).execute();
|
new DocumentationExecute(config).execute();
|
||||||
|
|
||||||
// 读取,返回
|
return FILE_OUTPUT_DIR + File.separator + fileName + fileOutputType.getFileSuffix();
|
||||||
ServletUtil.write(response,
|
|
||||||
new FileInputStream(FILE_OUTPUT_DIR + File.separator + DOC_FILE_NAME + FILE_OUTPUT_TYPE.getFileSuffix()),
|
|
||||||
MediaType.TEXT_HTML_VALUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleDeleteFile(Boolean deleteFile, String filePath) {
|
||||||
|
if (!deleteFile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FileUtil.del(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建数据源
|
* 创建数据源
|
||||||
*/
|
*/
|
||||||
|
@ -71,7 +116,6 @@ public class InfDbDocController {
|
||||||
private HikariDataSource buildDataSource() {
|
private HikariDataSource buildDataSource() {
|
||||||
// 创建 HikariConfig 配置类
|
// 创建 HikariConfig 配置类
|
||||||
HikariConfig hikariConfig = new HikariConfig();
|
HikariConfig hikariConfig = new HikariConfig();
|
||||||
// hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
|
|
||||||
hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
|
hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
|
||||||
hikariConfig.setUsername(dataSourceProperties.getUsername());
|
hikariConfig.setUsername(dataSourceProperties.getUsername());
|
||||||
hikariConfig.setPassword(dataSourceProperties.getPassword());
|
hikariConfig.setPassword(dataSourceProperties.getPassword());
|
||||||
|
@ -83,13 +127,13 @@ public class InfDbDocController {
|
||||||
/**
|
/**
|
||||||
* 创建 screw 的引擎配置
|
* 创建 screw 的引擎配置
|
||||||
*/
|
*/
|
||||||
private static EngineConfig buildEngineConfig() {
|
private static EngineConfig buildEngineConfig(EngineFileType fileOutputType, String docFileName) {
|
||||||
return EngineConfig.builder()
|
return EngineConfig.builder()
|
||||||
.fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
|
.fileOutputDir(FILE_OUTPUT_DIR) // 生成文件路径
|
||||||
.openOutputDir(false) // 打开目录
|
.openOutputDir(false) // 打开目录
|
||||||
.fileType(FILE_OUTPUT_TYPE) // 文件类型
|
.fileType(fileOutputType) // 文件类型
|
||||||
.produceType(EngineTemplateType.freemarker) // 文件类型
|
.produceType(EngineTemplateType.freemarker) // 文件类型
|
||||||
.fileName(DOC_FILE_NAME) // 自定义文件名称
|
.fileName(docFileName) // 自定义文件名称
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU
|
||||||
public class InfApiErrorLogExportReqVO {
|
public class InfApiErrorLogExportReqVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户编号", example = "666")
|
@ApiModelProperty(value = "用户编号", example = "666")
|
||||||
private Integer userId;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户类型", example = "1")
|
@ApiModelProperty(value = "用户类型", example = "1")
|
||||||
private Integer userType;
|
private Integer userType;
|
||||||
|
|
|
@ -19,7 +19,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU
|
||||||
public class InfApiErrorLogPageReqVO extends PageParam {
|
public class InfApiErrorLogPageReqVO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户编号", example = "666")
|
@ApiModelProperty(value = "用户编号", example = "666")
|
||||||
private Integer userId;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户类型", example = "1")
|
@ApiModelProperty(value = "用户类型", example = "1")
|
||||||
private Integer userType;
|
private Integer userType;
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class InfApiAccessLogDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
*/
|
*/
|
||||||
private Integer userId;
|
private Long userId;
|
||||||
/**
|
/**
|
||||||
* 用户类型
|
* 用户类型
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class InfApiErrorLogDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
*/
|
*/
|
||||||
private Integer userId;
|
private Long userId;
|
||||||
/**
|
/**
|
||||||
* 链路追踪编号
|
* 链路追踪编号
|
||||||
*
|
*
|
||||||
|
@ -148,6 +148,6 @@ public class InfApiErrorLogDO extends BaseDO {
|
||||||
*
|
*
|
||||||
* 关联 {@link SysUserDO#getId()}
|
* 关联 {@link SysUserDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Integer processUserId;
|
private Long processUserId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class InfJobServiceImpl implements InfJobService {
|
||||||
private SchedulerManager schedulerManager;
|
private SchedulerManager schedulerManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long createJob(InfJobCreateReqVO createReqVO) throws SchedulerException {
|
public Long createJob(InfJobCreateReqVO createReqVO) throws SchedulerException {
|
||||||
validateCronExpression(createReqVO.getCronExpression());
|
validateCronExpression(createReqVO.getCronExpression());
|
||||||
// 校验唯一性
|
// 校验唯一性
|
||||||
|
@ -68,7 +68,7 @@ public class InfJobServiceImpl implements InfJobService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateJob(InfJobUpdateReqVO updateReqVO) throws SchedulerException {
|
public void updateJob(InfJobUpdateReqVO updateReqVO) throws SchedulerException {
|
||||||
validateCronExpression(updateReqVO.getCronExpression());
|
validateCronExpression(updateReqVO.getCronExpression());
|
||||||
// 校验存在
|
// 校验存在
|
||||||
|
@ -88,7 +88,7 @@ public class InfJobServiceImpl implements InfJobService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateJobStatus(Long id, Integer status) throws SchedulerException {
|
public void updateJobStatus(Long id, Integer status) throws SchedulerException {
|
||||||
// 校验 status
|
// 校验 status
|
||||||
if (!containsAny(status, InfJobStatusEnum.NORMAL.getStatus(), InfJobStatusEnum.STOP.getStatus())) {
|
if (!containsAny(status, InfJobStatusEnum.NORMAL.getStatus(), InfJobStatusEnum.STOP.getStatus())) {
|
||||||
|
@ -122,7 +122,7 @@ public class InfJobServiceImpl implements InfJobService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteJob(Long id) throws SchedulerException {
|
public void deleteJob(Long id) throws SchedulerException {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
InfJobDO job = this.validateJobExists(id);
|
InfJobDO job = this.validateJobExists(id);
|
||||||
|
|
|
@ -9,12 +9,13 @@ import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogD
|
||||||
import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper;
|
import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper;
|
||||||
import cn.iocoder.dashboard.modules.infra.service.logger.InfApiAccessLogService;
|
import cn.iocoder.dashboard.modules.infra.service.logger.InfApiAccessLogService;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.scheduling.annotation.AsyncResult;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 访问日志 Service 实现类
|
* API 访问日志 Service 实现类
|
||||||
|
@ -30,10 +31,11 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Async
|
@Async
|
||||||
public void createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) {
|
public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) {
|
||||||
// 插入
|
// 插入
|
||||||
InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO);
|
InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO);
|
||||||
apiAccessLogMapper.insert(apiAccessLog);
|
int insert = apiAccessLogMapper.insert(apiAccessLog);
|
||||||
|
return new AsyncResult<>(insert == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,12 +10,14 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper;
|
||||||
import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
|
import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
|
||||||
import cn.iocoder.dashboard.modules.infra.service.logger.InfApiErrorLogService;
|
import cn.iocoder.dashboard.modules.infra.service.logger.InfApiErrorLogService;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.scheduling.annotation.AsyncResult;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND;
|
import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND;
|
||||||
|
@ -35,10 +37,11 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Async
|
@Async
|
||||||
public void createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) {
|
public Future<Boolean> createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) {
|
||||||
InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO);
|
InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO);
|
||||||
apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus());
|
apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus());
|
||||||
apiErrorLogMapper.insert(apiErrorLog);
|
int insert = apiErrorLogMapper.insert(apiErrorLog);
|
||||||
|
return new AsyncResult<>(insert == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,7 +65,7 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService {
|
||||||
}
|
}
|
||||||
// 标记处理
|
// 标记处理
|
||||||
apiErrorLogMapper.updateById(InfApiErrorLogDO.builder().id(id).processStatus(processStatus)
|
apiErrorLogMapper.updateById(InfApiErrorLogDO.builder().id(id).processStatus(processStatus)
|
||||||
.processUserId(processStatus).processTime(new Date()).build());
|
.processUserId(processUserId).processTime(new Date()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ public class SysCaptchaController {
|
||||||
@Resource
|
@Resource
|
||||||
private SysCaptchaService captchaService;
|
private SysCaptchaService captchaService;
|
||||||
|
|
||||||
@ApiOperation("生成图片验证码")
|
|
||||||
@GetMapping("/get-image")
|
@GetMapping("/get-image")
|
||||||
|
@ApiOperation("生成图片验证码")
|
||||||
public CommonResult<SysCaptchaImageRespVO> getCaptchaImage() {
|
public CommonResult<SysCaptchaImageRespVO> getCaptchaImage() {
|
||||||
return success(captchaService.getCaptchaImage());
|
return success(captchaService.getCaptchaImage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ public class SysUserController {
|
||||||
@Resource
|
@Resource
|
||||||
private SysDeptService deptService;
|
private SysDeptService deptService;
|
||||||
|
|
||||||
@ApiOperation("获得用户分页列表")
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
|
@ApiOperation("获得用户分页列表")
|
||||||
@PreAuthorize("@ss.hasPermission('system:user:list')")
|
@PreAuthorize("@ss.hasPermission('system:user:list')")
|
||||||
public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
|
public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
|
||||||
// 获得用户分页列表
|
// 获得用户分页列表
|
||||||
|
@ -66,9 +66,9 @@ public class SysUserController {
|
||||||
/**
|
/**
|
||||||
* 根据用户编号获取详细信息
|
* 根据用户编号获取详细信息
|
||||||
*/
|
*/
|
||||||
|
@GetMapping("/get")
|
||||||
@ApiOperation("获得用户详情")
|
@ApiOperation("获得用户详情")
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||||
@GetMapping("/get")
|
|
||||||
// @PreAuthorize("@ss.hasPermi('system:user:query')")
|
// @PreAuthorize("@ss.hasPermi('system:user:query')")
|
||||||
public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) {
|
public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) {
|
||||||
return success(SysUserConvert.INSTANCE.convert(userService.getUser(id)));
|
return success(SysUserConvert.INSTANCE.convert(userService.getUser(id)));
|
||||||
|
|
|
@ -1,92 +1,80 @@
|
||||||
package cn.iocoder.dashboard.modules.system.controller.user;
|
package cn.iocoder.dashboard.modules.system.controller.user;
|
||||||
|
|
||||||
|
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert;
|
||||||
|
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
|
||||||
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
|
||||||
|
import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
|
||||||
|
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
|
||||||
|
import cn.iocoder.dashboard.util.collection.CollectionUtils;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_IS_EMPTY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author niudehua
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/user/profile")
|
||||||
|
@Api(tags = "用户个人中心")
|
||||||
|
@Slf4j
|
||||||
public class SysUserProfileController {
|
public class SysUserProfileController {
|
||||||
|
|
||||||
// /**
|
@Resource
|
||||||
// * 个人信息
|
private SysUserService userService;
|
||||||
// */
|
@Resource
|
||||||
// @GetMapping
|
private SysPermissionService permissionService;
|
||||||
// public AjaxResult profile()
|
@Resource
|
||||||
// {
|
private SysRoleService roleService;
|
||||||
// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
|
||||||
// SysUser user = loginUser.getUser();
|
|
||||||
// AjaxResult ajax = AjaxResult.success(user);
|
|
||||||
// ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
|
|
||||||
// ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
|
|
||||||
// return ajax;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 修改用户
|
|
||||||
// */
|
|
||||||
// @Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
|
||||||
// @PutMapping
|
|
||||||
// public AjaxResult updateProfile(@RequestBody SysUser user)
|
|
||||||
// {
|
|
||||||
// if (userService.updateUserProfile(user) > 0)
|
|
||||||
// {
|
|
||||||
// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
|
||||||
// // 更新缓存用户信息
|
|
||||||
// loginUser.getUser().setNickName(user.getNickName());
|
|
||||||
// loginUser.getUser().setPhonenumber(user.getPhonenumber());
|
|
||||||
// loginUser.getUser().setEmail(user.getEmail());
|
|
||||||
// loginUser.getUser().setSex(user.getSex());
|
|
||||||
// tokenService.setLoginUser(loginUser);
|
|
||||||
// return AjaxResult.success();
|
|
||||||
// }
|
|
||||||
// return AjaxResult.error("修改个人信息异常,请联系管理员");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 重置密码
|
|
||||||
// */
|
|
||||||
// @Log(title = "个人信息", businessType = BusinessType.UPDATE)
|
|
||||||
// @PutMapping("/updatePwd")
|
|
||||||
// public AjaxResult updatePwd(String oldPassword, String newPassword)
|
|
||||||
// {
|
|
||||||
// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
|
||||||
// String userName = loginUser.getUsername();
|
|
||||||
// String password = loginUser.getPassword();
|
|
||||||
// if (!SecurityUtils.matchesPassword(oldPassword, password))
|
|
||||||
// {
|
|
||||||
// return AjaxResult.error("修改密码失败,旧密码错误");
|
|
||||||
// }
|
|
||||||
// if (SecurityUtils.matchesPassword(newPassword, password))
|
|
||||||
// {
|
|
||||||
// return AjaxResult.error("新密码不能与旧密码相同");
|
|
||||||
// }
|
|
||||||
// if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
|
|
||||||
// {
|
|
||||||
// // 更新缓存用户密码
|
|
||||||
// loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
|
|
||||||
// tokenService.setLoginUser(loginUser);
|
|
||||||
// return AjaxResult.success();
|
|
||||||
// }
|
|
||||||
// return AjaxResult.error("修改密码异常,请联系管理员");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 头像上传
|
|
||||||
// */
|
|
||||||
// @Log(title = "用户头像", businessType = BusinessType.UPDATE)
|
|
||||||
// @PostMapping("/avatar")
|
|
||||||
// public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException
|
|
||||||
// {
|
|
||||||
// if (!file.isEmpty())
|
|
||||||
// {
|
|
||||||
// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
|
||||||
// String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
|
|
||||||
// if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
|
|
||||||
// {
|
|
||||||
// AjaxResult ajax = AjaxResult.success();
|
|
||||||
// ajax.put("imgUrl", avatar);
|
|
||||||
// // 更新缓存用户头像
|
|
||||||
// loginUser.getUser().setAvatar(avatar);
|
|
||||||
// tokenService.setLoginUser(loginUser);
|
|
||||||
// return ajax;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return AjaxResult.error("上传图片异常,请联系管理员");
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@ApiOperation("获得登录用户信息")
|
||||||
|
public CommonResult<SysUserProfileRespVO> profile() {
|
||||||
|
// 获取用户信息
|
||||||
|
Long userId = SecurityFrameworkUtils.getLoginUserId();
|
||||||
|
SysUserDO user = userService.getUser(userId);
|
||||||
|
SysUserProfileRespVO userProfileRespVO = SysUserConvert.INSTANCE.convert03(user);
|
||||||
|
List<SysRoleDO> userRoles = roleService.listRolesFromCache(permissionService.listUserRoleIs(userId));
|
||||||
|
userProfileRespVO.setRoles(CollectionUtils.convertSet(userRoles, SysUserConvert.INSTANCE::convert));
|
||||||
|
return success(userProfileRespVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
@ApiOperation("修改用户个人信息")
|
||||||
|
public CommonResult<Boolean> updateProfile(@RequestBody SysUserProfileUpdateReqVO reqVO, HttpServletRequest request) {
|
||||||
|
userService.updateUserProfile(reqVO);
|
||||||
|
SecurityFrameworkUtils.setLoginUser(SysAuthConvert.INSTANCE.convert(reqVO), request);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/upload-avatar")
|
||||||
|
@ApiOperation("上传用户个人头像")
|
||||||
|
public CommonResult<Boolean> uploadAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
|
||||||
|
if (file.isEmpty()) {
|
||||||
|
throw ServiceExceptionUtil.exception(FILE_IS_EMPTY);
|
||||||
|
}
|
||||||
|
userService.updateAvatar(SecurityFrameworkUtils.getLoginUserId(), file.getInputStream());
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModel("用户个人中心信息 Response VO")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class SysUserProfileRespVO extends SysUserRespVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属角色
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(value = "所属角色", required = true, example = "123456")
|
||||||
|
private Set<Role> roles;
|
||||||
|
|
||||||
|
@ApiModel("角色")
|
||||||
|
@Data
|
||||||
|
public static class Role {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色编号", required = true, example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
@ApiModel("用户个人信息更新 Request VO")
|
||||||
|
@Data
|
||||||
|
public class SysUserProfileUpdateReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户编号", required = true, example = "1024")
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
|
||||||
|
@Size(max = 30, message = "用户昵称长度不能超过30个字符")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
|
||||||
|
@Email(message = "邮箱格式不正确")
|
||||||
|
@Size(max = 50, message = "邮箱长度不能超过50个字符")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "手机号码", example = "15601691300")
|
||||||
|
@Size(max = 11, message = "手机号码长度不能超过11个字符")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "旧密码", required = true, example = "123456")
|
||||||
|
private String oldPassword;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "新密码", required = true, example = "654321")
|
||||||
|
private String newPassword;
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth;
|
||||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
|
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
|
||||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
|
import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
|
@ -13,26 +14,33 @@ import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface SysAuthConvert {
|
public interface SysAuthConvert {
|
||||||
|
|
||||||
SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class);
|
SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class);
|
||||||
|
|
||||||
@Mapping(source = "updateTime", target = "updateTime", ignore = true) // 字段相同,但是含义不同,忽略
|
@Mapping(source = "updateTime", target = "updateTime", ignore = true)
|
||||||
|
// 字段相同,但是含义不同,忽略
|
||||||
LoginUser convert(SysUserDO bean);
|
LoginUser convert(SysUserDO bean);
|
||||||
|
|
||||||
default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
|
default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
|
||||||
return SysAuthPermissionInfoRespVO.builder()
|
return SysAuthPermissionInfoRespVO.builder()
|
||||||
.user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build())
|
.user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build())
|
||||||
.roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode))
|
.roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode))
|
||||||
.permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission))
|
.permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
SysAuthMenuRespVO convertTreeNode(SysMenuDO menu);
|
SysAuthMenuRespVO convertTreeNode(SysMenuDO menu);
|
||||||
|
|
||||||
|
LoginUser convert(SysUserProfileUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将菜单列表,构建成菜单树
|
* 将菜单列表,构建成菜单树
|
||||||
*
|
*
|
||||||
|
@ -47,12 +55,12 @@ public interface SysAuthConvert {
|
||||||
Map<Long, SysAuthMenuRespVO> treeNodeMap = new LinkedHashMap<>();
|
Map<Long, SysAuthMenuRespVO> treeNodeMap = new LinkedHashMap<>();
|
||||||
menuList.forEach(menu -> treeNodeMap.put(menu.getId(), SysAuthConvert.INSTANCE.convertTreeNode(menu)));
|
menuList.forEach(menu -> treeNodeMap.put(menu.getId(), SysAuthConvert.INSTANCE.convertTreeNode(menu)));
|
||||||
// 处理父子关系
|
// 处理父子关系
|
||||||
treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach((childNode) -> {
|
treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> {
|
||||||
// 获得父节点
|
// 获得父节点
|
||||||
SysAuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId());
|
SysAuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId());
|
||||||
if (parentNode == null) {
|
if (parentNode == null) {
|
||||||
LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]",
|
LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]",
|
||||||
childNode.getId(), childNode.getParentId());
|
childNode.getId(), childNode.getParentId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 将自己添加到父节点中
|
// 将自己添加到父节点中
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
package cn.iocoder.dashboard.modules.system.convert.user;
|
package cn.iocoder.dashboard.modules.system.convert.user;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
@ -23,4 +30,12 @@ public interface SysUserConvert {
|
||||||
|
|
||||||
SysUserDO convert(SysUserImportExcelVO bean);
|
SysUserDO convert(SysUserImportExcelVO bean);
|
||||||
|
|
||||||
|
SysUserProfileRespVO convert03(SysUserDO bean);
|
||||||
|
|
||||||
|
SysUserProfileRespVO.Role convert(SysRoleDO bean);
|
||||||
|
|
||||||
|
SysUserDO convert(SysUserProfileUpdateReqVO bean);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public interface SysErrorCodeConstants {
|
||||||
ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1002004002, "邮箱已经存在");
|
ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1002004002, "邮箱已经存在");
|
||||||
ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在");
|
ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在");
|
||||||
ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!");
|
ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!");
|
||||||
|
ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败");
|
||||||
|
|
||||||
// ========== 部门模块 1002005000 ==========
|
// ========== 部门模块 1002005000 ==========
|
||||||
ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门");
|
ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门");
|
||||||
|
@ -74,5 +75,7 @@ public interface SysErrorCodeConstants {
|
||||||
|
|
||||||
// ========== 文件 1002009000 ==========
|
// ========== 文件 1002009000 ==========
|
||||||
ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在");
|
ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在");
|
||||||
|
ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败");
|
||||||
|
ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,7 @@ public class SysMenuServiceImpl implements SysMenuService {
|
||||||
*
|
*
|
||||||
* @param menuId 菜单编号
|
* @param menuId 菜单编号
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteMenu(Long menuId) {
|
public void deleteMenu(Long menuId) {
|
||||||
// 校验更新的菜单是否存在
|
// 校验更新的菜单是否存在
|
||||||
if (menuMapper.selectById(menuId) == null) {
|
if (menuMapper.selectById(menuId) == null) {
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void assignRoleMenu(Long roleId, Set<Long> menuIds) {
|
public void assignRoleMenu(Long roleId, Set<Long> menuIds) {
|
||||||
// 获得角色拥有菜单编号
|
// 获得角色拥有菜单编号
|
||||||
Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId),
|
Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId),
|
||||||
|
|
|
@ -174,7 +174,7 @@ public class SysRoleServiceImpl implements SysRoleService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteRole(Long id) {
|
public void deleteRole(Long id) {
|
||||||
// 校验是否可以更新
|
// 校验是否可以更新
|
||||||
this.checkUpdateRole(id);
|
this.checkUpdateRole(id);
|
||||||
|
|
|
@ -2,10 +2,17 @@ package cn.iocoder.dashboard.modules.system.service.user;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||||
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
import cn.iocoder.dashboard.util.collection.CollectionUtils;
|
import cn.iocoder.dashboard.util.collection.CollectionUtils;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -102,6 +109,14 @@ public interface SysUserService {
|
||||||
*/
|
*/
|
||||||
void updateUser(SysUserUpdateReqVO reqVO);
|
void updateUser(SysUserUpdateReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户个人信息
|
||||||
|
*
|
||||||
|
* @param reqVO 用户个人信息
|
||||||
|
* @return 修改结果
|
||||||
|
*/
|
||||||
|
void updateUserProfile(SysUserProfileUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除用户
|
* 删除用户
|
||||||
*
|
*
|
||||||
|
@ -112,7 +127,7 @@ public interface SysUserService {
|
||||||
/**
|
/**
|
||||||
* 修改密码
|
* 修改密码
|
||||||
*
|
*
|
||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param password 密码
|
* @param password 密码
|
||||||
*/
|
*/
|
||||||
void updateUserPassword(Long id, String password);
|
void updateUserPassword(Long id, String password);
|
||||||
|
@ -120,7 +135,7 @@ public interface SysUserService {
|
||||||
/**
|
/**
|
||||||
* 修改密码
|
* 修改密码
|
||||||
*
|
*
|
||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param status 状态
|
* @param status 状态
|
||||||
*/
|
*/
|
||||||
void updateUserStatus(Long id, Integer status);
|
void updateUserStatus(Long id, Integer status);
|
||||||
|
@ -128,12 +143,20 @@ public interface SysUserService {
|
||||||
/**
|
/**
|
||||||
* 批量导入用户
|
* 批量导入用户
|
||||||
*
|
*
|
||||||
* @param importUsers 导入用户列表
|
* @param importUsers 导入用户列表
|
||||||
* @param isUpdateSupport 是否支持更新
|
* @param isUpdateSupport 是否支持更新
|
||||||
* @return 导入结果
|
* @return 导入结果
|
||||||
*/
|
*/
|
||||||
SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport);
|
SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户头像
|
||||||
|
*
|
||||||
|
* @param id 用户 id
|
||||||
|
* @param avatarFile 头像文件
|
||||||
|
*/
|
||||||
|
void updateAvatar(Long id, InputStream avatarFile);
|
||||||
|
|
||||||
//
|
//
|
||||||
// /**
|
// /**
|
||||||
// * 修改用户基本信息
|
// * 修改用户基本信息
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
package cn.iocoder.dashboard.modules.system.service.user;
|
package cn.iocoder.dashboard.modules.system.service.user;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
|
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.dashboard.common.exception.ServiceException;
|
import cn.iocoder.dashboard.common.exception.ServiceException;
|
||||||
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||||
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
|
import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
|
||||||
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
|
import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
|
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
|
||||||
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
|
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
|
||||||
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
|
import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
|
||||||
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
|
import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
|
||||||
|
@ -22,7 +31,14 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
|
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
|
||||||
|
|
||||||
|
@ -49,18 +65,8 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
@Resource
|
@Resource
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
// /**
|
@Resource
|
||||||
// * 根据条件分页查询用户列表
|
private InfFileService fileService;
|
||||||
// *
|
|
||||||
// * @param user 用户信息
|
|
||||||
// * @return 用户信息集合信息
|
|
||||||
// */
|
|
||||||
// @Override
|
|
||||||
// @DataScope(deptAlias = "d", userAlias = "u")
|
|
||||||
// public List<SysUser> selectUserList(SysUser user)
|
|
||||||
// {
|
|
||||||
// return userMapper.selectUserList(user);
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysUserDO getUserByUserName(String username) {
|
public SysUserDO getUserByUserName(String username) {
|
||||||
|
@ -108,7 +114,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
|
Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
|
||||||
deptId, true), SysDeptDO::getId);
|
deptId, true), SysDeptDO::getId);
|
||||||
deptIds.add(deptId); // 包括自身
|
deptIds.add(deptId); // 包括自身
|
||||||
return deptIds;
|
return deptIds;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +123,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
public Long createUser(SysUserCreateReqVO reqVO) {
|
public Long createUser(SysUserCreateReqVO reqVO) {
|
||||||
// 校验正确性
|
// 校验正确性
|
||||||
this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
|
this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
|
||||||
reqVO.getDeptId(), reqVO.getPostIds());
|
reqVO.getDeptId(), reqVO.getPostIds());
|
||||||
// 插入用户
|
// 插入用户
|
||||||
SysUserDO user = SysUserConvert.INSTANCE.convert(reqVO);
|
SysUserDO user = SysUserConvert.INSTANCE.convert(reqVO);
|
||||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
||||||
|
@ -130,12 +136,31 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
public void updateUser(SysUserUpdateReqVO reqVO) {
|
public void updateUser(SysUserUpdateReqVO reqVO) {
|
||||||
// 校验正确性
|
// 校验正确性
|
||||||
this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
|
this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
|
||||||
reqVO.getDeptId(), reqVO.getPostIds());
|
reqVO.getDeptId(), reqVO.getPostIds());
|
||||||
// 更新用户
|
// 更新用户
|
||||||
SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
|
SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
|
||||||
userMapper.updateById(updateObj);
|
userMapper.updateById(updateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUserProfile(SysUserProfileUpdateReqVO reqVO) {
|
||||||
|
// 校验正确性
|
||||||
|
this.checkUserExists(reqVO.getId());
|
||||||
|
this.checkEmailUnique(reqVO.getId(), reqVO.getEmail());
|
||||||
|
this.checkMobileUnique(reqVO.getId(), reqVO.getMobile());
|
||||||
|
// 校验填写密码
|
||||||
|
String encode = null;
|
||||||
|
if (this.checkOldPassword(reqVO.getId(), reqVO.getOldPassword(), reqVO.getNewPassword())) {
|
||||||
|
// 更新密码
|
||||||
|
encode = passwordEncoder.encode(reqVO.getNewPassword());
|
||||||
|
}
|
||||||
|
SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
|
||||||
|
if (StrUtil.isNotBlank(encode)) {
|
||||||
|
updateObj.setPassword(encode);
|
||||||
|
}
|
||||||
|
userMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteUser(Long id) {
|
public void deleteUser(Long id) {
|
||||||
// 校验用户存在
|
// 校验用户存在
|
||||||
|
@ -278,19 +303,42 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验旧密码、新密码
|
||||||
|
*
|
||||||
|
* @param id 用户 id
|
||||||
|
* @param oldPassword 旧密码
|
||||||
|
* @param newPassword 新密码
|
||||||
|
* @return 校验结果
|
||||||
|
*/
|
||||||
|
private boolean checkOldPassword(Long id, String oldPassword, String newPassword) {
|
||||||
|
if (id == null || StrUtil.isBlank(oldPassword) || StrUtil.isBlank(newPassword)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SysUserDO user = userMapper.selectById(id);
|
||||||
|
if (user == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
|
||||||
|
throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional // 添加事务,异常则回滚所有导入
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
||||||
public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) {
|
public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) {
|
||||||
if (CollUtil.isEmpty(importUsers)) {
|
if (CollUtil.isEmpty(importUsers)) {
|
||||||
throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY);
|
throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY);
|
||||||
}
|
}
|
||||||
SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>())
|
SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>())
|
||||||
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
.updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
|
||||||
importUsers.forEach(importUser -> {
|
importUsers.forEach(importUser -> {
|
||||||
// 校验,判断是否有不符合的原因
|
// 校验,判断是否有不符合的原因
|
||||||
try {
|
try {
|
||||||
checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
|
checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
|
||||||
importUser.getDeptId(), null);
|
importUser.getDeptId(), null);
|
||||||
} catch (ServiceException ex) {
|
} catch (ServiceException ex) {
|
||||||
respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
|
respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
|
||||||
return;
|
return;
|
||||||
|
@ -316,4 +364,16 @@ public class SysUserServiceImpl implements SysUserService {
|
||||||
return respVO;
|
return respVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAvatar(Long id, InputStream avatarFile) {
|
||||||
|
this.checkUserExists(id);
|
||||||
|
// 存储文件
|
||||||
|
String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
|
||||||
|
// 更新路径
|
||||||
|
SysUserDO sysUserDO = new SysUserDO();
|
||||||
|
sysUserDO.setId(id);
|
||||||
|
sysUserDO.setAvatar(avatar);
|
||||||
|
userMapper.updateById(sysUserDO);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public List<Long> createCodegenListFromDB(List<String> tableNames) {
|
public List<Long> createCodegenListFromDB(List<String> tableNames) {
|
||||||
List<Long> ids = new ArrayList<>(tableNames.size());
|
List<Long> ids = new ArrayList<>(tableNames.size());
|
||||||
// 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量
|
// 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量
|
||||||
|
@ -118,7 +118,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateCodegen(ToolCodegenUpdateReqVO updateReqVO) {
|
public void updateCodegen(ToolCodegenUpdateReqVO updateReqVO) {
|
||||||
// 校验是否已经存在
|
// 校验是否已经存在
|
||||||
if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) {
|
if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) {
|
||||||
|
@ -134,7 +134,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void syncCodegenFromDB(Long tableId) {
|
public void syncCodegenFromDB(Long tableId) {
|
||||||
// 校验是否已经存在
|
// 校验是否已经存在
|
||||||
ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
|
ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
|
||||||
|
@ -149,7 +149,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void syncCodegenFromSQL(Long tableId, String sql) {
|
public void syncCodegenFromSQL(Long tableId, String sql) {
|
||||||
// 校验是否已经存在
|
// 校验是否已经存在
|
||||||
ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
|
ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
|
||||||
|
@ -201,7 +201,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteCodegen(Long tableId) {
|
public void deleteCodegen(Long tableId) {
|
||||||
// 校验是否已经存在
|
// 校验是否已经存在
|
||||||
if (codegenTableMapper.selectById(tableId) == null) {
|
if (codegenTableMapper.selectById(tableId) == null) {
|
||||||
|
|
|
@ -145,14 +145,14 @@ yudao:
|
||||||
swagger:
|
swagger:
|
||||||
title: 管理后台
|
title: 管理后台
|
||||||
description: 提供管理员管理的所有功能
|
description: 提供管理员管理的所有功能
|
||||||
version: ${yudao.info.base-package}
|
version: ${yudao.info.version}
|
||||||
base-package: ${yudao.info.base-package}.modules
|
base-package: ${yudao.info.base-package}.modules
|
||||||
captcha:
|
captcha:
|
||||||
timeout: 5m
|
timeout: 5m
|
||||||
width: 160
|
width: 160
|
||||||
height: 60
|
height: 60
|
||||||
file:
|
file:
|
||||||
base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/
|
base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
|
||||||
codegen:
|
codegen:
|
||||||
base-package: ${yudao.info.base-package}
|
base-package: ${yudao.info.base-package}
|
||||||
db-schemas: ${spring.datasource.name}
|
db-schemas: ${spring.datasource.name}
|
||||||
|
|
|
@ -145,14 +145,14 @@ yudao:
|
||||||
swagger:
|
swagger:
|
||||||
title: 管理后台
|
title: 管理后台
|
||||||
description: 提供管理员管理的所有功能
|
description: 提供管理员管理的所有功能
|
||||||
version: ${yudao.info.base-package}
|
version: ${yudao.info.version}
|
||||||
base-package: ${yudao.info.base-package}.modules
|
base-package: ${yudao.info.base-package}.modules
|
||||||
captcha:
|
captcha:
|
||||||
timeout: 5m
|
timeout: 5m
|
||||||
width: 160
|
width: 160
|
||||||
height: 60
|
height: 60
|
||||||
file:
|
file:
|
||||||
base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/
|
base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
|
||||||
codegen:
|
codegen:
|
||||||
base-package: ${yudao.info.base-package}
|
base-package: ${yudao.info.base-package}
|
||||||
db-schemas: ${spring.datasource.name}
|
db-schemas: ${spring.datasource.name}
|
||||||
|
|
|
@ -16,9 +16,9 @@ import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
import org.springframework.test.context.jdbc.Sql;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 依赖内存 DB 的单元测试
|
* 依赖内存 DB + Redis 的单元测试
|
||||||
*
|
*
|
||||||
* 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
|
* 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package cn.iocoder.dashboard;
|
||||||
|
|
||||||
|
import cn.iocoder.dashboard.config.RedisTestConfiguration;
|
||||||
|
import cn.iocoder.dashboard.framework.redis.config.RedisConfig;
|
||||||
|
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 依赖内存 Redis 的单元测试
|
||||||
|
*
|
||||||
|
* 相比 {@link BaseDbUnitTest} 来说,从内存 DB 改成了内存 Redis
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisUnitTest.Application.class)
|
||||||
|
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
||||||
|
public class BaseRedisUnitTest {
|
||||||
|
|
||||||
|
@Import({
|
||||||
|
// Redis 配置类
|
||||||
|
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
||||||
|
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
||||||
|
RedisConfig.class, // 自己的 Redis 配置类
|
||||||
|
RedissonAutoConfiguration.class, // Redisson 自动高配置类
|
||||||
|
})
|
||||||
|
public static class Application {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
package cn.iocoder.dashboard;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.data.redis.core.RedisCallback;
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
|
||||||
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
|
||||||
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
|
|
||||||
@Deprecated
|
|
||||||
public class BaseSpringBootUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 每个单元测试结束后,清理 Redis
|
|
||||||
*/
|
|
||||||
@AfterEach
|
|
||||||
public void cleanRedis() {
|
|
||||||
stringRedisTemplate.execute((RedisCallback<Object>) connection -> {
|
|
||||||
connection.flushDb();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,19 +1,17 @@
|
||||||
package cn.iocoder.dashboard.config;
|
package cn.iocoder.dashboard.config;
|
||||||
|
|
||||||
import com.github.fppt.jedismock.RedisServer;
|
import com.github.fppt.jedismock.RedisServer;
|
||||||
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@Lazy(false) // 禁止延迟加载
|
||||||
@EnableConfigurationProperties(RedisProperties.class)
|
@EnableConfigurationProperties(RedisProperties.class)
|
||||||
@AutoConfigureBefore({RedisAutoConfiguration.class, RedissonAutoConfiguration.class}) // 在 Redis 自动配置前,进行初始化
|
|
||||||
public class RedisTestConfiguration {
|
public class RedisTestConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package cn.iocoder.dashboard.framework.quartz.core.scheduler;
|
package cn.iocoder.dashboard.framework.quartz.core.scheduler;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import cn.iocoder.dashboard.modules.system.job.auth.SysUserSessionTimeoutJob;
|
import cn.iocoder.dashboard.modules.system.job.auth.SysUserSessionTimeoutJob;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
class SchedulerManagerTest extends BaseSpringBootUnitTest {
|
class SchedulerManagerTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SchedulerManager schedulerManager;
|
private SchedulerManager schedulerManager;
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
package cn.iocoder.dashboard.modules.infra.service.logger;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
|
import cn.iocoder.dashboard.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
|
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogExportReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogPageReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogDO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiAccessLogServiceImpl;
|
||||||
|
import cn.iocoder.dashboard.util.RandomUtils;
|
||||||
|
import cn.iocoder.dashboard.util.object.ObjectUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link InfApiAccessLogServiceImpl} 单元测试
|
||||||
|
*/
|
||||||
|
@Import(InfApiAccessLogServiceImpl.class)
|
||||||
|
public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfApiAccessLogService infApiAccessLogServiceImpl;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfApiAccessLogMapper infApiAccessLogMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateApiAccessLogAsync() throws Exception {
|
||||||
|
ApiAccessLogCreateDTO createDTO = RandomUtils.randomPojo(
|
||||||
|
ApiAccessLogCreateDTO.class,
|
||||||
|
dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue())
|
||||||
|
);
|
||||||
|
|
||||||
|
// 执行service方法
|
||||||
|
Future<Boolean> future = infApiAccessLogServiceImpl.createApiAccessLogAsync(createDTO);
|
||||||
|
|
||||||
|
// 等异步执行完
|
||||||
|
future.get();
|
||||||
|
|
||||||
|
InfApiAccessLogDO infApiAccessLogDO = infApiAccessLogMapper.selectOne(null);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(infApiAccessLogDO);
|
||||||
|
// 断言,忽略基本字段
|
||||||
|
assertPojoEquals(createDTO, infApiAccessLogDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetApiAccessLogPage() {
|
||||||
|
// 构造测试数据
|
||||||
|
long userId = 2233L;
|
||||||
|
int userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
String applicationName = "ruoyi-test";
|
||||||
|
String requestUrl = "foo";
|
||||||
|
Date beginTime = buildTime(2021, 3, 13);
|
||||||
|
int duration = 1000;
|
||||||
|
int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode();
|
||||||
|
|
||||||
|
InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> {
|
||||||
|
dto.setUserId(userId);
|
||||||
|
dto.setUserType(userType);
|
||||||
|
dto.setApplicationName(applicationName);
|
||||||
|
dto.setRequestUrl(requestUrl);
|
||||||
|
dto.setBeginTime(beginTime);
|
||||||
|
dto.setDuration(duration);
|
||||||
|
dto.setResultCode(resultCode);
|
||||||
|
});
|
||||||
|
infApiAccessLogMapper.insert(infApiAccessLogDO);
|
||||||
|
|
||||||
|
// 下面几个都是不匹配的数据
|
||||||
|
// userId 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
|
||||||
|
// userType
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// applicationName 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
|
||||||
|
// requestUrl 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
|
||||||
|
// 构造一个早期时间 2021-02-06 00:00:00
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
|
||||||
|
// duration 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
|
||||||
|
// resultCode 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
|
||||||
|
|
||||||
|
// 构造调用参数
|
||||||
|
InfApiAccessLogPageReqVO reqVO = new InfApiAccessLogPageReqVO();
|
||||||
|
reqVO.setUserId(userId);
|
||||||
|
reqVO.setUserType(userType);
|
||||||
|
reqVO.setApplicationName(applicationName);
|
||||||
|
reqVO.setRequestUrl(requestUrl);
|
||||||
|
reqVO.setBeginBeginTime(buildTime(2021, 3, 12));
|
||||||
|
reqVO.setEndBeginTime(buildTime(2021, 3, 14));
|
||||||
|
reqVO.setDuration(duration);
|
||||||
|
reqVO.setResultCode(resultCode);
|
||||||
|
|
||||||
|
// 调用service方法
|
||||||
|
PageResult<InfApiAccessLogDO> pageResult = infApiAccessLogServiceImpl.getApiAccessLogPage(reqVO);
|
||||||
|
|
||||||
|
// 断言,只查到了一条符合条件的
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(infApiAccessLogDO, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetApiAccessLogList() {
|
||||||
|
// 构造测试数据
|
||||||
|
long userId = 2233L;
|
||||||
|
int userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
String applicationName = "ruoyi-test";
|
||||||
|
String requestUrl = "foo";
|
||||||
|
Date beginTime = buildTime(2021, 3, 13);
|
||||||
|
int duration = 1000;
|
||||||
|
int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode();
|
||||||
|
|
||||||
|
InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> {
|
||||||
|
dto.setUserId(userId);
|
||||||
|
dto.setUserType(userType);
|
||||||
|
dto.setApplicationName(applicationName);
|
||||||
|
dto.setRequestUrl(requestUrl);
|
||||||
|
dto.setBeginTime(beginTime);
|
||||||
|
dto.setDuration(duration);
|
||||||
|
dto.setResultCode(resultCode);
|
||||||
|
});
|
||||||
|
infApiAccessLogMapper.insert(infApiAccessLogDO);
|
||||||
|
|
||||||
|
// 下面几个都是不匹配的数据
|
||||||
|
// userId 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
|
||||||
|
// userType
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// applicationName 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
|
||||||
|
// requestUrl 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
|
||||||
|
// 构造一个早期时间 2021-02-06 00:00:00
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
|
||||||
|
// duration 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
|
||||||
|
// resultCode 不同的
|
||||||
|
infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
|
||||||
|
|
||||||
|
// 构造调用参数
|
||||||
|
InfApiAccessLogExportReqVO reqVO = new InfApiAccessLogExportReqVO();
|
||||||
|
reqVO.setUserId(userId);
|
||||||
|
reqVO.setUserType(userType);
|
||||||
|
reqVO.setApplicationName(applicationName);
|
||||||
|
reqVO.setRequestUrl(requestUrl);
|
||||||
|
reqVO.setBeginBeginTime(buildTime(2021, 3, 12));
|
||||||
|
reqVO.setEndBeginTime(buildTime(2021, 3, 14));
|
||||||
|
reqVO.setDuration(duration);
|
||||||
|
reqVO.setResultCode(resultCode);
|
||||||
|
|
||||||
|
// 调用service方法
|
||||||
|
List<InfApiAccessLogDO> list = infApiAccessLogServiceImpl.getApiAccessLogList(reqVO);
|
||||||
|
|
||||||
|
// 断言,只查到了一条符合条件的
|
||||||
|
assertEquals(1, list.size());
|
||||||
|
assertPojoEquals(infApiAccessLogDO, list.get(0));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
package cn.iocoder.dashboard.modules.infra.service.logger;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
|
import cn.iocoder.dashboard.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogExportReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogPageReqVO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
|
||||||
|
import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiErrorLogServiceImpl;
|
||||||
|
import cn.iocoder.dashboard.util.RandomUtils;
|
||||||
|
import cn.iocoder.dashboard.util.object.ObjectUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND;
|
||||||
|
import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_PROCESSED;
|
||||||
|
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
|
||||||
|
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
|
||||||
|
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link InfApiErrorLogServiceImpl} 单元测试
|
||||||
|
*/
|
||||||
|
@Import(InfApiErrorLogServiceImpl.class)
|
||||||
|
public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfApiErrorLogService infApiErrorLogServiceImpl;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfApiErrorLogMapper infApiErrorLogMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateApiErrorLogAsync() throws Exception {
|
||||||
|
ApiErrorLogCreateDTO createDTO = RandomUtils.randomPojo(
|
||||||
|
ApiErrorLogCreateDTO.class,
|
||||||
|
dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue())
|
||||||
|
);
|
||||||
|
|
||||||
|
// 执行service方法
|
||||||
|
Future<Boolean> future = infApiErrorLogServiceImpl.createApiErrorLogAsync(createDTO);
|
||||||
|
|
||||||
|
// 等异步执行完
|
||||||
|
future.get();
|
||||||
|
|
||||||
|
InfApiErrorLogDO infApiErrorLogDO = infApiErrorLogMapper.selectOne(null);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(infApiErrorLogDO);
|
||||||
|
// 断言,忽略基本字段
|
||||||
|
assertPojoEquals(createDTO, infApiErrorLogDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetApiErrorLogPage() {
|
||||||
|
// 构造测试数据
|
||||||
|
long userId = 2233L;
|
||||||
|
int userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
String applicationName = "ruoyi-test";
|
||||||
|
String requestUrl = "foo";
|
||||||
|
Date beginTime = buildTime(2021, 3, 13);
|
||||||
|
int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus();
|
||||||
|
|
||||||
|
InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> {
|
||||||
|
logDO.setUserId(userId);
|
||||||
|
logDO.setUserType(userType);
|
||||||
|
logDO.setApplicationName(applicationName);
|
||||||
|
logDO.setRequestUrl(requestUrl);
|
||||||
|
logDO.setExceptionTime(beginTime);
|
||||||
|
logDO.setProcessStatus(progressStatus);
|
||||||
|
});
|
||||||
|
infApiErrorLogMapper.insert(infApiErrorLogDO);
|
||||||
|
|
||||||
|
// 下面几个都是不匹配的数据
|
||||||
|
// userId 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
|
||||||
|
// userType
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// applicationName 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
|
||||||
|
// requestUrl 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
|
||||||
|
// 构造一个早期时间 2021-02-06 00:00:00
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
|
||||||
|
// progressStatus 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
|
||||||
|
|
||||||
|
// 构造调用参数
|
||||||
|
InfApiErrorLogPageReqVO reqVO = new InfApiErrorLogPageReqVO();
|
||||||
|
reqVO.setUserId(userId);
|
||||||
|
reqVO.setUserType(userType);
|
||||||
|
reqVO.setApplicationName(applicationName);
|
||||||
|
reqVO.setRequestUrl(requestUrl);
|
||||||
|
reqVO.setBeginExceptionTime(buildTime(2021, 3, 12));
|
||||||
|
reqVO.setEndExceptionTime(buildTime(2021, 3, 14));
|
||||||
|
reqVO.setProcessStatus(progressStatus);
|
||||||
|
|
||||||
|
// 调用service方法
|
||||||
|
PageResult<InfApiErrorLogDO> pageResult = infApiErrorLogServiceImpl.getApiErrorLogPage(reqVO);
|
||||||
|
|
||||||
|
// 断言,只查到了一条符合条件的
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(infApiErrorLogDO, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetApiErrorLogList() {
|
||||||
|
// 构造测试数据
|
||||||
|
long userId = 2233L;
|
||||||
|
int userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
String applicationName = "ruoyi-test";
|
||||||
|
String requestUrl = "foo";
|
||||||
|
Date beginTime = buildTime(2021, 3, 13);
|
||||||
|
int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus();
|
||||||
|
|
||||||
|
InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> {
|
||||||
|
logDO.setUserId(userId);
|
||||||
|
logDO.setUserType(userType);
|
||||||
|
logDO.setApplicationName(applicationName);
|
||||||
|
logDO.setRequestUrl(requestUrl);
|
||||||
|
logDO.setExceptionTime(beginTime);
|
||||||
|
logDO.setProcessStatus(progressStatus);
|
||||||
|
});
|
||||||
|
infApiErrorLogMapper.insert(infApiErrorLogDO);
|
||||||
|
|
||||||
|
// 下面几个都是不匹配的数据
|
||||||
|
// userId 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
|
||||||
|
// userType
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// applicationName 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
|
||||||
|
// requestUrl 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
|
||||||
|
// 构造一个早期时间 2021-02-06 00:00:00
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
|
||||||
|
// progressStatus 不同的
|
||||||
|
infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
|
||||||
|
|
||||||
|
// 构造调用参数
|
||||||
|
InfApiErrorLogExportReqVO reqVO = new InfApiErrorLogExportReqVO();
|
||||||
|
reqVO.setUserId(userId);
|
||||||
|
reqVO.setUserType(userType);
|
||||||
|
reqVO.setApplicationName(applicationName);
|
||||||
|
reqVO.setRequestUrl(requestUrl);
|
||||||
|
reqVO.setBeginExceptionTime(buildTime(2021, 3, 12));
|
||||||
|
reqVO.setEndExceptionTime(buildTime(2021, 3, 14));
|
||||||
|
reqVO.setProcessStatus(progressStatus);
|
||||||
|
|
||||||
|
// 调用service方法
|
||||||
|
List<InfApiErrorLogDO> list = infApiErrorLogServiceImpl.getApiErrorLogList(reqVO);
|
||||||
|
|
||||||
|
// 断言,只查到了一条符合条件的
|
||||||
|
assertEquals(1, list.size());
|
||||||
|
assertPojoEquals(infApiErrorLogDO, list.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateApiErrorLogProcess() {
|
||||||
|
// 先构造两条数据,第一条用于抛出异常,第二条用于正常的执行update操作
|
||||||
|
Long processUserId = 2233L;
|
||||||
|
|
||||||
|
InfApiErrorLogDO first = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> {
|
||||||
|
logDO.setProcessUserId(processUserId);
|
||||||
|
logDO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus());
|
||||||
|
});
|
||||||
|
infApiErrorLogMapper.insert(first);
|
||||||
|
|
||||||
|
InfApiErrorLogDO second = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> {
|
||||||
|
logDO.setProcessUserId(1122L);
|
||||||
|
logDO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus());
|
||||||
|
});
|
||||||
|
infApiErrorLogMapper.insert(second);
|
||||||
|
|
||||||
|
Long firstId = first.getId();
|
||||||
|
Long secondId = second.getId();
|
||||||
|
|
||||||
|
// 执行正常的 update 操作
|
||||||
|
infApiErrorLogServiceImpl.updateApiErrorLogProcess(secondId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId);
|
||||||
|
InfApiErrorLogDO secondSelect = infApiErrorLogMapper.selectOne("id", secondId);
|
||||||
|
|
||||||
|
// id 为 0 查询不到,应该抛出异常 API_ERROR_LOG_NOT_FOUND
|
||||||
|
assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(0L, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_NOT_FOUND);
|
||||||
|
// id 为 first 的 progressStatus 为 DONE ,应该抛出 API_ERROR_LOG_PROCESSED
|
||||||
|
assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(firstId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_PROCESSED);
|
||||||
|
// 验证 progressStatus 是否修改成功
|
||||||
|
assertEquals(InfApiErrorLogProcessStatusEnum.DONE.getStatus(), secondSelect.getProcessStatus());
|
||||||
|
// 验证 progressUserId 是否修改成功
|
||||||
|
assertEquals(processUserId, secondSelect.getProcessUserId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package cn.iocoder.dashboard.modules.system.service.common;
|
||||||
|
|
||||||
|
import cn.iocoder.dashboard.BaseRedisUnitTest;
|
||||||
|
import cn.iocoder.dashboard.framework.captcha.config.CaptchaProperties;
|
||||||
|
import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageRespVO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.dal.redis.common.SysCaptchaRedisDAO;
|
||||||
|
import cn.iocoder.dashboard.modules.system.service.common.impl.SysCaptchaServiceImpl;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.util.RandomUtils.randomString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@Import({SysCaptchaServiceImpl.class, CaptchaProperties.class, SysCaptchaRedisDAO.class})
|
||||||
|
public class SysCaptchaServiceTest extends BaseRedisUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysCaptchaServiceImpl captchaService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysCaptchaRedisDAO captchaRedisDAO;
|
||||||
|
@Resource
|
||||||
|
private CaptchaProperties captchaProperties;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCaptchaImage() {
|
||||||
|
// 调用
|
||||||
|
SysCaptchaImageRespVO respVO = captchaService.getCaptchaImage();
|
||||||
|
// 断言
|
||||||
|
assertNotNull(respVO.getUuid());
|
||||||
|
assertNotNull(respVO.getImg());
|
||||||
|
String captchaCode = captchaRedisDAO.get(respVO.getUuid());
|
||||||
|
assertNotNull(captchaCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCaptchaCode() {
|
||||||
|
// 准备参数
|
||||||
|
String uuid = randomString();
|
||||||
|
String code = randomString();
|
||||||
|
// mock 数据
|
||||||
|
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
String resultCode = captchaService.getCaptchaCode(uuid);
|
||||||
|
// 断言
|
||||||
|
assertEquals(code, resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteCaptchaCode() {
|
||||||
|
// 准备参数
|
||||||
|
String uuid = randomString();
|
||||||
|
String code = randomString();
|
||||||
|
// mock 数据
|
||||||
|
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
captchaService.deleteCaptchaCode(uuid);
|
||||||
|
// 断言
|
||||||
|
assertNull(captchaRedisDAO.get(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen;
|
package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolSchemaColumnDO;
|
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolSchemaColumnDO;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class ToolInformationSchemaColumnMapperTest extends BaseSpringBootUnitTest {
|
public class ToolInformationSchemaColumnMapperTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ToolSchemaColumnMapper toolInformationSchemaColumnMapper;
|
private ToolSchemaColumnMapper toolInformationSchemaColumnMapper;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen;
|
package cn.iocoder.dashboard.modules.tool.dal.mysql.codegen;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolSchemaTableDO;
|
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolSchemaTableDO;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
class ToolInformationSchemaTableMapperTest extends BaseSpringBootUnitTest {
|
class ToolInformationSchemaTableMapperTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ToolSchemaTableMapper toolInformationSchemaTableMapper;
|
private ToolSchemaTableMapper toolInformationSchemaTableMapper;
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColumnDO;
|
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenColumnDO;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
|
import cn.iocoder.dashboard.modules.tool.dal.dataobject.codegen.ToolCodegenTableDO;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenColumnMapper;
|
import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenColumnMapper;
|
||||||
import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenTableMapper;
|
import cn.iocoder.dashboard.modules.tool.dal.mysql.codegen.ToolCodegenTableMapper;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ToolCodegenEngineTest extends BaseSpringBootUnitTest {
|
public class ToolCodegenEngineTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ToolCodegenTableMapper codegenTableMapper;
|
private ToolCodegenTableMapper codegenTableMapper;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class ToolCodegenSQLParserTest extends BaseSpringBootUnitTest {
|
public class ToolCodegenSQLParserTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParse() {
|
public void testParse() {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
|
||||||
|
|
||||||
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
|
import cn.iocoder.dashboard.BaseDbUnitTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
class ToolCodegenServiceImplTest extends BaseSpringBootUnitTest {
|
class ToolCodegenServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ToolCodegenServiceImpl toolCodegenService;
|
private ToolCodegenServiceImpl toolCodegenService;
|
||||||
|
|
|
@ -131,7 +131,7 @@ CREATE TABLE IF NOT EXISTS "sys_menu" (
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT '菜单权限表';
|
) COMMENT '菜单权限表';
|
||||||
|
|
||||||
CREATE TABLE "sys_dict_type" (
|
CREATE TABLE IF NOT EXISTS "sys_dict_type" (
|
||||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
"name" varchar(100) NOT NULL DEFAULT '',
|
"name" varchar(100) NOT NULL DEFAULT '',
|
||||||
"type" varchar(100) NOT NULL DEFAULT '',
|
"type" varchar(100) NOT NULL DEFAULT '',
|
||||||
|
@ -145,7 +145,7 @@ CREATE TABLE "sys_dict_type" (
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT '字典类型表';
|
) COMMENT '字典类型表';
|
||||||
|
|
||||||
CREATE TABLE `sys_user_session` (
|
CREATE TABLE IF NOT EXISTS `sys_user_session` (
|
||||||
`id` varchar(32) NOT NULL,
|
`id` varchar(32) NOT NULL,
|
||||||
`user_id` bigint DEFAULT NULL,
|
`user_id` bigint DEFAULT NULL,
|
||||||
`username` varchar(50) NOT NULL DEFAULT '',
|
`username` varchar(50) NOT NULL DEFAULT '',
|
||||||
|
@ -209,7 +209,7 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` (
|
||||||
) COMMENT ='系统访问记录';
|
) COMMENT ='系统访问记录';
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `sys_operate_log` (
|
CREATE TABLE IF NOT EXISTS `sys_operate_log` (
|
||||||
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
`trace_id` varchar(64) NOT NULL DEFAULT '',
|
`trace_id` varchar(64) NOT NULL DEFAULT '',
|
||||||
`user_id` bigint(20) NOT NULL,
|
`user_id` bigint(20) NOT NULL,
|
||||||
|
@ -237,7 +237,7 @@ CREATE TABLE `sys_operate_log` (
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) COMMENT ='操作日志记录';
|
) COMMENT ='操作日志记录';
|
||||||
|
|
||||||
create table "sys_user" (
|
create table IF NOT EXISTS "sys_user" (
|
||||||
"id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
|
"id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
|
||||||
"username" varchar(30) not null,
|
"username" varchar(30) not null,
|
||||||
"password" varchar(100) not null default '',
|
"password" varchar(100) not null default '',
|
||||||
|
@ -259,3 +259,60 @@ create table "sys_user" (
|
||||||
"deleted" bit not null default false,
|
"deleted" bit not null default false,
|
||||||
primary key ("id")
|
primary key ("id")
|
||||||
) comment '用户信息表';
|
) comment '用户信息表';
|
||||||
|
|
||||||
|
|
||||||
|
create table "inf_api_access_log" (
|
||||||
|
"id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"trace_id" varchar(64) not null default '',
|
||||||
|
"user_id" bigint not null default '0',
|
||||||
|
"user_type" tinyint not null default '0',
|
||||||
|
"application_name" varchar(50) not null,
|
||||||
|
"request_method" varchar(16) not null default '',
|
||||||
|
"request_url" varchar(255) not null default '',
|
||||||
|
"request_params" varchar(8000) not null default '',
|
||||||
|
"user_ip" varchar(50) not null,
|
||||||
|
"user_agent" varchar(512) not null,
|
||||||
|
"begin_time" timestamp not null,
|
||||||
|
"end_time" timestamp not null,
|
||||||
|
"duration" integer not null,
|
||||||
|
"result_code" integer not null default '0',
|
||||||
|
"result_msg" varchar(512) default '',
|
||||||
|
"creator" varchar(64) default '',
|
||||||
|
"create_time" timestamp not null default current_timestamp,
|
||||||
|
"updater" varchar(64) default '',
|
||||||
|
"update_time" timestamp not null default current_timestamp,
|
||||||
|
"deleted" bit not null default false,
|
||||||
|
primary key ("id")
|
||||||
|
) comment 'API 访问日志表';
|
||||||
|
|
||||||
|
|
||||||
|
create table "inf_api_error_log" (
|
||||||
|
"id" integer not null GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"trace_id" varchar(64) not null,
|
||||||
|
"user_id" bigint not null default '0',
|
||||||
|
"user_type" tinyint not null default '0',
|
||||||
|
"application_name" varchar(50) not null,
|
||||||
|
"request_method" varchar(16) not null,
|
||||||
|
"request_url" varchar(255) not null,
|
||||||
|
"request_params" varchar(8000) not null,
|
||||||
|
"user_ip" varchar(50) not null,
|
||||||
|
"user_agent" varchar(512) not null,
|
||||||
|
"exception_time" timestamp not null,
|
||||||
|
"exception_name" varchar(128) not null default '',
|
||||||
|
"exception_message" clob not null,
|
||||||
|
"exception_root_cause_message" clob not null,
|
||||||
|
"exception_stack_trace" clob not null,
|
||||||
|
"exception_class_name" varchar(512) not null,
|
||||||
|
"exception_file_name" varchar(512) not null,
|
||||||
|
"exception_method_name" varchar(512) not null,
|
||||||
|
"exception_line_number" integer not null,
|
||||||
|
"process_status" tinyint not null,
|
||||||
|
"process_time" timestamp default null,
|
||||||
|
"process_user_id" bigint default '0',
|
||||||
|
"creator" varchar(64) default '',
|
||||||
|
"create_time" timestamp not null default current_timestamp,
|
||||||
|
"updater" varchar(64) default '',
|
||||||
|
"update_time" timestamp not null default current_timestamp,
|
||||||
|
"deleted" bit not null default false,
|
||||||
|
primary key ("id")
|
||||||
|
) comment '系统异常日志';
|
Loading…
Reference in New Issue