wheel-surf.js 10.9 KB
/* eslint-disable array-callback-return */
const {ActWheelSurfConf, ActWheelSurfPrize, ActWheelSurfUser, Activity} = require('../../../db');

// const md5 = require('yoho-md5');
const _ = require('lodash');
const logger = global.yoho.logger;
const mysqlCli = global.yoho.utils.mysqlCli;

const _sender = global.yoho.sender;

/**
 * 上报
 * @param type 0: packrain 1: turntable
 * @param tags 一些基础参数
 * @param fields 红包的金额
 * @param isFail 接口是否失败
 */
const sendMessage = (type, tags, fields, isFail) => {
  if (!_sender) {
    return;
  }
  const hostname = (require('os').hostname());
  let typeName = ['turntable-red', 'turntable-coupon'][type];
  let initTags = {
    hostname,
    pid: process.pid || 0,
    app: global.yoho.config.appName,
    type: typeName
  };

  tags = Object.assign({}, initTags, tags);
  isFail = isFail ? 1 : 0;
  fields = Object.assign({}, fields);

  let mesurement = ['monitor_success_report', 'monitor_error_report'][isFail];

  try {
    _sender.addMessage({
      measurement: mesurement,
      tags,
      fields
    });
  } catch (e) {
    console.error(e);
  }
};

class ActWheelSurfModel extends global.yoho.BaseModel {
  constructor(ctx) {
    super(ctx);
    this.cache = global.yoho.cache;
  }

  async getNowConf(obj) {
    try {
      // let data = await this.cache.get(md5('act' + obj.act_id));
      let data = {};

      // 获取当前活动基础信息,从redis里面取prize和conf,如果没有则查表再放入redis
      // if (data) {
      //   data = JSON.parse(data);
      // } else {
      // 从redis取,如果没有则去数据查询,然后再到放到redis
      // 获取活动基础

      data.conf = await ActWheelSurfConf.findOne({where: {act_id: obj.act_id}});

      // 获取当前活动奖品
      let prize = await ActWheelSurfPrize.findAll({where: {act_id: obj.act_id}});

      data.prize = prize.length;
      data.emptyPrize = {};

      for (let value of prize) {
        if (value.type === 1) {
          data.emptyPrize = value;
          break;
        }
      }

      //   this.cache.set(md5('act' + obj.act_id), data);
      // }
      let act = await Activity.findOne({where: {id: obj.act_id}});
      let nowDate = new Date();

      nowDate = parseInt(nowDate.getTime() / 1000);
      if (act.startTime > nowDate) {
        data.startType = false;
        data.errorType = 0;
        data.errorMsg = '活动未开始';
      }
      if (act.endTime < nowDate) {
        data.startType = false;
        data.errorType = 1;
        data.errorMsg = '活动已过期';
      }

      // 获取当去用户剩余次数
      let residueCount;

      // 判断用户是否登录 如果没登录就取当前活动最大次数
      if (obj.uid) {
        // 每日最大次数
        if (!data.conf.times_type) {
          // 获取当天0点和23:59:59
          let endTime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1);
          let startTime = new Date(new Date(new Date().toLocaleDateString()).getTime());

          obj.create_time = {gt: startTime, lte: endTime};
          residueCount = data.conf.day_limit_times - await ActWheelSurfUser.count({
              where: obj
            });
        } else {
          // 活动最大次数
          residueCount = data.conf.act_total_times - await ActWheelSurfUser.count({where: obj});
        }
      } else {
        residueCount = data.conf.times_type ? data.conf.act_total_times : data.conf.day_limit_times;
      }
      data.residueCount = residueCount;
      return Promise.resolve(data);
    } catch (e) {
      logger.error(e);
      return Promise.reject({code: 305, result: false, msg: '服务错误,请稍等'});
    }
  }

  // noinspection JSAnnotator
  async goPrize(obj) {
    try {
      // 校验有效活动时间
      let act = await Activity.findOne({where: {id: obj.act_id}});
      let nowDate = new Date();

      nowDate = parseInt(nowDate.getTime() / 1000);
      if (act.startTime > nowDate) {
        return Promise.reject({code: 301, result: false, msg: '活动未开始'});
      }
      if (act.endTime < nowDate) {
        return Promise.reject({code: 302, result: false, msg: '活动已过期'});
      }

      // 获取活动信息
      let conf = await ActWheelSurfConf.findOne({where: {act_id: obj.act_id}});
      let residueCount;
      let uid = {
        toString: () => {
          return _.parseInt(obj.uid);
        },
        sessionKey: obj.sessionKey,
        appVersion: obj.appVersion,
        sessionType: obj.sessionType
      };

      delete obj.sessionKey;
      delete obj.appVersion;
      delete obj.sessionType;

      // 计算用户剩余次数校验
      if (!conf.times_type) {
        // 获取当天0点和23:59:59
        let endTime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1);
        let startTime = new Date(new Date(new Date().toLocaleDateString()).getTime());

        obj.create_time = {gt: startTime, lte: endTime};
        residueCount = conf.day_limit_times - await ActWheelSurfUser.count({
            where: obj
          });
      } else {
        // 活动最大次数
        residueCount = conf.act_total_times - await ActWheelSurfUser.count({where: obj});
      }

      if (residueCount > 0) {
        // 获取抽取到奖品
        // 获取奖品信息
        let prize = await ActWheelSurfPrize.findAll({where: {act_id: obj.act_id}});

        // 获取每个奖品获取它们的中奖范围
        let arr = {}, oldValue;

        prize.map(function (value, index) {
          if (value.chance) {
            if (typeof(oldValue) === 'undefined') {
              arr[index] = {maxValue: value.chance, leastValue: 0};
            } else {
              let maxValue = value.chance + oldValue;
              let leastValue = oldValue;

              arr[index] = {maxValue, leastValue};
            }
            oldValue = arr[index].maxValue;
          }
        });

        // 比较概率获取中奖奖品
        // 随机生成0-100的随机数
        let random = Math.random() * 100;

        // 判定随机数在奖品池子取件 选定中奖奖品
        let getPrize, sendResult = {}, result;

        for (let i in arr) {
          if (arr[i].maxValue >= random && arr[i].leastValue < random) {
            getPrize = prize[i];
            break;
          }
        }
        if (getPrize.type !== 1) {
          // 校验剩余库存
          if (getPrize.total_left > 0) {
            // 减库存
            await getPrize.decrement('total_left');
          } else {
            // 查询有没有等于type1(谢谢惠顾)的商品 如果没有 返回概率最商品
            getPrize = null;
            for (let item of prize) {
              if (item.type === 1) {
                getPrize = item;
                break;
              }
            }
          }
        }
        getPrize = getPrize.dataValues;
        if (getPrize.type === 1) {
          sendResult.code = 200;
          getPrize.desc = '对不起,您没有中奖';
        } else if (getPrize.type === 2) {

          try {
            // 调用java接口
            sendResult = await this.get({
              data: {
                method: 'app.redpac.addRedpac',
                actSource: 1001,
                uid: uid,
                redpacToken: getPrize.value
              }
            });

            if (sendResult && sendResult.data) {
              sendMessage(0, {}, {succeedTimes: sendResult.data.amount || 0}, 0);

              if (sendResult && sendResult.code === 200) {
                if (sendResult.data.isRepReceive === 'N') {
                  sendResult.code = 201; // 不能重复领取
                } else {
                  getPrize.desc = '恭喜您获得' + sendResult.data.amount + '元红包';
                }
              }
            } else {
              sendMessage(0, {}, {
                message: sendResult.message || 'no result',
                stack: Object.assign({}, {code: sendResult.code})
              }, 1);
            }

          } catch (e) {
            sendMessage(0, {}, {message: e.message || 'interface error', stack: e}, 1);
          }
        } else if (getPrize.type === 3) {
          try {
            sendResult = await this.get({
              method: 'app.coupons.couponsSend',
              uid: uid,
              coupon_send_token: getPrize.value
            });

            if (sendResult && sendResult.data) {
              sendMessage(1, {}, {succeedTimes: sendResult.data.amount || 0}, 0);

              if (sendResult && sendResult.code === 200) {
                getPrize.desc = '恭喜您获得' + getPrize.name + '优惠券';
              }
            } else {
              sendMessage(1, {}, {
                message: sendResult.message || 'no result',
                stack: Object.assign({}, {code: sendResult.code})
              }, 1);
            }
          } catch (e) {
            sendMessage(1, {}, {message: e.message || 'interface error', stack: e}, 1);
          }
        } else if (getPrize.type === 4) {
          sendResult.code = 200;
          getPrize.desc = '恭喜您获得' + getPrize.name;
        }

        // 插入数据库
        if (sendResult.code !== 200) {
          getPrize = null;
          for (let item of prize) {
            if (item.dataValues.type === 1) {
              getPrize = item.dataValues;
              break;
            }
          }
          getPrize.desc = '对不起,您没有中奖';
        }
        result = await ActWheelSurfUser.create({act_id: obj.act_id, uid: obj.uid, prize_id: getPrize.id});
        if (result) {
          delete getPrize.chance;
          delete getPrize.create_time;
          delete getPrize.total;
          delete getPrize.total_left;
          delete getPrize.value;
          return Promise.resolve(getPrize);
        } else {
          return Promise.reject({code: 305, result: false, msg: '服务错误,请稍等'});
        }
      } else {
        return Promise.reject({code: 304, result: false, msg: '用户使用次数不足'});
      }
    } catch (e) {
      logger.error(e);
      return Promise.reject({code: 305, result: false, msg: '服务错误,请稍等'});
    }
  }

  async getUserPrize(obj) {
    try {
      return await mysqlCli.query(
        `select u.id, u.act_id act_id, u.prize_id prize_id, u.create_time createTime, p.name name,p.type type ,p.value value,p.img img
            from act_wheel_surf_user u , act_wheel_surf_prize p where u.prize_id = p.id and u.act_id =:act_id and u.uid = :uid and type != :type
            order by u.create_time desc`, {act_id: obj.act_id, uid: obj.uid, type: 1});

      // return await ActWheelSurfUser.findAll({include: [{
      //   model: ActWheelSurfPrize,
      //   as: 'ActWheelSurfPrize',
      // }],
      //   where: obj
      // });
    } catch (e) {
      logger.error(e);
      return Promise.reject({code: 305, result: false, msg: '服务错误,请稍等'});
    }
  }
}

module.exports = ActWheelSurfModel;