Merge branch 'master' of https://gitea.zianxin.com/zianxin/biz-mobile-cloud-zax
This commit is contained in:
commit
88fcff26be
4 files changed
+467
-6
No files matched your search
@@ -52,13 +52,21 @@
|
||||
<text class="ht-dates__val">{{ formatMd(query.checkOut) }}</text>
|
||||
</view>
|
||||
</tm-picker-date>
|
||||
<view class="ht-dates__item">
|
||||
<text class="ht-dates__label">共住</text>
|
||||
<text class="ht-dates__val">{{ nightCount }}晚</text>
|
||||
<view class="ht-dates__item" @tap="guestVisible = true">
|
||||
<text class="ht-dates__label">{{ nightCount }}晚 · 间数人数</text>
|
||||
<text class="ht-dates__val">{{ guestSummaryShort }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<hotel-guest-sheet
|
||||
v-model="guestVisible"
|
||||
:rooms="query.rooms"
|
||||
:adults="query.adults"
|
||||
:children="query.children"
|
||||
@confirm="onGuestConfirm"
|
||||
/>
|
||||
|
||||
<!-- 首页带入的城市 / 区域筛选:可一键清除 -->
|
||||
<view v-if="destinationLabel" class="ht-dest">
|
||||
<text class="ht-dest__lab">当前目的地</text>
|
||||
@@ -276,7 +284,11 @@
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<view class="ht-list">
|
||||
<view v-if="state.loading && !state.list.length && !refreshing" class="ht-empty">加载中…</view>
|
||||
<view v-if="state.loading && !state.list.length && !refreshing" class="ht-loading">
|
||||
<tm-icon name="loader-4-line" :size="56" color="#1570ef" spin />
|
||||
<text class="ht-loading__title">正在努力查找酒店中</text>
|
||||
<text class="ht-loading__sub">请稍候…</text>
|
||||
</view>
|
||||
<view v-else-if="!state.list.length" class="ht-empty">暂无符合条件的酒店</view>
|
||||
|
||||
<view v-for="(item, idx) in state.list" :key="item.id" class="ht-card" @tap="goDetail(item)">
|
||||
@@ -319,7 +331,10 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="state.loading && state.list.length" class="ht-empty">加载更多…</view>
|
||||
<view v-if="state.loading && state.list.length" class="ht-loading ht-loading--more">
|
||||
<tm-icon name="loader-4-line" :size="36" color="#1570ef" spin />
|
||||
<text class="ht-loading__sub">正在努力查找更多酒店…</text>
|
||||
</view>
|
||||
<view v-else-if="state.finished && state.list.length" class="ht-empty">没有更多了</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -333,10 +348,12 @@ import dayjs from "dayjs"
|
||||
import { hotelApi } from "@@/api"
|
||||
import { router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import HotelGuestSheet from "@@/components/hotel/hotel-guest-sheet.vue"
|
||||
|
||||
const statusBarHeight = ref(20)
|
||||
const scrollHeight = ref("100vh")
|
||||
const refreshing = ref(false)
|
||||
const guestVisible = ref(false)
|
||||
const panel = ref<"" | "area" | "price" | "score" | "more">("")
|
||||
|
||||
const filterTabs = [
|
||||
@@ -366,10 +383,12 @@ const query = reactive({
|
||||
checkOut: dayjs().add(1, "day").format("YYYY-MM-DD"),
|
||||
rooms: 1,
|
||||
adults: 1,
|
||||
children: 0,
|
||||
})
|
||||
|
||||
const listCheckOutMin = computed(() => dayjs(query.checkIn).add(1, "day").format("YYYY-MM-DD"))
|
||||
const listCheckOutMax = computed(() => dayjs(query.checkIn).add(MAX_STAY_NIGHTS, "day").format("YYYY-MM-DD"))
|
||||
const guestSummaryShort = computed(() => `${query.rooms}间${query.adults + query.children}人`)
|
||||
|
||||
const normalizeListDate = (value: string) => dayjs(String(value || "").replace(/\//g, "-")).format("YYYY-MM-DD")
|
||||
|
||||
@@ -391,6 +410,7 @@ const onListCheckInConfirm = (value: string) => {
|
||||
query.checkOut = dayjs(query.checkIn).add(1, "day").format("YYYY-MM-DD")
|
||||
}
|
||||
clampListStayRange(true)
|
||||
reload()
|
||||
}
|
||||
|
||||
const onListCheckOutConfirm = (value: string) => {
|
||||
@@ -403,6 +423,26 @@ const onListCheckOutConfirm = (value: string) => {
|
||||
}
|
||||
query.checkOut = d
|
||||
clampListStayRange(true)
|
||||
reload()
|
||||
}
|
||||
|
||||
const onGuestConfirm = (v: { rooms: number; adults: number; children: number }) => {
|
||||
query.rooms = v.rooms
|
||||
query.adults = v.adults
|
||||
query.children = v.children
|
||||
hotelApi
|
||||
.saveSearchPref({
|
||||
rooms: query.rooms,
|
||||
adults: query.adults,
|
||||
children: query.children,
|
||||
nights: nightCount.value,
|
||||
city: query.city,
|
||||
keyword: query.keyword,
|
||||
checkIn: query.checkIn,
|
||||
checkOut: query.checkOut,
|
||||
})
|
||||
.catch(() => {})
|
||||
reload()
|
||||
}
|
||||
|
||||
const filter = reactive({
|
||||
@@ -895,6 +935,11 @@ const fetchPage = async (reset = false) => {
|
||||
minPrice: filter.minPrice != null ? filter.minPrice : undefined,
|
||||
maxPrice: filter.maxPrice != null ? filter.maxPrice : undefined,
|
||||
facilityTags: filter.facilityTags.length ? filter.facilityTags.join(",") : undefined,
|
||||
checkIn: query.checkIn || undefined,
|
||||
checkOut: query.checkOut || undefined,
|
||||
rooms: query.rooms || undefined,
|
||||
adults: query.adults || undefined,
|
||||
children: query.children ?? undefined,
|
||||
})
|
||||
const data = res?.data || {}
|
||||
const rows = data.records || []
|
||||
@@ -930,6 +975,8 @@ const goDetail = (item: any) => {
|
||||
checkIn: query.checkIn,
|
||||
checkOut: query.checkOut,
|
||||
rooms: String(query.rooms),
|
||||
adults: String(query.adults),
|
||||
children: String(query.children),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -942,6 +989,7 @@ onLoad((opt: any) => {
|
||||
query.checkOut = opt?.checkOut || query.checkOut
|
||||
query.rooms = Number(opt?.rooms || 1) || 1
|
||||
query.adults = Number(opt?.adults || 1) || 1
|
||||
query.children = Math.max(0, Number(opt?.children || 0) || 0)
|
||||
clampListStayRange(false)
|
||||
layout()
|
||||
loadMeta()
|
||||
@@ -1278,6 +1326,29 @@ onLoad((opt: any) => {
|
||||
font-size: 26rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.ht-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 32rpx 80rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
.ht-loading--more {
|
||||
padding: 32rpx 0 48rpx;
|
||||
flex-direction: row;
|
||||
gap: 12rpx;
|
||||
}
|
||||
.ht-loading__title {
|
||||
margin-top: 8rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #334155;
|
||||
}
|
||||
.ht-loading__sub {
|
||||
font-size: 24rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.ht-hint {
|
||||
width: 100%;
|
||||
font-size: 22rpx;
|
||||
|
||||
@@ -56,6 +56,14 @@
|
||||
</tm-picker-date>
|
||||
</view>
|
||||
|
||||
<view class="ht-guest-row" @tap="guestVisible = true">
|
||||
<view class="ht-guest-row__main">
|
||||
<text class="ht-guest-row__lab">间数人数</text>
|
||||
<text class="ht-guest-row__val">{{ guestSummary }}</text>
|
||||
</view>
|
||||
<tm-icon name="arrow-right-s-line" :size="32" color="#94a3b8" />
|
||||
</view>
|
||||
|
||||
<view class="ht-keyword-wrap">
|
||||
<input
|
||||
class="ht-keyword"
|
||||
@@ -77,6 +85,14 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<hotel-guest-sheet
|
||||
v-model="guestVisible"
|
||||
:rooms="state.rooms"
|
||||
:adults="state.adults"
|
||||
:children="state.children"
|
||||
@confirm="onGuestConfirm"
|
||||
/>
|
||||
|
||||
<!-- 城市选择 -->
|
||||
<view v-if="cityVisible" class="ht-city-mask" @tap="closeCityPicker">
|
||||
<view class="ht-city-sheet" @tap.stop>
|
||||
@@ -121,7 +137,9 @@ import { onShow } from "@dcloudio/uni-app"
|
||||
import dayjs from "dayjs"
|
||||
import { router } from "@@/index"
|
||||
import { useTabbarStore } from "@@/stores/tabbar"
|
||||
import hotelApi from "@@/api/hotel"
|
||||
import TIndexAddress from "@@/components/address/t-index-address/t-index-address.vue"
|
||||
import HotelGuestSheet from "@@/components/hotel/hotel-guest-sheet.vue"
|
||||
|
||||
const DATE_PICKER_MIN = dayjs().format("YYYY-MM-DD")
|
||||
const DATE_PICKER_MAX = dayjs().add(365, "day").format("YYYY-MM-DD")
|
||||
@@ -133,12 +151,17 @@ const hotCities = ["北京", "上海", "广州", "深圳", "杭州", "成都", "
|
||||
|
||||
const cityVisible = ref(false)
|
||||
const cityKeyword = ref("")
|
||||
const guestVisible = ref(false)
|
||||
const prefLoaded = ref(false)
|
||||
|
||||
const state = reactive({
|
||||
city: "",
|
||||
keyword: "",
|
||||
checkIn: dayjs().format("YYYY-MM-DD"),
|
||||
checkOut: dayjs().add(1, "day").format("YYYY-MM-DD"),
|
||||
rooms: 1,
|
||||
adults: 1,
|
||||
children: 0,
|
||||
})
|
||||
|
||||
const nightCount = computed(() => {
|
||||
@@ -146,6 +169,10 @@ const nightCount = computed(() => {
|
||||
return n > 0 ? n : 1
|
||||
})
|
||||
|
||||
const guestSummary = computed(
|
||||
() => `${state.rooms}间 ${state.adults}成人 ${state.children}儿童`,
|
||||
)
|
||||
|
||||
const checkOutPickerMin = computed(() => dayjs(state.checkIn).add(1, "day").format("YYYY-MM-DD"))
|
||||
const checkOutPickerMax = computed(() => dayjs(state.checkIn).add(MAX_STAY_NIGHTS, "day").format("YYYY-MM-DD"))
|
||||
|
||||
@@ -213,13 +240,63 @@ const clearCity = () => {
|
||||
state.city = ""
|
||||
}
|
||||
|
||||
const onGuestConfirm = (v: { rooms: number; adults: number; children: number }) => {
|
||||
state.rooms = v.rooms
|
||||
state.adults = v.adults
|
||||
state.children = v.children
|
||||
}
|
||||
|
||||
const persistSearchPref = async () => {
|
||||
try {
|
||||
await hotelApi.saveSearchPref({
|
||||
rooms: state.rooms,
|
||||
adults: state.adults,
|
||||
children: state.children,
|
||||
nights: nightCount.value,
|
||||
city: state.city,
|
||||
keyword: state.keyword,
|
||||
checkIn: state.checkIn,
|
||||
checkOut: state.checkOut,
|
||||
})
|
||||
} catch {
|
||||
/* 未登录或接口失败不阻断搜索 */
|
||||
}
|
||||
}
|
||||
|
||||
const loadSearchPref = async () => {
|
||||
if (prefLoaded.value) return
|
||||
try {
|
||||
const res: any = await hotelApi.getSearchPref()
|
||||
const d = res?.data
|
||||
if (!d) return
|
||||
state.rooms = Math.max(1, Number(d.rooms) || 1)
|
||||
state.adults = Math.max(1, Number(d.adults) || 1)
|
||||
state.children = Math.max(0, Number(d.children) || 0)
|
||||
if (d.city) state.city = String(d.city)
|
||||
// 晚数习惯:若库里有 nights,且当前仍是默认 1 晚,则按习惯回填离店
|
||||
const nights = Math.max(1, Math.min(MAX_STAY_NIGHTS, Number(d.nights) || 1))
|
||||
const today = dayjs().format("YYYY-MM-DD")
|
||||
if (state.checkIn === today && nightCount.value === 1 && nights > 1) {
|
||||
state.checkOut = dayjs(state.checkIn).add(nights, "day").format("YYYY-MM-DD")
|
||||
}
|
||||
prefLoaded.value = true
|
||||
} catch {
|
||||
prefLoaded.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const goSearch = () => {
|
||||
clampStayRange(true)
|
||||
// 习惯落库异步,不阻塞跳转与列表请求
|
||||
persistSearchPref()
|
||||
router.jump("/pages/hotel/list", {
|
||||
city: state.city,
|
||||
keyword: state.keyword,
|
||||
checkIn: state.checkIn,
|
||||
checkOut: state.checkOut,
|
||||
rooms: "1",
|
||||
rooms: String(state.rooms),
|
||||
adults: String(state.adults),
|
||||
children: String(state.children),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -230,6 +307,7 @@ const goOrders = () => {
|
||||
onShow(() => {
|
||||
// 从酒店列表等业务页返回时,确保原生底栏重新显示
|
||||
useTabbarStore().showTabbar("/pages/tabbar/travel")
|
||||
loadSearchPref()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -347,6 +425,25 @@ onShow(() => {
|
||||
color: #1570ef;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
.ht-guest-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f1f5f9;
|
||||
}
|
||||
.ht-guest-row__lab {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.ht-guest-row__val {
|
||||
display: block;
|
||||
margin-top: 6rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
.ht-keyword-wrap {
|
||||
position: relative;
|
||||
margin-top: 20rpx;
|
||||
|
||||
@@ -33,6 +33,21 @@ export default {
|
||||
params,
|
||||
})
|
||||
},
|
||||
/** 当前用户酒店搜索习惯 */
|
||||
getSearchPref: (): Promise<any> => {
|
||||
return request({
|
||||
url: "/supermarket/app/hotel/search-pref",
|
||||
method: "GET",
|
||||
})
|
||||
},
|
||||
/** 保存酒店搜索习惯 */
|
||||
saveSearchPref: (data: any): Promise<any> => {
|
||||
return request({
|
||||
url: "/supermarket/app/hotel/search-pref",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
/** 酒店详情 */
|
||||
detail: (id: string | number): Promise<any> => {
|
||||
return request({
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<view v-if="visible" class="hg-mask" @tap="onClose">
|
||||
<view class="hg-sheet" @tap.stop>
|
||||
<view class="hg-sheet__head">
|
||||
<text class="hg-sheet__title">请选择房间和住客人数</text>
|
||||
<view class="hg-sheet__close" @tap="onClose">
|
||||
<tm-icon name="close-line" :size="36" color="#64748b" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="hg-sheet__body" scroll-y :show-scrollbar="false">
|
||||
<view class="hg-row">
|
||||
<text class="hg-row__lab">间数</text>
|
||||
<view class="hg-step">
|
||||
<view class="hg-step__btn" :class="{ off: draft.rooms <= 1 }" @tap="change('rooms', -1)">−</view>
|
||||
<text class="hg-step__val">{{ draft.rooms }}</text>
|
||||
<view class="hg-step__btn" :class="{ off: draft.rooms >= 10 }" @tap="change('rooms', 1)">+</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hg-row">
|
||||
<text class="hg-row__lab">成人数</text>
|
||||
<view class="hg-step">
|
||||
<view class="hg-step__btn" :class="{ off: draft.adults <= 1 }" @tap="change('adults', -1)">−</view>
|
||||
<text class="hg-step__val">{{ draft.adults }}</text>
|
||||
<view class="hg-step__btn" :class="{ off: draft.adults >= 20 }" @tap="change('adults', 1)">+</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hg-row">
|
||||
<view class="hg-row__lab-wrap">
|
||||
<text class="hg-row__lab">儿童数</text>
|
||||
<text class="hg-row__sub">0-17岁</text>
|
||||
</view>
|
||||
<view class="hg-step">
|
||||
<view class="hg-step__btn" :class="{ off: draft.children <= 0 }" @tap="change('children', -1)">−</view>
|
||||
<text class="hg-step__val">{{ draft.children }}</text>
|
||||
<view class="hg-step__btn" :class="{ off: draft.children >= 20 }" @tap="change('children', 1)">+</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="hg-tip">
|
||||
<text class="hg-tip__title">重要提示</text>
|
||||
<text class="hg-tip__txt">1、儿童年龄请按照入住酒店当天实际年龄计算。</text>
|
||||
<text class="hg-tip__txt">2、当前按总人数筛选可住房型;成人/儿童标签后续再细化。</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="hg-sheet__foot">
|
||||
<view class="hg-ok" @tap="onConfirm">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="HotelGuestSheet">
|
||||
import { computed, onBeforeUnmount, reactive, watch } from "vue"
|
||||
import { useTabbarStore } from "@@/stores/tabbar"
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
rooms?: number
|
||||
adults?: number
|
||||
children?: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:modelValue", v: boolean): void
|
||||
(e: "confirm", v: { rooms: number; adults: number; children: number }): void
|
||||
}>()
|
||||
|
||||
const tabbarStore = useTabbarStore()
|
||||
/** 本弹层是否已主动藏过底栏(关闭时再恢复,避免误伤其它逻辑) */
|
||||
let hidTabbarBySheet = false
|
||||
|
||||
const currentPagePath = () => {
|
||||
const pages = getCurrentPages()
|
||||
const cur = pages[pages.length - 1] as { route?: string } | undefined
|
||||
const route = String(cur?.route || "").replace(/^\//, "")
|
||||
return route ? `/${route}` : tabbarStore.currentPath || ""
|
||||
}
|
||||
|
||||
const syncTabbarWithSheet = (open: boolean) => {
|
||||
// 原生 TabBar 盖在页面 fixed 之上,只能 hideTabBar,靠 z-index 盖不住
|
||||
const path = currentPagePath()
|
||||
if (open) {
|
||||
if (!path || !tabbarStore.isTabbarPage(path)) return
|
||||
tabbarStore.hideTabbar(path)
|
||||
hidTabbarBySheet = true
|
||||
return
|
||||
}
|
||||
if (!hidTabbarBySheet) return
|
||||
hidTabbarBySheet = false
|
||||
if (path && tabbarStore.isTabbarPage(path)) {
|
||||
tabbarStore.showTabbar(path)
|
||||
}
|
||||
}
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (v: boolean) => emit("update:modelValue", v),
|
||||
})
|
||||
|
||||
const draft = reactive({
|
||||
rooms: 1,
|
||||
adults: 1,
|
||||
children: 0,
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(open) => {
|
||||
syncTabbarWithSheet(!!open)
|
||||
if (!open) return
|
||||
draft.rooms = Math.max(1, Math.min(10, Number(props.rooms) || 1))
|
||||
draft.adults = Math.max(1, Math.min(20, Number(props.adults) || 1))
|
||||
draft.children = Math.max(0, Math.min(20, Number(props.children) || 0))
|
||||
},
|
||||
)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
syncTabbarWithSheet(false)
|
||||
})
|
||||
|
||||
const change = (key: "rooms" | "adults" | "children", delta: number) => {
|
||||
const next = draft[key] + delta
|
||||
if (key === "rooms") draft.rooms = Math.max(1, Math.min(10, next))
|
||||
else if (key === "adults") draft.adults = Math.max(1, Math.min(20, next))
|
||||
else draft.children = Math.max(0, Math.min(20, next))
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
const onConfirm = () => {
|
||||
emit("confirm", {
|
||||
rooms: draft.rooms,
|
||||
adults: draft.adults,
|
||||
children: draft.children,
|
||||
})
|
||||
visible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.hg-mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1200;
|
||||
background: rgba(15, 23, 42, 0.45);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
/* 盖住底部 TabBar / 手势条,避免确定按钮被挡 */
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.hg-sheet {
|
||||
width: 100%;
|
||||
max-height: 85vh;
|
||||
background: #fff;
|
||||
border-radius: 28rpx 28rpx 0 0;
|
||||
padding: 28rpx 28rpx 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hg-sheet__head {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
.hg-sheet__body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
max-height: 52vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hg-sheet__foot {
|
||||
flex-shrink: 0;
|
||||
padding: 24rpx 0 calc(24rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
background: #fff;
|
||||
}
|
||||
.hg-sheet__title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
.hg-sheet__close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.hg-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 28rpx 0;
|
||||
border-bottom: 1rpx solid #f1f5f9;
|
||||
}
|
||||
.hg-row__lab-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rpx;
|
||||
}
|
||||
.hg-row__lab {
|
||||
font-size: 30rpx;
|
||||
color: #0f172a;
|
||||
font-weight: 500;
|
||||
}
|
||||
.hg-row__sub {
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.hg-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
.hg-step__btn {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid #cbd5e1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
color: #334155;
|
||||
line-height: 1;
|
||||
}
|
||||
.hg-step__btn.off {
|
||||
opacity: 0.35;
|
||||
}
|
||||
.hg-step__val {
|
||||
min-width: 40rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #0f172a;
|
||||
}
|
||||
.hg-tip {
|
||||
margin-top: 24rpx;
|
||||
padding: 20rpx;
|
||||
background: #f8fafc;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.hg-tip__title {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #334155;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
.hg-tip__txt {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #64748b;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.hg-ok {
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 999rpx;
|
||||
background: #1570ef;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user