go编写简单接口的过程

环境

系统

Windows server 2016 Datacener

go version

go1.13.3 windows/amd64

数据库

Microsoft SQL Server 2014(64位)

基本构成

接口代码使用扩展类库

"crypto/md5"
"encoding/json"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/gin-gonic/gin"
"github.com/go-xorm/xorm"
"github.com/satori/go.uuid"

gin web框架 负责web服务器及路由请求处理
xorm和go-mssqldb 数据库对象orm处理
go.uuid 生成uuid标识

代码

main.go

package main

import (
    "crypto/md5"
    "encoding/json"
    "fmt"
    _ "github.com/denisenkom/go-mssqldb"
    "github.com/gin-gonic/gin"
    "github.com/go-xorm/xorm"
    "github.com/satori/go.uuid"
)

func main() {

    //关闭gin debug
    gin.SetMode(gin.ReleaseMode)
    router := gin.Default()

    //提交生产api
    router.POST("/test", productionOrderHandler)
    //测试api是否正常访问
    router.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })

    router.Run(":8080")
}

/**
获取uuid
*/
func GetUuid() string {
    // or error handling
    val, err := uuid.NewV4()
    if err != nil {
        panic("生成uuid错误:"+err.Error())
    }
    return val.String()
}

/**
md函数
*/
func GetMd5(str string) string {

    hash := md5.New()
    hash.Write([]byte(str))
    result := hash.Sum([]byte(""))
    return fmt.Sprintf("%x",result)
}

/**
提交生产逻辑
*/
func productionOrder(orderNo interface{}, orderMap []interface{}, booksMap []interface{}, engineDb *xorm.Engine) (bool, string) {

    message := "执行成功"
    //事务开启
    session := engineDb.NewSession()
    defer session.Close()
    //4.1 pm_order表
    var orderData pm_order
    for _, item := range orderMap {
        // 类型转换
        orderItem := item.(map[string]interface{})
        orderData.Key_seq = GetUuid()
        //此处隐藏数据结构
        if _, err := engineDb.Insert(orderData); err != nil {
            session.Rollback()
            message = "pm_order添加数据失败:" + err.Error()
            return false, message
        }
    }
    //4.2 pm_order表 PM_OrderStatus表 PM_OrderStatusDetail表
    var bookData pm_books
    var orderStatusData pm_orderstatus
    var orderStatusDetailData pm_orderstatusdetail
    for _, item := range booksMap {
        // 类型转换
        bookItem := item.(map[string]interface{})
        //4.2.1 pm_order数据处理
        bookData.Key_seq = GetUuid()
        //此处隐藏数据结构
        //4.2.2 PM_OrderStatus数据处理
        orderStatusData.Orderno = bookItem["OrderNo"].(string)
        //此处隐藏数据结构
        //4.2.3 PM_OrderStatusDetail表
        orderStatusDetailData.Orderno = bookItem["OrderNo"].(string)
        //此处隐藏数据结构

        if _, err := engineDb.Insert(bookData, orderStatusData, orderStatusDetailData); err != nil {
            session.Rollback()
            message = "pm_books/pm_orderstatus/pm_orderstatusdetail添加数据失败:" + err.Error()
            return false, message
        }
    }

    session.Commit()

    return true, message
}

func productionOrderHandler(c *gin.Context) {
    message := "未知错误"
    //c.Request.ParseForm()
    //for k, v := range c.Request.PostForm {
    //  fmt.Printf("%v=>%v\n", k,v)
    //}
    //c.String(200, message)
    //return

    //验证数据合法性
    orderInfoJson := c.PostForm("OrderInfo")
    if false {
        message = "验证数据合法性失败"
        c.String(200, message)
        return
    }

    //1.获取post数据并解析
    var orderInfo map[string]interface{}
    // 解析字符串为Json
    json.Unmarshal([]byte(orderInfoJson), &orderInfo)
    //转换成map对象
    orderMap := orderInfo["PM_Order"].([]interface{})
    booksMap := orderInfo["PM_Books"].([]interface{})
    if orderMap == nil || booksMap == nil{
        message = "数据json解析失败"
        c.String(200, message)
        return
    }
    var orderNo string
    for _, item := range orderMap {
        // 类型转换
        orderItem := item.(map[string]interface{})
        orderNo = orderItem["OrderNo"].(string)
        if orderNo == "" {
            message = "数据json解析失败:orderno解析失败"
            c.String(200, message)
            return
        }
    }

    //2 建立连接
    var dbConfig = [...]string{
        "127.0.0.1",
        "sa",
        "123456",
        "test",
    }
    //fmt.Println(dbConfig)
    //c.String(200, message)
    //return

    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 = "连接数据库失败"
        c.String(200, message)
        return
    }
    //3 检查订单是否已提交,已提交则返回成功
    has, err := engineDb.SQL("select * from PM_Order where orderNo = ?", orderNo).Exist()
    if err != nil {
        message = "数据查询失败"
        c.String(200, message)
        return
    }
    if has {
        c.String(200, "ok")
        return
    }
    //4.开始提交订单数据
    result, errmsg := productionOrder(orderNo, orderMap, booksMap, engineDb)
    if result == false {
        c.String(200, errmsg)
        return
    }
    c.String(200, "ok")
    return
}

com_model.go

/**
数据库对应的struct
*/
package main
import "time"
//PM_Order表
type pm_order struct {
    Key_seq string
    ...
}
//PM_Books表
type pm_books struct {

    Key_seq string
    Orderno string
    ...

}
//PM_OrderStatus表
type pm_orderstatus struct {
    Orderno string
    ...
    Updatetime time.Time  `xorm:"created"`
}
//PM_OrderStatusDetail表
type pm_orderstatusdetail struct {
    Key_seq string
    ...
    Createtime time.Time `xorm:"created"`
}

可执行文件压缩

使用upx打压缩壳, upx 下载地址 https://upx.github.io/

编译无符号表和调试信息的可执行文件

go build -ldflags "-s -w"

调用upx压缩

upx.exe -9 ginTest.exe

猜你喜欢

转载自www.cnblogs.com/sentangle/p/12170493.html