tmp
This commit is contained in:
34
app.js
34
app.js
@@ -30,15 +30,35 @@ App({
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
this.globalData.hospitalContactReady = new Promise((resolve) => {
|
this.globalData.hospitalInfoReady = new Promise((resolve) => {
|
||||||
API.resource.getHospitalContact().then((data) => {
|
API.resource.getHospitalInfo().then((data) => {
|
||||||
this.globalData.hospitalContact = data.data.hospitalContact
|
this.globalData.hospitalInfo = data.data.hospitalInfo
|
||||||
resolve(data.data.hospitalContact)
|
resolve(data.data.hospitalInfo)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error('获取医院联系电话失败', err)
|
console.error('获取医院信息失败', err)
|
||||||
resolve([])
|
resolve([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.globalData.hospitalRankingReady = new Promise((resolve) => {
|
||||||
|
API.resource.getHospitalRanking().then((data) => {
|
||||||
|
this.globalData.hospitalRanking = data.data.hospitalRanking
|
||||||
|
resolve(data.data.hospitalRanking)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('获取医院排名失败', err)
|
||||||
|
resolve([])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.globalData.departmentRankingsReady = new Promise((resolve) => {
|
||||||
|
API.resource.getDepartmentRankings().then((data) => {
|
||||||
|
this.globalData.departmentRankings = data.data.departmentRankings
|
||||||
|
resolve(data.data.departmentRankings)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('获取科室排名失败', err)
|
||||||
|
resolve([])
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow(options) {
|
onShow(options) {
|
||||||
@@ -96,6 +116,8 @@ App({
|
|||||||
chatSocket: null,
|
chatSocket: null,
|
||||||
services: [],
|
services: [],
|
||||||
agreement: null,
|
agreement: null,
|
||||||
hospitalContact: [],
|
hospitalInfo: [],
|
||||||
|
hospitalRanking: [],
|
||||||
|
departmentRankings: [],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
3
app.json
3
app.json
@@ -8,7 +8,8 @@
|
|||||||
"pages/escort/agreement",
|
"pages/escort/agreement",
|
||||||
"pages/mine/mine",
|
"pages/mine/mine",
|
||||||
"pages/mine/about",
|
"pages/mine/about",
|
||||||
"pages/hospital/contact"
|
"pages/hospital/contact",
|
||||||
|
"pages/hospital/ranking"
|
||||||
],
|
],
|
||||||
"window": {
|
"window": {
|
||||||
"backgroundTextStyle": "light",
|
"backgroundTextStyle": "light",
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ Page({
|
|||||||
],
|
],
|
||||||
tools: [
|
tools: [
|
||||||
{ id: 1, name: '医院电话', icon: 'call', url: 'pages/hospital/contact', type: 'page' },
|
{ id: 1, name: '医院电话', icon: 'call', url: 'pages/hospital/contact', type: 'page' },
|
||||||
{ id: 2, name: '科室排行', icon: 'ai-coordinate-system', url: '', type: '' },
|
{ id: 2, name: '科室排行', icon: 'ai-coordinate-system', url: 'pages/hospital/ranking', type: 'page' },
|
||||||
{ id: 3, name: '医保备案', icon: 'system-code', url: '', type: '' },
|
{ id: 3, name: '医保备案', icon: 'system-code', url: '#小程序://异地备案/FfXUvTLmNptZx5E', type: 'wxapp' },
|
||||||
{ id: 4, name: '医疗影像', icon: 'film-1', url: '', type: '' }
|
{ id: 4, name: '医疗影像', icon: 'film-1', url: 'https://www.114yygh.com/', type: 'website' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -67,6 +67,9 @@ Page({
|
|||||||
case 'website':
|
case 'website':
|
||||||
wx.navigateTo({ url: '/pages/webview/index?url=' + encodeURIComponent(item.url) });
|
wx.navigateTo({ url: '/pages/webview/index?url=' + encodeURIComponent(item.url) });
|
||||||
break;
|
break;
|
||||||
|
case 'wxapp':
|
||||||
|
wx.navigateToMiniProgram({ shortLink: item.url, env: 'release' })
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wx.showToast({
|
wx.showToast({
|
||||||
title: '建设中, 请电话联系!',
|
title: '建设中, 请电话联系!',
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<view class="assist-grid">
|
<view class="assist-grid">
|
||||||
<view class="assist-item" wx:for="{{ escortServices }}" wx:key="id" bindtap="goToAssistDetail" data-id="{{ item.id }}">
|
<view class="assist-item" wx:for="{{ escortServices }}" wx:key="id" bindtap="goToAssistDetail" data-id="{{ item.id }}">
|
||||||
<view class="assist-icon-circle">
|
<view class="assist-icon-circle">
|
||||||
<t-icon name="{{ item.icon }}" class="assist-icon" style="color: #2D6A4F;" />
|
<t-icon name="{{ item.icon }}" class="assist-icon" />
|
||||||
</view>
|
</view>
|
||||||
<text class="assist-name">{{ item.name }}</text>
|
<text class="assist-name">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<view class="assist-grid">
|
<view class="assist-grid">
|
||||||
<view class="assist-item" wx:for="{{ tools }}" wx:key="id" bindtap="goToOtherServicesDetail" data-item="{{ item }}">
|
<view class="assist-item" wx:for="{{ tools }}" wx:key="id" bindtap="goToOtherServicesDetail" data-item="{{ item }}">
|
||||||
<view class="assist-icon-circle">
|
<view class="assist-icon-circle">
|
||||||
<t-icon name="{{ item.icon }}" class="assist-icon" style="color: #2D6A4F;" />
|
<t-icon name="{{ item.icon }}" class="assist-icon" />
|
||||||
</view>
|
</view>
|
||||||
<text class="assist-name">{{ item.name }}</text>
|
<text class="assist-name">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
<view class="assist-grid">
|
<view class="assist-grid">
|
||||||
<view class="assist-item" wx:for="{{ otherServices }}" wx:key="id" bindtap="goToOtherServicesDetail" data-item="{{ item }}">
|
<view class="assist-item" wx:for="{{ otherServices }}" wx:key="id" bindtap="goToOtherServicesDetail" data-item="{{ item }}">
|
||||||
<view class="assist-icon-circle">
|
<view class="assist-icon-circle">
|
||||||
<t-icon name="{{ item.icon }}" class="assist-icon" style="color: #2D6A4F;" />
|
<t-icon name="{{ item.icon }}" class="assist-icon" />
|
||||||
</view>
|
</view>
|
||||||
<text class="assist-name">{{ item.name }}</text>
|
<text class="assist-name">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<view class="container">
|
<view class="container">
|
||||||
<view class="header">
|
<view class="header">
|
||||||
<text class="title">北京主要医院联系电话</text>
|
<text class="title">主要医院联系电话</text>
|
||||||
<text class="subtitle">持续更新中, 仅供参考</text>
|
<text class="subtitle">持续更新中, 仅供参考</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -8,14 +8,14 @@
|
|||||||
<text>加载中...</text>
|
<text>加载中...</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:elif="{{hospitalContact.length === 0}}" class="empty">
|
<view wx:elif="{{hospitalInfo.length === 0}}" class="empty">
|
||||||
<text>暂无医院联系信息</text>
|
<text>暂无医院信息</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view wx:else class="list">
|
<view wx:else class="list">
|
||||||
<view
|
<view
|
||||||
class="item"
|
class="item"
|
||||||
wx:for="{{hospitalContact}}"
|
wx:for="{{hospitalInfo}}"
|
||||||
wx:key="id"
|
wx:key="id"
|
||||||
>
|
>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
@@ -26,10 +26,10 @@
|
|||||||
wx:for="{{item.phone}}"
|
wx:for="{{item.phone}}"
|
||||||
wx:for-item="phone"
|
wx:for-item="phone"
|
||||||
wx:key="*this"
|
wx:key="*this"
|
||||||
data-phone="{{phone}}"
|
data-phone="{{phone.number}}"
|
||||||
bindtap="onCallPhone"
|
bindtap="onCallPhone"
|
||||||
>
|
>
|
||||||
<text class="phone">{{phone}}</text>
|
<text class="phone">{{phone.number}} </text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -39,36 +39,36 @@ page {
|
|||||||
/* Header区域 */
|
/* Header区域 */
|
||||||
.header {
|
.header {
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
padding: 24rpx 32rpx 40rpx 32rpx;
|
padding: 16rpx 24rpx 20rpx 24rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 12rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 40rpx;
|
font-size: 32rpx;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #1F2937;
|
color: #1F2937;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 26rpx;
|
font-size: 24rpx;
|
||||||
color: #9CA3AF;
|
color: #9CA3AF;
|
||||||
margin-top: 12rpx;
|
margin-top: 6rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 加载和空状态 */
|
/* 加载和空状态 */
|
||||||
.loading,
|
.loading,
|
||||||
.empty {
|
.empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 120rpx 32rpx;
|
padding: 80rpx 24rpx;
|
||||||
color: #9CA3AF;
|
color: #9CA3AF;
|
||||||
font-size: 28rpx;
|
font-size: 26rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 列表区域 */
|
/* 列表区域 */
|
||||||
.list {
|
.list {
|
||||||
padding: 0 32rpx;
|
padding: 0 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
@@ -76,11 +76,11 @@ page {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border-radius: 24rpx;
|
border-radius: 16rpx;
|
||||||
padding: 32rpx;
|
padding: 20rpx 24rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 12rpx;
|
||||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.04);
|
||||||
border: 2rpx solid #F0F0F0;
|
border: 1rpx solid #F0F0F0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
@@ -92,10 +92,10 @@ page {
|
|||||||
|
|
||||||
.name {
|
.name {
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
font-weight: 700;
|
font-weight: 600;
|
||||||
color: #1F2937;
|
color: #1F2937;
|
||||||
line-height: 1.4;
|
line-height: 1.3;
|
||||||
margin-bottom: 16rpx;
|
margin-bottom: 10rpx;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,31 +103,31 @@ page {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 12rpx;
|
gap: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phone-wrap {
|
.phone-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12rpx;
|
gap: 8rpx;
|
||||||
padding: 12rpx 20rpx;
|
padding: 8rpx 14rpx;
|
||||||
background: #F5F7F6;
|
background: #F5F7F6;
|
||||||
border-radius: 12rpx;
|
border-radius: 8rpx;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phone {
|
.phone {
|
||||||
font-size: 28rpx;
|
font-size: 26rpx;
|
||||||
color: #2D6A4F;
|
color: #2D6A4F;
|
||||||
line-height: 1.4;
|
line-height: 1.3;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action {
|
.action {
|
||||||
margin-left: 24rpx;
|
margin-left: 16rpx;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 40rpx;
|
font-size: 36rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
192
pages/hospital/ranking.js
Normal file
192
pages/hospital/ranking.js
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
// pages/hospital/ranking.js
|
||||||
|
const app = getApp()
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
activeTab: 'overall',
|
||||||
|
searchKeyword: '',
|
||||||
|
selectedDepartment: '',
|
||||||
|
rankingYear: '',
|
||||||
|
rankingNote: '',
|
||||||
|
departmentList: [],
|
||||||
|
allHospitals: [],
|
||||||
|
filteredHospitals: [],
|
||||||
|
currentDepartmentRanking: {
|
||||||
|
top10: [],
|
||||||
|
nominated: []
|
||||||
|
},
|
||||||
|
hospitalRankingData: null,
|
||||||
|
departmentRankingsData: null
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options) {
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
if (!this.data.hospitalRankingData || !this.data.departmentRankingsData) {
|
||||||
|
this.loadData()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadData() {
|
||||||
|
try {
|
||||||
|
const appData = app.globalData
|
||||||
|
|
||||||
|
let hospitalRanking = appData.hospitalRanking
|
||||||
|
let departmentRankings = appData.departmentRankings
|
||||||
|
|
||||||
|
if (!hospitalRanking) {
|
||||||
|
hospitalRanking = await appData.hospitalRankingReady
|
||||||
|
}
|
||||||
|
if (!departmentRankings) {
|
||||||
|
departmentRankings = await appData.departmentRankingsReady
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
hospitalRankingData: hospitalRanking,
|
||||||
|
departmentRankingsData: departmentRankings
|
||||||
|
})
|
||||||
|
|
||||||
|
this.processHospitalRanking(hospitalRanking)
|
||||||
|
this.processDepartmentRankings(departmentRankings)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载排行榜数据失败', err)
|
||||||
|
wx.showToast({
|
||||||
|
title: '数据加载失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
processHospitalRanking(data) {
|
||||||
|
if (!data || !data.rankings) return
|
||||||
|
|
||||||
|
const gradeClassMap = {
|
||||||
|
'A+++++': 'grade-a5',
|
||||||
|
'A++++': 'grade-a4',
|
||||||
|
'A+++': 'grade-a3',
|
||||||
|
'A++': 'grade-a2',
|
||||||
|
'A+': 'grade-a1'
|
||||||
|
}
|
||||||
|
|
||||||
|
const hospitals = data.rankings.map(item => {
|
||||||
|
const allDeps = (item.depart || [])
|
||||||
|
.sort((a, b) => a.rank - b.rank)
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
gradeClass: gradeClassMap[item.grade] || 'grade-a1',
|
||||||
|
topDepartments: allDeps,
|
||||||
|
expanded: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
rankingYear: data.year || '',
|
||||||
|
rankingNote: data.note || '',
|
||||||
|
allHospitals: hospitals,
|
||||||
|
filteredHospitals: hospitals
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
processDepartmentRankings(data) {
|
||||||
|
if (!data || !data.departments) return
|
||||||
|
|
||||||
|
const departments = Object.keys(data.departments)
|
||||||
|
const firstDept = departments[0] || ''
|
||||||
|
|
||||||
|
this.setData({
|
||||||
|
departmentList: departments,
|
||||||
|
selectedDepartment: firstDept
|
||||||
|
})
|
||||||
|
|
||||||
|
if (firstDept) {
|
||||||
|
this.updateCurrentDepartmentRanking(firstDept)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateCurrentDepartmentRanking(deptName) {
|
||||||
|
const data = this.data.departmentRankingsData
|
||||||
|
if (!data || !data.departments || !data.departments[deptName]) {
|
||||||
|
this.setData({
|
||||||
|
currentDepartmentRanking: { top10: [], nominated: [] }
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const deptData = data.departments[deptName]
|
||||||
|
this.setData({
|
||||||
|
currentDepartmentRanking: {
|
||||||
|
top10: deptData.top10 || [],
|
||||||
|
nominated: deptData.nominated || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
switchTab(e) {
|
||||||
|
const tab = e.currentTarget.dataset.tab
|
||||||
|
if (tab === this.data.activeTab) return
|
||||||
|
this.setData({ activeTab: tab })
|
||||||
|
},
|
||||||
|
|
||||||
|
selectDepartment(e) {
|
||||||
|
const dept = e.currentTarget.dataset.dept
|
||||||
|
this.setData({ selectedDepartment: dept })
|
||||||
|
this.updateCurrentDepartmentRanking(dept)
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearchInput(e) {
|
||||||
|
const keyword = e.detail.value
|
||||||
|
this.setData({ searchKeyword: keyword })
|
||||||
|
this.filterHospitals(keyword)
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearch(e) {
|
||||||
|
const keyword = e.detail.value
|
||||||
|
this.filterHospitals(keyword)
|
||||||
|
},
|
||||||
|
|
||||||
|
clearSearch() {
|
||||||
|
this.setData({ searchKeyword: '' })
|
||||||
|
this.filterHospitals('')
|
||||||
|
},
|
||||||
|
|
||||||
|
filterHospitals(keyword) {
|
||||||
|
let result = this.data.allHospitals
|
||||||
|
|
||||||
|
if (keyword && keyword.trim()) {
|
||||||
|
const lowerKeyword = keyword.trim().toLowerCase()
|
||||||
|
result = result.filter(item => {
|
||||||
|
const nameMatch = item.name && item.name.toLowerCase().includes(lowerKeyword)
|
||||||
|
const deptMatch = item.depart && item.depart.some(d => d.name && d.name.toLowerCase().includes(lowerKeyword))
|
||||||
|
return nameMatch || deptMatch
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setData({ filteredHospitals: result })
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleHospital(e) {
|
||||||
|
const name = e.currentTarget.dataset.name
|
||||||
|
const hospitals = this.data.filteredHospitals.map(item => {
|
||||||
|
if (item.name === name) {
|
||||||
|
return { ...item, expanded: !item.expanded }
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
this.setData({ filteredHospitals: hospitals })
|
||||||
|
},
|
||||||
|
|
||||||
|
onPullDownRefresh() {
|
||||||
|
this.loadData().finally(() => {
|
||||||
|
wx.stopPullDownRefresh()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage() {
|
||||||
|
return {
|
||||||
|
title: '复旦中国医院排行榜',
|
||||||
|
path: '/pages/hospital/ranking'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
6
pages/hospital/ranking.json
Normal file
6
pages/hospital/ranking.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {},
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"backgroundTextStyle": "dark",
|
||||||
|
"navigationBarTitleText": "医院排行榜"
|
||||||
|
}
|
||||||
104
pages/hospital/ranking.wxml
Normal file
104
pages/hospital/ranking.wxml
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<!--pages/hospital/ranking.wxml-->
|
||||||
|
<view class="container">
|
||||||
|
<!-- 顶部标题 -->
|
||||||
|
<view class="header">
|
||||||
|
<text class="header-title">{{rankingYear}}复旦中国医院排行榜</text>
|
||||||
|
<text class="header-note">{{rankingNote}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- Tab 切换 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view class="tab-item {{activeTab === 'overall' ? 'active' : ''}}" bindtap="switchTab" data-tab="overall">
|
||||||
|
<text class="tab-text">综合榜</text>
|
||||||
|
<view class="tab-line" wx:if="{{activeTab === 'overall'}}"></view>
|
||||||
|
</view>
|
||||||
|
<view class="tab-item {{activeTab === 'department' ? 'active' : ''}}" bindtap="switchTab" data-tab="department">
|
||||||
|
<text class="tab-text">专科榜</text>
|
||||||
|
<view class="tab-line" wx:if="{{activeTab === 'department'}}"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 综合榜内容 -->
|
||||||
|
<view class="content" wx:if="{{activeTab === 'overall'}}">
|
||||||
|
<!-- 医院列表 -->
|
||||||
|
<view class="hospital-list">
|
||||||
|
<view class="hospital-card" wx:for="{{filteredHospitals}}" wx:key="name" bindtap="toggleHospital" data-name="{{item.name}}">
|
||||||
|
<view class="hospital-rank-badge">
|
||||||
|
<text class="rank-grade {{item.gradeClass}}">{{item.grade}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="hospital-header">
|
||||||
|
<view class="hospital-info">
|
||||||
|
<text class="hospital-name">{{item.name}}</text>
|
||||||
|
<view class="hospital-tags">
|
||||||
|
<text class="tag" wx:for="{{item.topDepartments}}" wx:for-item="dep" wx:key="name">{{dep.name}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="hospital-arrow">
|
||||||
|
<t-icon name="chevron-down" size="36rpx" color="#999" class="{{item.expanded ? 'arrow-up' : ''}}"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 展开详情 -->
|
||||||
|
<view class="hospital-detail" wx:if="{{item.expanded}}">
|
||||||
|
<view class="detail-title">专科排名详情</view>
|
||||||
|
<view class="dept-grid">
|
||||||
|
<view class="dept-item" wx:for="{{item.depart}}" wx:for-item="dep" wx:key="name">
|
||||||
|
<text class="dept-name">{{dep.name}}</text>
|
||||||
|
<view class="dept-rank">
|
||||||
|
<text class="rank-num">第{{dep.rank}}名</text>
|
||||||
|
<text class="rank-score">{{dep.score}}分</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 专科榜内容 -->
|
||||||
|
<view class="content" wx:if="{{activeTab === 'department'}}">
|
||||||
|
<!-- 科室筛选 -->
|
||||||
|
<scroll-view class="dept-filter" scroll-y enhanced show-scrollbar="{{true}}" style="height: calc(100vh - 340rpx);">
|
||||||
|
<view class="dept-sidebar">
|
||||||
|
<view class="sidebar-item {{selectedDepartment === item ? 'active' : ''}}" wx:for="{{departmentList}}" wx:key="*this" bindtap="selectDepartment" data-dept="{{item}}">
|
||||||
|
<text class="sidebar-text">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 科室排名详情 -->
|
||||||
|
<view class="dept-ranking-content">
|
||||||
|
<view class="dept-ranking-header">
|
||||||
|
<text class="dept-ranking-title">{{selectedDepartment}}</text>
|
||||||
|
<text class="dept-ranking-subtitle">{{rankingYear}}年度专科声誉排名</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- Top10 列表 -->
|
||||||
|
<view class="top10-list">
|
||||||
|
<view class="top10-item {{index < 3 ? 'top3' : ''}}" wx:for="{{currentDepartmentRanking.top10}}" wx:key="name">
|
||||||
|
<view class="top10-rank">
|
||||||
|
<text class="rank-badge" wx:if="{{index < 3}}">{{item.rank}}</text>
|
||||||
|
<text class="rank-num" wx:else>{{item.rank}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="top10-info">
|
||||||
|
<text class="top10-name">{{item.name}}</text>
|
||||||
|
<text class="top10-score">{{item.score}}分</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 获提名医院 -->
|
||||||
|
<view class="nominated-section" wx:if="{{currentDepartmentRanking.nominated && currentDepartmentRanking.nominated.length > 0}}">
|
||||||
|
<view class="nominated-title">获提名医院</view>
|
||||||
|
<view class="nominated-list">
|
||||||
|
<text class="nominated-item" wx:for="{{currentDepartmentRanking.nominated}}" wx:key="*this">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<view class="empty-state" wx:if="{{activeTab === 'overall' && filteredHospitals.length === 0}}">
|
||||||
|
<t-icon name="info-circle" size="80rpx" color="#ccc"/>
|
||||||
|
<text class="empty-text">未找到匹配的医院</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
450
pages/hospital/ranking.wxss
Normal file
450
pages/hospital/ranking.wxss
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
/* pages/hospital/ranking.wxss */
|
||||||
|
page {
|
||||||
|
background: linear-gradient(180deg, #E8F5E9 0%, #F1F8F2 30%, #F5FAF6 100%);
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-bottom: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 顶部标题 ========== */
|
||||||
|
.header {
|
||||||
|
padding: 32rpx 32rpx 16rpx 32rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1F2937;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-note {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #9CA3AF;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 搜索栏 ========== */
|
||||||
|
.search-bar {
|
||||||
|
padding: 16rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
padding: 16rpx 24rpx;
|
||||||
|
box-shadow: 0 2rpx 12rpx rgba(45, 106, 79, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1F2937;
|
||||||
|
margin-left: 16rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input::placeholder {
|
||||||
|
color: #9CA3AF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-clear {
|
||||||
|
padding: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== Tab 切换 ========== */
|
||||||
|
.tab-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 32rpx;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
border-bottom: 1rpx solid rgba(45, 106, 79, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
position: relative;
|
||||||
|
padding: 24rpx 48rpx;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #6B7280;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: #2D6A4F;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 48rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
background: linear-gradient(90deg, #2D6A4F 0%, #40916C 100%);
|
||||||
|
border-radius: 2rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 综合榜内容 ========== */
|
||||||
|
.content {
|
||||||
|
padding: 0 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 医院列表 */
|
||||||
|
.hospital-list {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-card {
|
||||||
|
position: relative;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(45, 106, 79, 0.08);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-rank-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-rank-badge .rank-grade {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
border-radius: 0 20rpx 0 12rpx;
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
min-width: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx 100rpx 24rpx 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
min-width: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade.grade-a5 {
|
||||||
|
background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);
|
||||||
|
color: #92400E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade.grade-a4 {
|
||||||
|
background: linear-gradient(135deg, #DBEAFE 0%, #BFDBFE 100%);
|
||||||
|
color: #1E40AF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade.grade-a3 {
|
||||||
|
background: linear-gradient(135deg, #D1FAE5 0%, #A7F3D0 100%);
|
||||||
|
color: #065F46;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade.grade-a2 {
|
||||||
|
background: linear-gradient(135deg, #E0E7FF 0%, #C7D2FE 100%);
|
||||||
|
color: #3730A3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-grade.grade-a1 {
|
||||||
|
background: linear-gradient(135deg, #F3E8FF 0%, #E9D5FF 100%);
|
||||||
|
color: #6B21A8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1F2937;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #2D6A4F;
|
||||||
|
background: rgba(45, 106, 79, 0.08);
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hospital-arrow {
|
||||||
|
margin-left: 16rpx;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-up {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 医院详情展开 */
|
||||||
|
.hospital-detail {
|
||||||
|
padding: 0 24rpx 24rpx 24rpx;
|
||||||
|
border-top: 1rpx solid rgba(45, 106, 79, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #374151;
|
||||||
|
padding: 16rpx 0 12rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-item {
|
||||||
|
background: #F9FAFB;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 12rpx 16rpx;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200rpx;
|
||||||
|
max-width: calc(50% - 6rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-name {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #4B5563;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-rank {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-num {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #2D6A4F;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-score {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #9CA3AF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 专科榜内容 ========== */
|
||||||
|
.content:has(.dept-filter) {
|
||||||
|
display: flex;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-filter {
|
||||||
|
width: 200rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-right: 1rpx solid rgba(45, 106, 79, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-sidebar {
|
||||||
|
padding: 8rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item {
|
||||||
|
padding: 24rpx 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
border-left: 4rpx solid transparent;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item.active {
|
||||||
|
background: #F0FDF4;
|
||||||
|
border-left-color: #2D6A4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #4B5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item.active .sidebar-text {
|
||||||
|
color: #2D6A4F;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-ranking-content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 16rpx 24rpx 24rpx 24rpx;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-ranking-header {
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-ranking-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1F2937;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-ranking-subtitle {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #9CA3AF;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top10 列表 */
|
||||||
|
.top10-list {
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(45, 106, 79, 0.08);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 24rpx;
|
||||||
|
border-bottom: 1rpx solid rgba(45, 106, 79, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item.top3 {
|
||||||
|
background: linear-gradient(90deg, rgba(254, 243, 199, 0.3) 0%, rgba(255, 255, 255, 0) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-rank {
|
||||||
|
margin-right: 20rpx;
|
||||||
|
min-width: 56rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item:nth-child(1) .rank-badge {
|
||||||
|
background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item:nth-child(2) .rank-badge {
|
||||||
|
background: linear-gradient(135deg, #9CA3AF 0%, #6B7280 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-item:nth-child(3) .rank-badge {
|
||||||
|
background: linear-gradient(135deg, #B45309 0%, #92400E 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-num {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6B7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1F2937;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top10-score {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #9CA3AF;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获提名医院 */
|
||||||
|
.nominated-section {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx 24rpx;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(45, 106, 79, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nominated-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #374151;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nominated-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nominated-item {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #4B5563;
|
||||||
|
background: #F9FAFB;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 空状态 ========== */
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 120rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #9CA3AF;
|
||||||
|
margin-top: 24rpx;
|
||||||
|
}
|
||||||
@@ -20,7 +20,9 @@ const API = {
|
|||||||
resource: {
|
resource: {
|
||||||
getServices: (params) => request.get('/health/service', params),
|
getServices: (params) => request.get('/health/service', params),
|
||||||
getAgreement: (params) => request.get('/health/agreement', params),
|
getAgreement: (params) => request.get('/health/agreement', params),
|
||||||
getHospitalContact: (params) => request.get('/health/hospital-contact', params),
|
getHospitalInfo: (params) => request.get('/health/hospital-info', params),
|
||||||
|
getHospitalRanking: (params) => request.get('/health/hospital-ranking', params),
|
||||||
|
getDepartmentRankings: (params) => request.get('/health/department-rankings', params),
|
||||||
},
|
},
|
||||||
|
|
||||||
ai: {
|
ai: {
|
||||||
|
|||||||
Reference in New Issue
Block a user