This commit is contained in:
Vinjor 2025-03-27 09:49:52 +08:00
parent c0abedee45
commit 2534693284
21 changed files with 366 additions and 77 deletions

View File

@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.exception.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
@ -132,6 +133,7 @@ public class BaseCategoryController extends BaseController
* @return com.ruoyi.common.core.domain.AjaxResult
**/
@GetMapping("/listByCode")
@Anonymous
public AjaxResult listByCode(@RequestParam(value = "code") String code,
@RequestParam(value = "isSystem",required = false) Integer isSystem)
{

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.busi.query.AppNoticeQuery;
import com.ruoyi.busi.query.BusiNoticeQuery;
import com.ruoyi.busi.vo.BusiNoticeVo;
import com.ruoyi.common.annotation.Anonymous;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -148,6 +149,7 @@ public class BusiNoticeController extends BaseController
* @return com.ruoyi.common.core.domain.AjaxResult
**/
@GetMapping("/appList")
@Anonymous
public AjaxResult appList(AppNoticeQuery query,
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize)

View File

@ -5,7 +5,7 @@ import io.jsonwebtoken.Claims;
import java.util.Locale;
/**
* 通用常量信息
* 通用字典常量信息
*
* @author ruoyi
*/
@ -24,6 +24,21 @@ public class DictConstants
*/
public static final String RIGHTS_TYPE_NUMBER = "02";
/**
* 用户类型字典--通告主
*/
public static final String USER_TYPE_TGZ = "01";
/**
* 用户类型字典--博主
*/
public static final String USER_TYPE_BZ = "02";
/**
* 是否字典--
*/
public static final String YES_NO_YES = "1";
/**
* 是否字典--
*/
public static final String YES_NO_NO = "0";
}

View File

@ -0,0 +1,13 @@
package com.ruoyi.constant;
/**
* 通用常量信息
*
* @author ruoyi
*/
public class StrConstants
{
}

View File

@ -4,6 +4,8 @@ import com.ruoyi.common.annotation.Excel;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.constant.DictConstants;
import lombok.*;
import com.ruoyi.common.core.domain.DlBaseEntity;
@ -71,4 +73,19 @@ public class MemberUser extends DlBaseEntity
@Excel(name = "博主-剩余积分")
private Long bPoints;
public MemberUser (String userType, SysUser user,Integer addNotice){
this.userType = userType;
this.userId = user.getUserId();
this.tel = user.getPhonenumber();
if(DictConstants.USER_TYPE_BZ.equals(userType)){
//博主
this.bPoints=0L;
}else{
//通告主
this.tRemaining = addNotice;
this.tTotalNum = 0L;
this.tFansNum = 0;
this.tOpenDisturb = DictConstants.YES_NO_NO;
}
}
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.ruoyi.member.domain.MemberCard;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 会员开卡记录Mapper接口
@ -14,5 +15,13 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MemberCardMapper extends BaseMapper<MemberCard>
{
/**
* 查询某会员当前生效的所有会员卡id
* @author vinjor-M
* @date 11:32 2025/3/26
* @param userId TODO
* @param userType TODO
* @return java.util.List<java.lang.String>
**/
List<MemberCard> selectCardIdByUserId(@Param("userId")Long userId,@Param("userType")String userType,@Param("nowDate")String nowDate);
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.ruoyi.member.domain.MemberRights;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 会员权益(定时任务重置剩余值)用户id会员卡id权益对应1Mapper接口
@ -15,4 +16,13 @@ import org.apache.ibatis.annotations.Mapper;
public interface MemberRightsMapper extends BaseMapper<MemberRights>
{
/**
* 查某用户某些会员卡的权益明细
* @author vinjor-M
* @date 13:52 2025/3/26
* @param cardIdList 会员卡id集和
* @param userId 用户id
* @return java.util.List<com.ruoyi.member.domain.MemberRights>
**/
List<MemberRights> selectUserRightsByCardIds(@Param("list")List<String> cardIdList,@Param("userId")Long userId);
}

View File

@ -2,8 +2,12 @@ package com.ruoyi.member.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.member.domain.MemberCard;
import com.ruoyi.member.domain.MemberRights;
import com.ruoyi.member.vo.MemberRightsVO;
import com.ruoyi.member.vo.ViewRightsVO;
import java.util.List;
import java.util.Map;
/**
* 会员开卡记录Service接口
@ -23,4 +27,13 @@ public interface IMemberCardService extends IService<MemberCard> {
**/
List<MemberCard> listByUserId(Long userId,String userType);
/**
* 查当前会员权益列表
* @author vinjor-M
* @date 11:26 2025/3/26
* @param userType 用户类型
* @param userId 用户id
**/
Map<String,Map<String, ViewRightsVO>> selectMemberRights(Long userId, String userType);
}

View File

@ -47,4 +47,13 @@ public interface IMemberUserService extends IService<MemberUser> {
**/
MemberUserVO bloggerDetail(Long userId);
/**
* 微信授权登陆
* @author vinjor-M
* @date 15:55 2025/3/26
* @param openid TODO
* @param decryptResult TODO
* @return java.lang.String
**/
String wxLogin(String openid,String decryptResult);
}

View File

@ -1,15 +1,24 @@
package com.ruoyi.member.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.DlBaseEntity;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.constant.DictConstants;
import com.ruoyi.member.domain.MemberCard;
import com.ruoyi.member.domain.MemberRights;
import com.ruoyi.member.mapper.MemberCardMapper;
import com.ruoyi.member.mapper.MemberRightsMapper;
import com.ruoyi.member.service.IMemberCardService;
import com.ruoyi.member.vo.MemberRightsVO;
import com.ruoyi.member.vo.ViewRightsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* 会员开卡记录Service业务层处理
@ -22,6 +31,8 @@ public class MemberCardServiceImpl extends ServiceImpl<MemberCardMapper,MemberCa
{
@Autowired
private MemberCardMapper memberCardMapper;
@Autowired
private MemberRightsMapper memberRightsMapper;
/**
@ -43,4 +54,71 @@ public class MemberCardServiceImpl extends ServiceImpl<MemberCardMapper,MemberCa
.orderByDesc(DlBaseEntity::getCreateTime);
return list(lambdaUpdateWrapper);
}
/**
* 查当前会员权益列表
*
* @param userId 用户id
* @param userType 用户类型
* @author vinjor-M
* @date 11:26 2025/3/26
**/
@Override
public Map<String, Map<String,ViewRightsVO>> selectMemberRights(Long userId, String userType) {
Map<String, Map<String,ViewRightsVO>> rtnMap = new HashMap<>();
//当前时间
String nowDate = DateUtil.formatDate(new Date());
if(null==userId){
userId = SecurityUtils.getUserId();
}
List<MemberCard> cardList = memberCardMapper.selectCardIdByUserId(userId,userType,nowDate);
if(cardList.isEmpty()){
//未开通任何会员卡
rtnMap.put("tgz",new HashMap<>());
rtnMap.put("bz",new HashMap<>());
}else{
//开通会员卡了根据会员卡id查询出所有权益
List<MemberRights> memberRightsList = memberRightsMapper.selectUserRightsByCardIds(cardList.stream().map(MemberCard::getCardId).collect(Collectors.toList()), userId);
//通告主权益
Map<String,ViewRightsVO> tgzRightsMap = new HashMap<>();
//博主权益
Map<String,ViewRightsVO> bzRightsMap = new HashMap<>();
memberRightsList.forEach(item -> {
if (DictConstants.USER_TYPE_TGZ.equals(item.getUserType())) {
//通告主
this.checkRights(tgzRightsMap,item);
} else if (DictConstants.USER_TYPE_BZ.equals(item.getUserType())) {
//博主
this.checkRights(bzRightsMap,item);
}
});
rtnMap.put("tgz",tgzRightsMap);
rtnMap.put("bz",bzRightsMap);
}
return rtnMap;
}
/**
*
* @author vinjor-M
* @date 14:19 2025/3/26
* @param memberRightsMap 会员权益map
* @param item 这个权益
**/
private void checkRights(Map<String, ViewRightsVO> memberRightsMap, MemberRights item){
ViewRightsVO newRights = new ViewRightsVO();
BeanUtils.copyProperties(item,newRights);
if (memberRightsMap.containsKey(item.getRightsCode())) {
//有这个权益了
ViewRightsVO oldRights = memberRightsMap.get(item.getRightsCode());
if (DictConstants.RIGHTS_TYPE_NUMBER.equals(item.getRightsType()) &&
oldRights.getRemaining() < item.getRemaining()) {
//权益类型是数量限制的且新的权益剩余值比原来的大取新的
memberRightsMap.put(item.getRightsCode(), newRights);
}
} else {
//没有这个权益直接加
memberRightsMap.put(item.getRightsCode(), newRights);
}
}
}

View File

@ -1,18 +1,29 @@
package com.ruoyi.member.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.busi.service.IBusiEvaluateService;
import com.ruoyi.busi.service.IBusiNoticeService;
import com.ruoyi.common.config.DlRightsConfig;
import com.ruoyi.common.config.WxAppConfig;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.constant.DictConstants;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.member.domain.MemberUser;
import com.ruoyi.member.mapper.MemberUserMapper;
import com.ruoyi.member.service.IMemberBusiCardService;
import com.ruoyi.member.service.IMemberCardService;
import com.ruoyi.member.service.IMemberUserService;
import com.ruoyi.member.vo.MemberUserVO;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@ -34,6 +45,12 @@ public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper, MemberU
private IBusiNoticeService noticeService;
@Resource
private IMemberBusiCardService busiCardService;
@Autowired
private TokenService tokenService;
@Autowired
private SysUserMapper userMapper;
@Autowired
private DlRightsConfig dlRightsConfig;
/**
@ -89,4 +106,66 @@ public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper, MemberU
result.setNoticeVos(noticeService.queryListByUserId(userId));
return result;
}
/**
* 微信授权登陆
*
* @param openid TODO
* @param decryptResult TODO
* @return java.lang.String
* @author vinjor-M
* @date 15:53 2025/3/26
**/
@Override
@Transactional(rollbackFor = Exception.class)
public String wxLogin(String openid, String decryptResult) {
//字符串转json
JSONObject jsonObject = JSONObject.parseObject(decryptResult);
//手机号
String phone = jsonObject.getString("phoneNumber");
//根据openid判断数据库中是否有该用户
//根据openid查询用户信息
SysUser wxUser = userMapper.selectWxUserByOpenIdOrPhone(openid,null);
if(null==wxUser){
//根据openId没查到再根据手机号查
wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,phone);
}
//如果查不到则新增查到了则更新
SysUser user = new SysUser();
if (wxUser == null) {
// 新增
// 设置姓名 默认使用昵称+随机数防止重复姓名的发生 数据库中把username的长度修改的长一点
user.setUserName(phone);
user.setNickName("微信用户");
user.setOpenId(openid);
user.setPhonenumber(phone);
user.setSex("2");
user.setCreateTime(DateUtils.getNowDate());
//新增 用户
userMapper.insertUser(user);
//插入用户扩展信息表数据
this.save(new MemberUser(DictConstants.USER_TYPE_TGZ,user,dlRightsConfig.getAddNotice()));
this.save(new MemberUser(DictConstants.USER_TYPE_BZ,user,null));
}else {
//,查到了
if(!"0".equals(wxUser.getStatus())){
//非正常状态无法登录
throw new ServiceException("账号状态异常");
}
// 更新
user = wxUser;
if(!openid.equals(user.getOpenId())){
user.setOpenId(openid);
user.setUpdateTime(DateUtils.getNowDate());
userMapper.updateUser(user);
}
}
//组装token信息
LoginUser loginUser = new LoginUser();
loginUser.setOpenId(openid);
loginUser.setUser(user);
loginUser.setUserId(user.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.member.vo;
import com.ruoyi.member.domain.MemberRights;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 会员拥有的权益明细
* @author vinjor-M
* @date 11:25 2025/3/26
**/
@EqualsAndHashCode(callSuper = true)
@Data
public class MemberRightsVO extends MemberRights {
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.member.vo;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
/**
* 会员权限浏览使用
* @author vinjor-M
* @date 15:09 2025/3/26
**/
@Data
public class ViewRightsVO {
/** 权益编码 */
private String rightsCode;
/** 剩余值 (权益类型为是否时0代表不支持1代表支持权益类型为数量限制时0代表不限制其他数字代表具体限制数量) */
private Long remaining;
}

View File

@ -13,6 +13,8 @@ import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.WxAppConfig;
import com.ruoyi.common.core.domain.model.WxLoginBody;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.member.service.IMemberCardService;
import com.ruoyi.member.service.IMemberUserService;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -60,6 +62,10 @@ public class SysLoginController
@Autowired
private SysPermissionService permissionService;
@Autowired
private IMemberUserService memberUserService;
@Autowired
private IMemberCardService memberCardService;
@Autowired
private TokenService tokenService;
@ -94,7 +100,7 @@ public class SysLoginController
if (StringUtils.hasText(decryptResult)){
//如果解析成功,获取token
String token = loginService.wxLogin(openid,decryptResult);
String token = memberUserService.wxLogin(openid,decryptResult);
AjaxResult ajax = AjaxResult.success();
ajax.put(Constants.TOKEN, token);
return ajax;
@ -143,6 +149,7 @@ public class SysLoginController
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
ajax.put("rights", memberCardService.selectMemberRights(loginUser.getUserId(),null));
return ajax;
}

View File

@ -146,7 +146,11 @@ xss:
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# 微信小程序配置
# 微信小程序配置----dl
wx-app:
appId: wxd8ef44a8268672e4
appSecret: 30c18855ceb0ab0f9801407c998199c2
appSecret: 30c18855ceb0ab0f9801407c998199c2
# 普通用户权益值
dl-rights:
# 每月发布通告额度
addNotice: 3

View File

@ -70,7 +70,7 @@
dbn.del_flag = 0
AND (dbn.approval_status = '1')
<if test="entity.gift!=null and entity.gift!=''">
AND ( dbn.gift_detail != NULL AND dbn.gift_detail != '' )
AND ( dbn.gift_detail IS NOT NULL AND dbn.gift_detail != '' )
</if>
<if test="entity.platformCode!=null and entity.platformCode!=''">
AND ( dbn.platform_code =#{entity.platformCode} )
@ -83,10 +83,10 @@
dbn.detail LIKE CONCAT('%',#{entity.searchValue},'%') )
</if>
<if test="entity.rewardType=='money'">
AND ( dbn.fee_down!=null OR dbn.fee_up!= null )
AND ( dbn.fee_down IS NOT NULL OR dbn.fee_up IS NOT NULL )
</if>
<if test="entity.rewardType=='gift'">
AND ( dbn.gift_detail!=null AND dbn.gift_detail!='' )
AND ( dbn.gift_detail IS NOT NULL AND dbn.gift_detail!='' )
</if>
<if test="entity.fansUp!=null">
AND ( dbn.fans_up &lt;=#{entity.fansUp} )

View File

@ -22,6 +22,26 @@
<sql id="selectMemberCardVo">
select id, user_id, user_type, card_id, start_date, end_date, order_id, creator, create_time, updater, update_time, del_flag from dl_member_card
</sql>
<select id="selectCardIdByUserId" resultType="com.ruoyi.member.domain.MemberCard">
SELECT
dmc.id,
dmc.user_id,
dmc.user_type,
dmc.card_id
FROM
dl_member_card dmc
WHERE
dmc.del_flag = 0
<if test="userId!=null">
AND dmc.user_id = #{userId}
</if>
<if test="userType!=null and userType!=''">
AND dmc.user_type = #{userType}
</if>
<if test="nowDate!=null and nowDate!=''">
AND dmc.start_date &lt;= #{nowDate} AND dmc.end_date &gt;= #{nowDate}
</if>
</select>
</mapper>

View File

@ -21,6 +21,18 @@
<sql id="selectMemberRightsVo">
select id, user_id, user_type, card_id, rights_code, rights_type, rights_cycle, rights_value, remaining, create_time, update_time from dl_member_rights
</sql>
<select id="selectUserRightsByCardIds" resultType="com.ruoyi.member.domain.MemberRights">
SELECT
dmr.*
FROM
dl_member_rights dmr
WHERE
dmr.user_id = #{userId}
AND dmr.card_id IN
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,14 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "dl-rights")
@Data
public class DlRightsConfig {
/** 每月发布通告额度 */
private Integer addNotice;
}

View File

@ -34,14 +34,18 @@ public class DefaultDBFieldHandler implements MetaObjectHandler {
baseDO.setUpdateTime(current);
}
// 获取当前的用户
Long userId = SecurityUtils.getUserId();
// 当前登录用户不为空创建人为空则当前登录用户为创建人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getCreator())) {
baseDO.setCreator(userId.toString());
}
// 当前登录用户不为空更新人为空则当前登录用户为更新人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getUpdater())) {
baseDO.setUpdater(userId.toString());
try {
Long userId = SecurityUtils.getUserId();
// 当前登录用户不为空创建人为空则当前登录用户为创建人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getCreator())) {
baseDO.setCreator(userId.toString());
}
// 当前登录用户不为空更新人为空则当前登录用户为更新人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getUpdater())) {
baseDO.setUpdater(userId.toString());
}
}catch (Exception e){
//拦截异常不抛出
}
}
}
@ -62,9 +66,13 @@ public class DefaultDBFieldHandler implements MetaObjectHandler {
// }
//更新数据时强制更新数据的更新时间和更新人
setFieldValByName("updateTime", new Date(), metaObject);
Long userId = SecurityUtils.getUserId();
if (Objects.nonNull(userId)) {
setFieldValByName("updater", userId.toString(), metaObject);
try {
Long userId = SecurityUtils.getUserId();
if (Objects.nonNull(userId)) {
setFieldValByName("updater", userId.toString(), metaObject);
}
}catch (Exception e){
//拦截异常不抛出
}
}
}

View File

@ -106,62 +106,6 @@ public class SysLoginService
return tokenService.createToken(loginUser);
}
/**
* 微信登录
*
* @param decryptResult 登录凭证 只能用一次
* @return
*/
public String wxLogin(String openid,String decryptResult){
//字符串转json
JSONObject jsonObject = JSONObject.parseObject(decryptResult);
//手机号
String phone = jsonObject.getString("phoneNumber");
//根据openid判断数据库中是否有该用户
//根据openid查询用户信息
SysUser wxUser = userMapper.selectWxUserByOpenIdOrPhone(openid,null);
if(null==wxUser){
//根据openId没查到再根据手机号查
wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,phone);
}
//如果查不到则新增查到了则更新
SysUser user = new SysUser();
if (wxUser == null) {
// 新增
// 设置姓名 默认使用昵称+随机数防止重复姓名的发生 数据库中把username的长度修改的长一点
user.setUserName(phone);
user.setNickName("微信用户");
user.setOpenId(openid);
user.setPhonenumber(phone);
user.setSex("2");
user.setCreateTime(DateUtils.getNowDate());
//新增 用户
userMapper.insertUser(user);
}else {
//,查到了
if(!"0".equals(wxUser.getStatus())){
//非正常状态无法登录
throw new ServiceException("账号状态异常");
}
// 更新
user = wxUser;
if(!openid.equals(user.getOpenId())){
user.setOpenId(openid);
user.setUpdateTime(DateUtils.getNowDate());
userMapper.updateUser(user);
}
}
//组装token信息
LoginUser loginUser = new LoginUser();
loginUser.setOpenId(openid);
loginUser.setUser(user);
loginUser.setUserId(user.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
/**
* 校验验证码
*