Ready to implement the cache lib.

This commit is contained in:
zicla 2018-11-28 21:02:06 +08:00
parent a2a35ed4d2
commit 7d8db0a518
8 changed files with 435 additions and 69 deletions

View File

@ -1,109 +1,133 @@
CREATE TABLE `tank20_download_token` (
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`matter_uuid` char(36) DEFAULT NULL COMMENT '文件标识',
CREATE TABLE `tank20_download_token`
(
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`matter_uuid` char(36) DEFAULT NULL COMMENT '文件标识',
`expire_time` timestamp NULL DEFAULT NULL COMMENT '授权访问的次数',
`ip` varchar(45) DEFAULT NULL COMMENT '消费者的ip',
`sort` bigint(20) DEFAULT NULL,
`ip` varchar(45) DEFAULT NULL COMMENT '消费者的ip',
`sort` bigint(20) DEFAULT NULL,
`update_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='下载的token表';
CREATE TABLE `tank20_image_cache` (
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '上传的用户id',
`matter_uuid` char(36) DEFAULT NULL,
`mode` varchar(512) DEFAULT NULL COMMENT '请求的uri',
`md5` varchar(45) DEFAULT NULL COMMENT '文件的md5值',
`size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`path` varchar(255) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
CREATE TABLE `tank20_image_cache`
(
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '上传的用户id',
`matter_uuid` char(36) DEFAULT NULL,
`mode` varchar(512) DEFAULT NULL COMMENT '请求的uri',
`md5` varchar(45) DEFAULT NULL COMMENT '文件的md5值',
`size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`path` varchar(255) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
`update_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='图片缓存表';
CREATE TABLE `tank20_matter` (
`uuid` char(36) NOT NULL,
`puuid` varchar(45) DEFAULT NULL COMMENT '上一级的uuid',
`user_uuid` char(36) DEFAULT NULL COMMENT '上传的用户id',
`dir` tinyint(1) DEFAULT '0' COMMENT '是否是文件夹',
`alien` tinyint(1) DEFAULT '0',
`name` varchar(255) DEFAULT NULL COMMENT '文件名称',
`md5` varchar(45) DEFAULT NULL COMMENT '文件的md5值',
`size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`privacy` tinyint(1) DEFAULT '0' COMMENT '文件是否是公有的',
`path` varchar(255) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
CREATE TABLE `tank20_matter`
(
`uuid` char(36) NOT NULL,
`puuid` varchar(45) DEFAULT NULL COMMENT '上一级的uuid',
`user_uuid` char(36) DEFAULT NULL COMMENT '上传的用户id',
`dir` tinyint(1) DEFAULT '0' COMMENT '是否是文件夹',
`alien` tinyint(1) DEFAULT '0',
`name` varchar(255) DEFAULT NULL COMMENT '文件名称',
`md5` varchar(45) DEFAULT NULL COMMENT '文件的md5值',
`size` bigint(20) DEFAULT '0' COMMENT '文件大小',
`privacy` tinyint(1) DEFAULT '0' COMMENT '文件是否是公有的',
`path` varchar(255) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
`update_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='file表';
CREATE TABLE `tank20_preference` (
`uuid` char(36) NOT NULL,
`name` varchar(45) DEFAULT NULL COMMENT '网站名称',
`logo_url` varchar(255) DEFAULT NULL,
`favicon_url` varchar(255) DEFAULT NULL,
CREATE TABLE `tank20_preference`
(
`uuid` char(36) NOT NULL,
`name` varchar(45) DEFAULT NULL COMMENT '网站名称',
`logo_url` varchar(255) DEFAULT NULL,
`favicon_url` varchar(255) DEFAULT NULL,
`footer_line1` varchar(1024) DEFAULT NULL,
`footer_line2` varchar(1024) DEFAULT NULL,
`version` varchar(45) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
`update_time` timestamp NULL DEFAULT NULL,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`version` varchar(45) DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
`update_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='网站偏好设置表';
CREATE TABLE `tank20_session` (
`uuid` char(36) NOT NULL,
`authentication` char(36) DEFAULT NULL COMMENT '认证身份存放在cookie中',
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`ip` varchar(45) DEFAULT NULL COMMENT '用户的ip地址',
`expire_time` timestamp NULL DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
CREATE TABLE `tank20_security_visit`
(
`uuid` char(36) NOT NULL,
`session_id` varchar(45) DEFAULT NULL,
`user_uuid` char(36) DEFAULT NULL,
`ip` varchar(45) DEFAULT NULL,
`host` varchar(45) DEFAULT NULL,
`uri` varchar(255) DEFAULT NULL,
`params` text,
`cost` int(11) DEFAULT '0' COMMENT '耗时 ms',
`success` tinyint(1) DEFAULT '1',
`sort` bigint(20) NOT NULL DEFAULT '0',
`update_time` timestamp NULL DEFAULT NULL,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='访问记录表';
CREATE TABLE `tank20_session`
(
`uuid` char(36) NOT NULL,
`authentication` char(36) DEFAULT NULL COMMENT '认证身份存放在cookie中',
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`ip` varchar(45) DEFAULT NULL COMMENT '用户的ip地址',
`expire_time` timestamp NULL DEFAULT NULL,
`sort` bigint(20) DEFAULT NULL,
`update_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='session表';
CREATE TABLE `tank20_upload_token` (
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`folder_uuid` char(36) DEFAULT NULL,
`matter_uuid` char(36) DEFAULT NULL,
`filename` varchar(255) DEFAULT NULL COMMENT '文件后缀名的过滤,可以只允许用户上传特定格式的文件。',
`privacy` tinyint(1) DEFAULT '1',
`size` bigint(20) DEFAULT '0',
CREATE TABLE `tank20_upload_token`
(
`uuid` char(36) NOT NULL,
`user_uuid` char(36) DEFAULT NULL COMMENT '用户uuid',
`folder_uuid` char(36) DEFAULT NULL,
`matter_uuid` char(36) DEFAULT NULL,
`filename` varchar(255) DEFAULT NULL COMMENT '文件后缀名的过滤,可以只允许用户上传特定格式的文件。',
`privacy` tinyint(1) DEFAULT '1',
`size` bigint(20) DEFAULT '0',
`expire_time` timestamp NULL DEFAULT NULL,
`ip` varchar(45) DEFAULT NULL COMMENT '消费者的ip',
`sort` bigint(20) DEFAULT NULL,
`ip` varchar(45) DEFAULT NULL COMMENT '消费者的ip',
`sort` bigint(20) DEFAULT NULL,
`update_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='上传的token表';
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,
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,
`update_time` timestamp NULL DEFAULT NULL,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`uuid`),

View File

@ -115,6 +115,11 @@ func (this *Context) registerBeans() {
this.registerBean(new(PreferenceDao))
this.registerBean(new(PreferenceService))
//securityVisit
this.registerBean(new(SecurityVisitController))
this.registerBean(new(SecurityVisitDao))
this.registerBean(new(SecurityVisitService))
//session
this.registerBean(new(SessionDao))

View File

@ -1,6 +1,7 @@
package rest
import (
"encoding/json"
"fmt"
"github.com/json-iterator/go"
"io"
@ -76,6 +77,58 @@ func (this *Router) GlobalPanicHandler(writer http.ResponseWriter, request *http
}
}
//记录访问记录
func (this *Router) logSecurityVisit(writer http.ResponseWriter, request *http.Request) {
//手动装填本实例的Bean. 这里必须要用中间变量方可。
var securityVisitDao *SecurityVisitDao
b := this.context.GetBean(securityVisitDao)
if b, ok := b.(*SecurityVisitDao); ok {
securityVisitDao = b
}
fmt.Printf("Host = %s Uri = %s Path = %s RawPath = %s RawQuery = %s \n",
request.Host,
request.RequestURI,
request.URL.Path,
request.URL.RawPath,
request.URL.RawQuery)
params := make(map[string][]string)
//POST请求参数
values := request.PostForm
for key, val := range values {
params[key] = val
}
//GET请求参数
values1 := request.URL.Query()
for key, val := range values1 {
params[key] = val
}
//用json的方式输出返回值。
paramsString := "{}"
paramsData, err := json.Marshal(params)
if err == nil {
paramsString = string(paramsData)
}
//将文件信息存入数据库中。
securityVisit := &SecurityVisit{
SessionId: "",
UserUuid: "testUserUUid",
Ip: GetIpAddress(request),
Host: request.Host,
Uri: request.URL.Path,
Params: paramsString,
Cost: 0,
Success: true,
}
securityVisit = securityVisitDao.Create(securityVisit)
}
//让Router具有处理请求的功能。
func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
@ -86,6 +139,7 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request)
path := request.URL.Path
if strings.HasPrefix(path, "/api") {
if handler, ok := this.routeMap[path]; ok {
handler(writer, request)
@ -108,6 +162,9 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request)
}
//正常的访问记录会落到这里。
go this.logSecurityVisit(writer, request)
} else {
//当作静态资源处理。默认从当前文件下面的static文件夹中取东西。
dir := GetHtmlPath()
@ -141,4 +198,5 @@ func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request)
}
}

View File

@ -0,0 +1,129 @@
package rest
import (
"net/http"
"strconv"
)
type SecurityVisitController struct {
BaseController
securityVisitDao *SecurityVisitDao
securityVisitService *SecurityVisitService
}
//初始化方法
func (this *SecurityVisitController) Init(context *Context) {
this.BaseController.Init(context)
//手动装填本实例的Bean. 这里必须要用中间变量方可。
b := context.GetBean(this.securityVisitDao)
if b, ok := b.(*SecurityVisitDao); ok {
this.securityVisitDao = b
}
b = context.GetBean(this.securityVisitService)
if b, ok := b.(*SecurityVisitService); ok {
this.securityVisitService = b
}
}
//注册自己的路由。
func (this *SecurityVisitController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
//每个Controller需要主动注册自己的路由。
routeMap["/api/security/visit/delete"] = this.Wrap(this.Delete, USER_ROLE_USER)
routeMap["/api/security/visit/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
routeMap["/api/security/visit/page"] = this.Wrap(this.Page, USER_ROLE_USER)
return routeMap
}
//查看详情。
func (this *SecurityVisitController) Detail(writer http.ResponseWriter, request *http.Request) *WebResult {
uuid := request.FormValue("uuid")
if uuid == "" {
return this.Error("图片缓存的uuid必填")
}
securityVisit := this.securityVisitService.Detail(uuid)
//验证当前之人是否有权限查看这么详细。
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR {
if securityVisit.UserUuid != user.Uuid {
panic("没有权限查看该图片缓存")
}
}
return this.Success(securityVisit)
}
//按照分页的方式查询
func (this *SecurityVisitController) Page(writer http.ResponseWriter, request *http.Request) *WebResult {
//如果是根目录那么就传入root.
pageStr := request.FormValue("page")
pageSizeStr := request.FormValue("pageSize")
userUuid := request.FormValue("userUuid")
orderCreateTime := request.FormValue("orderCreateTime")
orderSize := request.FormValue("orderSize")
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR {
userUuid = user.Uuid
}
var page int
if pageStr != "" {
page, _ = strconv.Atoi(pageStr)
}
pageSize := 200
if pageSizeStr != "" {
tmp, err := strconv.Atoi(pageSizeStr)
if err == nil {
pageSize = tmp
}
}
sortArray := []OrderPair{
{
key: "create_time",
value: orderCreateTime,
},
{
key: "size",
value: orderSize,
},
}
pager := this.securityVisitDao.Page(page, pageSize, userUuid, sortArray)
return this.Success(pager)
}
//删除一条记录
func (this *SecurityVisitController) Delete(writer http.ResponseWriter, request *http.Request) *WebResult {
uuid := request.FormValue("uuid")
if uuid == "" {
return this.Error("图片缓存的uuid必填")
}
securityVisit := this.securityVisitDao.FindByUuid(uuid)
//判断图片缓存的所属人是否正确
user := this.checkUser(writer, request)
if user.Role != USER_ROLE_ADMINISTRATOR && securityVisit.UserUuid != user.Uuid {
return this.Error(CODE_WRAPPER_UNAUTHORIZED)
}
this.securityVisitDao.Delete(securityVisit)
return this.Success("删除成功!")
}

View File

@ -0,0 +1,90 @@
package rest
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/nu7hatch/gouuid"
"time"
)
type SecurityVisitDao struct {
BaseDao
}
//按照Id查询文件
func (this *SecurityVisitDao) FindByUuid(uuid string) *SecurityVisit {
// Read
var securityVisit SecurityVisit
db := this.context.DB.Where(&SecurityVisit{Base: Base{Uuid: uuid}}).First(&securityVisit)
if db.Error != nil {
return nil
}
return &securityVisit
}
//按照Id查询文件
func (this *SecurityVisitDao) CheckByUuid(uuid string) *SecurityVisit {
// Read
var securityVisit SecurityVisit
db := this.context.DB.Where(&SecurityVisit{Base: Base{Uuid: uuid}}).First(&securityVisit)
this.PanicError(db.Error)
return &securityVisit
}
//按分页条件获取分页
func (this *SecurityVisitDao) Page(page int, pageSize int, userUuid string, sortArray []OrderPair) *Pager {
var wp = &WherePair{}
if userUuid != "" {
wp = wp.And(&WherePair{Query: "user_uuid = ?", Args: []interface{}{userUuid}})
}
var conditionDB *gorm.DB
conditionDB = this.context.DB.Model(&SecurityVisit{}).Where(wp.Query, wp.Args...)
count := 0
db := conditionDB.Count(&count)
this.PanicError(db.Error)
var securityVisits []*SecurityVisit
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&securityVisits)
this.PanicError(db.Error)
pager := NewPager(page, pageSize, count, securityVisits)
return pager
}
//创建
func (this *SecurityVisitDao) Create(securityVisit *SecurityVisit) *SecurityVisit {
timeUUID, _ := uuid.NewV4()
securityVisit.Uuid = string(timeUUID.String())
securityVisit.CreateTime = time.Now()
securityVisit.UpdateTime = time.Now()
db := this.context.DB.Create(securityVisit)
this.PanicError(db.Error)
return securityVisit
}
//修改一条记录
func (this *SecurityVisitDao) Save(securityVisit *SecurityVisit) *SecurityVisit {
securityVisit.UpdateTime = time.Now()
db := this.context.DB.Save(securityVisit)
this.PanicError(db.Error)
return securityVisit
}
//删除一条记录
func (this *SecurityVisitDao) Delete(securityVisit *SecurityVisit) {
db := this.context.DB.Delete(&securityVisit)
this.PanicError(db.Error)
}

View File

@ -0,0 +1,21 @@
package rest
/**
* 系统的所有访问记录均记录在此
*/
type SecurityVisit struct {
Base
SessionId string `json:"sessionId"`
UserUuid string `json:"userUuid"`
Ip string `json:"ip"`
Host string `json:"host"`
Uri string `json:"uri"`
Params string `json:"params"`
Cost int64 `json:"cost"`
Success bool `json:"success"`
}
// set File's table name to be `profiles`
func (SecurityVisit) TableName() string {
return TABLE_PREFIX + "security_visit"
}

View File

@ -0,0 +1,32 @@
package rest
//@Service
type SecurityVisitService struct {
Bean
securityVisitDao *SecurityVisitDao
userDao *UserDao
}
//初始化方法
func (this *SecurityVisitService) Init(context *Context) {
//手动装填本实例的Bean. 这里必须要用中间变量方可。
b := context.GetBean(this.securityVisitDao)
if b, ok := b.(*SecurityVisitDao); ok {
this.securityVisitDao = b
}
b = context.GetBean(this.userDao)
if b, ok := b.(*UserDao); ok {
this.userDao = b
}
}
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
func (this *SecurityVisitService) Detail(uuid string) *SecurityVisit {
securityVisit := this.securityVisitDao.CheckByUuid(uuid)
return securityVisit
}

View File

@ -24,3 +24,10 @@ func GetIpAddress(r *http.Request) string {
}
return ipAddress
}
//根据一个请求获取host
func GetHostFromRequest(r *http.Request) string {
return r.Host
}