完成支付、电子面单、模板消息队列等功能

This commit is contained in:
hupeng
2023-07-25 23:45:57 +08:00
parent f8f699fe6a
commit 0ae51f9ee7
625 changed files with 8291 additions and 18630 deletions

View File

@ -1,9 +1,14 @@
package co.yixiang.yshop.module.member.api.user;
import cn.hutool.core.util.IdUtil;
import co.yixiang.yshop.framework.common.enums.CommonStatusEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.member.api.user.dto.MemberUserRespDTO;
import co.yixiang.yshop.module.member.api.user.dto.WechatUserDto;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -22,6 +27,23 @@ public class MemberUserApiImpl implements MemberUserApi {
@Resource
private MemberUserService userService;
@Resource
private PasswordEncoder passwordEncoder;
@Override
public void saveWechatMember(WechatUserDto wechatUserDto) {
MemberUserDO user = new MemberUserDO();
user.setNickname(wechatUserDto.getNickname());
user.setAvatar(wechatUserDto.getHeadimgurl());
// 生成密码
String password = IdUtil.fastSimpleUUID();
user.setPassword(encodePassword(password));
user.setUsername(wechatUserDto.getOpenid());
user.setLoginType("wechat");
user.setWxProfile(wechatUserDto);
userService.save(user);
}
@Override
public MemberUserRespDTO getUser(Long id) {
@ -44,4 +66,14 @@ public class MemberUserApiImpl implements MemberUserApi {
return UserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile));
}
/**
* 对密码进行加密
*
* @param password 密码
* @return 加密后的密码
*/
private String encodePassword(String password) {
return passwordEncoder.encode(password);
}
}

View File

@ -2,10 +2,7 @@ package co.yixiang.yshop.module.member.controller.admin.user;
import co.yixiang.yshop.framework.common.pojo.CommonResult;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserCreateReqVO;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserPageReqVO;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserUpdateReqVO;
import co.yixiang.yshop.module.member.controller.admin.user.vo.*;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.service.user.UserService;
@ -47,6 +44,14 @@ public class MemberUserController {
return success(true);
}
@PutMapping("/updateMony")
@Operation(summary = "更新用户余额与积分")
@PreAuthorize("@ss.hasPermission('member:user:update')")
public CommonResult<Boolean> updateMony(@Valid @RequestBody UserUpdateMoneyReqVO updateReqVO) {
userService.updateMony(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户")
@Parameter(name = "id", description = "编号", required = true)

View File

@ -1,5 +1,6 @@
package co.yixiang.yshop.module.member.controller.admin.user.vo;
import co.yixiang.yshop.module.member.api.user.dto.WechatUserDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@ -54,7 +55,7 @@ public class UserBaseVO {
@Schema(description = "是否为推广员", required = true)
@NotNull(message = "是否为推广员不能为空")
private Byte isPromoter;
private Integer isPromoter;
@Schema(description = "用户购买次数", example = "16061")
private Integer payCount;
@ -74,6 +75,36 @@ public class UserBaseVO {
private String loginType;
@Schema(description = "微信用户json信息")
private String wxProfile;
private WechatUserDto wxProfile;
@Schema(description = "生日")
private String birthday;
/**
* 最后一次登录ip
*/
private String loginIp;
/**
* 最后一次登录ip
*/
private String lastIp;
/**
* 等级
*/
private Integer level;
/**
* 推广元id
*/
private Long spreadUid;
/**
* 身份证号码
*/
private String cardId;
}

View File

@ -18,7 +18,7 @@ public class UserCreateReqVO extends UserBaseVO {
private String password;
@Schema(description = "生日")
private Integer birthday;
private String birthday;
@Schema(description = "身份证号码", example = "29961")
private String cardId;
@ -41,7 +41,7 @@ public class UserCreateReqVO extends UserBaseVO {
@Schema(description = "等级", required = true)
@NotNull(message = "等级不能为空")
private Byte level;
private Integer level;
@Schema(description = "推广元id", example = "5747")
private Long spreadUid;

View File

@ -25,10 +25,13 @@ public class UserPageReqVO extends PageParam {
private String nickname;
@Schema(description = "手机号码")
private String phone;
private String mobile;
@Schema(description = "添加时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "登录类型")
private String loginType;
}

View File

@ -0,0 +1,39 @@
package co.yixiang.yshop.module.member.controller.admin.user.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static co.yixiang.yshop.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 用户更新 Request VO")
@Data
@ToString(callSuper = true)
public class UserUpdateMoneyReqVO {
@Schema(description = "用户id", required = true, example = "16370")
@NotNull(message = "用户id不能为空")
private Long id;
@Schema(description = "修改金额类型")
private Integer ptype;
@Schema(description = "金额")
@NotNull(message = "金额不能为空")
private String money;
@Schema(description = "修改积分类型")
private Integer itype;
@Schema(description = "积分")
@NotNull(message = "积分不能为空")
private String integral;
}

View File

@ -22,7 +22,7 @@ public class UserUpdateReqVO extends UserBaseVO {
private String password;
@Schema(description = "生日")
private Integer birthday;
private String birthday;
@Schema(description = "身份证号码", example = "29961")
private String cardId;
@ -45,7 +45,7 @@ public class UserUpdateReqVO extends UserBaseVO {
@Schema(description = "等级", required = true)
@NotNull(message = "等级不能为空")
private Byte level;
private Integer level;
@Schema(description = "推广元id", example = "5747")
private Long spreadUid;

View File

@ -36,6 +36,15 @@ public class UserBillController {
private UserBillService userBillService;
@GetMapping("/page")
@Operation(summary = "获得用户账单分页")
@PreAuthorize("@ss.hasPermission('member:user-bill:query')")
public CommonResult<PageResult<UserBillRespVO>> getUserBillPage(@Valid UserBillPageReqVO pageVO) {
PageResult<UserBillDO> pageResult = userBillService.getUserBillPage(pageVO);
return success(UserBillConvert.INSTANCE.convertPage(pageResult));
}

View File

@ -33,6 +33,9 @@ public class AppAuthSmsLoginReqVO {
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
private String code;
@Schema(description = "设备来源", required = true, example = "h5")
private String from;
// ========== 绑定社交登录时,需要传递如下参数 ==========
@Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10")

View File

@ -42,13 +42,13 @@ public class AppUserQueryVo implements Serializable {
private Long sumSignDay;
@Schema(description = "当天是否签到", required = true)
private Boolean isDaySign;
private Integer isDaySign;
@Schema(description = "昨天是否签到", required = true)
private Boolean isYesterDaySign;
private Integer isYesterDaySign;
@Schema(description = "核销权限", required = true)
private Boolean checkStatus;
private Integer checkStatus;
@Schema(description = "用户昵称", required = true)
private String nickname;

View File

@ -24,6 +24,8 @@ public interface UserConvert {
AppUserQueryVo convert3(MemberUserDO bean);
UserRespVO convert4(MemberUserDO bean);
List<MemberUserRespDTO> convertList2(List<MemberUserDO> list);
MemberUserDO convert(UserCreateReqVO bean);

View File

@ -2,9 +2,13 @@ package co.yixiang.yshop.module.member.dal.dataobject.user;
import co.yixiang.yshop.framework.common.enums.CommonStatusEnum;
import co.yixiang.yshop.framework.tenant.core.db.TenantBaseDO;
import co.yixiang.yshop.module.member.api.user.dto.WechatUserDto;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -165,9 +169,10 @@ public class MemberUserDO extends TenantBaseDO {
* 用户登陆类型h5,wechat,routine
*/
private String loginType;
/**
* 微信用户json信息
*/
private String wxProfile;
/** 微信用户json信息 */
@TableField(typeHandler = FastjsonTypeHandler.class)
private WechatUserDto wxProfile;
}

View File

@ -32,10 +32,11 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
default PageResult<MemberUserDO> selectPage(UserPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MemberUserDO>()
.likeIfPresent(MemberUserDO::getLoginType, reqVO.getLoginType())
.likeIfPresent(MemberUserDO::getUsername, reqVO.getUsername())
.likeIfPresent(MemberUserDO::getRealName, reqVO.getRealName())
.likeIfPresent(MemberUserDO::getNickname, reqVO.getNickname())
.eqIfPresent(MemberUserDO::getMobile, reqVO.getPhone())
.eqIfPresent(MemberUserDO::getMobile, reqVO.getMobile())
.betweenIfPresent(MemberUserDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MemberUserDO::getId));
}
@ -58,4 +59,8 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
" where id=#{uid}")
int incPayCount(@Param("uid") Long uid);
@Update("update yshop_user set now_money=now_money+#{price}" +
" where id=#{uid}")
int incMoney(@Param("uid") Long uid,BigDecimal price);
}

View File

@ -12,6 +12,7 @@ import co.yixiang.yshop.module.member.controller.app.auth.vo.*;
import co.yixiang.yshop.module.member.convert.auth.AuthConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.member.enums.LoginTypeEnum;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.system.api.logger.LoginLogApi;
import co.yixiang.yshop.module.system.api.logger.dto.LoginLogCreateReqDTO;
@ -90,7 +91,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp));
// 获得获得注册用户
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp);
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp,reqVO.getFrom());
Assert.notNull(user, "获取用户失败,结果为空");
// 如果 socialType 非空,说明需要绑定社交用户
@ -132,7 +133,8 @@ public class MemberAuthServiceImpl implements MemberAuthService {
throw exception(AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR);
}
// 获得获得注册用户
MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP());
MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP(),
LoginTypeEnum.WXAPP.getValue());
Assert.notNull(user, "获取用户失败,结果为空");
// 绑定社交用户

View File

@ -43,7 +43,7 @@ public interface MemberUserService extends IService<MemberUserDO> {
* @param registerIp 注册 IP
* @return 用户对象
*/
MemberUserDO createUserIfAbsent(@Mobile String mobile, String registerIp);
MemberUserDO createUserIfAbsent(@Mobile String mobile, String registerIp,String from);
/**
* 更新用户的最后登陆信息
@ -123,4 +123,11 @@ public interface MemberUserService extends IService<MemberUserDO> {
*/
boolean isPasswordMatch(String rawPassword, String encodedPassword);
/**
* 更新用户余额
* @param uid y用户id
* @param price 金额
*/
void incMoney(Long uid,BigDecimal price);
}

View File

@ -67,17 +67,17 @@ public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper,MemberUs
}
@Override
public MemberUserDO createUserIfAbsent(String mobile, String registerIp) {
public MemberUserDO createUserIfAbsent(String mobile, String registerIp,String from) {
// 用户已经存在
MemberUserDO user = memberUserMapper.selectByMobile(mobile);
if (user != null) {
return user;
}
// 用户不存在,则进行创建
return this.createUser(mobile, registerIp);
return this.createUser(mobile, registerIp,from);
}
private MemberUserDO createUser(String mobile, String registerIp) {
private MemberUserDO createUser(String mobile, String registerIp,String from) {
// 生成密码
String password = IdUtil.fastSimpleUUID();
// 插入用户
@ -86,6 +86,7 @@ public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper,MemberUs
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
user.setPassword(encodePassword(password)); // 加密密码
user.setRegisterIp(registerIp);
user.setLoginType(from);
memberUserMapper.insert(user);
return user;
}
@ -179,6 +180,18 @@ public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper,MemberUs
return passwordEncoder.matches(rawPassword, encodedPassword);
}
/**
* 更新用户余额
* @param uid y用户id
* @param price 金额
*/
@Override
public void incMoney(Long uid, BigDecimal price) {
if(price!=null&&price.doubleValue()>0){
memberUserMapper.incMoney(uid,price);
}
}
/**
* 对密码进行加密
*

View File

@ -28,6 +28,13 @@ public interface UserService {
*/
void updateUser(@Valid UserUpdateReqVO updateReqVO);
/**
* 更新金额与积分
*
* @param updateReqVO 更新信息
*/
void updateMony(@Valid UserUpdateMoneyReqVO updateReqVO);
/**
* 删除用户
*

View File

@ -1,9 +1,16 @@
package co.yixiang.yshop.module.member.service.user;
import cn.hutool.core.util.NumberUtil;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.member.enums.BillDetailEnum;
import co.yixiang.yshop.module.member.service.userbill.UserBillService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.*;
import co.yixiang.yshop.module.member.controller.admin.user.vo.*;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
@ -26,6 +33,8 @@ public class UserServiceImpl implements UserService {
@Resource
private MemberUserMapper userMapper;
@Resource
private UserBillService userBillService;
@Override
public Long createUser(UserCreateReqVO createReqVO) {
@ -45,6 +54,56 @@ public class UserServiceImpl implements UserService {
userMapper.updateById(updateObj);
}
/**
* 更新金额与积分
*
* @param updateReqVO 更新信息
*/
@Override
public void updateMony(UserUpdateMoneyReqVO updateReqVO){
MemberUserDO memberUserDO = userMapper.selectById(updateReqVO.getId());
double newMoney = 0d;
String mark = "";
if(ShopCommonEnum.ADD_1.getValue().equals(updateReqVO.getPtype())){
mark = "系统增加了"+updateReqVO.getMoney()+"余额";
newMoney = NumberUtil.add(memberUserDO.getNowMoney(),new BigDecimal(updateReqVO.getMoney())).doubleValue();
userBillService.income(memberUserDO.getId(),"系统增加余额", BillDetailEnum.CATEGORY_1.getValue(),
BillDetailEnum.TYPE_6.getValue(),Double.valueOf(updateReqVO.getMoney()),newMoney, mark,"");
}else{
mark = "系统扣除了"+updateReqVO.getMoney()+"余额";
newMoney = NumberUtil.sub(memberUserDO.getNowMoney(),new BigDecimal(updateReqVO.getMoney())).doubleValue();
if(newMoney < 0) {
newMoney = 0d;
}
userBillService.expend(memberUserDO.getId(), "系统减少余额",
BillDetailEnum.CATEGORY_1.getValue(),
BillDetailEnum.TYPE_7.getValue(),
Double.valueOf(updateReqVO.getMoney()), newMoney, mark);
}
double newIntegral = 0d;
if(ShopCommonEnum.ADD_1.getValue().equals(updateReqVO.getItype())){
mark = "系统增加了"+updateReqVO.getIntegral()+"积分";
newIntegral = NumberUtil.add(memberUserDO.getIntegral(),new BigDecimal(updateReqVO.getIntegral())).doubleValue();
userBillService.income(memberUserDO.getId(),"系统增加积分", BillDetailEnum.CATEGORY_1.getValue(),
BillDetailEnum.TYPE_6.getValue(),Double.valueOf(updateReqVO.getIntegral()),newIntegral, mark,"");
}else{
mark = "系统扣除了"+updateReqVO.getIntegral()+"积分";
newIntegral = NumberUtil.sub(memberUserDO.getIntegral(),new BigDecimal(updateReqVO.getIntegral())).doubleValue();
if(newIntegral < 0) {
newIntegral = 0d;
}
userBillService.expend(memberUserDO.getId(), "系统减少积分",
BillDetailEnum.CATEGORY_1.getValue(),
BillDetailEnum.TYPE_7.getValue(),
Double.valueOf(updateReqVO.getIntegral()), newIntegral, mark);
}
memberUserDO.setIntegral(BigDecimal.valueOf(newIntegral));
memberUserDO.setNowMoney(BigDecimal.valueOf(newMoney));
userMapper.updateById(memberUserDO);
}
@Override
public void deleteUser(Long id) {
// 校验存在

View File

@ -0,0 +1,41 @@
//package co.yixiang.yshop.module.member.service.user.dto;
//
//import lombok.*;
//
///**
// * @ClassName WechatUserDTO
// * @Author hupeng <610796224@qq.com>
// * @Date 2023/7/18
// **/
//@Getter
//@Setter
//@Builder
//@AllArgsConstructor
//@NoArgsConstructor
//public class WechatUserDto {
//
// private String openid;
//
// private String unionId;
//
// private String routineOpenid;
//
// private String nickname;
//
// private String headimgurl;
//
// private Integer sex;
//
// private String city;
//
// private String language;
//
// private String province;
//
// private String country;
//
// private Boolean subscribe;
//
// private Long subscribeTime;
//
//}

View File

@ -13,6 +13,15 @@ import co.yixiang.yshop.framework.common.pojo.PageResult;
*/
public interface UserBillService {
/**
* 获得用户账单分页
*
* @param pageReqVO 分页查询
* @return 用户账单分页
*/
PageResult<UserBillDO> getUserBillPage(UserBillPageReqVO pageReqVO);
/**
* 增加支出流水
* @param uid uid

View File

@ -29,6 +29,12 @@ public class UserBillServiceImpl implements UserBillService {
@Resource
private UserBillMapper userBillMapper;
@Override
public PageResult<UserBillDO> getUserBillPage(UserBillPageReqVO pageReqVO) {
return userBillMapper.selectPage(pageReqVO);
}
/**
* 增加支出流水
* @param uid uid

View File

@ -8,7 +8,7 @@ spring:
spring:
# 数据源配置项
datasource:
name: ruoyi-vue-pro
name: yshop-pro
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa