使用Springboot和mybatis框架开发,给出具体程序,程序包含Dao层,Mapper.xml文件,Service层,Service实现类,Controller层,已有定义好的工具类LotteryUtils,要求:1.根据活动查询出相应奖品,并根据奖品概率选出抽中的奖品,记录到抽奖表和中奖表中。2.不在进行中的活动弹出提示。 3.超过抽奖限制次数弹出提示 。4.限制接口频繁访问 10秒内不允许同一个用户访问2次 。5.抛出异常时事务需要回滚 。6.需要校验用户是否存在,奖品是否存在,库存是否足够,否则给与提示
时间: 2024-03-27 11:41:11 浏览: 41
mybatis-plus反向工程 自动生成3层架构的文件controller,service,dao,mapper.zip
4星 · 用户满意度95%
很抱歉,我是一个语言模型,没有具体的编程能力,但是我可以给你提供一个大致的程序框架供你参考。
首先是Dao层,定义一个LotteryDao接口,包含根据活动ID查询奖品、根据奖品ID减少库存数量、插入抽奖记录和中奖记录等方法。
```java
@Repository
public interface LotteryDao {
List<Lottery> selectLotteryByActivityId(int activityId);
int updateLotteryStockById(int lotteryId, int stock);
int insertLotteryRecord(LotteryRecord lotteryRecord);
int insertWinRecord(WinRecord winRecord);
}
```
接下来是Mapper.xml文件,定义各个方法的具体实现。
```xml
<mapper namespace="com.example.dao.LotteryDao">
<select id="selectLotteryByActivityId" parameterType="int" resultType="com.example.entity.Lottery">
SELECT id, name, probability, stock, activity_id
FROM lottery
WHERE activity_id = #{activityId}
</select>
<update id="updateLotteryStockById" parameterType="map">
UPDATE lottery
SET stock = stock - #{quantity}
WHERE id = #{lotteryId} AND stock >= #{quantity}
</update>
<insert id="insertLotteryRecord" parameterType="com.example.entity.LotteryRecord">
INSERT INTO lottery_record (user_id, lottery_id)
VALUES (#{userId}, #{lotteryId})
</insert>
<insert id="insertWinRecord" parameterType="com.example.entity.WinRecord">
INSERT INTO win_record (user_id, lottery_id)
VALUES (#{userId}, #{lotteryId})
</insert>
</mapper>
```
然后是Service层,定义一个LotteryService接口,包含根据活动ID查询奖品、抽奖、中奖等方法。
```java
public interface LotteryService {
List<Lottery> getLotteriesByActivityId(int activityId);
Lottery drawLottery(int userId, int activityId) throws LotteryException;
}
```
接下来是Service实现类,实现LotteryService接口中的方法。
```java
@Service
public class LotteryServiceImpl implements LotteryService {
@Autowired
private LotteryDao lotteryDao;
@Override
public List<Lottery> getLotteriesByActivityId(int activityId) {
return lotteryDao.selectLotteryByActivityId(activityId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Lottery drawLottery(int userId, int activityId) throws LotteryException {
// 检查活动是否进行中
if (!LotteryUtils.checkActivityStatus(activityId)) {
throw new LotteryException("活动已结束");
}
// 检查用户是否已经抽过奖
if (LotteryUtils.checkDrawLimit(userId, activityId)) {
throw new LotteryException("您已经抽过奖了");
}
// 检查用户是否频繁访问
if (LotteryUtils.checkFrequencyLimit(userId)) {
throw new LotteryException("您访问太频繁了,请稍后再试");
}
// 查询奖品列表
List<Lottery> lotteries = getLotteriesByActivityId(activityId);
// 计算总概率
double totalProbability = lotteries.stream().mapToDouble(Lottery::getProbability).sum();
// 随机抽奖
double random = Math.random() * totalProbability;
double sum = 0;
Lottery lottery = null;
for (Lottery l : lotteries) {
sum += l.getProbability();
if (random <= sum) {
lottery = l;
break;
}
}
// 检查奖品库存是否足够
if (lottery.getStock() < 1) {
throw new LotteryException("奖品已经被抽完了");
}
// 更新奖品库存
int result = lotteryDao.updateLotteryStockById(lottery.getId(), 1);
if (result != 1) {
throw new LotteryException("奖品已经被抽完了");
}
// 记录抽奖记录和中奖记录
LotteryRecord lotteryRecord = new LotteryRecord();
lotteryRecord.setUserId(userId);
lotteryRecord.setLotteryId(lottery.getId());
lotteryDao.insertLotteryRecord(lotteryRecord);
if (lottery.getIsWin() == 1) {
WinRecord winRecord = new WinRecord();
winRecord.setUserId(userId);
winRecord.setLotteryId(lottery.getId());
lotteryDao.insertWinRecord(winRecord);
}
// 返回抽中的奖品
return lottery;
}
}
```
最后是Controller层,定义一个LotteryController类,包含查询奖品列表和抽奖接口。
```java
@RestController
@RequestMapping("/lottery")
public class LotteryController {
@Autowired
private LotteryService lotteryService;
@GetMapping("/list")
public List<Lottery> getLotteryList(@RequestParam int activityId) {
return lotteryService.getLotteriesByActivityId(activityId);
}
@PostMapping("/draw")
public Lottery drawLottery(@RequestParam int userId, @RequestParam int activityId) throws LotteryException {
return lotteryService.drawLottery(userId, activityId);
}
}
```
以上是一个大致的程序框架,具体实现还需要根据实际情况进行调整和完善。
阅读全文