New file |
| | |
| | | import axios from "@/assets/js/axios"; |
| | | |
| | | /** |
| | | * 获取电池分析数据 |
| | | * @param type 分析数据的算法类型 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const bmsAnalysisApi = (type)=>{ |
| | | return axios({ |
| | | method: "POST", |
| | | url: "/monitor/box/bmsAlgorith", |
| | | params: { |
| | | type, |
| | | } |
| | | }); |
| | | } |
New file |
| | |
| | | import axios from "@/assets/js/axios"; |
| | | |
| | | /** |
| | | * 查询最近7天驾驶告警统计 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const searchRecentDaysDriveAlarmApi = ()=>{ |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/monitor/boxCameraAlarm/statisticDriveAlarmRegularLimits", |
| | | }); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查询今天的驾驶告警 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const searchTodayDriveAlarmApi = ()=>{ |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/monitor/boxCameraAlarm/statisticDriveAlarmRegularLimitsToday", |
| | | }); |
| | | } |
| | | |
| | | export const searchDriveListApi = (name, page, pageSize)=>{ |
| | | name = name?name:null; |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/monitor/box/select", |
| | | params: { |
| | | name, |
| | | page, |
| | | pageSize |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 查询车辆名称 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const searchAllDrivesApi = ()=>{ |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/monitor/box/selectNameByName", |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 添加车辆 |
| | | * @param name 车辆名称 |
| | | * @param boxSn 车辆编码 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const addDriveApi = (name, boxSn)=>{ |
| | | return axios({ |
| | | method: "POST", |
| | | url: "/monitor/box/addNewBox", |
| | | data: { |
| | | name, |
| | | boxSn |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 根据车辆ID删除指定车辆 |
| | | * @param id 车辆ID |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const deleteDriveApi = (id)=>{ |
| | | return axios({ |
| | | method: "POST", |
| | | url: "/monitor/box/deleteBox", |
| | | params: { |
| | | id |
| | | }, |
| | | }); |
| | | } |
| | |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .flex-page-layout { |
| | | display: flex; |
| | | height: 100%; |
| | | flex-direction: column; |
| | | } |
| | | .flex-page-header { |
| | | padding: 8px 8px 4px 8px; |
| | | } |
| | | .flex-page-content { |
| | | flex: 1; |
| | | padding: 4px 8px 8px 8px; |
| | | } |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100%; |
| | | background-image: radial-gradient(#151f4140, #3667ec40); |
| | | background-image: radial-gradient(#151f4140, rgba(23, 54, 140, 0.25)); |
| | | |
| | | >.flex-box-border { |
| | | position: absolute; |
| | |
| | | const getNormalLine = (data)=>{ |
| | | const defaultOption = { |
| | | minRatio: 0, |
| | | maxRatio: 1.1 |
| | | maxRatio: 1.1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | }; |
| | | const option = {...defaultOption, ...data}; |
| | | return { |
| | |
| | | legend: { |
| | | data: [] |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | grid: option.grid, |
| | | xAxis: { |
| | | name: "", |
| | | type: 'category', |
| | | nameTextStyle: { |
| | | color: "#00FEFF", |
| | | }, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: 'rgba(255,255,255,0.12)' |
| | |
| | | }, |
| | | }, |
| | | yAxis: [{ |
| | | name: "", |
| | | type: 'value', |
| | | nameTextStyle: { |
| | | color: "#00FEFF", |
| | | }, |
| | | min(data) { |
| | | const min =data.min; |
| | | if(isNaN(min)) { |
| | | return 0; |
| | | }else { |
| | | return (min * option.minRatio).toHold(2); |
| | | return (min * option.minRatio).toHold(3); |
| | | } |
| | | }, |
| | | max(data) { |
| | |
| | | if(isNaN(max)) { |
| | | return 1; |
| | | }else { |
| | | return (max * option.maxRatio).toHold(2); |
| | | return (max * option.maxRatio).toHold(3); |
| | | } |
| | | }, |
| | | axisLabel: { |
New file |
| | |
| | | <script setup> |
| | | import {onMounted, reactive, ref} from "vue"; |
| | | import {changeDriveInfoModule} from "@/views/moudle/driveInf/driveInf"; |
| | | const form = ref(null); |
| | | import { |
| | | ElLoading, |
| | | ElMessage |
| | | } from "element-plus"; |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }); |
| | | const emit = defineEmits(["update:visible", "success"]); |
| | | |
| | | const layout = reactive({ |
| | | gutter: 16, |
| | | span: 12 |
| | | }); |
| | | |
| | | const params = reactive({ |
| | | name: "", |
| | | boxSn: "", |
| | | }); |
| | | |
| | | const rules = reactive({ |
| | | name: [ |
| | | { required: true, message: '请输入车辆名称', trigger: 'blur' }, |
| | | ], |
| | | boxSn: [ |
| | | { required: true, message: '请输入车辆编码', trigger: 'blur' }, |
| | | ] |
| | | }); |
| | | |
| | | const close = ()=>{ |
| | | emit("update:visible", false); |
| | | } |
| | | |
| | | const submitForm = async (form) => { |
| | | if (!form) return |
| | | await form.validate((valid, fields) => { |
| | | if (valid) { |
| | | handleAdd(); |
| | | } else { |
| | | console.log('error submit!', fields) |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const { |
| | | addDrive |
| | | } = changeDriveInfoModule(); |
| | | |
| | | const handleAdd = async ()=>{ |
| | | const loading = ElLoading.service({ |
| | | text: "数据加载中...", |
| | | background: "rgba(122, 122, 122, 0.5)" |
| | | }); |
| | | try { |
| | | const rs = await addDrive(params.name, params.boxSn); |
| | | loading.close(); |
| | | if(rs.code === 1) { |
| | | ElMessage({ |
| | | message: rs.message, |
| | | type: "success" |
| | | }); |
| | | emit('success'); |
| | | close(); |
| | | }else { |
| | | ElMessage.error(rs.message); |
| | | } |
| | | }catch (e) { |
| | | console.log(e); |
| | | loading.close(); |
| | | } |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="params-container"> |
| | | <div class="params-content"> |
| | | <el-form |
| | | ref="form" |
| | | :model="params" |
| | | :rules="rules" |
| | | label-position="top"> |
| | | <el-row :gutter="layout.gutter"> |
| | | <el-col :span="layout.span"> |
| | | <el-form-item label="车辆名称" prop="name"> |
| | | <el-input v-model="params.name" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="layout.span"> |
| | | <el-form-item label="车辆编码" prop="boxSn"> |
| | | <el-input v-model="params.boxSn" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | <div class="params-footer"> |
| | | <el-button type="primary" @click="submitForm(form)">添加</el-button> |
| | | <el-button type="primary" @click="close">取消</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="less"> |
| | | .params-container { |
| | | width: 600px; |
| | | background-color: #FFFFFF; |
| | | .params-content { |
| | | padding: 8px; |
| | | } |
| | | .params-footer { |
| | | padding: 8px; |
| | | text-align: right; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | }); |
| | | |
| | | const params = reactive({ |
| | | name: "" |
| | | name: "", |
| | | boxSn: "", |
| | | id: "" |
| | | }); |
| | | |
| | | const rules = reactive({ |
| | |
| | | }, |
| | | { |
| | | path: "battShow", |
| | | name: "电池历史数据", |
| | | name: "电池测试原始数据", |
| | | meta: { |
| | | isTechPage: true, |
| | | title: "电池历史数据" |
| | | title: "电池测试原始数据" |
| | | }, |
| | | component: ()=>import("../views/battShow.vue"), |
| | | }, |
| | |
| | | meta: {}, |
| | | component: () => import("../views/user/videoList.vue"), |
| | | }, |
| | | { |
| | | path: "analysis/lof", |
| | | name: "局部离群因子LOF算法", |
| | | meta: { |
| | | isTechPage: true, |
| | | title: "局部离群因子LOF算法" |
| | | }, |
| | | component: ()=>import("../views/analysis/lofAnalysis.vue") |
| | | }, |
| | | { |
| | | path: "analysis/fusion", |
| | | name: "融合FEF和DTW算法", |
| | | meta: { |
| | | isTechPage: true, |
| | | title: "融合FEF和DTW算法" |
| | | }, |
| | | component: ()=>import("../views/analysis/fusionAnalysis.vue") |
| | | }, |
| | | ] |
| | | } |
| | | ] |
New file |
| | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import carInfoModule from "@/views/moudle/battShow/carInfo"; |
| | | import FlexBox from "@/components/FlexBox.vue"; |
| | | import ChartBox from "@/components/chartBox.vue"; |
| | | import {dataAnalysisModule} from "@/views/analysis/module"; |
| | | import HdwChart from "@/components/echarts/hdwChart.vue"; |
| | | import getNormalLine from "@/components/echarts/options/normalLine"; |
| | | |
| | | const carName = ref(""); |
| | | const timeRange = ref([]); |
| | | timeRange.value = [new Date("2020-01-01 00:00:00"), new Date("2023-01-01 00:00:00")]; |
| | | const {carList, getCarNames} = carInfoModule(); |
| | | |
| | | const { |
| | | analysisType, |
| | | searchBmsAnalysis, |
| | | } = dataAnalysisModule(); |
| | | |
| | | const title1 = ref("图表1"); |
| | | const chart1 = ref(null); |
| | | let chart1Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title2 = ref("图表2"); |
| | | const chart2 = ref(null); |
| | | let chart2Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title3 = ref("图表3"); |
| | | const chart3 = ref(null); |
| | | let chart3Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title4 = ref("图表4"); |
| | | const chart4 = ref(null); |
| | | let chart4Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | /** |
| | | * 格式化数据 |
| | | * @param data |
| | | * @return {{x: [], y: [], mark: []}} |
| | | */ |
| | | const formatData = (data)=>{ |
| | | console.log(data); |
| | | // 初始化lineData |
| | | const lineData = { |
| | | x: [], |
| | | y: [], |
| | | mark: [] |
| | | }; |
| | | |
| | | // 遍历数据 |
| | | for(let i=0; i<data.length; i++) { |
| | | let itemData = data[i]; |
| | | lineData.x.push(i); |
| | | |
| | | itemData.deginData.split(",").map((item, key)=>{ |
| | | if(lineData.y[key] === undefined) { |
| | | lineData.y[key] = []; |
| | | } |
| | | lineData.y[key].push(item); |
| | | }); |
| | | |
| | | // 阈值 |
| | | lineData.mark.push(itemData.thresholdData) |
| | | } |
| | | |
| | | return lineData; |
| | | } |
| | | |
| | | |
| | | const searchData = async ()=>{ |
| | | const rs = await searchBmsAnalysis(); |
| | | if(rs.code === 1) { |
| | | const data = rs.data; |
| | | // 图表1 |
| | | title1.value = data.y1Name; |
| | | let chart1Data = formatData(data.bmsAlgorithmVoList1); |
| | | chart1Option.xAxis.data = chart1Data.x; |
| | | chart1Option.series = chart1Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | |
| | | chart1Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart1Data.mark, |
| | | }); |
| | | |
| | | // 图表2 |
| | | title2.value = data.y2Name; |
| | | let chart2Data = formatData(data.bmsAlgorithmVoList2); |
| | | chart2Option.xAxis.data = chart2Data.x; |
| | | chart2Option.series = chart2Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart2Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart2Data.mark, |
| | | }); |
| | | |
| | | // 图表3 |
| | | title3.value = data.y3Name; |
| | | let chart3Data = formatData(data.bmsAlgorithmVoList3); |
| | | chart3Option.xAxis.data = chart3Data.x; |
| | | chart3Option.series = chart3Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart3Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart3Data.mark, |
| | | }); |
| | | |
| | | |
| | | // 图表4 |
| | | title4.value = data.y4Name; |
| | | let chart4Data = formatData(data.bmsAlgorithmVoList4); |
| | | chart4Option.xAxis.data = chart4Data.x; |
| | | chart4Option.series = chart4Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart4Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart4Data.mark, |
| | | }); |
| | | |
| | | }else { |
| | | initChart(); |
| | | } |
| | | |
| | | setChart(); |
| | | console.log(rs); |
| | | } |
| | | |
| | | const initChart = ()=>{ |
| | | title1.value = "图表1"; |
| | | chart1Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart1Option.tooltip.show = false; |
| | | chart1Option.xAxis.axisLabel.show = false; |
| | | chart1Option.xAxis.axisLine.show = false; |
| | | |
| | | title2.value = "图表2"; |
| | | chart2Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart2Option.tooltip.show = false; |
| | | chart2Option.xAxis.axisLabel.show = false; |
| | | chart2Option.xAxis.axisLine.show = false; |
| | | |
| | | title3.value = "图表3"; |
| | | chart3Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart3Option.tooltip.show = false; |
| | | chart3Option.xAxis.axisLabel.show = false; |
| | | chart3Option.xAxis.axisLine.show = false; |
| | | |
| | | title4.value = "图表4"; |
| | | chart4Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart4Option.tooltip.show = false; |
| | | chart4Option.xAxis.axisLabel.show = false; |
| | | chart4Option.xAxis.axisLine.show = false; |
| | | } |
| | | |
| | | const setChart = ()=>{ |
| | | chart1.value.setOption(chart1Option); |
| | | chart2.value.setOption(chart2Option); |
| | | chart3.value.setOption(chart3Option); |
| | | chart4.value.setOption(chart4Option); |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | getCarNames(); |
| | | initChart(); |
| | | setChart(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="flex-page-layout"> |
| | | <div class="flex-page-header"> |
| | | <div class="input-list"> |
| | | <div class="input-item"> |
| | | <div class="input-wrapper"> |
| | | <div class="input-label">车辆名称:</div> |
| | | <div class="input-content"> |
| | | <el-select v-model="carName" filterable> |
| | | <el-option |
| | | v-for="(item, key) in carList" :key="'key'+key" |
| | | :value="item.key" :label="item.label"></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-item"> |
| | | <div class="input-wrapper"> |
| | | <div class="input-label">日期选择:</div> |
| | | <div class="input-content"> |
| | | <el-date-picker |
| | | v-model="timeRange" |
| | | type="datetimerange" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | date-format="YYYY/MM/DD ddd" |
| | | time-format="A hh:mm:ss"></el-date-picker> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-item"> |
| | | <el-button type="primary" @click="searchData">查询</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="flex-page-content"> |
| | | <div class="chart-list-wrapper"> |
| | | <div class="chart-list-content"> |
| | | <div class="chart-list top"> |
| | | <div class="chart-item left"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title1"> |
| | | <hdw-chart ref="chart1"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | <div class="chart-item right"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title2"> |
| | | <hdw-chart ref="chart2"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | <div class="chart-list bottom"> |
| | | <div class="chart-item left"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title3"> |
| | | <hdw-chart ref="chart3"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | <div class="chart-item right"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title4"> |
| | | <hdw-chart ref="chart4"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <style scoped lang="less"> |
| | | .input-list { |
| | | .input-item { |
| | | display: inline-block; |
| | | margin-left: 8px; |
| | | vertical-align: middle; |
| | | .input-wrapper { |
| | | .input-content { |
| | | display: inline-block; |
| | | min-width: 160px; |
| | | } |
| | | .input-label { |
| | | display: inline-block; |
| | | line-height: 30px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | margin-right: 8px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart-list-wrapper { |
| | | display: flex; |
| | | height: 100%; |
| | | flex-direction: column; |
| | | .chart-list-content { |
| | | flex: 1; |
| | | .chart-list { |
| | | display: flex; |
| | | height: 50%; |
| | | &.top { |
| | | padding-bottom: 4px; |
| | | } |
| | | &.bottom { |
| | | padding-top: 4px; |
| | | } |
| | | .chart-item { |
| | | flex:1; |
| | | &.left { |
| | | padding-right: 4px; |
| | | } |
| | | &.right { |
| | | padding-left: 4px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .chart-list-footer { |
| | | padding: 4px 8px; |
| | | } |
| | | } |
| | | .flex-box-content { |
| | | height: 100%; |
| | | padding: 8px 0 8px 8px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <script setup> |
| | | import {onMounted, ref} from "vue"; |
| | | import carInfoModule from "@/views/moudle/battShow/carInfo"; |
| | | import FlexBox from "@/components/FlexBox.vue"; |
| | | import ChartBox from "@/components/chartBox.vue"; |
| | | import {dataAnalysisModule} from "@/views/analysis/module"; |
| | | import HdwChart from "@/components/echarts/hdwChart.vue"; |
| | | import getNormalLine from "@/components/echarts/options/normalLine"; |
| | | |
| | | const carName = ref(""); |
| | | const timeRange = ref([]); |
| | | timeRange.value = [new Date("2020-01-01 00:00:00"), new Date("2023-01-01 00:00:00")]; |
| | | const {carList, getCarNames} = carInfoModule(); |
| | | |
| | | const { |
| | | analysisType, |
| | | searchBmsAnalysis, |
| | | } = dataAnalysisModule(); |
| | | |
| | | const title1 = ref("图表1"); |
| | | const chart1 = ref(null); |
| | | let chart1Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title2 = ref("图表2"); |
| | | const chart2 = ref(null); |
| | | let chart2Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title3 = ref("图表3"); |
| | | const chart3 = ref(null); |
| | | let chart3Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | const title4 = ref("图表4"); |
| | | const chart4 = ref(null); |
| | | let chart4Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | }); |
| | | |
| | | /** |
| | | * 格式化数据 |
| | | * @param data |
| | | * @return {{x: [], y: [], mark: []}} |
| | | */ |
| | | const formatData = (data)=>{ |
| | | console.log(data); |
| | | // 初始化lineData |
| | | const lineData = { |
| | | x: [], |
| | | y: [], |
| | | mark: [] |
| | | }; |
| | | |
| | | // 遍历数据 |
| | | for(let i=0; i<data.length; i++) { |
| | | let itemData = data[i]; |
| | | lineData.x.push(i); |
| | | |
| | | itemData.deginData.split(",").map((item, key)=>{ |
| | | if(lineData.y[key] === undefined) { |
| | | lineData.y[key] = []; |
| | | } |
| | | lineData.y[key].push(item); |
| | | }); |
| | | |
| | | // 阈值 |
| | | lineData.mark.push(itemData.thresholdData) |
| | | } |
| | | |
| | | return lineData; |
| | | } |
| | | |
| | | |
| | | const searchData = async ()=>{ |
| | | const rs = await searchBmsAnalysis(); |
| | | if(rs.code === 1) { |
| | | const data = rs.data; |
| | | // 图表1 |
| | | title1.value = data.y1Name; |
| | | let chart1Data = formatData(data.bmsAlgorithmVoList1); |
| | | chart1Option.xAxis.data = chart1Data.x; |
| | | chart1Option.series = chart1Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | |
| | | chart1Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart1Data.mark, |
| | | }); |
| | | |
| | | // 图表2 |
| | | title2.value = data.y2Name; |
| | | let chart2Data = formatData(data.bmsAlgorithmVoList2); |
| | | chart2Option.xAxis.data = chart2Data.x; |
| | | chart2Option.series = chart2Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart2Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart2Data.mark, |
| | | }); |
| | | |
| | | // 图表3 |
| | | title3.value = data.y3Name; |
| | | let chart3Data = formatData(data.bmsAlgorithmVoList3); |
| | | chart3Option.xAxis.data = chart3Data.x; |
| | | chart3Option.series = chart3Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart3Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart3Data.mark, |
| | | }); |
| | | |
| | | |
| | | // 图表4 |
| | | title4.value = data.y4Name; |
| | | let chart4Data = formatData(data.bmsAlgorithmVoList4); |
| | | chart4Option.xAxis.data = chart4Data.x; |
| | | chart4Option.series = chart4Data.y.map((item, key)=>{ |
| | | return { |
| | | name: '#'+(key+1), |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | data: item, |
| | | } |
| | | }); |
| | | chart4Option.series.push({ |
| | | name: '阈值', |
| | | type: 'line', |
| | | smooth: false, |
| | | symbolSize: 0, |
| | | lineStyle: { |
| | | color: "#FF0000" |
| | | }, |
| | | data: chart4Data.mark, |
| | | }); |
| | | |
| | | }else { |
| | | initChart(); |
| | | } |
| | | |
| | | setChart(); |
| | | console.log(rs); |
| | | } |
| | | |
| | | const initChart = ()=>{ |
| | | title1.value = "图表1"; |
| | | chart1Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart1Option.tooltip.show = false; |
| | | chart1Option.xAxis.axisLabel.show = false; |
| | | chart1Option.xAxis.axisLine.show = false; |
| | | |
| | | title2.value = "图表2"; |
| | | chart2Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart2Option.tooltip.show = false; |
| | | chart2Option.xAxis.axisLabel.show = false; |
| | | chart2Option.xAxis.axisLine.show = false; |
| | | |
| | | title3.value = "图表3"; |
| | | chart3Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart3Option.tooltip.show = false; |
| | | chart3Option.xAxis.axisLabel.show = false; |
| | | chart3Option.xAxis.axisLine.show = false; |
| | | |
| | | title4.value = "图表4"; |
| | | chart4Option = getNormalLine({ |
| | | minRatio: 1, |
| | | maxRatio: 1, |
| | | grid: { |
| | | left: '1%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | top: "6%", |
| | | containLabel: true |
| | | } |
| | | }); |
| | | chart4Option.tooltip.show = false; |
| | | chart4Option.xAxis.axisLabel.show = false; |
| | | chart4Option.xAxis.axisLine.show = false; |
| | | } |
| | | |
| | | const setChart = ()=>{ |
| | | chart1.value.setOption(chart1Option); |
| | | chart2.value.setOption(chart2Option); |
| | | chart3.value.setOption(chart3Option); |
| | | chart4.value.setOption(chart4Option); |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | getCarNames(); |
| | | initChart(); |
| | | setChart(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="flex-page-layout"> |
| | | <div class="flex-page-header"> |
| | | <div class="input-list"> |
| | | <div class="input-item"> |
| | | <div class="input-wrapper"> |
| | | <div class="input-label">车辆名称:</div> |
| | | <div class="input-content"> |
| | | <el-select v-model="carName" filterable> |
| | | <el-option |
| | | v-for="(item, key) in carList" :key="'key'+key" |
| | | :value="item.key" :label="item.label"></el-option> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-item"> |
| | | <div class="input-wrapper"> |
| | | <div class="input-label">日期选择:</div> |
| | | <div class="input-content"> |
| | | <el-date-picker |
| | | v-model="timeRange" |
| | | type="datetimerange" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | date-format="YYYY/MM/DD ddd" |
| | | time-format="A hh:mm:ss"></el-date-picker> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="input-item"> |
| | | <el-button type="primary" @click="searchData">查询</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="flex-page-content"> |
| | | <div class="chart-list-wrapper"> |
| | | <div class="chart-list-content"> |
| | | <div class="chart-list top"> |
| | | <div class="chart-item left"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title1"> |
| | | <hdw-chart ref="chart1"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | <div class="chart-item right"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title2"> |
| | | <hdw-chart ref="chart2"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | <div class="chart-list bottom"> |
| | | <div class="chart-item left"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title3"> |
| | | <hdw-chart ref="chart3"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | <div class="chart-item right"> |
| | | <flex-box> |
| | | <div class="flex-box-content"> |
| | | <chart-box :title="title4"> |
| | | <hdw-chart ref="chart4"></hdw-chart> |
| | | </chart-box> |
| | | </div> |
| | | </flex-box> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <style scoped lang="less"> |
| | | .input-list { |
| | | .input-item { |
| | | display: inline-block; |
| | | margin-left: 8px; |
| | | vertical-align: middle; |
| | | .input-wrapper { |
| | | .input-content { |
| | | display: inline-block; |
| | | min-width: 160px; |
| | | } |
| | | .input-label { |
| | | display: inline-block; |
| | | line-height: 30px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | margin-right: 8px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .chart-list-wrapper { |
| | | display: flex; |
| | | height: 100%; |
| | | flex-direction: column; |
| | | .chart-list-content { |
| | | flex: 1; |
| | | .chart-list { |
| | | display: flex; |
| | | height: 50%; |
| | | &.top { |
| | | padding-bottom: 4px; |
| | | } |
| | | &.bottom { |
| | | padding-top: 4px; |
| | | } |
| | | .chart-item { |
| | | flex:1; |
| | | &.left { |
| | | padding-right: 4px; |
| | | } |
| | | &.right { |
| | | padding-left: 4px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .chart-list-footer { |
| | | padding: 4px 8px; |
| | | } |
| | | } |
| | | .flex-box-content { |
| | | height: 100%; |
| | | padding: 8px 0 8px 8px; |
| | | } |
| | | </style> |
New file |
| | |
| | | import {bmsAnalysisApi} from "@/api/analysis"; |
| | | import {ref} from "vue"; |
| | | |
| | | /** |
| | | * 查询bms数据分析 |
| | | * @return {{searchBmsAnalysis: (function(): Promise<*|{code: number, data: null, message: string}|undefined>), analysisType: Ref<UnwrapRef<number>>}} |
| | | */ |
| | | export const dataAnalysisModule = ()=>{ |
| | | const analysisType = ref(1); |
| | | const searchBmsAnalysis = async ()=>{ |
| | | try { |
| | | const res = await bmsAnalysisApi(analysisType.value); |
| | | return res.data; |
| | | }catch (e) { |
| | | console.log(e); |
| | | return { |
| | | code: 0, |
| | | data: null, |
| | | message: "数据请求失败,请联系管理员!" |
| | | } |
| | | } |
| | | } |
| | | |
| | | return { |
| | | analysisType, |
| | | searchBmsAnalysis |
| | | } |
| | | } |
| | |
| | | .input-item { |
| | | display: inline-block; |
| | | margin-left: 8px; |
| | | } |
| | | } |
| | | .input-wrapper { |
| | | display: flex; |
| | | .input-content { |
| | | min-width: 160px; |
| | | vertical-align: middle; |
| | | } |
| | | .input-label { |
| | | display: inline-block; |
| | | line-height: 32px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | margin-right: 8px; |
| | | vertical-align: middle; |
| | | vertical-align: middle; |
| | | .input-wrapper { |
| | | .input-content { |
| | | display: inline-block; |
| | | min-width: 160px; |
| | | } |
| | | .input-label { |
| | | display: inline-block; |
| | | line-height: 30px; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | margin-right: 8px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <script setup> |
| | | import loginPageImg from '@/assets/images/login-page-img.png'; |
| | | import loginPageImg from '@/assets/images/login-page-img1.jpg'; |
| | | import {loginMoudle} from "@/views/moudle/user/login"; |
| | | const {username, password, User, Lock, checkLogin} = loginMoudle(); |
| | | </script> |
| | |
| | | <div class="login-content-wrapper"> |
| | | <div class="login-img"> |
| | | <img :src="loginPageImg" alt="" /> |
| | | <!-- <img src="@/assets/images/logo1.png" alt="" />--> |
| | | </div> |
| | | <div class="login-content"> |
| | | <div class="sys-name">动力电池安全检测大数据分析平台</div> |
| | | <div class="sys-name"> |
| | | <!-- <img src="@/assets/images/logo1.png" width="50" alt="" />--> |
| | | 动力电池安全检测大数据分析平台 |
| | | </div> |
| | | <div class="input-wrapper"> |
| | | <el-input v-model="username" size="large" placeholder="请输入账户名" :prefix-icon="User" /> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="footer-content"> |
| | | <span style="margin-right: 16px">湖北工业大学</span><span>智能通信与大数据分析团队</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="less" scoped> |
| | | .login-wrapper { |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | |
| | | .sys-name { |
| | | text-align: center; |
| | | font-size: 24px; |
| | | letter-spacing: 2px; |
| | | font-weight: 400; |
| | | margin-bottom: 30px; |
| | | img { |
| | | vertical-align: middle; |
| | | } |
| | | .sub-text { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | .input-wrapper { |
| | | margin-bottom: 20px; |
| | |
| | | width: 100%; |
| | | } |
| | | } |
| | | .footer-content { |
| | | position: absolute; |
| | | width: 100%; |
| | | bottom: 16px; |
| | | text-align: center; |
| | | color: #FFFFFF; |
| | | } |
| | | </style> |
| | |
| | | import {useRoute} from "vue-router"; |
| | | import PageHeader from "@/views/mainLayout/components/pageHeader.vue"; |
| | | import logoImg from '@/assets/images/logo1.png'; |
| | | import {computed} from "vue"; |
| | | import usePageMenuStore from "@/stores/pageMenu"; |
| | | const route = useRoute(); |
| | | const {isCollapse, menuActive, menuData} = slideMenu(); |
| | | menuActive.value = route.path; |
| | |
| | | path: "/home", |
| | | icon: "HomeFilled" |
| | | }, |
| | | { |
| | | title: "视频监控", |
| | | path: "/videoShow", |
| | | icon: "VideoCameraFilled" |
| | | }, |
| | | // { |
| | | // title: "视频监控", |
| | | // path: "/videoShow", |
| | | // icon: "VideoCameraFilled" |
| | | // }, |
| | | // { |
| | | // title: "驾驶行为分析图", |
| | | // path: "/user/drivingAnalysis", |
| | | // icon: "Van" |
| | | // }, |
| | | { |
| | | title: "电池历史数据", |
| | | title: "原始数据", |
| | | path: "/battShow", |
| | | icon: "TrendCharts" |
| | | }, |
| | | { |
| | | title: "用户管理", |
| | | path: "/user", |
| | | icon: "UserFilled", |
| | | title: "故障分析", |
| | | path: "/analysis", |
| | | icon: "Monitor", |
| | | children: [ |
| | | { |
| | | title: "驾驶行为分析图", |
| | | path: "/user/drivingAnalysis", |
| | | title: "局部离群因子LOF算法", |
| | | path: "/analysis/lof", |
| | | }, |
| | | { |
| | | title: "融合FEF和DTW算法", |
| | | path: "/analysis/fusion", |
| | | }, |
| | | { |
| | | title: "Hausdorff距离算法", |
| | | path: "/user/videoList", |
| | | }, |
| | | { |
| | | title: "Frechet距离算法", |
| | | path: "/user/videoList", |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | title: "设备管理", |
| | | path: "/user", |
| | | icon: "OfficeBuilding", |
| | | children: [ |
| | | { |
| | | title: "汽车列表", |
| | | path: "/user/boxList", |
| | |
| | | title: "摄像头列表", |
| | | path: "/user/videoList", |
| | | }, |
| | | ], |
| | | }, |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | const pageMenuStore = usePageMenuStore(); |
| | | const isTechPage = computed(()=>{ |
| | | return pageMenuStore.isTechPage; |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | <div class="slide-footer"></div> |
| | | </div> |
| | | </div> |
| | | <div class="main-layout-content"> |
| | | <div class="main-layout-content" :class="{'is-tech-page': isTechPage}"> |
| | | <div class="full-height" style="overflow-x: hidden"> |
| | | <div class="main-layout-content-wrapper"> |
| | | <div class="main-layout-content-header"> |
| | |
| | | <router-view></router-view> |
| | | </div> |
| | | </div> |
| | | <div class="main-layout-content-footer" :class="{'is-tech-page': isTechPage}"> |
| | | <span style="margin-right: 16px">湖北工业大学</span><span>智能通信与大数据分析团队</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="main-layout-footer"></div> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | .main-layout { |
| | | display: flex; |
| | | height: 100%; |
| | | background-color: #f7f7f7; |
| | | .main-layout-left { |
| | | position: relative; |
| | | display: flex; |
| | |
| | | .main-layout-content { |
| | | flex: 1; |
| | | overflow-y: auto; |
| | | &.is-tech-page { |
| | | background: url("@/assets/images/dw_bg.jpg") no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | } |
| | | } |
| | | .main-layout-content-wrapper { |
| | |
| | | .main-layout-content-body { |
| | | position: relative; |
| | | flex: 1; |
| | | background-color: #FFFFFF; |
| | | .body-absolute { |
| | | position: absolute; |
| | | top: 0; |
| | |
| | | } |
| | | } |
| | | } |
| | | .make-group { |
| | | padding: 4px; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | } |
| | | .slide-footer { |
| | | text-align: center; |
| | | color: #00FEFF; |
| | | font-size: 14px; |
| | | } |
| | | .main-layout-content-footer { |
| | | text-align: center; |
| | | padding: 4px; |
| | | font-size: 14px; |
| | | color: #000; |
| | | &.is-tech-page { |
| | | color: #00FEFF; |
| | | } |
| | | } |
| | | </style> |
| | |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 查询车辆名称 |
| | | * @return {Promise<AxiosResponse<any>> | *} |
| | | */ |
| | | export const searchAllDrives = ()=>{ |
| | | return axios({ |
| | | method: "GET", |
| | | url: "/monitor/box/selectNameByName", |
| | | }); |
| | | } |
| | | |
| | | export const addDriveApi = ()=>{ |
| | | |
| | | } |
| | |
| | | import { |
| | | searchDriveList, |
| | | searchRecentDaysDriveAlarm, searchTodayDriveAlarm |
| | | searchRecentDaysDriveAlarm, |
| | | searchTodayDriveAlarm, |
| | | searchAllDrives |
| | | } from "./apis" |
| | | import {ref} from "vue"; |
| | | import {reactive, ref} from "vue"; |
| | | |
| | | import pageModule from "@/views/moudle/pageInfo"; |
| | | export const recentDaysDriveAlarmModule = ()=>{ |
| | |
| | | const driveList = ref([]); |
| | | |
| | | /** |
| | | * 获取汽车列表 |
| | | * 获取汽车列表,带分页信息 |
| | | * @return {Promise<{result: [], total: number, pages: number, pageSize: number, page: number}>} |
| | | */ |
| | | const getDriveList = async ()=>{ |
| | |
| | | total, |
| | | driveList, |
| | | carName, |
| | | getDriveList |
| | | getDriveList, |
| | | }; |
| | | } |
| | | |
| | | export const allDrivesModule = ()=>{ |
| | | // 获取所有车辆的信息 |
| | | const allDriveList = reactive({ |
| | | data: [] |
| | | }); |
| | | /** |
| | | * 获取全部的车辆信息 |
| | | * @return Promise<{code: number, data: *[], message: string}> |
| | | */ |
| | | const getAllDriveList = async ()=>{ |
| | | try { |
| | | const res = await searchAllDrives(); |
| | | return res.data; |
| | | }catch (e) { |
| | | console.log(e); |
| | | return { |
| | | code: 0, |
| | | data: [], |
| | | message: "查询失败,请联系管理员" |
| | | } |
| | | } |
| | | } |
| | | |
| | | return { |
| | | allDriveList, |
| | | getAllDriveList |
| | | } |
| | | } |
| | | |
| | | |
| | | import { |
| | | addDriveApi, |
| | | deleteDriveApi |
| | | } from "@/api/car"; |
| | | export const changeDriveInfoModule = ()=>{ |
| | | /** |
| | | * |
| | | * @param name 车辆名称 |
| | | * @param boxSn 车辆编码 |
| | | * @return Promise<{code: number, message: string}> |
| | | */ |
| | | const addDrive = async (name, boxSn)=>{ |
| | | try { |
| | | const res = await addDriveApi(name, boxSn); |
| | | return res.data; |
| | | }catch (e) { |
| | | return { |
| | | code: 0, |
| | | message: "添加失败,请联系管理员" |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据ID删除车辆 |
| | | * @param id 车辆ID |
| | | * @return {Promise<{code: number, message: string}|*>} |
| | | */ |
| | | const deleteDrive = async (id)=>{ |
| | | try { |
| | | const res = await deleteDriveApi(id); |
| | | return res.data; |
| | | }catch (e) { |
| | | return { |
| | | code: 0, |
| | | message: "删除失败,请联系管理员" |
| | | } |
| | | } |
| | | } |
| | | |
| | | return { |
| | | addDrive, |
| | | deleteDrive |
| | | } |
| | | } |
| | |
| | | <script setup> |
| | | import {ref, onMounted} from "vue"; |
| | | import {ElMessage, ElMessageBox} from "element-plus"; |
| | | import { |
| | | allDrivesModule, changeDriveInfoModule, |
| | | driveInfModule |
| | | } from "@/views/moudle/driveInf/driveInf"; |
| | | import EditDriveParams from "@/components/params/editDriveParams.vue"; |
| | | import AddDriveParams from "@/components/params/addDriveParams.vue"; |
| | | const editVisible = ref(false); |
| | | |
| | | const addVisible = ref(false); |
| | | const { |
| | | page, |
| | | pageSize, |
| | |
| | | carName, |
| | | getDriveList |
| | | } = driveInfModule(); |
| | | |
| | | const loading = ref(false); |
| | | const svg = ` |
| | | <path class="path" d=" |
| | | M 30 15 |
| | | L 28 17 |
| | | M 25.61 25.61 |
| | | A 15 15, 0, 0, 1, 15 30 |
| | | A 15 15, 0, 1, 1, 27.99 7.5 |
| | | L 15 15 |
| | | " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/> |
| | | `; |
| | | /** |
| | | * 查询汽车列表 |
| | | * @return {Promise<void>} |
| | | */ |
| | | const searchDriveList = async ()=>{ |
| | | // 开启等待框 |
| | | loading.value = true; |
| | | |
| | | let res = await getDriveList(); |
| | | driveList.value = res.result; |
| | | // 关闭等待框 |
| | | loading.value = false; |
| | | } |
| | | |
| | | /** |
| | |
| | | searchDriveList(); |
| | | } |
| | | |
| | | const { |
| | | allDriveList, |
| | | getAllDriveList |
| | | } = allDrivesModule(); |
| | | |
| | | const searchAllDrives = async ()=>{ |
| | | const res = await getAllDriveList(); |
| | | console.log(res); |
| | | } |
| | | |
| | | const { |
| | | deleteDrive |
| | | } = changeDriveInfoModule(); |
| | | const handleDeleteDrive = (row)=>{ |
| | | ElMessageBox.confirm( |
| | | "确认删除当前车辆", |
| | | "系统提示" |
| | | ).then(async ()=>{ |
| | | const rs = await deleteDrive(row.id); |
| | | if (rs.code === 1) { |
| | | ElMessage({ |
| | | message: rs.message, |
| | | type: "success" |
| | | }); |
| | | searchDriveList(); |
| | | }else { |
| | | ElMessage.error(rs.message); |
| | | } |
| | | }).catch(()=>{}); |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | searchDriveList(); |
| | | searchAllDrives(); |
| | | }); |
| | | </script> |
| | | |
| | |
| | | <div class="page-content"> |
| | | <div class="page-header"> |
| | | <div class="input-list"> |
| | | <div class="input-item"> |
| | | <!-- <div class="input-item">--> |
| | | <!-- <div class="input-wrapper">--> |
| | | <!-- <div class="input-label">车辆名称:</div>--> |
| | | <!-- <div class="input-content">--> |
| | | <!-- <el-select v-model="carName" filterable>--> |
| | | <!-- <el-option--> |
| | | <!-- v-for="(item, key) in carList" :key="'key'+key"--> |
| | | <!-- v-for="(item, key) in allDriveList.data" :key="'key'+key"--> |
| | | <!-- :value="item.key" :label="item.label"></el-option>--> |
| | | <!-- </el-select>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | </div> |
| | | <!-- </div>--> |
| | | <div class="input-item"> |
| | | <el-button type="success" icon="Plus">添加</el-button> |
| | | <el-button type="primary" icon="Search">查询</el-button> |
| | | <el-button type="success" icon="Plus" @click="addVisible=true">添加</el-button> |
| | | <el-button type="primary" icon="Search" @click="searchDriveList">查询</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="page-content"> |
| | | <el-table :data="driveList" height="100%"> |
| | | <el-table |
| | | v-loading="loading" |
| | | element-loading-text="数据加载中..." |
| | | :element-loading-spinner="svg" |
| | | element-loading-svg-view-box="-10, -10, 50, 50" |
| | | element-loading-background="rgba(122, 122, 122, 0.5)" |
| | | :data="driveList" |
| | | height="100%"> |
| | | <el-table-column min-width="120" align="center" prop="name" label="车辆名称" /> |
| | | <el-table-column min-width="120" align="center" prop="boxSn" label="车辆编码"></el-table-column> |
| | | <el-table-column align="center" prop="online" label="车辆状态"> |
| | |
| | | <el-table-column min-width="170" align="center" prop="onlineTime1" label="在线时间"></el-table-column> |
| | | <el-table-column min-width="170" align="center" prop="updateTime1" label="数据更新日期"></el-table-column> |
| | | <el-table-column align="center" fixed="right" label="操作" width="120"> |
| | | <template #default> |
| | | <el-button link type="primary" size="small" @click="editVisible = true">编辑</el-button> |
| | | <el-button link type="primary" size="small">删除</el-button> |
| | | <template #default="{row}"> |
| | | <!-- <el-button link type="primary" size="small" @click="editVisible = true">编辑</el-button>--> |
| | | <el-button link type="primary" size="small" @click="handleDeleteDrive(row)">删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | destroy-on-close |
| | | align-center> |
| | | <edit-drive-params v-model:visible="editVisible"></edit-drive-params> |
| | | </el-dialog> |
| | | |
| | | <el-dialog |
| | | v-model="addVisible" |
| | | title="车辆信息添加" |
| | | width="auto" |
| | | draggable |
| | | destroy-on-close |
| | | align-center> |
| | | <add-drive-params v-model:visible="addVisible" @success="searchDriveList"></add-drive-params> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | |
| | | .input-item { |
| | | display: inline-block; |
| | | margin-left: 8px; |
| | | vertical-align: top; |
| | | } |
| | | } |
| | | .input-wrapper { |
| | |
| | | } |
| | | .input-label { |
| | | font-size: 14px; |
| | | line-height: 40px; |
| | | line-height: 32px; |
| | | vertical-align: bottom; |
| | | margin-right: 8px; |
| | | } |
New file |
| | |
| | | #### V2023-9-25 |
| | | ```text |
| | | 初次提交 |
| | | ``` |
| | | #### V2023-9-28 |
| | | ```text |
| | | 调整驾驶行为页面内容 |
| | | ``` |
| | | #### V2023-11-10 |
| | | ```text |
| | | 对接电池历史数据 |
| | | ``` |
| | | #### V2023-11-16 |
| | | ```text |
| | | (1)调整首页内容布局 |
| | | (2)对接首页数据 |
| | | (3)电池历史数据增加滚动条,实现拖动滚动条,回放数据功能。 |
| | | ``` |
| | | #### V2023-11-21 |
| | | ```text |
| | | 汽车列表功能完善,完成查询,添加和删除。 |
| | | ps:编辑功能暂未开启 |
| | | ``` |
| | | #### V2023-11-23 |
| | | ```text |
| | | 一、登录页 |
| | | (1)替换图标为湖北工业大学的logo |
| | | (2)页面底部添加团队名称:湖北工业大学 智能通信与大数据分析团队 |
| | | 二、整体项目底部添加团队名称,颜色和页面的色调保持一致 |
| | | 三、调整左侧导航 |
| | | (1)去除用户管理 |
| | | (2)新增一级菜单: |
| | | 数据分析和其子菜单:健康状态估计;内短路检测;一致性分析 |
| | | (3)暂时隐藏驾驶行为和视频监控 |
| | | (4)最终导航为如下 |
| | | 首页 |
| | | 历史数据 |
| | | 数据分析 |
| | | 健康状态估计 |
| | | 内短路检测 |
| | | 一致性分析 |
| | | 设备管理 |
| | | 汽车列表 |
| | | 摄像头列表 |
| | | ``` |
| | | #### V2023-11-29 |
| | | ```text |
| | | 数据分析修改为故障分析 |
| | | 导航如下: |
| | | 故障分析 |
| | | 局部离群因子LOF算法 |
| | | 融合FEF和DTW算法 |
| | | Hausdorff距离算法 |
| | | Frechet距离算法 |
| | | ``` |
| | |
| | | } |
| | | }, |
| | | server: { |
| | | port: 8080 |
| | | port: 8081 |
| | | }, |
| | | resolve: { |
| | | alias: { |