Compare commits

..

19 Commits

Author SHA1 Message Date
奔跑的面条
bdbdd37789 build: 升级版本到1.1.3 2022-10-15 17:17:34 +08:00
奔跑的面条
c8fb5b9152 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-15 17:12:13 +08:00
奔跑的面条
aef155e039 fix: 修复组件导入数据错乱的问题 2022-10-09 16:37:30 +08:00
奔跑的面条
443573455b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-09 09:28:38 +08:00
奔跑的面条
d811ab7dfa build: 撤回错误版本号 2022-10-08 21:12:58 +08:00
奔跑的面条
5f79ab6e6d build: 升级版本到1.1.2 2022-10-08 21:12:27 +08:00
奔跑的面条
502edbca5d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 21:05:48 +08:00
奔跑的面条
1a04267cb7 build: 升级版本到1.1.1 2022-10-08 20:59:55 +08:00
奔跑的面条
9c2c1bdfa1 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 20:59:25 +08:00
奔跑的面条
72e93f3768 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-27 20:16:07 +08:00
奔跑的面条
e6f2066d42 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-22 14:15:00 +08:00
奔跑的面条
2812c39524 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-21 19:54:29 +08:00
奔跑的面条
491485856e Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:46:37 +08:00
奔跑的面条
abde7e176d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:13:50 +08:00
奔跑的面条
bab8faadee add default pipeline template yaml 2022-09-19 11:58:32 +00:00
奔跑的面条
427d72fb8b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:48:28 +08:00
奔跑的面条
dc5b20a329 build: 升级版本到1.1.0 2022-09-18 16:33:26 +08:00
奔跑的面条
4cb934eef3 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:32:34 +08:00
奔跑的面条
35e8cea0b5 docs: 更新已完成图表说明 2022-09-17 23:00:51 +08:00
207 changed files with 6530 additions and 6190 deletions

12
.env
View File

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

View File

@@ -0,0 +1,51 @@
version: '1.0'
name: branch-pipeline
displayName: BranchPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@nodejs
name: build_nodejs
displayName: Nodejs 构建
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
nodeVersion: 14.16.0
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
commands:
- npm install && rm -rf ./dist && npm run build
# 非必填字段开启后表示将构建产物暂存但不会上传到制品库中7天后自动清除
artifacts:
# 构建产物名字作为产物的唯一标识可向下传递支持自定义默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
path:
- ./dist
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 上传到制品库时的制品命名默认output
artifactName: output
dependsOn: build_nodejs
- stage:
name: release
displayName: 发布
steps:
- step: publish@release_artifacts
name: publish_release_artifacts
displayName: '发布'
# 上游上传制品任务的产出
dependArtifact: output
# 发布制品版本号
version: '1.0.0.0'
# 是否开启版本号自增,默认开启
autoIncrement: true
triggers:
push:
branches:
exclude:
- master
include:
- .*

View File

@@ -0,0 +1,49 @@
version: '1.0'
name: master-pipeline
displayName: MasterPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@nodejs
name: build_nodejs
displayName: Nodejs 构建
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
nodeVersion: 14.16.0
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
commands:
- npm install && rm -rf ./dist && npm run build
# 非必填字段开启后表示将构建产物暂存但不会上传到制品库中7天后自动清除
artifacts:
# 构建产物名字作为产物的唯一标识可向下传递支持自定义默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
path:
- ./dist
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 上传到制品库时的制品命名默认output
artifactName: output
dependsOn: build_nodejs
- stage:
name: release
displayName: 发布
steps:
- step: publish@release_artifacts
name: publish_release_artifacts
displayName: '发布'
# 上游上传制品任务的产出
dependArtifact: output
# 发布制品版本号
version: '1.0.0.0'
# 是否开启版本号自增,默认开启
autoIncrement: true
triggers:
push:
branches:
include:
- master

36
.workflow/pr-pipeline.yml Normal file
View File

@@ -0,0 +1,36 @@
version: '1.0'
name: pr-pipeline
displayName: PRPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@nodejs
name: build_nodejs
displayName: Nodejs 构建
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
nodeVersion: 14.16.0
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
commands:
- npm install && rm -rf ./dist && npm run build
# 非必填字段开启后表示将构建产物暂存但不会上传到制品库中7天后自动清除
artifacts:
# 构建产物名字作为产物的唯一标识可向下传递支持自定义默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
path:
- ./dist
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 上传到制品库时的制品命名默认output
artifactName: output
dependsOn: build_nodejs
triggers:
pr:
branches:
include:
- master

203
README.md
View File

@@ -1,114 +1,147 @@
## 总览
**`master-fetch` 分支是带有后端接口请求的分支**
![logo](readme/logo-t-y.png)
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)**
### 😶 纯 **前端** 分支: **`master`**
## 使用
### 👻 携带 **后端** 请求分支: **`master-fetch`**
所有的接口地址位置:`src\api\path\*`
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
接口地址修改:`.env`
项目纯前端-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 全局方法、组件等
工作台:
![项目截图](readme/go-view-canvas.png)
请求配置:
![项目截图](readme/go-view-fetch.png)
数据过滤:
![项目截图](readme/go-view-filter.png)
主题色:
![项目截图](readme/go-view-color.png)
主要技术栈为:
| 名称 | 版本 | 名称 | 版本 |
| ------------------- | ----- | ----------- | ------ |
| Vue | 3.2.x | TypeScript4 | 4.6.x |
| Vite | 2.9.x | NaiveUI | 2.27.x |
| ECharts | 5.3.x | Pinia | 2.0.x |
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
开发环境:
| 名称 | 版本 | 名称 | 版本 |
| ---- | ------- | ------- | ----- |
| node | 16.14.x | npm | 8.5.x |
| pnpm | 7.1.x | windows | 11 |
已完成图表:
| 分类 | 名称 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------- | -------------- | ------------------------ |
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
| \* | 漏斗图 | 中国地图 | 🤪 | 🤖 |
| 信息 | 文字 | 渐变文字 | 图片 | 😶 |
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 | 👻 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
## 浏览器支持
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
## 安装
本项目采用` pnpm` 进行包管理
```shell
# port
VITE_DEV_PORT = '8080'
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
#pnpm
pnpm install
# development path
VITE_DEV_PATH = 'http://127.0.0.1:8080'
#yarn
yarn install
# production path
VITE_PRO_PATH = 'http://127.0.0.1:8080'
#npm
npm install
```
公共前缀修改:`src\settings\httpSetting.ts`
## 启动
```shell
// 请求前缀
export const axiosPre = '/api/goview'
#pnpm
pnpm dev
# npm
npm run dev
#yarn
yarn dev
#Makefile
make dev
```
接口封装:`src\api\http.ts`
## 编译
```ts
import axiosInstance from './axios'
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
```shell
#pnpm
pnpm run build
export const get = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.GET,
params: params,
})
}
# npm
npm 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
}
})
}
#yarn
yarn run build
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
}
}
#Makefile
make dist
```
## 代码提交
* 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: 不属于以上类型的其他类型(日常事务)
## 交流

View File

@@ -1,4 +1,3 @@
import path from 'path'
export const OUTPUT_DIR = 'dist'
// monaco-editor 路径
@@ -7,7 +6,7 @@ export const prefix = `monaco-editor/esm/vs`
// chunk 警告大小
export const chunkSizeWarningLimit = 2000
// 禁用 brotliSize 压缩大小报告
// 禁用 brotli 压缩大小报告
export const brotliSize = false
// 分包
@@ -15,12 +14,7 @@ export const rollupOptions = {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: (chunkInfo) => {
if(['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) {
return `static/[ext]/[name].[ext]`
}
return `static/[ext]/[name]-[hash].[ext]`
},
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
manualChunks: {
jsonWorker: [`${prefix}/language/json/json.worker`],
cssWorker: [`${prefix}/language/css/css.worker`],

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "go-view",
"version": "2.1.3",
"version": "1.1.3",
"scripts": {
"dev": "vite --host",
"build": "vue-tsc --noEmit && vite build",
@@ -11,8 +11,6 @@
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx,.vue src --fix"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@amap/amap-jsapi-types": "^0.0.8",
"@types/color": "^3.0.3",
"@types/crypto-js": "^4.1.1",
"@types/keymaster": "^1.6.30",
@@ -35,7 +33,7 @@
"three": "^0.145.0",
"vue": "^3.2.31",
"vue-demi": "^0.13.1",
"vue-i18n": "9.1.10",
"vue-i18n": "9.1.9",
"vue-router": "4.0.12",
"vue3-lazyload": "^0.2.5-beta",
"vue3-sketch-ruler": "^1.3.3",

90
pnpm-lock.yaml generated
View File

@@ -1,8 +1,6 @@
lockfileVersion: 5.4
specifiers:
'@amap/amap-jsapi-loader': ^1.0.1
'@amap/amap-jsapi-types': ^0.0.8
'@commitlint/cli': ^17.0.2
'@commitlint/config-conventional': ^17.0.2
'@types/color': ^3.0.3
@@ -59,7 +57,7 @@ specifiers:
vue: ^3.2.31
vue-demi: ^0.13.1
vue-echarts: ^6.0.2
vue-i18n: 9.1.10
vue-i18n: 9.1.9
vue-router: 4.0.12
vue-tsc: ^0.28.10
vue3-lazyload: ^0.2.5-beta
@@ -67,8 +65,6 @@ specifiers:
vuedraggable: ^4.1.0
dependencies:
'@amap/amap-jsapi-loader': 1.0.1
'@amap/amap-jsapi-types': 0.0.8
'@types/color': 3.0.3
'@types/crypto-js': 4.1.1
'@types/keymaster': 1.6.30
@@ -91,7 +87,7 @@ dependencies:
three: 0.145.0
vue: 3.2.37
vue-demi: 0.13.1_vue@3.2.37
vue-i18n: 9.1.10_vue@3.2.37
vue-i18n: 9.1.9_vue@3.2.37
vue-router: 4.0.12_vue@3.2.37
vue3-lazyload: 0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae
vue3-sketch-ruler: 1.3.4_vue@3.2.37
@@ -136,14 +132,6 @@ devDependencies:
packages:
/@amap/amap-jsapi-loader/1.0.1:
resolution: {integrity: sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==}
dev: false
/@amap/amap-jsapi-types/0.0.8:
resolution: {integrity: sha512-q0FyZDIJcXjsMLGc3oS9rjfJsErOvt9rcp6AgzY4k14vo7bBhdq4eKwoSdVp/pYjR/rfaKBns5v10ycZOFwf/A==}
dev: false
/@ampproject/remapping/2.2.0:
resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==}
engines: {node: '>=6.0.0'}
@@ -671,60 +659,60 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true
/@intlify/core-base/9.1.10:
resolution: {integrity: sha512-So9CNUavB/IsZ+zBmk2Cv6McQp6vc2wbGi1S0XQmJ8Vz+UFcNn9MFXAe9gY67PreIHrbLsLxDD0cwo1qsxM1Nw==}
/@intlify/core-base/9.1.9:
resolution: {integrity: sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==}
engines: {node: '>= 10'}
dependencies:
'@intlify/devtools-if': 9.1.10
'@intlify/message-compiler': 9.1.10
'@intlify/message-resolver': 9.1.10
'@intlify/runtime': 9.1.10
'@intlify/shared': 9.1.10
'@intlify/vue-devtools': 9.1.10
'@intlify/devtools-if': 9.1.9
'@intlify/message-compiler': 9.1.9
'@intlify/message-resolver': 9.1.9
'@intlify/runtime': 9.1.9
'@intlify/shared': 9.1.9
'@intlify/vue-devtools': 9.1.9
dev: false
/@intlify/devtools-if/9.1.10:
resolution: {integrity: sha512-SHaKoYu6sog3+Q8js1y3oXLywuogbH1sKuc7NSYkN3GElvXSBaMoCzW+we0ZSFqj/6c7vTNLg9nQ6rxhKqYwnQ==}
/@intlify/devtools-if/9.1.9:
resolution: {integrity: sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==}
engines: {node: '>= 10'}
dependencies:
'@intlify/shared': 9.1.10
'@intlify/shared': 9.1.9
dev: false
/@intlify/message-compiler/9.1.10:
resolution: {integrity: sha512-+JiJpXff/XTb0EadYwdxOyRTB0hXNd4n1HaJ/a4yuV960uRmPXaklJsedW0LNdcptd/hYUZtCkI7Lc9J5C1gxg==}
/@intlify/message-compiler/9.1.9:
resolution: {integrity: sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==}
engines: {node: '>= 10'}
dependencies:
'@intlify/message-resolver': 9.1.10
'@intlify/shared': 9.1.10
'@intlify/message-resolver': 9.1.9
'@intlify/shared': 9.1.9
source-map: 0.6.1
dev: false
/@intlify/message-resolver/9.1.10:
resolution: {integrity: sha512-5YixMG/M05m0cn9+gOzd4EZQTFRUu8RGhzxJbR1DWN21x/Z3bJ8QpDYj6hC4FwBj5uKsRfKpJQ3Xqg98KWoA+w==}
/@intlify/message-resolver/9.1.9:
resolution: {integrity: sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==}
engines: {node: '>= 10'}
dev: false
/@intlify/runtime/9.1.10:
resolution: {integrity: sha512-7QsuByNzpe3Gfmhwq6hzgXcMPpxz8Zxb/XFI6s9lQdPLPe5Lgw4U1ovRPZTOs6Y2hwitR3j/HD8BJNGWpJnOFA==}
/@intlify/runtime/9.1.9:
resolution: {integrity: sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==}
engines: {node: '>= 10'}
dependencies:
'@intlify/message-compiler': 9.1.10
'@intlify/message-resolver': 9.1.10
'@intlify/shared': 9.1.10
'@intlify/message-compiler': 9.1.9
'@intlify/message-resolver': 9.1.9
'@intlify/shared': 9.1.9
dev: false
/@intlify/shared/9.1.10:
resolution: {integrity: sha512-Om54xJeo1Vw+K1+wHYyXngE8cAbrxZHpWjYzMR9wCkqbhGtRV5VLhVc214Ze2YatPrWlS2WSMOWXR8JktX/IgA==}
/@intlify/shared/9.1.9:
resolution: {integrity: sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==}
engines: {node: '>= 10'}
dev: false
/@intlify/vue-devtools/9.1.10:
resolution: {integrity: sha512-5l3qYARVbkWAkagLu1XbDUWRJSL8br1Dj60wgMaKB0+HswVsrR6LloYZTg7ozyvM621V6+zsmwzbQxbVQyrytQ==}
/@intlify/vue-devtools/9.1.9:
resolution: {integrity: sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==}
engines: {node: '>= 10'}
dependencies:
'@intlify/message-resolver': 9.1.10
'@intlify/runtime': 9.1.10
'@intlify/shared': 9.1.10
'@intlify/message-resolver': 9.1.9
'@intlify/runtime': 9.1.9
'@intlify/shared': 9.1.9
dev: false
/@jridgewell/gen-mapping/0.1.1:
@@ -3074,7 +3062,7 @@ packages:
source-map: 0.6.1
wordwrap: 1.0.0
optionalDependencies:
uglify-js: 3.17.4
uglify-js: 3.16.0
dev: true
/hard-rejection/2.1.0:
@@ -5014,8 +5002,8 @@ packages:
hasBin: true
dev: true
/uglify-js/3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
/uglify-js/3.16.0:
resolution: {integrity: sha512-FEikl6bR30n0T3amyBh3LoiBdqHRy/f4H80+My34HOesOKyHfOsxAPAxOoqC0JUnC1amnO0IwkYC3sko51caSw==}
engines: {node: '>=0.8.0'}
hasBin: true
requiresBuild: true
@@ -5385,15 +5373,15 @@ packages:
- supports-color
dev: true
/vue-i18n/9.1.10_vue@3.2.37:
resolution: {integrity: sha512-jpr7gV5KPk4n+sSPdpZT8Qx3XzTcNDWffRlHV/cT2NUyEf+sEgTTmLvnBAibjOFJ0zsUyZlVTAWH5DDnYep+1g==}
/vue-i18n/9.1.9_vue@3.2.37:
resolution: {integrity: sha512-JeRdNVxS2OGp1E+pye5XB6+M6BBkHwAv9C80Q7+kzoMdUDGRna06tjC0vCB/jDX9aWrl5swxOMFcyAr7or8XTA==}
engines: {node: '>= 10'}
peerDependencies:
vue: ^3.0.0
dependencies:
'@intlify/core-base': 9.1.10
'@intlify/shared': 9.1.10
'@intlify/vue-devtools': 9.1.10
'@intlify/core-base': 9.1.9
'@intlify/shared': 9.1.9
'@intlify/vue-devtools': 9.1.9
'@vue/devtools-api': 6.1.4
vue: 3.2.37
dev: false

View File

@@ -1,9 +1,9 @@
<template>
<n-config-provider
:locale="zhCN"
:theme="darkTheme"
:hljs="hljsTheme"
:locale="locale"
:date-locale="dateLocale"
:date-locale="dateZhCN"
:theme-overrides="overridesTheme"
>
<go-app-provider>
@@ -14,10 +14,11 @@
</template>
<script lang="ts" setup>
import { NConfigProvider } from 'naive-ui'
import { zhCN, dateZhCN, NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
import { useDarkThemeHook, useThemeOverridesHook, useCode } from '@/hooks'
// 暗黑主题
const darkTheme = useDarkThemeHook()
@@ -27,11 +28,4 @@ const overridesTheme = useThemeOverridesHook()
// 代码主题
const hljsTheme = useCode()
// 系统全局数据初始化
useSystemInit()
// 全局语言
const { locale, dateLocale } = useLang()
</script>

View File

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

View File

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

View File

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

View File

@@ -15,7 +15,6 @@ export const radarUrl = '/mock/radarData'
export const heatMapUrl = '/mock/heatMapData'
export const scatterBasicUrl = '/mock/scatterBasic'
export const mapUrl = '/mock/map'
export const capsuleUrl = '/mock/capsule'
export const wordCloudUrl = '/mock/wordCloud'
export const treemapUrl = '/mock/treemap'
export const threeEarth01Url = '/mock/threeEarth01Data'
@@ -83,11 +82,6 @@ const mockObject: MockMethod[] = [
method: RequestHttpEnum.GET,
response: () => test.fetchMap
},
{
url: capsuleUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchCapsule
},
{
url: wordCloudUrl,
method: RequestHttpEnum.GET,

View File

@@ -1,9 +1,79 @@
{
"markers|50": [
"point": [
{
"name": "某某地市",
"value": "@integer(2, 20)",
"position": ["@float(115, 117, 1, 6)", "@float(38, 40, 1, 6)"]
"name": "北京",
"value": [116.405285, 39.904989, 200]
},
{
"name": "郑州",
"value": [113.665412, 34.757975, 888]
},
{
"name": "青海",
"value": [101.778916, 36.623178, 666]
},
{
"name": "宁夏回族自治区",
"value": [106.278179, 38.46637, 66]
},
{
"name": "哈尔滨市",
"value": [126.642464, 45.756967, 101]
}
],
"map": [
{
"name": "北京市",
"value": "@integer(0, 1000)"
},
{
"name": "河北省",
"value": "@integer(0, 1000)"
},
{
"name": "江苏省",
"value": "@integer(0, 1000)"
},
{
"name": "福建省",
"value": "@integer(0, 1000)"
},
{
"name": "山东省",
"value": "@integer(0, 1000)"
},
{
"name": "河南省",
"value": "@integer(0, 1000)"
},
{
"name": "湖北省",
"value": "@integer(0, 1000)"
},
{
"name": "广西壮族自治区",
"value": "@integer(0, 1000)"
},
{
"name": "海南省",
"value": "@integer(0, 1000)"
},
{
"name": "青海省",
"value": "@integer(0, 1000)"
},
{
"name": "新疆维吾尔自治区",
"value": "@integer(0, 1000)"
}
],
"pieces": [
{ "gte": 1000, "label": ">1000" },
{ "gte": 600, "lte": 999, "label": "600-999" },
{ "gte": 200, "lte": 599, "label": "200-599" },
{ "gte": 50, "lte": 199, "label": "49-199" },
{ "gte": 10, "lte": 49, "label": "10-49" },
{ "lte": 9, "label": "<9" }
]
}

View File

@@ -11,7 +11,27 @@ export default {
msg: '请求成功',
data: {
dimensions: ['product', 'dataOne'],
'source|50': [
source: [
{
product: '@name',
'dataOne|0-900': 3
},
{
product: '@name',
'dataOne|0-900': 3
},
{
product: '@name',
'dataOne|0-900': 3
},
{
product: '@name',
'dataOne|0-900': 3
},
{
product: '@name',
'dataOne|0-900': 3
},
{
product: '@name',
'dataOne|0-900': 3
@@ -19,22 +39,6 @@ export default {
]
}
},
// 胶囊图
fetchCapsule: {
code: 0,
status: 200,
msg: '请求成功',
data: {
dimensions: ['name', 'value'],
source: [
{ name: '厦门', 'value|0-40': 20 },
{ name: '南阳', 'value|20-60': 40 },
{ name: '北京', 'value|40-80': 60 },
{ name: '上海', 'value|60-100': 80 },
{ name: '新疆', value: 100 }
]
}
},
// 图表
fetchMockData: {
code: 0,
@@ -42,7 +46,32 @@ export default {
msg: '请求成功',
data: {
dimensions: ['product', 'dataOne', 'dataTwo'],
'source|50': [
source: [
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3
},
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3
},
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3
},
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3
},
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3
},
{
product: '@name',
'dataOne|100-900': 3,
@@ -56,7 +85,21 @@ export default {
code: 0,
status: 200,
msg: '请求成功',
'data|50': [{ name: '@name', 'value|100-900': 5 }]
data: [
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 },
{ name: '@name', 'value|100-900': 5 }
]
},
// 轮播表格
fetchScrollBoard: {
@@ -219,7 +262,12 @@ export default {
data: [
{
startArray: { name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' },
'endArray|10': [{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }]
endArray: [
{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' },
{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' },
{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' },
{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }
]
}
]
}

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -1,5 +1,4 @@
import Flipper from './index.vue'
type FlipType = 'up' | 'down'
export { Flipper, FlipType }

View File

@@ -1,13 +1,19 @@
<template>
<div class="go-Flipper" :class="[flipType, { go: isFlipping }]">
<div class="M-Flipper" :class="[flipType, { go: isFlipping }]">
<div class="digital front" :data-front="frontTextFromData"></div>
<div class="digital back" :data-back="backTextFromData"></div>
</div>
</template>
<script lang="ts">
export default {
name: 'Flipper'
}
</script>
<script lang="ts" setup>
import { ref, PropType, watch } from 'vue'
import { FlipType } from './index'
import { FlipType } from '.'
const props = defineProps({
flipType: {
@@ -125,7 +131,7 @@ $lineColor: #4a9ef8;
}
// #endregion
.go-Flipper {
.M-Flipper {
display: inline-block;
position: relative;
width: $width;

View File

@@ -11,7 +11,7 @@
</template>
<n-list-item>
<n-space class="go-my-2" :size="20">
<n-space :size="20">
<n-text class="item-left">版权声明</n-text>
<n-text>
GoView 版权属于
@@ -21,7 +21,8 @@
</n-list-item>
<n-list-item>
<n-space class="go-my-2" :size="20">
<n-divider style="margin-top: 0" />
<n-space :size="20">
<n-text class="item-left">协议备注</n-text>
<n-text>
请遵守开源 MIT 协议以上声明 <n-text type="error">不可删除</n-text>否则视作侵权行为后果自负
@@ -30,7 +31,8 @@
</n-list-item>
<n-list-item>
<n-space class="go-mt-2" :size="20">
<n-divider style="margin-top: 0" />
<n-space :size="20">
<n-text class="item-left">商业授权</n-text>
<n-text>
若不想保留版权声明请通过仓库/交流群 联系项目作者进行授权
@@ -42,19 +44,13 @@
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { icon } from '@/plugins'
const props = defineProps({
modelShow: Boolean
})
const emit = defineEmits(['update:modelShow'])
const { HelpOutlineIcon, CloseIcon } = icon.ionicons5
const modelShow = ref(false)
const emit = defineEmits(['update:modelShow'])
watch(() => props.modelShow, (newValue) => {
modelShow.value = newValue
defineProps({
modelShow: Boolean
})
const closeHandle = () => {

View File

@@ -69,20 +69,21 @@
</template>
<script script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { reactive } from 'vue'
import { ListType } from './index.d'
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
import { SettingStoreEnums, ToolsStatusEnum } from '@/store/modules/settingStore/settingStore.d'
import { icon } from '@/plugins'
const props = defineProps({
const { HelpOutlineIcon, CloseIcon } = icon.ionicons5
const emit = defineEmits(['update:modelShow'])
defineProps({
modelShow: Boolean
})
const emit = defineEmits(['update:modelShow'])
const { HelpOutlineIcon, CloseIcon } = icon.ionicons5
const settingStore = useSettingStore()
const modelShow = ref(false)
const list = reactive<ListType[]>([
{
@@ -167,10 +168,6 @@ const list = reactive<ListType[]>([
}
])
watch(() => props.modelShow, (newValue) => {
modelShow.value = newValue
})
const closeHandle = () => {
emit('update:modelShow', false)
}

View File

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

View File

@@ -99,7 +99,6 @@ const colorSelectHandle = (color: AppThemeColorType) => {
overflow: hidden;
border-radius: 5px;
@extend .go-background-filter-shallow;
backdrop-filter: none;
}
&-color {
width: 8px;

View File

@@ -9,12 +9,6 @@ export enum DragKeyEnum {
DRAG_KEY = 'ChartData'
}
// 不同页面保存操作
export enum SavePageEnum {
CHART = 'SaveChart',
JSON = 'SaveJSON'
}
// 操作枚举
export enum MenuEnum {
// 移动
@@ -46,9 +40,8 @@ export enum MenuEnum {
UN_GROUP = 'unGroup',
// 后退
BACK = 'back',
// 前进
FORWORD = 'forward',
// 保存
SAVE = 'save',
// 锁定
LOCK = 'lock',
// 解除锁定
@@ -79,15 +72,3 @@ export enum MacKeyboard {
SHIFT_SOURCE_KEY = '⇧',
ALT_SOURCE_KEY = '⌥'
}
// 同步状态枚举
export enum SyncEnum {
// 等待
PENDING,
// 开始
START,
// 成功
SUCCESS,
// 失败
FAILURE
}

View File

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

View File

@@ -12,12 +12,6 @@ export enum PreviewEnum {
CHART_PREVIEW_NAME = 'ChartPreview',
}
export enum EditEnum {
// 图表JSON编辑
CHART_EDIT = '/chart/edit/:id(.*)*',
CHART_EDIT_NAME = 'ChartEdit',
}
export enum PageEnum {
// 登录
BASE_LOGIN = '/login',
@@ -26,15 +20,10 @@ export enum PageEnum {
//重定向
REDIRECT = '/redirect',
REDIRECT_NAME = 'Redirect',
// 未发布
REDIRECT_UN_PUBLISH = '/redirect/unPublish',
REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
// 重载
RELOAD = '/reload',
RELOAD_NAME = 'Reload',
// 首页
BASE_HOME = '/project',
BASE_HOME_NAME = 'Project',

View File

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

View File

@@ -1,8 +1,4 @@
export * from '@/hooks/useTheme.hook'
export * from '@/hooks/usePreviewScale.hook'
export * from '@/hooks/useCode.hook'
export * from '@/hooks/useChartDataFetch.hook'
export * from '@/hooks/useSystemInit.hook'
export * from '@/hooks/useChartDataPondFetch.hook'
export * from '@/hooks/useLifeHandler.hook'
export * from '@/hooks/useLang.hook'
export * from '@/hooks/useChartDataFetch.hook'

View File

@@ -1,7 +1,6 @@
import { ref, toRefs, toRaw } from 'vue'
import type VChart from 'vue-echarts'
import { customizeHttp } from '@/api/http'
import { useChartDataPondFetch } from '@/hooks/'
import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestDataTypeEnum } from '@/enums/httpEnum'
@@ -24,21 +23,6 @@ export const useChartDataFetch = (
const vChartRef = ref<typeof VChart | null>(null)
let fetchInterval: any = 0
// 数据池
const { addGlobalDataInterface } = useChartDataPondFetch()
// 组件类型
const { chartFrame } = targetComponent.chartConfig
// eCharts 组件配合 vChart 库更新方式
const echartsUpdateHandle = (dataset: any) => {
if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) {
vChartRef.value.setOption({ dataset: dataset })
}
}
}
const requestIntervalFn = () => {
const chartEditStore = useChartEditStore()
@@ -57,6 +41,9 @@ export const useChartDataFetch = (
requestInterval: targetInterval
} = toRefs(targetComponent.request)
// 组件类型
const { chartFrame } = targetComponent.chartConfig
// 非请求类型
if (requestDataType.value !== RequestDataTypeEnum.AJAX) return
@@ -71,11 +58,16 @@ export const useChartDataFetch = (
clearInterval(fetchInterval)
const fetchFn = async () => {
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig))
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.requestGlobalConfig))
if (res) {
try {
const filter = targetComponent.filter
echartsUpdateHandle(newFunctionHandle(res?.data, res, filter))
// eCharts 组件配合 vChart 库更新方式
if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) {
vChartRef.value.setOption({ dataset: newFunctionHandle(res?.data, res, filter) })
}
}
// 更新回调函数
if (updateCallback) {
updateCallback(newFunctionHandle(res?.data, res, filter))
@@ -88,6 +80,7 @@ export const useChartDataFetch = (
// 立即调用
fetchFn()
// 定时时间
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
// 单位
@@ -101,11 +94,6 @@ export const useChartDataFetch = (
}
}
if (isPreview()) {
// 判断是否是数据池类型
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
: requestIntervalFn()
}
isPreview() && requestIntervalFn()
return { vChartRef }
}

View File

@@ -1,115 +0,0 @@
import { toRaw } from 'vue'
import { customizeHttp } from '@/api/http'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestGlobalConfigType, RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { newFunctionHandle, intervalUnitHandle } from '@/utils'
// 获取类型
type ChartEditStoreType = typeof useChartEditStore
// 数据池存储的数据类型
type DataPondMapType = {
updateCallback: (...args: any) => any
filter?: string | undefined
}
// 数据池 Map 中请求对应 callback
const mittDataPondMap = new Map<string, DataPondMapType[]>()
// 创建单个数据项轮询接口
const newPondItemInterval = (
requestGlobalConfig: RequestGlobalConfigType,
requestDataPondItem: RequestDataPondItemType,
dataPondMapItem?: DataPondMapType[]
) => {
if (!dataPondMapItem) return
let fetchInterval: any = 0
clearInterval(fetchInterval)
// 请求
const fetchFn = async () => {
try {
const res = await customizeHttp(toRaw(requestDataPondItem.dataPondRequestConfig), toRaw(requestGlobalConfig))
if (res) {
try {
// 遍历更新回调函数
dataPondMapItem.forEach(item => {
item.updateCallback(newFunctionHandle(res?.data, res, item.filter))
})
} catch (error) {
console.error(error)
return error
}
}
} catch (error) {
return error
}
}
// 立即调用
fetchFn()
const targetInterval = requestDataPondItem.dataPondRequestConfig.requestInterval
const targetUnit = requestDataPondItem.dataPondRequestConfig.requestIntervalUnit
const globalRequestInterval = requestGlobalConfig.requestInterval
const globalUnit = requestGlobalConfig.requestIntervalUnit
// 定时时间
const time = targetInterval ? targetInterval : globalRequestInterval
// 单位
const unit = targetInterval ? targetUnit : globalUnit
// 开启轮询
if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
}
/**
* 数据池接口处理
*/
export const useChartDataPondFetch = () => {
// 新增全局接口
const addGlobalDataInterface = (
targetComponent: CreateComponentType,
useChartEditStore: ChartEditStoreType,
updateCallback: (...args: any) => any
) => {
const chartEditStore = useChartEditStore()
const { requestDataPond } = chartEditStore.getRequestGlobalConfig
// 组件对应的数据池 Id
const requestDataPondId = targetComponent.request.requestDataPondId as string
// 新增数据项
const mittPondIdArr = mittDataPondMap.get(requestDataPondId) || []
mittPondIdArr.push({
updateCallback: updateCallback,
filter: targetComponent.filter
})
mittDataPondMap.set(requestDataPondId, mittPondIdArr)
}
// 清除旧数据
const clearMittDataPondMap = () => {
mittDataPondMap.clear()
}
// 初始化数据池
const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => {
const { requestDataPond } = requestGlobalConfig
// 根据 mapId 查找对应的数据池配置
for (let pondKey of mittDataPondMap.keys()) {
const requestDataPondItem = requestDataPond.find(item => item.dataPondId === pondKey)
if (requestDataPondItem) {
newPondItemInterval(requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
}
}
}
return {
addGlobalDataInterface,
clearMittDataPondMap,
initDataPond
}
}

View File

@@ -1,24 +0,0 @@
import { computed } from 'vue'
import { LangEnum } from '@/enums/styleEnum'
import { useLangStore } from '@/store/modules/langStore/langStore'
import { zhCN, enUS, dateEnUS, dateZhCN } from 'naive-ui'
type LangStoreType = typeof useLangStore
// 语言切换
export const useLang = () => {
const lang = useLangStore()
const locale = computed(() => {
return lang.getLang === LangEnum.ZH ? zhCN : enUS
})
const dateLocale = computed(() => {
return lang.getLang === LangEnum.ZH ? dateZhCN : dateEnUS
})
return {
locale,
dateLocale
}
}

View File

@@ -1,78 +0,0 @@
import { CreateComponentType, CreateComponentGroupType, EventLife, BaseEvent } from '@/packages/index.d'
import * as echarts from 'echarts'
// 所有图表组件集合对象
const components: { [K in string]?: any } = {}
// 项目提供的npm 包变量
export const npmPkgs = { echarts }
// 组件事件处理 hook
export const useLifeHandler = (chartConfig: CreateComponentType | CreateComponentGroupType) => {
if (!chartConfig.events) return {}
// 处理基础事件
const baseEvent: { [key: string]: any } = {}
for (const key in chartConfig.events.baseEvent) {
const fnStr: string | undefined = (chartConfig.events.baseEvent as any)[key]
// 动态绑定基础事件
if (fnStr) {
baseEvent[key] = generateBaseFunc(fnStr)
}
}
// 生成生命周期事件
const events = chartConfig.events.advancedEvents || {}
const lifeEvents = {
[EventLife.VNODE_BEFORE_MOUNT](e: any) {
// 存储组件
components[chartConfig.id] = e.component
const fnStr = (events[EventLife.VNODE_BEFORE_MOUNT] || '').trim()
generateFunc(fnStr, e)
},
[EventLife.VNODE_MOUNTED](e: any) {
const fnStr = (events[EventLife.VNODE_MOUNTED] || '').trim()
generateFunc(fnStr, e)
}
}
return { ...baseEvent, ...lifeEvents }
}
/**
* 生成基础函数
* @param fnStr 用户方法体代码
* @param event 鼠标事件
*/
export function generateBaseFunc(fnStr: string) {
try {
return new Function(`
return (
async function(mouseEvent){
${fnStr}
}
)`)()
} catch (error) {
console.error(error)
}
}
/**
* 生成高级函数
* @param fnStr 用户方法体代码
* @param e 执行生命周期的动态组件实例
*/
function generateFunc(fnStr: string, e: any) {
try {
// npmPkgs 便于拷贝 echarts 示例时设置option 的formatter等相关内容
Function(`
"use strict";
return (
async function(e, components, node_modules){
const {${Object.keys(npmPkgs).join()}} = node_modules;
${fnStr}
}
)`)().bind(e?.component)(e, components, npmPkgs)
} catch (error) {
console.error(error)
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,2 @@
export * from './axis'
export * from './line'
export * from './label'
export * from './line'

View File

@@ -1,7 +0,0 @@
export const labelConfig = {
position: [
{ label: '外侧', value: 'outside' },
{ label: '内部', value: 'inside' },
{ label: '中心', value: 'center' }
]
}

View File

@@ -3,6 +3,12 @@
<global-setting :optionData="optionData"></global-setting>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index + 1}`" :expanded="true">
<SettingItemBox name="图形">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker>
</SettingItem>
<SettingItem>
<n-button size="small" @click="item.itemStyle.color = null"> 恢复默认 </n-button>
</SettingItem>
<SettingItem name="宽度">
<n-input-number
v-model:value="item.barWidth"

View File

@@ -3,6 +3,12 @@
<global-setting :optionData="optionData"></global-setting>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index+1}`" :expanded="true">
<SettingItemBox name="图形">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker>
</SettingItem>
<SettingItem>
<n-button size="small" @click="item.itemStyle.color = null">恢复默认</n-button>
</SettingItem>
<SettingItem name="宽度">
<n-input-number
v-model:value="item.barWidth"

View File

@@ -1,25 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CapsuleChartConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const option = {
dataset: dataJson,
colors: ['#c4ebad', '#6be6c1', '#a0a7e6', '#96dee8', '#3fb1e3' ],
unit: '',
itemHeight: 10,
valueFontSize: 16,
paddingRight: 50,
paddingLeft: 50,
showValue: true
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = CapsuleChartConfig.key
public attr = { ...chartInitConfig, zIndex: -1 }
public chartConfig = cloneDeep(CapsuleChartConfig)
public option = cloneDeep(option)
}

View File

@@ -1,53 +0,0 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"> </global-setting>
<!-- 胶囊柱图 -->
<collapse-item name="胶囊柱图" expanded>
<SettingItemBox name="布局">
<setting-item name="左侧边距">
<n-input-number v-model:value="optionData.paddingLeft" :min="10" :step="1" size="small"></n-input-number>
</setting-item>
<setting-item name="右侧边距">
<n-input-number v-model:value="optionData.paddingRight" :min="10" :step="1" size="small"></n-input-number>
</setting-item>
<setting-item name="每块高度(px)">
<n-input-number v-model:value="optionData.itemHeight" :min="0" :step="1" size="small"></n-input-number>
</setting-item>
</SettingItemBox>
<SettingItemBox name="文本">
<setting-item name="所有文字大小">
<n-input-number v-model:value="optionData.valueFontSize" :min="0" :step="1" size="small"></n-input-number>
</setting-item>
<setting-item name="单位">
<n-input v-model:value="optionData.unit" size="small"></n-input>
</setting-item>
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.showValue" size="small"></n-switch>
<n-text>显示数值</n-text>
</n-space>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="颜色">
<setting-item v-for="(item, index) in optionData.colors" :key="index" :name="`颜色${index}`">
<n-color-picker v-model:value="optionData.colors[index]" size="small" :modes="['hex']"></n-color-picker>
</setting-item>
</SettingItemBox>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option & GlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -1,10 +0,0 @@
{
"dimensions": ["name", "value"],
"source": [
{ "name": "厦门", "value": 20 },
{ "name": "南阳", "value": 40 },
{ "name": "北京", "value": 60 },
{ "name": "上海", "value": 80 },
{ "name": "新疆", "value": 100 }
]
}

View File

@@ -1,15 +0,0 @@
import image from '@/assets/images/chart/charts/capsule.png'
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const CapsuleChartConfig: ConfigType = {
key: 'CapsuleChart',
chartKey: 'VCapsuleChart',
conKey: 'VCCapsuleChart',
title: '胶囊柱图',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.COMMON,
image
}

View File

@@ -1,226 +0,0 @@
<template>
<div
v-if="state.mergedConfig"
class="go-dv-capsule-chart"
:style="{
fontSize: numberSizeHandle(state.mergedConfig.valueFontSize),
paddingLeft: numberSizeHandle(state.mergedConfig.paddingLeft),
paddingRight: numberSizeHandle(state.mergedConfig.paddingRight)
}"
>
<div class="label-column">
<div
v-for="item in state.mergedConfig.dataset.source"
:key="item[state.mergedConfig.dataset.dimensions[0]]"
:style="{ height: state.capsuleItemHeight, lineHeight: state.capsuleItemHeight }"
>
{{ item[state.mergedConfig.dataset.dimensions[0]] }}
</div>
<div class="laset">&nbsp;</div>
</div>
<div class="capsule-container">
<div
v-for="(capsule, index) in state.capsuleLength"
:key="index"
class="capsule-item"
:style="{ height: state.capsuleItemHeight }"
>
<div
class="capsule-item-column"
:style="`width: ${capsule * 100}%; background-color: ${
state.mergedConfig.colors[index % state.mergedConfig.colors.length]
};height:calc(100% - ${2}px);`"
>
<div v-if="state.mergedConfig.showValue" class="capsule-item-value">
{{ state.capsuleValue[index] }}
</div>
</div>
</div>
<div class="unit-label">
<div v-for="(label, index) in state.labelData" :key="label + index">
{{ label }}
</div>
</div>
</div>
<div v-if="state.mergedConfig.unit" class="unit-text">
{{ state.mergedConfig.unit }}
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, watch, reactive, PropType } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import config, { option } from './config'
import cloneDeep from 'lodash/cloneDeep'
type DataProps = {
name: string | number
value: string | number
[key: string]: string | number
}
interface StateProps {
defaultConfig: {
dataset: {
dimensions: Array<string>
source: Array<DataProps>
}
colors: Array<string>
unit: string
showValue: boolean
itemHeight: number
valueFontSize: number
paddingLeft: number
paddingRight: number
}
mergedConfig: any
capsuleLength: Array<number>
capsuleValue: Array<string | Object>
labelData: Array<number>
capsuleItemHeight: string
}
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
default: () => ({})
}
})
const state = reactive<StateProps>({
defaultConfig: option,
mergedConfig: null,
capsuleLength: [],
capsuleValue: [],
labelData: [],
capsuleItemHeight: ''
})
watch(
() => props.chartConfig.option,
newVal => {
calcData(newVal)
},
{
deep: true
}
)
const calcData = (data: any) => {
mergeConfig(props.chartConfig.option)
calcCapsuleLengthAndLabelData()
}
const mergeConfig = (data: any) => {
state.mergedConfig = cloneDeep(data || {})
}
// 数据解析
const calcCapsuleLengthAndLabelData = () => {
const { source } = state.mergedConfig.dataset
if (!source.length) return
state.capsuleItemHeight = numberSizeHandle(state.mergedConfig.itemHeight)
const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])
const maxValue = Math.max(...capsuleValue)
state.capsuleValue = capsuleValue
state.capsuleLength = capsuleValue.map((v: any) => (maxValue ? v / maxValue : 0))
const oneFifth = maxValue / 5
const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))
state.labelData = labelData
}
const numberSizeHandle = (val: string | number) => {
return val + 'px'
}
onMounted(() => {
calcData(props.chartConfig.option)
})
// 预览
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
calcData(newData)
})
</script>
<style lang="scss" scoped>
@include go('dv-capsule-chart') {
position: relative;
display: flex;
flex-direction: row;
box-sizing: border-box;
padding: 20px;
padding-right: 50px;
color: #b9b8cc;
.label-column {
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
padding-right: 10px;
text-align: right;
> div:not(:last-child) {
margin: 5px 0;
}
}
.capsule-container {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.capsule-item {
box-shadow: 0 0 3px #999;
height: 10px;
margin: 5px 0px;
border-radius: 5px;
.capsule-item-column {
position: relative;
height: 8px;
margin-top: 1px;
border-radius: 5px;
transition: all 0.3s;
display: flex;
justify-content: flex-end;
align-items: center;
.capsule-item-value {
padding-left: 10px;
transform: translateX(100%);
}
}
}
.unit-label {
height: 20px;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.unit-text {
text-align: right;
display: flex;
align-items: flex-end;
line-height: 20px;
margin-left: 10px;
}
}
</style>

View File

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

View File

@@ -2,7 +2,6 @@ import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { LineCommonConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
@@ -48,7 +47,7 @@ export const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineCommonConfig.key
public chartConfig = cloneDeep(LineCommonConfig)
public chartConfig = LineCommonConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -3,6 +3,9 @@
<global-setting :optionData="optionData"></global-setting>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true">
<SettingItemBox name="线条">
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.lineStyle.color"></n-color-picker>
</setting-item>
<SettingItem name="宽度">
<n-input-number
v-model:value="item.lineStyle.width"

View File

@@ -3,7 +3,6 @@ import { LineGradientSingleConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { graphic } from 'echarts/core'
import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
@@ -59,7 +58,7 @@ const options = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineGradientSingleConfig.key
public chartConfig = cloneDeep(LineGradientSingleConfig)
public chartConfig = LineGradientSingleConfig
// 图表配置项
public option = echartOptionProfixHandle(options, includes)
}

View File

@@ -3,7 +3,6 @@ import { LineGradientsConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { graphic } from 'echarts/core'
import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
@@ -86,7 +85,7 @@ const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineGradientsConfig.key
public chartConfig = cloneDeep(LineGradientsConfig)
public chartConfig = LineGradientsConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -2,7 +2,6 @@ import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { LineLinearSingleConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
@@ -55,7 +54,7 @@ export const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = LineLinearSingleConfig.key
public chartConfig = cloneDeep(LineLinearSingleConfig)
public chartConfig = LineLinearSingleConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -1,83 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { MapAmapConfig } from './index'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export enum ThemeEnum {
NORMAL = 'normal',
DARK = 'dark',
LIGHT = 'light',
WHITES_MOKE = 'whitesmoke',
FRESH = 'fresh',
GREY = 'grey',
GRAFFITI = 'graffiti',
MACARON = 'macaron',
BLUE = 'blue',
DARKBLUE = 'darkblue',
WINE = 'wine'
}
export enum LangEnum {
ZH_CN = 'zh_cn',
EN = 'en',
ZH_EN = 'zh_en'
}
export enum ViewModeEnum {
PLANE = '2D',
STEREOSCOPIC = '3D'
}
export enum FeaturesEnum {
BG = 'bg',
POINT = 'point',
ROAD = 'road',
BUILDING = 'building'
}
export enum MarkerEnum {
// 圆圈
CIRCLE_MARKER = 'CircleMarker',
// 定位标点
MARKER = 'Marker',
// 暂无
NONE = 'none'
}
export const option = {
dataset: dataJson,
mapOptions: {
pitch: 60,
skyColor: '#53A9DE',
amapKey: 'd5f3e16589dbecae64d05fe90e2ba4f2',
amapStyleKey: ThemeEnum.DARK,
amapStyleKeyCustom: '',
amapLon: 116.397428,
amapLat: 39.90923,
amapZindex: 11,
marker: {
fillColor: '#E98984FF',
fillOpacity: 0.5,
strokeColor: 'white',
strokeWeight: 2,
strokeOpacity: 0.5,
zIndex: 10,
bubble: true,
cursor: 'pointer',
clickable: true
},
mapMarkerType: MarkerEnum.CIRCLE_MARKER,
viewMode: ViewModeEnum.PLANE,
lang: LangEnum.ZH_CN,
features: [FeaturesEnum.BG, FeaturesEnum.POINT, FeaturesEnum.ROAD, FeaturesEnum.BUILDING]
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = MapAmapConfig.key
public attr = { ...chartInitConfig, w: 1000, h: 800, zIndex: -1 }
public chartConfig = cloneDeep(MapAmapConfig)
public option = cloneDeep(option)
}

View File

@@ -1,199 +0,0 @@
<template>
<collapse-item name="基础" :expanded="true">
<setting-item-box name="语言类型" :alone="true">
<setting-item>
<n-select size="small" v-model:value="optionData.mapOptions.lang" :options="langOptions" />
</setting-item>
</setting-item-box>
<setting-item-box name="Key" :alone="true">
<setting-item name="请务必使用自己的高德应用 key">
<n-input v-model:value="optionData.mapOptions.amapKey" size="small"></n-input>
</setting-item>
</setting-item-box>
<setting-item-box name="自定义地图样式ID" :alone="true">
<setting-item>
<n-input size="small" v-model:value="optionData.mapOptions.amapStyleKeyCustom" />
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="地图" :expanded="true">
<setting-item-box name="主题">
<setting-item>
<n-select size="small" v-model:value="optionData.mapOptions.amapStyleKey" :options="themeOptions" />
</setting-item>
</setting-item-box>
<setting-item-box name="内容" :alone="true">
<n-checkbox-group v-model:value="optionData.mapOptions.features">
<n-space item-style="display: flex;">
<n-checkbox :value="item.value" :label="item.label" v-for="(item, index) in featuresOptions" :key="index" />
</n-space>
</n-checkbox-group>
</setting-item-box>
<setting-item-box name="位置">
<setting-item name="经度">
<n-input-number v-model:value="optionData.mapOptions.amapLon" :show-button="false" size="small">
<template #suffix>°</template>
</n-input-number>
</setting-item>
<setting-item name="纬度">
<n-input-number v-model:value="optionData.mapOptions.amapLat" :show-button="false" size="small">
<template #suffix>°</template>
</n-input-number>
</setting-item>
<setting-item name="初始缩放">
<n-input-number v-model:value="optionData.mapOptions.amapZindex" :min="0" size="small"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="模式" :alone="true">
<setting-item>
<n-radio-group v-model:value="optionData.mapOptions.viewMode" name="radiogroup">
<n-space>
<n-radio v-for="song in viewModeOptions" :key="song.value" :value="song.value">
{{ song.label }}
</n-radio>
</n-space>
</n-radio-group>
</setting-item>
</setting-item-box>
<template v-if="optionData.mapOptions.viewMode === '3D'">
<setting-item-box>
<setting-item name="天空色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.mapOptions.skyColor"></n-color-picker>
</setting-item>
<setting-item name="俯仰角">
<n-input-number v-model:value="optionData.mapOptions.pitch" :min="0" :max="83" size="small"></n-input-number>
</setting-item>
</setting-item-box>
</template>
</collapse-item>
<collapse-item name="标记" :expanded="true">
<setting-item-box name="样式">
<setting-item name="类型">
<n-select size="small" v-model:value="optionData.mapOptions.mapMarkerType" :options="MarkerOptions" />
</setting-item>
<setting-item name="颜色">
<n-color-picker v-model:value="optionData.mapOptions.marker.fillColor" size="small"></n-color-picker>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option, MarkerEnum, ThemeEnum, LangEnum, ViewModeEnum, FeaturesEnum } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const themeOptions = [
{
value: ThemeEnum.NORMAL,
label: '标准'
},
{
value: ThemeEnum.DARK,
label: '幻影黑'
},
{
value: ThemeEnum.LIGHT,
label: '月光银'
},
{
value: ThemeEnum.WHITES_MOKE,
label: '远山黛'
},
{
value: ThemeEnum.FRESH,
label: '草色青'
},
{
value: ThemeEnum.GREY,
label: '雅士灰'
},
{
value: ThemeEnum.GRAFFITI,
label: '涂鸦'
},
{
value: ThemeEnum.MACARON,
label: '马卡龙'
},
{
value: ThemeEnum.BLUE,
label: '靛青蓝'
},
{
value: ThemeEnum.DARKBLUE,
label: '极夜蓝'
},
{
value: ThemeEnum.WINE,
label: '酱籽'
}
]
const langOptions = [
{
value: LangEnum.ZH_CN,
label: '中文简体'
},
{
value: LangEnum.EN,
label: '英文'
},
{
value: LangEnum.ZH_EN,
label: '中英文对照'
}
]
const viewModeOptions = [
{
value: ViewModeEnum.PLANE,
label: '2D'
},
{
value: ViewModeEnum.STEREOSCOPIC,
label: '3D'
}
]
const featuresOptions = [
{
value: FeaturesEnum.BG,
label: '显示地图背景'
},
{
value: FeaturesEnum.POINT,
label: '显示标识'
},
{
value: FeaturesEnum.ROAD,
label: '显示道路'
},
{
value: FeaturesEnum.BUILDING,
label: '显示建筑'
}
]
const MarkerOptions = [
{
value: MarkerEnum.CIRCLE_MARKER,
label: '圆形标点'
},
{
value: MarkerEnum.MARKER,
label: '定位标点'
},
{
value: MarkerEnum.NONE,
label: '隐藏标点'
}
]
</script>

View File

@@ -1,19 +0,0 @@
{
"markers": [
{
"name": "某某地市",
"value": 10,
"position": [116.300467, 39.907761]
},
{
"name": "某某地市",
"value": 15,
"position": [116.400567, 39.908761]
},
{
"name": "某某地市",
"value": 20,
"position": [116.200467, 39.937761]
}
]
}

View File

@@ -1,15 +0,0 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import image from '@/assets/images/chart/charts/map_amap.png'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const MapAmapConfig: ConfigType = {
key: 'MapAmap',
chartKey: 'VMapAmap',
conKey: 'VCMapAmap',
title: '高德地图',
category: ChatCategoryEnum.MAP,
categoryName: ChatCategoryEnumName.MAP,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.COMMON,
image
}

View File

@@ -1,130 +0,0 @@
<template>
<div ref="vChartRef"></div>
</template>
<script setup lang="ts">
import { ref, PropType, toRefs, watch } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'
import { CreateComponentType } from '@/packages/index.d'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { MarkerEnum } from './config'
import { isArray } from '@/utils'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
let {
amapKey,
amapStyleKey,
amapLon,
amapLat,
amapZindex,
mapMarkerType,
lang,
amapStyleKeyCustom,
features,
viewMode,
pitch,
skyColor,
marker
} = toRefs(props.chartConfig.option.mapOptions)
let mapIns: any = null
let markers: any = []
let AMapIns: any = null
const vChartRef = ref<HTMLElement>()
const initMap = (newData: any) => {
// 初始化
AMapLoader.load({
key: amapKey.value, //api服务key--另外需要在public中使用安全密钥
version: '1.4.8', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete'] // 需要使用的的插件列表
})
.then(AMap => {
AMapIns = AMap
mapIns = new AMap.Map(vChartRef.value, {
resizeEnable: true,
zoom: amapZindex.value, // 地图显示的缩放级别
center: [amapLon.value, amapLat.value],
mapStyle: `amap://styles/${amapStyleKeyCustom.value !== '' ? amapStyleKeyCustom.value : amapStyleKey.value}`, //自定义地图的显示样式
lang: lang.value,
features: features.value,
pitch: pitch.value, // 地图俯仰角度,有效范围 0 度- 83 度
skyColor: skyColor.value,
viewMode: viewMode.value, // 地图模式
willReadFrequently: true
})
dataHandle(props.chartConfig.option.dataset)
})
.catch(e => {})
}
const dataHandle = (newData: any) => {
if (!mapIns && !AMapIns) {
initMap(props.chartConfig.option)
return
}
if (isArray(newData.markers)) {
// 先清除旧标记
mapIns.remove(markers)
markers = []
// 记录新标记
if (mapMarkerType.value === MarkerEnum.MARKER) {
newData.markers.forEach((markerItem: any) => {
const markerInstance = new AMapIns.Marker({
position: [markerItem.position[0], markerItem.position[1]],
offset: new AMapIns.Pixel(-13, -30)
})
markers.push(markerInstance)
markerInstance.setMap(mapIns)
})
} else if (mapMarkerType.value === MarkerEnum.CIRCLE_MARKER) {
newData.markers.forEach((markerItem: any) => {
const markerInstance = new AMapIns.CircleMarker({
center: [markerItem.position[0], markerItem.position[1]],
radius: markerItem.value,
...marker.value
})
markers.push(markerInstance)
markerInstance.setMap(mapIns)
})
}
}
}
const stopWatch = watch(
() => props.chartConfig.option.mapOptions,
option => {
initMap(option)
},
{
immediate: true,
deep: true
}
)
watch(
() => props.chartConfig.option.dataset,
newData => {
try {
dataHandle(newData)
} catch (error) {
console.log(error)
}
},
{
deep: false
}
)
// 预览
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
stopWatch()
dataHandle(newData)
})
</script>

View File

@@ -2,7 +2,6 @@ import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { MapBaseConfig } from './index'
import { chartInitConfig } from '@/settings/designSetting'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = []
@@ -152,6 +151,6 @@ export const MapDefaultConfig = { ...option }
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = MapBaseConfig.key
public attr = { ...chartInitConfig, w: 750, h: 800, zIndex: -1 }
public chartConfig = cloneDeep(MapBaseConfig)
public chartConfig = MapBaseConfig
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -1,4 +1,3 @@
import { MapBaseConfig } from './MapBase/index'
import { MapAmapConfig } from './MapAmap/index'
export default [MapBaseConfig, MapAmapConfig]
export default [ MapBaseConfig ]

View File

@@ -1,7 +1,6 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { PieCircleConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
export const includes = []
@@ -58,7 +57,7 @@ const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = PieCircleConfig.key
public chartConfig = cloneDeep(PieCircleConfig)
public chartConfig = PieCircleConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)

View File

@@ -1,7 +1,6 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { PieCommonConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend']
@@ -43,9 +42,7 @@ const option = {
},
label: {
show: false,
position: 'center',
formatter: '{b}',
fontSize:12
position: 'center'
},
emphasis: {
label: {
@@ -64,7 +61,7 @@ const option = {
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = PieCommonConfig.key
public chartConfig = cloneDeep(PieCommonConfig)
public chartConfig = PieCommonConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)

View File

@@ -7,48 +7,6 @@
<n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />
</SettingItem>
</SettingItemBox>
<SettingItemBox name="标签">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.series[0].label.show" size="small"></n-switch>
<n-text>展示标签</n-text>
</n-space>
</SettingItem>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.series[0].labelLine.show" size="small"></n-switch>
<n-text>引导线</n-text>
</n-space>
</setting-item>
<SettingItem name="位置">
<n-select v-model:value="optionData.series[0].label.position" size="small" :options="labelConfig.position" />
</SettingItem>
<setting-item name="展示类型">
<n-select v-model:value="optionData.series[0].label.formatter" size="small" :options="labelFormatterOptions" />
</setting-item>
</SettingItemBox>
<setting-item-box name="圆角">
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderRadius"
size="small"
:min="0"
></n-input-number>
<n-text>圆角大小</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderWidth"
size="small"
:min="0"
></n-input-number>
<n-text>线条宽度</n-text>
</n-space>
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
@@ -57,7 +15,6 @@ import { PropType, watch } from 'vue'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { PieTypeObject, PieTypeEnum } from './config'
import { labelConfig } from '@/packages/chartConfiguration/echarts'
const props = defineProps({
optionData: {
@@ -79,10 +36,4 @@ const fontWeightOptions = [
value: PieTypeObject[PieTypeEnum.ROSE]
}
]
const labelFormatterOptions = [
{ label: '数据名', value: '{b}' },
{ label: '百分比', value: '{d}' },
{ label: '列名:百分比', value: '{b}:{d}%' }
]
</script>

View File

@@ -3,7 +3,7 @@ import { CreateComponentType } from '@/packages/index.d'
import { CountDownConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
import { FlipType } from '@/components/Pages/Flipper'
import { FlipType } from '@/components/Flipper'
type STYLE = '时分秒' | '冒号'

View File

@@ -76,7 +76,7 @@
<script setup lang="ts">
import { PropType, toRefs, watch, ref, onMounted } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { Flipper } from '@/components/Pages/Flipper'
import { Flipper } from '@/components/Flipper'
import { OptionType } from './config'
import { CountdownInst, CountdownProps } from 'naive-ui/es/countdown/src/Countdown'

View File

@@ -3,7 +3,7 @@ import { CreateComponentType } from '@/packages/index.d'
import { FlipperNumberConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { chartInitConfig } from '@/settings/designSetting'
import { FlipType } from '@/components/Pages/Flipper'
import { FlipType } from '@/components/Flipper'
export interface OptionType {
dataset: number | string

View File

@@ -6,7 +6,7 @@ export const FlipperNumberConfig: ConfigType = {
key: 'FlipperNumber',
chartKey: 'VFlipperNumber',
conKey: 'VCFlipperNumber',
title: '数字翻牌-需动态触发',
title: '数字翻牌',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.DECORATES,

View File

@@ -21,7 +21,7 @@ import { PropType, toRefs, watch, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartDataFetch } from '@/hooks'
import { Flipper } from '@/components/Pages/Flipper'
import { Flipper } from '@/components/Flipper'
import { OptionType } from './config'
const props = defineProps({

View File

@@ -67,7 +67,7 @@ watch(
onMounted(() => {
try {
if (navigator.userAgent.indexOf('Chrome') < -1 || navigator.userAgent.indexOf('Edg') > -1) {
window['$message'].error('三维地图组件仅在【谷歌】浏览器上能正常展示!')
window['$message'].error('组件仅在【谷歌】浏览器上能正常展示!')
chartEditStore.removeComponentList(undefined, false)
return
}

View File

@@ -1,20 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { IframeConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
// 网站路径
dataset: "https://www.mtruning.club/",
// 圆角
borderRadius: 10
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
public key = IframeConfig.key
public attr = { ...chartInitConfig, w: 800, h: 800, zIndex: -1 }
public chartConfig = cloneDeep(IframeConfig)
public option = cloneDeep(option)
}

View File

@@ -1,36 +0,0 @@
<template>
<collapse-item name="属性" :expanded="true">
<setting-item-box name="路径" :alone="true">
<setting-item name="请填写 https 协议的网址">
<n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item>
</setting-item-box>
<setting-item-box name="样式">
<setting-item name="圆角">
<n-input-number
v-model:value="optionData.borderRadius"
size="small"
:min="0"
placeholder="圆角"
></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from "vue";
import { option } from "./config";
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from "@/components/Pages/ChartItemSetting";
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
});
</script>

View File

@@ -1,15 +0,0 @@
import image from '@/assets/images/chart/informations/iframe.png'
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const IframeConfig: ConfigType = {
key: 'Iframe',
chartKey: 'VIframe',
conKey: 'VCIframe',
title: '远程网页',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.COMMON,
image
}

View File

@@ -1,49 +0,0 @@
<template>
<div :style="getStyle(borderRadius)">
<iframe :src="option.dataset" :width="w" :height="h" style="border-width: 0"></iframe>
</div>
</template>
<script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { borderRadius } = toRefs(props.chartConfig.option)
const option = shallowReactive({
dataset: ''
})
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
// 编辑更新
watch(
() => props.chartConfig.option.dataset,
(newData: string) => {
option.dataset = newData
},
{
immediate: true
}
)
// 预览更新
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
option.dataset = newData
})
</script>

View File

@@ -46,7 +46,8 @@ watch(
option.dataset = newData
},
{
immediate: true
immediate: true,
deep: false
}
)

View File

@@ -10,6 +10,6 @@ export const VideoConfig: ConfigType = {
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.COMMON,
chartFrame: ChartFrameEnum.ECHARTS,
image
}

View File

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

View File

@@ -1,42 +0,0 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TextBarrageConfig } from './index'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
export enum FontWeightEnum {
NORMAL = '常规',
BOLD = '加粗',
}
export const FontWeightObject = {
[FontWeightEnum.NORMAL]: 'normal',
[FontWeightEnum.BOLD]: 'bold',
}
export const option = {
dataset: '让数字化看得见',
fontSize: 32,
fontColor: '#ffffff',
fontWeight: 'normal',
// 字间距
letterSpacing: 5,
//阴影
showShadow: true,
boxShadow: 'none',
hShadow: 0,
vShadow: 0,
blurShadow: 8,
colorShadow: '#0075ff',
//动画
animationTime: 0,
animationSpeed: 50,
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TextBarrageConfig.key
public attr = { ...chartInitConfig, w: 500, h: 70, zIndex: -1 }
public chartConfig = cloneDeep(TextBarrageConfig)
public option = cloneDeep(option)
}

View File

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

View File

@@ -1,14 +0,0 @@
import image from '@/assets/images/chart/informations/text_barrage.png'
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const TextBarrageConfig: ConfigType = {
key: 'TextBarrage',
chartKey: 'VTextBarrage',
conKey: 'VCTextBarrage',
title: '弹幕文字',
category: ChatCategoryEnum.TEXT,
categoryName: ChatCategoryEnumName.TEXT,
package: PackagesCategoryEnum.INFORMATIONS,
image
}

View File

@@ -1,102 +0,0 @@
<template>
<div class="go-text-box">
<div class="content">
<span>
{{ option.dataset }}
</span>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch, computed, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { option as configOption } from './config'
import { values } from 'lodash'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType & typeof option>,
required: true
}
})
const { w } = toRefs(props.chartConfig.attr)
const { fontColor, fontSize, letterSpacing, fontWeight, animationTime, animationSpeed, boxShadow } = toRefs(
props.chartConfig.option
)
const option = shallowReactive({
dataset: configOption.dataset
})
// 手动更新
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
},
{
immediate: true,
deep: false
}
)
//阴影
watch(
props.chartConfig.option,
() => {
try {
if (props.chartConfig.option.showShadow) {
boxShadow.value = `${props.chartConfig.option.hShadow}px ${props.chartConfig.option.vShadow}px ${props.chartConfig.option.blurShadow}px ${props.chartConfig.option.colorShadow}`
} else {
boxShadow.value = 'none'
}
} catch (error) {
console.log(error)
}
},
{
immediate: true
}
)
const transitionDuration = computed(() => {
return Math.floor((w.value as any) / (animationSpeed.value as any))
})
// 预览更新
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
option.dataset = newData
})
</script>
<style lang="scss" scoped>
@include go('text-box') {
display: flex;
align-items: center;
.content {
width: 100%;
color: v-bind('fontColor');
font-size: v-bind('fontSize + "px"');
letter-spacing: v-bind('letterSpacing + "px"');
font-weight: v-bind('fontWeight');
text-shadow: v-bind('boxShadow');
position: absolute;
animation: barrage v-bind('transitionDuration + "s"') linear v-bind('animationTime + "s"') infinite;
}
@keyframes barrage {
from {
left: 100%;
transform: translateX(0);
}
to {
left: 0;
transform: translateX(-100%);
}
}
}
</style>

View File

@@ -1,5 +1,4 @@
import { TextCommonConfig } from './TextCommon/index'
import { TextBarrageConfig } from './TextBarrage/index'
import { TextGradientConfig } from './TextGradient/index'
export default [TextCommonConfig, TextGradientConfig, TextBarrageConfig]
export default [TextCommonConfig, TextGradientConfig]

View File

@@ -62,7 +62,7 @@ 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
@@ -94,7 +94,6 @@ const calcHeights = (onresize = false) => {
const { rowNum, dataset } = status.mergedConfig
const avgHeight = h.value / rowNum
status.avgHeight = avgHeight
if (!onresize) status.heights = new Array(dataset.length).fill(avgHeight)
}
@@ -132,17 +131,12 @@ const stopAnimation = () => {
const onRestart = async () => {
try {
if (!status.mergedConfig) return
let { dataset, rowNum, sort } = status.mergedConfig
stopAnimation()
calcRowsData()
let flag = true
if (dataset.length <= rowNum) {
flag=false
}
calcHeights(flag)
animation(flag)
calcHeights(true)
animation(true)
} catch (error) {
console.error(error)
console.log(error)
}
}

View File

@@ -90,26 +90,6 @@ export const BlendModeEnumList = [
{ label: '亮度', value: 'luminosity' }
]
// 基础事件类型(vue不加 on)
export enum BaseEvent {
// 点击
ON_CLICK = 'click',
// 双击
ON_DBL_CLICK = 'dblclick',
// 移入
ON_MOUSE_ENTER = 'mouseenter',
// 移出
ON_MOUSE_LEAVE = 'mouseleave',
}
// vue3 生命周期事件
export enum EventLife {
// 渲染之后
VNODE_MOUNTED = 'vnodeMounted',
// 渲染之前
VNODE_BEFORE_MOUNT = 'vnodeBeforeMount',
}
// 组件实例类
export interface PublicConfigType {
id: string
@@ -135,20 +115,12 @@ export interface PublicConfigType {
}
filter?: string
status: StatusType
events: {
baseEvent: {
[K in BaseEvent]?: string
},
advancedEvents: {
[K in EventLife]?: string
}
}
}
export interface CreateComponentType extends PublicConfigType, requestConfig {
key: string
chartConfig: ConfigType
option: GlobalThemeJsonType,
option: GlobalThemeJsonType
}
// 组件成组实例类

View File

@@ -1,4 +1,5 @@
import { getUUID } from '@/utils'
import { ChartFrameEnum, PublicConfigType, CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { groupTitle } from '@/settings/designSetting'
import {
@@ -8,19 +9,11 @@ import {
RequestContentTypeEnum,
RequestBodyEnum
} from '@/enums/httpEnum'
import {
BaseEvent,
EventLife,
ChartFrameEnum,
PublicConfigType,
CreateComponentType,
CreateComponentGroupType
} from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
// 请求基础属性
export const requestConfig: RequestConfigType = {
const requestConfig: RequestConfigType = {
requestDataType: RequestDataTypeEnum.STATIC,
requestHttpType: RequestHttpEnum.GET,
requestUrl: '',
@@ -88,19 +81,6 @@ export class PublicConfigClass implements PublicConfigType {
public request = cloneDeep(requestConfig)
// 数据过滤
public filter = undefined
// 事件
public events = {
baseEvent: {
[BaseEvent.ON_CLICK]: undefined,
[BaseEvent.ON_DBL_CLICK]: undefined,
[BaseEvent.ON_MOUSE_ENTER]: undefined,
[BaseEvent.ON_MOUSE_LEAVE]: undefined
},
advancedEvents: {
[EventLife.VNODE_MOUNTED]: undefined,
[EventLife.VNODE_BEFORE_MOUNT]: undefined
}
}
}
// 多选成组类

View File

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

View File

@@ -27,7 +27,6 @@ import {
LockClosedOutline as LockClosedOutlineIcon,
HelpCircleOutline as HelpOutlineIcon,
CodeSlash as CodeSlashIcon,
Create as CreateIcon,
Rocket as RocketIcon,
Duplicate as DuplicateIcon,
DuplicateOutline as DuplicateOutlineIcon,
@@ -54,7 +53,6 @@ import {
ArrowForward as ArrowForwardIcon,
Planet as PawIcon,
Search as SearchIcon,
Reload as ReloadIcon,
ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon,
Pulse as PulseIcon,
@@ -64,8 +62,7 @@ import {
Images as ImagesIcon,
List as ListIcon,
EyeOutline as EyeOutlineIcon,
EyeOffOutline as EyeOffOutlineIcon,
Albums as AlbumsIcon
EyeOffOutline as EyeOffOutlineIcon
} from '@vicons/ionicons5'
import {
@@ -94,12 +91,10 @@ 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
FilterEdit as FilterEditIcon
} from '@vicons/carbon'
const ionicons5 = {
@@ -111,8 +106,6 @@ const ionicons5 = {
DuplicateOutlineIcon,
// 代码
CodeSlashIcon,
// 修改代码
CreateIcon,
// 事件(火箭)
RocketIcon,
// 退出
@@ -212,8 +205,6 @@ const ionicons5 = {
PawIcon,
// 搜索(放大镜)
SearchIcon,
// 加载
ReloadIcon,
// 过滤器
FilterIcon,
// 向上
@@ -234,9 +225,7 @@ const ionicons5 = {
ListIcon,
// 眼睛
EyeOutlineIcon,
EyeOffOutlineIcon,
// 图表列表
AlbumsIcon
EyeOffOutlineIcon
}
const carbon = {
@@ -281,17 +270,13 @@ const carbon = {
FitToScreenIcon,
FitToHeightIcon,
FitToWidthIcon,
// 保存
SaveIcon,
// 成组
Carbon3DCursorIcon,
// 解组
Carbon3DSoftwareIcon,
// 过滤器
FilterIcon,
FilterEditIcon,
// 图层
LaptopIcon
FilterEditIcon
}
// https://www.xicons.org/#/ 还有很多

View File

@@ -7,7 +7,6 @@ import {
NH2,
NH3,
NH4,
NH5,
NCode,
NCountdown,
NText,
@@ -110,7 +109,6 @@ const naive = create({
NH2,
NH3,
NH4,
NH5,
NCode,
NCountdown,
NText,

View File

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

View File

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

View File

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

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