一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - SpringBoot 簽到獎勵實現方案的示例代碼

SpringBoot 簽到獎勵實現方案的示例代碼

2020-08-31 13:58當年的春天 Java教程

這篇文章主要介紹了SpringBoot 簽到獎勵實現方案的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

最近在做社交業務,用戶進入APP后有簽到功能,簽到成功后獲取相應的獎勵:

項目狀況:前期嘗試業務階段;

特點:

  • 快速實現(不需要做太重,滿足初期推廣運營即可)
  • 快速投入市場去運營

用戶簽到:

  • 用戶在每次啟動時查詢簽到記錄(規則:連續7日簽到從0開始,簽到過程中有斷簽從0開始)
  • 如果今日未簽到則提示用戶可以進行簽到
  • 用戶簽到獲取相應的獎勵

提到簽到,腦海中首先浮現特點:

  • 需要記錄每位用戶每天的簽到情況
  • 查詢時根據規則進行簽到記錄情況

需求&流程設計&技術實現方案

需求原型圖

SpringBoot 簽到獎勵實現方案的示例代碼

查詢簽到記錄

SpringBoot 簽到獎勵實現方案的示例代碼

進行簽到

SpringBoot 簽到獎勵實現方案的示例代碼

技術實現方案

  • SpringBoot
  • MySQL

數據庫表結構

簽到記錄最新表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE `zh_sign_in` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `bu_no` varchar(32) DEFAULT NULL COMMENT '業務編碼',
 `customer_id` varchar(32) DEFAULT NULL COMMENT '簽到用戶編碼',
 `sign_in_date` datetime DEFAULT NULL COMMENT '簽到日期(單位精確到日)',
 `reward_money` int(11) DEFAULT NULL COMMENT '本次簽到獎勵金幣個數',
 `continuite_day` int(2) DEFAULT '1' COMMENT '連續簽到天數(A:7天內如果有斷簽從0開始 B:7天簽滿從0開始)',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
 `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
 `param1` int(2) DEFAULT NULL COMMENT '預留字段1',
 `param2` int(4) DEFAULT NULL COMMENT '預留字段2',
 `param3` int(11) DEFAULT NULL COMMENT '預留字段3',
 `param4` varchar(20) DEFAULT NULL COMMENT '預留字段4',
 `param5` varchar(32) DEFAULT NULL COMMENT '預留字段5',
 `param6` varchar(64) DEFAULT NULL COMMENT '預留字段6',
 PRIMARY KEY (`id`) USING BTREE,
 UNIQUE KEY `uk_zh_sign_in_buno` (`bu_no`),
 UNIQUE KEY `uk_zh_sign_in_cid_signindate` (`customer_id`,`sign_in_date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶簽到表';

簽到記錄歷史表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE `zh_sign_in_hist` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `bu_no` varchar(32) DEFAULT NULL COMMENT '業務編碼',
 `customer_id` varchar(32) DEFAULT NULL COMMENT '簽到用戶編碼',
 `sign_in_date` datetime NULL DEFAULT NULL COMMENT '簽到日期(單位精確到日)',
 `reward_money` int(11) DEFAULT NULL COMMENT '本次簽到獎勵金幣個數',
 `continuite_day` int(2) DEFAULT '1' COMMENT '連續簽到天數(A:7天內如果有斷簽從0開始 B:7天簽滿從0開始)',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
 `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',
 `param1` int(2) DEFAULT NULL COMMENT '預留字段1',
 `param2` int(4) DEFAULT NULL COMMENT '預留字段2',
 `param3` int(11) DEFAULT NULL COMMENT '預留字段3',
 `param4` varchar(20) DEFAULT NULL COMMENT '預留字段4',
 `param5` varchar(32) DEFAULT NULL COMMENT '預留字段5',
 `param6` varchar(64) DEFAULT NULL COMMENT '預留字段6',
 PRIMARY KEY (`id`) USING BTREE,
 UNIQUE KEY `uk_zh_sign_in_hist_cid_signindate` (`customer_id`,`sign_in_date`) USING BTREE,
 KEY `key_zh_sign_in_hist_buno` (`bu_no`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶簽到歷史表';

代碼實現

完整代碼(GitHub,歡迎大家Star,Fork,Watch)

https://github.com/dangnianchuntian/springboot

主要代碼展示

Controller

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * Copyright (c) 2020. [email protected] All Rights Reserved.
 * 項目名稱:Spring Boot實戰:簽到獎勵實現方案
 * 類名稱:SignInController.java
 * 創建人:張晗
 * 聯系方式:[email protected]
 * 開源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://zhanghan.blog.csdn.net
 */
 
package com.zhanghan.zhsignin.controller;
 
import com.zhanghan.zhsignin.controller.request.PostSignInRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.zhanghan.zhsignin.controller.request.ListSignInDetailRequest;
import com.zhanghan.zhsignin.service.SignInService;
 
@RestController
public class SignInController {
 
  @Autowired
  private SignInService signInService;
 
  /**
   * 查詢簽到記錄
   */
  @RequestMapping(value = "/list/sign/in/detail", method = RequestMethod.POST)
  public Object listSignInDetail(@RequestBody @Validated ListSignInDetailRequest listSignInDetailRequest) {
    return signInService.listSignInDetail(listSignInDetailRequest);
  }
 
  /**
   * 用戶進行簽到
   */
  @RequestMapping(value = "/post/sign/in", method = RequestMethod.POST)
  public Object postSignIn(@RequestBody @Validated PostSignInRequest postSignInRequest) {
    return signInService.postSignIn(postSignInRequest);
  }
 
}

service

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Copyright (c) 2020. [email protected] All Rights Reserved.
 * 項目名稱:Spring Boot實戰:簽到獎勵實現方案
 * 類名稱:SignInServiceImpl.java
 * 創建人:張晗
 * 聯系方式:[email protected]
 * 開源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://zhanghan.blog.csdn.net
 */
 
package com.zhanghan.zhsignin.service.impl;
 
import cn.hutool.core.util.IdUtil;
import com.zhanghan.zhsignin.config.SignInRewardMoneyListConfig;
import com.zhanghan.zhsignin.constant.SignInConstant;
import com.zhanghan.zhsignin.controller.request.ListSignInDetailRequest;
import com.zhanghan.zhsignin.controller.request.PostSignInRequest;
import com.zhanghan.zhsignin.controller.response.ListSignInDetailResponse;
import com.zhanghan.zhsignin.mybatis.entity.XZhSignInEntity;
import com.zhanghan.zhsignin.mybatis.entity.XZhSignInHistEntity;
import com.zhanghan.zhsignin.mybatis.mapper.XZhSignInHistMapper;
import com.zhanghan.zhsignin.mybatis.mapper.XZhSignInMapper;
import com.zhanghan.zhsignin.service.SignInService;
import com.zhanghan.zhsignin.util.DateUtils;
import com.zhanghan.zhsignin.util.wrapper.WrapMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
 
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
 
import static com.zhanghan.zhsignin.constant.SignInConstant.*;
 
@Service
public class SignInServiceImpl implements SignInService {
 
  @Autowired
  private XZhSignInMapper xZhSignInMapper;
 
  @Autowired
  private XZhSignInHistMapper xZhSignInHistMapper;
 
  //校驗連續天數是否為7
  @Value("#{T(java.lang.Integer).parseInt('${zh.sign.in.continuite.day.threshold:7}')}")
  public Integer continuiteDayThreshold;
 
  //簽到獎勵金幣集合配置
  @Autowired
  public SignInRewardMoneyListConfig signInRewardMoneyListConfig;
 
 
  /**
   * 查詢用戶簽到記錄
   */
  @Override
  public Object listSignInDetail(ListSignInDetailRequest listSignInDetailRequest) {
 
    //若配置文件中未配置簽到獎勵則不展示簽到記錄
    List<Integer> signInRewardMoneyListConfigList = signInRewardMoneyListConfig.getList();
    if (CollectionUtils.isEmpty(signInRewardMoneyListConfigList)) {
      return WrapMapper.ok(new ListSignInDetailResponse(false));
    }
 
    String customerId = listSignInDetailRequest.getCustomerId();
    XZhSignInEntity xZhSignInEntity = xZhSignInMapper.findByCustomerId(customerId);
 
    List<ListSignInDetailResponse.SignInDetail> signInDetailList = signInRewardMoneyListConfigList.stream().map(aa -> new ListSignInDetailResponse.SignInDetail(0, aa)).collect(Collectors.toList());
 
    //該用戶之前未簽到過
    if (null == xZhSignInEntity) {
      return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList));
    }
 
    long signInDateTime = xZhSignInEntity.getSignInDate().getTime();
 
    //最近一次簽到是否為昨日之前
    if (signInDateTime < DateUtils.getYesterdayDateTime()) {
      return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList));
    }
 
    //最近一次簽到是否為昨日
    Integer todaySignStatus = TODAY_YES_SIGN_IN;
    Integer continuiteDay = xZhSignInEntity.getContinuiteDay();
    if (signInDateTime < DateUtils.getTodayDateTime()) {
      //最近一次簽到是昨日且之前已連續簽到7日
      if (continuiteDay >= continuiteDayThreshold) {
        return WrapMapper.ok(new ListSignInDetailResponse(TODAY_NOT_SIGN_IN, SignInConstant.CONTINUITE_DAY_ZERO, signInDetailList));
      }
      //最近一次簽到是昨日且之前連續未超7日
      todaySignStatus = TODAY_NOT_SIGN_IN;
    }
    //查詢用戶簽到歷史記錄
    List<XZhSignInHistEntity> xZhSignInHistEntitieList = xZhSignInHistMapper.listByCustomerIdAndLimit(customerId, continuiteDay);
    for (XZhSignInHistEntity xZhSignInHistEntity : xZhSignInHistEntitieList) {
      ListSignInDetailResponse.SignInDetail signInDetail = new ListSignInDetailResponse.SignInDetail(TODAY_YES_SIGN_IN, xZhSignInHistEntity.getRewardMoney());
      signInDetailList.remove(xZhSignInHistEntity.getContinuiteDay() - 1);
      signInDetailList.add(xZhSignInHistEntity.getContinuiteDay() - 1, signInDetail);
    }
 
    return WrapMapper.ok(new ListSignInDetailResponse(todaySignStatus, continuiteDay, signInDetailList));
  }
 
  /**
   * 進行簽到
   */
  @Override
  public Object postSignIn(PostSignInRequest postSignInRequest) {
 
    //若配置文件中未配置簽到獎勵則不展示簽到記錄
    List<Integer> signInRewardMoneyListConfigList = signInRewardMoneyListConfig.getList();
    if (CollectionUtils.isEmpty(signInRewardMoneyListConfigList)) {
      return WrapMapper.ok();
    }
 
    //獲取session用戶對象
    String customerId = postSignInRequest.getCustomerId();
    //根據customerId查詢用戶簽到記錄
    XZhSignInEntity xZhSignInEntityByCustomerId = xZhSignInMapper.findByCustomerId(customerId);
    //簽到記錄是否為空
    if (null == xZhSignInEntityByCustomerId) {
      XZhSignInEntity xZhSignInEntity = new XZhSignInEntity();
      xZhSignInEntity.setBuNo(IdUtil.simpleUUID());
      xZhSignInEntity.setCustomerId(customerId);
      xZhSignInEntity.setContinuiteDay(CONTINUITE_DAY_ONE);
      xZhSignInEntity.setRewardMoney(signInRewardMoneyListConfigList.get(0));
      xZhSignInEntity.setSignInDate(DateUtils.getTodayDate());
      insertSigninAndHist(xZhSignInEntity);
      return WrapMapper.ok();
    }
 
    long signInDateTime = xZhSignInEntityByCustomerId.getSignInDate().getTime();
    if (signInDateTime == DateUtils.getTodayDateTime()) {
      return WrapMapper.error("今天已經簽到");
    }
 
    //獲取連續簽到天數
    Integer continuiteDay = continuiteDay(xZhSignInEntityByCustomerId.getContinuiteDay(), signInDateTime);
    xZhSignInEntityByCustomerId.setSignInDate(DateUtils.getTodayDate());
    xZhSignInEntityByCustomerId.setContinuiteDay(continuiteDay);
    xZhSignInEntityByCustomerId.setRewardMoney(signInRewardMoneyListConfigList.get(continuiteDay - 1));
    xZhSignInEntityByCustomerId.setUpdateTime(new Date());
    xZhSignInEntityByCustomerId.setBuNo(IdUtil.simpleUUID());
    updateSignInAndInsertHist(xZhSignInEntityByCustomerId);
 
    return WrapMapper.ok();
 
  }
 
  private Integer continuiteDay(Integer continuiteDay, Long signInDateTime) {
    if (signInDateTime < DateUtils.getYesterdayDateTime()) {
      return CONTINUITE_DAY_ONE;
    }
    if (continuiteDay >= continuiteDayThreshold) {
      return CONTINUITE_DAY_ONE;
    }
    return continuiteDay + 1;
  }
 
  private void insertSigninAndHist(XZhSignInEntity xZhSignInEntity) {
    xZhSignInMapper.insertSelective(xZhSignInEntity);
    XZhSignInHistEntity xZhSignInHistEntity = new XZhSignInHistEntity();
    BeanUtils.copyProperties(xZhSignInEntity, xZhSignInHistEntity);
    xZhSignInHistEntity.setId(null);
    xZhSignInHistMapper.insertSelective(xZhSignInHistEntity);
  }
 
  private void updateSignInAndInsertHist(XZhSignInEntity xZhSignInEntity) {
    xZhSignInMapper.updateByPrimaryKeySelective(xZhSignInEntity);
    XZhSignInHistEntity xZhSignInHistEntity = new XZhSignInHistEntity();
    BeanUtils.copyProperties(xZhSignInEntity, xZhSignInHistEntity);
    xZhSignInHistEntity.setId(null);
    xZhSignInHistMapper.insertSelective(xZhSignInHistEntity);
  }
 
}

測試

模擬用戶進行簽到

進行請求

SpringBoot 簽到獎勵實現方案的示例代碼

查看數據庫結果

SpringBoot 簽到獎勵實現方案的示例代碼

模擬用戶查詢簽到記錄

進行請求

SpringBoot 簽到獎勵實現方案的示例代碼

總結

  • 亮點:實現業務連續簽到,斷簽以及獎勵的業務
  • 注意點:基于數據庫查詢做的,在進行簽到接口需要用redis鎖防止并發操作
  • 后續會持續分享更多業務中的亮點

到此這篇關于SpringBoot 簽到獎勵實現方案的示例代碼的文章就介紹到這了,更多相關SpringBoot 簽到獎勵內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/u012829124/article/details/108306434

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99视频都是精品热在线播放 | 99久久综合精品免费 | 日本888xxxx| 男人在女人下面狂躁 | 射逼网 | aaaa黄| 四虎精品免费国产成人 | 亚洲国产精品久久精品成人网站 | 免费在线视频一区 | 2021麻豆剧果冻传媒入口永久 | 欧美日韩国产手机在线观看视频 | 91正在 播放| 天天色天天色天天色 | 亚洲无人区乱码中文字幕 | 亚洲精品6久久久久中文字幕 | 福利国产片| 99精品国产美女福到在线不卡 | 青草视频在线观看免费视频 | 精品国产免费一区二区三区 | 国产-第1页-草草影院 | 国产一区日韩二区欧美三区 | 成人涩涩屋福利视频 | 草草剧场 | 好大好深好涨好烫还要 | 91香蕉视频在线 | 护士伦理片 | 免费国产高清精品一区在线 | 美女视频在线观看视频 | 香港三级血恋3 | 特黄特色大片免费高清视频 | 国产真实乱子伦xxxxchina | 久久国产主播福利在线 | 日韩在线1 | 日韩欧美精品 | 校花被拖到野外伦小说 | 青青青在线视频播放 | kayden·kross hd在线| 亚洲天堂三区 | 按摩院已婚妇女中文字幕 | 色综合久久综合网欧美综合网 | 久久国产36精品色熟妇 |