Add the frame for installation.

This commit is contained in:
zicla
2018-12-03 21:21:37 +08:00
parent 821c625fb9
commit 5611c5acb6
24 changed files with 593 additions and 452 deletions

View File

@ -82,14 +82,14 @@ func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *htt
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
//用json的方式输出返回值。
var json = jsoniter.ConfigCompatibleWithStandardLibrary
b, err := json.Marshal(webResult)
b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
this.PanicError(err)
writer.WriteHeader(FetchHttpStatus(webResult.Code))
fmt.Fprintf(writer, string(b))
_, err = fmt.Fprintf(writer, string(b))
this.PanicError(err)
} else {
//输出的内容是二进制的。
@ -117,7 +117,6 @@ func (this *BaseController) Success(data interface{}) *WebResult {
return webResult
}
//允许跨域请求
func (this *BaseController) allowCORS(writer http.ResponseWriter) {
writer.Header().Add("Access-Control-Allow-Origin", "*")

View File

@ -5,7 +5,11 @@ import (
)
type IBean interface {
//初始化方法
Init()
//所有配置都加载完成后调用的方法,包括数据库加载完毕
ConfigPost()
//快速的Panic方法
PanicError(err error)
}
@ -17,6 +21,10 @@ func (this *Bean) Init() {
this.logger = LOGGER
}
func (this *Bean) ConfigPost() {
}
//处理错误的统一方法 可以省去if err!=nil 这段代码
func (this *Bean) PanicError(err error) {
if err != nil {

View File

@ -2,12 +2,8 @@ package rest
import (
"encoding/json"
"flag"
"fmt"
"github.com/json-iterator/go"
"io/ioutil"
"os"
"strconv"
"time"
"unsafe"
)
@ -29,47 +25,28 @@ create database tank;
grant all privileges on tank.* to tank identified by 'tank123';
flush privileges;
*/
/*
你也可以在运行时的参数中临时修改一些配置项:
-MysqlHost=127.0.0.1 -MysqlPort=3306 -MysqlSchema=tank -MysqlUsername=tank -MysqlPassword=tank123
*/
var (
CONFIG = &Config{
//以下内容是默认配置项。
//默认监听端口号
ServerPort: 6010,
//上传的文件路径如果没有指定默认在根目录下的matter文件夹中
MatterPath: "",
//mysql相关配置。
//数据库端口
MysqlPort: 3306,
//数据库Host
MysqlHost: "127.0.0.1",
//数据库名字
MysqlSchema: "tank",
//用户名
MysqlUsername: "tank",
//密码
MysqlPassword: "tank123",
//数据库连接信息。这一项是上面几项组合而得,不可直接配置。
MysqlUrl: "%MysqlUsername:%MysqlPassword@tcp(%MysqlHost:%MysqlPort)/%MysqlSchema?charset=utf8&parseTime=True&loc=Local",
//超级管理员用户名,只能包含英文和数字
AdminUsername: "admin",
//超级管理员邮箱
AdminEmail: "admin@tank.eyeblue.cn",
//超级管理员密码
AdminPassword: "123456",
}
)
var CONFIG = &Config{}
//依赖外部定义的变量。
type Config struct {
//默认监听端口号
ServerPort int
//数据库是否配置完备
DBConfigured bool
//上传的文件路径,要求不以/结尾。如果没有指定默认在根目录下的matter文件夹中。eg: /var/www/matter
MatterPath string
//数据库连接信息。
MysqlUrl string
//配置文件中的项
Item *ConfigItem
}
//和tank.json文件中的键值一一对应。
type ConfigItem struct {
//默认监听端口号
ServerPort int
//上传的文件路径,要求不以/结尾。如果没有指定默认在根目录下的matter文件夹中。eg: /var/www/matter
MatterPath string
//mysql相关配置。
//数据库端口
MysqlPort int
@ -81,52 +58,49 @@ type Config struct {
MysqlUsername string
//密码
MysqlPassword string
//数据库连接信息。
MysqlUrl string
//超级管理员用户名,只能包含英文和数字
AdminUsername string
//超级管理员邮箱
AdminEmail string
//超级管理员密码
AdminPassword string
}
//验证配置文件的正确性。
func (this *Config) validate() {
func (this *ConfigItem) validate() bool {
if this.ServerPort == 0 {
LOGGER.Error("ServerPort 未配置")
return false
}
if this.MysqlUsername == "" {
LOGGER.Error("MysqlUsername 未配置")
return false
}
if this.MysqlPassword == "" {
LOGGER.Error("MysqlPassword 未配置")
return false
}
if this.MysqlHost == "" {
LOGGER.Error("MysqlHost 未配置")
return false
}
if this.MysqlPort == 0 {
LOGGER.Error("MysqlPort 未配置")
return false
}
if this.MysqlSchema == "" {
LOGGER.Error("MysqlSchema 未配置")
return false
}
this.MysqlUrl = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", this.MysqlUsername, this.MysqlPassword, this.MysqlHost, this.MysqlPort, this.MysqlSchema)
return true
}
//init方法只要这个包被引入了就一定会执行。
func init() {
//验证配置文件是否完好
func (this *Config) Init() {
//json中需要去特殊处理时间。
//JSON初始化
jsoniter.RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
//如果使用time.UTC那么时间会相差8小时
t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.Local)
@ -142,171 +116,39 @@ func init() {
//如果使用time.UTC那么时间会相差8小时
stream.WriteString(t.Local().Format("2006-01-02 15:04:05"))
}, nil)
}
//第一级. 从配置文件conf/tank.json中读取配置项
func LoadConfigFromFile() {
//默认从6010端口启动
CONFIG.ServerPort = 6010
//读取配置文件
filePath := GetConfPath() + "/tank.json"
content, err := ioutil.ReadFile(filePath)
if err != nil {
LOGGER.Warn("无法找到配置文件:%s 将使用config.go中的默认配置项。", filePath)
LOGGER.Warn("即将进入安装过程,无法找到配置文件:%s", filePath)
this.DBConfigured = false
} else {
// 用 json.Unmarshal
err := json.Unmarshal(content, CONFIG)
err := json.Unmarshal(content, this.Item)
if err != nil {
LOGGER.Panic("配置文件格式错误!")
LOGGER.Error("配置文件格式错误!")
this.DBConfigured = false
return
}
}
}
//第二级. 从环境变量中读取配置项
func LoadConfigFromEnvironment() {
tmpServerPort := os.Getenv("TANK_SERVER_PORT")
if tmpServerPort != "" {
i, e := strconv.Atoi(tmpServerPort)
if e == nil {
CONFIG.ServerPort = i
} else {
LOGGER.Panic("环境变量TANK_SERVER_PORT必须为整数%v", tmpServerPort)
//验证项是否齐全
itemValidate := this.Item.validate()
if !itemValidate {
this.DBConfigured = false
return
}
}
tmpMatterPath := os.Getenv("TANK_MATTER_PATH")
if tmpMatterPath != "" {
CONFIG.MatterPath = tmpMatterPath
}
tmpMysqlPort := os.Getenv("TANK_MYSQL_PORT")
if tmpMysqlPort != "" {
i, e := strconv.Atoi(tmpMysqlPort)
if e == nil {
CONFIG.MysqlPort = i
} else {
LOGGER.Panic("环境变量TANK_MYSQL_PORT必须为整数%v", tmpMysqlPort)
if this.Item.MatterPath == "" {
CONFIG.MatterPath = GetHomePath() + "/matter"
}
}
MakeDirAll(CONFIG.MatterPath)
tmpMysqlHost := os.Getenv("TANK_MYSQL_HOST")
if tmpMysqlHost != "" {
CONFIG.MysqlHost = tmpMysqlHost
}
tmpMysqlSchema := os.Getenv("TANK_MYSQL_SCHEMA")
if tmpMysqlSchema != "" {
CONFIG.MysqlSchema = tmpMysqlSchema
}
tmpMysqlUsername := os.Getenv("TANK_MYSQL_USERNAME")
if tmpMysqlUsername != "" {
CONFIG.MysqlUsername = tmpMysqlUsername
}
tmpMysqlPassword := os.Getenv("TANK_MYSQL_PASSWORD")
if tmpMysqlPassword != "" {
CONFIG.MysqlPassword = tmpMysqlPassword
}
tmpAdminUsername := os.Getenv("TANK_ADMIN_USERNAME")
if tmpAdminUsername != "" {
CONFIG.AdminUsername = tmpAdminUsername
}
tmpAdminEmail := os.Getenv("TANK_ADMIN_EMAIL")
if tmpAdminEmail != "" {
CONFIG.AdminEmail = tmpAdminEmail
}
tmpAdminPassword := os.Getenv("TANK_ADMIN_PASSWORD")
if tmpAdminPassword != "" {
CONFIG.AdminPassword = tmpAdminPassword
this.MysqlUrl = GetMysqlUrl(this.Item.MysqlPort, this.Item.MysqlHost, this.Item.MysqlSchema, this.Item.MysqlUsername, this.Item.MysqlPassword)
this.DBConfigured = true
}
}
//第三级. 从程序参数中读取配置项
func LoadConfigFromArguments() {
//从运行时参数中读取,运行时参数具有更高优先级。
//系统端口号
ServerPortPtr := flag.Int("ServerPort", CONFIG.ServerPort, "server port")
//日志和上传文件的路径
MatterPathPtr := flag.String("MatterPath", CONFIG.MatterPath, "matter path")
//mysql相关配置。
MysqlPortPtr := flag.Int("MysqlPort", CONFIG.MysqlPort, "mysql port")
MysqlHostPtr := flag.String("MysqlHost", CONFIG.MysqlHost, "mysql host")
MysqlSchemaPtr := flag.String("MysqlSchema", CONFIG.MysqlSchema, "mysql schema")
MysqlUsernamePtr := flag.String("MysqlUsername", CONFIG.MysqlUsername, "mysql username")
MysqlPasswordPtr := flag.String("MysqlPassword", CONFIG.MysqlPassword, "mysql password")
//超级管理员信息
AdminUsernamePtr := flag.String("AdminUsername", CONFIG.AdminUsername, "administrator username")
AdminEmailPtr := flag.String("AdminEmail", CONFIG.AdminEmail, "administrator email")
AdminPasswordPtr := flag.String("AdminPassword", CONFIG.AdminPassword, "administrator password")
//flag.Parse()方法必须要在使用之前调用。
flag.Parse()
if *ServerPortPtr != CONFIG.ServerPort {
CONFIG.ServerPort = *ServerPortPtr
}
if *MatterPathPtr != CONFIG.MatterPath {
CONFIG.MatterPath = *MatterPathPtr
}
if *MysqlPortPtr != CONFIG.MysqlPort {
CONFIG.MysqlPort = *MysqlPortPtr
}
if *MysqlHostPtr != CONFIG.MysqlHost {
CONFIG.MysqlHost = *MysqlHostPtr
}
if *MysqlSchemaPtr != CONFIG.MysqlSchema {
CONFIG.MysqlSchema = *MysqlSchemaPtr
}
if *MysqlUsernamePtr != CONFIG.MysqlUsername {
CONFIG.MysqlUsername = *MysqlUsernamePtr
}
if *MysqlPasswordPtr != CONFIG.MysqlPassword {
CONFIG.MysqlPassword = *MysqlPasswordPtr
}
if *AdminUsernamePtr != CONFIG.AdminUsername {
CONFIG.AdminUsername = *AdminUsernamePtr
}
if *AdminEmailPtr != CONFIG.AdminEmail {
CONFIG.AdminEmail = *AdminEmailPtr
}
if *AdminPasswordPtr != CONFIG.AdminPassword {
CONFIG.AdminPassword = *AdminPasswordPtr
}
}
//三种方式指定配置项,后面的策略会覆盖前面的策略。
func PrepareConfigs() {
//第一级. 从配置文件conf/tank.json中读取配置项
LoadConfigFromFile()
//第二级. 从环境变量中读取配置项
LoadConfigFromEnvironment()
//第三级. 从程序参数中读取配置项
LoadConfigFromArguments()
if CONFIG.MatterPath == "" {
CONFIG.MatterPath = GetHomePath() + "/matter"
}
MakeDirAll(CONFIG.MatterPath)
//验证配置项的正确性
CONFIG.validate()
//TODO:安装程序开始导入初始表和初始数据。 做成可视化安装。
//InstallDatabase()
}

View File

@ -26,9 +26,6 @@ type Context struct {
//初始化上下文
func (this *Context) Init() {
//处理数据库连接的开关。
this.OpenDb()
//创建一个用于存储session的缓存。
this.SessionCache = NewCacheTable()
@ -44,6 +41,13 @@ func (this *Context) Init() {
//初始化Router. 这个方法要在Bean注册好了之后才能。
this.Router = NewRouter()
//如果数据库信息配置好了,就直接打开数据库连接 同时执行Bean的ConfigPost方法
if CONFIG.DBConfigured {
this.OpenDb()
this.configPostBeans()
}
}
func (this *Context) OpenDb() {
@ -116,6 +120,9 @@ func (this *Context) registerBeans() {
this.registerBean(new(ImageCacheDao))
this.registerBean(new(ImageCacheService))
//install
this.registerBean(new(InstallController))
//matter
this.registerBean(new(MatterController))
this.registerBean(new(MatterDao))
@ -164,7 +171,14 @@ func (this *Context) initBeans() {
for _, bean := range this.BeanMap {
bean.Init()
}
}
//所有配置项完备后执行的方法
func (this *Context) configPostBeans() {
for _, bean := range this.BeanMap {
bean.ConfigPost()
}
}
//销毁的方法

View File

@ -46,9 +46,13 @@ func (this *DashboardService) Init() {
this.userDao = b
}
}
//系统启动,数据库配置完毕后会调用该方法
func (this *DashboardService) ConfigPost() {
//立即执行数据清洗任务
go SafeMethod(this.maintain)
}
//每日清洗离线数据表。

View File

@ -2,6 +2,7 @@ package rest
import (
"encoding/json"
"github.com/json-iterator/go"
"net/http"
"time"
)
@ -61,23 +62,30 @@ func (this *FootprintService) Trace(writer http.ResponseWriter, request *http.Re
paramsString = string(paramsData)
}
user := this.findUser(writer, request)
userUuid := ""
if user != nil {
userUuid = user.Uuid
}
//将文件信息存入数据库中。
footprint := &Footprint{
UserUuid: userUuid,
Ip: GetIpAddress(request),
Host: request.Host,
Uri: request.URL.Path,
Params: paramsString,
Cost: int64(duration / time.Millisecond),
Success: success,
Ip: GetIpAddress(request),
Host: request.Host,
Uri: request.URL.Path,
Params: paramsString,
Cost: int64(duration / time.Millisecond),
Success: success,
}
footprint = this.footprintDao.Create(footprint)
//有可能DB尚且没有配置 直接打印出内容,并且退出
if CONFIG.DBConfigured {
user := this.findUser(writer, request)
userUuid := ""
if user != nil {
userUuid = user.Uuid
}
footprint.UserUuid = userUuid
footprint = this.footprintDao.Create(footprint)
} else {
//用json的方式输出返回值。
b, _ := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(footprint)
this.logger.Info("%s", string(b))
}
}

View File

@ -3,9 +3,6 @@ package rest
import (
"fmt"
"github.com/jinzhu/gorm"
"github.com/nu7hatch/gouuid"
"regexp"
"time"
)
//首次运行的时候,将自动安装数据库等内容。
@ -85,44 +82,6 @@ func InstallDatabase() {
hasTable = db.HasTable(user)
if !hasTable {
//验证超级管理员的信息
if m, _ := regexp.MatchString(`^[0-9a-zA-Z_]+$`, CONFIG.AdminUsername); !m {
LOGGER.Panic(`超级管理员用户名必填,且只能包含字母,数字和'_''`)
}
if len(CONFIG.AdminPassword) < 6 {
LOGGER.Panic(`超级管理员密码长度至少为6位`)
}
if CONFIG.AdminEmail == "" {
LOGGER.Panic("超级管理员邮箱必填!")
}
createUser := "CREATE TABLE `tank20_user` (`uuid` char(36) NOT NULL,`role` varchar(45) DEFAULT 'USER',`username` varchar(255) DEFAULT NULL COMMENT '昵称',`password` varchar(255) DEFAULT NULL COMMENT '密码',`email` varchar(45) DEFAULT NULL COMMENT '邮箱',`phone` varchar(45) DEFAULT NULL COMMENT '电话',`gender` varchar(45) DEFAULT 'UNKNOWN' COMMENT '性别,默认未知',`city` varchar(45) DEFAULT NULL COMMENT '城市',`avatar_url` varchar(255) DEFAULT NULL COMMENT '头像链接',`last_time` datetime DEFAULT NULL COMMENT '上次登录使劲按',`last_ip` varchar(45) DEFAULT NULL,`size_limit` int(11) DEFAULT '-1' COMMENT '该账号上传文件的大小限制单位byte。<0 表示不设限制',`status` varchar(45) DEFAULT 'OK',`sort` bigint(20) DEFAULT NULL,`modify_time` timestamp NULL DEFAULT NULL,`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`uuid`),UNIQUE KEY `id_UNIQUE` (`uuid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表描述';"
db = db.Exec(createUser)
if db.Error != nil {
LOGGER.Panic(db.Error.Error())
}
LOGGER.Info("创建User表")
user := &User{}
timeUUID, _ := uuid.NewV4()
user.Uuid = string(timeUUID.String())
user.CreateTime = time.Now()
user.UpdateTime = time.Now()
user.LastTime = time.Now()
user.Sort = time.Now().UnixNano() / 1e6
user.Role = USER_ROLE_ADMINISTRATOR
user.Username = CONFIG.AdminUsername
user.Password = GetBcrypt(CONFIG.AdminPassword)
user.Email = CONFIG.AdminEmail
user.Phone = ""
user.Gender = USER_GENDER_UNKNOWN
user.SizeLimit = -1
user.Status = USER_STATUS_OK
db.Create(user)
}
}

104
rest/install_controller.go Normal file
View File

@ -0,0 +1,104 @@
package rest
import (
"github.com/jinzhu/gorm"
"net/http"
"strconv"
)
type InstallController struct {
BaseController
uploadTokenDao *UploadTokenDao
downloadTokenDao *DownloadTokenDao
matterDao *MatterDao
matterService *MatterService
imageCacheDao *ImageCacheDao
imageCacheService *ImageCacheService
}
//初始化方法
func (this *InstallController) Init() {
this.BaseController.Init()
//手动装填本实例的Bean.
b := CONTEXT.GetBean(this.uploadTokenDao)
if c, ok := b.(*UploadTokenDao); ok {
this.uploadTokenDao = c
}
b = CONTEXT.GetBean(this.downloadTokenDao)
if c, ok := b.(*DownloadTokenDao); ok {
this.downloadTokenDao = c
}
b = CONTEXT.GetBean(this.matterDao)
if c, ok := b.(*MatterDao); ok {
this.matterDao = c
}
b = CONTEXT.GetBean(this.matterService)
if c, ok := b.(*MatterService); ok {
this.matterService = c
}
b = CONTEXT.GetBean(this.imageCacheDao)
if c, ok := b.(*ImageCacheDao); ok {
this.imageCacheDao = c
}
b = CONTEXT.GetBean(this.imageCacheService)
if c, ok := b.(*ImageCacheService); ok {
this.imageCacheService = c
}
}
//注册自己的路由。
func (this *InstallController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
//每个Controller需要主动注册自己的路由。
routeMap["/api/install/verify"] = this.Wrap(this.Verify, USER_ROLE_GUEST)
routeMap["/api/install/table/dashboard"] = this.Wrap(this.InstallTableDashboard, USER_ROLE_GUEST)
return routeMap
}
//验证数据库连接
func (this *InstallController) Verify(writer http.ResponseWriter, request *http.Request) *WebResult {
mysqlPortStr := request.FormValue("mysqlPort")
mysqlHost := request.FormValue("mysqlHost")
mysqlSchema := request.FormValue("mysqlSchema")
mysqlUsername := request.FormValue("mysqlUsername")
mysqlPassword := request.FormValue("mysqlPassword")
var mysqlPort int
if mysqlPortStr != "" {
tmp, err := strconv.Atoi(mysqlPortStr)
this.PanicError(err)
mysqlPort = tmp
}
mysqlUrl := GetMysqlUrl(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword)
this.logger.Info("验证MySQL连接性 %s", mysqlUrl)
var err error = nil
db, err := gorm.Open("mysql", mysqlUrl)
this.PanicError(err)
this.logger.Info("Ping一下数据库")
err = db.DB().Ping()
this.PanicError(err)
return this.Success("OK")
}
//安装dashboard表
func (this *InstallController) InstallTableDashboard(writer http.ResponseWriter, request *http.Request) *WebResult {
return this.Success("")
}

View File

@ -104,7 +104,7 @@ func (this *Logger) maintain() {
now := time.Now()
nextTime := FirstSecondOfDay(Tomorrow())
duration := nextTime.Sub(now)
this.Info("%vs 后将进行下一次日志维护 下次时间维护时间:%v ", int64(duration/time.Second), nextTime)
this.Info("下次维护时间:%v ", int64(duration/time.Second), nextTime)
this.maintainTimer = time.AfterFunc(duration, func() {
go SafeMethod(this.maintain)
})

View File

@ -12,19 +12,28 @@ import (
//用于处理所有前来的请求
type Router struct {
footprintService *FootprintService
userService *UserService
routeMap map[string]func(writer http.ResponseWriter, request *http.Request)
installController *InstallController
footprintService *FootprintService
userService *UserService
routeMap map[string]func(writer http.ResponseWriter, request *http.Request)
installRouteMap map[string]func(writer http.ResponseWriter, request *http.Request)
}
//构造方法
func NewRouter() *Router {
router := &Router{
routeMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
routeMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
installRouteMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
}
//installController.
b := CONTEXT.GetBean(router.installController)
if b, ok := b.(*InstallController); ok {
router.installController = b
}
//装载userService.
b := CONTEXT.GetBean(router.userService)
b = CONTEXT.GetBean(router.userService)
if b, ok := b.(*UserService); ok {
router.userService = b
}
@ -35,12 +44,21 @@ func NewRouter() *Router {
router.footprintService = b
}
//将Controller中的路由规则装载进来
//将Controller中的路由规则装载进来InstallController中的除外
for _, controller := range CONTEXT.ControllerMap {
routes := controller.RegisterRoutes()
for k, v := range routes {
router.routeMap[k] = v
if controller == router.installController {
routes := controller.RegisterRoutes()
for k, v := range routes {
router.installRouteMap[k] = v
}
} else {
routes := controller.RegisterRoutes()
for k, v := range routes {
router.routeMap[k] = v
}
}
}
return router
@ -77,8 +95,7 @@ func (this *Router) GlobalPanicHandler(writer http.ResponseWriter, request *http
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
//用json的方式输出返回值。
var json = jsoniter.ConfigCompatibleWithStandardLibrary
b, _ := json.Marshal(webResult)
b, _ := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
//写到输出流中
_, err := fmt.Fprintf(writer, string(b))
@ -105,35 +122,44 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request)
path := request.URL.Path
if strings.HasPrefix(path, "/api") {
//统一处理用户的身份信息。
this.userService.bootstrap(writer, request)
if CONFIG.DBConfigured {
//已安装的模式
if handler, ok := this.routeMap[path]; ok {
//统一处理用户的身份信息。
this.userService.bootstrap(writer, request)
handler(writer, request)
if handler, ok := this.routeMap[path]; ok {
handler(writer, request)
} else {
//直接将请求扔给每个controller看看他们能不能处理如果都不能处理那就抛出找不到的错误
canHandle := false
for _, controller := range CONTEXT.ControllerMap {
if handler, exist := controller.HandleRoutes(writer, request); exist {
canHandle = true
handler(writer, request)
break
}
}
} else {
//直接将请求扔给每个controller看看他们能不能处理如果都不能处理那就抛出找不到的错误
canHandle := false
for _, controller := range CONTEXT.ControllerMap {
if handler, exist := controller.HandleRoutes(writer, request); exist {
canHandle = true
handler(writer, request)
break
if !canHandle {
panic(CustomWebResult(CODE_WRAPPER_NOT_FOUND, fmt.Sprintf("没有找到能够处理%s的方法", path)))
}
}
if !canHandle {
panic(CustomWebResult(CODE_WRAPPER_NOT_FOUND, fmt.Sprintf("没有找到能够处理%s的方法", path)))
}
//正常的访问记录会落到这里。
go SafeMethod(func() {
this.footprintService.Trace(writer, request, time.Now().Sub(startTime), true)
})
} else {
//未安装模式
if handler, ok := this.installRouteMap[path]; ok {
handler(writer, request)
} else {
panic(ConstWebResult(CODE_WRAPPER_NOT_INSTALLED))
}
}
//正常的访问记录会落到这里。
go SafeMethod(func() {
this.footprintService.Trace(writer, request, time.Now().Sub(startTime), true)
})
} else {
//当作静态资源处理。默认从当前文件下面的static文件夹中取东西。
dir := GetHtmlPath()

View File

@ -30,3 +30,13 @@ func HumanFileSize(bytes int64) string {
return fmt.Sprintf("%s%s", numStr, units[u])
}
//获取MySQL的URL
func GetMysqlUrl(
mysqlPort int,
mysqlHost string,
mysqlSchema string,
mysqlUsername string,
mysqlPassword string) string {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", mysqlUsername, mysqlPassword, mysqlHost, mysqlPort, mysqlSchema)
}

View File

@ -31,6 +31,7 @@ var (
CODE_WRAPPER_UNAUTHORIZED = &CodeWrapper{Code: "UNAUTHORIZED", HttpStatus: http.StatusUnauthorized, Description: "没有权限,禁止访问"}
CODE_WRAPPER_NOT_FOUND = &CodeWrapper{Code: "NOT_FOUND", HttpStatus: http.StatusNotFound, Description: "内容不存在"}
CODE_WRAPPER_RANGE_NOT_SATISFIABLE = &CodeWrapper{Code: "RANGE_NOT_SATISFIABLE", HttpStatus: http.StatusRequestedRangeNotSatisfiable, Description: "文件范围读取错误"}
CODE_WRAPPER_NOT_INSTALLED = &CodeWrapper{Code: "NOT_INSTALLED", HttpStatus: http.StatusInternalServerError, Description: "系统尚未安装"}
CODE_WRAPPER_UNKNOWN = &CodeWrapper{Code: "UNKNOWN", HttpStatus: http.StatusInternalServerError, Description: "服务器未知错误"}
)