9 changed files with 470 additions and 4 deletions
@ -0,0 +1,112 @@ |
|||||
|
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, |
||||
|
`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='下载的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, |
||||
|
`uri` 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, |
||||
|
`modify_time` timestamp NULL DEFAULT NULL, |
||||
|
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
||||
|
PRIMARY KEY (`uuid`), |
||||
|
UNIQUE KEY `id_UNIQUE` (`uuid`), |
||||
|
UNIQUE KEY `uri_UNIQUE` (`uri`) |
||||
|
) 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, |
||||
|
`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='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, |
||||
|
`footer_line1` varchar(1024) DEFAULT NULL, |
||||
|
`footer_line2` varchar(1024) DEFAULT NULL, |
||||
|
`version` varchar(45) DEFAULT NULL, |
||||
|
`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='网站偏好设置表'; |
||||
|
|
||||
|
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, |
||||
|
`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='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', |
||||
|
`expire_time` timestamp NULL DEFAULT NULL, |
||||
|
`ip` varchar(45) DEFAULT NULL COMMENT '消费者的ip', |
||||
|
`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='上传的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, |
||||
|
`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='用户表描述'; |
||||
@ -0,0 +1,158 @@ |
|||||
|
package rest |
||||
|
|
||||
|
import ( |
||||
|
"net/http" |
||||
|
"strconv" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
type ImageCacheController struct { |
||||
|
BaseController |
||||
|
imageCacheDao *ImageCacheDao |
||||
|
imageCacheService *ImageCacheService |
||||
|
} |
||||
|
|
||||
|
//初始化方法
|
||||
|
func (this *ImageCacheController) Init(context *Context) { |
||||
|
this.BaseController.Init(context) |
||||
|
|
||||
|
//手动装填本实例的Bean. 这里必须要用中间变量方可。
|
||||
|
b := context.GetBean(this.imageCacheDao) |
||||
|
if b, ok := b.(*ImageCacheDao); ok { |
||||
|
this.imageCacheDao = b |
||||
|
} |
||||
|
|
||||
|
b = context.GetBean(this.imageCacheService) |
||||
|
if b, ok := b.(*ImageCacheService); ok { |
||||
|
this.imageCacheService = b |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//注册自己的路由。
|
||||
|
func (this *ImageCacheController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) { |
||||
|
|
||||
|
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request)) |
||||
|
|
||||
|
//每个Controller需要主动注册自己的路由。
|
||||
|
routeMap["/api/image/cache/delete"] = this.Wrap(this.Delete, USER_ROLE_USER) |
||||
|
routeMap["/api/image/cache/delete/batch"] = this.Wrap(this.DeleteBatch, USER_ROLE_USER) |
||||
|
routeMap["/api/image/cache/detail"] = this.Wrap(this.Detail, USER_ROLE_USER) |
||||
|
routeMap["/api/image/cache/page"] = this.Wrap(this.Page, USER_ROLE_USER) |
||||
|
|
||||
|
return routeMap |
||||
|
} |
||||
|
|
||||
|
//查看某个文件的详情。
|
||||
|
func (this *ImageCacheController) Detail(writer http.ResponseWriter, request *http.Request) *WebResult { |
||||
|
|
||||
|
uuid := request.FormValue("uuid") |
||||
|
if uuid == "" { |
||||
|
return this.Error("文件的uuid必填") |
||||
|
} |
||||
|
|
||||
|
imageCache := this.imageCacheService.Detail(uuid) |
||||
|
|
||||
|
//验证当前之人是否有权限查看这么详细。
|
||||
|
user := this.checkUser(writer, request) |
||||
|
if user.Role != USER_ROLE_ADMINISTRATOR { |
||||
|
if imageCache.UserUuid != user.Uuid { |
||||
|
panic("没有权限查看该文件") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return this.Success(imageCache) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//按照分页的方式获取某个文件夹下文件和子文件夹的列表,通常情况下只有一页。
|
||||
|
func (this *ImageCacheController) 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.imageCacheDao.Page(page, pageSize, userUuid, sortArray) |
||||
|
|
||||
|
return this.Success(pager) |
||||
|
} |
||||
|
|
||||
|
//删除一个文件
|
||||
|
func (this *ImageCacheController) Delete(writer http.ResponseWriter, request *http.Request) *WebResult { |
||||
|
|
||||
|
uuid := request.FormValue("uuid") |
||||
|
if uuid == "" { |
||||
|
return this.Error("文件的uuid必填") |
||||
|
} |
||||
|
|
||||
|
imageCache := this.imageCacheDao.FindByUuid(uuid) |
||||
|
|
||||
|
//判断文件的所属人是否正确
|
||||
|
user := this.checkUser(writer, request) |
||||
|
if user.Role != USER_ROLE_ADMINISTRATOR && imageCache.UserUuid != user.Uuid { |
||||
|
return this.Error(RESULT_CODE_UNAUTHORIZED) |
||||
|
} |
||||
|
|
||||
|
this.imageCacheDao.Delete(imageCache) |
||||
|
|
||||
|
return this.Success("删除成功!") |
||||
|
} |
||||
|
|
||||
|
//删除一系列文件。
|
||||
|
func (this *ImageCacheController) DeleteBatch(writer http.ResponseWriter, request *http.Request) *WebResult { |
||||
|
|
||||
|
uuids := request.FormValue("uuids") |
||||
|
if uuids == "" { |
||||
|
return this.Error("文件的uuids必填") |
||||
|
} |
||||
|
|
||||
|
uuidArray := strings.Split(uuids, ",") |
||||
|
|
||||
|
for _, uuid := range uuidArray { |
||||
|
|
||||
|
imageCache := this.imageCacheDao.FindByUuid(uuid) |
||||
|
|
||||
|
//判断文件的所属人是否正确
|
||||
|
user := this.checkUser(writer, request) |
||||
|
if user.Role != USER_ROLE_ADMINISTRATOR && imageCache.UserUuid != user.Uuid { |
||||
|
return this.Error(RESULT_CODE_UNAUTHORIZED) |
||||
|
} |
||||
|
|
||||
|
this.imageCacheDao.Delete(imageCache) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return this.Success("删除成功!") |
||||
|
} |
||||
@ -0,0 +1,142 @@ |
|||||
|
package rest |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"github.com/jinzhu/gorm" |
||||
|
_ "github.com/jinzhu/gorm/dialects/mysql" |
||||
|
"github.com/nu7hatch/gouuid" |
||||
|
"os" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
type ImageCacheDao struct { |
||||
|
BaseDao |
||||
|
} |
||||
|
|
||||
|
//按照Id查询文件
|
||||
|
func (this *ImageCacheDao) FindByUuid(uuid string) *ImageCache { |
||||
|
|
||||
|
// Read
|
||||
|
var imageCache ImageCache |
||||
|
db := this.context.DB.Where(&ImageCache{Base: Base{Uuid: uuid}}).First(&imageCache) |
||||
|
if db.Error != nil { |
||||
|
return nil |
||||
|
} |
||||
|
return &imageCache |
||||
|
} |
||||
|
|
||||
|
//按照Id查询文件
|
||||
|
func (this *ImageCacheDao) CheckByUuid(uuid string) *ImageCache { |
||||
|
|
||||
|
// Read
|
||||
|
var imageCache ImageCache |
||||
|
db := this.context.DB.Where(&ImageCache{Base: Base{Uuid: uuid}}).First(&imageCache) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
return &imageCache |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//按照名字查询文件夹
|
||||
|
func (this *ImageCacheDao) FindByUri(uri string) *ImageCache { |
||||
|
|
||||
|
var wp = &WherePair{} |
||||
|
|
||||
|
wp = wp.And(&WherePair{Query: "uri = ?", Args: []interface{}{uri}}) |
||||
|
|
||||
|
var imageCache = &ImageCache{} |
||||
|
db := this.context.DB.Model(&ImageCache{}).Where(wp.Query, wp.Args...).First(imageCache) |
||||
|
|
||||
|
if db.Error != nil { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
return imageCache |
||||
|
} |
||||
|
|
||||
|
//按照id和userUuid来查找。找不到抛异常。
|
||||
|
func (this *ImageCacheDao) CheckByUuidAndUserUuid(uuid string, userUuid string) *ImageCache { |
||||
|
|
||||
|
// Read
|
||||
|
var imageCache = &ImageCache{} |
||||
|
db := this.context.DB.Where(&ImageCache{Base: Base{Uuid: uuid}, UserUuid: userUuid}).First(imageCache) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
return imageCache |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//获取某个用户的某个文件夹下的某个名字的文件(或文件夹)列表
|
||||
|
func (this *ImageCacheDao) ListByUserUuidAndPuuidAndDirAndName(userUuid string) []*ImageCache { |
||||
|
|
||||
|
var imageCaches []*ImageCache |
||||
|
|
||||
|
db := this.context.DB. |
||||
|
Where(ImageCache{UserUuid: userUuid}). |
||||
|
Find(&imageCaches) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
return imageCaches |
||||
|
} |
||||
|
|
||||
|
//获取某个文件夹下所有的文件和子文件
|
||||
|
func (this *ImageCacheDao) 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(&ImageCache{}).Where(wp.Query, wp.Args...) |
||||
|
|
||||
|
count := 0 |
||||
|
db := conditionDB.Count(&count) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
var imageCaches []*ImageCache |
||||
|
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&imageCaches) |
||||
|
this.PanicError(db.Error) |
||||
|
pager := NewPager(page, pageSize, count, imageCaches) |
||||
|
|
||||
|
return pager |
||||
|
} |
||||
|
|
||||
|
//创建
|
||||
|
func (this *ImageCacheDao) Create(imageCache *ImageCache) *ImageCache { |
||||
|
|
||||
|
timeUUID, _ := uuid.NewV4() |
||||
|
imageCache.Uuid = string(timeUUID.String()) |
||||
|
imageCache.CreateTime = time.Now() |
||||
|
imageCache.ModifyTime = time.Now() |
||||
|
db := this.context.DB.Create(imageCache) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
return imageCache |
||||
|
} |
||||
|
|
||||
|
//修改一个文件
|
||||
|
func (this *ImageCacheDao) Save(imageCache *ImageCache) *ImageCache { |
||||
|
|
||||
|
imageCache.ModifyTime = time.Now() |
||||
|
db := this.context.DB.Save(imageCache) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
return imageCache |
||||
|
} |
||||
|
|
||||
|
//删除一个文件,数据库中删除,物理磁盘上删除。
|
||||
|
func (this *ImageCacheDao) Delete(imageCache *ImageCache) { |
||||
|
|
||||
|
db := this.context.DB.Delete(&imageCache) |
||||
|
this.PanicError(db.Error) |
||||
|
|
||||
|
//删除文件
|
||||
|
err := os.Remove(CONFIG.MatterPath + imageCache.Path) |
||||
|
|
||||
|
if err != nil { |
||||
|
LogError(fmt.Sprintf("删除磁盘上的文件出错,不做任何处理")) |
||||
|
//this.PanicError(err)
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package rest |
||||
|
|
||||
|
/** |
||||
|
* 图片缓存,对于那些处理过的图片,统一管理在这里。 |
||||
|
*/ |
||||
|
type ImageCache struct { |
||||
|
Base |
||||
|
UserUuid string `json:"userUuid"` |
||||
|
MatterUuid string `json:"matterUuid"` |
||||
|
Uri string `json:"name"` |
||||
|
Md5 string `json:"md5"` |
||||
|
Size int64 `json:"size"` |
||||
|
Path string `json:"path"` |
||||
|
Matter *Matter `gorm:"-" json:"matter"` |
||||
|
} |
||||
|
|
||||
|
// set File's table name to be `profiles`
|
||||
|
func (ImageCache) TableName() string { |
||||
|
return TABLE_PREFIX + "image_cache" |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
package rest |
||||
|
|
||||
|
//@Service
|
||||
|
type ImageCacheService struct { |
||||
|
Bean |
||||
|
imageCacheDao *ImageCacheDao |
||||
|
} |
||||
|
|
||||
|
//初始化方法
|
||||
|
func (this *ImageCacheService) Init(context *Context) { |
||||
|
|
||||
|
//手动装填本实例的Bean. 这里必须要用中间变量方可。
|
||||
|
b := context.GetBean(this.imageCacheDao) |
||||
|
if b, ok := b.(*ImageCacheDao); ok { |
||||
|
this.imageCacheDao = b |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
|
||||
|
func (this *ImageCacheService) Detail(uuid string) *ImageCache { |
||||
|
|
||||
|
imageCache := this.imageCacheDao.CheckByUuid(uuid) |
||||
|
|
||||
|
return imageCache |
||||
|
} |
||||
Loading…
Reference in new issue