Compare commits

...

87 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
奔跑的面条
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
奔跑的面条
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
奔跑的面条
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
奔跑的面条
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
35 changed files with 886 additions and 151 deletions

158
README.md
View File

@@ -1,30 +1,62 @@
## 总览
#### 总览
<p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
![logo](readme/logo-t-y.png)
<h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
#### 长期赞助商
<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>
### 😶 **前端** 分支: **`master`**
#### 😶 **前端** 分支: **`master`**
### 👻 携带 **后端** 请求分支: **`master-fetch`**
#### 👻 携带 **后端** 请求分支: **`master-fetch`**
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
#### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
Cloud IDE 代码在线预览地址:[https://idegitee.com/dromara/go-view](https://idegitee.com/dromara/go-view)
文档-源码地址:[https://gitee.com/MTrun/go-view-doc](https://gitee.com/MTrun/go-view-doc)
#### 🤯 后端项目看这里!
### 🤯 后端项目
后端项目 gitee 地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
后端项目gitee地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
接口说明地址:[https://docs.apipost.cn/...](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](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)
其它后端方案地址:
技术点:
- 【.NET】[https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
#### 整体介绍
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
@@ -36,17 +68,34 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
说明文档:
![说明文档](readme/go-view-doc.png)
工作台:
![项目截图](readme/go-view-canvas.png)
![工作台](readme/go-view-canvas.png)
请求配置:
![项目截图](readme/go-view-fetch.png)
![请求配置](readme/go-view-fetch.png)
数据过滤:
![项目截图](readme/go-view-filter.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-color.png)
亮白主题:
![亮白主题](readme/go-view-theme.png)
主要技术栈为:
@@ -66,14 +115,17 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
已完成图表:
| 分类 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------------- | -------- |
| 图表 | 柱状图 | 横向柱状图 | 折线图 |
| \* | 单/多 折线面积图 | 饼图 | 水球图 |
| \* | 环形图 | NaiveUI 多种进度 | 🤠 |
| 信息 | 文字 | 图 | 😶 |
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 |
| 分类 | 名称 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------- | -------------- | ------------------------ |
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
| \* | 漏斗图 | 中国地图 | 高德地 | 🦊 |
| 信息 | 文字 | 渐变文字 | 词云 | 嵌套网页 |
| \* | 图片 | 视频 | 😺 | 🐯 |
| 列表 | 滚动排名列表 | 滚动表格 | 🐮 | 🐐 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 |
## 浏览器支持
@@ -81,52 +133,7 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
## 安装
本项目采用` pnpm` 进行包管理
```shell
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
#pnpm
pnpm install
#yarn
yarn install
#npm
npm install
```
## 启动
```shell
#pnpm
pnpm dev
# npm
npm run dev
#yarn
yarn dev
#Makefile
make dev
```
## 编译
```shell
#pnpm
pnpm run build
# npm
npm run build
#yarn
yarn run build
#Makefile
make dist
```
请查看文档:[https://www.mtruning.club/](https://www.mtruning.club/)
## 代码提交
@@ -142,10 +149,9 @@ make dist
- 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

@@ -1,8 +1,8 @@
{
"name": "go-view",
"version": "1.1.11",
"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

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -12,7 +12,8 @@ export enum DragKeyEnum {
// 不同页面保存操作
export enum SavePageEnum {
CHART = 'SaveChart',
JSON = 'SaveJSON'
JSON = 'SaveJSON',
CLOSE = 'close'
}
// 操作枚举

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,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

@@ -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)
}
@@ -127,7 +128,7 @@ watch(
//监听地图展示区域发生变化
watch(
() => props.chartConfig.option.mapRegion.adcode,
() => `${props.chartConfig.option.mapRegion.adcode}`,
async newData => {
try {
await getGeojson(newData)

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

@@ -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

@@ -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

@@ -66,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 {
@@ -238,7 +239,9 @@ const ionicons5 = {
EyeOutlineIcon,
EyeOffOutlineIcon,
// 图表列表
AlbumsIcon
AlbumsIcon,
// 分析
AnalyticsIcon
}
const carbon = {

View File

@@ -22,7 +22,8 @@ export enum EditCanvasTypeEnum {
LOCK_SCALE = 'lockScale',
IS_CREATE = 'isCreate',
IS_DRAG = 'isDrag',
IS_SELECT = 'isSelect'
IS_SELECT = 'isSelect',
IS_CODE_EDIT="isCodeEdit"
}
// 编辑区域
@@ -44,6 +45,8 @@ export type EditCanvasType = {
[EditCanvasTypeEnum.IS_DRAG]: boolean
// 框选中
[EditCanvasTypeEnum.IS_SELECT]: boolean
// 代码编辑中
[EditCanvasTypeEnum.IS_CODE_EDIT]: boolean
}
// 滤镜/背景色/宽高主题等

View File

@@ -54,7 +54,9 @@ export const useChartEditStore = defineStore({
// 拖拽中
isDrag: false,
// 框选中
isSelect: false
isSelect: false,
// 代码编辑中
isCodeEdit: false
},
// 右键菜单
rightMenuShow: false,

View File

@@ -10,7 +10,7 @@ import cloneDeep from 'lodash/cloneDeep'
import { WinKeyboard } from '@/enums/editPageEnum'
import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
import { excludeParseEventKeyList } from '@/enums/eventEnum'
import { excludeParseEventKeyList, excludeParseEventValueList } from '@/enums/eventEnum'
/**
* * 判断是否是开发环境
@@ -320,10 +320,17 @@ export const JSONStringify = <T>(data: T) => {
*/
export const JSONParse = (data: string) => {
return JSON.parse(data, (k, v) => {
// 过滤函数字符串
if (excludeParseEventKeyList.includes(k)) return v
// 过滤函数值表达式
if (typeof v === 'string') {
const someValue = excludeParseEventValueList.some(excludeValue => v.indexOf(excludeValue) > -1)
if (someValue) return v
}
// 还原函数值
if (typeof v === 'string' && v.indexOf && (v.indexOf('function') > -1 || v.indexOf('=>') > -1)) {
return eval(`(function(){return ${v}})()`)
} else if (typeof v === 'string' && v.indexOf && (v.indexOf('return ') > -1)) {
} else if (typeof v === 'string' && v.indexOf && v.indexOf('return ') > -1) {
const baseLeftIndex = v.indexOf('(')
if (baseLeftIndex > -1) {
const newFn = `function ${v.substring(baseLeftIndex)}`
@@ -340,4 +347,4 @@ export const JSONParse = (data: string) => {
*/
export const setTitle = (title?: string) => {
title && (document.title = title)
}
}

View File

@@ -1,42 +1,68 @@
import { watch } from 'vue'
import { useRoute } from 'vue-router'
import throttle from 'lodash/throttle'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useSync } from '@/views/chart/hooks/useSync.hook'
import { ChartEnum } from '@/enums/pageEnum'
import { SavePageEnum } from '@/enums/editPageEnum'
import { editToJsonInterval } from '@/settings/designSetting'
import { goDialog } from '@/utils'
const { updateComponent } = useSync()
const chartEditStore = useChartEditStore()
export const syncData = () => {
goDialog({
message: '是否覆盖源视图内容,此操作不可撤回?',
isMaskClosable: true,
transformOrigin: 'center',
onPositiveCallback: () => {
window['$message'].success('正在同步编辑器...')
dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo }))
}
})
}
// 侦听器更新
const useSyncUpdateHandle = () => {
// 定义侦听器变量
let timer: any
const updateFn = (e: any) => updateComponent(e!.detail, true, false)
const syncData = async () => {
dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo }))
// 更新处理
const updateFn = (e: any) => {
window['$message'].success('正在进行更新...')
updateComponent(e!.detail, true)
}
// 页面关闭处理
const closeFn = () => {
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CODE_EDIT, false)
}
// 开启侦听
const use = () => {
// // 1、定时同步数据
// 定时同步数据(暂不开启)
// timer = setInterval(() => {
// // 窗口激活并且处于工作台
// document.hasFocus() && syncData()
// }, editToJsonInterval)
// 2、失焦同步数据
addEventListener('blur', syncData)
// 【监听JSON代码 刷新工作台图表】
// 失焦同步数据(暂不开启)
// addEventListener('blur', syncData)
// 监听编辑器保存事件 刷新工作台图表
addEventListener(SavePageEnum.JSON, updateFn)
// 监听编辑页关闭
addEventListener(SavePageEnum.CLOSE, throttle(closeFn, 1000))
}
// 关闭侦听
const unUse = () => {
// clearInterval(timer)
// removeEventListener('blur', syncData)
removeEventListener(SavePageEnum.JSON, updateFn)
removeEventListener('blur', syncData)
}
// 路由变更时处理
@@ -48,11 +74,11 @@ const useSyncUpdateHandle = () => {
use()
}
}
return watchHandler
}
export const useSyncUpdate = () => {
const routerParamsInfo = useRoute()
watch(() => routerParamsInfo.name, useSyncUpdateHandle(), { immediate: true })
}
}

View File

@@ -66,7 +66,14 @@ import { ref, computed } from 'vue'
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
import { ToolsStatusEnum } from '@/store/modules/settingStore/settingStore.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { fetchRouteParamsLocation, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import {
fetchRouteParamsLocation,
fetchPathByName,
routerTurnByPath,
setSessionStorage,
getLocalStorage
} from '@/utils'
import { EditEnum } from '@/enums/pageEnum'
import { StorageEnum } from '@/enums/storageEnum'
import { useRoute } from 'vue-router'
@@ -137,8 +144,8 @@ const toolsMouseoutHandle = () => {
// 编辑处理
const editHandle = () => {
window['$message'].warning('将开启失焦更新')
// window['$message'].warning('将开启失焦更新与 5 秒同步更新!')
window['$message'].warning('请通过顶部【同步内容】按钮同步最新数据')
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CODE_EDIT, true)
setTimeout(() => {
// 获取id路径
const path = fetchPathByName(EditEnum.CHART_EDIT_NAME, 'href')
@@ -146,7 +153,7 @@ const editHandle = () => {
const id = fetchRouteParamsLocation()
updateToSession(id)
routerTurnByPath(path, [id], undefined, true)
}, 1000)
}, 2000)
}
// 把内存中的数据同步到SessionStorage 便于传递给新窗口初始化数据
@@ -169,7 +176,6 @@ const updateToSession = (id: string) => {
}
}
// 配置列表
const btnList: BtnListType[] = [
{

View File

@@ -1,6 +1,6 @@
<template>
<n-space class="go-mt-0">
<n-button v-for="item in btnList" :key="item.title" ghost @click="item.event">
<n-button v-for="item in comBtnList" :key="item.title" :type="item.type" ghost @click="item.event">
<template #icon>
<component :is="item.icon"></component>
</template>
@@ -10,16 +10,17 @@
</template>
<script setup lang="ts">
import { shallowReactive } from 'vue'
import { computed } from 'vue'
import { renderIcon, goDialog, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
import { PreviewEnum } from '@/enums/pageEnum'
import { StorageEnum } from '@/enums/storageEnum'
import { useRoute } from 'vue-router'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { syncData } from '../../ContentEdit/components/EditTools/hooks/useSyncUpdate.hook'
import { icon } from '@/plugins'
import { cloneDeep } from 'lodash'
const { BrowsersOutlineIcon, SendIcon } = icon.ionicons5
const { BrowsersOutlineIcon, SendIcon, AnalyticsIcon } = icon.ionicons5
const chartEditStore = useChartEditStore()
const routerParamsInfo = useRoute()
@@ -42,7 +43,8 @@ const previewHandle = () => {
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo)
} else {
sessionStorageInfo.push({
id: previewId, ...storageInfo
id: previewId,
...storageInfo
})
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, sessionStorageInfo)
}
@@ -56,14 +58,21 @@ const previewHandle = () => {
// 发布
const sendHandle = () => {
goDialog({
message: '想体验发布功能,请前往 master-fetch 分支查看: https://gitee.com/MTrun/go-view/tree/master-fetch',
message: '想体验发布功能,请前往 master-fetch 分支查看: https://demo.mtruning.club/#/login',
positiveText: '了然',
closeNegativeText: true,
onPositiveCallback: () => {}
})
}
const btnList = shallowReactive([
const btnList = [
{
select: true,
title: '同步内容',
type: 'primary',
icon: renderIcon(AnalyticsIcon),
event: syncData
},
{
select: true,
title: '预览',
@@ -76,9 +85,18 @@ const btnList = shallowReactive([
icon: renderIcon(SendIcon),
event: sendHandle
}
])
]
const comBtnList = computed(() => {
if (chartEditStore.getEditCanvas.isCodeEdit) {
return btnList
}
const cloneList = cloneDeep(btnList)
cloneList.shift()
return cloneList
})
</script>
<style lang="scss" scoped>
.align-center {
margin-top: -4px;

View File

@@ -14,8 +14,17 @@
</n-button>
</div>
<n-space>
<n-tag :bordered="false" type="warning"> 页面失焦保存 </n-tag>
<n-tag :bordered="false" type="warning"> ctrl + s 保存 </n-tag>
<!-- 暂时关闭 -->
<!-- <n-tag :bordered="false" type="warning"> 页面失焦保存 </n-tag> -->
<n-tag :bordered="false" type="warning"> Ctrl + S 更新视图 </n-tag>
<n-button v-if="showOpenFilePicker" class="go-mr-3" size="medium" @click="updateSync">
<template #icon>
<n-icon>
<analytics-icon></analytics-icon>
</n-icon>
</template>
保存
</n-button>
</n-space>
</n-layout-header>
<n-layout-content>
@@ -26,28 +35,31 @@
lineNumbers: 'on',
minimap: { enabled: true }
}"
/>
/>
</n-layout-content>
</n-layout>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { ref } from 'vue'
import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { SavePageEnum } from '@/enums/editPageEnum'
import { getSessionStorageInfo } from '../preview/utils'
import type { ChartEditStorageType } from '../preview/index.d'
import { setSessionStorage, JSONStringify, JSONParse, setTitle } from '@/utils'
import { setSessionStorage, JSONStringify, JSONParse, setTitle, goDialog } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
import { icon } from '@/plugins'
import type { ChartEditStorageType } from '../preview/index.d'
const { ChevronBackOutlineIcon, DownloadIcon } = icon.ionicons5
const { ChevronBackOutlineIcon, DownloadIcon, AnalyticsIcon } = icon.ionicons5
const showOpenFilePicker: Function = (window as any).showOpenFilePicker
const content = ref('')
window['$message'].warning('请不要刷新此窗口!')
// 从sessionStorage 获取数据
async function getDataBySession() {
const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
const localStorageInfo: ChartEditStorageType = (await getSessionStorageInfo()) as unknown as ChartEditStorageType
setTitle(`编辑-${localStorageInfo.editCanvasConfig.projectName}`)
content.value = JSONStringify(localStorageInfo)
}
@@ -60,44 +72,75 @@ function back() {
}
// 导入json文本
async function importJSON() {
const files = await showOpenFilePicker()
const file = await files[0].getFile()
const fr = new FileReader()
fr.readAsText(file)
fr.onloadend = () => {
content.value = (fr.result || '').toString()
}
function importJSON() {
goDialog({
message: '导入数据将覆盖内容,此操作不可撤回,是否继续?',
isMaskClosable: true,
transformOrigin: 'center',
onPositiveCallback: async () => {
try {
const files = await showOpenFilePicker()
const file = await files[0].getFile()
const fr = new FileReader()
fr.readAsText(file)
fr.onloadend = () => {
content.value = (fr.result || '').toString()
}
window['$message'].success('导入成功!')
} catch (error) {
window['$message'].error('导入失败,请检查文件是否损坏!')
console.log(error)
}
}
})
}
// 同步 [画布页失去焦点时同步数据到JSON页JSON页Ctrl+S 时同步数据到画布页]
// 同步数据编辑页
window.opener.addEventListener(SavePageEnum.CHART, (e: any) => {
window['$message'].success('正在进行更新...')
setSessionStorage(StorageEnum.GO_CHART_STORAGE_LIST, [e.detail])
content.value = JSONStringify(e.detail)
})
// 窗口失焦 + 保存 => 同步数据
// 保存按钮同步数据
document.addEventListener('keydown', function (e) {
if (e.keyCode == 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
e.preventDefault()
updateSync()
}
})
addEventListener('blur', updateSync)
// 失焦保存(暂时关闭)
// addEventListener('blur', updateSync)
// 同步更新
async function updateSync() {
if (!window.opener) {
return window['$message'].error('源窗口已关闭,视图同步失败')
return window['$message'].error('源窗口已关闭,视图同步失败')
}
try {
const detail = JSONParse(content.value)
delete detail.id
// 保持id不变
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.JSON, { detail }))
} catch (e) {
window['$message'].error('内容格式有误')
console.log(e)
goDialog({
message: '是否覆盖源视图内容? 此操作不可撤!',
isMaskClosable: true,
transformOrigin: 'center',
onPositiveCallback: () => {
try {
const detail = JSONParse(content.value)
delete detail.id
// 保持id不变
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.JSON, { detail }))
window['$message'].success('正在同步内容...')
} catch (e) {
window['$message'].error('内容格式有误')
console.log(e)
}
}
})
}
// 关闭页面发送关闭事件
window.onbeforeunload = () => {
if (window.opener) {
window.opener.dispatchEvent(new CustomEvent(SavePageEnum.CLOSE))
}
}
</script>