change choosefile
This commit is contained in:
parent
254355bd24
commit
f2753de7b6
4 changed files with 220 additions and 129 deletions
97
README.md
97
README.md
|
|
@ -5,7 +5,7 @@
|
|||
<h1 align="center">GodoOS</h1>
|
||||
<div align="center">
|
||||
|
||||
一款高效的内网办公平台,内含word/excel/ppt/pdf/内网聊天/白板/思维导图等多个办公系统工具,支持原生文件存储,满足多样化需求。平台界面精仿windows风格,操作简便,同时保持低资源消耗和高性能运行。无需注册即可自动连接内网用户,实现即时通讯和文件共享。
|
||||
一款高效的内网办公平台,内含word/excel/ppt/pdf/内网聊天/白板/思维导图等多个办公系统工具,支持原生文件存储。平台界面精仿windows风格,操作简便,同时保持低资源消耗和高性能运行。无需注册即可自动连接内网用户,实现即时通讯和文件共享。
|
||||
|
||||
[![license][license-image]][license-url]
|
||||
|
||||
|
|
@ -26,31 +26,110 @@
|
|||
|
||||
[Windows-image]: ./docs/img/Windows.svg
|
||||
|
||||
[Windows-url]: https://github.com/josStorer/RWKV-Runner/blob/master/build/windows/Readme_Install.txt
|
||||
[Windows-url]: https://
|
||||
|
||||
[MacOS-image]: ./docs/img/MacOS.svg
|
||||
|
||||
[MacOS-url]: https://github.com/josStorer/RWKV-Runner/blob/master/build/darwin/Readme_Install.txt
|
||||
[MacOS-url]: https://
|
||||
|
||||
[Linux-image]: ./docs/img/Linux.svg
|
||||
|
||||
[Linux-url]: https://github.com/josStorer/RWKV-Runner/blob/master/build/linux/Readme_Install.txt
|
||||
[Linux-url]: https://
|
||||
|
||||
</div>
|
||||
|
||||
## 功能说明
|
||||
|
||||
一、系统桌面
|
||||
### 一、系统桌面
|
||||
- 精仿windows风格
|
||||
- 桌面文件管理
|
||||
- 支持原生文件拖拽
|
||||
- 支持原生文件拖拽上传
|
||||
<img src="./docs/img/home.png" width="600" />
|
||||
|
||||
二、文件管理
|
||||
- 文件上传下载
|
||||
### 二、文件管理
|
||||
- 文件拖拽上传
|
||||
- 文件搜索
|
||||
- 原生文件存储
|
||||
<img src="./docs/img/file.png" width="600" />
|
||||
|
||||
三、内网聊天
|
||||
### 三、内网聊天
|
||||
- 无需繁琐的注册流程,只需在同一局域网内,即可自动发现并列出所有可用的聊天对象,即刻开启即时通讯。支持基于局域网的即时消息传输、文件传输等功能,促进团队内部的无缝沟通与协作。
|
||||
<img src="./docs/img/localchat.png" width="600" />
|
||||
|
||||
### 四、文档
|
||||
- 简便的word编辑器,原生存储,支持二维码、手写签名,导入导出
|
||||
<img src="./docs/img/doc.png" width="600" />
|
||||
|
||||
### 五、表格
|
||||
- 原生存储,Excel编辑器,支持导入、导出,支持图片、公式
|
||||
<img src="./docs/img/excel.png" width="600" />
|
||||
|
||||
### 六、markdown
|
||||
- 原生存储,采用vditor,支持导入、导出,支持大纲、实时预览
|
||||
<img src="./docs/img/markdown.png" width="600" />
|
||||
|
||||
### 七、思维导图
|
||||
- 内置多种主题;支持快捷键;节点内容支持图片、图标、超链接、备注、标签。
|
||||
<img src="./docs/img/mind.png" width="600" />
|
||||
|
||||
### 八、演示文稿
|
||||
- 原生存储,采用pptist,支持文字、图片、形状、线条、图表、表格、视频、公式等。
|
||||
<img src="./docs/img/ppt.png" width="600" />
|
||||
|
||||
### 九、文件编辑器
|
||||
- 原生存储,支持打开text/html/css/js/svg/xml/md等,可以当作一个简单的在线editplus。
|
||||
<img src="./docs/img/fileeditor.png" width="600" />
|
||||
|
||||
### 十、白板
|
||||
- 集自由布局、画笔、便签多种创意表达能力于一体,激发团队创造力,随时随地,围绕一块白板沟通。
|
||||
<img src="./docs/img/baiban.png" width="600" />
|
||||
|
||||
### 十一、图片编辑
|
||||
- 一个小型的photoshop,原生存储,支持搜索图片,支持图片裁剪、旋转、缩放、滤镜等功能
|
||||
<img src="./docs/img/pic.png" width="600" />
|
||||
|
||||
### 十二、甘特图
|
||||
- 项目管理必备工具,支持自定义项目人员和角色,支持拖拽/管理分配(资源、角色、工作)等。
|
||||
<img src="./docs/img/gant.png" width="600" />
|
||||
|
||||
### 十三、浏览器
|
||||
- 一款简单的内置浏览器
|
||||
<img src="./docs/img/ie.png" width="600" />
|
||||
|
||||
|
||||
### 十四、系统设置
|
||||
- 可在这里切换存储方式,可切换系统背景。
|
||||
<img src="./docs/img/setting-store.png" width="600" />
|
||||
|
||||
### 十五、应用商店
|
||||
- 应用商店管理,可添加外部应用。
|
||||
|
||||
### 十六、截图
|
||||
- 一个简单的截图工具。截图后文件存到本地。
|
||||
|
||||
### 十七、录屏
|
||||
- 一个简单的录屏工具。录屏后录后文件存到本地。
|
||||
|
||||
### 十八、计算器
|
||||
- 一个仿windows10的计算器,支持历史记录。
|
||||
<img src="./docs/img/cal.png" width="600" />
|
||||
|
||||
### 十九、音乐库
|
||||
- 一个简单的声音存储库,支持播放音乐。
|
||||
|
||||
### 二十、图片库
|
||||
- 一个简单的图片存储库,支持查看图片
|
||||
|
||||
### 二十一、看板
|
||||
- 支持标准看板,项目管理必备工具,可快速创建看板并放置到不同的文件夹
|
||||
<img src="./docs/img/kanban.png" width="600" />
|
||||
|
||||
## 开发
|
||||
|
||||
## 感谢
|
||||
- [element-plus](http://element-plus.org/)
|
||||
- [vue3](https://v3.cn.vuejs.org/)
|
||||
- [wails](https://wails.io/)
|
||||
- [pptist](https://github.com/pipipi-pikachu/PPTist)
|
||||
- [vditor](https://github.com/Vanessa219/vditor)
|
||||
- [mind-map](https://github.com/wanglin2/mind-map)
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
draggable="true"
|
||||
class="file-item"
|
||||
:class="{
|
||||
<div draggable="true" class="file-item" :class="{
|
||||
chosen: chosenIndexs.includes(index),
|
||||
'no-chosen': !chosenIndexs.includes(index),
|
||||
'mode-icon': mode === 'icon',
|
||||
|
|
@ -29,50 +26,27 @@
|
|||
'mode-middle': mode === 'middle',
|
||||
'mode-detail': mode === 'detail',
|
||||
'drag-over': hoverIndex === index,
|
||||
}"
|
||||
:style="{
|
||||
}" :style="{
|
||||
'--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)"
|
||||
@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) => {
|
||||
}" v-for="(item, index) in fileList" :key="item.path" @dblclick="handleOnOpen(item)"
|
||||
@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) {
|
||||
appPositions[index] = markRaw(ref as Element);
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
">
|
||||
<div class="file-item_img">
|
||||
<FileIcon :file="item" />
|
||||
</div>
|
||||
<span v-if="editIndex !== index" class="file-item_title">
|
||||
{{ getName(item) }}
|
||||
</span>
|
||||
<textarea
|
||||
autofocus
|
||||
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>
|
||||
<textarea autofocus 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'">
|
||||
<div class="file-item_type">
|
||||
<span>{{ item.isDirectory ? "-" : dealSize(item.size) }}</span>
|
||||
|
|
@ -93,8 +67,6 @@
|
|||
import { useSystem, basename, dirname, join, OsFileWithoutContent } from '@/system/index.ts';
|
||||
import { emitEvent, mountEvent } from '@/system/event';
|
||||
import { useContextMenu } from '@/hook/useContextMenu.ts';
|
||||
// import { basename, dirname, join } from '@/system/core/Path';
|
||||
// import { OsFileWithoutContent } from '@/system/core/FileSystem';
|
||||
import { i18n, dealSystemName } from '@/i18n';
|
||||
import { useFileDrag } from '@/hook/useFileDrag';
|
||||
import { useAppMenu } from '@/hook/useAppMenu';
|
||||
|
|
@ -103,9 +75,11 @@ 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";
|
||||
const { openPropsWindow, copyFile, createLink, deleteFile } = useContextMenu();
|
||||
const sys = useSystem();
|
||||
const { startDrag, folderDrop } = useFileDrag(sys);
|
||||
const choose = useChooseStore()
|
||||
const props = defineProps({
|
||||
onChosen: {
|
||||
type: Function,
|
||||
|
|
@ -149,9 +123,15 @@ function getName(item:any){
|
|||
}
|
||||
function handleOnOpen(item: OsFileWithoutContent) {
|
||||
chosenIndexs.value = [];
|
||||
if (choose.ifShow && !item.isDirectory) {
|
||||
choose.path.push(item.path)
|
||||
choose.close()
|
||||
} else {
|
||||
props.onOpen(item);
|
||||
emitEvent('desktop.app.open');
|
||||
}
|
||||
|
||||
}
|
||||
function hadnleDrop(mouse: DragEvent, path: string) {
|
||||
hoverIndex.value = -1;
|
||||
folderDrop(mouse, path);
|
||||
|
|
@ -267,27 +247,27 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
|
|||
// },
|
||||
|
||||
];
|
||||
//console.log(item.parentPath)
|
||||
//let filePath = item.path;
|
||||
// if(filePath.length > 1) {
|
||||
// if(filePath.charAt(1) === "B") {
|
||||
// menuArr.push({
|
||||
// label: "还原",
|
||||
// click: async () => {
|
||||
// //console.log(item);
|
||||
// await Promise.all(
|
||||
// chosenIndexs.value.map((index) => {
|
||||
// const item = props.fileList[index];
|
||||
// return backFile(item);
|
||||
// })
|
||||
// );
|
||||
// chosenIndexs.value = [];
|
||||
// props.onRefresh();
|
||||
if (choose.ifShow) {
|
||||
menuArr.push({
|
||||
label: i18n('selected'),
|
||||
click: () => {
|
||||
const paths: any = []
|
||||
chosenIndexs.value.forEach((index) => {
|
||||
const item = props.fileList[index];
|
||||
if (!item.isDirectory) {
|
||||
paths.push(item.path)
|
||||
}
|
||||
})
|
||||
if (paths.length > 0) {
|
||||
choose.path = paths
|
||||
choose.close()
|
||||
}
|
||||
chosenIndexs.value = [];
|
||||
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
},
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line prefer-const
|
||||
let extMenus = useAppMenu(item, index);
|
||||
if (extMenus && extMenus.length > 0) {
|
||||
|
|
@ -391,17 +371,21 @@ function handleDragLeave() {
|
|||
padding-top: 4px;
|
||||
border: 1px solid transparent;
|
||||
margin: 6px;
|
||||
|
||||
.file-item_img {
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.file-item_type {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-item_title {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.file-item_editing {
|
||||
display: inline-block !important;
|
||||
outline: none;
|
||||
|
|
@ -419,10 +403,12 @@ function handleDragLeave() {
|
|||
.file-item:hover {
|
||||
background-color: #b1f1ff4c;
|
||||
}
|
||||
|
||||
.chosen {
|
||||
border: 1px dashed #3bdbff3d;
|
||||
// background-color: #ffffff6b;
|
||||
background-color: var(--theme-color);
|
||||
|
||||
.file-item_title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
|
@ -432,6 +418,7 @@ function handleDragLeave() {
|
|||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.no-chosen {
|
||||
.file-item_title {
|
||||
overflow: hidden;
|
||||
|
|
@ -442,11 +429,13 @@ function handleDragLeave() {
|
|||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.drag-over {
|
||||
border: 1px dashed #3bdbff3d;
|
||||
// background-color: #ffffff6b;
|
||||
background-color: var(--theme-color);
|
||||
}
|
||||
|
||||
.mode-icon {
|
||||
.file-item_img {
|
||||
width: 60%;
|
||||
|
|
@ -486,18 +475,22 @@ function handleDragLeave() {
|
|||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.mode-icon {
|
||||
width: var(--desk-item-size);
|
||||
height: var(--desk-item-size);
|
||||
}
|
||||
|
||||
.mode-big {
|
||||
width: calc(var(--desk-item-size) * 2.5);
|
||||
height: calc(var(--desk-item-size) * 2.5);
|
||||
}
|
||||
|
||||
.mode-middle {
|
||||
width: calc(var(--desk-item-size) * 1.5);
|
||||
height: calc(var(--desk-item-size) * 1.5);
|
||||
}
|
||||
|
||||
.mode-detail {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
@ -505,9 +498,11 @@ function handleDragLeave() {
|
|||
height: var(--menulist-item-height);
|
||||
width: 100%;
|
||||
margin: 2px;
|
||||
|
||||
.file-item_img {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.file-item_title {
|
||||
width: 40%;
|
||||
display: flex;
|
||||
|
|
@ -517,6 +512,7 @@ function handleDragLeave() {
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.file-item_type {
|
||||
display: block;
|
||||
color: var(--color-dark-hover);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,19 @@ const { refersh, createFolder, backFolder, openFolder, onComputerMount } = useCo
|
|||
},
|
||||
setFileList(list) {
|
||||
//console.log(list)
|
||||
//currentList.value = list;
|
||||
if(config.ext && config.ext instanceof Array && config.ext.length > 0) {
|
||||
const res:any = []
|
||||
list.forEach((d : any) => {
|
||||
|
||||
if(config.ext.includes(d.ext) || d.isDirectory){
|
||||
res.push(d)
|
||||
}
|
||||
})
|
||||
currentList.value = res;
|
||||
}else{
|
||||
currentList.value = list;
|
||||
}
|
||||
},
|
||||
openFile(path) {
|
||||
system?.openFile(path);
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ import { BrowserWindow } from "@/system";
|
|||
import { ref } from 'vue';
|
||||
export const useChooseStore = defineStore('chooseStore', () => {
|
||||
const win:any = ref()
|
||||
const path = ref([])
|
||||
const path:any = ref([])
|
||||
const ifShow = ref(false)
|
||||
const select = (title = '选择文件', fileExt:any) => {
|
||||
win.value = new BrowserWindow({
|
||||
title,
|
||||
content: "FileList",
|
||||
content: "Computer",
|
||||
config: {
|
||||
ext: fileExt,
|
||||
path: '/'
|
||||
|
|
@ -22,14 +23,17 @@ export const useChooseStore = defineStore('chooseStore', () => {
|
|||
resizable: true,
|
||||
});
|
||||
win.value.show()
|
||||
ifShow.value = true
|
||||
}
|
||||
const close = () => {
|
||||
ifShow.value = false
|
||||
win.value.close()
|
||||
}
|
||||
|
||||
return {
|
||||
win,
|
||||
path,
|
||||
ifShow,
|
||||
select,
|
||||
close
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue