change readme
This commit is contained in:
parent
382fca2364
commit
336c57e042
14 changed files with 753 additions and 711 deletions
14
README.en.md
14
README.en.md
|
|
@ -11,6 +11,8 @@ An efficient intranet office platform that includes various tools such as Word,
|
||||||
|
|
||||||
English | [简体中文](README.md)
|
English | [简体中文](README.md)
|
||||||
|
|
||||||
|
[FAQ](./docs/Faq.md) | [API](./docs/Api.md)
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|
||||||
[![Windows][Windows-image]][Windows-url]
|
[![Windows][Windows-image]][Windows-url]
|
||||||
|
|
@ -38,12 +40,12 @@ English | [简体中文](README.md)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
- No need for internet connection, fully open source
|
- ***No need for internet connection, fully open source***
|
||||||
- Zero configuration, no registration required, download and use immediately
|
- ***Zero configuration, no registration required, download and use immediately***
|
||||||
- Zero pollution, no plugin dependency
|
- ***Zero pollution, no plugin dependency***
|
||||||
- Small in size, packaged for only 61M, it does include all the office suites
|
- ***Small in size, packaged for only 61M, it does include all the office suites***
|
||||||
- Unlimited scalability, supports custom applications
|
- ***Unlimited scalability, supports custom applications***
|
||||||
- Golang develops backend with low resource consumption and high performance
|
- ***Golang develops backend with low resource consumption and high performance***
|
||||||
|
|
||||||
## Function Description
|
## Function Description
|
||||||
|
|
||||||
|
|
|
||||||
28
README.md
28
README.md
|
|
@ -11,6 +11,10 @@
|
||||||
|
|
||||||
[English](README.en.md) | 简体中文
|
[English](README.en.md) | 简体中文
|
||||||
|
|
||||||
|
[FAQ](./docs/Faq.md) | [API](./docs/Api.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 安装
|
### 安装
|
||||||
|
|
||||||
[![Windows][Windows-image]][Windows-url]
|
[![Windows][Windows-image]][Windows-url]
|
||||||
|
|
@ -38,14 +42,24 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 亮点
|
## 亮点
|
||||||
- 无需联网使用,全开源
|
- ***无需联网使用,全开源***
|
||||||
- 零配置,无需注册,下载即用
|
- ***零配置,无需注册,下载即用***
|
||||||
- 零污染,无插件依赖
|
- ***零污染,无插件依赖***
|
||||||
- 精小,打包后仅61M,确包含了所有的办公套件
|
- ***精小,打包后仅61M,确包含了所有的办公套件***
|
||||||
- 可无限扩展,支持自定义应用
|
- ***可无限扩展,支持自定义应用***
|
||||||
- golang开发后端,低资源消耗和高性能
|
- ***golang开发后端,低资源消耗和高性能***
|
||||||
|
|
||||||
## 功能说明
|
## 开发进程
|
||||||
|
- 2024年7月,发布v1.0.0版本,发布后,项目进入第二阶段。
|
||||||
|
|
||||||
|
## 第二阶段目标
|
||||||
|
- [x] 完善的应用商店体系
|
||||||
|
- [x] 完善开发文档
|
||||||
|
- [x] 支持远程存储
|
||||||
|
- [x] 完成企业客户端
|
||||||
|
|
||||||
|
|
||||||
|
## 功能说明和预览
|
||||||
|
|
||||||
### 一、系统桌面
|
### 一、系统桌面
|
||||||
- 精仿windows风格
|
- 精仿windows风格
|
||||||
|
|
|
||||||
239
docs/Api.md
239
docs/Api.md
|
|
@ -0,0 +1,239 @@
|
||||||
|
## API
|
||||||
|
- 系统接口地址: http://localhost:56780
|
||||||
|
|
||||||
|
### 读取目录
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/read`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `path` (目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 目录内容列表
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 获取文件或目录状态
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/stat`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `path` (文件或目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 文件或目录的状态信息
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 更改文件权限
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`POST`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/chmod`
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **Body**: `{ "path": "string", "mode": "string" }`
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 检查文件或目录是否存在
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/exists`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `path` (文件或目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 存在性检查结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 读取文件内容
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/readfile`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `path` (文件路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 文件内容
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 删除文件
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/unlink`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `path` (文件路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 清空文件系统
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/clear`
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 重命名文件或目录
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/rename`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `oldPath` (原文件或目录路径), `newPath` (新文件或目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 创建目录
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`POST`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/mkdir`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `dirPath` (目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 删除目录
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/rmdir`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `dirPath` (目录路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 复制文件
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`GET`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/copyfile`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `srcPath` (源文件路径), `dstPath` (目标文件路径)
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 写入文件
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`POST`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/writefile`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `filePath` (文件路径)
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
- **Content-Type**: `multipart/form-data`
|
||||||
|
- **Body**: 包含 `content` 的表单数据
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 追加文件内容
|
||||||
|
|
||||||
|
#### HTTP 方法
|
||||||
|
`POST`
|
||||||
|
|
||||||
|
#### 路径
|
||||||
|
`/files/appendfile`
|
||||||
|
|
||||||
|
#### 请求参数
|
||||||
|
- **Query 参数**: `filePath` (文件路径)
|
||||||
|
|
||||||
|
#### 请求体
|
||||||
|
- **Content-Type**: `multipart/form-data`
|
||||||
|
- **Body**: 包含 `content` 的表单数据
|
||||||
|
|
||||||
|
#### 响应
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
- **响应体**: 操作结果
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 文件系统事件监听
|
||||||
|
|
||||||
|
#### 功能
|
||||||
|
监听文件系统变化事件
|
||||||
|
|
||||||
|
#### 参数
|
||||||
|
- **path** (监听的文件或目录路径)
|
||||||
|
- **callback** (事件回调函数)
|
||||||
|
- **errback** (错误回调函数)
|
||||||
15
docs/Faq.md
Normal file
15
docs/Faq.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
## 是否支持浏览器访问?
|
||||||
|
- 支持。
|
||||||
|
```
|
||||||
|
cd frontend
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
然后复制打包后的dist目录到运行程序的根目录,然后重启程序。访问地址为http://localhost:56780/
|
||||||
|
|
||||||
|
## 为什么找不到本地文件?
|
||||||
|
程序默认为浏览器存储。进入系统设置,修改存储方式为本地存储。
|
||||||
|
|
||||||
|
## 是否支持切换存储目录?
|
||||||
|
-支持。
|
||||||
|
进入系统设置页面,修改存储目录即可。修改后程序会重启一次。
|
||||||
|
|
||||||
241
docs/file.md
241
docs/file.md
|
|
@ -1,241 +0,0 @@
|
||||||
---
|
|
||||||
title: 文件系统接口
|
|
||||||
icon: circle-info
|
|
||||||
---
|
|
||||||
|
|
||||||
### 读取目录
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/read`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `path` (目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 目录内容列表
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 获取文件或目录状态
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/stat`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `path` (文件或目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 文件或目录的状态信息
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 更改文件权限
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`POST`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/chmod`
|
|
||||||
|
|
||||||
#### 请求体
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **Body**: `{ "path": "string", "mode": "string" }`
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 检查文件或目录是否存在
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/exists`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `path` (文件或目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 存在性检查结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 读取文件内容
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/readfile`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `path` (文件路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 文件内容
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 删除文件
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/unlink`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `path` (文件路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 清空文件系统
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/clear`
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 重命名文件或目录
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/rename`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `oldPath` (原文件或目录路径), `newPath` (新文件或目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 创建目录
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`POST`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/mkdir`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `dirPath` (目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 删除目录
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/rmdir`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `dirPath` (目录路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 复制文件
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`GET`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/copyfile`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `srcPath` (源文件路径), `dstPath` (目标文件路径)
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 写入文件
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`POST`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/writefile`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `filePath` (文件路径)
|
|
||||||
|
|
||||||
#### 请求体
|
|
||||||
- **Content-Type**: `multipart/form-data`
|
|
||||||
- **Body**: 包含 `content` 的表单数据
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 追加文件内容
|
|
||||||
|
|
||||||
#### HTTP 方法
|
|
||||||
`POST`
|
|
||||||
|
|
||||||
#### 路径
|
|
||||||
`/appendfile`
|
|
||||||
|
|
||||||
#### 请求参数
|
|
||||||
- **Query 参数**: `filePath` (文件路径)
|
|
||||||
|
|
||||||
#### 请求体
|
|
||||||
- **Content-Type**: `multipart/form-data`
|
|
||||||
- **Body**: 包含 `content` 的表单数据
|
|
||||||
|
|
||||||
#### 响应
|
|
||||||
- **Content-Type**: `application/json`
|
|
||||||
- **响应体**: 操作结果
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 文件系统事件监听
|
|
||||||
|
|
||||||
#### 功能
|
|
||||||
监听文件系统变化事件
|
|
||||||
|
|
||||||
#### 参数
|
|
||||||
- **path** (监听的文件或目录路径)
|
|
||||||
- **callback** (事件回调函数)
|
|
||||||
- **errback** (错误回调函数)
|
|
||||||
339
frontend/src/assets/store.scss
Normal file
339
frontend/src/assets/store.scss
Normal file
|
|
@ -0,0 +1,339 @@
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||||
|
background-color: rgba(132, 132, 132, 0.537);
|
||||||
|
}
|
||||||
|
|
||||||
|
.outer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uper {
|
||||||
|
padding: 0px 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: rgb(134, 134, 134);
|
||||||
|
background-color: rgb(243, 243, 243);
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-handle {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
user-select: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: rgb(243, 243, 243);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 60px;
|
||||||
|
height: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
background-color: rgb(243, 243, 243);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-icon {
|
||||||
|
width: 56px;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: white;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(243, 243, 243);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-derc {
|
||||||
|
height: 20px;
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #363533;
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-icon .ep_icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
color: #363533;
|
||||||
|
stroke: #363533;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store {
|
||||||
|
/* width: 100%; */
|
||||||
|
flex: 1;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-top {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-bar {
|
||||||
|
width: 60px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-main {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title {
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-variant-ligatures: discretionary-ligatures;
|
||||||
|
margin: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-title {
|
||||||
|
padding-top: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 10px;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgb(11, 31, 111);
|
||||||
|
margin-left: 10px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper {
|
||||||
|
width: max-content;
|
||||||
|
height: 300px;
|
||||||
|
/* overflow: hidden; */
|
||||||
|
margin: 0px 10px 10px 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes swiperAni {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
33% {
|
||||||
|
transform: translateX(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
36%,
|
||||||
|
66% {
|
||||||
|
transform: translateX(-600px);
|
||||||
|
}
|
||||||
|
|
||||||
|
69%,
|
||||||
|
96% {
|
||||||
|
transform: translateX(-1200px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper-inner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
animation: swiperAni 20s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper-tab {
|
||||||
|
width: 600px;
|
||||||
|
height: 300px;
|
||||||
|
background-color: rgb(243, 243, 243);
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0px 10px 20px 1px #2524241f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper-tab img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 20px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swiper-txt {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 30px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
z-index: 10;
|
||||||
|
text-shadow: 0px 0px 5px #00000058;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-app {
|
||||||
|
width: 100%;
|
||||||
|
/* height: 100%; */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: auto;
|
||||||
|
align-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-noready {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #cdcdcd69;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wait {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waitd {
|
||||||
|
position: absolute;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
left: 30px;
|
||||||
|
background-color: azure;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform-origin: -15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wait1 {
|
||||||
|
animation: dotAni1 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wait2 {
|
||||||
|
animation: dotAni2 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wait3 {
|
||||||
|
animation: dotAni3 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wait4 {
|
||||||
|
animation: dotAni4 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dotAni1 {
|
||||||
|
0% {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
20% {
|
||||||
|
transform: rotateZ(240deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
85% {
|
||||||
|
transform: rotateZ(290deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dotAni2 {
|
||||||
|
0% {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
35% {
|
||||||
|
transform: rotateZ(240deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
85% {
|
||||||
|
transform: rotateZ(290deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dotAni3 {
|
||||||
|
0% {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: rotateZ(240deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
85% {
|
||||||
|
transform: rotateZ(290deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dotAni4 {
|
||||||
|
0% {
|
||||||
|
transform: rotateZ(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
65% {
|
||||||
|
transform: rotateZ(240deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
85% {
|
||||||
|
transform: rotateZ(290deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotateZ(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,59 +1,66 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { OpenDirDialog } from "@/util/goutil";
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
importType: 'remote'
|
importType: 'download',
|
||||||
|
url: '',
|
||||||
|
devPath:''
|
||||||
})
|
})
|
||||||
const addType = [
|
const addType = [
|
||||||
{
|
{
|
||||||
'name' : '远程下载',
|
'name': '远程下载',
|
||||||
'type' : 'remote'
|
'type': 'download'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name' : '本地导入',
|
'name': '本地导入',
|
||||||
'type' : 'local'
|
'type': 'local'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name' : '开发模式',
|
'name': '开发模式',
|
||||||
'type' : 'dev'
|
'type': 'dev'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
function selectFile() {
|
||||||
|
OpenDirDialog().then((res: string) => {
|
||||||
|
formData.value.devPath = res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function addAppByDownload() {
|
||||||
|
|
||||||
|
}
|
||||||
|
async function addAppByImport() {
|
||||||
|
|
||||||
|
}
|
||||||
|
async function addAppByDev() {
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="setting">
|
<el-form label-width="auto" style="max-width: 600px;padding-left: 30px;">
|
||||||
<div class="setting-item">
|
<el-form-item label="添加方式">
|
||||||
<label>添加方式</label>
|
<el-select v-model="formData.importType" style="width: 280px;">
|
||||||
<el-select v-model="formData.importType" style="width: 180px;">
|
<el-option v-for="item in addType" :key="item.type" :label="item.name" :value="item.type" />
|
||||||
<el-option
|
|
||||||
v-for="item in addType"
|
|
||||||
:key="item.type"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.type"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</el-form-item>
|
||||||
</div>
|
<template v-if="formData.importType == 'download'">
|
||||||
|
<el-form-item label="下载地址">
|
||||||
|
<el-input v-model="formData.url" style="width: 280px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-button type="primary" @click="addAppByDownload()">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-if="formData.importType == 'local'">
|
||||||
|
<el-button type="primary" @click="addAppByImport()">导入</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-if="formData.importType == 'dev'">
|
||||||
|
<el-form-item label="本地路径">
|
||||||
|
<el-input v-model="formData.devPath" style="width: 280px;" @click="selectFile()" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-button type="primary" @click="addAppByDev()">添加</el-button>
|
||||||
|
</template>
|
||||||
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.el-button {
|
||||||
.setting-item {
|
margin:20px 100px
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-item label {
|
|
||||||
display: block;
|
|
||||||
width: 100px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
/>
|
/>
|
||||||
<div class="app-content">
|
<div class="app-content">
|
||||||
<div class="app-title">{{ item?.name }}</div>
|
<div class="app-title">{{ item?.name }}</div>
|
||||||
<div class="app-desc">{{ item?.desc ? item?.desc : item?.name }}</div>
|
<div class="app-desc">{{ item?.desc ?? item?.name }}</div>
|
||||||
<div class="app-button">
|
<div class="app-button">
|
||||||
<div
|
<div
|
||||||
v-if="installedList!.includes(item?.name)"
|
v-if="installedList!.includes(item?.name)"
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<button @click="uninstall?.(item)">卸载</button>
|
<button @click="uninstall?.(item)">卸载</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<button v-if="item?.url" @click="install?.(item)">安装</button>
|
<button v-if="item?.url || item?.path" @click="install?.(item)">安装</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -75,12 +75,12 @@ defineProps({
|
||||||
}
|
}
|
||||||
.app-item:hover {
|
.app-item:hover {
|
||||||
box-shadow: 0 0 20px 2px #dddddd5b;
|
box-shadow: 0 0 20px 2px #dddddd5b;
|
||||||
/* transform: translateY(-2px); */
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
/* .app-item:active {
|
.app-item:active {
|
||||||
box-shadow: 0 0 0px #ccc;
|
box-shadow: 0 0 0px #ccc;
|
||||||
transform: translateY(0px);
|
transform: translateY(0px);
|
||||||
} */
|
}
|
||||||
.app-button {
|
.app-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,70 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { inject, onMounted, ref } from "vue";
|
||||||
|
import { System } from "@/system";
|
||||||
|
import {notifySuccess, notifyError} from "@/util/msg";
|
||||||
|
import { t } from "@/i18n";
|
||||||
|
//import storeList from "@/assets/store.json";
|
||||||
|
import { getSystemKey, setSystemKey } from "@/system/config";
|
||||||
|
const sys: any = inject<System>("system");
|
||||||
|
const currentCateId = ref(0)
|
||||||
|
const currentTitle = ref(t("store.hots"))
|
||||||
|
const currentCate = ref('hots')
|
||||||
|
const categoryList = ['hots', 'work', 'development', 'games', 'education', 'news', 'shopping', 'social', 'utilities', 'others', 'add']
|
||||||
|
const categoryIcon = ['HomeFilled', 'Odometer', 'Postcard', 'TrendCharts', 'School', 'HelpFilled', 'ShoppingCart', 'ChatLineRound', 'MessageBox', 'Ticket', 'CirclePlusFilled']
|
||||||
|
const isready = ref(false);
|
||||||
|
const installed = getSystemKey("intstalledPlugins");
|
||||||
|
const apiUrl = getSystemKey("apiUrl");
|
||||||
|
const installedList: any = ref(installed);
|
||||||
|
const storeList: any = ref([])
|
||||||
|
onMounted(async() => {
|
||||||
|
await getList();
|
||||||
|
|
||||||
|
});
|
||||||
|
async function getList(){
|
||||||
|
if(currentCate.value == 'add')return;
|
||||||
|
const storeUrl = apiUrl + '/system/storeList?cate=' + currentCate.value
|
||||||
|
fetch(storeUrl).then(res => {
|
||||||
|
res.json().then(data => {
|
||||||
|
storeList.value = data
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
notifyError(t("store.errorList"))
|
||||||
|
})
|
||||||
|
isready.value = true;
|
||||||
|
}
|
||||||
|
async function changeCate(index: number, item: string) {
|
||||||
|
currentCateId.value = index
|
||||||
|
currentCate.value = item
|
||||||
|
currentTitle.value = t("store." + item)
|
||||||
|
await getList()
|
||||||
|
}
|
||||||
|
function setCache() {
|
||||||
|
setSystemKey("intstalledPlugins", installedList.value);
|
||||||
|
setTimeout(() => {
|
||||||
|
sys.refershAppList();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
function install(item: any) {
|
||||||
|
//console.log(item)
|
||||||
|
if(item.url){
|
||||||
|
sys.fs.writeFile(
|
||||||
|
`${sys._options.userLocation}Desktop/${item.name}.url`,
|
||||||
|
`link::url::${item.url}::${item.icon}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifySuccess(t("install.success"))
|
||||||
|
installedList.value.push(item.name);
|
||||||
|
setCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall(item: any) {
|
||||||
|
sys.fs.unlink(`${sys._options.userLocation}Desktop/${item.name}.url`);
|
||||||
|
notifySuccess(t("uninstall.success"))
|
||||||
|
delete installedList.value[installedList.value.indexOf(item.name)];
|
||||||
|
setCache();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="outer">
|
<div class="outer">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
|
|
@ -33,7 +100,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="main-app">
|
<div class="main-app">
|
||||||
<div v-for="item in storeList" v-if="currentTitle != t('store.add')" class="store-item" :key="item.name">
|
<div v-for="item in storeList" v-if="currentCate != 'add'" class="store-item" :key="item.name">
|
||||||
<AppItem :item="item" :installed-list="installedList" :install="install" :uninstall="uninstall" />
|
<AppItem :item="item" :installed-list="installedList" :install="install" :uninstall="uninstall" />
|
||||||
</div>
|
</div>
|
||||||
<AddApp v-else/>
|
<AddApp v-else/>
|
||||||
|
|
@ -53,412 +120,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
|
||||||
import { inject, onMounted, ref } from "vue";
|
|
||||||
import { System, Dialog } from "@/system";
|
|
||||||
import { t } from "@/i18n";
|
|
||||||
//import storeList from "@/assets/store.json";
|
|
||||||
import { getSystemKey, setSystemKey } from "@/system/config";
|
|
||||||
const sys: any = inject<System>("system");
|
|
||||||
const currentCateId = ref(0)
|
|
||||||
const currentTitle = ref(t("store.hots"))
|
|
||||||
const categoryList = ['hots', 'work', 'development', 'games', 'education', 'news', 'shopping', 'social', 'utilities', 'others', 'add']
|
|
||||||
const categoryIcon = ['HomeFilled', 'Odometer', 'Postcard', 'TrendCharts', 'School', 'HelpFilled', 'ShoppingCart', 'ChatLineRound', 'MessageBox', 'Ticket', 'CirclePlusFilled']
|
|
||||||
const isready = ref(false);
|
|
||||||
const installed = getSystemKey("intstalledPlugins");
|
|
||||||
const installedList: any = ref(installed);
|
|
||||||
const storeList: any = ref([])
|
|
||||||
onMounted(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!isready.value) {
|
|
||||||
isready.value = true;
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
function changeCate(index: number, item: string) {
|
|
||||||
currentCateId.value = index
|
|
||||||
currentTitle.value = t("store." + item)
|
|
||||||
}
|
|
||||||
function setCache() {
|
|
||||||
setSystemKey("intstalledPlugins", installedList.value);
|
|
||||||
//localStorage.setItem("godoOS_installedApp", JSON.stringify(installedList.value))
|
|
||||||
setTimeout(() => {
|
|
||||||
sys.refershAppList();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
function install(item: any) {
|
|
||||||
//console.log(item)
|
|
||||||
sys.fs.writeFile(
|
|
||||||
`${sys._options.userLocation}Desktop/${item.name}.url`,
|
|
||||||
`link::url::${item.url}::${item.icon}`
|
|
||||||
);
|
|
||||||
Dialog.showMessageBox({
|
|
||||||
message: t("install.success"),
|
|
||||||
type: "info",
|
|
||||||
buttons: [t("confirm")],
|
|
||||||
});
|
|
||||||
installedList.value.push(item.name);
|
|
||||||
setCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstall(item: any) {
|
|
||||||
sys.fs.unlink(`${sys._options.userLocation}Desktop/${item.name}.url`);
|
|
||||||
Dialog.showMessageBox({
|
|
||||||
message: t("uninstall.success"),
|
|
||||||
type: "info",
|
|
||||||
buttons: [t("confirm")],
|
|
||||||
});
|
|
||||||
delete installedList.value[installedList.value.indexOf(item.name)];
|
|
||||||
setCache();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/*定义滚动条高宽及背景
|
|
||||||
高宽分别对应横竖滚动条的尺寸*/
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 5px;
|
|
||||||
height: 16px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*定义滚动条轨道
|
|
||||||
内阴影+圆角*/
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*定义滑块
|
|
||||||
内阴影+圆角*/
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 10px;
|
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
|
||||||
background-color: rgba(132, 132, 132, 0.537);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.outer {
|
@import "@/assets/store.scss";
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uper {
|
|
||||||
padding: 0px 20px;
|
|
||||||
font-size: 12px;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
color: rgb(134, 134, 134);
|
|
||||||
background-color: rgb(243, 243, 243);
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-handle {
|
|
||||||
width: 100%;
|
|
||||||
height: 40px;
|
|
||||||
user-select: none;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-end;
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgb(243, 243, 243);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
width: 60px;
|
|
||||||
height: auto;
|
|
||||||
flex-shrink: 0;
|
|
||||||
background-color: rgb(243, 243, 243);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-icon {
|
|
||||||
width: 56px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background-color: white;
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgb(243, 243, 243);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-derc {
|
|
||||||
height: 20px;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #363533;
|
|
||||||
position: absolute;
|
|
||||||
left: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-icon .ep_icon {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
color: #363533;
|
|
||||||
stroke: #363533;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store {
|
|
||||||
/* width: 100%; */
|
|
||||||
flex: 1;
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
border-top-left-radius: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-top {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: flex-start;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-bar {
|
|
||||||
width: 60px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-main {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-title {
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-variant: small-caps;
|
|
||||||
font-variant-ligatures: discretionary-ligatures;
|
|
||||||
margin: 8px;
|
|
||||||
margin-top: 8px;
|
|
||||||
user-select: none;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-title {
|
|
||||||
padding-top: 30px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 10px;
|
|
||||||
user-select: none;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-tip {
|
|
||||||
font-size: 12px;
|
|
||||||
color: rgb(11, 31, 111);
|
|
||||||
margin-left: 10px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper {
|
|
||||||
width: max-content;
|
|
||||||
height: 300px;
|
|
||||||
/* overflow: hidden; */
|
|
||||||
margin: 10px;
|
|
||||||
margin-top: 0px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes swiperAni {
|
|
||||||
|
|
||||||
0%,
|
|
||||||
33% {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
36%,
|
|
||||||
66% {
|
|
||||||
transform: translateX(-600px);
|
|
||||||
}
|
|
||||||
|
|
||||||
69%,
|
|
||||||
96% {
|
|
||||||
transform: translateX(-1200px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translateX(0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-inner {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
animation: swiperAni 20s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-tab {
|
|
||||||
width: 600px;
|
|
||||||
height: 300px;
|
|
||||||
background-color: rgb(243, 243, 243);
|
|
||||||
border-radius: 20px;
|
|
||||||
box-shadow: 0px 10px 20px 1px #2524241f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-tab img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 20px;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-txt {
|
|
||||||
position: absolute;
|
|
||||||
top: 20px;
|
|
||||||
left: 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: white;
|
|
||||||
z-index: 10;
|
|
||||||
text-shadow: 0px 0px 5px #00000058;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-app {
|
|
||||||
width: 100%;
|
|
||||||
/* height: 100%; */
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: flex-start;
|
|
||||||
padding: 10px;
|
|
||||||
overflow: auto;
|
|
||||||
align-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-noready {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #cdcdcd69;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wait {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: calc(50% + 150px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.waitd {
|
|
||||||
position: absolute;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
left: 30px;
|
|
||||||
background-color: azure;
|
|
||||||
border-radius: 50%;
|
|
||||||
transform-origin: -15px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wait1 {
|
|
||||||
animation: dotAni1 2s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wait2 {
|
|
||||||
animation: dotAni2 2s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wait3 {
|
|
||||||
animation: dotAni3 2s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wait4 {
|
|
||||||
animation: dotAni4 2s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dotAni1 {
|
|
||||||
0% {
|
|
||||||
transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
20% {
|
|
||||||
transform: rotateZ(240deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
85% {
|
|
||||||
transform: rotateZ(290deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dotAni2 {
|
|
||||||
0% {
|
|
||||||
transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
35% {
|
|
||||||
transform: rotateZ(240deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
85% {
|
|
||||||
transform: rotateZ(290deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dotAni3 {
|
|
||||||
0% {
|
|
||||||
transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: rotateZ(240deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
85% {
|
|
||||||
transform: rotateZ(290deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dotAni4 {
|
|
||||||
0% {
|
|
||||||
transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
65% {
|
|
||||||
transform: rotateZ(240deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
85% {
|
|
||||||
transform: rotateZ(290deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@
|
||||||
"social": "Social Networking",
|
"social": "Social Networking",
|
||||||
"utilities": "Utilities",
|
"utilities": "Utilities",
|
||||||
"others": "Others",
|
"others": "Others",
|
||||||
"add":"Add"
|
"add":"Add",
|
||||||
|
"errorList":"Cannot get the list of applications"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +142,7 @@
|
||||||
"social": "社交",
|
"social": "社交",
|
||||||
"utilities": "实用工具",
|
"utilities": "实用工具",
|
||||||
"others": "其他",
|
"others": "其他",
|
||||||
"add":"添加应用"
|
"add":"添加应用",
|
||||||
|
"errorList":"获取列表失败!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,6 +26,12 @@ func OsStart() {
|
||||||
router.Use(loggingMiddleware{}.Middleware)
|
router.Use(loggingMiddleware{}.Middleware)
|
||||||
staticDir := libs.GetStaticDir()
|
staticDir := libs.GetStaticDir()
|
||||||
router.PathPrefix("/static").Handler(http.StripPrefix("/static", http.FileServer(http.Dir(staticDir))))
|
router.PathPrefix("/static").Handler(http.StripPrefix("/static", http.FileServer(http.Dir(staticDir))))
|
||||||
|
router.HandleFunc("/ping", progress.Ping).Methods(http.MethodGet)
|
||||||
|
if libs.PathExists("./dist") {
|
||||||
|
router.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("./dist"))))
|
||||||
|
} else {
|
||||||
|
router.HandleFunc("/", progress.Ping).Methods(http.MethodGet)
|
||||||
|
}
|
||||||
progressRouter := router.PathPrefix("/progress").Subrouter()
|
progressRouter := router.PathPrefix("/progress").Subrouter()
|
||||||
progressRouter.HandleFunc("/start/{name}", progress.StartProcess).Methods(http.MethodGet)
|
progressRouter.HandleFunc("/start/{name}", progress.StartProcess).Methods(http.MethodGet)
|
||||||
progressRouter.HandleFunc("/stop/{name}", progress.StopProcess).Methods(http.MethodGet)
|
progressRouter.HandleFunc("/stop/{name}", progress.StopProcess).Methods(http.MethodGet)
|
||||||
|
|
@ -37,8 +43,7 @@ func OsStart() {
|
||||||
progressRouter.HandleFunc("/killport", progress.KillPortHandler).Methods(http.MethodGet)
|
progressRouter.HandleFunc("/killport", progress.KillPortHandler).Methods(http.MethodGet)
|
||||||
progressRouter.HandleFunc("/app/{name}", progress.ForwardRequest).Methods(http.MethodGet, http.MethodPost)
|
progressRouter.HandleFunc("/app/{name}", progress.ForwardRequest).Methods(http.MethodGet, http.MethodPost)
|
||||||
progressRouter.HandleFunc("/app/{name}/{subpath:.*}", progress.ForwardRequest).Methods(http.MethodGet, http.MethodPost)
|
progressRouter.HandleFunc("/app/{name}/{subpath:.*}", progress.ForwardRequest).Methods(http.MethodGet, http.MethodPost)
|
||||||
router.HandleFunc("/ping", progress.Ping).Methods(http.MethodGet)
|
|
||||||
router.HandleFunc("/", progress.Ping).Methods(http.MethodGet)
|
|
||||||
router.HandleFunc("/system/updateInfo", sys.GetUpdateUrlHandler).Methods(http.MethodGet)
|
router.HandleFunc("/system/updateInfo", sys.GetUpdateUrlHandler).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/system/update", sys.UpdateAppHandler).Methods(http.MethodGet)
|
router.HandleFunc("/system/update", sys.UpdateAppHandler).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/system/storeList", sys.GetStoreInfoHandler).Methods(http.MethodGet)
|
router.HandleFunc("/system/storeList", sys.GetStoreInfoHandler).Methods(http.MethodGet)
|
||||||
|
|
|
||||||
1
main.go
1
main.go
|
|
@ -16,7 +16,6 @@ var assets embed.FS
|
||||||
func main() {
|
func main() {
|
||||||
// Create an instance of the app structure
|
// Create an instance of the app structure
|
||||||
app := App.NewApp()
|
app := App.NewApp()
|
||||||
|
|
||||||
// Create application with options
|
// Create application with options
|
||||||
err := wails.Run(&options.App{
|
err := wails.Run(&options.App{
|
||||||
Title: "GodoOS",
|
Title: "GodoOS",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue