一个毕设半程品,想要快速上手还得从项目来进行分析代码。
基本的Result类
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Result {
//返回的代码
public static final String CODE_SUCCESS = "200";
public static final String CODE_AUTH_ERROR = "401";
public static final String CODE_SYS_ERROR = "500";
/**
* 请求的返回编码 200 401 404 500
* 编码表示这次请求是成功还是失败
* 或者说 可以看出失败的类型是什么
*/
private String code;
/**
* msg表示错误的详细信息
*/
private String msg;
/**
* 数据从什么地方返回出去?
* 就是这个data
* user Object类型就是User
* List Object类型就是List
* Map Object类型就是Map
* Object extend Yushengjun
*/
private Object data; //object类
public static Result success() {
return Result.builder().code(CODE_SUCCESS).msg("请求成功").build(); //用建造者模式
}
public static Result success(Object data) {
return new Result(CODE_SUCCESS, "请求成功", data);
}
public static Result error(String msg) {
return new Result(CODE_SYS_ERROR, msg, null);
}
public static Result error(String code, String msg) {
return new Result(code, msg, null);
}
public static Result error() {
return new Result(CODE_SYS_ERROR, "系统错误", null);
}
}
加上loombk注解,可以省去构造方法等。
@Builder 是 Lombok 库中提供的一个注解,它可以用于自动创建建造者模式(Builder Pattern)相关的代码,以简化 Java 类的构建过程。
使用 @Builder 注解时,Lombok 会自动生成一个内部静态类,该类具有类中所有非静态字段(或称为属性)的 setter 方法,并返回一个构建该类对象的建造者实例。这样就可以通过链式调用方法来设置对象的属性,最后通过建造者的 build() 方法创建对象。
系统日志管理的实现
通过枚举类
public enum LogType {
ADD("新增"),UPDATE("修改"),DELETE("删除"), BATCH_DELETE("批量删除"),LOGIN("登录"),REGISTER("注册");
private String value;
public String getValue() {
return value;
}
LogType(String value) {
this.value = value;
}
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.entity.Logs;
import com.example.springboot.mapper.LogsMapper;
import org.springframework.stereotype.Service;
@Service
public class LogsService extends ServiceImpl<LogsMapper, Logs> {
}
@TableId(type = IdType.AUTO) 是 MyBatis-Plus 提供的一个注解,用于定义实体类的主键属性及其生成策略。
@TableId 注解用于标识实体类中作为主键的属性。
type = IdType.AUTO 参数指定了主键的生成策略为自动增长类型(Auto increment)。这意味着每次插入一条新的数据时,主键值会自动递增。
下面是一个示例代码,展示了如何在实体类中使用 @TableId(type = IdType.AUTO) 注解:
java
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
// other fields and methods...
}
在上述示例中,User 类中的 id 属性被标注为主键,并使用了 @TableId(type = IdType.AUTO) 注解。这意味着在数据库中,该主键属性将使用自动增长的方式生成。
通过将 @TableId 注解与 type = IdType.AUTO 参数结合使用,可以方便地定义实体类的主键属性及其生成策略,从而简化与数据库交互相关的代码。
需要注意的是,使用 @TableId(type = IdType.AUTO) 注解之前,需要确保已正确引入相关的依赖,并且遵循 MyBatis-Plus 的使用规则和约定。此外,生成的主键值的类型可能根据具体数据库的支持情况和配置而有所不同。
实现跨域功能
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(MAX_AGE);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
@HoneyLogs(operation = "文件", type = LogType.ADD) 是一个自定义注解的使用示例。
在这个例子中,@HoneyLogs 是一个自定义的注解。通过 @HoneyLogs(operation = "文件", type = LogType.ADD),我们给注解传递了两个参数的值:
operation = "文件" 表示注解的操作类型为 "文件"。
type = LogType.ADD 表示注解的日志类型为 LogType.ADD,也就是新增操作。
这个自定义注解的作用和功能需要根据具体的使用场景和代码实现来确定。通常情况下,自定义注解用于在代码中添加元数据,以标记方法、类或其他程序元素,并提供额外的信息给编译器、工具或运行时环境。
例如,在日志记录方面,我们可以使用自定义注解来标记需要记录日志的操作,以及日志的相关信息。在这个示例中,@HoneyLogs 注解可能用于标记文件相关的操作,如文件的新增、修改、删除等。通过在需要记录日志的方法上添加 @HoneyLogs 注解,我们可以获取到操作类型为 "文件",日志类型为新增的信息。
要使用 @HoneyLogs 注解,只需要在方法声明上添加 @HoneyLogs 注解,并传递相应的参数值。例如:
java
@HoneyLogs(operation = "文件", type = LogType.ADD)
public void addFile(File file) {
// Method implementation
}
请注意,在使用自定义注解之前,需要确保注解定义所在的包已经正确导入,并且遵循注解的特定使用规则和约定。同时,需要在程序中处理这些自定义注解,并根据注解的信息执行相应的逻辑,如记录日志、权限验证等。
批量导出数据
@GetMapping("/export")
public void exportData(@RequestParam(required = false) String username,
@RequestParam(required = false) String name,
@RequestParam(required = false) String ids, // 1,2,3,4,5
HttpServletResponse response) throws IOException {
ExcelWriter writer = ExcelUtil.getWriter(true);
List<User> list;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(ids)) { // ["1", "2", "3"] => [1,2,3]
List<Integer> idsArr1 = Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toList());
queryWrapper.in("id", idsArr1);
} else {
// 第一种全部导出或者条件导出
queryWrapper.like(StrUtil.isNotBlank(username), "username", username);
queryWrapper.like(StrUtil.isNotBlank(name), "name", name);
}
list = userService.list(queryWrapper); // 查询出当前User表的所有数据
writer.write(list, true);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户信息表", "UTF-8") + ".xlsx");
ServletOutputStream outputStream = response.getOutputStream();
writer.flush(outputStream, true);
writer.close();
outputStream.flush();
outputStream.close();
}
前端全局化变量
new 出来一个全局的对象
vue2的基本语法
这段代码是在 Vue 中创建根实例的一种常见方式。
new Vue({}) 创建了一个 Vue 实例。
router 是一个路由器对象,通过 router 参数将该路由器对象传递给 Vue 实例,以便在应用程序中使用 Vue Router 进行导航。
render: h => h(App) 定义了根组件的渲染函数。在这里,App 是根组件的名称,h 是 Vue 的内置 createElement 函数的别名。通过调用 h(App) 创建了 App 组件的实例。
$mount(‘#app’) 将根组件挂载到指定的 DOM 元素上,这里是 #app。挂载后,根组件将替换指定的 DOM 元素成为应用程序的根节点,这样根组件和其子组件就能够正常渲染和交互。
整体意思是创建了一个 Vue 实例,并将路由器对象和渲染函数配置给该实例。然后,将根组件挂载到指定的 DOM 元素上,最终完成 Vue 应用程序的初始化和渲染。
通常在 Vue 项目的主入口文件中会找到类似的代码。它表示了 Vue 实例的创建和挂载,以及与路由和根组件的关联。
生产和开发环境的地址需要分开。
requst请求的代码分析
import axios from 'axios' //引入axios
import router from "@/router"; //路由/省略了index.js 默认是index.js
// 创建可一个新的axios对象
const request = axios.create({
baseURL: process.env.VUE_APP_BASEURL, // 后端的接口地址
timeout: 30000 //相应的时间为30秒
})
// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
//发送的请求 config进行处理
//请求头携带content-type类型为json
config.headers['Content-Type'] = 'application/json;charset=utf-8';
let user = JSON.parse(localStorage.getItem("honey-user") || '{}')
config.headers['token'] = user.token // 设置请求头
return config
}, error => {
console.error('request error: ' + error) // for debug
return Promise.reject(error)
});
// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
response => {
let res = response.data;
// 兼容服务端返回的字符串数据
if (typeof res === 'string') {
res = res ? JSON.parse(res) : res //如果为字符串就解析为对象
}
//如果是未授权,那么就跳转到登录页面
if (res.code === '401') {
router.push('/login')
}
return res;
},
error => {
console.error('response error: ' + error) // for debug
return Promise.reject(error)
}
)
export default request //最后讲requst导出去