HomeLease/pages/index/index.vue
2025-09-13 17:47:26 +08:00

489 lines
14 KiB
Vue
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.

<template>
<view class="home-container">
<!-- 头部信息 -->
<custom-nav-bar
background-color="#FFDECB"
title="湖北幺娘子厨燃能源科技有限公司"
title-align="left"
></custom-nav-bar>
<!-- 公告栏 -->
<announcement-bar
:announcement-icon="commonEnum.ANNOUNCEMENT_ICON"
:announcement-text="announcementText"
@announcement-click="onAnnouncementClick"
/>
<!-- 轮播图 -->
<banner-swiper
:autoplay="autoplay"
:banner-list="bannerList"
:duration="duration"
:indicator-dots="indicatorDots"
:interval="interval"
@change="onBannerChange"
@banner-click="onBannerClick"
/>
<!-- 设备列表 -->
<equipment-list
:equipment-list="equipmentList"
:title="equipmentTitle"
@renew="onRenew"
@equipment-click="onEquipmentClick"
/>
<!-- 续费弹窗 -->
<renew-modal
:device="selectedDevice"
:loading="packageLoading"
:package-list="packageList"
:visible="showRenewModal"
@close="closeRenewModal"
@select-package="onSelectPackage"
@confirm-renew="onConfirmRenew"
/>
<!-- 底部导航已由系统tabBar处理 -->
</view>
</template>
<script>
import commonEnum from '../../enum/commonEnum'
import AnnouncementBar from '../../components/announcement-bar/announcement-bar.vue'
import BannerSwiper from '../../components/banner-swiper/banner-swiper.vue'
import EquipmentList from '../../components/equipment-list/equipment-list.vue'
import RenewModal from '../../components/renew-modal/renew-modal.vue'
import { getNewAnnouncement } from '../../api/article/article.js'
import { getBannerList } from '../../api/banner/banner.js'
import { getDeviceList } from '../../api/device/device.js'
import {
renewDevice,
getPeriodPackages,
getPeriodPackagesByTypeId,
getPeriodPackagesByDevId,
} from '../../api/lease/lease.js'
import { getIsRealName } from '../../api'
export default {
components: {
AnnouncementBar,
BannerSwiper,
EquipmentList,
RenewModal,
},
data() {
return {
hasExecuted: uni.getStorageSync('hasExecutedGoToRealName') || false,
// 基础配置
isRealName: false,
indicatorDots: true,
autoplay: true,
interval: 2000,
duration: 500,
commonEnum: commonEnum,
// 页面数据
companyName: '福鼎创特物联科技有限公司',
announcementText: '暂无更多公告! 暂无更多公告! 暂无更多公告!',
currentAnnouncement: null, // 当前公告数据
equipmentTitle: '我的租赁设备',
navItems: ['首页', '申请租赁', '个人中心'],
activeNavIndex: 0,
// 轮播图数据
currentBannerIndex: 0,
bannerList: [],
// 设备列表数据
equipmentList: [],
// 续费相关数据
showRenewModal: false,
selectedDevice: null,
packageList: [],
packageLoading: false,
selectedPackage: null,
renewData: {},
}
},
// 生命周期钩子
onLoad() {
this.fetchAnnouncement()
this.fetchBannerList()
this.fetchDeviceList()
},
onShow() {
this.fetchAnnouncement()
this.fetchBannerList()
this.fetchDeviceList()
this.onceTipRealName()
},
methods: {
async onceTipRealName() {
console.log('onceTipRealName-hasExecuted:', this.hasExecuted)
const storageInfo = uni.getStorageInfoSync()
console.log('当前存储Keys:', storageInfo.keys)
let token = uni.getStorageSync('token')
console.log('onceTipRealName-token:', token)
if (token && !this.hasExecuted) {
await this.goToRealName()
this.hasExecuted = true
uni.setStorageSync('hasExecutedGoToRealName', true)
}
},
async goToRealName() {
const res = await getIsRealName()
if (!res.data) {
uni.showModal({
title: '提示',
content: '需要租赁,请先实名',
showCancel: true,
confirmText: '去实名',
cancelText: '暂不',
success: function (res) {
if (res.confirm) {
uni.navigateTo({
url: '/pages/realNameAuthentication/realNameAuthentication',
})
}
},
})
}
},
// 获取最新公告
async fetchAnnouncement() {
try {
const response = await getNewAnnouncement()
if (response.code === 200 && response.data) {
this.currentAnnouncement = response.data
// 更新公告文本去除HTML标签
const content = response.data.content || ''
const plainText = content.replace(/<[^>]*>/g, '')
this.announcementText = response.data.title || plainText || '暂无更多公告!'
}
} catch (error) {
console.error('获取公告失败:', error)
this.announcementText = '暂无更多公告!'
}
},
// 获取轮播图列表
async fetchBannerList() {
try {
const response = await getBannerList()
if (response.code === 200 && response.data && Array.isArray(response.data)) {
// 按orderNum排序确保轮播图顺序正确
const sortedBanners = response.data
.filter(banner => banner.state === '1') // 只显示启用的轮播图
.sort((a, b) => parseInt(a.orderNum) - parseInt(b.orderNum))
.map(banner => ({
id: banner.id,
image: banner.imgUrl,
link: banner.link,
name: `轮播图${banner.id}`,
}))
this.bannerList = sortedBanners
}
} catch (error) {
console.error('获取轮播图失败:', error)
// 如果获取失败,使用默认轮播图
this.bannerList = [
{
id: 'default1',
image: commonEnum.TEMP1,
name: '默认轮播图1',
},
{
id: 'default2',
image: commonEnum.TEMP2,
name: '默认轮播图2',
},
]
}
},
// 获取设备列表
async fetchDeviceList() {
try {
const token = uni.getStorageSync('token')
if (!token) {
console.log('暂无登录,不请求设备列表')
return
}
const response = await getDeviceList()
if (response.code === 200 && response.data && Array.isArray(response.data)) {
// 转换设备数据格式
const devices = response.data.map(device => {
// 根据operationState判断设备状态
let status = 'normal'
if (device.operationState === '1') {
status = 'available' // 可租用
} else if (device.operationState === '2') {
status = 'rented' // 已出租
} else if (device.operationState === '3') {
status = 'maintenance' // 维护中
} else if (device.operationState === '4') {
status = 'scrapped' // 报废
}
// 根据onlineState判断在线状态
const isOnline = device.onlineState === '1'
return {
id: device.id,
name: device.newTypeName || device.typeName || '未知设备',
status: status,
startTime: device.leaseTime || '',
endTime: device.expirationTime || '',
image: device.img || commonEnum.TEMP2,
mac: device.mac,
sn: device.sn,
isOnline: isOnline,
powerStatus: device.powerStatus,
iotExpireTime: device.iotExpireTime,
// 保留原始数据用于API调用
suitIds: device.suitIds || device.devicesuitIds,
originalData: device,
}
})
this.equipmentList = devices
}
} catch (error) {
console.error('获取设备列表失败:', error)
}
},
// 头部点击事件
onLocationClick() {
uni.showToast({
title: '选择位置',
icon: 'none',
})
},
// 公告栏点击事件
onAnnouncementClick() {
if (this.currentAnnouncement) {
// 显示公告详情
uni.navigateTo({
url: '/pages/announcementList/announcementList',
})
} else {
uni.showToast({
title: '暂无公告',
icon: 'none',
})
}
},
// 轮播图变化事件
onBannerChange(index) {
this.currentBannerIndex = index
},
// 轮播图点击事件
onBannerClick({ item, index }) {
if (item.link) {
// 如果有链接,跳转到对应页面
uni.navigateTo({
url: item.link,
})
}
},
// 设备点击事件
onEquipmentClick(equipment) {
// 跳转到设备详情页面,传递设备信息
},
// 续费事件
async onRenew(equipment) {
try {
this.selectedDevice = equipment
this.packageLoading = true
// 根据设备ID查询套餐
console.log('设备信息originalData', this.selectedDevice.originalData)
await this.fetchPackageList(this.selectedDevice.originalData.id)
console.log('设备id', this.selectedDevice.originalData.id)
this.showRenewModal = true
} catch (error) {
console.error('打开续费弹窗失败:', error)
uni.showToast({
title: '打开续费弹窗失败',
icon: 'error',
})
}
},
// 获取套餐列表
async fetchPackageList(deviceId) {
try {
console.log('设备类型ID:', deviceId)
const response = await getPeriodPackagesByDevId(deviceId)
if (response.code === 200) {
this.packageList = response.data || []
console.log('套餐列表:', this.packageList)
} else {
throw new Error(response.message || '获取套餐列表失败')
}
} catch (error) {
console.error('获取套餐列表失败:', error)
uni.showToast({
title: error.message || '获取套餐列表失败',
icon: 'error',
})
} finally {
this.packageLoading = false
}
},
// 关闭续费弹窗
closeRenewModal() {
this.showRenewModal = false
this.selectedDevice = null
this.selectedPackage = null
this.packageList = []
},
// 选择套餐
onSelectPackage(combo) {
this.selectedPackage = combo
console.log('选择的套餐:', combo)
},
// 确认续费
async onConfirmRenew() {
if (!this.selectedPackage) {
uni.showToast({
title: '请选择套餐',
icon: 'none',
})
return
}
try {
if (this.selectedPackage.id && this.selectedPackage.id.endsWith('a')) {
this.renewData = {
payAmount: this.packageList.lastSuitAmount,
lastSuitDay: this.packageList.lastSuitDay,
lastSuitId: this.packageList.lastSuitId,
lastSuitName: this.packageList.lastSuitName,
// suitId: this.selectedPackage.id,
isLastSuit: true,
appId: '1', // 应用ID根据实际情况调整
// payAmount: this.selectedPackage.price || this.selectedPackage.amount,
channelId: '3', // 渠道ID根据实际情况调整
devId: this.selectedDevice.id,
}
console.log('ID以a结尾')
} else {
this.renewData = {
suitId: this.selectedPackage.id,
appId: '1', // 应用ID根据实际情况调整
payAmount: this.selectedPackage.price || this.selectedPackage.amount,
channelId: '3', // 渠道ID根据实际情况调整
devId: this.selectedDevice.id,
}
console.log('ID不以a结尾')
}
console.log('续费数据:', this.renewData)
uni.showLoading({
title: '生成续费订单中',
mask: 'true',
})
const response = await renewDevice(this.renewData)
uni.hideLoading()
if (response.code === 200) {
const data = response.data
const wxpPayParams = data.payParams
console.log(data)
const payParams = {
package: wxpPayParams.packageVal, // 后端返回的字段名
timeStamp: wxpPayParams.timeStamp,
nonceStr: wxpPayParams.nonceStr,
signType: wxpPayParams.signType,
paySign: wxpPayParams.paySign,
}
console.log('支付后端回调数据', payParams)
wx.requestPayment({
...payParams,
success: function (res) {
uni.showToast({
title: '支付成功',
icon: 'success',
duration: 3000,
})
setTimeout(() => {
uni.navigateTo({
url: `/pages/myOrder/orderDetail?id=${data.pay.bstId}`,
})
}, 3000)
},
fail: function (res) {
uni.showToast({
title: '支付失败',
icon: 'fail',
})
},
complete: function (res) {
console.log('微信支付调用结束')
},
})
// 关闭弹窗
this.closeRenewModal()
// 刷新设备列表
this.fetchDeviceList()
} else {
throw new Error(response.message || '续费失败')
}
} catch (error) {
uni.hideLoading()
console.error('续费失败:', error)
uni.showToast({
title: error.message || '续费失败',
icon: 'error',
})
}
},
// 底部导航点击事件
onNavClick(index) {
this.activeNavIndex = index
const navItems = ['首页', '申请租赁', '个人中心']
uni.showToast({
title: `切换到${navItems[index]}`,
icon: 'none',
})
},
},
}
</script>
<style lang="scss" scoped>
.home-container {
background: linear-gradient(to bottom, #ffddca 0px, #ffddca 450rpx, #fff 450rpx, #ffffff 100%);
padding-bottom: 120rpx; /* 为底部导航留出空间 */
max-width: 750rpx;
margin: 0 auto;
z-index: -2;
}
</style>