mirror of https://github.com/mindoc-org/mindoc.git
实现简单的权限控制
parent
6fb801d7ba
commit
f7fc11ed7c
|
@ -0,0 +1,31 @@
|
|||
package acl
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var AclList = &sync.Map{}
|
||||
|
||||
func AddMemberPermission(account string,resource Resource) {
|
||||
key := account + "!" + resource.Code
|
||||
|
||||
AclList.Store(key,resource)
|
||||
}
|
||||
|
||||
//判断指定的资源是否可以访问
|
||||
func IsAllow(account ,controllerName,actionName,methodName string) bool {
|
||||
|
||||
key := fmt.Sprintf("%s!%s!%s!%s",account,controllerName,actionName,methodName)
|
||||
fmt.Println(key)
|
||||
if _,ok := AclList.Load(key);ok {
|
||||
return true
|
||||
}
|
||||
key = fmt.Sprintf("%s!%s!%s!*",account,controllerName,actionName)
|
||||
fmt.Println(key)
|
||||
if _,ok := AclList.Load(key);ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package acl
|
||||
|
||||
var Modules = make(map[string]*Module)
|
||||
|
||||
//模块
|
||||
type Module struct {
|
||||
Name string
|
||||
Description string
|
||||
Code string
|
||||
Resources map[string]*Resource
|
||||
}
|
||||
|
||||
//资源
|
||||
type Resource struct {
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
ControllerName string `json:"controller_name"`
|
||||
ActionName string `json:"action_name"`
|
||||
MethodName string `json:"method_name"`
|
||||
}
|
||||
|
||||
|
||||
func NewModule() *Module {
|
||||
return &Module{ Resources : make(map[string]*Resource)}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
Modules["Common"] = &Module{
|
||||
Name : "公共功能",
|
||||
Code : "Common",
|
||||
Description:"所有用户都有的功能",
|
||||
Resources : map[string]*Resource {
|
||||
"Common!Account!Login!*" : { Name: "用户登录" , Code:"Account!Login!*", ControllerName:"Account",ActionName:"Login",MethodName:"*"},
|
||||
"Common!Account!Register!*" : { Name: "用户注册" , Code:"Account!Register!*", ControllerName:"Account",ActionName:"Register",MethodName:"*"},
|
||||
"Common!Account!FindPassword!*" : { Name: "找回密码" , Code:"Account!FindPassword!*", ControllerName:"Account",ActionName:"FindPassword",MethodName:"*"},
|
||||
"Common!Account!ValidEmail!*" : { Name: "邮箱修改密码" , Code:"Account!ValidEmail!*", ControllerName:"Account",ActionName:"ValidEmail",MethodName:"*"},
|
||||
"Common!Account!Logout!*" : { Name: "退出登录" , Code:"Account!Logout!*", ControllerName:"Account",ActionName:"Logout",MethodName:"*"},
|
||||
"Common!Account!Captcha!*" : { Name: "图片验证码" , Code:"Account!Captcha!*", ControllerName:"Account",ActionName:"Captcha",MethodName:"*"},
|
||||
"Common!Home!Index!*" : { Name:"站点首页",Code:"Home!Index!*",ControllerName:"Home",ActionName:"Index",MethodName:"*"},
|
||||
"Common!Search!Index!*" : { Name:"项目搜索",Code:"Search!Index!*",ControllerName:"Search",ActionName:"Index",MethodName:"*"},
|
||||
"Common!Error!Error404!*" : { Name:"404页面", Code:"Error!Index!*", ControllerName:"Error", ActionName:"Error404",MethodName:"*" },
|
||||
"Common!Error!Error403!*" : { Name:"403页面", Code:"Error!Index!*", ControllerName:"Error", ActionName:"Error403",MethodName:"*" },
|
||||
"Common!Error!Error500!*" : { Name:"500页面", Code:"Error!Error500!*", ControllerName:"Error", ActionName:"Error500",MethodName:"*" },
|
||||
},
|
||||
}
|
||||
|
||||
Modules["MemberCommon"] = &Module{
|
||||
Name : "用户公共功能",
|
||||
Code : "MemberCommon",
|
||||
Description:"只有登录用户才有的功能",
|
||||
Resources : map[string]*Resource {
|
||||
"MemberCommon!Book!Index!*" : { Name: "项目列表" , Code:"Book!Index!*", ControllerName:"Book",ActionName:"Index",MethodName:"*"},
|
||||
"MemberCommon!Book!Dashboard!*" : { Name: "项目概述" , Code:"Book!Index!*", ControllerName:"Book",ActionName:"Dashboard",MethodName:"*"},
|
||||
},
|
||||
}
|
||||
|
||||
Modules["Book"] = &Module{
|
||||
Name:"项目管理",
|
||||
Code:"Book",
|
||||
Resources: map[string]*Resource {
|
||||
"Book!Book!Setting!*" : { Name: "项目设置查看" , Code:"Book!Setting!*", ControllerName:"Book",ActionName:"Setting",MethodName:"*"},
|
||||
"Book!Book!SaveBook!*" : { Name: "项目设置保存" , Code:"Book!SaveBook!*", ControllerName:"Book",ActionName:"SaveBook",MethodName:"*"},
|
||||
},
|
||||
}
|
||||
|
||||
Modules["Document"] = &Module{
|
||||
Name:"文档管理",
|
||||
Code:"Book",
|
||||
Resources: map[string]*Resource {
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
Modules["Label"] = &Module{
|
||||
Name:"标签管理",
|
||||
Code:"Book",
|
||||
Resources: map[string]*Resource {
|
||||
|
||||
},
|
||||
}
|
||||
Modules["Manager"] = &Module{
|
||||
Name:"后台管理",
|
||||
Code:"Book",
|
||||
Resources: map[string]*Resource {
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
for _,resource := range Modules["Common"].Resources {
|
||||
AddMemberPermission("anonymous",*resource)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -97,7 +97,6 @@ func RegisterModel() {
|
|||
new(models.Label),
|
||||
new(models.MemberGroup),
|
||||
new(models.MemberGroupMembers),
|
||||
new(models.Resource),
|
||||
)
|
||||
//migrate.RegisterMigration()
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
//系统安装.
|
||||
|
@ -79,24 +80,32 @@ func initialization() {
|
|||
err := models.NewOption().Init()
|
||||
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
beego.Error("初始化全局配置失败 => ",err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
InitMemberGroup()
|
||||
|
||||
|
||||
member, err := models.NewMember().FindByFieldFirst("account", "admin")
|
||||
|
||||
//如果用户不存在,则添加用户,否则需要批量更新用户角色
|
||||
if err == orm.ErrNoRows {
|
||||
beego.Info("正在创建默认用户.")
|
||||
|
||||
member.Account = "admin"
|
||||
member.Avatar = "/static/images/headimgurl.jpg"
|
||||
member.Password = "123456"
|
||||
member.AuthMethod = "local"
|
||||
member.Role = 0
|
||||
member.Role = 1
|
||||
member.Email = "admin@iminho.me"
|
||||
|
||||
if err := member.Add(); err != nil {
|
||||
panic("Member.Add => " + err.Error())
|
||||
beego.Error("创建默认用户失败 => " + err.Error())
|
||||
os.Exit(0)
|
||||
}
|
||||
beego.Info("正在创建默认项目.")
|
||||
|
||||
book := models.NewBook()
|
||||
|
||||
|
@ -116,18 +125,60 @@ func initialization() {
|
|||
book.Theme = "default"
|
||||
|
||||
if err := book.Insert(); err != nil {
|
||||
panic("Book.Insert => " + err.Error())
|
||||
os.Exit(0)
|
||||
beego.Error("创建默认项目失败 => " , err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//初始化用户组
|
||||
func InitMemberGroup() {
|
||||
beego.Info("正在创建用户组.")
|
||||
|
||||
group := models.NewMemberGroup()
|
||||
|
||||
group.GroupId = 1
|
||||
group.GroupName = "管理员组"
|
||||
group.GroupNumber = 1
|
||||
group.GroupNumber = 0
|
||||
group.CreateTime = time.Now()
|
||||
group.CreateAt = 1
|
||||
group.IsEnableDelete = false
|
||||
|
||||
group.InsertOrUpdate()
|
||||
|
||||
if err := group.InsertOrUpdate();err != nil{
|
||||
beego.Error("创建用户组失败 ",group.GroupName,err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
group.GroupId = 2
|
||||
group.GroupName = "普通用户组"
|
||||
group.GroupNumber = 0
|
||||
group.CreateTime = time.Now()
|
||||
group.CreateAt = 1
|
||||
group.IsEnableDelete = false
|
||||
|
||||
group.InsertOrUpdate()
|
||||
|
||||
if err := group.InsertOrUpdate();err != nil{
|
||||
beego.Error("创建用户组失败 ",group.GroupName,err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
group.GroupId = 3
|
||||
group.GroupName = "匿名用户组"
|
||||
group.GroupNumber = 0
|
||||
group.CreateTime = time.Now()
|
||||
group.CreateAt = 1
|
||||
group.IsEnableDelete = false
|
||||
group.Resources = "1,2,3,4,5"
|
||||
|
||||
if err := group.InsertOrUpdate();err != nil{
|
||||
beego.Error("创建用户组失败 ",group.GroupName,err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -337,7 +337,7 @@ func (c *AccountController) ValidEmail() {
|
|||
password2 := c.GetString("password2")
|
||||
captcha := c.GetString("code")
|
||||
token := c.GetString("token")
|
||||
mail := c.GetString("mail")
|
||||
email := c.GetString("mail")
|
||||
|
||||
if password1 == "" {
|
||||
c.JsonResult(6001, "密码不能为空")
|
||||
|
@ -368,7 +368,7 @@ func (c *AccountController) ValidEmail() {
|
|||
}
|
||||
sub_time := member_token.SendTime.Sub(time.Now())
|
||||
|
||||
if !strings.EqualFold(member_token.Email, mail) || sub_time.Minutes() > float64(mail_conf.MailExpired) || !member_token.ValidTime.IsZero() {
|
||||
if !strings.EqualFold(member_token.Email, email) || sub_time.Minutes() > float64(mail_conf.MailExpired) || !member_token.ValidTime.IsZero() {
|
||||
|
||||
c.JsonResult(6008, "验证码已过期,请重新操作。")
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ import (
|
|||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/lifei6671/mindoc/utils"
|
||||
"github.com/lifei6671/mindoc/acl"
|
||||
)
|
||||
|
||||
type BaseController struct {
|
||||
beego.Controller
|
||||
Member *models.Member
|
||||
MemberResourceList []*models.Resource
|
||||
Option map[string]string
|
||||
EnableAnonymous bool
|
||||
EnableDocumentHistory bool
|
||||
|
@ -78,25 +78,12 @@ func (c *BaseController) Prepare() {
|
|||
}
|
||||
}
|
||||
}
|
||||
roleId := 4
|
||||
if c.Member != nil && c.Member.MemberId > 0 {
|
||||
roleId = c.Member.Role
|
||||
}
|
||||
//如果没有访问权限
|
||||
if !(acl.IsAllow("anonymous",strings.TrimSuffix(controller,"Controller"),action,c.Ctx.Input.Method()) ||
|
||||
(c.Member != nil && c.Member.Role > 0 && acl.IsAllow(c.Member.Account,strings.TrimSuffix(controller,"Controller"),action,c.Ctx.Input.Method()))) {
|
||||
|
||||
resourceList,err := models.NewMemberGroup().FindMemberGroupResourceList(roleId)
|
||||
if err != nil {
|
||||
beego.Error("获取用户许可资源时出错 =>", err)
|
||||
c.ShowErrorPage(500,"获取用户许可资源时出错")
|
||||
c.ShowErrorPage(403,"权限不足")
|
||||
}
|
||||
c.MemberResourceList = resourceList
|
||||
c.Data["MemberResource"] = resourceList
|
||||
|
||||
for _,resource := range resourceList {
|
||||
if resource.ControllerName == controller && resource.ActionName == action && resource.HttpMethod == c.Ctx.Input.Method() {
|
||||
return
|
||||
}
|
||||
}
|
||||
c.ShowErrorPage(403,"权限不足")
|
||||
}
|
||||
|
||||
// SetMember 获取或设置当前登录用户信息,如果 MemberId 小于 0 则标识删除 Session
|
||||
|
@ -109,6 +96,9 @@ func (c *BaseController) SetMember(member models.Member) {
|
|||
} else {
|
||||
c.SetSession(conf.LoginSessionName, member)
|
||||
c.SetSession("uid", member.MemberId)
|
||||
for _,resource := range acl.Modules["MemberCommon"].Resources {
|
||||
acl.AddMemberPermission(member.Account,*resource)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ func (c *BookController) Setting() {
|
|||
c.Prepare()
|
||||
c.TplName = "book/setting.tpl"
|
||||
|
||||
if c.Ctx.Input.IsPost() {
|
||||
saveBook(c)
|
||||
}
|
||||
key := c.Ctx.Input.Param(":key")
|
||||
|
||||
if key == "" {
|
||||
|
@ -120,7 +123,7 @@ func (c *BookController) Setting() {
|
|||
}
|
||||
|
||||
//保存项目信息
|
||||
func (c *BookController) SaveBook() {
|
||||
func saveBook(c *BookController) {
|
||||
c.Prepare()
|
||||
bookResult, err := c.IsPermission()
|
||||
|
||||
|
|
1
main.go
1
main.go
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/lifei6671/mindoc/commands"
|
||||
"github.com/lifei6671/mindoc/commands/daemon"
|
||||
_ "github.com/lifei6671/mindoc/routers"
|
||||
_ "github.com/lifei6671/mindoc/acl"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ type MemberGroup struct {
|
|||
ModifyTime time.Time `orm:"column(modify_time);type(datetime);auto_now" json:"modify_time"`
|
||||
Resources string `orm:"column(resources);type(text);null" json:"-"`
|
||||
IsEnableDelete bool `orm:"column(is_enable_delete);type(bool);default(true)" json:"is_enable_delete"`
|
||||
ResourceList []*Resource `orm:"-" json:"resource_list"`
|
||||
ResourceList []*ResourceModel `orm:"-" json:"resource_list"`
|
||||
ModifyAt int `orm:"column(modify_at);type(int)" json:"-"`
|
||||
ModifyName string `orm:"-" json:"modify_name"`
|
||||
ModifyRealName string `orm:"-" json:"modify_real_name"`
|
||||
|
@ -164,7 +164,13 @@ func (m *MemberGroup) InsertOrUpdate(cols...string) error {
|
|||
}
|
||||
|
||||
var err error
|
||||
//如果用户组已存在
|
||||
if m.GroupId > 0 {
|
||||
group := &MemberGroup{}
|
||||
|
||||
err = o.QueryTable(m.TableNameWithPrefix()).Filter("group_id",m.GroupId).One(group)
|
||||
}
|
||||
if err == nil {
|
||||
_,err = o.Update(m, cols...)
|
||||
}else{
|
||||
_,err = o.Insert(m)
|
||||
|
@ -209,7 +215,7 @@ func (m *MemberGroup) FindMemberGroupList(keyword string) ([]*MemberGroup,error)
|
|||
}
|
||||
|
||||
//查询指定用户组的资源列表
|
||||
func (m *MemberGroup) FindMemberGroupResourceList(groupId int) ([]*Resource,error) {
|
||||
func (m *MemberGroup) FindMemberGroupResourceList(groupId int) ([]*ResourceModel,error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
memberGroup := NewMemberGroup()
|
||||
|
@ -224,7 +230,7 @@ func (m *MemberGroup) FindMemberGroupResourceList(groupId int) ([]*Resource,erro
|
|||
if memberGroup.Resources != "" {
|
||||
resourceIds := strings.Split(strings.Trim(memberGroup.Resources,","),",")
|
||||
|
||||
var resources []*Resource
|
||||
var resources []*ResourceModel
|
||||
_,err = o.QueryTable(NewResource().TableNameWithPrefix()).Filter("resource_id__in",resourceIds).All(resources)
|
||||
if err != nil {
|
||||
beego.Error("查询用户组资源时出错 =>", err)
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
type Resource struct {
|
||||
type ResourceModel struct {
|
||||
//主键
|
||||
ResourceId int `orm:"column(resource_id);pk;auto;unique;" json:"resource_id"`
|
||||
//分组ID
|
||||
|
@ -22,41 +22,53 @@ type Resource struct {
|
|||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (m *Resource) TableName() string {
|
||||
func (m *ResourceModel) TableName() string {
|
||||
return "resource"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (m *Resource) TableEngine() string {
|
||||
func (m *ResourceModel) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
|
||||
// 多字段唯一键
|
||||
func (m *Resource) TableUnique() [][]string {
|
||||
func (m *ResourceModel) TableUnique() [][]string {
|
||||
return [][]string{{"resource_group_id", "resource_name","action_name","http_method"}}
|
||||
}
|
||||
|
||||
func (m *Resource) TableNameWithPrefix() string {
|
||||
func (m *ResourceModel) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + m.TableName()
|
||||
}
|
||||
|
||||
func NewResource() *Resource {
|
||||
return &Resource{}
|
||||
func NewResource() *ResourceModel {
|
||||
return &ResourceModel{}
|
||||
}
|
||||
//添加或更新资源
|
||||
func (m *Resource) InsertOrUpdate(cols ...string) (err error) {
|
||||
func (m *ResourceModel) InsertOrUpdate(cols ...string) (err error) {
|
||||
if m.ControllerName == "" || m.ActionName == "" || m.ResourceGroupId <= 0 || m.ResourceName == ""{
|
||||
return errors.New("参数错误")
|
||||
}
|
||||
if m.HttpMethod == "" {
|
||||
m.HttpMethod = "GET"
|
||||
m.HttpMethod = "*"
|
||||
}
|
||||
o := orm.NewOrm()
|
||||
|
||||
resource := &ResourceModel{}
|
||||
//如果设置了资源id,需要先查询是否真实存在
|
||||
if m.ResourceId > 0 {
|
||||
_,err = o.Update(m,cols...)
|
||||
}else{
|
||||
err = o.QueryTable(m.TableNameWithPrefix()).Filter("resource_id",m.ResourceId).One(resource)
|
||||
}
|
||||
//如果资源不存在,需要查询是否存在相同的资源
|
||||
if err == nil {
|
||||
err = o.QueryTable(m.TableNameWithPrefix()).Filter("controller_name",m.ControllerName).Filter("action_name",m.ActionName).Filter("http_method__in",[]string{"*",m.HttpMethod}).One(resource)
|
||||
if err == nil {
|
||||
return errors.New("资源已存在")
|
||||
}
|
||||
}
|
||||
|
||||
if err == orm.ErrNoRows {
|
||||
_,err = o.Insert(m)
|
||||
}else{
|
||||
_,err = o.Update(m,cols...)
|
||||
}
|
||||
if err != nil {
|
||||
beego.Error("添加或更新资源时出错 =>",err)
|
||||
|
@ -65,7 +77,7 @@ func (m *Resource) InsertOrUpdate(cols ...string) (err error) {
|
|||
}
|
||||
|
||||
//删除资源
|
||||
func (m *Resource) Delete(resourceId int) (err error) {
|
||||
func (m *ResourceModel) Delete(resourceId int) (err error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
_,err = o.QueryTable(m.TableNameWithPrefix()).Filter("resource_id",resourceId).Delete()
|
||||
|
|
|
@ -29,15 +29,13 @@ type Member struct {
|
|||
Email string `orm:"size(100);column(email);unique" json:"email"`
|
||||
Phone string `orm:"size(255);column(phone);null;default(null)" json:"phone"`
|
||||
Avatar string `orm:"size(1000);column(avatar)" json:"avatar"`
|
||||
//用户角色:0 超级管理员 /1 管理员/ 2 普通用户 .
|
||||
//用户角色:1 超级管理员 /2 管理员/ 3 普通用户 .
|
||||
Role int `orm:"column(role);type(int);default(1);index" json:"role"`
|
||||
RoleName string `orm:"-" json:"role_name"`
|
||||
Status int `orm:"column(status);type(int);default(0)" json:"status"` //用户状态:0 正常/1 禁用
|
||||
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"`
|
||||
CreateAt int `orm:"type(int);column(create_at)" json:"create_at"`
|
||||
LastLoginTime time.Time `orm:"type(datetime);column(last_login_time);null" json:"last_login_time"`
|
||||
//用户权限列表
|
||||
ResourceList []*Resource `orm:"-" json:"resource_list"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
|
@ -153,7 +151,7 @@ func (m *Member) ldapLogin(account string, password string) (*Member, error) {
|
|||
func (m *Member) Add() error {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if ok, err := regexp.MatchString(conf.RegexpAccount, m.Account); m.Account == "" || !ok || err != nil {
|
||||
if ok, err := regexp.MatchString(conf.RegexpAccount, m.Account); m.Account == "" || !ok || err != nil || m.Account == "anonymous" {
|
||||
return errors.New("账号只能由英文字母数字组成,且在3-50个字符")
|
||||
}
|
||||
if m.Email == "" {
|
||||
|
|
|
@ -54,7 +54,7 @@ func init() {
|
|||
|
||||
beego.Router("/book", &controllers.BookController{}, "*:Index")
|
||||
beego.Router("/book/:key/dashboard", &controllers.BookController{}, "*:Dashboard")
|
||||
beego.Router("/book/:key/setting", &controllers.BookController{}, "*:Setting")
|
||||
beego.Router("/book/:key/setting", &controllers.BookController{}, "get:Setting")
|
||||
beego.Router("/book/:key/users", &controllers.BookController{}, "*:Users")
|
||||
beego.Router("/book/:key/release", &controllers.BookController{}, "post:Release")
|
||||
beego.Router("/book/:key/sort", &controllers.BookController{}, "post:SaveSort")
|
||||
|
@ -67,7 +67,7 @@ func init() {
|
|||
beego.Router("/book/users/delete", &controllers.BookMemberController{}, "post:RemoveMember")
|
||||
beego.Router("/book/users/import", &controllers.BookController{},"post:Import")
|
||||
|
||||
beego.Router("/book/setting/save", &controllers.BookController{}, "post:SaveBook")
|
||||
beego.Router("/book/setting/save", &controllers.BookController{}, "post:Setting")
|
||||
beego.Router("/book/setting/open", &controllers.BookController{}, "post:PrivatelyOwned")
|
||||
beego.Router("/book/setting/transfer", &controllers.BookController{}, "post:Transfer")
|
||||
beego.Router("/book/setting/upload", &controllers.BookController{}, "post:UploadCover")
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
<div class="box-body" style="padding-right: 200px;">
|
||||
<div class="form-left">
|
||||
<form method="post" id="bookEditForm" action="{{urlfor "BookController.SaveBook"}}">
|
||||
<form method="post" id="bookEditForm" action="{{urlfor "BookController.Setting"}}">
|
||||
<input type="hidden" name="identify" value="{{.Model.Identify}}">
|
||||
<div class="form-group">
|
||||
<label>标题</label>
|
||||
|
|
Loading…
Reference in New Issue