first commit
This commit is contained in:
commit
e8195401d2
BIN
APIServer.exe
Normal file
BIN
APIServer.exe
Normal file
Binary file not shown.
489
APIServer.go
Normal file
489
APIServer.go
Normal file
@ -0,0 +1,489 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"APIServer/cnf"
|
||||||
|
"APIServer/ews"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/chai2010/winsvc"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/natefinch/lumberjack"
|
||||||
|
uuid "github.com/satori/go.uuid"
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cfg = cnf.Cfg{}
|
||||||
|
var svc string = "apisvr"
|
||||||
|
var vsn bool = false
|
||||||
|
var ver string = ""
|
||||||
|
var logger *log.Logger
|
||||||
|
var flagIns bool = false
|
||||||
|
var flagRmv bool = false
|
||||||
|
var flagRun bool = false
|
||||||
|
var flagTer bool = false
|
||||||
|
var flagRst bool = false
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.BoolVar(&flagIns, "i", false, "Install Service")
|
||||||
|
flag.BoolVar(&flagRmv, "u", false, "Uninstall Service")
|
||||||
|
flag.BoolVar(&flagRun, "s", false, "Start Service")
|
||||||
|
flag.BoolVar(&flagTer, "t", false, "Stop Service")
|
||||||
|
flag.BoolVar(&flagRst, "r", false, "Restart Service")
|
||||||
|
flag.BoolVar(&vsn, "v", false, "Show Program Version")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
logger = log.New(&lumberjack.Logger{
|
||||||
|
Filename: strings.TrimSuffix(os.Args[0], ".exe") + ".log",
|
||||||
|
MaxAge: 30,
|
||||||
|
MaxSize: 10,
|
||||||
|
MaxBackups: 100,
|
||||||
|
LocalTime: true,
|
||||||
|
}, "", log.Ldate|log.Ltime|log.Lmicroseconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if vsn {
|
||||||
|
showVersion()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
self := strings.TrimSuffix(os.Args[0], ".exe")
|
||||||
|
file := self + ".yml"
|
||||||
|
src, err := os.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = yaml.Unmarshal(src, &cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cwd, err := winsvc.GetAppPath()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = os.Chdir(filepath.Dir(cwd))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install Service
|
||||||
|
if flagIns {
|
||||||
|
err := winsvc.InstallService(cwd, svc, "API Server")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Install Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Install Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Install Service Successfully.\r\n")
|
||||||
|
logger.Printf("[MSG] Install Service Successfully.\r\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninstall Service
|
||||||
|
if flagRmv {
|
||||||
|
err := winsvc.RemoveService(svc)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Uninstall Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Uninstall Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Uninstall Service Successfully.\r\n")
|
||||||
|
logger.Printf("[MSG] Uninstall Service Successfully.\r\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Service
|
||||||
|
if flagRun {
|
||||||
|
err := winsvc.StartService(svc)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Start Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Start Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Service Started.\r\n")
|
||||||
|
logger.Printf("[MSG] Service Started.\r\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Service
|
||||||
|
if flagTer {
|
||||||
|
err := winsvc.StopService(svc)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Stop Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Stop Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Service Stop.\r\n")
|
||||||
|
logger.Printf("[MSG] Service Stop.\r\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restart Service
|
||||||
|
if flagRst {
|
||||||
|
err := winsvc.StopService(svc)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Stop Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Stop Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Service Stop.\r\n")
|
||||||
|
logger.Printf("[MSG] Service Stop.\r\n")
|
||||||
|
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
|
err = winsvc.StartService(svc)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Start Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Start Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Service Started.\r\n")
|
||||||
|
logger.Printf("[MSG] Service Started.\r\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !winsvc.InServiceMode() {
|
||||||
|
err := winsvc.RunAsService(svc, startSvc, stopSvc, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] Run As Service Failed: %s\r\n", err.Error())
|
||||||
|
logger.Printf("[ERR] Run As Service Failed: %s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Printf("[MSG] Run As Service ...\r\n")
|
||||||
|
logger.Printf("[MSG] Run As Service ...\r\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startSvc() {
|
||||||
|
log.Printf("[MSG] Starting Service ...\r\n")
|
||||||
|
logger.Printf("[MSG] Starting Service ...\r\n")
|
||||||
|
http.HandleFunc("/", handleIndex)
|
||||||
|
http.HandleFunc("/request/", handleRequest)
|
||||||
|
http.HandleFunc("/fileinfo/", handleFileInfo)
|
||||||
|
http.HandleFunc("/getuutinfo/", handleGetUutInfo)
|
||||||
|
http.HandleFunc("/setuutinfo/", handleSetUutInfo)
|
||||||
|
logger.Printf("[MSG] Starting HTTP Server On Port: %s\r\n", cfg.Settings.ListenPort)
|
||||||
|
err := http.ListenAndServe(":"+cfg.Settings.ListenPort, nil)
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("%s\r\n", err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopSvc() {
|
||||||
|
log.Printf("[MSG] Stopping Service ...\r\n")
|
||||||
|
logger.Printf("[MSG] Stopping Service ...\r\n")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.RequestURI == "/favicon.ico" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method != http.MethodGet {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
fmt.Fprintf(w, "MethodNotAllowed: %v\r\n", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tpl, err := template.ParseFiles("./Index.html")
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
fmt.Fprintf(w, "ErrMsg: %v\r\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = tpl.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
fmt.Fprintf(w, "ErrMsg: %v\r\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.RequestURI == "/favicon.ico" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
fmt.Fprintf(w, "MethodNotAllowed: %v\r\n", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqID := uuid.NewV4().String()
|
||||||
|
logger.Printf("RequestID: %s; Addr: %s; URI: %s\r\n", reqID, r.RemoteAddr, r.RequestURI)
|
||||||
|
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", reqID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var params []string
|
||||||
|
if len(r.Form) > 0 {
|
||||||
|
logger.Printf("RequestID: %s; Form: %#v\r\n", reqID, r.Form)
|
||||||
|
for k, v := range r.Form {
|
||||||
|
if cfg.Settings.ParamCheck {
|
||||||
|
if !chkParams(k) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !chkParams(v[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params = append(params, fmt.Sprintf("%s:%s", k, strings.ReplaceAll(v[0], " ", "_")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Printf("RequestID: %s; Params: %#v\r\n", reqID, params)
|
||||||
|
resp := runCommand(cfg.Settings.HookScript, params, reqID)
|
||||||
|
fmt.Fprintf(w, "%s\r\n", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleFileInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.RequestURI == "/favicon.ico" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reqID := uuid.NewV4().String()
|
||||||
|
logger.Printf("RequestID: %s; Addr: %s; URI: %s\r\n", reqID, r.RemoteAddr, r.RequestURI)
|
||||||
|
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", reqID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var path string = ""
|
||||||
|
if len(r.Form) > 0 {
|
||||||
|
for k, v := range r.Form {
|
||||||
|
if cfg.Settings.ParamCheck {
|
||||||
|
if !chkParams(k) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !chkParams(v[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if k == "path" {
|
||||||
|
path = v[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if path == "" {
|
||||||
|
fmt.Fprintf(w, "%v", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "%v", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileInfo struct {
|
||||||
|
FileName string `json:"FileName"`
|
||||||
|
FileSize int64 `json:"FileSize"`
|
||||||
|
LastModified string `json:"LastModified"`
|
||||||
|
//MD5Hash string `json:"MD5Hash"`
|
||||||
|
}
|
||||||
|
type FileList struct {
|
||||||
|
FileList []FileInfo `json:"FileList"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var infoList []FileInfo
|
||||||
|
err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if !info.IsDir() {
|
||||||
|
var fileInfo FileInfo
|
||||||
|
fileInfo.FileName = info.Name()
|
||||||
|
fileInfo.FileSize = info.Size()
|
||||||
|
fileInfo.LastModified = info.ModTime().Format("2006-01-02 15:04:05")
|
||||||
|
//fileInfo.MD5Hash = fileMD5(path)
|
||||||
|
infoList = append(infoList, fileInfo)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList := FileList{infoList}
|
||||||
|
jsonObj, err := json.MarshalIndent(fileList, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "%s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%s", string(jsonObj))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetUutInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.RequestURI == "/favicon.ico" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
host := strings.Split(r.Host, ":")[0]
|
||||||
|
addr := strings.Split(r.RemoteAddr, ":")[0]
|
||||||
|
uri := r.RequestURI
|
||||||
|
rst := map[string]string{"RESULT": ""}
|
||||||
|
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
logger.Printf("[ERR] %s; %s; %s\r\n", r.RemoteAddr, r.RequestURI, err.Error())
|
||||||
|
rst["RESULT"] = "NG"
|
||||||
|
rst["ErrMsg"] = err.Error()
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
fmt.Fprintf(w, "%v", strings.ReplaceAll(fmt.Sprintf("%#v", rst), "map[string]string", ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params := make(map[string]string, 0)
|
||||||
|
if len(r.Form) > 0 {
|
||||||
|
for k, v := range r.Form {
|
||||||
|
params[strings.ToUpper(strings.TrimSpace(k))] = strings.TrimSpace(v[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ews := new(ews.EWS)
|
||||||
|
rst = ews.GetUutInfo(cfg, logger, host, addr, uri, params)
|
||||||
|
if rst["RESULT"] != "OK" {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%v", rst["ErrMsg"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSetUutInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
if r.RequestURI == "/favicon.ico" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host := strings.Split(r.Host, ":")[0]
|
||||||
|
addr := strings.Split(r.RemoteAddr, ":")[0]
|
||||||
|
uri := r.RequestURI
|
||||||
|
rst := map[string]string{"RESULT": ""}
|
||||||
|
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
rst["RESULT"] = "NG"
|
||||||
|
rst["ErrMsg"] = fmt.Sprintf("MethodNotAllowed: %v", http.StatusMethodNotAllowed)
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
fmt.Fprintf(w, "%v", strings.ReplaceAll(fmt.Sprintf("%#v", rst), "map[string]string", ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params, err := parseReqParams(r)
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("[ERR] %s; %s; %#v; %s\r\n", r.RemoteAddr, r.RequestURI, params, rst["ErrMsg"])
|
||||||
|
rst["RESULT"] = "NG"
|
||||||
|
rst["ErrMsg"] = err.Error()
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
fmt.Fprintf(w, "%v", strings.ReplaceAll(fmt.Sprintf("%#v", rst), "map[string]string", ""))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ews := new(ews.EWS)
|
||||||
|
rst = ews.SetUutInfo(cfg, logger, host, addr, uri, params)
|
||||||
|
if rst["RESULT"] != "OK" {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%v", strings.ReplaceAll(fmt.Sprintf("%#v", rst), "map[string]string", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseReqParams(r *http.Request) (map[string]string, error) {
|
||||||
|
params := make(map[string]string, 0)
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
logger.Printf("[ERR] %s; %s; %s\r\n", r.RemoteAddr, r.RequestURI, err.Error())
|
||||||
|
return params, err
|
||||||
|
}
|
||||||
|
if len(r.Form) > 0 {
|
||||||
|
for k, v := range r.Form {
|
||||||
|
params[strings.ToUpper(strings.TrimSpace(k))] = strings.TrimSpace(v[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* func fileMD5(filePath string) string {
|
||||||
|
file, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
hash := md5.New()
|
||||||
|
_, err = io.Copy(hash, file)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(hash.Sum(nil))
|
||||||
|
} */
|
||||||
|
|
||||||
|
func chkParams(arg string) bool {
|
||||||
|
if strings.Contains(arg, ";") ||
|
||||||
|
strings.Contains(arg, "|") ||
|
||||||
|
strings.Contains(arg, "&") ||
|
||||||
|
strings.Contains(arg, ">") ||
|
||||||
|
strings.Contains(arg, "<") ||
|
||||||
|
strings.Contains(arg, "(") ||
|
||||||
|
strings.Contains(arg, ")") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommand(cmdStr string, argStr []string, requestID string) string {
|
||||||
|
cmd := exec.Command(cmdStr, argStr...)
|
||||||
|
if errors.Is(cmd.Err, exec.ErrDot) {
|
||||||
|
cmd.Err = nil
|
||||||
|
}
|
||||||
|
std, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", requestID, err.Error())
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
defer std.Close()
|
||||||
|
err = cmd.Start()
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", requestID, err.Error())
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
ret, err := io.ReadAll(std)
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", requestID, err.Error())
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
err = cmd.Wait()
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("RequestID: %s; ErrMsg: %s\r\n", requestID, err.Error())
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
//fmt.Printf("\r\n%s\r\n\r\n", string(ret))
|
||||||
|
//logger.Printf("RequestID: %s; Result: \r\n%s\r\n\r\n", requestID, string(ret))
|
||||||
|
return string(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func showVersion() {
|
||||||
|
fmt.Printf("%s\r\nVersion: %s\r\n", os.Args[0], ver)
|
||||||
|
}
|
17
APIServer.yml
Normal file
17
APIServer.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Settings:
|
||||||
|
ListenPort: 9000
|
||||||
|
HookScript: APIHOOK
|
||||||
|
ParamCheck: false
|
||||||
|
LogRequest: true
|
||||||
|
LogResponse: false
|
||||||
|
MySQL:
|
||||||
|
Server: 10.60.230.109
|
||||||
|
Port: 3306
|
||||||
|
Database: ewsv3_f716
|
||||||
|
User: apisvc
|
||||||
|
Password: wcqte
|
||||||
|
Remark:
|
||||||
|
Columns_UutInfo: [usn,mac,ipaddr,status,message,first_ack,last_ack,last_change,last_transfer]
|
||||||
|
Columns_LocInfo: [mac,line,col,row,num,last_found]
|
||||||
|
USER_RO: ewsv3:ewsv3
|
||||||
|
USER_RW: apisvc:wcqte
|
29
Index.html
Normal file
29
Index.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
|
||||||
|
<title>API Server</title>
|
||||||
|
<style type="text/css">
|
||||||
|
ul,li {margin: 0px; padding: 0px; list-style-type: none;}
|
||||||
|
label {font-family: Consolas; font-size: 16px;}
|
||||||
|
input {width: 250px; height: 20px; font-family: monospace; font-size: 14px;}
|
||||||
|
iframe {word-wrap: break-word; position: static; border: 0; top: 0px; left: 0px; min-width: 1000px; min-height: 1000px;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body leftmargin="10px" >
|
||||||
|
<h4>机台测试记录查询</h4>
|
||||||
|
<form name="getuutinfo" action="/getuutinfo/" method="POST" target="result">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<label>USN: </label>
|
||||||
|
<input type="text" name="USN" id="USN" />
|
||||||
|
|
||||||
|
<input type="submit" name="Query" value="Query" style="width:75px; height:25px;" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</form>
|
||||||
|
<br/>
|
||||||
|
<iframe title="result" name="result" frameborder="no" marginwidth="0" marginheight="0"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
22
cnf/cnf.go
Normal file
22
cnf/cnf.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cnf
|
||||||
|
|
||||||
|
type Cfg struct {
|
||||||
|
Settings Settings `yaml:"Settings"`
|
||||||
|
MySQL MySQL `yaml:"MySQL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Settings struct {
|
||||||
|
ListenPort string `yaml:"ListenPort"`
|
||||||
|
HookScript string `yaml:"HookScript"`
|
||||||
|
ParamCheck bool `yaml:"ParamCheck"`
|
||||||
|
LogRequest bool `yaml:"LogRequest"`
|
||||||
|
LogResponse bool `yaml:"LogResponse"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MySQL struct {
|
||||||
|
Server string `yaml:"Server"`
|
||||||
|
Port string `yaml:"Port"`
|
||||||
|
Database string `yaml:"Database"`
|
||||||
|
User string `yaml:"User"`
|
||||||
|
Password string `yaml:"Password"`
|
||||||
|
}
|
517
ews/ews.go
Normal file
517
ews/ews.go
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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["USN"] == "" {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
ui := new(UutInfo)
|
||||||
|
partNO := ""
|
||||||
|
mfgMO := ""
|
||||||
|
mfgSKU := ""
|
||||||
|
fstAck := ""
|
||||||
|
lstAck := ""
|
||||||
|
|
||||||
|
//Get Last Record
|
||||||
|
last := ""
|
||||||
|
row := 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"]))
|
||||||
|
|
||||||
|
err = row.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,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
last = fmt.Sprintf(`<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>`,
|
||||||
|
ui.USN, ui.MAC, ui.IPAddr, ui.Relay, ui.Item, ui.Status, ui.Message, ui.LastChg)
|
||||||
|
partNO = ui.PartNO
|
||||||
|
mfgMO = ui.MfgMO
|
||||||
|
mfgSKU = ui.MfgSKU
|
||||||
|
fstAck = ui.FirstAck
|
||||||
|
lstAck = ui.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'`, ui.MAC))
|
||||||
|
qry.Scan(&loc, &locTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get History Records
|
||||||
|
bkup := ""
|
||||||
|
rows, 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 usn='%s' ORDER BY seqid ASC;`, params["USN"]))
|
||||||
|
if err == nil {
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.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,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp := fmt.Sprintf(`<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>%s`,
|
||||||
|
ui.USN, ui.MAC, ui.IPAddr, ui.Relay, ui.Item, ui.Status, ui.Message, ui.LastChg, "\r\n")
|
||||||
|
bkup = bkup + temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
//Get Misc. Info
|
||||||
|
if partNO == "" {
|
||||||
|
partNO = ui.PartNO
|
||||||
|
}
|
||||||
|
if mfgMO == "" {
|
||||||
|
mfgMO = ui.MfgMO
|
||||||
|
}
|
||||||
|
if mfgSKU == "" {
|
||||||
|
mfgSKU = ui.MfgSKU
|
||||||
|
}
|
||||||
|
if fstAck == "" {
|
||||||
|
fstAck = ui.FirstAck
|
||||||
|
}
|
||||||
|
if lstAck == "" {
|
||||||
|
lstAck = ui.LastAck
|
||||||
|
}
|
||||||
|
|
||||||
|
misc := ""
|
||||||
|
misc = fmt.Sprintf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
|
||||||
|
partNO, mfgMO, mfgSKU, fstAck, lstAck)
|
||||||
|
|
||||||
|
rst["RESULT"] = "OK"
|
||||||
|
rst["ErrMsg"] = e.TemplateHTML(loc, locTime, misc, last, bkup)
|
||||||
|
if cfg.Settings.LogResponse {
|
||||||
|
logger.Printf("[MSG] %s; %s; Response: Length=%s\r\n", addr, uri, rst["RESULT"])
|
||||||
|
}
|
||||||
|
return rst
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EWS) SimpleMsgHTML(clr, msg string) string {
|
||||||
|
resp := fmt.Sprintf(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<head>
|
||||||
|
<style>pre {word-wrap: break-word;}</style>
|
||||||
|
<style>body {font-family: Calibri; font-size: 14px;}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<br/><span style="color: %s;">%s</span><br/>
|
||||||
|
</body>
|
||||||
|
</html>`, clr, msg)
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EWS) TemplateHTML(loc, locTime, misc, last, bkup string) string {
|
||||||
|
if loc == "" {
|
||||||
|
loc = `<span style="color: red; font-size: 14px; font-family: Consolas;">Unknown</span>`
|
||||||
|
}
|
||||||
|
|
||||||
|
if misc == "" {
|
||||||
|
misc = `<span style="color: red;">NO Records !</span>`
|
||||||
|
}
|
||||||
|
|
||||||
|
if bkup == "" {
|
||||||
|
bkup = `<span style="color: red;">NO Records !</span>`
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := fmt.Sprintf(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>Test Records</title>
|
||||||
|
<style type="text/css">
|
||||||
|
table {
|
||||||
|
border: 1px solid rgb(81, 130, 187);
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 0px;
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: rgb(81, 130, 187);
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid rgb(81, 130, 187);
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Verdana;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
border: 1px solid rgb(81, 130, 187);
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
color: #000;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Consolas;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Consolas;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<span style="font-weight: bold; font-size: 16px;">Location Info</span>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Location</th>
|
||||||
|
<th>Location Time</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>%s</td>
|
||||||
|
<td>%s</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<span style="font-weight: bold; font-size: 16px;">Misc. Info</span>
|
||||||
|
<br/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Part NO.</th>
|
||||||
|
<th>MO</th>
|
||||||
|
<th>SKU</th>
|
||||||
|
<th>First Ack</th>
|
||||||
|
<th>Last Ack</th>
|
||||||
|
</tr>
|
||||||
|
%s
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<span style="font-weight: bold; font-size: 16px;">测试记录</span>
|
||||||
|
<br/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>USN</th>
|
||||||
|
<th>MAC</th>
|
||||||
|
<th>IP Address</th>
|
||||||
|
<th>Server</th>
|
||||||
|
<th>Test Item</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Message</th>
|
||||||
|
<th>Last Change</th>
|
||||||
|
</tr>
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>`, loc, locTime, misc, bkup, last)
|
||||||
|
return resp
|
||||||
|
}
|
17
go.mod
Normal file
17
go.mod
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module APIServer
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/chai2010/winsvc v0.0.0-20230626053835-2858f12dbb33
|
||||||
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||||
|
github.com/satori/go.uuid v1.2.0
|
||||||
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||||
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
|
)
|
18
go.sum
Normal file
18
go.sum
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||||
|
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
github.com/chai2010/winsvc v0.0.0-20230626053835-2858f12dbb33 h1:xcs7ZpTuGng3AoeBS4aoMX0Ba+btfFE+dQTcqisO1vw=
|
||||||
|
github.com/chai2010/winsvc v0.0.0-20230626053835-2858f12dbb33/go.mod h1:b9Xy0A0C/binZARjeVfHEr+gHzQUVztL71bTms7PRIM=
|
||||||
|
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||||
|
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||||
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
Loading…
x
Reference in New Issue
Block a user