├── .gitignore ├── README.md ├── config └── config.json ├── controller ├── FoodCategoryController.go ├── GoodsController.go ├── HelloController.go ├── MemberController.go └── ShopController.go ├── dao ├── FoodCategoryDao.go ├── GoodsDao.go ├── Memberdao.go └── ShopDao.go ├── docs └── image │ └── login.png ├── go.mod ├── go.sum ├── main.go ├── model ├── FoodCategory.go ├── Goods.go ├── Member.go ├── Service.go ├── ShopInfo.go ├── ShopService.go └── SmsCode.go ├── param ├── LoginParam.go └── SmsLoginParam.go ├── service ├── FoodCategoryService.go ├── GoodsService.go ├── MemberService.go └── ShopService.go ├── targz ├── fastdfs-6.02.tar.gz ├── fastdfs-nginx-module-1.21.tar.gz └── libfastcommon-1.0.41.tar.gz └── tool ├── Captcha.go ├── CommonResult.go ├── Config.go ├── CookieUtil.go ├── FastDfsUtil.go ├── JsonParse.go ├── OrmEngine.go ├── PasswordEncoder.go ├── RedisStore.go └── SessionStore.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | app.json 8 | fastdfs.conf 9 | # Test binary, built with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | # vendor/ 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CloudRestaurant 2 | 3 | 作为一个线上餐厅项目,后端主要使用GO-Gin,前端主要使用Vue 4 | 5 | 正在开发中...... 6 | 7 | ![image](https://github.com/Teanix/CloudRestaurant/blob/main/docs/image/login.png) 8 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_name":"CloudRestaurant", 3 | "app_mode":"debug", 4 | "app_host":"localhost", 5 | "app_port":"10086", 6 | 7 | "sms":{ 8 | "comment":"短信字段需要自己定义", 9 | "sign_name":"null", 10 | "template_code":"null", 11 | "app_key":"null", 12 | "app_secret":"null", 13 | "region_id":"cn-hangzhou" 14 | }, 15 | "database":{ 16 | "driver":"mysql", 17 | "user":"root", 18 | "password":"123456", 19 | "host":"127.0.0.1", 20 | "port":"3306", 21 | "db_name":"cloudrestaurant", 22 | "char_set":"utf8", 23 | "isShowsql":true 24 | } 25 | } -------------------------------------------------------------------------------- /controller/FoodCategoryController.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "CloudRestaurant/service" 5 | "CloudRestaurant/tool" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | type FoodCategoryController struct { 11 | } 12 | 13 | func (fcc *FoodCategoryController) Router(engine *gin.Engine) { 14 | engine.GET("/api/food_category", fcc.foodCategory) 15 | } 16 | 17 | func (fcc *FoodCategoryController) foodCategory(ctx *gin.Context) { 18 | //调用service层获取食品种类信息 19 | foodCategoryService := service.FoodCategoryService{} 20 | categories, err := foodCategoryService.Categories() 21 | if err != nil { 22 | tool.Failed(ctx, "get foodCategory Failed") 23 | return 24 | } 25 | 26 | //转换格式 27 | for _, category := range categories { 28 | if category.ImageUrl != "" { 29 | category.ImageUrl = tool.FileServerAddr() + "/" + category.ImageUrl 30 | } 31 | } 32 | tool.Success(ctx, categories) 33 | } 34 | -------------------------------------------------------------------------------- /controller/GoodsController.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "CloudRestaurant/service" 5 | "CloudRestaurant/tool" 6 | "strconv" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | type GoodsController struct { 12 | } 13 | 14 | func (gc *GoodsController) Router(app *gin.Engine) { 15 | app.GET("/api/foods", gc.GetGoods) 16 | } 17 | 18 | func (gc *GoodsController) GetGoods(context *gin.Context) { 19 | shopId, exist := context.GetQuery("shop_id") 20 | if !exist { 21 | tool.Failed(context, "get goods error") 22 | return 23 | } 24 | id, err := strconv.Atoi(shopId) 25 | if err != nil { 26 | tool.Failed(context, "shop-id to int error") 27 | return 28 | } 29 | //service层 30 | goodservice := service.NewGoodsService() 31 | goods := goodservice.GetFoods(int64(id)) 32 | if len(goods) == 0 { 33 | tool.Failed(context, "no data") 34 | } 35 | tool.Success(context, goods) 36 | } 37 | -------------------------------------------------------------------------------- /controller/HelloController.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | type HelloController struct { //方法 8 | } 9 | 10 | func (hello *HelloController) Router(engine *gin.Engine) { 11 | 12 | engine.GET("/hello", hello.Hello) 13 | } 14 | 15 | func (hello *HelloController) Hello(context *gin.Context) { 16 | context.JSON(200, gin.H{ 17 | "name": "yang", 18 | "age": "18", 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /controller/MemberController.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "CloudRestaurant/param" 6 | "CloudRestaurant/service" 7 | "CloudRestaurant/tool" 8 | "encoding/json" 9 | "fmt" 10 | "os" 11 | "strconv" 12 | "time" 13 | 14 | "github.com/gin-gonic/gin" 15 | ) 16 | 17 | type MemberController struct { 18 | } 19 | 20 | func (mc *MemberController) Router(engine *gin.Engine) { 21 | engine.GET("/api/sendcode", mc.Sendcode) 22 | engine.POST("/api/login_sms", mc.SmsLogin) 23 | engine.GET("/api/captcha", mc.Captcha) 24 | engine.POST("/api/vertifycha", mc.Vertifycha) 25 | engine.POST("/api/login_pwd", mc.NameLogin) 26 | engine.POST("/api/upload/avator", mc.UploadAvator) 27 | engine.POST("/api/userinfo", mc.UserInfo) 28 | } 29 | 30 | func (mc *MemberController) Sendcode(context *gin.Context) { 31 | //处理发送验证码Sendcode 32 | phone, exist := context.GetQuery("phone") 33 | if !exist { 34 | tool.Failed(context, "phone not exist") 35 | return 36 | } 37 | 38 | ms := service.MemberService{} 39 | isSend := ms.Sendcode(phone) 40 | if isSend { 41 | tool.Success(context, "send success") 42 | } else { 43 | tool.Failed(context, "send error") 44 | } 45 | } 46 | 47 | func (mc *MemberController) SmsLogin(context *gin.Context) { 48 | var smsLoginParam param.SmsLoginParam 49 | 50 | if err := tool.Decode(context.Request.Body, &smsLoginParam); err != nil { 51 | tool.Failed(context, "json decode error") 52 | return 53 | } 54 | //完成手机+验证码登陆的逻辑 55 | us := service.MemberService{} 56 | if member := us.SmsLogin(smsLoginParam); member != nil { 57 | //将用户信息保存到session中 58 | sess, _ := json.Marshal(member) 59 | if err := tool.SetSess(context, "user_"+string(member.Id), sess); err != nil { 60 | tool.Failed(context, "session Set Failed") 61 | return 62 | } 63 | //设置cookie 64 | context.SetCookie("cookie_user", strconv.Itoa(int(member.Id)), 10*60, "/", "localhost", true, true) 65 | tool.Success(context, member) 66 | return 67 | } 68 | tool.Failed(context, "member Login Failed") 69 | } 70 | 71 | //生成验证码,并返回客户端 72 | func (mc *MemberController) Captcha(context *gin.Context) { 73 | tool.GenerateCaptcha(context) 74 | } 75 | 76 | //验证码是否正确 77 | func (mc *MemberController) Vertifycha(context *gin.Context) { 78 | var captcha tool.CaptchaResult 79 | if err := tool.Decode(context.Request.Body, &captcha); err != nil { 80 | tool.Failed(context, "captcha decode error!") 81 | return 82 | } 83 | if res := tool.VertifyCaptcha(captcha.ID, captcha.VertifyValue); res { 84 | fmt.Println("验证通过") 85 | } else { 86 | fmt.Println("验证失败") 87 | } 88 | 89 | } 90 | 91 | func (mc *MemberController) NameLogin(context *gin.Context) { 92 | //1.解析用户登录传递参数 93 | var loginParam param.Loginparam 94 | if err := tool.Decode(context.Request.Body, &loginParam); err != nil { 95 | tool.Failed(context, "login param decode error") 96 | return 97 | } 98 | 99 | // 2.验证验证码 100 | if !(tool.VertifyCaptcha(loginParam.Id, loginParam.Value)) { 101 | tool.Failed(context, "captcha error,Please try again") 102 | return 103 | } 104 | // 3.登录 105 | ms := service.MemberService{} 106 | 107 | member := ms.Login(loginParam.Name, loginParam.Password) 108 | if member.Id != 0 { 109 | //将用户信息保存到session中 110 | sess, err := json.Marshal(member) 111 | if err != nil { 112 | fmt.Println("json Marshal error!") 113 | return 114 | } 115 | // if err := tool.SetSess(context, "user_16"+string(member.Id), sess); err != nil { 116 | if err := tool.SetSess(context, "user_16", sess); err != nil { 117 | tool.Failed(context, "session set error") 118 | return 119 | } 120 | 121 | tool.Success(context, &member) 122 | return 123 | } 124 | tool.Failed(context, "login error") 125 | } 126 | 127 | //头像文件上传 128 | func (mc *MemberController) UploadAvator(context *gin.Context) { 129 | // 1.解析上传的参数:image-file , user-ID 130 | userID := context.PostForm("user_id") 131 | fmt.Println("userID >>", userID) 132 | file, err := context.FormFile("avatar") 133 | if err != nil { 134 | tool.Failed(context, "avator decode error") 135 | return 136 | } 137 | // 2.通过session判断用户是否已经登录 138 | sess := tool.GetSess(context, "user_"+userID) 139 | if sess == nil { 140 | tool.Failed(context, "get user session error") 141 | return 142 | } 143 | var member model.Member 144 | json.Unmarshal(sess.([]byte), &member) //将session的内容设置为member的内容 145 | // 3.将file保存到本地 146 | fileName := "./uploadfile/" + strconv.FormatInt(time.Now().Unix(), 10) + file.Filename 147 | if err := context.SaveUploadedFile(file, fileName); err != nil { 148 | tool.Failed(context, "save avator error") 149 | return 150 | } 151 | //3.1 将文件上传到fdfs 152 | fileID := tool.UploadFile(fileName) 153 | if fileID != "" { 154 | //删除本地的文件 155 | os.Remove(fileName) 156 | //将路径保存到用户表中的头像字段 157 | memberService := service.MemberService{} 158 | path := memberService.UploadAvator(member.Id, fileID) 159 | if path != "" { 160 | tool.Success(context, tool.FileServerAddr()+"/"+path) 161 | } 162 | } 163 | 164 | tool.Failed(context, "upload avator error") 165 | // 5.返回结果 166 | } 167 | 168 | //对用户信息进行查询 169 | func (mc *MemberController) UserInfo(context *gin.Context) { 170 | //1.判断用户是否登录 171 | cookie, err := tool.CookieAuth(context) 172 | if err != nil { 173 | context.Abort() //??? 174 | tool.Failed(context, "no login,Please login first") 175 | return 176 | } 177 | memberService := service.MemberService{} 178 | member := memberService.GetUserInfo(cookie.Value) 179 | if member != nil { 180 | 181 | tool.Success(context, gin.H{ 182 | "id": member.Id, 183 | "user_name": member.UserName, 184 | "mobile": member.Mobile, 185 | "register_time": member.RegisterTime, 186 | "avator": member.Avatar, 187 | "balance": member.Balance, 188 | "city": member.City, 189 | }) 190 | return 191 | } 192 | tool.Failed(context, "get user info error") 193 | } 194 | -------------------------------------------------------------------------------- /controller/ShopController.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "CloudRestaurant/service" 5 | "CloudRestaurant/tool" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | type ShopController struct { 11 | } 12 | 13 | func (sc *ShopController) Router(app *gin.Engine) { 14 | app.GET("/api/shops", sc.GetShopList) 15 | app.GET("/api/search_shops", sc.SearchShop) 16 | } 17 | 18 | func (sc *ShopController) GetShopList(context *gin.Context) { 19 | longitude := context.Query("longitud-e") 20 | latitude := context.Query("latitude") 21 | 22 | if longitude == "" || longitude == "undefined" || latitude == "" || latitude == "undefined" { 23 | longitude = "116.34" 24 | latitude = "40.34" 25 | } 26 | 27 | shopService := service.ShopService{} 28 | shops := shopService.ShopList(longitude, latitude) 29 | if len(shops) == 0 { 30 | tool.Failed(context, "shoplist get error") 31 | return 32 | } 33 | 34 | for _, shop := range shops { 35 | shopServices := shopService.GetShopServiceById(shop.Id) 36 | if len(shopServices) == 0 { 37 | shop.Supports = nil 38 | } else { 39 | shop.Supports = shopServices 40 | } 41 | } 42 | tool.Success(context, shops) 43 | } 44 | 45 | //关键词搜索商铺信息 46 | func (sc *ShopController) SearchShop(context *gin.Context) { 47 | longitude := context.Query("longitude") 48 | latitude := context.Query("latitude") 49 | keyword := context.Query("keyword") 50 | 51 | if keyword == "" { 52 | tool.Failed(context, "error search try again") 53 | } 54 | if longitude == "" || longitude == "undefined" || latitude == "" || latitude == "undefined" { 55 | longitude = "116.34" 56 | latitude = "40.34" 57 | } 58 | //执行真正的搜索逻辑 59 | shopService := service.ShopService{} 60 | 61 | shopService.SearchShops(longitude, latitude, keyword) 62 | } 63 | -------------------------------------------------------------------------------- /dao/FoodCategoryDao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "CloudRestaurant/tool" 6 | ) 7 | 8 | type FoodCategoryDao struct { 9 | *tool.Orm 10 | } 11 | 12 | //实例化Dao对象 13 | func NewFoodCategoryDao() *FoodCategoryDao { 14 | return &FoodCategoryDao{tool.Dbengine} 15 | } 16 | 17 | //从数据库查询食品种类并返回 18 | func (fcd *FoodCategoryDao) QueryCategories() ([]model.FoodCategory, error) { 19 | var categories []model.FoodCategory 20 | 21 | if err := fcd.Engine.Find(&categories); err != nil { 22 | return nil, err 23 | } 24 | return categories, nil 25 | } 26 | -------------------------------------------------------------------------------- /dao/GoodsDao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "CloudRestaurant/tool" 6 | ) 7 | 8 | type GoodsDao struct { 9 | *tool.Orm 10 | } 11 | 12 | //实例化Dao对象 13 | func NewGoodsDao() *GoodsDao { 14 | return &GoodsDao{tool.Dbengine} 15 | } 16 | 17 | //根据商户id查询拥有所有商品 18 | func (gd *GoodsDao) QueryFoods(shop_id int64) ([]model.Goods, error) { 19 | var goods []model.Goods 20 | 21 | err := gd.Orm.Where("shop_id = ?", shop_id).Find(&goods) 22 | 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | return goods, nil 28 | } 29 | -------------------------------------------------------------------------------- /dao/Memberdao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "CloudRestaurant/tool" 6 | "fmt" 7 | 8 | "github.com/wonderivan/logger" 9 | ) 10 | 11 | type MemberDao struct { 12 | *tool.Orm 13 | } 14 | 15 | //根据电话和密码查询用户 16 | func (md *MemberDao) Query(name string, password string) *model.Member { 17 | var member model.Member 18 | password = tool.EncoderSha256(password) 19 | if _, err := md.Where("user_name = ? and password = ?", name, password).Get(&member); err != nil { 20 | fmt.Println(err.Error()) 21 | return nil 22 | } 23 | return &member 24 | } 25 | 26 | //根据电话查询用户 27 | func (md *MemberDao) QueryByPhone(phone string) *model.Member { 28 | var member model.Member 29 | 30 | if _, err := md.Where("mobile = ?").Get(&member); err != nil { 31 | fmt.Println(err.Error()) 32 | } 33 | 34 | return &member 35 | } 36 | 37 | //插入新用户 38 | func (md *MemberDao) InsertMember(member model.Member) int64 { 39 | res, err := md.InsertOne(&member) 40 | if err != nil { 41 | fmt.Println(err.Error()) 42 | return 0 43 | } 44 | return res 45 | } 46 | 47 | //根据手机及验证码查询数据库 48 | func (md *MemberDao) ValidateSmsCode(phone string, code string) *model.Smscode { 49 | var sms model.Smscode 50 | 51 | if _, err := md.Where("phone = ? and code = ?", phone, code).Get(&sms); err != nil { 52 | fmt.Println(err.Error()) 53 | } 54 | 55 | return &sms 56 | } 57 | 58 | //插入电话及验证码 59 | func (md *MemberDao) InsertCode(sms model.Smscode) int64 { 60 | result, err := md.InsertOne(&sms) 61 | if err != nil { 62 | logger.Error(err.Error()) 63 | } 64 | return result 65 | } 66 | 67 | //更新用户头像信息 68 | func (md *MemberDao) UpdateMemberAvatar(userID int64, fileName string) int64 { 69 | member := model.Member{Avatar: fileName} 70 | res, err := md.Where("id = ?", userID).Update(&member) 71 | if err != nil { 72 | fmt.Println(err.Error()) 73 | return 0 74 | } 75 | return res 76 | } 77 | 78 | func (md *MemberDao) QueryMemberById(userID int64) *model.Member { 79 | var member model.Member 80 | _, err := md.Orm.Where("id = ?", userID).Get(&member) 81 | if err != nil { 82 | return nil 83 | } 84 | return &member 85 | } 86 | -------------------------------------------------------------------------------- /dao/ShopDao.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "CloudRestaurant/tool" 6 | ) 7 | 8 | type ShopDao struct { 9 | *tool.Orm 10 | } 11 | 12 | func NewShopDao() *ShopDao { 13 | return &ShopDao{tool.Dbengine} 14 | } 15 | 16 | const DEFAULT_RANGE = 5 17 | 18 | //查询商铺的数据 19 | func (sd *ShopDao) QueryShops(longitude, latitude float64, keyword string) []model.Shop { 20 | var shops []model.Shop 21 | if keyword == "" { 22 | err := sd.Where("longitude > ? and longitude < ? and latitude > ? and latitude < ? and name like ? and status = 1", 23 | longitude-DEFAULT_RANGE, 24 | longitude+DEFAULT_RANGE, 25 | latitude-DEFAULT_RANGE, 26 | latitude+DEFAULT_RANGE, 27 | keyword).Find(&shops) 28 | if err != nil { 29 | return nil 30 | } 31 | } else { 32 | err := sd.Where("longitude > ? and longitude < ? and latitude > ? and latitude < ? and name like ? and status = 1", 33 | longitude-DEFAULT_RANGE, 34 | longitude+DEFAULT_RANGE, 35 | latitude-DEFAULT_RANGE, 36 | latitude+DEFAULT_RANGE, 37 | keyword).Find(&shops) 38 | if err != nil { 39 | return nil 40 | } 41 | } 42 | 43 | return shops 44 | } 45 | 46 | //根据商户ID查询对应服务 47 | func (sd *ShopDao) QueryShopServiceById(shopId int64) []model.Service { 48 | var services []model.Service 49 | 50 | err := sd.Orm.Table("service").Join("INNER", "shop_service", "srevice.id = shop_service.service_id and shop_service.shop_id = ?", shopId).Find(&services) 51 | if err != nil { 52 | return nil 53 | } 54 | return services 55 | } 56 | -------------------------------------------------------------------------------- /docs/image/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Teanix/CloudRestaurant/7635f2158c07d770e14df9dcc3a6b7d71e707e9b/docs/image/login.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module CloudRestaurant 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/aliyun/alibaba-cloud-sdk-go v1.61.1402 7 | github.com/gin-contrib/sessions v0.0.4 8 | github.com/gin-gonic/gin v1.7.7 9 | github.com/go-redis/redis v6.15.9+incompatible 10 | github.com/go-sql-driver/mysql v1.6.0 11 | github.com/go-xorm/xorm v0.7.9 12 | github.com/mojocn/base64Captcha v1.2.2 13 | github.com/wonderivan/logger v1.0.0 14 | ) 15 | 16 | require ( 17 | github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect 18 | github.com/gin-contrib/sse v0.1.0 // indirect 19 | github.com/go-playground/locales v0.13.0 // indirect 20 | github.com/go-playground/universal-translator v0.17.0 // indirect 21 | github.com/go-playground/validator/v10 v10.4.1 // indirect 22 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect 23 | github.com/golang/protobuf v1.5.2 // indirect 24 | github.com/gomodule/redigo v2.0.0+incompatible // indirect 25 | github.com/google/go-cmp v0.5.6 // indirect 26 | github.com/gorilla/context v1.1.1 // indirect 27 | github.com/gorilla/securecookie v1.1.1 // indirect 28 | github.com/gorilla/sessions v1.2.0 // indirect 29 | github.com/jmespath/go-jmespath v0.4.0 // indirect 30 | github.com/json-iterator/go v1.1.12 // indirect 31 | github.com/leodido/go-urn v1.2.0 // indirect 32 | github.com/mattn/go-isatty v0.0.12 // indirect 33 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 34 | github.com/modern-go/reflect2 v1.0.2 // indirect 35 | github.com/tedcy/fdfs_client v0.0.0-20200106031142-21a04994525a // indirect 36 | github.com/ugorji/go/codec v1.1.7 // indirect 37 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 38 | golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect 39 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect 40 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 41 | google.golang.org/protobuf v1.26.0 // indirect 42 | gopkg.in/ini.v1 v1.66.2 // indirect 43 | gopkg.in/yaml.v2 v2.4.0 // indirect 44 | xorm.io/builder v0.3.9 // indirect 45 | xorm.io/core v0.7.3 // indirect 46 | ) 47 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= 4 | cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= 5 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= 6 | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= 7 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 8 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= 9 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= 10 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 11 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 12 | github.com/aliyun/alibaba-cloud-sdk-go v1.61.1402 h1:XUCAx7EaCEO7V8o4kb7YgJIs6ZgisJaE0W/H+97JIwk= 13 | github.com/aliyun/alibaba-cloud-sdk-go v1.61.1402/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= 14 | github.com/antonlindstrom/pgstore v0.0.0-20200229204646-b08ebf1105e0/go.mod h1:2Ti6VUHVxpC0VSmTZzEvpzysnaGAfGBOoMIz5ykPyyw= 15 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 16 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 17 | github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff h1:RmdPFa+slIr4SCBg4st/l/vZWVe9QJKMXGO60Bxbe04= 18 | github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw= 19 | github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= 20 | github.com/bradleypeabody/gorilla-sessions-memcache v0.0.0-20181103040241-659414f458e1/go.mod h1:dkChI7Tbtx7H1Tj7TqGSZMOeGpMP5gLHtjroHd4agiI= 21 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 22 | github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= 23 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 24 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 25 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 26 | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o= 27 | github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= 28 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 29 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 30 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= 31 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 32 | github.com/gin-contrib/sessions v0.0.4 h1:gq4fNa1Zmp564iHP5G6EBuktilEos8VKhe2sza1KMgo= 33 | github.com/gin-contrib/sessions v0.0.4/go.mod h1:pQ3sIyviBBGcxgyR8mkeJuXbeV3h3NYmhJADQTq5+Vo= 34 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 35 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 36 | github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= 37 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 38 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 39 | github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= 40 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 41 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 42 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 43 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 44 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 45 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 46 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 47 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 48 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 49 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 50 | github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= 51 | github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= 52 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 53 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 54 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 55 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 56 | github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= 57 | github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0= 58 | github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= 59 | github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 60 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 61 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 62 | github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= 63 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= 64 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 65 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 66 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 67 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 68 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 69 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 70 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 71 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 72 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 73 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 74 | github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= 75 | github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 76 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 77 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 78 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 79 | github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 80 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 81 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 82 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 83 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 84 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 85 | github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= 86 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 87 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 88 | github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= 89 | github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= 90 | github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= 91 | github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= 92 | github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= 93 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 94 | github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= 95 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 96 | github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= 97 | github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= 98 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 99 | github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= 100 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= 101 | github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= 102 | github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= 103 | github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 104 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 105 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 106 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 107 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 108 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 109 | github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw= 110 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 111 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 112 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 113 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 114 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 115 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 116 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 117 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 118 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 119 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 120 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 121 | github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= 122 | github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 123 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 124 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 125 | github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= 126 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 127 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 128 | github.com/memcachier/mc v2.0.1+incompatible/go.mod h1:7bkvFE61leUBvXz+yxsOnGBQSZpBSPIMUQSmmSHvuXc= 129 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 130 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 131 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 132 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 133 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 134 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 135 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 136 | github.com/mojocn/base64Captcha v1.2.2 h1:NTFnThPVrb3tR66JO/N8/ZHsyFrNc7ho+xRpxBUEIlo= 137 | github.com/mojocn/base64Captcha v1.2.2/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY= 138 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 139 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 140 | github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= 141 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 142 | github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= 143 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 144 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= 145 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 146 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 147 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 148 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 149 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 150 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 151 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 152 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 153 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 154 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 155 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 156 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 157 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 158 | github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= 159 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 160 | github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= 161 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 162 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 163 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 164 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 165 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 166 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 167 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 168 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 169 | github.com/tedcy/fdfs_client v0.0.0-20200106031142-21a04994525a h1:dpCQv2S1VO5OhmDpnPi80gwBxEue0LAz9FuxUu2LO1w= 170 | github.com/tedcy/fdfs_client v0.0.0-20200106031142-21a04994525a/go.mod h1:tXHpOPUNIPkX4aZD1INHt6c9Dn+avkUNiFIe6z18YPg= 171 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 172 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 173 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 174 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 175 | github.com/wonderivan/logger v1.0.0 h1:Z6Nz+3SNcizolx3ARH11axdD4DXjFpb2J+ziGUVlv/U= 176 | github.com/wonderivan/logger v1.0.0/go.mod h1:NObMfQ3WOLKfYEZuGeZQfuQfSPE5+QNgRddVMzsAT/k= 177 | github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= 178 | github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= 179 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 180 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 181 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 182 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 183 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 184 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 185 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 186 | golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 187 | golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= 188 | golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= 189 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 190 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 191 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 192 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 193 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 194 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 195 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 196 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 197 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 198 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 199 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 200 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= 201 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 202 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 203 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 204 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 205 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 206 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 207 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 208 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 209 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 210 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 211 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 212 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 213 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 214 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 215 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 216 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= 217 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 218 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 219 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 220 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 221 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 222 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 223 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 224 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 225 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 226 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 227 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 228 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 229 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 230 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 231 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 232 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 233 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 234 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 235 | google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 236 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 237 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 238 | google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 239 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= 240 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 241 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 242 | google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 243 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 244 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 245 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 246 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 247 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 248 | gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 249 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 250 | gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= 251 | gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 252 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 253 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 254 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 255 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 256 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 257 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 258 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 259 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 260 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 261 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 262 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 263 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 264 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 265 | xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= 266 | xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc= 267 | xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= 268 | xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= 269 | xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0= 270 | xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= 271 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "CloudRestaurant/controller" 5 | "CloudRestaurant/tool" 6 | "fmt" 7 | "net/http" 8 | "strings" 9 | 10 | "github.com/gin-gonic/gin" 11 | "github.com/wonderivan/logger" 12 | ) 13 | 14 | func main() { 15 | 16 | cfg, err := tool.ParseConfig("./config/app.json") 17 | if err != nil { 18 | panic(err) 19 | } 20 | _, err = tool.OrmEngine(cfg) 21 | if err != nil { 22 | logger.Error(err.Error()) 23 | } 24 | //初始化Redis 25 | tool.InitRedisStore() 26 | //生成webapp 27 | app := gin.Default() 28 | //设置全局跨域访问 29 | app.Use(Cors()) 30 | //集成session功能 31 | tool.InitSession(app) 32 | //路由配置 33 | registerRouter(app) 34 | 35 | app.Run(cfg.AppHost + ":" + cfg.AppPort) 36 | } 37 | 38 | //路由设置 39 | func registerRouter(router *gin.Engine) { 40 | new(controller.HelloController).Router(router) 41 | new(controller.MemberController).Router(router) 42 | new(controller.FoodCategoryController).Router(router) 43 | new(controller.ShopController).Router(router) 44 | } 45 | 46 | //跨域访问中间件 cross origin resource share 47 | func Cors() gin.HandlerFunc { 48 | return func(context *gin.Context) { 49 | method := context.Request.Method 50 | origin := context.Request.Header.Get("Origin") 51 | var headerKeys []string 52 | for key := range context.Request.Header { 53 | headerKeys = append(headerKeys, key) 54 | } 55 | headerStr := strings.Join(headerKeys, ",") 56 | if headerStr != "" { 57 | headerStr = fmt.Sprintf("access-control-allow-orgin, access-control-allow-headers, %s", headerStr) 58 | } else { 59 | headerStr = "access-control-allow-origin,access-control-allow-headers" 60 | } 61 | if origin != "" { 62 | context.Writer.Header().Set("Access-Control-Allow-Origin", "*") 63 | context.Header("Access-Control-Allow-Origin", "*") // 设置允许访问所有域 Access-Control-Allow-Origin 64 | context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") 65 | context.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma") 66 | context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") 67 | context.Header("Access-Control-Max-Age", "172800") 68 | context.Header("Access-Control-Allow-Credentials", "false") 69 | context.Set("content-type", "application/json") // 设置返回格式是json 70 | } 71 | if method == "OPTIONS" { 72 | context.JSON(http.StatusOK, "Options Request!") 73 | } 74 | //处理请求 75 | context.Next() 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /model/FoodCategory.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //食品种类 4 | type FoodCategory struct { 5 | Id int64 `xorm:"pk autoincr" json:"id"` //类别ID 6 | Title string `xorm:"varchar(20)" json:"title"` //食品类别标题 7 | Description string `xorm:"varchar(30)" json:"description"` //食品描述 8 | ImageUrl string `xorm:"varchar(255)" json:"image_url"` //食品种类图片 9 | LinkUrl string `xorm:"varchar(255)" json:"link_rl"` //食品类别链接 10 | IsInServing bool `json:"is_in_serving"` //是否处于服务状态 11 | } 12 | -------------------------------------------------------------------------------- /model/Goods.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //食品结构体的定义 4 | type Goods struct { 5 | Id int64 `xorm:"pk autoincr" json:"id"` 6 | Name string `xorm:"varchar(12)" json:"name"` //名称 7 | Description string `xorm:"varchar(32)" json:"description"` //商品描述 8 | Icon string `xorm:"varchar(255)" json:"icon"` //商品图标 9 | SellCount int64 `xorm:"int" json:"sell_count"` //销量 10 | Price float32 `xorm:"float" json:"price"` //优惠价格 11 | OldPrice float32 `xorm:"float" json:"old_price"` //初始价格 12 | ShopId int64 `xorm:"int" json:"shop_id"` //对应商家 13 | } 14 | -------------------------------------------------------------------------------- /model/Member.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Member struct { 4 | Id int64 `xorm:"pk autoincr" json:"id"` 5 | UserName string `xorm:"varchar(20)" json:"user_name"` 6 | Mobile string `xorm:"varchar(11)" json:"mobile"` 7 | Password string `xorm:"varchar(255)" ison:"password"` 8 | RegisterTime int64 `xorm:"bigint" json:"register_time"` 9 | Avatar string `xorm:"varchar(255)" json:"avatar"` 10 | Balance float64 `xorm:"double" json:"balance"` 11 | IsActive int8 `xorm:"tinyint" json:"is_active"` 12 | City string `xorm:"varchar(10)" json:"city"` 13 | } 14 | -------------------------------------------------------------------------------- /model/Service.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //商铺服务基础表 - 票 保 准 4 | type Service struct { 5 | Id int64 `xorm:"pk autoincr" json:"id"` //Id 6 | Name string `xorm:"varchar(20)" json:"name"` //服务名称 7 | Description string `xorm:"varchar(30)" json:"description"` //服务描述 8 | IconName string `xorm:"varchar(3)" json:"icon_name"` //服务图标名称 9 | IconColor string `xorm:"varchar(6)" json:"icon_color"` //服务图标颜色 10 | } 11 | -------------------------------------------------------------------------------- /model/ShopInfo.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //商家结构体 4 | type Shop struct { 5 | Id int64 `xorm:"pk autoincr" json:"id"` //id 6 | Name string `xorm:"varchar(12)" json:"name"` //商铺名称 7 | PromotionInfo string `xorm:"varchar(40)" json:"promotion_info"` //宣传信息 8 | Address string `xorm:"varchar(100)" json:"address"` //地址 9 | Phone string `xorm:"varchar(11)" json:"phone"` //电话 10 | Status int `xorm:"tinyint" json:"status"` //是否营业 11 | Longitude float64 `xorm:"" json:"longitude"` //经度 12 | Latitude float64 `xorm:"" json:"latitude"` //纬度 13 | Imagepath string `xorm:"varchar(255)" json:"image_path"` //店铺图像 14 | IsNew bool `xorm:"bool" json:"is_new"` // 15 | IsPremium bool `xorm:"bool" json:"is_premium"` // 16 | Rating float32 `xorm:"float" json:"rating"` //商铺评分 17 | RatingCount int64 `xorm:"int" json:"rating_count"` //评分总数 18 | RecentOrderNum int64 `xorm:"int" json:"recent_order_num"` //当前订单总数 19 | MinimumOrderAmount int32 `xorm:"int" json:"minimum_order_amount"` //配送价起价 20 | DeliveryFee int32 `xorm:"int" json:"delivery_fee"` //配送费 21 | OpeningHours string `xorm:"varchar(20)" json:"opening_hours"` //营业时间 22 | Supports []Service `xorm:""` //xorm赋空 则不在数据库进行映射 23 | } 24 | -------------------------------------------------------------------------------- /model/ShopService.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type ShopService struct { 4 | ShopId int64 `xorm:"pk not null" json:"shop_id"` //某一个商户的ID 5 | ServiceId int64 `xorm:"pk not null" json:"service_id"` //商户具备的服务ID 6 | } 7 | -------------------------------------------------------------------------------- /model/SmsCode.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Smscode struct { 4 | Id int64 `xorm:"pk autoincr" json:"id"` 5 | Phone string `xorm:"varchar(11)" json:"phone"` 6 | BizID string `xorm:"varchar(30)" json:"biz_id"` 7 | Code string `xorm:"varchar(6)" json:"code"` 8 | CreateTime int64 `xorm:"bigint" json:"create_time"` 9 | } 10 | -------------------------------------------------------------------------------- /param/LoginParam.go: -------------------------------------------------------------------------------- 1 | package param 2 | 3 | type Loginparam struct { 4 | Name string `json:"name"` //用户名 5 | Password string `json:"pwd"` //密码 6 | Id string `json:"id"` //验证码ID 7 | Value string `json:"value"` //验证码输入值 8 | } 9 | -------------------------------------------------------------------------------- /param/SmsLoginParam.go: -------------------------------------------------------------------------------- 1 | package param 2 | 3 | //手机号+验证码 登陆时传参 4 | type SmsLoginParam struct { 5 | Phone string `json:"phone"` 6 | Code string `json:"code"` 7 | } 8 | -------------------------------------------------------------------------------- /service/FoodCategoryService.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "CloudRestaurant/dao" 5 | "CloudRestaurant/model" 6 | ) 7 | 8 | type FoodCategoryService struct { 9 | } 10 | 11 | func (fcs *FoodCategoryService) Categories() ([]model.FoodCategory, error) { 12 | //调用数据库操作层 13 | foodCategorydao := dao.NewFoodCategoryDao() 14 | return foodCategorydao.QueryCategories() 15 | } 16 | -------------------------------------------------------------------------------- /service/GoodsService.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "CloudRestaurant/dao" 5 | "CloudRestaurant/model" 6 | ) 7 | 8 | type GoodsService struct { 9 | } 10 | 11 | func NewGoodsService() *GoodsService { 12 | return &GoodsService{} 13 | } 14 | 15 | //获取商家的食品列表 16 | func (gs *GoodsService) GetFoods(shopid int64) []model.Goods { 17 | goodsDao := dao.NewGoodsDao() 18 | 19 | var goods []model.Goods 20 | goods, err := goodsDao.QueryFoods(shopid) 21 | if err != nil { 22 | return nil 23 | } 24 | return goods 25 | } 26 | -------------------------------------------------------------------------------- /service/MemberService.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "CloudRestaurant/dao" 5 | "CloudRestaurant/model" 6 | "CloudRestaurant/param" 7 | "CloudRestaurant/tool" 8 | "encoding/json" 9 | "fmt" 10 | "math/rand" 11 | "strconv" 12 | "time" 13 | 14 | "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi" 15 | "github.com/wonderivan/logger" 16 | ) 17 | 18 | type MemberService struct { 19 | } 20 | 21 | func (ms *MemberService) Sendcode(phone string) bool { 22 | 23 | //1.生成验证码 24 | code := fmt.Sprintf("%06v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000)) 25 | 26 | //2.调用SDK发送 27 | config := tool.GetConfig().Sms 28 | client, err := dysmsapi.NewClientWithAccessKey(config.RegionId, config.AppKey, config.Appsecret) 29 | if err != nil { 30 | logger.Error(err.Error()) 31 | return false 32 | } 33 | request := dysmsapi.CreateSendSmsRequest() 34 | request.Scheme = "https" 35 | request.SignName = config.SignName 36 | request.TemplateCode = config.TemplateCode 37 | request.PhoneNumbers = phone 38 | //组装待发送信息 39 | par, err := json.Marshal(map[string]interface{}{ 40 | "name": code, 41 | }) 42 | if err != nil { 43 | logger.Error(err.Error()) 44 | } 45 | request.TemplateParam = string(par) 46 | //接收返回结果 47 | response, err := client.SendSms(request) 48 | if err != nil { 49 | logger.Error(err.Error()) 50 | fmt.Print(err.Error()) 51 | return false 52 | } 53 | fmt.Println(response) 54 | 55 | //3.判断发送状态 56 | if response.Code == "OK" { 57 | // 将验证码保存到数据库中 58 | smscode := model.Smscode{Phone: phone, BizID: response.BizId, Code: code, CreateTime: time.Now().Unix()} 59 | MemberDao := dao.MemberDao{tool.Dbengine} 60 | result := MemberDao.InsertCode(smscode) 61 | 62 | return result > 0 63 | 64 | } 65 | return false 66 | } 67 | 68 | //完成手机+验证码登陆的实体操作 69 | func (ms *MemberService) SmsLogin(loginparam param.SmsLoginParam) *model.Member { 70 | //todo 71 | //1.获取到手机号+验证码 72 | md := dao.MemberDao{tool.Dbengine} 73 | sms := md.ValidateSmsCode(loginparam.Phone, loginparam.Code) 74 | 75 | //2.验证是否正确 76 | if sms.Id == 0 { 77 | return nil 78 | } 79 | //3.根据手机号查询记录 80 | member := md.QueryByPhone(loginparam.Phone) 81 | if member.Id != 0 { 82 | return member 83 | } 84 | // 若不存在则新创建且保存 85 | user := model.Member{} 86 | user.UserName = loginparam.Phone 87 | user.Mobile = loginparam.Phone 88 | user.RegisterTime = time.Now().Unix() 89 | 90 | user.Id = md.InsertMember(user) 91 | 92 | return &user 93 | } 94 | 95 | //登录 96 | func (ms *MemberService) Login(name string, password string) *model.Member { 97 | // 1.使用用户名+密码查询是否存在 98 | md := dao.MemberDao{tool.Dbengine} 99 | if member := md.Query(name, password); member.Id != 0 { 100 | return member 101 | } 102 | // 2.若不存在则创建 103 | user := model.Member{} 104 | user.UserName = name 105 | user.Password = tool.EncoderSha256(password) //对用户密码进行加密 106 | user.RegisterTime = time.Now().Unix() 107 | 108 | res := md.InsertMember(user) 109 | user.Id = res 110 | 111 | return &user 112 | } 113 | 114 | func (ms *MemberService) UploadAvator(userID int64, fileName string) string { 115 | memberDao := dao.MemberDao{tool.Dbengine} 116 | if result := memberDao.UpdateMemberAvatar(userID, fileName); result == 0 { 117 | return "" 118 | } 119 | return fileName 120 | } 121 | 122 | func (ms *MemberService) GetUserInfo(userID string) *model.Member { 123 | id, err := strconv.Atoi(userID) 124 | if err != nil { 125 | return nil 126 | } 127 | 128 | memberDao := dao.MemberDao{tool.Dbengine} 129 | 130 | return memberDao.QueryMemberById(int64(id)) 131 | } 132 | -------------------------------------------------------------------------------- /service/ShopService.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "CloudRestaurant/dao" 5 | "CloudRestaurant/model" 6 | "strconv" 7 | ) 8 | 9 | type ShopService struct { 10 | } 11 | 12 | //查询商铺列表数据 13 | func (ss *ShopService) ShopList(long, lat string) []model.Shop { 14 | longitude, err := strconv.ParseFloat(long, 32) 15 | if err != nil { 16 | return nil 17 | } 18 | latitude, err := strconv.ParseFloat(lat, 32) 19 | if err != nil { 20 | return nil 21 | } 22 | shopDao := dao.NewShopDao().QueryShops(longitude, latitude, "") 23 | return shopDao 24 | } 25 | 26 | //关键词查询 27 | func (ss *ShopService) SearchShops(long, lat, keyword string) []model.Shop { 28 | shopDao := dao.NewShopDao() 29 | 30 | longitude, err := strconv.ParseFloat(long, 32) 31 | if err != nil { 32 | return nil 33 | } 34 | latitude, err := strconv.ParseFloat(lat, 32) 35 | if err != nil { 36 | return nil 37 | } 38 | 39 | return shopDao.QueryShops(longitude, latitude, keyword) 40 | } 41 | 42 | func (ss *ShopService) GetShopServiceById(shopID int64) []model.Service { 43 | shopDao := dao.NewShopDao() 44 | 45 | return shopDao.QueryShopServiceById(shopID) 46 | } 47 | -------------------------------------------------------------------------------- /targz/fastdfs-6.02.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Teanix/CloudRestaurant/7635f2158c07d770e14df9dcc3a6b7d71e707e9b/targz/fastdfs-6.02.tar.gz -------------------------------------------------------------------------------- /targz/fastdfs-nginx-module-1.21.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Teanix/CloudRestaurant/7635f2158c07d770e14df9dcc3a6b7d71e707e9b/targz/fastdfs-nginx-module-1.21.tar.gz -------------------------------------------------------------------------------- /targz/libfastcommon-1.0.41.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Teanix/CloudRestaurant/7635f2158c07d770e14df9dcc3a6b7d71e707e9b/targz/libfastcommon-1.0.41.tar.gz -------------------------------------------------------------------------------- /tool/Captcha.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "image/color" 5 | 6 | "github.com/gin-gonic/gin" 7 | "github.com/mojocn/base64Captcha" 8 | ) 9 | 10 | type CaptchaResult struct { 11 | ID string `json:"id"` 12 | Base64Blob string `json:"base_64_blob"` 13 | VertifyValue string `json:"code"` 14 | } 15 | 16 | func GenerateCaptcha(context *gin.Context) { 17 | parameters := base64Captcha.ConfigCharacter{ 18 | Height: 30, 19 | Width: 60, 20 | Mode: 3, 21 | ComplexOfNoiseText: 0, 22 | ComplexOfNoiseDot: 0, 23 | IsUseSimpleFont: true, 24 | IsShowHollowLine: false, 25 | IsShowNoiseDot: false, 26 | IsShowNoiseText: false, 27 | IsShowSlimeLine: false, 28 | IsShowSineLine: false, 29 | CaptchaLen: 4, //长度 30 | BgColor: &color.RGBA{ //背景颜色 31 | R: 3, 32 | G: 102, 33 | B: 214, 34 | A: 254, 35 | }, 36 | } 37 | 38 | captchaID, captchaInterfaceInstance := base64Captcha.GenerateCaptcha("", parameters) 39 | 40 | bse64blob := base64Captcha.CaptchaWriteToBase64Encoding(captchaInterfaceInstance) //编码至base64 41 | 42 | captchaResult := CaptchaResult{ID: captchaID, Base64Blob: bse64blob} 43 | Success(context, gin.H{ 44 | "captcha_result": captchaResult, 45 | }) 46 | } 47 | 48 | //验证图形码 49 | func VertifyCaptcha(id string, value string) bool { 50 | res := base64Captcha.VerifyCaptcha(id, value) 51 | return res 52 | } 53 | -------------------------------------------------------------------------------- /tool/CommonResult.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | const ( 10 | SUCCESS int = 0 11 | FAILED int = 1 12 | ) 13 | 14 | //普通成功返回 15 | func Success(ctx *gin.Context, v interface{}) { 16 | ctx.JSON(http.StatusOK, map[string]interface{}{ 17 | "code": SUCCESS, 18 | "msg": "Success", 19 | "data": v, 20 | }) 21 | } 22 | 23 | func Failed(ctx *gin.Context, v interface{}) { 24 | ctx.JSON(http.StatusOK, map[string]interface{}{ 25 | "code": FAILED, 26 | "msg": "Failed", 27 | "data": v, 28 | }) 29 | } 30 | 31 | type CommonResult struct { 32 | } 33 | -------------------------------------------------------------------------------- /tool/Config.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "os" 7 | ) 8 | 9 | type Config struct { 10 | AppName string `json:"app_name"` 11 | AppMode string `json:"app_mode"` 12 | AppHost string `json:"app_host"` 13 | AppPort string `json:"app_port"` 14 | Sms SmsConfig `json:"sms"` 15 | Database DbConfig `json:"database"` 16 | RedisConfig RedisConfig `json:"redis_config"` 17 | } 18 | 19 | type SmsConfig struct { 20 | SignName string `json:"sign_name"` 21 | TemplateCode string `json:"template_code"` 22 | RegionId string `json:"region_id"` 23 | AppKey string `json:"app_key"` 24 | Appsecret string `json:"app_secret"` 25 | } 26 | 27 | type DbConfig struct { 28 | Driver string `json:"driver"` 29 | User string `json:"user"` 30 | Password string `json:"password"` 31 | Host string `json:"host"` 32 | Port string `json:"port"` 33 | DbName string `json:"db_name"` 34 | CharSet string `json:"char_set"` 35 | IsShowsql bool `json:"isShowsql"` 36 | } 37 | 38 | type RedisConfig struct { 39 | Addr string `json:"addr"` 40 | Port string `json:"port"` 41 | Password string `json:"password"` 42 | Db int `json:"db"` 43 | } 44 | 45 | var _cfg *Config = nil 46 | 47 | func GetConfig() *Config { 48 | return _cfg 49 | } 50 | 51 | func ParseConfig(path string) (*Config, error) { 52 | file, err := os.Open(path) 53 | if err != nil { 54 | panic(err) 55 | } 56 | defer file.Close() 57 | 58 | reader := bufio.NewReader(file) //返回reader指针 59 | decoder := json.NewDecoder(reader) //NewDecoder解析器 60 | if err = decoder.Decode(&_cfg); err != nil { //判断返回状态 61 | return nil, err 62 | } 63 | 64 | return _cfg, nil 65 | } 66 | -------------------------------------------------------------------------------- /tool/CookieUtil.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | const CookieName = "cookie_user" 10 | const CookieTimeLength = 10 * 60 //10min 11 | 12 | func CookieAuth(context *gin.Context) (*http.Cookie, error) { 13 | cookie, err := context.Request.Cookie(CookieName) 14 | if err == nil { 15 | context.SetCookie(cookie.Name, cookie.Value, cookie.MaxAge, cookie.Path, cookie.Domain, cookie.Secure, cookie.HttpOnly) 16 | return cookie, nil 17 | } else { 18 | return nil, err 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tool/FastDfsUtil.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "github.com/tedcy/fdfs_client" 10 | ) 11 | 12 | func UploadFile(fileName string) string { 13 | client, err := fdfs_client.NewClientWithConfig("./config/fastdfs.conf") 14 | defer client.Destory() 15 | if err != nil { 16 | fmt.Println(err.Error()) 17 | return "" 18 | } 19 | 20 | fileID, err := client.UploadByFilename(fileName) 21 | if err != nil { 22 | fmt.Println(err.Error()) 23 | return "" 24 | } 25 | return fileID 26 | } 27 | 28 | /** 29 | * 从配置文件读取文件服务器的IP和端口配置 30 | */ 31 | 32 | func FileServerAddr() string { 33 | file, err := os.Open("./config/fastdfs.conf") 34 | if err != nil { 35 | return "" 36 | } 37 | 38 | reader := bufio.NewReader(file) 39 | for { 40 | line, err := reader.ReadString('\n') //读取一行 41 | if err != nil { 42 | return "" 43 | } 44 | line = strings.TrimSuffix(line, "\n") 45 | str := strings.SplitN(line, "=", 2) 46 | switch str[0] { 47 | case "http_server_port": 48 | return str[1] 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tool/JsonParse.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | ) 7 | 8 | type JsonParse struct { 9 | } 10 | 11 | func Decode(io io.ReadCloser, v interface{}) error { 12 | return json.NewDecoder(io).Decode(v) 13 | } 14 | -------------------------------------------------------------------------------- /tool/OrmEngine.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "CloudRestaurant/model" 5 | "fmt" 6 | 7 | "github.com/go-xorm/xorm" 8 | 9 | _ "github.com/go-sql-driver/mysql" 10 | ) 11 | 12 | type Orm struct { 13 | *xorm.Engine 14 | } 15 | 16 | var Dbengine *Orm //进行全局赋值 17 | 18 | func OrmEngine(cfg *Config) (*Orm, error) { 19 | dbconfig := cfg.Database 20 | conn := dbconfig.User + ":" + dbconfig.Password + "@tcp(" + dbconfig.Host + ":" + dbconfig.Port + ")/" + dbconfig.DbName + "?charset=" + dbconfig.CharSet 21 | engine, err := xorm.NewEngine(dbconfig.Driver, conn) 22 | if err != nil { 23 | return nil, err 24 | } 25 | 26 | //是否提示操作状态 27 | engine.ShowSQL(dbconfig.IsShowsql) 28 | 29 | //初始化时将结构体映射为数据库的表 30 | err = engine.Sync2( 31 | new(model.Smscode), 32 | new(model.Member), 33 | new(model.FoodCategory), 34 | new(model.Shop), 35 | new(model.Service), 36 | new(model.ShopService), 37 | new(model.Goods)) 38 | if err != nil { 39 | return nil, err 40 | } 41 | orm := new(Orm) 42 | orm.Engine = engine 43 | Dbengine = orm //进行全局赋值 44 | 45 | //InitShopData() //初始化shop数据 46 | //InitGoodsData() //初始化goods数据 47 | return orm, nil 48 | } 49 | 50 | //向shop表中初始化数据 51 | func InitShopData() { 52 | shops := []model.Shop{ 53 | {Id: 1, Name: "嘉禾一品(温都水城)", Address: "北京市昌平区宏福苑温都水城F1", Longitude: 116.36868, Latitude: 40.10039, 54 | Phone: "13437850035", Status: 1, RecentOrderNum: 106, RatingCount: 961, Rating: 4.7, PromotionInfo: "欢迎光临,用餐高峰请提前下单,谢谢", 55 | OpeningHours: "8:30/20:30", IsNew: true, IsPremium: true, Imagepath: "", MinimumOrderAmount: 20, DeliveryFee: 5}, 56 | 57 | {Id: 479, Name: "杨国福麻辣烫", Address: "北京市市蜀山区南二环路天鹅湖万达广场8号楼1705室", Longitude: 117.22124, Latitude: 31.81948, Phone: "13167583411", 58 | Status: 1, RecentOrderNum: 755, RatingCount: 167, Rating: 4.2, PromotionInfo: "欢迎光临,用餐高峰请提前下单,谢谢", OpeningHours: "8:30/20:30", 59 | IsNew: true, IsPremium: true, Imagepath: "", MinimumOrderAmount: 20, DeliveryFee: 5}, 60 | 61 | {Id: 485, Name: "好适口", Address: "北京市海淀区西二旗大街58号", Longitude: 120.65355, Latitude: 31.26578, Phone: "12345678901", 62 | Status: 1, RecentOrderNum: 58, RatingCount: 576, Rating: 4.6, PromotionInfo: "欢迎光临,用餐高峰请提前下单,谢谢", OpeningHours: "8:30/20:30", 63 | IsNew: true, IsPremium: true, Imagepath: "", MinimumOrderAmount: 20, DeliveryFee: 5}, 64 | 65 | {Id: 486, Name: "东来顺旗舰店", Address: "北京市天河区东圃镇汇彩路38号1领汇创展商务中心401", Longitude: 113.41724, Latitude: 23.1127, Status: 1, 66 | Phone: "13544323775", RecentOrderNum: 542, RatingCount: 372, Rating: 4.2, PromotionInfo: "老北京正宗涮羊肉,非物质文化遗产", 67 | OpeningHours: "09:00/21:30", IsNew: true, IsPremium: true, Imagepath: "", MinimumOrderAmount: 20, DeliveryFee: 5}, 68 | 69 | {Id: 487, Name: "北京酒家", Address: "北京市海淀区上下九商业步行街内", Longitude: 113.24826, Latitude: 23.11488, Phone: "13257482341", Status: 0, 70 | RecentOrderNum: 923, RatingCount: 871, Rating: 4.2, PromotionInfo: "北京第一家传承300年酒家", OpeningHours: "8:30/20:30", IsNew: true, IsPremium: true, Imagepath: "", 71 | MinimumOrderAmount: 20, DeliveryFee: 5}, 72 | 73 | {Id: 488, Name: "和平鸽饺子馆", Address: "北京市越秀区德政中路171", Longitude: 113.27521, Latitude: 23.12092, 74 | Phone: "17098764762", Status: 1, RecentOrderNum: 483, RatingCount: 273, Rating: 4.2, PromotionInfo: "吃饺子就来和平鸽饺子馆", OpeningHours: "8:30/20:30", 75 | IsNew: true, IsPremium: true, Imagepath: "", MinimumOrderAmount: 20, DeliveryFee: 5}} 76 | 77 | //多条数据-启用事务 78 | //事务 79 | session := Dbengine.NewSession() 80 | defer session.Close() 81 | 82 | //事务操作:开始-执行-回滚-提交 83 | err := session.Begin() 84 | if err != nil { 85 | fmt.Println(err.Error()) 86 | } 87 | for _, shop := range shops { 88 | _, err := session.Insert(&shop) 89 | if err != nil { 90 | session.Rollback() //回滚 91 | return 92 | } 93 | } 94 | err = session.Commit() 95 | if err != nil { 96 | fmt.Println(err.Error()) 97 | } 98 | 99 | } 100 | 101 | //初始化商品数据 102 | func InitGoodsData() { 103 | goods := []model.Goods{ 104 | {Id: 1, Name: "小小鲜肉包", Description: "滑蛋牛肉粥(1份)+小小鲜肉包(4只)", SellCount: 14, Price: 25, OldPrice: 29, ShopId: 1}, 105 | {Id: 2, Name: "滑蛋牛肉粥+小小鲜肉包", Description: "滑蛋牛肉粥(1份)+小小鲜肉包(3只)", SellCount: 6, Price: 35, OldPrice: 41, ShopId: 1}, 106 | {Id: 3, Name: "滑蛋牛肉粥+绿甘蓝馅饼", Description: "滑蛋牛肉粥(1份)+绿甘蓝馅饼(1张)", SellCount: 2, Price: 25, OldPrice: 30, ShopId: 1}, 107 | {Id: 4, Name: "茶香卤味蛋", Description: "咸鸡蛋", SellCount: 688, Price: 2.5, OldPrice: 3, ShopId: 1}, 108 | {Id: 5, Name: "韭菜鸡蛋馅饼(2张)", Description: "韭菜鸡蛋馅饼", SellCount: 381, Price: 10, OldPrice: 12, ShopId: 1}, 109 | {Id: 6, Name: "小小鲜肉包+豆浆套餐", Description: "小小鲜肉包(8只)装+豆浆(1杯)", SellCount: 335, Price: 9.9, OldPrice: 11.9, ShopId: 479}, 110 | {Id: 7, Name: "翠香炒素饼", Description: "咸鲜翠香素炒饼", SellCount: 260, Price: 17.9, OldPrice: 20.9, ShopId: 485}, 111 | {Id: 8, Name: "香煎鲜肉包", Description: "咸鲜猪肉鲜肉包", SellCount: 173, Price: 10.9, OldPrice: 12.9, ShopId: 486}} 112 | 113 | //多条数据-启用事务 114 | //事务 115 | session := Dbengine.NewSession() 116 | defer session.Close() 117 | 118 | //事务操作:开始-执行-回滚-提交 119 | err := session.Begin() 120 | if err != nil { 121 | fmt.Println(err.Error()) 122 | } 123 | for _, shop := range goods { 124 | _, err := session.Insert(&shop) 125 | if err != nil { 126 | session.Rollback() //回滚 127 | return 128 | } 129 | } 130 | err = session.Commit() 131 | if err != nil { 132 | fmt.Println(err.Error()) 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /tool/PasswordEncoder.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "crypto/md5" 5 | "crypto/sha256" 6 | "encoding/base64" 7 | "encoding/hex" 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | func EncoderSha256(data string) string { 13 | h := sha256.New() 14 | h.Write([]byte(data)) 15 | sum := h.Sum(nil) 16 | //由于是十六进制表示,因此需要进行转换 17 | s := hex.EncodeToString(sum) 18 | return string(s) 19 | } 20 | 21 | func Md5(data string) string { 22 | w := md5.New() 23 | io.WriteString(w, data) 24 | bydate := w.Sum(nil) 25 | result := fmt.Sprintf("%x", bydate) 26 | return result 27 | } 28 | 29 | func Base64Encode(data string) string { 30 | return base64.StdEncoding.EncodeToString([]byte(data)) 31 | } 32 | 33 | func Base64Decode(data string) ([]byte, error) { 34 | return base64.StdEncoding.DecodeString(data) 35 | } 36 | -------------------------------------------------------------------------------- /tool/RedisStore.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "log" 5 | "time" 6 | 7 | "github.com/go-redis/redis" 8 | "github.com/mojocn/base64Captcha" 9 | ) 10 | 11 | type RedisStore struct { 12 | client *redis.Client 13 | } 14 | 15 | var Redis_Store RedisStore 16 | 17 | func InitRedisStore() *RedisStore { 18 | config := GetConfig().RedisConfig 19 | client := redis.NewClient(&redis.Options{ 20 | Addr: config.Addr + ":" + config.Port, 21 | Password: config.Password, 22 | DB: config.Db, 23 | }) 24 | Redis_Store = RedisStore{client: client} 25 | base64Captcha.SetCustomStore(&Redis_Store) 26 | 27 | return &Redis_Store 28 | } 29 | 30 | //set 31 | func (rs *RedisStore) Set(id string, value string) { 32 | if err := rs.client.Set(id, value, time.Minute*10).Err(); err != nil { 33 | log.Println(err) 34 | } 35 | } 36 | 37 | //get 38 | func (rs *RedisStore) Get(id string, clear bool) string { 39 | val, err := rs.client.Get(id).Result() 40 | if err != nil { 41 | log.Println(err) 42 | return "" 43 | } 44 | if clear { 45 | if err := rs.client.Del(id).Err(); err != nil { 46 | log.Println(err) 47 | return "" 48 | } 49 | } 50 | 51 | return val 52 | } 53 | -------------------------------------------------------------------------------- /tool/SessionStore.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gin-contrib/sessions" 7 | "github.com/gin-contrib/sessions/redis" 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func InitSession(engine *gin.Engine) { 12 | config := GetConfig().RedisConfig 13 | store, err := redis.NewStore(10, "tcp", config.Addr+":"+config.Port, "", []byte("secret")) 14 | if err != nil { 15 | fmt.Println(err.Error()) 16 | } 17 | engine.Use(sessions.Sessions("mysession", store)) 18 | } 19 | 20 | //set session 21 | func SetSess(context *gin.Context, key interface{}, value interface{}) error { 22 | session := sessions.Default(context) //获取当前Session 23 | fmt.Println("key:", key, "value:", value) 24 | session.Set(key, value) 25 | fmt.Println("set session load") 26 | return session.Save() 27 | } 28 | 29 | //get session 30 | func GetSess(context *gin.Context, key interface{}) interface{} { 31 | session := sessions.Default(context) 32 | return session.Get(key) 33 | } 34 | --------------------------------------------------------------------------------