package ews import ( "APIServer/cnf" "database/sql" "fmt" "log" _ "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 LastTrn string } type DefectInfo struct { USN string PartNO 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,last_transfer 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, &ui.LastTrn, ) //如果在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,last_transfer 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, &ul.LastTrn, ) 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,last_transfer 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, &uh.LastTrn, ) 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,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.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`, num, di.USN, di.PartNO, 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,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.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`, num, di.USN, di.PartNO, 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 { resp := fmt.Sprintf(`
%s
`, clr, msg) return resp } func (e *EWS) TemplateUutInfo(loc, locTime, misc, last, bkup string) string { if loc == "" { loc = `Unknown` } // if misc == "" { // misc = `NO Records !` // } // if bkup == "" { // bkup = `NO Records !` // } resp := fmt.Sprintf(` Test Records Location Info
Location Location Time
%s %s

Misc. Info
%s
Part NO. MO SKU First Ack Last Ack

测试记录
%s %s
USN MAC IP Address Server Test Item Status Message Last Change
`, loc, locTime, misc, last, bkup) return resp } func (e *EWS) TemplateDefectInfo(src string) string { if src == "" { src = `NO Records !` } resp := fmt.Sprintf(` Test Records %s
NO. USN Part NO. SKU Line Location Item Status Message First Ack Last Ack Last Change Differ Time (Min)
`, src) return resp }