package main import ( "encoding/json" "flag" "fmt" "log" "strconv" "strings" "xiaoniaokuaiyan.com/xiaoniao/config" "xiaoniaokuaiyan.com/xiaoniao/constants" "time" "xiaoniaokuaiyan.com/xiaoniao/entity" "xiaoniaokuaiyan.com/xiaoniao/util" "github.com/jmoiron/sqlx" "gopkg.in/redis.v2" ) //type DetectItem struct { // Name string `db:"name" json:"name"` // //MarketPrice float32 `db:"market_price" json:"marketPrice"` //} // //type ProductDB struct { // Id string `db:"id" json:"id"` // Name string `db:"name" json:"name"` // Price int `db:"price" json:"price"` // IsRecommend int `db:"is_recommend" json:"isRecommend"` // Tags string `db:"tags" json:"tags"` // Picture string `db:"picture" json:"picture"` // Items []string `db:"-" json:"items"` //} func main() { var ( client *redis.Client nowStr string orderPayKey = "order_unpay" ticker = time.NewTicker(time.Second) db *sqlx.DB oid string timeStr string mId int64 delaySec int ) fs := flag.NewFlagSet("", flag.ExitOnError) configFile := fs.String("f", "config.ini", "app config file") config.Reload(*configFile) defer ticker.Stop() db = util.GetWriteSqlDB() strSql := "select id, created_at, m_id, delay_deadtime from t_order where status = 1" rows, err := db.Query(strSql) if err != nil { log.Fatal(err) } client = util.GetRedis() client.Select(12) for rows.Next() { rows.Scan(&oid, &timeStr, &mId, &delaySec) client.HSet(orderPayKey, oid, fmt.Sprintf("%s;%d;%d", timeStr, mId, delaySec)) } var delayTimeSecs int64 for { select { case <-ticker.C: client = util.GetRedis() client.Select(12) msCmd := client.HGetAllMap(orderPayKey) if err := msCmd.Err(); err != nil { log.Panicln(err) } kvs := msCmd.Val() for key, val := range kvs { temp := strings.Split(val, ";") if len(temp) < 2 { continue } delayTimeSecs = int64(time.Second) * 30 * 60 if len(temp) == 3 { delaySec, err = strconv.Atoi(temp[2]) if err != nil { log.Println(err, val) continue } delayTimeSecs = int64(time.Second) * int64(delaySec) } nowStr = time.Now().Add(-time.Duration(delayTimeSecs)).Format("2006-01-02 15:04:05") if temp[0] < nowStr { tx, _ := db.Begin() //todo set order status to unused sr, _ := tx.Exec("update t_order set status = 9, m_id = 0 where id = ? and status = 1", key) if er, _ := sr.RowsAffected(); er <= 0 { log.Println("update order status of ", key, " failed") client.HDel(orderPayKey, key) tx.Rollback() continue } if temp[1] != "0" { sr, _ = tx.Exec("update t_producer_info set remain_num = remain_num + 1 where id = ?", temp[1]) if er, _ := sr.RowsAffected(); er <= 0 { log.Println("failed to update producer info of ", key, temp[1]) client.HDel(orderPayKey, key) tx.Rollback() continue } } orderItem := entity.OrderDB{} err1 := db.Get(&orderItem, "select * FROM t_order WHERE id = ?", key) //回滚库存 var ops = []entity.OrderProduct{} db.Select(&ops, "select t1.*, t2.stock_switch from t_order_product t1 left join t_product t2 on t1.product_id = t2.id where order_id = ?", key) for _, op := range ops { if op.StockSwitch == "ON" { sql := "update t_product set stock = stock + ? where id = ?" if orderItem.Source == "sp_zfb" { sql = "update t_product set zfb_stock = zfb_stock + ? where id = ?" } result, _ := tx.Exec(sql, op.Quantity, op.ProductId) if ra, _ := result.RowsAffected(); ra <= 0 { tx.Rollback() log.Println(key + "更新库存失败") } } } db.Exec("update t_discount_ticket set order_id = null, status = 0 where order_id = ?;", key) intCmd := client.HDel(orderPayKey, key) if err := intCmd.Err(); err != nil { tx.Rollback() log.Println(err) continue } tx.Commit() if err1 == nil { //20210303 添加状态通知 if util.SourceCheck(orderItem.Source) { log.Printf("%s,send status 9", key) msg := map[string]interface{}{ "user": "system", "orderid": orderItem.Id, "source": orderItem.Source, "status": constants.ORDERSTATUS_UNUSED, } buf, _ := json.Marshal(msg) client.Publish("order-status-change", string(buf)) } } } } } } }