mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-12-24 08:12:55 +08:00
按需加载,移除vue-chart
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
"crypto-js": "^4.2.0",
|
||||
"css-color-function": "^1.3.3",
|
||||
"dayjs": "^1.11.19",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.12.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
@@ -39,12 +39,11 @@
|
||||
"spark-md5": "^3.0.2",
|
||||
"vue": "^3.5.25",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-echarts": "^7.0.3",
|
||||
"vue-router": "^4.5.1",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||
"vue3-video-play": "^1.3.2",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vxe-table": "^4.16.11",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8"
|
||||
"vxe-table": "^4.16.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.11.0",
|
||||
|
||||
123
admin/src/components/echart-component/index.vue
Normal file
123
admin/src/components/echart-component/index.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<!-- src/components/BaseChart.vue -->
|
||||
<template>
|
||||
<div ref="chartRef" class="base-chart" :style="{ width, height }"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onBeforeUnmount, watch, nextTick, ref, toRaw, shallowRef } from 'vue'
|
||||
import { echarts, ECOption } from '@/utils/echart'
|
||||
|
||||
// Props
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
option?: any
|
||||
width?: string
|
||||
height?: string
|
||||
loading?: boolean
|
||||
autoresize?: boolean // 是否自动 resize
|
||||
}>(),
|
||||
{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
loading: false,
|
||||
autoresize: true
|
||||
}
|
||||
)
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
(e: 'chartInstance', instance: echarts.ECharts): void
|
||||
}>()
|
||||
|
||||
// Refs
|
||||
const chartRef = ref<HTMLDivElement | null>(null)
|
||||
const chartInstance = shallowRef<echarts.ECharts | null>(null)
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return
|
||||
|
||||
// 销毁已有实例
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose()
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
chartInstance.value = echarts.init(chartRef.value)
|
||||
emit('chartInstance', chartInstance.value)
|
||||
|
||||
// 监听 option 变化
|
||||
setOption(props.option)
|
||||
}
|
||||
|
||||
// 设置配置项
|
||||
const setOption = (option: ECOption) => {
|
||||
if (!chartInstance.value || !option) return
|
||||
chartInstance.value.setOption(toRaw(option), {
|
||||
notMerge: false, // 合并配置(可设为 true 实现增量更新)
|
||||
lazyUpdate: false
|
||||
})
|
||||
}
|
||||
|
||||
// 处理 loading
|
||||
watch(
|
||||
() => props.loading,
|
||||
(loading) => {
|
||||
if (chartInstance.value) {
|
||||
loading ? chartInstance.value.showLoading() : chartInstance.value.hideLoading()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 响应 option 变化
|
||||
watch(
|
||||
() => props.option,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
setOption(props.option)
|
||||
})
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
// 自动 resize
|
||||
let resizeObserver: ResizeObserver | null = null
|
||||
const handleResize = () => {
|
||||
chartInstance.value?.resize()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initChart()
|
||||
|
||||
// 方式1:监听 window resize(简单场景)
|
||||
if (props.autoresize) {
|
||||
window.addEventListener('resize', handleResize)
|
||||
}
|
||||
|
||||
// 方式2(更精准):使用 ResizeObserver(推荐)
|
||||
if (typeof ResizeObserver !== 'undefined' && chartRef.value) {
|
||||
resizeObserver = new ResizeObserver(handleResize)
|
||||
resizeObserver.observe(chartRef.value)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose()
|
||||
}
|
||||
window.removeEventListener('resize', handleResize)
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
})
|
||||
defineExpose({
|
||||
setOption
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -63,7 +63,7 @@
|
||||
import { ref, useTemplateRef, watch, defineAsyncComponent } from 'vue'
|
||||
// import XForm from './XForm/index.vue'
|
||||
// import XForm2 from './XForm2/index.vue'
|
||||
const XForm2 = defineAsyncComponent(() => import('./XForm2/index.vue'))
|
||||
const XForm2 = defineAsyncComponent(() => import('./XForm/index.vue'))
|
||||
// import FlowEdit from './flowEdit/index.vue'
|
||||
const FlowEdit = defineAsyncComponent(() => import('./flowEdit/index.vue'))
|
||||
import BasicSetting from './BasicSetting/index.vue'
|
||||
|
||||
@@ -1,17 +1,42 @@
|
||||
<template>
|
||||
<v-form-designer ref="designerRef" :designer-config="designerConfig"></v-form-designer>
|
||||
<!-- <v-form-designer ref="designerRef" :designer-config="designerConfig"></v-form-designer> -->
|
||||
<fc-designer ref="designerRef" :config="config" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, useTemplateRef } from 'vue'
|
||||
import 'vform3-builds/dist/designer.style.css' //引入VForm3样式
|
||||
const designerRef = useTemplateRef<any>('designerRef')
|
||||
function setData(json) {
|
||||
import FcDesigner from '@form-create/designer'
|
||||
|
||||
const designerRef = useTemplateRef<InstanceType<typeof FcDesigner>>('designerRef')
|
||||
const config = {}
|
||||
function setData(json: any[]) {
|
||||
console.log('setFormJson', json)
|
||||
designerRef.value.setFormJson(json)
|
||||
json && designerRef.value.setRule(json)
|
||||
|
||||
// 使用 getJson和 getOptionsJson导出数据。
|
||||
// 使用 setRule和 setOptions方法回显数据。
|
||||
}
|
||||
function getFieldWidgets() {
|
||||
const fieldList = designerRef.value.getFieldWidgets()
|
||||
const description = designerRef.value.getDescription()
|
||||
console.log('description', description)
|
||||
const fieldList: { id: string; name: string }[] = []
|
||||
function deepChild(item: any) {
|
||||
if (item.children) {
|
||||
item.children.forEach((child: any) => {
|
||||
deepChild(child)
|
||||
})
|
||||
} else {
|
||||
fieldList.push({
|
||||
id: item.field,
|
||||
name: item.title
|
||||
})
|
||||
}
|
||||
}
|
||||
description &&
|
||||
description.forEach((item) => {
|
||||
deepChild(item)
|
||||
})
|
||||
|
||||
console.log('getFieldWidgets', fieldList)
|
||||
return fieldList
|
||||
}
|
||||
@@ -20,8 +45,15 @@ function getData() {
|
||||
formData: any
|
||||
}>((resolve, reject) => {
|
||||
try {
|
||||
const jsonData = designerRef.value.getFormJson()
|
||||
const jsonData = designerRef.value.getRule()
|
||||
const getOption = designerRef.value.getOption()
|
||||
const getDescription = designerRef.value.getDescription()
|
||||
// 表单组件的层级结构数据
|
||||
const getFormDescription = designerRef.value.getFormDescription()
|
||||
console.log('jsonData', jsonData)
|
||||
console.log('getOption', getOption)
|
||||
console.log('getDescription', getDescription)
|
||||
console.log('getFormDescription', getFormDescription)
|
||||
resolve({ formData: jsonData })
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
@@ -30,15 +62,11 @@ function getData() {
|
||||
}
|
||||
const props = defineProps({
|
||||
conf: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
const designerConfig = {
|
||||
languageMenu: false,
|
||||
externalLink: false,
|
||||
formTemplates: false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setData(props.conf)
|
||||
})
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<!-- <v-form-designer ref="designerRef" :designer-config="designerConfig"></v-form-designer> -->
|
||||
<fc-designer ref="designerRef" :config="config" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, useTemplateRef } from 'vue'
|
||||
import FcDesigner from '@form-create/designer'
|
||||
|
||||
const designerRef = useTemplateRef<InstanceType<typeof FcDesigner>>('designerRef')
|
||||
const config = {}
|
||||
function setData(json: any[]) {
|
||||
console.log('setFormJson', json)
|
||||
json && designerRef.value.setRule(json)
|
||||
|
||||
// 使用 getJson和 getOptionsJson导出数据。
|
||||
// 使用 setRule和 setOptions方法回显数据。
|
||||
}
|
||||
function getFieldWidgets() {
|
||||
const description = designerRef.value.getDescription()
|
||||
console.log('description', description)
|
||||
const fieldList: { id: string; name: string }[] = []
|
||||
function deepChild(item: any) {
|
||||
if (item.children) {
|
||||
item.children.forEach((child: any) => {
|
||||
deepChild(child)
|
||||
})
|
||||
} else {
|
||||
fieldList.push({
|
||||
id: item.field,
|
||||
name: item.title
|
||||
})
|
||||
}
|
||||
}
|
||||
description &&
|
||||
description.forEach((item) => {
|
||||
deepChild(item)
|
||||
})
|
||||
|
||||
console.log('getFieldWidgets', fieldList)
|
||||
return fieldList
|
||||
}
|
||||
function getData() {
|
||||
return new Promise<{
|
||||
formData: any
|
||||
}>((resolve, reject) => {
|
||||
try {
|
||||
const jsonData = designerRef.value.getRule()
|
||||
const getOption = designerRef.value.getOption()
|
||||
const getDescription = designerRef.value.getDescription()
|
||||
// 表单组件的层级结构数据
|
||||
const getFormDescription = designerRef.value.getFormDescription()
|
||||
console.log('jsonData', jsonData)
|
||||
console.log('getOption', getOption)
|
||||
console.log('getDescription', getDescription)
|
||||
console.log('getFormDescription', getFormDescription)
|
||||
resolve({ formData: jsonData })
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
const props = defineProps({
|
||||
conf: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
setData(props.conf)
|
||||
})
|
||||
defineExpose({
|
||||
setData,
|
||||
getData,
|
||||
getFieldWidgets
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-range-editor.el-input__wrapper {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeUnmount, useTemplateRef } from 'vue'
|
||||
import { ref, onMounted, onBeforeUnmount, useTemplateRef, defineAsyncComponent } from 'vue'
|
||||
import { LogicFlow } from '@logicflow/core'
|
||||
|
||||
import { SelectionSelect, Menu, BpmnElement, MiniMap } from '@logicflow/extension'
|
||||
@@ -31,9 +31,12 @@ import type { NodeType, PropertiesType } from './PropertyPanel/property.type'
|
||||
import '@logicflow/core/lib/style/index.css'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
|
||||
import DiagramToolbar from './DiagramToolbar.vue'
|
||||
import DiagramSidebar from './DiagramSidebar.vue'
|
||||
import PropertyPanel from './PropertyPanel/index.vue'
|
||||
// import DiagramToolbar from './DiagramToolbar.vue'
|
||||
// import DiagramSidebar from './DiagramSidebar.vue'
|
||||
// import PropertyPanel from './PropertyPanel/index.vue'
|
||||
const DiagramToolbar = defineAsyncComponent(() => import('./DiagramToolbar.vue'))
|
||||
const DiagramSidebar = defineAsyncComponent(() => import('./DiagramSidebar.vue'))
|
||||
const PropertyPanel = defineAsyncComponent(() => import('./PropertyPanel/index.vue'))
|
||||
import { registerCustomElement } from './node'
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -256,18 +256,19 @@
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
<preview v-model="showPreview" :url="previewUrl" />
|
||||
<Preview v-model="showPreview" :url="previewUrl" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FileTabsMap } from '@/enums/fileEnums'
|
||||
import { onMounted, ref, watch, computed } from 'vue'
|
||||
import { onMounted, ref, watch, computed, defineAsyncComponent } from 'vue'
|
||||
import { FileExt } from '@/enums/fileEnums'
|
||||
|
||||
import { useCate, useFile } from './hook'
|
||||
import FileItem from './file.vue'
|
||||
import Preview from './preview.vue'
|
||||
// import Preview from './preview.vue'
|
||||
const Preview = defineAsyncComponent(() => import('./preview.vue'))
|
||||
const props = defineProps({
|
||||
limit: {
|
||||
type: Number,
|
||||
|
||||
@@ -1,33 +1,57 @@
|
||||
//引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
|
||||
|
||||
import * as echarts from 'echarts/core'
|
||||
import type {
|
||||
// 系列类型的定义后缀都为 SeriesOption
|
||||
BarSeriesOption,
|
||||
LineSeriesOption
|
||||
} from 'echarts/charts'
|
||||
import type {
|
||||
// 组件类型的定义后缀都为 ComponentOption
|
||||
TitleComponentOption,
|
||||
TooltipComponentOption,
|
||||
GridComponentOption,
|
||||
DatasetComponentOption
|
||||
} from 'echarts/components'
|
||||
|
||||
import type { ComposeOption } from 'echarts/core'
|
||||
|
||||
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
|
||||
export type ECOption = ComposeOption<
|
||||
| BarSeriesOption
|
||||
| LineSeriesOption
|
||||
| TitleComponentOption
|
||||
| TooltipComponentOption
|
||||
| GridComponentOption
|
||||
| DatasetComponentOption
|
||||
>
|
||||
|
||||
//引入柱状图图表,图表后缀都为 Chart
|
||||
import {
|
||||
BarChart,
|
||||
LineChart,
|
||||
PieChart,
|
||||
MapChart,
|
||||
PictorialBarChart,
|
||||
RadarChart,
|
||||
ScatterChart,
|
||||
GaugeChart
|
||||
PieChart
|
||||
// MapChart,//地图
|
||||
// PictorialBarChart,//象形柱状图
|
||||
// RadarChart,//雷达图
|
||||
// ScatterChart,//散点图
|
||||
// GaugeChart,//仪表盘
|
||||
} from 'echarts/charts'
|
||||
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
|
||||
import {
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
PolarComponent,
|
||||
AriaComponent,
|
||||
ParallelComponent,
|
||||
// PolarComponent,//极坐标系
|
||||
// AriaComponent, //无障碍访问组件
|
||||
// ParallelComponent,//平行坐标系
|
||||
LegendComponent,
|
||||
RadarComponent,
|
||||
ToolboxComponent,
|
||||
DataZoomComponent,
|
||||
VisualMapComponent,
|
||||
TimelineComponent,
|
||||
CalendarComponent,
|
||||
GraphicComponent
|
||||
// RadarComponent,//雷达图
|
||||
// ToolboxComponent,
|
||||
DataZoomComponent
|
||||
// VisualMapComponent,//视觉映射组件
|
||||
// TimelineComponent,//时间线组件
|
||||
// CalendarComponent,//日历组件
|
||||
// GraphicComponent,//图形组件
|
||||
} from 'echarts/components'
|
||||
|
||||
//引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
|
||||
@@ -41,25 +65,27 @@ echarts.use([
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
PolarComponent,
|
||||
AriaComponent,
|
||||
ParallelComponent,
|
||||
// PolarComponent,
|
||||
// AriaComponent,
|
||||
// ParallelComponent,
|
||||
BarChart,
|
||||
LineChart,
|
||||
PieChart,
|
||||
MapChart,
|
||||
RadarChart,
|
||||
PictorialBarChart,
|
||||
RadarComponent,
|
||||
ToolboxComponent,
|
||||
// MapChart,
|
||||
// RadarChart,
|
||||
// PictorialBarChart,
|
||||
// RadarComponent,
|
||||
// ToolboxComponent,
|
||||
DataZoomComponent,
|
||||
VisualMapComponent,
|
||||
TimelineComponent,
|
||||
CalendarComponent,
|
||||
GraphicComponent,
|
||||
ScatterChart,
|
||||
// VisualMapComponent,
|
||||
// TimelineComponent,
|
||||
// CalendarComponent,
|
||||
// GraphicComponent,
|
||||
// ScatterChart,
|
||||
CanvasRenderer,
|
||||
LabelLayout,
|
||||
UniversalTransition,
|
||||
GaugeChart
|
||||
UniversalTransition
|
||||
// GaugeChart
|
||||
])
|
||||
|
||||
export { echarts }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="flex-1 flex items-center justify-center">
|
||||
<div class="login-card flex rounded-md">
|
||||
<div class="flex-1 h-full hidden md:inline-block">
|
||||
<image-contain :src="config.webBackdrop" :width="400" height="100%" />
|
||||
<ImageContain :src="config.webBackdrop" :width="400" height="100%" />
|
||||
</div>
|
||||
<div
|
||||
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[400px] w-[375px] flex-none mx-auto"
|
||||
@@ -102,7 +102,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, reactive, useTemplateRef } from 'vue'
|
||||
import { computed, onMounted, reactive, useTemplateRef, defineAsyncComponent } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import type { InputInstance, FormInstance } from 'element-plus'
|
||||
import LayoutFooter from '@/layout/components/footer.vue'
|
||||
@@ -113,8 +113,8 @@ import { ACCOUNT_KEY } from '@/enums/cacheEnums'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import { useLockFn } from '@/hooks/useLockFn'
|
||||
import { encryptPassword } from '@/utils/util'
|
||||
import Verify from '@/components/verify/Verify.vue'
|
||||
import ImageContain from '@/components/image-contain/index.vue'
|
||||
const Verify = defineAsyncComponent(() => import('@/components/verify/Verify.vue'))
|
||||
const ImageContain = defineAsyncComponent(() => import('@/components/image-contain/index.vue'))
|
||||
// const verifyRef = ref(null)
|
||||
const verifyRef = useTemplateRef<InstanceType<typeof Verify>>('verifyRef')
|
||||
const onShowCaptcha = () => {
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onActivated } from 'vue'
|
||||
import { ref, reactive, onActivated, defineAsyncComponent } from 'vue'
|
||||
import {
|
||||
generateTable,
|
||||
syncColumn,
|
||||
@@ -153,8 +153,8 @@ import {
|
||||
downloadCode
|
||||
} from '@/api/tools/code'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import DataTable from './components/data-table.vue'
|
||||
import CodePreview from './components/code-preview.vue'
|
||||
const DataTable = defineAsyncComponent(() => import('./components/data-table.vue'))
|
||||
const CodePreview = defineAsyncComponent(() => import('./components/code-preview.vue'))
|
||||
import feedback from '@/utils/feedback'
|
||||
import { streamFileDownload } from '@/utils/file'
|
||||
defineOptions({
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
:destroy-on-close="true"
|
||||
:title="applyDetail.flowName"
|
||||
>
|
||||
<formCreate
|
||||
<FormCreate
|
||||
v-if="dialogVisible"
|
||||
:rule="formJson"
|
||||
v-model="formData"
|
||||
v-model:api="api"
|
||||
:option="options"
|
||||
></formCreate>
|
||||
></FormCreate>
|
||||
|
||||
<!-- <v-form-render
|
||||
:form-json="formJson"
|
||||
@@ -48,8 +48,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import formCreate from '@form-create/element-ui'
|
||||
import { computed, ref, defineAsyncComponent } from 'vue'
|
||||
// import formCreate from '@form-create/element-ui'
|
||||
const FormCreate = defineAsyncComponent(() => import('@form-create/element-ui'))
|
||||
import type { Api } from '@form-create/element-ui'
|
||||
import { useDictData } from '@/hooks/useDictOptions'
|
||||
import type { type_dict } from '@/hooks/useDictOptions'
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, reactive } from 'vue'
|
||||
import { shallowRef, reactive, defineAsyncComponent } from 'vue'
|
||||
import {
|
||||
flow_apply_delete,
|
||||
flow_apply_lists,
|
||||
@@ -105,9 +105,8 @@ import { useDictData } from '@/hooks/useDictOptions'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
import ApplySubmit from './components/apply_submit.vue'
|
||||
import ViewForm from './components/ViewForm.vue'
|
||||
|
||||
const ApplySubmit = defineAsyncComponent(() => import('./components/apply_submit.vue'))
|
||||
const ViewForm = defineAsyncComponent(() => import('./components/ViewForm.vue'))
|
||||
defineOptions({
|
||||
name: 'flow_apply'
|
||||
})
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</el-card>
|
||||
<edit-popup
|
||||
<EditPopup
|
||||
v-if="showEdit"
|
||||
ref="editRef"
|
||||
:dict-data="dictData"
|
||||
@@ -144,7 +144,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, shallowRef, nextTick } from 'vue'
|
||||
import { ref, reactive, shallowRef, nextTick, defineAsyncComponent } from 'vue'
|
||||
import {
|
||||
flow_apply_delete,
|
||||
flow_apply_lists,
|
||||
@@ -158,10 +158,10 @@ import { useDictData } from '@/hooks/useDictOptions'
|
||||
import type { type_dict } from '@/hooks/useDictOptions'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import EditPopup from './edit.vue'
|
||||
const EditPopup = defineAsyncComponent(() => import('./edit.vue'))
|
||||
|
||||
import ApplySubmit from './components/apply_submit.vue'
|
||||
import ViewForm from './components/ViewForm.vue'
|
||||
const ApplySubmit = defineAsyncComponent(() => import('./components/apply_submit.vue'))
|
||||
const ViewForm = defineAsyncComponent(() => import('./components/ViewForm.vue'))
|
||||
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
draggable
|
||||
:title="applyDetail.flowName"
|
||||
>
|
||||
<formCreate
|
||||
<FormCreate
|
||||
v-if="dialogVisible"
|
||||
:rule="formJson"
|
||||
v-model="formData"
|
||||
v-model:api="api"
|
||||
:option="options"
|
||||
></formCreate>
|
||||
></FormCreate>
|
||||
<!-- <v-form-render
|
||||
:form-json="formJson"
|
||||
:form-data="formData"
|
||||
@@ -36,8 +36,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import formCreate from '@form-create/element-ui'
|
||||
import { ref, defineAsyncComponent } from 'vue'
|
||||
const FormCreate = defineAsyncComponent(() => import('@form-create/element-ui'))
|
||||
import type { Api } from '@form-create/element-ui'
|
||||
|
||||
// import { flow_apply_detail } from '@/api/flow/flow_apply'
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, reactive } from 'vue'
|
||||
import { shallowRef, reactive, defineAsyncComponent } from 'vue'
|
||||
import { flow_apply_detail } from '@/api/flow/flow_apply'
|
||||
import { flow_history_list } from '@/api/flow/flow_history'
|
||||
import type { type_flow_apply } from '@/api/flow/flow_apply'
|
||||
@@ -76,9 +76,7 @@ import type { type_flow_apply } from '@/api/flow/flow_apply'
|
||||
import { useDictData } from '@/hooks/useDictOptions'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
// import ApplySubmit from '@/views/flow/flow_apply/components/apply_submit.vue'
|
||||
import ViewForm from './components/ViewForm.vue'
|
||||
|
||||
const ViewForm = defineAsyncComponent(() => import('./components/ViewForm.vue'))
|
||||
const userStore = useUserStore()
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, reactive } from 'vue'
|
||||
import { shallowRef, reactive, defineAsyncComponent } from 'vue'
|
||||
import { flow_apply_detail } from '@/api/flow/flow_apply'
|
||||
import { flow_history_list, flow_history_edit } from '@/api/flow/flow_history'
|
||||
import type { type_flow_history } from '@/api/flow/flow_history'
|
||||
@@ -78,7 +78,8 @@ import { usePaging } from '@/hooks/usePaging'
|
||||
import feedback from '@/utils/feedback'
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
import ApplySubmit from './components/apply_submit.vue'
|
||||
import ViewForm from './components/ViewForm.vue'
|
||||
// import ViewForm from './components/ViewForm.vue'
|
||||
const ViewForm = defineAsyncComponent(() => import('./components/ViewForm.vue'))
|
||||
import Back from './components/Back.vue'
|
||||
const userStore = useUserStore()
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MaterialComponent from '@/components/material/index.vue'
|
||||
// import MaterialComponent from '@/components/material/index.vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
const MaterialComponent = defineAsyncComponent(() => import('@/components/material/index.vue'))
|
||||
|
||||
defineOptions({
|
||||
name: 'materialCenter'
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
</el-table-column>
|
||||
</el-table> -->
|
||||
</div>
|
||||
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
<EditPopup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, useTemplateRef, nextTick } from 'vue'
|
||||
|
||||
@@ -118,7 +118,10 @@
|
||||
<div>
|
||||
<div class="mb-10">命令统计</div>
|
||||
<div class="flex h-[300px] items-center">
|
||||
<v-charts autoresize :option="chartOptions.commandChartOption" />
|
||||
<echart-component
|
||||
:option="chartOptions.commandChartOption"
|
||||
:autoresize="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -128,7 +131,10 @@
|
||||
<div>
|
||||
<div class="mb-10">内存信息</div>
|
||||
<div class="flex h-[300px] items-center">
|
||||
<v-charts autoresize :option="chartOptions.memoryChartOption" />
|
||||
<echart-component
|
||||
:option="chartOptions.memoryChartOption"
|
||||
:autoresize="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -138,8 +144,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { systemCache } from '@/api/setting/system'
|
||||
import '@/utils/echart'
|
||||
import vCharts from 'vue-echarts'
|
||||
|
||||
import { reactive, ref } from 'vue'
|
||||
// import { ElTable } from 'element-plus'
|
||||
defineOptions({
|
||||
|
||||
@@ -79,10 +79,12 @@
|
||||
<template #header>
|
||||
<span>访问量趋势图</span>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<v-charts
|
||||
style="height: 350px"
|
||||
:option="workbenchData.visitorOption"
|
||||
<echart-component
|
||||
ref="visitorChartRef"
|
||||
height="350px"
|
||||
:option="visitorOption"
|
||||
:autoresize="true"
|
||||
/>
|
||||
</div>
|
||||
@@ -92,12 +94,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onDeactivated, onActivated, onMounted, onUnmounted } from 'vue'
|
||||
import { reactive, onDeactivated, onActivated, onMounted, useTemplateRef, onUnmounted } from 'vue'
|
||||
import { getWorkbench } from '@/api/app'
|
||||
import '@/utils/echart'
|
||||
import vCharts from 'vue-echarts'
|
||||
|
||||
import feedback from '@/utils/feedback'
|
||||
import useUserStore from '@/stores/modules/user'
|
||||
|
||||
import type { ECOption } from '@/utils/echart'
|
||||
|
||||
const userStore = useUserStore()
|
||||
defineOptions({
|
||||
name: 'workbench'
|
||||
@@ -118,37 +122,36 @@ const workbenchData: any = reactive({
|
||||
today: {}, // 今日数据
|
||||
|
||||
visitor: [], // 访问量
|
||||
article: [], // 文章阅读量
|
||||
|
||||
visitorOption: {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [0]
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
legend: {
|
||||
data: ['访问量']
|
||||
},
|
||||
itemStyle: {
|
||||
// 点的颜色。
|
||||
color: 'red'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '访问量',
|
||||
data: [0],
|
||||
type: 'line',
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
}
|
||||
article: [] // 文章阅读量
|
||||
})
|
||||
|
||||
const visitorOption = {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: []
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
legend: {
|
||||
data: ['访问量']
|
||||
},
|
||||
itemStyle: {
|
||||
// 点的颜色。
|
||||
color: 'red'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '访问量',
|
||||
data: [],
|
||||
type: 'line',
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
}
|
||||
const visitorChartRef = useTemplateRef('visitorChartRef')
|
||||
// 获取工作台主页数据
|
||||
const getData = async () => {
|
||||
const res = await getWorkbench()
|
||||
@@ -156,27 +159,22 @@ const getData = async () => {
|
||||
workbenchData.today = res.today
|
||||
workbenchData.visitor = res.visitor
|
||||
|
||||
// 清空echarts 数据
|
||||
workbenchData.visitorOption.xAxis.data = []
|
||||
workbenchData.visitorOption.series[0].data = []
|
||||
|
||||
// 写入从后台拿来的数据
|
||||
workbenchData.visitorOption.xAxis.data = res.visitor.date
|
||||
workbenchData.visitorOption.series[0].data = res.visitor.list
|
||||
visitorOption.xAxis.data = res.visitor.date
|
||||
visitorOption.series[0].data = res.visitor.list
|
||||
visitorChartRef.value?.setOption(visitorOption as ECOption)
|
||||
}
|
||||
const timer: any = null
|
||||
function updateChart(val) {
|
||||
// clearInterval(timer)
|
||||
// timer = setInterval(() => {
|
||||
workbenchData.visitorOption.xAxis.data.push(new Date().toLocaleTimeString())
|
||||
workbenchData.visitorOption.series[0].data.push(val)
|
||||
visitorOption.xAxis.data.push(new Date().toLocaleTimeString())
|
||||
visitorOption.series[0].data.push(val)
|
||||
|
||||
// 保持数据长度在10个
|
||||
if (workbenchData.visitorOption.xAxis.data.length > 20) {
|
||||
workbenchData.visitorOption.xAxis.data.shift()
|
||||
workbenchData.visitorOption.series[0].data.shift()
|
||||
if (visitorOption.xAxis.data.length > 20) {
|
||||
visitorOption.xAxis.data.shift()
|
||||
visitorOption.series[0].data.shift()
|
||||
}
|
||||
// }, 1000)
|
||||
visitorChartRef.value?.setOption(visitorOption as ECOption)
|
||||
}
|
||||
// // 用户 A,加入 room1
|
||||
const wsA = new WebSocket(`ws://localhost:8080/api/ws?token=${userStore.token}&room=room1`)
|
||||
@@ -192,6 +190,9 @@ wsA.onmessage = (event) => {
|
||||
feedback.msgSuccess(event.data)
|
||||
updateChart(JSON.parse(event.data).onlineCount)
|
||||
}
|
||||
wsA.onerror = (error) => {
|
||||
console.error('用户 A 连接错误:', error)
|
||||
}
|
||||
|
||||
// // 用户 B,加入 room1
|
||||
// wsB.onmessage = (event) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
optimizeDeps: {
|
||||
// 依赖预构建,避免开发刷新
|
||||
include: ['@wangeditor/editor-for-vue', 'vuedraggable', 'vue-echarts', 'crypto-js']
|
||||
include: ['@wangeditor/editor-for-vue', 'vuedraggable', 'crypto-js']
|
||||
},
|
||||
|
||||
base: '/',
|
||||
@@ -42,63 +42,51 @@ export default defineConfig(({ mode }) => {
|
||||
},
|
||||
{
|
||||
name: 'vue-router',
|
||||
test: /node_modules\/vue-router/
|
||||
test: /node_modules\/vue-router\//
|
||||
},
|
||||
{
|
||||
name: 'element-plus',
|
||||
test: /node_modules\/element-plus/
|
||||
test: /node_modules\/element-plus\//
|
||||
},
|
||||
{
|
||||
name: 'axios',
|
||||
test: /node_modules\/axios/
|
||||
test: /node_modules\/axios\//
|
||||
},
|
||||
{
|
||||
name: 'dayjs',
|
||||
test: /node_modules\/dayjs/
|
||||
test: /node_modules\/dayjs\//
|
||||
},
|
||||
// vuedraggable
|
||||
{
|
||||
name: 'vuedraggable',
|
||||
test: /node_modules\/vuedraggable/
|
||||
test: /node_modules\/vuedraggable\//
|
||||
},
|
||||
// vue3-video-play
|
||||
{
|
||||
name: 'vue3-video-play',
|
||||
test: /node_modules\/vue3-video-play/
|
||||
test: /node_modules\/vue3-video-play\//
|
||||
},
|
||||
// echarts
|
||||
{
|
||||
name: 'echarts',
|
||||
test: /node_modules\/echarts/
|
||||
test: /node_modules\/echarts\//
|
||||
},
|
||||
// highlight.js
|
||||
{
|
||||
name: 'highlight.js',
|
||||
test: /node_modules\/highlight\.js/
|
||||
test: /node_modules\/highlight\.js\//
|
||||
},
|
||||
// lodash-es
|
||||
{
|
||||
name: 'lodash-es',
|
||||
test: /node_modules\/lodash-es/
|
||||
test: /node_modules\/lodash-es\//
|
||||
},
|
||||
// @wangeditor/editor
|
||||
{
|
||||
name: '@wangeditor/editor',
|
||||
test: /node_modules\/@wangeditor/
|
||||
test: /node_modules\/@wangeditor\//
|
||||
}
|
||||
]
|
||||
// vue: ['vue'],
|
||||
// 'vue-router': ['vue-router'],
|
||||
// pinia: ['pinia'],
|
||||
// axios: ['axios'],
|
||||
// dayjs: ['dayjs'],
|
||||
// // echarts: ['echarts'],
|
||||
// // 'highlight.js': ['highlight.js'],
|
||||
// 'element-plus': ['element-plus']
|
||||
|
||||
// // 'lodash-es': ['lodash-es'],
|
||||
// // vuedraggable: ['vuedraggable'],
|
||||
// // 'vform3-builds': ['vform3-builds']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user