我的房屋流程对接接口,缴费页面功能修改一版
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
<uni-nav-bar title="缴费记录" left-icon="left" @clickLeft="goBack" backgroundColor="transparent" :border="false">
|
||||
</uni-nav-bar>
|
||||
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<scroll-view class="page" scroll-y="true">
|
||||
|
||||
@@ -14,8 +13,6 @@
|
||||
<view class="total-title">累计缴费</view>
|
||||
<view class="total-price">¥800.00</view>
|
||||
</view>
|
||||
<!-- 折线图 Canvas -->
|
||||
<!-- <canvas canvas-id="chargeChart" class="chart-canvas"></canvas> -->
|
||||
|
||||
<view class="chart-box">
|
||||
<view v-if="chartData.length === 0" class="empty-state">
|
||||
@@ -66,235 +63,213 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
onReady: function(e) {},
|
||||
components: {
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
computed
|
||||
|
||||
} from 'vue'
|
||||
import {
|
||||
onShow,
|
||||
onReady,
|
||||
onReachBottom,
|
||||
onLoad,
|
||||
onUnload,
|
||||
onPullDownRefresh
|
||||
} from '@dcloudio/uni-app'
|
||||
|
||||
// 响应式数据
|
||||
const statusBarHeight = ref(20)
|
||||
|
||||
const chartData = ref([{
|
||||
month: '1月',
|
||||
price: 250
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
|
||||
// 自动按月份分组
|
||||
monthGroups() {
|
||||
let map = {}
|
||||
this.billList.forEach(bill => {
|
||||
if (!map[bill.month]) {
|
||||
map[bill.month] = {
|
||||
month: bill.month,
|
||||
total: 0,
|
||||
list: []
|
||||
}
|
||||
}
|
||||
map[bill.month].list.push(bill)
|
||||
map[bill.month].total += bill.amount
|
||||
})
|
||||
return Object.values(map).sort((a, b) => b.month - a.month)
|
||||
}
|
||||
{
|
||||
month: '2月',
|
||||
price: 130
|
||||
},
|
||||
created() {
|
||||
|
||||
{
|
||||
month: '3月',
|
||||
price: 220
|
||||
},
|
||||
onShow() {
|
||||
|
||||
{
|
||||
month: '4月',
|
||||
price: 250
|
||||
},
|
||||
|
||||
mounted() {},
|
||||
|
||||
onReady() {
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.drawLineChart();
|
||||
})
|
||||
{
|
||||
month: '5月',
|
||||
price: 100
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
/* 设定状态栏默认高度 */
|
||||
statusBarHeight: 20,
|
||||
// 完全对应你图片的数据
|
||||
chartData: [{
|
||||
month: '1月',
|
||||
price: 250
|
||||
},
|
||||
{
|
||||
month: '2月',
|
||||
price: 130
|
||||
},
|
||||
{
|
||||
month: '3月',
|
||||
price: 220
|
||||
},
|
||||
{
|
||||
month: '4月',
|
||||
price: 250
|
||||
},
|
||||
{
|
||||
month: '5月',
|
||||
price: 100
|
||||
},
|
||||
{
|
||||
month: '6月',
|
||||
price: 130
|
||||
}
|
||||
],
|
||||
maxPrice: 250, // 最大值(基准高度)
|
||||
barMaxHeight: 300, // 柱子最大高度rpx
|
||||
// canvas折线图数据
|
||||
chart: {
|
||||
months: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
||||
values: [100, 140, 230, 100, 130, 100]
|
||||
},
|
||||
{
|
||||
month: '6月',
|
||||
price: 130
|
||||
}
|
||||
])
|
||||
|
||||
billList: [
|
||||
// 5月数据
|
||||
{
|
||||
id: 1,
|
||||
month: 5,
|
||||
name: '燃气费',
|
||||
account: '123123123123',
|
||||
amount: 25,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/gas.png",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
month: 5,
|
||||
name: '水费',
|
||||
account: '123123123123',
|
||||
amount: 25,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/water.png",
|
||||
},
|
||||
const maxPrice = ref(250)
|
||||
const barMaxHeight = ref(300)
|
||||
|
||||
// 6月数据
|
||||
{
|
||||
id: 3,
|
||||
month: 6,
|
||||
name: '燃气费',
|
||||
account: '123123123123',
|
||||
amount: 30,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/gas.png",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
month: 6,
|
||||
name: '水费',
|
||||
account: '123123123123',
|
||||
amount: 10,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/water.png",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
month: 6,
|
||||
name: '电费',
|
||||
account: '123123123123',
|
||||
amount: 30,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/electric.png",
|
||||
}
|
||||
]
|
||||
const chart = ref({
|
||||
months: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
||||
values: [100, 140, 230, 100, 130, 100]
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
const billList = ref([{
|
||||
id: 1,
|
||||
month: 5,
|
||||
name: '燃气费',
|
||||
account: '123123123123',
|
||||
amount: 25,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/gas.png"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
month: 5,
|
||||
name: '水费',
|
||||
account: '123123123123',
|
||||
amount: 25,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/water.png"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
month: 6,
|
||||
name: '燃气费',
|
||||
account: '123123123123',
|
||||
amount: 30,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/gas.png"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
month: 6,
|
||||
name: '水费',
|
||||
account: '123123123123',
|
||||
amount: 10,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/water.png"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
month: 6,
|
||||
name: '电费',
|
||||
account: '123123123123',
|
||||
amount: 30,
|
||||
icon: "http://47.104.199.163:9090/images/propertyImgs/electric.png"
|
||||
}
|
||||
])
|
||||
|
||||
|
||||
methods: {
|
||||
// 计算每个柱子自适应高度(按金额比例换算)
|
||||
barHeight(price) {
|
||||
const height = (price / this.maxPrice) * this.barMaxHeight
|
||||
return `${height}rpx`
|
||||
},
|
||||
drawLineChart() {
|
||||
const ctx = uni.createCanvasContext('chargeChart', this)
|
||||
const canvasPage = uni.getSystemInfoSync();
|
||||
const w = canvasPage.windowWidth - 30;
|
||||
const h = canvasPage.windowHeight * 0.3;
|
||||
|
||||
const padding = 40
|
||||
const stepX = (w - 60) / (this.chart.months.length - 1)
|
||||
const maxVal = 250
|
||||
|
||||
ctx.setFillStyle('#999')
|
||||
ctx.setFontSize(12)
|
||||
ctx.setTextAlign('center')
|
||||
|
||||
// 绘制网格
|
||||
ctx.beginPath()
|
||||
ctx.setStrokeStyle('#d8d8d8')
|
||||
ctx.setLineWidth(1)
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
let y = padding + (h - padding * 2) * (1 - i / 5)
|
||||
ctx.moveTo(40, y)
|
||||
ctx.lineTo(w - 20, y)
|
||||
ctx.fillText(i * 50 + '元', 20, y + 4)
|
||||
// 计算属性 —— 月份分组
|
||||
const monthGroups = computed(() => {
|
||||
let map = {}
|
||||
billList.value.forEach(bill => {
|
||||
if (!map[bill.month]) {
|
||||
map[bill.month] = {
|
||||
month: bill.month,
|
||||
total: 0,
|
||||
list: []
|
||||
}
|
||||
ctx.stroke()
|
||||
}
|
||||
map[bill.month].list.push(bill)
|
||||
map[bill.month].total += bill.amount
|
||||
})
|
||||
return Object.values(map).sort((a, b) => b.month - a.month)
|
||||
})
|
||||
|
||||
// 绘制X轴月份
|
||||
this.chart.months.forEach((m, i) => {
|
||||
let x = 40 + i * stepX
|
||||
ctx.fillText(m, x, h - 20)
|
||||
})
|
||||
// 生命周期
|
||||
onShow(() => {})
|
||||
onMounted(() => {})
|
||||
onReady(() => {
|
||||
drawLineChart()
|
||||
})
|
||||
|
||||
// 绘制折线
|
||||
let points = []
|
||||
this.chart.values.forEach((val, i) => {
|
||||
let x = 40 + i * stepX
|
||||
let y = padding + (h - padding * 2) * (1 - val / maxVal)
|
||||
points.push({
|
||||
x,
|
||||
y
|
||||
})
|
||||
})
|
||||
// 方法
|
||||
const barHeight = (price) => {
|
||||
const height = (price / maxPrice.value) * barMaxHeight.value
|
||||
return `${height}rpx`
|
||||
}
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.setStrokeStyle('#4080FF')
|
||||
ctx.setLineWidth(2)
|
||||
points.forEach((p, i) => {
|
||||
if (i === 0) ctx.moveTo(p.x, p.y)
|
||||
else ctx.lineTo(p.x, p.y)
|
||||
})
|
||||
ctx.stroke()
|
||||
const drawLineChart = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
const ctx = uni.createCanvasContext('chargeChart')
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
const ctx = uni.createCanvasContext('chargeChart', this)
|
||||
// #endif
|
||||
|
||||
// 绘制圆点
|
||||
points.forEach((p, i) => {
|
||||
ctx.beginPath()
|
||||
ctx.arc(p.x, p.y, 3, 0, 2 * Math.PI)
|
||||
ctx.setFillStyle('#fff')
|
||||
ctx.fill()
|
||||
ctx.setStrokeStyle('#4080FF')
|
||||
ctx.setLineWidth(2)
|
||||
ctx.stroke()
|
||||
const canvasPage = uni.getSystemInfoSync();
|
||||
const w = canvasPage.windowWidth - 30;
|
||||
const h = canvasPage.windowHeight * 0.3;
|
||||
const padding = 40
|
||||
const stepX = (w - 60) / (chart.value.months.length - 1)
|
||||
const maxVal = 250
|
||||
|
||||
ctx.setFillStyle('#4080FF')
|
||||
ctx.setFontSize(13)
|
||||
ctx.fillText(this.chart.values[i] + '元', p.x, p.y - 10)
|
||||
})
|
||||
ctx.setFillStyle('#999')
|
||||
ctx.setFontSize(12)
|
||||
ctx.setTextAlign('center')
|
||||
|
||||
ctx.draw()
|
||||
},
|
||||
goBack() {
|
||||
uni.redirectTo({
|
||||
url: '/pageSubPack/payment-list/paymentIndex',
|
||||
success: res => {},
|
||||
fail: () => {},
|
||||
complete: () => {}
|
||||
});
|
||||
},
|
||||
ctx.beginPath()
|
||||
ctx.setStrokeStyle('#d8d8d8')
|
||||
ctx.setLineWidth(1)
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
let y = padding + (h - padding * 2) * (1 - i / 5)
|
||||
ctx.moveTo(40, y)
|
||||
ctx.lineTo(w - 20, y)
|
||||
ctx.fillText(i * 50 + '元', 20, y + 4)
|
||||
}
|
||||
ctx.stroke()
|
||||
|
||||
},
|
||||
chart.value.months.forEach((m, i) => {
|
||||
let x = 40 + i * stepX
|
||||
ctx.fillText(m, x, h - 20)
|
||||
})
|
||||
|
||||
let points = []
|
||||
chart.value.values.forEach((val, i) => {
|
||||
let x = 40 + i * stepX
|
||||
let y = padding + (h - padding * 2) * (1 - val / maxVal)
|
||||
points.push({
|
||||
x,
|
||||
y
|
||||
})
|
||||
})
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.setStrokeStyle('#4080FF')
|
||||
ctx.setLineWidth(2)
|
||||
points.forEach((p, i) => {
|
||||
if (i === 0) ctx.moveTo(p.x, p.y)
|
||||
else ctx.lineTo(p.x, p.y)
|
||||
})
|
||||
ctx.stroke()
|
||||
|
||||
points.forEach((p, i) => {
|
||||
ctx.beginPath()
|
||||
ctx.arc(p.x, p.y, 3, 0, 2 * Math.PI)
|
||||
ctx.setFillStyle('#fff')
|
||||
ctx.fill()
|
||||
ctx.setStrokeStyle('#4080FF')
|
||||
ctx.setLineWidth(2)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.setFillStyle('#4080FF')
|
||||
ctx.setFontSize(13)
|
||||
ctx.fillText(chart.value.values[i] + '元', p.x, p.y - 10)
|
||||
})
|
||||
|
||||
ctx.draw()
|
||||
}
|
||||
|
||||
const goBack = () => {
|
||||
uni.redirectTo({
|
||||
url: '/pageSubPack/payment-list/paymentIndex'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
// background: #f2f1f6;
|
||||
@@ -306,7 +281,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
/* 关键:占满屏幕高度 */
|
||||
background: linear-gradient(to left bottom, #e2efff 0%, #f9f9f9 50%);
|
||||
}
|
||||
|
||||
@@ -315,15 +289,12 @@
|
||||
overflow-y: auto;
|
||||
padding: 0px 40rpx;
|
||||
box-sizing: border-box;
|
||||
/* background-color: #fff; */
|
||||
}
|
||||
|
||||
|
||||
.total-box {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -399,7 +370,6 @@
|
||||
.bill-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
/* background: #e6efff; */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -440,19 +410,17 @@
|
||||
height: 46px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
/* 图表外层容器 横向排列 */
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 444rpx;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-around;
|
||||
/* padding: 40rpx 20rpx; */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 单个柱子单元:垂直排列 文字+柱子+月份 */
|
||||
.chart-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -462,22 +430,18 @@
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 顶部金额标签 */
|
||||
.chart-label {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 蓝色圆角柱子 完全还原原图顶部圆角 */
|
||||
.chart-bar {
|
||||
width: 40rpx;
|
||||
background: #3388ff;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
/* 只有顶部圆角!和原图一模一样 */
|
||||
}
|
||||
|
||||
/* 底部月份文字 */
|
||||
.chart-month {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
|
||||
Reference in New Issue
Block a user