build: 1、升级sass-embedded版本,意图解决@import/@use 警告问题(暂未解决); 2、引入video.js插件
feat: 1、气象监测页面新增气象视频实时画面;开发虫情相关的交互,与后台接口初步对接master
parent
1b510b8cd5
commit
36cf3d7051
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-10-14 10:12:41
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-15 10:34:32
|
||||||
|
*/
|
||||||
|
export const baseInfoDict = {
|
||||||
|
plantingArea: {
|
||||||
|
svg: "nongshi",
|
||||||
|
text: "种植面积(亩)",
|
||||||
|
},
|
||||||
|
terrain: {
|
||||||
|
svg: "dixing",
|
||||||
|
text: "地形",
|
||||||
|
},
|
||||||
|
variety: {
|
||||||
|
svg: "pinzhong",
|
||||||
|
text: "种植品种(种)",
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
svg: "dapengzhongmiaoguanli",
|
||||||
|
text: "主要品种",
|
||||||
|
},
|
||||||
|
plantingNum: {
|
||||||
|
svg: "shuguo",
|
||||||
|
text: "种植荔枝(棵)",
|
||||||
|
},
|
||||||
|
yield: {
|
||||||
|
svg: "caizhaiguanli",
|
||||||
|
text: "去年产量(吨)",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const weatherTypes = [
|
||||||
|
"Temperature",
|
||||||
|
"Illuminance",
|
||||||
|
"WindSpeed",
|
||||||
|
"WindDirection",
|
||||||
|
"DailyRainfall",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const weatherDict = {
|
||||||
|
Temperature: {
|
||||||
|
name: "温度",
|
||||||
|
unit: "°C",
|
||||||
|
color: "#FF6B6B",
|
||||||
|
icon: "temperature2",
|
||||||
|
min: 0,
|
||||||
|
max: 40,
|
||||||
|
interval: 10,
|
||||||
|
},
|
||||||
|
Illuminance: {
|
||||||
|
name: "光照",
|
||||||
|
unit: "lux",
|
||||||
|
color: "#FFD166",
|
||||||
|
icon: "light",
|
||||||
|
min: 0,
|
||||||
|
max: 3200,
|
||||||
|
interval: 800,
|
||||||
|
},
|
||||||
|
WindSpeed: {
|
||||||
|
name: "风速",
|
||||||
|
unit: "km/h",
|
||||||
|
color: "#009688",
|
||||||
|
icon: "windPower",
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
interval: 2,
|
||||||
|
},
|
||||||
|
WindDirection: {
|
||||||
|
name: "风向",
|
||||||
|
unit: "°",
|
||||||
|
color: "#845EC2",
|
||||||
|
icon: "wind",
|
||||||
|
},
|
||||||
|
DailyRainfall: {
|
||||||
|
name: "降雨量",
|
||||||
|
unit: "mm",
|
||||||
|
color: "#6A0572",
|
||||||
|
icon: "rain",
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
interval: 2,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const soilTypes = [
|
||||||
|
"SoilTemperature",
|
||||||
|
"SoilHumidity",
|
||||||
|
"EC",
|
||||||
|
"PH",
|
||||||
|
"Nitrogen",
|
||||||
|
"Phosphorus",
|
||||||
|
"Potassium",
|
||||||
|
];
|
||||||
|
|
||||||
|
// 土壤数据 - 使用土壤设备常用的7个参数
|
||||||
|
export const soilDict = {
|
||||||
|
SoilTemperature: {
|
||||||
|
id: "SoilTemperature",
|
||||||
|
name: "土壤温度",
|
||||||
|
value: "22.5",
|
||||||
|
unit: "°C",
|
||||||
|
icon: "turangwendu",
|
||||||
|
color: "#ff7a45",
|
||||||
|
status: "normal",
|
||||||
|
description: "适宜作物生长",
|
||||||
|
},
|
||||||
|
SoilHumidity: {
|
||||||
|
id: "SoilHumidity",
|
||||||
|
name: "土壤湿度",
|
||||||
|
value: "65",
|
||||||
|
unit: "%",
|
||||||
|
icon: "turangshidu",
|
||||||
|
color: "#4096ff",
|
||||||
|
status: "normal",
|
||||||
|
description: "湿润度良好",
|
||||||
|
},
|
||||||
|
EC: {
|
||||||
|
id: "EC",
|
||||||
|
name: "电导率",
|
||||||
|
value: "0.8",
|
||||||
|
unit: "μS/cm",
|
||||||
|
icon: "turangdiandaoshuai",
|
||||||
|
color: "#73d13d",
|
||||||
|
status: "normal",
|
||||||
|
description: "盐分适中",
|
||||||
|
},
|
||||||
|
PH: {
|
||||||
|
id: "PH",
|
||||||
|
name: "土壤pH值",
|
||||||
|
value: "6.8",
|
||||||
|
unit: "",
|
||||||
|
icon: "suanjiandu",
|
||||||
|
color: "#ff9800",
|
||||||
|
status: "normal",
|
||||||
|
description: "酸碱度适宜",
|
||||||
|
},
|
||||||
|
Nitrogen: {
|
||||||
|
id: "Nitrogen",
|
||||||
|
name: "氮含量",
|
||||||
|
value: "35",
|
||||||
|
unit: "mg/kg",
|
||||||
|
icon: "turangdanhanliang",
|
||||||
|
color: "#fa541c",
|
||||||
|
status: "normal",
|
||||||
|
description: "肥力良好",
|
||||||
|
},
|
||||||
|
Phosphorus: {
|
||||||
|
id: "Phosphorus",
|
||||||
|
name: "磷含量",
|
||||||
|
value: "22",
|
||||||
|
unit: "mg/kg",
|
||||||
|
icon: "turanglinhanliang",
|
||||||
|
color: "#9c27b0",
|
||||||
|
status: "normal",
|
||||||
|
description: "含量适中",
|
||||||
|
},
|
||||||
|
Potassium: {
|
||||||
|
id: "Potassium",
|
||||||
|
name: "钾含量",
|
||||||
|
value: "85",
|
||||||
|
unit: "mg/kg",
|
||||||
|
icon: "turangjiahanliang",
|
||||||
|
color: "#2196f3",
|
||||||
|
status: "normal",
|
||||||
|
description: "钾素充足",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pestTypeDict = {
|
||||||
|
蚜虫: {
|
||||||
|
color: "#ff6b6b",
|
||||||
|
},
|
||||||
|
红蜘蛛: {
|
||||||
|
color: "#ffa502",
|
||||||
|
},
|
||||||
|
果蝇: {
|
||||||
|
color: "#5f27cd",
|
||||||
|
},
|
||||||
|
菜青虫: {
|
||||||
|
color: "#10ac84",
|
||||||
|
},
|
||||||
|
其他: {
|
||||||
|
color: "#54a0ff",
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-10-10 16:08:07
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-10 16:08:52
|
||||||
|
*/
|
||||||
|
const nowDate = new Date().toLocaleDateString().replace(/\//g, "-");
|
||||||
|
const nextDate = new Date(+new Date(nowDate) + 24 * 60 * 60 * 1000)
|
||||||
|
.toLocaleDateString()
|
||||||
|
.replace(/\//g, "-");
|
||||||
|
|
||||||
|
export const defaultParams = {
|
||||||
|
pageNum: 1,
|
||||||
|
deviceType: 1,
|
||||||
|
deviceId: null,
|
||||||
|
beginTime: `${nowDate} 00:00:00`,
|
||||||
|
endTime: `${nextDate} 23:59:59`,
|
||||||
|
};
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-08-08 16:17:54
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-15 17:31:37
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="dataList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
row-key="orchardId"
|
||||||
|
border
|
||||||
|
highlight-current-row
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
|
<el-table-column label="内容" align="center" prop="content" v-if="columns[0].visible" :show-overflow-tooltip="true"/>
|
||||||
|
<el-table-column label="状态" align="center" prop="status" v-if="columns[1].visible" />
|
||||||
|
<el-table-column label="模板" align="center" prop="template" v-if="columns[2].visible" />
|
||||||
|
<el-table-column label="推送时间" align="center" prop="createTime" v-if="columns[3].visible">
|
||||||
|
<template #default="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { parseTime } from '@/utils/ruoyi'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dataList: { type: Array, required: true },
|
||||||
|
loading: { type: Boolean, required: true },
|
||||||
|
columns: { type: Array, required: true }
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['selection-change'])
|
||||||
|
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
emits('selection-change', selection)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-08-18 09:27:23
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-15 17:34:07
|
||||||
|
-->
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
params: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['update:params', 'reset', 'query', 'export'])
|
||||||
|
|
||||||
|
const queryRef = ref()
|
||||||
|
const queryParams = ref({...props.params});
|
||||||
|
const dateRange = ref(null);
|
||||||
|
|
||||||
|
watch(() => dateRange.value, () => {
|
||||||
|
if (!dateRange.value.length) return;
|
||||||
|
queryParams.value.beginTime = dateRange.value[0]
|
||||||
|
queryParams.value.endTime = dateRange.value[1]
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => queryParams.value, (newVal) => {
|
||||||
|
emits('update:params', newVal)
|
||||||
|
}, {deep: true})
|
||||||
|
|
||||||
|
watch(() => props.params, (newVal) => {
|
||||||
|
Object.assign(queryParams.value, newVal)
|
||||||
|
})
|
||||||
|
|
||||||
|
function resetQuery() {
|
||||||
|
dateRange.value = [];
|
||||||
|
emits('reset', queryRef.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuery() {
|
||||||
|
// 触发 query 事件
|
||||||
|
emits('query')
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportData() {
|
||||||
|
emits('export')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
|
||||||
|
<el-form-item label="记录时间">
|
||||||
|
<el-date-picker
|
||||||
|
style="width: 300px"
|
||||||
|
v-model="dateRange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button type="warning" icon="Download" @click="exportData">导出</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-09-05 10:12:41
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-15 17:28:32
|
||||||
|
*/
|
||||||
|
// 列配置
|
||||||
|
export const columnsConfig = [
|
||||||
|
{ key: 0, label: "内容", visible: true },
|
||||||
|
{ key: 1, label: "状态", visible: true },
|
||||||
|
{ key: 2, label: "模板", visible: true },
|
||||||
|
{ key: 3, label: "时间", visible: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 状态颜色映射
|
||||||
|
export const statusColorMap = {
|
||||||
|
0: "success",
|
||||||
|
1: "danger",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultQueryParams = {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
beginTime: null,
|
||||||
|
endTime: null,
|
||||||
|
};
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-10-15 17:07:16
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-16 10:26:28
|
||||||
|
-->
|
||||||
|
<script setup>
|
||||||
|
import HistoryTable from './components/HistoryTable.vue';
|
||||||
|
import SearchForm from './components/SearchForm.vue';
|
||||||
|
import Statistics from './components/Statistics.vue';
|
||||||
|
import { columnsConfig, defaultQueryParams } from './config';
|
||||||
|
import { useSettings } from '@/hooks/useSettings';
|
||||||
|
import { listDeviceData, exportDeviceData } from '@/api/deviceData';
|
||||||
|
|
||||||
|
const { hasTags } = useSettings();
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const historyList = ref([]);
|
||||||
|
const chartData = ref([]);
|
||||||
|
const total = ref(0);
|
||||||
|
const loading = ref(false);
|
||||||
|
const queryParams = ref({...defaultQueryParams});
|
||||||
|
|
||||||
|
getHistoryList();
|
||||||
|
|
||||||
|
async function getHistoryList () {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const res = await listDeviceData(queryParams.value);
|
||||||
|
historyList.value = res.rows;
|
||||||
|
chartData.value = createChartData(res.rows)
|
||||||
|
total.value = res.total;
|
||||||
|
} catch (error) {
|
||||||
|
proxy.$modal.msgError('获取土壤墒情设备实时数据失败: ' + (error.message || '未知错误'))
|
||||||
|
console.error('Failed to get device live data:', error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
console.log(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNum = 1
|
||||||
|
getHistoryList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleReset(queryRef) {
|
||||||
|
queryParams.value = {...defaultQueryParams}
|
||||||
|
queryRef.resetFields()
|
||||||
|
getHistoryList()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleExport() {
|
||||||
|
const fileName = await proxy.download('/business/device-data/export', queryParams.value, `土壤墒情设备数据_${new Date().getTime()}.xlsx`)
|
||||||
|
fileName && proxy.$download.name(fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createChartData(data) {
|
||||||
|
const res = {}
|
||||||
|
data.forEach(item => {
|
||||||
|
const date = item.createTime?.split(' ')[0]
|
||||||
|
res[date] ? res[date]++ : (res[date] = 1)
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
names: Object.keys(res),
|
||||||
|
data: Object.values(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="['push-history-page', 'page-height', { 'hasTagsView': hasTags }]">
|
||||||
|
<el-card class="history-table-card">
|
||||||
|
<!-- 搜索表单 -->
|
||||||
|
<search-form v-model:params="queryParams" class="mb-12px" @query="handleQuery" @reset="handleReset" @export="handleExport" />
|
||||||
|
<!-- 历史记录表格 -->
|
||||||
|
<history-table :dataList="historyList" :columns="columnsConfig" :loading="loading" @selection-change="handleSelectionChange" />
|
||||||
|
<!-- 分页 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getHistoryList" />
|
||||||
|
</el-card>
|
||||||
|
<el-card class="analysis-card">
|
||||||
|
<statistics :chartData="chartData" />
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.push-history-page {
|
||||||
|
@apply p-20px flex flex-col gap-15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-table-card {
|
||||||
|
@apply flex-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-card {
|
||||||
|
@apply h-380px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-09-23 09:49:02
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-09-23 11:57:53
|
||||||
|
*/
|
||||||
|
export const soilTypes = [
|
||||||
|
"SoilTemperature",
|
||||||
|
"SoilHumidity",
|
||||||
|
"EC",
|
||||||
|
"PH",
|
||||||
|
"Nitrogen",
|
||||||
|
"Phosphorus",
|
||||||
|
"Potassium",
|
||||||
|
];
|
||||||
|
export const soilDict = {
|
||||||
|
SoilTemperature: {
|
||||||
|
name: "土壤温度",
|
||||||
|
unit: "°C",
|
||||||
|
color: "#FF6B6B",
|
||||||
|
icon: "temperature2",
|
||||||
|
},
|
||||||
|
SoilHumidity: {
|
||||||
|
name: "土壤湿度",
|
||||||
|
unit: "%",
|
||||||
|
color: "#4ECDC4",
|
||||||
|
icon: "humidity",
|
||||||
|
},
|
||||||
|
EC: {
|
||||||
|
name: "EC",
|
||||||
|
unit: "μS/cm",
|
||||||
|
color: "#6A0572",
|
||||||
|
icon: "ec",
|
||||||
|
},
|
||||||
|
PH: {
|
||||||
|
name: "PH",
|
||||||
|
unit: "",
|
||||||
|
color: "#FFD166",
|
||||||
|
icon: "ph-color",
|
||||||
|
},
|
||||||
|
Nitrogen: {
|
||||||
|
name: "氮",
|
||||||
|
unit: "mg/kg",
|
||||||
|
color: "#1A535C",
|
||||||
|
icon: "nitrogen",
|
||||||
|
},
|
||||||
|
Phosphorus: {
|
||||||
|
name: "磷",
|
||||||
|
unit: "mg/kg",
|
||||||
|
color: "#77DD77",
|
||||||
|
icon: "phosphorus",
|
||||||
|
},
|
||||||
|
Potassium: {
|
||||||
|
name: "钾",
|
||||||
|
unit: "mg/kg",
|
||||||
|
color: "#845EC2",
|
||||||
|
icon: "potassium",
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: chris
|
||||||
|
* @Date: 2025-10-10 12:03:45
|
||||||
|
* @LastEditors: chris
|
||||||
|
* @LastEditTime: 2025-10-10 14:36:11
|
||||||
|
-->
|
||||||
|
<script setup>
|
||||||
|
import { useSettings } from '@/hooks/useSettings'
|
||||||
|
|
||||||
|
const { hasTags } = useSettings()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="['uav-page', 'page-height', { 'hasTagsView': hasTags }]">
|
||||||
|
<iframe src="https://fh.dji.com/organization/6950d95b-1d32-44ef-9b69-816ad1ecdcf6/project/c50567c4-5582-47b3-b6c3-217f25f14281#/wayline" class="uav-iframe"></iframe>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.uav-iframe {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue