邀请码申请与审核

This commit is contained in:
wanggeng 2024-08-12 10:55:30 +08:00
parent 7ddab1ae68
commit 69cf630a57
17 changed files with 1391 additions and 5 deletions

View File

@ -1,4 +1,4 @@
# 邀请码
# 邀请码(未上线)
说明
@ -6,4 +6,9 @@
2. 邀请码的获取有两种方式:
1. 由管理员直接生成
2. 自己发起申请,管理员审核通过后生成
3. 生成邀请码时,必须设置金额和邀请码返利比例
3. 生成邀请码时,必须设置金额和邀请码返利比例
变更的表
sys_user_expand
sys_user_ic_apply

View File

@ -0,0 +1,72 @@
package cn.com.tenlion.operator.controller.api.user.ic.apply;
import cn.com.tenlion.operator.enums.ApplyStatusEnum;
import cn.com.tenlion.operator.pojo.dtos.user.ic.apply.UserIcApplyDTO;
import cn.com.tenlion.operator.pojo.vos.user.ic.apply.UserIcApplyReviewVO;
import cn.com.tenlion.operator.service.user.ic.apply.UserIcApplyService;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* ClassName: UserIcApplyController
* Description: 用户邀请码申请
* Author: wanggeng
* Date: 2024/8/8 上午11:59
* Version: 1.0
*/
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/user/ic/apply")
public class UserIcApplyController extends DefaultBaseController {
@Autowired
private UserIcApplyService userIcApplyService;
@PutMapping("review/{userIcApplyId}")
public synchronized SuccessResult review(@PathVariable("userIcApplyId") String userIcApplyId,
@RequestBody UserIcApplyReviewVO userIcApplyReview) {
if (ApplyStatusEnum.PENDING.equals(userIcApplyReview.getApplyStatus())) {
throw new ParamsException("状态不能是等待");
}
if (ApplyStatusEnum.REJECTED.equals(userIcApplyReview.getApplyStatus())) {
if (StringUtils.isBlank(userIcApplyReview.getApplyNotes())) {
throw new ParamsException("原因不能为空");
}
}
if (ApplyStatusEnum.APPROVED.equals(userIcApplyReview.getApplyStatus())) {
if (userIcApplyReview.getPriceAll() < 0) {
throw new ParamsException("全托价格不能小于0");
}
if (userIcApplyReview.getPriceMaterial() < 0) {
throw new ParamsException("写材料价格不能小于0");
}
if (StringUtils.isBlank(userIcApplyReview.getIc())) {
throw new ParamsException("邀请码不能为空");
}
if (userIcApplyReview.getIcRebateRatio() <= 0) {
throw new ParamsException("邀请码返利比率不能小于0");
}
}
userIcApplyService.updateReview(userIcApplyId, userIcApplyReview);
return new SuccessResult();
}
@GetMapping("get/{userIcApplyId}")
public UserIcApplyDTO get(@PathVariable("userIcApplyId") String userIcApplyId) {
return userIcApplyService.get(userIcApplyId);
}
@GetMapping("listpage")
public SuccessResultList<List<UserIcApplyDTO>> listpage(ListPage page) {
page.setParams(requestParams());
return userIcApplyService.listpage(page);
}
}

View File

@ -0,0 +1,43 @@
package cn.com.tenlion.operator.controller.resource.user.ic.apply;
import cn.com.tenlion.operator.pojo.dtos.user.ic.apply.UserIcApplyDTO;
import cn.com.tenlion.operator.service.user.ic.apply.UserIcApplyService;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.pojo.result.SuccessResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* ClassName: UserIcApplyResourceController
* Description:
* Author: wanggeng
* Date: 2024/8/8 下午12:01
* Version: 1.0
*/
@RestController
@RequestMapping(ISystemConstant.RESOURCE_PREFIX + "/user/ic/apply")
public class UserIcApplyResourceController {
@Autowired
private UserIcApplyService userIcApplyService;
@PostMapping("apply")
public synchronized SuccessResult apply(@RequestBody JSONObject body) {
if (StringUtils.isBlank(body.getString("applier"))) {
throw new ParamsException("申请人不能为空");
}
userIcApplyService.save(body.getString("applier"));
return new SuccessResult();
}
@GetMapping("get/{userId}")
public UserIcApplyDTO getByUserId(@PathVariable("userId") String userId) {
return userIcApplyService.getByUserId(userId);
}
}

View File

@ -0,0 +1,32 @@
package cn.com.tenlion.operator.controller.route.user.ic.apply;
import ink.wgink.interfaces.consts.ISystemConstant;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* ClassName: UserIcRouteController
* Description:
* Author: wanggeng
* Date: 2024/8/8 下午6:04
* Version: 1.0
*/
@Controller
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/user/ic/apply")
public class UserIcApplyRouteController {
@GetMapping("list")
public ModelAndView list() {
ModelAndView modelAndView = new ModelAndView("user/ic/apply/list");
return modelAndView;
}
@GetMapping("review")
public ModelAndView review() {
ModelAndView modelAndView = new ModelAndView("user/ic/apply/review");
return modelAndView;
}
}

View File

@ -21,6 +21,8 @@ public interface IUserExpandDao {
void update(Map<String, Object> params);
void updateIc(Map<String, Object> params);
void updateRelationIc(Map<String, Object> params);
void updateRelationRebateRatio(Map<String, Object> params);
@ -33,4 +35,5 @@ public interface IUserExpandDao {
List<String> listUserIdByRelationUserId(String userId);
}

View File

@ -0,0 +1,33 @@
package cn.com.tenlion.operator.dao.user.ic.apply;
import cn.com.tenlion.operator.pojo.dtos.user.ic.apply.UserIcApplyDTO;
import cn.com.tenlion.operator.pojo.pos.user.ic.apply.UserIcApplyPO;
import java.util.List;
import java.util.Map;
/**
* @ClassName: IUserIcApplyDao
* @Description:
* @Author: wanggeng
* @Date: 2024/8/8 上午11:50
* @Version: 1.0
*/
public interface IUserIcApplyDao {
void save(Map<String, Object> params);
void updateApplyStatus(Map<String, Object> params);
UserIcApplyPO getPO(Map<String, Object> params);
UserIcApplyPO getLatestPOByCreator(String creator);
UserIcApplyDTO get(Map<String, Object> params);
List<UserIcApplyPO> listPO(Map<String, Object> params);
List<UserIcApplyDTO> list(Map<String, Object> params);
}

View File

@ -0,0 +1,26 @@
package cn.com.tenlion.operator.enums;
/**
* ClassName: ApplyStatusEnum
* Description:
* Author: wanggeng
* Date: 2024/8/8 上午11:55
* Version: 1.0
*/
public enum ApplyStatusEnum {
PENDING("等待中"),
APPROVED("已通过"),
REJECTED("已拒绝");
private final String text;
ApplyStatusEnum(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

View File

@ -0,0 +1,153 @@
package cn.com.tenlion.operator.pojo.dtos.user.ic.apply;
import cn.com.tenlion.operator.enums.ApplyStatusEnum;
import cn.com.tenlion.operator.pojo.dtos.user.info.UserInfoDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* ClassName: UserIcApplyDTO
* Description:
* Author: wanggeng
* Date: 2024/8/8 下午2:30
* Version: 1.0
*/
@ApiModel
public class UserIcApplyDTO {
@ApiModelProperty(name = "userIcApplyId", value = "主键")
private String userIcApplyId;
@ApiModelProperty(name = "applyStatus", value = "申请状态")
private ApplyStatusEnum applyStatus;
@ApiModelProperty(name = "applyNotes", value = "申请备注")
private String applyNotes;
@ApiModelProperty(name = "reviewer", value = "审核人")
private String reviewer;
@ApiModelProperty(name = "gmtReview", value = "审核时间")
private String gmtReview;
@ApiModelProperty(name = "gmtCreate", value = "申请时间")
private String gmtCreate;
@ApiModelProperty(name = "creator", value = "申请人")
private String creator;
@ApiModelProperty(name = "userUsername", value = "用户名")
private String userUsername;
@ApiModelProperty(name = "userName", value = "昵称")
private String userName;
private UserInfoDTO userInfo;
private Long priceAll;
private Long priceMaterial;
private String ic;
private Integer icRebateRatio;
public String getUserIcApplyId() {
return userIcApplyId == null ? "" : userIcApplyId.trim();
}
public void setUserIcApplyId(String userIcApplyId) {
this.userIcApplyId = userIcApplyId;
}
public ApplyStatusEnum getApplyStatus() {
return applyStatus;
}
public void setApplyStatus(ApplyStatusEnum applyStatus) {
this.applyStatus = applyStatus;
}
public String getApplyNotes() {
return applyNotes == null ? "" : applyNotes.trim();
}
public void setApplyNotes(String applyNotes) {
this.applyNotes = applyNotes;
}
public String getReviewer() {
return reviewer == null ? "" : reviewer.trim();
}
public void setReviewer(String reviewer) {
this.reviewer = reviewer;
}
public String getGmtReview() {
return gmtReview == null ? "" : gmtReview.trim();
}
public void setGmtReview(String gmtReview) {
this.gmtReview = gmtReview;
}
public String getGmtCreate() {
return gmtCreate == null ? "" : gmtCreate.trim();
}
public void setGmtCreate(String gmtCreate) {
this.gmtCreate = gmtCreate;
}
public String getCreator() {
return creator == null ? "" : creator.trim();
}
public void setCreator(String creator) {
this.creator = creator;
}
public String getUserUsername() {
return userUsername == null ? "" : userUsername.trim();
}
public void setUserUsername(String userUsername) {
this.userUsername = userUsername;
}
public String getUserName() {
return userName == null ? "" : userName.trim();
}
public void setUserName(String userName) {
this.userName = userName;
}
public UserInfoDTO getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfoDTO userInfo) {
this.userInfo = userInfo;
}
public Long getPriceAll() {
return priceAll == null ? 0 : priceAll;
}
public void setPriceAll(Long priceAll) {
this.priceAll = priceAll;
}
public Long getPriceMaterial() {
return priceMaterial == null ? 0 : priceMaterial;
}
public void setPriceMaterial(Long priceMaterial) {
this.priceMaterial = priceMaterial;
}
public String getIc() {
return ic == null ? "" : ic.trim();
}
public void setIc(String ic) {
this.ic = ic;
}
public Integer getIcRebateRatio() {
return icRebateRatio == null ? 0 : icRebateRatio;
}
public void setIcRebateRatio(Integer icRebateRatio) {
this.icRebateRatio = icRebateRatio;
}
}

View File

@ -0,0 +1,86 @@
package cn.com.tenlion.operator.pojo.pos.user.ic.apply;
import cn.com.tenlion.operator.enums.ApplyStatusEnum;
/**
* ClassName: UserIcApplyPO
* Description:
* Author: wanggeng
* Date: 2024/8/8 上午11:42
* Version: 1.0
*/
public class UserIcApplyPO {
private String userIcApplyId;
private ApplyStatusEnum applyStatus;
private String applyNotes;
private String reviewer;
private String gmtReview;
private String gmtCreate;
private String creator;
private Integer isDelete;
public String getUserIcApplyId() {
return userIcApplyId == null ? "" : userIcApplyId.trim();
}
public void setUserIcApplyId(String userIcApplyId) {
this.userIcApplyId = userIcApplyId;
}
public ApplyStatusEnum getApplyStatus() {
return applyStatus;
}
public void setApplyStatus(ApplyStatusEnum applyStatus) {
this.applyStatus = applyStatus;
}
public String getApplyNotes() {
return applyNotes == null ? "" : applyNotes.trim();
}
public void setApplyNotes(String applyNotes) {
this.applyNotes = applyNotes;
}
public String getReviewer() {
return reviewer == null ? "" : reviewer.trim();
}
public void setReviewer(String reviewer) {
this.reviewer = reviewer;
}
public String getGmtReview() {
return gmtReview == null ? "" : gmtReview.trim();
}
public void setGmtReview(String gmtReview) {
this.gmtReview = gmtReview;
}
public String getGmtCreate() {
return gmtCreate == null ? "" : gmtCreate.trim();
}
public void setGmtCreate(String gmtCreate) {
this.gmtCreate = gmtCreate;
}
public String getCreator() {
return creator == null ? "" : creator.trim();
}
public void setCreator(String creator) {
this.creator = creator;
}
public Integer getIsDelete() {
return isDelete == null ? 0 : isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
}

View File

@ -0,0 +1,73 @@
package cn.com.tenlion.operator.pojo.vos.user.ic.apply;
import cn.com.tenlion.operator.enums.ApplyStatusEnum;
import cn.com.tenlion.operator.pojo.vos.user.expand.UserExpandVO;
import ink.wgink.annotation.CheckEmptyAnnotation;
import ink.wgink.annotation.CheckNullAnnotation;
import ink.wgink.annotation.CheckNumberAnnotation;
/**
* ClassName: UserIcApplyVO
* Description:
* Author: wanggeng
* Date: 2024/8/8 下午3:53
* Version: 1.0
*/
public class UserIcApplyReviewVO {
@CheckNullAnnotation(name = "申请状态")
private ApplyStatusEnum applyStatus;
private String applyNotes;
private Double priceAll;
private Double priceMaterial;
private String ic;
private Integer icRebateRatio;
public ApplyStatusEnum getApplyStatus() {
return applyStatus;
}
public void setApplyStatus(ApplyStatusEnum applyStatus) {
this.applyStatus = applyStatus;
}
public String getApplyNotes() {
return applyNotes == null ? "" : applyNotes.trim();
}
public void setApplyNotes(String applyNotes) {
this.applyNotes = applyNotes;
}
public Double getPriceAll() {
return priceAll == null ? 0 : priceAll;
}
public void setPriceAll(Double priceAll) {
this.priceAll = priceAll;
}
public Double getPriceMaterial() {
return priceMaterial == null ? 0 : priceMaterial;
}
public void setPriceMaterial(Double priceMaterial) {
this.priceMaterial = priceMaterial;
}
public String getIc() {
return ic == null ? "" : ic.trim();
}
public void setIc(String ic) {
this.ic = ic;
}
public Integer getIcRebateRatio() {
return icRebateRatio == null ? 0 : icRebateRatio;
}
public void setIcRebateRatio(Integer icRebateRatio) {
this.icRebateRatio = icRebateRatio;
}
}

View File

@ -44,8 +44,6 @@ public class UserCustomService extends DefaultBaseService {
private IRoleUserService roleUserService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private SystemApiPathProperties systemApiPathProperties;
public SuccessResultList<List<UserCustomDTO>> listpage(ListPage page) {
SuccessResultList<List<UserDTO>> successResultList = userService.listPage(page);

View File

@ -151,13 +151,15 @@ public class UserExpandServiceImpl extends DefaultBaseService implements IUserEx
Map<String, Object> params = getHashMap(2);
params.put("userId", userId);
UserExpandDTO userExpandDTO = userExpandDao.get(params);
params = HashMapUtil.beanToMap(userExpandVO);
params.put("userId", userId);
if (StringUtils.isNotBlank(userExpandVO.getIc())) {
params.put("icAssignUserId", securityComponent.getCurrentUser().getUserId());
params.put("icWayToGet", IcWayToGetEnum.ASSIGN);
params.put("icGetTime", DateUtil.getTime());
}
UserExpandDTO userExpandDTO = userExpandDao.get(params);
if (userExpandDTO == null) {
if (StringUtils.isNotBlank(userExpandVO.getIc()) && countIc(userExpandVO.getIc()) > 0) {
throw new SearchException("邀请码已存在,请重新生成");
@ -183,6 +185,37 @@ public class UserExpandServiceImpl extends DefaultBaseService implements IUserEx
updateBatchRelationRebateRatio(userId, userExpandDTO == null ? 0 : userExpandDTO.getIcRebateRatio(), userExpandVO.getIcRebateRatio());
}
public void saveOrUpdateWithIc(String userId, UserExpandVO userExpandVO) {
userExpandVO.setPriceAll(userExpandVO.getPriceAll() * 100);
userExpandVO.setPriceMaterial(userExpandVO.getPriceMaterial() * 100);
userExpandVO.setAvailableProjType("PRICE_ALL,PRICE_MATERIAL,PRICE_FREE");
Map<String, Object> params = getHashMap(2);
params.put("userId", userId);
UserExpandDTO userExpandDTO = userExpandDao.get(params);
params = HashMapUtil.beanToMap(userExpandVO);
params.put("userId", userId);
params.put("icAssignUserId", securityComponent.getCurrentUser().getUserId());
params.put("icWayToGet", IcWayToGetEnum.APPLY);
params.put("icGetTime", DateUtil.getTime());
if (StringUtils.isNotBlank(userExpandVO.getIc()) && countIc(userExpandVO.getIc()) > 0) {
throw new SearchException("邀请码已存在,请重新生成");
}
if (userExpandDTO == null) {
userExpandDao.save(params);
} else {
if (StringUtils.isNotBlank(userExpandDTO.getRelationIc()) &&
StringUtils.equals("ACTIVE", userExpandVO.getPostpaid())) {
throw new SearchException("已经绑定邀请码的用户不能设置为后付费用户");
}
userExpandDao.updateIc(params);
}
updateRedis(userId);
updateBatchRelationRebateRatio(userId, userExpandDTO == null ? 0 : userExpandDTO.getIcRebateRatio(), userExpandVO.getIcRebateRatio());
}
/**
* 批量更新返利比率
*

View File

@ -0,0 +1,145 @@
package cn.com.tenlion.operator.service.user.ic.apply;
import cn.com.tenlion.operator.dao.user.ic.apply.IUserIcApplyDao;
import cn.com.tenlion.operator.enums.ApplyStatusEnum;
import cn.com.tenlion.operator.pojo.dtos.user.ic.apply.UserIcApplyDTO;
import cn.com.tenlion.operator.pojo.dtos.user.info.UserInfoDTO;
import cn.com.tenlion.operator.pojo.pos.user.expand.UserExpandPO;
import cn.com.tenlion.operator.pojo.pos.user.ic.apply.UserIcApplyPO;
import cn.com.tenlion.operator.pojo.vos.user.expand.UserExpandVO;
import cn.com.tenlion.operator.pojo.vos.user.ic.apply.UserIcApplyReviewVO;
import cn.com.tenlion.operator.service.user.expand.UserExpandServiceImpl;
import cn.com.tenlion.operator.service.user.info.UserInfoService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SearchException;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* ClassName: UserIcApplyService
* Description:
* Author: wanggeng
* Date: 2024/8/8 上午11:58
* Version: 1.0
*/
@Service
public class UserIcApplyService extends DefaultBaseService {
@Autowired
private IUserIcApplyDao userIcApplyDao;
@Autowired
private UserExpandServiceImpl userExpandService;
@Autowired
private UserInfoService userInfoService;
public void save(String applier) {
UserIcApplyPO latestPO = userIcApplyDao.getLatestPOByCreator(applier);
if (latestPO != null) {
if (ApplyStatusEnum.PENDING.equals(latestPO.getApplyStatus())) {
throw new SearchException("正在审核");
}
if (ApplyStatusEnum.APPROVED.equals(latestPO.getApplyStatus())) {
throw new SearchException("申请已通过,不能重复申请");
}
}
String uuid = UUIDUtil.getUUID();
Map<String, Object> params = new HashMap<>();
params.put("userIcApplyId", uuid);
params.put("applyStatus", ApplyStatusEnum.PENDING);
params.put("creator", applier);
params.put("gmtCreate", DateUtil.getTime());
params.put("isDelete", 0);
userIcApplyDao.save(params);
}
public void updateReview(String userIcApplyId, UserIcApplyReviewVO userIcApplyReview) {
UserIcApplyPO po = getPO(userIcApplyId);
if (po == null) {
throw new SearchException("申请不存在");
}
if(!ApplyStatusEnum.PENDING.equals(po.getApplyStatus())) {
throw new SearchException("不能重复审核");
}
Map<String, Object> params = getHashMap(6);
params.put("receiver", securityComponent.getCurrentUser().getUserId());
params.put("applyStatus", userIcApplyReview.getApplyStatus());
params.put("applyNotes", userIcApplyReview.getApplyNotes());
params.put("reviewer", securityComponent.getCurrentUser().getUserId());
params.put("gmtReview", DateUtil.getTime());
params.put("userIcApplyId", userIcApplyId);
userIcApplyDao.updateApplyStatus(params);
if (ApplyStatusEnum.APPROVED.equals(userIcApplyReview.getApplyStatus())) {
UserExpandVO userExpandVO = new UserExpandVO();
BeanUtils.copyProperties(userIcApplyReview, userExpandVO);
userExpandService.saveOrUpdateWithIc(po.getCreator(), userExpandVO);
}
}
public UserIcApplyPO getPO(String userIcApplyId) {
Map<String, Object> params = getHashMap(2);
params.put("userIcApplyId", userIcApplyId);
return userIcApplyDao.getPO(params);
}
public UserIcApplyDTO get(String userIcApplyId) {
Map<String, Object> params = getHashMap(2);
params.put("userIcApplyId", userIcApplyId);
UserIcApplyDTO userIcApplyDTO = userIcApplyDao.get(params);
if (userIcApplyDTO == null) {
throw new SearchException("申请不存在");
}
UserExpandPO po = userExpandService.getPO(userIcApplyDTO.getCreator());
if (po != null) {
userIcApplyDTO.setPriceAll(po.getPriceAll());
userIcApplyDTO.setPriceMaterial(po.getPriceMaterial());
userIcApplyDTO.setIc(po.getIc());
userIcApplyDTO.setIcRebateRatio(po.getIcRebateRatio());
}
return userIcApplyDTO;
}
public UserIcApplyDTO getByUserId(String userId) {
Map<String, Object> params = getHashMap(2);
params.put("creator", userId);
return userIcApplyDao.get(params);
}
public UserIcApplyDTO getSelf() {
return getByUserId(securityComponent.getCurrentUser().getUserId());
}
public SuccessResultList<List<UserIcApplyDTO>> listpage(ListPage page) {
PageHelper.startPage(page.getPage(), page.getRows());
List<UserIcApplyDTO> userIcApplyDTOS = userIcApplyDao.list(page.getParams());
PageInfo<UserIcApplyDTO> pageInfo = new PageInfo<>(userIcApplyDTOS);
setUserInfo(userIcApplyDTOS);
return new SuccessResultList<>(userIcApplyDTOS, pageInfo.getPageNum(), pageInfo.getTotal());
}
private void setUserInfo(List<UserIcApplyDTO> userIcApplyDTOS) {
if (userIcApplyDTOS.isEmpty()) {
return;
}
List<String> userIds = userIcApplyDTOS.stream().map(UserIcApplyDTO::getCreator).collect(Collectors.toList());
List<UserInfoDTO> userInfoDTOS = userInfoService.listByUserIds(userIds);
userIcApplyDTOS.forEach(userIcApplyDTO -> {
userInfoDTOS.stream().filter(userInfoDTO -> StringUtils.equals(userIcApplyDTO.getCreator(), userInfoDTO.getUserId())).findFirst().ifPresent(userIcApplyDTO::setUserInfo);
});
}
}

View File

@ -69,6 +69,7 @@
correction_count,
ic,
ic_rebate_ratio,
ic_way_to_get,
ic_get_time,
ic_assign_user_id
) VALUES (
@ -87,6 +88,7 @@
#{correctionCount},
#{ic},
#{icRebateRatio},
#{icWayToGet},
#{icGetTime},
#{icAssignUserId}
)
@ -124,6 +126,22 @@
user_id = #{userId}
</update>
<update id="updateIc" parameterType="map">
UPDATE
sys_user_expand
SET
ic = #{ic},
ic_rebate_ratio = #{icRebateRatio},
ic_assign_user_id = #{icAssignUserId},
ic_way_to_get = #{icWayToGet},
ic_get_time = #{icGetTime},
price_all = #{priceAll},
price_material = #{priceMaterial},
available_proj_type = #{availableProjType}
WHERE
user_id = #{userId}
</update>
<update id="updateRelationIc" parameterType="map">
UPDATE
sys_user_expand

View File

@ -0,0 +1,219 @@
<?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="cn.com.tenlion.operator.dao.user.ic.apply.IUserIcApplyDao">
<resultMap id="userIcApplyPO" type="cn.com.tenlion.operator.pojo.pos.user.ic.apply.UserIcApplyPO">
<result column="user_ic_apply_id" property="userIcApplyId"/>
<result column="apply_status" property="applyStatus"/>
<result column="apply_notes" property="applyNotes"/>
<result column="reviewer" property="reviewer"/>
<result column="gmt_review" property="gmtReview"/>
<result column="gmt_create" property="gmtCreate"/>
<result column="creator" property="creator"/>
<result column="is_delete" property="isDelete"/>
</resultMap>
<resultMap id="userIcApplyDTO" type="cn.com.tenlion.operator.pojo.dtos.user.ic.apply.UserIcApplyDTO">
<result column="user_ic_apply_id" property="userIcApplyId"/>
<result column="apply_status" property="applyStatus"/>
<result column="apply_notes" property="applyNotes"/>
<result column="reviewer" property="reviewer"/>
<result column="gmt_review" property="gmtReview"/>
<result column="gmt_create" property="gmtCreate"/>
<result column="creator" property="creator"/>
<result column="user_username" property="userUsername"/>
<result column="user_name" property="userName"/>
</resultMap>
<insert id="save" parameterType="map">
INSERT INTO sys_user_ic_apply (
user_ic_apply_id,
apply_status,
apply_notes,
reviewer,
gmt_review,
gmt_create,
creator,
is_delete
) VALUES (
#{userIcApplyId},
#{applyStatus},
#{applyNotes},
#{reviewer},
#{gmtReview},
#{gmtCreate},
#{creator},
#{isDelete}
)
</insert>
<update id="updateApplyStatus" parameterType="map">
UPDATE
sys_user_ic_apply
SET
apply_status = #{applyStatus},
apply_notes = #{applyNotes},
reviewer = #{reviewer},
gmt_review = #{gmtReview}
WHERE
user_ic_apply_id = #{userIcApplyId}
</update>
<select id="getPO" parameterType="map" resultMap="userIcApplyPO">
SELECT
user_ic_apply_id,
apply_status,
apply_notes,
reviewer,
gmt_review,
gmt_create,
creator,
is_delete
FROM
sys_user_ic_apply
WHERE
is_delete = 0
<if test="userIcApplyId != null and userIcApplyId != ''">
AND
user_ic_apply_id = #{userIcApplyId}
</if>
<if test="applyStatus != null and applyStatus != ''">
AND
apply_status = #{applyStatus}
</if>
<if test="creator != null and creator != ''">
AND
creator = #{creator}
</if>
</select>
<select id="getLatestPOByCreator" parameterType="java.lang.String" resultMap="userIcApplyPO">
SELECT
user_ic_apply_id,
apply_status,
apply_notes,
reviewer,
gmt_review,
gmt_create,
creator,
is_delete
FROM
sys_user_ic_apply
WHERE
is_delete = 0
AND
creator = #{_parameter}
ORDER BY
id DESC
LIMIT 1
</select>
<select id="get" parameterType="map" resultMap="userIcApplyDTO">
SELECT
user_ic_apply_id,
apply_status,
apply_notes,
reviewer,
gmt_review,
gmt_create,
creator,
is_delete
FROM
sys_user_ic_apply
WHERE
is_delete = 0
<if test="userIcApplyId != null and userIcApplyId != ''">
AND
user_ic_apply_id = #{userIcApplyId}
</if>
<if test="applyStatus != null and applyStatus != ''">
AND
apply_status = #{applyStatus}
</if>
<if test="creator != null and creator != ''">
AND
creator = #{creator}
</if>
</select>
<select id="listPO" parameterType="map" resultMap="userIcApplyPO">
SELECT
user_ic_apply_id,
apply_status,
apply_notes,
reviewer,
gmt_review,
gmt_create,
creator,
is_delete
FROM
sys_user_ic_apply
WHERE
is_delete = 0
<if test="userIcApplyIds != null and userIcApplyIds.size > 0">
AND
user_ic_apply_id IN
<foreach collection="userIcApplyIds" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="applyStatus != null and applyStatus != ''">
AND
apply_status = #{applyStatus}
</if>
<if test="creator != null and creator != ''">
AND
creator = #{creator}
</if>
</select>
<select id="list" parameterType="map" resultMap="userIcApplyDTO">
SELECT
suia.user_ic_apply_id,
suia.apply_status,
suia.apply_notes,
suia.reviewer,
suia.gmt_review,
suia.gmt_create,
suia.creator,
su.user_username,
su.user_name
FROM
sys_user_ic_apply suia
INNER JOIN
sys_user su
ON
suia.creator = su.user_id
AND
su.is_delete = 0
WHERE
suia.is_delete = 0
<if test="userIcApplyIds != null and userIcApplyIds.size > 0">
AND
suia.user_ic_apply_id IN
<foreach collection="userIcApplyIds" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="applyStatus != null and applyStatus != ''">
AND
suia.apply_status = #{applyStatus}
</if>
<if test="creator != null and creator != ''">
AND
suia.creator = #{creator}
</if>
<if test="startTime != null and startTime != ''">
AND
LEFT(suia.gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
</if>
<if test="endTime != null and endTime != ''">
AND
LEFT(suia.gmt_create, 10) <![CDATA[ <= ]]> #{endTime}
</if>
ORDER BY
suia.gmt_create DESC
</select>
</mapper>

View File

@ -0,0 +1,202 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'}">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<style>
.id-card .img {width: 26px;height: 26px;cursor:pointer;}
.search-item .layui-form-select .layui-input {width: 150px;}
</style>
</head>
<body>
<div class="layui-fluid layui-anim layui-anim-fadein">
<div class="layui-row">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body">
<div class="test-table-reload-btn" style="margin-bottom: 10px;">
<div class="layui-inline">
<input type="text" id="keywords" class="layui-input search-item" placeholder="输入名称或姓名">
</div>
<button type="button" id="search" class="layui-btn layui-btn-sm">
<i class="fa fa-lg fa-search"></i> 搜索
</button>
</div>
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
</div>
</div>
</div>
</div>
</div>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
<script th:inline="javascript">
layui.config({
base: 'assets/layuiadmin/'
}).extend({
index: 'lib/index'
}).use(['index', 'table', 'laydate', 'common' , 'form'], function() {
var $ = layui.$;
var $win = $(window);
var table = layui.table;
var admin = layui.admin;
var laydate = layui.laydate;
var common = layui.common;
var form = layui.form;
var resizeTimeout = null;
var tableUrl = 'api/user/ic/apply/listpage';
// 初始化表格
function initTable() {
table.render({
elem: '#dataTable',
id: 'dataTable',
url: tableUrl,
width: admin.screen() > 1 ? '100%' : '',
height: $win.height() - 90,
limit: 20,
limits: [20, 40, 60, 80, 100, 200],
toolbar: false,
defaultToolbar: [],
request: {
pageName: 'page',
limitName: 'rows'
},
cols: [
[
{field:'rowNum', width:80, title: '序号', fixed: 'left', align:'center', templet: '<span>{{d.LAY_NUM}}</span>'},
{field: 'userUsername', width: 140, title: '用户名', align:'center',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
return rowData;
}
},
{field: 'userInfoName', width: 140, title: '用户信息名称', align:'center',
templet: function(row) {
var rowData = row.userInfo.userInfoName;
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
return rowData;
}
},
{field: 'applyStatus', width: 140, title: '申请状态', align:'center',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
if(rowData === 'PENDING') {
return '待审核';
}
if(rowData === 'APPROVED') {
return '已同意';
}
if(rowData === 'REJECTED') {
return '已拒绝';
}
return '错误';
}
},
{field: 'applyNotes', width: 180, title: '备注', align:'center',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
return rowData;
}
},
{field: 'gmtCreate', width: 180, title: '申请时间', align:'center',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
return rowData;
}
},
{field: 'operate', width: 80, title: '操作', align:'center', fixed: 'right',
templet: function(row) {
return `<button type="button" class="layui-btn layui-btn-xs" lay-event="reviewEvent">审核</button>`;
}
},
]
],
page: true,
parseData: function(data) {
return {
'code': 0,
'msg': '',
'count': data.total,
'data': data.rows
};
}
});
}
// 重载表格
function reloadTable(currentPage) {
table.reload('dataTable', {
where: {
keywords: $('#keywords').val(),
userInfoType: $("#userInfoType").val()
},
page: {
curr: currentPage
},
});
}
// 初始化日期
function initDate() {
// 日期选择
laydate.render({
elem: '#startTime',
format: 'yyyy-MM-dd'
});
laydate.render({
elem: '#endTime',
format: 'yyyy-MM-dd'
});
}
initTable();
initDate();
// 事件 - 页面变化
$win.on('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
reloadTable();
}, 500);
});
// 事件 - 搜索
$(document).on('click', '#search', function() {
reloadTable(1);
});
table.on('tool(dataTable)', function(obj) {
var event = obj.event;
var data = obj.data;
if(event === 'reviewEvent') {
top.dialog.open({
title: '审核',
url: top.restAjax.path('route/user/ic/apply/review?userIcApplyId={userIcApplyId}', [data.userIcApplyId]),
width: '800px',
height: '420px',
onClose: function() {
reloadTable();
}
})
}
})
});
</script>
</body>
</html>

View File

@ -0,0 +1,245 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'}">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<style>
.layui-form-item {margin-bottom: 0;}
.layui-form-label-new {width: 180px !important;}
.layui-input-block-new {margin-left: 180px !important;}
.layui-input-block-new-center {margin-left: 180px !important; margin-right: 80px;}
.layui-form-btn {width: 80px; text-align: center; position: absolute; top: 0; right: 0; border-color: #eeeeee;}
.slide {width: 100%}
.slide .layui-slider {height: 38px;}
.slide .layui-slider .layui-slider-step {height: 100%;}
.slide .layui-slider .layui-slider-wrap {height: 100%; top: 0;}
.slide .layui-slider .layui-slider-wrap .layui-slider-wrap-btn {width: 20px; height: 20px;}
</style>
</head>
<body>
<div class="layui-anim layui-anim-fadein">
<div class="layui-card">
<div class="layui-card-body" style="padding: 15px 15px 35px 15px;">
<form class="layui-form layui-form-pane" lay-filter="dataForm">
<div class="layui-row layui-col-space15">
<div class="layui-col-xs6">
<div class="layui-form-item" pane>
<label class="layui-form-label">审核状态 *</label>
<div class="layui-input-block">
<input type="radio" name="applyStatus" value="APPROVED" title="同意" lay-filter="applyStatusFilter">
<input type="radio" name="applyStatus" value="REJECTED" title="拒绝" lay-filter="applyStatusFilter">
</div>
</div>
</div>
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label">审核意见</label>
<div class="layui-input-block">
<input type="text" id="applyNotes" name="applyNotes" class="layui-input" value="" placeholder="审核意见" maxlength="50" lay-verify="required">
</div>
</div>
</div>
</div>
<div id="approvedContent" style="margin-top: 15px; display: none;">
<blockquote class="layui-elem-quote">【项目价格设置】单位为<b>元(¥)</b>可保留两位小数如要使用系统默认金额设置为0即可</blockquote>
<div class=" layui-row layui-col-space15">
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label layui-form-label-new">全托管</label>
<div class="layui-input-block layui-input-block-new">
<input type="number" id="priceAll" name="priceAll" class="layui-input" value="" placeholder="全托管价格" maxlength="50">
</div>
</div>
</div>
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label layui-form-label-new">写材料</label>
<div class="layui-input-block layui-input-block-new">
<input type="number" id="priceMaterial" name="priceMaterial" class="layui-input" value="" placeholder="全托管价格" maxlength="50">
</div>
</div>
</div>
</div>
<blockquote class="layui-elem-quote" style="margin-top: 15px;">邀请码设置</blockquote>
<div class=" layui-row layui-col-space15">
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label layui-form-label-new">邀请码</label>
<div class="layui-input-block layui-input-block-new-center">
<input type="text" id="ic" name="ic" class="layui-input" placeholder="邀请码" maxlength="50" readonly>
</div>
<button type="button" class="layui-form-btn layui-btn layui-btn-primary" id="generateIc">生成</button>
</div>
</div>
<div class="layui-col-xs6">
<div class="layui-form-item">
<label class="layui-form-label layui-form-label-new">返利比率</label>
<div class="layui-input-block layui-input-block-new">
<input type="hidden" id="icRebateRatio" name="icRebateRatio">
<div id="icRebateRatioSlide" class="slide"></div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item layui-layout-admin">
<div class="layui-input-block">
<div class="layui-footer" style="left: 0;">
<button id="confirmBtn" type="button" class="layui-btn" lay-submit lay-filter="submitForm" style="display: none;">提交审核</button>
<button type="button" class="layui-btn layui-btn-primary close">返回上级</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate', 'slider'], function(){
var $ = layui.$;
var form = layui.form;
var slider = layui.slider;
var common = layui.common;
var query = top.restAjax.params(window.location.href);
var userIcApplyId = query.userIcApplyId;
var icRebateRatioSlide;
var $icRebateRatio = $('#icRebateRatio');
var $approvedContent = $('#approvedContent');
var $applyNotes = $('#applyNotes');
var $confirmBtn = $('#confirmBtn');
function generateIc() {
var loadLayerIndex;
top.restAjax.get(`api/user/expand/generate-ic`, {}, null, function(code, data) {
form.val('dataForm', {
ic: data.data
})
if(parseInt($icRebateRatio.val()) <= 0) {
icRebateRatioSlide.setValue(10);
}
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg('生成中...', {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
}
function init() {
var loadLayerIndex;
top.restAjax.get(`api/user/ic/apply/get/${userIcApplyId}`, {}, null, function(code, data) {
if(data.applyStatus === 'PENDING') {
data.applyStatus = 'REJECTED';
$confirmBtn.show();
}
if(data.applyStatus === 'APPROVED') {
$approvedContent.show();
}
data.priceAll = (data.priceAll / 100).toFixed(2)
data.priceMaterial = (data.priceMaterial / 100).toFixed(2)
var dataFormData = {};
for(var i in data) {
dataFormData[i] = data[i] +'';
}
form.val('dataForm', dataFormData);
form.render(null, 'dataForm');
icRebateRatioSlide = slider.render({
elem: '#icRebateRatioSlide',
max: 50,
min: 0,
step: 1,
showstep: true,
value: data.icRebateRatio,
range: false,
change: function(value) {
$icRebateRatio.val(value);
}
})
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
}
// 提交表单
form.on('submit(submitForm)', function(formData) {
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(`api/user/ic/apply/review/${userIcApplyId}`, formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
shade: 0.3,
yes: function(index) {
top.dialog.close(index);
window.location.reload();
},
btn2: function() {
closeBox();
}
});
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
});
return false;
});
init();
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
$('.close').on('click', function() {
closeBox();
});
form.on('radio(applyStatusFilter)', function(data) {
var elem = data.elem; // 获得 radio 原始 DOM 对象
var checked = elem.checked; // 获得 radio 选中状态
var value = elem.value; // 获得 radio 值
var othis = data.othis; // 获得 radio 元素被替换后的 jQuery 对象
if(value === 'APPROVED') {
$approvedContent.show();
$applyNotes.removeAttr('lay-verify');
} else if(value === 'REJECTED') {
$approvedContent.hide();
$applyNotes.attr('lay-verify', 'required');
}
});
$('#generateIc').click(function() {
generateIc();
});
// 校验
form.verify({
});
});
</script>
</body>
</html>