# HoTime 快速上手指南 5 分钟入门 HoTime 框架。 ## 安装 ```bash go get code.hoteas.com/golang/hotime ``` ## 最小示例 ```go package main import ( . "code.hoteas.com/golang/hotime" . "code.hoteas.com/golang/hotime/common" ) func main() { appIns := Init("config/config.json") appIns.Run(Router{ "app": { "test": { "hello": func(that *Context) { that.Display(0, Map{"message": "Hello World"}) }, }, }, }) } ``` 访问: `http://localhost:8081/app/test/hello` ## 配置文件 创建 `config/config.json`: ```json { "port": "8081", "mode": 2, "sessionName": "HOTIME", "tpt": "tpt", "defFile": ["index.html", "index.htm"], "db": { "mysql": { "host": "localhost", "port": "3306", "name": "your_database", "user": "root", "password": "your_password", "prefix": "" } }, "cache": { "memory": { "db": true, "session": true, "timeout": 7200 } } } ``` ### 配置项说明 | 配置项 | 默认值 | 说明 | |--------|--------|------| | `port` | 80 | HTTP 服务端口,0 为不启用 | | `tlsPort` | - | HTTPS 端口,需配合 tlsCert/tlsKey | | `tlsCert` | - | HTTPS 证书路径 | | `tlsKey` | - | HTTPS 密钥路径 | | `mode` | 0 | 0=生产, 1=测试, 2=开发(输出SQL) | | `tpt` | tpt | 静态文件目录 | | `sessionName` | HOTIME | Session Cookie 名称 | | `modeRouterStrict` | false | 路由大小写敏感,false=忽略大小写 | | `crossDomain` | - | 跨域设置,空=不开启,auto=智能开启,或指定域名 | | `logFile` | - | 日志文件路径,如 `logs/20060102.txt` | | `logLevel` | 0 | 日志等级,0=关闭,1=打印 | | `webConnectLogShow` | true | 是否显示访问日志 | | `defFile` | ["index.html"] | 目录默认访问文件 | ### 数据库配置 ```json { "db": { "mysql": { "host": "127.0.0.1", "port": "3306", "name": "database_name", "user": "root", "password": "password", "prefix": "app_", "slave": { "host": "127.0.0.1", "port": "3306", "name": "database_name", "user": "root", "password": "password" } }, "sqlite": { "path": "config/data.db", "prefix": "" } } } ``` > MySQL 配置 `slave` 项即启用主从读写分离 ### 缓存配置 ```json { "cache": { "memory": { "db": true, "session": true, "timeout": 7200 }, "redis": { "host": "127.0.0.1", "port": 6379, "password": "", "db": true, "session": true, "timeout": 1296000 }, "db": { "db": true, "session": true, "timeout": 2592000 } } } ``` 缓存优先级: **Memory > Redis > DB**,自动穿透与回填 ### 错误码配置 ```json { "error": { "1": "内部系统异常", "2": "访问权限异常", "3": "请求参数异常", "4": "数据处理异常", "5": "数据结果异常" } } ``` > 自定义错误码建议从 10 开始 ## 路由系统 HoTime 使用三层路由结构:`模块/控制器/方法` ```go appIns.Run(Router{ "模块名": { "控制器名": { "方法名": func(that *Context) { // 处理逻辑 }, }, }, }) ``` ### 路由路径 ```go // 获取路由信息 module := that.RouterString[0] // 模块 controller := that.RouterString[1] // 控制器 action := that.RouterString[2] // 方法 // 完整请求路径 fullPath := that.HandlerStr // 如 /app/user/login ``` ## 请求参数获取 ### 新版推荐方法(支持链式调用) ```go // 获取 URL 查询参数 (?id=1) id := that.ReqParam("id").ToInt() name := that.ReqParam("name").ToStr() // 获取表单参数 (POST form-data / x-www-form-urlencoded) username := that.ReqForm("username").ToStr() age := that.ReqForm("age").ToInt() // 获取 JSON Body 参数 (POST application/json) data := that.ReqJson("data").ToMap() items := that.ReqJson("items").ToSlice() // 统一获取(自动判断来源,优先级: JSON > Form > URL) userId := that.ReqData("user_id").ToInt() status := that.ReqData("status").ToStr() ``` ### 类型转换方法 ```go obj := that.ReqData("key") obj.ToStr() // 转字符串 obj.ToInt() // 转 int obj.ToInt64() // 转 int64 obj.ToFloat64() // 转 float64 obj.ToBool() // 转 bool obj.ToMap() // 转 Map obj.ToSlice() // 转 Slice obj.Data // 获取原始值(interface{}) ``` ### 文件上传 ```go // 单文件上传 file, header, err := that.ReqFile("avatar") if err == nil { defer file.Close() // header.Filename - 文件名 // header.Size - 文件大小 } // 多文件上传(批量) files, err := that.ReqFiles("images") if err == nil { for _, fh := range files { file, _ := fh.Open() defer file.Close() // 处理每个文件 } } ``` ### 传统方法(兼容) ```go // GET/POST 参数 name := that.Req.FormValue("name") // URL 参数 id := that.Req.URL.Query().Get("id") // 请求头 token := that.Req.Header.Get("Authorization") ``` ## 响应数据 ### Display 方法 ```go // 成功响应 (status=0) that.Display(0, Map{"user": user, "token": token}) // 输出: {"status":0, "result":{"user":..., "token":...}} // 错误响应 (status>0) that.Display(1, "系统内部错误") // 输出: {"status":1, "result":{"type":"内部系统异常", "msg":"系统内部错误"}, "error":{...}} that.Display(2, "请先登录") // 输出: {"status":2, "result":{"type":"访问权限异常", "msg":"请先登录"}, "error":{...}} that.Display(3, "参数不能为空") // 输出: {"status":3, "result":{"type":"请求参数异常", "msg":"参数不能为空"}, "error":{...}} ``` ### 错误码含义 | 错误码 | 类型 | 使用场景 | |--------|------|----------| | 0 | 成功 | 请求成功 | | 1 | 内部系统异常 | 环境配置、文件权限等基础运行环境错误 | | 2 | 访问权限异常 | 未登录或登录异常 | | 3 | 请求参数异常 | 参数不足、类型错误等 | | 4 | 数据处理异常 | 数据库操作或第三方请求返回异常 | | 5 | 数据结果异常 | 无法返回要求的格式 | ### 自定义响应 ```go // 自定义 Header that.Resp.Header().Set("Content-Type", "application/json") // 直接写入 that.Resp.Write([]byte("raw data")) // 自定义响应函数 that.RespFunc = func() { // 自定义响应逻辑 } ``` ## 中间件 ```go // 全局中间件(请求拦截) appIns.SetConnectListener(func(that *Context) bool { // 放行登录接口 if len(that.RouterString) >= 3 && that.RouterString[2] == "login" { return false } // 检查登录状态 if that.Session("user_id").Data == nil { that.Display(2, "请先登录") return true // 返回 true 终止请求 } return false // 返回 false 继续处理 }) ``` ## Session 与缓存 ```go // Session 操作 that.Session("user_id", 123) // 设置 userId := that.Session("user_id") // 获取 *Obj that.Session("user_id", nil) // 删除 // 链式获取 id := that.Session("user_id").ToInt64() name := that.Session("username").ToStr() // 通用缓存 that.Cache("key", "value") // 设置 data := that.Cache("key") // 获取 that.Cache("key", nil) // 删除 ``` 三级缓存自动运作:**Memory → Redis → Database** ## 数据库操作(简要) ### 基础 CRUD ```go // 查询列表 users := that.Db.Select("user", "*", Map{"status": 1}) // 查询单条 user := that.Db.Get("user", "*", Map{"id": 1}) // 插入 id := that.Db.Insert("user", Map{"name": "test", "age": 18}) // 批量插入 affected := that.Db.Inserts("user", []Map{ {"name": "user1", "age": 20}, {"name": "user2", "age": 25}, }) // 更新 rows := that.Db.Update("user", Map{"name": "new"}, Map{"id": 1}) // 删除 rows := that.Db.Delete("user", Map{"id": 1}) ``` ### 链式查询 ```go users := that.Db.Table("user"). LeftJoin("order", "user.id=order.user_id"). Where("status", 1). And("age[>]", 18). Order("id DESC"). Page(1, 10). Select("*") ``` ### 条件语法速查 | 语法 | 说明 | 示例 | |------|------|------| | `key` | 等于 | `"id": 1` | | `key[>]` | 大于 | `"age[>]": 18` | | `key[<]` | 小于 | `"age[<]": 60` | | `key[>=]` | 大于等于 | `"age[>=]": 18` | | `key[<=]` | 小于等于 | `"age[<=]": 60` | | `key[!]` | 不等于 | `"status[!]": 0` | | `key[~]` | LIKE | `"name[~]": "test"` | | `key[<>]` | BETWEEN | `"age[<>]": Slice{18, 60}` | | `key` | IN | `"id": Slice{1, 2, 3}` | ### 事务 ```go success := that.Db.Action(func(tx db.HoTimeDB) bool { tx.Update("user", Map{"balance[#]": "balance - 100"}, Map{"id": 1}) tx.Insert("order", Map{"user_id": 1, "amount": 100}) return true // 返回 true 提交,false 回滚 }) ``` > **更多数据库操作**:参见 [HoTimeDB 使用说明](HoTimeDB_使用说明.md) ## 日志记录 ```go // 创建操作日志(自动插入 logs 表) that.Log = Map{ "type": "login", "action": "用户登录", "data": Map{"phone": phone}, } // 框架会自动添加 time, admin_id/user_id, ip 等字段 ``` ## 扩展功能 | 功能 | 路径 | 说明 | |------|------|------| | 微信支付/公众号/小程序 | `dri/wechat/` | 微信全套 SDK | | 阿里云服务 | `dri/aliyun/` | 企业认证等 | | 腾讯云服务 | `dri/tencent/` | 企业认证等 | | 文件上传 | `dri/upload/` | 文件上传处理 | | 文件下载 | `dri/download/` | 文件下载处理 | | MongoDB | `dri/mongodb/` | MongoDB 驱动 | | RSA 加解密 | `dri/rsa/` | RSA 加解密工具 | ## 完整示例 ```go package main import ( . "code.hoteas.com/golang/hotime" . "code.hoteas.com/golang/hotime/common" ) func main() { appIns := Init("config/config.json") // 登录检查中间件 appIns.SetConnectListener(func(that *Context) bool { // 放行登录接口 if len(that.RouterString) >= 3 && that.RouterString[2] == "login" { return false } if that.Session("user_id").Data == nil { that.Display(2, "请先登录") return true } return false }) appIns.Run(Router{ "api": { "user": { "login": func(that *Context) { phone := that.ReqData("phone").ToStr() password := that.ReqData("password").ToStr() if phone == "" || password == "" { that.Display(3, "手机号和密码不能为空") return } user := that.Db.Get("user", "*", Map{ "phone": phone, "password": Md5(password), }) if user == nil { that.Display(3, "账号或密码错误") return } that.Session("user_id", user.GetInt64("id")) that.Display(0, Map{"user": user}) }, "info": func(that *Context) { userId := that.Session("user_id").ToInt64() user := that.Db.Get("user", "*", Map{"id": userId}) that.Display(0, Map{"user": user}) }, "list": func(that *Context) { page := that.ReqData("page").ToInt() if page == 0 { page = 1 } users := that.Db.Table("user"). Where("status", 1). Order("id DESC"). Page(page, 10). Select("id,name,phone,created_at") total := that.Db.Count("user", Map{"status": 1}) that.Display(0, Map{ "list": users, "total": total, "page": page, }) }, "logout": func(that *Context) { that.Session("user_id", nil) that.Display(0, "退出成功") }, }, }, }) } ``` --- **下一步**: - [HoTimeDB 使用说明](HoTimeDB_使用说明.md) - 完整数据库教程 - [HoTimeDB API 参考](HoTimeDB_API参考.md) - API 速查手册