This commit is contained in:
weipengfei 2024-03-06 17:45:05 +08:00
parent 67be65ccde
commit 8bb3f21f7f
8 changed files with 280 additions and 241 deletions

View File

@ -1 +1,2 @@
VITE_BASE_URL = 'https://ceshi-suyuan-breed.lihaink.cn'
# VITE_BASE_URL = 'https://ceshi-suyuan-breed.lihaink.cn'
VITE_BASE_URL = 'https://suyuan-breed.lihaink.cn'

BIN
dist.zip

Binary file not shown.

View File

@ -29,9 +29,10 @@ export const useAppStore = defineStore('app', () => {
area.value = data;
}
const street = ref([]);
const street = ref(JSON.parse(localStorage.getItem('streetList')||'[]'));
const setStreet = (data) => {
street.value = data;
localStorage.setItem('streetList', JSON.stringify(street.value));
}
return {

View File

@ -21,8 +21,9 @@ const initDeviceCount = ()=>{
id: route.query.id || undefined
}).then(res=>{
Object.keys(leftInfo.value).forEach(key=>{
if(res.data[key]) leftInfo.value[key] = res.data[key];
if(res.data[key]) leftInfo.value[key] = +res.data[key];
})
leftInfo.value.alarmCount = Math.floor(leftInfo.value.alarmCount/100);
})
}

View File

@ -1,7 +1,7 @@
<script setup>
import { ref, reactive, onMounted } from "vue"
import { getFarmInfo } from "@/api/api.js"
import * as echarts from "echarts"
import { ref, reactive, onMounted } from "vue";
import { getFarmInfo, getfarmCount } from "@/api/api.js";
import * as echarts from "echarts";
import videoFlv from "@/components/videoFlv.vue";
import { useAppStore } from "@/store/app.js";
import { useRoute } from "vue-router";
@ -10,9 +10,9 @@ const appStore = useAppStore();
const route = useRoute();
const circleRef = ref(null);
const initCircle = () => {
const initCircle = async () => {
const echart = echarts.init(circleRef.value);
let color = ['#00A8FF', '#4B5FDB', '#00FFCB', '#5BDBF6'];
let color = ["#00A8FF", "#4B5FDB", "#00FFCB", "#5BDBF6"];
// let data = [
// { value: 400, name: '' },
@ -20,29 +20,34 @@ const initCircle = () => {
// { value: 580, name: '' },
// { value: 884, name: '' },
// ]
let data = breedTypeRows.value.map(item=>{
let data = breedTypeRows.value.map((item) => {
let value = farmList.value.reduce((count, t) => {
return item.value == t.breed_type ? count + t.animal_count : count + 0;
}, 0);
return {
name: item.name,
value: item.animalCount
}
value: value,
};
});
let option = {
tooltip: {
trigger: "item",
backgroundColor: 'rgba(0, 156, 255, 0.6)', //
backgroundColor: "rgba(0, 156, 255, 0.6)", //
textStyle: {
color: '#fff'
color: "#fff",
},
borderColor: "rgba(0, 156, 255, 1)",
axisPointer: {
type: 'shadow',
type: "shadow",
shadowStyle: {
color: 'rgba(255,255,255, .2)',
}
color: "rgba(255,255,255, .2)",
},
},
formatter: function (params) {
return params.data.name + ': ' + params.data.value;
}
return params.data.name + ": " + params.data.value;
},
},
color: color,
legend: {
@ -52,57 +57,57 @@ const initCircle = () => {
itemHeight: 8,
bottom: "5%",
textStyle: {
color: "#fff"
color: "#fff",
},
formatter: function (params) {
return '种类: ' + params;
}
return "种类: " + params;
},
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '40%'], //
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "40%"], //
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
position: "center",
},
emphasis: {
label: {
show: false,
fontSize: 10,
}
},
},
labelLine: {
show: false
show: false,
},
data: data
}
]
data: data,
},
],
};
echart.setOption(option)
}
echart.setOption(option);
};
const chartRef = ref(null)
const chartRef = ref(null);
const initMap = () => {
const echart = echarts.init(chartRef.value);
const basicColors = [
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB'],
['#00A8FF', '#2A7FEB']
]
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
["#00A8FF", "#2A7FEB"],
];
//
function genLinearGradient (colors) {
function genLinearGradient(colors) {
const color = {
type: 'linear',
type: "linear",
x: 0,
y: 0,
x2: 1,
@ -110,159 +115,166 @@ const initMap = () => {
colorStops: [
{
offset: 0,
color: colors[0] // 0%
color: colors[0], // 0%
},
{
offset: 1,
color: colors[1] // 100%
}
color: colors[1], // 100%
},
],
global: false
}
return color
global: false,
};
return color;
}
let dataText = [];
let dataValue = [];
breedTypeRows.value.forEach(item=>{
breedTypeRows.value.forEach((item) => {
let value = farmList.value.reduce((count, t) => {
return item.value == t.breed_type ? count + t.animal_count : count + 0;
}, 0);
dataText.push(item.name);
dataValue.push(item.animalCount);
})
dataValue.push(value);
});
let option = {
grid: {
left: '12%',
top: '5%',
bottom: '12%',
right: '0%'
left: "12%",
top: "5%",
bottom: "12%",
right: "0%",
},
tooltip: {
trigger: "axis",
backgroundColor: 'rgba(0, 156, 255, 0.6)', //
backgroundColor: "rgba(0, 156, 255, 0.6)", //
textStyle: {
color: '#fff'
color: "#fff",
},
borderColor: "rgba(0, 156, 255, 1)",
axisPointer: {
type: 'shadow',
type: "shadow",
shadowStyle: {
color: 'rgba(255,255,255, .2)',
}
color: "rgba(255,255,255, .2)",
},
},
formatter: function (params) {
let str = "";
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName !== "") {
str +=
params[i].name +
': ' +
params[i].value +
"<br/>";
str += params[i].name + ": " + params[i].value + "<br/>";
}
}
return str;
}
},
},
xAxis: {
data: dataText,
axisTick: {
show: false
show: false,
},
axisLine: {
lineStyle: {
color: 'rgba(255,255,255,0.3)',
width: 1 //
}
color: "rgba(255,255,255,0.3)",
width: 1, //
},
},
axisLabel: {
textStyle: {
color: '#fff',
fontSize: 12
}
}
color: "#fff",
fontSize: 12,
},
yAxis: [{
},
},
yAxis: [
{
splitNumber: 2,
axisTick: {
show: false
show: false,
},
axisLine: {
lineStyle: {
color: 'rgba(255,255,255,0.3)',
width: 1 //
}
color: "rgba(255,255,255,0.3)",
width: 1, //
},
},
axisLabel: {
textStyle: {
color: '#fff'
}
color: "#fff",
},
},
splitArea: {
areaStyle: {
color: 'rgba(255,255,255,.5)'
}
color: "rgba(255,255,255,.5)",
},
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255,255,255, 0.5)',
color: "rgba(255,255,255, 0.5)",
width: 0.5,
type: 'dashed'
}
}
}
type: "dashed",
},
},
},
],
series: [
{
name: 'hill',
type: 'pictorialBar',
barCategoryGap: '0%',
symbol: 'path://M0,10 L10,10 C5.5,8 5.5,5 5,0 C4.5,5 4.5,8 0,10 z',
name: "hill",
type: "pictorialBar",
barCategoryGap: "0%",
symbol: "path://M0,10 L10,10 C5.5,8 5.5,5 5,0 C4.5,5 4.5,8 0,10 z",
label: {
show: false,
position: 'top',
position: "top",
distance: 15,
color: '#FFF6B7',
color: "#FFF6B7",
fontSize: 16,
},
itemStyle: {
normal: {
color: function (params) {
return genLinearGradient(basicColors[params.dataIndex])
}
return genLinearGradient(basicColors[params.dataIndex]);
},
},
emphasis: {
opacity: 1
}
opacity: 1,
},
},
data: dataValue,
z: 10
}]
z: 10,
},
],
};
echart.setOption(option)
}
echart.setOption(option);
};
const farmInfo = ref({});
const farmList = ref([]);
const breedTypeRows = ref([]);
const getInfo = ()=>{
const getInfo = () => {
getFarmInfo({
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode || route.query.streetCode,
id: route.query.id || undefined
}).then(res=>{
id: route.query.id || undefined,
}).then(async (res) => {
farmInfo.value = res.data.farmInfo;
breedTypeRows.value = res.data.breedTypeRows;
let { data } = await getfarmCount({
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode,
});
farmList.value = data.farmList;
initCircle();
initMap();
})
}
});
};
onMounted(() => {
getInfo();
// initCircle();
// initMap();
})
});
</script>
<template>
@ -273,10 +285,7 @@ onMounted(() => {
<div class="bg"></div>
</div>
<div class="c-box">
<videoFlv
class="img"
url="http://rtsp.lihaink.cn/live/xumu_user1.live.mp4"
/>
<videoFlv class="img" :url="farmInfo.video_url" />
<div class="name">{{ farmInfo.farm_name }}</div>
</div>
</div>

View File

@ -20,8 +20,9 @@ const initDeviceCount = ()=>{
streetCode: appStore.address.streetCode
}).then(res=>{
Object.keys(leftInfo.value).forEach(key=>{
if(res.data[key]) leftInfo.value[key] = res.data[key];
if(res.data[key]) leftInfo.value[key] = +res.data[key];
})
leftInfo.value.alarmCount = Math.floor(leftInfo.value.alarmCount/100);
})
}

View File

@ -1,96 +1,91 @@
<script setup>
import { ref, reactive, onMounted, nextTick } from "vue"
import * as echarts from 'echarts';
import { ref, reactive, onMounted, nextTick } from "vue";
import * as echarts from "echarts";
import videoFlv from "@/components/videoFlv.vue";
import { getfarmCount, getBreedTypeCount } from "@/api/api.js";
import { useAppStore } from "@/store/app.js";
import { useDictStore } from "@/store/dict.js";
import QRCode from 'qrcode';
import QRCode from "qrcode";
const appStore = useAppStore();
const dictStore = useDictStore();
const farmInfo = ref({
farmCount: 0,
totalScale: 0
totalScale: 0,
});
const farmList = ref([{},{},{},{}]);
const initFarmCount = ()=>{
const farmList = ref([{}, {}, {}, {}]);
const initFarmCount = () => {
getfarmCount({
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode
}).then((res)=>{
streetCode: appStore.address.streetCode,
}).then((res) => {
farmInfo.value.farmCount = res.data.farmCount;
farmInfo.value.totalScale = res.data.totalScale;
farmList.value = res.data.farmList;
initData();
})
}
initBreedTypeCount();
});
};
const breedTypeRows = ref([]);
const animalList = ref([]);
const initBreedTypeCount = ()=>{
const initBreedTypeCount = () => {
getBreedTypeCount({
areaCode: appStore.address.areaCode,
streetCode: appStore.address.streetCode
}).then((res)=>{
streetCode: appStore.address.streetCode,
}).then((res) => {
breedTypeRows.value = res.data.breedTypeRows;
initMap();
let randomNumber = 0;
if(res.data.animalList.length>6) randomNumber = Math.floor(Math.random() * (res.data.animalList.length-6));
animalList.value = res.data.animalList.slice(randomNumber,randomNumber+6);
animalList.value.forEach(item=>{
QRCode.toDataURL('d_' + item.sn, {
margin: 1.5
// if(res.data.animalList.length>6) randomNumber = Math.floor(Math.random() * (res.data.animalList.length-6));
// animalList.value = res.data.animalList.slice(randomNumber,randomNumber+6);
animalList.value = res.data.animalList;
animalList.value.forEach((item) => {
QRCode.toDataURL("d_" + item.sn, {
margin: 1.5,
})
.then(url => {
.then((url) => {
item.qr_code_img = url;
}).catch(err => { //
console.error(err)
})
})
})
}
.catch((err) => {
//
console.error(err);
});
});
});
};
const initData = async (data) => {
let arr = [];
if(dictStore.breedTypeList.length==0) await nextTick();
if (dictStore.breedTypeList.length == 0) await nextTick();
for (let i = 0; i < farmList.value.length; i++) {
let type = dictStore.breedTypeList.find(item=>item.value==farmList.value[i].farm_type);
arr.push(
[
let type = dictStore.breedTypeList.find(
(item) => item.value == farmList.value[i].breed_type
);
arr.push([
`${i + 1}`,
`${farmList.value[i].farm_name}`,
`${type?.name||'-'}`,
`${farmList.value[i].animal_count||'-'}`,
]
)
`${type?.name || "-"}`,
`${farmList.value[i].animal_count || "-"}`,
]);
}
list.data = arr;
scrollBoardRef.value.updateRows(list.data);
}
};
const scrollBoardRef = ref(null);
const list = reactive({
header: [
`序号`,
`基地名称`,
`养殖种类`,
`养殖数量`,
],
header: [`序号`, `基地名称`, `养殖种类`, `养殖数量`],
data: [],
// index: true,
headerBGC: '#0d599c',
oddRowBGC: 'rgba(91, 219, 246, 0.10)',
evenRowBGC: '',
headerBGC: "#0d599c",
oddRowBGC: "rgba(91, 219, 246, 0.10)",
evenRowBGC: "",
columnWidth: [50],
align: 'center',
rowNum: 7
})
align: "center",
rowNum: 7,
});
const echarts1Ref = ref(null);
const echarts2Ref = ref(null);
@ -99,35 +94,38 @@ const initMap = () => {
const chart1 = echarts.init(echarts1Ref.value);
// const chart2 = echarts.init(echarts2Ref.value);
let color = ['#00A8FF', '#4B5FDB', '#00FFCB', '#5BDBF6'];
let data1 = breedTypeRows.value.map(item=>{
let color = ["#00A8FF", "#4B5FDB", "#00FFCB", "#5BDBF6"];
let data1 = breedTypeRows.value.map((item) => {
let value = farmList.value.reduce((count, t) => {
return item.value == t.breed_type ? count + t.animal_count : count + 0;
}, 0);
return {
name: item.name,
value: item.animalCount,
id: item.value
}
})
value: value,
id: item.value,
};
});
let option1 = {
tooltip: {
trigger: 'item',
trigger: "item",
},
color: color,
tooltip: {
trigger: "item",
backgroundColor: 'rgba(0, 156, 255, 0.6)', //
backgroundColor: "rgba(0, 156, 255, 0.6)", //
textStyle: {
color: '#fff'
color: "#fff",
},
borderColor: "rgba(0, 156, 255, 1)",
axisPointer: {
type: 'shadow',
type: "shadow",
shadowStyle: {
color: 'rgba(255,255,255, .2)',
}
color: "rgba(255,255,255, .2)",
},
},
formatter: function (params) {
return params.data.name + ': ' + params.data.value;
}
return params.data.name + ": " + params.data.value;
},
},
legend: {
show: true,
@ -141,49 +139,46 @@ const initMap = () => {
// bottom: "center",
textStyle: {
color: "#fff",
fontSize: "0.75rem"
fontSize: "0.75rem",
},
formatter: function (params) {
let total = data1.find(item=>item.name==params)?.value || 0;
return '种类: ' + params + ' --- ' + total + '只';
}
let total = data1.find((item) => item.name == params)?.value || 0;
return "种类: " + params + " --- " + total + "只";
},
},
series: [
{
name: '养殖数据',
type: 'pie',
radius: ['50%', '80%'],
center: ['20%', '50%'], //
name: "养殖数据",
type: "pie",
radius: ["50%", "80%"],
center: ["20%", "50%"], //
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
position: "center",
},
emphasis: {
label: {
show: false,
fontSize: 10,
}
},
},
labelLine: {
show: false
show: false,
},
data: data1
}
]
data: data1,
},
],
};
if(data1.length>0) chart1.setOption(option1);
}
if (data1.length > 0) chart1.setOption(option1);
};
const show = ref(false);
onMounted(() => {
initFarmCount();
initBreedTypeCount();
// initMap();
})
});
</script>
<template>
@ -201,8 +196,8 @@ onMounted(() => {
</div>
<div class="tab-item">
<img src="/src/assets/index_img/icon1.png" />
<div>养殖规模</div>
<div class="count">{{ farmInfo.totalScale }}</div>
<div>占地规模</div>
<div class="count">{{ farmInfo.totalScale }}</div>
</div>
</div>
<dv-scroll-board
@ -222,9 +217,12 @@ onMounted(() => {
<videoFlv
v-if="farmList[0]?.video_url"
style="width: 100%; height: 100%"
:url="farmList[0].video_url||''"
:url="farmList[0].video_url || ''"
/>
<div v-else style="width: 100%; height: 100%; background-color: #0c1122;"></div>
<div
v-else
style="width: 100%; height: 100%; background-color: #0c1122"
></div>
<div class="title">{{ farmList[0]?.farm_name || "" }}</div>
</div>
<div class="right">
@ -232,12 +230,17 @@ onMounted(() => {
<videoFlv
v-if="farmList[1]?.video_url"
style="width: 100%; height: 100%"
:url="farmList[1].video_url||''"
:url="farmList[1].video_url || ''"
/>
<div v-else style="width: 100%; height: 100%; background-color: #0c1122;"></div>
<div class="title">{{ farmList[1]?.farm_name || "" }}</div>
<div
v-else
style="width: 100%; height: 100%; background-color: #0c1122"
></div>
<div class="title">
{{ farmList[1]?.farm_name || "暂无更多监控" }}
</div>
<div class="item">
</div>
<!-- <div class="item">
<videoFlv
v-if="farmList[2]?.video_url"
style="width: 100%; height: 100%"
@ -254,10 +257,12 @@ onMounted(() => {
/>
<div v-else style="width: 100%; height: 100%; background-color: #0c1122;"></div>
<div class="title">{{ farmList[3]?.farm_name || "" }}</div>
</div>
</div> -->
<div class="item">
<!-- <img src="/src/assets/index_img/video.png" /> -->
<div style="width: 100%; height: 100%; background-color: #0c1122;"></div>
<div
style="width: 100%; height: 100%; background-color: #0c1122"
></div>
<div class="btn" @click="show = true">查看全部</div>
</div>
</div>
@ -272,6 +277,7 @@ onMounted(() => {
<div ref="echarts1Ref"></div>
</div>
<div class="qr">
<div class="qr-box">
<div class="qr_card" v-for="(item, index) in animalList" :key="index">
<div class="name">
<div>品类名称: {{ item.brand }}</div>
@ -281,6 +287,7 @@ onMounted(() => {
</div>
</div>
</div>
</div>
<transition name="fade" appear>
<div class="box4" v-show="show">
<div class="vedio">
@ -292,7 +299,7 @@ onMounted(() => {
<div class="item-vedio">
<videoFlv
style="width: 100%; height: 100%"
:url="item.video_url||''"
:url="item.video_url || ''"
/>
</div>
</div>
@ -386,13 +393,15 @@ onMounted(() => {
background-color: rgba($color: #000000, $alpha: 0.5);
}
.left {
width: calc(50% - 0.6rem);
/* width: calc(50% - 0.6rem); */
width: 72%;
height: 100%;
position: relative;
font-size: 0.8rem;
}
.right {
width: 50%;
/* width: 50%; */
width: 25%;
display: flex;
height: 100%;
flex-wrap: wrap;
@ -400,7 +409,8 @@ onMounted(() => {
font-size: 0.6rem;
.item {
position: relative;
width: calc(50% - 0.3rem);
/* width: calc(50% - 0.3rem); */
width: 100%;
height: calc(50% - 0.3rem);
.btn {
position: absolute;
@ -420,8 +430,11 @@ onMounted(() => {
}
&:nth-child(1) {
margin-right: 0.6rem;
margin-bottom: 0.6rem;
}
/* &:nth-child(1) {
margin-right: 0.6rem;
} */
&:nth-child(3) {
margin-right: 0.6rem;
margin-top: 0.6rem;
@ -450,8 +463,21 @@ onMounted(() => {
}
.qr {
height: 66%;
position: relative;
.qr-box {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow-y: scroll;
display: flex;
flex-wrap: wrap;
}
.qr-box::-webkit-scrollbar {
display: none; /* Webkit (Safari, Chrome) 支持,隐藏滚动条 */
}
.qr_card {
width: 50%;
height: 33%;

View File

@ -363,10 +363,12 @@ const mapInfo = async () => {
if (area.name == "合江县") map = hejiang_geo;
if (area.name == "古蔺县") map = gulin_geo;
map = JSON.parse(JSON.stringify(map));
if (appStore.address.streetCode) {
let street = appStore.street.find(
(item) => item.code == appStore.address.streetCode
);
console.error('##', appStore.street, appStore.address.streetCode);
initStreetMap(street, map);
// dataValue = dataValue.filter(
// (item) => item.street_code == appStore.address.streetCode
@ -394,9 +396,7 @@ const filterMap = () => {
const initFarmCount = () => {
mapInfo();
setTimeout(() => {
initMap();
}, 100);
};
onMounted(() => {