浏览代码

添加写入数据库功能

k.zhang 4 年之前
父节点
当前提交
6703d7de33
共有 20 个文件被更改,包括 1560 次插入3 次删除
  1. 29 0
      .idea/watcherTasks.xml
  2. 21 1
      apis/dyjx/url_jx.go
  3. 6 0
      conf/conf.ini
  4. 9 0
      conf/conf_master.ini
  5. 9 0
      conf/conf_test.ini
  6. 75 0
      conf/conn_ini_.go
  7. 89 0
      database/mysql.go
  8. 4 0
      go.mod
  9. 25 0
      go.sum
  10. 5 2
      main.go
  11. 52 0
      models/mysql/dysy_url_info.go
  12. 62 0
      tools/aes.go
  13. 68 0
      tools/app/message.go
  14. 73 0
      tools/app/model.go
  15. 72 0
      tools/app/return.go
  16. 36 0
      tools/json.go
  17. 784 0
      tools/jwtauth.go
  18. 17 0
      tools/md5.go
  19. 123 0
      tools/string.go
  20. 1 0
      tools/utils.go

+ 29 - 0
.idea/watcherTasks.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectTasksOptions">
+    <TaskOptions isEnabled="true">
+      <option name="arguments" value="fmt $FilePath$" />
+      <option name="checkSyntaxErrors" value="true" />
+      <option name="description" />
+      <option name="exitCodeBehavior" value="ERROR" />
+      <option name="fileExtension" value="go" />
+      <option name="immediateSync" value="false" />
+      <option name="name" value="go fmt" />
+      <option name="output" value="$FilePath$" />
+      <option name="outputFilters">
+        <array />
+      </option>
+      <option name="outputFromStdout" value="false" />
+      <option name="program" value="$GoExecPath$" />
+      <option name="runOnExternalChanges" value="false" />
+      <option name="scopeName" value="Project Files" />
+      <option name="trackOnlyRoot" value="true" />
+      <option name="workingDir" value="$ProjectFileDir$" />
+      <envs>
+        <env name="GOROOT" value="$GOROOT$" />
+        <env name="GOPATH" value="$GOPATH$" />
+        <env name="PATH" value="$GoBinDirs$" />
+      </envs>
+    </TaskOptions>
+  </component>
+</project>

+ 21 - 1
apis/dyjx/url_jx.go

@@ -3,8 +3,11 @@ package dyjx
 import (
 	"dysy/apis"
 	"dysy/models"
+	"dysy/models/mysql"
+	"dysy/tools"
 	"encoding/json"
 	"errors"
+	"fmt"
 	"github.com/asmcos/requests"
 	"github.com/gin-gonic/gin"
 	"net/http"
@@ -39,6 +42,7 @@ func DouYinUrlJieXi(c *gin.Context) {
 
 func DeWater(in models.DyJieXiInput) (error, models.DyJieXiOutput) {
 	var out models.DyJieXiOutput
+	var dysy mysql.DysyUrlInfo
 	//fmt.Println("test")
 	str := ""
 	baseHost := in.Url
@@ -61,7 +65,7 @@ func DeWater(in models.DyJieXiInput) (error, models.DyJieXiOutput) {
 
 	var inData models.DyJieXi
 	baseHost = "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=" + str[comma+7:pos]
-
+	fmt.Println("baseHost = ", baseHost)
 	req := requests.Requests()
 	resp, err := req.Get(baseHost)
 
@@ -75,6 +79,9 @@ func DeWater(in models.DyJieXiInput) (error, models.DyJieXiOutput) {
 		//fmt.Println()
 	}
 	//fmt.Println(inData)
+
+	//data,_ :=json.Marshal(inData)
+	//fmt.Println(string(data))
 	//视频url
 	var videoUrl = inData.ItemList[0].Video.PlayAddr.URLList[0]
 	//fmt.Println(inData.ItemList[0].Video.PlayAddr.URLList[0])
@@ -98,6 +105,19 @@ func DeWater(in models.DyJieXiInput) (error, models.DyJieXiOutput) {
 	//                dyDto.setDesc(desc);
 	//fmt.Println(inData.ItemList[0].Desc)
 	out.Data.Desc = inData.ItemList[0].Desc
+
+	//数据库创建记录
+	dysy.Desc = out.Data.Desc
+	dysy.VideoPic = out.Data.VideoPic
+	dysy.AudioURL = out.Data.AudioUrl
+	dysy.DouYinShortURL = in.Url
+	dysy.DeWaterVideoURL = out.Data.VideoUrl
+	dysy.DouYinBaseHost = baseHost
+	dysy.Number = 1
+	dysy.UpdateTime = tools.GetCurrntTimeStr()
+	dysy.CreateTime = tools.GetCurrntTimeStr()
+	dysy.Create(dysy.DeWaterVideoURL)
+
 	return nil, out
 
 }

+ 6 - 0
conf/conf.ini

@@ -0,0 +1,6 @@
+[mysql]
+mysql_host = 120.26.195.67
+mysql_name = tao1024_py2
+mysql_password = zhangkun0212a@
+mysql_port = 3306
+mysql_username = pythonweb

+ 9 - 0
conf/conf_master.ini

@@ -0,0 +1,9 @@
+[mysql]
+mysql_host = 39.98.43.138
+mysql_name = zxsm_v1
+mysql_password = ZdgErrx2ehRC0ZCW
+mysql_port = 3306
+mysql_username = u.zxsm.v1
+[ali]
+ali_access_key_id = LTAI4GGbmN7mUFWEgKx6MLux
+ali_access_key_secret = GTQawoUnFeQ2gokB9uy4NtAL3GAwfH

+ 9 - 0
conf/conf_test.ini

@@ -0,0 +1,9 @@
+[mysql]
+mysql_host = 39.98.43.138
+mysql_name = zxsm_v1
+mysql_password = ZdgErrx2ehRC0ZCW
+mysql_port = 3306
+mysql_username = u.zxsm.v1
+[ali]
+ali_access_key_id = LTAI4GGbmN7mUFWEgKx6MLux
+ali_access_key_secret = GTQawoUnFeQ2gokB9uy4NtAL3GAwfH

+ 75 - 0
conf/conn_ini_.go

@@ -0,0 +1,75 @@
+package conf
+
+import (
+	"errors"
+	"github.com/Unknwon/goconfig"
+	"os"
+	"strings"
+)
+
+// 读取配置文件
+var connIni *goconfig.ConfigFile
+var connIniTest = false
+
+func ConnIni() (conf *goconfig.ConfigFile, err error) {
+
+	// 判断是否加载成功过
+
+	if connIniTest == false {
+
+		conf, err = connIniGetPath()
+		if err != nil {
+			return conf, err
+		}
+
+		connIni = conf
+		connIniTest = true
+	}
+
+	return connIni, nil
+}
+
+func connIniGetPath() (conf *goconfig.ConfigFile, err error) {
+
+	// 通过全局变量设置配置文件的名字
+	var confName string
+
+	switch strings.ToLower(os.Getenv("model")) {
+
+	case "develop":
+		confName = "conf.ini"
+		break
+
+	case "master":
+		confName = "conf_master.ini"
+		break
+
+	case "test":
+		confName = "conf_test.ini"
+		break
+
+	default:
+		confName = "conf.ini"
+	}
+
+	// 判断是否加载成功过
+	if connIniTest == false {
+
+		var conFiles = []string{"conf/", "/conf/", "/app/conf/", "../conf/", "../../conf/", "../../../conf/", "../../../../conf/", "../../../../../conf/"}
+
+		for _, aConFile := range conFiles {
+			conn, err := goconfig.LoadConfigFile(aConFile + confName)
+			if err == nil {
+
+				connIniTest = true
+				connIni = conn
+				return connIni, nil
+
+			}
+		}
+
+		return connIni, errors.New("无法找到配置文件")
+	}
+
+	return connIni, nil
+}

+ 89 - 0
database/mysql.go

@@ -0,0 +1,89 @@
+package database
+
+import (
+	"bytes"
+	"fmt"
+	_ "github.com/go-sql-driver/mysql" //加载mysql
+	"github.com/jinzhu/gorm"
+	"log"
+	"dysy/conf"
+	"strconv"
+)
+
+var Eloquent *gorm.DB
+
+var (
+	Host     string
+	Port     int
+	Name     string
+	Username string
+	Password string
+)
+
+func Setup() {
+
+	//加载配置
+	confIni, errConf := conf.ConnIni()
+	if errConf != nil {
+		fmt.Println(errConf)
+	}
+
+	Host = confIni.MustValue("mysql", "mysql_host")
+	Port = confIni.MustInt("mysql", "mysql_port")
+	Name = confIni.MustValue("mysql", "mysql_name")
+	Username = confIni.MustValue("mysql", "mysql_username")
+	Password = confIni.MustValue("mysql", "mysql_password")
+
+	var err error
+
+	conn := GetMysqlConnect()
+
+	log.Println(conn)
+
+	var db Database
+
+	db = new(Mysql)
+	Eloquent, err = db.Open("mysql", conn)
+
+	if err != nil {
+		log.Fatalf("mysql connect error %v", err)
+	} else {
+		log.Printf("mysql connect success!")
+	}
+
+	if Eloquent.Error != nil {
+		log.Fatalf("database error %v", Eloquent.Error)
+	}
+
+	Eloquent.LogMode(true)
+	//McNew()
+
+}
+
+func GetMysqlConnect() string {
+	var conn bytes.Buffer
+	conn.WriteString(Username)
+	conn.WriteString(":")
+	conn.WriteString(Password)
+	conn.WriteString("@tcp(")
+	conn.WriteString(Host)
+	conn.WriteString(":")
+	conn.WriteString(strconv.Itoa(Port))
+	conn.WriteString(")")
+	conn.WriteString("/")
+	conn.WriteString(Name)
+	conn.WriteString("?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms")
+	return conn.String()
+}
+
+type Database interface {
+	Open(dbType string, conn string) (db *gorm.DB, err error)
+}
+
+type Mysql struct {
+}
+
+func (*Mysql) Open(dbType string, conn string) (db *gorm.DB, err error) {
+	eloquent, err := gorm.Open(dbType, conn)
+	return eloquent, err
+}

+ 4 - 0
go.mod

@@ -3,10 +3,14 @@ module dysy
 go 1.14
 
 require (
+	github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8
 	github.com/asmcos/requests v0.0.0-20210118082303-cb8f46dd3767
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/gin-gonic/gin v1.6.3
 	github.com/go-playground/validator/v10 v10.4.1 // indirect
+	github.com/go-sql-driver/mysql v1.5.0
 	github.com/golang/protobuf v1.4.3 // indirect
+	github.com/jinzhu/gorm v1.9.16
 	github.com/json-iterator/go v1.1.10 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

+ 25 - 0
go.sum

@@ -1,13 +1,22 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
+github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8 h1:1TrMV1HmBApBbM+Hy7RCKZD6UlYWYIPPfoeXomG7+zE=
+github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
+github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
 github.com/asmcos/requests v0.0.0-20210118082303-cb8f46dd3767 h1:/2W6hzSR62YUThJdMsKkx4n1kpe05cH8T21Jk0j3msA=
 github.com/asmcos/requests v0.0.0-20210118082303-cb8f46dd3767/go.mod h1:2W5PB6UTVRBypeouEebhwOJrDZOfJvPwMP1mtD8ZXM4=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgrijalva/jwt-go v1.0.2 h1:KPldsxuKGsS2FPWsNeg9ZO18aCrGKujPoWXn2yo+KQM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
@@ -21,6 +30,9 @@ github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1
 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
 github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
 github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -41,6 +53,11 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
+github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
@@ -49,8 +66,10 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
 github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
 github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
 github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -74,6 +93,8 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
 github.com/ugorji/go/codec v1.2.3 h1:/mVYEV+Jo3IZKeA5gBngN0AvNnQltEDkR+eQikkWQu0=
 github.com/ugorji/go/codec v1.2.3/go.mod h1:5FxzDJIgeiWJZslYHPj+LS1dq1ZBQVelZFnjsFGI/Uc=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
@@ -82,11 +103,14 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -97,6 +121,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=

+ 5 - 2
main.go

@@ -1,11 +1,14 @@
 package main
 
 import (
+	"dysy/database"
 	"dysy/routers"
-	"fmt"
 )
 
 func main() {
-	fmt.Println("hello")
+	//fmt.Println("hello")
+	//数据库连接加载
+	database.Setup()
+
 	routers.InitRouter()
 }

+ 52 - 0
models/mysql/dysy_url_info.go

@@ -0,0 +1,52 @@
+package mysql
+
+import (
+	orm "dysy/database"
+	"dysy/tools"
+	"github.com/jinzhu/gorm"
+)
+
+type DysyUrlInfo struct {
+	AudioURL        string `gorm:"column:audio_url" json:"audio_url"`
+	CreateTime      string `gorm:"column:create_time" json:"create_time"`
+	DeWaterVideoURL string `gorm:"column:de_water_video_url" json:"de_water_video_url"`
+	Desc            string `gorm:"column:desc" json:"desc"`
+	DouYinBaseHost  string `gorm:"column:dou_yin_base_host" json:"dou_yin_base_host"`
+	DouYinShortURL  string `gorm:"column:dou_yin_short_url" json:"dou_yin_short_url"`
+	Number          int    `gorm:"column:number" json:"number"`
+	UpdateTime      string `gorm:"column:update_time" json:"update_time"`
+	VideoPic        string `gorm:"column:video_pic" json:"video_pic"`
+}
+
+// TableName sets the insert table name for this struct type
+func (d *DysyUrlInfo) TableName() string {
+	return "dysy_url_info"
+}
+
+func (d *DysyUrlInfo) Create(deWaterVideoUrl string) (DysyUrlInfo, error) {
+	var doc DysyUrlInfo
+	var count = 0
+
+	orm.Eloquent.Where("de_water_video_url = ? ", deWaterVideoUrl).Table(d.TableName()).Count(&count)
+
+	if count != 0 {
+		//更新数字加1
+		//return doc, errors.New(app.ExtOrderIdAgain)
+		if err := orm.Eloquent.Table(d.TableName()).Model(&doc).Where("de_water_video_url = ? ", deWaterVideoUrl).Updates(
+			map[string]interface{}{
+				"number":      gorm.Expr("number + 1"),
+				"update_time": tools.GetCurrntTimeStr()}).Error; err != nil {
+			return doc, err
+		}
+		return doc, nil
+
+	}
+
+	result := orm.Eloquent.Table(d.TableName()).Create(&d)
+	if result.Error != nil {
+		err := result.Error
+		return doc, err
+	}
+	doc = *d
+	return doc, nil
+}

+ 62 - 0
tools/aes.go

@@ -0,0 +1,62 @@
+package tools
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"encoding/base64"
+	"errors"
+)
+
+// AES 加密
+func AesEncrypt(orig string, _Aeskey string) (string, error) {
+
+	origData := []byte(orig)
+	key := []byte(_Aeskey)
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return "", err
+	}
+
+	blockSize := block.BlockSize()
+	origData = func(ciphertext []byte, blockSize int) []byte {
+		padding := blockSize - len(ciphertext)%blockSize
+		padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+		return append(ciphertext, padtext...)
+	}(origData, blockSize)
+	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
+	crypted := make([]byte, len(origData))
+	blockMode.CryptBlocks(crypted, origData)
+	return base64.StdEncoding.EncodeToString(crypted), nil
+}
+
+// AES 解密
+func AesDecrypt(cryted string, _Aeskey string) (string, error) {
+
+	if cryted == "" {
+		return "", errors.New("错误的数据")
+	}
+
+	crypted, err := base64.StdEncoding.DecodeString(cryted)
+	if err != nil {
+		return "", err
+	}
+	key := []byte(_Aeskey)
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		return "", err
+	}
+
+	blockSize := block.BlockSize()
+	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
+	origData := make([]byte, len(crypted))
+	blockMode.CryptBlocks(origData, crypted)
+	origData = func(origData []byte) []byte {
+		length := len(origData)
+		unpadding := int(origData[length-1])
+		return origData[:(length - unpadding)]
+	}(origData)
+	return string(origData[:]), nil
+}

+ 68 - 0
tools/app/message.go

@@ -0,0 +1,68 @@
+package app
+
+const (
+	Success              = "成功" // 200
+	Fail                 = "Fail"
+	ServerError          = "Server Error" //500
+	ClientError          = "Client Error" //400
+	DatabaseError        = "Sql Error"
+	RequestParamError    = "request parameters error"
+	DataBaseError        = "网络异常请稍后重试"
+	InputError           = "参数类型错误或必填参数缺失"
+	UserIdError          = "用户ID不能为空"
+	ShareInfoIdError     = "分享信息ID不能为空"
+	TypeError            = "类型不能为空"
+	UserShareInfoIdError = "分享人ID不能为空"
+	LookTimeError        = "浏览时间不能为空"
+	PushRegisterError    = "推送注册失败"
+	PushNotifySend       = "推送消息失败"
+	MarketingUserAgain   = "该手机号已领取,请在微信小程序中搜索“众信山姆”或扫描下方二维码关注众信山姆小程序查看线路"
+	IdentifyingCodeError = "验证码错误"
+	OverTime             = "验证码超时"
+	MarketingSuccess     = "代金券领取成功,请在微信小程序中搜索“众信山姆”或扫描下方二维码关注众信山姆小程序查看线路。"
+	AliPermits1          = "获取短信频繁,请稍后再试。"
+	MobileAgain          = "此手机号已报名,不能重复报名"
+	IdNumberAgain        = "此身份证号已使用"
+	IdentityAgain        = "一个手机号下只能有一个员工状态"
+	EmployeeAgain        = "此员工已经登记过,不能重复登记。"
+	SignUpAmountError    = "输入单价与数量计算不等于总价"
+	PaymentError         = "发起支付失败"
+	VisitDateAgain       = "日期选择后不允许修改"
+	TicketStockError     = "库存不足"
+	VisitDateRefund      = "已选择日期的订单不允许退款"
+	RefundAgain          = "已申请退款的客户不能重复申请"
+	PayRefundError       = "支付发起退款失败"
+	OrderCancelError     = "只有未支付的订单才可以取消"
+)
+
+//code 标识
+const (
+	CodePaymentError = 501 //支付失败
+
+)
+
+//环球体验票预约订单状态
+const (
+	UbrOrderStatusUnPay       = "1" //未支付
+	UbrOrderStatusPay         = "2" //已支付
+	UbrOrderStatusOrderCancel = "3" //订单取消
+	UbrOrderStatusOrderRefund = "4" //订单退款
+)
+
+//环球影城预约客人信息与游玩日期补充状态
+const (
+	UbrTourVisitStatusUnComplete = "1" //待补充
+	UbrTourVisitStatusComplete   = "2" //信息完整
+)
+
+//环球影城退款状态
+const (
+	UbrRefundUnsubscribeApply        = "1" //退订申请
+	UbrRefundUnsubscribeExamine      = "2" //退订审核
+	UbrRefundUnsubscribeExamineError = "3" //退订审核失败
+	UbrRefundUnsubscribeSuccess      = "4" //退订成功
+	UbrRefundUnsubscribeError        = "5" //退订失败
+	UbrRefunding                     = "6" //退款中
+	UbrRefundSuccess                 = "7" //退款完成
+	UbrRefundError                   = "8" //退款失败
+)

+ 73 - 0
tools/app/model.go

@@ -0,0 +1,73 @@
+package app
+
+type Response struct {
+	ApiBaseOutputHead ApiBaseOutputHead `json:"apiBaseOutputHead"`
+	// 数据集
+	Data interface{} `json:"data"`
+}
+type ApiBaseOutputHead struct {
+	Code string `json:"code" example:"200"`
+	Msg  string `json:"msg"`
+}
+
+type Page struct {
+	List      interface{} `json:"tourList"`
+	Count     int         `json:"count"`
+	PageIndex int         `json:"pageIndex"`
+	PageSize  int         `json:"pageSize"`
+	//BrowseTotal int64       `json:"browseTotal"` //浏览总数
+	//ToGoTotal   int64       `json:"toGoTotal"`   //意向单总数
+
+}
+
+type UserDynamicPage struct {
+	List        interface{} `json:"tourList"`
+	Count       int         `json:"count"`
+	PageIndex   int         `json:"pageIndex"`
+	PageSize    int         `json:"pageSize"`
+	BrowseTotal int64       `json:"browseTotal"` //浏览总数
+	ToGoTotal   int64       `json:"toGoTotal"`   //意向单总数
+
+}
+
+type PageResponse struct {
+	ApiBaseOutputHead ApiBaseOutputHead `json:"apiBaseOutputHead"`
+	//Data              interface{}       `json:"data"`
+	// 代码
+	//Code int `json:"code" example:"200"`
+	// 数据集
+	Data Page `json:"tourData"`
+	// 消息
+	//Msg string `json:"msg"`
+}
+
+type UserDynamicPageResponse struct {
+	ApiBaseOutputHead ApiBaseOutputHead `json:"apiBaseOutputHead"`
+	//Data              interface{}       `json:"data"`
+	// 代码
+	//Code int `json:"code" example:"200"`
+	// 数据集
+	Data UserDynamicPage `json:"tourData"`
+	// 消息
+	//Msg string `json:"msg"`
+}
+
+func (res *Response) ReturnOK() *Response {
+	res.ApiBaseOutputHead.Code = "200"
+	return res
+}
+
+func (res *Response) ReturnError(code string) *Response {
+	res.ApiBaseOutputHead.Code = code
+	return res
+}
+
+func (res *PageResponse) ReturnOK() *PageResponse {
+	res.ApiBaseOutputHead.Code = "200"
+	return res
+}
+
+func (res *UserDynamicPageResponse) ReturnOK() *UserDynamicPageResponse {
+	res.ApiBaseOutputHead.Code = "200"
+	return res
+}

+ 72 - 0
tools/app/return.go

@@ -0,0 +1,72 @@
+package app
+
+import (
+	"github.com/gin-gonic/gin"
+
+	"net/http"
+)
+
+//func SetApiBaseOutputHead(code string, message string) models.ApiBaseOutputHead {
+//	var outData models.ApiBaseOutputHead
+//	outData.Code = code
+//	outData.Message = message
+//	return outData
+//}
+
+// 失败数据处理
+func Error(c *gin.Context, code string, err error, msg string) {
+	var res Response
+	if err != nil {
+		res.ApiBaseOutputHead.Msg = err.Error()
+	} else {
+		if msg != "" {
+			res.ApiBaseOutputHead.Msg = msg
+		}
+	}
+	c.JSON(http.StatusOK, res.ReturnError(code))
+}
+
+// 通常成功数据处理
+func OK(c *gin.Context, data interface{}, msg string) {
+	var res Response
+	res.Data = data
+	if msg != "" {
+		res.ApiBaseOutputHead.Msg = msg
+	}
+	c.JSON(http.StatusOK, res.ReturnOK())
+}
+
+// 分页数据处理
+func PageOK(c *gin.Context, result interface{}, count int, pageIndex int, pageSize int, msg string) {
+	var res PageResponse
+	res.Data.List = result
+	res.Data.Count = count
+	res.Data.PageIndex = pageIndex
+	res.Data.PageSize = pageSize
+
+	if msg != "" {
+		res.ApiBaseOutputHead.Msg = msg
+	}
+	c.JSON(http.StatusOK, res.ReturnOK())
+}
+
+// 分页数据处理
+func PageOKUserDynamic(c *gin.Context, result interface{}, count int, pageIndex int, pageSize int, msg string, browseTotal int64, toGoTotal int64) {
+	var res UserDynamicPageResponse
+	res.Data.List = result
+	res.Data.Count = count
+	res.Data.PageIndex = pageIndex
+	res.Data.PageSize = pageSize
+	res.Data.BrowseTotal = browseTotal
+	res.Data.ToGoTotal = toGoTotal
+
+	if msg != "" {
+		res.ApiBaseOutputHead.Msg = msg
+	}
+	c.JSON(http.StatusOK, res.ReturnOK())
+}
+
+// 兼容函数
+func Custum(c *gin.Context, data gin.H) {
+	c.JSON(http.StatusOK, data)
+}

+ 36 - 0
tools/json.go

@@ -0,0 +1,36 @@
+package tools
+
+import (
+	"encoding/json"
+)
+
+// 获得一个对象的Key,Value值
+func JsonMarshal(v interface{}) (jsonStr string, err error) {
+
+	jsonBytes, err := json.Marshal(v)
+	if err != nil {
+
+		return "", err
+	} else {
+
+		return string(jsonBytes), nil
+	}
+
+}
+
+// 对象转换为Json,并且格式化清晰的样子
+func JsonMarshalFormat(v interface{}) (jsonStr string, err error) {
+
+	jsonBytes, err := json.MarshalIndent(v, "", "    ")
+	if err != nil {
+		return "", err
+	} else {
+		return string(jsonBytes), nil
+	}
+
+}
+
+// JSON反序列化
+func JsonUnmarshal(jsonStr string, v interface{}) error {
+	return json.Unmarshal([]byte(jsonStr), v)
+}

+ 784 - 0
tools/jwtauth.go

@@ -0,0 +1,784 @@
+package tools
+
+import (
+	"crypto/rsa"
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/dgrijalva/jwt-go"
+	"github.com/gin-gonic/gin"
+)
+
+// MapClaims type that uses the map[string]interface{} for JSON decoding
+// This is the default claims type if you don't supply one
+type MapClaims map[string]interface{}
+
+// GinJWTMiddleware provides a Json-Web-Token authentication implementation. On failure, a 401 HTTP response
+// is returned. On success, the wrapped middleware is called, and the userID is made available as
+// c.Get("userID").(string).
+// Users can get a token by posting a json request to LoginHandler. The token then needs to be passed in
+// the Authentication header. Example: Authorization:Bearer XXX_TOKEN_XXX
+type GinJWTMiddleware struct {
+	// Realm name to display to the user. Required.
+	Realm string
+
+	// signing algorithm - possible values are HS256, HS384, HS512, RS256, RS384 or RS512
+	// Optional, default is HS256.
+	SigningAlgorithm string
+
+	// Secret key used for signing. Required.
+	Key []byte
+
+	// Duration that a jwt token is valid. Optional, defaults to one hour.
+	Timeout time.Duration
+
+	// This field allows clients to refresh their token until MaxRefresh has passed.
+	// Note that clients can refresh their token in the last moment of MaxRefresh.
+	// This means that the maximum validity timespan for a token is TokenTime + MaxRefresh.
+	// Optional, defaults to 0 meaning not refreshable.
+	MaxRefresh time.Duration
+
+	// Callback function that should perform the authentication of the user based on login info.
+	// Must return user data as user identifier, it will be stored in Claim Array. Required.
+	// Check error (e) to determine the appropriate error message.
+	Authenticator func(c *gin.Context) (interface{}, error)
+
+	// Callback function that should perform the authorization of the authenticated user. Called
+	// only after an authentication success. Must return true on success, false on failure.
+	// Optional, default to success.
+	Authorizator func(data interface{}, c *gin.Context) bool
+
+	// Callback function that will be called during login.
+	// Using this function it is possible to add additional payload data to the webtoken.
+	// The data is then made available during requests via c.Get("JWT_PAYLOAD").
+	// Note that the payload is not encrypted.
+	// The attributes mentioned on jwt.io can't be used as keys for the map.
+	// Optional, by default no additional data will be set.
+	PayloadFunc func(data interface{}) MapClaims
+
+	// User can define own Unauthorized func.
+	Unauthorized func(*gin.Context, int, string)
+
+	// User can define own LoginResponse func.
+	LoginResponse func(*gin.Context, int, string, time.Time)
+
+	// User can define own LogoutResponse func.
+	LogoutResponse func(*gin.Context, int)
+
+	// User can define own RefreshResponse func.
+	RefreshResponse func(*gin.Context, int, string, time.Time)
+
+	// Set the identity handler function
+	IdentityHandler func(*gin.Context) interface{}
+
+	// Set the identity key
+	IdentityKey string
+
+	// TokenLookup is a string in the form of "<source>:<name>" that is used
+	// to extract token from the request.
+	// Optional. Default value "header:Authorization".
+	// Possible values:
+	// - "header:<name>"
+	// - "query:<name>"
+	// - "cookie:<name>"
+	TokenLookup string
+
+	// TokenHeadName is a string in the header. Default value is "Bearer"
+	TokenHeadName string
+
+	// TimeFunc provides the current time. You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens.
+	TimeFunc func() time.Time
+
+	// HTTP Status messages for when something in the JWT middleware fails.
+	// Check error (e) to determine the appropriate error message.
+	HTTPStatusMessageFunc func(e error, c *gin.Context) string
+
+	// Private key file for asymmetric algorithms
+	PrivKeyFile string
+
+	// Public key file for asymmetric algorithms
+	PubKeyFile string
+
+	// Private key
+	privKey *rsa.PrivateKey
+
+	// Public key
+	pubKey *rsa.PublicKey
+
+	// Optionally return the token as a cookie
+	SendCookie bool
+
+	// Duration that a cookie is valid. Optional, by default equals to Timeout value.
+	CookieMaxAge time.Duration
+
+	// Allow insecure cookies for development over http
+	SecureCookie bool
+
+	// Allow cookies to be accessed client side for development
+	CookieHTTPOnly bool
+
+	// Allow cookie domain change for development
+	CookieDomain string
+
+	// SendAuthorization allow return authorization header for every request
+	SendAuthorization bool
+
+	// Disable abort() of context.
+	DisabledAbort bool
+
+	// CookieName allow cookie name change for development
+	CookieName string
+
+	// CookieSameSite allow use http.SameSite cookie param
+	CookieSameSite http.SameSite
+}
+
+var (
+	// ErrMissingSecretKey indicates Secret key is required
+	ErrMissingSecretKey = errors.New("secret key is required")
+
+	// ErrForbidden when HTTP status 403 is given
+	ErrForbidden = errors.New("you don't have permission to access this resource")
+
+	// ErrMissingAuthenticatorFunc indicates Authenticator is required
+	ErrMissingAuthenticatorFunc = errors.New("ginJWTMiddleware.Authenticator func is undefined")
+
+	// ErrMissingLoginValues indicates a user tried to authenticate without username or password
+	ErrMissingLoginValues = errors.New("missing Username or Password")
+
+	// ErrFailedAuthentication indicates authentication failed, could be faulty username or password
+	ErrFailedAuthentication = errors.New("incorrect Username or Password")
+
+	// ErrFailedTokenCreation indicates JWT Token failed to create, reason unknown
+	ErrFailedTokenCreation = errors.New("failed to create JWT Token")
+
+	// ErrExpiredToken indicates JWT token has expired. Can't refresh.
+	ErrExpiredToken = errors.New("token is expired")
+
+	// ErrEmptyAuthHeader can be thrown if authing with a HTTP header, the Auth header needs to be set
+	ErrEmptyAuthHeader = errors.New("auth header is empty")
+
+	// ErrMissingExpField missing exp field in token
+	ErrMissingExpField = errors.New("missing exp field")
+
+	// ErrWrongFormatOfExp field must be float64 format
+	ErrWrongFormatOfExp = errors.New("exp must be float64 format")
+
+	// ErrInvalidAuthHeader indicates auth header is invalid, could for example have the wrong Realm name
+	ErrInvalidAuthHeader = errors.New("auth header is invalid")
+
+	// ErrEmptyQueryToken can be thrown if authing with URL Query, the query token variable is empty
+	ErrEmptyQueryToken = errors.New("query token is empty")
+
+	// ErrEmptyCookieToken can be thrown if authing with a cookie, the token cookie is empty
+	ErrEmptyCookieToken = errors.New("cookie token is empty")
+
+	// ErrEmptyParamToken can be thrown if authing with parameter in path, the parameter in path is empty
+	ErrEmptyParamToken = errors.New("parameter token is empty")
+
+	// ErrInvalidSigningAlgorithm indicates signing algorithm is invalid, needs to be HS256, HS384, HS512, RS256, RS384 or RS512
+	ErrInvalidSigningAlgorithm = errors.New("invalid signing algorithm")
+
+	// ErrNoPrivKeyFile indicates that the given private key is unreadable
+	ErrNoPrivKeyFile = errors.New("private key file unreadable")
+
+	// ErrNoPubKeyFile indicates that the given public key is unreadable
+	ErrNoPubKeyFile = errors.New("public key file unreadable")
+
+	// ErrInvalidPrivKey indicates that the given private key is invalid
+	ErrInvalidPrivKey = errors.New("private key invalid")
+
+	// ErrInvalidPubKey indicates the the given public key is invalid
+	ErrInvalidPubKey = errors.New("public key invalid")
+
+	// IdentityKey default identity key
+	IdentityKey = "identity"
+
+	//NiceKey = "nice"
+	//
+	//DataScopeKey = "datascope"
+	//
+	//RKey      = "r"
+	//RoleIdKey = "roleid"
+	//
+	//RoleKey = "rolekey"
+	//
+	//RoleNameKey = "rolename"
+)
+
+// New for check error with GinJWTMiddleware
+func New(m *GinJWTMiddleware) (*GinJWTMiddleware, error) {
+	if err := m.MiddlewareInit(); err != nil {
+		return nil, err
+	}
+
+	return m, nil
+}
+
+func (mw *GinJWTMiddleware) readKeys() error {
+	err := mw.privateKey()
+	if err != nil {
+		return err
+	}
+	err = mw.publicKey()
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (mw *GinJWTMiddleware) privateKey() error {
+	keyData, err := ioutil.ReadFile(mw.PrivKeyFile)
+	if err != nil {
+		return ErrNoPrivKeyFile
+	}
+	key, err := jwt.ParseRSAPrivateKeyFromPEM(keyData)
+	if err != nil {
+		return ErrInvalidPrivKey
+	}
+	mw.privKey = key
+	return nil
+}
+
+func (mw *GinJWTMiddleware) publicKey() error {
+	keyData, err := ioutil.ReadFile(mw.PubKeyFile)
+	if err != nil {
+		return ErrNoPubKeyFile
+	}
+	key, err := jwt.ParseRSAPublicKeyFromPEM(keyData)
+	if err != nil {
+		return ErrInvalidPubKey
+	}
+	mw.pubKey = key
+	return nil
+}
+
+func (mw *GinJWTMiddleware) usingPublicKeyAlgo() bool {
+	switch mw.SigningAlgorithm {
+	case "RS256", "RS512", "RS384":
+		return true
+	}
+	return false
+}
+
+// MiddlewareInit initialize jwt configs.
+func (mw *GinJWTMiddleware) MiddlewareInit() error {
+
+	if mw.TokenLookup == "" {
+		mw.TokenLookup = "header:Authorization"
+	}
+
+	if mw.SigningAlgorithm == "" {
+		mw.SigningAlgorithm = "HS256"
+	}
+
+	if mw.Timeout == 0 {
+		mw.Timeout = time.Hour
+	}
+
+	if mw.TimeFunc == nil {
+		mw.TimeFunc = time.Now
+	}
+
+	mw.TokenHeadName = strings.TrimSpace(mw.TokenHeadName)
+	if len(mw.TokenHeadName) == 0 {
+		mw.TokenHeadName = "Bearer"
+	}
+
+	if mw.Authorizator == nil {
+		mw.Authorizator = func(data interface{}, c *gin.Context) bool {
+			return true
+		}
+	}
+
+	if mw.Unauthorized == nil {
+		mw.Unauthorized = func(c *gin.Context, code int, message string) {
+			c.JSON(code, gin.H{
+				"code":    code,
+				"message": message,
+			})
+		}
+	}
+
+	if mw.LoginResponse == nil {
+		mw.LoginResponse = func(c *gin.Context, code int, token string, expire time.Time) {
+			c.JSON(http.StatusOK, gin.H{
+				"code":   http.StatusOK,
+				"token":  token,
+				"expire": expire.Format(time.RFC3339),
+			})
+		}
+	}
+
+	if mw.LogoutResponse == nil {
+		mw.LogoutResponse = func(c *gin.Context, code int) {
+			c.JSON(http.StatusOK, gin.H{
+				"code": http.StatusOK,
+			})
+		}
+	}
+
+	if mw.RefreshResponse == nil {
+		mw.RefreshResponse = func(c *gin.Context, code int, token string, expire time.Time) {
+			c.JSON(http.StatusOK, gin.H{
+				"code":   http.StatusOK,
+				"token":  token,
+				"expire": expire.Format(time.RFC3339),
+			})
+		}
+	}
+
+	if mw.IdentityKey == "" {
+		mw.IdentityKey = IdentityKey
+	}
+
+	if mw.IdentityHandler == nil {
+		mw.IdentityHandler = func(c *gin.Context) interface{} {
+			claims := ExtractClaims(c)
+			return claims[mw.IdentityKey]
+		}
+	}
+
+	if mw.HTTPStatusMessageFunc == nil {
+		mw.HTTPStatusMessageFunc = func(e error, c *gin.Context) string {
+			return e.Error()
+		}
+	}
+
+	if mw.Realm == "" {
+		mw.Realm = "gin jwt"
+	}
+
+	if mw.CookieMaxAge == 0 {
+		mw.CookieMaxAge = mw.Timeout
+	}
+
+	if mw.CookieName == "" {
+		mw.CookieName = "jwt"
+	}
+
+	if mw.usingPublicKeyAlgo() {
+		return mw.readKeys()
+	}
+
+	if mw.Key == nil {
+		return ErrMissingSecretKey
+	}
+	return nil
+}
+
+// MiddlewareFunc makes GinJWTMiddleware implement the Middleware interface.
+func (mw *GinJWTMiddleware) MiddlewareFunc() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		mw.middlewareImpl(c)
+	}
+}
+
+func (mw *GinJWTMiddleware) middlewareImpl(c *gin.Context) {
+	claims, err := mw.GetClaimsFromJWT(c)
+	if err != nil {
+		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(err, c))
+		return
+	}
+
+	if claims["exp"] == nil {
+		mw.unauthorized(c, http.StatusBadRequest, mw.HTTPStatusMessageFunc(ErrMissingExpField, c))
+		return
+	}
+
+	if _, ok := claims["exp"].(float64); !ok {
+		mw.unauthorized(c, http.StatusBadRequest, mw.HTTPStatusMessageFunc(ErrWrongFormatOfExp, c))
+		return
+	}
+
+	if int64(claims["exp"].(float64)) < mw.TimeFunc().Unix() {
+		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(ErrExpiredToken, c))
+		return
+	}
+
+	c.Set("JWT_PAYLOAD", claims)
+	identity := mw.IdentityHandler(c)
+
+	if identity != nil {
+		c.Set(mw.IdentityKey, identity)
+	}
+
+	if !mw.Authorizator(identity, c) {
+		mw.unauthorized(c, http.StatusForbidden, mw.HTTPStatusMessageFunc(ErrForbidden, c))
+		return
+	}
+
+	c.Next()
+}
+
+// GetClaimsFromJWT get claims from JWT token
+func (mw *GinJWTMiddleware) GetClaimsFromJWT(c *gin.Context) (MapClaims, error) {
+	token, err := mw.ParseToken(c)
+
+	if err != nil {
+		return nil, err
+	}
+
+	if mw.SendAuthorization {
+		if v, ok := c.Get("JWT_TOKEN"); ok {
+			c.Header("Authorization", mw.TokenHeadName+" "+v.(string))
+		}
+	}
+
+	claims := MapClaims{}
+	for key, value := range token.Claims.(jwt.MapClaims) {
+		claims[key] = value
+	}
+
+	return claims, nil
+}
+
+// LoginHandler can be used by clients to get a jwt token.
+// Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
+// Reply will be of the form {"token": "TOKEN"}.
+func (mw *GinJWTMiddleware) LoginHandler(c *gin.Context) {
+	if mw.Authenticator == nil {
+		mw.unauthorized(c, http.StatusInternalServerError, mw.HTTPStatusMessageFunc(ErrMissingAuthenticatorFunc, c))
+		return
+	}
+
+	data, err := mw.Authenticator(c)
+
+	if err != nil {
+		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(err, c))
+		return
+	}
+
+	// Create the token
+	token := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm))
+	claims := token.Claims.(jwt.MapClaims)
+
+	if mw.PayloadFunc != nil {
+		for key, value := range mw.PayloadFunc(data) {
+			claims[key] = value
+		}
+	}
+
+	expire := mw.TimeFunc().Add(mw.Timeout)
+	claims["exp"] = expire.Unix()
+	claims["orig_iat"] = mw.TimeFunc().Unix()
+	tokenString, err := mw.signedString(token)
+
+	if err != nil {
+		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(ErrFailedTokenCreation, c))
+		return
+	}
+
+	// set cookie
+	if mw.SendCookie {
+		expireCookie := mw.TimeFunc().Add(mw.CookieMaxAge)
+		maxage := int(expireCookie.Unix() - mw.TimeFunc().Unix())
+
+		if mw.CookieSameSite != 0 {
+			c.SetSameSite(mw.CookieSameSite)
+		}
+
+		c.SetCookie(
+			mw.CookieName,
+			tokenString,
+			maxage,
+			"/",
+			mw.CookieDomain,
+			mw.SecureCookie,
+			mw.CookieHTTPOnly,
+		)
+	}
+
+	mw.LoginResponse(c, http.StatusOK, tokenString, expire)
+}
+
+// LogoutHandler can be used by clients to remove the jwt cookie (if set)
+func (mw *GinJWTMiddleware) LogoutHandler(c *gin.Context) {
+	// delete auth cookie
+	if mw.SendCookie {
+		if mw.CookieSameSite != 0 {
+			c.SetSameSite(mw.CookieSameSite)
+		}
+
+		c.SetCookie(
+			mw.CookieName,
+			"",
+			-1,
+			"/",
+			mw.CookieDomain,
+			mw.SecureCookie,
+			mw.CookieHTTPOnly,
+		)
+	}
+
+	mw.LogoutResponse(c, http.StatusOK)
+}
+
+func (mw *GinJWTMiddleware) signedString(token *jwt.Token) (string, error) {
+	var tokenString string
+	var err error
+	if mw.usingPublicKeyAlgo() {
+		tokenString, err = token.SignedString(mw.privKey)
+	} else {
+		tokenString, err = token.SignedString(mw.Key)
+	}
+	return tokenString, err
+}
+
+// RefreshHandler can be used to refresh a token. The token still needs to be valid on refresh.
+// Shall be put under an endpoint that is using the GinJWTMiddleware.
+// Reply will be of the form {"token": "TOKEN"}.
+func (mw *GinJWTMiddleware) RefreshHandler(c *gin.Context) {
+	tokenString, expire, err := mw.RefreshToken(c)
+	if err != nil {
+		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(err, c))
+		return
+	}
+
+	mw.RefreshResponse(c, http.StatusOK, tokenString, expire)
+}
+
+// RefreshToken refresh token and check if token is expired
+func (mw *GinJWTMiddleware) RefreshToken(c *gin.Context) (string, time.Time, error) {
+	claims, err := mw.CheckIfTokenExpire(c)
+	if err != nil {
+		return "", time.Now(), err
+	}
+
+	// Create the token
+	newToken := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm))
+	newClaims := newToken.Claims.(jwt.MapClaims)
+
+	for key := range claims {
+		newClaims[key] = claims[key]
+	}
+
+	expire := mw.TimeFunc().Add(mw.Timeout)
+	newClaims["exp"] = expire.Unix()
+	newClaims["orig_iat"] = mw.TimeFunc().Unix()
+	tokenString, err := mw.signedString(newToken)
+
+	if err != nil {
+		return "", time.Now(), err
+	}
+
+	// set cookie
+	if mw.SendCookie {
+		expireCookie := mw.TimeFunc().Add(mw.CookieMaxAge)
+		maxage := int(expireCookie.Unix() - time.Now().Unix())
+
+		if mw.CookieSameSite != 0 {
+			c.SetSameSite(mw.CookieSameSite)
+		}
+
+		c.SetCookie(
+			mw.CookieName,
+			tokenString,
+			maxage,
+			"/",
+			mw.CookieDomain,
+			mw.SecureCookie,
+			mw.CookieHTTPOnly,
+		)
+	}
+
+	return tokenString, expire, nil
+}
+
+// CheckIfTokenExpire check if token expire
+func (mw *GinJWTMiddleware) CheckIfTokenExpire(c *gin.Context) (jwt.MapClaims, error) {
+	token, err := mw.ParseToken(c)
+
+	if err != nil {
+		// If we receive an error, and the error is anything other than a single
+		// ValidationErrorExpired, we want to return the error.
+		// If the error is just ValidationErrorExpired, we want to continue, as we can still
+		// refresh the token if it's within the MaxRefresh time.
+		// (see https://github.com/appleboy/gin-jwt/issues/176)
+		validationErr, ok := err.(*jwt.ValidationError)
+		if !ok || validationErr.Errors != jwt.ValidationErrorExpired {
+			return nil, err
+		}
+	}
+
+	claims := token.Claims.(jwt.MapClaims)
+
+	origIat := int64(claims["orig_iat"].(float64))
+
+	if origIat < mw.TimeFunc().Add(-mw.MaxRefresh).Unix() {
+		return nil, ErrExpiredToken
+	}
+
+	return claims, nil
+}
+
+// TokenGenerator method that clients can use to get a jwt token.
+func (mw *GinJWTMiddleware) TokenGenerator(data interface{}) (string, time.Time, error) {
+	token := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm))
+	claims := token.Claims.(jwt.MapClaims)
+
+	if mw.PayloadFunc != nil {
+		for key, value := range mw.PayloadFunc(data) {
+			claims[key] = value
+		}
+	}
+
+	expire := mw.TimeFunc().UTC().Add(mw.Timeout)
+	claims["exp"] = expire.Unix()
+	claims["orig_iat"] = mw.TimeFunc().Unix()
+	tokenString, err := mw.signedString(token)
+	if err != nil {
+		return "", time.Time{}, err
+	}
+
+	return tokenString, expire, nil
+}
+
+func (mw *GinJWTMiddleware) jwtFromHeader(c *gin.Context, key string) (string, error) {
+	authHeader := c.Request.Header.Get(key)
+
+	if authHeader == "" {
+		return "", ErrEmptyAuthHeader
+	}
+
+	parts := strings.SplitN(authHeader, " ", 2)
+	if !(len(parts) == 2 && parts[0] == mw.TokenHeadName) {
+		return "", ErrInvalidAuthHeader
+	}
+
+	return parts[1], nil
+}
+
+func (mw *GinJWTMiddleware) jwtFromQuery(c *gin.Context, key string) (string, error) {
+	token := c.Query(key)
+
+	if token == "" {
+		return "", ErrEmptyQueryToken
+	}
+
+	return token, nil
+}
+
+func (mw *GinJWTMiddleware) jwtFromCookie(c *gin.Context, key string) (string, error) {
+	cookie, _ := c.Cookie(key)
+
+	if cookie == "" {
+		return "", ErrEmptyCookieToken
+	}
+
+	return cookie, nil
+}
+
+func (mw *GinJWTMiddleware) jwtFromParam(c *gin.Context, key string) (string, error) {
+	token := c.Param(key)
+
+	if token == "" {
+		return "", ErrEmptyParamToken
+	}
+
+	return token, nil
+}
+
+// ParseToken parse jwt token from gin context
+func (mw *GinJWTMiddleware) ParseToken(c *gin.Context) (*jwt.Token, error) {
+	var token string
+	var err error
+
+	methods := strings.Split(mw.TokenLookup, ",")
+	for _, method := range methods {
+		if len(token) > 0 {
+			break
+		}
+		parts := strings.Split(strings.TrimSpace(method), ":")
+		k := strings.TrimSpace(parts[0])
+		v := strings.TrimSpace(parts[1])
+		switch k {
+		case "header":
+			token, err = mw.jwtFromHeader(c, v)
+		case "query":
+			token, err = mw.jwtFromQuery(c, v)
+		case "cookie":
+			token, err = mw.jwtFromCookie(c, v)
+		case "param":
+			token, err = mw.jwtFromParam(c, v)
+		}
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	return jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
+		if jwt.GetSigningMethod(mw.SigningAlgorithm) != t.Method {
+			return nil, ErrInvalidSigningAlgorithm
+		}
+		if mw.usingPublicKeyAlgo() {
+			return mw.pubKey, nil
+		}
+
+		// save token string if vaild
+		c.Set("JWT_TOKEN", token)
+
+		return mw.Key, nil
+	})
+}
+
+// ParseTokenString parse jwt token string
+func (mw *GinJWTMiddleware) ParseTokenString(token string) (*jwt.Token, error) {
+	return jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
+		if jwt.GetSigningMethod(mw.SigningAlgorithm) != t.Method {
+			return nil, ErrInvalidSigningAlgorithm
+		}
+		if mw.usingPublicKeyAlgo() {
+			return mw.pubKey, nil
+		}
+
+		return mw.Key, nil
+	})
+}
+
+func (mw *GinJWTMiddleware) unauthorized(c *gin.Context, code int, message string) {
+	c.Header("WWW-Authenticate", "JWT realm="+mw.Realm)
+	if !mw.DisabledAbort {
+		c.Abort()
+	}
+
+	mw.Unauthorized(c, code, message)
+}
+
+// ExtractClaims help to extract the JWT claims
+func ExtractClaims(c *gin.Context) MapClaims {
+	claims, exists := c.Get("JWT_PAYLOAD")
+	if !exists {
+		return make(MapClaims)
+	}
+
+	return claims.(MapClaims)
+}
+
+// ExtractClaimsFromToken help to extract the JWT claims from token
+func ExtractClaimsFromToken(token *jwt.Token) MapClaims {
+	if token == nil {
+		return make(MapClaims)
+	}
+
+	claims := MapClaims{}
+	for key, value := range token.Claims.(jwt.MapClaims) {
+		claims[key] = value
+	}
+
+	return claims
+}
+
+// GetToken help to get the JWT token string
+func GetToken(c *gin.Context) string {
+	token, exists := c.Get("JWT_TOKEN")
+	if !exists {
+		return ""
+	}
+
+	return token.(string)
+}

+ 17 - 0
tools/md5.go

@@ -0,0 +1,17 @@
+package tools
+
+import (
+	"crypto/md5"
+	"fmt"
+	"io"
+	"strings"
+)
+
+// Aes加密
+func MD5(sourceValue string) string {
+	w := md5.New()
+	io.WriteString(w, sourceValue)
+	newMD5 := fmt.Sprintf("%x", w.Sum(nil))
+
+	return strings.ToUpper(newMD5)
+}

+ 123 - 0
tools/string.go

@@ -0,0 +1,123 @@
+package tools
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"io/ioutil"
+	"strconv"
+	"time"
+)
+
+func StringToInt64(e string) (int64, error) {
+	return strconv.ParseInt(e, 10, 64)
+}
+
+func StringToInt(e string) (int, error) {
+	return strconv.Atoi(e)
+}
+
+func GetCurrntTimeStr() string {
+
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	//time.Local, _ = time.LoadLocation("Asia/Chongqing")
+	//timelocal := time.LoadLocation("Asia/Chongqing")
+	//time.Local = timelocal
+	//time.LoadLocation("Asia/Chongqing")
+	//return time.Now().Local().Format("2006-01-02 15:04:05")
+	return time.Now().In(NowTimeZone).Format("2006-01-02 15:04:05")
+}
+
+func GetCurrntTime() time.Time {
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	return time.Now().In(NowTimeZone)
+}
+
+//获取日期
+func GetCurrntDateStr() string {
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	return time.Now().In(NowTimeZone).Format("2006-01-02")
+}
+
+func GetPayRemainingTime(inDate string) int64 {
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	timeLayout := "2006-01-02 15:04:05" //转化所需模板
+
+	stamp, _ := time.ParseInLocation(timeLayout, inDate, time.Local)
+	sr := stamp.Unix()
+	timestamp := time.Now().In(NowTimeZone).Format("2006-01-02 15:04:05")
+	now, _ := time.ParseInLocation(timeLayout, timestamp, time.Local)
+
+	return 900 - (now.Unix() - sr)
+}
+
+func SubTimeSecond(inDate string) int64 {
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	timeLayout := "2006-01-02 15:04:05" //转化所需模板
+
+	stamp, _ := time.ParseInLocation(timeLayout, inDate, time.Local)
+	sr := stamp.Unix()
+	timestamp := time.Now().In(NowTimeZone).Format("2006-01-02 15:04:05")
+	now, _ := time.ParseInLocation(timeLayout, timestamp, time.Local)
+
+	fmt.Println("sr  = ", sr)
+	fmt.Println("now", now.Unix())
+	return now.Unix() - sr
+}
+
+//输入日期减去当前日期
+func InDateSubNow(inDate string) int64 {
+	NowTimeZone := time.FixedZone("CST", 8*3600)
+	timeLayout := "2006-01-02 15:04:05" //转化所需模板
+
+	stamp, _ := time.ParseInLocation(timeLayout, inDate, time.Local)
+	sr := stamp.Unix()
+	timestamp := time.Now().In(NowTimeZone).Format("2006-01-02 15:04:05")
+	now, _ := time.ParseInLocation(timeLayout, timestamp, time.Local)
+
+	return sr - now.Unix()
+}
+
+//func GetCurrntTime() time.Time {
+//	return time.Now()
+//}
+
+func StructToJsonStr(e interface{}) (string, error) {
+	if b, err := json.Marshal(e); err == nil {
+		return string(b), err
+	} else {
+		return "", err
+	}
+}
+
+func GetBodyString(c *gin.Context) (string, error) {
+	body, err := ioutil.ReadAll(c.Request.Body)
+	if err != nil {
+		fmt.Printf("read body err, %v\n", err)
+		return string(body), nil
+	} else {
+		return "", err
+	}
+}
+
+func JsonStrToMap(e string) (map[string]interface{}, error) {
+	var dict map[string]interface{}
+	if err := json.Unmarshal([]byte(e), &dict); err == nil {
+		return dict, err
+	} else {
+		return nil, err
+	}
+}
+
+func StructToMap(data interface{}) (map[string]interface{}, error) {
+	dataBytes, err := json.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+	mapData := make(map[string]interface{})
+	err = json.Unmarshal(dataBytes, &mapData)
+	if err != nil {
+		return nil, err
+	}
+	return mapData, nil
+}

+ 1 - 0
tools/utils.go

@@ -0,0 +1 @@
+package tools