Compare commits

..

103 Commits

Author SHA1 Message Date
奔跑的面条
471610963b build: 升级版本到1.2.6 2023-05-28 17:29:19 +08:00
奔跑的面条
f6424245fd Merge branch 'dev' 2023-05-28 17:28:34 +08:00
奔跑的面条
6afbe59828 Merge branch 'dev' 2023-05-28 17:20:36 +08:00
奔跑的面条
adfd8c63e2 !159 地图组件新增卫星地图主题
Merge pull request !159 from tanhao/feat-map-theme
2023-05-24 12:58:20 +00:00
tanhao
11af941590 feat: 在地图组件基础上新增卫星地图主题 2023-05-24 14:44:46 +08:00
奔跑的面条
66e376a87d docs: update 2023-05-13 14:21:49 +08:00
奔跑的面条
318821680a docs: update 2023-05-13 14:19:52 +08:00
奔跑的面条
114fe5626a update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2023-05-13 05:55:38 +00:00
奔跑的面条
afb364b362 docs: add sponsors 2023-05-13 13:52:52 +08:00
奔跑的面条
5c1af11788 build: 升级版本到 1.2.5 2023-05-08 20:42:22 +08:00
奔跑的面条
c953ccd238 Merge branch 'dev' 2023-05-08 20:37:17 +08:00
奔跑的面条
697542f804 perf: 优化发布的提示文案 2023-05-08 20:27:53 +08:00
奔跑的面条
7b9da32215 Merge branch 'dev' 2023-04-23 21:14:43 +08:00
奔跑的面条
9b8cf36135 Merge branch 'dev' 2023-04-23 21:09:21 +08:00
奔跑的面条
465fbf713c fix: update readme 2023-04-11 09:23:33 +08:00
奔跑的面条
3b41bf480c Merge branch 'dev' 2023-04-05 16:39:25 +08:00
奔跑的面条
234755cd34 Merge branch 'dev' 2023-04-03 20:11:09 +08:00
奔跑的面条
c289252546 style: 去除多余代码 2023-04-02 18:16:27 +08:00
奔跑的面条
5207a98ce4 build: 升级版本号到 1.2.4 2023-04-02 18:15:12 +08:00
奔跑的面条
e411cb9b09 style: 去除多余代码 2023-04-02 18:14:22 +08:00
奔跑的面条
a2f32b0289 Merge branch 'dev' 2023-04-02 18:00:55 +08:00
奔跑的面条
5676a323d7 build: 升级版本到1.2.3 2023-03-16 20:51:57 +08:00
奔跑的面条
b435366ac4 Merge branch 'dev' 2023-03-16 20:51:31 +08:00
奔跑的面条
b5738f5cf4 Merge branch 'dev' 2023-03-04 17:32:10 +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
奔跑的面条
22924eb36f !131 feat: 新增轮播图组件
Merge pull request !131 from Ryker/dev
2023-03-04 09:02:34 +00: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
165 changed files with 1315 additions and 4235 deletions

12
.env
View File

@@ -1,8 +1,14 @@
# port # port
VITE_DEV_PORT = '8080' VITE_DEV_PORT = '8001'
# development path # development path
VITE_DEV_PATH = 'https://demo.mtruning.club' VITE_DEV_PATH = '/'
# production 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

243
README.md
View File

@@ -1,119 +1,184 @@
## 总览 #### 总览
**`master-fetch` 分支是带有后端接口请求的分支** <p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)** <h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
**接口说明地址:[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)** #### 长期赞助商
## 使用 <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://fastbee.cn/"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/fb-banner.gif" alt="go-view" style="width: 250px;" width="250px"/>
</a>
<br/>
<br/>
<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>
<span> &nbsp;</span>
<a
href="http://doc.zyplayer.com/#/integrate/zyplayer-doc?utm=goview"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/zyplayer-banner.png" alt="go-view" style="width: 250px;" width="250px"/>
</a>
</div>
</div>
所有的接口地址位置:`src\api\path\*` #### 😶 **纯前端** 分支: **`master`**
接口地址修改:`.env` #### 👻 携带 **后端** 请求分支: **`master-fetch`**
```shell #### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
# port
VITE_DEV_PORT = '8080'
# development path 项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
VITE_DEV_PATH = 'http://127.0.0.1:8080'
# production path 项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
VITE_PRO_PATH = 'http://127.0.0.1:8080'
```
公共前缀修改:`src\settings\httpSetting.ts` Cloud IDE 代码在线预览地址:[https://idegitee.com/dromara/go-view](https://idegitee.com/dromara/go-view)
```shell #### 🤯 后端项目看这里!
// 请求前缀
export const axiosPre = '/api/goview'
```
接口封装:`src\api\http.ts` 后端地址(社区实现,仅供参考):
```ts - `JAVA` [https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve) (当前使用)
import axiosInstance from './axios' - `.NET` [https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum' - `NODE` [https://gitee.com/qwdingyu/led](https://gitee.com/qwdingyu/led)
- `Docker 镜像` [https://gitee.com/AHEAD4/go-view-docker](https://gitee.com/AHEAD4/go-view-docker)
- `接口文档`[https://docs.apipost.cn](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3) (不是最新, 以前端代码为准)
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) => { - 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
return axiosInstance({
url: url,
method: RequestHttpEnum.POST,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const put = (url: string, data?: object, headersType?: string) => { - 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
return axiosInstance({
url: url,
method: RequestHttpEnum.PUT,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const del = (url: string, params?: object) => { - 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
return axiosInstance({
url: url,
method: RequestHttpEnum.DELETE,
params
})
}
// 获取请求函数默认get - 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
export const http = (type?: RequestHttpEnum) => {
switch (type) {
case RequestHttpEnum.GET:
return get
case RequestHttpEnum.POST: - 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
return post
case RequestHttpEnum.PUT: - 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
return put
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 | 4.2.x | NaiveUI | 2.34.x |
| ECharts | 5.3.x | Pinia | 2.0.x |
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
开发环境:
| 名称 | 版本 | 名称 | 版本 |
| ---- | ------- | ------- | ----- |
| node | 16.16.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: 新功能 - feat: 新功能
* fix: 修复 Bug - fix: 修复 Bug
* docs: 文档修改 - docs: 文档修改
* perf: 性能优化 - perf: 性能优化
* revert: 版本回退 - revert: 版本回退
* ci: CICD集成相关 - ci: CICD 集成相关
* test: 添加测试代码 - test: 添加测试代码
* refactor: 代码重构 - refactor: 代码重构
* build: 影响项目构建或依赖修改 - build: 影响项目构建或依赖修改
* style: 不影响程序逻辑的代码修改 - style: 不影响程序逻辑的代码修改
* chore: 不属于以上类型的其他类型(日常事务) - chore: 不属于以上类型的其他类型(日常事务)
## 交流 ## 交流
QQ 群:1030129384 QQ 群:663629294
<img width="260px" src="readme/go-view-qq.png" alt="QQ群" style="border-radius: 20px" />
![QQ群](readme/go-view-qq.png)
![渲染海报](readme/logo-poster.png) ![渲染海报](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,6 +1,6 @@
{ {
"name": "go-view", "name": "go-view",
"version": "2.2.4", "version": "1.2.6",
"engines": { "engines": {
"node": ">=12.0" "node": ">=12.0"
}, },
@@ -21,7 +21,7 @@
"@types/keymaster": "^1.6.30", "@types/keymaster": "^1.6.30",
"@types/lodash": "^4.14.184", "@types/lodash": "^4.14.184",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"axios": "^1.4.0", "axios": "^0.27.2",
"color": "^4.2.3", "color": "^4.2.3",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",

96
pnpm-lock.yaml generated
View File

@@ -1,9 +1,5 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies: dependencies:
'@amap/amap-jsapi-loader': '@amap/amap-jsapi-loader':
specifier: ^1.0.1 specifier: ^1.0.1
@@ -27,8 +23,8 @@ dependencies:
specifier: ^4.1.1 specifier: ^4.1.1
version: 4.1.1 version: 4.1.1
axios: axios:
specifier: ^1.4.0 specifier: ^0.27.2
version: 1.4.0 version: 0.27.2
color: color:
specifier: ^4.2.3 specifier: ^4.2.3
version: 4.2.3 version: 4.2.3
@@ -189,7 +185,7 @@ devDependencies:
version: 1.52.3 version: 1.52.3
sass-loader: sass-loader:
specifier: ^12.6.0 specifier: ^12.6.0
version: 12.6.0(sass@1.52.3)(webpack@5.88.2) version: 12.6.0(sass@1.52.3)(webpack@5.82.1)
typescript: typescript:
specifier: 4.6.3 specifier: 4.6.3
version: 4.6.3 version: 4.6.3
@@ -1200,8 +1196,8 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
dev: true dev: true
/@jridgewell/source-map@0.3.5: /@jridgewell/source-map@0.3.3:
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==}
dependencies: dependencies:
'@jridgewell/gen-mapping': 0.3.3 '@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.18 '@jridgewell/trace-mapping': 0.3.18
@@ -1320,12 +1316,12 @@ packages:
/@types/eslint-scope@3.7.4: /@types/eslint-scope@3.7.4:
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
dependencies: dependencies:
'@types/eslint': 8.44.2 '@types/eslint': 8.37.0
'@types/estree': 1.0.1 '@types/estree': 1.0.1
dev: true dev: true
/@types/eslint@8.44.2: /@types/eslint@8.37.0:
resolution: {integrity: sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==} resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==}
dependencies: dependencies:
'@types/estree': 1.0.1 '@types/estree': 1.0.1
'@types/json-schema': 7.0.11 '@types/json-schema': 7.0.11
@@ -1396,7 +1392,7 @@ packages:
dev: true dev: true
/@types/node@17.0.43: /@types/node@17.0.43:
resolution: {integrity: sha512-jnUpgw8fL9kP2iszfIDyBQtw5Mf4/XSqy0Loc1J9pI14ejL83XcCEvSf50Gs/4ET0I9VCCDoOfufQysj0S66xA==} resolution: {integrity: sha512-jnUpgw8fL9kP2iszfIDyBQtw5Mf4/XSqy0Loc1J9pI14ejL83XcCEvSf50Gs/4ET0I9VCCDoOfufQysj0S66xA==, tarball: https://registry.npm.taobao.org/@types/node/-/node-17.0.43.tgz}
/@types/normalize-package-data@2.4.1: /@types/normalize-package-data@2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -1892,12 +1888,12 @@ packages:
through: 2.3.8 through: 2.3.8
dev: true dev: true
/acorn-import-assertions@1.9.0(acorn@8.7.1): /acorn-import-assertions@1.9.0(acorn@8.8.2):
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
peerDependencies: peerDependencies:
acorn: ^8 acorn: ^8
dependencies: dependencies:
acorn: 8.7.1 acorn: 8.8.2
dev: true dev: true
/acorn-jsx@5.3.2(acorn@8.7.1): /acorn-jsx@5.3.2(acorn@8.7.1):
@@ -1919,14 +1915,14 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/acorn@8.10.0: /acorn@8.7.1:
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
dev: true dev: true
/acorn@8.7.1: /acorn@8.8.2:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
dev: true dev: true
@@ -2068,12 +2064,11 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: false dev: false
/axios@1.4.0: /axios@0.27.2:
resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
dependencies: dependencies:
follow-redirects: 1.15.1 follow-redirects: 1.15.1
form-data: 4.0.0 form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
dev: false dev: false
@@ -2757,7 +2752,7 @@ packages:
dev: false dev: false
/echarts-wordcloud@2.0.0(echarts@5.3.3): /echarts-wordcloud@2.0.0(echarts@5.3.3):
resolution: {integrity: sha512-K7l6pTklqdW7ZWzT/1CS0KhBSINr/cd7c5N1fVMzZMwLQHEwT7x+nivK7g5hkVh7WNcAv4Dn6/ZS5zMKRozC1g==} resolution: {integrity: sha512-K7l6pTklqdW7ZWzT/1CS0KhBSINr/cd7c5N1fVMzZMwLQHEwT7x+nivK7g5hkVh7WNcAv4Dn6/ZS5zMKRozC1g==, tarball: https://registry.npm.taobao.org/echarts-wordcloud/-/echarts-wordcloud-2.0.0.tgz}
peerDependencies: peerDependencies:
echarts: ^5.0.1 echarts: ^5.0.1
dependencies: dependencies:
@@ -2794,8 +2789,8 @@ packages:
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
dev: true dev: true
/enhanced-resolve@5.15.0: /enhanced-resolve@5.14.0:
resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} resolution: {integrity: sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@@ -2846,8 +2841,8 @@ packages:
unbox-primitive: 1.0.2 unbox-primitive: 1.0.2
dev: true dev: true
/es-module-lexer@1.3.0: /es-module-lexer@1.2.1:
resolution: {integrity: sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==} resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==}
dev: true dev: true
/es-shim-unscopables@1.0.0: /es-shim-unscopables@1.0.0:
@@ -3542,7 +3537,6 @@ packages:
/graceful-fs@4.2.11: /graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
requiresBuild: true
dev: true dev: true
/gsap@3.11.3: /gsap@3.11.3:
@@ -4832,10 +4826,6 @@ packages:
asap: 2.0.6 asap: 2.0.6
dev: true dev: true
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/pug-attrs@3.0.0: /pug-attrs@3.0.0:
resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==}
dependencies: dependencies:
@@ -5149,7 +5139,7 @@ packages:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: true dev: true
/sass-loader@12.6.0(sass@1.52.3)(webpack@5.88.2): /sass-loader@12.6.0(sass@1.52.3)(webpack@5.82.1):
resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==} resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==}
engines: {node: '>= 12.13.0'} engines: {node: '>= 12.13.0'}
peerDependencies: peerDependencies:
@@ -5171,7 +5161,7 @@ packages:
klona: 2.0.5 klona: 2.0.5
neo-async: 2.6.2 neo-async: 2.6.2
sass: 1.52.3 sass: 1.52.3
webpack: 5.88.2 webpack: 5.82.1
dev: true dev: true
/sass@1.52.3: /sass@1.52.3:
@@ -5184,8 +5174,8 @@ packages:
source-map-js: 1.0.2 source-map-js: 1.0.2
dev: true dev: true
/schema-utils@3.3.0: /schema-utils@3.1.2:
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==}
engines: {node: '>= 10.13.0'} engines: {node: '>= 10.13.0'}
dependencies: dependencies:
'@types/json-schema': 7.0.11 '@types/json-schema': 7.0.11
@@ -5438,8 +5428,8 @@ packages:
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
/terser-webpack-plugin@5.3.9(webpack@5.88.2): /terser-webpack-plugin@5.3.8(webpack@5.82.1):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} resolution: {integrity: sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==}
engines: {node: '>= 10.13.0'} engines: {node: '>= 10.13.0'}
peerDependencies: peerDependencies:
'@swc/core': '*' '@swc/core': '*'
@@ -5456,19 +5446,19 @@ packages:
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.18 '@jridgewell/trace-mapping': 0.3.18
jest-worker: 27.5.1 jest-worker: 27.5.1
schema-utils: 3.3.0 schema-utils: 3.1.2
serialize-javascript: 6.0.1 serialize-javascript: 6.0.1
terser: 5.19.2 terser: 5.17.3
webpack: 5.88.2 webpack: 5.82.1
dev: true dev: true
/terser@5.19.2: /terser@5.17.3:
resolution: {integrity: sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==} resolution: {integrity: sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg==}
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
dependencies: dependencies:
'@jridgewell/source-map': 0.3.5 '@jridgewell/source-map': 0.3.3
acorn: 8.10.0 acorn: 8.8.2
commander: 2.20.3 commander: 2.20.3
source-map-support: 0.5.21 source-map-support: 0.5.21
dev: true dev: true
@@ -6145,8 +6135,8 @@ packages:
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
dev: true dev: true
/webpack@5.88.2: /webpack@5.82.1:
resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} resolution: {integrity: sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -6160,12 +6150,12 @@ packages:
'@webassemblyjs/ast': 1.11.6 '@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6 '@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.7.1 acorn: 8.8.2
acorn-import-assertions: 1.9.0(acorn@8.7.1) acorn-import-assertions: 1.9.0(acorn@8.8.2)
browserslist: 4.21.5 browserslist: 4.21.5
chrome-trace-event: 1.0.3 chrome-trace-event: 1.0.3
enhanced-resolve: 5.15.0 enhanced-resolve: 5.14.0
es-module-lexer: 1.3.0 es-module-lexer: 1.2.1
eslint-scope: 5.1.1 eslint-scope: 5.1.1
events: 3.3.0 events: 3.3.0
glob-to-regexp: 0.4.1 glob-to-regexp: 0.4.1
@@ -6174,9 +6164,9 @@ packages:
loader-runner: 4.3.0 loader-runner: 4.3.0
mime-types: 2.1.35 mime-types: 2.1.35
neo-async: 2.6.2 neo-async: 2.6.2
schema-utils: 3.3.0 schema-utils: 3.1.2
tapable: 2.2.1 tapable: 2.2.1
terser-webpack-plugin: 5.3.9(webpack@5.88.2) terser-webpack-plugin: 5.3.8(webpack@5.82.1)
watchpack: 2.4.0 watchpack: 2.4.0
webpack-sources: 3.2.3 webpack-sources: 3.2.3
transitivePeerDependencies: transitivePeerDependencies:

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: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -17,7 +17,7 @@
import { NConfigProvider } from 'naive-ui' import { NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider' import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n' import { I18n } from '@/components/I18n'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks' import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
// 暗黑主题 // 暗黑主题
const darkTheme = useDarkThemeHook() const darkTheme = useDarkThemeHook()
@@ -28,9 +28,6 @@ const overridesTheme = useThemeOverridesHook()
// 代码主题 // 代码主题
const hljsTheme = useCode() const hljsTheme = useCode()
// 系统全局数据初始化
useSystemInit()
// 全局语言 // 全局语言
const { locale, dateLocale } = useLang() 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,93 +1,34 @@
import axios, { AxiosResponse, AxiosRequestConfig, Axios, AxiosError, InternalAxiosRequestConfig } from 'axios' import axios, { AxiosResponse, AxiosRequestConfig } from 'axios'
import { RequestHttpHeaderEnum, ResultEnum, ModuleTypeEnum } from '@/enums/httpEnum' import { ResultEnum } from "@/enums/httpEnum"
import { PageEnum, ErrorPageNameMap } from '@/enums/pageEnum' import { ErrorPageNameMap } from "@/enums/pageEnum"
import { StorageEnum } from '@/enums/storageEnum' import { redirectErrorPage } from '@/utils'
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>>
}
const axiosInstance = axios.create({ 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 timeout: ResultEnum.TIMEOUT,
}) as unknown as MyRequestInstance })
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => { (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[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
return config return config
}, },
(err: AxiosError) => { (error: AxiosRequestConfig) => {
Promise.reject(err) Promise.reject(error)
} }
) )
// 响应拦截器 // 响应拦截器
axiosInstance.interceptors.response.use( axiosInstance.interceptors.response.use(
(res: AxiosResponse) => { (res: AxiosResponse) => {
// 预览页面错误不进行处理
if (isPreview()) {
return Promise.resolve(res.data)
}
const { code } = res.data as { code: number } const { code } = res.data as { code: number }
if (code === undefined || code === null) return Promise.resolve(res.data) if (code === undefined || code === null) return Promise.resolve(res.data)
if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
// 成功 // 重定向
if (code === ResultEnum.SUCCESS) { if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
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))
return Promise.resolve(res.data) return Promise.resolve(res.data)
}, },
(err: AxiosError) => { (err: AxiosResponse) => {
const status = err.response?.status Promise.reject(err)
switch (status) {
case 401:
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
Promise.reject(err)
break
default:
Promise.reject(err)
break
}
} }
) )

View File

@@ -9,16 +9,16 @@ import {
} from '@/enums/httpEnum' } from '@/enums/httpEnum'
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d' import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
export const get = <T = any>(url: string, params?: object) => { export const get = (url: string, params?: object) => {
return axiosInstance<T>({ return axiosInstance({
url: url, url: url,
method: RequestHttpEnum.GET, method: RequestHttpEnum.GET,
params: params, params: params
}) })
} }
export const post = <T = any>(url: string, data?: object, headersType?: string) => { export const post = (url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({ return axiosInstance({
url: url, url: url,
method: RequestHttpEnum.POST, method: RequestHttpEnum.POST,
data: data, 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) => { export const patch = (url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({ return axiosInstance({
url: url, url: url,
method: RequestHttpEnum.PATCH, method: RequestHttpEnum.PATCH,
data: data, 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) => { export const put = (url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance<T>({ return axiosInstance({
url: url, url: url,
method: RequestHttpEnum.PUT, method: RequestHttpEnum.PUT,
data: data, 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) => { export const del = (url: string, params?: object) => {
return axiosInstance<T>({ return axiosInstance({
url: url, url: url,
method: RequestHttpEnum.DELETE, method: RequestHttpEnum.DELETE,
params params
@@ -82,11 +82,11 @@ export const http = (type?: RequestHttpEnum) => {
} }
const prefix = 'javascript:' const prefix = 'javascript:'
// 对输入字符进行转义处理 // 对输入字符进行转义处理
export const translateStr = (target: string | Record<any, any>) => { export const translateStr = (target: string | object) => {
if (typeof target === 'string') { if (typeof target === 'string') {
if (target.startsWith(prefix)) { if (target.startsWith(prefix)) {
const funcStr = target.split(prefix)[1] const funcStr = target.split(prefix)[1]
let result let result;
try { try {
result = new Function(`${funcStr}`)() result = new Function(`${funcStr}`)()
} catch (error) { } catch (error) {
@@ -100,8 +100,8 @@ export const translateStr = (target: string | Record<any, any>) => {
} }
for (const key in target) { for (const key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) { if (Object.prototype.hasOwnProperty.call(target, key)) {
const subTarget = target[key] const subTarget = (target as any)[key];
target[key] = translateStr(subTarget) (target as any)[key] = translateStr(subTarget)
} }
} }
return target return target
@@ -163,6 +163,7 @@ export const customizeHttp = (targetParams: RequestConfigType, globalParams: Req
params = translateStr(params) params = translateStr(params)
// form 类型处理 // form 类型处理
let formData: FormData = new FormData() let formData: FormData = new FormData()
formData.set('default', 'defaultData')
// 类型处理 // 类型处理
switch (requestParamsBodyType) { switch (requestParamsBodyType) {

View File

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

View File

@@ -1,99 +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,
fileurl: 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.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

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

View File

@@ -391,12 +391,8 @@ const visualMap = computed(() => {
// 监听legend color颜色改变type = scroll的颜色 // 监听legend color颜色改变type = scroll的颜色
watch(() => legend.value && legend.value.textStyle.color, (newVal) => { watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
if (legend.value && newVal) { if (legend.value && newVal) {
if (!legend.value.pageTextStyle) { legend.value.pageTextStyle.color = newVal
legend.value.pageTextStyle = { color: newVal } }
} else {
legend.value.pageTextStyle.color = newVal
}
}
}, { }, {
immediate: true, immediate: true,
deep: true, deep: true,

View File

@@ -69,22 +69,6 @@
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<!-- 预设滤镜 -->
<div v-if="presetImageList.length" class="preset-filter">
<n-image
class="preset-img"
width="46"
preview-disabled
object-fit="scale-down"
v-for="(item, index) in presetImageList"
:key="index"
:class="{ 'active-preset': item.hueRotate === chartStyles.hueRotate }"
:style="{ filter: `hue-rotate(${item.hueRotate}deg)` }"
:src="item.src"
@click="() => (chartStyles.hueRotate = item.hueRotate)"
></n-image>
</div>
<!-- 混合模式 --> <!-- 混合模式 -->
<setting-item-box v-if="!isCanvas" :alone="true"> <setting-item-box v-if="!isCanvas" :alone="true">
<template #name> <template #name>
@@ -165,12 +149,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, PropType } from 'vue' import { PropType } from 'vue'
import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d' import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d'
import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting' import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import logoImg from '@/assets/logo.png'
import { useDesignStore } from '@/store/modules/designStore/designStore'
const props = defineProps({ const props = defineProps({
isGroup: { isGroup: {
@@ -193,48 +175,10 @@ const { HelpOutlineIcon } = icon.ionicons5
const sliderFormatTooltip = (v: string) => { const sliderFormatTooltip = (v: string) => {
return `${(parseFloat(v) * 100).toFixed(0)}%` return `${(parseFloat(v) * 100).toFixed(0)}%`
} }
// 角度格式化 // 角度格式化
const degFormatTooltip = (v: string) => { const degFormatTooltip = (v: string) => {
return `${v}deg` return `${v}deg`
} }
// 预设滤镜
interface presetImageData {
index: number
src: string
hueRotate: number
}
const presetImageList = ref([] as presetImageData[])
for (let i = 1; i <= 12; i++) {
presetImageList.value.push({
index: i,
src: logoImg,
hueRotate: i * 30
})
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
// 预设滤镜
.preset-filter {
margin: 20px 0 10px 0;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.preset-img {
margin-bottom: 10px;
padding: 2px;
border-radius: 6px;
transition: 0.2s all;
cursor: pointer;
&:hover {
box-shadow: 0 0 0 2px #66a9c9;
}
}
.active-preset {
box-shadow: 0 0 0 2px #66a9c9;
}
}
</style>

View File

@@ -48,6 +48,7 @@ export enum MenuEnum {
UN_GROUP = 'unGroup', UN_GROUP = 'unGroup',
// 后退 // 后退
BACK = 'back', BACK = 'back',
// 前进
FORWORD = 'forward', FORWORD = 'forward',
// 保存 // 保存
SAVE = 'save', SAVE = 'save',
@@ -83,15 +84,3 @@ export enum MacKeyboard {
ALT_SOURCE_KEY = '⌥', ALT_SOURCE_KEY = '⌥',
SPACE = 'Space' SPACE = 'Space'
} }
// 同步状态枚举
export enum SyncEnum {
// 等待
PENDING,
// 开始
START,
// 成功
SUCCESS,
// 失败
FAILURE
}

View File

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

View File

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

View File

@@ -1,8 +1,10 @@
export enum StorageEnum { 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', GO_LANG_STORE = 'GO_LANG',
// 当前选择的主题 // 当前选择的主题

View File

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

View File

@@ -90,7 +90,7 @@ export const useChartDataFetch = (
// 普通初始化与组件交互处理监听 // 普通初始化与组件交互处理监听
watch( watch(
() => targetComponent.request.requestParams, () => targetComponent.request,
() => { () => {
fetchFn() fetchFn()
}, },
@@ -105,11 +105,7 @@ export const useChartDataFetch = (
// 单位 // 单位
const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
// 开启轮询 // 开启轮询
if (time) { if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
} else {
fetchFn()
}
} }
// eslint-disable-next-line no-empty // eslint-disable-next-line no-empty
} catch (error) { } catch (error) {
@@ -118,11 +114,10 @@ export const useChartDataFetch = (
} }
if (isPreview()) { if (isPreview()) {
// 判断是否是数据池类型
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle) ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
: requestIntervalFn() : requestIntervalFn()
} else {
requestIntervalFn()
} }
return { vChartRef } return { vChartRef }
} }

View File

@@ -1,4 +1,4 @@
import { toRaw, watch, computed, ComputedRef } from 'vue' import { toRaw } from 'vue'
import { customizeHttp } from '@/api/http' import { customizeHttp } from '@/api/http'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -20,7 +20,7 @@ const mittDataPondMap = new Map<string, DataPondMapType[]>()
// 创建单个数据项轮询接口 // 创建单个数据项轮询接口
const newPondItemInterval = ( const newPondItemInterval = (
requestGlobalConfig: RequestGlobalConfigType, requestGlobalConfig: RequestGlobalConfigType,
requestDataPondItem: ComputedRef<RequestDataPondItemType>, requestDataPondItem: RequestDataPondItemType,
dataPondMapItem?: DataPondMapType[] dataPondMapItem?: DataPondMapType[]
) => { ) => {
if (!dataPondMapItem) return if (!dataPondMapItem) return
@@ -31,7 +31,8 @@ const newPondItemInterval = (
// 请求 // 请求
const fetchFn = async () => { const fetchFn = async () => {
try { try {
const res = await customizeHttp(toRaw(requestDataPondItem.value.dataPondRequestConfig), toRaw(requestGlobalConfig)) const res = await customizeHttp(toRaw(requestDataPondItem.dataPondRequestConfig), toRaw(requestGlobalConfig))
if (res) { if (res) {
try { try {
// 遍历更新回调函数 // 遍历更新回调函数
@@ -48,32 +49,19 @@ const newPondItemInterval = (
} }
} }
watch(
() => requestDataPondItem.value.dataPondRequestConfig.requestParams.Params,
() => {
fetchFn()
},
{
immediate: false,
deep: true
}
)
// 立即调用 // 立即调用
fetchFn() fetchFn()
const targetInterval = requestDataPondItem.dataPondRequestConfig.requestInterval
const targetInterval = requestDataPondItem.value.dataPondRequestConfig.requestInterval const targetUnit = requestDataPondItem.dataPondRequestConfig.requestIntervalUnit
const targetUnit = requestDataPondItem.value.dataPondRequestConfig.requestIntervalUnit
const globalRequestInterval = requestGlobalConfig.requestInterval const globalRequestInterval = requestGlobalConfig.requestInterval
const globalUnit = requestGlobalConfig.requestIntervalUnit const globalUnit = requestGlobalConfig.requestIntervalUnit
// 定时时间 // 定时时间
const time = targetInterval ? targetInterval : globalRequestInterval const time = targetInterval ? targetInterval : globalRequestInterval
// 单位 // 单位
const unit = targetInterval ? targetUnit : globalUnit const unit = targetInterval ? targetUnit : globalUnit
// 开启轮询 // 开启轮询
if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit)) if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
} }
@@ -108,16 +96,13 @@ export const useChartDataPondFetch = () => {
} }
// 初始化数据池 // 初始化数据池
const initDataPond = (useChartEditStore: ChartEditStoreType) => { const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => {
const { requestGlobalConfig } = useChartEditStore() const { requestDataPond } = requestGlobalConfig
const chartEditStore = useChartEditStore()
// 根据 mapId 查找对应的数据池配置 // 根据 mapId 查找对应的数据池配置
for (let pondKey of mittDataPondMap.keys()) { for (let pondKey of mittDataPondMap.keys()) {
const requestDataPondItem = computed(() => { const requestDataPondItem = requestDataPond.find(item => item.dataPondId === pondKey)
return requestGlobalConfig.requestDataPond.find(item => item.dataPondId === pondKey)
}) as ComputedRef<RequestDataPondItemType>
if (requestDataPondItem) { if (requestDataPondItem) {
newPondItemInterval(chartEditStore.requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey)) newPondItemInterval(requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
} }
} }
} }

View File

@@ -1,5 +1,4 @@
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { isPreview } from '@/utils'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
@@ -13,7 +12,6 @@ export const useChartInteract = (
param: { [T: string]: any }, param: { [T: string]: any },
interactEventOn: string interactEventOn: string
) => { ) => {
if (!isPreview()) return
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
const { interactEvents } = chartConfig.events const { interactEvents } = chartConfig.events
const fnOnEvent = interactEvents.filter(item => { const fnOnEvent = interactEvents.filter(item => {
@@ -22,37 +20,20 @@ export const useChartInteract = (
if (fnOnEvent.length === 0) return if (fnOnEvent.length === 0) return
fnOnEvent.forEach(item => { fnOnEvent.forEach(item => {
const index = chartEditStore.fetchTargetIndex(item.interactComponentId)
const globalConfigPindAprndex = chartEditStore.requestGlobalConfig.requestDataPond.findIndex(cItem => if (index === -1) return
cItem.dataPondId === item.interactComponentId const { Params, Header } = toRefs(chartEditStore.componentList[index].request.requestParams)
) Object.keys(item.interactFn).forEach(key => {
if (globalConfigPindAprndex !== -1) { if (Params.value[key]) {
const { Params, Header } = toRefs(chartEditStore.requestGlobalConfig.requestDataPond[globalConfigPindAprndex].dataPondRequestConfig.requestParams) Params.value[key] = param[item.interactFn[key]]
}
Object.keys(item.interactFn).forEach(key => { if (Header.value[key]) {
if (key in Params.value) { Header.value[key] = param[item.interactFn[key]]
Params.value[key] = param[item.interactFn[key]] }
} })
if (key in Header.value) {
Header.value[key] = param[item.interactFn[key]]
}
})
} else {
const index = chartEditStore.fetchTargetIndex(item.interactComponentId)
if (index === -1) return
const { Params, Header } = toRefs(chartEditStore.componentList[index].request.requestParams)
Object.keys(item.interactFn).forEach(key => {
if (key in Params.value) {
Params.value[key] = param[item.interactFn[key]]
}
if (key in Header.value) {
Header.value[key] = param[item.interactFn[key]]
}
})
}
}) })
} }
// 联动事件触发的 type 变更时,清除当前绑定内容 // 联动事件触发的 type 变更时,清除当前绑定内容
export const clearInteractEvent = (chartConfig: CreateComponentType) => { export const clearInteractEvent = (chartConfig: CreateComponentType) => {

View File

@@ -48,10 +48,10 @@ export const useLifeHandler = (chartConfig: CreateComponentType | CreateComponen
try { try {
return new Function(` return new Function(`
return ( return (
async function(components,mouseEvent){ async function(mouseEvent){
${fnStr} ${fnStr}
} }
)`)().bind(undefined,components) )`)()
} catch (error) { } catch (error) {
console.error(error) console.error(error)
} }

View File

@@ -1,218 +1,218 @@
import throttle from 'lodash/throttle' import throttle from 'lodash/throttle'
// 拆出来是为了更好的分离单独复用 // 拆出来是为了更好的分离单独复用
// * 屏幕缩放适配(两边留白) // * 屏幕缩放适配(两边留白)
export const usePreviewFitScale = ( export const usePreviewFitScale = (
width: number, width: number,
height: number, height: number,
scaleDom: HTMLElement | null, scaleDom: HTMLElement | null,
callback?: (scale: { callback?: (scale: {
width: number; width: number;
height: number; height: number;
}) => void }) => void
) => { ) => {
// * 画布尺寸px // * 画布尺寸px
const baseWidth = width const baseWidth = width
const baseHeight = height const baseHeight = height
// * 默认缩放值 // * 默认缩放值
const scale = { const scale = {
width: 1, width: 1,
height: 1, height: 1,
} }
// * 需保持的比例 // * 需保持的比例
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
const calcRate = () => { const calcRate = () => {
// 当前屏幕宽高比 // 当前屏幕宽高比
const currentRate = parseFloat( const currentRate = parseFloat(
(window.innerWidth / window.innerHeight).toFixed(5) (window.innerWidth / window.innerHeight).toFixed(5)
) )
if (scaleDom) { if (scaleDom) {
if (currentRate > baseProportion) { if (currentRate > baseProportion) {
// 表示更宽 // 表示更宽
scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5))
scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5))
scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` scaleDom.style.transform = `scale(${scale.width}, ${scale.height})`
} else { } else {
// 表示更高 // 表示更高
scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5))
scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5))
scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` scaleDom.style.transform = `scale(${scale.width}, ${scale.height})`
} }
if (callback) callback(scale) if (callback) callback(scale)
} }
} }
const resize = throttle(() => { const resize = throttle(() => {
calcRate() calcRate()
}, 200) }, 200)
// * 改变窗口大小重新绘制 // * 改变窗口大小重新绘制
const windowResize = () => { const windowResize = () => {
window.addEventListener('resize', resize) window.addEventListener('resize', resize)
} }
// * 卸载监听 // * 改变窗口大小重新绘制
const unWindowResize = () => { const unWindowResize = () => {
window.removeEventListener('resize', resize) window.removeEventListener('resize', resize)
} }
return { return {
calcRate, calcRate,
windowResize, windowResize,
unWindowResize, unWindowResize,
} }
} }
// * X轴撑满Y轴滚动条 // * X轴撑满Y轴滚动条
export const usePreviewScrollYScale = ( export const usePreviewScrollYScale = (
width: number, width: number,
height: number, height: number,
scaleDom: HTMLElement | null, scaleDom: HTMLElement | null,
callback?: (scale: { callback?: (scale: {
width: number; width: number;
height: number; height: number;
}) => void }) => void
) => { ) => {
// * 画布尺寸px // * 画布尺寸px
const baseWidth = width const baseWidth = width
const baseHeight = height const baseHeight = height
// * 默认缩放值 // * 默认缩放值
const scale = { const scale = {
width: 1, width: 1,
height: 1, height: 1,
} }
// * 需保持的比例 // * 需保持的比例
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
const calcRate = () => { const calcRate = () => {
if (scaleDom) { if (scaleDom) {
scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5)) scale.height = parseFloat(((window.innerWidth / baseProportion) / baseHeight).toFixed(5))
scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5)) scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5))
scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` scaleDom.style.transform = `scale(${scale.width}, ${scale.height})`
if (callback) callback(scale) if (callback) callback(scale)
} }
} }
const resize = throttle(() => { const resize = throttle(() => {
calcRate() calcRate()
}, 200) }, 200)
// * 改变窗口大小重新绘制 // * 改变窗口大小重新绘制
const windowResize = () => { const windowResize = () => {
window.addEventListener('resize', resize) window.addEventListener('resize', resize)
} }
// * 卸载监听 // * 改变窗口大小重新绘制
const unWindowResize = () => { const unWindowResize = () => {
window.removeEventListener('resize', resize) window.removeEventListener('resize', resize)
} }
return { return {
calcRate, calcRate,
windowResize, windowResize,
unWindowResize, unWindowResize,
} }
} }
// * Y轴撑满X轴滚动条 // * Y轴撑满X轴滚动条
export const usePreviewScrollXScale = ( export const usePreviewScrollXScale = (
width: number, width: number,
height: number, height: number,
scaleDom: HTMLElement | null, scaleDom: HTMLElement | null,
callback?: (scale: { callback?: (scale: {
width: number; width: number;
height: number; height: number;
}) => void }) => void
) => { ) => {
// * 画布尺寸px // * 画布尺寸px
const baseWidth = width const baseWidth = width
const baseHeight = height const baseHeight = height
// * 默认缩放值 // * 默认缩放值
const scale = { const scale = {
height: 1, height: 1,
width: 1, width: 1,
} }
// * 需保持的比例 // * 需保持的比例
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
const calcRate = () => { const calcRate = () => {
if (scaleDom) { if (scaleDom) {
scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5)) scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5))
scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5)) scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5))
scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` scaleDom.style.transform = `scale(${scale.width}, ${scale.height})`
if (callback) callback(scale) if (callback) callback(scale)
} }
} }
const resize = throttle(() => { const resize = throttle(() => {
calcRate() calcRate()
}, 200) }, 200)
// * 改变窗口大小重新绘制 // * 改变窗口大小重新绘制
const windowResize = () => { const windowResize = () => {
window.addEventListener('resize', resize) window.addEventListener('resize', resize)
} }
// * 卸载监听 // * 改变窗口大小重新绘制
const unWindowResize = () => { const unWindowResize = () => {
window.removeEventListener('resize', resize) window.removeEventListener('resize', resize)
} }
return { return {
calcRate, calcRate,
windowResize, windowResize,
unWindowResize, unWindowResize,
} }
} }
// * 变形内容,宽高铺满 // * 变形内容,宽高铺满
export const usePreviewFullScale = ( export const usePreviewFullScale = (
width: number, width: number,
height: number, height: number,
scaleDom: HTMLElement | null, scaleDom: HTMLElement | null,
callback?: (scale: { callback?: (scale: {
width: number; width: number;
height: number; height: number;
}) => void }) => void
) => { ) => {
// * 默认缩放值 // * 默认缩放值
const scale = { const scale = {
width: 1, width: 1,
height: 1, height: 1,
} }
const calcRate = () => { const calcRate = () => {
if (scaleDom) { if (scaleDom) {
scale.width = parseFloat((window.innerWidth / width).toFixed(5)) scale.width = parseFloat((window.innerWidth / width).toFixed(5))
scale.height = parseFloat((window.innerHeight / height).toFixed(5)) scale.height = parseFloat((window.innerHeight / height).toFixed(5))
scaleDom.style.transform = `scale(${scale.width}, ${scale.height})` scaleDom.style.transform = `scale(${scale.width}, ${scale.height})`
if (callback) callback(scale) if (callback) callback(scale)
} }
} }
const resize = throttle(() => { const resize = throttle(() => {
calcRate() calcRate()
}, 200) }, 200)
// * 改变窗口大小重新绘制 // * 改变窗口大小重新绘制
const windowResize = () => { const windowResize = () => {
window.addEventListener('resize', resize) window.addEventListener('resize', resize)
} }
// * 卸载监听 // * 改变窗口大小重新绘制
const unWindowResize = () => { const unWindowResize = () => {
window.removeEventListener('resize', resize) window.removeEventListener('resize', resize)
} }
return { return {
calcRate, calcRate,
windowResize, windowResize,
unWindowResize, unWindowResize,
} }
} }

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', help: 'Help',
contact: 'About Software', contact: 'About Software',
logout: 'Logout', logout: 'Logout',
logout_success: 'Logout success',
logout_failure: 'Logout Failed',
// system setting // system setting
sys_set: 'System Setting', sys_set: 'System Setting',
lang_set: 'Language Setting', lang_set: 'Language Setting',
@@ -28,14 +26,8 @@ const global = {
r_more: 'More', 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 { export default {
global, global,
http,
login, login,
project project
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,75 +0,0 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { BarLineConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
// 柱状折线组合图 分别定义series
// 写死name可以定义legend显示的名称
export const barSeriesItem = {
type: 'bar',
barWidth: 15,
label: {
show: true,
position: 'top',
color: '#fff',
fontSize: 12
},
itemStyle: {
color: null,
borderRadius: 2
}
}
export const lineSeriesItem = {
type: 'line',
symbol: 'circle',
label: {
show: true,
position: 'top',
color: '#fff',
fontSize: 12
},
symbolSize: 5, //设定实心点的大小
itemStyle: {
color: '#FFE47A',
borderWidth: 1
},
lineStyle: {
type: 'solid',
width: 3,
color: null
}
}
export const option = {
tooltip: {
show: true,
trigger: 'axis',
axisPointer: {
show: true,
type: 'shadow'
}
},
legend: {
data: null
},
xAxis: {
show: true,
type: 'category'
},
yAxis: {
show: true,
type: 'value'
},
dataset: { ...dataJson },
series: [barSeriesItem, lineSeriesItem]
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = BarLineConfig.key
public chartConfig = cloneDeep(BarLineConfig)
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -1,93 +0,0 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem
v-for="(item, index) in seriesList"
:key="index"
:name="`${item.type == 'bar' ? '柱状图' : '折线图'}`"
:expanded="true"
>
<SettingItemBox name="图形" v-if="item.type == 'bar'">
<SettingItem name="宽度">
<n-input-number
v-model:value="item.barWidth"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="圆角">
<n-input-number v-model:value="item.itemStyle.borderRadius" :min="0" size="small"></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="线条" v-if="item.type == 'line'">
<SettingItem name="宽度">
<n-input-number
v-model:value="item.lineStyle.width"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="类型">
<n-select v-model:value="item.lineStyle.type" size="small" :options="lineConf.lineStyle.type"></n-select>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="实心点" v-if="item.type == 'line'">
<SettingItem name="大小">
<n-input-number
v-model:value="item.symbolSize"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
</SettingItemBox>
<setting-item-box name="标签">
<setting-item>
<n-space>
<n-switch v-model:value="item.label.show" size="small" />
<n-text>展示标签</n-text>
</n-space>
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item name="tip颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker>
</setting-item>
<setting-item name="位置">
<n-select
v-model:value="item.label.position"
:options="[
{ label: 'top', value: 'top' },
{ label: 'left', value: 'left' },
{ label: 'right', value: 'right' },
{ label: 'bottom', value: 'bottom' }
]"
/>
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { lineConf } from '@/packages/chartConfiguration/echarts'
import { GlobalThemeJsonType } from '@/settings/chartThemes'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const seriesList = computed(() => {
return props.optionData.series
})
</script>

View File

@@ -1,40 +0,0 @@
{
"dimensions": ["product", "data1", "data2"],
"source": [
{
"product": "1月",
"data1": 104,
"data2": 30
},
{
"product": "2月",
"data1": 56,
"data2": 56
},
{
"product": "3月",
"data1": 136,
"data2": 36
},
{
"product": "4月",
"data1": 86,
"data2": 6
},
{
"product": "5月",
"data1": 98,
"data2": 10
},
{
"product": "6月",
"data1": 86,
"data2": 70
},
{
"product": "7月",
"data1": 77,
"data2": 57
}
]
}

View File

@@ -1,16 +0,0 @@
// 公共类型声明
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
// 当前[信息模块]分类声明
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const BarLineConfig: ConfigType = {
key: 'BarLine',
chartKey: 'VBarLine',
conKey: 'VCBarLine',
title: '柱状图 & 折线图',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.ECHARTS,
image: 'bar_line.png'
}

View File

@@ -1,73 +0,0 @@
<template>
<v-chart
ref="vChartRef"
:init-options="initOptions"
:theme="themeColor"
:option="option"
:manual-update="isPreview()"
autoresize
></v-chart>
</template>
<script setup lang="ts">
import { ref, computed, watch, PropType, nextTick } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
//引入柱状图 折线图
import { BarChart, LineChart } from 'echarts/charts'
import config, { includes, barSeriesItem, lineSeriesItem } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([DatasetComponent, CanvasRenderer, BarChart, LineChart, GridComponent, TooltipComponent, LegendComponent])
const replaceMergeArr = ref<string[]>()
const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
})
watch(
() => props.chartConfig.option.dataset,
(newData, oldData) => {
if (newData.dimensions.length !== oldData.dimensions.length) {
const seriesArr = []
for (let i = 0; i < newData.dimensions.length - 1; i++) {
seriesArr.push(barSeriesItem, lineSeriesItem)
}
replaceMergeArr.value = ['series']
props.chartConfig.option.series = seriesArr
nextTick(() => {
replaceMergeArr.value = []
})
}
},
{
deep: false
}
)
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
</script>

View File

@@ -1,6 +1,5 @@
import { BarCommonConfig } from './BarCommon/index' import { BarCommonConfig } from './BarCommon/index'
import { BarCrossrangeConfig } from './BarCrossrange/index' import { BarCrossrangeConfig } from './BarCrossrange/index'
import { CapsuleChartConfig } from './CapsuleChart/index' import { CapsuleChartConfig } from './CapsuleChart/index'
import { BarLineConfig } from './BarLine/index'
export default [BarCommonConfig, BarCrossrangeConfig, CapsuleChartConfig]
export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig]

View File

@@ -33,10 +33,6 @@ export const option = {
width: 3, width: 3,
color: { color: {
type: 'linear', type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [ colorStops: [
{ {
offset: 0, offset: 0,

View File

@@ -84,10 +84,7 @@ export const option = {
shadowColor: '#E1FFFF', shadowColor: '#E1FFFF',
shadowBlur: 10 shadowBlur: 10
}, },
data: [], data: []
encode: {
value: 2
}
}, },
{ {
name: '区域', name: '区域',

View File

@@ -3,7 +3,7 @@
:type="type" :type="type"
:height="h" :height="h"
:processing="processing" :processing="processing"
:percentage="dataset" :percentage="option.dataset"
:indicator-placement="indicatorPlacement" :indicator-placement="indicatorPlacement"
:color="color" :color="color"
:rail-color="railColor" :rail-color="railColor"
@@ -15,7 +15,7 @@
fontSize: `${indicatorTextSize}px` fontSize: `${indicatorTextSize}px`
}" }"
> >
{{ dataset }} {{ unit }} {{ option.dataset }} {{ unit }}
</n-text> </n-text>
</n-progress> </n-progress>
</template> </template>

View File

@@ -7,22 +7,6 @@
</n-input-number> </n-input-number>
</SettingItem> </SettingItem>
</SettingItemBox> </SettingItemBox>
<!-- 中心标题 -->
<SettingItemBox v-if="config.title" name="标题">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number
v-model:value="config.title.textStyle.fontSize"
:min="0"
:step="1"
size="small"
placeholder="字体大小"
>
</n-input-number>
</SettingItem>
</SettingItemBox>
<!-- Echarts 全局设置 --> <!-- Echarts 全局设置 -->
<SettingItemBox name="进度条"> <SettingItemBox name="进度条">
<SettingItem name="颜色"> <SettingItem name="颜色">
@@ -47,8 +31,24 @@
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
</SettingItemBox> </SettingItemBox>
<!-- 中心标题 -->
<SettingItemBox v-if="config.title" name="标题">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number
v-model:value="config.title.textStyle.fontSize"
:min="0"
:step="1"
size="small"
placeholder="字体大小"
>
</n-input-number>
</SettingItem>
</SettingItemBox>
<!-- 其他样式 --> <!-- 其他样式 -->
<SettingItemBox name="轨道"> <SettingItemBox name="轨道样式">
<SettingItem name="颜色"> <SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker> <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker>
</SettingItem> </SettingItem>
@@ -69,18 +69,6 @@
v-model:value="item.data[1].itemStyle.shadowColor" v-model:value="item.data[1].itemStyle.shadowColor"
></n-color-picker> ></n-color-picker>
</SettingItem> </SettingItem>
<SettingItem name="轨道宽度">
<n-select
v-model:value="item.radius[0]"
size="small"
:options="[
{ label: '窄', value: '75%' },
{ label: '中', value: '60%' },
{ label: '宽', value: '45%' },
{ label: '更宽', value: '30%' }
]"
/>
</SettingItem>
</SettingItemBox> </SettingItemBox>
</CollapseItem> </CollapseItem>
</template> </template>

View File

@@ -41,7 +41,7 @@ const option = reactive({
const dataHandle = (newData: any) => { const dataHandle = (newData: any) => {
const d = parseFloat(`${newData}`) * 100 const d = parseFloat(`${newData}`) * 100
let config = props.chartConfig.option let config = props.chartConfig.option
config.title.text = `${+d.toFixed(2)}%` config.title.text = d.toFixed(2) + '%'
config.series[0].data[0].value[0] = d config.series[0].data[0].value[0] = d
config.series[0].data[1].value[0] = 100 - d config.series[0].data[1].value[0] = 100 - d
option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
@@ -68,7 +68,7 @@ watch(
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => { useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
let d = parseFloat(`${resData}`) * 100 let d = parseFloat(`${resData}`) * 100
// @ts-ignore // @ts-ignore
option.value.title.text = `${+d.toFixed(2)}%` option.value.title.text = d.toFixed(2) + '%'
// @ts-ignore // @ts-ignore
option.value.series[0].data[0].value[0] = d option.value.series[0].data[0].value[0] = d
// @ts-ignore // @ts-ignore

View File

@@ -14,6 +14,5 @@ export enum ChatCategoryEnumName {
LINE = '折线图', LINE = '折线图',
SCATTER = '散点图', SCATTER = '散点图',
MAP = '地图', MAP = '地图',
COMBINATION = '组合图',
MORE = '更多' MORE = '更多'
} }

View File

@@ -63,7 +63,7 @@ watch(
() => props.chartConfig.option, () => props.chartConfig.option,
newVal => { newVal => {
try { try {
updateDatasetHandler((newVal as any as OptionType).dataset) updateDatasetHandler((newVal as OptionType).dataset)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }

View File

@@ -1,18 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { FullScreenConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
border: 6,
bgColor: '#84a5e9',
borderColor: '#84a5e9'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = FullScreenConfig.key
public attr = { ...chartInitConfig, w: 150, h: 150, zIndex: -1 }
public chartConfig = cloneDeep(FullScreenConfig)
public option = cloneDeep(option)
}

View File

@@ -1,28 +0,0 @@
<template>
<CollapseItem name="全屏按钮" expanded>
<SettingItemBox name="按钮">
<SettingItem name="背景色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.bgColor"></n-color-picker>
</SettingItem>
<SettingItem name="边框色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.borderColor"></n-color-picker>
</SettingItem>
<SettingItem name="边框大小">
<n-input-number v-model:value="optionData.border" size="small" :step="0.5" :min="0"></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const FullScreenConfig: ConfigType = {
key: 'FullScreen',
chartKey: 'VFullScreen',
conKey: 'VCFullScreen',
title: '全屏按钮',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.STATIC,
image: 'fullScreen.png'
}

View File

@@ -1,111 +0,0 @@
<template>
<svg @click="toggleFullscreen" v-if="!isFullscreen" viewBox="0 0 1024 1024">
<path
d="M665.6 1017.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h268.8l6.4-268.8c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v294.4c0 32-25.6 51.2-51.2 51.2h-300.8zM51.2 396.8c-19.2 0-38.4-19.2-38.4-38.4V64C12.8 32 38.4 12.8 64 12.8h294.4c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H89.6v268.8c0 19.2-19.2 38.4-38.4 38.4zM64 1017.6c-32 0-51.2-25.6-51.2-51.2v-294.4c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v217.6l198.4-198.4c6.4-6.4 19.2-12.8 25.6-12.8s19.2 6.4 25.6 12.8c6.4 6.4 12.8 19.2 12.8 25.6 0 12.8-6.4 19.2-12.8 25.6l-198.4 198.4h217.6c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H64z m915.2-620.8c-19.2 0-38.4-19.2-38.4-38.4V140.8l-198.4 198.4c-6.4 6.4-19.2 12.8-25.6 12.8-12.8 0-19.2-6.4-25.6-12.8-12.8-12.8-12.8-38.4 0-51.2l198.4-198.4h-217.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h294.4c32 0 51.2 25.6 51.2 51.2v294.4c0 19.2-19.2 38.4-38.4 38.4z"
class="fullScreen-border"
></path>
</svg>
<svg @click="toggleFullscreen" v-else viewBox="0 0 1024 1024">
<path
d="M379.336 697.237L153.362 921.55c-14.11 14.007-36.905 13.922-50.912-0.188-14.007-14.11-13.922-36.905 0.188-50.912l227.6-225.927H138.645c-18.99 0-34.385-15.446-34.385-34.5 0-19.053 15.395-34.5 34.385-34.5H413.72c18.99 0 34.384 15.447 34.384 34.5v276c0 9.15-3.622 17.926-10.07 24.396a34.326 34.326 0 0 1-24.314 10.104 34.326 34.326 0 0 1-24.314-10.104 34.559 34.559 0 0 1-10.071-24.396V697.237z m263.395-366.88l227.813-227.813c14.059-14.059 36.853-14.059 50.912 0 14.059 14.059 14.059 36.853 0 50.912l-225.18 225.18h187.147c18.99 0 34.385 15.445 34.385 34.5 0 19.053-15.395 34.5-34.385 34.5H608.346c-18.99 0-34.384-15.447-34.384-34.5v-276c0-9.15 3.622-17.926 10.07-24.396a34.326 34.326 0 0 1 24.314-10.105c9.12 0 17.865 3.635 24.314 10.105a34.559 34.559 0 0 1 10.07 24.395v193.223zM99.385 410a34.326 34.326 0 0 1-24.314-10.105A34.559 34.559 0 0 1 65 375.5v-276C65 80.446 80.395 65 99.385 65h275.077c18.99 0 34.384 15.446 34.384 34.5 0 19.054-15.394 34.5-34.384 34.5H133.769v241.5c0 9.15-3.622 17.925-10.07 24.395A34.326 34.326 0 0 1 99.384 410z m825.23 552H649.538c-18.99 0-34.384-15.446-34.384-34.5 0-19.054 15.394-34.5 34.384-34.5h240.693V651.5c0-19.054 15.394-34.5 34.384-34.5 18.99 0 34.385 15.446 34.385 34.5v276c0 19.054-15.395 34.5-34.385 34.5z"
class="fullScreen-border"
></path>
</svg>
</template>
<script setup lang="ts">
import { PropType, toRefs, ref, onMounted, onUnmounted } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { option } from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType & typeof option>,
required: true
}
})
let { border, bgColor, borderColor } = toRefs(props.chartConfig.option)
const isFullscreen = ref(false)
const checkFullscreen = () => {
isFullscreen.value = !!(
document.fullscreenElement ||
(document as any).webkitFullscreenElement ||
(document as any).mozFullScreenElement ||
(document as any).msFullscreenElement
)
}
checkFullscreen()
const requestFullscreen = (element: Element) => {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if ((document as any).mozRequestFullScreen) {
/* Firefox */
(document as any).mozRequestFullScreen()
} else if ((document as any).webkitRequestFullscreen) {
/* Chrome, Safari and Opera */
(document as any).webkitRequestFullscreen()
} else if ((document as any).msRequestFullscreen) {
/* IE/Edge */
(document as any).msRequestFullscreen()
}
}
const exitFullscreen = () => {
if (document.fullscreenElement && document.exitFullscreen) {
document.exitFullscreen()
} else if ((document as any).mozFullScreenElement && (document as any).mozCancelFullScreen) {
/* Firefox */
(document as any).mozCancelFullScreen()
} else if ((document as any).webkitFullscreenElement && (document as any).webkitExitFullscreen) {
/* Chrome, Safari and Opera */
(document as any).webkitExitFullscreen()
} else if ((document as any).msFullscreenElement && (document as any).msExitFullscreen) {
/* IE/Edge */
(document as any).msExitFullscreen()
}
}
const toggleFullscreen = () => {
if (!isFullscreen.value) {
requestFullscreen(document.documentElement)
} else {
exitFullscreen()
}
isFullscreen.value = !isFullscreen.value
// 由于全屏状态的改变不会立即生效,所以需要延迟一段时间再去获取全屏状态
setTimeout(() => {
checkFullscreen()
}, 1000)
}
// 监听全屏状态的改变,保证多个全屏组件的状态一致
onMounted(() => {
document.addEventListener('fullscreenchange', checkFullscreen)
document.addEventListener('webkitfullscreenchange', checkFullscreen)
document.addEventListener('mozfullscreenchange', checkFullscreen)
document.addEventListener('MSFullscreenChange', checkFullscreen)
})
onUnmounted(() => {
document.removeEventListener('fullscreenchange', checkFullscreen)
document.removeEventListener('webkitfullscreenchange', checkFullscreen)
document.removeEventListener('mozfullscreenchange', checkFullscreen)
document.removeEventListener('MSFullscreenChange', checkFullscreen)
})
</script>
<style lang="scss" scoped>
svg {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
}
.fullScreen-border {
stroke: v-bind('borderColor');
stroke-width: v-bind('border+"px"');
fill: v-bind('bgColor');
}
</style>

View File

@@ -1,19 +1,9 @@
import { NumberConfig } from './Number/index' import { NumberConfig } from './Number/index'
import { TimeCommonConfig } from './TimeCommon/index' import { TimeCommonConfig } from './TimeCommon/index'
import { ClockConfig } from './Clock/index' import { ClockConfig } from './Clock/index'
import { FullScreenConfig } from './FullScreen/index'
import { CountDownConfig } from './CountDown/index' import { CountDownConfig } from './CountDown/index'
import { FlipperNumberConfig } from './FlipperNumber' import { FlipperNumberConfig } from './FlipperNumber'
import { PipelineHConfig } from './PipelineH/index' import { PipelineHConfig } from './PipelineH/index'
import { PipelineVConfig } from './PipelineV/index' import { PipelineVConfig } from './PipelineV/index'
export default [ export default [NumberConfig, FlipperNumberConfig, TimeCommonConfig, CountDownConfig, ClockConfig, PipelineHConfig, PipelineVConfig]
NumberConfig,
FlipperNumberConfig,
TimeCommonConfig,
CountDownConfig,
ClockConfig,
FullScreenConfig,
PipelineHConfig,
PipelineVConfig
]

View File

@@ -1,63 +1,62 @@
/** /**
* 创建 threejs 四大天王 * 创建 threejs 四大天王
* 场景、相机、渲染器、控制器 * 场景、相机、渲染器、控制器
*/ */
import * as THREE from 'three' import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export class Basic { export class Basic {
public scene!: THREE.Scene public scene!: THREE.Scene
public camera!: THREE.PerspectiveCamera public camera!: THREE.PerspectiveCamera
public renderer!: THREE.WebGLRenderer public renderer!: THREE.WebGLRenderer
public controls!: OrbitControls public controls!: OrbitControls
public dom: HTMLElement public dom: HTMLElement
constructor(dom: HTMLElement) { constructor(dom: HTMLElement) {
this.dom = dom this.dom = dom
this.initScenes() this.initScenes()
this.setControls() this.setControls()
} }
/** /**
* 初始化场景 * 初始化场景
*/ */
initScenes() { initScenes() {
this.scene = new THREE.Scene() this.scene = new THREE.Scene()
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000) this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000)
this.camera.position.set(0, 30, -250) this.camera.position.set(0, 30, -250)
this.renderer = new THREE.WebGLRenderer({ this.renderer = new THREE.WebGLRenderer({
// canvas: this.dom, // canvas: this.dom,
alpha: true, // 透明 alpha: true, // 透明
antialias: true, // 抗锯齿 antialias: true // 抗锯齿
preserveDrawingBuffer: true })
}) this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比
this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比 this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高
this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高 this.dom.appendChild(this.renderer.domElement) // 添加到dom中
this.dom.appendChild(this.renderer.domElement) // 添加到dom中 }
}
/**
/** * 设置控制器
* 设置控制器 */
*/ setControls() {
setControls() { // 鼠标控制 相机渲染dom
// 鼠标控制 相机渲染dom this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.autoRotateSpeed = 3
this.controls.autoRotateSpeed = 3 // 使动画循环使用时阻尼或自转 意思是否有惯性
// 使动画循环使用时阻尼或自转 意思是否有惯性 this.controls.enableDamping = true
this.controls.enableDamping = true // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
// 动态阻尼系数 就是鼠标拖拽旋转灵敏度 this.controls.dampingFactor = 0.05
this.controls.dampingFactor = 0.05 // 是否可以缩放
// 是否可以缩放 this.controls.enableZoom = true
this.controls.enableZoom = true // 设置相机距离原点的最远距离
// 设置相机距离原点的最远距离 this.controls.minDistance = 100
this.controls.minDistance = 100 // 设置相机距离原点的最远距离
// 设置相机距离原点的最远距离 this.controls.maxDistance = 300
this.controls.maxDistance = 300 // 是否开启右键拖拽
// 是否开启右键拖拽 this.controls.enablePan = false
this.controls.enablePan = false }
} }
}

View File

@@ -4,7 +4,7 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting' import { chartInitConfig } from '@/settings/designSetting'
import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum' import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
import { interactActions, ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum } from './interact' import { interactActions, ComponentInteractEventEnum } from './interact'
import { InputsDateConfig } from './index' import { InputsDateConfig } from './index'
export const option = { export const option = {
@@ -12,14 +12,9 @@ export const option = {
[COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE, [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATE,
// 下拉展示 // 下拉展示
isPanel: 0, isPanel: 0,
// 默认值 dataset: dayjs().valueOf(),
dataset: dayjs().valueOf() as number | number[] | null, differValue: 0
// 默认值类型
defaultType: DefaultTypeEnum.STATIC,
// 动态默认值偏移单位
differUnit: [DifferUnitEnum.DAY, DifferUnitEnum.DAY],
// 动态默认值偏移值
differValue: [0, 0]
} }
export default class Config extends PublicConfigClass implements CreateComponentType { export default class Config extends PublicConfigClass implements CreateComponentType {

View File

@@ -8,67 +8,39 @@
<collapse-item name="时间配置" :expanded="true"> <collapse-item name="时间配置" :expanded="true">
<setting-item-box name="基础"> <setting-item-box name="基础">
<setting-item name="类型"> <setting-item name="类型">
<n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions" <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions" />
@update:value="datePickerTypeUpdate"/>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="默认值"> <setting-item-box name="默认值" :alone="true">
<setting-item name="类型"> <n-date-picker size="small" v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
<n-select v-model:value="optionData.defaultType" size="small" :options="defaultTypeOptions" </setting-item-box>
@update:value="defaultTypeUpdate" />
</setting-item>
</setting-item-box> <setting-item-box :alone="true">
<setting-item-box v-if="optionData.defaultType === DefaultTypeEnum.STATIC" :alone="true">
<setting-item name="静态默认值">
<n-date-picker size="small" clearable v-model:value="optionData.dataset" :type="optionData.componentInteractEventKey" />
</setting-item>
</setting-item-box>
<setting-item-box v-if="optionData.defaultType === DefaultTypeEnum.DYNAMIC" >
<template #name> <template #name>
<n-text></n-text> <n-text>动态</n-text>
<n-tooltip trigger="hover"> <n-tooltip trigger="hover">
<template #trigger> <template #trigger>
<n-icon size="21" :depth="3"> <n-icon size="21" :depth="3">
<help-outline-icon></help-outline-icon> <help-outline-icon></help-outline-icon>
</n-icon> </n-icon>
</template> </template>
<span>打开页面时浏览器操作系统的系统时间+偏移量(单位)</span> <n-text>动态值不为0时默认值:取当天时间相加当前值</n-text>
</n-tooltip> </n-tooltip>
</template> </template>
<setting-item :name="differValueName"> <n-input-number v-model:value="optionData.differValue" class="input-num-width" size="small" :min="-40" :max="40">
<n-input-number v-model:value="optionData.differValue[0]" class="input-num-width" size="small"> <template #suffix> </template>
<template #suffix> </n-input-number>
{{DifferUnitObject[optionData.differUnit[0]]}}
</template>
</n-input-number>
</setting-item>
<setting-item :name="differUnitName">
<n-select v-model:value="optionData.differUnit[0]" size="small" :options="differUnitOptions" />
</setting-item>
<setting-item v-if="isRange" name="结束值动态偏移量">
<n-input-number v-model:value="optionData.differValue[1]" class="input-num-width" size="small">
<template #suffix>
{{DifferUnitObject[optionData.differUnit[1]]}}
</template>
</n-input-number>
</setting-item>
<setting-item v-if="isRange" name="结束值偏移单位">
<n-select v-model:value="optionData.differUnit[1]" size="small" :options="differUnitOptions" />
</setting-item>
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { PropType, computed } from 'vue' import { PropType } from 'vue'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { option } from './config' import { option } from './config'
import { ComponentInteractEventEnum, DefaultTypeEnum, DifferUnitEnum, DifferUnitObject } from './interact' import { ComponentInteractEventEnum } from './interact'
import dayjs from "dayjs";
const { HelpOutlineIcon } = icon.ionicons5 const { HelpOutlineIcon } = icon.ionicons5
@@ -128,87 +100,4 @@ const datePickerTypeOptions = [
value: ComponentInteractEventEnum.QUARTER_RANGE value: ComponentInteractEventEnum.QUARTER_RANGE
} }
] ]
const defaultTypeOptions = [
{
label: '静态',
value: DefaultTypeEnum.STATIC
},
{
label: '动态',
value: DefaultTypeEnum.DYNAMIC
},
{
label: '无',
value: DefaultTypeEnum.NONE
}
]
const differUnitOptions = [
// ManipulateType
{
value: DifferUnitEnum.DAY,
label: DifferUnitObject[DifferUnitEnum.DAY]
},
{
value: DifferUnitEnum.WEEK,
label: DifferUnitObject[DifferUnitEnum.WEEK]
},
{
value: DifferUnitEnum.MONTH,
label: DifferUnitObject[DifferUnitEnum.MONTH]
},
{
value: DifferUnitEnum.QUARTER,
label: DifferUnitObject[DifferUnitEnum.QUARTER]
},
{
value: DifferUnitEnum.YEAR,
label: DifferUnitObject[DifferUnitEnum.YEAR]
},
{
value: DifferUnitEnum.HOUR,
label: DifferUnitObject[DifferUnitEnum.HOUR]
},
{
value: DifferUnitEnum.MINUTE,
label: DifferUnitObject[DifferUnitEnum.MINUTE]
},
{
value: DifferUnitEnum.SECOND,
label: DifferUnitObject[DifferUnitEnum.SECOND]
},
{
value: DifferUnitEnum.MILLISECOND,
label: DifferUnitObject[DifferUnitEnum.MILLISECOND]
}
]
const isRange = computed(() => {
return props.optionData.componentInteractEventKey.endsWith('range')
})
const differValueName = computed(() => {
return isRange.value ? '开始值动态偏移量' : '动态偏移量'
})
const differUnitName = computed(() => {
return isRange.value ? '开始值偏移单位' : '偏移单位'
})
const datePickerTypeUpdate = () => {
props.optionData.dataset = isRange.value ? [dayjs().valueOf(), dayjs().valueOf()] : dayjs().valueOf()
}
const defaultTypeUpdate = (v: string) => {
if (v === DefaultTypeEnum.STATIC) {
datePickerTypeUpdate()
} else {
// DefaultTypeEnum.
props.optionData.dataset = null
}
}
</script> </script>

View File

@@ -1,7 +1,6 @@
<template> <template>
<n-date-picker <n-date-picker
v-model:value="option.dataset" v-model:value="option.dataset"
clearable
:panel="!!chartConfig.option.isPanel" :panel="!!chartConfig.option.isPanel"
:type="chartConfig.option.componentInteractEventKey" :type="chartConfig.option.componentInteractEventKey"
:style="`width:${w}px;`" :style="`width:${w}px;`"
@@ -10,15 +9,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType, ref, shallowReactive, toRefs, watch } from 'vue' import { PropType, toRefs, ref, shallowReactive, watch } from 'vue'
import dayjs from 'dayjs'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks' import { useChartInteract } from '@/hooks'
import { InteractEventOn } from '@/enums/eventEnum' import { InteractEventOn } from '@/enums/eventEnum'
import {ComponentInteractEventEnum, ComponentInteractParamsEnum, DefaultTypeEnum} from './interact' import { ComponentInteractParamsEnum } from './interact'
import dayjs, {ManipulateType} from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
const props = defineProps({ const props = defineProps({
chartConfig: { chartConfig: {
@@ -34,107 +31,61 @@ const option = shallowReactive({
dataset: props.chartConfig.option.dataset dataset: props.chartConfig.option.dataset
}) })
const isRange = computed(() => {
return props.chartConfig.option.componentInteractEventKey.endsWith('range')
})
// 监听事件改变 // 监听事件改变
const onChange = (v: number | number[] | null) => { const onChange = (v: number | number[]) => {
if (isRange.value) { if (v instanceof Array) {
let dateStart = null
let dateEnd = null
let daterange = null
if(v instanceof Array){
dateStart = v[0]
dateEnd = v[1]
daterange = `${v[0]}-${v[1]}`
}
// 存储到联动数据 // 存储到联动数据
useChartInteract( useChartInteract(
props.chartConfig, props.chartConfig,
useChartEditStore, useChartEditStore,
{ {
[ComponentInteractParamsEnum.DATE_START]: dateStart, [ComponentInteractParamsEnum.DATE_START]: v[0] || dayjs().valueOf(),
[ComponentInteractParamsEnum.DATE_END]: dateEnd, [ComponentInteractParamsEnum.DATE_END]: v[1] || dayjs().valueOf(),
[ComponentInteractParamsEnum.DATE_RANGE]: daterange [ComponentInteractParamsEnum.DATE_RANGE]: `${v[0] || dayjs().valueOf()}-${v[1] || dayjs().valueOf()}`
}, },
InteractEventOn.CHANGE InteractEventOn.CHANGE
) )
} else { } else {
// 存储到联动数据 // 存储到联动数据
useChartInteract( useChartInteract(
props.chartConfig, props.chartConfig,
useChartEditStore, useChartEditStore,
{ [ComponentInteractParamsEnum.DATE]: v }, { [ComponentInteractParamsEnum.DATE]: v || dayjs().valueOf() },
InteractEventOn.CHANGE InteractEventOn.CHANGE
) )
} }
} }
const getDiffDate = (type: ComponentInteractEventEnum, date: dayjs.Dayjs) => {
// 注册 quarterOfYear 插件
dayjs.extend(quarterOfYear)
switch (type) {
case ComponentInteractEventEnum.DATE:
case ComponentInteractEventEnum.DATE_RANGE:
date = date.startOf('day')
break
case ComponentInteractEventEnum.MONTH:
case ComponentInteractEventEnum.MONTH_RANGE:
date = date.startOf('month')
break
case ComponentInteractEventEnum.YEAR:
case ComponentInteractEventEnum.YEAR_RANGE:
date = date.startOf('year')
break
case ComponentInteractEventEnum.QUARTER:
case ComponentInteractEventEnum.QUARTER_RANGE:
date = date.startOf('quarter')
break
default:
break
}
return date
}
watch( watch(
() => { () => props.chartConfig.option.dataset,
return { (newData: number | number[]) => {
type: props.chartConfig.option.componentInteractEventKey as ComponentInteractEventEnum, option.dataset = newData
defaultType: props.chartConfig.option.defaultType as string, // 关联目标组件首次请求带上默认内容
differValue: props.chartConfig.option.differValue as number[], onChange(newData)
differUnit: props.chartConfig.option.differUnit as ManipulateType[], },
dataset: props.chartConfig.option.dataset as number | number[] | null, {
}; immediate: true
}, }
(newData, oldData) => { )
const hasTypeChanged = newData.type !== oldData?.type;
const hasDefaultTypeChanged = newData.defaultType !== oldData?.defaultType;
const hasDifferValueChanged = newData.differValue !== oldData?.differValue;
const hasDifferUnitChanged = newData.differUnit !== oldData?.differUnit;
if (hasTypeChanged || hasDefaultTypeChanged || hasDifferValueChanged || hasDifferUnitChanged) { // 手动更新
if (newData.defaultType === DefaultTypeEnum.NONE) { watch(
props.chartConfig.option.dataset = null; () => props.chartConfig.option.differValue,
} else if (newData.defaultType === DefaultTypeEnum.DYNAMIC) { (newData: number) => {
let date = dayjs(); if (props.chartConfig.option.differValue === 0) return
if (isRange.value) { if (typeof option.dataset === 'object') {
props.chartConfig.option.dataset = [ option.dataset[0] = dayjs().add(newData, 'day').valueOf()
getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf(), option.dataset[1] = dayjs().add(newData, 'day').valueOf()
getDiffDate(newData.type,date.add(newData.differValue[1], newData.differUnit[1])).valueOf(), } else {
]; option.dataset = dayjs().add(newData, 'day').valueOf()
} else {
props.chartConfig.option.dataset = getDiffDate(newData.type,date.add(newData.differValue[0], newData.differUnit[0])).valueOf()
}
}
}
option.dataset = props.chartConfig.option.dataset;
onChange(option.dataset);
},
{
immediate: true,
} }
); // 关联目标组件首次请求带上默认内容
onChange(newData)
},
{
immediate: true
}
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -22,37 +22,6 @@ export enum ComponentInteractParamsEnum {
DATE_RANGE = 'daterange' DATE_RANGE = 'daterange'
} }
export enum DefaultTypeEnum {
NONE = "none",
STATIC = "static",
DYNAMIC = "dynamic"
}
export enum DifferUnitEnum {
DAY = 'd',
WEEK = 'w',
MONTH = 'M',
QUARTER = 'Q',
YEAR = 'y',
HOUR = 'h',
MINUTE = 'm',
SECOND = 's',
MILLISECOND = 'ms',
}
export const DifferUnitObject = {
// https://day.js.org/docs/en/manipulate/add
[DifferUnitEnum.DAY]: '天',
[DifferUnitEnum.WEEK]: '周',
[DifferUnitEnum.MONTH]: '月',
[DifferUnitEnum.QUARTER]: '季度',
[DifferUnitEnum.YEAR]: '年',
[DifferUnitEnum.HOUR]: '小时',
[DifferUnitEnum.MINUTE]: '分钟',
[DifferUnitEnum.SECOND]: '秒',
[DifferUnitEnum.MILLISECOND]: '毫秒',
}
const time = [ const time = [
{ {
value: ComponentInteractParamsEnum.DATE, value: ComponentInteractParamsEnum.DATE,

View File

@@ -1,24 +0,0 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
import { interactActions, ComponentInteractEventEnum } from './interact'
import {InputsInputConfig} from "./index";
export const option = {
// 时间组件展示类型,必须和 interactActions 中定义的数据一致
[COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
// 默认值
inputValue: "0",
// 暴露配置内容给用户
dataset: ""
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = InputsInputConfig.key
public attr = { ...chartInitConfig, w: 260, h: 32, zIndex: -1 }
public chartConfig = cloneDeep(InputsInputConfig)
public interactActions = interactActions
public option = cloneDeep(option)
}

View File

@@ -1,18 +0,0 @@
<template>
<collapse-item name="输入框配置" :expanded="true">
<setting-item-box name="默认值" :alone="true">
<n-input v-model:value="optionData.dataset" placeholder="若未输入则默认值为0"/>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { option } from './config'
defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const InputsInputConfig: ConfigType = {
key: 'InputsInput',
chartKey: 'VInputsInput',
conKey: 'VCInputsInput',
title: '输入框',
category: ChatCategoryEnum.INPUTS,
categoryName: ChatCategoryEnumName.INPUTS,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.STATIC,
image: 'inputs_select.png'
}

View File

@@ -1,64 +0,0 @@
<template>
<div>
<n-input :style="`width:${w}px;`" type="text"
v-model:value="option.value.dataset"
placeholder="请输入"
@change="onChange">
</n-input>
</div>
</template>
<script lang="ts" setup>
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks'
import { InteractEventOn } from '@/enums/eventEnum'
import { ComponentInteractParamsEnum } from './interact'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const option = shallowReactive({
value: {
inputValue: props.chartConfig.option.inputValue,
dataset: props.chartConfig.option.dataset
}
})
const onChange = (v: string) => {
if(v == undefined) return;
// 存储到联动数据
useChartInteract(
props.chartConfig,
useChartEditStore,
{ [ComponentInteractParamsEnum.DATA]: v },
InteractEventOn.CHANGE
)
}
// 手动更新
watch(
() => props.chartConfig.option,
(newData: any) => {
option.value = newData
onChange(newData.inputValue)
},
{
immediate: true,
deep: true
}
)
</script>

View File

@@ -1,27 +0,0 @@
import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
// 时间组件类型
export enum ComponentInteractEventEnum {
DATA = 'data'
}
// 联动参数
export enum ComponentInteractParamsEnum {
DATA = 'data'
}
// 定义组件触发回调事件
export const interactActions: InteractActionsType[] = [
{
interactType: InteractEventOn.CHANGE,
interactName: '选择完成',
componentEmitEvents: {
[ComponentInteractEventEnum.DATA]: [
{
value: ComponentInteractParamsEnum.DATA,
label: '选择项'
}
]
}
}
]

View File

@@ -1,26 +0,0 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
import { interactActions, ComponentInteractEventEnum } from './interact'
import {InputsPaginationConfig} from "./index";
export const option = {
// 时间组件展示类型,必须和 interactActions 中定义的数据一致
[COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
// 默认值
pageValue:1,
sizeValue:[2,4,8,10,20],
pageSize:4,
// 暴露配置内容给用户
dataset: 10
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = InputsPaginationConfig.key
public attr = { ...chartInitConfig, w: 395, h: 32, zIndex: -1 }
public chartConfig = cloneDeep(InputsPaginationConfig)
public interactActions = interactActions
public option = cloneDeep(option)
}

View File

@@ -1,35 +0,0 @@
<template>
<collapse-item name="分页配置" :expanded="true">
<setting-item-box :alone="false" name="分页设置">
<setting-item name="默认页码" :alone="true">
<n-input-number v-model:value="optionData.pageValue" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="分页" :alone="true">
<n-select v-model:value="optionData.pageSize" size="small"
:options="page" />
</setting-item>
<setting-item name="页数" :alone="true">
<n-input-number v-model:value="optionData.dataset" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import {CollapseItem, SettingItem, SettingItemBox} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const page = [
{label:'2',value:2},
{label:'4',value:4},
{label:'8',value:8},
{label:'10',value:10},
{label:'20',value:20}
]
defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const InputsPaginationConfig: ConfigType = {
key: 'InputsPagination',
chartKey: 'VInputsPagination',
conKey: 'VCInputsPagination',
title: '分页',
category: ChatCategoryEnum.INPUTS,
categoryName: ChatCategoryEnumName.INPUTS,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.STATIC,
image: 'inputs_pagination.png'
}

View File

@@ -1,66 +0,0 @@
<template>
<div>
<n-pagination
@on-update:page="onChange" :style="`width:${w}px;`"
v-model:page="option.value.pageValue"
:page-count="option.value.dataset"
:page-slot="7"
show-size-picker
:page-sizes="option.value.sizeValue"
v-model:page-size="option.value.pageSize"
/>
</div>
</template>
<script lang="ts" setup>
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks'
import { InteractEventOn } from '@/enums/eventEnum'
import { ComponentInteractParamsEnum } from './interact'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const option = shallowReactive({
value: {
pageValue: props.chartConfig.option.pageValue,
dataset:props.chartConfig.option.dataset,
sizeValue:props.chartConfig.option.sizeValue,
pageSize:props.chartConfig.option.pageSize
}
})
const onChange = (v: number,v2:number) => {
if(v == undefined) return;
// 存储到联动数据
useChartInteract(
props.chartConfig,
useChartEditStore,
{
[ComponentInteractParamsEnum.DATA]: v ,
[ComponentInteractParamsEnum.DATA2]:v2
},
InteractEventOn.CHANGE
)
}
// 手动更新
watch(
() => props.chartConfig.option,
(newData: any) => {
option.value = newData
onChange(newData.pageValue,newData.pageSize)
},
{
immediate: true,
deep: true
}
)
</script>

View File

@@ -1,32 +0,0 @@
import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
// 时间组件类型
export enum ComponentInteractEventEnum {
DATA = 'data'
}
// 联动参数
export enum ComponentInteractParamsEnum {
DATA = 'data',
DATA2 = 'data2'
}
// 定义组件触发回调事件
export const interactActions: InteractActionsType[] = [
{
interactType: InteractEventOn.CHANGE,
interactName: '选择完成',
componentEmitEvents: {
[ComponentInteractEventEnum.DATA]: [
{
value: ComponentInteractParamsEnum.DATA,
label: '页数'
},
{
value: ComponentInteractParamsEnum.DATA2,
label: '每页条数'
}
]
}
}
]

View File

@@ -1,10 +1,7 @@
<template> <template>
<collapse-item name="标签页配置" :expanded="true"> <collapse-item name="标签页配置" :expanded="true">
<setting-item-box name="标签类型" :alone="true">
<n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" />
</setting-item-box>
<setting-item-box name="默认值" :alone="true"> <setting-item-box name="默认值" :alone="true">
<n-select size="small" v-model:value="optionData.tabLabel" value-field="label" :options="optionData.dataset" /> <n-select size="small" v-model:value="optionData.tabType" :options="tabTypeOptions" />
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
</template> </template>

View File

@@ -1,5 +1,5 @@
<template> <template>
<n-tabs :type="option.value.tabType" @update:value="onChange" :default-value="option.value.tabLabel"> <n-tabs :type="option.value.tabType" @update:value="onChange">
<n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab> <n-tab v-for="(item, index) in option.value.dataset" :name="item.label" :key="index"> {{ item.label }} </n-tab>
</n-tabs> </n-tabs>
</template> </template>

View File

@@ -1,7 +1,5 @@
import { InputsDateConfig } from './InputsDate/index' import { InputsDateConfig } from './InputsDate/index'
import { InputsSelectConfig } from './InputsSelect/index' import { InputsSelectConfig } from './InputsSelect/index'
import { InputsTabConfig } from './InputsTab/index' import { InputsTabConfig } from './InputsTab/index'
import { InputsPaginationConfig } from "./InputsPagination/index";
import { InputsInputConfig} from "./InputsInput/index";
export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig,InputsPaginationConfig,InputsInputConfig] export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig]

View File

@@ -1,89 +1,89 @@
<template> <template>
<collapse-item name="信息" :expanded="true"> <collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true"> <setting-item-box name="文字" :alone="true">
<setting-item> <setting-item>
<n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input> <n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
<collapse-item name="样式" :expanded="true"> <collapse-item name="样式" :expanded="true">
<setting-item-box name="文字"> <setting-item-box name="文字">
<setting-item name="颜色"> <setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker> <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker>
</setting-item> </setting-item>
<setting-item name="字体大小"> <setting-item name="字体大小">
<n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number> <n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number>
</setting-item> </setting-item>
<setting-item name="字体粗细"> <setting-item name="字体粗细">
<n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" /> <n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
</setting-item> </setting-item>
<setting-item name="字间距"> <setting-item name="字间距">
<n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number> <n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="阴影"> <setting-item-box name="阴影">
<setting-item> <setting-item>
<n-space> <n-space>
<n-switch v-model:value="optionData.showShadow" size="small" /> <n-switch v-model:value="optionData.showShadow" size="small" />
<n-text>展示阴影</n-text> <n-text>展示阴影</n-text>
</n-space> </n-space>
</setting-item> </setting-item>
<setting-item name="颜色"> <setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.colorShadow"></n-color-picker <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.colorShadow"></n-color-picker
></setting-item> ></setting-item>
<setting-item name="x"> <setting-item name="x">
<n-input-number v-model:value="optionData.hShadow" size="small"></n-input-number <n-input-number v-model:value="optionData.hShadow" size="small"></n-input-number
></setting-item> ></setting-item>
<setting-item name="y"> <setting-item name="y">
<n-input-number v-model:value="optionData.vShadow" size="small"></n-input-number <n-input-number v-model:value="optionData.vShadow" size="small"></n-input-number
></setting-item> ></setting-item>
<setting-item name="模糊"> <setting-item name="模糊">
<n-input-number v-model:value="optionData.blurShadow" size="small"></n-input-number <n-input-number v-model:value="optionData.blurShadow" size="small"></n-input-number
></setting-item> ></setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="动画"> <setting-item-box name="动画">
<setting-item name="动画速度"> <setting-item name="动画速度">
<n-input-number <n-input-number
v-model:value="optionData.animationSpeed" v-model:value="optionData.animationSpeed"
size="small" size="small"
placeholder="动画速度" placeholder="动画速度"
:min="0" :min="0"
></n-input-number> ></n-input-number>
</setting-item> </setting-item>
<setting-item name="动画间隔"> <setting-item name="动画间隔">
<n-input-number <n-input-number
v-model:value="optionData.animationTime" v-model:value="optionData.animationTime"
size="small" size="small"
placeholder="动画间隔" placeholder="动画间隔"
:min="0" :min="0"
></n-input-number> ></n-input-number>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from 'vue' import { PropType } from 'vue'
import { option, FontWeightEnum, FontWeightObject } from './config' import { option, FontWeightEnum, FontWeightObject } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
type: Object as PropType<typeof option>, type: Object as PropType<typeof option>,
required: true required: true
} }
}) })
const fontWeightOptions = [ const fontWeightOptions = [
{ {
label: FontWeightEnum.NORMAL, label: FontWeightEnum.NORMAL,
value: FontWeightObject[FontWeightEnum.NORMAL] value: FontWeightObject[FontWeightEnum.NORMAL]
}, },
{ {
label: FontWeightEnum.BOLD, label: FontWeightEnum.BOLD,
value: FontWeightObject[FontWeightEnum.BOLD] value: FontWeightObject[FontWeightEnum.BOLD]
} }
] ]
</script> </script>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="go-text-box"> <div class="go-text-box">
<div class="content"> <div class="content">
<span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{ option.dataset }}</span> <span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click"></span>
<span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span> <span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span>
</div> </div>
</div> </div>

View File

@@ -1,45 +1,45 @@
<template> <template>
<collapse-item name="信息" :expanded="true"> <collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true"> <setting-item-box name="文字" :alone="true">
<setting-item> <setting-item>
<n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input> <n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
<collapse-item name="样式" :expanded="true"> <collapse-item name="样式" :expanded="true">
<setting-item-box name="文字"> <setting-item-box name="文字">
<setting-item name="字体大小"> <setting-item name="字体大小">
<n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number> <n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="渐变色参数"> <setting-item-box name="渐变色参数">
<setting-item name="起始值"> <setting-item name="起始值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker> <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker>
</setting-item> </setting-item>
<setting-item name="结束值"> <setting-item name="结束值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker> <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker>
</setting-item> </setting-item>
<setting-item name="偏移角度"> <setting-item name="偏移角度">
<n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number> <n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType } from 'vue' import { PropType } from 'vue'
import { option } from './config' import { option } from './config'
import { import {
CollapseItem, CollapseItem,
SettingItemBox, SettingItemBox,
SettingItem SettingItem
} from '@/components/Pages/ChartItemSetting' } from '@/components/Pages/ChartItemSetting'
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
type: Object as PropType<typeof option>, type: Object as PropType<typeof option>,
required: true required: true
} }
}) })
</script> </script>

View File

@@ -1,35 +0,0 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { TablesBasicConfig } from './index'
import dataJson from './data.json'
const { dimensions, source } = dataJson
export const option = {
dataset: { dimensions, source },
pagination: {
page: 1,
pageSize: 5
},
align: 'center',
style: {
border: 'on',
singleColumn: 'off',
singleLine: 'off',
bottomBordered: 'on',
striped: 'on',
fontSize: 16,
borderWidth: 0,
borderColor: 'black',
borderStyle: 'solid'
},
inputShow: 'none'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TablesBasicConfig.key
public attr = { ...chartInitConfig, w: 600, h: 300, zIndex: -1 }
public chartConfig = cloneDeep(TablesBasicConfig)
public option = cloneDeep(option)
}

View File

@@ -1,162 +0,0 @@
<template>
<collapse-item name="表格设置" :expanded="true">
<n-tag type="primary">若配置无响应请在预览页面查看效果</n-tag>
<setting-item-box :alone="true" name="对齐方式">
<setting-item :alone="true">
<n-select
v-model:value="optionData.align"
size="small"
:options="[
{ label: '靠左', value: 'left' },
{ label: '居中', value: 'center' },
{ label: '靠右', value: 'right' }
]"
/>
</setting-item>
</setting-item-box>
<setting-item-box :alone="false" name="分页设置">
<setting-item name="默认页码" :alone="true">
<n-input-number v-model:value="optionData.pagination.page" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="分页" :alone="true">
<n-select v-model:value="optionData.pagination.pageSize" size="small" :options="page" />
</setting-item>
</setting-item-box>
<setting-item-box :alone="false" name="表格数据">
<SettingItem name="表头名称" class="form_name">
<div style="width: 260px">
<n-input v-model:value="header" size="small" placeholder="表头数据(英文','分割)"></n-input>
</div>
</SettingItem>
</setting-item-box>
<setting-item-box :alone="false" name="表格样式">
<SettingItem name="显示边框" :alone="true">
<n-select v-model:value="(optionData as any).style.border" size="small" :options="borderFlag" />
</SettingItem>
<SettingItem name="底部边框" :alone="true">
<n-select
v-model:value="(optionData as any).style.bottomBordered"
size="small"
:options="bottom_borderedFlag"
/>
</SettingItem>
<SettingItem name="列分割线" :alone="true">
<n-select v-model:value="(optionData as any).style.singleLine" size="small" :options="columnFlag" />
</SettingItem>
<SettingItem name="行分割线" :alone="true">
<n-select v-model:value="(optionData as any).style.singleColumn" size="small" :options="lineFlag" />
</SettingItem>
<SettingItem name="斑马条纹" :alone="true">
<n-select v-model:value="(optionData as any).style.striped" size="small" :options="stripedFlag" />
</SettingItem>
<setting-item name="字体大小" :alone="true">
<n-input-number
v-model:value="optionData.style.fontSize"
:min="12"
size="small"
placeholder="字体大小"
></n-input-number>
</setting-item>
<setting-item name="边框宽度" :alone="true">
<n-input-number
v-model:value="optionData.style.borderWidth"
:min="0"
size="small"
placeholder="字体大小"
></n-input-number>
</setting-item>
<setting-item name="边框颜色" :alone="true">
<n-color-picker size="small" :modes="['rgb']" v-model:value="optionData.style.borderColor"></n-color-picker>
</setting-item>
<setting-item name="边框样式" :alone="true">
<n-select v-model:value="optionData.style.borderStyle" size="small" :options="borderStyleFlag" />
</setting-item>
<SettingItem name="表格搜索(前端静态搜索)" :alone="true">
<n-select v-model:value="optionData.inputShow" size="small" :options="inputSelect" />
</SettingItem>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType, watch, ref } from 'vue'
import { option } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const page = [
{ label: '2', value: 2 },
{ label: '5', value: 5 },
{ label: '10', value: 10 },
{ label: '15', value: 15 },
{ label: '30', value: 30 }
]
const borderFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const columnFlag = [
{ label: '显示', value: 'off' },
{ label: '不显示', value: 'on' }
]
const lineFlag = [
{ label: '显示', value: 'off' },
{ label: '不显示', value: 'on' }
]
const bottom_borderedFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const stripedFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const borderStyleFlag = [
{ label: '实线边框', value: 'solid' },
{ label: '虚线边框', value: 'dashed' },
{ label: '点状边框', value: 'dotted' },
{ label: '双线边框', value: 'double' }
]
const inputSelect = [
{ label: '停用', value: 'none' },
{ label: '启用', value: 'flex' }
]
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const header = ref()
const median = ref<string[]>([])
props.optionData.dataset.dimensions.forEach(item => {
median.value.push(item.title)
})
//转string
watch(
() => props.optionData,
() => {
median.value = []
props.optionData.dataset.dimensions.forEach(item => {
median.value.push(item.title)
})
header.value = median.value.toString()
},
{
deep: false,
immediate: true
}
)
//更新columns
watch([header], ([headerNew], [headerOld]) => {
if (headerNew !== headerOld) {
headerNew.split(',').forEach((item: string, index: number) => {
if (index + 1 <= props.optionData.dataset.dimensions.length) {
props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index]
}
})
}
})
</script>

View File

@@ -1,60 +0,0 @@
{
"dimensions": [
{
"title": "产品名称",
"key": "productName"
},
{
"title": "产品销量(万)",
"key": "totalSum"
},
{
"title": "销售额(万)",
"key": "totalAmount"
}
],
"source": [
{
"key": 0,
"productName": "产品A1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 1,
"productName": "产品B1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 2,
"productName": "产品C1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 3,
"productName": "产品D1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 4,
"productName": "产品A2",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 5,
"productName": "产品D2",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 6,
"productName": "产品A3",
"totalSum": 10,
"totalAmount": 10
}
]
}

View File

@@ -1,14 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const TablesBasicConfig: ConfigType = {
key: 'TablesBasic',
chartKey: 'VTablesBasic',
conKey: 'VCTablesBasic',
title: '基础分页表格',
category: ChatCategoryEnum.TABLE,
categoryName: ChatCategoryEnumName.TABLE,
package: PackagesCategoryEnum.TABLES,
chartFrame: ChartFrameEnum.COMMON,
image: 'tables_basic.png'
}

View File

@@ -1,95 +0,0 @@
<template>
<div class="go-tables-basic">
<n-input
v-model:value="inputData"
placeholder="请输入信息"
:style="`display: ${inputShow}`"
style="margin-bottom: 5px; float: right; width: 240px"
>
<template #prefix>
<n-icon :component="SearchIcon" />
</template>
</n-input>
<n-data-table
:style="`
width: ${w}px;
height: ${h}px;
font-size: ${option.style.fontSize}px;
border-width: ${option.style.border === 'on' ? option.style.borderWidth : 0}px;
border-color: ${option.style.borderColor};
border-style: ${option.style.borderStyle}`"
:bordered="option.style.border === 'on'"
:single-column="option.style.singleColumn === 'on'"
:single-line="option.style.singleLine === 'on'"
:bottom-bordered="option.style.bottomBordered === 'on'"
:striped="option.style.striped === 'on'"
:max-height="h"
size="small"
:columns="option.dataset.dimensions"
:data="filterData"
:pagination="pagination"
/>
</div>
</template>
<script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { icon } from '@/plugins'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { SearchIcon } = icon.ionicons5
//查询字段
const inputData = ref('')
//前台过滤
const filterData = computed(() => {
return option?.dataset?.source?.filter((item: any) => {
return Object.values(item).some(val => {
return String(val).toLowerCase().includes(inputData.value.toLowerCase())
})
})
})
const { align, pagination, inputShow } = toRefs(props.chartConfig.option)
pagination.value.onChange = (page: number) => {
pagination.value.page = page
}
const { w, h } = toRefs(props.chartConfig.attr)
const option = reactive({
dataset: props.chartConfig.option.dataset,
style: props.chartConfig.option.style
})
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
option?.dataset?.dimensions?.forEach((header: any) => {
header.align = align.value
})
},
{
immediate: true,
deep: true
}
)
</script>
<style lang="scss" scoped>
@include go('tables-basic') {
display: flex;
flex-direction: column;
gap: 15px;
align-items: flex-end;
}
</style>

View File

@@ -1,5 +1,4 @@
import { TableListConfig } from './TableList' import { TableListConfig } from './TableList'
import { TableScrollBoardConfig } from './TableScrollBoard' import { TableScrollBoardConfig } from './TableScrollBoard'
import { TablesBasicConfig } from "./TablesBasic/index";
export default [TableListConfig, TableScrollBoardConfig,TablesBasicConfig] export default [TableListConfig, TableScrollBoardConfig]

View File

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

View File

@@ -56,7 +56,6 @@ import {
ArrowDown as ArrowDownIcon, ArrowDown as ArrowDownIcon,
Planet as PawIcon, Planet as PawIcon,
Search as SearchIcon, Search as SearchIcon,
Reload as ReloadIcon,
ChevronUpOutline as ChevronUpOutlineIcon, ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon, ChevronDownOutline as ChevronDownOutlineIcon,
Pulse as PulseIcon, Pulse as PulseIcon,
@@ -98,7 +97,6 @@ import {
FitToScreen as FitToScreenIcon, FitToScreen as FitToScreenIcon,
FitToHeight as FitToHeightIcon, FitToHeight as FitToHeightIcon,
FitToWidth as FitToWidthIcon, FitToWidth as FitToWidthIcon,
Save as SaveIcon,
Carbon3DCursor as Carbon3DCursorIcon, Carbon3DCursor as Carbon3DCursorIcon,
Carbon3DSoftware as Carbon3DSoftwareIcon, Carbon3DSoftware as Carbon3DSoftwareIcon,
Filter as FilterIcon, Filter as FilterIcon,
@@ -220,8 +218,6 @@ const ionicons5 = {
PawIcon, PawIcon,
// 搜索(放大镜) // 搜索(放大镜)
SearchIcon, SearchIcon,
// 加载
ReloadIcon,
// 过滤器 // 过滤器
FilterIcon, FilterIcon,
// 向上 // 向上
@@ -293,8 +289,6 @@ const carbon = {
FitToScreenIcon, FitToScreenIcon,
FitToHeightIcon, FitToHeightIcon,
FitToWidthIcon, FitToWidthIcon,
// 保存
SaveIcon,
// 成组 // 成组
Carbon3DCursorIcon, Carbon3DCursorIcon,
// 解组 // 解组

View File

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

View File

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

View File

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

View File

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

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