1
0
mirror of https://github.com/fumiama/paper-manager.git synced 2026-06-28 14:50:29 +08:00

finish filelist/file

This commit is contained in:
源文雨
2023-03-16 23:06:53 +08:00
parent df5bc78d4b
commit 57b32e609f
4 changed files with 221 additions and 129 deletions

View File

@@ -16,4 +16,38 @@ export default [
}) })
}, },
}, },
{
url: '/api/getFileStatus',
timeout: 500,
method: 'get',
response: (request: requestParams) => {
const token = getRequestToken(request)
if (!token) return resultError('Invalid token')
const id = Number(request.query.id)
if (!id || id < 0) return resultError('Invalid id')
return resultSuccess({
name: '100.docx',
size: 1.5,
questions: [
{ count: 4, point: 10, name: '一、填空题' },
{ count: 10, point: 20, name: '二、不定项选择题' },
{ count: 5, point: 10, name: '三、判断改错题' },
{ count: 5, point: 30, name: '四、简述题' },
{ count: 4, point: 30, name: '五、综合题' },
],
duplications: [
{ percent: 10, name: '二.1' },
{ percent: 20, name: '二.2' },
{ percent: 30, name: '二.3' },
{ percent: 40, name: '二.4' },
{ percent: 50, name: '二.5' },
{ percent: 60, name: '二.6' },
{ percent: 70, name: '二.7' },
{ percent: 80, name: '二.8' },
{ percent: 90, name: '二.9' },
{ percent: 100, name: '二.10' },
],
})
},
},
] as MockMethod[] ] as MockMethod[]

View File

@@ -1,6 +1,6 @@
import { defHttp } from '/@/utils/http/axios' import { defHttp } from '/@/utils/http/axios'
import { getFileListModel, FilePercent, DelFile, AnalyzeFile } from './model/fileListModel' import { getFileListModel, FilePercent, DelFile, AnalyzeFile } from './model/fileListModel'
import { DownloadFile } from './model/fileModel' import { DownloadFile, FileStatus } from './model/fileModel'
enum Api { enum Api {
GetFileList = '/getFileList', GetFileList = '/getFileList',
@@ -8,6 +8,7 @@ enum Api {
DelFile = '/delFile', DelFile = '/delFile',
AnalyzeFile = '/analyzeFile', AnalyzeFile = '/analyzeFile',
DlFile = '/dlFile', DlFile = '/dlFile',
GetFileStatus = '/getFileStatus',
} }
/** /**
@@ -44,3 +45,10 @@ export const analyzeFile = (id: number) => {
export const downloadFile = (id: number) => { export const downloadFile = (id: number) => {
return defHttp.get<DownloadFile>({ url: Api.DlFile, params: { id: id } }) return defHttp.get<DownloadFile>({ url: Api.DlFile, params: { id: id } })
} }
/**
* @description: Get file status
*/
export const getFileStatus = (id: number) => {
return defHttp.get<FileStatus>({ url: Api.GetFileStatus, params: { id: id } })
}

View File

@@ -1,3 +1,21 @@
export interface DownloadFile { export interface DownloadFile {
url: string url: string
} }
export interface Question {
count: number
point: number
name: string
}
export interface Duplication {
percent: number
name: string
}
export interface FileStatus {
name: string
size: number
questions: Question[]
duplications: Duplication[]
}

View File

@@ -1,7 +1,7 @@
<template> <template>
<PageWrapper :title="t('routes.filelist.file')"> <PageWrapper :title="t('routes.filelist.file') + ': ' + docxNameRef">
<template #headerContent> <template #headerContent>
<a-button type="primary" @click="downloadDocx"> 下载试卷 </a-button> <a-button type="primary" @click="downloadDocx"> 下载试卷 ({{ docxSizeRef }}MB) </a-button>
</template> </template>
<div ref="chartRef" :style="{ height, width }"></div> <div ref="chartRef" :style="{ height, width }"></div>
<div class="docxWrap" :style="{ width }"> <div class="docxWrap" :style="{ width }">
@@ -10,14 +10,15 @@
</PageWrapper> </PageWrapper>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, unref, PropType, ref, Ref, onMounted } from 'vue' import { computed, defineComponent, unref, PropType, ref, Ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
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 { downloadFile } from '/@/api/page' import { downloadFile, getFileStatus } from '/@/api/page'
import { DownloadFile } from '/@/api/page/model/fileModel' import { useMessage } from '/@/hooks/web/useMessage'
import { useGo } from '/@/hooks/web/usePage' import { useGo } from '/@/hooks/web/usePage'
import { useTabs } from '/@/hooks/web/useTabs'
import { PageEnum } from '/@/enums/pageEnum' import { PageEnum } from '/@/enums/pageEnum'
import { useI18n } from '/@/hooks/web/useI18n' import { useI18n } from '/@/hooks/web/useI18n'
import { downloadByData } from '/@/utils/file/download' import { downloadByData } from '/@/utils/file/download'
@@ -27,6 +28,9 @@
let docxRef = ref(null) let docxRef = ref(null)
let docxNameRef = ref('paper.docx')
let docxSizeRef = ref(0)
let docxBlob: Blob | null = null let docxBlob: Blob | null = null
function loadDocx(file: Blob) { function loadDocx(file: Blob) {
@@ -46,7 +50,7 @@
} }
function downloadDocx() { function downloadDocx() {
downloadByData(docxBlob as BlobPart, 'testName.docx') downloadByData(docxBlob as BlobPart, docxNameRef.value)
} }
export default defineComponent({ export default defineComponent({
@@ -64,6 +68,8 @@
}, },
setup() { setup() {
const { currentRoute } = useRouter() const { currentRoute } = useRouter()
const { createMessage } = useMessage()
const { closeCurrent } = useTabs()
const go = useGo() const go = useGo()
const params = computed(() => { const params = computed(() => {
@@ -72,141 +78,167 @@
if (!params.value || !params.value.id) { if (!params.value || !params.value.id) {
go(PageEnum.ERROR_PAGE) go(PageEnum.ERROR_PAGE)
closeCurrent()
} }
downloadFile(Number(params.value.id)).then((file: DownloadFile) => { ;(async () => {
if (file && file.url) { try {
axios({ const ret = await downloadFile(Number(params.value.id))
method: 'get', if (ret && ret.url) {
responseType: 'blob', const { data } = await axios({
url: file.url, method: 'get',
}).then(({ data }) => { responseType: 'blob',
loadDocx(data) url: ret.url,
}) })
} else go(PageEnum.ERROR_PAGE) if (data) {
}) loadDocx(data)
return
}
}
go(PageEnum.ERROR_PAGE)
closeCurrent()
} catch (error) {
createMessage.error('加载docx错误: ' + (error as unknown as Error).message)
go(PageEnum.ERROR_PAGE)
closeCurrent()
}
})()
const chartRef = ref<HTMLDivElement | null>(null) const chartRef = ref<HTMLDivElement | null>(null)
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
const dataAll = [389, 259, 262, 324, 232, 176, 196, 214, 133, 370]
const yAxisData = [ ;(async () => {
'原因1', try {
'原因2', const ret = await getFileStatus(Number(params.value.id))
'原因3', if (ret && ret.duplications.length > 0 && ret.questions.length > 0) {
'原因4', docxNameRef.value = ret.name
'原因5', docxSizeRef.value = ret.size
'原因6', const barNames = ret.duplications.map((value) => {
'原因7', return value.name
'原因8', })
'原因9', const barData = ret.duplications.map((value) => {
'原因10', return value.percent
] })
onMounted(() => { const queData = ret.questions.map((value) => {
setOptions({ return { value: value.count, name: value.name }
title: [ })
{ const ptData = ret.questions.map((value) => {
text: '题量占比', return { value: value.point, name: value.name }
left: '2%', })
top: '1%', setOptions({
textStyle: { title: [
fontSize: 20, {
}, text: '题量占比',
}, left: '2%',
{ top: '1%',
text: '重复率前十', textStyle: {
left: '40%', fontSize: 20,
top: '1%', },
textStyle: { },
fontSize: 20, {
}, text: '重复率前十',
}, left: '40%',
{ top: '1%',
text: '分数占比', textStyle: {
left: '2%', fontSize: 20,
top: '50%', },
textStyle: { },
fontSize: 20, {
}, text: '分数占比',
}, left: '2%',
], top: '50%',
grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }], textStyle: {
tooltip: { fontSize: 20,
formatter: '{b} ({c})', },
}, },
xAxis: [
{
gridIndex: 0,
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: false },
axisLine: { show: false },
},
],
yAxis: [
{
gridIndex: 0,
interval: 0,
data: yAxisData.reverse(),
axisTick: { show: false },
axisLabel: { show: true },
splitLine: { show: false },
axisLine: { show: true },
},
],
series: [
{
name: '各渠道投诉占比',
type: 'pie',
radius: '30%',
center: ['22%', '25%'],
data: [
{ value: 335, name: '客服电话' },
{ value: 310, name: '奥迪官网' },
{ value: 234, name: '媒体曝光' },
{ value: 135, name: '质检总局' },
{ value: 105, name: '其他' },
], ],
labelLine: { show: false }, grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }],
label: { tooltip: {
show: true, formatter: '{b} ({c})',
formatter: '{b} \n ({d}%)',
}, },
}, xAxis: [
{ {
name: '各级别投诉占比', gridIndex: 0,
type: 'pie', axisTick: { show: false },
radius: '30%', axisLabel: { show: false },
center: ['22%', '75%'], splitLine: { show: false },
labelLine: { show: false }, axisLine: { show: false },
data: [ },
{ value: 335, name: 'A级' },
{ value: 310, name: 'B级' },
{ value: 234, name: 'C级' },
{ value: 135, name: 'D级' },
], ],
label: { yAxis: [
show: true, {
formatter: '{b} \n ({d}%)', gridIndex: 0,
}, interval: 0,
}, data: barNames,
{ axisTick: { show: false },
name: '投诉原因TOP10', axisLabel: { show: true },
type: 'bar', splitLine: { show: false },
xAxisIndex: 0, axisLine: { show: true },
yAxisIndex: 0, },
barWidth: '45%', ],
itemStyle: { color: '#86c9f4' }, series: [
label: { show: true, position: 'right' }, {
data: dataAll.sort(), name: '题量占比',
}, type: 'pie',
], radius: '30%',
}) center: ['22%', '25%'],
}) data: queData,
labelLine: { show: false },
label: {
show: true,
formatter: function (d) {
return d.name + '(' + d.value + ')'
},
},
},
{
name: '分数占比',
type: 'pie',
radius: '30%',
center: ['22%', '75%'],
labelLine: { show: false },
data: ptData,
label: {
show: true,
formatter: '{b}\n  ({d}%) ',
},
},
{
name: '重复率前十',
type: 'bar',
xAxisIndex: 0,
yAxisIndex: 0,
barWidth: '45%',
itemStyle: { color: '#86c9f4' },
label: {
show: true,
position: 'right',
formatter: function (d) {
return d.data + '%'
},
},
data: barData,
},
],
})
return
}
go(PageEnum.ERROR_PAGE)
closeCurrent()
} catch (error) {
createMessage.error('加载分析数据错误: ' + (error as unknown as Error).message)
go(PageEnum.ERROR_PAGE)
closeCurrent()
}
})()
return { return {
t, t,
chartRef, chartRef,
docxRef, docxRef,
downloadDocx, downloadDocx,
docxNameRef,
docxSizeRef,
} }
}, },
}) })