feat: user & article: dev complete
This commit is contained in:
@@ -1,37 +1,49 @@
|
||||
package article
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/utils"
|
||||
)
|
||||
|
||||
func GetArticleList() *[]models.BackArticle {
|
||||
var articles []models.BackArticle
|
||||
global.Db.Omit("content").Find(&articles)
|
||||
return &articles
|
||||
//ListPublishedArticles list the articles published, use to show the articles to all people
|
||||
func ListPublishedArticles() *[]map[string]interface{} {
|
||||
article := models.ListField[models.BackArticle]([]map[string]interface{}{{"is_publish": 0}}, true, "content")
|
||||
if *article == nil {
|
||||
article = &[]map[string]interface{}{}
|
||||
}
|
||||
return article
|
||||
}
|
||||
|
||||
func SaveArticle(article *models.BackArticle) (ok bool) {
|
||||
return utils.Upsert(article)
|
||||
//ListAllArticles list all articles, will show the articles not published of the user
|
||||
// TODO: need only show the user's not published article
|
||||
func ListAllArticles() *[]map[string]interface{} {
|
||||
article := models.ListField[models.BackArticle]([]map[string]interface{}{{}}, true, "content")
|
||||
if *article == nil {
|
||||
article = &[]map[string]interface{}{}
|
||||
}
|
||||
return article
|
||||
}
|
||||
|
||||
//SaveArticle save the articles
|
||||
func SaveArticle(article map[string]interface{}) (ok bool) {
|
||||
models.BeforeSave(article, -1)
|
||||
ok, rows := models.Upsert[models.BackArticle](article)
|
||||
return ok && rows != 0
|
||||
}
|
||||
|
||||
//DeleteArticle delete article by id
|
||||
func DeleteArticle(id int) (ok bool) {
|
||||
tx := global.Db.Delete(&models.BackArticle{}, id)
|
||||
if tx.Error != nil {
|
||||
panic(tx.Error)
|
||||
}
|
||||
if tx.RowsAffected == 0 {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
ok, rowsAffected := models.DeleteById[models.BackArticle](id)
|
||||
return ok && rowsAffected != 0
|
||||
}
|
||||
|
||||
func GetArticleById(id int) *models.BackArticle {
|
||||
var article models.BackArticle
|
||||
tx := global.Db.Limit(1).Find(&article, id)
|
||||
if tx.RowsAffected == 0 {
|
||||
return nil
|
||||
}
|
||||
return &article
|
||||
//GetArticleById get an article
|
||||
func GetArticleById(id int) map[string]interface{} {
|
||||
return models.Get[models.BackArticle]([]map[string]interface{}{{"id": id}})
|
||||
}
|
||||
|
||||
//PublishArticle publish an article
|
||||
func PublishArticle(id int) (ok bool) {
|
||||
colMap := map[string]interface{}{"id": id, "is_publish": 1}
|
||||
ok, rowsAffected := models.Upsert[models.BackArticle](colMap)
|
||||
return ok && rowsAffected != 0
|
||||
}
|
||||
|
||||
140
service/user/user.go
Normal file
140
service/user/user.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/google/uuid"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/utils"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
EMAIL_CODE_REDIS_KEY = "verify_code_"
|
||||
)
|
||||
|
||||
// Login if login success, will return token
|
||||
func Login(user map[string]interface{}) (token string) {
|
||||
account := user["account"].(string)
|
||||
var queryMap []map[string]interface{}
|
||||
if strings.Contains(account, "@") {
|
||||
queryMap = append(queryMap, map[string]interface{}{"email": account})
|
||||
} else {
|
||||
queryMap = append(queryMap, map[string]interface{}{"phone": account})
|
||||
}
|
||||
userInfo := models.Get[models.BackUser](queryMap)
|
||||
if userInfo == nil {
|
||||
return ""
|
||||
}
|
||||
if !utils.PasswordCompare(user["password"].(string), userInfo["password"].(string)) {
|
||||
return ""
|
||||
}
|
||||
claims := jwt.MapClaims{
|
||||
"id": userInfo["id"],
|
||||
"username": userInfo["username"],
|
||||
"role": userInfo["role"],
|
||||
"email": userInfo["email"],
|
||||
}
|
||||
return utils.GenerateToken(claims)
|
||||
}
|
||||
|
||||
// Register user register, user can use account after approved
|
||||
func Register(user map[string]interface{}) {
|
||||
user["password"] = utils.PasswordEncrypt(user["password"].(string))
|
||||
userStr, _ := json.Marshal(user)
|
||||
// insert into redis, wait for approve
|
||||
cmd := global.Redis.HMSet(global.REGISTER_REDIS_KEY, map[string]interface{}{user["email"].(string): userStr})
|
||||
if cmd.Err() != nil {
|
||||
panic(cmd.Err())
|
||||
}
|
||||
}
|
||||
|
||||
// ListRegister list the registers in the redis to be approved
|
||||
func ListRegister() *[]map[string]interface{} {
|
||||
applyStrMap := global.Redis.HGetAll(global.REGISTER_REDIS_KEY).Val()
|
||||
var applies []map[string]interface{}
|
||||
for _, v := range applyStrMap {
|
||||
var apply map[string]interface{}
|
||||
_ = json.Unmarshal([]byte(v), &apply)
|
||||
applies = append(applies, apply)
|
||||
}
|
||||
if applies == nil {
|
||||
applies = []map[string]interface{}{}
|
||||
}
|
||||
return &applies
|
||||
}
|
||||
|
||||
// ApproveRegister approve a register
|
||||
func ApproveRegister(email string, pass bool) bool {
|
||||
if !pass {
|
||||
rowsAffected := global.Redis.HDel(global.REGISTER_REDIS_KEY, email).Val()
|
||||
return rowsAffected != 0
|
||||
}
|
||||
// if pass, will get the register info from redis, and the insert into mysql, this mean user is register success
|
||||
applyStr := global.Redis.HGet(global.REGISTER_REDIS_KEY, email).Val()
|
||||
rowsAffected := global.Redis.HDel(global.REGISTER_REDIS_KEY, email).Val()
|
||||
if rowsAffected == 0 {
|
||||
return false
|
||||
}
|
||||
var apply map[string]interface{}
|
||||
_ = json.Unmarshal([]byte(applyStr), &apply)
|
||||
if !NoDuplicatePhoneOrEmail(apply["phone"].(string), apply["email"].(string)) {
|
||||
return false
|
||||
}
|
||||
colMap := models.MapJ2c[models.BackUser](apply, true)
|
||||
ok, rowsAffected := models.Upsert[models.BackUser](colMap)
|
||||
return ok && rowsAffected != 0
|
||||
}
|
||||
|
||||
// ChangePassword user change password, or user forgot password
|
||||
func ChangePassword(changePwd map[string]interface{}) bool {
|
||||
match := VerifyEmailCode(changePwd["email"].(string), changePwd["code"].(string))["match"].(bool)
|
||||
if !match {
|
||||
return false
|
||||
}
|
||||
newPassword := utils.PasswordEncrypt(changePwd["newPassword"].(string))
|
||||
colMap := map[string]interface{}{
|
||||
"id": 1,
|
||||
"password": newPassword,
|
||||
}
|
||||
models.BeforeSave(colMap, -1)
|
||||
delete(colMap, "id")
|
||||
rowAffected := global.Db.Model(models.BackUser{}).Where("email = ?", changePwd["email"]).Updates(colMap).RowsAffected
|
||||
if rowAffected == 0 {
|
||||
return false
|
||||
}
|
||||
now := time.Now().Unix()
|
||||
global.Redis.HSet(global.CHANGEPWD_REDIS_KEY, changePwd["email"].(string), now)
|
||||
return true
|
||||
}
|
||||
|
||||
// NoDuplicatePhoneOrEmail detect the phone or email is registered or not
|
||||
func NoDuplicatePhoneOrEmail(phone string, email string) bool {
|
||||
var queryMap []map[string]interface{}
|
||||
if phone != "" {
|
||||
queryMap = append(queryMap, map[string]interface{}{"phone": phone})
|
||||
}
|
||||
if email != "" {
|
||||
queryMap = append(queryMap, map[string]interface{}{"email": email})
|
||||
}
|
||||
return len(queryMap) != 0 && models.Count[models.BackUser](queryMap) == 0
|
||||
}
|
||||
|
||||
// SendEmailCode used to send email verify code
|
||||
func SendEmailCode(email string) bool {
|
||||
code := uuid.New().String()[0:6]
|
||||
text := fmt.Sprintf("Your Verify Code is :%s, Will Expire After 10 Minutes", code)
|
||||
subject := "nCovTrack Verify"
|
||||
// only set expired, not limit the frequency of use
|
||||
global.Redis.Set(EMAIL_CODE_REDIS_KEY+email, code, 10*time.Minute)
|
||||
return utils.SendEmail(subject, text, email)
|
||||
}
|
||||
|
||||
// VerifyEmailCode use to verify user's verify code is correct or not
|
||||
func VerifyEmailCode(email string, code string) map[string]interface{} {
|
||||
verifyCode := global.Redis.Get(EMAIL_CODE_REDIS_KEY + email).Val()
|
||||
return map[string]interface{}{"match": verifyCode == code}
|
||||
}
|
||||
Reference in New Issue
Block a user