golang学习之beego框架配合easyui实现增删改查及图片上传
demo目录:
upload文件夹主要放置上传的头像文件,main是主文件,所有效果如下:
主页面:
具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基于golang的后台管理系统</title>
<link rel="stylesheet" type="text/css" href="/static/js/jquery-easyui-1.4.3/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="/static/js/jquery-easyui-1.4.3/themes/icon.css">
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/locale/easyui-lang-zh_CN.js"></script>
<style>
.top{ background:url(/static/img/top.jpg) repeat-x; height:78px; position:relative;}
.top .title{ font-size:18px; color:#fff; font-family:\5FAE\8F6F\96C5\9ED1; position:absolute; left:20px; top:26px;}
.top .out{ position:absolute; top:30px; right:20px; font-size:12px; color:#fff;}
.top .out a{ color:#fff; text-decoration:none;}
.panel-body{
overflow: hidden;
}
*{ margin:0px; padding:0px; list-style:none;font-size: 12px;font-family: 宋体;}
.line20{ clear:both; font-size:0px; height:20px; overflow:hidden; }
.nlist-1 {line-height: 45px;color: #444;font-size: 14px}
.nlist-1 ul {padding: 0 0 0 20px;overflow:hidden;}
.nlist-1 ul:after {clear: both;content: ".";display: block;height: 0;visibility: hidden}
.nlist-1 ul li {float: left;margin-right: 10px;width: 32%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
.nlist-2 {line-height: 30px;border: 1px solid #ebebeb;color: #444;font-size: 14px;}
.nlist-2 h3 {margin: 0;padding: 0 0 0 20px;font-size: 12px;font-weight: bold;color: #333;line-height: 34px;height: 34px}
.nlist-2 h3 i {display: inline-block;margin-right: 3px;width: 14px;height: 16px;vertical-align: middle;background: url(/images/skin_icons.png) -56px -112px no-repeat;overflow: hidden}
.nlist-2 ul {padding: 0 0 10px 20px;overflow:hidden;}
.nlist-2 p{ padding-left:20px;}
.nlist-2 ul:after {clear: both;content: ".";display: block;height: 0;visibility: hidden}
.nlist-2 ul li {float: left;margin-right: 10px;width: 32%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis}
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: none;
}
a:active {
text-decoration: none;
}
</style>
<script>
var url;
function openTab(text, url, iconCls) {
if ($("#tabs").tabs("exists", text)) {
$("#tabs").tabs("select", text);
} else {
var content = "<iframe frameborder=0 scrolling='yes' style='width:100%;height:100%;' src='" + url + "'></iframe>";
$("#tabs").tabs("add", {
title: text,
iconCls: iconCls,
closable: true,
content: content
})
}
}
function loginOut(){
$.messager.confirm('提示', '确定要退出登录吗?', function (r) {
if (r) {
window.location.href="/login/loginOut";
}
});
}
</script>
</head>
<body class="easyui-layout">
<div class="top" region="north"><span class="title">基于golang的easyui后台管理系统</span><span class="out">欢迎 <a href='javascript:void(0)' onclick='about()'>admin</a> 登录 <a onclick="loginOut()" href="javascript:void(0)">退出</a></span></div>
<div region="center" style="overflow: hidden" id="center">
<div class="easyui-tabs" fit="true" id="tabs">
<div title="首页" data-options="iconCls:'icon-home'" id="main">
</div>
</div>
</div>
<div region="west" style="width:200px; overflow-y:auto; overflow-x:auto;;height: 500px" title="导航菜单" split="true">
<div class="easyui-accordion" data-options="fit:true,border:false">
<div title="会员管理" data-options="iconCls:'icon-wrench'" style="padding:10px">
<a href="javascript:openTab('会员管理','/user/index','icon-user_home')" class="easyui-linkbutton" data-options="plain:true,iconCls:'icon-user_home'">会员管理</a><br/>
</div>
</div>
</div>
</body>
</html>
删除:
新增/修改会员:
app.conf配置文件:
appname = easyui_crud
httpport = 8080
runmode = dev
#数据库配置
db.host = 192.168.20.132
db.port = 3306
db.user = root
db.pass = root
db.name = test
db.timezone = Asia/Shanghai
base.go主要放置一些公共操作:
package controllers
import (
"github.com/astaxie/beego"
)
type BaseController struct {
beego.Controller
}
func (this *BaseController) Rsp(status bool, str string) {
this.Data["json"] = &map[string]interface{}{"succ": status, "msg": str}
this.ServeJSON()
}
userController:
package controllers
import (
m "easyui_crud/models"
"fmt"
)
type UserController struct {
BaseController
}
func (this *UserController) Index() {
user := this.GetSession("userinfo")
if user != nil {
this.Data["userinfo"] = user
this.TplName = "main.html"
return
}
this.Redirect("/", 302)
}
func (this *UserController) UserIndex() {
this.TplName = "user/usermanage.html"
}
func (this *UserController) UserList() {
page, _ := this.GetInt64("page")
pageSize, _ := this.GetInt64("rows")
u := m.User{}
if this.GetString("id") != "" {
u.Id, _ = this.GetInt("id")
}
if this.GetString("name") != "" {
u.Name = this.GetString("name")
}
if this.GetString("phone") != "" {
u.Phone = this.GetString("phone")
}
nodes, cnt := m.GetUserList(page, pageSize, &u)
this.Data["json"] = &map[string]interface{}{"total": cnt, "rows": &nodes}
this.ServeJSON()
}
func (this *UserController) UserDel() {
idstr := this.GetString("ids")
err := m.DelUser(idstr)
if err != nil {
this.Rsp(false, err.Error())
} else {
this.Rsp(true, "删除成功")
}
}
func (this *UserController) UserAdd() {
u := m.User{}
u.Id, _ = this.GetInt("Id")
if err := this.ParseForm(&u); err != nil {
this.Rsp(false, err.Error())
return
}
id, err := m.AddUser(&u)
if err == nil && id > 0 {
this.Rsp(true, "新增成功")
return
} else {
this.Rsp(false, err.Error())
return
}
}
func (this *UserController) UserUpdate() {
u := m.User{}
if err := this.ParseForm(&u); err != nil {
this.Rsp(false, err.Error())
return
}
id, err := m.UpdateUser(&u)
if err == nil && id > 0 {
this.Rsp(true, "修改成功")
return
} else {
this.Rsp(false, err.Error())
return
}
}
func (this *UserController) UserUpload() {
f, fh, err := this.GetFile("uploadFile")
defer f.Close()
if err != nil {
fmt.Println("get file error ", err)
this.Data["json"] = &map[string]interface{}{"path": "", "succ": false}
this.ServeJSON()
} else {
fmt.Println(fh.Filename)
this.SaveToFile("uploadFile", "static/upload/"+fh.Filename)
this.Data["json"] = &map[string]interface{}{"path": "/static/upload/" + fh.Filename, "succ": true}
this.ServeJSON()
}
}
models下的init主要用来进行数据库初始化:
package models
import (
"net/url"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
func init() {
dbhost := beego.AppConfig.String("db.host")
dbport := beego.AppConfig.String("db.port")
dbname := beego.AppConfig.String("db.name")
dbuser := beego.AppConfig.String("db.user")
dbpass := beego.AppConfig.String("db.pass")
timezone := beego.AppConfig.String("db.timezone")
if dbport == "" {
dbport = "3306"
}
dsn := dbuser + ":" + dbpass + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"
if timezone != "" {
dsn = dsn + "&loc=" + url.QueryEscape(timezone)
}
orm.RegisterDataBase("default", "mysql", dsn, 5, 30)
if beego.AppConfig.String("runmode") == "dev" {
orm.Debug = true
}
}
user models,user类的增删改查具体实现封装:
package models
import (
"errors"
"fmt"
"log"
"strconv"
"strings"
"time"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/validation"
)
type User struct {
Id int
Name string `form:"name" valid:"Required;MaxSize(20);MinSize(6)"`
Pass string `form:"pass" valid:"Required;MaxSize(20);MinSize(6)"`
Email string `form:"email" valid:"Required;Email"`
Phone string `form:"phone" valid:"Required;Mobile"`
Image string `form:"image" valid:"MaxSize(50);MinSize(6)"`
Addr string `form:"addr" valid:"MaxSize(30)" form:"name"`
Regtime string
Birth string `form:"birth"`
Remark string `valid:"MaxSize(200)" form:"remark"`
}
func init() {
orm.RegisterModel(new(User))
}
func (u *User) TableName() string {
return "t_user"
}
func (this *User) ToString() string {
return fmt.Sprintf("Id:%d\tName:%s", this.Id, this.Name)
}
func checkUser(u *User) (err error) {
valid := validation.Validation{}
b, _ := valid.Valid(&u)
if !b {
for _, err := range valid.Errors {
log.Println(err.Key, err.Message)
return errors.New(err.Message)
}
}
return nil
}
func GetUserList(page int64, pageSize int64, user *User) (userlist []*User, count int64) {
o := orm.NewOrm()
qs := o.QueryTable("t_user")
var offset int64
if page > 1 {
offset = (page - 1) * pageSize
}
if user.Id != 0 {
qs = qs.Filter("id__exact", user.Id)
}
if user.Phone != "" {
qs = qs.Filter("phone__contains", user.Phone)
}
if user.Name != "" {
qs = qs.Filter("name__contains", user.Name)
}
qs.Limit(pageSize, offset).OrderBy("-Id").All(&userlist)
count, _ = qs.Count()
return userlist, count
}
func DelUser(idstr string) error {
ids := strings.Split(idstr, ",")
num, err := orm.NewOrm().QueryTable("t_user").Filter("id__in", ids).Delete()
if num > 0 && err == nil {
return nil
} else {
return err
}
}
func AddUser(u *User) (int64, error) {
if err := checkUser(u); err != nil {
return 0, err
}
o := orm.NewOrm()
user := new(User)
user.Name = u.Name
user.Email = u.Email
user.Phone = u.Phone
user.Image = u.Image
user.Addr = u.Addr
tm2, _ := time.Parse("2006-02-02", u.Birth) //日期字符串转为时间戳
user.Birth = strconv.FormatInt(tm2.Unix(), 10)
user.Remark = u.Remark
user.Regtime = strconv.FormatInt(time.Now().Unix(), 10) //获取当前时间戳
id, err := o.Insert(user)
return id, err
}
func UpdateUser(u *User) (int64, error) {
if err := checkUser(u); err != nil {
return 0, err
}
o := orm.NewOrm()
user := make(orm.Params)
if len(u.Name) > 0 {
user["Name"] = u.Name
}
if len(u.Phone) > 0 {
user["Phone"] = u.Phone
}
if len(u.Addr) > 0 {
user["Addr"] = u.Addr
}
if len(u.Email) > 0 {
user["Email"] = u.Email
}
if len(u.Birth) > 0 {
tm, _ := time.Parse("2006-02-02", u.Birth) //日期字符串转为时间戳
user["Birth"] = strconv.FormatInt(tm.Unix(), 10)
}
if len(u.Image) > 0 {
user["Image"] = u.Image
}
if len(u.Remark) > 0 {
user["Remark"] = u.Remark
}
if len(user) == 0 {
return 0, errors.New("update field is empty")
}
var table User
num, err := o.QueryTable(table).Filter("Id", u.Id).Update(user)
return num, err
}
func GetUserByUsername(username string) (user User) {
user = User{Name: username}
o := orm.NewOrm()
o.Read(&user, "Name")
return user
}
usermanage.html文件为用户tab页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>crud测试</title>
<link rel="stylesheet" type="text/css" href="/static/js/jquery-easyui-1.4.3/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="/static/js/jquery-easyui-1.4.3/themes/icon.css">
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-easyui-1.4.3/locale/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="/static/js/plugin/moment.js"></script>
<script src="/static/js/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
<script src="/static/js/jquery-file-upload/js/jquery.iframe-transport.js"></script>
<script src="/static/js/jquery-file-upload/js/jquery.fileupload.js"></script>
</head>
<body>
<table id="dg" title="会员管理" fitColumns="true" pagination="true" rownumbers="true" nowrap="true" class="easyui-datagrid"
fit="true" toolbar="#tb"
data-options="pageSize:25,pageList:[10,15,25,50,100]">
<thead>
<tr>
<th field="cb" checkbox="true" align="center"></th>
<th data-options="field:'Id',width:100,align:'center'">编号</th>
<th data-options="field:'Phone',width:130,align:'center'">手机</th>
<th data-options="field:'Name',width:100,align:'center'">姓名</th>
<th data-options="field:'Addr',width:130,align:'center'">地址</th>
<th data-options="field:'Email',width:130,align:'center'">邮箱</th>
<th data-options="field:'Regtime',width:130,align:'center',formatter:formatTime">注册时间</th>
<th data-options="field:'Birth',width:130,align:'center',formatter:formatBirth">生日</th>
<th data-options="field:'Image',width:130,align:'center',formatter:formatImg">头像</th>
<th data-options="field:'Remark',width:130,align:'center'">备注</th>
<th field="_id" width="140" align="center" data-options="formatter:formatOperate">操作</th>
</tr>
</thead>
</table>
<div id="tb">
<div style="margin-top: 5px;margin-bottom: 5px;">
<a href="javascript:openUserAddDialog()" class="easyui-linkbutton"
data-options="plain:true,iconCls:'icon-user_add'" plain="true">添加</a>
<a href="javascript:delNums()" class="easyui-linkbutton"
data-options="plain:true,iconCls:'icon-user_delete'" plain="true">删除</a>
</div>
<div style="margin-top: 5px;">
<table>
<tr>
<td align="right">会员编号:</td>
<td align="right"><input class="easyui-numberbox" id="s_id" size="20" style="width: 150px;"></td>
<td align="right">手机号:</td>
<td align="right"><input class="easyui-numberbox" id="s_phone" size="20" style="width: 150px;"></td>
<td align="right">昵称:</td>
<td align="right"><input class="easyui-textbox" id="s_name" size="20" style="width: 150px;"></td>
<td align="right"><a href="javascript:searchUser()" class="easyui-linkbutton"
data-options="plain:true,iconCls:'icon-2012092109942'">查询</a></td>
</tr>
</table>
</div>
</div>
<div id="dlg" class="easyui-dialog" style="width: 680px;height:630px;padding: 5px 5px" closed="true" buttons="#dlg-buttons" data-options="modal:true"
overflow-y="scroll">
<form id="form" method="post">
<table style="margin: 5px 5px;" cellspacing="5px">
<tr>
<td align="right" style="width: 140px;">手机号:</td>
<td align="left">
<input id="phone" name="phone" type="text" class="easyui-textbox" data-options="required:true"
style="width: 150px;">
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">姓名:</td>
<td align="left">
<input id="name" type="text" name="name" class="easyui-textbox" data-options="required:true"
style="width: 150px;"></span>
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">地址:</td>
<td align="left">
<input id="addr" name="addr" type="text" class="easyui-textbox" style="width: 150px;" data-options="required:true">
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">邮箱:</td>
<td align="left">
<input id="email" type="text" name="email" class="easyui-textbox" style="width: 150px;" data-options="required:true">
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">生日:</td>
<td align="left">
<input id="birth" type="text" name="birth" class="easyui-datebox" style="width: 150px;" data-options="required:true">
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">头像:</td>
<td align="left">
<input type="file" id="file_upload"/>
<input type="hidden" id="file_path" name="image"/>
</td>
<td align="left"> </td>
</tr>
<tr>
<td valign="top" align="left" style="width: 140px;"> </td>
<td align="left">
<img id="newImg" style="width: 100px;height: 110px;" src="/static/img/default.gif"> <span id="errMsg" style="color: red"></span>
</td>
<td align="left"> </td>
</tr>
<tr>
<td align="right" style="width: 140px;">备注:</td>
<td align="left">
<textarea rows="10" cols="65" id="remark" name="remark" placeholder="请简要描述您的专业经验"></textarea>
</td>
</tr>
</table>
</form>
</div>
<div id="dlg-buttons">
<a href="javascript:save()" class="easyui-linkbutton" iconCls="icon-ok" plain="true">提交</a>
<a href="javascript:cancel()" class="easyui-linkbutton" iconCls="icon-cancel" plain="true">取消</a>
</div>
<script type="text/javascript">
var url;
jQuery(function(){
jQuery("#dg").datagrid({
url:"/user/list"
});
});
function formatOperate(value, row, index){
var del = "<a href='#' onclick='javascript:del("+row.Id+")'>删除</a>";
var update = "<a href='#' onclick='javascript:openUpdateDlg("+index+")'>修改</a>";
return del + " " + update;
}
function formatImg(value, row, index){
if(value)return "<span title='"+value+"'>"+value.substr(0,25)+"</span>";
}
function del(id){
jQuery.messager.confirm("系统提示","您确认要删除该会员吗?",function(r){
if(r){
jQuery.post("/user/del",{ids:([id]).join(",")},function(result){
jQuery.messager.show({title:"提示",msg:result.msg});
jQuery("#dg").datagrid("reload");
},"json");
}
});
}
function delNums(){
var selectedRows=jQuery("#dg").datagrid('getSelections');
if(selectedRows.length==0){
jQuery.messager.show({title:"提示",msg:"请选择要删除的会员!"});
return;
}
var strIds=[];
for(var i=0;i<selectedRows.length;i++){
strIds.push(selectedRows[i].Id);
}
var ids=strIds.join(",");
jQuery.messager.confirm("系统提示","您确认要删除这<span style='color: red'>"+selectedRows.length+"</span>条数据吗?",function(r){
if(r){
jQuery.post("/user/del",{ids:ids},function(result){
jQuery.messager.show({title:"提示",msg:result.msg});
jQuery("#dg").datagrid("reload");
},"json");
}
});
}
function openUserAddDialog(){
jQuery("#form").form("reset");
jQuery("#dlg").dialog("open").dialog("setTitle", "新增会员");
url = "/user/add";
jQuery("#file_upload").attr("name","uploadFile");
jQuery("#newImg").attr("src","/static/img/default.gif");
}
function save(){
jQuery("#form").form("submit", {
url: url,
onSubmit: function (param) {
if (!jQuery(this).form("validate")) {
return false;
}
return true;
},
success: function (result) { //result返回为String类型,需用eval函数处理为Object型对象再判断
result = JSON.parse(result);
jQuery.messager.show({title:"提示",msg:result.msg});
jQuery("#dg").datagrid("reload");
jQuery("#dlg").dialog("close");
jQuery("#form").form("reset");
}
});
}
function cancel(){
jQuery("#form").form("reset");
jQuery("#dlg").dialog("close");
}
function formatTime(value, row, index){
if(value)return moment.unix(value).format("YYYY-MM-DD HH:mm:ss");
}
function formatBirth(value, row, index){
if(value)return moment.unix(value).format("YYYY-MM-DD");
}
function dispValue(row){
jQuery("#phone").textbox("setText",row.Phone);
jQuery("#name").textbox("setText",row.Name);
jQuery("#addr").textbox("setText",row.Addr);
jQuery("#email").textbox("setText",row.Email);
jQuery("#birth").datebox("setValue",row.Birth?moment.unix(row.Birth).format("YYYY-MM-DD"):"");
jQuery("#remark").val(row.Remark);
jQuery("#newImg").attr("src",row.Image?row.Image:"/static/img/default.gif");
}
function openUpdateDlg(index){
var row = jQuery("#dg").datagrid('getData').rows[index];
dispValue(row);
jQuery("#dlg").dialog("open").dialog("setTitle", "修改会员");
url = "/user/update?Id="+row.Id;
jQuery("#file_upload").attr("name","uploadFile");
}
jQuery("#file_upload").fileupload({
iframe: true,
dataType: 'json',
url: "/user/upload",//文件上传地址,当然也可以直接写在input的data-url属性内
done: function (e, result) {
if(result.result.succ){
jQuery("#newImg").attr("src",result.result.path);
jQuery("#file_path").val(result.result.path);
}else{
jQuery("#errMsg").html("文件上传出错");
}
}
});
</script>
</body>
</html>
main.go启动文件:
package main
import (
_ "easyui_crud/models"
_ "easyui_crud/routers" //调用routes下的Init()方法来注册路由
"github.com/astaxie/beego"
)
const VERSION = "1.0.0"
func main() {
beego.AppConfig.Set("version", VERSION)
beego.Run() //运行程序
}
用户登录、session拦截:
login.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页</title>
<script src="/static/bootstrap3/js/jquery-1.11.2.min.js"></script>
<STYLE>
body{
background: #ebebeb;
font-family: "Helvetica Neue","Hiragino Sans GB","Microsoft YaHei","\9ED1\4F53",Arial,sans-serif;
color: #222;
font-size: 12px;
}
*{padding: 0px;margin: 0px;}
.top_div{
background: #008ead;
width: 100%;
height: 400px;
}
.ipt{
border: 1px solid #d3d3d3;
padding: 10px 10px;
width: 290px;
border-radius: 4px;
padding-left: 35px;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s
}
.ipt:focus{
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)
}
.u_logo{
background: url("/static/img/username.png") no-repeat;
padding: 10px 10px;
position: absolute;
top: 43px;
left: 40px;
}
.p_logo{
background: url("/static/img/password.png") no-repeat;
padding: 10px 10px;
position: absolute;
top: 12px;
left: 40px;
}
a{
text-decoration: none;
}
.tou{
background: url("/static/img/tou.png") no-repeat;
width: 97px;
height: 92px;
position: absolute;
top: -87px;
left: 140px;
}
.left_hand{
background: url("/static/img/left_hand.png") no-repeat;
width: 32px;
height: 37px;
position: absolute;
top: -38px;
left: 150px;
}
.right_hand{
background: url("/static/img/right_hand.png") no-repeat;
width: 32px;
height: 37px;
position: absolute;
top: -38px;
right: -64px;
}
.initial_left_hand{
background: url("/static/img/hand.png") no-repeat;
width: 30px;
height: 20px;
position: absolute;
top: -12px;
left: 100px;
}
.initial_right_hand{
background: url("/static/img/hand.png") no-repeat;
width: 30px;
height: 20px;
position: absolute;
top: -12px;
right: -112px;
}
.left_handing{
background: url("/static/img/left-handing.png") no-repeat;
width: 30px;
height: 20px;
position: absolute;
top: -24px;
left: 139px;
}
.right_handinging{
background: url("/static/img/right_handing.png") no-repeat;
width: 30px;
height: 20px;
position: absolute;
top: -21px;
left: 210px;
}
</STYLE>
<SCRIPT type="text/javascript">
$(function(){
//得到焦点
$("#password").focus(function(){
$("#left_hand").animate({
left: "150",
top: " -38"
},{step: function(){
if(parseInt($("#left_hand").css("left"))>140){
$("#left_hand").attr("class","left_hand");
}
}}, 2000);
$("#right_hand").animate({
right: "-64",
top: "-38px"
},{step: function(){
if(parseInt($("#right_hand").css("right"))> -70){
$("#right_hand").attr("class","right_hand");
}
}}, 2000);
});
//失去焦点
$("#password").blur(function(){
$("#left_hand").attr("class","initial_left_hand");
$("#left_hand").attr("style","left:100px;top:-12px;");
$("#right_hand").attr("class","initial_right_hand");
$("#right_hand").attr("style","right:-112px;top:-12px");
});
});
function checkForm(){
var userName=$("#userName").val();
var password=$("#password").val();
if(userName==null||userName==""){
$("#error").html("用户名不能为空!");
return false;
}
if(password==null||password==""){
$("#error").html("密码不能为空!");
return false;
}
return true;
}
</SCRIPT>
</head>
<body>
<DIV class="top_div">
</DIV>
<form action="/" method="post" onsubmit="return checkForm()">
<DIV style="background: rgb(255, 255, 255); margin: -100px auto auto; border: 1px solid rgb(231, 231, 231); border-image: none; width: 400px; height: 200px; text-align: center;">
<DIV style="width: 165px; height: 96px; position: absolute;">
<DIV class="tou">
</DIV>
<DIV class="initial_left_hand" id="left_hand">
</DIV>
<DIV class="initial_right_hand" id="right_hand">
</DIV>
</DIV>
<P style="padding: 30px 0px 10px; position: relative;">
<SPAN class="u_logo"></SPAN>
<INPUT id="userName" name="userName" class="ipt" type="text" placeholder="请输入用户名" value="{{.user.Name}}">
</P>
<P style="position: relative;">
<SPAN class="p_logo"></SPAN>
<INPUT id="password" name="password" class="ipt" type="password" placeholder="请输入密码" value="{{.user.Pass}}">
</P>
<DIV style="height: 50px; line-height: 50px; margin-top: 30px; border-top-color: rgb(231, 231, 231); border-top-width: 1px; border-top-style: solid;">
<P style="margin: 0px 35px 20px 45px;">
<SPAN style="float: left;">golang开源博客系统</SPAN>
<span><font color="red" id="error">{{.errmsg}}</font></span>
<SPAN style="float: right;">
<input type="submit" style="background: rgb(0, 142, 173); padding: 7px 10px; border-radius: 4px; border: 1px solid rgb(26, 117, 152); border-image: none; color: rgb(255, 255, 255); font-weight: bold;" value="登录"/>
</SPAN>
</P>
</DIV>
</DIV>
</form>
<div style="text-align:center;padding-top: 30px">
Copyright © 2012-2016 Java知识分享网 版权所有
</div>
</body>
</html>
loginController:
// login
package controllers
import (
"fmt"
)
type LoginController struct {
BaseController
}
func (this *LoginController) UserIndex() {
this.TplName = "login.html"
}
func (this *LoginController) UserLogin() {
username := this.GetString("userName")
password := this.GetString("password")
user, err := CheckLogin(username, password)
if err == nil {
this.Redirect("/main", 302)
user.Pass = "" //将密码置空
fmt.Println(user)
this.SetSession("userinfo", user)
} else {
this.Data["user"] = user
this.Data["errmsg"] = err.Error()
this.TplName = "login.html"
}
}
lib下的stringutil.go工具类:
package lib
import (
"crypto/md5"
"encoding/hex"
)
//create md5 string
func Strtomd5(s string) string {
h := md5.New()
h.Write([]byte(s))
rs := hex.EncodeToString(h.Sum(nil))
return rs
}
//password hash function
func Pwdhash(str string) string {
return Strtomd5(str)
}
有疑问加站长微信联系(非本文作者)