Compare commits

2 Commits

Author SHA1 Message Date
5f7c3b50ff Merge branch 'feature-course' into dev 2025-06-29 23:19:22 +08:00
869fd1a8b1 新增了小程序用户晋升申请的模块 2025-06-29 23:18:58 +08:00
25 changed files with 1149 additions and 98 deletions

View File

@ -43,4 +43,19 @@ public interface UserConstant {
*/ */
String BAN_ROLE = "ban"; String BAN_ROLE = "ban";
/**
* 经理
*/
String MANAGER_ROLE = "manager";
/**
* 主管
*/
String SUPERVISOR_ROLE = "supervisor";
/**
* 员工
*/
String STAFF_ROLE = "staff";
} }

View File

@ -0,0 +1,218 @@
package com.greenorange.promotion.controller.userInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.annotation.SysLog;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.CommonStringRequest;
import com.greenorange.promotion.model.dto.advancementApply.*;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.greenorange.promotion.model.entity.UserInfo;
import com.greenorange.promotion.model.enums.ReviewStatusEnum;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyApproveVO;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyVOPlus;
import com.greenorange.promotion.model.vo.advancementApply.AdvancementApplyVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.userInfo.AdvancementApplyService;
import com.greenorange.promotion.service.userInfo.UserInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.UUID;
/**
* 晋升申请 控制器
*/
@RestController
@RequestMapping("advancementApply")
@Slf4j
@Tag(name = "晋升申请模块")
public class AdvancementApplyController {
@Resource
private AdvancementApplyService advancementApplyService;
@Resource
private CommonService commonService;
@Resource
private UserInfoService userInfoService;
/**
* 小程序段用户添加晋升申请记录
* @param advancementApplyAddRequest 晋升申请记录添加请求体
* @return 申请记录查询凭据
*/
@PostMapping("add")
@Operation(summary = "小程序段用户添加晋升申请记录", description = "参数晋升申请添加请求体权限管理员方法名addAdvancementApply")
@SysLog(title = "晋升申请管理", content = "小程序段用户添加晋升申请记录")
public BaseResponse<String> addAdvancementApply(@Valid @RequestBody AdvancementApplyAddRequest advancementApplyAddRequest) {
String phone = advancementApplyAddRequest.getPhone();
String verificationCode = advancementApplyAddRequest.getVerificationCode();
// 校验用户手机号和验证码
userInfoService.checkPhoneAndVerificationCode(phone, verificationCode, UserRoleEnum.STAFF);
AdvancementApply advancementApply = commonService.copyProperties(advancementApplyAddRequest, AdvancementApply.class);
advancementApply.setCredential(UUID.randomUUID().toString());
advancementApplyService.save(advancementApply);
return ResultUtils.success(advancementApply.getCredential());
}
/**
* 小程序端用户撤销晋升申请记录
* @param commonRequest 晋升申请记录id
* @return 是否更新成功
*/
@PostMapping("modify/status")
@Operation(summary = "小程序端用户撤销晋升申请记录", description = "参数晋升申请更新请求体权限管理员方法名revokeAdvancementApply")
@SysLog(title = "晋升申请管理", content = "小程序端用户撤销晋升申请记录")
public BaseResponse<Boolean> revokeAdvancementApply(@Valid @RequestBody CommonRequest commonRequest) {
Long id = commonRequest.getId();
LambdaUpdateWrapper<AdvancementApply> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(AdvancementApply::getId, id).set(AdvancementApply::getReviewStatus, ReviewStatusEnum.WITHDRAWN.getValue());
advancementApplyService.update(updateWrapper);
return ResultUtils.success(true);
}
/**
* 小程序端用户根据id修改晋升申请记录信息
* @param advancementApplyUpdateRequest 晋升申请更新请求体
* @return 是否更新成功
*/
@PostMapping("update")
@Operation(summary = "小程序端用户根据id修改晋升申请记录信息", description = "参数晋升申请更新请求体权限管理员方法名updateAdvancementApply")
@SysLog(title = "晋升申请管理", content = "小程序端用户根据id修改晋升申请记录信息")
public BaseResponse<Boolean> updateAdvancementApply(@Valid @RequestBody AdvancementApplyUpdateRequest advancementApplyUpdateRequest) {
String phone = advancementApplyUpdateRequest.getPhone();
String verificationCode = advancementApplyUpdateRequest.getVerificationCode();
// 校验用户手机号和验证码
userInfoService.checkPhoneAndVerificationCode(phone, verificationCode, UserRoleEnum.STAFF);
AdvancementApply advancementApply = commonService.copyProperties(advancementApplyUpdateRequest, AdvancementApply.class);
advancementApplyService.updateById(advancementApply);
return ResultUtils.success(true);
}
/**
* 小程序端用户根据凭证credential查询晋升申请记录
* @param commonStringRequest 查询凭证
* @return 晋升申请记录信息
*/
@PostMapping("query/credential")
@Operation(summary = "小程序端用户根据凭证credential查询晋升申请记录", description = "参数晋升申请更新请求体权限管理员方法名queryAdvancementApplyByCredential")
@SysLog(title = "晋升申请管理", content = "小程序端用户根据凭证credential查询晋升申请记录")
public BaseResponse<AdvancementApplyApproveVO> queryAdvancementApplyByCredential(@Valid @RequestBody CommonStringRequest commonStringRequest) {
String credential = commonStringRequest.getTemplateString();
LambdaQueryWrapper<AdvancementApply> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(AdvancementApply::getCredential, credential);
AdvancementApply advancementApply = advancementApplyService.getOne(lambdaQueryWrapper);
AdvancementApplyApproveVO advancementApplyApproveVO = commonService.copyProperties(advancementApply, AdvancementApplyApproveVO.class);
String reviewStatus = advancementApply.getReviewStatus();
ReviewStatusEnum reviewStatusEnum = ReviewStatusEnum.getEnumByValue(reviewStatus);
// 如果审核通过,填充账号密码
if (ReviewStatusEnum.APPROVED.equals(reviewStatusEnum)) {
Long userId = advancementApply.getUserId();
UserInfo userInfo = userInfoService.getById(userId);
advancementApplyApproveVO.setUserAccount(userInfo.getUserAccount());
advancementApplyApproveVO.setUserPassword(userInfo.getUserPassword());
}
// 如果审核拒绝,填充拒绝理由
if (ReviewStatusEnum.REJECTED.equals(reviewStatusEnum)) {
advancementApplyApproveVO.setRejectReason(advancementApply.getRejectReason());
}
return ResultUtils.success(advancementApplyApproveVO);
}
/**
* web端管理员批准用户的晋升申请
* @param advancementApplyApproveRequest 晋升申请等信息
* @return 晋升用户的账号密码
*/
@PostMapping("approve")
@Operation(summary = "web端管理员批准用户的晋升申请", description = "参数晋升申请id权限管理员方法名approveAdvancementApply")
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
@SysLog(title = "晋升申请管理", content = "web端管理员批准用户的晋升申请")
public BaseResponse<Boolean> approveAdvancementApply(@Valid @RequestBody AdvancementApplyApproveRequest advancementApplyApproveRequest) {
userInfoService.staffUserInfoMiniRegister(advancementApplyApproveRequest);
return ResultUtils.success(true);
}
/**
* web端管理员拒绝晋升申请
* @param advancementApplyRejectRequest 晋升申请拒绝请求体
* @return 晋升申请信息
*/
@PostMapping("reject")
@Operation(summary = "web端管理员拒绝晋升申请", description = "参数晋升申请拒绝请求体权限管理员方法名rejectAdvancementApply")
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
@SysLog(title = "晋升申请管理", content = "web端管理员拒绝晋升申请")
public BaseResponse<Boolean> rejectAdvancementApply(@Valid @RequestBody AdvancementApplyRejectRequest advancementApplyRejectRequest) {
Long applyId = advancementApplyRejectRequest.getApplyId();
String rejectReason = advancementApplyRejectRequest.getRejectReason();
LambdaUpdateWrapper<AdvancementApply> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(AdvancementApply::getId, applyId)
.set(AdvancementApply::getReviewStatus, ReviewStatusEnum.REJECTED.getValue())
.set(AdvancementApply::getRejectReason, rejectReason);
advancementApplyService.update(updateWrapper);
return ResultUtils.success(true);
}
/**
* web端管理员根据id查询晋升申请
* @param commonRequest 晋升申请id
* @return 晋升申请信息
*/
@PostMapping("queryById")
@Operation(summary = "web端管理员根据id查询晋升申请", description = "参数晋升申请id权限管理员方法名queryAdvancementApplyById")
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
@SysLog(title = "晋升申请管理", content = "web端管理员根据id查询晋升申请")
public BaseResponse<AdvancementApplyVOPlus> queryAdvancementApplyById(@Valid @RequestBody CommonRequest commonRequest) {
Long id = commonRequest.getId();
AdvancementApply advancementApply = advancementApplyService.getById(id);
AdvancementApplyVOPlus advancementApplyVOPlus = commonService.copyProperties(advancementApply, AdvancementApplyVOPlus.class);
return ResultUtils.success(advancementApplyVOPlus);
}
/**
* Web端管理员分页查询晋升申请
* @param advancementApplyQueryRequest 晋升申请查询请求体
* @return 晋升申请列表
*/
@PostMapping("page")
@Operation(summary = "Web端管理员分页查询晋升申请", description = "参数晋升申请查询请求体权限管理员方法名listAdvancementApplyByPage")
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
@SysLog(title = "晋升申请管理", content = "Web端管理员分页查询晋升申请")
public BaseResponse<Page<AdvancementApplyVO>> listAdvancementApplyByPage(@Valid @RequestBody AdvancementApplyQueryRequest advancementApplyQueryRequest) {
long current = advancementApplyQueryRequest.getCurrent();
long pageSize = advancementApplyQueryRequest.getPageSize();
QueryWrapper<AdvancementApply> queryWrapper = advancementApplyService.getQueryWrapper(advancementApplyQueryRequest);
Page<AdvancementApply> page = advancementApplyService.page(new Page<>(current, pageSize), queryWrapper);
List<AdvancementApply> advancementApplyList = page.getRecords();
List<AdvancementApplyVO> advancementApplyVOList = commonService.convertList(advancementApplyList, AdvancementApplyVO.class);
Page<AdvancementApplyVO> voPage = new Page<>(current, pageSize);
voPage.setRecords(advancementApplyVOList);
voPage.setPages(page.getPages());
voPage.setTotal(page.getTotal());
return ResultUtils.success(voPage);
}
}

View File

@ -13,6 +13,7 @@ import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.userAccount.UserAccountAddRequest; import com.greenorange.promotion.model.dto.userAccount.UserAccountAddRequest;
import com.greenorange.promotion.model.dto.userAccount.UserAccountQueryRequest; import com.greenorange.promotion.model.dto.userAccount.UserAccountQueryRequest;
import com.greenorange.promotion.model.dto.userAccount.UserAccountUpdateRequest; import com.greenorange.promotion.model.dto.userAccount.UserAccountUpdateRequest;
import com.greenorange.promotion.model.entity.ProjectSettlement;
import com.greenorange.promotion.model.entity.UserAccount; import com.greenorange.promotion.model.entity.UserAccount;
import com.greenorange.promotion.model.vo.userAccount.UserAccountVO; import com.greenorange.promotion.model.vo.userAccount.UserAccountVO;
import com.greenorange.promotion.service.common.CommonService; import com.greenorange.promotion.service.common.CommonService;

View File

@ -27,13 +27,13 @@ public class Generator {
// 作者 // 作者
private static final String AUTHOR = "chenxinzhi"; private static final String AUTHOR = "chenxinzhi";
// 表注释 // 表注释
private static final String TABLE_COMMENT = "课程订单"; private static final String TABLE_COMMENT = "晋升申请";
// 实体类名 // 实体类名
private static final String ENTITY_NAME = "CourseOrder"; private static final String ENTITY_NAME = "AdvancementApply";
// 表名 // 表名
private static final String TABLE_NAME = "course_order"; private static final String TABLE_NAME = "advancement_apply";
// 实体类属性名 // 实体类属性名
private static final String ENTITY_NAME_LOWER = "courseOrder"; private static final String ENTITY_NAME_LOWER = "advancementApply";
// 父包名 // 父包名
private static final String PARENT_PATH = "com.greenorange.promotion"; private static final String PARENT_PATH = "com.greenorange.promotion";

View File

@ -0,0 +1,18 @@
package com.greenorange.promotion.mapper;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author 35880
* @description 针对表【advancement_apply(晋升申请表)】的数据库操作Mapper
* @createDate 2025-06-29 12:39:54
* @Entity com.greenorange.promotion.model.entity.AdvancementApply
*/
public interface AdvancementApplyMapper extends BaseMapper<AdvancementApply> {
}

View File

@ -0,0 +1,54 @@
package com.greenorange.promotion.model.dto.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;
import lombok.Data;
import java.math.BigDecimal;
import java.io.Serial;
import java.io.Serializable;
/**
* 晋升申请添加请求体
*/
@Data
@Schema(description = "晋升申请添加请求体", requiredProperties = {
"name",
"verificationCode"
})
public class AdvancementApplyAddRequest implements Serializable {
/**
* 申请人姓名
*/
@NotBlank(message = "申请人姓名不能为空")
@Schema(description = "申请人姓名", example = "张三")
private String name;
/**
* 申请人手机号
*/
@NotBlank(message = "申请人手机号不能为空")
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 验证码
*/
@NotBlank(message = "验证码不能为空")
@Schema(description = "验证码", example = "666999")
private String verificationCode;
/**
* 简历(view值)
*/
@NotBlank(message = "简历(view值)不能为空")
@Schema(description = "简历(view值)", example = "D89SKF3N")
private String resume;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,49 @@
package com.greenorange.promotion.model.dto.advancementApply;
import com.greenorange.promotion.annotation.EnumValue;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 晋升申请批准请求体
*/
@Data
@Schema(description = "晋升申请批准请求体", requiredProperties = {
"applyId",
"invitationCode",
"userRole"
})
public class AdvancementApplyApproveRequest implements Serializable {
/**
* 晋升申请id
*/
@Min(value = 1, message = "晋升申请id不能小于1")
@Schema(description = "晋升申请id", example = "1")
private Long applyId;
/**
* 邀请码
*/
@NotBlank(message = "邀请码不能为空")
@Schema(description = "邀请码", example = "666999")
private String invitationCode;
/**
* 用户角色
*/
@NotBlank(message = "用户角色不能为空")
@EnumValue(enumClass = UserRoleEnum.class)
@Schema(description = "用户角色", example = "user")
private String userRole;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,42 @@
package com.greenorange.promotion.model.dto.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;
import lombok.Data;
import java.math.BigDecimal;
import java.io.Serial;
import java.io.Serializable;
import com.greenorange.promotion.common.PageRequest;
/**
* 晋升申请查询请求体,继承自分页请求 PageRequest
*/
@Data
@Schema(description = "晋升申请查询请求体", requiredProperties = {"current", "pageSize"})
public class AdvancementApplyQueryRequest extends PageRequest implements Serializable {
/**
* 申请人姓名
*/
@Schema(description = "申请人姓名", example = "张三")
private String name;
/**
* 申请人手机号
*/
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 审核状态
*/
@Schema(description = "审核状态", example = "待审核")
private String reviewStatus;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,40 @@
package com.greenorange.promotion.model.dto.advancementApply;
import com.greenorange.promotion.annotation.EnumValue;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 晋升申请拒绝请求体
*/
@Data
@Schema(description = "晋升申请拒绝请求体", requiredProperties = {
"applyId",
"rejectReason"
})
public class AdvancementApplyRejectRequest implements Serializable {
/**
* 晋升申请id
*/
@Min(value = 1, message = "晋升申请id不能小于1")
@Schema(description = "晋升申请id", example = "1")
private Long applyId;
/**
* 拒绝理由
*/
@NotBlank(message = "拒绝理由不能为空")
@Schema(description = "拒绝理由", example = "拒绝理由")
private String rejectReason;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,71 @@
package com.greenorange.promotion.model.dto.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;
import lombok.Data;
import java.math.BigDecimal;
import java.io.Serial;
import java.io.Serializable;
/**
* 晋升申请更新请求体
*/
@Data
@Schema(description = "晋升申请更新请求体", requiredProperties = {
"id",
"name",
"phone",
"verificationCode",
"resume",
"reviewStatus",
})
public class AdvancementApplyUpdateRequest implements Serializable {
/**
* 晋升申请id
*/
@Min(value = 1L, message = "晋升申请id ID不能小于1")
@Schema(description = "晋升申请id", example = "张三")
private Long id;
/**
* 申请人姓名
*/
@NotBlank(message = "申请人姓名不能为空")
@Schema(description = "申请人姓名", example = "")
private String name;
/**
* 申请人手机号
*/
@NotBlank(message = "申请人手机号不能为空")
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 验证码
*/
@NotBlank(message = "验证码不能为空")
@Schema(description = "验证码", example = "666999")
private String verificationCode;
/**
* 简历(view值)
*/
@NotBlank(message = "简历(view值)不能为空")
@Schema(description = "简历(view值)", example = "3DFK2K3J")
private String resume;
/**
* 审核状态
*/
@NotBlank(message = "审核状态不能为空")
@Schema(description = "审核状态", example = "待审核")
private String reviewStatus;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -4,7 +4,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;

View File

@ -3,7 +3,10 @@ package com.greenorange.promotion.model.dto.userInfo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;

View File

@ -0,0 +1,76 @@
package com.greenorange.promotion.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 晋升申请表
* @TableName advancement_apply
*/
@TableName(value ="advancement_apply")
@Data
public class AdvancementApply implements Serializable {
/**
* 晋升申请id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 申请人姓名
*/
private String name;
/**
* 申请人手机号
*/
private String phone;
/**
* 简历
*/
private String resume;
/**
* 查询凭证
*/
private String credential;
/**
* 审核状态
*/
private String reviewStatus;
/**
* 拒绝理由
*/
private String rejectReason;
/**
* 用户id(申请成功后获得)
*/
private Long userId;
/**
* 是否删除
*/
private Integer isDelete;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -18,6 +18,9 @@ import lombok.NoArgsConstructor;
*/ */
@TableName(value ="user_info") @TableName(value ="user_info")
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserInfo implements Serializable { public class UserInfo implements Serializable {
/** /**
* 用户ID * 用户ID

View File

@ -0,0 +1,59 @@
package com.greenorange.promotion.model.enums;
import com.greenorange.promotion.annotation.BaseEnum;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 审核状态枚举
*/
@Getter
public enum ReviewStatusEnum implements BaseEnum {
PENDING("待审核"),
APPROVED("已通过"),
REJECTED("已拒绝"),
WITHDRAWN("已撤回");
private final String value;
ReviewStatusEnum(String value) {
this.value = value;
}
/**
* BaseEnum 要求的方法:返回枚举对应的校验值
*/
@Override
public String getValue() {
return this.value;
}
/**
* 获取所有枚举值列表
*/
public static List<String> getValues() {
return Arrays.stream(values())
.map(ReviewStatusEnum::getValue)
.collect(Collectors.toList());
}
/**
* 根据值获取对应的枚举对象
*/
public static ReviewStatusEnum getEnumByValue(String value) {
if (StringUtils.isBlank(value)) {
return null;
}
for (ReviewStatusEnum status : ReviewStatusEnum.values()) {
if (status.value.equals(value)) {
return status;
}
}
return null;
}
}

View File

@ -18,7 +18,10 @@ public enum UserRoleEnum implements BaseEnum {
USER("用户", "user"), USER("用户", "user"),
ADMIN("管理员", "admin"), ADMIN("管理员", "admin"),
BOSS("Boss", "boss"), BOSS("Boss", "boss"),
BAN("被封号", "ban"); BAN("被封号", "ban"),
MANAGER("经理", "manager"),
SUPERVISOR("主管", "supervisor"),
STAFF("员工", "staff");
private final String text; private final String text;

View File

@ -0,0 +1,57 @@
package com.greenorange.promotion.model.vo.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 晋升申请审核结果 视图对象
*/
@Data
@Schema(description = "晋升申请审核结果 视图对象")
public class AdvancementApplyApproveVO implements Serializable {
/**
* 申请人姓名
*/
@Schema(description = "申请人姓名", example = "张三")
private String name;
/**
* 申请人手机号
*/
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 审核状态
*/
@Schema(description = "审核状态", example = "待审核")
private String reviewStatus;
/**
* 拒绝理由
*/
@Schema(description = "拒绝理由", example = "")
private String rejectReason;
/**
* 账号
*/
@Schema(description = "账号", example = "qingcheng")
private String userAccount;
/**
* 密码(建议加密存储)
*/
@Schema(description = "密码(建议加密存储)", example = "qingcheng")
private String userPassword;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,64 @@
package com.greenorange.promotion.model.vo.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;
/**
* 晋升申请 视图对象
*/
@Data
@Schema(description = "晋升申请 视图对象")
public class AdvancementApplyVO implements Serializable {
/**
* 晋升申请ID
*/
@Schema(description = "晋升申请ID", example = "1")
private Long id;
/**
* 申请人姓名
*/
@Schema(description = "申请人姓名", example = "张三")
private String name;
/**
* 申请人手机号
*/
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 简历(view值)
*/
@Schema(description = "简历(view值)", example = "32DK8DKL8")
private String resume;
/**
* 查询凭证
*/
@Schema(description = "查询凭证", example = "cef281c7-578f-4cc9-aca9-f1b5f6bcacb1")
private String credential;
/**
* 审核状态
*/
@Schema(description = "审核状态", example = "待审核")
private String reviewStatus;
/**
* 创建时间
*/
@Schema(description = "创建时间", example = "2023-03-01 00:00:00")
private Date createTime;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,64 @@
package com.greenorange.promotion.model.vo.advancementApply;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 晋升申请记录id查询 视图对象
*/
@Data
@Schema(description = "晋升申请记录id查询 视图对象")
public class AdvancementApplyVOPlus implements Serializable {
/**
* 晋升申请ID
*/
@Schema(description = "晋升申请ID", example = "1")
private Long id;
/**
* 申请人姓名
*/
@Schema(description = "申请人姓名", example = "张三")
private String name;
/**
* 申请人手机号
*/
@Schema(description = "申请人手机号", example = "15888610253")
private String phone;
/**
* 简历(view值)
*/
@Schema(description = "简历(view值)", example = "32DK8DKL8")
private String resume;
/**
* 查询凭证
*/
@Schema(description = "查询凭证", example = "cef281c7-578f-4cc9-aca9-f1b5f6bcacb1")
private String credential;
/**
* 审核状态
*/
@Schema(description = "审核状态", example = "待审核")
private String reviewStatus;
/**
* 拒绝理由
*/
@Schema(description = "拒绝理由", example = "")
private String rejectReason;
/**
* 创建时间
*/
@Schema(description = "创建时间", example = "2023-03-01 00:00:00")
private Date createTime;
}

View File

@ -0,0 +1,20 @@
package com.greenorange.promotion.service.userInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.greenorange.promotion.model.dto.advancementApply.AdvancementApplyQueryRequest;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author 35880
* @description 针对表【advancement_apply(晋升申请表)】的数据库操作Service
* @createDate 2025-06-29 12:39:54
*/
public interface AdvancementApplyService extends IService<AdvancementApply> {
/**
* 获取查询条件
*/
QueryWrapper<AdvancementApply> getQueryWrapper(AdvancementApplyQueryRequest advancementApplyQueryRequest);
}

View File

@ -1,10 +1,13 @@
package com.greenorange.promotion.service.userInfo; package com.greenorange.promotion.service.userInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.greenorange.promotion.model.dto.userInfo.*;
import com.greenorange.promotion.model.entity.UserInfo;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletRequest; import com.greenorange.promotion.model.dto.advancementApply.AdvancementApplyApproveRequest;
import com.greenorange.promotion.model.dto.userInfo.*;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.greenorange.promotion.model.entity.UserInfo;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import java.util.List; import java.util.List;
@ -68,4 +71,22 @@ public interface UserInfoService extends IService<UserInfo> {
* 查询从 userId 一路到根节点的所有 id按 depth 倒序(根先出) * 查询从 userId 一路到根节点的所有 id按 depth 倒序(根先出)
*/ */
List<Long> findPathToRoot(Long userId); List<Long> findPathToRoot(Long userId);
/**
* 校验用户手机号和验证码
*/
void checkPhoneAndVerificationCode(String phoneNumber, String verificationCode, UserRoleEnum userRoleEnum);
/**
* 根据用户权限来获取条件构造器
*/
LambdaQueryWrapper<UserInfo> getQueryWrapperByUserRole(UserRoleEnum userRoleEnum, LambdaQueryWrapper<UserInfo> lambdaQueryWrapper);
/**
* 小程序端员工信息注册
*/
void staffUserInfoMiniRegister(AdvancementApplyApproveRequest advancementApplyApproveRequest);
} }

View File

@ -0,0 +1,44 @@
package com.greenorange.promotion.service.userInfo.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.greenorange.promotion.constant.CommonConstant;
import com.greenorange.promotion.model.dto.advancementApply.AdvancementApplyQueryRequest;
import com.greenorange.promotion.model.entity.AdvancementApply;
import com.greenorange.promotion.service.userInfo.AdvancementApplyService;
import com.greenorange.promotion.mapper.AdvancementApplyMapper;
import com.greenorange.promotion.utils.SqlUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
* @author 35880
* @description 针对表【advancement_apply(晋升申请表)】的数据库操作Service实现
* @createDate 2025-06-29 12:39:54
*/
@Service
public class AdvancementApplyServiceImpl extends ServiceImpl<AdvancementApplyMapper, AdvancementApply>
implements AdvancementApplyService{
/**
* 获取查询条件
*/
@Override
public QueryWrapper<AdvancementApply> getQueryWrapper(AdvancementApplyQueryRequest advancementApplyQueryRequest) {
String name = advancementApplyQueryRequest.getName();
String phone = advancementApplyQueryRequest.getPhone();
String reviewStatus = advancementApplyQueryRequest.getReviewStatus();
String sortField = advancementApplyQueryRequest.getSortField();
String sortOrder = advancementApplyQueryRequest.getSortOrder();
QueryWrapper<AdvancementApply> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(StringUtils.isNotBlank(name), "name", name);
queryWrapper.eq(StringUtils.isNotBlank(phone), "phone", phone);
queryWrapper.eq(StringUtils.isNotBlank(reviewStatus), "reviewStatus", reviewStatus);
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_DESC), sortField);
return queryWrapper;
}
}

View File

@ -10,16 +10,20 @@ import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.constant.CommonConstant; import com.greenorange.promotion.constant.CommonConstant;
import com.greenorange.promotion.constant.SystemConstant; import com.greenorange.promotion.constant.SystemConstant;
import com.greenorange.promotion.constant.UserConstant; import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.exception.BusinessException;
import com.greenorange.promotion.exception.ThrowUtils; import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.mapper.UserInfoMapper; import com.greenorange.promotion.mapper.UserInfoMapper;
import com.greenorange.promotion.model.dto.advancementApply.AdvancementApplyApproveRequest;
import com.greenorange.promotion.model.dto.projectCommission.ProjectCommissionAddRequest; import com.greenorange.promotion.model.dto.projectCommission.ProjectCommissionAddRequest;
import com.greenorange.promotion.model.dto.userInfo.*; import com.greenorange.promotion.model.dto.userInfo.*;
import com.greenorange.promotion.model.entity.*; import com.greenorange.promotion.model.entity.*;
import com.greenorange.promotion.model.enums.ReviewStatusEnum;
import com.greenorange.promotion.model.enums.UserRoleEnum; import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.service.common.CommonService; import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.project.ProjectCommissionService; import com.greenorange.promotion.service.project.ProjectCommissionService;
import com.greenorange.promotion.service.project.ProjectDetailService; import com.greenorange.promotion.service.project.ProjectDetailService;
import com.greenorange.promotion.service.project.SubUserProjectCommissionService; import com.greenorange.promotion.service.project.SubUserProjectCommissionService;
import com.greenorange.promotion.service.userInfo.AdvancementApplyService;
import com.greenorange.promotion.service.userInfo.UserInfoService; import com.greenorange.promotion.service.userInfo.UserInfoService;
import com.greenorange.promotion.service.userInfo.UserMainInfoService; import com.greenorange.promotion.service.userInfo.UserMainInfoService;
import com.greenorange.promotion.service.wechat.WechatGetQrcodeService; import com.greenorange.promotion.service.wechat.WechatGetQrcodeService;
@ -28,7 +32,6 @@ import com.greenorange.promotion.utils.RegexUtils;
import com.greenorange.promotion.utils.SendSmsUtil; import com.greenorange.promotion.utils.SendSmsUtil;
import com.greenorange.promotion.utils.SqlUtils; import com.greenorange.promotion.utils.SqlUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -36,13 +39,11 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/** /**
* @author 35880 * @author 35880
@ -89,6 +90,10 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
private ProjectDetailService projectDetailService; private ProjectDetailService projectDetailService;
@Resource
private AdvancementApplyService advancementApplyService;
/** /**
@ -131,6 +136,10 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
} }
/** /**
* 小程序用户注册 * 小程序用户注册
*/ */
@ -138,87 +147,31 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void userInfoMiniRegister(UserInfoRegisterRequest userInfoRegisterRequest) { public void userInfoMiniRegister(UserInfoRegisterRequest userInfoRegisterRequest) {
String phoneNumber = userInfoRegisterRequest.getPhoneNumber(); String phoneNumber = userInfoRegisterRequest.getPhoneNumber();
ThrowUtils.throwIf(RegexUtils.isPhoneInvalid(phoneNumber), ErrorCode.PARAMS_ERROR, "手机号格式无效");
LambdaQueryWrapper<UserInfo> phoneNumberLambdaQueryWrapper = new LambdaQueryWrapper<>();
phoneNumberLambdaQueryWrapper.eq(UserInfo::getPhoneNumber, phoneNumber);
UserInfo userInfo = this.getOne(phoneNumberLambdaQueryWrapper);
ThrowUtils.throwIf(userInfo != null, ErrorCode.OPERATION_ERROR, "手机号已注册");
String verificationCode = userInfoRegisterRequest.getVerificationCode(); String verificationCode = userInfoRegisterRequest.getVerificationCode();
String code = redisTemplate.opsForValue().get(SystemConstant.VERIFICATION_CODE + ":" + verificationCode); // 校验用户手机号和验证码
ThrowUtils.throwIf(code == null, ErrorCode.OPERATION_ERROR, "验证码已失效"); checkPhoneAndVerificationCode(phoneNumber, verificationCode, UserRoleEnum.USER);
// // 移除验证码
// redisTemplate.delete(SystemConstant.VERIFICATION_CODE + ":" + verificationCode);
// 根据邀请码获得上级用户信息
String invitationCode = userInfoRegisterRequest.getInvitationCode(); String invitationCode = userInfoRegisterRequest.getInvitationCode();
LambdaQueryWrapper<UserInfo> invitedLambdaQueryWrapper = new LambdaQueryWrapper<>(); UserInfo parentUserInfo = getParentUserInfoByInvitationCode(invitationCode);
invitedLambdaQueryWrapper.eq(UserInfo::getInvitationCode, invitationCode).eq(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE);
UserInfo parentUserInfo = this.getOne(invitedLambdaQueryWrapper);
ThrowUtils.throwIf(parentUserInfo == null, ErrorCode.OPERATION_ERROR, "邀请码错误");
// 保存用户
UserInfo myUserInfo = commonService.copyProperties(userInfoRegisterRequest, UserInfo.class); UserInfo myUserInfo = commonService.copyProperties(userInfoRegisterRequest, UserInfo.class);
// 判断当前用户是否是根节点
List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE, this);
if (userInfoList.isEmpty()) myUserInfo.setParentUserId(0L);
myUserInfo.setParentUserId(parentUserInfo.getId()); myUserInfo.setParentUserId(parentUserInfo.getId());
myUserInfo.setInvitationCode(RandomUtil.randomNumbers(6)); myUserInfo.setInvitationCode(RandomUtil.randomNumbers(6));
myUserInfo.setUserAccount(phoneNumber); myUserInfo.setUserAccount(phoneNumber);
myUserInfo.setUserRole(UserConstant.DEFAULT_ROLE); myUserInfo.setUserRole(UserConstant.DEFAULT_ROLE);
myUserInfo.setUserAvatar(UserConstant.USER_DEFAULT_AVATAR); myUserInfo.setUserAvatar(UserConstant.USER_DEFAULT_AVATAR);
this.save(myUserInfo); this.save(myUserInfo);
UserMainInfo userMainInfo = new UserMainInfo();
userMainInfo.setUserId(myUserInfo.getId());
// 批量更新父级用户团队人数 // 批量更新父级用户团队人数
List<Long> pathToRoot = this.findPathToRoot(myUserInfo.getId()); UserMainInfo userMainInfo = updateParentUserInfoTeamCount(myUserInfo.getId());
List<UserMainInfo> userMainInfoList = commonService.findByFieldInTargetField(pathToRoot, userMainInfoService, id -> id, UserMainInfo::getUserId);
for (UserMainInfo mainInfo : userMainInfoList) {
mainInfo.setTeamSize(mainInfo.getTeamSize() + 1);
}
userMainInfoService.updateBatchById(userMainInfoList);
// 生成邀请二维码 // 生成邀请二维码
try { generateInvitationQrcode(userMainInfo, myUserInfo.getInvitationCode());
String view = wechatGetQrcodeService.getWxQrCode(myUserInfo.getInvitationCode());
userMainInfo.setInviteQrCode(view);
} catch (IOException e) {
e.printStackTrace();
}
userMainInfoService.save(userMainInfo);
// 查询上级用户项目抽佣记录 // 批量保存当前用户的项目明细抽佣记录和下级用户项目明细抽佣记录
List<ProjectCommission> projectCommissionList = commonService.findByFieldEqTargetField(ProjectCommission::getUserId, parentUserInfo.getId(), projectCommissionService); saveBatchProjectCommissionAndSubUserProjectCommission(myUserInfo.getId(), parentUserInfo.getId());
// 封装Map集合项目明细id, 值:项目最小价格)
Map<Long, BigDecimal> projectDetailMinPriceMap = new HashMap<>();
List<ProjectDetail> projectDetailList = commonService.findByFieldInTargetField(projectCommissionList, projectDetailService, ProjectCommission::getProjectDetailId, ProjectDetail::getId);
for (ProjectDetail projectDetail : projectDetailList) {
projectDetailMinPriceMap.put(projectDetail.getId(), projectDetail.getProjectMinSettlementPrice());
}
// 插入当前用户的项目抽佣记录
List<ProjectCommission> projectCommissions = new ArrayList<>();
for (ProjectCommission projectCommission : projectCommissionList) {
ProjectCommissionAddRequest projectCommissionAddRequest = commonService.copyProperties(projectCommission, ProjectCommissionAddRequest.class);
ProjectCommission proCommission = commonService.copyProperties(projectCommissionAddRequest, ProjectCommission.class);
// 获取当前项目明细的最小结算价格
BigDecimal projectMinSettlementPrice = projectDetailMinPriceMap.get(projectCommission.getProjectDetailId());
BigDecimal currentSettlementPrice = projectCommission.getMyUnitPrice().multiply(BigDecimal.ONE.subtract(projectCommission.getCurrentCommissionRate().divide(BigDecimal.valueOf(100))));
// 比较当前结算价格和项目明细最小结算价格,取出最大值
proCommission.setMyUnitPrice(projectMinSettlementPrice.max(currentSettlementPrice));
proCommission.setCurrentCommissionRate(BigDecimal.ZERO);
proCommission.setUserId(myUserInfo.getId());
projectCommissions.add(proCommission);
}
projectCommissionService.saveBatch(projectCommissions);
// 插入下级用户的项目明细抽佣记录
List<SubUserProjectCommission> subUserProjectCommissionList = new ArrayList<>();
for (ProjectCommission projectCommission : projectCommissionList) {
ProjectCommissionAddRequest projectCommissionAddRequest = commonService.copyProperties(projectCommission, ProjectCommissionAddRequest.class);
SubUserProjectCommission subUserProjectCommission = commonService.copyProperties(projectCommissionAddRequest, SubUserProjectCommission.class);
subUserProjectCommission.setSubUserId(myUserInfo.getId());
subUserProjectCommissionList.add(subUserProjectCommission);
}
subUserProjectCommissionService.saveBatch(subUserProjectCommissionList);
} }
@ -254,14 +207,9 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
@Override @Override
public String userInfoMiniLoginByVcd(UserInfoMiniVerifyCodeLoginRequest userInfoMiniVerifyCodeLoginRequest) { public String userInfoMiniLoginByVcd(UserInfoMiniVerifyCodeLoginRequest userInfoMiniVerifyCodeLoginRequest) {
String phoneNumber = userInfoMiniVerifyCodeLoginRequest.getPhoneNumber(); String phoneNumber = userInfoMiniVerifyCodeLoginRequest.getPhoneNumber();
ThrowUtils.throwIf(RegexUtils.isPhoneInvalid(phoneNumber), ErrorCode.PARAMS_ERROR, "手机号格式无效");
String verificationCode = userInfoMiniVerifyCodeLoginRequest.getVerificationCode(); String verificationCode = userInfoMiniVerifyCodeLoginRequest.getVerificationCode();
String code = redisTemplate.opsForValue().get(SystemConstant.VERIFICATION_CODE + ":" + verificationCode); // 校验用户手机号和验证码
ThrowUtils.throwIf(code == null, ErrorCode.OPERATION_ERROR, "验证码已失效"); checkPhoneAndVerificationCode(phoneNumber, verificationCode, null);
// // 移除验证码
// redisTemplate.delete(SystemConstant.VERIFICATION_CODE + ":" + verificationCode);
LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserInfo::getPhoneNumber, phoneNumber); lambdaQueryWrapper.eq(UserInfo::getPhoneNumber, phoneNumber);
@ -282,14 +230,9 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
@Override @Override
public void userInfoMiniResetPwd(UserInfoResetRequest userInfoResetRequest, boolean isInner) { public void userInfoMiniResetPwd(UserInfoResetRequest userInfoResetRequest, boolean isInner) {
String phoneNumber = userInfoResetRequest.getPhoneNumber(); String phoneNumber = userInfoResetRequest.getPhoneNumber();
ThrowUtils.throwIf(RegexUtils.isPhoneInvalid(phoneNumber), ErrorCode.PARAMS_ERROR, "手机号格式无效");
String verificationCode = userInfoResetRequest.getVerificationCode(); String verificationCode = userInfoResetRequest.getVerificationCode();
String code = redisTemplate.opsForValue().get(SystemConstant.VERIFICATION_CODE + ":" + verificationCode); // 校验用户手机号和验证码
ThrowUtils.throwIf(code == null, ErrorCode.OPERATION_ERROR, "验证码已失效"); checkPhoneAndVerificationCode(phoneNumber, verificationCode, null);
// // 移除验证码
// redisTemplate.delete(SystemConstant.VERIFICATION_CODE + ":" + verificationCode);
String userPassword = userInfoResetRequest.getUserPassword(); String userPassword = userInfoResetRequest.getUserPassword();
String userConfirmPassword = userInfoResetRequest.getUserConfirmPassword(); String userConfirmPassword = userInfoResetRequest.getUserConfirmPassword();
@ -340,6 +283,7 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
} }
/** /**
* 小程序用户获取验证码(用于注册) * 小程序用户获取验证码(用于注册)
*/ */
@ -360,6 +304,173 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
} }
/**
* 校验用户手机号和验证码
*/
@Override
public void checkPhoneAndVerificationCode(String phoneNumber, String verificationCode, UserRoleEnum userRoleEnum) {
ThrowUtils.throwIf(RegexUtils.isPhoneInvalid(phoneNumber), ErrorCode.PARAMS_ERROR, "手机号格式无效");
if (userRoleEnum != null) {
LambdaQueryWrapper<UserInfo> phoneNumberLambdaQueryWrapper = new LambdaQueryWrapper<>();
phoneNumberLambdaQueryWrapper.eq(UserInfo::getPhoneNumber, phoneNumber);
phoneNumberLambdaQueryWrapper = getQueryWrapperByUserRole(userRoleEnum, phoneNumberLambdaQueryWrapper);
UserInfo userInfo = this.getOne(phoneNumberLambdaQueryWrapper);
ThrowUtils.throwIf(userInfo != null, ErrorCode.OPERATION_ERROR, "手机号已注册");
}
String code = redisTemplate.opsForValue().get(SystemConstant.VERIFICATION_CODE + ":" + verificationCode);
ThrowUtils.throwIf(code == null, ErrorCode.OPERATION_ERROR, "验证码已失效");
// // 移除验证码
// redisTemplate.delete(SystemConstant.VERIFICATION_CODE + ":" + verificationCode);
}
/**
* 根据用户权限来获取条件构造器
*/
@Override
public LambdaQueryWrapper<UserInfo> getQueryWrapperByUserRole(UserRoleEnum userRoleEnum, LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper) {
if (userRoleEnum.equals(UserRoleEnum.USER)) {
userInfoLambdaQueryWrapper.eq(UserInfo::getUserRole, userRoleEnum.getValue());
} else {
userInfoLambdaQueryWrapper.in(UserInfo::getUserRole, UserRoleEnum.MANAGER, UserRoleEnum.SUPERVISOR, UserRoleEnum.STAFF);
}
return userInfoLambdaQueryWrapper;
}
/**
* 小程序端员工信息注册
*/
@Override
public void staffUserInfoMiniRegister(AdvancementApplyApproveRequest advancementApplyApproveRequest) {
// 获取晋升申请记录信息
Long applyId = advancementApplyApproveRequest.getApplyId();
AdvancementApply advancementApply = advancementApplyService.getById(applyId);
String phoneNumber = advancementApply.getPhone();
ThrowUtils.throwIf(RegexUtils.isPhoneInvalid(phoneNumber), ErrorCode.PARAMS_ERROR, "手机号格式无效");
// 根据邀请码获得上级用户信息
String invitationCode = advancementApplyApproveRequest.getInvitationCode();
UserInfo parentUserInfo = getParentUserInfoByInvitationCode(invitationCode);
// 添加用户
UserInfo myUserInfo = UserInfo.builder()
.id(null)
.nickName(advancementApply.getName())
.phoneNumber(advancementApply.getPhone())
.userAvatar(UserConstant.USER_DEFAULT_AVATAR)
.userAccount(RandomUtil.randomNumbers(12))
.userPassword(RandomUtil.randomString(12))
.invitationCode(RandomUtil.randomNumbers(6))
.userRole(advancementApplyApproveRequest.getUserRole())
.parentUserId(parentUserInfo.getId())
.build();
this.save(myUserInfo);
// 批量更新父级用户团队人数
UserMainInfo userMainInfo = updateParentUserInfoTeamCount(myUserInfo.getId());
// 生成邀请二维码
generateInvitationQrcode(userMainInfo, myUserInfo.getInvitationCode());
// 批量保存当前用户的项目明细抽佣记录和下级用户项目明细抽佣记录
saveBatchProjectCommissionAndSubUserProjectCommission(myUserInfo.getId(), parentUserInfo.getId());
// 修改晋升申请记录的审核状态并绑定申请成功的用户id
LambdaUpdateWrapper<AdvancementApply> advancementApplyLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
advancementApplyLambdaUpdateWrapper.eq(AdvancementApply::getId, advancementApply.getId())
.set(AdvancementApply::getReviewStatus, ReviewStatusEnum.APPROVED.getValue())
.set(AdvancementApply::getUserId, myUserInfo.getId());
advancementApplyService.update(advancementApplyLambdaUpdateWrapper);
}
/**
* 根据邀请码获得上级用户信息
*/
private UserInfo getParentUserInfoByInvitationCode(String invitationCode) {
LambdaQueryWrapper<UserInfo> invitedLambdaQueryWrapper = new LambdaQueryWrapper<>();
invitedLambdaQueryWrapper.eq(UserInfo::getInvitationCode, invitationCode);
UserInfo parentUserInfo = this.getOne(invitedLambdaQueryWrapper);
ThrowUtils.throwIf(parentUserInfo == null, ErrorCode.OPERATION_ERROR, "邀请码错误");
return parentUserInfo;
}
/**
* 批量更新父级用户团队人数
*/
private UserMainInfo updateParentUserInfoTeamCount(Long userId) {
UserMainInfo userMainInfo = new UserMainInfo();
userMainInfo.setUserId(userId);
List<Long> pathToRoot = this.findPathToRoot(userId);
List<UserMainInfo> userMainInfoList = commonService.findByFieldInTargetField(pathToRoot, userMainInfoService, id -> id, UserMainInfo::getUserId);
for (UserMainInfo mainInfo : userMainInfoList) {
mainInfo.setTeamSize(mainInfo.getTeamSize() + 1);
}
userMainInfoService.updateBatchById(userMainInfoList);
return userMainInfo;
}
/**
* 生成邀请二维码
*/
private void generateInvitationQrcode(UserMainInfo userMainInfo, String invitationCode) {
try {
String view = wechatGetQrcodeService.getWxQrCode(invitationCode);
userMainInfo.setInviteQrCode(view);
} catch (IOException e) {
e.printStackTrace();
}
userMainInfoService.save(userMainInfo);
}
/**
* 批量保存当前用户的项目明细抽佣记录和下级用户项目明细抽佣记录
*/
private void saveBatchProjectCommissionAndSubUserProjectCommission(Long userId, Long parentUserId) {
// 查询上级用户的项目抽佣记录
List<ProjectCommission> projectCommissionList = commonService.findByFieldEqTargetField(ProjectCommission::getUserId, parentUserId, projectCommissionService);
// 封装Map集合项目明细id, 值:项目最小价格)
Map<Long, BigDecimal> projectDetailMinPriceMap = new HashMap<>();
List<ProjectDetail> projectDetailList = commonService.findByFieldInTargetField(projectCommissionList, projectDetailService, ProjectCommission::getProjectDetailId, ProjectDetail::getId);
for (ProjectDetail projectDetail : projectDetailList) {
projectDetailMinPriceMap.put(projectDetail.getId(), projectDetail.getProjectMinSettlementPrice());
}
// 插入当前用户的项目抽佣记录
List<ProjectCommission> projectCommissions = new ArrayList<>();
for (ProjectCommission projectCommission : projectCommissionList) {
ProjectCommissionAddRequest projectCommissionAddRequest = commonService.copyProperties(projectCommission, ProjectCommissionAddRequest.class);
ProjectCommission proCommission = commonService.copyProperties(projectCommissionAddRequest, ProjectCommission.class);
// 获取当前项目明细的最小结算价格
BigDecimal projectMinSettlementPrice = projectDetailMinPriceMap.get(projectCommission.getProjectDetailId());
BigDecimal currentSettlementPrice = projectCommission.getMyUnitPrice().multiply(BigDecimal.ONE.subtract(projectCommission.getCurrentCommissionRate().divide(BigDecimal.valueOf(100))));
// 比较当前结算价格和项目明细最小结算价格,取出最大值
proCommission.setMyUnitPrice(projectMinSettlementPrice.max(currentSettlementPrice));
proCommission.setCurrentCommissionRate(BigDecimal.ZERO);
proCommission.setUserId(userId);
projectCommissions.add(proCommission);
}
projectCommissionService.saveBatch(projectCommissions);
// 插入下级用户的项目明细抽佣记录
List<SubUserProjectCommission> subUserProjectCommissionList = new ArrayList<>();
for (ProjectCommission projectCommission : projectCommissionList) {
ProjectCommissionAddRequest projectCommissionAddRequest = commonService.copyProperties(projectCommission, ProjectCommissionAddRequest.class);
SubUserProjectCommission subUserProjectCommission = commonService.copyProperties(projectCommissionAddRequest, SubUserProjectCommission.class);
subUserProjectCommission.setSubUserId(userId);
subUserProjectCommissionList.add(subUserProjectCommission);
}
subUserProjectCommissionService.saveBatch(subUserProjectCommissionList);
}
} }

View File

@ -256,14 +256,6 @@ public class WechatGetQrcodeServiceImpl implements WechatGetQrcodeService {
String courseUrl = SystemConstant.FILE_COMMON_PREFIX + course.getImage(); String courseUrl = SystemConstant.FILE_COMMON_PREFIX + course.getImage();
BufferedImage courseImage = ImageIO.read(new URL(courseUrl)); BufferedImage courseImage = ImageIO.read(new URL(courseUrl));
// Graphics2D graphics = courseImage.createGraphics();
// graphics.setColor(Color.decode("#323232"));
// graphics.setFont(new Font("阿里巴巴普惠体", Font.PLAIN, 60));
// graphics.drawString("测试", 0, 80);
// graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
// graphics.drawString("测试", 0, 160);
// graphics.dispose();
// 将二维码数据转换为 BufferedImage // 将二维码数据转换为 BufferedImage
BufferedImage qrImage = ImageIO.read(new ByteArrayInputStream(responseBytes)); BufferedImage qrImage = ImageIO.read(new ByteArrayInputStream(responseBytes));

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.greenorange.promotion.mapper.AdvancementApplyMapper">
<resultMap id="BaseResultMap" type="com.greenorange.promotion.model.entity.AdvancementApply">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="phone" column="phone" jdbcType="VARCHAR"/>
<result property="resume" column="resume" jdbcType="VARCHAR"/>
<result property="reviewStatus" column="reviewStatus" jdbcType="OTHER"/>
<result property="isDelete" column="isDelete" jdbcType="TINYINT"/>
<result property="createTime" column="createTime" jdbcType="TIMESTAMP"/>
<result property="updateTime" column="updateTime" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,name,phone,
resume,reviewStatus,isDelete,
createTime,updateTime
</sql>
</mapper>