健康咨询平台大屏

This commit is contained in:
huangzhen
2025-09-25 14:57:31 +08:00
parent a97d9c64aa
commit d103785a45
15 changed files with 20569 additions and 5 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+10 -2
View File
@@ -19,13 +19,21 @@ const routes: Array<RouteRecordRaw> = [
component: () => import('/@/views/sys/login.vue'),
},
{
path: '/home',
name: 'index',
path: '/home2',
name: 'index2',
meta: {
title: '副屏',
},
component: () => import('/@/views/indexSun.vue'),
},
{
path: '/home',
name: 'index',
meta: {
title: '健康咨询',
},
component: () => import('../views/healthConsultation/HealthConsultationIndex.vue'),
},
{
path: '/indexSon',
name: 'indexSon',
@@ -0,0 +1,147 @@
<template>
<div class="sun-screen-box">
<div class="sun-screen-title">
<div class="sun-title-left">
{{ dateInfo?.day }} {{ dateInfo?.times }}<span style="margin-left: 30px">{{ rightDate }}</span>
</div>
<div class="sun-title-center">健康咨询平台</div>
<div class="sun-title-right">
<!-- <a-button class="top-right-button" @click="toOther">健康监测大屏</a-button> -->
</div>
</div>
<div class="sun-body-content">
<div class="sun-body-content-top">
<health-content-top />
</div>
<div class="sun-body-content-middle">
<health-content-middle />
</div>
<div class="sun-body-content-bottom">
<health-content-bottom-item1 class="item" />
<health-content-bottom-item2 class="item" />
<health-content-bottom-item3 class="item" />
<health-content-bottom-item4 class="item" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import healthContentTop from './components/healthContentTop.vue';
import healthContentMiddle from './components/healthContentMiddle.vue';
import healthContentBottomItem1 from './components/healthContentBottomItem1.vue';
import healthContentBottomItem2 from './components/healthContentBottomItem2.vue';
import healthContentBottomItem3 from './components/healthContentBottomItem3.vue';
import healthContentBottomItem4 from './components/healthContentBottomItem4.vue';
import { ref, onMounted, watch } from 'vue';
import dayjs from 'dayjs';
import { startTime } from '/@/utils/utils.ts';
interface DateInfo {
day?: string;
times?: string;
}
const dateInfo = ref<DateInfo>({});
const rightDate = ref<string>('');
const initDate = ref(startTime);
const getTime = () => {
dateInfo.value = {
day: dayjs().format('YYYY年MM月DD日'),
times: dayjs().format('HH:mm:ss'),
};
};
onMounted(() => {
getTime();
rightDate.value = '累计运行时间:' + (dayjs().diff(dayjs(initDate.value), 'days') + 1) + ' 天';
});
watch(
() => dateInfo.value.day,
() => {
rightDate.value = '累计运行时间:' + (dayjs().diff(dayjs(initDate.value), 'days') + 1) + ' 天';
}
);
</script>
<style lang="less" scoped>
.sun-screen-box {
height: 100vh;
letter-spacing: 2px;
background: url('/@/assets/indexSun/bigBg.png') no-repeat;
background-size: 100% 100%;
.sun-screen-title {
height: 87px;
background: url('/@/assets/indexSun/bg.png') no-repeat;
background-size: 100% 100%;
display: flex;
font-size: 20px;
color: #fff;
text-align: center;
.sun-title-left {
font-family: MicrosoftYaHei-Bold;
// font-size: 22px;
font-size: clamp(14px, 1vw, 50px);
font-weight: bold;
text-align: left;
flex: 1;
line-height: 60px;
padding-left: 15px;
}
.sun-title-right {
flex: 1;
text-align: right;
line-height: 50px;
padding-right: 30px;
}
.sun-title-center {
flex: 1;
font-size: 58px;
letter-spacing: 10px;
// text-shadow: 2px 2px 5px rgba(118, 141, 219, 0.53);
font-weight: 400;
font-family: PangMenZhengDao;
}
}
.sun-body-content {
height: calc(100% - 87px);
padding: 10px 20px;
box-sizing: border-box;
.sun-body-content-top {
height: 10%;
}
.sun-body-content-middle {
height: 55%;
// padding: 0 20px 20px 20px;
box-sizing: border-box;
width: 100%;
// position: absolute;
// left: 0;
// top: 200px;
}
.sun-body-content-bottom {
height: 35%;
// padding: 0 20px 20px 20px;
box-sizing: border-box;
width: 100%;
// height: 300px;
// position: absolute;
// left: 0;
// bottom: 0;
display: flex;
justify-content: space-around;
display: flex;
justify-content: space-between; /* 左右元素靠边,中间等间距 */
gap: 16px;
.item {
flex: 1; /* 等分占位 */
}
}
}
}
</style>
@@ -0,0 +1,28 @@
import { get } from '/@/api/request';
export enum Api {
staticCount = '/health-consultation/api/consult/screen/queryStaticCount',
docList = '/health-consultation/api/consult/screen/queryDocList',
docCountStat = '/health-consultation/api/consult/screen/queryDocCountStat',
deptCountStat = '/health-consultation/api/consult/screen/queryDeptCountStat',
departmentCountStat = '/health-consultation/api/consult/screen/queryDepartmentCountStat',
hospitalCountStat = '/health-consultation/api/consult/screen/queryHospitalCountStat',
}
//咨询大屏人数统计查询
export const getStaticCount = () => get(Api.staticCount);
//咨询大屏人数统计查询
export const getDocList = () => get(Api.docList);
//医院专家数量统计
export const getDocCountStat = () => get(Api.docCountStat);
//单位咨询数量统计
export const getDeptCountStat = () => get(Api.deptCountStat);
//科室咨询数量统计
export const getDepartmentCountStat = () => get(Api.departmentCountStat);
//医院咨询数量
export const getHospitalCountStat = () => get(Api.hospitalCountStat);
@@ -0,0 +1,250 @@
<template>
<div class="chart-container">
<div class="title">医院专家数量统计</div>
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue';
import * as echarts from 'echarts';
import { getDocCountStat } from '/@/views/healthConsultation/api/health';
const chartRef = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
// const total = 2920;
// const data = [
// { name: '新疆医科大学第一附属医院', value: 650 },
// { name: '昌吉州宝石花医院', value: 422 },
// { name: '新疆维吾尔自治区人民医院', value: 928 },
// { name: '新克拉玛依市中心医院', value: 560 },
// ];
const transformHospitalData = (hospitals: { docCount: number; hospitalName: string }[]) => {
return hospitals.map((hospital) => ({
name: hospital.hospitalName,
value: hospital.docCount,
}));
};
const colors = ['#1385FA', '#FB466C', '#2AC79F', '#FEB101'];
function getData() {
getDocCountStat()
.then((res: any) => {
if (res.code == 200) {
const transformedData = transformHospitalData(res.result);
initChart(transformedData);
}
})
.catch((err) => {
console.log(err);
});
}
function getTotalDocCount(hospitals: { value: number; name: string }[]): number {
return hospitals.reduce((total, hospital) => total + hospital.value, 0);
}
const initChart = (value: any[]) => {
if (!chartRef.value) return;
chartInstance = echarts.init(chartRef.value);
const option: echarts.EChartsOption = {
// title: {
// text: '医院专家数量统计',
// left: 'center',
// top: 10,
// textStyle: {
// color: '#fff',
// fontSize: 18,
// fontWeight: 'bold',
// },
// },
tooltip: {
trigger: 'item',
formatter: '{b}: {c}人 ({d}%)',
},
series: [
{
name: '专家人数',
type: 'pie',
radius: ['30%', '40%'],
center: ['50%', '55%'],
data: value,
label: {
show: true,
color: '#fff',
fontSize: 12,
lineHeight: 20,
formatter: (params: any) => {
const name: string = params.name;
const value: number = params.value;
const maxLen = 6; // 超过 6 个字就换行
let newName = '';
for (let i = 0; i < name.length; i += maxLen) {
newName += name.substring(i, i + maxLen) + '\n';
}
return `${newName}(${value}人)`;
},
},
// itemStyle: {
// borderRadius: 5,
// borderColor: '#0f2c44',
// borderWidth: 2,
// },
},
],
graphic: [
{
type: 'text',
left: 'center',
top: '48%',
style: {
text: `总人数`,
// textAlign: 'center',
fill: '#fff',
fontSize: 16,
fontFamily: 'HarmonyOS Sans SC',
// fontWeight: 'bold',
},
},
{
type: 'text',
left: 'center',
top: '56%', // 第二行位置
style: {
// text: `${total}`,
text: `${getTotalDocCount(value)}`,
// textAlign: 'center',
fill: '#fff',
fontSize: 20,
fontWeight: 'bold',
fontFamily: 'HarmonyOS Sans SC',
},
},
],
legend: [
{
orient: 'vertical',
left: 20,
top: 10,
itemGap: 10,
icon: 'path://M200 512 H307 a154,154 0 1,0 308,0 a154,154 0 1,0 -308,0 H824',
textStyle: {
color: '#fff',
fontSize: 12,
rich: {
name: {
fontSize: 12,
color: '#fff',
align: 'left', // 左对齐
// lineHeight: 20,
fontFamily: 'HarmonyOS Sans SC',
},
// value: {
// fontSize: 14,
// color: '#aaa',
// align: 'left', // 左对齐
// lineHeight: 20,
// },
},
},
// data: [data[0].name, data[3].name],
data:
value && Array.isArray(value)
? value
.filter((_, index) => index % 2 === 0)
.slice(0, 2)
.map((item) => item.name || '')
: ['', ''],
// formatter: (name: string) => {
// const item = data.find((d) => d.name === name);
// return `{name|${name}}\n{value|${item?.value}人}`;
// },
},
{
orient: 'vertical',
right: 20,
top: 10,
itemGap: 10,
icon: 'circle',
textStyle: {
color: '#fff',
fontSize: 12,
rich: {
name: {
fontSize: 12,
color: '#fff',
align: 'right', // 右对齐
// lineHeight: 20,
},
// value: {
// fontSize: 14,
// color: '#aaa',
// align: 'right', // 右对齐
// lineHeight: 20,
// },
},
},
// data: [data[1].name, data[2].name],
data:
value && Array.isArray(value)
? value
.filter((_, index) => index % 2 === 1)
.slice(0, 2)
.map((item) => item.name || '')
: ['', ''],
// formatter: (name: string) => {
// const item = data.find((d) => d.name === name);
// return `{name|${name}}\n{value|${item?.value}人}`;
// },
},
],
color: colors,
};
chartInstance.setOption(option);
window.addEventListener('resize', () => chartInstance?.resize());
};
onMounted(() => {
getData();
// initChart();
});
onBeforeUnmount(() => {
chartInstance?.dispose();
chartInstance = null;
});
</script>
<style scoped lang="less">
.chart-container {
height: 100%;
// width: calc(100% / 5);
border: 1px solid #00ccff;
border-radius: 14px;
background: rgba(8, 75, 100, 0.2);
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
text-align: center;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
}
.chart {
width: 100%;
height: calc(100% - 40px);
}
}
</style>
@@ -0,0 +1,149 @@
<template>
<div class="chart-container">
<div class="title">单位咨询数量统计</div>
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { getDeptCountStat } from '/@/views/healthConsultation/api/health';
const chartRef = ref<HTMLDivElement | null>(null);
let chart: echarts.ECharts | null = null;
function getData() {
getDeptCountStat()
.then((res: any) => {
if (res.code == 200) {
// 提取数据
const consultHelperCounts = res.result.map((item: any) => item.consultHelperCount);
const consultDocCounts = res.result.map((item: any) => item.consultDocCount);
const departNames = res.result.map((item: any) => item.departName);
initChart(departNames, consultDocCounts, consultHelperCounts);
}
})
.catch((err) => {
console.log(err);
});
}
const initChart = (departNames: string[], consultDocCounts: number[], consultHelperCounts: number[]) => {
if (!chartRef.value) return;
chart = echarts.init(chartRef.value);
const option: echarts.EChartsOption = {
backgroundColor: 'transparent',
// title: {
// text: '单位咨询数量统计',
// left: 'center',
// top: 10,
// textStyle: {
// color: '#fff',
// fontSize: 18,
// },
// },
legend: {
top: 10,
textStyle: { color: '#fff' },
itemWidth: 20,
itemHeight: 16,
itemGap: 30, // 默认 10,这里改成 30,让两段文字隔开一些
// 圆环 icon
// icon: 'path://M512 0a512 512 0 1 0 0 1024A512 512 0 0 0 512 0zm0 896a384 384 0 1 1 0-768 384 384 0 0 1 0 768z',
icon: 'circle',
data: ['员工咨询全科医生', '员工咨询专家'],
},
grid: {
top: 70,
left: 50,
right: 30,
bottom: 70,
},
xAxis: {
type: 'category',
data: departNames,
axisLine: { lineStyle: { color: '#3d5269' } },
axisLabel: {
color: '#fff',
fontSize: 10,
rotate: 30,
},
},
yAxis: {
type: 'value',
axisLine: { lineStyle: { color: '#3d5269' } },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
axisLabel: { color: '#89DBFF' },
},
series: [
{
name: '员工咨询全科医生',
type: 'bar',
data: consultDocCounts,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(90,191,255,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(30,166,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(30,166,253,0.7)' }, // 边缘实心
]),
},
},
{
name: '员工咨询专家',
type: 'bar',
data: consultHelperCounts,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(60,255,253,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(60,255,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(48,223,221,0.7)' }, // 边缘实心
]),
},
},
],
};
chart.setOption(option);
window.addEventListener('resize', () => chart?.resize());
};
onMounted(() => {
getData();
// initChart();
});
onBeforeUnmount(() => {
chart?.dispose();
});
</script>
<style scoped>
.chart-container {
height: 100%;
/* width: calc(100% / 5); */
border: 1px solid #00ccff;
border-radius: 14px;
background: rgba(8, 75, 100, 0.2);
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
text-align: center;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
}
.chart {
width: 100%;
height: calc(100% - 40px);
}
}
</style>
@@ -0,0 +1,149 @@
<template>
<div class="chart-container">
<div class="title">科室咨询数量统计</div>
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { getDepartmentCountStat } from '/@/views/healthConsultation/api/health';
const chartRef = ref<HTMLDivElement | null>(null);
let chart: echarts.ECharts | null = null;
function getData() {
getDepartmentCountStat()
.then((res: any) => {
if (res.code == 200) {
// 提取数据
const consultVedioCount = res.result.map((item: any) => item.consultVedioCount);
const consultImCount = res.result.map((item: any) => item.consultImCount);
const departmentName = res.result.map((item: any) => item.departmentName);
initChart(departmentName, consultImCount, consultVedioCount);
}
})
.catch((err) => {
console.log(err);
});
}
const initChart = (departmentName: string[], consultImCount: number[], consultVedioCount: number[]) => {
if (!chartRef.value) return;
chart = echarts.init(chartRef.value);
const option: echarts.EChartsOption = {
backgroundColor: 'transparent',
// title: {
// text: '科室咨询数量统计',
// left: 'center',
// top: 10,
// textStyle: {
// color: '#fff',
// fontSize: 18,
// },
// },
legend: {
top: 10,
textStyle: { color: '#fff' },
itemWidth: 20,
itemHeight: 16,
itemGap: 30, // 默认 10,这里改成 30,让两段文字隔开一些
// 圆环 icon
// icon: 'path://M512 0a512 512 0 1 0 0 1024A512 512 0 0 0 512 0zm0 896a384 384 0 1 1 0-768 384 384 0 0 1 0 768z',
icon: 'circle',
data: ['图文', '视频'],
},
grid: {
top: 70,
left: 50,
right: 30,
bottom: 70,
},
xAxis: {
type: 'category',
data: departmentName,
axisLine: { lineStyle: { color: '#3d5269' } },
axisLabel: {
color: '#fff',
fontSize: 10,
rotate: 30,
},
},
yAxis: {
type: 'value',
axisLine: { lineStyle: { color: '#3d5269' } },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
axisLabel: { color: '#89DBFF' },
},
series: [
{
name: '图文',
type: 'bar',
data: consultImCount,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(90,191,255,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(30,166,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(30,166,253,0.7)' }, // 边缘实心
]),
},
},
{
name: '视频',
type: 'bar',
data: consultVedioCount,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(60,255,253,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(60,255,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(48,223,221,0.7)' }, // 边缘实心
]),
},
},
],
};
chart.setOption(option);
window.addEventListener('resize', () => chart?.resize());
};
onMounted(() => {
getData();
// initChart();
});
onBeforeUnmount(() => {
chart?.dispose();
});
</script>
<style scoped>
.chart-container {
height: 100%;
/* width: calc(100% / 5); */
border: 1px solid #00ccff;
border-radius: 14px;
background: rgba(8, 75, 100, 0.2);
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
text-align: center;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
}
.chart {
width: 100%;
height: calc(100% - 40px);
}
}
</style>
@@ -0,0 +1,181 @@
<template>
<div class="chart-container">
<div class="title">医院咨询数量统计</div>
<div ref="chartRef" class="chart"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { getHospitalCountStat } from '/@/views/healthConsultation/api/health';
const chartRef = ref<HTMLDivElement | null>(null);
let chart: echarts.ECharts | null = null;
// 格式化医院名称,如果太长则在中间添加换行符
const formatHospitalName = (hospitalName: string, maxLength: number = 8) => {
if (hospitalName.length > maxLength) {
const midIndex = Math.floor(hospitalName.length / 2);
// 寻找最佳断行点,避免在词中间断开
let breakIndex = midIndex;
for (let i = midIndex; i < hospitalName.length; i++) {
const char = hospitalName.charAt(i);
// 如果是中文字符或空格,可以在其后断开
if (/[\u4e00-\u9fa5\s]/.test(char)) {
breakIndex = i + 1;
break;
}
}
// 如果还没找到合适的断行点,则在中间断开
if (breakIndex === midIndex) {
for (let i = midIndex - 1; i > 0; i--) {
const char = hospitalName.charAt(i);
if (/[\u4e00-\u9fa5\s]/.test(char)) {
breakIndex = i + 1;
break;
}
}
}
return hospitalName.slice(0, breakIndex) + '\n' + hospitalName.slice(breakIndex);
}
return hospitalName;
};
function getData() {
getHospitalCountStat()
.then((res: any) => {
if (res.code == 200) {
console.log(res);
// 提取数据
const consultVedioCount = res.result.map((item: any) => item.consultVedioCount);
const consultImCount = res.result.map((item: any) => item.consultImCount);
// 格式化医院名称
const hospitalName = res.result.map((item: any) => formatHospitalName(item.hospitalName));
initChart(hospitalName, consultImCount, consultVedioCount);
}
})
.catch((err) => {
console.log(err);
});
}
const initChart = (hospitalName: string[], consultImCount: number[], consultVedioCount: number[]) => {
if (!chartRef.value) return;
chart = echarts.init(chartRef.value);
const option: echarts.EChartsOption = {
backgroundColor: 'transparent',
// title: {
// text: '单位咨询数量统计',
// left: 'center',
// top: 10,
// textStyle: {
// color: '#fff',
// fontSize: 18,
// },
// },
legend: {
top: 10,
textStyle: { color: '#fff' },
itemWidth: 20,
itemHeight: 16,
itemGap: 30, // 默认 10,这里改成 30,让两段文字隔开一些
// 圆环 icon
// icon: 'path://M512 0a512 512 0 1 0 0 1024A512 512 0 0 0 512 0zm0 896a384 384 0 1 1 0-768 384 384 0 0 1 0 768z',
icon: 'circle',
data: ['图文', '视频'],
},
grid: {
top: 70,
left: 50,
right: 30,
bottom: 70,
},
xAxis: {
type: 'category',
data: hospitalName,
axisLine: { lineStyle: { color: '#3d5269' } },
axisLabel: {
color: '#fff',
fontSize: 10,
// rotate: 30,
interval: 0, // 显示全部标签
},
},
yAxis: {
type: 'value',
axisLine: { lineStyle: { color: '#3d5269' } },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
axisLabel: { color: '#89DBFF' },
},
series: [
{
name: '图文',
type: 'bar',
data: consultImCount,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(90,191,255,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(30,166,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(30,166,253,0.7)' }, // 边缘实心
]),
},
},
{
name: '视频',
type: 'bar',
data: consultVedioCount,
barWidth: 12, // 更细的柱子
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: 'rgba(60,255,253,0.7)' }, // 中心透明
{ offset: 0.5, color: 'rgba(60,255,253,0.4)' }, // 中间过渡
{ offset: 1, color: 'rgba(48,223,221,0.7)' }, // 边缘实心
]),
},
},
],
};
chart.setOption(option);
window.addEventListener('resize', () => chart?.resize());
};
onMounted(() => {
getData();
// initChart();
});
onBeforeUnmount(() => {
chart?.dispose();
});
</script>
<style scoped>
.chart-container {
height: 100%;
/* width: calc(100% / 5); */
border: 1px solid #00ccff;
border-radius: 14px;
background: rgba(8, 75, 100, 0.2);
.title {
height: 40px;
border-radius: 14px 14px 0 0;
font-weight: bold;
font-size: 20px;
letter-spacing: 2px;
text-align: center;
color: #ffffff;
line-height: 40px;
padding: 0 20px;
background: linear-gradient(to right, rgba(8, 75, 100, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
}
.chart {
width: 100%;
height: calc(100% - 40px);
}
}
</style>
@@ -0,0 +1,205 @@
<template>
<swiper :slides-per-view="1" :space-between="10" :loop="true" :autoplay="{ delay: 10000, disableOnInteraction: false }" class="mySwiper">
<swiper-slide v-for="(page, index) in pages" :key="index">
<div class="grid-container">
<div v-for="item in page" :key="item.id" class="item">
<div class="item-left">
<a-image class="item-img" :preview="false" height="100%" :src="getFileUrl(item.photo)" />
</div>
<div class="item-right">
<div class="name">
<span>{{ item.doctorName }}</span>
<span class="position">{{ item.doctorJob_dictText }}</span>
</div>
<div class="hospital">{{ item.resourceName }} | {{ item.departmentName }}</div>
<div class="experience">
<span class="label">经历</span>
{{ item.experience ? item.experience : '暂无' }}
</div>
<div class="goodAt">
<span class="label">擅长</span>
{{ item.goodAt ? item.goodAt : '暂无' }}
</div>
</div>
</div>
</div>
</swiper-slide>
</swiper>
</template>
<script setup lang="ts">
import { onMounted, ref, computed } from 'vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/css';
import 'swiper/css/navigation';
import SwiperCore from 'swiper';
import { Autoplay, Navigation } from 'swiper/modules'; // 修改此处导入路径
// import defaultPng from '/@/assets/health/default.png';
import { Image as AImage } from 'ant-design-vue';
import { getDocList } from '/@/views/healthConsultation/api/health';
function getFileUrl(path?: string) {
const GATEWAY_URL = import.meta.env.VITE_GLOB_API_URL;
if (!path) return '/@/assets/health/default.png'; // 使用默认图片
return `${GATEWAY_URL}/file/show/${path}`;
}
// 安装 Swiper 模块
SwiperCore.use([Autoplay, Navigation]);
interface Doctor {
id: string;
photo?: string;
doctorName: string;
doctorJob_dictText: string;
resourceName: string;
departmentName: string;
experience: string;
goodAt: string;
}
// 将每 6 个元素分为一页
const items = ref<Doctor[]>([]);
const pages = computed(() => {
const result: Doctor[][] = [];
for (let i = 0; i < items.value.length; i += 6) {
result.push(items.value.slice(i, i + 6));
}
return result;
});
function getData() {
getDocList()
.then((res: any) => {
if (res.code == 200) {
items.value = res.result;
}
})
.catch((err) => {
console.log(err);
});
}
onMounted(() => {
getData();
});
</script>
<style scoped lang="less">
.mySwiper {
height: 100%; /* 设置整个轮播高度 */
padding-bottom: 16px;
box-sizing: border-box;
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr); /* 每行平分Swiper高度 */
gap: 10px; /* item 间距 */
height: 100%; /* 占满Swiper高度 */
// padding: 10px; /* 可选:轮播边缘留空 */
// box-sizing: border-box;
.item {
width: 100%;
background: rgba(8, 75, 100, 0.2);
border: 1px solid #00ccff;
border-radius: 14px;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 18px;
transition: transform 0.3s;
padding: 16px;
box-sizing: border-box;
overflow: hidden;
.item-left {
width: 25%;
height: 100%;
overflow: hidden;
border-radius: 8px;
margin-right: 16px;
display: flex;
align-items: center;
.item-img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s;
}
}
.item-right {
flex: 1;
height: 100%;
// display: flex;
// flex-direction: column;
// gap: clamp(10px, 1vw, 40px);
// gap: 8px;
.name {
// height: 10%;
color: #ffc000;
font-size: 23px;
font-weight: bold;
font-family: HarmonyOS Sans SC;
letter-spacing: 1px;
line-height: 34px;
.position {
font-size: 18px;
color: #fff;
}
}
.hospital {
// height: 10%;
font-family: PingFang SC;
font-weight: bold;
font-size: 17px;
// font-size: clamp(14px, 1vw, 50px);
color: #fff;
line-height: 32px;
letter-spacing: 1px;
margin-bottom: 5px;
}
.experience {
// height: 40%;
// height: 57px;
// line-height: 22px;
font-family: PingFang SC;
font-weight: 500;
font-size: 13px;
color: #fff;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 显示3行 */
line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
letter-spacing: 1px;
margin-bottom: 8px;
.label {
color: #82a9ef;
}
}
.goodAt {
// height: 40%;
font-family: PingFang SC;
font-weight: 500;
font-size: 13px;
color: #fff;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 显示3行 */
line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
letter-spacing: 1px;
.label {
color: #82a9ef;
}
}
}
}
}
}
</style>
@@ -0,0 +1,116 @@
<template>
<div class="health-content-top">
<div class="count-item">
<div class="text">入驻专家</div>
<div class="num">{{ countData.docCount }}</div>
</div>
<div class="count-item">
<div class="text">累计咨询</div>
<div class="num">{{ countData.consultCount }}</div>
</div>
<div class="count-item">
<div class="text">咨询人数</div>
<div class="num">{{ countData.consultPersonCount }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { getStaticCount } from '/@/views/healthConsultation/api/health';
interface CountData {
docCount: number;
consultCount: number; // 假设这是“累计咨询”的字段名,请根据实际接口调整
consultPersonCount: number;
}
const countData = ref<CountData>({
docCount: 0,
consultCount: 0,
consultPersonCount: 0,
});
function getData() {
getStaticCount()
.then((res: any) => {
if (res.code == 200) {
countData.value = res.result;
}
})
.catch((err) => {
console.log(err);
});
}
onMounted(() => {
getData();
});
</script>
<style lang="less" scoped>
.health-content-top {
width: 100%;
height: 100%;
// position: absolute;
// left: 50%;
// top: 101px;
// transform: translateX(-50%);
display: flex;
justify-content: space-around;
margin-bottom: 10px;
gap: 20px;
> div {
position: relative;
// &:before {
// position: absolute;
// top: 10px;
// left: 10px;
// // background: #0a2043;
// content: '';
// width: 280px;
// height: 62px;
// z-index: -1;
// }
}
> :nth-child(1) {
background: url('/@/assets/health/healthBlue.png') no-repeat;
background-size: 100% 100%;
}
> :nth-child(2) {
background: url('/@/assets/health/healthGreen.png') no-repeat;
background-size: 100% 100%;
}
> :nth-child(3) {
background: url('/@/assets/health/healthYellow.png') no-repeat;
background-size: 100% 100%;
}
.count-item {
width: calc(100% / 5);
height: 100%;
display: flex;
align-items: center;
justify-content: space-around;
color: #fff;
//background: url('/@/assets/images/footer-num.png') no-repeat;
//border-radius: 14px;
.num {
font-size: 30px;
font-weight: 700;
font-family: HarmonyOS Sans SC;
}
.text {
font-size: 18px;
font-weight: 400;
font-family: HarmonyOS Sans SC;
}
}
}
</style>