first commit

This commit is contained in:
zhouyanli
2026-04-18 08:31:55 +08:00
commit eeb09abc04
989 changed files with 137562 additions and 0 deletions

View File

@@ -0,0 +1,351 @@
<template>
<view class="contentStyle" style="">
<view class="status-bar"></view>
<uni-nav-bar title="缴费记录" left-icon="left" @clickLeft="goBack" backgroundColor="transparent"
:border="false">
</uni-nav-bar>
<Loading mask="true" click="true" ref="loading"></Loading>
<!-- 表单区域 -->
<scroll-view class="page" scroll-y="true">
<!-- 累计缴费 -->
<view class="total-box">
<view class="total-title">累计缴费</view>
<view class="total-price">¥800.00</view>
<!-- 折线图 Canvas -->
<canvas canvas-id="chargeChart" class="chart-canvas"></canvas>
</view>
<!-- 缴费明细 -->
<view class="list-wrapper">
<!-- 按月份分组渲染 -->
<view class="month-group" v-for="(item, idx) in monthGroups" :key="idx">
<view class="month-title">
{{ item.month }} 缴费 ¥{{ item.total }}
</view>
<view class="item-list">
<view class="bill-item" v-for="bill in item.list" :key="bill.id">
<view class="bill-icon">
<text class="icon">{{ bill.icon }}</text>
</view>
<view class="bill-info">
<view class="name">{{ bill.name }}</view>
<view class="account">{{ bill.account }}</view>
</view>
<view class="bill-price">-{{ bill.amount }}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
onReady: function(e) {},
components: {
},
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)
}
},
created() {
},
onShow() {
},
mounted() {},
onReady() {
this.$nextTick(() => {
this.drawLineChart();
})
},
data() {
return {
/* 设定状态栏默认高度 */
statusBarHeight: 20,
// 折线图数据
chart: {
months: ['1月', '2月', '3月', '4月', '5月', '6月'],
values: [100, 140, 230, 100, 130, 100]
},
// ====================== 核心5月6月放在一个list里 ======================
billList: [
// 5月数据
{
id: 1,
month: 5,
name: '燃气费',
account: '123123123123',
amount: 25,
icon: ''
},
{
id: 2,
month: 5,
name: '水费',
account: '123123123123',
amount: 25,
icon: ''
},
// 6月数据
{
id: 3,
month: 6,
name: '燃气费',
account: '123123123123',
amount: 30,
icon: ''
},
{
id: 4,
month: 6,
name: '水费',
account: '123123123123',
amount: 10,
icon: ''
},
{
id: 5,
month: 6,
name: '电费',
account: '123123123123',
amount: 30,
icon: '⚡'
}
]
}
},
methods: {
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)
}
ctx.stroke()
// 绘制X轴月份
this.chart.months.forEach((m, i) => {
let x = 40 + i * stepX
ctx.fillText(m, x, h - 20)
})
// 绘制折线
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
})
})
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(this.chart.values[i] + '元', p.x, p.y - 10)
})
ctx.draw()
},
goBack() {
uni.redirectTo({
url: '/pages/payment-list/paymentIndex',
success: res => {},
fail: () => {},
complete: () => {}
});
},
},
}
</script>
<style lang="scss">
page {
background: #f2f1f6;
}
</style>
<style scoped>
.contentStyle {
display: flex;
flex-direction: column;
height: 100vh;
/* 关键:占满屏幕高度 */
background-color: #f9f9f9;
}
.page {
flex: 1;
overflow-y: auto;
padding: 0px 20px;
box-sizing: border-box;
background-color: #fff;
}
.total-box {
padding: 15px;
/* margin-bottom: 10px; */
}
.total-title {
font-size: 16px;
font-weight: 600;
color: #333;
}
.total-price {
font-size: 24px;
font-weight: bold;
margin-top: 6px;
margin-bottom: 10px;
}
.chart-canvas {
width: calc(100vw - 30px);
height: 30vh;
}
.list-wrapper {
padding: 0 15px;
}
.month-group {
padding-bottom: 15px;
border-bottom: 1px solid #f2f2f2;
}
.month-group:last-child {
border-bottom: none;
}
.month-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 15px;
}
.bill-item {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.bill-icon {
width: 40px;
height: 40px;
background: #e6efff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #4080FF;
margin-right: 12px;
font-size: 18px;
}
.bill-info {
flex: 1;
}
.name {
font-size: 14px;
color: #333;
font-weight: 600;
}
.account {
font-size: 12px;
color: #999;
margin-top: 4px;
}
.bill-price {
font-size: 16px;
color: #333;
}.status-bar{
width: 100vw;
height: 46px;
}
</style>