初次提交

This commit is contained in:
jiangs 2026-09-18 15:13:13 +08:00
parent cfdf5154a1
commit a430c4846a
30 changed files with 64545 additions and 0 deletions

1225
QYJY/css/icon.css Normal file

File diff suppressed because one or more lines are too long

560
QYJY/css/index.css Normal file
View File

@ -0,0 +1,560 @@
@charset "UTF-8";
/*
基准设计稿:1920 宽 × 1080 高
宽度相关 px → px / 19.2 = vw
高度相关 px → px / 10.8 = vh' */
/* CSS Document */
.bg {
margin: 0 auto;
width: 100vw;
height: 100vh;
background: url(../images/bg1.jpg) no-repeat;
background-size: 100% 100%;
padding: 0vw 1.04vw 0vw 1.56vw;
transform-origin: center center;
overflow: hidden;
}
.title {
width: 100%;
height: 3.7vh;
font-size: 2vw;
line-height: 8.5vh;
color: #0efdff;
text-align: center;
font-weight: bold;
}
.container {
display: flex;
height: calc(100vh - 5.56vh);
}
.border_bg_leftTop {
position: absolute;
left: -0.1vw;
top: -0.93vh;
width: 4.82vw;
height: 1.16vh;
display: block;
background: #01279d url(../images/title_left_bg.png) no-repeat;
background-size: cover;
}
.border_bg_rightTop {
position: absolute;
right: -0.13vw;
top: -0.23vh;
width: 1.3vw;
height: 2.31vh;
display: block;
background: url(../images/border_bg.jpg) no-repeat;
background-size: cover;
}
.border_bg_leftBottom {
position: absolute;
left: -0.1vw;
bottom: -0.19vh;
width: 1.3vw;
height: 2.31vh;
display: block;
background: url(../images/border_bg.jpg) no-repeat;
background-size: cover;
}
.border_bg_rightBottom {
position: absolute;
right: -0.13vw;
bottom: -0.23vh;
width: 1.04vw;
height: 1.85vh;
display: block;
background: url(../images/title_right_bg.png) no-repeat;
background-size: cover;
}
.leftMain {
width: 68%;
height: 100%;
display: flex;
flex-direction: column;
margin-right: 0.78vw;
}
.rightMain {
width: 32%;
height: 100%;
padding-top: 3.7vh;
}
.leftMain_top {
width: 100%;
}
.leftMain_top ul {
display: flex;
display: -webkit-flex;
}
.leftMain_top ul li {
width: 26%;
padding-right: 1.3vw;
}
.leftMain_top ul li:last-child {
padding: 0;
}
.leftMain_top ul li:first-child {
width: 22%;
}
.leftMain_top ul li .liIn {
border: 0.1vw solid rgba(14, 253, 255, 0.5);
width: 100%;
min-height: 5.56vh;
position: relative;
padding: 0.3vw 1.04vw;
}
.leftMain_top ul li .liIn h3 {
font-size: 1.6vw;
font-weight: 700;
color: #fff;
}
.leftMain_top ul li .liIn .shu {
font-size: 1.6vw;
color: #0efdff;
font-family: dig;
margin-bottom: 0.46vh;
}
.leftMain_top ul li .liIn .shu i {
font-size: 0.9vw;
margin-left: 0.1vw;
font-style: normal;
}
.leftMain_top ul li .liIn .zi {
font-size: 0.52vw;
color: #fff;
position: relative;
z-index: 10;
}
.leftMain_top ul li .liIn .zi .span1 {
margin-right: 1.3vw;
}
.leftMain_middle {
flex: 1;
width: 100%;
display: flex;
display: -webkit-flex;
margin-top: 1.85vh;
min-height: 0;
}
.leftMain_middle .leftMain_middle_left {
display: flex;
flex-direction: column;
width: 70%;
margin-right: 0.52vw;
}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn {
border: 0.1vw solid rgba(14, 253, 255, 0.5);
width: 100%;
height: 49%;
position: relative;
padding: 0.2vw;
}
.leftMain_middle_leftIn_zhe {
margin-top: 1%;
/* height: 48%; */
}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn h3 {
font-size: 1.6vw;
color: #fff;
font-weight: 700;
}
.leftMain_middle .leftMain_middle_left .leftMain_middle_leftIn .biaoge {
width: 100%;
height: calc(100% - 5vh);
}
.leftMain_middle .leftMain_middle_right {
width: 30%;
height: calc(100% - 0.46vh);
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn {
border: 0.1vw solid rgba(14, 253, 255, 0.5);
width: 100%;
height: 100%;
position: relative;
padding: 0.52vw;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn h3 {
font-size: 1.6vw;
color: #fff;
font-weight: 700;
}
/*左边中间部分排行榜*/
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai {
width: 100%;
height: calc(100% - 5vh);
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn {
display: flex;
display: -webkit-flex;
align-items: center;
color: #fff;
font-size: 1.6vw;
font-weight: 700;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_left {
width: 38%;
position: relative;
line-height: 1;
flex‑shrink: 0;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_left .bot {
width: 1.04vw;
height: 2vh;
background: #05d1fc;
border-radius: 1000px;
display: block;
position: absolute;
left: 0.26vw;
top: 0;
bottom: 0;
margin: auto 0;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li {
margin-bottom: 10px;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_line {
width: 40%;
height: 3.3vh;
background: rgba(255, 255, 255, 0.5);
border-radius: 2000px;
overflow: hidden;
position: relative;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .liIn_line .line_lineIn {
width: 100%;
height: 3.3vh;
background: #05d1fc;
border-radius: 2000px;
-webkit-animation: widthMove1 2s ease-in-out;
}
.leftMain_middle .line_lineIn_sy {
width: 100%;
height: 3.3vh;
background: #fcae05;
border-radius: 2000px;
-webkit-animation: widthMove2 2s ease-in-out;
}
.line_lineIn .per {
position: absolute;
top: 0;
left: 20%;
font-size: 1.4vw;
line-height: 3.3vh;
}
.line_lineIn_sy .per {
position: absolute;
top: 0;
left: 20%;
font-size: 1.4vw;
line-height: 3.3vh;
}
@-webkit-keyframes widthMove1 {
0% {
width: 0%;
}
100% {
width: 98.5%;
}
}
@-webkit-keyframes widthMove2 {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_pai ul li .liIn .num {
width: 22%;
font-family: dig;
padding-left: 0.26vw;
}
/*左边底部*/
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
width: 100%;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li {
width: 33.3%;
text-align: center;
margin-bottom: 1.16vh;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li .shu {
font-size: 1.82vw;
color: rgba(14, 253, 255, 1);
font-family: dig;
padding: 2.78vh 0 0.46vh;
font-weight: normal;
}
.leftMain_middle .leftMain_middle_right .leftMain_middle_rightIn .biaoge_bi ul li .zi {
font-size: 0.78vw;
color: #fff;
}
/*右边部分*/
.rightMain .rightMain_topIn {
border: 0.1vw solid rgba(14, 253, 255, 0.5);
width: 100%;
height: calc(100% - 0.46vh);
position: relative;
padding: 0.52vw;
}
.proportion {
height: calc(100% - 5vh);
overflow-y: auto;
}
.proportion ul li .liIn {
display: flex;
display: -webkit-flex;
align-items: center;
color: #fff;
font-size: 1.6vw;
font-weight: 700;
/* height: 5vh; */
margin-bottom: 10px;
}
.proportion ul li .liIn .zi {
line-height: 10px;
}
.proportion ul li .liIn .liIn_left {
width: 60%;
position: relative;
}
.proportion ul li .liIn .liIn_left .bot {
width: 1.04vw;
height: 1.85vh;
background: #05d1fc;
border-radius: 1000px;
display: block;
position: absolute;
left: 0.26vw;
top: 0;
bottom: 0;
margin: auto 0;
}
.proportion ul li .liIn .liIn_line {
width: 25%;
height: 3.3vh;
background: rgba(255, 255, 255, 0.5);
border-radius: 2000px;
overflow: hidden;
position: relative;
font-size: 1.4vw;
}
.proportion ul li .liIn .liIn_line .line_lineIn {
width: 100%;
height: 3.3vh;
background: #05d1fc;
border-radius: 2000px;
-webkit-animation: widthMove1 2s ease-in-out;
}
.proportion ul li .liIn .num {
width: 15%;
font-family: dig;
padding-left: 0.26vw;
}
.rightMain .rightMain_topIn h3 {
font-size: 1.6vw;
color: #fff;
font-weight: 700;
margin-bottom: 10px;
}
.rightMain .rightMain_topIn .biaoge {
/* min-height: 200px; */
}
.rightMain .rightMain_bottom {
width: 100%;
}
.rightMain .rightMain_bottomIn {
border: 0.1vw solid rgba(14, 253, 255, 0.5);
width: 100%;
min-height: 5.56vh;
position: relative;
padding: 1.85vh 0.65vw;
}
.rightMain .rightMain_bottomIn h3 {
font-size: 0.94vw;
color: #fff;
margin-bottom: 1.16vh;
font-weight: 700;
}
/*右下角表格*/
.rightMain .rightMain_bottomIn .biaoge {
min-height: 18.5vh;
}
.rightMain .rightMain_bottomIn .biaoge_list {
overflow: hidden;
position: relative;
}
.rightMain .rightMain_bottomIn .biaoge_list .biaoge_listIn .ul_list {
overflow: hidden;
position: relative;
}
.rightMain .rightMain_bottomIn .biaoge_list .biaoge_listIn .ul_listIn {
-webkit-animation: 14s gundong linear infinite normal;
animation: 14s gundong linear infinite normal;
position: relative;
}
@keyframes gundong {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, -30vh, 0);
transform: translate3d(0, -30vh, 0);
}
}
.rightMain .rightMain_bottomIn .biaoge_list ul {
display: flex;
display: -webkit-flex;
width: 100%;
}
.rightMain .rightMain_bottomIn .biaoge_list .ul_title {
background: linear-gradient(left, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
}
.rightMain .rightMain_bottomIn .biaoge_list .ul_con {
border-bottom: 0.1vw solid rgba(14, 253, 255, 0.5);
}
.rightMain .rightMain_bottomIn .biaoge_list ul li {
width: 20%;
text-align: center;
color: #fff;
font-size: 0.78vw;
height: 4.63vh;
line-height: 4.63vh;
}
.rightMain .rightMain_bottomIn .biaoge_list ul li:frist-child {
text-align: left;
}
.title_nums {
font-size: 1.6vw;
font-weight: 700;
color: #fff;
margin: 0.2vh 0 0.3vh;
}
.nums_box {
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: space-between;
}
/* 适配你深蓝色科技风的滚动条 */
/* 整体滚动条容器 */
::-webkit-scrollbar {
width: 0.52vw;
height: 0.52vw;
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background: rgba(0, 150, 255, 0.1);
border-radius: 0.21vw;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background: linear-gradient(to bottom,
#00d4ff,
#0099cc);
border-radius: 0.21vw;
box-shadow: 0 0 0.31vw rgba(0, 212, 255, 0.5);
}
/* 滑块 hover */
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(to bottom,
#00f0ff,
#00aadd);
box-shadow: 0 0 0.52vw rgba(0, 240, 255, 0.8);
}
::-webkit-scrollbar-button {
display: none;
}

95
QYJY/css/index2.css Normal file
View File

@ -0,0 +1,95 @@
.leftMain {
width: 70%;
height: 100%;
display: flex;
flex-direction: column;
margin-right: 15px;
padding-top: 30px;
}
.rightMain {
width: 30%;
height: 100%;
padding-top: 30px;
}
h3 {
font-size: 18px;
font-weight: 700;
color: #fff;
}
.leftMain_middle {
height: 100%;
display: flex;
flex-direction: column;
margin-top: 0;
}
.leftMain_middle_leftIn {
position: relative;
border: 2px solid rgba(14, 253, 255, 0.5);
height: 49%;
padding: 5px;
}
.leftMain_middle_leftIn_zhe {
margin-top: 10px;
}
.leftMain_middle .biaoge {
height: calc(100% - 70px);
}
.leftMain_middle_leftIn .left_mideele_top ul {
display: flex;
display: -webkit-flex;
}
.left_mideele_top ul li {
margin-right: 10px;
}
.left_mideele_top ul li:last-child {
margin: 0;
}
.left_mideele_top ul li .liIn {
border: 2px solid rgba(14, 253, 255, 0.5);
display: flex;
align-items: center;
padding: 5px;
}
.left_mideele_top ul li .liIn h3 {
font-size: 18px;
font-weight: 700;
color: #fff;
margin-right: 10px;
}
.left_mideele_top ul li .liIn .shu {
font-size: 18px;
color: #0efdff;
font-family: dig;
}
.left_mideele_top ul li .liIn .shu i {
font-size: 16px;
margin-left: 2px;
font-style: normal;
}
.left_mideele_top ul li .liIn .zi {
font-size: 10px;
color: #fff;
position: relative;
z-index: 10;
}
.rightMain_topIn {
position: relative;
border: 2px solid rgba(14, 253, 255, 0.5);
}

908
QYJY/css/public.css Normal file
View File

@ -0,0 +1,908 @@
@charset "utf-8";
/* CSS Document */
@font-face{
font-family: 'dig';
src : url('../fonts/DIN-Bold.otf');
}
body,p,div,h1,h2,h3,h4,h5,h6,button,input,ol,li,ul,dl,dt,dd,img,table,tr,td,th,select{
margin:0;
padding:0;
 -webkit-appearance:none;
border:0;
list-style:none;
box-sizing:border-box;}
a,img,button,input,textarea{-webkit-tap-highlight-color:rgba(255,255,255,0); outline-color:#0081ff; background:none;}
button{
outline:none;}
input::-webkit-input-placeholder {
color:#aaa;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button{
-webkit-appearance: none !important;
margin: 0;
}
input[type="number"]{-moz-appearance:textfield;}
body{
margin:0 auto;
font-size:16px;
color:#121212;
font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
position:relative;
}
a{
text-decoration:none;
color:#f06000;}
.noborder{
border:0 !important}
#header{
height:8px;
width:100%;
position:fixed;
top:0;
left:0;
z-index:1000;
}
.header{
height:8px;
width:100%;
position:fixed;
top:0;
left:0;
z-index:1000;
}
.headerIn{
width:100%;
height:100%;
position:relative;
background:#0081ff;
display: flex;
align-items: center;
justify-content: space-between;
}
.headerIn .back{
display: flex;
height: 100%;
align-items: center;
padding-left:3.2px;
font-size:2.24px;
color:#fff;
width:20%;
}
.headerIn .save{
display: flex;
height:65%;
align-items: center;
font-size:2.24px;
color:#fff;
padding:0 3.2px;
text-align:right;
justify-content:center;
margin-right:1.6px;
border-radius:3px;
border:1px solid #fff;
}
.cuIcon-back:before{
margin-right:3px;
font-size:2.56px;}
.headerIn h2{
width:50%;
font-size:2.88px;
color:#fff;
font-weight:normal;
text-align:center;
margin:0 auto;
padding:0;
font-family:"微软雅黑";
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
position:absolute;
left:0;
right:0;
top:0;
margin:auto;
height:100%;
line-height:8px;}
.headerIn .sel{
position:absolute;
top:0;
right:0;
display:block;
width:30%;
height:100%;
background:url(../images/icon_sel.png) no-repeat 90% center;
background-size:20px auto;
padding-right:25px;
color:#fff;
line-height:45px;}
.headerIn .share{
position:absolute;
top:0;
right:10px;
display:block;
width:60px;
height:100%;
background:url(../images/icon_share.png) no-repeat 5px center;
background-size:20px auto;
padding-left:25px;
color:#fff;
line-height:45px;
text-align:right;
font-size:14px;}
.zhezhao_new{
position:fixed;
z-index:100000;
background:rgba(0,0,0,0.5);
width:100%;
height:20000px;
top:0;
left:0;}
.nodate {
background: url(../images/nodate.png) no-repeat top center;
background-size: 65px auto;
padding-top: 75px;
text-align: center;
font-size: 14px;
color: #888;
line-height: 24px;
width: 90%;
margin: 0 auto;
}
.nodate2 {
background: url(../images/nodate8.png) no-repeat top center;
background-size:160px auto;
padding-top:150px;
text-align: center;
font-size: 14px;
color:#888;
line-height:24px;
width: 90%;
margin:150px auto 0;
}
.nodate3 {
background: url(../images/nodate10.png) no-repeat top center;
background-size:160px auto;
padding-top:150px;
text-align: center;
font-size: 14px;
color:#888;
line-height:24px;
width: 90%;
margin:150px auto 0;
}
.nodate3 .goto{
display:block;
width:120px;
height:40px;
background:none;
border:1px solid #f06000;
border-radius:5px;
color:#f06000;
font-size:16px;
font-family:"微软雅黑";
text-align:center;
margin:20px auto;
line-height:38px;}
.eggloading{
background: url(../images/loading2.gif) no-repeat top center;
background-size:60px auto;
padding-top:60px;
text-align: center;
font-size: 14px;
color: #888;
line-height: 24px;
width: 90%;
margin:200px auto 0;
}
.articleDel{
background: url(../images/nodate9.png) no-repeat top center;
background-size:160px auto;
padding-top:150px;
text-align: center;
font-size: 14px;
color:#888;
line-height:24px;
width: 90%;
margin:150px auto 0;
}
body .spinner-android{
display:none;}
body .loading{
background:url(../images/loading2.gif) no-repeat center center;
background-size:60px auto;
width:80px;
height:80px;
padding:10px;
}
/*资讯白色头部*/
.headerIn2{
width:100%;
height:100%;
position:relative;
background:#fff;
max-width:640px;
margin:0 auto;
box-shadow:1px 0 3px #aaa;
-webkit-box-shadow: 1px 0 3px #aaa;
-moz-box-shadow: 1px 0 3px #aaa;
}
.headerIn2 .back{
position:absolute;
top:0;
left:0;
display:block;
width:20%;
height:100%;
background:url(../images/back4.png) no-repeat 10px center;
background-size:12px auto;
padding-left:25px;
color:#555;
line-height:45px;
}
.headerIn2 h2{
width:80%;
height:100%;
line-height:45px;
font-size:16px;
color:#555;
font-weight:normal;
text-align:center;
margin:0 auto;
padding:0;
font-family:"微软雅黑";
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
font-weight:bold;}
.headerIn2 h2 img{
height:100%;
}
.headerIn2 .share{
position:absolute;
top:0;
right:10px;
display:block;
width:60px;
height:100%;
background:url(../images/zixun_icon_share.png) no-repeat right center;
background-size:20px auto;
padding-left:25px;
color:#fff;
line-height:45px;
text-align:right;
font-size:15px;}
.headerIn2 .fabu{
position:absolute;
top:7px;
right:10px;
height:30px;
line-height:30px;
padding:0 8px;
font-size:15px;
background:#f06000;
color:#fff;
border-radius:3px;}
body {
/* Color 可以自定义相关配色 */
/* var属性兼容性 --> https://www.caniuse.com/#feat=css-variables */
/* 标准色 */
--red: #e54d42;
--orange: #f37b1d;
--yellow: #fbbd08;
--olive: #8dc63f;
--green: #39b54a;
--cyan: #1cbbb4;
--blue: #0081ff;
--purple: #6739b6;
--mauve: #9c26b0;
--pink: #e03997;
--brown: #a5673f;
--grey: #8799a3;
--black: #333333;
--darkGray: #666666;
--gray: #aaaaaa;
--ghostWhite: #f1f1f1;
--white: #ffffff;
/* 浅色 */
--redLight: #fadbd9;
--orangeLight: #fde6d2;
--yellowLight: #fef2ce;
--oliveLight: #e8f4d9;
--greenLight: #d7f0db;
--cyanLight: #d2f1f0;
--blueLight: #cce6ff;
--purpleLight: #e1d7f0;
--mauveLight: #ebd4ef;
--pinkLight: #f9d7ea;
--brownLight: #ede1d9;
--greyLight: #e7ebed;
/* 渐变色 */
--gradualRed: linear-gradient(45deg, #f43f3b, #ec008c);
--gradualOrange: linear-gradient(45deg, #ff9700, #ed1c24);
--gradualGreen: linear-gradient(45deg, #39b54a, #8dc63f);
--gradualPurple: linear-gradient(45deg, #9000ff, #5e00ff);
--gradualPink: linear-gradient(45deg, #ec008c, #6739b6);
--gradualBlue: linear-gradient(45deg, #0081ff, #1cbbb4);
/* 阴影透明色 */
--ShadowSize: 6px 6px 8px;
--redShadow: rgba(204, 69, 59, 0.2);
--orangeShadow: rgba(217, 109, 26, 0.2);
--yellowShadow: rgba(224, 170, 7, 0.2);
--oliveShadow: rgba(124, 173, 55, 0.2);
--greenShadow: rgba(48, 156, 63, 0.2);
--cyanShadow: rgba(28, 187, 180, 0.2);
--blueShadow: rgba(0, 102, 204, 0.2);
--purpleShadow: rgba(88, 48, 156, 0.2);
--mauveShadow: rgba(133, 33, 150, 0.2);
--pinkShadow: rgba(199, 50, 134, 0.2);
--brownShadow: rgba(140, 88, 53, 0.2);
--greyShadow: rgba(114, 130, 138, 0.2);
--grayShadow: rgba(114, 130, 138, 0.2);
--blackShadow: rgba(26, 26, 26, 0.2);
background-color: var(--ghostWhite);
color: var(--black);
font-family: Helvetica Neue, Helvetica, sans-serif;
}
/* -- 阴影 -- */
.shadow[class*='white'] {
--ShadowSize: 0 1px 6px;
}
.shadow-lg {
--ShadowSize: 0px 6.4px 16px 0px;
}
.shadow-warp {
position: relative;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.shadow-warp:before,
.shadow-warp:after {
position: absolute;
content: "";
top: 20px;
bottom: 30px;
left: 20px;
width: 50%;
box-shadow: 0 30px 20px rgba(0, 0, 0, 0.2);
transform: rotate(-3deg);
z-index: -1;
}
.shadow-warp:after {
right: 20px;
left: auto;
transform: rotate(3deg);
}
.shadow-blur {
position: relative;
}
.shadow-blur::before {
content: "";
display: block;
background: inherit;
filter: blur(1.6px);
position: absolute;
width: 100%;
height: 100%;
top:0.8px;
left:0.8px;
z-index: -1;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
}
/* ==================
背景
==================== */
.line-red::after,
.lines-red::after {
border-color: var(--red);
}
.line-orange::after,
.lines-orange::after {
border-color: var(--orange);
}
.line-yellow::after,
.lines-yellow::after {
border-color: var(--yellow);
}
.line-olive::after,
.lines-olive::after {
border-color: var(--olive);
}
.line-green::after,
.lines-green::after {
border-color: var(--green);
}
.line-cyan::after,
.lines-cyan::after {
border-color: var(--cyan);
}
.line-blue::after,
.lines-blue::after {
border-color: var(--blue);
}
.line-purple::after,
.lines-purple::after {
border-color: var(--purple);
}
.line-mauve::after,
.lines-mauve::after {
border-color: var(--mauve);
}
.line-pink::after,
.lines-pink::after {
border-color: var(--pink);
}
.line-brown::after,
.lines-brown::after {
border-color: var(--brown);
}
.line-grey::after,
.lines-grey::after {
border-color: var(--grey);
}
.line-gray::after,
.lines-gray::after {
border-color: var(--gray);
}
.line-black::after,
.lines-black::after {
border-color: var(--black);
}
.line-white::after,
.lines-white::after {
border-color: var(--white);
}
.bg-red {
background-color: var(--red);
color: var(--white);
}
.bg-orange {
background-color: var(--orange);
color: var(--white);
}
.bg-yellow {
background-color: var(--yellow);
color: var(--black);
}
.bg-olive {
background-color: var(--olive);
color: var(--white);
}
.bg-green {
background-color: var(--green);
color: var(--white);
}
.bg-cyan {
background-color: var(--cyan);
color: var(--white);
}
.bg-blue {
background-color: var(--blue);
color: var(--white);
}
.bg-purple {
background-color: var(--purple);
color: var(--white);
}
.bg-mauve {
background-color: var(--mauve);
color: var(--white);
}
.bg-pink {
background-color: var(--pink);
color: var(--white);
}
.bg-brown {
background-color: var(--brown);
color: var(--white);
}
.bg-grey {
background-color: var(--grey);
color: var(--white);
}
.bg-gray {
background-color: #f0f0f0;
color: var(--black);
}
.bg-black {
background-color: var(--black);
color: var(--white);
}
.bg-white {
background-color: var(--white);
color: var(--darkGray);
}
.bg-shadeTop {
background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01));
color: var(--white);
}
.bg-shadeBottom {
background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1));
color: var(--white);
}
.bg-red.light {
color: var(--red);
background-color: var(--redLight);
}
.bg-orange.light {
color: var(--orange);
background-color: var(--orangeLight);
}
.bg-yellow.light {
color: var(--yellow);
background-color: var(--yellowLight);
}
.bg-olive.light {
color: var(--olive);
background-color: var(--oliveLight);
}
.bg-green.light {
color: var(--green);
background-color: var(--greenLight);
}
.bg-cyan.light {
color: var(--cyan);
background-color: var(--cyanLight);
}
.bg-blue.light {
color: var(--blue);
background-color: var(--blueLight);
}
.bg-purple.light {
color: var(--purple);
background-color: var(--purpleLight);
}
.bg-mauve.light {
color: var(--mauve);
background-color: var(--mauveLight);
}
.bg-pink.light {
color: var(--pink);
background-color: var(--pinkLight);
}
.bg-brown.light {
color: var(--brown);
background-color: var(--brownLight);
}
.bg-grey.light {
color: var(--grey);
background-color: var(--greyLight);
}
.bg-gradual-red {
background-image: var(--gradualRed);
color: var(--white);
}
.bg-gradual-orange {
background-image: var(--gradualOrange);
color: var(--white);
}
.bg-gradual-green {
background-image: var(--gradualGreen);
color: var(--white);
}
.bg-gradual-purple {
background-image: var(--gradualPurple);
color: var(--white);
}
.bg-gradual-pink {
background-image: var(--gradualPink);
color: var(--white);
}
.bg-gradual-blue {
background-image: var(--gradualBlue);
color: var(--white);
}
.shadow[class*="-red"] {
box-shadow: var(--ShadowSize) var(--redShadow);
}
.shadow[class*="-orange"] {
box-shadow: var(--ShadowSize) var(--orangeShadow);
}
.shadow[class*="-yellow"] {
box-shadow: var(--ShadowSize) var(--yellowShadow);
}
.shadow[class*="-olive"] {
box-shadow: var(--ShadowSize) var(--oliveShadow);
}
.shadow[class*="-green"] {
box-shadow: var(--ShadowSize) var(--greenShadow);
}
.shadow[class*="-cyan"] {
box-shadow: var(--ShadowSize) var(--cyanShadow);
}
.shadow[class*="-blue"] {
box-shadow: var(--ShadowSize) var(--blueShadow);
}
.shadow[class*="-purple"] {
box-shadow: var(--ShadowSize) var(--purpleShadow);
}
.shadow[class*="-mauve"] {
box-shadow: var(--ShadowSize) var(--mauveShadow);
}
.shadow[class*="-pink"] {
box-shadow: var(--ShadowSize) var(--pinkShadow);
}
.shadow[class*="-brown"] {
box-shadow: var(--ShadowSize) var(--brownShadow);
}
.shadow[class*="-grey"] {
box-shadow: var(--ShadowSize) var(--greyShadow);
}
.shadow[class*="-gray"] {
box-shadow: var(--ShadowSize) var(--grayShadow);
}
.shadow[class*="-black"] {
box-shadow: var(--ShadowSize) var(--blackShadow);
}
.shadow[class*="-white"] {
box-shadow: var(--ShadowSize) var(--blackShadow);
}
.text-shadow[class*="-red"] {
text-shadow: var(--ShadowSize) var(--redShadow);
}
.text-shadow[class*="-orange"] {
text-shadow: var(--ShadowSize) var(--orangeShadow);
}
.text-shadow[class*="-yellow"] {
text-shadow: var(--ShadowSize) var(--yellowShadow);
}
.text-shadow[class*="-olive"] {
text-shadow: var(--ShadowSize) var(--oliveShadow);
}
.text-shadow[class*="-green"] {
text-shadow: var(--ShadowSize) var(--greenShadow);
}
.text-shadow[class*="-cyan"] {
text-shadow: var(--ShadowSize) var(--cyanShadow);
}
.text-shadow[class*="-blue"] {
text-shadow: var(--ShadowSize) var(--blueShadow);
}
.text-shadow[class*="-purple"] {
text-shadow: var(--ShadowSize) var(--purpleShadow);
}
.text-shadow[class*="-mauve"] {
text-shadow: var(--ShadowSize) var(--mauveShadow);
}
.text-shadow[class*="-pink"] {
text-shadow: var(--ShadowSize) var(--pinkShadow);
}
.text-shadow[class*="-brown"] {
text-shadow: var(--ShadowSize) var(--brownShadow);
}
.text-shadow[class*="-grey"] {
text-shadow: var(--ShadowSize) var(--greyShadow);
}
.text-shadow[class*="-gray"] {
text-shadow: var(--ShadowSize) var(--grayShadow);
}
.text-shadow[class*="-black"] {
text-shadow: var(--ShadowSize) var(--blackShadow);
}
.bg-img {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.bg-mask {
background-color: var(--black);
position: relative;
}
.bg-mask::after {
content: "";
border-radius: inherit;
width: 100%;
height: 100%;
display: block;
background-color: rgba(0, 0, 0, 0.4);
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
}
.bg-mask div,
.bg-mask cover-div {
z-index: 5;
position: relative;
}
.bg-video {
position: relative;
}
.bg-video video {
display: block;
height: 100%;
width: 100%;
-o-object-fit: cover;
object-fit: cover;
position: absolute;
top: 0;
z-index: 0;
pointer-events: none;
}
/* ==================
文本
==================== */
.text-Abc {
text-transform: Capitalize;
}
.text-ABC {
text-transform: Uppercase;
}
.text-abc {
text-transform: Lowercase;
}
.text-price::before {
content: "¥";
font-size: 80%;
margin-right: 4px;
}
.text-cut {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.text-bold {
font-weight: bold;
}
.text-center {
text-align: center;
}
.text-content {
line-height: 1.6;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-red,
.line-red,
.lines-red {
color: var(--red);
}
.text-orange,
.line-orange,
.lines-orange {
color: var(--orange);
}
.text-yellow,
.line-yellow,
.lines-yellow {
color: var(--yellow);
}
.text-olive,
.line-olive,
.lines-olive {
color: var(--olive);
}
.text-green,
.line-green,
.lines-green {
color: var(--green);
}
.text-cyan,
.line-cyan,
.lines-cyan {
color: var(--cyan);
}
.text-blue,
.line-blue,
.lines-blue {
color: var(--blue);
}
.text-purple,
.line-purple,
.lines-purple {
color: var(--purple);
}
.text-mauve,
.line-mauve,
.lines-mauve {
color: var(--mauve);
}
.text-pink,
.line-pink,
.lines-pink {
color: var(--pink);
}
.text-brown,
.line-brown,
.lines-brown {
color: var(--brown);
}
.text-grey,
.line-grey,
.lines-grey {
color: var(--grey);
}
.text-gray,
.line-gray,
.lines-gray {
color: var(--gray);
}
.text-black,
.line-black,
.lines-black {
color: var(--black);
}
.text-white,
.line-white,
.lines-white {
color: var(--white);
}
.bdCon{
margin-top:8px;}
.anniu_btn{
width:100%;
padding:3.2px;
}
.anniu_btn button{
background:#0081ff;
height:6.4px;
border-radius:5px;
color:#fff;
width:50%;
margin:0 auto;
display:block;
font-size:1.92px;
max-width:200px;}
@media only screen and (min-width: 1400px) {
#header{
height:4.8px;
}
.header{
height:4.8px;
}
.headerIn .back{
font-size:1.28px;
}
.headerIn .save{
font-size:1.28px;
}
.cuIcon-back:before{
margin-right:3px;
font-size:1.6px;}
.headerIn h2{
font-size:1.6px;
line-height:4.8px;}
.bdCon{
margin-top:4.8px;}
.anniu_btn button{
height:4.16px;
font-size:1.28px;
max-width:400px;}
}
@media screen and (max-width: 641px) {
#header{
height:16px;
}
.header{
height:16px;
}
.headerIn .back{
font-size:4.8px;
}
.headerIn .save{
font-size:4.8px;
}
.cuIcon-back:before{
margin-right:3px;
font-size:4.8px;}
.headerIn h2{
font-size:5.12px;
line-height:16px;}
.bdCon{
margin-top:16px;}
.anniu_btn{
padding:3.2px 5%;}
.anniu_btn button{
height:16px;
font-size:4.8px;
max-width:100%;
width:100%;
}
}

BIN
QYJY/fonts/DIN-Bold.otf Normal file

Binary file not shown.

BIN
QYJY/fonts/DIN-Light.otf Normal file

Binary file not shown.

BIN
QYJY/fonts/DIN-Medium.otf Normal file

Binary file not shown.

BIN
QYJY/images/bg1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

BIN
QYJY/images/bg2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

BIN
QYJY/images/border_bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

497
QYJY/index.html Normal file
View File

@ -0,0 +1,497 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<script>
const cssVer = Date.now();
// 直接document.write输出带版本的link,写在head内,不会闪屏
document.write(`
<link rel="stylesheet" href="./css/icon.css">
<link rel="stylesheet" href="./css/index.css?v=${cssVer}">
<link rel="stylesheet" href="./css/public.css">
`);
</script>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1, user-scalable=no" />
<title>区域检验数据中心</title>
<!-- css/js增加版本号防缓存 -->
<!-- <link rel="stylesheet" href="./css/icon.css" />
<link rel="stylesheet" href="./css/index.css" />
<link rel="stylesheet" href="./css/public.css" /> -->
</head>
<body>
<div class="bg">
<div class="title">区域检验数据中心</div>
<div class="container">
<div class="leftMain">
<div class="leftMain_top">
<div class="leftMain_topIn">
<div class="title_nums">当月累计数据</div>
<ul id="sourceMonthWrap"></ul>
<div class="title_nums">当年累计数据</div>
<ul id="sourceYearWrap"></ul>
</div>
</div>
<div class="leftMain_middle">
<div class="leftMain_middle_left">
<div class="leftMain_middle_leftIn">
<h3>委托机构当月送检标本数量</h3>
<div class="biaoge">
<div id="chartmain" style="width:100%;height:100%;"></div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="leftMain_middle_leftIn leftMain_middle_leftIn_zhe">
<h3>当年送检标本数量趋势图</h3>
<div class="biaoge">
<div id="chartmain_zhe" style="width:100%;height:100%;"></div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
<div class="leftMain_middle_right">
<div class="leftMain_middle_rightIn">
<h3>当月标本全流程监控情况</h3>
<div class="biaoge biaoge_pai">
<div class="biaoge_paiIn">
<ul id="dayCountsWrap"></ul>
</div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<div class="rightMain">
<div class="rightMain_topIn">
<h3>委托机构当月送检标本占比</h3>
<div class="proportion">
<ul id="listDataWrap"></ul>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<script src="./js/echarts.min.js"></script>
<script>
// 全局变量
let echarts1Instance = null;
let echarts3Instance = null;
// 基础数据模板
const sourceMonth = [
{ name: '区域机构', num: 0, unit: '家', pre: 'jgs' },
{ name: '检验人数', num: 0, unit: '人', pre: 'rs' },
{ name: '检验管数', num: 0, unit: '个', pre: 'gs' },
{ name: '检验报告数', num: 0, unit: '份', pre: 'bgs' },
];
const sourceYear = [
{ name: '区域机构', num: 0, unit: '家', pre: 'jgs' },
{ name: '检验人数', num: 0, unit: '人', pre: 'rs' },
{ name: '检验管数', num: 0, unit: '个', pre: 'gs' },
{ name: '检验报告数', num: 0, unit: '份', pre: 'bgs' },
];
let dayCounts = [
{ dict_name: '检验申请', sl: 0, percent: '0%', flag: false },
{ dict_name: '标本采集', sl: 0, percent: '0%', remain: 0, remainPer: '0%', flag: true },
{ dict_name: '标本送检', sl: 0, percent: '0%', remain: 0, remainPer: '0%', flag: true },
{ dict_name: '标本签收', sl: 0, percent: '0%', remain: 0, remainPer: '0%', flag: true },
{ dict_name: '上机检测', sl: 0, percent: '0%', remain: 0, remainPer: '0%', flag: true },
{ dict_name: '结果审核', sl: 0, percent: '0%', remain: 0, remainPer: '0%', flag: true },
{ dict_name: '申请作废', sl: 0, percent: '0%', flag: false },
{ dict_name: '标本退回', sl: 0, percent: '0%', flag: false },
];
let listData = [];
// 折线图轮播变量
let lineTipTimer = null;
let lineCurrentIndex = -1;
const LINE_TIP_INTERVAL = 2500;
function startLineTipLoop() {
if (lineTipTimer) clearInterval(lineTipTimer);
lineCurrentIndex = -1;
lineTipTimer = setInterval(() => {
if (!echarts3Instance) return;
const opt = echarts3Instance.getOption();
const dataLen = opt.xAxis[0].data.length;
if (dataLen === 0) return;
lineCurrentIndex = (lineCurrentIndex + 1) % dataLen;
opt.series.forEach((_, idx) => echarts3Instance.dispatchAction({ type: 'downplay', seriesIndex: idx }));
opt.series.forEach((_, idx) => echarts3Instance.dispatchAction({ type: 'highlight', seriesIndex: idx, dataIndex: lineCurrentIndex }));
echarts3Instance.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: lineCurrentIndex });
}, LINE_TIP_INTERVAL);
}
function stopLineTipLoop() {
if (lineTipTimer) clearInterval(lineTipTimer);
lineTipTimer = null;
}
// 渲染列表函数
function renderNumList(containerId, arr) {
const wrap = document.getElementById(containerId);
wrap.innerHTML = '';
arr.forEach(item => {
const li = document.createElement('li');
li.innerHTML = `
<div class="liIn">
<div class="nums_box">
<h3>${item.name}</h3>
<p class="shu"><span class="shu1">${item.num}</span><i>${item.unit}</i></p>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
`;
wrap.appendChild(li);
})
}
function renderDayCounts() {
const wrap = document.getElementById('dayCountsWrap');
wrap.innerHTML = '';
dayCounts.forEach(item => {
const li = document.createElement('li');
li.innerHTML = `
<div class="liIn">
<div class="liIn_left"><span class="zi">${item.dict_name}</span></div>
<div class="liIn_line">
<div class="line_lineIn" style="width:${item.percent}">
<div class="per">${item.percent}</div>
</div>
</div>
<p class="num">${item.sl}</p>
<div class="clear"></div>
</div>
<div class="liIn" style="display:${item.flag ? 'flex' : 'none'}">
<div class="liIn_left"><span class="zi">&nbsp;</span></div>
<div class="liIn_line">
<div class="line_lineIn_sy" style="width:${item.remainPer}">
<div class="per">剩余${item.remain}</div>
</div>
</div>
<p class="num">&nbsp;</p>
<div class="clear"></div>
</div>
`;
wrap.appendChild(li);
})
}
function renderListData() {
const wrap = document.getElementById('listDataWrap');
wrap.innerHTML = '';
listData.forEach(item => {
const li = document.createElement('li');
li.innerHTML = `
<div class="liIn">
<div class="liIn_left"><span class="zi" title="${item.groupname}">${item.groupname}</span></div>
<div class="liIn_line">
<div class="line_lineIn" style="width:${item.percentage}">
<div class="per">${item.percentage}</div>
</div>
</div>
<p class="num">${item.groupsum}</p>
<div class="clear"></div>
</div>
`;
wrap.appendChild(li);
})
}
// ========= 只初始化一次柱状图,不再每次刷新销毁重建 =========
function initBarChart() {
const dom = document.getElementById('chartmain');
echarts1Instance = echarts.init(dom, null, { devicePixelRatio: window.devicePixelRatio });
const option = {
title: { text: '' },
grid: { x: 30, y: 30, x2: 10, y2: 20 },
tooltip: {
trigger: 'axis',
show: false,
backgroundColor: 'rgba(0,18,36,0.9)',
textStyle: { color: '#fff', fontSize: 14 },
padding: [12, 16],
borderWidth: 1,
borderColor: '#0efdff'
},
label: {
show: true,
color: '#fff',
fontSize: 16,
fontWeight: 700,
position: 'top',
//没有数据 0的情况不显示
formatter: function (params) {
if (params.value == 0) {
return '';
}
return params.value;
}
},
xAxis: {
data: [],
axisLabel: { interval: 0, color: '#fff', fontSize: 12 },
axisTick: { show: false },
axisLine: { show: true, symbol: ['none', 'arrow'], symbolOffset: 12, lineStyle: { color: '#fff' } },
z: 10
},
yAxis: {
type: 'value', name: '单位:个', minInterval: 1,
axisLine: { show: true, symbol: ['none', 'arrow'], symbolOffset: 12, lineStyle: { color: '#fff' } },
axisTick: { show: false },
axisLabel: { color: '#fff', fontSize: 12 }
},
series: [{
type: 'bar',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1,
[{ offset: 0, color: '#0efdff' }, { offset: 0.5, color: '#188df0' }, { offset: 1, color: '#188df0' }]
)
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1,
[{ offset: 0, color: '#2378f7' }, { offset: 0.7, color: '#2378f7' }, { offset: 1, color: '#0efdff' }]
)
}
},
data: []
}]
};
echarts1Instance.setOption(option);
}
// 仅更新柱状图数据,不销毁实例
function updateBarData(data) {
const dataAxis = data.map(item => item.daynum);
const dataVal = data.map(item => item.sl);
echarts1Instance.setOption({ xAxis: { data: dataAxis }, series: [{ data: dataVal }] });
}
// 基准:1920宽度下字号12px,最小字号8px防止过小
function calcLegendFont(container, baseFont = 12, baseWidth = 1920, minFont = 8) {
const width = container.clientWidth;
const scale = width / baseWidth;
return Math.max(minFont, Math.round(baseFont * scale));
}
// ========= 只初始化一次折线图,不再每次刷新销毁重建 =========
function initLineChart() {
const dom = document.getElementById('chartmain_zhe');
echarts3Instance = echarts.init(dom, null, { devicePixelRatio: window.devicePixelRatio });
const colors = ['#ff7f50', '#87cefa', '#da70d6', '#32cd32', '#6495ed', '#ff69b0', '#ba55d3', '#cd5c5c', '#ffa500', '#40e0d0', '#1e90ff', '#ff6347', '#7b68ee', '#d0648a', '#ffd700', '#6b8e23', '#4ea397', '#3cb371', '#b8860b'];
const legendFont = calcLegendFont(dom, 35, 1920);
// 图例方块也同步缩放,1920下itemWidth/itemHeight=15
const itemSize = calcLegendFont(dom, 35, 1920);
const option = {
title: { text: '' },
tooltip: {
trigger: 'axis',
confine: false, // 限制在图表内
backgroundColor: 'rgba(0,18,36,0.9)',
textStyle: { color: '#fff', fontSize: 14 },
padding: [12, 16],
borderWidth: 1,
borderColor: '#0efdff',
},
legend: {
// type: 'scroll', textStyle: { color: '#fff', fontSize: 12, lineHeight: 15, },
// // icon: 'circle',
// pageIcon: 'circle', pageIconColor: '#0efdff', pageIconSize: 12,
// pageIconInactiveColor: '#666', pageTextStyle: { color: '#0efdff' },
type: 'plain',
orient: 'horizontal', // ✅必须开启水平排列,超出width自动换行
left: 10,
right: 10,
top: 0,
width: 'auto', // 或者写固定像素,例如 width:450;left+right限制可用宽度
itemGap: 2, // 图例项水平间距
itemWidth: itemSize,
itemHeight: itemSize,
textStyle: { color: '#fff', fontSize: legendFont, fontWeight: 700 },
data: []
},
grid: { x: 30, y: 80, x2: 20, y2: 20 },
xAxis: {
type: 'category', boundaryGap: false, data: [],
axisLabel: { interval: 0, color: '#fff', fontSize: 12 },
axisTick: { show: false },
axisLine: { show: true, symbol: ['none', 'arrow'], symbolOffset: 12, lineStyle: { color: '#fff' } }
},
yAxis: {
type: 'value', name: '单位:个', minInterval: 1,
axisLine: { show: true, symbol: ['none', 'arrow'], symbolOffset: 12, lineStyle: { color: '#fff' } },
axisTick: { show: false },
axisLabel: { color: '#fff', fontSize: 12 }
},
series: []
}
echarts3Instance.setOption(option);
// dom.addEventListener('mouseenter', stopLineTipLoop);
// dom.addEventListener('mouseleave', startLineTipLoop);
// startLineTipLoop();
}
// 仅更新折线数据,不销毁实例
function updateLineData(list) {
const xData = list[0].dayline.map(item => item.month + '月');
const legendData = list.map(item => item.groupname);
const colors = ['#D62728', '#FF7F0E', '#FFBB78', '#2CA02C', '#17BECF', '#1F77B4', '#9467BD', '#8C564B', '#E377C2', '#BCBD22', '#393B79', '#637939',
'#8C6D31', '#843C39', '#5254A3', '#BD9E39', '#3182BD', '#E6550D', '#7F7F7F'];
const series = list.map((item, i) => ({
name: item.groupname,
type: 'line',
symbol: 'circle',
symbolSize: 7,
// 无数据转为 null,线条自动断开
data: item.dayline.map(v => {
if (!v.sl || v.sl <= 0) {
return null
}
return v.sl
}),
connectNulls: false, // 遇到null不连线
itemStyle: { color: colors[i] },
lineStyle: { color: colors[i], width: 2 }
}))
echarts3Instance.setOption({
xAxis: { data: xData },
legend: { data: legendData },
series: series
})
}
// 窗口自适应
function handleResize() {
if (echarts1Instance) echarts1Instance.resize();
if (echarts3Instance) echarts3Instance.resize();
}
// 原生Ajax请求封装
function httpGet(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function () {
if (xhr.status === 200) {
const res = JSON.parse(xhr.responseText);
callback(res);
}
}
xhr.onerror = function () {
console.log('接口请求失败:' + url);
}
xhr.send();
}
// 初始化数据
function init() {
renderNumList('sourceMonthWrap', sourceMonth);
renderNumList('sourceYearWrap', sourceYear);
// 一次性初始化两张图表,后续只更新数据
initBarChart();
initLineChart();
getDataInfo();
}
// 获取全部统计数据(30秒只更新数据,不重建图表)
//http://47.97.125.165:8905
function getDataInfo() {
const apiUrl = '/api/transitstat/getallcount';
httpGet(apiUrl, function (res) {
const data = res.data;
// 赋值当月/当年数字
sourceMonth.forEach(item => item.num = data.regStatAllMonth[item.pre]);
sourceYear.forEach(item => item.num = data.regStatAllYear[item.pre]);
listData = data.regStatHospMonth;
// 匹配流程数量&百分比
const baseNum = data.regStatStatusTotal['检验申请'] || 0
dayCounts.forEach(item => {
item.sl = res.data.regStatStatusTotal[item.dict_name] || 0
item.percent = (item.sl / baseNum * 100).toFixed(2) + '%'
if (item.percent.endsWith('.00%')) {
item.percent = item.percent.replace('.00%', '%')
}
})
const flowOrder = dayCounts.map(item => item.dict_name).filter(name => name !== '申请作废' && name !== '标本退回');
//初始化全部remain=0
dayCounts.forEach(d => d.remain = 0);
for (let i = 1; i < flowOrder.length; i++) {
const prevName = flowOrder[i - 1];
const currName = flowOrder[i];
const prevItem = dayCounts.find(x => x.dict_name === prevName);
const currItem = dayCounts.find(x => x.dict_name === currName);
if (prevItem && currItem) {
currItem.remain = prevItem.sl - currItem.sl;
if (currItem.remain < 0) currItem.remain = 0;
if (prevItem.sl > 0) {
currItem.remainPer = (currItem.remain / prevItem.sl * 100).toFixed(2) + '%';
} else {
currItem.remainPer = "0%";
}
}
}
// console.log('dayCounts==>', dayCounts);
// 刷新文字列表
renderNumList('sourceMonthWrap', sourceMonth);
renderNumList('sourceYearWrap', sourceYear);
renderDayCounts();
renderListData();
// 增量更新图表,不销毁画布(解决刷新卡顿)
updateBarData(data.regStatMonth);
updateLineData(data.regStatHospYear);
})
}
// setTimeout(function () {
// window.location.href = "index2.html";
// }, 60000);
let dataRefreshTimer = null;
// 页面初始化
window.onload = function () {
// 窗口/全屏监听
window.addEventListener('resize', handleResize);
document.addEventListener('fullscreenchange', handleResize);
document.addEventListener('webkitfullscreenchange', handleResize);
// 首次拉取数据
init();
// 定时刷新数据
dataRefreshTimer = setInterval(getDataInfo, 60000);
}
// 页面销毁释放资源
window.onbeforeunload = function () {
if (dataRefreshTimer) {
clearInterval(dataRefreshTimer);
dataRefreshTimer = null;
}
window.removeEventListener('resize', handleResize);
document.removeEventListener('fullscreenchange', handleResize);
document.removeEventListener('webkitfullscreenchange');
if (echarts1Instance) echarts1Instance.dispose();
if (echarts3Instance) echarts3Instance.dispose();
}
</script>
</body>
</html>

305
QYJY/index2.html Normal file
View File

@ -0,0 +1,305 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<!-- 禁用缓存meta -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1, user-scalable=no" />
<title>区域检验数据中心</title>
<link rel="stylesheet" href="./css/icon.css?v=1.0" />
<link rel="stylesheet" href="./css/index.css?v=1.0" />
<link rel="stylesheet" href="./css/index2.css?v=1.0" />
<link rel="stylesheet" href="./css/public.css?v=1.0" />
</head>
<body>
<div class="bg">
<div class="title">区域检验数据中心</div>
<div class="container">
<div class="leftMain">
<div class="leftMain_middle">
<!-- 左侧上半:项目类别 -->
<div class="leftMain_middle_leftIn">
<h3>当月项目类别数量</h3>
<div class="left_mideele_top">
<ul id="xmMonthWrap"></ul>
</div>
<div class="biaoge">
<div id="chartProject" style="height: 100%;"></div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<!-- 左侧下半:标本类别 -->
<div class="leftMain_middle_leftIn leftMain_middle_leftIn_zhe">
<h3>当月标本类别数量</h3>
<div class="left_mideele_top">
<ul id="bbMonthWrap"></ul>
</div>
<div class="biaoge">
<div id="chartSample" style="height: 100%;"></div>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
<!-- 右侧:委托机构项目占比 -->
<div class="rightMain">
<div class="rightMain_topIn">
<h3>委托机构当月项目占比</h3>
<div class="proportion">
<ul id="listDataWrap"></ul>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<script src="./js/echarts.min.js?v=1.0"></script>
<script>
// ECharts实例
let chartProjectIns = null;
let chartSampleIns = null;
const proData = [
{ name: '生化项目', num: 120 },
{ name: '免疫项目', num: 80 },
{ name: '临检', num: 60 },
{ name: '微生物', num: 40 },
{ name: '分子生物学', num: 40 },
{ name: '细胞学', num: 40 },
]
const bbData = [
{ name: '血清', num: 120 },
{ name: '全血', num: 83 },
{ name: '尿液', num: 120 },
{ name: '粪便', num: 64 },
]
// 项目类别 模拟数据
const mockProjectData = {
xAxis: ['1日', '2日', '3日', '4日', '5日', '6日', '7日', '8日', '9日', '10日', '11日', '12日', '13日', '14日', '15日', '16日', '17日', '18日', '19日', '20日', '21日', '22日', '23日', '24日', '25日', '26日', '27日', '28日', '29日', '30日', '31日'],
series: [
{ name: '生化项目', data: [120, 132, 101, 134, 90, 230, 210, 28, 872, 120, 132, 101, 134, 90, 230, 210] },
{ name: '免疫项目', data: [80, 92, 91, 114, 60, 120, 130, 282, 120, 132, 101, 134, 90, 230, 210] },
{ name: '临检', data: [60, 72, 81, 94, 85, 110, 95, 287, 120, 132, 101, 134, 90, 230, 210] },
{ name: '微生物', data: [40, 42, 51, 54, 45, 60, 55, 211, 120, 132, 101, 134, 90, 230, 210] },
{ name: '分子生物学', data: [40, 42, 51, 54, 45, 60, 55, 221, 120, 132, 101, 134, 90, 230, 210] },
{ name: '细胞学', data: [40, 42, 51, 54, 45, 60, 55, 221, 120, 132, 101, 134, 90, 230, 210] },
]
};
// 标本类别 模拟数据(数值、分类完全不同)
const mockSampleData = {
xAxis: ['1日', '2日', '3日', '4日', '5日', '6日', '7日', '8日', '9日', '10日', '11日', '12日', '13日', '14日', '15日', '16日', '17日', '18日', '19日', '20日', '21日', '22日', '23日', '24日', '25日', '26日', '27日', '28日', '29日', '30日', '31日'],
series: [
{ name: '血清', data: [320, 482, 391, 434, 390, 530, 410, 120, 130, 167, 98, 149, 208, 304, 408, 678, 359] },
{ name: '全血', data: [250, 332, 301, 254, 290, 430, 510, 120, 245, 156, 98, 149, 208, 604, 408, 778, 559] },
{ name: '尿液', data: [180, 232, 151, 234, 250, 320, 280, 120, 653, 245, 98, 149, 208, 304, 408, 558] },
{ name: '粪便', data: [60, 90, 70, 85, 98, 110, 95, 120, 130, 189, 245, 149, 208, 408, 558] }
]
};
// 3. 右侧项目占比列表
const mockListData = [
{ groupname: '肝功能', groupsum: 560, percentage: '38%' },
{ groupname: '肾功能', groupsum: 980, percentage: '29%' },
{ groupname: '性激素', groupsum: 620, percentage: '18%' },
{ groupname: '肿瘤标志物', groupsum: 500, percentage: '15%' },
];
// 图表配色数组
const colorArr = ['#0efdff', '#ff7f50', '#32cd32', '#6495ed', '#ff69b4', '#ffa500', '#ffd700', '#da70d6', '#c71585', '#00ffff', '#00ff7f', '#00ff00', '#7fff00', '#7fffd4', '#00ffff', '#00bfff', '#4169e1',];
// 渲染类别数量函数
function renderNumList(containerId, arr) {
const wrap = document.getElementById(containerId);
wrap.innerHTML = '';
arr.forEach(item => {
const li = document.createElement('li');
li.innerHTML = `
<div class="liIn">
<h3>${item.name}</h3>
<p class="shu"><span class="shu1">${item.num}</span></p>
</div>
`;
wrap.appendChild(li);
})
}
// 渲染右侧机构占比列表
function renderList() {
const wrap = document.getElementById('listDataWrap');
wrap.innerHTML = '';
mockListData.forEach(item => {
const li = document.createElement('li');
li.innerHTML = `
<div class="liIn">
<div class="liIn_left"><span class="zi" title="${item.groupname}">${item.groupname}</span></div>
<div class="liIn_line">
<div class="line_lineIn" style="width:${item.percentage}">
<div class="per">${item.percentage}</div>
</div>
</div>
<p class="num">${item.groupsum}</p>
<div class="clear"></div>
</div>
`;
wrap.appendChild(li);
})
}
// 折线图轮播变量
let lineTipTimer = null;
let lineCurrentIndex = -1;
const LINE_TIP_INTERVAL = 2500;
function startLineTipLoop() {
if (lineTipTimer) clearInterval(lineTipTimer);
lineCurrentIndex = -1;
lineTipTimer = setInterval(() => {
if (!chartProjectIns) return;
const opt = chartProjectIns.getOption();
const dataLen = opt.xAxis[0].data.length;
if (dataLen === 0) return;
lineCurrentIndex = (lineCurrentIndex + 1) % dataLen;
opt.series.forEach((_, idx) => chartProjectIns.dispatchAction({ type: 'downplay', seriesIndex: idx }));
opt.series.forEach((_, idx) => chartProjectIns.dispatchAction({ type: 'highlight', seriesIndex: idx, dataIndex: lineCurrentIndex }));
chartProjectIns.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: lineCurrentIndex });
}, LINE_TIP_INTERVAL);
}
function stopLineTipLoop() {
if (lineTipTimer) clearInterval(lineTipTimer);
lineTipTimer = null;
}
// ========== 初始化:项目类别折线 ==========
function initProjectChart() {
const dom = document.getElementById('chartProject');
chartProjectIns = echarts.init(dom);
const seriesArr = mockProjectData.series.map((item, idx) => ({
name: item.name,
type: 'line',
data: item.data,
lineStyle: { width: 2 },
itemStyle: { color: colorArr[idx % colorArr.length] }
}))
const opt = {
tooltip: {
trigger: 'axis',
confine: true, // 限制在图表内
backgroundColor: 'rgba(0,18,36,0.9)',
borderColor: '#0efdff',
padding: [12, 16],
textStyle: { color: '#fff', fontSize: 14 },
},
legend: { type: 'scroll', textStyle: { color: '#fff', fontSize: 12 }, pageIconColor: '#0efdff', data: mockProjectData.series.map(s => s.name) },
grid: { x: 40, y: 50, x2: 10, y2: 20 },
xAxis: {
type: 'category', data: mockProjectData.xAxis,
axisLine: { show: true, symbol: ['none', 'arrow'], lineStyle: { color: '#fff' } },
axisLabel: { interval: 0, color: '#fff', fontSize: 12 },
axisTick: { show: false }
},
yAxis: {
name: '数量(个)',
nameTextStyle: { color: '#fff' },
axisLine: { show: true, symbol: ['none', 'arrow'], lineStyle: { color: '#fff' } },
axisLabel: { color: '#fff' },
minInterval: 1
},
series: seriesArr
}
chartProjectIns.setOption(opt);
dom.addEventListener('mouseenter', stopLineTipLoop);
dom.addEventListener('mouseleave', startLineTipLoop);
startLineTipLoop();
}
// ========== 初始化:标本类别折线 ==========
function initSampleChart() {
const dom = document.getElementById('chartSample');
chartSampleIns = echarts.init(dom);
const seriesArr = mockSampleData.series.map((item, idx) => ({
name: item.name,
type: 'line',
data: item.data,
lineStyle: { width: 2 },
itemStyle: { color: colorArr[idx % colorArr.length] }
}))
const opt = {
tooltip: {
trigger: 'axis',
confine: true, // 限制在图表内
backgroundColor: 'rgba(0,18,36,0.9)',
borderColor: '#0efdff',
padding: [12, 16],
textStyle: { color: '#fff', fontSize: 14 }
},
legend: { type: 'scroll', textStyle: { color: '#fff', fontSize: 12 }, pageIconColor: '#0efdff', data: mockSampleData.series.map(s => s.name) },
grid: { x: 40, y: 50, x2: 10, y2: 20 },
xAxis: {
type: 'category',
data: mockSampleData.xAxis,
axisLine: { show: true, symbol: ['none', 'arrow'], lineStyle: { color: '#fff' } },
axisLabel: { interval: 0, color: '#fff', fontSize: 12 },
axisTick: { show: false }
},
yAxis: {
name: '数量(份)',
nameTextStyle: { color: '#fff' },
axisLine: { show: true, symbol: ['none', 'arrow'], lineStyle: { color: '#fff' } },
axisLabel: { color: '#fff' },
minInterval: 1
},
series: seriesArr
}
chartSampleIns.setOption(opt);
}
// 窗口自适应
function resizeAll() {
if (chartProjectIns) chartProjectIns.resize();
if (chartSampleIns) chartSampleIns.resize();
}
// setTimeout(function () {
// window.location.href = "index.html";
// }, 60000);
// 页面加载入口
window.onload = function () {
renderNumList('xmMonthWrap', proData);
renderNumList('bbMonthWrap', bbData);
// 渲染右侧机构占比列表
renderList();
initProjectChart();
initSampleChart();
window.addEventListener('resize', resizeAll);
document.addEventListener('fullscreenchange', resizeAll);
document.addEventListener('webkitfullscreenchange', resizeAll);
}
// 页面卸载释放资源
window.onbeforeunload = function () {
window.removeEventListener('resize', resizeAll);
document.removeEventListener('fullscreenchange');
document.removeEventListener('webkitfullscreenchange');
if (chartProjectIns) chartProjectIns.dispose();
if (chartSampleIns) chartSampleIns.dispose();
}
</script>
</body>
</html>

45
QYJY/js/echarts.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
TAT/css/element-plus.css Normal file

File diff suppressed because one or more lines are too long

232
TAT/css/index.css Normal file
View File

@ -0,0 +1,232 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.screen-container {
width: 100%;
height: 100vh;
background: url(../images/bg2.jpg);
background-size: 100% 100%;
padding: 10px 20px 5px 30px;
}
.screen-header {
position: relative;
width: 100%;
height: 60px;
}
.screen-title {
font-size: 1.875rem;
color: rgba(14, 253, 255, 1);
text-align: center;
font-weight: bold;
text-align: center;
line-height: 50px;
}
.screen-time {
position: absolute;
right: 80px;
font-size: 20px;
color: #0ef;
font-weight: 700;
top: 10px;
}
.border_bg_leftTop {
position: absolute;
left: -0.125rem;
top: -0.625rem;
width: 5.78125rem;
height: 0.78125rem;
display: block;
background: #01279d url(../images/title_left_bg.png) no-repeat;
background-size: cover;
}
.border_bg_rightTop {
position: absolute;
right: -0.15625rem;
top: -0.15625rem;
width: 1.5625rem;
height: 1.5625rem;
display: block;
background: url(../images/border_bg.jpg) no-repeat;
background-size: cover;
}
.border_bg_leftBottom {
position: absolute;
left: -0.125rem;
bottom: -0.125rem;
width: 1.5625rem;
height: 1.5625rem;
display: block;
background: url(../images/border_bg.jpg) no-repeat;
background-size: cover;
}
.border_bg_rightBottom {
position: absolute;
right: -0.15625rem;
bottom: -0.15625rem;
width: 1.25rem;
height: 1.25rem;
display: block;
background: url(../images/title_right_bg.png) no-repeat;
background-size: cover;
}
.div__body {
padding: 12px;
}
.grid-wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
/* 上下两行高度均分 */
gap: 10px;
flex: 1;
min-height: 0;
height: calc(100% - 80px);
}
.card {
border: 1px solid #0efdff;
padding: 5px;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
}
.card-header {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
border-bottom: 1px solid #0099ff;
color: #fff;
font-size: 20px;
font-weight: bold;
}
.red-text {
color: #ff4444;
font-weight: bold;
}
.table-box {
flex: 1;
min-height: 0;
}
table {
width: 100%;
/* height: 100%; */
border-collapse: collapse !important;
border: 1px solid #0099ff;
}
th {
background: rgba(30, 104, 195, 1);
color: #ffffff;
font-size: 16px;
font-weight: bold;
border: 1px solid #0099ff;
padding: 3px;
text-align: left;
height: 30px;
}
td {
background: transparent;
color: #ffffff;
font-size: 15px;
border: 1px solid #0099ff;
padding: 3px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 180px;
height: 30px;
}
/* 隔行变色 */
tbody tr:nth-child(even) td {
background: rgba(0, 153, 255, 0.1);
min-height: 30px;
}
/* 文字溢出悬浮完整提示 */
td {
position: relative;
}
td:hover::after {
content: attr(data-tip);
position: absolute;
left: 0;
top: 100%;
background: rgba(0, 18, 36, 0.95);
border: 1px solid #0efdff;
padding: 6px 10px;
z-index: 10;
white-space: normal;
max-width: 400px;
border-radius: 4px;
}
.timeout {
color: #00ff00;
font-weight: bold;
font-size: 16px;
}
.tips {
margin-top: 8px;
font-size: 12px;
color: #ff4d4f;
}
/* 右上角关闭叉号按钮 透明悬浮 */
.close-btn-box {
position: fixed;
right: 30px;
top: 20px;
z-index: 9999;
}
.close-icon-btn {
width: 44px;
height: 44px;
line-height: 44px;
text-align: center;
background: transparent;
border: 1px solid rgba(255, 255, 255, 0.25);
color: #fff;
border-radius: 50%;
cursor: pointer;
font-size: 24px;
font-weight: bold;
user-select: none;
}
.close-icon-btn:hover {
background: rgba(255, 0, 0, 0.35);
border-color: rgba(255, 255, 255, 0.5);
}

BIN
TAT/images/bg2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

BIN
TAT/images/border_bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

326
TAT/index copy.html Normal file
View File

@ -0,0 +1,326 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAT监控大屏</title>
<script src="./js/vue.global.prod.js"></script>
<link rel="stylesheet" href="./css/element-plus.css">
<script src="./js/element-plus.js"></script>
<script src="./js/axios.min.js"></script>
<script src="./js/dayjs.min.js"></script>
<link rel="stylesheet" href="./css/index.css">
<style>
/* 右上角关闭叉号按钮 透明悬浮 */
.close-btn-box {
position: fixed;
right: 20px;
top: 30px;
/* z-index: 9999; */
}
.close-icon-btn {
width: 44px;
height: 44px;
line-height: 44px;
text-align: center;
background: transparent;
border: 1px solid rgba(255, 255, 255, 0.25);
color: #fff;
border-radius: 50%;
cursor: pointer;
font-size: 24px;
font-weight: bold;
user-select: none;
}
.close-icon-btn:hover {
background: rgba(255, 0, 0, 0.35);
border-color: rgba(255, 255, 255, 0.5);
}
</style>
</head>
<body>
<div id="app">
<div class="screen-container">
<div class="screen-header">
<div class="screen-title">TAT超时提醒大屏</div>
<div class="screen-time">{{ nowTime }}</div>
</div>
<div class="grid-wrapper">
<div class="card">
<div class="card-header">
<span>已采集待收标本超时</span>
<span class="red-text">共 {{list1.length}}个标本</span>
</div>
<div class="table-box">
<el-table :data="pageList1" border stripe class="table" height="38vh" :header-cell-style="tableHeaderStyle"
:cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室" show-overflow-tooltip></el-table-column>
<el-table-column label="姓名/条码" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="cysj" label="采样时间" width="200" show-overflow-tooltip></el-table-column>
<el-table-column label="等待时间" width="120" show-overflow-tooltip>
<template #default="{ row }">
<span class="red-text">{{ row.holdtime || 0 }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="card">
<div class="card-header">
<span>已核收未上机超时</span>
<span class="red-text">共 {{list2.length}}个标本</span>
</div>
<div class="table-box">
<el-table :data="pageList2" border stripe class="table" height="38vh" :header-cell-style="tableHeaderStyle"
:cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室" show-overflow-tooltip></el-table-column>
<el-table-column label="姓名/条码" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="jssj" label="签收时间" width="200" show-overflow-tooltip></el-table-column>
<el-table-column label="等待时间" width="120" show-overflow-tooltip>
<template #default="{ row }">
<span class="red-text">{{ row.holdtime || 0 }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="card">
<div class="card-header">
<span>标本报告未完成超时</span>
<span class="red-text">共 {{list3.length}}个标本</span>
</div>
<div class="table-box">
<el-table :data="pageList3" border stripe class="table" height="38vh" :header-cell-style="tableHeaderStyle"
:cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器" show-overflow-tooltip></el-table-column>
<el-table-column label="样本号/条码号" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.ybh }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="sjsj" label="上机时间" width="200" show-overflow-tooltip></el-table-column>
<el-table-column label="等待时间" width="120" show-overflow-tooltip>
<template #default="{ row }">
<span class="red-text">{{ row.holdtime || 0 }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="card">
<div class="card-header">危急值未处理超时</div>
<div class="table-box">
<el-table :data="pageList4" border stripe class="table" height="38vh" :header-cell-style="tableHeaderStyle"
:cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器" show-overflow-tooltip></el-table-column>
<el-table-column prop="ybh" label="样本号" show-overflow-tooltip></el-table-column>
<el-table-column prop="xmmc" label="项目" show-overflow-tooltip></el-table-column>
<el-table-column prop="csjg" label="结果" show-overflow-tooltip></el-table-column>
<el-table-column label="等待时间" width="120" show-overflow-tooltip>
<template #default="{ row }">
<span class="red-text">{{ row.holdtime || 0 }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
<!-- 右上角 叉号关闭按钮 无文字 -->
<div class="close-btn-box">
<div class="close-icon-btn" @click="closeCurrentPage">×</div>
</div>
</div>
<script>
const { createApp, ref, onMounted, onUnmounted } = Vue;
const app = createApp({
setup() {
const request = axios.create({ baseURL: '' });
// ==================== 从地址栏获取 rows 参数 ====================
function getPageSizeFromUrl() {
const params = new URLSearchParams(window.location.search);
const rows = parseInt(params.get('rows'));
return !isNaN(rows) && rows > 0 ? rows : 13; // 默认13行
}
// ==================== 配置 ====================
const PAGE_SIZE = getPageSizeFromUrl(); // 从地址栏获取,默认13
const PAGE_DELAY = 5000; // 翻页间隔
const NO_PAGE_DELAY = 5000; // 不足一页刷新间隔
// ===============================================
// 原始数据
const list1 = ref([]);
const list2 = ref([]);
const list3 = ref([]);
const list4 = ref([]);
// 分页展示数据
const pageList1 = ref([]);
const pageList2 = ref([]);
const pageList3 = ref([]);
const pageList4 = ref([]);
// 样式
const tableHeaderStyle = {
background: 'rgba(30, 104, 195, 1)',
color: '#ffffff', fontSize: '16px', fontWeight: 'bold',
borderColor: '#0099ff', padding: '4px 0px'
};
const tableCellStyle = {
background: 'transparent', color: '#ffffff', fontSize: '15px',
borderColor: '#0099ff', padding: '2px 0px'
};
const tableRowStyle = ({ rowIndex }) => ({
background: rowIndex % 2 === 0 ? 'transparent' : 'rgba(0, 153, 255, 0.1)'
});
// 时间
const nowTime = ref('');
const updateTime = () => {
nowTime.value = dayjs().format('YYYY年MM月DD日 HH:mm:ss');
};
// 关闭当前网页
const closeCurrentPage = () => {
window.close();
};
// 安全清除定时器
const safeClear = (timer) => timer && clearTimeout(timer);
// 核心:分页轮播 + 最后一页刷新
function startCarousel(list, pageList, onFinish) {
let currentPage = 0;
let timer = null;
function run() {
safeClear(timer);
const total = list.value.length;
if (total === 0) {
pageList.value = [];
timer = setTimeout(run, NO_PAGE_DELAY);
return;
}
// 不足一页:不翻页,定时刷新
if (total <= PAGE_SIZE) {
pageList.value = list.value;
timer = setTimeout(run, NO_PAGE_DELAY);
return;
}
// 计算分页
const start = currentPage * PAGE_SIZE;
const end = start + PAGE_SIZE;
pageList.value = list.value.slice(start, end);
const isLastPage = end >= total;
// 最后一页:停留后刷新数据
if (isLastPage) {
timer = setTimeout(() => {
currentPage = 0;
onFinish(); // 刷新
}, PAGE_DELAY);
} else {
// 下一页
timer = setTimeout(() => {
currentPage++;
run();
}, PAGE_DELAY);
}
}
run();
return () => safeClear(timer);
}
// 加载数据 + 启动轮播
function createLoader(url, list, pageList) {
let stopCarousel = null;
async function load() {
try {
if (stopCarousel) stopCarousel();
const { data: res } = await request.get(url);
list.value = res.data || [];
stopCarousel = startCarousel(list, pageList, load);
} catch (e) {
console.log("加载失败", url);
setTimeout(load, NO_PAGE_DELAY);
}
}
load();
return () => stopCarousel && stopCarousel();
}
// 启动所有表格
let stop1, stop2, stop3, stop4;
onMounted(() => {
updateTime();
setInterval(updateTime, 1000);
stop1 = createLoader('/api/list1', list1, pageList1);
stop2 = createLoader('/api/list2', list2, pageList2);
stop3 = createLoader('/api/list3', list3, pageList3);
stop4 = createLoader('/api/list4', list4, pageList4);
});
onUnmounted(() => {
stop1?.();
stop2?.();
stop3?.();
stop4?.();
});
return {
list1, list2, list3, list4,
pageList1, pageList2, pageList3, pageList4,
nowTime, tableHeaderStyle, tableCellStyle, tableRowStyle,
closeCurrentPage
};
}
});
app.use(ElementPlus).mount('#app');
</script>
</body>
</html>

388
TAT/index-1.html Normal file
View File

@ -0,0 +1,388 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAT监控大屏</title>
<script src="./js/vue.global.prod.js"></script>
<link rel="stylesheet" href="./css/element-plus.css">
<script src="./js/element-plus.js"></script>
<script src="./js/axios.min.js"></script>
<script src="./js/dayjs.min.js"></script>
<!-- 自定义样式 -->
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="app">
<div class="screen-container">
<!-- 顶部标题 + 右侧动态时间 -->
<div class="screen-header">
<div class="screen-title">TAT监控大屏</div>
<div class="screen-time">{{ nowTime }}</div>
</div>
<div class="grid-wrapper">
<div class="card">
<div class="card-header">
<span>已采集待收标本</span>
<span class="red-text">
共 {{list1.length}}个标本
</span>
</div>
<div class="table-box">
<el-table :data="list1" border stripe class="table" height="35vh" ref="table1Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室"></el-table-column>
<el-table-column label="姓名/条码">
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="cysj" label="采样时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header">
<span>已核收还未上机标本</span>
<span class="red-text">
共 {{list2.length}}个标本
</span>
</div>
<div class="table-box">
<el-table :data="list2" border stripe class="table" height="35vh" ref="table2Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室"></el-table-column>
<el-table-column label="姓名/条码">
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="jssj" label="签收时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header">
<span>标本完成效率TAT</span>
</div>
<div class="table-box">
<el-table :data="list3" border stripe class="table" height="35vh" ref="table3Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器"></el-table-column>
<el-table-column label="样本号/条码号">
<template #default="{ row }">
<span>{{ row.ybh }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="sjsj" label="上机时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header red-title">危急值结果:(请工作人员及时处理!)</div>
<div class="table-box">
<el-table :data="list4" border stripe class="table" height="35vh" ref="table4Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器"></el-table-column>
<el-table-column prop="ybh" label="样本号"></el-table-column>
<el-table-column prop="xmmc" label="项目"></el-table-column>
<el-table-column prop="csjg" label="结果"></el-table-column>
<el-table-column prop="confirm" label="确认超时"></el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<script>
const { createApp, ref, onMounted, onUnmounted, nextTick } = Vue;
const app = createApp({
components: {
...ElementPlus.components
},
setup() {
// 创建axios实例
const request = axios.create({
baseURL: '',
timeout: 5000 // 请求超时时间
})
// 表格数据
const list1 = ref([]);
const list2 = ref([]);
const list3 = ref([]);
const list4 = ref([]);
// 表格样式配置
const tableHeaderStyle = {
background: 'rgba(30, 104, 195, 1)',
color: '#ffffff',
fontSize: '16px',
fontWeight: 'bold',
borderColor: '#0099ff',
padding: '4px 0px'
}
const tableCellStyle = {
background: 'transparent',
color: '#ffffff',
fontSize: '15px',
borderColor: '#0099ff',
padding: '2px 0px'
}
const tableRowStyle = ({ rowIndex }) => {
return {
background: rowIndex % 2 === 0 ? 'transparent' : 'rgba(0, 153, 255, 0.1)',
hover: 'rgba(0, 153, 255, 0.2)'
}
}
// 表格引用
const table1Ref = ref()
const table2Ref = ref()
const table3Ref = ref()
const table4Ref = ref()
// 定义各表格对应的接口地址
const tableApiMap = {
list1: '/api/list1',
list2: '/api/list2',
list3: '/api/list3',
list4: '/api/list4'
};
// 配置
const SCROLL_INTERVAL = 100; // 滚动速度
const SCROLL_PAUSE = 5000; // 到底停顿时间
const NO_SCROLL_REFRESH = 5000; // 无滚动自动刷新
const TOP_PAUSE = 3000; // 回到顶部后停顿时间
// 锁:防止重复触发
const locked = ref({
list1: false,
list2: false,
list3: false,
list4: false
});
const getScrollWrapper = (tableRef) => {
if (!tableRef.value) return null;
const bodyWrapper = tableRef.value.layout.table.refs.bodyWrapper;
return bodyWrapper?.firstElementChild?.firstElementChild || null;
};
// 获取单个表格数据
const fetchTableData = async (listKey) => {
try {
const response = await request.get(tableApiMap[listKey]);
// 根据列表key更新对应数据
if (listKey === 'list1') {
list1.value = response.data.data || [];
} else if (listKey === 'list2') {
list2.value = response.data.data || [];
} else if (listKey === 'list3') {
list3.value = response.data.data || [];
} else if (listKey === 'list4') {
list4.value = response.data.data || [];
}
console.log(`成功获取${listKey}数据`, response.data);
} catch (error) {
console.error(`获取${listKey}数据失败`, error);
}
};
// 封装滚动函数,接收表格ref、数据列表key、数据列表
const createTableScroll = (tableRef, listKey) => {
let scrollTimer = null;
let refreshTimer = null;
const clear = () => {
clearInterval(scrollTimer);
clearInterval(refreshTimer);
scrollTimer = null;
refreshTimer = null;
};
const start = () => {
clear();
// 定时检查:是否需要滚动
const checkAndScroll = () => {
const wrapper = getScrollWrapper(tableRef);
if (!wrapper) return;
// 内容没有溢出 → 只刷新,不滚动
if (wrapper.scrollHeight <= wrapper.clientHeight) {
return;
}
// 锁定中 → 不滚动
if (locked.value[listKey]) return;
// 正常滚动
wrapper.scrollTop += 1;
// 判断到底
const isBottom = wrapper.scrollTop + wrapper.clientHeight >= wrapper.scrollHeight - 2;
if (isBottom) {
locked.value[listKey] = true;
clearInterval(scrollTimer);
// 停顿后刷新 + 重置
setTimeout(async () => {
await fetchTableData(listKey);
await nextTick(); // 等待DOM更新
const newWrapper = getScrollWrapper(tableRef);
if (newWrapper) newWrapper.scrollTop = 0;
// 新增:回到顶部后停顿3秒再解锁并重启滚动
setTimeout(() => {
locked.value[listKey] = false;
start(); // 重新启动滚动
}, TOP_PAUSE);
}, SCROLL_PAUSE);
}
};
// 启动滚动定时器
scrollTimer = setInterval(checkAndScroll, SCROLL_INTERVAL);
// 无滚动时定时刷新
refreshTimer = setInterval(async () => {
const wrapper = getScrollWrapper(tableRef);
if (wrapper && wrapper.scrollHeight <= wrapper.clientHeight) {
await fetchTableData(listKey);
}
}, NO_SCROLL_REFRESH);
};
return { start, clear };
};
// 初始化所有表格数据
const initAllTableData = async () => {
await Promise.all([
fetchTableData('list1'),
fetchTableData('list2'),
fetchTableData('list3'),
fetchTableData('list4')
]);
};
// 每个表格独立实例化滚动
const table1Scroll = createTableScroll(table1Ref, 'list1');
const table2Scroll = createTableScroll(table2Ref, 'list2');
const table3Scroll = createTableScroll(table3Ref, 'list3');
const table4Scroll = createTableScroll(table4Ref, 'list4');
// 动态时间
const nowTime = ref('');
const updateTime = () => {
nowTime.value = dayjs().format('YYYY年MM月DD日 HH:mm:ss');
};
let timeTimer = null;
onMounted(async () => {
// 更新时间
updateTime();
timeTimer = setInterval(updateTime, 1000);
// 初始化加载所有表格数据
await initAllTableData();
// 等待DOM渲染完成后启动表格滚动/刷新
await nextTick();
table1Scroll.start();
table2Scroll.start();
table3Scroll.start();
table4Scroll.start();
});
onUnmounted(() => {
// 清理所有定时器
clearInterval(timeTimer);
table1Scroll.clear();
table2Scroll.clear();
table3Scroll.clear();
table4Scroll.clear();
});
return {
list1,
list2,
list3,
list4,
table1Ref,
table2Ref,
table3Ref,
table4Ref,
nowTime,
tableHeaderStyle,
tableCellStyle,
tableRowStyle
};
}
});
// 注册Element Plus
app.use(ElementPlus);
app.mount('#app');
</script>
</body>
</html>

374
TAT/index.html Normal file
View File

@ -0,0 +1,374 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAT监控大屏</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="screen-container">
<div class="screen-header">
<div class="screen-title">TAT超时提醒大屏</div>
<div class="screen-time" id="timeDom"></div>
</div>
<div class="grid-wrapper">
<!-- 表格1 已采集待收标本超时 -->
<div class="card">
<div class="card-header">
<span>已采集待收标本超时</span>
<span class="red-text" id="count1">共 0个标本</span>
</div>
<div class="table-box">
<table id="table1">
<thead>
<tr>
<th>科室</th>
<th>姓名/条码</th>
<th>标本/项目</th>
<th>采样时间</th>
<th width="120">等待时间</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- 表格2 已核收未上机超时 -->
<div class="card">
<div class="card-header">
<span>已核收未上机超时</span>
<span class="red-text" id="count2">共 0个标本</span>
</div>
<div class="table-box">
<table id="table2">
<thead>
<tr>
<th>科室</th>
<th>姓名/条码</th>
<th>标本/项目</th>
<th>签收时间</th>
<th width="120">等待时间</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<!-- 表格3 标本报告未完成超时 -->
<div class="card">
<div class="card-header">
<span>标本报告未完成超时</span>
<span class="red-text" id="count3">共 0个标本</span>
</div>
<div class="table-box">
<table id="table3">
<thead>
<tr>
<th>仪器</th>
<th>样本号/条码号</th>
<th>标本/项目</th>
<th>上机时间</th>
<th width="120">等待时间</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<!-- 表格4 危急值未处理超时 -->
<div class="card">
<div class="card-header">
<span>危急值未处理超时</span>
<span class="red-text" id="count4">共 0个标本</span>
</div>
<div class="table-box">
<table id="table4">
<thead>
<tr>
<th>仪器</th>
<th>样本号</th>
<th>项目</th>
<th>结果</th>
<th width="120">等待时间</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 右上角关闭按钮 -->
<div class="close-btn-box">
<div class="close-icon-btn" onclick="closeCurrentPage()">×</div>
</div>
<script>
// ===================== 全局配置 =====================
// 从url获取每页行数
function getPageSizeFromUrl() {
const search = window.location.search.slice(1);
const params = new URLSearchParams(search);
const rows = parseInt(params.get('rows'));
return !isNaN(rows) && rows > 0 ? rows : 13;
}
const PAGE_SIZE = getPageSizeFromUrl();
const PAGE_DELAY = 5000; // 翻页间隔
const NO_PAGE_DELAY = 5000; // 不足一页/无数据刷新间隔
// 全局数据存储
const globalData = {
list1: [], list2: [], list3: [], list4: [],
pageList1: [], pageList2: [], pageList3: [], pageList4: []
};
// 定时器存储,页面卸载统一清空
const timerPool = {
timeClock: null,
carousel1: null, carousel2: null, carousel3: null, carousel4: null,
load1: null, load2: null, load3: null, load4: null
};
// ===================== 工具函数 =====================
// 安全清除定时器
function safeClear(timer) {
if (timer) clearTimeout(timer);
return null;
}
// 关闭页面
function closeCurrentPage() {
window.close();
}
// 更新顶部时间
function updateNowTime() {
const dom = document.getElementById('timeDom');
const d = new Date();
const pad = n => String(n).padStart(2, '0');
const year = d.getFullYear();
const month = pad(d.getMonth() + 1);
const day = pad(d.getDate());
const h = pad(d.getHours());
const m = pad(d.getMinutes());
const s = pad(d.getSeconds());
dom.innerText = `${year}年${month}月${day}日 ${h}:${m}:${s}`;
}
// 原生Ajax GET请求
function ajaxGet(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
let res;
try {
res = JSON.parse(xhr.responseText);
} catch (err) {
res = {};
}
callback(null, res);
} else {
callback(new Error('请求失败'), null);
}
};
xhr.onerror = function () {
callback(new Error('网络错误'), null);
};
xhr.send();
}
// 渲染表格1 已采集待收标本超时
function renderTable1(dataArr) {
const tbody = document.querySelector('#table1 tbody');
const countDom = document.getElementById('count1');
tbody.innerHTML = '';
countDom.innerText = `共 ${globalData.list1.length}个标本`;
dataArr.forEach(row => {
const tr = document.createElement('tr');
const tds = [
{ text: row.ksdh },
{ text: `${row.brxm} / ${row.sqh}` },
{ text: `${row.yblx} / ${row.jymd}` },
{ text: row.cysj },
{ text: `${row.holdtime || 0} 分钟`, red: true }
];
tds.forEach(item => {
const td = document.createElement('td');
td.innerText = item.text;
td.setAttribute('data-tip', item.text);
if (item.red) td.className = 'red-text';
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}
// 渲染表格2 已核收未上机超时
function renderTable2(dataArr) {
const tbody = document.querySelector('#table2 tbody');
const countDom = document.getElementById('count2');
tbody.innerHTML = '';
countDom.innerText = `共 ${globalData.list2.length}个标本`;
dataArr.forEach(row => {
const tr = document.createElement('tr');
const tds = [
{ text: row.ksdh },
{ text: `${row.brxm} / ${row.sqh}` },
{ text: `${row.yblx} / ${row.jymd}` },
{ text: row.jssj },
{ text: `${row.holdtime || 0} 分钟`, red: true }
];
tds.forEach(item => {
const td = document.createElement('td');
td.innerText = item.text;
td.setAttribute('data-tip', item.text);
if (item.red) td.className = 'red-text';
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}
// 渲染表格3 标本报告未完成超时
function renderTable3(dataArr) {
const tbody = document.querySelector('#table3 tbody');
const countDom = document.getElementById('count3');
tbody.innerHTML = '';
countDom.innerText = `共 ${globalData.list3.length}个标本`;
dataArr.forEach(row => {
const tr = document.createElement('tr');
const tds = [
{ text: row.yq },
{ text: `${row.ybh} / ${row.sqh}` },
{ text: `${row.yblx} / ${row.jymd}` },
{ text: row.sjsj },
{ text: `${row.holdtime || 0} 分钟`, red: true }
];
tds.forEach(item => {
const td = document.createElement('td');
td.innerText = item.text;
td.setAttribute('data-tip', item.text);
if (item.red) td.className = 'red-text';
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}
// 渲染表格4 危急值未处理超时
function renderTable4(dataArr) {
const tbody = document.querySelector('#table4 tbody');
const countDom = document.getElementById('count4');
tbody.innerHTML = '';
countDom.innerText = `共 ${globalData.list4.length}个标本`;
dataArr.forEach(row => {
const tr = document.createElement('tr');
const tds = [
{ text: row.yq },
{ text: row.ybh },
{ text: row.xmmc },
{ text: row.csjg },
{ text: `${row.holdtime || 0} 分钟`, red: true }
];
tds.forEach(item => {
const td = document.createElement('td');
td.innerText = item.text;
td.setAttribute('data-tip', item.text);
if (item.red) td.className = 'red-text';
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}
// ===================== 分页轮播核心逻辑 =====================
/**
* @param listKey 全局原始数据key list1/list2...
* @param pageKey 分页数据key pageList1...
* @param renderFn 渲染函数
* @param timerKey 定时器存储key
* @param reloadFn 接口重载函数
*/
function startCarousel(listKey, pageKey, renderFn, timerKey, reloadFn) {
let currentPage = 0;
function runCarousel() {
timerPool[timerKey] = safeClear(timerPool[timerKey]);
const total = globalData[listKey].length;
if (total === 0) {
globalData[pageKey] = [];
renderFn([]);
timerPool[timerKey] = setTimeout(runCarousel, NO_PAGE_DELAY);
return;
}
// 数据不足一页,直接全部展示,定时刷新
if (total <= PAGE_SIZE) {
globalData[pageKey] = [...globalData[listKey]];
renderFn(globalData[pageKey]);
timerPool[timerKey] = setTimeout(runCarousel, NO_PAGE_DELAY);
return;
}
// 分页切片
const start = currentPage * PAGE_SIZE;
const end = start + PAGE_SIZE;
globalData[pageKey] = globalData[listKey].slice(start, end);
renderFn(globalData[pageKey]);
const isLastPage = end >= total;
if (isLastPage) {
// 最后一页停留后重新拉取接口数据
timerPool[timerKey] = setTimeout(() => {
currentPage = 0;
reloadFn();
}, PAGE_DELAY);
} else {
// 下一页
timerPool[timerKey] = setTimeout(() => {
currentPage++;
runCarousel();
}, PAGE_DELAY);
}
}
runCarousel();
}
// ===================== 接口加载封装 =====================
function createLoader(url, listKey, pageKey, renderFn, carouselTimerKey, loaderTimerKey) {
function loadData() {
timerPool[loaderTimerKey] = safeClear(timerPool[loaderTimerKey]);
// 停止当前轮播
timerPool[carouselTimerKey] = safeClear(timerPool[carouselTimerKey]);
ajaxGet(url, function (err, res) {
if (err) {
console.log('接口加载失败', url, err);
timerPool[loaderTimerKey] = setTimeout(loadData, NO_PAGE_DELAY);
return;
}
globalData[listKey] = res.data || [];
// 重启轮播
startCarousel(listKey, pageKey, renderFn, carouselTimerKey, loadData);
});
}
loadData();
}
// ===================== 页面初始化 =====================
function pageInit() {
// 初始化时间
updateNowTime();
timerPool.timeClock = setInterval(updateNowTime, 1000);
// 启动4个表格加载+轮播
createLoader('/api/list1', 'list1', 'pageList1', renderTable1, 'carousel1', 'load1');
createLoader('/api/list2', 'list2', 'pageList2', renderTable2, 'carousel2', 'load2');
createLoader('/api/list3', 'list3', 'pageList3', renderTable3, 'carousel3', 'load3');
createLoader('/api/list4', 'list4', 'pageList4', renderTable4, 'carousel4', 'load4');
}
// 页面卸载/关闭 清空全部定时器,释放资源
function clearAllTimer() {
Object.keys(timerPool).forEach(key => {
timerPool[key] = safeClear(timerPool[key]);
});
}
window.onbeforeunload = clearAllTimer;
window.onload = pageInit;
</script>
</body>
</html>

5
TAT/js/axios.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
TAT/js/dayjs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

59570
TAT/js/element-plus.js Normal file

File diff suppressed because it is too large Load Diff

13
TAT/js/vue.global.prod.js Normal file

File diff suppressed because one or more lines are too long