This commit is contained in:
zk
2023-12-21 09:02:45 +08:00
parent 1c65f18bab
commit 9230f659c1
34 changed files with 473 additions and 327 deletions
+2
View File
@@ -5,5 +5,7 @@ VITE_GLOB_API_URL=http://cqyt.dev.yg.dt.io
#应急求助-websocket #应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor
#VITE_GLOB_API_YIN_JI=ws://192.168.1.3:7098/websocket/watchMonitor
#健康监测工具报警-websocket #健康监测工具报警-websocket
VITE_GLOB_API_JIAN_CE=ws://cqyt.dev.yg.dt.io/health-emergency/websocket/emergency VITE_GLOB_API_JIAN_CE=ws://cqyt.dev.yg.dt.io/health-emergency/websocket/emergency
#VITE_GLOB_API_JIAN_CE=ws://192.168.1.3:7011/websocket/emergency
+5
View File
@@ -15,6 +15,7 @@
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1", "@amap/amap-jsapi-loader": "^1.0.1",
"@iamzzg/data-view": "^2.10.0", "@iamzzg/data-view": "^2.10.0",
"autoprefixer": "^10.4.16",
"axios": "^1.6.2", "axios": "^1.6.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"jsencrypt": "^3.3.2", "jsencrypt": "^3.3.2",
@@ -22,6 +23,10 @@
"mitt": "^3.0.1", "mitt": "^3.0.1",
"path": "^0.12.7", "path": "^0.12.7",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"postcss": "^8.4.32",
"postcss-loader": "^7.3.3",
"postcss-plugin-px2rem": "^0.8.1",
"postcss-px2rem": "^0.3.0",
"prettier": "^3.1.0", "prettier": "^3.1.0",
"qs": "^6.11.2", "qs": "^6.11.2",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
+2
View File
@@ -4,6 +4,7 @@ enum Api {
code = '/sys/dictItem/list', code = '/sys/dictItem/list',
} }
//锻炼字典
export const getCodeInfo = (params: any) => export const getCodeInfo = (params: any) =>
get(Api.code, { get(Api.code, {
pageNo: 1, pageNo: 1,
@@ -11,3 +12,4 @@ export const getCodeInfo = (params: any) =>
dictId: '1722171687208849409', dictId: '1722171687208849409',
...params, ...params,
}); });
export const montionFieldNames = { label: 'itemText', value: 'itemValue' };
+1 -1
View File
@@ -31,7 +31,7 @@ export function typeToIcon(type: string) {
if (type == '3') { if (type == '3') {
return createIcon({ icon: mapIcon2, iconSize, imageSize }); return createIcon({ icon: mapIcon2, iconSize, imageSize });
} }
if (type == '4') { if (type == '5') {
return createIcon({ icon: mapIcon3, iconSize, imageSize }); return createIcon({ icon: mapIcon3, iconSize, imageSize });
} }
if (type == '6') { if (type == '6') {
@@ -1,4 +1,5 @@
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { visibleChartLabel } from '/@/utils/utils.ts';
// 列表字段 // 列表字段
export const columns = [ export const columns = [
{ {
@@ -95,6 +96,7 @@ export function useHealth() {
} }
export function ringOption(chartData, total) { export function ringOption(chartData, total) {
const data = visibleChartLabel(chartData);
return { return {
title: { title: {
text: '总人数', text: '总人数',
@@ -147,7 +149,7 @@ export function ringOption(chartData, total) {
labelLine: { labelLine: {
show: false, show: false,
}, },
data: chartData, data: data,
}, },
], ],
}; };
+1 -3
View File
@@ -6,8 +6,7 @@
</template> </template>
</public-title> </public-title>
<div class="inner"> <div class="inner">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="4" <vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="4" v-bind="classOption">
v-bind="classOption">
<div class="item" v-for="(item, i) in scrollList" :key="i"> <div class="item" v-for="(item, i) in scrollList" :key="i">
<span class="fixed-width" :title="item?.realName">{{ item?.realName }}</span> <span class="fixed-width" :title="item?.realName">{{ item?.realName }}</span>
<span class="fixed-width" :title="item?.eventType_dictText">{{ item?.eventType_dictText }}</span> <span class="fixed-width" :title="item?.eventType_dictText">{{ item?.eventType_dictText }}</span>
@@ -141,7 +140,6 @@ function viewDetail() {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.right-text { .right-text {
font-size: 14px;
font-weight: 100; font-weight: 100;
cursor: pointer; cursor: pointer;
margin-right: 3px; margin-right: 3px;
+6 -6
View File
@@ -5,8 +5,8 @@ export enum TabType {
youTianYiYuan = '1', //油田医院 youTianYiYuan = '1', //油田医院
heZuoYiYuan = '2', //合作医院 heZuoYiYuan = '2', //合作医院
yiLiaoDian = '3', //医疗点 yiLiaoDian = '3', //医疗点
jiuHuChe = '4', //救护车 jiuHuChe = '5', //救护车
zhiShengJi = '5', //直升机 zhiShengJi = '4', //直升机
diFangYiYuan = '6', //地方医院 diFangYiYuan = '6', //地方医院
} }
@@ -105,12 +105,12 @@ export function mapApiSwitch(type, params: any) {
lon: 108, //经度 lon: 108, //经度
}; };
// 全部 油田 医疗点 合作医院 // 全部 油田 医疗点 合作医院
if ([TabType.all, TabType.youTianYiYuan, TabType.yiLiaoDian, TabType.heZuoYiYuan].includes(type)) { if ([TabType.all, TabType.youTianYiYuan, TabType.yiLiaoDian, TabType.heZuoYiYuan, TabType.jiuHuChe, TabType.jiuHuChe].includes(type)) {
return getAllList({ ...basicParams, ...params }); return getAllList({ ...basicParams, ...params });
} }
if ([TabType.jiuHuChe].includes(type)) { // if ([TabType.jiuHuChe].includes(type)) {
return getAmbulanceList({}); // return getAmbulanceList({});
} // }
} }
export const mapIcon1 = new URL('/@/assets/img/mapIcon1.png', import.meta.url).href; export const mapIcon1 = new URL('/@/assets/img/mapIcon1.png', import.meta.url).href;
+6 -5
View File
@@ -87,7 +87,6 @@
if (TabType.diFangYiYuan == item.type) { if (TabType.diFangYiYuan == item.type) {
Map.clearActiveHospital(); Map.clearActiveHospital();
Map.map.on('moveend', logMapinfo); Map.map.on('moveend', logMapinfo);
// debugger;
return; return;
} }
if (TabType.zhiShengJi == item.type) { if (TabType.zhiShengJi == item.type) {
@@ -116,7 +115,8 @@
async function getMapData(type, params = {}) { async function getMapData(type, params = {}) {
try { try {
const { code, result } = await mapApiSwitch(type, params); const { code, result } = await mapApiSwitch(type, params);
if (code == 200 && Array.isArray(result) && result.length > 0) { if (code == 200) {
if (Array.isArray(result) && result.length > 0) {
Map.createOverlay(result, { Map.createOverlay(result, {
content: (val) => { content: (val) => {
return `<div style=" return `<div style="
@@ -128,13 +128,13 @@
</div>`; </div>`;
}, },
}); });
} else {
Map.removeOverlayGroup();
}
} }
} catch (e) { } catch (e) {
console.log('error------------------------------');
console.warn(e); console.warn(e);
} }
1;
// console.log('--->data', result);
} }
const footerData = ref({ const footerData = ref({
@@ -241,6 +241,7 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
font-size: 16px;
.tab { .tab {
width: calc(100% / 8); width: calc(100% / 8);
+5 -2
View File
@@ -6,7 +6,7 @@
</template> </template>
</public-title> </public-title>
<div class="inner" ref="healthChart"></div> <div class="inner" ref="healthChart"></div>
<div class="count" v-show="props.tips"> <div class="count">
<div class="t">总人数</div> <div class="t">总人数</div>
<div class="v">{{ userCount }}</div> <div class="v">{{ userCount }}</div>
</div> </div>
@@ -48,6 +48,9 @@
() => props.data, () => props.data,
() => { () => {
init(); init();
},
{
deep: true,
} }
); );
@@ -57,7 +60,7 @@
function initChart(chartData, total, color) { function initChart(chartData, total, color) {
let myChart = echarts.init(healthChart.value); let myChart = echarts.init(healthChart.value);
let options = circleRing(chartData, total, color, '{d}%'); let options = circleRing(chartData, total, color);
myChart.setOption(options); myChart.setOption(options);
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
myChart.resize(); myChart.resize();
+10 -9
View File
@@ -1,3 +1,6 @@
// 步数
import {visibleChartLabel} from "/@/utils/utils.ts";
export function screenPie(chartData, total, color, formatter) { export function screenPie(chartData, total, color, formatter) {
return { return {
color: color, color: color,
@@ -11,7 +14,7 @@ export function screenPie(chartData, total, color, formatter) {
borderColor: '#1b7ef2', borderColor: '#1b7ef2',
}, },
legend: { legend: {
left: '74%', left: '72%',
top: 'center', top: 'center',
orient: 'vertical', orient: 'vertical',
icon: 'circle', icon: 'circle',
@@ -24,22 +27,19 @@ export function screenPie(chartData, total, color, formatter) {
series: [ series: [
{ {
type: 'pie', type: 'pie',
// radius: ['50%', '86%'],
// center: ['42%', '55%'],
radius: ['50%', '76%'], radius: ['50%', '76%'],
center: ['42%', '49%'], center: ['40%', '49%'],
avoidLabelOverlap: false, avoidLabelOverlap: false,
label: { label: {
show: true, show: true,
position: 'outside', position: 'outside',
formatter: formatter,
color: '#ffffff', color: '#ffffff',
fontSize: 14, fontSize: 14,
}, },
labelLine: { labelLine: {
show: true, show: true,
length: 6, length: 6,
length2: 20, length2: 10,
minTurnAngle: 120, minTurnAngle: 120,
}, },
data: chartData, data: chartData,
@@ -49,7 +49,8 @@ export function screenPie(chartData, total, color, formatter) {
} }
//左侧圆 //左侧圆
export function circleRing(chartData, total, color, formatter) { export function circleRing(chartData, total, color) {
const data = visibleChartLabel(chartData)
return { return {
color: color, color: color,
tooltip: { tooltip: {
@@ -81,14 +82,14 @@ export function circleRing(chartData, total, color, formatter) {
label: { label: {
show: true, show: true,
position: 'inner', position: 'inner',
formatter: formatter, formatter: '{d}%',
color: '#ffffff', color: '#ffffff',
fontSize: 14, fontSize: 14,
}, },
labelLine: { labelLine: {
show: false, show: false,
}, },
data: chartData, data: data,
}, },
], ],
}; };
+1 -1
View File
@@ -58,7 +58,7 @@
} }
.tips { .tips {
font-size: 13px; font-size: 16px;
padding-right: 10px; padding-right: 10px;
font-weight: normal; font-weight: normal;
} }
@@ -1,6 +1,6 @@
<template> <template>
<template v-for="(item, index) in dataList" :key="`list${index}`"> <template v-for="(item, index) in dataList" :key="`list${index}`">
<item-d :title="item.title" :data="item.data" :tips="item.tips" :color="item.color" :userCount="item.userCount" /> <item-d :keu="spinning" :title="item.title" :data="item.data" :tips="item.tips" :color="item.color" :userCount="item.userCount" />
</template> </template>
</template> </template>
@@ -9,7 +9,9 @@
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import ItemD from '/@/components/item-d/item-d.vue'; import ItemD from '/@/components/item-d/item-d.vue';
import { getWatchDataByOrgCode } from '/@/components/secondaryScreen/commonApi.ts'; import { getWatchDataByOrgCode } from '/@/components/secondaryScreen/commonApi.ts';
import { useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts';
const { spinning, setSpin } = useSpin();
const dataList = ref([ const dataList = ref([
{ {
title: '心率', title: '心率',
@@ -51,7 +53,7 @@
{ {
title: '体温', title: '体温',
data: [ data: [
{ name: '37.2', value: 0, key: 'normalCountCount' }, { name: '<37.2', value: 0, key: 'normalCount' },
{ name: '37.2-38', value: 0, key: 'warnCount' }, { name: '37.2-38', value: 0, key: 'warnCount' },
{ name: '>38', value: 0, key: 'riskCount' }, { name: '>38', value: 0, key: 'riskCount' },
], ],
@@ -73,6 +75,7 @@
async function init() { async function init() {
const { code, result } = await getWatchDataByOrgCode(props); const { code, result } = await getWatchDataByOrgCode(props);
// debugger;
if (code == 200) { if (code == 200) {
let data = cloneDeep(dataList.value); let data = cloneDeep(dataList.value);
data.forEach((item) => { data.forEach((item) => {
@@ -82,7 +85,9 @@
val.value = resData[val.key]; val.value = resData[val.key];
}); });
}); });
dataList.value = data; dataList.value = data;
setSpin(!spinning.value);
} }
} }
@@ -24,7 +24,6 @@
watch( watch(
props, props,
() => { () => {
console.log(111111111111);
init(); init();
}, },
{ immediate: true } { immediate: true }
@@ -69,7 +69,7 @@ export function sleepCharts({ time, short, long, awake, type }) {
height: 40, height: 40,
itemHeight: 14, itemHeight: 14,
top: -5, top: -5,
left: '55%', left: '52%',
}, },
color: ['#14B3F8', '#6D7BEB', '#5451DC'], color: ['#14B3F8', '#6D7BEB', '#5451DC'],
xAxis: { xAxis: {
@@ -23,7 +23,7 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from 'vue'; import { onUnmounted, ref, watch } from 'vue';
import PublicTitle from '/@/components/publicTitle.vue'; import PublicTitle from '/@/components/publicTitle.vue';
import { getMonitorList } from '/@/components/secondaryScreen/commonApi.ts'; import { getMonitorList } from '/@/components/secondaryScreen/commonApi.ts';
import { monitorColumns } from '/@/components/secondaryScreen/screen-right/screenRightHooks.ts'; import { monitorColumns } from '/@/components/secondaryScreen/screen-right/screenRightHooks.ts';
@@ -58,7 +58,6 @@
tableHeight.value == 0 && setHeight(); tableHeight.value == 0 && setHeight();
window.addEventListener('resize', setHeight); window.addEventListener('resize', setHeight);
timer.value && clearInterval(timer.value); timer.value && clearInterval(timer.value);
// interval();
}, },
{ immediate: true } { immediate: true }
); );
@@ -74,7 +73,7 @@
} }
async function init(page) { async function init(page) {
const { pageSize, current } = pagination.value; const { pageSize } = pagination.value;
const { code, result } = await getMonitorList({ pageSize, pageNo: page, orgCode: props.orgCode }); const { code, result } = await getMonitorList({ pageSize, pageNo: page, orgCode: props.orgCode });
if (code == 200) { if (code == 200) {
dataSource.value = result.records; dataSource.value = result.records;
@@ -91,10 +90,8 @@
} }
function interval() { function interval() {
// timer.value = setInterval(() => {
let page = pagination.value.current < pages.value ? pagination.value.current + 1 : 1; let page = pagination.value.current < pages.value ? pagination.value.current + 1 : 1;
init(page); init(page);
// }, 3000);
} }
const { refreshState } = useRefresh(PAGE_SWITCH, () => { const { refreshState } = useRefresh(PAGE_SWITCH, () => {
@@ -42,9 +42,10 @@
const { code, result } = await getStep(params); const { code, result } = await getStep(params);
setSpin(true); setSpin(true);
if (code != 200) { if (code != 200) {
return; return initChart(unref(stepData), 0);
} }
setStep(result); setStep(result);
initChart(unref(stepData), '15000'); initChart(unref(stepData), '15000');
} catch { } catch {
initChart(unref(stepData), 0); initChart(unref(stepData), 0);
@@ -74,7 +75,7 @@
.count { .count {
position: absolute; position: absolute;
width: 80%; width: 77%;
top: 51%; top: 51%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -56,7 +56,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -84,8 +85,6 @@
status.value = s; status.value = s;
if (s) { if (s) {
initEchart('0'); initEchart('0');
} else {
tableReload();
} }
} }
@@ -57,7 +57,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -87,8 +88,6 @@
nextTick(() => { nextTick(() => {
initEchart('0'); initEchart('0');
}); });
} else {
tableReload();
} }
} }
@@ -52,7 +52,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -55,7 +55,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -83,8 +84,6 @@
nextTick(() => { nextTick(() => {
initEchart('0'); initEchart('0');
}); });
} else {
tableReload();
} }
} }
@@ -15,7 +15,7 @@
style="display: flex; justify-content: center; margin-top: 20px; align-items: center; position: relative" style="display: flex; justify-content: center; margin-top: 20px; align-items: center; position: relative"
:style="{ minHeight: props.showList ? '' : '30px' }" :style="{ minHeight: props.showList ? '' : '30px' }"
> >
<div style="position: absolute; left: 10px; display: flex; align-items: center" v-if="!props.showList"> <div class="fff" style="position: absolute; left: 10px; display: flex; align-items: center; color: #fff" v-if="!props.showList">
锻炼类型 锻炼类型
<!-- <JDictSelectTag--> <!-- <JDictSelectTag-->
<!-- v-model:value="motionType"--> <!-- v-model:value="motionType"-->
@@ -24,6 +24,13 @@
<!-- dictCode="watch_exercise_type"--> <!-- dictCode="watch_exercise_type"-->
<!-- @change="changeSelect"--> <!-- @change="changeSelect"-->
<!-- />--> <!-- />-->
<a-select
v-model:value="motionType"
class="type-select"
:field-names="montionFieldNames"
:options="selectOptions"
@change="changeSelect"
></a-select>
</div> </div>
<div class="item-picker" style="display: flex; font-size: 20px" v-if="showStatus && props.showList"> <div class="item-picker" style="display: flex; font-size: 20px" v-if="showStatus && props.showList">
<span style="margin: 0 0 0 5px; cursor: pointer" @click="changeDate('0')">&lt;</span> <span style="margin: 0 0 0 5px; cursor: pointer" @click="changeDate('0')">&lt;</span>
@@ -52,13 +59,14 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { nextTick, onMounted, ref } from 'vue';
import chartImg from '/@/assets/images/chart.png'; import chartImg from '/@/assets/images/chart.png';
import listImg from '/@/assets/images/list.png'; import listImg from '/@/assets/images/list.png';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { propTypes } from '/@/utils/propTypes'; import { propTypes } from '/@/utils/propTypes';
// import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue'; // import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import { userDataDayByYearApi } from '/@/components/secondaryScreen/secondMap/secondMapApi.ts'; import { userDataDayByYearApi } from '/@/components/secondaryScreen/secondMap/secondMapApi.ts';
import { getCodeInfo, montionFieldNames } from '/@/api/dictCode.ts';
const props = defineProps({ const props = defineProps({
showOne: propTypes.bool.def(true), showOne: propTypes.bool.def(true),
@@ -66,6 +74,21 @@
keyType: propTypes.string.def(''), keyType: propTypes.string.def(''),
userId: propTypes.string.def(''), userId: propTypes.string.def(''),
}); });
const selectOptions = ref([]);
onMounted(() => {
getOptions();
});
async function getOptions() {
try {
const { code, result } = await getCodeInfo();
if (code == 0) {
nextTick(() => {
selectOptions.value = result?.records;
});
}
} catch {}
}
const emit = defineEmits(['changeV', 'changeShowStatus', 'changeM']); const emit = defineEmits(['changeV', 'changeShowStatus', 'changeM']);
@@ -93,7 +116,7 @@
}; };
userDataDayByYearApi(params) userDataDayByYearApi(params)
.then((res) => { .then((res) => {
infoData.value = res.month; infoData.value = res?.result?.month;
}) })
.catch(() => {}); .catch(() => {});
} }
@@ -60,7 +60,8 @@
function tableReload() { function tableReload() {
nextTick(() => { nextTick(() => {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -93,8 +94,6 @@
nextTick(() => { nextTick(() => {
initEchart('0'); initEchart('0');
}); });
} else {
tableReload();
} }
} }
@@ -130,22 +129,29 @@
echart = echarts.init(chartRef.value); echart = echarts.init(chartRef.value);
const option = { const option = {
title: {}, title: {},
legend: {}, legend: {
textStyle: {
color: '#fff',
},
},
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
type: 'shadow', type: 'shadow',
}, },
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
formatter: function (params) { formatter: function (params) {
let tar1 = params[1]; let tar1 = params[1];
let tar = params[0]; let tar = params[0];
// let tar = params[1];
// return (tar1.value > 0 ? '短睡' : '长睡') + '<br/>' + tar.seriesName + ' : ' + tar.value;
let str = ''; let str = '';
if (type.value === 1) { if (type.value === 1) {
str = tar1.value > 0 ? '睡' : '睡'; str = tar1.value > 0 ? '睡' : '睡';
} else { } else {
str = '睡' + ' : ' + (tar.value ? tar.value : 0) + '<br/>' + '睡' + ' : ' + (tar1.value ? tar1.value : 0); str = '睡' + ' : ' + (tar.value ? tar.value : 0) + '<br/>' + '睡' + ' : ' + (tar1.value ? tar1.value : 0);
} }
return str; return str;
}, },
@@ -159,14 +165,18 @@
xAxis: { xAxis: {
type: 'category', type: 'category',
splitLine: { show: false }, splitLine: { show: false },
data: xArr, data: xArr || ['', ''],
axisLabel: {
color: '#fff',
},
min: 5,
}, },
yAxis: { yAxis: {
show: false, show: false,
}, },
series: [ series: [
{ {
name: '睡', name: '睡',
type: 'bar', type: 'bar',
barMaxWidth: '20px', barMaxWidth: '20px',
itemStyle: { itemStyle: {
@@ -174,16 +184,10 @@
borderWidth: 0, borderWidth: 0,
color: '#5087ec', color: '#5087ec',
}, },
// emphasis: {
// itemStyle: {
// borderColor: '#68bbc4',
// color: '#68bbc4',
// },
// },
data: yArr, data: yArr,
}, },
{ {
name: '睡', name: '睡',
barMaxWidth: '20px', barMaxWidth: '20px',
itemStyle: { itemStyle: {
borderColor: '#85d0dc', borderColor: '#85d0dc',
@@ -59,7 +59,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -89,8 +90,6 @@
nextTick(() => { nextTick(() => {
initEchart('0'); initEchart('0');
}); });
} else {
tableReload();
} }
} }
@@ -123,7 +122,11 @@
backgroundColor: 'rgba(50,50,50,0.7)', backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2', borderColor: '#1b7ef2',
}, },
legend: {}, legend: {
textStyle: {
color: '#fff',
},
},
xAxis: { xAxis: {
type: 'category', type: 'category',
boundaryGap: true, boundaryGap: true,
@@ -56,7 +56,8 @@
function tableReload() { function tableReload() {
apiParams.value = { apiParams.value = {
...getParams(), flag: 0,
userId: props.userId,
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
}; };
@@ -86,8 +87,6 @@
nextTick(() => { nextTick(() => {
initEchart('0'); initEchart('0');
}); });
} else {
tableReload();
} }
} }
@@ -21,13 +21,19 @@
} }
} }
.fff {
color: #fff;
}
:deep(.ant-radio-button-checked) { :deep(.ant-radio-button-checked) {
background-color: #1B7EF2 !important; background-color: #1B7EF2 !important;
border-color: #1B7EF2 !important; border-color: #1B7EF2 !important;
} }
:deep(.ant-radio-button-wrapper-checked) { :deep(.ant-radio-button-wrapper-checked) {
border-color: #1B7EF2 !important; border-color: #1B7EF2 !important;
} }
:deep(.ant-radio-button-wrapper) { :deep(.ant-radio-button-wrapper) {
background-color: #d8dce5 !important; background-color: #d8dce5 !important;
border-color: #d8dce5 !important; border-color: #d8dce5 !important;
@@ -29,6 +29,8 @@
import UserInfoModal from '/@/components/secondaryScreen/secondMap/components/userInfoModal/userInfoModal.vue'; import UserInfoModal from '/@/components/secondaryScreen/secondMap/components/userInfoModal/userInfoModal.vue';
import { columns } from '/@/components/secondaryScreen/secondMap/secondMapHooks.ts'; import { columns } from '/@/components/secondaryScreen/secondMap/secondMapHooks.ts';
import { getUserListByDeptId } from '/@/components/secondaryScreen/secondMap/secondMapApi.ts'; import { getUserListByDeptId } from '/@/components/secondaryScreen/secondMap/secondMapApi.ts';
const emit = defineEmits(['close']);
//分页相关 //分页相关
const current = ref(1); const current = ref(1);
const pageSize = ref(10); const pageSize = ref(10);
@@ -61,6 +63,7 @@
function closeModal() { function closeModal() {
visible.value = false; visible.value = false;
emit('close');
} }
async function getRecords(id: string) { async function getRecords(id: string) {
@@ -76,7 +79,6 @@
const userInfoModal = ref(); const userInfoModal = ref();
function openUserInfoModal(item) { function openUserInfoModal(item) {
console.log('item', item);
const data = { const data = {
...item, ...item,
username: item?.realName, username: item?.realName,
@@ -9,32 +9,32 @@
</div> </div>
<div v-show="false" id="container"></div> <div v-show="false" id="container"></div>
<div v-show="false" id="panel"></div> <div v-show="false" id="panel"></div>
<div class="footer-data" v-show="isShow" style="--moveUp: 50px; --moveDown: -90px" :class="className"> <div v-show="isShow" :class="className" class="footer-data" style="--moveUp: 50px; --moveDown: -90px">
<div class="empty-png"></div> <div class="empty-png"></div>
<div <div
class="col-item nowrap"
v-for="item in footerList" v-for="item in footerList"
:style="{ cursor: item.key == 'allotDeviceNum' ? 'pointer' : 'default' }" :style="{ cursor: item.key == 'allotDeviceNum' ? 'pointer' : 'default' }"
class="col-item nowrap"
@click="openWatchList(item)" @click="openWatchList(item)"
> >
<div class="col-text">{{ item?.name }}</div> <div class="col-text">{{ item?.name }}</div>
<div class="col-value nowrap" :title="item.value">{{ item?.value }}</div> <div :title="item.value" class="col-value nowrap">{{ item?.value }}</div>
</div> </div>
</div> </div>
<div <div
v-show="isShowAlarm"
:class="isShowAlarm ? 'slide-top' : 'slide-bottom'"
class="footer-dialog-con" class="footer-dialog-con"
style="--moveUp: 120px; --moveDown: -120px" style="--moveUp: 120px; --moveDown: -120px"
:class="isShowAlarm ? 'slide-top' : 'slide-bottom'"
v-show="isShowAlarm"
> >
<FooterDialog :detailLeft="detailLeft" :detailRight="detailRight" @closeDialog="closeDialog"></FooterDialog> <FooterDialog :detailLeft="detailLeft" :detailRight="detailRight" @closeDialog="closeDialog"></FooterDialog>
</div> </div>
</div> </div>
<WatchListDialog ref="watchDialogRef"></WatchListDialog> <WatchListDialog ref="watchDialogRef" @close="closeWatch"></WatchListDialog>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { Map } from '/@/assets/mapUtils/map'; import { Map } from '/@/assets/mapUtils/map';
import $bus from '/@/utils/bus.ts'; import $bus from '/@/utils/bus.ts';
import FooterDialog from '/@/components/secondaryScreen/secondMap/components/footerDialog.vue'; import FooterDialog from '/@/components/secondaryScreen/secondMap/components/footerDialog.vue';
@@ -109,6 +109,12 @@
} catch {} } catch {}
} }
watch(
() => props.orgCode,
() => {
getMapList();
}
);
const { detailLeft, detailRight, setDetail } = useAlarmDetail(); const { detailLeft, detailRight, setDetail } = useAlarmDetail();
onMounted(() => { onMounted(() => {
init(); init();
@@ -121,12 +127,18 @@
}); });
/** /**
*@desc 预警弹窗关闭 *@desc 底部信息
*/ */
function closeDialog() { function closeDialog() {
setIsShowAlarm(!isShowAlarm.value); setIsShowAlarm(!isShowAlarm.value);
Map.clearMarker();
} }
/**
* @desc 预警弹窗关闭
*/
function closeWatch() {}
function drawMarker(data: any) { function drawMarker(data: any) {
const { lon, lat } = data; const { lon, lat } = data;
if (!lon || !lat) return; if (!lon || !lat) return;
@@ -24,7 +24,8 @@ export function useDepart() {
async function getOptionData() { async function getOptionData() {
const { result, code } = await allSecondaryDeparts(); const { result, code } = await allSecondaryDeparts();
if (code == 200) { if (code == 200) {
setOption(result); let res = [{ departName: '长庆油田', orgCode: 'A01' }, ...result];
setOption(res);
} }
} }
+1 -1
View File
@@ -4,4 +4,4 @@ const BASIC_SECOND = 1000; //1s
//副屏 心率、血氧、压力、睡眠、步数 //副屏 心率、血氧、压力、睡眠、步数
export const DEFAULT_TIME = BASIC_MIN * 10; export const DEFAULT_TIME = BASIC_MIN * 10;
//预警分页切换 //预警分页切换
export const PAGE_SWITCH = BASIC_SECOND * 300; export const PAGE_SWITCH = BASIC_SECOND * 3;
+71 -30
View File
@@ -15,9 +15,52 @@ export const basicPath = VITE_GLOB_API_YIN_JI;
export const emergencyPath = VITE_GLOB_API_JIAN_CE; export const emergencyPath = VITE_GLOB_API_JIAN_CE;
let t = token || getAuthCache(TOKEN_KEY); let t = token || getAuthCache(TOKEN_KEY);
export function useSocket(path = basicPath) { export function useSocket(p = basicPath) {
const socket = ref(); const socket = ref();
let socketData = ref({}); let socketData = ref({});
let lockReconnect = ref(false); //避免ws重复连接
const path = ref(p);
function reconnect(path) {
if (lockReconnect.value) return;
lockReconnect.value = true;
setTimeout(function () {
//没连接上会一直重连,设置延迟避免请求过多
init(path);
lockReconnect.value = false;
}, 2000);
}
//心跳检测
const heartCheck = {
timeout: 1000 * 10, //1分钟发一次心跳
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
let self = this;
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
if (socket.value.readyState === WebSocket.OPEN) {
//console.log('p1' + new Date().toLocaleString());
socket.value.send('ping');
} else {
//console.log('p2');
init();
}
self.serverTimeoutObj = setTimeout(function () {
//如果超过一定时间还没重置,说明后端主动断开了
// TODO
// socket.value.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout);
}, this.timeout);
},
};
function init() { function init() {
if (!t) { if (!t) {
@@ -27,44 +70,42 @@ export function useSocket(path = basicPath) {
alert('您的浏览器不支持socket'); alert('您的浏览器不支持socket');
} else { } else {
// 实例化socket // 实例化socket
socket.value = new WebSocket(path, [t]); socket.value = new WebSocket(path.value + Date.now(), [t]);
// 监听socket连接
socket.value.onopen = open;
// 监听socket错误信息
socket.value.onerror = error;
// 监听socket消息
socket.value.onmessage = getMessage;
socket.value.onclose = close;
}
}
function open() { socket.value.onclose = function () {
console.log('socket连接成功'); reconnect(path.value);
//console.log('连接关闭!:', new Date().toLocaleString());
};
socket.value.onerror = function () {
reconnect(path.value);
//console.log('连接错误!');
};
socket.value.onopen = function () {
heartCheck.reset().start(); //心跳检测重置
//console.log('连接成功!' + new Date().toLocaleString());
};
socket.value.onmessage = function (event) {
//如果获取到消息,心跳检测重置
heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
//console.log('收到消息啦:', event);
if (event.data != 'pong') {
let data = JSON.parse(event.data);
socketData.value = data;
} }
};
function error() {
console.log('socket连接错误');
} }
function getMessage(msg) {
console.log('getMessage', msg);
socketData.value = JSON.parse(msg.data);
} }
function setSocketData(data) { function setSocketData(data) {
socketData.value = data; socketData.value = data;
} }
function close(data) { init();
console.log(data);
console.log('socket已经关闭'); function closeSocket() {
socket.value && socket.value.close;
} }
onMounted(() => { return { socket, socketData, setSocketData, closeSocket };
init();
});
onUnmounted(() => {
//socket.value.onclose = close;
});
return { socket, socketData, setSocketData };
} }
+24 -9
View File
@@ -1,4 +1,5 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { cloneDeep } from 'lodash-es';
export function getZero(num: any) { export function getZero(num: any) {
if (num < 10) { if (num < 10) {
@@ -9,15 +10,14 @@ export function getZero(num: any) {
export function useTopTime() { export function useTopTime() {
const timeLeft = dayjs().format('YYYY年MM月DD日 HH时mm分ss秒'); const timeLeft = dayjs().format('YYYY年MM月DD日 HH时mm分ss秒');
const timeRight = const timeRight = dayjs().diff(dayjs('2018-10-01'), 'day') + '天';
dayjs().diff(dayjs('2018-10-01'), 'day') + // +
'天' + // getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00'), 'hours')) +
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00'), 'hours')) + // '时' +
'时' + // getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH') + ':00:00'), 'minutes')) +
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH') + ':00:00'), 'minutes')) + // '分' +
'分' + // getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD') + ':00'), 'seconds')) +
getZero(dayjs().diff(dayjs(dayjs().format('YYYY-MM-DD HH:mm') + ':00'), 'seconds')) + // '秒';
'秒';
return { return {
timeLeft, timeLeft,
timeRight, timeRight,
@@ -39,3 +39,18 @@ export function minuteToStr(minutes) {
} }
return `${m}分钟`; return `${m}分钟`;
} }
//处理echarts-环形图 数据为0时不显示label
export function visibleChartLabel(chartData) {
const data = cloneDeep(chartData);
let list = data?.map((item) => item?.value);
let flag = list.every((item) => item == 0);
if (!flag) {
data.forEach((val) => {
if (val.value == 0) {
val.value = null;
}
});
}
return data;
}
+19 -10
View File
@@ -66,7 +66,7 @@
}); });
init(); init();
// 健康监测工具报警 // 健康监测工具报警
const { socketData, setSocketData } = useSocket(basicPath); const { socketData, setSocketData, closeSocket } = useSocket(basicPath);
const employeeDialogRef = ref(); const employeeDialogRef = ref();
watch(socketData, (nVal) => { watch(socketData, (nVal) => {
if (nVal) { if (nVal) {
@@ -78,16 +78,25 @@
}); });
//应急求助 //应急求助
const { socketData: emergencyData, setSocketData: setEmergencyData } = useSocket(emergencyPath); // const { socketData: emergencyData, setSocketData: setEmergencyData, closeSocket: closeSocket2 } = useSocket(emergencyPath);
const emergencyDialogRef = ref(); // const emergencyDialogRef = ref();
//
// watch(emergencyData, (nVal) => {
// if (nVal) {
// nextTick(() => {
// setEmergencyData(nVal);
// emergencyDialogRef.value.openDialog;
// });
// }
// });
onUnmounted(() => {
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
// closeSocket();
// closeSocket2();
};
watch(emergencyData, (nVal) => { clearInterval(interval.value);
if (nVal) {
nextTick(() => {
setEmergencyData(nVal);
emergencyDialogRef.value.openDialog;
});
}
}); });
function test() { function test() {
+1 -1
View File
@@ -9,7 +9,7 @@
返回 返回
</span> </span>
</div> </div>
<div class="title-d-middle"> 应急就医服务中</div> <div class="title-d-middle"> 血管监测</div>
<div class="title-d-right"> 累计运行时间{{ dayTimeT }}</div> <div class="title-d-right"> 累计运行时间{{ dayTimeT }}</div>
</div> </div>
<div class="body-d"> <div class="body-d">
+17
View File
@@ -2,12 +2,26 @@ import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
import { resolve } from 'path'; import { resolve } from 'path';
import postcssPluginPx2rem from 'postcss-plugin-px2rem';
import resolveExternalsPlugin from 'vite-plugin-resolve-externals'; import resolveExternalsPlugin from 'vite-plugin-resolve-externals';
function pathResolve(dir: string) { function pathResolve(dir: string) {
return resolve(process.cwd(), '.', dir); return resolve(process.cwd(), '.', dir);
} }
const px2remOptions = {
remUnit: 14,
rootValue: 19, //换算基数, 默认100 ,也就是1440px ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多少px了
unitPrecision: 5, //允许REM单位增长到的十进制数字,其实就是精度控制
// propWhiteList: [], // 默认值是一个空数组,这意味着禁用白名单并启用所有属性。
// propBlackList: [], // 黑名单
// exclude:false, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
// selectorBlackList: [], //要忽略并保留为px的选择器
// ignoreIdentifier: false, //boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
// replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
mediaQuery: false, //(布尔值)允许在媒体查询中转换px
minPixelValue: 0, //设置要替换的最小像素值(3px会被转rem)。 默认 0
};
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
@@ -22,6 +36,9 @@ export default defineConfig({
javascriptEnabled: true, javascriptEnabled: true,
}, },
}, },
postcss: {
plugins: [postcssPluginPx2rem(px2remOptions)],
},
}, },
resolve: { resolve: {
alias: [ alias: [