XCMS源码浅析

2020/1/22

conf/app.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
appname = xcms
httpport = 8080
runmode = dev

copyrequestbody = true
sessionon = true

#mysql
db_alias = "default"
db_name = "xcms"
db_user = "" #数据库用户
db_pwd = "" #数据库密码
db_host = "" #数据库地址
db_port = 3306 #数据库端口
db_charset = "utf8"

consts/Common.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package consts

type JsonResultCode int

const (
JRCodeSucc JsonResultCode = iota
JRCodeFailed
JRCode302 = 302 //跳转至地址
JRCode401 = 401 //未授权访问
)

const (
Deleted = iota - 1
Disabled
Enabled
)

main.go

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
_ "github.com/ziyoubiancheng/xcms/routers"
_ "github.com/ziyoubiancheng/xcms/sysinit"

"github.com/astaxie/beego"
)

func main() {
beego.Run()
}

routers/router.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package routers

import (
"github.com/astaxie/beego"
"github.com/ziyoubiancheng/xcms/controllers"
)

func init() {
//home
beego.Router("/", &controllers.HomeController{}, "Get:Index")

//menu
beego.Router("/menu", &controllers.MenuController{}, "Get:Index")
beego.Router("/menu/add", &controllers.MenuController{}, "Get:Add")
beego.Router("/menu/adddo", &controllers.MenuController{}, "*:AddDo")
beego.Router("/menu/edit", &controllers.MenuController{}, "Get:Edit")
beego.Router("/menu/editdo", &controllers.MenuController{}, "*:EditDo")
beego.Router("/menu/deletedo", &controllers.MenuController{}, "Get:DeleteDo")
beego.Router("/menu/list", &controllers.MenuController{}, "*:List")

//user
beego.Router("/user", &controllers.UserController{}, "Get:Index")
beego.Router("/user/add", &controllers.UserController{}, "Get:Add")
beego.Router("/user/adddo", &controllers.UserController{}, "*:AddDo")
beego.Router("/user/edit", &controllers.UserController{}, "Get:Edit")
beego.Router("/user/editdo", &controllers.UserController{}, "*:EditDo")
beego.Router("/user/deletedo", &controllers.UserController{}, "Get:DeleteDo")
beego.Router("/user/list", &controllers.UserController{}, "*:List")

//login
beego.Router("/login", &controllers.LoginController{}, "*:Index")

//format
beego.Router("/format/edit", &controllers.FormatController{}, "Get:Edit")
beego.Router("/format/editdo", &controllers.FormatController{}, "*:EditDo")

beego.Router("/data/?:mid", &controllers.DataController{}, "Get:Index")
beego.Router("/data/list/?:mid", &controllers.DataController{}, "*:List")
}

controllers/BaseController.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package controllers

import (
"strings"

"github.com/astaxie/beego"
"github.com/ziyoubiancheng/xcms/consts"
"github.com/ziyoubiancheng/xcms/models"
)

type BaseController struct {
beego.Controller
controllerName string
actionName string
}

func (c *BaseController) Prepare() {
//附值
c.controllerName, c.actionName = c.GetControllerAndAction()
beego.Informational(c.controllerName, c.actionName)

user := c.auth()
c.Data["Menu"] = models.MenuTreeStruct(user)
}

// 设置模板
// 第一个参数模板,第二个参数为layout
func (c *BaseController) setTpl(template ...string) {
var tplName string
layout := "common/layout.html"
switch {
case len(template) == 1:
tplName = template[0]
case len(template) == 2:
tplName = template[0]
layout = template[1]
default:
//不要"Controller"这个10个字母
ctrlName := strings.ToLower(c.controllerName[0 : len(c.controllerName)-10])
actionName := strings.ToLower(c.actionName)
tplName = ctrlName + "/" + actionName + ".html"
}

_, found := c.Data["Footer"]
if !found {
c.Data["Footer"] = "menu/footerjs.html"
}
c.Layout = layout
c.TplName = tplName
}
func (c *BaseController) jsonResult(code consts.JsonResultCode, msg string, obj interface{}) {
r := &models.JsonResult{code, msg, obj}
c.Data["json"] = r
c.ServeJSON()
c.StopRun()
}

func (c *BaseController) listJsonResult(code consts.JsonResultCode, msg string, count int64, obj interface{}) {
r := &models.ListJsonResult{code, msg, count, obj}
c.Data["json"] = r
c.ServeJSON()
c.StopRun()
}

func (c *BaseController) auth() models.UserModel {
user := c.GetSession("xcmsuser")
if user == nil {
c.Redirect("/login", 302)
c.StopRun()
return models.UserModel{}
} else {
return user.(models.UserModel)
}
}

models/Common.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package models

import (
"github.com/ziyoubiancheng/xcms/consts"
)

// JsonResult 用于返回ajax请求的基类
type JsonResult struct {
Code consts.JsonResultCode `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}

type ListJsonResult struct {
Code consts.JsonResultCode `json:"code"`
Msg string `json:"msg"`
Count int64 `json:"count"`
Data interface{} `json:"data"`
}

static
views
sysinit/sysinit.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package sysinit

import (
"time"

cache "github.com/patrickmn/go-cache"
"github.com/ziyoubiancheng/xcms/utils"
)

func init() {
//init cache
utils.Cache = cache.New(60*time.Minute, 120*time.Minute)

//init db
initDB()
}

sysinit/initDB.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package sysinit

import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
_ "github.com/ziyoubiancheng/xcms/models"
)

func initDB() {
//连接名称
dbAlias := beego.AppConfig.String("db_alias")
//数据库名称
dbName := beego.AppConfig.String("db_name")
//数据库连接用户名
dbUser := beego.AppConfig.String("db_user")
//数据库连接用户名
dbPwd := beego.AppConfig.String("db_pwd")
//数据库IP(域名)
dbHost := beego.AppConfig.String("db_host")
//数据库端口
dbPort := beego.AppConfig.String("db_port")
//charset
dbCharset := beego.AppConfig.String("db_charset")

orm.RegisterDataBase(dbAlias, "mysql", dbUser+":"+dbPwd+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?charset="+dbCharset, 30)

//如果是开发模式,则显示命令信息
isDev := (beego.AppConfig.String("runmode") == "dev")
//自动建表
orm.RunSyncdb("default", false, isDev)
if isDev {
orm.Debug = isDev
}
}

utils/Cache.go

1
2
3
4
5
package utils

import cache "github.com/patrickmn/go-cache"

var Cache *cache.Cache

utils/String.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package utils

import (
"crypto/md5"
"fmt"
"math/rand"
"regexp"
"time"
)

var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")

func Md5(buf []byte) string {
hash := md5.New()
hash.Write(buf)
return fmt.Sprintf("%x", hash.Sum(nil))
}

func SizeFormat(size float64) string {
units := []string{"Byte", "KB", "MB", "GB", "TB"}
n := 0
for size > 1024 {
size /= 1024
n += 1
}

return fmt.Sprintf("%.2f %s", size, units[n])
}

func IsEmail(b []byte) bool {
return emailPattern.Match(b)
}

func Password(len int, pwdO string) (pwd string, salt string) {
salt = GetRandomString(4)
defaultPwd := "george518"
if pwdO != "" {
defaultPwd = pwdO
}
pwd = Md5([]byte(defaultPwd + salt))
return pwd, salt
}

//生成随机字符串
func GetRandomString(lens int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < lens; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}