mirror of
https://gitee.com/dromara/go-view.git
synced 2026-01-30 00:05:29 +08:00
Compare commits
417 Commits
fix-vchart
...
master-fet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06bed8e44e | ||
|
|
fa76f63760 | ||
|
|
ec98a62c7a | ||
|
|
4fd296cc3a | ||
|
|
34b808aebd | ||
|
|
c42c644567 | ||
|
|
b8ad9e2ad7 | ||
|
|
36f5396305 | ||
|
|
4ed9a5b50e | ||
|
|
99d1215654 | ||
|
|
a6ff024bf8 | ||
|
|
bbbf9691f3 | ||
|
|
85c0a08969 | ||
|
|
4439a48f45 | ||
|
|
076c174cb7 | ||
|
|
a9bb5e5397 | ||
|
|
99366efc8c | ||
|
|
8bb65e57f4 | ||
|
|
f883fec1f6 | ||
|
|
9fa0ee630e | ||
|
|
cfb2a667bd | ||
|
|
ac9483f666 | ||
|
|
3d4384a6f8 | ||
|
|
b3a8c23a47 | ||
|
|
d8227ae81b | ||
|
|
dd46701f6d | ||
|
|
97addb689a | ||
|
|
c47f729144 | ||
|
|
7309aa2e03 | ||
|
|
729c81aa61 | ||
|
|
415b3d6f7d | ||
|
|
343a61cdeb | ||
|
|
0869fd6c95 | ||
|
|
6af5f9ecf4 | ||
|
|
e57ebb1fc1 | ||
|
|
52beb77b76 | ||
|
|
950344127f | ||
|
|
64d4c40c07 | ||
|
|
22293bfed0 | ||
|
|
62518268a6 | ||
|
|
dafba45c64 | ||
|
|
aad77cf022 | ||
|
|
74abb136a4 | ||
|
|
d2c61f2de5 | ||
|
|
9bf81b113e | ||
|
|
3de0edcd4e | ||
|
|
9138d0b0bc | ||
|
|
8bfeca26c7 | ||
|
|
dce49c09fa | ||
|
|
d504639b7d | ||
|
|
812141bf62 | ||
|
|
4d62ea8b76 | ||
|
|
282cb75ef7 | ||
|
|
62d63c3f65 | ||
|
|
08f1b8380f | ||
|
|
79a7bc0229 | ||
|
|
c74269f1cf | ||
|
|
f9a8593e43 | ||
|
|
11ae2d89fb | ||
|
|
8a9b07ca45 | ||
|
|
fa6a780478 | ||
|
|
8835d9b217 | ||
|
|
a331fd99e9 | ||
|
|
5dea9b5c5a | ||
|
|
7ac0d38518 | ||
|
|
c4a078cc34 | ||
|
|
0fb8b3adf6 | ||
|
|
d60a1fd979 | ||
|
|
48e63b677f | ||
|
|
9db1980f9b | ||
|
|
07c8360207 | ||
|
|
a6b3580a01 | ||
|
|
f3c104d29d | ||
|
|
fbb137b3ad | ||
|
|
607deddb28 | ||
|
|
37a6ac35ff | ||
|
|
5fa71295ec | ||
|
|
6447a1a3bf | ||
|
|
d5ce9b80c2 | ||
|
|
39dbc913d1 | ||
|
|
5dd10d5465 | ||
|
|
f69dc60e7b | ||
|
|
a2c34a58d3 | ||
|
|
a420fc81d9 | ||
|
|
8dd8697d89 | ||
|
|
9c62c62820 | ||
|
|
a3119ff519 | ||
|
|
1819b074cd | ||
|
|
de06e42c5c | ||
|
|
fa93624cf7 | ||
|
|
bd5adfa922 | ||
|
|
8db3741725 | ||
|
|
f333be7f05 | ||
|
|
ea9590441b | ||
|
|
dd6c730021 | ||
|
|
1c43272719 | ||
|
|
2ae971d17a | ||
|
|
272815578b | ||
|
|
81e2e4784d | ||
|
|
ff403c5e6a | ||
|
|
d925a8e104 | ||
|
|
d7f0986cec | ||
|
|
278d67945a | ||
|
|
e62f9cbd02 | ||
|
|
131abbb28e | ||
|
|
a54652c072 | ||
|
|
656949f7b8 | ||
|
|
601e1a2ea7 | ||
|
|
c228bc97fb | ||
|
|
75c47dc97e | ||
|
|
b825e41707 | ||
|
|
bb1bfc564d | ||
|
|
e07be55f65 | ||
|
|
0cf5e175cf | ||
|
|
b06b5f252b | ||
|
|
6e55c9951b | ||
|
|
52aeca9dd4 | ||
|
|
87aa938e60 | ||
|
|
006a0edca9 | ||
|
|
58a4a4ca17 | ||
|
|
97bb192696 | ||
|
|
d6f4f20be0 | ||
|
|
d9fec13eae | ||
|
|
634f689f07 | ||
|
|
f4c9787807 | ||
|
|
24bcccdf2b | ||
|
|
6c968d9a24 | ||
|
|
586db5aca1 | ||
|
|
491604527e | ||
|
|
70da85c1e9 | ||
|
|
9dce33ee01 | ||
|
|
e903489a52 | ||
|
|
5b932af6c8 | ||
|
|
84f6bfcb8a | ||
|
|
2f43ddd59b | ||
|
|
45254c3dc4 | ||
|
|
afc6cf04a1 | ||
|
|
5340e89f7d | ||
|
|
4d05697b1c | ||
|
|
68c77760ca | ||
|
|
307480ded2 | ||
|
|
817b25f1a8 | ||
|
|
d457cc7135 | ||
|
|
8f996173b3 | ||
|
|
a06e8fb7a4 | ||
|
|
276bcbe831 | ||
|
|
2c6086edca | ||
|
|
55a6bd93ad | ||
|
|
622fec4e73 | ||
|
|
bdfad88357 | ||
|
|
c8e0b6c474 | ||
|
|
6b7f759071 | ||
|
|
dfe97bf5d5 | ||
|
|
8809022e8c | ||
|
|
fe87d0e433 | ||
|
|
f37264fdbb | ||
|
|
092a252ac4 | ||
|
|
0309c567e6 | ||
|
|
f23439d31f | ||
|
|
03be42b910 | ||
|
|
c3b7711f0a | ||
|
|
0a775af9bb | ||
|
|
15f2d77bec | ||
|
|
2e6611bf8b | ||
|
|
73524283ed | ||
|
|
6038bc8e58 | ||
|
|
5fce7f163e | ||
|
|
3be567ada8 | ||
|
|
2acf1f4351 | ||
|
|
8edc2767f9 | ||
|
|
29339c4c7c | ||
|
|
7836332a97 | ||
|
|
b5fe803059 | ||
|
|
30f1f058c7 | ||
|
|
afe17efde9 | ||
|
|
23e459de94 | ||
|
|
bcbf53d08f | ||
|
|
43aefe7b6e | ||
|
|
b7fda10caf | ||
|
|
824c7a29d8 | ||
|
|
326ad82182 | ||
|
|
92f50f0be2 | ||
|
|
dd0170eecc | ||
|
|
02500aff30 | ||
|
|
c31fa20b02 | ||
|
|
31cdbe2a57 | ||
|
|
5605e6a831 | ||
|
|
aef798c382 | ||
|
|
1922213f8b | ||
|
|
92afc0f366 | ||
|
|
7f9cde3c67 | ||
|
|
effd870897 | ||
|
|
dd7e1692d6 | ||
|
|
a3bbe95643 | ||
|
|
ef39ecb3c6 | ||
|
|
85fe91705b | ||
|
|
7ff21d6156 | ||
|
|
b53dd405a5 | ||
|
|
a53d9c4da2 | ||
|
|
de6b2e8bf9 | ||
|
|
968edea932 | ||
|
|
682419d174 | ||
|
|
e586311744 | ||
|
|
edaa9f7b99 | ||
|
|
0fdbde1cc1 | ||
|
|
3eb1ce7ec5 | ||
|
|
6e3302fed6 | ||
|
|
0d52a8bc5e | ||
|
|
09ac83a62b | ||
|
|
f04864ed7f | ||
|
|
4c968aee18 | ||
|
|
0fd8d11107 | ||
|
|
661b3570a5 | ||
|
|
4ffc6a608b | ||
|
|
2308e1c22b | ||
|
|
2967a6c763 | ||
|
|
327d23ebac | ||
|
|
15c12ca367 | ||
|
|
4351aef5cd | ||
|
|
8186595d84 | ||
|
|
16e58749a7 | ||
|
|
8214b30653 | ||
|
|
7dfa156e30 | ||
|
|
648f4f479e | ||
|
|
dff9ff2caf | ||
|
|
9a4f436b27 | ||
|
|
83e50d6e96 | ||
|
|
2d752f119d | ||
|
|
ab22db62f7 | ||
|
|
cb750c73b9 | ||
|
|
18784d4455 | ||
|
|
08b1c14a1c | ||
|
|
8cf47e9005 | ||
|
|
666841458e | ||
|
|
dafdbeca4b | ||
|
|
5aac8c0546 | ||
|
|
0609b95a28 | ||
|
|
6f9b109022 | ||
|
|
2f6bdcc8c8 | ||
|
|
4886af4bb5 | ||
|
|
b57cf1bf59 | ||
|
|
183349dce8 | ||
|
|
1b9d220abd | ||
|
|
70ee06d622 | ||
|
|
ae7f1bcb3e | ||
|
|
74c9d1df65 | ||
|
|
b270e0ad43 | ||
|
|
7b327df38e | ||
|
|
2ec4f56943 | ||
|
|
367d0a23ca | ||
|
|
4d6b68ee60 | ||
|
|
a34544296a | ||
|
|
e8399875e5 | ||
|
|
d78be0093e | ||
|
|
09fb1aff92 | ||
|
|
b79c2b2fdb | ||
|
|
656adfcf56 | ||
|
|
786458adfe | ||
|
|
31b5a6961b | ||
|
|
babab39710 | ||
|
|
60a2bf7f4f | ||
|
|
9e25e1866d | ||
|
|
781151319c | ||
|
|
d3c3cf86b2 | ||
|
|
5f7d505f20 | ||
|
|
cd8bdc5d1d | ||
|
|
d8117b66ca | ||
|
|
b26a45a7b6 | ||
|
|
37eb0ed357 | ||
|
|
858ee8515d | ||
|
|
7313f8707e | ||
|
|
564f8d0ae2 | ||
|
|
37df8a7fa1 | ||
|
|
8039213380 | ||
|
|
c5a704767d | ||
|
|
20be7f2e45 | ||
|
|
d43823794d | ||
|
|
5e09105a70 | ||
|
|
7d2a98ab85 | ||
|
|
2d302bb468 | ||
|
|
789328b02e | ||
|
|
b93a2a516a | ||
|
|
c8662537ca | ||
|
|
b083bd9724 | ||
|
|
5fd6870cfe | ||
|
|
9004a55b8c | ||
|
|
c349e6384e | ||
|
|
4e298efaa0 | ||
|
|
c7cbb9b72a | ||
|
|
bd5e06350d | ||
|
|
c311dd08e3 | ||
|
|
504a1f4703 | ||
|
|
a67cc9f876 | ||
|
|
e0d2e8031d | ||
|
|
bcec26374f | ||
|
|
a5981a4387 | ||
|
|
0d26dce512 | ||
|
|
6359ec15b3 | ||
|
|
32ca138e6a | ||
|
|
171e0aa408 | ||
|
|
52009a415b | ||
|
|
da809f13b3 | ||
|
|
801aa1f82f | ||
|
|
72c26b71f3 | ||
|
|
3b8181ae10 | ||
|
|
c2a9642393 | ||
|
|
3c04f81147 | ||
|
|
ec28ccf09c | ||
|
|
fa34300401 | ||
|
|
f506ccd2e4 | ||
|
|
f379f7652c | ||
|
|
e8760c81ac | ||
|
|
a9bb294f60 | ||
|
|
0b5f35752b | ||
|
|
7322817cb5 | ||
|
|
437ad1bd9f | ||
|
|
cd20e68480 | ||
|
|
35968475b9 | ||
|
|
78eb3ccc3f | ||
|
|
7cccbabca4 | ||
|
|
cdccfa3e12 | ||
|
|
e8c5455748 | ||
|
|
8e40416e72 | ||
|
|
d058361e01 | ||
|
|
2491f7ff57 | ||
|
|
c5908f6d92 | ||
|
|
7e64d30258 | ||
|
|
437818abce | ||
|
|
5197eb9292 | ||
|
|
3cf01f0c51 | ||
|
|
db815661e8 | ||
|
|
6edbb7c8a7 | ||
|
|
799c445c4b | ||
|
|
70fbf5de3e | ||
|
|
73c7697443 | ||
|
|
8092edab81 | ||
|
|
ef4f45ddb0 | ||
|
|
3e969e4ae5 | ||
|
|
bcd1dfd7bd | ||
|
|
c1dfd78d18 | ||
|
|
39aa1645c9 | ||
|
|
d3afea8c5e | ||
|
|
2499cbdd44 | ||
|
|
3cc3714e94 | ||
|
|
be0aa6d099 | ||
|
|
34d27c1004 | ||
|
|
85f3b4e9e3 | ||
|
|
0fb9a79df9 | ||
|
|
6b805fbdfb | ||
|
|
abe76aeb59 | ||
|
|
5f49bc1aa8 | ||
|
|
71807be01d | ||
|
|
e74f796203 | ||
|
|
041d7da9d8 | ||
|
|
a99d949b29 | ||
|
|
c2a9e2a469 | ||
|
|
80b05db764 | ||
|
|
340cab11b7 | ||
|
|
712233c215 | ||
|
|
b9b915e913 | ||
|
|
044143571f | ||
|
|
06fe805736 | ||
|
|
077881e499 | ||
|
|
f655a57e61 | ||
|
|
0b04bf4929 | ||
|
|
2fcd3b1132 | ||
|
|
568fd6c105 | ||
|
|
221351ec11 | ||
|
|
6ab34a0996 | ||
|
|
6b551ae68b | ||
|
|
2917cde2e5 | ||
|
|
294a4a6cdf | ||
|
|
1e678b7492 | ||
|
|
2ceca7287f | ||
|
|
7f4dd5295b | ||
|
|
ffd628fa82 | ||
|
|
d639e445eb | ||
|
|
b263681dda | ||
|
|
e16413b570 | ||
|
|
63b5186c3e | ||
|
|
ba20316761 | ||
|
|
437dd1c411 | ||
|
|
d0d5f5b77d | ||
|
|
efd9228cc9 | ||
|
|
ebd6132385 | ||
|
|
9098443c83 | ||
|
|
423890a4df | ||
|
|
fb2edeb7d2 | ||
|
|
b861587f01 | ||
|
|
c3738fab45 | ||
|
|
24fba75f28 | ||
|
|
00b6b63e1e | ||
|
|
5dab8fa7d9 | ||
|
|
9a5d71fb5c | ||
|
|
c930efba0c | ||
|
|
ff7c820b1f | ||
|
|
4252725d9d | ||
|
|
deeb3a472c | ||
|
|
763173de44 | ||
|
|
f46e6ad8c8 | ||
|
|
09b31547e1 | ||
|
|
dee2ff8dee | ||
|
|
7f315b95ce | ||
|
|
093e7d1edb | ||
|
|
a4e18f8893 | ||
|
|
c754a36ee5 | ||
|
|
a07d4daed5 | ||
|
|
39023832e3 | ||
|
|
5b8dda60bd | ||
|
|
f7ade54e93 | ||
|
|
4ae7e9dd2e | ||
|
|
7e237b508a | ||
|
|
28bb82e579 | ||
|
|
bcabcb0831 | ||
|
|
c24b03f3da | ||
|
|
63dd03e755 | ||
|
|
f3f1f57b01 |
12
.env
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'
|
||||
209
README.md
209
README.md
@@ -1,153 +1,114 @@
|
||||
## 总览
|
||||
|
||||

|
||||
**`master-fetch` 分支是带有后端接口请求的分支**
|
||||
|
||||
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
|
||||
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
|
||||
|
||||
### 😶 纯 **前端** 分支: **`master`**
|
||||
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)**
|
||||
|
||||
### 👻 携带 **后端** 请求分支: **`master-fetch`**
|
||||
## 使用
|
||||
|
||||
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
|
||||
所有的接口地址位置:`src\api\path\*`
|
||||
|
||||
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
|
||||
|
||||
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
|
||||
|
||||
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
|
||||
|
||||
文档-源码地址:[https://gitee.com/MTrun/go-view-doc](https://gitee.com/MTrun/go-view-doc)
|
||||
|
||||
### 🤯 后端项目
|
||||
|
||||
后端项目 gitee 地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
|
||||
|
||||
接口说明地址:[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)
|
||||
|
||||
技术点:
|
||||
|
||||
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
|
||||
|
||||
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
|
||||
|
||||
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
|
||||
|
||||
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
|
||||
|
||||
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
|
||||
|
||||
- 可视化:基于开源图表库[ECharts](https://echarts.apache.org/zh/index.html) 和 [VChart](https://www.visactor.io/vchart) 编写,具有丰富的图表类型和适配大屏的主题效果;
|
||||
|
||||
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
|
||||
|
||||
说明文档:
|
||||

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

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

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

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

|
||||
|
||||
主要技术栈为:
|
||||
|
||||
| 名称 | 版本 | 名称 | 版本 |
|
||||
| ------------------- | ----- | ----------- | ------ |
|
||||
| Vue | 3.2.x | TypeScript4 | 4.6.x |
|
||||
| Vite | 4.2.x | NaiveUI | 2.34.x |
|
||||
| ECharts | 5.3.x | Pinia | 2.0.x |
|
||||
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
|
||||
|
||||
开发环境:
|
||||
|
||||
| 名称 | 版本 | 名称 | 版本 |
|
||||
| ---- | ------- | ------- | ----- |
|
||||
| node | 16.16.x | npm | 8.5.x |
|
||||
| pnpm | 7.1.x | windows | 11 |
|
||||
|
||||
已完成图表:
|
||||
|
||||
| 分类 | 名称 | 名称 | 名称 |
|
||||
| ------ | ---------------- | ---------------- | -------- |
|
||||
| 图表 | 柱状图 | 横向柱状图 | 折线图 |
|
||||
| \* | 单/多 折线面积图 | 饼图 | 水球图 |
|
||||
| \* | 环形图 | NaiveUI 多种进度 | 🤠 |
|
||||
| 信息 | 文字 | 图片 | 😶 |
|
||||
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 |
|
||||
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 |
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
|
||||
|
||||
## 安装
|
||||
|
||||
本项目采用` pnpm` 进行包管理
|
||||
接口地址修改:`.env`
|
||||
|
||||
```shell
|
||||
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
|
||||
#pnpm
|
||||
pnpm install
|
||||
# port
|
||||
VITE_DEV_PORT = '8080'
|
||||
|
||||
#yarn
|
||||
yarn install
|
||||
# development path
|
||||
VITE_DEV_PATH = 'http://127.0.0.1:8080'
|
||||
|
||||
#npm
|
||||
npm install
|
||||
# production path
|
||||
VITE_PRO_PATH = 'http://127.0.0.1:8080'
|
||||
```
|
||||
|
||||
## 启动
|
||||
公共前缀修改:`src\settings\httpSetting.ts`
|
||||
|
||||
```shell
|
||||
#pnpm
|
||||
pnpm dev
|
||||
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
#yarn
|
||||
yarn dev
|
||||
|
||||
#Makefile
|
||||
make dev
|
||||
// 请求前缀
|
||||
export const axiosPre = '/api/goview'
|
||||
```
|
||||
|
||||
## 编译
|
||||
接口封装:`src\api\http.ts`
|
||||
|
||||
```shell
|
||||
#pnpm
|
||||
pnpm run build
|
||||
```ts
|
||||
import axiosInstance from './axios'
|
||||
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
# npm
|
||||
npm run build
|
||||
export const get = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.GET,
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
#yarn
|
||||
yarn run build
|
||||
export const post = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.POST,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#Makefile
|
||||
make dist
|
||||
export const put = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PUT,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const del = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.DELETE,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取请求函数,默认get
|
||||
export const http = (type?: RequestHttpEnum) => {
|
||||
switch (type) {
|
||||
case RequestHttpEnum.GET:
|
||||
return get
|
||||
|
||||
case RequestHttpEnum.POST:
|
||||
return post
|
||||
|
||||
case RequestHttpEnum.PUT:
|
||||
return put
|
||||
|
||||
case RequestHttpEnum.DELETE:
|
||||
return del
|
||||
|
||||
default:
|
||||
return get
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 代码提交
|
||||
|
||||
- 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: 不属于以上类型的其他类型(日常事务)
|
||||
|
||||
## 交流
|
||||
|
||||
|
||||
@@ -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, '');
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "go-view",
|
||||
"version": "1.1.11",
|
||||
"version": "2.2.9",
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
},
|
||||
@@ -21,7 +21,7 @@
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@visactor/vchart": "^1.12.12",
|
||||
"@visactor/vchart": "^2.0.0",
|
||||
"@visactor/vchart-theme": "^1.12.2",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.4.0",
|
||||
@@ -48,7 +48,7 @@
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "4.0.12",
|
||||
"vue3-lazyload": "^0.2.5-beta",
|
||||
"vue3-sketch-ruler": "^1.3.3",
|
||||
"vue3-sketch-ruler": "1.3.3",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -77,7 +77,7 @@
|
||||
"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",
|
||||
|
||||
1992
pnpm-lock.yaml
generated
1992
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -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,6 +28,9 @@ const overridesTheme = useThemeOverridesHook()
|
||||
// 代码主题
|
||||
const hljsTheme = useCode()
|
||||
|
||||
// 系统全局数据初始化
|
||||
useSystemInit()
|
||||
|
||||
// 全局语言
|
||||
const { locale, dateLocale } = useLang()
|
||||
//测试提交
|
||||
|
||||
14
src/api/axios.config.ts
Normal file
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,34 +1,93 @@
|
||||
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, AxiosError, InternalAxiosRequestConfig } from 'axios'
|
||||
import { RequestHttpHeaderEnum, 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,
|
||||
timeout: ResultEnum.TIMEOUT,
|
||||
})
|
||||
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) => {
|
||||
// 白名单校验
|
||||
if (includes(fetchAllowList, config.url)) return config
|
||||
// 获取 token
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
// 重新登录
|
||||
if (!info) {
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
return config
|
||||
}
|
||||
const userInfo = info[SystemStoreEnum.USER_INFO]
|
||||
config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
|
||||
return config
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
Promise.reject(error)
|
||||
(err: AxiosError) => {
|
||||
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 === 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) => {
|
||||
Promise.reject(err)
|
||||
(err: AxiosError) => {
|
||||
const status = err.response?.status
|
||||
switch (status) {
|
||||
case 401:
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
Promise.reject(err)
|
||||
break
|
||||
|
||||
default:
|
||||
Promise.reject(err)
|
||||
break
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
2
src/api/path/index.ts
Normal file
2
src/api/path/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from '@/api/path/project.api'
|
||||
export * from '@/api/path/system.api'
|
||||
99
src/api/path/project.api.ts
Normal file
99
src/api/path/project.api.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { http } from '@/api/http'
|
||||
import { httpErrorHandle } from '@/utils'
|
||||
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
import { ProjectItem, ProjectDetail } from './project'
|
||||
|
||||
// * 项目列表
|
||||
export const projectListApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 新增项目
|
||||
export const createProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
id: number
|
||||
}>(`${ModuleTypeEnum.PROJECT}/create`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 获取项目
|
||||
export const fetchProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectDetail>(`${ModuleTypeEnum.PROJECT}/getData`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 保存项目
|
||||
export const saveProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(
|
||||
`${ModuleTypeEnum.PROJECT}/save/data`,
|
||||
data,
|
||||
ContentTypeEnum.FORM_URLENCODED
|
||||
)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改项目基础信息
|
||||
export const updateProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 删除项目
|
||||
export const deleteProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.DELETE)(`${ModuleTypeEnum.PROJECT}/delete`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改发布状态 [-1未发布,1发布]
|
||||
export const changeProjectReleaseApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/publish`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 上传文件
|
||||
export const uploadFile = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
fileName: string,
|
||||
fileurl: string,
|
||||
}>(`${ModuleTypeEnum.PROJECT}/upload`, data, ContentTypeEnum.FORM_DATA)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
39
src/api/path/project.d.ts
vendored
Normal file
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
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
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
|
||||
}
|
||||
}
|
||||
BIN
src/assets/images/chart/vchart/vchart_bar_y.png
Normal file
BIN
src/assets/images/chart/vchart/vchart_bar_y.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 MiB |
@@ -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>
|
||||
@@ -197,7 +197,7 @@ const createOrUpdateChart = (
|
||||
}
|
||||
) => {
|
||||
if (vChartRef.value && !chart) {
|
||||
const spec = transformHandler[chartProps.category](chartProps)
|
||||
const spec = transformHandler[chartProps.category || '']?.(chartProps)
|
||||
chart = new VChart(
|
||||
{ ...spec, data: chartProps.dataset },
|
||||
{
|
||||
@@ -208,8 +208,12 @@ const createOrUpdateChart = (
|
||||
chart.renderSync()
|
||||
return true
|
||||
} else if (chart) {
|
||||
const spec = transformHandler[chartProps.category](chartProps)
|
||||
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined })
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
@@ -18,17 +18,28 @@ export default (chartProps: any) => {
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps,
|
||||
// paddingInner: 0.5
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
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,4 +1,4 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
@@ -18,15 +18,26 @@ export default (chartProps: any) => {
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
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,15 +1,10 @@
|
||||
import { Datum } from "@visactor/vchart/esm/typings"
|
||||
import { cloneDeep } from "lodash"
|
||||
const INNER_RADIUS = 0.75
|
||||
const OUTER_RADIUS = 0.68
|
||||
import { Datum } from '@visactor/vchart/esm/typings'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
spec.innerRadius = INNER_RADIUS
|
||||
spec.outerRadius = OUTER_RADIUS
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
@@ -21,119 +16,117 @@ export default (chartProps: any) => {
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// extensionMark
|
||||
spec.extensionMark = [
|
||||
{
|
||||
name: 'arc_inner_shadow',
|
||||
type: 'arc',
|
||||
dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
startAngle: (datum: Datum) => {
|
||||
console.log('startAngle', 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) => {
|
||||
console.log('context', context.seriesColor(datum[spec.seriesField]))
|
||||
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();
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// console.log('spec-pie-transform', spec)
|
||||
]
|
||||
}
|
||||
return spec
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
<template>
|
||||
<collapse-item v-model:name="axis.name">
|
||||
<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-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 name="角度">
|
||||
<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 :style="axis.label.style"></FontStyle>
|
||||
<FontStyle v-if="axis.label" :style="toRefs(axis.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴标题">
|
||||
<setting-item name="可见性">
|
||||
@@ -20,10 +31,16 @@
|
||||
<n-switch v-model:value="axis.title.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="标题内容">
|
||||
<setting-item name="内容">
|
||||
<n-input v-model:value="axis.title.style.text" size="small"></n-input>
|
||||
</setting-item>
|
||||
<FontStyle :style="axis.title.style"></FontStyle>
|
||||
<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="可见性">
|
||||
@@ -45,7 +62,11 @@
|
||||
<n-switch v-model:value="axis.grid.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name=""> </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>
|
||||
@@ -57,15 +78,33 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
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'
|
||||
|
||||
defineProps({
|
||||
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>
|
||||
|
||||
52
src/components/Pages/VChartItemSetting/Bar.vue
Normal file
52
src/components/Pages/VChartItemSetting/Bar.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<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>
|
||||
46
src/components/Pages/VChartItemSetting/Label.vue
Normal file
46
src/components/Pages/VChartItemSetting/Label.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<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>
|
||||
@@ -15,7 +15,7 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="项配置">
|
||||
<FontStyle :style="legendItem.item.label.style"></FontStyle>
|
||||
<FontStyle :style="toRefs(legendItem.item.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
@@ -23,7 +23,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
|
||||
33
src/components/Pages/VChartItemSetting/Line.vue
Normal file
33
src/components/Pages/VChartItemSetting/Line.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<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>
|
||||
56
src/components/Pages/VChartItemSetting/Point.vue
Normal file
56
src/components/Pages/VChartItemSetting/Point.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<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>
|
||||
@@ -20,20 +20,20 @@
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="标题">
|
||||
<FontStyle :style="optionData.tooltip.style.titleLabel"></FontStyle>
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.titleLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="名称">
|
||||
<FontStyle :style="optionData.tooltip.style.keyLabel"></FontStyle>
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.keyLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="值">
|
||||
<FontStyle :style="optionData.tooltip.style.valueLabel"></FontStyle>
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.valueLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
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'
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<!-- <div v-if="style"> -->
|
||||
<!-- <setting-item-box v-if="style" name=""> -->
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="style.fill" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="style.fontSize" :min="1" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字体">
|
||||
<n-select v-model:value="style.fontFamily" :options="fontStyleConfig.fontFamily" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字重">
|
||||
<n-select v-model:value="style.fontSize" :options="fontStyleConfig.fontWeight" size="small" />
|
||||
</setting-item>
|
||||
<!-- </setting-item-box> -->
|
||||
<!-- </div> -->
|
||||
<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">
|
||||
@@ -26,7 +33,7 @@ import { SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
style: {
|
||||
type: Object as PropType<FontType>,
|
||||
type: Object as PropType<any>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
84
src/components/Pages/VChartItemSetting/common/Padding.vue
Normal file
84
src/components/Pages/VChartItemSetting/common/Padding.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<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,4 +1,8 @@
|
||||
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 }
|
||||
export { VChartGlobalSetting, Axis, Label, Bar, Line, Point }
|
||||
|
||||
@@ -48,7 +48,6 @@ export enum MenuEnum {
|
||||
UN_GROUP = 'unGroup',
|
||||
// 后退
|
||||
BACK = 'back',
|
||||
// 前进
|
||||
FORWORD = 'forward',
|
||||
// 保存
|
||||
SAVE = 'save',
|
||||
@@ -84,3 +83,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',
|
||||
// 当前选择的主题
|
||||
|
||||
@@ -2,6 +2,7 @@ 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'
|
||||
|
||||
@@ -116,7 +116,7 @@ export const useChartDataPondFetch = () => {
|
||||
const requestDataPondItem = computed(() => {
|
||||
return requestGlobalConfig.requestDataPond.find(item => item.dataPondId === pondKey)
|
||||
}) as ComputedRef<RequestDataPondItemType>
|
||||
if (requestDataPondItem) {
|
||||
if (requestDataPondItem.value) {
|
||||
newPondItemInterval(chartEditStore.requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
|
||||
}
|
||||
}
|
||||
|
||||
23
src/hooks/useSystemInit.hook.ts
Normal file
23
src/hooks/useSystemInit.hook.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
|
||||
import { SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { ResultEnum } from '@/enums/httpEnum'
|
||||
import { ossUrlApi } from '@/api/path'
|
||||
|
||||
|
||||
// * 初始化
|
||||
export const useSystemInit = async () => {
|
||||
const systemStore = useSystemStore()
|
||||
|
||||
// 获取 OSS 信息的 url 地址,用来拼接展示图片的地址
|
||||
const getOssUrl = async () => {
|
||||
const res = await ossUrlApi({})
|
||||
if (res && res.code === ResultEnum.SUCCESS) {
|
||||
systemStore.setItem(SystemStoreEnum.FETCH_INFO, {
|
||||
OSSUrl: res.data?.bucketURL
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 执行
|
||||
getOssUrl()
|
||||
}
|
||||
@@ -11,6 +11,8 @@ const global = {
|
||||
help: 'Help',
|
||||
contact: 'About Software',
|
||||
logout: 'Logout',
|
||||
logout_success: 'Logout success!',
|
||||
logout_failure: 'Logout Failed!',
|
||||
// system setting
|
||||
sys_set: 'System Setting',
|
||||
lang_set: 'Language Setting',
|
||||
@@ -26,8 +28,14 @@ const global = {
|
||||
r_more: 'More',
|
||||
}
|
||||
|
||||
const http = {
|
||||
error_message: 'The interface is abnormal, please check the interface!',
|
||||
token_overdue_message: 'Login expired, please log in again!'
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
http,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ export default {
|
||||
desc: "Login",
|
||||
form_auto: "Sign in automatically",
|
||||
form_button: "Login",
|
||||
login_success: "Login success",
|
||||
login_message: "Please complete the letter",
|
||||
login_success: "Login success!",
|
||||
login_message: "Please complete the letter!",
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
export default {
|
||||
create_btn: 'Create',
|
||||
create_tip: 'Please select a content for development',
|
||||
create_btn: 'Creat',
|
||||
create_success: 'Creat Success!',
|
||||
create_failure: 'Failed to create, please try again later!',
|
||||
create_tip: 'Please select a content for development!',
|
||||
project: 'Project',
|
||||
my: 'My',
|
||||
new_project: 'New Project',
|
||||
all_project: 'All Project',
|
||||
my_templete: 'My Templete',
|
||||
my_template: 'My Template',
|
||||
template_market: 'Template Market',
|
||||
|
||||
// items
|
||||
|
||||
@@ -11,6 +11,8 @@ const global = {
|
||||
help: '帮助中心',
|
||||
contact: '关于软件',
|
||||
logout: '退出登录',
|
||||
logout_success: '退出成功!',
|
||||
logout_failure: '退出失败!',
|
||||
// 系统设置
|
||||
sys_set: '系统设置',
|
||||
lang_set: '语言设置',
|
||||
@@ -18,16 +20,27 @@ const global = {
|
||||
r_edit: '编辑',
|
||||
r_preview: '预览',
|
||||
r_copy: '克隆',
|
||||
r_copy_success: '克隆成功!',
|
||||
r_rename: '重命名',
|
||||
r_rename_success: '重命名成功!',
|
||||
r_publish: '发布',
|
||||
r_publish_success: '成功发布!',
|
||||
r_unpublish: '取消发布',
|
||||
r_unpublish_success: '取消成功!',
|
||||
r_download: '下载',
|
||||
r_delete: '删除',
|
||||
r_delete_success: '删除成功!',
|
||||
r_more: '更多',
|
||||
}
|
||||
|
||||
const http = {
|
||||
error_message: '获取数据失败,请稍后重试!',
|
||||
token_overdue_message: '登录过期,请重新登录!'
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
http,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ export default {
|
||||
desc: "登录",
|
||||
form_auto: "自动登录",
|
||||
form_button: "登录",
|
||||
login_success: "登录成功",
|
||||
login_message: "请填写完整信息",
|
||||
login_success: "登录成功!",
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
export default {
|
||||
// aside
|
||||
create_btn: '新建',
|
||||
create_success: '新建成功!',
|
||||
create_failure: '新建失败,请稍后重试!',
|
||||
create_tip: '从哪里出发好呢?',
|
||||
project: '项目',
|
||||
my: '我的',
|
||||
new_project: '新项目',
|
||||
all_project: '全部项目',
|
||||
my_templete: '我的模板',
|
||||
my_template: '我的模板',
|
||||
template_market: '模板市场',
|
||||
|
||||
// items
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
export * from './legends'
|
||||
export * from './legends'
|
||||
export * from './label'
|
||||
export * from './style'
|
||||
120
src/packages/chartConfiguration/vcharts/label.ts
Normal file
120
src/packages/chartConfiguration/vcharts/label.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
export const labelConfig = {
|
||||
position: [
|
||||
{
|
||||
label: '外部',
|
||||
value: 'outside'
|
||||
},
|
||||
{
|
||||
label: '内部',
|
||||
value: 'inside'
|
||||
},
|
||||
{
|
||||
label: '内部-外',
|
||||
value: 'inside-outer'
|
||||
},
|
||||
{
|
||||
label: '内部-里',
|
||||
value: 'inside-inner'
|
||||
},
|
||||
{
|
||||
label: '内部-居中',
|
||||
value: 'inside-center'
|
||||
}
|
||||
],
|
||||
barPosition: [
|
||||
{
|
||||
label: '外部',
|
||||
value: 'outside'
|
||||
},
|
||||
{
|
||||
label: '内部',
|
||||
value: 'inside'
|
||||
},
|
||||
{
|
||||
label: '顶部',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '底部',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左侧',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'right'
|
||||
},
|
||||
{
|
||||
label: '内部-顶',
|
||||
value: 'inside-top'
|
||||
},
|
||||
{
|
||||
label: '内部-底',
|
||||
value: 'inside-bottom'
|
||||
},
|
||||
{
|
||||
label: '内部-右',
|
||||
value: 'inside-right'
|
||||
},
|
||||
{
|
||||
label: '内部-左',
|
||||
value: 'inside-left'
|
||||
},
|
||||
{
|
||||
label: '顶部-右',
|
||||
value: 'top-right'
|
||||
},
|
||||
{
|
||||
label: '顶部-左',
|
||||
value: 'top-left'
|
||||
},
|
||||
{
|
||||
label: '底部-右',
|
||||
value: 'bottom-right'
|
||||
},
|
||||
{
|
||||
label: '底部-左',
|
||||
value: 'bottom-left'
|
||||
}
|
||||
],
|
||||
linePosition: [
|
||||
{
|
||||
label: '顶部',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '底部',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左侧',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'right'
|
||||
},
|
||||
{
|
||||
label: '顶部-右',
|
||||
value: 'top-right'
|
||||
},
|
||||
{
|
||||
label: '顶部-左',
|
||||
value: 'top-left'
|
||||
},
|
||||
{
|
||||
label: '底部-右',
|
||||
value: 'bottom-right'
|
||||
},
|
||||
{
|
||||
label: '底部-左',
|
||||
value: 'bottom-left'
|
||||
},
|
||||
{
|
||||
label: '居中',
|
||||
value: 'center'
|
||||
}
|
||||
]
|
||||
}
|
||||
150
src/packages/chartConfiguration/vcharts/style.ts
Normal file
150
src/packages/chartConfiguration/vcharts/style.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
export const styleConfig = {
|
||||
texture: [
|
||||
{
|
||||
label: '无纹理',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'circle'
|
||||
},
|
||||
{
|
||||
label: '钻石',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
label: '矩形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '竖线',
|
||||
value: 'horizontal-line'
|
||||
},
|
||||
{
|
||||
label: '横线',
|
||||
value: 'vertical-line'
|
||||
},
|
||||
{
|
||||
label: '右向左斜线',
|
||||
value: 'bias-rl'
|
||||
},
|
||||
{
|
||||
label: '左向右斜线',
|
||||
value: 'bias-lr'
|
||||
},
|
||||
{
|
||||
label: '格子',
|
||||
value: 'grid'
|
||||
}
|
||||
],
|
||||
curveType: [
|
||||
{
|
||||
label: '线性',
|
||||
value: 'linear'
|
||||
},
|
||||
{
|
||||
label: '平滑',
|
||||
value: 'monotone'
|
||||
},
|
||||
{
|
||||
label: '平滑趋近X',
|
||||
value: 'monotoneX'
|
||||
},
|
||||
{
|
||||
label: '台阶',
|
||||
value: 'step'
|
||||
},
|
||||
{
|
||||
label: '连线闭合',
|
||||
value: 'catmullRom'
|
||||
},
|
||||
{
|
||||
label: '顺滑闭合',
|
||||
value: 'catmullRomClosed'
|
||||
}
|
||||
],
|
||||
lineCap: [
|
||||
{
|
||||
label: '默认',
|
||||
value: 'butt'
|
||||
},
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'round'
|
||||
},
|
||||
{
|
||||
label: '方形',
|
||||
value: 'square'
|
||||
}
|
||||
],
|
||||
symbolType: [
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'circle'
|
||||
},
|
||||
{
|
||||
label: '方形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '菱形',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
label: '三角形',
|
||||
value: 'square'
|
||||
},
|
||||
{
|
||||
label: '指向向上',
|
||||
value: 'arrow'
|
||||
},
|
||||
{
|
||||
label: '指向向左',
|
||||
value: 'arrow2Left'
|
||||
},
|
||||
{
|
||||
label: '箭头向右',
|
||||
value: 'arrow2Right'
|
||||
},
|
||||
{
|
||||
label: '瘦箭头向上',
|
||||
value: 'wedge'
|
||||
},
|
||||
{
|
||||
label: '箭头向上',
|
||||
value: 'triangle'
|
||||
},
|
||||
{
|
||||
label: '箭头向下',
|
||||
value: 'triangleDown'
|
||||
},
|
||||
{
|
||||
label: '箭头向右',
|
||||
value: 'triangleRight'
|
||||
},
|
||||
{
|
||||
label: '箭头向左',
|
||||
value: 'triangleLeft'
|
||||
},
|
||||
{
|
||||
label: '星星',
|
||||
value: 'star'
|
||||
},
|
||||
{
|
||||
label: 'y字形物',
|
||||
value: 'wye'
|
||||
},
|
||||
{
|
||||
label: '矩形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '圆角矩形',
|
||||
value: 'rectRound'
|
||||
},
|
||||
{
|
||||
label: '扁平矩形',
|
||||
value: 'roundLine'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -124,7 +124,14 @@ const calcData = (data: any, type?: string) => {
|
||||
const calcCapsuleLengthAndLabelData = (dataset: any) => {
|
||||
try {
|
||||
const { source } = dataset
|
||||
if (!source || !source.length) return
|
||||
if (!source) return
|
||||
|
||||
if (source.length === 0) {
|
||||
// 清空数据
|
||||
state.capsuleLength = []
|
||||
state.labelData = []
|
||||
return
|
||||
}
|
||||
|
||||
state.capsuleItemHeight = numberSizeHandle(state.mergedConfig.itemHeight)
|
||||
const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])
|
||||
@@ -140,9 +147,8 @@ const calcCapsuleLengthAndLabelData = (dataset: any) => {
|
||||
const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))
|
||||
|
||||
state.labelData = labelData
|
||||
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ import config, { includes, seriesItem } from './config'
|
||||
import { mergeTheme } from '@/packages/public/chart'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { isPreview } from '@/utils'
|
||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import isObject from 'lodash/isObject'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
@@ -61,7 +61,7 @@ watch(
|
||||
if (Array.isArray(newData?.dimensions)) {
|
||||
const seriesArr = []
|
||||
for (let i = 0; i < newData.dimensions.length - 1; i++) {
|
||||
seriesArr.push(seriesItem)
|
||||
seriesArr.push(cloneDeep(seriesItem))
|
||||
}
|
||||
replaceMergeArr.value = ['series']
|
||||
props.chartConfig.option.series = seriesArr
|
||||
|
||||
@@ -56,7 +56,7 @@ export const option = {
|
||||
mapOptions: {
|
||||
pitch: 60,
|
||||
skyColor: '#53A9DE',
|
||||
amapKey: 'd5f3e16589dbecae64d05fe90e2ba4f2',
|
||||
amapKey: '',
|
||||
amapStyleKey: ThemeEnum.DARK,
|
||||
amapStyleKeyCustom: '',
|
||||
amapLon: 116.397428,
|
||||
|
||||
@@ -61,7 +61,7 @@ const option = {
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '40',
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
:options="labelConfig.fontWeight"
|
||||
/>
|
||||
</SettingItem>
|
||||
<setting-item name="文字边框大小" v-if="optionData.series[0].label.textBorderWidth">
|
||||
<setting-item name="文字边框大小" v-if="optionData.series[0].label.textBorderWidth > -1">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].label.textBorderWidth"
|
||||
size="small"
|
||||
@@ -81,7 +81,7 @@
|
||||
></n-color-picker>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="圆角">
|
||||
<setting-item-box name="分段样式">
|
||||
<setting-item name="圆角大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].itemStyle.borderRadius"
|
||||
|
||||
@@ -103,6 +103,10 @@ watch(
|
||||
() => props.chartConfig.option.type,
|
||||
newData => {
|
||||
try {
|
||||
// 防止初始化时触发修改,导致部分参数丢失
|
||||
if (isPreview()) {
|
||||
return
|
||||
}
|
||||
if (newData === 'nomal') {
|
||||
props.chartConfig.option.series[0].radius = '70%'
|
||||
props.chartConfig.option.series[0].roseType = false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="vChartRef">
|
||||
<n-countdown
|
||||
ref="countdownRef"
|
||||
:duration="totalDuration"
|
||||
@@ -79,6 +79,8 @@ import { CreateComponentType } from '@/packages/index.d'
|
||||
import { Flipper } from '@/components/Pages/Flipper'
|
||||
import { OptionType } from './config'
|
||||
import { CountdownInst, CountdownProps } from 'naive-ui/es/countdown/src/Countdown'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
@@ -174,6 +176,10 @@ watch(
|
||||
onMounted(() => {
|
||||
updateTotalDuration()
|
||||
})
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
<div class="rank" :style="`color: ${color};font-size: ${indexFontSize}px`">No.{{ item.ranking }}</div>
|
||||
<div class="info-name" :style="`font-size: ${leftFontSize}px`" v-html="item.name" />
|
||||
<div class="ranking-value" :style="`color: ${textColor};font-size: ${rightFontSize}px`">
|
||||
{{ status.mergedConfig.valueFormatter ? status.mergedConfig.valueFormatter(item) : item.value }}
|
||||
{{
|
||||
typeof status.mergedConfig.valueFormatter === 'function'
|
||||
? status.mergedConfig.valueFormatter(item)
|
||||
: item.value
|
||||
}}
|
||||
{{ unit }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,7 +66,8 @@ const status = reactive({
|
||||
const calcRowsData = () => {
|
||||
let { dataset, rowNum, sort } = status.mergedConfig
|
||||
// @ts-ignore
|
||||
sort &&dataset.sort(({ value: a }, { value: b } ) => {
|
||||
sort &&
|
||||
dataset.sort(({ value: a }, { value: b }) => {
|
||||
if (a > b) return -1
|
||||
if (a < b) return 1
|
||||
if (a === b) return 0
|
||||
@@ -137,7 +142,7 @@ const onRestart = async () => {
|
||||
calcRowsData()
|
||||
let flag = true
|
||||
if (dataset.length <= rowNum) {
|
||||
flag=false
|
||||
flag = false
|
||||
}
|
||||
calcHeights(flag)
|
||||
animation(flag)
|
||||
|
||||
@@ -3,11 +3,11 @@ import { VChartBarCommonConfig } from './index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
|
||||
import data from './data.json'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
|
||||
import { IBarOption } from '../../index.d'
|
||||
import { ChatCategoryEnum, IBarOption } from '../../index.d'
|
||||
import { merge, cloneDeep } from 'lodash'
|
||||
|
||||
export const includes = ['legends', 'tooltip']
|
||||
export const includes = ['legends', 'tooltip', 'label', 'bar']
|
||||
export const option: IBarOption & { dataset?: any } = {
|
||||
// 图表配置
|
||||
type: 'bar',
|
||||
@@ -17,10 +17,17 @@ export const option: IBarOption & { dataset?: any } = {
|
||||
yField: ['value'],
|
||||
seriesField: 'type',
|
||||
// 业务配置(后续会被转换为图表spec)
|
||||
category: VChartBarCommonConfig.category,
|
||||
category: VChartBarCommonConfig.category as ChatCategoryEnum.BAR,
|
||||
xAxis: {
|
||||
name: 'x轴',
|
||||
...axisThemeJson,
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 10,
|
||||
dy: 0
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
visible: false
|
||||
@@ -28,12 +35,18 @@ export const option: IBarOption & { dataset?: any } = {
|
||||
},
|
||||
yAxis: {
|
||||
name: 'y轴',
|
||||
...axisThemeJson,
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 0,
|
||||
dy: -10
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
style: {
|
||||
...axisThemeJson.grid.style,
|
||||
lineDash: [3, 3]
|
||||
...axisThemeJson.grid.style
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
|
||||
<Axis :axis="optionData.xAxis"></Axis>
|
||||
<Axis :axis="optionData.yAxis"></Axis>
|
||||
<!-- 标签 -->
|
||||
<Label :optionData="optionData"></Label>
|
||||
<!-- 柱体 -->
|
||||
<Bar :optionData="optionData"></Bar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
|
||||
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
|
||||
defineProps({
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartBarCommonConfig: ConfigType = {
|
||||
key: 'VChartBarCommon',
|
||||
chartKey: 'VVChartBarCommon',
|
||||
conKey: 'VCVChartBarCommon',
|
||||
title: 'VChart并列柱状图',
|
||||
title: '并列柱状图-VChart',
|
||||
category: ChatCategoryEnum.BAR,
|
||||
categoryName: ChatCategoryEnumName.BAR,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { VChartBarCrossrangeConfig } from './index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
|
||||
import data from './data.json'
|
||||
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
|
||||
import { ChatCategoryEnum, IBarOption } from '../../index.d'
|
||||
import { merge, cloneDeep } from 'lodash'
|
||||
import { vChartGlobalThemeJson } from '@/settings/vchartThemes'
|
||||
|
||||
const barConfig = merge(cloneDeep(vChartGlobalThemeJson.bar), {
|
||||
style: {
|
||||
height: 10
|
||||
}
|
||||
})
|
||||
delete (barConfig.style as { width?: any }).width
|
||||
|
||||
export const includes = ['legends', 'tooltip', 'label']
|
||||
export const option: IBarOption & { dataset?: any } = {
|
||||
// 图表配置
|
||||
type: 'bar',
|
||||
dataset: data,
|
||||
stack: true,
|
||||
xField: ['value'],
|
||||
yField: ['year', 'type'],
|
||||
seriesField: 'type',
|
||||
// 业务配置(后续会被转换为图表spec)
|
||||
category: VChartBarCrossrangeConfig.category as ChatCategoryEnum.BAR,
|
||||
direction: 'horizontal',
|
||||
xAxis: {
|
||||
name: 'x轴',
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 10,
|
||||
dy: 0
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: 'y轴',
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 0,
|
||||
dy: -10
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
style: {
|
||||
...axisThemeJson.grid.style
|
||||
}
|
||||
}
|
||||
},
|
||||
bar: {
|
||||
...barConfig
|
||||
}
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = VChartBarCrossrangeConfig.key
|
||||
public chartConfig = cloneDeep(VChartBarCrossrangeConfig)
|
||||
// 图表配置项
|
||||
public option = vChartOptionPrefixHandle(option, includes)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<!-- vCharts 全局设置 -->
|
||||
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
|
||||
<Axis :axis="optionData.xAxis"></Axis>
|
||||
<Axis :axis="optionData.yAxis"></Axis>
|
||||
<!-- 标签 -->
|
||||
<Label :optionData="optionData"></Label>
|
||||
<!-- 柱体 -->
|
||||
<Bar :optionData="optionData"></Bar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"values": [
|
||||
{ "type": "Autocracies", "year": "1930", "value": 129 },
|
||||
{ "type": "Autocracies", "year": "1940", "value": 133 },
|
||||
{ "type": "Autocracies", "year": "1950", "value": 130 },
|
||||
{ "type": "Autocracies", "year": "1960", "value": 126 },
|
||||
{ "type": "Autocracies", "year": "1970", "value": 117 },
|
||||
{ "type": "Autocracies", "year": "1980", "value": 114 },
|
||||
{ "type": "Autocracies", "year": "1990", "value": 111 },
|
||||
{ "type": "Autocracies", "year": "2000", "value": 89 },
|
||||
{ "type": "Autocracies", "year": "2010", "value": 80 },
|
||||
{ "type": "Autocracies", "year": "2018", "value": 80 },
|
||||
|
||||
{ "type": "Democracies", "year": "1930", "value": 22 },
|
||||
{ "type": "Democracies", "year": "1940", "value": 13 },
|
||||
{ "type": "Democracies", "year": "1950", "value": 25 },
|
||||
{ "type": "Democracies", "year": "1960", "value": 29 },
|
||||
{ "type": "Democracies", "year": "1970", "value": 38 },
|
||||
{ "type": "Democracies", "year": "1980", "value": 41 },
|
||||
{ "type": "Democracies", "year": "1990", "value": 57 },
|
||||
{ "type": "Democracies", "year": "2000", "value": 87 },
|
||||
{ "type": "Democracies", "year": "2010", "value": 98 },
|
||||
{ "type": "Democracies", "year": "2018", "value": 99 }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const VChartBarCrossrangeConfig: ConfigType = {
|
||||
key: 'VChartBarCrossrange',
|
||||
chartKey: 'VVChartBarCrossrange',
|
||||
conKey: 'VCVChartBarCrossrange',
|
||||
title: '并列柱状图-VChart',
|
||||
category: ChatCategoryEnum.BAR,
|
||||
categoryName: ChatCategoryEnumName.BAR,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
chartFrame: ChartFrameEnum.VCHART,
|
||||
image: 'vchart_bar_y.png'
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { GoVChart } from '@/components/GoVChart'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import config from './config'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<config>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
</script>
|
||||
@@ -3,11 +3,18 @@ import { VChartBarStackConfig } from './index'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
|
||||
import data from './data.json'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
|
||||
import { IBarOption } from '../../index.d'
|
||||
import { ChatCategoryEnum, IBarOption } from '../../index.d'
|
||||
import { merge, cloneDeep } from 'lodash'
|
||||
import { vChartGlobalThemeJson } from '@/settings/vchartThemes'
|
||||
|
||||
export const includes = ['legends', 'tooltip']
|
||||
const barConfig = merge(cloneDeep(vChartGlobalThemeJson.bar), {
|
||||
style: {
|
||||
width: 15
|
||||
}
|
||||
})
|
||||
|
||||
export const includes = ['legends', 'tooltip', 'label']
|
||||
export const option: IBarOption & { dataset?: any } = {
|
||||
// 图表配置
|
||||
type: 'bar',
|
||||
@@ -16,11 +23,20 @@ export const option: IBarOption & { dataset?: any } = {
|
||||
yField: ['value'],
|
||||
seriesField: 'year',
|
||||
stack: true,
|
||||
// 开启百分比
|
||||
percent: false,
|
||||
// 业务配置(后续会被转换为图表spec)
|
||||
category: VChartBarStackConfig.category,
|
||||
category: VChartBarStackConfig.category as ChatCategoryEnum.BAR,
|
||||
xAxis: {
|
||||
name: 'x轴',
|
||||
...axisThemeJson,
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 10,
|
||||
dy: 0
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
visible: false
|
||||
@@ -28,14 +44,23 @@ export const option: IBarOption & { dataset?: any } = {
|
||||
},
|
||||
yAxis: {
|
||||
name: 'y轴',
|
||||
...axisThemeJson,
|
||||
...(merge(cloneDeep(axisThemeJson), {
|
||||
unit: {
|
||||
style: {
|
||||
dx: 0,
|
||||
dy: -10
|
||||
}
|
||||
}
|
||||
}) as any),
|
||||
grid: {
|
||||
...axisThemeJson.grid,
|
||||
style: {
|
||||
...axisThemeJson.grid.style,
|
||||
lineDash: [3, 3]
|
||||
...axisThemeJson.grid.style
|
||||
}
|
||||
}
|
||||
},
|
||||
bar: {
|
||||
...barConfig
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,26 @@
|
||||
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
|
||||
<Axis :axis="optionData.xAxis"></Axis>
|
||||
<Axis :axis="optionData.yAxis"></Axis>
|
||||
<!-- 标签 -->
|
||||
<Label :optionData="optionData"></Label>
|
||||
<!-- 柱体 -->
|
||||
<Bar :optionData="optionData"></Bar>
|
||||
<!-- 开启百分比 -->
|
||||
<CollapseItem name="百分比堆叠">
|
||||
<SettingItemBox name="配置" alone>
|
||||
<n-space>
|
||||
<span>开启百分比堆叠</span>
|
||||
<n-switch v-model:value="optionData.percent" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
|
||||
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartBarStackConfig: ConfigType = {
|
||||
key: 'VChartBarStack',
|
||||
chartKey: 'VVChartBarStack',
|
||||
conKey: 'VCVChartBarStack',
|
||||
title: 'VChart堆叠柱状图',
|
||||
title: '堆叠柱状图-VChart',
|
||||
category: ChatCategoryEnum.BAR,
|
||||
categoryName: ChatCategoryEnumName.BAR,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { VChartBarCommonConfig } from './VChartBarCommon/index'
|
||||
import { VChartBarCrossrangeConfig } from './VChartBarCrossrange/index'
|
||||
import { VChartBarStackConfig } from './VChartBarStack/index'
|
||||
|
||||
export default [VChartBarCommonConfig, VChartBarStackConfig]
|
||||
export default [VChartBarCommonConfig, VChartBarCrossrangeConfig, VChartBarStackConfig]
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartFunnelConfig: ConfigType = {
|
||||
key: 'VChartFunnel',
|
||||
chartKey: 'VVChartFunnel',
|
||||
conKey: 'VCVChartFunnel',
|
||||
title: 'VChart漏斗图',
|
||||
title: '漏斗图-VChart',
|
||||
category: ChatCategoryEnum.FUNNEL,
|
||||
categoryName: ChatCategoryEnumName.FUNNEL,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -5,9 +5,9 @@ import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
|
||||
import data from './data.json'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
|
||||
import { ILineOption } from '../../index.d'
|
||||
import { ChatCategoryEnum, ILineOption } from '../../index.d'
|
||||
|
||||
export const includes = ['legends', 'tooltip']
|
||||
export const includes = ['legends', 'tooltip', 'label', 'line', 'point']
|
||||
export const option: ILineOption & { dataset?: any } = {
|
||||
// 图表配置
|
||||
type: 'line',
|
||||
@@ -16,8 +16,10 @@ export const option: ILineOption & { dataset?: any } = {
|
||||
yField: 'value',
|
||||
seriesField: 'country',
|
||||
stack: true,
|
||||
// 开启百分比
|
||||
percent: false,
|
||||
// 业务配置(后续会被转换为图表spec)
|
||||
category: VChartLineConfig.category,
|
||||
category: VChartLineConfig.category as ChatCategoryEnum.LINE,
|
||||
xAxis: {
|
||||
name: 'x轴',
|
||||
...axisThemeJson,
|
||||
@@ -25,7 +27,7 @@ export const option: ILineOption & { dataset?: any } = {
|
||||
...axisThemeJson.grid,
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
} as any,
|
||||
yAxis: {
|
||||
name: 'y轴',
|
||||
...axisThemeJson,
|
||||
@@ -36,7 +38,7 @@ export const option: ILineOption & { dataset?: any } = {
|
||||
lineDash: [3, 3]
|
||||
}
|
||||
}
|
||||
}
|
||||
} as any
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
|
||||
@@ -3,12 +3,26 @@
|
||||
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
|
||||
<Axis :axis="optionData.xAxis"></Axis>
|
||||
<Axis :axis="optionData.yAxis"></Axis>
|
||||
<!-- 开启百分比 -->
|
||||
<CollapseItem name="百分比堆叠">
|
||||
<SettingItemBox name="配置" alone>
|
||||
<n-space>
|
||||
<span>开启百分比堆叠</span>
|
||||
<n-switch v-model:value="optionData.percent" size="small"></n-switch>
|
||||
</n-space>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
<Line :optionData="optionData"></Line>
|
||||
<Label :optionData="optionData" :positionOptions="labelConfig.linePosition"></Label>
|
||||
<Point :optionData="optionData"></Point>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
|
||||
import { VChartGlobalSetting, Axis, Label, Line, Point } from '@/components/Pages/VChartItemSetting'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
|
||||
import { labelConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartLineConfig: ConfigType = {
|
||||
key: 'VChartLine',
|
||||
chartKey: 'VVChartLine',
|
||||
conKey: 'VCVChartLine',
|
||||
title: 'VChart折线图',
|
||||
title: '折线图-VChart',
|
||||
category: ChatCategoryEnum.LINE,
|
||||
categoryName: ChatCategoryEnumName.LINE,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -4,7 +4,9 @@ import { CreateComponentType } from '@/packages/index.d'
|
||||
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
|
||||
import data from './data.json'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { IPieOption } from '../../index.d'
|
||||
import type { ChatCategoryEnum, IPieOption } from '../../index.d'
|
||||
|
||||
const OUTER_RADIUS = 0.75
|
||||
|
||||
export const includes = ['legends', 'tooltip']
|
||||
export const option: IPieOption & { dataset?: any } = {
|
||||
@@ -14,8 +16,57 @@ export const option: IPieOption & { dataset?: any } = {
|
||||
categoryField: 'year',
|
||||
valueField: 'value',
|
||||
seriesField: 'year',
|
||||
// 中心
|
||||
centerX: '50%',
|
||||
centerY: '50%',
|
||||
innerRadius: 0.68,
|
||||
outerRadius: OUTER_RADIUS,
|
||||
label: {
|
||||
visible: true,
|
||||
position: 'outside',
|
||||
style: {
|
||||
fontSize: 12,
|
||||
fill: '#B9B8CE',
|
||||
fontFamily: 'SimSun',
|
||||
fontWeight: 'normal',
|
||||
angle: 0
|
||||
},
|
||||
line: {
|
||||
visible: true
|
||||
}
|
||||
},
|
||||
pie: {
|
||||
style: {
|
||||
// 圆角
|
||||
cornerRadius: 50,
|
||||
// 描边宽度
|
||||
outerBorder: {
|
||||
// 透明度
|
||||
strokeOpacity: 1,
|
||||
// 外描边距离
|
||||
distance: 0,
|
||||
// 宽度
|
||||
lineWidth: 0,
|
||||
// 颜色
|
||||
stroke: '#ffffff'
|
||||
},
|
||||
// 纹理
|
||||
texture: ''
|
||||
},
|
||||
state: {
|
||||
hover: {
|
||||
outerRadius: 0.85
|
||||
},
|
||||
selected: {
|
||||
outerRadius: 0.85
|
||||
}
|
||||
}
|
||||
},
|
||||
// 业务配置(后续会被转换为图表spec)
|
||||
category: VChartPieConfig.category,
|
||||
category: VChartPieConfig.category as ChatCategoryEnum.PIE,
|
||||
extensionMark: [],
|
||||
// 动画
|
||||
animationNormal: {}
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
|
||||
@@ -1,17 +1,164 @@
|
||||
<template>
|
||||
<!-- vCharts 全局设置 -->
|
||||
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
|
||||
<!-- 饼图配制 -->
|
||||
<CollapseItem name="饼图" expanded>
|
||||
<!-- <SettingItemBox name="动画">
|
||||
<SettingItem>
|
||||
<n-space>
|
||||
<n-switch v-model:value="animationRef" size="small" @update:value="animationHandle"></n-switch>
|
||||
<n-text>开启动画</n-text>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
</SettingItemBox> -->
|
||||
<SettingItemBox name="图形">
|
||||
<setting-item name="内圈范围">
|
||||
<n-input-number v-model:value="optionData.innerRadius" :step="0.1" :min="0" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="外圈范围">
|
||||
<n-input-number v-model:value="optionData.outerRadius" :step="0.1" :min="0" size="small"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="中心轴X">
|
||||
<n-input v-model:value="optionData.centerX" :step="1" :min="0" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="中心轴Y">
|
||||
<n-input v-model:value="optionData.centerY" :step="1" :min="0" size="small"></n-input>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="标签" v-if="optionData.label">
|
||||
<SettingItem>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.label.visible" size="small"></n-switch>
|
||||
<n-text>展示标签</n-text>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-space>
|
||||
<n-switch v-model:value="optionData.label.line.visible" size="small"></n-switch>
|
||||
<n-text>引导线</n-text>
|
||||
</n-space>
|
||||
</SettingItem>
|
||||
<SettingItem name="位置">
|
||||
<n-select v-model:value="optionData.label.position" :options="labelConfig.position" size="small" />
|
||||
</SettingItem>
|
||||
<FontStyle :style="toRefs(optionData.label.style)"></FontStyle>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="分段样式">
|
||||
<setting-item name="纹理类型">
|
||||
<n-select v-model:value="optionData.pie.style.texture" :options="styleConfig.texture" size="small"></n-select>
|
||||
</setting-item>
|
||||
<setting-item name="圆角大小">
|
||||
<n-input-number v-model:value="optionData.pie.style.cornerRadius" size="small" :min="0"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="描边宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.pie.style.outerBorder.lineWidth"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="optionData.pie.style.outerBorder.stroke" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="外描边距离">
|
||||
<n-input-number
|
||||
v-model:value="optionData.pie.style.outerBorder.distance"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="描边透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.pie.style.outerBorder.strokeOpacity"
|
||||
:step="0.1"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="内环形">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="extensionMarkRef" size="small" @update:value="markerHandle"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { PropType, ref, toRefs } from 'vue'
|
||||
import { VChartGlobalSetting } from '@/components/Pages/VChartItemSetting'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import FontStyle from '@/components/Pages/VChartItemSetting/common/FontStyle.vue'
|
||||
import type { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { labelConfig, styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const animationRef = ref(props.optionData.animationNormal && Object.keys(props.optionData.animationNormal)?.length > 0)
|
||||
const extensionMarkRef = ref(!!props.optionData?.extensionMark)
|
||||
|
||||
const markerHandle = (value: boolean) => {
|
||||
if (value) {
|
||||
props.optionData.extensionMark = []
|
||||
} else {
|
||||
delete props.optionData.extensionMark
|
||||
}
|
||||
}
|
||||
|
||||
const animationHandle = (value: boolean) => {
|
||||
if (value) {
|
||||
props.optionData.animationNormal = {
|
||||
pie: [
|
||||
{
|
||||
loop: true,
|
||||
startTime: 800,
|
||||
oneByOne: true,
|
||||
timeSlices: [
|
||||
{
|
||||
effects: {
|
||||
channel: {
|
||||
outerRadius: {
|
||||
to: props.optionData.outerRadius * 100 + 10
|
||||
}
|
||||
},
|
||||
easing: 'linear'
|
||||
},
|
||||
duration: 500
|
||||
},
|
||||
{
|
||||
effects: {
|
||||
channel: {
|
||||
outerRadius: {
|
||||
to: props.optionData.outerRadius * 100 + 10
|
||||
}
|
||||
},
|
||||
easing: 'linear'
|
||||
},
|
||||
duration: 500
|
||||
},
|
||||
{
|
||||
effects: {
|
||||
channel: {
|
||||
outerRadius: {
|
||||
to: props.optionData.outerRadius * 100
|
||||
}
|
||||
}
|
||||
},
|
||||
duration: 500
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
props.optionData.animationNormal = {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartPieConfig: ConfigType = {
|
||||
key: 'VChartPie',
|
||||
chartKey: 'VVChartPie',
|
||||
conKey: 'VCVChartPie',
|
||||
title: 'VChart饼图',
|
||||
title: '饼图多欢-VChart',
|
||||
category: ChatCategoryEnum.PIE,
|
||||
categoryName: ChatCategoryEnumName.PIE,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartScatterConfig: ConfigType = {
|
||||
key: 'VChartScatter',
|
||||
chartKey: 'VVChartScatter',
|
||||
conKey: 'VCVChartScatter',
|
||||
title: 'VChart散点图',
|
||||
title: '散点图-VChart',
|
||||
category: ChatCategoryEnum.SCATTER,
|
||||
categoryName: ChatCategoryEnumName.SCATTER,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
@@ -5,7 +5,7 @@ export const VChartWordCloudConfig: ConfigType = {
|
||||
key: 'VChartWordCloud',
|
||||
chartKey: 'VVChartWordCloud',
|
||||
conKey: 'VCVChartWordCloud',
|
||||
title: 'VChart词云图',
|
||||
title: '词云图-VChart',
|
||||
category: ChatCategoryEnum.WORDCLOUD,
|
||||
categoryName: ChatCategoryEnumName.WORDCLOUD,
|
||||
package: PackagesCategoryEnum.VCHART,
|
||||
|
||||
2
src/packages/components/VChart/index.d.ts
vendored
2
src/packages/components/VChart/index.d.ts
vendored
@@ -56,7 +56,7 @@ export interface IAreaOption extends Omit<IAreaChartSpec, 'axes'> {
|
||||
}
|
||||
|
||||
export interface IPieOption extends IPieChartSpec {
|
||||
category: ChatCategoryEnum.PIE
|
||||
category?: ChatCategoryEnum.PIE
|
||||
type: 'pie'
|
||||
}
|
||||
|
||||
|
||||
4
src/packages/index.d.ts
vendored
4
src/packages/index.d.ts
vendored
@@ -27,9 +27,9 @@ export type ConfigType = {
|
||||
// 标题
|
||||
title: string
|
||||
// 分类
|
||||
category: ChatCategoryEnum
|
||||
category: string
|
||||
// 分类名称
|
||||
categoryName: ChatCategoryEnumName
|
||||
categoryName: string
|
||||
// 所属包
|
||||
package: PackagesCategoryEnum
|
||||
// 归类
|
||||
|
||||
@@ -8,7 +8,10 @@ import { SketchRule } from 'vue3-sketch-ruler'
|
||||
* @param app
|
||||
*/
|
||||
export function setupCustomComponents(app: App) {
|
||||
// 骨架屏
|
||||
app.component('GoSkeleton', GoSkeleton)
|
||||
// 加载
|
||||
app.component('GoLoading', GoLoading)
|
||||
// 标尺
|
||||
app.component('SketchRule', SketchRule)
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
ArrowDown as ArrowDownIcon,
|
||||
Planet as PawIcon,
|
||||
Search as SearchIcon,
|
||||
Reload as ReloadIcon,
|
||||
ChevronUpOutline as ChevronUpOutlineIcon,
|
||||
ChevronDownOutline as ChevronDownOutlineIcon,
|
||||
ChevronForward as ChevronForwardIcon,
|
||||
@@ -98,12 +99,14 @@ import {
|
||||
FitToScreen as FitToScreenIcon,
|
||||
FitToHeight as FitToHeightIcon,
|
||||
FitToWidth as FitToWidthIcon,
|
||||
Save as SaveIcon,
|
||||
Carbon3DCursor as Carbon3DCursorIcon,
|
||||
Carbon3DSoftware as Carbon3DSoftwareIcon,
|
||||
Filter as FilterIcon,
|
||||
FilterEdit as FilterEditIcon,
|
||||
Laptop as LaptopIcon,
|
||||
ChartPie as ChartPieIcon
|
||||
ChartPie as ChartPieIcon,
|
||||
Edit as EditIcon
|
||||
} from '@vicons/carbon'
|
||||
|
||||
const ionicons5 = {
|
||||
@@ -220,6 +223,8 @@ const ionicons5 = {
|
||||
PawIcon,
|
||||
// 搜索(放大镜)
|
||||
SearchIcon,
|
||||
// 加载
|
||||
ReloadIcon,
|
||||
// 过滤器
|
||||
FilterIcon,
|
||||
// 向上
|
||||
@@ -293,6 +298,8 @@ const carbon = {
|
||||
FitToScreenIcon,
|
||||
FitToHeightIcon,
|
||||
FitToWidthIcon,
|
||||
// 保存
|
||||
SaveIcon,
|
||||
// 成组
|
||||
Carbon3DCursorIcon,
|
||||
// 解组
|
||||
@@ -303,7 +310,9 @@ const carbon = {
|
||||
// 图层
|
||||
LaptopIcon,
|
||||
// 柱状图
|
||||
ChartPieIcon
|
||||
ChartPieIcon,
|
||||
// 编辑
|
||||
EditIcon
|
||||
}
|
||||
|
||||
// https://www.xicons.org/#/ 还有很多
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import type { AppRouteRecordRaw } from '@/router/types';
|
||||
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout } from '@/router/constant';
|
||||
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout, RedirectHome, RedirectUnPublish } from '@/router/constant';
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import { GoReload } from '@/components/GoReload'
|
||||
|
||||
|
||||
export const LoginRoute: RouteRecordRaw = {
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
path: PageEnum.BASE_LOGIN,
|
||||
name: PageEnum.BASE_LOGIN_NAME,
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
meta: {
|
||||
title: '登录',
|
||||
@@ -60,22 +60,21 @@ export const ReloadRoute: AppRouteRecordRaw = {
|
||||
},
|
||||
}
|
||||
|
||||
export const RedirectRoute: AppRouteRecordRaw = {
|
||||
path: PageEnum.REDIRECT,
|
||||
name: PageEnum.REDIRECT_NAME,
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: PageEnum.REDIRECT_NAME,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
name: PageEnum.REDIRECT_NAME,
|
||||
component: () => import('@/views/redirect/index.vue'),
|
||||
meta: {
|
||||
title: PageEnum.REDIRECT_NAME,
|
||||
hideBreadcrumb: true,
|
||||
},
|
||||
export const RedirectRoute: RouteRecordRaw[] = [
|
||||
{
|
||||
path: PageEnum.REDIRECT,
|
||||
name: PageEnum.REDIRECT_NAME,
|
||||
component: RedirectHome,
|
||||
meta: {
|
||||
title: PageEnum.REDIRECT_NAME,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
{
|
||||
path: PageEnum.REDIRECT_UN_PUBLISH,
|
||||
name: PageEnum.REDIRECT_UN_PUBLISH_NAME,
|
||||
component: RedirectUnPublish,
|
||||
meta: {
|
||||
title: PageEnum.REDIRECT_UN_PUBLISH_NAME,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -4,6 +4,10 @@ export const ErrorPage403 = () => import('@/views/exception/403.vue');
|
||||
|
||||
export const ErrorPage500 = () => import('@/views/exception/500.vue');
|
||||
|
||||
export const RedirectHome = () => import('@/views/redirect/index.vue');
|
||||
|
||||
export const RedirectUnPublish = () => import('@/views/redirect/UnPublish.vue');
|
||||
|
||||
export const Layout = () => import('@/layout/index.vue');
|
||||
|
||||
export const ParentLayout = () => import('@/layout/parentLayout.vue');
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type { App } from 'vue'
|
||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
|
||||
import { RedirectRoute } from '@/router/base'
|
||||
import { createRouterGuards } from './router-guards'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import { HttpErrorPage, LoginRoute, ReloadRoute } from '@/router/base'
|
||||
import { HttpErrorPage, LoginRoute, ReloadRoute, RedirectRoute } from '@/router/base'
|
||||
import { Layout } from '@/router/constant'
|
||||
|
||||
import modules from '@/router/modules'
|
||||
@@ -19,6 +18,7 @@ const RootRoute: Array<RouteRecordRaw> = [
|
||||
},
|
||||
children: [
|
||||
...HttpErrorPage,
|
||||
...RedirectRoute,
|
||||
modules.projectRoutes,
|
||||
modules.chartRoutes,
|
||||
modules.previewRoutes,
|
||||
@@ -28,7 +28,7 @@ const RootRoute: Array<RouteRecordRaw> = [
|
||||
]
|
||||
|
||||
|
||||
export const constantRouter: any[] = [LoginRoute, ...RootRoute, RedirectRoute, ReloadRoute];
|
||||
export const constantRouter: any[] = [LoginRoute, ...RootRoute, ReloadRoute];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(''),
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { Router } from 'vue-router';
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import { PageEnum, PreviewEnum } from '@/enums/pageEnum'
|
||||
import { loginCheck } from '@/utils'
|
||||
|
||||
// 路由白名单
|
||||
const routerAllowList = [
|
||||
// 登录
|
||||
PageEnum.BASE_LOGIN_NAME,
|
||||
// 预览
|
||||
PreviewEnum.CHART_PREVIEW_NAME
|
||||
]
|
||||
|
||||
export function createRouterGuards(router: Router) {
|
||||
// 前置
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
@@ -19,10 +27,8 @@ export function createRouterGuards(router: Router) {
|
||||
next({ name: PageEnum.ERROR_PAGE_NAME_404 })
|
||||
}
|
||||
|
||||
if (!loginCheck()) {
|
||||
if (to.name === PageEnum.BASE_LOGIN_NAME) {
|
||||
next()
|
||||
}
|
||||
// @ts-ignore
|
||||
if (!routerAllowList.includes(to.name) && !loginCheck()) {
|
||||
next({ name: PageEnum.BASE_LOGIN_NAME })
|
||||
}
|
||||
next()
|
||||
|
||||
@@ -61,6 +61,9 @@ export const editToJsonInterval = 5000
|
||||
// 数据请求间隔
|
||||
export const requestInterval = 30
|
||||
|
||||
// 工作台自动保存间隔(s)
|
||||
export const saveInterval = 30
|
||||
|
||||
// 数据请求间隔单位
|
||||
export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND
|
||||
|
||||
|
||||
2
src/settings/httpSetting.ts
Normal file
2
src/settings/httpSetting.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
// 请求前缀
|
||||
export const axiosPre = '/api/goview'
|
||||
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"visible": true,
|
||||
"unit": {
|
||||
"visible": true,
|
||||
"text": "",
|
||||
"style": {
|
||||
"text": "",
|
||||
"fontSize": 12,
|
||||
"fill": "#B9B8CE",
|
||||
"fontFamily": "SimSun",
|
||||
"fontWeight": "normal",
|
||||
"angle": 0,
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"visible": true,
|
||||
"style": {
|
||||
@@ -7,17 +21,25 @@
|
||||
"fill": "#B9B8CE",
|
||||
"fontFamily": "SimSun",
|
||||
"fontWeight": "normal",
|
||||
"angle": 0
|
||||
"angle": 0,
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"visible": true,
|
||||
"position": "middle",
|
||||
"angle": 0,
|
||||
"padding": [],
|
||||
"style": {
|
||||
"text": "",
|
||||
"fontSize": 12,
|
||||
"fill": "#B9B8CE",
|
||||
"fontFamily": "SimSun",
|
||||
"fontWeight": "normal"
|
||||
"fontWeight": "normal",
|
||||
"angle": 0,
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
"domainLine": {
|
||||
|
||||
@@ -74,5 +74,49 @@
|
||||
},
|
||||
"spaceRow": 10
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"visible": false,
|
||||
"position": "outside",
|
||||
"offset": 5,
|
||||
"type": "text",
|
||||
"style": {
|
||||
"fontSize": 12,
|
||||
"fill": "#B9B8CE",
|
||||
"fontFamily": "SimSun",
|
||||
"fontWeight": "normal",
|
||||
"angle": 0,
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"style": {
|
||||
"width": 10,
|
||||
"cornerRadius": 0,
|
||||
"fillOpacity": 1,
|
||||
"opacity": 1,
|
||||
"texture": ""
|
||||
}
|
||||
},
|
||||
"line": {
|
||||
"style": {
|
||||
"lineWidth": 1,
|
||||
"lineCap": "butt",
|
||||
"curveType": "linear"
|
||||
}
|
||||
},
|
||||
"point": {
|
||||
"visible": true,
|
||||
"style": {
|
||||
"symbolType": "circle",
|
||||
"size": 10,
|
||||
"fillOpacity": 1,
|
||||
"lineWidth": 2,
|
||||
"stroke": "#ffffff",
|
||||
"strokeOpacity": 1,
|
||||
"dx": 0,
|
||||
"dy": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ export type FontType = {
|
||||
fontFamily: string
|
||||
fontWeight: string
|
||||
fill: string
|
||||
dy?: number
|
||||
dx?: number
|
||||
angle?: number
|
||||
[T: string]: any
|
||||
}
|
||||
export interface vChartGlobalThemeJsonType extends Partial<ThemeJsonType> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d'
|
||||
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
import { SyncEnum } from '@/enums/editPageEnum'
|
||||
import {
|
||||
RequestHttpEnum,
|
||||
RequestContentTypeEnum,
|
||||
@@ -12,6 +13,29 @@ import {
|
||||
import { PreviewScaleEnum } from '@/enums/styleEnum'
|
||||
import type { ChartColorsNameType, CustomColorsType, GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
|
||||
// 项目数据枚举
|
||||
export enum ProjectInfoEnum {
|
||||
// ID
|
||||
PROJECT_ID = "projectId",
|
||||
// 名称
|
||||
PROJECT_NAME = 'projectName',
|
||||
// 描述
|
||||
REMARKS = 'remarks',
|
||||
// 缩略图
|
||||
THUMBNAIL= 'thumbnail',
|
||||
// 是否公开发布
|
||||
RELEASE = 'release'
|
||||
}
|
||||
|
||||
// 项目数据
|
||||
export type ProjectInfoType = {
|
||||
[ProjectInfoEnum.PROJECT_ID]: string,
|
||||
[ProjectInfoEnum.PROJECT_NAME]: string,
|
||||
[ProjectInfoEnum.REMARKS]: string,
|
||||
[ProjectInfoEnum.THUMBNAIL]: string,
|
||||
[ProjectInfoEnum.RELEASE]: boolean
|
||||
}
|
||||
|
||||
// 编辑画布属性
|
||||
export enum EditCanvasTypeEnum {
|
||||
EDIT_LAYOUT_DOM = 'editLayoutDom',
|
||||
@@ -20,13 +44,14 @@ export enum EditCanvasTypeEnum {
|
||||
SCALE = 'scale',
|
||||
USER_SCALE = 'userScale',
|
||||
LOCK_SCALE = 'lockScale',
|
||||
SAVE_STATUS = 'saveStatus',
|
||||
IS_CREATE = 'isCreate',
|
||||
IS_DRAG = 'isDrag',
|
||||
IS_SELECT = 'isSelect',
|
||||
IS_CODE_EDIT="isCodeEdit"
|
||||
}
|
||||
|
||||
// 编辑区域
|
||||
// 编辑区域(临时)
|
||||
export type EditCanvasType = {
|
||||
// 编辑区域 DOM
|
||||
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
|
||||
@@ -43,13 +68,15 @@ export type EditCanvasType = {
|
||||
[EditCanvasTypeEnum.IS_CREATE]: boolean
|
||||
// 拖拽中
|
||||
[EditCanvasTypeEnum.IS_DRAG]: boolean
|
||||
// 保存状态
|
||||
[EditCanvasTypeEnum.SAVE_STATUS]: SyncEnum
|
||||
// 框选中
|
||||
[EditCanvasTypeEnum.IS_SELECT]: boolean
|
||||
// 代码编辑中
|
||||
[EditCanvasTypeEnum.IS_CODE_EDIT]: boolean
|
||||
}
|
||||
|
||||
// 滤镜/背景色/宽高主题等
|
||||
// 画布数据/滤镜/背景色/宽高主题等
|
||||
export enum EditCanvasConfigEnum {
|
||||
PROJECT_NAME = 'projectName',
|
||||
WIDTH = 'width',
|
||||
@@ -64,7 +91,14 @@ export enum EditCanvasConfigEnum {
|
||||
PREVIEW_SCALE_TYPE = 'previewScaleType'
|
||||
}
|
||||
|
||||
export interface EditCanvasConfigType {
|
||||
// 画布属性(需保存)
|
||||
export type EditCanvasConfigType = {
|
||||
// ID
|
||||
[EditCanvasConfigEnum.PROJECT_ID]: string,
|
||||
// 项目名称
|
||||
[EditCanvasConfigEnum.PROJECT_NAME]?: string,
|
||||
// 项目描述
|
||||
[EditCanvasConfigEnum.REMARKS]: string,
|
||||
// 滤镜-启用
|
||||
[FilterEnum.FILTERS_SHOW]: boolean
|
||||
// 滤镜-色相
|
||||
@@ -143,6 +177,7 @@ export type RecordChartType = {
|
||||
|
||||
// Store 枚举
|
||||
export enum ChartEditStoreEnum {
|
||||
PROJECT_INFO = 'projectInfo',
|
||||
EDIT_RANGE = 'editRange',
|
||||
EDIT_CANVAS = 'editCanvas',
|
||||
RIGHT_MENU_SHOW = 'rightMenuShow',
|
||||
@@ -204,6 +239,7 @@ export interface RequestConfigType extends RequestPublicConfigType {
|
||||
|
||||
// Store 类型
|
||||
export interface ChartEditStoreType {
|
||||
[ChartEditStoreEnum.PROJECT_INFO]: ProjectInfoType
|
||||
[ChartEditStoreEnum.EDIT_CANVAS]: EditCanvasType
|
||||
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
|
||||
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean
|
||||
|
||||
@@ -10,14 +10,22 @@ import { requestInterval, previewScaleType, requestIntervalUnit } from '@/settin
|
||||
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
|
||||
// 全局设置
|
||||
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
|
||||
// 历史类型
|
||||
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
// 画布枚举
|
||||
import { MenuEnum, SyncEnum } from '@/enums/editPageEnum'
|
||||
|
||||
import {
|
||||
HistoryActionTypeEnum,
|
||||
HistoryItemType,
|
||||
HistoryTargetTypeEnum
|
||||
} from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
|
||||
import { MenuEnum } from '@/enums/editPageEnum'
|
||||
import { getUUID, loadingStart, loadingFinish, loadingError, isString, isArray } from '@/utils'
|
||||
getUUID,
|
||||
loadingStart,
|
||||
loadingFinish,
|
||||
loadingError,
|
||||
isString,
|
||||
isArray
|
||||
} from '@/utils'
|
||||
|
||||
import {
|
||||
ProjectInfoType,
|
||||
ChartEditStoreEnum,
|
||||
ChartEditStorage,
|
||||
ChartEditStoreType,
|
||||
@@ -36,6 +44,14 @@ const settingStore = useSettingStore()
|
||||
export const useChartEditStore = defineStore({
|
||||
id: 'useChartEditStore',
|
||||
state: (): ChartEditStoreType => ({
|
||||
// 项目数据
|
||||
projectInfo: {
|
||||
projectId: '',
|
||||
projectName: '',
|
||||
remarks: '',
|
||||
thumbnail: '',
|
||||
release: false
|
||||
},
|
||||
// 画布属性
|
||||
editCanvas: {
|
||||
// 编辑区域 Dom
|
||||
@@ -55,6 +71,8 @@ export const useChartEditStore = defineStore({
|
||||
isDrag: false,
|
||||
// 框选中
|
||||
isSelect: false,
|
||||
// 同步中
|
||||
saveStatus: SyncEnum.PENDING,
|
||||
// 代码编辑中
|
||||
isCodeEdit: false
|
||||
},
|
||||
@@ -140,6 +158,9 @@ export const useChartEditStore = defineStore({
|
||||
componentList: []
|
||||
}),
|
||||
getters: {
|
||||
getProjectInfo(): ProjectInfoType {
|
||||
return this.projectInfo
|
||||
},
|
||||
getMousePosition(): MousePositionType {
|
||||
return this.mousePosition
|
||||
},
|
||||
@@ -203,6 +224,10 @@ export const useChartEditStore = defineStore({
|
||||
setEditCanvasConfig<T extends keyof EditCanvasConfigType, K extends EditCanvasConfigType[T]>(key: T, value: K) {
|
||||
this.editCanvasConfig[key] = value
|
||||
},
|
||||
// * 设置 peojectInfo 数据项
|
||||
setProjectInfo<T extends keyof ProjectInfoType, K extends ProjectInfoType[T]>(key: T, value: K) {
|
||||
this.projectInfo[key] = value
|
||||
},
|
||||
// * 设置右键菜单
|
||||
setRightMenuShow(value: boolean) {
|
||||
this.rightMenuShow = value
|
||||
|
||||
@@ -4,10 +4,10 @@ import { asideCollapsedWidth } from '@/settings/designSetting'
|
||||
import { SettingStoreType, ToolsStatusEnum } from './settingStore.d'
|
||||
import { setLocalStorage, getLocalStorage } from '@/utils'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
const { GO_SYSTEM_SETTING_STORE } = StorageEnum
|
||||
const { GO_SETTING_STORE } = StorageEnum
|
||||
|
||||
const storageSetting: SettingStoreType = getLocalStorage(
|
||||
GO_SYSTEM_SETTING_STORE
|
||||
GO_SETTING_STORE
|
||||
)
|
||||
|
||||
// 全局设置
|
||||
@@ -48,7 +48,7 @@ export const useSettingStore = defineStore({
|
||||
this.$patch(state => {
|
||||
state[key] = value
|
||||
})
|
||||
setLocalStorage(GO_SYSTEM_SETTING_STORE, this.$state)
|
||||
setLocalStorage(GO_SETTING_STORE, this.$state)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
31
src/store/modules/systemStore/systemStore.d.ts
vendored
Normal file
31
src/store/modules/systemStore/systemStore.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
export enum SystemStoreUserInfoEnum {
|
||||
USER_TOKEN = 'userToken',
|
||||
TOKEN_NAME = 'tokenName',
|
||||
USER_ID = 'userId',
|
||||
USER_NAME = 'userName',
|
||||
NICK_NAME = 'nickName',
|
||||
}
|
||||
|
||||
export interface UserInfoType {
|
||||
[SystemStoreUserInfoEnum.USER_TOKEN]?: string,
|
||||
[SystemStoreUserInfoEnum.TOKEN_NAME]?: string,
|
||||
[SystemStoreUserInfoEnum.USER_ID]?: string,
|
||||
[SystemStoreUserInfoEnum.USER_NAME]?: string,
|
||||
[SystemStoreUserInfoEnum.NICK_NAME]?: string,
|
||||
}
|
||||
|
||||
export interface FetchInfoType {
|
||||
OSSUrl?: string,
|
||||
}
|
||||
|
||||
export enum SystemStoreEnum {
|
||||
// 用户
|
||||
USER_INFO = 'userInfo',
|
||||
// 请求
|
||||
FETCH_INFO = 'fetchInfo'
|
||||
}
|
||||
|
||||
export interface SystemStoreType {
|
||||
[SystemStoreEnum.USER_INFO]: UserInfoType
|
||||
[SystemStoreEnum.FETCH_INFO]: FetchInfoType
|
||||
}
|
||||
40
src/store/modules/systemStore/systemStore.ts
Normal file
40
src/store/modules/systemStore/systemStore.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { SystemStoreType, UserInfoType, FetchInfoType } from './systemStore.d'
|
||||
import { setLocalStorage, getLocalStorage } from '@/utils'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
|
||||
const { GO_SYSTEM_STORE } = StorageEnum
|
||||
|
||||
const storageSystem: SystemStoreType = getLocalStorage(GO_SYSTEM_STORE)
|
||||
|
||||
// 系统数据记录
|
||||
export const useSystemStore = defineStore({
|
||||
id: 'useSystemStore',
|
||||
state: (): SystemStoreType => storageSystem || {
|
||||
userInfo: {
|
||||
userId: undefined,
|
||||
userName: undefined,
|
||||
userToken: undefined,
|
||||
nickName: undefined
|
||||
},
|
||||
fetchInfo: {
|
||||
OSSUrl: undefined
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getUserInfo(): UserInfoType {
|
||||
return this.userInfo
|
||||
},
|
||||
getFetchInfo(): FetchInfoType {
|
||||
return this.fetchInfo
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setItem<T extends keyof SystemStoreType, K extends SystemStoreType[T]>(key: T, value: K): void {
|
||||
this.$patch(state => {
|
||||
state[key] = value
|
||||
});
|
||||
setLocalStorage(GO_SYSTEM_STORE, this.$state)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,3 +1,65 @@
|
||||
/**
|
||||
* * base64转file
|
||||
* @param dataurl
|
||||
* @param fileName
|
||||
* @returns
|
||||
*/
|
||||
export const base64toFile = (dataurl: string, fileName: string) => {
|
||||
let dataArr = dataurl.split(","),
|
||||
mime = (dataArr as any[])[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(dataArr[1]),
|
||||
n = bstr.length,
|
||||
u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new File([u8arr], fileName, { type: mime });
|
||||
}
|
||||
|
||||
/**
|
||||
* * file转url
|
||||
*/
|
||||
export const fileToUrl = (file: File): string => {
|
||||
const Url = URL || window.URL || window.webkitURL
|
||||
const ImageUrl = Url.createObjectURL(file)
|
||||
return ImageUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* * url转file
|
||||
*/
|
||||
export const urlToFile = (fileUrl: string, fileName = `${new Date().getTime()}`): File => {
|
||||
const dataArr = fileUrl.split(',')
|
||||
const mime = (dataArr as any[])[0].match(/:(.*);/)[1]
|
||||
const originStr = atob(dataArr[1])
|
||||
return new File([originStr], `${fileName}`, { type: mime })
|
||||
}
|
||||
|
||||
/**
|
||||
* * file转base64
|
||||
* @param file 文件数据
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
export const fileTobase64 = (file: File, callback: Function) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (e: ProgressEvent<FileReader>) {
|
||||
if (e.target) {
|
||||
let base64 = e.target.result
|
||||
callback(base64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * canvas转file
|
||||
* @param canvas
|
||||
*/
|
||||
export const canvastoFile = (canvas: HTMLCanvasElement, name?: string) => {
|
||||
const dataurl = canvas.toDataURL('image/png')
|
||||
return urlToFile(dataurl, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* *获取上传的文件数据
|
||||
* @param { File } file 文件对象
|
||||
@@ -51,4 +113,4 @@ export const downloadTextFile = (
|
||||
// 字符内容转变成blob地址
|
||||
const blob = new Blob([content])
|
||||
downloadByA(URL.createObjectURL(blob), filename, fileSuffix)
|
||||
}
|
||||
}
|
||||
6
src/utils/http.ts
Normal file
6
src/utils/http.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* * 请求失败统一处理
|
||||
*/
|
||||
export const httpErrorHandle = () => {
|
||||
window['$message'].error(window['$t']('http.error_message'))
|
||||
}
|
||||
@@ -7,3 +7,4 @@ export * from '@/utils/plugin'
|
||||
export * from '@/utils/components'
|
||||
export * from '@/utils/type'
|
||||
export * from '@/utils/file'
|
||||
export * from '@/utils/http'
|
||||
@@ -35,7 +35,7 @@ export const loadingError = () => {
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export const goDialog = (
|
||||
export const goDialog = (
|
||||
params: {
|
||||
// 基本
|
||||
type?: DialogEnum
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ResultEnum } from '@/enums/httpEnum'
|
||||
import { ErrorPageNameMap, PageEnum } from '@/enums/pageEnum'
|
||||
import { ResultEnum, RequestHttpHeaderEnum } from '@/enums/httpEnum'
|
||||
import { ErrorPageNameMap, PageEnum, PreviewEnum } from '@/enums/pageEnum'
|
||||
import { docPath, giteeSourceCodePath } from '@/settings/pathConst'
|
||||
import { cryptoDecode } from './crypto'
|
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { clearLocalStorage, getLocalStorage } from './storage'
|
||||
import { clearLocalStorage, getLocalStorage, clearCookie } from './storage'
|
||||
import router from '@/router'
|
||||
import { logoutApi } from '@/api/path'
|
||||
|
||||
/**
|
||||
* * 根据名字跳转路由
|
||||
@@ -101,11 +102,20 @@ export const reloadRoutePage = () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* * 退出
|
||||
* * 退出登录
|
||||
*/
|
||||
export const logout = () => {
|
||||
clearLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
export const logout = async () => {
|
||||
try {
|
||||
const res = await logoutApi()
|
||||
if(res && res.code === ResultEnum.SUCCESS) {
|
||||
window['$message'].success(window['$t']('global.logout_success'))
|
||||
clearCookie(RequestHttpHeaderEnum.COOKIE)
|
||||
clearLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
}
|
||||
} catch (error) {
|
||||
window['$message'].success(window['$t']('global.logout_failure'))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +167,7 @@ export const fetchRouteParams = () => {
|
||||
* * 通过硬解析获取当前路由下的参数
|
||||
* @returns object
|
||||
*/
|
||||
export const fetchRouteParamsLocation = () => {
|
||||
export const fetchRouteParamsLocation = () => {
|
||||
try {
|
||||
// 防止添加query参数的时候,解析ID异常
|
||||
return document.location.hash.split('?')[0].split('/').pop() || ''
|
||||
@@ -176,19 +186,29 @@ export const goHome = () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断是否登录(现阶段是有 login 数据即可)
|
||||
* * 判断是否登录
|
||||
* @return boolean
|
||||
*/
|
||||
export const loginCheck = () => {
|
||||
try {
|
||||
const info = getLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
if (!info) return false
|
||||
const decodeInfo = cryptoDecode(info)
|
||||
if (decodeInfo) {
|
||||
if (info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_TOKEN]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 预览地址
|
||||
* @returns
|
||||
*/
|
||||
export const previewPath = (id?: string | number) => {
|
||||
const { origin, pathname } = document.location
|
||||
const path = fetchPathByName(PreviewEnum.CHART_PREVIEW_NAME, 'href')
|
||||
const previewPath = `${origin}${pathname}${path}/${id || fetchRouteParamsLocation()}`
|
||||
return previewPath
|
||||
}
|
||||
@@ -70,3 +70,41 @@ export const getSessionStorage: (k: string) => any = (k: string) => {
|
||||
export const clearSessioStorage = (name: string) => {
|
||||
window.sessionStorage.removeItem(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* * 设置 cookie
|
||||
* @param name 键名
|
||||
* @param cvalue 键值
|
||||
* @param exdays 过期时间
|
||||
*/
|
||||
export const setCookie = (name: string, cvalue: string, exdays: number) => {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
||||
const expires = "expires=" + d.toUTCString();
|
||||
document.cookie = name + "=" + cvalue + "; " + expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 获取 cookie
|
||||
* @param cname 键名
|
||||
* @returns string
|
||||
*/
|
||||
export const getCookie = (cname: string) => {
|
||||
const name = cname + "=";
|
||||
const ca = document.cookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') c = c.substring(1);
|
||||
if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* * 清除 cookie
|
||||
* @param name 键名
|
||||
* @returns string
|
||||
*/
|
||||
export const clearCookie = (name: string) => {
|
||||
setCookie(name, "", -1);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user