conf/app.conf
appname = blog1 httpport = 8080 runmode = dev name=admin pwd=admin
controllersmy/attach.go
package controllersmy import ( "github.com/astaxie/beego" //导入beego包 "io" "net/url" "os" ) type AttachmentController struct { beego.Controller } func (c *AttachmentController) Get() { filePath, err := url.QueryUnescape(c.Ctx.Request.RequestURI[1:]) //去除最开头的一个/ if err != nil { c.Ctx.WriteString(err.Error()) return } f, err := os.Open(filePath) if err != nil { c.Ctx.WriteString(err.Error()) return } defer f.Close() _, err = io.Copy(c.Ctx.ResponseWriter, f) //2个参数是输出流和输入流 if err != nil { c.Ctx.WriteString(err.Error()) return } }
controllersmy/default.go
//model的上层,下层调用models来操作数据库 package controllersmy //跟外面的包名一致 import ( "github.com/astaxie/beego" //导入beego包 ) type MainController struct { beego.Controller //"github.com/astaxie/beego"包里面的Controller } func (c *MainController) Get() { c.TplName = "index.html" //返回页面名字 c.Data["isHome"] = true c.Data["isCookie"] = checkCookie(c.Ctx) }
controllersmy/login.go
package controllersmy import ( //"fmt" "github.com/astaxie/beego" //导入beego包 "github.com/astaxie/beego/context" //"net/url" ) type LoginController struct { beego.Controller } func (c *LoginController) Get() { c.Data["islogin"] = true isExit := c.Input().Get("exit") == "true" if isExit { c.Ctx.SetCookie("name", "", -1, "/") //-1就会删除cookie c.Ctx.SetCookie("pwd", "", -1, "/") return //不需要指定跳的首页了 } c.TplName = "login.html" //返回页面名字 } func (c *LoginController) Post() { //c.TplName = "login.html" //返回页面名字 c.Data["islogin"] = true //c.Ctx.WriteString(fmt.Sprint(c.Input())) //获取post时候带过来的参数,WriteString页面就跳转了不执行下面的了, uname := c.Input().Get("username") pwd := c.Input().Get("pwd") autologin := c.Input().Get("auto") == "on" //bool值 //跟app.conf里面的用户名和密码比对 if beego.AppConfig.String("name") == uname && beego.AppConfig.String("pwd") == pwd { maxAge := 0 if autologin { //自动登陆就要设置cookie maxAge = 1<<31 - 1 } c.Ctx.SetCookie("name", uname, maxAge, "/") //保存时间和保存路径 c.Ctx.SetCookie("pwd", uname, maxAge, "/") //保存时间和保存路径 c.Redirect("/welcome", 301) //登陆后重定向到欢迎页面 //c.TplName = "welcome.html" //返回页面名字,没有走过滤器controller,Redirect走了过滤器controller, } else { return } return } //整个包可访问 func checkCookie(ctx *context.Context) bool { ck, err := ctx.Request.Cookie("name") //获取请求带来的cookie if err != nil { return false } uname := ck.Value ck, err = ctx.Request.Cookie("pwd") //获取请求带来的cookie if err != nil { return false } pwd := ck.Value return beego.AppConfig.String("name") == uname && beego.AppConfig.String("pwd") == pwd }
controllersmy/topic.go
package controllersmy import ( "blog1/models" "github.com/astaxie/beego" //导入beego包 "path" ) type TopicController struct { beego.Controller } func (c *TopicController) Get() { c.TplName = "topic.html" //返回页面名字 c.Data["isTopic"] = true c.Data["isCookie"] = checkCookie(c.Ctx) } func (c *TopicController) Post() { if !checkAccount(c.Ctx) { //没有账号登陆页面 c.Redirect("/login", 302) return } title := c.Input().Get("title") content := c.Input().Get("content") //获取附件,上传删除修改跟cmss一样, _, fh, err = this.GetFile("attachment") if err != nil { beego.Error(err) } var attachFilename string if fh != nil { //保存附件 attachFilename = fh.FileName beego.Info(attachFilename) //filement:tmp.go //path:attachments/tmp.go err = this.SaveToFile("attachment", path.Join("attachments", attachFilename)) //path的第一个参数是工程目录下attachments文件夹名字 } if len(id) == 0 { err := models.AddTopic(title, content, attachFilename) } else { err := models.ModifyTopic(id, title, content, attachFilename) } if err != nil { beego.Debug(err) } c.Redirect("/topic/view"+id, 302) //添加完之后跳转到查看页面 } func (c *TopicController) Add() { c.TplName = "topic_add.html" //返回页面名字 c.Ctx.WriteString("topic_add") } func (c *TopicController) View() { //查看单偏文章 c.TplName = "topic_add.html" topic, err := models.GetOneTopic(c.Ctx.Input.Params("0")) //localhost:8080/topic/view/2343, Params("0")是2343 if err != nil { c.Redirect("/", 302) } c.Data["Topic"] = topic //如果要获取文章的回复,就到这个写 reply, err := models.GetAllApply(c.Ctx.Input.Params("0")) //localhost:8080/topic/view/2343, Params("0")是2343 if err != nil { c.Redirect("/", 302) } c.Data["reply"] = reply } func (c *TopicController) Modify() { //查看单偏文章 tid := c.Input().Get("id") //获取url中传过来的id topic, err := models.GetOneTopic(tid) //localhost:8080/topic/view/2343, Params("0")是2343 if err != nil { c.Redirect("/", 302) return } c.Data["Topic"] = topic c.Data["id"] = id c.Redirect("/", 302) } func (c *TopicController) Delete() { if !checkAccount(c.Ctx) { //没有账号登陆页面 c.Redirect("/login", 302) return } err := models.DeleteTopic(c.Ctx.Input.Params("0")) if err != nil { beego.Error(err) } c.TplName = "topic_add.html" }
controllersmy/welcome.go
package controllersmy //跟外面的包名一致 import ( "blog1/models" //"fmt" "github.com/astaxie/beego" //导入beego包 ) type WelcomeController struct { beego.Controller //"github.com/astaxie/beego"包里面的Controller } func (c *WelcomeController) Get() { op := c.Input().Get("op") beego.Debug("aaa") switch op { case "add": //c.Ctx.WriteString(fmt.Sprint(c.Input())) name := c.Input().Get("name") if len(name) == 0 { break } err := models.AddCatory(name) if err != nil { beego.Debug(err) return } case "del": beego.Debug("333") //c.Ctx.WriteString(fmt.Sprint(c.Input())) id := c.Input().Get("id") if len(id) == 0 { break } err := models.DelCatory(id) if err != nil { beego.Debug(err) } } c.Data["welcome"] = true var err error c.Data["Categories"], err = models.GetAllCategory(false) beego.Debug("111") beego.Debug(c.Data["Categories"]) if err != nil { beego.Debug(err) } c.TplName = "welcome.html" //返回页面名字,控制器之后写页面的名字, }
model/models.go
//操作数据库层,control调用, //使用beego的orm,先要创建好结构,然后将结构提交给orm进行创建表 package models import ( "github.com/Unknwon/com" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" //导入beegoorm的路径, _ "github.com/mattn/go-sqlite3" //go-sqlite3的驱动程序,_表示只执行初始化函数, "os" "path" "strconv" "strings" "time" ) const ( _DB_NAME = "data/beego1.db" _SQLITE3_DRIVER = "sqlite3" ) //后面再添加字段,也可以动态在表中增加 type Category struct { Id int64 //名称是Id,类型是int32或者int64,orm就认为是主键 Title string //不指定长度,默认是255字节 Created time.Time `orm:"index"` //创建时间,`orm:"index"`是tag,表示建立索引, Views int64 `orm:"index"` //浏览次数 TopicTime time.Time `orm:"index"` newziduan string } // //打印 // beego.Trace("trace") // beego.Info("info") // beego.Debug("debug") // beego.Warn("warn") // beego.Error("error") type Topic struct { Id int64 Uid int64 Title string Content string `orm:"size(5000)"` Attachment string Created time.Time `orm:"index"` //创建时间,`orm:"index"`是tag, Updated time.Time `orm:"index"` //创建时间,`orm:"index"`是tag, Views int64 `orm:"index"` //浏览次数 Author string ReplayTime time.Time `orm:"index"` } func RegisterDB() { if !com.IsExist(_DB_NAME) { //数据文件不存在就人为创建 os.MkdirAll(path.Dir(_DB_NAME), os.ModePerm) os.Create(_DB_NAME) } //orm需要先注册模型Category、Topic orm.RegisterModel(new(Category), new(Topic)) //注册驱动 orm.RegisterDriver(_SQLITE3_DRIVER, orm.DRSqlite) //注册默认数据库,可以是多个数据库,不管有几个数据库,默认数据库名字要叫default //驱动名称,数据库路径,最大连接数 orm.RegisterDataBase("default", _SQLITE3_DRIVER, _DB_NAME, 10) } func AddCatory(name string) error { beego.Debug("aaa1") o := orm.NewOrm() //获取orm对象 o.Using("default") c := &Category{Title: name, Created: time.Now(), Views: 11, TopicTime: time.Now()} //创建Category对象,title=传进来的name qs := o.QueryTable("category") //查询判断name是否被用了,使用的是beego的查询,Category是表名, err := qs.Filter("title", name).One(c) //根据title找到category,One(c)预期只有一个, beego.Debug(err) if err == nil { //==nil表示找到了 beego.Debug(err) return err } beego.Debug("aaa") //否则插入 id, err1 := o.Insert(c) beego.Debug("cc") if err1 != nil { //err != nil表示插入失败 beego.Debug(err1) return err1 } beego.Debug(id) beego.Debug("bbb") return nil } func GetAllCategory(isPaixu bool) ([]*Category, error) { //返回元素类型为Category的slice和error o := orm.NewOrm() o.Using("default") cs := make([]*Category, 0) //定义一个slice qs := o.QueryTable("category") var err error if isPaixu { _, err = qs.All(&cs) } else { _, err = qs.OrderBy("-created").All(&cs) //根据created降序 } return cs, err } func DelCatory(id string) error { cid, err := strconv.ParseInt(id, 10, 64) //10进制,64位大小 if err != nil { return err //人为非法操作 } o := orm.NewOrm() cat := &Category{Id: cid} //删除必须要指定主键,如果不知道主键就要QueryTable,Filter操作 _, err = o.Delete(cat) //前面下横线表示不得到,否则你不使用就会报错 return err } func AddTopic(name, con label, attachment string) error { //空格作为多个标签的分割,strings.Split(label, " ")通过空格把string分割成slice, //strings.Join将slice组合成string, label:="$"+strings.Join( strings.Split(label, " "), "#$") + "#" o := orm.NewOrm() //获取orm对象 o.Using("default") topic := &Topic{ Title: name, Created: time.Now(), Views: 11, } topic.Title := strings.Replace(strings.Replace(Topic.Label, "#", " ", -1), "$", "", -1)//先把#变成空格,然后去除$, _, err1 := o.Insert(topic) if err1 != nil { //err != nil表示插入失败 beego.Debug(err1) return err1 } return nil } func GetOneTopic(id string) (*Topic, error) { tidnum, err := strconv.ParseInt(id, 10, 64) //把10进制的转成64位 if err != nil { return nil, err } o := orm.NewOrm() topic := new(Topic) qs := o.QueryTable("topic") err = qs.Filter("id", tidnum).One(topic) //理论上只有一个,qs.Filter("id", tidnum).All(&topic)是获取所有, err = qs.Filter("labels__contains", "$"+label+"#")//模糊查询,包含查询, if err != nil { return nil, err } topic.Views++ //浏览数加一 _, err = o.Update(topic) //更新 return topic, err } func ModifyTopic(id, title, content string) error { tidnum, err := strconv.ParseInt(id, 10, 64) //把10进制的转成64位 if err != nil { return err } o := orm.NewOrm() topic := &Topic{Id: tidnum} if o.Read(topic) == nil { topic.Title = title topic.Content = content o.Update(topic) } return err } func DeleteTopic(id, title, content string) error { cid, err := strconv.ParseInt(id, 10, 64) //10进制,64位大小 if err != nil { return err //人为非法操作 } o := orm.NewOrm() top := &Topic{Id: cid} //删除必须要指定主键,如果不知道主键就要QueryTable,Filter操作 //先创建Topic对象,然后根据这个对象进行删除, _, err = o.Delete(top) //前面下横线表示不得到,否则你不使用就会报错 return err }
routers/router.go
package routers import ( "blog1/controllersmy" "github.com/astaxie/beego" "os" ) func init() { beego.Router("/", &controllersmy.MainController{}) //"blog1/controllersmy"里面的 &controllersmy beego.Router("/login", &controllersmy.LoginController{}) //"blog1/controllersmy"里面的 &controllersmy beego.Router("/welcome", &controllersmy.WelcomeController{}) beego.Router("/topic", &controllersmy.TopicController{}) beego.Router("/topic/add", &controllersmy.TopicController{}, "post:Add") //是post请求,并且是add方法, beego.Router("/topic/delete", &controllersmy.TopicController{}, "get:delete") //创建附件目录attachments os.Mkdir("attachments", os.ModePerm) //作为静态文件将附件反馈出来 beego.SetStaticPath("/attachments", "attachment") //不作为静态文件,作为一个控制器来处理 beego.Router("/attachment/:all", &controllersmy.AttachmentController{}) }
views/index.html
{{template "header" .}} <title>首页</title> <style type="text/css"> </style> </head> <body> {{template "navbar" .}} <!-- get请求就用a标签就可以了,post请求还要写一个表单 --> <form method="POST" action="/login"> 表单登陆 <input name="username" id="uname"/> <input name="pwd"/ id="pwd"> <input name="auto"/> <input type="submit" onclick="return checkInput();"> <input type="button" onclick="return backHome();">回到首页</input> </form> {{if .isCookie}} 有cokie了 {{end}} <script src="/static/js/reload.min.js"></script> <script type="text/javascript"> function checkInput(){ var name = document.getElementById("uname") if (name.value.length == 0) { alert("输入账号") return false//不提交表单 } var pwd = document.getElementById("pwd") if (pwd.value.length == 0) { alert("输入账号") return false//不提交表单 } return true//提交表单 } function backHome(){ window.location.href = "/" return false//表单一直不提交 } </script> </body> </html>
views/login.html
{{template "header" .}} <title>登陆成功</title> <style type="text/css"> </style> </head> <body> {{template "navbar" .}} 登陆成功 <script src="/static/js/reload.min.js"></script> </body>
views/T.head.tpl
{{define "header"}} <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="shortcut icon" href="" type="image/x-icon" /> <!-- <link id="mobile-style" type="text/css" rel="stylesheet" href="/static/css/main.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> --> {{end}}
views/T.navbar.tpl
{{define "navbar"}} <!-- if .isHome是contrloller传递进来的值 --> <div {{if .isHome}}class="active"{{end}} style="height:100px;width:400px;background-color:red;display:inline-block;">首页</div> <div {{if .islogin}}class="active"{{end}} style="height:100px;width:400px;background-color:blue;display:inline-block;">登陆</div> <ul class="nav navber-nav"> {{if .islogin}} <li>登陆成功</li> {{else}} <li>首页</li> {{end}} </ul> {{end}}
views/topic.html
{{template "header" .}} <title>topic</title> <style type="text/css"> </style> </head> <body> {{template "navbar" .}} {{.Topic.Title}} {{.Topic.Content}} {{.Topic.Attachment}} {{$tid := .Topic.Id}} <!-- 这就是一个模版变量 --> {{$isLogin := .IsLogin}} <script src="/static/js/reload.min.js"></script> {{if $isLogin}} <!-- 模版变量使用 --> <a href="/topic/modify?id={{.Tid}}&tid={{$tid}}">修改文章</a> <!-- 模版变量的使用 --> {{end}} <form method="POST" action="/topic"> <input name="name" id="name"/> <input name="op" id="op"/> <input type="file" name="attachment">文章附件</input> <input type="submit">添加文章</input> </form> </body>
views/welcome.html
{{template "header" .}} <title>huayin</title> <style type="text/css"> </style> </head> <body> {{template "navbar" .}} 欢迎你 <script src="/static/js/reload.min.js"></script> <tbody> {{range .Categories}} <th>{{.Id}}</th> <th>{{.Title}}</th> <th>{{.TopicTime}}</th> <a href="/welcome?op=del&id={{.Id}}">删除</a><br> {{end}} </tbody>> <form method="Get" action="/welcome"> <input name="name" id="name"/> <input name="op" id="op"/> <input type="submit">add添加del删除</input> </form> </body> </html>
main.go
package main import ( "blog1/models" _ "blog1/routers" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" ) func main() { orm.Debug = true orm.RunSyncdb("default", false, true) //建表,建立的数据库在data目录下, beego.Run() } func init() { //初始化数据库,使用navicat premiun查看数据库 models.RegisterDB() }