<template>
|
<view class="page">
|
<image class="hero-image" :src="heroImage" mode="aspectFill" @error="replaceHero"></image>
|
<view class="hero-shade"></view>
|
<view class="custom-nav">
|
<view class="safe-space" :style="'height:' + navTop + 'px'"></view>
|
<view class="nav-row" :style="'height:' + navHeight + 'px;padding-right:' + navRight + 'px'">
|
<view class="back-button" @tap="goBack"><image src="/static/food-assets/arrow-left-white.svg" mode="aspectFit"></image></view>
|
<view class="capsule-space" :style="'width:' + navWidth + 'px'"></view>
|
</view>
|
</view>
|
|
<view class="content-sheet">
|
<view class="service-row"><text class="service-name">{{benefitTitle}}</text><text class="free-label">{{freeLabel}}</text></view>
|
<view class="section-title"><text>权益详情</text><view></view></view>
|
<scroll-view class="org-scroll" scroll-y :show-scrollbar="false">
|
<view v-if="listLoading" class="list-state"><view class="loading-spinner"></view><text>正在加载服务机构</text></view>
|
<view v-else-if="listError" class="list-state error-state"><text>服务机构加载失败</text><text class="retry-text" @tap="loadOrgs">重新加载</text></view>
|
<view v-else-if="listLoaded && orgs.length == 0" class="list-state"><text>暂无行政审批服务机构</text></view>
|
<text v-if="listLoaded && !benefitAvailable" class="unavailable-text">{{unavailableReason}}</text>
|
<view v-for="item in orgs" :key="item.id" class="org-card">
|
<text class="org-name">{{item.name}}</text>
|
<view class="org-address"><image src="/static/premium-assets/map-pin.png" mode="aspectFit"></image><text>{{item.address}}</text></view>
|
<view class="org-desc"><text>{{item.description}}</text></view>
|
<view class="org-footer">
|
<view v-if="item.phone != ''" class="phone-row" @tap="callOrg(item)"><image src="/static/premium-assets/phone.png" mode="aspectFit"></image><text>咨询电话-{{item.phone}}</text></view>
|
<view v-if="item.hasWindowInfo" class="window-button" hover-class="window-button-active" @tap="showWindowInfo(item)"><text>查看窗口信息</text></view>
|
</view>
|
</view>
|
<view class="bottom-space"></view>
|
</scroll-view>
|
</view>
|
|
<view v-if="popupVisible" class="popup-mask" @tap="hideWindowInfo">
|
<view class="popup-card" @tap.stop="noop">
|
<text class="popup-title">窗口信息</text>
|
<text class="popup-org">{{popupOrgName}}</text>
|
<view v-for="window in popupWindows" :key="window.id" class="popup-row"><view class="popup-dot"></view><text>{{window.name}}{{window.location != '' ? '(' + window.location + ')' : ''}}</text></view>
|
<text class="popup-time">办公时间:{{popupHours}}</text>
|
<view class="popup-close" hover-class="popup-close-active" @tap="hideWindowInfo"><text>我知道了</text></view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script setup lang="uts">
|
import { getAdminApprovalBenefit } from '../../services/portal.uts'
|
import { resolveApiUrl } from '../../services/http.uts'
|
import { safeBack } from '../../utils/navigation.uts'
|
|
const navTop = ref(28)
|
const navHeight = ref(32)
|
const navWidth = ref(88)
|
const navRight = ref(10)
|
const serviceId = ref('')
|
const heroImage = ref('')
|
const benefitTitle = ref('行政审批')
|
const freeLabel = ref('免费')
|
const benefitAvailable = ref(true)
|
const unavailableReason = ref('该权益暂未开放')
|
const orgs = ref<any[]>([])
|
const listLoading = ref(true)
|
const listLoaded = ref(false)
|
const listError = ref(false)
|
const popupVisible = ref(false)
|
const popupOrgName = ref('')
|
const popupHours = ref('')
|
const popupWindows = ref<any[]>([])
|
|
onLoad((options: any) => {
|
// #ifdef MP-WEIXIN
|
const capsule = uni.getMenuButtonBoundingClientRect()
|
const info = uni.getSystemInfoSync()
|
navTop.value = capsule.top
|
navHeight.value = capsule.height
|
navWidth.value = capsule.width
|
navRight.value = info.windowWidth - capsule.right
|
// #endif
|
serviceId.value = options != null && options['serviceId'] != null ? options['serviceId'] as string : ''
|
loadOrgs()
|
})
|
const loadOrgs = () => {
|
listLoading.value = true
|
listLoaded.value = false
|
listError.value = false
|
if (serviceId.value == '') { listLoading.value = false; listError.value = true; return }
|
getAdminApprovalBenefit(serviceId.value, (data: any) => {
|
benefitTitle.value = data.title || '行政审批'
|
freeLabel.value = data.freeLabel || '免费'
|
heroImage.value = data.heroImage != null && data.heroImage != '' ? resolveApiUrl(data.heroImage as string) : ''
|
benefitAvailable.value = data.available === true
|
unavailableReason.value = data.unavailableReason || '该权益暂未开放'
|
orgs.value = data.organizations instanceof Array ? data.organizations as any[] : []
|
listLoading.value = false
|
listLoaded.value = true
|
}, () => { listLoading.value = false; listError.value = true })
|
}
|
const goBack = () => safeBack('/pages/premium-benefits/premium-benefits')
|
const noop = () => {}
|
const replaceHero = () => { heroImage.value = '' }
|
const callOrg = (item: any) => { if (item.phone == null || item.phone == '') { uni.showToast({ title: '机构暂未提供咨询电话', icon: 'none' }); return }; uni.makePhoneCall({ phoneNumber: item.phone, fail: () => uni.showToast({ title: '暂时无法拨打电话', icon: 'none' }) }) }
|
const showWindowInfo = (item: any) => {
|
if (!(item.windows instanceof Array) || item.windows.length == 0) return
|
popupOrgName.value = item.name || ''
|
popupHours.value = item.officeHours || '以机构公示时间为准'
|
popupWindows.value = item.windows as any[]
|
popupVisible.value = true
|
}
|
const hideWindowInfo = () => { popupVisible.value = false }
|
</script>
|
|
<style>
|
.page { width:100%; height:100vh; position:relative; overflow:hidden; background-color:#F5F5F5; }
|
.hero-image { position:absolute; left:0; right:0; top:0; width:100%; height:425rpx; background-color:#C6D2DE; }
|
.hero-shade { position:absolute; z-index:1; left:0; right:0; top:0; height:210rpx; background-image:linear-gradient(180deg,rgba(0,0,0,.55),rgba(0,0,0,0)); }
|
.custom-nav { position:absolute; z-index:10; left:0; right:0; top:0; }
|
.safe-space { height:28px; }
|
.nav-row { display:flex; box-sizing:border-box; padding-left:24rpx; flex-direction:row; align-items:center; justify-content:space-between; }
|
.back-button { display:flex; width:54rpx; height:54rpx; border-radius:50%; background-color:rgba(45,45,45,.38); justify-content:center; align-items:center; }
|
.back-button image { width:38rpx; height:38rpx; }
|
.capsule-space { height:100%; flex-shrink:0; }
|
.content-sheet { display:flex; position:absolute; z-index:3; left:0; right:0; top:405rpx; bottom:0; box-sizing:border-box; padding:28rpx 25rpx 0; border-radius:30rpx 30rpx 0 0; background-color:#F5F5F5; flex-direction:column; }
|
.service-row { display:flex; height:64rpx; padding:0 10rpx; flex-direction:row; justify-content:space-between; align-items:center; flex-shrink:0; }
|
.service-name { color:#252525; font-size:35rpx; line-height:48rpx; font-weight:700; }
|
.free-label { color:#FF7A27; font-size:24rpx; }
|
.section-title { display:flex; height:84rpx; margin-top:15rpx; padding-left:20rpx; flex-direction:column; align-items:flex-start; flex-shrink:0; }
|
.section-title text { color:#756B67; font-size:31rpx; line-height:42rpx; font-weight:600; }
|
.section-title view { width:61rpx; height:7rpx; margin:10rpx 0 0 28rpx; border-radius:4rpx; background-image:linear-gradient(90deg,#FF4C56,#FFD43A); }
|
.org-scroll { min-height:0; flex:1; }
|
.list-state { display:flex; height:360rpx; flex-direction:row; justify-content:center; align-items:center; color:#969CA5; font-size:25rpx; }
|
.error-state { flex-direction:column; }
|
.retry-text { margin-top:20rpx; color:#FF742A; }
|
.unavailable-text { display:block; margin:0 20rpx 20rpx; color:#D96B3B; font-size:24rpx; line-height:34rpx; }
|
.loading-spinner { width:28rpx; height:28rpx; margin-right:13rpx; box-sizing:border-box; border:3rpx solid #FFD6C4; border-top-color:#FF6C2B; border-radius:50%; animation:org-loading 720ms linear infinite; }
|
@keyframes org-loading { from { transform:rotate(0deg); } to { transform:rotate(360deg); } }
|
.org-card { display:flex; margin:0 0 22rpx; box-sizing:border-box; padding:28rpx 26rpx; border-radius:15rpx; background-color:#FFFFFF; flex-direction:column; }
|
.org-name { color:#252525; font-size:30rpx; line-height:42rpx; font-weight:700; }
|
.org-address { display:flex; margin-top:16rpx; box-sizing:border-box; padding:7rpx 10rpx; border-radius:7rpx; background-image:linear-gradient(90deg,rgba(239,240,242,.98),rgba(242,243,245,.76) 58%,rgba(255,255,255,0)); flex-direction:row; align-items:center; }
|
.org-address image { width:26rpx; height:26rpx; margin-right:8rpx; flex-shrink:0; }
|
.org-address text { min-width:0; flex:1; color:#7E8490; font-size:24rpx; line-height:34rpx; }
|
.org-desc { margin-top:18rpx; box-sizing:border-box; padding:20rpx 22rpx; border-radius:12rpx; background-color:#F5F6F8; }
|
.org-desc text { color:#727983; font-size:25rpx; line-height:40rpx; }
|
.org-footer { display:flex; min-height:56rpx; margin-top:20rpx; flex-direction:row; justify-content:space-between; align-items:center; }
|
.phone-row { display:flex; flex-direction:row; align-items:center; }
|
.phone-row image { width:28rpx; height:28rpx; margin-right:10rpx; flex-shrink:0; }
|
.phone-row text { color:#FF7A27; font-size:26rpx; line-height:36rpx; }
|
.window-button { display:flex; box-sizing:border-box; padding:10rpx 26rpx; border:2rpx solid #FF8A3C; border-radius:30rpx; background-color:#FFFFFF; justify-content:center; align-items:center; }
|
.window-button text { color:#FF7A27; font-size:24rpx; line-height:32rpx; }
|
.window-button-active { opacity:.7; }
|
.bottom-space { height:calc(30rpx + env(safe-area-inset-bottom)); }
|
.popup-mask { display:flex; position:fixed; z-index:30; left:0; right:0; top:0; bottom:0; background-color:rgba(0,0,0,.5); justify-content:center; align-items:center; }
|
.popup-card { display:flex; width:600rpx; box-sizing:border-box; padding:40rpx; border-radius:24rpx; background-color:#FFFFFF; flex-direction:column; }
|
.popup-title { color:#252525; font-size:32rpx; line-height:44rpx; font-weight:700; text-align:center; }
|
.popup-org { margin-top:24rpx; color:#363636; font-size:27rpx; line-height:38rpx; font-weight:600; }
|
.popup-row { display:flex; margin-top:14rpx; flex-direction:row; align-items:center; }
|
.popup-dot { width:10rpx; height:10rpx; margin-right:12rpx; border-radius:50%; background-color:#FF7A27; flex-shrink:0; }
|
.popup-row text { color:#5A5F66; font-size:25rpx; line-height:36rpx; }
|
.popup-time { margin-top:20rpx; color:#8A8D92; font-size:23rpx; line-height:32rpx; }
|
.popup-close { display:flex; height:76rpx; margin-top:30rpx; border-radius:38rpx; background-image:linear-gradient(90deg,#FF4B32,#FF8A1E); justify-content:center; align-items:center; }
|
.popup-close text { color:#FFFFFF; font-size:28rpx; font-weight:600; }
|
.popup-close-active { opacity:.8; }
|
</style>
|