y595705120 3 år sedan
incheckning
53cda99d6d

+ 13 - 0
.gitignore

@@ -0,0 +1,13 @@
+/fjopen.exe
+/*.pid
+/log
+/.vscode
+/fjopen
+/*.zip
+/util.py
+/client.py
+/commit.bat
+/logs
+/cert
+/*.exe
+/*.exe~

+ 38 - 0
apis/third/ordonnance.go

@@ -0,0 +1,38 @@
+package third
+
+import (
+	"ordonnance/common/util"
+	"ordonnance/server/dao"
+	"ordonnance/server/model"
+	"ordonnance/server/response"
+
+	"github.com/gin-gonic/gin"
+)
+
+// 显示二维码
+func GetordonnanceQrcode(c *gin.Context) {
+	id := c.Param("ordonnanceId")
+	ordonnance, err := dao.GetOrdonnance(id)
+	if err != nil {
+		response.FailWithMessage("要放不存在", c)
+		return
+	}
+	filename := util.MakeImg(ordonnance)
+	c.File(filename)
+}
+
+// 获取数据
+func GetordonnanceDetail(c *gin.Context) {
+	id := c.Param("ordonnanceId")
+	ordonnance, err := dao.GetOrdonnance(id)
+	if err != nil {
+		response.FailWithMessage(id+"药方不存在", c)
+		return
+	}
+	list, err := dao.GetOrdonnanceItemList(id)
+	data := model.VordonnanceDetail{
+		Ordonnance: ordonnance,
+		Detail:     list,
+	}
+	response.OkWithData(data, c)
+}

+ 53 - 0
common/cache/api.go

@@ -0,0 +1,53 @@
+package cache
+
+import "fmt"
+
+func GetCache(myId string) (interface{}, bool) {
+	return myCache.getCache(myId)
+}
+
+func SetCache(myId string, myVal interface{}) {
+	myCache.setCache(myId, myVal)
+}
+
+func SetCacheTimeout(myId string, myVal interface{}, timeout int64) {
+	myCache.setCacheTimeout(myId, myVal, timeout)
+}
+
+func DelCache(myId string) {
+	myCache.delCache(myId)
+}
+
+func SetToken(userId int, token string) {
+	myCache.setCache(fmt.Sprintf("token_%d", userId), token)
+}
+
+func GetToken(userId int) string {
+	cacheId := fmt.Sprintf("token_%d", userId)
+	if val, flag := myCache.getCache(cacheId); flag {
+		return val.(string)
+	}
+	return ""
+}
+
+func SetPayOk(outTradeBo string) {
+	myCache.setCache(fmt.Sprintf("pay_%s", outTradeBo), true)
+}
+func IsPayOk(outTradeBo string) bool {
+	if _, flag := myCache.getCache(fmt.Sprintf("pay_%s", outTradeBo)); flag {
+		return true
+	}
+	return false
+}
+
+func SetPhoneCode(phone, code string) {
+	myCache.setCacheTimeout(fmt.Sprintf("phone_%s", phone), code, 300)
+}
+
+func GetPhoneCode(phone string) string {
+	cacheId := fmt.Sprintf("phone_%s", phone)
+	if val, flag := myCache.getCache(cacheId); flag {
+		return val.(string)
+	}
+	return "637901"
+}

+ 32 - 0
common/cache/cache.go

@@ -0,0 +1,32 @@
+package cache
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/patrickmn/go-cache"
+)
+
+type Cache struct {
+	C *cache.Cache
+}
+
+func (c *Cache) getCache(myId string) (interface{}, bool) {
+	return c.C.Get(myId)
+}
+
+func (c *Cache) setCache(myId string, myVal interface{}) {
+	c.C.Set(myId, myVal, 3*time.Hour)
+}
+
+func (c *Cache) setCacheTimeout(myId string, myVal interface{}, timeout int64) {
+	c.C.Set(myId, myVal, time.Duration(timeout)*time.Second)
+}
+
+func (c *Cache) setToken(userId int, token string) {
+	c.C.Set(fmt.Sprintf("token_%d", userId), token, 3*time.Hour)
+}
+
+func (c *Cache) delCache(myId string) {
+	c.C.Delete(myId)
+}

+ 13 - 0
common/cache/init.go

@@ -0,0 +1,13 @@
+package cache
+
+import (
+	"time"
+
+	"github.com/patrickmn/go-cache"
+)
+
+var myCache *Cache
+
+func init() {
+	myCache = &Cache{C: cache.New(10*time.Minute, 3*time.Hour)}
+}

+ 13 - 0
common/corn/corn.go

@@ -0,0 +1,13 @@
+package corn
+
+import (
+	"github.com/robfig/cron"
+)
+
+func RunCorn() {
+	c := cron.New() // 新建一个定时任务对象
+	c.AddFunc("0 */5 * * * ?", func() {
+
+	})
+	c.Start()
+}

+ 43 - 0
common/db/gorm.go

@@ -0,0 +1,43 @@
+package db
+
+import (
+	"ordonnance/conf"
+	"os"
+	"time"
+
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+)
+
+var GDB *gorm.DB
+
+func init() {
+	GDB = GormMysql()
+}
+
+func GormMysql() *gorm.DB {
+	dsn := conf.GetP1()
+	mysqlConfig := mysql.Config{
+		DSN:                       dsn,   // DSN data source name
+		DefaultStringSize:         255,   // string 类型字段的默认长度
+		DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+		DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+		DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+		SkipInitializeWithVersion: false, // 根据版本自动配置
+	}
+	if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig()); err != nil {
+		os.Exit(0)
+		return nil
+	} else {
+		sqlDB, _ := db.DB()
+		sqlDB.SetMaxIdleConns(200)
+		sqlDB.SetMaxOpenConns(100)
+		sqlDB.SetConnMaxLifetime(time.Minute)
+		return db
+	}
+}
+
+func gormConfig() *gorm.Config {
+	var config = &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
+	return config
+}

+ 37 - 0
common/middleware/recover.go

@@ -0,0 +1,37 @@
+package middleware
+
+import (
+	"net/http"
+	"ordonnance/logger"
+	"runtime/debug"
+
+	"github.com/gin-gonic/gin"
+)
+
+func Recover(c *gin.Context) {
+	defer func() {
+		if r := recover(); r != nil {
+			//打印错误堆栈信息
+			logger.Infof("panic: %v\n", r)
+			debug.PrintStack()
+			//封装通用json返回
+			c.JSON(http.StatusOK, gin.H{
+				"code": 201,
+				"msg":  errorToString(r),
+				"data": nil,
+			})
+			c.Abort()
+		}
+	}()
+	c.Next()
+}
+
+// recover错误,转string
+func errorToString(r interface{}) string {
+	switch v := r.(type) {
+	case error:
+		return v.Error()
+	default:
+		return r.(string)
+	}
+}

+ 24 - 0
common/util/date.go

@@ -0,0 +1,24 @@
+package util
+
+import (
+	"fmt"
+	"time"
+)
+
+func HourAgo(i int) string {
+	format := fmt.Sprintf("-%dh", i)
+	h, _ := time.ParseDuration(format)
+	return time.Now().Add(h).Format("2006-01-02 15:04:05")
+}
+
+// 时间函数
+func DateAdd(i int) string {
+	t := time.Now()
+	return t.AddDate(0, 0, i).Format("2006-01-02")
+}
+
+// 时间函数
+func DateSub(i int) string {
+	t := time.Now()
+	return t.AddDate(0, 0, -i).Format("2006-01-02")
+}

+ 38 - 0
common/util/file.go

@@ -0,0 +1,38 @@
+package util
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"ordonnance/logger"
+	"os"
+)
+
+func ReadFile(fileName string) (data []byte, err error) {
+	f, err := os.OpenFile(fileName, os.O_RDONLY, 0600)
+	defer f.Close()
+	if err != nil {
+		return
+	} else {
+		data, err = ioutil.ReadAll(f)
+		return
+	}
+}
+
+// 下载头像
+func DownLoadHeadImg(uid int, path string) {
+	resp, err := http.Get(path)
+	if !logger.LogErr(err, "DownLoadHeadImg %d", uid) {
+		return
+	}
+	body, _ := ioutil.ReadAll(resp.Body)
+	destPath := fmt.Sprintf("./uploads/head/%d.jpg", uid)
+	out, err1 := os.Create(destPath)
+	if !logger.LogErr(err1, "create file") {
+		return
+	}
+	io.Copy(out, bytes.NewReader(body))
+	out.Close()
+}

+ 39 - 0
common/util/http.go

@@ -0,0 +1,39 @@
+package util
+
+import (
+	"io/ioutil"
+	"net/http"
+	"strings"
+)
+
+func HttpGet(url string) ([]byte, error) {
+	client := &http.Client{}
+	//提交请求
+	reqest, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return []byte{}, err
+	}
+	//处理返回结果
+	response, _ := client.Do(reqest)
+	bodyBytes, _ := ioutil.ReadAll(response.Body)
+
+	return bodyBytes, nil
+}
+
+
+func PostHeader(url string, msg string, headers map[string]string) ([]byte, error) {
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", url, strings.NewReader(msg))
+	if err != nil {
+		return nil, err
+	}
+	for key, header := range headers {
+		req.Header.Set(key, header)
+	}
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	return ioutil.ReadAll(resp.Body)
+}

+ 47 - 0
common/util/ordonnance.go

@@ -0,0 +1,47 @@
+package util
+
+import (
+	"bytes"
+	"fmt"
+	"image"
+	"image/color"
+	"image/draw"
+	"image/jpeg"
+	"image/png"
+	"io/ioutil"
+	"ordonnance/server/model"
+	"os"
+	"time"
+
+	"github.com/golang/freetype"
+	"github.com/golang/freetype/truetype"
+	qrcode "github.com/skip2/go-qrcode"
+)
+
+func MakeImg(ordonnance model.Ordonnance) string {
+	m := image.NewRGBA(image.Rect(0, 0, 200, 200))
+	white := color.RGBA{255, 255, 255, 0}
+	draw.Draw(m, m.Bounds(), &image.Uniform{white}, image.ZP, draw.Src)
+	var font *truetype.Font
+	fontBytes, _ := ioutil.ReadFile("./line.ttf")
+	font, _ = freetype.ParseFont(fontBytes)
+	f := freetype.NewContext()
+	f.SetFont(font)
+	f.SetClip(m.Bounds())
+	f.SetDst(m)
+	f.SetSrc(image.NewUniform(color.RGBA{0, 0, 0, 255}))
+	f.SetFontSize(18)
+	url := fmt.Sprintf("https://sm.hqedust.com/ordonnance/%d", ordonnance.OrdonnanceId)
+	qrcodeData, _ := qrcode.Encode(url, qrcode.Medium, 160)
+	qrImg, _ := png.Decode(bytes.NewReader(qrcodeData))
+	offset := image.Pt(20, 10)
+	draw.Draw(m, qrImg.Bounds().Add(offset), qrImg, image.ZP, draw.Over)
+
+	f.SetFontSize(12)
+	w, h := 20, 180
+	f.DrawString("时间:"+time.Now().Format("2006-01-02 15:04:05"), freetype.Pt(w, h))
+	filename := time.Now().Format("tempdir/20060102150405.jpg")
+	myfile, _ := os.Create(filename)
+	jpeg.Encode(myfile, m, &jpeg.Options{Quality: 100})
+	return filename
+}

+ 255 - 0
common/util/util.go

@@ -0,0 +1,255 @@
+package util
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"math/rand"
+	"ordonnance/logger"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+)
+
+const secret = "1a113ef6b61820daa5611c870ed8d5ee"
+
+var (
+	rr = rand.New(rand.NewSource(time.Now().UnixNano()))
+)
+
+func Strip(res string) string {
+	res = strings.Replace(res, " ", "", -1)
+	res = strings.Replace(res, "\t", "", -1)
+	res = strings.Replace(res, "\n", "", -1)
+	res = strings.Replace(res, " ", "", -1)
+	return res
+}
+
+func Md5(data string) string {
+	c := md5.New()
+	c.Write([]byte(data))
+	cipherStr := c.Sum(nil)
+	return hex.EncodeToString(cipherStr)
+}
+func RandToken(userId int) string {
+	timestamp := time.Now().Unix()
+	userIdStr := strconv.Itoa(userId)
+	return Md5("demo_"+strconv.FormatInt(timestamp, 16)) + userIdStr
+}
+
+func LogErr(tag string, err error) bool {
+	if err != nil {
+		logger.Infof("err %s  %s", tag, err.Error())
+		return true
+	}
+	return false
+}
+
+func IsIdCard(idCard string) bool {
+	checkStr := "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$|^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$"
+	if res, err := regexp.Match(checkStr, []byte(idCard)); err == nil && res {
+		return true
+	}
+	return false
+}
+
+func IsEmail(email string) bool {
+	//pattern := `\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*` //匹配电子邮箱
+	pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
+
+	reg := regexp.MustCompile(pattern)
+	return reg.MatchString(email)
+}
+
+//mobile verify
+func IsPhone(mobileNum string) bool {
+	regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
+	reg := regexp.MustCompile(regular)
+	return reg.MatchString(mobileNum)
+}
+
+func CurTime() string {
+	return time.Now().Format("2006-01-02 15:04:05")
+}
+
+type Media struct {
+	MediaId  int
+	CourseId int
+	Duration int
+	Xs       int
+	Play     int
+}
+
+//
+type MediaUrl struct {
+	MediaId int
+	UserId  int
+	Time    int
+}
+
+func GetInt(val interface{}) int {
+	if val == nil || val == "" {
+		return 0
+	}
+	switch val.(type) {
+	case int:
+		return val.(int)
+	case int64:
+		return int(val.(int64))
+	case float32:
+		return int(val.(float32))
+	case float64:
+		return int(val.(float64))
+	case string:
+		if mint, flag := strconv.Atoi(val.(string)); flag == nil {
+			return mint
+		}
+	}
+	return 0
+}
+func JoinInts(list []int) string {
+	res := ""
+	for i, item := range list {
+		if i > 0 {
+			res += ","
+		}
+		res += strconv.Itoa(item)
+	}
+
+	return res
+}
+
+func GetBoolInt(val interface{}) int {
+	if GetBool(val) {
+		return 1
+	} else {
+		return 0
+	}
+}
+
+func GetBool(val interface{}) bool {
+	if val == nil || val == "" {
+		return false
+	}
+	switch val.(type) {
+	case int:
+		return val.(int) > 0
+	case int64:
+		return val.(int64) > 0
+	case float32:
+		return val.(float32) > 0
+	case float64:
+		return val.(float64) > 0
+	case string:
+		return val != ""
+	}
+	return false
+}
+
+func ToInts(str string) []int {
+	data := []int{}
+	for _, item := range strings.Split(str, ",") {
+		if val, err := strconv.Atoi(item); err == nil {
+			data = append(data, val)
+		}
+	}
+	return data
+}
+
+func sliceOutOfOrder(in []int) []int {
+	l := len(in)
+	for i := l - 1; i > 0; i-- {
+		r := rr.Intn(i)
+		in[r], in[i] = in[i], in[r]
+	}
+	return in
+}
+
+func FilterMap(list []int, data map[int]bool, minCount int) []int {
+	nlist := []int{}
+	slist := sliceOutOfOrder(list)
+	gmap := make(map[int]bool)
+	for _, id := range slist {
+		// 80% 的概率剔除
+		if data[id] {
+			continue
+		}
+		if len(nlist) > minCount {
+			break
+		}
+		gmap[id] = true
+		nlist = append(nlist, id)
+	}
+
+	for _, id := range slist {
+		if len(nlist) > minCount {
+			break
+		}
+		if gmap[id] {
+			continue
+		}
+		nlist = append(nlist, id)
+	}
+	return nlist
+}
+
+func FilterList(list []int, data map[int]bool) []int {
+	nlist := []int{}
+	for _, id := range list {
+		if data[id] {
+			continue
+		}
+		nlist = append(nlist, id)
+	}
+	return nlist
+}
+
+// 生成随机数
+func GenerateRandomNumber(start int, end int, count int) []int {
+	if end < start || (end-start) < count {
+		return nil
+	}
+	nums := make([]int, 0)
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for len(nums) < count {
+		num := r.Intn((end - start)) + start
+		exist := false
+		for _, v := range nums {
+			if v == num {
+				exist = true
+				break
+			}
+		}
+		if !exist {
+			nums = append(nums, num)
+		}
+	}
+	return nums
+}
+
+func RandIntList(data []int, count int) []int {
+	lenData := len(data)
+	if lenData <= count {
+		return data
+	}
+	datalist := []int{}
+	existMap := map[int]bool{}
+	//自由随机
+	for i := 0; i < lenData; i++ {
+		existMap[i] = true
+	}
+	// 利用 map无序
+	for index := range existMap {
+		if count == 0 {
+			break
+		}
+		count--
+		datalist = append(datalist, data[index])
+	}
+
+	return datalist
+}
+
+func GetBirthday(cardId string) string {
+	return cardId[6:10] + "-" + cardId[10:12] + "-" + cardId[12:14]
+}

+ 28 - 0
conf/conf.go

@@ -0,0 +1,28 @@
+package conf
+
+import (
+	"github.com/widuu/goini"
+)
+
+var conf = &goini.Config{}
+
+func init() {
+	conf = goini.SetConfig("./conf/conf.ini")
+	// 微信
+}
+
+func GetConf() *goini.Config {
+	return conf
+}
+
+func GetP1() string {
+	return conf.GetValue("ordonnance", "p1")
+}
+
+func GetPort() string {
+	return conf.GetValue("ordonnance", "port")
+}
+
+func GetPidName() string {
+	return "ordonnance"
+}

+ 3 - 0
conf/conf.ini

@@ -0,0 +1,3 @@
+[ordonnance]
+port = 8000
+p1=cert_net:VH7Ou7IWWMjE$v6o@tcp(183.251.232.110:3306)/ordonnance?charset=utf8

+ 3 - 0
conf/consts.go

@@ -0,0 +1,3 @@
+package conf
+
+const ()

+ 35 - 0
go.mod

@@ -0,0 +1,35 @@
+module ordonnance
+
+go 1.15
+
+require (
+	github.com/aliyun/alibaba-cloud-sdk-go v1.61.999
+	github.com/aliyun/aliyun-oss-go-sdk v2.1.1+incompatible
+	github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
+	github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible
+	github.com/gin-gonic/gin v1.6.3
+	github.com/go-sql-driver/mysql v1.6.0
+	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
+	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
+	github.com/lestrrat-go/strftime v1.0.3 // indirect
+	github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de
+	github.com/mojocn/base64Captcha v1.3.1
+	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
+	github.com/objcoding/wxpay v1.0.6
+	github.com/patrickmn/go-cache v2.1.0+incompatible
+	github.com/pkg/errors v0.8.1
+	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
+	github.com/robfig/cron v1.2.0
+	github.com/signintech/gopdf v0.9.8
+	github.com/sirupsen/logrus v1.7.0
+	github.com/skip2/go-qrcode v0.0.0-20200526175731-7ac0b40b2038
+	github.com/tealeg/xlsx v1.0.5 // indirect
+	github.com/urfave/cli v1.22.4
+	github.com/widuu/goini v0.0.0-20180603013956-56a38bd2e09b
+	github.com/wleven/wxpay v1.2.9
+	golang.org/x/image v0.0.0-20200430140353-33d19683fad8
+	golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
+	gorm.io/driver/mysql v1.0.5
+	gorm.io/gorm v1.21.5
+)

+ 151 - 0
go.sum

@@ -0,0 +1,151 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.999 h1:8MR403mClEPOwQo2lG27Zd+2uTsiPYTZj1d/b97mmO0=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.999/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
+github.com/aliyun/aliyun-oss-go-sdk v2.1.1+incompatible h1:rCOqkJYYTYM6vQH0dWkWTXAw4uKFp8+GPXcYl4Oayr8=
+github.com/aliyun/aliyun-oss-go-sdk v2.1.1+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
+github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
+github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
+github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=
+github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+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/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=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+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/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+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.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
+github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+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/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.3 h1:qqOPU7y+TM8Y803I8fG9c/DyKG3xH/xkng6keC1015Q=
+github.com/lestrrat-go/strftime v1.0.3/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+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=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mojocn/base64Captcha v1.3.1 h1:2Wbkt8Oc8qjmNJ5GyOfSo4tgVQPsbKMftqASnq8GlT0=
+github.com/mojocn/base64Captcha v1.3.1/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
+github.com/objcoding/wxpay v1.0.6 h1:8DOQ5NSJcbIYxiIJVn4j9847h4dOxk5KMAFvJjLIiSw=
+github.com/objcoding/wxpay v1.0.6/go.mod h1:z7rH38P+iS3ibWDABSnNjYzYOnqqORB0QDZukzkRwnc=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/phpdave11/gofpdi v1.0.8 h1:9HRg0Z0qDfWeMU7ska+YNQ13RHxTxqP5KTg/dBl4o7c=
+github.com/phpdave11/gofpdi v1.0.8/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
+github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
+github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/signintech/gopdf v0.9.8 h1:tafWEjYhorfHMl9JT9II43fvf5XhUwrjUKVNwQqqyJQ=
+github.com/signintech/gopdf v0.9.8/go.mod h1:MrARAC6LaOgbnV6vrC5885VuoWCXazhAqx8L8zmjYy4=
+github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/skip2/go-qrcode v0.0.0-20200526175731-7ac0b40b2038 h1:YV7j5thtTo5/Len66qC+EHMFBH4JZXO3rZ1I4ogb3HM=
+github.com/skip2/go-qrcode v0.0.0-20200526175731-7ac0b40b2038/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
+github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
+github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/webview/webview v0.0.0-20200724072439-e0c01595b361 h1:e0+/fQY5l9NdCwPsEg9S8AgE5lFhZ/6UX+b2KkpIBFg=
+github.com/webview/webview v0.0.0-20200724072439-e0c01595b361/go.mod h1:rpXAuuHgyEJb6kXcXldlkOjU6y4x+YcASKKXJNUhh0Y=
+github.com/widuu/goini v0.0.0-20180603013956-56a38bd2e09b h1:Fc2RRfaaHdNmSNbN4F7te3jiPuCxqzusksEG1y5BLbE=
+github.com/widuu/goini v0.0.0-20180603013956-56a38bd2e09b/go.mod h1:4q5KUnbuu2CNbSmQru54JCD9Q49oLopMVPEgroiFtFw=
+github.com/wleven/wxpay v1.2.9 h1:mqYIy3H4mF3LEDjzMZZmtC/HmkG56ejcAFHDhEu/XSM=
+github.com/wleven/wxpay v1.2.9/go.mod h1:IlMR8ba5TZ9lwmh8vMbSoIbY5UawPJL9Dc2T14Q5qWM=
+golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ=
+golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
+golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
+gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gorm.io/driver/mysql v1.0.5 h1:WAAmvLK2rG0tCOqrf5XcLi2QUwugd4rcVJ/W3aoon9o=
+gorm.io/driver/mysql v1.0.5/go.mod h1:N1OIhHAIhx5SunkMGqWbGFVeh4yTNWKmMo1GOAsohLI=
+gorm.io/gorm v1.21.3/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
+gorm.io/gorm v1.21.5 h1:Qf3uCq1WR9lt9/udefdhaFcf+aAZ+mrDtfXTA+GB9Gc=
+gorm.io/gorm v1.21.5/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=

BIN
line.ttf


+ 11 - 0
log.xml

@@ -0,0 +1,11 @@
+<seelog type="asynctimer" asyncinterval="5000000" minlevel="trace" maxlevel="error">
+   <outputs formatid="common">
+     <buffered formatid="common" size="20480" flushperiod="1000">
+      <rollingfile type="date" filename="./log/console.log" datepattern="02.01.2006" fullname="true" maxrolls="30"/>
+     </buffered>
+   </outputs>
+   
+    <formats>
+      <format id="common" format="[%Date %Time] [%LEV] [%File:%Line] [%Func] %Msg%n" />
+    </formats>
+</seelog>

+ 176 - 0
logger/log.go

@@ -0,0 +1,176 @@
+package logger
+
+import (
+	// "path"
+	"fmt"
+	"net/http"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	// "time"
+	"github.com/gin-gonic/gin"
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
+	"github.com/rifflock/lfshook"
+	"github.com/sirupsen/logrus"
+)
+
+const filename = "./logs/console"
+
+func init() {
+	logrus.SetFormatter(&DFormatter{})
+	writer, _ := rotatelogs.New(
+		filename+".%Y%m%d.log",
+		// rotatelogs.WithLinkName(filename),
+		rotatelogs.WithRotationCount(50),
+		rotatelogs.WithRotationTime(time.Hour*24),
+	)
+	logrus.AddHook(lfshook.NewHook(
+		lfshook.WriterMap{
+			logrus.DebugLevel: writer,
+			logrus.InfoLevel:  writer,
+			logrus.WarnLevel:  writer,
+			logrus.ErrorLevel: writer,
+			logrus.FatalLevel: writer,
+			logrus.PanicLevel: writer,
+		}, &logrus.TextFormatter{}),
+	)
+
+	// logrus.SetOutput(writer)
+	// logrus.SetLevel(logrus.InfoLevel)
+}
+
+type DFormatter struct {
+	TimestampFormat string
+}
+
+func (f *DFormatter) Format(entry *logrus.Entry) ([]byte, error) {
+	timestampFormat := f.TimestampFormat
+	if timestampFormat == "" {
+		timestampFormat = "2006/01/02 15:04:05"
+	}
+	_, file, line, ok := runtime.Caller(9)
+	if !ok {
+		file = "???"
+		line = 0
+	}
+	// _, filename := path.Split(file)
+	msg := entry.Time.Format(timestampFormat) +
+		" " + strings.ToUpper(entry.Level.String()) +
+		" [" + file + ":" + strconv.Itoa(line) + "] " +
+		entry.Message + "\n"
+
+	return []byte(msg), nil
+}
+
+func Debugf(format string, args ...interface{}) {
+	logrus.Debugf(format, args...)
+}
+
+func LogErr(err error, format string, args ...interface{}) bool {
+	if err != nil {
+		args = append(args, err.Error())
+		logrus.Infof(format+" %s", args...)
+		return false
+	}
+	return true
+}
+
+func Infof(format string, args ...interface{}) {
+	logrus.Infof(format, args...)
+}
+
+func Warnf(format string, args ...interface{}) {
+	logrus.Warnf(format, args...)
+}
+
+func Errorf(format string, args ...interface{}) {
+	logrus.Errorf(format, args...)
+}
+
+func Fatalf(format string, args ...interface{}) {
+	logrus.Fatalf(format, args...)
+}
+
+func Panicf(format string, args ...interface{}) {
+	logrus.Panicf(format, args...)
+}
+
+func Debug(args ...interface{}) {
+	logrus.Debug(args...)
+}
+
+func Info(args ...interface{}) {
+	logrus.Info(args...)
+}
+
+func Warn(args ...interface{}) {
+	logrus.Warn(args...)
+}
+
+func Error(args ...interface{}) {
+	logrus.Error(args...)
+}
+
+func Fatal(args ...interface{}) {
+	logrus.Fatal(args...)
+}
+
+func Panic(args ...interface{}) {
+	logrus.Panic(args...)
+}
+
+func SetGinLogger() gin.LoggerConfig {
+	var c gin.LoggerConfig
+	c.Output = gin.DefaultWriter
+	c.Formatter = func(params gin.LogFormatterParams) string {
+		userName := GetStr("userId", params.Keys, "")
+		var formatStr string
+		if params.StatusCode == http.StatusOK {
+			formatStr = fmt.Sprintf("%s  %-15s %-16s  %-4s   %s  %d  %s  %s\n",
+				params.TimeStamp.Format("2006-01-02 15:04:05"),
+				params.ClientIP,
+				userName,
+				params.Method,
+				params.Path,
+				params.StatusCode,
+				params.Latency,
+				params.ErrorMessage,
+			)
+		} else {
+			formatStr = fmt.Sprintf("\x1b[93m%s  %-15s %-16s %-4s   %s  %d  %s  %s\n\x1b[0m",
+				params.TimeStamp.Format("2006-01-02 15:04:05"),
+				params.ClientIP,
+				userName,
+				params.Method,
+				params.Path,
+				params.StatusCode,
+				params.Latency,
+				params.ErrorMessage,
+			)
+		}
+		// logrus.Infof(" %-15s %-16s %-4s   %s  %d  %s  %s", params.ClientIP, userName,
+		// 	params.Method,
+		// 	params.Path,
+		// 	params.StatusCode,
+		// 	params.Latency,
+		// 	params.ErrorMessage,
+		// )
+		return formatStr
+	}
+	return c
+
+}
+
+func GetStr(key string, obj map[string]interface{}, def string) string {
+	if val, flag := obj[key]; flag {
+		if sVal, flag2 := val.(string); flag2 {
+			return sVal
+		}
+		if sVal, flag2 := val.(int); flag2 {
+			return strconv.Itoa(sVal)
+		}
+	}
+	return def
+}

+ 106 - 0
main.go

@@ -0,0 +1,106 @@
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	_ "net/http/pprof"
+	"ordonnance/conf"
+	"ordonnance/logger"
+	"ordonnance/route"
+	"os"
+	"os/exec"
+	"time"
+
+	"github.com/urfave/cli"
+)
+
+var pidPath string
+var pidName string
+
+func main() {
+	app := cli.NewApp()
+	pidName = "./ordonnance"
+
+	pidPath = pidName + ".pid"
+
+	app.Name = "ordonnance"
+	app.Author = "ordonnance authors"
+	app.Version = "0.0.1"
+	app.Copyright = "ordonnance authors reserved"
+	app.Usage = "ordonnance start|stop|restart|{-d}"
+
+	app.Commands = []cli.Command{
+		cli.Command{
+			Name: "start",
+			Flags: []cli.Flag{
+				&cli.BoolFlag{Name: "d", Usage: "run background"},
+			},
+			Aliases: []string{"start"},
+			Action:  start,
+		},
+		cli.Command{
+			Name:    "stop",
+			Aliases: []string{"stop"},
+			Action:  stop,
+		},
+		cli.Command{
+			Name:    "restart",
+			Aliases: []string{"restart"},
+			Action:  restart,
+		},
+	}
+	app.Run(os.Args)
+}
+
+func start(ctx *cli.Context) error {
+	d := ctx.Bool("d")
+	logger.Info("start_d ", d)
+	if d {
+		start := exec.Command(pidName, "start")
+		start.Start()
+		os.Exit(0)
+	}
+	doStart()
+	return nil
+}
+
+// Start 启动
+func doStart() {
+	pid := fmt.Sprintf("%d", os.Getpid())
+	if err := ioutil.WriteFile(pidPath, []byte(pid), 0666); err != nil {
+		logger.Warn("start pid error ", pid)
+		panic(err)
+	}
+	go func() {
+		http.ListenAndServe(":6060", nil)
+	}()
+
+	addr := conf.GetPort()
+	route.RunService(addr)
+}
+
+// Stop 停止
+func stop(ctx *cli.Context) error {
+	pid, _ := ioutil.ReadFile(pidPath)
+	logger.Info("doStop ", ctx.String("stop"), string(pid))
+	cmd := exec.Command("kill", "-9", string(pid))
+	cmd.Start()
+	if err := ioutil.WriteFile(pidPath, nil, 0666); err != nil {
+		logger.Warnf("write pid error %v %v", string(pid), err.Error())
+	}
+	return nil
+}
+
+// Restart 重启
+func restart(ctx *cli.Context) error {
+	logger.Info("doRestart ", ctx.String("restart"))
+	pid, _ := ioutil.ReadFile(pidPath)
+	logger.Info("restarting..." + string(pid))
+	stop := exec.Command("kill", "-9", string(pid))
+	stop.Start()
+	time.Sleep(5 * time.Second)
+	start := exec.Command(pidName, "start")
+	start.Start()
+	return nil
+}

+ 23 - 0
route/index.go

@@ -0,0 +1,23 @@
+package route
+
+import (
+	"ordonnance/apis/third"
+	"ordonnance/common/corn"
+	"ordonnance/common/middleware"
+	"ordonnance/logger"
+
+	"github.com/gin-gonic/gin"
+	_ "github.com/go-sql-driver/mysql"
+)
+
+func RunService(myport string) {
+	corn.RunCorn()
+	r := gin.Default()
+	r.Use(middleware.Recover)
+	// base
+	r.GET("/ordonnance/qrcode/:ordonnanceId", third.GetordonnanceQrcode)
+	r.POST("/ordonnance/detail/:ordonnanceId", third.GetordonnanceDetail)
+	//
+	logger.Infof("strat http server @port=%s", myport)
+	r.Run(":" + myport)
+}

+ 18 - 0
server/dao/ordonnance.go

@@ -0,0 +1,18 @@
+package dao
+
+import (
+	"ordonnance/common/db"
+	"ordonnance/server/model"
+)
+
+// 获取 药方
+func GetOrdonnance(id interface{}) (info model.Ordonnance, err error) {
+	err = db.GDB.Where("ordonnance_id=?", id).First(&info).Error
+	return
+}
+
+// 获取 药剂量
+func GetOrdonnanceItemList(id interface{}) (list []model.OrdonnanceItem, err error) {
+	err = db.GDB.Where("ordonnance_id=?", id).Find(&list).Error
+	return
+}

+ 29 - 0
server/model/ordonnance.go

@@ -0,0 +1,29 @@
+package model
+
+type Ordonnance struct {
+	OrdonnanceId     int    `json:"ordonnanceId" gorm:"primaryKey" `
+	Organ            string `json:"organ"`
+	Nickname         string `json:"nickname"`
+	Symptom          string `json:"symptom"`
+	Doctor           string `json:"doctor"`
+	TakingWay        string `json:"takingWay"`
+	DosageConfirm    string `json:"dosageConfirm"`
+	ProvideConfirm   string `json:"provideConfirm"`
+	PrescriptionSign string `json:"prescriptionSign"`
+	ReviewSign       string `json:"reviewSign"`
+	PrintDate        string `json:"printDate"`
+
+	TotalFee    uint16 `json:"totalFee"`
+	ChineseFee  uint16 `json:"chineseFee"`
+	BoilFee     uint16 `json:"boilFee"`
+	DeliveryFee uint16 `json:"deliveryFee"`
+}
+
+type VordonnanceDetail struct {
+	Ordonnance
+	Detail []OrdonnanceItem `json:"detail"`
+}
+
+func (Ordonnance) TableName() string {
+	return "t_ordonnance"
+}

+ 24 - 0
server/model/ordonnanceItem.go

@@ -0,0 +1,24 @@
+package model
+
+type OrdonnanceItem struct {
+	Id               int    `json:"id" gorm:"primaryKey" `
+	Organ            string `json:"organ"`
+	Nickname         string `json:"nickname"`
+	Symptom          string `json:"symptom"`
+	Doctor           string `json:"doctor"`
+	TakingWay        string `json:"takingWay"`
+	DosageConfirm    string `json:"dosageConfirm"`
+	ProvideConfirm   string `json:"provideConfirm"`
+	PrescriptionSign string `json:"prescriptionSign"`
+	ReviewSign       string `json:"reviewSign"`
+	PrintDate        string `json:"printDate"`
+
+	TotalFee    uint16 `json:"totalFee"`
+	ChineseFee  uint16 `json:"chineseFee"`
+	BoilFee     uint16 `json:"boilFee"`
+	DeliveryFee uint16 `json:"deliveryFee"`
+}
+
+func (OrdonnanceItem) TableName() string {
+	return "t_ordonnance_item"
+}

+ 75 - 0
server/response/response.go

@@ -0,0 +1,75 @@
+package response
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+)
+
+type Response struct {
+	Code int         `json:"code"`
+	Data interface{} `json:"data"`
+	Msg  string      `json:"msg"`
+}
+
+const (
+	ERROR   = 7
+	SUCCESS = 0
+)
+
+func Result(code int, data interface{}, msg string, c *gin.Context) {
+	// 开始时间
+	c.JSON(http.StatusOK, Response{
+		code,
+		data,
+		msg,
+	})
+}
+
+func Ok(c *gin.Context) {
+	Result(SUCCESS, map[string]interface{}{}, "操作成功", c)
+}
+
+func ReturnErr(err error, c *gin.Context) {
+	if err != nil {
+		FailWithError(err, c)
+	} else {
+		OkWithMessage("操作成功", c)
+	}
+}
+
+func ReturnErrData(err error, data interface{}, c *gin.Context) {
+	if err != nil {
+		FailWithError(err, c)
+	} else {
+		OkWithData(data, c)
+	}
+}
+
+func OkWithMessage(message string, c *gin.Context) {
+	Result(SUCCESS, map[string]interface{}{}, message, c)
+}
+
+func OkWithData(data interface{}, c *gin.Context) {
+	Result(SUCCESS, data, "操作成功", c)
+}
+
+func OkWithDetailed(data interface{}, message string, c *gin.Context) {
+	Result(SUCCESS, data, message, c)
+}
+
+func Fail(c *gin.Context) {
+	Result(ERROR, map[string]interface{}{}, "操作失败", c)
+}
+
+func FailWithError(err error, c *gin.Context) {
+	Result(ERROR, map[string]interface{}{}, err.Error(), c)
+}
+
+func FailWithMessage(message string, c *gin.Context) {
+	Result(ERROR, map[string]interface{}{}, message, c)
+}
+
+func FailWithDetailed(data interface{}, message string, c *gin.Context) {
+	Result(ERROR, data, message, c)
+}

BIN
tempdir/20211102183344.jpg