Compare commits

..

110 Commits

Author SHA1 Message Date
奔跑的面条
b5738f5cf4 Merge branch 'dev' 2023-03-04 17:32:10 +08:00
奔跑的面条
dbd33cd676 perf: 优化顶部展示 2023-03-04 17:31:49 +08:00
奔跑的面条
032956e03b build: 升级版本到1.2.2 2023-03-04 17:06:28 +08:00
奔跑的面条
b94b44090b Merge branch 'dev' 2023-03-04 17:05:46 +08:00
奔跑的面条
19a382afe5 perf: 优化轮播组件 2023-03-04 17:05:07 +08:00
奔跑的面条
02fe552d1b !131 feat: 新增轮播图组件
Merge pull request !131 from Ryker/dev
2023-03-04 17:02:56 +08:00
奔跑的面条
22924eb36f !131 feat: 新增轮播图组件
Merge pull request !131 from Ryker/dev
2023-03-04 09:02:34 +00:00
奔跑的面条
a626f64e57 !133 解决adcode类型不正确可能导致的问题
Merge pull request !133 from wallellen/master-fetch-dev
2023-03-04 16:18:08 +08:00
奔跑的面条
00a4c752ed perf: 优化 JSONParse 过滤函数值表达式写法 2023-03-04 14:18:17 +08:00
奔跑的面条
134b44944e !132 fix: 动态请求中,body的json参数使用javasctipt
Merge pull request !132 from guo_ddt/master-fetch
2023-03-04 13:49:35 +08:00
奔跑的面条
1eb0485a86 perf: 优化编辑 JSON 交互功能 2023-03-03 22:25:36 +08:00
ryker
35e5374628 feat: 轮播图 2023-03-02 12:25:21 +08:00
奔跑的面条
432cceed2a docs: 优化说明文档 2023-02-28 20:16:50 +08:00
奔跑的面条
5b828d4982 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-28 12:00:26 +00:00
奔跑的面条
605fd14b3d build: 新增1.2.1版本 2023-02-27 18:59:59 +08:00
奔跑的面条
1b2b319467 Merge branch 'dev' 2023-02-27 18:59:18 +08:00
奔跑的面条
dc458ea88e fix: 解决删除颜色之后自动选择的错误 2023-02-27 13:06:27 +08:00
奔跑的面条
6f4e967b49 perf: 优化自定义颜色组件交互 2023-02-27 12:46:36 +08:00
奔跑的面条
97899f275a perf: 优化自定义颜色交互 2023-02-27 00:24:19 +08:00
奔跑的面条
8b6c616a15 perf: 处理渐变色和自定义色的交互 2023-02-26 23:34:40 +08:00
奔跑的面条
87386e69a3 feat: 对接全局颜色和自定义组件交互 2023-02-26 18:36:15 +08:00
奔跑的面条
196df94aee perf: 优化颜色组件展示 2023-02-26 13:08:22 +08:00
奔跑的面条
a407d118fa perf: 优化 UI 控件交互 2023-02-26 01:43:46 +08:00
奔跑的面条
0fc7bde348 perf: 优化数据 2023-02-25 23:44:03 +08:00
奔跑的面条
9a8899ae40 feat: 优化颜色选择器页面 2023-02-25 22:28:09 +08:00
奔跑的面条
8cb711b892 feat: 新增自定义颜色弹窗 2023-02-25 22:00:55 +08:00
奔跑的面条
49d8c35747 perf: 优化主题颜色UI 2023-02-24 21:42:27 +08:00
奔跑的面条
125856677a fix: 处理 deep 失效的问题 2023-02-24 21:34:15 +08:00
奔跑的面条
bcf0417624 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 10:22:05 +00:00
奔跑的面条
4b81a09293 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 10:16:27 +00:00
奔跑的面条
bcaffd1579 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 10:15:56 +00:00
奔跑的面条
7309d603f5 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 10:14:53 +00:00
奔跑的面条
ada4ce9885 docs: 修改文档 2023-02-18 17:48:32 +08:00
奔跑的面条
7758fb30d0 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 09:32:19 +00:00
奔跑的面条
6ddea30289 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-02-18 09:29:41 +00:00
奔跑的面条
ac42782f12 docs: 修改文档说明 2023-02-18 17:27:30 +08:00
奔跑的面条
4348688e34 docs: 修改文档 2023-02-18 17:27:01 +08:00
奔跑的面条
d447c85830 docs: 新增合作伙伴说明 2023-02-18 17:22:18 +08:00
奔跑的面条
0a3c1b3438 Merge branch 'dev' 2023-02-17 18:15:26 +08:00
奔跑的面条
b3bff2ee45 fix: 解决顶层无法写 await 的问题 2023-02-17 18:15:00 +08:00
奔跑的面条
d90e0953b9 build: 修改版本到1.2.0 2023-02-17 14:30:40 +08:00
奔跑的面条
ba04005b09 Merge branch 'dev' 2023-02-17 14:26:52 +08:00
奔跑的面条
fc58df2148 feat: 新增 public 预览配置项preview 2023-02-15 14:24:56 +08:00
奔跑的面条
4f2609a121 perf: 优化内存泄漏问题 2023-02-15 09:20:48 +08:00
奔跑的面条
f21c9f1246 perf: 优化 iframe 组件默认宽度 2023-02-14 21:12:30 +08:00
奔跑的面条
16d7ae8176 docs: 修改文档 2023-02-14 18:39:33 +08:00
奔跑的面条
0e77b196b6 docs: 修改群二维码 2023-02-14 18:29:47 +08:00
奔跑的面条
0ea81aeaee docs: 更换群二维码 2023-02-14 18:26:43 +08:00
奔跑的面条
d7aa41094b perf: 优化过滤器体验,提示错误内容 2023-02-09 11:29:23 +08:00
奔跑的面条
4ec1bbd912 fix: 解决预览序列化遗漏替换的位置 2023-02-08 16:38:38 +08:00
奔跑的面条
a7b98fe3d6 feat: 新增初始化函数,全局异步错误捕获功能 2023-02-02 20:54:02 +08:00
奔跑的面条
bc02950a6f !126 工作空间初始化,右侧页面配置内容被挤出
Merge pull request !126 from 且听风吟720/N/A
2023-02-02 09:45:29 +00:00
且听风吟720
4e5c921bf2 fix: 工作空间初始化,右侧页面配置内容被挤出
Signed-off-by: 且听风吟720 <shige720@qq.com>
2023-02-02 09:34:50 +00:00
奔跑的面条
14c5d935c4 !125 轮播列表配置界面增加轮播方式配置项
Merge pull request !125 from alucardpj/dev
2023-02-02 08:52:08 +00:00
pengjian
b73893a6af 轮播列表配置界面增加轮播方式配置项 2023-02-02 10:00:30 +08:00
奔跑的面条
cf85574c67 Merge remote-tracking branch 'origin/dev' 2023-01-17 15:35:25 +08:00
奔跑的面条
cec39d693a update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-01-17 03:12:32 +00:00
奔跑的面条
c250f9d4d8 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-01-17 03:10:59 +00:00
奔跑的面条
97ca3e8664 Merge branch 'dev' 2023-01-16 17:58:43 +08:00
奔跑的面条
01d971b902 build: 升级版本到 1.1.9 2023-01-13 16:52:10 +08:00
奔跑的面条
855d810d0d Merge branch 'dev' 2023-01-13 16:51:21 +08:00
奔跑的面条
bc10d06c78 !122 update src/packages/components/Decorates/Three/ThreeEarth01/index.vue.
Merge pull request !122 from CarnivalO/N/A
2023-01-12 06:32:55 +00:00
CarnivalO
fa2530634d update src/packages/components/Decorates/Three/ThreeEarth01/index.vue.
Edge浏览器不行 Edg应该也是<-1

Signed-off-by: CarnivalO <xmwjn@qq.com>
2023-01-12 05:54:12 +00:00
奔跑的面条
fb93d35c91 build: 修改版本号到1.1.8 2023-01-08 20:05:31 +08:00
奔跑的面条
fc2b1fc42e Merge branch 'dev' 2023-01-08 20:02:23 +08:00
奔跑的面条
8fd121a335 build: 修改版本号到1.1.7 2022-12-31 20:57:56 +08:00
奔跑的面条
d183c5815b build: 修改版本号到1.1.12 2022-12-31 20:53:29 +08:00
奔跑的面条
661f56e773 build: 1.1.12 2022-12-31 20:53:02 +08:00
奔跑的面条
f9c715c72c build: 升级版本到1.1.6 2022-12-16 14:01:47 +08:00
奔跑的面条
e2b3118d9d Merge branch 'dev' 2022-12-16 13:57:02 +08:00
奔跑的面条
f4c3a2b04f docs: 修改首页说明 2022-12-16 10:04:25 +08:00
奔跑的面条
31a8957de9 !106 docs: add Cloud IDE preview link
Merge pull request !106 from aresn/master
2022-12-16 01:49:34 +00:00
奔跑的面条
46f20f61b5 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-12-09 08:11:47 +00:00
aresn
dba5ab3ef3 update README.md.
Signed-off-by: aresn <admin@aresn.com>
2022-12-07 09:51:33 +00:00
aresn
2251bebee6 add preview.yml.
Signed-off-by: aresn <admin@aresn.com>
2022-12-07 09:49:48 +00:00
奔跑的面条
3ac9ffc73c Merge branch 'dev' 2022-11-22 12:44:51 +08:00
奔跑的面条
c420ae467f Merge branch 'dev' 2022-11-21 10:49:25 +08:00
奔跑的面条
8334fe5bcc build: 升级版本到 1.1.5 2022-11-19 21:04:53 +08:00
奔跑的面条
f99edce6f4 Merge branch 'dev' 2022-11-19 21:04:32 +08:00
奔跑的面条
f47acca703 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-11-10 10:13:19 +00:00
奔跑的面条
73a6c6b920 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-11-10 10:10:58 +00:00
奔跑的面条
672f7a0a7c Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-11-05 21:46:26 +08:00
奔跑的面条
de78fb2149 docs: 新增文档截图 2022-11-05 18:19:33 +08:00
奔跑的面条
4a59e69bbe docs: 修改首页地址 2022-11-02 19:46:19 +08:00
奔跑的面条
a442e13a7b feat: 升级版本到1.1.4 2022-11-02 19:05:16 +08:00
奔跑的面条
4d093a4a80 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-11-02 19:02:38 +08:00
奔跑的面条
7e59d8d36c docs: 修改链接地址 2022-11-02 09:57:28 +08:00
奔跑的面条
8241077495 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-10-29 12:09:36 +00:00
奔跑的面条
82b29a2f8b docs: 优化说明文档 2022-10-29 19:57:02 +08:00
奔跑的面条
b789d80f98 fix: 修改主页说明 2022-10-29 19:51:33 +08:00
奔跑的面条
a8c80e2366 docs: 修改主页说明 2022-10-29 19:50:30 +08:00
奔跑的面条
bdbdd37789 build: 升级版本到1.1.3 2022-10-15 17:17:34 +08:00
奔跑的面条
c8fb5b9152 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-15 17:12:13 +08:00
奔跑的面条
aef155e039 fix: 修复组件导入数据错乱的问题 2022-10-09 16:37:30 +08:00
奔跑的面条
443573455b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-09 09:28:38 +08:00
奔跑的面条
d811ab7dfa build: 撤回错误版本号 2022-10-08 21:12:58 +08:00
奔跑的面条
5f79ab6e6d build: 升级版本到1.1.2 2022-10-08 21:12:27 +08:00
奔跑的面条
502edbca5d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 21:05:48 +08:00
奔跑的面条
1a04267cb7 build: 升级版本到1.1.1 2022-10-08 20:59:55 +08:00
奔跑的面条
9c2c1bdfa1 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 20:59:25 +08:00
奔跑的面条
72e93f3768 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-27 20:16:07 +08:00
奔跑的面条
e6f2066d42 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-22 14:15:00 +08:00
奔跑的面条
2812c39524 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-21 19:54:29 +08:00
奔跑的面条
491485856e Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:46:37 +08:00
奔跑的面条
abde7e176d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:13:50 +08:00
奔跑的面条
bab8faadee add default pipeline template yaml 2022-09-19 11:58:32 +00:00
奔跑的面条
427d72fb8b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:48:28 +08:00
奔跑的面条
dc5b20a329 build: 升级版本到1.1.0 2022-09-18 16:33:26 +08:00
奔跑的面条
4cb934eef3 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:32:34 +08:00
奔跑的面条
35e8cea0b5 docs: 更新已完成图表说明 2022-09-17 23:00:51 +08:00
162 changed files with 2570 additions and 2077 deletions

12
.env
View File

@@ -1,8 +1,14 @@
# port
VITE_DEV_PORT = '8080'
VITE_DEV_PORT = '8001'
# development path
VITE_DEV_PATH = 'https://demo.mtruning.club'
VITE_DEV_PATH = '/'
# production path
VITE_PRO_PATH = 'https://demo.mtruning.club'
VITE_PRO_PATH = '/'
# spa-title
VITE_GLOB_APP_TITLE = GoView
# spa shortname
VITE_GLOB_APP_SHORT_NAME = GoView

216
README.md
View File

@@ -1,119 +1,157 @@
## 总览
#### 总览
<p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
**`master-fetch` 分支是带有后端接口请求的分支**
<h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
#### 长期赞助商
<div>
<div align="center" style="column-gap: 20px;">
<a
href="http://www.ccflow.org/?from=goviewGitee"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/ccflow-banner.png" alt="go-view" style="width: 250px;" width="250px" />
</a>
<span> &nbsp;</span>
<a
href="https://www.qeasy.cloud/"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/qyy-banner.png" alt="go-view" style="width: 250px;" width="250px"/>
</a>
</div>
</div>
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)**
#### 😶 **纯前端** 分支: **`master`**
## 使用
#### 👻 携带 **后端** 请求分支: **`master-fetch`**
所有的接口地址位置:`src\api\path\*`
#### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
接口地址修改:`.env`
项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
```shell
# port
VITE_DEV_PORT = '8080'
项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
# development path
VITE_DEV_PATH = 'http://127.0.0.1:8080'
Cloud IDE 代码在线预览地址:[https://idegitee.com/dromara/go-view](https://idegitee.com/dromara/go-view)
# production path
VITE_PRO_PATH = 'http://127.0.0.1:8080'
```
#### 🤯 后端项目看这里!
公共前缀修改:`src\settings\httpSetting.ts`
后端项目 gitee 地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
```shell
// 请求前缀
export const axiosPre = '/api/goview'
```
接口说明地址:[https://docs.apipost.cn/...](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)
接口封装:`src\api\http.ts`
其它后端方案地址:
```ts
import axiosInstance from './axios'
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
- 【.NET】[https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
export const get = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.GET,
params: params,
})
}
#### 整体介绍
export const post = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.POST,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
export const put = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.PUT,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
export const del = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.DELETE,
params
})
}
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
// 获取请求函数默认get
export const http = (type?: RequestHttpEnum) => {
switch (type) {
case RequestHttpEnum.GET:
return get
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
case RequestHttpEnum.POST:
return post
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
case RequestHttpEnum.PUT:
return put
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
case RequestHttpEnum.DELETE:
return del
说明文档:
![说明文档](readme/go-view-doc.png)
default:
return get
}
}
工作台:
![工作台](readme/go-view-canvas.png)
```
请求配置:
![请求配置](readme/go-view-fetch.png)
数据过滤:
![数据过滤](readme/go-view-filter.png)
高级事件编辑:
![高级事件编辑](readme/go-view-event.png)
自定义组件颜色:
![高级事件编辑](readme/go-view-echarts-color.png)
快捷主页:
![快捷主页](readme/go-view-indexpage.png)
主题色:
![主题色](readme/go-view-color.png)
亮白主题:
![亮白主题](readme/go-view-theme.png)
主要技术栈为:
| 名称 | 版本 | 名称 | 版本 |
| ------------------- | ----- | ----------- | ------ |
| Vue | 3.2.x | TypeScript4 | 4.6.x |
| Vite | 2.9.x | NaiveUI | 2.27.x |
| ECharts | 5.3.x | Pinia | 2.0.x |
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
开发环境:
| 名称 | 版本 | 名称 | 版本 |
| ---- | ------- | ------- | ----- |
| node | 16.14.x | npm | 8.5.x |
| pnpm | 7.1.x | windows | 11 |
已完成图表:
| 分类 | 名称 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------- | -------------- | ------------------------ |
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
| \* | 漏斗图 | 中国地图 | 高德地图 | 🦊 |
| 信息 | 文字 | 渐变文字 | 词云 | 嵌套网页 |
| \* | 图片 | 视频 | 😺 | 🐯 |
| 列表 | 滚动排名列表 | 滚动表格 | 🐮 | 🐐 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 |
## 浏览器支持
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
## 安装
请查看文档:[https://www.mtruning.club/](https://www.mtruning.club/)
## 代码提交
* feat: 新功能
* fix: 修复 Bug
* docs: 文档修改
* perf: 性能优化
* revert: 版本回退
* ci: CICD集成相关
* test: 添加测试代码
* refactor: 代码重构
* build: 影响项目构建或依赖修改
* style: 不影响程序逻辑的代码修改
* chore: 不属于以上类型的其他类型(日常事务)
- feat: 新功能
- fix: 修复 Bug
- docs: 文档修改
- perf: 性能优化
- revert: 版本回退
- ci: CICD 集成相关
- test: 添加测试代码
- refactor: 代码重构
- build: 影响项目构建或依赖修改
- style: 不影响程序逻辑的代码修改
- chore: 不属于以上类型的其他类型(日常事务)
## 交流
## 交流
QQ 群:1030129384
![QQ群](readme/go-view-qq.png)
QQ 群:663629294
<img width="260px" src="readme/go-view-qq.png" alt="QQ群" style="border-radius: 20px" />
![渲染海报](readme/logo-poster.png)

View File

@@ -0,0 +1,9 @@
/**
* Get the configuration file variable name
* @param env
*/
export const getConfigFileName = (env: Record<string, any>) => {
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
.toUpperCase()
.replace(/\s/g, '');
};

View File

@@ -1,8 +1,8 @@
{
"name": "go-view",
"version": "2.1.6",
"version": "1.2.2",
"engines": {
"node": ">=16.14 <18.0.0"
"node": ">=12.0"
},
"scripts": {
"dev": "vite --host",

10
preview.yml Normal file
View File

@@ -0,0 +1,10 @@
# preview.yml
autoOpen: true # 打开工作空间时是否自动开启所有应用的预览
apps:
- port: 3000 # 应用的端口
run: npm i --registry=https://registry.npmmirror.com && npm run dev # 应用的启动命令
command: # 使用此命令启动服务且不执行run
root: ./ # 应用的启动目录
name: GoView # 应用名称
description: 开源、精美、便捷的「数据可视化」低代码开发平台 # 应用描述
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen)

BIN
readme/go-view-doc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 70 KiB

BIN
readme/go-view-theme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -17,7 +17,7 @@
import { NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
// 暗黑主题
const darkTheme = useDarkThemeHook()
@@ -28,9 +28,6 @@ const overridesTheme = useThemeOverridesHook()
// 代码主题
const hljsTheme = useCode()
// 系统全局数据初始化
useSystemInit()
// 全局语言
const { locale, dateLocale } = useLang()

View File

@@ -1,14 +0,0 @@
import { ModuleTypeEnum } from '@/enums/httpEnum'
// 接口白名单(免登录)
export const fetchAllowList = [
// 登录
`${ModuleTypeEnum.SYSTEM}/login`,
// 获取 OSS 接口
`${ModuleTypeEnum.SYSTEM}/getOssInfo`,
// 预览获取数据
`${ModuleTypeEnum.PROJECT}/getData`,
]
// 接口黑名单
export const fetchBlockList = []

View File

@@ -1,82 +1,30 @@
import axios, { AxiosResponse, AxiosRequestConfig, Axios } from 'axios'
import { ResultEnum, ModuleTypeEnum } from "@/enums/httpEnum"
import { PageEnum, ErrorPageNameMap } from "@/enums/pageEnum"
import { StorageEnum } from '@/enums/storageEnum'
import { axiosPre } from '@/settings/httpSetting'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
import { fetchAllowList } from './axios.config'
import includes from 'lodash/includes'
export interface MyResponseType<T> {
code: ResultEnum
data: T
message: string
}
export interface MyRequestInstance extends Axios {
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
}
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios'
import { ResultEnum } from "@/enums/httpEnum"
import { ErrorPageNameMap } from "@/enums/pageEnum"
import { redirectErrorPage } from '@/utils'
const axiosInstance = axios.create({
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
baseURL: import.meta.env.DEV ? import.meta.env.VITE_DEV_PATH : import.meta.env.VITE_PRO_PATH,
timeout: ResultEnum.TIMEOUT,
}) as unknown as MyRequestInstance
})
axiosInstance.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 白名单校验
if (includes(fetchAllowList, config.url)) return config
// 获取 token
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
// 重新登录
if (!info) {
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return config
}
const userInfo = info[SystemStoreEnum.USER_INFO]
config.headers = {
...config.headers,
[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
}
return config
},
(err: AxiosRequestConfig) => {
Promise.reject(err)
(error: AxiosRequestConfig) => {
Promise.reject(error)
}
)
// 响应拦截器
axiosInstance.interceptors.response.use(
(res: AxiosResponse) => {
// 预览页面错误不进行处理
if (isPreview()) {
return Promise.resolve(res.data)
}
const { code } = res.data as { code: number }
if (code === undefined || code === null) return Promise.resolve(res)
// 成功
if (code === ResultEnum.SUCCESS) {
return Promise.resolve(res.data)
}
// 登录过期
if (code === ResultEnum.TOKEN_OVERDUE) {
window['$message'].error(window['$t']('http.token_overdue_message'))
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return Promise.resolve(res.data)
}
// 固定错误码重定向
if (ErrorPageNameMap.get(code)) {
redirectErrorPage(code)
return Promise.resolve(res.data)
}
// 提示错误
window['$message'].error(window['$t']((res.data as any).msg))
if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
// 重定向
if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
return Promise.resolve(res.data)
},
(err: AxiosResponse) => {

View File

@@ -9,16 +9,16 @@ import {
} from '@/enums/httpEnum'
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
export const get = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
export const get = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.GET,
params: params,
params: params
})
}
export const post = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
export const post = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.POST,
data: data,
@@ -28,8 +28,8 @@ export const post = <T = any>(url: string, data?: object, headersType?: string)
})
}
export const patch = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
export const patch = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.PATCH,
data: data,
@@ -39,8 +39,8 @@ export const patch = <T = any>(url: string, data?: object, headersType?: string)
})
}
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance<T>({
export const put = (url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.PUT,
data: data,
@@ -50,8 +50,8 @@ export const put = <T = any>(url: string, data?: object, headersType?: ContentTy
})
}
export const del = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
export const del = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.DELETE,
params
@@ -82,11 +82,11 @@ export const http = (type?: RequestHttpEnum) => {
}
const prefix = 'javascript:'
// 对输入字符进行转义处理
export const translateStr = (target: string | Record<any, any>) => {
export const translateStr = (target: string | object) => {
if (typeof target === 'string') {
if (target.startsWith(prefix)) {
const funcStr = target.split(prefix)[1]
let result
let result;
try {
result = new Function(`${funcStr}`)()
} catch (error) {
@@ -100,8 +100,8 @@ export const translateStr = (target: string | Record<any, any>) => {
}
for (const key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
const subTarget = target[key]
target[key] = translateStr(subTarget)
const subTarget = (target as any)[key];
(target as any)[key] = translateStr(subTarget)
}
}
return target
@@ -172,7 +172,9 @@ export const customizeHttp = (targetParams: RequestConfigType, globalParams: Req
case RequestBodyEnum.JSON:
headers['Content-Type'] = ContentTypeEnum.JSON
data = translateStr(JSON.parse(targetRequestParams.Body['json']))
//json对象也能使用'javasctipt:'来动态拼接参数
data = translateStr(targetRequestParams.Body['json'])
if(typeof data === 'string') data = JSON.parse(data)
// json 赋值给 data
break

View File

@@ -1,2 +0,0 @@
export * from '@/api/path/project.api'
export * from '@/api/path/system.api'

View File

@@ -1,98 +0,0 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { ProjectItem, ProjectDetail } from './project'
// * 项目列表
export const projectListApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 新增项目
export const createProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<{
/**
* 项目id
*/
id: number
}>(`${ModuleTypeEnum.PROJECT}/create`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 获取项目
export const fetchProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<ProjectDetail>(`${ModuleTypeEnum.PROJECT}/getData`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 保存项目
export const saveProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(
`${ModuleTypeEnum.PROJECT}/save/data`,
data,
ContentTypeEnum.FORM_URLENCODED
)
return res
} catch {
httpErrorHandle()
}
}
// * 修改项目基础信息
export const updateProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 删除项目
export const deleteProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.DELETE)(`${ModuleTypeEnum.PROJECT}/delete`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 修改发布状态 [-1未发布,1发布]
export const changeProjectReleaseApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/publish`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 上传文件
export const uploadFile = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<{
/**
* 文件地址
*/
fileName: string
}>(`${ModuleTypeEnum.PROJECT}/upload`, data, ContentTypeEnum.FORM_DATA)
return res
} catch {
httpErrorHandle()
}
}

View File

@@ -1,39 +0,0 @@
export type ProjectItem = {
/**
* 项目 id
*/
id: string
/**
* 项目名称
*/
projectName: string
/**
* 项目状态:\
* -1: 未发布\
* 1: 已发布
*/
state: number
/**
* 创建时间
*/
createTime: string
/**
* 预览图片url
*/
indexImage: string
/**
* 创建者 id
*/
createUserId: string
/**
* 项目备注
*/
remarks: string
}
export interface ProjectDetail extends ProjectItem {
/**
* 项目参数
*/
content: string
}

View File

@@ -1,39 +0,0 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { LoginResult } from './system'
// * 登录
export const loginApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<LoginResult>(`${ModuleTypeEnum.SYSTEM}/login`, data)
return res
} catch (err) {
httpErrorHandle()
}
}
// * 登出
export const logoutApi = async () => {
try {
const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.SYSTEM}/logout`)
return res
} catch (err) {
httpErrorHandle()
}
}
// * 获取 oss 上传接口
export const ossUrlApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<{
/**
* bucket 地址
*/
bucketURL?: string
}>(`${ModuleTypeEnum.SYSTEM}/getOssInfo`, data)
return res
} catch (err) {
httpErrorHandle()
}
}

View File

@@ -1,26 +0,0 @@
export interface LoginResult {
token: {
/**
* token 值
*/
tokenValue: string
/**
* token key
*/
tokenName: string
}
userinfo: {
/**
* 昵称
*/
nickname: string
/**
* 用户名
*/
username: string
/**
* 用户 id
*/
id: string
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -27,9 +27,7 @@
<script lang="ts" setup>
import { h, ref } from 'vue'
import { NAvatar, NText } from 'naive-ui'
import { renderIcon, getLocalStorage } from '@/utils'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { StorageEnum } from '@/enums/storageEnum'
import { renderIcon } from '@/utils'
import { logout, renderLang } from '@/utils'
import { GoSystemSet } from '@/components/GoSystemSet/index'
import { GoSystemInfo } from '@/components/GoSystemInfo/index'
@@ -66,17 +64,7 @@ const renderUserInfo = () => {
}),
h('div', null, [
h('div', null, [
h(NText, { depth: 2 }, {
default: () => {
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
if (info) {
return info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_NAME];
}
else {
return 'admin';
}
}
})
h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
])
])
]
@@ -149,4 +137,4 @@ const handleSelect = (key: string) => {
cursor: pointer;
transform: scale(0.7);
}
</style>
</style>

View File

@@ -12,7 +12,8 @@ export enum DragKeyEnum {
// 不同页面保存操作
export enum SavePageEnum {
CHART = 'SaveChart',
JSON = 'SaveJSON'
JSON = 'SaveJSON',
CLOSE = 'close'
}
// 操作枚举
@@ -46,6 +47,7 @@ export enum MenuEnum {
UN_GROUP = 'unGroup',
// 后退
BACK = 'back',
// 前进
FORWORD = 'forward',
// 保存
SAVE = 'save',
@@ -81,15 +83,3 @@ export enum MacKeyboard {
ALT_SOURCE_KEY = '⌥',
SPACE = 'Space'
}
// 同步状态枚举
export enum SyncEnum {
// 等待
PENDING,
// 开始
START,
// 成功
SUCCESS,
// 失败
FAILURE
}

View File

@@ -7,15 +7,15 @@ export enum BaseEvent {
// 移入
ON_MOUSE_ENTER = 'mouseenter',
// 移出
ON_MOUSE_LEAVE = 'mouseleave',
ON_MOUSE_LEAVE = 'mouseleave'
}
// vue3 生命周期事件
export enum EventLife {
export enum EventLife {
// 渲染之后
VNODE_MOUNTED = 'vnodeMounted',
// 渲染之前
VNODE_BEFORE_MOUNT = 'vnodeBeforeMount',
VNODE_BEFORE_MOUNT = 'vnodeBeforeMount'
}
// 内置字符串函数对象列表
@@ -28,4 +28,9 @@ export const excludeParseEventKeyList = [
BaseEvent.ON_MOUSE_LEAVE,
//过滤器
'filter'
]
]
// 内置字符串函数键值列表
export const excludeParseEventValueList = [
// 请求里的函数语句
'javascript:'
]

View File

@@ -1,18 +1,13 @@
// 模块 Path 前缀分类
export enum ModuleTypeEnum {
SYSTEM = 'sys',
PROJECT = 'project',
}
// 请求结果集
/**
* @description: 请求结果集
*/
export enum ResultEnum {
DATA_SUCCESS = 0,
SUCCESS = 200,
SERVER_ERROR = 500,
SERVER_FORBIDDEN = 403,
NOT_FOUND = 404,
TOKEN_OVERDUE = 886,
TIMEOUT = 60000,
TIMEOUT = 60000
}
// 数据相关
@@ -33,13 +28,9 @@ export enum RequestContentTypeEnum {
SQL = 1
}
// 头部
export enum RequestHttpHeaderEnum {
TOKEN = 'Token',
COOKIE = 'Cookie'
}
// 请求方法
/**
* @description: 请求方法
*/
export enum RequestHttpEnum {
GET = 'get',
POST = 'post',
@@ -120,7 +111,9 @@ export type RequestParams = {
}
}
// 常用的contentTyp类型
/**
* @description: 常用的contentTyp类型
*/
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',

View File

@@ -26,15 +26,10 @@ export enum PageEnum {
//重定向
REDIRECT = '/redirect',
REDIRECT_NAME = 'Redirect',
// 未发布
REDIRECT_UN_PUBLISH = '/redirect/unPublish',
REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
// 重载
RELOAD = '/reload',
RELOAD_NAME = 'Reload',
// 首页
BASE_HOME = '/project',
BASE_HOME_NAME = 'Project',

View File

@@ -1,8 +1,10 @@
export enum StorageEnum {
// 全局设置
GO_SETTING_STORE = 'GO_SETTING',
GO_SYSTEM_SETTING_STORE = 'GO_SYSTEM_SETTING',
// token 等信息
GO_ACCESS_TOKEN_STORE = 'GO_ACCESS_TOKEN',
// 登录信息
GO_SYSTEM_STORE = 'GO_SYSTEM',
GO_LOGIN_INFO_STORE = 'GO_LOGIN_INFO',
// 语言
GO_LANG_STORE = 'GO_LANG',
// 当前选择的主题

View File

@@ -2,7 +2,6 @@ export * from '@/hooks/useTheme.hook'
export * from '@/hooks/usePreviewScale.hook'
export * from '@/hooks/useCode.hook'
export * from '@/hooks/useChartDataFetch.hook'
export * from '@/hooks/useSystemInit.hook'
export * from '@/hooks/useChartDataPondFetch.hook'
export * from '@/hooks/useLifeHandler.hook'
export * from '@/hooks/useLang.hook'

View File

@@ -6,6 +6,7 @@ import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestDataTypeEnum } from '@/enums/httpEnum'
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
import { setOption } from '@/packages/public/chart'
// 获取类型
type ChartEditStoreType = typeof useChartEditStore
@@ -34,7 +35,7 @@ export const useChartDataFetch = (
const echartsUpdateHandle = (dataset: any) => {
if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) {
vChartRef.value.setOption({ dataset: dataset })
setOption(vChartRef.value, { dataset: dataset })
}
}
}

View File

@@ -1,23 +0,0 @@
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
import { SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d'
import { ResultEnum } from '@/enums/httpEnum'
import { ossUrlApi } from '@/api/path'
// * 初始化
export const useSystemInit = async () => {
const systemStore = useSystemStore()
// 获取 OSS 信息的 url 地址,用来拼接展示图片的地址
const getOssUrl = async () => {
const res = await ossUrlApi({})
if (res && res.code === ResultEnum.SUCCESS) {
systemStore.setItem(SystemStoreEnum.FETCH_INFO, {
OSSUrl: res.data?.bucketURL
})
}
}
// 执行
getOssUrl()
}

View File

@@ -11,8 +11,6 @@ const global = {
help: 'Help',
contact: 'About Software',
logout: 'Logout',
logout_success: 'Logout success',
logout_failure: 'Logout Failed',
// system setting
sys_set: 'System Setting',
lang_set: 'Language Setting',
@@ -28,14 +26,8 @@ const global = {
r_more: 'More',
}
const http = {
error_message: 'The interface is abnormal, please check the interface!',
token_overdue_message: 'Login expired, please log in again!'
}
export default {
global,
http,
login,
project
}

View File

@@ -2,6 +2,6 @@ export default {
desc: "Login",
form_auto: "Sign in automatically",
form_button: "Login",
login_success: "Login success!",
login_message: "Please complete the letter!",
login_success: "Login success",
login_message: "Please complete the letter",
}

View File

@@ -1,8 +1,6 @@
export default {
create_btn: 'Creat',
create_success: 'Creat Success!',
create_failure: 'Failed to create, please try again later',
create_tip: 'Please select a content for development!',
create_tip: 'Please select a content for development',
project: 'Project',
my: 'My',
new_project: 'New Project',

View File

@@ -11,8 +11,6 @@ const global = {
help: '帮助中心',
contact: '关于软件',
logout: '退出登录',
logout_success: '退出成功!',
logout_failure: '退出失败!',
// 系统设置
sys_set: '系统设置',
lang_set: '语言设置',
@@ -20,27 +18,16 @@ const global = {
r_edit: '编辑',
r_preview: '预览',
r_copy: '克隆',
r_copy_success: '克隆成功!',
r_rename: '重命名',
r_rename_success: '重命名成功!',
r_publish: '发布',
r_publish_success: '成功发布!',
r_unpublish: '取消发布',
r_unpublish_success: '取消成功!',
r_download: '下载',
r_delete: '删除',
r_delete_success: '删除成功!',
r_more: '更多',
}
const http = {
error_message: '获取数据失败,请稍后重试!',
token_overdue_message: '登录过期,请重新登录!'
}
export default {
global,
http,
login,
project
}

View File

@@ -2,6 +2,6 @@ export default {
desc: "登录",
form_auto: "自动登录",
form_button: "登录",
login_success: "登录成功",
login_message: "请填写完整信息",
login_success: "登录成功!",
}

View File

@@ -1,8 +1,6 @@
export default {
// aside
create_btn: '新建',
create_success: '新建成功!',
create_failure: '新建失败,请稍后重试!',
create_tip: '从哪里出发好呢?',
project: '项目',
my: '我的',

View File

@@ -1,6 +1,6 @@
<template>
<n-layout-header bordered class="go-header">
<header class="go-header-box">
<header class="go-header-box" :class="{ 'is-project': isProject }">
<div class="header-item left">
<n-space>
<slot name="left"></slot>
@@ -23,17 +23,29 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { GoThemeSelect } from '@/components/GoThemeSelect'
import { GoLangSelect } from '@/components/GoLangSelect'
import { ThemeColorSelect } from '@/components/Pages/ThemeColorSelect'
import { PageEnum } from '@/enums/pageEnum'
const route = useRoute()
const isProject = computed(() => {
return route.fullPath === PageEnum.BASE_HOME_ITEMS
})
</script>
<style lang="scss" scoped>
$min-width: 400px;
$min-width: 520px;
@include go(header) {
&-box {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-columns: repeat(3, 33%);
&.is-project {
grid-template-columns: none;
}
.header-item {
display: flex;
align-items: center;
@@ -49,7 +61,7 @@ $min-width: 400px;
}
}
height: $--header-height;
padding: 0 60px;
padding: 0 20px 0 60px;
}
}
</style>

View File

@@ -3,7 +3,7 @@ import App from './App.vue'
import router, { setupRouter } from '@/router'
import i18n from '@/i18n/index'
import { setupStore } from '@/store'
import { setupNaive, setupDirectives, setupCustomComponents } from '@/plugins'
import { setupNaive, setupDirectives, setupCustomComponents, initFunction } from '@/plugins'
import { GoAppProvider } from '@/components/GoAppProvider/index'
import { setHtmlTheme } from '@/utils'
@@ -53,4 +53,7 @@ async function appInit() {
window['$vue'] = app
}
void appInit()
appInit().then(() => {
initFunction()
})

View File

@@ -122,23 +122,28 @@ const calcData = (data: any, type?: string) => {
// 数据解析
const calcCapsuleLengthAndLabelData = (dataset: any) => {
const { source } = dataset
if (!source.length) return
try {
const { source } = dataset
if (!source || !source.length) return
state.capsuleItemHeight = numberSizeHandle(state.mergedConfig.itemHeight)
const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])
state.capsuleItemHeight = numberSizeHandle(state.mergedConfig.itemHeight)
const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])
const maxValue = Math.max(...capsuleValue)
const maxValue = Math.max(...capsuleValue)
state.capsuleValue = capsuleValue
state.capsuleValue = capsuleValue
state.capsuleLength = capsuleValue.map((v: any) => (maxValue ? v / maxValue : 0))
state.capsuleLength = capsuleValue.map((v: any) => (maxValue ? v / maxValue : 0))
const oneFifth = maxValue / 5
const oneFifth = maxValue / 5
const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))
const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))
state.labelData = labelData
state.labelData = labelData
} catch (error) {
console.warn(error);
}
}
const numberSizeHandle = (val: string | number) => {

View File

@@ -1,7 +1,6 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { LineCommonConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'

View File

@@ -15,7 +15,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import { useChartDataFetch } from '@/hooks'
import { isPreview } from '@/utils'
import { isPreview, colorGradientCustomMerge} from '@/utils'
const props = defineProps({
themeSetting: {
@@ -45,7 +45,9 @@ watch(
(newColor: keyof typeof chartColorsSearch) => {
try {
if (!isPreview()) {
const themeColor = chartColorsSearch[newColor] || chartColorsSearch[defaultTheme]
const themeColor =
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] ||
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
props.chartConfig.option.series.forEach((value: any, index: number) => {
value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{

View File

@@ -14,7 +14,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import { useChartDataFetch } from '@/hooks'
import { isPreview } from '@/utils'
import { isPreview, colorGradientCustomMerge} from '@/utils'
const props = defineProps({
themeSetting: {
@@ -44,7 +44,9 @@ watch(
(newColor: keyof typeof chartColorsSearch) => {
try {
if (!isPreview()) {
const themeColor = chartColorsSearch[newColor] || chartColorsSearch[defaultTheme]
const themeColor =
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] ||
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
props.chartConfig.option.series.forEach((value: any, index: number) => {
value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{

View File

@@ -15,7 +15,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import { useChartDataFetch } from '@/hooks'
import { isPreview } from '@/utils'
import { isPreview, colorGradientCustomMerge } from '@/utils'
const props = defineProps({
themeSetting: {
@@ -45,7 +45,9 @@ watch(
(newColor: keyof typeof chartColorsSearch) => {
try {
if (!isPreview()) {
const themeColor = chartColorsSearch[newColor] || chartColorsSearch[defaultTheme]
const themeColor =
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] ||
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
props.chartConfig.option.series.forEach((value: any) => {
value.lineStyle.shadowColor = themeColor[2]
value.lineStyle.color.colorStops.forEach((v: { color: string }, i: number) => {

View File

@@ -11,7 +11,7 @@ import { use, registerMap } from 'echarts/core'
import { EffectScatterChart, MapChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'
import { useChartDataFetch } from '@/hooks'
import { mergeTheme } from '@/packages/public/chart'
import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json'
@@ -59,13 +59,14 @@ const getGeojson = (regionId: string) => {
}
//异步时先注册空的 保证初始化不报错
registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
registerMap(`${props.chartConfig.option.mapRegion.adcode}`, { geoJSON: {} as any, specialAreas: {} })
// 进行更换初始化地图 如果为china 单独处理
const registerMapInitAsync = async () => {
await nextTick()
if (props.chartConfig.option.mapRegion.adcode != 'china') {
await getGeojson(props.chartConfig.option.mapRegion.adcode)
const adCode = `${props.chartConfig.option.mapRegion.adcode}`;
if (adCode !== 'china') {
await getGeojson(adCode)
} else {
await hainanLandsHandle(props.chartConfig.option.mapRegion.showHainanIsLands)
}
@@ -76,7 +77,7 @@ registerMapInitAsync()
// 手动触发渲染
const vEchartsSetOption = () => {
option.value = props.chartConfig.option
vChartRef.value?.setOption(props.chartConfig.option)
setOption(vChartRef.value, props.chartConfig.option)
}
// 更新数据处理
@@ -127,7 +128,7 @@ watch(
//监听地图展示区域发生变化
watch(
() => props.chartConfig.option.mapRegion.adcode,
() => `${props.chartConfig.option.mapRegion.adcode}`,
async newData => {
try {
await getGeojson(newData)

View File

@@ -10,7 +10,7 @@ import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { HeatmapChart } from 'echarts/charts'
import { includes } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -68,7 +68,7 @@ const dataSetHandle = (dataset: typeof dataJson) => {
props.chartConfig.option.series[0].data = seriesData
}
if (vChartRef.value && isPreview()) {
vChartRef.value.setOption(props.chartConfig.option)
setOption(vChartRef.value, props.chartConfig.option)
}
}

View File

@@ -10,7 +10,7 @@ import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { RadarChart } from 'echarts/charts'
import { includes } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -50,7 +50,7 @@ const dataSetHandle = (dataset: typeof dataJson) => {
props.chartConfig.option.radar.indicator = dataset.radarIndicator
}
if (vChartRef.value && isPreview()) {
vChartRef.value.setOption(props.chartConfig.option)
setOption(vChartRef.value, props.chartConfig.option)
}
}

View File

@@ -10,7 +10,7 @@ import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { TreemapChart } from 'echarts/charts'
import { includes } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -42,7 +42,7 @@ const option = computed(() => {
const dataSetHandle = (dataset: typeof dataJson) => {
if (dataset) {
props.chartConfig.option.series[0].data = dataset
vChartRef.value?.setOption(props.chartConfig.option)
setOption(vChartRef.value, props.chartConfig.option)
}
}

View File

@@ -10,7 +10,7 @@ import 'echarts-liquidfill/src/liquidFill.js'
import { CanvasRenderer } from 'echarts/renderers'
import { GridComponent } from 'echarts/components'
import config from './config'
import { isPreview, isString, isNumber } from '@/utils'
import { isPreview, isString, isNumber, colorGradientCustomMerge } from '@/utils'
import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartDataFetch } from '@/hooks'
@@ -44,7 +44,9 @@ watch(
(newColor: keyof typeof chartColorsSearch) => {
try {
if (!isPreview()) {
const themeColor = chartColorsSearch[newColor] || chartColorsSearch[defaultTheme]
const themeColor =
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] ||
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
// 背景颜色
props.chartConfig.option.series[0].backgroundStyle.color = themeColor[2]
// 水球颜色

View File

@@ -0,0 +1,47 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { CarouselConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import logo from '@/assets/logo.png'
// 示例图片资源
const modules = import.meta.globEager("./images/*");
const dataset = [logo]
for (var item in modules) {
dataset.push(modules[item].default)
}
export const option = {
// 图片资源列表
dataset: dataset,
// 自动播放
autoplay: true,
// 自动播放的间隔ms
interval: 5000,
// 每页显示的图片数量
slidesPerview: 1,
// 轮播方向
direction: "horizontal",
// 拖曳切换
draggable: true,
// 居中显示
centeredSlides: false,
// 过渡效果
effect: "slide",
// 是否显示指示点
showDots: true,
// 指示器样式
dotType: "dot",
// 指示器位置
dotPlacement: "bottom",
// 显示箭头
showArrow: false,
// 图片样式
fit: "contain",
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = CarouselConfig.key
public chartConfig = cloneDeep(CarouselConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,176 @@
<template>
<collapse-item name="属性" :expanded="true">
<setting-item-box name="路径" :alone="true">
<setting-item v-for="item, index in optionData.dataset" :key="index">
<n-input-group>
<n-input v-model:value="optionData.dataset[index]" size="small" placeholder="请输入图片地址"></n-input>
<n-button ghost @click="optionData.dataset.splice(index, 1)">
-
</n-button>
</n-input-group>
</setting-item>
<setting-item>
<n-button size="small" @click="optionData.dataset.push('')">
+
</n-button>
</setting-item>
</setting-item-box>
<setting-item-box name="播放器">
<setting-item>
<n-space>
<n-switch v-model:value="optionData.autoplay" size="small" />
<n-text>自动播放</n-text>
</n-space>
</setting-item>
<!-- 开启自动播放时设置间隔时间 -->
<setting-item name="间隔时间">
<n-input-number v-model:value="optionData.interval" size="small" placeholder=""></n-input-number>
</setting-item>
<setting-item name="轮播方向">
<n-select v-model:value="optionData.direction" :options="directions" placeholder="选择方向" />
</setting-item>
<setting-item name="过渡效果">
<n-select v-model:value="optionData.effect" :options="effects" placeholder="效果" />
</setting-item>
<setting-item name="每页数量">
<n-input-number v-model:value="optionData.slidesPerview" size="small" placeholder=""></n-input-number>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.centeredSlides" size="small" />
<n-text>居中显示</n-text>
</n-space>
</setting-item>
<setting-item name="图片样式">
<n-select v-model:value="optionData.fit" :options="fitList" placeholder="样式" />
</setting-item>
</setting-item-box>
<setting-item-box name="指示器">
<setting-item name="样式">
<n-select v-model:value="optionData.dotType" :options="dotTypes" placeholder="选择样式" />
</setting-item>
<setting-item name="位置">
<n-select v-model:value="optionData.dotPlacement" :options="dotPlacements" placeholder="选择位置" />
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showDots" size="small" />
<n-text>显示</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showArrow" size="small" />
<n-text>箭头</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.draggable" size="small" />
<n-text>拖曳切换</n-text>
</n-space>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
// 字典
const dotTypes = [
{
label: "点",
value: "dot"
},
{
label: "线",
value: "line"
}
]
const directions = [
{
label: "水平方向",
value: "horizontal"
},
{
label: "垂直方向",
value: "vertical"
}
]
const effects = [
{
label: "slide",
value: "slide"
},
{
label: "fade",
value: "fade"
},
{
label: "card",
value: "card"
},
{
label: "custom",
value: "custom"
}
]
const dotPlacements = [
{
label: "上边",
value: "top"
},
{
label: "下边",
value: "bottom"
},
{
label: "左边",
value: "left"
},
{
label: "右边",
value: "right"
}
]
// 适应类型
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
},
]
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const CarouselConfig: ConfigType = {
key: 'Carousel',
chartKey: 'VCarousel',
conKey: 'VCCarousel',
title: '轮播图',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.NAIVE_UI,
image: 'photo.png'
}

View File

@@ -0,0 +1,47 @@
<template>
<div>
<n-carousel :autoplay="autoplay" :interval="interval" :centered-slides="centeredSlides" :direction="direction"
:dot-placement="dotPlacement" :dot-type="dotType" :draggable="draggable" :effect="effect"
:slides-per-view="slidesPerview" :show-arrow="showArrow" :show-dots="showDots">
<n-image v-for="url in option.dataset" :object-fit="fit" preview-disabled :src="url"
:fallback-src="requireErrorImg()" :width="w" :height="h"></n-image>
</n-carousel>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { requireErrorImg } from '@/utils'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { option as configOption } from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const option = shallowReactive({
dataset: configOption.dataset
})
const { w, h } = toRefs(props.chartConfig.attr)
const { autoplay, interval, slidesPerview, direction, draggable, centeredSlides, effect, dotType, dotPlacement, showArrow, showDots, fit } = toRefs(props.chartConfig.option)
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
},
{
immediate: true,
deep: false
}
)
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData
})
</script>

View File

@@ -14,7 +14,7 @@ export const option = {
export default class Config extends PublicConfigClass implements CreateComponentType
{
public key = IframeConfig.key
public attr = { ...chartInitConfig, w: 800, h: 800, zIndex: -1 }
public attr = { ...chartInitConfig, w: 1200, h: 800, zIndex: -1 }
public chartConfig = cloneDeep(IframeConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,44 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { ImageCarouselConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import logo from '@/assets/logo.png'
export const option = {
// 图片资源列表
dataset: [
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg',
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg',
'https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg',
],
// 自动播放
autoplay: true,
// 自动播放的间隔(豪秒)
interval: 5000,
// 每页显示的图片数量
slidesPerview: 1,
// 轮播方向
direction: "horizontal",
// 拖曳切换
draggable: true,
// 居中显示
centeredSlides: false,
// 过渡效果
effect: "slide",
// 是否显示指示点
showDots: true,
// 指示器样式
dotType: "dot",
// 指示器位置
dotPlacement: "bottom",
// 显示箭头
showArrow: false,
// 图片样式
fit: "contain",
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = ImageCarouselConfig.key
public chartConfig = cloneDeep(ImageCarouselConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,168 @@
<template>
<collapse-item name="路径" :expanded="true">
<setting-item v-for="(item, index) in optionData.dataset" :key="index">
<n-input-group>
<n-input v-model:value="optionData.dataset[index]" size="small" placeholder="请输入图片地址"></n-input>
<n-button ghost @click="optionData.dataset.splice(index, 1)"> - </n-button>
</n-input-group>
</setting-item>
<setting-item>
<n-button size="small" @click="optionData.dataset.push('')"> + 新增</n-button>
</setting-item>
</collapse-item>
<collapse-item name="轮播属性" :expanded="true">
<setting-item-box name="播放器">
<setting-item>
<n-space>
<n-switch v-model:value="optionData.autoplay" size="small" />
<n-text>自动播放</n-text>
</n-space>
</setting-item>
<!-- 开启自动播放时设置间隔时间 -->
<setting-item name="间隔时间">
<n-input-number v-model:value="optionData.interval" size="small" placeholder="">
<template #suffix> 毫秒 </template>
</n-input-number>
</setting-item>
<setting-item name="轮播方向">
<n-select v-model:value="optionData.direction" :options="directions" placeholder="选择方向" />
</setting-item>
<setting-item name="过渡效果">
<n-select v-model:value="optionData.effect" :options="effects" placeholder="效果" />
</setting-item>
<setting-item name="每页数量">
<n-input-number v-model:value="optionData.slidesPerview" size="small" placeholder=""></n-input-number>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.centeredSlides" size="small" />
<n-text>居中显示</n-text>
</n-space>
</setting-item>
<setting-item name="图片样式">
<n-select v-model:value="optionData.fit" :options="fitList" placeholder="样式" />
</setting-item>
</setting-item-box>
<setting-item-box name="指示器">
<setting-item name="样式">
<n-select v-model:value="optionData.dotType" :options="dotTypes" placeholder="选择样式" />
</setting-item>
<setting-item name="位置">
<n-select v-model:value="optionData.dotPlacement" :options="dotPlacements" placeholder="选择位置" />
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showDots" size="small" />
<n-text>显示</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showArrow" size="small" />
<n-text>箭头</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.draggable" size="small" />
<n-text>拖曳切换</n-text>
</n-space>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
// 字典
const dotTypes = [
{
label: '点',
value: 'dot'
},
{
label: '线',
value: 'line'
}
]
const directions = [
{
label: '水平方向',
value: 'horizontal'
},
{
label: '垂直方向',
value: 'vertical'
}
]
const effects = [
{
label: 'slide',
value: 'slide'
},
{
label: 'fade',
value: 'fade'
},
{
label: 'card',
value: 'card'
},
{
label: 'custom',
value: 'custom'
}
]
const dotPlacements = [
{
label: '上边',
value: 'top'
},
{
label: '下边',
value: 'bottom'
},
{
label: '左边',
value: 'left'
},
{
label: '右边',
value: 'right'
}
]
// 适应类型
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
}
]
</script>

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const ImageCarouselConfig: ConfigType = {
key: 'ImageCarousel',
chartKey: 'VImageCarousel',
conKey: 'VCImageCarousel',
title: '轮播图',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.NAIVE_UI,
image: 'photo_carousel.png'
}

View File

@@ -0,0 +1,78 @@
<template>
<div>
<n-carousel
:autoplay="autoplay"
:interval="interval"
:centered-slides="centeredSlides"
:direction="direction"
:dot-placement="dotPlacement"
:dot-type="dotType"
:draggable="draggable"
:effect="effect"
:slides-per-view="slidesPerview"
:show-arrow="showArrow"
:show-dots="showDots"
>
<n-image
v-for="(url, index) in option.dataset"
preview-disabled
:key="index"
:object-fit="fit"
:src="url"
:fallback-src="requireErrorImg()"
:width="w"
:height="h"
></n-image>
</n-carousel>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { requireErrorImg } from '@/utils'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { option as configOption } from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const option = shallowReactive({
dataset: configOption.dataset
})
const { w, h } = toRefs(props.chartConfig.attr)
const {
autoplay,
interval,
slidesPerview,
direction,
draggable,
centeredSlides,
effect,
dotType,
dotPlacement,
showArrow,
showDots,
fit
} = toRefs(props.chartConfig.option)
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
},
{
immediate: true,
deep: false
}
)
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData
})
</script>

View File

@@ -16,7 +16,7 @@ import 'echarts-wordcloud'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import config, { includes } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
@@ -49,7 +49,7 @@ const option = computed(() => {
const dataSetHandle = (dataset: typeof dataJson) => {
try {
dataset && (props.chartConfig.option.series[0].data = dataset)
vChartRef.value && isPreview() && vChartRef.value.setOption(props.chartConfig.option)
vChartRef.value && isPreview() && setOption(vChartRef.value, props.chartConfig.option)
} catch (error) {
console.log(error)
}

View File

@@ -1,6 +1,8 @@
import { ImageConfig } from './Image/index'
import { ImageCarouselConfig } from './ImageCarousel/index'
import { IframeConfig } from './Iframe/index'
import { VideoConfig } from './Video/index'
import { WordCloudConfig } from './WordCloud/index'
import { CarouselConfig } from './Carousel/index'
export default [WordCloudConfig, ImageConfig, VideoConfig, IframeConfig]
export default [ImageConfig, ImageCarouselConfig, VideoConfig, IframeConfig, WordCloudConfig]

View File

@@ -15,7 +15,6 @@ export const FontWeightObject = {
}
export const option = {
dataset: '让数字化看得见',
fontSize: 32,
fontColor: '#ffffff',
@@ -39,4 +38,5 @@ export default class Config extends PublicConfigClass implements CreateComponent
public attr = { ...chartInitConfig, w: 500, h: 70, zIndex: -1 }
public chartConfig = cloneDeep(TextBarrageConfig)
public option = cloneDeep(option)
public preview = { overFlowHidden: true }
}

View File

@@ -40,6 +40,15 @@
<SettingItem name="列宽度">
<n-input v-model:value="columnWidth" :min="1" size="small" placeholder="列宽度(英文','分割)"></n-input>
</SettingItem>
<SettingItem name="轮播方式">
<n-select
v-model:value="optionData.carousel"
:options="[
{ label: '单条轮播', value: 'single' },
{ label: '整页轮播', value: 'page' },
]"
/>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="样式">

View File

@@ -114,6 +114,10 @@ export interface PublicConfigType {
// 动画
animations: string[]
}
preview?: {
// 预览超出隐藏
overFlowHidden?: boolean
}
filter?: string
status: StatusType
events: {

View File

@@ -2,6 +2,7 @@ import merge from 'lodash/merge'
import pick from 'lodash/pick'
import { EchartsDataType } from '../index.d'
import { globalThemeJson } from '@/settings/chartThemes/index'
import type VChart from 'vue-echarts'
/**
* * 合并 color 和全局配置项
@@ -33,3 +34,15 @@ export const setData = (option: any, data: EchartsDataType) => {
option.dataset = data
return option
}
/**
* * 配置公共 setOption 方法
* @param instance
* @param data
*/
export const setOption = <T extends typeof VChart | undefined, D>(instance: T, data: D) => {
if (!instance) return
const option = instance.getOption()
option.dataset = null
instance.setOption(data)
}

View File

@@ -78,6 +78,10 @@ export class PublicConfigClass implements PublicConfigType {
// 动画
animations: []
}
// 预览
public preview = {
overFlowHidden: false
}
// 状态
public status = {
lock: false,

View File

@@ -8,10 +8,7 @@ import { SketchRule } from 'vue3-sketch-ruler'
* @param app
*/
export function setupCustomComponents(app: App) {
// 骨架屏
app.component('GoSkeleton', GoSkeleton)
// 加载
app.component('GoLoading', GoLoading)
// 标尺
app.component('SketchRule', SketchRule)
}

View File

@@ -1,4 +1,5 @@
import {
Add as AddIcon,
Close as CloseIcon,
Remove as RemoveIcon,
Resize as ResizeIcon,
@@ -52,9 +53,9 @@ import {
ColorWand as ColorWandIcon,
ArrowBack as ArrowBackIcon,
ArrowForward as ArrowForwardIcon,
ArrowDown as ArrowDownIcon,
Planet as PawIcon,
Search as SearchIcon,
Reload as ReloadIcon,
ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon,
Pulse as PulseIcon,
@@ -65,7 +66,8 @@ import {
List as ListIcon,
EyeOutline as EyeOutlineIcon,
EyeOffOutline as EyeOffOutlineIcon,
Albums as AlbumsIcon
Albums as AlbumsIcon,
Analytics as AnalyticsIcon
} from '@vicons/ionicons5'
import {
@@ -94,7 +96,6 @@ import {
FitToScreen as FitToScreenIcon,
FitToHeight as FitToHeightIcon,
FitToWidth as FitToWidthIcon,
Save as SaveIcon,
Carbon3DCursor as Carbon3DCursorIcon,
Carbon3DSoftware as Carbon3DSoftwareIcon,
Filter as FilterIcon,
@@ -103,6 +104,8 @@ import {
} from '@vicons/carbon'
const ionicons5 = {
// 新增
AddIcon,
// 帮助(问号)
HelpOutlineIcon,
// 添加
@@ -208,12 +211,12 @@ const ionicons5 = {
ArrowBackIcon,
// 前进
ArrowForwardIcon,
// 向下
ArrowDownIcon,
// 狗爪
PawIcon,
// 搜索(放大镜)
SearchIcon,
// 加载
ReloadIcon,
// 过滤器
FilterIcon,
// 向上
@@ -236,7 +239,9 @@ const ionicons5 = {
EyeOutlineIcon,
EyeOffOutlineIcon,
// 图表列表
AlbumsIcon
AlbumsIcon,
// 分析
AnalyticsIcon
}
const carbon = {
@@ -281,8 +286,6 @@ const carbon = {
FitToScreenIcon,
FitToHeightIcon,
FitToWidthIcon,
// 保存
SaveIcon,
// 成组
Carbon3DCursorIcon,
// 解组

View File

@@ -2,3 +2,4 @@ export { setupNaive } from '@/plugins/naive'
export { setupDirectives } from '@/plugins/directives'
export { setupCustomComponents } from '@/plugins/customComponents'
export { icon } from '@/plugins/icon'
export { initFunction } from '@/plugins/initFunction'

View File

@@ -0,0 +1,9 @@
/**
* * 页面初始化就执行的函数
*/
export const initFunction = async () => {
// 捕获全局错误
window.addEventListener("unhandledrejection", event => {
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
});
}

View File

@@ -57,6 +57,7 @@ import {
NProgress,
NDatePicker,
NGrid,
NGi,
NGridItem,
NList,
NListItem,
@@ -160,6 +161,7 @@ const naive = create({
NProgress,
NDatePicker,
NGrid,
NGi,
NGridItem,
NList,
NListItem,

View File

@@ -1,13 +1,13 @@
import { RouteRecordRaw } from 'vue-router'
import type { AppRouteRecordRaw } from '@/router/types';
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout, RedirectHome, RedirectUnPublish } from '@/router/constant';
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout } from '@/router/constant';
import { PageEnum } from '@/enums/pageEnum'
import { GoReload } from '@/components/GoReload'
export const LoginRoute: RouteRecordRaw = {
path: PageEnum.BASE_LOGIN,
name: PageEnum.BASE_LOGIN_NAME,
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue'),
meta: {
title: '登录',
@@ -60,21 +60,22 @@ export const ReloadRoute: AppRouteRecordRaw = {
},
}
export const RedirectRoute: RouteRecordRaw[] = [
{
path: PageEnum.REDIRECT,
name: PageEnum.REDIRECT_NAME,
component: RedirectHome,
meta: {
title: PageEnum.REDIRECT_NAME,
},
export const RedirectRoute: AppRouteRecordRaw = {
path: PageEnum.REDIRECT,
name: PageEnum.REDIRECT_NAME,
component: Layout,
meta: {
title: PageEnum.REDIRECT_NAME,
},
{
path: PageEnum.REDIRECT_UN_PUBLISH,
name: PageEnum.REDIRECT_UN_PUBLISH_NAME,
component: RedirectUnPublish,
meta: {
title: PageEnum.REDIRECT_UN_PUBLISH_NAME,
children: [
{
path: '/redirect/:path(.*)',
name: PageEnum.REDIRECT_NAME,
component: () => import('@/views/redirect/index.vue'),
meta: {
title: PageEnum.REDIRECT_NAME,
hideBreadcrumb: true,
},
},
},
]
],
};

View File

@@ -4,10 +4,6 @@ export const ErrorPage403 = () => import('@/views/exception/403.vue');
export const ErrorPage500 = () => import('@/views/exception/500.vue');
export const RedirectHome = () => import('@/views/redirect/index.vue');
export const RedirectUnPublish = () => import('@/views/redirect/UnPublish.vue');
export const Layout = () => import('@/layout/index.vue');
export const ParentLayout = () => import('@/layout/parentLayout.vue');

View File

@@ -1,8 +1,9 @@
import type { App } from 'vue'
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import { RedirectRoute } from '@/router/base'
import { createRouterGuards } from './router-guards'
import { PageEnum } from '@/enums/pageEnum'
import { HttpErrorPage, LoginRoute, ReloadRoute, RedirectRoute } from '@/router/base'
import { HttpErrorPage, LoginRoute, ReloadRoute } from '@/router/base'
import { Layout } from '@/router/constant'
import modules from '@/router/modules'
@@ -18,7 +19,6 @@ const RootRoute: Array<RouteRecordRaw> = [
},
children: [
...HttpErrorPage,
...RedirectRoute,
modules.projectRoutes,
modules.chartRoutes,
modules.previewRoutes,
@@ -28,7 +28,7 @@ const RootRoute: Array<RouteRecordRaw> = [
]
export const constantRouter: any[] = [LoginRoute, ...RootRoute, ReloadRoute];
export const constantRouter: any[] = [LoginRoute, ...RootRoute, RedirectRoute, ReloadRoute];
const router = createRouter({
history: createWebHashHistory(''),

View File

@@ -1,15 +1,7 @@
import { Router } from 'vue-router';
import { PageEnum, PreviewEnum } from '@/enums/pageEnum'
import { PageEnum } from '@/enums/pageEnum'
import { loginCheck } from '@/utils'
// 路由白名单
const routerAllowList = [
// 登录
PageEnum.BASE_LOGIN_NAME,
// 预览
PreviewEnum.CHART_PREVIEW_NAME
]
export function createRouterGuards(router: Router) {
// 前置
router.beforeEach(async (to, from, next) => {
@@ -20,8 +12,10 @@ export function createRouterGuards(router: Router) {
next({ name: PageEnum.ERROR_PAGE_NAME_404 })
}
// @ts-ignore
if (!routerAllowList.includes(to.name) && !loginCheck()) {
if (!loginCheck()) {
if (to.name === PageEnum.BASE_LOGIN_NAME) {
next()
}
next({ name: PageEnum.BASE_LOGIN_NAME })
}
next()

View File

@@ -31,38 +31,20 @@ export const chartColors = {
// 默认主题
export const defaultTheme = 'dark'
// 主题色列表
export type ChartColorsNameType = keyof typeof chartColorsName
export const chartColorsName = {
dark: '明亮',
customed: '暗淡',
macarons: '马卡龙',
walden: '蓝绿',
purplePassion: '深紫',
vintage: '复古',
chalk: '粉青',
westeros: '灰粉',
wonderland: '青草',
essos: '橘红',
shine: '深色',
roma: '罗马红'
// 默认展示的选择器颜色列表
export const swatchesColors = ['#232324', '#2a2a2b', '#313132', '#373739', '#757575', '#e0e0e0', '#eeeeee', '#fafafa']
// 自定义颜色
export type CustomColorsType = {
id: string,
name: string,
color: string[]
}
// 主题色列表
export const chartColorsshow = {
dark: 'linear-gradient(to right, #4992ff 0%, #7cffb2 100%)',
customed: 'linear-gradient(to right, #5470c6 0%, #91cc75 100%)',
macarons: 'linear-gradient(to right, #2ec7c9 0%, #b6a2de 100%)',
walden: 'linear-gradient(to right, #3fb1e3 0%, #6be6c1 100%)',
purplePassion: 'linear-gradient(to right, #9b8bba 0%, #e098c7 100%)',
vintage: 'linear-gradient(to right, #d87c7c 0%, #919e8b 100%)',
chalk: 'linear-gradient(to right, #fc97af 0%, #87f7cf 100%)',
westeros: 'linear-gradient(to right, #516b91 0%, #edafda 100%)',
wonderland: 'linear-gradient(to right, #4ea397 0%, #22c3aa 100%)',
essos: 'linear-gradient(to right, #893448 0%, #d95850 100%)',
shine: 'linear-gradient(to right, #c12e34 0%, #0098d9 100%)',
roma: 'linear-gradient(to right, #e01f54 0%, #5e4ea5 100%)'
}
// 主题色列表, 自定义的颜色使用的是 UUID 作为标识,因为两者数据结构不一致
export type ChartColorsNameType = keyof typeof chartColors
// 渐变主题色列表主色1、主色2、阴影、渐变1、渐变2
export const chartColorsSearch = {
dark: ['#4992ff', '#7cffb2', 'rgba(68, 181, 226, 0.3)', 'rgba(73, 146, 255, 0.5)', 'rgba(124, 255, 178, 0.5)'],

View File

@@ -8,5 +8,6 @@
"#d4a4eb",
"#d2f5a6",
"#76f2f2"
]
],
"name": "粉青"
}

View File

@@ -9,5 +9,6 @@
"#fc8452",
"#9a60b4",
"#ea7ccc"
]
],
"name": "暗淡"
}

View File

@@ -9,5 +9,6 @@
"#ff8a45",
"#8d48e3",
"#dd79ff"
]
],
"name": "明亮"
}

View File

@@ -6,5 +6,6 @@
"#ffb248",
"#f2d643",
"#ebdba4"
]
],
"name": "橘红"
}

View File

@@ -20,5 +20,6 @@
"#7eb00a",
"#6f5553",
"#c14089"
]
],
"name": "马卡龙"
}

View File

@@ -6,5 +6,6 @@
"#71669e",
"#cc70af",
"#7cb4cc"
]
],
"name": "深紫"
}

View File

@@ -20,5 +20,6 @@
"#3cb371",
"#d5b158",
"#38b6b6"
]
],
"name": "罗马红"
}

View File

@@ -8,5 +8,6 @@
"#339ca8",
"#cda819",
"#32a487"
]
],
"name": "深色"
}

View File

@@ -10,5 +10,6 @@
"#cc7e63",
"#724e58",
"#4b565b"
]
],
"name": "复古"
}

View File

@@ -6,5 +6,6 @@
"#a0a7e6",
"#c4ebad",
"#96dee8"
]
],
"name": "蓝绿"
}

View File

@@ -6,5 +6,6 @@
"#93b7e3",
"#a5e7f0",
"#cbb0e3"
]
],
"name": "灰粉"
}

View File

@@ -6,5 +6,6 @@
"#d0648a",
"#f58db2",
"#f2b3c9"
]
],
"name": "青草"
}

View File

@@ -61,9 +61,6 @@ export const editToJsonInterval = 5000
// 数据请求间隔
export const requestInterval = 30
// 工作台自动保存间隔s
export const saveInterval = 30
// 数据请求间隔单位
export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND

View File

@@ -1,2 +0,0 @@
// 请求前缀
export const axiosPre = '/api/goview'

View File

@@ -1,6 +1,5 @@
import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { SyncEnum } from '@/enums/editPageEnum'
import {
RequestHttpEnum,
RequestContentTypeEnum,
@@ -11,30 +10,7 @@ import {
RequestParamsObjType
} from '@/enums/httpEnum'
import { PreviewScaleEnum } from '@/enums/styleEnum'
import type { ChartColorsNameType, GlobalThemeJsonType } from '@/settings/chartThemes/index'
// 项目数据枚举
export enum ProjectInfoEnum {
// ID
PROJECT_ID = "projectId",
// 名称
PROJECT_NAME = 'projectName',
// 描述
REMARKS = 'remarks',
// 缩略图
THUMBNAIL= 'thumbnail',
// 是否公开发布
RELEASE = 'release'
}
// 项目数据
export type ProjectInfoType = {
[ProjectInfoEnum.PROJECT_ID]: string,
[ProjectInfoEnum.PROJECT_NAME]: string,
[ProjectInfoEnum.REMARKS]: string,
[ProjectInfoEnum.THUMBNAIL]: string,
[ProjectInfoEnum.RELEASE]: boolean
}
import type { ChartColorsNameType, CustomColorsType, GlobalThemeJsonType } from '@/settings/chartThemes/index'
// 编辑画布属性
export enum EditCanvasTypeEnum {
@@ -44,13 +20,13 @@ export enum EditCanvasTypeEnum {
SCALE = 'scale',
USER_SCALE = 'userScale',
LOCK_SCALE = 'lockScale',
SAVE_STATUS = 'saveStatus',
IS_CREATE = 'isCreate',
IS_DRAG = 'isDrag',
IS_SELECT = 'isSelect'
IS_SELECT = 'isSelect',
IS_CODE_EDIT="isCodeEdit"
}
// 编辑区域(临时)
// 编辑区域
export type EditCanvasType = {
// 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@@ -67,18 +43,19 @@ export type EditCanvasType = {
[EditCanvasTypeEnum.IS_CREATE]: boolean
// 拖拽中
[EditCanvasTypeEnum.IS_DRAG]: boolean
// 保存状态
[EditCanvasTypeEnum.SAVE_STATUS]: SyncEnum
// 框选中
[EditCanvasTypeEnum.IS_SELECT]: boolean
// 代码编辑中
[EditCanvasTypeEnum.IS_CODE_EDIT]: boolean
}
// 画布数据/滤镜/背景色/宽高主题等
// 滤镜/背景色/宽高主题等
export enum EditCanvasConfigEnum {
PROJECT_NAME = 'projectName',
WIDTH = 'width',
HEIGHT = 'height',
CHART_THEME_COLOR = 'chartThemeColor',
CHART_CUSTOM_THEME_COLOR_INFO = 'chartCustomThemeColorInfo',
CHART_THEME_SETTING = 'chartThemeSetting',
BACKGROUND = 'background',
BACKGROUND_IMAGE = 'backgroundImage',
@@ -86,14 +63,7 @@ export enum EditCanvasConfigEnum {
PREVIEW_SCALE_TYPE = 'previewScaleType'
}
// 画布属性(需保存)
export type EditCanvasConfigType = {
// ID
[EditCanvasConfigEnum.PROJECT_ID]: string,
// 项目名称
[EditCanvasConfigEnum.PROJECT_NAME]?: string,
// 项目描述
[EditCanvasConfigEnum.REMARKS]: string,
export interface EditCanvasConfigType {
// 滤镜-启用
[FilterEnum.FILTERS_SHOW]: boolean
// 滤镜-色相
@@ -121,9 +91,12 @@ export type EditCanvasConfigType = {
[EditCanvasConfigEnum.HEIGHT]: number
// 背景色
[EditCanvasConfigEnum.BACKGROUND]?: string
// 背景图片
[EditCanvasConfigEnum.BACKGROUND_IMAGE]?: string | null
// 图表主题颜色
[EditCanvasConfigEnum.CHART_THEME_COLOR]: ChartColorsNameType
// 自定义图表主题颜色
[EditCanvasConfigEnum.CHART_CUSTOM_THEME_COLOR_INFO]?: CustomColorsType[]
// 图表全局配置
[EditCanvasConfigEnum.CHART_THEME_SETTING]: GlobalThemeJsonType
// 图表主题颜色
@@ -167,7 +140,6 @@ export type RecordChartType = {
// Store 枚举
export enum ChartEditStoreEnum {
PROJECT_INFO = 'projectInfo',
EDIT_RANGE = 'editRange',
EDIT_CANVAS = 'editCanvas',
RIGHT_MENU_SHOW = 'rightMenuShow',
@@ -229,7 +201,6 @@ export interface RequestConfigType extends RequestPublicConfigType {
// Store 类型
export interface ChartEditStoreType {
[ChartEditStoreEnum.PROJECT_INFO]: ProjectInfoType
[ChartEditStoreEnum.EDIT_CANVAS]: EditCanvasType
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean

View File

@@ -10,22 +10,14 @@ import { requestInterval, previewScaleType, requestIntervalUnit } from '@/settin
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
// 全局设置
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
// 历史类型
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
// 画布枚举
import { MenuEnum, SyncEnum } from '@/enums/editPageEnum'
import {
getUUID,
loadingStart,
loadingFinish,
loadingError,
isString,
isArray
} from '@/utils'
HistoryActionTypeEnum,
HistoryItemType,
HistoryTargetTypeEnum
} from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { MenuEnum } from '@/enums/editPageEnum'
import { getUUID, loadingStart, loadingFinish, loadingError, isString, isArray } from '@/utils'
import {
ProjectInfoType,
ChartEditStoreEnum,
ChartEditStorage,
ChartEditStoreType,
@@ -44,14 +36,6 @@ const settingStore = useSettingStore()
export const useChartEditStore = defineStore({
id: 'useChartEditStore',
state: (): ChartEditStoreType => ({
// 项目数据
projectInfo: {
projectId: '',
projectName: '',
remarks: '',
thumbnail: '',
release: false
},
// 画布属性
editCanvas: {
// 编辑区域 Dom
@@ -71,8 +55,8 @@ export const useChartEditStore = defineStore({
isDrag: false,
// 框选中
isSelect: false,
// 同步
saveStatus: SyncEnum.PENDING
// 代码编辑
isCodeEdit: false
},
// 右键菜单
rightMenuShow: false,
@@ -126,6 +110,8 @@ export const useChartEditStore = defineStore({
selectColor: true,
// chart 主题色
chartThemeColor: defaultTheme || 'dark',
// 自定义颜色列表
chartCustomThemeColorInfo: undefined,
// 全局配置
chartThemeSetting: globalThemeJson,
// 适配方式
@@ -152,9 +138,6 @@ export const useChartEditStore = defineStore({
componentList: []
}),
getters: {
getProjectInfo(): ProjectInfoType {
return this.projectInfo
},
getMousePosition(): MousePositionType {
return this.mousePosition
},
@@ -189,10 +172,6 @@ export const useChartEditStore = defineStore({
}
},
actions: {
// * 设置 peojectInfo 数据项
setProjectInfo<T extends keyof ProjectInfoType, K extends ProjectInfoType[T]>(key: T, value: K) {
this.projectInfo[key] = value
},
// * 设置 editCanvas 数据项
setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) {
this.editCanvas[key] = value

View File

@@ -4,10 +4,10 @@ import { asideCollapsedWidth } from '@/settings/designSetting'
import { SettingStoreType, ToolsStatusEnum } from './settingStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
const { GO_SETTING_STORE } = StorageEnum
const { GO_SYSTEM_SETTING_STORE } = StorageEnum
const storageSetting: SettingStoreType = getLocalStorage(
GO_SETTING_STORE
GO_SYSTEM_SETTING_STORE
)
// 全局设置
@@ -48,7 +48,7 @@ export const useSettingStore = defineStore({
this.$patch(state => {
state[key] = value
})
setLocalStorage(GO_SETTING_STORE, this.$state)
setLocalStorage(GO_SYSTEM_SETTING_STORE, this.$state)
}
}
})

View File

@@ -1,31 +0,0 @@
export enum SystemStoreUserInfoEnum {
USER_TOKEN = 'userToken',
TOKEN_NAME = 'tokenName',
USER_ID = 'userId',
USER_NAME = 'userName',
NICK_NAME = 'nickName',
}
export interface UserInfoType {
[SystemStoreUserInfoEnum.USER_TOKEN]?: string,
[SystemStoreUserInfoEnum.TOKEN_NAME]?: string,
[SystemStoreUserInfoEnum.USER_ID]?: string,
[SystemStoreUserInfoEnum.USER_NAME]?: string,
[SystemStoreUserInfoEnum.NICK_NAME]?: string,
}
export interface FetchInfoType {
OSSUrl?: string,
}
export enum SystemStoreEnum {
// 用户
USER_INFO = 'userInfo',
// 请求
FETCH_INFO = 'fetchInfo'
}
export interface SystemStoreType {
[SystemStoreEnum.USER_INFO]: UserInfoType
[SystemStoreEnum.FETCH_INFO]: FetchInfoType
}

View File

@@ -1,40 +0,0 @@
import { defineStore } from 'pinia'
import { SystemStoreType, UserInfoType, FetchInfoType } from './systemStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
const { GO_SYSTEM_STORE } = StorageEnum
const storageSystem: SystemStoreType = getLocalStorage(GO_SYSTEM_STORE)
// 系统数据记录
export const useSystemStore = defineStore({
id: 'useSystemStore',
state: (): SystemStoreType => storageSystem || {
userInfo: {
userId: undefined,
userName: undefined,
userToken: undefined,
nickName: undefined
},
fetchInfo: {
OSSUrl: undefined
}
},
getters: {
getUserInfo(): UserInfoType {
return this.userInfo
},
getFetchInfo(): FetchInfoType {
return this.fetchInfo
},
},
actions: {
setItem<T extends keyof SystemStoreType, K extends SystemStoreType[T]>(key: T, value: K): void {
this.$patch(state => {
state[key] = value
});
setLocalStorage(GO_SYSTEM_STORE, this.$state)
}
}
})

View File

@@ -1,65 +1,3 @@
/**
* * base64转file
* @param dataurl
* @param fileName
* @returns
*/
export const base64toFile = (dataurl: string, fileName: string) => {
let dataArr = dataurl.split(","),
mime = (dataArr as any[])[0].match(/:(.*?);/)[1],
bstr = atob(dataArr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], fileName, { type: mime });
}
/**
* * file转url
*/
export const fileToUrl = (file: File): string => {
const Url = URL || window.URL || window.webkitURL
const ImageUrl = Url.createObjectURL(file)
return ImageUrl
}
/**
* * url转file
*/
export const urlToFile = (fileUrl: string, fileName = `${new Date().getTime()}`): File => {
const dataArr = fileUrl.split(',')
const mime = (dataArr as any[])[0].match(/:(.*);/)[1]
const originStr = atob(dataArr[1])
return new File([originStr], `${fileName}`, { type: mime })
}
/**
* * file转base64
* @param file 文件数据
* @param callback 回调函数
*/
export const fileTobase64 = (file: File, callback: Function) => {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function (e: ProgressEvent<FileReader>) {
if (e.target) {
let base64 = e.target.result
callback(base64)
}
}
}
/**
* * canvas转file
* @param canvas
*/
export const canvastoFile = (canvas: HTMLCanvasElement, name?: string) => {
const dataurl = canvas.toDataURL('image/png')
return urlToFile(dataurl, name)
}
/**
* *获取上传的文件数据
* @param { File } file 文件对象
@@ -113,4 +51,4 @@ export const downloadTextFile = (
// 字符内容转变成blob地址
const blob = new Blob([content])
downloadByA(URL.createObjectURL(blob), filename, fileSuffix)
}
}

View File

@@ -1,6 +0,0 @@
/**
* * 请求失败统一处理
*/
export const httpErrorHandle = () => {
window['$message'].error(window['$t']('http.error_message'))
}

View File

@@ -7,4 +7,3 @@ export * from '@/utils/plugin'
export * from '@/utils/components'
export * from '@/utils/type'
export * from '@/utils/file'
export * from '@/utils/http'

View File

@@ -35,7 +35,7 @@ export const loadingError = () => {
* })
* ```
*/
export const goDialog = (
export const goDialog = (
params: {
// 基本
type?: DialogEnum

Some files were not shown because too many files have changed in this diff Show More