使用time.NewTicker做定时任务做数据推送


之前用php实现定时器 ,如果用golang来做个功能就简单多了,golang自带time包,提供了定时器的作用,接下来使用time.NewTicker来做

一 实现的功能

生产系统打码发货后更新生产系统中订单物流状态
将生产系统订单状态时时更新到商城物流系统

二 idea新项目和安装mssql orm包

new Project选择Go Modules

go get xorm.io/xorm
go get github.com/denisenkom/go-mssqldb

三 代码

package main

import (
	"encoding/json"
	"fmt"
	_ "github.com/denisenkom/go-mssqldb"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
	"xorm.io/xorm"
)

type job struct {
	syncAction func(j *job)
	params     map[string]interface{}
	ch         chan int
}

func (j *job) Run(t time.Duration) {
	ticker := time.NewTicker(time.Second * t)
	for {
		select {
		case <-ticker.C:
			go j.syncAction(j)
		}
	}
}
func NewJob() *job {
	return &job{
		params: make(map[string]interface{}),
		ch:     make(chan int),
	}
}


func main() {

	//配置参数
	selectWhere := " AND LEFT(TableA.OrderNo, 4) NOT IN( 'CP01') "

	//1.数据库连接
	message := ""
	var dbConfig = [...]string{
		"192.168.0.190",
		"setangle",
		"123456",
		"PM_01",
	}
	connString := fmt.Sprintf("server=%s;port%d;user id=%s;password=%s;database=%s;", dbConfig[0], 1433, dbConfig[1], dbConfig[2], dbConfig[3])
	engineDb, err := xorm.NewEngine("mssql", connString)
	if err != nil {
		message = "连接数据库失败:"
		fmt.Print(message + err.Error())
		return
	}
	//engineDb.ShowSQL(true)
	fieldSql := "TableA.OrderNo as field2,TableA.BookNo field1,TableA.LinkMan as name," +
		"TableA.LogisticsCompany as freight_id,TableA.ZipCode as postcode"
	sqlSelect := "SELECT TOP 3 " + fieldSql + " FROM TableB INNER JOIN TableA" +
		" ON TableB.c_orderNo = TableA.OrderNo AND TableB.c_orderItem = TableA.BookNo" +
		" WHERE  TableB.sync_flag != 999 " + selectWhere + "  ORDER BY TableB.d_createTime DESC"

	sqlUpdate := "UPDATE `TableB` SET `sync_flag`=999 WHERE c_orderNo=? and c_orderItem=? "

	//2.同步推送
	siteDomain := ""
	jobObj := NewJob()
	jobObj.syncAction = func(jj *job) {
		orderList, err := engineDb.QueryString(sqlSelect)
		if err != nil {
			fmt.Print("数据库错误" + err.Error())
			return
		}
		if len(orderList) <1 {
			fmt.Println(time.Now().Format("2006-02-01 15:04:05"),"暂时没有需要推送的发货订单")
			return
		}
		postUrl := "/deliveryApi"
		for _, orderVo := range orderList {

			siteDomain = getSiteDomain(orderVo["field2"])

			fmt.Print(time.Now().Format("2006-02-01 15:04:05"), " 订单号"+orderVo["field2"]+"_"+orderVo["field1"])
			response, _ := CurlPost(siteDomain+postUrl, orderVo, 2);
			fmt.Print(" 返回" + response)
			if strings.Contains(response, "ok") {
				_, err := engineDb.Exec(sqlUpdate, orderVo["field2"], orderVo["field1"])
				if err != nil {
					fmt.Print(" 回写失败" + err.Error())
				}
			}
			fmt.Print("\n")
		}
	}
	jobObj.Run(5)

}
//curl post请求(可以设置超时时间)
func CurlPost(link string, param map[string]string, timeout time.Duration) (response string, err error) {

	bytes, err := json.Marshal(param)
	r := strings.NewReader(string(bytes))
	req, err := http.NewRequest("POST", link, r)
	if err != nil {
		return response, err
	}
	//设置json
	req.Header.Set("Content-Type", "application/json")
	//设置post超时时间
	client := http.Client{
		Timeout: time.Second * timeout,
	}
	resp, err := client.Do(req)
	if err != nil {
		return response, err
	}
	//处理返回数据
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return string(body), nil
}

//根据订单前缀判断同步域名
func getSiteDomain(orderNo string) string  {

	siteDomain := "http://www.test.com"
	return siteDomain
}