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.
 
 
 
 
 
 

76 lines
2.7 KiB

package pay
import (
"strings"
"yunyan/pb"
)
// 订单「来源设备快照」:渠道分成月结算的归属依据。
//
// 取值优先级(与前端约定一致):
// 1. 客户端下单时带的【当前使用设备】(devicemac 优先,其次 license);
// 2. 用户的【最后绑定设备】(userdevice 里最近绑定的一台,等价于 DBUser.Lastbind*,
// 但能一并拿到 license/mac);
// 3. 都没有 → 只用 DBUser.Lastbind* 里的产品/渠道商,license/mac 留空;
// 4. 用户从未绑过设备 → 全空,该订单在结算时归入「无渠道归属」。
//
// 快照在下单那一刻冻结进订单行:用户之后换设备、换绑、渠道商停用,都不影响历史订单的归属。
// orderSource 一次下单解析出的来源设备快照。
type orderSource struct {
License string
Mac string
ProductId uint32
BrandId uint32
ChannelId string
}
// resolveOrderSource 解析订单的来源设备。任何一步查库失败都只是降级,不阻断下单。
func (this *apiComp) resolveOrderSource(uid, devicemac, license string) orderSource {
var src orderSource
dev := this.lookupOrderDevice(uid, devicemac, license)
if dev != nil {
src.License = dev.License
src.Mac = dev.Devicemac
src.ProductId = dev.Productid
src.ChannelId = dev.Channelid
}
// 设备行缺产品/渠道时(老数据),退回用户身上记的最后绑定信息补齐。
if src.ProductId == 0 || src.ChannelId == "" {
if u, err := this.module.model.getUser(uid); err == nil && u != nil {
if src.ProductId == 0 {
src.ProductId = u.Lastbindproductid
}
if src.ChannelId == "" {
src.ChannelId = u.Lastbindchannelid
}
}
}
// 品牌商由产品反查(产品表在平台公共库,是品牌商归属的唯一权威)。
if src.ProductId != 0 {
if p, err := this.module.model.getProduct(src.ProductId); err == nil && p != nil {
src.BrandId = p.Brandid
}
}
return src
}
// lookupOrderDevice 按优先级定位来源设备行:当前使用设备(mac → license) → 最后绑定设备。
func (this *apiComp) lookupOrderDevice(uid, devicemac, license string) *pb.DBUserDivice {
if mac := strings.TrimSpace(devicemac); mac != "" {
if dev, err := this.module.model.getUserDeviceByMac(uid, mac); err == nil && dev != nil && dev.Id != 0 {
return dev
}
}
if lic := strings.TrimSpace(license); lic != "" {
if dev, err := this.module.model.getUserDeviceByLicense(uid, lic); err == nil && dev != nil && dev.Id != 0 {
return dev
}
}
// 客户端没带、或带的设备不属于该用户 → 回退最后绑定设备。
if dev, err := this.module.model.getUserLastDevice(uid); err == nil && dev != nil && dev.Id != 0 {
return dev
}
return nil
}