Browse Source

add:markdown写文件选择地址

master
prr 6 months ago
parent
commit
de9693bf5a
  1. 4
      frontend/public/markdown/scripts/index.js
  2. 9
      frontend/src/components/computer/Computer.vue
  3. 132
      frontend/src/components/window/IframeFile.vue
  4. 6
      frontend/src/components/window/MenuFooter.vue
  5. 3
      frontend/src/components/window/WindowInner.vue
  6. 27
      frontend/src/components/window/WindowTemplate.vue
  7. 20
      frontend/src/stores/choose.ts
  8. 5
      frontend/src/system/window/BrowserWindow.ts
  9. 17
      frontend/src/util/eventBus.ts

4
frontend/public/markdown/scripts/index.js

@ -1,5 +1,6 @@
var markdownTitle = "" var markdownTitle = ""
let aiSelected = "" let aiSelected = ""
let componentID = ""
var CustomHookA = Cherry.createSyntaxHook('codeBlock', Cherry.constants.HOOKS_TYPE_LIST.PAR, { var CustomHookA = Cherry.createSyntaxHook('codeBlock', Cherry.constants.HOOKS_TYPE_LIST.PAR, {
makeHtml(str) { makeHtml(str) {
console.warn('custom hook', 'hello'); console.warn('custom hook', 'hello');
@ -441,7 +442,7 @@ const saveData = () => {
markdownTitle = window.prompt("请输入文稿标题"); markdownTitle = window.prompt("请输入文稿标题");
} }
const postData = { title: markdownTitle, content: cherry.getMarkdown() } const postData = { title: markdownTitle, content: cherry.getMarkdown() }
window.parent.postMessage({ type: 'exportMd', data: JSON.stringify(postData) }, '*') window.parent.postMessage({ type: 'exportMd', data: JSON.stringify(postData),componentID }, '*')
} }
var saveMenu = Cherry.createMenuHook('保存', { var saveMenu = Cherry.createMenuHook('保存', {
onClick: function () { onClick: function () {
@ -701,6 +702,7 @@ function decodeBase64(base64String) {
} }
const eventHandler = (e) => { const eventHandler = (e) => {
const eventData = e.data const eventData = e.data
componentID = eventData.componentID ? eventData.componentID : ''
if (eventData.type === 'start') { if (eventData.type === 'start') {
markdownTitle = eventData.title || '未命名文稿' markdownTitle = eventData.title || '未命名文稿'
return return

9
frontend/src/components/computer/Computer.vue

@ -167,7 +167,16 @@
const system = useSystem(); const system = useSystem();
const { dragFileToDrop } = useFileDrag(system); const { dragFileToDrop } = useFileDrag(system);
const { createDesktopContextMenu } = useContextMenu(); const { createDesktopContextMenu } = useContextMenu();
//
const props = defineProps({
translateSavePath: {
type: Function
}
})
const setRouter = function (path: string) { const setRouter = function (path: string) {
if (props.translateSavePath) {
props.translateSavePath(path)
}
router_url.value = path; router_url.value = path;
if ( if (
router_url_history_index.value <= router_url_history_index.value <=

132
frontend/src/components/window/IframeFile.vue

@ -10,6 +10,8 @@ import { isShareFile } from "@/util/sharePath.ts";
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue"; import { inject, onMounted, onUnmounted, ref, toRaw } from "vue";
import { askAi } from "@/hook/useAi"; import { askAi } from "@/hook/useAi";
import { useChooseStore } from "@/stores/choose"; import { useChooseStore } from "@/stores/choose";
import { nanoid } from "nanoid";
import eventBus from "@/util/eventBus";
const SP = getSplit(); const SP = getSplit();
const sys: any = inject<System>("system"); const sys: any = inject<System>("system");
@ -28,21 +30,15 @@ const props = defineProps({
default: "md", default: "md",
}, },
}); });
//console.log('iframe: ', props);
//console.log(props);
//let path = win?.config?.path;
// let currentPath = ref('')
const storeRef = ref<HTMLIFrameElement | null>(null); const storeRef = ref<HTMLIFrameElement | null>(null);
let hasInit = false; let hasInit = false;
const choose = useChooseStore(); const choose = useChooseStore();
const eventHandler = async (e: MessageEvent) => { const componentID = nanoid();
const eventData = e.data; // console.log("ID", componentID);
if (eventData.type == props.eventType) { const saveFile = async (e: any) => {
let data = JSON.parse(eventData.data); if (e.componentID !== componentID) return;
let title = data.title; let data = JSON.parse(e.eventData.data);
let path;
let ext: any = props.ext; let ext: any = props.ext;
if (ext instanceof Array) { if (ext instanceof Array) {
ext = ext[0]; ext = ext[0];
@ -50,33 +46,24 @@ const eventHandler = async (e: MessageEvent) => {
if (data.ext) { if (data.ext) {
ext = data.ext; ext = data.ext;
} }
if (title.indexOf('.' + ext) > -1) { let path:string
title = title.replace('.' + ext, ""); e.filePath !== ""
} ? (path = `${e.filePath}/${e.fileName}.${ext}`)
if (win.config && win.config.path) { : (path = `${SP}C${SP}Users${SP}Desktop${SP}${e.fileName}.${ext}`);
path = win.config.path; // console.log('',path);
await writeFile(path, data, e.fileName);
//1 };
let fileTitleArr = path.split(SP).pop().split("."); eventBus.on("saveFile", saveFile);
let oldExt = fileTitleArr.pop(); const writeFile = async (path: string, data: any, title: string) => {
let fileTitle = fileTitleArr.join(".");
if (fileTitle != title) {
path = path.replace(fileTitle, title);
}
if (oldExt != ext) {
path = path.replace("." + oldExt, "." + ext);
}
} else {
choose.saveFile('选择地址','*')
path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`;
}
//
const isShare = ref(false); const isShare = ref(false);
const isWrite = ref(0); const isWrite = ref(0);
if (isShareFile(path)) { if (isShareFile(path)) {
const file = await sys?.fs.getShareInfo(path); const file = await sys?.fs.getShareInfo(path);
isShare.value = true; isShare.value = true;
isWrite.value = file.fs.sender === getSystemConfig().userInfo.id ? 1 : file.fs.is_write; isWrite.value =
file.fs.sender === getSystemConfig().userInfo.id
? 1
: file.fs.is_write;
if ( if (
!isWrite.value && !isWrite.value &&
file.fs.sender !== getSystemConfig().userInfo.id file.fs.sender !== getSystemConfig().userInfo.id
@ -111,19 +98,54 @@ const eventHandler = async (e: MessageEvent) => {
} }
const res = isShare.value const res = isShare.value
? await sys?.fs.writeShareFile( ? await sys?.fs.writeShareFile(path, data.content, isWrite.value)
path,
data.content,
isWrite.value
)
: await sys?.fs.writeFile(path, data.content); : await sys?.fs.writeFile(path, data.content);
// console.log("", res, isShare); // console.log("", res, isShare);
new Notify({ new Notify({
title: "提示", title: "提示",
content: res.message content: res.message,
// content: res.code === 0 ? "" : res.message, // content: res.code === 0 ? "" : res.message,
}); });
sys.refershAppList(); sys.refershAppList();
};
const eventHandler = async (e: MessageEvent) => {
const eventData = e.data;
// console.log('', componentID == eventData.componentID);
if (eventData.type == props.eventType) {
// if (eventData.componentID !== componentID) return;
let data = JSON.parse(eventData.data);
let title = data.title;
let path;
let ext: any = props.ext;
if (ext instanceof Array) {
ext = ext[0];
}
if (data.ext) {
ext = data.ext;
}
if (title.indexOf("." + ext) > -1) {
title = title.replace("." + ext, "");
}
if (win.config && win.config.path) {
path = win.config.path;
//1
let fileTitleArr = path.split(SP).pop().split(".");
let oldExt = fileTitleArr.pop();
let fileTitle = fileTitleArr.join(".");
if (fileTitle != title) {
path = path.replace(fileTitle, title);
}
if (oldExt != ext) {
path = path.replace("." + oldExt, "." + ext);
}
} else {
choose.saveFile("选择地址", "*", componentID, eventData);
return;
// path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`;
}
writeFile(path, data, title);
} else if (eventData.type == "initSuccess") { } else if (eventData.type == "initSuccess") {
if (hasInit) { if (hasInit) {
return; return;
@ -154,6 +176,7 @@ const eventHandler = async (e: MessageEvent) => {
{ {
type: "init", type: "init",
data: { content, title }, data: { content, title },
componentID,
}, },
"*" "*"
); );
@ -162,16 +185,15 @@ const eventHandler = async (e: MessageEvent) => {
{ {
type: "start", type: "start",
title, title,
componentID,
}, },
"*" "*"
); );
} }
} } else if (eventData.type == "close") {
else if (eventData.type == "close") {
// console.log(""); // console.log("");
win.close(); win.close();
} } else if (eventData.type == "saveMind") {
else if (eventData.type == "saveMind") {
// console.log(""); // console.log("");
const data = eventData.data; const data = eventData.data;
const path = win?.config?.path; const path = win?.config?.path;
@ -181,9 +203,9 @@ const eventHandler = async (e: MessageEvent) => {
url: "/mind/index.html", url: "/mind/index.html",
frame: true, frame: true,
config: { config: {
ext: 'mind', ext: "mind",
path: path, path: path,
content: data.content content: data.content,
}, },
icon: "gallery", icon: "gallery",
width: 700, width: 700,
@ -194,29 +216,27 @@ const eventHandler = async (e: MessageEvent) => {
minimizable: false, minimizable: false,
resizable: true, resizable: true,
}); });
winMind.show() winMind.show();
} else if (eventData.type == "aiCreater") {
} console.log("传递内容: ", eventData);
else if (eventData.type == 'aiCreater') { let postData: any = {};
console.log('传递内容: ', eventData)
let postData: any = {}
if (eventData.data) { if (eventData.data) {
postData.content = eventData.data postData.content = eventData.data;
} }
if (eventData.title) { if (eventData.title) {
postData.title = eventData.title postData.title = eventData.title;
} }
if (eventData.category) { if (eventData.category) {
postData.category = eventData.category postData.category = eventData.category;
} }
//console.log(postData,eventData.action) //console.log(postData,eventData.action)
// AI // AI
const res: any = await askAi(postData, eventData.action); const res: any = await askAi(postData, eventData.action);
storeRef.value?.contentWindow?.postMessage( storeRef.value?.contentWindow?.postMessage(
{ {
type: 'aiReciver', type: "aiReciver",
data: res, data: res,
action: eventData.action action: eventData.action,
}, },
"*" "*"
); );

6
frontend/src/components/window/MenuFooter.vue

@ -16,13 +16,15 @@ import { UnwrapNestedRefs, ref } from "vue";
const props = defineProps<{ const props = defineProps<{
browserWindow: UnwrapNestedRefs<BrowserWindow>; browserWindow: UnwrapNestedRefs<BrowserWindow>;
}>(); }>();
const emit = defineEmits(['translateSavePath'])
let fileName = ref('未命名文件') let fileName = ref('未命名文件')
//console.log('', props.browserWindow);
function cancleSave() { function cancleSave() {
props.browserWindow.close() props.browserWindow.close()
} }
function saveFile() { function saveFile() {
emit('translateSavePath','',fileName.value)
props.browserWindow.close()
} }
</script> </script>

3
frontend/src/components/window/WindowInner.vue

@ -1,7 +1,7 @@
<template> <template>
<IframeFile v-if="win.url" :src="win.url" :ext="win.ext" :eventType="win.eventType" /> <IframeFile v-if="win.url" :src="win.url" :ext="win.ext" :eventType="win.eventType" />
<Suspense v-else> <Suspense v-else>
<component v-if="win.content" :is="stepComponent(win.content)"></component> <component v-if="win.content" :is="stepComponent(win.content)" :translateSavePath="translateSavePath"></component>
<RouterView v-else /> <RouterView v-else />
</Suspense> </Suspense>
<!-- <component :is="window.content"></component> --> <!-- <component :is="window.content"></component> -->
@ -14,6 +14,7 @@ const props = defineProps<{
win: any; win: any;
}>(); }>();
const win = ref(props.win) const win = ref(props.win)
const translateSavePath = inject('translateSavePath')
if (props.win.path) { if (props.win.path) {
router.push(props.win.path); router.push(props.win.path);
} }

27
frontend/src/components/window/WindowTemplate.vue

@ -52,7 +52,7 @@
@touchstart.stop.passive="startScale($event, border.type)" @touchstart.stop.passive="startScale($event, border.type)"
></div> ></div>
<div class="wintmp_footer" v-if="browserWindow.windowInfo.footer"> <div class="wintmp_footer" v-if="browserWindow.windowInfo.footer">
<MenuFooter :browser-window="browserWindow"></MenuFooter> <MenuFooter :browser-window="browserWindow" @translateSavePath="translateSavePath"></MenuFooter>
</div> </div>
</div> </div>
</template> </template>
@ -73,6 +73,8 @@
ref, ref,
UnwrapNestedRefs, UnwrapNestedRefs,
} from "vue"; } from "vue";
import { useChooseStore } from "@/stores/choose";
import eventBus from '@/util/eventBus'
const sys = useSystem(); const sys = useSystem();
const props = defineProps<{ const props = defineProps<{
@ -81,15 +83,28 @@
const browserWindow = props.browserWindow; const browserWindow = props.browserWindow;
// console.log('', browserWindow);
const windowInfo = browserWindow.windowInfo; const windowInfo = browserWindow.windowInfo;
// const temp = reactive(browserWindow)
provide("browserWindow", browserWindow); provide("browserWindow", browserWindow);
provide("system", sys); provide("system", sys);
// let filePath = ref(inject('saveFilePath')) const choose = useChooseStore()
// watch(filePath, (newVal) => {
// console.log('', newVal); function translateSavePath (path: string, name?: string) {
if (browserWindow.windowInfo.footer) {
const pos = choose.saveFileContent.findIndex((item) => {
return item.componentID == browserWindow.windowInfo.componentID
})
if (pos == -1) return
if (path && path !== '') {
choose.saveFileContent[pos].filePath = path
} else if (name && name !== '') {
choose.saveFileContent[pos].fileName = name
eventBus.emit('saveFile', choose.saveFileContent[pos] )
}
}
}
provide('translateSavePath', translateSavePath)
// })
function predown() { function predown() {
browserWindow.moveTop(); browserWindow.moveTop();
emitEvent("window.content.click", browserWindow); emitEvent("window.content.click", browserWindow);

20
frontend/src/stores/choose.ts

@ -5,7 +5,11 @@ export const useChooseStore = defineStore('chooseStore', () => {
const win:any = ref() const win:any = ref()
const path:any = ref([]) const path:any = ref([])
const ifShow = ref(false) const ifShow = ref(false)
//const savePath:any = ref('') let savePath = ref({
path: '',
name: ''
})
const saveFileContent = ref<any[]>([])
const select = (title = '选择文件', fileExt:any) => { const select = (title = '选择文件', fileExt:any) => {
win.value = new BrowserWindow({ win.value = new BrowserWindow({
@ -27,7 +31,7 @@ export const useChooseStore = defineStore('chooseStore', () => {
win.value.show() win.value.show()
ifShow.value = true ifShow.value = true
} }
const saveFile = (title: string, fileExt: any) => { const saveFile = (title: string, fileExt: any, componentID: string, eventData: any) => {
// console.log('保存文件'); // console.log('保存文件');
win.value = new BrowserWindow({ win.value = new BrowserWindow({
title, title,
@ -44,9 +48,17 @@ export const useChooseStore = defineStore('chooseStore', () => {
center: true, center: true,
minimizable: false, minimizable: false,
resizable: true, resizable: true,
footer: true footer: true,
componentID
}); });
win.value.show() win.value.show()
saveFileContent.value.push({
componentID,
eventData,
filePath: '',
fileName: ''
})
return savePath
// ifShow.value = true // ifShow.value = true
} }
const close = () => { const close = () => {
@ -58,6 +70,8 @@ export const useChooseStore = defineStore('chooseStore', () => {
win, win,
path, path,
ifShow, ifShow,
savePath,
saveFileContent,
select, select,
close, close,
saveFile saveFile

5
frontend/src/system/window/BrowserWindow.ts

@ -33,6 +33,7 @@ export interface BrowserWindowConstructorOptions {
skipTaskbar: boolean; skipTaskbar: boolean;
backgroundColor: string; backgroundColor: string;
footer: boolean; footer: boolean;
componentID: string;
} }
export interface WindowInfo extends BrowserWindowConstructorOptions { export interface WindowInfo extends BrowserWindowConstructorOptions {
state: WindowStateEnum; state: WindowStateEnum;
@ -61,7 +62,8 @@ class BrowserWindow {
alwaysOnTop: false, alwaysOnTop: false,
skipTaskbar: false, skipTaskbar: false,
backgroundColor: '#fff', backgroundColor: '#fff',
footer: false footer: false,
componentID: ''
}; };
public static defaultInfo: Omit<WindowInfo, keyof BrowserWindowConstructorOptions> = { public static defaultInfo: Omit<WindowInfo, keyof BrowserWindowConstructorOptions> = {
state: WindowStateEnum.normal, state: WindowStateEnum.normal,
@ -115,6 +117,7 @@ class BrowserWindow {
previousState: this.windowInfo.state, previousState: this.windowInfo.state,
}; };
this.windowInfo.footer = option?.footer || false this.windowInfo.footer = option?.footer || false
this.windowInfo.componentID = option?.componentID || ''
} }
_setZindex() { _setZindex() {

17
frontend/src/util/eventBus.ts

@ -0,0 +1,17 @@
let eventBus = {
events: {} as { [key: string]: Function[]},
on: function (eventName: string, callback: Function) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
},
emit: function (eventName:string, ...args: any[]) {
if (this.events[eventName]) {
this.events[eventName].forEach((callback) => {
callback(...args);
});
}
}
};
export default eventBus;
Loading…
Cancel
Save