mirror of
https://gitee.com/dromara/go-view.git
synced 2025-10-15 06:52:10 +08:00
Pre Merge pull request !28 from 陪伴是最长情的告白¹³¹⁴/dev
This commit is contained in:
commit
4c502fd393
@ -13,9 +13,14 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
env: {
|
||||
'vue/setup-compiler-macros': true,
|
||||
node: true,
|
||||
},
|
||||
extends: ["plugin:vue/vue3-essential", "eslint:recommended"],
|
||||
extends: [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"./.eslintrc-auto-import.json"
|
||||
],
|
||||
rules: {
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +1,12 @@
|
||||
node_modules
|
||||
.history
|
||||
.husky
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
.vscode
|
||||
stats.html
|
||||
auto-imports.d.ts
|
||||
.eslintrc-auto-import.json
|
||||
components.d.ts
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install commitlint -e
|
32
package.json
32
package.json
@ -3,29 +3,33 @@
|
||||
"version": "1.0.6",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"build": "rimraf ./dist && npm run test && vite build",
|
||||
"preview": "vite preview",
|
||||
"new": "plop --plopfile ./plop/plopfile.js",
|
||||
"test": "vue-tsc --noEmit",
|
||||
"postinstall": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@vicons/carbon": "^0.12.0",
|
||||
"@vicons/ionicons5": "~0.11.0",
|
||||
"@vueuse/core": "^7.7.1",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^0.27.2",
|
||||
"color": "^4.2.3",
|
||||
"crypto-js": "^4.1.1",
|
||||
"echarts": "^5.3.2",
|
||||
"echarts-liquidfill": "^3.1.0",
|
||||
"highlight.js": "^11.5.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"keymaster": "^1.6.2",
|
||||
"lodash": "~4.17.21",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"naive-ui": "2.30.3",
|
||||
"pinia": "^2.0.13",
|
||||
"screenfull": "^6.0.1",
|
||||
"tiny-emitter": "^2.1.0",
|
||||
"vue": "^3.2.31",
|
||||
"vue-demi": "^0.13.1",
|
||||
"vue-echarts": "^6.0.2",
|
||||
"vue-i18n": "9.1.9",
|
||||
"vue-router": "4.0.12",
|
||||
"vue3-lazyload": "^0.2.5-beta",
|
||||
@ -35,37 +39,35 @@
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.0.2",
|
||||
"@commitlint/config-conventional": "^17.0.2",
|
||||
"@types/node": "^16.11.26",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@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": "^1.10.2",
|
||||
"@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",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"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",
|
||||
"prettier": "^2.6.2",
|
||||
"rollup-plugin-visualizer": "^5.7.1",
|
||||
"sass": "^1.49.11",
|
||||
"sass-loader": "^12.6.0",
|
||||
"typescript": "^4.6.3",
|
||||
"unplugin-auto-import": "^0.10.1",
|
||||
"unplugin-vue-components": "^0.21.1",
|
||||
"vite": "2.9.5",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-importer": "^0.2.5",
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vue-echarts": "^6.0.2",
|
||||
"vue-tsc": "^0.28.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
14
plop/component-template/config.ts
Normal file
14
plop/component-template/config.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { publicConfig } from '@/packages/public/publicConfig';
|
||||
import { ComponentConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType
|
||||
{
|
||||
public key = ComponentConfig.key
|
||||
public chartConfig = cloneDeep(ComponentConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
27
plop/component-template/config.vue
Normal file
27
plop/component-template/config.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<CollapseItem>
|
||||
<SettingItem>
|
||||
<SettingItemBox></SettingItemBox>
|
||||
</SettingItem>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import {
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<GlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
13
plop/component-template/index.ts
Normal file
13
plop/component-template/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { FormCategoryEnum, FormCategoryEnumName } from './../../index.d';
|
||||
import { PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { getComponentConfig } from '@/utils/componets';
|
||||
|
||||
export const ComponentConfig = getComponentConfig({
|
||||
key: 'InputCommon',
|
||||
title: '输入框',
|
||||
category: FormCategoryEnum.INPUT,
|
||||
categoryName: FormCategoryEnumName.INPUT,
|
||||
package: PackagesCategoryEnum.FORM,
|
||||
chartFrame: ChartFrameEnum.COMMON
|
||||
})
|
||||
|
18
plop/component-template/index.vue
Normal file
18
plop/component-template/index.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>your component</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
5189
pnpm-lock.yaml
generated
5189
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
BIN
readme/event-design.png
Normal file
BIN
readme/event-design.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 457 KiB |
@ -7,22 +7,30 @@
|
||||
size="small"
|
||||
></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="标题">
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker
|
||||
v-model:value="title.textStyle.color"
|
||||
size="small"
|
||||
></n-color-picker>
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number
|
||||
v-model:value="title.textStyle.fontSize"
|
||||
:min="1"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
<setting-item-box name="属性" :alone="true">
|
||||
<setting-item name="文本">
|
||||
<n-input v-model:value="title.text" size="small" type="text"></n-input>
|
||||
</setting-item>
|
||||
<!-- <setting-item name="textAlign">
|
||||
<n-select v-model:value="title.textAlign" size="small" :options="textAlignOptions" />
|
||||
</setting-item> -->
|
||||
<template v-if="title.textStyle">
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker
|
||||
v-model:value="title.textStyle.color"
|
||||
size="small"
|
||||
></n-color-picker>
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number
|
||||
v-model:value="title.textStyle.fontSize"
|
||||
:min="1"
|
||||
size="small"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
</template>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="副标题">
|
||||
<setting-item-box name="副标题" v-if="title.subtextStyle">
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
@ -374,4 +382,11 @@ const yAxis = computed(() => {
|
||||
const legend = computed(() => {
|
||||
return props.optionData.legend
|
||||
})
|
||||
|
||||
const textAlignOptions = [
|
||||
{label: '自动', value: 'auto'},
|
||||
{label: '左对齐', value: 'left'},
|
||||
{label: '右对齐', value: 'right'},
|
||||
{label: '居中对齐', value: 'center'},
|
||||
]
|
||||
</script>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template></template>
|
||||
|
||||
<script setup>
|
||||
import * as monaco from 'monaco-editor'
|
||||
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
||||
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
|
||||
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { ref, onBeforeUnmount, nextTick } from 'vue'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||
import { editor } from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||
|
||||
export const useMonacoEditor = (language = 'javascript') => {
|
||||
const designStore = useDesignStore()
|
||||
|
||||
let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null
|
||||
let monacoEditor: editor.IStandaloneCodeEditor | null = null
|
||||
let initReadOnly = false
|
||||
const el = ref<HTMLElement | null>(null)
|
||||
|
||||
@ -25,12 +25,12 @@ const designStore = useDesignStore()
|
||||
}
|
||||
|
||||
// 创建实例
|
||||
const createEditor = (editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) => {
|
||||
const createEditor = (editorOption: editor.IStandaloneEditorConstructionOptions = {}) => {
|
||||
if (!el.value) return
|
||||
const javascriptModel = monaco.editor.createModel('', language)
|
||||
const javascriptModel = editor.createModel('', language)
|
||||
initReadOnly = !!editorOption.readOnly
|
||||
// 创建
|
||||
monacoEditor = monaco.editor.create(el.value, {
|
||||
monacoEditor = editor.create(el.value, {
|
||||
model: javascriptModel,
|
||||
// 是否启用预览图
|
||||
minimap: { enabled: false },
|
||||
|
13
src/enums/componentEnum.ts
Normal file
13
src/enums/componentEnum.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export enum COMPONENT_SIZE_ENUM {
|
||||
TINY = 'tiny',
|
||||
SMALL = 'small',
|
||||
MEDIUM = 'medium',
|
||||
LARGE = 'large'
|
||||
}
|
||||
|
||||
export const componentSizeMap = new Map([
|
||||
[COMPONENT_SIZE_ENUM.TINY, '迷你'],
|
||||
[COMPONENT_SIZE_ENUM.SMALL, '小'],
|
||||
[COMPONENT_SIZE_ENUM.MEDIUM, '中'],
|
||||
[COMPONENT_SIZE_ENUM.LARGE, '大'],
|
||||
])
|
54
src/enums/eventEnum.ts
Normal file
54
src/enums/eventEnum.ts
Normal file
@ -0,0 +1,54 @@
|
||||
export enum EventType {
|
||||
CLICK = 'click',
|
||||
DBCLICK = 'dblclick',
|
||||
CHANGE = 'change',
|
||||
// MOUSE_ENTER = 'mouseenter',
|
||||
// MOUSE_LEAVE = 'mouseleave',
|
||||
MOUNTED = 'vnodeMounted',
|
||||
// OTHER = 'other'
|
||||
}
|
||||
|
||||
export const EventTypeTitle = {
|
||||
[EventType.CLICK]: '点击',
|
||||
[EventType.DBCLICK]: '双击',
|
||||
[EventType.CHANGE]: '值变化',
|
||||
// [EventType.MOUSE_ENTER]: '鼠标进入',
|
||||
// [EventType.MOUSE_LEAVE]: '鼠标移开',
|
||||
[EventType.MOUNTED]: '渲染完成',
|
||||
// [EventType.OTHER]: '其它',
|
||||
}
|
||||
|
||||
export enum EventTriggerType {
|
||||
COMPONENT = 'component',
|
||||
JAVASCRIPT = 'javascript'
|
||||
}
|
||||
|
||||
export const EventTriggerTypeMap = new Map(
|
||||
[
|
||||
[EventTriggerType.COMPONENT, '组件联动'],
|
||||
[EventTriggerType.JAVASCRIPT, '自定义js'],
|
||||
]
|
||||
)
|
||||
|
||||
// 数据组件事件
|
||||
export enum DATA_COMPONENT_EVENT_ENUM {
|
||||
LOAD_DATA ='loadData'
|
||||
}
|
||||
|
||||
export const dataComponentEventMap = new Map(
|
||||
[
|
||||
[DATA_COMPONENT_EVENT_ENUM.LOAD_DATA, '加载数据'],
|
||||
]
|
||||
)
|
||||
|
||||
// 公共事件
|
||||
export enum COMMON_EVENT_ENUM {
|
||||
FORCE_UPDATE ='forceUpdate'
|
||||
}
|
||||
|
||||
export const CommonEventMap = new Map(
|
||||
[
|
||||
[COMMON_EVENT_ENUM.FORCE_UPDATE, '强制更新'],
|
||||
]
|
||||
)
|
||||
|
@ -12,5 +12,7 @@ export enum StorageEnum {
|
||||
// 工作台布局配置
|
||||
GO_CHART_LAYOUT_STORE = 'GO_CHART_LAYOUT',
|
||||
// 工作台需要保存的数据
|
||||
GO_CHART_STORAGE_LIST = 'GO_CHART_STORAGE_LIST'
|
||||
GO_CHART_STORAGE_LIST = 'GO_CHART_STORAGE_LIST',
|
||||
// 数据收集
|
||||
GO_DATA_COLLECT = 'GO_DATA_COLLECT'
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export * from '@/hooks/useTheme.hook'
|
||||
export * from '@/hooks/usePreviewScale.hook'
|
||||
export * from '@/hooks/useCode.hook'
|
||||
export * from '@/hooks/useChartDataFetch.hook'
|
||||
export * from '@/hooks/useChartDataFetch.hook'
|
||||
export * from '@/hooks/useEventBus.hook'
|
@ -5,6 +5,7 @@ import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { RequestDataTypeEnum } from '@/enums/httpEnum'
|
||||
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
|
||||
import { useIntervalFn } from '@vueuse/core'
|
||||
|
||||
// 获取类型
|
||||
type ChartEditStoreType = typeof useChartEditStore
|
||||
@ -21,10 +22,16 @@ export const useChartDataFetch = (
|
||||
updateCallback?: (...args: any) => any
|
||||
) => {
|
||||
const vChartRef = ref<typeof VChart | null>(null)
|
||||
let fetchInterval: any = 0
|
||||
let pauseFn: any = null
|
||||
let resumeFn: any = null
|
||||
let fetchFn: any = null
|
||||
|
||||
const requestIntervalFn = () => {
|
||||
const chartEditStore = useChartEditStore()
|
||||
|
||||
pauseFn = null
|
||||
resumeFn = null
|
||||
fetchFn = null
|
||||
|
||||
// 全局数据
|
||||
const {
|
||||
@ -55,9 +62,7 @@ export const useChartDataFetch = (
|
||||
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
|
||||
if (!completePath) return
|
||||
|
||||
clearInterval(fetchInterval)
|
||||
|
||||
const fetchFn = async () => {
|
||||
fetchFn = async (callback: () => any) => {
|
||||
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.requestGlobalConfig))
|
||||
if (res && res.data) {
|
||||
try {
|
||||
@ -73,6 +78,7 @@ export const useChartDataFetch = (
|
||||
}
|
||||
}
|
||||
}
|
||||
callback && callback()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
@ -87,11 +93,17 @@ export const useChartDataFetch = (
|
||||
// 单位
|
||||
const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
|
||||
// 开启轮询
|
||||
if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
|
||||
if (time) {
|
||||
const { pause, resume, isActive } = useIntervalFn(fetchFn, intervalUnitHandle(time, unit))
|
||||
pauseFn = pause
|
||||
resumeFn = resume
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isPreview() && requestIntervalFn()
|
||||
return { vChartRef }
|
||||
return { vChartRef, pauseFn, resumeFn, fetchFn }
|
||||
}
|
||||
|
67
src/hooks/useEventBus.hook.ts
Normal file
67
src/hooks/useEventBus.hook.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import Emitter from 'tiny-emitter'
|
||||
import { onBeforeUnmount } from 'vue'
|
||||
|
||||
|
||||
/**
|
||||
* {
|
||||
* on: {
|
||||
* [event]: []
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
|
||||
type EventBusListeners = {
|
||||
[key: string]: () => any
|
||||
};
|
||||
|
||||
export type EventBusOptions = {
|
||||
on?: EventBusListeners
|
||||
once?: EventBusListeners
|
||||
}
|
||||
|
||||
|
||||
//@ts-ignore
|
||||
const bus = new Emitter()
|
||||
|
||||
const addListeners = (listeners: EventBusListeners | undefined, isOnce = false): void => {
|
||||
if(!listeners) return
|
||||
Object.keys(listeners).forEach(key => {
|
||||
console.info('监听事件:', key)
|
||||
bus[isOnce ? 'once' : 'on'](key, listeners[key])
|
||||
onBeforeUnmount(() => {
|
||||
bus.off(key, listeners[key])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 转换事件名
|
||||
const convertListeners = (listeners: EventBusListeners, dst: object, prefix = 'prefix'): void => {
|
||||
Object.keys(listeners).forEach((key: string) => {
|
||||
// @ts-ignore
|
||||
dst[`${prefix}:${key}`] = listeners[key]
|
||||
})
|
||||
}
|
||||
|
||||
export const convertEventBusListeners = (listeners: EventBusOptions, prefix: string): EventBusOptions => {
|
||||
const res = {
|
||||
on: {},
|
||||
once: {},
|
||||
}
|
||||
|
||||
if(listeners.on) {
|
||||
convertListeners(listeners.on, res.on, prefix)
|
||||
}
|
||||
|
||||
if(listeners.once) {
|
||||
convertListeners(listeners.once, res.once, prefix)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
export const useEventBus = (listeners: EventBusOptions = {}) => {
|
||||
addListeners(listeners.on);
|
||||
addListeners(listeners.once, true)
|
||||
return bus
|
||||
}
|
@ -20,7 +20,7 @@ async function appInit() {
|
||||
const app = createApp(App)
|
||||
|
||||
// 注册全局常用的 naive-ui 组件
|
||||
setupNaive(app)
|
||||
// setupNaive(app)
|
||||
|
||||
// 注册全局自定义指令
|
||||
setupDirectives(app)
|
||||
|
13
src/packages/components/Charts/Bars/BarCommon/enum.ts
Normal file
13
src/packages/components/Charts/Bars/BarCommon/enum.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { dataComponentEventMap } from '@/enums/eventEnum';
|
||||
import { OptionsType } from '@/packages/index.d';
|
||||
import { mapToOptions } from '@/utils';
|
||||
|
||||
//内置方法
|
||||
export const methodList = mapToOptions(dataComponentEventMap) as Array<OptionsType>
|
||||
|
||||
export const config = {
|
||||
key: 'BarCommon',
|
||||
title: '柱状图',
|
||||
methodList
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
import image from '@/assets/images/chart/charts/bar_x.png'
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { getComponentConfig } from '@/utils'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
import { config } from './enum'
|
||||
|
||||
export const BarCommonConfig: ConfigType = {
|
||||
key: 'BarCommon',
|
||||
chartKey: 'VBarCommon',
|
||||
conKey: 'VCBarCommon',
|
||||
title: '柱状图',
|
||||
export const BarCommonConfig: ConfigType = getComponentConfig({
|
||||
...config,
|
||||
category: ChatCategoryEnum.BAR,
|
||||
categoryName: ChatCategoryEnumName.BAR,
|
||||
package: PackagesCategoryEnum.CHARTS,
|
||||
chartFrame: ChartFrameEnum.ECHARTS,
|
||||
image
|
||||
}
|
||||
})
|
||||
|
@ -49,5 +49,15 @@ const option = computed(() => {
|
||||
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||
})
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
const { vChartRef, pauseFn, resumeFn, fetchFn } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
|
||||
defineExpose({
|
||||
loadData: async () => {
|
||||
if(fetchFn){
|
||||
pauseFn()
|
||||
await fetchFn()
|
||||
resumeFn()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
41
src/packages/components/Charts/Mores/Funnel/config.ts
Normal file
41
src/packages/components/Charts/Mores/Funnel/config.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { FunnelConfig } from './index'
|
||||
import dataJson from './data.json'
|
||||
import { echartOptionProfixHandle, publicConfig } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const includes = ['legend']
|
||||
|
||||
export const option = {
|
||||
title: {
|
||||
textStyle: {},
|
||||
},
|
||||
legend: {},
|
||||
color: [
|
||||
'#142f53', '#13407e', '#0f62d4', '#0c73ff'
|
||||
],
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'item',
|
||||
},
|
||||
dataset: {
|
||||
...dataJson
|
||||
},
|
||||
series: {
|
||||
sort: 'descending',
|
||||
orient: 'vertical',
|
||||
type: 'funnel',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'inside'
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType {
|
||||
public key = FunnelConfig.key
|
||||
public chartConfig = cloneDeep(FunnelConfig)
|
||||
// 图表配置项
|
||||
public option = echartOptionProfixHandle(option, includes)
|
||||
}
|
||||
|
@ -1,6 +1,64 @@
|
||||
<template>
|
||||
<CollapseItem
|
||||
name="朝向">
|
||||
<template #header>
|
||||
<n-switch
|
||||
checked-value="vertical"
|
||||
unchecked-value="horizontal"
|
||||
v-model:value="props.optionData.series.orient"
|
||||
>
|
||||
<template #checked>
|
||||
垂直
|
||||
</template>
|
||||
<template #unchecked>
|
||||
水平
|
||||
</template>
|
||||
</n-switch>
|
||||
</template>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem
|
||||
name="排序">
|
||||
<template #header>
|
||||
<n-switch
|
||||
checked-value="descending"
|
||||
unchecked-value="ascending"
|
||||
v-model:value="props.optionData.series.sort"
|
||||
>
|
||||
<template #checked>
|
||||
降序
|
||||
</template>
|
||||
<template #unchecked>
|
||||
升序
|
||||
</template>
|
||||
</n-switch>
|
||||
</template>
|
||||
</CollapseItem>
|
||||
|
||||
<CollapseItem
|
||||
name="间隔"
|
||||
:expanded="true">
|
||||
<n-slider v-model:value="props.optionData.series.gap" />
|
||||
</CollapseItem>
|
||||
<!-- Echarts 全局设置 -->
|
||||
<global-setting :optionData="optionData" :in-chart="true"></global-setting>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import {
|
||||
GlobalSetting,
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<GlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
9
src/packages/components/Charts/Mores/Funnel/data.json
Normal file
9
src/packages/components/Charts/Mores/Funnel/data.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"source": [
|
||||
["name","value"],
|
||||
["Visit", 20],
|
||||
["Inquiry", 40],
|
||||
["Order", 60],
|
||||
["Click", 80]
|
||||
]
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { getComponentConfig } from './../../../../../utils/componets';
|
||||
import image from '@/assets/images/chart/charts/funnel.png'
|
||||
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const FunnelConfig: ConfigType = {
|
||||
export const FunnelConfig: ConfigType = getComponentConfig({
|
||||
key: 'Funnel',
|
||||
chartKey: 'VFunnel',
|
||||
conKey: 'VCFunnel',
|
||||
title: '漏斗图',
|
||||
category: ChatCategoryEnum.MORE,
|
||||
categoryName: ChatCategoryEnumName.MORE,
|
||||
package: PackagesCategoryEnum.CHARTS,
|
||||
image
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,10 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
水波
|
||||
</div>
|
||||
<v-chart ref="vChartRef" :theme="themeColor" :option="option" :manual-update="isPreview()" autoresize></v-chart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
import { FunnelChart } from 'echarts/charts'
|
||||
import {
|
||||
DatasetComponent,
|
||||
LegendComponent,
|
||||
TitleComponent,
|
||||
TooltipComponent
|
||||
} from 'echarts/components'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { mergeTheme } from '@/packages/public/chart'
|
||||
import { isPreview } from '@/utils'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { includes } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
themeColor: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
use([
|
||||
DatasetComponent,
|
||||
LegendComponent,
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
FunnelChart
|
||||
])
|
||||
|
||||
|
||||
const option = computed(() => {
|
||||
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||
})
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -5,7 +5,7 @@ import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
colors: ['#1089ff', '#0000ff'],
|
||||
backgroundColor: '#00000000'
|
||||
backgroundColor: '#000000'
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { publicConfig } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CreateComponentType, EventConfig, OptionsType } from '@/packages/index.d'
|
||||
import { Decorates04Config } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { publicConfig } from '@/packages/public/publicConfig';
|
||||
import { DatePickerCommonConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType
|
||||
{
|
||||
public key = DatePickerCommonConfig.key
|
||||
public chartConfig = cloneDeep(DatePickerCommonConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>config</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style></style>
|
@ -0,0 +1,13 @@
|
||||
import { FormCategoryEnum, FormCategoryEnumName } from '../../index.d';
|
||||
import { PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { getComponentConfig } from '@/utils/componets';
|
||||
|
||||
export const DatePickerCommonConfig = getComponentConfig({
|
||||
key: 'DatePickerCommon',
|
||||
title: '日期选择',
|
||||
category: FormCategoryEnum.DATE_PICKER,
|
||||
categoryName: FormCategoryEnumName.DATE_PICKER,
|
||||
package: PackagesCategoryEnum.FORM,
|
||||
chartFrame: ChartFrameEnum.COMMON
|
||||
})
|
||||
|
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<span>DATE_PICKER</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
defineProps({})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
3
src/packages/components/Form/DatePickers/index.ts
Normal file
3
src/packages/components/Form/DatePickers/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { DatePickerCommonConfig } from './DatePickerCommon/index'
|
||||
|
||||
export default [ DatePickerCommonConfig ]
|
24
src/packages/components/Form/Inputs/InputCommon/config.ts
Normal file
24
src/packages/components/Form/Inputs/InputCommon/config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { publicConfig } from '@/packages/public/publicConfig';
|
||||
import { InputCommonConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { COMPONENT_SIZE_ENUM } from '@/enums/componentEnum';
|
||||
|
||||
export const option = {
|
||||
// 参考 https://www.naiveui.com/zh-CN/os-theme/components/input
|
||||
inputOption: {
|
||||
clearable: true,
|
||||
maxlength: 20,
|
||||
placeholder: '',
|
||||
round: false,
|
||||
showCount: false,
|
||||
size: COMPONENT_SIZE_ENUM.MEDIUM
|
||||
}
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType
|
||||
{
|
||||
public key = InputCommonConfig.key
|
||||
public chartConfig = cloneDeep(InputCommonConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
48
src/packages/components/Form/Inputs/InputCommon/config.vue
Normal file
48
src/packages/components/Form/Inputs/InputCommon/config.vue
Normal file
@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<CollapseItem name="属性配置" :expanded="true">
|
||||
<n-form label-placement="left" label-align="right" label-width="auto">
|
||||
<n-form-item label="可清空">
|
||||
<n-switch v-model:value="inputOption.clearable"></n-switch>
|
||||
</n-form-item>
|
||||
<n-form-item label="最大长度">
|
||||
<n-input-number v-model:value="inputOption.maxlength" :min="0" :max="200" :precision="0"/>
|
||||
</n-form-item>
|
||||
<n-form-item label="placeholder">
|
||||
<n-input v-model:value="inputOption.placeholder"/>
|
||||
</n-form-item>
|
||||
<n-form-item label="圆角">
|
||||
<n-switch v-model:value="inputOption.round"></n-switch>
|
||||
</n-form-item>
|
||||
<n-form-item label="显示字数统计">
|
||||
<n-switch v-model:value="inputOption.showCount"></n-switch>
|
||||
</n-form-item>
|
||||
<n-form-item label="尺寸">
|
||||
<n-select v-model:value="inputOption.size" :options="mapToOptions(componentSizeMap)"></n-select>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import {
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
import { mapToOptions } from '@/utils';
|
||||
import { componentSizeMap } from '@/enums/componentEnum'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<GlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { inputOption } = toRefs(props.optionData)
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
13
src/packages/components/Form/Inputs/InputCommon/index.ts
Normal file
13
src/packages/components/Form/Inputs/InputCommon/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { FormCategoryEnum, FormCategoryEnumName } from './../../index.d';
|
||||
import { PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { getComponentConfig } from '@/utils/componets';
|
||||
|
||||
export const InputCommonConfig = getComponentConfig({
|
||||
key: 'InputCommon',
|
||||
title: '输入框',
|
||||
category: FormCategoryEnum.INPUT,
|
||||
categoryName: FormCategoryEnumName.INPUT,
|
||||
package: PackagesCategoryEnum.FORM,
|
||||
chartFrame: ChartFrameEnum.COMMON
|
||||
})
|
||||
|
23
src/packages/components/Form/Inputs/InputCommon/index.vue
Normal file
23
src/packages/components/Form/Inputs/InputCommon/index.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<n-form-item>
|
||||
<n-input v-bind="inputOption" v-model:value="val"/>
|
||||
</n-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, computed, ref } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const inputOption = computed(() => props.chartConfig.option.inputOption)
|
||||
|
||||
const val = ref('')
|
||||
</script>
|
||||
|
||||
<style></style>
|
3
src/packages/components/Form/Inputs/index.ts
Normal file
3
src/packages/components/Form/Inputs/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { InputCommonConfig } from './InputCommon/index'
|
||||
|
||||
export default [ InputCommonConfig ]
|
14
src/packages/components/Form/Selects/SelectCommon/config.ts
Normal file
14
src/packages/components/Form/Selects/SelectCommon/config.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { publicConfig } from '@/packages/public/publicConfig';
|
||||
import { SelectCommonConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
}
|
||||
|
||||
export default class Config extends publicConfig implements CreateComponentType
|
||||
{
|
||||
public key = SelectCommonConfig.key
|
||||
public chartConfig = cloneDeep(SelectCommonConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>config</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style></style>
|
13
src/packages/components/Form/Selects/SelectCommon/index.ts
Normal file
13
src/packages/components/Form/Selects/SelectCommon/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { FormCategoryEnum, FormCategoryEnumName } from './../../index.d';
|
||||
import { PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { getComponentConfig } from '@/utils/componets';
|
||||
|
||||
export const SelectCommonConfig = getComponentConfig({
|
||||
key: 'SelectCommon',
|
||||
title: '下拉框',
|
||||
category: FormCategoryEnum.SELECT,
|
||||
categoryName: FormCategoryEnumName.SELECT,
|
||||
package: PackagesCategoryEnum.FORM,
|
||||
chartFrame: ChartFrameEnum.COMMON
|
||||
})
|
||||
|
13
src/packages/components/Form/Selects/SelectCommon/index.vue
Normal file
13
src/packages/components/Form/Selects/SelectCommon/index.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
select
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
defineProps({})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
3
src/packages/components/Form/Selects/index.ts
Normal file
3
src/packages/components/Form/Selects/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { SelectCommonConfig } from './SelectCommon/index'
|
||||
|
||||
export default [ SelectCommonConfig ]
|
13
src/packages/components/Form/index.d.ts
vendored
Normal file
13
src/packages/components/Form/index.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
export enum FormCategoryEnum {
|
||||
INPUT = 'Inputs',
|
||||
SELECT = 'Selects',
|
||||
DATE_PICKER = 'DatePickers',
|
||||
MORE = 'Mores'
|
||||
}
|
||||
|
||||
export enum FormCategoryEnumName {
|
||||
INPUT = '输入框',
|
||||
SELECT = '下拉框',
|
||||
DATE_PICKER = '日期选择',
|
||||
MORE = '更多'
|
||||
}
|
5
src/packages/components/Form/index.ts
Normal file
5
src/packages/components/Form/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import Inputs from './Inputs'
|
||||
import DatePickers from './DatePickers'
|
||||
import Selects from './Selects'
|
||||
|
||||
export const FormList = [...Inputs, ...DatePickers, ...Selects]
|
@ -62,7 +62,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { option, WritingModeEnum, WritingModeObject } from './config'
|
||||
import {
|
||||
CollapseItem,
|
||||
@ -77,6 +77,8 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const { optionData} = toRefs(props)
|
||||
|
||||
const verticalOptions = [{
|
||||
label: WritingModeEnum.HORIZONTAL,
|
||||
value: WritingModeObject[WritingModeEnum.HORIZONTAL]
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { OptionsType } from '@/packages/index.d';
|
||||
import { mapToOptions } from '@/utils';
|
||||
|
||||
// 内置方法
|
||||
export enum TextCommonEventEnum {
|
||||
FOO = 'foo',
|
||||
BAR = 'bar'
|
||||
}
|
||||
|
||||
//内置事件
|
||||
|
||||
export const methodList = mapToOptions(new Map([
|
||||
[TextCommonEventEnum.FOO, '内置方法'],
|
||||
])) as Array<OptionsType>
|
||||
|
||||
export const eventList = mapToOptions(new Map([
|
||||
[TextCommonEventEnum.BAR, 'setup'],
|
||||
])) as Array<OptionsType>
|
||||
|
||||
export const TextConfig = {
|
||||
key: 'TextCommon',
|
||||
title: '文字',
|
||||
methodList
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { getComponentConfig } from '@/utils';
|
||||
import image from '@/assets/images/chart/informations/text_static.png'
|
||||
import { ConfigType, PackagesCategoryEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
|
||||
import { TextConfig, methodList, eventList } from './enum'
|
||||
|
||||
export const TextCommonConfig: ConfigType = {
|
||||
key: 'TextCommon',
|
||||
chartKey: 'VTextCommon',
|
||||
conKey: 'VCTextCommon',
|
||||
title: '文字',
|
||||
export const TextCommonConfig: ConfigType = getComponentConfig({
|
||||
key: TextConfig.key,
|
||||
title: TextConfig.title,
|
||||
category: ChatCategoryEnum.TEXT,
|
||||
categoryName: ChatCategoryEnumName.TEXT,
|
||||
package: PackagesCategoryEnum.INFORMATIONS,
|
||||
methodList,
|
||||
eventList,
|
||||
image
|
||||
}
|
||||
})
|
@ -22,9 +22,10 @@
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs, shallowReactive, watch } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartDataFetch, useEventBus, convertEventBusListeners } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { option as configOption } from './config'
|
||||
import { TextCommonEventEnum } from './enum'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
@ -33,6 +34,20 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits([TextCommonEventEnum.BAR])
|
||||
|
||||
emits(TextCommonEventEnum.BAR, 'setup event')
|
||||
|
||||
const listeners = convertEventBusListeners({
|
||||
on: {
|
||||
[TextCommonEventEnum.FOO]: () => {
|
||||
alert('触发方法')
|
||||
}
|
||||
}
|
||||
}, props.chartConfig.id)
|
||||
|
||||
useEventBus(listeners)
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const {
|
||||
dataset,
|
||||
|
49
src/packages/index.d.ts
vendored
49
src/packages/index.d.ts
vendored
@ -1,5 +1,7 @@
|
||||
import type { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||
import type { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
import { EventType } from '@/enums/eventEnum';
|
||||
|
||||
|
||||
export enum ChartFrameEnum {
|
||||
// echarts 框架
|
||||
@ -12,8 +14,15 @@ export enum ChartFrameEnum {
|
||||
STATIC = 'static'
|
||||
}
|
||||
|
||||
export type OptionsType = {
|
||||
label: string
|
||||
value: string
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
// 组件配置
|
||||
export type ConfigType = {
|
||||
id?: string
|
||||
key: string
|
||||
chartKey: string
|
||||
conKey: string
|
||||
@ -22,7 +31,29 @@ export type ConfigType = {
|
||||
categoryName: string
|
||||
package: string
|
||||
chartFrame?: ChartFrameEnum
|
||||
image: string | (() => Promise<typeof import('*.png')>)
|
||||
methodList?: Array<OptionsType>
|
||||
eventList?: Array<OptionsType>
|
||||
image?: string | (() => Promise<typeof import('*.png')>)
|
||||
}
|
||||
|
||||
|
||||
export type MethodList = Array<{
|
||||
name: string,
|
||||
event: string,
|
||||
type: string,
|
||||
code: string,
|
||||
uid: string,
|
||||
[key: string]: any
|
||||
}>
|
||||
|
||||
|
||||
export type EventConfigValue = Record<string, {
|
||||
title: string,
|
||||
methodList: MethodList
|
||||
}>
|
||||
|
||||
export type EventConfig = {
|
||||
[key: EventType]: EventConfigValue
|
||||
}
|
||||
|
||||
// 数据请求
|
||||
@ -83,11 +114,20 @@ export interface PublicConfigType extends requestConfig {
|
||||
filter?: string
|
||||
setPosition: Function
|
||||
}
|
||||
export interface dataCollectComponent {
|
||||
componentId: string
|
||||
field: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface CreateComponentType extends PublicConfigType {
|
||||
key: string
|
||||
chartConfig: ConfigType
|
||||
option: GlobalThemeJsonType
|
||||
eventList?: Array<OptionsType>
|
||||
methodList?: Array<OptionsType>
|
||||
eventConfig?: EventConfig
|
||||
dataCollectComponentList?: Array<dataCollectComponent>
|
||||
}
|
||||
|
||||
// 获取组件实例类中某个key对应value类型的方法
|
||||
@ -98,7 +138,8 @@ export enum PackagesCategoryEnum {
|
||||
CHARTS = 'Charts',
|
||||
TABLES = 'Tables',
|
||||
INFORMATIONS = 'Informations',
|
||||
DECORATES = 'Decorates'
|
||||
DECORATES = 'Decorates',
|
||||
FORM = 'Form',
|
||||
}
|
||||
|
||||
// 包分类名称
|
||||
@ -106,7 +147,8 @@ export enum PackagesCategoryName {
|
||||
CHARTS = '图表',
|
||||
TABLES = '列表',
|
||||
INFORMATIONS = '信息',
|
||||
DECORATES = '小组件'
|
||||
DECORATES = '小组件',
|
||||
FORM = '表单',
|
||||
}
|
||||
|
||||
// 获取组件
|
||||
@ -121,4 +163,5 @@ export type PackagesType = {
|
||||
[PackagesCategoryEnum.INFORMATIONS]: ConfigType[]
|
||||
[PackagesCategoryEnum.TABLES]: ConfigType[]
|
||||
[PackagesCategoryEnum.DECORATES]: ConfigType[]
|
||||
[PackagesCategoryEnum.FORM]: ConfigType[]
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { ChartList } from '@/packages/components/Charts/index'
|
||||
import { DecorateList } from '@/packages/components/Decorates/index'
|
||||
import { InformationList } from '@/packages/components/Informations/index'
|
||||
import { TableList } from '@/packages/components/Tables/index'
|
||||
import { FormList } from '@/packages/components/Form/index'
|
||||
import {
|
||||
PackagesCategoryEnum,
|
||||
PackagesType,
|
||||
@ -17,7 +18,8 @@ export let packagesList: PackagesType = {
|
||||
[PackagesCategoryEnum.CHARTS]: ChartList,
|
||||
[PackagesCategoryEnum.INFORMATIONS]: InformationList,
|
||||
[PackagesCategoryEnum.TABLES]: TableList,
|
||||
[PackagesCategoryEnum.DECORATES]: DecorateList
|
||||
[PackagesCategoryEnum.DECORATES]: DecorateList,
|
||||
[PackagesCategoryEnum.FORM]: FormList,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@ import { globalThemeJson } from '@/settings/chartThemes/index'
|
||||
* * 合并 color 和全局配置项
|
||||
* @param option 配置
|
||||
* @param themeSetting 设置
|
||||
* @param excludes 排除元素
|
||||
* @param includes 合并元素
|
||||
* @returns object
|
||||
*/
|
||||
export const mergeTheme = <T, U>(option: T, themeSetting: U, includes: string[]) => {
|
||||
|
@ -53,6 +53,9 @@ import {
|
||||
ArrowForward as ArrowForwardIcon,
|
||||
Planet as PawIcon,
|
||||
Search as SearchIcon,
|
||||
Reload as ReloadIcon,
|
||||
Add as AddIcon,
|
||||
AddCircle as AddCircleIcon,
|
||||
ChevronUpOutline as ChevronUpOutlineIcon,
|
||||
ChevronDownOutline as ChevronDownOutlineIcon,
|
||||
Pulse as PulseIcon
|
||||
@ -85,10 +88,16 @@ import {
|
||||
FitToHeight as FitToHeightIcon,
|
||||
FitToWidth as FitToWidthIcon,
|
||||
Filter as FilterIcon,
|
||||
FilterEdit as FilterEditIcon
|
||||
FilterEdit as FilterEditIcon,
|
||||
Edit as EditIcon,
|
||||
DataFormat as DataFormatIcon
|
||||
} from '@vicons/carbon'
|
||||
|
||||
const ionicons5 = {
|
||||
// 新增
|
||||
AddIcon,
|
||||
// 新增2
|
||||
AddCircleIcon,
|
||||
// 帮助(问号)
|
||||
HelpOutlineIcon,
|
||||
// 添加
|
||||
@ -194,6 +203,8 @@ const ionicons5 = {
|
||||
ArrowForwardIcon,
|
||||
// 狗爪
|
||||
PawIcon,
|
||||
// 重新加载
|
||||
ReloadIcon,
|
||||
// 搜索(放大镜)
|
||||
SearchIcon,
|
||||
// 过滤器
|
||||
@ -207,6 +218,8 @@ const ionicons5 = {
|
||||
}
|
||||
|
||||
const carbon = {
|
||||
EditIcon,
|
||||
DataFormatIcon,
|
||||
// 图表
|
||||
RoadmapIcon,
|
||||
// 信息
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"title": {
|
||||
"text": "",
|
||||
"show": true,
|
||||
"textStyle": {
|
||||
"color": "#BFBFBF",
|
||||
|
@ -131,6 +131,7 @@ export enum ChartEditStoreEnum {
|
||||
RECORD_CHART = 'recordChart',
|
||||
// 以下需要存储
|
||||
EDIT_CANVAS_CONFIG = 'editCanvasConfig',
|
||||
EVENT_CONFIG = 'eventConfig',
|
||||
REQUEST_GLOBAL_CONFIG = 'requestGlobalConfig',
|
||||
COMPONENT_LIST = 'componentList'
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import {
|
||||
RequestGlobalConfigType,
|
||||
EditCanvasConfigType
|
||||
} from './chartEditStore.d'
|
||||
|
||||
const chartHistoryStore = useChartHistoryStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
|
7
src/store/modules/dataCollectStore/dataCollectStore.d.ts
vendored
Normal file
7
src/store/modules/dataCollectStore/dataCollectStore.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export enum DataCollectStoreEnums {
|
||||
}
|
||||
|
||||
export interface DataCollectStoreType {
|
||||
model: Record<string, number | string | Array<string | number>>,
|
||||
mountedComponentSet: Set<string | number>
|
||||
}
|
24
src/store/modules/dataCollectStore/dataCollectStore.ts
Normal file
24
src/store/modules/dataCollectStore/dataCollectStore.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { DataCollectStoreType, DataCollectStoreEnums } from './dataCollectStore.d'
|
||||
|
||||
// 全局设置
|
||||
export const useDataCollectStore = defineStore({
|
||||
id: 'useDataCollectStore',
|
||||
state: (): DataCollectStoreType => {
|
||||
return {
|
||||
mountedComponentSet: new Set(),
|
||||
model: {}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
clearAll(){
|
||||
this.mountedComponentSet.clear()
|
||||
},
|
||||
recordMountedComponent(id: string){
|
||||
this.mountedComponentSet.add(id)
|
||||
}
|
||||
}
|
||||
})
|
@ -1,5 +1,6 @@
|
||||
import { defineAsyncComponent, AsyncComponentLoader } from 'vue'
|
||||
import { AsyncLoading, AsyncSkeletonLoading } from '@/components/GoLoading'
|
||||
import { ConfigType } from '@/packages/index.d'
|
||||
|
||||
/**
|
||||
* * 动态注册组件
|
||||
@ -19,6 +20,11 @@ export const loadAsyncComponent = (loader: AsyncComponentLoader<any>) =>
|
||||
defineAsyncComponent({
|
||||
loader,
|
||||
loadingComponent: AsyncLoading,
|
||||
errorComponent: {
|
||||
render(){
|
||||
return '加载失败'
|
||||
}
|
||||
},
|
||||
delay: 20,
|
||||
})
|
||||
|
||||
@ -28,3 +34,12 @@ export const loadSkeletonAsyncComponent = (loader: AsyncComponentLoader<any>) =>
|
||||
loadingComponent: AsyncSkeletonLoading,
|
||||
delay: 20,
|
||||
})
|
||||
|
||||
|
||||
export const getComponentConfig = (options: Omit<ConfigType, 'chartKey' | 'conKey' | 'id'>): ConfigType => {
|
||||
return {
|
||||
...options,
|
||||
chartKey: `V${options.key}`,
|
||||
conKey: `VC${options.key}`,
|
||||
}
|
||||
}
|
6
src/utils/data.ts
Normal file
6
src/utils/data.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export const mapToOptions = <K extends string = 'key', V extends string = 'value'>(map: Map<string, string>, options = { k: 'label', v: 'value'} as { k: K; v: V }) => Array.from(map, item => {
|
||||
return {
|
||||
[options.k]: item[1],
|
||||
[options.v]: item[0],
|
||||
} as {[key in K | V]: string}
|
||||
});
|
@ -7,3 +7,4 @@ export * from '@/utils/plugin'
|
||||
export * from '@/utils/componets'
|
||||
export * from '@/utils/type'
|
||||
export * from '@/utils/file'
|
||||
export * from '@/utils/data'
|
@ -204,7 +204,7 @@ export const newFunctionHandle = (
|
||||
try {
|
||||
if (!funcStr) return data
|
||||
const fn = new Function('data', funcStr)
|
||||
const fnRes = fn(cloneDeep(data))
|
||||
const fnRes = fn(data)
|
||||
const resHandle = isToString ? toString(fnRes) : fnRes
|
||||
// 成功回调
|
||||
successCallBack && successCallBack(resHandle)
|
||||
|
@ -13,6 +13,7 @@ const {
|
||||
RoadmapIcon,
|
||||
SpellCheckIcon,
|
||||
GraphicalDataFlowIcon,
|
||||
DataFormatIcon,
|
||||
} = icon.carbon
|
||||
|
||||
|
||||
@ -44,6 +45,10 @@ const packagesListObj = {
|
||||
icon: renderIcon(GraphicalDataFlowIcon),
|
||||
label: PackagesCategoryName.DECORATES,
|
||||
},
|
||||
[PackagesCategoryEnum.FORM]: {
|
||||
icon: renderIcon(DataFormatIcon),
|
||||
label: PackagesCategoryName.FORM,
|
||||
},
|
||||
}
|
||||
|
||||
// 处理列表
|
||||
|
@ -0,0 +1,3 @@
|
||||
import ChartDataForeignKey from './index.vue'
|
||||
|
||||
export { ChartDataForeignKey }
|
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<CollapseItem name="关联表单组件" :expanded="true">
|
||||
<template #header>
|
||||
<n-icon size="24" @click="onAdd">
|
||||
<component :is="AddCircleIcon"></component>
|
||||
</n-icon>
|
||||
</template>
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
/>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
CollapseItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { icon } from '@/plugins/icon'
|
||||
import { FormInst, NSpace as Space, NIcon as Icon } from 'naive-ui'
|
||||
import { ref, watch, h, reactive } from 'vue'
|
||||
import { useTargetData } from '../../../hooks/useTargetData.hook'
|
||||
|
||||
const { targetData } = useTargetData();
|
||||
const { AddCircleIcon } = icon.ionicons5
|
||||
const showModal = ref(false)
|
||||
const model = ref({})
|
||||
|
||||
let dataCollectComponentList: any
|
||||
|
||||
watch(targetData, () => {
|
||||
if(targetData.value.dataCollectComponentList){
|
||||
dataCollectComponentList = targetData.value.dataCollectComponentList
|
||||
}else{
|
||||
dataCollectComponentList = reactive([])
|
||||
}
|
||||
})
|
||||
|
||||
const columnIconAttr = {
|
||||
size: 18,
|
||||
style: {
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
model.value = {}
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const onEdit = (rowData: Record<string, any>) => {
|
||||
model.value = {
|
||||
...rowData
|
||||
}
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{title: '组件名称', key: 'componentName'},
|
||||
// {title: '组件Id', key: 'componentId'},
|
||||
{title: '绑定字段', field: 'field'},
|
||||
{ title: '操作', render(rowData: any){
|
||||
return h(Space, () => (h({
|
||||
render(){
|
||||
return [
|
||||
h(Icon, {
|
||||
...columnIconAttr,
|
||||
title: '编辑',
|
||||
onClick(){
|
||||
onEdit(rowData)
|
||||
}
|
||||
}, () => h(icon.carbon.EditIcon)),
|
||||
h(Icon, {
|
||||
...columnIconAttr,
|
||||
title: '删除',
|
||||
onClick(){
|
||||
|
||||
}
|
||||
}, () => h(icon.ionicons5.RemoveIcon))
|
||||
]
|
||||
}
|
||||
})))
|
||||
}},
|
||||
]
|
||||
const data: Array<any> = []
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -13,7 +13,10 @@
|
||||
></chart-data-static>
|
||||
|
||||
<!-- 动态 -->
|
||||
<chart-data-ajax v-else></chart-data-ajax>
|
||||
<template v-else>
|
||||
<chart-data-ajax></chart-data-ajax>
|
||||
<chart-data-foreign-key></chart-data-foreign-key>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -22,6 +25,7 @@ import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
|
||||
import { useTargetData } from '../hooks/useTargetData.hook'
|
||||
import { ChartDataStatic } from './components/ChartDataStatic/index'
|
||||
import { ChartDataAjax } from './components/ChartDataAjax/index'
|
||||
import { ChartDataForeignKey } from './components/ChartDataForeignKey/index'
|
||||
import { SelectCreateDataType, SelectCreateDataEnum } from './index.d'
|
||||
import { RequestDataTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
|
@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<n-collapse :default-expanded-names="Object.values(EventType)">
|
||||
<!-- todo 暂时用any -->
|
||||
<n-collapse-item
|
||||
v-for="(item, key) in targetData.eventConfig as any"
|
||||
:key="key"
|
||||
:title="item.title"
|
||||
:name="key">
|
||||
<template #header-extra>
|
||||
<n-icon size="24" @click.stop="onAddEvent(item, key as unknown as EventType)">
|
||||
<component :is="AddCircleIcon"></component>
|
||||
</n-icon>
|
||||
</template>
|
||||
<n-empty
|
||||
v-if="!item.methodList.length"
|
||||
:show-icon="false">
|
||||
</n-empty>
|
||||
<template v-else>
|
||||
<n-data-table
|
||||
:row-key="(rowData:any) => rowData.uid"
|
||||
:columns="columns"
|
||||
:data="item.methodList"
|
||||
/>
|
||||
</template>
|
||||
</n-collapse-item>
|
||||
</n-collapse>
|
||||
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
title="事件"
|
||||
type="info"
|
||||
preset="dialog"
|
||||
:mask-closable="false"
|
||||
:on-after-leave="onModalClosed">
|
||||
<n-form
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
:rules="rules"
|
||||
:model="model"
|
||||
>
|
||||
<n-form-item label="名称" path="name">
|
||||
<n-input v-model:value="model.name" />
|
||||
</n-form-item>
|
||||
<n-form-item label="类型" path="type">
|
||||
<n-select
|
||||
v-model:value="model.type"
|
||||
placeholder="类型"
|
||||
:options="typeOptions"
|
||||
/>
|
||||
</n-form-item>
|
||||
<template v-if="model.type === EventTriggerType.COMPONENT">
|
||||
<n-form-item label="选择组件" path="componentId">
|
||||
<n-select
|
||||
v-model:value="model.componentId"
|
||||
placeholder="请选择组件"
|
||||
:options="componentListOptions"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="触发方法" path="componentMethod">
|
||||
<n-select
|
||||
v-model:value="model.componentMethod"
|
||||
placeholder="请选择触发方法"
|
||||
:options="componentMethodOptions"
|
||||
/>
|
||||
</n-form-item>
|
||||
</template>
|
||||
<template v-else-if="model.type === EventTriggerType.JAVASCRIPT">
|
||||
<n-form-item label="自定义js" path="code">
|
||||
<n-space vertical :style="{width: '100%'}">
|
||||
<n-tag type="info">
|
||||
<span class="func-keyword">function</span> (data) {
|
||||
</n-tag>
|
||||
<monaco-editor v-model:modelValue="model.code" language="javascript" height="500px"/>
|
||||
<n-tag type="info">}</n-tag>
|
||||
</n-space>
|
||||
</n-form-item>
|
||||
</template>
|
||||
<div style="display: flex; justify-content: center">
|
||||
<n-space>
|
||||
<n-button round type="primary" @click="onSubmit">
|
||||
确认
|
||||
</n-button>
|
||||
<n-button round type="primary" @click="onCancel">
|
||||
取消
|
||||
</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {reactive, ref, h, watch, computed, unref, toRaw, markRaw} from 'vue'
|
||||
import { icon } from '@/plugins/icon'
|
||||
import { MonacoEditor } from '@/components/Pages/MonacoEditor'
|
||||
import { EventType, EventTypeTitle, EventTriggerType, EventTriggerTypeMap, CommonEventMap } from '@/enums/eventEnum'
|
||||
import { FormInst, NSpace as Space, NIcon as Icon } from 'naive-ui'
|
||||
import { getUUID, mapToOptions } from '@/utils'
|
||||
import { useTargetData } from '../hooks/useTargetData.hook'
|
||||
import { CreateComponentType, OptionsType, EventConfig, EventConfigValue } from '@/packages/index.d'
|
||||
|
||||
const { targetData, chartEditStore } = useTargetData();
|
||||
|
||||
// 事件配置
|
||||
const eventConfig = computed<EventConfig>(() => {
|
||||
return targetData.value?.eventConfig as EventConfig
|
||||
})
|
||||
|
||||
// 监听数据变化, 设置初始值
|
||||
watch(targetData, (newVal) => {
|
||||
if(!newVal)return
|
||||
if(!eventConfig.value){
|
||||
newVal.eventConfig = reactive({})
|
||||
}
|
||||
//原生事件
|
||||
Object.keys(EventTypeTitle).forEach((key: string) => {
|
||||
if(!(key in eventConfig.value)){
|
||||
(newVal.eventConfig as any)[key] = {
|
||||
title: EventTypeTitle[key as EventType],
|
||||
methodList: []
|
||||
}
|
||||
}
|
||||
})
|
||||
// 组件内置事件
|
||||
newVal.chartConfig.eventList?.map((item: OptionsType) => {
|
||||
if(!(item.value in eventConfig.value)){
|
||||
(newVal.eventConfig as any)[item.value] = {
|
||||
title: item.label,
|
||||
methodList: []
|
||||
}
|
||||
}
|
||||
})
|
||||
}, {
|
||||
immediate: true
|
||||
})
|
||||
|
||||
const { AddCircleIcon } = icon.ionicons5
|
||||
|
||||
const showModal = ref(false)
|
||||
|
||||
let eventType: EventType = EventType.CLICK
|
||||
let operateCollapse: any = null
|
||||
|
||||
const formRef = ref<FormInst | null>(null)
|
||||
|
||||
const model = ref<Record<string, string>>({
|
||||
uid: '',
|
||||
name: '',
|
||||
type: EventTriggerType.JAVASCRIPT,
|
||||
code: '',
|
||||
componentId: ''
|
||||
});
|
||||
|
||||
const defaultModel: Record<string, string> = {
|
||||
...markRaw(toRaw(unref(model)))
|
||||
}
|
||||
|
||||
const typeOptions = [
|
||||
{label: EventTriggerTypeMap.get(EventTriggerType.COMPONENT), value: EventTriggerType.COMPONENT},
|
||||
{label: EventTriggerTypeMap.get(EventTriggerType.JAVASCRIPT), value: EventTriggerType.JAVASCRIPT},
|
||||
]
|
||||
|
||||
const componentListOptions = computed(() => {
|
||||
return chartEditStore.componentList.map(item => {
|
||||
return {
|
||||
disabled: item.id === targetData.value.id,
|
||||
label: item.chartConfig.title,
|
||||
value: item.id
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const selectedComponent = computed((): CreateComponentType | void => {
|
||||
return chartEditStore.componentList.find(item => Object.is(item.id, model.value.componentId))
|
||||
})
|
||||
|
||||
const commMethodList = mapToOptions(CommonEventMap)
|
||||
|
||||
const componentMethodOptions = computed(() => {
|
||||
return [
|
||||
...commMethodList,
|
||||
...(selectedComponent.value ? (selectedComponent.value.chartConfig.methodList as Array<OptionsType>) : [])
|
||||
]
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: { required: true, message: '必填项不能为空' },
|
||||
type: { required: true, message: '必填项不能为空' },
|
||||
componentId: { required: true, message: '必填项不能为空' },
|
||||
componentMethod: { required: true, message: '必填项不能为空' },
|
||||
}
|
||||
|
||||
const onAddEvent = (item: any, type: EventType) => {
|
||||
eventType = type
|
||||
operateCollapse = item
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const onEdit = (rowData: Record<string, any>) => {
|
||||
model.value = {
|
||||
...rowData
|
||||
}
|
||||
eventType = rowData.eventType
|
||||
// @ts-ignore
|
||||
operateCollapse = targetData.value?.eventConfig[eventType]
|
||||
showModal.value = true
|
||||
}
|
||||
|
||||
const columnIconAttr = {
|
||||
size: 18,
|
||||
style: {
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{ title: '名称', key: 'name'},
|
||||
{ title: '类型', key: 'type', render(rowData: any){
|
||||
return EventTriggerTypeMap.get(rowData.type)
|
||||
}},
|
||||
{ title: '操作', render(rowData: any, rowIndex: number){
|
||||
return h(Space, () => (h({
|
||||
render(){
|
||||
return [
|
||||
h(Icon, {
|
||||
...columnIconAttr,
|
||||
title: '编辑',
|
||||
onClick(){
|
||||
onEdit(rowData)
|
||||
}
|
||||
}, () => h(icon.carbon.EditIcon)),
|
||||
h(Icon, {
|
||||
...columnIconAttr,
|
||||
title: '删除',
|
||||
onClick(){
|
||||
((eventConfig.value[rowData.eventType as keyof EventConfig]) as EventConfigValue[string]).methodList.splice(rowIndex, 1)
|
||||
}
|
||||
}, () => h(icon.ionicons5.RemoveIcon))
|
||||
]
|
||||
}
|
||||
})))
|
||||
}},
|
||||
]
|
||||
|
||||
|
||||
const onSubmit = () => {
|
||||
formRef.value?.validate((errors) => {
|
||||
if (!errors && operateCollapse) {
|
||||
if(model.value.uid){
|
||||
const index = operateCollapse.methodList
|
||||
.findIndex((item:any) => item.uid === model.value.uid)
|
||||
if(index > -1){
|
||||
operateCollapse.methodList[index] = {...model.value}
|
||||
}
|
||||
}else{
|
||||
operateCollapse.methodList.push({
|
||||
...model.value,
|
||||
eventType,
|
||||
uid: getUUID(),
|
||||
})
|
||||
}
|
||||
showModal.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onCancel = () => {
|
||||
showModal.value = false
|
||||
}
|
||||
|
||||
const onModalClosed = () => {
|
||||
Object.keys(model.value).forEach(key => {
|
||||
if(key in defaultModel){
|
||||
model.value[key] = defaultModel[key]
|
||||
}else{
|
||||
model.value[key] = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.func-keyword {
|
||||
color: #b478cf;
|
||||
}
|
||||
</style>
|
@ -92,7 +92,8 @@ const {
|
||||
ConstructIcon,
|
||||
FlashIcon,
|
||||
DesktopOutlineIcon,
|
||||
LeafIcon
|
||||
LeafIcon,
|
||||
RocketIcon
|
||||
} = icon.ionicons5
|
||||
|
||||
const ContentEdit = loadAsyncComponent(() => import('../ContentEdit/index.vue'))
|
||||
@ -108,6 +109,9 @@ const ChartData = loadAsyncComponent(() =>
|
||||
const ChartAnimation = loadAsyncComponent(() =>
|
||||
import('./components/ChartAnimation/index.vue')
|
||||
)
|
||||
const ChartEvent = loadAsyncComponent(() =>
|
||||
import('./components/ChartEvent/index.vue')
|
||||
)
|
||||
|
||||
const collapsed = ref<boolean>(getDetails.value)
|
||||
|
||||
@ -164,6 +168,12 @@ const canvasTabList = [
|
||||
title: '数据',
|
||||
icon: FlashIcon,
|
||||
render: ChartData
|
||||
},
|
||||
{
|
||||
key: 'eventData',
|
||||
title: '事件',
|
||||
icon: RocketIcon,
|
||||
render: ChartEvent
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
@ -70,6 +70,7 @@ const select = computed(() => {
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
transform: translate(-40%, -30%);
|
||||
cursor: col-resize;
|
||||
&.t {
|
||||
width: 30px;
|
||||
transform: translate(-50%, -50%);
|
||||
|
@ -127,6 +127,12 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ContentEdit'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@include goId('chart-edit-layout') {
|
||||
position: relative;
|
||||
|
@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, toRefs, computed } from 'vue'
|
||||
import { ref, toRefs, computed,isRef } from 'vue'
|
||||
import { requireErrorImg } from '@/utils'
|
||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
@ -39,7 +39,10 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const { image } = toRefs(props.componentData.chartConfig)
|
||||
// 消除页面警告
|
||||
const { image } = isRef(props.componentData.chartConfig) ?
|
||||
toRefs(props.componentData.chartConfig)
|
||||
: props.componentData.chartConfig
|
||||
|
||||
// 计算当前选中目标
|
||||
const select = computed(() => {
|
||||
|
@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<component
|
||||
ref="componentRef"
|
||||
:is="item.chartConfig.chartKey"
|
||||
:chartConfig="item"
|
||||
:themeSetting="themeSetting"
|
||||
:themeColor="themeColor"
|
||||
:style="{...getSizeStyle(item.attr)}"
|
||||
v-on="useEvent ? getEventList(item.eventConfig as EventConfig) : {}"
|
||||
></component>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { PropType, ref, toRefs, getCurrentInstance, ComponentInternalInstance, onMounted } from 'vue'
|
||||
import { useEventBus } from '@/hooks'
|
||||
import { convertEventBusListeners } from '@/hooks/useEventBus.hook'
|
||||
import { getSizeStyle } from '../../utils'
|
||||
import { EventTriggerType } from '@/enums/eventEnum'
|
||||
import { CreateComponentType, EventConfig, PackagesCategoryEnum } from '@/packages/index.d'
|
||||
import { newFunctionHandle } from '@/utils'
|
||||
import isObject from 'lodash/isObject'
|
||||
import { COMMON_EVENT_ENUM, DATA_COMPONENT_EVENT_ENUM } from '@/enums/eventEnum'
|
||||
import { useDataCollectStore } from '@/store/modules/dataCollectStore/dataCollectStore'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
},
|
||||
themeSetting: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
themeColor: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
useEvent: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const { item, themeSetting, themeColor, useEvent } = toRefs(props);
|
||||
const componentRef = ref<any>(null)
|
||||
const instance = getCurrentInstance() as ComponentInternalInstance
|
||||
const bus = useEventBus()
|
||||
/**
|
||||
* @return
|
||||
* {
|
||||
* click: [fn1, fn2],
|
||||
* change: [fn1, fn2],
|
||||
* }
|
||||
*/
|
||||
const getEventList = (eventConfig: EventConfig) => {
|
||||
if(!isObject(eventConfig)) return {}
|
||||
const res = Object.keys(eventConfig)
|
||||
.reduce((previousValue: EventConfig, currentValue: string) => {
|
||||
// @ts-ignore
|
||||
previousValue[currentValue] = eventConfig[currentValue].methodList.map((item: any) => {
|
||||
if(item.type === EventTriggerType.JAVASCRIPT){
|
||||
return (e: any) => {
|
||||
try {
|
||||
newFunctionHandle(e, item.code)
|
||||
} catch (error) {
|
||||
console.error(error, item.code)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return (data: any) => {
|
||||
bus.emit(`${item.componentId}:${item.componentMethod}`, data)
|
||||
}
|
||||
}
|
||||
})
|
||||
return previousValue
|
||||
}, {} as EventConfig)
|
||||
return res;
|
||||
}
|
||||
const listeners: Record<string, any> = {
|
||||
on: {
|
||||
[COMMON_EVENT_ENUM.FORCE_UPDATE]: () => {
|
||||
instance.proxy?.$forceUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 数据组件
|
||||
if( item.value.chartConfig.package === PackagesCategoryEnum.CHARTS ||
|
||||
item.value.chartConfig.package === PackagesCategoryEnum.TABLES){
|
||||
// 数据组件监听刷新数据
|
||||
listeners.on[DATA_COMPONENT_EVENT_ENUM.LOAD_DATA] = () => {
|
||||
componentRef.value?.loadData()
|
||||
}
|
||||
}
|
||||
|
||||
// 表单组件
|
||||
if(item.value.chartConfig.package === PackagesCategoryEnum.FORM){
|
||||
const dataCollectStore = useDataCollectStore()
|
||||
// 渲染完成记录状态
|
||||
onMounted(() => {
|
||||
dataCollectStore.recordMountedComponent(item.value.id)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
useEventBus(convertEventBusListeners(listeners, item.value.id))
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
</style>
|
@ -10,13 +10,12 @@
|
||||
...getTransformStyle(item.styles)
|
||||
}"
|
||||
>
|
||||
<component
|
||||
:is="item.chartConfig.chartKey"
|
||||
:chartConfig="item"
|
||||
<PreViewRenderItem
|
||||
:use-event="true"
|
||||
:item="item"
|
||||
:themeSetting="themeSetting"
|
||||
:themeColor="themeColor"
|
||||
:style="{...getSizeStyle(item.attr)}"
|
||||
></component>
|
||||
:themeColor="themeColor">
|
||||
</PreViewRenderItem>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -26,6 +25,8 @@ import { ChartEditStorageType } from '../../index.d'
|
||||
import { chartColors } from '@/settings/chartThemes/index'
|
||||
import { animationsClass, getFilterStyle, getTransformStyle } from '@/utils'
|
||||
import { getSizeStyle, getComponentAttrStyle } from '../../utils'
|
||||
import PreViewRenderItem from './PreViewRenderItem.vue'
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
localStorageInfo: {
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { PreviewRenderList } from './components/PreviewRenderList'
|
||||
import { PreviewRenderList } from './components/PreviewRenderList/index'
|
||||
import { getFilterStyle } from '@/utils'
|
||||
import { getEditCanvasConfigStyle, getSessionStorageInfo } from './utils'
|
||||
import { useComInstall } from './hooks/useComInstall.hook'
|
||||
|
183
vite.config.ts
183
vite.config.ts
@ -5,67 +5,140 @@ import { OUTPUT_DIR, brotliSize, chunkSizeWarningLimit, terserOptions, rollupOpt
|
||||
import viteCompression from 'vite-plugin-compression'
|
||||
import { viteMockServe } from 'vite-plugin-mock'
|
||||
import monacoEditorPlugin from 'vite-plugin-monaco-editor'
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
import viteImagemin from 'vite-plugin-imagemin'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { NaiveUiResolver
|
||||
} from 'unplugin-vue-components/resolvers'
|
||||
|
||||
function pathResolve(dir: string) {
|
||||
return resolve(process.cwd(), '.', dir)
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
base: '/',
|
||||
// 路径重定向
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
find: /\/#\//,
|
||||
replacement: pathResolve('types') + '/'
|
||||
},
|
||||
{
|
||||
find: '@',
|
||||
replacement: pathResolve('src') + '/'
|
||||
}
|
||||
],
|
||||
dedupe: ['vue']
|
||||
},
|
||||
// 全局 css 注册
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
javascriptEnabled: true,
|
||||
additionalData: `@import "src/styles/common/style.scss";`
|
||||
const plugins = [
|
||||
vue(),
|
||||
monacoEditorPlugin({
|
||||
languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
|
||||
}),
|
||||
]
|
||||
|
||||
const devPlugins = [
|
||||
AutoImport(
|
||||
{
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
{
|
||||
'vue': ['PropType']
|
||||
}
|
||||
],
|
||||
eslintrc: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
monacoEditorPlugin({
|
||||
languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
|
||||
}),
|
||||
viteMockServe({
|
||||
mockPath: '/src/api/mock',
|
||||
// 开发打包开关
|
||||
localEnabled: true,
|
||||
// 生产打包开关
|
||||
prodEnabled: true,
|
||||
// 打开后,可以读取 ts 文件模块。 请注意,打开后将无法监视.js 文件
|
||||
supportTs: true,
|
||||
// 监视文件更改
|
||||
watchFiles: true
|
||||
}),
|
||||
// 压缩
|
||||
viteCompression({
|
||||
verbose: true,
|
||||
disable: false,
|
||||
threshold: 10240,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz'
|
||||
})
|
||||
],
|
||||
build: {
|
||||
target: 'es2015',
|
||||
outDir: OUTPUT_DIR,
|
||||
terserOptions: terserOptions,
|
||||
rollupOptions: rollupOptions,
|
||||
brotliSize: brotliSize,
|
||||
chunkSizeWarningLimit: chunkSizeWarningLimit
|
||||
),
|
||||
Components({
|
||||
resolvers: [
|
||||
NaiveUiResolver()
|
||||
]
|
||||
}),
|
||||
viteMockServe({
|
||||
mockPath: '/src/api/mock',
|
||||
// 开发打包开关
|
||||
localEnabled: true,
|
||||
// 生产打包开关
|
||||
prodEnabled: true,
|
||||
// 打开后,可以读取 ts 文件模块。 请注意,打开后将无法监视.js 文件
|
||||
supportTs: true,
|
||||
// 监视文件更改
|
||||
watchFiles: true
|
||||
}),
|
||||
]
|
||||
const proPlugins = [
|
||||
// 图片压缩
|
||||
viteImagemin({
|
||||
gifsicle: {
|
||||
optimizationLevel: 7,
|
||||
interlaced: false,
|
||||
},
|
||||
optipng: {
|
||||
optimizationLevel: 7,
|
||||
},
|
||||
mozjpeg: {
|
||||
quality: 20,
|
||||
},
|
||||
pngquant: {
|
||||
quality: [0.8, 0.9],
|
||||
speed: 4,
|
||||
},
|
||||
svgo: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'removeViewBox',
|
||||
},
|
||||
{
|
||||
name: 'removeEmptyAttrs',
|
||||
active: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
// 压缩
|
||||
viteCompression({
|
||||
verbose: true,
|
||||
disable: false,
|
||||
threshold: 10240,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz'
|
||||
}),
|
||||
// 打包分析
|
||||
visualizer({
|
||||
open: true
|
||||
})
|
||||
]
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
if(mode === 'development'){
|
||||
plugins.push(...devPlugins)
|
||||
}else{
|
||||
plugins.push(...proPlugins)
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
base: '/',
|
||||
// 路径重定向
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
find: /\/#\//,
|
||||
replacement: pathResolve('types') + '/'
|
||||
},
|
||||
{
|
||||
find: '@',
|
||||
replacement: pathResolve('src') + '/'
|
||||
}
|
||||
],
|
||||
dedupe: ['vue']
|
||||
},
|
||||
// 全局 css 注册
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
javascriptEnabled: true,
|
||||
additionalData: `@import "src/styles/common/style.scss";`
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins,
|
||||
build: {
|
||||
target: 'es2015',
|
||||
outDir: OUTPUT_DIR,
|
||||
terserOptions: terserOptions,
|
||||
rollupOptions: rollupOptions,
|
||||
brotliSize: brotliSize,
|
||||
chunkSizeWarningLimit: chunkSizeWarningLimit
|
||||
}
|
||||
}
|
||||
})
|
||||
|
240
数据收集模块设计.drawio
Normal file
240
数据收集模块设计.drawio
Normal file
@ -0,0 +1,240 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="tYnlZV8h0JO72zglXhLP" name="Page-1">
|
||||
<mxGraphModel dx="1032" dy="528" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="8" style="edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="2" target="3" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="38" value="组件Id<br>fieldKey" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="8" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.0869" y="2" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="9" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="2" target="4" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="13" value="同上" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="9" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.1013" y="1" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="10" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="2" target="5" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="14" value="同上" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="10" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.0923" y="2" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="11" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="2" target="6" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="15" value="同上" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="11" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.085" y="1" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="31" value="" style="edgeStyle=none;html=1;" parent="1" source="2" target="30" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="2" value="数据组件" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="250" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="20" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="3" target="16" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="220"/>
|
||||
<mxPoint x="760" y="50"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="57" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="3" target="51" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="220"/>
|
||||
<mxPoint x="760" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="表单组件1" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="447" y="210" width="120" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="24" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="4" target="16" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="260"/>
|
||||
<mxPoint x="760" y="50"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="58" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="4" target="51" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="260"/>
|
||||
<mxPoint x="760" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="4" value="表单组件2" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="447" y="250" width="120" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="26" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="5" target="16" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="300"/>
|
||||
<mxPoint x="760" y="50"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="59" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="5" target="51" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="300"/>
|
||||
<mxPoint x="760" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="5" value="..." style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="447" y="290" width="120" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="27" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="6" target="16" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="340"/>
|
||||
<mxPoint x="760" y="50"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="61" value="修改组件渲染状态" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="27" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.6751" y="-2" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="60" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="6" target="51" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="760" y="340"/>
|
||||
<mxPoint x="760" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="62" value="双向绑定" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="60" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.6167" y="-2" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="6" value="表单组件n" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="447" y="330" width="120" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="16" value="Store<br>["组件Id1","组件Id2"]" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="330" y="10" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="33" value="" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="30" target="32" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="37" value="Y" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="33" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.2626" y="1" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="35" value="" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="30" target="34" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="414" y="420"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="39" value="N" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="35" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.5169" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="30" value="渲染完成,检查关联组件是否渲染完成" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="390" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="41" value="" style="edgeStyle=none;html=1;" parent="1" source="32" target="40" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="32" value="收集数据" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="520" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="46" style="edgeStyle=none;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="34" target="32" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="47" value="Y" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="46" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.2239" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="19" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="48" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="34" target="34" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="414" y="510" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="414" y="640"/>
|
||||
<mxPoint x="634" y="640"/>
|
||||
<mxPoint x="634" y="550"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="50" value="N" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="48" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.9351" relative="1" as="geometry">
|
||||
<mxPoint y="9" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="34" value="监听Store变化,判断关联组件是否渲染完成" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="354" y="520" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="43" value="" style="edgeStyle=none;html=1;" parent="1" source="40" target="42" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="40" value="格式化数据" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="660" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="45" value="" style="edgeStyle=none;html=1;" parent="1" source="42" target="44" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="42" value="发送请求" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="800" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="70" value="" style="edgeStyle=none;html=1;" parent="1" source="44" target="69" edge="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="44" value="根据配置的过滤函数处理返回结果" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="940" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="51" value="Store<br>{<br>"组件Id1": value,<br>"组件Id2":value,<br>}" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="330" y="110" width="120" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="63" value="" style="endArrow=classic;startArrow=classic;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="32" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="560" as="sourcePoint"/>
|
||||
<mxPoint x="330" y="150" as="targetPoint"/>
|
||||
<Array as="points">
|
||||
<mxPoint x="80" y="550"/>
|
||||
<mxPoint x="80" y="150"/>
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="64" value="根据关联组件Id获取源数据" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="63" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.1051" y="1" relative="1" as="geometry">
|
||||
<mxPoint y="61" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="66" value="比如日期范围,<br>绑定值[2022-08-08,2022-08-09],<br>需要格式化为开始时间、结束时间两个字段" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="327" y="665" width="240" height="50" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="68" value="" style="endArrow=none;dashed=1;html=1;" parent="1" target="66" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="260" y="690" as="sourcePoint"/>
|
||||
<mxPoint x="320" y="670" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="69" value="渲染视图" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="134" y="1080" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
Loading…
x
Reference in New Issue
Block a user