65 Star 398 Fork 128

admpub/nging

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
embedded.go 6.77 KB
一键复制 编辑 原始数据 按行查看 历史
admpub 提交于 2019-10-30 21:58 . update
/*
Nging is a toolbox for webmasters
Copyright (C) 2018-present Wenhui Shen <swh@admpub.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package file
import (
"fmt"
"strings"
"github.com/webx-top/com"
"github.com/webx-top/db"
"github.com/webx-top/echo"
"github.com/webx-top/echo/param"
"github.com/admpub/nging/application/dbschema"
"github.com/admpub/nging/application/library/fileupdater"
"github.com/admpub/nging/application/model/base"
uploadHelper "github.com/admpub/nging/application/registry/upload/helper"
)
func NewEmbedded(ctx echo.Context, fileMdls ...*File) *Embedded {
if ctx == nil {
panic(`ctx is nil`)
}
var fileM *File
if len(fileMdls) > 0 {
fileM = fileMdls[0]
} else {
fileM = NewFile(ctx)
}
m := &Embedded{
FileEmbedded: &dbschema.FileEmbedded{},
base: base.New(ctx),
File: fileM,
}
m.FileEmbedded.SetContext(ctx)
return m
}
type Embedded struct {
*dbschema.FileEmbedded
base *base.Base
File *File
updater *fileupdater.FileUpdater
}
func (f *Embedded) Updater(table string, field string, tableID string) *fileupdater.FileUpdater {
if f.updater == nil {
f.updater = fileupdater.New(f)
}
f.updater.Set(table, field, tableID)
return f.updater
}
func (f *Embedded) FileIDs() []uint64 {
fileIDs := []uint64{}
if len(f.FileIds) == 0 {
return fileIDs
}
for _, fileID := range strings.Split(f.FileIds, `,`) {
fileIDs = append(fileIDs, param.AsUint64(fileID))
}
return fileIDs
}
// DeleteByTableID 删除嵌入文件
func (f *Embedded) DeleteByTableID(project string, table string, tableID string) error {
_, err := f.ListByOffset(nil, nil, 0, -1, db.And(
db.Cond{`table_id`: tableID},
db.Cond{`table_name`: table},
db.Cond{`project`: project},
))
if err != nil {
return err
}
var ids []uint64
for _, row := range f.Objects() {
err = f.File.SetField(nil, `used_times`, db.Raw(`used_times-1`), db.And(
db.Cond{`used_times`: db.Gt(0)},
db.Cond{`id`: db.In(strings.Split(row.FileIds, `,`))},
))
if err != nil {
return err
}
ids = append(ids, row.Id)
}
if len(ids) > 0 {
err = f.Delete(nil, db.Cond{`id`: db.In(ids)})
}
return err
}
func (f *Embedded) UpdateByFileID(project string, table string, field string, tableID string, fileID uint64) error {
err := f.File.UpdateUnrelation(project, table, field, tableID, fileID)
if err != nil {
return err
}
err = f.File.Incr(fileID)
if err != nil {
return err
}
m := &dbschema.FileEmbedded{}
err = m.Get(nil, db.And(
db.Cond{`table_id`: tableID},
db.Cond{`table_name`: table},
db.Cond{`field_name`: field},
))
if err != nil {
if err != db.ErrNoMoreRows {
return err
}
m.Reset()
m.FieldName = field
m.TableName = table
m.Project = project
m.TableId = tableID
m.FileIds = fmt.Sprint(fileID)
_, err = m.Add()
}
return err
}
func (f *Embedded) UpdateEmbedded(embedded bool, project string, table string, field string, tableID string, fileIds ...interface{}) (err error) {
f.base.Begin()
defer func() {
f.base.End(err == nil)
}()
f.Use(f.base.Tx())
f.File.Use(f.Trans())
err = f.File.UpdateUnrelation(project, table, field, tableID, fileIds...)
if err != nil {
return err
}
m := &dbschema.FileEmbedded{}
err = m.Use(f.Trans()).Get(nil, db.And(
db.Cond{`table_id`: tableID},
db.Cond{`table_name`: table},
db.Cond{`field_name`: field},
))
if err != nil {
if err != db.ErrNoMoreRows {
return err
}
if len(fileIds) < 1 {
return nil
}
// 不存在时,添加
m.Reset()
m.FieldName = field
m.TableName = table
m.Project = project
m.TableId = tableID
if embedded {
m.Embedded = `Y`
} else {
m.Embedded = `N`
}
m.FileIds = ""
err = f.File.Incr(fileIds...)
if err != nil {
return err
}
for _, v := range fileIds {
m.FileIds += fmt.Sprintf("%v,", v)
}
m.FileIds = strings.TrimSuffix(m.FileIds, ",")
f.FileIds = m.FileIds // 供FileIDs()使用
_, err = m.Add()
return err
}
isEmpty := len(fileIds) < 1
if isEmpty { // 删除关联记录
return f.DeleteByInstance(m)
}
var fidsString string
fidList := make([]string, len(fileIds))
for k, v := range fileIds {
s := fmt.Sprint(v)
fidList[k] = s
fidsString += s + `,`
}
fidsString = strings.TrimSuffix(fidsString, ",")
if m.FileIds == fidsString {
return nil
}
ids := strings.Split(m.FileIds, ",")
//新增引用
err = f.AddFileByIds(fidList, ids...)
if err != nil {
return err
}
//已删除引用
err = f.DeleteFileByIds(ids, fidList...)
if err != nil {
return err
}
m.FileIds = fidsString
f.FileIds = m.FileIds // 供FileIDs()使用
err = f.SetField(nil, `file_ids`, m.FileIds, db.Cond{`id`: m.Id})
return err
}
// RelationEmbeddedFiles 关联嵌入的文件
// @param project 项目名称
// @param table 表名称
// @param field 被嵌入的字段名
// @param tableID 表中行主键ID
// @param v 内容
// @return
// @author AdamShen <swh@admpub.com>
func (f *Embedded) RelationEmbeddedFiles(project string, table string, field string, tableID string, v string) error {
var (
files []interface{}
fids []interface{} //旧文件ID
)
uploadHelper.EmbeddedRes(v, func(file string, fid int64) {
var exists bool
if fid > 0 {
exists = com.InSliceIface(fid, fids)
} else {
exists = com.InSliceIface(file, files)
}
if exists {
return
}
files = append(files, file)
if fid > 0 {
fids = append(fids, fid)
}
})
if len(fids) < 1 && len(files) > 0 {
fids = f.File.GetIDByViewURLs(files)
}
err := f.UpdateEmbedded(true, project, table, field, tableID, fids...)
return err
}
func (f *Embedded) RelationFiles(project string, table string, field string, tableID string, v string, seperator ...string) error {
var (
files []interface{}
fids []interface{} //旧文件ID
)
//println(`RelationFiles:`, v)
uploadHelper.RelatedRes(v, func(file string, fid int64) {
var exists bool
if fid > 0 {
exists = com.InSliceIface(fid, fids)
} else {
exists = com.InSliceIface(file, files)
}
if exists {
return
}
files = append(files, file)
if fid > 0 {
fids = append(fids, fid)
}
}, seperator...)
if len(fids) < 1 && len(files) > 0 {
fids = f.File.GetIDByViewURLs(files)
}
err := f.UpdateEmbedded(false, project, table, field, tableID, fids...)
return err
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/admpub/nging.git
git@gitee.com:admpub/nging.git
admpub
nging
nging
v2.1.0

搜索帮助