package ews import ( "APIServer/cnf" "database/sql" "fmt" "log" "time" _ "github.com/go-sql-driver/mysql" ) type EWS struct{} type UutInfo struct { USN string MAC string IPAddr string Relay string Item string Status string Message string PartNO string MfgMO string MfgSKU string MfgLine string MfgStage string FirstAck string LastAck string LastChg string } type DefectInfo struct { USN string PartNO string MfgMO string SKU string Line string Location string Item string Status string Message string FirstAck string LastAck string LastChg string DiffMins string } func (e *EWS) SetUutInfo(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { if cfg.Settings.LogRequest { logger.Printf("[MSG] %s; %s; Request: %#v\r\n", addr, uri, params) } rst := map[string]string{"RESULT": ""} dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } rec := dbo.QueryRow( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfo WHERE usn='%s';`, params["USN"])) ui := new(UutInfo) err = rec.Scan( &ui.USN, &ui.MAC, &ui.IPAddr, &ui.Relay, &ui.Item, &ui.Status, &ui.Message, &ui.PartNO, &ui.MfgMO, &ui.MfgSKU, &ui.MfgLine, &ui.MfgStage, &ui.FirstAck, &ui.LastAck, &ui.LastChg, ) //如果在uutinfo表中未查找到此USN的记录, 则新增一条此USN的记录 if err == sql.ErrNoRows { dmlInsert := fmt.Sprintf("INSERT INTO uutinfo (usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%s,%s,%s);", params["USN"], params["MAC"], addr, host, params["ITEM"], params["STATUS"], params["MESSAGE"], params["PARTNO"], params["MO"], params["SKU"], params["LINE"], params["STAGE"], "NOW()", "NOW()", "NOW()", ) _, err = dbo.Exec(dmlInsert) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: %#v\r\n", addr, uri, rst) } rst["RESULT"] = "OK" rst["ErrMsg"] = "Inserted 1 new record." return rst } //如果此USN的记录存在与uutinfo表中, 且此USN的MAC/Item/Status/Message已变化, 则: //1. 备份此USN对应记录行到uutinfobkup表 //2. 更新uutinfo表中对应USN记录的MAC/Item/Status/Message/PartNO/MO/SKU/Line/Stage //3. 更新uutinfo表中此USN记录行的last_ack和last_change栏位为当前时间 extFlag := false chgFlag := false _, extFlag = params["MAC"] if extFlag && params["MAC"] != ui.MAC { chgFlag = true } _, extFlag = params["ITEM"] if extFlag && params["ITEM"] != ui.Item { chgFlag = true } _, extFlag = params["STATUS"] if extFlag && params["STATUS"] != ui.Status { chgFlag = true } _, extFlag = params["MESSAGE"] if extFlag && params["MESSAGE"] != ui.Message { chgFlag = true } if chgFlag { tx, err := dbo.Begin() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } stmt, err := tx.Prepare("INSERT INTO uutinfobkup (usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);") if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer stmt.Close() _, err = stmt.Exec( ui.USN, ui.MAC, addr, host, ui.Item, ui.Status, ui.Message, ui.PartNO, ui.MfgMO, ui.MfgSKU, ui.MfgLine, ui.MfgStage, ui.FirstAck, ui.LastAck, ui.LastChg, ) if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } stmt, err = tx.Prepare("UPDATE uutinfo SET mac=?, ipaddr=?, relay=?, item=?, status=?, message=?, partno=?, mo=?, sku=?, line=?, stage=?, last_ack=NOW(), last_change=NOW() WHERE usn=?;") if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer stmt.Close() _, err = stmt.Exec( params["MAC"], addr, host, params["ITEM"], params["STATUS"], params["MESSAGE"], params["PARTNO"], params["MO"], params["SKU"], params["LINE"], params["STAGE"], params["USN"], ) if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } err = tx.Commit() if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: %#v\r\n", addr, uri, rst) } rst["RESULT"] = "OK" rst["ErrMsg"] = "Updated and backed up 1 record." return rst } //如果此USN的记录存在与uutinfo表中, 且MAC/Item/Status/Message未变化, 则更新此USN记录的ipaddr,relay,stage, 并更新last_ack栏位为当前时间 dmlUpdate := fmt.Sprintf("UPDATE uutinfo SET ipaddr='%s', relay='%s', stage='%s', last_ack=NOW() WHERE usn='%s'", addr, host, params["STAGE"], params["USN"]) _, err = dbo.Exec(dmlUpdate) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: %#v\r\n", addr, uri, rst) } rst["RESULT"] = "OK" rst["ErrMsg"] = "Updated 1 record." return rst } func (e *EWS) GetUutInfo(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { if cfg.Settings.LogRequest { logger.Printf("[MSG] %s; %s; Request: %#v\r\n", addr, uri, params) } rst := map[string]string{"RESULT": ""} if params["KEY"] == "" || params["VALUE"] == "" { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, "Invalid Parameters !") rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", "Invalid Parameters !") return rst } dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } ul := new(UutInfo) partNO := "" mfgMO := "" mfgSKU := "" fstAck := "" lstAck := "" //Get Last Record last := "" curr, err := dbo.Query( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfo WHERE %s='%s' ORDER BY usn ASC, seqid ASC;`, params["KEY"], params["VALUE"])) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer curr.Close() for curr.Next() { err := curr.Scan( &ul.USN, &ul.MAC, &ul.IPAddr, &ul.Relay, &ul.Item, &ul.Status, &ul.Message, &ul.PartNO, &ul.MfgMO, &ul.MfgSKU, &ul.MfgLine, &ul.MfgStage, &ul.FirstAck, &ul.LastAck, &ul.LastChg, ) if err != nil { break } last = last + fmt.Sprintf(` %s %s %s %s %s %s %s %s %s`, ul.USN, ul.MAC, ul.IPAddr, ul.Relay, ul.Item, ul.Status, ul.Message, ul.LastChg, "\r\n") if ul.PartNO != "" { partNO = ul.PartNO } if ul.MfgMO != "" { mfgMO = ul.MfgMO } if ul.MfgSKU != "" { mfgSKU = ul.MfgSKU } if ul.FirstAck != "" { fstAck = ul.FirstAck } if ul.LastAck != "" { lstAck = ul.LastAck } } //Get Location Information loc, locTime := "", "" if last != "" { qry := dbo.QueryRow(fmt.Sprintf(`SELECT CONCAT_WS('-',line,col,row,num) AS loc, update_time FROM locinfo WHERE mac='%s'`, ul.MAC)) qry.Scan(&loc, &locTime) } //Get History Records uh := new(UutInfo) bkup := "" prev, err := dbo.Query( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfobkup WHERE %s='%s' ORDER BY usn ASC, seqid ASC;`, params["KEY"], params["VALUE"])) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer prev.Close() for prev.Next() { err := prev.Scan( &uh.USN, &uh.MAC, &uh.IPAddr, &uh.Relay, &uh.Item, &uh.Status, &uh.Message, &uh.PartNO, &uh.MfgMO, &uh.MfgSKU, &uh.MfgLine, &uh.MfgStage, &uh.FirstAck, &uh.LastAck, &uh.LastChg, ) if err != nil { break } bkup = bkup + fmt.Sprintf(`%s%s%s%s%s%s%s%s%s`, uh.USN, uh.MAC, uh.IPAddr, uh.Relay, uh.Item, uh.Status, uh.Message, uh.LastChg, "\r\n") } //Get Misc. Info if partNO == "" { partNO = uh.PartNO } if mfgMO == "" { mfgMO = uh.MfgMO } if mfgSKU == "" { mfgSKU = uh.MfgSKU } if fstAck == "" { fstAck = uh.FirstAck } if lstAck == "" { lstAck = uh.LastAck } misc := "" misc = fmt.Sprintf("%s%s%s%s%s", partNO, mfgMO, mfgSKU, fstAck, lstAck) rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateUutInfo(loc, locTime, misc, last, bkup) if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: Length=%d\r\n", addr, uri, len(rst["ErrMsg"])) } return rst } func (e *EWS) GetDefectReport(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { if cfg.Settings.LogRequest { logger.Printf("[MSG] %s; %s; Request: %#v\r\n", addr, uri, params) } rst := map[string]string{"RESULT": ""} dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } di := new(DefectInfo) defect := "" rows, err := dbo.Query( `SELECT usn,partno,mo,sku,line,location,item,status,message,first_ack,last_ack,last_change,diffmins FROM v_ngreport ORDER BY diffmins ASC;`) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer rows.Close() num := 1 for rows.Next() { err := rows.Scan( &di.USN, &di.PartNO, &di.MfgMO, &di.SKU, &di.Line, &di.Location, &di.Item, &di.Status, &di.Message, &di.FirstAck, &di.LastAck, &di.LastChg, &di.DiffMins, ) if err != nil { break } temp := fmt.Sprintf(`%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s`, num, di.USN, di.PartNO, di.MfgMO, di.SKU, di.Line, di.Location, di.Item, di.Status, di.Message, di.FirstAck, di.LastAck, di.LastChg, di.DiffMins, "\r\n") defect = defect + temp num += 1 } rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateDefectInfo(defect) if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: Length=%d\r\n", addr, uri, len(rst["ErrMsg"])) } return rst } func (e *EWS) GetOfflineReport(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { if cfg.Settings.LogRequest { logger.Printf("[MSG] %s; %s; Request: %#v\r\n", addr, uri, params) } rst := map[string]string{"RESULT": ""} dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } di := new(DefectInfo) offline := "" rows, err := dbo.Query( `SELECT usn,partno,mo,sku,line,location,item,status,message,first_ack,last_ack,last_change,diffmins FROM v_offline ORDER BY diffmins DESC;`) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer rows.Close() num := 1 for rows.Next() { err := rows.Scan( &di.USN, &di.PartNO, &di.MfgMO, &di.SKU, &di.Line, &di.Location, &di.Item, &di.Status, &di.Message, &di.FirstAck, &di.LastAck, &di.LastChg, &di.DiffMins, ) if err != nil { break } temp := fmt.Sprintf(`%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s`, num, di.USN, di.PartNO, di.MfgMO, di.SKU, di.Line, di.Location, di.Item, di.Status, di.Message, di.FirstAck, di.LastAck, di.LastChg, di.DiffMins, "\r\n") offline = offline + temp num += 1 } rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateDefectInfo(offline) if cfg.Settings.LogResponse { logger.Printf("[MSG] %s; %s; Response: Length=%d\r\n", addr, uri, len(rst["ErrMsg"])) } return rst } func (e *EWS) SimpleMsgHTML(clr, msg string) string { now := time.Now().Format("2006-01-02 15:04:05") resp := fmt.Sprintf(`
[%s] %s
`, clr, now, msg) return resp } func (e *EWS) TemplateUutInfo(loc, locTime, misc, last, bkup string) string { now := time.Now().Format("2006-01-02 15:04:05") if loc == "" { loc = `Unknown` } // if misc == "" { // misc = `NO Records !` // } // if bkup == "" { // bkup = `NO Records !` // } resp := fmt.Sprintf(` Test Records Response Time: %s

Location Info
Location Location Time
%s %s

Misc. Info
%s
PartNO. MO SKU First Ack Last Ack

测试记录
%s %s
USN MAC IP Address Server Test Item Status Message Last Change
`, now, loc, locTime, misc, last, bkup) return resp } func (e *EWS) TemplateDefectInfo(src string) string { now := time.Now().Format("2006-01-02 15:04:05") if src == "" { src = fmt.Sprintf(`[%s] NO Records !
`, now) } resp := fmt.Sprintf(` Test Records Response Time: %s
%s
NO. USN PartNO. MO SKU Line Location Item Status Message First Ack Last Ack Last Change Differ Time (Min)
`, now, src) return resp }