feat: 优化首页服务入口与租住业务流程

补齐首页待办跳转、押金支付引导和多类租住服务页面能力,统一租客端关键业务流程体验。
This commit is contained in:
liangjian
2026-08-25 13:53:12 +08:00
parent 1111ac148b
commit 9fee2c3a74
41 changed files with 6985 additions and 933 deletions

View File

@@ -33,7 +33,7 @@
</view>
</view>
<text class="asset-name tn-text-ellipsis">{{ item.assetName }}</text>
<text class="asset-name tn-text-ellipsis">{{ getAssetDisplayName(item) }}</text>
<text v-if="item.brand" class="asset-brand tn-text-ellipsis">{{ item.brand }}</text>
<text v-else class="asset-brand-placeholder"></text>
</view>
@@ -53,7 +53,14 @@ export default {
default: 'zh'
}
},
methods: {}
methods: {
getAssetDisplayName(item = {}) {
if (this.language === 'en') {
return item.assetNameEn || item.assetName || ''
}
return item.assetName || item.assetNameEn || ''
}
}
}
</script>

View File

@@ -446,6 +446,7 @@ function normalizeRoomAssets(list = []) {
return null
}
const assetName = normalizeText(item.assetName || item.name || item.label)
const assetNameEn = normalizeText(item.assetNameEn || item.nameEn || item.labelEn)
if (!assetName) {
return null
}
@@ -456,6 +457,7 @@ function normalizeRoomAssets(list = []) {
key: `${item.roomTypeCode || 'asset'}-${item.assetName || item.name || index}`,
roomTypeCode: item.roomTypeCode || '',
assetName,
assetNameEn,
brand: normalizeText(item.brand),
icon: iconClass ? '' : addFilePrefix(rawIcon),
iconClass,

View File

@@ -98,8 +98,8 @@
import StoreInfo from './components/StoreInfo.vue';
import FacilityList from './components/FacilityList.vue';
import RoomList from './components/RoomList.vue';
import { facilityManagers } from '@/api/index.js'
import { localizeFacilityName, localizeHousingTag } from '../../utils/select-room-normalizers'
import { areaDetailPagination, facilityManagers } from '@/api/index.js'
import { localizeFacilityName, localizeHousingTag, normalizeAreaItem } from '../../utils/select-room-normalizers'
function parseCoordinate(...values) {
for (let i = 0; i < values.length; i += 1) {
@@ -140,18 +140,12 @@ export default {
if (Array.isArray(this.storeData.images) && this.storeData.images.length) {
return this.storeData.images.filter(Boolean)
}
if (this.heroImage) {
return [this.heroImage]
}
return []
},
heroImage() {
if (this.storeData.images && this.storeData.images[0]) {
return this.storeData.images[0]
}
if (this.roomTypes.length > 0 && this.roomTypes[0].images && this.roomTypes[0].images[0]) {
return this.roomTypes[0].images[0]
}
return ''
},
storeTags() {
@@ -284,7 +278,74 @@ export default {
applyStoreData(data) {
this.storeData = data && typeof data === 'object' ? data : {}
this.roomTypes = this.storeData.roomTypes || []
this.loadAreaManager()
this.currentImageIndex = 0
return this.loadAreaDetail()
.catch((error) => {
console.warn('查询区域详情失败', error)
})
.finally(() => {
this.loadAreaManager()
})
},
pickAreaDetail(rawList = []) {
if (!Array.isArray(rawList) || !rawList.length) {
return null
}
const areaCode = String(this.storeData.code || this.storeData.areaCode || '').trim()
const areaName = String(this.storeData.name || '').trim()
const areaNameEn = String(this.storeData.nameEn || '').trim()
if (areaCode) {
const exactCodeItem = rawList.find((item) => String(item && item.code || '').trim() === areaCode)
if (exactCodeItem) {
return exactCodeItem
}
}
const exactNameItem = rawList.find((item) => {
const name = String(item && item.name || '').trim()
const nameEn = String(item && item.nameEn || '').trim()
return (areaName && name === areaName) || (areaNameEn && nameEn === areaNameEn)
})
if (exactNameItem) {
return exactNameItem
}
return rawList[0] || null
},
loadAreaDetail() {
const areaCode = String(this.storeData.code || this.storeData.areaCode || '').trim()
const searchKeyword = areaCode || String(this.storeData.name || '').trim()
if (!searchKeyword) {
return Promise.resolve()
}
return areaDetailPagination({
PageIndex: 1,
PageSize: areaCode ? 20 : 50,
Search: searchKeyword
}, this.language)
.then((res) => {
const rawList = Array.isArray(res && res.data && res.data.data)
? res.data.data
: Array.isArray(res && res.data)
? res.data
: []
const matchedArea = this.pickAreaDetail(rawList)
if (!matchedArea) {
return
}
const normalizedArea = normalizeAreaItem(matchedArea)
this.storeData = {
...this.storeData,
...normalizedArea,
roomTypes: (this.storeData.roomTypes || []).length ? (this.storeData.roomTypes || []) : normalizedArea.roomTypes,
tags: (this.storeData.tags || []).length ? this.storeData.tags : normalizedArea.tags,
facilities: (this.storeData.facilities || []).length ? this.storeData.facilities : normalizedArea.facilities
}
})
},
loadAreaManager() {
const areaCode = this.storeData.code || this.storeData.areaCode || ''