|
|
@@ -1,70 +1,102 @@
|
|
|
<template>
|
|
|
<div class="ehr-page">
|
|
|
<Header />
|
|
|
- <section class="hero max-w-[1400px] mx-auto">
|
|
|
- <div class="hero-inner">
|
|
|
- <!-- 判断上下午 -->
|
|
|
- <h1 class="hero-title">
|
|
|
- {{ getGreeting() }},{{ userStore.getUser.nickname }}
|
|
|
- </h1>
|
|
|
- <p class="hero-desc">
|
|
|
- 今天是 {{ new Date().toLocaleDateString() }}。您有
|
|
|
- {{ stats[0].number }}条流程待处理。
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </section>
|
|
|
-
|
|
|
- <!-- 任务统计 -->
|
|
|
- <section class="total max-w-[1400px] mx-auto">
|
|
|
- <div class="total-card" v-for="(item, index) in stats" :key="index">
|
|
|
- <el-popover
|
|
|
- placement="top"
|
|
|
- :width="100"
|
|
|
- trigger="hover"
|
|
|
- popper-class="glass-popover"
|
|
|
- :disabled="getDetailList(index).length === 0"
|
|
|
- transition="el-zoom-in-left"
|
|
|
- >
|
|
|
- <template #reference>
|
|
|
- <div class="card-wrapper">
|
|
|
- <!-- ... 图标和内容 ... -->
|
|
|
- <div class="card-icon" :style="{ backgroundColor: item.bgcolor }">
|
|
|
- <Icon :icon="item.icon" :color="item.color" />
|
|
|
+
|
|
|
+ <div class="banner max-w-[1400px] mx-auto rounded-2xl mt-10">
|
|
|
+ <section class="hero max-w-[1400px] mx-auto">
|
|
|
+ <div class="hero-inner">
|
|
|
+ <!-- 判断上下午 -->
|
|
|
+ <h1 class="hero-title">
|
|
|
+ {{ getGreeting() }},{{ userStore.getUser.nickname }}
|
|
|
+ </h1>
|
|
|
+ <p class="hero-desc">
|
|
|
+ 今天是 {{ new Date().toLocaleDateString() }}。您有
|
|
|
+ {{ stats[0].number }}条流程待处理。
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <!-- 任务统计 -->
|
|
|
+ <section class="total max-w-[1400px] mx-auto">
|
|
|
+ <div class="total-card" v-for="(item, index) in stats" :key="index">
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ :width="100"
|
|
|
+ trigger="hover"
|
|
|
+ popper-class="glass-popover"
|
|
|
+ :disabled="getDetailList(index).length === 0"
|
|
|
+ transition="el-zoom-in-left"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <div
|
|
|
+ class="card-wrapper flex items-center justify-center gap-4 flex-col md:flex-row"
|
|
|
+ >
|
|
|
+ <!-- ... 图标和内容 ... -->
|
|
|
+ <div class="">
|
|
|
+ <img
|
|
|
+ v-if="item.title === '我的待办'"
|
|
|
+ src="../../assets//images/todo.png"
|
|
|
+ alt=""
|
|
|
+ class="h-15 w-15"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ v-if="item.title === '已办事项'"
|
|
|
+ src="../../assets//images/done.png"
|
|
|
+ alt=""
|
|
|
+ class="h-15 w-15"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="card-content">
|
|
|
+ <p class="card-title">{{ item.title }}</p>
|
|
|
+ <el-skeleton
|
|
|
+ :rows="1"
|
|
|
+ :animated="true"
|
|
|
+ :loading="statsLoading"
|
|
|
+ >
|
|
|
+ <template #template>
|
|
|
+ <el-skeleton-item
|
|
|
+ variant="text"
|
|
|
+ style="
|
|
|
+ width: 60%;
|
|
|
+ height: 32px;
|
|
|
+ border-radius: 50px;
|
|
|
+ background: #0a193d;
|
|
|
+ "
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <p class="card-number">{{ item.number }}</p>
|
|
|
+ </el-skeleton>
|
|
|
+ <p
|
|
|
+ v-if="item.title === '我的待办'"
|
|
|
+ class="text-[#6b6f99] !text-sm"
|
|
|
+ >
|
|
|
+ 待处理的流程
|
|
|
+ </p>
|
|
|
+ <p v-else class="text-[#6b6f99] !text-sm">已完成的流程</p>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="card-content">
|
|
|
- <p class="card-title">{{ item.title }}</p>
|
|
|
- <el-skeleton :rows="1" :animated="true" :loading="statsLoading">
|
|
|
- <template #template>
|
|
|
- <el-skeleton-item
|
|
|
- variant="text"
|
|
|
- style="width: 60%; height: 32px; border-radius: 50px"
|
|
|
- />
|
|
|
- </template>
|
|
|
- <p class="card-number">{{ item.number }}</p>
|
|
|
- </el-skeleton>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div class="detail-list">
|
|
|
+ <div
|
|
|
+ v-for="(task, idx) in getDetailList(index)"
|
|
|
+ :key="idx"
|
|
|
+ class="detail-item"
|
|
|
+ @click="handleDetailClick(task, item.title)"
|
|
|
+ >
|
|
|
+ <span class="detail-name">{{ task.name }}</span>
|
|
|
+ <span class="detail-val">{{ task.value }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="getDetailList(index).length === 0" class="empty-tip">
|
|
|
+ 暂无详细数据
|
|
|
</div>
|
|
|
</div>
|
|
|
- </template>
|
|
|
-
|
|
|
- <div class="detail-list">
|
|
|
- <div
|
|
|
- v-for="(task, idx) in getDetailList(index)"
|
|
|
- :key="idx"
|
|
|
- class="detail-item"
|
|
|
- @click="handleDetailClick(task, item.title)"
|
|
|
- >
|
|
|
- <span class="detail-name">{{ task.name }}</span>
|
|
|
- <span class="detail-val">{{ task.value }}</span>
|
|
|
- </div>
|
|
|
- <div v-if="getDetailList(index).length === 0" class="empty-tip">
|
|
|
- 暂无详细数据
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-popover>
|
|
|
- </div>
|
|
|
- </section>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="content max-w-[1400px] mx-auto">
|
|
|
+ <div class="content max-w-[1400px] mx-auto mt-10">
|
|
|
<div class="search-bar">
|
|
|
<div class="search-input">
|
|
|
<Icon icon="mdi:magnify" class="search-icon" />
|
|
|
@@ -868,21 +900,27 @@ onBeforeUnmount(() => {
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-/* .ehr-page {
|
|
|
- color: #1f2a37;
|
|
|
- background: linear-gradient(180deg, #f4f4f2 0%, #f7f6f3 50%, #f2f1ef 100%);
|
|
|
- min-height: 100vh;
|
|
|
-} */
|
|
|
-
|
|
|
:global(body) {
|
|
|
background-color: #f8fafc;
|
|
|
}
|
|
|
|
|
|
+.banner {
|
|
|
+ position: relative;
|
|
|
+ height: 300px;
|
|
|
+ top: 20px;
|
|
|
+ /* 设置背景图 */
|
|
|
+ background: url("../../assets//images/flwoBanner.png"); /* 或者使用变量 if defined in script */
|
|
|
+ background-size: cover;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center;
|
|
|
+ border: 2px solid #061338;
|
|
|
+}
|
|
|
+
|
|
|
.hero {
|
|
|
position: relative;
|
|
|
- padding: 72px 6vw 48px;
|
|
|
+ padding: 20px 6vw 48px;
|
|
|
overflow: hidden;
|
|
|
- margin-top: 20px;
|
|
|
+
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
@@ -896,13 +934,13 @@ onBeforeUnmount(() => {
|
|
|
font-size: clamp(18px, 2vw, 22px);
|
|
|
line-height: 1.2;
|
|
|
margin: 16px 0 12px;
|
|
|
- color: #111827;
|
|
|
+ color: #fff;
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
|
|
|
.hero-desc {
|
|
|
font-size: 16px;
|
|
|
- color: #4b5563;
|
|
|
+ color: #a7a0b1;
|
|
|
max-width: 720px;
|
|
|
line-height: 1.8;
|
|
|
}
|
|
|
@@ -1255,32 +1293,83 @@ onBeforeUnmount(() => {
|
|
|
}
|
|
|
|
|
|
.total-card {
|
|
|
- /* flex: 1; */
|
|
|
+ position: relative; /* 必须设置为 relative,作为伪元素的定位基准 */
|
|
|
width: 300px;
|
|
|
- background: #ffffff;
|
|
|
+ /* 内部背景保持深色半透明 */
|
|
|
+ background: rgba(5, 15, 46, 0.85);
|
|
|
border-radius: 16px;
|
|
|
padding: 20px;
|
|
|
- box-shadow:
|
|
|
- rgba(0, 0, 0, 0.05) 0px 1px 3px 0px,
|
|
|
- rgba(0, 0, 0, 0) 0px 0px 0px 0px,
|
|
|
- rgba(0, 0, 0, 0.05) 0px 1px 2px 0px,
|
|
|
- rgba(0, 0, 0, 0.05) 0px 2px 4px -1px,
|
|
|
- rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
|
|
|
- transition:
|
|
|
- transform 0.2s ease,
|
|
|
- box-shadow 0.2s ease;
|
|
|
+ backdrop-filter: blur(8px);
|
|
|
+ -webkit-backdrop-filter: blur(8px);
|
|
|
+
|
|
|
+ /* 移除原有的普通边框和阴影,由伪元素接管视觉效果 */
|
|
|
+ border: none;
|
|
|
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); /* 增加一点投影增强立体感 */
|
|
|
+
|
|
|
+ transition: transform 0.3s ease;
|
|
|
cursor: pointer;
|
|
|
- /* border: 1px solid #e5e7eb; */
|
|
|
- /* border-top: solid 5px #02409b; */
|
|
|
- overflow: visible;
|
|
|
+ overflow: hidden; /* 关键:隐藏伪元素溢出的部分 */
|
|
|
+ z-index: 1; /* 确保内容在发光边框之上 */
|
|
|
}
|
|
|
|
|
|
+/* 霓虹发光边框层 */
|
|
|
+.total-card::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ top: -50%;
|
|
|
+ left: -50%;
|
|
|
+ width: 200%;
|
|
|
+ height: 200%;
|
|
|
+ /* 彩色圆锥渐变:包含蓝、紫、粉、青等霓虹色 */
|
|
|
+ background: conic-gradient(
|
|
|
+ transparent,
|
|
|
+ #02409b,
|
|
|
+ #00d2ff,
|
|
|
+ #7c3aed,
|
|
|
+ #db2777,
|
|
|
+ transparent 30%
|
|
|
+ );
|
|
|
+ animation: rotate-border 4s linear infinite; /* 旋转动画 */
|
|
|
+ z-index: -2;
|
|
|
+}
|
|
|
+
|
|
|
+/* 内部遮罩层:用于覆盖中间区域,只露出边缘形成边框 */
|
|
|
+.total-card::after {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ inset: 1px; /* 这里控制边框宽度,2px 即边框宽 */
|
|
|
+ background: rgba(
|
|
|
+ 5,
|
|
|
+ 15,
|
|
|
+ 46,
|
|
|
+ 0.92
|
|
|
+ ); /* 与卡片背景一致,稍微不透明一点以遮盖旋转背景 */
|
|
|
+ border-radius: 14px; /* 比父容器小一点 */
|
|
|
+ z-index: -1;
|
|
|
+}
|
|
|
+
|
|
|
+/* 悬停时增强发光效果 */
|
|
|
.total-card:hover {
|
|
|
transform: translateY(-4px);
|
|
|
- box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
|
|
|
- color: #02409b !important;
|
|
|
+ box-shadow: 0 0 20px rgba(2, 64, 155, 0.4); /* 整体外发光 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 悬停时加速旋转或改变亮度(可选) */
|
|
|
+.total-card:hover::before {
|
|
|
+ filter: brightness(1.2); /* 悬停时更亮 */
|
|
|
}
|
|
|
|
|
|
+/* 定义旋转动画 */
|
|
|
+@keyframes rotate-border {
|
|
|
+ 0% {
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 保持原有内部文字样式不变,但确保它们在最上层 */
|
|
|
.card-icon {
|
|
|
width: 40px;
|
|
|
height: 40px;
|
|
|
@@ -1290,6 +1379,8 @@ onBeforeUnmount(() => {
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
margin-bottom: 12px;
|
|
|
+ position: relative; /* 确保图标层级 */
|
|
|
+ z-index: 2;
|
|
|
}
|
|
|
|
|
|
.card-icon svg {
|
|
|
@@ -1305,14 +1396,14 @@ onBeforeUnmount(() => {
|
|
|
|
|
|
.card-title {
|
|
|
font-size: 14px;
|
|
|
- color: #6b7280;
|
|
|
+ color: #a7a0b1; /* 调整为浅色以适配深色背景 */
|
|
|
margin-bottom: 4px;
|
|
|
}
|
|
|
|
|
|
.card-number {
|
|
|
font-size: 28px;
|
|
|
font-weight: 600;
|
|
|
- /* color: #111827; */
|
|
|
+ color: #ffffff; /* 数字改为白色 */
|
|
|
}
|
|
|
|
|
|
.card-extra {
|