mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-28 06:40:28 +08:00
implement chkdup & optimize file
This commit is contained in:
@@ -31,7 +31,7 @@ type filelist struct {
|
|||||||
Per uint `json:"percent"`
|
Per uint `json:"percent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileList(count int, istemp bool) ([]filelist, error) {
|
func getFileList(count int, istemp *bool) ([]filelist, error) {
|
||||||
lst, err := global.FileDB.ListUploadedFile(istemp)
|
lst, err := global.FileDB.ListUploadedFile(istemp)
|
||||||
if err != nil && err != sql.ErrNullResult {
|
if err != nil && err != sql.ErrNullResult {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -149,7 +149,12 @@ 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"
|
istemp := (*bool)(nil)
|
||||||
|
permanent := r.URL.Query().Get("permanent")
|
||||||
|
if permanent != "" {
|
||||||
|
b := permanent != "true"
|
||||||
|
istemp = &b
|
||||||
|
}
|
||||||
count := -1
|
count := -1
|
||||||
var err error
|
var err error
|
||||||
countstr := r.URL.Query().Get("count")
|
countstr := r.URL.Query().Get("count")
|
||||||
|
|||||||
@@ -83,11 +83,14 @@ 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(istemp bool) (lst []*List, err error) {
|
func (f *FileDatabase) ListUploadedFile(istemp *bool) (lst []*List, err error) {
|
||||||
q := ""
|
q := ""
|
||||||
if istemp {
|
switch {
|
||||||
|
case istemp == nil:
|
||||||
|
q = "ORDER BY UpTime DESC"
|
||||||
|
case *istemp:
|
||||||
q = "WHERE IsTemp ORDER BY UpTime DESC"
|
q = "WHERE IsTemp ORDER BY UpTime DESC"
|
||||||
} else {
|
default:
|
||||||
q = "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC"
|
q = "WHERE (HasntAnalyzed AND IsTemp) OR (NOT HasntAnalyzed AND NOT IsTemp) ORDER BY UpTime DESC"
|
||||||
}
|
}
|
||||||
f.mu.RLock()
|
f.mu.RLock()
|
||||||
|
|||||||
@@ -23,10 +23,23 @@ enum Api {
|
|||||||
/**
|
/**
|
||||||
* @description: Get file list
|
* @description: Get file list
|
||||||
*/
|
*/
|
||||||
export const getFileList = (permanent: boolean, count?: number) => {
|
export const getFileList = (permanent?: boolean, count?: number) => {
|
||||||
return defHttp.get<getFileListModel>({ url: Api.GetFileList, params: { count, permanent } })
|
return defHttp.get<getFileListModel>({ url: Api.GetFileList, params: { count, permanent } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Get file options
|
||||||
|
*/
|
||||||
|
export const getFileOptions = async () => {
|
||||||
|
const data = await defHttp.get<getFileListModel>({
|
||||||
|
url: Api.GetFileList,
|
||||||
|
})
|
||||||
|
return data.map((item) => ({
|
||||||
|
label: item.description,
|
||||||
|
value: item.id.toString(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: Get file info
|
* @description: Get file info
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
name: '试卷查重',
|
name: '试卷查重',
|
||||||
|
templist: '临时试卷库',
|
||||||
file: '查重报告',
|
file: '查重报告',
|
||||||
|
dup: '开始查重',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ const menu: MenuModule = {
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
name: t('routes.templist.name'),
|
name: t('routes.templist.templist'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'chkdup',
|
||||||
|
name: t('routes.templist.dup'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ const templist: AppRouteModule = {
|
|||||||
component: LAYOUT,
|
component: LAYOUT,
|
||||||
redirect: '/templist/index',
|
redirect: '/templist/index',
|
||||||
meta: {
|
meta: {
|
||||||
hideChildrenInMenu: true,
|
|
||||||
icon: 'ion:ios-analytics',
|
icon: 'ion:ios-analytics',
|
||||||
title: t('routes.templist.name'),
|
title: t('routes.templist.name'),
|
||||||
orderNo: 30,
|
orderNo: 30,
|
||||||
@@ -19,9 +18,17 @@ const templist: AppRouteModule = {
|
|||||||
name: 'TempListPage',
|
name: 'TempListPage',
|
||||||
component: () => import('/@/views/page/templist/index.vue'),
|
component: () => import('/@/views/page/templist/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: t('routes.templist.name'),
|
title: t('routes.templist.templist'),
|
||||||
icon: 'ion:file-tray-full-outline',
|
icon: 'ion:albums-outline',
|
||||||
hideMenu: true,
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'chkdup',
|
||||||
|
name: 'CheckDupPage',
|
||||||
|
component: () => import('/@/views/page/chkdup/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: t('routes.templist.dup'),
|
||||||
|
icon: 'ion:podium-sharp',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
24
frontend/vben/src/views/page/chkdup/data.ts
Normal file
24
frontend/vben/src/views/page/chkdup/data.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { FormSchema } from '/@/components/Form'
|
||||||
|
|
||||||
|
export const schemas: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'f1',
|
||||||
|
component: 'Input',
|
||||||
|
label: '试卷名',
|
||||||
|
slot: 'localSearch',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export const taskSchemas: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 't1',
|
||||||
|
component: 'RangePicker',
|
||||||
|
label: '查询年限范围',
|
||||||
|
required: true,
|
||||||
|
componentProps: {
|
||||||
|
format: 'YYYY',
|
||||||
|
placeholder: ['起始年份', '结束年份'],
|
||||||
|
showTime: { format: 'YYYY' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
101
frontend/vben/src/views/page/chkdup/index.vue
Normal file
101
frontend/vben/src/views/page/chkdup/index.vue
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<template>
|
||||||
|
<PageWrapper
|
||||||
|
class="high-form"
|
||||||
|
:title="t('routes.templist.dup')"
|
||||||
|
content="设定好待查重试卷和查重年限后,即可生成查重报告。"
|
||||||
|
>
|
||||||
|
<a-card title="待查重试卷" :bordered="false">
|
||||||
|
<BasicForm @register="register">
|
||||||
|
<template #localSearch="{ model, field }">
|
||||||
|
<ApiSelect
|
||||||
|
:api="getFileOptions"
|
||||||
|
showSearch
|
||||||
|
v-model:value="model[field]"
|
||||||
|
optionFilterProp="label"
|
||||||
|
resultField="value"
|
||||||
|
labelField="label"
|
||||||
|
valueField="value"
|
||||||
|
:params="searchParams"
|
||||||
|
@search="onSearch"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</BasicForm>
|
||||||
|
</a-card>
|
||||||
|
<a-card title="查重限定条件" :bordered="false" class="!mt-5">
|
||||||
|
<BasicForm @register="registerTask" />
|
||||||
|
</a-card>
|
||||||
|
<a-card title="查重报告" :bordered="false" class="!mt-5">
|
||||||
|
<p> aaaaa </p>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<template #rightFooter>
|
||||||
|
<a-button type="primary" @click="submitAll"> 提交 </a-button>
|
||||||
|
</template>
|
||||||
|
</PageWrapper>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { BasicForm, useForm, ApiSelect } from '/@/components/Form'
|
||||||
|
import { defineComponent, ref, unref, computed } from 'vue'
|
||||||
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
|
import { PageWrapper } from '/@/components/Page'
|
||||||
|
import { schemas, taskSchemas } from './data'
|
||||||
|
import { Card } from 'ant-design-vue'
|
||||||
|
import { useI18n } from '/@/hooks/web/useI18n'
|
||||||
|
import { getFileOptions } from '/@/api/page'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'FormHightPage',
|
||||||
|
components: { ApiSelect, BasicForm, PageWrapper, [Card.name]: Card },
|
||||||
|
setup() {
|
||||||
|
const { t } = useI18n()
|
||||||
|
const keyword = ref<string>('')
|
||||||
|
const searchParams = computed<Recordable>(() => {
|
||||||
|
return { keyword: unref(keyword) }
|
||||||
|
})
|
||||||
|
|
||||||
|
const [register, { validate }] = useForm({
|
||||||
|
layout: 'vertical',
|
||||||
|
baseColProps: {
|
||||||
|
span: 24,
|
||||||
|
},
|
||||||
|
schemas: schemas,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const [registerTask, { validate: validateTaskForm }] = useForm({
|
||||||
|
layout: 'vertical',
|
||||||
|
baseColProps: {
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
schemas: taskSchemas,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
async function submitAll() {
|
||||||
|
try {
|
||||||
|
const [values, taskValues] = await Promise.all([validate(), validateTaskForm()])
|
||||||
|
console.log('form data:', values, taskValues)
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSearch(value: string) {
|
||||||
|
keyword.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
t,
|
||||||
|
register,
|
||||||
|
registerTask,
|
||||||
|
submitAll,
|
||||||
|
getFileOptions,
|
||||||
|
searchParams,
|
||||||
|
onSearch: useDebounceFn(onSearch, 300),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.high-form {
|
||||||
|
padding-bottom: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,10 +5,16 @@
|
|||||||
下载试卷 ({{ docxSizeRef.toFixed(2) }}MB)
|
下载试卷 ({{ docxSizeRef.toFixed(2) }}MB)
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
<div ref="chartRef" :style="{ height, width }"></div>
|
|
||||||
<div class="docxWrap" :style="{ width }">
|
<a-card title="分析报告" :bordered="false">
|
||||||
<div ref="docxRef"></div>
|
<div ref="chartRef" :style="{ height, width }"></div>
|
||||||
</div>
|
</a-card>
|
||||||
|
|
||||||
|
<a-card title="原卷预览" :bordered="false" class="!mt-5">
|
||||||
|
<div class="docxWrap" :style="{ width }">
|
||||||
|
<div ref="docxRef"></div>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -17,6 +23,7 @@
|
|||||||
import { PageWrapper } from '/@/components/Page'
|
import { PageWrapper } from '/@/components/Page'
|
||||||
import { useECharts } from '/@/hooks/web/useECharts'
|
import { useECharts } from '/@/hooks/web/useECharts'
|
||||||
import { renderAsync } from 'docx-preview'
|
import { renderAsync } from 'docx-preview'
|
||||||
|
import { Card } from 'ant-design-vue'
|
||||||
import { downloadFile, getFileStatus, getFileBlob } from '/@/api/page'
|
import { downloadFile, getFileStatus, getFileBlob } from '/@/api/page'
|
||||||
import { useMessage } from '/@/hooks/web/useMessage'
|
import { useMessage } from '/@/hooks/web/useMessage'
|
||||||
import { useGo } from '/@/hooks/web/usePage'
|
import { useGo } from '/@/hooks/web/usePage'
|
||||||
@@ -56,7 +63,7 @@
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'PaperAnalyzeTab',
|
name: 'PaperAnalyzeTab',
|
||||||
components: { PageWrapper },
|
components: { PageWrapper, [Card.name]: Card },
|
||||||
props: {
|
props: {
|
||||||
width: {
|
width: {
|
||||||
type: String as PropType<string>,
|
type: String as PropType<string>,
|
||||||
@@ -133,7 +140,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '重复率: ' + ret.rate.toFixed(2) + '%, 前十如下',
|
text: '全库重复率: ' + ret.rate.toFixed(2) + '%, 前十如下',
|
||||||
left: '40%',
|
left: '40%',
|
||||||
top: '1%',
|
top: '1%',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<PageWrapper :class="prefixCls" :title="t('routes.templist.name')">
|
<PageWrapper :class="prefixCls" :title="t('routes.templist.templist')">
|
||||||
<template #headerContent>
|
<template #headerContent>
|
||||||
<BasicUpload
|
<div>
|
||||||
name="paper"
|
<p> 此处用来临时上传存放待查重试卷备用。 </p>
|
||||||
v-if="hasPermission([RoleEnum.SUPER, RoleEnum.FILE_MANAGER])"
|
<BasicUpload
|
||||||
:maxSize="64"
|
name="paper"
|
||||||
:maxNumber="16"
|
v-if="hasPermission([RoleEnum.SUPER, RoleEnum.FILE_MANAGER])"
|
||||||
:api="uploadApi"
|
:maxSize="64"
|
||||||
@change="onChange"
|
:maxNumber="16"
|
||||||
:accept="['application/vnd.openxmlformats-officedocument.wordprocessingml.document']"
|
:api="uploadApi"
|
||||||
/>
|
@change="onChange"
|
||||||
|
:accept="['application/vnd.openxmlformats-officedocument.wordprocessingml.document']"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div :class="`${prefixCls}__top`">
|
<div :class="`${prefixCls}__top`">
|
||||||
<a-row :gutter="12">
|
<a-row :gutter="12">
|
||||||
|
|||||||
3
main.go
3
main.go
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/fumiama/paper-manager/backend"
|
"github.com/fumiama/paper-manager/backend"
|
||||||
"github.com/fumiama/paper-manager/frontend"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func line() int {
|
func line() int {
|
||||||
@@ -34,7 +33,7 @@ func main() {
|
|||||||
http.HandleFunc("/file/", backend.FileHandler)
|
http.HandleFunc("/file/", backend.FileHandler)
|
||||||
http.HandleFunc("/paper/", backend.PaperHandler)
|
http.HandleFunc("/paper/", backend.PaperHandler)
|
||||||
http.HandleFunc("/upload", backend.UploadHandler)
|
http.HandleFunc("/upload", backend.UploadHandler)
|
||||||
http.Handle("/", frontend.StaticHandler)
|
//http.Handle("/", frontend.StaticHandler)
|
||||||
|
|
||||||
logrus.Infoln("[http.Serve] start at", l.Addr())
|
logrus.Infoln("[http.Serve] start at", l.Addr())
|
||||||
logrus.Errorln("[http.Serve]", http.Serve(l, nil))
|
logrus.Errorln("[http.Serve]", http.Serve(l, nil))
|
||||||
|
|||||||
Reference in New Issue
Block a user