Просмотр исходного кода

feat: 添加HTML代码/文件上传创建网页功能

1. 更新多语言文案,将"上传网页"改为"上传代码"并新增相关提示文本
2. 新增上传代码侧边菜单,支持上传HTML/HTM文件或粘贴HTML代码
3. 新增文件上传和粘贴代码的切换标签页
4. 实现上传文件/粘贴代码到S3并创建幻灯片的完整流程
5. 优化部分代码格式和缩进
lsc 1 неделя назад
Родитель
Сommit
e600de0cd9
4 измененных файлов с 399 добавлено и 91 удалено
  1. 381 85
      src/components/CollapsibleToolbar/index2.vue
  2. 6 2
      src/views/lang/cn.json
  3. 6 2
      src/views/lang/en.json
  4. 6 2
      src/views/lang/hk.json

+ 381 - 85
src/components/CollapsibleToolbar/index2.vue

@@ -2,7 +2,8 @@
   <div class="collapsible-toolbar" :class="{ collapsed: isCollapsed }">
     <div class="toolbar-content" v-show="!isCollapsed">
       <div class="sidebar-content">
-        <div class="sidebar-item feature-sidebar-item" :class="{ active: activeSubmenu === 'cocoai' }" @click="toggleSubmenu('cocoai')">
+        <div class="sidebar-item feature-sidebar-item" :class="{ active: activeSubmenu === 'cocoai' }"
+          @click="toggleSubmenu('cocoai')">
           <svg class="item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
             <path d="M12 2L2 7l10 5 10-5-10-5z"></path>
             <path d="M2 17l10 5 10-5"></path>
@@ -138,36 +139,33 @@
           </div>
         </template>
         <template v-else-if="!showFileConfirmModal && !exportingDialog">
-          <FileInput accept=".pptx"
-            @change="handleFileUpload">
+          <FileInput accept=".pptx" @change="handleFileUpload">
             <div class="upload-dropzone">
-                <div class="upload-dropzone-icon">
-                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
-                        <path d="M12 15V4"></path>
-                        <path d="M7 9l5-5 5 5"></path>
-                        <path d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2"></path>
-                    </svg>
-                </div>
-                <div class="upload-dropzone-title">{{ lang.ssDragAndDrop }}</div>
-                <div class="upload-dropzone-subtitle">{{ lang.ssSupportPptx }}</div>
-                <!-- <div class="upload-dropzone-footnote">同类型文件支持批量导入,跨类型文件请分开处理</div> -->
+              <div class="upload-dropzone-icon">
+                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
+                  <path d="M12 15V4"></path>
+                  <path d="M7 9l5-5 5 5"></path>
+                  <path d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2"></path>
+                </svg>
+              </div>
+              <div class="upload-dropzone-title">{{ lang.ssDragAndDrop }}</div>
+              <div class="upload-dropzone-subtitle">{{ lang.ssSupportPptx }}</div>
+              <!-- <div class="upload-dropzone-footnote">同类型文件支持批量导入,跨类型文件请分开处理</div> -->
             </div>
           </FileInput>
         </template>
-        
+
         <template v-else-if="!exportingDialog">
           <div class="file-confirm-inline">
             <div class="file-info">
               <div class="file-title">{{ lang.ssFileDetected }}{{ currentFileName }}</div>
-              <div class="file-subtitle">{{ currentFileName }}({{ lang.ssTotalPages.replace('{count}', pageCount.toString()) }})</div>
+              <div class="file-subtitle">{{ currentFileName }}({{ lang.ssTotalPages.replace('{count}',
+                pageCount.toString()) }})</div>
             </div>
-            
+
             <div class="import-options">
-              <div 
-                class="import-option" 
-                :class="{ active: selectedImportOption === 'page' }"
-                @click="selectedImportOption = 'page'"
-              >
+              <div class="import-option" :class="{ active: selectedImportOption === 'page' }"
+                @click="selectedImportOption = 'page'">
                 <div class="option-icon">
                 </div>
                 <div class="option-text">
@@ -175,13 +173,9 @@
                   <div class="option-desc">{{ lang.ssImportAsSlideDesc }}</div>
                 </div>
               </div>
-              
-              <div
-                v-show="false" 
-                class="import-option" 
-                :class="{ active: selectedImportOption === 'library' }"
-                @click="selectedImportOption = 'library'"
-              >
+
+              <div v-show="false" class="import-option" :class="{ active: selectedImportOption === 'library' }"
+                @click="selectedImportOption = 'library'">
                 <div class="option-icon">
                 </div>
                 <div class="option-text">
@@ -203,14 +197,15 @@
             <div class="progress-header">
               <!-- <span class="file-name">{{ currentFileName }}</span>
               <span class="progress-percent">{{ importProgress }}%</span> -->
-                <div class="upload-task-main">
-                    <div class="upload-task-name">{{ currentFileName }}</div>
-                    <div class="upload-task-meta">课件文件 · {{ formatFileSize(currentFileSize) }}</div>
-                </div>
-                <div class="upload-task-side">
-                    <div class="upload-task-percent">{{importProgress}}%</div>
-                    <button type="button" class="upload-task-action" :class="{ 'upload-task-close': !exporting}" @click="handleParsingClose">{{ exporting ? '取消' :'×'}}</button>
-                </div>
+              <div class="upload-task-main">
+                <div class="upload-task-name">{{ currentFileName }}</div>
+                <div class="upload-task-meta">课件文件 · {{ formatFileSize(currentFileSize) }}</div>
+              </div>
+              <div class="upload-task-side">
+                <div class="upload-task-percent">{{ importProgress }}%</div>
+                <button type="button" class="upload-task-action" :class="{ 'upload-task-close': !exporting }"
+                  @click="handleParsingClose">{{ exporting ? '取消' : '×' }}</button>
+              </div>
             </div>
             <div class="progress-bar">
               <div class="progress-fill" :style="{ width: importProgress + '%' }"></div>
@@ -493,7 +488,17 @@
           </div>
           <span class="submenu-label">{{ lang.ssUploadWebpageLink }}</span>
         </div>
-        <!-- <div class="submenu-item">
+        <div class="submenu-item" @click="handleToolClick('createWebpage')">
+          <div class="submenu-icon">
+            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+              <rect x="3" y="3" width="18" height="14" rx="2"></rect>
+              <path d="M12 8v6"></path>
+              <path d="M9 11h6"></path>
+            </svg>
+          </div>
+          <span class="submenu-label">{{ lang.ssNewWebpage }}</span>
+        </div>
+        <div class="submenu-item" @click="handleToolClick('uploadCode')">
           <div class="submenu-icon">
             <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
               <g id="Component 1">
@@ -506,16 +511,6 @@
             </svg>
           </div>
           <span class="submenu-label">{{ lang.ssUploadWebpage }}</span>
-        </div> -->
-        <div class="submenu-item" @click="handleToolClick('createWebpage')">
-          <div class="submenu-icon">
-            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
-              <rect x="3" y="3" width="18" height="14" rx="2"></rect>
-              <path d="M12 8v6"></path>
-              <path d="M9 11h6"></path>
-            </svg>
-          </div>
-          <span class="submenu-label">{{ lang.ssNewWebpage }}</span>
         </div>
         <!-- <div class="submenu-item">
           <div class="submenu-icon">
@@ -563,6 +558,67 @@
         </div>
       </div>
     </div>
+    <div class="submenu" :class="{ visible: activeSubmenu === 'uploadCode' }">
+      <div class="submenu-title">
+        <div class="title">{{ lang.ssUploadWebpage }}</div>
+        <div class="close-icon" @click="activeSubmenu = 'h5page'">
+          <svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+            <g id="Component 3">
+              <g id="Component 1">
+                <path id="Vector" d="M16 18L12 14L16 10" stroke="#9CA3AF" stroke-width="1.33333" />
+              </g>
+            </g>
+          </svg>
+        </div>
+      </div>
+      <div class="line_box">
+        <div class="upload-box">
+          <div class="upload-tabs">
+            <button class="upload-tab" :class="{ active: uploadTab === 'file' }"
+              @click="switchUploadTab('file')">上传文件</button>
+            <button class="upload-tab" :class="{ active: uploadTab === 'code' }"
+              @click="switchUploadTab('code')">粘贴代码</button>
+          </div>
+          <div class="uploadFilePanel" v-if="uploadTab === 'file'">
+            <div class="form-group">
+              <FileInput accept=".html,.htm" @change="handleFileCodeUpload" v-if="!uploadCodeFile">
+                <div class="file-upload-area">
+                  <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
+                    <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"></path>
+                    <polyline points="17 8 12 3 7 8"></polyline>
+                    <line x1="12" y1="3" x2="12" y2="15"></line>
+                  </svg>
+                  <p class="upload-text">{{ lang.ssDragAndDropHint }}</p>
+                  <p class="upload-hint">{{ lang.ssSupportHTML }}</p>
+                </div>
+              </FileInput>
+              <div class="file-name-display" v-else>
+                <span>{{ uploadCodeFile.name }}</span>
+                <button type="button" class="upload-task-action"
+                  @click="handleFileCodeUpload(null)">×</button>
+              </div>
+            </div>
+          </div>
+          <div class="pasteCodePanel" v-if="uploadTab === 'code'">
+            <div class="form-group">
+              <textarea class="code-textarea" :placeholder="lang.ssPasteHTML" v-model="codeInput"></textarea>
+            </div>
+          </div>
+          <button class="webpage-link-button"
+            :class="{ 'loading': isLoading, 'disabled': !uploadCodeFile || isLoading }"
+            :disabled="!uploadCodeFile || isLoading" @click="handleUploadCodeFile"
+            v-if="uploadTab === 'file'">
+            {{ isLoading ? lang.ssUploading : !uploadCodeFile ? lang.ssWaitingForInput2 : lang.ssStartUpload }}
+          </button>
+          <button class="webpage-link-button"
+            :class="{ 'loading': isLoading, 'disabled': !codeInput || isLoading }"
+            :disabled="!codeInput || isLoading" @click="handleUploadCode"
+            v-else-if="uploadTab === 'code'">
+            {{ isLoading ? lang.ssUploading : !codeInput ? lang.ssWaitingForInput2 : lang.ssStartUpload }}
+          </button>
+        </div>
+      </div>
+    </div>
     <div class="submenu" :class="{ visible: activeSubmenu === 'multimedia' }">
       <div class="submenu-title">
         <div class="title">{{ lang.ssAddMultimedia }}</div>
@@ -999,6 +1055,9 @@ const handleToolClick = _.debounce((tool: string) => {
   else if (tool === 'uploadWebpage') {
     activeSubmenu.value = 'uploadWebpage'
   }
+  else if (tool === 'uploadCode') {
+    activeSubmenu.value = 'uploadCode'
+  }
 }, 300)
 
 const loadContentList = () => {
@@ -1106,7 +1165,7 @@ const getTypeClass = (type?: number) => {
 
 import useImport from '@/hooks/useImport'
 import message from '@/utils/message'
-const { importPPTXFile, exporting, getFile, getPPTInfo } = useImport()
+const { importPPTXFile, exporting, getFile, getPPTInfo, uploadFileToS3 } = useImport()
 const currentFileName = ref('')
 const currentFileSize = ref(0)
 const parsingStatus = ref<'parsing' | 'success'>('parsing')
@@ -1138,7 +1197,7 @@ const handleFileUpload = async (files: FileList) => {
   pendingFile.value = files
   selectedImportOption.value = 'page'
   readingFile.value = true
-  
+
   try {
     // 读取 PPT 信息获取页码
     const info = await getPPTInfo(file)
@@ -1151,7 +1210,7 @@ const handleFileUpload = async (files: FileList) => {
   finally {
     readingFile.value = false
   }
-  
+
   showFileConfirmModal.value = true
 }
 
@@ -1188,7 +1247,7 @@ const confirmFileUpload = async () => {
   const confirmOnclose = () => {
     handleParsingClose()
   }
-  
+
   try {
     // 创建AbortController用于取消操作
     parsingAbortController.value = new AbortController()
@@ -1238,6 +1297,48 @@ const handleParsingClose = () => {
 
   exportingDialog.value = false
 }
+
+const uploadTab = ref('file')
+const switchUploadTab = (tab: 'file' | 'code') => {
+  uploadTab.value = tab
+}
+
+const codeInput = ref('')
+const uploadCodeFile = ref<File | null>()
+const handleFileCodeUpload = (files: FileList | null) => {
+  
+  if (!files || files.length === 0) {
+    uploadCodeFile.value = null
+    return
+  }
+
+  const file = files[0]
+  uploadCodeFile.value = file
+}
+
+const handleUploadCodeFile = async () => {
+  if (!uploadCodeFile.value) return
+  const fileName = uploadCodeFile.value.name.toLowerCase()
+  if (fileName.endsWith('.html') || fileName.endsWith('.htm')) {
+    isLoading.value = true
+    const url = await uploadFileToS3(uploadCodeFile.value)
+    createSlide()
+    createFrameElement(url, 73)
+    uploadCodeFile.value = null
+    isLoading.value = false
+  }
+}
+
+const handleUploadCode = async () => {
+  if (!codeInput.value) return
+  const file = new File([codeInput.value], 'index.html', { type: 'text/html' })
+  isLoading.value = true
+  const url = await uploadFileToS3(file)
+  createSlide()
+  createFrameElement(url, 73)
+  codeInput.value = ''
+  isLoading.value = false
+}
 </script>
 
 <style lang="scss" scoped>
@@ -1271,13 +1372,13 @@ const handleParsingClose = () => {
 }
 
 .sidebar-divider::before {
-    content: "";
-    position: absolute;
-    left: 0;
-    right: 0;
-    top: 50%;
-    height: 1px;
-    background: #e8ddd0;
+  content: "";
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 50%;
+  height: 1px;
+  background: #e8ddd0;
 }
 
 .feature-sidebar-item {
@@ -1736,10 +1837,11 @@ const handleParsingClose = () => {
     //   color: #FF9300;
     // }
 
-    .upload-task-main{
+    .upload-task-main {
       min-width: 0;
     }
-    .upload-task-name{
+
+    .upload-task-name {
       font-size: 13px;
       font-weight: 700;
       color: #111827;
@@ -1747,18 +1849,21 @@ const handleParsingClose = () => {
       overflow: hidden;
       text-overflow: ellipsis;
     }
-    .upload-task-meta{
+
+    .upload-task-meta {
       margin-top: 2px;
       font-size: 11px;
       color: #8b7356;
     }
-    .upload-task-side{
+
+    .upload-task-side {
       display: flex;
       align-items: center;
       gap: 8px;
       flex-shrink: 0;
     }
-    .upload-task-percent{
+
+    .upload-task-percent {
       font-size: 12px;
       font-weight: 700;
       color: #c76a0c;
@@ -1767,15 +1872,15 @@ const handleParsingClose = () => {
     }
 
     .upload-task-action {
-        border: 0;
-        background: transparent;
-        color: #9a8a77;
-        font-size: 12px;
-        font-weight: 600;
-        cursor: pointer;
+      border: 0;
+      background: transparent;
+      color: #9a8a77;
+      font-size: 12px;
+      font-weight: 600;
+      cursor: pointer;
     }
 
-    .upload-task-close{
+    .upload-task-close {
       width: 20px;
       height: 20px;
       display: inline-flex;
@@ -1804,7 +1909,7 @@ const handleParsingClose = () => {
     }
   }
 
-  .progress-loading{
+  .progress-loading {
     font-size: 12px;
     color: #111827;
   }
@@ -1896,7 +2001,7 @@ const handleParsingClose = () => {
   }
 }
 
-.upload-dropzone{
+.upload-dropzone {
   position: relative;
   border: 1.5px dashed rgba(247, 139, 34, 0.38);
   border-radius: 20px;
@@ -1916,14 +2021,15 @@ const handleParsingClose = () => {
   margin: 15px auto;
   box-sizing: border-box;
 
-  &:hover{
+  &:hover {
     border-style: solid;
     border-color: #f78b22;
     background: #fff3e2;
     box-shadow: 0 18px 34px rgba(247, 139, 34, 0.16);
     transform: translateY(-1px);
   }
-  .upload-dropzone-icon{
+
+  .upload-dropzone-icon {
     width: 56px;
     height: 56px;
     border-radius: 18px;
@@ -1934,26 +2040,26 @@ const handleParsingClose = () => {
     background: rgba(247, 139, 34, 0.10);
     box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
 
-    svg{
+    svg {
       width: 28px;
       height: 28px;
     }
   }
 
-  .upload-dropzone-title{
+  .upload-dropzone-title {
     font-size: 16px;
     font-weight: 700;
     color: #111827;
   }
 
-  .upload-dropzone-subtitle{
+  .upload-dropzone-subtitle {
     font-size: 12px;
     line-height: 1.6;
     color: #7c6d5d;
     max-width: 320px;
   }
 
-  .upload-dropzone-footnote{
+  .upload-dropzone-footnote {
     font-size: 11px;
     color: #9a8a77;
   }
@@ -1986,6 +2092,7 @@ const handleParsingClose = () => {
   0% {
     transform: rotate(0deg);
   }
+
   100% {
     transform: rotate(360deg);
   }
@@ -2004,12 +2111,14 @@ const handleParsingClose = () => {
 
   .file-info {
     margin-bottom: 16px;
+
     .file-title {
       font-size: 14px;
       font-weight: 700;
       color: #111827;
       margin-bottom: 6px;
     }
+
     .file-subtitle {
       font-size: 12px;
       color: #7c6d5d;
@@ -2045,11 +2154,11 @@ const handleParsingClose = () => {
           border-color: #f78b22;
 
           &::after {
-              content: '';
-              position: absolute;
-              inset: 3px;
-              border-radius: 50%;
-              background: #f78b22;
+            content: '';
+            position: absolute;
+            inset: 3px;
+            border-radius: 50%;
+            background: #f78b22;
           }
         }
       }
@@ -2088,7 +2197,8 @@ const handleParsingClose = () => {
     gap: 10px;
     justify-content: flex-end;
 
-    .cancel-btn, .confirm-btn {
+    .cancel-btn,
+    .confirm-btn {
       min-width: 84px;
       height: 34px;
       padding: 0 14px;
@@ -2109,7 +2219,193 @@ const handleParsingClose = () => {
       background: linear-gradient(180deg, #f89a34 0%, #f07815 100%);
       border: 0;
       color: #fff;
-      box-shadow: 0 10px 20px rgba(240, 120, 21, 0.18); 
+      box-shadow: 0 10px 20px rgba(240, 120, 21, 0.18);
+    }
+  }
+}
+
+.line_box {
+  height: calc(100% - 75px);
+  overflow: hidden;
+}
+
+.upload-box {
+  padding: 20px;
+
+  .upload-tabs {
+    display: flex;
+    margin-bottom: 20px;
+    border-bottom: 1px solid rgb(229, 231, 235);
+
+    .upload-tab {
+      border-top-width: initial;
+      border-right-width: initial;
+      border-left-width: initial;
+      border-top-color: initial;
+      border-right-color: initial;
+      border-left-color: initial;
+      background-color: transparent;
+      cursor: pointer;
+      font-size: 14px;
+      color: rgb(107, 114, 128);
+      margin-bottom: -1px;
+      padding: 10px 16px;
+      border-style: none none solid;
+      border-image: initial;
+      border-bottom: 2px solid transparent;
+
+      &.active {
+        color: rgb(247, 139, 34);
+        border-bottom-color: rgb(247, 139, 34);
+        font-weight: 600;
+      }
+    }
+  }
+
+  .uploadFilePanel {
+
+    .form-group {
+      display: flex;
+      flex-direction: column;
+      gap: 12px;
+
+      .file-upload-area {
+        text-align: center;
+        cursor: pointer;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        min-height: 190px;
+        border-width: 2px;
+        border-style: dashed;
+        border-color: rgb(229, 231, 235);
+        border-image: initial;
+        border-radius: 12px;
+        background: rgb(250, 251, 252);
+        padding: 40px 20px;
+        transition: 0.2s;
+        gap: 10px;
+
+        svg {
+          color: rgb(156, 163, 175);
+          margin-bottom: 12px;
+        }
+
+        .upload-text {
+          font-size: 14px;
+          font-weight: 500;
+          color: rgb(55, 65, 81);
+          margin-bottom: 6px;
+        }
+
+        .upload-hint {
+          font-size: 12px;
+          color: rgb(107, 114, 128);
+        }
+
+        &:hover {
+          border-color: rgb(247, 139, 34);
+          background: rgb(255, 248, 240);
+        }
+      }
+
+      .file-name-display {
+        margin-top: 12px;
+        font-size: 13px;
+        color: rgb(75, 85, 99);
+        background-color: rgb(249, 250, 251);
+        border-radius: 6px;
+        padding: 8px 12px;
+        border-width: 1px;
+        border-style: solid;
+        border-color: rgb(229, 231, 235);
+        border-image: initial;
+        display: flex;
+        justify-content: space-between;
+
+        span {
+          flex: 1;
+        }
+
+        .upload-task-action {
+          border: 0;
+          background: transparent;
+          color: #9a8a77;
+          font-size: 12px;
+          font-weight: 600;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+
+  .pasteCodePanel {
+    .form-group {
+      display: flex;
+      flex-direction: column;
+      gap: 10px;
+
+      .code-textarea {
+        width: 100%;
+        min-height: 190px;
+        font-family: monospace;
+        font-size: 13px;
+        resize: vertical;
+        border-width: 1px;
+        border-style: solid;
+        border-color: rgb(209, 213, 219);
+        border-image: initial;
+        border-radius: 8px;
+        padding: 12px;
+        transition: border-color 0.2s;
+        box-sizing: border-box;
+        resize: none;
+
+        &:focus {
+          outline: none;
+          border-color: rgb(247, 139, 34);
+        }
+      }
+    }
+  }
+
+  .webpage-link-button {
+    text-align: center;
+    padding: 10px 24px;
+    border: none;
+    border-radius: 4px;
+    font-size: 14px;
+    font-weight: 500;
+    cursor: pointer;
+    transition: all 0.3s;
+    background-color: #FF9300;
+    color: white;
+    margin: 0 auto;
+    display: block;
+    margin-top: 15px;
+
+    &:hover:not(:disabled) {
+      background-color: #e68a00;
+    }
+
+    &:disabled {
+      opacity: 0.5;
+      cursor: not-allowed;
+    }
+
+    &.loading {
+      cursor: not-allowed;
+      opacity: 0.8;
+    }
+
+    &.error {
+      background-color: #ff4d4f;
+      color: white;
+
+      &:hover:not(:disabled) {
+        background-color: #ff7875;
+      }
     }
   }
 }

+ 6 - 2
src/views/lang/cn.json

@@ -707,7 +707,7 @@
   "ssCreateApp": "创建应用",
   "ssAddInteractiveWebpage": "添加交互网页",
   "ssWebpageCenter": "网页中心",
-  "ssUploadWebpage": "上传网页",
+  "ssUploadWebpage": "上传代码",
   "ssCrawlWebpage": "爬取网页",
   "ssAddMultimedia": "添加多媒体",
   "ssDocument": "文档",
@@ -716,6 +716,7 @@
   "ssWebpageLink": "网页链接",
   "ssEnterCompleteUrl": "请输入完整的网页URL地址",
   "ssWaitingForInput": "等待输入...",
+  "ssWaitingForInput2": "等待上传...",
   "ssInvalidUrl": "URL格式不正确,请检查",
   "ssStartUpload": "开始上传",
   "ssUploading": "上传中...",
@@ -901,5 +902,8 @@
   "ssReadingFile": "正在读取文件...",
   "ssAiChatQuickAction3": "为当前页面内容生成2道选择题",
   "ssAiChatQuickAction4": "为当前页面生成互动网页",
-  "ssAiChatQuickAction5": "为课件推荐适合页面的互动工具"
+  "ssAiChatQuickAction5": "为课件推荐适合页面的互动工具",
+  "ssDragAndDropHint": "点击或拖拽文件到此处上传",
+  "ssSupportHTML": "支持 HTML、HTM 格式",
+  "ssPasteHTML": "请在此处粘贴完整的HTML代码"
 }

+ 6 - 2
src/views/lang/en.json

@@ -708,7 +708,7 @@
   "ssCreateApp": "Create App",
   "ssAddInteractiveWebpage": "Add Interactive Webpage",
   "ssWebpageCenter": "Webpage Center",
-  "ssUploadWebpage": "Upload Webpage",
+  "ssUploadWebpage": "Upload Code",
   "ssCrawlWebpage": "Crawl Webpage",
   "ssAddMultimedia": "Add Multimedia",
   "ssDocument": "Document",
@@ -717,6 +717,7 @@
   "ssWebpageLink": "Webpage Link",
   "ssEnterCompleteUrl": "Please enter complete webpage URL",
   "ssWaitingForInput": "Waiting for input...",
+  "ssWaitingForInput2": "Waiting for upload...",
   "ssInvalidUrl": "URL format is incorrect, please check",
   "ssStartUpload": "Start Upload",
   "ssUploading": "Uploading...",
@@ -901,5 +902,8 @@
   "ssReadingFile": "Reading file...",
   "ssAiChatQuickAction3": "Generate 2 multiple-choice questions for the current page content",
   "ssAiChatQuickAction4": "Generate an interactive web page for the current page",
-  "ssAiChatQuickAction5": "Recommend interactive tools for the current page"
+  "ssAiChatQuickAction5": "Recommend interactive tools for the current page",
+  "ssDragAndDropHint": "Click or drag files here to upload",
+  "ssSupportHTML": "Supports HTML, HTM format",
+  "ssPasteHTML": "Please paste the complete HTML code here"
 }

+ 6 - 2
src/views/lang/hk.json

@@ -708,7 +708,7 @@
   "ssCreateApp": "創建應用",
   "ssAddInteractiveWebpage": "添加交互網頁",
   "ssWebpageCenter": "網頁中心",
-  "ssUploadWebpage": "上傳網頁",
+  "ssUploadWebpage": "上傳代碼",
   "ssCrawlWebpage": "爬取網頁",
   "ssAddMultimedia": "添加多媒體",
   "ssDocument": "文檔",
@@ -717,6 +717,7 @@
   "ssWebpageLink": "網頁鏈接",
   "ssEnterCompleteUrl": "請輸入完整的網頁URL地址",
   "ssWaitingForInput": "等待輸入...",
+  "ssWaitingForInput2": "等待上傳...",
   "ssInvalidUrl": "URL格式不正確,請檢查",
   "ssStartUpload": "開始上傳",
   "ssUploading": "上傳中...",
@@ -901,5 +902,8 @@
   "ssReadingFile": "正在讀取文件...",
   "ssAiChatQuickAction3": "為當頁內容生成2道選擇題",
   "ssAiChatQuickAction4": "為當頁生成互動網頁。",
-  "ssAiChatQuickAction5": "為課件推薦適合的互動工具。"
+  "ssAiChatQuickAction5": "為課件推薦適合的互動工具。",
+  "ssDragAndDropHint": "點擊或拖拽文件至此,或點擊選擇",
+  "ssSupportHTML": "支持 HTML、HTM 格式",
+  "ssPasteHTML": "請在此处粘貼完整的HTML代碼"
 }