基于Java的抽奖逻辑

您所在的位置:网站首页 抽奖人数应该设置几人 基于Java的抽奖逻辑

基于Java的抽奖逻辑

2023-10-21 18:49| 来源: 网络整理| 查看: 265

小组在做一个抽奖系统,现在给我分配到了抽奖逻辑这方面的实现。 EMMM,拿到分配的时候是懵B的。

老大给的需求图 给的关键表结构

DROP TABLE IF EXISTS `dd_annual_meeting_check`; CREATE TABLE `dd_annual_meeting_check` ( `check_id` int(255) NOT NULL AUTO_INCREMENT COMMENT '主键', `check_prize_id` varchar(255) NOT NULL COMMENT '抽奖Id', `emp_id` int(10) NOT NULL COMMENT '中奖员工id', `emp_prize_time` varchar(255) NOT NULL COMMENT '中奖时间', `check_receive` varchar(100) NOT NULL COMMENT '核销 0-已经核销 1-未核销', `check_user_id` int(10) DEFAULT NULL COMMENT '核销工作人员(对于员工id)', `check_time` varchar(255) DEFAULT NULL COMMENT '核销时间', PRIMARY KEY (`check_id`) ) ENGINE=InnoDB AUTO_INCREMENT=158 DEFAULT CHARSET=utf8 COMMENT='中奖池信息表'; DROP TABLE IF EXISTS `dd_annual_meeting_prize`; CREATE TABLE `dd_annual_meeting_prize` ( `prize_id` varchar(255) NOT NULL COMMENT '主键', `prize_name` varchar(100) NOT NULL COMMENT '抽奖名称', `prize_num` varchar(100) NOT NULL COMMENT '抽奖总人数', `prize_count` varchar(100) NOT NULL COMMENT '每次中奖人数', `prize_range` varchar(100) DEFAULT NULL COMMENT '抽奖范围: 0-all 1-未中奖', `prize_state` varchar(100) DEFAULT NULL COMMENT '状态: 0-待抽 1-抽中 2-已抽', `prize_date` varchar(255) DEFAULT NULL COMMENT '状态时间', `leader_id` int(10) NOT NULL COMMENT '抽奖领导Id', `giver_id` int(10) DEFAULT NULL COMMENT '加奖人Id', `prize_detial` varchar(100) NOT NULL COMMENT '抽奖详情', `giver_state` varchar(255) DEFAULT '0' COMMENT '是否加奖 0-否 1-是', PRIMARY KEY (`prize_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖池信息表'; DROP TABLE IF EXISTS `dd_annual_meeting_user`; CREATE TABLE `dd_annual_meeting_user` ( `u_id` int(10) NOT NULL AUTO_INCREMENT, `user_id` varchar(100) NOT NULL COMMENT '员工工号', `user_name` varchar(100) NOT NULL COMMENT '员工姓名', `user_time` varchar(255) DEFAULT NULL COMMENT '扫码时间', `user_type` varchar(100) DEFAULT NULL COMMENT '身份: 0-普通员工 1-领导 2-工作人员', `user_state` varchar(100) DEFAULT NULL COMMENT '状态: 1-已领取0-未领取', `state_date` varchar(255) DEFAULT NULL COMMENT '状态时间', `user_prize` varchar(255) NOT NULL COMMENT '奖票号', PRIMARY KEY (`u_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3423 DEFAULT CHARSET=utf8 COMMENT='人员信息表';

追加:

-- ---------------------------- -- Table structure for dd_annual_meeting_record -- ---------------------------- DROP TABLE IF EXISTS `dd_annual_meeting_record`; CREATE TABLE `dd_annual_meeting_record` ( `record_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `record_prize_id` int(10) NOT NULL COMMENT '抽奖id', `record_times` int(10) NOT NULL COMMENT '第几轮', `record_over` int(10) NOT NULL COMMENT '剩余次数', `record_count` int(10) NOT NULL COMMENT '每次中奖数', `record_state` varchar(100) NOT NULL COMMENT '进行状态 0-未开始 1-已结束', PRIMARY KEY (`record_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of dd_annual_meeting_record -- ----------------------------

没有多余讲解,就一句话,“需求是这样,怎样实现我不管。”这是老大的座右铭。 可我特么的是新手啊,难受啊,马飞! 好吧,其实是说业务流程和其他表结构并没有最终确定,先做个大概的抽奖逻辑出来,咱就按照表结构和自己的意思做一把思想上的巨人。

先从第一个开始(一二三等奖不能重复获得)

分析下表结构:

一共三张表,中奖池信息表dd_annual_meeting_check,这个比较容易理解,就是将得到的中奖人的id和奖 项id插入这张表。 抽奖池信息表dd_annual_meeting_prize,这张表看来是获取抽奖信息的来源。 人员信息表dd_annual_meeting_user,这个就是用来得到抽奖人集合的表了。

分析下抽奖的过程: 抽奖池信息表里面信息已经定好了不用我管 ,假设人员信息表有100个人参与活动。

第一次抽奖(一等奖) 从100人中抽5个人来中奖,但是要分5次抽完,每次抽1人。

第二次抽奖(二等奖)从95人(中了一次奖的人,不参与抽奖)中抽10个人来中奖,每次抽5人出来,要抽2次。

第三次抽奖(二等奖)从85人(中了一次奖的人,不参与抽奖)中抽5个人来中奖,每次抽1人,抽5次。 来个图:

思路图

实现逻辑大致思路:

1.从人员信息表获得所有参与人员的数量

2.根据页面数据判断抽的什么奖励

3.从抽奖池信息表中获得抽奖主键id(prize_id),抽奖总人数(prize_num),每次中奖人数(prize_count),抽奖人领导id(leader_id)

4.进行抽奖,从人数中抽出对应的数字,根据数字去人员表中得到对应的人员信息

5.将中奖人信息与奖项信息绑定,添加到中奖池信息表

简单的分析后,有了大致思路,细节什么的就在代码中完成:

一,先弄两个页面出来,一个是显示中奖信息的页面,另外一个是发送抽奖指令的页面(因为是领导来点击抽奖,所以有一个领导信息需要发送过来)。 抽奖页面

奖品列表!!!!!!!!!!!!

var psel = document.getElementById("poe"); window.onload=function (){ websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); websocket.onmessage = function(msg) { console.log(msg.data); $.ajax({ url:"test2", type:"POST", data:{ msg:msg.data, peo:psel.value }, dataType : "json", success : function (rtn) { console.log("Successfully"); console.log(rtn); if(rtn.list != null){ var inf = ''; inf += "获奖人id获奖人姓名获奖人奖券号" /**/ var stu = rtn.list[i]; inf += ""+stu.user_id+""+stu.user_name+""+stu.user_prize+"" } inf += "" $("#showData").html(inf); } if(rtn.poe != null){ psel.value = rtn.poe; } } }); } } //发送消息测试页面 发送消息测试页面 Sorry,浏览器不支持WebSocket 发送 var websocket=null; window.onload=function (){ if ('WebSocket' in window) { console.log("1"); websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); } else if ('MozWebSocket' in window) { console.log("2"); websocket = new MozWebSocket("ws://127.0.0.1:8080/websocket"); } else { websocket = new SockJS("ws://127.0.0.1:8080/websocket"); } //websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); websocket.onmessage = function(msg) { console.log(msg.data); } } function send() { var message = document.getElementById('text').value; console.log(message); websocket.send(message); }

这是之前写的用websocket来实时传值的两个页面,稍微改了改。

二,写Controller层代码

先把两个页面的请求写出来

@Controller @RequestMapping("/hello") public class WsController { //测试页面 @RequestMapping("/test1") public String test() throws IOException{ return "showlist"; } //消息发送页面 @RequestMapping("/test3") public String test2() throws IOException{ return "ws2"; }

剩下的就是抽奖逻辑代码 和数据库脚本代码了,细节如何构思的就不说了,脑壳疼,一边想着怎么做,然后老大那边又说这个流程这么走,不不不,那么走,嗯嗯嗯,还是这么走。

//抽奖测试 @Autowired private TestDao testDao; @ResponseBody @RequestMapping("/test2") public Map test(@RequestParam("msg") String msg,@RequestParam("peo") List peo) throws IOException { String prize_name = "第一轮抽奖"; //收到页面传来数据msg(抽奖人id),prize_name(抽取的奖项)获得抽奖信息 Map priz_info = testDao.findPrizinfo(msg,prize_name); //定义一个最终传回值的集合 Map m1 = new HashMap(); if(priz_info != null) { //判断peo数据如果没人数数据 添加数据 if(peo.isEmpty()) { //n为人员总数 int n = testDao.findAll(); for(int i = 0; i < n;i++) { peo.add(i); } } System.out.println("当前抽奖总人数为:"+peo); //定义一个最终获奖人id的集合 ArrayList dIdList = new ArrayList(); //定义一个获取抽奖结果的集合 Map m2 = new HashMap(); //得到抽奖次数 int count = Integer.parseInt(priz_info.get("prize_num")) / Integer.parseInt(priz_info.get("prize_count")) ; for(int i = 0; i < count;i++) { //进行抽奖并获得结果集 m2 = luck(peo,Integer.parseInt( priz_info.get("prize_count"))); //得到中奖人id集合 dIdList.addAll((List)m2.get("eidList")); //得到剩余人数 peo = (List) m2.get("idList"); //将每一次抽奖的状态改变 testDao.update(priz_info.get("prize_id"), i+1); } System.out.println("获奖id:"+dIdList); System.out.println("最后人数:"+peo); //循环获得LIST 中奖人信息 ArrayList infoList = new ArrayList(); for(int i = 0;i < dIdList.size();i++) { infoList.add(testDao.findById(dIdList.get(i))); } //为返回值传入参数 //获奖信息 m1.put("list", infoList); //未中奖人 m1.put("poe", peo); } return m1; } //抽奖 传参 1.总人数 3,几人中奖 Map luck(List idList,int n) { //取得中奖人id ArrayList a = makeRandom(0,idList.size(), n); System.out.println("中奖的数字为"+a); //获奖id临时存储集合 ArrayList eidList = new ArrayList(); //排序 Object[] b = a.toArray(); Arrays.sort(b); //定义一个中奖人数据集合 List t = new ArrayList(); for(int i = 0; i < b.length;i++) { eidList.add(idList.get((int) b[i])); System.out.println("中奖的id为"+idList.get((int) b[i])); t.add(idList.get((int) b[i])); } //总人数中移除中奖人数据 idList.removeAll(t); //写到Map集合回传 Map m = new HashMap(); //剩余id m.put("idList", idList); //获奖id m.put("eidList", eidList); return m; } //从x-y 取num个随机数 ArrayList makeRandom(int x, int y, int num) { //创建一个integer的动态数组 ArrayList a = new ArrayList(); int index = 0; //往数组里面逐一加取到不重复的元素 while(index < num) { //产生x-y的随机数 Random r = new Random(); int temp = r.nextInt(y-x)+x ; //设置是否重复的标记变量为false boolean flag = false; for(int i =0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3