13451294168 1 year ago
parent 686be8e74a
commit 678dfa9bcd

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/go_fabric.iml" filepath="$PROJECT_DIR$/.idea/go_fabric.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -0,0 +1,21 @@
package v1
import (
"encoding/json"
"go_fabric/serializer"
)
func ErrorResponse(err error) serializer.Response {
if _, ok := err.(*json.UnmarshalTypeError); ok {
return serializer.Response{
Status: 400,
Msg: "JSON类型不匹配",
Error: err.Error(),
}
}
return serializer.Response{
Status: 400,
Msg: "参数错误",
Error: err.Error(),
}
}

@ -0,0 +1,20 @@
package v1
import (
"go_fabric/pkg/util"
"go_fabric/service"
"net/http"
"github.com/gin-gonic/gin"
)
func PoemGet(c *gin.Context) {
var userRegister service.UserService
if err := c.ShouldBind(&userRegister); err == nil {
res := userRegister.Register(c.Request.Context())
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}

@ -0,0 +1,80 @@
package v1
import (
"go_fabric/pkg/util"
"go_fabric/service"
"net/http"
"github.com/gin-gonic/gin"
)
func UserRegister(c *gin.Context) {
var userRegister service.UserService
if err := c.ShouldBind(&userRegister); err == nil {
res := userRegister.Register(c.Request.Context())
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}
func UserLogin(c *gin.Context) {
var userLogin service.UserService
if err := c.ShouldBind(&userLogin); err == nil {
res := userLogin.Login(c.Request.Context())
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}
func UserUpdate(c *gin.Context) {
var userUpdate service.UserService
claims, _ := util.ParseToken(c.GetHeader("Authorization"))
if err := c.ShouldBind(&userUpdate); err == nil {
res := userUpdate.Update(c.Request.Context(), claims.ID)
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}
func UpdateAvatar(c *gin.Context) {
file, fileHeader, _ := c.Request.FormFile("file")
fileSize := fileHeader.Size
var updateAvatar service.UserService
claims, _ := util.ParseToken(c.GetHeader("Authorization"))
if err := c.ShouldBind(&updateAvatar); err == nil {
res := updateAvatar.Post(c.Request.Context(), claims.ID, file, fileSize)
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}
func SendEmail(c *gin.Context) {
var sendEmail service.SendEmailService
claims, _ := util.ParseToken(c.GetHeader("Authorization"))
if err := c.ShouldBind(&sendEmail); err == nil {
res := sendEmail.Send(c.Request.Context(), claims.ID)
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}
func ValidEmail(c *gin.Context) {
var validEmail service.ValidEmailService
if err := c.ShouldBind(&validEmail); err == nil {
res := validEmail.Valid(c.Request.Context(), c.GetHeader("Authorization"))
c.JSON(http.StatusOK, res)
} else {
c.JSON(http.StatusBadRequest, ErrorResponse(err)) //400参数错误
util.LoggerObj.Error(err)
}
}

@ -0,0 +1,47 @@
package cache
import (
"fmt"
"strconv"
"github.com/go-redis/redis"
"gopkg.in/ini.v1"
)
var (
RedisClient *redis.Client
RedisDb string
RedisAddr string
RedisPw string
RedisDbName string
)
func Init() {
file, err := ini.Load("C:/Users/801028/Desktop/marketv1.2/go_fabric/conf/config.ini")
if err != nil {
fmt.Println("redis config err", err)
}
LoadRedisData(file)
Redis()
}
func LoadRedisData(file *ini.File) {
RedisDb = file.Section("redis").Key("RedisDb").String()
RedisAddr = file.Section("redis").Key("RedisAddr").String()
RedisPw = file.Section("redis").Key("RedisPw").String()
RedisDbName = file.Section("redis").Key("RedisDbName").String()
}
func Redis() {
db, _ := strconv.ParseUint(RedisDbName, 10, 64)
client := redis.NewClient(&redis.Options{
Addr: RedisAddr,
//Password
DB: int(db),
})
_, err := client.Ping().Result()
if err != nil {
panic(err)
}
RedisClient = client
}

@ -0,0 +1,14 @@
package cache
import (
"fmt"
"strconv"
)
const (
RankKey = "rank" //排名
)
func ProductViewKey(id uint) string{
return fmt.Sprintf("view:product:%s",strconv.Itoa(int(id)))
}

@ -0,0 +1,14 @@
package main
import (
// "go_fabric/cache"
"go_fabric/conf"
"go_fabric/routes"
)
func main() {
conf.Init()
// cache.Init()
r := routes.NewRouter()
_ = r.Run(conf.HttpPort)
}

@ -0,0 +1,86 @@
package conf
import (
"go_fabric/dao"
"strings"
"gopkg.in/ini.v1"
)
var (
AppModel string
HttpPort string
Db string
DbHost string
DbPort string
DbUser string
DbPassword string
DbName string
RedisDb string
RedisAddr string
RedisPw string
RedisDbName string
ValidEmail string
SmtpHost string
SmtpEmail string
SmtpPass string
Host string
ProductPath string
AvatarPath string
)
func Init() {
//从本地文件读取环境变量
file, err := ini.Load("C:/Users/801028/Desktop/marketv1.2/go_fabric/conf/config.ini")
if err != nil {
panic(err)
}
LoadServer(file)
LoadMySql(file)
LoadRedis(file)
LoadEmail(file)
// mysql读
LoadPhotoPath(file)
PathRead := strings.Join([]string{DbUser, ":", DbPassword, "@tcp(", DbHost, ":", DbPort, ")/", DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "")
//写
PathWrite := strings.Join([]string{DbUser, ":", DbPassword, "@tcp(", DbHost, ":", DbPort, ")/", DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "")
dao.Database(PathRead, PathWrite)
}
func LoadServer(file *ini.File) {
AppModel = file.Section("service").Key("AppMode").String()
HttpPort = file.Section("service").Key("HttpPort").String()
}
func LoadMySql(file *ini.File) {
Db = file.Section("mysql").Key("DB").String()
DbHost = file.Section("mysql").Key("DbHost").String()
DbPort = file.Section("mysql").Key("DbPort").String()
DbUser = file.Section("mysql").Key("DbUser").String()
DbPassword = file.Section("mysql").Key("DbPassword").String()
DbName = file.Section("mysql").Key("DbName").String()
}
func LoadRedis(file *ini.File) {
RedisDb = file.Section("redis").Key("RedisDb").String()
RedisAddr = file.Section("redis").Key("RedisAddr").String()
RedisPw = file.Section("redis").Key("RedisPw").String()
RedisDbName = file.Section("redis").Key("RedisDbName").String()
}
func LoadEmail(file *ini.File) {
ValidEmail = file.Section("email").Key("ValidEmail").String()
SmtpHost = file.Section("email").Key("SmtpHost").String()
SmtpEmail = file.Section("email").Key("SmtpEmail").String()
SmtpPass = file.Section("email").Key("SmtpPass").String()
}
func LoadPhotoPath(file *ini.File) {
Host = file.Section("path").Key("Host").String()
ProductPath = file.Section("path").Key("ProductPath").String()
AvatarPath = file.Section("path").Key("AvatarPath").String()
}

@ -0,0 +1,36 @@
[service]
AppMode = debug
HttpPort = :3000
[mysql]
DB = mysql
DbHost = 127.0.0.1
DbPort = 3306
DbUser = root
DbPassword = 240011@rbb
DbName = poem
[redis]
RedisDb = redis
RedisAddr = 127.0.0.1:6379
RedisPw =
RedisDbName = 2
[qiniu]
AccessKey =
SecretKey =
Bucket =
QiniuServer =
[email]
ValidEmail = http://localhost:8080/#/vaild/email/
SmtpHost = smtp.qq.com
SmtpEmail = 1065109019@qq.com
; 管理员邮箱
SmtpPass = coziejecpksvbbcf
; 授权码
[path]
Host = http://127.0.0.1
ProductPath =C:/Users/801028/Desktop/marketv1.2/go_fabric/static/imags/Product/
AvatarPath =C:/Users/801028/Desktop/marketv1.2/static/imags/avatar/

@ -0,0 +1,61 @@
package dao
import (
"context"
"time"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
var _db *gorm.DB
func Database(connRead, connWrite string) {
var ormLogger logger.Interface
if gin.Mode() == "debug" {
ormLogger = logger.Default.LogMode(logger.Info)
} else {
ormLogger = logger.Default
}
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: connRead,
DefaultStringSize: 256, //string类型字段默认长度
DisableDatetimePrecision: true, //禁止datatime精度
DontSupportRenameIndex: true, //重命名索引,需要先删除索引再重建
DontSupportRenameColumn: true, //用change重命名列mysql 8之前不支持
SkipInitializeWithVersion: false,
}), &gorm.Config{
Logger: ormLogger,
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
})
if err != nil {
return
}
sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(20) //设置连接池
sqlDB.SetMaxOpenConns(100) //打开连接数
sqlDB.SetConnMaxLifetime(time.Second * 30)
_db = db
// 主从配置
_ = _db.Use(dbresolver.
Register(dbresolver.Config{
Sources: []gorm.Dialector{mysql.Open(connWrite)}, //写操作
Replicas: []gorm.Dialector{mysql.Open(connRead), mysql.Open(connRead)}, //读操作
Policy: dbresolver.RandomPolicy{},
}))
//数据库迁移
migration()
}
func NewDBClient(ctx context.Context) *gorm.DB {
db := _db
return db.WithContext(ctx)
}

@ -0,0 +1,17 @@
package dao
import (
"fmt"
"go_fabric/model"
)
func migration() {
err := _db.Set("gorm:table_options", "charset=utf8mb4").
AutoMigrate(
&model.Poem{},
)
if err != nil {
fmt.Println("err", err)
}
return
}

@ -0,0 +1,64 @@
package dao
import (
"context"
"go_fabric/model"
"gorm.io/gorm"
)
type UserDao struct {
*gorm.DB
}
func NewUserDao(ctx context.Context) *UserDao {
return &UserDao{NewDBClient(ctx)}
}
func NewUserDaoDB(db *gorm.DB) *UserDao {
return &UserDao{db}
}
// 是否存在该用户名用户
func (dao *UserDao) ExistOrNotByUserName(userName string) (user *model.User, exist bool, err error) {
var count int64
err = dao.DB.Model(&model.User{}).Where("user_name=?", userName).Find(&user).Count(&count).Error
if count == 0 {
return nil, false, err
}
return user, true, nil
}
// 添加用户
func (dao *UserDao) CreateUser(user *model.User) error {
return dao.DB.Model(&model.User{}).Create(&user).Error
}
// 根据Id寻找用户
func (dao *UserDao) GetUserById(id uint) (user *model.User, err error) {
err = dao.DB.Model(&model.User{}).Where("id=?", id).First(&user).Error
return
}
// 查询所有用户 列表
// offset表示偏移量pageSize表示每页数据量pageNum表示当前查询的页码数
func (dao *UserDao) ListUser(pageNum int, pageSize int) (users []model.User, err error) {
offset := (pageNum - 1) * pageSize
err = dao.DB.Model(&model.User{}).Offset(offset).Limit(pageSize).Find(&users).Error
return
}
// 根据id修改用户信息
func (dao *UserDao) UpdateUserById(uId uint, user *model.User) error {
return dao.DB.Model(&model.User{}).Where("id=?", uId).Updates(&user).Error
}
// 根据用户名删除用户
func (dao *UserDao) DeleteByUserName(user *model.User) error {
return dao.DB.Delete(&user).Error
}
// 封禁用户
func (dao *UserDao) PassiveByUserName(uId uint) error {
return dao.DB.Model(&model.User{}).Where("id=?", uId).Update("status", "passive").Error
}

@ -0,0 +1,44 @@
module go_fabric
go 1.20
require github.com/gin-gonic/gin v1.9.1
require (
github.com/bytedance/sonic v1.9.2 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/go-redis/redis v6.15.9+incompatible // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/mail.v2 v2.3.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.1 // indirect
gorm.io/gorm v1.25.2 // indirect
gorm.io/plugin/dbresolver v1.4.1 // indirect
)

@ -0,0 +1,109 @@
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.2 h1:GDaNjuWSGu09guE9Oql0MSTNhNCLlWwO8y/xM5BzcbM=
github.com/bytedance/sonic v1.9.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/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/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
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.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/plugin/dbresolver v1.4.1 h1:Ug4LcoPhrvqq71UhxtF346f+skTYoCa/nEsdjvHwEzk=
gorm.io/plugin/dbresolver v1.4.1/go.mod h1:CTbCtMWhsjXSiJqiW2R8POvJ2cq18RVOl4WGyT5nhNc=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

@ -0,0 +1,45 @@
package middleware
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
// 跨域
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method //请求方法
origin := c.Request.Header.Get("Origin") //请求头部
var headerKeys []string // 声明请求头keys
for k := range c.Request.Header {
headerKeys = append(headerKeys, k)
}
headerStr := strings.Join(headerKeys, ", ")
if headerStr != "" {
headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
} else {
headerStr = "access-control-allow-origin, access-control-allow-headers"
}
if origin != "" {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Origin", "*") // 这是允许访问所有域
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
// header的类型
c.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")
// 允许跨域设置 可以返回其他子段
c.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") // 跨域关键设置 让浏览器可以解析
c.Header("Access-Control-Max-Age", "172800") // 缓存请求信息 单位为秒
c.Header("Access-Control-Allow-Credentials", "false") // 跨域请求是否需要带cookie信息 默认设置为true
c.Set("content-type", "application/json") // 设置返回格式是json
}
//放行所有OPTIONS方法
if method == "OPTIONS" {
c.JSON(http.StatusOK, "Options Request!")
}
// 处理请求
c.Next() // 处理请求
}
}

@ -0,0 +1,36 @@
package middleware
import (
"github.com/gin-gonic/gin"
"go_fabric/pkg/e"
"go_fabric/pkg/util"
"time"
)
func JWT() gin.HandlerFunc {
return func(c *gin.Context) {
var code int
//var data interface{}
code = 200
token := c.GetHeader("Authorization")
if token == "" {
code = 404
} else {
claims, err := util.ParseToken(token)
if err != nil {
code = e.ErrorToken
} else if time.Now().Unix() > claims.ExpiresAt {
code = e.ErrorCheckTokenTimeOut
}
}
if code != e.Success {
c.JSON(200, gin.H{
"status": code,
"msg": e.GetMsg(code),
})
c.Abort()
return
}
c.Next()
}
}

@ -0,0 +1,9 @@
package model
import "gorm.io/gorm"
type Poem struct {
gorm.Model
Id uint `gorm:"not null"`
Content string
}

@ -0,0 +1,29 @@
package e
const (
Success = 200
Error = 500
InvalidParams = 400
//user模块错误
ErrorExistUser = 30001
ErrorFailEncryption = 30002
NullPassword = 30003
UserNotFind = 30004
ErrorPassword = 30005
ErrorToken = 30006
ErrorCheckTokenTimeOut = 30007
ErrorUploadFail = 30008
ErrorSendEmail = 30009
ErrorNotActive = 30010
//product模块错误
ErrorProductImgUpload = 40001
ProductNotFind = 40002
ErrorBossForProduct = 40003
ErrorNotSale = 40004
ErrorProductNum = 40005
//收藏夹模块
ErrorFavoriteExist = 50001
)

@ -0,0 +1,39 @@
package e
var MsgFlags = map[int]string{
Success: "ok",
Error: "fail",
InvalidParams: "参数错误",
//user模块错误
ErrorExistUser: "用户已存在",
NullPassword: "密码不能为空",
ErrorFailEncryption: "密码加密失败",
UserNotFind: "用户不存在",
ErrorPassword: "密码错误",
ErrorToken: "token验证失败",
ErrorCheckTokenTimeOut: "token过期",
ErrorUploadFail: "图片上传失败",
ErrorSendEmail: "邮件发送失败",
ErrorNotActive: "用户未激活",
//product模块错误
ErrorProductImgUpload: "商品图片上传失败",
ProductNotFind: "商品不存在",
ErrorBossForProduct: "商品与商户不匹配",
ErrorNotSale: "商品不在售",
ErrorProductNum: "商品数量错误",
//收藏夹模块
ErrorFavoriteExist: "收藏夹已存在",
}
// GetMsg 获取状态码对应信息
func GetMsg(code int) string {
msg, ok := MsgFlags[code]
if !ok {
return MsgFlags[Error]
} else {
return msg
}
}

@ -0,0 +1,88 @@
package util
import (
"bytes"
"crypto/aes"
"encoding/base64"
"errors"
)
var Encrypt *Encryption
// AES 加密算法
type Encryption struct {
key string
}
func init() {
Encrypt = NewEncryption()
}
func NewEncryption() *Encryption {
return &Encryption{}
}
// 填充密码长度
func PadPwd(srcByte []byte, blockSize int) []byte {
padNum := blockSize - len(srcByte)%blockSize
ret := bytes.Repeat([]byte{byte(padNum)}, padNum)
srcByte = append(srcByte, ret...)
return srcByte
}
// 加密
func (k *Encryption) AesEncoding(src string) string {
srcByte := []byte(src)
block, err := aes.NewCipher([]byte(k.key))
if err != nil {
return src
}
// 密码填充
NewSrcByte := PadPwd(srcByte, block.BlockSize()) //由于字节长度不够,所以要进行字节的填充
dst := make([]byte, len(NewSrcByte))
block.Encrypt(dst, NewSrcByte)
// base64 编码
pwd := base64.StdEncoding.EncodeToString(dst)
return pwd
}
// 去掉填充的部分
func UnPadPwd(dst []byte) ([]byte, error) {
if len(dst) <= 0 {
return dst, errors.New("长度有误")
}
// 去掉的长度
unpadNum := int(dst[len(dst)-1])
strErr := "error"
op := []byte(strErr)
if len(dst) < unpadNum {
return op, nil
}
str := dst[:(len(dst) - unpadNum)]
return str, nil
}
// 解密
func (k *Encryption) AesDecoding(pwd string) string {
pwdByte := []byte(pwd)
pwdByte, err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return pwd
}
block, errBlock := aes.NewCipher([]byte(k.key))
if errBlock != nil {
return pwd
}
dst := make([]byte, len(pwdByte))
block.Decrypt(dst, pwdByte)
dst, err = UnPadPwd(dst) // 填充的要去掉
if err != nil {
return "0"
}
return string(dst)
}
// set方法
func (k *Encryption) SetKey(key string) {
k.key = key
}

@ -0,0 +1,87 @@
package util
import (
"github.com/dgrijalva/jwt-go"
"time"
)
var jwtSecret = []byte("test")
// 用户唯一token信息类
type Claims struct {
ID uint `json:"id"`
UserName string `json:"user_name"`
Authority int `json:"authority"` //权限
jwt.StandardClaims
}
// token分发
func GenerateToken(id uint, userName string, authority int) (string, error) {
nowTime := time.Now()
endTime := nowTime.Add(24 * time.Hour)
claims := Claims{
ID: id,
UserName: userName,
Authority: authority,
StandardClaims: jwt.StandardClaims{
ExpiresAt: endTime.Unix(),
Issuer: "test-mall",
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) //哈希256加密
token, err := tokenClaims.SignedString(jwtSecret) //数字签名
return token, err
}
// token验证
func ParseToken(token string) (*Claims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if tokenClaims != nil {
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
}
type EmailClaims struct {
UserID uint `json:"user_id"`
Email string `json:"email"`
Password string `json:"password"`
OperationType uint `json:"operation_type"`
jwt.StandardClaims
}
// 签发email token
func GenerateEmailToken(userId, Operation uint, email, password string) (string, error) {
nowTime := time.Now()
endTime := nowTime.Add(24 * time.Hour)
claims := EmailClaims{
UserID: userId,
Email: email,
Password: password,
OperationType: Operation,
StandardClaims: jwt.StandardClaims{
ExpiresAt: endTime.Unix(),
Issuer: "test-mall",
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) //哈希256加密
token, err := tokenClaims.SignedString(jwtSecret) //数字签名
return token, err
}
// 解密email token
func ParseEmailToken(token string) (*EmailClaims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &EmailClaims{}, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if tokenClaims != nil {
if claims, ok := tokenClaims.Claims.(*EmailClaims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
}

@ -0,0 +1,59 @@
package util
import (
"github.com/sirupsen/logrus"
"log"
"os"
"path"
"time"
)
// 日志打印
var LoggerObj *logrus.Logger
func init() {
src, _ := setOutPutFile()
if LoggerObj != nil {
LoggerObj.Out = src
return
}
//实例化
logger := logrus.New()
logger.Out = src //设置输出
logger.SetLevel(logrus.DebugLevel) //设置日志级别
logger.SetFormatter(&logrus.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
LoggerObj = logger
}
func setOutPutFile() (*os.File, error) {
now := time.Now()
logFilePath := ""
if dir, err := os.Getwd(); err == nil { //工作目录下
logFilePath = dir + "/logs/"
}
_, err := os.Stat(logFilePath)
if os.IsNotExist(err) {
if err = os.MkdirAll(logFilePath, 0777); err != nil {
log.Println(err.Error())
return nil, err
}
}
logFileName := now.Format("2006-1-02") + ".log"
//日志文件
fileName := path.Join(logFilePath, logFileName)
_, err = os.Stat(fileName)
if os.IsNotExist(err) {
if err = os.MkdirAll(fileName, 0777); err != nil {
log.Println(err.Error())
return nil, err
}
}
// 写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
return nil, err
}
return src, nil
}

@ -0,0 +1,40 @@
package routes
import (
api "go_fabric/api/v1"
"go_fabric/middleware"
"net/http"
"github.com/gin-gonic/gin"
)
func NewRouter() *gin.Engine {
r := gin.Default()
r.Use(middleware.Cors())
r.StaticFS("/static", http.Dir("C:/Users/801028/Desktop/marketv1.2/go_fabric/static/"))
// jr.StaticFile("/avatar.jpg", "/GOCODE/go_fabric/static/imags/avatar/avatar.jpg")
v1 := r.Group("api/v1")
{
v1.GET("ping", func(ctx *gin.Context) {
ctx.JSON(200, "success")
})
//获取诗词
v1.GET("poem/gain", api.PoemGet)
//用户操作
v1.POST("user/register", api.UserRegister)
v1.POST("user/login", api.UserLogin)
authed := v1.Group("/") //登录保护
authed.Use(middleware.JWT())
{
// 用户操作
authed.PUT("user", api.UserUpdate) //用户信息更新
authed.POST("avatar", api.UpdateAvatar) //用户上传头像
authed.POST("user/send-email", api.SendEmail) //发送验证邮件
authed.POST("user/valid-email", api.ValidEmail) //绑定邮箱
}
}
return r
}

@ -0,0 +1,39 @@
package serializer
type Response struct {
Status int `json:"status"`
Data interface{} `json:"data"`
Msg string `json:"msg"`
Error string `json:"error"`
}
type TokenData struct {
User interface{} `json:"user"`
Token string `json:"tokens"`
}
type AdminToken struct {
Admin interface{} `json:"admin"`
Token string `json:"tokens"`
}
type BossToken struct {
Boss interface{} `json:"boss"`
Token string `json:"tokens"`
}
type DataList struct {
Item interface{} `json:"item"`
Total uint `json:"total"`
}
func BuildListResponse(items interface{}, total uint) Response {
return Response{
Status: 200,
Data: DataList{
Item: items,
Total: total,
},
Msg: "ok",
}
}

@ -0,0 +1,26 @@
package serializer
import (
"go_fabric/model"
)
// Vo 向前端展示
type PoemVo struct {
Id uint `json:"id"`
Content string `json:"content"`
}
func BuildUser(poem *model.Poem) PoemVo {
return PoemVo{
Id: poem.Id,
Content: poem.Content,
}
}
func BuildUsers(items []model.Poem) (users []PoemVo) {
for _, item := range items {
poem := BuildUser(&item)
poems = append(poems, poem)
}
return poems
}

@ -0,0 +1,379 @@
package service
import (
"context"
"fmt"
"go_fabric/conf"
"go_fabric/dao"
"go_fabric/model"
"go_fabric/pkg/e"
"go_fabric/pkg/util"
"go_fabric/serializer"
"mime/multipart"
"strings"
"time"
"gopkg.in/mail.v2"
)
type UserService struct {
NickName string `json:"nick_name" form:"nick_name"`
UserName string `json:"user_name" form:"user_name"`
Password string `json:"password" form:"password"`
Key string `json:"key" form:"key"` //加密密钥
}
type SendEmailService struct {
Email string `json:"email" form:"email"`
Password string `json:"password"`
OperationType uint `json:"operation_type" form:"operation_type"` // 1.绑定邮箱 2.解绑邮箱 3.更改密码
}
type ValidEmailService struct {
}
// 注册
func (service *UserService) Register(ctx context.Context) serializer.Response {
var user model.User
code := e.Success
if service.Key == "" || len(service.Key) != 6 {
code = e.Error
return serializer.Response{
Status: code,
Data: nil,
Msg: e.GetMsg(code),
Error: "密钥长度不符",
}
}
util.Encrypt.SetKey(service.Key)
userDao := dao.NewUserDao(ctx)
_, exist, err := userDao.ExistOrNotByUserName(service.UserName)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
if exist {
code = e.ErrorExistUser
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
user = model.User{
UserName: service.UserName,
NickName: service.NickName,
Avatar: "avatar.JPG",
Status: model.Active,
Money: "1000",
Vip: 0,
}
//密码是否为空
if service.Password == "" {
code = e.NullPassword
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
//密码加密
if err = user.SetPassword(service.Password); err != nil {
util.LoggerObj.Error(err)
code = e.ErrorFailEncryption
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
//创建用户
err = userDao.CreateUser(&user)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
// 登录
func (service *UserService) Login(ctx context.Context) serializer.Response {
var user *model.User
code := e.Success
userDao := dao.NewUserDao(ctx)
//检查用户是否存在
user, exist, err := userDao.ExistOrNotByUserName(service.UserName)
if !exist || err != nil {
util.LoggerObj.Error(err)
code = e.UserNotFind
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: "用户不存在,请先注册",
}
}
//验证密码是否正确
if user.CheckPassword(service.Password) == false {
code = e.ErrorPassword
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: "密码错误,请重新输入",
}
}
//分发token
token, err := util.GenerateToken(user.ID, service.UserName, 0)
if err != nil {
util.LoggerObj.Error(err)
code = e.ErrorToken
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: "token验证失败",
}
}
return serializer.Response{
Status: code,
Data: serializer.TokenData{User: serializer.BuildUser(user), Token: token},
Msg: e.GetMsg(code),
}
}
// 用户修改信息
func (service *UserService) Update(ctx context.Context, uId uint) serializer.Response {
var user *model.User
var err error
code := e.Success
//寻找用户
userDao := dao.NewUserDao(ctx)
user, err = userDao.GetUserById(uId)
//检查用户状态
if user.Status == "passive" {
code = e.ErrorNotActive
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: "用户没有激活,没有权限",
}
}
//修改昵称nickname
if service.NickName != "" {
user.NickName = service.NickName
}
err = userDao.UpdateUserById(uId, user)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: serializer.BuildUser(user),
}
}
// 头像更新
func (service *UserService) Post(ctx context.Context, uId uint, file multipart.File, fileSize int64) serializer.Response {
code := e.Success
var user *model.User
var err error
userDao := dao.NewUserDao(ctx)
user, err = userDao.GetUserById(uId)
if user.Status == "passive" {
code = e.ErrorNotActive
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: "用户没有激活,没有权限",
}
}
if err != nil {
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
//保存图片到本地
path, err := UploadAvatarLocalStatic(file, uId, user.UserName)
if err != nil {
code = e.ErrorUploadFail
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
user.Avatar = path
err = userDao.UpdateUserById(uId, user)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: serializer.BuildUser(user),
}
}
// 发送验证邮件
func (service *SendEmailService) Send(ctx context.Context, uId uint) serializer.Response {
code := e.Success
var address string
var notice *model.Notice // 绑定邮箱,修改密码 模板通知
userDao := dao.NewUserDao(ctx)
user, err := userDao.GetUserById(uId)
//检查用户状态
if user.Status == "passive" {
code = e.ErrorNotActive
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: "用户没有激活,没有权限",
}
}
token, err := util.GenerateEmailToken(uId, service.OperationType, service.Email, service.Password)
if err != nil {
util.LoggerObj.Error(err)
code = e.ErrorToken
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
noticeDao := dao.NewNoticeDao(ctx)
notice, err = noticeDao.GetNoticeById(service.OperationType)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
address = conf.ValidEmail + token //发送者
mailStr := notice.Text
mailText := strings.Replace(mailStr, "+", address, -1)
fmt.Println(mailText)
m := mail.NewMessage()
m.SetHeader("From", conf.SmtpEmail) //管理员邮箱
m.SetHeader("To", service.Email) //验证者邮箱
m.SetHeader("Subject", "fabric_mall")
m.SetBody("text/html", mailText)
d := mail.NewDialer(conf.SmtpHost, 465, conf.SmtpEmail, conf.SmtpPass)
d.StartTLSPolicy = mail.MandatoryStartTLS
if err = d.DialAndSend(m); err != nil {
util.LoggerObj.Error(err)
code = e.ErrorSendEmail
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Error: err.Error(),
}
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
// 验证邮箱
func (service *ValidEmailService) Valid(ctx context.Context, token string) serializer.Response {
var userId uint
var email string
var password string
var operationType uint
code := e.Success
//验证token
if token == "" {
code = e.InvalidParams
} else {
claims, err := util.ParseEmailToken(token)
if err != nil {
util.LoggerObj.Error(err)
code = e.ErrorToken
} else if time.Now().Unix() > claims.ExpiresAt {
code = e.ErrorCheckTokenTimeOut
} else {
userId = claims.UserID
email = claims.Email
password = claims.Password
operationType = claims.OperationType
}
}
if code != e.Success {
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
// token解析成功获取用户信息
userDao := dao.NewUserDao(ctx)
user, err := userDao.GetUserById(userId)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
if operationType == 1 { //1.绑定邮箱
user.Email = email
} else if operationType == 2 { //2.解绑邮箱
user.Email = ""
} else if operationType == 3 { //3.修改密码
err = user.SetPassword(password)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
}
err = userDao.UpdateUserById(userId, user)
if err != nil {
util.LoggerObj.Error(err)
code = e.Error
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
}
}
return serializer.Response{
Status: code,
Msg: e.GetMsg(code),
Data: serializer.BuildUser(user),
}
}

@ -0,0 +1,17 @@
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/index", func(ctx *gin.Context) {
ctx.String(200, "hellpo_world")
})
router.StaticFile("/avatar.jpg", "/gocode/go_fabric/static/imags/avatar/avatar.jpg")
router.Run(":8080")
}
Loading…
Cancel
Save