Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5f7e20891 |
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.cpop</groupId>
|
||||
<artifactId>Cpop-Union</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>Cpop-Api</artifactId>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.cpop.api.cloudDb.core.dto;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import io.swagger.models.auth.In;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -3,6 +3,7 @@ package com.cpop.api.cloudDb.handler;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
import com.cpop.api.cloudDb.core.dto.CloudBrandDto;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.core.base.exception.UtilException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
import com.cpop.api.cloudDb.core.dto.CloudClassCardDto;
|
||||
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.exception.ServiceException;
|
||||
import com.cpop.core.base.exception.UtilException;
|
||||
|
||||
@ -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.CloudClassStudentDto;
|
||||
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.mybatisflex.core.paginate.Page;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@ -3,8 +3,10 @@ package com.cpop.api.cloudDb.handler;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
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.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.mybatisflex.core.paginate.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
import com.cpop.api.cloudDb.core.dto.CloudCustomerDto;
|
||||
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.mybatisflex.core.paginate.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -3,7 +3,7 @@ package com.cpop.api.cloudDb.handler;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
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.exception.UtilException;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
||||
@ -2,8 +2,9 @@ package com.cpop.api.cloudDb.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
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.core.utils.StringUtils;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.core.base.exception.UtilException;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.cloudDb.core.constant.CloudDbUrl;
|
||||
import com.cpop.api.cloudDb.core.dto.CloudStoreActiveDto;
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
package com.cpop.api.tencent.location.handler;
|
||||
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
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 okhttp3.Response;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -3,7 +3,7 @@ package com.cpop.api.tencent.wxWork.handler;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.api.tencent.wxWork.core.config.WxWorkApiConfig;
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.cpop</groupId>
|
||||
<artifactId>Cpop-Union</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>Cpop-ClockIn-Demo</artifactId>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.cpop.clockin.business.bo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -10,7 +10,7 @@ import lombok.Data;
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "打卡记录VO")
|
||||
@ApiModel(value = "打卡记录VO")
|
||||
public class ClockInRecordBo {
|
||||
@ExcelProperty(value = "姓名")
|
||||
private String staffName;
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
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 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.GetMapping;
|
||||
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.service.ClassesService;
|
||||
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.util.List;
|
||||
|
||||
@ -26,7 +26,7 @@ import java.util.List;
|
||||
* @since 2024-01-23
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "打卡班次表接口")
|
||||
@Api(tags = "打卡班次表接口")
|
||||
@RequestMapping("/backstage/classes")
|
||||
public class ClassesController {
|
||||
|
||||
@ -40,8 +40,8 @@ public class ClassesController {
|
||||
* @return {@code true} 添加成功,{@code false} 添加失败
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
@Operation(summary = "保存打卡班次表")
|
||||
public R<Void> save(@RequestBody @Parameter(description = "打卡班次表") Classes classes) {
|
||||
@ApiOperation("保存打卡班次表")
|
||||
public R<Void> save(@RequestBody @ApiParam("打卡班次表") Classes classes) {
|
||||
classesService.save(classes);
|
||||
return R.ok();
|
||||
}
|
||||
@ -53,8 +53,8 @@ public class ClassesController {
|
||||
* @return {@code true} 删除成功,{@code false} 删除失败
|
||||
*/
|
||||
@DeleteMapping("/remove/{id}")
|
||||
@Operation(summary = "根据主键删除打卡班次表")
|
||||
public R<Void> remove(@PathVariable @Parameter(description = "打卡班次表主键") Serializable id) {
|
||||
@ApiOperation("根据主键删除打卡班次表")
|
||||
public R<Void> remove(@PathVariable @ApiParam("打卡班次表主键") Serializable id) {
|
||||
classesService.removeById(id);
|
||||
return R.ok();
|
||||
}
|
||||
@ -66,8 +66,8 @@ public class ClassesController {
|
||||
* @return {@code true} 更新成功,{@code false} 更新失败
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "根据主键更新打卡班次表")
|
||||
public R<Void> update(@RequestBody @Parameter(description = "打卡班次表主键") Classes classes) {
|
||||
@ApiOperation("根据主键更新打卡班次表")
|
||||
public R<Void> update(@RequestBody @ApiParam("打卡班次表主键") Classes classes) {
|
||||
classesService.updateById(classes);
|
||||
return R.ok();
|
||||
}
|
||||
@ -78,7 +78,7 @@ public class ClassesController {
|
||||
* @return 所有数据
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询所有打卡班次表")
|
||||
@ApiOperation("查询所有打卡班次表")
|
||||
public R<List<Classes>> list() {
|
||||
return R.ok(classesService.list());
|
||||
}
|
||||
@ -90,8 +90,8 @@ public class ClassesController {
|
||||
* @return 打卡班次表详情
|
||||
*/
|
||||
@GetMapping("/getInfo/{id}")
|
||||
@Operation(summary = "根据主键获取打卡班次表")
|
||||
public R<Classes> getInfo(@PathVariable @Parameter(description = "打卡班次表主键") Serializable id) {
|
||||
@ApiOperation("根据主键获取打卡班次表")
|
||||
public R<Classes> getInfo(@PathVariable @ApiParam("打卡班次表主键") Serializable id) {
|
||||
return R.ok(classesService.getById(id));
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ public class ClassesController {
|
||||
* @return 分页对象
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "分页查询打卡班次表")
|
||||
public R<Page<Classes>> page(@Parameter(description = "分页信息") Page<Classes> page) {
|
||||
@ApiOperation("分页查询打卡班次表")
|
||||
public R<Page<Classes>> page(@ApiParam("分页信息") Page<Classes> page) {
|
||||
return R.ok(classesService.page(page));
|
||||
}
|
||||
|
||||
|
||||
@ -4,16 +4,16 @@ import com.alibaba.excel.EasyExcel;
|
||||
import com.cpop.clockin.business.bo.EmployeeAttendanceBo;
|
||||
import com.cpop.clockin.business.service.ClockInRecordService;
|
||||
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.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.ParseException;
|
||||
@ -27,7 +27,7 @@ import java.util.List;
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "打卡记录接口")
|
||||
@Api(tags = "打卡记录接口")
|
||||
@RequestMapping("/backstage/clockInRecord")
|
||||
public class ClockInRecordController {
|
||||
@Autowired
|
||||
@ -35,7 +35,7 @@ public class ClockInRecordController {
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
@PostMapping("/upload")
|
||||
@Operation(summary = "上传钉钉Excel表")
|
||||
@ApiOperation("上传钉钉Excel表")
|
||||
public R<String> uploadRecord(@RequestParam("file") MultipartFile file) throws IOException, ParseException {
|
||||
/* List<ClockInRecordBo> clockInRecordBoList = ;
|
||||
// 将对象数据返回给前端*/
|
||||
@ -43,7 +43,7 @@ public class ClockInRecordController {
|
||||
}
|
||||
|
||||
@GetMapping("/output")
|
||||
@Operation(summary = "导出表格")
|
||||
@ApiOperation("导出表格")
|
||||
public void outPut(HttpServletResponse response) throws IOException {
|
||||
String manTimeJson = redisService.getCacheObject(ClockInConstant.MAN_TIME_JSON);
|
||||
/*byte[] bytes = manTimeJson.getBytes();
|
||||
|
||||
@ -3,14 +3,14 @@ package com.cpop.clockin.business.controller;
|
||||
import com.cpop.clockin.business.dto.StaffClassesDto;
|
||||
import com.cpop.clockin.business.service.StaffClassesService;
|
||||
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 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.beans.factory.annotation.Autowired;
|
||||
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.util.List;
|
||||
|
||||
@ -21,7 +21,7 @@ import java.util.List;
|
||||
* @since 2024-01-23
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "员工-班次关联表接口")
|
||||
@Api(tags = "员工-班次关联表接口")
|
||||
@RequestMapping("/backstage/staffClasses")
|
||||
public class StaffClassesController {
|
||||
|
||||
@ -34,11 +34,11 @@ public class StaffClassesController {
|
||||
* @author: Yxz
|
||||
* @date: 2024/1/24 20:54
|
||||
* @param: [staffClassesDto]
|
||||
* @return: com.cpop.core.base.entity.R<java.lang.Void>
|
||||
* @return: com.cpop.core.base.R<java.lang.Void>
|
||||
**/
|
||||
@PostMapping("/save")
|
||||
@Operation(summary = "保存员工-班次关联表")
|
||||
public R<Void> save(@RequestBody @Parameter(description = "员工-班次保存Dto") StaffClassesDto staffClassesDto) {
|
||||
@ApiOperation("保存员工-班次关联表")
|
||||
public R<Void> save(@RequestBody @ApiParam("员工-班次保存Dto") StaffClassesDto staffClassesDto) {
|
||||
staffClassesService.saveAll(staffClassesDto);
|
||||
return R.ok();
|
||||
}
|
||||
@ -50,11 +50,11 @@ public class StaffClassesController {
|
||||
* @author: Yxz
|
||||
* @date: 2024/1/24 20:54
|
||||
* @param: [staffClassesDto]
|
||||
* @return: com.cpop.core.base.entity.R<java.lang.Void>
|
||||
* @return: com.cpop.core.base.R<java.lang.Void>
|
||||
**/
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新员工-班次关联表")
|
||||
public R<Void> update(@RequestBody @Parameter(description = "员工-班次修改Dto") StaffClassesDto staffClassesDto) {
|
||||
@ApiOperation("更新员工-班次关联表")
|
||||
public R<Void> update(@RequestBody @ApiParam("员工-班次修改Dto") StaffClassesDto staffClassesDto) {
|
||||
staffClassesService.updateAll(staffClassesDto);
|
||||
return R.ok();
|
||||
}
|
||||
@ -65,7 +65,7 @@ public class StaffClassesController {
|
||||
* @return 所有数据
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询员工班次信息")
|
||||
@ApiOperation("查询员工班次信息")
|
||||
public R<List<StaffClassesVo>> list() {
|
||||
return R.ok(staffClassesService.getStaffClassesVolist());
|
||||
}
|
||||
@ -78,8 +78,8 @@ public class StaffClassesController {
|
||||
* @return 员工-班次关联表详情
|
||||
*/
|
||||
@GetMapping("/getInfo/{id}")
|
||||
@Operation(summary = "根据主键获取员工-班次关联表")
|
||||
public R<StaffClasses> getInfo(@PathVariable @Parameter(description = "员工-班次关联表主键") Serializable id) {
|
||||
@ApiOperation("根据主键获取员工-班次关联表")
|
||||
public R<StaffClasses> getInfo(@PathVariable @ApiParam("员工-班次关联表主键") Serializable id) {
|
||||
return R.ok(staffClassesService.getById(id));
|
||||
}
|
||||
|
||||
@ -89,11 +89,11 @@ public class StaffClassesController {
|
||||
* @author: Yxz
|
||||
* @date: 2024/1/24 20:55
|
||||
* @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")
|
||||
@Operation(summary = "分页查询员工-班次信息")
|
||||
public R<Page<StaffClassesVo>> page( @Parameter(description = "员工名称") @RequestParam(value = "staffName", required = false)String staffName) {
|
||||
@ApiOperation("分页查询员工-班次信息")
|
||||
public R<Page<StaffClassesVo>> page( @ApiParam("员工名称") @RequestParam(value = "staffName", required = false)String staffName) {
|
||||
|
||||
return R.ok(staffClassesService.selectPage(staffName));
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -9,10 +10,10 @@ import lombok.Data;
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "员工班次DTO")
|
||||
@ApiModel(value = "员工班次DTO")
|
||||
public class StaffClassesDto {
|
||||
@Schema(description = "员工id")
|
||||
@ApiModelProperty(value = "员工id")
|
||||
private String staffId;
|
||||
@Schema(description = "班次id数组")
|
||||
@ApiModelProperty(value = "班次id数组")
|
||||
private String[] classId;
|
||||
}
|
||||
|
||||
@ -8,8 +8,11 @@ import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -25,6 +28,7 @@ import lombok.experimental.Accessors;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "打卡班次表对象")
|
||||
@Table(value = "cp_oam_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
|
||||
public class Classes extends BaseEntity implements Serializable {
|
||||
|
||||
@ -34,23 +38,29 @@ public class Classes extends BaseEntity implements Serializable {
|
||||
/**
|
||||
* 班次名称
|
||||
*/
|
||||
@ApiModelProperty(value = "班次名称")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@ApiModelProperty(value = "开始时间")
|
||||
@JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@ApiModelProperty(value = "结束时间")
|
||||
@JsonFormat(pattern = "HH:mm:ss",timezone = "GMT+8")
|
||||
private Date endTime;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 逻辑删除(0否1是)
|
||||
*/
|
||||
@ApiModelProperty(value = "逻辑删除(0否1是)")
|
||||
@Column(isLogicDelete = true)
|
||||
private Integer isDelete;
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -23,68 +25,85 @@ import lombok.experimental.Accessors;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "部门表对象")
|
||||
@Table(value = "cp_oam_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
|
||||
public class ClockInDept extends BaseEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@ApiModelProperty(value = "部门id")
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 父部门id
|
||||
*/
|
||||
@ApiModelProperty(value = "父部门id")
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 企微id
|
||||
*/
|
||||
@ApiModelProperty(value = "企微id")
|
||||
private Long wxCpId;
|
||||
|
||||
/**
|
||||
* 企微父id
|
||||
*/
|
||||
@ApiModelProperty(value = "企微父id")
|
||||
private Long wxCpParentId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@ApiModelProperty(value = "部门名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer orderNo;
|
||||
|
||||
/**
|
||||
* 负责人
|
||||
*/
|
||||
@ApiModelProperty(value = "负责人")
|
||||
private String leader;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@ApiModelProperty(value = "电话")
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 部门状态:1正常,0停用
|
||||
*/
|
||||
@ApiModelProperty(value = "部门状态:1正常,0停用")
|
||||
private Boolean status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 逻辑删除(0否1是)
|
||||
*/
|
||||
@ApiModelProperty(value = "逻辑删除(0否1是)")
|
||||
@Column(isLogicDelete = true)
|
||||
private Boolean isDelete;
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -23,48 +25,61 @@ import lombok.experimental.Accessors;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "员工表对象")
|
||||
@Table(value = "cp_oam_staff", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
|
||||
public class ClockInStaff extends BaseEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ApiModelProperty(value = "主键")
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
@ApiModelProperty(value = "姓名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 员工类型(0:技术人员;1:售后人员;2:管理人员)
|
||||
*/
|
||||
@ApiModelProperty(value = "员工类型(0:技术人员;1:售后人员;2:管理人员)")
|
||||
private Integer staffType;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
@ApiModelProperty(value = "角色id")
|
||||
private String roleId;
|
||||
|
||||
/**
|
||||
* 微信用userId
|
||||
*/
|
||||
@ApiModelProperty(value = "微信用userId")
|
||||
private String wxCpUserId;
|
||||
|
||||
/**
|
||||
* 是否是运维账号
|
||||
*/
|
||||
@ApiModelProperty(value = "是否是运维账号")
|
||||
private Boolean isOperation;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 逻辑删除(0否1是)
|
||||
*/
|
||||
@ApiModelProperty(value = "逻辑删除(0否1是)")
|
||||
@Column(isLogicDelete = true)
|
||||
private Boolean isDelete;
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ import com.cpop.core.base.entity.BaseUpdateListener;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -21,17 +23,20 @@ import lombok.experimental.Accessors;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "Oam-员工-用户中间表对象")
|
||||
@Table(value = "cp_oam_staff_mid_dept", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
|
||||
public class ClockInStaffMidDept extends BaseEntity implements Serializable {
|
||||
|
||||
/**
|
||||
* 员工id
|
||||
*/
|
||||
@ApiModelProperty(value = "员工id")
|
||||
private String staffId;
|
||||
|
||||
/**
|
||||
* 部门id
|
||||
*/
|
||||
@ApiModelProperty(value = "部门id")
|
||||
private String deptId;
|
||||
|
||||
|
||||
|
||||
@ -7,6 +7,9 @@ import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -22,6 +25,7 @@ import lombok.experimental.Accessors;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value = "员工-班次关联表对象")
|
||||
@Table(value = "cp_oam_staff_classes", onInsert = BaseInsertListener.class, onUpdate = BaseUpdateListener.class, mapperGenerateEnable = false)
|
||||
public class StaffClasses extends BaseEntity implements Serializable {
|
||||
|
||||
@ -31,16 +35,23 @@ public class StaffClasses extends BaseEntity implements Serializable {
|
||||
/**
|
||||
* 员工id
|
||||
*/
|
||||
@ApiModelProperty(value = "员工id")
|
||||
private String staffId;
|
||||
|
||||
/**
|
||||
* 班次id
|
||||
*/
|
||||
@ApiModelProperty(value = "班次id")
|
||||
private String classId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 逻辑删除(0否1是)
|
||||
*/
|
||||
@ApiModelProperty(value = "逻辑删除(0否1是)")
|
||||
@Column(isLogicDelete = true)
|
||||
private Integer isDelete;
|
||||
|
||||
|
||||
@ -8,9 +8,13 @@ import com.cpop.clockin.business.service.*;
|
||||
import com.cpop.clockin.business.vo.ClassesVo;
|
||||
import com.cpop.clockin.business.vo.StaffClassesVo;
|
||||
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.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.cpop.clockin.business.mapper.StaffClassesMapper;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@ -21,6 +25,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.mybatisflex.core.query.QueryMethods.groupConcat;
|
||||
|
||||
/**
|
||||
* 员工-班次关联表 服务层实现。
|
||||
*
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -8,15 +9,15 @@ import lombok.Data;
|
||||
* @Date: 2024/1/23 18:56
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Schema(description = "班次VO")
|
||||
@ApiModel(value = "班次VO")
|
||||
@Data
|
||||
public class ClassesVo {
|
||||
@Schema(description = "班次Id")
|
||||
@ApiModelProperty(value = "班次Id")
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 班次名称
|
||||
*/
|
||||
@Schema(description = "班次名称")
|
||||
@ApiModelProperty(value = "班次名称")
|
||||
private String className;
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
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 java.util.List;
|
||||
@ -10,18 +12,18 @@ import java.util.List;
|
||||
* @Date: 2024/1/23 17:45
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Schema(description = "员工班次关联VO")
|
||||
@ApiModel(value = "员工班次关联VO")
|
||||
@Data
|
||||
public class StaffClassesVo {
|
||||
@Schema(description = "员工Id")
|
||||
@ApiModelProperty("员工Id")
|
||||
private String staffId;
|
||||
@Schema(description = "员工名称")
|
||||
@ApiModelProperty("员工名称")
|
||||
private String staffName;
|
||||
@Schema(description = "部门名称")
|
||||
@ApiModelProperty("部门名称")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "考勤班次名称")
|
||||
@ApiModelProperty("考勤班次名称")
|
||||
private String className;
|
||||
@Schema(description = "考勤班次集合")
|
||||
@ApiModelProperty("考勤班次集合")
|
||||
private List<ClassesVo> classesVoList;
|
||||
}
|
||||
|
||||
55
Cpop-Common/pom.xml
Normal file
55
Cpop-Common/pom.xml
Normal 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>
|
||||
@ -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
|
||||
*/
|
||||
String CONFIG_KEY = "config:";
|
||||
String SYS_CONFIG_KEY = "sys_config:";
|
||||
|
||||
/**
|
||||
* 字典管理 cache key
|
||||
@ -172,17 +172,12 @@ public interface Constants {
|
||||
/**
|
||||
* 超级管理员
|
||||
*/
|
||||
String SUPER_ADMIN = "Jambox";
|
||||
String SUPER_ADMIN = "Cpop";
|
||||
|
||||
/**
|
||||
* 超级管理员ID
|
||||
*/
|
||||
String SUPER_ADMIN_ID = "100";
|
||||
|
||||
/**
|
||||
* 超级身份id
|
||||
*/
|
||||
String SUPER_IDENTITY_AUTH_ID = "100";
|
||||
String SUPER_ADMIN_ID = "1";
|
||||
|
||||
/**
|
||||
* 超级管理员
|
||||
@ -192,12 +187,12 @@ public interface Constants {
|
||||
/**
|
||||
* 所有权限
|
||||
*/
|
||||
String ALL_PERMISSION = "*";
|
||||
String ALL_PERMISSION = "*:*:*";
|
||||
|
||||
/**
|
||||
* 隐藏菜单
|
||||
*/
|
||||
String HIDE_MENU = "System,Menu,Dict";
|
||||
String HIDE_MENU = "Menu";
|
||||
|
||||
/**
|
||||
* 用户类型
|
||||
@ -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 STORE_EXPIRE = 10000;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.constant;
|
||||
package com.cpop.common.constant;
|
||||
|
||||
/**
|
||||
* @author DB
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.base.enums;
|
||||
package com.cpop.common.enums;
|
||||
|
||||
/**
|
||||
* @author DB
|
||||
@ -1,11 +1,8 @@
|
||||
package com.cpop.core.base.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
package com.cpop.common.enums;
|
||||
|
||||
/**
|
||||
* @author LOST.yuan
|
||||
*/
|
||||
@Getter
|
||||
public enum ErrorCodeEnum {
|
||||
|
||||
/** jwt凭据已过期 */
|
||||
@ -70,6 +67,14 @@ public enum ErrorCodeEnum {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public static ErrorCodeEnum codeOf(Integer code) {
|
||||
for (ErrorCodeEnum value : values()) {
|
||||
if (value.getCode().equals(code)) {
|
||||
653
Cpop-Common/src/main/java/com/cpop/common/utils/DateUtils.java
Normal file
653
Cpop-Common/src/main/java/com/cpop/common/utils/DateUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
public class JsonUtils {
|
||||
private static final ObjectMapper JSON = new ObjectMapper();
|
||||
|
||||
@ -22,8 +20,9 @@ public class JsonUtils {
|
||||
try {
|
||||
return JSON.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,14 @@
|
||||
package com.cpop.core.utils;
|
||||
package com.cpop.common.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cpop.core.utils.text.Convert;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.common.utils.text.Convert;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
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.IOException;
|
||||
|
||||
@ -152,5 +152,4 @@ public class ServletUtils {
|
||||
String ajax = request.getParameter("__ajax");
|
||||
return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
package com.cpop.core.utils;
|
||||
package com.cpop.common.utils;
|
||||
|
||||
import com.cpop.core.constant.Constants;
|
||||
import com.cpop.core.utils.text.StrFormatter;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import com.cpop.common.constant.Constants;
|
||||
import com.cpop.common.utils.text.StrFormatter;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
@ -559,24 +559,4 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.utils.bean;
|
||||
package com.cpop.common.utils.bean;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -44,7 +44,7 @@ public class BeanUtils extends org.springframework.beans.BeanUtils {
|
||||
try {
|
||||
copyProperties(src, dest);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ public class BeanUtils extends org.springframework.beans.BeanUtils {
|
||||
try {
|
||||
field.set(t, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 转义和反转义工具类
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.utils.html;
|
||||
package com.cpop.common.utils.html;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -19,13 +19,6 @@ import java.nio.charset.StandardCharsets;
|
||||
public class HttpHelper {
|
||||
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) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BufferedReader reader = null;
|
||||
@ -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.core.utils.StringUtils;
|
||||
import com.cpop.common.constant.Constants;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import okhttp3.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -1,9 +1,9 @@
|
||||
package com.cpop.core.utils.ip;
|
||||
package com.cpop.common.utils.ip;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cpop.core.constant.Constants;
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import com.cpop.core.utils.http.HttpUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.cpop.common.constant.Constants;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.common.utils.http.HttpUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -19,13 +19,14 @@ public class AddressUtils {
|
||||
// IP地址查询
|
||||
public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
|
||||
|
||||
@Value("${jambox.address-enabled}")
|
||||
@Value("${rockBlade.addressEnabled}")
|
||||
private static Boolean isAddressEnabled;
|
||||
|
||||
// 未知地址
|
||||
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)) {
|
||||
return "内网IP";
|
||||
@ -45,6 +46,6 @@ public class AddressUtils {
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
}
|
||||
}
|
||||
return UN_KNOW;
|
||||
return address;
|
||||
}
|
||||
}
|
||||
@ -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.core.utils.html.EscapeUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.common.utils.html.EscapeUtil;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@ -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.StandardCharsets;
|
||||
@ -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 java.math.BigDecimal;
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 字符串格式化
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.cpop</groupId>
|
||||
<artifactId>Cpop-Union</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>Cpop-Core</artifactId>
|
||||
@ -14,20 +14,45 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||
<!--Cpop公共包-->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<groupId>com.cpop</groupId>
|
||||
<artifactId>Cpop-Common</artifactId>
|
||||
</dependency>
|
||||
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
|
||||
<!--AOP-->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!-- 提供Redis连接池 -->
|
||||
<!--Mybatis-flex-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<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>
|
||||
<groupId>redis.clients</groupId>
|
||||
@ -42,85 +67,54 @@
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- Sa-Token 整合 jwt -->
|
||||
<!--easyExcel-->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jwt</artifactId>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
</dependency>
|
||||
<!--Mysql-->
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
</dependency>
|
||||
<!--HikariCP-->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<!--Mybatis-flex-->
|
||||
<!--knife4j-Swagger-->
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot3-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>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<!--knife4j-Swagger-->
|
||||
<!--quartz-->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>
|
||||
<!--mongo-plus-->
|
||||
<!-- 腾讯云-->
|
||||
<dependency>
|
||||
<groupId>com.gitee.anwena</groupId>
|
||||
<artifactId>mongo-plus-boot-starter</artifactId>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<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>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.anno;
|
||||
package com.cpop.core.annontation;
|
||||
|
||||
import com.cpop.core.base.enums.OperationLogEnum;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.anno;
|
||||
package com.cpop.core.annontation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.anno;
|
||||
package com.cpop.core.annontation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.core.anno;
|
||||
package com.cpop.core.annontation;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
@ -1,16 +1,15 @@
|
||||
package com.cpop.core.aspect;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.cpop.core.base.entity.R;
|
||||
import com.cpop.core.base.enums.ErrorCodeEnum;
|
||||
import com.cpop.common.constant.HttpStatus;
|
||||
import com.cpop.common.enums.ErrorCodeEnum;
|
||||
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.base.exception.ServiceException;
|
||||
import com.cpop.core.base.table.OperationLog;
|
||||
import com.cpop.core.constant.HttpStatus;
|
||||
import com.cpop.core.base.table.SysOperationLog;
|
||||
import com.cpop.core.event.OperationLogEvent;
|
||||
import com.cpop.core.utils.MessageUtils;
|
||||
import com.cpop.core.utils.SecurityUtils;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
@ -30,7 +29,7 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class OperationLogAspect {
|
||||
|
||||
private final OperationLog operationLog = new OperationLog();
|
||||
private final SysOperationLog operationLog = new SysOperationLog();
|
||||
|
||||
private OperationLogEnum operationLogEnum;
|
||||
|
||||
@ -43,7 +42,7 @@ public class OperationLogAspect {
|
||||
/**
|
||||
* 定义controller切入点拦截规则,拦截SysLog注解的方法
|
||||
*/
|
||||
@Pointcut("@annotation(com.cpop.core.anno.OperationLog)")
|
||||
@Pointcut("@annotation(com.cpop.core.annontation.OperationLog)")
|
||||
public void operationLogAspect() {
|
||||
|
||||
}
|
||||
@ -58,16 +57,18 @@ public class OperationLogAspect {
|
||||
public void recordLog(JoinPoint joinPoint) {
|
||||
//设置枚举信息
|
||||
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();
|
||||
try {
|
||||
SaSession session = StpUtil.getSession();
|
||||
operationLog.setOperationUserName(session.getString("username"))
|
||||
.setOperationUserId(session.getString("userId"))
|
||||
.setOperationUserType((UserType) session.get("userType"))
|
||||
.setDevIp(session.getString("loginIp"))
|
||||
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
|
||||
operationLog.setOperationUserName(loginUser.getUsername())
|
||||
.setOperationUserId(loginUser.getUserId())
|
||||
.setOperationUserType(loginUser.getUserType())
|
||||
.setDevIp(loginUser.getIpAddr())
|
||||
.setCode(operationLogEnum.getCode())
|
||||
.setInfo(MessageUtils.message(operationLogEnum.getInfo()));
|
||||
.setInfo(MessageUtils.message(operationLogEnum.getInfo()))
|
||||
.setCreateUserId(loginUser.getUserId());
|
||||
operationLog.setUpdateUserId(loginUser.getUserId());
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getInfo(), ErrorCodeEnum.OPERATION_LOG_EXCEPTION.getCode());
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
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.UtilException;
|
||||
import com.cpop.core.utils.RsaUtils;
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
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.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.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -41,7 +50,7 @@ public class SignatureCheckAspect {
|
||||
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() {}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
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.UtilException;
|
||||
import com.cpop.core.utils.RsaUtils;
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
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.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.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -45,7 +53,7 @@ public class SimpleSignatureCheckAspect {
|
||||
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() {}
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
@ -13,7 +11,6 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class R<T> implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@ -1,8 +1,6 @@
|
||||
package com.cpop.core.base.entity;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.cpop.core.constant.Constants;
|
||||
import com.cpop.core.utils.SecurityUtils;
|
||||
import com.mybatisflex.annotation.InsertListener;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -17,16 +15,11 @@ public class BaseInsertListener implements InsertListener {
|
||||
@Override
|
||||
public void onInsert(Object entity) {
|
||||
BaseEntity baseEntity = (BaseEntity) entity;
|
||||
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
|
||||
//设置 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.setCreateUserId(userId);
|
||||
baseEntity.setCreateUserId(null == loginUser ? "1" : loginUser.getUserId());
|
||||
baseEntity.setUpdateTime(LocalDateTime.now());
|
||||
baseEntity.setUpdateUserId(userId);
|
||||
baseEntity.setUpdateUserId(null == loginUser ? "1" : loginUser.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package com.cpop.core.base.entity;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.cpop.core.constant.Constants;
|
||||
import com.cpop.core.utils.SecurityUtils;
|
||||
import com.mybatisflex.annotation.UpdateListener;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -17,14 +15,9 @@ public class BaseUpdateListener implements UpdateListener {
|
||||
@Override
|
||||
public void onUpdate(Object entity) {
|
||||
BaseEntity baseEntity = (BaseEntity) entity;
|
||||
String userId;
|
||||
try {
|
||||
userId = StpUtil.getLoginIdDefaultNull() == null ? Constants.SUPER_ADMIN_ID : StpUtil.getLoginIdDefaultNull().toString();
|
||||
} catch (SaTokenException e) {
|
||||
userId = Constants.SUPER_ADMIN_ID;
|
||||
}
|
||||
LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
|
||||
//设置 account 被更新时的一些默认数据
|
||||
baseEntity.setUpdateTime(LocalDateTime.now());
|
||||
baseEntity.setUpdateUserId(userId);
|
||||
baseEntity.setUpdateUserId(null == loginUser ? "1" : loginUser.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package com.cpop.core.base.entity;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
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.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
@ -20,52 +19,42 @@ import java.nio.charset.StandardCharsets;
|
||||
* @Author: DB
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 构造器.
|
||||
*
|
||||
* @param clazz cls
|
||||
*/
|
||||
static {
|
||||
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
|
||||
//如果遇到反序列化autoType is not support错误,请添加并修改一下包名到bean文件路径
|
||||
// ParserConfig.getGlobalInstance().addAccept("com.xxxxx.xxx");
|
||||
}
|
||||
public FastJson2JsonRedisSerializer(Class<T> clazz) {
|
||||
super();
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化.
|
||||
*
|
||||
* @param t object to serialize. Can be {@literal null}.
|
||||
* @return es
|
||||
* @throws SerializationException e
|
||||
*/
|
||||
@Override
|
||||
public byte[] serialize(T t) throws SerializationException {
|
||||
if (t == null) {
|
||||
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
|
||||
public T deserialize(byte[] bytes) throws SerializationException {
|
||||
if (bytes == null || bytes.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
String str = new String(bytes, StandardCharsets.UTF_8);
|
||||
String str = new String(bytes, DEFAULT_CHARSET);
|
||||
|
||||
return JSON.parseObject(str, clazz);
|
||||
}
|
||||
|
||||
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "'objectMapper' must not be null");
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
protected JavaType getJavaType(Class<?> clazz) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -3,7 +3,6 @@ package com.cpop.core.base.entity;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
@ -16,7 +15,6 @@ import java.util.Set;
|
||||
@Accessors(chain = true)
|
||||
public class LoginSuccess implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
|
||||
156
Cpop-Core/src/main/java/com/cpop/core/base/entity/LoginUser.java
Normal file
156
Cpop-Core/src/main/java/com/cpop/core/base/entity/LoginUser.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package com.cpop.core.base.entity;
|
||||
|
||||
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 分页数据
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
package com.cpop.core.base.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 权限组
|
||||
*/
|
||||
@Getter
|
||||
public class Permission {
|
||||
|
||||
/**
|
||||
@ -13,6 +10,10 @@ public class Permission {
|
||||
*/
|
||||
private String permission;
|
||||
|
||||
public String getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public void setPermission(String permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.system.framework.enums;
|
||||
package com.cpop.core.base.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,10 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -12,15 +17,15 @@ public enum UserType {
|
||||
/**
|
||||
* 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
|
||||
@ -32,9 +37,12 @@ public enum UserType {
|
||||
*/
|
||||
private final String key;
|
||||
|
||||
UserType(Integer code, String key) {
|
||||
private final LoginStrategy strategy;
|
||||
|
||||
UserType(Integer code, String key, LoginStrategy strategy) {
|
||||
this.code = code;
|
||||
this.key = key;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,20 +1,15 @@
|
||||
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 lombok.Getter;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 基础异常
|
||||
*
|
||||
* @author DB
|
||||
*/
|
||||
@Getter
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@ -72,4 +67,19 @@ public class BaseException extends RuntimeException {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public String getDefaultMessage() {
|
||||
return defaultMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@ import java.io.Serializable;
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@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 {
|
||||
|
||||
/**
|
||||
* 参数键
|
||||
@ -24,7 +24,7 @@ import java.io.Serializable;
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@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
|
||||
@ -25,7 +25,7 @@ import java.io.Serializable;
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@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 {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
@ -45,16 +45,18 @@ public class AsyncScheduledTaskConfig {
|
||||
executor.setWaitForTasksToCompleteOnShutdown(false);
|
||||
//设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
|
||||
executor.setAwaitTerminationSeconds(config.getAwaitTerminationSeconds());
|
||||
//拒绝处理策略
|
||||
//CallerRunsPolicy():交由调用方线程运行,比如 main 线程。
|
||||
//AbortPolicy():直接抛出异常。
|
||||
//DiscardPolicy():直接丢弃。
|
||||
//DiscardOldestPolicy():丢弃队列中最老的任务。
|
||||
//特殊说明:
|
||||
//1. 这里演示环境,拒绝策略咱们采用抛出异常
|
||||
//2.真实业务场景会把缓存队列的大小会设置大一些,
|
||||
//如果,提交的任务数量超过最大线程数量或将任务环缓存到本地、redis、mysql中,保证消息不丢失
|
||||
//3.如果项目比较大的话,异步通知种类很多的话,建议采用MQ做异步通知方案
|
||||
/**
|
||||
* 拒绝处理策略
|
||||
* CallerRunsPolicy():交由调用方线程运行,比如 main 线程。
|
||||
* AbortPolicy():直接抛出异常。
|
||||
* DiscardPolicy():直接丢弃。
|
||||
* DiscardOldestPolicy():丢弃队列中最老的任务。
|
||||
* 特殊说明:
|
||||
* 1. 这里演示环境,拒绝策略咱们采用抛出异常
|
||||
* 2.真实业务场景会把缓存队列的大小会设置大一些,
|
||||
* 如果,提交的任务数量超过最大线程数量或将任务环缓存到本地、redis、mysql中,保证消息不丢失
|
||||
* 3.如果项目比较大的话,异步通知种类很多的话,建议采用MQ做异步通知方案
|
||||
*/
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
|
||||
//线程初始化
|
||||
executor.initialize();
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.cpop.core.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -9,7 +8,6 @@ import org.springframework.stereotype.Component;
|
||||
*
|
||||
* @author DB
|
||||
*/
|
||||
@Getter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "cpop")
|
||||
public class CpopConfig {
|
||||
@ -31,13 +29,20 @@ public class CpopConfig {
|
||||
/**
|
||||
* 验证码类型
|
||||
*/
|
||||
@Getter
|
||||
private static String captchaType;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
@ -50,6 +55,10 @@ public class CpopConfig {
|
||||
CpopConfig.profile = profile;
|
||||
}
|
||||
|
||||
public static String getCaptchaType() {
|
||||
return captchaType;
|
||||
}
|
||||
|
||||
public void setCaptchaType(String captchaType) {
|
||||
CpopConfig.captchaType = captchaType;
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
package com.cpop.core.config;
|
||||
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.core.filter.XssFilter;
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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.Configuration;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -34,10 +34,11 @@ public class FilterConfig {
|
||||
private String urlPatterns;
|
||||
|
||||
/**
|
||||
* xss过滤器
|
||||
* @return FilterRegistrationBean
|
||||
* @author DB
|
||||
* @since 2023/4/17 9:17
|
||||
* @Description: xss过滤器
|
||||
* @param
|
||||
* @return: FilterRegistrationBean
|
||||
* @Author: DB
|
||||
* @Date: 2023/4/17 9:17
|
||||
**/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
|
||||
@ -1,28 +1,15 @@
|
||||
package com.cpop.core.config;
|
||||
|
||||
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.EnableCaching;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* redis配置
|
||||
*
|
||||
@ -32,24 +19,9 @@ import java.util.Arrays;
|
||||
@EnableCaching
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Autowired
|
||||
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")
|
||||
@Bean
|
||||
@SuppressWarnings(value = {"unchecked", "rawtypes"})
|
||||
@ConditionalOnMissingBean(name = "redisTemplate")
|
||||
public RedisTemplate<Object, Object> redisTemplate(@Qualifier("redisConnectionFactory") RedisConnectionFactory connectionFactory) {
|
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
|
||||
RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(connectionFactory);
|
||||
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
|
||||
@ -63,28 +35,6 @@ public class RedisConfig extends CachingConfigurerSupport {
|
||||
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
|
||||
public DefaultRedisScript<Long> limitScript() {
|
||||
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package com.cpop.core.config;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* @author DB
|
||||
* @version 1.0.0
|
||||
@ -17,13 +14,15 @@ import java.time.Duration;
|
||||
public class RestTemplateConfig {
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
||||
public RestTemplate restTemplate() {
|
||||
// 创建一个 HttpComponentsClientHttpRequestFactory 客户端请求工厂实例
|
||||
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
||||
// 设置连接超时时间为 5 秒
|
||||
restTemplateBuilder.setConnectTimeout(Duration.ofMillis(5000));
|
||||
requestFactory.setConnectTimeout(5000);
|
||||
// 设置读取超时时间为 10 秒
|
||||
restTemplateBuilder.setReadTimeout(Duration.ofMillis(10000));
|
||||
requestFactory.setReadTimeout(10000);
|
||||
// 使用 HttpComponentsClientHttpRequestFactory 客户端请求工厂实例创建 RestTemplate 实例
|
||||
return restTemplateBuilder.build();
|
||||
return new RestTemplate(requestFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
215
Cpop-Core/src/main/java/com/cpop/core/config/SecurityConfig.java
Normal file
215
Cpop-Core/src/main/java/com/cpop/core/config/SecurityConfig.java
Normal 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() + "/");
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
package com.cpop.core.config;
|
||||
|
||||
import com.cpop.core.utils.ServletUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import com.cpop.common.utils.ServletUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 服务相关配置
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.cpop.system.framework.config.tencentCos;
|
||||
package com.cpop.core.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ -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:
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,14 @@
|
||||
package com.cpop.core.filter;
|
||||
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Repeatable 过滤器
|
||||
@ -16,14 +17,14 @@ import java.io.IOException;
|
||||
*/
|
||||
@Component
|
||||
public class RepeatableFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
if (request instanceof HttpServletRequest && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
|
||||
requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package com.cpop.core.filter;
|
||||
|
||||
import com.cpop.common.utils.http.HttpHelper;
|
||||
|
||||
import com.cpop.core.utils.http.HttpHelper;
|
||||
import jakarta.servlet.ReadListener;
|
||||
import jakarta.servlet.ServletInputStream;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package com.cpop.core.filter;
|
||||
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import com.cpop.common.utils.StringUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
package com.cpop.core.filter;
|
||||
|
||||
|
||||
import com.cpop.core.utils.StringUtils;
|
||||
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 com.cpop.common.utils.StringUtils;
|
||||
import com.cpop.common.utils.html.EscapeUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
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.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,23 @@
|
||||
package com.cpop.core.handler;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import com.cpop.core.base.entity.R;
|
||||
import com.cpop.core.base.enums.ErrorCodeEnum;
|
||||
import com.cpop.core.base.R;
|
||||
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.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.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -23,23 +29,23 @@ import java.util.Objects;
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
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)
|
||||
public R<Void> handleServiceException(ServiceException e) {
|
||||
public R handleServiceException(ServiceException 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
|
||||
*/
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
|
||||
public R handleRuntimeException(RuntimeException e, HttpServletRequest request) {
|
||||
String requestUrl = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生未知异常.", requestUrl, e);
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统异常
|
||||
* @param e
|
||||
* @param request
|
||||
* @return
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public R<Void> handleException(Exception e, HttpServletRequest request) {
|
||||
String requestUrl = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生系统异常.", requestUrl, e);
|
||||
return R.fail(e.getMessage());
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
|
||||
return R.fail(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public R<Void> handleBindException(BindException e) {
|
||||
public R handleBindException(BindException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String message = e.getAllErrors().get(0).getDefaultMessage();
|
||||
return R.fail(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义验证异常
|
||||
* 系统异常
|
||||
* @author DB
|
||||
* @since 2023/12/04
|
||||
* @param e 异常
|
||||
* @param request 请求
|
||||
* @return R
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public R<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String message = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
|
||||
return R.fail(message);
|
||||
@ExceptionHandler(Exception.class)
|
||||
public R handleException(Exception e, HttpServletRequest request) {
|
||||
String requestUrl = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生系统异常.", requestUrl, e);
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user