Browse Source

账户 和积分

master
DU 6 months ago
parent
commit
b124923d25
  1. 1
      src/pagesOrder/accountBalance/components/BalanceList.scss
  2. 21
      src/pagesOrder/accountBalance/components/OpenRecordList.scss
  3. 95
      src/pagesOrder/accountBalance/components/OpenRecordList.tsx
  4. 121
      src/pagesOrder/accountBalance/components/RechargeRecordList.scss
  5. 177
      src/pagesOrder/accountBalance/components/RechargeRecordList.tsx
  6. 18
      src/pagesOrder/accountBalance/index.tsx

1
src/pagesOrder/accountBalance/components/BalanceList.scss

@ -57,6 +57,7 @@
// 余额和存柜信息卡片 // 余额和存柜信息卡片
.info-cards { .info-cards {
display: flex; display: flex;
align-items: center;
gap: 26px; gap: 26px;
margin-bottom: 26px; margin-bottom: 26px;

21
src/pagesOrder/accountBalance/components/OpenRecordList.scss

@ -82,7 +82,7 @@
.item-row { .item-row {
display: flex; display: flex;
align-items: center; align-items: baseline;
justify-content: space-between; justify-content: space-between;
.store-name { .store-name {
@ -92,13 +92,13 @@
} }
.status { .status {
font-size: 25px; font-size: 32px;
color: #F5C8A6; color: #F5C8A6;
} }
.vip-type { .vip-type {
font-size: 25px; font-size: 25px;
color: #B8B8B8; color: #FFFFFF;
} }
.price { .price {
@ -107,13 +107,22 @@
} }
.pay-time { .pay-time {
font-size: 25px; font-size: 22px;
color: #8B8B8B; color: #999999;
} }
.actual-pay { .actual-pay {
font-size: 25px; display: flex;
align-items: baseline;
color: #FFFFFF; color: #FFFFFF;
.pay-label {
font-size: 22px;
}
.pay-amount {
font-size: 33px;
}
} }
} }

95
src/pagesOrder/accountBalance/components/OpenRecordList.tsx

@ -4,6 +4,7 @@
import { View, Text, Image } from '@tarojs/components' import { View, Text, Image } from '@tarojs/components'
import { FC, useState } from 'react' import { FC, useState } from 'react'
import { ArrowDown } from '@taroify/icons' import { ArrowDown } from '@taroify/icons'
import { Popup, DatetimePicker } from '@taroify/core'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import './OpenRecordList.scss' import './OpenRecordList.scss'
@ -25,6 +26,48 @@ interface OpenRecordListProps {
const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => { const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => {
const [selectedMonth, setSelectedMonth] = useState('2025-02') const [selectedMonth, setSelectedMonth] = useState('2025-02')
const [datePickerOpen, setDatePickerOpen] = useState(false)
const [pickerValue, setPickerValue] = useState(new Date())
const [dataList, setDataList] = useState<OpenRecordItem[]>(recordList)
// 模拟接口请求开通记录数据
const fetchOpenRecords = async (yearMonth: string) => {
Taro.showLoading({
title: '加载中...',
mask: true
})
// 模拟接口请求
return new Promise<OpenRecordItem[]>((resolve) => {
setTimeout(() => {
// 模拟返回数据
const mockData: OpenRecordItem[] = [
{
id: `${yearMonth}-1`,
storeName: '来力.山岩',
payTime: `${yearMonth}-20 16:30:00`,
vipType: 'VIP年卡',
amount: 299,
status: '已生效',
canRefund: true
},
{
id: `${yearMonth}-2`,
storeName: '来力.山岩',
payTime: `${yearMonth}-05 09:15:00`,
vipType: 'VIP月卡',
amount: 99,
status: '已生效',
canRefund: false
}
]
setDataList(mockData)
Taro.hideLoading()
resolve(mockData)
}, 1000) // 模拟 1 秒的网络延迟
})
}
// 按月份分组记录 // 按月份分组记录
const groupByMonth = (records: OpenRecordItem[]) => { const groupByMonth = (records: OpenRecordItem[]) => {
@ -39,21 +82,35 @@ const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => {
return groups return groups
} }
const groupedRecords = groupByMonth(recordList) const groupedRecords = groupByMonth(dataList)
// 计算当月总金额 // 计算当月总金额
const calculateMonthTotal = (records: OpenRecordItem[]) => { const calculateMonthTotal = (records: OpenRecordItem[]) => {
return records.reduce((sum, record) => sum + record.amount, 0) return records.reduce((sum, record) => sum + record.amount, 0)
} }
// 选择月份 // 打开月份选择器
const handleSelectMonth = () => { const handleSelectMonth = () => {
console.log('选择月份') setDatePickerOpen(true)
// TODO: 打开月份选择器 }
Taro.showToast({
title: '月份选择功能开发中', // 确认选择月份
icon: 'none' const handleDateConfirm = async (value: Date) => {
}) const year = value.getFullYear()
const month = String(value.getMonth() + 1).padStart(2, '0')
const formattedMonth = `${year}-${month}`
setSelectedMonth(formattedMonth)
setPickerValue(value)
setDatePickerOpen(false)
// 调用接口请求该月份的数据
await fetchOpenRecords(formattedMonth)
}
// 取消选择
const handleDateCancel = () => {
setDatePickerOpen(false)
} }
// 退款 // 退款
@ -76,7 +133,7 @@ const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => {
return ( return (
<View className="open-record-list"> <View className="open-record-list">
{recordList.length === 0 ? ( {dataList.length === 0 ? (
<View className="empty-data"> <View className="empty-data">
<Image className="empty-image" src={noDataImg} mode="aspectFit" /> <Image className="empty-image" src={noDataImg} mode="aspectFit" />
</View> </View>
@ -124,7 +181,10 @@ const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => {
{/* 第三行:支付时间 + 实付金额 */} {/* 第三行:支付时间 + 实付金额 */}
<View className="item-row"> <View className="item-row">
<Text className="pay-time">{item.payTime}</Text> <Text className="pay-time">{item.payTime}</Text>
<Text className="actual-pay"> {item.amount.toFixed(2)}</Text> <View className="actual-pay">
<Text className="pay-label"> </Text>
<Text className="pay-amount">{item.amount.toFixed(2)}</Text>
</View>
</View> </View>
{/* 退款按钮(7天内可退款) */} {/* 退款按钮(7天内可退款) */}
@ -154,6 +214,21 @@ const OpenRecordList: FC<OpenRecordListProps> = ({ recordList }) => {
</View> </View>
</> </>
)} )}
{/* 年月选择器 */}
<Popup
open={datePickerOpen}
placement="bottom"
onClose={() => setDatePickerOpen(false)}
>
<DatetimePicker
type="year-month"
value={pickerValue}
onChange={setPickerValue}
onCancel={handleDateCancel}
onConfirm={handleDateConfirm}
/>
</Popup>
</View> </View>
) )
} }

121
src/pagesOrder/accountBalance/components/RechargeRecordList.scss

@ -14,42 +14,119 @@
} }
} }
.record-card { // 月份卡片
.month-card {
background-color: #202029; background-color: #202029;
border-radius: 12px; border-radius: 12px;
padding: 33px 30px;
margin-bottom: 30px; margin-bottom: 30px;
&:last-child { // 月份标题行
margin-bottom: 0; .month-header {
}
.record-header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 25px; padding: 36px 30px;
.month-left {
display: flex;
align-items: center;
gap: 10px;
.store-name { .month-text {
font-size: 33px; font-size: 33px;
color: #FFFEFE; color: #FFFEFE;
flex: 1; }
.month-arrow {
flex-shrink: 0;
}
} }
.amount { .month-right {
font-size: 33px; display: flex;
color: #01CA68; align-items: baseline;
gap: 4px;
.amount-label {
font-size: 25px;
color: #999999;
margin-right: 8px;
}
.amount-symbol {
font-size: 25px;
color: #FFFFFF;
}
.amount-value {
font-size: 30px;
color: #FFFFFF;
}
} }
} }
.record-info { // 分割线
display: flex; .divider {
flex-direction: column; height: 1px;
gap: 15px; background-color: #45454C;
}
// 记录列表
.record-list {
padding: 20px;
.record-item {
display: flex;
flex-direction: column;
gap: 20px;
.item-row {
display: flex;
align-items: baseline;
justify-content: space-between;
.store-name {
font-size: 33px;
color: #FFFEFE;
flex: 1;
}
.status {
font-size: 32px;
color: #F5C8A6;
}
.recharge-type {
font-size: 25px;
color: #FFFFFF;
}
.recharge-time {
font-size: 22px;
color: #999999;
}
.actual-pay {
display: flex;
align-items: baseline;
color: #FFFFFF;
.pay-label {
font-size: 22px;
}
.pay-amount {
font-size: 33px;
}
}
}
}
.info-text { // item 之间的分割线
font-size: 25px; .item-divider {
color: #B8B8B8; height: 1px;
background-color: #45454C;
margin: 20px 0;
} }
} }
} }

177
src/pagesOrder/accountBalance/components/RechargeRecordList.tsx

@ -2,7 +2,10 @@
* *
*/ */
import { View, Text, Image } from '@tarojs/components' import { View, Text, Image } from '@tarojs/components'
import { FC } from 'react' import { FC, useState } from 'react'
import { ArrowDown } from '@taroify/icons'
import { Popup, DatetimePicker } from '@taroify/core'
import Taro from '@tarojs/taro'
import './RechargeRecordList.scss' import './RechargeRecordList.scss'
const noDataImg = require('../../../assets/big/noData.png') const noDataImg = require('../../../assets/big/noData.png')
@ -21,27 +24,158 @@ interface RechargeRecordListProps {
} }
const RechargeRecordList: FC<RechargeRecordListProps> = ({ recordList }) => { const RechargeRecordList: FC<RechargeRecordListProps> = ({ recordList }) => {
const [selectedMonth, setSelectedMonth] = useState('2025-03')
const [datePickerOpen, setDatePickerOpen] = useState(false)
const [pickerValue, setPickerValue] = useState(new Date())
const [dataList, setDataList] = useState<RechargeRecordItem[]>(recordList)
// 模拟接口请求充值记录数据
const fetchRechargeRecords = async (yearMonth: string) => {
Taro.showLoading({
title: '加载中...',
mask: true
})
// 模拟接口请求
return new Promise<RechargeRecordItem[]>((resolve) => {
setTimeout(() => {
// 模拟返回数据
const mockData: RechargeRecordItem[] = [
{
id: `${yearMonth}-1`,
storeName: '来力.山岩',
rechargeTime: `${yearMonth}-15 14:30:00`,
rechargeType: '账户充值',
amount: 100,
status: '充值完成'
},
{
id: `${yearMonth}-2`,
storeName: '来力.山岩',
rechargeTime: `${yearMonth}-10 10:20:00`,
rechargeType: '账户充值',
amount: 200,
status: '充值完成'
}
]
setDataList(mockData)
Taro.hideLoading()
resolve(mockData)
}, 1000) // 模拟 1 秒的网络延迟
})
}
// 按月份分组记录
const groupByMonth = (records: RechargeRecordItem[]) => {
const groups: Record<string, RechargeRecordItem[]> = {}
records.forEach(record => {
const month = record.rechargeTime.substring(0, 7) // 提取 YYYY-MM
if (!groups[month]) {
groups[month] = []
}
groups[month].push(record)
})
return groups
}
const groupedRecords = groupByMonth(dataList)
// 计算当月总充值金额
const calculateMonthTotal = (records: RechargeRecordItem[]) => {
return records.reduce((sum, record) => sum + record.amount, 0)
}
// 打开月份选择器
const handleSelectMonth = () => {
setDatePickerOpen(true)
}
// 确认选择月份
const handleDateConfirm = async (value: Date) => {
const year = value.getFullYear()
const month = String(value.getMonth() + 1).padStart(2, '0')
const formattedMonth = `${year}-${month}`
setSelectedMonth(formattedMonth)
setPickerValue(value)
setDatePickerOpen(false)
// 调用接口请求该月份的数据
await fetchRechargeRecords(formattedMonth)
}
// 取消选择
const handleDateCancel = () => {
setDatePickerOpen(false)
}
return ( return (
<View className="recharge-record-list"> <View className="recharge-record-list">
{recordList.length === 0 ? ( {dataList.length === 0 ? (
<View className="empty-data"> <View className="empty-data">
<Image className="empty-image" src={noDataImg} mode="aspectFit" /> <Image className="empty-image" src={noDataImg} mode="aspectFit" />
</View> </View>
) : ( ) : (
<> <>
{recordList.map(item => ( {Object.keys(groupedRecords).map(month => {
<View key={item.id} className="record-card"> const monthRecords = groupedRecords[month]
<View className="record-header"> const monthTotal = calculateMonthTotal(monthRecords)
<Text className="store-name">{item.storeName}</Text>
<Text className="amount">+{item.amount.toFixed(2)}</Text> return (
</View> <View key={month} className="month-card">
<View className="record-info"> {/* 月份标题和充值统计 */}
<Text className="info-text">{item.rechargeType}</Text> <View className="month-header">
<Text className="info-text">{item.rechargeTime}</Text> <View className="month-left" onClick={handleSelectMonth}>
<Text className="info-text">{item.status}</Text> <Text className="month-text">{month}</Text>
<ArrowDown className="month-arrow" size="20px" color="#FFFEFE" />
</View>
<View className="month-right">
<Text className="amount-label"></Text>
<Text className="amount-symbol"></Text>
<Text className="amount-value">{monthTotal.toFixed(2)}</Text>
</View>
</View>
{/* 分割线 */}
<View className="divider" />
{/* 记录列表 */}
<View className="record-list">
{monthRecords.map((item, index) => (
<View key={item.id}>
<View className="record-item">
{/* 第一行:店铺名称 + 状态 */}
<View className="item-row">
<Text className="store-name">{item.storeName}</Text>
<Text className="status">{item.status}</Text>
</View>
{/* 第二行:充值类型 */}
<View className="item-row">
<Text className="recharge-type">{item.rechargeType}</Text>
</View>
{/* 第三行:充值时间 + 实付金额 */}
<View className="item-row">
<Text className="recharge-time">{item.rechargeTime}</Text>
<View className="actual-pay">
<Text className="pay-label"> </Text>
<Text className="pay-amount">{item.amount.toFixed(2)}</Text>
</View>
</View>
</View>
{/* item 之间的分割线 */}
{index < monthRecords.length - 1 && (
<View className="item-divider" />
)}
</View>
))}
</View>
</View> </View>
</View> )
))} })}
{/* 到底了提示 */} {/* 到底了提示 */}
<View className="list-end"> <View className="list-end">
@ -49,6 +183,21 @@ const RechargeRecordList: FC<RechargeRecordListProps> = ({ recordList }) => {
</View> </View>
</> </>
)} )}
{/* 年月选择器 */}
<Popup
open={datePickerOpen}
placement="bottom"
onClose={() => setDatePickerOpen(false)}
>
<DatetimePicker
type="year-month"
value={pickerValue}
onChange={setPickerValue}
onCancel={handleDateCancel}
onConfirm={handleDateConfirm}
/>
</Popup>
</View> </View>
) )
} }

18
src/pagesOrder/accountBalance/index.tsx

@ -77,19 +77,19 @@ const AccountBalance = () => {
const [rechargeRecordList] = useState([ const [rechargeRecordList] = useState([
{ {
id: '1', id: '1',
storeName: '北京XXXXXX店', storeName: '北京XXXXXXXXXXXXX店',
rechargeTime: '2026-01-15 10:20:30', rechargeTime: '2025-03-09 00:00:00',
rechargeType: '微信支付', rechargeType: '账户充值',
amount: 500.00, amount: 100.00,
status: '充值成' status: '充值成'
}, },
{ {
id: '2', id: '2',
storeName: '北京XXXXXXXXXXXXX店', storeName: '北京XXX店',
rechargeTime: '2026-01-10 14:15:20', rechargeTime: '2025-03-09 00:00:00',
rechargeType: '支付宝', rechargeType: '账户充值',
amount: 100.00, amount: 100.00,
status: '充值成' status: '充值成'
} }
]) ])

Loading…
Cancel
Save