Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2386687f2e | ||
|
|
f0f9905583 | ||
|
|
8d57af2dab | ||
|
|
98b1380d0d | ||
|
|
a448bb678b | ||
|
|
ca580db132 | ||
|
|
b248f73a88 | ||
|
|
8bff2f9b12 | ||
|
|
aa1b11d9f0 | ||
|
|
d5fb0b54de | ||
|
|
3d88a39a02 | ||
|
|
873c6fef53 | ||
|
|
b2f53a7123 | ||
|
|
2a850e4249 | ||
|
|
0b89aeca82 | ||
|
|
126c7ce5d2 | ||
|
|
e2ba151794 | ||
|
|
92dcd7fecd | ||
|
|
e841d3db17 | ||
|
|
800a0141a5 | ||
|
|
c92d7cab97 | ||
|
|
86de4e105e | ||
|
|
62a2ed2b4a | ||
|
|
e8e05033cd | ||
|
|
3790bc0207 | ||
|
|
8c4e3e8965 | ||
|
|
b03107d8cb | ||
|
|
e9a4ebe38f | ||
|
|
a702decfd4 | ||
|
|
0eecc1e19d | ||
|
|
182b2c508a | ||
|
|
2907d1b514 | ||
|
|
7bda46021a | ||
|
|
6d91262faa | ||
|
|
1672978730 | ||
|
|
36a6bb4214 | ||
|
|
14b37d82d0 | ||
|
|
4300b1f617 | ||
|
|
de4bd655ed | ||
|
|
0434c779cd | ||
|
|
aa0578776c | ||
|
|
3bd8cbe535 | ||
|
|
c81aff2c57 | ||
|
|
59eaed5b09 | ||
|
|
5d0c6f4487 | ||
|
|
c903b607df | ||
|
|
ec5bed5b13 | ||
|
|
ec97340c25 | ||
|
|
7bbf285e8e | ||
|
|
d652b06137 | ||
|
|
e55e63bca1 | ||
|
|
9b47d353c0 | ||
|
|
c3f9a470fc | ||
|
|
bd2557f3e4 | ||
|
|
730099efb9 | ||
|
|
c5706f839e | ||
|
|
faa0d6538f | ||
|
|
f15e0cd15f | ||
|
|
aa17e93966 | ||
|
|
feb9796449 | ||
|
|
e4b641a9c9 | ||
|
|
352a1742cf | ||
|
|
1af7ae865d | ||
|
|
7bc6ff7619 | ||
|
|
67f6dcd1fe | ||
|
|
de60c7cde5 | ||
|
|
889e5075ba | ||
|
|
2bba1dcae0 | ||
|
|
9d81159141 | ||
|
|
f8ebaa60b1 | ||
|
|
02ec3c78d6 | ||
|
|
8230757bd1 | ||
|
|
c1de1f9db6 | ||
|
|
1b0591ee62 | ||
|
|
3ee5faa248 | ||
|
|
ab9b79e8a8 | ||
|
|
b6a78c64ed | ||
|
|
9855d28e33 | ||
|
|
16fb258908 | ||
|
|
52ed72e502 | ||
|
|
6f9993e9e8 | ||
|
|
3347e3b12a | ||
|
|
b4a5ff7935 | ||
|
|
e75e2ccfe6 | ||
|
|
3d568f08de | ||
|
|
5cc20e9b19 | ||
|
|
dec1130ace | ||
|
|
e3a294eb00 | ||
|
|
104551b600 | ||
|
|
5c6bf57de1 | ||
|
|
b0cb3addbd | ||
|
|
77ff4cdffd | ||
|
|
dde92bfe60 | ||
|
|
a8bcc93aed | ||
|
|
b6903a777a | ||
|
|
f7cbc75e22 | ||
|
|
0e1ae71b78 | ||
|
|
7fcfb953bd | ||
|
|
a76ad93600 | ||
|
|
f9ed391c81 | ||
|
|
8ab64846d4 | ||
|
|
a82cc840b5 | ||
|
|
2171843c61 | ||
|
|
934bac7201 | ||
|
|
ed2a46a3ef | ||
|
|
766a3a8ede | ||
|
|
f3ec85050e | ||
|
|
ba54d934a2 | ||
|
|
d6ecad6467 | ||
|
|
74cab1e9af | ||
|
|
a823851541 | ||
|
|
618d1d77cb | ||
|
|
17c48608ec | ||
|
|
6d5dfbced0 | ||
|
|
c773bd8010 | ||
|
|
5746da73dd | ||
|
|
60bbfd9c92 | ||
|
|
12d92f3aa4 | ||
|
|
2edb1caf18 | ||
|
|
75067221da | ||
|
|
3358e164a1 | ||
|
|
94cde3f517 | ||
|
|
a2c8827a35 | ||
|
|
172a3163aa | ||
|
|
4d189e954c | ||
|
|
8a1f3ac2ef | ||
|
|
68dbf3e9ef | ||
|
|
0aece46d91 | ||
|
|
094c7ed392 | ||
|
|
c48517a89b | ||
|
|
68c68e96b1 | ||
|
|
36b1f37f3f | ||
|
|
51e5c756a7 | ||
|
|
8df951992e | ||
|
|
1a00993ee8 | ||
|
|
cb7e887c36 | ||
|
|
255b14a597 | ||
|
|
3f462c1bee | ||
|
|
cacc99683d | ||
|
|
d3a9f7d60f | ||
|
|
8d4dd3160d | ||
|
|
6847f7d966 | ||
|
|
35204898fc | ||
|
|
7fe743d624 | ||
|
|
6a285f610c | ||
|
|
a4c0450f7a | ||
|
|
a81f016e3f | ||
|
|
ee5fed4cd0 | ||
|
|
3fb0fe43bb | ||
|
|
f1f5f9cca9 | ||
|
|
2ce17c3974 | ||
|
|
1d7e40950f | ||
|
|
91bda457e7 | ||
|
|
68aeea70cf | ||
|
|
7a19346700 | ||
|
|
8d2269df78 | ||
|
|
b133cbdfea | ||
|
|
f45d4ca5af | ||
|
|
d96e7f71d7 | ||
|
|
24fee76237 | ||
|
|
d59193bc33 | ||
|
|
6928a70d9f | ||
|
|
e0796280f5 | ||
|
|
5d803e3fa6 | ||
|
|
749c0a2f39 | ||
|
|
737504cef5 | ||
|
|
8115950893 | ||
|
|
f458a21a2f | ||
|
|
13a9675894 | ||
|
|
77b5a41af9 | ||
|
|
2bf895ad3d | ||
|
|
6a5abd6762 | ||
|
|
5cb458c45b | ||
|
|
f828c48ab6 | ||
|
|
2626bc794f | ||
|
|
734dd68607 | ||
|
|
19f53f705c | ||
|
|
b93caf1386 | ||
|
|
aa613e2805 | ||
|
|
616584fc19 | ||
|
|
a5e83bfe9f | ||
|
|
1252d266dd | ||
|
|
3c820d53a6 | ||
|
|
f0525c7522 | ||
|
|
600f1b2dd2 | ||
|
|
757b79514a | ||
|
|
cf8121eb00 | ||
|
|
faf2d44fbb | ||
|
|
88516d9491 | ||
|
|
88dbbe03ea | ||
|
|
ae1fd2e7cf | ||
|
|
d3931f47bc | ||
|
|
bf9bd59b63 | ||
|
|
fb0ff50837 | ||
|
|
93727a0ac7 | ||
|
|
2641e70c78 | ||
|
|
bc44584698 | ||
|
|
82394dd7a3 | ||
|
|
2e688ad686 | ||
|
|
9b998e0c6d | ||
|
|
1045588301 | ||
|
|
ba86399fd3 | ||
|
|
a89164f885 | ||
|
|
7f2344c82c | ||
|
|
3c8e430533 | ||
|
|
f7209fba53 | ||
|
|
9fae683d8b | ||
|
|
79a2b98a1a | ||
|
|
98b28a631a | ||
|
|
6fec64f515 | ||
|
|
01d5890b35 | ||
|
|
fea583eb5b | ||
|
|
bfe5039a1c | ||
|
|
7a57d944c8 | ||
|
|
ca27e87241 | ||
|
|
e674a1ece4 | ||
|
|
dfb63346d3 | ||
|
|
4d899d48dc | ||
|
|
fa3a3dfcb0 | ||
|
|
e36210aa27 | ||
|
|
20a599594c | ||
|
|
70f8dbae53 | ||
|
|
d8022b2682 | ||
|
|
0d7c5b8ace | ||
|
|
88c9850c44 | ||
|
|
f1ed62cdca | ||
|
|
bfac86d5dd | ||
|
|
341015c584 | ||
|
|
7c5a66978e | ||
|
|
b21fc3f5e7 | ||
|
|
0e52628842 | ||
|
|
f7922cafa5 | ||
|
|
8c5496829e | ||
|
|
8514f051a7 | ||
|
|
61feb29fe2 | ||
|
|
fa29881f04 | ||
|
|
46cb8e7d0b | ||
|
|
b6143bc75e | ||
|
|
92e1ec05d2 | ||
|
|
75f23bb1bf | ||
|
|
5f5731f813 | ||
|
|
55159be0dc | ||
|
|
0c4e1dc7ae | ||
|
|
b4abdeb246 | ||
|
|
7e61dda4aa | ||
|
|
283aafb27d |
12
.env
@@ -1,14 +1,8 @@
|
||||
# port
|
||||
VITE_DEV_PORT = '8001'
|
||||
VITE_DEV_PORT = '8080'
|
||||
|
||||
# development path
|
||||
VITE_DEV_PATH = '/'
|
||||
VITE_DEV_PATH = 'https://demo.mtruning.club'
|
||||
|
||||
# production path
|
||||
VITE_PRO_PATH = '/'
|
||||
|
||||
# spa-title
|
||||
VITE_GLOB_APP_TITLE = GoView
|
||||
|
||||
# spa shortname
|
||||
VITE_GLOB_APP_SHORT_NAME = GoView
|
||||
VITE_PRO_PATH = 'https://demo.mtruning.club'
|
||||
2
.gitignore
vendored
@@ -4,5 +4,3 @@ dist
|
||||
dist-ssr
|
||||
*.local
|
||||
.vscode
|
||||
.idea
|
||||
pnpm-lock
|
||||
284
README.md
@@ -1,227 +1,119 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a
|
||||
href="https://ai.goviewlink.com/saas/"
|
||||
target="_blank"
|
||||
style="
|
||||
padding: 10px 20px;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
">
|
||||
<img src="readme/GoViewPro.png" alt="go-view" />
|
||||
</a>
|
||||
</p>
|
||||
## 总览
|
||||
|
||||
<p align="center">
|
||||
<img src="readme/logo-t-y.png" alt="go-view" />
|
||||
</p>
|
||||
**`master-fetch` 分支是带有后端接口请求的分支**
|
||||
|
||||
<h4 align="center">
|
||||
开源、精美、便捷的「数据可视化」低代码开发平台
|
||||
</h4>
|
||||
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
|
||||
|
||||
<h4 align="center">
|
||||
<img src="https://gitee.com/dromara/go-view/badge/star.svg?theme=gvp" style="position: relative; display: inline-block; top: 6px; border-radius: 0px;" />
|
||||
<img src="https://gitcode.com/GoView/go-view/star/badge.svg" style="display: inline-block; position: relative; top: 4px;">
|
||||
</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> </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.mingdao.com?s=utm_88&utm_source=Goview&utm_medium=banner&utm_campaign=gitee&utm_content=IT%E8%B5%8B%E8%83%BD%E4%B8%9A%E5%8A%A1"
|
||||
target="_blank"
|
||||
style="
|
||||
padding: 10px 20px;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
background: #f9f9f9;
|
||||
">
|
||||
<img src="readme/sponsors/mdy-banner.png" alt="go-view" style="width: 270px;" width="270px"/>
|
||||
</a>
|
||||
<a
|
||||
href="https://doc.hummingbird.winc-link.com?from=Goview"
|
||||
target="_blank"
|
||||
style="
|
||||
padding: 10px 20px;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
background: #f9f9f9;
|
||||
">
|
||||
<img src="readme/sponsors/yingchuang-banner.png" alt="go-view" style="width: 270px;" width="270px"/>
|
||||
</a>
|
||||
<br/>
|
||||
<br/>
|
||||
<a
|
||||
href="https://www.mtruning.club/chengDan/index.html"
|
||||
target="_blank"
|
||||
style="
|
||||
padding: 10px 20px;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
background: #f9f9f9;
|
||||
">
|
||||
<img src="readme/sponsors/chengdan-banner.png" alt="go-view" style="width: 270px;" width="270px"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
所有的接口地址位置:`src\api\path\*`
|
||||
|
||||
#### 😶 **纯前端** 分支: **`master`**
|
||||
接口地址修改:`.env`
|
||||
|
||||
#### 👻 携带 **后端** 请求分支: **`master-fetch`**
|
||||
```shell
|
||||
# port
|
||||
VITE_DEV_PORT = '8080'
|
||||
|
||||
#### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
|
||||
# development path
|
||||
VITE_DEV_PATH = 'http://127.0.0.1:8080'
|
||||
|
||||
项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
|
||||
# production path
|
||||
VITE_PRO_PATH = 'http://127.0.0.1:8080'
|
||||
```
|
||||
|
||||
项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
|
||||
公共前缀修改:`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
|
||||
import axiosInstance from './axios'
|
||||
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
- `JAVA` [https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve) (当前使用)
|
||||
- `.NET` [https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
|
||||
- `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)
|
||||
- `GO-goframe` [https://gitee.com/bufanyun/go-view-server](https://gitee.com/bufanyun/go-view-server)
|
||||
- `GO-gin` [https://gitee.com/ls1990/go-view-serve](https://gitee.com/ls1990/go-view-serve)
|
||||
- `接口文档` [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) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.POST,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
|
||||
export const put = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PUT,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
|
||||
export const del = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.DELETE,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
|
||||
// 获取请求函数,默认get
|
||||
export const http = (type?: RequestHttpEnum) => {
|
||||
switch (type) {
|
||||
case RequestHttpEnum.GET:
|
||||
return get
|
||||
|
||||
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
|
||||
case RequestHttpEnum.POST:
|
||||
return post
|
||||
|
||||
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
|
||||
case RequestHttpEnum.PUT:
|
||||
return put
|
||||
|
||||
- 可视化:基于开源图表库[ECharts](https://echarts.apache.org/zh/index.html) 和 [VChart](https://www.visactor.io/vchart) 编写,具有丰富的图表类型和适配大屏的主题效果;
|
||||
case RequestHttpEnum.DELETE:
|
||||
return del
|
||||
|
||||
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
|
||||
default:
|
||||
return get
|
||||
}
|
||||
}
|
||||
|
||||
说明文档:
|
||||

|
||||
|
||||
工作台:
|
||||

|
||||
|
||||
请求配置:
|
||||

|
||||
|
||||
数据过滤:
|
||||

|
||||
|
||||
高级事件编辑:
|
||||

|
||||
|
||||
自定义组件颜色:
|
||||

|
||||
|
||||
快捷主页:
|
||||

|
||||
|
||||
主题色:
|
||||

|
||||
|
||||
亮白主题:
|
||||

|
||||
|
||||
最新动态: 整合字节图表框架 VChart[https://visactor.io/vchart](https://visactor.io/vchart)
|
||||

|
||||
|
||||
主要技术栈为:
|
||||
|
||||
| 名称 | 版本 | 名称 | 版本 |
|
||||
| ------------------- | ----- | ----------- | ------ |
|
||||
| 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 | 18.20.x | npm | 10.7.x |
|
||||
| pnpm | 8.6.7 | windows | 11 |
|
||||
|
||||
已完成图表:
|
||||
|
||||
| 分类 | 名称 | 名称 | 名称 | 名称 |
|
||||
| ------ | ---------------- | ---------- | -------------- | ------------------------ |
|
||||
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
|
||||
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
|
||||
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
|
||||
| \* | 漏斗图 | 中国地图 | 高德地图 | 🦊 |
|
||||
| 信息 | 文字 | 渐变文字 | 词云 | 嵌套网页 |
|
||||
| \* | 图片 | 视频 | 😺 | 🐯 |
|
||||
| 列表 | 滚动排名列表 | 滚动表格 | 🐮 | 🐐 |
|
||||
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
|
||||
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 |
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
|
||||
|
||||
## 安装
|
||||
|
||||
请查看文档:[https://www.mtruning.club/](https://www.mtruning.club/)
|
||||
```
|
||||
|
||||
## 代码提交
|
||||
|
||||
- feat: 新功能
|
||||
- fix: 修复 Bug
|
||||
- docs: 文档修改
|
||||
- perf: 性能优化
|
||||
- revert: 版本回退
|
||||
- ci: CICD 集成相关
|
||||
- test: 添加测试代码
|
||||
- refactor: 代码重构
|
||||
- build: 影响项目构建或依赖修改
|
||||
- style: 不影响程序逻辑的代码修改
|
||||
- chore: 不属于以上类型的其他类型(日常事务)
|
||||
* feat: 新功能
|
||||
* fix: 修复 Bug
|
||||
* docs: 文档修改
|
||||
* perf: 性能优化
|
||||
* revert: 版本回退
|
||||
* ci: CICD集成相关
|
||||
* test: 添加测试代码
|
||||
* refactor: 代码重构
|
||||
* build: 影响项目构建或依赖修改
|
||||
* style: 不影响程序逻辑的代码修改
|
||||
* chore: 不属于以上类型的其他类型(日常事务)
|
||||
|
||||
## 交流群
|
||||
## 交流
|
||||
|
||||
QQ 群:687586375
|
||||
QQ 群:1030129384
|
||||
|
||||
<img width="260px" src="readme/go-view-qq.jpg" alt="QQ群" style="border-radius: 20px" />
|
||||
|
||||
## Pro 部分功能展示
|
||||
|
||||
体验地址: <a href="https://ai.goviewlink.com/saas/" target="_blank">https://ai.goviewlink.com/saas/</a>
|
||||

|
||||
|
||||

|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* 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, '');
|
||||
};
|
||||
@@ -7,8 +7,10 @@
|
||||
<meta name="description" content="GoView 是高效、高性能的拖拽式低代码数据可视化开发平台,将页面元素封装为基础组件,无需编写代码即可完成业务需求。">
|
||||
<meta name="keywords" content="GoView,goview,低代码,可视化">
|
||||
<meta name="author" content="奔跑的面条,面条">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1,maximum-scale=1,user-scalable=0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=yes" media="(min-width: 769px)">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||
/>
|
||||
<link rel="icon" href="./favicon.ico" />
|
||||
<title>GoView</title>
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
|
||||
27
package.json
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "go-view",
|
||||
"version": "1.3.2",
|
||||
"version": "2.2.0",
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview",
|
||||
"new": "plop --plopfile ./plop/plopfile.js",
|
||||
"postinstall": "husky install",
|
||||
@@ -16,15 +16,12 @@
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
"@amap/amap-jsapi-types": "^0.0.8",
|
||||
"@iconify/json": "^2.2.158",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@visactor/vchart": "^2.0.0",
|
||||
"@visactor/vchart-theme": "^1.12.2",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.4.0",
|
||||
"axios": "^0.27.2",
|
||||
"color": "^4.2.3",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.11.7",
|
||||
@@ -35,17 +32,15 @@
|
||||
"gsap": "^3.11.3",
|
||||
"highlight.js": "^11.5.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"iconify-icon": "^1.0.8",
|
||||
"keymaster": "^1.6.2",
|
||||
"mitt": "^3.0.0",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"naive-ui": "2.40.3",
|
||||
"naive-ui": "2.34.3",
|
||||
"pinia": "^2.0.13",
|
||||
"screenfull": "^6.0.1",
|
||||
"three": "^0.145.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue": "^3.2.31",
|
||||
"vue-demi": "^0.13.1",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "4.0.12",
|
||||
"vue3-lazyload": "^0.2.5-beta",
|
||||
"vue3-sketch-ruler": "^1.3.3",
|
||||
@@ -60,8 +55,8 @@
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"@vicons/carbon": "^0.12.0",
|
||||
"@vicons/ionicons5": "~0.11.0",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||
"@vitejs/plugin-vue": "^1.10.2",
|
||||
"@vitejs/plugin-vue-jsx": "^1.3.9",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
"@vueuse/core": "^7.7.1",
|
||||
"commitlint": "^17.0.2",
|
||||
@@ -77,10 +72,10 @@
|
||||
"mockjs": "^1.1.0",
|
||||
"plop": "^3.0.5",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "1.49.11",
|
||||
"sass": "^1.49.11",
|
||||
"sass-loader": "^12.6.0",
|
||||
"typescript": "4.6.3",
|
||||
"vite": "4.3.6",
|
||||
"vite": "2.9.9",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-importer": "^0.2.5",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
|
||||
10407
pnpm-lock.yaml
generated
10
preview.yml
@@ -1,10 +0,0 @@
|
||||
# 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)
|
||||
|
Before Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 292 KiB |
|
Before Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 70 KiB |
BIN
readme/go-view-qq.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 404 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 136 KiB |
@@ -17,7 +17,7 @@
|
||||
import { NConfigProvider } from 'naive-ui'
|
||||
import { GoAppProvider } from '@/components/GoAppProvider'
|
||||
import { I18n } from '@/components/I18n'
|
||||
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
|
||||
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
|
||||
|
||||
// 暗黑主题
|
||||
const darkTheme = useDarkThemeHook()
|
||||
@@ -28,7 +28,10 @@ const overridesTheme = useThemeOverridesHook()
|
||||
// 代码主题
|
||||
const hljsTheme = useCode()
|
||||
|
||||
// 系统全局数据初始化
|
||||
useSystemInit()
|
||||
|
||||
// 全局语言
|
||||
const { locale, dateLocale } = useLang()
|
||||
//测试提交
|
||||
|
||||
</script>
|
||||
|
||||
14
src/api/axios.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
// 接口白名单(免登录)
|
||||
export const fetchAllowList = [
|
||||
// 登录
|
||||
`${ModuleTypeEnum.SYSTEM}/login`,
|
||||
// 获取 OSS 接口
|
||||
`${ModuleTypeEnum.SYSTEM}/getOssInfo`,
|
||||
// 预览获取数据
|
||||
`${ModuleTypeEnum.PROJECT}/getData`,
|
||||
]
|
||||
|
||||
// 接口黑名单
|
||||
export const fetchBlockList = []
|
||||
@@ -1,30 +1,82 @@
|
||||
import axios, { AxiosResponse, InternalAxiosRequestConfig, AxiosError } from 'axios'
|
||||
import { ResultEnum } from "@/enums/httpEnum"
|
||||
import { ErrorPageNameMap } from "@/enums/pageEnum"
|
||||
import { redirectErrorPage } from '@/utils'
|
||||
import axios, { AxiosResponse, AxiosRequestConfig, Axios } from 'axios'
|
||||
import { ResultEnum, ModuleTypeEnum } from "@/enums/httpEnum"
|
||||
import { PageEnum, ErrorPageNameMap } from "@/enums/pageEnum"
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { axiosPre } from '@/settings/httpSetting'
|
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
|
||||
import { fetchAllowList } from './axios.config'
|
||||
import includes from 'lodash/includes'
|
||||
|
||||
export interface MyResponseType<T> {
|
||||
code: ResultEnum
|
||||
data: T
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface MyRequestInstance extends Axios {
|
||||
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
|
||||
}
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: import.meta.env.DEV ? import.meta.env.VITE_DEV_PATH : import.meta.env.VITE_PRO_PATH,
|
||||
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
|
||||
timeout: ResultEnum.TIMEOUT,
|
||||
})
|
||||
}) as unknown as MyRequestInstance
|
||||
|
||||
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 = {
|
||||
...config.headers,
|
||||
[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
Promise.reject(error)
|
||||
(err: AxiosRequestConfig) => {
|
||||
Promise.reject(err)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
axiosInstance.interceptors.response.use(
|
||||
(res: AxiosResponse) => {
|
||||
// 预览页面错误不进行处理
|
||||
if (isPreview()) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
const { code } = res.data as { code: number }
|
||||
if (code === undefined || code === null) return Promise.resolve(res.data)
|
||||
if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
|
||||
// 重定向
|
||||
if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
|
||||
|
||||
if (code === undefined || code === null) return Promise.resolve(res)
|
||||
|
||||
// 成功
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 登录过期
|
||||
if (code === ResultEnum.TOKEN_OVERDUE) {
|
||||
window['$message'].error(window['$t']('http.token_overdue_message'))
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 固定错误码重定向
|
||||
if (ErrorPageNameMap.get(code)) {
|
||||
redirectErrorPage(code)
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 提示错误
|
||||
window['$message'].error(window['$t']((res.data as any).msg))
|
||||
return Promise.resolve(res.data)
|
||||
},
|
||||
(err: AxiosResponse) => {
|
||||
|
||||
@@ -9,16 +9,16 @@ import {
|
||||
} from '@/enums/httpEnum'
|
||||
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
|
||||
export const get = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
export const get = <T = any>(url: string, params?: object) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.GET,
|
||||
params: params
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
export const post = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
export const post = <T = any>(url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.POST,
|
||||
data: data,
|
||||
@@ -28,8 +28,8 @@ export const post = (url: string, data?: object, headersType?: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const patch = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
export const patch = <T = any>(url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PATCH,
|
||||
data: data,
|
||||
@@ -39,8 +39,8 @@ export const patch = (url: string, data?: object, headersType?: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const put = (url: string, data?: object, headersType?: ContentTypeEnum) => {
|
||||
return axiosInstance({
|
||||
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PUT,
|
||||
data: data,
|
||||
@@ -50,8 +50,8 @@ export const put = (url: string, data?: object, headersType?: ContentTypeEnum) =
|
||||
})
|
||||
}
|
||||
|
||||
export const del = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
export const del = <T = any>(url: string, params?: object) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.DELETE,
|
||||
params
|
||||
@@ -82,11 +82,11 @@ export const http = (type?: RequestHttpEnum) => {
|
||||
}
|
||||
const prefix = 'javascript:'
|
||||
// 对输入字符进行转义处理
|
||||
export const translateStr = (target: string | object) => {
|
||||
export const translateStr = (target: string | Record<any, any>) => {
|
||||
if (typeof target === 'string') {
|
||||
if (target.startsWith(prefix)) {
|
||||
const funcStr = target.split(prefix)[1]
|
||||
let result;
|
||||
let result
|
||||
try {
|
||||
result = new Function(`${funcStr}`)()
|
||||
} catch (error) {
|
||||
@@ -100,8 +100,8 @@ export const translateStr = (target: string | object) => {
|
||||
}
|
||||
for (const key in target) {
|
||||
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
||||
const subTarget = (target as any)[key];
|
||||
(target as any)[key] = translateStr(subTarget)
|
||||
const subTarget = target[key]
|
||||
target[key] = translateStr(subTarget)
|
||||
}
|
||||
}
|
||||
return target
|
||||
@@ -163,6 +163,7 @@ export const customizeHttp = (targetParams: RequestConfigType, globalParams: Req
|
||||
params = translateStr(params)
|
||||
// form 类型处理
|
||||
let formData: FormData = new FormData()
|
||||
formData.set('default', 'defaultData')
|
||||
// 类型处理
|
||||
|
||||
switch (requestParamsBodyType) {
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "0",
|
||||
"name": "Myriel",
|
||||
"symbolSize": "@integer(0, 50)",
|
||||
"x": -266.82776,
|
||||
"y": 299.6904,
|
||||
"value": "@integer(0, 50)",
|
||||
"category": 3
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Napoleon",
|
||||
"symbolSize": "@integer(0, 50)",
|
||||
"x": -418.08344,
|
||||
"y": 446.8853,
|
||||
"value": "@integer(0, 50)",
|
||||
"category": 5
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "MlleBaptistine",
|
||||
"symbolSize": "@integer(0, 50)",
|
||||
"x": -212.76357,
|
||||
"y": 245.29176,
|
||||
"value": "@integer(0, 50)",
|
||||
"category": 1
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"name": "MmeMagloire",
|
||||
"symbolSize": "@integer(0, 50)",
|
||||
"x": -242.82404,
|
||||
"y": 235.26283,
|
||||
"value": "@integer(0, 50)",
|
||||
"category": 1
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"name": "CountessDeLo",
|
||||
"symbolSize": "@integer(0, 50)",
|
||||
"x": -379.30386,
|
||||
"y": 429.06424,
|
||||
"value": "@integer(0, 50)",
|
||||
"category": 0
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"source": "1",
|
||||
"target": "@integer(2, 4)"
|
||||
},
|
||||
{
|
||||
"source": "2",
|
||||
"target": "@integer(3, 4)"
|
||||
},
|
||||
{
|
||||
"source": "3",
|
||||
"target": "@integer(0, 2)"
|
||||
},
|
||||
{
|
||||
"source": "3",
|
||||
"target": "@integer(0, 1)"
|
||||
},
|
||||
{
|
||||
"source": "4",
|
||||
"target": "@integer(0, 3)"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "A"
|
||||
},
|
||||
{
|
||||
"name": "B"
|
||||
},
|
||||
{
|
||||
"name": "C"
|
||||
},
|
||||
{
|
||||
"name": "D"
|
||||
},
|
||||
{
|
||||
"name": "E"
|
||||
},
|
||||
{
|
||||
"name": "F"
|
||||
},
|
||||
{
|
||||
"name": "G"
|
||||
},
|
||||
{
|
||||
"name": "H"
|
||||
},
|
||||
{
|
||||
"name": "I"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import test from './test.mock'
|
||||
import vchart from './vchart.mock'
|
||||
import { MockMethod } from 'vite-plugin-mock'
|
||||
import { RequestHttpEnum } from '@/enums/httpEnum'
|
||||
|
||||
@@ -20,10 +19,6 @@ export const capsuleUrl = '/mock/capsule'
|
||||
export const wordCloudUrl = '/mock/wordCloud'
|
||||
export const treemapUrl = '/mock/treemap'
|
||||
export const threeEarth01Url = '/mock/threeEarth01Data'
|
||||
export const sankeyUrl = '/mock/sankey'
|
||||
export const graphUrl = '/mock/graphData'
|
||||
|
||||
export const vchartBarDataUrl = '/mock/vchart/barDataUrl'
|
||||
|
||||
const mockObject: MockMethod[] = [
|
||||
{
|
||||
@@ -108,21 +103,6 @@ const mockObject: MockMethod[] = [
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => test.threeEarth01Data
|
||||
},
|
||||
{
|
||||
url: sankeyUrl,
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => test.fetchSankey
|
||||
},
|
||||
{
|
||||
url: graphUrl,
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => test.graphData
|
||||
},
|
||||
{
|
||||
url: vchartBarDataUrl,
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => vchart.bar
|
||||
}
|
||||
]
|
||||
|
||||
export default mockObject
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"label": [
|
||||
{
|
||||
"name": "a"
|
||||
},
|
||||
{
|
||||
"name": "b"
|
||||
},
|
||||
{
|
||||
"name": "a1"
|
||||
},
|
||||
{
|
||||
"name": "a2"
|
||||
},
|
||||
{
|
||||
"name": "b1"
|
||||
},
|
||||
{
|
||||
"name": "b2"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"source": "a",
|
||||
"target": "a1",
|
||||
"value": "@integer(0, 10)"
|
||||
},
|
||||
{
|
||||
"source": "a",
|
||||
"target": "a2",
|
||||
"value": "@integer(0, 10)"
|
||||
},
|
||||
{
|
||||
"source": "b",
|
||||
"target": "b1",
|
||||
"value": "@integer(0, 10)"
|
||||
},
|
||||
{
|
||||
"source": "a",
|
||||
"target": "b1",
|
||||
"value": "@integer(0, 10)"
|
||||
},
|
||||
{
|
||||
"source": "b1",
|
||||
"target": "a1",
|
||||
"value": "@integer(0, 10)"
|
||||
},
|
||||
{
|
||||
"source": "b1",
|
||||
"target": "b2",
|
||||
"value": "@integer(0, 10)"
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"depth": 0,
|
||||
"itemStyle": {
|
||||
"color": "#decbe4"
|
||||
},
|
||||
"lineStyle": {
|
||||
"color": "source",
|
||||
"opacity": 0.9
|
||||
}
|
||||
},
|
||||
{
|
||||
"depth": 1,
|
||||
"itemStyle": {
|
||||
"color": "#b3cde3"
|
||||
},
|
||||
"lineStyle": {
|
||||
"color": "source",
|
||||
"opacity": 0.6
|
||||
}
|
||||
},
|
||||
{
|
||||
"depth": 2,
|
||||
"itemStyle": {
|
||||
"color": "#ccebc5"
|
||||
},
|
||||
"lineStyle": {
|
||||
"color": "source",
|
||||
"opacity": 0.6
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,8 +2,6 @@ import heatmapJson from './heatMapData.json'
|
||||
import scatterJson from './scatter.json'
|
||||
import mapJson from './map.json'
|
||||
import tTreemapJson from './treemap.json'
|
||||
import sankeyJson from './sankey.json'
|
||||
import graphDataJson from './graph.json'
|
||||
|
||||
export default {
|
||||
// 单图表
|
||||
@@ -221,19 +219,5 @@ export default {
|
||||
'endArray|10': [{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }]
|
||||
}
|
||||
]
|
||||
},
|
||||
// 桑基图
|
||||
fetchSankey: {
|
||||
code: 0,
|
||||
status: 200,
|
||||
msg: '请求成功',
|
||||
data: sankeyJson
|
||||
},
|
||||
// 关系图
|
||||
graphData: {
|
||||
code: 0,
|
||||
status: 200,
|
||||
msg: '请求成功',
|
||||
data: graphDataJson
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import bar from './vchart/bar.json'
|
||||
|
||||
export default {
|
||||
bar: {
|
||||
code: 0,
|
||||
status: 200,
|
||||
msg: '请求成功',
|
||||
data: bar
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"values": [
|
||||
{ "type": "Nail polish", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "USA", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "USA", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "USA", "value|100-900": 3 }
|
||||
]
|
||||
}
|
||||
2
src/api/path/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from '@/api/path/project.api'
|
||||
export * from '@/api/path/system.api'
|
||||
98
src/api/path/project.api.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { http } from '@/api/http'
|
||||
import { httpErrorHandle } from '@/utils'
|
||||
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
import { ProjectItem, ProjectDetail } from './project'
|
||||
|
||||
// * 项目列表
|
||||
export const projectListApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 新增项目
|
||||
export const createProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
id: number
|
||||
}>(`${ModuleTypeEnum.PROJECT}/create`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 获取项目
|
||||
export const fetchProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectDetail>(`${ModuleTypeEnum.PROJECT}/getData`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 保存项目
|
||||
export const saveProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(
|
||||
`${ModuleTypeEnum.PROJECT}/save/data`,
|
||||
data,
|
||||
ContentTypeEnum.FORM_URLENCODED
|
||||
)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改项目基础信息
|
||||
export const updateProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 删除项目
|
||||
export const deleteProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.DELETE)(`${ModuleTypeEnum.PROJECT}/delete`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改发布状态 [-1未发布,1发布]
|
||||
export const changeProjectReleaseApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/publish`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 上传文件
|
||||
export const uploadFile = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
fileName: string
|
||||
}>(`${ModuleTypeEnum.PROJECT}/upload`, data, ContentTypeEnum.FORM_DATA)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
39
src/api/path/project.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
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
|
||||
}
|
||||
39
src/api/path/system.api.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
26
src/api/path/system.d.ts
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface LoginResult {
|
||||
token: {
|
||||
/**
|
||||
* token 值
|
||||
*/
|
||||
tokenValue: string
|
||||
/**
|
||||
* token key
|
||||
*/
|
||||
tokenName: string
|
||||
}
|
||||
userinfo: {
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
nickname: string
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
username: string
|
||||
/**
|
||||
* 用户 id
|
||||
*/
|
||||
id: string
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 377 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 999 B |
|
Before Width: | Height: | Size: 983 B |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 475 KiB |
|
Before Width: | Height: | Size: 46 KiB |
@@ -1,3 +0,0 @@
|
||||
import GoIconify from './index.vue';
|
||||
|
||||
export { GoIconify };
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<iconify-icon
|
||||
:icon="icon"
|
||||
:rotate="`${rotate}deg`"
|
||||
:width="width"
|
||||
:style="{
|
||||
color: color
|
||||
}"
|
||||
></iconify-icon>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#999999',
|
||||
required: false
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: '20',
|
||||
required: false
|
||||
},
|
||||
rotate: {
|
||||
type: [String, Number],
|
||||
default: '0',
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -27,7 +27,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { h, ref } from 'vue'
|
||||
import { NAvatar, NText } from 'naive-ui'
|
||||
import { renderIcon } from '@/utils'
|
||||
import { renderIcon, getLocalStorage } from '@/utils'
|
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { logout, renderLang } from '@/utils'
|
||||
import { GoSystemSet } from '@/components/GoSystemSet/index'
|
||||
import { GoSystemInfo } from '@/components/GoSystemInfo/index'
|
||||
@@ -64,7 +66,17 @@ const renderUserInfo = () => {
|
||||
}),
|
||||
h('div', null, [
|
||||
h('div', null, [
|
||||
h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
|
||||
h(NText, { depth: 2 }, {
|
||||
default: () => {
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
if (info) {
|
||||
return info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_NAME];
|
||||
}
|
||||
else {
|
||||
return 'admin';
|
||||
}
|
||||
}
|
||||
})
|
||||
])
|
||||
])
|
||||
]
|
||||
@@ -137,4 +149,4 @@ const handleSelect = (key: string) => {
|
||||
cursor: pointer;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,3 +0,0 @@
|
||||
import GoVChart from './index.vue'
|
||||
|
||||
export { GoVChart }
|
||||
@@ -1,250 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
ref="vChartRef"
|
||||
v-on="{
|
||||
...Object.fromEntries(event.map((eventName: string) => [eventName, (eventData: MouseEvent) => eventHandlers(eventData, eventName)]))
|
||||
}"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType, watch, onBeforeUnmount, nextTick, toRaw, toRefs } from 'vue'
|
||||
import { VChart, type IVChart, type IInitOption } from '@visactor/vchart'
|
||||
import { transformHandler } from './transformProps'
|
||||
import { IOption } from '@/packages/components/VChart/index.d'
|
||||
import { registerChartsAndComponents } from './register'
|
||||
|
||||
// VChart按需加载: 注册图表及组件
|
||||
registerChartsAndComponents()
|
||||
|
||||
// 事件说明 v1.13.0 https://www.visactor.io/vchart/api/API/event
|
||||
const event = [
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'mouseupoutside',
|
||||
'rightdown',
|
||||
'rightup',
|
||||
'rightupoutside',
|
||||
'click',
|
||||
'dblclick',
|
||||
'mousemove',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'mouseenter',
|
||||
'mouseleave',
|
||||
'wheel',
|
||||
'touchstart',
|
||||
'touchend',
|
||||
'touchendoutside',
|
||||
'touchmove',
|
||||
'touchcancel',
|
||||
'tap',
|
||||
'dragstart',
|
||||
'dragend',
|
||||
'drag',
|
||||
'dragenter',
|
||||
'dragleave',
|
||||
'dragover',
|
||||
'drop',
|
||||
'pan',
|
||||
'panstart',
|
||||
'panend',
|
||||
'press',
|
||||
'pressup',
|
||||
'pressend',
|
||||
'pinch',
|
||||
'pinchstart',
|
||||
'pinchend',
|
||||
'swipe',
|
||||
'dimensionHover',
|
||||
'dimensionClick',
|
||||
'dataZoomChange',
|
||||
'scrollBarChange',
|
||||
'brushStart',
|
||||
'brushChange',
|
||||
'brushEnd',
|
||||
'brushClear',
|
||||
'drill',
|
||||
'legendItemClick',
|
||||
'legendItemHover',
|
||||
'legendItemUnHover',
|
||||
'legendFilter',
|
||||
'initialized',
|
||||
'rendered',
|
||||
'renderFinished',
|
||||
'animationFinished',
|
||||
'layoutStart',
|
||||
'layoutEnd',
|
||||
'afterResizef'
|
||||
]
|
||||
const emit = defineEmits([
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'mouseupoutside',
|
||||
'rightdown',
|
||||
'rightup',
|
||||
'rightupoutside',
|
||||
'click',
|
||||
'dblclick',
|
||||
'mousemove',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'mouseenter',
|
||||
'mouseleave',
|
||||
'wheel',
|
||||
'touchstart',
|
||||
'touchend',
|
||||
'touchendoutside',
|
||||
'touchmove',
|
||||
'touchcancel',
|
||||
'tap',
|
||||
'dragstart',
|
||||
'dragend',
|
||||
'drag',
|
||||
'dragenter',
|
||||
'dragleave',
|
||||
'dragover',
|
||||
'drop',
|
||||
'pan',
|
||||
'panstart',
|
||||
'panend',
|
||||
'press',
|
||||
'pressup',
|
||||
'pressend',
|
||||
'pinch',
|
||||
'pinchstart',
|
||||
'pinchend',
|
||||
'swipe',
|
||||
'dimensionHover',
|
||||
'dimensionClick',
|
||||
'dataZoomChange',
|
||||
'scrollBarChange',
|
||||
'brushStart',
|
||||
'brushChange',
|
||||
'brushEnd',
|
||||
'brushClear',
|
||||
'drill',
|
||||
'legendItemClick',
|
||||
'legendItemHover',
|
||||
'legendItemUnHover',
|
||||
'legendFilter',
|
||||
'initialized',
|
||||
'rendered',
|
||||
'renderFinished',
|
||||
'animationFinished',
|
||||
'layoutStart',
|
||||
'layoutEnd',
|
||||
'afterResizef'
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object as PropType<
|
||||
IOption & {
|
||||
dataset: any
|
||||
}
|
||||
>,
|
||||
required: true
|
||||
},
|
||||
initOptions: {
|
||||
type: Object as PropType<
|
||||
IInitOption & {
|
||||
deepWatch?: boolean | number
|
||||
}
|
||||
>,
|
||||
required: false,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const vChartRef = ref()
|
||||
let chart: IVChart
|
||||
|
||||
// 解构 props.option,排除 dataset
|
||||
const { dataset, ...restOfOption } = toRefs(props.option)
|
||||
|
||||
// 排除 data 监听
|
||||
watch(
|
||||
() => ({
|
||||
...restOfOption
|
||||
}),
|
||||
() => {
|
||||
nextTick(() => {
|
||||
createOrUpdateChart(props.option)
|
||||
})
|
||||
},
|
||||
{
|
||||
deep: props.initOptions?.deepWatch || true,
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => dataset.value,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
createOrUpdateChart(props.option)
|
||||
})
|
||||
},
|
||||
{
|
||||
deep: false
|
||||
}
|
||||
)
|
||||
|
||||
// 更新
|
||||
const createOrUpdateChart = (
|
||||
chartProps: IOption & {
|
||||
dataset: any
|
||||
}
|
||||
) => {
|
||||
if (vChartRef.value && !chart) {
|
||||
const spec = transformHandler[chartProps.category || '']?.(chartProps)
|
||||
chart = new VChart(
|
||||
{ ...spec, data: chartProps.dataset },
|
||||
{
|
||||
dom: vChartRef.value,
|
||||
...props.initOptions
|
||||
}
|
||||
)
|
||||
chart.renderSync()
|
||||
return true
|
||||
} else if (chart) {
|
||||
const spec = transformHandler[chartProps.category || '']?.(chartProps)
|
||||
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined }, false, undefined, {
|
||||
change: false,
|
||||
reMake: true,
|
||||
reAnimate: true
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 刷新
|
||||
const refresh = () => {
|
||||
if (chart) {
|
||||
chart.renderSync()
|
||||
}
|
||||
}
|
||||
|
||||
// 抛出事件
|
||||
const eventHandlers = (eventData: MouseEvent, eventName: string) => {
|
||||
if (event.includes(eventName)) emit(eventName as any, eventData)
|
||||
}
|
||||
|
||||
// 卸载
|
||||
onBeforeUnmount(() => {
|
||||
if (chart) {
|
||||
chart.release()
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
// 重刷新
|
||||
refresh,
|
||||
release: () => {
|
||||
if (chart) {
|
||||
chart.release()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,29 +0,0 @@
|
||||
import { VChart } from '@visactor/vchart/esm/core';
|
||||
import { registerBarChart, registerAreaChart, registerLineChart, registerPieChart, registerFunnelChart, registerWordCloudChart, registerScatterChart } from '@visactor/vchart/esm/chart';
|
||||
import { registerTooltip, registerCartesianCrossHair, registerDiscreteLegend, registerLabel } from '@visactor/vchart/esm/component';
|
||||
import { registerDomTooltipHandler } from '@visactor/vchart/esm/plugin/components';
|
||||
import { registerAnimate } from '@visactor/vchart';
|
||||
|
||||
export const registerChartsAndComponents = () => {
|
||||
VChart.useRegisters([
|
||||
// 图表
|
||||
registerBarChart,
|
||||
registerAreaChart,
|
||||
registerLineChart,
|
||||
registerPieChart,
|
||||
registerScatterChart,
|
||||
registerFunnelChart,
|
||||
registerWordCloudChart,
|
||||
|
||||
// 组件
|
||||
registerTooltip,
|
||||
registerDomTooltipHandler,
|
||||
registerCartesianCrossHair,
|
||||
registerDiscreteLegend,
|
||||
registerLabel,
|
||||
|
||||
// 动画
|
||||
registerAnimate
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
// console.log('spec-area-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [
|
||||
{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
// paddingInner: 0.5
|
||||
},
|
||||
{
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}
|
||||
]
|
||||
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
|
||||
spec.label = {
|
||||
...spec.label,
|
||||
style: {
|
||||
...spec.label?.style,
|
||||
lineWidth: 0
|
||||
}
|
||||
}
|
||||
// console.log('spec-bar-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Datum } from "@visactor/vchart/esm/typings"
|
||||
import { cloneDeep } from "lodash"
|
||||
const INNER_RADIUS = 0.75
|
||||
const OUTER_RADIUS = 0.68
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// label
|
||||
spec.label = {
|
||||
visible: true,
|
||||
}
|
||||
|
||||
// console.log('spec-funnel-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ChatCategoryEnum, IOption } from "@/packages/components/VChart/index.d";
|
||||
import bars from './bars'
|
||||
import pies from './pies'
|
||||
import lines from './lines'
|
||||
import areas from './areas'
|
||||
import funnels from "./funnels";
|
||||
import wordClouds from "./wordClouds";
|
||||
import scatters from "./scatters";
|
||||
export const transformHandler: {
|
||||
[key: string]: (args: IOption) => any
|
||||
} = {
|
||||
[ChatCategoryEnum.BAR]: bars,
|
||||
[ChatCategoryEnum.PIE]: pies,
|
||||
[ChatCategoryEnum.LINE]: lines,
|
||||
[ChatCategoryEnum.AREA]: areas,
|
||||
[ChatCategoryEnum.FUNNEL]: funnels,
|
||||
[ChatCategoryEnum.WORDCLOUD]: wordClouds,
|
||||
[ChatCategoryEnum.SCATTER]: scatters,
|
||||
// todo: more charts handler
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [
|
||||
{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
},
|
||||
{
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}
|
||||
]
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
|
||||
spec.label = {
|
||||
...spec.label,
|
||||
style: {
|
||||
...spec.label?.style,
|
||||
lineWidth: 0
|
||||
}
|
||||
}
|
||||
// console.log('spec-line-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import { Datum } from '@visactor/vchart/esm/typings'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
if (spec.extensionMark) {
|
||||
// extensionMark
|
||||
spec.extensionMark = [
|
||||
{
|
||||
name: 'arc_inner_shadow',
|
||||
type: 'arc',
|
||||
dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
startAngle: (datum: Datum) => {
|
||||
return datum['__VCHART_ARC_START_ANGLE']
|
||||
},
|
||||
endAngle: (datum: Datum) => {
|
||||
return datum['__VCHART_ARC_END_ANGLE']
|
||||
},
|
||||
innerRadius: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * spec.innerRadius - 30
|
||||
},
|
||||
outerRadius: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * spec.innerRadius
|
||||
},
|
||||
fillOpacity: 0.3,
|
||||
fill: (datum: Datum, context: any) => {
|
||||
return context.seriesColor(datum[spec.seriesField])
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arc_inner',
|
||||
type: 'symbol',
|
||||
// dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
size: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * 2 * spec.innerRadius - 100
|
||||
},
|
||||
fillOpacity: 0,
|
||||
lineWidth: 1,
|
||||
strokeOpacity: 0.5,
|
||||
stroke: {
|
||||
gradient: 'conical',
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI * 2,
|
||||
stops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#FFF',
|
||||
opacity: 0
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#FFF',
|
||||
opacity: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arc_outer',
|
||||
type: 'symbol',
|
||||
// dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
size: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * 2 * spec.outerRadius + 50
|
||||
},
|
||||
fillOpacity: 0,
|
||||
lineWidth: 1,
|
||||
strokeOpacity: 0.5,
|
||||
stroke: {
|
||||
gradient: 'conical',
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI * 2,
|
||||
stops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#FFF',
|
||||
opacity: 0
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#FFF',
|
||||
opacity: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
return spec
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps,
|
||||
label: {
|
||||
formatMethod: (value: string) => Number(value).toFixed(2)
|
||||
}
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
// console.log('spec-scatter-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Datum } from "@visactor/vchart/esm/typings"
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
|
||||
// console.log('spec-word-cloud-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -257,36 +257,9 @@
|
||||
<n-switch v-model:value="legend.show" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="图例文字">
|
||||
<setting-item name="颜色">
|
||||
<setting-item>
|
||||
<n-color-picker size="small" v-model:value="legend.textStyle.color"></n-color-picker>
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="legend.textStyle.fontSize" :min="1" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="图例位置">
|
||||
<setting-item name="x轴">
|
||||
<n-select v-model:value="legend.x" size="small" :options="legendConfig.lengendX" />
|
||||
</setting-item>
|
||||
<setting-item name="y轴">
|
||||
<n-select v-model:value="legend.y" size="small" :options="legendConfig.lengendY" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="图例信息">
|
||||
<setting-item name="方向">
|
||||
<n-select v-model:value="legend.orient" size="small" :options="legendConfig.orient" />
|
||||
</setting-item>
|
||||
<setting-item name="形状">
|
||||
<n-select v-model:value="legend.icon" size="small" :options="legendConfig.shape" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="图例大小">
|
||||
<setting-item name="宽">
|
||||
<n-input-number v-model:value="legend.itemWidth" :min="1" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="高">
|
||||
<n-input-number v-model:value="legend.itemHeight" :min="1" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
|
||||
@@ -336,9 +309,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed, watch } from 'vue'
|
||||
import { PropType, computed } from 'vue'
|
||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
import { axisConfig, legendConfig } from '@/packages/chartConfiguration/echarts/index'
|
||||
import { axisConfig } from '@/packages/chartConfiguration/echarts/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem, GlobalSettingPosition } from '@/components/Pages/ChartItemSetting'
|
||||
import { icon } from '@/plugins'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
@@ -387,18 +360,4 @@ const grid = computed(() => {
|
||||
const visualMap = computed(() => {
|
||||
return props.optionData.visualMap
|
||||
})
|
||||
|
||||
// 监听legend color颜色改变type = scroll的颜色
|
||||
watch(() => legend.value && legend.value.textStyle.color, (newVal) => {
|
||||
if (legend.value && newVal) {
|
||||
if (!legend.value.pageTextStyle) {
|
||||
legend.value.pageTextStyle = { color: newVal }
|
||||
} else {
|
||||
legend.value.pageTextStyle.color = newVal
|
||||
}
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -69,22 +69,6 @@
|
||||
</setting-item>
|
||||
</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">
|
||||
<template #name>
|
||||
@@ -165,12 +149,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType } from 'vue'
|
||||
import { PropType } from 'vue'
|
||||
import { PickCreateComponentType, BlendModeEnumList } from '@/packages/index.d'
|
||||
import { SettingItemBox, SettingItem, CollapseItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { icon } from '@/plugins'
|
||||
import logoImg from '@/assets/logo.png'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
|
||||
const props = defineProps({
|
||||
isGroup: {
|
||||
@@ -193,48 +175,10 @@ const { HelpOutlineIcon } = icon.ionicons5
|
||||
const sliderFormatTooltip = (v: string) => {
|
||||
return `${(parseFloat(v) * 100).toFixed(0)}%`
|
||||
}
|
||||
|
||||
// 角度格式化
|
||||
const degFormatTooltip = (v: string) => {
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 预设滤镜
|
||||
.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>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="go-flipper" :class="[flipType, { go: isFlipping }]">
|
||||
<div class="go-Flipper" :class="[flipType, { go: isFlipping }]">
|
||||
<div class="digital front" :data-front="frontTextFromData"></div>
|
||||
<div class="digital back" :data-back="backTextFromData"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, PropType, watch, nextTick } from 'vue'
|
||||
import { FlipType } from './index'
|
||||
import { ref, PropType, watch } from 'vue'
|
||||
import { FlipType } from './index'
|
||||
|
||||
const props = defineProps({
|
||||
flipType: {
|
||||
@@ -43,10 +43,6 @@ const props = defineProps({
|
||||
backColor: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
borderWidth: {
|
||||
type: Number,
|
||||
default: 2
|
||||
}
|
||||
})
|
||||
|
||||
@@ -54,27 +50,19 @@ const isFlipping = ref(false)
|
||||
const frontTextFromData = ref(props.count || 0)
|
||||
const backTextFromData = ref(props.count || 0)
|
||||
|
||||
let timeoutID: any = 0
|
||||
|
||||
// 翻牌
|
||||
const flip = async (front: string | number, back: string | number) => {
|
||||
const flip = (front: string | number, back: string | number) => {
|
||||
// 如果处于翻转中,则不执行
|
||||
if (isFlipping.value) {
|
||||
isFlipping.value = false // 立即结束此次动画
|
||||
clearTimeout(timeoutID) // 清除上一个计时器任务
|
||||
await nextTick()
|
||||
await flip(front, back) // 开始最后一次翻牌任务
|
||||
return
|
||||
}
|
||||
|
||||
if (isFlipping.value) return
|
||||
// 设置翻盘前后数据
|
||||
backTextFromData.value = back
|
||||
frontTextFromData.value = front
|
||||
|
||||
// 设置翻转状态为true
|
||||
isFlipping.value = true
|
||||
|
||||
// 翻牌结束的行为
|
||||
timeoutID = setTimeout(() => {
|
||||
setTimeout(() => {
|
||||
isFlipping.value = false // 设置翻转状态为false
|
||||
frontTextFromData.value = back
|
||||
}, props.duration)
|
||||
@@ -98,7 +86,6 @@ $radius: v-bind('`${props.radius}px`');
|
||||
$width: v-bind('`${props.width}px`');
|
||||
$height: v-bind('`${props.height}px`');
|
||||
$perspective: v-bind('`${props.height * 2}px`');
|
||||
$borderWidth: v-bind('`${props.borderWidth * 2}px`');
|
||||
$speed: v-bind('`${props.duration / 1000}s`');
|
||||
$shadowColor: #000000;
|
||||
$lineColor: #4a9ef8;
|
||||
@@ -138,12 +125,13 @@ $lineColor: #4a9ef8;
|
||||
}
|
||||
// #endregion
|
||||
|
||||
.go-flipper {
|
||||
.go-Flipper {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: $width;
|
||||
height: $height;
|
||||
line-height: $height;
|
||||
border: solid 1px $backColor;
|
||||
border-radius: $radius;
|
||||
background: $frontColor;
|
||||
font-size: $width;
|
||||
@@ -151,17 +139,6 @@ $lineColor: #4a9ef8;
|
||||
box-shadow: 0 0 6px rgba($color: $shadowColor, $alpha: 0.5); // 阴影部分
|
||||
text-align: center;
|
||||
// font-family: 'Helvetica Neue';
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
box-shadow: inset 0 0 $borderWidth 0 $frontColor; // 内测阴影部分
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
.digital:before,
|
||||
.digital:after {
|
||||
@@ -209,13 +186,11 @@ $lineColor: #4a9ef8;
|
||||
&.down.go .front:before {
|
||||
transform-origin: 50% 100%;
|
||||
animation: frontFlipDown $speed ease-in-out both;
|
||||
box-shadow: 0 -2px $borderWidth 0 $frontColor;
|
||||
box-shadow: 0 -2px 6px rgba($color: $lineColor, $alpha: 0.3);
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
&.down.go .back:after {
|
||||
animation: backFlipDown $speed ease-in-out both;
|
||||
box-shadow: 0 2px $borderWidth 0 $frontColor;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
/*向上翻*/
|
||||
&.up .front:after {
|
||||
@@ -233,13 +208,11 @@ $lineColor: #4a9ef8;
|
||||
&.up.go .front:after {
|
||||
transform-origin: 50% 0;
|
||||
animation: frontFlipUp $speed ease-in-out both;
|
||||
box-shadow: 0 2px $borderWidth 0 $frontColor;
|
||||
box-shadow: 0 2px 6px rgba($color: $lineColor, $alpha: 0.3);
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
&.up.go .back:before {
|
||||
animation: backFlipUp $speed ease-in-out both;
|
||||
box-shadow: 0 -2px $borderWidth 0 $frontColor;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<collapse-item :name="axis.name">
|
||||
<template #header>
|
||||
<n-switch v-model:value="axis.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="单位">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.unit.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="内容">
|
||||
<n-input v-model:value="axis.unit.text" size="small"></n-input>
|
||||
</setting-item>
|
||||
<FontStyle :style="toRefs(axis.unit.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴标签">
|
||||
<setting-item v-if="axis.label" name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.label.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item v-if="axis.label" name="角度">
|
||||
<n-input-number v-model:value="axis.label.style.angle" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
<FontStyle v-if="axis.label" :style="toRefs(axis.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴标题">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.title.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="内容">
|
||||
<n-input v-model:value="axis.title.style.text" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="axis.title.position" :options="legendsConfig.position" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="角度">
|
||||
<n-input-number v-model:value="axis.title.angle" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
<FontStyle :style="toRefs(axis.title.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴线">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.domainLine.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name=""> </setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="axis.domainLine.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="axis.domainLine.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="网格线">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.grid.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="开启虚线">
|
||||
<n-space>
|
||||
<n-switch v-model:value="isLineDashRef" size="small" @update:value="changeLineDash"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="axis.grid.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="axis.grid.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, ref, toRefs } from 'vue'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
const props = defineProps({
|
||||
axis: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 判断是否是虚线
|
||||
const isDash = (data: undefined | Array<number>) => {
|
||||
if (!data || data.length === 0 || data[0] === 0) return false
|
||||
return true
|
||||
}
|
||||
|
||||
// 虚线
|
||||
const isLineDashRef = ref(isDash(props.axis.grid.style.lineDash))
|
||||
|
||||
const changeLineDash = (data: boolean) => {
|
||||
if (data) {
|
||||
props.axis.grid.style.lineDash = [4, 4] // 设置为虚线
|
||||
} else {
|
||||
props.axis.grid.style.lineDash = [0] // 设置为实线
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.bar">
|
||||
<collapse-item name="柱体">
|
||||
<SettingItemBox name="样式">
|
||||
<setting-item v-if="'width' in optionData.bar.style" name="宽度">
|
||||
<n-input-number v-model:value="optionData.bar.style.width" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item v-if="'height' in (optionData.bar.style as any)" name="高度">
|
||||
<n-input-number v-model:value="(optionData.bar.style as any).height" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="圆角大小">
|
||||
<n-input-number v-model:value="optionData.bar.style.cornerRadius" size="small" :min="0"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="填充透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.bar.style.fillOpacity"
|
||||
:step="0.1"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="1"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="整体透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.bar.style.opacity"
|
||||
:step="0.1"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="1"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="纹理类型">
|
||||
<n-select v-model:value="optionData.bar.style.texture" :options="styleConfig.texture" size="small"></n-select>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,46 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.label">
|
||||
<collapse-item name="标签">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.label.visible" size="small"></n-switch>
|
||||
</template>
|
||||
|
||||
<setting-item-box name="布局">
|
||||
<setting-item name="位置">
|
||||
<n-select
|
||||
v-model:value="optionData.label.position"
|
||||
size="small"
|
||||
:options="positionOptions || labelConfig.barPosition"
|
||||
/>
|
||||
</setting-item>
|
||||
|
||||
<setting-item name="间距">
|
||||
<n-input-number v-model:value="optionData.label.offset" :min="1" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
|
||||
<setting-item-box name="字体">
|
||||
<FontStyle :style="toRefs(optionData.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { labelConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
},
|
||||
positionOptions: {
|
||||
type: Array,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<div v-if="optionData.legends">
|
||||
<div v-for="(legendItem, index) in optionData.legends" :key="index">
|
||||
<collapse-item name="图例">
|
||||
<template #header>
|
||||
<n-switch v-model:value="legendItem.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="布局">
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="legendItem.orient" size="small" :options="legendsConfig.orient" />
|
||||
</setting-item>
|
||||
<setting-item name="对齐方式">
|
||||
<n-select v-model:value="legendItem.position" size="small" :options="legendsConfig.position" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="项配置">
|
||||
<FontStyle :style="toRefs(legendItem.item.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<collapse-item name="线条" v-if="optionData.line">
|
||||
<SettingItemBox name="样式">
|
||||
<setting-item name="宽度">
|
||||
<n-input-number v-model:value="optionData.line.style.lineWidth" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="线条类型">
|
||||
<n-select
|
||||
v-model:value="optionData.line.style.curveType"
|
||||
:options="styleConfig.curveType"
|
||||
size="small"
|
||||
></n-select>
|
||||
</setting-item>
|
||||
<setting-item name="末端样式">
|
||||
<n-select v-model:value="optionData.line.style.lineCap" :options="styleConfig.lineCap" size="small"></n-select>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.point">
|
||||
<collapse-item name="实心点(图元)">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.point.visible" size="small"></n-switch>
|
||||
</template>
|
||||
|
||||
<setting-item-box name="样式">
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="optionData.point.style.symbolType" size="small" :options="styleConfig.symbolType" />
|
||||
</setting-item>
|
||||
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="optionData.point.style.size" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="填充透明度">
|
||||
<n-input-number v-model:value="optionData.point.style.fillOpacity" :step="0.1" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框宽度">
|
||||
<n-input-number v-model:value="optionData.point.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框颜色">
|
||||
<n-color-picker v-model:value="optionData.point.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框透明度">
|
||||
<n-input-number v-model:value="optionData.point.style.strokeOpacity" :step="0.1" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="偏移X">
|
||||
<n-input-number v-model:value="optionData.point.style.dx" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="偏移Y">
|
||||
<n-input-number v-model:value="optionData.point.style.dy" :min="0" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
},
|
||||
positionOptions: {
|
||||
type: Array,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<div v-if="optionData.tooltip">
|
||||
<collapse-item name="提示框">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.tooltip.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="框">
|
||||
<setting-item name="填充">
|
||||
<n-color-picker v-model:value="optionData.tooltip.style.panel.backgroundColor" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="瞄边">
|
||||
<n-color-picker v-model:value="optionData.tooltip.style.panel.border.color" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="optionData.tooltip.style.panel.border.width" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="圆角">
|
||||
<n-input-number v-model:value="optionData.tooltip.style.panel.border.radius" :min="0" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="标题">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.titleLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="名称">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.keyLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="值">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.valueLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<!-- 图例 -->
|
||||
<Legends :optionData="optionData"></Legends>
|
||||
<Tooltip :optionData="optionData"></Tooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import Legends from './Legends.vue'
|
||||
import Tooltip from './Tooltip.vue'
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<template v-if="style">
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="style.fill.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="style.fontSize.value" :min="1" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字体">
|
||||
<n-select v-model:value="style.fontFamily.value" :options="fontStyleConfig.fontFamily" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字重">
|
||||
<n-select v-model:value="style.fontWeight.value" :options="fontStyleConfig.fontWeight" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.dx" name="X轴偏移">
|
||||
<n-input-number v-model:value="style.dx.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.dy" name="Y轴偏移">
|
||||
<n-input-number v-model:value="style.dy.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.angle" name="旋转">
|
||||
<n-input-number v-model:value="style.angle.value" :step="0.1" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { fontStyleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import { FontType } from '@/settings/vchartThemes/index'
|
||||
import { SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
style: {
|
||||
type: Object as PropType<any>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<setting-item name="间距">
|
||||
<n-input v-model:value="paddingArray" size="small" @update:value="updateHandle"/>
|
||||
</setting-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ICartesianTitle } from '@visactor/vchart/esm/component/axis'
|
||||
import { forEach, isNumber } from 'lodash'
|
||||
import { SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { PropType, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
axis: {
|
||||
type: Object as PropType<ICartesianTitle>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 解析间距
|
||||
const paddingInit = (padding: ICartesianTitle['padding']) => {
|
||||
const arr = [0, 0, 0, 0]
|
||||
if (!padding) {
|
||||
return arr
|
||||
}
|
||||
if (isNumber(padding)) {
|
||||
arr.forEach((item, index) => {
|
||||
arr[index] = padding
|
||||
})
|
||||
} else if (Array.isArray(padding)) {
|
||||
if (padding.length === 1) {
|
||||
arr.forEach((item, index) => {
|
||||
arr[index] = padding[0]
|
||||
})
|
||||
} else if (padding.length === 2) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[0]
|
||||
arr[3] = padding[1]
|
||||
} else if (padding.length === 3) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[2]
|
||||
arr[3] = padding[1]
|
||||
} else if (padding.length === 4) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[2]
|
||||
arr[3] = padding[3]
|
||||
}
|
||||
}
|
||||
|
||||
// 转成字符串,逗号分隔
|
||||
return arr.map(item => item.toString()).join(',')
|
||||
}
|
||||
|
||||
// 间距处理
|
||||
const paddingArray = ref(paddingInit(props.axis.padding))
|
||||
|
||||
// 字符串转成数组
|
||||
const paddingArrayToNumber = (padding: string) => {
|
||||
const arr = padding.split(',').map(item => parseFloat(item.trim()))
|
||||
if (arr.length === 1) {
|
||||
return [arr[0], arr[0], arr[0], arr[0]]
|
||||
} else if (arr.length === 2) {
|
||||
return [arr[0], arr[1], arr[0], arr[1]]
|
||||
} else if (arr.length === 3) {
|
||||
return [arr[0], arr[1], arr[2], arr[1]]
|
||||
} else if (arr.length === 4) {
|
||||
return arr
|
||||
}
|
||||
return [0, 0, 0, 0]
|
||||
}
|
||||
|
||||
const updateHandle = (value: string) => {
|
||||
const padding = paddingArrayToNumber(value)
|
||||
forEach(padding, (item, index) => {
|
||||
if (isNaN(item)) {
|
||||
padding[index] = 0
|
||||
}
|
||||
})
|
||||
props.axis.padding = padding
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +0,0 @@
|
||||
import VChartGlobalSetting from './VChartGlobalSetting.vue'
|
||||
import Axis from './Axis.vue'
|
||||
import Label from './Label.vue'
|
||||
import Bar from './Bar.vue'
|
||||
import Line from './Line.vue'
|
||||
import Point from './Point.vue'
|
||||
|
||||
export { VChartGlobalSetting, Axis, Label, Bar, Line, Point }
|
||||
@@ -12,7 +12,6 @@ export enum DragKeyEnum {
|
||||
// 不同页面保存操作
|
||||
export enum SavePageEnum {
|
||||
CHART = 'SaveChart',
|
||||
CHART_TO_PREVIEW = 'ChartToPreview',
|
||||
JSON = 'SaveJSON',
|
||||
CLOSE = 'close'
|
||||
}
|
||||
@@ -48,7 +47,6 @@ export enum MenuEnum {
|
||||
UN_GROUP = 'unGroup',
|
||||
// 后退
|
||||
BACK = 'back',
|
||||
// 前进
|
||||
FORWORD = 'forward',
|
||||
// 保存
|
||||
SAVE = 'save',
|
||||
@@ -84,3 +82,15 @@ export enum MacKeyboard {
|
||||
ALT_SOURCE_KEY = '⌥',
|
||||
SPACE = 'Space'
|
||||
}
|
||||
|
||||
// 同步状态枚举
|
||||
export enum SyncEnum {
|
||||
// 等待
|
||||
PENDING,
|
||||
// 开始
|
||||
START,
|
||||
// 成功
|
||||
SUCCESS,
|
||||
// 失败
|
||||
FAILURE
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
/**
|
||||
* @description: 请求结果集
|
||||
*/
|
||||
// 模块 Path 前缀分类
|
||||
export enum ModuleTypeEnum {
|
||||
SYSTEM = 'sys',
|
||||
PROJECT = 'project',
|
||||
}
|
||||
|
||||
// 请求结果集
|
||||
export enum ResultEnum {
|
||||
DATA_SUCCESS = 0,
|
||||
SUCCESS = 200,
|
||||
SERVER_ERROR = 500,
|
||||
SERVER_FORBIDDEN = 403,
|
||||
NOT_FOUND = 404,
|
||||
TIMEOUT = 60000
|
||||
TOKEN_OVERDUE = 886,
|
||||
TIMEOUT = 60000,
|
||||
}
|
||||
|
||||
// 数据相关
|
||||
@@ -28,9 +33,13 @@ export enum RequestContentTypeEnum {
|
||||
SQL = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 请求方法
|
||||
*/
|
||||
// 头部
|
||||
export enum RequestHttpHeaderEnum {
|
||||
TOKEN = 'Token',
|
||||
COOKIE = 'Cookie'
|
||||
}
|
||||
|
||||
// 请求方法
|
||||
export enum RequestHttpEnum {
|
||||
GET = 'get',
|
||||
POST = 'post',
|
||||
@@ -111,9 +120,7 @@ export type RequestParams = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 常用的contentTyp类型
|
||||
*/
|
||||
// 常用的contentTyp类型
|
||||
export enum ContentTypeEnum {
|
||||
// json
|
||||
JSON = 'application/json;charset=UTF-8',
|
||||
|
||||
@@ -26,10 +26,15 @@ export enum PageEnum {
|
||||
//重定向
|
||||
REDIRECT = '/redirect',
|
||||
REDIRECT_NAME = 'Redirect',
|
||||
|
||||
// 未发布
|
||||
REDIRECT_UN_PUBLISH = '/redirect/unPublish',
|
||||
REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
|
||||
|
||||
// 重载
|
||||
RELOAD = '/reload',
|
||||
RELOAD_NAME = 'Reload',
|
||||
|
||||
|
||||
// 首页
|
||||
BASE_HOME = '/project',
|
||||
BASE_HOME_NAME = 'Project',
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
export enum StorageEnum {
|
||||
// 全局设置
|
||||
GO_SYSTEM_SETTING_STORE = 'GO_SYSTEM_SETTING',
|
||||
// token 等信息
|
||||
GO_ACCESS_TOKEN_STORE = 'GO_ACCESS_TOKEN',
|
||||
GO_SETTING_STORE = 'GO_SETTING',
|
||||
// 登录信息
|
||||
GO_LOGIN_INFO_STORE = 'GO_LOGIN_INFO',
|
||||
GO_SYSTEM_STORE = 'GO_SYSTEM',
|
||||
// 语言
|
||||
GO_LANG_STORE = 'GO_LANG',
|
||||
// 当前选择的主题
|
||||
@@ -12,7 +10,5 @@ export enum StorageEnum {
|
||||
// 工作台布局配置
|
||||
GO_CHART_LAYOUT_STORE = 'GO_CHART_LAYOUT',
|
||||
// 工作台需要保存的数据
|
||||
GO_CHART_STORAGE_LIST = 'GO_CHART_STORAGE_LIST',
|
||||
// 用户存储的图片媒体
|
||||
GO_USER_MEDIA_PHOTOS = 'GO_USER_MEDIA_PHOTOS'
|
||||
GO_CHART_STORAGE_LIST = 'GO_CHART_STORAGE_LIST'
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ export * from '@/hooks/useTheme.hook'
|
||||
export * from '@/hooks/usePreviewScale.hook'
|
||||
export * from '@/hooks/useCode.hook'
|
||||
export * from '@/hooks/useChartDataFetch.hook'
|
||||
export * from '@/hooks/useSystemInit.hook'
|
||||
export * from '@/hooks/useChartDataPondFetch.hook'
|
||||
export * from '@/hooks/useLifeHandler.hook'
|
||||
export * from '@/hooks/useLang.hook'
|
||||
export * from '@/hooks/useChartInteract.hook'
|
||||
export * from '@/hooks/useVCharts.hook'
|
||||
export * from '@/hooks/useChartInteract.hook'
|
||||
@@ -1,130 +1,122 @@
|
||||
import { ref, toRefs, toRaw, watch } from 'vue'
|
||||
import type VChart from 'vue-echarts'
|
||||
import { customizeHttp } from '@/api/http'
|
||||
import { useChartDataPondFetch } from '@/hooks/'
|
||||
import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { RequestDataTypeEnum } from '@/enums/httpEnum'
|
||||
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
|
||||
import { setOption } from '@/packages/public/chart'
|
||||
import { isNil } from 'lodash'
|
||||
|
||||
// 获取类型
|
||||
type ChartEditStoreType = typeof useChartEditStore
|
||||
|
||||
/**
|
||||
* setdata 数据监听与更改
|
||||
* @param targetComponent
|
||||
* @param useChartEditStore 若直接引会报错,只能动态传递
|
||||
* @param updateCallback 自定义更新函数
|
||||
*/
|
||||
export const useChartDataFetch = (
|
||||
targetComponent: CreateComponentType,
|
||||
useChartEditStore: ChartEditStoreType,
|
||||
updateCallback?: (...args: any) => any
|
||||
) => {
|
||||
const vChartRef = ref<typeof VChart | null>(null)
|
||||
let fetchInterval: any = 0
|
||||
|
||||
// 数据池
|
||||
const { addGlobalDataInterface } = useChartDataPondFetch()
|
||||
|
||||
// 组件类型
|
||||
const { chartFrame } = targetComponent.chartConfig
|
||||
|
||||
// eCharts 组件配合 vChart 库更新方式
|
||||
const echartsUpdateHandle = (dataset: any) => {
|
||||
if (chartFrame === ChartFrameEnum.ECHARTS) {
|
||||
if (vChartRef.value) {
|
||||
setOption(vChartRef.value, { dataset: dataset }, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const requestIntervalFn = () => {
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
// 全局数据
|
||||
const {
|
||||
requestOriginUrl,
|
||||
requestIntervalUnit: globalUnit,
|
||||
requestInterval: globalRequestInterval
|
||||
} = toRefs(chartEditStore.getRequestGlobalConfig)
|
||||
|
||||
// 目标组件
|
||||
const {
|
||||
requestDataType,
|
||||
requestUrl,
|
||||
requestIntervalUnit: targetUnit,
|
||||
requestInterval: targetInterval
|
||||
} = toRefs(targetComponent.request)
|
||||
|
||||
// 非请求类型
|
||||
if (requestDataType.value !== RequestDataTypeEnum.AJAX) return
|
||||
|
||||
try {
|
||||
// 处理地址
|
||||
// @ts-ignore
|
||||
if (requestUrl?.value) {
|
||||
// requestOriginUrl 允许为空
|
||||
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
|
||||
if (!completePath) return
|
||||
|
||||
clearInterval(fetchInterval)
|
||||
|
||||
const fetchFn = async () => {
|
||||
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig))
|
||||
if (res) {
|
||||
try {
|
||||
const filter = targetComponent.filter
|
||||
const { data } = res
|
||||
echartsUpdateHandle(newFunctionHandle(data, res, filter))
|
||||
// 更新回调函数
|
||||
if (updateCallback) {
|
||||
updateCallback(newFunctionHandle(data, res, filter))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 普通初始化与组件交互处理监听
|
||||
watch(
|
||||
() => targetComponent.request.requestParams,
|
||||
() => {
|
||||
fetchFn()
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
// 定时时间
|
||||
const time = targetInterval && !isNil(targetInterval.value) ? targetInterval.value : globalRequestInterval.value
|
||||
// 单位
|
||||
const unit = targetInterval && !isNil(targetInterval.value) ? targetUnit.value : globalUnit.value
|
||||
// 开启轮询
|
||||
if (time) {
|
||||
fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
if (isPreview()) {
|
||||
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
|
||||
? addGlobalDataInterface(targetComponent, useChartEditStore, (newData: any) => {
|
||||
echartsUpdateHandle(newData)
|
||||
if (updateCallback) updateCallback(newData)
|
||||
})
|
||||
: requestIntervalFn()
|
||||
} else {
|
||||
requestIntervalFn()
|
||||
}
|
||||
return { vChartRef }
|
||||
}
|
||||
import { ref, toRefs, toRaw, watch } from 'vue'
|
||||
import type VChart from 'vue-echarts'
|
||||
import { customizeHttp } from '@/api/http'
|
||||
import { useChartDataPondFetch } from '@/hooks/'
|
||||
import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { RequestDataTypeEnum } from '@/enums/httpEnum'
|
||||
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
|
||||
import { setOption } from '@/packages/public/chart'
|
||||
|
||||
// 获取类型
|
||||
type ChartEditStoreType = typeof useChartEditStore
|
||||
|
||||
/**
|
||||
* setdata 数据监听与更改
|
||||
* @param targetComponent
|
||||
* @param useChartEditStore 若直接引会报错,只能动态传递
|
||||
* @param updateCallback 自定义更新函数
|
||||
*/
|
||||
export const useChartDataFetch = (
|
||||
targetComponent: CreateComponentType,
|
||||
useChartEditStore: ChartEditStoreType,
|
||||
updateCallback?: (...args: any) => any
|
||||
) => {
|
||||
const vChartRef = ref<typeof VChart | null>(null)
|
||||
let fetchInterval: any = 0
|
||||
|
||||
// 数据池
|
||||
const { addGlobalDataInterface } = useChartDataPondFetch()
|
||||
|
||||
// 组件类型
|
||||
const { chartFrame } = targetComponent.chartConfig
|
||||
|
||||
// eCharts 组件配合 vChart 库更新方式
|
||||
const echartsUpdateHandle = (dataset: any) => {
|
||||
if (chartFrame === ChartFrameEnum.ECHARTS) {
|
||||
if (vChartRef.value) {
|
||||
setOption(vChartRef.value, { dataset: dataset })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const requestIntervalFn = () => {
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
// 全局数据
|
||||
const {
|
||||
requestOriginUrl,
|
||||
requestIntervalUnit: globalUnit,
|
||||
requestInterval: globalRequestInterval
|
||||
} = toRefs(chartEditStore.getRequestGlobalConfig)
|
||||
|
||||
// 目标组件
|
||||
const {
|
||||
requestDataType,
|
||||
requestUrl,
|
||||
requestIntervalUnit: targetUnit,
|
||||
requestInterval: targetInterval
|
||||
} = toRefs(targetComponent.request)
|
||||
|
||||
// 非请求类型
|
||||
if (requestDataType.value !== RequestDataTypeEnum.AJAX) return
|
||||
|
||||
try {
|
||||
// 处理地址
|
||||
// @ts-ignore
|
||||
if (requestUrl?.value) {
|
||||
// requestOriginUrl 允许为空
|
||||
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
|
||||
if (!completePath) return
|
||||
|
||||
clearInterval(fetchInterval)
|
||||
|
||||
const fetchFn = async () => {
|
||||
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig))
|
||||
if (res) {
|
||||
try {
|
||||
const filter = targetComponent.filter
|
||||
echartsUpdateHandle(newFunctionHandle(res?.data, res, filter))
|
||||
// 更新回调函数
|
||||
if (updateCallback) {
|
||||
updateCallback(newFunctionHandle(res?.data, res, filter))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 普通初始化与组件交互处理监听
|
||||
watch(
|
||||
() => targetComponent.request,
|
||||
() => {
|
||||
fetchFn()
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
// 定时时间
|
||||
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
|
||||
// 单位
|
||||
const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
|
||||
// 开启轮询
|
||||
if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
if (isPreview()) {
|
||||
// 判断是否是数据池类型
|
||||
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
|
||||
? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
|
||||
: requestIntervalFn()
|
||||
}
|
||||
return { vChartRef }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { toRaw, watch, computed, ComputedRef } from 'vue'
|
||||
import { toRaw } from 'vue'
|
||||
import { customizeHttp } from '@/api/http'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
@@ -20,7 +20,7 @@ const mittDataPondMap = new Map<string, DataPondMapType[]>()
|
||||
// 创建单个数据项轮询接口
|
||||
const newPondItemInterval = (
|
||||
requestGlobalConfig: RequestGlobalConfigType,
|
||||
requestDataPondItem: ComputedRef<RequestDataPondItemType>,
|
||||
requestDataPondItem: RequestDataPondItemType,
|
||||
dataPondMapItem?: DataPondMapType[]
|
||||
) => {
|
||||
if (!dataPondMapItem) return
|
||||
@@ -31,7 +31,8 @@ const newPondItemInterval = (
|
||||
// 请求
|
||||
const fetchFn = async () => {
|
||||
try {
|
||||
const res = await customizeHttp(toRaw(requestDataPondItem.value.dataPondRequestConfig), toRaw(requestGlobalConfig))
|
||||
const res = await customizeHttp(toRaw(requestDataPondItem.dataPondRequestConfig), toRaw(requestGlobalConfig))
|
||||
|
||||
if (res) {
|
||||
try {
|
||||
// 遍历更新回调函数
|
||||
@@ -48,32 +49,19 @@ const newPondItemInterval = (
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => requestDataPondItem.value.dataPondRequestConfig.requestParams.Params,
|
||||
() => {
|
||||
fetchFn()
|
||||
},
|
||||
{
|
||||
immediate: false,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
// 立即调用
|
||||
fetchFn()
|
||||
|
||||
|
||||
const targetInterval = requestDataPondItem.value.dataPondRequestConfig.requestInterval
|
||||
const targetUnit = requestDataPondItem.value.dataPondRequestConfig.requestIntervalUnit
|
||||
const targetInterval = requestDataPondItem.dataPondRequestConfig.requestInterval
|
||||
const targetUnit = requestDataPondItem.dataPondRequestConfig.requestIntervalUnit
|
||||
|
||||
const globalRequestInterval = requestGlobalConfig.requestInterval
|
||||
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))
|
||||
}
|
||||
@@ -108,16 +96,13 @@ export const useChartDataPondFetch = () => {
|
||||
}
|
||||
|
||||
// 初始化数据池
|
||||
const initDataPond = (useChartEditStore: ChartEditStoreType) => {
|
||||
const { requestGlobalConfig } = useChartEditStore()
|
||||
const chartEditStore = useChartEditStore()
|
||||
const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => {
|
||||
const { requestDataPond } = requestGlobalConfig
|
||||
// 根据 mapId 查找对应的数据池配置
|
||||
for (let pondKey of mittDataPondMap.keys()) {
|
||||
const requestDataPondItem = computed(() => {
|
||||
return requestGlobalConfig.requestDataPond.find(item => item.dataPondId === pondKey)
|
||||
}) as ComputedRef<RequestDataPondItemType>
|
||||
const requestDataPondItem = requestDataPond.find(item => item.dataPondId === pondKey)
|
||||
if (requestDataPondItem) {
|
||||
newPondItemInterval(chartEditStore.requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
|
||||
newPondItemInterval(requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||