产出品管理 - 产出品概览页面饼图展示开发
This commit is contained in:
		
							parent
							
								
									f9f83986df
								
							
						
					
					
						commit
						b741c624f2
					
				| @ -10,6 +10,7 @@ declare module 'vue' { | ||||
|     AreaCascader: typeof import('./src/components/AreaCascader/index.vue')['default'] | ||||
|     AreaSelect: typeof import('./src/components/AreaSelect/index.vue')['default'] | ||||
|     CodeDialog: typeof import('./src/components/code-dialog/index.vue')['default'] | ||||
|     CustomEchartPie: typeof import('./src/components/custom-echart-pie/index.vue')['default'] | ||||
|     FileUploader: typeof import('./src/components/FileUploader/index.vue')['default'] | ||||
|     LandSelect: typeof import('./src/components/LandSelect.vue')['default'] | ||||
|     RouterLink: typeof import('vue-router')['RouterLink'] | ||||
|  | ||||
| @ -0,0 +1,101 @@ | ||||
| <template> | ||||
|   <div ref="chartRef" :style="{ height, width }"></div> | ||||
| </template> | ||||
| <script> | ||||
| import { ref, reactive, watch, watchEffect } from 'vue'; | ||||
| import { cloneDeep } from 'lodash'; | ||||
| import { useEcharts } from '../../hooks/useEcharts'; | ||||
| 
 | ||||
| export default { | ||||
|   name: 'CustomEchartPie', | ||||
|   props: { | ||||
|     chartData: { | ||||
|       type: Array, | ||||
|       default: () => [], | ||||
|     }, | ||||
|     size: { | ||||
|       type: Object, | ||||
|       default: () => {}, | ||||
|     }, | ||||
|     option: { | ||||
|       type: Object, | ||||
|       default: () => ({}), | ||||
|     }, | ||||
|     width: { | ||||
|       type: String, | ||||
|       default: '100%', | ||||
|     }, | ||||
|     height: { | ||||
|       type: String, | ||||
|       default: 'calc(100vh - 78px)', | ||||
|     }, | ||||
|   }, | ||||
|   emits: ['click'], | ||||
|   setup(props, { emit }) { | ||||
|     const chartRef = ref(null); | ||||
|     const { setOptions, getInstance, resize, startAutoPlay } = useEcharts(chartRef); | ||||
|     const option = reactive({ | ||||
|       tooltip: { | ||||
|         backgroundColor: '#fff', // 背景颜色(支持RGBA格式) | ||||
|         borderColor: 'rgba(0, 0, 0, 0.1)', // 边框颜色 | ||||
|         borderWidth: 1, // 边框宽度 | ||||
|         textStyle: { | ||||
|           color: '#333', // 文字颜色 | ||||
|           fontSize: 12, | ||||
|         }, | ||||
|         formatter: '{b} ({c})', | ||||
|       }, | ||||
|       series: [ | ||||
|         { | ||||
|           type: 'pie', | ||||
|           radius: '72%', | ||||
|           center: ['50%', '55%'], | ||||
|           data: [], | ||||
|           labelLine: { show: true }, | ||||
|           label: { | ||||
|             show: true, | ||||
|             formatter: '{b} \n ({d}%)', | ||||
|             color: '#B1B9D3', | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }); | ||||
| 
 | ||||
|     watchEffect(() => { | ||||
|       props.chartData && initCharts(); | ||||
|     }); | ||||
| 
 | ||||
|     watch( | ||||
|       () => props.size, | ||||
|       () => { | ||||
|         resize(); | ||||
|       }, | ||||
|       { | ||||
|         immediate: true, | ||||
|       } | ||||
|     ); | ||||
| 
 | ||||
|     function initCharts() { | ||||
|       if (props.option) { | ||||
|         Object.assign(option, cloneDeep(props.option)); | ||||
|       } | ||||
|       option.series[0].data = props.chartData; | ||||
|       setOptions(option); | ||||
|       startAutoPlay({ | ||||
|         interval: 2000, | ||||
|         seriesIndex: 0, | ||||
|         showTooltip: true, | ||||
|       }); | ||||
|       resize(); | ||||
|       getInstance()?.off('click', onClick); | ||||
|       getInstance()?.on('click', onClick); | ||||
|     } | ||||
| 
 | ||||
|     function onClick(params) { | ||||
|       emit('click', params); | ||||
|     } | ||||
| 
 | ||||
|     return { chartRef }; | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
							
								
								
									
										84
									
								
								sub-government-affairs-service/src/hooks/useBreakpoint.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								sub-government-affairs-service/src/hooks/useBreakpoint.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| import { ref, computed, unref } from 'vue'; | ||||
| import { useEventListener } from './useEventListener'; | ||||
| 
 | ||||
| let globalScreenRef = 0; | ||||
| let globalWidthRef = 0; | ||||
| let globalRealWidthRef = 0; | ||||
| 
 | ||||
| const screenMap = new Map(); | ||||
| screenMap.set('XS', 480); | ||||
| screenMap.set('SM', 576); | ||||
| screenMap.set('MD', 768); | ||||
| screenMap.set('LG', 992); | ||||
| screenMap.set('XL', 1200); | ||||
| screenMap.set('XXL', 1600); | ||||
| 
 | ||||
| export function useBreakpoint() { | ||||
|   return { | ||||
|     screenRef: computed(() => unref(globalScreenRef)), | ||||
|     widthRef: globalWidthRef, | ||||
|     realWidthRef: globalRealWidthRef, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| // Just call it once
 | ||||
| export function createBreakpointListen(fn) { | ||||
|   const screenRef = ref('XL'); | ||||
|   const realWidthRef = ref(window.innerWidth); | ||||
| 
 | ||||
|   function getWindowWidth() { | ||||
|     const width = document.body.clientWidth; | ||||
|     const xs = screenMap.get('XS'); | ||||
|     const sm = screenMap.get('SM'); | ||||
|     const md = screenMap.get('MD'); | ||||
|     const lg = screenMap.get('LG'); | ||||
|     const xl = screenMap.get('XL'); | ||||
|     const xxl = screenMap.set('XXL', 1600); | ||||
|     if (width < xs) { | ||||
|       screenRef.value = xs; | ||||
|     } else if (width < sm) { | ||||
|       screenRef.value = sm; | ||||
|     } else if (width < md) { | ||||
|       screenRef.value = md; | ||||
|     } else if (width < lg) { | ||||
|       screenRef.value = lg; | ||||
|     } else if (width < xl) { | ||||
|       screenRef.value = xl; | ||||
|     } else { | ||||
|       screenRef.value = xxl; | ||||
|     } | ||||
|     realWidthRef.value = width; | ||||
|   } | ||||
| 
 | ||||
|   useEventListener({ | ||||
|     el: window, | ||||
|     name: 'resize', | ||||
| 
 | ||||
|     listener: () => { | ||||
|       getWindowWidth(); | ||||
|       resizeFn(); | ||||
|     }, | ||||
|     // wait: 100,
 | ||||
|   }); | ||||
| 
 | ||||
|   getWindowWidth(); | ||||
|   globalScreenRef = computed(() => unref(screenRef)); | ||||
|   globalWidthRef = computed(() => screenMap.get(unref(screenRef))); | ||||
|   globalRealWidthRef = computed(() => unref(realWidthRef)); | ||||
| 
 | ||||
|   function resizeFn() { | ||||
|     fn?.({ | ||||
|       screen: globalScreenRef, | ||||
|       width: globalWidthRef, | ||||
|       realWidth: globalRealWidthRef, | ||||
|       screenMap, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   resizeFn(); | ||||
|   return { | ||||
|     screenRef: globalScreenRef, | ||||
|     widthRef: globalWidthRef, | ||||
|     realWidthRef: globalRealWidthRef, | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										191
									
								
								sub-government-affairs-service/src/hooks/useEcharts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								sub-government-affairs-service/src/hooks/useEcharts.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,191 @@ | ||||
| import { unref, nextTick, watch, computed, ref } from 'vue'; | ||||
| import { useDebounceFn, tryOnUnmounted } from '@vueuse/core'; | ||||
| import { useTimeoutFn } from './useTimeout'; | ||||
| import { useEventListener } from './useEventListener'; | ||||
| import { useBreakpoint } from './useBreakpoint'; | ||||
| import echarts from '../utils/echarts'; | ||||
| 
 | ||||
| export const useEcharts = (elRef, theme = 'default') => { | ||||
|   // 新增轮播相关状态
 | ||||
|   const autoPlayTimer = ref(null); | ||||
|   const currentIndex = ref(-1); | ||||
|   const dataLength = ref(0); | ||||
| 
 | ||||
|   // 新增方法 - 启动轮播
 | ||||
|   const startAutoPlay = (options = {}) => { | ||||
|     const { | ||||
|       interval = 2000, // 轮播间隔(ms)
 | ||||
|       seriesIndex = 0, // 默认操作第一个系列
 | ||||
|       showTooltip = true, // 是否显示提示框
 | ||||
|     } = options; | ||||
| 
 | ||||
|     stopAutoPlay(); // 先停止已有轮播
 | ||||
| 
 | ||||
|     // 获取数据长度
 | ||||
|     const seriesData = unref(getOptions).series?.[seriesIndex]?.data; | ||||
|     dataLength.value = seriesData?.length || 0; | ||||
|     if (dataLength.value === 0) return; | ||||
| 
 | ||||
|     autoPlayTimer.value = setInterval(() => { | ||||
|       currentIndex.value = (currentIndex.value + 1) % dataLength.value; | ||||
| 
 | ||||
|       // 执行轮播动作
 | ||||
|       chartInstance?.dispatchAction({ | ||||
|         type: 'downplay', | ||||
|         seriesIndex: seriesIndex, | ||||
|       }); | ||||
|       chartInstance?.dispatchAction({ | ||||
|         type: 'highlight', | ||||
|         seriesIndex: seriesIndex, | ||||
|         dataIndex: currentIndex.value, | ||||
|       }); | ||||
|       if (showTooltip) { | ||||
|         chartInstance?.dispatchAction({ | ||||
|           type: 'showTip', | ||||
|           seriesIndex: seriesIndex, | ||||
|           dataIndex: currentIndex.value, | ||||
|         }); | ||||
|       } | ||||
|     }, interval); | ||||
|   }; | ||||
| 
 | ||||
|   // 新增方法 - 停止轮播
 | ||||
|   const stopAutoPlay = () => { | ||||
|     if (autoPlayTimer.value) { | ||||
|       clearInterval(autoPlayTimer.value); | ||||
|       autoPlayTimer.value = null; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const getDarkMode = computed(() => { | ||||
|     return theme === 'default' ? 'dark' : theme; | ||||
|   }); | ||||
|   let chartInstance = null; | ||||
|   let resizeFn = resize; | ||||
|   const cacheOptions = ref({}); | ||||
|   let removeResizeFn = null; | ||||
| 
 | ||||
|   resizeFn = useDebounceFn(resize, 200); | ||||
| 
 | ||||
|   const getOptions = computed(() => { | ||||
|     if (getDarkMode.value !== 'dark') { | ||||
|       return cacheOptions.value; | ||||
|     } | ||||
|     return { | ||||
|       backgroundColor: 'transparent', | ||||
|       ...cacheOptions.value, | ||||
|     }; | ||||
|   }); | ||||
| 
 | ||||
|   function initCharts(t = theme) { | ||||
|     const el = unref(elRef); | ||||
|     if (!el || !unref(el)) { | ||||
|       return; | ||||
|     } | ||||
|     nextTick(() => { | ||||
|       if (el.offsetWidth === 0 || el.offsetHeight === 0) { | ||||
|         // console.warn('图表容器不可见,延迟初始化');
 | ||||
|         useTimeoutFn(() => initCharts(t), 100); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       chartInstance = echarts.init(el, t); | ||||
|       const { removeEvent } = useEventListener({ | ||||
|         el: window, | ||||
|         name: 'resize', | ||||
|         listener: resizeFn, | ||||
|       }); | ||||
|       removeResizeFn = removeEvent; | ||||
|       const { widthRef } = useBreakpoint(); | ||||
|       if (unref(widthRef) <= 768 || el.offsetHeight === 0) { | ||||
|         useTimeoutFn(() => { | ||||
|           resizeFn(); | ||||
|         }, 30); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   function setOptions(options = {}, clear = true) { | ||||
|     const mergedOptions = { | ||||
|       animation: true, | ||||
|       animationDuration: 3000, | ||||
|       animationEasing: 'cubicOut', | ||||
|       ...unref(options), | ||||
|       animationThreshold: 2000, // 数据量超过2000自动关闭动画
 | ||||
|       animationDelayUpdate: (idx) => idx * 50, // 数据项延迟
 | ||||
|     }; | ||||
|     cacheOptions.value = mergedOptions; | ||||
|     cacheOptions.value = options; | ||||
|     if (unref(elRef)?.offsetHeight === 0) { | ||||
|       useTimeoutFn(() => { | ||||
|         setOptions(unref(getOptions)); | ||||
|       }, 30); | ||||
|       return; | ||||
|     } | ||||
|     nextTick(() => { | ||||
|       useTimeoutFn(() => { | ||||
|         if (!chartInstance) { | ||||
|           initCharts(getDarkMode.value ?? 'default'); | ||||
| 
 | ||||
|           if (!chartInstance) return; | ||||
|         } | ||||
|         clear && chartInstance?.clear(); | ||||
| 
 | ||||
|         chartInstance?.setOption(unref(getOptions)); | ||||
|       }, 30); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   function resize() { | ||||
|     chartInstance?.resize(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * 注册地图数据 | ||||
|    * @param {string} mapName - 地图名称 | ||||
|    * @param {object} geoJSON - GeoJSON 数据 | ||||
|    */ | ||||
|   function registerMap(mapName, geoJSON) { | ||||
|     if (!mapName || !geoJSON) { | ||||
|       console.warn('地图名称或 GeoJSON 数据无效'); | ||||
|       return; | ||||
|     } | ||||
|     echarts.registerMap(mapName, geoJSON); | ||||
|   } | ||||
| 
 | ||||
|   watch( | ||||
|     () => getDarkMode.value, | ||||
|     (theme) => { | ||||
|       if (chartInstance) { | ||||
|         chartInstance.dispose(); | ||||
|         initCharts(theme); | ||||
|         setOptions(cacheOptions.value); | ||||
|       } | ||||
|     } | ||||
|   ); | ||||
| 
 | ||||
|   tryOnUnmounted(() => { | ||||
|     stopAutoPlay(); // 清理定时器
 | ||||
|     if (!chartInstance) return; | ||||
|     removeResizeFn(); | ||||
|     chartInstance.dispose(); | ||||
|     chartInstance = null; | ||||
|   }); | ||||
| 
 | ||||
|   function getInstance() { | ||||
|     if (!chartInstance) { | ||||
|       initCharts(getDarkMode.value ?? 'default'); | ||||
|     } | ||||
|     return chartInstance; | ||||
|   } | ||||
| 
 | ||||
|   return { | ||||
|     setOptions, | ||||
|     resize, | ||||
|     echarts, | ||||
|     getInstance: () => chartInstance, | ||||
|     registerMap, | ||||
|     startAutoPlay, // 暴露轮播方法
 | ||||
|     stopAutoPlay, | ||||
|   }; | ||||
| }; | ||||
							
								
								
									
										38
									
								
								sub-government-affairs-service/src/hooks/useEventListener.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								sub-government-affairs-service/src/hooks/useEventListener.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| import { ref, watch, unref } from 'vue'; | ||||
| import { useThrottleFn, useDebounceFn } from '@vueuse/core'; | ||||
| 
 | ||||
| export function useEventListener({ el = window, name, listener, options, autoRemove = true, isDebounce = true, wait = 80 }) { | ||||
|   let remove; | ||||
|   const isAddRef = ref(false); | ||||
| 
 | ||||
|   if (el) { | ||||
|     const element = ref(el); | ||||
| 
 | ||||
|     const handler = isDebounce ? useDebounceFn(listener, wait) : useThrottleFn(listener, wait); | ||||
|     const realHandler = wait ? handler : listener; | ||||
|     const removeEventListener = (e) => { | ||||
|       isAddRef.value = true; | ||||
|       e.removeEventListener(name, realHandler, options); | ||||
|     }; | ||||
|     const addEventListener = (e) => e.addEventListener(name, realHandler, options); | ||||
| 
 | ||||
|     const removeWatch = watch( | ||||
|       element, | ||||
|       (v, _ov, cleanUp) => { | ||||
|         if (v) { | ||||
|           !unref(isAddRef) && addEventListener(v); | ||||
|           cleanUp(() => { | ||||
|             autoRemove && removeEventListener(v); | ||||
|           }); | ||||
|         } | ||||
|       }, | ||||
|       { immediate: true } | ||||
|     ); | ||||
| 
 | ||||
|     remove = () => { | ||||
|       removeEventListener(element.value); | ||||
|       removeWatch(); | ||||
|     }; | ||||
|   } | ||||
|   return { removeEvent: remove }; | ||||
| } | ||||
							
								
								
									
										44
									
								
								sub-government-affairs-service/src/hooks/useTimeout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								sub-government-affairs-service/src/hooks/useTimeout.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| import { ref, watch } from 'vue'; | ||||
| import { tryOnUnmounted } from '@vueuse/core'; | ||||
| 
 | ||||
| export function useTimeoutFn(handle, wait, native = false) { | ||||
|   if (typeof handle !== 'function') { | ||||
|     throw new Error('handle is not Function!'); | ||||
|   } | ||||
| 
 | ||||
|   const { readyRef, stop, start } = useTimeoutRef(wait); | ||||
|   if (native) { | ||||
|     handle(); | ||||
|   } else { | ||||
|     watch( | ||||
|       readyRef, | ||||
|       (maturity) => { | ||||
|         maturity && handle(); | ||||
|       }, | ||||
|       { immediate: false } | ||||
|     ); | ||||
|   } | ||||
|   return { readyRef, stop, start }; | ||||
| } | ||||
| 
 | ||||
| export function useTimeoutRef(wait) { | ||||
|   const readyRef = ref(false); | ||||
| 
 | ||||
|   let timer; | ||||
|   function stop() { | ||||
|     readyRef.value = false; | ||||
|     timer && window.clearTimeout(timer); | ||||
|   } | ||||
|   function start() { | ||||
|     stop(); | ||||
|     timer = setTimeout(() => { | ||||
|       readyRef.value = true; | ||||
|     }, wait); | ||||
|   } | ||||
| 
 | ||||
|   start(); | ||||
| 
 | ||||
|   tryOnUnmounted(stop); | ||||
| 
 | ||||
|   return { readyRef, stop, start }; | ||||
| } | ||||
| @ -247,7 +247,6 @@ | ||||
|   justify-content: space-between; | ||||
|   gap: 10px; | ||||
|   padding: 3px 0; | ||||
|    | ||||
| } | ||||
| .el-icon-custom { | ||||
|   vertical-align: middle; | ||||
| @ -373,3 +372,16 @@ | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .statistics-cont { | ||||
|   padding: 10px 20px; | ||||
|   .statistics-echart-box { | ||||
|     height: 400px; | ||||
|     padding-bottom: 50px; | ||||
|     box-sizing: content-box; | ||||
|     background-color: #fff; | ||||
|   } | ||||
|   .statistics-echart-title { | ||||
|     font-size: 18px; | ||||
|     font-weight: bold; | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										66
									
								
								sub-government-affairs-service/src/utils/echarts.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								sub-government-affairs-service/src/utils/echarts.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | ||||
| import * as echarts from 'echarts/core'; | ||||
| 
 | ||||
| import { | ||||
|   BarChart, | ||||
|   LineChart, | ||||
|   PieChart, | ||||
|   MapChart, | ||||
|   PictorialBarChart, | ||||
|   RadarChart, | ||||
|   GraphChart, | ||||
|   GaugeChart, | ||||
|   ScatterChart, | ||||
|   EffectScatterChart, | ||||
| } from 'echarts/charts'; | ||||
| import 'echarts-gl'; | ||||
| import 'echarts-liquidfill'; | ||||
| import 'echarts-wordcloud'; | ||||
| 
 | ||||
| import { | ||||
|   TitleComponent, | ||||
|   TooltipComponent, | ||||
|   GridComponent, | ||||
|   PolarComponent, | ||||
|   AriaComponent, | ||||
|   ParallelComponent, | ||||
|   LegendComponent, | ||||
|   RadarComponent, | ||||
|   ToolboxComponent, | ||||
|   DataZoomComponent, | ||||
|   VisualMapComponent, | ||||
|   TimelineComponent, | ||||
|   CalendarComponent, | ||||
|   GraphicComponent, | ||||
| } from 'echarts/components'; | ||||
| 
 | ||||
| import { CanvasRenderer } from 'echarts/renderers'; | ||||
| 
 | ||||
| echarts.use([ | ||||
|   LegendComponent, | ||||
|   TitleComponent, | ||||
|   TooltipComponent, | ||||
|   GridComponent, | ||||
|   PolarComponent, | ||||
|   AriaComponent, | ||||
|   ParallelComponent, | ||||
|   BarChart, | ||||
|   LineChart, | ||||
|   PieChart, | ||||
|   MapChart, | ||||
|   RadarChart, | ||||
|   CanvasRenderer, | ||||
|   PictorialBarChart, | ||||
|   RadarComponent, | ||||
|   ToolboxComponent, | ||||
|   DataZoomComponent, | ||||
|   VisualMapComponent, | ||||
|   TimelineComponent, | ||||
|   CalendarComponent, | ||||
|   GraphicComponent, | ||||
|   GraphChart, | ||||
|   GaugeChart, | ||||
|   ScatterChart, | ||||
|   EffectScatterChart, | ||||
| ]); | ||||
| 
 | ||||
| export default echarts; | ||||
| @ -14,3 +14,67 @@ import { getAssetsFile } from '@/utils'; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
| </style> | ||||
| 
 | ||||
| <!-- <template> | ||||
|   <div class="app-container"> | ||||
|     <div class="container-custom"> | ||||
|       <h2 class="custom-h2">产出品概览</h2> | ||||
|       <div ref="searchBarRef" class="search-box"> | ||||
|         <div class="search-bar"> | ||||
|           <div class="search-bar-left"> | ||||
|             <el-form ref="searchForm" :inline="true" :model="formInline" class="demo-form-inline" :label-width="'auto'"> | ||||
|               <el-form-item label="" style="margin-left: -15px"> | ||||
|                 <AreaCascader v-model:region-code="formInline.regionCode" v-model:grid-id="formInline.gridId" label="行政区域-网格" :width="500" /> | ||||
|               </el-form-item> | ||||
|               <el-form-item label=""> | ||||
|                 <el-button type="primary" icon="Search" @click="onSubmit">查询</el-button> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="statistics-cont"> | ||||
|         <el-row :gutter="20"> | ||||
|           <el-col :span="12" class="statistics-echart-box"> | ||||
|             <p class="statistics-echart-title">产出品产量数据</p> | ||||
|             <customEchartPie ref="pie1" :chart-data="chartData1" :option="option" :width="'100%'" :height="'100%'"></customEchartPie> | ||||
|           </el-col> | ||||
|         </el-row> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup> | ||||
| import { ref, reactive, computed, onMounted } from 'vue'; | ||||
| import customEchartPie from '@/components/custom-echart-pie'; | ||||
| import { ElMessage } from 'element-plus'; | ||||
| 
 | ||||
| // 查询条件 | ||||
| const formInline = reactive({ | ||||
|   regionCode: '', | ||||
|   regionName: '', | ||||
|   gridId: '', | ||||
|   gridName: '', | ||||
| }); | ||||
| const searchForm = ref(null); | ||||
| 
 | ||||
| const chartData1 = ref([ | ||||
|   { value: 1048, name: '蔬菜类' }, | ||||
|   { value: 735, name: '水果类' }, | ||||
|   { value: 484, name: '药材类' }, | ||||
| ]); | ||||
| const option = reactive({ | ||||
|   tooltip: { | ||||
|     formatter: '{b} ({c} 吨)', | ||||
|   }, | ||||
| }); | ||||
| const onSubmit = () => { | ||||
|   console.log(formInline); | ||||
| }; | ||||
| 
 | ||||
| onMounted(() => { | ||||
|   // onSubmit(); | ||||
| }); | ||||
| </script> | ||||
| <style lang="scss" scoped></style> --> | ||||
|  | ||||
| @ -137,7 +137,7 @@ | ||||
|           </el-descriptions-item> | ||||
|         </el-descriptions> | ||||
|         <el-descriptions title="区块链认证信息" border class="mb-20 custom-descriptions" :column="1"> | ||||
|           <el-descriptions-item label="质检报告"> | ||||
|           <el-descriptions-item label="认证信息"> | ||||
|             <img :src="dialogForm?.traceUrl ?? ''" alt="" /> | ||||
|           </el-descriptions-item> | ||||
|         </el-descriptions> | ||||
| @ -274,7 +274,7 @@ const seedTypeChange = () => { | ||||
|   // 重新获取表格数据,需添加参数 | ||||
| }; | ||||
| 
 | ||||
| const tabsRadio = ref(2); | ||||
| const tabsRadio = ref(1); | ||||
| const dialogFormVisible = ref(false); | ||||
| const dialogRef = ref(null); | ||||
| const dialogTitle = ref('溯源产品详情'); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user