健康咨询平台大屏
This commit is contained in:
Generated
+19331
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -34,7 +34,7 @@
|
|||||||
"postcss-px2rem": "^0.3.0",
|
"postcss-px2rem": "^0.3.0",
|
||||||
"prettier": "^3.1.0",
|
"prettier": "^3.1.0",
|
||||||
"qs": "^6.11.2",
|
"qs": "^6.11.2",
|
||||||
"vite": "^7.0.5",
|
"swiper": "^12.0.2",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"vue3-seamless-scroll": "^2.0.1"
|
"vue3-seamless-scroll": "^2.0.1"
|
||||||
},
|
},
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||||
"@typescript-eslint/parser": "^6.15.0",
|
"@typescript-eslint/parser": "^6.15.0",
|
||||||
"@vitejs/plugin-vue": "^4.2.3",
|
"@vitejs/plugin-vue": "^4.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||||
"ant-design-vue": "^3.2.20",
|
"ant-design-vue": "^3.2.20",
|
||||||
"eslint": "^8.51.0",
|
"eslint": "^8.51.0",
|
||||||
"eslint-config-prettier": "^8.10.0",
|
"eslint-config-prettier": "^8.10.0",
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
"vite": "^4.4.5",
|
"vite": "^5.4.20",
|
||||||
"vite-plugin-resolve-externals": "^0.2.2",
|
"vite-plugin-resolve-externals": "^0.2.2",
|
||||||
"vue-tsc": "^1.8.5"
|
"vue-tsc": "^1.8.5"
|
||||||
}
|
}
|
||||||
|
|||||||
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
@@ -19,13 +19,21 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
component: () => import('/@/views/sys/login.vue'),
|
component: () => import('/@/views/sys/login.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/home',
|
path: '/home2',
|
||||||
name: 'index',
|
name: 'index2',
|
||||||
meta: {
|
meta: {
|
||||||
title: '副屏',
|
title: '副屏',
|
||||||
},
|
},
|
||||||
component: () => import('/@/views/indexSun.vue'),
|
component: () => import('/@/views/indexSun.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/home',
|
||||||
|
name: 'index',
|
||||||
|
meta: {
|
||||||
|
title: '健康咨询',
|
||||||
|
},
|
||||||
|
component: () => import('../views/healthConsultation/HealthConsultationIndex.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/indexSon',
|
path: '/indexSon',
|
||||||
name: '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>
|
||||||
Reference in New Issue
Block a user