mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-09 02:01:31 +08:00
finish filelist/file
This commit is contained in:
@@ -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[]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defHttp } from '/@/utils/http/axios'
|
||||
import { getFileListModel, FilePercent, DelFile, AnalyzeFile } from './model/fileListModel'
|
||||
import { DownloadFile } from './model/fileModel'
|
||||
import { DownloadFile, FileStatus } from './model/fileModel'
|
||||
|
||||
enum Api {
|
||||
GetFileList = '/getFileList',
|
||||
@@ -8,6 +8,7 @@ enum Api {
|
||||
DelFile = '/delFile',
|
||||
AnalyzeFile = '/analyzeFile',
|
||||
DlFile = '/dlFile',
|
||||
GetFileStatus = '/getFileStatus',
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,3 +45,10 @@ export const analyzeFile = (id: number) => {
|
||||
export const downloadFile = (id: number) => {
|
||||
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 } })
|
||||
}
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
export interface DownloadFile {
|
||||
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[]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<PageWrapper :title="t('routes.filelist.file')">
|
||||
<PageWrapper :title="t('routes.filelist.file') + ': ' + docxNameRef">
|
||||
<template #headerContent>
|
||||
<a-button type="primary" @click="downloadDocx"> 下载试卷 </a-button>
|
||||
<a-button type="primary" @click="downloadDocx"> 下载试卷 ({{ docxSizeRef }}MB) </a-button>
|
||||
</template>
|
||||
<div ref="chartRef" :style="{ height, width }"></div>
|
||||
<div class="docxWrap" :style="{ width }">
|
||||
@@ -10,14 +10,15 @@
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<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 { PageWrapper } from '/@/components/Page'
|
||||
import { useECharts } from '/@/hooks/web/useECharts'
|
||||
import { renderAsync } from 'docx-preview'
|
||||
import { downloadFile } from '/@/api/page'
|
||||
import { DownloadFile } from '/@/api/page/model/fileModel'
|
||||
import { downloadFile, getFileStatus } from '/@/api/page'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { useGo } from '/@/hooks/web/usePage'
|
||||
import { useTabs } from '/@/hooks/web/useTabs'
|
||||
import { PageEnum } from '/@/enums/pageEnum'
|
||||
import { useI18n } from '/@/hooks/web/useI18n'
|
||||
import { downloadByData } from '/@/utils/file/download'
|
||||
@@ -27,6 +28,9 @@
|
||||
|
||||
let docxRef = ref(null)
|
||||
|
||||
let docxNameRef = ref('paper.docx')
|
||||
let docxSizeRef = ref(0)
|
||||
|
||||
let docxBlob: Blob | null = null
|
||||
|
||||
function loadDocx(file: Blob) {
|
||||
@@ -46,7 +50,7 @@
|
||||
}
|
||||
|
||||
function downloadDocx() {
|
||||
downloadByData(docxBlob as BlobPart, 'testName.docx')
|
||||
downloadByData(docxBlob as BlobPart, docxNameRef.value)
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
@@ -64,6 +68,8 @@
|
||||
},
|
||||
setup() {
|
||||
const { currentRoute } = useRouter()
|
||||
const { createMessage } = useMessage()
|
||||
const { closeCurrent } = useTabs()
|
||||
const go = useGo()
|
||||
|
||||
const params = computed(() => {
|
||||
@@ -72,141 +78,167 @@
|
||||
|
||||
if (!params.value || !params.value.id) {
|
||||
go(PageEnum.ERROR_PAGE)
|
||||
closeCurrent()
|
||||
}
|
||||
|
||||
downloadFile(Number(params.value.id)).then((file: DownloadFile) => {
|
||||
if (file && file.url) {
|
||||
axios({
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
url: file.url,
|
||||
}).then(({ data }) => {
|
||||
loadDocx(data)
|
||||
})
|
||||
} else go(PageEnum.ERROR_PAGE)
|
||||
})
|
||||
;(async () => {
|
||||
try {
|
||||
const ret = await downloadFile(Number(params.value.id))
|
||||
if (ret && ret.url) {
|
||||
const { data } = await axios({
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
url: ret.url,
|
||||
})
|
||||
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 { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
||||
const dataAll = [389, 259, 262, 324, 232, 176, 196, 214, 133, 370]
|
||||
const yAxisData = [
|
||||
'原因1',
|
||||
'原因2',
|
||||
'原因3',
|
||||
'原因4',
|
||||
'原因5',
|
||||
'原因6',
|
||||
'原因7',
|
||||
'原因8',
|
||||
'原因9',
|
||||
'原因10',
|
||||
]
|
||||
onMounted(() => {
|
||||
setOptions({
|
||||
title: [
|
||||
{
|
||||
text: '题量占比',
|
||||
left: '2%',
|
||||
top: '1%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '重复率前十',
|
||||
left: '40%',
|
||||
top: '1%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '分数占比',
|
||||
left: '2%',
|
||||
top: '50%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
],
|
||||
grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }],
|
||||
tooltip: {
|
||||
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: '其他' },
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
const ret = await getFileStatus(Number(params.value.id))
|
||||
if (ret && ret.duplications.length > 0 && ret.questions.length > 0) {
|
||||
docxNameRef.value = ret.name
|
||||
docxSizeRef.value = ret.size
|
||||
const barNames = ret.duplications.map((value) => {
|
||||
return value.name
|
||||
})
|
||||
const barData = ret.duplications.map((value) => {
|
||||
return value.percent
|
||||
})
|
||||
const queData = ret.questions.map((value) => {
|
||||
return { value: value.count, name: value.name }
|
||||
})
|
||||
const ptData = ret.questions.map((value) => {
|
||||
return { value: value.point, name: value.name }
|
||||
})
|
||||
setOptions({
|
||||
title: [
|
||||
{
|
||||
text: '题量占比',
|
||||
left: '2%',
|
||||
top: '1%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '重复率前十',
|
||||
left: '40%',
|
||||
top: '1%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '分数占比',
|
||||
left: '2%',
|
||||
top: '50%',
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
],
|
||||
labelLine: { show: false },
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b} \n ({d}%)',
|
||||
grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }],
|
||||
tooltip: {
|
||||
formatter: '{b} ({c})',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '各级别投诉占比',
|
||||
type: 'pie',
|
||||
radius: '30%',
|
||||
center: ['22%', '75%'],
|
||||
labelLine: { show: false },
|
||||
data: [
|
||||
{ value: 335, name: 'A级' },
|
||||
{ value: 310, name: 'B级' },
|
||||
{ value: 234, name: 'C级' },
|
||||
{ value: 135, name: 'D级' },
|
||||
xAxis: [
|
||||
{
|
||||
gridIndex: 0,
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: false },
|
||||
splitLine: { show: false },
|
||||
axisLine: { show: false },
|
||||
},
|
||||
],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b} \n ({d}%)',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '投诉原因TOP10',
|
||||
type: 'bar',
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 0,
|
||||
barWidth: '45%',
|
||||
itemStyle: { color: '#86c9f4' },
|
||||
label: { show: true, position: 'right' },
|
||||
data: dataAll.sort(),
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
yAxis: [
|
||||
{
|
||||
gridIndex: 0,
|
||||
interval: 0,
|
||||
data: barNames,
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: true },
|
||||
splitLine: { show: false },
|
||||
axisLine: { show: true },
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
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 {
|
||||
t,
|
||||
chartRef,
|
||||
docxRef,
|
||||
downloadDocx,
|
||||
docxNameRef,
|
||||
docxSizeRef,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user