| | |
| | | |
| | | |
| | | -- ============================================================ |
| | | -- 2026/05/13 注册满年赠送优惠券定时任务 |
| | | -- ============================================================ |
| | | INSERT INTO `system_job` (`JOB_NAME`, `HANDLER`, `CRON`, `WITH_LOG`, `WITH_ASYNC`, `STATUS`, `REMARK`, `CREATE_USER`, `CREATE_TIME`, `UPDATE_USER`, `UPDATE_TIME`, `DELETED`) |
| | | VALUES ('注册满年赠送优惠券', 'registerCouponGiftJob', '0 0 3 * * ?', 1, 0, 1, '根据运营配置,查询注册满X年的会员赠送优惠券', 1, NOW(), 1, NOW(), 0); |
| | | |
| | | -- ============================================================ |
| | | -- 2026/05/13 运营配置增加优惠券赠送规则 |
| | | -- ============================================================ |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'ORDER_COUPON_ORDER_COUNT', '下单赠送-订单次数', 0, 0, 1, NOW(), 0); |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'ORDER_COUPON_GIFT_COUNT', '下单赠送-至多赠送次数', 1, 0, 1, NOW(), 0); |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'ORDER_COUPON_ID', '下单赠送-优惠券ID', 2, 0, 1, NOW(), 0); |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'REGISTER_COUPON_YEARS', '注册赠送-注册年数', 3, 0, 1, NOW(), 0); |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'REGISTER_COUPON_GIFT_COUNT', '注册赠送-至多赠送次数', 4, 0, 1, NOW(), 0); |
| | | INSERT INTO `SYSTEM_DICT_DATA` (`DICT_ID`, `CODE`, `LABEL`, `REMARK`, `SORT`, `DISABLED`, `CREATE_USER`, `CREATE_TIME`, `DELETED`) VALUES (105, '', 'REGISTER_COUPON_ID', '注册赠送-优惠券ID', 5, 0, 1, NOW(), 0); |
| | | |
| | | |
| | | -- ============================================================ |
| | | -- 2026/05/13 会员增加优惠券赠送次数字段 |
| | | -- ============================================================ |
| | | ALTER TABLE `member` ADD COLUMN `ORDER_COUPON_GIFT_COUNT` INT DEFAULT 0 COMMENT '下单赠送优惠券已赠送次数' AFTER `TYPE`; |
| | | ALTER TABLE `member` ADD COLUMN `REGISTER_COUPON_GIFT_COUNT` INT DEFAULT 0 COMMENT '注册满年赠送优惠券已赠送次数' AFTER `ORDER_COUPON_GIFT_COUNT`; |
| | | |
| | | -- ============================================================ |
| | | -- 2026/05/13 优惠券信息表 |
| | | -- ============================================================ |
| | | CREATE TABLE `coupon` ( |
| | |
| | | dto.setDefaultDeliveryRange(getValue(Constants.OP_DEFAULT_DELIVERY_RANGE)); |
| | | dto.setArrivalPickUpTime(getValue(Constants.OP_ARRIVAL_PICK_UP_TIME)); |
| | | dto.setOperationRadius(getValue(Constants.OP_OPERATION_RADIUS)); |
| | | dto.setOrderCouponOrderCount(getValue(Constants.OP_ORDER_COUPON_ORDER_COUNT)); |
| | | dto.setOrderCouponGiftCount(getValue(Constants.OP_ORDER_COUPON_GIFT_COUNT)); |
| | | dto.setOrderCouponId(getValue(Constants.OP_ORDER_COUPON_ID)); |
| | | dto.setRegisterCouponYears(getValue(Constants.OP_REGISTER_COUPON_YEARS)); |
| | | dto.setRegisterCouponGiftCount(getValue(Constants.OP_REGISTER_COUPON_GIFT_COUNT)); |
| | | dto.setRegisterCouponId(getValue(Constants.OP_REGISTER_COUPON_ID)); |
| | | return dto; |
| | | } |
| | | |
| | |
| | | saveOrUpdate(Constants.OP_DEFAULT_DELIVERY_RANGE, "默认配送范围", dto.getDefaultDeliveryRange()); |
| | | saveOrUpdate(Constants.OP_ARRIVAL_PICK_UP_TIME, "即将到达取件时间通知", dto.getArrivalPickUpTime()); |
| | | // saveOrUpdate(Constants.OP_OPERATION_RADIUS, "允许操作半径", dto.getOperationRadius()); |
| | | saveOrUpdate(Constants.OP_ORDER_COUPON_ORDER_COUNT, "下单赠送-订单次数", dto.getOrderCouponOrderCount()); |
| | | saveOrUpdate(Constants.OP_ORDER_COUPON_GIFT_COUNT, "下单赠送-至多赠送次数", dto.getOrderCouponGiftCount()); |
| | | saveOrUpdate(Constants.OP_ORDER_COUPON_ID, "下单赠送-优惠券ID", dto.getOrderCouponId()); |
| | | saveOrUpdate(Constants.OP_REGISTER_COUPON_YEARS, "注册赠送-注册年数", dto.getRegisterCouponYears()); |
| | | saveOrUpdate(Constants.OP_REGISTER_COUPON_GIFT_COUNT, "注册赠送-至多赠送次数", dto.getRegisterCouponGiftCount()); |
| | | saveOrUpdate(Constants.OP_REGISTER_COUPON_ID, "注册赠送-优惠券ID", dto.getRegisterCouponId()); |
| | | } |
| | | |
| | | private String getValue(String label) { |
| | |
| | | public static final String OP_DEFAULT_DELIVERY_RANGE = "DEFAULT_DELIVERY_RANGE"; |
| | | public static final String OP_ARRIVAL_PICK_UP_TIME = "ARRIVAL_PICK_UP_TIME"; |
| | | public static final String OP_OPERATION_RADIUS = "OPERATION_RADIUS"; |
| | | public static final String OP_ORDER_COUPON_ORDER_COUNT = "ORDER_COUPON_ORDER_COUNT"; |
| | | public static final String OP_ORDER_COUPON_GIFT_COUNT = "ORDER_COUPON_GIFT_COUNT"; |
| | | public static final String OP_ORDER_COUPON_ID = "ORDER_COUPON_ID"; |
| | | public static final String OP_REGISTER_COUPON_YEARS = "REGISTER_COUPON_YEARS"; |
| | | public static final String OP_REGISTER_COUPON_GIFT_COUNT = "REGISTER_COUPON_GIFT_COUNT"; |
| | | public static final String OP_REGISTER_COUPON_ID = "REGISTER_COUPON_ID"; |
| | | |
| | | // 芯烨云打印机配置 |
| | | public static final String XPYUN_CONFIG = "XPYUN_CONFIG"; |
| | |
| | | @TableField(exist = false) |
| | | private Integer type; |
| | | |
| | | @ApiModelProperty(value = "下单赠送优惠券已赠送次数", example = "0") |
| | | private Integer orderCouponGiftCount; |
| | | |
| | | @ApiModelProperty(value = "注册满年赠送优惠券已赠送次数", example = "0") |
| | | private Integer registerCouponGiftCount; |
| | | |
| | | @ApiModelProperty(value = "头像全路径") |
| | | @TableField(exist = false) |
| | | private String fullCoverImage; |
| | | |
| | | @ApiModelProperty(value = "接单权重", example = "1") |
| | | @TableField(exist = false) |
| | | private Integer level; |
| | | |
| | | @ApiModelProperty(value = "距离", example = "1") |
| | | @TableField(exist = false) |
| | | private BigDecimal distance; |
| | | |
| | | @ApiModelProperty(value = "身份信息", example = "1") |
| | | @TableField(exist = false) |
| | |
| | | @ApiModelProperty(value = "允许操作半径(m)", required = true) |
| | | private String operationRadius; |
| | | |
| | | @ApiModelProperty(value = "下单满X次赠送优惠券-订单次数") |
| | | private String orderCouponOrderCount; |
| | | |
| | | @ApiModelProperty(value = "下单满X次赠送优惠券-至多赠送次数") |
| | | private String orderCouponGiftCount; |
| | | |
| | | @ApiModelProperty(value = "下单满X次赠送优惠券-赠送优惠券ID") |
| | | private String orderCouponId; |
| | | |
| | | @ApiModelProperty(value = "注册满X年赠送优惠券-注册年数") |
| | | private String registerCouponYears; |
| | | |
| | | @ApiModelProperty(value = "注册满X年赠送优惠券-至多赠送次数") |
| | | private String registerCouponGiftCount; |
| | | |
| | | @ApiModelProperty(value = "注册满X年赠送优惠券-赠送优惠券ID") |
| | | private String registerCouponId; |
| | | |
| | | } |
| | |
| | | * @return MemberDetailVO |
| | | */ |
| | | MemberDetailVO findMemberDetail(Integer id); |
| | | } |
| | | |
| | | void giftRegisterCoupon(); |
| | | } |
| | |
| | | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; |
| | | import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.biz.system.OperationConfigBiz; |
| | | import com.doumee.biz.system.SystemDictDataBiz; |
| | | import com.doumee.config.jwt.JwtTokenUtil; |
| | | import com.doumee.config.wx.WxMiniConfig; |
| | |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.core.utils.Utils; |
| | | import com.doumee.dao.business.MemberMapper; |
| | | import com.doumee.dao.business.CouponMapper; |
| | | import com.doumee.dao.business.MemberCouponMapper; |
| | | import com.doumee.dao.business.OrdersMapper; |
| | | import com.doumee.dao.business.ShopInfoMapper; |
| | | import com.doumee.dao.business.SmsrecordMapper; |
| | | import com.doumee.dao.business.model.Member; |
| | | import com.doumee.dao.business.model.Coupon; |
| | | import com.doumee.dao.business.model.MemberCoupon; |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.ShopInfo; |
| | | import com.doumee.dao.business.model.MemberRevenue; |
| | | import com.doumee.dao.business.model.Smsrecord; |
| | | import com.doumee.dao.dto.MemberListQueryDTO; |
| | | import com.doumee.dao.dto.OperationConfigDTO; |
| | | import com.doumee.dao.dto.UpdMobileRequest; |
| | | import com.doumee.dao.dto.WxPhoneRequest; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import me.chanjar.weixin.common.error.WxErrorException; |
| | | import nonapi.io.github.classgraph.json.Id; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | |
| | | * @author 江蹄蹄 |
| | | * @date 2025/07/09 12:00 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class MemberServiceImpl implements MemberService { |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private OrdersMapper ordersMapper; |
| | | |
| | | @Autowired |
| | | private OperationConfigBiz operationConfigBiz; |
| | | |
| | | @Autowired |
| | | private CouponMapper couponMapper; |
| | | |
| | | @Autowired |
| | | private MemberCouponMapper memberCouponMapper; |
| | | |
| | | |
| | | @Override |
| | |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public void giftRegisterCoupon() { |
| | | // 1. 读取配置 |
| | | OperationConfigDTO config = operationConfigBiz.getConfig(); |
| | | String yearsStr = config.getRegisterCouponYears(); |
| | | String maxGiftStr = config.getRegisterCouponGiftCount(); |
| | | String couponIdStr = config.getRegisterCouponId(); |
| | | if (StringUtils.isBlank(yearsStr) || StringUtils.isBlank(maxGiftStr) || StringUtils.isBlank(couponIdStr)) { |
| | | return; |
| | | } |
| | | int configYears = Integer.parseInt(yearsStr); |
| | | int maxGiftCount = Integer.parseInt(maxGiftStr); |
| | | int couponId = Integer.parseInt(couponIdStr); |
| | | if (configYears <= 0 || maxGiftCount <= 0) { |
| | | return; |
| | | } |
| | | |
| | | // 2. 校验优惠券存在且启用 |
| | | Coupon coupon = couponMapper.selectById(couponId); |
| | | if (coupon == null || !Constants.equalsInteger(coupon.getIsdeleted(), Constants.ZERO) |
| | | || !Constants.equalsInteger(coupon.getStatus(), Constants.ZERO)) { |
| | | return; |
| | | } |
| | | |
| | | // 3. 查询所有普通会员 |
| | | List<Member> members = memberMapper.selectList(new QueryWrapper<Member>().lambda() |
| | | .eq(Member::getDeleted, Constants.ZERO) |
| | | .eq(Member::getStatus, Constants.ZERO) |
| | | .eq(Member::getUserType, Constants.ZERO) |
| | | .isNotNull(Member::getCreateTime)); |
| | | |
| | | Date now = new Date(); |
| | | long msPerYear = 365L * 24 * 60 * 60 * 1000; |
| | | int giftedMemberCount = 0; |
| | | |
| | | for (Member member : members) { |
| | | int alreadyGifted = member.getRegisterCouponGiftCount() != null ? member.getRegisterCouponGiftCount() : 0; |
| | | // 已注册年数(取整) |
| | | int registeredYears = (int) ((now.getTime() - member.getCreateTime().getTime()) / msPerYear); |
| | | // 应赠送总次数 |
| | | int shouldGiftTotal = registeredYears / configYears; |
| | | // 实际还需赠送次数 |
| | | int remainGift = Math.min(shouldGiftTotal, maxGiftCount) - alreadyGifted; |
| | | if (remainGift <= 0) { |
| | | continue; |
| | | } |
| | | |
| | | // 4. 赠送优惠券 |
| | | for (int i = 0; i < remainGift; i++) { |
| | | MemberCoupon mc = new MemberCoupon(); |
| | | mc.setCouponId(couponId); |
| | | mc.setMemberId(member.getId()); |
| | | mc.setStatus(Constants.CouponStatus.waitClaim.getKey()); |
| | | // 推送后领取有效期 |
| | | Calendar validCal = Calendar.getInstance(); |
| | | validCal.add(Calendar.DAY_OF_MONTH, coupon.getPushDays() != null ? coupon.getPushDays() : 7); |
| | | mc.setValidDate(validCal.getTime()); |
| | | // 拷贝优惠券信息 |
| | | mc.setName(coupon.getName()); |
| | | mc.setInfo(coupon.getInfo()); |
| | | mc.setType(coupon.getType()); |
| | | mc.setLimitPrice(coupon.getLimitPrice()); |
| | | mc.setPrice(coupon.getPrice()); |
| | | mc.setGetMethod(coupon.getGetMethod()); |
| | | mc.setCouponType(coupon.getCouponType()); |
| | | mc.setPushDays(coupon.getPushDays()); |
| | | mc.setValidDays(coupon.getValidDays()); |
| | | mc.setIsdeleted(Constants.ZERO); |
| | | mc.setCreateDate(now); |
| | | mc.setEditDate(now); |
| | | memberCouponMapper.insert(mc); |
| | | } |
| | | |
| | | // 5. 更新会员已赠送次数 |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda() |
| | | .set(Member::getRegisterCouponGiftCount, alreadyGifted + remainGift) |
| | | .eq(Member::getId, member.getId())); |
| | | giftedMemberCount++; |
| | | } |
| | | log.info("注册满年赠送优惠券完成,共处理{}名会员", giftedMemberCount); |
| | | } |
| | | |
| | | } |