Browse Source

fix:企业版文件加密

master
18786462055 8 months ago
parent
commit
795d76dd82
  1. 287
      frontend/src/components/builtin/FileList.vue
  2. 5
      frontend/src/components/builtin/FileTree.vue
  3. 154
      frontend/src/components/computer/Computer.vue
  4. 76
      frontend/src/components/computer/ComputerNavBar.vue
  5. 50
      frontend/src/components/oa/FilePwd.vue
  6. 86
      frontend/src/components/window/IframeFile.vue
  7. 13
      frontend/src/system/config.ts
  8. 79
      frontend/src/system/core/FileOs.ts
  9. 8
      frontend/src/system/core/FileSystem.ts
  10. 22
      frontend/src/system/index.ts
  11. 6
      frontend/src/system/window/Dialog.ts

287
frontend/src/components/builtin/FileList.vue

@ -17,7 +17,10 @@
</div> </div>
</div> </div>
</template> </template>
<div draggable="true" class="file-item" :class="{ <div
draggable="true"
class="file-item"
:class="{
chosen: chosenIndexs.includes(index), chosen: chosenIndexs.includes(index),
'no-chosen': !chosenIndexs.includes(index), 'no-chosen': !chosenIndexs.includes(index),
'mode-icon': mode === 'icon', 'mode-icon': mode === 'icon',
@ -26,27 +29,52 @@
'mode-middle': mode === 'middle', 'mode-middle': mode === 'middle',
'mode-detail': mode === 'detail', 'mode-detail': mode === 'detail',
'drag-over': hoverIndex === index, 'drag-over': hoverIndex === index,
}" :style="{ }"
:style="{
'--theme-color': theme === 'light' ? '#ffffff6b' : '#3bdbff3d', '--theme-color': theme === 'light' ? '#ffffff6b' : '#3bdbff3d',
}" v-for="(item, index) in fileList" :key="item.path" @dblclick="handleOnOpen(item)" }"
@touchstart.passive="doubleTouch($event, item)" @contextmenu.stop.prevent="handleRightClick($event, item, index)" v-for="(item, index) in fileList"
@drop="hadnleDrop($event, item.path)" @dragenter.prevent="handleDragEnter(index)" @dragover.prevent :key="item.path"
@dragleave="handleDragLeave()" @dragstart.stop="startDragApp($event, item)" @click="handleClick(index)" @dblclick="handleOnOpen(item)"
@mousedown.stop :ref="(ref: any) => { @touchstart.passive="doubleTouch($event, item)"
@contextmenu.stop.prevent="handleRightClick($event, item, index)"
@drop="hadnleDrop($event, item.path)"
@dragenter.prevent="handleDragEnter(index)"
@dragover.prevent
@dragleave="handleDragLeave()"
@dragstart.stop="startDragApp($event, item)"
@click="handleClick(index)"
@mousedown.stop
:ref="(ref: any) => {
if (ref) { if (ref) {
appPositions[index] = markRaw(ref as Element); appPositions[index] = markRaw(ref as Element);
} }
} }
"> "
>
<div class="file-item_img"> <div class="file-item_img">
<FileIcon :file="item" /> <FileIcon :file="item" />
</div> </div>
<span v-if="editIndex !== index" class="file-item_title"> <span
v-if="editIndex !== index"
class="file-item_title"
>
{{ getName(item) }} {{ getName(item) }}
</span> </span>
<textarea autofocus draggable="false" @dragover.stop @dragstart.stop @dragenter.stop @mousedown.stop @dblclick.stop <textarea
@click.stop @blur="onEditNameEnd" v-if="editIndex === index" class="file-item_title file-item_editing" autofocus
v-model="editName"></textarea> draggable="false"
@dragover.stop
@dragstart.stop
@dragenter.stop
@mousedown.stop
@dblclick.stop
@click.stop
@blur="onEditNameEnd"
v-if="editIndex === index"
class="file-item_title file-item_editing"
v-model="editName"
></textarea>
<template v-if="mode === 'detail'"> <template v-if="mode === 'detail'">
<div class="file-item_type"> <div class="file-item_type">
<span>{{ item.isDirectory ? "-" : dealSize(item.size) }}</span> <span>{{ item.isDirectory ? "-" : dealSize(item.size) }}</span>
@ -64,23 +92,30 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useSystem, basename, OsFileWithoutContent, Notify, BrowserWindow } from '@/system/index.ts'; import { useAppMenu } from "@/hook/useAppMenu";
import { getSystemKey } from '@/system/config' import { useContextMenu } from "@/hook/useContextMenu.ts";
import { emitEvent, mountEvent } from '@/system/event'; import { useFileDrag } from "@/hook/useFileDrag";
import { useContextMenu } from '@/hook/useContextMenu.ts'; import { Rect } from "@/hook/useRectChosen";
import { t, dealSystemName } from '@/i18n'; import { dealSystemName, t } from "@/i18n";
import { useFileDrag } from '@/hook/useFileDrag';
import { useAppMenu } from '@/hook/useAppMenu';
import { onMounted, ref, markRaw } from 'vue';
import { Rect } from '@/hook/useRectChosen';
import { throttle } from '@/util/debounce';
import { dealSize } from '@/util/file';
import { Menu } from '@/system/menu/Menu';
import { useChooseStore } from "@/stores/choose"; import { useChooseStore } from "@/stores/choose";
const { openPropsWindow, copyFile, createLink, deleteFile } = useContextMenu(); import { getSystemKey } from "@/system/config";
import { emitEvent, mountEvent } from "@/system/event";
import {
basename,
BrowserWindow,
Notify,
OsFileWithoutContent,
useSystem,
} from "@/system/index.ts";
import { Menu } from "@/system/menu/Menu";
import { throttle } from "@/util/debounce";
import { dealSize } from "@/util/file";
import { markRaw, onMounted, ref } from "vue";
const { openPropsWindow, copyFile, createLink, deleteFile } =
useContextMenu();
const sys = useSystem(); const sys = useSystem();
const { startDrag, folderDrop } = useFileDrag(sys); const { startDrag, folderDrop } = useFileDrag(sys);
const choose = useChooseStore() const choose = useChooseStore();
const props = defineProps({ const props = defineProps({
onChosen: { onChosen: {
type: Function, type: Function,
@ -104,22 +139,22 @@ const props = defineProps({
}, },
theme: { theme: {
type: String || Object, type: String || Object,
default: 'light', default: "light",
}, },
mode: { mode: {
type: String, type: String,
default: 'icon', default: "icon",
}, },
}); });
function getName(item: any) { function getName(item: any) {
const name = dealSystemName(basename(item.path)) const name = dealSystemName(basename(item.path));
// console.log(name) // console.log(name)
// console.log(item.path) // console.log(item.path)
if (name.endsWith('.exe')) { if (name.endsWith(".exe")) {
return t(name.replace('.exe', "")) return t(name.replace(".exe", ""));
} else { } else {
return name return name;
} }
} }
function handleOnOpen(item: OsFileWithoutContent) { function handleOnOpen(item: OsFileWithoutContent) {
@ -127,13 +162,13 @@ function handleOnOpen(item: OsFileWithoutContent) {
// emitEvent('desktop.app.open'); // emitEvent('desktop.app.open');
chosenIndexs.value = []; chosenIndexs.value = [];
if (choose.ifShow && !item.isDirectory) { if (choose.ifShow && !item.isDirectory) {
choose.path.push(item.path) choose.path.push(item.path);
choose.close() choose.close();
} else { } else {
// console.log(' file list:',props.fileList); // console.log(' file list:',props.fileList);
props.onOpen(item); props.onOpen(item);
emitEvent('desktop.app.open'); emitEvent("desktop.app.open");
} }
} }
function hadnleDrop(mouse: DragEvent, path: string) { function hadnleDrop(mouse: DragEvent, path: string) {
@ -160,33 +195,30 @@ function doubleTouch(e: TouchEvent, item: OsFileWithoutContent) {
} }
const editIndex = ref<number>(-1); const editIndex = ref<number>(-1);
const editName = ref<string>(''); const editName = ref<string>("");
async function onEditNameEnd() { async function onEditNameEnd() {
const editEndName = editName.value.trim(); const editEndName = editName.value.trim();
if (editEndName && editIndex.value >= 0) { if (editEndName && editIndex.value >= 0) {
const editpath: any = props.fileList[editIndex.value].path.toString() const editpath: any =
props.fileList[editIndex.value].path.toString();
let newPath: any; let newPath: any;
let sp = "/" let sp = "/";
if (editpath.indexOf("/") === -1) { if (editpath.indexOf("/") === -1) {
sp = "\\" sp = "\\";
} }
newPath = editpath?.split(sp); newPath = editpath?.split(sp);
newPath.pop() newPath.pop();
newPath.push(editEndName) newPath.push(editEndName);
newPath = newPath.join(sp) newPath = newPath.join(sp);
await sys?.fs.rename( await sys?.fs.rename(editpath, newPath);
editpath,
newPath
);
props.onRefresh(); props.onRefresh();
if (newPath.indexOf("Desktop") !== -1) { if (newPath.indexOf("Desktop") !== -1) {
sys.refershAppList() sys.refershAppList();
} }
} }
editIndex.value = -1; editIndex.value = -1;
} }
mountEvent('edit.end', () => { mountEvent("edit.end", () => {
onEditNameEnd(); onEditNameEnd();
}); });
@ -240,35 +272,39 @@ function startDragApp(mouse: DragEvent, item: OsFileWithoutContent) {
} }
} }
function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index: number) { function handleRightClick(
mouse: MouseEvent,
item: OsFileWithoutContent,
index: number
) {
if (chosenIndexs.value.length <= 1) { if (chosenIndexs.value.length <= 1) {
chosenIndexs.value = [props.fileList.findIndex((app) => app.path === item.path)]; chosenIndexs.value = [
props.fileList.findIndex((app) => app.path === item.path),
];
} }
const ext = item.name.split(".").pop(); const ext = item.name.split(".").pop();
const zipSucess = (res: any) => { const zipSucess = (res: any) => {
if (!res || res.code < 0) { if (!res || res.code < 0) {
new Notify({ new Notify({
title: t('tips'), title: t("tips"),
content: t('error'), content: t("error"),
}); });
} else { } else {
props.onRefresh(); props.onRefresh();
new Notify({ new Notify({
title: t('tips'), title: t("tips"),
content: t('file.zip.success'), content: t("file.zip.success"),
}); });
if (item.parentPath == '/C/Users/Desktop') { if (item.parentPath == "/C/Users/Desktop") {
sys.refershAppList() sys.refershAppList();
} }
} }
}; };
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let menuArr: any = [ let menuArr: any = [
{ {
label: t('open'), label: t("open"),
click: () => { click: () => {
chosenIndexs.value = []; chosenIndexs.value = [];
props.onOpen(item); props.onOpen(item);
@ -281,78 +317,80 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
// openWith(item); // openWith(item);
// }, // },
// }, // },
]; ];
if (item.isDirectory && !item.isShare) { if (item.isDirectory && !item.isShare) {
if (getSystemKey('storeType') == 'local') { if (getSystemKey("storeType") == "local") {
menuArr.push({ menuArr.push({
label: t('zip'), label: t("zip"),
submenu: [ submenu: [
{ {
label: 'zip', label: "zip",
click: () => { click: () => {
sys.fs.zip(item.path, 'zip').then((res: any) => { sys.fs
zipSucess(res) .zip(item.path, "zip")
.then((res: any) => {
zipSucess(res);
}); });
}, },
}, },
{ {
label: 'tar', label: "tar",
click: () => { click: () => {
sys.fs.zip(item.path, 'tar').then((res: any) => { sys.fs
zipSucess(res) .zip(item.path, "tar")
.then((res: any) => {
zipSucess(res);
}); });
}, },
}, },
{ {
label: 'gz', label: "gz",
click: () => { click: () => {
sys.fs.zip(item.path, 'gz').then((res: any) => { sys.fs.zip(item.path, "gz").then((res: any) => {
zipSucess(res) zipSucess(res);
}); });
}, },
}, },
], ],
}) });
} else { } else {
menuArr.push({ menuArr.push({
label: t('zip'), label: t("zip"),
click: () => { click: () => {
sys.fs.zip(item.path, 'zip').then((res: any) => { sys.fs.zip(item.path, "zip").then((res: any) => {
zipSucess(res) zipSucess(res);
}); });
}, },
}) });
} }
} }
if (choose.ifShow) { if (choose.ifShow) {
menuArr.push({ menuArr.push({
label: "选中发送", label: "选中发送",
click: () => { click: () => {
const paths: any = [] const paths: any = [];
chosenIndexs.value.forEach((index) => { chosenIndexs.value.forEach((index) => {
const item = props.fileList[index]; const item = props.fileList[index];
paths.push(item.path) paths.push(item.path);
}) });
if (paths.length > 0) { if (paths.length > 0) {
choose.path = paths choose.path = paths;
choose.close() choose.close();
} }
chosenIndexs.value = []; chosenIndexs.value = [];
}, },
}) });
} }
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let extMenus = useAppMenu(item, sys, props); let extMenus = useAppMenu(item, sys, props);
if (extMenus && extMenus.length > 0) { if (extMenus && extMenus.length > 0) {
// eslint-disable-next-line prefer-spread // eslint-disable-next-line prefer-spread
menuArr.push.apply(menuArr, extMenus) menuArr.push.apply(menuArr, extMenus);
} }
if (ext != 'exe') { if (ext != "exe") {
const fileMenus = [ const fileMenus = [
{ {
label: t('rename'), label: t("rename"),
click: () => { click: () => {
editIndex.value = index; editIndex.value = index;
editName.value = basename(item.path); editName.value = basename(item.path);
@ -360,50 +398,58 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
}, },
}, },
{ {
label: t('copy'), label: t("copy"),
click: () => { click: () => {
//if(["/","/B"].includes(item.path)) return; //if(["/","/B"].includes(item.path)) return;
copyFile(chosenIndexs.value.map((index) => props.fileList[index])); copyFile(
chosenIndexs.value.map(
(index) => props.fileList[index]
)
);
chosenIndexs.value = []; chosenIndexs.value = [];
}, },
}, },
]; ];
if (!item.isShare || item.path.indexOf('/F/othershare') !== 0) { if (!item.isShare || item.path.indexOf("/F/othershare") !== 0) {
fileMenus.push({ fileMenus.push({
label: t('delete'), label: t("delete"),
click: async () => { click: async () => {
for (let i = 0; i < chosenIndexs.value.length; i++) { for (let i = 0; i < chosenIndexs.value.length; i++) {
await deleteFile(props.fileList[chosenIndexs.value[i]]); await deleteFile(
props.fileList[chosenIndexs.value[i]]
);
} }
chosenIndexs.value = []; chosenIndexs.value = [];
props.onRefresh(); props.onRefresh();
if (item.path.indexOf('Desktop') > -1) { if (item.path.indexOf("Desktop") > -1) {
sys.refershAppList() sys.refershAppList();
} }
}, },
}) });
} }
if (!item.isShare) { if (!item.isShare) {
fileMenus.push({ fileMenus.push({
label: t('create.shortcut'), label: t("create.shortcut"),
click: () => { click: () => {
createLink(item.path)?.then(() => { createLink(item.path)?.then(() => {
chosenIndexs.value = []; chosenIndexs.value = [];
props.onRefresh(); props.onRefresh();
}); });
}, },
},) });
} }
const userType = sys.getConfig('userType'); const userType = sys.getConfig("userType");
if (userType == 'member' && !item.isShare && !item.isDirectory) { interface UserInfo {
isPwd?: boolean
menuArr.push( }
{ const userInfo = sys.getConfig("userInfo") as UserInfo
label: '分享给...', const isPwd = userInfo?.isPwd || false;
if (userType == "member" && !item.isShare && !item.isDirectory) {
menuArr.push({
label: "分享给...",
click: () => { click: () => {
const win = new BrowserWindow({ const win = new BrowserWindow({
title: '分享', title: "分享",
content: "ShareFiles", content: "ShareFiles",
config: { config: {
path: item.path, path: item.path,
@ -414,14 +460,13 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
}); });
win.show(); win.show();
}, },
} });
) if (isPwd) {
menuArr.push( menuArr.push({
{ label: "文件加密",
label: '文件加密',
click: () => { click: () => {
const win = new BrowserWindow({ const win = new BrowserWindow({
title: '文件加密', title: "文件加密",
content: "FilePwd", content: "FilePwd",
config: { config: {
path: item.path, path: item.path,
@ -432,14 +477,13 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
}); });
win.show(); win.show();
}, },
});
} }
) menuArr.push({
menuArr.push( label: "评论",
{
label: '评论',
click: () => { click: () => {
const win = new BrowserWindow({ const win = new BrowserWindow({
title: '评论', title: "评论",
content: "CommentsFiles", content: "CommentsFiles",
config: { config: {
path: item.path, path: item.path,
@ -450,25 +494,24 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
}); });
win.show(); win.show();
}, },
} });
)
} }
// eslint-disable-next-line prefer-spread // eslint-disable-next-line prefer-spread
menuArr.push.apply(menuArr, fileMenus) menuArr.push.apply(menuArr, fileMenus);
} }
const sysEndMenu = [ const sysEndMenu = [
{ {
label: t('props'), label: t("props"),
click: () => { click: () => {
chosenIndexs.value.forEach((index) => { chosenIndexs.value.forEach((index) => {
openPropsWindow(props.fileList[index].path); openPropsWindow(props.fileList[index].path);
chosenIndexs.value = []; chosenIndexs.value = [];
}); });
}, },
} },
]; ];
// eslint-disable-next-line prefer-spread // eslint-disable-next-line prefer-spread
menuArr.push.apply(menuArr, sysEndMenu) menuArr.push.apply(menuArr, sysEndMenu);
//console.log(item) //console.log(item)
//console.log(ext) //console.log(ext)

5
frontend/src/components/builtin/FileTree.vue

@ -51,7 +51,6 @@
import { useSystem,OsFileWithoutContent,basename } from '@/system/index.ts'; import { useSystem,OsFileWithoutContent,basename } from '@/system/index.ts';
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { dealSystemName } from '@/i18n'; import { dealSystemName } from '@/i18n';
import { getSystemConfig } from "@/system/config";
import { isShareFile } from '@/util/sharePath'; import { isShareFile } from '@/util/sharePath';
const sys = useSystem(); const sys = useSystem();
@ -113,7 +112,7 @@ function onSubOpen(path: string) {
async function onSubRefresh(item: FileWithOpen) { async function onSubRefresh(item: FileWithOpen) {
if(isShareFile(item.path)) { if(isShareFile(item.path)) {
item.subFileList = (await sys.fs.sharedir(getSystemConfig().userInfo.id, item?.path)).filter((file:any) => { item.subFileList = (await sys.fs.sharedir(item?.path)).filter((file:any) => {
return file.isDirectory; return file.isDirectory;
}); });
} else { } else {
@ -135,7 +134,7 @@ async function onOpenArrow(item: FileWithOpen) {
// }); // });
// } else // } else
if(isShareFile(item.path)) { if(isShareFile(item.path)) {
item.subFileList = (await sys.fs.sharedir(getSystemConfig().userInfo.id, item?.path)).filter((file:any) => { item.subFileList = (await sys.fs.sharedir(item?.path)).filter((file:any) => {
return file.isDirectory; return file.isDirectory;
}); });
} else { } else {

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

@ -3,12 +3,25 @@
<div class="group"> <div class="group">
<!-- <div class="button">文件</div> --> <!-- <div class="button">文件</div> -->
<!-- <div class="button">计算机</div> --> <!-- <div class="button">计算机</div> -->
<div class="button" @click="backFolder()">{{ t("back") }}</div> <div
class="button"
@click="backFolder()"
>
{{ t("back") }}
</div>
<!-- 查看 --> <!-- 查看 -->
<div class="button" @click="popoverChange()">{{ t("view") }}</div> <div
class="button"
@click="popoverChange()"
>
{{ t("view") }}
</div>
<!-- <div class="button" @click="newFolder()">新建</div> --> <!-- <div class="button" @click="newFolder()">新建</div> -->
</div> </div>
<div v-if="isPopoverView" class="up-pop"> <div
v-if="isPopoverView"
class="up-pop"
>
<UpPopover v-model="chosenView"></UpPopover> <UpPopover v-model="chosenView"></UpPopover>
</div> </div>
<ComputerNavBar <ComputerNavBar
@ -19,15 +32,24 @@
@changeHistory="handleHistoryChange" @changeHistory="handleHistoryChange"
></ComputerNavBar> ></ComputerNavBar>
</div> </div>
<div class="main" @click="handleOuterClick"> <div
class="main"
@click="handleOuterClick"
>
<div <div
class="left-tree" class="left-tree"
:style="{ :style="{
width: leftWidth + 'px', width: leftWidth + 'px',
}" }"
> >
<div class="disktopshow" @click="onTreeOpen('/C/Users/Desktop')"> <div
<el-icon :size="20" color="#137bd2"> class="disktopshow"
@click="onTreeOpen('/C/Users/Desktop')"
>
<el-icon
:size="20"
color="#137bd2"
>
<Platform /> <Platform />
</el-icon> </el-icon>
{{ t("desktop") }} {{ t("desktop") }}
@ -42,7 +64,12 @@
:key="random" :key="random"
> >
</FileTree> </FileTree>
<div class="showName" v-if="shareShow">{{ t("share") }}</div> <div
class="showName"
v-if="shareShow"
>
{{ t("share") }}
</div>
<FileTree <FileTree
v-if="shareShow" v-if="shareShow"
:chosen-path="chosenTreePath" :chosen-path="chosenTreePath"
@ -54,7 +81,10 @@
> >
</FileTree> </FileTree>
<QuickLink :on-open="onTreeOpen"></QuickLink> <QuickLink :on-open="onTreeOpen"></QuickLink>
<div class="left-handle" @mousedown="leftHandleDown"></div> <div
class="left-handle"
@mousedown="leftHandleDown"
></div>
</div> </div>
<div <div
class="desk-outer" class="desk-outer"
@ -75,38 +105,54 @@
> >
</FileList> </FileList>
<div draggable="true" class="desk-item" v-if="creating"> <div
draggable="true"
class="desk-item"
v-if="creating"
>
<div class="item_img"> <div class="item_img">
<!-- <img draggable="false" width="50" :src="foldericon" /> --> <!-- <img draggable="false" width="50" :src="foldericon" /> -->
<svg class="icon" aria-hidden="true" style="font-size: 1.2em"> <svg
class="icon"
aria-hidden="true"
style="font-size: 1.2em"
>
<use xlink:href="#icon-folder"></use> <use xlink:href="#icon-folder"></use>
</svg> </svg>
</div> </div>
<input class="item_input" v-model="createInput" @blur="creatingEditEnd" /> <input
class="item_input"
v-model="createInput"
@blur="creatingEditEnd"
/>
</div> </div>
<Chosen></Chosen> <Chosen></Chosen>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted, inject } from "vue"; import { inject, onMounted, ref } from "vue";
//import foldericon from '@/assets/folder.png'; //import foldericon from '@/assets/folder.png';
import { useComputer } from "@/hook/useComputer";
import { useContextMenu } from "@/hook/useContextMenu";
import { useFileDrag } from "@/hook/useFileDrag";
import { Rect, useRectChosen } from "@/hook/useRectChosen";
import { getSystemConfig } from "@/system/config";
import { emitEvent, mountEvent } from "@/system/event";
import { import {
BrowserWindow, BrowserWindow,
OsFileWithoutContent,
dirname, dirname,
Notify, Notify,
useSystem, OsFileWithoutContent,
t, t,
useSystem,
} from "@/system/index.ts"; } from "@/system/index.ts";
import { useContextMenu } from "@/hook/useContextMenu"; import {
import { emitEvent, mountEvent } from "@/system/event"; isRootShare,
import { useFileDrag } from "@/hook/useFileDrag"; isShareFile,
import { useComputer } from "@/hook/useComputer"; turnLocalPath,
import { Rect, useRectChosen } from "@/hook/useRectChosen"; } from "@/util/sharePath.ts";
import { getSystemConfig } from "@/system/config";
import { isShareFile, isRootShare, turnLocalPath } from "@/util/sharePath.ts";
const { choseStart, chosing, choseEnd, getRect, Chosen } = useRectChosen(); const { choseStart, chosing, choseEnd, getRect, Chosen } = useRectChosen();
@ -123,7 +169,10 @@ const { dragFileToDrop } = useFileDrag(system);
const { createDesktopContextMenu } = useContextMenu(); const { createDesktopContextMenu } = useContextMenu();
const setRouter = function (path: string) { const setRouter = function (path: string) {
router_url.value = path; router_url.value = path;
if (router_url_history_index.value <= router_url_history.value.length - 1) { if (
router_url_history_index.value <=
router_url_history.value.length - 1
) {
router_url_history.value = router_url_history.value.slice( router_url_history.value = router_url_history.value.slice(
0, 0,
router_url_history_index.value + 1 router_url_history_index.value + 1
@ -132,7 +181,8 @@ const setRouter = function (path: string) {
router_url_history_index.value = router_url_history.value.length; router_url_history_index.value = router_url_history.value.length;
router_url_history.value.push(path); router_url_history.value.push(path);
}; };
const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useComputer({ const { refersh, createFolder, backFolder, openFolder, onComputerMount } =
useComputer({
setRouter: setRouter, setRouter: setRouter,
getRouter() { getRouter() {
return router_url.value; return router_url.value;
@ -140,14 +190,17 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
setFileList(list) { setFileList(list) {
// console.log('list:',list) // console.log('list:',list)
//currentList.value = list; //currentList.value = list;
if(config.ext && config.ext instanceof Array && config.ext.length > 0) { if (
const res:any = [] config.ext &&
config.ext instanceof Array &&
config.ext.length > 0
) {
const res: any = [];
list.forEach((d: any) => { list.forEach((d: any) => {
if (config.ext.includes(d.ext) || d.isDirectory) { if (config.ext.includes(d.ext) || d.isDirectory) {
res.push(d) res.push(d);
} }
}) });
currentList.value = res; currentList.value = res;
} else { } else {
currentList.value = list; currentList.value = list;
@ -166,7 +219,7 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
return system.fs.readdir(path); return system.fs.readdir(path);
}, },
sharedir(path) { sharedir(path) {
return system.fs.sharedir(getSystemConfig().userInfo.id,path) return system.fs.sharedir(path);
}, },
exists(path) { exists(path) {
return system.fs.exists(path); return system.fs.exists(path);
@ -185,7 +238,10 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
// file = params // file = params
// } // }
// return system.fs.readShareFileDir(getSystemConfig().userInfo.id, file) // return system.fs.readShareFileDir(getSystemConfig().userInfo.id, file)
return system.fs.readShareFileDir(getSystemConfig().userInfo.id, path) return system.fs.readShareFileDir(
getSystemConfig().userInfo.id,
path
);
}, },
notify(title, content) { notify(title, content) {
new Notify({ new Notify({
@ -199,10 +255,15 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
}); });
function handleHistoryChange(offset: number) { function handleHistoryChange(offset: number) {
if (router_url_history_index.value + offset < 0) return; if (router_url_history_index.value + offset < 0) return;
if (router_url_history_index.value + offset > router_url_history.value.length - 1) if (
router_url_history_index.value + offset >
router_url_history.value.length - 1
)
return; return;
router_url_history_index.value = router_url_history_index.value + offset; router_url_history_index.value =
router_url.value = router_url_history.value[router_url_history_index.value]; router_url_history_index.value + offset;
router_url.value =
router_url_history.value[router_url_history_index.value];
refersh(); refersh();
} }
@ -241,7 +302,7 @@ const shareFileList = ref<Array<OsFileWithoutContent>>([
mtime: "", mtime: "",
rdev: 0, rdev: 0,
atime: "", atime: "",
birthtime: "" birthtime: "",
}, },
{ {
ext: "", ext: "",
@ -258,11 +319,11 @@ const shareFileList = ref<Array<OsFileWithoutContent>>([
mtime: "", mtime: "",
rdev: 0, rdev: 0,
atime: "", atime: "",
birthtime: "" birthtime: "",
} },
]); ]);
const random = ref(0); const random = ref(0);
const shareShow = ref(false) const shareShow = ref(false);
onMounted(() => { onMounted(() => {
if (config) { if (config) {
router_url.value = config.path; router_url.value = config.path;
@ -282,9 +343,9 @@ onMounted(() => {
random.value = random.value + 1; random.value = random.value + 1;
} }
}); });
shareShow.value = system.getConfig('userType') === 'member' ? true : false shareShow.value =
system.getConfig("userType") === "member" ? true : false;
// console.log('', system.getConfig('userInfo').id); // console.log('', system.getConfig('userInfo').id);
}); });
function handleOuterClick() { function handleOuterClick() {
@ -312,16 +373,19 @@ const chosenView = ref("icon");
const chosenTreePath = ref(""); const chosenTreePath = ref("");
async function onTreeOpen(path: string) { async function onTreeOpen(path: string) {
chosenTreePath.value = path; chosenTreePath.value = path;
let file:any let file: any;
// const file = await system.fs.stat(path); // const file = await system.fs.stat(path);
if (isRootShare(path)) { if (isRootShare(path)) {
file = path === '/F/myshare' ? shareFileList.value[0] : shareFileList.value[1] file =
path === "/F/myshare"
? shareFileList.value[0]
: shareFileList.value[1];
} else if (isShareFile(path)) { } else if (isShareFile(path)) {
file = await system.fs.getShareInfo(path) file = await system.fs.getShareInfo(path);
file = file.fi file = file.fi;
file.path = turnLocalPath(file.path, path, 1) file.path = turnLocalPath(file.path, path, 1);
} else { } else {
file = await system.fs.stat(path) file = await system.fs.stat(path);
} }
if (file) { if (file) {
openFolder(file); openFolder(file);

76
frontend/src/components/computer/ComputerNavBar.vue

@ -1,6 +1,9 @@
<template> <template>
<div class="uper_nav"> <div class="uper_nav">
<div class="uper_nav_button" @click="changeHistory(-1)"> <div
class="uper_nav_button"
@click="changeHistory(-1)"
>
<svg <svg
t="1632984723698" t="1632984723698"
class="icon" class="icon"
@ -15,7 +18,10 @@
/> />
</svg> </svg>
</div> </div>
<div class="uper_nav_button" @click="changeHistory(1)"> <div
class="uper_nav_button"
@click="changeHistory(1)"
>
<svg <svg
t="1632984737821" t="1632984737821"
class="icon" class="icon"
@ -30,7 +36,10 @@
/> />
</svg> </svg>
</div> </div>
<div class="uper_nav_button" @click="backFolder()"> <div
class="uper_nav_button"
@click="backFolder()"
>
<svg <svg
t="1639145815176" t="1639145815176"
class="icon" class="icon"
@ -47,7 +56,11 @@
</svg> </svg>
</div> </div>
<div @click="startInput()" v-if="path_state == 'pendding'" class="path"> <div
@click="startInput()"
v-if="path_state == 'pendding'"
class="path"
>
<template v-if="modelValue?.startsWith('search:')"> <template v-if="modelValue?.startsWith('search:')">
<span>{{ modelValue }}</span> <span>{{ modelValue }}</span>
</template> </template>
@ -62,62 +75,81 @@
></span> ></span>
</template> </template>
</div> </div>
<div @focusout="endInput()" v-show="path_state == 'inputing'" class="path_inputing nav-path"> <div
<input ref="myinput" v-model="inputStr" @keyup.enter="endInput()" /> @focusout="endInput()"
v-show="path_state == 'inputing'"
class="path_inputing nav-path"
>
<input
ref="myinput"
v-model="inputStr"
@keyup.enter="endInput()"
/>
</div> </div>
<div class="search path_inputing"> <div class="search path_inputing">
<input placeholder="search" v-model="searchStr" @keyup.enter="endSearch" @blur="endSearch" /> <input
placeholder="search"
v-model="searchStr"
@keyup.enter="endSearch"
@blur="endSearch"
/>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, nextTick } from 'vue'; import { nextTick, ref } from "vue";
const props = defineProps<{ const props = defineProps<{
modelValue?: string; modelValue?: string;
}>(); }>();
const emit = defineEmits(['update:modelValue', 'backFolder', 'changeHistory', 'refresh', 'search']); const emit = defineEmits([
"update:modelValue",
"backFolder",
"changeHistory",
"refresh",
"search",
]);
function backFolder() { function backFolder() {
emit('backFolder'); emit("backFolder");
} }
function changeHistory(num: number) { function changeHistory(num: number) {
emit('changeHistory', num); emit("changeHistory", num);
} }
/* ------------ 路径输入框 ------------*/ /* ------------ 路径输入框 ------------*/
const myinput = ref<HTMLElement | null>(null); const myinput = ref<HTMLElement | null>(null);
const inputStr = ref(props.modelValue); const inputStr = ref(props.modelValue);
const path_state = ref('pendding'); const path_state = ref("pendding");
function startInput() { function startInput() {
path_state.value = 'inputing'; path_state.value = "inputing";
inputStr.value = props.modelValue; inputStr.value = props.modelValue;
nextTick(() => { nextTick(() => {
myinput.value?.focus(); myinput.value?.focus();
}); });
} }
function endInput() { function endInput() {
path_state.value = 'pendding'; path_state.value = "pendding";
emit('refresh', inputStr.value); emit("refresh", inputStr.value);
} }
/* ------------ 路径输入框end ---------*/ /* ------------ 路径输入框end ---------*/
/* ------------ 搜索框 ------------*/ /* ------------ 搜索框 ------------*/
const searchStr = ref(''); const searchStr = ref("");
function endSearch() { function endSearch() {
if (searchStr.value == '') return; if (searchStr.value == "") return;
emit('search', searchStr.value); emit("search", searchStr.value);
searchStr.value = ''; searchStr.value = "";
} }
function handlePathPClick(index: number) { function handlePathPClick(index: number) {
const path = props.modelValue const path = props.modelValue
?.split('/') ?.split("/")
.slice(0, index + 2) .slice(0, index + 2)
.join('/'); .join("/");
if (path === undefined) return; if (path === undefined) return;
if (path === props.modelValue) return; if (path === props.modelValue) return;
emit('refresh', path); emit("refresh", path);
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

50
frontend/src/components/oa/FilePwd.vue

@ -1,27 +1,51 @@
<template> <template>
<el-form label-width="auto" style="max-width: 560px;margin-top:20px;padding: 20px;"> <el-form
label-width="auto"
style="max-width: 560px; margin-top: 20px; padding: 20px"
>
<el-form-item label="文件密码"> <el-form-item label="文件密码">
<el-input v-model="filePwd" type="password" show-password/> <el-input
v-model="filePwd"
type="password"
show-password
/>
</el-form-item> </el-form-item>
<div class="btn-group"> <div class="btn-group">
<el-button type="primary" @click="setFilePwd">提交</el-button> <el-button
type="primary"
@click="setFilePwd"
>提交</el-button
>
</div> </div>
</el-form> </el-form>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { fetchPost } from '@/system/config'; import { BrowserWindow, useSystem } from "@/system";
import { ref } from 'vue' import { notifyError, notifySuccess } from "@/util/msg";
import { getSystemConfig } from "@/system/config"; import { ref } from "vue";
import { BrowserWindow } from '@/system';
const window: BrowserWindow | undefined = inject("browserWindow"); const window: BrowserWindow | undefined = inject("browserWindow");
const filePwd = ref('') const filePwd = ref("");
const userInfo = getSystemConfig().userInfo const sys = useSystem();
async function setFilePwd() { async function setFilePwd() {
if (filePwd.value !== '' && filePwd.value.length >= 6 && filePwd.value.length <= 10) { if (
const path = window?.config.path || '' filePwd.value !== "" &&
const res = await fetchPost(`${userInfo.url}`, filePwd.value) filePwd.value.length >= 6 &&
console.log('路径:', res, path); filePwd.value.length <= 10
) {
const path = window?.config.path || "";
const header = {
pwd: filePwd.value,
};
const file = await sys.fs.readFile(path);
if (file === false) return;
const res = await sys.fs.writeFile(path, file, header);
if (res && res.success) {
notifySuccess("文件密码设置成功");
} else {
notifyError("文件密码设置失败");
}
//console.log("", res, path);
} }
} }
</script> </script>

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

@ -1,13 +1,18 @@
<template> <template>
<iframe class="setiframe" allow="fullscreen" ref="storeRef" :src="src"></iframe> <iframe
class="setiframe"
allow="fullscreen"
ref="storeRef"
:src="src"
></iframe>
</template> </template>
<script lang="ts" setup name="IframeFile"> <script lang="ts" setup name="IframeFile">
//@ts-ignore //@ts-ignore
import { BrowserWindow, Notify, System, Dialog } from "@/system"; import { BrowserWindow, Dialog, Notify, System } from "@/system";
import { ref, onMounted, inject, onUnmounted, toRaw } from "vue"; import { getSplit, getSystemConfig, setSystemKey } from "@/system/config";
import { isBase64, base64ToBuffer } from "@/util/file"; import { base64ToBuffer, isBase64 } from "@/util/file";
import { getSplit, getSystemConfig } from "@/system/config";
import { isShareFile } from "@/util/sharePath.ts"; import { isShareFile } from "@/util/sharePath.ts";
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue";
const SP = getSplit(); const SP = getSplit();
const sys: any = inject<System>("system"); const sys: any = inject<System>("system");
@ -30,6 +35,7 @@ const props = defineProps({
//console.log(props); //console.log(props);
//let path = win?.config?.path; //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 eventHandler = async (e: MessageEvent) => { const eventHandler = async (e: MessageEvent) => {
@ -50,26 +56,30 @@ const eventHandler = async (e: MessageEvent) => {
// console.log(data) // console.log(data)
if (win.config && win.config.path) { if (win.config && win.config.path) {
path = win.config.path; path = win.config.path;
let fileTitleArr = path.split(SP).pop().split("."); //1
let oldExt = fileTitleArr.pop(); // let fileTitleArr = path.split(SP).pop().split(".");
let fileTitle = fileTitleArr.join("."); // let oldExt = fileTitleArr.pop();
if (fileTitle != title) { // let fileTitle = fileTitleArr.join(".");
path = path.replace(fileTitle, title); // if (fileTitle != title) {
} // path = path.replace(fileTitle, title);
if (oldExt != ext) { // }
path = path.replace("." + oldExt, "." + ext); // if (oldExt != ext) {
} // path = path.replace("." + oldExt, "." + ext);
// }
} else { } else {
path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`; 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.is_write isWrite.value = file.fs.is_write;
if (!isWrite.value) { if (
!isWrite.value &&
file.fs.sender !== getSystemConfig().userInfo.id
) {
new Notify({ new Notify({
title: "提示", title: "提示",
content: "该文件没有编辑权限", content: "该文件没有编辑权限",
@ -98,11 +108,18 @@ const eventHandler = async (e: MessageEvent) => {
//console.log(data.content) //console.log(data.content)
} }
} }
const res = isShare ? await sys?.fs.writeShareFile(path, data.content, isWrite.value) : await sys?.fs.writeFile(path, data.content);
console.log('编写文件:', res); const res = isShare.value
? await sys?.fs.writeShareFile(
path,
data.content,
isWrite.value
)
: await sys?.fs.writeFile(path, data.content);
// console.log("", res, isShare);
new Notify({ new Notify({
title: "提示", title: "提示",
content: res.code === 0 ? '文件已保存' : '文件保存失败', content: res.code === 0 ? "文件已保存" : "文件保存失败",
}); });
sys.refershAppList(); sys.refershAppList();
} else if (eventData.type == "initSuccess") { } else if (eventData.type == "initSuccess") {
@ -111,21 +128,20 @@ const eventHandler = async (e: MessageEvent) => {
} }
hasInit = true; hasInit = true;
let content = win?.config?.content; let content = win?.config?.content;
console.log(win?.config);
let title = win.getTitle(); let title = win.getTitle();
// console.log("win.config;", win?.config);
// console.log(title); // console.log(title);
title = title.split(SP).pop(); title = title.split(SP).pop();
//console.log(title);
if (!content && win?.config.path) { if (!content && win?.config.path) {
const file = getSystemConfig().file const file = getSystemConfig().file;
const header = { const header = {
salt: file.salt, salt: file.salt,
filePwd: file.pwd pwd: file.pwd,
} };
content = await sys?.fs.readFile(win?.config.path, header); content = await sys?.fs.readFile(win?.config.path, header);
} }
content = toRaw(content); content = toRaw(content);
// console.log(content);
if (content && content !== "") { if (content && content !== "") {
storeRef.value?.contentWindow?.postMessage( storeRef.value?.contentWindow?.postMessage(
{ {
@ -145,11 +161,21 @@ const eventHandler = async (e: MessageEvent) => {
} }
} }
}; };
//
const delFileInputPwd = async () => {
let fileInputPwd = getSystemConfig().fileInputPwd;
const currentPath = win.config.path;
const temp = fileInputPwd.filter(
(item: any) => item.path !== currentPath
);
setSystemKey("fileInputPwd", temp);
};
onMounted(() => { onMounted(() => {
window.addEventListener("message", eventHandler); window.addEventListener("message", eventHandler);
}); });
onUnmounted(() => { onUnmounted(async () => {
await delFileInputPwd();
window.removeEventListener("message", eventHandler); window.removeEventListener("message", eventHandler);
}); });
</script> </script>

13
frontend/src/system/config.ts

@ -1,4 +1,4 @@
import { generateRandomString } from "../util/common.ts" import { generateRandomString } from "../util/common.ts";
export const configStoreType = localStorage.getItem('GodoOS-storeType') || 'local'; export const configStoreType = localStorage.getItem('GodoOS-storeType') || 'local';
/** /**
* *
@ -36,6 +36,9 @@ export const getSystemConfig = (ifset = false) => {
salt: 'vIf_wIUedciAd0nTm6qjJA==' salt: 'vIf_wIUedciAd0nTm6qjJA=='
} }
} }
if (!config.fileInputPwd) {
config.fileInputPwd = []
}
// 初始化用户信息,若本地存储中已存在则不进行覆盖 // 初始化用户信息,若本地存储中已存在则不进行覆盖
if (!config.userInfo) { if (!config.userInfo) {
config.userInfo = { config.userInfo = {
@ -58,7 +61,8 @@ export const getSystemConfig = (ifset = false) => {
deptName: '', deptName: '',
token: '', token: '',
user_auths: '', user_auths: '',
user_shares: '' user_shares: '',
isPwd: false
}; };
} }
@ -216,6 +220,8 @@ export function getWorkflowUrl(){
} }
} }
export function fetchGet(url: string, headerConfig?: { [key: string]: string }) { export function fetchGet(url: string, headerConfig?: { [key: string]: string }) {
// console.log('请求头部;', headerConfig);
const config = getSystemConfig(); const config = getSystemConfig();
if (config.userType == 'person') { if (config.userType == 'person') {
return fetch(url, { return fetch(url, {
@ -229,7 +235,8 @@ export function fetchGet(url: string, headerConfig?: {[key: string]: string}) {
headers: { headers: {
//'Content-Type': 'application/json', //'Content-Type': 'application/json',
'ClientID': getClientId(), 'ClientID': getClientId(),
'Authorization': config.userInfo.token 'Authorization': config.userInfo.token,
...headerConfig
} }
}) })
} }

79
frontend/src/system/core/FileOs.ts

@ -1,9 +1,10 @@
import { getFileUrl,fetchGet,fetchPost } from "../config.ts";
const API_BASE_URL = getFileUrl()
import { OsFileMode } from '../core/FileMode';
import { getSystemConfig } from "@/system/config"; import { getSystemConfig } from "@/system/config";
import { turnServePath, turnLocalPath, isRootShare, isShareFile } from "@/util/sharePath.ts"; import { isRootShare, isShareFile, turnLocalPath, turnServePath } from "@/util/sharePath.ts";
import { md5 } from "js-md5";
import { fetchGet, fetchPost, getFileUrl } from "../config.ts";
import { OsFileMode } from '../core/FileMode';
import { OsFile } from "./FileSystem.ts"; import { OsFile } from "./FileSystem.ts";
const API_BASE_URL = getFileUrl()
// import { notifyError } from "@/util/msg"; // import { notifyError } from "@/util/msg";
export async function handleReadDir(path: any): Promise<any> { export async function handleReadDir(path: any): Promise<any> {
const res = await fetchGet(`${API_BASE_URL}/read?path=${encodeURIComponent(path)}`); const res = await fetchGet(`${API_BASE_URL}/read?path=${encodeURIComponent(path)}`);
@ -13,18 +14,18 @@ export async function handleReadDir(path: any): Promise<any> {
return await res.json(); return await res.json();
} }
// 查看分享文件 // 查看分享文件
export async function handleReadShareDir(id: number,path: string): Promise<any> { export async function handleReadShareDir(path: string): Promise<any> {
const url = path.indexOf('/F/myshare') !== -1 ? 'sharemylist' : 'sharelist' const url = path.indexOf('/F/myshare') !== -1 ? 'sharemylist' : 'sharelist'
const res = await fetchGet(`${API_BASE_URL}/${url}?id=${id}`); const res = await fetchGet(`${API_BASE_URL}/${url}`);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
return await res.json(); return await res.json();
} }
// 查看分享文件夹 // 查看分享文件夹
export async function handleShareDir(id: number,path: string): Promise<any> { export async function handleShareDir(path: string): Promise<any> {
path = turnServePath(path) path = turnServePath(path)
const res = await fetchGet(`${API_BASE_URL}/sharedir?id=${id}&dirPath=${path}`); const res = await fetchGet(`${API_BASE_URL}/sharedir?dirPath=${path}`);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
@ -41,7 +42,7 @@ export async function handleReadShareFile(path: string): Promise<any> {
} }
// 删除分享文件 // 删除分享文件
export async function handleShareUnlink(path: string): Promise<any> { export async function handleShareUnlink(path: string): Promise<any> {
const file = await handleShareDetail(path,getSystemConfig()?.userInfo.id) const file = await handleShareDetail(path)
path = turnServePath(path) path = turnServePath(path)
const res = await fetchGet(`${API_BASE_URL}/sharedelete?senderid=${file.data.fs.sender}&path=${path}&receverid=${file.data.fs.recever}`); const res = await fetchGet(`${API_BASE_URL}/sharedelete?senderid=${file.data.fs.sender}&path=${path}&receverid=${file.data.fs.recever}`);
if (!res.ok) { if (!res.ok) {
@ -50,11 +51,11 @@ export async function handleShareUnlink(path: string): Promise<any> {
return await res.json(); return await res.json();
} }
// 查看文件信息 // 查看文件信息
export async function handleShareDetail(path: string, id: number): Promise<any> { export async function handleShareDetail(path: string): Promise<any> {
const sig = path.indexOf('/F/myshare') === 0 ? 0 : 1 const sig = path.indexOf('/F/myshare') === 0 ? 0 : 1
path = turnServePath(path) path = turnServePath(path)
const res = await fetchGet(`${API_BASE_URL}/shareinfo?path=${path}&id=${id}&sig=${sig}`); const res = await fetchGet(`${API_BASE_URL}/shareinfo?path=${path}&sig=${sig}`);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
@ -113,7 +114,20 @@ export async function handleExists(path: string): Promise<any> {
} }
export async function handleReadFile(path: string, header?: { [key: string]: string }): Promise<any> { export async function handleReadFile(path: string, header?: { [key: string]: string }): Promise<any> {
const res = await fetchGet(`${API_BASE_URL}/readfile?path=${encodeURIComponent(path)}`, header); const userType = getSystemConfig().userType
// let head = userType === 'member' ? { pwd: header?.pwd || '' } : { ...header }
let head = {}
if (userType === 'member') {
head = {
pwd: header?.pwd || ''
}
} else if (getSystemConfig().file.isPwd === 1) {
head = {
pwd: md5(header?.pwd || ''),
salt: header?.salt || ''
}
}
const res = await fetchGet(`${API_BASE_URL}/readfile?path=${encodeURIComponent(path)}`, head);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
@ -205,11 +219,12 @@ export function getFormData(content: any) {
formData.append('content', blobContent); formData.append('content', blobContent);
return formData return formData
} }
export async function handleWriteFile(filePath: string, content: any): Promise<any> { export async function handleWriteFile(filePath: string, content: any, header?: { [key: string]: any }): Promise<any> {
const formData = getFormData(content); const formData = getFormData(content);
const head = header ? { ...header } : {}
const url = `${API_BASE_URL}/writefile?filePath=${encodeURIComponent(filePath)}`; const url = `${API_BASE_URL}/writefile?path=${encodeURIComponent(filePath)}`;
const res = await fetchPost(url, formData); // const url = `${API_BASE_URL}/writefile?filePath=${encodeURIComponent(filePath)}`;
const res = await fetchPost(url, formData, head);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
@ -262,9 +277,9 @@ export async function handleUnZip(path: string): Promise<any> {
export const useOsFile = () => { export const useOsFile = () => {
return { return {
// 分享 // 分享
async sharedir(id: number, path: string) { async sharedir(path: string) {
const fun = isRootShare(path) ? handleReadShareDir : handleShareDir const fun = isRootShare(path) ? handleReadShareDir : handleShareDir
const response = await fun(id, path); const response = await fun(path);
if (response && response.data) { if (response && response.data) {
const result = response.data.map((item: { [key: string]: OsFile }) => { const result = response.data.map((item: { [key: string]: OsFile }) => {
item.fi.isShare = true item.fi.isShare = true
@ -285,8 +300,8 @@ export const useOsFile = () => {
return []; return [];
}, },
//分享文件夹取消 //分享文件夹取消
async readShareFileDir(id: number, path: string) { async readShareFileDir(path: string) {
const response = await handleShareDir(id, path) const response = await handleShareDir(path)
if (response && response.data) { if (response && response.data) {
return response.data return response.data
} }
@ -306,7 +321,7 @@ export const useOsFile = () => {
// return []; // return [];
}, },
async getShareInfo(path: string) { async getShareInfo(path: string) {
const response = await handleShareDetail(path, getSystemConfig().userInfo.id); const response = await handleShareDetail(path);
if (response && response.data) { if (response && response.data) {
response.data.fi.isShare = true response.data.fi.isShare = true
response.data.fi.path = turnLocalPath(response.data.fi.path, path, 1) response.data.fi.path = turnLocalPath(response.data.fi.path, path, 1)
@ -355,7 +370,7 @@ export const useOsFile = () => {
async readFile(path: string, header?: { [key: string]: string }) { async readFile(path: string, header?: { [key: string]: string }) {
// 注意:handleReadFile返回的是JSON,但通常readFile期望返回Buffer或字符串 // 注意:handleReadFile返回的是JSON,但通常readFile期望返回Buffer或字符串
const response = await handleReadFile(path, header); const response = await handleReadFile(path, header);
if (response && response.data) { if (response && response.code === 0) {
return response.data; return response.data;
} }
return false; return false;
@ -397,8 +412,24 @@ export const useOsFile = () => {
} }
return false; return false;
}, },
async writeFile(path: string, content: string | Blob) { async writeFile(path: string, content: string | Blob, header?: { [key: string]: any }) {
const response = await handleWriteFile(path, content); let head = {}
if (getSystemConfig().userType == 'member') {
if (header) {
head = { ...header }
} else {
const filePwd = getSystemConfig().fileInputPwd
const pos = filePwd.findIndex((item: any) => item.path == path)
if (pos !== -1) {
head = {
pwd: filePwd[pos].pwd
}
}
}
}
//console.log('创建露肩:', path);
const response = await handleWriteFile(path, content, head);
if (response) { if (response) {
return response; return response;
} }

8
frontend/src/system/core/FileSystem.ts

@ -1,10 +1,10 @@
import * as fspath from './Path'; import JSZip from "jszip";
import { OsFileInterface } from './FIleInterface';
import { SystemOptions } from '../type/type'; import { SystemOptions } from '../type/type';
import { InitSystemFile, InitUserFile } from './SystemFileConfig';
import { createInitFile } from './createInitFile'; import { createInitFile } from './createInitFile';
import { OsFileInterface } from './FIleInterface';
import { OsFileMode } from './FileMode'; import { OsFileMode } from './FileMode';
import JSZip from "jszip"; import * as fspath from './Path';
import { InitSystemFile, InitUserFile } from './SystemFileConfig';
type DateLike = Date | string | number; type DateLike = Date | string | number;
// Os文件模式枚举 // Os文件模式枚举
class OsFileInfo { class OsFileInfo {

22
frontend/src/system/index.ts

@ -452,7 +452,7 @@ export class System {
const filePwd = getSystemConfig() const filePwd = getSystemConfig()
const header = { const header = {
salt: '', salt: '',
filePwd: '' pwd: ''
} }
//判断文件是否需要输入密码 //判断文件是否需要输入密码
if (fileStat.isPwd && path.indexOf('.exe') === -1) { if (fileStat.isPwd && path.indexOf('.exe') === -1) {
@ -461,14 +461,30 @@ export class System {
return return
} }
header.salt = filePwd.file.salt || 'vIf_wIUedciAd0nTm6qjJA==' header.salt = filePwd.file.salt || 'vIf_wIUedciAd0nTm6qjJA=='
header.filePwd = temp?.inputPwd || '' header.pwd = temp?.inputPwd || ''
} }
// 读取文件内容 // 读取文件内容
const fileContent = await this.fs.readFile(path, header); const fileContent = await this.fs.readFile(path, header);
if (!fileContent && fileStat.isPwd) { // console.log('文件:', fileContent);
if (fileContent === false && fileStat.isPwd) {
notifyError('密码错误') notifyError('密码错误')
return return
} }
//企业用户文件加密密码存储
if (fileStat.isPwd && getSystemConfig().userType === 'member') {
let fileInputPwd = getSystemConfig().fileInputPwd
const pos = fileInputPwd.findIndex((item: any) => item.path == path)
if (pos !== -1) {
fileInputPwd[pos].pwd = header.pwd
} else {
fileInputPwd.push({
path: path,
pwd: header.pwd
})
}
setSystemKey('fileInputPwd', fileInputPwd)
}
// 从_fileOpenerMap中获取文件扩展名对应的函数并调用 // 从_fileOpenerMap中获取文件扩展名对应的函数并调用
const fileName = extname(fileStat?.name || '') || 'link' const fileName = extname(fileStat?.name || '') || 'link'
this._flieOpenerMap this._flieOpenerMap

6
frontend/src/system/window/Dialog.ts

@ -1,6 +1,7 @@
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { BrowserWindow } from "./BrowserWindow" import { BrowserWindow } from "./BrowserWindow"
import { md5 } from "js-md5" // import { setSystemKey } from "@/system/config"
// import { md5 } from "js-md5"
class Dialog { class Dialog {
constructor() { constructor() {
// static class // static class
@ -120,8 +121,9 @@ class Dialog {
}).then(({value}) => { }).then(({value}) => {
promres({ promres({
response: 1, response: 1,
inputPwd: md5(value) inputPwd: value
}); });
// setSystemKey('filePwd', value)
}).catch(()=>{ }).catch(()=>{
promres({ promres({
response: -1, response: -1,

Loading…
Cancel
Save