深圳网站建设服务哪个便宜啊网站后台构建

张小明 2026/1/11 5:00:25
深圳网站建设服务哪个便宜啊,网站后台构建,网站建设介绍会发言稿,自己注册一家公司需要多少钱day10接口 1 查询发放中的优惠券接口说明查询发放中的优惠券请求方式GET请求路径/coupons/list请求参数无返回值[ { id: 110, // 优惠券id name: 年中大促, // 优惠券名称 specific: true, // 优惠券是…day10接口1 查询发放中的优惠券接口说明查询发放中的优惠券请求方式GET请求路径/coupons/list请求参数无返回值[ { id: 110, // 优惠券id name: 年中大促, // 优惠券名称 specific: true, // 优惠券是否限定了课程范围 discountType: , // 折扣类型 thresholdAmount: 0 // 折扣门槛 discountValue: 0, // 折扣值 maxDiscountAmount: 0, // 最大折扣金额 termDays: 0, // 有效天数 termEndTime: , // 过期时间 available: true, // 是否可领取 received: true, // 是否已领取 } ]CouponController.java/** * 查询发放中的优惠券列表 * return */ApiOperation(查询发放中的优惠券列表)GetMapping(list)publicListCouponVOqueryIssuingCoupons(){returncouponService.queryIssuingCoupons();}ICouponService.javaListCouponVOqueryIssuingCoupons();CouponServiceImpl.javaOverridepublicListCouponVOqueryIssuingCoupons(){//1.查询属于手动领取以及发放中的优惠券ListCouponlistlambdaQuery().eq(Coupon::getStatus,CouponStatus.ISSUING).eq(Coupon::getObtainWay,PUBLIC).list();if(CollUtils.isEmpty(list)){returnCollUtils.emptyList();}ListLongidslist.stream().map(Coupon::getId).collect(Collectors.toList());// 2.查询用户领取的并符合条件的优惠券ListUserCouponequserCouponService.lambdaQuery().eq(UserCoupon::getUserId,UserContext.getUser()).in(UserCoupon::getCouponId,ids).list();//2.1当前用户已经领取的数量MapLong,Longmapeq.stream().collect(Collectors.groupingBy(UserCoupon::getCouponId,Collectors.counting()));//2.2当前用户对优惠券已经领取但是没使用的数量MapLong,Longunusedeq.stream().filter(uc-uc.getStatus().equals(UserCouponStatus.UNUSED)).collect(Collectors.groupingBy(UserCoupon::getCouponId,Collectors.counting()));//3.封装优惠券信息并返回ArrayListCouponVOcouponVOSnewArrayList();for(Couponcoupon:list){CouponVOcouponVOBeanUtils.copyBean(coupon,CouponVO.class);//3.是否可以领取被领取数量未达到总发放数量当前用户领取数量小于每人最多领取数量couponVO.setAvailable(coupon.getIssueNum()coupon.getTotalNum()map.getOrDefault(coupon.getId(),0L)coupon.getUserLimit());//4.是否可以使用(未使用的)couponVO.setReceived(unused.getOrDefault(coupon.getId(),0L)0);couponVOS.add(couponVO);}returncouponVOS;}2 手动领取优惠券UserCouponController.java/** * 领取优惠券(方式为手动领取的优惠券) * * param couponId * return */PostMapping({couponId}/receive)ApiOperation(领取优惠券)publicvoidreceiveCoupon(PathVariableLongcouponId){userCouponService.receiveCoupon(couponId);}IUserCouponService.javavoidreceiveCoupon(LongcouponId);UserCouponServiceImpl.javaOverrideTransactionalpublicvoidreceiveCoupon(LongcouponId){CouponcouponcouponMapper.selectById(couponId);if(couponnull){thrownewBizIllegalException(优惠券不存在);}LocalDateTimenowLocalDateTime.now();if(now.isBefore(coupon.getIssueBeginTime())||now.isAfter(coupon.getIssueEndTime())){thrownewBizIllegalException(优惠券不在领取时间范围内);}LonguserIdUserContext.getUser();LongresultredisLuaService.tryReceiveCoupon(couponId,userId,coupon.getUserLimit());if(resultnull){thrownewBizIllegalException(系统繁忙);}if(result-1){thrownewBizIllegalException(超过个人领取上限);}if(result0){thrownewBizIllegalException(库存不足);}try{saveUserCouponWithTx(coupon,userId,now);}catch(Exceptione){redisLuaService.rollbackCoupon(couponId,userId);throwe;}}TransactionalpublicvoidsaveUserCouponWithTx(Couponcoupon,LonguserId,LocalDateTimenow){// 1. 校验每人限领数量兜底IntegercountlambdaQuery().eq(UserCoupon::getUserId,userId).eq(UserCoupon::getCouponId,coupon.getId()).count();if(count!nullcountcoupon.getUserLimit()){thrownewBizIllegalException(该用户领取数量超出限制);}// 2. 乐观更新优惠券发放数量最终防线introwscouponMapper.incrIssueNumWithLimit(coupon.getId());if(rows0){thrownewBizIllegalException(优惠券库存不足);}// 3. 新增用户优惠券addCoupon(coupon.getId(),coupon,now,userId);}privatevoidaddCoupon(LongcouponId,Couponcoupon,LocalDateTimenow,LonguserId){UserCouponuserCouponnewUserCoupon();LocalDateTimetermBeginTimecoupon.getTermBeginTime();LocalDateTimetermEndTimecoupon.getTermEndTime();if(termBeginTimenull){termBeginTimenow;termEndTimetermBeginTime.plusDays(coupon.getTermDays());}userCoupon.setUserId(userId);userCoupon.setCouponId(couponId);userCoupon.setTermBeginTime(termBeginTime);userCoupon.setTermEndTime(termEndTime);userCoupon.setStatus(UserCouponStatus.UNUSED);this.save(userCoupon);}Lua脚本-- KEYS[1] coupon:stock:{couponId}-- KEYS[2] coupon:user:{couponId}-- ARGV[1] userId-- ARGV[2] userLimit-- 1. 查询用户已领取数量localcounttonumber(redis.call(HGET,KEYS[2],ARGV[1])or0)locallimittonumber(ARGV[2])ifcountlimitthenreturn-1-- 超过个人限领end-- 2. 校验库存localstocktonumber(redis.call(GET,KEYS[1]))ifnotstockorstock0thenreturn0-- 库存不足end-- 3. 扣库存redis.call(DECR,KEYS[1])-- 4. 用户领取数量 1redis.call(HINCRBY,KEYS[2],ARGV[1],1)-- 5. 成功return1LUA配置类packagecom.tianji.promotion.config;importcom.tianji.promotion.constants.PromotionConstants;importlombok.RequiredArgsConstructor;importorg.springframework.core.io.ClassPathResource;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.data.redis.core.script.DefaultRedisScript;importorg.springframework.stereotype.Service;importjava.util.Arrays;importjava.util.List;/** * Redis Lua 执行统一封装 * * 职责 * 1. 负责 Lua 脚本加载 * 2. 统一管理 Redis Key 拼装 * 3. 对业务层屏蔽 Lua 细节 * author ABC */ServiceRequiredArgsConstructorpublicclassRedisLuaService{privatefinalStringRedisTemplateredisTemplate;privatestaticfinalDefaultRedisScriptLongRECEIVE_COUPON_SCRIPT;static{RECEIVE_COUPON_SCRIPTnewDefaultRedisScript();RECEIVE_COUPON_SCRIPT.setLocation(newClassPathResource(redis/lua/receive_coupon.lua));RECEIVE_COUPON_SCRIPT.setResultType(Long.class);}publicLongtryReceiveCoupon(LongcouponId,LonguserId,IntegeruserLimit){StringstockKeyPromotionConstants.COUPON_STOCK_KEYcouponId;StringuserCountKeyPromotionConstants.COUPON_USER_COUNT_KEYcouponId;returnredisTemplate.execute(RECEIVE_COUPON_SCRIPT,List.of(stockKey,userCountKey),userId.toString(),userLimit.toString());}/** * DB 失败回滚 */publicvoidrollbackCoupon(LongcouponId,LonguserId){StringstockKeyPromotionConstants.COUPON_STOCK_KEYcouponId;StringuserCountKeyPromotionConstants.COUPON_USER_COUNT_KEYcouponId;redisTemplate.opsForValue().increment(stockKey);redisTemplate.opsForHash().increment(userCountKey,userId.toString(),-1);}}Redis常量Keypackagecom.tianji.promotion.constants;/** * 优惠券常量类 * * author ax */publicinterfacePromotionConstants{/** * 优惠券的兑换码生成序列号key */StringCOUPON_CODE_SERIAL_KEYcoupon:code:serial:;/** * 优惠券的兑换码兑换序列号key */StringCOUPON_CODE_MAP_KEYcoupon:code:serial:;/** * 优惠券库存 * coupon:stock:{couponId} - int */StringCOUPON_STOCK_KEYcoupon:stock:;/** * 用户已领取数量 * coupon:user:{couponId} - Hash(userId - count) */StringCOUPON_USER_COUNT_KEYcoupon:user:;}CouponMapper.javaUpdate(update coupon set issue_num issue_num 1 where id #{couponId} and issue_num total_num)intincrIssueNumWithLimit(LongcouponId);3 兑换码兑换优惠券UserCouponController.java/** * 兑换码兑换优惠券(方式为兑换码兑换的优惠券) * * return */PostMapping({code}/exchange)ApiOperation(兑换码兑换优惠券)publicvoidexchangeCoupon(PathVariableStringcode){userCouponService.exchangeCoupon(code);}IUserCouponService.javavoidexchangeCoupon(Stringcode);UserCouponServiceImpl.javaOverrideTransactionalpublicvoidexchangeCoupon(Stringcode){//校验兑换码是否被兑换过是否存在longlCodeUtil.parseCode(code);//是否已经兑换过 setbit替换getbitbooleanisExchangeexchangeCodeService.updateExchangeMark(l,true);try{if(isExchange){thrownewBizIllegalException(该兑换码已经兑换过);}ExchangeCodebyIdexchangeCodeService.getById(l);if(byIdnull){thrownewBizIllegalException(该兑换码不存在);}LocalDateTimenowLocalDateTime.now();if(now.isAfter(byId.getExpiredTime())){thrownewBizIllegalException(该兑换码已过期);}//查询优惠券CouponcouponcouponMapper.selectById(byId.getExchangeTargetId());LonguserIdUserContext.getUser();//领取优惠券saveUserCouponWithTx(coupon,userId,now);//更新兑换码状态exchangeCodeService.lambdaUpdate().eq(ExchangeCode::getId,l).set(ExchangeCode::getUserId,userId).set(ExchangeCode::getStatus,ExchangeCodeStatus.USED).update();}catch(Exceptione){exchangeCodeService.updateExchangeMark(l,false);throwe;}}IExchangeCodeServicebooleanupdateExchangeMark(longl,booleanb);ExchangeCodeServiceImplOverridepublicbooleanupdateExchangeMark(longl,booleanb){BooleanisstringRedisTemplate.opsForValue().setBit(COUPON_CODE_MAP_KEY,l,b);returnis!nullis;}CouponMapper.javaUpdate(update coupon set issue_num issue_num 1 where id #{couponId} and issue_num total_num)intincrIssueNumWithLimit(LongcouponId);一种解决方案我们可以借助AspectJ来实现。1引入AspectJ依赖!--aspecj--dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactId/dependency2暴露代理对象在启动类上添加注解暴露代理对象3使用代理对象最后改造领取优惠券的代码获取代理对象来调用事务方法
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

豆芽网站建设douyanet荆门市城乡建设管理局网站

基于微信小程序的网络安全知识科普平台系统 两个角色(管理员,用户) 效果如下: 登录页面用户首页面科普分类页面智能问答页面管理员首页面用户管理页面科普知识页面轮播图管理页面研究背景 在数字化浪潮席卷全球的当下,…

张小明 2026/1/1 6:42:32 网站建设

怎么做谷歌这样的网站ic电子网站建设

飞书文档批量导出完整指南:高效迁移与备份方案 【免费下载链接】feishu-doc-export 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 面对企业办公软件切换或知识库迁移的需求,文档批量导出成为许多团队面临的挑战。特别是从飞书…

张小明 2025/12/31 10:52:00 网站建设

做优化排名会不会影响网站速度杭州建筑培训中心

Wan2.1-VACE-14B作为一款全能视频生成编辑模型,凭借其卓越的性能、广泛的任务支持以及对消费级GPU的兼容性,正在重新定义视频内容创作的边界,为行业带来了前所未有的可能性。 【免费下载链接】Wan2.1-VACE-14B 项目地址: https://ai.gitco…

张小明 2026/1/9 1:13:48 网站建设

如何建企业网站广告推广软件

概述 WebP:由 Google 基于 VP8 视频编码派生(libwebp),支持有损(基于预测变换熵编码)与无损(基于局部字典/预测)压缩、RGBA alpha、动画。设计目标:在保持视觉质量的同时…

张小明 2025/12/31 11:48:45 网站建设

单招网站开发基础知识看视频的app有哪些

Wan2.2-T2V-A14B在金融产品介绍视频批量创建中的效率提升 你有没有算过,一家银行每年要为多少款理财产品拍宣传视频?如果每条视频从策划到上线平均耗时3天、成本5万元——那一年光是“讲清楚自家产品”,就得烧掉几百万预算。更别提还要做不同…

张小明 2025/12/31 23:29:20 网站建设

网站通知系统wordpress 后台空白

NPS净推荐值调查:衡量用户满意程度 在今天这个AI工具层出不穷的时代,一个产品能不能“打”,早已不只看它有没有炫酷的技术参数。响应速度再快、模型再强大,如果用户用起来皱眉头、不愿分享给同事朋友——那它很可能只是实验室里的…

张小明 2025/12/31 22:26:33 网站建设