diff --git a/src-electron/electron-flag.d.ts b/src-electron/electron-flag.d.ts index a78cbf5..2bc4f17 100644 --- a/src-electron/electron-flag.d.ts +++ b/src-electron/electron-flag.d.ts @@ -1,9 +1,9 @@ // THIS FEATURE-FLAG FILE IS AUTOGENERATED, // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING -import "quasar/dist/types/feature-flag"; +import 'quasar/dist/types/feature-flag' -declare module "quasar/dist/types/feature-flag" { +declare module 'quasar/dist/types/feature-flag' { interface QuasarFeatureFlags { - electron: true; + electron: true } } diff --git a/src/App.vue b/src/App.vue index 9eaba1d..48da253 100644 --- a/src/App.vue +++ b/src/App.vue @@ -23,7 +23,7 @@ export default { }, methods: { ...mapClientActions(['initClientStore']), - ...mapServerActions(['initServerStore']), + ...mapServerActions(['initServerStore', 'reLogin']), ...mapServerState(['isLogin']) } } diff --git a/src/ScheduleHandler.js b/src/ScheduleHandler.js index 6aa0820..3bf3bd4 100644 --- a/src/ScheduleHandler.js +++ b/src/ScheduleHandler.js @@ -4,7 +4,11 @@ import ServerFileStorage from './utils/storage/ServerFileStorage' const refreshWizToken = (app) => { schedule.scheduleJob('30 * * * * *', async () => { if (!ServerFileStorage.isKeyExistsInLocalStorage('token') || !app.isLogin) return - await api.AccountServerApi.keepTokenAlive() + try { + await api.AccountServerApi.keepTokenAlive() + } catch (e) { + await app.reLogin() + } }) } diff --git a/src/components/Vditor.vue b/src/components/Vditor.vue index 689ec90..6e639fd 100644 --- a/src/components/Vditor.vue +++ b/src/components/Vditor.vue @@ -37,7 +37,7 @@ export default { dataLoaded: function () { return !helper.isNullOrEmpty(this.currentNote) }, - ...mapServerGetters(['currentNote', 'uploadImageUrl']), + ...mapServerGetters(['currentNote', 'uploadImageUrl', 'currentNoteResources', 'currentNoteResourceUrl']), ...mapServerState(['isCurrentNoteLoading', 'contentsList']), ...mapClientState(['darkMode', 'lightCodeTheme', 'darkCodeTheme']) }, @@ -71,6 +71,12 @@ export default { hljs: { style: this.$q.dark.isActive ? this.darkCodeTheme : this.lightCodeTheme } + // transform: (html) => { + // const imgReg = /(]*\s+)?(data-src|src)=")index_files(\/[^"]*")/ig + // const newHtml = imgReg.exec(html) + // console.log(newHtml) + // return newHtml + // } }, upload: { max: 5 * 1024 * 1024, diff --git a/src/components/ui/NoteItem.vue b/src/components/ui/NoteItem.vue index 7aec70c..694ad90 100644 --- a/src/components/ui/NoteItem.vue +++ b/src/components/ui/NoteItem.vue @@ -52,7 +52,7 @@ export default { components: { CategoryDialog, NoteItemContextMenu }, computed: { summary () { - if (helper.isNullOrEmpty(this.data.abstractText)) { + if (helper.isNullOrEmpty(this.data.abstractText) && !helper.isNullOrEmpty(this.data.highlight)) { const { highlight: { text = [] } } = this.data const summary = text.join('') return summary.length > this.maxSummaryLength diff --git a/src/css/vditor.css b/src/css/vditor.css index 5eb0d9a..561f5cf 100644 --- a/src/css/vditor.css +++ b/src/css/vditor.css @@ -796,7 +796,7 @@ word-wrap: break-word; overflow: auto; line-height: 28px; - font-size: 16px; + font-size: 19px; word-break: break-word; padding-bottom: 30px; } diff --git a/src/store/server/actions.js b/src/store/server/actions.js index 98d0675..1dd9f61 100644 --- a/src/store/server/actions.js +++ b/src/store/server/actions.js @@ -19,7 +19,12 @@ export default { const localStore = ClientFileStorage.getItemsFromStore(state) commit(types.INIT, localStore) ServerFileStorage.removeItemFromLocalStorage('token') - const [autoLogin, userId, password, url] = ClientFileStorage.getItemsFromStore([ + const [ + autoLogin, + userId, + password, + url + ] = ClientFileStorage.getItemsFromStore([ 'autoLogin', 'userId', 'password', @@ -66,11 +71,33 @@ export default { return result }, + /** + * 登出 + * @param commit + * @returns {Promise} + */ async logout ({ commit }) { await api.AccountServerApi.Logout() ServerFileStorage.removeItemFromLocalStorage('token') commit(types.LOGOUT) }, + /** + * 重新登录 + * @param commit + * @returns {Promise} + */ + async reLogin ({ commit }) { + const [userId, password, url] = ClientFileStorage.getItemsFromStore([ + 'userId', + 'password', + 'url' + ]) + await this.dispatch('server/login', { + userId, + password, + url + }) + }, /** * 获取指定文件夹下的笔记 * @param commit @@ -185,9 +212,9 @@ export default { let { title } = state.currentNote.info const { resources } = state.currentNote const isLite = category.replace(/\//g, '') === 'Lite' - const html = helper.embedMDNote(markdown, { wrapWithPreTag: isLite }) + const html = helper.embedMDNote(markdown, resources, { wrapWithPreTag: isLite }) - const _updateNote = async (title) => { + const _updateNote = async title => { const result = await api.KnowledgeBaseApi.updateNote({ kbGuid, docGuid, @@ -197,12 +224,15 @@ export default { kbGuid, docGuid, category, - resources, + resources: resources.map(r => r.name), type: isLite ? 'lite/markdown' : 'document' } }) - ClientFileStorage.setCachedNote({ info: result, html }, api.KnowledgeBaseApi.getCacheKey(kbGuid, docGuid)) + ClientFileStorage.setCachedNote( + { info: result, html }, + api.KnowledgeBaseApi.getCacheKey(kbGuid, docGuid) + ) Notify.create({ color: 'primary', message: i18n.t('saveNoteSuccessfully'), @@ -238,7 +268,7 @@ export default { * @returns {Promise} */ async createNote ({ commit, state, rootState }, title) { - const { kbGuid, currentCategory } = state + const { kbGuid, currentCategory = '' } = state const userId = ClientFileStorage.getItemFromStore('userId') const isLite = currentCategory.replace(/\//g, '') === 'Lite' const result = await api.KnowledgeBaseApi.createNote({ @@ -248,7 +278,7 @@ export default { kbGuid, title, owner: userId, - html: helper.embedMDNote(`# ${title}`, { wrapWithPreTag: isLite }), + html: helper.embedMDNote(`# ${title}`, [], { wrapWithPreTag: isLite }), type: isLite ? 'lite/markdown' : 'document' } }) @@ -380,6 +410,7 @@ export default { getters.imageUrl(result, imageUploadService) ) } + if (imageUploadService === 'wizOfficialImageUploadService') commit(types.UPDATE_CURRENT_NOTE_RESOURCE, result) }, async moveNote ({ commit }, noteInfo) { const { kbGuid, docGuid } = noteInfo diff --git a/src/store/server/getters.js b/src/store/server/getters.js index 31e14a2..53deea5 100644 --- a/src/store/server/getters.js +++ b/src/store/server/getters.js @@ -10,7 +10,8 @@ export default { let img = '' switch (imageUploadService) { case 'wizOfficialImageUploadService': - img = docGuid ? `${api.KnowledgeBaseApi.getBaseUrl()}/ks/note/view/${kbGuid}/${docGuid}/${url}` : url + img = url.url + // img = docGuid ? `${api.KnowledgeBaseApi.getBaseUrl()}/ks/note/view/${kbGuid}/${docGuid}/${url.url}` : url break case 'smmsImageUploadService': case 'customWebUploadService': @@ -51,6 +52,14 @@ export default { } return helper.isNullOrEmpty(result) ? `# ${currentNote.info.title}` : result }, + currentNoteResources: ({ currentNote }) => { + const { resources } = currentNote + return resources + }, + currentNoteResourceUrl: ({ currentNote }) => { + const { info: { docGuid, kbGuid } } = currentNote + return `${api.KnowledgeBaseApi.getBaseUrl()}/${kbGuid}/${docGuid}` + }, categories: ({ categories }) => { return helper.generateCategoryNodeTree(categories) }, diff --git a/src/store/server/mutations.js b/src/store/server/mutations.js index 8884c91..0a6ab75 100644 --- a/src/store/server/mutations.js +++ b/src/store/server/mutations.js @@ -48,6 +48,15 @@ export default { } return state }, + [types.UPDATE_CURRENT_NOTE_RESOURCE] (state, newResource) { + if (state.currentNote && state.currentNote.resources) { + if (Array.isArray(newResource)) { + newResource.forEach(nr => state.currentNote.resources.push({ name: nr.name })) + } else { + state.currentNote.resources.push({ name: newResource.name }) + } + } + }, [types.SAVE_TO_LOCAL_STORE_SYNC] (state, [key, value]) { ClientFileStorage.setItemInStore(key, value) return state diff --git a/src/store/server/types.js b/src/store/server/types.js index b4ece60..8224cd2 100644 --- a/src/store/server/types.js +++ b/src/store/server/types.js @@ -3,6 +3,7 @@ export default { LOGOUT: 'logout', UPDATE_CURRENT_NOTES: 'update_current_notes', UPDATE_CURRENT_NOTE: 'update_current_note', + UPDATE_CURRENT_NOTE_RESOURCE: 'update_current_note_resource', INIT: 'init', SAVE_TO_LOCAL_STORE_SYNC: 'save_to_local_store_sync', UPDATE_ALL_CATEGORIES: 'update_all_categories', diff --git a/src/utils/helper.js b/src/utils/helper.js index d045507..78fa9ad 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -45,7 +45,7 @@ function convertHtml2Markdown (html, kbGuid, docGuid, resources) { */ function extractMarkdownFromMDNote (html, kbGuid, docGuid, resources = []) { resources.forEach(resource => { - html = html.replace(`index_files/${resource.name}`, resource.url) + html = html.replace(new RegExp(`index_files/${resource.name}`, 'g'), resource.url) }) return wizMarkdownParser.extract(html, { convertImgTag: true, @@ -56,10 +56,18 @@ function extractMarkdownFromMDNote (html, kbGuid, docGuid, resources = []) { /** * embed markdown source string to html string * @param markdown + * @param resources * @param options * @returns {string} */ -function embedMDNote (markdown, options) { +function embedMDNote (markdown, resources, options) { + resources.forEach(resource => { + const imgReg = new RegExp(`!\\[.*\\]\\(${resource.name}\\)`, 'g') + markdown = markdown.replace(resource.url, resource.name) + const result = imgReg.exec(markdown) + console.log(result) + markdown = markdown.replace(imgReg, `![](index_files/${resource.name})`) + }) return wizMarkdownParser.embed(markdown, options) } diff --git a/src/utils/storage/BaseFileStorage.js b/src/utils/storage/BaseFileStorage.js index 86fe34e..402cb66 100644 --- a/src/utils/storage/BaseFileStorage.js +++ b/src/utils/storage/BaseFileStorage.js @@ -80,8 +80,12 @@ class BaseFileStorage { } if (note.info.dataModified === dataModified) { note.info = info - this.setCachedNote(note, cacheKey) - return note + this.setCachedNote(note, cacheKey, note.cachedDate) + const now = new Date().getTime() + // 没有资源文件的时候直接返回缓存,如果有资源文件但是缓存时间小于三小时的也可以使用缓存 + if ((note.resources && note.resources.length === 0) || (note.cachedDate && now - note.cachedDate < 3 * 60 * 60 * 1000)) { + return note + } } else this.removeItemFromStore(cacheKey) return null } @@ -90,9 +94,10 @@ class BaseFileStorage { * 设置笔记缓存 * @param note * @param cacheKey + * @param {number} cachedDate */ - setCachedNote (note, cacheKey) { - this.setItemInStore(cacheKey, note) + setCachedNote (note, cacheKey, cachedDate) { + this.setItemInStore(cacheKey, { ...note, cachedDate: cachedDate || new Date().getTime() }) } } export default BaseFileStorage diff --git a/src/utils/storage/ServerFileStorage.js b/src/utils/storage/ServerFileStorage.js index 85232b4..cb2dc87 100644 --- a/src/utils/storage/ServerFileStorage.js +++ b/src/utils/storage/ServerFileStorage.js @@ -1,5 +1,6 @@ import BaseFileStorage from 'src/utils/storage/BaseFileStorage' import Store from 'electron-store' +// import { session } from 'electron' class ServerFileStorage extends BaseFileStorage { constructor () { super() @@ -8,6 +9,7 @@ class ServerFileStorage extends BaseFileStorage { name: 'ServerFileStorage', encryptionKey: 'server.file.storage' }) + // this._cookie = session.defaultSession.cookies } // Chrome LocalStorage @@ -16,7 +18,11 @@ class ServerFileStorage extends BaseFileStorage { } getValueFromLocalStorage (key) { - return JSON.parse(localStorage.getItem(key)) + try { + return JSON.parse(localStorage.getItem(key)) + } catch (e) { + return localStorage.getItem(key) + } } isKeyExistsInLocalStorage (key) { @@ -30,5 +36,14 @@ class ServerFileStorage extends BaseFileStorage { clearUpLocalStorage () { return localStorage.clear() } + + /** + * 设置cookie + * @param name + * @param value + */ + setCookie (name, value) { + this._cookie.set({ name, value }) + } } export default new ServerFileStorage()