当前位置: 首页 > article >正文

抽奖系统核心——抽奖管理

目录

前端逻辑:

核心全局变量:

reloadConf函数:

nextStep函数:

后端实现:

抽奖接口:

Controller层:

Service层:

MqReceiver:

drawPrizeService:

statusConvert()方法:

activityStatusManage服务handerEvent()方法:

加入设计模式:责任链模式和策略模式。

drawPrizeService.saveWinnerRecords()方法:

并发处理短信通知和邮箱通知:

Mapper层:

校验抽奖请求是否有效,通过活动id查询活动:

​编辑查询相关信息:活动,人员,奖品,活动关联奖品表,构造中奖者信息。

 状态扭转更新数据库:


前端逻辑:

判断是否为管理员,管理员可以抽奖:

活动进行中,valid为true,身份为管理员,使用reloadConf初始化页面(nextStep作为回调函数),活动未开始,调用showRecords函数进行展示。 

核心全局变量:

    // 奖品列表var steps = null// 抽到第几个了var step = 0// 人员列表var names = null// 正在做什么var state = ''

reloadConf函数:

reloadConf函数调用接口,获取活动的详细信息,给全局变量steps(奖品列表)names(人员列表)赋值,调用传过来的回调函数nextStep用于根据当前状态显示下一个步骤的内容。

nextStep函数:

使用data函数拿到奖品列表中的奖品,根据奖品的状态执行不同逻辑:

一开始状态为空(全局变量的state属性默认为空),走else逻辑,将状态设置为showPic,执行showPic()函数,将奖品信息传入函数中,showPic()函数用于显示图片和奖品信息。

调用changeNextButtonText()函数 ,改变按钮的文本(比如开始抽奖,已抽完,下一步):

如果活动状态未在进行中,执行showRecords()函数:展示中奖信息。

前端点击开始抽奖按钮,接着执行nextStep()函数:奖品为抽取,走if逻辑,,将状态设置为‘showBlink’,执行showBlink()函数,传入奖品信息。执行changeNextButtonText()函数切换按钮文本。showBlink函数用于显示闪烁的文字,它首先设置奖品信息,隐藏图片,显示列表,然后创建与data.count相等数量的span元素。使用window.requestAnimationFrame()循环调用doBlink()函数模拟抽奖的展示效果,让文字不断闪烁。

 继续点击确定按钮,执行nextStep()函数,此时状态state等于showBlink(),执行此函数,将已中奖的人员和奖品信息移除,执行saveLuck()函数调用后端接口,保存中奖信息,将此奖品状态设置为falsestate设置为‘showList’,执行showList()函数,调用changeNextButtonText()函数,切换按钮文本为“已抽完,下一步”。

saveLuck函数:发送请求到后端

showList()函数用于显示静态的文字列表。它设置奖品信息,隐藏图片,显示列表,并将data.list中的数据添加到列表中。

奖品列表在前端只能临时保存,刷新后丢失,如果列表为空,则需要调用后端接口,进行查询:

使用函数showWinnerListWithPrize()传入奖品信息:调用后端的winning-records/show接口:

 点击下一步,如果step小于奖品列表长度,将state设置为空,执行nextStep()函数,将按钮重置为开始抽奖。否则代表奖品已经抽完,执行showRecords()方法,改变按钮为已全部抽完。showRecords方法调用后端“winning-records/show”接口,展示中奖者信息。

到此前端抽奖核心逻辑梳理完毕。

后端实现:

抽奖接口:

Controller层:

接收前端参数,调用Service服务。

使用DrawPrizeParam类接收前端参数:

活动id,奖品id,奖品等级,中奖时间,中奖者列表(中奖者id和姓名)。

Service层:

drawPrize方法将信息发送到RabbitMQ中:

MqReceiver:

接收来自service层的消息,进行异步消息处理:

Mq接收消息后,首先对抽奖的请求进行校验,调用drawPrizeService的方法校验是否为两个一样的抽奖请求,将中奖的人员,奖品,活动状态进行状态扭转。保存中奖者名单,发送邮箱和短信通知中奖者。遇到异常回滚状态,保持事务一致性。

drawPrizeService:

对抽奖请求进行校验,根据活动id,查询活动信息和活动奖品详细信息。判断活动和活动奖品是否存在,校验抽奖活动的状态是否已经完成,校验抽奖奖品是否有效,校验中奖人数是否和奖品数量相同。

statusConvert()方法:

ConvertActivityStatusDTO类存放活动id,活动目标状态,奖品id,奖品目标状态,人员id,人员目标状态。将这些状态设置为目标状态,调用activityStatusManage服务,将需要扭转的状态进行扭转。

activityStatusManage服务handerEvent()方法:
加入设计模式:责任链模式和策略模式。

策略模式:将活动扭转(ActivityOperater),奖品扭转(PriceOperater),人员扭转(UserOperater)分为3个不同实现类。每个类继承公共的类AbstractActivityOperater,公共类包含处理的顺序码,判断是否需要状态转换的方法,状态转换方法。策略模式增强代码的维护性和可读性。

责任链模式:将活动扭转,奖品扭转,人员扭转看成三个节点,在进行状态扭转操作时,根据不同操作码,区分执行先后顺序。由于活动扭转的前提是参与人员和参与奖品全部扭转,有一个依赖关系,使用责任链模式,极大增强了系统的拓展性和可维护性。比如,在状态转换时,加入新的需要转换的,目前是人员和奖品,后期可以加入参与奖,参与奖是没中奖的人员全部获得参与奖,参与奖状态也会随之改变。

调用processConvertStatus()方法,根据状态码先处理活动参与人员和活动参与奖品状态,在处理活动状态的转换。循环遍历链式结构,处理状态码为1的状态转换,第二次调用该方法,处理状态码为2的状态转换

调用needConvert()方法,转换状态:

 抽奖核心流程结束。

drawPrizeService.saveWinnerRecords()方法:

保存中奖者名单,构造中奖者记录,将中奖者记录入库,然后再加入到缓存中,方便后续查询使用。

并发处理短信通知和邮箱通知:

使用线程池,创建两个线程,执行发送短信和邮箱功能。

Mapper层:

持久层,包含抽奖操作涉及到的全部sql语句。

校验抽奖请求是否有效,通过活动id查询活动:

根据活动id和奖品id查询活动奖品:

查询相关信息:活动,人员,奖品,活动关联奖品表,构造中奖者信息。

根据id查询活动相关信息:

根据中奖者id查询相关活动人员:

根据奖品id查询奖品详细信息:

根据活动关联奖品id查询活动关联奖品信息:

中奖者信息插入数据库:

 状态扭转更新数据库:

更新活动状态:

更新中奖人员状态:

更新活动关联奖品状态:

 

文章到此结束,感谢观看! 

相关文章:

抽奖系统核心——抽奖管理

目录 前端逻辑: 核心全局变量: reloadConf函数: nextStep函数: 后端实现: 抽奖接口: Controller层: Service层: MqReceiver: drawPrizeService: statusConvert()方法: activityStatu…...

Android 蓝牙通信

Android 平台提供了完整的蓝牙 API,支持 传统蓝牙(Bluetooth Classic)和低功耗蓝牙(BBluetooth Low Energy, BLE)两种通信方式。 以下是开发蓝牙应用的关键知识点。 1. 基本概念 传统蓝牙(Bluetooth Classic) 适合大流量数据传输(如音频、文件传输) 典型协议: R…...

任务调度器-关于中心化调度 vs 去中心化调度的核心区别

1. 定义与架构模型 维度中心化调度去中心化调度核心角色存在一个中央调度器(如XXL-JOB的调度中心),统一管理任务分配、状态监控和故障处理。无中心节点,调度逻辑分散在多个节点,通过共识算法(如选举机制&a…...

二、【ESP32开发全栈指南:ESP32 GPIO深度使用】

GPIO(通用输入输出) 是ESP32最基础却最核心的功能。本文将带你深入ESP32的GPIO操作,通过按键读取和LED控制实现物理按键→ESP32→LED的完整信号链路。 一、ESP32 GPIO核心特性速览 34个可编程GPIO(部分引脚受限)输入模…...

力扣刷题(第四十九天)

灵感来源 - 保持更新,努力学习 - python脚本学习 反转链表 解题思路 迭代法:通过遍历链表,逐个改变节点的指针方向。具体步骤如下: 使用三个指针:prev(初始为None)、curr(初始为…...

机器学习:集成学习概念和分类、随机森林、Adaboost、GBDT

本文目录: 一、集成学习概念**核心思想:** 二、集成学习分类(一)Bagging集成(二)Boosting集成(三)两种集成方法对比 三、随机森林(一)构造过程(二…...

基于J2EE架构的在线考试系统设计与实现【源码+文档】

目录 摘要: Abstract: 1 引言 2 在线考试系统构架 2.1 在线考试系统一般需求分析 2.2 当前在线考试系统现状分析 2.3 基于J2EE的在线考试系统架构介绍及拥有的优势 2.3.1 结构总体介绍 2.3.2 客户层组件 2.3.2.1 Applets 2.3.2.2 应用程序客户端 2.3.3 …...

tpc udp http

TCP(传输控制协议)、UDP(用户数据报协议)和 HTTP(超文本传输协议)是网络通信中常用的三种协议,它们在不同的层次和场景中发挥作用。以下是对这三种协议的详细解释以及它们之间的区别&#xff1a…...

联想拯救者R9000P 网卡 Realtek 8852CE Ubuntu/Mint linux 系统睡眠后,无线网卡失效

联想拯救者R9000P 网卡型号 Realtek PCle GbE Family Controller Realtek 8852CE WiFi 6E PCI-E NIC 系统版本 Ubuntu 24.04 / mint 22.1 问题现象 rtw89_8852ce,Link is Down,xtal si not ready,mac init fail,xtal si not …...

Python训练营打卡 Day46

道注意力(SE注意力) 知识点回顾: 不同CNN层的特征图:不同通道的特征图什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。通道注意力:模型的定义和插入的位置通道注意力后…...

解决微软应用商店 (Microsoft store) 打不开,无网络连接的问题!

很多小伙伴都会遇见微软应用商店 (Microsoft store)打开后出现无网络的问题,一般出现这种问题基本都是因为你的电脑安装了某些银行的网银工具,因为网银工具为了安全会关闭Internet 选项中的最新版本的TLS协议,而微软商店又需要最新的TLS协议才…...

《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》|文献速递-深度学习医疗AI最新文献

Title 题目 Preoperative fracture reduction planning for image-guided pelvic trauma surgery: A comprehensive pipeline with learning 《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》 01 文献速递介绍 《影像引导下骨盆创伤手术的术前…...

如何使用Webhook触发器,在 ONLYOFFICE 协作空间构建智能工作流

在数字化办公中,ONLYOFFICE 协作空间作为一款功能强大的文档协作平台,提供了丰富的自动化功能。对于开发者而言,Webhook 触发器是实现业务流程自动化与系统集成的关键工具。本文将深入探讨如何在 ONLYOFFICE 协作空间中高效利用 Webhook&…...

跟我学c++中级篇——理解类型推导和C++不同版本的支持

一、类型推导 在前面反复分析过类型推导(包括前面提到的类模板参数推导CTAD),类型推导其实就是满足C语言这种强类型语言的要求即编译期必须确定对象的数据类型。换一句话说,理论上如果编译器中能够自动推导所有的相关数据类型&am…...

什么是DevOps智能平台的核心功能?

在数字化转型的浪潮中,DevOps智能平台已成为企业提升研发效能、加速产品迭代的核心工具。然而,许多人对“DevOps智能平台”的理解仍停留在“自动化工具链”的表层概念。今天,我们从一个真实场景切入:假设你是某互联网公司的技术负…...

Windows账户管理,修改密码,创建帐户...(无需密码)

前言 我们使用wWindows操作系统时,账户是非常重要的概念 它不仅能够帮助我们区分文档主题权限等等 嗯还有最重要的解锁电脑的作用! 但想要管理他,不仅需要原本的密码,而且设置中的管理项也非常的不全。 Windows有一款netplwi…...

软件功能模块归属论证方法

文章目录 **一、核心设计原则****二、论证方法****三、常见决策模式****四、验证方法****五、反模式警示****总结** 在讨论软件功能点应该归属哪些模块时,并没有放之四海而皆准的固定方法,但可以通过系统化的论证和设计原则来做出合理决策。以下是常见的…...

【Java后端基础 005】ThreadLocal-线程数据共享和安全

📚博客主页:代码探秘者 ✨专栏:文章正在持续更新ing… ✅C语言/C:C(详细版) 数据结构) 十大排序算法 ✅Java基础:JavaSE基础 面向对象大合集 JavaSE进阶 Java版数据结构JDK新特性…...

【C语言】C语言经典小游戏:贪吃蛇(下)

文章目录 一、游戏前准备二、游戏开始1、游戏开始函数(GameStart)1)打印欢迎界⾯(WelcomeToGame)2)创建地图(CreateMap)3)初始化蛇⾝(InitSnake)4…...

NTT印地赛车:数字孪生技术重构赛事体验范式,驱动观众参与度革命

引言:数字孪生技术赋能体育赛事,开启沉浸式观赛新纪元 在传统体育赛事观赛模式遭遇体验天花板之际,NTT与印地赛车系列赛(NTT INDYCAR SERIES)的深度合作,通过数字孪生(Digital Twin&#xff09…...

30.【新型数据架构】-区块链数据架构

30.【新型数据架构】-区块链数据架构:分布式账本,不可篡改性,用于数据溯源 一、区块链数据架构的本质:分布式账本的革新 区块链的核心是分布式账本技术(Distributed Ledger Technology, DLT),它颠覆了传统中心化数据库的架构模式: 去中心化存储: 账本数据不再集中存储…...

使用docker 安装Redis 带配置文件(x86和arm)版本

一、安装redis 1.1 拉去ARM镜像(7.4.2) docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/linux_arm64_redis:latest1.2 拉去x86镜像(8.0.1)版本 docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/redis:latest新建文件夹 mkd…...

在CSDN发布AWS Proton解决方案:实现云原生应用的标准化部署

引言:云原生时代的部署挑战 在云原生应用开发中,基础设施管理的复杂性已成为团队面临的核心挑战。随着微服务架构的普及,每个服务可能包含数十个AWS资源(如Lambda、API Gateway、ECS集群等),传统的手动配置…...

小白的进阶之路系列之十----人工智能从初步到精通pytorch综合运用的讲解第三部分

本文将介绍Autograd基础。 PyTorch的Autograd特性是PyTorch灵活和快速构建机器学习项目的一部分。它允许在一个复杂的计算中快速而简单地计算多个偏导数(也称为梯度)。这个操作是基于反向传播的神经网络学习的核心。 autograd的强大之处在于它在运行时动态地跟踪你的计算,…...

[蓝桥杯]整理玩具

整理玩具 题目描述 小明有一套玩具,一共包含 NMNM 个部件。这些部件摆放在一个包含 NMNM 个小格子的玩具盒中,每个小格子中恰好摆放一个部件。 每一个部件上标记有一个 0 ~ 9 的整数,有可能有多个部件标记相同的整数。 小明对玩具的摆放有…...

C++11 Move Constructors and Move Assignment Operators 从入门到精通

文章目录 一、引言二、基本概念2.1 右值引用(Rvalue References)2.2 移动语义(Move Semantics) 三、移动构造函数(Move Constructors)3.1 定义和语法3.2 示例代码3.3 使用场景 四、移动赋值运算符&#xff…...

JavaScript 中的单例内置对象:Global 与 Math 的深度解析

JavaScript 中的单例内置对象:Global 与 Math 的深度解析 在 JavaScript 的世界中,单例内置对象是开发者必须了解的核心概念之一。它们是语言规范中预定义的对象,无需显式创建即可直接使用。本文将深入解析 JavaScript 中最重要的两个单例内…...

11 - ArcGIS For JavaScript -- 高程分析

这里写自定义目录标题 描述代码实现结果 描述 高程分析是地理信息系统(GIS)中的核心功能之一&#xff0c;主要涉及对地表高度数据(数字高程模型, DEM)的处理和分析。 ArcGIS For JavaScript4.32版本的发布&#xff0c;提供了Web端的针对高程分析的功能。 代码实现 <!doct…...

通道注意力

一、 什么是注意力 其中注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器&#xff0c;就像人类视觉会自动忽略背景&#xff0c;聚焦于图片中的主体&#xff08;如猫、汽车&#xff09;。 transformer中的叫做自注意力机制&#xff0c;他是一种自己学习自己的机制…...

2048游戏的技术实现分析-完全Java和Processing版

目录 简介Processing库基础项目构建指南项目结构核心数据结构游戏核心机制图形界面实现性能优化代码详解设计模式分析测试策略总结与展望简介 2048是一款由Gabriele Cirulli开发的经典益智游戏。本文将深入分析其Java实现版本的技术细节。该实现使用了Processing库来创建图形界…...