Compare commits

...

2 Commits

Author SHA1 Message Date
c00a065030 新增店铺会员功能 2026-01-13 16:23:31 +08:00
8f6948af90 新增店铺会员功能 2026-01-13 16:23:10 +08:00
54 changed files with 1918 additions and 187 deletions

View File

@ -187,7 +187,7 @@ public class AccountController {
@RequestParam(name = "user_store_total") Integer user_store_total,
@RequestParam(name = "user_fans_vip_total", defaultValue = "0") Integer user_fans_vip_total,
@RequestParam(name = "user_fans_team_total", defaultValue = "0") Integer user_fans_team_total) {
return CommonResult.success(accountUserInfoService.checkUpdateUserLevel(user_id, user_exp_total, user_fans_total, user_spend_total, user_store_total, user_fans_vip_total, user_fans_team_total));
return CommonResult.success(accountUserInfoService.checkUpdateUserLevel(user_id, user_exp_total, user_fans_total, user_spend_total, user_store_total, user_fans_vip_total, user_fans_team_total,null,null));
}
@RequestMapping(value = "/checkUpdateUserLevelById", method = RequestMethod.POST)
@ -196,7 +196,7 @@ public class AccountController {
@RequestParam(name = "user_exp_total") BigDecimal user_exp_total,
@RequestParam(name = "user_fans_total") Integer user_fans_total) {
AccountUserAnalytics analytics = accountUserAnalyticsService.get(user_id);
return CommonResult.success(accountUserInfoService.checkUpdateUserLevel(user_id, user_exp_total, user_fans_total, analytics.getUser_spend(), 0, 0, 0));
return CommonResult.success(accountUserInfoService.checkUpdateUserLevel(user_id, user_exp_total, user_fans_total, analytics.getUser_spend(), 0, 0, 0,null,null));
}
@ApiOperation(value = "用户SNS信息", notes = "用户SNS信息")
@ -494,4 +494,9 @@ public class AccountController {
return accountUserBindConnectService.getAllBindCount(bindTmpl);
}
@RequestMapping(value = "/updateBatchAccountUserBindConnect", method = RequestMethod.POST)
public ThirdApiRes updateBatchAccountUserBindConnect(@RequestBody List<AccountUserBindConnect> accountUserBindConnectList) {
return accountUserBindConnectService.updateBatchAccountUserBindConnect(accountUserBindConnectList);
}
}

View File

@ -1,13 +1,11 @@
package com.suisung.mall.account.controller.mobile;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.suisung.mall.account.service.AccountUserBindConnectService;
import com.suisung.mall.account.service.WeiXinService;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@ -160,4 +158,12 @@ public class WeiXinController extends BaseControllerImpl {
return "fail";
}
@ApiOperation(value = "同意之后调用函数", notes = "小程序回调")
@RequestMapping(value = "/addPatAccountSendNumber")
public CommonResult addPatAccountSendNumber(@RequestParam(value = "storeId",defaultValue ="0") Integer storeId,
@RequestParam(value = "mobile") String mobile) {
accountUserBindConnectService.saveBindCountSendNumber(storeId,mobile);
return CommonResult.success();
}
}

View File

@ -36,7 +36,7 @@ public class UpgradeUserLevelListener {
// String messageId = message.getMessageProperties().getMessageId();
try {
boolean flag = accountUserInfoService.checkUpdateUserLevel(userLevelTO.getUser_id(), userLevelTO.getUser_exp_total(), userLevelTO.getUser_fans_total(), userLevelTO.getUser_spend_total(), 0, 0, 0);
boolean flag = accountUserInfoService.checkUpdateUserLevel(userLevelTO.getUser_id(), userLevelTO.getUser_exp_total(), userLevelTO.getUser_fans_total(), userLevelTO.getUser_spend_total(), 0, 0, 0,userLevelTO.getStore_id(),userLevelTO.getUser_store_spend_total());
if (flag) {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} else {

View File

@ -3,6 +3,7 @@ package com.suisung.mall.account.service;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.modules.account.AccountUserBindConnect;
import com.suisung.mall.common.pojo.req.WxUserInfoReq;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
import com.suisung.mall.core.web.service.IBaseService;
import java.util.List;
@ -103,4 +104,13 @@ public interface AccountUserBindConnectService extends IBaseService<AccountUserB
* @return 1-存在2-不存在3-参数有误
*/
Integer isMerchantExists(String mobile);
void saveBindCountSendNumber(Integer storeId,String mobile);
/**
* 批量保存accountUserBindConnect
*
* @return
*/
ThirdApiRes updateBatchAccountUserBindConnect(List<AccountUserBindConnect> accountUserBindConnectList);
}

View File

@ -26,7 +26,7 @@ public interface AccountUserInfoService extends IBaseService<AccountUserInfo> {
Map getLists(QueryWrapper<AccountUserBase> queryWrapper, Integer page, Integer rows);
boolean checkUpdateUserLevel(Integer user_id, BigDecimal user_exp_total, Integer user_fans_total, BigDecimal user_spend_total, Integer user_store_total, Integer user_fans_vip_total, Integer user_fans_team_total);
boolean checkUpdateUserLevel(Integer user_id, BigDecimal user_exp_total, Integer user_fans_total, BigDecimal user_spend_total, Integer user_store_total, Integer user_fans_vip_total, Integer user_fans_team_total,Integer store_id,BigDecimal user_store_spend_total);
BigDecimal getDistUserLevelConfig(String key, Integer user_id, BigDecimal defaultValue);

View File

@ -50,6 +50,10 @@ import com.suisung.mall.common.modules.distribution.ShopDistributionUser;
import com.suisung.mall.common.modules.distribution.ShopDistributionUserCommission;
import com.suisung.mall.common.modules.pay.PayUserResource;
import com.suisung.mall.common.modules.plantform.ShopPlantformSubsiteUser;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.store.ShopStoreInfo;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import com.suisung.mall.common.pojo.dto.SmsDto;
import com.suisung.mall.common.pojo.req.WxUserInfoReq;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
@ -67,6 +71,7 @@ import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -107,6 +112,8 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
private SnsService snsService;
@Autowired
private HttpServletRequest request;
@Lazy
@Autowired
private ShopService shopService;
@Autowired
@ -1348,7 +1355,7 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
// 检测升级
AccountUserSns user_role_row = accountUserSnsService.get(fx_user_parent_id);
accountUserInfoService.checkUpdateUserLevel(fx_user_parent_id, BigDecimal.ZERO, user_role_row.getUser_fans(), BigDecimal.ZERO, 0, 0, 0);
accountUserInfoService.checkUpdateUserLevel(fx_user_parent_id, BigDecimal.ZERO, user_role_row.getUser_fans(), BigDecimal.ZERO, 0, 0, 0,null,null);
}
} else {
// 判断是否需要减少用户关系
@ -3028,6 +3035,7 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
String mobile = PhoneNumberUtils.convWithIDDCodePhoneNumber(wxUserInfoReq.getPhoneNumber(), iddCode);
AccountUserBase accountUserBase = getByAccountAndType(mobile, CommonConstant.USER_TYPE_NORMAL);
Integer userId=0;
if (accountUserBase == null) {
// 检测到用户尚未注册立即新增用户基本信息和用户附加信息
Date today = new Date();
@ -3060,7 +3068,7 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
return CommonResult.failed(_("微信注册账号失败!"));
}
Integer userId = accountUserBase.getUser_id();
userId = accountUserBase.getUser_id();
AccountUserLogin user_login_reg_row = new AccountUserLogin();
user_login_reg_row.setUser_id(userId);
@ -3142,6 +3150,36 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
args.put("register_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(today));
messageService.sendNoticeMsg(userId, 0, message_id, args);
}else {
userId=accountUserBase.getUser_id();
}
//店铺会员如果从店铺进去 则生成店铺会员需要传入店铺id
if(com.suisung.mall.common.utils.StringUtils.isNotEmpty(wxUserInfoReq.getStoreId())){
ShopStoreMember params=new ShopStoreMember();
params.setUserId(accountUserBase.getUser_id());
params.setStoreId(Convert.toInt(wxUserInfoReq.getStoreId()));
List<ShopStoreMember> shopStoreMembers= shopService.findShopStoreMemberList(params);
ShopStoreBase shopStoreBase= shopService.getShopStoreBase(Convert.toInt(wxUserInfoReq.getStoreId()));
if(shopStoreMembers.isEmpty()&&shopStoreBase!=null){
ShopStoreMember shopStoreMember = new ShopStoreMember();
shopStoreMember.setStoreName(shopStoreBase.getStore_name());
shopStoreMember.setStoreId(shopStoreBase.getStore_id());
shopStoreMember.setUserId(userId);
shopStoreMember.setBind_openid(wxUserInfoReq.getOpenId());
shopStoreMember.setUserNickname(accountUserBase.getUser_nickname());
shopStoreMember.setUserAccount(accountUserBase.getUser_account());
ShopStoreMember saveShopStoreMember= shopService.saveShopStoreMember(shopStoreMember);
ShopStoreMemberLevel shopStoreMemberLevel = getShopStoreMemberLevel(shopStoreBase, saveShopStoreMember);
shopStoreMemberLevel.setUserId(userId);
shopService.saveShopStoreMemberLevel(shopStoreMemberLevel);
}else{
ShopStoreMember updateShopStoreMember = shopStoreMembers.get(0);
if(com.suisung.mall.common.utils.StringUtils.isNotEmpty(updateShopStoreMember.getBind_openid())){
updateShopStoreMember.setBind_openid(wxUserInfoReq.getOpenId());
shopService.saveShopStoreMember(updateShopStoreMember);
}
}
}
// accountUserBase == null 的情况
@ -3168,6 +3206,17 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
return login(params);
}
private ShopStoreMemberLevel getShopStoreMemberLevel(ShopStoreBase shopStoreBase, ShopStoreMember shopStoreMember) {
ShopStoreMemberLevel shopStoreMemberLevel=new ShopStoreMemberLevel();
shopStoreMemberLevel.setStoreId(shopStoreBase.getStore_id());
shopStoreMemberLevel.setStoreMemberId(shopStoreMember.getStore_member_id());
shopStoreMemberLevel.setUserLevelName("v1");
shopStoreMemberLevel.setUserLevelId(1001);
shopStoreMemberLevel.setMemberLevelId(1001);
shopStoreMemberLevel.setMemberLevelName("v1");
return shopStoreMemberLevel;
}
/**
* 手机号登陆操作

View File

@ -15,12 +15,18 @@ import com.suisung.mall.account.service.AccountUserInfoService;
import com.suisung.mall.common.api.BindCode;
import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.constant.RedisConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.feignService.ShopService;
import com.suisung.mall.common.modules.account.AccountUserBase;
import com.suisung.mall.common.modules.account.AccountUserBindConnect;
import com.suisung.mall.common.modules.account.AccountUserInfo;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.pojo.req.WxUserInfoReq;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.ContextUtil;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
@ -28,10 +34,10 @@ import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@ -45,6 +51,7 @@ import java.util.*;
*/
@Slf4j
@Service
@Transactional
public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUserBindConnectMapper, AccountUserBindConnect> implements AccountUserBindConnectService {
@Autowired
@ -53,6 +60,12 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
@Autowired
private AccountUserBaseService accountUserBaseService;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ShopService shopService;
/**
* 获取有效绑定
*
@ -427,6 +440,82 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
}
}
@Override
public void saveBindCountSendNumber(Integer storeId,String mobile) {
if (storeId == null) {
return ;
}
UserDto userDto= ContextUtil.getCurrentUser();
assert userDto != null;
Integer userId=userDto.getId();
String mapKey= RedisConstant.SUB_SEND_CACHE+userId;
redisTemplate.opsForHash().increment(RedisConstant.SUB_SEND_CACHE,mapKey, 1);//todo 删除
if(redisTemplate.opsForHash().get(RedisConstant.SUB_SEND_CACHE,mapKey)!=null) {
Integer integer = (Integer) redisTemplate.opsForHash().get(RedisConstant.SUB_SEND_CACHE, mapKey);
if(integer!=null&& integer >0){
if(storeId>0){ //店铺推送订阅
ShopStoreMember params=new ShopStoreMember();
params.setUserId(userId);
params.setStoreId(storeId);
List<ShopStoreMember> shopStoreMemberList=shopService.findShopStoreMemberList(params);
if(shopStoreMemberList!=null&& !shopStoreMemberList.isEmpty()){
ShopStoreMember shopStoreMember= shopStoreMemberList.get(0);
shopStoreMember.setSend_number(shopStoreMember.getSend_number()+1);
ShopStoreMember resultShopStoreMember = shopService.saveShopStoreMember(shopStoreMember);
if(resultShopStoreMember.getStore_member_id()!=null){
redisTemplate.opsForHash().increment(RedisConstant.SUB_SEND_CACHE,mapKey, -1);//店铺扣除一次
}
}
}else {//平台推送订阅
QueryWrapper<AccountUserBindConnect> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("bind_id", "+86"+mobile)//+86的
.eq("bind_type", BindCode.MOBILE)
.eq("user_type", 0)
.eq("user_id", userId)
.eq("bind_active", CommonConstant.Enable)
.orderByAsc("bind_time");
List<AccountUserBindConnect> accountUserBindConnectList = list(queryWrapper);
AccountUserBindConnect accountUserBindConnect= accountUserBindConnectList.get(0);
if (accountUserBindConnectList.isEmpty()){
return;
}
UpdateWrapper<AccountUserBindConnect> updateWrapper = new UpdateWrapper<>();
accountUserBindConnect.setSend_number(accountUserBindConnect.getSend_number()+1);
getUpdateWrapper(updateWrapper, accountUserBindConnect);
if(update(updateWrapper)){
redisTemplate.opsForHash().increment(RedisConstant.SUB_SEND_CACHE,mapKey, -1);//店铺扣除一次
}
}
}
}
}
@Override
public ThirdApiRes updateBatchAccountUserBindConnect(List<AccountUserBindConnect> accountUserBindConnectList) {
boolean result = false;
if (!accountUserBindConnectList.isEmpty()) {
UpdateWrapper<AccountUserBindConnect> updateWrapper= new UpdateWrapper<>();
try {
for (AccountUserBindConnect accountUserBindConnect : accountUserBindConnectList) {
updateWrapper.set("send_number", accountUserBindConnect.getSend_number());
updateWrapper.eq("bind_id", accountUserBindConnect.getBind_id());
updateWrapper.eq("user_id", accountUserBindConnect.getUser_id());
updateWrapper.eq("bind_type", accountUserBindConnect.getBind_type());
updateWrapper.eq("user_type", accountUserBindConnect.getUser_type());
this.update(updateWrapper);
}
} catch (Exception e) {
throw new RuntimeException("保存AccountUserBindConnect报错" + e.getMessage());
}
}
if (result) {
return new ThirdApiRes().success("成功");
}
return new ThirdApiRes().fail(250, "保存异常");
}
/**
* 用户绑定手机号和openid
@ -573,6 +662,7 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
.eq("user_type", CommonConstant.USER_TYPE_NORMAL)
.eq("bind_active", CommonConstant.Enable)
.eq("bind_tmpl", bindTmpl)
.gt("send_number",0)
.orderByAsc("bind_time");
return this.lists(queryWrapper, pageNum, pageSize).getRecords();
}
@ -621,6 +711,8 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
String templateId = object.getStr("TemplateId");//模板id
String SubscribeStatusString = object.getStr("SubscribeStatusString");//订阅结果accept接收reject拒收参考地址https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF%E8%AF%AD%E9%9F%B3%E6%8F%90%E9%86%92
if (SubscribeStatusString.equals("accept")) {
String mapKey= RedisConstant.SUB_SEND_CACHE+accountUserBindConnect.getUser_id();
redisTemplate.opsForHash().increment(RedisConstant.SUB_SEND_CACHE,mapKey, 1);
accountUserBindConnect.setBind_tmpl(templateId);
getUpdateWrapper(updateWrapper, accountUserBindConnect);
}
@ -629,6 +721,8 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
String templateId = object.getStr("TemplateId");//模板id
String SubscribeStatusString = object.getStr("SubscribeStatusString");
if (StringUtils.isNotEmpty(SubscribeStatusString) && SubscribeStatusString.equals("accept")) {
String mapKey= RedisConstant.SUB_SEND_CACHE+accountUserBindConnect.getUser_id();
redisTemplate.opsForHash().increment(RedisConstant.SUB_SEND_CACHE,mapKey, 1);
accountUserBindConnect.setBind_tmpl(templateId);
getUpdateWrapper(updateWrapper, accountUserBindConnect);
} else {
@ -643,6 +737,8 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
}
}
/**
* 封装相同参数的调用方法
*
@ -656,6 +752,7 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl<AccountUs
updateWrapper.eq("bind_type", accountUserBindConnect.getBind_type());
updateWrapper.eq("user_id", accountUserBindConnect.getUser_id());
updateWrapper.eq("user_type", accountUserBindConnect.getUser_type());
updateWrapper.set("send_number",accountUserBindConnect.getSend_number());
}
}

View File

@ -23,6 +23,7 @@ import com.suisung.mall.common.feignService.PayService;
import com.suisung.mall.common.feignService.ShopService;
import com.suisung.mall.common.modules.account.*;
import com.suisung.mall.common.modules.distribution.ShopDistributionPlantformUser;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import com.suisung.mall.common.modules.user.ShopUserExpHistory;
import com.suisung.mall.common.utils.CSVUtils;
import com.suisung.mall.common.utils.CheckUtil;
@ -155,7 +156,7 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
}
@Override
public boolean checkUpdateUserLevel(Integer user_id, BigDecimal user_exp_total, Integer user_fans_total, BigDecimal user_spend_total, Integer user_store_total, Integer user_fans_vip_total, Integer user_fans_team_total) {
public boolean checkUpdateUserLevel(Integer user_id, BigDecimal user_exp_total, Integer user_fans_total, BigDecimal user_spend_total, Integer user_store_total, Integer user_fans_vip_total, Integer user_fans_team_total,Integer store_id,BigDecimal user_store_spend_total) {
AccountBaseUserLevel level_row = null;
if (CheckUtil.isNotEmpty(user_exp_total)) {
@ -213,6 +214,30 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
throw new ApiException(ResultCode.FAILED);
}
}
if(level_row != null && user_store_spend_total!=null){//店铺消费
//查找会员再更新店铺会员等级 todo
ShopStoreMemberLevel params = new ShopStoreMemberLevel();
params.setUserId(user_id);
params.setStoreId(store_id);
List<ShopStoreMemberLevel> shopStoreMemberLevels= shopService.findShopStoreMemberLevelList(params);
if(shopStoreMemberLevels!=null && !shopStoreMemberLevels.isEmpty()){
ShopStoreMemberLevel updateShopStoreMemberLevel= shopStoreMemberLevels.get(0);
BigDecimal storeSpend=NumberUtil.add(updateShopStoreMemberLevel.getUserLevelSpend(),user_store_spend_total);//店铺会员总消费
QueryWrapper<AccountBaseUserLevel> levelQueryWrapper = new QueryWrapper<>();
levelQueryWrapper.le("user_level_spend", storeSpend)
.gt("user_level_spend", 0).orderByDesc("user_level_spend");
level_row = accountBaseUserLevelService.findOne(levelQueryWrapper);
updateShopStoreMemberLevel.setUserLevelSpend(storeSpend);
if(level_row != null && CheckUtil.isNotEmpty(level_row.getUser_level_id())){
Integer user_level_id = level_row.getUser_level_id();
String user_level_name = level_row.getUser_level_name();
updateShopStoreMemberLevel.setUserLevelId(user_level_id);
updateShopStoreMemberLevel.setUserLevelName(user_level_name);
}
shopService.saveShopStoreMemberLevel(updateShopStoreMemberLevel);
}
}
return true;
}
@ -422,7 +447,7 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
}
}
if (!checkUpdateUserLevel(user_id, BigDecimal.ZERO, user_fans, BigDecimal.ZERO, 0, 0, 0)) {
if (!checkUpdateUserLevel(user_id, BigDecimal.ZERO, user_fans, BigDecimal.ZERO, 0, 0, 0,null,null)) {
throw new ApiException(ResultCode.FAILED);
}
@ -431,8 +456,11 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
@Override
public List<Map> getUser(List<Integer> user_ids) {
List<AccountUserBase> user_base_rows = accountUserBaseService.gets(user_ids);
List<Map> user_info_rows = Convert.toList(Map.class, gets(user_ids));
QueryWrapper<AccountUserBase> queryWrapper = new QueryWrapper<>();
queryWrapper.in("user_id", user_ids);
List<AccountUserBase> user_base_rows = accountUserBaseService.list(queryWrapper);
//List<AccountUserBase> user_base_rows = accountUserBaseService.gets(user_ids);
List<Map> user_info_rows = Convert.toList(Map.class, user_base_rows);
for (Map user_info_row : user_info_rows) {
Integer user_id = (Integer) user_info_row.get("user_id");

View File

@ -110,6 +110,12 @@ public class CommonConstant {
//秒杀活动订阅消息模板id
public static final String BIND_SUB_TMPL_SKILL = "kiDj_hSF_ASwD-Dlgxnypi6IJBQZ12a-hEpd3zZ-Uxc";
//平台首页
public static final String INDEX_PLAFT_PAGE = "pages/index/index";
//店铺首页
public static final String INDEX_STORE_PAGE = "pagesub/index/store";
//分账计算方式1-按总金额2-按可分账金额
public static final int SeparateCalcMode_TotalAmt = 1;
public static final int SeparateCalcMode_CanSeparateAmt = 2;

View File

@ -49,4 +49,8 @@ public class RedisConstant {
// 拉卡拉合同是否强制签署
public static final String LKL_EC_REPEAT_SIGN = "lkl:ec:repeat:sign:";
// 微信同意记录
public static final String SUB_SEND_CACHE = "sub:send:cache";
}

View File

@ -314,6 +314,15 @@ public interface AccountService {
@GetMapping(value = "/admin/account/accountController/getAllBindCount")
long getAllBindCount(@RequestParam(name = "bindTmpl") String bindTmpl);
/**
* 批量更新保存accountUserBindConnect
*
* @return
*/
@PostMapping(value = "/admin/account/accountController/updateBatchAccountUserBindConnect")
ThirdApiRes updateBatchAccountUserBindConnect(@RequestBody List<AccountUserBindConnect> accountUserBindConnectList);
/**
* 检查手机注册的商家是否存在(仅供内部调用)

View File

@ -53,7 +53,7 @@ public class AccountBaseUserLevel implements Serializable {
private Integer user_level_fans_team;
@ApiModelProperty(value = "累计消费")
private Integer user_level_spend;
private BigDecimal user_level_spend;
@ApiModelProperty(value = "升级产品SPU编号(DOT)")
private String user_level_product_id;

View File

@ -108,4 +108,7 @@ public class AccountUserBindConnect implements Serializable {
@ApiModelProperty(value = "允许通知的消息通知模板id")
private String bind_tmpl;
@ApiModelProperty(value = "剩余订阅次数")
private Integer send_number;
}

View File

@ -139,4 +139,13 @@ public class ShopStoreActivityBase implements Serializable {
@TableField(updateStrategy = NOT_EMPTY)
private String lucky_turn;
@ApiModelProperty(value = "每人限购,0为不限购")
private Integer person_limit;
@ApiModelProperty(value = "每单限购,0为不限购")
private Integer order_limit;
@ApiModelProperty(value = "是否店铺新用户专享1是0否")
private String is_new_person_shop;
}

View File

@ -1,15 +1,14 @@
package com.suisung.mall.common.modules.store;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.io.Serializable;
import java.util.Date;
@Data
@ -17,38 +16,47 @@ import java.util.Date;
@Accessors(chain = true)
@TableName("shop_store_member")
@ApiModel(value = "ShopStoreMember", description = "店铺会员表")
public class ShopStoreMember {
@TableId(value = "store_member_id", type = IdType.AUTO)
public class ShopStoreMember implements Serializable {
@TableId(value ="store_member_id", type = IdType.AUTO)
@ApiModelProperty(value = "店铺会员ID", example = "10001")
private Integer storeMemberId;
private Long store_member_id;
@ApiModelProperty(value = "用户ID", example = "20001")
@TableField(value = "user_id")
private Integer userId;
@ApiModelProperty(value = "店铺ID", example = "30001")
@TableField(value = "store_id")
private Integer storeId;
@ApiModelProperty(value = "用户名")
@TableField(value = "user_account")
private String userAccount;
@ApiModelProperty(value = "用户昵称")
@TableField(value = "user_nickname")
private String userNickname;
@ApiModelProperty(value = "店铺名称", example = "旗舰店")
@TableField(value = "store_name")
private String storeName;
@ApiModelProperty(value = "首次消费时间")
private Date firstPurchaseTime;
@ApiModelProperty(value = "累计消费金额", example = "1500.00")
private BigDecimal totalConsumption;
@ApiModelProperty(value = "最近消费时间")
private Date lastPurchaseTime;
@ApiModelProperty(value = "会员等级ID", example = "2")
private Integer memberLevelId;
@ApiModelProperty(value = "等级名称", example = "铂金会员")
private String memberLevelName;
@ApiModelProperty(value = "创建时间")
private Date createdAt;
@TableField(value = "create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updatedAt;
@TableField(value = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ApiModelProperty(value = "访问Open编号")
private String bind_openid;
@ApiModelProperty(value = "剩余订阅次数")
private Integer send_number;
@TableField(exist = false)
private ShopStoreMemberLevel shopStoreMemberLevel;
}

View File

@ -1,14 +1,14 @@
package com.suisung.mall.common.modules.store;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@ -17,26 +17,74 @@ import java.util.Date;
@Accessors(chain = true)
@TableName("shop_store_member_level")
@ApiModel(value = "ShopStoreMemberLevel", description = "店铺会员等级表")
public class ShopStoreMemberLevel {
@TableId(value = "user_level_id", type = IdType.AUTO)
public class ShopStoreMemberLevel implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "store_member_level_id", type = IdType.AUTO)
@ApiModelProperty(value = "主表id", example = "1")
private Integer store_member_level_id;
@ApiModelProperty(value = "等级编号", example = "1")
@TableField(value = "user_level_id")
private Integer userLevelId;
@ApiModelProperty(value = "等级名称", example = "黄金会员")
@TableField(value = "user_level_name")
private String userLevelName;
@ApiModelProperty(value = "累计消费额度", example = "1000.00")
@TableField(value = "user_level_spend")
private BigDecimal userLevelSpend;
@ApiModelProperty(value = "首次消费时间")
@TableField(value = "first_purchase_time",updateStrategy = FieldStrategy.NOT_EMPTY)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date firstPurchaseTime;
@ApiModelProperty(value = "积分")
@TableField(value = "create_time",updateStrategy = FieldStrategy.NOT_EMPTY)
private Integer store_points;
@ApiModelProperty(value = "最近消费时间")
@TableField(value = "last_purchase_time",updateStrategy = FieldStrategy.NOT_EMPTY)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastPurchaseTime;
@ApiModelProperty(value = "会员等级ID", example = "2")
@TableField(value = "member_level_id",updateStrategy = FieldStrategy.NOT_EMPTY)
private Integer memberLevelId;
@ApiModelProperty(value = "等级名称", example = "铂金会员")
@TableField(value = "member_level_name")
private String memberLevelName;
@ApiModelProperty(value = "折扣率百分比", example = "95.00")
@TableField(value = "user_level_rate")
private BigDecimal userLevelRate;
@ApiModelProperty(value = "等级修改时间")
@TableField(value = "user_level_time")
private Date userLevelTime;
@ApiModelProperty(value = "创建时间")
private Date createdAt;
@TableField(value = "create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty(value = "更新时间")
private Date updatedAt;
@TableField(value = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ApiModelProperty(value = "店铺id")
@TableField(value = "store_id",updateStrategy = FieldStrategy.NOT_EMPTY)
private Integer storeId;
@TableField(value = "store_member_id")
@ApiModelProperty(value = "店铺会员ID")
private Long storeMemberId;
@ApiModelProperty(value = "用户ID", example = "20001")
@TableField(value = "user_id")
private Integer userId;
}

View File

@ -0,0 +1,50 @@
package com.suisung.mall.common.modules.store;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("shop_store_points_account")
@ApiModel(value = "ShopStorePointsAccount", description = "会员表-积分账户表")
public class ShopStorePointsAccount implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户ID")
@TableId(value = "user_id", type = IdType.AUTO)
private String user_id;
@ApiModelProperty(value = "店铺会员id", required = true)
@TableField("store_member_id")
private Integer storeMemberId;
@ApiModelProperty(value = "累计获得积分")
@TableField("total_points")
private Integer totalPoints;
@ApiModelProperty(value = "可用积分")
@TableField("available_points")
private Integer availablePoints;
@ApiModelProperty(value = "冻结积分")
@TableField("frozen_points")
private Integer frozenPoints;
@ApiModelProperty(value = "已过期积分")
@TableField("expired_points")
private Integer expiredPoints;
@ApiModelProperty(value = "最后更新时间", required = true)
@TableField(value = "last_update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdateTime;
}

View File

@ -0,0 +1,78 @@
package com.suisung.mall.common.modules.store;
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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("shop_store_points_rule")
@ApiModel(value = "ShopStorePointsRuleDTO对象", description = "会员表-积分规则表")
public class ShopStorePointsRule implements Serializable {
@ApiModelProperty(value = "规则ID")
@TableId(value = "rule_id", type = IdType.INPUT)
private String rule_id;
@ApiModelProperty(value = "规则名称", required = true)
@TableField("rule_name")
private String ruleName;
@ApiModelProperty(value = "规则类型1-获取规则 2-过期规则", required = true)
@TableField("rule_type")
private Integer ruleType;
@ApiModelProperty(value = "获取积分数值或比例")
@TableField("points_value")
private Integer pointsValue;
@ApiModelProperty(value = "过期天数(0表示永久有效)")
@TableField("expiry_days")
private Integer expiryDays;
@ApiModelProperty(value = "状态1-启用 0-禁用")
@TableField("status")
private Integer status;
@ApiModelProperty(value = "开始时间")
@TableField("start_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
@ApiModelProperty(value = "结束时间")
@TableField("end_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
@ApiModelProperty(value = "新建时间")
@TableField("create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty(value = "更新时间")
@TableField("update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@ApiModelProperty(value = "店铺编号", required = true)
@TableField("store_id")
private Long storeId;
@ApiModelProperty(value = "预警通知0是表示没有预警")
@TableField("warning_day")
private Integer warningDay;
@ApiModelProperty(value = "备注")
@TableField("remark")
private String remark;
}

View File

@ -0,0 +1,69 @@
package com.suisung.mall.common.modules.store;
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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("shop_store_points_transaction")
@ApiModel(value = "ShopStorePointsTransactionDTO对象", description = "会员表-积分流水表")
public class ShopStorePointsTransaction implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "流水ID")
@TableId(value = "transaction_id", type = IdType.AUTO)
private String transaction_id;
@ApiModelProperty(value = "用户编号", required = true)
@TableField("user_id")
private Integer userId;
@ApiModelProperty(value = "店铺会员id", required = true)
@TableField("store_member_id")
private String storeMemberId;
@ApiModelProperty(value = "正数为获得,负数为消耗", required = true)
@TableField("points")
private Integer points;
@ApiModelProperty(value = "交易后余额", required = true)
@TableField("balance_after")
private Integer balanceAfter;
@ApiModelProperty(value = "交易类型1-获取 2-消费 3-过期 4-调整", required = true)
@TableField("transaction_type")
private Integer transactionType;
@ApiModelProperty(value = "流水时间")
@TableField("transaction_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date transactionTime;
@ApiModelProperty(value = "过期日期")
@TableField("expiry_date")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date expiryDate;
@ApiModelProperty(value = "来源ID(订单ID等)")
@TableField("source_id")
private String sourceId;
@ApiModelProperty(value = "来源描述")
@TableField("source_desc")
private String sourceDesc;
@ApiModelProperty(value = "备注")
@TableField("remark")
private String remark;
}

View File

@ -45,4 +45,7 @@ public class WxUserInfoReq implements Serializable {
private String country;
@ApiModelProperty("头像")
private String avatarUrl;
@ApiModelProperty("店铺id")
private String storeId;
}

View File

@ -32,4 +32,7 @@ public class UserLevelTO implements Serializable {
private Integer user_fans_team_total;
private Integer store_id;
private BigDecimal user_store_spend_total;
}

View File

@ -65,8 +65,8 @@ public class DistanceCalculatorUtils {
// 使用示例
public static void main(String[] args) {
// 示例北京(39.9042, 116.4074)到上海(31.2304, 121.4737)
double lat1 = 23.212212;
double lon1 = 110.23232332;
double lat1 = 23.37144181211829;
double lon1 = 110.07554742288707;
double lat2 = 23.332099038755167;
double lon2 = 110.08853179682197;

View File

@ -19,7 +19,8 @@ public class XcxSubSendMessageJob extends QuartzJobBean {
Logger logger = LoggerFactory.getLogger(XcxSubSendMessageJob.class);
logger.info("小程序订阅号消息发送消息开始--------start");
ShopMessageTemplateService shopMessageTemplateService = SpringUtil.getBean(ShopMessageTemplateService.class);
shopMessageTemplateService.sendToXcxAllUserMessage();
shopMessageTemplateService.sendToXcxAllUserMessage();//平台店铺消息推送
shopMessageTemplateService.sendToXcxShopMemberUserMessage();//店铺消息订阅发送
logger.info("小程序订阅号消息发送消息结束-------end");
}

View File

@ -47,4 +47,6 @@ public interface ShopMessageTemplateService extends IBaseService<ShopMessageTemp
CommonResult sendToXcxUserMessage(Integer user_id);
void sendToXcxAllUserMessage();
void sendToXcxShopMemberUserMessage();
}

View File

@ -27,6 +27,7 @@ import com.suisung.mall.common.modules.account.AccountUserBindConnect;
import com.suisung.mall.common.modules.account.AccountUserLogin;
import com.suisung.mall.common.modules.message.ShopMessageTemplate;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.modules.wechat.ShopWechatTplmsg;
import com.suisung.mall.common.pojo.dto.ErrorTypeEnum;
import com.suisung.mall.common.pojo.dto.SmsDto;
@ -45,10 +46,12 @@ import com.suisung.mall.shop.message.vo.WxTelMsgPushVo;
import com.suisung.mall.shop.message.vo.WxXcxMsgPushVo;
import com.suisung.mall.shop.sixun.utils.CommonUtil;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import com.suisung.mall.shop.store.service.ShopStoreMemberService;
import com.suisung.mall.shop.wechat.service.ShopWechatTplmsgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
@ -99,6 +102,10 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
@Autowired
private Environment environment;
@Lazy
@Autowired
private ShopStoreMemberService shopStoreMemberService;
public String dealMessageTemplate(String message_content, Map args) {
StringSubstitutor sub = new StringSubstitutor(args);
@ -708,7 +715,7 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
if (wechatTplmsg != null) {
Map timeArgs = getActiveTime();
args.putAll(timeArgs);
String wechatTplData = getXcxWechatTplData(open_id, wechatTplmsg, args);
String wechatTplData = getXcxWechatTplData(open_id, CommonConstant.INDEX_PLAFT_PAGE,CommonConstant.BIND_SUB_TMPL_SKILL, args);
log.info(wechatTplData);
String result = WxHttpUtil.request(WxHttpUtil.MethodType.POST, WxHttpUtil.WxType.XCX, accessToken, url, null, wechatTplData);
JSONObject resultJson = JSONUtil.parseObj(result);
@ -746,14 +753,14 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
}
String accessToken = accountService.getXcxAccessToken(true);
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
QueryWrapper<ShopWechatTplmsg> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("tplmsg_id", 1022);//todo 后期改为动态
ShopWechatTplmsg wechatTplmsg = shopWechatTplmsgService.getOne(queryWrapper);
ShopStoreBase shopStoreBase = shopStoreBaseService.get(wechatTplmsg.getStore_id());
// QueryWrapper<ShopWechatTplmsg> queryWrapper = new QueryWrapper<>();
// queryWrapper.eq("tplmsg_id", 1022);//todo 后期改为动态
// ShopWechatTplmsg wechatTplmsg = shopWechatTplmsgService.getOne(queryWrapper);
// ShopStoreBase shopStoreBase = shopStoreBaseService.get(wechatTplmsg.getStore_id());
Map args = new HashMap();
String[] activeProfiles = environment.getActiveProfiles();
String activeProfile = activeProfiles[0];
args.put("storeName", shopStoreBase.getStore_name());
args.put("storeName", "小发同城线上购物");
args.put("evn", activeProfile);
Map timeArgs = getActiveTime();
args.putAll(timeArgs);
@ -767,19 +774,90 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
.collect(Collectors.toList());
int finalI = i;
futures.add(executor.submit(() -> {
List<AccountUserBindConnect> updateAccountUserBindConnect=new ArrayList<>();
finalList.forEach(accountUserBindConnect -> {
String open_id = accountUserBindConnect.getBind_openid();
if (StrUtil.isNotEmpty(open_id)) {
String wechatTplData = getXcxWechatTplData(open_id, wechatTplmsg, args);
String wechatTplData = getXcxWechatTplData(open_id, CommonConstant.INDEX_PLAFT_PAGE,CommonConstant.BIND_SUB_TMPL_SKILL, args);
String result = WxHttpUtil.request(WxHttpUtil.MethodType.POST, WxHttpUtil.WxType.XCX, accessToken, url, null, wechatTplData);
JSONObject resultJson = JSONUtil.parseObj(result);
Integer errcode = Convert.toInt(resultJson.get("errcode"));
String errmsg = Convert.toStr(resultJson.get("errmsg"));
if (errcode != 0) {
log.error("微信公众号推送失败,失败原因:{}", errmsg);
}else {
accountUserBindConnect.setSend_number(accountUserBindConnect.getSend_number()-1);
updateAccountUserBindConnect.add(accountUserBindConnect);
}
}
});
if(!updateAccountUserBindConnect.isEmpty()){
accountService.updateBatchAccountUserBindConnect(updateAccountUserBindConnect);
}
return "完成推送批次:" + finalI;
}));
}
// 等待所有任务完成
for (Future<?> future : futures) {
try {
log.info("推送任务结果: {}", future.get());
} catch (Exception e) {
log.info("推送任务执行异常: {}", e.getMessage());
}
}
executor.shutdown();
}
@Override
public void sendToXcxShopMemberUserMessage() {
QueryWrapper<ShopStoreMember> shopStoreMemberQueryWrapper = new QueryWrapper<>();
shopStoreMemberQueryWrapper.gt("send_number", 0);
long sendCount = shopStoreMemberService.count(shopStoreMemberQueryWrapper);
if (sendCount == 0) {
return;
}
String accessToken = accountService.getXcxAccessToken(true);
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
Map args = new HashMap();
String[] activeProfiles = environment.getActiveProfiles();
String activeProfile = activeProfiles[0];
args.put("evn", activeProfile);
Map timeArgs = getActiveTime();
args.putAll(timeArgs);
int total = (int) sendCount;
Integer pages = CommonUtil.getPagesCount(total, BATCH_SIZE);
ExecutorService executor = Executors.newFixedThreadPool(6);
List<Future<?>> futures = new ArrayList<>();
for (int i = 1; i <= pages; i++) {
List<ShopStoreMember> shopStoreMembers = shopStoreMemberService.findSendPage(shopStoreMemberQueryWrapper,i,BATCH_SIZE);
// List<AccountUserBindConnect> finalList = accountService.getAllBindPage(CommonConstant.BIND_SUB_TMPL_SKILL, i, BATCH_SIZE)
// .stream().filter(com.suisung.mall.common.utils.CommonUtil.distinctByKey(AccountUserBindConnect::getBind_openid))
// .collect(Collectors.toList());
int finalI = i;
futures.add(executor.submit(() -> {
List<ShopStoreMember> updateShopStoreMembers = new ArrayList<>();
shopStoreMembers.forEach(shopStoreMember -> {
String open_id = shopStoreMember.getBind_openid();
if (StrUtil.isNotEmpty(open_id)) {
args.put("storeName", shopStoreMember.getStoreName());
String wechatTplData = getXcxWechatTplData(open_id, CommonConstant.INDEX_STORE_PAGE+"?store_id="+shopStoreMember.getStoreId(),CommonConstant.BIND_SUB_TMPL_SKILL, args);
String result = WxHttpUtil.request(WxHttpUtil.MethodType.POST, WxHttpUtil.WxType.XCX, accessToken, url, null, wechatTplData);
JSONObject resultJson = JSONUtil.parseObj(result);
Integer errcode = Convert.toInt(resultJson.get("errcode"));
String errmsg = Convert.toStr(resultJson.get("errmsg"));
if (errcode != 0) {
log.error("微信公众号推送失败,失败原因:{}", errmsg);
}else {
shopStoreMember.setSend_number(shopStoreMember.getSend_number()-1);
updateShopStoreMembers.add(shopStoreMember);
}
}
});
if(!updateShopStoreMembers.isEmpty()){
shopStoreMemberService.updateBatchById(updateShopStoreMembers,updateShopStoreMembers.size());
}
return "完成推送批次:" + finalI;
}));
}
@ -799,18 +877,20 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
* 获取微信小程序模板数据
*
* @param open_id
* @param wechatTplmsg
* @param pageUrl
* @param template_id
* @param args
* @return
*/
public String getXcxWechatTplData(String open_id, ShopWechatTplmsg wechatTplmsg, Map args) {
public String getXcxWechatTplData(String open_id, String pageUrl,String template_id, Map args) {
WxXcxMsgPushVo wxXcxMsgPushVo = new WxXcxMsgPushVo();
wxXcxMsgPushVo.setTouser(open_id);
wxXcxMsgPushVo.setTemplate_id(wechatTplmsg.getTplmsg_tpl_id());
wxXcxMsgPushVo.setPage(wechatTplmsg.getLink_url());
wxXcxMsgPushVo.setTemplate_id(template_id);
wxXcxMsgPushVo.setPage(pageUrl);
String evn = Convert.toStr(args.get("evn"));
String storeName = Convert.toStr(args.get("storeName"));
String miniprogram_state = "trial";//默认为体验版
if (evn.equals("prod")) {
miniprogram_state = "formal";

View File

@ -21,6 +21,7 @@ import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.constant.ConfigConstant;
import com.suisung.mall.common.constant.MqConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.enums.DicEnum;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.exception.ApiUserException;
import com.suisung.mall.common.feignService.AccountService;
@ -395,6 +396,13 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
@Value("${sf-express.enable}")
private Integer enable_sf_express;
@Autowired
private ShopStoreActivityItemService shopStoreActivityItemService ;
@Lazy
@Autowired
private ShopStoreMemberLevelService shopStoreMemberLevelService;
@Override
public List<Map<String, Object>> statisticState() {
UserDto user = getCurrentUser();
@ -1356,29 +1364,30 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
throw new ApiException(I18nUtil._("请选择你的收货地址!"));
}
Integer chainId = getParameter("chain_id", 0);
Boolean ifChain = Convert.toBool(getParameter("if_chain"), false);
Integer checkedStore = getParameter("checked_store", 0);
Integer ifCart = getParameter("ifcart", 0);
// 购物车商品列表
List<Map> cartItemRows = new ArrayList();
if (ifCart > 0) {
// 从购物车走
QueryWrapper<ShopUserCart> cartQueryWrapper = new QueryWrapper<>();
cartQueryWrapper.eq("chain_id", chainId).eq("user_id", userId).eq("cart_select", 1).gt("cart_quantity", 0);
if (checkedStore > 0) {
// 权限判断
cartQueryWrapper.eq("store_id", checkedStore);
}
// 购物车数据
Map cartResultData = shopUserCartService.getLists(cartQueryWrapper);
cartItemRows = (List<Map>) cartResultData.get("items");
}
//lyj start 20251226 todo 是不是多此一举
// Integer chainId = getParameter("chain_id", 0);
// Boolean ifChain = Convert.toBool(getParameter("if_chain"), false);
// Integer checkedStore = getParameter("checked_store", 0);
//
// Integer ifCart = getParameter("ifcart", 0);
// // 购物车商品列表
// List<Map> cartItemRows = new ArrayList();
// if (ifCart > 0) {
// // 从购物车走
// QueryWrapper<ShopUserCart> cartQueryWrapper = new QueryWrapper<>();
// cartQueryWrapper.eq("chain_id", chainId).eq("user_id", userId).eq("cart_select", 1).gt("cart_quantity", 0);
// if (checkedStore > 0) {
// // 权限判断
// cartQueryWrapper.eq("store_id", checkedStore);
// }
//
// // 购物车数据
// Map cartResultData = shopUserCartService.getListDivideActivity(cartQueryWrapper,null,null);
// cartItemRows = (List<Map>) cartResultData.get("items");
// }
//lyj start 20251226 todo 是不是多此一举
// 重要方法
return doQuickAddOrder(userId, cartItemRows, udId, true, "", StateCode.ORDER_TYPE_DD, null);
return doQuickAddOrder(userId, new ArrayList(), udId, true, "", StateCode.ORDER_TYPE_DD, null);
}
@ -1462,7 +1471,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
cartQueryWrapper.eq("store_id", checkedStore);
}
cartData = shopUserCartService.getLists(cartQueryWrapper, 1, 500);
cartData = shopUserCartService.getListDivideActivity(cartQueryWrapper, 1, 500);
} else {
String itemInfo = getParameter("cart_id");
List<String> itemInfoRow = new ArrayList();
@ -1487,15 +1496,44 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
cartRows.add(cartRow);
ShopProductItem productRow = shopProductItemService.get(itemId);
//新增活动限购逻辑 lyj 20251227 start 将活动商品分开处理方便进入shop_order_item
Map<Long,ShopStoreActivityBase> shopStoreActivityBaseMap=checkActivity(itemId,productRow.getStore_id(),userId);
Integer finalCartQuantity=cartQuantity;
if(null!=shopStoreActivityBaseMap){
ShopStoreActivityBase shopStoreActivityBase= shopStoreActivityBaseMap.get(itemId);
Integer orderLimit= shopStoreActivityBase.getOrder_limit();
if(orderLimit>0 && shopStoreActivityBase.getActivity_type_id()==StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT){
Integer noDiscount= cartQuantity-orderLimit;
if(noDiscount>0){//购物车购买的商品数量大于最大活动限购数量则需要分开需要分开
finalCartQuantity=noDiscount;
HashMap cartRowDiscount = new HashMap();
cartRowDiscount.put("user_id", userId);
cartRowDiscount.put("store_id", productRow.getStore_id());
cartRowDiscount.put("item_id", itemId);
cartRowDiscount.put("cart_quantity", orderLimit);
cartRowDiscount.put("single_activity", shopUserCartService.ifSingleActivity());
cartRowDiscount.put("cart_select", 1);
cartRowDiscount.put("cart_type", 1);
cartRowDiscount.put("activity_id", shopStoreActivityBase.getActivity_id());
cartRowDiscount.put("cart_file", getParameter("cart_file"));
cartRowDiscount.put("pfgb_id", pfgbId);
cartRows.add(cartRowDiscount);
}else {
activityId=shopStoreActivityBase.getActivity_id();
}
}else {
activityId=shopStoreActivityBase.getActivity_id();
}
}
//新增活动限购逻辑 lyj 20251227 end
if (ifChain) {
cartRow.put("chain_id", chainId);
}
cartRow.put("user_id", userId);
Integer storeId = productRow.getStore_id();
cartRow.put("store_id", storeId);
cartRow.put("item_id", itemId);
cartRow.put("cart_quantity", cartQuantity);
cartRow.put("cart_quantity", finalCartQuantity);
cartRow.put("single_activity", shopUserCartService.ifSingleActivity());
cartRow.put("cart_select", 1);
cartRow.put("cart_type", 1);
@ -3372,7 +3410,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
// 检测升级
AccountUserAnalytics analytics = accountService.getUserAnalytics(user_id);
if (analytics != null) {
UserLevelTO userLevelTO = new UserLevelTO(user_id, BigDecimal.ZERO, 0, analytics.getUser_spend(), 0, 0, 0);
UserLevelTO userLevelTO = new UserLevelTO(user_id, BigDecimal.ZERO, 0, analytics.getUser_spend(), 0, 0, 0,store_id,order_payment_amount);
mqMessageVos.add(new MqMessageVo(MqConstant.ACCOUNT_EXCHANGE, MqConstant.ACCOUNT_UPGRADE_ROUTING_KEY, JSONUtil.parseObj(userLevelTO)));
// todo do_action("init_order_paid", order_base_rows, order_item_rows);
}
@ -6170,6 +6208,11 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
Integer buyer_user_id = Convert.toInt(cart_data.get("buyer_user_id"));
AccountUserInfo user_info_row = accountService.getUserInfo(buyer_user_id);
QueryWrapper<ShopStoreMemberLevel> shopStoreMemberLevelQueryWrapper=new QueryWrapper<>();
shopStoreMemberLevelQueryWrapper.eq("user_id",buyer_user_id);
shopStoreMemberLevelQueryWrapper.eq("store_id", Convert.toInt(cart_data.get("store_id")));
ShopStoreMemberLevel shopStoreMemberLevel= shopStoreMemberLevelService.getOne(shopStoreMemberLevelQueryWrapper);
if (user_info_row == null) {
throw new ApiException(I18nUtil._("该用户信息不存在!"));
}
@ -7749,12 +7792,12 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
List<ShopStoreActivityBase> point_activity_rows = shopStoreActivityBaseService.find(baseQueryWrapper);
if (CollUtil.isNotEmpty(point_activity_rows)) {
Integer user_level_id= Optional.ofNullable(shopStoreMemberLevel).map(
ShopStoreMemberLevel::getUserLevelId).orElse(1001);
for (int i = 0; i < point_activity_rows.size(); i++) {
ShopStoreActivityBase shopStoreActivityBase = point_activity_rows.get(i);
List<Integer> activity_use_level = Convert.toList(Integer.class, shopStoreActivityBase.getActivity_use_level());
Integer user_level_id = user_info_row.getUser_level_id();
//Integer user_level_id = user_info_row.getUser_level_id();
if (CollectionUtil.isEmpty(activity_use_level) || activity_use_level.contains(user_level_id)) {
JSONObject activity_rule = JSONUtil.parseObj(shopStoreActivityBase.getActivity_rule());
List<Map> rule = ObjectUtil.defaultIfNull((List<Map>) activity_rule.get("rule"), new ArrayList<>());
@ -9506,6 +9549,79 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
return false;
}
}
/**
* 校验限购
* @param itemId
* @return
*/
private Map<Long,ShopStoreActivityBase> checkActivity(Long itemId,Integer storeId,Integer user_id){
QueryWrapper<ShopStoreActivityItem> queryWrapper = new QueryWrapper();
queryWrapper.eq("store_id",storeId);
queryWrapper.eq("item_id",itemId);
queryWrapper.eq("activity_item_state",StateCode.ACTIVITY_STATE_NORMAL);
List<ShopStoreActivityItem> shopStoreActivityItems=shopStoreActivityItemService.list(queryWrapper);
if(shopStoreActivityItems.isEmpty()){
return null;
}
Integer activity_id=shopStoreActivityItems.get(0).getActivity_id();
QueryWrapper<ShopStoreActivityBase> shopStoreActivityBaseQueryWrapper=new QueryWrapper<>();
shopStoreActivityBaseQueryWrapper.eq("activity_id", shopStoreActivityItems.get(0).getActivity_id());
List<ShopStoreActivityBase> shopStoreActivityBases= shopStoreActivityBaseService.list(shopStoreActivityBaseQueryWrapper);
if(shopStoreActivityBases.isEmpty()){
logger.info("活动不存在");
return null;
}
ShopStoreActivityBase shopStoreActivityBase=shopStoreActivityBases.get(0);
if(shopStoreActivityBase.getActivity_type_id()==StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT){//限时折扣才有这种规则
String is_new_person_shop=shopStoreActivityBase.getIs_new_person_shop();
if(DicEnum.YESORNO_1.getCode().equals(is_new_person_shop)){
Integer store_id=shopStoreActivityBase.getStore_id();
boolean isNewUser=checkoutNewPerson(user_id,store_id);
if(!isNewUser){//不能参加活动
return null;
}else {
Integer person_limit=shopStoreActivityBase.getPerson_limit();//每人限购 每单限购不能大于每人限购
QueryWrapper<ShopOrderItem> shopOrderItemQueryWrapper=new QueryWrapper<>();
shopOrderItemQueryWrapper.eq("activity_id", activity_id);
shopOrderItemQueryWrapper.eq("item_id", itemId);
List<ShopOrderItem> shopOrderItemList= shopOrderItemService.list(shopOrderItemQueryWrapper);//计算用户购买的商品
Integer person_limit_count=shopOrderItemList.stream().mapToInt(ShopOrderItem::getOrder_item_quantity).sum();
if(person_limit_count >= person_limit){//不能参加活动
return null;
}
}
}else {//如果不是新人活动要考虑每人限购问题就是每人参加活动的次数 todo 按店铺会员等级
Integer person_limit=shopStoreActivityBase.getPerson_limit();//每人限购 每单限购不能大于每人限购
QueryWrapper<ShopOrderItem> shopOrderItemQueryWrapper=new QueryWrapper<>();
shopOrderItemQueryWrapper.eq("activity_id", activity_id);
shopOrderItemQueryWrapper.eq("item_id", itemId);
List<ShopOrderItem> shopOrderItemList= shopOrderItemService.list(shopOrderItemQueryWrapper);//计算用户购买的商品
Integer person_limit_count=shopOrderItemList.stream().mapToInt(ShopOrderItem::getOrder_item_quantity).sum();
if(person_limit_count >= person_limit){//不能参加活动
return null;
}
}
}
Map<Long,ShopStoreActivityBase> stringShopOrderBaseMap=new HashMap<>();
stringShopOrderBaseMap.put(itemId,shopStoreActivityBase);
return stringShopOrderBaseMap;
}
/**
* 检查是否为新用户
* @param user_id
*/
private boolean checkoutNewPerson(Integer user_id,Integer store_id){
boolean isNewUser=false;
QueryWrapper<ShopStoreMemberLevel> shopStoreMemberLevelQueryWrapper=new QueryWrapper();
shopStoreMemberLevelQueryWrapper.eq("user_id",user_id);
shopStoreMemberLevelQueryWrapper.eq("store_id",store_id);
shopStoreMemberLevelQueryWrapper.eq("user_level_spend",new BigDecimal("0.00"));
long count=shopStoreMemberLevelService.count(shopStoreMemberLevelQueryWrapper);
if(count>0){
isNewUser=true;
}
return isNewUser;
}
}

View File

@ -0,0 +1,101 @@
package com.suisung.mall.shop.store.controller.admin;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.shop.store.service.ShopStoreMemberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 页面导航表 前端控制器
* </p>
*
* @author lyj
* @since 2025-12-22
*/
@Api(tags = "页面导航表-店铺会员")
@RestController
@RequestMapping("/admin/shop/shop-store-member")
public class ShopStoreMemberController extends BaseControllerImpl {
@Autowired
private ShopStoreMemberService shopStoreMemberService;
/**
* 分页列表查询
* @param
* @param pageNum
* @param pageSize
* @return
*/
@ApiOperation(value = "列表查询-分页列表查询店铺会员", notes = "列表查询-分页列表查询店铺会员")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Page<ShopStoreMember> list(@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
ShopStoreMember shopStoreMember=new ShopStoreMember();
String userId=getParameter("userId");
if(StringUtils.isNotEmpty(userId)){
shopStoreMember.setUserId(Convert.toInt(userId));
}
return shopStoreMemberService.findPage(shopStoreMember,pageNum,pageSize);
}
/**
* 单笔获取
* @param shopStoreMember
* @return
*/
@ApiOperation(value = "单笔获取-店铺会员", notes = "单笔获取-店铺会员")
@RequestMapping(value = "/getShopStoreMember", method = RequestMethod.GET)
public CommonResult getShopStoreMember(@RequestBody ShopStoreMember shopStoreMember) {
return CommonResult.success(shopStoreMemberService.getShopStoreMemberById(shopStoreMember.getStore_member_id()));
}
/**
* 新增
* @param shopStoreMember
* @return
*/
@ApiOperation(value = "新增修改-店铺会员", notes = "新增修改-店铺会员")
@RequestMapping(value = "/saveShopStoreMember", method = RequestMethod.POST)
public ShopStoreMember saveShopStoreMember(@RequestBody @Valid ShopStoreMember shopStoreMember) {
shopStoreMemberService.saveOrUpdate(shopStoreMember);
return shopStoreMember;
}
/**
* 查找
* @param shopStoreMember
* @return
*/
@ApiOperation(value = "新增修改-根据店铺和用户查找店铺会员", notes = "新增修改-根据店铺和用户查找店铺会员--微服务调用")
@RequestMapping(value = "/findShopStoreMemberList", method = RequestMethod.POST)
public List<ShopStoreMember> findShopStoreMemberList(@RequestBody ShopStoreMember shopStoreMember) {
return shopStoreMemberService.findShopStoreMemberList(shopStoreMember);
}
/**
* 导出会员数据
* @param
* @return
*/
@ApiOperation(value = "导出数据店铺会员", notes = "列表查询-导出数据店铺会员")
@RequestMapping(value = "/exportShopStoreMember", method = RequestMethod.GET)
public void exportShopStoreMember(HttpServletResponse response) {
shopStoreMemberService.exportShopStoreMember(response);
}
}

View File

@ -0,0 +1,90 @@
package com.suisung.mall.shop.store.controller.admin;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.shop.store.service.ShopStoreMemberLevelService;
import com.suisung.mall.shop.store.service.ShopStoreMemberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 页面导航表 前端控制器
* </p>
*
* @author lyj
* @since 2025-12-22
*/
@Api(tags = "页面导航表-店铺会员")
@RestController
@RequestMapping("/admin/shop/shop-store-member-lever")
public class ShopStoreMemberLevelController extends BaseControllerImpl {
@Autowired
private ShopStoreMemberLevelService shopStoreMemberLevelService;
/**
* 分页列表查询
* @param
* @param pageNum
* @param pageSize
* @return
*/
@ApiOperation(value = "列表查询-分页列表查询店铺会员", notes = "列表查询-分页列表查询店铺会员")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Page<ShopStoreMemberLevel> list(@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
ShopStoreMemberLevel shopStoreMemberLevel=new ShopStoreMemberLevel();
String userLevelName=getParameter("userLevelName");
if(StringUtils.isNotEmpty(userLevelName)){
shopStoreMemberLevel.setUserLevelName(userLevelName);
}
return shopStoreMemberLevelService.findPage(shopStoreMemberLevel,pageNum,pageSize);
}
/**
* 单笔获取
* @param shopStoreMemberLevel
* @return
*/
@ApiOperation(value = "单笔获取-店铺会员", notes = "单笔获取-店铺会员")
@RequestMapping(value = "/getShopStoreMemberLevel", method = RequestMethod.GET)
public CommonResult getShopStoreMemberLevel(@RequestBody ShopStoreMemberLevel shopStoreMemberLevel) {
return CommonResult.success(shopStoreMemberLevelService.getById(shopStoreMemberLevel.getStore_member_level_id()));
}
/**
* 新增
* @param shopStoreMemberLevel
* @return
*/
@ApiOperation(value = "新增修改-店铺会员", notes = "新增修改-店铺会员")
@RequestMapping(value = "/saveShopStoreMemberLevel", method = RequestMethod.POST)
public CommonResult saveShopStoreMemberLevel(@RequestBody @Valid ShopStoreMemberLevel shopStoreMemberLevel) {
return CommonResult.success(shopStoreMemberLevelService.saveOrUpdate(shopStoreMemberLevel));
}
/**
* 根据userId查找
* @param shopStoreMemberLevel
* @return
*/
@ApiOperation(value = "新增修改-根据userId查找", notes = "新增修改-根据userId查找")
@RequestMapping(value = "/findShopStoreMemberLevelList", method = RequestMethod.POST)
public List<ShopStoreMemberLevel> findShopStoreMemberLevelList(@RequestBody ShopStoreMemberLevel shopStoreMemberLevel) {
return shopStoreMemberLevelService.findShopStoreMemberLevelList(shopStoreMemberLevel);
}
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import org.springframework.stereotype.Component;
@Component
public interface ShopStoreMemberLevelMapper extends BaseMapper<ShopStoreMemberLevel> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import org.springframework.stereotype.Repository;
@Repository
public interface ShopStoreMemberMapper extends BaseMapper<ShopStoreMember> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStorePointsAccount;
import org.springframework.stereotype.Component;
@Component
public interface ShopStorePointsAccountMapper extends BaseMapper<ShopStorePointsAccount> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStorePointsRule;
import org.springframework.stereotype.Component;
@Component
public interface ShopStorePointsRuleMapper extends BaseMapper<ShopStorePointsRule> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.store.ShopStorePointsTransaction;
import org.springframework.stereotype.Component;
@Component
public interface ShopStorePointsTransactionMapper extends BaseMapper<ShopStorePointsTransaction> {
}

View File

@ -0,0 +1,14 @@
package com.suisung.mall.shop.store.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import java.util.List;
public interface ShopStoreMemberLevelService extends IService<ShopStoreMemberLevel> {
Page<ShopStoreMemberLevel> findPage(ShopStoreMemberLevel shopStoreMemberLevel, Integer pageNo, Integer pageSize);
List<ShopStoreMemberLevel> findShopStoreMemberLevelList(ShopStoreMemberLevel shopStoreMemberLevel);
}

View File

@ -0,0 +1,22 @@
package com.suisung.mall.shop.store.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface ShopStoreMemberService extends IService<ShopStoreMember> {
Page<ShopStoreMember> findPage(ShopStoreMember shopStoreMember, Integer pageNo, Integer pageSize);
List<ShopStoreMember> findShopStoreMemberList(ShopStoreMember shopStoreMember);
void exportShopStoreMember(HttpServletResponse response);
List<ShopStoreMember> findSendPage(QueryWrapper<ShopStoreMember> queryWrapper, Integer pageNo, Integer pageSize);
ShopStoreMember getShopStoreMemberById(Long id);
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suisung.mall.common.modules.store.ShopStorePointsAccount;
public interface ShopStorePointsAccountService extends IService<ShopStorePointsAccount> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suisung.mall.common.modules.store.ShopStorePointsRule;
public interface ShopStorePointsRuleService extends IService<ShopStorePointsRule> {
}

View File

@ -0,0 +1,9 @@
package com.suisung.mall.shop.store.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suisung.mall.common.modules.store.ShopStorePointsTransaction;
public interface ShopStorePointsTransactionService extends IService<ShopStorePointsTransaction> {
}

View File

@ -21,6 +21,7 @@ import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.api.StateCode;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.enums.DicEnum;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.exception.ApiUserException;
import com.suisung.mall.common.feignService.AccountService;
@ -37,6 +38,7 @@ import com.suisung.mall.common.modules.product.ShopProductItem;
import com.suisung.mall.common.modules.store.ShopStoreActivityBase;
import com.suisung.mall.common.modules.store.ShopStoreActivityItem;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.utils.*;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.activity.service.*;
@ -53,10 +55,7 @@ import com.suisung.mall.shop.product.service.ShopProductImageService;
import com.suisung.mall.shop.product.service.ShopProductIndexService;
import com.suisung.mall.shop.product.service.ShopProductItemService;
import com.suisung.mall.shop.store.mapper.ShopStoreActivityBaseMapper;
import com.suisung.mall.shop.store.service.ShopStoreActivityBaseService;
import com.suisung.mall.shop.store.service.ShopStoreActivityCodeService;
import com.suisung.mall.shop.store.service.ShopStoreActivityItemService;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import com.suisung.mall.shop.store.service.*;
import com.suisung.mall.shop.user.service.ShopUserVoucherService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -146,6 +145,9 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
@Autowired
private ShopBaseActivityTypeService shopBaseActivityTypeService;
@Autowired
private ShopStoreMemberService shopStoreMemberService;
/**
* 返回随机金额数组 分为单位
*
@ -327,7 +329,6 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
//等级要求
if (!levelMap.isEmpty()) {
List<Integer> activity_use_level = Convert.toList(Integer.class, baseMap.get("activity_use_level"));
if (CollectionUtil.isNotEmpty(activity_use_level)) {
List<String> levelName = new ArrayList<>();
for (Integer use_id : activity_use_level) {
@ -530,10 +531,25 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
activity_info.put(store_id, activity_row_List);
}
} else {
String is_new_person_shop = Convert.toStr(activity_row.get("is_new_person_shop"));//新用户配置配置了新用户就不能配等级
Integer store_id = Convert.toInt(activity_row.get("store_id"));
List<Map> activity_row_List = (List<Map>) ObjectUtil.defaultIfNull(activity_info.get(store_id), new ArrayList<>());
activity_row_List.add(activity_row);
activity_info.put(store_id, activity_row_List);
if(DicEnum.YESORNO_1.getCode().equals(is_new_person_shop)){//新用户
if(null!=user){
QueryWrapper<ShopStoreMember> shopStoreMemberQueryWrapper = new QueryWrapper<>();
shopStoreMemberQueryWrapper.eq("store_id", store_id);
shopStoreMemberQueryWrapper.eq("user_id", user.getId());
long count= shopStoreMemberService.count(shopStoreMemberQueryWrapper);//店铺会员
if(count==0){//平台等级为空证明没有买过
List<Map> activity_row_List = (List<Map>) ObjectUtil.defaultIfNull(activity_info.get(store_id), new ArrayList<>());
activity_row_List.add(activity_row);
activity_info.put(store_id, activity_row_List);
}
}
}else {
List<Map> activity_row_List = (List<Map>) ObjectUtil.defaultIfNull(activity_info.get(store_id), new ArrayList<>());
activity_row_List.add(activity_row);
activity_info.put(store_id, activity_row_List);
}
}
}
}
@ -688,7 +704,8 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
discount_item_row.put(item_id, price);
}
// discount_money
int order_limit_count=0;//当前活动限购
Integer order_limit= Convert.toInt(activity_row.get("order_limit"));//每单限购
for (Map item : items) {
// 并且类型为 限时折扣
Boolean cart_select = Convert.toBool(item.get("cart_select"));
@ -696,19 +713,54 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
BigDecimal price = (BigDecimal) discount_item_row.get(item_id);
if (CheckUtil.isNotEmpty(price) && cart_select) {
Integer shopCartActivityId= Convert.toInt(item.get("activity_id"));
if(shopCartActivityId==0){
continue;
}
BigDecimal item_sale_price = Convert.toBigDecimal(item.get("item_sale_price"));
BigDecimal item_discount_amount = Convert.toBigDecimal(item.get("item_discount_amount"));
BigDecimal cart_quantity = Convert.toBigDecimal(item.get("cart_quantity"));
if (ObjectUtil.isNotNull(price) && cart_select) {
item.put("show_typename", shopBaseStateCodeService.getText(StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT, null));
BigDecimal discount_sale_money = NumberUtil.sub(item_sale_price, NumberUtil.min(price, item_sale_price));
BigDecimal final_item_sale_price=NumberUtil.min(price, item_sale_price);//最后的单价就是活动价格
BigDecimal discount_sale_money = NumberUtil.sub(item_sale_price, final_item_sale_price);//单个商品优惠价格
BigDecimal _item_discount_amount=BigDecimal.ZERO;
Integer noDiscountQuantity=cart_quantity.intValue();
//每人限购逻辑
if(order_limit > 0 ){//每单限购逻辑
if(order_limit_count<order_limit){//没有超限购还有优惠
BigDecimal orin_sale_amount=NumberUtil.mul(cart_quantity, item_sale_price);//原商品总价
noDiscountQuantity= cart_quantity.intValue()-order_limit;
if(noDiscountQuantity>=0){//部分优惠
BigDecimal disCountSaleTotal=NumberUtil.mul(final_item_sale_price, order_limit);//折扣总价
BigDecimal oringSaleTotal=NumberUtil.mul(item_sale_price, noDiscountQuantity);//原价计算
BigDecimal discount_sale_amount=NumberUtil.add(disCountSaleTotal,oringSaleTotal);//优惠之后的价格
_item_discount_amount = NumberUtil.add(item_discount_amount, NumberUtil.sub(orin_sale_amount,discount_sale_amount));//小计优惠总价
order_limit_count+=order_limit;
}else {//所有都优惠
_item_discount_amount = NumberUtil.add(item_discount_amount, NumberUtil.mul(discount_sale_money, cart_quantity));
order_limit_count+=cart_quantity.intValue();
}
}else{//超出限购无优惠
final_item_sale_price=item_sale_price;
discount_sale_money=BigDecimal.ZERO;
}
}else {
_item_discount_amount = NumberUtil.add(item_discount_amount, NumberUtil.mul(discount_sale_money, cart_quantity));
}
item.put("discount_sale_money", discount_sale_money);
item.put("item_sale_price", NumberUtil.min(price, item_sale_price));
BigDecimal _item_discount_amount = NumberUtil.add(item_discount_amount, NumberUtil.mul(discount_sale_money, cart_quantity));
item.put("item_sale_price", final_item_sale_price);
item.put("item_discount_amount", _item_discount_amount.floatValue());
item.put("pulse_discount", activity_row);
item.put("activity_discount_amount", _item_discount_amount);
// todo new add
item.put("item_not_discount_quantity", noDiscountQuantity);//无优惠数量
item.put("item_discount_quantity", cart_quantity.intValue()-noDiscountQuantity);//优惠数量
item.put("item_activity_price", price);//活动价格
}
}
}
@ -5550,6 +5602,17 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
activity_rule.put("voucher_quantity_use", 0);
activity_rule.put("activity_intro", activity_intro);
} else if (ObjectUtil.equal(activity_type_id, StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT)) {
String person_limit = getParameter("person_limit","0");//每人限购 每个人可以参加多少次这个活动
String order_limit = getParameter("order_limit","0");//每单限购 这个活动可以选多少个商品
Integer personLimit=Convert.toInt(person_limit);
Integer orderLimit=Convert.toInt(order_limit);
if(orderLimit>personLimit){
throw new ApiException("每单限购不能超过每人限购数量");
}
String is_new_person_shop = getParameter("is_new_person_shop","0");//是否店铺新用户专享1是0否
// 限时折扣
Map requirement = new HashMap();
Map buy = new HashMap();
@ -5558,6 +5621,9 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
buy.put("subtotal", subtotal);
buy.put("buy", buy);
data.put("requirement", requirement);
data.put("person_limit",personLimit);
data.put("order_limit",orderLimit);
data.put("is_new_person_shop",is_new_person_shop);
} else if (ObjectUtil.equal(activity_type_id, StateCode.ACTIVITY_TYPE_MARKETING)) {
//市场活动
String start_join_time = getParameter("start_join_time");

View File

@ -71,6 +71,7 @@ public class ShopStoreActivityItemServiceImpl extends BaseServiceImpl<ShopStoreA
baseQueryWrapper.in("activity_id", activity_ids);
List<ShopStoreActivityBase> activityBaseList = shopStoreActivityBaseService.find(baseQueryWrapper);
if (CollUtil.isNotEmpty(activityBaseList)) {
//todo 加入限购逻辑
activityBases = shopStoreActivityBaseService.fixActivityData(activityBaseList);
}
}

View File

@ -0,0 +1,60 @@
package com.suisung.mall.shop.store.service.impl;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import com.suisung.mall.common.utils.ContextUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStoreMemberLevelMapper;
import com.suisung.mall.shop.store.service.ShopStoreMemberLevelService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 店铺会员-会员等级
* </p>
*/
@Transactional
@Service
public class ShopStoreMemberLevelServiceImpl extends BaseServiceImpl<ShopStoreMemberLevelMapper, ShopStoreMemberLevel> implements ShopStoreMemberLevelService {
@Override
public Page<ShopStoreMemberLevel> findPage(ShopStoreMemberLevel shopStoreMemberLevel, Integer pageNo, Integer pageSize) {
QueryWrapper<ShopStoreMemberLevel> queryWrapper = new QueryWrapper<>();
UserDto userDto= ContextUtil.getCurrentUser();
assert userDto != null;
queryWrapper.eq("store_id", Convert.toInt(userDto.getStore_id()));
queryWrapper.orderByDesc("id");
if(shopStoreMemberLevel.getUserLevelName()!=null){
queryWrapper.like("user_id", shopStoreMemberLevel.getUserLevelName());
}
//return this.getBaseMapper().selectPage(new Page<>(pageNo, pageSize), queryWrapper);
return this.lists(queryWrapper, pageNo, pageSize);
}
@Override
public List<ShopStoreMemberLevel> findShopStoreMemberLevelList(ShopStoreMemberLevel shopStoreMemberLevel) {
QueryWrapper<ShopStoreMemberLevel> queryWrapper = new QueryWrapper<>();
if(shopStoreMemberLevel.getStoreId()!=null){
queryWrapper.eq("store_id",shopStoreMemberLevel.getStoreId());
}
if(shopStoreMemberLevel.getMemberLevelId()!=null){
queryWrapper.eq("store_member_id",shopStoreMemberLevel.getStoreMemberId());
}
if(shopStoreMemberLevel.getUserId()!=null){
queryWrapper.eq("user_id",shopStoreMemberLevel.getUserId());
}
return this.list(queryWrapper);
}
}

View File

@ -0,0 +1,120 @@
package com.suisung.mall.shop.store.service.impl;
import cn.hutool.core.convert.Convert;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.modules.store.*;
import com.suisung.mall.common.utils.ContextUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStoreMemberMapper;
import com.suisung.mall.shop.store.service.ShopStoreMemberLevelService;
import com.suisung.mall.shop.store.service.ShopStoreMemberService;
import com.suisung.mall.shop.sync.excleHandle.ExportStyleHandler;
import com.suisung.mall.shop.sync.exelModel.ShopStoreMemberExcel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 店铺会员-店铺会员
* </p>
*/
@Transactional
@Service
public class ShopStoreMemberServiceImpl extends BaseServiceImpl<ShopStoreMemberMapper, ShopStoreMember> implements ShopStoreMemberService {
@Autowired
private ShopStoreMemberLevelService shopStoreMemberLevelService;
@Override
public Page<ShopStoreMember> findPage(ShopStoreMember shopStoreMember, Integer pageNo, Integer pageSize) {
QueryWrapper<ShopStoreMember> queryWrapper = new QueryWrapper<>();
UserDto userDto= ContextUtil.getCurrentUser();
assert userDto != null;
if(userDto.getRole_id()!=2){
throw new ApiException("无权限");
}
queryWrapper.eq("store_id", Convert.toInt(userDto.getStore_id()));
if(shopStoreMember.getUserId()!=null){
queryWrapper.eq("user_id", shopStoreMember.getUserId());
}
return this.lists(queryWrapper, pageNo, pageSize);
}
@Override
public List<ShopStoreMember> findShopStoreMemberList(ShopStoreMember shopStoreMember) {
QueryWrapper<ShopStoreMember> queryWrapper = new QueryWrapper<>();
if(shopStoreMember.getUserId()!=null){
queryWrapper.eq("user_id",shopStoreMember.getUserId());
}
if(shopStoreMember.getStoreId()!=null){
queryWrapper.eq("store_id", shopStoreMember.getStoreId());
}
return this.list(queryWrapper);
}
@Override
public void exportShopStoreMember(HttpServletResponse response) {
// 设置响应头
setExcelResponseHeader(response, "店铺会员数据.xlsx");
try {
String storeId= ContextUtil.getCurrentUser().getStore_id();
QueryWrapper<ShopStoreMember> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", Convert.toInt(storeId));
List<ShopStoreMember> shopStoreMemberList= this.list(queryWrapper);
List<ShopStoreMemberExcel> exportShopStoreMemberList=shopStoreMemberList.stream().map(ShopStoreMemberExcel::fromEntity).collect(Collectors.toList());
EasyExcel.write(response.getOutputStream(), ShopStoreMemberExcel.class)
.sheet("店铺会员数据")
.registerWriteHandler(new ExportStyleHandler())
.doWrite(exportShopStoreMemberList);
} catch (IOException e) {
throw new ApiException("导出店铺会员数据失败:"+e.getMessage());
}
}
@Override
public List<ShopStoreMember> findSendPage(QueryWrapper<ShopStoreMember> queryWrapper, Integer pageNo, Integer pageSize) {
return this.lists(queryWrapper,pageNo,pageSize).getRecords();
}
@Override
public ShopStoreMember getShopStoreMemberById(Long id) {
ShopStoreMember shopStoreMember=this.getById(id);
if(null!=shopStoreMember){
QueryWrapper<ShopStoreMemberLevel> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_member_id", shopStoreMember.getStore_member_id());
ShopStoreMemberLevel shopStoreMemberLevel= shopStoreMemberLevelService.getOne(queryWrapper);
if(shopStoreMemberLevel!=null){
shopStoreMember.setShopStoreMemberLevel(shopStoreMemberLevel);
}
}
return shopStoreMember;
}
// 设置Excel响应头
private void setExcelResponseHeader(HttpServletResponse response, String fileName) {
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("文件名编码失败");
}
}
}

View File

@ -0,0 +1,20 @@
package com.suisung.mall.shop.store.service.impl;
import com.suisung.mall.common.modules.store.ShopStorePointsAccount;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStorePointsAccountMapper;
import com.suisung.mall.shop.store.service.ShopStorePointsAccountService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 店铺会员-积分账户
* </p>
*/
@Transactional
@Service
public class ShopStorePointsAccountServiceImpl extends BaseServiceImpl<ShopStorePointsAccountMapper, ShopStorePointsAccount> implements ShopStorePointsAccountService {
}

View File

@ -0,0 +1,20 @@
package com.suisung.mall.shop.store.service.impl;
import com.suisung.mall.common.modules.store.ShopStorePointsRule;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStorePointsRuleMapper;
import com.suisung.mall.shop.store.service.ShopStorePointsRuleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 店铺会员-积分规则
* </p>
*/
@Transactional
@Service
public class ShopStorePointsRuleServiceImpl extends BaseServiceImpl<ShopStorePointsRuleMapper, ShopStorePointsRule> implements ShopStorePointsRuleService {
}

View File

@ -0,0 +1,18 @@
package com.suisung.mall.shop.store.service.impl;
import com.suisung.mall.common.modules.store.ShopStorePointsTransaction;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStorePointsTransactionMapper;
import com.suisung.mall.shop.store.service.ShopStorePointsTransactionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 店铺会员-积分流水
*/
@Transactional
@Service
public class ShopStorePointsTransactionServiceImpl extends BaseServiceImpl<ShopStorePointsTransactionMapper, ShopStorePointsTransaction> implements ShopStorePointsTransactionService {
}

View File

@ -0,0 +1,38 @@
package com.suisung.mall.shop.sync.exelModel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import lombok.Data;
import java.util.Date;
@Data
public class ShopStoreMemberExcel {
@ExcelProperty(value = "用户ID", index = 0)
private Integer userId;
@ExcelProperty(value = "用户名称/手机号码", index = 1)
private String userAccount;
@ExcelProperty(value = "用户昵称", index = 2)
private String userNickname;
@ExcelProperty(value = "店铺名称", index = 3)
private String storeName;
@ExcelProperty(value = "会员新增时间", index = 4)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
// 从实体对象转换
public static ShopStoreMemberExcel fromEntity(ShopStoreMember entity) {
ShopStoreMemberExcel excel = new ShopStoreMemberExcel();
excel.setUserId(entity.getUserId());
excel.setUserAccount(entity.getUserAccount());
excel.setUserNickname(entity.getUserNickname());
excel.setStoreName(entity.getStoreName());
excel.setCreateTime(entity.getCreateTime());
return excel;
}
}

View File

@ -34,6 +34,8 @@ import com.suisung.mall.common.modules.sixun.SxSyncGoods;
import com.suisung.mall.common.modules.sixun.SxSyncVip;
import com.suisung.mall.common.modules.store.ShopStoreActivityBase;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.store.ShopStoreMember;
import com.suisung.mall.common.modules.store.ShopStoreMemberLevel;
import com.suisung.mall.common.pojo.dto.LibraryProductDTO;
import com.suisung.mall.common.pojo.req.SyncThirdMemberReq;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
@ -55,6 +57,8 @@ import com.suisung.mall.shop.product.service.ShopProductItemService;
import com.suisung.mall.shop.sixun.dto.SxGoosModel;
import com.suisung.mall.shop.store.service.ShopStoreActivityBaseService;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import com.suisung.mall.shop.store.service.ShopStoreMemberLevelService;
import com.suisung.mall.shop.store.service.ShopStoreMemberService;
import org.apache.commons.lang3.math.NumberUtils;
import org.hibernate.validator.internal.util.stereotypes.Lazy;
import org.slf4j.Logger;
@ -65,7 +69,6 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@ -108,6 +111,12 @@ public abstract class SyncBaseThirdSxAbstract{
@Autowired
private RedisService redisService;
@Autowired
private ShopStoreMemberService shopStoreMemberService;
@Autowired
private ShopStoreMemberLevelService shopStoreMemberLevelService;
@Autowired
public static final Set<String> FORBID_CATEGORY= Collections.unmodifiableSet(new HashSet<>(
Arrays.asList("香烟类","香烟","烟类", "","烟草")
@ -610,6 +619,7 @@ public abstract class SyncBaseThirdSxAbstract{
List<AccountUserInfo> addAcountUserInfo=new ArrayList<>();
List<PayUserResource> addPayUserResource=new ArrayList<>();
List<AccountUserLogin> accountUserLogins=new ArrayList<>();
Date today=new Date();
for (int i = 0; i < accountBaseIds.size(); i++) {
// account_user_base
@ -676,7 +686,11 @@ public abstract class SyncBaseThirdSxAbstract{
if(thirdApiRes.getError_code()!=0){
throw new ApiException(ResultCode.FAILED);
}
QueryWrapper<ShopStoreBase> shopStoreBaseQueryWrapper=new QueryWrapper<>();
Integer store_id=Convert.toInt(storeId);
shopStoreBaseQueryWrapper.eq("store_id", storeId);
ShopStoreBase shopStoreBase= shopStoreBaseService.findOne(shopStoreBaseQueryWrapper);
dealShopStoreMember(addAccountUserBases,shopStoreBase.getStore_name(),store_id);
}
if(!addAcountUserInfo.isEmpty()){
ThirdApiRes thirdApiRes= accountService.saveBatchAccountInfo(addAcountUserInfo);
@ -696,6 +710,7 @@ public abstract class SyncBaseThirdSxAbstract{
throw new ApiException(ResultCode.FAILED,"accountUserLogin保存异常");
}
}
//保存完之后将会员导入到新的会员
return count;
}
@ -1233,5 +1248,58 @@ public abstract class SyncBaseThirdSxAbstract{
return shopStoreActivityBaseService.list(query);
}
/**
* 处理店铺会员
* @param accountUserBaseList
*/
private void dealShopStoreMember(List<AccountUserBase> accountUserBaseList,String storeName,Integer storeId){
List<ShopStoreMember> addShopStoreMember=new ArrayList<>();
for(AccountUserBase accountUserBase:accountUserBaseList){
ShopStoreMember shopStoreMember=new ShopStoreMember();
shopStoreMember.setUserId(accountUserBase.getUser_id());
shopStoreMember.setStoreName(storeName);
shopStoreMember.setUserAccount(accountUserBase.getUser_account());
shopStoreMember.setUserNickname(accountUserBase.getUser_nickname());
shopStoreMember.setStoreId(storeId);
addShopStoreMember.add(shopStoreMember);
}
if(!addShopStoreMember.isEmpty()){
shopStoreMemberService.saveBatch(addShopStoreMember,addShopStoreMember.size());
List<Integer> userIds=addShopStoreMember.stream().map(ShopStoreMember::getUserId).collect(Collectors.toList());
QueryWrapper<ShopStoreMember> query = new QueryWrapper<>();
query.eq("store_id",storeId);
query.in("user_id", userIds);
List<ShopStoreMember> shopStoreMemberList =shopStoreMemberService.list(query);
if(!shopStoreMemberList.isEmpty()){
List<ShopStoreMemberLevel> addShopStoreMemberLevels = getShopStoreMemberLevels(storeId, shopStoreMemberList);
if(!addShopStoreMemberLevels.isEmpty()){
shopStoreMemberLevelService.saveBatch(addShopStoreMemberLevels, addShopStoreMemberLevels.size());
}
}
}
}
/**
* 店铺会员初始化信息
* @param storeId
* @param shopStoreMemberList
* @return
*/
private List<ShopStoreMemberLevel> getShopStoreMemberLevels(Integer storeId, List<ShopStoreMember> shopStoreMemberList) {
List<ShopStoreMemberLevel> addShopStoreMemberLevels=new ArrayList<>();
for (ShopStoreMember shopStoreMember: shopStoreMemberList){
ShopStoreMemberLevel addShopStoreMemberLevel=new ShopStoreMemberLevel();
addShopStoreMemberLevel.setStoreId(storeId);
addShopStoreMemberLevel.setStoreMemberId(shopStoreMember.getStore_member_id());
addShopStoreMemberLevel.setUserLevelName("v1");
addShopStoreMemberLevel.setUserLevelId(1001);
addShopStoreMemberLevel.setMemberLevelId(1001);
addShopStoreMemberLevel.setMemberLevelName("v1");
addShopStoreMemberLevel.setUserId(shopStoreMember.getUserId());
addShopStoreMemberLevels.add(addShopStoreMemberLevel);
}
return addShopStoreMemberLevels;
}
}

View File

@ -50,6 +50,14 @@ public interface ShopUserCartService extends IBaseService<ShopUserCart> {
*/
Map getLists(QueryWrapper<ShopUserCart> queryWrapper);
/**
* 读取购物车(不分页,把活动商品剥离出来)
*
* @param queryWrapper
* @return
*/
Map getListDivideActivity(QueryWrapper<ShopUserCart> queryWrapper, Integer page, Integer rows);
/**
* 修改购物车数量
*

View File

@ -16,6 +16,7 @@ import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.api.StateCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.enums.DicEnum;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.exception.ApiUserException;
import com.suisung.mall.common.feignService.AccountService;
@ -26,6 +27,7 @@ import com.suisung.mall.common.modules.chain.ShopChainBase;
import com.suisung.mall.common.modules.chain.ShopChainItem;
import com.suisung.mall.common.modules.invoicing.InvoicingCustomerBase;
import com.suisung.mall.common.modules.invoicing.InvoicingCustomerLevel;
import com.suisung.mall.common.modules.order.ShopOrderItem;
import com.suisung.mall.common.modules.pay.PayPaymentChannel;
import com.suisung.mall.common.modules.product.*;
import com.suisung.mall.common.modules.store.*;
@ -47,6 +49,7 @@ import com.suisung.mall.shop.chain.service.ShopChainItemService;
import com.suisung.mall.shop.invoicing.service.InvoicingCustomerBaseService;
import com.suisung.mall.shop.invoicing.service.InvoicingCustomerLevelService;
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
import com.suisung.mall.shop.order.service.ShopOrderItemService;
import com.suisung.mall.shop.product.pojo.vo.FixOrderVo;
import com.suisung.mall.shop.product.pojo.vo.ProductVo;
import com.suisung.mall.shop.product.service.*;
@ -55,8 +58,10 @@ import com.suisung.mall.shop.user.mapper.ShopUserCartMapper;
import com.suisung.mall.shop.user.service.ShopUserCartService;
import com.suisung.mall.shop.user.service.ShopUserDeliveryAddressService;
import com.suisung.mall.shop.user.service.ShopUserVoucherService;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.util.Pair;
@ -159,10 +164,20 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
private ShopStoreSameCityTransportBaseService shopStoreSameCityTransportBaseService;
@Autowired
@Lazy
private RedisService redisService;
// @Autowired
// private ShopStoreMemberService shopStoreMemberService;
@Autowired
@Lazy
private ShopStoreMemberService shopStoreMemberService;
@Autowired
@Lazy
private ShopStoreMemberLevelService shopStoreMemberLevelService;
@Autowired
@Lazy
private ShopOrderItemService shopOrderItemService;
@Override
@Transactional
@ -420,14 +435,17 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
}
//购物车控制活动的商品数量 todo
// if(null!=activity_id&&0!=activity_id){
// checkActivity(activity_id,user_id);
// }
if(null!=activity_id&&0!=activity_id){
data= checkActivity(activity_id,activity_item_id,user_id,data,item_id);
}else {
data.put("activity_id", activity_id);
data.put("activity_item_id", activity_item_id);
}
data.put("item_id", item_id);
data.put("cart_quantity", cart_quantity >= 0 ? Math.max(1, cart_quantity) : Math.min(-1, cart_quantity)); // 购买商品数量
data.put("cart_type", cart_type);
data.put("activity_id", activity_id);
data.put("activity_item_id", activity_item_id);
// data.put("activity_id", activity_id);
//data.put("activity_item_id", activity_item_id);
data.put("cart_file", cart_file);
data.put("chain_id", chain_id);
data.put("user_id", user_id);
@ -630,7 +648,15 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
// 直接点击购买数据检测
if (StrUtil.isNotBlank(cartId)) {
List<String> itemInfoList = StrUtil.split(cartId, ",");
if(0!=activityId){
Map data=new HashMap();
String itemIdStr= itemInfoList.get(0);
long[] itemData = StrUtil.splitToLong(itemIdStr, "|");
if(itemData[1]>0){
data= checkActivity(activityId,0L,currentUserId,data,itemData[0]);
activityId= Convert.toInt(data.get("activity_id"));
}
}
// 购物车行项目列表
List<Map> directPurchaseItems = new ArrayList();
for (String itemInfo : itemInfoList) {
@ -1267,6 +1293,93 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
return processCartData(cart_rows);
}
/**
* 读取所有购物车列表不分页区分活动
*
* @param queryWrapper 查询条件
* @return
*/
@Override
@Transactional
public Map getListDivideActivity(QueryWrapper<ShopUserCart> queryWrapper, Integer page, Integer rows) {
List<ShopUserCart> cart_rows =null;
if(null!=page&&null!=rows){
Page<ShopUserCart> userCartPage =lists(queryWrapper,page,rows);
cart_rows =userCartPage.getRecords();
}else {
cart_rows = find(queryWrapper);
}
QueryWrapper<ShopStoreActivityBase> shopStoreActivityBaseQueryWrapper=new QueryWrapper<>();
List<Integer> activityIdList=cart_rows.stream().map(ShopUserCart::getActivity_id).filter(activityId -> activityId !=0).collect(Collectors.toList());
if(!activityIdList.isEmpty()){//把折扣的活动分开进入shopItem时就会分开处理
shopStoreActivityBaseQueryWrapper.in("activity_id",activityIdList);
List<ShopStoreActivityBase> shopStoreActivityBases= shopStoreActivityBaseService.list(shopStoreActivityBaseQueryWrapper);
Map<Integer,ShopStoreActivityBase> shopStoreActivityBaseHashMap=new HashMap<>();
shopStoreActivityBases.forEach(shopStoreActivityBase -> {
if(shopStoreActivityBase.getActivity_type_id()==StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT){
shopStoreActivityBaseHashMap.put(shopStoreActivityBase.getActivity_id(),shopStoreActivityBase);
}
});
List<ShopUserCart> newShopUserCartList=new ArrayList<>();
Map<Integer,Integer> activityCountLimitMap=new HashMap<>();
cart_rows.forEach(shopUserCart -> {
if(null!=shopStoreActivityBaseHashMap.get(shopUserCart.getActivity_id())){
ShopStoreActivityBase shopStoreActivityBase=shopStoreActivityBaseHashMap.get(shopUserCart.getActivity_id());
//校验扣减逻辑
Integer orderLimit= shopStoreActivityBase.getOrder_limit();//每单限购
Integer cart_quantity= shopUserCart.getCart_quantity();//购物车数量
Integer activity_id= shopStoreActivityBase.getActivity_id();//活动id
if(orderLimit>0){//限购逻辑处理
if(orderLimit>=cart_quantity){//没有超限购
if(null!=activityCountLimitMap.get(activity_id)){//相同的活动有其他购买可能需要分开
Integer countOrderLimit= activityCountLimitMap.get(activity_id);
int noDiscountLest=orderLimit-countOrderLimit-cart_quantity;
if(noDiscountLest>=0){//没有超出限购直接加入统计不用分开
newShopUserCartList.add(shopUserCart);
activityCountLimitMap.put(activity_id,(countOrderLimit+cart_quantity));
}else {//超出限购需要分开
noDiscountLest= noDiscountLest*(-1);
ShopUserCart newUserCart=new ShopUserCart();
BeanUtils.copyProperties(shopUserCart,newUserCart);//新建一个分开的购物清单
shopUserCart.setCart_quantity(orderLimit);//数量改变旧的活动依旧
newShopUserCartList.add(newUserCart);
newUserCart.setCart_quantity(noDiscountLest);
newUserCart.setActivity_id(0);//新的购物清单无活动
newShopUserCartList.add(shopUserCart);
if(!activityCountLimitMap.containsKey(activity_id)){
activityCountLimitMap.put(activity_id,orderLimit);
}
}
}else {//相同的活动没有其他购买不用分开
newShopUserCartList.add(shopUserCart);
activityCountLimitMap.put(activity_id,cart_quantity);
}
}else {//超出限购范围了直接分开
int noDiscountLest=cart_quantity-orderLimit;
ShopUserCart newUserCart=new ShopUserCart();
BeanUtils.copyProperties(shopUserCart,newUserCart);//新建一个分开的购物清单
shopUserCart.setCart_quantity(orderLimit);//数量改变旧的活动依旧
newShopUserCartList.add(newUserCart);
newUserCart.setCart_quantity(noDiscountLest);
newUserCart.setActivity_id(0);//新的购物清单无活动
newShopUserCartList.add(shopUserCart);
if(!activityCountLimitMap.containsKey(activity_id)){
activityCountLimitMap.put(activity_id,orderLimit);
}
}
}
}else {
newShopUserCartList.add(shopUserCart);
}
});
return processCartData(newShopUserCartList);
}
return processCartData(cart_rows);
}
/**
* 处理购物车数据的公共方法
*
@ -1769,8 +1882,15 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
// 修正价格策略影响
fixPricePolicy(productItemInStore, customerLevelId, userLevelId);
storeInfo.put("policy_discountrate", productItemInStore.get("policy_discountrate"));
storeTotalAmount = NumberUtil.add(Convert.toBigDecimal(productItemInStore.get("subtotal")), storeTotalAmount);
if(productItemInStore.get("item_discount_quantity")!=null&&Convert.toInt(productItemInStore.get("item_discount_quantity"))>0){
BigDecimal item_unit_price=Convert.toBigDecimal(productItemInStore.get("item_unit_price"));
BigDecimal num=BigDecimal.valueOf(Convert.toInt(productItemInStore.get("num")));
BigDecimal oldSubTotal=NumberUtil.mul(item_unit_price, num);//原总价
BigDecimal subTotal=NumberUtil.sub(oldSubTotal,Convert.toBigDecimal(productItemInStore.get("item_discount_amount")));//最终价格=原总价-总优惠价
storeTotalAmount = NumberUtil.add(subTotal, storeTotalAmount);
}else {
storeTotalAmount = NumberUtil.add(Convert.toBigDecimal(productItemInStore.get("subtotal")), storeTotalAmount);
}
storeOriginalAmount = storeOriginalAmount.add(itemUnitPrice.multiply(Convert.toBigDecimal(cartQuantity)));
storePointsAmount = NumberUtil.add(Convert.toBigDecimal(productItemInStore.get("points_subtotal")), storePointsAmount);
@ -3171,6 +3291,111 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
logger.debug("店铺ID为{},实体商品订单,收取打包费{}元", storeId, packingFee);
return packingFee;
}
/**
* 校验限购
* @param activity_id
* @return
*/
private Map checkActivity(Integer activity_id,Long activity_item_id,Integer user_id,Map data,Long item_id){
QueryWrapper<ShopStoreActivityBase> shopStoreActivityBaseQueryWrapper=new QueryWrapper<>();
shopStoreActivityBaseQueryWrapper.eq("activity_id", activity_id);
List<ShopStoreActivityBase> shopStoreActivityBases= shopStoreActivityBaseService.list(shopStoreActivityBaseQueryWrapper);
if(shopStoreActivityBases.isEmpty()){
throw new ApiException("活动不存在");
}
ShopStoreActivityBase shopStoreActivityBase=shopStoreActivityBases.get(0);
//店铺会员等级店铺会员才能参加
boolean canTakePart=checkStoreMemberLever(user_id,shopStoreActivityBase);
if(!canTakePart){//不能参加活动
data.put("activity_id",0);
data.put("activity_item_id",0);
return data;
}
if(shopStoreActivityBase.getActivity_type_id()==StateCode.ACTIVITY_TYPE_LIMITED_DISCOUNT){//限时折扣才有这种规则
String is_new_person_shop=shopStoreActivityBase.getIs_new_person_shop();
if(DicEnum.YESORNO_1.getCode().equals(is_new_person_shop)){
Integer store_id=shopStoreActivityBase.getStore_id();
boolean isNewUser=checkoutNewPerson(user_id,store_id);
if(!isNewUser){//不能参加活动
data.put("activity_id",0);
data.put("activity_item_id",0);
return data;
// throw new ApiException("店铺新人才能购买");
}
// else {
// Integer person_limit=shopStoreActivityBase.getPerson_limit();//每人限购 每单限购不能大于每人限购
// QueryWrapper<ShopOrderItem> shopOrderItemQueryWrapper=new QueryWrapper<>();
// shopOrderItemQueryWrapper.eq("activity_id", activity_id);
// List<ShopOrderItem> shopOrderItemList= shopOrderItemService.list(shopOrderItemQueryWrapper);//计算用户购买的商品
// Integer person_limit_count=shopOrderItemList.stream().mapToInt(ShopOrderItem::getOrder_item_quantity).sum();
// if(person_limit_count >= person_limit){//不能参加活动
// data.put("activity_id",0);
// data.put("activity_item_id",0);
// return data;
// }
// }
}else {//如果不是新人活动要考虑每人限购问题就是每人参加活动的次数 todo 按店铺会员等级
Integer person_limit=shopStoreActivityBase.getPerson_limit();//每人限购 每单限购不能大于每人限购
QueryWrapper<ShopOrderItem> shopOrderItemQueryWrapper=new QueryWrapper<>();
shopOrderItemQueryWrapper.eq("activity_id", activity_id);
shopOrderItemQueryWrapper.eq("item_id", item_id);
List<ShopOrderItem> shopOrderItemList= shopOrderItemService.list(shopOrderItemQueryWrapper);//计算用户购买的商品
Integer person_limit_count=shopOrderItemList.stream().mapToInt(ShopOrderItem::getOrder_item_quantity).sum();
if(person_limit_count >= person_limit){//不能参加活动
data.put("activity_id",0);
data.put("activity_item_id",0);
return data;
}
}
}
data.put("activity_id",activity_id);
data.put("activity_item_id",activity_item_id);
// Integer person_limit= shopStoreActivityBase.getPerson_limit();
// Integer order_limit=shopStoreActivityBase.getOrder_limit();
// data.put("person_limit",person_limit);
// data.put("order_limit",order_limit);
return data;
}
/**
* 检查是否为新用户
* @param user_id
*/
private boolean checkoutNewPerson(Integer user_id,Integer store_id){
boolean isNewUser=false;
QueryWrapper<ShopStoreMemberLevel> shopStoreMemberLevelQueryWrapper=new QueryWrapper();
shopStoreMemberLevelQueryWrapper.eq("user_id",user_id);
shopStoreMemberLevelQueryWrapper.eq("store_id",store_id);
shopStoreMemberLevelQueryWrapper.eq("",new BigDecimal("0.00"));
long count=shopStoreMemberLevelService.count(shopStoreMemberLevelQueryWrapper);
if(count>0){
isNewUser=true;
}
return isNewUser;
}
/**
* 检查等级是否可以参加
* @param user_id
*/
public boolean checkStoreMemberLever(Integer user_id,ShopStoreActivityBase shopStoreActivityBase){
String activity_use_levels = shopStoreActivityBase.getActivity_use_level();
if(StringUtils.isNotEmpty(activity_use_levels)) {
QueryWrapper<ShopStoreMemberLevel> shopStoreMemberLevelQueryWrapper = new QueryWrapper<>();
shopStoreMemberLevelQueryWrapper.eq("user_id", user_id);
shopStoreMemberLevelQueryWrapper.eq("store_id", shopStoreActivityBase.getStore_id());
List<ShopStoreMemberLevel> shopStoreMemberLevelList = shopStoreMemberLevelService.list(shopStoreMemberLevelQueryWrapper);
if (!shopStoreMemberLevelList.isEmpty()) {
ShopStoreMemberLevel shopStoreMember = shopStoreMemberLevelList.get(0);
Integer userLeveId = shopStoreMember.getUserLevelId();
List<Integer> activity_use_level = Convert.toList(Integer.class, activity_use_levels);
if(!activity_use_level.contains(userLeveId)){
return false;
}
}
}
return true;
}
}

View File

@ -1,83 +1,85 @@
CREATE TABLE `shop_store_member_level` (
`store_member_level_id` int unsigned NOT NULL COMMENT '主表id',
`user_level_id` int NOT NULL AUTO_INCREMENT COMMENT '等级编号',
`user_level_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '等级名称',
`user_level_spend` decimal(6,2) NOT NULL DEFAULT '0.00' COMMENT '累计消费',
`user_level_rate` decimal(6,2) NOT NULL DEFAULT '0.00' COMMENT '折扣率百分比',
`first_purchase_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '首次消费时间(成为店铺会员的时间)',
`store_points` int NOT NULL DEFAULT '0' COMMENT '积分',
`last_purchase_time` datetime DEFAULT NULL COMMENT '最近消费时间',
`member_level_id` int unsigned NOT NULL DEFAULT '0' COMMENT '店铺会员等级id',
`member_level_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '等级名称',
`user_level_rate` decimal(6,2) NOT NULL DEFAULT '100.00' COMMENT '折扣率百分比',
`user_level_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`user_level_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员等级表-店铺';
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`store_id` int unsigned NOT NULL COMMENT '店铺编号',
`store_member_id` int unsigned NOT NULL COMMENT '店铺会员id',
PRIMARY KEY (`store_member_level_id`) USING BTREE,
KEY `index_user_level_id` (`user_level_id`) USING BTREE,
KEY `index_user_level_name` (`user_level_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员等级表-店铺';
alter table shop_store_member_level add column `user_id` int unsigned NOT NULL COMMENT '用户编号';
CREATE TABLE `shop_store_member` (
`store_member_id` int NOT NULL AUTO_INCREMENT COMMENT '店铺会员id',
`user_id` int unsigned NOT NULL COMMENT '用户编号',
`store_id` int unsigned NOT NULL COMMENT '店铺编号',
`store_name` varchar(50) NOT NULL COMMENT '店铺名称',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`user_account` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户名',
`user_nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT ' 用户昵称',
`send_number` int unsigned NOT NULL DEFAULT '0' COMMENT '剩余订阅次数',
`bind_openid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '访问Open编号',
PRIMARY KEY (`store_member_id`),
UNIQUE KEY `unique_user_store` (`user_id`,`store_id`),
KEY `index_store_id` (`store_id`) USING BTREE,
KEY `index_store_name` (`store_name`) USING BTREE,
KEY `index_user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员表-店铺';
CREATE TABLE shop_store_member (
store_member_id int PRIMARY KEY AUTO_INCREMENT COMMENT '店铺会员id',
user_id int unsigned NOT NULL COMMENT '用户编号',
store_id int unsigned NOT NULL COMMENT '店铺编号',
store_name varchar(50) NOT NULL COMMENT '店铺名称',
first_purchase_time DATETIME NOT NULL COMMENT '首次消费时间(成为店铺会员的时间)',
total_consumption DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '在该店铺累计消费金额默认0',
store_points int NOT NULL DEFAULT 0.00 COMMENT '积分',
last_purchase_time DATETIME default null COMMENT '最近消费时间',
member_level_id int unsigned NOT NULL DEFAULT 0 COMMENT '店铺会员等级id',
member_level_name varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '等级名称',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
UNIQUE KEY unique_user_store (store_member_id, store_id),
KEY `index_store_id` (`store_id`) USING BTREE,
KEY `index_store_name` (`store_name`) USING BTREE,
KEY `index_user_id` (`user_id`) USING BTREE
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-店铺';
CREATE TABLE shop_store_points_account (
user_id VARCHAR(32) PRIMARY KEY,
store_member_id int NOT NULL COMMENT '店铺会员id',
total_points INT DEFAULT 0 COMMENT '累计获得积分',
available_points INT DEFAULT 0 COMMENT '可用积分',
frozen_points INT DEFAULT 0 COMMENT '冻结积分',
expired_points INT DEFAULT 0 COMMENT '已过期积分',
last_update_time DATETIME NOT NULL COMMENT '最后更新时间',
FOREIGN KEY (store_member_id) REFERENCES shop_store_member(store_member_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分账户表';
CREATE TABLE shop_store_points_transaction (
transaction_id VARCHAR(32) PRIMARY KEY,
user_id int NOT NULL COMMENT '用户编号',
store_member_id VARCHAR(32) NOT NULL COMMENT '店铺会员id',
points INT NOT NULL COMMENT '正数为获得,负数为消耗',
balance_after INT NOT NULL COMMENT '交易后余额',
transaction_type TINYINT NOT NULL COMMENT '1-获取 2-消费 3-过期 4-调整',
transaction_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '流水时间',
expiry_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '过期日期',
source_id VARCHAR(32) NOT NULL DEFAULT '' COMMENT '来源ID(订单ID等)',
source_desc VARCHAR(100) NOT NULL DEFAULT '' COMMENT '来源描述',
remark VARCHAR(200) COMMENT '备注',
INDEX idx_account (user_id),
INDEX idx_expiry (expiry_date),
INDEX idx_transaction_time (transaction_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分流水表';
-- 积分账户表
CREATE TABLE points_account (
user_id VARCHAR(32) PRIMARY KEY,
store_member_id VARCHAR(32) NOT NULL,
total_points INT DEFAULT 0 COMMENT '累计获得积分',
available_points INT DEFAULT 0 COMMENT '可用积分',
frozen_points INT DEFAULT 0 COMMENT '冻结积分',
expired_points INT DEFAULT 0 COMMENT '已过期积分',
last_update_time DATETIME NOT NULL,
FOREIGN KEY (member_id) REFERENCES members(member_id),
INDEX idx_member (member_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 积分流水表
CREATE TABLE points_transaction (
transaction_id VARCHAR(32) PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
store_member_id VARCHAR(32) NOT NULL,
points INT NOT NULL COMMENT '正数为获得,负数为消耗',
balance_after INT NOT NULL COMMENT '交易后余额',
transaction_type TINYINT NOT NULL COMMENT '1-获取 2-消费 3-过期 4-调整',
transaction_time DATETIME NOT NULL,
expiry_date DATE COMMENT '过期日期',
source_id VARCHAR(32) COMMENT '来源ID(订单ID等)',
source_desc VARCHAR(100) COMMENT '来源描述',
remark VARCHAR(200),
FOREIGN KEY (account_id) REFERENCES points_account(account_id),
FOREIGN KEY (member_id) REFERENCES members(member_id),
INDEX idx_member (member_id),
INDEX idx_account (account_id),
INDEX idx_expiry (expiry_date),
INDEX idx_transaction_time (transaction_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 积分规则表
CREATE TABLE points_rule (
rule_id VARCHAR(32) PRIMARY KEY,
rule_name VARCHAR(50) NOT NULL,
rule_type TINYINT NOT NULL COMMENT '1-获取规则 2-过期规则',
points_value INT COMMENT '获取积分数值或比例',
expiry_days INT COMMENT '过期天数(0表示永久有效)',
status TINYINT DEFAULT 1 COMMENT '1-启用 0-禁用',
start_time DATETIME,
end_time DATETIME,
create_time DATETIME NOT NULL,
update_time DATETIME,
store_id int unsigned NOT NULL COMMENT '店铺编号',
warning_day INT NOT NULL default 0 COMMENT '预警通知0是表示没有预警',
remark VARCHAR(200)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE shop_store_points_rule (
rule_id VARCHAR(32) PRIMARY KEY,
rule_name VARCHAR(50) NOT NULL COMMENT '规则名称',
rule_type TINYINT NOT NULL COMMENT '1-获取规则 2-过期规则',
points_value INT default 0 COMMENT '获取积分数值或比例',
expiry_days INT default 0 COMMENT '过期天数(0表示永久有效)',
status TINYINT DEFAULT 1 COMMENT '1-启用 0-禁用',
start_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',
end_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '结束时间',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
store_id int unsigned NOT NULL COMMENT '店铺编号',
warning_day INT NOT NULL default 0 COMMENT '预警通知0是表示没有预警',
remark VARCHAR(200) DEFAULT '' COMMENT '备注'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分规则表';
alter table shop_store_points_rule add index `rule_name` (`rule_name`) USING BTREE;

View File

@ -0,0 +1,6 @@
alter table shop_store_activity_base add column `person_limit` int DEFAULT '0' COMMENT '每人限购,0为不限购';
alter table shop_store_activity_base add column `order_limit` int DEFAULT '0' COMMENT '每单限购,0为不限购';
alter table shop_store_activity_base add column `is_new_person_shop` char(1) DEFAULT '0' COMMENT '是否店铺新用户专享1是0否';
alter table account_base_user_level change user_level_spend user_level_spend decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '累计消费';

View File

@ -0,0 +1 @@
alter table account_user_bind_connect add column send_number int unsigned NOT NULL DEFAULT '0' comment '剩余订阅次数';

View File

@ -0,0 +1,92 @@
CREATE TABLE `shop_store_member_level` (
`store_member_level_id` int unsigned NOT NULL COMMENT '主表id',
`user_level_id` int NOT NULL AUTO_INCREMENT COMMENT '等级编号',
`user_level_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '等级名称',
`user_level_spend` decimal(6,2) NOT NULL DEFAULT '0.00' COMMENT '累计消费',
`first_purchase_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '首次消费时间(成为店铺会员的时间)',
`store_points` int NOT NULL DEFAULT '0' COMMENT '积分',
`last_purchase_time` datetime DEFAULT NULL COMMENT '最近消费时间',
`member_level_id` int unsigned NOT NULL DEFAULT '0' COMMENT '店铺会员等级id',
`member_level_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '等级名称',
`user_level_rate` decimal(6,2) NOT NULL DEFAULT '100.00' COMMENT '折扣率百分比',
`user_level_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`store_id` int unsigned NOT NULL COMMENT '店铺编号',
`store_member_id` int unsigned NOT NULL COMMENT '店铺会员id',
PRIMARY KEY (`store_member_level_id`) USING BTREE,
KEY `index_user_level_id` (`user_level_id`) USING BTREE,
KEY `index_user_level_name` (`user_level_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员等级表-店铺';
alter table shop_store_member_level add column `user_id` int unsigned NOT NULL COMMENT '用户编号';
CREATE TABLE `shop_store_member` (
`store_member_id` int NOT NULL AUTO_INCREMENT COMMENT '店铺会员id',
`user_id` int unsigned NOT NULL COMMENT '用户编号',
`store_id` int unsigned NOT NULL COMMENT '店铺编号',
`store_name` varchar(50) NOT NULL COMMENT '店铺名称',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`user_account` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户名',
`user_nickname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT ' 用户昵称',
`send_number` int unsigned NOT NULL DEFAULT '0' COMMENT '剩余订阅次数',
`bind_openid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '访问Open编号',
PRIMARY KEY (`store_member_id`),
UNIQUE KEY `unique_user_store` (`user_id`,`store_id`),
KEY `index_store_id` (`store_id`) USING BTREE,
KEY `index_store_name` (`store_name`) USING BTREE,
KEY `index_user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员表-店铺';
CREATE TABLE shop_store_points_account (
user_id VARCHAR(32) PRIMARY KEY,
store_member_id int NOT NULL COMMENT '店铺会员id',
total_points INT DEFAULT 0 COMMENT '累计获得积分',
available_points INT DEFAULT 0 COMMENT '可用积分',
frozen_points INT DEFAULT 0 COMMENT '冻结积分',
expired_points INT DEFAULT 0 COMMENT '已过期积分',
last_update_time DATETIME NOT NULL COMMENT '最后更新时间',
FOREIGN KEY (store_member_id) REFERENCES shop_store_member(store_member_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分账户表';
CREATE TABLE shop_store_points_transaction (
transaction_id VARCHAR(32) PRIMARY KEY,
user_id int NOT NULL COMMENT '用户编号',
store_member_id VARCHAR(32) NOT NULL COMMENT '店铺会员id',
points INT NOT NULL COMMENT '正数为获得,负数为消耗',
balance_after INT NOT NULL COMMENT '交易后余额',
transaction_type TINYINT NOT NULL COMMENT '1-获取 2-消费 3-过期 4-调整',
transaction_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '流水时间',
expiry_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '过期日期',
source_id VARCHAR(32) NOT NULL DEFAULT '' COMMENT '来源ID(订单ID等)',
source_desc VARCHAR(100) NOT NULL DEFAULT '' COMMENT '来源描述',
remark VARCHAR(200) COMMENT '备注',
INDEX idx_account (user_id),
INDEX idx_expiry (expiry_date),
INDEX idx_transaction_time (transaction_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分流水表';
CREATE TABLE shop_store_points_rule (
rule_id VARCHAR(32) PRIMARY KEY,
rule_name VARCHAR(50) NOT NULL COMMENT '规则名称',
rule_type TINYINT NOT NULL COMMENT '1-获取规则 2-过期规则',
points_value INT default 0 COMMENT '获取积分数值或比例',
expiry_days INT default 0 COMMENT '过期天数(0表示永久有效)',
status TINYINT DEFAULT 1 COMMENT '1-启用 0-禁用',
start_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',
end_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '结束时间',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '新建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
store_id int unsigned NOT NULL COMMENT '店铺编号',
warning_day INT NOT NULL default 0 COMMENT '预警通知0是表示没有预警',
remark VARCHAR(200) DEFAULT '' COMMENT '备注'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表-积分规则表';
alter table shop_store_points_rule add index `rule_name` (`rule_name`) USING BTREE;
alter table shop_store_activity_base add column `person_limit` int DEFAULT '0' COMMENT '每人限购,0为不限购';
alter table shop_store_activity_base add column `order_limit` int DEFAULT '0' COMMENT '每单限购,0为不限购';
alter table shop_store_activity_base add column `is_new_person_shop` char(1) DEFAULT '0' COMMENT '是否店铺新用户专享1是0否';
alter table account_user_bind_connect add column send_number int unsigned NOT NULL DEFAULT '0' comment '剩余订阅次数';
alter table account_base_user_level change user_level_spend user_level_spend decimal(16,2) NOT NULL DEFAULT '0.00' COMMENT '累计消费';

View File

@ -0,0 +1,3 @@
INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-store-member/list', 'index', 'master', '', '0', '/admin/shop/shop-store-member/list','店铺会员查询');
INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-store-member/exportShopStoreMember', 'index', 'master', '', '0', '/admin/shop/shop-store-member/exportShopStoreMember','店铺会员导出');
INSERT INTO `admin_base_protocol` (`ctl`, `met`, `db`, `rights_id`, `log`, `path`,`comment`) VALUES ('/admin/shop/shop-store-member/getShopStoreMember', 'index', 'master', '', '0', '/admin/shop/shop-store-member/getShopStoreMember','单个店铺会员查看');