yxh 6 سال پیش
والد
کامیت
bbb15376cb

+ 2 - 1
.gitignore

@@ -18,4 +18,5 @@ cbuild
 main
 .vscode
 *.exe
-tmp
+tmp
+resource/pub_upload/

+ 2 - 2
app/controller/admin/cms_news.go

@@ -25,9 +25,9 @@ func (c *CmsNews) Add(r *ghttp.Request) {
 		if err := r.Parse(&req); err != nil {
 			response.FailJson(true, r, err.(*gvalid.Error).FirstString())
 		}
-		menuIds := r.GetInts("menuIds")
+		cateIds := r.GetInts("cateIds")
 		userId := user_service.GetLoginID(r)
-		ids, err := cms_service.AddNews(req, menuIds, userId)
+		ids, err := cms_service.AddNews(req, cateIds, userId)
 		if err != nil {
 			response.FailJson(true, r, err.Error())
 		}

+ 4 - 0
app/controller/admin/config_params.go

@@ -4,6 +4,7 @@ import (
 	"gfast/app/model/admin/sys_config"
 	"gfast/app/service/admin/params_service"
 	"gfast/app/service/admin/user_service"
+	"gfast/app/service/cache_service"
 	"gfast/library/response"
 	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/net/ghttp"
@@ -49,6 +50,7 @@ func (c *Params) Add(r *ghttp.Request) {
 		if err != nil {
 			response.FailJson(true, r, err.Error())
 		}
+		cache_service.New().Remove(req.ConfigKey)
 		response.SusJson(true, r, "添加参数成功")
 	}
 }
@@ -70,6 +72,7 @@ func (c *Params) Edit(r *ghttp.Request) {
 		if err != nil {
 			response.FailJson(true, r, err.Error())
 		}
+		cache_service.New().Remove(req.ConfigKey)
 		response.SusJson(true, r, "修改参数成功")
 	}
 	id := r.GetInt("id")
@@ -90,5 +93,6 @@ func (c *Params) Delete(r *ghttp.Request) {
 	if err != nil {
 		response.FailJson(true, r, "删除失败")
 	}
+	cache_service.New().RemoveByTag(cache_service.AdminSysConfigTag)
 	response.SusJson(true, r, "删除成功")
 }

+ 22 - 0
app/controller/admin/upload.go

@@ -0,0 +1,22 @@
+package admin
+
+import (
+	"gfast/app/service/admin/upload_service"
+	"gfast/library/response"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+type Upload struct{}
+
+func (c *Upload) UpImg(r *ghttp.Request) {
+	upFile := r.GetUploadFile("file")
+	info, err := upload_service.UpImg(upFile)
+	if err != nil {
+		response.FailJson(true, r, "上传失败,"+err.Error())
+	}
+	res := g.Map{
+		"fileInfo": info,
+	}
+	response.SusJson(true, r, "上传成功", res)
+}

+ 11 - 11
app/model/admin/cms_news/cms_news.go

@@ -31,20 +31,20 @@ type ReqAddParams struct {
 }
 
 //添加文章操作
-func AddNews(req *ReqAddParams, menuIds []int, userId int) (insId []int64, err error) {
-	if len(menuIds) == 0 {
+func AddNews(req *ReqAddParams, cateIds []int, userId int) (insId []int64, err error) {
+	if len(cateIds) == 0 {
 		err = gerror.New("栏目不能为空")
 		return
 	}
 	tx, err := g.DB().Begin()
 	if err != nil {
 		g.Log().Error(err)
-		err = gerror.New("保存失败")
+		err = gerror.New("添加失败")
 		return
 	}
-	for _, menuId := range menuIds {
+	for _, cateId := range cateIds {
 		entity := &Entity{
-			CateId:        gconv.Uint(menuId),
+			CateId:        gconv.Uint(cateId),
 			UserId:        gconv.Uint64(userId),
 			NewsStatus:    req.NewsStatus,
 			IsTop:         req.IsTop,
@@ -60,16 +60,16 @@ func AddNews(req *ReqAddParams, menuIds []int, userId int) (insId []int64, err e
 			IsJump:        req.IsJump,
 			JumpUrl:       req.JumpUrl,
 		}
-		res, err := entity.Save()
-		if err != nil {
-			g.Log().Error(err)
+		res, e := entity.Save()
+		if e != nil {
+			g.Log().Error(e)
 			err = gerror.New("添加文章失败")
 			tx.Rollback()
 			return
 		}
-		id, err := res.LastInsertId()
-		if err != nil {
-			g.Log().Error(err)
+		id, e := res.LastInsertId()
+		if e != nil {
+			g.Log().Error(e)
 			err = gerror.New("添加文章失败")
 			tx.Rollback()
 			return

+ 0 - 5
app/model/admin/cms_news/cms_news_entity.go

@@ -46,11 +46,6 @@ func (r *Entity) Insert() (result sql.Result, err error) {
 	return Model.Data(r).Insert()
 }
 
-// InsertIgnore does "INSERT IGNORE INTO ..." statement for inserting current object into table.
-func (r *Entity) InsertIgnore() (result sql.Result, err error) {
-	return Model.Data(r).InsertIgnore()
-}
-
 // 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.

+ 70 - 56
app/model/admin/cms_news/cms_news_model.go

@@ -8,13 +8,12 @@ import (
 	"database/sql"
 	"github.com/gogf/gf/database/gdb"
 	"github.com/gogf/gf/frame/g"
-	"github.com/gogf/gf/frame/gmvc"
 	"time"
 )
 
 // arModel is a active record design model for table cms_news operations.
 type arModel struct {
-	gmvc.M
+	M *gdb.Model
 }
 
 var (
@@ -22,54 +21,6 @@ var (
 	Table = "cms_news"
 	// Model is the model object of cms_news.
 	Model = &arModel{g.DB("default").Table(Table).Safe()}
-	// Columns defines and stores column names for table cms_news.
-	Columns = struct {
-		Id            string //
-		CateId        string // 栏目id
-		NewsFormat    string // 内容格式;1:html;2:md
-		UserId        string // 发表者用户id
-		NewsStatus    string // 状态;1:已发布;0:未发布;
-		IsTop         string // 是否置顶;1:置顶;0:不置顶
-		Recommended   string // 是否推荐;1:推荐;0:不推荐
-		NewsHits      string // 查看数
-		NewsLike      string // 点赞数
-		CreateTime    string // 创建时间
-		UpdateTime    string // 更新时间
-		PublishedTime string // 发布时间
-		DeleteTime    string // 删除时间
-		NewsTitle     string // post标题
-		NewsKeywords  string // seo keywords
-		NewsExcerpt   string // post摘要
-		NewsSource    string // 转载文章的来源
-		NewsContent   string // 文章内容
-		Thumbnail     string // 缩略图
-		IsJump        string // 是否跳转地址
-		JumpUrl       string // 跳转地址
-		IsPushed      string // 是否已推送
-	}{
-		Id:            "id",
-		CateId:        "cate_id",
-		NewsFormat:    "news_format",
-		UserId:        "user_id",
-		NewsStatus:    "news_status",
-		IsTop:         "is_top",
-		Recommended:   "recommended",
-		NewsHits:      "news_hits",
-		NewsLike:      "news_like",
-		CreateTime:    "create_time",
-		UpdateTime:    "update_time",
-		PublishedTime: "published_time",
-		DeleteTime:    "delete_time",
-		NewsTitle:     "news_title",
-		NewsKeywords:  "news_keywords",
-		NewsExcerpt:   "news_excerpt",
-		NewsSource:    "news_source",
-		NewsContent:   "news_content",
-		Thumbnail:     "thumbnail",
-		IsJump:        "is_jump",
-		JumpUrl:       "jump_url",
-		IsPushed:      "is_pushed",
-	}
 )
 
 // FindOne is a convenience method for Model.FindOne.
@@ -90,12 +41,6 @@ func FindValue(fieldsAndWhere ...interface{}) (gdb.Value, error) {
 	return Model.FindValue(fieldsAndWhere...)
 }
 
-// FindArray is a convenience method for Model.FindArray.
-// See Model.FindArray.
-func FindArray(fieldsAndWhere ...interface{}) ([]gdb.Value, error) {
-	return Model.FindArray(fieldsAndWhere...)
-}
-
 // FindCount is a convenience method for Model.FindCount.
 // See Model.FindCount.
 func FindCount(where ...interface{}) (int, error) {
@@ -277,6 +222,53 @@ 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.
@@ -312,6 +304,16 @@ func (m *arModel) One(where ...interface{}) (*Entity, error) {
 	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) {
@@ -340,6 +342,18 @@ func (m *arModel) FindAll(where ...interface{}) ([]*Entity, error) {
 	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 {

+ 10 - 0
app/model/admin/sys_config/sys_config.go

@@ -176,3 +176,13 @@ func DeleteByIds(ids []int) error {
 	}
 	return nil
 }
+
+//通过key获取配置信息
+func GetByKey(key string) (config *Entity, err error) {
+	config, err = Model.FindOne("config_key", key)
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取配置失败")
+	}
+	return
+}

+ 2 - 2
app/service/admin/cms_service/news.go

@@ -5,6 +5,6 @@ import (
 )
 
 //添加文章操作
-func AddNews(req *cms_news.ReqAddParams, menuIds []int, userId int) (insId []int64, err error) {
-	return cms_news.AddNews(req, menuIds, userId)
+func AddNews(req *cms_news.ReqAddParams, cateIds []int, userId int) (insId []int64, err error) {
+	return cms_news.AddNews(req, cateIds, userId)
 }

+ 17 - 0
app/service/admin/params_service/params.go

@@ -2,6 +2,7 @@ package params_service
 
 import (
 	"gfast/app/model/admin/sys_config"
+	"gfast/app/service/cache_service"
 )
 
 //保存参数
@@ -38,3 +39,19 @@ func CheckConfigKeyUnique(configKey string, configId int64) error {
 func DeleteByIds(ids []int) error {
 	return sys_config.DeleteByIds(ids)
 }
+
+//通过key获取参数
+func GetConfigByKey(key string) (config *sys_config.Entity, err error) {
+	cache := cache_service.New()
+	cf := cache.Get(key)
+	if cf != nil {
+		config = cf.(*sys_config.Entity)
+		return
+	}
+	config, err = sys_config.GetByKey(key)
+	if err != nil {
+		return
+	}
+	cache.Set(key, config, 0, cache_service.AdminSysConfigTag)
+	return
+}

+ 134 - 0
app/service/admin/upload_service/upload.go

@@ -0,0 +1,134 @@
+package upload_service
+
+import (
+	"gfast/app/model/admin/sys_config"
+	"gfast/app/service/admin/params_service"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/text/gregex"
+	"github.com/gogf/gf/text/gstr"
+	"github.com/gogf/gf/util/gconv"
+)
+
+var uploadPath string
+
+//上传得文件信息
+type FileInfo struct {
+	FileName string
+	FileSize int64
+	FileUrl  string
+	fileType string
+}
+
+func init() {
+	uploadPath = g.Cfg().GetString("server.ServerRoot") + "/pub_upload/"
+}
+
+//上传图片
+func UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	if file == nil {
+		err = gerror.New("未上传任何文件")
+		return
+	}
+	//获取上传类型配置
+	config, err := getUpConfig("sys.uploadFile.imageType")
+	if err != nil {
+		return
+	}
+	//检测文件类型
+	rightType := checkFileType(file.Filename, config.ConfigValue)
+	if !rightType {
+		err = gerror.New("上传文件类型错误,只能包含后缀为:" + config.ConfigValue + "的文件。")
+		return
+	}
+	//获取上传大小配置
+	config, err = getUpConfig("sys.uploadFile.imageSize")
+	if err != nil {
+		return
+	}
+	rightSize, err := checkSize(config.ConfigValue, file.Size)
+	if err != nil {
+		return
+	}
+	if !rightSize {
+		gerror.New("上传文件超过最大尺寸:" + config.ConfigValue)
+		return
+	}
+	path := getUpPath()
+	fileName, err := file.Save(path, true)
+	if err != nil {
+		return
+	}
+	fileInfo = &FileInfo{
+		FileName: file.Filename,
+		FileSize: file.Size,
+		FileUrl:  getUrl(path, fileName),
+		fileType: file.Header.Get("Content-type"),
+	}
+	return
+}
+
+//检查文件大小是否合法
+func checkSize(configSize string, fileSize int64) (bool, error) {
+	match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize)
+	if err != nil {
+		return false, err
+	}
+	if len(match) == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)")
+		return false, err
+	}
+	var cfSize int64
+	switch gstr.ToUpper(match[2]) {
+	case "MB", "M":
+		cfSize = gconv.Int64(match[1]) * 1024 * 1024
+	case "KB", "K":
+		cfSize = gconv.Int64(match[1]) * 1024
+	case "":
+		cfSize = gconv.Int64(match[1])
+	}
+	if cfSize == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB")
+		return false, err
+	}
+	return cfSize >= fileSize, nil
+}
+
+//获取上传配置
+func getUpConfig(key string) (config *sys_config.Entity, err error) {
+	config, err = params_service.GetConfigByKey(key)
+	if err != nil {
+		return
+	}
+	if config == nil {
+		err = gerror.New("上传文件类型未设置,请在后台配置")
+		return
+	}
+	return
+}
+
+//判断上传文件类型是否合法
+func checkFileType(fileName, typeString string) bool {
+	suffix := gstr.SubStr(fileName, gstr.Pos(fileName, ".")+1)
+	imageType := gstr.Split(typeString, ",")
+	rightType := false
+	for _, v := range imageType {
+		if gstr.Equal(suffix, v) {
+			rightType = true
+			break
+		}
+	}
+	return rightType
+}
+
+func getUpPath() (upPath string) {
+	upPath = uploadPath + gtime.Date() + "/"
+	return
+}
+
+func getUrl(path, fileName string) string {
+	url := gstr.SubStr(path, gstr.Pos(path, "/pub_upload/")+1) + fileName
+	return url
+}

+ 1 - 0
app/service/cache_service/cache_values.go

@@ -11,4 +11,5 @@ const (
 const (
 	AdminAuthTag = iota
 	AdminCmsTag
+	AdminSysConfigTag
 )

+ 7 - 3
router/router.go

@@ -21,20 +21,24 @@ func init() {
 		//后台操作日志记录
 		group.Hook("/*", ghttp.HOOK_AFTER_OUTPUT, hook.OperationLog)
 
+		//文件上传
+		group.POST("/upload", new(admin.Upload))
+		//后台首页
 		group.ALL("/index", new(admin.Index))
+		//权限管理
 		group.ALL("/auth", new(admin.Auth))
-
+		//cms管理
 		group.Group("/cms", func(group *ghttp.RouterGroup) {
 			group.ALL("/menu", new(admin.CmsMenu))
 			group.ALL("/news", new(admin.CmsNews))
 			group.ALL("/model", new(admin.CmsModel))
 		})
-
+		//配置管理
 		group.Group("/config", func(group *ghttp.RouterGroup) {
 			group.ALL("/dict", new(admin.Dict))
 			group.ALL("/params", new(admin.Params))
 		})
-
+		//系统监控
 		group.Group("/monitor", func(group *ghttp.RouterGroup) {
 			group.ALL("/online", new(admin.MonitorOnline))
 			group.ALL("/job", new(admin.MonitorJob))

+ 3 - 1
test/demo2_test.go

@@ -1,6 +1,8 @@
 package test
 
 import (
+	"fmt"
+	"github.com/gogf/gf/os/gtime"
 	"testing"
 )
 
@@ -9,5 +11,5 @@ func TestDemo2(t *testing.T) {
 }
 
 func test21(t *testing.T) {
-
+	fmt.Println(gtime.Date())
 }