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

news2024/11/30 12:37:37

概述

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

实战要求:

1、用户可以注册、登录;
2、登录后可以查看所有的注册的用户;
3、管理员操作对用户有删除和编辑权限。(不使用3方的web框架)
4、普通用户登录后可以查看所有用户,不能编辑、删除;

结构:

界面展示

在这里插入图片描述

在这里插入图片描述

go相关代码

db.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代码

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

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

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

<!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

<!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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2215419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP(一)从入门到放弃

参考文献&#xff1a;https://www.php.net/manual/zh/introduction.php PHP 是什么&#xff1f; PHP&#xff08;“PHP: Hypertext Preprocessor”&#xff0c;超文本预处理器的字母缩写&#xff09;是一种被广泛应用的开放源代码的多用途脚本语言&#xff0c;它可嵌入到 HTML…

Qt/C++编写的mqtt调试助手使用说明

一、使用说明 第一步&#xff0c;选择协议前缀&#xff0c;可选mqtt://、mqtts://、ws://、wss://四种&#xff0c;带s结尾的是走ssl通信&#xff0c;ws表示走websocket通信。一般选默认的mqtt://就好。第二步&#xff0c;填写服务所在主机地址&#xff0c;可以是IP地址也可以…

使用LSPatch+PlusNE修改手机软件

一、问题概述 国内使用一些软件&#xff0c;即使科学上网&#xff0c;打开都是网络错误&#xff0c;更换节点同样如此。 二、软件下载 通过官网或者正规商店(如Google play)下载并且安装。 是的&#xff0c;先要下载一个无法使用的版本&#xff0c;后续对其进行修改。 三、下…

代码随想录(七) —— 二叉树部分

1. 二叉树的四种遍历方式的理解 前序遍历&#xff0c;中序遍历&#xff0c;后序遍历&#xff1b;层次遍历 结合另一篇博客&#xff0c;关于灵神的题单刷题 二叉树刷题记录-CSDN博客 理解&#xff1a; 在二叉树类型题目中&#xff0c;遍历顺序的选择需要根据具体问题来确定…

算法笔记day04

目录 1. 在字符串中找出连续最长的数字串 2.岛屿数量 3.拼三角 1. 在字符串中找出连续最长的数字串 字符串中找出连续最长的数字串_牛客题霸_牛客网 (nowcoder.com) 算法思路&#xff1a; 这是一道简单的双指针题目&#xff0c;首先用i遍历数组&#xff0c;当遍历到数字的时…

春日技术辅导:Spring Boot课程答疑

3系统分析 3.1可行性分析 通过对本课程答疑系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本课程答疑系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

数据驱动,漫途能耗管理系统打造高效节能新生态!

在我国能源消耗结构中&#xff0c;工业企业所占能耗比例相对较大。为实现碳达峰、碳中和目标&#xff0c;工厂需强化能效管理&#xff0c;减少能耗与成本。高效的能耗管理系统通过数据采集与分析&#xff0c;能实时监控工厂能源使用及报警情况&#xff0c;为节能提供数据。构建…

JVM 调优篇10 使用arthas排优

一 Arthas的作用 1.1 作用 1. 这个类从哪个 jar 包加载的&#xff1f;为什么会报各种类相关的 Exception&#xff1f; 2.是否有一个全局视角来查看系统的运行状况&#xff1f; 3. 有什么办法可以监控到JVM的实时运行状态&#xff1f; 4. 怎么快速定位应用的热点&#x…

TensorFlow详细配置

Anaconda 的安装路径配置系统环境变量 1 windows path配置 2 conda info C:\Users\Administrator>conda info active environment : None user config file : C:\Users\Administrator\.condarc populated config files : C:\Users\Administrator\.condarc …

【含文档】基于Springboot+Vue的高校科研信息管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

mybatis之入门(详细介绍)

1.Mybatis简介 MyBatis 是一个开源、轻量级的数据持久化框架&#xff0c;是 JDBC 和 Hibernate 的替代方案。MyBatis 内部封装了 JDBC&#xff0c;简化了加载驱动、创建连接、创建 statement 等繁杂的过程&#xff0c;开发者只需要关注 SQL 语句本身。 1.1.什么是Mybatis MyB…

VSCODE 导入cubeide工程

1.下载vscode及插件STM32 VS Code Ectersion 版本号1.0.0&#xff0c;之后这个有导入功能。 2.等待自动安装对应插件&#xff0c;提示缺少什么就补什么 3.在左侧出现stm32图标。点击Import a local project导入本地项目。 4.报错 [{"resource": "/f:V11/cmak…

【Linux】进程控制:从fork到exec

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 进程创建 &#x1f95d; fork函数初识&#x1f95d; 写时拷贝&#x1f95d; fork常规用法&#x1f95d; fork调用失败的原因 二&#xff1a;&#x1f525;…

群晖使用Docker搭建NASTool自动化观影工具并实现在线远程管理

文章目录 前言1. 本地搭建Nastool2. nastool基础设置3. 群晖NAS安装内网穿透工具4. 配置公网地址5. 配置固定公网地址 前言 本文主要分享一下如何在群晖NAS中本地部署Nastool&#xff0c;并结合cpolar内网穿透工具&#xff0c;轻松实现公网环境远程管理与访问本地NAS中储存的影…

惠普电脑怎么开启vt_惠普电脑开启vt虚拟化图文教程(支持新旧bios开启方法)

最近使用惠普电脑的小伙伴们问我&#xff0c;惠普电脑怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术&#xff0c;当CPU支持VT-x虚拟化技术&#xff0c;有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中&#xff0c;手动进行设置&#xff…

数字媒体产业园区:创新资源集聚,助力企业成长

在当今数字化浪潮汹涌的时代&#xff0c;数字媒体产业园区作为创意与技术的交汇点&#xff0c;正以其独特的魅力和无限的潜力&#xff0c;成为助力企业成长的重要平台。其中&#xff0c;“数字媒体产业园区”以其创新资源的集聚效应&#xff0c;为入驻企业提供了广阔的发展空间…

双十一有什么好物推荐?双十一必买清单大汇总

双十一的钟声即将敲响&#xff0c;数码好礼的选购热潮已然兴起。在这个信息爆炸的时代&#xff0c;我们被各种数码产品的广告和推荐所包围。如何从中筛选出真正适合自己的数码礼物呢&#xff1f;本文将以专业的视角、客观的评价&#xff0c;为你梳理数码产品的优缺点&#xff0…

将 QT 应用程序打包成如意玲珑软件包

在上一篇文章《国产系统之如意玲珑》中&#xff0c;我为大家介绍了一款创新的国产软件包管理工具——如意玲珑&#xff08;Linyaps&#xff09;。该工具集致力于解决 Linux 系统下传统软件包格式带来的复杂性和依赖问题&#xff0c;提供了一种更独立、更简洁的打包和管理方式。…

python爬虫,爬取网页壁纸图片

python爬虫实战&#xff0c;爬取网页壁纸图片 使用python爬取壁纸图片&#xff0c;保存到本地。 爬取彼岸图网&#xff0c;网站地址https://pic.netbian.com/ 本人小白&#xff0c;记录一下学习过程。 开始前的准备 安装python环境&#xff0c;略。 python编辑器pycharm2…

Linux:防火墙相关命令使用(Ubuntu)

1.安装防火墙工具 虚拟机安装好系统后&#xff0c;默认是没有管理工具的。如果已经安装可以跳过。 # 安装ufw&#xff08;Uncomplicated Firewall&#xff09;&#xff0c;这是Ubuntu上管理防火墙的一个简单工具 sudo apt-get install ufw2.开启和关闭防火墙 # 开启防火墙 sud…