Browse Source

fix:企业版文件加密

master
18786462055 8 months ago
parent
commit
795d76dd82
  1. 405
      frontend/src/components/builtin/FileList.vue
  2. 5
      frontend/src/components/builtin/FileTree.vue
  3. 356
      frontend/src/components/computer/Computer.vue
  4. 160
      frontend/src/components/computer/ComputerNavBar.vue
  5. 60
      frontend/src/components/oa/FilePwd.vue
  6. 2
      frontend/src/components/setting/SetFilePwd.vue
  7. 126
      frontend/src/components/window/IframeFile.vue
  8. 27
      frontend/src/system/config.ts
  9. 91
      frontend/src/system/core/FileOs.ts
  10. 8
      frontend/src/system/core/FileSystem.ts
  11. 22
      frontend/src/system/index.ts
  12. 8
      frontend/src/system/window/Dialog.ts

405
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,24 +92,31 @@
</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 { useChooseStore } from "@/stores/choose";
import { useAppMenu } from '@/hook/useAppMenu'; import { getSystemKey } from "@/system/config";
import { onMounted, ref, markRaw } from 'vue'; import { emitEvent, mountEvent } from "@/system/event";
import { Rect } from '@/hook/useRectChosen'; import {
import { throttle } from '@/util/debounce'; basename,
import { dealSize } from '@/util/file'; BrowserWindow,
import { Menu } from '@/system/menu/Menu'; Notify,
import { useChooseStore } from "@/stores/choose"; OsFileWithoutContent,
const { openPropsWindow, copyFile, createLink, deleteFile } = useContextMenu(); useSystem,
const sys = useSystem(); } from "@/system/index.ts";
const { startDrag, folderDrop } = useFileDrag(sys); import { Menu } from "@/system/menu/Menu";
const choose = useChooseStore() import { throttle } from "@/util/debounce";
const props = defineProps({ import { dealSize } from "@/util/file";
import { markRaw, onMounted, ref } from "vue";
const { openPropsWindow, copyFile, createLink, deleteFile } =
useContextMenu();
const sys = useSystem();
const { startDrag, folderDrop } = useFileDrag(sys);
const choose = useChooseStore();
const props = defineProps({
onChosen: { onChosen: {
type: Function, type: Function,
required: true, required: true,
@ -104,45 +139,45 @@ 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) {
// props.onOpen(item); // props.onOpen(item);
// 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) {
hoverIndex.value = -1; hoverIndex.value = -1;
folderDrop(mouse, path); folderDrop(mouse, path);
chosenIndexs.value = []; chosenIndexs.value = [];
} }
let expired: number | null = null; let expired: number | null = null;
function doubleTouch(e: TouchEvent, item: OsFileWithoutContent) { function doubleTouch(e: TouchEvent, item: OsFileWithoutContent) {
if (e.touches.length === 1) { if (e.touches.length === 1) {
if (!expired) { if (!expired) {
expired = e.timeStamp + 400; expired = e.timeStamp + 400;
@ -157,47 +192,44 @@ function doubleTouch(e: TouchEvent, item: OsFileWithoutContent) {
expired = e.timeStamp + 400; expired = e.timeStamp + 400;
} }
} }
} }
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();
}); });
const hoverIndex = ref<number>(-1); const hoverIndex = ref<number>(-1);
const appPositions = ref<Array<Element>>([]); const appPositions = ref<Array<Element>>([]);
const chosenIndexs = ref<Array<number>>([]); const chosenIndexs = ref<Array<number>>([]);
function handleClick(index: number) { function handleClick(index: number) {
chosenIndexs.value = [index]; chosenIndexs.value = [index];
} }
onMounted(() => { onMounted(() => {
chosenIndexs.value = []; chosenIndexs.value = [];
props.onChosen( props.onChosen(
throttle((rect: Rect) => { throttle((rect: Rect) => {
@ -220,9 +252,9 @@ onMounted(() => {
chosenIndexs.value = tempChosen; chosenIndexs.value = tempChosen;
}, 100) }, 100)
); );
}); });
function startDragApp(mouse: DragEvent, item: OsFileWithoutContent) { function startDragApp(mouse: DragEvent, item: OsFileWithoutContent) {
if (chosenIndexs.value.length) { if (chosenIndexs.value.length) {
startDrag( startDrag(
mouse, mouse,
@ -238,37 +270,41 @@ function startDragApp(mouse: DragEvent, item: OsFileWithoutContent) {
chosenIndexs.value = []; chosenIndexs.value = [];
}); });
} }
} }
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,46 +494,45 @@ 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)
Menu.buildFromTemplate(menuArr).popup(mouse); Menu.buildFromTemplate(menuArr).popup(mouse);
} }
function handleDragEnter(index: number) { function handleDragEnter(index: number) {
hoverIndex.value = index; hoverIndex.value = index;
} }
function handleDragLeave() { function handleDragLeave() {
hoverIndex.value = -1; hoverIndex.value = -1;
} }
// function dealtName(name: string) { // function dealtName(name: string) {
// return name; // return name;
// } // }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.file-item { .file-item {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -529,13 +572,13 @@ function handleDragLeave() {
resize: none; resize: none;
border-radius: 0; border-radius: 0;
} }
} }
.file-item:hover { .file-item:hover {
background-color: #b1f1ff4c; background-color: #b1f1ff4c;
} }
.chosen { .chosen {
border: 1px dashed #3bdbff3d; border: 1px dashed #3bdbff3d;
// background-color: #ffffff6b; // background-color: #ffffff6b;
background-color: var(--theme-color); background-color: var(--theme-color);
@ -548,9 +591,9 @@ function handleDragLeave() {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
} }
} }
.no-chosen { .no-chosen {
.file-item_title { .file-item_title {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -559,15 +602,15 @@ function handleDragLeave() {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
} }
} }
.drag-over { .drag-over {
border: 1px dashed #3bdbff3d; border: 1px dashed #3bdbff3d;
// background-color: #ffffff6b; // background-color: #ffffff6b;
background-color: var(--theme-color); background-color: var(--theme-color);
} }
.mode-icon { .mode-icon {
.file-item_img { .file-item_img {
width: 60%; width: 60%;
height: calc(0.6 * var(--desk-item-size)); height: calc(0.6 * var(--desk-item-size));
@ -584,9 +627,9 @@ function handleDragLeave() {
word-break: break-all; word-break: break-all;
flex-grow: 0; flex-grow: 0;
} }
} }
.mode-list { .mode-list {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
@ -605,24 +648,24 @@ function handleDragLeave() {
height: min-content; height: min-content;
word-break: break-all; word-break: break-all;
} }
} }
.mode-icon { .mode-icon {
width: var(--desk-item-size); width: var(--desk-item-size);
height: var(--desk-item-size); height: var(--desk-item-size);
} }
.mode-big { .mode-big {
width: calc(var(--desk-item-size) * 2.5); width: calc(var(--desk-item-size) * 2.5);
height: calc(var(--desk-item-size) * 2.5); height: calc(var(--desk-item-size) * 2.5);
} }
.mode-middle { .mode-middle {
width: calc(var(--desk-item-size) * 1.5); width: calc(var(--desk-item-size) * 1.5);
height: calc(var(--desk-item-size) * 1.5); height: calc(var(--desk-item-size) * 1.5);
} }
.mode-detail { .mode-detail {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
@ -652,10 +695,10 @@ function handleDragLeave() {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
} }
.file-bar:hover { .file-bar:hover {
background-color: unset; background-color: unset;
user-select: none; user-select: none;
} }
</style> </style>

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 {

356
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,55 +105,74 @@
> >
</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 { 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 {
BrowserWindow, BrowserWindow,
OsFileWithoutContent,
dirname, dirname,
Notify, Notify,
useSystem, OsFileWithoutContent,
t, t,
} from "@/system/index.ts"; useSystem,
import { useContextMenu } from "@/hook/useContextMenu"; } from "@/system/index.ts";
import { emitEvent, mountEvent } from "@/system/event"; import {
import { useFileDrag } from "@/hook/useFileDrag"; isRootShare,
import { useComputer } from "@/hook/useComputer"; isShareFile,
import { Rect, useRectChosen } from "@/hook/useRectChosen"; turnLocalPath,
import { getSystemConfig } from "@/system/config"; } from "@/util/sharePath.ts";
import { isShareFile, isRootShare, turnLocalPath } from "@/util/sharePath.ts";
const { choseStart, chosing, choseEnd, getRect, Chosen } = useRectChosen(); const { choseStart, chosing, choseEnd, getRect, Chosen } = useRectChosen();
const browserWindow: BrowserWindow | undefined = inject("browserWindow"); const browserWindow: BrowserWindow | undefined = inject("browserWindow");
const config = browserWindow?.config; const config = browserWindow?.config;
const router_url = ref(""); const router_url = ref("");
const router_url_history = ref<Array<string>>([]); const router_url_history = ref<Array<string>>([]);
const router_url_history_index = ref(0); const router_url_history_index = ref(0);
const currentList = ref<Array<OsFileWithoutContent>>([]); const currentList = ref<Array<OsFileWithoutContent>>([]);
const system = useSystem(); const system = useSystem();
const { dragFileToDrop } = useFileDrag(system); 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
@ -131,8 +180,9 @@ 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,16 +190,19 @@ 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 &&
list.forEach((d : any) => { config.ext instanceof Array &&
config.ext.length > 0
if(config.ext.includes(d.ext) || d.isDirectory){ ) {
res.push(d) const res: any = [];
list.forEach((d: any) => {
if (config.ext.includes(d.ext) || d.isDirectory) {
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);
@ -175,7 +228,7 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
return file.isDirectory; return file.isDirectory;
}, },
// //
async readShareDir(path){ async readShareDir(path) {
// let file: OsFileWithoutContent // let file: OsFileWithoutContent
// if (type === 'path') { // if (type === 'path') {
// file = await system.fs.getShareInfo(params) // file = await system.fs.getShareInfo(params)
@ -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({
@ -196,18 +252,23 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
search(keyword) { search(keyword) {
return system.fs.search(keyword); return system.fs.search(keyword);
}, },
}); });
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();
} }
const leftWidth = ref(200); const leftWidth = ref(200);
function leftHandleDown(e: MouseEvent) { function leftHandleDown(e: MouseEvent) {
const startX = e.clientX; const startX = e.clientX;
const startWidth = leftWidth.value; const startWidth = leftWidth.value;
addEventListener("mousemove", leftHandleMove); addEventListener("mousemove", leftHandleMove);
@ -222,10 +283,10 @@ function leftHandleDown(e: MouseEvent) {
removeEventListener("mousemove", leftHandleMove); removeEventListener("mousemove", leftHandleMove);
removeEventListener("mouseup", leftHandleUp); removeEventListener("mouseup", leftHandleUp);
} }
} }
const rootFileList = ref<Array<OsFileWithoutContent>>([]); const rootFileList = ref<Array<OsFileWithoutContent>>([]);
const shareFileList = ref<Array<OsFileWithoutContent>>([ const shareFileList = ref<Array<OsFileWithoutContent>>([
{ {
ext: "", ext: "",
isDirectory: true, isDirectory: true,
@ -241,7 +302,7 @@ const shareFileList = ref<Array<OsFileWithoutContent>>([
mtime: "", mtime: "",
rdev: 0, rdev: 0,
atime: "", atime: "",
birthtime: "" birthtime: "",
}, },
{ {
ext: "", ext: "",
@ -258,12 +319,12 @@ 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;
} else { } else {
@ -282,74 +343,77 @@ 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() {
emitEvent("mycomputer.click"); emitEvent("mycomputer.click");
} }
function onListRefresh() { function onListRefresh() {
refersh(); refersh();
system.fs.readdir("/").then((file: any) => { system.fs.readdir("/").then((file: any) => {
if (file) { if (file) {
rootFileList.value = [...file]; rootFileList.value = [...file];
} }
}); });
} }
/**------视图切换------ */ /**------视图切换------ */
const isPopoverView = ref(false); const isPopoverView = ref(false);
function popoverChange() { function popoverChange() {
isPopoverView.value = !isPopoverView.value; isPopoverView.value = !isPopoverView.value;
} }
const chosenView = ref("icon"); 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);
} }
router_url.value = path; router_url.value = path;
} }
/**------框选--------- */ /**------框选--------- */
let chosenCallback: (rect: Rect) => void = () => { let chosenCallback: (rect: Rect) => void = () => {
// //
}; };
function onChosen(callback: (rect: Rect) => void) { function onChosen(callback: (rect: Rect) => void) {
chosenCallback = callback; chosenCallback = callback;
} }
function backgroundDown(e: MouseEvent) { function backgroundDown(e: MouseEvent) {
choseStart(e); choseStart(e);
addEventListener("mousemove", backgroundMove); addEventListener("mousemove", backgroundMove);
addEventListener("mouseup", backgroundUp); addEventListener("mouseup", backgroundUp);
} }
function backgroundMove(e: MouseEvent) { function backgroundMove(e: MouseEvent) {
chosing(e); chosing(e);
const rectValue = getRect(); const rectValue = getRect();
if (rectValue) { if (rectValue) {
chosenCallback(rectValue); chosenCallback(rectValue);
} }
} }
function backgroundUp() { function backgroundUp() {
choseEnd(); choseEnd();
const rectValue = getRect(); const rectValue = getRect();
if (rectValue) { if (rectValue) {
@ -357,31 +421,31 @@ function backgroundUp() {
} }
removeEventListener("mousemove", backgroundMove); removeEventListener("mousemove", backgroundMove);
removeEventListener("mouseup", backgroundUp); removeEventListener("mouseup", backgroundUp);
} }
/* ------------ 新建文件夹 ------------*/ /* ------------ 新建文件夹 ------------*/
const createInput = ref(t("new.folder")); const createInput = ref(t("new.folder"));
const creating = ref(false); const creating = ref(false);
function creatingEditEnd() { function creatingEditEnd() {
if (creating.value) { if (creating.value) {
createFolder(createInput.value); createFolder(createInput.value);
creating.value = false; creating.value = false;
createInput.value = t("new.folder"); createInput.value = t("new.folder");
} }
} }
function onBackClick() { function onBackClick() {
creatingEditEnd(); creatingEditEnd();
} }
/* ------------ 新建文件夹end ---------*/ /* ------------ 新建文件夹end ---------*/
function showOuterMenu(e: MouseEvent) { function showOuterMenu(e: MouseEvent) {
e.preventDefault(); e.preventDefault();
createDesktopContextMenu(e, router_url.value, () => { createDesktopContextMenu(e, router_url.value, () => {
refersh(); refersh();
}); });
} }
/* ------------ 路径输入框 ------------*/ /* ------------ 路径输入框 ------------*/
async function handleNavRefresh(path: string) { async function handleNavRefresh(path: string) {
if (path == "") return; if (path == "") return;
if (path.startsWith("search:")) { if (path.startsWith("search:")) {
setRouter(path); setRouter(path);
@ -397,23 +461,23 @@ async function handleNavRefresh(path: string) {
setRouter(dirname(path)); setRouter(dirname(path));
refersh(); refersh();
} }
} }
async function handleNavSearch(path: string) { async function handleNavSearch(path: string) {
setRouter("search:" + path); setRouter("search:" + path);
refersh(); refersh();
} }
/* ------------ 路径输入框end ---------*/ /* ------------ 路径输入框end ---------*/
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.uper { .uper {
/* height: 40px; */ /* height: 40px; */
background-color: rgba(255, 235, 205, 0); background-color: rgba(255, 235, 205, 0);
font-size: 12px; font-size: 12px;
font-weight: 300; font-weight: 300;
/* border-bottom: 1px solid black; */ /* border-bottom: 1px solid black; */
--button-item-height: 30px; --button-item-height: 30px;
} }
.main { .main {
display: flex; display: flex;
height: 100%; height: 100%;
position: relative; position: relative;
@ -448,9 +512,9 @@ async function handleNavSearch(path: string) {
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
} }
} }
.desk-item { .desk-item {
position: relative; position: relative;
cursor: default; cursor: default;
box-sizing: border-box; box-sizing: border-box;
@ -459,29 +523,29 @@ async function handleNavSearch(path: string) {
background-color: rgba(119, 119, 119, 0); background-color: rgba(119, 119, 119, 0);
color: white; color: white;
border: 1px solid rgba(0, 0, 0, 0); border: 1px solid rgba(0, 0, 0, 0);
} }
.chosen { .chosen {
border: 1px dashed #3bdbff3d; border: 1px dashed #3bdbff3d;
background-color: #b9e3fd90; background-color: #b9e3fd90;
} }
.desk-item:hover { .desk-item:hover {
border: 1px solid rgba(149, 149, 149, 0.233); border: 1px solid rgba(149, 149, 149, 0.233);
background-color: #b9e3fd5a; background-color: #b9e3fd5a;
} }
.item_img { .item_img {
width: 50px; width: 50px;
height: 40px; height: 40px;
overflow: hidden; overflow: hidden;
padding: 10px; padding: 10px;
text-align: center; text-align: center;
} }
.item_img img { .item_img img {
user-select: none; user-select: none;
} }
.item_name { .item_name {
overflow: hidden; overflow: hidden;
max-width: 200px; max-width: 200px;
color: rgba(0, 0, 0, 0.664); color: rgba(0, 0, 0, 0.664);
@ -496,20 +560,20 @@ async function handleNavSearch(path: string) {
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
} }
.item_input { .item_input {
width: 100%; width: 100%;
} }
.group { .group {
display: flex; display: flex;
border-bottom: 1px solid rgba(134, 134, 134, 0.267); border-bottom: 1px solid rgba(134, 134, 134, 0.267);
user-select: none; user-select: none;
} }
.button { .button {
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
width: 50px; width: 50px;
@ -525,18 +589,18 @@ async function handleNavSearch(path: string) {
transition: 0.1s; transition: 0.1s;
white-space: nowrap; white-space: nowrap;
user-select: none; user-select: none;
} }
.button:hover { .button:hover {
/* background-color: #137bd2; */ /* background-color: #137bd2; */
background-color: #1b6bad; background-color: #1b6bad;
color: white; color: white;
} }
.showName { .showName {
font-size: 11px; font-size: 11px;
text-indent: 5px; text-indent: 5px;
} }
.disktopshow { .disktopshow {
font-size: 12px; font-size: 12px;
line-height: 20px; line-height: 20px;
max-width: 200px; max-width: 200px;
@ -548,8 +612,8 @@ async function handleNavSearch(path: string) {
.el-icon { .el-icon {
margin-right: 3px; margin-right: 3px;
} }
} }
.disktopshow:hover { .disktopshow:hover {
background-color: #b1f1ff4c; background-color: #b1f1ff4c;
} }
</style> </style>

160
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,66 +75,85 @@
></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>
.icon-arrow-down { .icon-arrow-down {
display: inline-block; display: inline-block;
width: 4px; width: 4px;
height: 4px; height: 4px;
@ -131,14 +163,14 @@ function handlePathPClick(index: number) {
border-top: none; border-top: none;
transition: all 0.1s; transition: all 0.1s;
margin: 0 2px; margin: 0 2px;
} }
.uper_nav { .uper_nav {
height: var(--button-item-height); height: var(--button-item-height);
display: flex; display: flex;
margin-top:5px; margin-top: 5px;
} }
.uper_nav_button { .uper_nav_button {
width: calc(var(--button-item-height) - 10px); width: calc(var(--button-item-height) - 10px);
height: var(--button-item-height); height: var(--button-item-height);
line-height: var(--button-item-height); line-height: var(--button-item-height);
@ -150,18 +182,18 @@ function handlePathPClick(index: number) {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.uper_nav_button_small { .uper_nav_button_small {
width: calc(var(--button-item-height) - 16px); width: calc(var(--button-item-height) - 16px);
} }
.uper_nav_button svg { .uper_nav_button svg {
width: calc(var(--button-item-height) - 16px); width: calc(var(--button-item-height) - 16px);
height: calc(var(--button-item-height) - 16px); height: calc(var(--button-item-height) - 16px);
} }
.path { .path {
height: calc(var(--button-item-height)); height: calc(var(--button-item-height));
width: 100%; width: 100%;
line-height: calc(var(--button-item-height) - 6px); line-height: calc(var(--button-item-height) - 6px);
@ -192,9 +224,9 @@ function handlePathPClick(index: number) {
/* text-align: center; */ /* text-align: center; */
line-height: var(--button-item-height); line-height: var(--button-item-height);
} }
} }
.path_inputing { .path_inputing {
height: calc(var(--button-item-height)); height: calc(var(--button-item-height));
width: 100%; width: 100%;
line-height: calc(var(--button-item-height) - 6px); line-height: calc(var(--button-item-height) - 6px);
@ -203,9 +235,9 @@ function handlePathPClick(index: number) {
border: 1px solid rgba(134, 134, 134, 0.267); border: 1px solid rgba(134, 134, 134, 0.267);
transition: all 0.1s; transition: all 0.1s;
user-select: text; user-select: text;
} }
.path_inputing input { .path_inputing input {
height: 100%; height: 100%;
width: 100%; width: 100%;
/* padding: 1px 5px; */ /* padding: 1px 5px; */
@ -215,13 +247,13 @@ function handlePathPClick(index: number) {
border: none; border: none;
outline: none; outline: none;
user-select: none; user-select: none;
} }
.nav-path { .nav-path {
} }
.search { .search {
width: 200px; width: 200px;
} }
.path:hover { .path:hover {
border: 1px solid rgb(0, 102, 255); border: 1px solid rgb(0, 102, 255);
} }
</style> </style>

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

@ -1,33 +1,57 @@
<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 sys = useSystem();
const userInfo = getSystemConfig().userInfo async function setFilePwd() {
async function setFilePwd() { if (
if (filePwd.value !== '' && filePwd.value.length >= 6 && filePwd.value.length <= 10) { filePwd.value !== "" &&
const path = window?.config.path || '' filePwd.value.length >= 6 &&
const res = await fetchPost(`${userInfo.url}`, filePwd.value) filePwd.value.length <= 10
console.log('路径:', res, path); ) {
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>
<style scoped> <style scoped>
.btn-group{ .btn-group {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
</style> </style>

2
frontend/src/components/setting/SetFilePwd.vue

@ -63,7 +63,7 @@ async function clearPwd() {
await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=0`) await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=0`)
setSystemKey('file',params) setSystemKey('file',params)
} }
onMounted(()=>{ onMounted(() => {
params.isPwd = config.file.isPwd params.isPwd = config.file.isPwd
setPwd.value = params.isPwd ? true : false setPwd.value = params.isPwd ? true : false
}) })

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

@ -1,18 +1,23 @@
<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");
const win: any = inject<BrowserWindow>("browserWindow"); const win: any = inject<BrowserWindow>("browserWindow");
const props = defineProps({ const props = defineProps({
src: { src: {
type: String, type: String,
default: "", default: "",
@ -25,14 +30,15 @@ const props = defineProps({
type: String, type: String,
default: "md", default: "md",
}, },
}); });
//console.log('iframe: ', props); //console.log('iframe: ', props);
//console.log(props); //console.log(props);
//let path = win?.config?.path; //let path = win?.config?.path;
const storeRef = ref<HTMLIFrameElement | null>(null); // let currentPath = ref('')
let hasInit = false; const storeRef = ref<HTMLIFrameElement | null>(null);
const eventHandler = async (e: MessageEvent) => { let hasInit = false;
const eventHandler = async (e: MessageEvent) => {
const eventData = e.data; const eventData = e.data;
if (eventData.type == props.eventType) { if (eventData.type == props.eventType) {
@ -50,33 +56,37 @@ 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: "该文件没有编辑权限",
}); });
return; return;
} }
}else if (await sys?.fs.exists(path)) { } else if (await sys?.fs.exists(path)) {
let res = await Dialog.showMessageBox({ let res = await Dialog.showMessageBox({
type: "info", type: "info",
title: "提示", title: "提示",
@ -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(
{ {
@ -144,19 +160,29 @@ const eventHandler = async (e: MessageEvent) => {
); );
} }
} }
}; };
onMounted(() => { //
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(() => {
window.addEventListener("message", eventHandler); window.addEventListener("message", eventHandler);
}); });
onUnmounted(() => { onUnmounted(async () => {
await delFileInputPwd();
window.removeEventListener("message", eventHandler); window.removeEventListener("message", eventHandler);
}); });
</script> </script>
<style scoped> <style scoped>
.setiframe { .setiframe {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: none; border: none;
} }
</style> </style>

27
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
}; };
} }
@ -108,7 +112,7 @@ export const getSystemConfig = (ifset = false) => {
password: '', password: '',
}; };
} }
if(config.userType == 'member'){ if (config.userType == 'member') {
config.account.ad = false config.account.ad = false
} }
if (!config.storenet) { if (!config.storenet) {
@ -168,7 +172,7 @@ export function getApiUrl() {
const config = getSystemConfig(); const config = getSystemConfig();
if (config.userType == 'person') { if (config.userType == 'person') {
return config.apiUrl return config.apiUrl
}else{ } else {
return config.userInfo.url return config.userInfo.url
} }
} }
@ -201,21 +205,23 @@ export function getUrl(url: string, islast = true) {
if (config.userType == 'person') { if (config.userType == 'person') {
return config.apiUrl + url return config.apiUrl + url
} else { } else {
if(islast){ if (islast) {
return config.userInfo.url + url + '&uuid=' + getClientId() + '&token=' + config.userInfo.token return config.userInfo.url + url + '&uuid=' + getClientId() + '&token=' + config.userInfo.token
}else{ } else {
return config.userInfo.url + url + '?uuid=' + getClientId() + '&token=' + config.userInfo.token return config.userInfo.url + url + '?uuid=' + getClientId() + '&token=' + config.userInfo.token
} }
} }
} }
export function getWorkflowUrl(){ export function getWorkflowUrl() {
const config = getSystemConfig(); const config = getSystemConfig();
if (config.userType == 'member') { if (config.userType == 'member') {
return config.userInfo.url + '/views/desktop/index.html' + '?uuid=' + getClientId() + '&token=' + config.userInfo.token return config.userInfo.url + '/views/desktop/index.html' + '?uuid=' + getClientId() + '&token=' + config.userInfo.token
} }
} }
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,12 +235,13 @@ 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
} }
}) })
} }
} }
export function fetchPost(url: string, data: any, headerConfig?: {[key: string]: string}) { export function fetchPost(url: string, data: any, headerConfig?: { [key: string]: string }) {
const config = getSystemConfig(); const config = getSystemConfig();
if (config.userType == 'person') { if (config.userType == 'person') {
return fetch(url, { return fetch(url, {

91
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;
} }
@ -112,8 +113,21 @@ export async function handleExists(path: string): Promise<any> {
return await res.json(); return await res.json();
} }
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,14 +277,14 @@ 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
item.fi.parentPath = turnLocalPath(item.fi.parentPath ,path) item.fi.parentPath = turnLocalPath(item.fi.parentPath, path)
item.fi.path = turnLocalPath(item.fi.path ,path) item.fi.path = turnLocalPath(item.fi.path, path)
//item.fi.titleName = turnLocalPath(item.fi.titleName, path) //item.fi.titleName = turnLocalPath(item.fi.titleName, path)
return item.fi return item.fi
}) })
@ -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)
@ -352,10 +367,10 @@ export const useOsFile = () => {
} }
return false; return false;
}, },
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;
} }
@ -412,7 +443,7 @@ export const useOsFile = () => {
return false; return false;
}, },
async search(path: string, options: any) { async search(path: string, options: any) {
console.log('search:',path, options) console.log('search:', path, options)
return true; return true;
}, },
async zip(path: string, ext: string) { async zip(path: string, ext: string) {

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

8
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