@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
module.exports = { |
||||
extends: ["@commitlint/config-conventional"] |
||||
}; |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
# port |
||||
VITE_DEV_PORT = '3000' |
||||
|
||||
# development path |
||||
# VITE_DEV_PATH = 'https://demo.mtruning.club' |
||||
VITE_DEV_PATH = 'http://127.0.0.1:48080' |
||||
|
||||
# production path |
||||
VITE_PRO_PATH = 'https://demo.mtruning.club' |
||||
|
||||
# 租户开关 |
||||
VITE_APP_TENANT_ENABLE=true |
||||
|
||||
# 验证码的开关 |
||||
VITE_APP_CAPTCHA_ENABLE=true |
||||
|
||||
#默认路由开关 |
||||
VITE_ROUTER_DEFAULT=true |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
node_modules/ |
||||
public/ |
||||
es/ |
||||
lib/ |
||||
dist/ |
||||
package.json |
||||
src/assets/ |
||||
plop-templates/ |
||||
handlebars/ |
||||
website/ |
||||
build/ |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
module.exports = { |
||||
root: true, |
||||
parser: 'vue-eslint-parser', |
||||
globals: { |
||||
postMessage: true |
||||
}, |
||||
parserOptions: { |
||||
parser: '@typescript-eslint/parser', |
||||
sourceType: 'module', |
||||
ecmaFeatures: { |
||||
jsx: true, |
||||
tsx: true |
||||
} |
||||
}, |
||||
env: { |
||||
node: true, |
||||
// The Follow config only works with eslint-plugin-vue v8.0.0+
|
||||
'vue/setup-compiler-macros': true |
||||
}, |
||||
extends: ['plugin:vue/vue3-essential', 'eslint:recommended'], |
||||
rules: { |
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', |
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', |
||||
'no-unused-vars': 'off', |
||||
'vue/no-unused-vars': 'off', |
||||
'vue/multi-word-component-names': 'off', |
||||
'vue/valid-template-root': 'off', |
||||
'vue/no-mutating-props': 'off' |
||||
} |
||||
} |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
node_modules |
||||
.DS_Store |
||||
dist |
||||
dist-ssr |
||||
*.local |
||||
.vscode |
||||
.idea |
||||
.workflow |
||||
.husky |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
MIT License |
||||
|
||||
Copyright (c) 2021-present GoView |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
.PHONY: dist test |
||||
default: help |
||||
dev: |
||||
npm run dev
|
||||
|
||||
dist: |
||||
npm run build
|
||||
|
||||
view: |
||||
npm run preview
|
||||
|
||||
lint: |
||||
npm run lint
|
||||
|
||||
new: |
||||
npm run new
|
||||
|
||||
|
||||
|
||||
help: |
||||
@echo " make dev [npm run dev] 开发模式"
|
||||
@echo " make dist [npm run build] 编译模式"
|
||||
@echo " make view [npm run preview] 预览打包文件"
|
||||
@echo " make new [npm run lint] 通过自动化流程创建代码"
|
||||
@echo " make lint [npm run new] 格式校验"
|
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
## 总览 |
||||
|
||||
<p align="center"> |
||||
<img src="readme/logo-t-y.png" alt="go-view" /> |
||||
</p> |
||||
|
||||
<h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4> |
||||
|
||||
由 [芋道](https://doc.iocoder.cn/) 与 GoView 共同建设,基于 Vue3 搭建的低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可完成业务需求。 |
||||
|
||||
* 框架:基于 Vue3 框架编写,使用 hooks 写法抽离部分逻辑,使代码结构更加清晰 |
||||
* 类型:使用 TypeScript 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容 |
||||
* 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度 |
||||
* 存储:拥有本地记忆,部分配置项采用 storage 存储本地,提升使用体验 |
||||
* 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等 |
||||
* 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community) |
||||
|
||||
## 项目地址 |
||||
|
||||
 |
||||
|
||||
* 前端:<https://gitee.com/zhijiantianya/yudao-ui-go-view> |
||||
* Boot 后端:<https://gitee.com/zhijiantianya/ruoyi-vue-pro> |
||||
* Cloud 后端:<https://gitee.com/zhijiantianya/yudao-cloud> |
||||
|
||||
## 文档地址 |
||||
|
||||
* 演示环境:<http://dashboard.yudao.iocoder.cn/login> 「报表管理 - 大屏设计器」 |
||||
* 文档地址:<https://doc.iocoder.cn/report/> |
||||
|
||||
## 技术栈 |
||||
|
||||
主要技术栈为: |
||||
|
||||
| 名称 | 版本 | 名称 | 版本 | |
||||
|-------------------|-------|-------------|--------| |
||||
| 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 | 数字翻牌 | 通用时间 | |
||||
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 | |
||||
|
||||
## 项目截图 |
||||
|
||||
#### 工作台 |
||||
|
||||
|
||||
 |
||||
|
||||
#### 请求配置 |
||||
|
||||
 |
||||
|
||||
#### 数据过滤 |
||||
|
||||
 |
||||
|
||||
#### 高级事件编辑 |
||||
|
||||
 |
||||
|
||||
#### 快捷主页 |
||||
|
||||
 |
||||
|
||||
#### 主题色 |
||||
|
||||
 |
||||
|
||||
#### 亮白主题 |
||||
|
||||
 |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
import path from 'path' |
||||
export const OUTPUT_DIR = 'dist' |
||||
|
||||
// monaco-editor 路径
|
||||
export const prefix = `monaco-editor/esm/vs` |
||||
|
||||
// chunk 警告大小
|
||||
export const chunkSizeWarningLimit = 2000 |
||||
|
||||
// 禁用 brotliSize 压缩大小报告
|
||||
export const brotliSize = false |
||||
|
||||
// 分包
|
||||
export const rollupOptions = { |
||||
output: { |
||||
chunkFileNames: 'static/js/[name]-[hash].js', |
||||
entryFileNames: 'static/js/[name]-[hash].js', |
||||
assetFileNames: (chunkInfo) => { |
||||
if(['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) { |
||||
return `static/[ext]/[name].[ext]` |
||||
} |
||||
return `static/[ext]/[name]-[hash].[ext]` |
||||
}, |
||||
manualChunks: { |
||||
jsonWorker: [`${prefix}/language/json/json.worker`], |
||||
cssWorker: [`${prefix}/language/css/css.worker`], |
||||
htmlWorker: [`${prefix}/language/html/html.worker`], |
||||
tsWorker: [`${prefix}/language/typescript/ts.worker`], |
||||
editorWorker: [`${prefix}/editor/editor.worker`] |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 去除开发代码
|
||||
export const terserOptions = { |
||||
compress: { |
||||
keep_infinity: true, |
||||
drop_console: true, |
||||
drop_debugger: true |
||||
} |
||||
} |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
* { |
||||
margin: 0; |
||||
} |
||||
.first-loading-wrp { |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
height: 100vh; |
||||
background-color: #17171a; |
||||
} |
||||
.first-loading-wrp > h1 { |
||||
font-size: 128px; |
||||
} |
||||
.first-loading-wrp .loading-wrp { |
||||
padding: 98px; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
.dot { |
||||
animation: antRotate 1.2s infinite linear; |
||||
transform: rotate(45deg); |
||||
position: relative; |
||||
display: inline-block; |
||||
font-size: 32px; |
||||
width: 32px; |
||||
height: 32px; |
||||
box-sizing: border-box; |
||||
} |
||||
.dot i { |
||||
width: 14px; |
||||
height: 14px; |
||||
position: absolute; |
||||
display: block; |
||||
background-color: #1890ff; |
||||
border-radius: 100%; |
||||
transform: scale(0.75); |
||||
transform-origin: 50% 50%; |
||||
opacity: 0.3; |
||||
animation: antSpinMove 1s infinite linear alternate; |
||||
} |
||||
.dot i:nth-child(1) { |
||||
top: 0; |
||||
left: 0; |
||||
} |
||||
.dot i:nth-child(2) { |
||||
top: 0; |
||||
right: 0; |
||||
-webkit-animation-delay: 0.4s; |
||||
animation-delay: 0.4s; |
||||
} |
||||
.dot i:nth-child(3) { |
||||
right: 0; |
||||
bottom: 0; |
||||
-webkit-animation-delay: 0.8s; |
||||
animation-delay: 0.8s; |
||||
} |
||||
.dot i:nth-child(4) { |
||||
bottom: 0; |
||||
left: 0; |
||||
-webkit-animation-delay: 1.2s; |
||||
animation-delay: 1.2s; |
||||
} |
||||
@keyframes antRotate { |
||||
to { |
||||
-webkit-transform: rotate(405deg); |
||||
transform: rotate(405deg); |
||||
} |
||||
} |
||||
@-webkit-keyframes antRotate { |
||||
to { |
||||
-webkit-transform: rotate(405deg); |
||||
transform: rotate(405deg); |
||||
} |
||||
} |
||||
@keyframes antSpinMove { |
||||
to { |
||||
opacity: 1; |
||||
} |
||||
} |
||||
@-webkit-keyframes antSpinMove { |
||||
to { |
||||
opacity: 1; |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html> |
||||
<html lang="zh-cmn-Hans"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
||||
<meta name="renderer" content="webkit" /> |
||||
<meta name="description" content="GoView 是高效、高性能的拖拽式低代码数据可视化开发平台,将页面元素封装为基础组件,无需编写代码即可完成业务需求。 "> |
||||
<meta name="keywords" content="GoView,goview,低代码,可视化"> |
||||
<meta name="author" content="奔跑的面条,面条"> |
||||
<meta |
||||
name="viewport" |
||||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" |
||||
/> |
||||
<link rel="icon" href="./favicon.ico" /> |
||||
<title>GoView</title> |
||||
<link rel="stylesheet" href="./index.css" /> |
||||
<script src="js/esobjs-xe2-plugin/dist-web/xe2-assets/js/load-common.js"></script> |
||||
</head> |
||||
<body> |
||||
<div id="appProvider" style="display: none;"></div> |
||||
<div id="app"> |
||||
<div class="first-loading-wrp"> |
||||
<div class="loading-wrp"> |
||||
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<script type="module" src="/src/main.ts"></script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
{ |
||||
"type": "module", |
||||
"name": "go-view", |
||||
"version": "2.1.6", |
||||
"engines": { |
||||
"node": ">=12.0" |
||||
}, |
||||
"scripts": { |
||||
"dev": "vite --host", |
||||
"build": "vue-tsc --noEmit && vite build", |
||||
"build:prod": "vite build --mode production", |
||||
"preview": "vite preview", |
||||
"new": "plop --plopfile ./plop/plopfile.js", |
||||
"postinstall": "husky install", |
||||
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.vue src", |
||||
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx,.vue src --fix" |
||||
}, |
||||
"dependencies": { |
||||
"@amap/amap-jsapi-loader": "^1.0.1", |
||||
"@amap/amap-jsapi-types": "^0.0.8", |
||||
"@iconify/json": "^2.2.158", |
||||
"@types/color": "^3.0.3", |
||||
"@types/crypto-js": "^4.1.1", |
||||
"@types/keymaster": "^1.6.30", |
||||
"@types/lodash": "^4.14.184", |
||||
"@visactor/vchart": "^1.12.3", |
||||
"@visactor/vchart-theme": "^1.12.1", |
||||
"animate.css": "^4.1.1", |
||||
"axios": "^1.6.8", |
||||
"cesium": "1.99", |
||||
"color": "^4.2.3", |
||||
"crypto-js": "^4.1.1", |
||||
"dayjs": "^1.11.7", |
||||
"dom-helpers": "^5.2.1", |
||||
"echarts-liquidfill": "^3.1.0", |
||||
"echarts-stat": "^1.2.0", |
||||
"echarts-wordcloud": "^2.0.0", |
||||
"esobjs-xe2-plugin": "^0.1.126-beta-0.3", |
||||
"gsap": "^3.11.3", |
||||
"highlight.js": "^11.5.0", |
||||
"html2canvas": "^1.4.1", |
||||
"iconify-icon": "^1.0.8", |
||||
"keymaster": "^1.6.2", |
||||
"mitt": "^3.0.0", |
||||
"monaco-editor": "^0.33.0", |
||||
"naive-ui": "2.34.3", |
||||
"pinia": "^2.0.13", |
||||
"pnpm": "^8.7.0", |
||||
"screenfull": "^6.0.1", |
||||
"three": "^0.145.0", |
||||
"vite-plugin-cesium": "^1.2.23", |
||||
"vue": "^3.2.31", |
||||
"vue-demi": "^0.13.1", |
||||
"vue-i18n": "9.2.2", |
||||
"vue-router": "4.0.12", |
||||
"vue-xe2-plugin": "^0.1.3", |
||||
"vue3-lazyload": "^0.2.5-beta", |
||||
"vue3-sketch-ruler": "^1.3.3", |
||||
"vuedraggable": "^4.1.0", |
||||
"xbsj-xe2": "^0.1.16", |
||||
"xbsj-xe2-assets": "^0.1.16", |
||||
"smplotting-xe2-plugin": "^0.1.3" |
||||
}, |
||||
"devDependencies": { |
||||
"@commitlint/cli": "^17.0.2", |
||||
"@commitlint/config-conventional": "^17.0.2", |
||||
"@types/node": "^16.11.26", |
||||
"@types/three": "^0.144.0", |
||||
"@typescript-eslint/eslint-plugin": "^5.18.0", |
||||
"@typescript-eslint/parser": "^5.18.0", |
||||
"@vicons/carbon": "^0.12.0", |
||||
"@vicons/ionicons5": "~0.11.0", |
||||
"@vitejs/plugin-vue": "^4.2.3", |
||||
"@vitejs/plugin-vue-jsx": "^3.0.1", |
||||
"@vue/compiler-sfc": "^3.2.31", |
||||
"@vueuse/core": "^7.7.1", |
||||
"commitlint": "^17.0.2", |
||||
"default-passive-events": "^2.0.0", |
||||
"echarts": "^5.3.2", |
||||
"eslint": "^8.12.0", |
||||
"eslint-config-prettier": "^8.5.0", |
||||
"eslint-plugin-import": "^2.26.0", |
||||
"eslint-plugin-prettier": "^4.0.0", |
||||
"eslint-plugin-vue": "^8.5.0", |
||||
"esobjs-xe2-plugin-assets": "^0.1.14", |
||||
"husky": "^8.0.1", |
||||
"lodash": "~4.17.21", |
||||
"mockjs": "^1.1.0", |
||||
"plop": "^3.0.5", |
||||
"prettier": "^2.6.2", |
||||
"sass": "^1.49.11", |
||||
"sass-loader": "^12.6.0", |
||||
"typescript": "4.6.3", |
||||
"vite": "4.3.6", |
||||
"vite-plugin-compression": "^0.5.1", |
||||
"vite-plugin-externals": "^0.6.2", |
||||
"vite-plugin-importer": "^0.2.5", |
||||
"vite-plugin-mock": "^2.9.6", |
||||
"vite-plugin-monaco-editor": "^1.1.0", |
||||
"vite-plugin-static-copy": "^1.0.6", |
||||
"vue-echarts": "^6.0.2", |
||||
"vue-tsc": "^0.28.10" |
||||
} |
||||
} |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
const storeGenerator = require('./store-template/prompt') |
||||
|
||||
module.exports = (plop) => { |
||||
plop.setGenerator('store', storeGenerator) |
||||
} |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
export interface {{upperDataName}}StoreType { |
||||
|
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
import { defineStore } from 'pinia' |
||||
import { {{upperDataName}}StoreType } from './{{name}}Store.d' |
||||
import { setLocalStorage, getLocalStorage } from '@/utils' |
||||
import { StorageEnum } from '@/enums/storageEnum' |
||||
|
||||
export const use{{upperDataName}}Store = defineStore({ |
||||
id: 'use{{upperDataName}}Store', |
||||
state: (): {{upperDataName}}StoreType => ({}), |
||||
getters: {}, |
||||
actions: {} |
||||
}) |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
module.exports = { |
||||
description: 'create a store', |
||||
prompts: [ |
||||
{ |
||||
type: 'input', |
||||
name: 'name', |
||||
message: 'Please enter store name,such as "newStoreName" :', |
||||
validate (value) { |
||||
if (!value || value.trim === '') { |
||||
return 'name is required'; |
||||
} |
||||
return true; |
||||
}, |
||||
} |
||||
], |
||||
actions: (data) => { |
||||
const dataName = data.name |
||||
|
||||
// 首字母大写
|
||||
const upperDataName = dataName.slice(0, 1).toUpperCase() + dataName.slice(1) |
||||
|
||||
const actions = [ |
||||
{ |
||||
type: 'add', |
||||
path: `${process.cwd()}/src/store/modules/${dataName}Store/${dataName}Store.ts`, // 这里的name就是上面定义的键
|
||||
templateFile: './store-template/index.hbs', |
||||
data: { |
||||
name: data.name, |
||||
upperDataName, |
||||
} |
||||
}, |
||||
{ |
||||
type: 'add', |
||||
path: `${process.cwd()}/src/store/modules/${dataName}Store/${dataName}Store.d.ts`, // 这里的name就是上面定义的键
|
||||
templateFile: './store-template/index.d.hbs', |
||||
data: { |
||||
name: data.name, |
||||
upperDataName, |
||||
} |
||||
}, |
||||
] |
||||
|
||||
return actions |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
module.exports = { |
||||
printWidth: 120, |
||||
tabWidth: 2, |
||||
useTabs: false, |
||||
singleQuote: true, |
||||
semi: false, |
||||
trailingComma: "none", |
||||
bracketSpacing: true, |
||||
jsxSingleQuote: true, |
||||
jsxBracketSameLine: false, |
||||
arrowParens: "avoid" |
||||
} |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
# preview.yml |
||||
autoOpen: true # 打开工作空间时是否自动开启所有应用的预览 |
||||
apps: |
||||
- port: 3000 # 应用的端口 |
||||
run: npm i --registry=https://registry.npmmirror.com && npm run dev # 应用的启动命令 |
||||
command: # 使用此命令启动服务,且不执行run |
||||
root: ./ # 应用的启动目录 |
||||
name: GoView # 应用名称 |
||||
description: 开源、精美、便捷的「数据可视化」低代码开发平台 # 应用描述 |
||||
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen) |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 344 KiB |
After Width: | Height: | Size: 218 KiB |
After Width: | Height: | Size: 140 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 257 KiB |
After Width: | Height: | Size: 167 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 140 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 49 KiB |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
<template> |
||||
<n-config-provider |
||||
:theme="darkTheme" |
||||
:hljs="hljsTheme" |
||||
:locale="locale" |
||||
:date-locale="dateLocale" |
||||
:theme-overrides="overridesTheme" |
||||
> |
||||
<go-app-provider> |
||||
<I18n></I18n> |
||||
<router-view></router-view> |
||||
</go-app-provider> |
||||
</n-config-provider> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { NConfigProvider } from 'naive-ui' |
||||
import { GoAppProvider } from '@/components/GoAppProvider' |
||||
import { I18n } from '@/components/I18n' |
||||
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks' |
||||
|
||||
//字节图表全局配置部分 |
||||
import vScreenVolcanoBlue from '@visactor/vchart-theme/public/vScreenVolcanoBlue.json'; |
||||
import VChart from '@visactor/vchart'; |
||||
import {IGlobalMarkThemeByName, IGlobalMarkThemeByType, ITheme} from "@visactor/vchart/esm/theme/interface"; |
||||
import {languages} from "monaco-editor"; |
||||
import type {IColorKey} from "@visactor/vchart/esm/theme/color-scheme/interface"; |
||||
import type {ITokenKey} from "@visactor/vchart/esm/theme/token"; |
||||
import type {ISeriesTheme} from "@visactor/vchart/esm/series/interface"; |
||||
import type {IComponentTheme} from "@visactor/vchart/esm/component/interface"; |
||||
const myVScreenVolcanoBlue: Partial<ITheme> = { |
||||
...vScreenVolcanoBlue, |
||||
type:"dark", |
||||
background:vScreenVolcanoBlue.background as IColorKey, |
||||
fontFamily:vScreenVolcanoBlue.fontFamily as ITokenKey, |
||||
mark:vScreenVolcanoBlue.mark as IGlobalMarkThemeByType, |
||||
markByName:vScreenVolcanoBlue.markByName as IGlobalMarkThemeByName, |
||||
series:vScreenVolcanoBlue.series as ISeriesTheme, |
||||
component: vScreenVolcanoBlue.component as unknown as IComponentTheme |
||||
// 其他字段逐个检查和断言 |
||||
}; |
||||
|
||||
VChart.ThemeManager.registerTheme('vScreenVolcanoBlue',myVScreenVolcanoBlue); |
||||
// apply the theme |
||||
VChart.ThemeManager.setCurrentTheme('vScreenVolcanoBlue'); |
||||
//字节图标配置部分END |
||||
|
||||
|
||||
|
||||
// 暗黑主题 |
||||
const darkTheme = useDarkThemeHook() |
||||
|
||||
// 主题配置 |
||||
const overridesTheme = useThemeOverridesHook() |
||||
|
||||
// 代码主题 |
||||
const hljsTheme = useCode() |
||||
|
||||
// 系统全局数据初始化 |
||||
useSystemInit() |
||||
|
||||
// 全局语言 |
||||
const { locale, dateLocale } = useLang() |
||||
|
||||
</script> |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
import { ModuleTypeEnum } from '@/enums/httpEnum' |
||||
|
||||
// 接口白名单(免登录)
|
||||
export const fetchAllowList = [ |
||||
// 登录
|
||||
`${ModuleTypeEnum.SYSTEM}/auth-login`, |
||||
// 预览获取数据
|
||||
`${ModuleTypeEnum.PROJECT}/getData`, |
||||
] |
||||
|
||||
// 接口黑名单
|
||||
export const fetchBlockList = [] |
@ -0,0 +1,220 @@
@@ -0,0 +1,220 @@
|
||||
import axios, { AxiosResponse, AxiosRequestConfig, Axios,AxiosRequestHeaders,InternalAxiosRequestConfig } from 'axios' |
||||
import { ResultEnum, ModuleTypeEnum } from "@/enums/httpEnum" |
||||
import {PageEnum, ErrorPageNameMap, PreviewEnum} from "@/enums/pageEnum" |
||||
import { StorageEnum } from '@/enums/storageEnum' |
||||
import { axiosPre } from '@/settings/httpSetting' |
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum,UserInfoType } from '@/store/modules/systemStore/systemStore.d' |
||||
import { |
||||
redirectErrorPage, |
||||
getLocalStorage, |
||||
routerTurnByName, |
||||
isPreview, |
||||
clearAllSessio, |
||||
clearAllStorage, |
||||
setLocalStorage, |
||||
setSessionStorage, fetchRouteParamsLocation, fetchRouteName, logout, fetchRoutePath |
||||
} from '@/utils' |
||||
import { fetchAllowList } from './axios.config' |
||||
import includes from 'lodash/includes' |
||||
import {useSystemStore} from "@/store/modules/systemStore/systemStore"; |
||||
import { useDialog } from 'naive-ui' |
||||
// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现
|
||||
// 请求队列
|
||||
let requestList: any[] = [] |
||||
// 是否正在刷新中
|
||||
let isRefreshToken = false |
||||
// 请求路径
|
||||
let base_url=`${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}` |
||||
|
||||
const dialog = useDialog() |
||||
|
||||
|
||||
|
||||
export interface MyResponseType<T> extends AxiosResponse<T, any>{ |
||||
code: ResultEnum |
||||
data: T |
||||
message: string |
||||
} |
||||
|
||||
export interface MyRequestInstance extends Axios { |
||||
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>> |
||||
} |
||||
|
||||
const axiosInstance = axios.create({ |
||||
baseURL: base_url, |
||||
timeout: ResultEnum.TIMEOUT, |
||||
}) as unknown as MyRequestInstance |
||||
|
||||
axiosInstance.interceptors.request.use( |
||||
(config:InternalAxiosRequestConfig) => { |
||||
// 获取 tenantId
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) |
||||
// console.log(window.location)
|
||||
const tenantId = info ? info[SystemStoreEnum.TENANT_INFO]['tenantId'] : undefined |
||||
|
||||
if (tenantId) (config as Recordable).headers['tenant-id'] = tenantId |
||||
|
||||
|
||||
// 白名单校验
|
||||
if (includes(fetchAllowList, config.url)) return config |
||||
// 获取 token
|
||||
// 重新登录
|
||||
if (!info) { |
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME) |
||||
return config |
||||
} |
||||
const userInfo:UserInfoType = info[SystemStoreEnum.USER_INFO] as UserInfoType |
||||
|
||||
(config as Recordable).headers.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || '' |
||||
// config.headers = {
|
||||
// ...config.headers,
|
||||
// [userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
|
||||
// }
|
||||
return config |
||||
}, |
||||
(err: AxiosRequestConfig) => { |
||||
Promise.reject(err) |
||||
} |
||||
) |
||||
|
||||
// 响应拦截器
|
||||
axiosInstance.interceptors.response.use( |
||||
async (res: AxiosResponse<any>) => { |
||||
const config = res.config |
||||
|
||||
const { code,msg } = res.data as { code: number,msg:string } |
||||
|
||||
if (code === undefined || code === null) return Promise.resolve(res) |
||||
// 预览页面错误不进行处理
|
||||
if (isPreview()&&code!==ResultEnum.TOKEN_OVERDUE) { |
||||
return Promise.resolve(res.data) |
||||
} |
||||
// 如果是验证码的返回,直接返回数据
|
||||
|
||||
|
||||
// 成功
|
||||
if (code === ResultEnum.SUCCESS) { |
||||
return Promise.resolve(res.data) |
||||
} |
||||
|
||||
// 登录过期
|
||||
if (code === ResultEnum.TOKEN_OVERDUE) { |
||||
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
|
||||
console.log('Auth2:-------------------准备刷新令牌-----------------') |
||||
if (!isRefreshToken) { |
||||
isRefreshToken = true |
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) |
||||
// console.log(window.location)
|
||||
const refreshToken = info ? info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_REFRESH_TOKEN] : undefined |
||||
// 1. 如果获取不到刷新令牌,则只能执行登出操作
|
||||
|
||||
if (!refreshToken) { |
||||
console.log('无刷新令牌,即将返回。') |
||||
return handleAuthorized() |
||||
} |
||||
// 2. 进行刷新访问令牌
|
||||
try { |
||||
const systemStore = useSystemStore() |
||||
const refreshTokenRes = await getTefreshToken() |
||||
// 2.1 刷新成功,则回放队列的请求 + 当前请求
|
||||
systemStore.setItem(SystemStoreEnum.USER_INFO, { |
||||
[SystemStoreUserInfoEnum.USER_TOKEN]: (await refreshTokenRes).data.data.accessToken, |
||||
[SystemStoreUserInfoEnum.USER_REFRESH_TOKEN]: (await refreshTokenRes).data.data.refreshToken, |
||||
[SystemStoreUserInfoEnum.TOKEN_NAME]: 'Authorization' |
||||
}) |
||||
//修改当前访问令牌
|
||||
// config.headers!.Authorization = 'Bearer ' + (await refreshTokenRes).data.data.accessToken
|
||||
const userInfo:UserInfoType = info[SystemStoreEnum.USER_INFO] as UserInfoType |
||||
// config.headers = {
|
||||
// ...config.headers,
|
||||
// [userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
|
||||
// }
|
||||
(config as Recordable).headers.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || '' |
||||
requestList.forEach((cb: any) => { |
||||
cb() |
||||
}) |
||||
requestList = [] |
||||
console.log('Auth2:-------------------令牌刷新成功-----------------') |
||||
return axiosInstance(config) |
||||
} catch (e) { |
||||
// 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
|
||||
// 2.2 刷新失败,只回放队列的请求
|
||||
requestList.forEach((cb: any) => { |
||||
cb() |
||||
}) |
||||
// 提示是否要登出。即不回放当前请求!不然会形成递归
|
||||
return handleAuthorized() |
||||
} finally { |
||||
requestList = [] |
||||
isRefreshToken = false |
||||
} |
||||
} else { |
||||
console.log('Auth2:-------------------已添加刷新队列-----------------') |
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) |
||||
// 添加到队列,等待刷新获取到新的令牌
|
||||
return new Promise((resolve) => { |
||||
requestList.push(() => { |
||||
const userInfo = info[SystemStoreEnum.USER_INFO] |
||||
config.headers!.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
resolve(axiosInstance(config)) |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
} |
||||
|
||||
// 固定错误码重定向
|
||||
if (ErrorPageNameMap.get(code)) { |
||||
redirectErrorPage(code) |
||||
return Promise.resolve(res.data) |
||||
} |
||||
|
||||
if (code !== 200) { |
||||
if (msg === '无效的刷新令牌') { |
||||
// hard coding:忽略这个提示,直接登出
|
||||
console.log(msg) |
||||
return handleAuthorized() |
||||
} else { |
||||
window['$message'].error(msg) |
||||
} |
||||
return Promise.reject('error') |
||||
} |
||||
|
||||
// 提示错误
|
||||
window['$message'].error(window['$t']((res.data as any).msg)) |
||||
return Promise.resolve(res.data) |
||||
}, |
||||
(err: AxiosResponse) => { |
||||
Promise.reject(err) |
||||
} |
||||
) |
||||
|
||||
|
||||
const getTefreshToken = async () => { |
||||
let tenantData = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) |
||||
axios.defaults.headers.common['tenant-id'] = tenantData[SystemStoreEnum.TENANT_INFO]['tenantId'] ?? undefined; |
||||
return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + tenantData[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_REFRESH_TOKEN] ?? undefined) |
||||
} |
||||
|
||||
|
||||
const handleAuthorized = () =>{ |
||||
// window['$message'].error(window['$t']('http.token_overdue_message'))
|
||||
console.log(useDialog()) |
||||
window['$dialog'].warning( {title: '登录已超时', |
||||
content: '登录超时,请重新登录。', |
||||
positiveText: '确定', |
||||
negativeText: '取消', |
||||
onPositiveClick: () => { |
||||
// session 不需要清除 clearAllSessio() //清除所有Session缓存
|
||||
clearAllStorage() //清除所有Storage缓存
|
||||
//临时缓存跳回目录进行登录重新跳回
|
||||
if('/chart/preview' === fetchRoutePath()){ |
||||
setSessionStorage('setRedirectPath','/chart/preview') |
||||
setSessionStorage('setRedirectPathId', fetchRouteParamsLocation()) |
||||
} |
||||
logout() |
||||
return Promise.resolve(window['$t']('http.token_overdue_message')) |
||||
} |
||||
}) |
||||
} |
||||
export default axiosInstance |
@ -0,0 +1,254 @@
@@ -0,0 +1,254 @@
|
||||
import axiosInstance from './axios' |
||||
import { |
||||
RequestHttpEnum, |
||||
ContentTypeEnum, |
||||
RequestBodyEnum, |
||||
RequestDataTypeEnum, |
||||
RequestContentTypeEnum, |
||||
RequestParamsObjType |
||||
} from '@/enums/httpEnum' |
||||
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d' |
||||
import { getLocalStorage } from "@/utils"; |
||||
import { StorageEnum } from "@/enums/storageEnum"; |
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d' |
||||
|
||||
export const get = <T = any>(url: string, params?: object) => { |
||||
return axiosInstance<T>({ |
||||
url: url, |
||||
method: RequestHttpEnum.GET, |
||||
params: params, |
||||
}) |
||||
} |
||||
|
||||
export const post = <T = any>(url: string, data?: object, headersType?: string) => { |
||||
return axiosInstance<T>({ |
||||
url: url, |
||||
method: RequestHttpEnum.POST, |
||||
data: data, |
||||
headers: { |
||||
'Content-Type': headersType || ContentTypeEnum.JSON |
||||
} |
||||
}) |
||||
} |
||||
|
||||
export const patch = <T = any>(url: string, data?: object, headersType?: string) => { |
||||
return axiosInstance<T>({ |
||||
url: url, |
||||
method: RequestHttpEnum.PATCH, |
||||
data: data, |
||||
headers: { |
||||
'Content-Type': headersType || ContentTypeEnum.JSON |
||||
} |
||||
}) |
||||
} |
||||
|
||||
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => { |
||||
return axiosInstance<T>({ |
||||
url: url, |
||||
method: RequestHttpEnum.PUT, |
||||
data: data, |
||||
headers: { |
||||
'Content-Type': headersType || ContentTypeEnum.JSON |
||||
} |
||||
}) |
||||
} |
||||
|
||||
export const del = <T = any>(url: string, params?: object) => { |
||||
return axiosInstance<T>({ |
||||
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.PATCH: |
||||
return patch |
||||
|
||||
case RequestHttpEnum.PUT: |
||||
return put |
||||
|
||||
case RequestHttpEnum.DELETE: |
||||
return del |
||||
|
||||
default: |
||||
return get |
||||
} |
||||
} |
||||
const prefix = 'javascript:' |
||||
// 对输入字符进行转义处理
|
||||
export const translateStr = (target: string | Record<any, any>) => { |
||||
if (typeof target === 'string') { |
||||
if (target.startsWith(prefix)) { |
||||
const funcStr = target.split(prefix)[1] |
||||
let result |
||||
try { |
||||
result = new Function(`${funcStr}`)() |
||||
} catch (error) { |
||||
console.log(error) |
||||
window['$message'].error('js内容解析有误!') |
||||
} |
||||
return result |
||||
} else { |
||||
return target |
||||
} |
||||
} |
||||
for (const key in target) { |
||||
if (Object.prototype.hasOwnProperty.call(target, key)) { |
||||
const subTarget = target[key] |
||||
target[key] = translateStr(subTarget) |
||||
} |
||||
} |
||||
return target |
||||
} |
||||
|
||||
// 处理 token 和多租户的头;注意:只拼接属于 VITE_DEV_PATH 或 VITE_PROD_PATH 开头的 URL 地址,就是自己的后端
|
||||
export const appendTokenAndTenant = (headers: RequestParamsObjType, requestUrl: string) => { |
||||
if (requestUrl.indexOf(import.meta.env.VITE_DEV_PATH) === -1 |
||||
|| requestUrl.indexOf(import.meta.env.VITE_PROD_PATH) === -1) { |
||||
return headers |
||||
} |
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE) |
||||
if (!info) { |
||||
return headers; |
||||
} |
||||
// ① 获取 tenantId
|
||||
const tenantId = info ? info[SystemStoreEnum.TENANT_INFO]['tenantId'] : undefined |
||||
if (tenantId) { |
||||
headers['tenant-id'] = tenantId |
||||
} |
||||
// ② 获取 token
|
||||
const userInfo = info[SystemStoreEnum.USER_INFO] |
||||
if (!userInfo) { |
||||
return headers |
||||
} |
||||
headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] |
||||
return headers |
||||
} |
||||
|
||||
/** |
||||
* * 自定义请求 |
||||
* @param targetParams 当前组件参数 |
||||
* @param globalParams 全局参数 |
||||
*/ |
||||
export const customizeHttp = (targetParams: RequestConfigType, globalParams: RequestGlobalConfigType) => { |
||||
if (!targetParams || !globalParams) { |
||||
return |
||||
} |
||||
// 全局
|
||||
const { |
||||
// 全局请求源地址
|
||||
requestOriginUrl, |
||||
// 全局请求内容
|
||||
requestParams: globalRequestParams |
||||
} = globalParams |
||||
|
||||
// 目标组件(优先级 > 全局组件)
|
||||
const { |
||||
// 请求地址
|
||||
requestUrl, |
||||
// 普通 / sql
|
||||
requestContentType, |
||||
// 获取数据的方式
|
||||
requestDataType, |
||||
// 请求方式 get/post/del/put/patch
|
||||
requestHttpType, |
||||
// 请求体类型 none / form-data / x-www-form-urlencoded / json /xml
|
||||
requestParamsBodyType, |
||||
// SQL 请求对象
|
||||
requestSQLContent, |
||||
// 请求内容 params / cookie / header / body: 同 requestParamsBodyType
|
||||
requestParams: targetRequestParams |
||||
} = targetParams |
||||
|
||||
// 静态排除
|
||||
if (requestDataType === RequestDataTypeEnum.STATIC) return |
||||
|
||||
if (!requestUrl) { |
||||
return |
||||
} |
||||
|
||||
// 处理头部
|
||||
let headers: RequestParamsObjType = { |
||||
...globalRequestParams.Header, |
||||
...targetRequestParams.Header |
||||
} |
||||
headers = translateStr(headers) |
||||
// 处理 token 和多租户的头
|
||||
headers = appendTokenAndTenant(headers, requestUrl) |
||||
|
||||
// data 参数
|
||||
let data: RequestParamsObjType | FormData | string = {} |
||||
// params 参数
|
||||
let params: RequestParamsObjType = { ...targetRequestParams.Params } |
||||
params = translateStr(params) |
||||
// form 类型处理
|
||||
let formData: FormData = new FormData() |
||||
formData.set('default', 'defaultData') |
||||
// 类型处理
|
||||
|
||||
switch (requestParamsBodyType) { |
||||
case RequestBodyEnum.NONE: |
||||
break |
||||
|
||||
case RequestBodyEnum.JSON: |
||||
headers['Content-Type'] = ContentTypeEnum.JSON |
||||
data = translateStr(JSON.parse(targetRequestParams.Body['json'])) |
||||
// json 赋值给 data
|
||||
break |
||||
|
||||
case RequestBodyEnum.XML: |
||||
headers['Content-Type'] = ContentTypeEnum.XML |
||||
// xml 字符串赋值给 data
|
||||
data = translateStr(targetRequestParams.Body['xml']) |
||||
break |
||||
|
||||
case RequestBodyEnum.X_WWW_FORM_URLENCODED: { |
||||
headers['Content-Type'] = ContentTypeEnum.FORM_URLENCODED |
||||
const bodyFormData = targetRequestParams.Body['x-www-form-urlencoded'] |
||||
for (const i in bodyFormData) formData.set(i, translateStr(bodyFormData[i])) |
||||
// FormData 赋值给 data
|
||||
data = formData |
||||
break |
||||
} |
||||
|
||||
case RequestBodyEnum.FORM_DATA: { |
||||
headers['Content-Type'] = ContentTypeEnum.FORM_DATA |
||||
const bodyFormUrlencoded = targetRequestParams.Body['form-data'] |
||||
for (const i in bodyFormUrlencoded) { |
||||
formData.set(i, translateStr(bodyFormUrlencoded[i])) |
||||
} |
||||
// FormData 赋值给 data
|
||||
data = formData |
||||
break |
||||
} |
||||
} |
||||
|
||||
// sql 处理
|
||||
if (requestContentType === RequestContentTypeEnum.SQL) { |
||||
headers['Content-Type'] = ContentTypeEnum.JSON |
||||
data = requestSQLContent |
||||
} |
||||
|
||||
try { |
||||
const url = (new Function("return `" + `${requestOriginUrl}${requestUrl}`.trim() + "`"))(); |
||||
return axiosInstance({ |
||||
url, |
||||
method: requestHttpType, |
||||
data, |
||||
params, |
||||
headers |
||||
}) |
||||
} catch (error) { |
||||
console.log(error) |
||||
window['$message'].error('URL地址格式有误!') |
||||
} |
||||
} |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
{ |
||||
"nodes": [ |
||||
{ |
||||
"id": "0", |
||||
"name": "Myriel", |
||||
"symbolSize": "@integer(0, 50)", |
||||
"x": -266.82776, |
||||
"y": 299.6904, |
||||
"value": "@integer(0, 50)", |
||||
"category": 3 |
||||
}, |
||||
{ |
||||
"id": "1", |
||||
"name": "Napoleon", |
||||
"symbolSize": "@integer(0, 50)", |
||||
"x": -418.08344, |
||||
"y": 446.8853, |
||||
"value": "@integer(0, 50)", |
||||
"category": 5 |
||||
}, |
||||
{ |
||||
"id": "2", |
||||
"name": "MlleBaptistine", |
||||
"symbolSize": "@integer(0, 50)", |
||||
"x": -212.76357, |
||||
"y": 245.29176, |
||||
"value": "@integer(0, 50)", |
||||
"category": 1 |
||||
}, |
||||
{ |
||||
"id": "3", |
||||
"name": "MmeMagloire", |
||||
"symbolSize": "@integer(0, 50)", |
||||
"x": -242.82404, |
||||
"y": 235.26283, |
||||
"value": "@integer(0, 50)", |
||||
"category": 1 |
||||
}, |
||||
{ |
||||
"id": "4", |
||||
"name": "CountessDeLo", |
||||
"symbolSize": "@integer(0, 50)", |
||||
"x": -379.30386, |
||||
"y": 429.06424, |
||||
"value": "@integer(0, 50)", |
||||
"category": 0 |
||||
} |
||||
], |
||||
"links": [ |
||||
{ |
||||
"source": "1", |
||||
"target": "@integer(2, 4)" |
||||
}, |
||||
{ |
||||
"source": "2", |
||||
"target": "@integer(3, 4)" |
||||
}, |
||||
{ |
||||
"source": "3", |
||||
"target": "@integer(0, 2)" |
||||
}, |
||||
{ |
||||
"source": "3", |
||||
"target": "@integer(0, 1)" |
||||
}, |
||||
{ |
||||
"source": "4", |
||||
"target": "@integer(0, 3)" |
||||
} |
||||
], |
||||
"categories": [ |
||||
{ |
||||
"name": "A" |
||||
}, |
||||
{ |
||||
"name": "B" |
||||
}, |
||||
{ |
||||
"name": "C" |
||||
}, |
||||
{ |
||||
"name": "D" |
||||
}, |
||||
{ |
||||
"name": "E" |
||||
}, |
||||
{ |
||||
"name": "F" |
||||
}, |
||||
{ |
||||
"name": "G" |
||||
}, |
||||
{ |
||||
"name": "H" |
||||
}, |
||||
{ |
||||
"name": "I" |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,199 @@
@@ -0,0 +1,199 @@
|
||||
{ |
||||
"xAxis": [ |
||||
"12a", |
||||
"1a", |
||||
"2a", |
||||
"3a", |
||||
"4a", |
||||
"5a", |
||||
"6a", |
||||
"7a", |
||||
"8a", |
||||
"9a", |
||||
"10a", |
||||
"11a", |
||||
"12p", |
||||
"1p", |
||||
"2p", |
||||
"3p", |
||||
"4p", |
||||
"5p", |
||||
"6p", |
||||
"7p", |
||||
"8p", |
||||
"9p", |
||||
"10p", |
||||
"11p" |
||||
], |
||||
"yAxis": ["Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday"], |
||||
"seriesData": [ |
||||
[0, 0, "@integer(0, 10)"], |
||||
[1, 0, "@integer(0, 10)"], |
||||
[2, 0, "-"], |
||||
[3, 0, "-"], |
||||
[4, 0, "-"], |
||||
[5, 0, "-"], |
||||
[6, 0, "-"], |
||||
[7, 0, "-"], |
||||
[8, 0, "-"], |
||||
[9, 0, "-"], |
||||
[10, 0, "-"], |
||||
[11, 0, "@integer(0, 10)"], |
||||
[12, 0, "@integer(0, 10)"], |
||||
[13, 0, "@integer(0, 10)"], |
||||
[14, 0, "@integer(0, 10)"], |
||||
[15, 0, "@integer(0, 10)"], |
||||
[16, 0, "@integer(0, 10)"], |
||||
[17, 0, "@integer(0, 10)"], |
||||
[18, 0, "@integer(0, 10)"], |
||||
[19, 0, "@integer(0, 10)"], |
||||
[20, 0, "@integer(0, 10)"], |
||||
[21, 0, "@integer(0, 10)"], |
||||
[22, 0, "@integer(0, 10)"], |
||||
[23, 0, "@integer(0, 10)"], |
||||
[0, 1, 7], |
||||
[1, 1, "-"], |
||||
[2, 1, "-"], |
||||
[3, 1, "-"], |
||||
[4, 1, "-"], |
||||
[5, 1, "-"], |
||||
[6, 1, "-"], |
||||
[7, 1, "-"], |
||||
[8, 1, "-"], |
||||
[9, 1, "-"], |
||||
[10, 1, "@integer(0, 10)"], |
||||
[11, 1, "@integer(0, 10)"], |
||||
[12, 1, "@integer(0, 10)"], |
||||
[13, 1, "@integer(0, 10)"], |
||||
[14, 1, "@integer(0, 10)"], |
||||
[15, 1, "@integer(0, 10)"], |
||||
[16, 1, "@integer(0, 10)"], |
||||
[17, 1, "@integer(0, 10)"], |
||||
[18, 1, "@integer(0, 10)"], |
||||
[19, 1, "@integer(0, 10)"], |
||||
[20, 1, "@integer(0, 10)"], |
||||
[21, 1, "@integer(0, 10)"], |
||||
[22, 1, "@integer(0, 10)"], |
||||
[23, 1, "@integer(0, 10)"], |
||||
[0, 2, 1], |
||||
[1, 2, 1], |
||||
[2, 2, "-"], |
||||
[3, 2, "-"], |
||||
[4, 2, "-"], |
||||
[5, 2, "-"], |
||||
[6, 2, "-"], |
||||
[7, 2, "-"], |
||||
[8, 2, "-"], |
||||
[9, 2, "-"], |
||||
[10, 2, "@integer(0, 10)"], |
||||
[11, 2, "@integer(0, 10)"], |
||||
[12, 2, "@integer(0, 10)"], |
||||
[13, 2, "@integer(0, 10)"], |
||||
[14, 2, "@integer(0, 10)"], |
||||
[15, 2, "@integer(0, 10)"], |
||||
[16, 2, "@integer(0, 10)"], |
||||
[17, 2, "@integer(0, 10)"], |
||||
[18, 2, "@integer(0, 10)"], |
||||
[19, 2, "@integer(0, 10)"], |
||||
[20, 2, "@integer(0, 10)"], |
||||
[21, 2, "@integer(0, 10)"], |
||||
[22, 2, "@integer(0, 10)"], |
||||
[23, 2, "@integer(0, 10)"], |
||||
[0, 3, 7], |
||||
[1, 3, 3], |
||||
[2, 3, "-"], |
||||
[3, 3, "-"], |
||||
[4, 3, "-"], |
||||
[5, 3, "-"], |
||||
[6, 3, "-"], |
||||
[7, 3, "-"], |
||||
[8, 3, 1], |
||||
[9, 3, "-"], |
||||
[10, 3, "@integer(0, 10)"], |
||||
[11, 3, "@integer(0, 10)"], |
||||
[12, 3, "@integer(0, 10)"], |
||||
[13, 3, "@integer(0, 10)"], |
||||
[14, 3, "@integer(0, 10)"], |
||||
[15, 3, "@integer(0, 10)"], |
||||
[16, 3, "@integer(0, 10)"], |
||||
[17, 3, "@integer(0, 10)"], |
||||
[18, 3, "@integer(0, 10)"], |
||||
[19, 3, "@integer(0, 10)"], |
||||
[20, 3, "@integer(0, 10)"], |
||||
[21, 3, "@integer(0, 10)"], |
||||
[22, 3, "@integer(0, 10)"], |
||||
[23, 3, "@integer(0, 10)"], |
||||
[0, 4, "@integer(0, 10)"], |
||||
[1, 4, "@integer(0, 10)"], |
||||
[2, 4, "-"], |
||||
[3, 4, "-"], |
||||
[4, 4, "-"], |
||||
[5, 4, "@integer(0, 10)"], |
||||
[6, 4, "-"], |
||||
[7, 4, "-"], |
||||
[8, 4, "-"], |
||||
[9, 4, "@integer(0, 10)"], |
||||
[10, 4, "@integer(0, 10)"], |
||||
[11, 4, "@integer(0, 10)"], |
||||
[12, 4, "@integer(0, 10)"], |
||||
[13, 4, "@integer(0, 10)"], |
||||
[14, 4, "@integer(0, 10)"], |
||||
[15, 4, "@integer(0, 10)"], |
||||
[16, 4, "@integer(0, 10)"], |
||||
[17, 4, "@integer(0, 10)"], |
||||
[18, 4, "@integer(0, 10)"], |
||||
[19, 4, "@integer(0, 10)"], |
||||
[20, 4, "@integer(0, 10)"], |
||||
[21, 4, "@integer(0, 10)"], |
||||
[22, 4, "@integer(0, 10)"], |
||||
[23, 4, "-"], |
||||
[0, 5, "@integer(0, 10)"], |
||||
[1, 5, "@integer(0, 10)"], |
||||
[2, 5, "-"], |
||||
[3, 5, "@integer(0, 10)"], |
||||
[4, 5, "-"], |
||||
[5, 5, "-"], |
||||
[6, 5, "-"], |
||||
[7, 5, "-"], |
||||
[8, 5, "@integer(0, 10)"], |
||||
[9, 5, "-"], |
||||
[10, 5, "@integer(0, 10)"], |
||||
[11, 5, "@integer(0, 10)"], |
||||
[12, 5, "@integer(0, 10)"], |
||||
[13, 5, "@integer(0, 10)"], |
||||
[14, 5, "@integer(0, 10)"], |
||||
[15, 5, "@integer(0, 10)"], |
||||
[16, 5, "@integer(0, 10)"], |
||||
[17, 5, "@integer(0, 10)"], |
||||
[18, 5, "-"], |
||||
[19, 5, "@integer(0, 10)"], |
||||
[20, 5, "@integer(0, 10)"], |
||||
[21, 5, "@integer(0, 10)"], |
||||
[22, 5, "@integer(0, 10)"], |
||||
[23, 5, "-"], |
||||
[0, 6, "@integer(0, 10)"], |
||||
[1, 6, "-"], |
||||
[2, 6, "-"], |
||||
[3, 6, "-"], |
||||
[4, 6, "-"], |
||||
[5, 6, "-"], |
||||
[6, 6, "-"], |
||||
[7, 6, "-"], |
||||
[8, 6, "-"], |
||||
[9, 6, "-"], |
||||
[10, 6, "@integer(0, 10)"], |
||||
[11, 6, "-"], |
||||
[12, 6, "@integer(0, 10)"], |
||||
[13, 6, "@integer(0, 10)"], |
||||
[14, 6, "@integer(0, 10)"], |
||||
[15, 6, "@integer(0, 10)"], |
||||
[16, 6, "-"], |
||||
[17, 6, "-"], |
||||
[18, 6, "-"], |
||||
[19, 6, "-"], |
||||
[20, 6, "@integer(0, 10)"], |
||||
[21, 6, "@integer(0, 10)"], |
||||
[22, 6, "@integer(0, 10)"], |
||||
[23, 6, "@integer(0, 10)"] |
||||
] |
||||
} |
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
import test from './test.mock' |
||||
import { MockMethod } from 'vite-plugin-mock' |
||||
import { RequestHttpEnum } from '@/enums/httpEnum' |
||||
|
||||
// 单个X数据
|
||||
export const chartDataUrl = '/mock/chartData' |
||||
export const chartSingleDataUrl = '/mock/chartSingleData' |
||||
export const numberFloatUrl = '/mock/number/float' |
||||
export const numberIntUrl = '/mock/number/int' |
||||
export const textUrl = '/mock/text' |
||||
export const imageUrl = '/mock/image' |
||||
export const rankListUrl = '/mock/rankList' |
||||
export const scrollBoardUrl = '/mock/scrollBoard' |
||||
export const radarUrl = '/mock/radarData' |
||||
export const heatMapUrl = '/mock/heatMapData' |
||||
export const scatterBasicUrl = '/mock/scatterBasic' |
||||
export const mapUrl = '/mock/map' |
||||
export const capsuleUrl = '/mock/capsule' |
||||
export const wordCloudUrl = '/mock/wordCloud' |
||||
export const treemapUrl = '/mock/treemap' |
||||
export const threeEarth01Url = '/mock/threeEarth01Data' |
||||
export const sankeyUrl = '/mock/sankey' |
||||
export const graphUrl = '/mock/graphData' |
||||
|
||||
const mockObject: MockMethod[] = [ |
||||
{ |
||||
// 正则
|
||||
// url: /\/mock\/mockData(|\?\S*)$/,
|
||||
url: chartDataUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchMockData |
||||
}, |
||||
{ |
||||
url: chartSingleDataUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchMockSingleData |
||||
}, |
||||
{ |
||||
url: numberFloatUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchNumberFloat |
||||
}, |
||||
{ |
||||
url: numberIntUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchNumberInt |
||||
}, |
||||
{ |
||||
url: textUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchText |
||||
}, |
||||
{ |
||||
url: imageUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchImage(Math.round(Math.random() * 10)) |
||||
}, |
||||
{ |
||||
url: rankListUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchRankList |
||||
}, |
||||
{ |
||||
url: scrollBoardUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchScrollBoard |
||||
}, |
||||
{ |
||||
url: radarUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchRadar |
||||
}, |
||||
{ |
||||
url: heatMapUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchHeatmap |
||||
}, |
||||
{ |
||||
url: scatterBasicUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchScatterBasic |
||||
}, |
||||
{ |
||||
url: mapUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchMap |
||||
}, |
||||
{ |
||||
url: capsuleUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchCapsule |
||||
}, |
||||
{ |
||||
url: wordCloudUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchWordCloud |
||||
}, |
||||
{ |
||||
url: treemapUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchTreemap |
||||
}, |
||||
{ |
||||
url: threeEarth01Url, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.threeEarth01Data |
||||
}, |
||||
{ |
||||
url: sankeyUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.fetchSankey |
||||
}, |
||||
{ |
||||
url: graphUrl, |
||||
method: RequestHttpEnum.GET, |
||||
response: () => test.graphData |
||||
}, |
||||
] |
||||
|
||||
export default mockObject |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
{ |
||||
"markers|50": [ |
||||
{ |
||||
"name": "某某地市", |
||||
"value": "@integer(2, 20)", |
||||
"position": ["@float(115, 117, 1, 6)", "@float(38, 40, 1, 6)"] |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
{ |
||||
"label": [ |
||||
{ |
||||
"name": "a" |
||||
}, |
||||
{ |
||||
"name": "b" |
||||
}, |
||||
{ |
||||
"name": "a1" |
||||
}, |
||||
{ |
||||
"name": "a2" |
||||
}, |
||||
{ |
||||
"name": "b1" |
||||
}, |
||||
{ |
||||
"name": "b2" |
||||
} |
||||
], |
||||
"links": [ |
||||
{ |
||||
"source": "a", |
||||
"target": "a1", |
||||
"value": "@integer(0, 10)" |
||||
}, |
||||
{ |
||||
"source": "a", |
||||
"target": "a2", |
||||
"value": "@integer(0, 10)" |
||||
}, |
||||
{ |
||||
"source": "b", |
||||
"target": "b1", |
||||
"value": "@integer(0, 10)" |
||||
}, |
||||
{ |
||||
"source": "a", |
||||
"target": "b1", |
||||
"value": "@integer(0, 10)" |
||||
}, |
||||
{ |
||||
"source": "b1", |
||||
"target": "a1", |
||||
"value": "@integer(0, 10)" |
||||
}, |
||||
{ |
||||
"source": "b1", |
||||
"target": "b2", |
||||
"value": "@integer(0, 10)" |
||||
} |
||||
], |
||||
"levels": [ |
||||
{ |
||||
"depth": 0, |
||||
"itemStyle": { |
||||
"color": "#decbe4" |
||||
}, |
||||
"lineStyle": { |
||||
"color": "source", |
||||
"opacity": 0.9 |
||||
} |
||||
}, |
||||
{ |
||||
"depth": 1, |
||||
"itemStyle": { |
||||
"color": "#b3cde3" |
||||
}, |
||||
"lineStyle": { |
||||
"color": "source", |
||||
"opacity": 0.6 |
||||
} |
||||
}, |
||||
{ |
||||
"depth": 2, |
||||
"itemStyle": { |
||||
"color": "#ccebc5" |
||||
}, |
||||
"lineStyle": { |
||||
"color": "source", |
||||
"opacity": 0.6 |
||||
} |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
[ |
||||
{ |
||||
"dimensions": ["data1"], |
||||
"source": [ |
||||
[10.0, "@integer(0, 100)"], |
||||
[8.07, "@integer(0, 100)"], |
||||
[13.0, "@integer(0, 100)"], |
||||
[9.05, "@integer(0, 100)"], |
||||
[11.0, "@integer(0, 100)"], |
||||
[14.0, "@integer(0, 100)"], |
||||
[13.4, "@integer(0, 100)"], |
||||
[10.0, "@integer(0, 100)"], |
||||
[14.0, "@integer(0, 100)"], |
||||
[12.5, "@integer(0, 100)"], |
||||
[9.15, "@integer(0, 100)"], |
||||
[11.5, "@integer(0, 100)"], |
||||
[3.03, "@integer(0, 100)"], |
||||
[12.2, "@integer(0, 100)"], |
||||
[2.02, "@integer(0, 100)"], |
||||
[1.05, "@integer(0, 100)"], |
||||
[4.05, "@integer(0, 100)"], |
||||
[6.03, "@integer(0, 100)"], |
||||
[12.0, "@integer(0, 100)"], |
||||
[12.0, "@integer(0, 100)"], |
||||
[7.08, "@integer(0, 100)"], |
||||
[5.02, "@integer(0, 100)"] |
||||
] |
||||
}, |
||||
{ |
||||
"dimensions": ["data2"], |
||||
"source": [ |
||||
[10.0, "@integer(0, 70)"], |
||||
[8.07, "@integer(0, 70)"], |
||||
[13.0, "@integer(0, 70)"], |
||||
[9.05, "@integer(0, 70)"], |
||||
[11.0, "@integer(0, 70)"], |
||||
[14.0, "@integer(0, 70)"], |
||||
[13.4, "@integer(0, 70)"], |
||||
[10.0, "@integer(0, 70)"], |
||||
[14.0, "@integer(0, 70)"], |
||||
[12.5, "@integer(0, 70)"], |
||||
[9.15, "@integer(0, 70)"], |
||||
[11.5, "@integer(0, 70)"], |
||||
[3.03, "@integer(0, 70)"], |
||||
[12.2, "@integer(0, 70)"], |
||||
[2.02, "@integer(0, 70)"], |
||||
[1.05, "@integer(0, 70)"], |
||||
[4.05, "@integer(0, 70)"], |
||||
[6.03, "@integer(0, 70)"], |
||||
[12.0, "@integer(0, 70)"], |
||||
[12.0, "@integer(0, 70)"], |
||||
[7.08, "@integer(0, 70)"], |
||||
[5.02, "@integer(0, 70)"] |
||||
] |
||||
} |
||||
] |
@ -0,0 +1,239 @@
@@ -0,0 +1,239 @@
|
||||
import heatmapJson from './heatMapData.json' |
||||
import scatterJson from './scatter.json' |
||||
import mapJson from './map.json' |
||||
import tTreemapJson from './treemap.json' |
||||
import sankeyJson from './sankey.json' |
||||
import graphDataJson from './graph.json' |
||||
|
||||
export default { |
||||
// 单图表
|
||||
fetchMockSingleData: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: { |
||||
dimensions: ['product', 'dataOne'], |
||||
'source|20': [ |
||||
{ |
||||
product: '@name', |
||||
'dataOne|0-900': 3 |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
// 胶囊图
|
||||
fetchCapsule: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: { |
||||
dimensions: ['name', 'value'], |
||||
"source|2-5": [ |
||||
{ 'name|+1': ["厦门","福州","北京","上海","新疆","郑州","湖南","内蒙古"], 'value|0-40': 20 }, |
||||
] |
||||
} |
||||
}, |
||||
// 图表
|
||||
fetchMockData: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: { |
||||
dimensions: ['product', 'dataOne', 'dataTwo', 'dataThree'], |
||||
'source|20': [ |
||||
{ |
||||
product: '@name', |
||||
'dataOne|100-900': 3, |
||||
'dataTwo|100-900': 3, |
||||
'dataThree|100-900': 3 |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
// 排名列表
|
||||
fetchRankList: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
'data|50': [{ name: '@name', 'value|100-900': 5 }] |
||||
}, |
||||
// 轮播表格
|
||||
fetchScrollBoard: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: [ |
||||
['行1列1', '行1列2', '1'], |
||||
['行2列1', '行2列2', '2'], |
||||
['行3列1', '行3列2', '3'], |
||||
['行4列1', '行4列2', '4'], |
||||
['行5列1', '行5列2', '5'], |
||||
['行6列1', '行6列2', '6'], |
||||
['行7列1', '行7列2', '行7列3'], |
||||
['行8列1', '行8列2', '行8列3'], |
||||
['行9列1', '行9列2', '行9列3'], |
||||
['行10列1', '行10列2', '行10列3'] |
||||
] |
||||
}, |
||||
// 获取数字-浮点型
|
||||
fetchNumberFloat: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: '@float(0, 0.99, 1, 4)' |
||||
}, |
||||
// 获取数字-整型
|
||||
fetchNumberInt: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: '@integer(0, 100)' |
||||
}, |
||||
// 文字
|
||||
fetchText: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: '@paragraph(1, 10)' |
||||
}, |
||||
// 图片
|
||||
fetchImage: (num: number) => ({ |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: `https://robohash.org/${num}` |
||||
}), |
||||
// 雷达
|
||||
fetchRadar: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: { |
||||
radarIndicator: [ |
||||
{ name: '@name', max: 10000 }, |
||||
{ name: '@name', max: 10000 }, |
||||
{ name: '@name', max: 10000 }, |
||||
{ name: '@name', max: 10000 }, |
||||
{ name: '@name', max: 10000 }, |
||||
{ name: '@name', max: 10000 } |
||||
], |
||||
seriesData: [ |
||||
{ |
||||
value: [ |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)' |
||||
], |
||||
name: 'data1' |
||||
}, |
||||
{ |
||||
value: [ |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)', |
||||
'@integer(0, 10000)' |
||||
], |
||||
name: 'data2' |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
// 热力图
|
||||
fetchHeatmap: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: heatmapJson |
||||
}, |
||||
// 散点图
|
||||
fetchScatterBasic: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: scatterJson |
||||
}, |
||||
// 中国地图
|
||||
fetchMap: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: mapJson |
||||
}, |
||||
// 词云
|
||||
fetchWordCloud: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: [ |
||||
{ |
||||
name: '@name', |
||||
value: 8000, |
||||
textStyle: { |
||||
color: '#78fbb2' |
||||
}, |
||||
emphasis: { |
||||
textStyle: { |
||||
color: 'red' |
||||
} |
||||
} |
||||
}, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' }, |
||||
{ name: '@name', value: '@integer(10, 8000)' } |
||||
] |
||||
}, |
||||
// 树图
|
||||
fetchTreemap: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: tTreemapJson |
||||
}, |
||||
// 三维地球
|
||||
threeEarth01Data: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: [ |
||||
{ |
||||
startArray: { name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }, |
||||
'endArray|10': [{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }] |
||||
} |
||||
] |
||||
}, |
||||
// 桑基图
|
||||
fetchSankey: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: sankeyJson |
||||
}, |
||||
// 关系图
|
||||
graphData: { |
||||
code: 0, |
||||
status: 200, |
||||
msg: '请求成功', |
||||
data: graphDataJson |
||||
}, |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
[ |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)", |
||||
"children": [ |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 500)" |
||||
}, |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 500)" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)", |
||||
"children": [ |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 00)" |
||||
}, |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 500)" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)", |
||||
"children": [ |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)", |
||||
"children": [ |
||||
{ |
||||
"name": "@name", |
||||
"value": "@integer(0, 1000)" |
||||
} |
||||
] |
||||
} |
||||
] |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
export * from '@/api/path/project.api' |
||||
export * from '@/api/path/system.api' |
||||
export * from '@/api/path/infra.api' |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
import { http } from '@/api/http' |
||||
import { httpErrorHandle } from '@/utils' |
||||
import { RequestHttpEnum, ModuleTypeEnum, ContentTypeEnum } from '@/enums/httpEnum' |
||||
|
||||
// * 上传文件
|
||||
export const uploadFile = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)<string>(`${ModuleTypeEnum.INFRA}/file/upload`, data, ContentTypeEnum.FORM_DATA) |
||||
return res |
||||
} catch { |
||||
httpErrorHandle() |
||||
} |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
import { http } from '@/api/http' |
||||
import { httpErrorHandle } from '@/utils' |
||||
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum' |
||||
import { ProjectItem, ProjectDetail } from './project' // TODO 分页返回,优化使用 ProjectItem
|
||||
|
||||
// * 项目列表
|
||||
export const projectListApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.GET)<{ |
||||
list: ProjectItem[], |
||||
count: number |
||||
}>(`${ModuleTypeEnum.PROJECT}/my-page`, data) |
||||
return res |
||||
} catch { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// * 新增项目
|
||||
export const createProjectApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)<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}/get`, data) |
||||
return res |
||||
} catch { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// * 保存项目
|
||||
export const saveProjectApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, data) |
||||
return res |
||||
} catch { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// * 修改项目基础信息
|
||||
export const updateProjectApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, 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() |
||||
} |
||||
} |
||||
|
||||
// * 修改发布状态 [0 已发布, 1 未发布]
|
||||
export const changeProjectReleaseApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, data) |
||||
return res |
||||
} catch { |
||||
httpErrorHandle() |
||||
} |
||||
} |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
export type ProjectItem = { |
||||
/** |
||||
* 项目 id |
||||
*/ |
||||
id: string |
||||
/** |
||||
* 项目名称 |
||||
*/ |
||||
name: string |
||||
/** |
||||
* 项目状态: |
||||
* |
||||
* 0 - 已发布 |
||||
* 1 - 未发布 |
||||
*/ |
||||
status: number |
||||
/** |
||||
* 创建时间 |
||||
*/ |
||||
createTime: number |
||||
/** |
||||
* 预览图片 URL |
||||
*/ |
||||
picUrl: string |
||||
/** |
||||
* 创建者 |
||||
*/ |
||||
creator: string |
||||
/** |
||||
* 项目备注 |
||||
*/ |
||||
remark: string |
||||
} |
||||
|
||||
export interface ProjectDetail extends ProjectItem { |
||||
/** |
||||
* 项目参数 |
||||
*/ |
||||
content: string |
||||
} |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
import { http } from '@/api/http' |
||||
import { httpErrorHandle } from '@/utils' |
||||
import { RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum' |
||||
import {AuthLoginRespVO, ProfileVO} from './system' |
||||
|
||||
// * 登录
|
||||
export const loginApi = async (data: object) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)<AuthLoginRespVO>(`${ModuleTypeEnum.SYSTEM}/auth/login`, data) |
||||
console.log(res) |
||||
return res |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// * 登出
|
||||
export const logoutApi = async () => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/auth/logout`) |
||||
return res |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// 查询用户个人信息
|
||||
export const getUserProfileApi = async () => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.GET)<ProfileVO>(`${ModuleTypeEnum.SYSTEM}/user/profile/get`) |
||||
return res |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
|
||||
// 获取验证图片 以及token
|
||||
export const getCodeApi = async (data: any) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/captcha/get`, data) |
||||
return res.data |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// 滑动或者点选验证
|
||||
export const reqCheckApi = async (data: any) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/captcha/check`, data) |
||||
return res.data |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
||||
|
||||
// 使用租户名,获得租户编号
|
||||
export const getTenantIdByNameApi = async (name: string) => { |
||||
try { |
||||
const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.SYSTEM}/tenant/get-id-by-name?name=` + name) |
||||
return res |
||||
} catch (err) { |
||||
httpErrorHandle() |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
export interface AuthLoginRespVO { |
||||
/** |
||||
* 用户编号 |
||||
*/ |
||||
userId: number |
||||
/** |
||||
* 访问令牌 |
||||
*/ |
||||
accessToken: string |
||||
/** |
||||
* 刷新令牌 |
||||
*/ |
||||
refreshToken: string |
||||
/** |
||||
* 过期时间 |
||||
*/ |
||||
expiresTime: number |
||||
} |
||||
|
||||
export interface ProfileVO { |
||||
id: number |
||||
nickname: string |
||||
} |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 377 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 999 B |
After Width: | Height: | Size: 983 B |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.4 KiB |