diff --git a/elsrc/TopMenu.js b/elsrc/TopMenu.js index 006d8bd..f182679 100644 --- a/elsrc/TopMenu.js +++ b/elsrc/TopMenu.js @@ -99,6 +99,23 @@ exports.menuRebuild = (mainWindow) => { } } ] + }, + { + label: '云服务', + submenu: [ + { + label: '同步上传', + click: async () => { + await shell.openExternal('http://www.huaruyu.com') + } + }, + { + label: '同步下载', + click: async () => { + await shell.openExternal('http://www.huaruyu.com') + } + } + ] } ]; } diff --git a/elsrc/sync/tencent/UploadUtils.js b/elsrc/sync/tencent/UploadUtils.js index f20d464..47f55fe 100644 --- a/elsrc/sync/tencent/UploadUtils.js +++ b/elsrc/sync/tencent/UploadUtils.js @@ -1,18 +1,58 @@ const COS = require('cos-nodejs-sdk-v5'); -const pathOpt = require("path"); -const cos = new COS({ - SecretId: 'AKIDvjKhqrfEaliRq11nMcrGZmsATiyNl1BA', - // 推荐使用环境变量获取;用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。 - // 子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140 - SecretKey: 'xpZCjCTVJzZG2wyy8mFVwLWTVVIqAKct', - Domain: 'https://note-1324909903.cos.ap-beijing.myqcloud.com' -}); -const Bucket='note-1324909903' -const Region = 'ap-beijing' +const {dialog} = require('electron') +const {readFileSync,createWriteStream}=require('node:fs') +const md5 = require("md5"); class UploadUtils { + + static cos = new COS({ + SecretId: 'AKIDvjKhqrfEaliRq11nMcrGZmsATiyNl1BA', + // 推荐使用环境变量获取;用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。 + // 子账号密钥获取可参考https://cloud.tencent.com/document/product/598/37140 + SecretKey: 'xpZCjCTVJzZG2wyy8mFVwLWTVVIqAKct', + Domain: 'https://note-1324909903.cos.ap-beijing.myqcloud.com' + }); + static Bucket='note-1324909903' + static Region = 'ap-beijing' + constructor(store) { this.store = store; } + static selfUploadFile(activeFile){ + console.log("cos.uploadFile") + UploadUtils.cos.uploadFile({ + Bucket: UploadUtils.Bucket, /* 填入您自己的存储桶,必须字段 */ + Region: UploadUtils.Region, /* 存储桶所在地域,例如 ap-beijing,必须字段 */ + Key: activeFile, /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */ + FilePath: activeFile, /* 必须 */ + SliceSize: 1024 * 1024 * 5, /* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */ + onTaskReady: function (taskId) { /* 非必须 */ + console.log(taskId); + }, + onProgress: function (progressData) { /* 非必须 */ + console.log(JSON.stringify(progressData)); + }, + onFileFinish: function (err, data, options) { /* 非必须 */ + console.log(options.Key + '上传' + (err ? '失败' : '完成')); + }, + // 支持自定义headers 非必须 + }, function (err, data) { + console.log(err || data); + }); + } + + static selfDownLoadFile(activeFile){ + console.log("cos.downloadFile",activeFile) + UploadUtils.cos.getObject({ + Bucket: UploadUtils.Bucket, /* 填入您自己的存储桶,必须字段 */ + Region: UploadUtils.Region, /* 存储桶所在地域,例如 ap-beijing,必须字段 */ + Key: activeFile, /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */ + Output: activeFile + // 支持自定义headers 非必须 + }, function (err, data) { + console.log(err || data); + }); + } + syncActiveFile() { let tableBarItem = JSON.parse(this.store.get("persist:tableBarItem")); if (!tableBarItem) { @@ -21,38 +61,48 @@ class UploadUtils { let activeFile = tableBarItem.activeKey?tableBarItem.activeKey.replaceAll('"',""):undefined; console.log("activeFile:", activeFile) if (activeFile) { - cos.headObject({ - Bucket:Bucket, - Region:Region, + let dirMessage = JSON.parse(this.store.get("persist:dirMessage")); + UploadUtils.cos.headObject({ + Bucket:UploadUtils.Bucket, + Region:UploadUtils.Region, // 不能以 / 开头 Key: activeFile, }, function(err, data) { - console.log("err || data.CommonPrefixes",err || data); + console.log("err || data.CommonPrefixes"+activeFile,err || data); if (data&&data.ETag){ // 文件存在,比较MD5值 - let md5= data.ETag.replaceAll('"',"") - console.log("fileList[0].ETag",md5) - }else { - console.log("cos.uploadFile") - cos.uploadFile({ - Bucket: Bucket, /* 填入您自己的存储桶,必须字段 */ - Region: Region, /* 存储桶所在地域,例如 ap-beijing,必须字段 */ - Key: activeFile, /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */ - FilePath: activeFile, /* 必须 */ - SliceSize: 1024 * 1024 * 5, /* 触发分块上传的阈值,超过5MB使用分块上传,非必须 */ - onTaskReady: function (taskId) { /* 非必须 */ - console.log(taskId); - }, - onProgress: function (progressData) { /* 非必须 */ - console.log(JSON.stringify(progressData)); - }, - onFileFinish: function (err, data, options) { /* 非必须 */ - console.log(options.Key + '上传' + (err ? '失败' : '完成')); - }, - // 支持自定义headers 非必须 - }, function (err, data) { - console.log(err || data); + let onlineMd5= data.ETag.replaceAll('"',"") + let fileMd5 + if (dirMessage&&dirMessage.data&&dirMessage.data.activeFile) { + fileMd5= dirMessage.data.activeFile.fileMd5; + } + if (!fileMd5){ + fileMd5=md5(readFileSync(activeFile).toString()) + } + if (onlineMd5===fileMd5){ + return + } + console.log("fileList[0].ETag",onlineMd5) + let number = dialog.showMessageBoxSync({ + "message":"云文件已修改是否同步到本地", + "type":"info", + "buttons":["是","否"], + "defaultId":0 }); + if (number===0){ + UploadUtils.selfDownLoadFile(activeFile) + }else if(number===1){ + if (dialog.showMessageBoxSync({ + "message":"是否使用本地文件覆盖远程文件", + "type":"info", + "buttons":["是","否"], + "defaultId":0 + })===0){ + UploadUtils.selfUploadFile(activeFile) + } + } + }else { + UploadUtils.selfUploadFile(activeFile) } }); } diff --git a/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js index dad4e79..4c32741 100644 --- a/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js +++ b/src/pages/Note/Hlexical/plugins/SaveFilePlugin.js @@ -11,7 +11,7 @@ import md5 from "md5" import {message} from "antd"; const {ipcRenderer} = window.require('electron') import "./ToobarPlugin.less" -import {newFileAdd} from "../../../../redux/dirMessage_reducer"; +import {newFileAdd, updateFileMd5} from "../../../../redux/dirMessage_reducer"; const SaveFilePlugin=(props)=> { let activeKey = useSelector(state => state.tableBarItem.activeKey); const dispatch = useDispatch(); @@ -71,7 +71,8 @@ const SaveFilePlugin=(props)=> { // 修改当前文件名 dispatch(updatedSavedFile({filePath: filePath})) // 文件目录更新 - dispatch(newFileAdd({fileName:getFileFullNameByPath(filePath),dirFlag:false,children:[],filePath: filePath})) + dispatch(newFileAdd({fileName:getFileFullNameByPath(filePath),dirFlag:false,children:[],filePath: filePath, + fileId:filePath,fileMd5:md5(resultSave)})) } }) return @@ -82,20 +83,27 @@ const SaveFilePlugin=(props)=> { const editorStateSave = {"editorState": JSON.parse(editorState)}; resultSave = JSON.stringify(editorStateSave); } + + // 后期不再读取文件,直接读取文件MD5 importFile(filePath).then(value => { let save + let newFileMd5 if (props.filePath.endsWith(".md")){ // editorState - save = (isEmpty(value)) || md5(resultSave) !== md5(value.toString()); + newFileMd5 = md5(value.toString()); + save = (isEmpty(value)) || md5(resultSave) !== newFileMd5; }else { - save = (isEmpty(value)) || md5(resultSave) !== md5(JSON.stringify(JSON.parse(value.toString()))); + newFileMd5 = md5(JSON.stringify(JSON.parse(value.toString()))); + save = (isEmpty(value)) || md5(resultSave) !== newFileMd5; } - if (save) { - overWriteFile(filePath, resultSave) - console.log("保存成功"+ filePath) - // messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1}) - message.success("保存成功:" + filePath) + overWriteFile(filePath, resultSave).then(()=>{ + console.log("保存成功"+ filePath) + // 修改文件Md5 + dispatch(updateFileMd5({filePath,"fileMd5":newFileMd5})) + // messageApi.open({type:"success",content:"保存成功:" + filePath,duration:1}) + message.success("保存成功:" + filePath) + }) } }).catch(error => console.error(error) @@ -115,10 +123,5 @@ const SaveFilePlugin=(props)=> { }; },[editor,onChange] ) - // return ( - //