[ADD]first commit
This commit is contained in:
commit
e98c0f3b34
|
@ -0,0 +1,18 @@
|
||||||
|
RUN_MODE = debug
|
||||||
|
|
||||||
|
[app]
|
||||||
|
PAGE_SIZE = 10
|
||||||
|
JWT_SECRET = 23347$040412
|
||||||
|
|
||||||
|
[server]
|
||||||
|
HTTP_PORT = 8001
|
||||||
|
READ_TIMEOUT = 60
|
||||||
|
WRITE_TIMEOUT = 60
|
||||||
|
|
||||||
|
[database]
|
||||||
|
TYPE = mysql
|
||||||
|
USER = root
|
||||||
|
PASSWORD = a19960425
|
||||||
|
HOST = localhost:3306
|
||||||
|
NAME = blog
|
||||||
|
TABLE_PREFIX = blog_
|
|
@ -0,0 +1,40 @@
|
||||||
|
module github.com/go-pripro/shop
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
|
github.com/gin-gonic/gin v1.6.3
|
||||||
|
github.com/go-ini/ini v1.61.0
|
||||||
|
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.4.2 // indirect
|
||||||
|
github.com/jinzhu/gorm v1.9.16
|
||||||
|
github.com/json-iterator/go v1.1.10 // indirect
|
||||||
|
github.com/lib/pq v1.2.0 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
|
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
|
||||||
|
github.com/ugorji/go v1.1.8 // indirect
|
||||||
|
github.com/unknwon/com v1.0.1
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
|
gopkg.in/ini.v1 v1.61.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace (
|
||||||
|
github.com/go-pripro/shop/conf => ./shop/pkg/conf
|
||||||
|
github.com/go-pripro/shop/docs => ./shop/docs
|
||||||
|
github.com/go-pripro/shop/middleware => ./shop/middleware
|
||||||
|
github.com/go-pripro/shop/models => ./shop/models
|
||||||
|
github.com/go-pripro/shop/pkg/e => ./shop/pkg/e
|
||||||
|
github.com/go-pripro/shop/pkg/logging => ./shop/pkg/logging
|
||||||
|
github.com/go-pripro/shop/pkg/setting => ./shop/pkg/setting
|
||||||
|
github.com/go-pripro/shop/pkg/util => ./shop/pkg/util
|
||||||
|
github.com/go-pripro/shop/routers => ./shop/routers
|
||||||
|
)
|
|
@ -0,0 +1,22 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-pripro/shop/pkg/setting"
|
||||||
|
"github.com/go-pripro/shop/routers"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
router := routers.InitRouter()
|
||||||
|
|
||||||
|
s := &http.Server{
|
||||||
|
Addr: fmt.Sprintf(":%d", setting.HTTPPort),
|
||||||
|
Handler: router,
|
||||||
|
ReadTimeout: setting.ReadTimeout,
|
||||||
|
WriteTimeout: setting.WriteTimeout,
|
||||||
|
MaxHeaderBytes: 1 << 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ListenAndServe()
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-pripro/shop/pkg/e"
|
||||||
|
"github.com/go-pripro/shop/pkg/util"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func JWT() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
var code int
|
||||||
|
var data interface{}
|
||||||
|
code = e.SUCCESS
|
||||||
|
token := c.Query("token")
|
||||||
|
if token == "" {
|
||||||
|
code = e.INVALID_PARAMS
|
||||||
|
} else {
|
||||||
|
claims, err := util.ParseToken(token)
|
||||||
|
if err != nil {
|
||||||
|
code = e.ERROR_AUTH_CHECK_TOKEN_FAIL
|
||||||
|
} else if time.Now().Unix() > claims.ExpiresAt {
|
||||||
|
code = e.ERROR_AUTH_CHECK_TOKEN_TIMEOUT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if code != e.SUCCESS {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{
|
||||||
|
"code" : code,
|
||||||
|
"msg" : e.GetMsg(code),
|
||||||
|
"data" : data,
|
||||||
|
})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-pripro/shop/pkg/setting"
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var db *gorm.DB
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
ID int `gorm:"primary_key" json:"id"`
|
||||||
|
CreatedOn int `json:"created_on"`
|
||||||
|
ModifiedOn int `json:"modified_on"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
dbType, dbName, user, password, host, tablePrefix string
|
||||||
|
)
|
||||||
|
|
||||||
|
sec, err := setting.Cfg.GetSection("database")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(2, "Fail to get section 'database': %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbType = sec.Key("TYPE").String()
|
||||||
|
dbName = sec.Key("NAME").String()
|
||||||
|
user = sec.Key("USER").String()
|
||||||
|
password = sec.Key("PASSWORD").String()
|
||||||
|
host = sec.Key("HOST").String()
|
||||||
|
tablePrefix = sec.Key("TABLE_PREFIX").String()
|
||||||
|
|
||||||
|
db, err = gorm.Open(dbType, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
|
||||||
|
user,
|
||||||
|
password,
|
||||||
|
host,
|
||||||
|
dbName))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
|
||||||
|
return tablePrefix + defaultTableName
|
||||||
|
}
|
||||||
|
|
||||||
|
//db.AutoMigrate(&Tag{}, &Article{}, &Auth{})
|
||||||
|
//db.SingularTable(true)
|
||||||
|
db.LogMode(true)
|
||||||
|
db.DB().SetMaxIdleConns(10)
|
||||||
|
db.DB().SetMaxOpenConns(100)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloseDB() {
|
||||||
|
defer db.Close()
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package e
|
||||||
|
|
||||||
|
const (
|
||||||
|
SUCCESS = 200
|
||||||
|
ERROR = 500
|
||||||
|
INVALID_PARAMS = 400
|
||||||
|
|
||||||
|
ERROR_EXIST_TAG = 10001
|
||||||
|
ERROR_NOT_EXIST_TAG = 10002
|
||||||
|
ERROR_NOT_EXIST_ARTICLE = 10003
|
||||||
|
|
||||||
|
ERROR_AUTH_CHECK_TOKEN_FAIL = 20001
|
||||||
|
ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002
|
||||||
|
ERROR_AUTH_TOKEN = 20003
|
||||||
|
ERROR_AUTH = 20004
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
package e
|
||||||
|
|
||||||
|
var MsgFlags = map[int]string{
|
||||||
|
SUCCESS: "ok",
|
||||||
|
ERROR: "fail",
|
||||||
|
INVALID_PARAMS: "请求参数错误",
|
||||||
|
ERROR_EXIST_TAG: "已存在该标签名称",
|
||||||
|
ERROR_NOT_EXIST_TAG: "该标签不存在",
|
||||||
|
ERROR_NOT_EXIST_ARTICLE: "该文章不存在",
|
||||||
|
ERROR_AUTH_CHECK_TOKEN_FAIL: "TOKEN鉴权失败",
|
||||||
|
ERROR_AUTH_CHECK_TOKEN_TIMEOUT: "TOKEN已超时",
|
||||||
|
ERROR_AUTH_TOKEN: "TOKEN生成失败",
|
||||||
|
ERROR_AUTH: "TOKEN错误",
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMsg(code int) string {
|
||||||
|
msg, ok := MsgFlags[code]
|
||||||
|
if ok {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
return MsgFlags[ERROR]
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
LogSavePath = "runtime/logs/"
|
||||||
|
LogSaveName = "log"
|
||||||
|
LogFileExt = "log"
|
||||||
|
TimeFormat = "20060102"
|
||||||
|
)
|
||||||
|
func getLogFilePath() string {
|
||||||
|
return fmt.Sprintf("%s", LogSavePath)
|
||||||
|
}
|
||||||
|
func getLogFileFullPath() string {
|
||||||
|
prefixPath := getLogFilePath()
|
||||||
|
suffixPath := fmt.Sprintf("%s%s.%s", LogSaveName, time.Now().Format(TimeFormat), LogFileExt)
|
||||||
|
return fmt.Sprintf("%s%s", prefixPath, suffixPath)
|
||||||
|
}
|
||||||
|
func openLogFile(filePath string) *os.File {
|
||||||
|
_, err := os.Stat(filePath)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
mkDir()
|
||||||
|
case os.IsPermission(err):
|
||||||
|
log.Fatalf("Permission :%v", err)
|
||||||
|
}
|
||||||
|
handle, err := os.OpenFile(filePath, os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to OpenFile :%v", err)
|
||||||
|
}
|
||||||
|
return handle
|
||||||
|
}
|
||||||
|
func mkDir() {
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
err := os.MkdirAll(dir + "/" + getLogFilePath(), os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Level int
|
||||||
|
|
||||||
|
var (
|
||||||
|
F *os.File
|
||||||
|
DefaultPrefix = ""
|
||||||
|
DefaultCallerDepth = 2
|
||||||
|
logger *log.Logger
|
||||||
|
logPrefix = ""
|
||||||
|
levelFlags = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEBUG Level = iota
|
||||||
|
INFO
|
||||||
|
WARNING
|
||||||
|
ERROR
|
||||||
|
FATAL
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
filePath := getLogFileFullPath()
|
||||||
|
F = openLogFile(filePath)
|
||||||
|
logger = log.New(F, DefaultPrefix, log.LstdFlags)
|
||||||
|
}
|
||||||
|
func Debug(v ...interface{}) {
|
||||||
|
setPrefix(DEBUG)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
func Info(v ...interface{}) {
|
||||||
|
setPrefix(INFO)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
func Warn(v ...interface{}) {
|
||||||
|
setPrefix(WARNING)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
func Error(v ...interface{}) {
|
||||||
|
setPrefix(ERROR)
|
||||||
|
logger.Println(v)
|
||||||
|
}
|
||||||
|
func Fatal(v ...interface{}) {
|
||||||
|
setPrefix(FATAL)
|
||||||
|
logger.Fatalln(v)
|
||||||
|
}
|
||||||
|
func setPrefix(level Level) {
|
||||||
|
_, file, line, ok := runtime.Caller(DefaultCallerDepth)
|
||||||
|
if ok {
|
||||||
|
logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
|
||||||
|
} else {
|
||||||
|
logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
|
||||||
|
}
|
||||||
|
logger.SetPrefix(logPrefix)
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package setting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-ini/ini"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Cfg *ini.File
|
||||||
|
var (
|
||||||
|
RunMode string
|
||||||
|
HTTPPort int
|
||||||
|
ReadTimeout time.Duration
|
||||||
|
WriteTimeout time.Duration
|
||||||
|
PageSize int
|
||||||
|
JwtSecret string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
Cfg, err = ini.Load("conf/app.ini")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to parse 'conf/app.ini': %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadBase()
|
||||||
|
LoadServer()
|
||||||
|
LoadApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadBase() {
|
||||||
|
RunMode = Cfg.Section("").Key("RUN_MODE").MustString("debug")
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadServer() {
|
||||||
|
sec, err := Cfg.GetSection("server")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to get section 'sever' : %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTPPort = sec.Key("HTTP_PORT").MustInt(8000)
|
||||||
|
ReadTimeout = time.Duration(sec.Key("READ_TIMEOUT").MustUint(60)) * time.Second
|
||||||
|
WriteTimeout = time.Duration(sec.Key("WRITE_TIMEOUT").MustInt(60)) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadApp() {
|
||||||
|
sec, err := Cfg.GetSection("app")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to get section 'app':%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
JwtSecret = sec.Key("JWT_SECRET").MustString("!@#!@#!@#!@@#!@#")
|
||||||
|
PageSize = sec.Key("PAGE_SIZE").MustInt(10)
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
"github.com/go-pripro/shop/pkg/setting"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var jwtSecret = []byte(setting.JwtSecret)
|
||||||
|
|
||||||
|
type Claims struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
jwt.StandardClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateToken(username, password string) (string, error) {
|
||||||
|
nowTime := time.Now()
|
||||||
|
expireTime := nowTime.Add(3 * time.Hour)
|
||||||
|
|
||||||
|
claims := Claims{
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
jwt.StandardClaims{
|
||||||
|
ExpiresAt: expireTime.Unix(),
|
||||||
|
Issuer: "gin-blog",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
token, err := tokenClaims.SignedString(jwtSecret)
|
||||||
|
|
||||||
|
return token, err
|
||||||
|
}
|
||||||
|
func ParseToken(token string) (*Claims, error) {
|
||||||
|
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return jwtSecret, nil
|
||||||
|
})
|
||||||
|
if tokenClaims != nil {
|
||||||
|
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-pripro/shop/pkg/setting"
|
||||||
|
"github.com/unknwon/com"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPage(c *gin.Context) int {
|
||||||
|
result := 0
|
||||||
|
page, _ := com.StrTo(c.Query("page")).Int()
|
||||||
|
if page > 0 {
|
||||||
|
result = (page - 1) * setting.PageSize
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package routers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-pripro/shop/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitRouter() *gin.Engine {
|
||||||
|
r := gin.New()
|
||||||
|
|
||||||
|
r.Use(gin.Logger())
|
||||||
|
|
||||||
|
r.Use(gin.Recovery())
|
||||||
|
|
||||||
|
gin.SetMode(setting.RunMode)
|
||||||
|
|
||||||
|
r.GET("/ping", func(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"message": "pong",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
r.GET("/test", func(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"message": "test",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
Loading…
Reference in New Issue