go+bootstrap实现简单的注册登录和管理

概述

使用,go+mysql实现了用户的登录,注册,和管理的简单功能,不同用户根据不同权限显示不同的内容

实战要求:

1、用户可以注册、登录;

2、登录后可以查看所有的注册的用户;

3、管理员操作对用户有删除和编辑权限。(不使用3方的web框架)

4、普通用户登录后可以查看所有用户,不能编辑、删除;

结构:

界面展示

go相关代码

db.go

go 复制代码
package src

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
)

var mdb *sql.DB

func InitDB() {
	var err error
	mdb, err = sql.Open("mysql", "root:5201314@tcp(127.0.0.1:3306)/user_management")//数据库连接账号密码
	if err != nil {
		log.Println("数据库连接失败", err)
		return
	} else {
		log.Println("数据库连接成功")
	}
}

func SelectPersonal(email string) (id int, isAdmin bool) {
	log.Println("SelectPersonal")
	err := mdb.QueryRow("select id,is_admin from users where username = ?", email).Scan(&id, &isAdmin)
	if err != nil {
		log.Println("SelectPersona", err)
	}
	log.Println("SelectPersonal over")
	return id, isAdmin
}

func SelectAll() *sql.Rows {
	log.Println("SelectAll")
	stmt, err := mdb.Prepare("select * from users")
	if err != nil {
		log.Println("预处理失败")
	}
	rows, err := stmt.Query()
	if err != nil {
		log.Println("获取结果失败")
	}
	log.Println("SelectAll over")
	return rows
}

func SelectPassword(email string) string {
	log.Println("SelectPassword")
	var storedPassword string
	err := mdb.QueryRow("select password from users where username = ?", email).Scan(&storedPassword)
	if err != nil {
		log.Println(err)
	}
	log.Println("SelectPassword over")
	return storedPassword
}
func AddUser(email string, password string) bool {
	log.Println("AddUser")
	stmt, err := mdb.Prepare("insert into users values (default,?,?,false)")
	if err != nil {
		fmt.Println("预处理失败")
		return false
	}

	r, err := stmt.Exec(email, password)
	if err != nil {
		fmt.Println("sql执行失败")
		return false
	}
	count, err := r.RowsAffected()
	if err != nil {
		fmt.Println("结果获取失败")
		return false
	}
	if count > 0 {
		log.Println("AddUser over")
		fmt.Println("新增成功")
		return true
	} else {
		fmt.Println("用户创建失败")
		return false
	}
}
func IsExist(email string) bool {
	var emailExists bool
	err := mdb.QueryRow("select exists(select 1 from users where username = ?)", email).Scan(&emailExists)
	if err != nil {
		log.Println(err)
	}
	return emailExists
}

func IsAdminEmail(email string) bool {
	var emailExists bool
	err := mdb.QueryRow("select is_admin from users where username = ?", email).Scan(&emailExists)
	if err != nil {
		log.Println(err)
	}
	return emailExists
}
func RemoveUser(id int) bool {
	log.Println("RemoveUser")
	stmt, err := mdb.Prepare("delete from users where id=?")
	if err != nil {
		fmt.Println("预处理失败")
		return false
	}

	r, err := stmt.Exec(id)
	if err != nil {
		fmt.Println("sql执行失败")
		return false
	}
	count, err := r.RowsAffected()
	if err != nil {
		fmt.Println("结果获取失败")
		return false
	}
	if count > 0 {
		log.Println("ARemoveUser over")
		fmt.Println("删除成功")
		return true
	} else {
		fmt.Println("用户删除失败")
		return false
	}
}
func IsAdminId(id int) bool {
	var emailExists bool
	err := mdb.QueryRow("select is_admin from users where id = ?", id).Scan(&emailExists)
	if err != nil {
		log.Println(err)
	}
	return emailExists
}

func Manager(id int) bool {
	log.Println("Manager")
	stmt, err := mdb.Prepare("update users set is_admin = ? where id=?")
	if err != nil {
		fmt.Println("预处理失败")
		return false
	}

	r, err := stmt.Exec(true, id)
	if err != nil {
		fmt.Println("sql执行失败")
		return false
	}
	count, err := r.RowsAffected()
	if err != nil {
		fmt.Println("结果获取失败")
		return false
	}
	if count > 0 {
		log.Println("Manager over")
		fmt.Println("管理员设置成功")
		return true
	} else {
		fmt.Println("管理员设置失败")
		return false
	}
}

func RemoveManager(id int) bool {
	log.Println("RemoveManager")
	if id == 1 {
		return false
	}
	stmt, err := mdb.Prepare("update users set is_admin = ? where id=?")
	if err != nil {
		fmt.Println("预处理失败")
		return false
	}

	r, err := stmt.Exec(false, id)
	if err != nil {
		fmt.Println("sql执行失败")
		return false
	}
	count, err := r.RowsAffected()
	if err != nil {
		fmt.Println("结果获取失败")
		return false
	}
	if count > 0 {
		log.Println("RemoveManager over")
		fmt.Println("管理员移除成功")
		return true
	} else {
		fmt.Println("用户删除失败")
		return false
	}
}
func ChangePassword(email string, newPassword string) bool {
	log.Println("ChangePassword")

	stmt, err := mdb.Prepare("update users set password = ? where username=?")
	if err != nil {
		fmt.Println("预处理失败")
		return false
	}

	r, err := stmt.Exec(newPassword, email)
	if err != nil {
		fmt.Println("sql执行失败")
		return false
	}
	count, err := r.RowsAffected()
	if err != nil {
		fmt.Println("结果获取失败")
		return false
	}
	if count > 0 {
		log.Println("ChangePassword over")
		fmt.Println("密码修改成功")
		return true
	} else {
		fmt.Println("密码修改失败")
		return false
	}
}

main代码

go 复制代码
package main

import (
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"webTest2.0/src"
)

func main() {
	src.InitDB()
	r := mux.NewRouter()
	r.HandleFunc("/login", src.Login).Methods("GET")
	r.HandleFunc("/login/{url}", src.LoginHandler).Methods("POST")
	r.HandleFunc("/index/{url}", src.IndexHandler).Methods("POST", "DELETE")
	r.HandleFunc("/", src.Index).Methods("GET")
	r.PathPrefix("/bootstrap5/").Handler(http.StripPrefix("/bootstrap5/", http.FileServer(http.Dir("bootstrap5"))))

	log.Println("Starting server on :8090")
	if err := http.ListenAndServe(":8090", r); err != nil {
		log.Fatalf("Could not start server: %v", err)
	}
}

index.go

go 复制代码
package src

import (
	"encoding/json"
	"github.com/gorilla/mux"
	"html/template"
	"log"
	"net/http"
	"strconv"
)

type User struct {
	ID      int
	Name    string
	IsAdmin bool
}
type Personal struct {
	ID      int
	Name    string
	IsAdmin bool
}
type UserId struct {
	UserID string `json:"userId"`
}
type Password struct {
	OldPassword string
	NewPassword string
}
type MyErr struct{}

func (e *MyErr) Error() string {
	return "logout"
}

func Index(w http.ResponseWriter, r *http.Request) {
	log.Println("index")
	personal, err := CookieMessage(r)
	if err != nil {
		http.Redirect(w, r, "/login", http.StatusSeeOther)
		return
	}
	rows := SelectAll()
	users := make([]User, 0)
	for rows.Next() {
		name := ""
		id := 0
		var ignored interface{}
		isAdmin := false
		rows.Scan(&id, &name, &ignored, &isAdmin)
		users = append(users, User{id, name, isAdmin})
	}
	tmpl, err := template.ParseFiles("view/index.html")
	if err != nil {
		log.Println("login.html打开失败:", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	err = tmpl.Execute(w, map[string]interface{}{
		"Users":    users,
		"Personal": personal,
	})
	if err != nil {
		log.Println("模板执行失败:", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
	}
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("IndexHandler")
	vars := mux.Vars(r)
	log.Println(vars)
	switch vars["url"] {
	case "delete":
		deleteUser(w, r)
	case "updateAdmin":
		addAdmin(w, r)
	case "removeAdmin":
		removeAdmin(w, r)
	case "changePassword":
		changePassword(w, r)
	case "logout":

		logout(w)
	}
}
func CookieMessage(r *http.Request) (Personal, error) {
	c, err := r.Cookie("email")
	if err != nil {
		// 如果获取 Cookie 失败,返回错误
		return Personal{}, err
	}
	if c.Value == "logout" {
		return Personal{}, &MyErr{}
	}
	id, isAdmin := SelectPersonal(c.Value)
	log.Println(id, isAdmin)
	personal := Personal{
		id,
		c.Value,
		isAdmin,
	}
	return personal, nil
}

func changePassword(w http.ResponseWriter, r *http.Request) {
	log.Println("changePassword")
	response := make(map[string]string)
	c, err := r.Cookie("email")
	if err != nil {
		response["success"] = "false"
		response["message"] = "cookie获取失败"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	var password Password
	err = json.NewDecoder(r.Body).Decode(&password)
	if err != nil {
		response["success"] = "false"
		response["message"] = "客户端信息解析错误"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		http.Error(w, "Invalid request payload", http.StatusBadRequest)
		return
	}
	log.Println(password.NewPassword, password.OldPassword)
	if password.NewPassword == SelectPassword(c.Value) {
		response["success"] = "false"
		response["message"] = "新秘密与旧密码相同"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	if password.OldPassword == SelectPassword(c.Value) {
		if ChangePassword(c.Value, password.NewPassword) {
			response["success"] = "true"
			response["message"] = "密码修改成功"
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		} else {
			response["success"] = "false"
			response["message"] = "密码修改失败"
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		}
	} else {
		response["success"] = "false"
		response["message"] = "旧密码错误"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
	}

}
func deleteUser(w http.ResponseWriter, r *http.Request) {
	log.Println("deleteUser")
	response := make(map[string]string)
	c, err := r.Cookie("email")
	if err != nil {
		response["success"] = "false"
		response["message"] = "cookie获取失败"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	var Id UserId
	err = json.NewDecoder(r.Body).Decode(&Id)
	if err != nil {
		http.Error(w, "Invalid request payload", http.StatusBadRequest)
		return
	}
	deleteId, err := strconv.Atoi(Id.UserID)
	king := IsAdminId(deleteId)
	id, isAdmin := SelectPersonal(c.Value)
	if isAdmin {
		if id == 1 {
			RemoveUser(deleteId)
			response["success"] = "true"
			response["message"] = "删除成功"
		} else if !king {
			RemoveUser(deleteId)
			response["success"] = "true"
			response["message"] = "删除成功"
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
	}
	log.Println("deleteUser over")
}
func addAdmin(w http.ResponseWriter, r *http.Request) {
	log.Println("addAdmin")
	response := make(map[string]string)
	c, err := r.Cookie("email")
	if err != nil {
		response["success"] = "false"
		response["message"] = "cookie获取失败"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	id, _ := SelectPersonal(c.Value)
	log.Println(id)
	if id != 1 {
		response["success"] = "false"
		response["message"] = "用户权限不足"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	var Id UserId
	err = json.NewDecoder(r.Body).Decode(&Id)
	log.Println(Id.UserID)
	if err != nil {
		log.Println(err)
		http.Error(w, "Invalid request payload", http.StatusBadRequest)
		return
	}
	updateId, err := strconv.Atoi(Id.UserID)
	Manager(updateId)
	response["success"] = "true"
	response["message"] = "管理员设置成功"
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
	log.Println("addAdmin over")
}

func removeAdmin(w http.ResponseWriter, r *http.Request) {
	response := make(map[string]string)
	c, err := r.Cookie("email")
	if err != nil {
		response["success"] = "false"
		response["message"] = "cookie获取失败"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	id, _ := SelectPersonal(c.Value)
	if id != 1 {
		response["success"] = "false"
		response["message"] = "用户权限不足"
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
		return
	}
	var Id UserId
	err = json.NewDecoder(r.Body).Decode(&Id)
	log.Println(Id.UserID)
	if err != nil {
		log.Println(err)
		http.Error(w, "Invalid request payload", http.StatusBadRequest)
		return
	}
	deleteId, err := strconv.Atoi(Id.UserID)
	RemoveManager(deleteId)
	response["success"] = "true"
	response["message"] = "管理员移除成功"
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}

func logout(w http.ResponseWriter) {
	log.Println("loginOut")
	http.SetCookie(w, &http.Cookie{
		Name:     "email",
		Value:    "logout",
		MaxAge:   5,
		Path:     "/",
		HttpOnly: true,
		SameSite: http.SameSiteLaxMode,
	})
	json.NewEncoder(w).Encode(map[string]interface{}{"success": true})
	log.Println("loginOut over")
}

login.go

go 复制代码
package src

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"html/template"
	"log"
	"net/http"
)

type LoginRequest struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

func Login(w http.ResponseWriter, r *http.Request) {
	_, err := CookieMessage(r)
	if err == nil {
		http.Redirect(w, r, "/", http.StatusSeeOther)
		return
	}
	log.Println("Login")
	tmpl, err := template.ParseFiles("view/login.html")
	if err != nil {
		log.Println("login.html打开失败:", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}
	err = tmpl.Execute(w, nil)
	if err != nil {
		log.Println("模板执行失败:", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
	}
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("LoginHandler")
	vars := mux.Vars(r)
	fmt.Println(vars)
	log.Println("loginHandler")
	switch vars["url"] {
	case "login":
		var req LoginRequest
		err := json.NewDecoder(r.Body).Decode(&req)
		if err != nil {
			http.Error(w, "Invalid request payload", http.StatusBadRequest)
			return
		}

		log.Printf("Received login request: Email: %s  password: %s\n", req.Email, req.Password)
		emailExists := IsExist(req.Email)
		if !emailExists {
			response := map[string]string{"success": "false", "message": "用户不存在"}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		}

		storedPassword := SelectPassword(req.Email)
		log.Println(storedPassword)
		if storedPassword != req.Password {
			response := map[string]string{"success": "false", "message": "密码错误"}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		}
		c := http.Cookie{
			Name:     "email",
			Value:    req.Email,
			Path:     "/",
			HttpOnly: true,
			Secure:   true,
			MaxAge:   3600,
		}
		http.SetCookie(w, &c)
		response := map[string]string{"success": "true", "message": ""}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(response)
	case "register":
		var req LoginRequest
		err := json.NewDecoder(r.Body).Decode(&req)
		if err != nil {
			http.Error(w, "Invalid request payload", http.StatusBadRequest)
			return
		}

		log.Printf("Received login request: Email: %s  password: %s\n", req.Email, req.Password)
		emailExists := IsExist(req.Email)
		if !emailExists {
			king := AddUser(req.Email, req.Password)
			response := make(map[string]string)
			if king {
				response["success"] = "true"
				response["message"] = "注册成功"
			} else {
				response["success"] = "false"
				response["message"] = "注册失败"
			}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		} else {
			response := map[string]string{"success": "false", "message": "用户已存在"}
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(response)
			return
		}

	default:
		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
	}
}

html相关代码

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户管理系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script>
    <style>
        .content-block {
            display: none;
        }
        .content-block:first-of-type {
            display: block;
        }
    </style>
</head>
<body>
<div class="container p-4">
    <div class="row">
        <div class="text-xxl-center list-group">
            <h1>用户管理系统</h1>
        </div>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-3">
            <div id="list-example" class="list-group">
                <a class="list-group-item list-group-item-action-active text-xxl-center list-group-item-primary" href="#list-item-1">个人</a>
                <a class="list-group-item list-group-item-action text-xxl-center list-group-item-primary" href="#list-item-2">其他</a>
                <a class="list-group-item list-group-item-action text-xxl-center list-group-item-primary" href="#list-item-3">设置</a>
            </div>
        </div>
        <div class="col-9">
            <div data-bs-spy="scroll" data-bs-target="#list-example" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
                <div id="list-item-1" class="content-block">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">用户ID:</th>
                            <th scope="col">{{.Personal.ID}}</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr>
                            <th scope="row">用户昵称:</th>
                            <td>{{.Personal.Name}}</td>
                        </tr>
                        <tr>
                            <th scope="row">用户身份:</th>
                            {{if and .Personal.IsAdmin (eq .Personal.ID 1)}}<td>超级管理员</td>
                            {{else if .Personal.IsAdmin}}<td>管理员</td>
                            {{else}}<td>普通成员</td>
                            {{end}}
                        </tr>
                        </tbody>
                    </table>
                </div>
                <div id="list-item-2" class="content-block">
                    <table class="table">
                        <thead>
                        <tr>
                            <th scope="col">ID</th>
                            <th scope="col">用户</th>
                            <th scope="col">身份</th>
                            {{if and .Personal.IsAdmin (eq .Personal.ID 1)}}
                            <th scope="col">管理</th>
                            {{end}}
                            {{if .Personal.IsAdmin}}
                            <th scope="col">删除</th>
                            {{end}}
                        </tr>
                        </thead>
                        <tbody>
                        {{range .Users}}
                        <tr>
                            <th scope="row">{{.ID}}</th>
                            <td>{{.Name}}</td>
                            {{if and .IsAdmin (eq .ID 1)}}<td>超级管理员</td>
                            {{else if .IsAdmin}}<td>管理员</td>
                            {{else}}<td>普通用户</td>
                            {{end}}
                            {{if eq $.Personal.ID 1}}
                            {{if eq .ID 1}}
                            {{else if .IsAdmin}}
                            <td><button type="button" class="btn btn-primary remove-user-btn" data-id="{{.ID}}">移除管理员</button></td>
                            <td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
                            {{else}}
                            <td><button type="button" class="btn btn-primary manage-user-btn" data-id="{{.ID}}">设置管理员</button></td>
                            <td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
                            {{end}}
                            {{else if $.Personal.IsAdmin}}
                            {{if not .IsAdmin}}
                            <td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
                            {{end}}
                            {{end}}

                        </tr>
                        {{end}}
                        </tbody>
                    </table>
                </div>

                <div id="list-item-3" class="content-block">
                    <div class="container">
                        <div class="row">
                            <div class="text-xxl-center col-6">
                                <button type="button" class="btn btn-primary" id="change-password-btn">修改密码</button>
                            </div>
                            <div class="col-6">
                                <button type="button" class="btn btn-primary" id="logout-btn">退出登录</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="changePasswordModal" tabindex="-1" aria-labelledby="changePasswordModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="changePasswordModalLabel">修改密码</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form id="change-password-form">
                    <div class="mb-3">
                        <label for="old-password" class="form-label">旧密码</label>
                        <input type="password" class="form-control" id="old-password" required>
                    </div>
                    <div class="mb-3">
                        <label for="new-password" class="form-label">新密码</label>
                        <input type="password" class="form-control" id="new-password" required>
                    </div>
                    <div class="mb-3">
                        <label for="confirm-password" class="form-label">确认新密码</label>
                        <input type="password" class="form-control" id="confirm-password" required>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" id="submit-change-password">确定</button>
            </div>
        </div>
    </div>
</div>
<script>
    document.querySelectorAll('#list-example a').forEach(anchor => {
        anchor.addEventListener('click', function (e) {
            e.preventDefault();
            const targetId = this.getAttribute('href');
            document.querySelectorAll('.content-block').forEach(block => {
                block.style.display = 'none';
            });
            document.querySelector(targetId).style.display = 'block';
        });
    });
    // 管理用户
    document.querySelectorAll('.manage-user-btn').forEach(button => {
        button.addEventListener('click', function() {
            const userId = this.getAttribute('data-id');
            if (confirm('确定要设置当前用户为管理员吗?')) {
                fetch(`/index/updateAdmin`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ "userId":userId })
                }).then(response => response.json())
                    .then(data => {
                        if (data.success === "true") {
                            alert('用户已成功设置成管理员!');
                            location.reload();
                        } else {
                            alert('设置管理员失败:' + data.message);
                        }
                    });
            }
        });
    });

    document.querySelectorAll('.remove-user-btn').forEach(button => {
        button.addEventListener('click', function() {
            const userId = this.getAttribute('data-id');
            if (confirm('确定要取消当前用户管理员身份吗?')) {
                fetch(`/index/removeAdmin`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ "userId":userId })
                }).then(response => response.json())
                    .then(data => {
                        if (data.success === "true") {
                            alert('已成功取消当前用户管理员身份!');
                            location.reload();
                        } else {
                            alert('取消当前用户管理员身份失败:' + data.message);
                        }
                    });
            }
        });
    });

    // 删除用户
    document.querySelectorAll('.delete-user-btn').forEach(button => {
        button.addEventListener('click', function() {
            const userId = this.getAttribute('data-id');
            if (confirm('确定要删除该用户吗?')) {
                fetch(`/index/delete`, {
                    method: 'DELETE',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ "userId":userId }),
                }).then(response => response.json())
                    .then(data => {
                        if (data.success === "true") {
                            alert('用户已成功删除!');
                            location.reload();
                        } else {
                            alert('删除用户失败:' + data.message);
                        }
                    });
            }
        });
    });

    document.getElementById('logout-btn').addEventListener('click', function() {
        fetch('/index/logout', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            credentials: 'include'
        }).then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('注销成功');

                        window.location.href="/";
                } else {
                    alert('注销失败:' + data.message);
                }
            });
    });
    document.addEventListener('DOMContentLoaded', function() {
        const changePasswordModal = new bootstrap.Modal(document.getElementById('changePasswordModal'));

        document.getElementById('change-password-btn').addEventListener('click', function () {
            changePasswordModal.show();
        });

        document.getElementById('submit-change-password').addEventListener('click', function () {
            const oldPassword = document.getElementById('old-password').value;
            const newPassword = document.getElementById('new-password').value;
            const confirmPassword = document.getElementById('confirm-password').value;

            if (newPassword !== confirmPassword) {
                alert('新密码和确认密码不一致!');
                return;
            }

            fetch('/index/changePassword', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    "oldPassword": oldPassword,
                    "newPassword": newPassword
                })
            }).then(response => response.json())
                .then(data => {
                    if (data.success === "true") {
                        alert('密码已成功更改!');
                        changePasswordModal.hide();
                    } else {
                        if (data.message === "新秘密与旧密码相同"){
                            alert('新秘密与旧密码相同');
                        }
                        alert('更改密码失败:' + data.message);
                    }
                });
        });
    });


</script>

</body>
</html>

login.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
    <form id="loginForm" onsubmit="return handleSubmit(event, 'login')">
        <div class="col-4 mx-auto">
            <div class="col-md-4 mx-auto p-6">
                <h2>登录/注册</h2>
            </div>
        </div>
        <div class="col-4 mx-auto">
            <label for="exampleInputEmail1" class="form-label">邮箱地址</label>
            <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
        </div>
        <div class="col-4 mx-auto">
            <label for="exampleInputPassword1" class="form-label">密码</label>
            <input type="password" class="form-control" id="exampleInputPassword1">
        </div>
        <div class="col-4 mx-auto">
            <button type="submit" class="col-12 btn-outline-primary p-2">登录</button>
        </div>
        <div class="col-4 mx-auto">
            <button type="button" class="col-12 btn-outline-primary p-2" onclick="handleSubmit(event, 'register')">注册</button>
        </div>
    </form>
</div>

<script>
    function handleSubmit(event, action) {
        event.preventDefault();

        const email = document.getElementById('exampleInputEmail1').value;
        const password = document.getElementById('exampleInputPassword1').value;

        const url = action === 'login' ? '/login/login' : '/login/register';

        fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ email, password }),
        })
            .then(response => response.json())
            .then(data => {
                if (data.success === "true") {
                    if (action === 'login') {
                        alert('登录成功!');
                        window.location.href = '/';
                    } else if (action === 'register') {
                        alert('注册成功,请登录!');
                    }
                } else {
                    if (data.message === "用户不存在") {
                        alert('用户不存在,请先注册');
                    } else if (data.message === "密码错误") {
                        alert('密码错误,请重新输入');
                    } else if (data.message === "用户已存在") {
                        alert('用户已存在,请直接登录');
                    } else {
                        alert('请求失败,请稍后再试');
                    }
                }
            })
            .catch((error) => {
                console.error('Error:', error);
                alert('请求错误,请稍后再试');
            });
    }
</script>

</body>
</html>
相关推荐
cjy00011143 分钟前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本2 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34162 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan2 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer3 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor3563 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor3563 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer4 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP5 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)5 小时前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang