Kaynağa Gözat

国际化翻译基本完成

Huanyi 2 ay önce
ebeveyn
işleme
5eb8620aa5

+ 1 - 0
locales/common/en_US.js

@@ -28,6 +28,7 @@ export default {
     error: 'Operation failed',
     loading: 'Loading...',
     noData: 'No data',
+    noMore: 'No more',
     networkError: 'Network error, please try again later'
   },
   error: {

+ 1 - 0
locales/common/zh_CN.js

@@ -28,6 +28,7 @@ export default {
     error: '操作失败',
     loading: '加载中...',
     noData: '暂无数据',
+    noMore: '没有更多了',
     networkError: '网络错误,请稍后重试'
   },
   error: {

+ 16 - 0
locales/index.js

@@ -9,6 +9,14 @@ import homeZhCN from './pages/home/zh_CN'
 import homeEnUS from './pages/home/en_US'
 import scanZhCN from './pages/scan/zh_CN'
 import scanEnUS from './pages/scan/en_US'
+import fileSelectZhCN from './pages/scan/fileSelect/zh_CN'
+import fileSelectEnUS from './pages/scan/fileSelect/en_US'
+import projectSelectZhCN from './pages/scan/projectSelect/zh_CN'
+import projectSelectEnUS from './pages/scan/projectSelect/en_US'
+import uploadZhCN from './pages/scan/upload/zh_CN'
+import uploadEnUS from './pages/scan/upload/en_US'
+import pdfViewerZhCN from './pages/scan/pdfViewer/zh_CN'
+import pdfViewerEnUS from './pages/scan/pdfViewer/en_US'
 import myZhCN from './pages/my/zh_CN'
 import myEnUS from './pages/my/en_US'
 import aggreementZhCN from './pages/my/aggreement/zh_CN'
@@ -31,6 +39,10 @@ export const messages = {
     login: loginZhCN,
     home: homeZhCN,
     scan: scanZhCN,
+    fileSelect: fileSelectZhCN,
+    projectSelect: projectSelectZhCN,
+    upload: uploadZhCN,
+    pdfViewer: pdfViewerZhCN,
     my: myZhCN,
     aggreement: aggreementZhCN,
     taskDocuments: taskDocumentsZhCN,
@@ -46,6 +58,10 @@ export const messages = {
     login: loginEnUS,
     home: homeEnUS,
     scan: scanEnUS,
+    fileSelect: fileSelectEnUS,
+    projectSelect: projectSelectEnUS,
+    upload: uploadEnUS,
+    pdfViewer: pdfViewerEnUS,
     my: myEnUS,
     aggreement: aggreementEnUS,
     taskDocuments: taskDocumentsEnUS,

+ 15 - 1
locales/pages/scan/en_US.js

@@ -12,5 +12,19 @@ export default {
   capture: 'Capture',
   importDocument: 'Import Document',
   imageImportSuccess: 'Image imported successfully',
-  documentImportSuccess: 'Document imported successfully'
+  documentImportSuccess: 'Document imported successfully',
+  processFailed: 'Process failed',
+  uploading: 'Uploading...',
+  upload: 'Upload',
+  uploadSuccess: 'Upload successful',
+  uploadFailed: 'Upload failed',
+  selectDocumentFailed: 'Failed to select document',
+  addImage: 'Please add images first',
+  scanned: 'Scanned page {count}',
+  added: 'Added document {count}',
+  deleted: 'Deleted',
+  noPdf: 'No PDF',
+  scanFailed: 'Scan failed',
+  openDocumentFailed: 'Failed to open document',
+  processPdfFailed: 'Failed to process PDF'
 }

+ 40 - 0
locales/pages/scan/fileSelect/en_US.js

@@ -0,0 +1,40 @@
+export default {
+  title: 'Select Missing File',
+  search: {
+    placeholder: 'Search file name',
+    button: 'Search'
+  },
+  fileInfo: {
+    project: 'Project',
+    folder: 'Folder',
+    createBy: 'Created by',
+    deadline: 'Deadline'
+  },
+  empty: {
+    noFiles: 'No files to submit',
+    hint: 'You can upload files directly'
+  },
+  action: {
+    directUpload: 'Direct Upload',
+    selectDate: 'Select Effective Date',
+    cancel: 'Cancel',
+    confirm: 'Confirm'
+  },
+  message: {
+    loading: 'Loading...',
+    loadFailed: 'Load failed',
+    submitting: 'Submitting...',
+    submitSuccess: 'Submit successful',
+    submitFailed: 'Submit failed',
+    selectDateFirst: 'Please select effective date',
+    noFileSelected: 'No file selected',
+    noScanFile: 'No scan file found',
+    noAvailableFile: 'No available files',
+    pleaseSelectFile: 'Please select a file'
+  },
+  dateModal: {
+    title: 'Select Effective Date',
+    label: 'Effective Date:',
+    placeholder: 'Please select date'
+  }
+}

+ 40 - 0
locales/pages/scan/fileSelect/zh_CN.js

@@ -0,0 +1,40 @@
+export default {
+  title: '请选择对应缺失文件',
+  search: {
+    placeholder: '搜索文件名',
+    button: '搜索'
+  },
+  fileInfo: {
+    project: '项目',
+    folder: '文件夹',
+    createBy: '创建人',
+    deadline: '截止日期'
+  },
+  empty: {
+    noFiles: '暂无待递交文件',
+    hint: '您可以直接上传文件'
+  },
+  action: {
+    directUpload: '直接上传',
+    selectDate: '选择生效日期',
+    cancel: '取消',
+    confirm: '确认'
+  },
+  message: {
+    loading: '加载中...',
+    loadFailed: '加载失败',
+    submitting: '提交中...',
+    submitSuccess: '提交成功',
+    submitFailed: '提交失败',
+    selectDateFirst: '请选择生效日期',
+    noFileSelected: '未选择文件',
+    noScanFile: '未找到扫描文件',
+    noAvailableFile: '暂无可选文件',
+    pleaseSelectFile: '请点击选择对应的文件'
+  },
+  dateModal: {
+    title: '选择生效日期',
+    label: '生效日期:',
+    placeholder: '请选择日期'
+  }
+}

+ 33 - 0
locales/pages/scan/pdfViewer/en_US.js

@@ -0,0 +1,33 @@
+export default {
+  title: 'PDF Management',
+  totalPages: 'Total {count} pages',
+  document: 'Document_{index}',
+  clickToPreview: 'Click to preview',
+  longPressToEdit: 'Long press to edit name',
+  previewTip: 'Click to preview · Long press to edit name',
+  empty: 'No PDF documents',
+  submit: 'Submit',
+  message: {
+    openFailed: 'Failed to open document',
+    movedUp: 'Moved up',
+    movedDown: 'Moved down',
+    deleted: 'Deleted',
+    editSuccess: 'Modified successfully',
+    addPdf: 'Please add PDF first',
+    uploadSuccess: 'Upload successful',
+    uploadFailed: 'Upload failed',
+    uploading: 'Uploading...'
+  },
+  dialog: {
+    deleteTitle: 'Confirm Delete',
+    deleteContent: 'Are you sure to delete "{name}"?',
+    deleteConfirm: 'Delete',
+    deleteCancel: 'Cancel',
+    editTitle: 'Edit File Name',
+    editPlaceholder: 'Please enter file name',
+    uploadTitle: 'Confirm Upload',
+    uploadContent: 'Will upload {count} PDF documents in current order',
+    uploadConfirm: 'Upload',
+    uploadCancel: 'Cancel'
+  }
+}

+ 33 - 0
locales/pages/scan/pdfViewer/zh_CN.js

@@ -0,0 +1,33 @@
+export default {
+  title: 'PDF管理',
+  totalPages: '共{count}页',
+  document: '文档_{index}',
+  clickToPreview: '点击预览',
+  longPressToEdit: '长按编辑名称',
+  previewTip: '点击预览 · 长按编辑名称',
+  empty: '暂无PDF文档',
+  submit: '提交',
+  message: {
+    openFailed: '打开文档失败',
+    movedUp: '已上移',
+    movedDown: '已下移',
+    deleted: '已删除',
+    editSuccess: '修改成功',
+    addPdf: '请先添加PDF',
+    uploadSuccess: '上传成功',
+    uploadFailed: '上传失败',
+    uploading: '上传中...'
+  },
+  dialog: {
+    deleteTitle: '确认删除',
+    deleteContent: '确定要删除"{name}"吗?',
+    deleteConfirm: '删除',
+    deleteCancel: '取消',
+    editTitle: '编辑文件名',
+    editPlaceholder: '请输入文件名',
+    uploadTitle: '确认上传',
+    uploadContent: '将按当前顺序上传{count}个PDF文档',
+    uploadConfirm: '上传',
+    uploadCancel: '取消'
+  }
+}

+ 19 - 0
locales/pages/scan/projectSelect/en_US.js

@@ -0,0 +1,19 @@
+export default {
+  title: 'Select Project',
+  search: {
+    placeholder: 'Search project name or code',
+    button: 'Search'
+  },
+  projectInfo: {
+    code: 'Project Code',
+    type: 'Project Type',
+    startTime: 'Start Time'
+  },
+  message: {
+    empty: 'No projects',
+    loading: 'Loading...',
+    loadFailed: 'Load failed',
+    noScanFile: 'No scan file found',
+    currentProject: 'Current Project'
+  }
+}

+ 19 - 0
locales/pages/scan/projectSelect/zh_CN.js

@@ -0,0 +1,19 @@
+export default {
+  title: '选择项目',
+  search: {
+    placeholder: '搜索项目名称或编号',
+    button: '搜索'
+  },
+  projectInfo: {
+    code: '项目编号',
+    type: '项目类型',
+    startTime: '开始时间'
+  },
+  message: {
+    empty: '暂无项目',
+    loading: '加载中...',
+    loadFailed: '加载失败',
+    noScanFile: '未找到扫描文件',
+    currentProject: '当前项目'
+  }
+}

+ 25 - 0
locales/pages/scan/upload/en_US.js

@@ -0,0 +1,25 @@
+export default {
+  title: 'Upload',
+  form: {
+    countryCenter: 'Country - Center',
+    selectCountryCenter: 'Please select country and center',
+    name: 'Name',
+    documentName: 'Enter document name',
+    effectiveDate: 'Enter effective date',
+    namePreview: 'Full Name Preview',
+    submit: 'Submit'
+  },
+  message: {
+    loading: 'Loading...',
+    loadFailed: 'Load failed',
+    selectCountry: 'Please select country',
+    selectCenter: 'Please select center',
+    inputDocumentName: 'Please enter document name',
+    inputEffectiveDate: 'Please enter effective date',
+    noScanFile: 'No scan file found',
+    submitting: 'Submitting...',
+    submitSuccess: 'Submit successful',
+    submitFailed: 'Submit failed',
+    noHyphen: 'Document name cannot contain "-" character'
+  }
+}

+ 25 - 0
locales/pages/scan/upload/zh_CN.js

@@ -0,0 +1,25 @@
+export default {
+  title: '上传',
+  form: {
+    countryCenter: '国家 - 中心',
+    selectCountryCenter: '请选择国家和中心',
+    name: '名称',
+    documentName: '请输入具体文档名',
+    effectiveDate: '请输入生效日期',
+    namePreview: '完整名称预览',
+    submit: '提交'
+  },
+  message: {
+    loading: '加载中...',
+    loadFailed: '加载失败',
+    selectCountry: '请选择国家',
+    selectCenter: '请选择中心',
+    inputDocumentName: '请输入具体文档名',
+    inputEffectiveDate: '请输入生效日期',
+    noScanFile: '未找到扫描文件',
+    submitting: '提交中...',
+    submitSuccess: '提交成功',
+    submitFailed: '提交失败',
+    noHyphen: '文档名称不能包含"-"字符'
+  }
+}

+ 15 - 1
locales/pages/scan/zh_CN.js

@@ -12,5 +12,19 @@ export default {
   capture: '拍照',
   importDocument: '导入文档',
   imageImportSuccess: '图片导入成功',
-  documentImportSuccess: '文档导入成功'
+  documentImportSuccess: '文档导入成功',
+  processFailed: '处理失败',
+  uploading: '上传中...',
+  upload: '上传',
+  uploadSuccess: '上传成功',
+  uploadFailed: '上传失败',
+  selectDocumentFailed: '选择文档失败',
+  addImage: '请先添加图片',
+  scanned: '已扫描第{count}页',
+  added: '已添加第{count}个文档',
+  deleted: '已删除',
+  noPdf: '暂无PDF',
+  scanFailed: '扫描失败',
+  openDocumentFailed: '打开文档失败',
+  processPdfFailed: '处理PDF失败'
 }

+ 1 - 1
pages.json

@@ -59,7 +59,7 @@
       }
     },
     {
-      "path": "pages/scan/folderSelect/index",
+      "path": "pages/scan/upload/index",
       "style": {
         "navigationStyle": "custom",
         "enablePullDownRefresh": false

+ 4 - 4
pages/home/index.vue

@@ -89,7 +89,7 @@
           
           <!-- 没有更多数据 -->
           <view v-if="!hasMore && recentDocuments.length > 0" class="no-more">
-            <text class="no-more-text">没有更多了</text>
+            <text class="no-more-text">{{ t('common.message.noMore') }}</text>
           </view>
           
           <!-- 空状态 -->
@@ -539,14 +539,14 @@ const handleDocumentClick = (doc) => {
             display: flex;
             flex-direction: column;
             gap: 12rpx;
+            min-width: 0;
             
             .doc-name {
               font-size: 28rpx;
               font-weight: 500;
               color: #333333;
-              overflow: hidden;
-              text-overflow: ellipsis;
-              white-space: nowrap;
+              word-break: break-all;
+              line-height: 1.5;
             }
             
             .doc-meta {

+ 7 - 7
pages/my/aggreement/detail.vue

@@ -43,7 +43,7 @@ const loading = ref(false)
 
 // 页面标题
 const pageTitle = computed(() => {
-  return agreementType.value === 'user' ? '用户协议' : '隐私政策'
+  return agreementType.value === 'user' ? t('aggreement.userAgreementTitle') : t('aggreement.privacyPolicyTitle')
 })
 
 
@@ -80,7 +80,7 @@ const fetchAgreementContent = async () => {
     
     // 显示加载提示
     uni.showLoading({
-      title: '加载中...',
+      title: t('aggreement.loading'),
       mask: true
     })
     
@@ -114,7 +114,7 @@ const fetchAgreementContent = async () => {
     console.error('获取协议内容失败:', error)
     
     uni.showToast({
-      title: error.message || '获取协议内容失败',
+      title: error.message || t('aggreement.loadFailed'),
       icon: 'none',
       duration: 2000
     })
@@ -132,15 +132,15 @@ const getDefaultContent = () => {
   if (agreementType.value === 'user') {
     return `
       <div style="padding: 20px; line-height: 1.8; color: #333;">
-        <h2 style="text-align: center; color: #1ec9c9; margin-bottom: 20px;">用户服务协议</h2>
-        <p>协议内容加载失败,请稍后重试。</p>
+        <h2 style="text-align: center; color: #1ec9c9; margin-bottom: 20px;">${t('aggreement.userAgreementTitle')}</h2>
+        <p>${t('aggreement.loadFailed')}</p>
       </div>
     `
   } else {
     return `
       <div style="padding: 20px; line-height: 1.8; color: #333;">
-        <h2 style="text-align: center; color: #1ec9c9; margin-bottom: 20px;">隐私政策</h2>
-        <p>协议内容加载失败,请稍后重试。</p>
+        <h2 style="text-align: center; color: #1ec9c9; margin-bottom: 20px;">${t('aggreement.privacyPolicyTitle')}</h2>
+        <p>${t('aggreement.loadFailed')}</p>
       </div>
     `
   }

+ 29 - 26
pages/scan/fileSelect/index.vue

@@ -6,7 +6,7 @@
         <view class="back-btn" @click="handleBack">
           <text class="back-icon">‹</text>
         </view>
-        <text class="header-title">请选择对应缺失文件</text>
+        <text class="header-title">{{ t('fileSelect.title') }}</text>
         <view class="placeholder"></view>
       </view>
     </view>
@@ -16,11 +16,11 @@
       <input 
         class="search-input" 
         v-model="searchName" 
-        placeholder="搜索文件名"
+        :placeholder="t('fileSelect.search.placeholder')"
         @confirm="handleSearch"
       />
       <view class="search-btn" @click="handleSearch">
-        <text class="search-text">搜索</text>
+        <text class="search-text">{{ t('fileSelect.search.button') }}</text>
       </view>
     </view>
     
@@ -41,21 +41,21 @@
         </view>
         <view class="file-info">
           <text class="file-name">{{ item.name }}</text>
-          <text class="file-detail">项目: {{ item.project }}</text>
-          <text class="file-detail">文件夹: {{ item.folder }}</text>
-          <text class="file-detail">创建人: {{ item.createBy }}</text>
-          <text class="file-detail">截止日期: {{ formatDate(item.deadline) }}</text>
+          <text class="file-detail">{{ t('fileSelect.fileInfo.project') }}: {{ item.project }}</text>
+          <text class="file-detail">{{ t('fileSelect.fileInfo.folder') }}: {{ item.folder }}</text>
+          <text class="file-detail">{{ t('fileSelect.fileInfo.createBy') }}: {{ item.createBy }}</text>
+          <text class="file-detail">{{ t('fileSelect.fileInfo.deadline') }}: {{ formatDate(item.deadline) }}</text>
         </view>
 
       </view>
       
       <view v-if="fileList.length === 0 && !loading" class="empty-tip">
-        <text class="empty-text">暂无待递交文件</text>
-        <text class="empty-hint">您可以直接上传文件</text>
+        <text class="empty-text">{{ t('fileSelect.empty.noFiles') }}</text>
+        <text class="empty-hint">{{ t('fileSelect.empty.hint') }}</text>
       </view>
       
       <view v-if="loading" class="loading-tip">
-        <text class="loading-text">加载中...</text>
+        <text class="loading-text">{{ t('fileSelect.message.loading') }}</text>
       </view>
     </scroll-view>
     
@@ -65,7 +65,7 @@
         class="submit-btn secondary" 
         @click="handleDirectUpload"
       >
-        <text class="submit-text">直接上传</text>
+        <text class="submit-text">{{ t('fileSelect.action.directUpload') }}</text>
       </view>
     </view>
     
@@ -73,7 +73,7 @@
     <view v-if="showDateModal" class="modal-overlay" @click="handleCloseModal">
       <view class="modal-content" @click.stop>
         <view class="modal-header">
-          <text class="modal-title">选择生效日期</text>
+          <text class="modal-title">{{ t('fileSelect.dateModal.title') }}</text>
         </view>
         
         <view class="modal-body">
@@ -84,9 +84,9 @@
               @change="handleDateChange"
             >
               <view class="date-display">
-                <text class="date-label">生效日期:</text>
+                <text class="date-label">{{ t('fileSelect.dateModal.label') }}</text>
                 <text class="date-value" :class="{ placeholder: !selectedDate }">
-                  {{ selectedDate || '请选择日期' }}
+                  {{ selectedDate || t('fileSelect.dateModal.placeholder') }}
                 </text>
                 <text class="date-arrow">›</text>
               </view>
@@ -96,10 +96,10 @@
         
         <view class="modal-footer">
           <view class="modal-btn cancel" @click="handleCloseModal">
-            <text class="modal-btn-text">取消</text>
+            <text class="modal-btn-text">{{ t('fileSelect.action.cancel') }}</text>
           </view>
           <view class="modal-btn confirm" @click="handleConfirmDate">
-            <text class="modal-btn-text">确认</text>
+            <text class="modal-btn-text">{{ t('fileSelect.action.confirm') }}</text>
           </view>
         </view>
       </view>
@@ -109,8 +109,11 @@
 
 <script setup>
 import { ref, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
 import { getToSubmitList, uploadOnSubmit } from '@/apis/scan'
 
+const { t } = useI18n()
+
 // 状态栏高度
 const statusBarHeight = ref(0)
 
@@ -165,7 +168,7 @@ const loadFileList = async () => {
   } catch (error) {
     console.error('加载文件列表失败:', error)
     uni.showToast({
-      title: '加载失败',
+      title: t('fileSelect.message.loadFailed'),
       icon: 'none'
     })
   } finally {
@@ -212,7 +215,7 @@ const handleDateChange = (e) => {
 const handleConfirmDate = async () => {
   if (!selectedDate.value) {
     uni.showToast({
-      title: '请选择生效日期',
+      title: t('fileSelect.message.selectDateFirst'),
       icon: 'none'
     })
     return
@@ -220,7 +223,7 @@ const handleConfirmDate = async () => {
   
   if (!selectedFile.value) {
     uni.showToast({
-      title: '未选择文件',
+      title: t('fileSelect.message.noFileSelected'),
       icon: 'none'
     })
     return
@@ -232,7 +235,7 @@ const handleConfirmDate = async () => {
     
     if (!fileBase64List || fileBase64List.length === 0) {
       uni.showToast({
-        title: '未找到扫描文件',
+        title: t('fileSelect.message.noScanFile'),
         icon: 'none'
       })
       return
@@ -242,7 +245,7 @@ const handleConfirmDate = async () => {
     showDateModal.value = false
     
     uni.showLoading({
-      title: '提交中...',
+      title: t('fileSelect.message.submitting'),
       mask: true
     })
     
@@ -260,7 +263,7 @@ const handleConfirmDate = async () => {
       getApp().globalData.scannedFileBase64List = null
       
       uni.showToast({
-        title: '提交成功',
+        title: t('fileSelect.message.submitSuccess'),
         icon: 'success',
         duration: 2000
       })
@@ -278,7 +281,7 @@ const handleConfirmDate = async () => {
     uni.hideLoading()
     console.error('提交失败:', error)
     uni.showToast({
-      title: error.message || '提交失败',
+      title: t('fileSelect.message.submitFailed'),
       icon: 'none'
     })
   }
@@ -288,14 +291,14 @@ const handleConfirmDate = async () => {
 const handleSubmitAll = () => {
   if (fileList.value.length === 0) {
     uni.showToast({
-      title: '暂无可选文件',
+      title: t('fileSelect.message.noAvailableFile'),
       icon: 'none'
     })
     return
   }
   
   uni.showToast({
-    title: '请点击选择对应的文件',
+    title: t('fileSelect.message.pleaseSelectFile'),
     icon: 'none'
   })
 }
@@ -307,7 +310,7 @@ const handleDirectUpload = () => {
   
   if (!fileBase64List || fileBase64List.length === 0) {
     uni.showToast({
-      title: '未找到扫描文件',
+      title: t('fileSelect.message.noScanFile'),
       icon: 'none'
     })
     return

+ 37 - 37
pages/scan/index.vue

@@ -6,7 +6,7 @@
         <view class="back-btn" @click="handleBack">
           <text class="back-icon">‹</text>
         </view>
-        <text class="header-title">小程序扫描</text>
+        <text class="header-title">{{ t('scan.title') }}</text>
         <view class="placeholder"></view>
       </view>
     </view>
@@ -29,14 +29,14 @@
             :class="{ active: scanMode === 'single' }"
             @click="switchToSingle"
           >
-            <text class="mode-text">单页</text>
+            <text class="mode-text">{{ t('scan.singlePage') }}</text>
           </view>
           <view 
             class="mode-btn" 
             :class="{ active: scanMode === 'multiple' }"
             @click="switchToMultiple"
           >
-            <text class="mode-text">多页</text>
+            <text class="mode-text">{{ t('scan.multiplePage') }}</text>
           </view>
         </view>
       </view>
@@ -69,7 +69,7 @@
         class="upload-btn"
         @click="handleMultipleUpload"
       >
-        <text class="upload-text">上传</text>
+        <text class="upload-text">{{ t('scan.upload') }}</text>
       </view>
       
       <!-- PDF缩略图预览(右下角) -->
@@ -85,7 +85,7 @@
       <view class="action-buttons">
         <view class="action-btn" @click="handleSelectImage">
           <image class="btn-icon" src="/static/pages/scan/import-pic.svg" mode="aspectFit" />
-          <text class="btn-text">导入图片</text>
+          <text class="btn-text">{{ t('scan.importImage') }}</text>
         </view>
         
         <view class="capture-btn" @click="handleCapture">
@@ -94,7 +94,7 @@
         
         <view class="action-btn" @click="handleSelectFile">
           <image class="btn-icon" src="/static/pages/scan/import-doc.svg" mode="aspectFit" />
-          <text class="btn-text">导入文档</text>
+          <text class="btn-text">{{ t('scan.importDocument') }}</text>
         </view>
       </view>
     </view>
@@ -176,7 +176,7 @@ const switchToSingle = () => {
   scanMode.value = 'single'
   
   uni.showToast({
-    title: '已切换到单页模式',
+    title: t('scan.switchToSingle'),
     icon: 'none',
     duration: 1500
   })
@@ -188,7 +188,7 @@ const switchToMultiple = () => {
   scanMode.value = 'multiple'
   
   uni.showToast({
-    title: '已切换到多页模式',
+    title: t('scan.switchToMultiple'),
     icon: 'none',
     duration: 1500
   })
@@ -198,7 +198,7 @@ const switchToMultiple = () => {
 const handleCameraError = (e) => {
   console.error('相机错误:', e)
   uni.showToast({
-    title: '相机启动失败',
+    title: t('scan.cameraError'),
     icon: 'none'
   })
 }
@@ -212,7 +212,7 @@ const handleCapture = () => {
     success: async (res) => {
       try {
         uni.showLoading({
-          title: '处理中..',
+          title: t('scan.processing'),
           mask: true
         })
         
@@ -230,7 +230,7 @@ const handleCapture = () => {
         uni.hideLoading()
         console.error('处理图片失败:', error)
         uni.showToast({
-          title: '处理失败',
+          title: t('scan.processFailed'),
           icon: 'none'
         })
       }
@@ -238,7 +238,7 @@ const handleCapture = () => {
     fail: (err) => {
       console.error('拍照失败:', err)
       uni.showToast({
-        title: '拍照失败',
+        title: t('scan.captureFailed'),
         icon: 'none'
       })
     }
@@ -254,7 +254,7 @@ const handleSelectImage = async () => {
     success: async (res) => {
       try {
         uni.showLoading({
-          title: '处理�?..',
+          title: t('scan.processing'),
           mask: true
         })
         
@@ -272,7 +272,7 @@ const handleSelectImage = async () => {
         uni.hideLoading()
         console.error('处理图片失败:', error)
         uni.showToast({
-          title: '处理失败',
+          title: t('scan.processFailed'),
           icon: 'none'
         })
       }
@@ -289,7 +289,7 @@ const handleSelectFile = () => {
     success: async (res) => {
       try {
         uni.showLoading({
-          title: '处理中...',
+          title: t('scan.processing'),
           mask: true
         })
         
@@ -309,7 +309,7 @@ const handleSelectFile = () => {
         uni.hideLoading()
         console.error('处理文档失败:', error)
         uni.showToast({
-          title: '处理失败',
+          title: t('scan.processFailed'),
           icon: 'none'
         })
       }
@@ -317,7 +317,7 @@ const handleSelectFile = () => {
     fail: (err) => {
       console.error('选择文档失败:', err)
       uni.showToast({
-        title: '选择文档失败',
+        title: t('scan.selectDocumentFailed'),
         icon: 'none'
       })
     }
@@ -349,7 +349,7 @@ const handleDocumentUpload = async (base64Data) => {
     uni.hideLoading()
     
     uni.showToast({
-      title: '文档导入成功',
+      title: t('scan.documentImportSuccess'),
       icon: 'success',
       duration: 1500
     })
@@ -364,7 +364,7 @@ const handleDocumentUpload = async (base64Data) => {
     uni.hideLoading()
     console.error('处理文档失败:', error)
     uni.showToast({
-      title: error.message || '处理失败',
+      title: error.message || t('scan.processFailed'),
       icon: 'none'
     })
   }
@@ -386,7 +386,7 @@ const handleDocumentInMultipleMode = async (base64Data, fileName) => {
     uni.hideLoading()
     
     uni.showToast({
-      title: `已添加第${pdfDataList.value.length}个文档`,
+      title: t('scan.added', { count: pdfDataList.value.length }),
       icon: 'success',
       duration: 1500
     })
@@ -394,7 +394,7 @@ const handleDocumentInMultipleMode = async (base64Data, fileName) => {
     uni.hideLoading()
     console.error('处理文档失败:', error)
     uni.showToast({
-      title: error.message || '处理失败',
+      title: error.message || t('scan.processFailed'),
       icon: 'none'
     })
   }
@@ -443,19 +443,19 @@ const uploadSingleImage = async (base64Data) => {
         })
       } else {
         uni.showToast({
-          title: '上传成功',
+          title: t('scan.uploadSuccess'),
           icon: 'success',
           duration: 2000
         })
       }
     } else {
-      throw new Error(response.msg || '上传失败')
+      throw new Error(response.msg || t('scan.uploadFailed'))
     }
   } catch (error) {
     uni.hideLoading()
     console.error('上传失败:', error)
     uni.showToast({
-      title: error.message || '上传失败',
+      title: error.message || t('scan.uploadFailed'),
       icon: 'none'
     })
   }
@@ -465,7 +465,7 @@ const uploadSingleImage = async (base64Data) => {
 const handleMultipleUpload = async () => {
   if (imageBase64List.value.length === 0) {
     uni.showToast({
-      title: '请先添加图片',
+      title: t('scan.addImage'),
       icon: 'none'
     })
     return
@@ -473,7 +473,7 @@ const handleMultipleUpload = async () => {
   
   try {
     uni.showLoading({
-      title: '上传中...',
+      title: t('scan.uploading'),
       mask: true
     })
     
@@ -497,19 +497,19 @@ const handleMultipleUpload = async () => {
         await handlePdfPreview(response.data.fileBase64)
       } else {
         uni.showToast({
-          title: '上传成功',
+          title: t('scan.uploadSuccess'),
           icon: 'success',
           duration: 2000
         })
       }
     } else {
-      throw new Error(response.msg || '上传失败')
+      throw new Error(response.msg || t('scan.uploadFailed'))
     }
   } catch (error) {
     uni.hideLoading()
     console.error('上传失败:', error)
     uni.showToast({
-      title: error.message || '上传失败',
+      title: error.message || t('scan.uploadFailed'),
       icon: 'none'
     })
   }
@@ -540,7 +540,7 @@ const uploadAndScanImage = async (base64Data) => {
       })
       
       uni.showToast({
-        title: `已扫描第${pdfDataList.value.length}页`,
+        title: t('scan.scanned', { count: pdfDataList.value.length }),
         icon: 'success',
         duration: 1500
       })
@@ -551,7 +551,7 @@ const uploadAndScanImage = async (base64Data) => {
     uni.hideLoading()
     console.error('扫描失败:', error)
     uni.showToast({
-      title: error.message || '扫描失败',
+      title: t('scan.scanFailed'),
       icon: 'none'
     })
   }
@@ -563,7 +563,7 @@ const handleDeleteImage = (index) => {
   imageTempPaths.value.splice(index, 1)
   
   uni.showToast({
-    title: '已删除',
+    title: t('scan.deleted'),
     icon: 'success',
     duration: 1000
   })
@@ -574,7 +574,7 @@ const handleDeletePdf = (index) => {
   pdfDataList.value.splice(index, 1)
   
   uni.showToast({
-    title: '已删除',
+    title: t('scan.deleted'),
     icon: 'success',
     duration: 1000
   })
@@ -584,7 +584,7 @@ const handleDeletePdf = (index) => {
 const handleViewAllPdf = () => {
   if (pdfDataList.value.length === 0) {
     uni.showToast({
-      title: '暂无PDF',
+      title: t('scan.noPdf'),
       icon: 'none'
     })
     return
@@ -607,14 +607,14 @@ const handlePdfPreview = async (base64Data) => {
     showPdfThumbnail.value = true
     
     uni.showToast({
-      title: '上传成功',
+      title: t('scan.uploadSuccess'),
       icon: 'success',
       duration: 2000
     })
   } catch (error) {
     console.error('处理PDF失败:', error)
     uni.showToast({
-      title: '处理PDF失败',
+      title: t('scan.processPdfFailed'),
       icon: 'none'
     })
   }
@@ -655,7 +655,7 @@ const handleOpenPdf = () => {
     fail: (err) => {
       console.error('打开文档失败:', err)
       uni.showToast({
-        title: '打开文档失败',
+        title: t('scan.openDocumentFailed'),
         icon: 'none'
       })
     }

+ 34 - 29
pages/scan/pdfViewer/index.vue

@@ -6,7 +6,7 @@
         <view class="back-btn" @click="handleBack">
           <text class="back-icon">‹</text>
         </view>
-        <text class="header-title">PDF管理 (共{{ pdfList.length }}页)</text>
+        <text class="header-title">{{ t('pdfViewer.title') }} ({{ t('pdfViewer.totalPages', { count: pdfList.length }) }})</text>
         <view class="placeholder"></view>
       </view>
     </view>
@@ -22,8 +22,8 @@
           <image src="/static/icon/pdf.svg" mode="aspectFit" class="pdf-icon" />
         </view>
         <view class="pdf-info" @click="handlePreviewPdf(item.path, index)" @longpress="handleEditName(index)">
-          <text class="pdf-name">{{ item.name || `文档_${index + 1}` }}</text>
-          <text class="pdf-tip">点击预览 · 长按编辑名称</text>
+          <text class="pdf-name">{{ item.name || t('pdfViewer.document', { index: index + 1 }) }}</text>
+          <text class="pdf-tip">{{ t('pdfViewer.previewTip') }}</text>
         </view>
         
         <!-- 操作按钮 -->
@@ -49,23 +49,26 @@
       </view>
       
       <view v-if="pdfList.length === 0" class="empty-tip">
-        <text class="empty-text">暂无PDF文档</text>
+        <text class="empty-text">{{ t('pdfViewer.empty') }}</text>
       </view>
     </scroll-view>
     
     <!-- 底部提交按钮 -->
     <view class="submit-footer">
       <view class="submit-btn" @click="handleSubmit">
-        <text class="submit-text">提交</text>
+        <text class="submit-text">{{ t('pdfViewer.submit') }}</text>
       </view>
     </view>
   </view>
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue'
+import { ref, onMounted, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
 import { scanUploadBatch } from '@/apis/scan'
 
+const { t } = useI18n()
+
 // 状态栏高度
 const statusBarHeight = ref(0)
 
@@ -90,7 +93,7 @@ onMounted(() => {
       id: generateId(),
       path: item.path,
       base64: item.base64,
-      name: item.name || `文档_${Date.now()}`
+      name: item.name || t('pdfViewer.document', { index: Date.now() })
     }))
   }
 })
@@ -112,7 +115,7 @@ const handlePreviewPdf = (path, index) => {
     fail: (err) => {
       console.error('打开文档失败:', err)
       uni.showToast({
-        title: '打开文档失败',
+        title: t('pdfViewer.message.openFailed'),
         icon: 'none'
       })
     }
@@ -131,7 +134,7 @@ const handleMoveUp = (index) => {
   pdfList.value = [...pdfList.value]
   
   uni.showToast({
-    title: '已上移',
+    title: t('pdfViewer.message.movedUp'),
     icon: 'success',
     duration: 1000
   })
@@ -149,7 +152,7 @@ const handleMoveDown = (index) => {
   pdfList.value = [...pdfList.value]
   
   uni.showToast({
-    title: '已下移',
+    title: t('pdfViewer.message.movedDown'),
     icon: 'success',
     duration: 1000
   })
@@ -157,17 +160,19 @@ const handleMoveDown = (index) => {
 
 // 删除
 const handleDelete = (index) => {
+  const itemName = pdfList.value[index].name || t('pdfViewer.document', { index: index + 1 })
+  
   uni.showModal({
-    title: '确认删除',
-    content: `确定要删除"${pdfList.value[index].name || `文档_${index + 1}`}"吗?`,
-    confirmText: '删除',
-    cancelText: '取消',
+    title: t('pdfViewer.dialog.deleteTitle'),
+    content: t('pdfViewer.dialog.deleteContent', { name: itemName }),
+    confirmText: t('pdfViewer.dialog.deleteConfirm'),
+    cancelText: t('pdfViewer.dialog.deleteCancel'),
     success: (res) => {
       if (res.confirm) {
         pdfList.value.splice(index, 1)
         
         uni.showToast({
-          title: '已删除',
+          title: t('pdfViewer.message.deleted'),
           icon: 'success',
           duration: 1000
         })
@@ -178,19 +183,19 @@ const handleDelete = (index) => {
 
 // 编辑文件名
 const handleEditName = (index) => {
-  const currentName = pdfList.value[index].name || `文档_${index + 1}`
+  const currentName = pdfList.value[index].name || t('pdfViewer.document', { index: index + 1 })
   
   uni.showModal({
-    title: '编辑文件名',
+    title: t('pdfViewer.dialog.editTitle'),
     content: currentName,
     editable: true,
-    placeholderText: '请输入文件名',
+    placeholderText: t('pdfViewer.dialog.editPlaceholder'),
     success: (res) => {
       if (res.confirm && res.content && res.content.trim()) {
         pdfList.value[index].name = res.content.trim()
         
         uni.showToast({
-          title: '修改成功',
+          title: t('pdfViewer.message.editSuccess'),
           icon: 'success',
           duration: 1000
         })
@@ -203,7 +208,7 @@ const handleEditName = (index) => {
 const handleSubmit = () => {
   if (pdfList.value.length === 0) {
     uni.showToast({
-      title: '请先添加PDF',
+      title: t('pdfViewer.message.addPdf'),
       icon: 'none'
     })
     return
@@ -225,22 +230,22 @@ const handleSubmit = () => {
 const handleUploadAll = async () => {
   if (pdfList.value.length === 0) {
     uni.showToast({
-      title: '请先添加PDF',
+      title: t('pdfViewer.message.addPdf'),
       icon: 'none'
     })
     return
   }
   
   uni.showModal({
-    title: '确认上传',
-    content: `将按当前顺序上传${pdfList.value.length}个PDF文档`,
-    confirmText: '上传',
-    cancelText: '取消',
+    title: t('pdfViewer.dialog.uploadTitle'),
+    content: t('pdfViewer.dialog.uploadContent', { count: pdfList.value.length }),
+    confirmText: t('pdfViewer.dialog.uploadConfirm'),
+    cancelText: t('pdfViewer.dialog.uploadCancel'),
     success: async (res) => {
       if (res.confirm) {
         try {
           uni.showLoading({
-            title: '上传中...',
+            title: t('pdfViewer.message.uploading'),
             mask: true
           })
           
@@ -256,7 +261,7 @@ const handleUploadAll = async () => {
           
           if (response.code === 200 && response.data) {
             uni.showToast({
-              title: '上传成功',
+              title: t('pdfViewer.message.uploadSuccess'),
               icon: 'success',
               duration: 2000
             })
@@ -266,13 +271,13 @@ const handleUploadAll = async () => {
               uni.navigateBack()
             }, 2000)
           } else {
-            throw new Error(response.msg || '上传失败')
+            throw new Error(response.msg || t('pdfViewer.message.uploadFailed'))
           }
         } catch (error) {
           uni.hideLoading()
           console.error('上传失败:', error)
           uni.showToast({
-            title: error.message || '上传失败',
+            title: error.message || t('pdfViewer.message.uploadFailed'),
             icon: 'none'
           })
         }

+ 13 - 13
pages/scan/projectSelect/index.vue

@@ -6,7 +6,7 @@
         <view class="back-btn" @click="handleBack">
           <text class="back-icon">‹</text>
         </view>
-        <text class="header-title">选择项目</text>
+        <text class="header-title">{{ t('projectSelect.title') }}</text>
         <view class="placeholder"></view>
       </view>
     </view>
@@ -16,11 +16,11 @@
       <input 
         class="search-input" 
         v-model="searchName" 
-        placeholder="搜索项目名称或编号"
+        :placeholder="t('projectSelect.search.placeholder')"
         @confirm="handleSearch"
       />
       <view class="search-btn" @click="handleSearch">
-        <text class="search-text">搜索</text>
+        <text class="search-text">{{ t('projectSelect.search.button') }}</text>
       </view>
     </view>
     
@@ -52,18 +52,18 @@
         </view>
         <view class="project-info">
           <text class="project-name">{{ item.name }}</text>
-          <text class="project-detail">项目编号: {{ item.code }}</text>
-          <text class="project-detail">项目类型: {{ getProjectTypeLabel(item.type) }}</text>
-          <text class="project-detail">开始时间: {{ formatDate(item.startTime) }}</text>
+          <text class="project-detail">{{ t('projectSelect.projectInfo.code') }}: {{ item.code }}</text>
+          <text class="project-detail">{{ t('projectSelect.projectInfo.type') }}: {{ getProjectTypeLabel(item.type) }}</text>
+          <text class="project-detail">{{ t('projectSelect.projectInfo.startTime') }}: {{ formatDate(item.startTime) }}</text>
         </view>
       </view>
       
       <view v-if="projectList.length === 0 && !loading" class="empty-tip">
-        <text class="empty-text">暂无项目</text>
+        <text class="empty-text">{{ t('projectSelect.message.empty') }}</text>
       </view>
       
       <view v-if="loading" class="loading-tip">
-        <text class="loading-text">加载中...</text>
+        <text class="loading-text">{{ t('projectSelect.message.loading') }}</text>
       </view>
     </scroll-view>
   </view>
@@ -75,7 +75,7 @@ import { useI18n } from 'vue-i18n'
 import { getProjectList } from '@/apis/scan'
 import { getDictDataByType } from '@/apis/dict'
 
-const { locale } = useI18n()
+const { locale, t } = useI18n()
 
 // 状态栏高度
 const statusBarHeight = ref(0)
@@ -179,7 +179,7 @@ const loadProjectList = async () => {
   } catch (error) {
     console.error('加载项目列表失败:', error)
     uni.showToast({
-      title: '加载失败',
+      title: t('projectSelect.message.loadFailed'),
       icon: 'none'
     })
   } finally {
@@ -211,15 +211,15 @@ const handleSelectProject = async (project) => {
   
   if (!fileBase64List || fileBase64List.length === 0) {
     uni.showToast({
-      title: '未找到扫描文件',
+      title: t('projectSelect.message.noScanFile'),
       icon: 'none'
     })
     return
   }
   
-  // 跳转到文件夹选择页面
+  // 跳转到上传页面
   uni.navigateTo({
-    url: `/pages/scan/folderSelect/index?projectId=${project.id}&projectName=${encodeURIComponent(project.name)}&projectCode=${encodeURIComponent(project.code)}`
+    url: `/pages/scan/upload/index?projectId=${project.id}&projectName=${encodeURIComponent(project.name)}&projectCode=${encodeURIComponent(project.code)}`
   })
 }
 

+ 0 - 0
pages/scan/folderSelect/components/FolderTreeItem.vue → pages/scan/upload/components/FolderTreeItem.vue


+ 30 - 25
pages/scan/folderSelect/index.vue → pages/scan/upload/index.vue

@@ -6,27 +6,27 @@
         <view class="back-btn" @click="handleBack">
           <text class="back-icon">‹</text>
         </view>
-        <text class="header-title">选择文件夹</text>
+        <text class="header-title">{{ t('upload.title') }}</text>
         <view class="placeholder"></view>
       </view>
     </view>
     
     <!-- 项目信息 -->
     <view class="project-info-bar">
-      <text class="project-label">当前项目:</text>
+      <text class="project-label">{{ t('projectSelect.message.currentProject') }}:</text>
       <text class="project-name">{{ projectName }}</text>
     </view>
     
     <!-- 选择表单 -->
     <view class="form-container">
       <view v-if="loading" class="loading-tip">
-        <text class="loading-text">加载中...</text>
+        <text class="loading-text">{{ t('upload.message.loading') }}</text>
       </view>
       
       <view v-else class="form-content">
         <!-- 国家-中心联动选择 -->
         <view class="form-item">
-          <view class="form-label">国家 - 中心:</view>
+          <view class="form-label">{{ t('upload.form.countryCenter') }}:</view>
           <picker 
             mode="multiSelector" 
             :range="pickerRange"
@@ -45,12 +45,12 @@
         
         <!-- 名称和生效日期合并 -->
         <view class="form-item highlight-item">
-          <view class="form-label required">名称:</view>
+          <view class="form-label required">{{ t('upload.form.name') }}:</view>
           <view class="input-wrapper highlight">
             <input
               v-model="documentName"
               type="text"
-              placeholder="请输入具体文档名"
+              :placeholder="t('upload.form.documentName')"
               class="input-field"
               @input="handleDocumentNameInput"
             />
@@ -63,14 +63,14 @@
             >
               <view class="picker-display">
                 <text class="picker-text" :class="{ placeholder: !effectiveDate }">
-                  {{ effectiveDate || '请输入生效日期' }}
+                  {{ effectiveDate || t('upload.form.effectiveDate') }}
                 </text>
                 <text class="picker-arrow">›</text>
               </view>
             </picker>
           </view>
           <view class="final-name-preview">
-            <text class="preview-label">完整名称预览:</text>
+            <text class="preview-label">{{ t('upload.form.namePreview') }}:</text>
             <text class="preview-text">{{ getFinalName() }}</text>
           </view>
         </view>
@@ -81,7 +81,7 @@
           :disabled="selectedCountryIndex < 0 || selectedCenterIndex < 0 || !documentName.trim()"
           @click="handleSubmit"
         >
-          提交
+          {{ t('upload.form.submit') }}
         </button>
 		</view>
     </view>
@@ -90,8 +90,13 @@
 
 <script>
 import { getFolderList, uploadScanFile } from '@/apis/scan'
+import { useI18n } from 'vue-i18n'
 
 export default {
+  setup() {
+    const { t } = useI18n()
+    return { t }
+  },
   data() {
     return {
       statusBarHeight: 0,
@@ -177,7 +182,7 @@ export default {
       } catch (error) {
         console.error('加载失败:', error)
         uni.showToast({
-          title: '加载失败',
+          title: this.t('upload.message.loadFailed'),
           icon: 'none'
         })
       } finally {
@@ -290,7 +295,7 @@ export default {
           return `${country.name} - ${centerName}`
         }
       }
-      return '请选择国家和中心'
+      return this.t('upload.form.selectCountryCenter')
     },
     
     // 日期选择变化
@@ -310,7 +315,7 @@ export default {
         
         // 提示用户
         uni.showToast({
-          title: '文档名称不能包含"-"字符',
+          title: this.t('upload.message.noHyphen'),
           icon: 'none',
           duration: 1500
         })
@@ -363,8 +368,8 @@ export default {
       const center = this.centerList[this.selectedCenterIndex]
       const centerId = center && center.id !== 'NA' ? center.id : 'NA'
       
-      const docName = this.documentName.trim() || '[请输入具体文档名]'
-      const date = this.formatDate(this.effectiveDate) || '[请输入生效日期]'
+      const docName = this.documentName.trim() || `[${this.t('upload.form.documentName')}]`
+      const date = this.formatDate(this.effectiveDate) || `[${this.t('upload.form.effectiveDate')}]`
       
       return `${projectCode}-${countryName}-${centerId}-${docName}-${date}`
     },
@@ -380,8 +385,8 @@ export default {
       const center = this.centerList[this.selectedCenterIndex]
       const centerId = center && center.id !== 'NA' ? center.id : ''
       
-      const docName = this.documentName.trim() || '[请输入具体文档名]'
-      const date = this.formatDate(this.effectiveDate) || '[请输入生效日期]'
+      const docName = this.documentName.trim() || `[${this.t('upload.form.documentName')}]`
+      const date = this.formatDate(this.effectiveDate) || `[${this.t('upload.form.effectiveDate')}]`
       
       // 构建名称数组,过滤掉空值
       const nameParts = [projectCode, countryName, centerId, docName, date].filter(part => part !== '')
@@ -437,7 +442,7 @@ export default {
     async handleSubmit() {
       if (this.selectedCountryIndex < 0) {
         uni.showToast({
-          title: '请选择国家',
+          title: this.t('upload.message.selectCountry'),
           icon: 'none'
         })
         return
@@ -445,7 +450,7 @@ export default {
       
       if (this.selectedCenterIndex < 0) {
         uni.showToast({
-          title: '请选择中心',
+          title: this.t('upload.message.selectCenter'),
           icon: 'none'
         })
         return
@@ -453,7 +458,7 @@ export default {
       
       if (!this.documentName.trim()) {
         uni.showToast({
-          title: '请输入具体文档名',
+          title: this.t('upload.message.inputDocumentName'),
           icon: 'none'
         })
         return
@@ -461,7 +466,7 @@ export default {
       
       if (!this.effectiveDate) {
         uni.showToast({
-          title: '请输入生效日期',
+          title: this.t('upload.message.inputEffectiveDate'),
           icon: 'none'
         })
         return
@@ -475,7 +480,7 @@ export default {
       
       if (!fileBase64List || fileBase64List.length === 0) {
         uni.showToast({
-          title: '未找到扫描文件',
+          title: this.t('upload.message.noScanFile'),
           icon: 'none'
         })
         return
@@ -483,7 +488,7 @@ export default {
       
       try {
         uni.showLoading({
-          title: '提交中...',
+          title: this.t('upload.message.submitting'),
           mask: true
         })
         
@@ -507,7 +512,7 @@ export default {
         
         if (response.code === 200) {
           uni.showToast({
-            title: '提交成功',
+            title: this.t('upload.message.submitSuccess'),
             icon: 'success',
             duration: 2000
           })
@@ -522,14 +527,14 @@ export default {
             })
           }, 2000)
         } else {
-          throw new Error(response.msg || '提交失败')
+          throw new Error(response.msg || this.t('upload.message.submitFailed'))
         }
         
       } catch (error) {
         uni.hideLoading()
         console.error('提交失败:', error)
         uni.showToast({
-          title: error.message || '提交失败',
+          title: error.message || this.t('upload.message.submitFailed'),
           icon: 'none'
         })
       }