Ver Fonte

菜单添加

yxh há 6 anos atrás
pai
commit
6600588bfa

+ 30 - 0
app/controller/admin/auth.go

@@ -0,0 +1,30 @@
+package admin
+
+import (
+	"gfast/app/service/auth_service"
+	"gfast/library/response"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+//用户管理
+type Auth struct{}
+
+//添加用户组
+func (c *Auth) AddGroup(r *ghttp.Request) {
+	r.Response.Write("添加用户组")
+}
+
+func (c *Auth) AddMenu(r *ghttp.Request) {
+	if r.Method == "POST" {
+		postData := r.GetFormMap()
+		response.SusJson(true, r, "成功", postData)
+	}
+	//获取父级菜单信息
+	err, list := auth_service.GetMenuList()
+	if err != nil {
+		response.FailJson(true, r, "获取数据失败")
+	}
+	returnData := g.Map{"parentList": list}
+	response.SusJson(true, r, "成功", returnData)
+}

+ 3 - 1
app/controller/admin/index.go

@@ -2,6 +2,7 @@ package admin
 
 import (
 	"gfast/boot"
+	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/net/ghttp"
 	"github.com/gogf/gf/util/gconv"
 )
@@ -9,6 +10,7 @@ import (
 type Index struct{}
 
 func (c *Index) Index(r *ghttp.Request) {
-	resp := boot.GfToken.GetTokenData(r)
+	resp := boot.AdminGfToken.GetTokenData(r)
+	g.Log().Debug(r.Router.Uri)
 	r.Response.Write("hello Index-", gconv.Map(resp.Get("data"))["user_nickname"])
 }

+ 3 - 0
app/model/qxkj_auth_rule/qxkj_auth_rule.go

@@ -0,0 +1,3 @@
+package qxkj_auth_rule
+
+// Fill with you ideas below.

+ 64 - 0
app/model/qxkj_auth_rule/qxkj_auth_rule_entity.go

@@ -0,0 +1,64 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. You may not really want to edit it.
+// ==========================================================================
+
+package qxkj_auth_rule
+
+import (
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+)
+
+// Entity is the golang structure for table qxkj_auth_rule.
+type Entity struct {
+	Id         uint   `orm:"id,primary"  json:"id"`         //
+	Type       string `orm:"type"        json:"type"`       // menu为菜单,file为权限节点
+	Pid        uint   `orm:"pid"         json:"pid"`        // 父ID
+	Name       string `orm:"name,unique" json:"name"`       // 规则名称
+	Title      string `orm:"title"       json:"title"`      // 规则名称
+	Icon       string `orm:"icon"        json:"icon"`       // 图标
+	Condition  string `orm:"condition"   json:"condition"`  // 条件
+	Remark     string `orm:"remark"      json:"remark"`     // 备注
+	Ismenu     uint   `orm:"ismenu"      json:"ismenu"`     // 是否为菜单
+	Createtime uint   `orm:"createtime"  json:"createtime"` // 创建时间
+	Updatetime uint   `orm:"updatetime"  json:"updatetime"` // 更新时间
+	Weigh      int    `orm:"weigh"       json:"weigh"`      // 权重
+	Status     string `orm:"status"      json:"status"`     // 状态
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (r *Entity) OmitEmpty() *arModel {
+	return Model.Data(r).OmitEmpty()
+}
+
+// Inserts does "INSERT...INTO..." statement for inserting current object into table.
+func (r *Entity) Insert() (result sql.Result, err error) {
+	return Model.Data(r).Insert()
+}
+
+// Replace does "REPLACE...INTO..." statement for inserting current object into table.
+// If there's already another same record in the table (it checks using primary key or unique index),
+// it deletes it and insert this one.
+func (r *Entity) Replace() (result sql.Result, err error) {
+	return Model.Data(r).Replace()
+}
+
+// Save does "INSERT...INTO..." statement for inserting/updating current object into table.
+// It updates the record if there's already another same record in the table
+// (it checks using primary key or unique index).
+func (r *Entity) Save() (result sql.Result, err error) {
+	return Model.Data(r).Save()
+}
+
+// Update does "UPDATE...WHERE..." statement for updating current object from table.
+// It updates the record if there's already another same record in the table
+// (it checks using primary key or unique index).
+func (r *Entity) Update() (result sql.Result, err error) {
+	return Model.Data(r).Where(gdb.GetWhereConditionOfStruct(r)).Update()
+}
+
+// Delete does "DELETE FROM...WHERE..." statement for deleting current object from table.
+func (r *Entity) Delete() (result sql.Result, err error) {
+	return Model.Where(gdb.GetWhereConditionOfStruct(r)).Delete()
+}

+ 367 - 0
app/model/qxkj_auth_rule/qxkj_auth_rule_model.go

@@ -0,0 +1,367 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. You may not really want to edit it.
+// ==========================================================================
+
+package qxkj_auth_rule
+
+import (
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"time"
+)
+
+// arModel is a active record design model for table qxkj_auth_rule operations.
+type arModel struct {
+	M *gdb.Model
+}
+
+var (
+	// Table is the table name of qxkj_auth_rule.
+	Table = "qxkj_auth_rule"
+	// Model is the model object of qxkj_auth_rule.
+	Model = &arModel{g.DB("default").Table(Table).Safe()}
+)
+
+// FindOne is a convenience method for Model.FindOne.
+// See Model.FindOne.
+func FindOne(where ...interface{}) (*Entity, error) {
+	return Model.FindOne(where...)
+}
+
+// FindAll is a convenience method for Model.FindAll.
+// See Model.FindAll.
+func FindAll(where ...interface{}) ([]*Entity, error) {
+	return Model.FindAll(where...)
+}
+
+// FindValue is a convenience method for Model.FindValue.
+// See Model.FindValue.
+func FindValue(fieldsAndWhere ...interface{}) (gdb.Value, error) {
+	return Model.FindValue(fieldsAndWhere...)
+}
+
+// FindCount is a convenience method for Model.FindCount.
+// See Model.FindCount.
+func FindCount(where ...interface{}) (int, error) {
+	return Model.FindCount(where...)
+}
+
+// Insert is a convenience method for Model.Insert.
+func Insert(data ...interface{}) (result sql.Result, err error) {
+	return Model.Insert(data...)
+}
+
+// Replace is a convenience method for Model.Replace.
+func Replace(data ...interface{}) (result sql.Result, err error) {
+	return Model.Replace(data...)
+}
+
+// Save is a convenience method for Model.Save.
+func Save(data ...interface{}) (result sql.Result, err error) {
+	return Model.Save(data...)
+}
+
+// Update is a convenience method for Model.Update.
+func Update(dataAndWhere ...interface{}) (result sql.Result, err error) {
+	return Model.Update(dataAndWhere...)
+}
+
+// Delete is a convenience method for Model.Delete.
+func Delete(where ...interface{}) (result sql.Result, err error) {
+	return Model.Delete(where...)
+}
+
+// As sets an alias name for current table.
+func (m *arModel) As(as string) *arModel {
+	return &arModel{m.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (m *arModel) TX(tx *gdb.TX) *arModel {
+	return &arModel{m.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (m *arModel) Master() *arModel {
+	return &arModel{m.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (m *arModel) Slave() *arModel {
+	return &arModel{m.M.Slave()}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+func (m *arModel) LeftJoin(joinTable string, on string) *arModel {
+	return &arModel{m.M.LeftJoin(joinTable, on)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+func (m *arModel) RightJoin(joinTable string, on string) *arModel {
+	return &arModel{m.M.RightJoin(joinTable, on)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+func (m *arModel) InnerJoin(joinTable string, on string) *arModel {
+	return &arModel{m.M.InnerJoin(joinTable, on)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+func (m *arModel) Fields(fields string) *arModel {
+	return &arModel{m.M.Fields(fields)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+func (m *arModel) FieldsEx(fields string) *arModel {
+	return &arModel{m.M.FieldsEx(fields)}
+}
+
+// Option sets the extra operation option for the model.
+func (m *arModel) Option(option int) *arModel {
+	return &arModel{m.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (m *arModel) OmitEmpty() *arModel {
+	return &arModel{m.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (m *arModel) Filter() *arModel {
+	return &arModel{m.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (m *arModel) Where(where interface{}, args ...interface{}) *arModel {
+	return &arModel{m.M.Where(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (m *arModel) And(where interface{}, args ...interface{}) *arModel {
+	return &arModel{m.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (m *arModel) Or(where interface{}, args ...interface{}) *arModel {
+	return &arModel{m.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (m *arModel) Group(groupBy string) *arModel {
+	return &arModel{m.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (m *arModel) Order(orderBy string) *arModel {
+	return &arModel{m.M.Order(orderBy)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (m *arModel) Limit(limit ...int) *arModel {
+	return &arModel{m.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (m *arModel) Offset(offset int) *arModel {
+	return &arModel{m.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (m *arModel) Page(page, limit int) *arModel {
+	return &arModel{m.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (m *arModel) Batch(batch int) *arModel {
+	return &arModel{m.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (m *arModel) Cache(expire time.Duration, name ...string) *arModel {
+	return &arModel{m.M.Cache(expire, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (m *arModel) Data(data ...interface{}) *arModel {
+	return &arModel{m.M.Data(data...)}
+}
+
+// Insert does "INSERT INTO ..." statement for the model.
+// The optional parameter <data> is the same as the parameter of Model.Data function,
+// see Model.Data.
+func (m *arModel) Insert(data ...interface{}) (result sql.Result, err error) {
+	return m.M.Insert(data...)
+}
+
+// Replace does "REPLACE INTO ..." statement for the model.
+// The optional parameter <data> is the same as the parameter of Model.Data function,
+// see Model.Data.
+func (m *arModel) Replace(data ...interface{}) (result sql.Result, err error) {
+	return m.M.Replace(data...)
+}
+
+// Save does "INSERT INTO ... ON DUPLICATE KEY UPDATE..." statement for the model.
+// It updates the record if there's primary or unique index in the saving data,
+// or else it inserts a new record into the table.
+//
+// The optional parameter <data> is the same as the parameter of Model.Data function,
+// see Model.Data.
+func (m *arModel) Save(data ...interface{}) (result sql.Result, err error) {
+	return m.M.Save(data...)
+}
+
+// Update does "UPDATE ... " statement for the model.
+//
+// If the optional parameter <dataAndWhere> is given, the dataAndWhere[0] is the updated
+// data field, and dataAndWhere[1:] is treated as where condition fields.
+// Also see Model.Data and Model.Where functions.
+func (m *arModel) Update(dataAndWhere ...interface{}) (result sql.Result, err error) {
+	return m.M.Update(dataAndWhere...)
+}
+
+// Delete does "DELETE FROM ... " statement for the model.
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+func (m *arModel) Delete(where ...interface{}) (result sql.Result, err error) {
+	return m.M.Delete(where...)
+}
+
+// Count does "SELECT COUNT(x) FROM ..." statement for the model.
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+func (m *arModel) Count(where ...interface{}) (int, error) {
+	return m.M.Count(where...)
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*Entity.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+func (m *arModel) All(where ...interface{}) ([]*Entity, error) {
+	all, err := m.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*Entity
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *Entity.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+func (m *arModel) One(where ...interface{}) (*Entity, error) {
+	one, err := m.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *Entity
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// Value retrieves a specified record value from table and returns the result as interface type.
+// It returns nil if there's no record found with the given conditions from table.
+//
+// If the optional parameter <fieldsAndWhere> is given, the fieldsAndWhere[0] is the selected fields
+// and fieldsAndWhere[1:] is treated as where condition fields.
+// Also see Model.Fields and Model.Where functions.
+func (m *arModel) Value(fieldsAndWhere ...interface{}) (gdb.Value, error) {
+	return m.M.Value(fieldsAndWhere...)
+}
+
+// FindOne retrieves and returns a single Record by Model.WherePri and Model.One.
+// Also see Model.WherePri and Model.One.
+func (m *arModel) FindOne(where ...interface{}) (*Entity, error) {
+	one, err := m.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *Entity
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by Model.WherePri and Model.All.
+// Also see Model.WherePri and Model.All.
+func (m *arModel) FindAll(where ...interface{}) ([]*Entity, error) {
+	all, err := m.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*Entity
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// FindValue retrieves and returns single field value by Model.WherePri and Model.Value.
+// Also see Model.WherePri and Model.Value.
+func (m *arModel) FindValue(fieldsAndWhere ...interface{}) (gdb.Value, error) {
+	return m.M.FindValue(fieldsAndWhere...)
+}
+
+// FindCount retrieves and returns the record number by Model.WherePri and Model.Count.
+// Also see Model.WherePri and Model.Count.
+func (m *arModel) FindCount(where ...interface{}) (int, error) {
+	return m.M.FindCount(where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (m *arModel) Chunk(limit int, callback func(entities []*Entity, err error) bool) {
+	m.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*Entity
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}

+ 24 - 0
app/service/auth_service/qxkj_auth_rule.go

@@ -0,0 +1,24 @@
+package auth_service
+
+import (
+	"gfast/app/model/qxkj_auth_rule"
+	"gfast/library/utils"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/util/gconv"
+)
+
+func GetMenuList() (error, gdb.List) {
+	list, err := qxkj_auth_rule.Model.Where(" ismenu=?", 1).Order("weigh desc,id asc").FindAll()
+	if err != nil {
+		g.Log().Error(err)
+		return err, nil
+	}
+	var gdbList = make(gdb.List, len(list))
+	for k, v := range list {
+		tMap := gconv.Map(v)
+		gdbList[k] = tMap
+	}
+	gdbList = utils.ParentSonSort(gdbList)
+	return nil, gdbList
+}

+ 8 - 4
boot/boot.go

@@ -6,13 +6,17 @@ import (
 	"github.com/gogf/gf/frame/g"
 )
 
-var GfToken *gtoken.GfToken
+var AdminGfToken *gtoken.GfToken
 
 func init() {
 	g.Server().SetPort(8200)
 	g.Server().AddStaticPath("/public", g.Cfg().Get("server.ServerRoot").(string))
-	// 启动gtoken
-	GfToken = &gtoken.GfToken{
+	// 设置并启动后台gtoken处理
+	initAdminGfToken()
+}
+
+func initAdminGfToken() {
+	AdminGfToken = &gtoken.GfToken{
 		CacheMode:        int8(g.Cfg().Get("gToken.CacheMode").(float64)),
 		CacheKey:         g.Cfg().Get("gToken.CacheKey").(string),
 		Timeout:          int(g.Cfg().Get("gToken.Timeout").(float64)),
@@ -27,5 +31,5 @@ func init() {
 		AuthPaths:        g.SliceStr{"/system/*"},
 		LogoutBeforeFunc: utils.AdminLoginOut,
 	}
-	GfToken.Start()
+	AdminGfToken.Start()
 }

+ 1 - 0
config/config.toml

@@ -1,6 +1,7 @@
 # 数据库连接
 [database]
     link = "mysql:root:123456@tcp(127.0.0.1:3306)/gfast"
+    debug  = true
 
 #web服务器配置
 [server]

+ 39 - 1
data/db.sql

@@ -15,6 +15,44 @@
 /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
 /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
 
+--
+-- Table structure for table `qxkj_auth_rule`
+--
+
+DROP TABLE IF EXISTS `qxkj_auth_rule`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `qxkj_auth_rule` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `type` enum('menu','file') NOT NULL DEFAULT 'file' COMMENT 'menu为菜单,file为权限节点',
+  `pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
+  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '规则名称',
+  `title` varchar(50) NOT NULL DEFAULT '' COMMENT '规则名称',
+  `icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标',
+  `condition` varchar(255) NOT NULL DEFAULT '' COMMENT '条件',
+  `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
+  `ismenu` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否为菜单',
+  `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
+  `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
+  `weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
+  `status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `name` (`name`) USING BTREE,
+  KEY `pid` (`pid`),
+  KEY `weigh` (`weigh`)
+) ENGINE=MyISAM AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='菜单节点表';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `qxkj_auth_rule`
+--
+
+LOCK TABLES `qxkj_auth_rule` WRITE;
+/*!40000 ALTER TABLE `qxkj_auth_rule` DISABLE KEYS */;
+INSERT INTO `qxkj_auth_rule` VALUES (5,'file',0,'auth','权限管理','fa fa-group','','',1,1497429920,1497430092,99,'normal'),(9,'file',5,'auth/admin','管理员管理','fa fa-user','','Admin tips',1,1497429920,1497430320,118,'normal'),(10,'file',5,'auth/adminlog','管理员日志','fa fa-list-alt','','Admin log tips',1,1497429920,1497430307,113,'normal'),(11,'file',5,'auth/group','角色组','fa fa-group','','Group tips',1,1497429920,1497429920,109,'normal'),(12,'file',5,'auth/rule','菜单规则','fa fa-bars','','Rule tips',1,1497429920,1497430581,104,'normal'),(43,'file',9,'auth/admin/del','删除','fa fa-circle-o','','',0,1497429920,1497429920,114,'normal'),(42,'file',9,'auth/admin/edit','修改','fa fa-circle-o','','',0,1497429920,1497429920,115,'normal'),(41,'file',9,'auth/admin/add','添加','fa fa-circle-o','','',0,1497429920,1497429920,116,'normal'),(40,'file',9,'auth/admin/index','查看','fa fa-circle-o','','Admin tips',0,1497429920,1497429920,117,'normal');
+/*!40000 ALTER TABLE `qxkj_auth_rule` ENABLE KEYS */;
+UNLOCK TABLES;
+
 --
 -- Table structure for table `qxkj_role`
 --
@@ -121,4 +159,4 @@ UNLOCK TABLES;
 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
--- Dump completed on 2019-12-26 22:52:55
+-- Dump completed on 2020-01-16 18:07:54

+ 10 - 7
library/response/response.go

@@ -6,13 +6,8 @@ import (
 )
 
 const (
-	SuccessCode       int = 200
-	ErrorCode         int = 400
-	AccessDeniedCode  int = 403
-	NotFoundCode      int = 404
-	NotAcceptableCode int = 406
-	ServerErrorCode   int = 500
-	RedirectCode      int = 302
+	SuccessCode int = 0
+	ErrorCode   int = -1
 )
 
 // 返回JSON数据并退出当前HTTP执行函数。
@@ -43,3 +38,11 @@ func SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
 	}
 	RJson(r, SuccessCode, msg, data...)
 }
+
+//失败返回JSON
+func FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	if isExit {
+		JsonExit(r, ErrorCode, msg, data...)
+	}
+	RJson(r, ErrorCode, msg, data...)
+}

+ 10 - 10
library/utils/function.go

@@ -5,14 +5,14 @@ import (
 	"gfast/library/response"
 	"github.com/gogf/gf/crypto/gaes"
 	"github.com/gogf/gf/encoding/gbase64"
+	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/net/ghttp"
-	"github.com/gogf/gf/os/glog"
 	"github.com/gogf/gf/util/grand"
 	"github.com/gogf/gf/util/gvalid"
 	"github.com/mojocn/base64Captcha"
 )
 
-const adminCbcPublicKey = "HqmP1KLMuz09Q0Bu"
+const AdminCbcPublicKey = "HqmP1KLMuz09Q0Bu"
 
 //获取验证码
 func GetVerifyImg() (idKeyC string, base64stringC string) {
@@ -60,13 +60,13 @@ func AdminLogin(r *ghttp.Request) (string, interface{}) {
 	if !base64Captcha.VerifyCaptchaAndIsClear(data["idKeyC"], data["idValueC"], true) {
 		response.JsonExit(r, response.ErrorCode, "验证码输入错误")
 	}
-
-	if err, user := user_service.SignIn(data["username"], EncryptCBC(data["password"], adminCbcPublicKey), r.Session); err != nil {
-		response.JsonExit(r, response.NotAcceptableCode, err.Error())
+	password := EncryptCBC(data["password"], AdminCbcPublicKey)
+	if err, user := user_service.SignIn(data["username"], password, r.Session); err != nil {
+		response.JsonExit(r, response.ErrorCode, err.Error())
 	} else {
-		return data["username"], user
+		return data["username"] + password, user
 	}
-	return data["username"], nil
+	return data["username"] + password, nil
 }
 
 //后台退出登陆
@@ -79,7 +79,7 @@ func EncryptCBC(plainText, publicKey string) string {
 	key := []byte(publicKey)
 	b, e := gaes.EncryptCBC([]byte(plainText), key, key)
 	if e != nil {
-		glog.Error(e.Error())
+		g.Log().Error(e.Error())
 		return ""
 	}
 	return gbase64.EncodeToString(b)
@@ -90,12 +90,12 @@ func DecryptCBC(plainText, publicKey string) string {
 	key := []byte(publicKey)
 	plainTextByte, e := gbase64.DecodeString(plainText)
 	if e != nil {
-		glog.Error(e.Error())
+		g.Log().Error(e.Error())
 		return ""
 	}
 	b, e := gaes.DecryptCBC(plainTextByte, key, key)
 	if e != nil {
-		glog.Error(e.Error())
+		g.Log().Error(e.Error())
 		return ""
 	}
 	return gbase64.EncodeToString(b)

+ 82 - 0
library/utils/slice_tree.go

@@ -0,0 +1,82 @@
+package utils
+
+import (
+	"fmt"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/util/gconv"
+	"strings"
+)
+
+//有层级关系的数组,父级-》子级 排序
+func ParentSonSort(list gdb.List, params ...interface{}) gdb.List {
+	args := make([]interface{}, 8)
+	for k, v := range params {
+		if k == 8 {
+			break
+		}
+		args[k] = v
+	}
+	var (
+		pid       int    //父级id
+		level     int    //层级数
+		fieldName string //父级id键名
+		id        string //id键名
+		levelName string //层级名称
+		title     string //标题名称
+		breaks    int    //中断层级
+		prefixStr string //字符串前缀
+	)
+	pid = gconv.Int(GetSliceByKey(args, 0, 0))
+	level = gconv.Int(GetSliceByKey(args, 1, 0))
+	fieldName = gconv.String(GetSliceByKey(args, 2, "pid"))
+	id = gconv.String(GetSliceByKey(args, 3, "id"))
+	levelName = gconv.String(GetSliceByKey(args, 4, "flg"))
+	title = gconv.String(GetSliceByKey(args, 5, "title"))
+	breaks = gconv.Int(GetSliceByKey(args, 6, -1))
+	prefixStr = gconv.String(GetSliceByKey(args, 7, "&nbsp;&nbsp;"))
+	//定义一个新slice用于返回
+	var returnSlice gdb.List
+	for _, v := range list {
+		if pid == gconv.Int(v[fieldName]) {
+			v[levelName] = level
+			levelClone := level
+			titlePrefix := ""
+			for {
+				if levelClone < 0 {
+					break
+				}
+				titlePrefix = strings.Repeat(prefixStr, 2)
+				levelClone--
+			}
+			titlePrefix += "├"
+			if level == 0 {
+				v["title_prefix"] = ""
+			} else {
+				v["title_prefix"] = titlePrefix
+			}
+			v["title_show"] = fmt.Sprintf("%s%s", v["title_prefix"], v[title])
+			returnSlice = append(returnSlice, v)
+			if breaks != -1 && breaks == level {
+				continue
+			}
+			args[0] = v[id]
+			args[1] = level + 1
+			newSlice2 := ParentSonSort(list, args...)
+			if len(newSlice2) > 0 {
+				returnSlice = append(returnSlice, newSlice2...)
+			}
+		}
+	}
+	return returnSlice
+}
+
+//获取切片里的值 若为nil 可设置默认值val
+func GetSliceByKey(args []interface{}, key int, val interface{}) interface{} {
+	var value interface{}
+	if args[key] != nil {
+		value = args[key]
+	} else {
+		value = val
+	}
+	return value
+}

+ 1 - 0
router/router.go

@@ -16,4 +16,5 @@ func init() {
 	sysLoginGroup.ALL("/public", new(admin.Public))
 	systemGroup := group.Group("/system")
 	systemGroup.ALL("/index", new(admin.Index))
+	systemGroup.ALL("/auth", new(admin.Auth))
 }

+ 19 - 0
test/demo2_test.go

@@ -0,0 +1,19 @@
+package test
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestDemo2(t *testing.T) {
+	t.Run("Adapters_test", test21)
+}
+
+func test21(t *testing.T) {
+	a := []int{1, 2, 3, 4, 5}
+	b := []int{6, 7, 8, 9}
+	c := make([]int, 0, 9)
+	c = append(c, a...)
+	c = append(c, b...)
+	fmt.Println(c)
+}