@@ -1,7 +1,7 @@ | |||||
<!-- | <!-- | ||||
* @Date: 2022-08-17 16:19:13 | * @Date: 2022-08-17 16:19:13 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-10-09 09:47:52 | |||||
* @LastEditTime: 2023-10-13 14:50:29 | |||||
* @FilePath: \TelpoH5FrontendWeb\README.md | * @FilePath: \TelpoH5FrontendWeb\README.md | ||||
* @description: 项目说明 | * @description: 项目说明 | ||||
--> | --> | ||||
@@ -718,4 +718,12 @@ update | |||||
`2023.10.9` | `2023.10.9` | ||||
update | update | ||||
- 问卷调查 | - 问卷调查 | ||||
- 增加 答题完成返回错误后如果是从随手精灵公众号调过来的用户,则第8 11题文字变红 | |||||
- 增加 答题完成返回错误后如果是从随手精灵公众号调过来的用户,则第8 11题文字变红 | |||||
## v1.0.90 | |||||
`2023.10.13` | |||||
feature | |||||
- 增加 c1后台设备功耗查看页面 | |||||
- 增加 cell,echarts和table组件 |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* @Date: 2021-12-18 15:49:01 | * @Date: 2021-12-18 15:49:01 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-03-27 15:29:01 | |||||
* @LastEditTime: 2023-10-12 11:37:52 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\api\core.js | * @FilePath: \TelpoH5FrontendWeb\src\api\core.js | ||||
* @description: | * @description: | ||||
* b端的接口, 每次调用前先获取token | * b端的接口, 每次调用前先获取token | ||||
@@ -12,6 +12,7 @@ const baseUrl = process.env.VUE_APP_BASE_API + 'gateway'; | |||||
const service = axios.create({ | const service = axios.create({ | ||||
baseURL: baseUrl, | baseURL: baseUrl, | ||||
}); | }); | ||||
const HTTP_PREFIX_CORE = process.env.VUE_APP_BASE_API + 'gateway/' + 'core'; | |||||
service.interceptors.request.use( | service.interceptors.request.use( | ||||
request => { | request => { | ||||
if (localStorage.getItem(prefix + 'gatewayToken')) { | if (localStorage.getItem(prefix + 'gatewayToken')) { | ||||
@@ -30,6 +31,30 @@ export const APICore = { | |||||
cardPackageList, //零川基础套餐列表 | cardPackageList, //零川基础套餐列表 | ||||
devicePayPackage, | devicePayPackage, | ||||
drownReportFilterAdd,//添加过滤危险水域区域 | drownReportFilterAdd,//添加过滤危险水域区域 | ||||
setLocationConfig, //设置设备定位控制参数 | |||||
getLocationConfig, //获取设备定位控制参数 | |||||
getHealthConfig, //获取设备健康控制参数(心率、血氧、测温) | |||||
setHealthConfig, //设置设备健康控制参数(心率、血氧、测温) | |||||
setUploadConfig, //置设备上报周期参数 | |||||
getUploadConfig, //取设备上报周期参数 | |||||
setDrownConfig, //设置设备防溺水参数 | |||||
getDrownConfig, //获取设备防溺水参数 | |||||
setNowearConfig, //设置设备未佩戴检测参数 | |||||
getNowearConfig, //获取设备未佩戴检测参数 | |||||
setWatchConfig , //手表模式设置参数(平台) | |||||
getWatchConfig , //查看手表模式设置参数 | |||||
getDrownReportFilterQuery, //获取水域告警白名单 | |||||
drownReportFilterDelete, ////删除过滤危险水域区域 | |||||
setAutoPlayConfigOfDiba, //设置迪爸自动播放参数接口 | |||||
getAutoPlayConfigOfDiba, //获取迪爸自动播放列表接口 | |||||
getBloodPressList, //获取血压数据列表 | |||||
getBloodPressConfig, //获取设备血压周期性检测参数 | |||||
setBloodPressConfig, //设置设备血压周期性检测参数 | |||||
setPsychAbilityConfig, //心理监测能力开通(下发参数) | |||||
getPsychAbilityConfig,//获取心理监测能力开通参数 | |||||
setIotCtlMode, //设置设备iot连接控制属性 | |||||
getIotCtlMode, //获取设备iot连接控制属性 | |||||
checkImei, //检查设备关联的物联网厂商信息 | |||||
} | } | ||||
/* const headerAuth = this.$store.getters.gatewayToken; */ | /* const headerAuth = this.$store.getters.gatewayToken; */ | ||||
// 获取告警详情 | // 获取告警详情 | ||||
@@ -101,4 +126,187 @@ function drownReportFilterAdd(data) { | |||||
data, | data, | ||||
}); | }); | ||||
} | } | ||||
function setLocationConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetLocationConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getLocationConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetLocationConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setHealthConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetHealthConfig`, | |||||
method: 'post', | |||||
headers: {authKey: 'key1'}, | |||||
data: params, | |||||
}); | |||||
} | |||||
function getHealthConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetHealthConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setUploadConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetUploadConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getUploadConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetUploadConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setAutoPlayConfigOfDiba(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/OpenAbility/Diba/setConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getAutoPlayConfigOfDiba({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/OpenAbility/Diba/getConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setDrownConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetDrownConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getDrownConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetDrownConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setNowearConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetNowearConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getNowearConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetNowearConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function setWatchConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/Device/SetWatchConfig`, | |||||
method: 'post', | |||||
data: params, | |||||
}); | |||||
} | |||||
function getWatchConfig({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/Device/GetWatchConfig`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function getDrownReportFilterQuery({imei}) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/Device/DrownReportFilterQuery`, | |||||
method: 'get', | |||||
params: {imei}, | |||||
}) | |||||
} | |||||
function drownReportFilterDelete(data) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/Device/DrownReportFilterDelete`, | |||||
method: 'get', | |||||
params: data, | |||||
}) | |||||
} | |||||
function getBloodPressList(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/healthy/BloodPressQuery`, | |||||
method: 'post', | |||||
data: params , | |||||
}); | |||||
} | |||||
function getBloodPressConfig(data) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetBloodPressConfig`, | |||||
method: 'get', | |||||
params: data, | |||||
}) | |||||
} | |||||
function setBloodPressConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetBloodPressConfig`, | |||||
method: 'post', | |||||
data: params , | |||||
}); | |||||
} | |||||
function getPsychAbilityConfig(data) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetPsychAbilityConfig`, | |||||
method: 'get', | |||||
params: data, | |||||
}) | |||||
} | |||||
function setPsychAbilityConfig(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetPsychAbilityConfig`, | |||||
method: 'post', | |||||
data: params , | |||||
}); | |||||
} | |||||
function setIotCtlMode(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/SetIotCtlMode`, | |||||
method: 'post', | |||||
data: params, | |||||
}) | |||||
} | |||||
function getIotCtlMode(imei) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/open/OpenIot/GetIotCtlMode`, | |||||
method: 'get', | |||||
params: { imei }, | |||||
}) | |||||
} | |||||
function checkImei(params) { | |||||
return service({ | |||||
url: `${HTTP_PREFIX_CORE}/api/v1/Device/CheckImei`, | |||||
method: 'post', | |||||
data: params, | |||||
}) | |||||
} | |||||
export default APICore; | export default APICore; |
@@ -0,0 +1,25 @@ | |||||
import axios from 'axios'; | |||||
import prefix from '@/store/prefix'; | |||||
const baseUrl = process.env.VUE_APP_BASE_API; | |||||
const service = axios.create({ | |||||
baseURL: baseUrl, | |||||
}); | |||||
service.interceptors.request.use( | |||||
request => { | |||||
/* if (localStorage.getItem(prefix + 'gatewayToken')) { | |||||
request.headers.AccessToken = localStorage.getItem(prefix + 'gatewayToken'); | |||||
} */ | |||||
return request; | |||||
}, | |||||
); | |||||
export const APIIot = { | |||||
getdeviceinfo | |||||
} | |||||
function getdeviceinfo(params) { | |||||
return service({ | |||||
url: `${baseUrl}iotservice/getdeviceinfo`, | |||||
method: 'post', | |||||
data: params | |||||
}) | |||||
} | |||||
export default APIIot; |
@@ -0,0 +1,16 @@ | |||||
.custom-cell { | |||||
.van-cell { | |||||
padding: 10px 5px !important; | |||||
.van-cell__title { | |||||
width: 150px !important; | |||||
text-align: left !important; | |||||
} | |||||
.van-cell__value { | |||||
/* width: 200px !important; */ | |||||
/* height: 60px !important; */ | |||||
text-align: left !important; | |||||
padding-left: 10px; | |||||
/* overflow: scroll; */ | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,58 @@ | |||||
<!-- | |||||
* @Date: 2023-10-12 10:07:08 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-13 11:32:14 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\components\custom-cell\index.vue | |||||
* @description: | |||||
--> | |||||
<template> | |||||
<div class="custom-cell"> | |||||
<van-cell-group> | |||||
<van-cell :title="title" :value="value" @click="onClick" /> | |||||
</van-cell-group> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { isNotNull} from "@/utils/index"; | |||||
export default { | |||||
name: 'custom-cell', | |||||
props: { | |||||
title: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
value: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: ()=> [] | |||||
}, | |||||
click: { | |||||
type: String, | |||||
default: '' | |||||
} | |||||
}, | |||||
data(){ | |||||
return { | |||||
} | |||||
}, | |||||
methods: { | |||||
onClick() { | |||||
if(isNotNull(this.click)) { | |||||
console.log(this.click); | |||||
this.$router.push({ | |||||
name: this.click | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
@import "./index.scss"; | |||||
</style> |
@@ -0,0 +1,12 @@ | |||||
.charDom { | |||||
position: relative; | |||||
//屏幕大于750 或者小于1440 | |||||
@media screen and (max-width: 1920px) and (min-width: 750px){ | |||||
height: 100px; | |||||
width: 100%; | |||||
} | |||||
@media screen and (max-width: 750px) and (min-width: 200px){ | |||||
height: 300px; | |||||
width: 100%; | |||||
} | |||||
} |
@@ -0,0 +1,67 @@ | |||||
<!-- | |||||
* @Date: 2023-10-10 15:32:47 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-10 17:26:42 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\components\echarts\index.vue | |||||
* @description: | |||||
--> | |||||
<template> | |||||
<div :ref="id" id="charDom" class="charDom"/> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: 'Echart', | |||||
props: { | |||||
option: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
id: { | |||||
type: String, | |||||
default: 'charDom' | |||||
}, | |||||
}, | |||||
data(){ | |||||
return { | |||||
chart: null, | |||||
} | |||||
}, | |||||
watch: { | |||||
option: { | |||||
handler(val) { | |||||
this.chart.setOption(this.option) | |||||
}, | |||||
deep: true | |||||
} | |||||
}, | |||||
created() {}, | |||||
mounted() { | |||||
this.renderCharts(); | |||||
}, | |||||
beforeDestroy() { | |||||
// 销毁echarts实例 | |||||
/* this.chart.dispose() | |||||
this.chart = null */ | |||||
}, | |||||
methods: { | |||||
// 初始化 | |||||
renderCharts() { | |||||
this.chart = this.$echarts.init(this.$refs[this.id]); | |||||
console.log("初始化中"); | |||||
if (this.option) { | |||||
this.chart.setOption(this.option) | |||||
}; | |||||
const _this = this; | |||||
// 注册点击事件 | |||||
this.chart.on('click', function(params) { | |||||
_this.$emit('onClick', params) | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
@import "./index.scss"; | |||||
</style> |
@@ -0,0 +1,37 @@ | |||||
.table-container { | |||||
table { | |||||
position: relative; | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
border-spacing: 0; | |||||
empty-cells: show; | |||||
border: .5px solid #e9e9e9; | |||||
overflow: scroll; | |||||
} | |||||
table th { | |||||
background: #f7f7f7; | |||||
color: #5c6b77; | |||||
font-weight: 600; | |||||
white-space: nowrap; | |||||
} | |||||
table td, | |||||
table th { | |||||
border: .5px solid #e9e9e9; | |||||
text-align: left; | |||||
@media screen and (max-width: 1920px) and (min-width: 550px){ | |||||
padding: 4px; | |||||
} | |||||
@media screen and (max-width: 550px) and (min-width: 200px){ | |||||
font-size: 16px; | |||||
padding: 8px; | |||||
} | |||||
} | |||||
tbody { | |||||
height: 50px; | |||||
overflow: scroll; | |||||
} | |||||
} |
@@ -0,0 +1,74 @@ | |||||
<!-- | |||||
* @Date: 2023-10-10 17:38:30 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-11 17:05:31 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\components\tables\index.vue | |||||
* @description: | |||||
--> | |||||
<template> | |||||
<div class="table-container"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th | |||||
v-for="(item, key) in columns" | |||||
:key="key" | |||||
>{{ item.title }}</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr | |||||
v-for="(row, key1) in data" | |||||
:key="key1" | |||||
> | |||||
<td | |||||
v-for="(col, key2) in columns" | |||||
:key="key2" | |||||
:style="{'width': col.width}" | |||||
> | |||||
{{ row[col.key] }} | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: '', | |||||
props: { | |||||
height: { | |||||
type: String, | |||||
default: '', | |||||
}, | |||||
columns: { | |||||
type: Array, | |||||
require: true, | |||||
default(){ | |||||
return [] | |||||
} | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
require: true, | |||||
default(){ | |||||
return [] | |||||
} | |||||
} | |||||
/* row: { | |||||
type: Array, | |||||
default: [] | |||||
} */ | |||||
}, | |||||
data(){ | |||||
return { | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
@import "./index.scss"; | |||||
</style> |
@@ -1,11 +1,11 @@ | |||||
/* | /* | ||||
* @Date: 2021-11-20 10:26:39 | * @Date: 2021-11-20 10:26:39 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-10-09 09:38:30 | |||||
* @LastEditTime: 2023-10-11 17:39:54 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\config\models.js | * @FilePath: \TelpoH5FrontendWeb\src\config\models.js | ||||
* @description: | * @description: | ||||
*/ | */ | ||||
export const VERSION_MODEL = '1.0.89F'; //版本号 | |||||
export const VERSION_MODEL = '1.0.90F'; //版本号 | |||||
export const IMAGE_URL = { | export const IMAGE_URL = { | ||||
production: 'http://zfb.ssjlai.com/web/', | production: 'http://zfb.ssjlai.com/web/', | ||||
test: 'http://zfb.ssjlai.com/web/', | test: 'http://zfb.ssjlai.com/web/', | ||||
@@ -60,4 +60,27 @@ export const EmotionModel = { | |||||
}; | }; | ||||
//心理健康相关接口地址 | //心理健康相关接口地址 | ||||
export const PsyBaseUrl = process.env.NODE_ENV === 'production' ? 'https://dbmq.rzliot.com/auth_heart' : 'https://dbmq.rzliot.com/heart'; | |||||
export const PsyBaseUrl = process.env.NODE_ENV === 'production' ? 'https://dbmq.rzliot.com/auth_heart' : 'https://dbmq.rzliot.com/heart'; | |||||
// 设备耗电情况 | |||||
export const DEVICE_POWER = { | |||||
// 电量 | |||||
BatteryLevel: { | |||||
title: '设备电量值', | |||||
value: 'BatteryLevel', | |||||
type: 1, | |||||
}, | |||||
// 信号强度 | |||||
status: { | |||||
title: '信号强度', | |||||
value: 'status', | |||||
type: 2, | |||||
}, | |||||
// 离线行为 | |||||
Offline: { | |||||
title: '设备离线行为', | |||||
value: 'offline', | |||||
type: 3, | |||||
} | |||||
} |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* @Date: 2022-01-19 10:08:26 | * @Date: 2022-01-19 10:08:26 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-09-20 14:15:47 | |||||
* @LastEditTime: 2023-10-11 15:36:55 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\main.js | * @FilePath: \TelpoH5FrontendWeb\src\main.js | ||||
* @description: | * @description: | ||||
*/ | */ | ||||
@@ -58,6 +58,9 @@ import { | |||||
Toast, | Toast, | ||||
ActionSheet, | ActionSheet, | ||||
Progress, | Progress, | ||||
DropdownMenu, | |||||
DropdownItem, | |||||
TreeSelect, | |||||
} from 'vant'; //按需加载vant组件 | } from 'vant'; //按需加载vant组件 | ||||
Vue | Vue | ||||
@@ -101,6 +104,9 @@ Vue | |||||
.use(Toast) | .use(Toast) | ||||
.use(ActionSheet) | .use(ActionSheet) | ||||
.use(Progress) | .use(Progress) | ||||
.use(DropdownMenu) | |||||
.use(DropdownItem ) | |||||
.use(TreeSelect) | |||||
Vue.config.productionTip = false; | Vue.config.productionTip = false; | ||||
Vue.config.devtools = true; | Vue.config.devtools = true; | ||||
@@ -1,7 +1,14 @@ | |||||
/* | |||||
* @Date: 2023-09-21 09:54:53 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-13 11:30:23 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\router\index.js | |||||
* @description: | |||||
*/ | |||||
/* | /* | ||||
* @Date: 2023-06-01 18:41:50 | * @Date: 2023-06-01 18:41:50 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-09-20 11:15:50 | |||||
* @LastEditTime: 2023-10-10 15:56:50 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\router\index.js | * @FilePath: \TelpoH5FrontendWeb\src\router\index.js | ||||
* @description: | * @description: | ||||
*/ | */ | ||||
@@ -59,6 +66,12 @@ const routes = [ | |||||
{ path: '/aiCallAlarm', name: 'aiCallAlarm', component: resolve => require(['@/views/ai-call-alarm'], resolve) }, | { path: '/aiCallAlarm', name: 'aiCallAlarm', component: resolve => require(['@/views/ai-call-alarm'], resolve) }, | ||||
// 物联网卡错误页 | // 物联网卡错误页 | ||||
{ path: '/iotcardError', name: 'iotcardError', component: resolve => require(['@/views/error-pages/iotcard-error'], resolve) }, | { path: '/iotcardError', name: 'iotcardError', component: resolve => require(['@/views/error-pages/iotcard-error'], resolve) }, | ||||
// c1(4g管理后台)设备耗电情况页面 | |||||
{ path: '/devicePower', name: 'devicePower', component: resolve => require(['@/views/gps-card-frontend/device-power'], resolve) }, | |||||
// c1(4g管理后台)设备设置页面 | |||||
{ path: '/deviceSetting', name: 'deviceSetting', component: resolve => require(['@/views/gps-card-frontend/device-setting'], resolve) }, | |||||
// c1(4g管理后台)涉水区域白名单 | |||||
{ path: '/drownWhiteList', name: 'drownWhiteList', component: resolve => require(['@/views/gps-card-frontend/drown-white-list'], resolve) }, | |||||
]; | ]; | ||||
const router = new VueRouter({ | const router = new VueRouter({ | ||||
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* @Date: 2022-08-17 16:18:02 | * @Date: 2022-08-17 16:18:02 | ||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @LastEditTime: 2023-06-19 11:26:22 | |||||
* @LastEditTime: 2023-10-13 14:45:16 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\store\index.js | * @FilePath: \TelpoH5FrontendWeb\src\store\index.js | ||||
* @description: | * @description: | ||||
*/ | */ | ||||
@@ -13,7 +13,7 @@ import { isNotNull } from '@/utils'; | |||||
Vue.use(Vuex); | Vue.use(Vuex); | ||||
export default new Vuex.Store({ | export default new Vuex.Store({ | ||||
state: { | state: { | ||||
imei: '', //例子 | |||||
imei: '', // | |||||
gatewayToken: '', //gateway接口token | gatewayToken: '', //gateway接口token | ||||
token: '', | token: '', | ||||
wxAuthCode: '', | wxAuthCode: '', | ||||
@@ -22,6 +22,7 @@ export default new Vuex.Store({ | |||||
isFromWx: null, | isFromWx: null, | ||||
ssjlToken: '', | ssjlToken: '', | ||||
fromSsjl: '', | fromSsjl: '', | ||||
active: null, //点击左边树形图下标 | |||||
}, | }, | ||||
mutations: { | mutations: { | ||||
imei(state, imei) { | imei(state, imei) { | ||||
@@ -60,6 +61,10 @@ export default new Vuex.Store({ | |||||
state.fromSsjl = fromSsjl; | state.fromSsjl = fromSsjl; | ||||
window.localStorage[prefix + 'fromSsjl'] = fromSsjl; | window.localStorage[prefix + 'fromSsjl'] = fromSsjl; | ||||
}, | }, | ||||
active(state, active) { | |||||
state.active = active; | |||||
window.localStorage[prefix + 'active'] = active; | |||||
}, | |||||
}, | }, | ||||
getters: { | getters: { | ||||
imei: state => { | imei: state => { | ||||
@@ -98,6 +103,10 @@ export default new Vuex.Store({ | |||||
if (state.fromSsjl != '') return state.fromSsjl; | if (state.fromSsjl != '') return state.fromSsjl; | ||||
return window.localStorage[prefix + 'fromSsjl'] == null ? '' : window.localStorage[prefix + 'fromSsjl']; | return window.localStorage[prefix + 'fromSsjl'] == null ? '' : window.localStorage[prefix + 'fromSsjl']; | ||||
}, | }, | ||||
active: state => { | |||||
if (state.active != '') return state.active; | |||||
return window.localStorage[prefix + 'active'] == null ? '' : window.localStorage[prefix + 'active']; | |||||
}, | |||||
}, | }, | ||||
actions: {}, | actions: {}, | ||||
modules: {} | modules: {} |
@@ -0,0 +1,59 @@ | |||||
.device-power { | |||||
position: relative; | |||||
/* overflow: hidden; */ | |||||
overflow: hidden; | |||||
height: 100vh; | |||||
background-color: #fff; | |||||
.top { | |||||
padding: 10px 15px; | |||||
text-align: left; | |||||
@media screen and (max-width: 550px) and (min-width: 200px){ | |||||
font-size: 16px; | |||||
} | |||||
} | |||||
.action { | |||||
display: flex; | |||||
justify-content: space-between; | |||||
@media screen and (max-width: 550px) and (min-width: 200px){ | |||||
justify-content: space-around; | |||||
} | |||||
align-items: center; | |||||
padding: 0 10px; | |||||
.left { | |||||
border: .5px solid $lineGray;; | |||||
.van-dropdown-menu { | |||||
.van-dropdown-menu__bar { | |||||
/* border: .5px solid #000; */ | |||||
.van-dropdown-menu__item { | |||||
min-width: 150px !important; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.right { | |||||
.btn { | |||||
&.active { | |||||
color: $blue; | |||||
border: .5px solid $blue; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.details-container{ | |||||
position: relative; | |||||
padding: 10px; | |||||
@media screen and (max-width: 1920px) and (min-width: 550px){ | |||||
height: 100px; | |||||
overflow: scroll; | |||||
} | |||||
@media screen and (max-width: 550px) and (min-width: 200px){ | |||||
max-height: 500px; | |||||
overflow: scroll; | |||||
} | |||||
.echart { | |||||
height: 30%; | |||||
padding: 0 5px; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,328 @@ | |||||
<!-- | |||||
* @Date: 2023-10-10 15:29:50 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-13 14:41:57 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\views\gps-card-frontend\device-power\index.vue | |||||
* @description: | |||||
--> | |||||
<template> | |||||
<div class="device-power"> | |||||
<van-nav-bar :left-arrow="true" @click-left="onNavBack"> | |||||
<template #left> | |||||
<van-icon name="arrow-left" size="24" style="padding: 0"/> | |||||
<span>返回</span> | |||||
</template> | |||||
</van-nav-bar> | |||||
<div class="top"> | |||||
<p>查看数据</p> | |||||
</div> | |||||
<div class="action"> | |||||
<div class="left"> | |||||
<van-dropdown-menu> | |||||
<van-dropdown-item style="min-width: 150px" v-model="dayValue" :options="dayOption" @change="onChange" /> | |||||
</van-dropdown-menu> | |||||
</div> | |||||
<div class="right"> | |||||
<div class="btn-container"> | |||||
<van-button :class="['btn', {active: btnActive ===item.index }]" @click="onClickBtn(item.index)" v-for="(item, index) in btnList" :key="index">{{ item.text }}</van-button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="details-container" v-if="data.length > 0"> | |||||
<Echart :option="chartOption" v-show="btnActive === 0"/> | |||||
<Table :columns="titleList" :data="tableData" v-show="btnActive === 1"/> | |||||
</div> | |||||
<div class="details-container no-data" v-else> | |||||
<van-empty image="error" description="暂无数据" /> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import Echart from '@/components/echarts'; | |||||
import Table from '@/components/tables'; | |||||
import APIIot from '@/api/iot'; | |||||
import { DEVICE_POWER } from "@/config/models"; | |||||
import axios from 'axios'; | |||||
export default { | |||||
name:'', | |||||
components: { Echart,Table }, | |||||
data(){ | |||||
return { | |||||
dayValue: 7, | |||||
dayOption: [ | |||||
{ text: '7天', value: 7 }, | |||||
{ text: '30天', value: 30 }, | |||||
], | |||||
btnList: [ | |||||
{ text: '图表', index: 0 }, | |||||
{ text: '表格', index: 1 }, | |||||
], | |||||
btnActive: 0, | |||||
chartOption: {}, | |||||
titleList: [ | |||||
{ title: '时间', width: '40%', key: 'time'}, | |||||
{ title: '原始值', width: '60%', key: 'value' }, | |||||
], | |||||
tableData: [], | |||||
echarts: { | |||||
title: '', | |||||
type: '', | |||||
}, | |||||
data: [], | |||||
xAxisData: [], | |||||
filterData: [], | |||||
yAxisObject: {} | |||||
} | |||||
}, | |||||
created() { | |||||
}, | |||||
mounted() { | |||||
this.loadParams(); | |||||
}, | |||||
methods: { | |||||
loadParams() { | |||||
let params = this.$route.query; | |||||
if(params) { | |||||
this.echarts.title = DEVICE_POWER[params.title].title; | |||||
this.echarts.type = DEVICE_POWER[params.title].value; | |||||
// 获取接口数据 | |||||
this.getData(); | |||||
} else { | |||||
// todo跳转404页面 | |||||
} | |||||
}, | |||||
getData() { | |||||
this.$toast.loading(); | |||||
let reqBody = { | |||||
days: String(this.dayValue), | |||||
identifier: this.echarts.type, | |||||
imei: /* '861281060086216' *//* '862838050029479' */this.$store.getters.imei | |||||
}; | |||||
// 线上地址 | |||||
let baseUrl = process.env.VUE_APP_BASE_API; | |||||
let reqUrl = `${baseUrl}iotservice/getdeviceinfo`; | |||||
// 开启代理如下 | |||||
/* let reqUrl = `/api/id/getdeviceinfo`; */ | |||||
axios.post(`${reqUrl}`, reqBody).then(res => { | |||||
let data = res.data; | |||||
if(data.code === 200) { | |||||
if(this.echarts.type === 'BatteryLevel' || this.echarts.type === 'status') { | |||||
this.filterData = data[this.echarts.type].data.list.propertyInfo; | |||||
} else if(this.echarts.type === 'status') { | |||||
this.filterData = data[this.echarts.type].data.list.propertyInfo; | |||||
} else if(this.echarts.type === 'offline') { | |||||
this.filterData = data.Offline.data; | |||||
} | |||||
if(this.echarts.type === 'status') { | |||||
// 信号强度 | |||||
this.yAxisObject = { | |||||
type: "value", | |||||
/* max: 4, | |||||
min: 0, | |||||
interval: 1, | |||||
splitNumber : 1, | |||||
boundaryGap : [ '5%', '5%' ], */ | |||||
} | |||||
this.titleList = [ | |||||
{ title: '时间', width: '40%', key: 'time'}, | |||||
{ title: '原始值', width: '60%', key: 'value' }, | |||||
], | |||||
// 表格则要显示全部数据 | |||||
this.tableData = this.filterData.map(item => { | |||||
return { | |||||
value: item.value, | |||||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm") | |||||
} | |||||
}); | |||||
// 图表筛选过滤只显示 rssi <= 2的数据 | |||||
this.data = this.filterData.map(item => { | |||||
// 序列化json | |||||
let json = JSON.parse(item.value); | |||||
return { | |||||
value: json.rssi, | |||||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm"), | |||||
type: 'status' | |||||
} | |||||
}).filter(f => { | |||||
return f.value <=2; | |||||
}) | |||||
console.log(this.data); | |||||
} else if (this.echarts.type === 'offline') { | |||||
// 设备离线次数 | |||||
this.titleList = [ | |||||
{ title: '时间', width: '60%', key: 'time'}, | |||||
{ title: '离线次数', width: '40%', key: 'value' }, | |||||
], | |||||
this.yAxisObject = { | |||||
type: "value", | |||||
/* max: 10, | |||||
min: 0, | |||||
interval: 1, | |||||
splitNumber : 1, | |||||
boundaryGap : [ '5%', '5%' ], */ | |||||
}; | |||||
this.data = this.filterData.map(item => { | |||||
return { | |||||
/* value: item.value, */ | |||||
time: item.createTime.slice(0,10), | |||||
day: item.createTime.slice(0,10), | |||||
type: 'offline' | |||||
} | |||||
}).reduce((accumulator, currentValue) => { | |||||
if (accumulator.find(obj => obj.day === currentValue.day)) { | |||||
accumulator.find(obj => obj.day === currentValue.day).value++; | |||||
} else { | |||||
accumulator.push({ day: currentValue.day, time: currentValue.time, value: 1, type: 'offline' }); | |||||
} | |||||
return accumulator; | |||||
}, []).sort(function(date1, date2) { | |||||
// 日期升序排序 | |||||
return date2.time < date1.time ? 1 : -1 | |||||
}); | |||||
this.tableData = this.filterData.map(item => { | |||||
return { | |||||
/* value: item.value, */ | |||||
time: item.createTime.slice(0,10), | |||||
day: item.createTime.slice(0,10) | |||||
} | |||||
}).reduce((accumulator, currentValue) => { | |||||
// 筛选遍历数据,获取相同日期的数据,计算出现的次数后重新累加组合到一个新的数组里面 | |||||
if (accumulator.find(obj => obj.day === currentValue.day)) { | |||||
accumulator.find(obj => obj.day === currentValue.day).value++; | |||||
} else { | |||||
accumulator.push({ day: currentValue.day, time: currentValue.time, value: 1 }); | |||||
} | |||||
return accumulator; | |||||
}, []).sort(function(date1, date2) { | |||||
// 日期升序排序 | |||||
return date2.time < date1.time ? 1 : -1 | |||||
}); | |||||
} else { | |||||
this.titleList = [ | |||||
{ title: '时间', width: '40%', key: 'time'}, | |||||
{ title: '电量', width: '60%', key: 'value' }, | |||||
], | |||||
this.yAxisObject = { | |||||
type: "value", | |||||
max: 100, | |||||
min: 0, | |||||
interval: 20, | |||||
splitNumber : 1, | |||||
boundaryGap : [ '5%', '5%' ], | |||||
} | |||||
this.data = this.filterData.map(item => { | |||||
return { | |||||
value: item.value, | |||||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm"), | |||||
} | |||||
}); | |||||
this.tableData = this.filterData.map(item => { | |||||
return { | |||||
value: item.value, | |||||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm") | |||||
} | |||||
}); | |||||
} | |||||
this.xAxisData = this.data.map(item => { | |||||
return this.$dayjs(item.time).format("MM/DD"); | |||||
}) | |||||
this.chartOption = { | |||||
title: { | |||||
text: this.echarts.title, | |||||
}, | |||||
xAxis: { | |||||
type: "category", | |||||
axisLine: { | |||||
show: false | |||||
}, | |||||
textStyle: { | |||||
fontSize: 10 | |||||
}, | |||||
axisTick: { | |||||
show: false | |||||
}, | |||||
splitLine: { | |||||
show: false, | |||||
lineStyle: { | |||||
color: "#ddd", | |||||
width: 2 | |||||
} | |||||
}, | |||||
nameLocation: 'center', | |||||
axisLabel: { | |||||
show: true, | |||||
fontSize: 12, | |||||
showMinLabel: true, //显示最小值 | |||||
showMaxLabel: true, //显示最大值 | |||||
}, | |||||
data: this.xAxisData | |||||
}, | |||||
yAxis: this.yAxisObject, | |||||
series: [ | |||||
{ | |||||
type: "line", | |||||
data: this.data, | |||||
/* areaStyle: {}, */ | |||||
}, | |||||
], | |||||
dataZoom: [ | |||||
{ | |||||
start: 0, | |||||
end: 100, | |||||
textStyle: { | |||||
color: "#FFF", | |||||
fontSize: 14 | |||||
}, | |||||
show: true, | |||||
height: 20, | |||||
bottom: 5, | |||||
handleStyle: { | |||||
borderWidth: 1, | |||||
borderCap: "square" | |||||
} | |||||
} | |||||
], | |||||
tooltip: { | |||||
trigger: "axis", | |||||
textStyle: { | |||||
fontSize: 14, | |||||
align: "center" | |||||
}, | |||||
formatter: function(params) { | |||||
console.log(params); | |||||
return `${params[0].marker}${params[0].data.time}</br> | |||||
${ params[0].data.type === 'offline' ? '离线次数:' + params[0].data.value + '次' : | |||||
params[0].data.type === 'status' ? 'rssi值:' + params[0].data.value : | |||||
'电量:' + params[0].data.value}` | |||||
} | |||||
}, | |||||
} | |||||
} | |||||
}).catch(() => { | |||||
}).finally(() => { | |||||
this.$toast.clear(); | |||||
}) | |||||
}, | |||||
onClickBtn(value) { | |||||
this.btnActive = value; | |||||
this.getData(); | |||||
}, | |||||
onChange(value) { | |||||
this.dayValue = value; | |||||
this.getData(); | |||||
}, | |||||
onNavBack() { | |||||
this.$router.push({ | |||||
name: 'deviceSetting' | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
@import "./index.scss"; | |||||
</style> |
@@ -0,0 +1,15 @@ | |||||
.device-setting { | |||||
position: relative; | |||||
height: 100vh; | |||||
width: 100%; | |||||
overflow: hidden; | |||||
background-color: #fff; | |||||
.tree-select { | |||||
position: relative; | |||||
padding: 10px; | |||||
@media screen and (max-width: 550px) and (min-width: 200px){ | |||||
font-size: 16px; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,449 @@ | |||||
<!-- | |||||
* @Date: 2023-10-11 15:34:12 | |||||
* @LastEditors: JinxChen | |||||
* @LastEditTime: 2023-10-13 15:01:00 | |||||
* @FilePath: \TelpoH5FrontendWeb\src\views\gps-card-frontend\device-setting\index.vue | |||||
* @description: | |||||
--> | |||||
<template> | |||||
<div classs="device-setting"> | |||||
<div class="tree-select"> | |||||
<van-tree-select :items="settingItems" :main-active-index.sync="active" :height="clientHeight" @click-nav="onCkickNav"> | |||||
<template #content> | |||||
<div class="item" v-for="(item, index) in settingItems" :key="index" v-show="item.index === active"> | |||||
<div class="item-setting" v-for="(child, index) in item.data" :key="index"> | |||||
<customCell :title="child.name" :value="child.value" :click="child.router"/> | |||||
</div> | |||||
</div> | |||||
<div class="power" v-show="active === 10 || active === 11 || active === 12"> | |||||
<van-button @click="onClick(active)">点击查看</van-button> | |||||
</div> | |||||
</template> | |||||
</van-tree-select> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import customCell from '@/components/custom-cell/index'; | |||||
import { isNotNull} from "@/utils/index"; | |||||
import APICore from "@/api/core"; | |||||
export default { | |||||
name:'', | |||||
components: { customCell }, | |||||
data(){ | |||||
return { | |||||
active: 0, | |||||
settingItems: [ | |||||
{ text: '监护角色', index: 0, data: [],}, | |||||
{ text: '场景模式', index: 1, data: []}, | |||||
{ text: '加强省电模式', index: 2, data: []}, | |||||
{ text: '定位监测', index: 3, data: []}, | |||||
{ text: '危险区域监测', index: 4, data: [] }, | |||||
{ text: '健康监测', index: 5, data: []}, | |||||
{ text: '血压监测', index: 6, data: []}, | |||||
{ text: '心理监测', index: 7, data: []}, | |||||
{ text: '佩戴监测', index: 8, data: []}, | |||||
/* { text: '久坐提醒', index: 9, data: []}, */ | |||||
{ text: '上报周期', index: 10, data: []}, | |||||
{ text: '电量查看', index: 11, data: []}, | |||||
{ text: '设备信号强度查看', index: 12, data: []}, | |||||
{ text: '设备行为日志查看', index: 13, data: []}, | |||||
], | |||||
dateList: [], //时间列表 | |||||
clientHeight: '', //当前窗口可视页面高度 | |||||
} | |||||
}, | |||||
computed: { | |||||
imei() { | |||||
return this.$store.getters.imei/* '861281060086216' */; | |||||
}, | |||||
}, | |||||
created() { | |||||
this.getAuth(); | |||||
this.getUrlQueryParams(); | |||||
}, | |||||
mounted() { | |||||
this.$toast.loading({message: "加载中"}); | |||||
this.getWatchConfig(); | |||||
this.getIotCtlMode(); | |||||
this.getLocationConfig(); | |||||
this.getDrownConfig(); | |||||
this.getHealthConfig(); | |||||
this.getBloodConfig(); | |||||
this.getPsychAbilityConfig(); | |||||
this.getNowearConfig(); | |||||
this.getUploadConfig(); | |||||
this.clientHeight = document.documentElement.clientHeight; | |||||
this.active = Number(this.$store.getters.active) || 0; | |||||
this.$toast.success({message: "加载完成"}); | |||||
}, | |||||
methods: { | |||||
// 获取b端接口的token | |||||
getAuth() { | |||||
let manufactorId = "5bf13062-a41e-4d00-ba14-1101aad12650"; | |||||
APICore.getAuth({ manufactorId: manufactorId }).then(res => { | |||||
this.$store.commit("gatewayToken", res.data.data); | |||||
}); | |||||
}, | |||||
getUrlQueryParams() { | |||||
// 从url中获取参数并缓存 | |||||
let params = this.$route.query; | |||||
if (isNotNull( params )) { | |||||
// 首次进入且正确传参 | |||||
//this.imei = params.imei; | |||||
if(params.accessToken) {this.$store.commit('accessToken', params.accessToken); } | |||||
this.$store.commit('imei', params.imei); | |||||
} | |||||
}, | |||||
// 获取设备场景模式参数 | |||||
getWatchConfig() { | |||||
APICore.getWatchConfig({imei: this.imei}).then(res => { | |||||
let data = res.data; | |||||
if(data) { | |||||
const modeId = data.modeId; | |||||
const roleId = data.roleId; | |||||
this.modeId = data.modeId; | |||||
this.roleId = roleId; | |||||
this.settingItems[0].text = `监护角色(${roleId === 1 ? '学生' : '老人'})`; | |||||
this.settingItems[1].text = `场景模式(${this.getModeById(modeId)})`; | |||||
} else { | |||||
this.settingItems[0].text = `监护角色(学生)`; | |||||
this.settingItems[1].text = `场景模式(无)`; | |||||
/* this.modeId = 1; | |||||
this.roleId = 1; */ | |||||
} | |||||
}) | |||||
}, | |||||
// 通过模式id获取场景模式 | |||||
getModeById(id) { | |||||
if(id === 1) { | |||||
return '标准' | |||||
} else if (id === 2) { | |||||
return '省电' | |||||
} else { | |||||
return '个性' | |||||
} | |||||
}, | |||||
// 组装选项数据 | |||||
concatTitle(title, status, power){ | |||||
return `${title}(${status}) (${power})` | |||||
}, | |||||
// 获取加强省电模式参数配置 | |||||
getIotCtlMode() { | |||||
APICore.getIotCtlMode(this.imei).then(res => { | |||||
let data = res.data.data; | |||||
console.log("data", data); | |||||
if(data) { | |||||
this.checked = data.mode === 1; | |||||
this.settingItems[2].text = this.concatTitle('加强省电模式', data.mode === 1 ? '打开' : '关闭', data.mode === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[2].data = [ | |||||
{ name: '开启状态:', value: data.enabled === 1 ? '打开': '关闭' }, | |||||
]; | |||||
} else { | |||||
this.settingItems[2].text = this.concatTitle('加强省电模式','关闭', '耗电低'); | |||||
} | |||||
}) | |||||
}, | |||||
// 获取设备定位参数 | |||||
getLocationConfig() { | |||||
APICore.getLocationConfig({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
console.log(data); | |||||
if(data) { | |||||
this.settingItems[3].text = this.concatTitle('定位监测', data.enabled === 1 ? '打开': '关闭', data.enabled === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[3].data = [ | |||||
{ name: '开启状态:', value: data.enabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: data.sampleinteval + '分钟' }, | |||||
]; | |||||
} else { | |||||
this.settingItems[3].text = this.concatTitle('定位监测','关闭', '耗电低'); | |||||
} | |||||
}) | |||||
}, | |||||
// 获取免告警水域 | |||||
getDrownReportFilterQuery() { | |||||
APICore.getDrownReportFilterQuery({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
if(data) { | |||||
let json = {}; | |||||
for(var i=0; i<data.length; i++){ | |||||
json[i] = data[i]; | |||||
} | |||||
this.drownWhite = JSON.stringify(json); | |||||
} | |||||
}) | |||||
}, | |||||
// 获取设备危险区域参数 | |||||
getDrownConfig() { | |||||
APICore.getDrownConfig({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
if(data) { | |||||
this.settingItems[4].text = this.concatTitle('危险区域监测', data.enabled === 1 ? '打开': '关闭', data.enabled === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[4].data = [ | |||||
{ name: '涉水监测:', value: data.enabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: data.config.intervallvl1 + data.config.intervallvl2 + '分钟' }, | |||||
{ name: '告警阈值:', value: data.config.warningdistance + '米' }, | |||||
{ name: '涉水停留告警间隔:', value: (data.config.distancelvl2 / 60) + '分钟' }, | |||||
{ name: '告警提示持续次数:', value: data.config.warningtimes + '次' }, | |||||
{ name: '首次告警逗留设置:', value: data.config.delaytimes + '次' }, | |||||
{ name: '时速免告警(≥):', value: data.config.ignorespeed + '公里' }, | |||||
{ name: '免告警水域:', value: '查看', router: 'drownWhiteList' }, | |||||
{ name: '告警方式:', value: `${data.config.vibrateenabled === 1 ? '震动' : '无'} , ${data.config.lcdenabled === 1 ? '亮屏' : '无'} , ${data.config.musicenabled === 1 ? '声音' : '无'}`}, | |||||
]; | |||||
} else { | |||||
this.settingItems[4].text = this.concatTitle('危险区域监测','关闭', '耗电低'); | |||||
this.settingItems[4].data = []; | |||||
} | |||||
}) | |||||
}, | |||||
// 格式化某些特殊参数值的时间显示方式 | |||||
formatInteval(value) { | |||||
return value >= 360 ? (value / 60) + '小时' : value + '分钟' | |||||
}, | |||||
// 获取设备健康参数 | |||||
getHealthConfig() { | |||||
APICore.getHealthConfig({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
if(data) { | |||||
let healthEnablelist = [ | |||||
{ enabled: data.config.heartrateenabled}, | |||||
{ enabled: data.config.spo2enabled}, | |||||
{ enabled: data.config.temperatureenabled}, | |||||
]; | |||||
let config = data.config; | |||||
// 获取健康设置打开的次数 | |||||
const healthSettingCount = healthEnablelist.reduce((acc, cur) => cur.enabled === 1 ? ++acc : acc, 0); | |||||
this.settingItems[5].text = this.concatTitle('健康监测', healthSettingCount >= 3 ? '打开' | |||||
: healthSettingCount >= 1 ? '部分' | |||||
: '关闭', healthSettingCount > 2 ? '耗电高': healthSettingCount === 2 ? '耗电中': '耗电低'); | |||||
this.settingItems[5].data = [ | |||||
{ name: '体温监测:', value: config.temperatureenabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: this.formatInteval(config.temperatureinteval) }, | |||||
{ name: '告警阈值-高温:', value: (config.temperaturemaxvalue / 10) + '度' }, | |||||
/* { name: '告警阈值-低温:', value: config.temperatureminvalue + '度' }, */ | |||||
{ name: '告警方式:', value: `${config.temperaturevibrateenabled === 1 ? '震动' : '无'} , ${config.temperaturelcdenabled === 1 ? '亮屏' : '无'}`}, | |||||
{ name: '心率监测:', value: config.heartrateenabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: this.formatInteval(config.heartrateinteval) }, | |||||
{ name: '告警阈值-上限:', value: config.heartratemaxvalue + '次' }, | |||||
{ name: '告警阈值-下限:', value: config.heartrateminvalue + '次' }, | |||||
{ name: '告警方式:', value: `${config.heartratevibrateenabled === 1 ? '震动' : '无'} , ${config.heartratelcdenabled === 1 ? '亮屏' : '无'}`}, | |||||
{ name: '血氧监测:', value: config.spo2enabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: this.formatInteval(config.spo2inteval) }, | |||||
{ name: '告警阈值-低于:', value: config.spo2minvalue + '%' }, | |||||
/* { name: '告警阈值-低温:', value: config.temperatureminvalue + '度' }, */ | |||||
{ name: '告警方式:', value: `${config.spo2vibrateenabled === 1 ? '震动' : '无'} , ${config.spo2lcdenabled === 1 ? '亮屏' : '无'}`}, | |||||
] | |||||
} else { | |||||
this.settingItems[5].text = this.concatTitle('健康监测','关闭', '耗电低'); | |||||
this.settingItems[5].data = []; | |||||
} | |||||
}) | |||||
}, | |||||
// 获取血压监测参数设置 | |||||
getBloodConfig() { | |||||
APICore.getBloodPressConfig({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
if(data) { | |||||
this.settingItems[6].text = this.concatTitle('血压监测', data.bloodPressenabled === 1 ? '打开': '关闭', data.bloodPressenabled === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[6].data = [ | |||||
{ name: '血压监测:', value: data.bloodPressenabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: this.formatInteval(data.bloodPressinteval) }, | |||||
{ name: '告警阈值-收缩压:', value: String(data.systolicmaxvalue)}, | |||||
{ name: '告警方式:', value: `${data.bloodPressvibrateenabled === 1 ? '震动' : '无'} ,${data.bloodPresslcdenabled === 1 ? '亮屏' : '无'}`}, | |||||
] | |||||
} else { | |||||
this.settingItems[6].text = this.concatTitle('血压监测','关闭', '耗电低'); | |||||
this.settingItems[6].data = []; | |||||
} | |||||
}) | |||||
}, | |||||
// 格式化等级 | |||||
formatReminder(value) { | |||||
let text = ""; | |||||
if (value == 1) { | |||||
text = "轻度"; | |||||
} else if (value == 2) { | |||||
text = "中度"; | |||||
} else if (value == 3) { | |||||
text = "重度"; | |||||
} | |||||
return text; | |||||
}, | |||||
// 格式化监测时段 | |||||
formatTimeArea(timeArr) { | |||||
let timeToString = timeArr.map(item => { | |||||
return `{时段: ${item.time},时长:${item.duration};}`; | |||||
}); | |||||
return String(timeToString); | |||||
}, | |||||
// 获取心理监测参数设置 | |||||
getPsychAbilityConfig() { | |||||
APICore.getPsychAbilityConfig({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
if (data) { | |||||
this.settingItems[7].text = this.concatTitle('心理监测', data.enabled === 1 ? '打开': '关闭', data.enabled === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[7].data = [ | |||||
{ name: '心理监测:', value: data.enabled === 1 ? '打开': '关闭' }, | |||||
{ name: '设备显示:', value: data.device_display === 1 ? '打开': '关闭' }, | |||||
{ name: '监测时段:', value: this.formatTimeArea(data.time_area) }, | |||||
{ name: '提醒设置:', value: data.reminder_setting.enable === 1 ? '打开': '关闭' }, | |||||
{ name: '抑郁等级:', value: this.formatReminder(data.reminder_setting.setting.depressive) }, | |||||
{ name: '压力等级:', value: this.formatReminder(data.reminder_setting.setting.pressure) }, | |||||
{ name: '疲劳等级:', value: this.formatReminder(data.reminder_setting.setting.fatigue) }, | |||||
{ name: '告警方式:', value: `${data.vibrating_screen === 1 ? '震动' : '无'}, ${data.brightening_screen === 1 ? '亮屏' : '无'}`}, | |||||
] | |||||
} else { | |||||
this.settingItems[7].text = this.concatTitle('心理监测', '关闭', '耗电低'); | |||||
this.settingItems[7].data = []; | |||||
} | |||||
}) | |||||
}, | |||||
// 转换时间格式 | |||||
shiftTime(time, model) { | |||||
if(time) { | |||||
let startTime = '{' + time.slice(0,2) + ":" + time.slice(2,4); | |||||
let endTime = time.slice(4,6) + ":" + time.slice(6,8) + '}'; | |||||
let timeObj = { | |||||
startTime: startTime, | |||||
endTime: endTime, | |||||
}; | |||||
this.dateList.push(timeObj); | |||||
} | |||||
}, | |||||
// 转化时间数组 :) | |||||
fomatTimeArr(arr) { | |||||
let timeString = arr.map(item => { | |||||
return item.startTime + '-' + item.endTime | |||||
}); | |||||
return String(timeString); | |||||
}, | |||||
// 获取佩戴监测参数设置 | |||||
getNowearConfig() { | |||||
APICore.getNowearConfig({ imei: this.imei }).then(res => { | |||||
let data = res.data.data; | |||||
if(data) { | |||||
this.dateList = []; | |||||
this.shiftTime(data.timearea1, 0); | |||||
this.shiftTime(data.timearea2, 1); | |||||
this.shiftTime(data.timearea3, 2); | |||||
this.shiftTime(data.timearea4, 3); | |||||
this.shiftTime(data.timearea5, 4); | |||||
this.shiftTime(data.timearea6, 5); | |||||
this.shiftTime(data.timearea7, 6); | |||||
this.shiftTime(data.timearea8, 7); | |||||
this.shiftTime(data.timearea9, 8); | |||||
this.shiftTime(data.timearea10, 9); | |||||
this.settingItems[8].text = this.concatTitle('佩戴监测', data.enabled === 1 ? '打开': '关闭', data.enabled === 1 ? '耗电高' : '耗电低'); | |||||
this.settingItems[8].data = [ | |||||
{ name: '佩戴监测:', value: data.enabled === 1 ? '打开': '关闭' }, | |||||
{ name: '检测周期:', value: (data.interval / 60) + '分钟' }, | |||||
{ name: '检测时段:', value: this.fomatTimeArr(this.dateList)}, | |||||
{ name: '未佩戴处理方式:', value: data.mode === 1 ? '不处理': '飞行模式' }, | |||||
{ name: '佩戴提醒:', value: data.warningtimes !== 0 ? '打开' : '关闭' }, | |||||
{ name: '提醒时间间隔:', value: (data.warninginterval / 60) + '分钟' }, | |||||
{ name: '提醒次数:', value: data.warningtimes + '次'}, | |||||
{ name: '告警方式:', value: `${data.vibrateenabled === 1 ? '震动' : '无'} ,${data.lcdenabled === 1 ? '亮屏' : '无'} ,${data.soundenabled === 1 ? '声音' : '无'}`}, | |||||
] | |||||
} else { | |||||
this.settingItems[8].text = this.concatTitle('佩戴监测', '关闭', '耗电低'); | |||||
this.settingItems[8].data = []; | |||||
} | |||||
}) | |||||
}, | |||||
// 获取设备上报参数 | |||||
getUploadConfig() { | |||||
APICore.getUploadConfig({imei: this.imei}).then(res => { | |||||
const data = res.data.data; | |||||
if(data) { | |||||
this.settingItems[9].text = `上报周期(${data.uploadinteval}分钟)`; | |||||
} else { | |||||
this.settingItems[9].text = '关闭'; | |||||
} | |||||
}) | |||||
}, | |||||
// 点击左边树形图 | |||||
onCkickNav(value) { | |||||
console.log("value", value); | |||||
this.active = value; | |||||
this.$store.commit('active', value); | |||||
switch(value) { | |||||
/* case 10: | |||||
case 11: | |||||
case 12: | |||||
this.$router.push({ | |||||
name: 'devicePower', | |||||
query: { | |||||
title: `${value === 10 ? 'BatteryLevel' : value === 11 ? 'status': 'Offline'}` | |||||
} | |||||
}); | |||||
break; */ | |||||
case 0: | |||||
this.getWatchConfig(); | |||||
break; | |||||
case 1: | |||||
this.getWatchConfig(); | |||||
break; | |||||
case 2: | |||||
this.getIotCtlMode(); | |||||
break; | |||||
case 3: | |||||
this.getLocationConfig(); | |||||
break; | |||||
case 4: | |||||
this.getDrownConfig(); | |||||
break; | |||||
case 5: | |||||
this.getHealthConfig(); | |||||
break; | |||||
case 6: | |||||
this.getBloodConfig(); | |||||
break; | |||||
case 7: | |||||
this.getPsychAbilityConfig(); | |||||
break; | |||||
case 8: | |||||
this.getNowearConfig(); | |||||
break; | |||||
case 9: | |||||
this.getUploadConfig(); | |||||
break; | |||||
default: break; | |||||
} | |||||
}, | |||||
// 点击页面查看按钮 | |||||
onClick(value) { | |||||
if(value) { | |||||
this.$router.push({ | |||||
name: 'devicePower', | |||||
query: { | |||||
title: `${value === 10 ? 'BatteryLevel' : value === 11 ? 'status': 'Offline'}` | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss"> | |||||
.van-tree-select__nav-item { | |||||
padding: 15px 5px !important; | |||||
} | |||||
.van-tree-select__content { | |||||
padding: 5px; | |||||
} | |||||
.van-tree-select__nav{ | |||||
flex: 1 !important; | |||||
} | |||||
.van-tree-select__content { | |||||
@include center(); | |||||
} | |||||
</style> | |||||
<style scoped lang="scss"> | |||||
@import "./index.scss"; | |||||
</style> |
@@ -0,0 +1,148 @@ | |||||
<template> | |||||
<div class="drown-white-list"> | |||||
<van-nav-bar title="免告警水域" :border="true" left-arrow @click-left="onNavBack"/> | |||||
<div class="main"> | |||||
<div class="list" v-if="drownList.length > 0"> | |||||
<div class="item" v-for="(item, index) in drownList" :key="index"> | |||||
<p><span>poiId:{{ item.poiId }}</span></p> | |||||
<p><span>水域类型:{{ item.title }}</span></p> | |||||
<p><span>水域名称:{{ item.address }}</span></p> | |||||
<p><span>设置时间:{{ item.createTime }}</span></p> | |||||
<!-- <div class="btn-con"> | |||||
<div class="btn" @click="onDelete(item.imei, item.poiId)"> | |||||
<p>删除</p> | |||||
</div> | |||||
</div> --> | |||||
</div> | |||||
</div> | |||||
<div class="noData" v-else> | |||||
<p>暂无数据~</p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import { isNotNull} from "@/utils/index"; | |||||
import APICore from "@/api/core"; | |||||
export default { | |||||
name:'', | |||||
data(){ | |||||
return { | |||||
drownList: [], | |||||
} | |||||
}, | |||||
computed: { | |||||
imei() { | |||||
return this.$store.getters.imei; | |||||
}, | |||||
}, | |||||
mounted() { | |||||
this.getDrownReportFilterQuery(); | |||||
}, | |||||
methods: { | |||||
onNavBack(){ | |||||
this.$router.push({ | |||||
name: 'deviceSetting' | |||||
}) | |||||
}, | |||||
// 获取免告警水域 | |||||
getDrownReportFilterQuery() { | |||||
this.$toast.loading({ message: '数据加载中' }); | |||||
APICore.getDrownReportFilterQuery({imei: this.imei}).then(res => { | |||||
let data = res.data.data; | |||||
console.log(data); | |||||
if(data) { | |||||
if(isNotNull(data)) { | |||||
this.drownList = data; | |||||
this.$toast.success({ message: '数据加载完成' }); | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.drown-white-list { | |||||
position: relative; | |||||
height: 100vh; | |||||
width: 100%; | |||||
overflow: hidden; | |||||
.main { | |||||
/* height: calc(100vh - 88px); | |||||
overflow: auto; */ | |||||
overflow: auto; | |||||
.list { | |||||
@media screen and (max-width: 1920px) and (min-width: 750px){ | |||||
padding: 2vh; | |||||
height: 70vh; | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
align-content: center; | |||||
align-items: center; | |||||
flex-wrap: wrap; | |||||
} | |||||
@media screen and (max-width: 750px) and (min-width: 200px){ | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
align-content: center; | |||||
align-items: center; | |||||
flex-direction: column; | |||||
height: calc(100vh - 88px); | |||||
} | |||||
.item { | |||||
@media screen and (max-width: 1920px) and (min-width: 750px){ | |||||
width: 25%; | |||||
} | |||||
@media screen and (max-width: 750px) and (min-width: 200px){ | |||||
width: 300px; | |||||
font-size: 16px; | |||||
} | |||||
margin: 2vh; | |||||
padding: 1vh; | |||||
/* font-size: 16px; */ | |||||
border: 1px solid $border_color; | |||||
border-radius: 8px; | |||||
p { | |||||
padding: 4px 0; | |||||
} | |||||
.btn-con { | |||||
display: flex; | |||||
justify-content: flex-end; | |||||
align-items: center; | |||||
.btn { | |||||
height: 30px; | |||||
width: 110px; | |||||
@include center(); | |||||
border-radius: 15px; | |||||
margin-top: 10px; | |||||
background-color: red; | |||||
color: #fff; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.noData { | |||||
@media screen and (max-width: 1920px) and (min-width: 750px){ | |||||
height: 100px; | |||||
width: 100%; | |||||
} | |||||
@media screen and (max-width: 750px) and (min-width: 200px){ | |||||
height: 225px; | |||||
width: 100%; | |||||
} | |||||
@include center(); | |||||
margin: 100px auto 0; | |||||
background-size: 165px 120px; | |||||
p { | |||||
@include colorAndFont(#999, 28); | |||||
margin: 100px auto 0; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* @Author: your name | * @Author: your name | ||||
* @Date: 2020-04-15 10:00:32 | * @Date: 2020-04-15 10:00:32 | ||||
* @LastEditTime: 2023-06-14 17:10:10 | |||||
* @LastEditTime: 2023-10-12 17:24:41 | |||||
* @LastEditors: JinxChen | * @LastEditors: JinxChen | ||||
* @Description: In User Settings Edit | * @Description: In User Settings Edit | ||||
* @FilePath: \TelpoH5FrontendWeb\vue.config.js | * @FilePath: \TelpoH5FrontendWeb\vue.config.js | ||||
@@ -14,10 +14,10 @@ const pxtorem = require('postcss-pxtorem'); // 把代码中px转为rem | |||||
const CompressionPlugin = require("compression-webpack-plugin"); | const CompressionPlugin = require("compression-webpack-plugin"); | ||||
const port = process.env.port || process.env.npm_config_port || 8080;/* 7788 */ // dev port | const port = process.env.port || process.env.npm_config_port || 8080;/* 7788 */ // dev port | ||||
/* const proxy = process.env.NODE_ENV === 'development' ?{ | |||||
const proxy = process.env.NODE_ENV === 'development' ?{ | |||||
// 调试完毕需要把这个代理注释掉,否则发布到线上会有问题产生 | // 调试完毕需要把这个代理注释掉,否则发布到线上会有问题产生 | ||||
'/api/id': { | |||||
target: 'https://id.ssjlai.com/watersoutboundapi/', | |||||
/* '/api/id': { | |||||
target: 'http://id.ssjlai.com/iotservice', | |||||
changeOrigin: true, | changeOrigin: true, | ||||
pathRewrite: { | pathRewrite: { | ||||
'^/api/id': '' | '^/api/id': '' | ||||
@@ -29,9 +29,9 @@ const port = process.env.port || process.env.npm_config_port || 8080;/* 7788 */ | |||||
pathRewrite: { | pathRewrite: { | ||||
'^/api/ai': '' | '^/api/ai': '' | ||||
} | } | ||||
} | |||||
} */ | |||||
} | } | ||||
: null; */ | |||||
: null; | |||||
module.exports = { | module.exports = { | ||||
// 注意: 多页面配置 不再使用全路径,单页面时可以开启 | // 注意: 多页面配置 不再使用全路径,单页面时可以开启 | ||||
publicPath: './', | publicPath: './', | ||||
@@ -46,7 +46,7 @@ module.exports = { | |||||
warnings: false, | warnings: false, | ||||
errors: true | errors: true | ||||
}, | }, | ||||
/* proxy: proxy, */ | |||||
/* proxy: proxy, */ //开启代理后必须也要把这个开启,否则不生效 | |||||
/* host: '192.168.3.186', */// 原为: hotst: 'localhost', 可在同一ip局域网下通过网址生成二维码的方式调试h5, 注意:调试完毕请注释 | /* host: '192.168.3.186', */// 原为: hotst: 'localhost', 可在同一ip局域网下通过网址生成二维码的方式调试h5, 注意:调试完毕请注释 | ||||
//disableHostCheck: true, //真机调试开启 | //disableHostCheck: true, //真机调试开启 | ||||
}, | }, | ||||