生产经营主体和农产品溯源调整(未完)

This commit is contained in:
2090205686@qq.com 2025-05-16 17:43:53 +08:00
parent 313705c4c0
commit 1986442641
21 changed files with 20778 additions and 14137 deletions

BIN
main/.yarn/install-state.gz Normal file

Binary file not shown.

1
main/.yarnrc.yml Normal file
View File

@ -0,0 +1 @@
nodeLinker: node-modules

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

View File

@ -29,6 +29,10 @@ export default {
type: String, type: String,
default: 'calc(100vh - 78px)', default: 'calc(100vh - 78px)',
}, },
activeIndex: {
type: Number,
default: 1,
},
}, },
emits: ['click'], emits: ['click'],
setup(props, { emit }) { setup(props, { emit }) {
@ -56,13 +60,16 @@ export default {
zlevel: 1, zlevel: 1,
name: '漏斗图', name: '漏斗图',
type: 'funnel', type: 'funnel',
animation: true, //
animationDuration: 500, //
animationEasing: 'cubicOut', //
top: '11%', top: '11%',
left: 'center', left: 'center',
width: '25%', width: '25%',
sort: 'ascending', sort: 'ascending',
gap: 0, gap: 0,
label: { label: {
show: true, show: false,
position: 'outside', position: 'outside',
width: '200px', width: '200px',
align: 'right', align: 'right',
@ -79,9 +86,8 @@ export default {
padding: [5, 6], // padding: [5, 6], //
}, },
labelLine: { labelLine: {
show: true, show: false,
length: 10, length: 30,
length2: 50,
smooth: true, smooth: true,
lineStyle: { lineStyle: {
width: 1, width: 1,
@ -90,28 +96,6 @@ export default {
type: 'solid', type: 'solid',
}, },
}, },
// 线
// markLine: {
// symbol: 'none', //
// lineStyle: {
// type: 'solid',
// color: '#fff',
// width: 1,
// },
// data: [
// // labelLine
// [
// {
// coord: [50, 50], // 线
// name: 'Label1',
// },
// {
// coord: [80, 50], // 线
// name: 'Label1',
// },
// ],
// ],
// },
itemStyle: { itemStyle: {
show: false, show: false,
borderColor: '#fff', borderColor: '#fff',
@ -141,12 +125,50 @@ export default {
} }
); );
watch(
() => props.activeIndex,
(newVal) => {
showLabel(newVal);
}
);
function initCharts() { function initCharts() {
if (props.option) { if (props.option) {
Object.assign(option, cloneDeep(props.option)); Object.assign(option, cloneDeep(props.option));
} }
option.series[0].data = props.chartData; option.series[0].data = props.chartData;
setOptions(option); setOptions(option);
showLabel(props.activeIndex);
}
// labeloption
function getOption(activeIndex) {
//
let myData = props.chartData.map((item, idx) => ({
...item,
label: {
show: idx === activeIndex, //
},
labelLine: {
show: idx === activeIndex, // 线
},
}));
let myOption = {
...option,
series: [
{
...option.series[0],
data: myData,
},
],
};
return myOption;
}
//
function showLabel(activeIndex) {
const newOption = getOption(activeIndex);
setOptions(newOption);
} }
function onClick(params) { function onClick(params) {

View File

@ -176,7 +176,7 @@ function handleTitleClick(val) {
position: relative; position: relative;
width: 31%; width: 31%;
height: 100%; height: 100%;
overflow: hidden; // overflow: hidden;
line-height: 90px; line-height: 90px;
.title_content { .title_content {
position: absolute; position: absolute;

View File

@ -50,7 +50,7 @@ export default {
meta: { title: '生产经营主体', icon: '' }, meta: { title: '生产经营主体', icon: '' },
}, },
{ {
path: '/new-digital-agriculture-screen/trace', path: '/new-digital-agriculture-screen/v2/trace',
name: 'trace', name: 'trace',
component: () => import('@/views/trace/index.vue'), component: () => import('@/views/trace/index.vue'),
meta: { title: '农产品溯源', icon: '' }, meta: { title: '农产品溯源', icon: '' },

View File

@ -11,6 +11,7 @@ import {
GaugeChart, GaugeChart,
ScatterChart, ScatterChart,
EffectScatterChart, EffectScatterChart,
FunnelChart,
} from 'echarts/charts'; } from 'echarts/charts';
import 'echarts-gl'; import 'echarts-gl';
import 'echarts-liquidfill'; import 'echarts-liquidfill';
@ -70,6 +71,7 @@ echarts.use([
MarkPointComponent, MarkPointComponent,
MarkLineComponent, MarkLineComponent,
MarkAreaComponent, MarkAreaComponent,
FunnelChart,
]); ]);
export default echarts; export default echarts;

View File

@ -20,10 +20,10 @@ const state = reactive({
option: { option: {
// //
dataset: [], dataset: [],
type: 'column', type: 'row',
rowNum: 6, rowNum: 6,
isAnimation: true, isAnimation: true,
waitTime: 5, waitTime: 12,
unit: '万元', unit: '万元',
sort: true, sort: true,
height: 12, height: 12,
@ -32,9 +32,9 @@ const state = reactive({
borderRadius: '12px', borderRadius: '12px',
carousel: 'single', carousel: 'single',
indexPrefix: 'TOP', indexPrefix: 'TOP',
indexFontSize: 12, indexFontSize: 22,
leftFontSize: 14, leftFontSize: 16,
rightFontSize: 14, rightFontSize: 16,
valueFormatter: (item) => { valueFormatter: (item) => {
return item.value; return item.value;
}, },

View File

@ -44,7 +44,28 @@ const state = reactive({
radius: '80%', radius: '80%',
center: ['50%', '50%'], center: ['50%', '50%'],
backgroundStyle: { backgroundStyle: {
color: 'transparent', color: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [
{
offset: 0,
color: 'rgba(220, 255, 255, 0.3)', //
},
{
offset: 0.7,
color: 'rgba(0, 231, 240, 0.2)', //
},
{
offset: 1,
color: 'rgba(0, 150, 200, 0.3)', //
},
],
globalCoord: false,
},
blur: 10, //
}, },
data: [], data: [],
amplitude: 12, // amplitude: 12, //
@ -57,6 +78,7 @@ const state = reactive({
}, },
}, },
outline: { outline: {
//
borderDistance: 2, borderDistance: 2,
itemStyle: { itemStyle: {
borderWidth: 2, borderWidth: 2,
@ -85,6 +107,8 @@ const state = reactive({
}, },
}, },
itemStyle: { itemStyle: {
opacity: 1, //
//
color: { color: {
type: 'linear', // 线 type: 'linear', // 线
x: 0, x: 0,
@ -92,8 +116,9 @@ const state = reactive({
x2: 0, x2: 0,
y2: 1, y2: 1,
colorStops: [ colorStops: [
{ offset: 0, color: 'rgba(13, 204, 163, 0.6)' }, { offset: 0, color: '#6af7e8' }, //
{ offset: 1, color: 'rgba(71, 202, 219, 1)' }, // { offset: 0.7, color: '#5fcbc1' },
{ offset: 1, color: '#55e7ff' },
], ],
global: false, // false global: false, // false
}, },
@ -107,8 +132,9 @@ watch(
() => props.data, () => props.data,
(val) => { (val) => {
if (!isEmpty(val)) { if (!isEmpty(val)) {
state.option.series[0].data = [0, val.percent]; //
state.option.series[0].label.formatter = val.percent * 100 + '%'; state.option.series[0].data = [val.percent + 0.05, val.percent]; //
state.option.series[0].label.formatter = val.percent * 100 + '%'; //
} }
}, },
{ {

View File

@ -193,20 +193,19 @@ function getPie3D(pieData, internalDiameterRatio) {
}, },
title: { title: {
text: '', text: '',
x: '35%', x: '34%', //
y: '30%', y: '32%',
itemGap: 4,
textAlign: 'center',
textStyle: { textStyle: {
rich: { color: '#ffffff',
a: { fontSize: '26px',
fontSize: 20, fontWeight: 'bold',
color: '#fff', },
}, subtext: '',
c: { subtextStyle: {
fontSize: 12, color: '#02FD94',
color: '#fff', fontSize: '18px',
padding: [15, 0],
},
},
}, },
}, },
xAxis3D: { xAxis3D: {
@ -224,14 +223,14 @@ function getPie3D(pieData, internalDiameterRatio) {
grid3D: { grid3D: {
show: false, show: false,
boxHeight: boxHeight, boxHeight: boxHeight,
left: '-10%', left: '-15%',
top: -20, top: -20,
viewControl: { viewControl: {
alpha: 55, //( ) alpha: 40, //( )
distance: 150, //zoom() distance: 150, //zoom()
rotateSensitivity: 1, //0 rotateSensitivity: 1, //0
zoomSensitivity: 0, //0 zoomSensitivity: 10, //0
panSensitivity: 0, //0 panSensitivity: 10, //0
autoRotate: true, // autoRotate: true, //
}, },
}, },
@ -243,7 +242,8 @@ function getPie3D(pieData, internalDiameterRatio) {
const initData = (pieData = []) => { const initData = (pieData = []) => {
const option = getPie3D(pieData, 0.8); const option = getPie3D(pieData, 0.8);
const { name, value } = option.series[0].pieData; const { name, value } = option.series[0].pieData;
option.title.text = `{a|${value}%}{c|\n${name}}`; option.title.text = value + '%'; //
option.title.subtext = name; //
state.option = option; state.option = option;
state.data = option.series; state.data = option.series;
}; };

View File

@ -15,7 +15,7 @@
:down-title="'农资企业'" :down-title="'农资企业'"
:label-field="'label'" :label-field="'label'"
:value-field="'value'" :value-field="'value'"
:down-width="'130px'" :down-width="''"
:options="[ :options="[
{ value: 1, label: '农企/合作社' }, { value: 1, label: '农企/合作社' },
{ value: 2, label: '农资企业' }, { value: 2, label: '农资企业' },

View File

@ -5,7 +5,7 @@
<span class="right_btn" @click="handleChange(1)"></span> <span class="right_btn" @click="handleChange(1)"></span>
{{ current.info.name }} {{ current.info.name }}
</section> </section>
<custom-echart-triangle :chart-data="data" height="100%" :option="option" /> <custom-echart-triangle :chart-data="data" height="100%" :option="option" :active-index="current.info.level - 1" />
</div> </div>
</template> </template>
<script setup> <script setup>
@ -23,14 +23,17 @@ const list = ref([
{ {
name: '茶叶', name: '茶叶',
value: '1', value: '1',
level: 1,
}, },
{ {
name: '核桃', name: '核桃',
value: '2', value: '2',
level: 2,
}, },
{ {
name: '玉米', name: '玉米',
value: '3', value: '3',
level: 3,
}, },
]); ]);
const current = reactive({ const current = reactive({
@ -38,7 +41,8 @@ const current = reactive({
length: list.value.length - 1, length: list.value.length - 1,
info: { info: {
name: '茶叶', name: '茶叶',
value: '20', value: '1',
level: 1,
}, },
}); });
function handleChange(n) { function handleChange(n) {

View File

@ -1,32 +1,71 @@
<template> <template>
<custom-echart-bar :chart-data="state.data" height="100%" :option="state.option" /> <custom-echart-bar :chart-data="dataList" height="100%" :option="state.option" />
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import { onMounted, reactive } from 'vue';
const dataList = reactive([
{
name: '其他',
value: 3500,
},
{
name: '烟叶',
value: 4000,
},
{
name: '甘蔗',
value: 6000,
},
{
name: '核桃',
value: 8000,
},
{
name: '茶叶',
value: 12000,
},
]);
let titles = reactive([]);
let values = reactive([]);
const max = Math.max(...dataList);
const maxData = dataList.map((item, index) => {
return {
value: [max, index],
name: titles[index],
};
});
const barData = dataList.map((item, index) => {
return {
value: [item, index],
name: titles[index],
};
});
const getValue = () => {
let arr = [];
for (let i = 0; i < dataList.length; i++) {
arr.push(dataList[i].value);
}
return arr;
};
const getName = () => {
let arr = [];
for (let i = 0; i < dataList.length; i++) {
arr.push(dataList[i].name);
}
return arr;
};
onMounted(() => {
titles = getName();
values = getValue();
console.log(titles);
console.log(values);
});
const state = reactive({ const state = reactive({
data: [
{
name: '其他',
value: 3500,
},
{
name: '烟叶',
value: 4000,
},
{
name: '甘蔗',
value: 6000,
},
{
name: '核桃',
value: 8000,
},
{
name: '茶叶',
value: 12000,
},
],
option: { option: {
grid: { grid: {
left: '5%', left: '5%',
@ -36,11 +75,13 @@ const state = reactive({
containLabel: true, containLabel: true,
}, },
tooltip: { tooltip: {
show: false,
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
type: 'shadow', type: 'shadow',
}, },
backgroundColor: 'rgba(18, 55, 85, 0.8);', className: 'custom-tooltip-container', //
backgroundColor: 'rgba(0,0,0,0.5)',
borderColor: '#35d0c0', borderColor: '#35d0c0',
formatter: (data) => { formatter: (data) => {
const params = data[0]; const params = data[0];
@ -53,19 +94,20 @@ const state = reactive({
}, },
barStyle: { barStyle: {
barWidth: 14, barWidth: 14,
showBackground: true,
itemStyle: { itemStyle: {
borderWidth: 14, borderWidth: 14,
borderRadius: [8, 8, 8, 8], // borderRadius: [10, 10, 10, 10], //
}, },
color: { color: {
type: 'linear', type: 'linear',
x: 0, x: 0,
y: 0, y: 0,
x2: 0, x2: 1,
y2: 1, y2: 0,
colorStops: [ colorStops: [
{ offset: 0, color: '#35D0C0' }, { offset: 0, color: 'rgba(1,254,253,0)' },
{ offset: 1, color: '#35D0C0' }, { offset: 1, color: '#01fefd' },
], ],
global: false, global: false,
}, },
@ -76,13 +118,13 @@ const state = reactive({
show: false, show: false,
lineStyle: { lineStyle: {
type: 'dashed', type: 'dashed',
color: '#E5E5E5', color: '#eee',
}, },
}, },
axisLabel: { axisLabel: {
show: false, show: false,
textStyle: { textStyle: {
color: '#424242', color: '#ffffff',
}, },
}, },
show: false, show: false,
@ -93,28 +135,144 @@ const state = reactive({
show: false, show: false,
}, },
}, },
yAxis: { yAxis: [
type: 'category', {
data: ['茶叶', '核桃', '甘蔗', '烟叶', '其他'], // title
axisLabel: { type: 'category',
color: '#fff', data: ['茶叶', '核桃', '甘蔗', '烟叶', '其他'],
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '16',
},
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLine: {
show: false,
},
}, },
axisTick: { {
show: false, //
type: 'category',
inverse: true,
offset: 10,
axisTick: 'none',
axisLine: 'none',
show: true,
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '16',
},
formatter: function (value) {
let str = '{title|' + value + '吨}';
return str;
},
rich: {
title: {
color: '#fff',
fontSize: 16,
},
},
},
data: [12000, 8000, 6000, 4000, 3500],
}, },
splitLine: { ],
show: false,
},
axisLine: {
show: false,
},
},
series: [ series: [
{ {
name: '值',
type: 'bar', type: 'bar',
// barWidth: '40%', // zlevel: 1,
// barMinHeight: 2, // barBorderRadius: 10,
// barGap: '20%', // itemStyle: {
borderRadius: [10, 10, 10, 10],
color: 'rgba(100, 200, 255, 0.3)',
},
backgroundStyle: {
color: 'rgba(100, 200, 255, 0.3)',
borderRadius: [10, 10, 10, 10], // barBorderRadius
},
barWidth: 20,
data: values,
label: {
position: [0, -16],
align: 'left',
show: true,
formatter: (params) => {
return params.name;
},
},
barMaxWidth: 40,
markLine: {
label: {
color: '#26a69a',
},
},
},
{
name: '背景',
type: 'bar',
barWidth: 20,
barGap: '-100%',
data: maxData,
barBorderRadius: 30,
itemStyle: {
normal: {
color: 'rgba(105,131,242,.3)',
borderRadius: 10,
},
},
label: {
show: false,
},
barMaxWidth: 40,
markLine: {
label: {
color: '#26a69a',
},
},
},
{
name: '内圆',
type: 'scatter',
hoverAnimation: false,
data: barData,
yAxisIndex: 0,
symbolSize: 22,
itemStyle: {
normal: {
color: '#26a69a',
opacity: 1,
},
},
zlevel: 2,
label: {
show: false,
},
},
{
name: '外圆',
type: 'scatter',
hoverAnimation: false,
data: barData,
yAxisIndex: 0,
symbolSize: 28,
symbol: `path://M512 960C264.576 960 64 759.424 64 512S264.576 64 512 64s448 200.576 448 448-200.576 448-448 448z m0-268.8a179.2 179.2 0 1 0 0-358.4 179.2 179.2 0 0 0 0 358.4z`,
itemStyle: {
color: 'rgb(255, 255, 255)',
opacity: 1,
borderColor: 'rgba(44, 111, 226, 0.2)',
borderWidth: 2,
},
zlevel: 3,
label: {
show: false,
},
}, },
], ],
}, },

View File

@ -20,7 +20,7 @@
</div> </div>
</div> </div>
<section class="line_info" :style="{ '--top': info.show ? '18vh' : '140vh' }"> <section class="line_info" :style="{ '--top': info.show ? '18vh' : '140vh' }">
<i class="el-icon-close" @click="handleCloseInfo">X</i> <i class="el-icon-close" @click="handleCloseInfo"></i>
<section> <section>
<section class="info_box"> <section class="info_box">
<div> <div>
@ -59,8 +59,8 @@
<div class="_time">{{ item.time }}</div> <div class="_time">{{ item.time }}</div>
</div> </div>
<div style="text-align: center"> <div style="text-align: center">
<img src="../../../assets/1.png" style="width: 30%" /> <img src="../../../assets/images/trace/testReport.png" style="width: 30%" />
<div>测报告</div> <div>测报告</div>
</div> </div>
</section> </section>
</section> </section>
@ -104,7 +104,7 @@ function handleCloseInfo() {
display: grid; display: grid;
grid-template-columns: 25% 40% 18% 17%; grid-template-columns: 25% 40% 18% 17%;
background-color: rgba(53, 208, 192, 0.3); background-color: rgba(53, 208, 192, 0.3);
color: #c5d0d4; color: #ffffff;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
border-radius: 4px; border-radius: 4px;
@ -149,10 +149,10 @@ function handleCloseInfo() {
} }
.line_info { .line_info {
position: fixed; position: fixed;
padding: 32px 10px 20px 20px; padding: 24px 10px 16px 16px;
left: 30%; right: 30%;
top: var(--top); top: var(--top);
max-height: 74vh; max-height: 85vh;
width: 400px; width: 400px;
color: #fff; color: #fff;
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(0, 0, 0, 0.2);
@ -167,14 +167,18 @@ function handleCloseInfo() {
} }
.el-icon-close { .el-icon-close {
position: absolute; position: absolute;
right: 8px; right: -40px;
top: 8px; top: 0px;
cursor: pointer; cursor: pointer;
font-size: 16px; font-size: 16px;
width: 30px;
height: 30px;
background-image: url(../../../assets/images/trace/delete.png);
background-size: contain;
} }
> section { > section {
padding-right: 10px; padding-right: 10px;
max-height: calc(74vh - 100px); max-height: calc(85vh - 100px);
overflow-y: auto; overflow-y: auto;
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 6px; width: 6px;

View File

@ -51,7 +51,7 @@ onMounted(() => {});
} }
._value { ._value {
> span { > span {
font-size: 24px; font-size: 20px;
} }
} }
img { img {

View File

@ -36,7 +36,7 @@ const option = reactive({
autoItemHeight: 2, autoItemHeight: 2,
grid3D: { grid3D: {
show: false, show: false,
boxHeight: 5, boxHeight: 3,
top: '0', top: '0',
left: '-20%', left: '-20%',
viewControl: { viewControl: {

View File

@ -51,7 +51,7 @@ import { ref } from 'vue';
._left { ._left {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: flex-start;
align-items: center; align-items: center;
color: #fff; color: #fff;
font-size: 18px; font-size: 18px;

View File

@ -23,7 +23,7 @@
:down-title="'1号仓库'" :down-title="'1号仓库'"
:label-field="'label'" :label-field="'label'"
:value-field="'value'" :value-field="'value'"
:down-width="'100px'" :down-width="''"
:options="[ :options="[
{ label: '1号仓库', value: '530926' }, { label: '1号仓库', value: '530926' },
{ label: '2号仓库', value: '42611' }, { label: '2号仓库', value: '42611' },

File diff suppressed because it is too large Load Diff