user.js 5.49 KB
/**
 * Created by Tommy Huang on 18/03/21.
 */

const config = require('config-lite')({
  config_basedir: __dirname,
  config_dir: 'config'
})
const moment = require('moment')
const axios = require('axios')
const jwt = require('jsonwebtoken')
const Helper = require('./helper')

const User = require('../models').User
const Redis = require('../models/redis')

exports.get = async function(req, res) {
  try {
    const expires = Date.now() + 2592000000
    var userToken
    if (process.env.NODE_ENV !== 'production') {
      let userId = 'oLP-es_k21Xzv-HgFMXTNFLlUMPY'
      let user = await User.findOne({
        where: {id: userId}
      })
      userToken = jwt.sign({
        iss: 'qicaidai',
        userId: user.id, 
        exp: expires
      }, config.jwt.key)
      res.json({
        success: 1,
        token: userToken,
        user: {
          id: user.id,
          username: user.username,
          headimgurl: user.headimgurl,
          phone: user.phone || '',
          needPhoneBind: !user.phoneBinded,
          needIdBind: !user.idBinded
        }
      })
      return
    }
    const code = req.query.code
    let userId, user, token, info, refreshToken
    if (req.session.userId) {
      userId = req.session.userId
    }
    console.log('userId:', userId)
    if (userId) {
      user = await User.findOne({
        where: {id: userId}
      })
    }
    if (user && user.refreshToken) {
      let tokenResult = await Helper.refreshUserWxToken(user.refreshToken)
      if (!tokenResult) throw new Error('刷新微信授权失败')
      userId = user.id
      token = tokenResult.access_token
      refreshToken = user.refreshToken
    } else if (code) {
      let ticketResult = await Helper.getUserWxAccessTokenInfo(code)
      if (!ticketResult) throw new Error('获取微信授权失败')
      userId = ticketResult.openid
      token = ticketResult.access_token
      refreshToken = ticketResult.refresh_token
    } else {
      throw new Error('非法参数')
    }
    info = await Helper.getUserWxInfo(token, userId)
    if (!info) throw new Error('拉取微信信息失败')
    if (!user) {
      user = await User.findOne({
        where: {id: info.openid}
      })
    }
    if (user) {
      await user.update({
        username: info.nickname,
        headimgurl: info.headimgurl,
        refreshToken: refreshToken
      })
    } else {
      user = await User.create({
        id: info.openid,
        username: info.nickname,
        headimgurl: info.headimgurl,
        refreshToken: refreshToken
      })
    }
    console.log(user.id)
    userToken = jwt.sign({
      iss: 'qicaidai',
      userId: user.id, 
      exp: expires
    }, config.jwt.key)
    res.json({
      success: 1,
      token: userToken,
      user: {
        id: user.id,
        username: info.nickname,
        headimgurl: info.headimgurl,
        phone: user.phone || '',
        needPhoneBind: !user.phoneBinded,
        needIdBind: !user.idBinded
      }
    })
  } catch (e) {
    console.log(e)
    res.json({
      success: 0,
      redirect: config.entryURL,
      msg: `获取用户信息失败:${e.message}`
    })
  }
}

exports.getVerificationCode = async function(req, res) {
  try {
    const phone = req.query.phone
    const id = req.user.userId
    const reg =  /^1[0-9]{10}$/
    if (!id)  throw new Error('参数错误')
    if (!reg.test(phone)) throw new Error('手机号码不正确')
    let [user, userByPhone ] = await Promise.all([
      User.findOne({where: {id: id}}),
      User.findOne({where: {phone: phone, phoneBinded: true}})
    ])
    if (userByPhone) throw new Error('该号码已注册')    
    if (!user) throw new Error('用户不存在')
    let date = moment().format('YYYY-MM-DD')
    let timesKey = `sms_${phone}_${date}`
    let frequencyKey = `fqy_${phone}_${date}`
    let [timesData, frequencyData] = await Promise.all([Redis.get(timesKey), Redis.get(frequencyKey)])
    if (frequencyData) throw new Error('获取验证码太频繁')
    // if (timesData >= 6) throw new Error('今日获取验证码数量已达上限')
    let times = parseInt(timesData) || 0
    let [timeResult, frequencyResult] = await Promise.all([
      Redis.sendCommand("set", [timesKey, times + 1, 'ex', 86400]),
      Redis.sendCommand("set", [frequencyKey, 'exist', 'ex', 60])
    ])
    let send = await Helper.sendVerificationCode(phone)
    if (!send.success) throw new Error(send.msg)
    await user.update({
      verificationCode: send.code,
      phone: phone,
      codeTime: moment().format()
    })
    res.json({
      success: 1
    })
  } catch (e) {
    console.log(e)
    res.json({
      success: 0,
      msg: `获取验证码失败:${e.message}`
    })
  }
}

exports.bindPhone = async function(req, res) {
  try {
    const id = req.user.userId
    const phone = req.body.phone
    const code = req.body.verificationCode
    if (!id || !phone || !code)  throw new Error('参数错误')
    let user = await User.findOne({
      where: {id: id}
    })
    if (!user) throw new Error('用户不存在')
    if (user.phone !== phone) throw new Error('修改手机号后请重新获取验证码')
    if (user.verificationCode !== code) throw new Error('验证码不正确')
    let codeTime = moment(user.codeTime).add(5, 'minutes')
    if (moment().isAfter(codeTime)) throw new Error('验证码已过期')
    const update = await user.update({
      phoneBinded: true
    })
    res.json({
      success: 1,
      phone: phone
    })
  } catch (e) {
    console.log(e)
    res.json({
      success: 0,
      msg: `绑定失败:${e.message}`
    })
  }
}