package xiao import ( "errors" "fmt" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/xiao" xiaoReq "github.com/flipped-aurora/gin-vue-admin/server/model/xiao/request" "github.com/flipped-aurora/gin-vue-admin/server/model/xiao/xiaores" "github.com/flipped-aurora/gin-vue-admin/server/plugin/chain/online" "github.com/flipped-aurora/gin-vue-admin/server/plugin/chain/wallet" "github.com/shopspring/decimal" ) type CliWithdrawService struct{} // CreateCliWithdraw 创建提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) CreateCliWithdraw(cliwithdraw *xiao.CliWithdraw) (err error) { err = global.GVA_DB.Create(cliwithdraw).Error return err } // DeleteCliWithdraw 删除提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) DeleteCliWithdraw(ID string) (err error) { err = global.GVA_DB.Delete(&xiao.CliWithdraw{}, "id = ?", ID).Error return err } // DeleteCliWithdrawByIds 批量删除提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) DeleteCliWithdrawByIds(IDs []string) (err error) { err = global.GVA_DB.Delete(&[]xiao.CliWithdraw{}, "id in ?", IDs).Error return err } // UpdateCliWithdraw 更新提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) UpdateCliWithdraw(cliwithdraw xiao.CliWithdraw) (err error) { err = global.GVA_DB.Model(&xiao.CliWithdraw{}).Where("id = ?", cliwithdraw.ID).Updates(&cliwithdraw).Error return err } // GetCliWithdraw 根据ID获取提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) GetCliWithdraw(ID string) (cliwithdraw xiao.CliWithdraw, err error) { err = global.GVA_DB.Where("id = ?", ID).First(&cliwithdraw).Error return } // GetCliWithdrawInfoList 分页获取提币详情记录 // Author [yourname](https://github.com/yourname) func (cliwithdrawService *CliWithdrawService) GetCliWithdrawInfoList(info xiaoReq.CliWithdrawSearch) (list []xiao.CliWithdraw, total int64, err error) { limit := info.PageSize offset := info.PageSize * (info.Page - 1) // 创建db db := global.GVA_DB.Model(&xiao.CliWithdraw{}) var cliwithdraws []xiao.CliWithdraw // 如果有条件搜索 下方会自动创建搜索语句 if info.StartCreatedAt != nil && info.EndCreatedAt != nil { db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt) } if info.Address != "" { db = db.Where("address LIKE ?", "%"+info.Address+"%") } if info.Text != "" { db = db.Where("text LIKE ?", "%"+info.Text+"%") } if info.Status != "" { db = db.Where("status LIKE ?", "%"+info.Status+"%") } if info.Desc != "" { db = db.Where("desc LIKE ?", "%"+info.Desc+"%") } err = db.Count(&total).Error if err != nil { return } var OrderStr string orderMap := make(map[string]bool) orderMap["amount"] = true orderMap["descnum"] = true if orderMap[info.Sort] { OrderStr = info.Sort if info.Order == "descending" { OrderStr = OrderStr + " desc" } db = db.Order(OrderStr) } if limit != 0 { db = db.Limit(limit).Offset(offset) } err = db.Find(&cliwithdraws).Error return cliwithdraws, total, err } func (cliwithdrawService *CliWithdrawService) GetCliWithdrawPublic(pageInfo *xiaoReq.CliWithdrawSearch) (res xiaores.CliWithdrawRes, err error) { // 此方法为获取数据源定义的数据 // 开始事务 tx := global.GVA_DB.Begin() if tx == nil { return res, errors.New("failed to start transaction") } defer func() { if r := recover(); r != nil { tx.Rollback() err = fmt.Errorf("transaction failed: %v", r) } else if err != nil { tx.Rollback() } else { tx.Commit() } }() // 查询提币总表 maininfo, err := xiao.NewCliMainwith(pageInfo.Address).GetCliMainwith(tx) if err != nil { return res, errors.Join(err, errors.New("查询提币总表失败")) } if maininfo != nil { res.CliMainwiths = maininfo } // 查询提币记录 withinfo, err := xiao.NewCliWithdraw(pageInfo.Address).GetCliWithdraw(tx) if err != nil { return res, errors.Join(err, errors.New("查询提币记录失败")) } if withinfo != nil { res.CliWithdraws = withinfo } return res, nil } // CliWithdraw func (cliwithdrawService *CliWithdrawService) CliWithdraw(cliwithdraw *xiao.CliWithdraw) (err error) { if cliwithdraw.Amount.Cmp(decimal.NewFromInt(50)) < 0 { return errors.New("提币金额必须大于50") } //开启事务 tx := global.GVA_DB.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() //计算手续费 var setinfo *xiao.CliSet err = tx.First(&setinfo).Error if err != nil { return errors.Join(err, errors.New("查询设置表失败")) } fee := cliwithdraw.Amount.Mul(*setinfo.Fee).Div(decimal.NewFromInt(100)) if cliwithdraw.Desc == "赎回" { //计算提币金额=投入资金-提币总额 //查询投入资金 var maininfo xiao.CliMainorder if err := tx.Raw(`SELECT * FROM cli_mainorder WHERE address = ? FOR UPDATE`, cliwithdraw.Address).Scan(&maininfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("查询投入资金失败")) } //查询提币总额 var withedinfo xiao.CliMainwith if err := tx.Raw(`SELECT * FROM cli_mainwith WHERE address = ? FOR UPDATE`, cliwithdraw.Address).Scan(&withedinfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("查询提币总额失败")) } nowtiqu := maininfo.Descnum.Mul(decimal.NewFromFloat(0.8)).Sub(*withedinfo.Withed) if nowtiqu.Cmp(decimal.NewFromInt(0)) < 0 { tx.Rollback() return errors.New("可提金额为0") } //更新个人业绩 myselfnum := decimal.NewFromInt(0) maininfo.Descnum = &myselfnum if err := tx.Save(maininfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("更新投入资金失败")) } //更新个人收益 withedinfo.Withable = &myselfnum *withedinfo.Withed = withedinfo.Withed.Add(nowtiqu) if err := tx.Save(withedinfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("更新个人收益失败")) } //更新团队业绩 //查找上级的团队业绩减去赎回业绩 //将订单转为赎回 orders, err := xiao.NewOrder(cliwithdraw.Address).GetCliAllOrder(tx) if err != nil { return err } for _, order := range orders { order.Status = "赎回" if err := tx.Save(&order).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("更新订单状态失败")) } } //提币方法 truenum := nowtiqu.Sub(fee) clienteth, err := online.NewClient() if err != nil { tx.Rollback() return errors.Join(err, errors.New("连接以太坊节点失败")) } //0x79D954564b77C9550327B3e11cFe31472bc1e0d0 store, err := wallet.ImportKeyStore("0xa4416da064bbee02d0f71130cf1414279a32280a") if err != nil { tx.Rollback() return errors.Join(err, errors.New("导入私钥失败")) } transfer, err := online.Bsc20Transfer(clienteth, store, "0x55d398326f99059fF775485246999027B3197955", cliwithdraw.Address, &truenum) if err != nil { tx.Rollback() return errors.Join(err, errors.New("转账失败")) } //创建提币记录 cliwithdraw.Amount = &nowtiqu cliwithdraw.Status = "赎回本金" cliwithdraw.Desc = transfer cliwithdraw.Descnum = &fee err = tx.Create(&cliwithdraw).Error if err != nil { // 回滚事务 return errors.Join(err, errors.New("创建提币记录失败")) } err = tx.Commit().Error if err != nil { return errors.Join(err, errors.New("提交事务失败")) } return nil } // 查询提币总表并加锁 var maininfo xiao.CliMainwith if err := tx.Raw(`SELECT * FROM cli_mainwith WHERE address = ? FOR UPDATE`, cliwithdraw.Address).Scan(&maininfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("查询提币总表失败")) } //查询提币总表 //maininfo, err := xiao.NewCliMainwith(cliwithdraw.Address).GetCliMainwith(tx) //if err != nil { // return errors.Join(err, errors.New("查询提币总表失败")) //} if maininfo.Withable.Cmp(*cliwithdraw.Amount) < 0 { tx.Rollback() return errors.New("提币金额大于可提金额") } *maininfo.Withable = maininfo.Withable.Sub(*cliwithdraw.Amount) *maininfo.Withed = maininfo.Withed.Add(*cliwithdraw.Amount) if err := tx.Save(maininfo).Error; err != nil { tx.Rollback() return errors.Join(err, errors.New("更新提币总表失败")) } truenum := cliwithdraw.Amount.Sub(fee) //提币方法 clienteth, err := online.NewClient() if err != nil { tx.Rollback() return errors.Join(err, errors.New("连接以太坊节点失败")) } //0x79D954564b77C9550327B3e11cFe31472bc1e0d0 store, err := wallet.ImportKeyStore("0xa4416da064bbee02d0f71130cf1414279a32280a") if err != nil { tx.Rollback() return errors.Join(err, errors.New("导入私钥失败")) } transfer, err := online.Bsc20Transfer(clienteth, store, "0x55d398326f99059fF775485246999027B3197955", cliwithdraw.Address, &truenum) if err != nil { tx.Rollback() return errors.Join(err, errors.New("转账失败")) } //创建提币记录 cliwithdraw.Status = "自动发放" cliwithdraw.Desc = transfer cliwithdraw.Descnum = &fee err = tx.Create(&cliwithdraw).Error if err != nil { tx.Rollback() // 回滚事务 return errors.Join(err, errors.New("创建提币记录失败")) } err = tx.Commit().Error if err != nil { tx.Rollback() return errors.Join(err, errors.New("提交事务失败")) } return nil }