Compare commits

..

35 Commits

Author SHA1 Message Date
奔跑的面条
3ac9ffc73c Merge branch 'dev' 2022-11-22 12:44:51 +08:00
奔跑的面条
c420ae467f Merge branch 'dev' 2022-11-21 10:49:25 +08:00
奔跑的面条
8334fe5bcc build: 升级版本到 1.1.5 2022-11-19 21:04:53 +08:00
奔跑的面条
f99edce6f4 Merge branch 'dev' 2022-11-19 21:04:32 +08:00
奔跑的面条
f47acca703 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-11-10 10:13:19 +00:00
奔跑的面条
73a6c6b920 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-11-10 10:10:58 +00:00
奔跑的面条
672f7a0a7c Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-11-05 21:46:26 +08:00
奔跑的面条
de78fb2149 docs: 新增文档截图 2022-11-05 18:19:33 +08:00
奔跑的面条
4a59e69bbe docs: 修改首页地址 2022-11-02 19:46:19 +08:00
奔跑的面条
a442e13a7b feat: 升级版本到1.1.4 2022-11-02 19:05:16 +08:00
奔跑的面条
4d093a4a80 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-11-02 19:02:38 +08:00
奔跑的面条
7e59d8d36c docs: 修改链接地址 2022-11-02 09:57:28 +08:00
奔跑的面条
8241077495 update README.md.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-10-29 12:09:36 +00:00
奔跑的面条
82b29a2f8b docs: 优化说明文档 2022-10-29 19:57:02 +08:00
奔跑的面条
b789d80f98 fix: 修改主页说明 2022-10-29 19:51:33 +08:00
奔跑的面条
a8c80e2366 docs: 修改主页说明 2022-10-29 19:50:30 +08:00
奔跑的面条
bdbdd37789 build: 升级版本到1.1.3 2022-10-15 17:17:34 +08:00
奔跑的面条
c8fb5b9152 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-15 17:12:13 +08:00
奔跑的面条
aef155e039 fix: 修复组件导入数据错乱的问题 2022-10-09 16:37:30 +08:00
奔跑的面条
443573455b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-09 09:28:38 +08:00
奔跑的面条
d811ab7dfa build: 撤回错误版本号 2022-10-08 21:12:58 +08:00
奔跑的面条
5f79ab6e6d build: 升级版本到1.1.2 2022-10-08 21:12:27 +08:00
奔跑的面条
502edbca5d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 21:05:48 +08:00
奔跑的面条
1a04267cb7 build: 升级版本到1.1.1 2022-10-08 20:59:55 +08:00
奔跑的面条
9c2c1bdfa1 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-10-08 20:59:25 +08:00
奔跑的面条
72e93f3768 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-27 20:16:07 +08:00
奔跑的面条
e6f2066d42 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-22 14:15:00 +08:00
奔跑的面条
2812c39524 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-21 19:54:29 +08:00
奔跑的面条
491485856e Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:46:37 +08:00
奔跑的面条
abde7e176d Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-19 20:13:50 +08:00
奔跑的面条
bab8faadee add default pipeline template yaml 2022-09-19 11:58:32 +00:00
奔跑的面条
427d72fb8b Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:48:28 +08:00
奔跑的面条
dc5b20a329 build: 升级版本到1.1.0 2022-09-18 16:33:26 +08:00
奔跑的面条
4cb934eef3 Merge branch 'dev' of https://gitee.com/MTrun/go-view 2022-09-18 16:32:34 +08:00
奔跑的面条
35e8cea0b5 docs: 更新已完成图表说明 2022-09-17 23:00:51 +08:00
132 changed files with 6149 additions and 3162 deletions

12
.env
View File

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

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

221
README.md
View File

@@ -1,114 +1,165 @@
## 总览 ## 总览
**`master-fetch` 分支是带有后端接口请求的分支** <p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)** <h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)** #### 😶 **纯前端** 分支: **`master`**
## 使用 #### 👻 携带 **后端** 请求分支: **`master-fetch`**
所有的接口地址位置:`src\api\path\*` #### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
接口地址修改:`.env` 项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
文档-源码地址:[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)
其它后端方案地址:
- 【.NET】[https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
#### 整体介绍
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
说明文档:
![说明文档](readme/go-view-doc.png)
工作台:
![工作台](readme/go-view-canvas.png)
请求配置:
![请求配置](readme/go-view-fetch.png)
数据过滤:
![数据过滤](readme/go-view-filter.png)
高级事件编辑:
![高级事件编辑](readme/go-view-event.png)
快捷主页:
![快捷主页](readme/go-view-indexpage.png)
主题色:
![主题色](readme/go-view-color.png)
亮白主题:
![亮白主题](readme/go-view-theme.png)
主要技术栈为:
| 名称 | 版本 | 名称 | 版本 |
| ------------------- | ----- | ----------- | ------ |
| Vue | 3.2.x | TypeScript4 | 4.6.x |
| Vite | 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 ```shell
# port #建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
VITE_DEV_PORT = '8080' #pnpm
pnpm install
# development path #yarn
VITE_DEV_PATH = 'http://127.0.0.1:8080' yarn install
# production path #npm
VITE_PRO_PATH = 'http://127.0.0.1:8080' npm install
``` ```
公共前缀修改:`src\settings\httpSetting.ts` ## 启动
```shell ```shell
// 请求前缀 #pnpm
export const axiosPre = '/api/goview' pnpm dev
# npm
npm run dev
#yarn
yarn dev
#Makefile
make dev
``` ```
接口封装:`src\api\http.ts` ## 编译
```ts ```shell
import axiosInstance from './axios' #pnpm
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum' pnpm run build
export const get = (url: string, params?: object) => { # npm
return axiosInstance({ npm run build
url: url,
method: RequestHttpEnum.GET,
params: params,
})
}
export const post = (url: string, data?: object, headersType?: string) => { #yarn
return axiosInstance({ yarn run build
url: url,
method: RequestHttpEnum.POST,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const put = (url: string, data?: object, headersType?: string) => { #Makefile
return axiosInstance({ make dist
url: url,
method: RequestHttpEnum.PUT,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const del = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.DELETE,
params
})
}
// 获取请求函数默认get
export const http = (type?: RequestHttpEnum) => {
switch (type) {
case RequestHttpEnum.GET:
return get
case RequestHttpEnum.POST:
return post
case RequestHttpEnum.PUT:
return put
case RequestHttpEnum.DELETE:
return del
default:
return get
}
}
``` ```
## 代码提交 ## 代码提交
* feat: 新功能 - feat: 新功能
* fix: 修复 Bug - fix: 修复 Bug
* docs: 文档修改 - docs: 文档修改
* perf: 性能优化 - perf: 性能优化
* revert: 版本回退 - revert: 版本回退
* ci: CICD集成相关 - ci: CICD 集成相关
* test: 添加测试代码 - test: 添加测试代码
* refactor: 代码重构 - refactor: 代码重构
* build: 影响项目构建或依赖修改 - build: 影响项目构建或依赖修改
* style: 不影响程序逻辑的代码修改 - style: 不影响程序逻辑的代码修改
* chore: 不属于以上类型的其他类型(日常事务) - chore: 不属于以上类型的其他类型(日常事务)
## 交流 ## 交流

View File

@@ -1,4 +1,3 @@
import path from 'path'
export const OUTPUT_DIR = 'dist' export const OUTPUT_DIR = 'dist'
// monaco-editor 路径 // monaco-editor 路径
@@ -7,7 +6,7 @@ export const prefix = `monaco-editor/esm/vs`
// chunk 警告大小 // chunk 警告大小
export const chunkSizeWarningLimit = 2000 export const chunkSizeWarningLimit = 2000
// 禁用 brotliSize 压缩大小报告 // 禁用 brotli 压缩大小报告
export const brotliSize = false export const brotliSize = false
// 分包 // 分包
@@ -15,12 +14,7 @@ export const rollupOptions = {
output: { output: {
chunkFileNames: 'static/js/[name]-[hash].js', chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js', entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: (chunkInfo) => { assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
if(['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) {
return `static/[ext]/[name].[ext]`
}
return `static/[ext]/[name]-[hash].[ext]`
},
manualChunks: { manualChunks: {
jsonWorker: [`${prefix}/language/json/json.worker`], jsonWorker: [`${prefix}/language/json/json.worker`],
cssWorker: [`${prefix}/language/css/css.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", "name": "go-view",
"version": "2.1.3", "version": "1.1.5",
"scripts": { "scripts": {
"dev": "vite --host", "dev": "vite --host",
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit && vite build",
@@ -35,7 +35,7 @@
"three": "^0.145.0", "three": "^0.145.0",
"vue": "^3.2.31", "vue": "^3.2.31",
"vue-demi": "^0.13.1", "vue-demi": "^0.13.1",
"vue-i18n": "9.1.10", "vue-i18n": "9.1.9",
"vue-router": "4.0.12", "vue-router": "4.0.12",
"vue3-lazyload": "^0.2.5-beta", "vue3-lazyload": "^0.2.5-beta",
"vue3-sketch-ruler": "^1.3.3", "vue3-sketch-ruler": "^1.3.3",

78
pnpm-lock.yaml generated
View File

@@ -59,7 +59,7 @@ specifiers:
vue: ^3.2.31 vue: ^3.2.31
vue-demi: ^0.13.1 vue-demi: ^0.13.1
vue-echarts: ^6.0.2 vue-echarts: ^6.0.2
vue-i18n: 9.1.10 vue-i18n: 9.1.9
vue-router: 4.0.12 vue-router: 4.0.12
vue-tsc: ^0.28.10 vue-tsc: ^0.28.10
vue3-lazyload: ^0.2.5-beta vue3-lazyload: ^0.2.5-beta
@@ -91,7 +91,7 @@ dependencies:
three: 0.145.0 three: 0.145.0
vue: 3.2.37 vue: 3.2.37
vue-demi: 0.13.1_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 vue-router: 4.0.12_vue@3.2.37
vue3-lazyload: 0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae vue3-lazyload: 0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae
vue3-sketch-ruler: 1.3.4_vue@3.2.37 vue3-sketch-ruler: 1.3.4_vue@3.2.37
@@ -671,60 +671,60 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true dev: true
/@intlify/core-base/9.1.10: /@intlify/core-base/9.1.9:
resolution: {integrity: sha512-So9CNUavB/IsZ+zBmk2Cv6McQp6vc2wbGi1S0XQmJ8Vz+UFcNn9MFXAe9gY67PreIHrbLsLxDD0cwo1qsxM1Nw==} resolution: {integrity: sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
'@intlify/devtools-if': 9.1.10 '@intlify/devtools-if': 9.1.9
'@intlify/message-compiler': 9.1.10 '@intlify/message-compiler': 9.1.9
'@intlify/message-resolver': 9.1.10 '@intlify/message-resolver': 9.1.9
'@intlify/runtime': 9.1.10 '@intlify/runtime': 9.1.9
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
'@intlify/vue-devtools': 9.1.10 '@intlify/vue-devtools': 9.1.9
dev: false dev: false
/@intlify/devtools-if/9.1.10: /@intlify/devtools-if/9.1.9:
resolution: {integrity: sha512-SHaKoYu6sog3+Q8js1y3oXLywuogbH1sKuc7NSYkN3GElvXSBaMoCzW+we0ZSFqj/6c7vTNLg9nQ6rxhKqYwnQ==} resolution: {integrity: sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
dev: false dev: false
/@intlify/message-compiler/9.1.10: /@intlify/message-compiler/9.1.9:
resolution: {integrity: sha512-+JiJpXff/XTb0EadYwdxOyRTB0hXNd4n1HaJ/a4yuV960uRmPXaklJsedW0LNdcptd/hYUZtCkI7Lc9J5C1gxg==} resolution: {integrity: sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
'@intlify/message-resolver': 9.1.10 '@intlify/message-resolver': 9.1.9
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
source-map: 0.6.1 source-map: 0.6.1
dev: false dev: false
/@intlify/message-resolver/9.1.10: /@intlify/message-resolver/9.1.9:
resolution: {integrity: sha512-5YixMG/M05m0cn9+gOzd4EZQTFRUu8RGhzxJbR1DWN21x/Z3bJ8QpDYj6hC4FwBj5uKsRfKpJQ3Xqg98KWoA+w==} resolution: {integrity: sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dev: false dev: false
/@intlify/runtime/9.1.10: /@intlify/runtime/9.1.9:
resolution: {integrity: sha512-7QsuByNzpe3Gfmhwq6hzgXcMPpxz8Zxb/XFI6s9lQdPLPe5Lgw4U1ovRPZTOs6Y2hwitR3j/HD8BJNGWpJnOFA==} resolution: {integrity: sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
'@intlify/message-compiler': 9.1.10 '@intlify/message-compiler': 9.1.9
'@intlify/message-resolver': 9.1.10 '@intlify/message-resolver': 9.1.9
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
dev: false dev: false
/@intlify/shared/9.1.10: /@intlify/shared/9.1.9:
resolution: {integrity: sha512-Om54xJeo1Vw+K1+wHYyXngE8cAbrxZHpWjYzMR9wCkqbhGtRV5VLhVc214Ze2YatPrWlS2WSMOWXR8JktX/IgA==} resolution: {integrity: sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dev: false dev: false
/@intlify/vue-devtools/9.1.10: /@intlify/vue-devtools/9.1.9:
resolution: {integrity: sha512-5l3qYARVbkWAkagLu1XbDUWRJSL8br1Dj60wgMaKB0+HswVsrR6LloYZTg7ozyvM621V6+zsmwzbQxbVQyrytQ==} resolution: {integrity: sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
dependencies: dependencies:
'@intlify/message-resolver': 9.1.10 '@intlify/message-resolver': 9.1.9
'@intlify/runtime': 9.1.10 '@intlify/runtime': 9.1.9
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
dev: false dev: false
/@jridgewell/gen-mapping/0.1.1: /@jridgewell/gen-mapping/0.1.1:
@@ -3074,7 +3074,7 @@ packages:
source-map: 0.6.1 source-map: 0.6.1
wordwrap: 1.0.0 wordwrap: 1.0.0
optionalDependencies: optionalDependencies:
uglify-js: 3.17.4 uglify-js: 3.16.0
dev: true dev: true
/hard-rejection/2.1.0: /hard-rejection/2.1.0:
@@ -5014,8 +5014,8 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/uglify-js/3.17.4: /uglify-js/3.16.0:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} resolution: {integrity: sha512-FEikl6bR30n0T3amyBh3LoiBdqHRy/f4H80+My34HOesOKyHfOsxAPAxOoqC0JUnC1amnO0IwkYC3sko51caSw==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
hasBin: true hasBin: true
requiresBuild: true requiresBuild: true
@@ -5385,15 +5385,15 @@ packages:
- supports-color - supports-color
dev: true dev: true
/vue-i18n/9.1.10_vue@3.2.37: /vue-i18n/9.1.9_vue@3.2.37:
resolution: {integrity: sha512-jpr7gV5KPk4n+sSPdpZT8Qx3XzTcNDWffRlHV/cT2NUyEf+sEgTTmLvnBAibjOFJ0zsUyZlVTAWH5DDnYep+1g==} resolution: {integrity: sha512-JeRdNVxS2OGp1E+pye5XB6+M6BBkHwAv9C80Q7+kzoMdUDGRna06tjC0vCB/jDX9aWrl5swxOMFcyAr7or8XTA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
dependencies: dependencies:
'@intlify/core-base': 9.1.10 '@intlify/core-base': 9.1.9
'@intlify/shared': 9.1.10 '@intlify/shared': 9.1.9
'@intlify/vue-devtools': 9.1.10 '@intlify/vue-devtools': 9.1.9
'@vue/devtools-api': 6.1.4 '@vue/devtools-api': 6.1.4
vue: 3.2.37 vue: 3.2.37
dev: false dev: false

BIN
readme/go-view-doc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
readme/go-view-theme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

View File

@@ -17,7 +17,7 @@
import { NConfigProvider } from 'naive-ui' import { NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider' import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n' import { I18n } from '@/components/I18n'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks' import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
// 暗黑主题 // 暗黑主题
const darkTheme = useDarkThemeHook() const darkTheme = useDarkThemeHook()
@@ -28,9 +28,6 @@ const overridesTheme = useThemeOverridesHook()
// 代码主题 // 代码主题
const hljsTheme = useCode() const hljsTheme = useCode()
// 系统全局数据初始化
useSystemInit()
// 全局语言 // 全局语言
const { locale, dateLocale } = useLang() const { locale, dateLocale } = useLang()

View File

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

View File

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

View File

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

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

View File

@@ -42,19 +42,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch } from 'vue'
import { icon } from '@/plugins' import { icon } from '@/plugins'
const props = defineProps({
modelShow: Boolean
})
const emit = defineEmits(['update:modelShow'])
const { HelpOutlineIcon, CloseIcon } = icon.ionicons5 const { HelpOutlineIcon, CloseIcon } = icon.ionicons5
const modelShow = ref(false) const emit = defineEmits(['update:modelShow'])
watch(() => props.modelShow, (newValue) => { defineProps({
modelShow.value = newValue modelShow: Boolean
}) })
const closeHandle = () => { const closeHandle = () => {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -26,10 +26,11 @@ export const useChartDataFetch = (
// 数据池 // 数据池
const { addGlobalDataInterface } = useChartDataPondFetch() const { addGlobalDataInterface } = useChartDataPondFetch()
const { requestDataPondId } = toRefs(targetComponent.request)
// 组件类型 // 组件类型
const { chartFrame } = targetComponent.chartConfig const { chartFrame } = targetComponent.chartConfig
// eCharts 组件配合 vChart 库更新方式 // eCharts 组件配合 vChart 库更新方式
const echartsUpdateHandle = (dataset: any) => { const echartsUpdateHandle = (dataset: any) => {
if (chartFrame === ChartFrameEnum.ECHARTS) { if (chartFrame === ChartFrameEnum.ECHARTS) {
@@ -88,6 +89,7 @@ export const useChartDataFetch = (
// 立即调用 // 立即调用
fetchFn() fetchFn()
// 定时时间 // 定时时间
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
// 单位 // 单位
@@ -102,8 +104,8 @@ export const useChartDataFetch = (
} }
if (isPreview()) { if (isPreview()) {
// 判断是否数据池类型 // 判断是否数据池对应 id
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond requestDataPondId
? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle) ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
: requestIntervalFn() : requestIntervalFn()
} }

View File

@@ -3,7 +3,7 @@ import { customizeHttp } from '@/api/http'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestGlobalConfigType, RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d' import { RequestGlobalConfigType, RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { newFunctionHandle, intervalUnitHandle } from '@/utils' import { newFunctionHandle } from '@/utils'
// 获取类型 // 获取类型
type ChartEditStoreType = typeof useChartEditStore type ChartEditStoreType = typeof useChartEditStore
@@ -24,9 +24,6 @@ const newPondItemInterval = (
dataPondMapItem?: DataPondMapType[] dataPondMapItem?: DataPondMapType[]
) => { ) => {
if (!dataPondMapItem) return if (!dataPondMapItem) return
let fetchInterval: any = 0
clearInterval(fetchInterval)
// 请求 // 请求
const fetchFn = async () => { const fetchFn = async () => {
@@ -51,19 +48,6 @@ const newPondItemInterval = (
// 立即调用 // 立即调用
fetchFn() 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))
} }
/** /**
@@ -80,7 +64,7 @@ export const useChartDataPondFetch = () => {
const { requestDataPond } = chartEditStore.getRequestGlobalConfig const { requestDataPond } = chartEditStore.getRequestGlobalConfig
// 组件对应的数据池 Id // 组件对应的数据池 Id
const requestDataPondId = targetComponent.request.requestDataPondId as string const requestDataPondId = '111' || (targetComponent.request.requestDataPondId as string)
// 新增数据项 // 新增数据项
const mittPondIdArr = mittDataPondMap.get(requestDataPondId) || [] const mittPondIdArr = mittDataPondMap.get(requestDataPondId) || []
mittPondIdArr.push({ mittPondIdArr.push({
@@ -90,11 +74,6 @@ export const useChartDataPondFetch = () => {
mittDataPondMap.set(requestDataPondId, mittPondIdArr) mittDataPondMap.set(requestDataPondId, mittPondIdArr)
} }
// 清除旧数据
const clearMittDataPondMap = () => {
mittDataPondMap.clear()
}
// 初始化数据池 // 初始化数据池
const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => { const initDataPond = (requestGlobalConfig: RequestGlobalConfigType) => {
const { requestDataPond } = requestGlobalConfig const { requestDataPond } = requestGlobalConfig
@@ -109,7 +88,6 @@ export const useChartDataPondFetch = () => {
return { return {
addGlobalDataInterface, addGlobalDataInterface,
clearMittDataPondMap,
initDataPond initDataPond
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -43,9 +43,7 @@ const option = {
}, },
label: { label: {
show: false, show: false,
position: 'center', position: 'center'
formatter: '{b}',
fontSize:12
}, },
emphasis: { emphasis: {
label: { label: {

View File

@@ -7,48 +7,6 @@
<n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" /> <n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />
</SettingItem> </SettingItem>
</SettingItemBox> </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> </CollapseItem>
</template> </template>
@@ -57,7 +15,6 @@ import { PropType, watch } from 'vue'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index' import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { PieTypeObject, PieTypeEnum } from './config' import { PieTypeObject, PieTypeEnum } from './config'
import { labelConfig } from '@/packages/chartConfiguration/echarts'
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@@ -79,10 +36,4 @@ const fontWeightOptions = [
value: PieTypeObject[PieTypeEnum.ROSE] value: PieTypeObject[PieTypeEnum.ROSE]
} }
] ]
const labelFormatterOptions = [
{ label: '数据名', value: '{b}' },
{ label: '百分比', value: '{d}' },
{ label: '列名:百分比', value: '{b}:{d}%' }
]
</script> </script>

View File

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

View File

@@ -20,7 +20,7 @@ import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
// 请求基础属性 // 请求基础属性
export const requestConfig: RequestConfigType = { const requestConfig: RequestConfigType = {
requestDataType: RequestDataTypeEnum.STATIC, requestDataType: RequestDataTypeEnum.STATIC,
requestHttpType: RequestHttpEnum.GET, requestHttpType: RequestHttpEnum.GET,
requestUrl: '', requestUrl: '',

View File

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

View File

@@ -54,7 +54,6 @@ import {
ArrowForward as ArrowForwardIcon, ArrowForward as ArrowForwardIcon,
Planet as PawIcon, Planet as PawIcon,
Search as SearchIcon, Search as SearchIcon,
Reload as ReloadIcon,
ChevronUpOutline as ChevronUpOutlineIcon, ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon, ChevronDownOutline as ChevronDownOutlineIcon,
Pulse as PulseIcon, Pulse as PulseIcon,
@@ -94,7 +93,6 @@ import {
FitToScreen as FitToScreenIcon, FitToScreen as FitToScreenIcon,
FitToHeight as FitToHeightIcon, FitToHeight as FitToHeightIcon,
FitToWidth as FitToWidthIcon, FitToWidth as FitToWidthIcon,
Save as SaveIcon,
Carbon3DCursor as Carbon3DCursorIcon, Carbon3DCursor as Carbon3DCursorIcon,
Carbon3DSoftware as Carbon3DSoftwareIcon, Carbon3DSoftware as Carbon3DSoftwareIcon,
Filter as FilterIcon, Filter as FilterIcon,
@@ -212,8 +210,6 @@ const ionicons5 = {
PawIcon, PawIcon,
// 搜索(放大镜) // 搜索(放大镜)
SearchIcon, SearchIcon,
// 加载
ReloadIcon,
// 过滤器 // 过滤器
FilterIcon, FilterIcon,
// 向上 // 向上
@@ -281,8 +277,6 @@ const carbon = {
FitToScreenIcon, FitToScreenIcon,
FitToHeightIcon, FitToHeightIcon,
FitToWidthIcon, FitToWidthIcon,
// 保存
SaveIcon,
// 成组 // 成组
Carbon3DCursorIcon, Carbon3DCursorIcon,
// 解组 // 解组

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +0,0 @@
// 请求前缀
export const axiosPre = '/api/goview'

View File

@@ -1,6 +1,5 @@
import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d' import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d' import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { SyncEnum } from '@/enums/editPageEnum'
import { import {
RequestHttpEnum, RequestHttpEnum,
RequestContentTypeEnum, RequestContentTypeEnum,
@@ -13,29 +12,6 @@ import {
import { PreviewScaleEnum } from '@/enums/styleEnum' import { PreviewScaleEnum } from '@/enums/styleEnum'
import type { ChartColorsNameType, GlobalThemeJsonType } from '@/settings/chartThemes/index' import type { ChartColorsNameType, GlobalThemeJsonType } from '@/settings/chartThemes/index'
// 项目数据枚举
export enum ProjectInfoEnum {
// ID
PROJECT_ID = "projectId",
// 名称
PROJECT_NAME = 'projectName',
// 描述
REMARKS = 'remarks',
// 缩略图
THUMBNAIL= 'thumbnail',
// 是否公开发布
RELEASE = 'release'
}
// 项目数据
export type ProjectInfoType = {
[ProjectInfoEnum.PROJECT_ID]: string,
[ProjectInfoEnum.PROJECT_NAME]: string,
[ProjectInfoEnum.REMARKS]: string,
[ProjectInfoEnum.THUMBNAIL]: string,
[ProjectInfoEnum.RELEASE]: boolean
}
// 编辑画布属性 // 编辑画布属性
export enum EditCanvasTypeEnum { export enum EditCanvasTypeEnum {
EDIT_LAYOUT_DOM = 'editLayoutDom', EDIT_LAYOUT_DOM = 'editLayoutDom',
@@ -44,13 +20,12 @@ export enum EditCanvasTypeEnum {
SCALE = 'scale', SCALE = 'scale',
USER_SCALE = 'userScale', USER_SCALE = 'userScale',
LOCK_SCALE = 'lockScale', LOCK_SCALE = 'lockScale',
SAVE_STATUS = 'saveStatus',
IS_CREATE = 'isCreate', IS_CREATE = 'isCreate',
IS_DRAG = 'isDrag', IS_DRAG = 'isDrag',
IS_SELECT = 'isSelect' IS_SELECT = 'isSelect'
} }
// 编辑区域(临时) // 编辑区域
export type EditCanvasType = { export type EditCanvasType = {
// 编辑区域 DOM // 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null [EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@@ -67,13 +42,11 @@ export type EditCanvasType = {
[EditCanvasTypeEnum.IS_CREATE]: boolean [EditCanvasTypeEnum.IS_CREATE]: boolean
// 拖拽中 // 拖拽中
[EditCanvasTypeEnum.IS_DRAG]: boolean [EditCanvasTypeEnum.IS_DRAG]: boolean
// 保存状态
[EditCanvasTypeEnum.SAVE_STATUS]: SyncEnum
// 框选中 // 框选中
[EditCanvasTypeEnum.IS_SELECT]: boolean [EditCanvasTypeEnum.IS_SELECT]: boolean
} }
// 画布数据/滤镜/背景色/宽高主题等 // 滤镜/背景色/宽高主题等
export enum EditCanvasConfigEnum { export enum EditCanvasConfigEnum {
WIDTH = 'width', WIDTH = 'width',
HEIGHT = 'height', HEIGHT = 'height',
@@ -85,14 +58,7 @@ export enum EditCanvasConfigEnum {
PREVIEW_SCALE_TYPE = 'previewScaleType' PREVIEW_SCALE_TYPE = 'previewScaleType'
} }
// 画布属性(需保存) export interface EditCanvasConfigType {
export type EditCanvasConfigType = {
// ID
[EditCanvasConfigEnum.PROJECT_ID]: string,
// 项目名称
[EditCanvasConfigEnum.PROJECT_NAME]: string,
// 项目描述
[EditCanvasConfigEnum.REMARKS]: string,
// 滤镜-启用 // 滤镜-启用
[FilterEnum.FILTERS_SHOW]: boolean [FilterEnum.FILTERS_SHOW]: boolean
// 滤镜-色相 // 滤镜-色相
@@ -164,7 +130,6 @@ export type RecordChartType = {
// Store 枚举 // Store 枚举
export enum ChartEditStoreEnum { export enum ChartEditStoreEnum {
PROJECT_INFO = 'projectInfo',
EDIT_RANGE = 'editRange', EDIT_RANGE = 'editRange',
EDIT_CANVAS = 'editCanvas', EDIT_CANVAS = 'editCanvas',
RIGHT_MENU_SHOW = 'rightMenuShow', RIGHT_MENU_SHOW = 'rightMenuShow',
@@ -226,7 +191,6 @@ export interface RequestConfigType extends RequestPublicConfigType {
// Store 类型 // Store 类型
export interface ChartEditStoreType { export interface ChartEditStoreType {
[ChartEditStoreEnum.PROJECT_INFO]: ProjectInfoType
[ChartEditStoreEnum.EDIT_CANVAS]: EditCanvasType [ChartEditStoreEnum.EDIT_CANVAS]: EditCanvasType
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType [ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean [ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean

View File

@@ -10,22 +10,14 @@ import { requestInterval, previewScaleType, requestIntervalUnit } from '@/settin
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore' import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
// 全局设置 // 全局设置
import { useSettingStore } from '@/store/modules/settingStore/settingStore' import { useSettingStore } from '@/store/modules/settingStore/settingStore'
// 历史类型
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
// 画布枚举
import { MenuEnum, SyncEnum } from '@/enums/editPageEnum'
import { import {
getUUID, HistoryActionTypeEnum,
loadingStart, HistoryItemType,
loadingFinish, HistoryTargetTypeEnum
loadingError, } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
isString, import { MenuEnum } from '@/enums/editPageEnum'
isArray import { getUUID, loadingStart, loadingFinish, loadingError, isString, isArray } from '@/utils'
} from '@/utils'
import { import {
ProjectInfoType,
ChartEditStoreEnum, ChartEditStoreEnum,
ChartEditStorage, ChartEditStorage,
ChartEditStoreType, ChartEditStoreType,
@@ -44,14 +36,6 @@ const settingStore = useSettingStore()
export const useChartEditStore = defineStore({ export const useChartEditStore = defineStore({
id: 'useChartEditStore', id: 'useChartEditStore',
state: (): ChartEditStoreType => ({ state: (): ChartEditStoreType => ({
// 项目数据
projectInfo: {
projectId: '',
projectName: '',
remarks: '',
thumbnail: '',
release: false
},
// 画布属性 // 画布属性
editCanvas: { editCanvas: {
// 编辑区域 Dom // 编辑区域 Dom
@@ -70,9 +54,7 @@ export const useChartEditStore = defineStore({
// 拖拽中 // 拖拽中
isDrag: false, isDrag: false,
// 框选中 // 框选中
isSelect: false, isSelect: false
// 同步中
saveStatus: SyncEnum.PENDING
}, },
// 右键菜单 // 右键菜单
rightMenuShow: false, rightMenuShow: false,
@@ -150,9 +132,6 @@ export const useChartEditStore = defineStore({
componentList: [] componentList: []
}), }),
getters: { getters: {
getProjectInfo(): ProjectInfoType {
return this.projectInfo
},
getMousePosition(): MousePositionType { getMousePosition(): MousePositionType {
return this.mousePosition return this.mousePosition
}, },
@@ -187,10 +166,6 @@ export const useChartEditStore = defineStore({
} }
}, },
actions: { actions: {
// * 设置 peojectInfo 数据项
setProjectInfo<T extends keyof ProjectInfoType, K extends ProjectInfoType[T]>(key: T, value: K) {
this.projectInfo[key] = value
},
// * 设置 editCanvas 数据项 // * 设置 editCanvas 数据项
setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) { setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) {
this.editCanvas[key] = value this.editCanvas[key] = value

View File

@@ -4,10 +4,10 @@ import { asideCollapsedWidth } from '@/settings/designSetting'
import { SettingStoreType, ToolsStatusEnum } from './settingStore.d' import { SettingStoreType, ToolsStatusEnum } from './settingStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils' import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum' import { StorageEnum } from '@/enums/storageEnum'
const { GO_SETTING_STORE } = StorageEnum const { GO_SYSTEM_SETTING_STORE } = StorageEnum
const storageSetting: SettingStoreType = getLocalStorage( const storageSetting: SettingStoreType = getLocalStorage(
GO_SETTING_STORE GO_SYSTEM_SETTING_STORE
) )
// 全局设置 // 全局设置
@@ -48,7 +48,7 @@ export const useSettingStore = defineStore({
this.$patch(state => { this.$patch(state => {
state[key] = value state[key] = value
}) })
setLocalStorage(GO_SETTING_STORE, this.$state) setLocalStorage(GO_SYSTEM_SETTING_STORE, this.$state)
} }
} }
}) })

View File

@@ -1,31 +0,0 @@
export enum SystemStoreUserInfoEnum {
USER_TOKEN = 'userToken',
TOKEN_NAME = 'tokenName',
USER_ID = 'userId',
USER_NAME = 'userName',
NICK_NAME = 'nickName',
}
export interface UserInfoType {
[SystemStoreUserInfoEnum.USER_TOKEN]?: string,
[SystemStoreUserInfoEnum.TOKEN_NAME]?: string,
[SystemStoreUserInfoEnum.USER_ID]?: string,
[SystemStoreUserInfoEnum.USER_NAME]?: string,
[SystemStoreUserInfoEnum.NICK_NAME]?: string,
}
export interface FetchInfoType {
OSSUrl?: string,
}
export enum SystemStoreEnum {
// 用户
USER_INFO = 'userInfo',
// 请求
FETCH_INFO = 'fetchInfo'
}
export interface SystemStoreType {
[SystemStoreEnum.USER_INFO]: UserInfoType
[SystemStoreEnum.FETCH_INFO]: FetchInfoType
}

View File

@@ -1,40 +0,0 @@
import { defineStore } from 'pinia'
import { SystemStoreType, UserInfoType, FetchInfoType } from './systemStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
const { GO_SYSTEM_STORE } = StorageEnum
const storageSystem: SystemStoreType = getLocalStorage(GO_SYSTEM_STORE)
// 系统数据记录
export const useSystemStore = defineStore({
id: 'useSystemStore',
state: (): SystemStoreType => storageSystem || {
userInfo: {
userId: undefined,
userName: undefined,
userToken: undefined,
nickName: undefined
},
fetchInfo: {
OSSUrl: undefined
}
},
getters: {
getUserInfo(): UserInfoType {
return this.userInfo
},
getFetchInfo(): FetchInfoType {
return this.fetchInfo
},
},
actions: {
setItem<T extends keyof SystemStoreType, K extends SystemStoreType[T]>(key: T, value: K): void {
this.$patch(state => {
state[key] = value
});
setLocalStorage(GO_SYSTEM_STORE, this.$state)
}
}
})

View File

@@ -1,65 +1,3 @@
/**
* * base64转file
* @param dataurl
* @param fileName
* @returns
*/
export const base64toFile = (dataurl: string, fileName: string) => {
let dataArr = dataurl.split(","),
mime = (dataArr as any[])[0].match(/:(.*?);/)[1],
bstr = atob(dataArr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], fileName, { type: mime });
}
/**
* * file转url
*/
export const fileToUrl = (file: File): string => {
const Url = URL || window.URL || window.webkitURL
const ImageUrl = Url.createObjectURL(file)
return ImageUrl
}
/**
* * url转file
*/
export const urlToFile = (fileUrl: string, fileName = `${new Date().getTime()}`): File => {
const dataArr = fileUrl.split(',')
const mime = (dataArr as any[])[0].match(/:(.*);/)[1]
const originStr = atob(dataArr[1])
return new File([originStr], `${fileName}`, { type: mime })
}
/**
* * file转base64
* @param file 文件数据
* @param callback 回调函数
*/
export const fileTobase64 = (file: File, callback: Function) => {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function (e: ProgressEvent<FileReader>) {
if (e.target) {
let base64 = e.target.result
callback(base64)
}
}
}
/**
* * canvas转file
* @param canvas
*/
export const canvastoFile = (canvas: HTMLCanvasElement, name?: string) => {
const dataurl = canvas.toDataURL('image/png')
return urlToFile(dataurl, name)
}
/** /**
* *获取上传的文件数据 * *获取上传的文件数据
* @param { File } file 文件对象 * @param { File } file 文件对象
@@ -113,4 +51,4 @@ export const downloadTextFile = (
// 字符内容转变成blob地址 // 字符内容转变成blob地址
const blob = new Blob([content]) const blob = new Blob([content])
downloadByA(URL.createObjectURL(blob), filename, fileSuffix) downloadByA(URL.createObjectURL(blob), filename, fileSuffix)
} }

View File

@@ -1,6 +0,0 @@
/**
* * 请求失败统一处理
*/
export const httpErrorHandle = () => {
window['$message'].error(window['$t']('http.error_message'))
}

View File

@@ -7,4 +7,3 @@ export * from '@/utils/plugin'
export * from '@/utils/components' export * from '@/utils/components'
export * from '@/utils/type' export * from '@/utils/type'
export * from '@/utils/file' export * from '@/utils/file'
export * from '@/utils/http'

View File

@@ -35,7 +35,7 @@ export const loadingError = () => {
* }) * })
* ``` * ```
*/ */
export const goDialog = ( export const goDialog = (
params: { params: {
// 基本 // 基本
type?: DialogEnum type?: DialogEnum

View File

@@ -1,12 +1,11 @@
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { ResultEnum, RequestHttpHeaderEnum } from '@/enums/httpEnum' import { ResultEnum } from '@/enums/httpEnum'
import { ErrorPageNameMap, PageEnum, PreviewEnum } from '@/enums/pageEnum' import { ErrorPageNameMap, PageEnum } from '@/enums/pageEnum'
import { docPath, giteeSourceCodePath } from '@/settings/pathConst' import { docPath, giteeSourceCodePath } from '@/settings/pathConst'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d' import { cryptoDecode } from './crypto'
import { StorageEnum } from '@/enums/storageEnum' import { StorageEnum } from '@/enums/storageEnum'
import { clearLocalStorage, getLocalStorage, clearCookie } from './storage' import { clearLocalStorage, getLocalStorage } from './storage'
import router from '@/router' import router from '@/router'
import { logoutApi } from '@/api/path'
/** /**
* * 根据名字跳转路由 * * 根据名字跳转路由
@@ -102,20 +101,11 @@ export const reloadRoutePage = () => {
} }
/** /**
* * 退出登录 * * 退出
*/ */
export const logout = async () => { export const logout = () => {
try { clearLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
const res = await logoutApi() routerTurnByName(PageEnum.BASE_LOGIN_NAME)
if(res && res.code === ResultEnum.SUCCESS) {
window['$message'].success(window['$t']('global.logout_success'))
clearCookie(RequestHttpHeaderEnum.COOKIE)
clearLocalStorage(StorageEnum.GO_SYSTEM_STORE)
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
}
} catch (error) {
window['$message'].success(window['$t']('global.logout_failure'))
}
} }
/** /**
@@ -167,7 +157,7 @@ export const fetchRouteParams = () => {
* * 通过硬解析获取当前路由下的参数 * * 通过硬解析获取当前路由下的参数
* @returns object * @returns object
*/ */
export const fetchRouteParamsLocation = () => { export const fetchRouteParamsLocation = () => {
try { try {
return document.location.hash.split('/').pop() || '' return document.location.hash.split('/').pop() || ''
} catch (error) { } catch (error) {
@@ -185,29 +175,19 @@ export const goHome = () => {
} }
/** /**
* * 判断是否登录 * * 判断是否登录(现阶段是有 login 数据即可)
* @return boolean * @return boolean
*/ */
export const loginCheck = () => { export const loginCheck = () => {
try { try {
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) const info = getLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
if (!info) return false if (!info) return false
if (info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_TOKEN]) { const decodeInfo = cryptoDecode(info)
if (decodeInfo) {
return true return true
} }
return false return false
} catch (error) { } catch (error) {
return false return false
} }
} }
/**
* * 预览地址
* @returns
*/
export const previewPath = (id?: string | number) => {
const { origin, pathname } = document.location
const path = fetchPathByName(PreviewEnum.CHART_PREVIEW_NAME, 'href')
const previewPath = `${origin}${pathname}${path}/${id || fetchRouteParamsLocation()}`
return previewPath
}

View File

@@ -68,41 +68,3 @@ export const getSessionStorage: (k: string) => any = (k: string) => {
export const clearSessioStorage = (name: string) => { export const clearSessioStorage = (name: string) => {
window.sessionStorage.removeItem(name) window.sessionStorage.removeItem(name)
} }
/**
* * 设置 cookie
* @param name 键名
* @param cvalue 键值
* @param exdays 过期时间
*/
export const setCookie = (name: string, cvalue: string, exdays: number) => {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
const expires = "expires=" + d.toUTCString();
document.cookie = name + "=" + cvalue + "; " + expires;
}
/**
* * 获取 cookie
* @param cname 键名
* @returns string
*/
export const getCookie = (cname: string) => {
const name = cname + "=";
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1);
if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
}
return "";
}
/**
* * 清除 cookie
* @param name 键名
* @returns string
*/
export const clearCookie = (name: string) => {
setCookie(name, "", -1);
}

View File

@@ -113,6 +113,29 @@ export const isMac = () => {
return /macintosh|mac os x/i.test(navigator.userAgent) return /macintosh|mac os x/i.test(navigator.userAgent)
} }
/**
* * file转url
*/
export const fileToUrl = (file: File): string => {
const Url = URL || window.URL || window.webkitURL
const ImageUrl = Url.createObjectURL(file)
return ImageUrl
}
/**
* * file转base64
*/
export const fileTobase64 = (file: File, callback: Function) => {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function (e: ProgressEvent<FileReader>) {
if (e.target) {
let base64 = e.target.result
callback(base64)
}
}
}
/** /**
* * 挂载监听 * * 挂载监听
*/ */

View File

@@ -1,41 +1,35 @@
<template> <template>
<div class="go-content-charts-item-animation-patch"> <div class="go-content-charts-item-box" :class="{ double: chartMode === ChartModeEnum.DOUBLE }">
<!-- 每一项组件的渲染 -->
<div <div
ref="contentChartsItemBoxRef" class="item-box"
class="go-content-charts-item-box" v-for="(item, index) in menuOptions"
:class="[chartMode === ChartModeEnum.DOUBLE ? 'double' : 'single']" :key="index"
draggable
@dragstart="dragStartHandle($event, item)"
@dragend="dragendHandle"
@dblclick="dblclickHandle(item)"
> >
<!-- 每一项组件的渲染 --> <div class="list-header">
<div <mac-os-control-btn class="list-header-control-btn" :mini="true" :disabled="true"></mac-os-control-btn>
class="item-box" <n-text class="list-header-text" depth="3">
v-for="(item, index) in menuOptions" <n-ellipsis>{{ item.title }}</n-ellipsis>
:key="index" </n-text>
draggable </div>
@dragstart="dragStartHandle($event, item)" <div class="list-center go-flex-center">
@dragend="dragendHandle" <img class="list-img" v-lazy="item.image" alt="图表图片" />
@dblclick="dblclickHandle(item)" </div>
> <div class="list-bottom">
<div class="list-header"> <n-text class="list-bottom-text" depth="3">
<mac-os-control-btn class="list-header-control-btn" :mini="true" :disabled="true"></mac-os-control-btn> <n-ellipsis style="max-width: 90%">{{ item.title }}</n-ellipsis>
<n-text class="list-header-text" depth="3"> </n-text>
<n-ellipsis>{{ item.title }}</n-ellipsis>
</n-text>
</div>
<div class="list-center go-flex-center go-transition">
<img class="list-img" v-lazy="item.image" alt="图表图片" />
</div>
<div class="list-bottom">
<n-text class="list-bottom-text" depth="3">
<n-ellipsis style="max-width: 90%">{{ item.title }}</n-ellipsis>
</n-text>
</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, watch, ref, Ref, computed, nextTick } from 'vue' import { PropType, ref, Ref, computed } from 'vue'
import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn/index' import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn/index'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d' import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@@ -57,7 +51,6 @@ defineProps({
}) })
const chartLayoutStore = useChartLayoutStore() const chartLayoutStore = useChartLayoutStore()
const contentChartsItemBoxRef = ref()
// 组件展示状态 // 组件展示状态
const chartMode: Ref<ChartModeEnum> = computed(() => { const chartMode: Ref<ChartModeEnum> = computed(() => {
@@ -99,38 +92,21 @@ const dblclickHandle = async (item: ConfigType) => {
window['$message'].warning(`图表正在研发中, 敬请期待...`) window['$message'].warning(`图表正在研发中, 敬请期待...`)
} }
} }
watch(
() => chartMode.value,
(newValue: ChartModeEnum) => {
if (newValue === ChartModeEnum.DOUBLE) {
nextTick(() => {
contentChartsItemBoxRef.value.classList.add('miniAnimation')
})
}
}
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/* 列表项宽度 */ /* 列表项宽度 */
$itemWidth: 100%; $itemWidth: 100%;
$maxItemWidth: 180px;
$halfItemWidth: 46%; $halfItemWidth: 46%;
/* 内容高度 */ /* 内容高度 */
$centerHeight: 100px; $centerHeight: 100px;
$halfCenterHeight: 50px; $halfCenterHeight: 50px;
@include go('content-charts-item-animation-patch') {
padding: 10px;
}
@include go('content-charts-item-box') { @include go('content-charts-item-box') {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
gap: 9px; gap: 9px;
transition: all 0.7s linear; padding: 10px;
.item-box { .item-box {
margin: 0; margin: 0;
width: $itemWidth; width: $itemWidth;
@@ -139,6 +115,7 @@ $halfCenterHeight: 50px;
cursor: pointer; cursor: pointer;
border: 1px solid rgba(0, 0, 0, 0); border: 1px solid rgba(0, 0, 0, 0);
@include fetch-bg-color('background-color2'); @include fetch-bg-color('background-color2');
@extend .go-transition;
&:hover { &:hover {
@include hover-border-color('background-color4'); @include hover-border-color('background-color4');
.list-img { .list-img {
@@ -175,11 +152,7 @@ $halfCenterHeight: 50px;
} }
} }
} }
&.single { /* 缩小展示 */
.item-box {
@extend .go-transition;
}
}
&.double { &.double {
.list-header { .list-header {
padding: 2px 5px; padding: 2px 5px;
@@ -192,7 +165,6 @@ $halfCenterHeight: 50px;
} }
.item-box { .item-box {
width: $halfItemWidth; width: $halfItemWidth;
max-width: $maxItemWidth;
} }
.list-center { .list-center {
height: $halfCenterHeight; height: $halfCenterHeight;
@@ -200,24 +172,11 @@ $halfCenterHeight: 50px;
.list-img { .list-img {
height: $halfCenterHeight; height: $halfCenterHeight;
width: auto; width: auto;
transition: all 0.2s;
} }
} }
.list-bottom { .list-bottom {
display: block; display: block;
} }
} }
/* 缩小展示 */
@keyframes miniAnimation {
from {
width: $itemWidth * 2;
}
to {
width: $itemWidth;
}
}
&.miniAnimation {
animation: miniAnimation 0.5s;
}
} }
</style> </style>

View File

@@ -131,20 +131,16 @@ import { backgroundImageSize } from '@/settings/designSetting'
import { FileTypeEnum } from '@/enums/fileTypeEnum' import { FileTypeEnum } from '@/enums/fileTypeEnum'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d' import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
import { StylesSetting } from '@/components/Pages/ChartItemSetting' import { StylesSetting } from '@/components/Pages/ChartItemSetting'
import { UploadCustomRequestOptions } from 'naive-ui' import { UploadCustomRequestOptions } from 'naive-ui'
import { loadAsyncComponent, fetchRouteParamsLocation } from '@/utils' import { fileToUrl, loadAsyncComponent } from '@/utils'
import { PreviewScaleEnum } from '@/enums/styleEnum' import { PreviewScaleEnum } from '@/enums/styleEnum'
import { ResultEnum } from '@/enums/httpEnum'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { uploadFile} from '@/api/path'
const { ColorPaletteIcon } = icon.ionicons5 const { ColorPaletteIcon } = icon.ionicons5
const { ScaleIcon, FitToScreenIcon, FitToHeightIcon, FitToWidthIcon } = icon.carbon const { ScaleIcon, FitToScreenIcon, FitToHeightIcon, FitToWidthIcon } = icon.carbon
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
const systemStore = useSystemStore()
const canvasConfig = chartEditStore.getEditCanvasConfig const canvasConfig = chartEditStore.getEditCanvasConfig
const editCanvas = chartEditStore.getEditCanvas const editCanvas = chartEditStore.getEditCanvas
@@ -272,30 +268,11 @@ const clearColor = () => {
// 自定义上传操作 // 自定义上传操作
const customRequest = (options: UploadCustomRequestOptions) => { const customRequest = (options: UploadCustomRequestOptions) => {
const { file } = options const { file } = options
nextTick(async () => { nextTick(() => {
if (file.file) { if (file.file) {
// 修改名称 const ImageUrl = fileToUrl(file.file)
const newNameFile = new File( chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.BACKGROUND_IMAGE, ImageUrl)
[file.file], chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.SELECT_COLOR, false)
`${fetchRouteParamsLocation()}_index_background.png`,
{ type: file.file.type }
)
let uploadParams = new FormData()
uploadParams.append('object', newNameFile)
const uploadRes = await uploadFile(uploadParams)
if(uploadRes && uploadRes.code === ResultEnum.SUCCESS) {
chartEditStore.setEditCanvasConfig(
EditCanvasConfigEnum.BACKGROUND_IMAGE,
`${systemStore.getFetchInfo.OSSUrl}${uploadRes.data.fileName}?time=${new Date().getTime()}`
)
chartEditStore.setEditCanvasConfig(
EditCanvasConfigEnum.SELECT_COLOR,
false
)
return
}
window['$message'].error('添加图片失败,请稍后重试!')
} else { } else {
window['$message'].error('添加图片失败,请稍后重试!') window['$message'].error('添加图片失败,请稍后重试!')
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="go-chart-configurations-animations" v-if="targetData"> <div class="go-chart-configurations-animations" v-if="targetData">
<n-button <n-button
class="clear-btn go-my-2" class="clear-btn"
:disabled="!targetData.styles.animations.length" :disabled="!targetData.styles.animations.length"
@click="clearAnimation" @click="clearAnimation"
> >
@@ -72,7 +72,7 @@ const addAnimation = (item: { label: string; value: string }) => {
<style lang="scss" scoped> <style lang="scss" scoped>
@include go('chart-configurations-animations') { @include go('chart-configurations-animations') {
padding: 0; padding: 20px 10px;
.clear-btn { .clear-btn {
width: 100%; width: 100%;
} }

View File

@@ -12,7 +12,7 @@
<n-input size="small" :placeholder="targetData.request.requestHttpType || '暂无'" :disabled="true"></n-input> <n-input size="small" :placeholder="targetData.request.requestHttpType || '暂无'" :disabled="true"></n-input>
</setting-item> </setting-item>
<setting-item name="组件间隔"> <setting-item name="组件间隔(高级)">
<n-input size="small" :placeholder="`${targetData.request.requestInterval || '暂无'}`" :disabled="true"> <n-input size="small" :placeholder="`${targetData.request.requestInterval || '暂无'}`" :disabled="true">
<template #suffix> {{ SelectHttpTimeNameObj[targetData.request.requestIntervalUnit] }} </template> <template #suffix> {{ SelectHttpTimeNameObj[targetData.request.requestIntervalUnit] }} </template>
</n-input> </n-input>
@@ -41,9 +41,13 @@
</n-input> </n-input>
</setting-item-box> </setting-item-box>
<n-space justify="end">
<n-text depth="3" style="font-size: 12px">更新内容请点击展示区域</n-text>
</n-space>
<div class="edit-text" @click="requestModelHandle"> <div class="edit-text" @click="requestModelHandle">
<div class="go-absolute-center"> <div class="go-absolute-center">
<n-button type="primary" secondary>编辑配置</n-button> <n-button type="primary" secondary>查看更多</n-button>
</div> </div>
</div> </div>
</n-card> </n-card>
@@ -72,16 +76,10 @@
<!-- 底部数据展示 --> <!-- 底部数据展示 -->
<chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show> <chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show>
<!-- 骨架图 --> <!-- 骨架图 -->
<go-skeleton :load="loading" :repeat="3"></go-skeleton> <go-skeleton :load="loading" :repeat="3"></go-skeleton>
<!-- 请求配置model --> <!-- 请求配置model -->
<chart-data-request <chart-data-request v-model:modelShow="requestShow" @sendHandle="sendHandle"></chart-data-request>
v-model:modelShow="requestShow"
:targetData="targetData"
@sendHandle="sendHandle"
></chart-data-request>
</div> </div>
</template> </template>
@@ -97,7 +95,7 @@ import { http, customizeHttp } from '@/api/http'
import { SelectHttpType } from '../../index.d' import { SelectHttpType } from '../../index.d'
import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow' import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
import { newFunctionHandle } from '@/utils' import { isDev, newFunctionHandle } from '@/utils'
const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5 const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5
const { targetData, chartEditStore } = useTargetData() const { targetData, chartEditStore } = useTargetData()
@@ -130,7 +128,7 @@ const sendHandle = async () => {
const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig)) const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
loading.value = false loading.value = false
if (res) { if (res) {
if (!res?.data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!') if(!res?.data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter) targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter)
showMatching.value = true showMatching.value = true
return return
@@ -177,7 +175,7 @@ onBeforeUnmount(() => {
top: 0px; top: 0px;
left: 0px; left: 0px;
width: 325px; width: 325px;
height: 270px; height: 292px;
cursor: pointer; cursor: pointer;
opacity: 0; opacity: 0;
transition: all 0.3s; transition: all 0.3s;

View File

@@ -117,7 +117,7 @@ const { uploadFileListRef, customRequest, beforeUpload, download } = useFile(tar
// 是否展示过滤器 // 是否展示过滤器
const filterShow = computed(() => { const filterShow = computed(() => {
return targetData.value.request.requestDataType !== RequestDataTypeEnum.STATIC return targetData.value.request.requestDataType === RequestDataTypeEnum.AJAX
}) })
// 是支持 dataset 的图表类型 // 是支持 dataset 的图表类型

View File

@@ -34,7 +34,7 @@
</template> </template>
<!-- 弹窗 --> <!-- 弹窗 -->
<n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false" :closeOnEsc="false"> <n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false">
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 600px"> <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 600px">
<template #header> <template #header>
<n-space> <n-space>
@@ -101,7 +101,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch, toRef, toRefs, toRaw, reactive } from 'vue' import { ref, computed, watch, toRefs, toRaw } from 'vue'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
import { MonacoEditor } from '@/components/Pages/MonacoEditor' import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { icon } from '@/plugins' import { icon } from '@/plugins'
@@ -187,10 +187,7 @@ const saveFilter = () => {
watch( watch(
() => showModal.value, () => showModal.value,
(newData: boolean) => { (newData: boolean) => {
if (newData) { if (newData) fetchTargetData()
fetchTargetData()
filter.value = targetData.value.filter || `return data`
}
} }
) )
</script> </script>

View File

@@ -1,64 +0,0 @@
<template>
<n-table
:bordered="false"
:single-line="false"
size="small"
style="border-bottom-right-radius: 7px; border-bottom-left-radius: 7px"
>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableArray.content" :key="index">
<td>
{{ item.key || '暂无'}}
</td>
<td>
{{ item.value || '暂无'}}
</td>
</tr>
</tbody>
</n-table>
</template>
<script setup lang="ts">
import { PropType, reactive, ref, toRefs, watch } from 'vue'
import { RequestParamsObjType } from '@/enums/httpEnum'
import noData from '@/assets/images/canvas/noData.png'
const props = defineProps({
target: Object as PropType<RequestParamsObjType>
})
// 默认表格
const defaultItem = {
key: '',
value: ''
}
const tableArray = reactive<{
content: typeof defaultItem[]
}>({ content: [] })
// 监听选项
watch(
() => props.target as RequestParamsObjType,
(target: RequestParamsObjType) => {
tableArray.content = []
for (const k in target) {
tableArray.content.push({
key: k,
value: target[k]
})
}
// 默认值
if (!tableArray.content.length) tableArray.content = [JSON.parse(JSON.stringify(defaultItem))]
},
{
immediate: true,
deep: true
}
)
</script>

View File

@@ -1,3 +0,0 @@
import ChartDataDisplay from './index.vue'
export { ChartDataDisplay }

View File

@@ -1,191 +0,0 @@
<template>
<div class="go-chart-data-display">
<n-scrollbar style="max-height: 570px">
<div class="go-mr-3">
<div>
<setting-item-box name="主体信息">
<setting-item name="接口名称">
<n-input size="small" :placeholder="targetData?.dataPondName || '暂无'" :disabled="true"> </n-input>
</setting-item>
<setting-item name="接口类型">
<n-input size="small" :placeholder="requestHttpType || '暂无'" :disabled="true"></n-input>
</setting-item>
</setting-item-box>
<setting-item-box>
<setting-item name="组件间隔">
<n-input size="small" :placeholder="`${requestInterval || '暂无'}`" :disabled="true">
<template #suffix>
{{ targetData && SelectHttpTimeNameObj[requestIntervalUnit] }}
</template>
</n-input>
</setting-item>
<setting-item name="全局间隔(默认)">
<n-input size="small" :placeholder="`${globalData?.requestInterval || '暂无'}`" :disabled="true">
<template #suffix> {{ globalData && SelectHttpTimeNameObj[globalData.requestIntervalUnit] }} </template>
</n-input>
</setting-item>
</setting-item-box>
<setting-item-box name="源地址" :alone="true">
<n-input size="small" :placeholder="globalData?.requestOriginUrl || '暂无'" :disabled="true">
<template #prefix>
<n-icon :component="PulseIcon" />
</template>
</n-input>
</setting-item-box>
<setting-item-box name="接口地址" :alone="true">
<n-input
size="small"
:placeholder="requestUrl || '暂无'"
:disabled="true"
>
<template #prefix>
<n-icon :component="FlashIcon" />
</template>
</n-input>
</setting-item-box>
</div>
<n-divider />
<setting-item-box name="类型">
<setting-item name="配置类型">
<n-input
size="small"
:placeholder="targetData && requestContentTypeObj[requestContentType]"
:disabled="true"
></n-input>
</setting-item>
<setting-item name="body 类型" v-if="requestContentType === RequestContentTypeEnum.DEFAULT">
<n-input size="small" :placeholder="targetData && requestParamsBodyType" :disabled="true"></n-input>
</setting-item>
</setting-item-box>
<div v-if="requestContentType === RequestContentTypeEnum.DEFAULT">
<n-tabs type="line" animated v-model:value="tabValue">
<n-tab v-for="item in RequestParamsTypeEnum" :key="item" :name="item" :tab="item"> {{ item }} </n-tab>
</n-tabs>
<!-- 各个页面 -->
<div class="go-mt-3">
<div v-if="tabValue !== RequestParamsTypeEnum.BODY">
<display-table class="go-my-3" :target="requestParams[tabValue]"> </display-table>
</div>
<!-- 选择了 body -->
<div v-else>
<!-- none -->
<n-card class="go-mt-3 go-pb-3" v-if="requestParamsBodyType === RequestBodyEnum['NONE']">
<n-text depth="3">该接口没有 Body </n-text>
</n-card>
<!-- 具有对象属性时 -->
<template
v-else-if="
requestParamsBodyType === RequestBodyEnum['FORM_DATA'] ||
requestParamsBodyType === RequestBodyEnum['X_WWW_FORM_URLENCODED']
"
>
<display-table
class="go-my-3"
:target="requestParams[RequestParamsTypeEnum.BODY][requestParamsBodyType]"
></display-table>
</template>
<!-- json -->
<template v-else-if="requestParamsBodyType === RequestBodyEnum['JSON']">
<n-card size="small" style="padding-bottom: 7px">
<n-code
:code="requestParams[RequestParamsTypeEnum.BODY][requestParamsBodyType] || '暂无内容'"
language="json"
></n-code>
</n-card>
</template>
<!-- xml -->
<template v-else-if="requestParamsBodyType === RequestBodyEnum['XML']">
<n-code
:code="requestParams[RequestParamsTypeEnum.BODY][requestParamsBodyType] || ''"
language="html"
></n-code>
</template>
</div>
</div>
</div>
<!-- SQL 请求 -->
<div v-else>
<setting-item-box name="键名">
<n-text>sql</n-text>
</setting-item-box>
<setting-item-box name="键值">
<n-code :code="requestSQLContent.sql || ''" language="sql"></n-code>
</setting-item-box>
</div>
</div>
</n-scrollbar>
</div>
</template>
<script setup lang="ts">
import { PropType, ref, toRefs } from 'vue'
import { icon } from '@/plugins'
import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { RequestDataPondItemType, RequestGlobalConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
import displayTable from './displayTable.vue'
import {
RequestBodyEnum,
RequestParamsTypeEnum,
SelectHttpTimeNameObj,
RequestContentTypeEnum,
RequestBodyEnumList,
RequestParamsObjType
} from '@/enums/httpEnum'
const props = defineProps({
globalData: Object as PropType<RequestGlobalConfigType>,
targetData: Object as PropType<RequestDataPondItemType>
})
const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5
const {
requestUrl,
requestInterval,
requestHttpType,
requestContentType,
requestSQLContent,
requestParams,
requestParamsBodyType,
requestIntervalUnit
} = toRefs((props.targetData as RequestDataPondItemType).dataPondRequestConfig)
const tabs = [RequestParamsTypeEnum.HEADER]
const requestContentTypeObj = {
[RequestContentTypeEnum.DEFAULT]: '普通请求',
[RequestContentTypeEnum.SQL]: 'SQL 请求'
}
const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS)
// 更新参数表格数据
const updateRequestParams = (paramsObj: RequestParamsObjType) => {
if (tabValue.value !== RequestParamsTypeEnum.BODY) {
requestParams.value[tabValue.value] = paramsObj
}
}
// 更新参数表格数据
const updateRequestBodyTable = (paramsObj: RequestParamsObjType) => {
if (
tabValue.value === RequestParamsTypeEnum.BODY &&
// 仅有两种类型有 body
(requestParamsBodyType.value === RequestBodyEnum.FORM_DATA ||
requestParamsBodyType.value === RequestBodyEnum.X_WWW_FORM_URLENCODED)
) {
requestParams.value[RequestParamsTypeEnum.BODY][requestParamsBodyType.value] = paramsObj
}
}
</script>
<style lang="scss" scoped>
@include go('chart-data-display') {
flex: 1;
}
</style>

View File

@@ -1,3 +0,0 @@
import ChartDataPondControl from './index.vue'
export { ChartDataPondControl }

View File

@@ -1,230 +0,0 @@
<template>
<n-modal class="go-chart-data-pond-control" v-model:show="modelShow" :mask-closable="false">
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 900px; height: 650px">
<template #header></template>
<template #header-extra> </template>
<div class="pond-content">
<!-- 展示区域 -->
<chart-data-display
v-if="pondData && !loading"
:targetData="pondData"
:globalData="chartEditStore.getRequestGlobalConfig"
></chart-data-display>
<!-- 无数据 -->
<div v-else class="no-data go-flex-center">
<img :src="noData" alt="暂无数据" />
<n-text :depth="3">暂未选择公共接口</n-text>
</div>
<!-- 左侧列表 -->
<chart-data-pond-list @createPond="createPond" @deletePond="deletePond"></chart-data-pond-list>
</div>
<!-- 底部 -->
<template #action>
<n-space justify="space-between">
<n-button type="info" secondary :disabled="!pondData" @click="openPond(true)">
编辑内容
<template #icon>
<n-icon>
<pencil-icon />
</n-icon>
</template>
</n-button>
<n-button type="primary" @click="closeHandle">保存 & 发送请求</n-button>
</n-space>
</template>
</n-card>
</n-modal>
<!-- 请求配置model -->
<pond-data-request
v-if="requestShow"
v-model:modelShow="requestShow"
:targetDataRequest="editData"
:isEdit="isEdit"
@editSaveHandle="saveHandle"
></pond-data-request>
</template>
<script setup lang="ts">
import { ref, toRefs, computed, nextTick, watch, toRaw } from 'vue'
import noData from '@/assets/images/canvas/noData.png'
import { ChartDataPondList } from '../ChartDataPondList'
import { PondDataRequest } from '../../../ChartDataRequest'
import { ChartDataDisplay } from '../ChartDataDisplay'
import { requestConfig } from '@/packages/public/publicConfig'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { RequestDataTypeEnum } from '@/enums/httpEnum'
import { icon } from '@/plugins'
import { getUUID, goDialog } from '@/utils'
import { cloneDeep } from 'lodash'
defineProps({
modelShow: Boolean
})
const emit = defineEmits(['update:modelShow', 'sendHandle'])
const { PencilIcon } = icon.ionicons5
const { chartEditStore, targetData } = useTargetData()
const { requestDataPond } = toRefs(chartEditStore.getRequestGlobalConfig)
const requestShow = ref(false)
const loading = ref(false)
const isEdit = ref(false)
const editData = ref<RequestDataPondItemType>()
// 所选数据池
const pondData = computed(() => {
const selectId = targetData?.value?.request?.requestDataPondId
if (!selectId) return undefined
const data = requestDataPond.value.filter(item => {
return selectId === item.dataPondId
})
return data[0]
})
watch(
() => pondData.value,
newValue => {
loading.value = true
editData.value = newValue
nextTick(() => {
loading.value = false
})
},
{
immediate: true
}
)
// 打开/编辑
const openPond = (isEditFlag: boolean = false) => {
isEdit.value = !!isEditFlag
requestShow.value = true
}
// 创建
const createPond = () => {
const id = getUUID()
editData.value = {
dataPondId: id,
dataPondName: id,
dataPondRequestConfig: cloneDeep({ ...requestConfig, requestDataType: RequestDataTypeEnum.Pond })
}
openPond()
}
// 完成创建/编辑
const saveHandle = (newData: RequestDataPondItemType) => {
// 走创建
if (isEdit.value) {
editSaveHandle(newData)
} else {
createSaveHandle(newData)
}
isEdit.value = false
requestShow.value = false
}
// 编辑保存之后
const editSaveHandle = (newData: RequestDataPondItemType) => {
try {
const targetIndex = requestDataPond.value.findIndex(item => item.dataPondId === newData.dataPondId)
if (targetIndex !== -1) {
requestDataPond.value.splice(targetIndex, 1, newData)
// 修改数据池后, 修改所有关联的组件
chartEditStore.getComponentList.forEach(item => {
if (
item.request.requestDataType === RequestDataTypeEnum.Pond &&
item.request.requestDataPondId === newData.dataPondId
) {
item.request = {
...toRaw(newData.dataPondRequestConfig),
requestDataPondId: newData.dataPondId
}
}
})
window.$message.success('保存成功!')
} else {
window.$message.error('编辑失败,请稍后重试!')
}
} catch (error) {
window.$message.error('编辑失败,请稍后重试!')
}
}
// 创建保存成功之后
const createSaveHandle = (newData: RequestDataPondItemType) => {
try {
if (editData.value) {
requestDataPond.value.unshift(newData)
window.$message.success('创建成功!')
} else {
window.$message.error('创建失败,请稍后重试!')
}
} catch (error) {
window.$message.error('创建失败,请稍后重试!')
}
}
// 删除数据池
const deletePond = (targetData: RequestDataPondItemType) => {
goDialog({
message: '删除数据后,需手动处理使用改接口的组件,是否继续?',
isMaskClosable: true,
transformOrigin: 'center',
onPositiveCallback: () => {
const targetIndex = requestDataPond.value.findIndex(item => item.dataPondId === targetData.dataPondId)
if (targetIndex !== -1) {
requestDataPond.value.splice(targetIndex, 1)
window.$message.success('删除成功!')
} else {
window.$message.error('删除失败,请稍后重试!')
}
}
})
}
// 关闭
const closeHandle = () => {
// 将所选内容赋值给对象
if (pondData.value) {
targetData.value.request = {
...toRaw(pondData.value.dataPondRequestConfig),
requestDataPondId: pondData.value.dataPondId
}
}
emit('update:modelShow', false)
emit('sendHandle')
}
</script>
<style lang="scss" scoped>
@include go('chart-data-pond-control') {
/* 中间 */
.pond-content {
display: flex;
}
.no-data {
flex-direction: column;
width: 100%;
img {
width: 200px;
}
}
&.n-card.n-modal,
.n-card {
@extend .go-background-filter;
}
.n-card-shallow {
background-color: rgba(0, 0, 0, 0) !important;
}
@include deep() {
& > .n-card__content {
padding-right: 0;
}
.n-card__content {
padding-bottom: 5px;
}
}
}
</style>

View File

@@ -1,3 +0,0 @@
import ChartDataPondList from './index.vue'
export { ChartDataPondList }

View File

@@ -1,202 +0,0 @@
<template>
<div class="go-chart-data-pond-list">
<n-timeline style="width: 20px">
<n-timeline-item type="info"> </n-timeline-item>
<n-timeline-item type="success"></n-timeline-item>
</n-timeline>
<div class="pond-item-box">
<!-- 新增 -->
<n-button class="create-btn go-py-4" ghost @click="createPond">
<span> 创建 </span>
<template #icon>
<n-icon>
<DuplicateOutlineIcon></DuplicateOutlineIcon>
</n-icon>
</template>
</n-button>
<n-divider style="margin: 10px 0"></n-divider>
<n-space v-if="!requestDataPond.length" justify="center">
<n-text class="not-layer-text" :depth="3">
暂无数据内容
<n-a @click="createPond">立即创建</n-a>
</n-text>
</n-space>
<n-scrollbar style="max-height: 490px">
<div
v-for="item in requestDataPond"
:key="item.dataPondId"
:class="{ select: item.dataPondId === selectPondId }"
class="pond-item"
@click="clickHandle(item)"
>
<div class="item-content">
<div class="item-content-body">
<div>
<n-tag class="go-mr-1" :type="item.dataPondId === selectPondId ? 'warning' : ''" :bordered="false">
名称
</n-tag>
<n-ellipsis style="max-width: 180px">
{{ item.dataPondName || '暂无' }}
</n-ellipsis>
</div>
<div>
<n-tag class="go-mr-1" :type="item.dataPondId === selectPondId ? 'warning' : ''" :bordered="false">
地址
</n-tag>
<n-ellipsis style="max-width: 180px">
{{ item.dataPondRequestConfig.requestUrl || '暂无' }}
</n-ellipsis>
</div>
</div>
<div class="item-content-icon go-transition-quick" @click="deletePond($event, item)">
<n-icon>
<trash-icon></trash-icon>
</n-icon>
</div>
</div>
<div :class="{ 'select-modal': item.dataPondId === selectPondId }"></div>
</div>
</n-scrollbar>
</div>
</div>
</template>
<script setup lang="ts">
import { toRefs, computed } from 'vue'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { icon } from '@/plugins'
const emit = defineEmits(['createPond', 'deletePond'])
const { DuplicateOutlineIcon, TrashIcon } = icon.ionicons5
const designStore = useDesignStore()
const { chartEditStore, targetData } = useTargetData()
const { requestDataPond } = toRefs(chartEditStore.getRequestGlobalConfig)
// 选中的全局数据
const selectPondId = computed(() => {
return targetData.value.request.requestDataPondId
})
// 颜色
const themeColor = computed(() => {
return designStore.getAppTheme
})
// 创建数据池
const createPond = () => {
emit('createPond', true)
}
// 删除数据池
const deletePond = (target: Event, targetData: RequestDataPondItemType) => {
target.stopPropagation()
target.preventDefault()
emit('deletePond', targetData)
}
// 选中
const clickHandle = (item: RequestDataPondItemType) => {
targetData.value.request.requestDataPondId = item.dataPondId
}
</script>
<style scoped lang="scss">
$height: 530px;
$listWidth: 280px;
$centerHeight: 60px;
$centerMiniHeight: 28px;
$textSize: 10px;
@include go('chart-data-pond-list') {
padding-top: 10px;
padding-bottom: 5px;
margin-right: 5px;
display: flex;
@include deep() {
.n-timeline > .n-timeline-item {
&:first-child {
height: $height;
}
}
}
.pond-item-box {
width: $listWidth;
position: relative;
.create-btn {
width: calc(#{$listWidth - 15px});
margin-right: 15px;
}
.pond-item {
position: relative;
height: $centerHeight;
padding: 5px;
margin-bottom: 10px;
margin-right: 15px;
border-radius: 5px;
cursor: pointer;
border: 1px solid rgba(0, 0, 0, 0);
@include fetch-bg-color('background-color3');
@extend .go-transition-quick;
&.hover,
&:hover {
@include fetch-bg-color('background-color4');
}
&:hover {
@include deep() {
.icon-item {
opacity: 1;
}
}
.item-content-icon {
opacity: 1 !important;
}
}
&.select {
border: 1px solid v-bind('themeColor');
background-color: rgba(0, 0, 0, 0);
.item-content-icon {
display: none;
}
}
.select-modal,
.item-content {
position: absolute;
top: 0;
left: 0;
}
.item-content {
z-index: 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px;
.item-content-body {
width: 230px;
display: flex;
flex-direction: column;
gap: 5px;
}
.item-content-icon {
opacity: 0;
height: $centerHeight;
line-height: $centerHeight;
padding-left: 5px;
}
}
.select-modal {
width: 100%;
height: 100%;
opacity: 0.3;
background-color: v-bind('themeColor');
}
}
}
}
</style>

View File

@@ -1,3 +0,0 @@
import ChartDataPond from './index.vue'
export { ChartDataPond }

View File

@@ -1,185 +0,0 @@
<template>
<!-- 选中内容 -->
<div class="go-chart-data-pond">
<n-card class="n-card-shallow">
<setting-item-box name="请求名称" :alone="true">
<n-input size="small" :placeholder="pondData?.dataPondName || '暂无'" :disabled="true">
<template #prefix>
<n-icon :component="FishIcon" />
</template>
</n-input>
</setting-item-box>
<setting-item-box name="接口地址" :alone="true">
<n-input size="small" :placeholder="pondData?.dataPondRequestConfig.requestUrl || '暂无'" :disabled="true">
<template #prefix>
<n-icon :component="FlashIcon" />
</template>
</n-input>
</setting-item-box>
<div class="edit-text" @click="controlModelHandle">
<div class="go-absolute-center">
<n-button type="primary" secondary>编辑配置</n-button>
</div>
</div>
</n-card>
</div>
<setting-item-box :alone="true">
<template #name>
测试
<n-tooltip trigger="hover">
<template #trigger>
<n-icon size="21" :depth="3">
<help-outline-icon></help-outline-icon>
</n-icon>
</template>
默认赋值给 dataset 字段
</n-tooltip>
</template>
<n-button type="primary" ghost @click="sendHandle">
<template #icon>
<n-icon>
<flash-icon />
</n-icon>
</template>
发送请求
</n-button>
</setting-item-box>
<!-- 底部数据展示 -->
<chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show>
<!-- 骨架图 -->
<go-skeleton :load="loading" :repeat="3"></go-skeleton>
<!-- 编辑 / 新增弹窗 -->
<chart-data-pond-control v-model:modelShow="controlModel" @sendHandle="sendHandle"></chart-data-pond-control>
</template>
<script setup lang="ts">
import { ref, toRefs, toRaw, onBeforeUnmount, computed, watchEffect } from 'vue'
import { icon } from '@/plugins'
import { http, customizeHttp } from '@/api/http'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { ChartDataPondControl } from './components/ChartDataPondControl'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useTargetData } from '../../../hooks/useTargetData.hook'
import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow'
import { newFunctionHandle } from '@/utils'
const designStore = useDesignStore()
const { HelpOutlineIcon, FlashIcon, PulseIcon, FishIcon } = icon.ionicons5
const { targetData, chartEditStore } = useTargetData()
const {
requestDataPond,
requestInterval: GlobalRequestInterval,
requestIntervalUnit: GlobalRequestIntervalUnit
} = toRefs(chartEditStore.getRequestGlobalConfig)
const loading = ref(false)
const controlModel = ref(false)
const showMatching = ref(false)
let firstFocus = 0
let lastFilter: any = undefined
// 所选数据池
const pondData = computed(() => {
const selectId = targetData.value.request.requestDataPondId
if (!selectId) return undefined
const data = requestDataPond.value.filter(item => {
return selectId === item.dataPondId
})
return data[0]
})
// 颜色
const themeColor = computed(() => {
return designStore.getAppTheme
})
// 请求配置 model
const controlModelHandle = () => {
controlModel.value = true
}
// 发送请求
const sendHandle = async () => {
if (!targetData.value?.request) {
window.$message.warning('请选择一个公共接口!')
return
}
loading.value = true
try {
// const res = await customizeHttp(
// toRaw(pondData.value?.dataPondRequestConfig),
// toRaw(chartEditStore.getRequestGlobalConfig)
// )
const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
loading.value = false
if (res) {
if (!res?.data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter)
showMatching.value = true
return
}
window['$message'].warning('数据异常,请检查参数!')
} catch (error) {
loading.value = false
window['$message'].warning('数据异常,请检查参数!')
}
}
watchEffect(() => {
const filter = targetData.value?.filter
if (lastFilter !== filter && firstFocus) {
lastFilter = filter
sendHandle()
}
firstFocus++
})
onBeforeUnmount(() => {
lastFilter = null
})
</script>
<style scoped lang="scss">
@include go('chart-data-pond') {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
.n-card-shallow {
&.n-card {
@extend .go-background-filter;
@include deep() {
.n-card__content {
padding: 10px;
}
}
}
.edit-text {
position: absolute;
top: 0px;
left: 0px;
width: 325px;
height: 136px;
cursor: pointer;
opacity: 0;
transition: all 0.3s;
@extend .go-background-filter;
backdrop-filter: blur(2px) !important;
}
&:hover {
border-color: v-bind('themeColor');
.edit-text {
opacity: 1;
}
}
}
}
</style>

View File

@@ -1,7 +1,7 @@
<template> <template>
<!-- 全局配置 --> <!-- 全局配置 -->
<n-card class="n-card-shallow"> <n-card class="n-card-shallow">
<n-tag type="info" :bordered="false" style="border-radius: 5px"> 全局公共配置 </n-tag> <n-tag type="info" :bordered="false" style="border-radius: 5px"> 全局配置 </n-tag>
<setting-item-box <setting-item-box
name="服务" name="服务"
:itemRightStyle="{ :itemRightStyle="{

View File

@@ -29,7 +29,7 @@
<!-- none --> <!-- none -->
<n-card class="go-mt-3 go-pb-3" v-if="requestParamsBodyType === RequestBodyEnum['NONE']"> <n-card class="go-mt-3 go-pb-3" v-if="requestParamsBodyType === RequestBodyEnum['NONE']">
<n-text depth="3">接口没有 Body </n-text> <n-text depth="3">请求没有 Body </n-text>
</n-card> </n-card>
<!-- 具有对象属性时 --> <!-- 具有对象属性时 -->
@@ -86,12 +86,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRefs, PropType } from 'vue' import { ref, toRefs } from 'vue'
import { MonacoEditor } from '@/components/Pages/MonacoEditor' import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { RequestHeaderTable } from '../RequestHeaderTable/index'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook' import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d' import { RequestHeaderTable } from '../RequestHeaderTable/index'
import { import {
RequestParamsTypeEnum, RequestParamsTypeEnum,
RequestContentTypeEnum, RequestContentTypeEnum,
@@ -101,13 +102,9 @@ import {
RequestHttpEnum RequestHttpEnum
} from '@/enums/httpEnum' } from '@/enums/httpEnum'
const props = defineProps({ const { targetData } = useTargetData()
targetDataRequest: Object as PropType<RequestConfigType>
})
const { requestHttpType, requestContentType, requestSQLContent, requestParams, requestParamsBodyType } = toRefs( const { requestHttpType, requestContentType, requestSQLContent, requestParams, requestParamsBodyType } = toRefs(targetData.value.request)
props.targetDataRequest as RequestConfigType
)
const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS) const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS)

View File

@@ -5,7 +5,7 @@
:itemRightStyle="{ :itemRightStyle="{
gridTemplateColumns: '6fr 2fr' gridTemplateColumns: '6fr 2fr'
}" }"
style="padding-right: 25px" style="padding-right: 25px;"
> >
<template #name> <template #name>
地址 地址
@@ -51,16 +51,15 @@
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="选择方式" class="go-mt-0"> <setting-item-box name="选择方式" class="go-mt-0">
<request-header :targetDataRequest="targetDataRequest"></request-header> <request-header></request-header>
</setting-item-box> </setting-item-box>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { PropType, toRefs } from 'vue' import { ref, toRefs } from 'vue'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook' import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { selectTypeOptions, selectTimeOptions } from '@/views/chart/ContentConfigurations/components/ChartData/index.d' import { selectTypeOptions, selectTimeOptions } from '@/views/chart/ContentConfigurations/components/ChartData/index.d'
import { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { RequestHeader } from '../RequestHeader' import { RequestHeader } from '../RequestHeader'
import { isDev } from '@/utils' import { isDev } from '@/utils'
import { icon } from '@/plugins' import { icon } from '@/plugins'
@@ -83,16 +82,10 @@ import {
threeEarth01Url threeEarth01Url
} from '@/api/mock' } from '@/api/mock'
const props = defineProps({
targetDataRequest: Object as PropType<RequestConfigType>
})
const { HelpOutlineIcon } = icon.ionicons5 const { HelpOutlineIcon } = icon.ionicons5
const { chartEditStore } = useTargetData() const { targetData, chartEditStore } = useTargetData()
const { requestOriginUrl } = toRefs(chartEditStore.getRequestGlobalConfig) const { requestOriginUrl } = toRefs(chartEditStore.getRequestGlobalConfig)
const { requestInterval, requestIntervalUnit, requestHttpType, requestUrl } = toRefs( const { requestInterval, requestIntervalUnit, requestHttpType, requestUrl } = toRefs(targetData.value.request)
props.targetDataRequest as RequestConfigType
)
const apiList = [ const apiList = [
{ {

View File

@@ -1,4 +1,3 @@
import ChartDataRequest from './index.vue' import ChartDataRequest from './index.vue'
import PondDataRequest from './pondIndex.vue'
export { ChartDataRequest, PondDataRequest } export { ChartDataRequest }

View File

@@ -1,5 +1,5 @@
<template> <template>
<n-modal class="go-chart-data-request" v-model:show="modelShow" :mask-closable="false" :closeOnEsc="false"> <n-modal class="go-chart-data-request" v-model:show="modelShow" :mask-closable="false">
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 800px"> <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 800px">
<template #header></template> <template #header></template>
<template #header-extra> </template> <template #header-extra> </template>
@@ -7,7 +7,7 @@
<div class="go-pr-3"> <div class="go-pr-3">
<n-space vertical> <n-space vertical>
<request-global-config></request-global-config> <request-global-config></request-global-config>
<request-target-config :target-data-request="targetData?.request"></request-target-config> <request-target-config></request-target-config>
</n-space> </n-space>
</div> </div>
</n-scrollbar> </n-scrollbar>
@@ -17,11 +17,9 @@
<div> <div>
<n-text> {{ chartConfig.categoryName }} </n-text> <n-text> {{ chartConfig.categoryName }} </n-text>
<n-text> </n-text> <n-text> </n-text>
<n-tag type="primary" :bordered="false" style="border-radius: 5px"> <n-tag type="primary" :bordered="false" style="border-radius: 5px"> {{ requestContentTypeObj[requestContentType] }} </n-tag>
{{ requestContentTypeObj[requestContentType] }}
</n-tag>
</div> </div>
<n-button type="primary" @click="closeAndSendHandle"> {{ saveBtnText || '保存 & 发送请求' }}</n-button> <n-button type="primary" @click="closeHandle">保存 & 发送请求</n-button>
</n-space> </n-space>
</template> </template>
</n-card> </n-card>
@@ -29,40 +27,30 @@
</template> </template>
<script script lang="ts" setup> <script script lang="ts" setup>
import { toRefs, PropType } from 'vue' import { toRefs } from 'vue'
import { RequestContentTypeEnum } from '@/enums/httpEnum' import { RequestContentTypeEnum } from '@/enums/httpEnum'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
import { RequestGlobalConfig } from './components/RequestGlobalConfig' import { RequestGlobalConfig } from './components/RequestGlobalConfig'
import { RequestTargetConfig } from './components/RequestTargetConfig' import { RequestTargetConfig } from './components/RequestTargetConfig'
import { useSync } from '@/views/chart/hooks/useSync.hook'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
const props = defineProps({
modelShow: Boolean,
targetData: Object as PropType<CreateComponentType>,
saveBtnText: String || null
})
const emit = defineEmits(['update:modelShow', 'sendHandle']) const emit = defineEmits(['update:modelShow', 'sendHandle'])
const { targetData } = useTargetData() const { targetData } = useTargetData()
const { dataSyncUpdate } = useSync()
// 解构基础配置 // 解构基础配置
const { chartConfig } = toRefs(props.targetData as CreateComponentType) const { chartConfig } = toRefs(targetData.value)
const { requestContentType } = toRefs((props.targetData as CreateComponentType).request) const { requestContentType } = toRefs(targetData.value.request)
const requestContentTypeObj = { const requestContentTypeObj = {
[RequestContentTypeEnum.DEFAULT]: '普通请求', [RequestContentTypeEnum.DEFAULT]: '普通请求',
[RequestContentTypeEnum.SQL]: 'SQL 请求' [RequestContentTypeEnum.SQL]: 'SQL 请求'
} }
defineProps({
modelShow: Boolean
})
const closeHandle = () => { const closeHandle = () => {
emit('update:modelShow', false) emit('update:modelShow', false)
}
const closeAndSendHandle = () => {
emit('update:modelShow', false)
emit('sendHandle') emit('sendHandle')
dataSyncUpdate()
} }
</script> </script>

View File

@@ -1,105 +0,0 @@
<template>
<n-modal class="go-chart-data-request" v-model:show="modelShow" :mask-closable="false" :closeOnEsc="false">
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 800px">
<template #header></template>
<template #header-extra> </template>
<n-scrollbar style="max-height: 718px">
<div class="go-pr-3">
<n-space vertical>
<request-global-config></request-global-config>
<request-target-config
:target-data-request="targetDataRequest?.dataPondRequestConfig"
></request-target-config>
</n-space>
</div>
</n-scrollbar>
<!-- 底部 -->
<template #action>
<n-space justify="space-between">
<n-space v-if="targetDataRequest">
<n-tag :bordered="false" type="primary">名称</n-tag>
<n-input
v-model:value="targetDataRequest.dataPondName"
ref="inputInstRef"
type="text"
size="small"
:autofocus="true"
:clearable="true"
:minlength="1"
:maxlength="16"
placeholder="请输入名称"
></n-input>
</n-space>
<span v-else></span>
<n-space>
<n-button @click="closeHandle">取消</n-button>
<n-button type="primary" @click="closeAndSendHandle">保存</n-button>
</n-space>
</n-space>
</template>
</n-card>
</n-modal>
</template>
<script script lang="ts" setup>
import { PropType, ref, watchEffect } from 'vue'
import { RequestContentTypeEnum } from '@/enums/httpEnum'
import { useTargetData } from '../../../hooks/useTargetData.hook'
import { RequestGlobalConfig } from './components/RequestGlobalConfig'
import { RequestTargetConfig } from './components/RequestTargetConfig'
import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useSync } from '@/views/chart/hooks/useSync.hook'
import { goDialog } from '@/utils'
const props = defineProps({
modelShow: Boolean,
targetDataRequest: Object as PropType<RequestDataPondItemType>
})
const emit = defineEmits(['update:modelShow', 'editSaveHandle'])
const { dataSyncUpdate } = useSync()
const pondName = ref()
const inputInstRef = ref()
const closeHandle = () => {
emit('update:modelShow', false)
}
const closeAndSendHandle = () => {
if (!props.targetDataRequest?.dataPondName) {
window.$message.warning('请在左下角输入名称!')
inputInstRef.value?.focus()
return
}
goDialog({
message: '保存内容将同步修改所有使用此接口的组件, 是否继续?',
isMaskClosable: true,
transformOrigin: 'center',
onPositiveCallback: () => {
emit('update:modelShow', false)
emit('editSaveHandle', props.targetDataRequest)
dataSyncUpdate()
}
})
}
</script>
<style lang="scss" scoped>
@include go('chart-data-request') {
&.n-card.n-modal,
.n-card {
@extend .go-background-filter;
}
.n-card-shallow {
background-color: rgba(0, 0, 0, 0) !important;
}
@include deep() {
& > .n-card__content {
padding-right: 0;
}
.n-card__content {
padding-bottom: 5px;
}
}
}
</style>

View File

@@ -16,7 +16,6 @@ export enum TimelineTitleEnum {
export enum SelectCreateDataEnum { export enum SelectCreateDataEnum {
STATIC = '静态数据', STATIC = '静态数据',
AJAX = '动态请求', AJAX = '动态请求',
Pond = '公共接口',
} }
export interface SelectCreateDataType { export interface SelectCreateDataType {

View File

@@ -3,27 +3,24 @@
<setting-item-box name="请求方式" :alone="true"> <setting-item-box name="请求方式" :alone="true">
<n-select v-model:value="targetData.request.requestDataType" :disabled="isNotData" :options="selectOptions" /> <n-select v-model:value="targetData.request.requestDataType" :disabled="isNotData" :options="selectOptions" />
</setting-item-box> </setting-item-box>
<!-- 静态 --> <!-- 静态 -->
<chart-data-static v-if="targetData.request.requestDataType === RequestDataTypeEnum.STATIC"></chart-data-static> <chart-data-static v-if="targetData.request.requestDataType === RequestDataTypeEnum.STATIC"></chart-data-static>
<!-- 动态 --> <!-- 动态 -->
<chart-data-ajax v-if="targetData.request.requestDataType === RequestDataTypeEnum.AJAX"></chart-data-ajax> <chart-data-ajax v-else></chart-data-ajax>
<!-- 数据池 -->
<chart-data-pond v-if="targetData.request.requestDataType === RequestDataTypeEnum.Pond"></chart-data-pond>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import { loadAsyncComponent } from '@/utils'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting' import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '../hooks/useTargetData.hook' import { useTargetData } from '../hooks/useTargetData.hook'
import { ChartDataStatic } from './components/ChartDataStatic/index'
import { ChartDataAjax } from './components/ChartDataAjax/index'
import { SelectCreateDataType, SelectCreateDataEnum } from './index.d' import { SelectCreateDataType, SelectCreateDataEnum } from './index.d'
import { RequestDataTypeEnum } from '@/enums/httpEnum' import { RequestDataTypeEnum } from '@/enums/httpEnum'
const ChartDataStatic = loadAsyncComponent(() => import('./components/ChartDataStatic/index.vue'))
const ChartDataAjax = loadAsyncComponent(() => import('./components/ChartDataAjax/index.vue'))
const ChartDataPond = loadAsyncComponent(() => import('./components/ChartDataPond/index.vue'))
const { targetData } = useTargetData() const { targetData } = useTargetData()
// 选项 // 选项
@@ -35,10 +32,6 @@ const selectOptions: SelectCreateDataType[] = [
{ {
label: SelectCreateDataEnum.AJAX, label: SelectCreateDataEnum.AJAX,
value: RequestDataTypeEnum.AJAX value: RequestDataTypeEnum.AJAX
},
{
label: SelectCreateDataEnum.Pond,
value: RequestDataTypeEnum.Pond
} }
] ]

View File

@@ -5,8 +5,6 @@
<edit-history></edit-history> <edit-history></edit-history>
<!-- CTRL按键触发展示 --> <!-- CTRL按键触发展示 -->
<n-text id="keyboard-dress-show" depth="3"></n-text> <n-text id="keyboard-dress-show" depth="3"></n-text>
<n-divider vertical />
<edit-data-sync></edit-data-sync>
</n-space> </n-space>
<n-space class="bottom-ri"> <n-space class="bottom-ri">
@@ -57,8 +55,7 @@
import { reactive, ref, toRefs, watchEffect } from 'vue' import { reactive, ref, toRefs, watchEffect } from 'vue'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { EditHistory } from '../EditHistory/index' import { EditHistory } from '../EditHistory/index'
import { EditShortcutKey } from '../EditShortcutKey/index' import EditShortcutKey from '../EditShortcutKey/index.vue'
import { EditDataSync } from '../EditDataSync/index'
import { useDesignStore } from '@/store/modules/designStore/designStore' import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d' import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@@ -147,10 +144,6 @@ $max-width: 670px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0 10px;
width: 100%;
min-width: $min-width;
height: 40px;
.bottom-ri { .bottom-ri {
position: relative; position: relative;
top: 15px; top: 15px;

View File

@@ -1,3 +0,0 @@
import EditDataSync from './index.vue'
export { EditDataSync }

View File

@@ -1,97 +0,0 @@
<template>
<div class="go-edit-data-sync go-flex-items-center">
<n-tooltip trigger="hover">
<template #trigger>
<n-text class="status-desc go-ml-2" :type="descType" depth="3">
{{ statusDesc }}
</n-text>
</template>
<span>{{saveInterval}}s 更新一次</span>
</n-tooltip>
<n-spin
v-show="statusDesc === statusDescObj[1]['text']"
class="go-ml-2"
size="small"
>
<template #icon>
<n-icon size="13">
<reload-icon />
</n-icon>
</template>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, toRefs, watch } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { SyncEnum } from '@/enums/editPageEnum'
import { icon } from '@/plugins'
import { saveInterval } from '@/settings/designSetting'
const { ReloadIcon } = icon.ionicons5
const chartEditStore = useChartEditStore()
const designStore = useDesignStore()
const { saveStatus } = toRefs(chartEditStore.getEditCanvas)
const themeColor = ref(designStore.getAppTheme)
const statusDesc = ref('')
const descType = ref('')
let setTimeoutIns: NodeJS.Timeout = setTimeout(() => {})
const statusDescObj = {
[SyncEnum.PENDING]: {
text: '等待自动同步',
type: '',
},
[SyncEnum.START]: {
text: '正在同步中',
type: 'success',
},
[SyncEnum.SUCCESS]: {
text: '同步成功!',
type: 'success',
},
[SyncEnum.FAILURE]: {
text: '同步失败!',
type: 'error',
},
}
watch(
() => saveStatus.value,
newData => {
clearTimeout(setTimeoutIns)
statusDesc.value = statusDescObj[newData]['text']
descType.value = statusDescObj[newData]['type']
// 3秒重置展示
setTimeoutIns = setTimeout(() => {
statusDesc.value = statusDescObj[SyncEnum.PENDING]['text']
descType.value = statusDescObj[SyncEnum.PENDING]['type']
}, 3000)
},
{
immediate: true,
}
)
</script>
<style lang="scss" scoped>
@include go('edit-data-sync') {
@include deep() {
.n-spin {
width: 13px;
height: 13px;
}
}
.status-desc {
cursor: default;
color: v-bind('themeColor');
font-size: 12px;
opacity: 0.8;
}
}
</style>

View File

@@ -133,6 +133,9 @@ const options = computed(() => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mr-10 {
margin-right: 10px;
}
.edit-history-popover { .edit-history-popover {
.btn-text { .btn-text {
font-size: 12px; font-size: 12px;

View File

@@ -113,25 +113,20 @@ const shortcutKeyOptions = [
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + Z `, win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + Z `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + ${MacKeyboard.SHIFT.toUpperCase()} + Z ` mac: `${MacKeyboard.CTRL.toUpperCase()} + ${MacKeyboard.SHIFT.toUpperCase()} + Z `
}, },
{
label: '保存',
win: `${WinKeyboard.CTRL.toUpperCase()} + S `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + S `,
},
{ {
label: '多选', label: '多选',
win: `${WinKeyboard.CTRL.toUpperCase()} + 🖱️ `, win: `${WinKeyboard.CTRL.toUpperCase()} + 🖱️ `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + 🖱️ ` mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + 🖱️ `
}, },
{ {
label: '创建分组', label: '创建分组',
win: `${WinKeyboard.CTRL.toUpperCase()} + G / 🖱️ `, win: `${WinKeyboard.CTRL.toUpperCase()} + G / 🖱️ `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + G / 🖱️` mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + G / 🖱️`
}, },
{ {
label: '解除分组', label: '解除分组',
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `, win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G ` mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `
} }
] ]
const closeHandle = () => { const closeHandle = () => {

View File

@@ -1,3 +1,2 @@
import EditShortcutKey from './index.vue' import EditShortcutKey from './index.vue'
export { EditShortcutKey } export { EditShortcutKey }

View File

@@ -7,6 +7,7 @@ import { useSync } from '@/views/chart/hooks/useSync.hook'
export const useFile = () => { export const useFile = () => {
const importUploadFileListRef = ref() const importUploadFileListRef = ref()
const { updateComponent } = useSync() const { updateComponent } = useSync()
// 上传-前置 // 上传-前置
//@ts-ignore //@ts-ignore
const importBeforeUpload = ({ file }) => { const importBeforeUpload = ({ file }) => {

View File

@@ -6,7 +6,7 @@ import { ChartEnum } from '@/enums/pageEnum'
import { SavePageEnum } from '@/enums/editPageEnum' import { SavePageEnum } from '@/enums/editPageEnum'
import { editToJsonInterval } from '@/settings/designSetting' import { editToJsonInterval } from '@/settings/designSetting'
const { updateComponent, dataSyncUpdate } = useSync() const { updateComponent } = useSync()
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
// 侦听器更新 // 侦听器更新
@@ -15,17 +15,11 @@ const useSyncUpdateHandle = () => {
let timer: any let timer: any
const updateFn = (e: any) => updateComponent(e!.detail, true, false) const updateFn = (e: any) => updateComponent(e!.detail, true, false)
const syncData = async () => { const syncData = async () => {
dataSyncUpdate && (await dataSyncUpdate())
dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo })) dispatchEvent(new CustomEvent(SavePageEnum.CHART, { detail: chartEditStore.getStorageInfo }))
} }
// 开启侦听 // 开启侦听
const use = () => { const use = () => {
// // 1、定时同步数据
// timer = setInterval(() => {
// // 窗口激活并且处于工作台
// document.hasFocus() && syncData()
// }, editToJsonInterval)
// // 1、定时同步数据 // // 1、定时同步数据
// timer = setInterval(() => { // timer = setInterval(() => {
// // 窗口激活并且处于工作台 // // 窗口激活并且处于工作台
@@ -40,7 +34,6 @@ const useSyncUpdateHandle = () => {
// 关闭侦听 // 关闭侦听
const unUse = () => { const unUse = () => {
// clearInterval(timer)
// clearInterval(timer) // clearInterval(timer)
removeEventListener(SavePageEnum.JSON, updateFn) removeEventListener(SavePageEnum.JSON, updateFn)
removeEventListener('blur', syncData) removeEventListener('blur', syncData)

View File

@@ -9,7 +9,7 @@ export const exportHandle = () => {
// 导出数据 // 导出数据
downloadTextFile( downloadTextFile(
JSON.stringify(chartEditStore.getStorageInfo || {}, (k, v) => { JSON.stringify(chartEditStore.getStorageInfo || [], (k, v) => {
return v === undefined ? null : v return v === undefined ? null : v
}), }),
undefined, undefined,

View File

@@ -91,7 +91,6 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
import { useLayout } from './hooks/useLayout.hook' import { useLayout } from './hooks/useLayout.hook'
import { useAddKeyboard } from '../hooks/useKeyboard.hook' import { useAddKeyboard } from '../hooks/useKeyboard.hook'
import { useSync } from '../hooks/useSync.hook'
import { dragHandle, dragoverHandle, mousedownHandleUnStop, useMouseHandle } from './hooks/useDrag.hook' import { dragHandle, dragoverHandle, mousedownHandleUnStop, useMouseHandle } from './hooks/useDrag.hook'
import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook' import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
@@ -105,7 +104,6 @@ import { EditTools } from './components/EditTools'
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
const { handleContextMenu } = useContextMenu() const { handleContextMenu } = useContextMenu()
const { dataSyncFetch, intervalDataSyncUpdate } = useSync()
// 布局处理 // 布局处理
useLayout() useLayout()
@@ -174,13 +172,9 @@ const rangeStyle = computed(() => {
} }
}) })
// 键盘事件
onMounted(() => { onMounted(() => {
// 键盘事件
useAddKeyboard() useAddKeyboard()
// 获取数据
dataSyncFetch()
// 定时更新数据
intervalDataSyncUpdate()
}) })
</script> </script>

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