You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.8 KiB
261 lines
7.8 KiB
package user
|
|
|
|
import (
|
|
"yunyan/comm"
|
|
"yunyan/lego/sys/log"
|
|
"yunyan/pb"
|
|
"yunyan/utils/license"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// @Summary 绑定耳机设备
|
|
// @Description 绑定耳机设备
|
|
// @Tags User
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Param user body pb.UserBindDeviceReq true "发送绑定请求"
|
|
// @Success 200 {object} comm.HttpResult{data=pb.UserBindDeviceResp} "成功返回"
|
|
// @Router /api/home/user_binddevice [post]
|
|
func (this *apiComp) BindDevice(session comm.IUserSession, req *pb.UserBindDeviceReq) (resp *pb.UserBindDeviceResp, errdata *pb.ErrorData) {
|
|
var (
|
|
user *pb.DBUser
|
|
product *pb.DBProduct
|
|
divices []*pb.DBUserDivice
|
|
model *pb.DBAuthCode
|
|
codestate int32
|
|
divice *pb.DBUserDivice
|
|
pid uint16
|
|
Isgiveaway bool
|
|
err error
|
|
)
|
|
if user, err = this.module.model.findforid(session.GetUserId()); err != nil { //未找到授权码
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_UserSessionNobeing,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
if product, err = this.module.cache.GetProduct(req.Pid); err != nil { //未找到授权码
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
|
|
if divices, err = this.module.model.getDevices(session.GetUserId()); err != nil { //未找到授权码
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
for _, v := range divices {
|
|
if v.Devicename == req.Devicename && v.Devicemac == req.Devicemac && v.License == req.Code {
|
|
// errdata = &pb.ErrorData{
|
|
// Code: pb.ErrorCode_DeviceBinded,
|
|
// Message: "设备已绑定",
|
|
// }
|
|
divice = v
|
|
resp = &pb.UserBindDeviceResp{
|
|
Device: divice,
|
|
}
|
|
return
|
|
}
|
|
}
|
|
if product.Devicetype == pb.DeviceType_Classic_bluetooth_Headset {
|
|
if model, err = this.module.model.getFactoryDeviceformac(product.Id, req.Devicemac); err != nil { //设备已被注册
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
} else {
|
|
pid, err = license.ProductID(req.Code)
|
|
if err != nil { //老得一批License 由于数据和新版对因不上 会产生错误
|
|
// errdata = &pb.ErrorData{
|
|
// Code: pb.ErrorCode_AuthorizeIllegal,
|
|
// Message: err.Error(),
|
|
// }
|
|
err = nil
|
|
pid = uint16(45058)
|
|
// return
|
|
}
|
|
if model, err = this.module.model.getFactoryDevice(uint32(pid), req.Code); err != nil { //设备已被注册
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
if model.Disabled != 0 { //设备码已被后台禁用 直接拒绝绑定
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
Message: "设备码已被禁用",
|
|
}
|
|
return
|
|
}
|
|
codestate = model.Status
|
|
if model.Status != 0 && model.Uid != session.GetUserId() { //授权码已被使用 自动解绑
|
|
if divices, err = this.module.model.getDevices(model.Uid); err == nil {
|
|
for _, v := range divices {
|
|
if v.License == model.Code {
|
|
this.module.model.delDevice(v.Id) // 删除设备
|
|
}
|
|
}
|
|
}
|
|
// errdata = &pb.ErrorData{
|
|
// Code: pb.ErrorCode_AuthorizeNoCanUse,
|
|
// Message: "授权码已被使用",
|
|
// }
|
|
// return
|
|
}
|
|
// 移动渠道产品生成 CMEI: TUI(8位) + batch(2位) + serial(5位) = 15位
|
|
var cmei string
|
|
if product.Channel == "mobile" {
|
|
var tui string
|
|
if product.Channelextra != "" {
|
|
extra := struct {
|
|
Tui string `json:"tui"`
|
|
}{}
|
|
if jerr := json.Unmarshal([]byte(product.Channelextra), &extra); jerr == nil {
|
|
tui = extra.Tui
|
|
}
|
|
}
|
|
macStr := strings.ReplaceAll(req.Devicemac, ":", "")
|
|
if len(tui) == 8 && len(macStr) == 12 {
|
|
batch, _ := strconv.ParseUint(macStr[4:6], 16, 8)
|
|
serial, _ := strconv.ParseUint(macStr[8:12], 16, 16)
|
|
cmei = fmt.Sprintf("%s%02d%05d", tui, batch%100, serial%100000)
|
|
}
|
|
}
|
|
divice = &pb.DBUserDivice{
|
|
Uid: session.GetUserId(),
|
|
Productid: product.Id,
|
|
Devicetype: product.Devicetype,
|
|
Devicename: req.Devicename,
|
|
Devicemac: req.Devicemac,
|
|
License: req.Code,
|
|
Cmei: cmei,
|
|
Version: req.Version,
|
|
}
|
|
model.Status = 1 //已绑定
|
|
model.Uid = session.GetUserId()
|
|
model.Devicemac = req.Devicemac
|
|
// 首次激活(此前 status==0)记录激活时间:供按统计日聚合设备激活/绑定数。
|
|
// 历史设备漏记 usedtime 是失误,从此补上;仅在 0→1 首激时写,换绑/接管不覆盖原始激活日。
|
|
if codestate == 0 {
|
|
model.Usedtime = time.Now().Unix()
|
|
}
|
|
if err = this.module.model.saveFactoryDevice(model.Productid, model); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
if err = this.module.model.addDevice(divice); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
// 记录最后绑定的产品ID:后续充值/消耗埋点按此产品归属统计
|
|
user.Lastbindproductid = product.Id
|
|
userSaved := false
|
|
// 设备激活 + 绑定埋点
|
|
if this.module.analyze != nil {
|
|
this.module.analyze.Report(&comm.StatEvent{Type: comm.StatEventDeviceActive, Uid: session.GetUserId(), ProductId: uint32(product.Id)})
|
|
this.module.analyze.Report(&comm.StatEvent{Type: comm.StatEventDeviceBind, Uid: session.GetUserId(), ProductId: uint32(product.Id)})
|
|
}
|
|
this.module.Debug("BindDevice",
|
|
log.Field{Key: "Isgiveaway", Value: user.Isgiveaway},
|
|
log.Field{Key: "Iscanbindagain", Value: product.Iscanbindagain},
|
|
log.Field{Key: "codestate", Value: codestate})
|
|
if !user.Isgiveaway || codestate == 0 {
|
|
Isgiveaway = true
|
|
user.Isgiveaway = true
|
|
var addVipDay, addTrade, addMeet int64
|
|
if product.Bindrewardvpitime > 0 {
|
|
addVipDay = 90
|
|
if user.Vipexptime == 0 || user.Vipexptime < time.Now().Unix() { //重置
|
|
user.Vipexptime = time.Now().Unix() + 90*24*60*60
|
|
} else { //累加
|
|
user.Vipexptime = user.Vipexptime + 90*24*60*60
|
|
}
|
|
}
|
|
// translate/meeting 配置为分钟,积分按秒存储
|
|
if product.Bindrewardtranslate > 0 {
|
|
addTrade = int64(product.Bindrewardtranslate) * 60
|
|
user.Tradeintegral += addTrade
|
|
user.Tradetotalintegral += addTrade
|
|
}
|
|
if product.Bindrewardmeeting > 0 {
|
|
addMeet = int64(product.Bindrewardmeeting) * 60
|
|
user.Meetintegral += addMeet
|
|
user.Meettotalintegral += addMeet
|
|
}
|
|
err = this.module.model.save(user)
|
|
if err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
userSaved = true
|
|
// 记录绑定设备奖励流水
|
|
if addVipDay > 0 || addTrade > 0 || addMeet > 0 {
|
|
_ = this.module.model.addIntegralLog(&pb.DBUserUseLog{
|
|
Uid: session.GetUserId(),
|
|
Logtype: pb.UserLogType_ActivityReward,
|
|
Ts: time.Now().Unix(),
|
|
Addvipday: addVipDay,
|
|
Addtradesecond: addTrade,
|
|
Addmeetsecond: addMeet,
|
|
Extra: req.Code, // 绑定时使用的设备/授权码
|
|
})
|
|
// 绑定赠送资源埋点
|
|
if this.module.analyze != nil {
|
|
this.module.analyze.Report(&comm.StatEvent{
|
|
Type: comm.StatEventResourceGrant,
|
|
ProductId: product.Id,
|
|
Uid: session.GetUserId(),
|
|
GrantVipDay: addVipDay,
|
|
GrantTradeSecond: addTrade,
|
|
GrantMeetSecond: addMeet,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
// 首绑送资源分支未触发时,仍需持久化 lastbindproductid
|
|
if !userSaved {
|
|
if err = this.module.model.save(user); err != nil {
|
|
errdata = &pb.ErrorData{
|
|
Code: pb.ErrorCode_DBError,
|
|
Message: err.Error(),
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
resp = &pb.UserBindDeviceResp{
|
|
Device: divice,
|
|
Isgiveaway: Isgiveaway,
|
|
Viplv: user.Viplv,
|
|
Vipexptime: user.Vipexptime,
|
|
Tradeintegral: user.Tradeintegral,
|
|
Tradetotalintegral: user.Tradetotalintegral,
|
|
Meetintegral: user.Meetintegral,
|
|
Meettotalintegral: user.Meettotalintegral,
|
|
}
|
|
return
|
|
}
|
|
|