Compare commits

...
138 Commits
Author SHA1 Message Date
xf 8b9c3abf77 update: 初始化 2025-06-30 11:09:27 +08:00
weixin 2db1e6d33c update
1.青海大屏
2025-06-19 16:15:43 +08:00
weixin 25b8acdda6 update
1.修改websocket,多窗口可以同时弹窗
2025-05-23 14:16:01 +08:00
weixin 736ee91e93 update
1.手表监测弹窗上报时间/发生时间修改
2025-05-08 09:46:48 +08:00
weixin fd02cf131a update
1.修改手表监测来通知,更新页面数据
2025-04-27 15:24:55 +08:00
weixin 48a137133d update
1.右上角手表应急添加日月周累计(庆阳大屏)
2025-04-27 09:37:20 +08:00
weixin 5c3bf4a7ed update 2025-04-21 10:41:59 +08:00
weixin 35c5625e1b update
1.添加庆阳大屏柱状图
2025-04-21 10:24:47 +08:00
weixin 8dc44b465b update
1.修改查看健康终端报警,不需要时间筛选
2025-04-03 12:36:29 +08:00
weixin 58d3b5a933 update
1.修改table模块,改回原有逻辑
2025-03-25 15:34:10 +08:00
weixin 988c2365de update
1.修改大屏逻辑,只有庆阳大屏查询当天数据,其余大屏查询所有数据
2.修改table模块,监听变化后,才更新列表
2025-03-25 11:59:16 +08:00
weixin 2fac32d002 update
1.修改庆阳大屏
2025-03-11 18:30:30 +08:00
weixin 0b48810f5c update
1.手表监测添加参数,查询当天信息
2025-03-05 15:20:20 +08:00
weixin a4bddba648 update
1.修改提示弹窗
2024-12-12 16:23:05 +08:00
weixin 8e9426eb45 update
1.添加弹窗提示音
2024-12-12 16:13:25 +08:00
weixin 6484e08fdc update
1.修改标准化大屏标题逻辑
2024-12-08 12:01:24 +08:00
项富 cd2a16dde5 修改手表弹窗 2024-12-02 13:26:01 +08:00
weixin bfb10320f7 update 2024-11-22 13:24:34 +08:00
weixin 7da4003f6b update
1.修改登录逻辑,大屏登录问题
2024-11-21 10:10:21 +08:00
weixin 01d2ee0665 update
1.修改登录逻辑,大屏登录问题
2024-11-21 09:45:16 +08:00
weixin 983c92ce48 update 2024-11-14 14:47:48 +08:00
weixin f81fb4a868 update
1.修改标准化大屏跳转逻辑,根据获取分中心信息,进行跳转至对应页面
2024-11-14 13:04:05 +08:00
weixin 1cfc2e5d89 update 2024-11-07 09:19:14 +08:00
weixin 35380d4114 update
1.打开标准化大屏的求助websocket
2024-10-31 09:23:11 +08:00
weixin af8fe6ca21 update
1.修改弹窗结构
2024-10-28 17:53:23 +08:00
weixin 68047001d1 update
1.银川大屏新增急救数据模块
2024-10-23 15:22:57 +08:00
weixin 09f4ddc2d7 update
1.银川大屏新增急救数据模块
2024-10-23 15:20:57 +08:00
weixin 27beb42eb0 update
1.修改逻辑,每次刷新后都会重新调用应急中心信息接口,重新处理
2024-10-16 17:38:15 +08:00
weixin 64feafb1d5 update
1.修改特殊大屏(宽度200%,偏移中心)
2.设置特殊参数/specialScreen
3.添加隐藏退出功能
2024-10-16 14:04:27 +08:00
zk 1aaf8e7120 update 2024-10-10 13:54:17 +08:00
zk 4394844890 文件 2024-10-10 13:17:07 +08:00
zk 3df70a2b3f update 2024-10-09 09:40:20 +08:00
zk f3ca399b85 update 2024-10-09 09:39:50 +08:00
zk b525fc08eb update 2024-10-09 09:21:53 +08:00
zk 216d0be436 update 2024-09-29 11:20:39 +08:00
zk b0b2bf2838 update 2024-09-29 11:20:02 +08:00
zk 389ed8d5f1 update 2024-09-29 10:41:19 +08:00
zk 51e33f6f0b update 2024-09-27 11:10:58 +08:00
zk 46a3752d74 update 2024-09-23 17:20:51 +08:00
zk 1a05b92fee update 2024-09-23 16:52:02 +08:00
zk c2e0d26094 update 2024-09-23 16:50:53 +08:00
zk 278e91c262 update 2024-09-23 16:43:57 +08:00
zk ca4a9a8c28 update 地图接口调整 2024-09-20 14:45:13 +08:00
zk ed8fc6f8a6 update 2024-09-20 14:32:16 +08:00
项富 ed5810611f update: 修改接口路径,弹窗搬运 2024-09-20 14:30:48 +08:00
项富 b871eabb08 update: 几个弹窗 2024-09-20 13:59:12 +08:00
zk 51af62e164 update 2024-09-20 13:27:51 +08:00
zk 094e88a79e update 增加新版大屏 2024-09-20 09:28:11 +08:00
zk 01519c97ec update 调整模拟数据 2024-09-04 17:33:05 +08:00
zk 28cb5cbb9b update:测试界面不做登录校验 2024-09-03 17:39:01 +08:00
zk d166e3e2d6 update 2024-08-29 15:18:41 +08:00
zk 7693850d47 update 2024-08-29 15:14:04 +08:00
zk a9fedaf124 update 优化弹窗显示效果 2024-07-24 14:19:47 +08:00
zk 830ad950c3 update 2024-07-08 17:24:43 +08:00
zk e625073dcc update 2024-07-08 17:08:39 +08:00
zk e367d13c78 update 弹窗增加手机号字段,增加预警详情弹窗 2024-07-08 15:22:03 +08:00
zk b732e3ab64 update 2024-07-04 15:12:58 +08:00
zk 352948e98b update 增加应急单弹窗、调整echart图表 2024-07-03 10:31:13 +08:00
zk a1850b95b6 update 修改颜色 2024-07-02 13:59:18 +08:00
zk 9e8a5da257 update 调整大病人数类型 2024-07-02 10:35:46 +08:00
zk 8551369cfb update 云坐席弹窗WebSocket 2024-07-01 14:46:01 +08:00
zk 80745c9d8c update 2024-07-01 10:36:12 +08:00
zk 292a32a311 update 调整权限问题 2024-06-27 14:41:46 +08:00
zk 752405b9a4 update 2024-06-27 11:26:55 +08:00
zk 778e350959 update 调整样式· 2024-06-17 11:56:02 +08:00
zk de77657b64 update 调整样式 2024-06-17 10:45:19 +08:00
zk 205273fd61 update 调整应急大屏样式· 2024-06-16 14:46:23 +08:00
zk 1645f16579 update 调整样式 2024-06-15 18:26:15 +08:00
zk fc6e3a736e update 调整样式· 2024-06-15 16:22:48 +08:00
weixin dcf14220b3 update
1.副屏标题
2024-06-15 16:21:54 +08:00
zk 0f391ffc22 update 调整样式· 2024-06-15 15:51:18 +08:00
zk e16b9e054e update 调整样式· 2024-06-15 13:52:49 +08:00
weixin f6129b7aa4 update
1.更新西安大屏样式
2024-06-15 13:51:44 +08:00
zk 1adff85a83 update 调整样式· 2024-06-15 12:08:57 +08:00
weixin 78e5bab6a9 update
1.更新西安大屏样式
2024-06-15 12:06:57 +08:00
zk 7ee32fb8d9 update 调整样式· 2024-06-15 11:46:49 +08:00
zk 14c50baeed update 优化地图工具方法,调整地图样式 2024-06-14 18:11:09 +08:00
zk 83f768a4a0 update 增加菜单权限校验 2024-05-28 14:37:29 +08:00
zk 0eb5fad72f 增加地图元素清空功能,完成附近医院路线规划功能 2024-05-23 15:05:34 +08:00
zk 1599ffd6d8 add 添加图片 2024-05-22 17:06:03 +08:00
zk 062afc3d71 update 调整位置为空时的文字样式,调整表格组件 2024-05-21 16:11:13 +08:00
zk 8c7e4a6e91 update 关闭浏览器时缓存当前页面 2024-05-21 16:08:35 +08:00
zk 16e85fe15d update 银川地图中心点做特殊处理 2024-05-21 16:07:12 +08:00
zk f3f100cd18 update 进入登录页时验证缓存token是否有效 2024-05-21 16:06:02 +08:00
zk 510f34953f update 调整websocket 2024-05-20 15:25:12 +08:00
zk 60be7c4fe2 update 优化token失效后跳转登录页的逻辑 2024-05-20 11:14:09 +08:00
zk 6ff0b25f1b update 后台跳转大屏免登录,优化登录数据缓存 2024-05-18 15:16:10 +08:00
zk cb2a823d25 update 2024-05-17 16:12:10 +08:00
zk 7444e6ff75 update 2024-05-17 16:10:51 +08:00
weixin ce2b8f5837 update
1.修改列表分页问题
2024-05-17 13:25:28 +08:00
zk 13faaa92a6 update 调整银川大屏和西安大屏 2024-05-17 13:07:39 +08:00
zk 45aec85fad update 调整大屏各个模块参数及样式 2024-05-16 15:53:04 +08:00
zk adca7ae65e update 添加银川大屏 2024-05-16 15:51:02 +08:00
zk 1c908b0615 update 添加图标 2024-05-16 15:49:12 +08:00
zk 65a3ee7eb5 update 调整省边界线 2024-02-20 13:19:54 +08:00
zk 2def3738c2 更改 2024-02-20 13:18:30 +08:00
weixin ef3e1c3b31 update
1.修改睡眠模块,总览添加步数模块
2024-01-22 17:42:45 +08:00
zk 5cf32ce40e update:大屏调整 2024-01-22 15:49:00 +08:00
zk 84dfa935ea update:大屏调整 2024-01-12 15:07:49 +08:00
zk 3459db992c update 2024-01-09 14:16:30 +08:00
weixin f016fdc69f update
1.睡眠缺少单位问题
2023-12-29 14:54:46 +08:00
zk ecbd690117 Merge branch 'test' into dev
# Conflicts:
#	src/components/secondaryScreen/secondMap/components/userInfoModal/sleep.vue
2023-12-28 17:19:53 +08:00
zk 88c9ac1576 update 2023-12-28 17:16:08 +08:00
weixin 861d9e4798 update
1.睡眠图标缺失字段
2023-12-28 17:13:53 +08:00
zk 1d28db6839 Merge branch 'dev' into test 2023-12-27 18:34:47 +08:00
zk f93e2dccae update 2023-12-27 18:34:06 +08:00
zk 6352e5dd21 Merge branch 'dev' into test 2023-12-27 18:05:16 +08:00
zk 36f484d028 update 2023-12-27 18:00:39 +08:00
weixin 63eb01d641 update
1.用户数据左侧没有工号
2.样式问题
2023-12-27 17:55:35 +08:00
weixin a0ffce1fa7 update
1.睡眠模块:深睡、浅水颠倒问题
2023-12-27 16:05:46 +08:00
weixin 626fbf9085 update
1.压力模块接口调用错误
2023-12-27 14:44:13 +08:00
weixin c1474f0c64 update
1.体温模块字段变更
2023-12-27 10:59:49 +08:00
zk dfcf737258 update 2023-12-27 09:14:48 +08:00
zk 98abe8d9ca Merge branch 'dev' into test 2023-12-27 09:14:17 +08:00
zk 2e106c4731 update 2023-12-27 09:13:09 +08:00
zk dd89375d40 update 2023-12-26 17:39:59 +08:00
zk 541fbb4b0a update 2023-12-22 17:42:54 +08:00
zk 22a4132300 update 2023-12-22 17:15:26 +08:00
zk b9f2b3b521 update 2023-12-22 16:57:16 +08:00
zk dd5a47e7fb update 2023-12-21 16:42:22 +08:00
zk 5a33aa1df4 update 2023-12-21 14:07:18 +08:00
zk 568c0132e7 update 2023-12-21 09:04:17 +08:00
zk 9230f659c1 update 2023-12-21 09:02:45 +08:00
weixin 1c65f18bab update
1.修改样式
2023-12-20 10:36:22 +08:00
zk 3cc95902ae update 2023-12-20 10:25:06 +08:00
zk ce85f39c11 update 2023-12-20 09:08:13 +08:00
zk 26f4a6ad81 update 2023-12-20 09:05:44 +08:00
zk 8dccce0208 update 2023-12-19 18:10:46 +08:00
zk 3e53c75a6f update 2023-12-19 14:41:00 +08:00
zk e732938a34 update 2023-12-19 14:26:27 +08:00
zk cf29ea07c1 update 2023-12-19 12:49:00 +08:00
zk 5342774ca5 update 2023-12-19 12:41:15 +08:00
zk 9b5be1af25 update 2023-12-19 10:46:50 +08:00
zk 8cb7d4baf8 update 2023-12-19 09:09:11 +08:00
zk 12ae90f274 add svg 2023-12-19 09:04:24 +08:00
SkyJourney 2501a5e6be 构建去掉ts类型检测 2023-12-19 05:58:37 +08:00
SkyJourney 6c2510147f 更新自动化脚本 2023-12-19 05:51:36 +08:00
SkyJourney 6c5e3e8f06 添加开发环境和测试环境自动化配置,修正eslint配置和依赖 2023-12-19 05:37:04 +08:00
207 changed files with 22221 additions and 1457 deletions
+4
View File
@@ -0,0 +1,4 @@
# 选择更小体积的基础镜像
FROM nginx:stable-alpine
COPY ./default.conf /etc/nginx/conf.d
COPY ./dist /usr/share/nginx/html
+12
View File
@@ -0,0 +1,12 @@
version: "3.9"
services:
ms-service:
build:
dockerfile: Dockerfile
context: .
tags:
- "${IMAGE_NAME}:${IMAGE_TAG_LATEST}"
- "${IMAGE_NAME}:${IMAGE_TAG_COMMIT}"
- "${REGISTER_HOST}/${REGISTER_REPO}/${IMAGE_NAME}:${IMAGE_TAG_LATEST}"
- "${REGISTER_HOST}/${REGISTER_REPO}/${IMAGE_NAME}:${IMAGE_TAG_COMMIT}"
+31
View File
@@ -0,0 +1,31 @@
#版本
version: '3.9'
x-template:
service: &service_tmp
restart: always
tty: true
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
extra_hosts:
- "yg.dt.io:192.168.1.5"
#服务配置
services:
emergency-screen:
<<: *service_tmp
container_name: es_${PROFILE_NAME}
hostname: es_${PROFILE_NAME}
image: ${IMAGE_NAME}:${IMAGE_TAG_LATEST}
networks:
default:
name: ${NETWORK_NAME}
external: true
+8
View File
@@ -0,0 +1,8 @@
NODE_ENV=development
#开发环境
VITE_GLOB_API_URL=http://cqyt.dev.yg.dt.io
#应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor
#健康监测工具报警-websocket
VITE_GLOB_API_JIAN_CE=ws://cqyt.dev.yg.dt.io/health-emergency/websocket/emergency
+12 -4
View File
@@ -1,9 +1,17 @@
# 王昊地址
#VITE_GLOB_API_URL=http://192.168.1.3
#VITE_GLOB_API_URL=http://192.168.1.27
#开发环境
VITE_GLOB_API_URL=http://cqyt.dev.yg.dt.io
#VITE_GLOB_API_URL=https://api.cqygjk.com
#健康监测工具报警-websocket
#VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor
VITE_GLOB_API_YIN_JI=ws://192.168.1.27:7098/websocket/watchMonitor
#应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://cqyt.dev.yg.dt.io/health-watch/websocket/watchMonitor
#健康监测工具报警-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.27:7011/websocket/emergency
#西安云坐席
VITE_GLOB_API_XIAN_YUN=ws://192.168.1.27:7011/websocket/emergency3
#银川云坐席
VITE_GLOB_API_YIN_CHUAN=ws://192.168.1.27:7011/websocket/emergency4
+8 -3
View File
@@ -1,7 +1,12 @@
#后台地址
VITE_GLOB_API_URL=https://api.cqygjk.com
#应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://api.cqygjk.com/health-watch/websocket/watchMonitor
#健康监测工具报警-websocket
VITE_GLOB_API_JIAN_CE=ws://api.cqygjk.com/health-emergency/websocket/emergency
VITE_GLOB_API_YIN_JI=wss://api.cqygjk.com/health-watch/websocket/watchMonitor
#应急求助-websocket
VITE_GLOB_API_JIAN_CE=wss://api.cqygjk.com/health-emergency/websocket/emergency
#西安云坐席
VITE_GLOB_API_XIAN_YUN=wss://api.cqygjk.com/health-emergency/websocket/emergency3
#银川云坐席
VITE_GLOB_API_YIN_CHUAN=wss://api.cqygjk.com/health-emergency/websocket/emergency4
+12
View File
@@ -0,0 +1,12 @@
NODE_ENV=development
#测试环境
VITE_GLOB_API_URL=http://cqyt.test.yg.dt.io
#应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://cqyt.test.yg.dt.io/health-emergency/websocket/watchMonitor
#健康监测工具报警-websocket
VITE_GLOB_API_JIAN_CE=ws://cqyt.test.yg.dt.io/health-emergency/websocket/emergency
#西安云坐席
VITE_GLOB_API_XIAN_YUN=ws://cqyt.test.yg.dt.io/health-emergency/websocket/emergency3
#银川云坐席
VITE_GLOB_API_YIN_CHUAN=ws://cqyt.test.yg.dt.io/health-emergency/websocket/emergency4
+1
View File
@@ -7,6 +7,7 @@ node_modules
.vscode
.idea
dist
dist.zip
/public
/docs
.husky
+3 -2
View File
@@ -1,7 +1,8 @@
// @ts-check
import {defineConfig} from 'eslint-define-config'
// import {defineConfig} from 'eslint-define-config'
// const {defineConfig} = require('eslint-define-config');
export default {
module.exports = {
root: true,
env: {
browser: true,
+1
View File
@@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
pnpm-lock.yaml
+5
View File
@@ -0,0 +1,5 @@
shamefully-hoist=true
strict-peer-dependencies=false
registry=https://registry.npmmirror.com
auto-install-peers=true
canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas
-7
View File
@@ -1,7 +0,0 @@
#测试环境
VITE_GLOB_API_URL=http://cqyt.test.yg.dt.io
#应急求助-websocket
VITE_GLOB_API_YIN_JI=ws://192.168.1.3:7098/websocket/watchMonitor
#健康监测工具报警-websocket
VITE_GLOB_API_JIAN_CE=ws://cqyt.test.yg.dt.io/health-emergency/websocket/emergency
+2 -5
View File
@@ -1,8 +1,8 @@
<!doctype html>
<html lang="en">
<html lang="zh">
<head>
<meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="/vite.svg"/>
<link rel="icon" type="image/svg+xml" href="/screen.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>应急就医服务中心</title>
<!-- 全局配置 -->
@@ -12,9 +12,6 @@
securityJsCode: "1b3b86585c863d22db1e7f7636a9e495",
}
</script>
<!-- <script type="text/javascript"-->
<!-- src="https://webapi.amap.com/maps?v=2.0&key=4bbcb216b889f2d612cbed05ae6979c8&plugin=AMap.Driving,AMap.ToolBar,AMap.Driving,AMap.GeoJSON,AMap.MarkerCluster"></script>-->
<script type="text/javascript" src="./public/amap.js"></script>
</head>
<style>
html, body, #app {
+20 -4
View File
@@ -5,20 +5,31 @@
"type": "module",
"scripts": {
"dev": "vite --open",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"build": "vite build",
"build:dev": "vite build --mode dev",
"build:test": "vite build --mode test",
"preview": "vite build && vite preview",
"type:check": "vue-tsc --noEmit --skipLibCheck",
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\""
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@iamzzg/data-view": "^2.10.0",
"@turf/turf": "^6.5.0",
"autoprefixer": "^10.4.16",
"axios": "^1.6.2",
"dayjs": "^1.11.10",
"echarts": "5.4.3",
"echarts-gl": "^2.0.9",
"jsencrypt": "^3.3.2",
"lodash-es": "^4.17.21",
"mitt": "^3.0.1",
"path": "^0.12.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",
"qs": "^6.11.2",
"vue-router": "^4.2.5",
@@ -27,18 +38,23 @@
"devDependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/icons-vue": "^6.1.0",
"@types/node": "^20.10.5",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"ant-design-vue": "^3.2.20",
"echarts": "^5.4.3",
"eslint": "^8.51.0",
"eslint-config-prettier": "^8.10.0",
"eslint-define-config": "^1.24.1",
"eslint-plugin-jest": "^27.4.2",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-vue": "^9.17.0",
"jest": "^29.7.0",
"less": "^4.2.0",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vite-plugin-resolve-externals": "^0.2.2",
"vue-tsc": "^1.8.5"
}
}
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727574260527" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5102" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M693.2 874.8c0-15.5-12.6-28.1-28.1-28.1H362.2c-15.5 0-28.1 12.6-28.1 28.1v82.3H111.5v65.9h802.6v-65.9H693.2v-82.3zM363.7 395.3l164.7 174.6 95.3-103.6 174 176.7 70.1-299.7-30.3-8-58.1 244.8-153-163.7-99 103.1-162.6-170.8L156 566.9l23.2 21.4z" p-id="5103" fill="#ff4b00"></path><path d="M523 444l73-195.1c22.2-123.5-173.3-123.5-148.8 0L523 444z" p-id="5104" fill="#ff4b00"></path><path d="M0 0.9v754.8h1024V0.9H0z m957.6 689.5H66.4v-624h891.3v624z" p-id="5105" fill="#ff4b00"></path></svg>

After

Width:  |  Height:  |  Size: 818 B

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

+57 -1
View File
@@ -7,9 +7,65 @@
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { onMounted, watch } from 'vue';
import { getEmergencyCenterApi } from '/@/api/user.ts';
import { useUserStore } from '/@/store/modules/user.ts';
import { useRouter } from 'vue-router';
import { getBaseLogin } from '/@/enum/pageEnum.ts';
dayjs.locale('zh-cn');
const locle = zhCN;
const userStore = useUserStore();
const router = useRouter();
onMounted(async () => {
try {
if (userStore.getToken && getBaseLogin() === '/centralScreenLogin') {
const { result } = await getEmergencyCenterApi();
if (result?.screenPath) {
router.replace(result?.screenPath);
} else {
router.replace('centralScreen');
}
userStore.setCenterInfo(result);
}
} catch (e) {}
if (userStore.getUserInfo) {
}
document.body.addEventListener('click', initAudio);
});
watch(
() => userStore.getCount,
() => {
audioPlay();
}
);
const audio = new Audio('13203.wav');
function initAudio() {
audioPlay(true);
document.body.addEventListener('remove', initAudio);
}
function audioPlay(flag: boolean = false) {
audio.muted = flag;
audio.play();
}
</script>
<style lang="less" src="./assets/less/index.less"></style>
<style lang="less" scoped></style>
<style src="./assets/theme/theme.css"></style>
<style lang="less">
.modal-confirm-d {
top: 28% !important;
.ant-modal-confirm-content,
.ant-modal-confirm-title {
color: #ffffff !important;
}
.ant-modal-confirm-btns {
width: 100%;
display: flex;
justify-content: center;
}
}
</style>
+15
View File
@@ -0,0 +1,15 @@
import { get } from '/@/api/request.ts';
enum Api {
code = '/sys/dictItem/list',
}
//锻炼字典
export const getCodeInfo = (params: any) =>
get(Api.code, {
pageNo: 1,
pageSize: 999,
dictId: '1722171687208849409',
...params,
});
export const montionFieldNames = { label: 'itemText', value: 'itemValue' };
+37 -12
View File
@@ -1,28 +1,53 @@
import axios from 'axios';
import { getAppEnvConfig } from '../utils/env.ts';
import { useUserStore } from '/@/store/modules/user.ts';
import { getAppEnvConfig } from '/@/utils/env.ts';
import { getAuthCache } from '/@/utils/auth.ts';
import { TOKEN_KEY } from '/@/enum/cacheEnum.ts';
import { useMessage } from '/@/hooks/web/useMessage.ts';
import router from '/@/router';
import { useUserStore } from '/@/store/modules/user.ts';
import { getBaseLogin, toLoginByNowPath } from '/@/enum/pageEnum.ts';
const { createMessage } = useMessage();
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const userStore = useUserStore();
const { token } = userStore;
const service = axios.create({
baseURL: VITE_GLOB_API_URL,
timeout: 50000,
headers: {
// 设置后端需要的传参类型
'Content-Type': 'application/json;charset=UTF-8',
'X-Access-Token': token || getAuthCache(TOKEN_KEY),
},
/**
* @description: 响应错误处理
*/
responseInterceptorsCatch(error: any) {
const { response, code, message, config } = error || {};
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
'X-Access-Token': getAuthCache(TOKEN_KEY),
},
});
service.interceptors.request.use((config, options) => {
const userStore = useUserStore();
const token = userStore.getToken;
config.headers['X-Access-Token'] = token || getAuthCache(TOKEN_KEY);
return config;
});
service.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (error.response) {
console.log('response', error.response);
switch (error.response.data.code) {
case 401:
// debugger;
let path = getBaseLogin();
if (!path) {
path = toLoginByNowPath(router.currentRoute.value.path);
}
// createMessage.warn(error.response.data.message);
router.replace({
path: path,
});
}
}
return Promise.reject(error.response.data); // 返回接口返回的错误信息
}
);
export const get = (url, params = {}) => {
return new Promise((resolve, reject) => {
service
+14
View File
@@ -5,6 +5,8 @@ enum Api {
Login = '/sys/login',
Logout = '/sys/logout',
GetUserInfo = '/sys/user/getUserInfo',
auth = '/sys/permission/getPermCode',
emergencyCenter = '/health-emergency/emergency/center/getCenterDetail',
}
export const getCodeInfo = (params: any) => get(Api.getInputCode + `/${params}`);
@@ -13,6 +15,14 @@ export function loginApi(params: any) {
return post(Api.Login, params);
}
/**
* @description 获取登录人应急中心数据
* @param params
*/
export function getEmergencyCenterApi(params?: any) {
return get(Api.emergencyCenter, params);
}
/**
* @description: getUserInfo
*/
@@ -27,6 +37,10 @@ export function getUserInfo() {
});
}
export function getAuth() {
return get(Api.auth);
}
export function doLogout() {
return get(Api.Logout);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+44 -10
View File
@@ -1,20 +1,20 @@
//高德信息弹窗
.amap-info-contentContainer {
.amap-content-body {
background: #00152B;
border: 1px solid #129BFF;
background: var(--alarmContentBg);
border: 1px solid var(--alarmBorder);
.amap-lib-infowindow {
background: #00152B;
background: var(--alarmContentBg);
.amap-lib-infowindow-title {
color: #fff;
border-bottom: 1px solid #129BFF;
color: var(--antSelectFontColor);
border-bottom: 1px solid var(--alarmBorder);
padding: 4px 0;
}
.amap-lib-infowindow-content {
color: #fff;
color: var(--antSelectFontColor);
padding: 4px 0;
}
}
@@ -31,29 +31,30 @@
//marker
.amap-marker-label {
padding: 0;
border: none;
}
.alarm-content {
background-color: #263d5e;
color: #fff;
border: 1px solid #1b7ef2;
font-size: 14px;
padding: 7px 10px;
border: 1px solid #1b7ef2;
position: relative;
.close-btn {
color: #fff;
background: #ccc;
box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
position: absolute;
top: -6px;
right: -8px;
width: 15px;
height: 15px;
font-size: 12px;
background: #ccc;
border-radius: 50%;
color: #fff;
text-align: center;
line-height: 15px;
box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
}
.close-btn:hover {
@@ -61,4 +62,37 @@
}
}
//浅色地图上info-window
.light {
.alarm-content {
background-color: #f3f5ff;
color: #5876DB;
border: 1px solid #1b7ef2;
.close-btn {
background-color: #f3f5ff;
color: #5876DB;
box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
}
.close-btn:hover {
background: #1b7ef2;
}
}
}
/*地图元素样式---end*/
/*infoWindow*/
.amap-info-content {
width: 100%;
height: 100%;
background: url("../images/info-modal.png") no-repeat center;
background-size: 100% 100%;
//padding: 16px 18px 22px 10px;
}
.amap-info-contentContainer {
.amap-info-sharp {
border-top: none;
}
}
+113 -26
View File
@@ -1,7 +1,13 @@
@import "./amap-item";
@import "./themeType";
@import "./public-title";
html, body, #app {
min-width: 1300px;
overflow-x: auto;
}
.type-time {
padding-right: 4%;
padding-top: 3%;
font-size: 16px;
display: flex;
@@ -12,8 +18,8 @@
cursor: pointer;
}
.select {
color: #45a2ff;
.select.dark {
color: var(--typeTimeSelectColor);
position: relative;
&:after {
@@ -24,13 +30,49 @@
left: 6px;
bottom: -12px;
height: 6px;
background: url('../images/light.png') no-repeat;
background: url('/@/assets/images/light.png') no-repeat;
background-size: 100% 100%;
}
}
.unSelect {
color: #a3a4a4;
.unSelect.dark {
color: var(--typeTimeUnSelectColor);
}
.select.light {
color: #5876DB;
background-color: #BDC9F5;
position: relative;
margin-left: 5px;
border: 1px solid #607DDB;
border-radius: 5px;
}
.unSelect.light {
background-color: #d2d7f7;
margin-left: 5px;
color: #889BDB;
border: 1px solid #BDC9F5;
border-radius: 5px;
}
}
.type-check {
.select.light {
color: #5876DB;
background-color: #BDC9F5;
position: relative;
margin-left: 5px;
border: 1px solid #607DDB;
border-radius: 5px;
}
.unSelect.light {
background-color: #d2d7f7;
margin-left: 5px;
color: #889BDB;
border: 1px solid #BDC9F5;
border-radius: 5px;
}
}
@@ -64,15 +106,24 @@
}
.ant-modal-mask {
background-color: rgba(0, 0, 0, 0.65) !important;
background-color: #00000073 !important;
}
/* 为其他所有的 .ant-modal-mask 设置透明背景 */
.ant-modal-mask.no-mask {
background-color: transparent !important;
}
// 下拉框样式-start
.ant-select {
color: var(--antSelectFontColor) !important;
background-color: var(--antSelectBg);
}
.ant-select-dropdown {
background-color: #00152b !important;
border-right: 1px solid #1b7ef2;
border-left: 1px solid #1b7ef2;
border-bottom: 1px solid #1b7ef2;
background-color: var(--antSelectDropdownBg) !important;
border: 1px solid var(--antSelectDropdownBorderColor);
border-top: none;
}
.ant-select-item {
@@ -81,9 +132,9 @@
//框背景色
.ant-select:not(.ant-select-customize-input) .ant-select-selector {
color: #1b7ef2 !important;
color: var(--antSelectFontColor) !important;
background-color: transparent !important;
border: 1px solid #1b7ef2 !important;
border: 1px solid var(--antSelectDropdownBorderColor) !important;
}
.ant-select-item-option-selected {
@@ -91,9 +142,8 @@
}
// 选中字体颜色
.ant-select-selection-item {
//color: #1b7ef2 !important;
color: #fff;
:deep(.ant-select-selection-item) {
color: var(--antSelectFontColor);
}
.ant-select-item-option-active {
@@ -101,16 +151,16 @@
}
.ant-select-item-option-active:hover {
background-color: #002e64 !important;
background-color: var(--antSelectItemActive) !important;
}
// 箭头颜色
.ant-select-arrow {
color: #1b7ef2 !important;
color: var(--antSelectDropdownBorderColor) !important;
}
.ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
background-color: #002e64 !important;
background-color: var(--antSelectItemActive) !important;
}
// 下拉框样式-end
@@ -121,12 +171,12 @@
}
.ant-cascader-menu-item:hover {
background-color: #002e64 !important;
background-color: var(--antSelectItemActive) !important;
}
.ant-cascader-menu-item-active {
color: #fff !important;
background-color: #002e64 !important;
color: var(--antSelectFontColor) !important;
background-color: var(--antSelectItemActive) !important;
}
.ant-cascader-menu-item-expand .ant-cascader-menu-item-expand-icon, .ant-cascader-menu-item-loading-icon {
@@ -135,20 +185,57 @@
// 级联选择器样式-end
.ant-empty-description {
color: #fff;
color: var(--antSelectFontColor);
}
//表格
//表格hover白色
.ant-table-tbody > tr.ant-table-placeholder:hover > td {
background: transparent;
background: transparent !important;
}
//直升机
.helicopter {
width: 60px;
height: 37px;
background: url("../img/helicopter.png") no-repeat;
background: url("/@/assets/img/helicopter.png") no-repeat;
background-size: 100% 100%;
margin-bottom: 4px;
}
//Modal
.dialog.light {
background-color: #f3f5ff;
border: 1px solid #f3f5ff;
.police-con {
color: var(--tableFontColor);
background-color: #f3f5ff;
}
.ant-modal-title {
color: #576BAD !important;
background: url('/@/assets/images/dialog-light.png') no-repeat;
background-size: 100% 100%;
}
}
.dialog.dark {
color: #ffffff;
background-color: #00152b;
.police-con {
color: #ffffff;
background-color: #00152b;
}
.ant-modal-title {
color: #ffffff !important;
background: url('/@/assets/images/dialog.png') no-repeat;
background-size: 100% 100%;
}
}
/*表单*/
:deep(.ant-form-item-label > label) {
color: var(--formLabel);
}
+118
View File
@@ -0,0 +1,118 @@
.public-title.dark {
background: linear-gradient(90deg, rgba(106, 112, 124, 0.4) 0%, rgba(106, 112, 124, 0) 70%, rgba(106, 112, 124, 0) 100%);
opacity: 1;
border-top: 1px solid #6a707c;
border-bottom: 1px solid #6a707c;
border-image: linear-gradient(90deg,
rgba(217.0000022649765, 231.00000143051147, 255, 0.5),
rgba(217.0000022649765, 231.00000143051147, 255, 0)) 1 1;
color: #ffffff;
&:before {
position: absolute;
content: '';
width: 7px;
height: 100%;
top: 0;
left: 0;
background-color: #45a2ff;
}
.tips {
font-size: 16px;
padding-right: 10px;
font-weight: normal;
}
}
.public-title.light {
background: url("/@/assets/images/title-background.png") no-repeat;
background-size: 100% 100%;
color: #576BAD;
}
.server-item.light {
color: #607DDB;
}
.server-item.dark {
&:nth-child(odd) {
background-color: #0a0a0c;
}
}
.right-top-item.light {
.fixed-width {
display: inline-flex;
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
//名字和类型宽度100
> span:nth-child(1) {
color: #607DDB;
width: 100px;
}
> span:nth-child(2) {
color: #F58584;
width: 100px;
}
> div {
color: #607DDB;
}
.terminal-icon {
background: url('/@/assets/images/terminalNew.png') no-repeat;
}
.position {
background: url('/@/assets/images/positionNew.png') no-repeat;
}
}
.right-top-item.dark {
.fixed-width {
display: inline-flex;
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
> span:nth-child(1) {
width: 100px;
}
> span:nth-child(2) {
width: 100px;
}
span {
color: #ffffff;
font-size: 16px;
}
.terminal-icon {
background: url('/@/assets/images/terminal.png') no-repeat;
}
.position {
background: url('/@/assets/img/position.png') no-repeat;
}
}
.outer-title.light {
color: #576BAD;
background: url('/@/assets/images/top-title-new.png') no-repeat;
}
.outer-title.dark {
color: #ffffff;
background: url('/@/assets/images/top-title.png') no-repeat;
}
+97
View File
@@ -0,0 +1,97 @@
/*弹窗背景色*/
.police-con.light {
color: #000;
background-color: #fff;
}
.police-con.dark {
color: #ffffff;
background-color: #00152b;
}
.common-card.light {
background: #f3f5ff;
border-radius: 14px;
}
// 左侧区域
.body-d-left.light {
padding: 0 16px;
}
//右侧区域
.body-d-right.light {
padding: 0 16px;
}
//路线导航-light
.center-map .route-navigation.light {
background: #E4E8F9 !important;
--cardFontColor: #607ddb;
--cardFontFFF: #fff;
--cardBgColor: #e4e8f9;
--circelBg: #1478f5;
}
//路线导航-dark
.center-map .route-navigation.dark {
background: #002e64;
}
.hospital-list.light {
.hospital-item {
color: #5876DB;
background-color: #f3f5ff;
border: 1px solid #5876DB;
box-shadow: 0 1px 11px 0 rgba(194, 189, 189, 0.5);
}
.hospital-item:hover {
background-color: #c6cff9;
box-shadow: inset 0px 0px 16px 3px #f3f5ff;
}
}
.hospital-list.dark {
.hospital-item {
color: #fff;
background-color: #00152b;
border: 1px solid #1b7ef2;
box-shadow: 0 1px 11px 0 rgba(194, 189, 189, 0.5);
}
.hospital-item:hover {
background-color: #192a46;
box-shadow: inset 0px 0px 16px 3px #2562a9;
}
}
//点击地图医院触发的导航弹窗
.driving-route-panel.light {
background: #E4E8F9;
--cardFontColor: #607ddb;
--cardFontFFF: #fff;
--cardBgColor: #e4e8f9;
--circelBg: #1478f5;
}
.driving-route-panel.dark {
background: #2a4164;
border: 1px solid #1b7ef2;
--cardFontColor: rgba(255, 255, 255, 0.8);
--cardFontFFF: #fff;
--cardBgColor: #e4e8f9;
--circelBg: #1478f5;
}
.reset-map.dark {
color: #05d5ff;
background: #243b5d;
}
.reset-map.light {
color: #607ddb;
background: #e4e8f9;
}
+39 -3
View File
@@ -1,5 +1,6 @@
import { mapIcon1, mapIcon2, mapIcon3, mapIcon4 } from '/@/components/chinaMap/chinaHooks.ts';
import { mapIcon1, mapIcon2, mapIcon3, mapIcon4, mapIcon7 } from '/@/components/chinaMap/chinaHooks.ts';
import { watchIcon } from '/@/components/secondaryScreen/secondMap/secondMapHooks.ts';
import * as turf from '@turf/turf';
/**
* @desc 创建icon
@@ -19,7 +20,7 @@ export function createIcon({ icon, iconSize, imageSize }) {
* @desc 根据类型创建Icon
* @type 1:油田医院,2:合作医院,3:医疗点
*/
export function typeToIcon(type: string) {
export function typeToIcon(type: string, centerResource: boolean) {
const iconSize = [18, 44];
const imageSize = [18, 44];
if (type == '1') {
@@ -28,10 +29,14 @@ export function typeToIcon(type: string) {
if (type == '2') {
return createIcon({ icon: mapIcon4, iconSize, imageSize });
}
//关联医疗点
if (type == '3' && centerResource) {
return createIcon({ icon: mapIcon7, iconSize, imageSize });
}
if (type == '3') {
return createIcon({ icon: mapIcon2, iconSize, imageSize });
}
if (type == '4') {
if (type == '5' || type == '4') {
return createIcon({ icon: mapIcon3, iconSize, imageSize });
}
if (type == '6') {
@@ -60,3 +65,34 @@ export function createCircle(option) {
...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;
}
if (!lon || !lat) {
continue;
}
let point = turf.point([lon, lat]);
arr.push(point);
}
return arr;
}
/**
* @desc 根据多点算中心点
*/
export function getCenter(list = []) {
if (!list || !Array.isArray(list)) {
return undefined;
}
if (list.length < 1) {
return undefined;
}
let features = turf.featureCollection(list);
let centerObj = turf.center(features);
return centerObj?.geometry?.coordinates;
}
+238 -34
View File
@@ -1,16 +1,13 @@
import AMapLoader from '@amap/amap-jsapi-loader';
import china from '/@/assets/lngLat/china.ts';
import chinaInner from '/@/assets/lngLat/chinaInner.ts';
import { createCircle, createIcon, typeToIcon } from '/@/assets/mapUtils/commonFun.ts';
import { aircraftContent, alarmIcon } from '/@/components/chinaMap/chinaHooks.ts';
import { createCircle, createIcon, getCenter, getLonLat, typeToIcon } from '/@/assets/mapUtils/commonFun.ts';
import { aircraftContent, alarmIcon, female, male } from '/@/components/chinaMap/chinaHooks.ts';
import { isFunction } from '/@/utils/is.ts';
import { Callback, ExtDataType, InitMap, MarkerOption, ResultType } from '/@/assets/mapUtils/mapFunTypes.ts';
import { defaultOption, getZoom, mapKey, mapPlugin } from '/@/assets/mapUtils/mapConstant.ts';
export const defaultOption = {
center: [106.3, 37.87], //地图中心点
zoom: 4.3, //地图显示的缩放级别
mapStyle: 'darkblue', //地图样式
};
export const mapPlugin = ['AMap.ToolBar', 'AMap.Driving', 'AMap.GeoJSON', 'AMap.MarkerCluster', 'AMap.PlaceSearch'];
let AMap = null;
export const Map = {
map: null,
overlayGroup: null, // 地图中marker
@@ -19,12 +16,24 @@ export const Map = {
airMarkerList: [], //直升机markerList
placeSearch: null, //地点查询
marker: null, // 健康终端报警
infoWindow: null, //地图弹窗
driveLine: null, // 导航轨迹线
emergencyMarker: null, // 应急人员marker
/**
* @desc 地图舒适化
* @param el dom元素 id选择器
* @param option 地图配置
* @param innerLineOption 内轨迹线配置
* @param outlineOption 外轨迹线配置
*/
initMap({ el, option }: InitMap) {
initMap({ el, option, innerLineOption, outerLineOption }: InitMap) {
return new Promise((resolve) => {
AMapLoader.load({
key: mapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: mapPlugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((res) => {
AMap = res;
const { zoom, center, mapStyle } = { ...defaultOption, ...option };
//基本地图加载
this.map = new AMap.Map(el, {
@@ -32,27 +41,45 @@ export const Map = {
center: center,
zoom: zoom,
mapStyle: 'amap://styles/' + mapStyle,
version: '2.0',
});
// 异步同时加载多个插件
new AMap.plugin(mapPlugin, () => {
if (outerLineOption) {
this.drawInnerLine(innerLineOption);
this.drawOutLine(outerLineOption);
} else {
this.drawInnerLine();
this.drawOutLine();
}
});
} /**
resolve();
});
});
},
/**
*#desc 获取地图中心点
*/
getMapCenter() {
return this.map.getCenter();
},
/**
* @desc 中国外层边界线
*/,
drawOutLine() {
*/
drawOutLine(outerLineOption = {}) {
let line = {
strokeColor: '#2384dd',
strokeWeight: 3,
isOutline: false,
};
let geoJson = new AMap.GeoJSON({
geoJSON: china,
getPolygon: function (geoJson: string, lngLats: any) {
return new AMap.Polyline({
path: lngLats[0],
strokeColor: '#6ccffe',
strokeWeight: 3,
lineJoin: 'round', //折线拐点的绘制样式
isOutline: true,
borderWeight: 2,
outlineColor: '#2d475f',
...line,
...outerLineOption,
});
},
});
@@ -60,15 +87,19 @@ export const Map = {
} /**
* @desc 中国内层边界线
*/,
drawInnerLine() {
drawInnerLine(innerLineOption = {}) {
let line = {
isOutline: true,
outlineColor: '#2692fc',
borderWeight: 1,
strokeColor: '#88b9f8',
strokeWeight: 1,
strokeOpacity: 0.8,
};
let geoJson = new AMap.GeoJSON({
geoJSON: chinaInner,
getPolygon: function (geoJson: string, lngLats: any) {
return new AMap.Polyline({
path: lngLats[0],
strokeColor: '#359de5',
strokeWeight: 1,
});
return new AMap.Polyline({ path: lngLats[0], ...line, ...innerLineOption });
},
});
this.map.add(geoJson);
@@ -92,6 +123,8 @@ export const Map = {
if (this.airMarkerList) {
this.airMarkerList = [];
}
this.clearActiveHospital();
this.clearInfoModal();
// this.map.remove(this.airMarkerList);
}, //
/**
@@ -99,12 +132,19 @@ export const Map = {
* @param result
* @param extData
* @param callback
* @param computedCenter 是否计算中心点
*/
createOverlay(result: ResultType[], extData?: ExtDataType, callback?: Callback) {
createOverlay(result: ResultType[], extData?: ExtDataType, callback?: Callback, computedCenter?: boolean) {
this.removeOverlayGroup();
this.overlayGroup = new AMap.OverlayGroup();
let list = getLonLat(result);
let center = getCenter(list);
let zoom = getZoom(list);
if (computedCenter) {
this.setZoomCenter(center, zoom);
}
for (let i = 0; i < result.length; i++) {
let { type, lon, lat, lng } = result[i];
let { type, lon, lat, lng, centerResource } = result[i];
if (lng) {
lon = lng;
}
@@ -112,14 +152,15 @@ export const Map = {
continue;
}
// 创建一个 Icon
let startIcon = typeToIcon(type);
// debugger;
let startIcon = typeToIcon(type, centerResource);
// 将 icon 传入 marker
let startMarker = new AMap.Marker({
// 点的坐标
position: [lon, lat], // 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了
icon: startIcon, //启用点击事件 如果需要点击事件,必须开启
clickable: true, //点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型
offset: [-18, -32],
maxZoom: 14,
extData: result[i],
label: {
content: isFunction(extData?.content) && extData?.content(result[i]),
@@ -135,7 +176,6 @@ export const Map = {
this.overlayGroup.on('click', function (e) {
//拿到点中携带的数据
// console.log(e.target.getExtData());
if (!isFunction(callback)) return;
callback(e.target.getExtData());
});
@@ -153,10 +193,8 @@ export const Map = {
* @param result
*/
createAircraft(result: ResultType[]) {
console.log('result', result);
this.removeOverlayGroup();
this.clearActiveHospital();
// debugger;
if (!Array.isArray(result) && result.length == 0) return;
this.createAirRange(result);
let that = this;
@@ -167,7 +205,6 @@ export const Map = {
arr,
{
renderMarker: (context) => {
console.log('context', context);
let factor = Math.pow(context.count / count, 1 / 18);
let div = document.createElement('div');
div.className = 'render-air';
@@ -221,6 +258,7 @@ export const Map = {
this.removeOverlayGroup();
this.clearActiveHospital();
if (!cityCode) return;
if (!this.placeSearch) {
this.placeSearch = new AMap.PlaceSearch({
pageSize: 30, // 单页显示结果条数
pageIndex: 1, // 页码
@@ -230,14 +268,14 @@ export const Map = {
// panel: 'map_hospital', // 结果列表将在此容器中进行展示。
autoFitView: false, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
}
this.placeSearch.setCity(cityCode);
//关键字查询
this.placeSearch.search(keywords);
},
clearActiveHospital() {
if (this.placeSearch) {
// debugger;
this.placeSearch.clear();
this.placeSearch = null;
}
},
createMarker(option: MarkerOption, callbck?: Callback) {
@@ -267,4 +305,170 @@ export const Map = {
this.marker = null;
}
},
/**
* @desc 创建地图详情弹窗
*
* */
createInfoModal({ option, content }) {
let { lat, lng } = option;
this.infoWindow = new AMap.InfoWindow({
position: [lng, lat],
offset: new AMap.Pixel(-5, -25),
content: content,
closeWhenClickMap: true,
});
this.infoWindow.open(this.map);
},
clearInfoModal() {
if (this.infoWindow) {
this.infoWindow?.setMap(null);
this.infoWindow = null;
}
},
/**
* @desc 计算两个坐标点的距离
* @param {Array} listA 坐标点数组
* @param {Array} listB 坐标点数组
* @return {Number} 距离
*/
getDistance(listA: number[], listB: number[]) {
let lnglatA = new AMap.LngLat(listA[0], listA[1]);
let lnglatB = new AMap.LngLat(listB[0], listB[1]);
return lnglatA.distance(lnglatB);
},
/**
* @desc 计算两个坐标点的驾车时间
* @param {Array} listA 坐标点数组
* @param {Array} listB 坐标点数组
* @param {Function} callback 回调
* @return {Number} 时间
*/
getDriveTime(listA: number[], listB: number[], callback?: Callback) {
let lnglatA = new AMap.LngLat(listA[0], listA[1]);
let lnglatB = new AMap.LngLat(listB[0], listB[1]);
const drivingOptions = {
policy: AMap.DrivingPolicy.LEAST_TIME,
};
let driving = new AMap.Driving(drivingOptions);
return new Promise((resolve, reject) => {
driving.search(lnglatA, lnglatB, (status, result) => {
if (status === 'complete') {
// console.log('result', result);
if (callback && isFunction(callback)) {
callback(result);
}
return resolve(result.routes[0]);
}
});
});
},
/**
* @desc 创建导航轨迹线路
* @param {Array} listA 坐标点数组
* @param {Array} listB 坐标点数组
*
*/
createNaviLine(listA: number[], listB: number[]) {
this.clearNaviLine();
let lnglatA = new AMap.LngLat(listA[0], listA[1]);
let lnglatB = new AMap.LngLat(listB[0], listB[1]);
const drivingOptions = {
policy: AMap.DrivingPolicy.LEAST_TIME,
map: this.map,
autoFitView: true,
// panel: 'driving-panel',
};
this.driveLine = new AMap.Driving(drivingOptions);
this.driveLine.search(lnglatA, lnglatB, (status, result) => {
if (status === 'complete') {
// console.log('result', result);
}
});
this.driveLine.on('error', function (result) {
let str = '定位失败:';
console.log('error', result);
switch (result.info) {
case 'PERMISSION_DENIED':
str += '浏览器阻止了定位操作';
break;
case 'POSITION_UNAVAILBLE':
str += '无法获得当前位置';
break;
case 'TIMEOUT':
str += '定位超时';
break;
default:
str += '未知错误';
break;
}
console.log(str);
return false;
});
},
/**
* @desc 清除导航轨迹线路
*/
clearNaviLine() {
if (this.driveLine) {
this.driveLine.clear();
}
},
/**
* @desc 创建应急人员Marker
*/
createEmergencyMarker(option) {
this.clearEmergencyMarker();
const { sex, address, name, position } = option;
const icon = sex == '1' ? female : male;
this.emergencyMarker = new AMap.Marker({
position: position,
icon: createIcon({ icon: icon, iconSize: [36, 36], imageSize: [36, 36] }),
offset: new AMap.Pixel(0, 0), //设置偏移量
label: {
content: `<div class="alarm-content" style="width: 180px" >
<div style="text-align: center;padding-bottom: 6px">${name}</div>
<div style="text-wrap: wrap">${address}</div>
</div>`,
offset: new AMap.Pixel(-100, 55),
},
});
this.map.add(this.emergencyMarker);
this.setZoomCenter(position);
},
/**
* @desc 清除应急人员Marker
*/
clearEmergencyMarker() {
if (this.emergencyMarker) {
this.emergencyMarker?.setMap(null);
this.emergencyMarker = null;
}
},
/**
* @desc 根据坐标获取地址信息
* @param {Array} list 坐标点数组
*/
getAddressByPoint(list: number[]) {
const geocoder = new AMap.Geocoder({
city: '全国',
radius: 1000,
});
let lnglat = new AMap.LngLat(list[0], list[1]);
return new Promise((resolve, reject) => {
geocoder.getAddress(lnglat, (status, result) => {
if (status === 'complete' && result.regeocode) {
return resolve(result.regeocode.formattedAddress, result.regeocode);
}
return reject(result);
});
});
},
/**
* @desc 清除导航元素
*/
clearNavigationElements() {
this.clearNaviLine();
this.clearEmergencyMarker();
},
};
+39
View File
@@ -0,0 +1,39 @@
// 地图默认配置
export const defaultOption = {
center: [108.660704, 36.386058], //地图中心点
zoom: 6.5, //地图显示的缩放级别
mapStyle: 'darkblue', //地图样式
};
export const YinChuanOption = {
center: [106.32, 38.45], //地图中心点
zoom: 8, //地图显示的缩放级别
mapStyle: 'darkblue', //地图样式
};
//浅色地图样式
export const lightMapOption = {
mapStyle: 'normal', //地图样式
};
export const outerLineOption = {
strokeColor: '#768ddb',
};
export const innerLineLight = {
outlineColor: '#88a2f9',
strokeColor: '#93aaf8',
};
// 地图key
export const mapKey = '4bbcb216b889f2d612cbed05ae6979c8';
// 地图插件
export const mapPlugin = ['AMap.ToolBar', 'AMap.Driving', 'AMap.GeoJSON', 'AMap.MarkerCluster', 'AMap.PlaceSearch', 'AMap.Driving', 'AMap.Geocoder'];
//根据数据量设置地图层级
export function getZoom(list = []) {
let len = list.length;
// console.log('len', len)
if (len <= 5) {
return 7.5;
} else if (len <= 30) {
return 6.7;
} else {
return 7;
}
}
+2
View File
@@ -1,6 +1,8 @@
export interface InitMap {
el: string;
option: any;
innerLineOption?: any;
outerLineOption?: any;
}
export type Callback = (result?: any) => void;
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 54 KiB

+19
View File
@@ -0,0 +1,19 @@
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="6395" height="1080" viewBox="0 0 6395 1080">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_73" data-name="Rectangle 73" width="6395" height="1079" transform="translate(-5391)" fill="#fff"/>
</clipPath>
<linearGradient id="linear-gradient" x1="0.631" y1="0.5" x2="0.958" y2="0.488" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#2e364a"/>
<stop offset="1" stop-color="#2c344a"/>
</linearGradient>
</defs>
<g id="Web_1920_1" data-name="Web 1920 1" clip-path="url(#clip-Web_1920_1)">
<g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(5391)" clip-path="url(#clip-path)">
<g id="Group_118" data-name="Group 118" transform="translate(-419.333 -1.126)">
<path id="Path_142" data-name="Path 142" d="M6271.734-6.176s-222.478,187.809-55.349,583.254c44.957,106.375,81.514,205.964,84.521,277,8.164,192.764-156.046,268.564-156.046,268.564l-653.53-26.8L5475.065-21.625Z" transform="translate(-4876.383)" fill="#2d3750"/>
<path id="Union_6" data-name="Union 6" d="M-2631.1,1081.8v-1.6H-8230.9V.022h5599.8V0h759.7s-187.845,197.448-91.626,488.844c49.167,148.9,96.309,256.289,104.683,362.118,7.979,100.852-57.98,201.711-168.644,254.286-65.858,31.29-144.552,42.382-223.028,42.383C-2441.2,1147.632-2631.1,1081.8-2631.1,1081.8Z" transform="translate(3259.524 0.803)" fill="url(#linear-gradient)"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+17
View File
@@ -0,0 +1,17 @@
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="6395" height="1079" viewBox="0 0 6395 1079">
<defs>
<clipPath id="clip-path">
<rect width="6395" height="1079" transform="translate(-5391)" fill="#fff"/>
</clipPath>
<linearGradient id="linear-gradient" x1="0.747" y1="0.222" x2="0.973" y2="0.807" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#2c41b4"/>
<stop offset="1" stop-color="#1b4fab"/>
</linearGradient>
</defs>
<g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(5391)" clip-path="url(#clip-path)">
<g id="Group_118" data-name="Group 118" transform="translate(-419.333 -1.126)">
<path id="Path_142" data-name="Path 142" d="M6271.734-6.176s-222.478,187.809-55.349,583.254c44.957,106.375,81.514,205.964,84.521,277,8.164,192.764-156.046,268.564-156.046,268.564l-653.53-26.8L5475.065-21.625Z" transform="translate(-4876.383 0)" fill="#f1f5f8"/>
<path id="Union_6" data-name="Union 6" d="M-2631.1,1081.8v-1.6H-8230.9V.022H-2631.1V0H-1871.4s-187.845,197.448-91.626,488.844c49.167,148.9,96.309,256.289,104.683,362.118,7.979,100.852-57.98,201.711-168.644,254.286-65.858,31.29-144.552,42.382-223.028,42.383C-2441.2,1147.632-2631.1,1081.8-2631.1,1081.8Z" transform="translate(3259.524 0.803)" fill="url(#linear-gradient)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns:xlink="http://www.w3.org/1999/xlink" t="1595306944988" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1820" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M1464.3 279.7" p-id="1821" fill="#ffffff"></path><path d="M512 960c-60.5 0-119.1-11.9-174.4-35.2-53.4-22.6-101.3-54.9-142.4-96s-73.4-89-96-142.4C75.9 631.1 64 572.5 64 512s11.9-119.1 35.2-174.4c22.6-53.4 54.9-101.3 96-142.4s89-73.4 142.4-96C392.9 75.9 451.5 64 512 64s119.1 11.9 174.4 35.2c53.4 22.6 101.3 54.9 142.4 96s73.4 89 96 142.4C948.1 392.9 960 451.5 960 512c0 19.1-15.5 34.6-34.6 34.6s-34.6-15.5-34.6-34.6c0-51.2-10-100.8-29.8-147.4-19.1-45.1-46.4-85.6-81.2-120.4C745 209.4 704.5 182 659.4 163c-46.7-19.7-96.3-29.8-147.4-29.8-51.2 0-100.8 10-147.4 29.8-45.1 19.1-85.6 46.4-120.4 81.2S182 319.5 163 364.6c-19.7 46.7-29.8 96.3-29.8 147.4 0 51.2 10 100.8 29.8 147.4 19.1 45.1 46.4 85.6 81.2 120.4C279 814.6 319.5 842 364.6 861c46.7 19.7 96.3 29.8 147.4 29.8 64.6 0 128.4-16.5 184.4-47.8 54.4-30.4 100.9-74.1 134.6-126.6 10.3-16.1 31.7-20.8 47.8-10.4 16.1 10.3 20.8 31.7 10.4 47.8-39.8 62-94.8 113.7-159.1 149.6-66.2 37-141.7 56.6-218.1 56.6z" p-id="1822" fill="#ffffff"></path><path d="M924 552c-19.8 0-36-16.2-36-36V228c0-19.8 16.2-36 36-36s36 16.2 36 36v288c0 19.8-16.2 36-36 36zM275.4 575.5c9.5-2.5 19.1 2.9 22.3 12.2 3.5 10.2 9.9 17.7 19.1 22.6 7.1 3.9 15.1 5.8 24 5.8 16.6 0 30.8-6.9 42.5-20.8 11.7-13.8 20-32.7 24.9-75.1-7.7 12.2-17.3 20.8-28.7 25.8-11.4 5-23.7 7.4-36.8 7.4-26.7 0-47.7-8.3-63.3-24.9-15.5-16.6-23.3-37.9-23.3-64.1 0-25.1 7.7-47.1 23-66.2 15.3-19 37.9-28.6 67.8-28.6 40.3 0 68.1 18.1 83.4 54.4 8.5 19.9 12.7 44.9 12.7 74.9 0 33.8-5.1 63.8-15.3 89.9-16.9 43.5-45.5 65.2-85.8 65.2-27 0-47.6-7.1-61.6-21.2-10-10.1-16.4-22-19.3-35.8-2-9.6 4-19.1 13.5-21.6l0.9 0.1z m103-74.4c9.4-7.5 14.1-20.6 14.1-39.3 0-16.8-4.2-29.3-12.7-37.5S360.6 412 347.5 412c-14 0-25.2 4.7-33.4 14.1-8.2 9.4-12.4 22-12.4 37.7 0 14.9 3.6 26.7 10.9 35.5 7.2 8.8 18.8 13.1 34.6 13.1 11.4 0 21.8-3.8 31.2-11.3zM646.6 414.4c12.4 22.8 18.5 54 18.5 93.7 0 37.6-5.6 68.7-16.8 93.3-16.2 35.3-42.8 52.9-79.6 52.9-33.2 0-57.9-14.4-74.2-43.3-13.5-24.1-20.3-56.4-20.3-97 0-31.4 4.1-58.4 12.2-80.9 15.2-42 42.7-63 82.5-63 35.9 0 61.8 14.8 77.7 44.3z m-40.2 173.3c9.4-13.9 14-39.9 14-78 0-27.4-3.4-50-10.1-67.7-6.8-17.7-19.9-26.6-39.4-26.6-17.9 0-31 8.4-39.3 25.2-8.3 16.8-12.4 41.6-12.4 74.3 0 24.6 2.6 44.4 7.9 59.4 8.1 22.8 22 34.3 41.6 34.3 15.7 0 28.3-7 37.7-20.9zM803.3 387.2c11.2 11.3 16.8 25 16.8 41.2 0 16.7-5.8 30.7-17.5 41.8C791 481.4 777.4 487 762 487c-17.1 0-31.2-5.8-42.1-17.4-10.9-11.6-16.4-25.1-16.4-40.6 0-16.5 5.8-30.4 17.3-41.7 11.5-11.3 25.3-17 41.2-17 16.3 0 30.1 5.7 41.3 16.9zM739.5 451c6.2 6.2 13.7 9.3 22.5 9.3 8.4 0 15.8-3.1 22.1-9.3 6.3-6.2 9.4-13.7 9.4-22.6 0-8.5-3.1-15.9-9.3-22.1-6.2-6.2-13.6-9.3-22.2-9.3s-16.1 3.1-22.4 9.3c-6.3 6.2-9.4 13.7-9.4 22.6-0.1 8.4 3 15.8 9.3 22.1z" p-id="1823" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns:xlink="http://www.w3.org/1999/xlink" t="1595307154239" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7317" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M316 672h60c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8zM512 622c22.1 0 40-17.9 40-39 0-23.1-17.9-41-40-41s-40 17.9-40 41c0 21.1 17.9 39 40 39zM512 482c22.1 0 40-17.9 40-39 0-23.1-17.9-41-40-41s-40 17.9-40 41c0 21.1 17.9 39 40 39z" p-id="7318" fill="#ffffff"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H184V184h656v656z" p-id="7319" fill="#ffffff"></path><path d="M648 672h60c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8z" p-id="7320" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 996 B

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns:xlink="http://www.w3.org/1999/xlink" t="1595307195033" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8116" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M887.081 904.791a25.8 25.8 0 0 1-18.376-7.619L705.618 734.075l-4.163 3.369c-58.255 47.18-131.522 73.16-206.32 73.16-181.07 0-328.377-147.308-328.377-328.367 0-181.068 147.308-328.376 328.377-328.376 181.063 0 328.376 147.308 328.376 328.376 0 77.072-27.412 152.07-77.169 211.17l-3.522 4.173 162.719 162.744a25.846 25.846 0 0 1 7.639 18.432 26.081 26.081 0 0 1-26.051 26.045l-0.046-0.01zM495.13 205.957c-152.336 0-276.27 123.935-276.27 276.27 0 152.33 123.934 276.27 276.27 276.27 152.34 0 276.275-123.94 276.275-276.27 0-152.335-123.935-276.27-276.275-276.27z" fill="#ffffff" p-id="8117"></path><path d="M626.545 508.355h-262.83a26.127 26.127 0 0 1 0-52.255h262.83a26.127 26.127 0 0 1 0 52.255z" fill="#ffffff" p-id="8118"></path><path d="M495.13 639.77a26.127 26.127 0 0 1-26.128-26.128v-262.83a26.127 26.127 0 0 1 52.255 0v262.835a26.127 26.127 0 0 1-26.127 26.123z" fill="#ffffff" p-id="8119"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns:xlink="http://www.w3.org/1999/xlink" t="1595306911635" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1352" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M924.8 337.6c-22.6-53.4-54.9-101.3-96-142.4s-89-73.4-142.4-96C631.1 75.9 572.5 64 512 64S392.9 75.9 337.6 99.2c-53.4 22.6-101.3 54.9-142.4 96-22.4 22.4-42.2 46.8-59.2 73.1V228c0-19.8-16.2-36-36-36s-36 16.2-36 36v288c0 19.8 16.2 36 36 36s36-16.2 36-36v-50.2c4.2-34.8 13.2-68.7 27-101.2 19.1-45.1 46.4-85.6 81.2-120.4C279 209.4 319.5 182 364.6 163c46.7-19.7 96.3-29.8 147.4-29.8 51.2 0 100.8 10 147.4 29.8 45.1 19.1 85.6 46.4 120.4 81.2C814.6 279 842 319.5 861 364.6c19.7 46.7 29.8 96.3 29.8 147.4 0 51.2-10 100.8-29.8 147.4-19.1 45.1-46.4 85.6-81.2 120.4C745 814.6 704.5 842 659.4 861c-46.7 19.7-96.3 29.8-147.4 29.8-64.6 0-128.4-16.5-184.4-47.8-54.4-30.4-100.9-74.1-134.6-126.6-10.3-16.1-31.7-20.8-47.8-10.4-16.1 10.3-20.8 31.7-10.4 47.8 39.8 62 94.8 113.7 159.1 149.6 66.2 37 141.7 56.6 218.1 56.6 60.5 0 119.1-11.9 174.4-35.2 53.4-22.6 101.3-54.9 142.4-96 41.1-41.1 73.4-89 96-142.4C948.1 631.1 960 572.5 960 512s-11.9-119.1-35.2-174.4z" p-id="1353" fill="#ffffff"></path><path d="M275.4 575.5c9.5-2.5 19.1 2.9 22.3 12.2 3.5 10.2 9.9 17.7 19.1 22.6 7.1 3.9 15.1 5.8 24 5.8 16.6 0 30.8-6.9 42.5-20.8 11.7-13.8 20-32.7 24.9-75.1-7.7 12.2-17.3 20.8-28.7 25.8-11.4 5-23.7 7.4-36.8 7.4-26.7 0-47.7-8.3-63.3-24.9-15.5-16.6-23.3-37.9-23.3-64.1 0-25.1 7.7-47.1 23-66.2 15.3-19 37.9-28.6 67.8-28.6 40.3 0 68.1 18.1 83.4 54.4 8.5 19.9 12.7 44.9 12.7 74.9 0 33.8-5.1 63.8-15.3 89.9-16.9 43.5-45.5 65.2-85.8 65.2-27 0-47.6-7.1-61.6-21.2-10-10.1-16.4-22-19.3-35.8-2-9.6 4-19.1 13.5-21.6l0.9 0.1z m103-74.4c9.4-7.5 14.1-20.6 14.1-39.3 0-16.8-4.2-29.3-12.7-37.5S360.6 412 347.5 412c-14 0-25.2 4.7-33.4 14.1-8.2 9.4-12.4 22-12.4 37.7 0 14.9 3.6 26.7 10.9 35.5 7.2 8.8 18.8 13.1 34.6 13.1 11.4 0 21.8-3.8 31.2-11.3zM646.6 414.4c12.4 22.8 18.5 54 18.5 93.7 0 37.6-5.6 68.7-16.8 93.3-16.2 35.3-42.8 52.9-79.6 52.9-33.2 0-57.9-14.4-74.2-43.3-13.5-24.1-20.3-56.4-20.3-97 0-31.4 4.1-58.4 12.2-80.9 15.2-42 42.7-63 82.5-63 35.9 0 61.8 14.8 77.7 44.3z m-40.2 173.3c9.4-13.9 14-39.9 14-78 0-27.4-3.4-50-10.1-67.7-6.8-17.7-19.9-26.6-39.4-26.6-17.9 0-31 8.4-39.3 25.2-8.3 16.8-12.4 41.6-12.4 74.3 0 24.6 2.6 44.4 7.9 59.4 8.1 22.8 22 34.3 41.6 34.3 15.7 0 28.3-7 37.7-20.9zM803.3 387.2c11.2 11.3 16.8 25 16.8 41.2 0 16.7-5.8 30.7-17.5 41.8C791 481.4 777.4 487 762 487c-17.1 0-31.2-5.8-42.1-17.4-10.9-11.6-16.4-25.1-16.4-40.6 0-16.5 5.8-30.4 17.3-41.7 11.5-11.3 25.3-17 41.2-17 16.3 0 30.1 5.7 41.3 16.9zM739.5 451c6.2 6.2 13.7 9.3 22.5 9.3 8.4 0 15.8-3.1 22.1-9.3 6.3-6.2 9.4-13.7 9.4-22.6 0-8.5-3.1-15.9-9.3-22.1-6.2-6.2-13.6-9.3-22.2-9.3s-16.1 3.1-22.4 9.3c-6.3 6.2-9.4 13.7-9.4 22.6-0.1 8.4 3 15.8 9.3 22.1z" p-id="1354" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns:xlink="http://www.w3.org/1999/xlink" t="1595308005241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9878" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M750.3 198.7C598 46.4 351.1 46.4 198.7 198.7s-152.3 399.2 0 551.5C345.1 896.6 578.8 902.3 732 767.3l172.1 172.1 35.4-35.4-172.1-171.9c135-153.2 129.3-387-17.1-533.4z m39.3 403.8c-17.1 42.1-42.2 80-74.7 112.4-32.5 32.5-70.3 57.6-112.4 74.7-40.7 16.5-83.8 24.9-128 24.9s-87.2-8.4-128-24.9c-42.1-17.1-80-42.2-112.4-74.7s-57.6-70.3-74.7-112.4c-16.5-40.7-24.9-83.8-24.9-128s8.4-87.2 24.9-128c17.1-42.1 42.2-80 74.7-112.4s70.3-57.6 112.4-74.7c40.7-16.5 83.8-24.9 128-24.9s87.2 8.4 128 24.9c42.1 17.1 80 42.2 112.4 74.7 32.5 32.5 57.6 70.3 74.7 112.4 16.5 40.7 24.9 83.8 24.9 128s-8.4 87.3-24.9 128zM671 502H271v-50h400v50z" fill="#ffffff" p-id="9879"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+23
View File
@@ -0,0 +1,23 @@
/*默认dark*/
:root {
--antSelectDropdownBg: #00152b;
--antSelectDropdownBorderColor: #1b7ef2;
--antSelectItemActive: #002e64;
--antSelectFontColor: #fff;
--antSelectBg: #000;
/*服务详情数据*/
--typeTimeSelectColor: #45a2ff;
--typeTimeUnSelectColor: #a3a4a4;
/*表格 */
--tableHeadBg: rgba(35, 132, 221, 0.5);
--tableFontColor: #fff;
--tableRowBg: #00152b;
--tableRowBorder: #2384dd;
--pageItemLink: #bdc9f5;
--pageItemActiveBg: #0081ff;
/*表单*/
--formLabel: #1b7ef2;
/*地图弹窗*/
--alarmContentBg: #00152B;
--alarmBorder: #1b7ef2;
}
+55
View File
@@ -0,0 +1,55 @@
export const themeList = {
dark: {
/*下拉框*/
antSelectDropdownBg: '#00152b',
antSelectDropdownBorderColor: '#1b7ef2',
antSelectItemActive: '#002e64', //选中或鼠标移过
antSelectFontColor: '#fff',
antSelectBg: '#000',
/*服务详情数据*/
typeTimeSelectColor: '#45a2ff',
typeTimeUnSelectColor: '#a3a4a4',
// 表格
tableHeadBg: 'rgba(35, 132, 221, 0.5)',
tableFontColor: '#fff',
tableRowBg: '#00152b',
tableRowBorder: '#2384dd',
pageItemLink: '#1f2935',
pageItemActiveBg: '#0081ff',
//form
formLabel: '#1b7ef2',
//地图弹窗
alarmContentBg: '#00152B',
alarmBorder: '#1b7ef2',
},
light: {
antSelectDropdownBg: '#fff',
antSelectDropdownBorderColor: '#607DDB',
antSelectItemActive: '#ced7f6',
antSelectFontColor: '#5876DB',
antSelectBg: '#ced7f6',
/*服务详情数据*/
typeTimeSelectColor: '#45a2ff',
typeTimeUnSelectColor: '#a3a4a4',
// 表格
tableHeadBg: '#bdc9f5',
tableFontColor: '#607DDB',
tableRowBg: '#f3f5ff',
tableRowBorder: '#e1e6fa',
pageItemLink: '#bdc9f5',
pageItemActiveBg: '#7092ff',
//form
formLabel: '#7092ff',
//地图弹窗
alarmContentBg: '#ced7f6',
alarmBorder: '#1b7ef2',
},
};
export function setTheme(theme: string) {
const themeStyle = themeList[theme];
for (const key in themeStyle) {
document.documentElement.style.setProperty(`--${key}`, themeStyle[key]);
document.documentElement.className = theme;
}
}
+31 -2
View File
@@ -1,7 +1,36 @@
import type { App } from 'vue';
import { Form, Input, Button, Radio, Modal, Table, Select, Cascader, Spin, ConfigProvider } from 'ant-design-vue';
import {
Form,
Input,
Button,
Radio,
RadioGroup,
RadioButton,
DatePicker,
Modal,
Table,
Select,
Cascader,
Spin,
ConfigProvider,
Tabs,
} from 'ant-design-vue';
import dataV from '@iamzzg/data-view/dist/vue3/datav.map.vue.esm';
export default function registerGlobComp(app: App) {
app.use(dataV).use(Button).use(Form).use(Input).use(Radio).use(Modal).use(Table).use(Select).use(Cascader).use(Spin).use(ConfigProvider);
app.use(dataV)
.use(Button)
.use(Form)
.use(Input)
.use(Radio)
.use(RadioGroup)
.use(RadioButton)
.use(DatePicker)
.use(Modal)
.use(Table)
.use(Select)
.use(Cascader)
.use(Spin)
.use(Tabs)
.use(ConfigProvider);
}
+393 -37
View File
@@ -1,5 +1,14 @@
import { ref } from 'vue';
import { ref, unref } from 'vue';
import * as echarts from 'echarts';
import { emptyChart } from '/@/utils/utils.ts';
//服务详情数据弹窗参数
export enum ServerDetailType {
gross = '0', //最新呼入电话
alerdyreceive = '1', //最新受理电话
jqqz = '2', //突发重大伤病应急
dbjy = '3', //重大伤病应急就医
}
export function useStatistics() {
const statistics = ref([
@@ -25,6 +34,10 @@ export function useStatistics() {
},
]);
function getStatistics() {
return unref(statistics);
}
function setStatistics(data = {}) {
statistics.value.forEach((item) => {
const { key } = item;
@@ -34,15 +47,16 @@ export function useStatistics() {
return {
statistics,
getStatistics,
setStatistics,
};
}
export const timeTab = [
{
name: '全部',
value: '1',
},
// {
// name: '全部',
// value: '1',
// },
{
name: '本年',
value: '2',
@@ -57,6 +71,10 @@ export const timeTab = [
},
];
export const sexType = [
{
name: '全部',
value: '0',
},
{
name: '男',
value: '2',
@@ -81,33 +99,282 @@ export function useSpin() {
}
export const hospitalList = [
{
title: '兴隆医院',
key: 'tangdu',
},
{
title: '泾河医院',
key: 'zhigong',
},
{
title: '宁夏宝石花医院',
key: 'yangehu',
},
{
title: '庆阳医院',
key: 'changan',
},
{
title: '延安市人民医院',
key: 'yananshi',
},
{
title: '西京医院',
key: 'xijing',
},
// {
// name: '泾河医院',
// key: 'zhigong',
// value: 0,
// },
// {
// name: '兴隆医院',
// key: 'tangdu',
// value: 0,
// },
// {
// name: '宁夏宝石花医院',
// key: 'yangehu',
// value: 0,
// },
// {
// name: '延安市人民医院',
// key: 'yananshi',
// value: 0,
// },
// {
// name: '西京医院',
// key: 'xijing',
// value: 0,
// },
// {
// name: '庆阳医院',
// key: 'changan',
// value: 0,
// },
];
export function barOption(xData, ydata) {
export function useHospitalList() {
const radarList = ref(hospitalList);
function getRadarList() {
return unref(radarList);
}
function setRadarList(res) {
radarList.value = res;
// radarList.value.forEach((item) => {
// const { key } = item;
// item.value = res[key] || 0;
// });
}
return {
radarList,
getRadarList,
setRadarList,
};
}
const radarChartsTheme = {
dark: {
radarName: {
textStyle: {
color: '#fff',
},
},
splitLine: {
color: '#597589',
},
axisName: {
color: '#ffffff',
},
areaStyle: {
color: '#05D5FF',
},
lineStyle: {
color: '#05D5FF',
},
itemStyle: {
color: '#05D5FF',
},
},
light: {
radarName: {
textStyle: {
color: '#607DDB',
},
},
splitLine: {
color: '#b5c2ef',
},
axisName: {
color: '#607DDB',
},
areaStyle: {
color: '#a0b6fd',
},
lineStyle: {
color: '#607DDB',
},
itemStyle: {
color: '#607DDB',
},
},
};
/**
* @Description:体检医院雷达图
* @date 2023/6/27
* @param indicator:名称及最大值
* @param countList:数据项
*/
export const radarCharts = ({ indicator, countList, theme }) => {
if (!countList?.length) {
return emptyChart();
}
const { radarName, splitLine, axisName, areaStyle, lineStyle, itemStyle } = radarChartsTheme[theme] || radarChartsTheme.dark;
return {
noDataLoadingOption: {
text: '暂无数据',
effect: 'whirling',
effectOption: {
period: 3,
radius: 10,
frame: 3,
},
textStyle: {
color: '#333',
fontSize: 16,
},
},
grid: {
top: '1%',
left: '5%',
right: '5%',
bottom: '1%',
containLabel: true,
},
radar: {
name: {
textStyle: {
color: '#fff',
fontSize: 14,
},
...radarName,
},
shape: 'polygon',
center: ['50%', '50%'],
radius: '65%',
//坐标系起始角度,也就是第一个指示器轴的角度。
startAngle: 360,
scale: true,
axisLine: {
lineStyle: {
color: '#597589',
},
},
splitLine: {
show: true,
lineStyle: {
width: 1,
color: '#597589', // 设置网格的颜色
...splitLine,
},
},
indicator: indicator,
splitArea: {
show: false,
},
axisName: {
formatter: function (params) {
let dataIndex = indicator.findIndex((item) => item.name === params);
return `${params}\n${countList[dataIndex]}`;
},
color: '#ffffff',
...axisName,
},
},
polar: {
center: ['50%', '50%'], // 默认全局居中
radius: '0%',
},
angleAxis: {
min: 0,
interval: 5,
clockwise: false,
axisTick: {
show: false,
},
axisLabel: {
show: false,
},
axisLine: {
show: false,
},
splitLine: {
show: false,
},
},
radiusAxis: {
min: 0,
interval: 20,
splitLine: {
show: false,
},
},
series: [
{
name: '本年度健康体检',
type: 'radar',
symbol: 'circle', // 拐点的样式,还可以取值'rect','angle'等
symbolSize: 10, // 拐点的大小
itemStyle: {
normal: {
color: '#05D5FF',
...itemStyle,
},
},
areaStyle: {
normal: {
color: '#05D5FF',
opacity: 0.5,
...areaStyle,
},
},
lineStyle: {
width: 2,
color: '#05D5FF',
...lineStyle,
},
label: {
normal: {
show: false,
},
},
data: [
{
value: countList,
},
],
},
],
};
};
const barTheme = {
dark: {
tooltip: {
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
},
xAxisLabel: {
color: '#FFFFFF',
},
itemStyle: [
{ offset: 0, color: '#008CFF' },
{ offset: 1, color: '#33CBFE' },
],
},
light: {
tooltip: {
textStyle: {
color: '#768ddb',
},
backgroundColor: '#d5dcf8',
borderColor: '#1b7ef2',
},
xAxisLabel: {
color: '#607DDB',
},
itemStyle: [
{ offset: 0, color: '#607DDB' },
{ offset: 1, color: '#768ddb' },
],
},
};
export function barOption(xData, ydata, theme) {
const { tooltip, xAxisLabel, itemStyle } = barTheme[theme] || barTheme.dark;
function maxCount() {
if (ydata.length) {
return Math.max(...ydata) < 5 ? 5 : null;
@@ -120,16 +387,18 @@ export function barOption(xData, ydata) {
grid: {
top: '18%',
left: '8%',
right: '8%',
right: '4%',
bottom: '15%',
},
tooltip: {
show: true,
trigger: 'axis', // 触发类型为坐标轴
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
...tooltip,
},
xAxis: {
type: 'category',
@@ -137,9 +406,16 @@ export function barOption(xData, ydata) {
axisLabel: {
color: '#FFFFFF',
fontSize: 14,
...xAxisLabel,
},
axisLine: {
color: '#bac9e1',
lineStyle: {
type: 'solid',
color: '#8798d1',
},
},
axisTick: {
show: false,
},
},
yAxis: {
@@ -147,17 +423,19 @@ export function barOption(xData, ydata) {
nameTextStyle: {
color: '#fff',
padding: [0, 0, 0, -15],
...xAxisLabel,
},
type: 'value',
axisLabel: {
color: '#FFFFFF',
fontSize: 14,
...xAxisLabel,
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: 'rgba(217, 231, 255, 0.2)',
color: '#a2add2',
},
},
min: 0,
@@ -169,10 +447,8 @@ export function barOption(xData, ydata) {
type: 'bar',
barWidth: '20%',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#008CFF' },
{ offset: 1, color: '#33CBFE' },
]),
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, itemStyle),
borderRadius: 12,
},
barMaxWidth: '10',
label: {
@@ -180,8 +456,88 @@ export function barOption(xData, ydata) {
position: 'top',
color: '#33CBFE',
fontWeight: 'normal',
...xAxisLabel,
},
},
],
};
}
export function getOptions(data: any[] = [], colors: any[] = [], totalTimes: number = 0) {
return {
title: [
{
text: totalTimes + '人',
left: 'center',
top: '35%',
textStyle: {
color: '#ffffff',
fontStyle: 'normal',
fontWeight: '400', // 字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
fontFamily: 'Source Han Sans CN',
fontSize: 20,
height: '22%',
},
},
{
subtext: '急救总次数',
subtextStyle: {
color: '#ffffff',
fontStyle: 'normal',
fontWeight: '500',
fontFamily: 'Source Han Sans CN',
fontSize: 24,
},
left: 'center',
top: '48%',
},
],
tooltip: {
trigger: 'item',
},
label: {
formatter: '{b} {c}',
// fontSize: 18
},
legend: {
top: '0%',
left: 'center',
textStyle: {
color: '#ffffff',
},
},
colors: colors,
series: [
{
type: 'pie',
radius: ['60%', '70%'],
avoidLabelOverlap: false,
padAngle: 1,
itemStyle: {
borderRadius: 10,
},
center: ['50%', '55%'],
// emphasis: {
// label: {
// show: true,
// fontSize: 40,
// fontWeight: 'bold',
// },
// },
data: data,
},
],
};
}
/**
* @desc 值是否不为零
* @param list 数组
* @param key 元素属性
*/
export function allValueEmpty(key: string, list: any[]) {
if (!Array.isArray(list)) {
return false;
}
return list.every((item: any) => item?.[key] != 0);
}
+7 -1
View File
@@ -3,8 +3,10 @@ import { get } from '/@/api/request';
export enum Api {
departList = '/sys/sysDepart/allSecondaryDeparts',
server = '/health-emergency/emergency/tblUserHelp/statistics',
getDetail = '/health-emergency/emergency/tblHealthData/getDetail',
getDetail = '/health-medical/medical/hospital/getMedicalHospital',
complaint = '/health-emergency/emergency/tblHelpCenter/sicknessTypeStatistic',
orderDetail = '/health-emergency/emergency/order/list',
listCustom = '/health-watch/watch/watchMonitorData/listCustom',
}
//获取全部部门
@@ -15,3 +17,7 @@ export const list = (params: any) => get(Api.server, params);
export const complaint = (params: any) => get(Api.complaint, params);
//体检数据
export const getDetail = (params: any) => get(Api.getDetail, params);
//获取主诉分类应急工单详情
export const getOrderDetail = (params: any) => get(Api.orderDetail, params);
//副屏预警查看详情
export const getEarlyWarningDetail = (params: any) => get(Api.listCustom, params);
+70 -36
View File
@@ -1,18 +1,24 @@
<template>
<div>
<public-title title="服务详情数据" />
<div class="common-card" :class="[themeType]">
<public-title title="服务详情数据" :themeType="themeType" />
<div class="inner">
<div class="type-time">
<span
v-for="(item, index) in typeTime"
:key="index"
:class="[selectIndex === index ? 'select' : 'unSelect']"
:class="[selectIndex === index ? 'select' : 'unSelect', themeType]"
@click="handleSelect(index, item.value)"
>{{ item.name }}</span
>
</div>
<div class="server-container">
<div v-for="(item, index) in statistics" :key="index" class="server-item">
<div
v-for="(item, index) in statistics"
:key="index"
class="server-item"
:class="[['gross', 'alerdyreceive'].includes(item.key) ? 'hasCursor' : '', themeType]"
@click="handleClick(item)"
>
<span>{{ item?.name }}</span>
<span>{{ item?.value }}</span>
</div>
@@ -22,35 +28,64 @@
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import bus from '/@/utils/bus.ts';
import PublicTitle from '../publicTitle.vue';
import { list } from './left.api';
import { onMounted, ref, watch } from 'vue';
import PublicTitle from '/@/components/publicTitle.vue';
import { list } from '/@/components/body-d-left/left.api';
import { timeTab, useSpin, useStatistics } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { useDetailStore } from '/@/store/modules/detailData.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const { themeType } = useTheme();
const { LEFT_KEY1 } = caching;
const props = defineProps({
refreshState: {
type: Boolean,
},
setting: {
type: Object,
},
theme: {
type: String,
},
});
const emit = defineEmits(['handleClick']);
const typeTime = ref(timeTab);
const { statistics, setStatistics } = useStatistics();
const { statistics, setStatistics, getStatistics } = useStatistics();
const selectIndex = ref(0);
const selectVal = ref('1');
const selectVal = ref('2'); //本年
const { setSpin, spinning } = useSpin();
onMounted(() => {
getList();
});
const useDetail = useDetailStore();
const { setSession, getSession } = useSession();
async function getList() {
setSpin(true);
try {
const { code, result } = (await list({ condition: selectVal.value })) || {};
setSpin(!spinning.value);
if (code != 200 || !Array.isArray(result)) {
const { code, result } = (await list({ condition: selectVal.value, dataType: props.setting.dataType })) || {};
setSpin(false);
if (code != 200 || !result) {
return;
}
setStatistics(result[0]);
let { alerdyreceive = '', totalacceptance = '' } = result[0];
bus.emit('alerdyreceive', { alerdyreceive, totalacceptance });
setSession(LEFT_KEY1, JSON.stringify(result));
setValue(result);
} catch {
setSpin(!spinning.value);
setSpin(false);
const result = JSON.parse(getSession(LEFT_KEY1));
setValue(result);
}
}
function setValue(result = {}) {
let { alerdyreceive = '', totalacceptance = '' } = result;
setStatistics(result);
if (alerdyreceive || totalacceptance) {
useDetail.setAlerdyreceive(alerdyreceive);
useDetail.setTotalacceptance(totalacceptance);
}
}
@@ -59,6 +94,17 @@
selectVal.value = value;
getList();
}
function handleClick(item) {
emit('handleClick', item);
}
watch(
() => props.refreshState,
() => {
getList();
}
);
</script>
<style scoped lang="less">
.inner {
@@ -66,7 +112,7 @@
.server-container {
color: #fff;
padding-top: 4%;
padding-top: 10px;
height: 88%;
display: grid;
align-items: start;
@@ -78,30 +124,18 @@
left: 50%;
top: 50%;
}
}
.server-item {
font-size: 16px;
padding: 6px 0;
padding: 6px 6% 6px 5%;
span {
display: inline-block;
width: 50%;
&.hasCursor {
cursor: pointer;
}
span:nth-child(1) {
text-align: left;
padding-left: 5%;
}
span:nth-child(2) {
text-align: right;
padding-right: 6%;
}
}
.server-item:nth-child(odd) {
background-color: #0a0a0c;
}
display: flex;
justify-content: space-between;
}
}
</style>
+64 -51
View File
@@ -1,73 +1,112 @@
<template>
<div>
<public-title title="体检数据" />
<div class="common-card" :class="[themeType]">
<public-title title="体检数据" :themeType="themeType" />
<div class="inner">
<div class="type-time">
<span
:class="selectIndex === index ? 'select' : 'unSelect'"
v-for="(item, index) in timeTab"
:key="index"
@click="handleSelect(index)"
:class="[selectIndex === index ? 'select' : 'unSelect', themeType]"
@click="handleSelect(index, item.value)"
>{{ item.name }}</span
>
</div>
<div class="physical-container">
<a-spin :spinning="spinning" class="spin"></a-spin>
<div class="physical-item" v-for="(item, i) in hospitalList" :key="i" :class="[i < 3 ? 'b1' : 'b2']">
<div class="ct">
<div class="value">{{ countData[item.key] || '/' }}</div>
<div class="label">{{ item.title }}</div>
</div>
</div>
<div class="RadarCharts" ref="radarChartsRef"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import PublicTitle from '../publicTitle.vue';
<script lang="ts" setup>
import { onMounted, ref, unref, watch } from 'vue';
import PublicTitle from '/@/components/publicTitle.vue';
import { getDetail } from '/@/components/body-d-left/left.api';
import { hospitalList, useSpin, timeTab } from '/@/components/body-d-left/bodyLeftHooks';
import { useSpin, timeTab, useHospitalList, radarCharts, allValueEmpty } from '/@/components/body-d-left/bodyLeftHooks';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
import * as echarts from 'echarts';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const props = defineProps({
refreshState: {
type: Boolean,
},
setting: Object,
});
const { themeType } = useTheme();
const { setSession, getSession } = useSession();
const { LEFT_KEY3 } = caching;
const { setSpin, spinning } = useSpin();
const selectIndex = ref(0);
function handleSelect(index: number) {
const selectVal = ref('2'); //本年
function handleSelect(index: number, value: string) {
selectIndex.value = index;
selectVal.value = value;
setSpin(true);
setTimeout(() => {
setSpin(false);
}, 1000);
getList();
}
onMounted(() => {
getList();
});
const countData = ref({});
const { radarList, setRadarList, getRadarList } = useHospitalList();
async function getList() {
setSpin(true);
try {
const { code, result } = (await getDetail({})) || {};
const { code, result } = (await getDetail({ dataType: props.setting.dataType, condition: selectVal.value })) || {};
setSpin(!spinning.value);
if (code != 200) {
return;
}
countData.value = result[0] || {};
setSession(LEFT_KEY3, JSON.stringify(result));
setValue(result);
} catch {
const result = JSON.parse(getSession(LEFT_KEY3));
setValue(result);
setSpin(!spinning.value);
}
}
function setValue(result) {
setRadarList(result);
const everyEmpty = allValueEmpty('value', getRadarList());
everyEmpty && initChart();
}
const radarChartsRef = ref<HTMLElement>();
function initChart() {
const myChart = echarts.init(radarChartsRef.value);
let countList = radarList?.value.map((item) => item?.userCount);
if (countList.length < 1) return;
let max = Math.max(...countList);
const indicator = radarList?.value.map((item) => ({ name: item?.hospitalName, max: max }));
const option = radarCharts({ indicator, countList, theme: unref(themeType) });
myChart.setOption(option);
window.addEventListener('resize', () => {
myChart.resize();
});
}
watch(
() => props.refreshState,
() => {
getList();
}
);
</script>
<style scoped lang="less">
<style lang="less" scoped>
.inner {
height: calc(100% - 40px);
.physical-container {
width: 96%;
height: 92%;
padding-top: 6%;
height: calc(100% - 35px);
display: flex;
flex-wrap: wrap;
align-content: space-around;
@@ -79,35 +118,9 @@
top: 50%;
}
.physical-item {
width: 33%;
height: 46%;
color: #ffffff;
display: flex;
flex-direction: column;
.ct {
margin-top: -20px;
}
.value {
font-size: 20px;
font-weight: bold;
}
.label {
font-size: 14px;
}
}
.b1 {
background: url('../../assets/images/physical-top.png') no-repeat;
background-size: 95% 95%;
}
.b2 {
background: url('../../assets/images/physical-bottom.png') no-repeat;
background-size: 95% 95%;
.RadarCharts {
width: 100%;
height: 100%;
}
}
}
+65 -91
View File
@@ -1,22 +1,24 @@
<template>
<div>
<public-title title="主诉分类" />
<div class="inner">
<div class="common-card" :class="[themeType]">
<public-title title="主诉分类" :themeType="themeType">
<template #right><span class="right-text" :class="[themeType]" @click="viewDetail">查看详情</span> </template>
</public-title>
<div class="zc-inner">
<div class="title">
<div class="type-check">
<span
:class="sexIndex === index ? 'select' : 'unSelect'"
v-for="(item, index) in sexType"
:key="index"
@click="handleSelect(index)"
>{{ item.name }}</span
>
</div>
<div class="type-all">
<a-select v-model:value="selectValue" class="type-select" :options="selectOptions">
<a-select-option value="全部数据">全部数据</a-select-option>
</a-select>
</div>
<div class="type-check">
<span
:class="[sexIndex === index ? 'select' : 'unSelect', themeType]"
v-for="(item, index) in sexType"
:key="index"
@click="handleSelect(index, item.value)"
>{{ item.name }}</span
>
</div>
</div>
<div class="line-chart" ref="chiefChart"></div>
<a-spin :spinning="spinning" class="spin"></a-spin>
@@ -25,21 +27,34 @@
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import PublicTitle from '../publicTitle.vue';
import PublicTitle from '/@/components/publicTitle.vue';
import * as echarts from 'echarts';
import { complaint, getDepart } from '/@/components/body-d-left/left.api.ts';
import { useSpin, barOption, sexType } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const props = defineProps({
refreshState: {
type: Boolean,
},
});
const emit = defineEmits(['viewDetail']);
const { themeType } = useTheme();
const { setSession, getSession } = useSession();
const { LEFT_KEY2 } = caching;
const { setSpin, spinning } = useSpin();
const sexIndex = ref(0);
const sexVal = ref('');
const chiefChart = ref<HTMLElement>();
const selectOptions = ref([{ label: '全部数据', value: 'all' }]);
const selectValue = ref('all');
function handleSelect(index: number) {
function handleSelect(index: number, val: string) {
sexIndex.value = index;
sexVal.value = val;
}
onMounted(() => {
@@ -63,7 +78,7 @@
setSpin(true);
try {
const searchParams = {
sex: sexType[sexIndex.value].value,
sex: sexVal.value,
depart: selectValue.value == 'all' ? '' : selectValue.value,
};
const { code, result } = (await complaint(searchParams)) || {};
@@ -71,19 +86,22 @@
if (code != 200) {
return;
}
if (Array.isArray(result) && result.length == 0) {
return EmptyChart();
}
if (Array.isArray(result) && result.length > 0) {
const xData = result.map((item) => item.name);
const yData = result.map((item) => item.count);
setSession(LEFT_KEY2, JSON.stringify({ xData, yData }));
initChart(xData, yData);
} else {
EmptyChart();
}
} catch {
setSpin(false);
EmptyChart();
const { xData, yData } = getSession(LEFT_KEY2) ? JSON.parse(getSession(LEFT_KEY2)) : {};
initChart(xData, yData);
}
}
watch([selectValue, sexIndex], () => {
watch([selectValue, sexIndex, () => props.refreshState], () => {
getList();
});
@@ -93,16 +111,39 @@
function initChart(xData, ydata) {
let myChart = echarts.init(chiefChart.value);
let options = barOption(xData, ydata);
let options = barOption(xData, ydata, themeType.value);
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
});
}
/**
* 查看详情
*/
function viewDetail() {
emit('viewDetail');
}
</script>
<style scoped lang="less">
.inner {
.right-text {
font-weight: 100;
cursor: pointer;
margin-right: 3px;
font-size: 18px;
}
.right-text.light {
color: #667ecc;
}
.right-text:hover {
color: #129bff;
}
.zc-inner {
position: relative;
width: 100%;
height: calc(100% - 40px);
.spin {
@@ -115,41 +156,19 @@
width: 100%;
display: flex;
align-items: center;
justify-content: right;
justify-content: space-between;
padding: 2% 0;
.type-check {
color: #ffffff;
width: 15%;
display: flex;
justify-content: space-around;
span {
padding: 0 2%;
width: 50px;
cursor: pointer;
font-size: 16px;
}
.select {
color: #45a2ff;
position: relative;
&:after {
content: '';
position: absolute;
display: block;
width: 100%;
left: 0;
bottom: -12px;
height: 6px;
background: url('../../assets/images/light.png') no-repeat;
background-size: 100% 100%;
}
}
.unSelect {
color: #a3a4a4;
}
}
.type-all {
@@ -170,48 +189,3 @@
}
}
</style>
<style lang="less">
.ant-select-dropdown {
background-color: #00152b !important;
border-right: 1px solid #1b7ef2;
border-left: 1px solid #1b7ef2;
border-bottom: 1px solid #1b7ef2;
}
.ant-select-item {
color: #1b7ef2 !important;
}
//框背景色
.ant-select:not(.ant-select-customize-input) .ant-select-selector {
color: #1b7ef2 !important;
background-color: transparent !important;
border: 1px solid #1b7ef2 !important;
}
.ant-select-item-option-selected {
color: #ffffff !important;
}
// 选中字体颜色
.ant-select-selection-item {
color: #1b7ef2 !important;
}
.ant-select-item-option-active {
background-color: transparent !important;
}
.ant-select-item-option-active:hover {
background-color: #002e64 !important;
}
// 箭头颜色
.ant-select-arrow {
color: #1b7ef2 !important;
}
.ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
background-color: #002e64 !important;
}
</style>
+76 -11
View File
@@ -1,4 +1,5 @@
import { computed, ref } from 'vue';
import { visibleChartLabel } from '/@/utils/utils.ts';
// 列表字段
export const columns = [
{
@@ -57,19 +58,19 @@ export function useHealth() {
{
name: '高危人数',
value: '0',
type: '1',
type: '2',
type_dictText: '恶性肿瘤',
},
{
name: '中危人数',
value: '0',
type: '2',
type: '1',
type_dictText: '其他',
},
{
name: '可控人数',
value: '0',
type: '3',
type: '0',
type_dictText: '其他',
},
]);
@@ -94,7 +95,63 @@ export function useHealth() {
};
}
export function ringOption(chartData, total) {
const ringTheme = {
dark: {
color: ['#F58584', '#F5CC84', '#0CD9B5'],
textStyle: {
color: '#ffffff',
},
subtextStyle: {
color: '#ffffff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
tooltip: {
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
},
legend: {
textStyle: {
color: '#ffffff',
},
},
seriesLabel: {
color: '#ffffff',
},
},
light: {
color: ['#F58584', '#F5CC84', '#0CD9B5'],
textStyle: {
color: '#5169B8',
},
subtextStyle: {
color: '#607DDB',
},
backgroundColor: 'rgba(50,50,50,0.7)',
tooltip: {
textStyle: {
color: '#768ddb',
},
backgroundColor: '#d5dcf8',
borderColor: '#1b7ef2',
},
legend: {
textStyle: {
color: '#1b7ef2',
},
},
seriesLabel: {
color: '#27386e',
},
},
};
export function ringOption(chartData, total, theme) {
const { textStyle, subtextStyle, tooltip, legend, seriesLabel, color } = ringTheme[theme] || ringTheme.dark;
const data = visibleChartLabel(chartData);
return {
title: {
text: '总人数',
@@ -105,14 +162,16 @@ export function ringOption(chartData, total) {
fontSize: 14,
color: '#ffffff',
fontWeight: 'normal',
...textStyle,
},
subtextStyle: {
color: '#ffffff',
fontSize: 24,
fontWeight: 'bold',
...subtextStyle,
},
},
color: ['#0098FA', '#0CD9B5', '#3B72AD'],
color: color || ['#0098FA', '#0CD9B5', '#F5CC84'],
tooltip: {
trigger: 'item',
show: true,
@@ -121,6 +180,7 @@ export function ringOption(chartData, total) {
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
...tooltip,
},
legend: {
bottom: '0',
@@ -130,26 +190,31 @@ export function ringOption(chartData, total) {
color: '#ffffff',
fontSize: 16,
},
selectedMode: false,
...legend,
},
series: [
{
type: 'pie',
radius: ['50%', '74%'],
radius: ['50%', '72%'],
center: ['50%', '47%'],
avoidLabelOverlap: false,
label: {
show: true,
position: 'inner',
position: 'outside',
formatter: '{d}%',
color: '#ffffff',
color: '#27386e',
fontSize: 14,
// ...seriesLabel,
},
labelLine: {
show: false,
show: true,
smooth: true,
length: 12,
length2: 5,
},
data: chartData,
data: data,
},
],
};
}
+199 -161
View File
@@ -1,14 +1,13 @@
<template>
<div class="terminal-container">
<public-title title="健康终端报警">
<div class="terminal-container common-card" :class="[themeType]">
<public-title title="健康终端报警" :themeType="themeType">
<template #right>
<span class="right-text" @click="viewDetail">查看详情</span>
<span class="right-text" :class="[themeType]" @click="viewDetail">查看详情</span>
</template>
</public-title>
<div class="inner">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="4"
v-bind="classOption">
<div class="item" v-for="(item, i) in scrollList" :key="i">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="4" v-bind="classOption">
<div class="item right-top-item" :class="themeType" v-for="(item, i) in scrollList" :key="i">
<span class="fixed-width" :title="item?.realName">{{ item?.realName }}</span>
<span class="fixed-width" :title="item?.eventType_dictText">{{ item?.eventType_dictText }}</span>
<div class="time-icon">
@@ -19,139 +18,196 @@
</div>
</vue3-seamless-scroll>
</div>
<!-- <Dialog :openVis="open" width="65%" title="健康终端报警列表" @close="handleClose">-->
<!-- <template #container>-->
<!-- <div class="dialog-con">-->
<!-- <a-table :dataSource="dataSource" :columns="columns" :scroll="{ y: '56vh' }" :pagination="false" />-->
<!-- </div>-->
<!-- </template>-->
<!-- </Dialog>-->
<Dialog :openVis="openInfor" width="30%" title="健康报警员工信息" @close="handlePoliceClose">
<template #container>
<div class="police-con">
<div class="con-item">
<span>姓名</span>
<span>{{ userInfo?.realName }}</span>
<div class="police-con" :class="[themeType]">
<Row style="font-size: 14px; font-weight: bold"> 个人信息 </Row>
<Row>
<Col :span="8">姓名{{ userInfo?.realName || '--' }}</Col>
<Col :span="8">性别{{ userInfo?.sex_dictText || '--' }}</Col>
<Col :span="8">年龄{{ userInfo?.age || '--' }}</Col>
</Row>
<Row>
<Col :span="8">二级单位{{ userInfo?.orgName2 || '--' }}</Col>
<Col :span="8">部门{{ userInfo?.orgName || '--' }}</Col>
<Col :span="8">手机号码{{ userInfo?.phone || '--' }}</Col>
</Row>
<Row style="font-size: 14px; font-weight: bold"> 健康信息 </Row>
<Row> 异常事件{{ userInfo?.eventType_dictText || '--' }} </Row>
<Row>
<Col :span="8">异常值{{ userInfo?.dataValue || '--' }}</Col>
<Col :span="16">发生时间{{ userInfo?.warnTime || '--' }}</Col>
</Row>
<div style="display: flex">
<div style="width: 67px">发生地点</div>
<div style="width: calc(100% - 67px); display: flex; overflow-wrap: anywhere">
{{ userInfo?.address || userInfo?.gpsErrorMsg || '--' }}
</div>
<div class="con-item">
<span>二级单位</span>
<span>{{ userInfo?.orgName1 }}</span>
</div>
<div class="con-item">
<span>手机号码</span>
<span>{{ userInfo?.phone }}</span>
</div>
<div class="con-item">
<span>异常事件</span>
<span>{{ userInfo?.eventType_dictText }}</span>
</div>
<div class="con-item">
<span>发生时间</span>
<span>{{ userInfo?.warnTime }}</span>
</div>
<div class="con-item">
<span>发生地点</span>
<span>{{ userInfo?.address }}</span>
</div>
<!-- <div class="con-item">-->
<!-- <div>姓名</div>-->
<!-- <div>{{ userInfo?.realName }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>二级单位</div>-->
<!-- <div>{{ userInfo?.orgName1 }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>手机号码</div>-->
<!-- <div>{{ userInfo?.phone }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>异常事件</div>-->
<!-- <div>{{ userInfo?.eventType_dictText }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>异常值</div>-->
<!-- <div>{{ userInfo?.dataValue }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>发生时间</div>-->
<!-- <div>{{ userInfo?.warnTime }}</div>-->
<!-- </div>-->
<!-- <div class="con-item">-->
<!-- <div>发生地点</div>-->
<!-- <div v-if="userInfo?.address">{{ userInfo?.address }} </div>-->
<!-- <div style="color: #eb3636" v-else>{{ userInfo?.gpsErrorMsg }}</div>-->
<!-- </div>-->
</div>
</template>
</Dialog>
</div>
</template>
<script setup lang="ts">
import {onMounted, ref} from 'vue';
import {useRouter} from 'vue-router';
import $bus from '/@/utils/bus.ts';
import {columns} from '/@/components/body-d-right/bodyRightHooks.ts';
import PublicTitle from '/@/components/publicTitle.vue';
import Dialog from '/@/components/dialog/Dialog.vue';
import {Vue3SeamlessScroll} from 'vue3-seamless-scroll';
import {getMonitorList} from '/@/components/body-d-right/right.api.ts';
import {Map} from '/@/assets/mapUtils/map.ts';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import PublicTitle from '/@/components/publicTitle.vue';
import Dialog from '/@/components/dialog/Dialog.vue';
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
import { getMonitorList } from '/@/components/body-d-right/right.api.ts';
import { Map } from '/@/assets/mapUtils/map.ts';
import { caching, useSession } from '/@/hooks/autoRefresh/caching.ts';
import { DataType } from '/@/utils/settings.ts';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
import { message } from 'ant-design-vue';
import { Row, Col } from 'ant-design-vue';
import dayjs from 'dayjs';
const router = useRouter();
const classOption = ref({
const props = defineProps({
setting: Object,
});
const { themeType } = useTheme();
const emit = defineEmits(['emit-view-detail']);
const router = useRouter();
const { setSession, getSession } = useSession();
const { RIGHT_KEY1 } = caching;
const classOption = ref({
step: 0.3, // 速度
});
const open = ref<boolean>(false);
const openInfor = ref<boolean>(false);
const userInfo = ref({
});
const openInfor = ref<boolean>(false); //弹窗显示
const userInfo = ref({
realName: '',
orgName1: '',
phone: '',
eventType_dictText: '',
warnTime: '',
address: '',
});
dataValue: '',
});
onMounted(() => {
getScrollList();
});
const dataSource = ref([
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
]);
/**
/**
* @desc open员工信息
*/
function handlePolice(item) {
function handlePolice(item) {
userInfo.value = item;
openInfor.value = true;
classOption.value.step = 0;
}
}
/**
/**
* @desc close员工信息
*/
function handlePoliceClose() {
function handlePoliceClose() {
openInfor.value = false;
classOption.value.step = 0.3;
}
}
onMounted(() => {
getScrollList();
});
/**
/**
* @desc 终端报警
* */
const scrollList = ref([]);
const scrollList = ref([]);
async function getScrollList() {
const {code, result} = await getMonitorList({pageSize: 10, pageNo: 1});
const interval = ref<any>(null);
const nowDate = ref(dayjs());
onMounted(() => {
// interval.value = setInterval(() => {
// if (dayjs(nowDate.value).diff(dayjs(), 'date') < 0) {
// nowDate.value = dayjs();
// getScrollList();
// }
// }, 1000);
});
async function getScrollList() {
console.log(dayjs());
try {
const { code, result } = await getMonitorList({
pageSize: 10,
pageNo: 1,
orgCode: props.setting?.orgCode,
startDate: dayjs().format('YYYY-MM-DD'),
endDate: dayjs().format('YYYY-MM-DD'),
});
if (code == 200) {
setSession(RIGHT_KEY1, JSON.stringify(result.records));
scrollList.value = result.records;
}
}
} catch {
scrollList.value = JSON.parse(getSession(RIGHT_KEY1));
}
}
function sendPosition(item) {
let {lon, lat} = item;
function sendPosition(item) {
let { lon, lat } = item;
if (lon && lat) {
Map.createMarker(item, () => {
handlePolice(item);
});
} else {
message.warn('暂无经纬度信息!');
}
}
}
function viewDetail() {
router.push({path: '/secondScreen'});
}
function viewDetail() {
if (props.setting.dataType == DataType.xian) {
router.push({ path: '/secondScreen' });
}
if (props.setting.dataType == DataType.yinChuan) {
emit('emit-view-detail');
}
}
</script>
<style scoped lang="less">
.right-text {
font-size: 14px;
.right-text {
font-weight: 100;
cursor: pointer;
margin-right: 3px;
}
font-size: 18px;
}
.right-text:hover {
.right-text.light {
color: #667ecc;
}
.right-text:hover {
color: #129bff;
}
}
.inner {
.inner {
height: calc(100% - 40px);
display: flex;
align-items: center;
@@ -168,19 +224,6 @@ function viewDetail() {
justify-content: space-between;
padding: 3% 0;
.fixed-width {
display: inline-flex;
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
span {
color: #ffffff;
font-size: 16px;
}
.time-icon {
display: flex;
align-items: center;
@@ -191,93 +234,88 @@ function viewDetail() {
display: inline-block;
width: 18px;
height: 18px;
background: url('/@/assets/images/terminal.png') no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.position {
width: 18px;
height: 18px;
background-size: 100% 100%;
margin-left: 5px;
display: inline-block;
width: 20px;
height: 20px;
background: url('/@/assets/img/position.png') no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
}
}
}
}
.police-con {
color: #ffffff;
background-color: #00152b;
border: 1px solid #129bff;
padding: 2% 0 2% 5%;
.police-con {
padding: 2% 5% 2% 5%;
display: grid;
.con-item {
padding: 1.3% 0;
display: flex;
span:nth-child(1) {
div:nth-child(1) {
font-weight: bold;
display: inline-block;
width: 20%;
width: 100px;
text-align: right;
}
span:nth-child(2) {
padding-left: 2%;
div:nth-child(2) {
width: calc(100% - 100px);
}
}
}
}
.ant-row {
margin-bottom: 10px;
}
</style>
<style lang="less">
.dialog-con {
background-color: #00152b;
border: 1px solid #129bff;
/*
antd表格样式
*/
<!--<style lang="less">-->
<!-- .dialog-con {-->
<!-- background-color: #00152b;-->
<!-- // antd表格样式-->
<!-- .ant-table-thead > tr > th {-->
<!-- //border-bottom: 1px solid #1e73c2 !important;-->
<!-- }-->
.ant-table-thead > tr > th {
border-bottom: 1px solid #1e73c2 !important;
}
<!-- .ant-table-body {-->
<!-- background-color: #00152b !important;-->
<!-- }-->
.ant-table-body {
background-color: #00152b !important;
}
<!-- .ant-modal-header {-->
<!-- border-bottom: none !important;-->
<!-- }-->
.ant-modal-header {
border-bottom: none !important;
}
<!-- .ant-table-tbody > tr > td {-->
<!-- border-bottom: 1px solid #1e73c2 !important;-->
<!-- background-color: #00152b !important;-->
<!-- color: #ffffff !important;-->
<!-- }-->
.ant-table-tbody > tr > td {
border-bottom: 1px solid #1e73c2 !important;
background-color: #00152b !important;
color: #ffffff !important;
}
<!-- .ant-table-tbody > tr.ant-table-row:hover > td,-->
<!-- .ant-table-tbody > tr > td.ant-table-cell-row-hover,-->
<!-- .ant-table-thead > tr > th {-->
<!-- background-color: #00152b !important;-->
<!-- color: #ffffff !important;-->
<!-- }-->
.ant-table-tbody > tr.ant-table-row:hover > td,
.ant-table-tbody > tr > td.ant-table-cell-row-hover,
.ant-table-thead > tr > th {
background-color: #00152b !important;
color: #ffffff !important;
}
<!-- .ant-table-cell-scrollbar {-->
<!-- box-shadow: none !important;-->
<!-- }-->
.ant-table-cell-scrollbar {
box-shadow: none !important;
}
<!-- /*-->
<!--表格滚动条-->
<!--*/-->
/*
表格滚动条
*/
.ant-table-body::-webkit-scrollbar-thumb {
border: 4px solid rgba(0, 0, 0, 0);
height: 6px;
border-radius: 25px;
background-clip: padding-box;
background-color: rgba(30, 115, 194, 0.3);
}
}
</style>
<!-- .ant-table-body::-webkit-scrollbar-thumb {-->
<!-- border: 4px solid rgba(0, 0, 0, 0);-->
<!-- height: 6px;-->
<!-- border-radius: 25px;-->
<!-- background-clip: padding-box;-->
<!-- background-color: rgba(30, 115, 194, 0.3);-->
<!-- }-->
<!-- }-->
<!--</style>-->
+1 -1
View File
@@ -2,7 +2,7 @@ import { get } from '/src/api/request';
export enum Api {
getMonitorList = '/health-watch/watch/watchMonitorData/getMonitorList',
getHealthDataList = '/health-emergency/emergency/tblHealthData/getHealthDataList',
getHealthDataList = '/health-archives/archives/groupUserA/getGroupUserAInfo',
}
//健康终端报警
+8 -5
View File
@@ -1,6 +1,6 @@
<template>
<div>
<public-title title="基层医疗点远程会诊" />
<div class="common-card" :class="themeType">
<public-title title="基层医疗点远程会诊" :theme-type="themeType" />
<div class="inner">
<div class="inner-item" data-text="应急就医-服务中心"></div>
<div class="inner-item" data-text="采油九厂-薛岔作业区"></div>
@@ -10,7 +10,10 @@
</div>
</template>
<script setup lang="ts">
import PublicTitle from '../publicTitle.vue';
import PublicTitle from '/@/components/publicTitle.vue';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const { themeType } = useTheme();
</script>
<style scoped lang="less">
.inner {
@@ -37,8 +40,8 @@
position: absolute;
content: attr(data-text);
color: #fff;
bottom: 0px;
left: 0px;
bottom: 0;
left: 0;
width: 100%;
text-align: left;
padding-left: 10px;
+22 -8
View File
@@ -1,17 +1,25 @@
<template>
<div>
<public-title title="长庆油田大病人数" />
<div class="common-card" :class="themeType">
<public-title title="长庆油田大病人数" :themeType="themeType" />
<div class="inner" ref="healthChart"></div>
</div>
</template>
<script setup lang="ts">
import { ref, unref, onMounted } from 'vue';
import * as echarts from 'echarts';
import PublicTitle from '../publicTitle.vue';
import PublicTitle from '/@/components/publicTitle.vue';
import { getHealthDataList } from '/@/components/body-d-right/right.api';
import { useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { ringOption, useHealth } from '/@/components/body-d-right/bodyRightHooks.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const props = defineProps({
setting: Object,
});
const { themeType } = useTheme();
const { setSession, getSession } = useSession();
const { RIGHT_KEY2 } = caching;
const { setSpin, spinning } = useSpin();
const healthChart = ref<HTMLElement>();
onMounted(() => {
@@ -21,23 +29,29 @@
async function init() {
try {
const { code, result } = await getHealthDataList({});
const { code, result } = await getHealthDataList({ dataType: props.setting?.dataType, orgCode: props.setting?.orgCode });
setSpin(true);
if (code != 200) {
return;
}
setSession(RIGHT_KEY2, JSON.stringify(result));
setValue(result);
} catch {
const result = JSON.parse(getSession(RIGHT_KEY2));
setValue(result);
}
}
function setValue(result) {
setHealth(result);
const yData = unref(getValue);
let total = yData.reduce((accumulator, currentValue) => Number(accumulator) + Number(currentValue), 0);
initChart(unref(healthData), total);
} catch {
initChart(unref(healthData), 0);
}
}
function initChart(chartData, total) {
let myChart = echarts.init(healthChart.value);
let options = ringOption(chartData, total);
let options = ringOption(chartData, total, unref(themeType));
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
+13 -13
View File
@@ -5,8 +5,8 @@ export enum TabType {
youTianYiYuan = '1', //油田医院
heZuoYiYuan = '2', //合作医院
yiLiaoDian = '3', //医疗点
jiuHuChe = '4', //救护车
zhiShengJi = '5', //直升机
jiuHuChe = '5', //救护车
zhiShengJi = '4', //直升机
diFangYiYuan = '6', //地方医院
}
@@ -35,10 +35,10 @@ export const tabList = [
name: '地方医院',
type: TabType.diFangYiYuan,
},
{
name: '直升机',
type: TabType.zhiShengJi,
},
// {
// name: '直升机',
// type: TabType.zhiShengJi,
// },
{
name: '急救路线',
},
@@ -47,7 +47,8 @@ export const tabList = [
export const helicopter = new URL('/@/assets/img/helicopter.png', import.meta.url).href;
export const mapbg = new URL('/@/assets/img/helicopter.png', import.meta.url).href;
export const alarmIcon = new URL('/@/assets/img/alarm-icon.png', import.meta.url).href;
export const male = new URL('/@/assets/img/male.png', import.meta.url).href;
export const female = new URL('/@/assets/img/female.png', import.meta.url).href;
// 直升机位置数据
export const aircraft = [
{
@@ -105,12 +106,12 @@ export function mapApiSwitch(type, params: any) {
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 });
}
if ([TabType.jiuHuChe].includes(type)) {
return getAmbulanceList({});
}
// if ([TabType.jiuHuChe].includes(type)) {
// return getAmbulanceList({});
// }
}
export const mapIcon1 = new URL('/@/assets/img/mapIcon1.png', import.meta.url).href;
@@ -119,13 +120,13 @@ export const mapIcon3 = new URL('/@/assets/img/mapIcon3.png', import.meta.url).h
export const mapIcon4 = new URL('/@/assets/img/mapIcon4.png', import.meta.url).href;
export const mapIcon5 = new URL('/@/assets/img/mapIcon5.png', import.meta.url).href;
export const mapIcon6 = new URL('/@/assets/img/mapIcon6.png', import.meta.url).href;
export const mapIcon7 = new URL('/@/assets/img/mapIcon7.png', import.meta.url).href;
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 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 const legend6 = new URL('/@/assets/img/legend6.png', import.meta.url).href;
export const legendList = [
{ img: legend1, text: '油田医院' },
@@ -133,7 +134,6 @@ export const legendList = [
{ img: legend3, text: '救护车' },
{ img: legend4, text: '合作医院' },
{ img: legend5, text: '地方医院' },
{ img: legend6, text: '直升机' },
];
/**
+189 -38
View File
@@ -16,7 +16,7 @@
</a-form-item>
<a-form-item>
<a-button class="reset-btn" @click="removeInput">清空</a-button>
<a-button class="search-btn" @click="searchRoute">路线规划</a-button>
<a-button class="search-btn" @click="searchRoute" :loading="searchFlag" :disabled="searchFlag"> 路线规划 </a-button>
</a-form-item>
</a-form>
<div v-show="showRoutePanel" v-click-outside="outClick" class="line-container">
@@ -36,6 +36,16 @@
<div v-show="!routeList.length" class="empty-data"> 暂无数据</div>
</div>
</div>
<div v-show="showHospitalList" class="reset-map" @click="resetMap">
<RedoOutlined title="重置地图" />
</div>
<RoutePanel
class="driving-route-panel"
v-show="showDrivingPanel"
:drivingRoute="drivingRoute"
:drivingTitle="drivingTitle"
@out-click="showDrivingPanel = false"
/>
<div style="flex: 1; overflow: hidden; margin: 0 0 10px">
<div id="mapContainer" class="mapContainer"></div>
</div>
@@ -48,31 +58,73 @@
</div>
<!-- <div class="level">地图层级{{ level }}</div>-->
</div>
<div class="center-footer">
<div class="count-item" @click="test">
<div class="num">{{ footerData?.alerdyreceive || '/' }}</div>
<div class="center-footer" v-if="showFooter">
<div class="count-item">
<div class="num">{{ useDetail?.alerdyreceive || '0' }}</div>
<div class="text">累计受理</div>
</div>
<div class="count-item">
<div class="num">{{ footerData?.totalacceptance || '/' }}</div>
<div class="num">{{ useDetail?.totalacceptance || '0' }}</div>
<div class="text">累计处置</div>
</div>
</div>
<!-- 附近医院医疗点 -->
<div class="hospital-list" v-if="showHospitalList">
<div class="hospital-item" v-for="(item, index) in hospitalList" :key="index" @click="showDrivingLine(item)">
<div>{{ item.name }}</div>
<div>相距{{ item.distance }}</div>
<div>驾车大约{{ item.driveTime }}</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import $bus from '/@/utils/bus.ts';
import { nextTick, onMounted, ref } from 'vue';
import { message } from 'ant-design-vue';
import { RedoOutlined } from '@ant-design/icons-vue';
import { Map } from '/@/assets/mapUtils/map';
import { aircraft, getKmStr, getTimeStr, legendList, mapApiSwitch, tabList, TabType } from '/@/components/chinaMap/chinaHooks';
import { useDetailStore } from '/@/store/modules/detailData.ts';
import RoutePanel from '/@/components/chinaMap/components/routePanel.vue';
function test() {
Map.clearActiveHospital();
console.log('清空了');
}
const props = defineProps({
//是否展示底部统计
showFooter: {
type: Boolean,
default: () => {
return true;
},
},
//地图是否按照接口数据的中心点定位
computedCenter: {
type: Boolean,
default: () => {
return true;
},
},
// 地图配置
mapOptions: {
type: Object,
default: () => {
return {};
},
},
//是否展示最近的三个医院
showHospitalList: {
type: Boolean,
default: () => {
return false;
},
},
hospitalList: {
type: Array,
default: () => {
return [];
},
},
});
const emits = defineEmits(['clearHospitalList']);
const useDetail = useDetailStore();
const formState = ref({
start: '',
end: '',
@@ -83,11 +135,11 @@
function changeTab(item, i: number) {
currentIndex.value = i; // 地方医院
Map.clearActiveHospital();
closeDrivingElement();
Map.map.off('moveend', logMapinfo);
if (TabType.diFangYiYuan == item.type) {
Map.clearActiveHospital();
Map.removeOverlayGroup();
Map.map.on('moveend', logMapinfo);
// debugger;
return;
}
if (TabType.zhiShengJi == item.type) {
@@ -98,11 +150,15 @@
}
}
const currentCityCode = ref('');
function logMapinfo() {
// let zoom = Map.map.getZoom();
Map.map.getCity(function (info) {
const { citycode } = info;
if (currentCityCode.value != citycode) {
Map.createActiveHospital(citycode);
currentCityCode.value = citycode;
}
});
}
@@ -116,8 +172,11 @@
async function getMapData(type, params = {}) {
try {
const { code, result } = await mapApiSwitch(type, params);
if (code == 200 && Array.isArray(result) && result.length > 0) {
Map.createOverlay(result, {
if (code == 200) {
if (Array.isArray(result) && result.length > 0) {
Map.createOverlay(
result,
{
content: (val) => {
return `<div style="
width: 21px;
@@ -127,35 +186,26 @@
top: -20px;" title="${val?.name}">
</div>`;
},
});
},
() => {},
props.computedCenter
);
} else {
Map.removeOverlayGroup();
}
}
} catch (e) {
console.log('error------------------------------');
console.warn(e);
}
1;
// console.log('--->data', result);
}
const footerData = ref({
alerdyreceive: '',
totalacceptance: '',
});
onMounted(() => {
console.log('reload');
initMap();
Map.initMap({ el: 'mapContainer', option: props.mapOptions }).then(() => {
getMapData(tabList[0].type);
Map.map && Map.map.on('moveend', setLevel);
Map.map && Map.map.on('zoomend', setLevel);
$bus.on('alerdyreceive', (val) => {
footerData.value = val;
Map.map && Map.map.on('zoomend', setLevel);
});
});
function initMap() {
Map.initMap({ el: 'mapContainer' });
}
const routeList = ref([]);
const showRoutePanel = ref(false);
const panelTitle = ref();
@@ -171,6 +221,8 @@
panelTitle.value = str;
}
let searchFlag = ref(false);
/**
* @desc 路线规划
* @param callback
@@ -184,6 +236,7 @@
if (!formState.value.end) {
return message.warn('请输入终点');
}
searchFlag.value = true;
//基本地图加载
let map = new AMap.Map('container', {
resizeEnable: true,
@@ -199,13 +252,18 @@
driving.search([{ keyword: formState.value.start }, { keyword: formState.value.end }], function (status, result) {
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
if (status === 'complete') {
searchFlag.value = false;
// console.log('绘制驾车路线完成');
} else {
searchFlag.value = false;
// console.log('获取驾车数据失败:' + result);
}
});
AMap.Event.addListener(driving, 'complete', (res) => {
const data = JSON.parse(JSON.stringify(res));
searchFlag.value = false;
if (data.info == 'OK') {
const { routes } = data;
setTitle(routes[0]);
@@ -224,6 +282,37 @@
function removeInput() {
formState.value.start = '';
formState.value.end = '';
searchFlag.value = false;
}
// 驾车路线
const drivingRoute = ref([]);
const drivingTitle = ref('');
const showDrivingPanel = ref(false);
function showDrivingLine(item) {
nextTick(() => {
drivingTitle.value = '全程' + item.driveTime + item.distance;
drivingRoute.value = item.routeList?.map((item) => item?.instruction);
showDrivingPanel.value = true;
if (item.lon) {
Map.clearNaviLine();
Map.createNaviLine(item.userLocation, [item.lon, item.lat]);
}
});
}
function closeDrivingElement() {
Map.clearNavigationElements();
formState.value.start = '';
formState.value.end = '';
showDrivingPanel.value = false;
emits('clearHospitalList');
}
function resetMap() {
closeDrivingElement();
changeTab(list.value[currentIndex.value], currentIndex.value);
}
</script>
<style lang="less" scoped>
@@ -245,6 +334,7 @@
display: flex;
flex-wrap: wrap;
justify-content: space-between;
font-size: 16px;
.tab {
width: calc(100% / 8);
@@ -305,7 +395,7 @@
.search-btn {
margin-left: 10px;
width: 88px;
width: 120px;
height: 32px;
color: #efefef;
background: #45a2ff;
@@ -384,7 +474,7 @@
margin: 5px 19px 5px 8px;
}
.line-sesc {
.line-desc {
flex: 1;
}
}
@@ -396,6 +486,34 @@
}
}
.reset-map {
position: absolute;
left: 0;
top: 50px;
z-index: 99;
font-size: 20px;
color: #05d5ff;
cursor: pointer;
background: #243b5d;
padding: 0px 6px;
}
//驾驶路线导航面板
.driving-route-panel {
position: absolute;
right: 0;
top: 86px;
width: 288px;
padding: 9px 18px;
min-height: 200px;
max-height: 473px;
overflow: auto;
background: #2a4164;
border-radius: 2px;
border: 1px solid #1b7ef2;
z-index: 99;
}
.mapContainer {
flex: 1;
height: calc(100% + 22px);
@@ -459,5 +577,38 @@
}
}
}
.hospital-list {
position: absolute;
bottom: 200px;
width: 800px;
left: 50%;
transform: translateX(-50%);
display: flex;
.hospital-item {
position: relative;
flex: 1;
gap: 20px;
min-width: 230px;
max-width: 230px;
height: 110px;
text-align: center;
padding: 10px;
margin: 0 10px;
color: #fff;
font-size: 16px;
background-color: #00152b;
border: 1px solid #1b7ef2;
border-radius: 12px;
box-shadow: 0 1px 11px 0 rgba(194, 189, 189, 0.5);
cursor: pointer;
}
.hospital-item:hover {
background-color: #192a46;
box-shadow: inset 0px 0px 16px 3px #2562a9;
}
}
}
</style>
@@ -0,0 +1,120 @@
<template>
<div class="route-panel">
<div v-show="drivingRoute.length" class="has-data">
<div class="line-title">
<div>{{ drivingTitle }}</div>
<div class="close-icon">
<CloseCircleOutlined style="font-size: 16px" @click="outClick" />
</div>
</div>
<div class="line-content">
<div class="start">起点</div>
<div class="line-body">
<div class="line"></div>
<div class="line-desc">
<p v-for="(item, i) in drivingRoute" :key="i">{{ item }}</p>
</div>
</div>
<div class="end">终点</div>
</div>
</div>
<div v-show="!drivingRoute.length" class="empty-data"> 暂无数据</div>
</div>
</template>
<script setup lang="ts">
import { CloseCircleOutlined } from '@ant-design/icons-vue';
const props = defineProps({
drivingRoute: {
type: Array,
default: () => [],
},
drivingTitle: {
type: String,
default: '',
},
});
const emit = defineEmits(['outClick']);
function outClick() {
emit('outClick', false);
}
</script>
<style scoped lang="less">
.route-panel {
.line-title {
position: relative;
margin-bottom: 9px;
font-size: 14px;
font-weight: 700;
color: rgba(255, 255, 255, 0.8);
.close-icon {
position: absolute;
top: 1px;
right: -13px;
}
}
.line-content {
font-size: 12px;
.start {
display: flex;
align-items: center;
&::before {
content: '起';
color: #fff;
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #1478f5;
}
}
.end {
display: flex;
align-items: center;
&::before {
content: '终';
color: #fff;
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #1478f5;
}
}
.line-body {
display: flex;
//max-height: 370px;
}
.line {
width: 1px;
//max-height: 370px;
background-color: #1478f5;
margin: 5px 19px 5px 8px;
}
.line-desc {
flex: 1;
}
}
.empty-data {
margin-top: 30%;
text-align: center;
}
}
</style>
+52 -6
View File
@@ -1,12 +1,41 @@
<template>
<a-modal class="dialog" v-model:visible="props.openVis" :title="props.title" :width="props.width" :maskClosable="true" @cancel="handleCancel">
<template v-if="props.title">
<a-modal
:class="['dialog', themeType]"
v-model:visible="props.openVis"
:title="props.title"
:width="props.width"
:maskClosable="true"
@cancel="handleCancel"
destroy-on-close
>
<template #title>
<slot name="modalTitle"></slot>
</template>
<slot name="container"></slot>
<template #footer></template>
</a-modal>
</template>
<template v-else>
<a-modal
:class="['dialog', themeType]"
v-model:visible="props.openVis"
:width="props.width"
:maskClosable="true"
@cancel="handleCancel"
destroy-on-close
>
<template #title>
<slot name="modalTitle"></slot>
</template>
<slot name="container"></slot>
<template #footer></template>
</a-modal>
</template>
</template>
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
import { useTheme } from '/@/hooks/theme/useTheme.ts';
const emit = defineEmits(['close']);
const props = defineProps({
@@ -18,8 +47,10 @@
},
title: {
type: String,
default: () => '',
},
});
const { themeType } = useTheme();
function handleCancel() {
emit('close');
@@ -28,37 +59,52 @@
<style lang="less">
.dialog {
border: 1px solid #0a50a0;
background-color: #00152b;
padding-bottom: 0;
min-height: 300px;
box-shadow:
0 3px 6px -4px #0000001f,
0 6px 16px #00000014,
0 9px 28px 8px #0000000d;
.ant-modal-title {
position: relative;
display: flex;
align-items: center;
width: 100%;
min-height: 40px;
height: 40px;
background: url('../../assets/images/dialog.png') no-repeat;
background-size: 100% 100%;
color: #ffffff !important;
padding-left: 2%;
font-size: 18px;
font-weight: bold;
}
.ant-modal-header {
padding: 0 !important;
padding-bottom: 0;
border-bottom: none;
}
.ant-modal-header,
.ant-modal-content {
background-color: transparent !important;
box-shadow: none;
}
.ant-modal-body {
padding: 0 !important;
}
.ant-modal-close-x,
.anticon {
color: #999999 !important;
height: 40px;
}
.ant-modal-close-x {
color: #999999 !important;
height: 40px;
line-height: 40px;
}
@@ -67,7 +113,7 @@
}
.ant-modal-wrap {
background-color: rgba(0, 0, 0, 0.6);
//background-color: rgba(0, 0, 0, 0.6);
}
}
</style>
+20 -3
View File
@@ -1,12 +1,12 @@
<template>
<div class="left-pie">
<public-title :title="props.title">
<public-title :title="props.title" :theme-type="themeType">
<template #right>
{{ props.tips }}
</template>
</public-title>
<div class="inner" ref="healthChart"></div>
<div class="count" v-show="props.tips">
<div class="count">
<div class="t">总人数</div>
<div class="v">{{ userCount }}</div>
</div>
@@ -38,6 +38,10 @@
userCount: {
type: Number,
},
themeType: {
type: String,
default: () => '',
},
});
const healthChart = ref<HTMLElement>();
onMounted(() => {
@@ -48,6 +52,9 @@
() => props.data,
() => {
init();
},
{
deep: true,
}
);
@@ -57,7 +64,7 @@
function initChart(chartData, total, color) {
let myChart = echarts.init(healthChart.value);
let options = circleRing(chartData, total, color, '{d}%');
let options = circleRing(chartData, total, color);
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
@@ -71,6 +78,16 @@
height: calc(100% - 40px);
}
.inner::after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
background-color: #051a2b;
}
.left-pie {
position: relative;
padding-bottom: 0 !important;
+34 -17
View File
@@ -1,6 +1,10 @@
export function screenPie(chartData, total, color, formatter) {
// 步数
import {visibleChartLabel} from "/@/utils/utils.ts";
export function screenPie(chartData) {
const data = visibleChartLabel(chartData)
return {
color: color,
color: ['#B750BE', '#6C63F0', '#3AACFF', '#ED589D', '#FB466C'],
tooltip: {
trigger: 'item',
show: true,
@@ -11,7 +15,7 @@ export function screenPie(chartData, total, color, formatter) {
borderColor: '#1b7ef2',
},
legend: {
left: '74%',
right: '5%',
top: 'center',
orient: 'vertical',
icon: 'circle',
@@ -20,36 +24,35 @@ export function screenPie(chartData, total, color, formatter) {
color: '#ffffff',
fontSize: 16,
},
selectedMode: false
},
series: [
{
type: 'pie',
// radius: ['50%', '86%'],
// center: ['42%', '55%'],
radius: ['50%', '76%'],
center: ['42%', '49%'],
radius: ['50%', '72%'],
center: ['37%', '49%'],
avoidLabelOverlap: false,
label: {
show: true,
position: 'outside',
formatter: formatter,
color: '#ffffff',
fontSize: 14,
},
labelLine: {
show: true,
length: 6,
length2: 20,
length2: 10,
minTurnAngle: 120,
},
data: chartData,
data: data,
},
],
};
}
//左侧圆
export function circleRing(chartData, total, color, formatter) {
export function circleRing(chartData, total, color) {
const data = visibleChartLabel(chartData)
return {
color: color,
tooltip: {
@@ -71,24 +74,38 @@ export function circleRing(chartData, total, color, formatter) {
color: '#ffffff',
fontSize: 16,
},
selectedMode: false
},
series: [
{
type: 'pie',
radius: ['50%', '82%'],
center: ['42%', '55%'],
radius: ['50%', '75%'],
center: ['42%', '50%'],
avoidLabelOverlap: false,
// label: {
// show: true,
// // position: 'inner',
// formatter: '{d}%',
// color: '#ffffff',
// fontSize: 14,
// },
// labelLine: {
// show: false,
// },
label: {
show: true,
position: 'inner',
formatter: formatter,
position: 'outside',
formatter: '{d}%',
color: '#ffffff',
fontSize: 14,
},
labelLine: {
show: false,
show: true,
length: 4,
length2: 12,
minTurnAngle: 120,
},
data: chartData,
data: data,
},
],
};
+5 -29
View File
@@ -1,9 +1,9 @@
<template>
<div class="title-d">
<div class="title-d public-title" :class="props.themeType">
<span>{{ props.title }}</span>
<div>
<span class="tips"><slot name="right"></slot></span>
<img src="../assets/img/point.png" alt="" />
<img v-if="props.themeType !== 'light'" src="../assets/img/point.png" alt="" />
</div>
</div>
</template>
@@ -17,6 +17,9 @@
type: Boolean,
default: () => false,
},
themeType: {
type: String,
},
});
const emit = defineEmits(['clickMore']);
@@ -31,36 +34,9 @@
text-align: left;
height: 40px;
line-height: 40px;
background: linear-gradient(90deg, rgba(106, 112, 124, 0.4) 0%, rgba(106, 112, 124, 0) 70%, rgba(106, 112, 124, 0) 100%);
opacity: 1;
border-top: 1px solid #6a707c;
border-bottom: 1px solid #6a707c;
border-image: linear-gradient(
90deg,
rgba(217.0000022649765, 231.00000143051147, 255, 0.5),
rgba(217.0000022649765, 231.00000143051147, 255, 0)
)
1 1;
color: #ffffff;
font-size: 20px;
font-weight: 700;
display: flex;
justify-content: space-between;
&:before {
position: absolute;
content: '';
width: 7px;
height: 100%;
top: 0;
left: 0;
background-color: #45a2ff;
}
.tips {
font-size: 13px;
padding-right: 10px;
font-weight: normal;
}
}
</style>
+5 -1
View File
@@ -1,11 +1,12 @@
import { get, post } from '/@/api/request.ts';
export enum Api {
depart = 'sys/sysDepart/allSecondaryDeparts',
depart = '/health-watch/watch/watchDevice/getUnitList',
getWatchDataByOrgCode = '/health-watch/watch/watchData/getWatchDataByOrgCode',
getMonitorList = '/health-watch/watch/watchMonitorData/getMonitorList',
sleepApi = '/health-watch/watch/watchData/getSleep',
stepApi = '/health-watch/watch/watchData/getSdc',
listCustom = 'health-watch/watch/watchMonitorData/listCustom',
}
// 单位-
@@ -20,3 +21,6 @@ export const getMonitorList = (params: any) => get(Api.getMonitorList, params);
export const getSleep = (params: any) => post(Api.sleepApi, params);
// 右-步数
export const getStep = (params: any) => post(Api.stepApi, params);
//副屏-预警
export const getCustom = (params: any) => get(Api.listCustom, params);
@@ -1,6 +1,14 @@
<template>
<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
:themeType="themeType"
:keu="spinning"
:title="item.title"
:data="item.data"
:tips="item.tips"
:color="item.color"
:userCount="item.userCount"
/>
</template>
</template>
@@ -9,7 +17,12 @@
import { cloneDeep } from 'lodash-es';
import ItemD from '/@/components/item-d/item-d.vue';
import { getWatchDataByOrgCode } from '/@/components/secondaryScreen/commonApi.ts';
import { useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
const { setSession, getSession } = useSession();
const { PAGE2_LEFT } = caching;
const { spinning, setSpin } = useSpin();
const dataList = ref([
{
title: '心率',
@@ -51,7 +64,7 @@
{
title: '体温',
data: [
{ name: '37.2', value: 0, key: 'normalCountCount' },
{ name: '<37.2', value: 0, key: 'normalCount' },
{ name: '37.2-38', value: 0, key: 'warnCount' },
{ name: '>38', value: 0, key: 'riskCount' },
],
@@ -65,6 +78,7 @@
const props = defineProps({
orgCode: String,
type: String,
themeType: String,
});
onMounted(() => {});
watch(props, () => {
@@ -72,8 +86,21 @@
});
async function init() {
setSpin(true);
try {
const { code, result } = await getWatchDataByOrgCode(props);
if (code == 200) {
setValue(result);
setSession(PAGE2_LEFT, JSON.stringify(result));
}
} catch {
const result = JSON.parse(getSession(PAGE2_LEFT));
setValue(result);
}
}
function setValue(result) {
setSpin(false);
let data = cloneDeep(dataList.value);
data.forEach((item) => {
let resData = result.find((v) => v.type == item.type);
@@ -84,7 +111,6 @@
});
dataList.value = data;
}
}
defineExpose({
init,
@@ -1,6 +1,6 @@
<template>
<div class="terminal-container self">
<public-title title="睡眠" />
<public-title title="睡眠" :theme-type="themeType" />
<div class="inner">
<div class="title">
<span class="lightSleep">平均睡眠 {{ nums.avg }} 深睡 {{ nums.avgLong }} 浅睡 {{ nums.avgShort }}</span>
@@ -12,22 +12,25 @@
<script setup lang="ts">
import PublicTitle from '/@/components/publicTitle.vue';
import * as echarts from 'echarts';
import { ref, onMounted, watch } from 'vue';
import { ref, watch } from 'vue';
import { formatStr, sleepCharts } from '/@/components/secondaryScreen/screen-right/screenRightHooks';
import { getSleep } from '/@/components/secondaryScreen/commonApi.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
const { setSession, getSession } = useSession();
const { PAGE2_RIGHT1 } = caching;
const props = defineProps({
orgCode: String,
type: String,
themeType: String,
});
const sleepChart = ref<HTMLElement>();
watch(
props,
() => {
console.log(111111111111);
init();
},
{ immediate: true }
{ immediate: true, deep: true }
);
const nums = ref({
avgShort: '',
@@ -36,12 +39,23 @@
});
async function init() {
try {
const params = {
orgCode: props.orgCode,
type: props.type,
};
const { code, result } = await getSleep(params);
if (code == 200 && result.length > 0) {
setSession(PAGE2_RIGHT1, JSON.stringify(result));
setValue(result);
}
} catch {
const result = JSON.parse(getSession(PAGE2_RIGHT1));
setValue(result);
}
}
function setValue(result) {
let time = result?.map((item) => item.dataDate);
let short = result?.map((item) => item.avgShortDuration);
let long = result?.map((item) => item.avgLongDuration);
@@ -58,7 +72,6 @@
avg: formatStr({ list: avg, len }), //平均
};
}
}
function initChart({ time, short, long, awake, type }) {
let myChart = echarts.init(sleepChart.value);
@@ -1,4 +1,4 @@
import { ref } from 'vue';
import { ref, unref } from 'vue';
import dayjs from 'dayjs';
import { minuteToStr } from '/@/utils/utils.ts';
@@ -61,6 +61,7 @@ export function sleepCharts({ time, short, long, awake, type }) {
borderColor: '#1b7ef2',
},
legend: {
orient: 'horizontal',
data: ['清醒', '浅睡', '深睡'],
textStyle: {
color: '#ffffff',
@@ -69,7 +70,8 @@ export function sleepCharts({ time, short, long, awake, type }) {
height: 40,
itemHeight: 14,
top: -5,
left: '55%',
right: '15%',
selectedMode: false,
},
color: ['#14B3F8', '#6D7BEB', '#5451DC'],
xAxis: {
@@ -144,19 +146,19 @@ export function useStep() {
{
name: '1~1.5w',
value: '0',
type: 'TenThousandToFifteenThousand',
type: 'tenThousandToFifteenThousand',
type_dictText: '其他',
},
{
name: '1.5w~2w',
value: '0',
type: 'FifteenToTwentyThousand',
type: 'fifteenToTwentyThousand',
type_dictText: '其他',
},
{
name: '2以上',
name: '2w以上',
value: '0',
type: 'TwentyThousandOrMore',
type: 'twentyThousandOrMore',
type_dictText: '其他',
},
]);
@@ -168,18 +170,28 @@ export function useStep() {
total.value = data?.userCount;
}
function getStepData() {
return unref(stepData);
}
function getTotal() {
return unref(total);
}
return {
total,
stepData,
setStep,
getStepData,
getTotal,
};
}
export const monitorColumns = [
{
title: '姓名',
dataIndex: 'realName',
key: 'realName',
dataIndex: 'userName',
key: 'userName',
align: 'center',
},
{
@@ -1,6 +1,8 @@
<template>
<div>
<public-title title="预警" />
<public-title title="预警" :theme-type="themeType">
<template #right><span class="right-text" :class="[themeType]" @click="viewDetail">查看详情</span> </template>
</public-title>
<div class="inner-screen">
<a-table
:scroll="{
@@ -10,8 +12,11 @@
:columns="monitorColumns"
:dataSource="dataSource"
:pagination="pagination"
:rowClassName="(record, index) => (index % 2 === 1 ? 'table-default' : 'table-striped')"
class="ant-table-striped"
:rowClassName="
(record, index) => (index % 2 === 1 ? 'table-default no-white cursor-pointer' : 'table-striped no-white cursor-pointer')
"
class="ant-table-striped three-table"
:custom-row="customRow"
>
<template #address="{ text, record }">
<div class="police-times" @click="handlePoliceDetail(record)">
@@ -20,28 +25,38 @@
</template>
</a-table>
</div>
<!--预警查看详情-->
<EarlyWarningDialog ref="earlyWarningRef"></EarlyWarningDialog>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from 'vue';
import { onUnmounted, ref, watch } from 'vue';
import PublicTitle from '/@/components/publicTitle.vue';
import { getMonitorList } from '/@/components/secondaryScreen/commonApi.ts';
import EarlyWarningDialog from '/@/views/components/earlyWarningDialog.vue';
import { getCustom, getMonitorList } from '/@/components/secondaryScreen/commonApi.ts';
import { monitorColumns } from '/@/components/secondaryScreen/screen-right/screenRightHooks.ts';
import $bus from '/@/utils/bus.ts';
import { earlyWarning } from '/@/utils/busConstant.ts';
import { useRefresh } from '/@/hooks/autoRefresh';
import { PAGE_SWITCH } from '/@/hooks/autoRefresh/pageRefreshTime.ts';
import { useSession, caching } from '/@/hooks/autoRefresh/caching.ts';
const props = defineProps({
orgCode: String,
type: String,
themeType: String,
});
const { setSession, getSession } = useSession();
const { PAGE2_RIGHT3 } = caching;
const tableHeight = ref(0);
const dataSource = ref([]);
const pagination = ref({
current: 1,
pageSize: 2,
pageSize: 10,
total: 0,
onChange: pageChange,
showSizeChanger: false,
});
const timer = ref(null);
const pages = ref(0); //总页数
@@ -57,9 +72,8 @@
tableHeight.value == 0 && setHeight();
window.addEventListener('resize', setHeight);
timer.value && clearInterval(timer.value);
// interval();
},
{ immediate: true }
{ immediate: true, deep: true }
);
onUnmounted(() => {
@@ -73,15 +87,27 @@
}
async function init(page) {
const { pageSize, current } = pagination.value;
const { code, result } = await getMonitorList({ pageSize, pageNo: page, orgCode: props.orgCode });
try {
const { pageSize } = pagination.value;
const { code, result } = await getCustom({ pageSize, pageNo: page, orgCode: props.orgCode });
if (code == 200) {
setSession(PAGE2_RIGHT3, JSON.stringify({ page, result }));
setValue(result, page);
}
} catch {
const { result, page } = getSession(PAGE2_RIGHT3) ? JSON.parse(getSession(PAGE2_RIGHT3)) : {};
if (result) {
setValue(result, page);
}
}
}
function setValue(result, page) {
dataSource.value = result.records;
pagination.value.total = result.total;
pages.value = result.pages;
pagination.value.current = page;
}
}
function pageChange(page, pageS) {
pagination.value.current = page;
@@ -90,26 +116,52 @@
}
function interval() {
console.log(55555);
// timer.value = setInterval(() => {
let page = pagination.value.current < pages.value ? pagination.value.current + 1 : 1;
init(page);
// }, 3000);
}
const { refreshState } = useRefresh(3000, () => {
interval();
const { refreshState } = useRefresh(PAGE_SWITCH, () => {
// interval();
});
function customRow(record = {}) {
return {
onClick: () => {
handlePoliceDetail(record);
},
};
}
const earlyWarningRef = ref(null);
/**
* 查看详情
*/
function viewDetail() {
earlyWarningRef.value && earlyWarningRef.value.openDialog();
}
onUnmounted(() => {
clearInterval(timer.value);
});
</script>
<style lang="less" scoped>
.right-text {
font-weight: 100;
cursor: pointer;
margin-right: 3px;
font-size: 18px;
}
.inner-screen {
width: 100%;
height: calc(100% - 40px);
margin: 20px 0;
.cursor-pointer {
cursor: pointer;
}
.police-times {
display: flex;
align-items: center;
@@ -138,6 +190,11 @@
:deep(.ant-table-tbody > tr > td) {
border-bottom: none;
padding: 6px 4px;
cursor: pointer;
}
:deep(.ant-table-tbody > tr.ant-table-placeholder:hover > td) {
background-color: transparent !important;
}
:deep(.ant-table-row:hover) {
@@ -146,6 +203,15 @@
}
}
:deep(.ant-table-tbody > .no-white > td) {
background-color: blue;
}
.no-white,
.no-white:hover > td {
background-color: blue;
}
//奇行
.ant-table-striped :deep(.table-striped) td {
background-color: #0a0a0c;
@@ -1,6 +1,6 @@
<template>
<div class="pie-container self">
<public-title title="步数" />
<public-title title="步数" :theme-type="themeType" />
<div class="inner" ref="healthChart"></div>
<div class="count">
<div class="t">总人数</div>
@@ -9,29 +9,31 @@
</div>
</template>
<script setup lang="ts">
import { ref, unref, onMounted, watch } from 'vue';
import { ref, watch } from 'vue';
import * as echarts from 'echarts';
import PublicTitle from '/@/components/publicTitle.vue';
import { useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { useStep } from '/@/components/secondaryScreen/screen-right/screenRightHooks.ts';
import { screenPie } from '/@/components/item-d/pieCharts.ts';
import { getStep } from '/@/components/secondaryScreen/commonApi.ts';
import { caching, useSession } from '/@/hooks/autoRefresh/caching.ts';
const props = defineProps({
orgCode: String,
type: String,
themeType: String,
});
const { setSession, getSession } = useSession();
const { PAGE2_RIGHT2 } = caching;
watch(
props,
() => {
init();
},
{ immediate: true }
{ immediate: true, deep: true }
);
const { setSpin, spinning } = useSpin();
const healthChart = ref<HTMLElement>();
const color = ref(['#B750BE', '#6C63F0', '#3AACFF', '#ED589D', '#FB466C']);
const { stepData, total, setStep } = useStep();
const { total, setStep, getStepData } = useStep();
async function init() {
try {
@@ -40,20 +42,24 @@
type: props.type,
};
const { code, result } = await getStep(params);
setSpin(true);
if (code != 200) {
return;
if (code == 200) {
setValue(result);
setSession(PAGE2_RIGHT2, JSON.stringify(result));
}
setStep(result);
initChart(unref(stepData), '15000');
} catch {
initChart(unref(stepData), 0);
const result = JSON.parse(getSession(PAGE2_RIGHT2));
setValue(result);
}
}
function initChart(chartData, total) {
function setValue(result) {
setStep(result);
initChart(getStepData());
}
function initChart(chartData) {
let myChart = echarts.init(healthChart.value);
let options = screenPie(chartData, total, color.value, '{c}');
let options = screenPie(chartData);
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
@@ -74,7 +80,7 @@
.count {
position: absolute;
width: 80%;
width: 71%;
top: 51%;
display: flex;
flex-direction: column;
@@ -0,0 +1,207 @@
<template>
<a-table
class="ant-table-striped"
:loading="tableLoading"
:dataSource="dataSource"
:columns="columns"
:scroll="{ y: '56vh' }"
:pagination="paginationProp"
:rowClassName="(record, index) => (index % 2 === 1 ? 'table-default' : 'table-striped')"
>
<template #bodyCell="{ column, record, index, text }">
<template v-if="column.customRender && isFunction(column.customRender)" v-html="column.customRender({ column, record, index, text })">
</template>
<slot v-else-if="column.slot" :name="column.slot" v-bind="{ column, record, index, text } || {}"></slot>
<template v-else>
{{ text }}
</template>
<slot name="bodyCell" v-bind="{ column, record, index, text } || {}"></slot>
</template>
</a-table>
</template>
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import { isFunction } from '/@/utils/is.ts';
const props = defineProps({
columns: {
default: () => [],
},
api: {
type: Function,
},
apiParams: {
default: () => {},
},
afterFetch: {
type: Function,
},
});
//分页相关
const current = ref(1);
const pageSize = ref(10);
const tableLoading = ref(false);
const total = ref(0);
const deptId = ref();
const paginationProp = ref({
showSizeChanger: true,
pageSizeOptions: ['10', '30', '50'],
pageSize,
current,
total,
showTotal: (total) => `${total}`,
onChange: pageChange,
});
function pageChange(page, pageS) {
current.value = page;
pageSize.value = pageS;
getRecords();
}
function setPage({ cur, size, sum }) {
current.value = cur;
pageSize.value = size;
total.value = sum;
}
function setDataSource(result) {
dataSource.value = result;
}
const dataSource = ref([]);
async function getRecords() {
try {
tableLoading.value = true;
const { code, result } = await props.api({ ...props.apiParams, pageSize: pageSize.value, pageNo: current.value });
if (code == 200) {
if (props.afterFetch && isFunction(props.afterFetch)) {
dataSource.value = props.afterFetch({ result, setPage: setPage, setDataSource: setDataSource });
} else {
dataSource.value = result?.records;
}
paginationProp.value = { ...paginationProp.value, ...result };
paginationProp.value.pageSize = result.size;
}
} catch (e) {
dataSource.value = [];
tableLoading.value = false;
} finally {
tableLoading.value = false;
}
}
watch(
props,
() => {
nextTick(() => {
pageSize.value = 10;
current.value = 1;
getRecords();
});
},
{
immediate: true,
}
);
defineExpose({
getRecords,
});
</script>
<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;
border-bottom: none;
padding: 9px 9px;
text-align: center;
}
:deep(.ant-table-cell-scrollbar) {
box-shadow: none !important;
}
:deep(.ant-table) {
color: var(--tableFontColor);
background-color: transparent;
//pointer-events: none;
}
:deep(.ant-table-tbody > tr > td) {
border-bottom: none;
padding: 0 4px;
}
:deep(.ant-table-row:hover) {
background-color: transparent;
color: var(--tableFontColor);
}
.ant-table-striped :deep(.table-default) td,
.ant-table-striped :deep(.table-striped) td {
background-color: var(--tableRowBg) !important;
border-bottom: 1px solid var(--tableRowBorder);
padding: 10px 4px !important;
text-align: center;
}
:deep(.ant-table-tbody > tr.ant-table-row:hover > td, .ant-table-tbody > tr > td.ant-table-cell-row-hover) {
background: transparent;
}
// 分页
:deep(.ant-pagination-prev .ant-pagination-item-link, .ant-pagination-next .ant-pagination-item-link) {
background-color: var(--pageItemLink);
color: #8291a9;
border: none;
}
:deep(.ant-pagination-item) {
background-color: var(--pageItemLink);
color: var(--tableFontColor);
border: none;
}
// 当前页选中的样式
:deep(.ant-pagination-item-active) {
background-color: var(--pageItemActiveBg);
}
:deep(.ant-pagination-item-active a) {
color: #fff;
}
:deep(.ant-pagination-item a),
:deep(.ant-pagination-total-text) {
color: var(--tableFontColor);
}
//:deep(.ant-pagination-prev .ant-pagination-item-link, .ant-pagination-next .ant-pagination-item-link) {
// color: var(--tableFontColor);
// background-color: var(--pageItemLink);
//}
// 省略样式
:deep(.ant-pagination-jump-next .ant-pagination-item-container .ant-pagination-item-ellipsis) {
color: var(--tableFontColor);
}
// 省略鼠标移入样式
:deep(.ant-pagination-jump-next .ant-pagination-item-container .ant-pagination-item-link-icon) {
color: rgba(255, 255, 255, 0.4);
}
// 下一页
:deep(.ant-pagination-next .ant-pagination-item-link) {
background-color: var(--pageItemLink);
color: #8291a9;
border: none;
}
:deep(.ant-table-pagination-right) {
margin-right: 10px !important;
}
</style>
@@ -1,20 +1,27 @@
<template>
<div class="modal-content">
<div class="empty-png"></div>
<div class="modal-header">
<button type="button" aria-label="Close" class="modal-close" @click="closeDialog">X</button>
<div class="modal-title" id="vcDialogTitle0">健康报警员工信息</div>
</div>
<div class="modal-body">
<div class="info-left">
<div v-for="item in detailLeft" :key="item.key"
><span class="info-label">{{ item.name }}</span><span class="info-value">{{ item.value }}</span></div
>
<div v-for="item in detailLeft" :key="item.key" style="display: flex">
<template v-if="item.customRender">
<div class="info-label">{{ item.name }}</div>
<div class="info-value" v-html="item.customRender(item.value)"></div>
</template>
<template v-else>
<div class="info-label">{{ item.name }}</div>
<div class="info-value">{{ item.value }}</div>
</template>
</div>
</div>
<div class="info-right">
<div v-for="item in detailRight" :key="item.key"
><span class="info-label">{{ item.name }}</span><span class="info-value">{{ item.value }}</span></div
>
<div v-for="item in detailRight" :key="item.key" style="display: flex">
<div class="info-label">{{ item.name }}</div>
<div class="info-value">{{ item.value }}</div>
</div>
</div>
</div>
</div>
@@ -38,13 +45,6 @@
border: 0;
border-radius: 2px;
.empty-png {
width: 100%;
height: 16px;
background: url('../../../../assets/images/bg.png') no-repeat;
background-position-y: -500px;
}
.modal-close {
width: 40px;
height: 40px;
@@ -97,12 +97,18 @@
padding: 2% 0 2% 5%;
display: flex;
div {
flex: 1;
> div {
line-height: 28px;
flex: 1;
.info-label {
text-align: right;
font-weight: bold;
width: 100px;
}
.info-value {
width: calc(100% - 100px);
}
}
}

Some files were not shown because too many files have changed in this diff Show More