1
0
mirror of https://github.com/fumiama/paper-manager.git synced 2026-06-24 04:27:09 +08:00

implement delfile

This commit is contained in:
源文雨
2023-04-11 16:02:29 +08:00
parent d317aba2d0
commit 27834d7292
9 changed files with 107 additions and 45 deletions

View File

@@ -490,7 +490,7 @@ func (f *FileDatabase) AddFile(lstid int, reg *Regex, istemp bool, progress func
} }
// DelFile by listid // DelFile by listid
func (f *FileDatabase) DelFile(fileid, uid int, istemp bool) error { func (f *FileDatabase) DelFile(lstid, uid int, istemp bool) error {
user, err := UserDB.GetUserByID(uid) user, err := UserDB.GetUserByID(uid)
if err != nil { if err != nil {
return err return err
@@ -498,19 +498,14 @@ func (f *FileDatabase) DelFile(fileid, uid int, istemp bool) error {
if !user.IsSuper() { if !user.IsSuper() {
return ErrInvalidRole return ErrInvalidRole
} }
var file File ftable := ""
f.mu.RLock()
if istemp { if istemp {
file, err = sql.Find[File](&f.db, FileTableTempFile, "WHERE ID="+strconv.Itoa(fileid)) ftable = FileTableTempFile
} else { } else {
file, err = sql.Find[File](&f.db, FileTableFile, "WHERE ID="+strconv.Itoa(fileid)) ftable = FileTableFile
}
f.mu.RUnlock()
if err != nil {
return err
} }
f.mu.RLock() f.mu.RLock()
lst, err := sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(file.ListID)) lst, err := sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(lstid))
f.mu.RUnlock() f.mu.RUnlock()
if err != nil { if err != nil {
return err return err
@@ -518,21 +513,33 @@ func (f *FileDatabase) DelFile(fileid, uid int, istemp bool) error {
if lst.Path == "" || strings.Contains(lst.Path, "..") { if lst.Path == "" || strings.Contains(lst.Path, "..") {
return os.ErrNotExist return os.ErrNotExist
} }
ques := make([]QuestionJSON, 0, 64) i := strings.LastIndex(lst.Path, "/")
err = json.Unmarshal(file.Questions, &ques) if i <= 0 {
if err != nil { return os.ErrNotExist
return err
} }
for _, q := range ques { parentfolder := lst.Path[:i]
q.Delete(f, istemp) if utils.IsNotExist(parentfolder) {
return os.ErrNotExist
} }
if istemp { if !lst.HasntAnalyzed {
err = f.db.Del(FileTableTempFile, "WHERE ID="+strconv.Itoa(fileid)) f.mu.RLock()
} else { file, err := sql.Find[File](&f.db, ftable, "WHERE ListID="+strconv.Itoa(lstid))
err = f.db.Del(FileTableFile, "WHERE ID="+strconv.Itoa(fileid)) f.mu.RUnlock()
if err != nil {
return err
}
err = f.db.Del(ftable, "WHERE ListID="+strconv.Itoa(lstid))
if err != nil {
return err
}
ques := make([]QuestionJSON, 0, 64)
err = json.Unmarshal(file.Questions, &ques)
if err != nil {
return err
}
for _, q := range ques {
q.Delete(f, istemp)
}
} }
if err != nil { return os.RemoveAll(parentfolder)
logrus.Warnln("[global.DelFile] err:", err)
}
} }

View File

@@ -6,7 +6,9 @@ import (
"encoding/json" "encoding/json"
"strconv" "strconv"
sql "github.com/FloatTech/sqlite"
"github.com/corona10/goimagehash" "github.com/corona10/goimagehash"
base14 "github.com/fumiama/go-base16384"
"github.com/fumiama/paper-manager/backend/utils" "github.com/fumiama/paper-manager/backend/utils"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@@ -19,7 +21,7 @@ type QuestionJSON struct {
Sub []QuestionJSON `json:"sub,omitempty"` Sub []QuestionJSON `json:"sub,omitempty"`
} }
// Delete me and all subs // Delete me and all subs, ignore errors
func (q *QuestionJSON) Delete(f *FileDatabase, istemp bool) { func (q *QuestionJSON) Delete(f *FileDatabase, istemp bool) {
if b, err := hex.DecodeString(q.Name); err == nil { if b, err := hex.DecodeString(q.Name); err == nil {
err = f.DelQuestion(int64(binary.LittleEndian.Uint64(b)), istemp) err = f.DelQuestion(int64(binary.LittleEndian.Uint64(b)), istemp)
@@ -32,14 +34,49 @@ func (q *QuestionJSON) Delete(f *FileDatabase, istemp bool) {
} }
} }
// DelQuestion 删除问题, 其它问题的 dup 可能会残留有 id, 使用时需要排除 // DelQuestion 删除问题, 其它问题的 dup
func (f *FileDatabase) DelQuestion(id int64, istemp bool) error { func (f *FileDatabase) DelQuestion(id int64, istemp bool) error {
qtable := ""
if istemp {
qtable = FileTableTempQuestion
} else {
qtable = FileTableQuestion
}
f.mu.Lock() f.mu.Lock()
defer f.mu.Unlock() defer f.mu.Unlock()
if istemp { q, err := sql.Find[Question](&f.db, qtable, "WHERE ID="+strconv.FormatInt(id, 10))
return f.db.Del(FileTableTempQuestion, "WHERE ID="+strconv.FormatInt(id, 10)) if err != nil {
return err
} }
return f.db.Del(FileTableQuestion, "WHERE ID="+strconv.FormatInt(id, 10)) if len(q.Dup) > 2 {
dupmap := make(map[string]float64, 64)
err = json.Unmarshal(q.Dup, &dupmap)
if err == nil {
var buf [8]byte
for k := range dupmap {
_, err = hex.Decode(buf[:], base14.StringToBytes(k))
if err == nil {
qid := int64(binary.LittleEndian.Uint64(buf[:]))
qq, err := sql.Find[Question](&f.db, qtable, "WHERE ID="+strconv.FormatInt(qid, 10))
if err == nil && len(qq.Dup) > 2 {
dupmap2 := make(map[string]float64, 64)
err = json.Unmarshal(qq.Dup, &dupmap2)
if err == nil {
delete(dupmap2, k)
qq.Dup, err = json.Marshal(dupmap2)
if err == nil {
err = f.db.Insert(qtable, &qq)
if err != nil {
logrus.Warnln("[global.DelQuestion] insert modified dup to id", k, "table", qtable, "err:", err)
}
}
}
}
}
}
}
}
return f.db.Del(qtable, "WHERE ID="+strconv.FormatInt(id, 10))
} }
type Question struct { type Question struct {

View File

@@ -23,6 +23,7 @@ var analyzeper = ttl.NewCache[int, uint](time.Hour)
var ( var (
errNoAnalyzePermission = errors.New("no analyze permission") errNoAnalyzePermission = errors.New("no analyze permission")
errNoDeletePermission = errors.New("no delete permission")
) )
type filelist struct { type filelist struct {
@@ -200,6 +201,34 @@ func init() {
writeresult(w, codeSuccess, &message{C: 0, M: "分析完成"}, messageOk, typeSuccess) writeresult(w, codeSuccess, &message{C: 0, M: "分析完成"}, messageOk, typeSuccess)
} }
}} }}
apimap["/api/delFile"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
user := usertokens.Get(token)
if user == nil {
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
return
}
if !user.IsSuper() {
writeresult(w, codeError, nil, errNoDeletePermission.Error(), typeError)
return
}
idstr := r.URL.Query().Get("id")
if idstr == "" {
writeresult(w, codeError, nil, "empty id", typeError)
return
}
id, err := strconv.Atoi(idstr)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
err = global.FileDB.DelFile(id, *user.ID, false)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
writeresult(w, codeSuccess, "删除成功", messageOk, typeSuccess)
}}
} }
// PaperHandler serves protected contents in global.FileFolder // PaperHandler serves protected contents in global.FileFolder

View File

@@ -70,7 +70,7 @@ export default [
}) })
}, },
},*/ },*/
{ /*{
url: '/api/delFile', url: '/api/delFile',
timeout: 200, timeout: 200,
method: 'get', method: 'get',
@@ -84,7 +84,7 @@ export default [
msg: '已成功删除文件' + id + '.', msg: '已成功删除文件' + id + '.',
}) })
}, },
}, },*/
/*{ /*{
url: '/api/analyzeFile', url: '/api/analyzeFile',
timeout: 1000, timeout: 1000,

View File

@@ -29,7 +29,6 @@
"test:gzip": "npx http-server dist --cors --gzip -c-1", "test:gzip": "npx http-server dist --cors --gzip -c-1",
"test:br": "npx http-server dist --cors --brotli -c-1", "test:br": "npx http-server dist --cors --brotli -c-1",
"reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && pnpm run bootstrap", "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && pnpm run bootstrap",
"prepare": "husky install",
"gen:icon": "esno ./build/generate/icon/index.ts" "gen:icon": "esno ./build/generate/icon/index.ts"
}, },
"dependencies": { "dependencies": {
@@ -108,7 +107,6 @@
"eslint-plugin-vue": "^8.6.0", "eslint-plugin-vue": "^8.6.0",
"esno": "^0.14.1", "esno": "^0.14.1",
"fs-extra": "^10.1.0", "fs-extra": "^10.1.0",
"husky": "^7.0.4",
"inquirer": "^8.2.2", "inquirer": "^8.2.2",
"less": "^4.1.2", "less": "^4.1.2",
"lint-staged": "12.3.7", "lint-staged": "12.3.7",

View File

@@ -1,5 +1,5 @@
import { defHttp } from '/@/utils/http/axios' import { defHttp } from '/@/utils/http/axios'
import { getFileListModel, DelFile, AnalyzeFile, FileListGroupItem } from './model/fileListModel' import { getFileListModel, AnalyzeFile, FileListGroupItem } from './model/fileListModel'
import { DownloadFile, FileStatus } from './model/fileModel' import { DownloadFile, FileStatus } from './model/fileModel'
enum Api { enum Api {
@@ -37,7 +37,7 @@ export const getFilePercent = (id: number) => {
* @description: Get file percent * @description: Get file percent
*/ */
export const delFile = (id: number) => { export const delFile = (id: number) => {
return defHttp.get<DelFile>({ url: Api.DelFile, params: { id: id } }) return defHttp.get<string>({ url: Api.DelFile, params: { id: id } })
} }
/** /**

View File

@@ -14,10 +14,6 @@ export interface FileListGroupItem {
*/ */
export type getFileListModel = FileListGroupItem[] export type getFileListModel = FileListGroupItem[]
export interface DelFile {
msg: string
}
export interface AnalyzeFile { export interface AnalyzeFile {
code: number code: number
msg: string msg: string

View File

@@ -130,7 +130,7 @@
item.delloading = true item.delloading = true
const msg = await delFile(item.id) const msg = await delFile(item.id)
if (msg) { if (msg) {
createMessage.success(msg.msg) createMessage.success(msg)
setTimeout(() => { setTimeout(() => {
deleteFileByID(item.id) deleteFileByID(item.id)
}, 1000) }, 1000)

View File

@@ -5174,11 +5174,6 @@
"resolved" "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz" "resolved" "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz"
"version" "2.1.0" "version" "2.1.0"
"husky@^7.0.4":
"integrity" "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ=="
"resolved" "https://registry.npmmirror.com/husky/-/husky-7.0.4.tgz"
"version" "7.0.4"
"iconv-lite@^0.4.24": "iconv-lite@^0.4.24":
"integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="
"resolved" "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz" "resolved" "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz"