2025-12-04 09:58:14 +08:00

812 lines
27 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="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
</view>
</view>
<view class="community">
<view class="community_left">
<image mode="aspectFill" src="https://static.hshuishang.com/property-img-file/test.png"
alt="" />
</view>
<view class="community_right" @click="changeShow">
<view class="community_right_text">
<view class="community_right_text1">{{ currentRoom.name }}</view>
<view class="community_right_text2">{{ currentCommunityAddr }}</view>
</view>
<view class="community_right_more">
<u-icon bold color="#999999" size="30" name="arrow-right"></u-icon>
</view>
</view>
</view>
<view class="tabList">
<view class="tabItem" :class="active == 0 ? 'active' : ''" @click="changeTab(0)">
账单
</view>
<view class="line"></view>
<view class="tabItem" :class="active == 1 ? 'active' : ''" @click="changeTab(1)">
缴费记录
</view>
</view>
<view class="homeMoney" v-if="active == 0">
<view class="homeMoney_box">
<view class="homeMoney_box_left">
<view class="homeMoney_box_left1">物业费</view>
<view class="homeMoney_box_left2">可抵扣账户金额</view>
</view>
<view class="homeMoney_box_right">
<view class="homeMoney_box_right1">
<span>¥</span>{{ balanceMoney }}
</view>
<view class="homeMoney_box_right2" @click="more(currentRoom)">
查看详情
<view style="margin-left: 12rpx">
<u-icon bold color="#894B11" size="30" name="arrow-right"></u-icon>
</view>
</view>
</view>
</view>
</view>
<view class="payList" v-if="active == 0">
<view class="payItem" v-for="(item, index) in Bill" :key="index">
<view class="payItem_tit">
<view class="payItem_left">
<checkbox :checked="item.check" @click="checkChange(item, index)"
v-if="item.community_order_rows.some(itemObj => itemObj.pay_status == 1)"
:disabled="!canSelectBill(index)">
</checkbox>
<view style="margin-left: 24rpx">{{ item.order_date }}</view>
</view>
<view class="payItem_right">
<span></span>
<view class="payItem_money">{{ item.unpaid_amount }}</view>
<p>未缴</p>
<view style="margin-left: 40rpx" @click="changeCheck(item, index)">
<u-icon bold color="#894B11" size="30" name="arrow-down" v-if="!item.more"></u-icon>
<u-icon bold color="#894B11" size="30" name="arrow-up" v-if="item.more"></u-icon>
</view>
</view>
</view>
<view v-if="item.more">
<view class="payItem_List" v-for="(items, indes) in item.community_order_rows" :key="items.order_id">
<checkbox :checked="items.check" @click="itemsCheckChange(items, indes, index)" v-if="items.pay_status == 1"
:disabled="!canSelectItem(indes, index)"></checkbox>
<view class="Item_time" v-if="items.billing_cycle == 1">
{{ items.order_date }}
</view>
<view class="Item_time" v-if="items.billing_cycle == 2">
{{ items.order_datetime }}
</view>
<view class="Item_type">
{{ items.community_fee_type ? items.community_fee_type.type_name : '' }}
</view>
<view class="Item_money">{{ items.money }}</view>
<view class="Item_status" v-if="items.pay_status == 1">未付款</view>
<view class="Item_status sucess" v-if="items.pay_status == 2">
已付款
</view>
</view>
</view>
</view>
</view>
<!-- 选择支付类型 -->
<view class="payTypeList" v-if="active == 0">
<view class="PayTypeItem">
<view class="PayTypeItem_left">
<view class="PayTypeItem_img">
<image mode="aspectFill"
src="https://static.hshuishang.com/property-img-file/com_wechat.png" alt="" />
</view>
<view class="PayTypeItem_con">
<view class="PayTypeItem_con_tit">微信支付</view>
<view class="PayTypeItem_con_msg">单笔支付限额10000.00</view>
</view>
</view>
<view class="PayTypeItem_right">
<radio :checked="payType == 1" @click="changePayType(1)"></radio>
</view>
</view>
<view class="line3"></view>
<view class="PayTypeItem">
<view class="PayTypeItem_left">
<view class="PayTypeItem_img">
<image mode="aspectFill"
src="https://static.hshuishang.com/property-img-file/com_homeMoney.png" alt="" />
</view>
<view class="PayTypeItem_con">
<view class="PayTypeItem_con_tit">物业费支付</view>
<view class="PayTypeItem_con_msg">
可用公积金<span></span>{{ balanceMoney }}
<view class="PayTypeItem_con_msg2" @click="changeShow2">
可组合支付
</view>
</view>
</view>
</view>
<view class="PayTypeItem_right">
<radio :checked="payType == 2" @click="changePayType(2)"></radio>
</view>
</view>
</view>
<view class="bottom" v-if="active == 0">
<view class="bottom_left">
<span>合计</span>
<p></p>
{{ currentMoney }}
</view>
<view class="bottom_right" @click="createPay">立即支付</view>
</view>
<view class="payHisList" v-if="active == 1">
<view class="payHisItem" v-for="item in payOrderList" :key="item.id">
<view class="row">
<view class="row_label">缴费金额</view>
<view class="row_con1">{{ item.money + item.property_housing_fund }}</view>
</view>
<view class="row">
<view class="row_label2"></view>
<view class="row_con2">{{ item.pay_time }}支付</view>
</view>
<view class="line4"></view>
<view class="row">
<view class="row_label">缴费账单数量</view>
<view class="row_con3">
<view class="row_con3_1">
{{ item.community_order ? item.community_order.length : 0 }}个账单
</view>
<!-- <view class="row_con3_2">明细可从收据查看</view> -->
</view>
</view>
<view class="row">
<view class="row_label">应缴费金额</view>
<view class="row_con4">{{ item.money + item.property_housing_fund }}</view>
</view>
<view class="row">
<view class="row_label">物业费抵扣金额</view>
<view class="row_con4">-{{ item.property_housing_fund }}</view>
</view>
<view class="row">
<view class="row_label">缴费单号</view>
<view class="row_con4">{{ item.order_pay_no }}</view>
</view>
<view class="line4"></view>
<!-- <view class="Receipt">收据</view> -->
</view>
</view>
<view class="boxshadow" v-if="show" @click="changeShow">
<view class="boxshadowCon">
<view class="boxshadowCon_Tit">
选择房源
<view class="cancel" @click.stop="show = false">取消</view>
</view>
<view class="lines"></view>
<view class="communityList" v-if="roomList.length > 0">
<view class="communityItem" v-for="item in roomList" :key="item.room_id" @click="selectRoom(item)">
<view class="communityItem_text">
{{ item.facility_name }}{{ item.floor }} {{ item.number }}
</view>
<view class="communityItem_radio">
<radio :checked="selectedRoomId === item.room_id"></radio>
</view>
</view>
</view>
<view class="communityList" v-else>
<view class="communityItem">
<view class="communityItem_text">暂无房源</view>
</view>
</view>
</view>
</view>
<view class="boxshadow" v-if="show2" @click="changeShow2">
<view class="boxshadowCon">
<view class="boxshadowCon_Tit">
付款总金额
<view class="cancel" @click.stop="show2 = false">取消</view>
</view>
<view class="boxshadowCon_subTit">
<p></p>
{{ currentMoney }}
</view>
<view class="lines"></view>
<view class="BanlenceList">
<view class="banlenceItem">
<view class="banlenceItem_left">
<image mode="aspectFill"
src="https://static.hshuishang.com/property-img-file/com_wechat.png" alt="" />
微信支付
</view>
<view class="banlenceItem_right">
<span></span>{{ balanceMoney > currentMoney ? 0.00 : (currentMoney - balanceMoney).toFixed(2) }}
</view>
</view>
<view class="line3"></view>
<view class="banlenceItem">
<view class="banlenceItem_left">
<image mode="aspectFill"
src="https://static.hshuishang.com/property-img-file/com_homeMoney.png" alt="" />
物业费支付
</view>
<view class="banlenceItem_right">
<span></span>{{ balanceMoney > currentMoney ? currentMoney : balanceMoney }}
</view>
</view>
</view>
<view class="btn" @click="createPay">
物业费+微信支付 <span></span>{{ currentMoney }}
</view>
</view>
</view>
</view>
</template>
<script>
import {
request,
picUrl,
uniqueByField,
menuButtonInfo,
formatDate,
NavgateTo,
} from "../../../utils";
import { apiArr } from "../../../api/community";
export default {
data() {
return {
top: "",
localHeight: "",
active: 0,
show: false,
show2: false,
roomList: [],
currentRoom: {},
selectedRoomId: "", // 选中的房源ID
currentCommunity: "", //当前房源
currentCommunityAddr: "", //当前房源地址
Bill: "", //账单
Bill2: "", //未支付账单
balanceMoney: 0, //公积金
currentMoney: 0, //所选金额
payType: "1",
payInfoId: "", //支付信息id
page_size: 10,
page_num: 1,
payOrderList: [],
flag: false,
isAllow: false,
};
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
// this.top = meun.height + meun.top;
this.localHeight = meun.height;
this.currentCommunity = uni.getStorageSync("changeCommData");
this.currentCommunityAddr = uni.getStorageSync("currentCommunityAddr");
// 解析从providentFund页面传递过来的房源信息
if (options.item) {
try {
const item = JSON.parse(decodeURIComponent(options.item));
this.currentRoom = item;
} catch (error) {
console.error("解析房源信息失败:", error);
}
}
this.getRoomSelect();
this.getUserGovenmentMoney();
},
// 下拉刷新生命周期函数
onPullDownRefresh() {
// 根据当前激活的标签页,重新加载对应的数据
if (this.active === 0) {
// 账单页面,重新获取公积金和账单数据,不重置已选择的小区
Promise.all([
this.getUserGovenmentMoney(),
this.getOrderList()
]).then(() => {
// 数据加载完成后停止下拉刷新
uni.stopPullDownRefresh();
}).catch(() => {
// 加载失败也需要停止下拉刷新
uni.stopPullDownRefresh();
});
} else if (this.active === 1) {
// 缴费记录页面,重新获取缴费记录
this.page_num = 1;
this.page_size = 10;
this.getPayList().then(() => {
// 数据加载完成后停止下拉刷新
uni.stopPullDownRefresh();
}).catch(() => {
// 加载失败也需要停止下拉刷新
uni.stopPullDownRefresh();
});
}
},
// 滑动到底部生命周期函数
onReachBottom() {
// 只有在缴费记录页面且还有更多数据时才触发加载更多
if (this.active === 1 && this.flag) {
// 增加page_size的值
this.page_size += 10;
// 重新获取缴费记录
this.getPayList();
}
},
methods: {
changeTab(index) {
this.active = index;
if (index == 1) {
// 重置分页参数
this.page_num = 1;
this.page_size = 10;
this.getPayList();
}
},
back() {
uni.navigateBack({
delta: 1,
});
},
changeShow() {
this.show = !this.show;
},
changeShow2() {
if (this.currentMoney == 0) {
uni.showToast({
title: "请选择账单",
icon: "none",
});
return;
}
this.show2 = !this.show2;
},
//获取房源
getRoomSelect() {
return new Promise((resolve, reject) => {
request(apiArr.getCommunityRoomList, "POST", {
community_id: this.currentCommunity.id,
page_num: 1,
page_size: 50,
}).then((res) => {
this.isAllow = res.rows[0].community.bill_allow_skip_payment === 1;
this.roomList = res.rows;
if (!this.currentRoom.room_id) {
this.currentRoom = this.roomList[0]
}
this.selectedRoomId = this.currentRoom.room_id;
this.getOrderList().then(() => {
resolve();
}).catch((error) => {
reject(error);
});
}).catch((error) => {
reject(error);
});
});
},
// 选择房源
selectRoom(item) {
this.getRoomSelect()
// 更新选中的房源ID
this.selectedRoomId = item.room_id;
// 在控制台输出选中的数据
console.log("选中的房源数据:", item);
this.currentRoom = item;
this.getOrderList();
// 如果当前是缴费记录标签页,重新请求缴费记录数据
if (this.active === 1) {
// 重置分页参数
this.page_num = 1;
this.page_size = 10;
this.getPayList();
}
},
//获取用户公积金
getUserGovenmentMoney() {
return new Promise((resolve, reject) => {
request(apiArr.getUserGovenmentMoney, "POST", {}).then((res) => {
console.log(res, "公积金");
this.balanceMoney = res.balance_after;
resolve();
}).catch((error) => {
reject(error);
});
});
},
//获取账单
getOrderList() {
return new Promise((resolve, reject) => {
request(apiArr.getOrderList, "POST", {
room_id: this.currentRoom.room_id,
page_num: 1,
page_size: 50,
}).then((res) => {
console.log(res, "账单");
res.rows.forEach((item) => {
item.check = false;
item.more = false;
item.community_order_rows.forEach((ite) => {
ite.check = false;
});
});
// 按照年份和月份进行排序
res.rows.sort((a, b) => {
// 首先获取年份从community_order_rows中第一个元素的order_date提取
const yearA = a.community_order_rows && a.community_order_rows.length > 0 ? parseInt(a.community_order_rows[0].order_date) : 0;
const yearB = b.community_order_rows && b.community_order_rows.length > 0 ? parseInt(b.community_order_rows[0].order_date) : 0;
// 如果年份不同,按照年份排序
if (yearA !== yearB) {
return yearA - yearB;
}
// 如果年份相同,获取月份进行比较
const monthA = a.community_order_rows && a.community_order_rows.length > 0 ? parseInt(a.community_order_rows[0].order_datetime) : 0;
const monthB = b.community_order_rows && b.community_order_rows.length > 0 ? parseInt(b.community_order_rows[0].order_datetime) : 0;
return monthA - monthB;
});
this.Bill = res.rows;
this.Bill2 = res.rows.reduce((result, item) => {
const paidOrders = item.community_order_rows.filter(ite => ite.pay_status == 1);
return result.concat(paidOrders);
}, []);
resolve();
}).catch((error) => {
reject(error);
});
});
},
//账单详情切换展示显示
changeCheck(e, index) {
this.Bill[index].more = !this.Bill[index].more;
},
// 判断是否可以选择该年份的账单
canSelectBill(index) {
if (this.isAllow) return true;
// 如果是第一条账单,总是可以选择
if (index === 0) return true;
// 检查前面所有年份的账单是否都已支付
for (let i = 0; i < index; i++) {
const yearBill = this.Bill[i];
// 检查该年份是否有未支付的账单
const hasUnpaid = yearBill.community_order_rows.some(item => item.pay_status === 1);
if (hasUnpaid) {
return false;
}
}
return true;
},
// 判断是否可以选择该具体的账单项
canSelectItem(indes, index) {
if (this.isAllow) return true;
// 首先检查该年份是否可以选择
if (!this.canSelectBill(index)) {
return false;
}
// 如果是该年份的第一项,总是可以选择
if (indes === 0) return true;
// 检查该年份前面的月份是否都已支付
const yearBill = this.Bill[index];
for (let i = 0; i < indes; i++) {
if (yearBill.community_order_rows[i].pay_status === 1) {
return false;
}
}
return true;
},
//整体选择
checkChange(e, index) {
// 只针对没有禁用的多选框操作
if (this.canSelectBill(index)) {
this.Bill[index].check = !this.Bill[index].check;
this.Bill[index].community_order_rows.forEach((item, indes) => {
// 子项也只针对没有禁用的多选框操作
if (item.pay_status == 1 && this.canSelectItem(indes, index)) {
item.check = this.Bill[index].check;
}
});
// 重新计算选中金额
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check && ite.pay_status == 1) {
money += ite.money;
}
});
});
this.currentMoney = money ? money.toFixed(2) : 0.00;
}
},
//具体选择
itemsCheckChange(e, indes, index) {
// 只针对没有禁用的多选框操作
if (this.canSelectItem(indes, index)) {
this.Bill[index].community_order_rows[indes].check =
!this.Bill[index].community_order_rows[indes].check;
//判断是否全部选中(只检查可选中的项)
let isAll = this.Bill[index].community_order_rows.every((item, idx) => {
// 只考虑可选中的项(未支付且可以选择)
if (item.pay_status === 1 && this.canSelectItem(idx, index)) {
return item.check;
}
// 对于已支付或不可选择的项,不影响全选状态
return true;
});
if (isAll) {
this.Bill[index].check = true;
} else {
this.Bill[index].check = false;
}
// 计算所有选中的金额
let money = 0;
this.Bill.forEach((item) => {
item.community_order_rows.forEach((ite) => {
if (ite.check && ite.pay_status == 1) {
money += ite.money;
}
});
});
this.currentMoney = money ? money.toFixed(2) : 0.00;
}
},
//切换支付方式
changePayType(e) {
this.payType = e;
},
//创建支付订单
async createPay() {
let order_ids = [];
this.Bill.forEach((item) => {
item.community_order_rows.forEach((items) => {
if (items.check) {
order_ids.push(items.order_id);
}
});
});
let name_mini = "";
if (this.payType == 1) {
name_mini = "微信";
} else if (this.payType == 2) {
name_mini = "物业费";
} else {
name_mini = "微信 + 物业费";
}
if (!this.currentMoney) {
return uni.showToast({
title: "请选择账单",
duration: 2000,
});
}
// 构建支付参数,根据支付类型决定传递哪些字段
const payParams = {
order_ids: order_ids,
community_id: this.currentCommunity.id,
room_id: this.currentRoom.room_id,
pay_user_id: uni.getStorageSync("userId"),
user_name: uni.getStorageSync("nickName"),
pay_user_name: uni.getStorageSync("nickName"),
pay_time: formatDate(new Date()),
name_mini,
};
// 判断是否是组合支付
const isComboPay = this.show2;
if (this.payType == 1 || isComboPay) {
//微信支付或组合支付
if (isComboPay) {
payParams.money = this.currentMoney - Number(this.balanceMoney).toFixed(2) > 0 ? this.currentMoney - Number(this.balanceMoney).toFixed(2) : 0.00;
if (payParams.money == 0.00) {
this.payType = 2;
}
} else {
payParams.money = this.currentMoney;
}
}
if (this.payType == 2 || isComboPay) {
// 公积金支付或组合支付
const fundAmount = Math.min(Number(this.balanceMoney), Number(this.currentMoney));
payParams.property_housing_fund = fundAmount.toFixed(2);
if (isComboPay && payParams.money == 0) {
this.payType = 2;
}
// 仅公积金支付 公积金不足
if (this.payType == 2 && !isComboPay) {
if (Number(this.balanceMoney) < Number(this.currentMoney)) {
uni.showToast({
title: '可用公积金不足,可选择组合支付',
icon: 'none',
duration: 3000
});
return;
}
}
}
// 组合支付
if (isComboPay && (payParams.money != 0.00 || payParams.money != 0)) {
this.payType = 3;
name_mini = "微信 + 物业费";
}
payParams.name_mini = name_mini;
if (this.payType == 2) {
uni.showModal({
title: '提示',
content: '确定使用物业费支付?',
success: async (res) => {
if (res.confirm) {
await request(apiArr.createPayOrder, "POST", payParams).then((res) => {
const params = {
order_pay_id: res.id,
}
request(apiArr.tradeQuery, "POST", params).then(res => {
uni.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
});
setTimeout(() => {
this.getRoomSelect();
this.getUserGovenmentMoney();
}, 1500);
})
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
} else {
await request(apiArr.createPayOrder, "POST", payParams).then((res) => {
this.payInfoId = res.id;
this.OrderPay();
});
}
},
//根据支付订单查询交易信息
async getPayInfo() {
await request(apiArr.getPayOrderInfo, "POST", { order_pay_id: 6 }).then(
(res) => {
this.OrderPay();
}
);
},
//预下单
async OrderPay() {
// this.payInfoId
await request(apiArr.OrderPay, "POST", { order_pay_id: this.payInfoId }).then(
async (res) => {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
// 调用微信支付
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_pay_id: this.payInfoId,
}
request(apiArr.tradeQuery, "POST", params).then(res => {
this.getRoomSelect();
this.getUserGovenmentMoney();
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '已取消支付' : '支付失败',
icon: 'none'
})
const params = {
order_pay_id: this.payInfoId,
}
request(apiArr.delPay, "POST", params).then(res => {
})
},
complete: () => {
// 支付完成后的回调,无论成功失败都会执行
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
}
);
},
//支付记录
getPayList() {
return new Promise((resolve, reject) => {
request(apiArr.getPayOrderList, "POST", {
room_id: this.currentRoom.room_id,
page_num: this.page_num,
page_size: this.page_size,
}).then((res) => {
// 判断是否还有更多数据
let flag = false;
if (res.rows && res.rows.length === this.page_size) {
flag = true;
} else {
flag = false;
}
this.flag = flag;
// 如果是第一页,直接替换数据;如果是加载更多,追加数据
if (this.page_num === 1) {
this.payOrderList = res.rows || [];
} else {
this.payOrderList = [...this.payOrderList, ...(res.rows || [])];
}
resolve();
}).catch((error) => {
reject(error);
});
});
},
//物业费详情
more(item) {
NavgateTo(`../providentFund/index?item=${JSON.stringify(item)}`);
},
},
};
</script>
<style>
@import url("./index.css");
</style>