Authored by 邱骏

签到逻辑

@@ -28,12 +28,12 @@ const dailyCheckInController = { @@ -28,12 +28,12 @@ const dailyCheckInController = {
28 * @returns {Promise.<void>} 28 * @returns {Promise.<void>}
29 */ 29 */
30 async actCreate(req, res) { 30 async actCreate(req, res) {
31 - console.log(req.body); 31 +
32 const title = req.body.title; 32 const title = req.body.title;
33 const startTime = req.body.startTime; 33 const startTime = req.body.startTime;
34 const endTime = req.body.endTime; 34 const endTime = req.body.endTime;
35 const normalWheelId = req.body.normalWheelId || ''; 35 const normalWheelId = req.body.normalWheelId || '';
36 - let prizeDayArr = req.body.prizeDays ? JSON.parse(req.body.prizeDays) : []; 36 + let prizeDayArr = req.body.prizeDayArr ? JSON.parse(req.body.prizeDayArr) : [];
37 37
38 if (!title || !startTime || !endTime || prizeDayArr.length === 0) { 38 if (!title || !startTime || !endTime || prizeDayArr.length === 0) {
39 return res.json({ 39 return res.json({
@@ -61,7 +61,77 @@ const dailyCheckInController = { @@ -61,7 +61,77 @@ const dailyCheckInController = {
61 } catch (err) { 61 } catch (err) {
62 res.json(err); 62 res.json(err);
63 } 63 }
  64 + },
  65 +
  66 + /**
  67 + * 获取活动列表获取通过id获取单个活动信息
  68 + * @param req
  69 + * @param res
  70 + * @returns {Promise.<void>}
  71 + */
  72 + async actList(req, res) {
  73 + try {
  74 + let result = await req.ctx(dailyCheckInModel).activityList();
  75 +
  76 + return res.json({
  77 + code: 200,
  78 + data: result
  79 + });
  80 +
  81 + } catch (err) {
  82 + return res.json(err);
  83 + }
  84 + },
  85 +
  86 + /**
  87 + * 通过id获取单个活动信息
  88 + * @param req
  89 + * @param res
  90 + * @returns {Promise.<void>}
  91 + */
  92 + async actInfo(req, res) {
  93 + let actId = req.query.id || 0;
  94 +
  95 + if (!actId) {
  96 + return res.json({
  97 + code: 400,
  98 + message: '缺少参数'
  99 + });
  100 + }
  101 +
  102 + let result = await req.ctx(dailyCheckInModel).actInfo(actId);
  103 +
  104 + if (result.code !== 201) {
  105 + return res.json({
  106 + code: 200,
  107 + data: result
  108 + });
  109 + } else {
  110 + return res.json(result);
  111 + }
  112 + },
  113 +
  114 + /**
  115 + * 通过id删除一个活动
  116 + * @param req
  117 + * @param res
  118 + * @returns {Promise.<void>}
  119 + */
  120 + async actDelete(req, res) {
  121 + const id = req.body.id;
  122 +
  123 + try {
  124 + const result = await req.ctx(dailyCheckInModel).actDelete(id);
  125 +
  126 + return res.json({
  127 + code: 200,
  128 + data: result
  129 + });
  130 + } catch (err) {
  131 + return res.json(err);
  132 + }
64 } 133 }
  134 +
65 }; 135 };
66 136
67 module.exports = dailyCheckInController; 137 module.exports = dailyCheckInController;
@@ -2,8 +2,9 @@ @@ -2,8 +2,9 @@
2 * Created by qiujun on 2019/5/7. 2 * Created by qiujun on 2019/5/7.
3 */ 3 */
4 const _ = require('lodash'); 4 const _ = require('lodash');
5 -const md5 = require('yoho-md5');  
6 -const ACTIVITY_TABLE = 'dailysignin:activity'; // 活动表 5 +const aes = require('../../../utils/aes');
  6 +const PARENT_TABLE_NAME = 'dailysignin';
  7 +const TABLE_NAME = PARENT_TABLE_NAME + ':activity'; // 签到活动表
7 8
8 class ActDailyCheckInModel extends global.yoho.BaseModel { 9 class ActDailyCheckInModel extends global.yoho.BaseModel {
9 constructor(ctx) { 10 constructor(ctx) {
@@ -14,9 +15,9 @@ class ActDailyCheckInModel extends global.yoho.BaseModel { @@ -14,9 +15,9 @@ class ActDailyCheckInModel extends global.yoho.BaseModel {
14 15
15 // 获取签到活动列表 16 // 获取签到活动列表
16 async activityList() { 17 async activityList() {
17 - let length = await this.client.llenAsync(ACTIVITY_TABLE); 18 + let length = await this.client.llenAsync(TABLE_NAME);
18 19
19 - return this.client.lrangeAsync(ACTIVITY_TABLE, 0, length - 1).then(acts => { 20 + return this.client.lrangeAsync(TABLE_NAME, 0, length - 1).then(acts => {
20 return acts.filter(act => act).map(act => { 21 return acts.filter(act => act).map(act => {
21 return JSON.parse(act); 22 return JSON.parse(act);
22 }); 23 });
@@ -25,13 +26,46 @@ class ActDailyCheckInModel extends global.yoho.BaseModel { @@ -25,13 +26,46 @@ class ActDailyCheckInModel extends global.yoho.BaseModel {
25 26
26 // 创建签到活动 27 // 创建签到活动
27 async createActivity(data) { 28 async createActivity(data) {
28 - let length = await this.client.llenAsync(ACTIVITY_TABLE); 29 + let length = await this.client.llenAsync(TABLE_NAME);
29 30
30 data.id = length + 1; 31 data.id = length + 1;
31 - data.encryptedId = md5(length + 1);  
32 - return this.client.rpushAsync(ACTIVITY_TABLE, JSON.stringify(data)); 32 + data.encryptedId = aes.encryptUid(length + 1);
  33 + return this.client.rpushAsync(TABLE_NAME, JSON.stringify(data));
33 } 34 }
34 35
  36 + /**
  37 + * 获取活动信息
  38 + * @param actId
  39 + * @returns {Promise.<void>}
  40 + */
  41 + async actInfo(actId) {
  42 + let idx = parseInt(aes.decryptUid(actId), 10) - 1;
  43 +
  44 + if (idx) {
  45 + return this.client.lrangeAsync(TABLE_NAME, idx, idx).then(act => {
  46 + return JSON.parse(act[0] || {});
  47 + });
  48 + } else {
  49 + return {
  50 + code: 201,
  51 + message: '无活动信息'
  52 + };
  53 + }
  54 +
  55 +
  56 + }
  57 +
  58 + /**
  59 + * 删除活动
  60 + * @param id
  61 + * @returns {Promise.<*>}
  62 + */
  63 + async actDelete(id) {
  64 + id = parseInt(aes.decryptUid(id), 10);
  65 + return this.client.lsetAsync(TABLE_NAME, id - 1, '');
  66 + }
  67 +
  68 +
35 69
36 } 70 }
37 71
@@ -115,8 +115,13 @@ router.get('/wheelSurf/*', wheelSurf.entry); @@ -115,8 +115,13 @@ router.get('/wheelSurf/*', wheelSurf.entry);
115 115
116 // 签到活动管理 116 // 签到活动管理
117 router.get('/dailyCheckIn', dailyCheckIn.entry); 117 router.get('/dailyCheckIn', dailyCheckIn.entry);
118 -router.get('/dailyCheckIn/*', dailyCheckIn.entry);  
119 -router.post('/dailyCheckIn/api/create', dailyCheckIn.actCreate);  
120 118
121 119
  120 +router.post('/dailyCheckIn/api/create', dailyCheckIn.actCreate); // 创建签到活动
  121 +router.get('/dailyCheckIn/api/actList', dailyCheckIn.actList); // 获取活动列表
  122 +router.get('/dailyCheckIn/api/actInfo', dailyCheckIn.actInfo); // 获取活动信息
  123 +router.post('/dailyCheckIn/api/delete', dailyCheckIn.actDelete);
  124 +
  125 +router.get('/dailyCheckIn/*', dailyCheckIn.entry);
  126 +
122 module.exports = router; 127 module.exports = router;
1 /** 1 /**
  2 + * 签到活动controller
2 * Created by qiujun on 2019/5/7. 3 * Created by qiujun on 2019/5/7.
3 */ 4 */
  5 +const dailyCheckInModel = require('../models/daily-check-in');
  6 +
  7 +const dailyCheckInController = {
  8 + /**
  9 + * 普通签到
  10 + * @param req
  11 + * @param res
  12 + * @returns {Promise.<void>}
  13 + */
  14 + async checkInNormal(req, res) {
  15 + let {actId, uid, sessionKey, appVersion, appSessionType} = req.body;
  16 +
  17 + if (!actId) {
  18 + return res.json({
  19 + code: 400,
  20 + message: '缺少参数'
  21 + });
  22 + }
  23 +
  24 + if (!parseInt(uid, 10) || !sessionKey || !appVersion || !appSessionType) {
  25 + return res.json({
  26 + code: 401,
  27 + message: '未登录'
  28 + });
  29 + }
  30 +
  31 + let params = {
  32 + actId,
  33 + uid: parseInt(uid, 10),
  34 + sessionKey,
  35 + appVersion,
  36 + appSessionType
  37 + };
  38 +
  39 + try {
  40 + let result = await req.ctx(dailyCheckInModel).checkInNormal(params);
  41 +
  42 + return res.json(result);
  43 + } catch (err) {
  44 + return res.json(err);
  45 + }
  46 + },
  47 +
  48 + async checkInCumulative(req, res) {
  49 + let {actId, uid, sessionKey, appVersion, appSessionType} = req.body;
  50 +
  51 + if (!actId) {
  52 + return res.json({
  53 + code: 400,
  54 + message: '缺少参数'
  55 + });
  56 + }
  57 +
  58 + if (!parseInt(uid, 10) || !sessionKey || !appVersion || !appSessionType) {
  59 + return res.json({
  60 + code: 401,
  61 + message: '未登录'
  62 + });
  63 + }
  64 +
  65 + let params = {
  66 + actId,
  67 + uid: parseInt(uid, 10),
  68 + sessionKey,
  69 + appVersion,
  70 + appSessionType
  71 + };
  72 +
  73 + try {
  74 + let result = await req.ctx(dailyCheckInModel).checkInCumulative(params);
  75 +
  76 + return res.json(result);
  77 + } catch (err) {
  78 + return res.json(err);
  79 + }
  80 + },
  81 +
  82 + /**
  83 + * 获取用户签到累计信息
  84 + * @param req
  85 + * @param res
  86 + * @returns {Promise.<void>}
  87 + */
  88 + async getUserCumulativeData(req, res) {
  89 + let {actId, uid} = req.query;
  90 +
  91 + if (!actId || !parseInt(uid, 10)) {
  92 + return res.json({
  93 + code: 400,
  94 + message: '缺少参数'
  95 + });
  96 + }
  97 +
  98 + let params = {
  99 + actId,
  100 + uid: parseInt(uid, 10)
  101 + };
  102 +
  103 + try {
  104 + req.ctx(dailyCheckInModel).getUserCumulativeData(params).then(result => {
  105 + if (result.code === 200) {
  106 + let cumDaysResult = [];
  107 + let cumDaysArr = [];
  108 + let cumPrizeResult = result.cumPrize;
  109 +
  110 + result.cumDays.map(ret => {
  111 + if (ret.createTime) {
  112 + cumDaysArr.push(ret.createTime);// 把签到时间拿出来,用于签到日期列表
  113 + cumDaysResult.push({ // 每次签到获得的奖品
  114 + prizeId: ret.prizeId,
  115 + prizeImg: ret.prizeImg,
  116 + prizeDesc: ret.prizeDesc,
  117 + prizeType: ret.prizeType,
  118 + createTime: ret.createTime
  119 + });
  120 + }
  121 + });
  122 +
  123 +
  124 + return res.json({
  125 + code: 200,
  126 + actId: actId,
  127 + uid: uid,
  128 + data: {
  129 + signDays: cumDaysArr,
  130 + cumDays: cumDaysResult,
  131 + cumPrize: cumPrizeResult
  132 + }
  133 + });
  134 + } else {
  135 + return res.json(result);
  136 + }
  137 + });
  138 + } catch (err) {
  139 + return res.json(err);
  140 + }
  141 +
  142 + },
  143 +
  144 + /**
  145 + * 保存用户信息
  146 + * @param req
  147 + * @param res
  148 + * @returns {Promise.<void>}
  149 + */
  150 + async saveUserInfo(req, res) {
  151 + let {uid, actId, phone, nickname} = req.body;
  152 + let regExp = /^1[34578]\d{9}$/;
  153 +
  154 + if (!actId || !uid || !phone || phone.toString().length !== 11 || !nickname) {
  155 + return res.json({
  156 + code: 400,
  157 + message: '缺少参数'
  158 + });
  159 + }
  160 +
  161 + if (!regExp.test(phone)) {
  162 + return res.json({
  163 + code: 400,
  164 + message: '错误的手机号码格式'
  165 + });
  166 + }
  167 +
  168 +
  169 + let params = {
  170 + actId,
  171 + uid,
  172 + phone,
  173 + nickname
  174 + };
  175 +
  176 + try {
  177 + let result = await req.ctx(dailyCheckInModel).saveUserInfo(params);
  178 +
  179 + return res.json(result);
  180 + } catch (err) {
  181 + return res.json(err);
  182 + }
  183 + },
  184 +
  185 + /**
  186 + * 获取用户是否填写过手机号的信息
  187 + * @param req
  188 + * @param res
  189 + * @returns {Promise.<void>}
  190 + */
  191 + async getUserInfo(req, res) {
  192 + let {uid, actId} = req.query;
  193 +
  194 + if (!actId || !uid) {
  195 + return res.json({
  196 + code: 400,
  197 + message: '缺少参数'
  198 + });
  199 + }
  200 +
  201 + try {
  202 + let result = await req.ctx(dailyCheckInModel).getUserInfo({actId, uid});
  203 +
  204 + return res.json(result);
  205 + } catch (err) {
  206 + return res.json(err);
  207 + }
  208 + },
  209 +
  210 + /**
  211 + * 获取所有实物中奖人员列表
  212 + * @param req
  213 + * @param res
  214 + * @returns {Promise.<void>}
  215 + */
  216 + async getWinnerList(req, res) {
  217 + let {actId} = req.query;
  218 +
  219 + if (!actId) {
  220 + return res.json({
  221 + code: 400,
  222 + message: '缺少参数'
  223 + });
  224 + }
  225 +
  226 + try {
  227 + let result = await req.ctx(dailyCheckInModel).getWinnerList({actId: actId});
  228 +
  229 + return res.json({
  230 + code: 200,
  231 + data: result
  232 + });
  233 + } catch (err) {
  234 + return res.json(err);
  235 + }
  236 + }
  237 +};
  238 +
  239 +module.exports = dailyCheckInController;
1 /** 1 /**
  2 + * 签到活动model
2 * Created by qiujun on 2019/5/7. 3 * Created by qiujun on 2019/5/7.
3 */ 4 */
  5 +const _ = require('lodash');
  6 +const aes = require('../../../utils/aes');
  7 +const WheelSurfModel = require('./wheel-surf');
  8 +const PARENT_TABLE_NAME = 'dailysignin';
  9 +const TABLE_NAME = PARENT_TABLE_NAME + ':activity';
4 10
5 -class ActDailyCheckIn extends global.yoho.BaseModel { 11 +class DailyCheckInModel extends global.yoho.BaseModel {
6 constructor(ctx) { 12 constructor(ctx) {
7 super(ctx); 13 super(ctx);
  14 + this.redis = global.yoho.redis;
  15 + this.client = this.redis.client;
  16 + this.wheelSurfModel = new WheelSurfModel(ctx);
8 } 17 }
9 18
  19 + /**
  20 + * 获取活动信息
  21 + * @param actId
  22 + * @returns {Promise.<void>}
  23 + */
  24 + async getActInfo(actId) {
  25 + let idx = 0;
10 26
  27 + try {
  28 + idx = parseInt(aes.decryptUid(actId), 10) - 1;
  29 + } catch (err) {
  30 + return {
  31 + code: 203,
  32 + message: '无活动信息'
  33 + };
  34 + }
  35 +
  36 + if (idx) {
  37 + return this.client.lrangeAsync(TABLE_NAME, idx, idx).then(act => {
  38 + return JSON.parse(act[0]);
  39 + });
  40 + } else {
  41 + return {
  42 + code: 203,
  43 + message: '无活动信息'
  44 + };
  45 + }
  46 + }
  47 +
  48 + /**
  49 + * 每日签到
  50 + * @param data
  51 + * @returns {Promise.<void>}
  52 + */
  53 + async checkInNormal(data) {
  54 + if (data.uid && data.actId) {
  55 + let actInfo = await this.getActInfo(data.actId);
  56 +
  57 + if (actInfo.code && actInfo.code === 203) { // 无活动信息,返回
  58 + return actInfo;
  59 + }
  60 + let now = new Date(); // 今天的日期用于判断
  61 +
  62 + if (now.getTime() < parseInt(actInfo.startTime, 10) * 1000) {
  63 + return {
  64 + code: 203,
  65 + message: '活动未开始'
  66 + };
  67 + }
  68 +
  69 + if (now.getTime() > parseInt(actInfo.endTime, 10) * 1000) {
  70 + return {
  71 + code: 203,
  72 + message: '活动已结束'
  73 + };
  74 + }
  75 +
  76 + let normalWheelId = actInfo.normalWheelId;
  77 + let checkInKey = `${PARENT_TABLE_NAME}:${actInfo.id}:user:${data.uid}:checkin`;
  78 +
  79 + let params = {
  80 + act_id: normalWheelId,
  81 + uid: data.uid,
  82 + sessionKey: data.sessionKey,
  83 + appVersion: data.appVersion,
  84 + appSessionType: data.appSessionType
  85 + };
  86 + let getUserCheckInData = await this.client.zrevrangeAsync(checkInKey, 0, 0); // 查询用户最近一次签到信息
  87 + let isChecked = false;
  88 +
  89 + if (getUserCheckInData && getUserCheckInData.length > 0) { // 如果有签到信息,判断是否是今日签到的
  90 + let checkInData = JSON.parse(getUserCheckInData[0]);
  91 + let date = new Date(checkInData.createTime);
  92 +
  93 + if ((new Date(date.toLocaleDateString())).getTime() >= (new Date(now.toLocaleDateString())).getTime()) {
  94 + isChecked = true;
  95 + }
  96 + }
  97 +
  98 + if (!isChecked) { // 没有签到的情况下,签到
  99 + return this.wheelSurfModel.goPrize(params).then(prize => {
  100 + // console.log(prize);
  101 + if (prize.name && prize.type) { // 从大转盘接口返回的奖品信息
  102 +
  103 + let score = (new Date()).getTime();
  104 + let checkInData = {
  105 + actId: data.actId,
  106 + wheelId: normalWheelId,
  107 + prizeId: prize.id,
  108 + prizeImg: prize.img,
  109 + prizeDesc: prize.desc,
  110 + prizeType: prize.type,
  111 + createTime: score
  112 + };
  113 +
  114 + // console.log('checkInData=', checkInData);
  115 +
  116 + return this.client.zaddAsync(checkInKey, score, JSON.stringify(checkInData)).then(() => {
  117 + return Object.assign({}, {code: 200}, checkInData);
  118 + });
  119 + } else {
  120 + return {
  121 + code: 205,
  122 + message: '未中奖',
  123 + data: prize
  124 + };
  125 + }
  126 + });
  127 + } else {
  128 + return {
  129 + code: 201,
  130 + message: '今天已经签到过咯~'
  131 + };
  132 + }
  133 + }
  134 + }
  135 +
  136 + /**
  137 + * 对于实物中奖的用户,保存其中奖信息
  138 + * @param data
  139 + * @returns {Promise.<void>}
  140 + */
  141 + async saveUserInfo(data) {
  142 + if (data.uid && data.actId) {
  143 + let actId;
  144 +
  145 + try {
  146 + actId = parseInt(aes.decryptUid(data.actId), 10);
  147 + } catch (err) {
  148 + return {
  149 + code: 203,
  150 + message: '无活动信息'
  151 + };
  152 + }
  153 + let userPhoneKey = `${PARENT_TABLE_NAME}:${actId}:user:${data.uid}:info`;
  154 + let allPrizeKey = `${PARENT_TABLE_NAME}:${actId}:prizelist`;
  155 + let userCumulativeData = await this.getUserCumulativeData({uid: data.uid, actId: data.actId});
  156 +
  157 +
  158 + if (userCumulativeData.cumPrize.length > 0) {
  159 + let userInfo = await this.getUserInfo(data);
  160 +
  161 + if (!userInfo.hasPhoneNum) {
  162 + let hasRealPrize = false; // 是否存在实物奖品
  163 + let realPrizeArr = []; // 临时存储中到的实物奖品
  164 +
  165 + for (let i = 0; i < userCumulativeData.cumPrize.length; i++) {
  166 +
  167 + let prize = userCumulativeData.cumPrize[i];
  168 +
  169 + if (prize.prizeType === 4) {
  170 + hasRealPrize = true;
  171 + realPrizeArr.push(prize);
  172 + }
  173 + }
  174 + // console.log('real:', realPrizeArr)
  175 +
  176 + if (hasRealPrize) { // 有实物奖品的情况下
  177 + let score = (new Date()).getTime();
  178 + let phoneData = {
  179 + phone: data.phone.toString(),
  180 + nickname: data.nickname,
  181 + uid: data.uid
  182 + };
  183 +
  184 + return this.client.zaddAsync(userPhoneKey, score, JSON.stringify(phoneData)).then(async() => { // 往用户信息表添加信息
  185 + let finalResult = [];
  186 +
  187 + for (let j = 0; j < realPrizeArr.length; j++) {
  188 + let prize = realPrizeArr[j];
  189 + let prizeData = {
  190 + id: parseInt(phoneData.uid, 10).toString(16), // 隐藏一下真实uid
  191 + nickname: phoneData.nickname,
  192 + daysCount: prize.daysCount,
  193 + phone: phoneData.phone.substring(0, 3) + '****' + phoneData.phone.substring(7, 11),
  194 + prizeName: prize.prizeDesc.replace('恭喜您获得', '')
  195 + };
  196 +
  197 + let result = await this.client.zaddAsync(allPrizeKey, score, JSON.stringify(prizeData)); // 往中奖公布列表添加数据
  198 +
  199 + finalResult.push(result);
  200 + }
  201 +
  202 + return {
  203 + code: 200,
  204 + data: finalResult,
  205 + message: '保存成功'
  206 + };
  207 + });
  208 +
  209 + } else {
  210 + return {
  211 + code: 204,
  212 + message: '无实物奖品中奖信息'
  213 + };
  214 + }
  215 + } else {
  216 + return {
  217 + code: 203,
  218 + message: '您已填写过手机号,请勿重复提交'
  219 + };
  220 + }
  221 + } else {
  222 + return {
  223 + code: 204,
  224 + message: '无中奖信息'
  225 + };
  226 + }
  227 + }
  228 + }
  229 +
  230 + /**
  231 + * 获取用户是否填写过手机号信息
  232 + * @param data
  233 + * @returns {Promise.<void>}
  234 + */
  235 + async getUserInfo(data) {
  236 + if (data.uid && data.actId) {
  237 + let actId;
  238 +
  239 + try {
  240 + actId = parseInt(aes.decryptUid(data.actId), 10);
  241 + } catch (err) {
  242 + return {
  243 + code: 203,
  244 + message: '无活动信息'
  245 + };
  246 + }
  247 + let userPhoneKey = `${PARENT_TABLE_NAME}:${actId}:user:${data.uid}:info`;
  248 + let userInfo = await this.client.zrangeAsync(userPhoneKey, 0, 0);
  249 +
  250 + if (userInfo && userInfo.length > 0) {
  251 + return {
  252 + code: 200,
  253 + hasPhoneNum: 1
  254 + };
  255 + } else {
  256 + return {
  257 + code: 203,
  258 + hasPhoneNum: 0
  259 + };
  260 + }
  261 + }
  262 + }
  263 +
  264 + /**
  265 + * 获取此次活动所有获得实物奖品的人员列表
  266 + * @param data
  267 + * @returns {Promise.<void>}
  268 + */
  269 + async getWinnerList(data) {
  270 + if (data.actId) {
  271 + let actId;
  272 +
  273 + try {
  274 + actId = parseInt(aes.decryptUid(data.actId), 10);
  275 + } catch (err) {
  276 + return {
  277 + code: 203,
  278 + message: '无活动信息'
  279 + };
  280 + }
  281 +
  282 + let prizeListKey = `${PARENT_TABLE_NAME}:${actId}:prizelist`;
  283 +
  284 + return this.client.zrevrangeAsync(prizeListKey, 0, -1).then(result => {
  285 + return result.map(ret => {
  286 + return JSON.parse(ret);
  287 + });
  288 + });
  289 + }
  290 + }
  291 +
  292 + /**
  293 + * 累计签到
  294 + * @param data
  295 + * @returns {Promise.<void>}
  296 + */
  297 + async checkInCumulative(data) {
  298 + if (data.uid && data.actId) {
  299 + let actInfo = await this.getActInfo(data.actId);
  300 + let userCumulativeData = await this.getUserCumulativeData({uid: data.uid, actId: data.actId});
  301 +
  302 + if (actInfo.code && actInfo.code === 203) { // 无活动信息,返回
  303 + return actInfo;
  304 + }
  305 +
  306 +
  307 + if (actInfo.prizeDayArr && actInfo.prizeDayArr.length > 0) {
  308 + let totalDays = userCumulativeData.cumDays.length; // 累计已签到天数
  309 + let prizeKey = `${PARENT_TABLE_NAME}:${actInfo.id}:user:${data.uid}:prize`;
  310 +
  311 + if (totalDays > 0) {
  312 + for (let i = 0; i < actInfo.prizeDayArr.length; i++) {
  313 + let day = actInfo.prizeDayArr[i]; // 配置的累计天数信息
  314 + let daysCount = parseInt(day.count, 10); // 当前循环中累计天数的数量
  315 + let wheelId = day.wheelId; // 累计天数信息中配置的大转盘id
  316 + let params = {
  317 + act_id: wheelId,
  318 + uid: data.uid,
  319 + sessionKey: data.sessionKey,
  320 + appVersion: data.appVersion,
  321 + appSessionType: data.appSessionType
  322 + };
  323 +
  324 +
  325 + // console.log('totalDays:', totalDays, '&daysCount:', daysCount, '&day:', day);
  326 + // console.log('userCumulativeData:', userCumulativeData.cumPrize);
  327 +
  328 + if (totalDays >= daysCount) { // 比较累计签到的天数是否大于活动设定的累计签到天数
  329 + if (userCumulativeData.cumPrize.length > 0) { // 如果获得过签到奖品,则判断是否是已领取过对应的累计奖励
  330 + let isGet = false;
  331 +
  332 + for (let j = 0; j < userCumulativeData.cumPrize.length; j++) {
  333 + let prizeGet = userCumulativeData.cumPrize[j];
  334 +
  335 + if (parseInt(prizeGet.daysCount, 10) === daysCount) { // 如果获得的累计奖品的天数和当前循环的累计天数相同
  336 + isGet = true;
  337 + }
  338 + }
  339 +
  340 + if (!isGet) {
  341 + return this.wheelSurfModel.goPrize(params).then(prize => { // 调用对应的大转盘获取奖品返回
  342 + // console.log('prize_' + totalDays + '_' + daysCount, prize);
  343 + if (prize.name && prize.type) {
  344 + let score = (new Date()).getTime();
  345 + let checkInData = {
  346 + actId: data.actId,
  347 + wheelId: wheelId,
  348 + prizeId: prize.id,
  349 + prizeImg: prize.img,
  350 + prizeDesc: prize.desc,
  351 + prizeType: prize.type,
  352 + daysCount: daysCount,
  353 + createTime: score
  354 + };
  355 +
  356 + return this.client.zaddAsync(prizeKey, score, JSON.stringify(checkInData)).then(() => {
  357 + return Object.assign({}, {code: 200}, checkInData);
  358 + });
  359 + }
  360 + });
  361 + }
  362 + } else { // 如果没有获得过累计签到的奖品
  363 + return this.wheelSurfModel.goPrize(params).then(prize => { // 调用对应的大转盘获取奖品返回
  364 + // console.log('prize:', prize);
  365 + if (prize.name && prize.type) {
  366 + let score = (new Date()).getTime();
  367 + let checkInData = {
  368 + actId: data.actId,
  369 + wheelId: wheelId,
  370 + prizeId: prize.id,
  371 + prizeImg: prize.img,
  372 + prizeDesc: prize.desc,
  373 + prizeType: prize.type,
  374 + daysCount: daysCount,
  375 + createTime: score
  376 + };
  377 +
  378 + return this.client.zaddAsync(prizeKey, score, JSON.stringify(checkInData)).then(() => {
  379 + return Object.assign({}, {code: 200}, checkInData);
  380 + });
  381 + }
  382 + });
  383 + }
  384 + } else {
  385 + return {
  386 + code: 202,
  387 + message: '未满足累计天数要求'
  388 + };
  389 + }
  390 + }
  391 +
  392 + // 循环内全部未返回,则默认返回
  393 + return {
  394 + code: 202,
  395 + message: '未满足累计天数要求'
  396 + };
  397 + } else { // 累计签到天数为0返回
  398 + return {
  399 + code: 202,
  400 + message: '未满足累计天数要求'
  401 + };
  402 + }
  403 +
  404 + } else {
  405 + return {
  406 + code: 201,
  407 + message: '无累计抽奖可用'
  408 + };
  409 + }
  410 + }
  411 + }
  412 +
  413 + /**
  414 + * 获取签到累计天数
  415 + * @param data
  416 + * @returns {Promise.<{cumDays: *, cumGeted: (*|Array)}>}
  417 + */
  418 + async getUserCumulativeData(data) {
  419 + if (data.uid && data.actId) {
  420 + let actId = 0;
  421 +
  422 + try {
  423 + actId = parseInt(aes.decryptUid(data.actId), 10);
  424 + } catch (err) {
  425 + return {
  426 + code: 203,
  427 + message: '无活动信息'
  428 + };
  429 + }
  430 +
  431 + if (actId) {
  432 + let checkInKey = `${PARENT_TABLE_NAME}:${actId}:user:${data.uid}:checkin`;
  433 + let cumPrizeKey = `${PARENT_TABLE_NAME}:${actId}:user:${data.uid}:prize`;
  434 +
  435 + let cumDays = await this.client.zrangeAsync(checkInKey, 0, -1); // 已签到天数
  436 + let cumPrizeGeted = await this.client.zrangeAsync(cumPrizeKey, 0, -1); // 已获得的累计签到奖励
  437 + let cumDaysResult = [];
  438 + let cumPrizeResult = [];
  439 +
  440 + cumDays.map(day => {
  441 + cumDaysResult.push(JSON.parse(day));
  442 + });
  443 +
  444 + cumPrizeGeted.map(prize => {
  445 + cumPrizeResult.push(JSON.parse(prize));
  446 + });
  447 +
  448 + return {
  449 + code: 200,
  450 + cumDays: cumDaysResult,
  451 + cumPrize: cumPrizeResult
  452 + };
  453 + }
  454 +
  455 + }
  456 +
  457 + }
11 458
12 } 459 }
13 460
14 -module.exports = ActDailyCheckIn; 461 +module.exports = DailyCheckInModel;
@@ -186,6 +186,8 @@ class ActWheelSurfModelRedis extends global.yoho.BaseModel { @@ -186,6 +186,8 @@ class ActWheelSurfModelRedis extends global.yoho.BaseModel {
186 return conf; 186 return conf;
187 }); 187 });
188 188
  189 +
  190 +
189 let residueCount; 191 let residueCount;
190 let uid = { 192 let uid = {
191 toString: () => { 193 toString: () => {
@@ -20,6 +20,7 @@ const coupon511 = require('./controllers/coupon511'); @@ -20,6 +20,7 @@ const coupon511 = require('./controllers/coupon511');
20 const common = require('./controllers/common'); 20 const common = require('./controllers/common');
21 const mutilpartMiddleware = multipart(); 21 const mutilpartMiddleware = multipart();
22 const yohoActivitys = require('./controllers/yoho-activitys'); 22 const yohoActivitys = require('./controllers/yoho-activitys');
  23 +const dailyCheckIn = require('./controllers/daily-check-in');
23 24
24 router.get('/gettoken', qiniu.getToken); 25 router.get('/gettoken', qiniu.getToken);
25 router.get('/share/getSignPackage', wechat.getSignPackage); 26 router.get('/share/getSignPackage', wechat.getSignPackage);
@@ -96,4 +97,12 @@ router.get('/activity/yohoActivitys/getArticleList', yohoActivitys.getArticleLis @@ -96,4 +97,12 @@ router.get('/activity/yohoActivitys/getArticleList', yohoActivitys.getArticleLis
96 router.post('/activity/yohoActivitys/addLike', yohoActivitys.addLike);// 给对应文章点赞 97 router.post('/activity/yohoActivitys/addLike', yohoActivitys.addLike);// 给对应文章点赞
97 // router.get('/activity/yohoActivitys/removeRangeByRand', yohoActivitys.removeRangeByRand); // 删除所有文章 98 // router.get('/activity/yohoActivitys/removeRangeByRand', yohoActivitys.removeRangeByRand); // 删除所有文章
98 99
  100 +// 签到活动
  101 +router.post('/activity/checkIn/checkInNormal', dailyCheckIn.checkInNormal);// 每日签到
  102 +router.get('/activity/checkIn/getUserCumulativeData', dailyCheckIn.getUserCumulativeData); // 获取签到信息
  103 +router.post('/activity/checkIn/checkInCumulative', dailyCheckIn.checkInCumulative);// 累计签到
  104 +router.post('/activity/checkIn/saveUserInfo', dailyCheckIn.saveUserInfo); // 保存用户信息
  105 +router.get('/activity/checkIn/getWinnerList', dailyCheckIn.getWinnerList); // 获取实物奖品中奖用户
  106 +router.get('/activity/checkIn/getUserInfo', dailyCheckIn.getUserInfo); // 获取用户信息
  107 +
99 module.exports = router; 108 module.exports = router;
@@ -20,13 +20,13 @@ module.exports = { @@ -20,13 +20,13 @@ module.exports = {
20 20
21 // yohoVerifyUdid: '0f626ede-0e17-460b-a8ea-069ee506e8e9', 21 // yohoVerifyUdid: '0f626ede-0e17-460b-a8ea-069ee506e8e9',
22 domains: { 22 domains: {
23 - // api: 'http://api-test3.dev.yohocorp.com/',  
24 - // service: 'http://api-test3.dev.yohocorp.com/',  
25 - // singleApi: 'http://api-test3.yohops.com:9999/', 23 + api: 'http://api-test3.dev.yohocorp.com/',
  24 + service: 'http://api-test3.dev.yohocorp.com/',
  25 + singleApi: 'http://api-test3.yohops.com:9999/',
26 26
27 - singleApi: 'http://api.yoho.cn/',  
28 - api: 'http://api.yoho.cn/',  
29 - service: 'http://service.yoho.cn/', 27 + // singleApi: 'http://api.yoho.cn/',
  28 + // api: 'http://api.yoho.cn/',
  29 + // service: 'http://service.yoho.cn/',
30 ufo: 'http://2.yohobuy.com', 30 ufo: 'http://2.yohobuy.com',
31 store: 'http://192.168.102.47:8080/portal-gateway/wechat/', 31 store: 'http://192.168.102.47:8080/portal-gateway/wechat/',
32 serviceNotify: 'http://service.yoho.cn/', 32 serviceNotify: 'http://service.yoho.cn/',
@@ -20,17 +20,17 @@ @@ -20,17 +20,17 @@
20 <Input v-model="normalWheelId" placeholder="平时每日领取对应的大转盘id" style="width: 400px;"></Input> 20 <Input v-model="normalWheelId" placeholder="平时每日领取对应的大转盘id" style="width: 400px;"></Input>
21 </FormItem> 21 </FormItem>
22 <FormItem label="第一次累计天数"> 22 <FormItem label="第一次累计天数">
23 - <Input v-model="days1.count" placeholder="第一次累计天数" style="width: 100px;" type="number"></Input> 23 + <Input v-model="days1.count" placeholder="第一次累计天数" style="width: 100px;"></Input>
24 转盘ID 24 转盘ID
25 <Input v-model="days1.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input> 25 <Input v-model="days1.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input>
26 </FormItem> 26 </FormItem>
27 <FormItem label="第二次累计天数"> 27 <FormItem label="第二次累计天数">
28 - <Input v-model="days2.count" placeholder="第二次累计天数" style="width: 100px;" type="number"></Input> 28 + <Input v-model="days2.count" placeholder="第二次累计天数" style="width: 100px;"></Input>
29 转盘ID 29 转盘ID
30 <Input v-model="days2.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input> 30 <Input v-model="days2.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input>
31 </FormItem> 31 </FormItem>
32 <FormItem label="第三次累计天数"> 32 <FormItem label="第三次累计天数">
33 - <Input v-model="days3.count" placeholder="第二次累计天数" style="width: 100px;" type="number"></Input> 33 + <Input v-model="days3.count" placeholder="第二次累计天数" style="width: 100px;"></Input>
34 转盘ID 34 转盘ID
35 <Input v-model="days3.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input> 35 <Input v-model="days3.wheelId" placeholder="对应的大转盘id" style="width: 200px;"></Input>
36 </FormItem> 36 </FormItem>
@@ -68,6 +68,9 @@ @@ -68,6 +68,9 @@
68 } 68 }
69 }; 69 };
70 }, 70 },
  71 + mounted() {
  72 +
  73 + },
71 methods: { 74 methods: {
72 dateTimeChange(range) { 75 dateTimeChange(range) {
73 this.startTime = range[0]; 76 this.startTime = range[0];
@@ -76,15 +79,16 @@ @@ -76,15 +79,16 @@
76 save() { 79 save() {
77 let prizeDayArr = []; 80 let prizeDayArr = [];
78 81
79 - if (this.days1.count && this.days1.wheelId) { // 第一次累计 82 +
  83 + if (parseInt(this.days1.count, 10) && this.days1.wheelId) { // 第一次累计
80 prizeDayArr.push(this.days1); 84 prizeDayArr.push(this.days1);
81 - if (this.days2.count && this.days2.wheelId) { // 第二次累计  
82 - if (this.days2.count <= this.days1.count) { 85 + if (parseInt(this.days2.count, 10) && this.days2.wheelId) { // 第二次累计
  86 + if (parseInt(this.days2.count, 10) <= parseInt(this.days1.count, 10)) {
83 return alert('第二次的天数必须大于第一次的天数'); 87 return alert('第二次的天数必须大于第一次的天数');
84 } else { 88 } else {
85 prizeDayArr.push(this.days2); 89 prizeDayArr.push(this.days2);
86 - if (this.days3.count && this.days3.wheelId) { // 第三次累计  
87 - if (this.days3.count <= this.days2.count) { 90 + if (parseInt(this.days3.count, 10) && this.days3.wheelId) { // 第三次累计
  91 + if (parseInt(this.days3.count, 10) <= parseInt(this.days2.count, 10)) {
88 return alert('第三次的天数必须大于第二次的天数'); 92 return alert('第三次的天数必须大于第二次的天数');
89 } else { 93 } else {
90 prizeDayArr.push(this.days3); 94 prizeDayArr.push(this.days3);
@@ -94,6 +98,19 @@ @@ -94,6 +98,19 @@
94 } 98 }
95 } 99 }
96 100
  101 + if (!this.title) {
  102 + return alert('清填写标题');
  103 + }
  104 +
  105 + if (!this.startTime || !this.endTime) {
  106 + return alert('请选择开始结束时间');
  107 + }
  108 +
  109 + if (!this.normalWheelId) {
  110 + return alert('请填写每日领取的大转盘ID');
  111 + }
  112 +
  113 +
97 $.ajax({ 114 $.ajax({
98 method: 'post', 115 method: 'post',
99 url: '/admin/dailyCheckIn/api/create', 116 url: '/admin/dailyCheckIn/api/create',
@@ -105,10 +122,11 @@ @@ -105,10 +122,11 @@
105 prizeDayArr: JSON.stringify(prizeDayArr) 122 prizeDayArr: JSON.stringify(prizeDayArr)
106 } 123 }
107 }).then(res => { 124 }).then(res => {
108 - console.log(res);  
109 -  
110 -  
111 - // this.$router.push({name: 'list'}); 125 + if (res.code === 200) {
  126 + this.$router.push({name: 'list'});
  127 + } else {
  128 + alert('创建失败');
  129 + }
112 }); 130 });
113 131
114 }, 132 },
@@ -14,60 +14,61 @@ @@ -14,60 +14,61 @@
14 columns1: [ 14 columns1: [
15 { 15 {
16 title: '活动ID', 16 title: '活动ID',
17 - key: 'encryptedId' 17 + key: 'encryptedId',
  18 + align: 'center'
18 }, 19 },
19 { 20 {
20 title: '活动标题', 21 title: '活动标题',
21 - key: 'title' 22 + key: 'title',
  23 + align: 'center'
22 }, 24 },
23 { 25 {
24 title: '开始时间', 26 title: '开始时间',
25 key: 'startTime', 27 key: 'startTime',
  28 + width: 200,
  29 + align: 'center',
26 render: (h, {row}) => { 30 render: (h, {row}) => {
27 - return h('span', {}, moment(row.startTime * 1000).format('YYYY-MM-DD HH:mm:ss ')); 31 + console.log(row);
  32 + return h('span', {}, moment(row.startTime * 1000).format('YYYY-MM-DD'));
28 } 33 }
29 }, 34 },
30 { 35 {
31 title: '结束时间', 36 title: '结束时间',
32 key: 'endTime', 37 key: 'endTime',
  38 + width: 200,
  39 + align: 'center',
33 render: (h, {row}) => { 40 render: (h, {row}) => {
34 - return h('span', {}, moment(row.endTime * 1000).format('YYYY-MM-DD HH:mm:ss ')); 41 + return h('span', {}, moment(row.endTime * 1000).format('YYYY-MM-DD'));
  42 + }
  43 + },
  44 + {
  45 + title: '每日大转盘',
  46 + key: 'normalWheelId',
  47 + align: 'center'
  48 + },
  49 + {
  50 + title: '累计信息',
  51 + key: 'prizeDayArr',
  52 + align: 'center',
  53 + render: (h, {row}) => {
  54 + let elements = [];
  55 +
  56 + for (let i = 0; i < row.prizeDayArr.length; i++) {
  57 + let prize = row.prizeDayArr[i];
  58 +
  59 + elements.push(h('span', {style: {display: 'inline-block', borderBottom: '1px solid lightgray'}}, '满' + prize.count + '天: ' + prize.wheelId));
  60 + }
  61 +
  62 + return h('div', elements);
35 } 63 }
36 }, 64 },
37 { 65 {
38 title: '操作', 66 title: '操作',
  67 + align: 'center',
39 render: (h, {row}) => { 68 render: (h, {row}) => {
40 return h('div', [ 69 return h('div', [
41 h('Button', { 70 h('Button', {
42 props: { 71 props: {
43 - type: 'primary',  
44 - size: 'small'  
45 - },  
46 - style: {  
47 - marginRight: '5px'  
48 - },  
49 - on: {  
50 - click: () => {  
51 - this.conf(row.encryptedId);  
52 - }  
53 - }  
54 - }, '配置'),  
55 - h('Button', {  
56 - props: {  
57 - type: 'success',  
58 - size: 'small'  
59 - },  
60 - style: {  
61 - marginRight: '5px'  
62 - },  
63 - on: {  
64 - click: () => {  
65 - this.prizeSent(row.encryptedId);  
66 - }  
67 - }  
68 - }, '中奖一览'),  
69 - h('Button', {  
70 - props: {  
71 type: 'error', 72 type: 'error',
72 size: 'small' 73 size: 'small'
73 }, 74 },
@@ -102,7 +103,7 @@ @@ -102,7 +103,7 @@
102 onOk: () => { 103 onOk: () => {
103 $.ajax({ 104 $.ajax({
104 method: 'post', 105 method: 'post',
105 - url: '/admin/wheelSurf/api/delete', 106 + url: '/admin/dailyCheckIn/api/delete',
106 data: {id} 107 data: {id}
107 }).then(() => { 108 }).then(() => {
108 this.list(); 109 this.list();
@@ -112,7 +113,7 @@ @@ -112,7 +113,7 @@
112 }, 113 },
113 list() { 114 list() {
114 $.ajax({ 115 $.ajax({
115 - url: '/admin/wheelSurf/api/list', 116 + url: '/admin/dailyCheckIn/api/actList',
116 }).then(res => { 117 }).then(res => {
117 this.data = res.data; 118 this.data = res.data;
118 }); 119 });