|
@@ -0,0 +1,297 @@
|
|
|
|
+package order
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "config"
|
|
|
|
+ "encoding/json"
|
|
|
|
+ "fmt"
|
|
|
|
+ "github.com/cron"
|
|
|
|
+ "io/ioutil"
|
|
|
|
+ "log"
|
|
|
|
+ "mongodb"
|
|
|
|
+ "net/http"
|
|
|
|
+ qutil "qfw/util"
|
|
|
|
+ "qfw/util/redis"
|
|
|
|
+ "regexp"
|
|
|
|
+ "strings"
|
|
|
|
+ "time"
|
|
|
|
+ "util"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+type wxToken struct {
|
|
|
|
+ ErrorCode int `json:"errcode,omitempty"`
|
|
|
|
+ ErrorMessage string `json:"errmsg,omitempty"`
|
|
|
|
+ AccessToken string `json:"access_token"`
|
|
|
|
+ ExpiresIn int64 `json:"expires_in"`
|
|
|
|
+ LastTime int64 `json:"last_time"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type wxxdOrder struct {
|
|
|
|
+ ErrorCode int `json:"errcode"`
|
|
|
|
+ Total_num int `json:"total_num"`
|
|
|
|
+ Orders []struct {
|
|
|
|
+ Order_id int `json:"order_id"`
|
|
|
|
+ Status int `json:"status"`
|
|
|
|
+ Create_time string `json:"create_time"`
|
|
|
|
+ Update_time string `json:"update_time"`
|
|
|
|
+ Order_detail struct {
|
|
|
|
+ Product_infos []struct {
|
|
|
|
+ Title string `json:"title"`
|
|
|
|
+ Sku_attrs []struct {
|
|
|
|
+ Attr_key string `json:"attr_key"`
|
|
|
|
+ Attr_value string `json:"attr_value"`
|
|
|
|
+ } `json:"sku_attrs"`
|
|
|
|
+ } `json:"product_infos"`
|
|
|
|
+ Price_info struct {
|
|
|
|
+ Product_price int `json:"product_price"`
|
|
|
|
+ Order_price int `json:"order_price"`
|
|
|
|
+ Discounted_price int `json:"discounted_price"`
|
|
|
|
+ Freight int `json:"freight"`
|
|
|
|
+ Is_discounted bool `json:"is_discounted"`
|
|
|
|
+ } `json:"price_info"`
|
|
|
|
+ Couponcode_info struct {
|
|
|
|
+ Phone_number string `json:"phone_number"`
|
|
|
|
+ } `json:"couponcode_info"`
|
|
|
|
+ Pay_info struct {
|
|
|
|
+ Transaction_id string `json:"transaction_id"`
|
|
|
|
+ Pay_time string `json:"pay_time"`
|
|
|
|
+ } `json:"pay_info"`
|
|
|
|
+ } `json:"order_detail"`
|
|
|
|
+ } `json:"orders"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func ShopTask() {
|
|
|
|
+ go func() {
|
|
|
|
+ TokenHandle()
|
|
|
|
+ OrderHandle()
|
|
|
|
+ // 获取未执行的消息
|
|
|
|
+ c := cron.New()
|
|
|
|
+ c.AddFunc(config.SysConfigs.OrdreInterval, func() {
|
|
|
|
+ //订单处理
|
|
|
|
+ OrderHandle()
|
|
|
|
+ })
|
|
|
|
+ c.Start()
|
|
|
|
+ c2 := cron.New()
|
|
|
|
+ c2.AddFunc(config.SysConfigs.TokenInterval, func() {
|
|
|
|
+ //订单处理
|
|
|
|
+ TokenHandle()
|
|
|
|
+ })
|
|
|
|
+ c2.Start()
|
|
|
|
+ }()
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+func TokenHandle() string {
|
|
|
|
+ appid := config.SysConfigs.WxxdAppId
|
|
|
|
+ tokenKey := fmt.Sprintf("wxxdToken_%s", appid)
|
|
|
|
+ token := ""
|
|
|
|
+ resp, err := http.Get(config.SysConfigs.WxxdHost + "/cgi-bin/token?grant_type=client_credential&appid=" + config.SysConfigs.WxxdAppId + "&secret=" + config.SysConfigs.WxxdSecret)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Println(config.SysConfigs.WxxdAppId, "Get access token error", err)
|
|
|
|
+ } else {
|
|
|
|
+ defer resp.Body.Close()
|
|
|
|
+ body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Println(config.SysConfigs.WxxdAppId, "Read access token error", err)
|
|
|
|
+ } else {
|
|
|
|
+ var res wxToken
|
|
|
|
+ if err := json.Unmarshal(body, &res); err != nil {
|
|
|
|
+ log.Println(appid, "Parse access token error", err)
|
|
|
|
+ } else if res.ErrorCode != 0 {
|
|
|
|
+ log.Println(appid, "Reply access token error", res.ErrorCode, res.ErrorMessage)
|
|
|
|
+ } else if res.AccessToken != "" {
|
|
|
|
+ token = res.AccessToken
|
|
|
|
+ redis.Put("other", tokenKey, res.AccessToken, 3600)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return token
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func OrderHandle() {
|
|
|
|
+ //拉取核销过得数据
|
|
|
|
+ //获取token
|
|
|
|
+ appid := config.SysConfigs.WxxdAppId
|
|
|
|
+ tokenKey := fmt.Sprintf("wxxdToken_%s", appid)
|
|
|
|
+ token := ""
|
|
|
|
+ if fool, _ := redis.Exists("other", tokenKey); fool {
|
|
|
|
+ //存在
|
|
|
|
+ token = qutil.ObjToString(redis.Get("other", tokenKey))
|
|
|
|
+ } else {
|
|
|
|
+ token = TokenHandle()
|
|
|
|
+ }
|
|
|
|
+ //拉取核销人数据
|
|
|
|
+ //获取最后一次拉数据时间 ,如果没有,以当天时间凌晨0点为准
|
|
|
|
+ //start_update_time := "2022-04-18 06:22:44"
|
|
|
|
+ start_update_time := ""
|
|
|
|
+ data := util.JysqlDB.SelectBySql("select update_time from wxxd_order ORDER BY update_time desc LIMIT 1")
|
|
|
|
+ if len((*data)) > 0 {
|
|
|
|
+ start_update_time = qutil.ObjToString((*data)[0]["update_time"])
|
|
|
|
+ } else {
|
|
|
|
+ t := time.Now()
|
|
|
|
+ addTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
|
|
|
+ start_update_time = addTime.Format(qutil.Date_Full_Layout)
|
|
|
|
+ }
|
|
|
|
+ client := &http.Client{}
|
|
|
|
+ log.Println(start_update_time)
|
|
|
|
+ var jsonData = strings.NewReader(`{ "start_update_time": "` + start_update_time + `", "end_update_time": "` + time.Now().Format(qutil.Date_Full_Layout) + `", "status":"100", "page": 1, "page_size": 50, "source": 1 //选填,默认1 } `)
|
|
|
|
+ req, err := http.NewRequest("POST", config.SysConfigs.WxxdHost+"/product/order/get_list?access_token="+token, jsonData)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ req.Header.Set("User-Agent", "Apipost client Runtime/+https://www.apipost.cn/")
|
|
|
|
+ req.Header.Set("Content-Type", "application/json")
|
|
|
|
+ resp, err := client.Do(req)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ bodyText, err := ioutil.ReadAll(resp.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ var res wxxdOrder
|
|
|
|
+ if err := json.Unmarshal(bodyText, &res); err != nil {
|
|
|
|
+ log.Println(appid, "Parse access token error", err)
|
|
|
|
+ }
|
|
|
|
+ //循环处理一天数据
|
|
|
|
+ log.Println(res)
|
|
|
|
+ if res.Total_num > 0 {
|
|
|
|
+ for _, value := range res.Orders {
|
|
|
|
+ //先判断订单是否创建过
|
|
|
|
+ data := util.JysqlDB.CountBySql("select count(id) from wxxd_order where order_id=?", value.Order_id)
|
|
|
|
+ if data > 0 {
|
|
|
|
+ log.Println("此", value.Order_id, "订单核销创建过")
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ /*if value.Order_id!=3202692702381539840{
|
|
|
|
+ continue
|
|
|
|
+ }*/
|
|
|
|
+ orderStatus := false
|
|
|
|
+ code := fmt.Sprintf("%s%s", time.Now().Format("150405"), qutil.GetRandom(6))
|
|
|
|
+ param := &CreateOtherOrderParams{}
|
|
|
|
+ param.Phone = value.Order_detail.Couponcode_info.Phone_number
|
|
|
|
+ param.CourseId = value.Order_detail.Couponcode_info.Phone_number
|
|
|
|
+ param.ContractMoney = value.Order_detail.Price_info.Order_price
|
|
|
|
+ param.OrderMoney = param.ContractMoney
|
|
|
|
+ param.OrderMoney = value.Order_detail.Price_info.Product_price
|
|
|
|
+ param.ChargeMode = 1
|
|
|
|
+ param.ProceduresMoney = "0"
|
|
|
|
+ param.OrderChannel = "d03"
|
|
|
|
+ param.Commission = "0"
|
|
|
|
+ param.ReturnStatus = 1
|
|
|
|
+ param.SalesChannel = "x012"
|
|
|
|
+ param.PaybackCompany = "h01"
|
|
|
|
+ param.CreateTime = value.Create_time
|
|
|
|
+ param.Pay_time = value.Order_detail.Pay_info.Pay_time
|
|
|
|
+ param.Pay_way = "wx_app"
|
|
|
|
+ param.Transaction_id = value.Order_detail.Pay_info.Transaction_id
|
|
|
|
+ if strings.Index(value.Order_detail.Product_infos[0].Title, "超级订阅") >= 0 {
|
|
|
|
+ //超级订阅
|
|
|
|
+ param.ProductType = "VIP订阅"
|
|
|
|
+ //根据标题获取季度还是身份
|
|
|
|
+ titleArr := strings.Split(value.Order_detail.Product_infos[0].Title, " ")
|
|
|
|
+ if len(titleArr) == 0 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ param.CycleUnit = 2
|
|
|
|
+ for _, skuValue := range value.Order_detail.Product_infos[0].Sku_attrs {
|
|
|
|
+ if skuValue.Attr_key == "月" {
|
|
|
|
+ rCharacter := regexp.MustCompile(`\d`)
|
|
|
|
+ numb := ""
|
|
|
|
+ for _, value := range rCharacter.FindAllStringSubmatch(skuValue.Attr_value, -1) {
|
|
|
|
+ numb += value[0]
|
|
|
|
+ }
|
|
|
|
+ param.CycleCount = qutil.IntAll(numb)
|
|
|
|
+ }
|
|
|
|
+ if titleArr[2] == "单省" {
|
|
|
|
+ if skuValue.Attr_key != "月" {
|
|
|
|
+ param.Area = skuValue.Attr_value
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else if titleArr[2] == "全国" {
|
|
|
|
+ param.Area = "全国"
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ param.VipStartTime, param.VipType = vipInfo(param.Phone)
|
|
|
|
+ orderStatus, _ = createVipOrder(param, code)
|
|
|
|
+ } else if strings.Index(value.Order_detail.Product_infos[0].Title, "剑鱼投标课") >= 0 {
|
|
|
|
+ //线上课程
|
|
|
|
+ //根据线上课程名称查找Id
|
|
|
|
+ data, _ := util.MQFW.FindOne("jy_course", map[string]interface{}{"s_name": value.Order_detail.Product_infos[0].Sku_attrs[0].Attr_value})
|
|
|
|
+ param.CourseId = mongodb.BsonIdToSId((*data)["_id"])
|
|
|
|
+ orderStatus, _ = createCourseOrder(param, code)
|
|
|
|
+ }
|
|
|
|
+ if orderStatus {
|
|
|
|
+ //插入一条回款记录
|
|
|
|
+ payInsertData := map[string]interface{}{
|
|
|
|
+ "transaction_id": value.Order_detail.Pay_info.Transaction_id,
|
|
|
|
+ "out_trade_no": code,
|
|
|
|
+ "user_openid": "",
|
|
|
|
+ "total_fee": value.Order_detail.Price_info.Order_price,
|
|
|
|
+ "create_time": value.Order_detail.Pay_info.Pay_time,
|
|
|
|
+ "cash_fee": value.Order_detail.Price_info.Product_price,
|
|
|
|
+ "time_end": value.Order_detail.Pay_info.Pay_time,
|
|
|
|
+ "user_id": "",
|
|
|
|
+ "pay_channel": 1,
|
|
|
|
+ }
|
|
|
|
+ util.JysqlDB.Insert("weixin_pay", payInsertData)
|
|
|
|
+ //成功的话插入一条记录
|
|
|
|
+ insertData := map[string]interface{}{
|
|
|
|
+ "order_id": value.Order_id,
|
|
|
|
+ "create_time": time.Now().Format(qutil.Date_Full_Layout),
|
|
|
|
+ "status": value.Status,
|
|
|
|
+ "update_time": value.Update_time,
|
|
|
|
+ "order_code": code,
|
|
|
|
+ }
|
|
|
|
+ util.JysqlDB.Insert("wxxd_order", insertData)
|
|
|
|
+ log.Println(value.Order_id, ":创建成功")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+func vipInfo(phone string) (string, int) {
|
|
|
|
+ //查找之前是否开通超级订阅
|
|
|
|
+ vipStartTime := time.Now().Format(qutil.Date_Short_Layout)
|
|
|
|
+ vipType := 0
|
|
|
|
+ userData, ok := util.MQFW.FindOne("user", map[string]interface{}{"s_phone": phone})
|
|
|
|
+ userId := ""
|
|
|
|
+ if ok && userData != nil && len(*userData) > 0 {
|
|
|
|
+ userId = mongodb.BsonIdToSId((*userData)["_id"])
|
|
|
|
+ } else {
|
|
|
|
+ userData, ok = util.MQFW.FindOne("user", map[string]interface{}{"s_m_phone": phone})
|
|
|
|
+ if ok && userData != nil && len(*userData) > 0 {
|
|
|
|
+ userId = mongodb.BsonIdToSId((*userData)["_id"])
|
|
|
|
+ } else {
|
|
|
|
+ return vipStartTime, vipType
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ userInfo, oks := util.MQFW.FindOneByField("user", map[string]interface{}{"_id": mongodb.StringTOBsonId(userId)}, `{"_id":1,"i_vip_expire_tip":1,"i_vip_status":1,"l_vip_endtime":1,"l_vip_starttime":1,"o_vipjy":1,"s_m_phone":1,"s_phone":1}`)
|
|
|
|
+ if oks && userInfo != nil && len(*userInfo) > 0 {
|
|
|
|
+ //先判断用户是否有即将生效的超级订阅订单
|
|
|
|
+ query := map[string]interface{}{
|
|
|
|
+ "_id": mongodb.StringTOBsonId(userId),
|
|
|
|
+ "l_vip_starttime": map[string]interface{}{
|
|
|
|
+ "$gt": time.Now().Unix(),
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ count1 := util.MQFW.Count("user", query)
|
|
|
|
+ if count1 > 0 {
|
|
|
|
+ t := qutil.Int64All((*userInfo)["l_vip_endtime"])
|
|
|
|
+ _t := time.Unix(t, 0)
|
|
|
|
+ vipStartTime = (_t.AddDate(0, 0, 1)).Format(qutil.Date_Short_Layout)
|
|
|
|
+ vipType = 1
|
|
|
|
+ }
|
|
|
|
+ //查询是有是超级订阅的数据
|
|
|
|
+ //判断用户购买过超级订阅并且在有效期内 i_vip_status 开启状态:0-暂不使用vip订阅 1-试用 2-正式 -1-试用到期 -2-正式到期
|
|
|
|
+ userDatas, oks := util.MQFW.FindOneByField("user", map[string]interface{}{"_id": mongodb.StringTOBsonId(userId), "i_vip_status": 2}, `{"_id":1,"i_vip_expire_tip":1,"i_vip_status":1,"l_vip_endtime":1,"l_vip_starttime":1,"o_vipjy":1}`)
|
|
|
|
+ if oks && userDatas != nil && len(*userDatas) > 0 {
|
|
|
|
+ //正在生效的
|
|
|
|
+ if fmt.Sprint((*userInfo)["i_vip_status"]) == "2" {
|
|
|
|
+ t := qutil.Int64All((*userInfo)["l_vip_endtime"])
|
|
|
|
+ _t := time.Unix(t, 0)
|
|
|
|
+ vipStartTime = (_t.AddDate(0, 0, 1)).Format(qutil.Date_Short_Layout)
|
|
|
|
+ vipType = 1
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return vipStartTime, vipType
|
|
|
|
+}
|