|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/go-chi/jwtauth/v5"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var tokenAuth *jwtauth.JWTAuth
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
tokenAuth = jwtauth.New("HS256", []byte("secret"), nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
type userInfo struct {
|
|
|
|
id uint
|
|
|
|
Name string
|
|
|
|
PhoneNumber string
|
|
|
|
Password string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *userInfo) Bind(r *Request) error {
|
|
|
|
if name, ok := r.Get("name"); ok && len(name) > 0 {
|
|
|
|
u.Name = name
|
|
|
|
} else {
|
|
|
|
return NewError(1, "缺少用户名称")
|
|
|
|
}
|
|
|
|
|
|
|
|
if phoneNumber, ok := r.Get("phone_number"); ok && len(phoneNumber) > 0 {
|
|
|
|
if len(phoneNumber) != 11 {
|
|
|
|
return NewError(2, "手机号码格式错误")
|
|
|
|
}
|
|
|
|
u.PhoneNumber = phoneNumber
|
|
|
|
} else {
|
|
|
|
return NewError(2, "缺少手机号码")
|
|
|
|
}
|
|
|
|
|
|
|
|
if password, ok := r.Get("password"); ok && len(password) > 0 {
|
|
|
|
if len(password) < 6 {
|
|
|
|
return NewError(2, "密码太短")
|
|
|
|
}
|
|
|
|
u.Password = password
|
|
|
|
} else {
|
|
|
|
return NewError(2, "缺少密码")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateUser 创建用户
|
|
|
|
func CreateUser(w *ResponseWriter, r *Request) {
|
|
|
|
var ui userInfo
|
|
|
|
if err := ui.Bind(r); err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
if err := DB.Model(&User{}).Where("phone_number = ?", ui.PhoneNumber).Count(&count).Error; err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if count > 0 {
|
|
|
|
w.Error(NewError(2, "手机号码已经被使用了"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
hash, err := HashPassword(ui.Password)
|
|
|
|
if err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Error(NewError(1, "加密密码失败"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
user := User{
|
|
|
|
Name: ui.Name,
|
|
|
|
PhoneNumber: ui.PhoneNumber,
|
|
|
|
Password: hash,
|
|
|
|
}
|
|
|
|
if err := DB.Create(&user).Error; err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
} else {
|
|
|
|
w.Ok(ui, "创建用户成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateUser 更新用户
|
|
|
|
func UpdateUser(w *ResponseWriter, r *Request) {
|
|
|
|
id := chi.URLParam(r.Request, "id")
|
|
|
|
if len(id) == 0 {
|
|
|
|
w.Error(NewError(1, "缺少用户ID"))
|
|
|
|
}
|
|
|
|
var ui userInfo
|
|
|
|
if err := ui.Bind(r); err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 查询用户信息
|
|
|
|
var user User
|
|
|
|
if err := DB.First(&user, "id = ?", id).Error; err != nil {
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
err = NewError(1, "用户不存在")
|
|
|
|
}
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 用户信息未发生变化
|
|
|
|
if ui.Name == user.Name && ui.PhoneNumber == user.PhoneNumber && CheckPasswordHash(ui.Password, user.Password) {
|
|
|
|
w.Ok(nil, "操作成功")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 检查手机号码是否被使用
|
|
|
|
var count int64
|
|
|
|
if err := DB.Model(&User{}).Where("phone_number = ? AND id != ?", ui.PhoneNumber, id).Count(&count).Error; err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if count > 0 {
|
|
|
|
w.Error(NewError(1, "手机号码已被使用"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 保存用户信息
|
|
|
|
user.Name = ui.Name
|
|
|
|
user.PhoneNumber = ui.PhoneNumber
|
|
|
|
user.Password = ui.Password
|
|
|
|
if err := DB.Save(&user).Error; err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
} else {
|
|
|
|
w.Ok(nil, "操作成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteUser 删除用户
|
|
|
|
func DeleteUser(w *ResponseWriter, r *Request) {
|
|
|
|
id := chi.URLParam(r.Request, "id")
|
|
|
|
if len(id) == 0 {
|
|
|
|
w.Error(NewError(1, "缺少用户ID"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// 查询用户信息
|
|
|
|
var user User
|
|
|
|
if err := DB.First(&user, "id = ?", id).Error; err != nil {
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
err = NewError(1, "用户不存在")
|
|
|
|
}
|
|
|
|
w.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 删除用户
|
|
|
|
if err := DB.Delete(&user).Error; err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Error(NewError(1, "删除用户失败"))
|
|
|
|
} else {
|
|
|
|
w.Ok(nil, "删除用户成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListUser 用户列表
|
|
|
|
func ListUser(w *ResponseWriter, r *Request) {
|
|
|
|
search := func(db *gorm.DB) *gorm.DB {
|
|
|
|
return db.
|
|
|
|
Model(&User{}).
|
|
|
|
Scopes(Search(r, "name", "name LIKE ?")).
|
|
|
|
Scopes(Paginate(r))
|
|
|
|
}
|
|
|
|
var userList []User
|
|
|
|
var total int64
|
|
|
|
var err error
|
|
|
|
if err = DB.Scopes(search).Count(&total).Error; err == nil {
|
|
|
|
err = DB.Scopes(search).Find(&userList).Error
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
w.Fail(http.StatusInternalServerError, 1, err.Error())
|
|
|
|
} else {
|
|
|
|
w.Ok(map[string]any{
|
|
|
|
"list": userList,
|
|
|
|
"total": total,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Login 用户登录
|
|
|
|
func Login(w *ResponseWriter, r *Request) {
|
|
|
|
var phoneNumber string
|
|
|
|
var password string
|
|
|
|
var token string
|
|
|
|
var ok bool
|
|
|
|
|
|
|
|
// 提交的手机号码
|
|
|
|
if phoneNumber, ok = r.Get("phone_number"); ok && len(phoneNumber) > 0 {
|
|
|
|
if len(phoneNumber) != 11 {
|
|
|
|
w.Error(NewError(2, "手机号码格式错误"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
w.Error(NewError(2, "缺少手机号码"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 提交的登陆密码
|
|
|
|
if password, ok = r.Get("password"); ok && len(password) > 0 {
|
|
|
|
if len(password) < 6 {
|
|
|
|
w.Error(NewError(2, "密码太短"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
w.Error(NewError(2, "缺少密码"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 提交的设备码
|
|
|
|
if token, ok = r.Get("token"); !ok || len(token) == 0 {
|
|
|
|
w.Error(NewError(2, "缺少设备码"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 查询用户是否存在
|
|
|
|
var user User
|
|
|
|
err := DB.First(&user, "phone_number = ?", phoneNumber).Error
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
w.Error(NewError(1, "手机号码或密码错误"))
|
|
|
|
} else if err != nil {
|
|
|
|
w.Error(err)
|
|
|
|
} else {
|
|
|
|
if !CheckPasswordHash(password, user.Password) {
|
|
|
|
w.Error(NewError(1, "手机号码或密码错误"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_, tokenString, err := tokenAuth.Encode(map[string]any{"uid": user.ID, "tkn": token})
|
|
|
|
if err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Error(NewError(1, "登录失败"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
w.Ok(map[string]any{
|
|
|
|
"user": user,
|
|
|
|
"token": tokenString,
|
|
|
|
}, "登录成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateGoods 创建商品
|
|
|
|
func CreateGoods(w *ResponseWriter, r *Request) {
|
|
|
|
name := r.Value("name")
|
|
|
|
price := r.Float32("price", 0)
|
|
|
|
if len(name) == 0 {
|
|
|
|
w.Fail(http.StatusBadRequest, 1, "商品名称错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if price <= 0 {
|
|
|
|
w.Fail(http.StatusBadRequest, 2, "商品价格错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var goods Goods
|
|
|
|
err := DB.First(&goods, "name = ?", name).Error
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
goods = Goods{
|
|
|
|
Name: name,
|
|
|
|
Price: price,
|
|
|
|
}
|
|
|
|
err = DB.Create(&goods).Error
|
|
|
|
if err != nil {
|
|
|
|
w.Fail(http.StatusBadRequest, 3, "创建商品失败")
|
|
|
|
} else {
|
|
|
|
w.Ok(goods)
|
|
|
|
}
|
|
|
|
} else if err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Fail(http.StatusBadRequest, 4, "商品价格错误")
|
|
|
|
} else {
|
|
|
|
w.Fail(http.StatusBadRequest, 5, "商品已经存在")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateGoods 更新产品信息
|
|
|
|
func UpdateGoods(w *ResponseWriter, r *Request) {
|
|
|
|
name := r.Value("name")
|
|
|
|
price := r.Float32("price", 0)
|
|
|
|
id := uint(r.Uint64("id", 0))
|
|
|
|
if len(name) == 0 {
|
|
|
|
w.Fail(http.StatusBadRequest, 1, "商品名称错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if price <= 0 {
|
|
|
|
w.Fail(http.StatusBadRequest, 2, "商品价格错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var goods Goods
|
|
|
|
err := DB.First(&goods, "id = ?", id).Error
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
w.Fail(http.StatusBadRequest, 2, "商品不存在")
|
|
|
|
} else if err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Fail(http.StatusBadRequest, 3, err.Error())
|
|
|
|
} else {
|
|
|
|
// 商品名称不能重复
|
|
|
|
err = DB.Where("id <> ?", id).First(&Goods{}, "name = ?", name).Error
|
|
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
LogError(err)
|
|
|
|
w.Fail(http.StatusBadRequest, 4, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if goods.Name != name || goods.Price != price {
|
|
|
|
goods.Name = name
|
|
|
|
goods.Price = price
|
|
|
|
err = DB.Save(&goods).Error
|
|
|
|
if err != nil {
|
|
|
|
LogError(err)
|
|
|
|
w.Fail(http.StatusBadRequest, 5, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w.Ok(goods, "修改成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetGoodsList 查询商品列表
|
|
|
|
func GetGoodsList(w *ResponseWriter, r *Request) {
|
|
|
|
search := func(db *gorm.DB) *gorm.DB {
|
|
|
|
return db.
|
|
|
|
Model(&Goods{}).
|
|
|
|
Scopes(TimeRange(r, "created_at")).
|
|
|
|
Scopes(Paginate(r)).
|
|
|
|
Scopes(Search(r, "name", "name LIKE ?"))
|
|
|
|
}
|
|
|
|
var goodsList []Goods
|
|
|
|
var total int64
|
|
|
|
var err error
|
|
|
|
if err = DB.Scopes(search).Count(&total).Error; err == nil {
|
|
|
|
err = DB.Scopes(search).Find(&goodsList).Error
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
w.Fail(http.StatusInternalServerError, 1, err.Error())
|
|
|
|
} else {
|
|
|
|
w.Ok(map[string]any{
|
|
|
|
"list": goodsList,
|
|
|
|
"total": total,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetGoodsPrices(w *ResponseWriter, r *Request) {
|
|
|
|
id := uint(r.Uint64("id", 0))
|
|
|
|
var goods Goods
|
|
|
|
if err := DB.Scopes(func(db *gorm.DB) *gorm.DB {
|
|
|
|
var queries []string
|
|
|
|
var args []any
|
|
|
|
if val, ok := r.Get("start_time"); ok {
|
|
|
|
queries = append(queries, "created_at >= ?")
|
|
|
|
args = append(args, val)
|
|
|
|
}
|
|
|
|
if val, ok := r.Get("end_time"); ok {
|
|
|
|
queries = append(queries, "created_at <= ?")
|
|
|
|
args = append(args, val)
|
|
|
|
}
|
|
|
|
if len(queries) == 0 {
|
|
|
|
return db.Preload("Prices")
|
|
|
|
}
|
|
|
|
args = append([]any{strings.Join(queries, " AND ")}, args...)
|
|
|
|
return db.Preload("Prices", args...)
|
|
|
|
}).First(&goods, "id = ?", id).Error; err != nil {
|
|
|
|
w.Fail(http.StatusInternalServerError, 1, err.Error())
|
|
|
|
} else {
|
|
|
|
w.Ok(goods)
|
|
|
|
}
|
|
|
|
}
|