func personFinanceSettle() { now := time.Now() //invokeSettle(now.Add(time.Hour * -24)) unix := tool.GetStartDate(time.Now()).Unix() if todayIsSettled(unix) { log.Println("[ PersonFinance][ Settle][ Info]:Today is settled!") return } invokeSettle(now) saveLatestSettleUnix(unix) }
// 确认转入数据 // 采用按ID分段,通过传入ID区间用多个gorouting进行处理. func confirmTransferIn(t time.Time) { var err error settleTime := t.AddDate(0, 0, -personfinance.RiseSettleTValue) // 倒推结算日 unixDate := tool.GetStartDate(settleTime).Unix() cursor := 0 // 游标,每次从db中取条数 setupNum := 0 //步骤编号 for { // 获取前1000条记录到IdArr idArr := []int{} i := 0 err = _db.Query("SELECT id FROM pf_riselog WHERE unix_date=? AND type=? AND state=? LIMIT 0,?", func(rows *sql.Rows) { for rows.Next() { rows.Scan(&i) if i > 0 { idArr = append(idArr, i) } } }, unixDate, personfinance.RiseTypeTransferIn, personfinance.RiseStateDefault, 1000) if err != nil { log.Println("[ Error][ Transfer-Confirm]:", err.Error()) break } if len(idArr) == 0 { break } setupNum += 1 log.Println("[ PersonFinance][ Transfer][ Job]:Setup", setupNum, "; Total", len(idArr), "records! unix date =", unixDate) // 将IdArr按指定size切片处理 wg := sync.WaitGroup{} for cursor < len(idArr) { var splitIdArr []int if cursor+batGroupSize < len(idArr) { splitIdArr = idArr[cursor : cursor+batGroupSize] } else { splitIdArr = idArr[cursor:] } go confirmTransferInByCursor(&wg, unixDate, splitIdArr) cursor += batGroupSize wg.Add(1) time.Sleep(time.Microsecond * 1000) //log.Println("[Output]- ", splitIdArr[0], splitIdArr[len(splitIdArr)-1],len(splitIdArr)) } wg.Wait() cursor = 0 //重置游标 } }
// 结算增利数据,t为结算日 // 采用按ID分段,通过传入ID区间用多个gorouting进行处理. func settleRiseData(settleDate time.Time) { var err error settleUnix := tool.GetStartDate(settleDate).Unix() //结算日期 cursor := 0 setupNum := 0 //步骤编号 for { idArr := []int{} i := 0 err = _db.Query("SELECT person_id FROM pf_riseinfo WHERE settlement_amount > 0 AND settled_date < ? LIMIT 0,?", func(rows *sql.Rows) { for rows.Next() { rows.Scan(&i) if i > 0 { idArr = append(idArr, i) } } }, settleUnix, 1000) if err != nil { log.Println("[ Error][ Rise-Settle]:", err.Error()) break } if len(idArr) == 0 { break } setupNum += 1 log.Println("[ PersonFinance][ RiseSettle][ Job]:Setup ", setupNum, " ; Total ", len(idArr), "records! unix date =", settleUnix) wg := sync.WaitGroup{} for cursor < len(idArr) { var splitIdArr []int if cursor+batGroupSize < len(idArr) { splitIdArr = idArr[cursor : cursor+batGroupSize] } else { splitIdArr = idArr[cursor:] } go riseGroupSettle(&wg, settleUnix, splitIdArr) cursor += batGroupSize wg.Add(1) time.Sleep(time.Microsecond * 1000) log.Println("[Output]- ", splitIdArr[0], splitIdArr[len(splitIdArr)-1], len(splitIdArr)) } wg.Wait() cursor = 0 //重置游标 time.Sleep(time.Second * 5) } }
// 转入 func (this *riseInfo) TransferIn(amount float32, w personfinance.TransferWith) (err error) { if this._v == nil { //判断会员是否存在 if _, err = this.Value(); err != nil { return err } } if amount <= 0 { return personfinance.ErrIncorrectAmount } if amount < personfinance.RiseMinTransferInAmount { return errors.New(fmt.Sprintf(personfinance.ErrLessThanMinTransferIn.Error(), format.FormatFloat(personfinance.RiseMinTransferInAmount))) } dt := time.Now() this._v.TransferIn += amount this._v.TotalAmount += amount this._v.UpdateTime = dt.Unix() if err = this.Save(); err == nil { //保存并记录日志 _, err = this._rep.SaveRiseLog(&personfinance.RiseLog{ PersonId: this.GetDomainId(), Title: "[转入]从" + personfinance.TransferInWithText(w) + "转入", Amount: amount, Type: personfinance.RiseTypeTransferIn, TransferWith: int(w), State: personfinance.RiseStateDefault, UnixDate: tool.GetStartDate(dt).Unix(), LogTime: this._v.UpdateTime, UpdateTime: this._v.UpdateTime, }) } return err }
// 转出,w为转出方式(如银行,余额等),state为日志的状态,某些操作 // 需要确认,有些不需要.通过state来传入 func (this *riseInfo) TransferOut(amount float32, w personfinance.TransferWith, state int) (err error) { if this._v == nil { //判断会员是否存在 if _, err = this.Value(); err != nil { return err } } if amount <= 0 { return personfinance.ErrIncorrectAmount } if amount > this._v.Balance { //超出账户金额 return personfinance.ErrOutOfBalance } // 低于最低转出金额,且不是全部转出.返回错误. 若转出到余额则无限制 if amount != this._v.Balance && //非全部转出 w != personfinance.TransferOutWithBalance && //非转出余额 amount < personfinance.RiseMinTransferOutAmount { if this._v.Balance > personfinance.RiseMinTransferOutAmount { //金额大于转出金额 return errors.New(fmt.Sprintf(personfinance.ErrLessThanMinTransferOut.Error(), format.FormatFloat(personfinance.RiseMinTransferOutAmount))) } else { //金额小于转出金额 return errors.New(fmt.Sprintf(personfinance.ErrMustAllTransferOut.Error(), format.FormatFloat(personfinance.RiseMinTransferOutAmount))) } } dt := time.Now() this._v.UpdateTime = dt.Unix() this._v.Balance -= amount this._v.SettlementAmount -= amount if this._v.SettlementAmount < 0 { //提现超出结算金额 this._v.SettlementAmount = 0 } if this._v.Balance == 0 { //若全部提出,则理财收益和结算金额清零 this._v.Rise = 0 this._v.SettlementAmount = 0 } if err = this.Save(); err == nil { //保存并记录日志 _, err = this._rep.SaveRiseLog(&personfinance.RiseLog{ PersonId: this.GetDomainId(), Title: "[转出]转出到" + personfinance.TransferOutWithText(w), Amount: amount, Type: personfinance.RiseTypeTransferOut, TransferWith: int(w), State: state, UnixDate: tool.GetStartDate(dt).Unix(), LogTime: this._v.UpdateTime, UpdateTime: this._v.UpdateTime, }) } //todo: 新增操作记录,如审核,打款,完成等 return err }