feat: 收入和支出图表展示
This commit is contained in:
parent
31ff32fe34
commit
ec36a45f34
|
@ -13,6 +13,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
public class BunnyException extends RuntimeException {
|
public class BunnyException extends RuntimeException {
|
||||||
Integer code;// 状态码
|
Integer code;// 状态码
|
||||||
String message;// 描述信息
|
String message;// 描述信息
|
||||||
|
ResultCodeEnum resultCodeEnum;
|
||||||
|
|
||||||
|
|
||||||
public BunnyException(Integer code, String message) {
|
public BunnyException(Integer code, String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -29,5 +31,6 @@ public class BunnyException extends RuntimeException {
|
||||||
super(codeEnum.getMessage());
|
super(codeEnum.getMessage());
|
||||||
this.code = codeEnum.getCode();
|
this.code = codeEnum.getCode();
|
||||||
this.message = codeEnum.getMessage();
|
this.message = codeEnum.getMessage();
|
||||||
|
this.resultCodeEnum = codeEnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.bunny.common.service.utils;
|
|
||||||
|
|
||||||
import cn.bunny.common.service.exception.BunnyException;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class EmptyUtil {
|
|
||||||
/**
|
|
||||||
* 是否为空
|
|
||||||
*
|
|
||||||
* @param value 判断值
|
|
||||||
* @param message 错误消息
|
|
||||||
*/
|
|
||||||
public static void isEmpty(Object value, String message) {
|
|
||||||
if (value == null || !StringUtils.hasText(value.toString())) {
|
|
||||||
log.error("为空对象错误:{},{}", value, message);
|
|
||||||
throw new BunnyException(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package cn.bunny.dao.dto.financial.bill;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "ExpendWithIncomeDto对象", title = "账单收入和支出查询表单", description = "账单收入和支出查询表单")
|
||||||
|
public class ExpendWithIncomeDto {
|
||||||
|
|
||||||
|
@Schema(name = "userId", title = "绑定的用户id")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(name = "type", title = "类型")
|
||||||
|
private Byte type;
|
||||||
|
|
||||||
|
@Schema(name = "startDate", title = "开始日期")
|
||||||
|
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||||
|
@NotNull(message = "日期不能为空")
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
@Schema(name = "endDate", title = "结束日期")
|
||||||
|
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||||
|
@NotNull(message = "日期不能为空")
|
||||||
|
private LocalDate endDate;
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ public enum ResultCodeEnum {
|
||||||
FILE_NOT_EXIST(206, "文件不存在"),
|
FILE_NOT_EXIST(206, "文件不存在"),
|
||||||
NEW_PASSWORD_SAME_OLD_PASSWORD(206, "新密码不能和旧密码相同"),
|
NEW_PASSWORD_SAME_OLD_PASSWORD(206, "新密码不能和旧密码相同"),
|
||||||
MISSING_TEMPLATE_FILES(206, "缺少模板文件"),
|
MISSING_TEMPLATE_FILES(206, "缺少模板文件"),
|
||||||
THE_MAXIMUM_BAR_CODE(206, "最大条码为50"),
|
THE_MAXIMUM_BAR_CODE(206, "超过最大上限"),
|
||||||
|
|
||||||
// 身份过期 208
|
// 身份过期 208
|
||||||
LOGIN_AUTH(208, "请先登陆"),
|
LOGIN_AUTH(208, "请先登陆"),
|
||||||
|
@ -65,15 +65,13 @@ public enum ResultCodeEnum {
|
||||||
ILLEGAL_DATA_REQUEST(219, "非法数据请求"),
|
ILLEGAL_DATA_REQUEST(219, "非法数据请求"),
|
||||||
CLASS_NOT_FOUND(219, "类名不存在"),
|
CLASS_NOT_FOUND(219, "类名不存在"),
|
||||||
ADMIN_ROLE_CAN_NOT_DELETED(219, "无法删除admin角色"),
|
ADMIN_ROLE_CAN_NOT_DELETED(219, "无法删除admin角色"),
|
||||||
|
ROUTER_RANK_NEED_LARGER_THAN_THE_PARENT(219, "设置路由等级需要大于或等于父级的路由等级"),
|
||||||
|
|
||||||
// 无权访问 403
|
// 无权访问 403
|
||||||
FAIL_REQUEST_NOT_AUTH(403, "用户未认证"),
|
|
||||||
FAIL_NO_ACCESS_DENIED(403, "无权访问"),
|
FAIL_NO_ACCESS_DENIED(403, "无权访问"),
|
||||||
FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"),
|
FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"),
|
||||||
LOGGED_IN_FROM_ANOTHER_DEVICE(403, "没有权限访问"),
|
|
||||||
TOKEN_PARSING_FAILED(403, "token解析失败"),
|
TOKEN_PARSING_FAILED(403, "token解析失败"),
|
||||||
FAIL_NO_ACCESS_DENIED_USER_LOCKED(403, "该账户已封禁"),
|
FAIL_NO_ACCESS_DENIED_USER_LOCKED(403, "该账户已封禁"),
|
||||||
ROUTER_RANK_NEED_LARGER_THAN_THE_PARENT(219, "设置路由等级需要大于或等于父级的路由等级"),
|
|
||||||
|
|
||||||
// 系统错误 500
|
// 系统错误 500
|
||||||
UNKNOWN_EXCEPTION(500, "服务异常"),
|
UNKNOWN_EXCEPTION(500, "服务异常"),
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.bunny.dao.vo.financial.user.expendAndIncome;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "ExpendWithIncomeVo对象", title = "账单收入和支出", description = "账单收入和支出")
|
||||||
|
public class CategoryAmount {
|
||||||
|
|
||||||
|
@Schema(name = "amount", title = "金额")
|
||||||
|
private Number amount;
|
||||||
|
|
||||||
|
@Schema(name = "categoryName", title = "分类名称")
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package cn.bunny.dao.vo.financial.user.expendAndIncome;
|
||||||
|
|
||||||
|
import cn.bunny.dao.common.vo.BaseVo;
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "ExpendWithIncomeVo对象", title = "账单收入和支出", description = "账单收入和支出")
|
||||||
|
public class ExpendWithIncome extends BaseVo {
|
||||||
|
|
||||||
|
@Schema(name = "username", title = "类型:1 - 收入,-1 - 支出")
|
||||||
|
private Byte type;
|
||||||
|
|
||||||
|
@Schema(name = "amount", title = "金额")
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
@Schema(name = "description", title = "描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(name = "categoryId", title = "分类Id")
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||||
|
@JSONField(serializeUsing = ToStringSerializer.class)
|
||||||
|
private String categoryId;
|
||||||
|
|
||||||
|
@Schema(name = "categoryName", title = "分类名称")
|
||||||
|
private String categoryName;
|
||||||
|
|
||||||
|
@Schema(name = "transactionDate", title = "交易日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@JsonSerialize(using = LocalDateTimeSerializer.class)
|
||||||
|
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
|
||||||
|
private LocalDateTime transactionDate;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package cn.bunny.dao.vo.financial.user.expendAndIncome;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "ExpendWithIncomeVo对象", title = "账单收入和支出", description = "账单收入和支出")
|
||||||
|
public class ExpendWithIncomeListVo {
|
||||||
|
|
||||||
|
@Schema(name = "list", title = "基础列表")
|
||||||
|
private List<ExpendWithIncome> list;
|
||||||
|
|
||||||
|
@Schema(name = "categoryList", title = "分类列表")
|
||||||
|
private List<CategoryAmount> categoryAmounts;
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.bunny.services.controller.financial;
|
package cn.bunny.services.controller.financial;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||||
|
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
||||||
|
@ -11,6 +12,7 @@ import cn.bunny.dao.pojo.result.Result;
|
||||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.financial.admin.BillVo;
|
import cn.bunny.dao.vo.financial.admin.BillVo;
|
||||||
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncomeListVo;
|
||||||
import cn.bunny.services.service.financial.BillService;
|
import cn.bunny.services.service.financial.BillService;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
@ -65,6 +67,13 @@ public class BillController {
|
||||||
return Mono.just(Result.success(pageResult));
|
return Mono.just(Result.success(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "账单收入和支出", description = "账单收入和支出")
|
||||||
|
@GetMapping("noManage/getExpendOrIncome")
|
||||||
|
public Mono<Result<ExpendWithIncomeListVo>> getExpendOrIncome(ExpendWithIncomeDto dto) {
|
||||||
|
ExpendWithIncomeListVo vo = billService.getExpendOrIncome(dto);
|
||||||
|
return Mono.just(Result.success(vo));
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "添加账单信息", description = "添加账单信息")
|
@Operation(summary = "添加账单信息", description = "添加账单信息")
|
||||||
@PostMapping("addBill")
|
@PostMapping("addBill")
|
||||||
public Mono<Result<String>> addBill(@Valid @RequestBody BillAddDto dto) {
|
public Mono<Result<String>> addBill(@Valid @RequestBody BillAddDto dto) {
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package cn.bunny.services.factory;
|
|
||||||
|
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class UserLoginLogFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户登录日志分页查询通用方法
|
|
||||||
*
|
|
||||||
* @param page 分页结果
|
|
||||||
* @return 分页用户登录日志
|
|
||||||
*/
|
|
||||||
public PageResult<UserLoginLogVo> getUserLoginLogVoPageResult(IPage<UserLoginLogVo> page) {
|
|
||||||
List<UserLoginLogVo> voList = page.getRecords().stream().map(userLoginLog -> {
|
|
||||||
UserLoginLogVo userLoginLogVo = new UserLoginLogVo();
|
|
||||||
BeanUtils.copyProperties(userLoginLog, userLoginLogVo);
|
|
||||||
return userLoginLogVo;
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
return PageResult.<UserLoginLogVo>builder()
|
|
||||||
.list(voList)
|
|
||||||
.pageNo(page.getCurrent())
|
|
||||||
.pageSize(page.getSize())
|
|
||||||
.total(page.getTotal())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,10 @@
|
||||||
package cn.bunny.services.mapper.financial;
|
package cn.bunny.services.mapper.financial;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||||
|
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||||
import cn.bunny.dao.entity.financial.Bill;
|
import cn.bunny.dao.entity.financial.Bill;
|
||||||
import cn.bunny.dao.vo.financial.admin.BillVo;
|
import cn.bunny.dao.vo.financial.admin.BillVo;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -37,4 +39,12 @@ public interface BillMapper extends BaseMapper<Bill> {
|
||||||
* @return 账单信息分页结果
|
* @return 账单信息分页结果
|
||||||
*/
|
*/
|
||||||
IPage<BillVo> selectListByPage(@Param("page") Page<Bill> pageParams, @Param("dto") BillDto dto);
|
IPage<BillVo> selectListByPage(@Param("page") Page<Bill> pageParams, @Param("dto") BillDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账单收入和支出
|
||||||
|
*
|
||||||
|
* @param dto 请求表单
|
||||||
|
* @return 账单收入和支出
|
||||||
|
*/
|
||||||
|
List<ExpendWithIncome> selectListByExpendWithIncomeDto(@Param("dto") ExpendWithIncomeDto dto);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,14 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableMethodSecurity
|
@EnableMethodSecurity
|
||||||
public class WebSecurityConfig {
|
public class WebSecurityConfig {
|
||||||
|
|
||||||
|
public static String[] annotations = {
|
||||||
|
"/", "/ws/**",
|
||||||
|
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
|
||||||
|
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "/swagger-ui/**",
|
||||||
|
"/error", "/*/i18n/getI18n",
|
||||||
|
};
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@ -40,12 +48,6 @@ public class WebSecurityConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||||
String[] annotations = {
|
|
||||||
"/", "/ws/**",
|
|
||||||
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
|
|
||||||
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
|
|
||||||
"/error", "/*/i18n/getI18n",
|
|
||||||
};
|
|
||||||
httpSecurity
|
httpSecurity
|
||||||
// 前端段分离不需要---禁用明文验证
|
// 前端段分离不需要---禁用明文验证
|
||||||
.httpBasic(AbstractHttpConfigurer::disable)
|
.httpBasic(AbstractHttpConfigurer::disable)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.bunny.services.security.custom;
|
||||||
|
|
||||||
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理与认证相关的异常
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@Slf4j
|
||||||
|
public class CustomAuthenticationException extends AuthenticationException {
|
||||||
|
ResultCodeEnum resultCodeEnum;
|
||||||
|
|
||||||
|
public CustomAuthenticationException(ResultCodeEnum codeEnum) {
|
||||||
|
super(codeEnum.getMessage());
|
||||||
|
this.resultCodeEnum = codeEnum;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package cn.bunny.services.security.handelr;
|
||||||
import cn.bunny.common.service.utils.ResponseUtil;
|
import cn.bunny.common.service.utils.ResponseUtil;
|
||||||
import cn.bunny.dao.pojo.result.Result;
|
import cn.bunny.dao.pojo.result.Result;
|
||||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
|
import cn.bunny.services.security.custom.CustomAuthenticationException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -10,26 +11,20 @@ import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求未认证接口
|
* 自定义请求未认证接口异常
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
@Override
|
@Override
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
|
||||||
String token = request.getHeader("token");
|
|
||||||
String message = authException.getMessage();
|
|
||||||
// 创建结果对象
|
|
||||||
Result<Object> result;
|
Result<Object> result;
|
||||||
|
|
||||||
if (token == null) {
|
if (authException instanceof CustomAuthenticationException customException) {
|
||||||
result = Result.error(ResultCodeEnum.LOGIN_AUTH);
|
result = Result.error(customException.getResultCodeEnum());
|
||||||
log.info("请求未登录接口:{},用户id:{}", message, null);
|
|
||||||
} else {
|
} else {
|
||||||
result = Result.error(ResultCodeEnum.LOGGED_IN_FROM_ANOTHER_DEVICE);
|
result = Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED);
|
||||||
log.info("请求未授权接口:{},用户id:{}", message, token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回响应
|
|
||||||
ResponseUtil.out(response, result);
|
ResponseUtil.out(response, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,14 @@ import cn.bunny.common.service.utils.JwtHelper;
|
||||||
import cn.bunny.dao.entity.system.Power;
|
import cn.bunny.dao.entity.system.Power;
|
||||||
import cn.bunny.dao.entity.system.Role;
|
import cn.bunny.dao.entity.system.Role;
|
||||||
import cn.bunny.dao.pojo.constant.RedisUserConstant;
|
import cn.bunny.dao.pojo.constant.RedisUserConstant;
|
||||||
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.user.LoginVo;
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
import cn.bunny.services.mapper.system.PowerMapper;
|
import cn.bunny.services.mapper.system.PowerMapper;
|
||||||
import cn.bunny.services.mapper.system.RoleMapper;
|
import cn.bunny.services.mapper.system.RoleMapper;
|
||||||
|
import cn.bunny.services.security.custom.CustomAuthenticationException;
|
||||||
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
|
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
@ -44,21 +45,21 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
@Override
|
@Override
|
||||||
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
|
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
|
||||||
|
|
||||||
// 用户的token和用户id、请求Url
|
// 用户的token和用户id、请求Url
|
||||||
HttpServletRequest request = context.getRequest();
|
HttpServletRequest request = context.getRequest();
|
||||||
|
|
||||||
// 判断是否有 token
|
// 判断是否有 token
|
||||||
String token = request.getHeader("token");
|
String token = request.getHeader("token");
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
return new AuthorizationDecision(false);
|
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断 token 是否过期
|
// 判断 token 是否过期
|
||||||
if (JwtHelper.isExpired(token)) {
|
if (JwtHelper.isExpired(token)) {
|
||||||
return new AuthorizationDecision(false);
|
throw new CustomAuthenticationException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析JWT中的用户名
|
// 解析JWT中的用户名
|
||||||
|
@ -71,12 +72,12 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
|
|
||||||
// 登录信息为空
|
// 登录信息为空
|
||||||
if (loginVo == null) {
|
if (loginVo == null) {
|
||||||
return new AuthorizationDecision(false);
|
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断用户是否禁用
|
// 判断用户是否禁用
|
||||||
if (loginVo.getStatus()) {
|
if (loginVo.getStatus()) {
|
||||||
return new AuthorizationDecision(false);
|
throw new CustomAuthenticationException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置用户信息
|
// 设置用户信息
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.bunny.services.service.financial;
|
package cn.bunny.services.service.financial;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||||
|
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
||||||
|
@ -9,6 +10,7 @@ import cn.bunny.dao.entity.financial.Bill;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.financial.admin.BillVo;
|
import cn.bunny.dao.vo.financial.admin.BillVo;
|
||||||
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncomeListVo;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
@ -79,4 +81,12 @@ public interface BillService extends IService<Bill> {
|
||||||
* @param dto 更新表单
|
* @param dto 更新表单
|
||||||
*/
|
*/
|
||||||
void updateUserBill(BillUpdateUserDto dto);
|
void updateUserBill(BillUpdateUserDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账单收入和支出
|
||||||
|
*
|
||||||
|
* @param dto 请求表单
|
||||||
|
* @return 账单收入和支出
|
||||||
|
*/
|
||||||
|
ExpendWithIncomeListVo getExpendOrIncome(ExpendWithIncomeDto dto);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cn.bunny.services.service.financial.impl;
|
||||||
import cn.bunny.common.service.context.BaseContext;
|
import cn.bunny.common.service.context.BaseContext;
|
||||||
import cn.bunny.common.service.exception.BunnyException;
|
import cn.bunny.common.service.exception.BunnyException;
|
||||||
import cn.bunny.dao.dto.financial.bill.BillDto;
|
import cn.bunny.dao.dto.financial.bill.BillDto;
|
||||||
|
import cn.bunny.dao.dto.financial.bill.ExpendWithIncomeDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillAddDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
import cn.bunny.dao.dto.financial.bill.admin.BillUpdateDto;
|
||||||
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
import cn.bunny.dao.dto.financial.bill.user.BillAddUserDto;
|
||||||
|
@ -12,6 +13,9 @@ import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.financial.admin.BillVo;
|
import cn.bunny.dao.vo.financial.admin.BillVo;
|
||||||
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
import cn.bunny.dao.vo.financial.user.BillUserVo;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.CategoryAmount;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome;
|
||||||
|
import cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncomeListVo;
|
||||||
import cn.bunny.services.mapper.financial.BillMapper;
|
import cn.bunny.services.mapper.financial.BillMapper;
|
||||||
import cn.bunny.services.service.financial.BillService;
|
import cn.bunny.services.service.financial.BillService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
@ -22,6 +26,7 @@ import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -144,6 +149,41 @@ public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements Bi
|
||||||
updateById(bill);
|
updateById(bill);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 账单收入和支出
|
||||||
|
*
|
||||||
|
* @param dto 请求表单
|
||||||
|
* @return 账单收入和支出
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ExpendWithIncomeListVo getExpendOrIncome(ExpendWithIncomeDto dto) {
|
||||||
|
// 判断请求用户id是否为空
|
||||||
|
if (dto.getUserId() == null) {
|
||||||
|
dto.setUserId(BaseContext.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询收入和支出
|
||||||
|
List<ExpendWithIncome> expendWithIncomeList = baseMapper.selectListByExpendWithIncomeDto(dto);
|
||||||
|
|
||||||
|
// 分类列表
|
||||||
|
List<CategoryAmount> categoryAmountList = expendWithIncomeList.stream()
|
||||||
|
.filter(expendWithIncome -> dto.getType() != null && expendWithIncome.getType().equals(dto.getType()))
|
||||||
|
.collect(Collectors.groupingBy(ExpendWithIncome::getCategoryName,
|
||||||
|
Collectors.summingDouble(expend -> expend.getAmount().doubleValue()))
|
||||||
|
).entrySet()
|
||||||
|
.stream().map(expendWithIncome -> {
|
||||||
|
CategoryAmount categoryAmount = new CategoryAmount();
|
||||||
|
categoryAmount.setCategoryName(expendWithIncome.getKey());
|
||||||
|
categoryAmount.setAmount(expendWithIncome.getValue());
|
||||||
|
return categoryAmount;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return ExpendWithIncomeListVo.builder()
|
||||||
|
.categoryAmounts(categoryAmountList)
|
||||||
|
.list(expendWithIncomeList)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除|批量删除账单信息
|
* 删除|批量删除账单信息
|
||||||
*
|
*
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class RolePowerServiceImpl extends ServiceImpl<RolePowerMapper, RolePower
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleFactory roleFactory;
|
private RoleFactory roleFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRoleMapper userRoleMapper;
|
private UserRoleMapper userRoleMapper;
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,12 @@ import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogLocalVo;
|
import cn.bunny.dao.vo.log.UserLoginLogLocalVo;
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
import cn.bunny.services.factory.UserLoginLogFactory;
|
|
||||||
import cn.bunny.services.mapper.system.UserLoginLogMapper;
|
import cn.bunny.services.mapper.system.UserLoginLogMapper;
|
||||||
import cn.bunny.services.service.system.UserLoginLogService;
|
import cn.bunny.services.service.system.UserLoginLogService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -31,9 +29,6 @@ import java.util.List;
|
||||||
@Transactional
|
@Transactional
|
||||||
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserLoginLogFactory factory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 用户登录日志 服务实现类
|
* * 用户登录日志 服务实现类
|
||||||
*
|
*
|
||||||
|
@ -45,7 +40,18 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
|
||||||
public PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto) {
|
public PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto) {
|
||||||
IPage<UserLoginLogVo> page = baseMapper.selectListByPage(pageParams, dto);
|
IPage<UserLoginLogVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||||
|
|
||||||
return factory.getUserLoginLogVoPageResult(page);
|
List<UserLoginLogVo> voList = page.getRecords().stream().map(userLoginLog -> {
|
||||||
|
UserLoginLogVo userLoginLogVo = new UserLoginLogVo();
|
||||||
|
BeanUtils.copyProperties(userLoginLog, userLoginLogVo);
|
||||||
|
return userLoginLogVo;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return PageResult.<UserLoginLogVo>builder()
|
||||||
|
.list(voList)
|
||||||
|
.pageNo(page.getCurrent())
|
||||||
|
.pageSize(page.getSize())
|
||||||
|
.total(page.getTotal())
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
Long userId = JwtHelper.getUserId(dto.getRefreshToken());
|
Long userId = JwtHelper.getUserId(dto.getRefreshToken());
|
||||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
||||||
|
|
||||||
if (adminUser == null) throw new BunnyException(ResultCodeEnum.FAIL_REQUEST_NOT_AUTH);
|
if (adminUser == null) throw new BunnyException(ResultCodeEnum.USER_IS_EMPTY);
|
||||||
if (adminUser.getStatus()) throw new BunnyException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
if (adminUser.getStatus()) throw new BunnyException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
||||||
|
|
||||||
LoginVo buildUserVo = userFactory.buildLoginUserVo(adminUser, dto.getReadMeDay());
|
LoginVo buildUserVo = userFactory.buildLoginUserVo(adminUser, dto.getReadMeDay());
|
||||||
|
|
|
@ -16,20 +16,20 @@ logging:
|
||||||
|
|
||||||
bunny:
|
bunny:
|
||||||
master:
|
master:
|
||||||
host: 192.168.3.98
|
host: 192.168.3.129
|
||||||
port: 3304
|
port: 3304
|
||||||
database: family_financial
|
database: family_financial
|
||||||
username: root
|
username: root
|
||||||
password: "02120212"
|
password: "02120212"
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
host: 192.168.3.98
|
host: 192.168.3.129
|
||||||
port: 6379
|
port: 6379
|
||||||
database: 6
|
database: 6
|
||||||
password: "123456"
|
password: "123456"
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
endpointUrl: "http://192.168.3.98:9000"
|
endpointUrl: "http://192.168.3.129:9000"
|
||||||
accessKey: bunny
|
accessKey: bunny
|
||||||
secretKey: "02120212"
|
secretKey: "02120212"
|
||||||
bucket-name: financial
|
bucket-name: financial
|
||||||
|
|
|
@ -53,6 +53,24 @@
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 账单收入和支出 -->
|
||||||
|
<select id="selectListByExpendWithIncomeDto" resultType="cn.bunny.dao.vo.financial.user.expendAndIncome.ExpendWithIncome">
|
||||||
|
select *
|
||||||
|
from t_bill b left join t_category tc on b.category_id = tc.id
|
||||||
|
<where>
|
||||||
|
<if test="dto.userId != null and dto.userId != ''">
|
||||||
|
and b.user_id = #{dto.userId}
|
||||||
|
</if>
|
||||||
|
<if test="dto.type != null">
|
||||||
|
and b.type = #{dto.type}
|
||||||
|
</if>
|
||||||
|
<if test="dto.startDate != null and dto.endDate != null">
|
||||||
|
and b.transaction_date between #{dto.startDate} and #{dto.endDate}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by b.amount desc
|
||||||
|
</select>
|
||||||
|
|
||||||
<!-- 物理删除账单信息 -->
|
<!-- 物理删除账单信息 -->
|
||||||
<delete id="deleteBatchIdsWithPhysics">
|
<delete id="deleteBatchIdsWithPhysics">
|
||||||
delete
|
delete
|
||||||
|
|
Loading…
Reference in New Issue