Browse Source

问题修改

dsy 23 hours ago
parent
commit
fe3ac24975

+ 83 - 1
main.js

@@ -1,6 +1,8 @@
-const { app, BrowserWindow, shell } = require('electron');
+const { app, BrowserWindow, ipcMain, net, shell } = require('electron');
 const path = require('path');
 const url = require('url');
+const fs = require('fs');
+const { spawn } = require('child_process'); // 用于启动子进程
 
 let win = null;
 
@@ -53,6 +55,86 @@ app.whenReady().then(() => {
   });
 });
 
+// 检查更新
+ipcMain.handle('check-update', async () => {
+  const apiUrl = 'https://your-api.com/api/app/latest'; // <-- 替换为真实接口
+  const currentVersion = app.getVersion();
+
+  return new Promise((resolve, reject) => {
+    const req = net.request(apiUrl);
+    let body = '';
+    req.on('response', (res) => {
+      res.on('data', (chunk) => (body += chunk));
+      res.on('end', () => {
+        try {
+          const latest = JSON.parse(body);
+          const update = latest.version && latest.version !== currentVersion;
+          resolve({ update, latest, currentVersion });
+        } catch (e) {
+          reject(e);
+        }
+      });
+    });
+    req.on('error', (err) => reject(err));
+    req.end();
+  });
+});
+
+// 下载更新(渲染进程发起),主进程负责流式保存并推送进度
+ipcMain.on('download-update', (event, downloadUrl) => {
+  const win = BrowserWindow.getAllWindows()[0];
+  const filename = path.basename(downloadUrl).split('?')[0] || `update-${Date.now()}.exe`;
+  const tmpPath = path.join(app.getPath('temp'), filename);
+  const fileStream = fs.createWriteStream(tmpPath);
+  const req = net.request(downloadUrl);
+
+  let received = 0;
+  let total = 0;
+
+  req.on('response', (res) => {
+    total = parseInt(res.headers['content-length'] || res.headers['Content-Length'] || '0');
+    res.on('data', (chunk) => {
+      received += chunk.length;
+      fileStream.write(chunk);
+      win.webContents.send('update-download-progress', { received, total });
+    });
+    res.on('end', () => {
+      fileStream.end();
+      win.webContents.send('update-downloaded', { path: tmpPath });
+    });
+  });
+
+  req.on('error', (err) => {
+    win.webContents.send('update-error', { message: err.message || String(err) });
+  });
+
+  req.end();
+});
+
+// 安装更新(渲染进程确认安装时调用)
+ipcMain.on('install-update', (event, filePath) => {
+  if (!fs.existsSync(filePath)) {
+    event.sender.send('update-error', { message: '安装文件不存在' });
+    return;
+  }
+
+  if (process.platform === 'win32') {
+    // Windows:直接执行安装程序(根据你的安装包参数添加静默/等待参数)
+    try {
+      spawn(filePath, [], { detached: true, stdio: 'ignore' }).unref();
+      app.quit();
+    } catch (e) {
+      event.sender.send('update-error', { message: e.message });
+    }
+  } else if (process.platform === 'darwin') {
+    // macOS:打开 dmg 或者打开 .pkg
+    shell.openPath(filePath).then(() => app.quit());
+  } else {
+    // linux:按照需要实现
+    shell.openPath(filePath).then(() => app.quit());
+  }
+});
+
 // 当所有窗口都已关闭时退出
 app.on('window-all-closed', () => {
   if (process.platform !== 'darwin') {

+ 3 - 2
src/components/CommonPreview.vue

@@ -693,14 +693,15 @@ export default {
   }
 
   .main-container {
+    display: flex;
     flex: 1;
+    justify-content: center;
     min-width: 1110px;
     overflow: auto;
   }
 
   main.preview-main {
     display: flex;
-    flex: 1;
     flex-direction: column;
     row-gap: 5px;
     width: 1100px;
@@ -728,7 +729,7 @@ export default {
       color: #fff;
       background-color: #f44444;
       border-top-left-radius: 12px;
-      border-bottom-right-radius: 16px;
+      border-top-right-radius: 16px;
     }
   }
 

+ 7 - 7
src/views/book/courseware/create/components/question/new_word/NewWord.vue

@@ -340,8 +340,8 @@
         label="生词音频"
         type="audio"
         width="500px"
-        @uploadSuccess="uploadAudioSuccess"
         :style="{ marginBottom: data.audio_data.url.length === 0 ? '5px' : '' }"
+        @uploadSuccess="uploadAudioSuccess"
       />
       <div v-if="data.audio_data.url.length > 0" class="upload-file">
         <div class="file-name">
@@ -368,9 +368,9 @@
           <el-button type="text" @click="againWordTime">重新生成</el-button>
         </div>
         <template v-else>
-          <el-button v-if="!isWordTime" size="medium" :loading="loading" @click="createWordTime"
-            >自动生成字幕节点</el-button
-          >
+          <el-button v-if="!isWordTime" size="medium" :loading="loading" @click="createWordTime">
+            自动生成字幕节点
+          </el-button>
           <p v-else>字幕节点生成中...请等待</p>
         </template>
       </div>
@@ -592,11 +592,11 @@ export default {
     // 上移下移
     moveElement(dItem, index, type) {
       let obj = JSON.parse(JSON.stringify(dItem));
-      if (type == 'up' && index > 0) {
+      if (type === 'up' && index > 0) {
         this.data.new_word_list.splice(index - 1, 0, obj);
         this.data.new_word_list.splice(index + 1, 1);
       }
-      if (type == 'down' && index < this.data.new_word_list.length - 1) {
+      if (type === 'down' && index < this.data.new_word_list.length - 1) {
         this.data.new_word_list[index] = this.data.new_word_list.splice(
           index + 1,
           1,
@@ -618,7 +618,7 @@ export default {
       GetStaticResources(MethodName, data)
         .then((res) => {
           for (let key in res) {
-            if (key != 'status' && key != ',' && res[key]) {
+            if (key !== 'status' && key !== ',' && res[key]) {
               res[key] = JSON.parse(res[key]);
             }
           }

+ 9 - 1
src/views/book/courseware/create/components/question/voice_matrix/CheckSubtitles.vue

@@ -18,7 +18,10 @@
 
       <div class="audio-player">
         <div class="player-line">
-          <div class="progress-bar" :style="{ width: (audio.current_time / audio.max_time) * 100 + '%' }"></div>
+          <div
+            class="progress-bar"
+            :style="{ width: Math.min((audio.current_time / audio.max_time) * 100, 100) + '%' }"
+          ></div>
           <div class="progress-dot"></div>
         </div>
         <div class="player-controls">
@@ -116,6 +119,10 @@ export default {
       handler(val) {
         if (!val) {
           this.$refs[this.audioId].pause();
+          this.lrcIndex = {
+            row: 0,
+            col: 0,
+          };
         }
       },
     },
@@ -328,6 +335,7 @@ export default {
       .progress-bar {
         position: relative;
         width: 0%;
+        max-width: 540px;
         height: 100%;
         background-color: $main-color;
 

+ 22 - 19
src/views/book/courseware/data/newWord.js

@@ -58,7 +58,7 @@ export function getOption() {
     label: '', // 标签
     hz_info: [],
     bg: 0,
-    ed: 0
+    ed: 0,
   };
 }
 
@@ -79,8 +79,8 @@ export function getNewWordData() {
   return {
     type: 'new_word',
     title: '生词组件',
-    source_courseware_id_list:[],
-    source_courseware_id:'', // 生词关联课件id,即跨页高亮生词
+    source_courseware_id_list: [],
+    source_courseware_id: '', // 生词关联课件id,即跨页高亮生词
     property: getNewWordProperty(),
     title_con: '',
     new_word_list: [getOption()],
@@ -101,27 +101,30 @@ export function getNewWordData() {
       file_id: '',
     },
     wordTime: [], // 字幕时间节点
-    taskId:'',
+    taskId: '',
     file_id_list: [], // 文件 id
     col_width: [
       {
-        value:125  // 生词
-      },{
-        value:125  // 拼音
-      },{
-        value:125  // 词性
-      },{
-        value:445  // 释义
-      },{
-        value:0  // 搭配
-      },{
-        value:0  // 例句
-      }
+        value: 125, // 生词
+      },
+      {
+        value: 125, // 拼音
+      },
+      {
+        value: 125, // 词性
+      },
+      {
+        value: 445, // 释义
+      },
+      {
+        value: 0, // 搭配
+      },
+      {
+        value: 0, // 例句
+      },
     ], // 列宽
     mind_map: {
-      node_list: [
-        { name: '生词组件' }
-      ], // 思维导图数据
+      node_list: [{ name: '生词组件' }], // 思维导图数据
     },
     answer: {
       answer_list: [],