GoWeb 书城项目

数据库

连接数据库信息

grant all on *.* to 'root'@'%' identified by 'root';

创建书城数据库

create database bookstore0612 charset utf8;

创建用户表

create table users(
id int primary key auto_increment,
username varchar(100) not null unique,
password varchar(100) not null,
email varchar(100)
);

处理登录注册

在这里插入图片描述

utils/db.go

package utils

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

var (
	Db *sql.DB
	err error
)

func init()  {
	Db, err = sql.Open("mysql", "root:root@tcp(10.0.0.51:3306)/bookstore0612")
	if err != nil {
		panic(err.Error())
	}
}

model/user.go

package model

//User 结构体
type User struct {
	ID int
	Username string
	Password string
	Email string
}

dao/userdao.go

package dao

import (
	"bookstore0612/model"
	"bookstore0612/utils"
)

//CheckUserNameAndPassword 根据用户名和密码从数据库中查询一条记录
func CheckUserNameAndPassword(username string, password string) (*model.User, error) {
	//写sql语句
	sqlStr := "select id,username,password,email from users where username = ? and password = ?"
	//执行
	row := utils.Db.QueryRow(sqlStr, username, password)
	user := &model.User{}
	row.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
	return user, nil
}
//CheckUserName 根据用户名和密码从数据库中查询一条记录
func CheckUserName(username string) (*model.User, error) {
	//写sql语句
	sqlStr := "select id,username,password,email from users where username = ?"
	//执行
	row := utils.Db.QueryRow(sqlStr, username)
	user := &model.User{}
	row.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
	return user, nil
}

//SaveUser 向数据库中插入用户信息
func SaveUser(username string, password string, email string) error {
	//写sql语句
	sqlStr := "insert into users(username,password,email) values(?,?,?)"
	//执行
	_, err := utils.Db.Exec(sqlStr, username, password, email)
	if err != nil {
		return err
	}
	return nil
}

dao/userdao_test.go

package dao

import (
	"fmt"
	"testing"
)

func TestUser(t *testing.T)  {
	fmt.Println("测试userdao中的函数")
	t.Run("验证用户名或密码:", testLogin)
	t.Run("验证用户名:", testRegist)
	//t.Run("保存用户:", testSave)
}

func testLogin(t *testing.T)  {
	user, _ := CheckUserNameAndPassword("admin", "123456")
	fmt.Println("获取用户信息是:", user)
}
func testRegist(t *testing.T)  {
	user, _ := CheckUserName("admin")
	fmt.Println("获取用户信息是:", user)
}
func testSave(t *testing.T)  {
	SaveUser("admin3", "123456", "admin3@wuxing.com")
}

完成登录注册功能

main.go

package main

import (
	"bookstore0612/controller"
	"html/template"
	"net/http"
)

// IndexHandler  去首页
func IndexHandler(w http.ResponseWriter, r *http.Request)  {
	//解析模板
	t := template.Must(template.ParseFiles("views/index.html"))
	//执行
	t.Execute(w, "")
}
func main() {
	//设置处理静态资源
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("views/static/"))))
	http.Handle("/pages/", http.StripPrefix("/pages/", http.FileServer(http.Dir("views/pages/"))))
	http.HandleFunc("/main", IndexHandler)
	//去登陆
	http.HandleFunc("/login", controller.Login)
	//去注册
	http.HandleFunc("/regist", controller.Regist)
	http.ListenAndServe(":8080", nil)
}

controller/userhandler.go

package controller

import (
	"bookstore0612/dao"
	"html/template"
	"net/http"
)

//Login 处理用户登陆函数
func Login(w http.ResponseWriter, r *http.Request)  {
	//获取用户名和密码
	username := r.PostFormValue("username")
	password := r.PostFormValue("password")
	//调用userdao中验证用户名和密码的方法
	user, _ := dao.CheckUserNameAndPassword(username, password)
	if user.ID > 0 {
		//用户名和密码正确
		t := template.Must(template.ParseFiles("views/pages/user/login_success.html"))
		t.Execute(w, "")
	} else {
		//用户名或密码不正确
		t := template.Must(template.ParseFiles("views/pages/user/login.html"))
		t.Execute(w, "用户名或密码不正确!")
	}
}
//Regist 处理用户注册函数
func Regist(w http.ResponseWriter, r *http.Request)  {
	//获取用户名和密码
	username := r.PostFormValue("username")
	password := r.PostFormValue("password")
	email := r.PostFormValue("email")
	//调用userdao中验证用户名和密码的方法
	user, _ := dao.CheckUserName(username)
	if user.ID > 0 {
		//用户名已经存在
		t := template.Must(template.ParseFiles("views/pages/user/regist.html"))
		t.Execute(w, "用户名已存在!")
	} else {
		//用户名可用,将用户保存到数据库中
		dao.SaveUser(username, password, email)
		t := template.Must(template.ParseFiles("views/pages/user/regist_success.html"))
		t.Execute(w, "")
	}
}

通过发送Ajax验证用户名

			//发送Ajax请求验证用户名是否存在
			//给输入用户名的文本框绑定change事件
			$("#username").change(function(){
				//获取用户输入的用户名
				var username = $(this).val();
				//设置请求地址
				var url = "/checkUserName";
				//设置请求参数
				var param = {"username":username};
				//发送Ajax请求
				$.post(url,param,function(res){
					//将显示提示信息的span元素显示
					$("#msg").show();
					//将响应信息设置到span元素中
					$("#msg").html(res);
				});
			});
							<div class="tit">
								<h1>注册尚硅谷会员</h1>
								<span class="errorMsg" id="msg">{{.}}</span>
							</div>
	//通过Ajax请求验证用户名是否可用
	http.HandleFunc("/checkUserName", controller.CheckUserName)
//CheckUserName 通过发送Ajax验证用户名是否可用
func CheckUserName(w http.ResponseWriter, r *http.Request)  {
	//获取用户输入的用户名
	username := r.PostFormValue("username")
	//调用userdao中验证用户名和密码的方法
	user, _ := dao.CheckUserName(username)
	if user.ID > 0 {
		//用户名已经存在
		w.Write([]byte("用户名已存在!"))
	} else {
		//用户名可用
		w.Write([]byte("<font style='color:green'>用户名可用! </font>"))
	}
}

获取所有图书

创建表

create table books(
id int primary key auto_increment,
title varchar(100) not null,
author varchar(100) not null,
price double(11,2) not null,
sales int not null,
stock int not null,
img_path varchar(100)
);

插入数据

INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('解忧杂货店','东野圭吾',27.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('边城','沈从文',23.00,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('中国哲学史','冯友兰',44.5,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('忽然七日',' 劳伦',19.33,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('苏东坡传','林语堂',19.30,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('百年孤独','马尔克斯',29.50,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('扶桑','严歌苓',19.8,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('给孩子的诗','北岛',22.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('为奴十二年','所罗门',16.5,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('平凡的世界','路遥',55.00,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('悟空传','今何在',14.00,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('硬派健身','斌卡',31.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('从晚清到民国','唐德刚',39.90,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('三体','刘慈欣',56.5,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('看见','柴静',19.50,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('活着','余华',11.00,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('小王子','安托万',19.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('我们仨','杨绛',11.30,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('生命不息,折腾不止','罗永浩',25.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('皮囊','蔡崇达',23.90,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('恰到好处的幸福','毕淑敏',16.40,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('大数据预测','埃里克',37.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('人月神话','布鲁克斯',55.90,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('C语言入门经典','霍尔顿',45.00,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('数学之美','吴军',29.90,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('Java编程思想','埃史尔',70.50,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('设计模式之禅','秦小波',20.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('图解机器学习','杉山将',33.80,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('艾伦图灵传','安德鲁',47.20,100,100,'static/img/default.jpg');
INSERT INTO books (title, author ,price, sales , stock , img_path) VALUES('教父','马里奥普佐',29.00,100,100,'static/img/default.jpg');

book.go

package model

//Book 结构体
type Book struct {
	Id int
	Title string
	Author string
	Price float64
	Sales int
	Stock int
	ImgPath string
}

bookdao.go

package dao

import (
	"bookstore0612/model"
	"bookstore0612/utils"
)

// GetBooks 获取数据库中所有的图书
func GetBooks() ([]*model.Book, error) {
	// 写sql
	sqlStr := "select id,title,author,price,sales,stock,img_path from books"
	//执行
	rows, err := utils.Db.Query(sqlStr)
	if err != nil {
		return nil, err
	}
	var books []*model.Book
	for rows.Next() {
		book := &model.Book{}
		//给book中的字段赋值
		rows.Scan(&book.Id, &book.Title, &book.Author, &book.Price, &book.Sales, &book.Stock, &book.ImgPath)
		//将book添加到books中
		books = append(books, book)
	}
	return books, nil
}

测试

package dao

import (
	"fmt"
	"testing"
)

func TestMain(m *testing.M)  {
	fmt.Println("测试bookdao中的方法")
	m.Run()
}

func TestUser(t *testing.T)  {
	//fmt.Println("测试userdao中的函数")
	//t.Run("验证用户名或密码:", testLogin)
	//t.Run("验证用户名:", testRegist)
	//t.Run("保存用户:", testSave)
}

func testLogin(t *testing.T)  {
	user, _ := CheckUserNameAndPassword("admin", "123456")
	fmt.Println("获取用户信息是:", user)
}
func testRegist(t *testing.T)  {
	user, _ := CheckUserName("admin")
	fmt.Println("获取用户信息是:", user)
}
func testSave(t *testing.T)  {
	SaveUser("admin3", "123456", "admin3@wuxing.com")
}

func TestBook(t *testing.T)  {
	fmt.Println("测试bookdao中的相关函数")
	t.Run("测试获取所有图书", testGetBooks)
}

func testGetBooks(t *testing.T)  {
	books, _ := GetBooks()
	//遍历得到每一本图书
	for k, v := range books {
		fmt.Printf("第%v本图书的信息是: %v\n", k + 1, v)
	}
}

manager.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>后台管理</title>
<link type="text/css" rel="stylesheet" href="/static/css/style.css" >
<style type="text/css">
	h1 {
		text-align: center;
		margin-top: 200px;
	}
</style>
</head>
<body>
	
	<div id="header">
			<img class="logo_img" alt="" src="/static/img/logo.gif" >
			<span class="wel_word">后台管理系统</span>
			<div>
				<a href="/getBooks">图书管理</a>
				<a href="/">返回商城</a>
			</div>
	</div>
	
	<div id="main">
		<h1>欢迎管理员进入后台管理系统</h1>
	</div>
	
	<div id="bottom">
		<span>
			尚硅谷书城.Copyright &copy;2015
		</span>
	</div>
</body>
</html>

main.go

...
	//获取所有图书
	http.HandleFunc("/getBooks", controller.GetBooks)
...

bookhandler.go

package controller

import (
	"bookstore0612/dao"
	"html/template"
	"net/http"
)

//GetBooks 获取所有图书
func GetBooks(w http.ResponseWriter, r *http.Request)  {
	//调用bookdao中获取所有图书的函数
	books, _ := dao.GetBooks()
	//解析模板文件
	t := template.Must(template.ParseFiles("views/pages/manager/book_manager.html"))
	//执行
	t.Execute(w, books)
}

book_manager.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<link type="text/css" rel="stylesheet" href="/static/css/style.css" >
</head>
<body>
	
	<div id="header">
			<img class="logo_img" alt="" src="/static/img/logo.gif" >
			<span class="wel_word">图书管理系统</span>
			<div>
				<a href="/pages/manager/book_manager.html">图书管理</a>
				<a href="/">返回商城</a>
			</div>
	</div>
	
	<div id="main">
		<table>
			<tr>
				<td>名称</td>
				<td>价格</td>
				<td>作者</td>
				<td>销量</td>
				<td>库存</td>
				<td colspan="2">操作</td>
			</tr>
			{{range .}}
			<tr>
				<td>{{.Title}}</td>
				<td>{{.Price}}</td>
				<td>{{.Author}}</td>
				<td>{{.Sales}}</td>
				<td>{{.Stock}}</td>
				<td><a href="/pages/manager/book_edit.html">修改</a></td>
				<td><a href="#">删除</a></td>
			</tr>
			{{end}}
			<tr>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td><a href="/pages/manager/book_edit.html">添加图书</a></td>
			</tr>
		</table>
	</div>
	
	<div id="bottom">
		<span>
			尚硅谷书城.Copyright &copy;2015
		</span>
	</div>
</body>
</html>

添加图书

book_edit.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>编辑图书</title>
<link type="text/css" rel="stylesheet" href="/static/css/style.css" >
<style type="text/css">
	h1 {
		text-align: center;
		margin-top: 200px;
	}
	
	h1 a {
		color:red;
	}
	
	input {
		text-align: center;
	}
</style>
</head>
<body>
		<div id="header">
			<img class="logo_img" alt="" src="/static/img/logo.gif" >
			<span class="wel_word">编辑图书</span>
			<div>
				<a href="/pages/manager/book_manager.html">图书管理</a>
				<a href="/">返回商城</a>
			</div>
		</div>
		
		<div id="main">
			<form action="/addBook" method="POST">
				<table>
					<tr>
						<td>名称</td>
						<td>价格</td>
						<td>作者</td>
						<td>销量</td>
						<td>库存</td>
						<td colspan="2">操作</td>
					</tr>		
					<tr>
						<td><input name="title" type="text" value=""/></td>
						<td><input name="price" type="text" value=""/></td>
						<td><input name="author" type="text" value=""/></td>
						<td><input name="sales" type="text" value=""/></td>
						<td><input name="stock" type="text" value=""/></td>
						<td><input type="submit" value="提交"/></td>
					</tr>		
				</table>
			</form>
			
	
		</div>
		
		<div id="bottom">
			<span>
				五行哥书城.Copyright &copy;2015
			</span>
		</div>
</body>
</html>

main.go

	//添加图书
	http.HandleFunc("/addBook", controller.AddBook)

bookhandler.go

// AddBook添加图书
func AddBook(w http.ResponseWriter, r *http.Request)  {
	//获取图书信息
	title := r.PostFormValue("title")
	author := r.PostFormValue("author")
	price := r.PostFormValue("price")
	sales := r.PostFormValue("sales")
	stock := r.PostFormValue("stock")
	//将价格,销量,库存转换
	fPrice, _ := strconv.ParseFloat(price,64)
	iSales, _ := strconv.ParseInt(sales, 10, 0)
	iStock, _ := strconv.ParseInt(stock, 10, 0)
	//创建Book
	book := &model.Book{
		Title: title,
		Author: author,
		Price: fPrice,
		Sales: int(iSales),
		Stock: int(iStock),
		ImgPath: "/static/img/default.jpg",
	}
	//调用bookdao中添加图书的函数
	dao.AddBook(book)
	//调用GetBooks函数再查询一次
	GetBooks(w, r)

}

bookdao.go

// AddBook 向数据库中添加一本图书
func AddBook(b *model.Book) error {
	//写sql
	sqlStr := "insert into books(title,author,price,sales,stock,img_path) values(?,?,?,?,?,?)"
	//执行sql
	_, err := utils.Db.Exec(sqlStr,b.Title,b.Author,b.Price,b.Sales,b.Stock,b.ImgPath)
	if err != nil {
		return err
	}
	return nil
}

删除图书

book_manager.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<link type="text/css" rel="stylesheet" href="/static/css/style.css" >
<script src="/static/script/jquery-1.7.2.js"></script>
<script>
	$(function() {
		//给删除图书的超链接绑定事件
		$(".deleteBook").click(function() {
			//获取书名
			var title = $(this).attr("id");
			// var flag = confirm("确定要删除["+title+"] 这本图书吗?");
			// if (!flag){
			// 	//取消默认行为
			// 	return false;
			// }
			return confirm("确定要删除["+title+"] 这本图书吗?");
		});
	});
</script>
</head>
<body>
	
	<div id="header">
			<img class="logo_img" alt="" src="/static/img/logo.gif" >
			<span class="wel_word">图书管理系统</span>
			<div>
				<a href="/pages/manager/book_manager.html">图书管理</a>
				<a href="/">返回商城</a>
			</div>
	</div>
	
	<div id="main">
		<table>
			<tr>
				<td>名称</td>
				<td>价格</td>
				<td>作者</td>
				<td>销量</td>
				<td>库存</td>
				<td colspan="2">操作</td>
			</tr>
			{{range .}}
			<tr>
				<td>{{.Title}}</td>
				<td>{{.Price}}</td>
				<td>{{.Author}}</td>
				<td>{{.Sales}}</td>
				<td>{{.Stock}}</td>
				<td><a href="/pages/manager/book_edit.html">修改</a></td>
				<td><a id="{{.Title}}" class="deleteBook" href="/deleteBook?bookId={{.Id}}">删除</a></td>
			</tr>
			{{end}}
			<tr>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td></td>
				<td><a href="/pages/manager/book_edit.html">添加图书</a></td>
			</tr>
		</table>
	</div>
	
	<div id="bottom">
		<span>
			五行哥书城.Copyright &copy;2015
		</span>
	</div>
</body>
</html>

main.go

	//删除图书
	http.HandleFunc("/deleteBook", controller.DeleteBook)

bookhandler.go

// DeleteBook 删除图书
func DeleteBook(w http.ResponseWriter, r *http.Request)  {
	//获取要删除的图书的id
	bookID := r.FormValue("bookId")
	//调用bookdao中删除图书函数
	dao.DeleteBook(bookID)
	//调用GetBooks函数再查询一次
	GetBooks(w, r)

}

bookdao.go

//DeleteBook 根据图书的id从数据库中删除图书
func DeleteBook(bookID string) error {
	//写sql
	sqlStr := "delete from books where id = ?"
	//执行
	_, err := utils.Db.Exec(sqlStr, bookID)
	if err != nil {
		return err
	}
	return nil
}

修改图书

分页功能

首页图书显示

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuxingge

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值