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>
相关推荐
2401_865854881 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
AskHarries2 小时前
Spring Boot集成Access DB实现数据导入和解析
java·spring boot·后端
2401_857622662 小时前
SpringBoot健身房管理:敏捷与自动化
spring boot·后端·自动化
程序员阿龙2 小时前
基于SpringBoot的医疗陪护系统设计与实现(源码+定制+开发)
java·spring boot·后端·医疗陪护管理平台·患者护理服务平台·医疗信息管理系统·患者陪护服务平台
程思扬2 小时前
为什么Uptime+Kuma本地部署与远程使用是网站监控新选择?
linux·服务器·网络·经验分享·后端·网络协议·1024程序员节
阿华的代码王国2 小时前
【Spring】——SpringBoot项目创建
java·spring boot·后端·启动类·target文件
九鼎科技-Leo3 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
阿芯爱编程3 小时前
平衡二叉树
java·后端·算法
程序员清风3 小时前
浅析Web实时通信技术!
java·后端·面试
dessler4 小时前
Linux系统-rocky系统安装
linux·运维·后端