Compare commits

..

1 Commits

Author SHA1 Message Date
yxz
a5f7e20891 新增团购枚举常量 2025-04-28 18:43:30 +08:00
399 changed files with 8782 additions and 3032 deletions

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.cpop</groupId> <groupId>com.cpop</groupId>
<artifactId>Cpop-Union</artifactId> <artifactId>Cpop-Union</artifactId>
<version>1.1.0</version> <version>1.0.0</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository --> <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>Cpop-Api</artifactId> <artifactId>Cpop-Api</artifactId>

View File

@ -1,6 +1,7 @@
package com.cpop.api.cloudDb.core.dto; package com.cpop.api.cloudDb.core.dto;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import io.swagger.models.auth.In;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;

View File

@ -3,6 +3,7 @@ package com.cpop.api.cloudDb.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudBrandDto; import com.cpop.api.cloudDb.core.dto.CloudBrandDto;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudClassCardDto; import com.cpop.api.cloudDb.core.dto.CloudClassCardDto;
import com.cpop.api.cloudDb.core.dto.CloudClassCardRecordDto; import com.cpop.api.cloudDb.core.dto.CloudClassCardRecordDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.entity.ExtendPage; import com.cpop.core.base.entity.ExtendPage;
import com.cpop.core.base.exception.ServiceException; import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;

View File

@ -5,7 +5,7 @@ import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudClassDto; import com.cpop.api.cloudDb.core.dto.CloudClassDto;
import com.cpop.api.cloudDb.core.dto.CloudClassStudentDto; import com.cpop.api.cloudDb.core.dto.CloudClassStudentDto;
import com.cpop.api.cloudDb.core.dto.CloudCourseDto; import com.cpop.api.cloudDb.core.dto.CloudCourseDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;

View File

@ -3,8 +3,10 @@ package com.cpop.api.cloudDb.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudCourseDto; import com.cpop.api.cloudDb.core.dto.CloudCourseDto;
import com.cpop.api.cloudDb.core.dto.CloudCourseStudentDto;
import com.cpop.api.cloudDb.core.dto.CloudCourseStudentListDto; import com.cpop.api.cloudDb.core.dto.CloudCourseStudentListDto;
import com.cpop.core.utils.StringUtils; import com.cpop.api.cloudDb.core.dto.CloudCustomerDto;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudCustomerDto; import com.cpop.api.cloudDb.core.dto.CloudCustomerDto;
import com.cpop.api.cloudDb.core.dto.CloudStudentDto; import com.cpop.api.cloudDb.core.dto.CloudStudentDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -3,7 +3,7 @@ package com.cpop.api.cloudDb.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudOrderDto; import com.cpop.api.cloudDb.core.dto.CloudOrderDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.entity.ExtendPage; import com.cpop.core.base.entity.ExtendPage;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;

View File

@ -2,8 +2,9 @@ package com.cpop.api.cloudDb.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudClassDto;
import com.cpop.api.cloudDb.core.dto.CloudStaffDto; import com.cpop.api.cloudDb.core.dto.CloudStaffDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;

View File

@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
import com.cpop.api.cloudDb.core.constant.CloudDbUrl; import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
import com.cpop.api.cloudDb.core.dto.CloudStoreActiveDto; import com.cpop.api.cloudDb.core.dto.CloudStoreActiveDto;
import com.cpop.api.cloudDb.core.dto.CloudStoreDto; import com.cpop.api.cloudDb.core.dto.CloudStoreDto;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.exception.UtilException; import com.cpop.core.base.exception.UtilException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,9 +1,14 @@
package com.cpop.api.tencent.location.handler; package com.cpop.api.tencent.location.handler;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.tencent.location.core.constant.TencentApiUrl; import com.cpop.api.tencent.location.core.constant.TencentApiUrl;
import com.cpop.common.utils.http.HttpUtils;
import com.cpop.core.base.exception.UtilException;
import com.cpop.core.utils.SpringUtils; import com.cpop.core.utils.SpringUtils;
import okhttp3.Response;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.io.IOException; import java.io.IOException;

View File

@ -3,7 +3,7 @@ package com.cpop.api.tencent.wxWork.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.api.tencent.wxWork.core.config.WxWorkApiConfig; import com.cpop.api.tencent.wxWork.core.config.WxWorkApiConfig;
import com.cpop.api.tencent.wxWork.webHook.WebHookSendTextRequest; import com.cpop.api.tencent.wxWork.webHook.WebHookSendTextRequest;
import com.cpop.core.utils.http.HttpUtils; import com.cpop.common.utils.http.HttpUtils;
import okhttp3.*; import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.cpop</groupId> <groupId>com.cpop</groupId>
<artifactId>Cpop-Union</artifactId> <artifactId>Cpop-Union</artifactId>
<version>1.1.0</version> <version>1.0.0</version>
</parent> </parent>
<artifactId>Cpop-ClockIn-Demo</artifactId> <artifactId>Cpop-ClockIn-Demo</artifactId>

View File

@ -1,7 +1,7 @@
package com.cpop.clockin.business.bo; package com.cpop.clockin.business.bo;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.annotations.ApiModel;
import lombok.Data; import lombok.Data;
/** /**
@ -10,7 +10,7 @@ import lombok.Data;
* @Version: 1.0 * @Version: 1.0
*/ */
@Data @Data
@Schema(description = "打卡记录VO") @ApiModel(value = "打卡记录VO")
public class ClockInRecordBo { public class ClockInRecordBo {
@ExcelProperty(value = "姓名") @ExcelProperty(value = "姓名")
private String staffName; private String staffName;

View File

@ -1,10 +1,7 @@
package com.cpop.clockin.business.controller; package com.cpop.clockin.business.controller;
import com.cpop.core.base.entity.R; import com.cpop.core.base.R;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -16,6 +13,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import com.cpop.clockin.business.entity.Classes; import com.cpop.clockin.business.entity.Classes;
import com.cpop.clockin.business.service.ClassesService; import com.cpop.clockin.business.service.ClassesService;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@ -26,7 +26,7 @@ import java.util.List;
* @since 2024-01-23 * @since 2024-01-23
*/ */
@RestController @RestController
@Tag(name = "打卡班次表接口") @Api(tags = "打卡班次表接口")
@RequestMapping("/backstage/classes") @RequestMapping("/backstage/classes")
public class ClassesController { public class ClassesController {
@ -40,8 +40,8 @@ public class ClassesController {
* @return {@code true} 添加成功{@code false} 添加失败 * @return {@code true} 添加成功{@code false} 添加失败
*/ */
@PostMapping("/save") @PostMapping("/save")
@Operation(summary = "保存打卡班次表") @ApiOperation("保存打卡班次表")
public R<Void> save(@RequestBody @Parameter(description = "打卡班次表") Classes classes) { public R<Void> save(@RequestBody @ApiParam("打卡班次表") Classes classes) {
classesService.save(classes); classesService.save(classes);
return R.ok(); return R.ok();
} }
@ -53,8 +53,8 @@ public class ClassesController {
* @return {@code true} 删除成功{@code false} 删除失败 * @return {@code true} 删除成功{@code false} 删除失败
*/ */
@DeleteMapping("/remove/{id}") @DeleteMapping("/remove/{id}")
@Operation(summary = "根据主键删除打卡班次表") @ApiOperation("根据主键删除打卡班次表")
public R<Void> remove(@PathVariable @Parameter(description = "打卡班次表主键") Serializable id) { public R<Void> remove(@PathVariable @ApiParam("打卡班次表主键") Serializable id) {
classesService.removeById(id); classesService.removeById(id);
return R.ok(); return R.ok();
} }
@ -66,8 +66,8 @@ public class ClassesController {
* @return {@code true} 更新成功{@code false} 更新失败 * @return {@code true} 更新成功{@code false} 更新失败
*/ */
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "根据主键更新打卡班次表") @ApiOperation("根据主键更新打卡班次表")
public R<Void> update(@RequestBody @Parameter(description = "打卡班次表主键") Classes classes) { public R<Void> update(@RequestBody @ApiParam("打卡班次表主键") Classes classes) {
classesService.updateById(classes); classesService.updateById(classes);
return R.ok(); return R.ok();
} }
@ -78,7 +78,7 @@ public class ClassesController {
* @return 所有数据 * @return 所有数据
*/ */
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "查询所有打卡班次表") @ApiOperation("查询所有打卡班次表")
public R<List<Classes>> list() { public R<List<Classes>> list() {
return R.ok(classesService.list()); return R.ok(classesService.list());
} }
@ -90,8 +90,8 @@ public class ClassesController {
* @return 打卡班次表详情 * @return 打卡班次表详情
*/ */
@GetMapping("/getInfo/{id}") @GetMapping("/getInfo/{id}")
@Operation(summary = "根据主键获取打卡班次表") @ApiOperation("根据主键获取打卡班次表")
public R<Classes> getInfo(@PathVariable @Parameter(description = "打卡班次表主键") Serializable id) { public R<Classes> getInfo(@PathVariable @ApiParam("打卡班次表主键") Serializable id) {
return R.ok(classesService.getById(id)); return R.ok(classesService.getById(id));
} }
@ -102,8 +102,8 @@ public class ClassesController {
* @return 分页对象 * @return 分页对象
*/ */
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "分页查询打卡班次表") @ApiOperation("分页查询打卡班次表")
public R<Page<Classes>> page(@Parameter(description = "分页信息") Page<Classes> page) { public R<Page<Classes>> page(@ApiParam("分页信息") Page<Classes> page) {
return R.ok(classesService.page(page)); return R.ok(classesService.page(page));
} }

View File

@ -4,16 +4,16 @@ import com.alibaba.excel.EasyExcel;
import com.cpop.clockin.business.bo.EmployeeAttendanceBo; import com.cpop.clockin.business.bo.EmployeeAttendanceBo;
import com.cpop.clockin.business.service.ClockInRecordService; import com.cpop.clockin.business.service.ClockInRecordService;
import com.cpop.clockin.framework.constant.ClockInConstant; import com.cpop.clockin.framework.constant.ClockInConstant;
import com.cpop.core.base.entity.R; import com.cpop.core.base.R;
import com.cpop.core.service.RedisService; import com.cpop.core.service.RedisService;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.annotations.ApiOperation;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.text.ParseException; import java.text.ParseException;
@ -27,7 +27,7 @@ import java.util.List;
* @Version: 1.0 * @Version: 1.0
*/ */
@RestController @RestController
@Tag(name = "打卡记录接口") @Api(tags = "打卡记录接口")
@RequestMapping("/backstage/clockInRecord") @RequestMapping("/backstage/clockInRecord")
public class ClockInRecordController { public class ClockInRecordController {
@Autowired @Autowired
@ -35,7 +35,7 @@ public class ClockInRecordController {
@Autowired @Autowired
private RedisService redisService; private RedisService redisService;
@PostMapping("/upload") @PostMapping("/upload")
@Operation(summary = "上传钉钉Excel表") @ApiOperation("上传钉钉Excel表")
public R<String> uploadRecord(@RequestParam("file") MultipartFile file) throws IOException, ParseException { public R<String> uploadRecord(@RequestParam("file") MultipartFile file) throws IOException, ParseException {
/* List<ClockInRecordBo> clockInRecordBoList = ; /* List<ClockInRecordBo> clockInRecordBoList = ;
// 将对象数据返回给前端*/ // 将对象数据返回给前端*/
@ -43,7 +43,7 @@ public class ClockInRecordController {
} }
@GetMapping("/output") @GetMapping("/output")
@Operation(summary = "导出表格") @ApiOperation("导出表格")
public void outPut(HttpServletResponse response) throws IOException { public void outPut(HttpServletResponse response) throws IOException {
String manTimeJson = redisService.getCacheObject(ClockInConstant.MAN_TIME_JSON); String manTimeJson = redisService.getCacheObject(ClockInConstant.MAN_TIME_JSON);
/*byte[] bytes = manTimeJson.getBytes(); /*byte[] bytes = manTimeJson.getBytes();

View File

@ -3,14 +3,14 @@ package com.cpop.clockin.business.controller;
import com.cpop.clockin.business.dto.StaffClassesDto; import com.cpop.clockin.business.dto.StaffClassesDto;
import com.cpop.clockin.business.service.StaffClassesService; import com.cpop.clockin.business.service.StaffClassesService;
import com.cpop.clockin.business.vo.StaffClassesVo; import com.cpop.clockin.business.vo.StaffClassesVo;
import com.cpop.core.base.entity.R; import com.cpop.core.base.R;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import com.cpop.clockin.business.entity.StaffClasses; import com.cpop.clockin.business.entity.StaffClasses;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@ -21,7 +21,7 @@ import java.util.List;
* @since 2024-01-23 * @since 2024-01-23
*/ */
@RestController @RestController
@Tag(name = "员工-班次关联表接口") @Api(tags = "员工-班次关联表接口")
@RequestMapping("/backstage/staffClasses") @RequestMapping("/backstage/staffClasses")
public class StaffClassesController { public class StaffClassesController {
@ -34,11 +34,11 @@ public class StaffClassesController {
* @author: Yxz * @author: Yxz
* @date: 2024/1/24 20:54 * @date: 2024/1/24 20:54
* @param: [staffClassesDto] * @param: [staffClassesDto]
* @return: com.cpop.core.base.entity.R<java.lang.Void> * @return: com.cpop.core.base.R<java.lang.Void>
**/ **/
@PostMapping("/save") @PostMapping("/save")
@Operation(summary = "保存员工-班次关联表") @ApiOperation("保存员工-班次关联表")
public R<Void> save(@RequestBody @Parameter(description = "员工-班次保存Dto") StaffClassesDto staffClassesDto) { public R<Void> save(@RequestBody @ApiParam("员工-班次保存Dto") StaffClassesDto staffClassesDto) {
staffClassesService.saveAll(staffClassesDto); staffClassesService.saveAll(staffClassesDto);
return R.ok(); return R.ok();
} }
@ -50,11 +50,11 @@ public class StaffClassesController {
* @author: Yxz * @author: Yxz
* @date: 2024/1/24 20:54 * @date: 2024/1/24 20:54
* @param: [staffClassesDto] * @param: [staffClassesDto]
* @return: com.cpop.core.base.entity.R<java.lang.Void> * @return: com.cpop.core.base.R<java.lang.Void>
**/ **/
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新员工-班次关联表") @ApiOperation("更新员工-班次关联表")
public R<Void> update(@RequestBody @Parameter(description = "员工-班次修改Dto") StaffClassesDto staffClassesDto) { public R<Void> update(@RequestBody @ApiParam("员工-班次修改Dto") StaffClassesDto staffClassesDto) {
staffClassesService.updateAll(staffClassesDto); staffClassesService.updateAll(staffClassesDto);
return R.ok(); return R.ok();
} }
@ -65,7 +65,7 @@ public class StaffClassesController {
* @return 所有数据 * @return 所有数据
*/ */
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "查询员工班次信息") @ApiOperation("查询员工班次信息")
public R<List<StaffClassesVo>> list() { public R<List<StaffClassesVo>> list() {
return R.ok(staffClassesService.getStaffClassesVolist()); return R.ok(staffClassesService.getStaffClassesVolist());
} }
@ -78,8 +78,8 @@ public class StaffClassesController {
* @return 员工-班次关联表详情 * @return 员工-班次关联表详情
*/ */
@GetMapping("/getInfo/{id}") @GetMapping("/getInfo/{id}")
@Operation(summary = "根据主键获取员工-班次关联表") @ApiOperation("根据主键获取员工-班次关联表")
public R<StaffClasses> getInfo(@PathVariable @Parameter(description = "员工-班次关联表主键") Serializable id) { public R<StaffClasses> getInfo(@PathVariable @ApiParam("员工-班次关联表主键") Serializable id) {
return R.ok(staffClassesService.getById(id)); return R.ok(staffClassesService.getById(id));
} }
@ -89,11 +89,11 @@ public class StaffClassesController {
* @author: Yxz * @author: Yxz
* @date: 2024/1/24 20:55 * @date: 2024/1/24 20:55
* @param: [staffName] * @param: [staffName]
* @return: com.cpop.core.base.entity.R<com.mybatisflex.core.paginate.Page<com.cpop.clockin.business.vo.StaffClassesVo>> * @return: com.cpop.core.base.R<com.mybatisflex.core.paginate.Page<com.cpop.clockin.business.vo.StaffClassesVo>>
**/ **/
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "分页查询员工-班次信息") @ApiOperation("分页查询员工-班次信息")
public R<Page<StaffClassesVo>> page( @Parameter(description = "员工名称") @RequestParam(value = "staffName", required = false)String staffName) { public R<Page<StaffClassesVo>> page( @ApiParam("员工名称") @RequestParam(value = "staffName", required = false)String staffName) {
return R.ok(staffClassesService.selectPage(staffName)); return R.ok(staffClassesService.selectPage(staffName));
} }

View File

@ -1,6 +1,7 @@
package com.cpop.clockin.business.dto; package com.cpop.clockin.business.dto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
/** /**
@ -9,10 +10,10 @@ import lombok.Data;
* @Version: 1.0 * @Version: 1.0
*/ */
@Data @Data
@Schema(description = "员工班次DTO") @ApiModel(value = "员工班次DTO")
public class StaffClassesDto { public class StaffClassesDto {
@Schema(description = "员工id") @ApiModelProperty(value = "员工id")
private String staffId; private String staffId;
@Schema(description = "班次id数组") @ApiModelProperty(value = "班次id数组")
private String[] classId; private String[] classId;
} }

View File

@ -8,8 +8,11 @@ import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -25,6 +28,7 @@ import lombok.experimental.Accessors;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "打卡班次表对象")
@Table(value = "cp_oam_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_oam_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class Classes extends BaseEntity implements Serializable { public class Classes extends BaseEntity implements Serializable {
@ -34,23 +38,29 @@ public class Classes extends BaseEntity implements Serializable {
/** /**
* 班次名称 * 班次名称
*/ */
@ApiModelProperty(value = "班次名称")
private String className; private String className;
/** /**
* 开始时间 * 开始时间
*/ */
@ApiModelProperty(value = "开始时间")
@JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8") @JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8")
private Date startTime; private Date startTime;
/** /**
* 结束时间 * 结束时间
*/ */
@ApiModelProperty(value = "结束时间")
@JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8") @JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8")
private Date endTime; private Date endTime;
/** /**
* 逻辑删除0否1是 * 逻辑删除0否1是
*/ */
@ApiModelProperty(value = "逻辑删除0否1是")
@Column(isLogicDelete = true) @Column(isLogicDelete = true)
private Integer isDelete; private Integer isDelete;

View File

@ -8,6 +8,8 @@ import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -23,68 +25,85 @@ import lombok.experimental.Accessors;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "部门表对象")
@Table(value = "cp_oam_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_oam_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class ClockInDept extends BaseEntity implements Serializable { public class ClockInDept extends BaseEntity implements Serializable {
/** /**
* 部门id * 部门id
*/ */
@ApiModelProperty(value = "部门id")
@Id @Id
private String id; private String id;
/** /**
* 父部门id * 父部门id
*/ */
@ApiModelProperty(value = "父部门id")
private String parentId; private String parentId;
/** /**
* 企微id * 企微id
*/ */
@ApiModelProperty(value = "企微id")
private Long wxCpId; private Long wxCpId;
/** /**
* 企微父id * 企微父id
*/ */
@ApiModelProperty(value = "企微父id")
private Long wxCpParentId; private Long wxCpParentId;
/** /**
* 部门名称 * 部门名称
*/ */
@ApiModelProperty(value = "部门名称")
private String name; private String name;
/** /**
* 排序 * 排序
*/ */
@ApiModelProperty(value = "排序")
private Integer orderNo; private Integer orderNo;
/** /**
* 负责人 * 负责人
*/ */
@ApiModelProperty(value = "负责人")
private String leader; private String leader;
/** /**
* 电话 * 电话
*/ */
@ApiModelProperty(value = "电话")
private String phone; private String phone;
/** /**
* 邮箱 * 邮箱
*/ */
@ApiModelProperty(value = "邮箱")
private String email; private String email;
/** /**
* 部门状态:1正常,0停用 * 部门状态:1正常,0停用
*/ */
@ApiModelProperty(value = "部门状态:1正常,0停用")
private Boolean status; private Boolean status;
/** /**
* 备注 * 备注
*/ */
@ApiModelProperty(value = "备注")
private String remark; private String remark;
/** /**
* 逻辑删除(0否1是) * 逻辑删除(0否1是)
*/ */
@ApiModelProperty(value = "逻辑删除(0否1是)")
@Column(isLogicDelete = true) @Column(isLogicDelete = true)
private Boolean isDelete; private Boolean isDelete;

View File

@ -8,6 +8,8 @@ import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -23,48 +25,61 @@ import lombok.experimental.Accessors;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "员工表对象")
@Table(value = "cp_oam_staff", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_oam_staff", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class ClockInStaff extends BaseEntity implements Serializable { public class ClockInStaff extends BaseEntity implements Serializable {
/** /**
* 主键 * 主键
*/ */
@ApiModelProperty(value = "主键")
@Id @Id
private String id; private String id;
/** /**
* 姓名 * 姓名
*/ */
@ApiModelProperty(value = "姓名")
private String name; private String name;
/** /**
* 用户id * 用户id
*/ */
@ApiModelProperty(value = "用户id")
private String userId; private String userId;
/** /**
* 员工类型(0:技术人员;1:售后人员;2:管理人员) * 员工类型(0:技术人员;1:售后人员;2:管理人员)
*/ */
@ApiModelProperty(value = "员工类型(0:技术人员;1:售后人员;2:管理人员)")
private Integer staffType; private Integer staffType;
/** /**
* 角色id * 角色id
*/ */
@ApiModelProperty(value = "角色id")
private String roleId; private String roleId;
/** /**
* 微信用userId * 微信用userId
*/ */
@ApiModelProperty(value = "微信用userId")
private String wxCpUserId; private String wxCpUserId;
/** /**
* 是否是运维账号 * 是否是运维账号
*/ */
@ApiModelProperty(value = "是否是运维账号")
private Boolean isOperation; private Boolean isOperation;
/** /**
* 逻辑删除(0否1是) * 逻辑删除(0否1是)
*/ */
@ApiModelProperty(value = "逻辑删除(0否1是)")
@Column(isLogicDelete = true) @Column(isLogicDelete = true)
private Boolean isDelete; private Boolean isDelete;

View File

@ -6,6 +6,8 @@ import com.cpop.core.base.entity.BaseUpdateListener;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -21,17 +23,20 @@ import lombok.experimental.Accessors;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "Oam-员工-用户中间表对象")
@Table(value = "cp_oam_staff_mid_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_oam_staff_mid_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class ClockInStaffMidDept extends BaseEntity implements Serializable { public class ClockInStaffMidDept extends BaseEntity implements Serializable {
/** /**
* 员工id * 员工id
*/ */
@ApiModelProperty(value = "员工id")
private String staffId; private String staffId;
/** /**
* 部门id * 部门id
*/ */
@ApiModelProperty(value = "部门id")
private String deptId; private String deptId;

View File

@ -7,6 +7,9 @@ import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@ -22,6 +25,7 @@ import lombok.experimental.Accessors;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@ApiModel(value = "员工-班次关联表对象")
@Table(value = "cp_oam_staff_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_oam_staff_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class StaffClasses extends BaseEntity implements Serializable { public class StaffClasses extends BaseEntity implements Serializable {
@ -31,16 +35,23 @@ public class StaffClasses extends BaseEntity implements Serializable {
/** /**
* 员工id * 员工id
*/ */
@ApiModelProperty(value = "员工id")
private String staffId; private String staffId;
/** /**
* 班次id * 班次id
*/ */
@ApiModelProperty(value = "班次id")
private String classId; private String classId;
/** /**
* 逻辑删除0否1是 * 逻辑删除0否1是
*/ */
@ApiModelProperty(value = "逻辑删除0否1是")
@Column(isLogicDelete = true) @Column(isLogicDelete = true)
private Integer isDelete; private Integer isDelete;

View File

@ -8,9 +8,13 @@ import com.cpop.clockin.business.service.*;
import com.cpop.clockin.business.vo.ClassesVo; import com.cpop.clockin.business.vo.ClassesVo;
import com.cpop.clockin.business.vo.StaffClassesVo; import com.cpop.clockin.business.vo.StaffClassesVo;
import com.cpop.core.base.entity.PageDomain; import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.utils.SqlUtils; import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.cpop.clockin.business.mapper.StaffClassesMapper; import com.cpop.clockin.business.mapper.StaffClassesMapper;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -21,6 +25,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.mybatisflex.core.query.QueryMethods.groupConcat;
/** /**
* 员工-班次关联表 服务层实现 * 员工-班次关联表 服务层实现
* *

View File

@ -1,6 +1,7 @@
package com.cpop.clockin.business.vo; package com.cpop.clockin.business.vo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
/** /**
@ -8,15 +9,15 @@ import lombok.Data;
* @Date: 2024/1/23 18:56 * @Date: 2024/1/23 18:56
* @Version: 1.0 * @Version: 1.0
*/ */
@Schema(description = "班次VO") @ApiModel(value = "班次VO")
@Data @Data
public class ClassesVo { public class ClassesVo {
@Schema(description = "班次Id") @ApiModelProperty(value = "班次Id")
private String id; private String id;
/** /**
* 班次名称 * 班次名称
*/ */
@Schema(description = "班次名称") @ApiModelProperty(value = "班次名称")
private String className; private String className;
} }

View File

@ -1,6 +1,8 @@
package com.cpop.clockin.business.vo; package com.cpop.clockin.business.vo;
import io.swagger.v3.oas.annotations.media.Schema; import com.mybatisflex.annotation.RelationOneToMany;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -10,18 +12,18 @@ import java.util.List;
* @Date: 2024/1/23 17:45 * @Date: 2024/1/23 17:45
* @Version: 1.0 * @Version: 1.0
*/ */
@Schema(description = "员工班次关联VO") @ApiModel(value = "员工班次关联VO")
@Data @Data
public class StaffClassesVo { public class StaffClassesVo {
@Schema(description = "员工Id") @ApiModelProperty("员工Id")
private String staffId; private String staffId;
@Schema(description = "员工名称") @ApiModelProperty("员工名称")
private String staffName; private String staffName;
@Schema(description = "部门名称") @ApiModelProperty("部门名称")
private String deptName; private String deptName;
@Schema(description = "考勤班次名称") @ApiModelProperty("考勤班次名称")
private String className; private String className;
@Schema(description = "考勤班次集合") @ApiModelProperty("考勤班次集合")
private List<ClassesVo> classesVoList; private List<ClassesVo> classesVoList;
} }

55
Cpop-Common/pom.xml Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cpop</groupId>
<artifactId>Cpop-Union</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>Cpop-Common</artifactId>
<name>Cpop-Common</name>
<description>公共包</description>
<packaging>jar</packaging>
<dependencies>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/commons-io/commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- 时间工具类 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- okhttp3 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,4 +1,4 @@
package com.cpop.core.constant; package com.cpop.common.constant;
/** /**
* 通用常量信息 * 通用常量信息
@ -51,7 +51,7 @@ public interface Constants {
/** /**
* 通用失败标识 * 通用失败标识
*/ */
Integer FAIL = 500; Integer FAIL = 400;
/** /**
* 登录成功 * 登录成功
@ -141,7 +141,7 @@ public interface Constants {
/** /**
* 参数管理 cache key * 参数管理 cache key
*/ */
String CONFIG_KEY = "config:"; String SYS_CONFIG_KEY = "sys_config:";
/** /**
* 字典管理 cache key * 字典管理 cache key
@ -172,17 +172,12 @@ public interface Constants {
/** /**
* 超级管理员 * 超级管理员
*/ */
String SUPER_ADMIN = "Jambox"; String SUPER_ADMIN = "Cpop";
/** /**
* 超级管理员ID * 超级管理员ID
*/ */
String SUPER_ADMIN_ID = "100"; String SUPER_ADMIN_ID = "1";
/**
* 超级身份id
*/
String SUPER_IDENTITY_AUTH_ID = "100";
/** /**
* 超级管理员 * 超级管理员
@ -192,12 +187,12 @@ public interface Constants {
/** /**
* 所有权限 * 所有权限
*/ */
String ALL_PERMISSION = "*"; String ALL_PERMISSION = "*:*:*";
/** /**
* 隐藏菜单 * 隐藏菜单
*/ */
String HIDE_MENU = "System,Menu,Dict"; String HIDE_MENU = "Menu";
/** /**
* 用户类型 * 用户类型

View File

@ -1,4 +1,4 @@
package com.cpop.core.constant; package com.cpop.common.constant;
/** /**
* 返回状态码 * 返回状态码
@ -85,9 +85,4 @@ public interface HttpStatus {
* 接口未实现 * 接口未实现
*/ */
int NOT_IMPLEMENTED = 501; int NOT_IMPLEMENTED = 501;
/**
* 校区过期
*/
int STORE_EXPIRE = 10000;
} }

View File

@ -1,4 +1,4 @@
package com.cpop.core.constant; package com.cpop.common.constant;
/** /**
* @author DB * @author DB

View File

@ -1,4 +1,4 @@
package com.cpop.core.base.enums; package com.cpop.common.enums;
/** /**
* @author DB * @author DB

View File

@ -1,11 +1,8 @@
package com.cpop.core.base.enums; package com.cpop.common.enums;
import lombok.Getter;
/** /**
* @author LOST.yuan * @author LOST.yuan
*/ */
@Getter
public enum ErrorCodeEnum { public enum ErrorCodeEnum {
/** jwt凭据已过期 */ /** jwt凭据已过期 */
@ -70,6 +67,14 @@ public enum ErrorCodeEnum {
this.info = info; this.info = info;
} }
public Integer getCode() {
return code;
}
public String getInfo() {
return info;
}
public static ErrorCodeEnum codeOf(Integer code) { public static ErrorCodeEnum codeOf(Integer code) {
for (ErrorCodeEnum value : values()) { for (ErrorCodeEnum value : values()) {
if (value.getCode().equals(code)) { if (value.getCode().equals(code)) {

View File

@ -0,0 +1,653 @@
package com.cpop.common.utils;
import com.cpop.common.enums.CycleEnum;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 时间工具类
*
* @author DB
*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YYYYMMDD = "yyyyMMdd";
public static String TIME = "HH:mm:ss";
/**
* yyyy-MM-dd HH:mm
*/
public final static String DATE_TIME_HOUR_MINUTE = "yyyy-MM-dd HH:mm";
private static final String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
public final static String HOUR = "HH:mm";
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate() {
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate() {
return dateTimeNow(YYYY_MM_DD);
}
public static String getTime() {
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static String dateTimeNow() {
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static String dateTimeNow(final String format) {
return parseDateToStr(format, new Date());
}
public static String dateTime(final Date date) {
return parseDateToStr(YYYY_MM_DD, date);
}
public static String parseDateToStr(final String format, final Date date) {
return new SimpleDateFormat(format).format(date);
}
public static Date dateTime(final String format, final String ts) {
try {
return new SimpleDateFormat(format).parse(ts);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年// 如2018/08/08
*/
public static String datePath() {
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年// 如20180808
*/
public static String dateTime() {
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str) {
if (str == null) {
return null;
}
try {
return parseDate(str.toString(), parsePatterns);
} catch (ParseException e) {
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate) {
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟";
}
/**
* 对日期的进行加/
*
* @param date 日期
* @param months 月数负数为减
* @return /减几月后的日期
*/
public static Date addDateMonths(Date date, int months) {
DateTime dateTime = new DateTime(date);
return dateTime.plusMonths(months).toDate();
}
/**
* 获取指定时间前一天的时间
*
* @param date
* @return
* @Author: ZJ
*/
public static Date getLasDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
return calendar.getTime();
}
/**
* 对日期的进行加/
*
* @param date 日期
* @param days 天数负数为减
* @return /减几天后的日期
*/
public static Date addDateDays(Date date, int days) {
DateTime dateTime = new DateTime(date);
return dateTime.plusDays(days).toDate();
}
/**
* 对日期的小时进行加/
*
* @param date 日期
* @param hours 小时数负数为减
* @return /减几小时后的日期
*/
public static Date addDateHours(Date date, int hours) {
DateTime dateTime = new DateTime(date);
return dateTime.plusHours(hours).toDate();
}
/**
* 判断当前时间是周几
*
* @param date
* @return
*/
public static String getWeek(Date date) {
String format = DateUtils.parseDateToStr("yyyy-MM-dd", date);
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
Date now = null;
try {
now = format1.parse(format);
} catch (ParseException e) {
e.printStackTrace();
}
assert now != null;
Instant instant = now.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
java.time.LocalDate localDate = instant.atZone(zoneId).toLocalDate();
DayOfWeek day = localDate.getDayOfWeek();
String WeekDay = "";
switch (day) {
case MONDAY:
WeekDay = "1";
break;
case FRIDAY:
WeekDay = "5";
break;
case SATURDAY:
WeekDay = "6";
break;
case SUNDAY:
WeekDay = "7";
break;
case THURSDAY:
WeekDay = "4";
break;
case TUESDAY:
WeekDay = "2";
break;
case WEDNESDAY:
WeekDay = "3";
break;
}
return WeekDay;
}
/**
* 获取指定时间前一个月的时间
*
* @param date 指定时间如果传空为当前时间
* @return
* @Author: 李性禄
*/
public static Date getLastMon(Date date) {
Calendar calendar = Calendar.getInstance();
if (date != null) {
calendar.setTime(date);
}
calendar.add(Calendar.MONTH, -1);
return calendar.getTime();
}
/**
* 获取指定时间前一年的时间
*
* @param date 指定时间如果传空为当前时间
* @return
* @Author: 李性禄
*/
public static Date getLastYear(Date date) {
Calendar calendar = Calendar.getInstance();
if (date != null) {
calendar.setTime(date);
}
calendar.add(Calendar.YEAR, -1);
return calendar.getTime();
}
/**
* 传入两个时间比较两个时间相差年
*
* @param startDate
* @param endxDate
* @return
*/
public static List<String> getTimeList(String startDate, String endxDate) {
SimpleDateFormat sdf;
int calendarType;
switch (startDate.length()) {
case 10:
sdf = new SimpleDateFormat("yyyy-MM-dd");
calendarType = Calendar.DATE;
break;
case 7:
sdf = new SimpleDateFormat("yyyy-MM");
calendarType = Calendar.MONTH;
break;
case 4:
sdf = new SimpleDateFormat("yyyy");
calendarType = Calendar.YEAR;
break;
default:
return null;
}
List<String> result = new ArrayList<>();
Calendar min = Calendar.getInstance();
Calendar max = Calendar.getInstance();
try {
min.setTime(sdf.parse(startDate));
min.add(calendarType, 0);
max.setTime(sdf.parse(endxDate));
max.add(calendarType, 1);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar curr = min;
while (curr.before(max)) {
result.add(sdf.format(min.getTime()));
curr.add(calendarType, 1);
}
return result;
}
/**
* 日期转换字符串
*
* @param date
* @param pattern 转换的类型
* @return
*/
public static String format(Date date, String pattern) {
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
/**
* 根据相差毫秒值查询相差多少天
*
* @param result
* @return
*/
public static long days(long result) {
return result / (1000 * 60 * 60 * 24);
}
/**
* 根据相差毫秒值查询相差多少个钟
*
* @param result
* @return
*/
public static long hour(long result) {
return (result % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
}
/**
* 根据相差毫秒值查询相差多少分钟
*
* @param result
* @return
*/
public static long minutes(long result) {
return (result % (1000 * 60 * 60)) / (1000 * 60);
}
/**
* 字符串转换成日期
*
* @param strDate 日期字符串
* @param pattern 日期的格式DateUtils.DATE_TIME_PATTERN
*/
public static Date stringToDate(String strDate, String pattern) {
if (StringUtils.isBlank(strDate)) {
return null;
}
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
return fmt.parseLocalDateTime(strDate).toDate();
}
/**
* 根据传入的时间获取当前月份的所有日期
*
* @param date
* @return
*/
public static List<Date> getAllTheDateOfTheMonth(Date date) {
List<Date> list = new ArrayList<Date>();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DATE, 1);
int month = cal.get(Calendar.MONTH);
while (cal.get(Calendar.MONTH) == month) {
list.add(cal.getTime());
cal.add(Calendar.DAY_OF_YEAR, 1);
}
return list;
}
/**
* 根据传入的时间获取是当月的第几天
*
* @param date
* @return
*/
public static Integer dayOfMonth(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.DAY_OF_MONTH);
}
/**
* 根据当前时间yyyyMMdd 格式判断是否是节假日私人api慎用容易服务挂掉
*
* @param date 请求参数
* @return 返回结果 默认返回 0工作1-5 1周末 2节假日
*/
public static String holidays(String date) {
String httpUrl = "http://tool.bitefu.net/jiari/";
BufferedReader reader = null;
String holidays = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?d=" + date;
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
}
reader.close();
holidays = sbf.toString();
} catch (Exception e) {
e.printStackTrace();
}
return holidays;
}
/**
* 获取两个时间之前的日期
*
* @return
*/
public static List<String> getDatesBetweenTwoDatesForApprove(Date startTime, Date endTime) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date1 = sdf.format(startTime);
String date2 = sdf.format(endTime);
List<String> dateList = new ArrayList<String>();
try {
Date dateOne = sdf.parse(date1);
Date dateTwo = sdf.parse(date2);
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateOne);
dateList.add(sdf.format(dateOne));
while (calendar.getTime().before(dateTwo)) {
calendar.add(Calendar.DAY_OF_MONTH, +1);
dateList.add(sdf.format(calendar.getTime()));
}
} catch (Exception e) {
e.printStackTrace();
}
return dateList;
}
/**
* 计算两个时间是否为同一周期
*
* @param d1 时间1
* @param d2 时间2
* @param type 周期类型
*/
public static Boolean sameCycle(Date d1, Date d2, int type) {
CycleEnum cycle = CycleEnum.getCycle(type);
assert cycle != null;
if (cycle.equals(CycleEnum.YEAR)) {
return isSameYear(d1, d2);
} else if (cycle.equals(CycleEnum.MONTH)) {
return isSameMonth(d1, d2);
} else if (cycle.equals(CycleEnum.WEEK)) {
return isSameWeek(d1, d2);
} else if (cycle.equals(CycleEnum.DAY)) {
return isSameDate(d1, d2);
}
return false;
}
/**
* 同一年
*
* @param date1
* @param date2
*/
public static Boolean isSameYear(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
}
/**
* 同一月
*
* @param date1
* @param date2
* @return
*/
public static Boolean isSameMonth(Date date1, Date date2) {
if (!isSameYear(date1, date2)) {
return false;
}
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
}
/**
* 同一周
*
* @param date1
* @param date2
* @return
*/
public static Boolean isSameWeek(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
//西方周日为一周的第一天咱得将周一设为一周第一天
cal1.setFirstDayOfWeek(Calendar.MONDAY);
cal1.setTime(date1);
cal2.setTime(date2);
return cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);
}
/**
* 同一天
*
* @param date1
* @param date2
* @return
*/
public static Boolean isSameDate(Date date1, Date date2) {
if (!isSameMonth(date1, date2)) {
return false;
}
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
}
/**
* 查看两个时间之间的日期(包含结束那一天)
*
* @param startTime
* @param endTime
* @return
*/
public static List<String> getDatesBetweenTwoDatesT(Date startTime, Date endTime) {
List<String> days = new ArrayList<>();
Calendar startCal = Calendar.getInstance();
startCal.setTime(startTime);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endTime);
endCal.add(Calendar.DATE, 1);
while (startCal.before(endCal)) {
days.add(DateUtils.format(startCal.getTime(), DateUtils.YYYY_MM_DD));
startCal.add(Calendar.DAY_OF_YEAR, 1);
}
return days;
}
/**
* 获取指定时间内所有时间所有天数转为字符串集合
*
* @param startTime 开始时间
* * @param endTime 结束时间
* *@Author: 李性禄
* @return
*/
public static List<String> getDateList(Date startTime, Date endTime, String format) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
List<String> list = new ArrayList<>();
list.add(simpleDateFormat.format(startTime));
String endDay = simpleDateFormat.format(endTime);
String end = null;
Date date = startTime;
while (!endDay.equals(end)) {
if ("yyyy-MM-dd".equals(format)) {
date = getLasDate(date);
}
if ("yyyy-MM".equals(format)) {
date = getLastMon(date);
}
end = simpleDateFormat.format(date);
list.add(end);
}
return list;
}
public static String setTime(Date date) {
long millis = System.currentTimeMillis();
String endTim = "";
if (date != null) {
long time = date.getTime();
long end = (millis - time) / 1000;
if (end < 60L) {
endTim = end + "秒前";
} else if (end < 3600L) {
endTim = (end / 60) + "分前";
} else if (end < (long) (60 * 60 * 24)) {
endTim = (end / (60 * 60)) + "小时前";
} else if (end < (long) (60 * 60 * 24 * 30)) {
endTim = (end / (60 * 60 * 24)) + "天前";
} else if (end < (long) (60 * 60 * 24 * 30 * 12)) {
endTim = (end / (60 * 60 * 24)) + "月前";
} else {
endTim = (end / (60 * 60 * 24 * 30 * 12)) + "年前";
}
}
return endTim;
}
}

View File

@ -1,15 +1,13 @@
package com.cpop.core.utils; package com.cpop.common.utils;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;
/** /**
* @author <a href="https://github.com/binarywang">Binary Wang</a> * @author <a href="https://github.com/binarywang">Binary Wang</a>
*/ */
@Slf4j
public class JsonUtils { public class JsonUtils {
private static final ObjectMapper JSON = new ObjectMapper(); private static final ObjectMapper JSON = new ObjectMapper();
@ -22,8 +20,9 @@ public class JsonUtils {
try { try {
return JSON.writeValueAsString(obj); return JSON.writeValueAsString(obj);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error(e.getMessage()); e.printStackTrace();
} }
return null; return null;
} }
} }

View File

@ -1,14 +1,14 @@
package com.cpop.core.utils; package com.cpop.common.utils;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.core.utils.text.Convert; import com.cpop.common.utils.text.Convert;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
@ -152,5 +152,4 @@ public class ServletUtils {
String ajax = request.getParameter("__ajax"); String ajax = request.getParameter("__ajax");
return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
} }
} }

View File

@ -1,10 +1,10 @@
package com.cpop.core.utils; package com.cpop.common.utils;
import com.cpop.core.constant.Constants; import com.cpop.common.constant.Constants;
import com.cpop.core.utils.text.StrFormatter; import com.cpop.common.utils.text.StrFormatter;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -559,24 +559,4 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
return new String(subBytes, StandardCharsets.UTF_8); return new String(subBytes, StandardCharsets.UTF_8);
} }
/**
* 字符串是否再匹配项内
* @author DB
* @since 2024/2/5
* @param string 字符串
* @param searchStrings 匹配项
* @return boolean
*/
public static boolean startWithAny(final CharSequence string, final CharSequence... searchStrings) {
if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
return false;
}
for (final CharSequence searchString : searchStrings) {
if (StringUtils.startsWith(string, searchString)) {
return true;
}
}
return false;
}
} }

View File

@ -1,4 +1,4 @@
package com.cpop.core.utils.bean; package com.cpop.common.utils.bean;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -44,7 +44,7 @@ public class BeanUtils extends org.springframework.beans.BeanUtils {
try { try {
copyProperties(src, dest); copyProperties(src, dest);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e.getMessage()); e.printStackTrace();
} }
} }
@ -186,7 +186,7 @@ public class BeanUtils extends org.springframework.beans.BeanUtils {
try { try {
field.set(t, value); field.set(t, value);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
LOGGER.error(e.getMessage()); e.printStackTrace();
} }
} }
} }

View File

@ -1,6 +1,7 @@
package com.cpop.core.utils.html; package com.cpop.common.utils.html;
import com.cpop.core.utils.StringUtils;
import com.cpop.common.utils.StringUtils;
/** /**
* 转义和反转义工具类 * 转义和反转义工具类

View File

@ -1,4 +1,4 @@
package com.cpop.core.utils.html; package com.cpop.common.utils.html;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

View File

@ -1,10 +1,10 @@
package com.cpop.core.utils.http; package com.cpop.common.utils.http;
import jakarta.servlet.ServletRequest;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -19,13 +19,6 @@ import java.nio.charset.StandardCharsets;
public class HttpHelper { public class HttpHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class); private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
/**
* 获取请求体信息失败
* @author DB
* @since 2024/2/1
* @param request 请求
* @return String
*/
public static String getBodyString(ServletRequest request) { public static String getBodyString(ServletRequest request) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
BufferedReader reader = null; BufferedReader reader = null;

View File

@ -1,7 +1,7 @@
package com.cpop.core.utils.http; package com.cpop.common.utils.http;
import com.cpop.core.constant.Constants; import com.cpop.common.constant.Constants;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import okhttp3.*; import okhttp3.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -1,9 +1,9 @@
package com.cpop.core.utils.ip; package com.cpop.common.utils.ip;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.cpop.core.constant.Constants; import com.cpop.common.constant.Constants;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.http.HttpUtils; import com.cpop.common.utils.http.HttpUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -19,13 +19,14 @@ public class AddressUtils {
// IP地址查询 // IP地址查询
public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
@Value("${jambox.address-enabled}") @Value("${rockBlade.addressEnabled}")
private static Boolean isAddressEnabled; private static Boolean isAddressEnabled;
// 未知地址 // 未知地址
public static final String UN_KNOW = "XX XX"; public static final String UN_KNOW = "XX XX";
public static String getRealAddressByIp(String ip) { public static String getRealAddressByIP(String ip) {
String address = UN_KNOW;
// 内网不查询 // 内网不查询
if (IpUtils.internalIp(ip)) { if (IpUtils.internalIp(ip)) {
return "内网IP"; return "内网IP";
@ -45,6 +46,6 @@ public class AddressUtils {
log.error("获取地理位置异常 {}", ip); log.error("获取地理位置异常 {}", ip);
} }
} }
return UN_KNOW; return address;
} }
} }

View File

@ -1,9 +1,9 @@
package com.cpop.core.utils.ip; package com.cpop.common.utils.ip;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.html.EscapeUtil; import com.cpop.common.utils.html.EscapeUtil;
import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;

View File

@ -1,6 +1,6 @@
package com.cpop.core.utils.text; package com.cpop.common.utils.text;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;

View File

@ -1,6 +1,6 @@
package com.cpop.core.utils.text; package com.cpop.common.utils.text;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import java.math.BigDecimal; import java.math.BigDecimal;

View File

@ -1,6 +1,6 @@
package com.cpop.core.utils.text; package com.cpop.common.utils.text;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
/** /**
* 字符串格式化 * 字符串格式化

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.cpop</groupId> <groupId>com.cpop</groupId>
<artifactId>Cpop-Union</artifactId> <artifactId>Cpop-Union</artifactId>
<version>1.1.0</version> <version>1.0.0</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository --> <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent> </parent>
<artifactId>Cpop-Core</artifactId> <artifactId>Cpop-Core</artifactId>
@ -14,20 +14,45 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>
<!-- Sa-Token 权限认证在线文档https://sa-token.cc --> <!--Cpop公共包-->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>com.cpop</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId> <artifactId>Cpop-Common</artifactId>
</dependency> </dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) --> <!--AOP-->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>sa-token-redis-jackson</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<!-- 提供Redis连接池 --> <!--Mybatis-flex-->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>com.mybatis-flex</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>mybatis-flex-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
</dependency>
<!--Security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- jwt 相关依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!--Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
@ -42,85 +67,54 @@
<groupId>org.springframework.integration</groupId> <groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId> <artifactId>spring-integration-redis</artifactId>
</dependency> </dependency>
<!-- Sa-Token 整合 jwt --> <!--easyExcel-->
<dependency> <dependency>
<groupId>cn.dev33</groupId> <groupId>com.alibaba</groupId>
<artifactId>sa-token-jwt</artifactId> <artifactId>easyexcel</artifactId>
</dependency> </dependency>
<!--Mysql--> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency> <dependency>
<groupId>com.mysql</groupId> <groupId>org.apache.commons</groupId>
<artifactId>mysql-connector-j</artifactId> <artifactId>commons-compress</artifactId>
<scope>runtime</scope>
</dependency> </dependency>
<!--HikariCP--> <!--HikariCP-->
<dependency> <dependency>
<groupId>com.zaxxer</groupId> <groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId> <artifactId>HikariCP</artifactId>
</dependency> </dependency>
<!--Mybatis-flex--> <!--knife4j-Swagger-->
<dependency> <dependency>
<groupId>com.mybatis-flex</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>mybatis-flex-spring-boot3-starter</artifactId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!--https://mvnrepository.com/artifact/commons-io/commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!--easyExcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- okhttp3 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<!--quartz-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!-- Sa-Token 整合 SpringAOP 实现注解鉴权 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-aop</artifactId>
</dependency> </dependency>
<!-- 自定义验证注解 --> <!-- 自定义验证注解 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<!--knife4j-Swagger--> <!--quartz-->
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> <artifactId>spring-boot-starter-quartz</artifactId>
</dependency> </dependency>
<!--mongo-plus--> <!-- 腾讯云-->
<dependency> <dependency>
<groupId>com.gitee.anwena</groupId> <groupId>com.qcloud</groupId>
<artifactId>mongo-plus-boot-starter</artifactId> <artifactId>cos_api</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,4 +1,4 @@
package com.cpop.core.anno; package com.cpop.core.annontation;
import com.cpop.core.base.enums.OperationLogEnum; import com.cpop.core.base.enums.OperationLogEnum;

View File

@ -1,4 +1,4 @@
package com.cpop.core.anno; package com.cpop.core.annontation;
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@ -1,4 +1,4 @@
package com.cpop.core.anno; package com.cpop.core.annontation;
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@ -1,4 +1,4 @@
package com.cpop.core.anno; package com.cpop.core.annontation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

View File

@ -1,16 +1,15 @@
package com.cpop.core.aspect; package com.cpop.core.aspect;
import cn.dev33.satoken.session.SaSession; import com.cpop.common.constant.HttpStatus;
import cn.dev33.satoken.stp.StpUtil; import com.cpop.common.enums.ErrorCodeEnum;
import com.cpop.core.base.entity.R; import com.cpop.core.base.R;
import com.cpop.core.base.enums.ErrorCodeEnum; import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.OperationLogEnum; import com.cpop.core.base.enums.OperationLogEnum;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.ServiceException; import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.OperationLog; import com.cpop.core.base.table.SysOperationLog;
import com.cpop.core.constant.HttpStatus;
import com.cpop.core.event.OperationLogEvent; import com.cpop.core.event.OperationLogEvent;
import com.cpop.core.utils.MessageUtils; import com.cpop.core.utils.MessageUtils;
import com.cpop.core.utils.SecurityUtils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
@ -30,7 +29,7 @@ import org.springframework.stereotype.Component;
@Component @Component
public class OperationLogAspect { public class OperationLogAspect {
private final OperationLog operationLog = new OperationLog(); private final SysOperationLog operationLog = new SysOperationLog();
private OperationLogEnum operationLogEnum; private OperationLogEnum operationLogEnum;
@ -43,7 +42,7 @@ public class OperationLogAspect {
/** /**
* 定义controller切入点拦截规则拦截SysLog注解的方法 * 定义controller切入点拦截规则拦截SysLog注解的方法
*/ */
@Pointcut("@annotation(com.cpop.core.anno.OperationLog)") @Pointcut("@annotation(com.cpop.core.annontation.OperationLog)")
public void operationLogAspect() { public void operationLogAspect() {
} }
@ -58,16 +57,18 @@ public class OperationLogAspect {
public void recordLog(JoinPoint joinPoint) { public void recordLog(JoinPoint joinPoint) {
//设置枚举信息 //设置枚举信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
com.cpop.core.anno.OperationLog annotation = signature.getMethod().getAnnotation(com.cpop.core.anno.OperationLog.class); com.cpop.core.annontation.OperationLog annotation = signature.getMethod().getAnnotation(com.cpop.core.annontation.OperationLog.class);
operationLogEnum = annotation.operationLogEnumType(); operationLogEnum = annotation.operationLogEnumType();
try { try {
SaSession session = StpUtil.getSession(); LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
operationLog.setOperationUserName(session.getString("username")) operationLog.setOperationUserName(loginUser.getUsername())
.setOperationUserId(session.getString("userId")) .setOperationUserId(loginUser.getUserId())
.setOperationUserType((UserType) session.get("userType")) .setOperationUserType(loginUser.getUserType())
.setDevIp(session.getString("loginIp")) .setDevIp(loginUser.getIpAddr())
.setCode(operationLogEnum.getCode()) .setCode(operationLogEnum.getCode())
.setInfo(MessageUtils.message(operationLogEnum.getInfo())); .setInfo(MessageUtils.message(operationLogEnum.getInfo()))
.setCreateUserId(loginUser.getUserId());
operationLog.setUpdateUserId(loginUser.getUserId());
} catch (Exception e) { } catch (Exception e) {
throw new ServiceException(ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getInfo(), ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getCode()); throw new ServiceException(ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getInfo(), ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getCode());
} }

View File

@ -1,10 +1,10 @@
package com.cpop.core.aspect; package com.cpop.core.aspect;
import com.cpop.core.base.entity.R; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.exception.ServiceException; import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.exception.UtilException;
import com.cpop.core.utils.RsaUtils; import com.cpop.core.utils.RsaUtils;
import com.cpop.core.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
@ -15,7 +15,16 @@ import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -41,7 +50,7 @@ public class SignatureCheckAspect {
put("1688842965582499840", new String[]{"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"}); put("1688842965582499840", new String[]{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmsFHkB4iIdVSgaz8u8QG66wiZupgSbu2T/ml/kdPm2vemsKgvEqUqp1gR6ulfHcPF8otjVbjiE8q8oR70XfxFIREbomTUmpsOzurLFrAmVhyvu6/tY23/txjQoeeH/tlCy7Lq/TL1AqPKyBcGzsQ4yInpIgRWpXz7fmJCTRw07tyE+4lpXBqiaLdWrkkGG00LnHQAOfcUoXf0TdxFPSfRHiBikfbkmgeVoU66RGlUEXU2esTY2nYGvFn+FqWsNkGEnn2YxIqgbQQ1zNX33+FWBlba1WdQtc8mTJAleaPGXmFnQiEMb55b7xVPjyyCWt6aRwl97KQgtCmfsoPZUWwQQIDAQAB", "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCawUeQHiIh1VKBrPy7xAbrrCJm6mBJu7ZP+aX+R0+ba96awqC8SpSqnWBHq6V8dw8Xyi2NVuOITyryhHvRd/EUhERuiZNSamw7O6ssWsCZWHK+7r+1jbf+3GNCh54f+2ULLsur9MvUCo8rIFwbOxDjIiekiBFalfPt+YkJNHDTu3IT7iWlcGqJot1auSQYbTQucdAA59xShd/RN3EU9J9EeIGKR9uSaB5WhTrpEaVQRdTZ6xNjadga8Wf4Wpaw2QYSefZjEiqBtBDXM1fff4VYGVtrVZ1C1zyZMkCV5o8ZeYWdCIQxvnlvvFU+PLIJa3ppHCX3spCC0KZ+yg9lRbBBAgMBAAECggEAdstPp+25vccHYsvr5icAOQEWF3JrH66csJ+vMJaFIYWYh6xHvsJxhNbyBZJZokWyrExi01CTsRs0mJ3iflVYFqvB7ChnkqhnFMElERNJLW2cB702JKP5TgbXm0aHt30/f2oYppNvtAG3DR/2FGEvAWxCiiZ5S9Q4P8GB1DMROTZBpYQgVlN9vOxqgcy8SsJyruy0xsEP3RIKko9UQ7Y9y/b6TbNOJDx/ZpC9KcOUmI8Or73IMdG1ZucumzHNO3dS2XKL7qeTQ8AWMwwAk2ZsCRx9g05QLiW3+7ZrpmOMwI3wCeJOoxhUQKijCXI3B8Rh1cU++CMk4LdyPOe78PYEEQKBgQDnyOL69Ck6+xe1EJ2HAEDPla5ujCexv6ctYvSernhI6OsMVCWa1D5rCqzC4L0IvRW7/m5lUSWlSzpfIGhSGc+PNyIaYsyYMbaIV5e8LKRp8SxUDrTA4IfYmxoXdYyq2l0PSkBPKMJ2ZyWlRoGGEC432IsiY+GBaznvHwIYFvkYHwKBgQCq7DkJYT6du/bQ2uoZv6hYYIGTY4A9TzjJ0Kp5O00BUz5zNpgBUfb1SmuISHwGyN1hOWFntR0uwfj/BUDvtG0b07k1Xz+4UWXsDqtS6eEnvUR6q/i2yWWGjCMS74t61FZopV6AxHneJV2S6Tt26MFK0VbrCwXaiYg/3tMYgC2rnwKBgF0kfRIby/XHsV8xrhvyHhlNLSt/ZvQm8Cds/KBHvE6QSuRJbFMrt2mMgKBPb6dzVKiXNgXA9j/WWz6e500W0jHbFflEerMuRwvDJ1aXGfr4z7d3sWtQz0ZcDcAfnMeLuJnMXMtytbKfAKHKE4KsPeZzPnYzbQt063MMIutLUA5BAoGBAIduFONxwgOJY8+pJcSxL9qW3RTDymDJ3N1MEUdtzV43b0wq/dZN87f396xMgrl9fqwCo0NhJnZeC8VFjGZiN/HMmPvJNNv+4xtfpDBWUKkENrZcfP2YJnGtqDzgwUvZ432XSoINK+LxCGvXkd5uHnoB1TT3zvOR9ftluy22onlRAoGBAKkIZmwW/2H/86ILrCDyARK4obULB4op8IyrunZ+lH14DksxbL7fmTsSbLyRX7oD/QvGJIuc0EDkgONztsAn5vrETv8Z6RqyKdoZZI3sAQWIBc0om6nH2zqJDIs+mep96DOg/jJAcgiVhyIoFP91IvHY7pvKwy5MTttdZLvvS2XB"});
}}; }};
@Pointcut("@annotation(com.cpop.core.anno.SignatureCheck)") @Pointcut("@annotation(com.cpop.core.annontation.SignatureCheck)")
public void signatureCheck() {} public void signatureCheck() {}
/** /**

View File

@ -1,10 +1,10 @@
package com.cpop.core.aspect; package com.cpop.core.aspect;
import com.cpop.core.base.entity.R; import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.exception.ServiceException; import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.exception.UtilException;
import com.cpop.core.utils.RsaUtils; import com.cpop.core.utils.RsaUtils;
import com.cpop.core.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
@ -15,11 +15,19 @@ import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -45,7 +53,7 @@ public class SimpleSignatureCheckAspect {
put("1688842965582499840", new String[]{"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"}); put("1688842965582499840", new String[]{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmsFHkB4iIdVSgaz8u8QG66wiZupgSbu2T/ml/kdPm2vemsKgvEqUqp1gR6ulfHcPF8otjVbjiE8q8oR70XfxFIREbomTUmpsOzurLFrAmVhyvu6/tY23/txjQoeeH/tlCy7Lq/TL1AqPKyBcGzsQ4yInpIgRWpXz7fmJCTRw07tyE+4lpXBqiaLdWrkkGG00LnHQAOfcUoXf0TdxFPSfRHiBikfbkmgeVoU66RGlUEXU2esTY2nYGvFn+FqWsNkGEnn2YxIqgbQQ1zNX33+FWBlba1WdQtc8mTJAleaPGXmFnQiEMb55b7xVPjyyCWt6aRwl97KQgtCmfsoPZUWwQQIDAQAB", "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCawUeQHiIh1VKBrPy7xAbrrCJm6mBJu7ZP+aX+R0+ba96awqC8SpSqnWBHq6V8dw8Xyi2NVuOITyryhHvRd/EUhERuiZNSamw7O6ssWsCZWHK+7r+1jbf+3GNCh54f+2ULLsur9MvUCo8rIFwbOxDjIiekiBFalfPt+YkJNHDTu3IT7iWlcGqJot1auSQYbTQucdAA59xShd/RN3EU9J9EeIGKR9uSaB5WhTrpEaVQRdTZ6xNjadga8Wf4Wpaw2QYSefZjEiqBtBDXM1fff4VYGVtrVZ1C1zyZMkCV5o8ZeYWdCIQxvnlvvFU+PLIJa3ppHCX3spCC0KZ+yg9lRbBBAgMBAAECggEAdstPp+25vccHYsvr5icAOQEWF3JrH66csJ+vMJaFIYWYh6xHvsJxhNbyBZJZokWyrExi01CTsRs0mJ3iflVYFqvB7ChnkqhnFMElERNJLW2cB702JKP5TgbXm0aHt30/f2oYppNvtAG3DR/2FGEvAWxCiiZ5S9Q4P8GB1DMROTZBpYQgVlN9vOxqgcy8SsJyruy0xsEP3RIKko9UQ7Y9y/b6TbNOJDx/ZpC9KcOUmI8Or73IMdG1ZucumzHNO3dS2XKL7qeTQ8AWMwwAk2ZsCRx9g05QLiW3+7ZrpmOMwI3wCeJOoxhUQKijCXI3B8Rh1cU++CMk4LdyPOe78PYEEQKBgQDnyOL69Ck6+xe1EJ2HAEDPla5ujCexv6ctYvSernhI6OsMVCWa1D5rCqzC4L0IvRW7/m5lUSWlSzpfIGhSGc+PNyIaYsyYMbaIV5e8LKRp8SxUDrTA4IfYmxoXdYyq2l0PSkBPKMJ2ZyWlRoGGEC432IsiY+GBaznvHwIYFvkYHwKBgQCq7DkJYT6du/bQ2uoZv6hYYIGTY4A9TzjJ0Kp5O00BUz5zNpgBUfb1SmuISHwGyN1hOWFntR0uwfj/BUDvtG0b07k1Xz+4UWXsDqtS6eEnvUR6q/i2yWWGjCMS74t61FZopV6AxHneJV2S6Tt26MFK0VbrCwXaiYg/3tMYgC2rnwKBgF0kfRIby/XHsV8xrhvyHhlNLSt/ZvQm8Cds/KBHvE6QSuRJbFMrt2mMgKBPb6dzVKiXNgXA9j/WWz6e500W0jHbFflEerMuRwvDJ1aXGfr4z7d3sWtQz0ZcDcAfnMeLuJnMXMtytbKfAKHKE4KsPeZzPnYzbQt063MMIutLUA5BAoGBAIduFONxwgOJY8+pJcSxL9qW3RTDymDJ3N1MEUdtzV43b0wq/dZN87f396xMgrl9fqwCo0NhJnZeC8VFjGZiN/HMmPvJNNv+4xtfpDBWUKkENrZcfP2YJnGtqDzgwUvZ432XSoINK+LxCGvXkd5uHnoB1TT3zvOR9ftluy22onlRAoGBAKkIZmwW/2H/86ILrCDyARK4obULB4op8IyrunZ+lH14DksxbL7fmTsSbLyRX7oD/QvGJIuc0EDkgONztsAn5vrETv8Z6RqyKdoZZI3sAQWIBc0om6nH2zqJDIs+mep96DOg/jJAcgiVhyIoFP91IvHY7pvKwy5MTttdZLvvS2XB"});
}}; }};
@Pointcut("@annotation(com.cpop.core.anno.SimpleSignatureCheck)") @Pointcut("@annotation(com.cpop.core.annontation.SimpleSignatureCheck)")
public void simpleSignatureCheck() {} public void simpleSignatureCheck() {}
/** /**

View File

@ -1,9 +1,7 @@
package com.cpop.core.base.entity; package com.cpop.core.base;
import com.cpop.common.constant.Constants;
import com.cpop.core.constant.Constants;
import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
/** /**
@ -13,7 +11,6 @@ import java.io.Serializable;
*/ */
public class R<T> implements Serializable { public class R<T> implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -1,8 +1,6 @@
package com.cpop.core.base.entity; package com.cpop.core.base.entity;
import cn.dev33.satoken.exception.SaTokenException; import com.cpop.core.utils.SecurityUtils;
import cn.dev33.satoken.stp.StpUtil;
import com.cpop.core.constant.Constants;
import com.mybatisflex.annotation.InsertListener; import com.mybatisflex.annotation.InsertListener;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -17,16 +15,11 @@ public class BaseInsertListener implements InsertListener {
@Override @Override
public void onInsert(Object entity) { public void onInsert(Object entity) {
BaseEntity baseEntity = (BaseEntity) entity; BaseEntity baseEntity = (BaseEntity) entity;
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
//设置 account 被新增时的一些默认数据 //设置 account 被新增时的一些默认数据
String userId;
try {
userId = StpUtil.getLoginIdDefaultNull() == null ? Constants.SUPER_ADMIN_ID : StpUtil.getLoginIdDefaultNull().toString();
} catch (SaTokenException e) {
userId = Constants.SUPER_ADMIN_ID;
}
baseEntity.setCreateTime(LocalDateTime.now()); baseEntity.setCreateTime(LocalDateTime.now());
baseEntity.setCreateUserId(userId); baseEntity.setCreateUserId(null == loginUser ? "1" : loginUser.getUserId());
baseEntity.setUpdateTime(LocalDateTime.now()); baseEntity.setUpdateTime(LocalDateTime.now());
baseEntity.setUpdateUserId(userId); baseEntity.setUpdateUserId(null == loginUser ? "1" : loginUser.getUserId());
} }
} }

View File

@ -1,8 +1,6 @@
package com.cpop.core.base.entity; package com.cpop.core.base.entity;
import cn.dev33.satoken.exception.SaTokenException; import com.cpop.core.utils.SecurityUtils;
import cn.dev33.satoken.stp.StpUtil;
import com.cpop.core.constant.Constants;
import com.mybatisflex.annotation.UpdateListener; import com.mybatisflex.annotation.UpdateListener;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -17,14 +15,9 @@ public class BaseUpdateListener implements UpdateListener {
@Override @Override
public void onUpdate(Object entity) { public void onUpdate(Object entity) {
BaseEntity baseEntity = (BaseEntity) entity; BaseEntity baseEntity = (BaseEntity) entity;
String userId; LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
try {
userId = StpUtil.getLoginIdDefaultNull() == null ? Constants.SUPER_ADMIN_ID : StpUtil.getLoginIdDefaultNull().toString();
} catch (SaTokenException e) {
userId = Constants.SUPER_ADMIN_ID;
}
//设置 account 被更新时的一些默认数据 //设置 account 被更新时的一些默认数据
baseEntity.setUpdateTime(LocalDateTime.now()); baseEntity.setUpdateTime(LocalDateTime.now());
baseEntity.setUpdateUserId(userId); baseEntity.setUpdateUserId(null == loginUser ? "1" : loginUser.getUserId());
} }
} }

View File

@ -1,9 +1,8 @@
package com.cpop.core.base.entity; package com.cpop.core.base.entity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeFactory;
@ -20,52 +19,42 @@ import java.nio.charset.StandardCharsets;
* @Author: DB * @Author: DB
*/ */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> { public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private final Class<T> clazz; private final Class<T> clazz;
/** static {
* 构造器. ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
* //如果遇到反序列化autoType is not support错误请添加并修改一下包名到bean文件路径
* @param clazz cls // ParserConfig.getGlobalInstance().addAccept("com.xxxxx.xxx");
*/ }
public FastJson2JsonRedisSerializer(Class<T> clazz) { public FastJson2JsonRedisSerializer(Class<T> clazz) {
super(); super();
this.clazz = clazz; this.clazz = clazz;
} }
/**
* 序列化.
*
* @param t object to serialize. Can be {@literal null}.
* @return es
* @throws SerializationException e
*/
@Override @Override
public byte[] serialize(T t) throws SerializationException { public byte[] serialize(T t) throws SerializationException {
if (t == null) { if (t == null) {
return new byte[0]; return new byte[0];
} }
return com.alibaba.fastjson2.JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(StandardCharsets.UTF_8); return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
} }
/**
* 反序列化.
*
* @param bytes object binary representation. Can be {@literal null}.
* @return es
* @throws SerializationException e
*/
@Override @Override
public T deserialize(byte[] bytes) throws SerializationException { public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) { if (bytes == null || bytes.length <= 0) {
return null; return null;
} }
String str = new String(bytes, StandardCharsets.UTF_8); String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz); return JSON.parseObject(str, clazz);
} }
public void setObjectMapper(ObjectMapper objectMapper) { public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null"); Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
} }
protected JavaType getJavaType(Class<?> clazz) { protected JavaType getJavaType(Class<?> clazz) {

View File

@ -0,0 +1,35 @@
package com.cpop.core.base.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @author DB
* @create 2023-04-05 17:53
*/
@Data
public class LoginForm implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 验证码
*/
private String code;
/**
* 单次标识
*/
private String userKey;
}

View File

@ -3,7 +3,6 @@ package com.cpop.core.base.entity;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Set; import java.util.Set;
@ -16,7 +15,6 @@ import java.util.Set;
@Accessors(chain = true) @Accessors(chain = true)
public class LoginSuccess implements Serializable { public class LoginSuccess implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -0,0 +1,156 @@
package com.cpop.core.base.entity;
import com.alibaba.fastjson.annotation.JSONField;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.table.SysUser;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Set;
/**
* 登录用户身份权限
*
* @author DB
*/
@Data
@Accessors(chain = true)
public class LoginUser implements UserDetails {
/**
* 用户ID
*/
private String userId;
/**
* 用户名
*/
private String userName;
/**
* 用户唯一标识
*/
private String identification;
/**
* 登录时间
*/
private Long loginTime = System.currentTimeMillis();
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipAddr;
/**
* 登录地点
*/
private String loginLocation;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 用户信息
*/
private SysUser user;
/**
* 消息
*/
private String msg;
/**
* 登录状态
*/
private Boolean status;
/**
* 用户类型
*/
private UserType userType = UserType.OAM_USER;
public LoginUser() {
}
public LoginUser(SysUser user,String identification, Set<String> permissions) {
this.user = user;
this.identification = identification;
this.permissions = permissions;
}
public LoginUser(String userId, SysUser user, Set<String> permissions) {
this.userId = userId;
this.user = user;
this.permissions = permissions;
}
@JSONField(serialize = false)
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
if (StringUtils.isBlank(this.userName)){
return user.getUserName();
}else {
return this.userName;
}
}
/**
* 账户是否未过期,过期无法验证
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
*/
@JSONField(serialize = false)
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
*/
@JSONField(serialize = false)
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否可用 ,禁用的用户不能身份验证
*/
@JSONField(serialize = false)
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//根据自定义逻辑来返回用户权限如果用户权限返回空或者和拦截路径对应权限不同验证不通过;自定义权限注解此处设定为null
return null;
}
}

View File

@ -0,0 +1,115 @@
package com.cpop.core.base.entity;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* @author DB
* @since 2023-12-10 9:35
* @version 1.0.0
*
* 负责将InputStream转换MultipartFile,可以少引一个jar包,本来用的是spring-test-4.3.9中的MockMultipartFile,直接提取出来使用
*/
public class MultipartFileDto implements MultipartFile {
private final String name;
private String originalFilename;
private String contentType;
private final byte[] content;
/**
* Create a new MultipartFileDto with the given content.
* @param name the name of the file
* @param content the content of the file
*/
public MultipartFileDto(String name, byte[] content) {
this(name, "", null, content);
}
/**
* Create a new MultipartFileDto with the given content.
* @param name the name of the file
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MultipartFileDto(String name, InputStream contentStream) throws IOException {
this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
}
/**
* Create a new MultipartFileDto with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param content the content of the file
*/
public MultipartFileDto(String name, String originalFilename, String contentType, byte[] content) {
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
this.contentType = contentType;
this.content = (content != null ? content : new byte[0]);
}
/**
* Create a new MultipartFileDto with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MultipartFileDto(String name, String originalFilename, String contentType, InputStream contentStream)
throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
}
@Override
public String getName() {
return this.name;
}
@Override
public String getOriginalFilename() {
return this.originalFilename;
}
@Override
public String getContentType() {
return this.contentType;
}
@Override
public boolean isEmpty() {
return (this.content.length == 0);
}
@Override
public long getSize() {
return this.content.length;
}
@Override
public byte[] getBytes() throws IOException {
return this.content;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.content);
}
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(this.content, dest);
}
}

View File

@ -1,7 +1,6 @@
package com.cpop.core.base.entity; package com.cpop.core.base.entity;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.StringUtils;
/** /**
* 分页数据 * 分页数据

View File

@ -1,11 +1,8 @@
package com.cpop.core.base.entity; package com.cpop.core.base.entity;
import lombok.Getter;
/** /**
* 权限组 * 权限组
*/ */
@Getter
public class Permission { public class Permission {
/** /**
@ -13,6 +10,10 @@ public class Permission {
*/ */
private String permission; private String permission;
public String getPermission() {
return permission;
}
public void setPermission(String permission) { public void setPermission(String permission) {
this.permission = permission; this.permission = permission;
} }

View File

@ -0,0 +1,48 @@
package com.cpop.core.base.entity.loginInfo;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.table.SysUser;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @author DB
* @createTime 2023/10/19 13:10
* @description 商城管理员工登陆信息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class MallStaffLoginInfo extends SysUser {
/**
* 员工id(mallStaffId)
*/
private String id;
/**
* 姓名
*/
private String name;
/**
* 用户id
*/
private String userId;
/**
* 角色id
*/
private String roleId;
/**
* 品牌id
*/
private String brandId;
/**
* 用户来源
*/
private SourceType sourceType;
}

View File

@ -0,0 +1,58 @@
package com.cpop.core.base.entity.loginInfo;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.table.SysUser;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @author DB
* @createTime 2023/10/24 9:16
* @description 小程序登陆用户信息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class MiniUserLoginInfo extends SysUser {
/**
* 小程序用户id
*/
private String id;
/**
* 小程序openId
*/
private String openId;
/**
* 小程序appid
*/
private String appId;
/**
* 用户id
*/
private String userId;
/**
* 品牌id
*/
private String brandId;
/**
* 昵称
*/
private String nickName;
/**
* 头像
*/
private String avatar;
/**
* 小程序用户来源
*/
private SourceType sourceType;
}

View File

@ -0,0 +1,47 @@
package com.cpop.core.base.entity.loginInfo;
import com.cpop.core.base.table.SysUser;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @author DB
* @createTime 2023/09/10 13:02
* @description 系统员工登陆信息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class OamStaffLoginInfo extends SysUser {
/**
* 员工id(staffId)
*/
private String id;
/**
* 姓名
*/
private String name;
/**
* 部门id
*/
private String deptId;
/**
* 用户id
*/
private String userId;
/**
* 员工类型(0:技术人员;1:售后人员;2:管理人员)
*/
private Integer staffType;
/**
* 角色id
*/
private String roleId;
}

View File

@ -1,6 +1,5 @@
package com.cpop.system.framework.enums; package com.cpop.core.base.enums;
import com.cpop.core.base.enums.UserType;
import lombok.Getter; import lombok.Getter;
/** /**

View File

@ -1,4 +1,4 @@
package com.cpop.system.framework.enums; package com.cpop.core.base.enums;
import lombok.Getter; import lombok.Getter;

View File

@ -0,0 +1,27 @@
package com.cpop.core.base.enums;
import lombok.Getter;
@Getter
public enum SourceType {
/**
* 通用
*/
COMMON("Common"),
/**
* 果酱
*/
JAMBOX("Jambox");
private String name;
SourceType(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,5 +1,10 @@
package com.cpop.core.base.enums; package com.cpop.core.base.enums;
import com.cpop.core.strategy.login.LoginStrategy;
import com.cpop.core.strategy.login.MallLoginStrategy;
import com.cpop.core.strategy.login.MiniLoginStrategy;
import com.cpop.core.strategy.login.OamLoginStrategy;
import com.cpop.core.utils.SpringUtils;
import lombok.Getter; import lombok.Getter;
/** /**
@ -12,15 +17,15 @@ public enum UserType {
/** /**
* oam系统员工 * oam系统员工
*/ */
OAM_USER(0, "oam:loginUser:"), OAM_USER(0, "oam:loginUser:", SpringUtils.getBean(OamLoginStrategy.class)),
/** /**
* 小程序用户 * 小程序用户
*/ */
MINI_USER(1, "mini:loginUser:"), MINI_USER(1, "mini:loginUser:", SpringUtils.getBean(MiniLoginStrategy.class)),
/** /**
* 商城系统员工 * 商城系统员工
*/ */
MALL_USER(2, "mall:loginUser:"); MALL_USER(2, "mall:loginUser:",SpringUtils.getBean(MallLoginStrategy.class));
/** /**
* code * code
@ -32,9 +37,12 @@ public enum UserType {
*/ */
private final String key; private final String key;
UserType(Integer code, String key) { private final LoginStrategy strategy;
UserType(Integer code, String key, LoginStrategy strategy) {
this.code = code; this.code = code;
this.key = key; this.key = key;
this.strategy = strategy;
} }
} }

View File

@ -1,20 +1,15 @@
package com.cpop.core.base.exception; package com.cpop.core.base.exception;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.MessageUtils; import com.cpop.core.utils.MessageUtils;
import lombok.Getter;
import java.io.Serial;
/** /**
* 基础异常 * 基础异常
* *
* @author DB * @author DB
*/ */
@Getter
public class BaseException extends RuntimeException { public class BaseException extends RuntimeException {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
@ -72,4 +67,19 @@ public class BaseException extends RuntimeException {
return message; return message;
} }
public String getModule() {
return module;
}
public String getCode() {
return code;
}
public Object[] getArgs() {
return args;
}
public String getDefaultMessage() {
return defaultMessage;
}
} }

View File

@ -0,0 +1,26 @@
package com.cpop.core.base.exception;
import org.springframework.security.core.AuthenticationException;
/**
* @author: DB
* @Date: 2023/08/24/18:10
* @Description: 自定义认证失败异常
*/
public class CpopAuthenticationException extends AuthenticationException {
private Object params;
public CpopAuthenticationException(String msg) {
super(msg);
}
public CpopAuthenticationException(String msg, Object params) {
super(msg);
this.params = params;
}
public Object getParams() {
return params;
}
}

View File

@ -23,7 +23,7 @@ import java.io.Serializable;
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@Table(value = "cp_sys_config", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_sys_config", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class Config extends BaseEntity implements Serializable { public class SysConfig extends BaseEntity implements Serializable {
/** /**
* 参数键 * 参数键

View File

@ -24,7 +24,7 @@ import java.io.Serializable;
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@Table(value = "cp_sys_operation_log", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_sys_operation_log", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class OperationLog extends BaseEntity implements Serializable { public class SysOperationLog extends BaseEntity implements Serializable {
/** /**
* ID * ID

View File

@ -25,7 +25,7 @@ import java.io.Serializable;
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
@Table(value = "cp_sys_user", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false) @Table(value = "cp_sys_user", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
public class User extends BaseEntity implements Serializable { public class SysUser extends BaseEntity implements Serializable {
/** /**
* 主键 * 主键

View File

@ -45,16 +45,18 @@ public class AsyncScheduledTaskConfig {
executor.setWaitForTasksToCompleteOnShutdown(false); executor.setWaitForTasksToCompleteOnShutdown(false);
//设置线程池中任务的等待时间如果超过这个时候还没有销毁就强制销毁以确保应用最后能够被关闭而不是阻塞住 //设置线程池中任务的等待时间如果超过这个时候还没有销毁就强制销毁以确保应用最后能够被关闭而不是阻塞住
executor.setAwaitTerminationSeconds(config.getAwaitTerminationSeconds()); executor.setAwaitTerminationSeconds(config.getAwaitTerminationSeconds());
//拒绝处理策略 /**
//CallerRunsPolicy()交由调用方线程运行比如 main 线程 * 拒绝处理策略
//AbortPolicy()直接抛出异常 * CallerRunsPolicy()交由调用方线程运行比如 main 线程
//DiscardPolicy()直接丢弃 * AbortPolicy()直接抛出异常
//DiscardOldestPolicy()丢弃队列中最老的任务 * DiscardPolicy()直接丢弃
//特殊说明 * DiscardOldestPolicy()丢弃队列中最老的任务
//1. 这里演示环境拒绝策略咱们采用抛出异常 * 特殊说明
//2.真实业务场景会把缓存队列的大小会设置大一些 * 1. 这里演示环境拒绝策略咱们采用抛出异常
//如果提交的任务数量超过最大线程数量或将任务环缓存到本地redismysql中,保证消息不丢失 * 2.真实业务场景会把缓存队列的大小会设置大一些
//3.如果项目比较大的话异步通知种类很多的话建议采用MQ做异步通知方案 * 如果提交的任务数量超过最大线程数量或将任务环缓存到本地redismysql中,保证消息不丢失
* 3.如果项目比较大的话异步通知种类很多的话建议采用MQ做异步通知方案
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
//线程初始化 //线程初始化
executor.initialize(); executor.initialize();

View File

@ -1,29 +0,0 @@
package com.cpop.core.config;
import com.cpop.core.service.ConfigService;
import com.cpop.core.strategy.dataSourceSharding.CpopDataSourceShardingStrategy;
import com.cpop.core.utils.SpringUtils;
import com.mybatisflex.core.datasource.DataSourceManager;
import jakarta.annotation.PostConstruct;
import org.springframework.context.annotation.Configuration;
/**
* 核心初始化文件
* @author DB
* @version 1.0.0
* @since 2024-02-05 9:39
*/
@Configuration
public class CoreInitConfig {
/**
* 初始化
*/
@PostConstruct
public void init() {
//设置数据源分片策略
DataSourceManager.setDataSourceShardingStrategy(new CpopDataSourceShardingStrategy());
//初始化系统配置信息
SpringUtils.getBean(ConfigService.class).loadingConfigCache();
}
}

View File

@ -1,6 +1,5 @@
package com.cpop.core.config; package com.cpop.core.config;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -9,7 +8,6 @@ import org.springframework.stereotype.Component;
* *
* @author DB * @author DB
*/ */
@Getter
@Component @Component
@ConfigurationProperties(prefix = "cpop") @ConfigurationProperties(prefix = "cpop")
public class CpopConfig { public class CpopConfig {
@ -31,13 +29,20 @@ public class CpopConfig {
/** /**
* 验证码类型 * 验证码类型
*/ */
@Getter
private static String captchaType; private static String captchaType;
public String getName() {
return name;
}
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
public String getVersion() {
return version;
}
public void setVersion(String version) { public void setVersion(String version) {
this.version = version; this.version = version;
} }
@ -50,6 +55,10 @@ public class CpopConfig {
CpopConfig.profile = profile; CpopConfig.profile = profile;
} }
public static String getCaptchaType() {
return captchaType;
}
public void setCaptchaType(String captchaType) { public void setCaptchaType(String captchaType) {
CpopConfig.captchaType = captchaType; CpopConfig.captchaType = captchaType;
} }

View File

@ -1,8 +1,7 @@
package com.cpop.core.config; package com.cpop.core.config;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.filter.XssFilter; import com.cpop.core.filter.XssFilter;
import com.cpop.core.utils.StringUtils;
import jakarta.servlet.DispatcherType;
import lombok.Data; import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -10,6 +9,7 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
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 javax.servlet.DispatcherType;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -34,10 +34,11 @@ public class FilterConfig {
private String urlPatterns; private String urlPatterns;
/** /**
* xss过滤器 * @Description: xss过滤器
* @return FilterRegistrationBean * @param
* @author DB * @return: FilterRegistrationBean
* @since 2023/4/17 9:17 * @Author: DB
* @Date: 2023/4/17 9:17
**/ **/
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Bean @Bean

View File

@ -1,28 +1,15 @@
package com.cpop.core.config; package com.cpop.core.config;
import com.cpop.core.base.entity.FastJson2JsonRedisSerializer; import com.cpop.core.base.entity.FastJson2JsonRedisSerializer;
import com.cpop.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.Primary;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.Arrays;
/** /**
* redis配置 * redis配置
* *
@ -32,24 +19,9 @@ import java.util.Arrays;
@EnableCaching @EnableCaching
public class RedisConfig extends CachingConfigurerSupport { public class RedisConfig extends CachingConfigurerSupport {
@Autowired @Bean
private RedisProperties redisProperties;
@Primary
@Bean(name = "redisConnectionFactory")
public RedisConnectionFactory wxOpenRedisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());
configuration.setDatabase(redisProperties.getDatabase());
if (StringUtils.isNotBlank(redisProperties.getPassword())) {
configuration.setPassword(redisProperties.getPassword());
}
return new JedisConnectionFactory(configuration);
}
@Bean(name = "redisTemplate")
@SuppressWarnings(value = {"unchecked", "rawtypes"}) @SuppressWarnings(value = {"unchecked", "rawtypes"})
@ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
public RedisTemplate<Object, Object> redisTemplate(@Qualifier("redisConnectionFactory") RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>(); RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory); template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
@ -63,28 +35,6 @@ public class RedisConfig extends CachingConfigurerSupport {
return template; return template;
} }
/**
* 缓存管理器
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory);
return builder.build();
}
@Bean
public KeyGenerator wiselyKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
Arrays.stream(params).map(Object::toString).forEach(sb::append);
return sb.toString();
};
}
@Bean @Bean
public DefaultRedisScript<Long> limitScript() { public DefaultRedisScript<Long> limitScript() {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(); DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();

View File

@ -1,13 +1,10 @@
package com.cpop.core.config; package com.cpop.core.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
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.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.time.Duration;
/** /**
* @author DB * @author DB
* @version 1.0.0 * @version 1.0.0
@ -17,13 +14,15 @@ import java.time.Duration;
public class RestTemplateConfig { public class RestTemplateConfig {
@Bean @Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { public RestTemplate restTemplate() {
// 创建一个 HttpComponentsClientHttpRequestFactory 客户端请求工厂实例
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// 设置连接超时时间为 5 // 设置连接超时时间为 5
restTemplateBuilder.setConnectTimeout(Duration.ofMillis(5000)); requestFactory.setConnectTimeout(5000);
// 设置读取超时时间为 10 // 设置读取超时时间为 10
restTemplateBuilder.setReadTimeout(Duration.ofMillis(10000)); requestFactory.setReadTimeout(10000);
// 使用 HttpComponentsClientHttpRequestFactory 客户端请求工厂实例创建 RestTemplate 实例 // 使用 HttpComponentsClientHttpRequestFactory 客户端请求工厂实例创建 RestTemplate 实例
return restTemplateBuilder.build(); return new RestTemplate(requestFactory);
} }
} }

View File

@ -0,0 +1,215 @@
package com.cpop.core.config;
import com.cpop.common.constant.Constants;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.filter.JwtAuthenticationFilter;
import com.cpop.core.filter.RepeatableFilter;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationFilter;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationProvider;
import com.cpop.core.gateway.sys.SysAuthenticationFilter;
import com.cpop.core.gateway.sys.SysAuthenticationProvider;
import com.cpop.core.handler.*;
import com.cpop.core.utils.JwtUtils;
import com.cpop.core.utils.PasswordEncoder;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.Collections;
/**
* @author DB
* @Description: Security配置中心
* @since 2023-08-05 8:01
*/
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfig implements WebMvcConfigurer {
@Autowired
private JwtLogoutSuccessHandler jwtLogoutSuccessHandler;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private JwtAccessDeniedHandler jwtAccessDeniedHandler;
@Autowired
private RepeatableFilter repeatableFilter;
@Autowired
private LoginSuccessHandler loginSuccessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
@Autowired
private CpopConfig cpopConfig;
@Autowired
private JwtUtils jwtUtils;
/**
* Security过滤拦截配置
*
* @param http 请求
* @return SecurityFilterChain 认证过滤链
* @throws Exception 异常
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
//登录配置(多登陆模式自定义成功与失败->现已注释)
/*.formLogin(formLogin -> {
formLogin.successHandler(loginSuccessHandler)
.failureHandler(loginFailureHandler);
})*/
//登出配置
.logout(logout -> logout.logoutSuccessHandler(jwtLogoutSuccessHandler))
//禁用session
.sessionManagement(sessionManagement -> {
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
})
//配置拦截规则
.authorizeHttpRequests(authorizeHttpRequests -> {
authorizeHttpRequests.antMatchers(StringUtils.split(jwtUtils.getWhiteList(), ",")).permitAll()
.anyRequest().authenticated();
})
//异常处理器
.exceptionHandling(exceptionHandling -> {
exceptionHandling.authenticationEntryPoint(jwtAuthenticationEntryPoint).accessDeniedHandler(jwtAccessDeniedHandler);
})
//自定义认证管理器
.authenticationManager(authenticationManager())
//流重复使用
.addFilterBefore(repeatableFilter, UsernamePasswordAuthenticationFilter.class)
// 添加 JWT 过滤器JWT 过滤器在退出认证过滤器之前
.addFilterBefore(authFilter(), LogoutFilter.class)
//.addFilterAt(oamLoginFilter(http.getSharedObject(AuthenticationManager.class)), UsernamePasswordAuthenticationFilter.class)
//系统登陆
.addFilterAt(sysAuthenticationFilter(http.getSharedObject(AuthenticationManager.class)), UsernamePasswordAuthenticationFilter.class)
//小程序认证
.addFilterAt(miniProgramAuthenticationFilter(http.getSharedObject(AuthenticationManager.class)), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
/**
* @Description: 小程序登陆认证方式(可自定义其他模式)
* @param authenticationManager 认证管理器
* @return MiniProgramAuthenticationFilter
* @author DB
* @Date: 2023/8/24 0024 10:43
*/
@Bean
public SysAuthenticationFilter sysAuthenticationFilter(AuthenticationManager authenticationManager) {
SysAuthenticationFilter filter = new SysAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
filter.setAuthenticationSuccessHandler(loginSuccessHandler);
filter.setAuthenticationFailureHandler(loginFailureHandler);
return filter;
}
@Bean
public SysAuthenticationProvider sysAuthenticationProvider() {
return new SysAuthenticationProvider();
}
/**
* @Description: 小程序登陆认证方式(可自定义其他模式)
* @param authenticationManager 认证管理器
* @return MiniProgramAuthenticationFilter
* @author DB
* @Date: 2023/8/24 0024 10:43
*/
@Bean
public MiniProgramAuthenticationFilter miniProgramAuthenticationFilter(AuthenticationManager authenticationManager) {
MiniProgramAuthenticationFilter filter = new MiniProgramAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
filter.setAuthenticationSuccessHandler(loginSuccessHandler);
filter.setAuthenticationFailureHandler(loginFailureHandler);
return filter;
}
@Bean
public MiniProgramAuthenticationProvider miniProgramAuthenticationProvider() {
return new MiniProgramAuthenticationProvider();
}
/**
* 获取AuthenticationManager认证管理器登录时认证使用
* @return AuthenticationManager
*/
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Arrays.asList(sysAuthenticationProvider(), miniProgramAuthenticationProvider()));
}
/**
* 密码明文加密方式配置
* @return PasswordEncoder
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder();
}
/**
* jwt 校验过滤器 http 头部 Authorization 字段读取 token 并校验
* @return JwtAuthenticationFilter
*/
@Bean
public JwtAuthenticationFilter authFilter() {
return new JwtAuthenticationFilter();
}
/**
* 配置跨源访问(CORS)
* @return CorsConfigurationSource
*/
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
/**
* @param registry 资源注册
* @Description: 资源映射
* @Author DB
* @Date: 2023/5/27 13:57
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//本地文件上传路径
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + cpopConfig.getProfile() + "/");
}
}

View File

@ -1,9 +1,9 @@
package com.cpop.core.config; package com.cpop.core.config;
import com.cpop.core.utils.ServletUtils; import com.cpop.common.utils.ServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/** /**
* 服务相关配置 * 服务相关配置

View File

@ -1,4 +1,4 @@
package com.cpop.system.framework.config.tencentCos; package com.cpop.core.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@ -0,0 +1,163 @@
package com.cpop.core.filter;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.constant.Constants;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.ip.IpUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.loginInfo.MiniUserLoginInfo;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationToken;
import com.cpop.core.gateway.sys.SysAuthenticationToken;
import com.cpop.core.service.CoreService;
import com.cpop.core.service.RedisService;
import com.cpop.core.service.impl.OamStaffDetailsServiceImpl;
import com.cpop.core.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.lang.NonNullApi;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* @author: DB
* @date: 2022-09-25 16:34
* @Description: jwt认证过滤器
*/
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private OamStaffDetailsServiceImpl oamStaffDetailsService;
@Autowired
private CoreService coreService;
@Autowired
private RedisService redisService;
@Override
protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response,@NonNull FilterChain chain) throws IOException, ServletException {
String jwt = request.getHeader(jwtUtils.getHeader());
// 这里如果没有jwt继续往后走因为后面还有鉴权管理器等去判断是否拥有身份凭证所以是可以放行的
// 没有jwt相当于匿名访问若有一些接口是需要权限的则不能访问这些接口
if (StringUtils.isEmpty(jwt)) {
chain.doFilter(request, response);
return;
}
Jws<Claims> jws = jwtUtils.getClaimsByToken(jwt);
if (jws == null) {
returnJwtException(response,"token 失效");
return;
}
Claims claim = jws.getBody();
if (claim == null) {
returnJwtException(response,"token 异常");
return;
}
if (jwtUtils.isTokenExpired(claim)) {
returnJwtException(response,"token 已过期");
return;
}
//当前用户类型下唯一
String identification = claim.getSubject();
String username = jws.getHeader().get(Constants.USERNAME).toString();
UserType userType = UserType.valueOf(jws.getHeader().get(Constants.USER_TYPE).toString());
//从缓存中获取
JSONObject jsonObject = redisService.getCacheObject(userType.getKey() + identification);
LoginUser loginUser;
if (null == jsonObject){
loginUser = multipleLoadUser(userType, username);
//存入缓存
redisService.setCacheObject(userType.getKey() + loginUser.getIdentification(), loginUser);
} else {
loginUser = jsonObject.toJavaObject(LoginUser.class);
}
//获取当前请求ip
loginUser.setIpAddr(IpUtils.getIpAddr(request));
multipleAuth(loginUser);
chain.doFilter(request, response);
}
/**
* jwt异常直接返回
* @param response 响应
* @param msg 错误信息
*/
private void returnJwtException(HttpServletResponse response,String msg) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_OK);
ServletOutputStream outputStream = response.getOutputStream();
R<String> result = R.fail(401, msg);
outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
/**
* @descriptions 多种获取用户信息
* @author DB
* @date 2023/09/11 13:49
* @param userType 用户类型
* @param username 用户名
* @return com.pupu.core.base.entity.LoginUser
*/
private LoginUser multipleLoadUser(UserType userType, String username) {
LoginUser loginUser = null;
switch (userType) {
//系统登陆
case OAM_USER:
case MALL_USER:
loginUser = coreService.loadUserByUsername(username, userType);
break;
case MINI_USER:
// 获取用户的权限等信息
loginUser = coreService.loadUserByPhone(username, userType, null);
break;
default:
}
return loginUser;
}
/**
* @Description: 多种认证方式
* @param loginUser 登陆用户信息
* @author DB
* @Date: 2023/8/24 0024 17:12
*/
private void multipleAuth(LoginUser loginUser) {
switch (loginUser.getUserType()) {
case OAM_USER:
case MALL_USER:
//构建通用系统用户登陆
// 构建UsernamePasswordAuthenticationToken,这里密码为null是因为提供了正确的JWT,实现自动登录
SysAuthenticationToken sysAuthenticationToken = new SysAuthenticationToken(loginUser.getIdentification(), loginUser, null);
SecurityContextHolder.getContext().setAuthentication(sysAuthenticationToken);
break;
case MINI_USER:
// MiniProgramAuthenticationToken,实现自动登录
MiniProgramAuthenticationToken miniProgramAuthenticationToken = new MiniProgramAuthenticationToken(loginUser.getIdentification(), loginUser, null);
SecurityContextHolder.getContext().setAuthentication(miniProgramAuthenticationToken);
break;
default:
}
}
}

View File

@ -1,13 +1,14 @@
package com.cpop.core.filter; package com.cpop.core.filter;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
;
/** /**
* Repeatable 过滤器 * Repeatable 过滤器
@ -16,14 +17,14 @@ import java.io.IOException;
*/ */
@Component @Component
public class RepeatableFilter implements Filter { public class RepeatableFilter implements Filter {
@Override @Override
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
} }
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ServletRequest requestWrapper = null; ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { if (request instanceof HttpServletRequest && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);

View File

@ -1,13 +1,12 @@
package com.cpop.core.filter; package com.cpop.core.filter;
import com.cpop.common.utils.http.HttpHelper;
import com.cpop.core.utils.http.HttpHelper; import javax.servlet.ReadListener;
import jakarta.servlet.ReadListener; import javax.servlet.ServletInputStream;
import jakarta.servlet.ServletInputStream; import javax.servlet.ServletResponse;
import jakarta.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;

View File

@ -1,10 +1,10 @@
package com.cpop.core.filter; package com.cpop.core.filter;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.StringUtils;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -1,16 +1,15 @@
package com.cpop.core.filter; package com.cpop.core.filter;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.utils.StringUtils; import com.cpop.common.utils.html.EscapeUtil;
import com.cpop.core.utils.html.EscapeUtil;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;

View File

@ -0,0 +1,86 @@
package com.cpop.core.gateway.miniProgram;
import com.cpop.common.utils.StringUtils;
import com.cpop.core.base.enums.UserType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author DB
* @Description: 小程序认证过滤器
* @create 2023-08-23 21:03
*/
public class MiniProgramAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public MiniProgramAuthenticationFilter() {
super(new AntPathRequestMatcher("/miniLogin", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (!"POST".equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
ObjectMapper mapper = new ObjectMapper();
InputStream inputStream;
Map authenticationBean;
try {
inputStream = request.getInputStream();
authenticationBean = mapper.readValue(inputStream, Map.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
String principal = (String) authenticationBean.get("phone");
if (StringUtils.isBlank(principal)){
throw new AuthenticationServiceException("登录手机号为空");
}
String openId = (String) authenticationBean.get("openId");
if (StringUtils.isBlank(openId)){
throw new AuthenticationServiceException("登录openId为空");
}
String appId = (String) authenticationBean.get("appId");
if (StringUtils.isBlank(appId)){
throw new AuthenticationServiceException("登录appId为空");
}
String brandId = (String) authenticationBean.get("brandId");
if (StringUtils.isBlank(brandId)){
throw new AuthenticationServiceException("登录brandId为空");
}
String nickName = (String) authenticationBean.get("nickName");
String avatar = (String) authenticationBean.get("avatar");
String sourceType = (String) authenticationBean.get("sourceType");
if (StringUtils.isBlank(sourceType)){
throw new AuthenticationServiceException("登录sourceType为空");
}
UserType userType = UserType.valueOf(authenticationBean.get("userType").toString());//传递信息
HashMap<String, Object> credentials = new HashMap<>(2);
credentials.put("appId", appId);
credentials.put("openId", openId);
credentials.put("userType", userType);
credentials.put("brandId", brandId);
credentials.put("nickName", nickName);
credentials.put("avatar", avatar);
credentials.put("sourceType", sourceType);
principal = principal.trim();
MiniProgramAuthenticationToken authRequest = new MiniProgramAuthenticationToken(principal, credentials);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected void setDetails(HttpServletRequest request, AbstractAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
}

View File

@ -0,0 +1,40 @@
package com.cpop.core.gateway.miniProgram;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.service.CoreService;
import com.cpop.core.utils.SpringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import java.util.Map;
/**
* @author DB
* @Description: 自定义校验过程
* @create 2023-08-23 21:13
*/
public class MiniProgramAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 这个获取表单输入中返回的用户名;
String phone =(String) authentication.getPrincipal();
// 这个是表单中输入的密码
Map<String,Object> credentials = (Map<String, Object>) authentication.getCredentials();
UserType userType = (UserType) credentials.get("userType");
LoginUser loginUser = SpringUtils.getBean(CoreService.class).loadUserByPhone(phone, userType, credentials);
loginUser.setUserType(UserType.MINI_USER);
MiniProgramAuthenticationToken result = new MiniProgramAuthenticationToken(phone, loginUser);
result.setDetails(loginUser);
return result;
}
@Override
public boolean supports(Class<?> authentication) {
//providerManager会遍历所有;securityConfig中注册的provider集合;根据此方法返回true或false来决定由哪个provider;去校验请求过来的authentication
return (MiniProgramAuthenticationToken.class.isAssignableFrom(authentication));
}
}

View File

@ -0,0 +1,72 @@
package com.cpop.core.gateway.miniProgram;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* @author DB
* @Description:
* @create 2023-08-23 21:11
*/
public class MiniProgramAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()}
* will return <code>false</code>.
*
*/
public MiniProgramAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
/**
* This constructor should only be used by <code>AuthenticationManager</code> or
* <code>AuthenticationProvider</code> implementations that are satisfied with
* producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal
* @param credentials
* @param authorities
*/
public MiniProgramAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
// must use super, as we override
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
}

View File

@ -0,0 +1,63 @@
package com.cpop.core.gateway.sys;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author DB
* @createTime 2023/10/19 9:27
* @description
*/
public class SysAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public SysAuthenticationFilter() {
super(new AntPathRequestMatcher("/login", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (!"POST".equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
//读取表单
ObjectMapper mapper = new ObjectMapper();
InputStream inputStream;
Map authenticationBean;
try {
inputStream = request.getInputStream();
authenticationBean = mapper.readValue(inputStream, Map.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
String principal = (String) authenticationBean.get("username");
String password = (String) authenticationBean.get("password");
UserType userType = UserType.valueOf(authenticationBean.get("userType").toString());
principal = principal.trim();
//传递信息
HashMap<String, Object> credentials = new HashMap<>(2);
credentials.put("password", password);
credentials.put("userType", userType);
SysAuthenticationToken authRequest = new SysAuthenticationToken(principal, credentials);
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected void setDetails(HttpServletRequest request, AbstractAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
}
}

View File

@ -0,0 +1,49 @@
package com.cpop.core.gateway.sys;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.CpopAuthenticationException;
import com.cpop.core.gateway.miniProgram.MiniProgramAuthenticationToken;
import com.cpop.core.service.CoreService;
import com.cpop.core.utils.PasswordEncoder;
import com.cpop.core.utils.SpringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Map;
/**
* @author DB
* @createTime 2023/10/19 9:36
* @description
*/
public class SysAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// 这个获取表单输入中返回的用户名;
String principal = (String) authentication.getPrincipal();
// 这个是表单中输入的密码与用户类型
Map<String, Object> credentials = (Map<String, Object>) authentication.getCredentials();
UserType userType = (UserType) credentials.get("userType");
//认证用户名密码
LoginUser loginUser = SpringUtils.getBean(CoreService.class).loadUserByUsername(principal, userType);
//账号密码校验
boolean password = SpringUtils.getBean(PasswordEncoder.class).matches((String) credentials.get("password"), loginUser.getUser().getPassword());
if (!password){
throw new BadCredentialsException("用户名密码错误!");
}
SysAuthenticationToken result = new SysAuthenticationToken(principal, loginUser);
result.setDetails(loginUser);
return result;
}
@Override
public boolean supports(Class<?> authentication) {
//providerManager会遍历所有;securityConfig中注册的provider集合;根据此方法返回true或false来决定由哪个provider;去校验请求过来的authentication
return (SysAuthenticationToken.class.isAssignableFrom(authentication));
}
}

View File

@ -0,0 +1,72 @@
package com.cpop.core.gateway.sys;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* @author DB
* @createTime 2023/10/19 9:35
* @description
*/
public class SysAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
/**
* This constructor can be safely used by any code that wishes to create a
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()}
* will return <code>false</code>.
*
*/
public SysAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
/**
* This constructor should only be used by <code>AuthenticationManager</code> or
* <code>AuthenticationProvider</code> implementations that are satisfied with
* producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal 第一个参数
* @param credentials 第二个参数
* @param authorities 认证
*/
public SysAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
// must use super, as we override
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
credentials = null;
}
}

View File

@ -1,17 +1,23 @@
package com.cpop.core.handler; package com.cpop.core.handler;
import cn.dev33.satoken.exception.SaTokenException; import com.cpop.core.base.R;
import com.cpop.core.base.entity.R;
import com.cpop.core.base.enums.ErrorCodeEnum;
import com.cpop.core.base.exception.ServiceException; import com.cpop.core.base.exception.ServiceException;
import jakarta.servlet.http.HttpServletRequest; import com.cpop.common.enums.ErrorCodeEnum;
import io.jsonwebtoken.JwtException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects; import java.util.Objects;
/** /**
@ -23,23 +29,23 @@ import java.util.Objects;
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 无登录异常
*/
@ExceptionHandler(SaTokenException.class)
public R<Void> handleNotLoginException(SaTokenException e) {
log.error(e.getMessage(), e);
return R.fail(e.getCode(), e.getMessage());
}
/** /**
* 业务异常 * 业务异常
*/ */
@ExceptionHandler(ServiceException.class) @ExceptionHandler(ServiceException.class)
public R<Void> handleServiceException(ServiceException e) { public R handleServiceException(ServiceException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
return R.fail(e.getMessage()); Integer code = e.getCode();
return null != code ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
}
/**
* 权限不足
* @param e 权限不足异常
*/
@ExceptionHandler(AccessDeniedException.class)
public R handleException(AccessDeniedException e) {
return R.fail(ErrorCodeEnum.HTTP_401.getInfo());
} }
/** /**
@ -49,43 +55,45 @@ public class GlobalExceptionHandler {
* @return * @return
*/ */
@ExceptionHandler(RuntimeException.class) @ExceptionHandler(RuntimeException.class)
public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) { public R handleRuntimeException(RuntimeException e, HttpServletRequest request) {
String requestUrl = request.getRequestURI(); String requestUrl = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestUrl, e); log.error("请求地址'{}',发生未知异常.", requestUrl, e);
return R.fail(e.getMessage()); return R.fail(e.getMessage());
} }
/** /**
* 系统异常 * 自定义验证异常
* @param e
* @param request
* @return
*/ */
@ExceptionHandler(Exception.class) @ExceptionHandler(MethodArgumentNotValidException.class)
public R<Void> handleException(Exception e, HttpServletRequest request) { public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String requestUrl = request.getRequestURI(); log.error(e.getMessage(), e);
log.error("请求地址'{}',发生系统异常.", requestUrl, e); String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
return R.fail(e.getMessage()); return R.fail(message);
} }
/** /**
* 自定义验证异常 * 自定义验证异常
*/ */
@ExceptionHandler(BindException.class) @ExceptionHandler(BindException.class)
public R<Void> handleBindException(BindException e) { public R handleBindException(BindException e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
String message = e.getAllErrors().get(0).getDefaultMessage(); String message = e.getAllErrors().get(0).getDefaultMessage();
return R.fail(message); return R.fail(message);
} }
/** /**
* 自定义验证异常 * 系统异常
* @author DB
* @since 2023/12/04
* @param e 异常
* @param request 请求
* @return R
*/ */
@ExceptionHandler(MethodArgumentNotValidException.class) @ExceptionHandler(Exception.class)
public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { public R handleException(Exception e, HttpServletRequest request) {
log.error(e.getMessage(), e); String requestUrl = request.getRequestURI();
String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage(); log.error("请求地址'{}',发生系统异常.", requestUrl, e);
return R.fail(message); return R.fail(e.getMessage());
} }
} }

View File

@ -0,0 +1,33 @@
package com.cpop.core.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.core.base.R;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* @author: DB
* @date: 2022-09-25 16:55
* @Description: 无权限访问处理器
*/
@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
R<String> result = R.fail(e.getMessage());
outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
}

View File

@ -0,0 +1,33 @@
package com.cpop.core.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.core.base.R;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* @author: DB
* @date: 2022-09-25 16:40
* @Description: jwt认证失败处理器
*/
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
R<String> result = R.fail("请先登录");
outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
}

View File

@ -0,0 +1,77 @@
package com.cpop.core.handler;
import com.alibaba.fastjson.JSONObject;
import com.cpop.common.constant.Constants;
import com.cpop.core.base.R;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.OperationLogEnum;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.service.CoreService;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.JwtUtils;
import com.cpop.core.utils.MessageUtils;
import com.cpop.core.utils.SpringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* @author: DB
* @date: 2022-09-25 16:56
* @Description: 登出成功处理器
*/
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private RedisService redisService;
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException {
if (authentication != null) {
new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication);
}
String jwt = httpServletRequest.getHeader(jwtUtils.getHeader());
//添加退出登录成功日志
Jws<Claims> jws = jwtUtils.getClaimsByToken(jwt);
Claims claim = jws.getBody();
if (claim == null) {
throw new JwtException("token 异常");
}
if (jwtUtils.isTokenExpired(claim)) {
throw new JwtException("token 已过期");
}
String identification = claim.getSubject();
UserType userType = UserType.valueOf(jws.getHeader().get(Constants.USER_TYPE).toString());
//从缓存中获取
JSONObject jsonObject = redisService.getCacheObject(userType.getKey() + identification);
if (null != jsonObject) {
LoginUser loginUser = jsonObject.toJavaObject(LoginUser.class);
SpringUtils.getBean(CoreService.class).insertOperationLog(Constants.SUCCESS, OperationLogEnum.SYSTEM_LOGOUT, loginUser, MessageUtils.message("i18n_operationLog_systemLogout"));
}
//清除缓存
redisService.deleteObject(userType.getKey() + identification);
httpServletResponse.setContentType("application/json;charset=UTF-8");
ServletOutputStream outputStream = httpServletResponse.getOutputStream();
String header = jwtUtils.getHeader();
httpServletResponse.setHeader(header, "");
R<String> result = R.ok(MessageUtils.message("i18n_loginOut_success"));
outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
}

Some files were not shown because too many files have changed in this diff Show More