Repository: fuzhengwei/Lottery
Branch: main
Commit: 8457679abd80
Files: 50
Total size: 76.9 KB
Directory structure:
gitextract_3lapcxae/
├── .gitignore
├── LICENSE
├── README.md
├── lottery-application/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── package-info.java
├── lottery-common/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── cn/
│ └── itedus/
│ └── lottery/
│ └── common/
│ ├── Constants.java
│ └── Result.java
├── lottery-domain/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── cn/
│ └── itedus/
│ └── lottery/
│ └── domain/
│ └── strategy/
│ ├── model/
│ │ ├── aggregates/
│ │ │ └── StrategyRich.java
│ │ ├── req/
│ │ │ └── DrawReq.java
│ │ ├── res/
│ │ │ └── DrawResult.java
│ │ └── vo/
│ │ └── AwardRateInfo.java
│ ├── repository/
│ │ ├── IStrategyRepository.java
│ │ └── impl/
│ │ └── StrategyRepository.java
│ └── service/
│ ├── algorithm/
│ │ ├── BaseAlgorithm.java
│ │ ├── IDrawAlgorithm.java
│ │ └── impl/
│ │ ├── DefaultRateRandomDrawAlgorithm.java
│ │ └── SingleRateRandomDrawAlgorithm.java
│ └── draw/
│ ├── DrawBase.java
│ ├── DrawConfig.java
│ ├── IDrawExec.java
│ └── impl/
│ └── DrawExecImpl.java
├── lottery-infrastructure/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── cn/
│ └── itedus/
│ └── lottery/
│ └── infrastructure/
│ ├── dao/
│ │ ├── IActivityDao.java
│ │ ├── IAwardDao.java
│ │ ├── IStrategyDao.java
│ │ └── IStrategyDetailDao.java
│ └── po/
│ ├── Activity.java
│ ├── Award.java
│ ├── Strategy.java
│ └── StrategyDetail.java
├── lottery-interfaces/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── cn/
│ │ │ └── itedus/
│ │ │ └── lottery/
│ │ │ ├── LotteryApplication.java
│ │ │ └── interfaces/
│ │ │ └── ActivityBooth.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── mybatis/
│ │ ├── config/
│ │ │ └── mybatis-config.xml
│ │ └── mapper/
│ │ ├── Activity_Mapper.xml
│ │ ├── Award_Mapper.xml
│ │ ├── StrategyDetail_Mapper.xml
│ │ └── Strategy_Mapper.xml
│ └── test/
│ └── java/
│ └── cn/
│ └── itedus/
│ └── lottery/
│ └── test/
│ ├── ApiTest.java
│ ├── DrawAlgorithmTest.java
│ └── SpringRunnerTest.java
├── lottery-rpc/
│ ├── pom.xml
│ └── src/
│ └── main/
│ └── java/
│ └── cn/
│ └── itedus/
│ └── lottery/
│ └── rpc/
│ ├── IActivityBooth.java
│ ├── dto/
│ │ └── ActivityDto.java
│ ├── req/
│ │ └── ActivityReq.java
│ └── res/
│ └── ActivityRes.java
└── pom.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践
[](https://t.zsxq.com/jAi2nUf)
- **加入项目**:[https://t.zsxq.com/jAi2nUf](https://t.zsxq.com/jAi2nUf) - 加入后在星球置顶消息可以申请加入项目组,`公众号:bugstack虫洞栈 回复:星球 可以获得加入优惠券`
- **代码仓库**:[https://gitcode.net/KnowledgePlanet/Lottery](https://gitcode.net/KnowledgePlanet/Lottery) - `必须加入星球:码农会锁,在置顶🔝消息,申请授权后才可以访问。`
- **小册地址**:[https://gitcode.net/KnowledgePlanet/Lottery/-/wikis/home](https://gitcode.net/KnowledgePlanet/Lottery/-/wikis/home) - `小册地址会有专门的学习目录,授权后可访问`
---
**本文接下来的阅读,会帮助你🔜快速进入项目学习,这里包括:项目的起始、涉及的技术、环境的配置、代码的拉取、学习的方式,请一定仔细阅读!**
写CRUD、堆API、改屎山⛰,熬多少个996也只是成为重复的螺丝钉。如果你希望捅破现有工作的瓶颈,拉高一下对技术的认知,那么就非常需要一个大项目来贯穿常用技术栈的知识体系。*碎片化断层的背八股文,是解决不了这个事情*
那怎么办?当然是要肝项目了,肝一个`有互联网技术体系`、`有分布式架构运用`、`有DDD思想和设计模式实践`的真实场景项目,才能让一个尚未接触此类项目或是长期陷入CURD的熟练工,打开视野,快速成长起来。
**整整半年**,小傅哥都在做这件事情,直到今天才完成整个系统的第一期设计实现和落地。在这个[《分布式抽奖系统》](#)项目中,我会带着大家以DDD架构和设计模式落地实战的方式,进行`代码开发`、`视频介绍`、`文档说明`的方式讲解和实现分布式抽奖系统,那么这里会涉及到很多DDD的设计思路和设计模式应用,以及互联网大厂开发中所应用到的技术,包括:SpringBoot、Mybatis、Dubbo、MQ、Redis、Mysql、ELK、分库分表、Otter 等。
在加入项目之前,你可以仔细阅读如下的介绍信息,方便你能更加快速的进入学习。*一点点投资,为你3月-4月,拿一个更高更靠谱的Offer*
## 一、咋,撸个项目?
**在这之前一直有粉丝伙伴问傅哥**,有没有能`上手练习技术的项目`,现在学了这么多技术知识、看了这么多设计模式、搜了这么多架构设计,但这些内容都是怎么结合在一起使用的呢?互联网中的项目架构设计是什么样的呢?我该怎么开始学到什么样才能进大厂呢?
| 项目学习意见(收集结果) |
| ---- |
|  |
- [项目学习意见(收集结果).xlsx](https://gitcode.net/KnowledgePlanet/Lottery/-/blob/master/doc/assets/excel/%E9%A1%B9%E7%9B%AE%E5%AD%A6%E4%B9%A0%E6%84%8F%E8%A7%81%EF%BC%88%E6%94%B6%E9%9B%86%E7%BB%93%E6%9E%9C%EF%BC%89.xlsx)
`咋neng呢,撸个项目吧!` 在撸项目开始之前,做了一次项目学习意见调研,问了问大家:“想做个什么项目,如;积分商城、抽奖系统、活动系统、监控系统、技术组件,并且这些项目中用到了哪些技术栈。” 最后在大家的意见反馈中,先以开发互联网中C端类项目 **抽奖系统** 开始,这样一个项目可以让大家在系统的`架构搭建`、`功能配置`、`服务开发`中学习到关于一些关于解决`高并发`、`高性能`、`高可用`场景时的技术实践运用。*放心,其他类的互联网项目,我们也会陆续的折腾起来!*
So!基于DDD领域驱动设计的四层架构**抽奖系统**,开始啦!有座,这趟车的你跟上!
## 二、呀,能学东西!

一个以真实场景`实践技术栈整合`开发实际需求的项目,势必会因为要完成需求而引入各项技术栈的使用,也会由于要解决互联网中C端场景中的三高问题,而使用相应的技术实现不同类别解决与方案,我们也可以把此类解决方案理解为DDD中的业务领域模型开发。在这个设计和开发的过程中会涉及到`架构设计`、`技术应用`、`场景实现`,每一块内容都会有非常多的实践知识,可以让读者学到东西。
### 1. 涉及技术
在此项目中你会学习到互联网公司关于C端项目开发时候用到的一些,技术、架构、规范等内容。由于项目为实战类编程项目,在学习的过程中需要上手操作,小傅哥会把系统的搭建拉不同的分支列为每一个章节进行设计和实现并记录到开发日记中,读者在学习的过程中可以结合这部分内容边看文章边写代码实践。

- 技术:JDK 1.8、SpringBoot、Mybatis、Dubbo、MQ、Redis、Mysql、ELK、分库分表、Otter、vue、微信公众号、Docker
- 架构:DDD 领域驱动设计、充血模型、设计模式
- 规范:分支提交规范、代码编写规范
**其他所需环境如下(mysql\kafka\zk\redis\xxl-job):**

- 不只是 DDD 分布式项目开发,你还可以学习到关于 Docker 的实践使用
### 2. 系统架构

- 此系统架构为 DDD 领域驱动设计的四层架构实现方式,以重视代码实现落地的方式向读者介绍和展示如何开发这样的代码。
- 在 Domain 领域层逐步通过拆解系统流程设计,按照职责边界的领域模块进行设计和开发,最终在应用层进行逻辑功能编排。
- 这个系统中会体现出很多的设计模式思想和最终的实现,只有把 DDD 和设计模式结合起来,才能开发出更加易于扩展和维护的代码结构。
### 3. 分布式设计

整体系统架构设计包含了6个工程:
1. Lottery:分布式部署的抽奖服务系统,提供抽奖业务领域功能,以分布式部署的方式提供 RPC 服务。
2. Lottery-API:网关API服务,提供;H5 页面抽奖、公众号开发回复消息抽奖。
3. Lottery-Front:C端用户系统,vue H5 lucky-canvas 大转盘抽奖界面,讲解 vue 工程创建、引入模块、开发接口、跨域访问和功能实现
4. Lottery-ERP:B端运营系统,满足运营人员对于活动的查询、配置、修改、审核等操作。
5. DB-Router:分库分表路由组件,开发一个基于 HashMap 核心设计原理,使用哈希散列+扰动函数的方式,把数据散列到多个库表中的组件,并验证使用。
6. Lottery-Test:测试验证系统,用于测试验证RPC服务、系统功能调用的测试系统。
📢 **注意**:db-router-spring-boot-starter 为自研数据库路由组件,你需要下载代码到本地,自行构建到本地仓库进行使用。*章节中也会介绍这个路由组件的设计和开发*
### 4. 凝练流程领域

- 拆解功能流程,提炼领域服务,一步步教会你把一个业务功能流程如何拆解为各个职责边界下的领域模块,在通过把开发好的领域服务在应用层进行串联,提供整个服务链路。
- 通过这样的设计和落地思想,以及在把流程化的功能按照面向对象的思路使用设计模式进行设计,让每一步代码都变得清晰易懂,这样实现出来的代码也就更加易于维护和扩展了。
- 所以,你在这个过程中学会的不只是代码开发,还有更多的落地思想实践在这里面体现出来。也能为你以后开发这样的一个项目或者在面试过程中,一些实际复杂场景问题的设计思路,打下不错的基础。
## 三、呐,怎么开始?
### 🔜 快速加入
为了能让读者伙伴快速🔜进入项目学习,可以按照下面的步骤开始:
1. 加入知识星球:[`码农会锁`](https://t.zsxq.com/jAi2nUf) 通过在公众号:`bugstack虫洞栈` 回复:`星球` 获取优惠券加入,也可以点击链接加入:[https://t.zsxq.com/jAi2nUf](https://t.zsxq.com/jAi2nUf)
2. 【入口】[Lottery](https://gitcode.net/KnowledgePlanet/Lottery) 项目主入口中有一个 README.md 有关于项目的学习说明、开发规范、章节目录和问题交流提交issue说明以及群内交流,在学习的过程中可以参考使用。
3. 【文章】每一个章节内容中都会包括;需求、实现、验证、细节,四块内容的介绍,以及当前章节中对应的代码分支可以切换学习。
4. 【代码】在代码学习的过程中可以克隆工程进行开发练习,也可以给主工程小傅哥工程代码提交PR、ISSUE,我会去审核和合并以及不断的完善代码。
### 📝 学习说明(小册、源码、视频)
课程包括:`小册`、`视频`、`代码`、`作业`,四方面结合的方式进行学习,所以也能让即使缺少编码经验的在校学生、应届生或者是CRUD熟练工,都能快速加入项目进行学习。

- 课程分为:`大厂规范`、`领域开发`、`运营后台`、`应用场景`、`系统运维`,共5章34节来讲解DDD分布式系统的架构设计和实践落地。
- 只要你能认真跟着敲下来,22年的 Offer 不会便宜!*真的是研发能力有差异吗,其实不是,你差的只是一个有人带着你肝的大型系统而已!*
**Lottery 抽奖系统** - 基于领域驱动设计的四层架构实践 `只有加入知识星球:码农会锁 申请加入项目组以下链接才能访问`
1. 代码:[https://gitcode.net/KnowledgePlanet/Lottery](https://gitcode.net/KnowledgePlanet/Lottery)
2. 小册:[https://gitcode.net/KnowledgePlanet/Lottery/-/wikis/home](https://gitcode.net/KnowledgePlanet/Lottery/-/wikis/home)
3. 提问:[https://gitcode.net/KnowledgePlanet/Lottery/-/issues](https://gitcode.net/KnowledgePlanet/Lottery/-/issues)
4. 介绍:[https://articles.zsxq.com/id_tz44w3oqjftv.html](https://articles.zsxq.com/id_tz44w3oqjftv.html)
注意:在项目学习的过程中,如果遇到问题可以先查看 issue,一般大家的共性问题都会在这里体现。如果你没有搜到与你相同的问题,也可以提一个新的 issue,可以包括:学习疑惑、Bug提醒、优化建议、技术分享等。
### 🎨 环境配置
- **技术栈项**:JDK1.8、Maven3.6.3、Mysql5.7(可升级配置),SpringBoot、Mybatis、Dubbo 随POM版本
- **初始打包**:你需要在 Lottery 工程的 Maven 根上,点击 Install 这样才能完整打包,否则 Lottery-Test 等,不能正常引入 Jar 包
- **建表语句**:[doc/asserts/sql](https://gitcode.net/KnowledgePlanet/Lottery/-/blob/master/doc/assets/sql/lottery.sql) - `建议随非分支内sql版本走,因为需求不断迭代升级优化,直接使用最新的会遇到在各个分支下的代码运行问题`
- **代码仓库**:`2种使用方式`
- 密码方式:登录的用户ID为 CSDN 个人中心的用户ID,[https://i.csdn.net/#/user-center/profile](https://i.csdn.net/#/user-center/profile) 密码为 CSDN 登录密码。如果没有密码或者忘记,可以在 CSDN 登录页找回密码。
- SSH 秘钥免登录方式,设置:[https://gitcode.net/-/profile/keys](https://gitcode.net/-/profile/keys) 文档:[生成 SSH 密钥](https://gitcode.net/codechina/help-docs/-/wikis/docs/ssh#%E7%94%9F%E6%88%90-ssh-%E5%AF%86%E9%92%A5)
- **学习使用**:下载代码库后,切换本地分支到wiki中章节对应的分支,这样代码与章节内容是对应的,否则你在master看到的是全量代码。
- **下载依赖**:[db-router-spring-boot-starter](https://gitcode.net/KnowledgePlanet/db-router-spring-boot-starter) 本项目依赖自研分库分表组件,需要可以用IDEA像打开一个项目一样打开,之后点击 Maven Install 这样就把 Jar 打包到你本地仓库了,Lottery 就可以引入这个 Jar 了
### 📐 开发规范
**分支命名**:日期_姓名首字母缩写_功能单词,如:`210804_xfg_buildFramework`
**提交规范**:`作者,type: desc` 如:`小傅哥,fix:修复查询用户信息逻辑问题` *参考Commit message 规范*
```java
# 主要type
feat: 增加新功能
fix: 修复bug
# 特殊type
docs: 只改动了文档相关的内容
style: 不影响代码含义的改动,例如去掉空格、改变缩进、增删分号
build: 构造工具的或者外部依赖的改动,例如webpack,npm
refactor: 代码重构时使用
revert: 执行git revert打印的message
# 暂不使用type
test: 添加测试或者修改现有测试
perf: 提高性能的改动
ci: 与CI(持续集成服务)有关的改动
chore: 不修改src或者test的其余修改,例如构建过程或辅助工具的变动
```
### 🐾 学习作业
- 你可以在星球APP中提交`作业题目` | 网页提交:[https://t.zsxq.com/MvFYJe2](https://t.zsxq.com/MvFYJe2)
1. 今天的你学到了哪个章节?
2. 遇到什么问题?
3. 怎么解决的?
4. 掌握到了什么知识?
基于大家的学习反馈,小傅哥会在后续的直播中统一解决相关学习问题。加油,这趟车人人有收获!
注意️:按照作业提交频次和质量,小傅哥会组织一波奖品。**按照作业提交数量、质量、点赞、留言,综合评分,送技术图书等奖品。**
<img src="https://bugstack.cn/images/article/project/lottery/introduce/job.jpg" width="414" height="891"/>
- 也可以提交 issue:[https://gitcode.net/KnowledgePlanet/Lottery/-/issues](https://gitcode.net/KnowledgePlanet/Lottery/-/issues)
**课代表作业**
`讲真,我遇到了一个懂我的人!`
在星球实战项目学习中,有一个女课代表,每一次交作业提交都可以用精致来形容,她的学习速度超级快,也可以非常清晰的分析出每一块的流程并配上流程图,如下:

- 我也希望有更多的优秀的你,与我一起学习、成长、赚钱,22年,我们加油!
## 四、来,上我的车!
### 1. 你会学到什么
- 分布式系统架构如何开发(`RPC`、`MQ`、`分布式任务`、`分库分表`)
- DDD 四层架构设计与设计模式的结合落地
- 互联网大厂的代码开发规范、需求评审、运维监控
- Docker 运维实践,环境、部署、配置、监控、日志等
### 2. 适宜人群
- 具备 Java 编程基础的研发人员,想提升自己的技术能力
- 希望提升编码思维,剔除到代码中的坏味道
- 有意愿成为架构师,但还处在一定瓶颈期
- 想加入大厂做码农,但总感觉找不到门路
---
🚌 `来吧,上车,还有座!`
动手、动手、动手,一个实践类型的项目最需要的就是你动起手来,只有这样你才能发现各种问题细节的处理。更何况哪怕在别人电脑💻上运行的再顺畅的代码,在你那也可能*拉跨*,不过没关系因为所有拉跨的过程都将是你抓住学习的点!
我一直坚持很多事情要慢下来,希望你也不要过于的着急快,火急火燎不是学习的长久过程,而迟迟以恒才能让你的收获更加丰满。趁着时间还多正当年恰,坚持做好自己想做的事情吧!
================================================
FILE: lottery-application/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lottery-application</artifactId>
</project>
================================================
FILE: lottery-application/src/main/java/package-info.java
================================================
/**
* 应用层{application}
*
* - 应用服务位于应用层。用来表述应用和用户行为,负责服务的组合、编排和转发,负责处理业务用例的执行顺序以及结果的拼装。
* - 应用层的服务包括应用服务和领域事件相关服务。
* - 应用服务可对微服务内的领域服务以及微服务外的应用服务进行组合和编排,或者对基础层如文件、缓存等数据直接操作形成应用服务,对外提供粗粒度的服务。
* - 领域事件服务包括两类:领域事件的发布和订阅。通过事件总线和消息队列实现异步数据传输,实现微服务之间的解耦。
*/
================================================
FILE: lottery-common/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>lottery-common</artifactId>
<build>
<finalName>lottery-common</finalName>
<plugins>
<!-- 编译plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<compilerVersion>1.8</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: lottery-common/src/main/java/cn/itedus/lottery/common/Constants.java
================================================
package cn.itedus.lottery.common;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*
* 枚举信息定义
*/
public class Constants {
public enum ResponseCode {
SUCCESS("0000", "成功"),
UN_ERROR("0001","未知失败"),
ILLEGAL_PARAMETER("0002","非法参数"),
INDEX_DUP("0003","主键冲突");
private String code;
private String info;
ResponseCode(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
}
}
================================================
FILE: lottery-common/src/main/java/cn/itedus/lottery/common/Result.java
================================================
package cn.itedus.lottery.common;
import java.io.Serializable;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*
* 统一返回对象中,Code码、Info描述
*/
public class Result implements Serializable {
private static final long serialVersionUID = -3826891916021780628L;
private String code;
private String info;
public static Result buildResult(String code, String info) {
return new Result(code, info);
}
public static Result buildSuccessResult() {
return new Result(Constants.ResponseCode.SUCCESS.getCode(), Constants.ResponseCode.SUCCESS.getInfo());
}
public static Result buildErrorResult() {
return new Result(Constants.ResponseCode.UN_ERROR.getCode(), Constants.ResponseCode.UN_ERROR.getInfo());
}
public Result(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
================================================
FILE: lottery-domain/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lottery-domain</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>cn.itedus.lottery</groupId>
<artifactId>lottery-infrastructure</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>lottery-domain</finalName>
<plugins>
<!-- 编译plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<compilerVersion>1.8</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/aggregates/StrategyRich.java
================================================
package cn.itedus.lottery.domain.strategy.model.aggregates;
import cn.itedus.lottery.infrastructure.po.Strategy;
import cn.itedus.lottery.infrastructure.po.StrategyDetail;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class StrategyRich {
// 策略ID
private Long strategyId;
// 策略配置
private Strategy strategy;
// 策略明细
private List<StrategyDetail> strategyDetailList;
public StrategyRich() {
}
public StrategyRich(Long strategyId, Strategy strategy, List<StrategyDetail> strategyDetailList) {
this.strategyId = strategyId;
this.strategy = strategy;
this.strategyDetailList = strategyDetailList;
}
public Long getStrategyId() {
return strategyId;
}
public void setStrategyId(Long strategyId) {
this.strategyId = strategyId;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public List<StrategyDetail> getStrategyDetailList() {
return strategyDetailList;
}
public void setStrategyDetailList(List<StrategyDetail> strategyDetailList) {
this.strategyDetailList = strategyDetailList;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/req/DrawReq.java
================================================
package cn.itedus.lottery.domain.strategy.model.req;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DrawReq {
// 用户ID
private String uId;
// 策略ID
private Long strategyId;
public DrawReq() {
}
public DrawReq(String uId, Long strategyId) {
this.uId = uId;
this.strategyId = strategyId;
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public Long getStrategyId() {
return strategyId;
}
public void setStrategyId(Long strategyId) {
this.strategyId = strategyId;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/res/DrawResult.java
================================================
package cn.itedus.lottery.domain.strategy.model.res;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DrawResult {
// 用户ID
private String uId;
// 策略ID
private Long strategyId;
// 奖品ID
private String rewardId;
// 奖品名称
private String awardName;
public DrawResult() {
}
public DrawResult(String uId, Long strategyId, String rewardId, String awardName) {
this.uId = uId;
this.strategyId = strategyId;
this.rewardId = rewardId;
this.awardName = awardName;
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public Long getStrategyId() {
return strategyId;
}
public void setStrategyId(Long strategyId) {
this.strategyId = strategyId;
}
public String getRewardId() {
return rewardId;
}
public void setRewardId(String rewardId) {
this.rewardId = rewardId;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/vo/AwardRateInfo.java
================================================
package cn.itedus.lottery.domain.strategy.model.vo;
import java.math.BigDecimal;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*
* 奖品概率信息,奖品编号、库存、概率
*/
public class AwardRateInfo {
// 奖品ID
private String awardId;
// 中奖概率
private BigDecimal awardRate;
public AwardRateInfo() {
}
public AwardRateInfo(String awardId, BigDecimal awardRate) {
this.awardId = awardId;
this.awardRate = awardRate;
}
public String getAwardId() {
return awardId;
}
public void setAwardId(String awardId) {
this.awardId = awardId;
}
public BigDecimal getAwardRate() {
return awardRate;
}
public void setAwardRate(BigDecimal awardRate) {
this.awardRate = awardRate;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/repository/IStrategyRepository.java
================================================
package cn.itedus.lottery.domain.strategy.repository;
import cn.itedus.lottery.domain.strategy.model.aggregates.StrategyRich;
import cn.itedus.lottery.infrastructure.po.Award;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public interface IStrategyRepository {
StrategyRich queryStrategyRich(Long strategyId);
Award queryAwardInfo(String awardId);
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/repository/impl/StrategyRepository.java
================================================
package cn.itedus.lottery.domain.strategy.repository.impl;
import cn.itedus.lottery.domain.strategy.model.aggregates.StrategyRich;
import cn.itedus.lottery.domain.strategy.repository.IStrategyRepository;
import cn.itedus.lottery.infrastructure.dao.IAwardDao;
import cn.itedus.lottery.infrastructure.dao.IStrategyDao;
import cn.itedus.lottery.infrastructure.dao.IStrategyDetailDao;
import cn.itedus.lottery.infrastructure.po.Award;
import cn.itedus.lottery.infrastructure.po.Strategy;
import cn.itedus.lottery.infrastructure.po.StrategyDetail;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Component
public class StrategyRepository implements IStrategyRepository {
@Resource
private IStrategyDao strategyDao;
@Resource
private IStrategyDetailDao strategyDetailDao;
@Resource
private IAwardDao awardDao;
@Override
public StrategyRich queryStrategyRich(Long strategyId) {
Strategy strategy = strategyDao.queryStrategy(strategyId);
List<StrategyDetail> strategyDetailList = strategyDetailDao.queryStrategyDetailList(strategyId);
return new StrategyRich(strategyId, strategy, strategyDetailList);
}
@Override
public Award queryAwardInfo(String awardId) {
return awardDao.queryAwardInfo(awardId);
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/BaseAlgorithm.java
================================================
package cn.itedus.lottery.domain.strategy.service.algorithm;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 共用的算法逻辑
*/
public abstract class BaseAlgorithm implements IDrawAlgorithm {
// 斐波那契散列增量,逻辑:黄金分割点:(√5 - 1) / 2 = 0.6180339887,Math.pow(2, 32) * 0.6180339887 = 0x61c88647
private final int HASH_INCREMENT = 0x61c88647;
// 数组初始化长度
private final int RATE_TUPLE_LENGTH = 128;
// 存放概率与奖品对应的散列结果,strategyId -> rateTuple
protected Map<Long, String[]> rateTupleMap = new ConcurrentHashMap<>();
// 奖品区间概率值,strategyId -> [awardId->begin、awardId->end]
protected Map<Long, List<AwardRateInfo>> awardRateInfoMap = new ConcurrentHashMap<>();
@Override
public void initRateTuple(Long strategyId, List<AwardRateInfo> awardRateInfoList) {
// 保存奖品概率信息
awardRateInfoMap.put(strategyId, awardRateInfoList);
String[] rateTuple = rateTupleMap.computeIfAbsent(strategyId, k -> new String[RATE_TUPLE_LENGTH]);
int cursorVal = 0;
for (AwardRateInfo awardRateInfo : awardRateInfoList) {
int rateVal = awardRateInfo.getAwardRate().multiply(new BigDecimal(100)).intValue();
// 循环填充概率范围值
for (int i = cursorVal + 1; i <= (rateVal + cursorVal); i++) {
rateTuple[hashIdx(i)] = awardRateInfo.getAwardId();
}
cursorVal += rateVal;
}
}
@Override
public boolean isExistRateTuple(Long strategyId) {
return rateTupleMap.containsKey(strategyId);
}
/**
* 斐波那契(Fibonacci)散列法,计算哈希索引下标值
*
* @param val 值
* @return 索引
*/
protected int hashIdx(int val) {
int hashCode = val * HASH_INCREMENT + HASH_INCREMENT;
return hashCode & (RATE_TUPLE_LENGTH - 1);
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/IDrawAlgorithm.java
================================================
package cn.itedus.lottery.domain.strategy.service.algorithm;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 抽奖算法接口
*/
public interface IDrawAlgorithm {
/**
* 程序启动时初始化概率元祖,在初始化完成后使用过程中不允许修改元祖数据
* <p>
* 元祖数据作用在于讲百分比内(0.2、0.3、0.5)的数据,转换为一整条数组上分区数据,如下;
* 0.2 = 0 ~ 0.2
* 0.3 = 0 + 0.2 ~ 0.2 + 0.3 = 0.2 ~ 0.5
* 0.5 = 0.5 ~ 1 (计算方式同上)
* <p>
* 通过数据拆分为整条后,再根据0-100中各个区间的奖品信息,使用斐波那契散列计算出索引位置,把奖品数据存放到元祖中。比如:
* <p>
* 1. 把 0.2 转换为 20
* 2. 20 对应的斐波那契值哈希值:(20 * HASH_INCREMENT + HASH_INCREMENT)= -1549107828 HASH_INCREMENT = 0x61c88647
* 3. 再通过哈希值计算索引位置:hashCode & (rateTuple.length - 1) = 12
* 4. 那么tup[14] = 0.2 中奖概率对应的奖品
* 5. 当后续通过随机数获取到1-100的值后,可以直接定位到对应的奖品信息,通过这样的方式把轮训算奖的时间复杂度从O(n) 降低到 0(1)
*
* @param strategyId 策略ID
* @param awardRateInfoList 奖品概率配置集合 「值示例:AwardRateInfo.awardRate = 0.04」
*/
void initRateTuple(Long strategyId, List<AwardRateInfo> awardRateInfoList);
/**
* 判断是否已经,做了数据初始化
* @param strategyId
* @return
*/
boolean isExistRateTuple(Long strategyId);
/**
* SecureRandom 生成随机数,索引到对应的奖品信息返回结果
*
* @param strategyId 策略ID
* @param excludeAwardIds 排除掉已经不能作为抽奖的奖品ID,留给风控和空库存使用
* @return 中奖结果
*/
String randomDraw(Long strategyId, List<String> excludeAwardIds);
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/impl/DefaultRateRandomDrawAlgorithm.java
================================================
package cn.itedus.lottery.domain.strategy.service.algorithm.impl;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import cn.itedus.lottery.domain.strategy.service.algorithm.BaseAlgorithm;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*
* 必中奖策略抽奖,排掉已经中奖的概率,重新计算中奖范围
*/
@Component("defaultRateRandomDrawAlgorithm")
public class DefaultRateRandomDrawAlgorithm extends BaseAlgorithm {
@Override
public String randomDraw(Long strategyId, List<String> excludeAwardIds) {
BigDecimal differenceDenominator = BigDecimal.ZERO;
// 排除掉不在抽奖范围的奖品ID集合
List<AwardRateInfo> differenceAwardRateList = new ArrayList<>();
List<AwardRateInfo> awardRateIntervalValList = awardRateInfoMap.get(strategyId);
for (AwardRateInfo awardRateInfo : awardRateIntervalValList) {
String awardId = awardRateInfo.getAwardId();
if (excludeAwardIds.contains(awardId)) {
continue;
}
differenceAwardRateList.add(awardRateInfo);
differenceDenominator = differenceDenominator.add(awardRateInfo.getAwardRate());
}
// 前置判断
if (differenceAwardRateList.size() == 0) return "";
if (differenceAwardRateList.size() == 1) return differenceAwardRateList.get(0).getAwardId();
// 获取随机概率值
SecureRandom secureRandom = new SecureRandom();
int randomVal = secureRandom.nextInt(100) + 1;
// 循环获取奖品
String awardId = "";
int cursorVal = 0;
for (AwardRateInfo awardRateInfo : differenceAwardRateList) {
int rateVal = awardRateInfo.getAwardRate().divide(differenceDenominator, 2, BigDecimal.ROUND_UP).multiply(new BigDecimal(100)).intValue();
if (randomVal <= (cursorVal + rateVal)) {
awardId = awardRateInfo.getAwardId();
break;
}
cursorVal += rateVal;
}
// 返回中奖结果
return awardId;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/impl/SingleRateRandomDrawAlgorithm.java
================================================
package cn.itedus.lottery.domain.strategy.service.algorithm.impl;
import cn.itedus.lottery.domain.strategy.service.algorithm.BaseAlgorithm;
import org.springframework.stereotype.Component;
import java.security.SecureRandom;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 【推荐】单项随机概率抽奖,抽到一个已经排掉的奖品则未中奖
*/
@Component("singleRateRandomDrawAlgorithm")
public class SingleRateRandomDrawAlgorithm extends BaseAlgorithm {
@Override
public String randomDraw(Long strategyId, List<String> excludeAwardIds) {
// 获取策略对应的元祖
String[] rateTuple = super.rateTupleMap.get(strategyId);
assert rateTuple != null;
// 随机索引
int randomVal = new SecureRandom().nextInt(100) + 1;
int idx = super.hashIdx(randomVal);
// 返回结果
String awardId = rateTuple[idx];
if (excludeAwardIds.contains(awardId)) return "未中奖";
return awardId;
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/DrawBase.java
================================================
package cn.itedus.lottery.domain.strategy.service.draw;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import cn.itedus.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
import cn.itedus.lottery.infrastructure.po.StrategyDetail;
import java.util.ArrayList;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DrawBase extends DrawConfig {
public void checkAndInitRateData(Long strategyId, Integer strategyMode, List<StrategyDetail> strategyDetailList) {
if (1 != strategyMode) return;
IDrawAlgorithm drawAlgorithm = drawAlgorithmMap.get(strategyMode);
boolean existRateTuple = drawAlgorithm.isExistRateTuple(strategyId);
if (existRateTuple) return;
List<AwardRateInfo> awardRateInfoList = new ArrayList<>(strategyDetailList.size());
for (StrategyDetail strategyDetail : strategyDetailList) {
awardRateInfoList.add(new AwardRateInfo(strategyDetail.getAwardId(), strategyDetail.getAwardRate()));
}
drawAlgorithm.initRateTuple(strategyId, awardRateInfoList);
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/DrawConfig.java
================================================
package cn.itedus.lottery.domain.strategy.service.draw;
import cn.itedus.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
import org.springframework.context.annotation.Bean;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class DrawConfig {
@Resource
private IDrawAlgorithm defaultRateRandomDrawAlgorithm;
@Resource
private IDrawAlgorithm singleRateRandomDrawAlgorithm;
protected static Map<Integer, IDrawAlgorithm> drawAlgorithmMap = new ConcurrentHashMap<>();
@PostConstruct
public void init() {
drawAlgorithmMap.put(1, defaultRateRandomDrawAlgorithm);
drawAlgorithmMap.put(2, singleRateRandomDrawAlgorithm);
}
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/IDrawExec.java
================================================
package cn.itedus.lottery.domain.strategy.service.draw;
import cn.itedus.lottery.domain.strategy.model.req.DrawReq;
import cn.itedus.lottery.domain.strategy.model.res.DrawResult;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public interface IDrawExec {
DrawResult doDrawExec(DrawReq req);
}
================================================
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/impl/DrawExecImpl.java
================================================
package cn.itedus.lottery.domain.strategy.service.draw.impl;
import cn.itedus.lottery.domain.strategy.model.aggregates.StrategyRich;
import cn.itedus.lottery.domain.strategy.model.req.DrawReq;
import cn.itedus.lottery.domain.strategy.model.res.DrawResult;
import cn.itedus.lottery.domain.strategy.repository.IStrategyRepository;
import cn.itedus.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
import cn.itedus.lottery.domain.strategy.service.draw.DrawBase;
import cn.itedus.lottery.domain.strategy.service.draw.IDrawExec;
import cn.itedus.lottery.infrastructure.po.Award;
import cn.itedus.lottery.infrastructure.po.Strategy;
import cn.itedus.lottery.infrastructure.po.StrategyDetail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Service("drawExec")
public class DrawExecImpl extends DrawBase implements IDrawExec {
private Logger logger = LoggerFactory.getLogger(DrawExecImpl.class);
@Resource
private IStrategyRepository strategyRepository;
@Override
public DrawResult doDrawExec(DrawReq req) {
logger.info("执行策略抽奖开始,strategyId:{}", req.getStrategyId());
// 获取抽奖策略配置数据
StrategyRich strategyRich = strategyRepository.queryStrategyRich(req.getStrategyId());
Strategy strategy = strategyRich.getStrategy();
List<StrategyDetail> strategyDetailList = strategyRich.getStrategyDetailList();
// 校验和初始化数据
checkAndInitRateData(req.getStrategyId(), strategy.getStrategyMode(), strategyDetailList);
// 根据策略方式抽奖
IDrawAlgorithm drawAlgorithm = drawAlgorithmMap.get(strategy.getStrategyMode());
String awardId = drawAlgorithm.randomDraw(req.getStrategyId(), new ArrayList<>());
// 获取奖品信息
Award award = strategyRepository.queryAwardInfo(awardId);
logger.info("执行策略抽奖完成,中奖用户:{} 奖品ID:{} 奖品名称:{}", req.getuId(), awardId, award.getAwardName());
// 封装结果
return new DrawResult(req.getuId(), req.getStrategyId(), awardId, award.getAwardName());
}
}
================================================
FILE: lottery-infrastructure/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lottery-infrastructure</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
</dependencies>
<build>
<finalName>lottery-infrastructure</finalName>
<plugins>
<!-- 编译plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<compilerVersion>1.8</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IActivityDao.java
================================================
package cn.itedus.lottery.infrastructure.dao;
import cn.itedus.lottery.infrastructure.po.Activity;
import org.apache.ibatis.annotations.Mapper;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Mapper
public interface IActivityDao {
void insert(Activity req);
Activity queryActivityById(Long activityId);
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IAwardDao.java
================================================
package cn.itedus.lottery.infrastructure.dao;
import cn.itedus.lottery.infrastructure.po.Award;
import org.apache.ibatis.annotations.Mapper;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Mapper
public interface IAwardDao {
Award queryAwardInfo(String awardId);
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IStrategyDao.java
================================================
package cn.itedus.lottery.infrastructure.dao;
import cn.itedus.lottery.infrastructure.po.Strategy;
import org.apache.ibatis.annotations.Mapper;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Mapper
public interface IStrategyDao {
Strategy queryStrategy(Long strategyId);
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IStrategyDetailDao.java
================================================
package cn.itedus.lottery.infrastructure.dao;
import cn.itedus.lottery.infrastructure.po.StrategyDetail;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@Mapper
public interface IStrategyDetailDao {
List<StrategyDetail> queryStrategyDetailList(Long strategyId);
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Activity.java
================================================
package cn.itedus.lottery.infrastructure.po;
import java.util.Date;
/**
* 活动基础信息表
* <p>
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class Activity {
// 自增ID
private Long id;
// 活动ID
private Long activityId;
// 活动名称
private String activityName;
// 活动描述
private String activityDesc;
// 开始时间
private Date beginDateTime;
// 结束时间
private Date endDateTime;
// 库存
private Integer stockCount;
// 每人可参与次数
private Integer takeCount;
// 活动状态:编辑、提审、撤审、通过、运行、拒绝、关闭、开启
private Integer state;
// 创建人
private String creator;
// 创建时间
private Date createTime;
// 修改时间
private Date updateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getActivityId() {
return activityId;
}
public void setActivityId(Long activityId) {
this.activityId = activityId;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public String getActivityDesc() {
return activityDesc;
}
public void setActivityDesc(String activityDesc) {
this.activityDesc = activityDesc;
}
public Date getBeginDateTime() {
return beginDateTime;
}
public void setBeginDateTime(Date beginDateTime) {
this.beginDateTime = beginDateTime;
}
public Date getEndDateTime() {
return endDateTime;
}
public void setEndDateTime(Date endDateTime) {
this.endDateTime = endDateTime;
}
public Integer getStockCount() {
return stockCount;
}
public void setStockCount(Integer stockCount) {
this.stockCount = stockCount;
}
public Integer getTakeCount() {
return takeCount;
}
public void setTakeCount(Integer takeCount) {
this.takeCount = takeCount;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Award.java
================================================
package cn.itedus.lottery.infrastructure.po;
import java.util.Date;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class Award {
// 自增ID
private Long id;
// 奖品ID
private String awardId;
// 奖品类型(文字描述、兑换码、优惠券、实物奖品暂无)
private Integer awardType;
// 奖品数量
private Integer awardCount;
// 奖品名称
private String awardName;
// 奖品内容「文字描述、Key、码」
private String awardContent;
// 创建时间
private Date createTime;
// 修改时间
private Date updateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAwardId() {
return awardId;
}
public void setAwardId(String awardId) {
this.awardId = awardId;
}
public Integer getAwardType() {
return awardType;
}
public void setAwardType(Integer awardType) {
this.awardType = awardType;
}
public Integer getAwardCount() {
return awardCount;
}
public void setAwardCount(Integer awardCount) {
this.awardCount = awardCount;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
public String getAwardContent() {
return awardContent;
}
public void setAwardContent(String awardContent) {
this.awardContent = awardContent;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Strategy.java
================================================
package cn.itedus.lottery.infrastructure.po;
import java.util.Date;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 策略配置
*/
public class Strategy {
// 自增ID
private Long id;
// 策略ID
private Long strategyId;
// 策略描述
private String strategyDesc;
// 策略方式「1:单项概率、2:总体概率」
private Integer strategyMode;
// 发放奖品方式「1:即时、2:定时[含活动结束]、3:人工」
private Integer grantType;
// 发放奖品时间
private Date grantDate;
// 扩展信息
private String extInfo;
// 创建时间
private Date createTime;
// 修改时间
private Date updateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getStrategyId() {
return strategyId;
}
public void setStrategyId(Long strategyId) {
this.strategyId = strategyId;
}
public String getStrategyDesc() {
return strategyDesc;
}
public void setStrategyDesc(String strategyDesc) {
this.strategyDesc = strategyDesc;
}
public Integer getStrategyMode() {
return strategyMode;
}
public void setStrategyMode(Integer strategyMode) {
this.strategyMode = strategyMode;
}
public Integer getGrantType() {
return grantType;
}
public void setGrantType(Integer grantType) {
this.grantType = grantType;
}
public Date getGrantDate() {
return grantDate;
}
public void setGrantDate(Date grantDate) {
this.grantDate = grantDate;
}
public String getExtInfo() {
return extInfo;
}
public void setExtInfo(String extInfo) {
this.extInfo = extInfo;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
================================================
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/StrategyDetail.java
================================================
package cn.itedus.lottery.infrastructure.po;
import java.math.BigDecimal;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 策略明细
*/
public class StrategyDetail {
// 自增ID
private String id;
// 策略ID
private Long strategyId;
// 奖品ID
private String awardId;
// 奖品数量
private String awardCount;
// 中奖概率
private BigDecimal awardRate;
// 创建时间
private String createTime;
// 修改时间
private String updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getStrategyId() {
return strategyId;
}
public void setStrategyId(Long strategyId) {
this.strategyId = strategyId;
}
public String getAwardId() {
return awardId;
}
public void setAwardId(String awardId) {
this.awardId = awardId;
}
public String getAwardCount() {
return awardCount;
}
public void setAwardCount(String awardCount) {
this.awardCount = awardCount;
}
public BigDecimal getAwardRate() {
return awardRate;
}
public void setAwardRate(BigDecimal awardRate) {
this.awardRate = awardRate;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
}
================================================
FILE: lottery-interfaces/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lottery-interfaces</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>cn.itedus.lottery</groupId>
<artifactId>lottery-infrastructure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.itedus.lottery</groupId>
<artifactId>lottery-rpc</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.itedus.lottery</groupId>
<artifactId>lottery-domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>Lottery</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: lottery-interfaces/src/main/java/cn/itedus/lottery/LotteryApplication.java
================================================
package cn.itedus.lottery;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@SpringBootApplication
@Configurable
@EnableDubbo
public class LotteryApplication {
public static void main(String[] args) {
SpringApplication.run(LotteryApplication.class, args);
}
}
================================================
FILE: lottery-interfaces/src/main/java/cn/itedus/lottery/interfaces/ActivityBooth.java
================================================
package cn.itedus.lottery.interfaces;
import cn.itedus.lottery.common.Constants;
import cn.itedus.lottery.common.Result;
import cn.itedus.lottery.infrastructure.dao.IActivityDao;
import cn.itedus.lottery.infrastructure.po.Activity;
import cn.itedus.lottery.rpc.IActivityBooth;
import cn.itedus.lottery.rpc.dto.ActivityDto;
import cn.itedus.lottery.rpc.req.ActivityReq;
import cn.itedus.lottery.rpc.res.ActivityRes;
import org.apache.dubbo.config.annotation.Service;
import javax.annotation.Resource;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
* <p>
* 活动展台
*/
@Service
public class ActivityBooth implements IActivityBooth {
@Resource
private IActivityDao activityDao;
@Override
public ActivityRes queryActivityById(ActivityReq req) {
Activity activity = activityDao.queryActivityById(req.getActivityId());
ActivityDto activityDto = new ActivityDto();
activityDto.setActivityId(activity.getActivityId());
activityDto.setActivityName(activity.getActivityName());
activityDto.setActivityDesc(activity.getActivityDesc());
activityDto.setBeginDateTime(activity.getBeginDateTime());
activityDto.setEndDateTime(activity.getEndDateTime());
activityDto.setStockCount(activity.getStockCount());
activityDto.setTakeCount(activity.getTakeCount());
return new ActivityRes(new Result(Constants.ResponseCode.SUCCESS.getCode(), Constants.ResponseCode.SUCCESS.getInfo()), activityDto);
}
}
================================================
FILE: lottery-interfaces/src/main/resources/application.yml
================================================
server:
port: 8080
spring:
datasource:
username: root
password: 1234
url: jdbc:mysql://127.0.0.1:3306/lottery?useUnicode=true
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:/mybatis/mapper/*.xml
config-location: classpath:/mybatis/config/mybatis-config.xml
# Dubbo 广播方式配置
dubbo:
application:
name: Lottery
version: 1.0.0
registry:
address: multicast://224.5.6.7:1234
protocol:
name: dubbo
port: 20880
scan:
base-packages: cn.itedus.lottery.rpc
================================================
FILE: lottery-interfaces/src/main/resources/mybatis/config/mybatis-config.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="cn.itedus.lottery.infrastructure.po.Activity"/>
</typeAliases>
</configuration>
================================================
FILE: lottery-interfaces/src/main/resources/mybatis/mapper/Activity_Mapper.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itedus.lottery.infrastructure.dao.IActivityDao">
<insert id="insert" parameterType="cn.itedus.lottery.infrastructure.po.Activity">
INSERT INTO activity
(activityId, activityName, activityDesc,beginDateTime, endDateTime,
stockCount, takeCount, state, creator, createTime, updateTime)
VALUES
(#{activityId}, #{activityName}, #{activityDesc},#{beginDateTime}, #{endDateTime},
#{stockCount}, #{takeCount}, #{state}, #{creator}, now(), now())
</insert>
<select id="queryActivityById" parameterType="java.lang.Long" resultType="cn.itedus.lottery.infrastructure.po.Activity">
SELECT activityId, activityName, activityDesc,beginDateTime, endDateTime,
stockCount, takeCount, state, creator, createTime, updateTime
FROM activity
WHERE activityId = #{activityId}
</select>
</mapper>
================================================
FILE: lottery-interfaces/src/main/resources/mybatis/mapper/Award_Mapper.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itedus.lottery.infrastructure.dao.IAwardDao">
<select id="queryAwardInfo" parameterType="java.lang.String" resultType="cn.itedus.lottery.infrastructure.po.Award">
SELECT
id, awardId, awardType, awardCount, awardName, awardContent, createTime, updateTime
FROM award
WHERE awardId = #{awardId}
</select>
</mapper>
================================================
FILE: lottery-interfaces/src/main/resources/mybatis/mapper/StrategyDetail_Mapper.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itedus.lottery.infrastructure.dao.IStrategyDetailDao">
<select id="queryStrategyDetailList" parameterType="java.lang.Long" resultType="cn.itedus.lottery.infrastructure.po.StrategyDetail">
SELECT id, strategyId, awardId, awardCount, awardRate, createTime, updateTime
FROM strategy_detail
WHERE strategyId = #{strategyId}
</select>
</mapper>
================================================
FILE: lottery-interfaces/src/main/resources/mybatis/mapper/Strategy_Mapper.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itedus.lottery.infrastructure.dao.IStrategyDao">
<select id="queryStrategy" parameterType="java.lang.Long" resultType="cn.itedus.lottery.infrastructure.po.Strategy">
SELECT
id, strategyId, strategyDesc, strategyMode, grantType,
grantDate, extInfo , createTime, updateTime
FROM strategy
WHERE strategyId = #{strategyId}
</select>
</mapper>
================================================
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/ApiTest.java
================================================
package cn.itedus.lottery.test;
import org.junit.Test;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class ApiTest {
/**
* 抽奖策略测试
* <p>
* https://www.jugong.wang/random-portal/my/qa
* https://csrc.nist.gov/Projects/Random-Bit-Generation/Documentation-and-Software
* Java 随机数生成器 Random & SecureRandom 原理分析 https://blog.csdn.net/hustspy1990/article/details/93364805
* 使用 SecureRandom 产生随机数采坑记录 https://blog.csdn.net/weixin_41385912/article/details/103267277
*/
@Test
public void test_strategy() {
SecureRandom random = new SecureRandom();
int rate = random.nextInt(100);
System.out.println("概率:" + rate);
List<Map<String, String>> strategyList = new ArrayList<>();
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "一等奖:彩电");
put("awardId", "10001");
put("awardCount", "3");
put("awardRate", "0.2");
}});
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "二等奖:冰箱");
put("awardId", "10002");
put("awardCount", "5");
put("awardRate", "0.3");
}});
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "三等奖:洗衣机");
put("awardId", "10003");
put("awardCount", "10");
put("awardRate", "0.5");
}});
}
@Test
public void test_idx() {
Map<Integer, Integer> map = new HashMap<>();
int HASH_INCREMENT = 0x61c88647;
int hashCode = 0;
for (int i = 1; i <= 100; i++) {
hashCode = i * HASH_INCREMENT + HASH_INCREMENT;
int idx = hashCode & (128 - 1);
map.merge(idx, 1, Integer::sum);
System.out.println("斐波那契散列:" + idx + " 普通散列:" + (String.valueOf(i).hashCode() & (128 - 1)));
}
System.out.println(map);
}
@Test
public void test_DrawStrategy() {
List<Map<String, String>> strategyList = new ArrayList<>();
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "一等奖:彩电");
put("awardId", "10001");
put("awardCount", "3");
put("awardRate", "20");
}});
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "二等奖:冰箱");
put("awardId", "10002");
put("awardCount", "5");
put("awardRate", "30");
}});
strategyList.add(new HashMap<String, String>() {{
put("awardDesc", "三等奖:洗衣机");
put("awardId", "10003");
put("awardCount", "10");
put("awardRate", "50");
}});
DrawStrategy drawStrategy = new DrawStrategy();
drawStrategy.initRateTuple(strategyList);
for (int i = 0; i < 20; i++) {
System.out.println("中奖结果:" + drawStrategy.randomDraw());
}
}
@Test
public void test_random() {
SecureRandom random = new SecureRandom();
for (int i = 0; i < 20; i++) {
System.out.println(random.nextInt(1));
}
}
}
class DrawStrategy {
// 黄金分割点:(√5 - 1) / 2 = 0.6180339887 1.618:1 == 1:0.618,Math.pow(2, 32) * 0.6180339887 = 0x61c88647
private final int HASH_INCREMENT = 0x61c88647;
// 用于保存0-100,斐波那契散列索引的结果
private String[] rateTuple = new String[128];
/**
*
* 初始化概率索引数组
* 不同奖项概率 0.20、0.30、0.50,调整为三个奖项的范围值;
* 一等奖:0-20
* 二等奖:21-30
* 三等奖:51-100
*
* 再把各个区间范围填充到数组中,索引位置和对应的奖品值
* @param drawConfig
*/
public void initRateTuple(List<Map<String, String>> drawConfig) {
int cursorVal = 0;
for (Map<String, String> drawMap : drawConfig) {
int rateVal = Integer.parseInt(drawMap.get("awardRate"));
for (int i = cursorVal + 1; i <= (rateVal + cursorVal); i++) {
// 计算数组索引并填充数据
int hashCode = i * HASH_INCREMENT + HASH_INCREMENT;
int idx = hashCode & (rateTuple.length - 1);
rateTuple[idx] = drawMap.get("awardDesc");
}
cursorVal += rateVal;
}
}
/**
* 随机抽奖
* @return 中奖结果
*/
public String randomDraw() {
// 随机数
int rate = new SecureRandom().nextInt(100) + 1;
// 索引位置
int hashCode = rate * HASH_INCREMENT + HASH_INCREMENT;
int idx = hashCode & (rateTuple.length - 1);
return rateTuple[idx];
}
}
================================================
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/DrawAlgorithmTest.java
================================================
package cn.itedus.lottery.test;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import cn.itedus.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class DrawAlgorithmTest {
// @Resource(name = "defaultRateRandomDrawAlgorithm")
@Resource(name = "singleRateRandomDrawAlgorithm")
private IDrawAlgorithm randomDrawAlgorithm;
@Before
public void init() {
// 奖品信息
List<AwardRateInfo> strategyList = new ArrayList<>();
strategyList.add(new AwardRateInfo("一等奖:IMac", new BigDecimal("0.05")));
strategyList.add(new AwardRateInfo("二等奖:iphone", new BigDecimal("0.15")));
strategyList.add(new AwardRateInfo("三等奖:ipad", new BigDecimal("0.20")));
strategyList.add(new AwardRateInfo("四等奖:AirPods", new BigDecimal("0.25")));
strategyList.add(new AwardRateInfo("五等奖:充电宝", new BigDecimal("0.35")));
// 初始数据
randomDrawAlgorithm.initRateTuple(100001L, strategyList);
}
@Test
public void test_randomDrawAlgorithm() {
List<String> excludeAwardIds = new ArrayList<>();
excludeAwardIds.add("二等奖:iphone");
excludeAwardIds.add("四等奖:AirPods");
for (int i = 0; i < 20; i++) {
System.out.println("中奖结果:" + randomDrawAlgorithm.randomDraw(100001L, excludeAwardIds));
}
}
}
================================================
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/SpringRunnerTest.java
================================================
package cn.itedus.lottery.test;
import cn.itedus.lottery.domain.strategy.model.req.DrawReq;
import cn.itedus.lottery.domain.strategy.model.res.DrawResult;
import cn.itedus.lottery.domain.strategy.model.vo.AwardRateInfo;
import cn.itedus.lottery.domain.strategy.service.algorithm.IDrawAlgorithm;
import cn.itedus.lottery.domain.strategy.service.draw.IDrawExec;
import cn.itedus.lottery.infrastructure.dao.IActivityDao;
import cn.itedus.lottery.infrastructure.po.Activity;
import com.alibaba.fastjson.JSON;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.json.JsonbTester;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringRunnerTest {
private Logger logger = LoggerFactory.getLogger(SpringRunnerTest.class);
@Resource
private IActivityDao activityDao;
@Resource
private IDrawExec drawExec;
@Test
public void test_drawExec() {
drawExec.doDrawExec(new DrawReq("小傅哥", 10001L));
drawExec.doDrawExec(new DrawReq("小佳佳", 10001L));
drawExec.doDrawExec(new DrawReq("小蜗牛", 10001L));
drawExec.doDrawExec(new DrawReq("八杯水", 10001L));
}
@Test
public void test_insert() {
Activity activity = new Activity();
activity.setActivityId(100001L);
activity.setActivityName("测试活动");
activity.setActivityDesc("仅用于插入数据测试");
activity.setBeginDateTime(new Date());
activity.setEndDateTime(new Date());
activity.setStockCount(100);
activity.setTakeCount(10);
activity.setState(0);
activity.setCreator("xiaofuge");
activityDao.insert(activity);
}
@Test
public void test_select() {
Activity activity = activityDao.queryActivityById(100001L);
logger.info("测试结果:{}", JSON.toJSONString(activity));
}
}
================================================
FILE: lottery-rpc/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Lottery</artifactId>
<groupId>cn.itedus.lottery</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lottery-rpc</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>cn.itedus.lottery</groupId>
<artifactId>lottery-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>lottery-rpc</finalName>
<plugins>
<!-- 编译plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<compilerVersion>1.8</compilerVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/IActivityBooth.java
================================================
package cn.itedus.lottery.rpc;
import cn.itedus.lottery.rpc.req.ActivityReq;
import cn.itedus.lottery.rpc.res.ActivityRes;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*
* 活动展台
* 1. 创建活动
* 2. 更新活动
* 3. 查询活动
*/
public interface IActivityBooth {
ActivityRes queryActivityById(ActivityReq req);
}
================================================
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/dto/ActivityDto.java
================================================
package cn.itedus.lottery.rpc.dto;
import java.io.Serializable;
import java.util.Date;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class ActivityDto implements Serializable {
// 活动ID
private Long activityId;
// 活动名称
private String activityName;
// 活动描述
private String activityDesc;
// 开始时间
private Date beginDateTime;
// 结束时间
private Date endDateTime;
// 库存
private Integer stockCount;
// 每人可参与次数
private Integer takeCount;
// 活动状态:编辑、提审、撤审、通过、运行、拒绝、关闭、开启
private Integer state;
public Long getActivityId() {
return activityId;
}
public void setActivityId(Long activityId) {
this.activityId = activityId;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public String getActivityDesc() {
return activityDesc;
}
public void setActivityDesc(String activityDesc) {
this.activityDesc = activityDesc;
}
public Date getBeginDateTime() {
return beginDateTime;
}
public void setBeginDateTime(Date beginDateTime) {
this.beginDateTime = beginDateTime;
}
public Date getEndDateTime() {
return endDateTime;
}
public void setEndDateTime(Date endDateTime) {
this.endDateTime = endDateTime;
}
public Integer getStockCount() {
return stockCount;
}
public void setStockCount(Integer stockCount) {
this.stockCount = stockCount;
}
public Integer getTakeCount() {
return takeCount;
}
public void setTakeCount(Integer takeCount) {
this.takeCount = takeCount;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
}
================================================
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/req/ActivityReq.java
================================================
package cn.itedus.lottery.rpc.req;
import java.io.Serializable;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class ActivityReq implements Serializable {
private Long activityId;
public Long getActivityId() {
return activityId;
}
public void setActivityId(Long activityId) {
this.activityId = activityId;
}
}
================================================
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/res/ActivityRes.java
================================================
package cn.itedus.lottery.rpc.res;
import cn.itedus.lottery.common.Result;
import cn.itedus.lottery.rpc.dto.ActivityDto;
import java.io.Serializable;
/**
* 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
* 公众号:bugstack虫洞栈
* Create by 小傅哥(fustack)
*/
public class ActivityRes implements Serializable {
private Result result;
private ActivityDto activity;
public ActivityRes() {
}
public ActivityRes(Result result) {
this.result = result;
}
public ActivityRes(Result result, ActivityDto activity) {
this.result = result;
this.activity = activity;
}
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
public ActivityDto getActivity() {
return activity;
}
public void setActivity(ActivityDto activity) {
this.activity = activity;
}
}
================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itedus.lottery</groupId>
<artifactId>Lottery</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>lottery-application</module>
<module>lottery-domain</module>
<module>lottery-infrastructure</module>
<module>lottery-interfaces</module>
<module>lottery-rpc</module>
<module>lottery-common</module>
</modules>
<properties>
<!-- Base -->
<jdk.version>1.8</jdk.version>
<sourceEncoding>UTF-8</sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
gitextract_3lapcxae/ ├── .gitignore ├── LICENSE ├── README.md ├── lottery-application/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── package-info.java ├── lottery-common/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── cn/ │ └── itedus/ │ └── lottery/ │ └── common/ │ ├── Constants.java │ └── Result.java ├── lottery-domain/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── cn/ │ └── itedus/ │ └── lottery/ │ └── domain/ │ └── strategy/ │ ├── model/ │ │ ├── aggregates/ │ │ │ └── StrategyRich.java │ │ ├── req/ │ │ │ └── DrawReq.java │ │ ├── res/ │ │ │ └── DrawResult.java │ │ └── vo/ │ │ └── AwardRateInfo.java │ ├── repository/ │ │ ├── IStrategyRepository.java │ │ └── impl/ │ │ └── StrategyRepository.java │ └── service/ │ ├── algorithm/ │ │ ├── BaseAlgorithm.java │ │ ├── IDrawAlgorithm.java │ │ └── impl/ │ │ ├── DefaultRateRandomDrawAlgorithm.java │ │ └── SingleRateRandomDrawAlgorithm.java │ └── draw/ │ ├── DrawBase.java │ ├── DrawConfig.java │ ├── IDrawExec.java │ └── impl/ │ └── DrawExecImpl.java ├── lottery-infrastructure/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── cn/ │ └── itedus/ │ └── lottery/ │ └── infrastructure/ │ ├── dao/ │ │ ├── IActivityDao.java │ │ ├── IAwardDao.java │ │ ├── IStrategyDao.java │ │ └── IStrategyDetailDao.java │ └── po/ │ ├── Activity.java │ ├── Award.java │ ├── Strategy.java │ └── StrategyDetail.java ├── lottery-interfaces/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── cn/ │ │ │ └── itedus/ │ │ │ └── lottery/ │ │ │ ├── LotteryApplication.java │ │ │ └── interfaces/ │ │ │ └── ActivityBooth.java │ │ └── resources/ │ │ ├── application.yml │ │ └── mybatis/ │ │ ├── config/ │ │ │ └── mybatis-config.xml │ │ └── mapper/ │ │ ├── Activity_Mapper.xml │ │ ├── Award_Mapper.xml │ │ ├── StrategyDetail_Mapper.xml │ │ └── Strategy_Mapper.xml │ └── test/ │ └── java/ │ └── cn/ │ └── itedus/ │ └── lottery/ │ └── test/ │ ├── ApiTest.java │ ├── DrawAlgorithmTest.java │ └── SpringRunnerTest.java ├── lottery-rpc/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── cn/ │ └── itedus/ │ └── lottery/ │ └── rpc/ │ ├── IActivityBooth.java │ ├── dto/ │ │ └── ActivityDto.java │ ├── req/ │ │ └── ActivityReq.java │ └── res/ │ └── ActivityRes.java └── pom.xml
SYMBOL INDEX (208 symbols across 33 files)
FILE: lottery-common/src/main/java/cn/itedus/lottery/common/Constants.java
class Constants (line 10) | public class Constants {
type ResponseCode (line 12) | public enum ResponseCode {
method ResponseCode (line 21) | ResponseCode(String code, String info) {
method getCode (line 26) | public String getCode() {
method getInfo (line 30) | public String getInfo() {
FILE: lottery-common/src/main/java/cn/itedus/lottery/common/Result.java
class Result (line 12) | public class Result implements Serializable {
method buildResult (line 18) | public static Result buildResult(String code, String info) {
method buildSuccessResult (line 22) | public static Result buildSuccessResult() {
method buildErrorResult (line 26) | public static Result buildErrorResult() {
method Result (line 30) | public Result(String code, String info) {
method getCode (line 35) | public String getCode() {
method setCode (line 39) | public void setCode(String code) {
method getInfo (line 43) | public String getInfo() {
method setInfo (line 47) | public void setInfo(String info) {
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/aggregates/StrategyRich.java
class StrategyRich (line 14) | public class StrategyRich {
method StrategyRich (line 23) | public StrategyRich() {
method StrategyRich (line 26) | public StrategyRich(Long strategyId, Strategy strategy, List<StrategyD...
method getStrategyId (line 32) | public Long getStrategyId() {
method setStrategyId (line 36) | public void setStrategyId(Long strategyId) {
method getStrategy (line 40) | public Strategy getStrategy() {
method setStrategy (line 44) | public void setStrategy(Strategy strategy) {
method getStrategyDetailList (line 48) | public List<StrategyDetail> getStrategyDetailList() {
method setStrategyDetailList (line 52) | public void setStrategyDetailList(List<StrategyDetail> strategyDetailL...
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/req/DrawReq.java
class DrawReq (line 8) | public class DrawReq {
method DrawReq (line 16) | public DrawReq() {
method DrawReq (line 19) | public DrawReq(String uId, Long strategyId) {
method getuId (line 24) | public String getuId() {
method setuId (line 28) | public void setuId(String uId) {
method getStrategyId (line 32) | public Long getStrategyId() {
method setStrategyId (line 36) | public void setStrategyId(Long strategyId) {
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/res/DrawResult.java
class DrawResult (line 8) | public class DrawResult {
method DrawResult (line 22) | public DrawResult() {
method DrawResult (line 25) | public DrawResult(String uId, Long strategyId, String rewardId, String...
method getuId (line 32) | public String getuId() {
method setuId (line 36) | public void setuId(String uId) {
method getStrategyId (line 40) | public Long getStrategyId() {
method setStrategyId (line 44) | public void setStrategyId(Long strategyId) {
method getRewardId (line 48) | public String getRewardId() {
method setRewardId (line 52) | public void setRewardId(String rewardId) {
method getAwardName (line 56) | public String getAwardName() {
method setAwardName (line 60) | public void setAwardName(String awardName) {
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/model/vo/AwardRateInfo.java
class AwardRateInfo (line 12) | public class AwardRateInfo {
method AwardRateInfo (line 20) | public AwardRateInfo() {
method AwardRateInfo (line 23) | public AwardRateInfo(String awardId, BigDecimal awardRate) {
method getAwardId (line 28) | public String getAwardId() {
method setAwardId (line 32) | public void setAwardId(String awardId) {
method getAwardRate (line 36) | public BigDecimal getAwardRate() {
method setAwardRate (line 40) | public void setAwardRate(BigDecimal awardRate) {
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/repository/IStrategyRepository.java
type IStrategyRepository (line 11) | public interface IStrategyRepository {
method queryStrategyRich (line 13) | StrategyRich queryStrategyRich(Long strategyId);
method queryAwardInfo (line 15) | Award queryAwardInfo(String awardId);
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/repository/impl/StrategyRepository.java
class StrategyRepository (line 21) | @Component
method queryStrategyRich (line 33) | @Override
method queryAwardInfo (line 40) | @Override
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/BaseAlgorithm.java
class BaseAlgorithm (line 17) | public abstract class BaseAlgorithm implements IDrawAlgorithm {
method initRateTuple (line 31) | @Override
method isExistRateTuple (line 52) | @Override
method hashIdx (line 63) | protected int hashIdx(int val) {
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/IDrawAlgorithm.java
type IDrawAlgorithm (line 14) | public interface IDrawAlgorithm {
method initRateTuple (line 35) | void initRateTuple(Long strategyId, List<AwardRateInfo> awardRateInfoL...
method isExistRateTuple (line 42) | boolean isExistRateTuple(Long strategyId);
method randomDraw (line 51) | String randomDraw(Long strategyId, List<String> excludeAwardIds);
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/impl/DefaultRateRandomDrawAlgorithm.java
class DefaultRateRandomDrawAlgorithm (line 19) | @Component("defaultRateRandomDrawAlgorithm")
method randomDraw (line 22) | @Override
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/algorithm/impl/SingleRateRandomDrawAlgorithm.java
class SingleRateRandomDrawAlgorithm (line 16) | @Component("singleRateRandomDrawAlgorithm")
method randomDraw (line 19) | @Override
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/DrawBase.java
class DrawBase (line 15) | public class DrawBase extends DrawConfig {
method checkAndInitRateData (line 17) | public void checkAndInitRateData(Long strategyId, Integer strategyMode...
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/DrawConfig.java
class DrawConfig (line 16) | public class DrawConfig {
method init (line 26) | @PostConstruct
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/IDrawExec.java
type IDrawExec (line 11) | public interface IDrawExec {
method doDrawExec (line 13) | DrawResult doDrawExec(DrawReq req);
FILE: lottery-domain/src/main/java/cn/itedus/lottery/domain/strategy/service/draw/impl/DrawExecImpl.java
class DrawExecImpl (line 26) | @Service("drawExec")
method doDrawExec (line 34) | @Override
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IActivityDao.java
type IActivityDao (line 11) | @Mapper
method insert (line 14) | void insert(Activity req);
method queryActivityById (line 16) | Activity queryActivityById(Long activityId);
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IAwardDao.java
type IAwardDao (line 11) | @Mapper
method queryAwardInfo (line 14) | Award queryAwardInfo(String awardId);
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IStrategyDao.java
type IStrategyDao (line 11) | @Mapper
method queryStrategy (line 14) | Strategy queryStrategy(Long strategyId);
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/dao/IStrategyDetailDao.java
type IStrategyDetailDao (line 13) | @Mapper
method queryStrategyDetailList (line 16) | List<StrategyDetail> queryStrategyDetailList(Long strategyId);
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Activity.java
class Activity (line 12) | public class Activity {
method getId (line 50) | public Long getId() {
method setId (line 54) | public void setId(Long id) {
method getActivityId (line 58) | public Long getActivityId() {
method setActivityId (line 62) | public void setActivityId(Long activityId) {
method getActivityName (line 66) | public String getActivityName() {
method setActivityName (line 70) | public void setActivityName(String activityName) {
method getActivityDesc (line 74) | public String getActivityDesc() {
method setActivityDesc (line 78) | public void setActivityDesc(String activityDesc) {
method getBeginDateTime (line 82) | public Date getBeginDateTime() {
method setBeginDateTime (line 86) | public void setBeginDateTime(Date beginDateTime) {
method getEndDateTime (line 90) | public Date getEndDateTime() {
method setEndDateTime (line 94) | public void setEndDateTime(Date endDateTime) {
method getStockCount (line 98) | public Integer getStockCount() {
method setStockCount (line 102) | public void setStockCount(Integer stockCount) {
method getTakeCount (line 106) | public Integer getTakeCount() {
method setTakeCount (line 110) | public void setTakeCount(Integer takeCount) {
method getState (line 114) | public Integer getState() {
method setState (line 118) | public void setState(Integer state) {
method getCreator (line 122) | public String getCreator() {
method setCreator (line 126) | public void setCreator(String creator) {
method getCreateTime (line 130) | public Date getCreateTime() {
method setCreateTime (line 134) | public void setCreateTime(Date createTime) {
method getUpdateTime (line 138) | public Date getUpdateTime() {
method setUpdateTime (line 142) | public void setUpdateTime(Date updateTime) {
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Award.java
class Award (line 10) | public class Award {
method getId (line 36) | public Long getId() {
method setId (line 40) | public void setId(Long id) {
method getAwardId (line 44) | public String getAwardId() {
method setAwardId (line 48) | public void setAwardId(String awardId) {
method getAwardType (line 52) | public Integer getAwardType() {
method setAwardType (line 56) | public void setAwardType(Integer awardType) {
method getAwardCount (line 60) | public Integer getAwardCount() {
method setAwardCount (line 64) | public void setAwardCount(Integer awardCount) {
method getAwardName (line 68) | public String getAwardName() {
method setAwardName (line 72) | public void setAwardName(String awardName) {
method getAwardContent (line 76) | public String getAwardContent() {
method setAwardContent (line 80) | public void setAwardContent(String awardContent) {
method getCreateTime (line 84) | public Date getCreateTime() {
method setCreateTime (line 88) | public void setCreateTime(Date createTime) {
method getUpdateTime (line 92) | public Date getUpdateTime() {
method setUpdateTime (line 96) | public void setUpdateTime(Date updateTime) {
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/Strategy.java
class Strategy (line 12) | public class Strategy {
method getId (line 41) | public Long getId() {
method setId (line 45) | public void setId(Long id) {
method getStrategyId (line 49) | public Long getStrategyId() {
method setStrategyId (line 53) | public void setStrategyId(Long strategyId) {
method getStrategyDesc (line 57) | public String getStrategyDesc() {
method setStrategyDesc (line 61) | public void setStrategyDesc(String strategyDesc) {
method getStrategyMode (line 65) | public Integer getStrategyMode() {
method setStrategyMode (line 69) | public void setStrategyMode(Integer strategyMode) {
method getGrantType (line 73) | public Integer getGrantType() {
method setGrantType (line 77) | public void setGrantType(Integer grantType) {
method getGrantDate (line 81) | public Date getGrantDate() {
method setGrantDate (line 85) | public void setGrantDate(Date grantDate) {
method getExtInfo (line 89) | public String getExtInfo() {
method setExtInfo (line 93) | public void setExtInfo(String extInfo) {
method getCreateTime (line 97) | public Date getCreateTime() {
method setCreateTime (line 101) | public void setCreateTime(Date createTime) {
method getUpdateTime (line 105) | public Date getUpdateTime() {
method setUpdateTime (line 109) | public void setUpdateTime(Date updateTime) {
FILE: lottery-infrastructure/src/main/java/cn/itedus/lottery/infrastructure/po/StrategyDetail.java
class StrategyDetail (line 12) | public class StrategyDetail {
method getId (line 35) | public String getId() {
method setId (line 39) | public void setId(String id) {
method getStrategyId (line 43) | public Long getStrategyId() {
method setStrategyId (line 47) | public void setStrategyId(Long strategyId) {
method getAwardId (line 51) | public String getAwardId() {
method setAwardId (line 55) | public void setAwardId(String awardId) {
method getAwardCount (line 59) | public String getAwardCount() {
method setAwardCount (line 63) | public void setAwardCount(String awardCount) {
method getAwardRate (line 67) | public BigDecimal getAwardRate() {
method setAwardRate (line 71) | public void setAwardRate(BigDecimal awardRate) {
method getCreateTime (line 75) | public String getCreateTime() {
method setCreateTime (line 79) | public void setCreateTime(String createTime) {
method getUpdateTime (line 83) | public String getUpdateTime() {
method setUpdateTime (line 87) | public void setUpdateTime(String updateTime) {
FILE: lottery-interfaces/src/main/java/cn/itedus/lottery/LotteryApplication.java
class LotteryApplication (line 13) | @SpringBootApplication
method main (line 18) | public static void main(String[] args) {
FILE: lottery-interfaces/src/main/java/cn/itedus/lottery/interfaces/ActivityBooth.java
class ActivityBooth (line 22) | @Service
method queryActivityById (line 28) | @Override
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/ApiTest.java
class ApiTest (line 16) | public class ApiTest {
method test_strategy (line 26) | @Test
method test_idx (line 60) | @Test
method test_DrawStrategy (line 79) | @Test
method test_random (line 114) | @Test
class DrawStrategy (line 128) | class DrawStrategy {
method initRateTuple (line 147) | public void initRateTuple(List<Map<String, String>> drawConfig) {
method randomDraw (line 168) | public String randomDraw() {
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/DrawAlgorithmTest.java
class DrawAlgorithmTest (line 21) | @RunWith(SpringRunner.class)
method init (line 29) | @Before
method test_randomDrawAlgorithm (line 43) | @Test
FILE: lottery-interfaces/src/test/java/cn/itedus/lottery/test/SpringRunnerTest.java
class SpringRunnerTest (line 30) | @RunWith(SpringRunner.class)
method test_drawExec (line 42) | @Test
method test_insert (line 50) | @Test
method test_select (line 65) | @Test
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/IActivityBooth.java
type IActivityBooth (line 16) | public interface IActivityBooth {
method queryActivityById (line 18) | ActivityRes queryActivityById(ActivityReq req);
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/dto/ActivityDto.java
class ActivityDto (line 11) | public class ActivityDto implements Serializable {
method getActivityId (line 37) | public Long getActivityId() {
method setActivityId (line 41) | public void setActivityId(Long activityId) {
method getActivityName (line 45) | public String getActivityName() {
method setActivityName (line 49) | public void setActivityName(String activityName) {
method getActivityDesc (line 53) | public String getActivityDesc() {
method setActivityDesc (line 57) | public void setActivityDesc(String activityDesc) {
method getBeginDateTime (line 61) | public Date getBeginDateTime() {
method setBeginDateTime (line 65) | public void setBeginDateTime(Date beginDateTime) {
method getEndDateTime (line 69) | public Date getEndDateTime() {
method setEndDateTime (line 73) | public void setEndDateTime(Date endDateTime) {
method getStockCount (line 77) | public Integer getStockCount() {
method setStockCount (line 81) | public void setStockCount(Integer stockCount) {
method getTakeCount (line 85) | public Integer getTakeCount() {
method setTakeCount (line 89) | public void setTakeCount(Integer takeCount) {
method getState (line 93) | public Integer getState() {
method setState (line 97) | public void setState(Integer state) {
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/req/ActivityReq.java
class ActivityReq (line 10) | public class ActivityReq implements Serializable {
method getActivityId (line 14) | public Long getActivityId() {
method setActivityId (line 18) | public void setActivityId(Long activityId) {
FILE: lottery-rpc/src/main/java/cn/itedus/lottery/rpc/res/ActivityRes.java
class ActivityRes (line 13) | public class ActivityRes implements Serializable {
method ActivityRes (line 18) | public ActivityRes() {
method ActivityRes (line 21) | public ActivityRes(Result result) {
method ActivityRes (line 25) | public ActivityRes(Result result, ActivityDto activity) {
method getResult (line 30) | public Result getResult() {
method setResult (line 34) | public void setResult(Result result) {
method getActivity (line 38) | public ActivityDto getActivity() {
method setActivity (line 42) | public void setActivity(ActivityDto activity) {
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (100K chars).
[
{
"path": ".gitignore",
"chars": 278,
"preview": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Packa"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 8088,
"preview": "# Lottery 抽奖系统 - 基于领域驱动设计的四层架构实践\n\n[. The extraction includes 50 files (76.9 KB), approximately 24.6k tokens, and a symbol index with 208 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.