update: 新疆大屏

This commit is contained in:
xf
2025-07-06 15:04:39 +08:00
parent 22c5b89f90
commit 86ed8341e2
30 changed files with 984 additions and 151 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
# 王昊地址
#VITE_GLOB_API_URL=http://192.168.1.27
#VITE_GLOB_API_URL=http://192.168.1.98
#开发环境
VITE_GLOB_API_URL=http://cqyt.dev.yg.dt.io
VITE_GLOB_API_URL=https://xjgateway.mcrm.vip:8888
#VITE_GLOB_API_URL=https://api.cqygjk.com
#健康监测工具报警-websocket
#VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

+11 -7
View File
@@ -115,8 +115,9 @@ html, body, #app {
// 下拉框样式-start
.ant-select {
color: var(--antSelectFontColor) !important;
background-color: var(--antSelectBg);
color: #fff !important;
background-color: #082147 !important;
border-radius: 4px !important;
}
.ant-select-dropdown {
@@ -126,14 +127,15 @@ html, body, #app {
}
.ant-select-item {
color: #1b7ef2 !important;
color: #fff !important;
}
//框背景色
.ant-select:not(.ant-select-customize-input) .ant-select-selector {
color: var(--antSelectFontColor) !important;
background-color: transparent !important;
border: 1px solid var(--antSelectDropdownBorderColor) !important;
border: 1px solid transparent !important;
border-radius: 4px !important;
}
.ant-select-item-option-selected {
@@ -213,7 +215,7 @@ html, body, #app {
.ant-modal-title {
color: #576BAD !important;
background: url('/@/assets/images/dialog-light.png') no-repeat;
//background: url('/@/assets/images/dialog-light.png') no-repeat;
background-size: 100% 100%;
}
}
@@ -229,8 +231,10 @@ html, body, #app {
.ant-modal-title {
color: #ffffff !important;
background: url('/@/assets/images/dialog.png') no-repeat;
background-size: 100% 100%;
//background: url('/@/assets/images/dialog.png') no-repeat;
//background-size: 100% 100%;
background: #082147;
border: 1px solid #00CCFF;
}
}
+10 -7
View File
@@ -1,4 +1,4 @@
import { mapIcon1, mapIcon2, mapIcon3, mapIcon4, mapIcon7 } from '/@/components/chinaMap/chinaHooks.ts';
import { mapIcon1, mapIcon2, mapIcon3, mapIcon4, mapIcon5, mapIcon7 } from '/@/components/chinaMap/chinaHooks.ts';
import { watchIcon } from '/@/components/secondaryScreen/secondMap/secondMapHooks.ts';
import * as turf from '@turf/turf';
@@ -27,7 +27,7 @@ export function typeToIcon(type: string, centerResource: boolean) {
return createIcon({ icon: mapIcon1, iconSize, imageSize });
}
if (type == '2') {
return createIcon({ icon: mapIcon4, iconSize, imageSize });
return createIcon({ icon: mapIcon5, iconSize, imageSize });
}
//关联医疗点
if (type == '3' && centerResource) {
@@ -69,14 +69,17 @@ export function createCircle(option) {
export function getLonLat(result = []) {
let arr = [];
for (let i = 0; i < result.length; i++) {
let { lon, lat, lng } = result[i];
if (lng) {
lon = lng;
let { lon, lat, lng, longitude, latitude } = result[i];
if (longitude) {
lon = longitude;
}
if (!lon || !lat) {
if (latitude) {
lat = latitude;
}
if (!longitude || !latitude) {
continue;
}
let point = turf.point([lon, lat]);
let point = turf.point([lon * 1, lat * 1]);
arr.push(point);
}
return arr;
+11 -7
View File
@@ -144,11 +144,15 @@ export const Map = {
this.setZoomCenter(center, zoom);
}
for (let i = 0; i < result.length; i++) {
let { type, lon, lat, lng, centerResource } = result[i];
if (lng) {
lon = lng;
let { type, lon, lat, longitude, latitude, lng, centerResource } = result[i];
if (longitude) {
lon = longitude;
}
if (!lon || !lat || !type) {
if (latitude) {
lat = latitude;
}
if (!longitude || !latitude || !type) {
continue;
}
// 创建一个 Icon
@@ -310,10 +314,10 @@ export const Map = {
*
* */
createInfoModal({ option, content }) {
let { lat, lng } = option;
let { latitude, longitude } = option;
this.infoWindow = new AMap.InfoWindow({
position: [lng, lat],
offset: new AMap.Pixel(-5, -25),
position: [longitude, latitude],
offset: new AMap.Pixel(-8, -25),
content: content,
closeWhenClickMap: true,
});
+2 -2
View File
@@ -4,12 +4,12 @@
--antSelectDropdownBorderColor: #1b7ef2;
--antSelectItemActive: #002e64;
--antSelectFontColor: #fff;
--antSelectBg: #000;
--antSelectBg: #082147;
/*服务详情数据*/
--typeTimeSelectColor: #45a2ff;
--typeTimeUnSelectColor: #a3a4a4;
/*表格 */
--tableHeadBg: rgba(35, 132, 221, 0.5);
--tableHeadBg: #073063;
--tableFontColor: #fff;
--tableRowBg: #00152b;
--tableRowBorder: #2384dd;
@@ -15,7 +15,6 @@
<template v-else>
{{ text }}
</template>
<slot name="bodyCell" v-bind="{ column, record, index, text } || {}"></slot>
</template>
</a-table>
@@ -113,8 +112,8 @@
<style scoped lang="less">
:deep(.ant-table-thead > tr > th) {
color: var(--tableFontColor) !important;
background: var(--tableHeadBg) !important;
border-top: 1px solid var(--tableHeadBg) !important;
background: #073063 !important;
border-top: 1px solid #073063 !important;
border-bottom: none;
padding: 9px 9px;
text-align: center;
@@ -24,7 +24,7 @@ export function useDepart() {
async function getOptionData() {
const { result = [], code } = await allSecondaryDeparts();
if (code == 200) {
let res = [{ departName: '长庆油田', orgCode: 'A01' }, ...result];
let res = [...result];
setOption(res);
}
}
+2
View File
@@ -2,10 +2,12 @@ import { get } from '/@/api/request.ts';
export enum Api {
allList = '/health-emergency/emergency/tblAmbulanceGps/getAllList',
allListNew = '/health-emergency/emergency/LargeScreenNew/map',
getAmbulanceList = '/health-emergency/emergency/tblAmbulanceGps/getAmbulanceList',
}
// 获取所有资源
export const getAllList = (params) => get(Api.allList, params);
export const getAllListNew = (params) => get(Api.allListNew, params);
//获取救护车GPS信息
export const getAmbulanceList = (params) => get(Api.getAmbulanceList, params);
+53 -28
View File
@@ -1,44 +1,72 @@
import { getAllList, getAmbulanceList } from '/@/components/xianMap/xianMapApi.ts';
import { getAllList, getAllListNew, getAmbulanceList } from '/@/components/xianMap/xianMapApi.ts';
// export enum TabType {
// all = '', //所有资源
// youTianYiYuan = '1', //油田医院
// heZuoYiYuan = '2', //合作医院
// yiLiaoDian = '3', //医疗点
// jiuHuChe = '5', //救护车
// zhiShengJi = '4', //直升机
// diFangYiYuan = '6', //地方医院
// }
//
// export const tabList = [
// {
// name: '所有资源',
// type: TabType.all,
// },
// {
// name: '油田医院',
// type: TabType.youTianYiYuan,
// },
// {
// name: '医疗点',
// type: TabType.yiLiaoDian,
// },
// {
// name: '救护车',
// type: TabType.jiuHuChe,
// },
// {
// name: '合作医院',
// type: TabType.heZuoYiYuan,
// },
// {
// name: '地方医院',
// type: TabType.diFangYiYuan,
// },
// // {
// // name: '直升机',
// // type: TabType.zhiShengJi,
// // },
// {
// name: '急救路线',
// },
// ];
export enum TabType {
all = '', //所有资源
youTianYiYuan = '1', //油田医院
heZuoYiYuan = '2', //合作医院
yiLiaoDian = '3', //医疗点
jianKangXiaoWu = '2', //健康小屋
jiuHuChe = '5', //救护车
zhiShengJi = '4', //直升机
diFangYiYuan = '6', //地方医院
}
export const tabList = [
{
name: '所有资源',
type: TabType.all,
},
{
name: '油田医院',
type: TabType.youTianYiYuan,
name: '健康小屋',
type: TabType.jianKangXiaoWu,
},
{
name: '医疗点',
type: TabType.yiLiaoDian,
name: '油田医院',
type: TabType.youTianYiYuan,
},
{
name: '救护车',
type: TabType.jiuHuChe,
},
{
name: '合作医院',
type: TabType.heZuoYiYuan,
},
{
name: '地方医院',
type: TabType.diFangYiYuan,
},
// {
// name: '直升机',
// type: TabType.zhiShengJi,
// },
{
name: '急救路线',
},
@@ -101,13 +129,10 @@ export function aircraftContent() {
}
export function mapApiSwitch(type, params: any) {
const basicParams = {
lat: 34, //纬度34
lon: 108, //经度
};
// 全部 油田 医疗点 合作医院
if ([TabType.all, TabType.youTianYiYuan, TabType.yiLiaoDian, TabType.heZuoYiYuan, TabType.jiuHuChe, TabType.jiuHuChe].includes(type)) {
return getAllList({ ...basicParams, ...params });
if ([TabType.all, TabType.youTianYiYuan, TabType.jianKangXiaoWu, TabType.jiuHuChe].includes(type)) {
// return getAllList({ ...params });
return getAllListNew({ ...params });
}
// if ([TabType.jiuHuChe].includes(type)) {
// return getAmbulanceList({});
+23 -26
View File
@@ -1,6 +1,7 @@
import { createRouter, createWebHistory, Router, RouteRecordRaw } from 'vue-router';
import { setCurrentPath } from '/@/enum/pageEnum.ts';
import { getAuthCache } from '/@/utils/auth.ts';
import { TOKEN_KEY } from '/@/enum/cacheEnum.ts';
const routes: Array<RouteRecordRaw> = [
{
@@ -25,6 +26,22 @@ const routes: Array<RouteRecordRaw> = [
},
component: () => import('/@/views/indexSun.vue'),
},
{
path: '/indexSon',
name: 'indexSon',
meta: {
title: '心血管监测',
},
component: () => import('/@/views/indexSon.vue'),
},
{
path: '/home1',
name: 'index1',
meta: {
title: '副屏1',
},
component: () => import('/@/views/index.vue'),
},
];
const router: Router = createRouter({
@@ -38,32 +55,12 @@ router.beforeEach((to, from, next) => {
if (to.path !== '/login' && to.path !== '/home') {
setCurrentPath(to.path);
}
let flag1 = getAuthCache('flag1')?.includes('yinchuan');
let flag2 = getAuthCache('flag2')?.includes('xian');
if (to.path == '/yinChuanTest') {
const flag = getAuthCache('flag3');
const token = getAuthCache(TOKEN_KEY);
if (!flag || !token) {
return next({ path: '/login' });
}
next();
}
if (flag1 && flag2) {
next();
} else {
// 检查是否有权访问目标页面
if (yinchuan.includes(to.path)) {
// 如果在 yinchuan 列表中,并且有权限,则导航到目标页面
if (flag1) {
next();
} else {
next({ path: '/screenLogin' });
}
}
if (xian.includes(to.path)) {
// 如果在 xian 列表中,并且有权限,则导航到目标页面
if (flag2) {
next();
} else {
next({ path: '/login' });
}
}
next();
}
});
export default router;
@@ -4,18 +4,11 @@
<div v-if="useForm" class="form-container">
<Form :model="formRecord" :label-width="100" v-bind="formItemLayout">
<a-form-item label="性别">
<a-select v-model:value="formRecord.sex" placeholder="请选择" :options="sexTypeList"></a-select>
<a-select v-model:value="formRecord.sex" placeholder="请选择" :options="sexTypeList" />
</a-form-item>
</Form>
</div>
<BasicTable
ref="registerTable"
class="table-container"
:class="[themeType]"
:key="visible"
:columns="columns"
:apiParams="formState"
></BasicTable>
<BasicTable ref="registerTable" class="table-container" :class="[themeType]" :key="visible" :columns="columns" :apiParams="formState" />
</template>
</Dialog>
</template>
+83 -11
View File
@@ -8,13 +8,14 @@
<div class="sun-body-content">
<div class="sun-body-left">
<div class="sun-body-left-one">
<OneL />
<OneL @handle-click="handleOneLeftClick" :center-id="centerId" />
</div>
<div class="sun-body-left-two">
<twoL />
<twoL @handle-view="handleTwoLClick" />
</div>
<div class="sun-body-left-three" style="margin-bottom: 0">
<threeL />
<!-- <threeL />-->
<threeNewL />
</div>
</div>
<div class="sun-body-center">
@@ -22,21 +23,79 @@
</div>
<div class="sun-body-right">
<div class="sun-body-right-one">
<oneR :title="'体检数据'" :type="1" />
<oneR @handle-view="handleOneRClick" />
</div>
<div class="sun-body-right-two">
<oneR :title="'健康打卡数据'" :type="2" />
<twoR />
</div>
<div class="sun-body-right-three">
<threeR />
</div>
</div>
</div>
</div>
<PhoneDialog ref="phoneDialogRef" :title="phoneDialogTitle" :useForm="true" :setting="setting" :phoneType="phoneType" />
<IndexModal ref="indexModalRef" :title="indexModalTitle" :useForm="true" :column="indexColumn" :firstForm="firstFormOne"> </IndexModal>
</template>
<script setup lang="ts">
import twoL from '/@/views/indexSun/twoL.vue';
import threeL from '/@/views/indexSun/threeL.vue';
// import threeL from '/@/views/indexSun/threeL.vue';
import OneL from '/@/views/indexSun/oneL.vue';
import twoL from '/@/views/indexSun/twoL.vue';
import threeNewL from '/@/views/indexSun/threeNewL.vue';
import oneR from '/@/views/indexSun/oneR.vue';
import twoR from '/@/views/indexSun/twoR.vue';
import threeR from '/@/views/indexSun/threeR.vue';
import CenterMap from '/@/views/indexSun/centerMap.vue';
import { ServerDetailType } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { nextTick, onMounted, ref } from 'vue';
import { columns, fromLists } from '/@/views/indexSun/indexSun.ts';
import PhoneDialog from '/@/views/components/phoneDialog/phoneDialog.vue';
import { DataType, getSettings } from '/@/utils/settings.ts';
import IndexModal from '/@/views/indexSun/indexModal.vue';
import router from '/@/router';
import { getAuthCache } from '/@/utils/auth.ts';
//0:处置 1:处理 2:呼入 3:全部
const phoneType = ref('');
const phoneDialogTitle = ref('呼入电话');
const phoneDialogRef = ref();
const indexModalRef = ref();
const indexModalTitle = ref();
const indexColumn: any = ref([]);
const setting = getSettings(DataType.xian);
const firstFormOne = ref();
const centerId = ref();
onMounted(() => {
const centerInfo = getAuthCache('centerInfo');
centerId.value = centerInfo.id;
console.log(centerInfo);
});
function handleOneLeftClick(item) {
const { name, key } = item;
//呼入电话
//受理电话
if (key == 'alerdyreceive' || key == 'gross') {
phoneType.value = ServerDetailType[key];
indexModalTitle.value = name;
firstFormOne.value = fromLists[0];
indexColumn.value = columns[0];
nextTick(() => {
indexModalRef.value.openDialog();
});
}
}
function handleTwoLClick() {
indexModalTitle.value = '主诉分类详情';
indexColumn.value = columns[1];
nextTick(() => {
indexModalRef.value.openDialog();
});
}
function handleOneRClick() {
console.log(12333);
router.push({
path: '/indexSon',
});
}
</script>
<style lang="less" scoped>
.sun-screen-box {
@@ -95,7 +154,8 @@
border-radius: 14px;
.one-l-box,
.two-l-box,
.three-l-box {
.three-l-box,
.three-new-l {
height: 100%;
}
}
@@ -109,14 +169,26 @@
}
.sun-body-right {
.sun-body-right-one,
.sun-body-right-two {
height: 49.5%;
.sun-body-right-two,
.sun-body-right-three {
border: 1px solid #00ccff;
border-radius: 14px;
.three-l-box {
margin-bottom: 10px;
.one-r-box,
.two-r-box,
.three-r-box {
height: 100%;
}
}
.sun-body-right-one {
height: 30%;
}
.sun-body-right-two {
height: 42%;
}
.sun-body-right-three {
height: 26%;
}
}
}
}
+69 -3
View File
@@ -63,12 +63,14 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { tabList, legendList } from '/@/views/indexSun/indexSun.ts';
import { tabList, legendList, infoContent } from '/@/views/indexSun/indexSun.ts';
import { message } from 'ant-design-vue';
import { innerLineLight, outerLineOption } from '/@/assets/mapUtils/mapConstant.ts';
import { Map } from '/@/assets/mapUtils/map.ts';
import { aircraft, getKmStr, getTimeStr, mapApiSwitch, TabType } from '/@/components/xianMap/xianMapHooks.ts';
import { useDetailStore } from '/@/store/modules/detailData.ts';
import $bus from '/@/utils/bus.ts';
import { earlyWarning } from '/@/utils/busConstant.ts';
const list = ref(tabList);
const currentIndex = ref(0);
@@ -104,6 +106,19 @@
Map.map && Map.map.on('zoomend', setLevel);
Map.map && Map.map.on('zoomend', setLevel);
});
$bus.on(earlyWarning, (params) => {
console.log(params, 12323);
drawMarker(params);
});
document.addEventListener('click', (e) => {
let t = e.target.closest('.viewBtn');
if (t) {
console.log(t.id);
if (t.id) {
handleClcikDetail(JSON.parse(t.id));
}
}
});
});
function setLevel() {
//获取当前地图级别
@@ -182,8 +197,9 @@
}
});
}
async function getMapData(type, params = {}) {
async function getMapData(type, params = { type: '' }) {
try {
console.log(type, params, 'asghujis');
const { code, result } = await mapApiSwitch(type, params);
if (code == 200) {
if (Array.isArray(result) && result.length > 0) {
@@ -200,7 +216,14 @@
</div>`;
},
},
() => {},
async (val) => {
console.log(val);
Map.createInfoModal({ option: val, content: infoContent(val) });
// const viewBtn = document.getElementById(val.id);
// viewBtn.onclick = () => {
// handleClcikDetail(val);
// };
},
true
);
} else {
@@ -218,6 +241,9 @@
showDrivingPanel.value = false;
emits('clearHospitalList');
}
function handleClcikDetail(res) {
console.log(res);
}
function setTitle({ time, distance }) {
let str = '全程';
str += getTimeStr(time);
@@ -238,6 +264,15 @@
}
});
}
function drawMarker(data: any) {
console.log(data);
const { lon, lat } = data;
if (!lon || !lat) {
Map.clearMarker();
return;
}
Map.createMarker({ ...data, realName: data.userName });
}
</script>
<style lang="less" scoped>
@@ -483,5 +518,36 @@
}
}
}
:deep(.modal-box) {
width: 330px;
height: 220px;
padding: 10px 20px;
display: flex;
flex-direction: column;
justify-content: space-around;
.modal-item {
display: flex;
justify-content: space-between;
.item-one {
width: 50%;
}
.item-two {
color: #00ccff;
}
}
.modal-btn {
display: flex;
justify-content: center;
.view-btn {
padding: 5px;
width: 60%;
text-align: center;
color: #00ccff;
border-radius: 5px;
cursor: pointer;
border: 1px solid #00ccff;
}
}
}
}
</style>
+149
View File
@@ -0,0 +1,149 @@
<template>
<Dialog class="index-modal" :openVis="visible" width="60%" :title="dialogTitle" @close="closeDialog" :maskClosable="false">
<template #container>
<div v-if="useForm" class="form-container">
<Form :model="formRecord" :label-width="100" v-bind="formItemLayout">
<slot name="searchFirst"></slot>
<a-form-item v-for="(item, index) in firstForm" :label="item.label" :key="index">
<a-input :placeholder="item.placeholder" v-if="item.type == 'input'" v-model:value="formRecord[item.field]" />
</a-form-item>
<a-form-item label="单位">
<a-select placeholder="选择单位" v-model:value="orgCode" :options="option" :field-names="fieldNames" />
</a-form-item>
<a-form-item label="部门">
<a-select placeholder="选择单位" @focus="changeDept" v-model:value="orgCode" :options="option" :field-names="fieldNames" />
</a-form-item>
<slot name="searchSecond"></slot>
<a-form-item label="性别">
<a-select v-model:value="formRecord.sex" placeholder="请选择" :options="sexTypeList" />
</a-form-item>
</Form>
<div class="form-btn">
<a-button @click="handleClicksearch">搜索</a-button>
</div>
</div>
<BasicTable ref="registerTable" class="table-container" :key="visible" :columns="column" :apiParams="formState" />
</template>
</Dialog>
</template>
<script setup lang="ts">
import Dialog from '/@/components/dialog/Dialog.vue';
import { useDialog } from '/@/views/components/dialogHooks.ts';
import { ref, watch } from 'vue';
import { SexType, sexTypeList } from '/@/utils/settings.ts';
import { Form } from 'ant-design-vue';
import { useDepart } from '/@/components/secondaryScreen/secondMap/secondMapHooks.ts';
import { message } from 'ant-design-vue';
import BasicTable from '/@/components/secondaryScreen/secondMap/components/basicTable/BasicTable.vue';
const props = defineProps({
title: {
type: String,
default: () => '',
},
useForm: {
type: Boolean,
default: () => false,
},
column: {
type: Array,
default: () => [],
},
firstForm: {
type: Array,
default: () => [],
},
});
const formState = ref();
const dialogTitle = ref('');
const formRecord = ref({
sex: SexType.all,
});
function changeDept() {
if (!orgCode.value) {
return message.warning('请先选择单位');
}
}
const formItemLayout = {
labelCol: {
style: { width: '60px' },
...props.labelCol,
},
wrapperCol: {
span: 24,
...props.wrapperCol,
},
};
watch(props, () => {
dialogTitle.value = props.title;
getField();
});
function getField() {
let result = {};
props.firstForm.map((item) => {
result[item.field] = '';
});
formRecord.value = {
...formRecord.value,
...result,
};
console.log(formRecord.value);
}
function handleClicksearch() {
console.log(formRecord.value);
}
const { orgCode, option, fieldNames, setOrgCode } = useDepart();
const { visible, closeDialog, openDialog } = useDialog({ title: dialogTitle.value });
defineExpose({
openDialog,
});
</script>
<style lang="less" scoped>
:deep(.dialog) {
border: 1px solid #00ccff !important;
}
.index-modal {
border: 1px solid #00ccff !important;
:deep(.dialog .ant-modal-title) {
background: red !important;
}
.form-container {
margin: 10px 0;
display: flex;
justify-content: space-between;
:deep(.ant-form-item-label > label) {
color: var(--formLabel);
}
:deep(.ant-input) {
color: #fff !important;
background-color: #082147 !important;
border: 1px solid transparent !important;
border-radius: 4px !important;
}
:deep(.ant-form) {
width: 80%;
display: flex;
.ant-form-item {
flex: 1;
}
}
.form-btn {
flex: 1;
text-align: right;
padding-right: 20px;
:deep(.ant-btn) {
background: #082147;
border: 1px solid #00ccff;
color: #fff;
border-radius: 4px;
}
//margin: 0 15px;
}
}
.table-container {
margin: 0 10px;
}
}
</style>
+7
View File
@@ -0,0 +1,7 @@
import { post } from '/@/api/request.ts';
enum Api {
statisticsNew = '/health-emergency/emergency/LargeScreenNew/statisticsNew',
}
export const statisticsNewApi = (params) => post(Api.statisticsNew, params);
+110 -6
View File
@@ -1,10 +1,8 @@
import * as echarts from 'echarts';
import { legend1, legend2, legend3, legend4, legend5 } from '/@/components/xianMap/xianMapHooks.ts';
export const legend1 = new URL('/@/assets/img/legend1.png', import.meta.url).href;
export const legend2 = new URL('/@/assets/img/legend2.png', import.meta.url).href;
export const legend2 = new URL('/@/assets/img/legend5.png', import.meta.url).href;
export const legend3 = new URL('/@/assets/img/legend3.png', import.meta.url).href;
export const legend4 = new URL('/@/assets/img/legend4.png', import.meta.url).href;
export const legend5 = new URL('/@/assets/img/legend5.png', import.meta.url).href;
export function getClassCharts(dx, dy) {
return {
grid: {
@@ -118,9 +116,115 @@ export const tabList = [
},
];
export const legendList = [
{ img: legend2, text: '健康小屋', color: '#1BEFF6' },
{ img: legend1, text: '油田医院', color: '#D86AF7' },
{ img: legend2, text: '医疗点', color: '#39D78B' },
{ img: legend3, text: '救护车', color: '#EE7E31' },
{ img: legend4, text: '合作医院', color: '#3BAAFA' },
{ img: legend5, text: '地方医院', color: '#1BEFF6' },
];
export function infoContent(res) {
return `
<div class="modal-box">
<div class="modal-item">
<span class="item-one">单位:</span>
<span class="item-two">${res.orgName ? res.orgName : '--'}</span>
</div>
<div class="modal-item">
<span class="item-one">关爱人数:</span>
<span class="item-two">${res.loveNum ? res.loveNum : '--'}</span>
</div>
<div class="modal-item">
<span class="item-one">地点:</span>
<span class="item-two">${res.name ? res.name : '--'}</span>
</div>
<div class="modal-btn">
<div class="view-btn viewBtn" id='${JSON.stringify(res)}'>查看详情</div>
</div>
</div> `;
}
const columns1 = [
{
title: '姓名',
dataIndex: 'realName',
key: 'realName',
},
{
title: '单位',
dataIndex: 'departName',
key: 'departName',
ellipsis: true,
},
{
title: '部门',
dataIndex: 'orgName',
key: 'orgName',
ellipsis: true,
},
{
title: '性别',
dataIndex: 'sex_dictText',
key: 'sex_dictText',
width: 80,
},
{
title: '时间',
dataIndex: 'time',
key: 'time',
},
{
title: '电话',
dataIndex: 'phone',
key: 'phone',
},
];
const columns2 = [
{
title: '被救助人',
dataIndex: 'realName',
key: 'realName',
},
{
title: '单位',
dataIndex: 'realName',
key: 'realName',
},
{
title: '部门',
dataIndex: 'realName',
key: 'realName',
},
{
title: '性别',
dataIndex: 'realName',
key: 'realName',
},
{
title: '救助方式',
dataIndex: 'realName',
key: 'realName',
},
{
title: '救助时间',
dataIndex: 'realName',
key: 'realName',
},
{
title: '联系电话',
dataIndex: 'realName',
key: 'realName',
},
];
const fromList = [
{
label: '姓名',
field: 'realName',
type: 'input',
placeholder: '请输入姓名',
},
];
export const columns = [columns1, columns2];
export const fromLists = [fromList];
+62 -8
View File
@@ -3,16 +3,16 @@
<div class="title"> 服务详情数据 </div>
<div class="content">
<div class="type-time">
<div @click="clickChooseType('0')" :class="[chooseType === '0' ? 'selected' : 'no-selected']">
<div @click="clickChooseType('4')" :class="[chooseType === '4' ? 'selected' : 'no-selected']">
本周
<div>
<div v-if="chooseType === '0'" class="triangle"></div>
<div v-if="chooseType === '4'" class="triangle"></div>
</div>
</div>
<div @click="clickChooseType('1')" :class="[chooseType === '1' ? 'selected' : 'no-selected']">
<div @click="clickChooseType('3')" :class="[chooseType === '3' ? 'selected' : 'no-selected']">
本月
<div>
<div v-if="chooseType === '1'" class="triangle"></div>
<div v-if="chooseType === '3'" class="triangle"></div>
</div>
</div>
<div @click="clickChooseType('2')" :class="[chooseType === '2' ? 'selected' : 'no-selected']">
@@ -23,25 +23,79 @@
</div>
</div>
<div class="server-container">
<div v-for="(item, index) in statistics" class="server-item" :key="index">
<div
v-for="(item, index) in statistics"
:class="[['gross', 'alerdyreceive'].includes(item.key) ? 'hasCursor' : '']"
class="server-item"
:key="index"
@click="handleClick(item)"
>
<span>{{ item?.name }}</span>
<span>{{ item?.value }}123</span>
<span>{{ item?.value }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { useStatistics } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { statisticsNewApi } from '/@/views/indexSun/indexSun.api.ts';
import { caching, useSession } from '/@/hooks/autoRefresh/caching.ts';
import { useDetailStore } from '/@/store/modules/detailData.ts';
const chooseType = ref('0');
const { LEFT_KEY1 } = caching;
const props = defineProps({
centerId: {
type: String,
default: () => '',
},
});
const useDetail = useDetailStore();
const emit = defineEmits(['handleClick']);
const chooseType = ref('4');
const { statistics, setStatistics, getStatistics } = useStatistics();
const { setSession, getSession } = useSession();
watch(props, () => {
getOneLeftInfo();
});
watch(
() => chooseType.value,
() => {
getOneLeftInfo();
}
);
async function getOneLeftInfo() {
const params = {
condition: chooseType.value,
centerId: props.centerId,
};
statisticsNewApi(params).then((res) => {
console.log(res);
if (res.code != 200 || !res.result) {
return;
}
setSession(LEFT_KEY1, JSON.stringify(res.result));
setValue(res.result);
});
}
function setValue(result) {
let { alerdyreceive = '', totalacceptance = '' } = result;
setStatistics(result);
if (alerdyreceive || totalacceptance) {
useDetail.setAlerdyreceive(alerdyreceive);
useDetail.setTotalacceptance(totalacceptance);
}
}
function clickChooseType(index) {
if (chooseType.value === index) return;
chooseType.value = index;
}
function handleClick(item) {
emit('handleClick', item);
}
</script>
<style lang="less" scoped>
.one-l-box {
+16 -17
View File
@@ -1,18 +1,21 @@
<template>
<div class="three-l-box">
<div class="one-r-box">
<div class="title">
<span>{{ props.title }}</span>
<span class="look-view">查看详情</span>
<span>健康终端报警</span>
<span class="look-view" @click="handleView">查看详情</span>
</div>
<div class="content">
<div class="content-item">
<template v-if="scrollList.length > 0">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="5" v-bind="{ step: 0.2 }">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :copyNum="3" :limitScrollNum="5" v-bind="{ step: 0.2 }">
<div class="item-d" v-for="(item, index) in scrollList" :key="index">
<div>张二雷{{ index }}</div>
<div>40</div>
<div :style="{ color: props.type == 1 ? '#f24439' : '#f6ff00' }">体重(超重)</div>
<div style="color: #f6ff00">压力异常(82)</div>
<div>2025-10-26 22:29:58</div>
<div class="item-d-img">
<img :src="pointPng" alt="" />
<img :src="addressPng" alt="" />
</div>
</div>
</vue3-seamless-scroll>
</template>
@@ -32,23 +35,19 @@
import pointPng from '/@/assets/indexSun/point.png';
import addressPng from '/@/assets/indexSun/address.png';
const loading = ref(true);
const props = defineProps({
title: {
type: String,
default: '',
},
type: {
type: Number,
default: 1,
},
});
const scrollList = ref<any[]>([{}, {}, {}, {}, {}, {}, {}, {}]);
const emit = defineEmits(['handleView']);
function handleView() {
emit('handleView');
}
</script>
<style lang="less" scoped>
.three-l-box {
.one-r-box {
background: rgba(8, 75, 100, 0.2);
display: flex;
flex-direction: column;
letter-spacing: 0px;
.title {
height: 40px;
border-radius: 14px 14px 0 0;
+3 -3
View File
@@ -7,7 +7,7 @@
<div class="content">
<div class="content-item">
<template v-if="scrollList.length > 0">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="5" v-bind="{ step: 0.2 }">
<!-- <vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="5" v-bind="{ step: 0.2 }">-->
<div class="item-d" v-for="(item, index) in scrollList" :key="index">
<div>张二雷{{ index }}</div>
<div style="color: #f6ff00">压力异常(82)</div>
@@ -17,7 +17,7 @@
<img :src="addressPng" alt="" />
</div>
</div>
</vue3-seamless-scroll>
<!-- </vue3-seamless-scroll>-->
</template>
<template v-else>
<div style="height: 100%; width: 100%; display: flex; align-items: center; justify-content: center">
@@ -65,8 +65,8 @@
height: calc(100% - 40px);
.content-item {
height: 100%;
overflow: hidden;
letter-spacing: 1px;
overflow: auto;
.scroll {
width: 98%;
height: 100%;
+87
View File
@@ -0,0 +1,87 @@
<template>
<div class="three-new-l">
<div class="title">
<span>体检人数统计</span>
<!-- <span class="look-view">查看详情</span>-->
</div>
<div class="content">
<div class="content-item">
<template v-if="scrollList.length > 0">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :copyNum="3" :limitScrollNum="5" v-bind="{ step: 0.2 }">
<div class="item-d" v-for="(item, index) in scrollList" :key="index">
<div style="display: flex; align-items: center">
<div style="margin-right: 10px">
<img :src="hospitalPng" alt="" />
</div>
克拉玛依市中西医结合医院(市人民医院)
</div>
<div>23</div>
</div>
</vue3-seamless-scroll>
</template>
<template v-else>
<div style="height: 100%; width: 100%; display: flex; align-items: center; justify-content: center">
<Empty :description="'暂无数据'" />
</div>
</template>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
import { Empty } from 'ant-design-vue';
import { ref } from 'vue';
import hospitalPng from '/@/assets/indexSun/hospital.png';
const scrollList = ref<any[]>([{}, {}, {}, {}, {}, {}, {}, {}]);
</script>
<style lang="less" scoped>
.three-new-l {
background: rgba(8, 75, 100, 0.2);
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
.look-view {
font-size: 14px;
cursor: pointer;
}
}
.content {
padding: 10px 20px;
height: calc(100% - 40px);
.content-item {
height: 100%;
overflow: hidden;
.item-d {
height: 40px;
display: flex;
align-items: center;
color: #ffffff;
justify-content: space-between;
font-size: 14px;
letter-spacing: 0;
margin-bottom: 20px;
cursor: pointer;
.item-d-img {
img {
display: inline-block;
width: 32px;
height: 32px;
cursor: pointer;
}
}
}
}
}
}
</style>
+73
View File
@@ -0,0 +1,73 @@
<template>
<div class="three-r-box">
<div class="title">
<span>体检数据</span>
<!-- <span class="look-view">查看详情</span>-->
</div>
<div class="content">
<div class="content-item">
<template v-if="scrollList.length > 0">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :copyNum="3" :limitScrollNum="4" v-bind="{ step: 0.2 }">
<div class="item-d" v-for="(item, index) in scrollList" :key="index">
<div>体检总人数</div>
<div style="font-weight: bold">18000</div>
</div>
</vue3-seamless-scroll>
</template>
<template v-else>
<div style="height: 100%; width: 100%; display: flex; align-items: center; justify-content: center">
<Empty :description="'暂无数据'" />
</div>
</template>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
const scrollList = ref<any[]>([{}, {}, {}, {}, {}, {}, {}, {}]);
import { Empty } from 'ant-design-vue';
import { ref } from 'vue';
</script>
<style lang="less" scoped>
.three-r-box {
background: rgba(8, 75, 100, 0.2);
display: flex;
flex-direction: column;
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
.look-view {
font-size: 14px;
cursor: pointer;
}
}
.content {
padding: 10px 20px;
height: calc(100% - 40px);
.content-item {
height: 100%;
overflow: hidden;
.item-d {
//background: pink;
height: 40px;
line-height: 40px;
display: flex;
font-size: 14px;
color: #fff;
justify-content: space-between;
}
}
}
}
</style>
+8 -1
View File
@@ -2,7 +2,7 @@
<div class="two-l-box">
<div class="title">
<span>主诉分类</span>
<span class="look-view">查看详情</span>
<span class="look-view" @click="handleView">查看详情</span>
</div>
<div class="content">
<div class="content-search">
@@ -63,6 +63,13 @@
const dy = [46, 39, 18];
let option = getClassCharts(dx, dy);
myChart.value.setOption(option);
window.addEventListener('resize', () => {
myChart.value.resize();
});
}
const emit = defineEmits(['handleView']);
function handleView() {
emit('handleView');
}
</script>
<style lang="less" scoped>
+188
View File
@@ -0,0 +1,188 @@
<template>
<div class="two-r-box">
<div class="title">
<span>健康打卡数据</span>
<!-- <span class="look-view">查看详情</span>-->
</div>
<div class="content">
<div class="content-item">
<div class="content-item-info">
<div class="content-item-name" style="font-size: 16px">
<div class="content-item-img">
<img :src="WeightPng" alt="" />
</div>
减重打卡
</div>
<div class="content-item-clock">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">86</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
<div class="content-item-clock" style="margin-bottom: 0">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">86</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
</div>
</div>
<div class="content-item">
<div class="content-item-info">
<div class="content-item-name" style="font-size: 16px">
<div class="content-item-img">
<img :src="WeightPng" alt="" />
</div>
减重打卡
</div>
<div class="content-item-clock">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">86</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
<div class="content-item-clock" style="margin-bottom: 0">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">86</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
</div>
</div>
<div class="content-item" style="margin-bottom: 0">
<div class="content-item-info">
<div class="content-item-name" style="font-size: 16px">
<div class="content-item-img">
<img :src="WeightPng" alt="" />
</div>
减重打卡
</div>
<div class="content-item-clock">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">12386</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
<div class="content-item-clock" style="margin-bottom: 0">
<div>
<span class="clock-text">今日打卡人数</span>
<span class="clock-num1">86</span>
</div>
<div>
<span class="clock-text">异常人数</span>
<span class="clock-num2">86</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import WeightPng from '/@/assets/indexSun/weightClock.png';
import FatPng from '/@/assets/indexSun/fatClock.png';
import BloodPng from '/@/assets/indexSun/bloodClock.png';
</script>
<style lang="less" scoped>
.two-r-box {
background: rgba(8, 75, 100, 0.2);
display: flex;
flex-direction: column;
letter-spacing: 0;
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
.look-view {
font-size: 14px;
cursor: pointer;
}
}
.content {
height: calc(100% - 40px);
padding: 10px 30px 10px 15px;
display: flex;
flex-direction: column;
.content-item {
flex: 1;
margin-bottom: 5px;
display: flex;
.content-item-img {
margin-right: 10px;
img {
width: 32px;
margin-top: -3px;
}
}
.content-item-info {
flex: 1;
color: #fff;
display: flex;
flex-direction: column;
justify-content: space-around;
font-size: 14px;
.content-item-name,
.content-item-clock {
width: 100%;
display: flex;
align-items: center;
}
.content-item-clock {
padding-left: 42px;
justify-content: space-between;
> div {
width: 49%;
padding-bottom: 2px;
margin-bottom: 5px;
> span {
border-bottom: 1px dashed #fff;
}
}
.clock-text {
padding-bottom: 1px;
}
.clock-num1,
.clock-num2 {
font-size: 16px;
}
.clock-num1 {
color: #22e8ff;
}
.clock-num2 {
color: #f24439;
}
}
}
}
}
}
</style>
+2 -2
View File
@@ -191,7 +191,7 @@
try {
let { code, result, message: msg } = await getAuth();
let centerInfo = {};
if(route.path !== PageEnum.Q_SCREEN_LOGIN) {
if (route.path !== PageEnum.Q_SCREEN_LOGIN) {
try {
let { result } = await getEmergencyCenterApi();
centerInfo = result;
@@ -220,7 +220,7 @@
//1如果有权限 2025-06-16补充判断,如果登陆路由为qLogin 青海登陆,则不走原有逻辑
//1.2若果是有两种权限
// debugger;
if(route.path === PageEnum.Q_SCREEN_LOGIN && flag4) {
if (route.path === PageEnum.Q_SCREEN_LOGIN && flag4) {
goPath = PageEnum.Q_SCREEN;
} else if (flag1 && flag2) {
// 1.2.1 如果是登录地址是西安