ai-c/pages/service/service.js
2026-02-02 18:21:32 +08:00

294 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 服务页面 - 按照Figma设计实现
const api = require('../../utils/api')
const config = require('../../config/index')
Page({
data: {
statusBarHeight: 44,
navBarHeight: 44,
totalNavHeight: 88,
searchText: '',
hasNotification: true,
totalUnread: 0,
// 轮播图 - 从后台素材管理API加载
banners: [],
swiperHeight: 400,
// 服务类型 - 6个
serviceTypes: [
{ id: 'points', name: '礼品商城', icon: '/images/fuw-shangcheng.png', bgColor: '#FFF7ED' },
{ id: 'merchants', name: '合作商家', icon: '/images/fuw-shangjia.png', bgColor: '#FFF1F2' },
{ id: 'eldercare', name: '智慧康养', icon: '/images/fuw-kangyang.png', bgColor: '#F0FDFA' },
{ id: 'custom', name: '定制服务', icon: '/images/fuw-dingzhi.png', bgColor: '#F0F9FF' },
{ id: 'academy', name: '心伴学堂', icon: '/images/fuw-pinpai.png', bgColor: '#F5F3FF' },
{ id: 'brand', name: '关于品牌', icon: '/images/fuw-aixin.png', bgColor: '#FFF1F2' }
],
// 内容列表 (通用)
listData: [],
isLoading: false,
page: 1,
hasMore: true,
// 审核状态
auditStatus: 0
},
onLoad() {
const systemInfo = wx.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 44
const menuButton = wx.getMenuButtonBoundingClientRect()
const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2
const totalNavHeight = statusBarHeight + navBarHeight
this.setData({
statusBarHeight,
navBarHeight,
totalNavHeight
})
// 加载Banner配置
this.loadBanners()
// 加载合作商家列表
this.loadListData()
},
/**
* 轮播图图片加载完成,自适应高度
*/
onBannerLoad(e) {
if (this.data.swiperHeight !== 400) return; // 只计算一次,避免多次抖动
const { width, height } = e.detail;
const sysInfo = wx.getSystemInfoSync();
// 减去左右padding (32rpx * 2)
const swiperWidth = sysInfo.windowWidth - (32 * 2 / 750 * sysInfo.windowWidth);
const ratio = width / height;
const swiperHeight = swiperWidth / ratio;
const swiperHeightRpx = swiperHeight * (750 / sysInfo.windowWidth);
this.setData({
swiperHeight: swiperHeightRpx
});
},
/**
* 处理图片URL如果是相对路径则拼接域名并设置清晰度为85
*/
processImageUrl(url) {
if (!url) return ''
let fullUrl = url
if (!url.startsWith('http://') && !url.startsWith('https://')) {
const baseUrl = 'https://ai-c.maimanji.com'
fullUrl = baseUrl + (url.startsWith('/') ? '' : '/') + url
}
// 添加清晰度参数 q=85
if (fullUrl.includes('?')) {
if (!fullUrl.includes('q=')) {
fullUrl += '&q=85'
}
} else {
fullUrl += '?q=85'
}
return fullUrl
},
/**
* 加载合作商家列表
*/
async loadListData(reset = true) {
if (this.data.isLoading) return
if (!reset && !this.data.hasMore) return
this.setData({ isLoading: true })
const page = reset ? 1 : this.data.page + 1
try {
// 加载合作商家 (Merchants)
const res = await api.request('/service/providers', {
data: { page, limit: 20, type: 'merchant' }
})
let newData = []
let total = 0
if (res.success && res.data) {
newData = res.data.providers || []
total = res.data.total || 0
newData = newData.map(item => ({
...item,
id: item.id,
image: this.processImageUrl(item.avatar),
tags: item.skills || item.service_types || [],
desc: item.desc || item.introduction || '暂无简介',
rating: item.rating || item.avg_rating || '5.0'
}))
}
this.setData({
listData: reset ? newData : [...this.data.listData, ...newData],
page,
hasMore: (page * 20) < total,
isLoading: false
})
} catch (err) {
if (err.code === 404) {
console.warn('列表接口未部署 (404), 显示空列表')
} else {
console.error('加载列表数据失败', err)
}
this.setData({
listData: reset ? [] : this.data.listData,
isLoading: false,
hasMore: false
})
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.loadListData(false)
},
onShow() {
wx.hideTabBar({ animation: false })
const app = getApp()
this.setData({
auditStatus: app.globalData.auditStatus
})
this.loadListData()
this.loadUnreadCount()
},
/**
* 加载服务页Banner
* 调用专用API,只返回在线的Banner,按排序顺序
*/
async loadBanners() {
try {
const res = await api.pageAssets.getServiceBanners()
if (res && res.success && res.data) {
// 提取URL数组(API已按排序返回,已过滤下线的)
const banners = res.data.map(item => this.processImageUrl(item.asset_url))
if (banners.length > 0) {
this.setData({ banners })
} else {
// 如果全部下线,使用默认配置
this.setDefaultBanners()
}
} else {
this.setDefaultBanners()
}
} catch (err) {
if (err.code !== 404) {
console.error('加载Banner失败:', err)
}
this.setDefaultBanners()
}
},
/**
* 设置默认Banner降级方案 - 使用CDN URL
*/
setDefaultBanners() {
const cdnBase = 'https://ai-c.maimanji.com/images'
this.setData({
banners: [
`${cdnBase}/service-banner-1.png`,
`${cdnBase}/service-banner-2.png`,
`${cdnBase}/service-banner-3.png`,
`${cdnBase}/service-banner-4.png`,
`${cdnBase}/service-banner-5.png`,
`${cdnBase}/service-banner-6.png`
]
})
console.log('使用默认Banner配置')
},
/**
* 加载未读消息数
*/
loadUnreadCount() {
if (!api.chat || typeof api.chat.getConversations !== 'function') return
api.chat.getConversations().then(res => {
if (res && res.success && res.data) {
let count = 0
res.data.forEach(item => {
count += (item.unread_count || 0)
})
this.setData({ totalUnread: count })
}
}).catch(err => {
// 静默处理未读数获取失败
if (err.code !== 404) {
console.warn('获取未读数静默失败:', err)
}
})
},
/**
* 点击服务类型
*/
onServiceType(e) {
const id = e.currentTarget.dataset.id
if (id === 'points') {
// 礼品商城 - 跳转到兑换商城
wx.navigateTo({ url: '/pages/gift-shop/gift-shop' })
} else if (id === 'merchants') {
// 合作商家 - 刷新列表
this.loadListData()
} else if (id === 'eldercare') {
// 智慧康养 - 跳转到详情页
wx.navigateTo({ url: '/pages/eldercare/eldercare' })
} else if (id === 'custom') {
// 定制服务 - 跳转到详情页
wx.navigateTo({ url: '/pages/custom/custom' })
} else if (id === 'academy') {
// 心伴学堂 - 跳转到列表页
wx.navigateTo({ url: '/pages/academy/list/list' })
} else if (id === 'brand') {
// 关于品牌 - 跳转到品牌详情页
wx.navigateTo({ url: '/pages/brand/brand' })
}
},
/**
* 点击列表项 - 跳转商家详情
*/
onItemTap(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({
url: `/pages/service-provider-detail/service-provider-detail?id=${id}`
})
},
/**
* 切换Tab
*/
switchTab(e) {
const path = e.currentTarget.dataset.path
if (path) {
const app = getApp()
// 消息页面需要登录
if (path === '/pages/chat/chat') {
if (!app.globalData.isLoggedIn) {
wx.navigateTo({
url: '/pages/login/login?redirect=' + encodeURIComponent(path)
})
return
}
}
wx.switchTab({ url: path })
}
}
})