go語言實現用戶管理系統

goweb實現用戶管理系統

用戶后臺管理系統功能描述

登錄功能

  1. 支持用戶通過郵箱密碼和密碼進行登錄。
  2. 對輸入的郵箱和密碼進行驗證,確保用戶信息的正確性。
  3. 登錄成功后,更新用戶的今日登錄統計信息,并將用戶信息存入會話(cookie)中,便于后續操作。
  4. 提供友好的錯誤提示,如“用戶不存在”“密碼錯誤”“用戶已被禁用”等,幫助用戶了解登錄失敗的原因。

在這里插入圖片描述

package serviceimport ("UserManager/src/mapper""UserManager/src/utils""fmt""golang.org/x/crypto/bcrypt"
)type LoginService struct {Mapper *mapper.LoginMapper
}func NewLoginService(lm *mapper.LoginMapper) *LoginService {return &LoginService{Mapper: lm,}
}// 用戶登錄
func (ls *LoginService) LoginUser(email string, password string) (string, error) {user, err := ls.Mapper.GetUserByEmail(email)if err != nil || user == nil {return "", fmt.Errorf("用戶不存在")}//驗證密碼if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {return "", fmt.Errorf("密碼錯誤")}fmt.Println("hhh", user)if user.Status == 0 {return "", fmt.Errorf("用戶已被禁用")}//生成JWTtoken, err := utils.GenerateToken(user)if err != nil {return "", fmt.Errorf("生成令牌失敗")}return token, nil
}

注冊功能

  1. 允許用戶輸入郵箱、驗證碼,密碼及確認密碼進行注冊。
  2. 對郵箱進行唯一性校驗,避免重復注冊,并發送驗證碼。
  3. 檢查兩次輸入的密碼是否一致,確保用戶密碼的準確性。
  4. 使用 bcrypt 算法對用戶密碼進行加密存儲,保障用戶密碼的安全性。
  5. 注冊成功后,自動增加今日新增人數統計。

在這里插入圖片描述

package serviceimport ("UserManager/src/mapper""UserManager/src/models""UserManager/src/utils""fmt""github.com/google/uuid""golang.org/x/crypto/bcrypt""regexp"
)// VerificationInfo 保存驗證碼及其過期時間type RegisterService struct {Mapper              *mapper.RegisterMapperEmailService        *utils.EmailServiceVerificationService *utils.VerificationService
}func NewRegisterService(rm *mapper.RegisterMapper, emailService *utils.EmailService, vService *utils.VerificationService) *RegisterService {return &RegisterService{Mapper:              rm,EmailService:        emailService,VerificationService: vService,}
}// SendVerificationCode 生成驗證碼,并使用 Redis 存儲(有效期5分鐘)后發送郵件
func (rs *RegisterService) SendVerificationCode(email string) error {code, err := rs.VerificationService.GenerateAndStoreCode(email)if err != nil {return err}subject := "您的驗證碼"body := fmt.Sprintf("您的驗證碼為:%s,請勿泄露于他人!該驗證碼5分鐘內有效!如非本人操作,請忽略此郵件!。", code)return rs.EmailService.SendEmail(email, subject, body)
}// 用戶注冊
func (rs *RegisterService) RegisterUser(email, inputCode, password, passwordConfirm string) error {if !isValidPassword(password) {return fmt.Errorf("密碼必須是8-12位字母和數字組合")}if password != passwordConfirm {return fmt.Errorf("兩次密碼輸入不一致")}// 驗證驗證碼if err := rs.VerificationService.VerifyCode(email, inputCode); err != nil {return err}// 檢查郵箱是否已注冊if user, _ := rs.Mapper.GetUserByEmail(email); user != nil {return fmt.Errorf("郵箱已注冊")}// 加密密碼hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)if err != nil {return fmt.Errorf("密碼加密失敗:%v", err)}// 插入新用戶newUser := &models.User{Email:        email,PasswordHash: string(hashed),Nickname:     "user_" + uuid.New().String()[:8],}if err := rs.Mapper.InsertUser(newUser); err != nil {return fmt.Errorf("用戶注冊失敗:%v", err)}return nil
}// isValidPassword 校驗密碼是否滿足8-12位字母和數字組合
func isValidPassword(password string) bool {// 1. 檢查長度是否為8-12位if len(password) < 8 || len(password) > 12 {return false}// 2. 檢查是否只包含字母和數字validChars, err := regexp.MatchString(`^[0-9A-Za-z]+$`, password)if err != nil || !validChars {return false}// 3. 檢查是否至少包含一個字母hasLetter, err := regexp.MatchString(`[A-Za-z]`, password)if err != nil || !hasLetter {return false}// 4. 檢查是否至少包含一個數字hasDigit, err := regexp.MatchString(`\d`, password)if err != nil || !hasDigit {return false}return true
}

用戶管理

用戶列表展示

在這里插入圖片描述

  1. 以分頁的形式展示系統中的用戶列表,每頁顯示固定數量的用戶記錄。
  2. 提供用戶的基本信息,包括用戶名、角色、狀態、郵箱、頭像、注冊時間等,方便管理員快速了解用戶情況。
  3. 根據當前頁碼和總記錄數,動態計算并顯示分頁導航欄,方便管理員切換頁面查看不同用戶數據。
用戶搜索
  1. 支持管理員通過用戶名關鍵字進行用戶搜索,快速定位目標用戶。
  2. 搜索結果同樣以分頁形式展示,方便查看大量用戶數據。
  3. 提供搜索結果的總記錄數、總頁數等信息,幫助管理員了解搜索結果的范圍。
用戶創建

在這里插入圖片描述

**

  1. 管理員可以輸入用戶名、密碼、郵箱、角色、狀態等信息創建新用戶。
  2. 對輸入的用戶信息進行校驗,如用戶名是否已存在、必填項是否填寫等。
  3. 支持上傳用戶頭像,并對上傳的文件進行類型、大小校驗,確保頭像的合法性。 創建成功后,自動更新今日新增人數統計。
用戶更新

在這里插入圖片描述

  1. 管理員可以對現有用戶的信息進行修改,包括用戶名、密碼、郵箱、角色、狀態、頭像等。
  2. 在修改密碼時,只有當用戶輸入了新密碼時才會進行密碼更新,并且會對新密碼進行加密處理。
  3. 對修改后的用戶信息進行校驗,如用戶名是否被其他用戶占用等。
  4. 更新成功后,返回更新后的用戶頭像路徑等信息。
用戶刪除

在這里插入圖片描述

  1. 管理員可以刪除指定的用戶,但不允許刪除當前登錄用戶自己。
  2. 刪除用戶時,同時刪除該用戶的頭像文件(如果頭像不是默認頭像)。
  3. 刪除成功后,自動更新今日被刪除人數統計。
package serviceimport ("UserManager/src/mapper""UserManager/src/models""UserManager/src/utils""errors""fmt""golang.org/x/crypto/bcrypt""io"
)type UserService struct {Mapper *mapper.UserMapper
}func NewUserService(hm *mapper.UserMapper) *UserService {return &UserService{Mapper: hm,}
}// GetUsers 支持分頁 + 搜索 + 狀態篩選
func (us *UserService) GetUsers(keyword, statusStr string, page, pageSize int) ([]*models.User, int, error) {// 計算 offsetoffset := (page - 1) * pageSize// 委托 Mapper 執行查詢并返回總數return us.Mapper.QueryUsersWithPage(keyword, statusStr, offset, pageSize)
}// 新增用戶
func (us *UserService) CreateUser(email, passwordHash, nickname string, avatarFile io.Reader, avatarFileName string, role, status int) (*models.User, error) {// 上傳頭像到 OSSavatarURL, err := utils.UploadFileToOSS(avatarFile, avatarFileName)if err != nil {return nil, err}// 檢查郵箱是否已注冊if user, _ := us.Mapper.GetUserByEmail(email); user != nil {return nil, errors.New("郵箱已注冊,請使用其他郵箱")}// 加密密碼hashed, err := bcrypt.GenerateFromPassword([]byte(passwordHash), bcrypt.DefaultCost)if err != nil {return nil, errors.New("密碼加密失敗")}user := &models.User{Email:        email,PasswordHash: string(hashed),Nickname:     nickname,AvatarUrl:    avatarURL,Role:         role,Status:       status,}if err := us.Mapper.CreateUser(user); err != nil {return nil, err}return user, nil
}func (us *UserService) UpdateUser(id int, email, passwordHash, nickname string, avatarFile io.Reader, avatarFileName string, role, status int) (*models.User, error) {// 1. 先取出數據庫中的原用戶user, err := us.Mapper.GetUserByID(id)if err != nil {return nil, err}// 2. 如果郵箱被修改,檢查是否重復if email != user.Email {if existing, _ := us.Mapper.GetUserByEmail(email); existing != nil {return nil, errors.New("郵箱已注冊,請使用其他郵箱")}}// 3. 更新基本字段user.Email = emailuser.Nickname = nicknameuser.Role = roleuser.Status = status// 4. 如果前端傳了非空密碼,才加密并更新if passwordHash != "" {if !isValidPassword(passwordHash) {return nil, fmt.Errorf("密碼必須是8-12位字母和數字組合")}hashed, err := bcrypt.GenerateFromPassword([]byte(passwordHash), bcrypt.DefaultCost)if err != nil {return nil, errors.New("密碼加密失敗")}user.PasswordHash = string(hashed)}// 5. 如果前端上傳了新頭像,才上傳并更新 URLif avatarFile != nil {url, err := utils.UploadFileToOSS(avatarFile, avatarFileName)if err != nil {return nil, err}user.AvatarUrl = url}// 6. 寫回數據庫if err := us.Mapper.UpdateUser(user); err != nil {return nil, err}return user, nil
}// 根據用戶 ID 獲取用戶信息
func (us *UserService) GetUserByID(id int) (*models.User, error) {return us.Mapper.GetUserByID(id)
}// 刪除用戶信息
func (us *UserService) DeleteUser(id int) error {return us.Mapper.DeleteUser(id)
}

用戶統計與數據展示

首頁統計信息展示
  1. 在系統首頁展示一些關鍵的用戶統計數據,如總用戶數、本月登錄人次、注銷用戶數量等。
    提供登錄增長率、用戶增長率、注銷用戶增長率等指標,幫助管理員了解系統的整體發展趨勢
  2. 展示過去 30天的登錄趨勢圖表,以日期為維度展示每日的登錄次數,方便管理員觀察登錄量的變化趨勢。
  3. 相關的統計信息(如今日登錄人數、今日新增人數、今日被刪除人數)會隨著用戶的登錄、注冊、刪除等操作實時更新,確保數據的準確性和時效性。

在這里插入圖片描述
在這里插入圖片描述

package serviceimport ("UserManager/src/mapper""time"
)type HomeService struct {Mapper *mapper.HomeMapper
}// TrendData 用于返回給前端的訪問趨勢數據
type TrendData struct {Date  string `json:"date"`Count int    `json:"count"`
}// 儀表數據
type DashboardData struct {RegisteredUsers        int     `json:"registered_users"`Visits                 int     `json:"visits"`DeactivatedUsers       int     `json:"deactivated_users"`RegisteredUsersGrowth  float64 `json:"registered_users_growth"`VisitsGrowth           float64 `json:"visits_growth"`DeactivatedUsersGrowth float64 `json:"deactivated_users_growth"`
}func NewHomeService(hm *mapper.HomeMapper) *HomeService {return &HomeService{Mapper: hm,}
}// 獲取儀表盤統計數據
func (hs *HomeService) GetDashboardStats() (DashboardData, error) {// 獲取當前時間now := time.Now()currentUsers, err := hs.Mapper.CountRegisteredUsers(now)if err != nil {return DashboardData{}, err}currentVisits, err := hs.Mapper.CountVisits(time.Now())if err != nil {return DashboardData{}, err}currentDeactivated, err := hs.Mapper.CountDeactivatedUsers(time.Now())if err != nil {return DashboardData{}, err}//獲取上個月的數據// 獲取當前年份和月份year, month, _ := now.Date()// 計算上個月的年份和月份if month == time.January {year--month = time.December} else {month--}// 獲取上個月的第一天firstOfMonth := time.Date(year, month, 1, 0, 0, 0, 0, now.Location())// 上個月的最后一天是本月第一天的前一天lastMonth := firstOfMonth.AddDate(0, 1, -1)previousUsers, err := hs.Mapper.CountRegisteredUsers(lastMonth)if err != nil {return DashboardData{}, err}previousVisits, err := hs.Mapper.CountVisits(lastMonth)if err != nil {return DashboardData{}, err}previousDeactivated, err := hs.Mapper.CountDeactivatedUsers(lastMonth)if err != nil {return DashboardData{}, err}// 計算增長率usersGrowth := calculateGrowth(previousUsers, currentUsers)visitsGrowth := calculateGrowth(previousVisits, currentVisits)deactivatedGrowth := calculateGrowth(previousDeactivated, currentDeactivated)return DashboardData{RegisteredUsers:        currentUsers,Visits:                 currentVisits,DeactivatedUsers:       currentDeactivated,RegisteredUsersGrowth:  usersGrowth,VisitsGrowth:           visitsGrowth,DeactivatedUsersGrowth: deactivatedGrowth,}, nil
}// calculateGrowth 計算增長率
func calculateGrowth(previous, current int) float64 {if previous == 0 {if current > 0 {return 100.0 // 從0增長到正數,視為100%增長}return 0.0 // 無變化}return (float64(current-previous) / float64(previous)) * 100
}
func (hs *HomeService) AddVisitCounts(userID int) error {err := hs.Mapper.AddVisitCounts(userID)if err != nil {return err}return nil
}// 根據傳入天數獲取訪問趨勢數據
func (hs *HomeService) GetAccessTrends(days int) ([]TrendData, error) {// 計算起始時間(包含當天)startTime := time.Now().AddDate(0, 0, -days+1)visits, err := hs.Mapper.GetVisitsFrom(startTime)if err != nil {return nil, err}// 初始化每天的訪問計數(key 為日期字符串)trendMap := make(map[string]int)for i := 0; i < days; i++ {dateStr := time.Now().AddDate(0, 0, -i).Format("2006-01-02")trendMap[dateStr] = 0}// 遍歷訪問記錄進行計數for _, visit := range visits {dateStr := visit.VisitTime.Format("2006-01-02")trendMap[dateStr]++}// 按時間順序組織返回數據(例如從最早到最新)var trends []TrendDatafor i := days - 1; i >= 0; i-- {date := time.Now().AddDate(0, 0, -i).Format("2006-01-02")trends = append(trends, TrendData{Date:  date,Count: trendMap[date],})}return trends, nil
}

具體代碼看我github,https://github.com/cxzgit/UserManager
另外utils下的oss.go這里你配一下就好了

package utilsimport ("fmt""github.com/aliyun/aliyun-oss-go-sdk/oss""io""time"
)// UploadFileToOSS 上傳文件到 OSS,并返回公開訪問的 URL
func UploadFileToOSS(file io.Reader, fileName string) (string, error) {endpoint := ""accessKeyID := ""accessKeySecret := ""bucketName := ""client, err := oss.New(endpoint, accessKeyID, accessKeySecret)if err != nil {return "", fmt.Errorf("failed to create OSS client: %w", err)}bucket, err := client.Bucket(bucketName)if err != nil {return "", fmt.Errorf("failed to get OSS bucket: %w", err)}// 生成唯一的對象 key(例如:avatars/時間戳_原文件名)objectKey := fmt.Sprintf("avatars/%d_%s", time.Now().UnixNano(), fileName)if err := bucket.PutObject(objectKey, file); err != nil {return "", fmt.Errorf("failed to upload file: %w", err)}// 假設 bucket 為公共讀,構造公開訪問的 URLossURL := fmt.Sprintf("https://%s.%s/%s", bucketName, endpoint, objectKey)return ossURL, nil}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79584.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Elasticsearch:RAG 和 grounding 的價值

作者&#xff1a;來自 Elastic Toms Mura 了解 RAG、grounding&#xff0c;以及如何通過將 LLM 連接到你的文檔來減少幻覺。 更多閱讀&#xff1a;Elasticsearch&#xff1a;在 Elastic 中玩轉 DeepSeek R1 來實現 RAG 應用 想獲得 Elastic 認證嗎&#xff1f;查看下一期 Elast…

【黑馬JavaWeb+AI知識梳理】后端Web基礎01 - Maven

Maven Maven核心 Maven概述 定義&#xff1a; Maven是一款用于管理和構建Java項目的工具&#xff0c;是apache旗下的一個開源項目&#xff0c;基于項目對象模型&#xff08;POM&#xff0c;project object model&#xff09;的概念&#xff0c;通過一小段描述信息來管理項目的…

C語言易混淆知識點詳解

C語言中容易混淆的知識點詳解 C語言作為一門基礎且強大的編程語言&#xff0c;有許多容易混淆的概念和特性。以下是C語言中一些常見易混淆知識點的詳細解析&#xff1a; 1. 指針與數組 相似點&#xff1a; c 復制 下載 int arr[10]; int *ptr arr; 都可以使用[]運算符訪…

MCP原理詳解及實戰案例(動嘴出UI稿、3D建模)

文章目錄 MCP 原理介紹架構核心組件協議層傳輸層連接生命周期MCP與function calling: 互補關系 MCP python SDKMCP的優點 怎么用MCP&#xff1a;天氣服務參考應用項目&#xff1a; REF 24年11月份&#xff0c;claude推出了模型上下文協議( MCP),作為一種潛在的解決方案&#xf…

2025年深圳杯數學建模(東三省)B題【顏色轉換】原論文講解(含完整python代碼)

大家好呀&#xff0c;從發布賽題一直到現在&#xff0c;總算完成了2025年深圳杯數學建模&#xff08;東三省&#xff09;B題【顏色轉換】完整的成品論文。 本論文可以保證原創&#xff0c;保證高質量。絕不是隨便引用一大堆模型和代碼復制粘貼進來完全沒有應用糊弄人的垃圾半成…

cpp學習筆記1--class

2年前學過cpp&#xff0c;但是一直沒有用到&#xff0c;現在要讀研了&#xff0c;終于要用到了&#xff0c;重新拿出來看一看&#xff0c;覺得很多東西都能在c和python上看到影子。 #include "iostream" class Person { private:std::string name;int age;public://…

基于YOLOv的目標檢測訓練數據構建方法研究—圖像采集、標注、劃分與增強一體化流程設計

在目標檢測任務中,高質量的訓練數據是模型性能提升的關鍵。本文圍繞 YOLOv 系列模型,系統性地研究了目標檢測訓練數據的構建方法,提出了一套從圖像采集、標注、數據集劃分到數據增強的一體化流程設計 。通過多源圖像采集策略確保樣本多樣性,結合 LabelImg 工具完成 VOC 格式…

SQL數據庫操作大全:從基礎到高級查詢技巧

大家好&#xff0c;歡迎來到程序視點&#xff01;我是你們的老朋友.小二&#xff01; SQL數據庫操作核心語法精要 數據庫基礎操作 創建/刪除數據庫&#xff1a;CREATE DATABASE / DROP DATABASE 備份SQL Server&#xff1a;使用sp_addumpdevice和BACKUP DATABASE命令 數據庫…

[2025]MySQL的事務機制是什么樣的?redolog,undolog、binog三種日志的區別?二階段提交是什么?ACID怎么保證的?主從復制的過程?

MySQL事務機制與日志系統詳解 一、MySQL事務機制 1. 事務特性&#xff08;ACID&#xff09; 特性實現機制原子性(Atomicity)undo log回滾,(事務作為一個整體被執行&#xff0c;包含在其中的對數據庫的操作要么全部被執行&#xff0c;要么都不執行)。一致性(Consistency)約束…

LLama-v2 權重下載

地址&#xff1a;llama模型 官方github倉庫&#xff1a;llama倉庫 注意點 網絡代理位置&#xff1a;美國下面的國家選擇 United States 克隆倉庫后 運行bash download.sh輸入郵箱收到的URL選擇要下載的權重等待下載完成即可 有問題留言&#xff01;&#xff01;&#xff01…

zephyr OS架構下構建Nordic MCU boot

目錄 概述 1. 軟硬件環境 1.1 軟件開發環境 1.2 硬件環境 2 MCU boot 2.1 核心功能 2.2 關鍵術語 2.3 重要字段介紹 3 VS-Code下創建MCU-BOOT項目 3.1 軟件框架結構 3.2 創建測試項目 3.3 編譯項目 3.3 固件在Flash中的分布 4 驗證 4.1 燒寫固件 ? 4.2 代碼…

【Mytais系列】介紹、核心概念

MyBatis 是一款優秀的 持久層框架&#xff0c;它通過簡化 JDBC 操作、提供靈活的 SQL 映射能力&#xff0c;成為 Java 開發中處理數據庫交互的核心工具之一。以下是 MyBatis 的核心框架和概念解析&#xff1a; 一、MyBatis 框架概述 1. 核心定位 作用&#xff1a;將 Java 對象…

IO模型和多路復用

一、IO模型的基礎理解 什么是IO? IO全稱是 Input/Output(輸入/輸出),在計算機科學里主要指程序與外部設備(硬盤、網絡、用戶終端等)進行數據交換的操作。首要特點是: IO通常很慢(從CPU和內存的視角看)經常需要等待外部設備響應1. 為什么要談IO模型? 當一個程序需要…

深入理解 Bash 中的 $‘...‘ 字符串語法糖

在 Bash 腳本編程中&#xff0c;字符串處理是不可或缺的一部分。為了讓開發者更高效地處理特殊字符和控制字符&#xff0c;Bash 引入了一種獨特的字符串語法糖&#xff1a;$&#xff08;帶單引號的 ANSI-C 風格字符串&#xff09;。這種語法來源于 C 語言的 ANSI-C 標準&#x…

用Python打造自己的專屬命令行工具

在日常的開發和使用過程中&#xff0c;我們常常會編寫一些實用的Python腳本&#xff0c;比如用來批量處理文件、獲取系統信息等。然而&#xff0c;每次都要輸入python script_name.py來運行腳本&#xff0c;時間一長難免覺得繁瑣。要是能像使用系統自帶的命令&#xff08;如ls、…

【KWDB 創作者計劃】KWDB 2.2.0多模融合架構與分布式時序引擎

KWDB介紹 KWDB數據庫是由開放原子開源基金會孵化的分布式多模數據庫&#xff0c;專為AIoT場景設計&#xff0c;支持時序數據、關系數據和非結構化數據的統一管理。其核心架構采用多模融合引擎&#xff0c;集成列式時序存儲、行式關系存儲及自適應查詢優化器&#xff0c;實現跨模…

學習Linux的第二天

如何在Linux環境下做開發 Linux的一些基操 Tips&#xff1a;平常最表層的是命令行模式&#xff0c;最多見這個默認叫做命令行模式 Vi操作是什么意思呢 就是在提示符輸入vi a.c 是可以創建一個a.c這個文件并進入這個輸入模式 按i可以輸入代碼 要退出的時候按esc 再按:(冒號…

鏈表操作練習

要求 現在有一個雙向鏈表&#xff0c;里面要保存歌曲的名字&#xff1b;例如 蔡琴/渡口.mp3 我們把它定義在一個link.h文件中。 #ifndef LINK_H #define LINK_H #include <stdlib.h> #include <stdio.h> #include <string.h>typedef struct Node {//保存歌…

MATLAB制作散點圖:從基礎到進階的三種類型講解

一、什么是散點圖 散點圖是一種用來展示兩個或多個變量之間關系的圖表形式。它可以幫助我們直觀地觀察變量之間是否存在相關性、趨勢或異常值&#xff0c;常用于數據分析的初步探索階段。 二、三種類型散點圖 1. 基本二維散點圖&#xff1a;最簡單、最常用 基本二維散點圖的…

模塊方法模式(Module Method Pattern)

&#x1f9e0; 模塊方法模式&#xff08;Module Method Pattern&#xff09; 模塊方法模式是一種結構型設計模式&#xff0c;它將復雜的操作分解成一系列相對簡單、獨立且單一職責的模塊。每個模塊負責完成一種具體的操作&#xff0c;其他模塊或系統可以通過調用這些模塊的公開…