之前用php實現定時器 基於swoole+Redis的消息實時推送通知 ,如果用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
}