mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-12 04:00:23 +08:00
finish 试卷查重
This commit is contained in:
@@ -497,7 +497,7 @@ func (f *FileDatabase) DelFile(lstid, uid int, istemp bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !user.IsSuper() {
|
if !user.IsSuper() && !istemp {
|
||||||
return ErrInvalidRole
|
return ErrInvalidRole
|
||||||
}
|
}
|
||||||
ftable := ""
|
ftable := ""
|
||||||
@@ -512,6 +512,9 @@ func (f *FileDatabase) DelFile(lstid, uid int, istemp bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if istemp && lst.Uploader != uid {
|
||||||
|
return ErrInvalidRole
|
||||||
|
}
|
||||||
if lst.Path == "" || strings.Contains(lst.Path, "..") {
|
if lst.Path == "" || strings.Contains(lst.Path, "..") {
|
||||||
return os.ErrNotExist
|
return os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,14 +83,20 @@ func (f *FileDatabase) SaveFileToTemp(uploader int, file io.Reader, name string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListUploadedFile will select all file that HasntAnalyzed && IsTemp or !HasntAnalyzed && !IsTemp
|
// ListUploadedFile will select all file that HasntAnalyzed && IsTemp or !HasntAnalyzed && !IsTemp
|
||||||
func (f *FileDatabase) ListUploadedFile() (lst []*List, err error) {
|
func (f *FileDatabase) ListUploadedFile(istemp bool) (lst []*List, err error) {
|
||||||
|
q := ""
|
||||||
|
if istemp {
|
||||||
|
q = "WHERE IsTemp ORDER BY UpTime DESC"
|
||||||
|
} else {
|
||||||
|
q = "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC"
|
||||||
|
}
|
||||||
f.mu.RLock()
|
f.mu.RLock()
|
||||||
lst, err = sql.FindAll[List](&f.db, FileTableList, "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC")
|
lst, err = sql.FindAll[List](&f.db, FileTableList, q)
|
||||||
f.mu.RUnlock()
|
f.mu.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileDatabase) GetFileInfo(id int) (lst List, err error) {
|
func (f *FileDatabase) ListFileByID(id int) (lst List, err error) {
|
||||||
f.mu.RLock()
|
f.mu.RLock()
|
||||||
lst, err = sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(id))
|
lst, err = sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(id))
|
||||||
f.mu.RUnlock()
|
f.mu.RUnlock()
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ type loginResult struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
usertokens = ttl.NewCache[string, *global.User](time.Hour)
|
usertokens = ttl.NewCacheOn(time.Hour, [4]func(string, *global.User){
|
||||||
|
nil, nil, func(t string, _ *global.User) { loginstatus.Delete(t) }, nil,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
func login(username, challenge string) (*loginResult, error) {
|
func login(username, challenge string) (*loginResult, error) {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
istemp := r.URL.Query().Get("permanent") != "true"
|
||||||
count := -1
|
count := -1
|
||||||
var err error
|
var err error
|
||||||
countstr := r.URL.Query().Get("count")
|
countstr := r.URL.Query().Get("count")
|
||||||
@@ -64,7 +65,7 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lst, err := global.FileDB.ListUploadedFile()
|
lst, err := global.FileDB.ListUploadedFile(istemp)
|
||||||
if err != nil && err != sql.ErrNullResult {
|
if err != nil && err != sql.ErrNullResult {
|
||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
@@ -112,7 +113,7 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lst, err := global.FileDB.GetFileInfo(id)
|
lst, err := global.FileDB.ListFileByID(id)
|
||||||
if err != nil && err != sql.ErrNullResult {
|
if err != nil && err != sql.ErrNullResult {
|
||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
@@ -217,7 +218,8 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !user.IsSuper() {
|
istemp := r.URL.Query().Get("permanent") != "true"
|
||||||
|
if !user.IsSuper() && !istemp {
|
||||||
writeresult(w, codeError, nil, errNoDeletePermission.Error(), typeError)
|
writeresult(w, codeError, nil, errNoDeletePermission.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -231,7 +233,7 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = global.FileDB.DelFile(id, *user.ID, false)
|
err = global.FileDB.DelFile(id, *user.ID, istemp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
@@ -245,10 +247,6 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !user.IsSuper() {
|
|
||||||
writeresult(w, codeError, nil, errNoDeletePermission.Error(), typeError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
idstr := r.URL.Query().Get("id")
|
idstr := r.URL.Query().Get("id")
|
||||||
if idstr == "" {
|
if idstr == "" {
|
||||||
writeresult(w, codeError, nil, "empty id", typeError)
|
writeresult(w, codeError, nil, "empty id", typeError)
|
||||||
@@ -259,7 +257,7 @@ func init() {
|
|||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lst, err := global.FileDB.GetFileInfo(id)
|
lst, err := global.FileDB.ListFileByID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ enum Api {
|
|||||||
/**
|
/**
|
||||||
* @description: Get file list
|
* @description: Get file list
|
||||||
*/
|
*/
|
||||||
export const getFileList = (count?: number) => {
|
export const getFileList = (permanent: boolean, count?: number) => {
|
||||||
return defHttp.get<getFileListModel>({ url: Api.GetFileList, params: { count: count } })
|
return defHttp.get<getFileListModel>({ url: Api.GetFileList, params: { count, permanent } })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +36,8 @@ export const getFilePercent = (id: number) => {
|
|||||||
/**
|
/**
|
||||||
* @description: Get file percent
|
* @description: Get file percent
|
||||||
*/
|
*/
|
||||||
export const delFile = (id: number) => {
|
export const delFile = (id: number, permanent: boolean) => {
|
||||||
return defHttp.get<string>({ url: Api.DelFile, params: { id: id } })
|
return defHttp.get<string>({ url: Api.DelFile, params: { id, permanent } })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
4
frontend/vben/src/locales/lang/zh-CN/routes/templist.ts
Normal file
4
frontend/vben/src/locales/lang/zh-CN/routes/templist.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export default {
|
||||||
|
name: '试卷查重',
|
||||||
|
file: '查重报告',
|
||||||
|
}
|
||||||
17
frontend/vben/src/router/menus/modules/templist.ts
Normal file
17
frontend/vben/src/router/menus/modules/templist.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import type { MenuModule } from '/@/router/types'
|
||||||
|
import { t } from '/@/hooks/web/useI18n'
|
||||||
|
const menu: MenuModule = {
|
||||||
|
orderNo: 20,
|
||||||
|
menu: {
|
||||||
|
name: t('routes.templist.name'),
|
||||||
|
path: '/templist',
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
name: t('routes.templist.name'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default menu
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
import type { AppRouteModule } from '/@/router/types'
|
import type { AppRouteModule } from '/@/router/types'
|
||||||
import { ExceptionEnum } from '/@/enums/exceptionEnum'
|
|
||||||
import { LAYOUT } from '/@/router/constant'
|
import { LAYOUT } from '/@/router/constant'
|
||||||
import { t } from '/@/hooks/web/useI18n'
|
import { t } from '/@/hooks/web/useI18n'
|
||||||
|
|
||||||
const ExceptionPage = () => import('/@/views/sys/exception/Exception.vue')
|
|
||||||
|
|
||||||
const filelist: AppRouteModule = {
|
const filelist: AppRouteModule = {
|
||||||
path: '/filelist',
|
path: '/filelist',
|
||||||
name: 'FileList',
|
name: 'FileList',
|
||||||
@@ -38,17 +35,6 @@ const filelist: AppRouteModule = {
|
|||||||
hideMenu: true,
|
hideMenu: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '404',
|
|
||||||
name: 'PageNotFound',
|
|
||||||
component: ExceptionPage,
|
|
||||||
props: {
|
|
||||||
status: ExceptionEnum.PAGE_NOT_FOUND,
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
title: '404',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
41
frontend/vben/src/router/routes/modules/templist.ts
Normal file
41
frontend/vben/src/router/routes/modules/templist.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import type { AppRouteModule } from '/@/router/types'
|
||||||
|
import { LAYOUT } from '/@/router/constant'
|
||||||
|
import { t } from '/@/hooks/web/useI18n'
|
||||||
|
|
||||||
|
const templist: AppRouteModule = {
|
||||||
|
path: '/templist',
|
||||||
|
name: 'TempList',
|
||||||
|
component: LAYOUT,
|
||||||
|
redirect: '/templist/index',
|
||||||
|
meta: {
|
||||||
|
hideChildrenInMenu: true,
|
||||||
|
icon: 'ion:ios-analytics',
|
||||||
|
title: t('routes.templist.name'),
|
||||||
|
orderNo: 20,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
name: 'TempListPage',
|
||||||
|
component: () => import('/@/views/page/templist/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: t('routes.templist.name'),
|
||||||
|
icon: 'ion:file-tray-full-outline',
|
||||||
|
hideMenu: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'file/:id',
|
||||||
|
name: 'TempFilePage',
|
||||||
|
component: () => import('/@/views/page/file/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: t('routes.templist.file'),
|
||||||
|
carryParam: true,
|
||||||
|
icon: 'bi:filetype-docx',
|
||||||
|
hideMenu: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default templist
|
||||||
@@ -34,7 +34,7 @@ export function getListOfPage(pageSize: number, page: number): any[] {
|
|||||||
|
|
||||||
async function refreshFileList() {
|
async function refreshFileList() {
|
||||||
const __cardList: any[] = []
|
const __cardList: any[] = []
|
||||||
const lst = (await getFileList()) as getFileListModel
|
const lst = (await getFileList(true)) as getFileListModel
|
||||||
let __totalSize = 0
|
let __totalSize = 0
|
||||||
let __totalQuestions = 0
|
let __totalQuestions = 0
|
||||||
for (let i = 0; i < lst.length; i++) {
|
for (let i = 0; i < lst.length; i++) {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@
|
|||||||
async function deleteFile(item: any) {
|
async function deleteFile(item: any) {
|
||||||
try {
|
try {
|
||||||
item.delloading = true
|
item.delloading = true
|
||||||
const msg = await delFile(item.id)
|
const msg = await delFile(item.id, true)
|
||||||
if (msg) {
|
if (msg) {
|
||||||
createMessage.success(msg)
|
createMessage.success(msg)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
115
frontend/vben/src/views/page/templist/data.tsx
Normal file
115
frontend/vben/src/views/page/templist/data.tsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { reactive } from 'vue'
|
||||||
|
import { getFileList, getFilePercent, getFileInfo } from '/@/api/page'
|
||||||
|
import { getFileListModel } from '/@/api/page/model/fileListModel'
|
||||||
|
|
||||||
|
export const random = (min: number, max: number) =>
|
||||||
|
Math.floor(Math.random() * (max - min + 1) + min)
|
||||||
|
|
||||||
|
export function refreshFilePercent(item: any) {
|
||||||
|
return async () => {
|
||||||
|
const p = await getFilePercent(item.id)
|
||||||
|
if (p) {
|
||||||
|
item.percent = p
|
||||||
|
if (p < 100) {
|
||||||
|
setTimeout(refreshFilePercent(item), 1000)
|
||||||
|
}
|
||||||
|
} else item.hassettimeout = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getListOfPage(pageSize: number, page: number): any[] {
|
||||||
|
const i = page - 1
|
||||||
|
let lst: any[] = []
|
||||||
|
if (i < cardList._cardList.length / pageSize)
|
||||||
|
lst = reactive(cardList._cardList.slice(i * pageSize, page * pageSize))
|
||||||
|
else lst = reactive(cardList._cardList.slice((cardList._cardList.length / pageSize) * pageSize))
|
||||||
|
for (let i = 0; i < lst.length; i++) {
|
||||||
|
if (!lst[i].hassettimeout && lst[i].percent > 0 && lst[i].percent < 100) {
|
||||||
|
setTimeout(refreshFilePercent(lst[i]), 1000 + random(0, 1000))
|
||||||
|
lst[i].hassettimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lst
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshFileList() {
|
||||||
|
const __cardList: any[] = []
|
||||||
|
const lst = (await getFileList(false)) as getFileListModel
|
||||||
|
let __totalSize = 0
|
||||||
|
let __totalQuestions = 0
|
||||||
|
for (let i = 0; i < lst.length; i++) {
|
||||||
|
__cardList.push({
|
||||||
|
id: lst[i].id,
|
||||||
|
title: lst[i].title,
|
||||||
|
description: lst[i].description,
|
||||||
|
size: lst[i].size,
|
||||||
|
questions: lst[i].questions,
|
||||||
|
datetime: lst[i].datetime,
|
||||||
|
icon: 'bi:filetype-docx',
|
||||||
|
color: '#1890ff',
|
||||||
|
author: lst[i].author,
|
||||||
|
percent: lst[i].percent,
|
||||||
|
hassettimeout: false,
|
||||||
|
delloading: false,
|
||||||
|
})
|
||||||
|
__totalSize += lst[i].size
|
||||||
|
__totalQuestions += lst[i].questions
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
_cardList: __cardList,
|
||||||
|
_totalSize: __totalSize,
|
||||||
|
_totalQuestions: __totalQuestions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cardList = reactive(await refreshFileList())
|
||||||
|
|
||||||
|
export const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
total: cardList._cardList.length,
|
||||||
|
show: true,
|
||||||
|
pageSize: 10,
|
||||||
|
onChange: function (page: number, pageSize: number) {
|
||||||
|
this.current = page
|
||||||
|
this.pageSize = pageSize
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export function refreshCardList() {
|
||||||
|
refreshFileList().then((value) => {
|
||||||
|
cardList._cardList = value._cardList
|
||||||
|
cardList._totalQuestions = value._totalQuestions
|
||||||
|
cardList._totalSize = value._totalSize
|
||||||
|
pagination.current = 1
|
||||||
|
pagination.total = cardList._cardList.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteFileByID(id: number) {
|
||||||
|
cardList._cardList.map((value: any, index: number) => {
|
||||||
|
if (value.id == id) {
|
||||||
|
cardList._cardList.splice(index, 1)
|
||||||
|
cardList._totalSize -= value.size
|
||||||
|
cardList._totalQuestions -= value.questions
|
||||||
|
pagination.total = cardList._cardList.length
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshFileByID(id: number) {
|
||||||
|
getFileInfo(id).then((info) => {
|
||||||
|
cardList._cardList.map((value: any) => {
|
||||||
|
if (value.id == id) {
|
||||||
|
cardList._totalSize = cardList._totalSize - value.size + info.size
|
||||||
|
cardList._totalQuestions = cardList._totalQuestions - value.questions + info.questions
|
||||||
|
value.title = info.title
|
||||||
|
value.description = info.description
|
||||||
|
value.size = info.size
|
||||||
|
value.questions = info.questions
|
||||||
|
value.datetime = info.datetime
|
||||||
|
value.author = info.author
|
||||||
|
value.percent = info.percent
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
269
frontend/vben/src/views/page/templist/index.vue
Normal file
269
frontend/vben/src/views/page/templist/index.vue
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
<template>
|
||||||
|
<PageWrapper :class="prefixCls" :title="t('routes.templist.name')">
|
||||||
|
<template #headerContent>
|
||||||
|
<BasicUpload
|
||||||
|
name="paper"
|
||||||
|
v-if="hasPermission([RoleEnum.SUPER, RoleEnum.FILE_MANAGER])"
|
||||||
|
:maxSize="64"
|
||||||
|
:maxNumber="16"
|
||||||
|
:api="uploadApi"
|
||||||
|
@change="onChange"
|
||||||
|
:accept="['application/vnd.openxmlformats-officedocument.wordprocessingml.document']"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div :class="`${prefixCls}__top`">
|
||||||
|
<a-row :gutter="12">
|
||||||
|
<a-col :span="8" :class="`${prefixCls}__top-col`">
|
||||||
|
<div>总文件数</div>
|
||||||
|
<p> {{ pagination.total }}</p>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8" :class="`${prefixCls}__top-col`">
|
||||||
|
<div>占用空间</div>
|
||||||
|
<p> {{ cardList._totalSize.toFixed(2) }}MB </p>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8" :class="`${prefixCls}__top-col`">
|
||||||
|
<div>总题目数</div>
|
||||||
|
<p> {{ cardList._totalQuestions }} </p>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div :class="`${prefixCls}__content`">
|
||||||
|
<a-list :pagination="pagination">
|
||||||
|
<template
|
||||||
|
v-for="item in getListOfPage(pagination.pageSize, pagination.current)"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<a-list-item class="list">
|
||||||
|
<a-list-item-meta>
|
||||||
|
<template #avatar>
|
||||||
|
<Icon class="icon" v-if="item.icon" :icon="item.icon" :color="item.color" />
|
||||||
|
</template>
|
||||||
|
<template #title>
|
||||||
|
<span>{{ item.title }}</span>
|
||||||
|
<div class="extra">
|
||||||
|
<a-button
|
||||||
|
color="success"
|
||||||
|
:disabled="item.percent < 100"
|
||||||
|
@click="openFile(item.id)"
|
||||||
|
>
|
||||||
|
查阅
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
color="warning"
|
||||||
|
:disabled="item.percent != 0"
|
||||||
|
@click="analyzeFile(item)"
|
||||||
|
>
|
||||||
|
解析
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
color="error"
|
||||||
|
:disabled="item.percent > 0 && item.percent < 100"
|
||||||
|
:loading="item.delloading"
|
||||||
|
@click="deleteFile(item)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #description>
|
||||||
|
<div class="description">
|
||||||
|
{{ item.description }}
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div><span>文件大小</span>{{ item.size.toFixed(2) }}MB</div>
|
||||||
|
<div><span>上传用户</span>{{ item.author }}</div>
|
||||||
|
<div><span>上传时间</span>{{ item.datetime }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<div><span>解析进度</span></div>
|
||||||
|
<Progress
|
||||||
|
:percent="item.percent"
|
||||||
|
:status='((): "normal" | "success" | "active" | "exception" | undefined => {
|
||||||
|
if (item.percent < 100) return "active"
|
||||||
|
return "success"
|
||||||
|
})()'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
</template>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
</PageWrapper>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { Progress, Row, Col } from 'ant-design-vue'
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import { Icon } from '/@/components/Icon'
|
||||||
|
import { BasicUpload } from '/@/components/Upload'
|
||||||
|
import {
|
||||||
|
cardList,
|
||||||
|
getListOfPage,
|
||||||
|
deleteFileByID,
|
||||||
|
pagination,
|
||||||
|
refreshFilePercent,
|
||||||
|
random,
|
||||||
|
refreshCardList,
|
||||||
|
refreshFileByID,
|
||||||
|
} from './data'
|
||||||
|
import { PageWrapper } from '/@/components/Page'
|
||||||
|
import { useMessage } from '/@/hooks/web/useMessage'
|
||||||
|
import { usePermission } from '/@/hooks/web/usePermission'
|
||||||
|
import { RoleEnum } from '/@/enums/roleEnum'
|
||||||
|
import { List } from 'ant-design-vue'
|
||||||
|
import { uploadApi } from '/@/api/sys/upload'
|
||||||
|
import { useI18n } from '/@/hooks/web/useI18n'
|
||||||
|
import { delFile, analyzeFile } from '/@/api/page'
|
||||||
|
import { useGo } from '/@/hooks/web/usePage'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const { createMessage } = useMessage()
|
||||||
|
|
||||||
|
async function deleteFile(item: any) {
|
||||||
|
try {
|
||||||
|
item.delloading = true
|
||||||
|
const msg = await delFile(item.id, false)
|
||||||
|
if (msg) {
|
||||||
|
createMessage.success(msg)
|
||||||
|
setTimeout(() => {
|
||||||
|
deleteFileByID(item.id)
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
createMessage.error((error as unknown as Error).message)
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
item.delloading = false
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function analFile(item: any) {
|
||||||
|
try {
|
||||||
|
const msg = await analyzeFile(item.id, false)
|
||||||
|
if (msg) {
|
||||||
|
createMessage.success(msg.msg)
|
||||||
|
if (msg.code == 0) {
|
||||||
|
item.percent = 100
|
||||||
|
refreshFileByID(item.id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!item.hassettimeout && item.percent == 0) {
|
||||||
|
setTimeout(refreshFilePercent(item), 1000 + random(0, 1000))
|
||||||
|
item.hassettimeout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
createMessage.error((error as unknown as Error).message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
BasicUpload,
|
||||||
|
Icon,
|
||||||
|
Progress,
|
||||||
|
PageWrapper,
|
||||||
|
[List.name]: List,
|
||||||
|
[List.Item.name]: List.Item,
|
||||||
|
AListItemMeta: List.Item.Meta,
|
||||||
|
[Row.name]: Row,
|
||||||
|
[Col.name]: Col,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const { hasPermission } = usePermission()
|
||||||
|
const go = useGo()
|
||||||
|
|
||||||
|
function openFile(id: number) {
|
||||||
|
go({ name: 'TempFilePage', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onChange(_: number[]) {
|
||||||
|
refreshCardList()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
t,
|
||||||
|
RoleEnum,
|
||||||
|
uploadApi,
|
||||||
|
hasPermission,
|
||||||
|
prefixCls: 'list-basic',
|
||||||
|
getListOfPage,
|
||||||
|
openFile,
|
||||||
|
deleteFile,
|
||||||
|
analyzeFile: analFile,
|
||||||
|
cardList,
|
||||||
|
pagination,
|
||||||
|
onChange,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.list-basic {
|
||||||
|
&__top {
|
||||||
|
padding: 24px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: @component-background;
|
||||||
|
&-col {
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-right: 1px dashed @border-color-base;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: @text-color;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 32px;
|
||||||
|
color: @text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__content {
|
||||||
|
padding: 24px;
|
||||||
|
margin-top: 12px;
|
||||||
|
background-color: @component-background;
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
font-size: 40px !important;
|
||||||
|
}
|
||||||
|
.extra {
|
||||||
|
position: absolute;
|
||||||
|
top: 38px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
.description {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
display: inline-block;
|
||||||
|
width: 40%;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: top;
|
||||||
|
div {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 20px;
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.progress {
|
||||||
|
display: inline-block;
|
||||||
|
width: 15%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user