2 Star 0 Fork 0

TeamsHub/backend-gopkg

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
teamsFile.go 14.19 KB
一键复制 编辑 原始数据 按行查看 历史
HCY 提交于 2024-05-10 13:07 . edit pkg
package model
import (
"errors"
"fmt"
"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/cache"
"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/hashid"
"gitee.com/wuzheng0709/backend-gopkg/infrastructure/pkg/util"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"math"
"strings"
"time"
)
// ItemService 处理多文件/目录相关服务
type FolderItem struct {
Folder Folder `json:"folder"`
Dir uint `json:"dir"`
}
// Share 分享模型
type TeamsFolderMember struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
Password string // 分享密码,空值为非加密分享
IsDir bool // 原始资源是否为目录
UserID uint // 创建用户ID
SourceID uint // 原始资源ID
Views int // 浏览数
Downloads int // 下载数
RemainDownloads int // 剩余下载配额,负值标识无限制
Expires *time.Time // 过期时间,空值表示无过期时间
Score int // 每人次下载扣除积分
GroupRole int // 角色
PreviewEnabled bool // 是否允许直接预览
SourceName string `gorm:"index:source"` // 用于搜索的字段
DownloadEnabled bool // 是否允许直接下载
UploadEnabled bool // 是否允许直接上传
EditEnabled bool // 是否允许直接编辑
ManaEnabled bool // 是否允许直接管理
IsRoot bool // 是否根节点
// 数据库忽略字段
User User `gorm:"PRELOAD:false,association_autoupdate:false"`
File File `gorm:"PRELOAD:false,association_autoupdate:false"`
Folder Folder `gorm:"PRELOAD:false,association_autoupdate:false"`
}
// Create 创建分享
func (share *TeamsFolderMember) Create() (uint, error) {
if err := DB.Create(share).Error; err != nil {
util.Log().Warning("无法插入数据库记录, %s", err)
return 0, err
}
return share.ID, nil
}
func GetUserTeamsRootFolder(userId uint) (sourceIds []uint) {
DB.Model(TeamsFolderMember{}).Where("user_id = ? and is_root = 1 ", userId).Pluck("source_id", &sourceIds)
return sourceIds
}
func GetUserTeamsFolder(userId uint, sourceId uint) (source TeamsFolderMember) {
DB.Model(TeamsFolderMember{}).Where("user_id = ? and source_id = ? ", userId, sourceId).First(&source)
return source
}
// ListShares 列出UID下的分享
func ListTeamsShare(uid uint, publicOnly bool) ([]TeamsFolderMember, error) {
var (
shares []TeamsFolderMember
)
dbChain := DB
dbChain = dbChain.Where("user_id = ? and is_root= 1", uid)
if publicOnly {
dbChain = dbChain.Where("password = ?", "")
}
// 计算总数用于分页
//dbChain.Model(&Share{}).Count(&total)
// 查询记录
dbChain.Find(&shares)
return shares, nil
}
func ListTeamsGroupFolder(folder_id uint, key string) ([]TeamsFolderMember, error) {
var (
shares []TeamsFolderMember
)
dbChain := DB
dbChain = dbChain.Where("source_id = ?", folder_id)
// 计算总数用于分页
//dbChain.Model(&Share{}).Count(&total)
// 查询记录
dbChain.Find(&shares)
userIDs := make([]uint, 0, len(shares))
for _, v := range shares {
userIDs = append(userIDs, v.UserID)
}
var userList []User
DB.Where("id in (?) and nick like ?", userIDs, "%"+key+"%").Find(&userList)
for _, v := range userList {
for i := 0; i < len(shares); i++ {
if shares[i].UserID == v.ID {
shares[i].User = v
}
}
}
return shares, nil
}
// GetShareByHashID 根据HashID查找分享
func GetTeamsFolderByHashID(hashID string) *TeamsFolderMember {
id, err := hashid.DecodeHashID(hashID, hashid.ShareID)
util.Log().Warning("hash解密, %s%s", hashID, id)
if err != nil {
return nil
}
var share TeamsFolderMember
result := DB.First(&share, id)
if result.Error != nil {
return nil
}
return &share
}
// IsAvailable 返回此分享是否可用(是否过期)
func (share *TeamsFolderMember) IsAvailable() bool {
if share.RemainDownloads == 0 {
return false
}
if share.Expires != nil && time.Now().After(*share.Expires) {
return false
}
// 检查创建者状态
if share.Creator().Status != Active {
return false
}
// 检查源对象是否存在
var sourceID uint
if share.IsDir {
folder := share.SourceFolder()
sourceID = folder.ID
} else {
file := share.SourceFile()
sourceID = file.ID
}
if sourceID == 0 {
// TODO 是否要在这里删除这个无效分享?
return false
}
return true
}
// Creator 获取分享的创建者
func (share *TeamsFolderMember) Creator() *User {
if share.User.ID == 0 {
share.User, _ = GetUserByID(share.UserID)
}
return &share.User
}
// Source 返回源对象
func (share *TeamsFolderMember) Source() interface{} {
if share.IsDir {
return share.SourceFolder()
}
return share.SourceFile()
}
// SourceFolder 获取源目录
func (share *TeamsFolderMember) SourceFolder() *Folder {
if share.Folder.ID == 0 {
folders, _ := GetFoldersByIDs([]uint{share.SourceID}, share.UserID)
if len(folders) > 0 {
share.Folder = folders[0]
}
}
return &share.Folder
}
// Source 返回源对象
// SourceFile 获取源文件
func (share *TeamsFolderMember) SourceFile() *File {
if share.File.ID == 0 {
files, _ := GetFilesByIDs([]uint{share.SourceID}, share.UserID)
if len(files) > 0 {
share.File = files[0]
}
}
return &share.File
}
// CanBeDownloadBy 返回此分享是否可以被给定用户下载
func (share *TeamsFolderMember) CanBeDownloadBy(user *User) error {
// 用户组权限
if !user.Group.OptionsSerialized.ShareDownload {
if user.IsAnonymous() {
return errors.New("未登录用户无法下载")
}
return errors.New("您当前的用户组无权下载")
}
// 需要积分但未登录
if share.Score > 0 && user.IsAnonymous() {
return errors.New("未登录用户无法下载")
}
return nil
}
// WasDownloadedBy 返回分享是否已被用户下载过
func (share *TeamsFolderMember) WasDownloadedBy(user *User, c *gin.Context) (exist bool) {
if user.IsAnonymous() {
exist = util.GetSession(c, fmt.Sprintf("share_%d_%d", share.ID, user.ID)) != nil
} else {
_, exist = cache.Get(fmt.Sprintf("share_%d_%d", share.ID, user.ID))
}
return exist
}
// DownloadBy 增加下载次数、检查积分等,匿名用户不会缓存
func (share *TeamsFolderMember) DownloadBy(user *User, c *gin.Context) error {
if !share.WasDownloadedBy(user, c) {
if err := share.Purchase(user); err != nil {
return err
}
share.Downloaded()
if !user.IsAnonymous() {
cache.Set(fmt.Sprintf("share_%d_%d", share.ID, user.ID), true,
GetIntSetting("share_download_session_timeout", 2073600))
} else {
util.SetSession(c, map[string]interface{}{fmt.Sprintf("share_%d_%d", share.ID, user.ID): true})
}
}
return nil
}
// Purchase 使用积分购买分享
func (share *TeamsFolderMember) Purchase(user *User) error {
// 不需要付积分
if share.Score == 0 || user.Group.OptionsSerialized.ShareFree || user.ID == share.UserID {
return nil
}
ok := user.PayScore(share.Score)
if !ok {
return errors.New("积分不足")
}
scoreRate := GetIntSetting("share_score_rate", 100)
gainedScore := int(math.Ceil(float64(share.Score*scoreRate) / 100))
share.Creator().AddScore(gainedScore)
return nil
}
// Viewed 增加访问次数
func (share *TeamsFolderMember) Viewed() {
share.Views++
DB.Model(share).UpdateColumn("views", gorm.Expr("views + ?", 1))
}
// Downloaded 增加下载次数
func (share *TeamsFolderMember) Downloaded() {
share.Downloads++
if share.RemainDownloads > 0 {
share.RemainDownloads--
}
DB.Model(share).Updates(map[string]interface{}{
"downloads": share.Downloads,
"remain_downloads": share.RemainDownloads,
})
}
// Update 更新分享属性
func (share *TeamsFolderMember) Update(props map[string]interface{}) error {
return DB.Model(share).Updates(props).Error
}
// Delete 删除分享
func (share *TeamsFolderMember) Delete() error {
return DB.Model(share).Delete(share).Error
}
// DeleteShareBySourceIDs 根据原始资源类型和ID删除文件
func DeleteTeamsFoloderBySourceIDs(sources []uint, isDir bool) error {
return DB.Where("source_id in (?) and is_dir = ?", sources, isDir).Delete(&TeamsFolderMember{}).Error
}
func TransferTeamsFoldersToUsers(dirs []uint, folderIteams []FolderItem, UserItems []TeamsFolderMember) (err error) {
DB.Where("source_id in (?)", dirs).Delete(&TeamsFolderMember{})
for i := 0; i < len(UserItems); i++ {
for j := 0; j < len(folderIteams); j++ {
UserItems[i].SourceID = folderIteams[j].Dir
UserItems[i].SourceName = folderIteams[j].Folder.Name
UserItems[i].IsDir = true
UserItems[i] = GetFolderMemberPermissionByGroupRole(UserItems[i])
var sourceMembers []TeamsFolderMember
UserItems[i].IsRoot = UserTeamsFolderIsRoot(sourceMembers, UserItems[i])
DB.Model(TeamsFolderMember{}).Create(&UserItems[i])
}
}
return nil
}
func UserTeamsFolderIsRoot(sourceMembers []TeamsFolderMember, sourceFolder TeamsFolderMember) (IsRoot bool) {
// 最多5000层
var sourceId = sourceFolder.SourceID
var userId = sourceFolder.UserID
for i := 0; i < 5000; i++ {
folder := GetChildFolderById(sourceId)
if folder.ID == 0 {
break
}
var member TeamsFolderMember
DB.Model(TeamsFolderMember{}).Where("source_id = ? and user_id = ? and is_root = 1 ", folder.ID, userId).First(&member)
if member.ID > 0 {
//修改当前IsRoot
DB.Model(TeamsFolderMember{}).Where("id = ?", member.ID).UpdateColumn("is_root", 0)
return true
} else {
member.SourceID = folder.ID
member.SourceName = folder.Name
member.IsDir = true
member.UserID = userId
member.GroupRole = sourceFolder.GroupRole
member = GetFolderMemberPermissionByGroupRole(member)
member.IsRoot = false
DB.Model(TeamsFolderMember{}).Create(&member)
sourceId = folder.ID
}
}
for i := 0; i < 5000; i++ {
folder := GetFolderById(sourceId)
if folder.ID == 0 {
break
}
var member TeamsFolderMember
DB.Model(TeamsFolderMember{}).Where("source_id = ? and user_id = ? and is_root = 1 ", folder.ParentID, userId).First(&member)
if member.ID > 0 {
return false
} else {
if folder.ParentID != nil {
sourceId = *folder.ParentID
} else {
break
}
}
}
return true
}
func CopyTeamsMemberToFolderId(folder Folder, parentTeamsMembers []TeamsFolderMember) {
for i := 0; i < len(parentTeamsMembers); i++ {
parentTeamsMembers[i].ID = 0
parentTeamsMembers[i].SourceID = folder.ID
parentTeamsMembers[i].SourceName = folder.Name
var sourceMembers []TeamsFolderMember
parentTeamsMembers[i].IsRoot = UserTeamsFolderIsRoot(sourceMembers, parentTeamsMembers[i])
DB.Model(TeamsFolderMember{}).Create(&parentTeamsMembers[i])
}
return
}
func GetUserFolderMember(user_id uint, source_id uint) (member TeamsFolderMember) {
DB.Where("source_id = ? and user_id = ?", source_id, user_id).First(&member)
return member
}
func GetTeamsFolderMembers(source_id uint) (members []TeamsFolderMember) {
DB.Where("source_id = ? ", source_id).Find(&members)
return members
}
func GetFolderMemberPermissionByGroupRole(UserItem TeamsFolderMember) TeamsFolderMember {
if UserItem.GroupRole == 1 { //创建人
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = true
UserItem.DownloadEnabled = true
UserItem.PreviewEnabled = true
UserItem.EditEnabled = true
UserItem.ManaEnabled = true
} else if UserItem.GroupRole == 2 { //可管理
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = true
UserItem.DownloadEnabled = true
UserItem.PreviewEnabled = true
UserItem.EditEnabled = true
UserItem.ManaEnabled = true
} else if UserItem.GroupRole == 3 { //可编辑
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = true
UserItem.DownloadEnabled = true
UserItem.PreviewEnabled = true
UserItem.EditEnabled = true
UserItem.ManaEnabled = false
} else if UserItem.GroupRole == 4 { //可上传、下载
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = true
UserItem.DownloadEnabled = true
UserItem.PreviewEnabled = true
UserItem.EditEnabled = false
UserItem.ManaEnabled = false
} else if UserItem.GroupRole == 5 { // 仅下载
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = false
UserItem.DownloadEnabled = true
UserItem.PreviewEnabled = true
UserItem.EditEnabled = false
UserItem.ManaEnabled = false
} else if UserItem.GroupRole == 6 { // 仅上传
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = true
UserItem.DownloadEnabled = false
UserItem.PreviewEnabled = false
UserItem.EditEnabled = false
UserItem.ManaEnabled = false
} else if UserItem.GroupRole == 7 { //仅预览
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = false
UserItem.DownloadEnabled = false
UserItem.PreviewEnabled = true
UserItem.EditEnabled = false
UserItem.ManaEnabled = false
} else {
UserItem.RemainDownloads = -1
UserItem.UploadEnabled = false
UserItem.DownloadEnabled = false
UserItem.PreviewEnabled = false
UserItem.EditEnabled = false
UserItem.ManaEnabled = false
}
return UserItem
}
// ListShares 列出UID下的分享
func ListTeamsFolders(uid uint, page, pageSize int, order string, publicOnly bool) ([]TeamsFolderMember, int) {
var (
shares []TeamsFolderMember
total int
)
dbChain := DB
dbChain = dbChain.Where("user_id = ?", uid)
if publicOnly {
dbChain = dbChain.Where("password = ?", "")
}
// 计算总数用于分页
dbChain.Model(&Share{}).Count(&total)
// 查询记录
dbChain.Limit(pageSize).Offset((page - 1) * pageSize).Order(order).Find(&shares)
return shares, total
}
// SearchShares 根据关键字搜索分享
func SearchTeamsFolders(page, pageSize int, order, keywords string) ([]TeamsFolderMember, int) {
var (
shares []TeamsFolderMember
total int
)
keywordList := strings.Split(keywords, " ")
availableList := make([]string, 0, len(keywordList))
for i := 0; i < len(keywordList); i++ {
if len(keywordList[i]) > 0 {
availableList = append(availableList, keywordList[i])
}
}
if len(availableList) == 0 {
return shares, 0
}
dbChain := DB
dbChain = dbChain.Where("password = ? and remain_downloads <> 0 and (expires is NULL or expires > ?) and source_name like ?", "", time.Now(), "%"+strings.Join(availableList, "%")+"%")
// 计算总数用于分页
dbChain.Model(&TeamsFolderMember{}).Count(&total)
// 查询记录
dbChain.Limit(pageSize).Offset((page - 1) * pageSize).Order(order).Find(&shares)
return shares, total
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wuzheng0709/backend-gopkg.git
git@gitee.com:wuzheng0709/backend-gopkg.git
wuzheng0709
backend-gopkg
backend-gopkg
v1.5.9

搜索帮助