Compare commits

...

57 Commits

Author SHA1 Message Date
奔跑的面条
b8705c4f31 build: 修改版本号到1.0.4 2022-06-16 10:47:23 +08:00
奔跑的面条
588cc380cd fix: 解决 login 背景打包后消失的问题 2022-06-15 17:36:06 +08:00
奔跑的面条
5eca551271 feat: 新增 preview 模式 2022-06-15 17:30:24 +08:00
奔跑的面条
5522837b00 feat: 新增 commitlint,修改部分规则 2022-06-15 17:09:40 +08:00
奔跑的面条
29fd85254b docs: 修改说明文档 2022-06-15 16:15:49 +08:00
奔跑的面条
61af1674b9 fix: 修改npm,yarn打包问题,升级依赖文件 2022-06-15 16:01:31 +08:00
奔跑的面条
d8ccff8de5 fix: 解决 npm ,yarn 安装依赖报错的问题 2022-06-15 15:45:55 +08:00
奔跑的面条
e29c427f8d chore: 优化渐变文本展示图 2022-06-15 09:46:53 +08:00
Ryker
b8d0d1a2ff feat: 新增信息-文字-新增【渐变文字】组件
feat: 新增信息-文字-新增【渐变文字】组件
2022-06-15 01:43:07 +00:00
奔跑的面条
ffa127593a fix: 修改滚动表格组件TS报错问题 2022-06-14 12:14:44 +08:00
奔跑的面条
f9c17c732a Merge pull request !19 from 王志强/master 2022-06-14 03:27:49 +00:00
wangzhiqiang
427c5589b2 修改小组件边框-04下边框缺失bug 2022-06-14 11:02:58 +08:00
王志强
b618f9e865 新增滚动列表
新增滚动列表
2022-06-14 02:46:52 +00:00
wangzhiqiang
2182c7d34a Merge branch 'master' of https://gitee.com/assxy/go-view 2022-06-14 09:13:28 +08:00
wangzhiqiang
9482e9aba3 Merge branch 'master' of https://gitee.com/MTrun/go-view
# Conflicts:
#	src/packages/components/Decorates/Mores/Number/index.vue
2022-06-14 09:12:46 +08:00
奔跑的面条
6d5651fd1d !17 fit: 数字翻牌-动态数据
Merge pull request !17 from Ryker/number
2022-06-14 01:02:55 +00:00
13050022537
c195b69003 添加滚动列表 2022-06-13 20:51:15 +08:00
wangzhiqiang
8216cd7604 增加轮播表--未完成 2022-06-13 20:51:12 +08:00
ryker
8d691f2d69 数字翻牌动态数据 2022-06-13 18:04:01 +08:00
奔跑的面条
09d8c58e73 style: 优化水球图代码结构 2022-06-13 17:30:17 +08:00
Ryker
0823bf1d9c feat:新增水球图的形状、文字大小配置
水球图的形状、文字大小配置
2022-06-13 09:09:28 +00:00
王志强
43e8b9939b feat:小组件-数字翻牌-增加精度参数
小组件-数字翻牌-增加精度参数
2022-06-13 05:12:24 +00:00
奔跑的面条
c792482c60 chore: 优化进度条组件内容 2022-06-13 13:05:41 +08:00
奔跑的面条
e48ca421d8 chore: 优化【饼图-环形】展示图 2022-06-13 12:02:43 +08:00
alex
ac23d4c8dc feat: PieCircle
新增饼图环形
2022-06-13 03:59:29 +00:00
wangzhiqiang
68b49ea710 小组件-数字翻牌-增加精度参数 2022-06-13 11:55:13 +08:00
wangzhiqiang
99287497cc Merge branch 'master' of https://gitee.com/MTrun/go-view 2022-06-13 09:07:13 +08:00
奔跑的面条
70f9df7650 fix: 解决缩放比例展示不全的问题 2022-06-12 18:44:53 +08:00
奔跑的面条
8b39ec2773 style: 优化进度条组件 2022-06-12 18:25:44 +08:00
奔跑的面条
eafbcb2cde 新增Naive UI 进度条
Merge pull request !11 from alex/chart
2022-06-12 09:39:08 +00:00
alex li
f8f5bc7688 添加naive ui的进度条 2022-06-11 23:53:01 +08:00
wangzhiqiang
0335b379ea Merge branch 'master' of https://gitee.com/MTrun/go-view 2022-06-11 15:54:23 +08:00
奔跑的面条
3c221345dd chore: 优化拖拽锚点 2022-06-11 15:09:42 +08:00
wangzhiqiang
13bcf3c649 修改gitgnore 2022-06-11 15:05:21 +08:00
奔跑的面条
58fee4a86f fix:修改请求地址为null时引起的异常bug 2022-06-11 14:36:19 +08:00
奔跑的面条
a22e4b814b fix: 修改双折线图X轴无法变化的问题 2022-06-11 14:08:25 +08:00
奔跑的面条
c249c120c1 build: 升级NaiveUI到2.30.3 2022-06-11 14:03:41 +08:00
奔跑的面条
c8d016e1b4 Merge branch 'master' into dev 2022-06-10 16:28:07 +08:00
奔跑的面条
2e6d87ab80 update README.md. 2022-06-10 08:27:34 +00:00
奔跑的面条
5c07885a4e fix: 解决列表页布局问题 2022-06-09 09:07:39 +08:00
奔跑的面条
5f8db36888 fix: 解决列表页布局错误问题 2022-06-09 09:00:39 +08:00
奔跑的面条
ce34a7ed2a fix: 解决导出图片白边的问题 2022-06-09 08:59:36 +08:00
奔跑的面条
b3422eaede chore: 优化搜索结果列表UI 2022-06-05 11:40:32 +08:00
奔跑的面条
8b57ffa124 chore: 修改发布文案提示,修改 dialog 全局封装 2022-06-04 16:17:11 +08:00
奔跑的面条
dcbaf37a69 Merge branch 'dev' 2022-06-03 20:11:07 +08:00
奔跑的面条
741ba1a039 style: 优化类名,页面UI细节 2022-06-03 20:10:52 +08:00
奔跑的面条
80176e5737 docs: 更新md说明 2022-06-03 19:56:03 +08:00
奔跑的面条
04ed5d354d Merge branch 'dev' 2022-06-01 23:08:54 +08:00
奔跑的面条
fa678e1089 fix: 修改列表页标题过长的展示问题 2022-06-01 23:08:36 +08:00
奔跑的面条
8575d27504 Merge branch 'dev' 2022-06-01 22:28:10 +08:00
奔跑的面条
fa6ef30cd8 build: 修改版本为1.0.3 2022-06-01 22:27:59 +08:00
奔跑的面条
14402e6674 Merge branch 'dev' 2022-06-01 22:27:14 +08:00
奔跑的面条
0915e162fd fix: 解决导入组件后控制组件不会出现的bug 2022-06-01 22:26:52 +08:00
奔跑的面条
fffe49cd0f update README.md. 2022-05-31 09:01:51 +00:00
奔跑的面条
94fc6138a0 docs: 修改MD说明 2022-05-31 11:40:06 +08:00
奔跑的面条
4f248e57c8 docs: 修改首页说明 2022-05-31 11:36:26 +08:00
奔跑的面条
e5bf08f709 docs: 更新说明文档 2022-05-29 15:45:45 +08:00
57 changed files with 2953 additions and 803 deletions

3
.commitlintrc.js Normal file
View File

@@ -0,0 +1,3 @@
module.exports = {
extends: ["@commitlint/config-conventional"]
};

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ node_modules
dist
dist-ssr
*.local
.vscode

4
.husky/commit-msg Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint -e

View File

@@ -6,15 +6,20 @@ 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] 格式校验"

View File

@@ -1,9 +1,15 @@
## 总览
![logo](readme/logo-t-y.png)
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。当然低代码也不是 “银弹”,希望所有人员都能理智看待此技术。
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
项目-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
### 纯 **😶前端** 分支: **`master`**
### 携带 **👻后端** 请求分支: **`master-fetch`**
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
@@ -39,7 +45,7 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
| 名称 | 版本 | 名称 | 版本 |
| ---- | ------- | ------- | ----- |
| node | 16.14.x | npm | 8.5.x |
| pnpm | 6.32.x | windows | 11 |
| pnpm | 7.1.x | windows | 11 |
已完成图表:
@@ -57,11 +63,18 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
## 安装
本项目采用` pnpm` 进行包管理,经反馈若采用 `npm/yarn` 等方式安装依赖会导致错误,请使用 `pnpm` 安装依赖包。
本项目采用` pnpm` 进行包管理
```shell
#pnpm建议使用nrm切换到淘宝源
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
#pnpm
pnpm install
#yarn
yarn install
#npm
npm install
```
## 启动
@@ -96,10 +109,22 @@ yarn run build
make dist
```
## 代码提交
* feat: 新功能
* fix: 修复 Bug
* docs: 文档修改
* perf: 性能优化
* revert: 版本回退
* ci: CICD集成相关
* test: 添加测试代码
* refactor: 代码重构
* build: 影响项目构建或依赖修改
* style: 不影响程序逻辑的代码修改
* chore: 不属于以上类型的其他类型(日常事务)
## 交流
QQ 群1030129384
![QQ群](readme/goView-QQ.png)

View File

@@ -1,10 +1,12 @@
{
"name": "go-view",
"version": "1.0.2",
"version": "1.0.4",
"scripts": {
"dev": "vite --host",
"build": "vue-tsc --noEmit && vite build",
"new": "plop --plopfile ./plop/plopfile.js"
"preview": "vite preview",
"new": "plop --plopfile ./plop/plopfile.js",
"postinstall": "husky install"
},
"dependencies": {
"@types/color": "^3.0.3",
@@ -18,10 +20,11 @@
"highlight.js": "^11.5.0",
"html2canvas": "^1.4.1",
"keymaster": "^1.6.2",
"naive-ui": "^2.29.0",
"naive-ui": "2.30.3",
"pinia": "^2.0.13",
"screenfull": "^6.0.1",
"vue": "^3.2.31",
"vue-demi": "^0.13.1",
"vue-i18n": "9.1.9",
"vue-router": "4.0.12",
"vue3-lazyload": "^0.2.5-beta",
@@ -29,6 +32,8 @@
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@commitlint/cli": "^17.0.2",
"@commitlint/config-conventional": "^17.0.2",
"@types/node": "^16.11.26",
"@typescript-eslint/eslint-plugin": "^5.18.0",
"@typescript-eslint/parser": "^5.18.0",
@@ -38,6 +43,7 @@
"@vitejs/plugin-vue-jsx": "^1.3.9",
"@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",
@@ -45,6 +51,7 @@
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.5.0",
"husky": "^8.0.1",
"lodash": "~4.17.21",
"mockjs": "^1.1.0",
"plop": "^3.0.5",

2327
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
module.exports = {
printWidth: 80,
printWidth: 120,
tabWidth: 2,
useTabs: false,
singleQuote: true,
semi: false,
trailingComma: "es5",
trailingComma: "none",
bracketSpacing: true,
jsxSingleQuote: true,
jsxBracketSameLine: false,

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -21,7 +21,6 @@ const option = {
xAxis: {
show: true,
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
show: true,

View File

@@ -0,0 +1,47 @@
import { publicConfig } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { ProcessConfig } from './index'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
export const types = [
{
label: '线形',
value: 'line'
},
{
label: '圆形',
value: 'circle'
},
{
label: '仪表盘',
value: 'dashboard'
},
]
export const indicatorPlacements = [
{
label: '内部',
value: 'inside'
},
{
label: '外部',
value: 'outside'
}
]
export const option = {
dataset: 36,
type: types[2].value,
color: '#4992FFFF',
// 指标位置(线条时可用)
indicatorPlacement: "outside"
}
export default class Config extends publicConfig implements CreateComponentType {
public key = ProcessConfig.key
public attr = {...chartInitConfig, h: 500, zIndex: -1}
public chartConfig = cloneDeep(ProcessConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,49 @@
<template>
<!-- 默认展开 -->
<CollapseItem
name="进度条" :expanded="true">
<SettingItemBox name="内容">
<SettingItem name="数值">
<!-- config.ts 里的 option 对应 --><!-- n-input-number NaiveUI 的控件 -->
<n-input-number v-model:value="optionData.dataset" size="small" :min="0" placeholder="进度值"></n-input-number>
</SettingItem>
<!-- 颜色粗细等等... -->
</SettingItemBox>
<SettingItemBox name="外观">
<SettingItem name="形状">
<n-select v-model:value="optionData.type" :options="types" placeholder="选择形状" />
</SettingItem>
<SettingItem name="指标位置" v-if="optionData.type == types[0].value">
<n-select v-model:value="optionData.indicatorPlacement" :options="indicatorPlacements" placeholder="选择形状" />
</SettingItem>
<!-- 颜色粗细等等... -->
<SettingItem name="进度条颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.color"
></n-color-picker>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
// 以下是封装的设置模块布局组件,具体效果可在官网查看
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
// 获取 option 的数据,便于使用 typeof 获取类型
import { option, types, indicatorPlacements} from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,25 @@
// 展示图片
import image from '@/assets/images/chart/charts/process.png'
// 公共类型声明
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
// 当前[信息模块]分类声明
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const ProcessConfig: ConfigType = {
// 唯一key
key: 'Process',
// 图表组件渲染 Components 格式: V + key
chartKey: 'VProcess',
// 配置组件渲染 Components 格式: VC + key
conKey: 'VCProcess',
// 名称
title: 'NaiveUI-进度',
// 子分类目录
category: ChatCategoryEnum.MORE,
// 子分类目录
categoryName: ChatCategoryEnumName.MORE,
// 包分类
package: PackagesCategoryEnum.CHARTS,
// 图片
image: image
}

View File

@@ -0,0 +1,27 @@
<template>
<n-progress
:type="type"
:percentage="dataset"
:indicator-placement="indicatorPlacement"
:color="color"
/>
</template>
<script setup lang="ts">
import { PropType, toRefs, watch } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true,
},
})
// 取配置数据
const { type, color, indicatorPlacement, dataset } = toRefs(props.chartConfig.option)
useChartDataFetch(props.chartConfig, useChartEditStore)
</script>

View File

@@ -3,6 +3,37 @@ import { CreateComponentType } from '@/packages/index.d'
import { WaterPoloConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const shapes = [
{
label: '圆形',
value: 'circle'
},
{
label: '正方形',
value: 'rect'
},
{
label: '带圆角的正方形',
value: 'roundRect'
},
{
label: '正三角形',
value: 'triangle'
},
{
label: '菱形',
value: 'diamond'
},
{
label: '水滴',
value: 'pin'
},
{
label: '箭头',
value: 'arrow'
},
]
export const includes = []
export const option = {
@@ -10,6 +41,7 @@ export const option = {
series: [
{
type: 'liquidFill',
shape: shapes[0].value,
radius: '90%',
data: [0],
center: ['50%', '50%'],

View File

@@ -15,19 +15,26 @@
placeholder="水球数值"
></n-input-number>
</SettingItem>
<SettingItem name="形状">
<n-select v-model:value="item.shape" :options="shapes" placeholder="选择形状" />
</SettingItem>
<SettingItem name="文本">
<n-input-number v-model:value="item.label.normal.textStyle.fontSize" :min="0" :step="1" size="small" placeholder="文字大小">
</n-input-number>
</SettingItem>
<SettingItem name="颜色1">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.color[0].colorStops[0].color"
></n-color-picker>
></n-color-picker>
</SettingItem>
<SettingItem name="颜色2">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.color[0].colorStops[1].color"
></n-color-picker>
></n-color-picker>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="背景" :alone="true">
@@ -44,7 +51,7 @@
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { option } from './config'
import { option, shapes } from './config'
import {
CollapseItem,
SettingItemBox,

View File

@@ -1,3 +1,4 @@
import { ProcessConfig } from './Process/index'
import { RadarConfig } from './Radar/index'
import { FunnelConfig } from './Funnel/index'
import { HeatmapConfig } from './Heatmap/index'
@@ -5,4 +6,4 @@ import { PointConfig } from './Point/index'
import { WaterPoloConfig } from './WaterPolo/index'
import { TreeMapConfig } from './TreeMap/index'
export default [RadarConfig, FunnelConfig, HeatmapConfig,PointConfig, WaterPoloConfig, TreeMapConfig]
export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, PointConfig, WaterPoloConfig, TreeMapConfig]

View File

@@ -0,0 +1,63 @@
import { echartOptionProfixHandle, publicConfig } from '@/packages/public'
import { PieCircleConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
export const includes = ['legend']
const option = {
tooltip: {
show: true,
trigger: 'item'
},
legend: {
show: true,
},
dataset: 0.25,
title: {
text: 25 + "%",
x: "center",
y: "center",
textStyle: {
color: "#56B9F8",
fontSize: 30
}
},
series: [
{
type: "pie",
radius: ["75%", "80%"],
center: ["50%", "50%"],
hoverAnimation: true,
color: ["#00bcd44a", "transparent"],
label: {
show: false
},
data: [
{
value: [25],
itemStyle: {
color: "#03a9f4",
shadowBlur: 10,
shadowColor:"#97e2f5"
}
},
{
value: [75],
itemStyle: {
color: "#00bcd44a",
shadowBlur: 0,
shadowColor:"#00bcd44a"
}
}
]
},
]
}
export default class Config extends publicConfig implements CreateComponentType {
public key: string = PieCircleConfig.key
public chartConfig = PieCircleConfig
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -0,0 +1,89 @@
<template>
<!-- 遍历 seriesList -->
<CollapseItem v-for="(item, index) in config.series" :key="index" :name="`圆环`" :expanded="true">
<SettingItemBox name="数据">
<SettingItem name="数值">
<n-input-number v-model:value="config.dataset" :min="0" :max="1" :step="0.01" size="small" placeholder="数值">
</n-input-number>
</SettingItem>
</SettingItemBox>
<!-- Echarts 全局设置 -->
<SettingItemBox name="进度条">
<SettingItem name="颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.data[0].itemStyle.color"
></n-color-picker>
</SettingItem>
<SettingItem name="阴影模糊等级">
<n-input-number v-model:value="item.data[0].itemStyle.shadowBlur" :min="0" :max="50" :step="1" size="small" placeholder="阴影模糊等级">
</n-input-number>
</SettingItem>
<SettingItem name="阴影颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.data[0].itemStyle.shadowColor"
></n-color-picker>
</SettingItem>
</SettingItemBox>
<!-- 中心标题 -->
<SettingItemBox v-if="config.title" name="标题">
<SettingItem name="颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="config.title.textStyle.color"
></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number v-model:value="config.title.textStyle.fontSize" :min="0" :step="1" size="small" placeholder="字体大小">
</n-input-number>
</SettingItem>
</SettingItemBox>
<!-- 其他样式 -->
<SettingItemBox name="轨道样式">
<SettingItem name="颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.data[1].itemStyle.color"
></n-color-picker>
</SettingItem>
<SettingItem name="阴影模糊等级">
<n-input-number v-model:value="item.data[1].itemStyle.shadowBlur" :min="0" :step="1" size="small" placeholder="阴影模糊等级">
</n-input-number>
</SettingItem>
<SettingItem name="阴影颜色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="item.data[1].itemStyle.shadowColor"
></n-color-picker>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
// 以下是封装的设置模块布局组件,具体效果可在官网查看
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
import { GlobalThemeJsonType } from '@/settings/chartThemes'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const config = computed(() => {
return props.optionData
})
</script>

View File

@@ -0,0 +1,14 @@
import image from '@/assets/images/chart/charts/pie-circle.png'
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const PieCircleConfig: ConfigType = {
key: 'PieCircle',
chartKey: 'VPieCircle',
conKey: 'VCPieCircle',
title: '饼图-环形',
category: ChatCategoryEnum.PIE,
categoryName: ChatCategoryEnumName.PIE,
package: PackagesCategoryEnum.CHARTS,
image
}

View File

@@ -0,0 +1,71 @@
<template>
<v-chart ref="vChartRef" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize></v-chart>
</template>
<script setup lang="ts">
import {computed, PropType, reactive, watch} from 'vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import { mergeTheme } from '@/packages/public/chart'
import config, { includes } from './config'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import {
DatasetComponent,
GridComponent,
TooltipComponent,
LegendComponent,
TitleComponent,
} from 'echarts/components'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
use([
DatasetComponent,
CanvasRenderer,
PieChart,
GridComponent,
TooltipComponent,
LegendComponent,
TitleComponent
])
const option = reactive({
value: {}
})
watch(
() => props.chartConfig.option.dataset,
(newData) => {
// console.log('update:'+newData)
const d = parseFloat(`${newData}`) * 100
let config = props.chartConfig.option
config.title.text = d.toFixed(2) + "%"
config.series[0].data[0].value[0] = d
config.series[0].data[1].value[0] = 100 - d
option.value = mergeTheme(config, props.themeSetting, includes)
option.value = config
},
{
immediate: true,
}
)
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
</script>

View File

@@ -1,3 +1,4 @@
import { PieCommonConfig } from './PieCommon/index'
import { PieCircleConfig } from './PieCircle/index'
export default [PieCommonConfig]
export default [PieCommonConfig, PieCircleConfig]

View File

@@ -4,4 +4,4 @@ import Lines from './Lines'
import Mores from './Mores'
import Maps from './Maps'
export const ChartList = [...Bars, ...Pies, ...Lines, ...Maps , ...Mores]
export const ChartList = [...Bars, ...Pies, ...Lines, ...Maps, ...Mores]

View File

@@ -2,7 +2,7 @@
<div class="go-border-box">
<svg :width="w" :height="h">
<defs>
<filter :id="filterId" h="150%" width="150%" x="-25%" y="-25%">
<filter :id="filterId" height="150%" width="150%" x="-25%" y="-25%">
<feMorphology
operator="dilate"
radius="2"

View File

@@ -7,6 +7,7 @@ export const option = {
from: 50000,
to: 100000,
dur: 3,
precision: 0,
showSeparator: true,
numberSize: 24,
numberColor: '#4a9ef8',

View File

@@ -28,6 +28,13 @@
<n-text>展示分割符</n-text>
</n-space>
</SettingItem>
<SettingItem name="精度">
<n-input-number
v-model:value="optionData.precision"
size="small"
:min="0"
></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="数值">

View File

@@ -6,12 +6,8 @@
</span>
</template>
<span :style="`color:${numberColor};font-size:${numberSize}px`">
<n-number-animation
:from="from"
:to="to"
:duration="dur * 1000"
:show-separator="showSeparator"
></n-number-animation>
<n-number-animation :from="option.from" :to="option.to" :duration="dur * 1000" :show-separator="showSeparator"
:precision="precision"></n-number-animation>
</span>
<template #suffix>
<span :style="`color:${suffixColor};font-size:${numberSize}px`">
@@ -22,8 +18,10 @@
</template>
<script setup lang="ts">
import { PropType, toRefs } from 'vue'
import { PropType, toRefs, ref, reactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartDataFetch } from '@/hooks'
const props = defineProps({
chartConfig: {
@@ -31,20 +29,44 @@ const props = defineProps({
required: true,
},
})
const option = reactive({
from: 0,
to: 0,
})
const { w, h } = toRefs(props.chartConfig.attr)
const {
let {
dur,
showSeparator,
prefixText,
prefixColor,
suffixText,
suffixColor,
from,
to,
precision,
numberSize,
numberColor,
} = toRefs(props.chartConfig.option)
const updateNumber = (newData: number) => {
// 原来的目标值作为新的数字动画的起始值
option.from = option.to
option.to = newData
}
watch(
() => props.chartConfig.option.from,
() => {
option.from = props.chartConfig.option.from
}, { immediate: true }
)
watch(
() => props.chartConfig.option.to,
() => {
option.to = props.chartConfig.option.to
}, { immediate: true }
)
useChartDataFetch(props.chartConfig, useChartEditStore, updateNumber)
</script>
<style lang="scss" scoped>
@include go('decorates-number') {

View File

@@ -0,0 +1,20 @@
import { publicConfig } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TextGradientConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
dataset: '我是渐变文本',
size: 20,
gradient: {
from: '#0000FFFF',
to: '#00FF00FF',
deg: 45
}
}
export default class Config extends publicConfig implements CreateComponentType {
public key = TextGradientConfig.key
public chartConfig = cloneDeep(TextGradientConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,45 @@
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true">
<setting-item>
<n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="样式" :expanded="true">
<setting-item-box name="文字">
<setting-item name="字体大小">
<n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="渐变色参数">
<setting-item name="起始值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker>
</setting-item>
<setting-item name="结束值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker>
</setting-item>
<setting-item name="偏移角度">
<n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,14 @@
import image from '@/assets/images/chart/informations/text_gradient.png'
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const TextGradientConfig: ConfigType = {
key: 'TextGradient',
chartKey: 'VTextGradient',
conKey: 'VCTextGradient',
title: '渐变文字',
category: ChatCategoryEnum.TEXT,
categoryName: ChatCategoryEnumName.TEXT,
package: PackagesCategoryEnum.INFORMATIONS,
image
}

View File

@@ -0,0 +1,52 @@
<template>
<div class="go-text-box">
<n-gradient-text :size="size" :gradient="gradient">
{{ option.dataset }}
</n-gradient-text>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs, reactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true,
},
})
const option = reactive({
dataset: ''
})
const { w, h } = toRefs(props.chartConfig.attr)
const {
size,
gradient
} = toRefs(props.chartConfig.option)
const callback = (newData: string) => {
option.dataset = newData
}
watch(
() => props.chartConfig.option.dataset,
() => {
option.dataset = props.chartConfig.option.dataset
}, { immediate: true }
)
useChartDataFetch(props.chartConfig, useChartEditStore, callback)
</script>
<style lang="scss" scoped>
@include go('text-box') {
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

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

View File

@@ -0,0 +1,29 @@
import { publicConfig } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TableScrollBoardConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const option = {
header: ['列1', '列2', '列3'],
dataset: dataJson,
index: true,
columnWidth: [30, 100, 100],
align: ['center','right','right','right'],
rowNum: 5,
waitTime: 2,
headerHeight: 35,
carousel: 'single',
headerBGC: '#00BAFF',
oddRowBGC: '#003B51',
evenRowBGC: '#0A2732',
}
export default class Config
extends publicConfig
implements CreateComponentType
{
public key = TableScrollBoardConfig.key
public chartConfig = cloneDeep(TableScrollBoardConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,121 @@
<template>
<CollapseItem name="列表" :expanded="true">
<SettingItemBox name="基础">
<SettingItem name="表行数">
<n-input-number
v-model:value="optionData.rowNum"
:min="1"
size="small"
placeholder="请输入自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="轮播时间(s)">
<n-input-number
v-model:value="optionData.waitTime"
:min="1"
size="small"
placeholder="请输入轮播时间"
></n-input-number>
</SettingItem>
<SettingItem name="表头高度">
<n-input-number
v-model:value="optionData.headerHeight"
:min="1"
size="small"
placeholder="请输入表头高度"
></n-input-number>
</SettingItem>
<SettingItem name="显示行号">
<n-switch size="small" v-model:value="optionData.index" />
</SettingItem>
</SettingItemBox>
<SettingItemBox name="配置" :alone="true">
<SettingItem name="表头数据">
<n-input
v-model:value="header"
:min="1"
size="small"
placeholder="表头数据(英文','分割)"
></n-input>
</SettingItem>
<SettingItem name="列对齐方式">
<n-input
v-model:value="align"
:min="1"
size="small"
placeholder="对齐方式(英文','分割)"
></n-input>
</SettingItem>
<SettingItem name="列宽度">
<n-input
v-model:value="columnWidth"
:min="1"
size="small"
placeholder="列宽度(英文','分割)"
></n-input>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="样式">
<SettingItem name="表头背景色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.headerBGC"
></n-color-picker>
</SettingItem>
<SettingItem name="奇数行背景色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.oddRowBGC"
></n-color-picker>
</SettingItem>
<SettingItem name="偶数行背景色">
<n-color-picker
size="small"
:modes="['hex']"
v-model:value="optionData.evenRowBGC"
></n-color-picker>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, ref, watch } from 'vue'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
const header = ref(props.optionData.header.toString())
const align = ref(props.optionData.align.toString())
const columnWidth = ref(props.optionData.columnWidth.toString())
watch([header, align, columnWidth],([headerNew,alignNew,columnWidthNew],[headerOld,alignOld,columnWidthOld])=>{
if(headerNew !== headerOld){
props.optionData.header = headerNew.split(',')
}
if(alignNew !== alignOld){
props.optionData.align = alignNew.split(',')
}
if(columnWidthNew !== columnWidthOld){
// @ts-ignore
props.optionData.columnWidth = columnWidthNew.split(',')
}
})
</script>

View File

@@ -0,0 +1,12 @@
[
["行1列1", "行1列2", "行1列3"],
["行2列1", "行2列2", "行2列3"],
["行3列1", "行3列2", "行3列3"],
["行4列1", "行4列2", "行4列3"],
["行5列1", "行5列2", "行5列3"],
["行6列1", "行6列2", "行6列3"],
["行7列1", "行7列2", "行7列3"],
["行8列1", "行8列2", "行8列3"],
["行9列1", "行9列2", "行9列3"],
["行10列1", "行10列2", "行10列3"]
]

View File

@@ -0,0 +1,14 @@
import image from '@/assets/images/chart/tables/table_scrollboard.png'
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const TableScrollBoardConfig: ConfigType = {
key: 'TableScrollBoard',
chartKey: 'VTableScrollBoard',
conKey: 'VCTableScrollBoard',
title: '轮播列表',
category: ChatCategoryEnum.TABLE,
categoryName: ChatCategoryEnumName.TABLE,
package: PackagesCategoryEnum.TABLES,
image
}

View File

@@ -0,0 +1,355 @@
<template>
<div class="dv-scroll-board">
<div class="header" v-if="status.header.length && status.mergedConfig"
:style="`background-color: ${status.mergedConfig.headerBGC};`">
<div class="header-item" v-for="(headerItem, i) in status.header" :key="`${headerItem}${i}`" :style="`
height: ${status.mergedConfig.headerHeight}px;
line-height: ${status.mergedConfig.headerHeight}px;
width: ${status.widths[i]}px;
`" :align="status.aligns[i]" v-html="headerItem" />
</div>
<div v-if="status.mergedConfig" class="rows"
:style="`height: ${h - (status.header.length ? status.mergedConfig.headerHeight : 0)}px;`">
<div class="row-item" v-for="(row, ri) in status.rows" :key="`${row.toString()}${row.scroll}`" :style="`
height: ${status.heights[ri]}px;
line-height: ${status.heights[ri]}px;
background-color: ${status.mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']};
`">
<div class="ceil" v-for="(ceil, ci) in row.ceils" :key="`${ceil}${ri}${ci}`"
:style="`width: ${status.widths[ci]}px;`" :align="status.aligns[ci]" v-html="ceil" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType, onUnmounted, reactive, toRefs, watch, onMounted } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import merge from 'lodash/merge'
import cloneDeep from 'lodash/cloneDeep'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true,
},
})
// 这里能拿到图表宽高等
const { w, h } = toRefs(props.chartConfig.attr)
// 这里能拿到上面 config.ts 里的 option 数据
// const { rowNum, headerHeight, index, backgroundColor } = toRefs(props.chartConfig.option)
const status = reactive({
defaultConfig: {
/**
* @description Board header
* @type {Array<String>}
* @default header = []
* @example header = ['column1', 'column2', 'column3']
*/
header: [],
/**
* @description Board dataset
* @type {Array<Array>}
* @default dataset = []
*/
dataset: [],
/**
* @description Row num
* @type {Number}
* @default rowNum = 5
*/
rowNum: 5,
/**
* @description Header background color
* @type {String}
* @default headerBGC = '#00BAFF'
*/
headerBGC: '#00BAFF',
/**
* @description Odd row background color
* @type {String}
* @default oddRowBGC = '#003B51'
*/
oddRowBGC: '#003B51',
/**
* @description Even row background color
* @type {String}
* @default evenRowBGC = '#003B51'
*/
evenRowBGC: '#0A2732',
/**
* @description Scroll wait time
* @type {Number}
* @default waitTime = 2
*/
waitTime: 2,
/**
* @description Header height
* @type {Number}
* @default headerHeight = 35
*/
headerHeight: 35,
/**
* @description Column width
* @type {Array<Number>}
* @default columnWidth = []
*/
columnWidth: [],
/**
* @description Column align
* @type {Array<String>}
* @default align = []
* @example align = ['left', 'center', 'right']
*/
align: [],
/**
* @description Show index
* @type {Boolean}
* @default index = false
*/
index: false,
/**
* @description index Header
* @type {String}
* @default indexHeader = '#'
*/
indexHeader: '#',
/**
* @description Carousel type
* @type {String}
* @default carousel = 'single'
* @example carousel = 'single' | 'page'
*/
carousel: 'single',
/**
* @description Pause scroll when mouse hovered
* @type {Boolean}
* @default hoverPause = true
* @example hoverPause = true | false
*/
hoverPause: true
},
mergedConfig: props.chartConfig.option,
header: [],
rowsData: [],
rows: [{
ceils: [],
rowIndex: 0,
scroll: 0
}],
widths: [],
heights: [0],
avgHeight: 0,
aligns: [],
animationIndex: 0,
animationHandler: 0,
updater: 0,
needCalc: false
})
const calcData = () => {
mergeConfig()
calcHeaderData()
calcRowsData()
calcWidths()
calcHeights()
calcAligns()
animation(true)
}
onMounted(()=> {
calcData()
})
const mergeConfig = () => {
status.mergedConfig = merge(cloneDeep(status.defaultConfig), props.chartConfig.option)
}
const calcHeaderData = () => {
let { header, index, indexHeader } = status.mergedConfig
if (!header.length) {
status.header = []
return
}
header = [...header]
if (index) header.unshift(indexHeader)
status.header = header
}
const calcRowsData = () => {
let { dataset, index, headerBGC, rowNum } = status.mergedConfig
if (index) {
dataset = dataset.map((row:any, i:number) => {
row = [...row]
const indexTag = `<span class="index" style="background-color: ${headerBGC};border-radius: 3px;padding: 0px 3px;">${i + 1}</span>`
row.unshift(indexTag)
return row
})
}
dataset = dataset.map((ceils:any, i:number) => ({ ceils, rowIndex: i }))
const rowLength = dataset.length
if (rowLength > rowNum && rowLength < 2 * rowNum) {
dataset = [...dataset, ...dataset]
}
dataset = dataset.map((d:any, i:number) => ({ ...d, scroll: i }))
status.rowsData = dataset
status.rows = dataset
}
const calcWidths = () => {
const { mergedConfig, rowsData } = status
const { columnWidth, header } = mergedConfig
const usedWidth = columnWidth.reduce((all:any, ws:number) => all + ws, 0)
let columnNum = 0
if (rowsData[0]) {
columnNum = (rowsData[0] as any).ceils.length
} else if (header.length) {
columnNum = header.length
}
const avgWidth = (w.value - usedWidth) / (columnNum - columnWidth.length)
const widths = new Array(columnNum).fill(avgWidth)
status.widths = merge(widths, columnWidth)
}
const calcHeights = (onresize = false) => {
const { mergedConfig, header } = status
const { headerHeight, rowNum, dataset } = mergedConfig
let allHeight = h.value
if (header.length) allHeight -= headerHeight
const avgHeight = allHeight / rowNum
status.avgHeight = avgHeight
if (!onresize) status.heights = new Array(dataset.length).fill(avgHeight)
}
const calcAligns = () => {
const { header, mergedConfig } = status
const columnNum = header.length
let aligns = new Array(columnNum).fill('left')
const { align } = mergedConfig
status.aligns = merge(aligns, align)
}
const animation = async (start = false) => {
const { needCalc } = status
if (needCalc) {
calcRowsData()
calcHeights()
status.needCalc = false
}
let { avgHeight, animationIndex, mergedConfig, rowsData, updater } = status
const { waitTime, carousel, rowNum } = mergedConfig
const rowLength = rowsData.length
if (rowNum >= rowLength) return
if (start) {
await new Promise(resolve => setTimeout(resolve, waitTime*1000))
if (updater !== status.updater) return
}
const animationNum = carousel === 'single' ? 1 : rowNum
let rows = rowsData.slice(animationIndex)
rows.push(...rowsData.slice(0, animationIndex))
status.rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1)
status.heights = new Array(rowLength).fill(avgHeight)
await new Promise(resolve => setTimeout(resolve, 300))
if (updater !== status.updater) return
status.heights.splice(0, animationNum, ...new Array(animationNum).fill(0))
animationIndex += animationNum
const back = animationIndex - rowLength
if (back >= 0) animationIndex = back
status.animationIndex = animationIndex
status.animationHandler = setTimeout(animation, waitTime*1000 - 300) as any
}
const stopAnimation = () => {
status.updater = (status.updater + 1) % 999999
if (!status.animationHandler) return
clearTimeout(status.animationHandler)
}
const onRestart = async () => {
if (!status.mergedConfig) return
stopAnimation()
calcData()
}
watch(
() => w.value,
() => {
onRestart()
}
)
watch(
() => h.value,
() => {
onRestart()
}
)
// 数据更新
watch(
() => props.chartConfig.option,
() => {
onRestart()
},
{deep:true}
)
// 数据更新 (默认更新 dataset若更新之后有其它操作可添加回调函数)
useChartDataFetch(props.chartConfig, useChartEditStore)
onUnmounted(() => {
stopAnimation()
})
</script>
<style lang="scss" scoped>
.dv-scroll-board {
position: relative;
width: 100%;
height: 100%;
color: #fff;
.text {
padding: 0 10px;
box-sizing: border-box;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.header {
display: flex;
flex-direction: row;
font-size: 15px;
.header-item {
transition: all 0.3s;
}
}
.rows {
overflow: hidden;
.row-item {
display: flex;
font-size: 14px;
transition: all 0.3s;
overflow: hidden;
}
}
}
</style>

View File

@@ -1,5 +1,6 @@
import { TableListConfig } from './TableList'
import { TableCommonConfig } from './TableCommon'
import { TableCategoryConfig } from './TableCategory'
import { TableScrollBoardConfig } from './TableScrollBoard'
export default [TableListConfig, TableCommonConfig, TableCategoryConfig]
export default [TableListConfig, TableScrollBoardConfig, TableCommonConfig, TableCategoryConfig]

View File

@@ -6,7 +6,8 @@ import { chartInitConfig } from '@/settings/designSetting'
const requestConfig: RequestConfigType = {
requestDataType: RequestDataTypeEnum.STATIC,
requestHttpType: RequestHttpEnum.GET
requestHttpType: RequestHttpEnum.GET,
requestUrl: ''
}
export class publicConfig implements PublicConfigType {

View File

@@ -1,5 +1,5 @@
// 闪烁
.animation-twinkle {
.go-animation-twinkle {
animation: twinkle 2s ease;
animation-iteration-count: infinite;
opacity: 1;

View File

@@ -28,7 +28,6 @@ export const loadingError = () => {
/**
* * render 对话框
* @param { Object} params 配置参数, 详见 https://www.naiveui.com/zh-CN/light/components/dialog
* @param { Function } dialogFn 函数
* ```
* 最简易的 demo
* goDialog({
@@ -44,14 +43,12 @@ export const goDialog = (
title?: string | (() => any)
// 提示
message?: string
// 取消提示词
negativeText?: string
// 取消按钮的属性
negativeButtonProps?: object,
// 确定提示词
positiveText?: string
// 确定按钮的属性
positiveButtonProps?: object,
// 取消提示词
negativeText?: string
// 是否不展示取消按钮
closeNegativeText?: boolean,
// 点击遮罩是否关闭
isMaskClosable?: boolean
// 回调
@@ -61,17 +58,16 @@ export const goDialog = (
promise?: boolean
promiseResCallback?: Function
promiseRejCallback?: Function
},
dialogFn?: Function
[T:string]: any
}
) => {
const {
type,
title,
message,
negativeText,
negativeButtonProps,
positiveText,
positiveButtonProps,
negativeText,
closeNegativeText,
isMaskClosable,
onPositiveCallback,
onNegativeCallback,
@@ -83,7 +79,7 @@ export const goDialog = (
const typeObj = {
// 自定义
[DialogEnum.DELETE]: {
fn: dialogFn || window['$dialog'].warning,
fn: window['$dialog'].warning,
message: message || '是否删除此数据?'
},
// 原有
@@ -108,7 +104,7 @@ export const goDialog = (
icon: renderIcon(InformationCircleIcon, { size: dialogIconSize }),
content: typeObj[type || DialogEnum.WARNING]['message'],
positiveText: positiveText || '确定',
negativeText: negativeText || '取消',
negativeText: closeNegativeText ? undefined : (negativeText || '取消'),
// 是否通过遮罩关闭
maskClosable: isMaskClosable || maskClosable,
onPositiveClick: async () => {

View File

@@ -178,7 +178,9 @@ export const canvasCut = (html: HTMLElement | null, callback?: Function) => {
return
}
html2canvas(html).then((canvas: HTMLCanvasElement) => {
html2canvas(html, {
backgroundColor: null
}).then((canvas: HTMLCanvasElement) => {
window['$message'].success('导出成功!')
downloadByA(canvas.toDataURL(), undefined, 'png')
if (callback) callback()

View File

@@ -39,7 +39,7 @@
@click="selectChartHandle(item)"
>
<img class="list-item-img" v-lazy="item.image" alt="展示图" />
<n-text depth="2">{{ item.title }}</n-text>
<n-text class="list-item-fs" depth="2">{{ item.title }}</n-text>
</div>
</n-scrollbar>
<div class="popover-modal"></div>
@@ -167,13 +167,27 @@ $width: 178px;
position: relative;
cursor: pointer;
padding: 2px;
padding-left: 6px;
margin-bottom: 5px;
&-fs {
font-size: 12px;
}
&-img {
height: 30px;
height: 28px;
margin-right: 5px;
border-radius: 5px;
}
&:hover {
&::before {
content: '';
position: absolute;
width: 3px;
height: 100%;
left: 0;
top: 0;
border-radius: 2px;
background-color: v-bind('themeColor');
}
&::after {
z-index: -1;
content: '';

View File

@@ -61,7 +61,7 @@
import { ref, toRefs } from 'vue'
import { icon } from '@/plugins'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { RequestHttpEnum } from '@/enums/httpEnum'
import { RequestHttpEnum, ResultEnum } from '@/enums/httpEnum'
import { chartDataUrl, rankListUrl, numberUrl } from '@/api/mock'
import { http } from '@/api/http'
import { SelectHttpType } from '../../index.d'
@@ -113,7 +113,7 @@ const sendHandle = async () => {
const res = await http(requestHttpType)(completePath || '', {})
setTimeout(() => {
loading.value = false
if (res.status === 200) {
if (res.status === ResultEnum.SUCCESS) {
// @ts-ignore
targetData.value.option.dataset = res.data
showMatching.value = true

View File

@@ -152,6 +152,7 @@ $min-width: 500px;
}
}
.scale-btn {
width: 90px;
font-size: 12px;
@include deep() {
.n-base-selection-label {

View File

@@ -71,15 +71,24 @@ const select = computed(() => {
border-radius: 5px;
background-color: #fff;
transform: translate(-40%, -30%);
&.t,
&.t {
width: 30px;
transform: translate(-50%, -50%);
}
&.b {
width: 30px;
transform: translate(-50%, -30%);
}
&.l,
&.r {
height: 30px;
}
&.r,
&.r {
transform: translate(-20%, -50%);
}
&.l {
transform: translate(-45%, -50%);
}
&.rt,
&.rb
{

View File

@@ -1,7 +1,7 @@
import { ref, nextTick } from 'vue'
import { UploadCustomRequestOptions } from 'naive-ui'
import { FileTypeEnum } from '@/enums/fileTypeEnum'
import { fetchChartComponent } from '@/packages/index'
import { fetchChartComponent, fetchConfigComponent } from '@/packages/index'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { ChartEditStoreEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@@ -27,6 +27,10 @@ const updateComponent = async (fileData: any, isSplace = false) => {
e.chartConfig.chartKey,
fetchChartComponent(e.chartConfig)
)
window['$vue'].component(
e.chartConfig.conKey,
fetchConfigComponent(e.chartConfig)
)
}
})
// 数据赋值

View File

@@ -11,7 +11,7 @@
<script setup lang="ts">
import { shallowReactive } from 'vue'
import { renderIcon, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
import { renderIcon, goDialog, fetchPathByName, routerTurnByPath, setSessionStorage, getLocalStorage } from '@/utils'
import { PreviewEnum } from '@/enums/pageEnum'
import { StorageEnum } from '@/enums/storageEnum'
import { useRoute } from 'vue-router'
@@ -55,7 +55,12 @@ const previewHandle = () => {
// 发布
const sendHandle = () => {
window['$message'].warning('该功能暂未实现(因为压根没有后台)')
goDialog({
message: '想体验发布功能,请前往 master-fetch 分支查看: https://gitee.com/MTrun/go-view/tree/master-fetch',
positiveText: '了然',
closeNegativeText: true,
onPositiveCallback: () => {}
})
}
const btnList = shallowReactive([

View File

@@ -5,7 +5,11 @@
</n-icon>
<n-text @click="handleFocus">
工作空间 -
<n-button v-show="!focus" secondary round size="tiny">{{ comTitle }}</n-button>
<n-button v-show="!focus" secondary round size="tiny">
<span class="title">
{{ comTitle }}
</span>
</n-button>
</n-text>
<n-input
@@ -41,7 +45,6 @@ const fetchProhectInfoById = () => {
return id[0]
}
return ''
}
const title = ref<string>(fetchProhectInfoById() || '')
@@ -63,3 +66,8 @@ const handleBlur = () => {
focus.value = false
}
</script>
<style lang="scss" scoped>
.title {
font-size: 15px;
}
</style>

View File

@@ -18,7 +18,6 @@
<!-- https://github.com/SortableJS/vue.draggable.next -->
<draggable
item-key="id"
tag="transition-group"
v-model="reverseList"
ghostClass="ghost"
@change="onMoveCallback"

View File

@@ -315,7 +315,7 @@ $carousel-image-height: 60vh;
align-items: center;
width: 100vw;
height: 100vh;
background: url('../../assets/images/login/login-bg.png') no-repeat 0 -120px;
background: url('@/assets/images/login/login-bg.png') no-repeat 0 -120px;
.bg-slot {
width: $carousel-width;
}

View File

@@ -26,56 +26,58 @@
</div>
</div>
<template #action>
<n-space class="list-footer" justify="space-between">
<n-text>
<div class="go-flex-items-center list-footer" justify="space-between">
<n-text class="go-ellipsis-1" :title="cardData.title">
{{ cardData.title || '' }}
</n-text>
<!-- 工具 -->
<n-space>
<n-text>
<n-badge
class="animation-twinkle"
dot
:color="cardData.release ? '#34c749' : '#fcbc40'"
></n-badge>
{{
cardData.release
? $t('project.release')
: $t('project.unreleased')
}}
</n-text>
<div class="go-flex-items-center list-footer-ri">
<n-space>
<n-text>
<n-badge
class="go-animation-twinkle"
dot
:color="cardData.release ? '#34c749' : '#fcbc40'"
></n-badge>
{{
cardData.release
? $t('project.release')
: $t('project.unreleased')
}}
</n-text>
<template v-for="item in fnBtnList" :key="item.key">
<template v-if="item.key === 'select'">
<n-dropdown
trigger="hover"
placement="bottom"
:options="selectOptions"
:show-arrow="true"
@select="handleSelect"
>
<n-button size="small">
<template #icon>
<component :is="item.icon"></component>
</template>
</n-button>
</n-dropdown>
</template>
<n-tooltip v-else placement="bottom" trigger="hover">
<template #trigger>
<n-button size="small" @click="handleSelect(item.key)">
<template #icon>
<component :is="item.icon"></component>
</template>
</n-button>
<template v-for="item in fnBtnList" :key="item.key">
<template v-if="item.key === 'select'">
<n-dropdown
trigger="hover"
placement="bottom"
:options="selectOptions"
:show-arrow="true"
@select="handleSelect"
>
<n-button size="small">
<template #icon>
<component :is="item.icon"></component>
</template>
</n-button>
</n-dropdown>
</template>
<component :is="item.label"></component>
</n-tooltip>
</template>
</n-space>
<n-tooltip v-else placement="bottom" trigger="hover">
<template #trigger>
<n-button size="small" @click="handleSelect(item.key)">
<template #icon>
<component :is="item.icon"></component>
</template>
</n-button>
</template>
<component :is="item.label"></component>
</n-tooltip>
</template>
</n-space>
</div>
<!-- end -->
</n-space>
</div>
</template>
</n-card>
</div>
@@ -227,7 +229,13 @@ $contentHeight: 180px;
}
}
.list-footer {
flex-wrap: nowrap;
justify-content: space-between;
line-height: 30px;
&-ri {
justify-content: flex-end;
min-width: 180px;
}
}
}
</style>

View File

@@ -43,7 +43,7 @@
<n-space>
<n-text>
<n-badge
class="animation-twinkle"
class="go-animation-twinkle"
dot
:color="cardData?.release ? '#34c749' : '#fcbc40'"
></n-badge>
@@ -129,7 +129,7 @@ $contentWidth: calc(82vw);
@include go('modal-box') {
width: $contentWidth;
.list-content {
margin-top: 20px;
margin-top: 28px;
border-radius: $--border-radius-base;
overflow: hidden;
@include background-image('background-point');

View File

@@ -10,7 +10,7 @@ function pathResolve(dir: string) {
}
export default defineConfig({
base: './',
base: '/',
// 路径重定向
resolve: {
alias: [