feat: PDF 转换前端(epub 上传/进度轮询/下载/用户软删,复用 zTools2 API)
便携式 Vue3 前端:上传 epub 转 PDF,显示上传与转换进度,完成后下载; 用户可软删任务(不再对自己展示,管理员仍可见)。凭 cookie 标识用户。 复用 zTools2 后端 /api/pdf/*(同源),独立 i18n(中英懒加载), 可独立运行或经 mainPage iframe 同源集成。含 vitest 单测 20 项。
This commit is contained in:
46
src/i18n/index.js
Normal file
46
src/i18n/index.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import zhCN from './locales/zh-CN.js'
|
||||
|
||||
// ★ zPDF_package 独立 i18n 实例。中文同步注入(默认语言);英文动态 import() 懒加载。
|
||||
// 嵌入 mainPage 时,父项目把当前语言经 :locale prop 传入 App.vue,watch 同步到本实例,
|
||||
// 从而跟随父项目语言开关切换(不共享父的 messages,仅同步 locale 值,文案来自本子项目自有 locale)。
|
||||
// 注:组件内不用 useI18n() 注入(会解析到宿主实例),改用 ./composables/useLocale.js 直接读本实例。
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-CN',
|
||||
fallbackLocale: 'zh-CN',
|
||||
messages: {
|
||||
'zh-CN': zhCN
|
||||
}
|
||||
})
|
||||
|
||||
const loadedLocales = new Set(['zh-CN'])
|
||||
|
||||
/**
|
||||
* 懒加载并切换到目标语言。首次切换某语言时动态 import 其语言包并 mergeLocaleMessage。
|
||||
* @param {string} locale
|
||||
*/
|
||||
export async function loadLocaleAsync(locale) {
|
||||
if (i18n.global.locale.value === locale) return
|
||||
if (loadedLocales.has(locale)) {
|
||||
i18n.global.locale.value = locale
|
||||
document.documentElement.setAttribute('lang', locale)
|
||||
return
|
||||
}
|
||||
|
||||
let messages
|
||||
if (locale === 'en') {
|
||||
messages = (await import('./locales/en.js')).default
|
||||
} else {
|
||||
i18n.global.locale.value = 'zh-CN'
|
||||
document.documentElement.setAttribute('lang', 'zh-CN')
|
||||
return
|
||||
}
|
||||
|
||||
i18n.global.mergeLocaleMessage(locale, messages)
|
||||
loadedLocales.add(locale)
|
||||
i18n.global.locale.value = locale
|
||||
document.documentElement.setAttribute('lang', locale)
|
||||
}
|
||||
|
||||
export default i18n
|
||||
41
src/i18n/locales/en.js
Normal file
41
src/i18n/locales/en.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// 英文语言包 -- 通过动态 import() 加载,被打成独立 chunk,
|
||||
// 只看中文的访客不会下载此文件。
|
||||
export default {
|
||||
app: {
|
||||
title: 'PDF Converter'
|
||||
},
|
||||
upload: {
|
||||
hint: 'Drop an .epub file, or',
|
||||
pick: 'click to choose',
|
||||
limit: 'Only epub, up to 250MB',
|
||||
requireEpub: 'Only epub files are supported',
|
||||
oversize: 'File exceeds the 250MB limit',
|
||||
uploading: 'Uploading…',
|
||||
submitted: 'Submitted, converting…',
|
||||
failed: 'Upload failed',
|
||||
networkError: 'Network error'
|
||||
},
|
||||
list: {
|
||||
count: '{total} task(s)',
|
||||
empty: 'No tasks yet. Upload an epub to start.',
|
||||
loading: 'Loading…',
|
||||
loadFailed: 'Load failed: {msg}'
|
||||
},
|
||||
job: {
|
||||
name: 'Filename',
|
||||
size: 'Size',
|
||||
status: 'Status',
|
||||
created: 'Created',
|
||||
actions: 'Actions',
|
||||
statusDone: 'Done',
|
||||
statusFailed: 'Failed',
|
||||
statusConverting: 'Converting',
|
||||
statusPending: 'Queued',
|
||||
download: 'Download',
|
||||
delete: 'Delete',
|
||||
deleteConfirm: 'Delete "{name}"?\nIt will no longer be shown to you (admin can still see it; only admin hard-delete truly removes it).',
|
||||
deleted: 'Deleted',
|
||||
deleteFailed: 'Delete failed: {msg}'
|
||||
},
|
||||
refresh: 'Refresh'
|
||||
}
|
||||
40
src/i18n/locales/zh-CN.js
Normal file
40
src/i18n/locales/zh-CN.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// 中文语言包(默认语言,同步注入主 chunk)
|
||||
export default {
|
||||
app: {
|
||||
title: 'PDF 转换'
|
||||
},
|
||||
upload: {
|
||||
hint: '拖入 .epub 文件,或',
|
||||
pick: '点击选择文件',
|
||||
limit: '仅支持 epub,最大 250MB',
|
||||
requireEpub: '仅支持 epub 文件',
|
||||
oversize: '文件超过 250MB 上限',
|
||||
uploading: '上传中…',
|
||||
submitted: '已提交,转换中…',
|
||||
failed: '上传失败',
|
||||
networkError: '网络错误'
|
||||
},
|
||||
list: {
|
||||
count: '共 {total} 个任务',
|
||||
empty: '还没有任务。上传一个 epub 试试吧。',
|
||||
loading: '加载中…',
|
||||
loadFailed: '加载失败:{msg}'
|
||||
},
|
||||
job: {
|
||||
name: '文件名',
|
||||
size: '大小',
|
||||
status: '状态',
|
||||
created: '创建时间',
|
||||
actions: '操作',
|
||||
statusDone: '完成',
|
||||
statusFailed: '失败',
|
||||
statusConverting: '转换中',
|
||||
statusPending: '排队中',
|
||||
download: '下载',
|
||||
delete: '删除',
|
||||
deleteConfirm: '确定删除「{name}」?\n删除后将不再显示(管理员仍可见,需管理员彻底删除才会清除)。',
|
||||
deleted: '已删除',
|
||||
deleteFailed: '删除失败:{msg}'
|
||||
},
|
||||
refresh: '刷新'
|
||||
}
|
||||
Reference in New Issue
Block a user