@@ -1,7 +1,7 @@ | |||
<!-- | |||
* @Date: 2022-08-17 16:19:13 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-09-16 09:24:37 | |||
* @LastEditTime: 2023-10-19 14:25:30 | |||
* @FilePath: \TelpoH5FrontendWeb\README.md | |||
* @description: 项目说明 | |||
--> | |||
@@ -704,4 +704,39 @@ update | |||
# 无基础套餐时 | |||
#是零川或者小台风,跳转话费查询页面 | |||
#否则跳转错误页面 | |||
- 增加 一个物联网卡的错误页面 | |||
- 增加 一个物联网卡的错误页面 | |||
## v1.0.88 | |||
`2023.9.25` | |||
update | |||
- 问卷调查 | |||
- 修改 答题完成后返回方法,修复使用浏览器原生返回方法可能会导致页面返回异常 | |||
## v1.0.89 | |||
`2023.10.9` | |||
update | |||
- 问卷调查 | |||
- 增加 答题完成返回错误后如果是从随手精灵公众号调过来的用户,则第8 11题文字变红 | |||
## v1.0.90 | |||
`2023.10.10` | |||
update | |||
- 问卷调查 | |||
- 增加 答题完成返回错误后如果是从随手精灵公众号调过来的用户,则第6题文字变红 | |||
## v1.0.91 | |||
`2023.10.13` | |||
feature | |||
- 增加 c1后台设备功耗查看页面 | |||
- 增加 cell,echarts和table组件 | |||
## v1.0.92 | |||
`2023.10.19` | |||
update | |||
- c1后台设备功耗查看页面 | |||
- 修改 数据解析方法 |
@@ -1,7 +1,7 @@ | |||
/* | |||
* @Date: 2021-12-18 15:49:01 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-03-27 15:29:01 | |||
* @LastEditTime: 2023-10-12 11:37:52 | |||
* @FilePath: \TelpoH5FrontendWeb\src\api\core.js | |||
* @description: | |||
* b端的接口, 每次调用前先获取token | |||
@@ -12,6 +12,7 @@ const baseUrl = process.env.VUE_APP_BASE_API + 'gateway'; | |||
const service = axios.create({ | |||
baseURL: baseUrl, | |||
}); | |||
const HTTP_PREFIX_CORE = process.env.VUE_APP_BASE_API + 'gateway/' + 'core'; | |||
service.interceptors.request.use( | |||
request => { | |||
if (localStorage.getItem(prefix + 'gatewayToken')) { | |||
@@ -30,6 +31,30 @@ export const APICore = { | |||
cardPackageList, //零川基础套餐列表 | |||
devicePayPackage, | |||
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; */ | |||
// 获取告警详情 | |||
@@ -101,4 +126,187 @@ function drownReportFilterAdd(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; |
@@ -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 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-09-18 10:45:59 | |||
* @LastEditTime: 2023-10-16 09:34:24 | |||
* @FilePath: \TelpoH5FrontendWeb\src\config\models.js | |||
* @description: | |||
*/ | |||
export const VERSION_MODEL = '1.0.87F'; //版本号 | |||
export const VERSION_MODEL = '1.0.92F'; //版本号 | |||
export const IMAGE_URL = { | |||
production: '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 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-09-20 14:15:47 | |||
* @LastEditTime: 2023-10-11 15:36:55 | |||
* @FilePath: \TelpoH5FrontendWeb\src\main.js | |||
* @description: | |||
*/ | |||
@@ -58,6 +58,9 @@ import { | |||
Toast, | |||
ActionSheet, | |||
Progress, | |||
DropdownMenu, | |||
DropdownItem, | |||
TreeSelect, | |||
} from 'vant'; //按需加载vant组件 | |||
Vue | |||
@@ -101,6 +104,9 @@ Vue | |||
.use(Toast) | |||
.use(ActionSheet) | |||
.use(Progress) | |||
.use(DropdownMenu) | |||
.use(DropdownItem ) | |||
.use(TreeSelect) | |||
Vue.config.productionTip = false; | |||
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 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-09-20 11:15:50 | |||
* @LastEditTime: 2023-10-10 15:56:50 | |||
* @FilePath: \TelpoH5FrontendWeb\src\router\index.js | |||
* @description: | |||
*/ | |||
@@ -59,6 +66,12 @@ const routes = [ | |||
{ 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) }, | |||
// 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({ | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* @Date: 2022-08-17 16:18:02 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-06-19 11:26:22 | |||
* @LastEditTime: 2023-10-13 14:45:16 | |||
* @FilePath: \TelpoH5FrontendWeb\src\store\index.js | |||
* @description: | |||
*/ | |||
@@ -13,7 +13,7 @@ import { isNotNull } from '@/utils'; | |||
Vue.use(Vuex); | |||
export default new Vuex.Store({ | |||
state: { | |||
imei: '', //例子 | |||
imei: '', // | |||
gatewayToken: '', //gateway接口token | |||
token: '', | |||
wxAuthCode: '', | |||
@@ -22,6 +22,7 @@ export default new Vuex.Store({ | |||
isFromWx: null, | |||
ssjlToken: '', | |||
fromSsjl: '', | |||
active: null, //点击左边树形图下标 | |||
}, | |||
mutations: { | |||
imei(state, imei) { | |||
@@ -60,6 +61,10 @@ export default new Vuex.Store({ | |||
state.fromSsjl = fromSsjl; | |||
window.localStorage[prefix + 'fromSsjl'] = fromSsjl; | |||
}, | |||
active(state, active) { | |||
state.active = active; | |||
window.localStorage[prefix + 'active'] = active; | |||
}, | |||
}, | |||
getters: { | |||
imei: state => { | |||
@@ -98,6 +103,10 @@ export default new Vuex.Store({ | |||
if (state.fromSsjl != '') return state.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: {}, | |||
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,340 @@ | |||
<!-- | |||
* @Date: 2023-10-10 15:29:50 | |||
* @LastEditors: JinxChen | |||
* @LastEditTime: 2023-10-19 14:21:55 | |||
* @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="btnActive === 0 && data.length > 0 || tableData.length > 0 && btnActive === 1"> | |||
<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 === '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' }, | |||
]; | |||
let propertyInfo = this.filterData.map(item => { | |||
return item.list.propertyInfo; | |||
}); | |||
let result = []; | |||
for (let i = 0; i < propertyInfo.length; i++) { | |||
// 循环对象中的数组 | |||
result = [].concat(...propertyInfo) | |||
} | |||
// 表格则要显示全部数据 | |||
this.tableData = result.map(item => { | |||
return { | |||
value: item.value, | |||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm") | |||
} | |||
}).reverse(); | |||
// 图表筛选过滤只显示 rssi <= 2的数据 | |||
this.data = result.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; | |||
}) | |||
} 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 | |||
}).reverse(); | |||
} 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%' ], | |||
} | |||
let propertyInfo = this.filterData.map(item => { | |||
return item.list.propertyInfo; | |||
}); | |||
let result = []; | |||
for (let i = 0; i < propertyInfo.length; i++) { | |||
// 循环对象中的数组 | |||
result = [].concat(...propertyInfo) | |||
} | |||
this.data = result.map(item => { | |||
return { | |||
value: item.value, | |||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm"), | |||
} | |||
}); | |||
this.tableData = result.map(item => { | |||
return { | |||
value: item.value, | |||
time: this.$dayjs(this.$dayjs(Number(item.time))).format("YYYY/MM/DD hh:mm") | |||
} | |||
}).reverse(); | |||
} | |||
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) { | |||
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,151 @@ | |||
<template> | |||
<div class="drown-white-list"> | |||
<van-nav-bar title="免告警水域" :border="true" left-arrow @click-left="onNavBack"/> | |||
<div class="main" v-show="loading"> | |||
<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: [], | |||
loading: false, | |||
} | |||
}, | |||
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: '数据加载完成' }); | |||
} | |||
} | |||
}).catch(() => {}).finally(() => { | |||
this.loading = true; | |||
}) | |||
}, | |||
} | |||
} | |||
</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, 16); | |||
margin: 100px auto 0; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@@ -22,7 +22,7 @@ | |||
</div> | |||
<div class="list_box"> | |||
<div class="item" v-for="(item, index) in topic" :key="index"> | |||
<div class="label"> | |||
<div :class="['label', {error: (isError && fromSsjl && item.Id == '6') || (isError && fromSsjl && item.Id == '8') || (isError && fromSsjl && item.Id == '11')}]"> | |||
<span>{{ item.Title }}</span> | |||
<span>({{ item.Type }})</span> | |||
</div> | |||
@@ -38,6 +38,7 @@ | |||
:key="idx" | |||
:title="ite.label" | |||
@click="onRadio(index, ite.value)" | |||
:title-class="[{cellTitle: (isError && fromSsjl && item.Id == '6') || (isError && fromSsjl && item.Id == '8') || (isError && fromSsjl && item.Id == '11')}]" | |||
> | |||
<template #right-icon> | |||
<van-radio :name="ite.value" /> | |||
@@ -89,7 +90,9 @@ export default { | |||
keyCode: '', | |||
title: '', | |||
topic: [], //题目列表 | |||
select: [], | |||
select: [], | |||
isError: null, //是否是答题错误 | |||
fromSsjl: this.$store.getters.fromSsjl | |||
} | |||
}, | |||
mounted() { | |||
@@ -201,9 +204,16 @@ export default { | |||
data: temp, | |||
}, this.$store.getters.ssjlToken) | |||
if (re.success) { | |||
this.$toast('问卷提交成功', 3000) | |||
this.$toast('问卷提交成功', 3000); | |||
this.isError = false; | |||
setTimeout(() => { | |||
window.history.back(-1) | |||
// 2023.09.25 使用此返回方法可能会导致页面返回异常,故使用路由跳转到指定页面 | |||
this.$router.replace({ | |||
name: 'PsychologicalModeling', | |||
query: { | |||
uid: this.uid | |||
} | |||
}) | |||
}, 3000) | |||
} else { | |||
//this.$toast(re.msg); | |||
@@ -211,6 +221,7 @@ export default { | |||
message: re.msg, | |||
showCancelButton: false, | |||
}); | |||
this.isError = true; | |||
} | |||
}, | |||
onRadio(index, value) { | |||
@@ -330,7 +341,17 @@ export default { | |||
.label { | |||
font-size: 4vw; | |||
&.error { | |||
color: red; | |||
} | |||
} | |||
.van-cell { | |||
.van-cell__title { | |||
&.cellTitle { | |||
color: red; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,7 +1,7 @@ | |||
/* | |||
* @Author: your name | |||
* @Date: 2020-04-15 10:00:32 | |||
* @LastEditTime: 2023-06-14 17:10:10 | |||
* @LastEditTime: 2023-10-12 17:24:41 | |||
* @LastEditors: JinxChen | |||
* @Description: In User Settings Edit | |||
* @FilePath: \TelpoH5FrontendWeb\vue.config.js | |||
@@ -14,10 +14,10 @@ const pxtorem = require('postcss-pxtorem'); // 把代码中px转为rem | |||
const CompressionPlugin = require("compression-webpack-plugin"); | |||
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, | |||
pathRewrite: { | |||
'^/api/id': '' | |||
@@ -29,9 +29,9 @@ const port = process.env.port || process.env.npm_config_port || 8080;/* 7788 */ | |||
pathRewrite: { | |||
'^/api/ai': '' | |||
} | |||
} | |||
} */ | |||
} | |||
: null; */ | |||
: null; | |||
module.exports = { | |||
// 注意: 多页面配置 不再使用全路径,单页面时可以开启 | |||
publicPath: './', | |||
@@ -46,7 +46,7 @@ module.exports = { | |||
warnings: false, | |||
errors: true | |||
}, | |||
/* proxy: proxy, */ | |||
/* proxy: proxy, */ //开启代理后必须也要把这个开启,否则不生效 | |||
/* host: '192.168.3.186', */// 原为: hotst: 'localhost', 可在同一ip局域网下通过网址生成二维码的方式调试h5, 注意:调试完毕请注释 | |||
//disableHostCheck: true, //真机调试开启 | |||
}, | |||