优化细节

This commit is contained in:
2026-02-06 12:06:33 +08:00
parent b7545173c6
commit d00f0b7412
83 changed files with 3901 additions and 2354 deletions

View File

@@ -1,63 +1,63 @@
<template>
<template>
<view class="finance-balance-stats">
<!-- 顶部数据统计卡片 (3列布局) -->
<!-- 椤堕儴鏁版嵁缁熻鍗$墖 (3鍒楀竷灞€) -->
<view class="stats-grid">
<view class="stat-card border-shadow">
<view class="stat-icon-circle bg-blue">
<text class="icon-white">💰</text>
<text class="icon-white">馃挵</text>
</view>
<view class="stat-content">
<text class="stat-value">1447117274.55</text>
<text class="stat-label">当前余额</text>
<text class="stat-label">褰撳墠浣欓</text>
</view>
</view>
<view class="stat-card border-shadow">
<view class="stat-icon-circle bg-orange">
<text class="icon-white">🏦</text>
<text class="icon-white">馃彟</text>
</view>
<view class="stat-content">
<text class="stat-value">1602611838.49</text>
<text class="stat-label">累计余额</text>
<text class="stat-label">绱浣欓</text>
</view>
</view>
<view class="stat-card border-shadow">
<view class="stat-icon-circle bg-green">
<text class="icon-white">💳</text>
<text class="icon-white">馃挸</text>
</view>
<view class="stat-content">
<text class="stat-value">155494563.94</text>
<text class="stat-label">累计消耗余额</text>
<text class="stat-label">绱娑堣€椾綑棰?/text>
</view>
</view>
</view>
<!-- 时间筛选区 -->
<!-- 鏃堕棿绛涢€夊尯 -->
<view class="filter-bar border-shadow">
<view class="filter-item">
<text class="filter-label">时间选择:</text>
<text class="filter-label">鏃堕棿閫夋嫨:</text>
<view class="date-picker-wrap">
<text class="calendar-icon">📅</text>
<text class="calendar-icon">馃搮</text>
<text class="date-range">2026/01/05 - 2026/02/03</text>
</view>
</view>
</view>
<!-- 趋势图表区 (CRMEB 1:1) -->
<!-- 瓒嬪娍鍥捐〃鍖?(CRMEB 1:1) -->
<view class="chart-box border-shadow">
<view class="chart-header">
<text class="chart-title">余额使用趋势</text>
<text class="chart-title">浣欓浣跨敤瓒嬪娍</text>
<view class="chart-legend">
<view class="legend-item">
<view class="dot blue-dot"></view>
<text class="legend-txt">余额积累</text>
<text class="legend-txt">浣欓绉疮</text>
</view>
<view class="legend-item">
<view class="dot green-dot"></view>
<text class="legend-txt">余额消耗</text>
<text class="legend-txt">浣欓娑堣€?/text>
</view>
</view>
<view class="chart-ops">
<text class="op-icon">📥</text>
<text class="op-icon">馃摜</text>
</view>
</view>
<view class="main-chart-wrap">
@@ -65,26 +65,26 @@
</view>
</view>
<!-- 底部双列分析 -->
<!-- 搴曢儴鍙屽垪鍒嗘瀽 -->
<view class="bottom-analysis">
<view class="analysis-box border-shadow">
<view class="box-header">
<text class="box-title">余额来源分析</text>
<text class="box-title">浣欓鏉ユ簮鍒嗘瀽</text>
<view class="btn-toggle" @click="toggleSourceStyle">
<text class="toggle-txt">切换样式</text>
<text class="toggle-txt">鍒囨崲鏍峰紡</text>
</view>
</view>
<view class="chart-container">
<!-- 样式 0: 图表 -->
<!-- 鏍峰紡 0: 鍥捐〃 -->
<EChartsView v-if="sourceStyleMode == 0 && sourceOption != null" :option="sourceOption" class="pie-chart" />
<!-- 样式 1: 列表 -->
<!-- 鏍峰紡 1: 鍒楄〃 -->
<view v-if="sourceStyleMode == 1" class="stats-table">
<view class="table-header">
<text class="th col-idx">序号</text>
<text class="th col-name">来源</text>
<text class="th col-amount">金额</text>
<text class="th col-percent">占比率</text>
<text class="th col-idx">搴忓彿</text>
<text class="th col-name">鏉ユ簮</text>
<text class="th col-amount">閲戦</text>
<text class="th col-percent">鍗犳瘮鐜?/text>
</view>
<scroll-view class="table-body">
<view class="table-row" v-for="(item, index) in sourceData" :key="index">
@@ -104,22 +104,22 @@
</view>
<view class="analysis-box border-shadow">
<view class="box-header">
<text class="box-title">余额消耗</text>
<text class="box-title">浣欓娑堣€?/text>
<view class="btn-toggle" @click="toggleConsumptionStyle">
<text class="toggle-txt">切换样式</text>
<text class="toggle-txt">鍒囨崲鏍峰紡</text>
</view>
</view>
<view class="chart-container">
<!-- 样式 0: 图表 -->
<!-- 鏍峰紡 0: 鍥捐〃 -->
<EChartsView v-if="consumptionStyleMode == 0 && consumptionOption != null" :option="consumptionOption" class="pie-chart" />
<!-- 样式 1: 列表 -->
<!-- 鏍峰紡 1: 鍒楄〃 -->
<view v-if="consumptionStyleMode == 1" class="stats-table">
<view class="table-header">
<text class="th col-idx">序号</text>
<text class="th col-name">来源</text>
<text class="th col-amount">金额</text>
<text class="th col-percent">占比率</text>
<text class="th col-idx">搴忓彿</text>
<text class="th col-name">鏉ユ簮</text>
<text class="th col-amount">閲戦</text>
<text class="th col-percent">鍗犳瘮鐜?/text>
</view>
<scroll-view class="table-body">
<view class="table-row" v-for="(item, index) in consumptionDataList" :key="index">
@@ -149,28 +149,28 @@ const trendOption = ref<any>(null)
const sourceOption = ref<any>(null)
const consumptionOption = ref<any>(null)
// 样式切换状态: 0=图表, 1=列表
// 鏍峰紡鍒囨崲鐘舵€? 0=鍥捐〃, 1=鍒楄〃
const sourceStyleMode = ref(0)
const consumptionStyleMode = ref(0)
// 统计数据 (使用 ref 保证响应式)
// 缁熻鏁版嵁 (浣跨敤 ref 淇濊瘉鍝嶅簲寮?
const sourceData = ref([
{ value: 125000.00, name: '系统增加', percent: 40.00 },
{ value: 93750.00, name: '用户充值', percent: 30.00 },
{ value: 78125.00, name: '佣金提现', percent: 25.00 },
{ value: 62500.00, name: '抽奖赠送', percent: 20.00 },
{ value: 46875.00, name: '商品退款', percent: 15.00 }
{ value: 125000.00, name: '绯荤粺澧炲姞', percent: 40.00 },
{ value: 93750.00, name: '鐢ㄦ埛鍏呭€?, percent: 30.00 },
{ value: 78125.00, name: '浣i噾鎻愮幇', percent: 25.00 },
{ value: 62500.00, name: '鎶藉璧犻€?, percent: 20.00 },
{ value: 46875.00, name: '鍟嗗搧閫€娆?, percent: 15.00 }
])
const consumptionDataList = ref([
{ value: 435692.51, name: '购买商品', percent: 50.00 },
{ value: 8060.18, name: '购买会员', percent: 20.00 },
{ value: 0.00, name: '充值退款', percent: 15.00 },
{ value: 0.00, name: '系统减少', percent: 15.00 }
{ value: 435692.51, name: '璐拱鍟嗗搧', percent: 50.00 },
{ value: 8060.18, name: '璐拱浼氬憳', percent: 20.00 },
{ value: 0.00, name: '鍏呭€奸€€娆?, percent: 15.00 },
{ value: 0.00, name: '绯荤粺鍑忓皯', percent: 15.00 }
])
/**
* 转换 Plain Object 工具
* 杞崲 Plain Object 宸ュ叿
*/
function toPlainObject(obj : any) : any {
if (obj == null) return null
@@ -225,14 +225,14 @@ function initTrendChart() {
},
series: [
{
name: '余额积累',
name: '浣欓绉疮',
type: 'line',
smooth: true,
data: accumulationData,
itemStyle: { color: '#1890ff' }
},
{
name: '余额消耗',
name: '浣欓娑堣€?,
type: 'line',
smooth: true,
data: consumptionData,
@@ -250,12 +250,12 @@ function initSourceChart() {
color: ['#5b8ff9', '#5ad8a6', '#5d7092', '#f6bd16', '#e8684a'],
series: [
{
name: '余额来源',
name: '浣欓鏉ユ簮',
type: 'pie',
radius: '70%',
center: ['40%', '50%'],
label: { show: true, fontSize: 11, formatter: '{b}\n{c}%' },
// 关键点:将图表数据映射到 percent 字段
// 鍏抽敭鐐癸細灏嗗浘琛ㄦ暟鎹槧灏勫埌 percent 瀛楁
data: sourceData.value.map(item => ({ value: item.percent, name: item.name }))
}
]
@@ -270,12 +270,12 @@ function initConsumptionChart() {
color: ['#5b8ff9', '#5ad8a6', '#5d7092', '#f6bd16'],
series: [
{
name: '余额消耗',
name: '浣欓娑堣€?,
type: 'pie',
radius: '70%',
center: ['40%', '50%'],
label: { show: true, fontSize: 11, formatter: '{b}\n{c}%' },
// 关键点:将图表数据映射到 percent 字段
// 鍏抽敭鐐癸細灏嗗浘琛ㄦ暟鎹槧灏勫埌 percent 瀛楁
data: consumptionDataList.value.map(item => ({ value: item.percent, name: item.name }))
}
]
@@ -311,7 +311,7 @@ function toggleConsumptionStyle() {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
/* 顶部卡片 */
/* 椤堕儴鍗$墖 */
.stats-grid {
display: flex;
flex-direction: row;
@@ -365,7 +365,7 @@ function toggleConsumptionStyle() {
margin-top: 4px;
}
/* 时间筛选区 */
/* 鏃堕棿绛涢€夊尯 */
.filter-bar {
padding: 16px 24px;
margin-bottom: 20px;
@@ -397,7 +397,7 @@ function toggleConsumptionStyle() {
.calendar-icon { font-size: 14px; color: #c0c4cc; margin-right: 10px; }
.date-range { font-size: 14px; color: #606266; }
/* 趋势图表区 */
/* 瓒嬪娍鍥捐〃鍖?*/
.chart-box {
padding: 24px;
margin-bottom: 20px;
@@ -436,7 +436,7 @@ function toggleConsumptionStyle() {
height: 100%;
}
/* 底部分析 */
/* 搴曢儴鍒嗘瀽 */
.bottom-analysis {
display: flex;
flex-direction: row;
@@ -478,7 +478,7 @@ function toggleConsumptionStyle() {
height: 100%;
}
/* 列表样式 */
/* 鍒楄〃鏍峰紡 */
.stats-table {
display: flex;
flex-direction: column;
@@ -521,7 +521,7 @@ function toggleConsumptionStyle() {
.progress-container {
flex: 1;
height: 8px;
background-color: #f5f5f5;
border-radius: 4px;
margin-right: 10px;
overflow: hidden;
@@ -539,3 +539,4 @@ function toggleConsumptionStyle() {
color: #666;
}
</style>

View File

@@ -1,15 +1,15 @@
<template>
<template>
<view class="page-container">
<view class="page-header">
<text class="page-title">财务记录</text>
<text class="page-title">璐㈠姟璁板綍</text>
<text class="page-subtitle">Component: FinanceRecord</text>
</view>
<view class="page-content">
<view class="placeholder-card">
<text class="placeholder-title">页面占位</text>
<text class="placeholder-desc">该功能模块正在开发中</text>
<text class="placeholder-info">当前采用 CRMEB 路由体系 1:1 映射</text>
<text class="placeholder-title">椤甸潰鍗犱綅</text>
<text class="placeholder-desc">璇ュ姛鑳芥ā鍧楁鍦ㄥ紑鍙戜腑</text>
<text class="placeholder-info">褰撳墠閲囩敤 CRMEB 璺敱浣撶郴 1:1 鏄犲皠</text>
</view>
</view>
</view>
@@ -18,14 +18,14 @@
<script setup lang="uts">
import { ref } from 'vue'
// TODO: 实现 财务记录 的具体功能
// TODO: 瀹炵幇 璐㈠姟璁板綍 鐨勫叿浣撳姛鑳?
const loading = ref<boolean>(false)
</script>
<style scoped lang="scss">
.page-container {
padding: 20px;
min-height: 100vh;
/* padding removed */
background: #f5f5f5;
}
@@ -79,3 +79,5 @@ const loading = ref<boolean>(false)
color: #1890ff;
}
</style>

View File

@@ -1,14 +1,14 @@
<template>
<template>
<view class="finance-withdrawal">
<!-- 头部筛选区 -->
<!-- 澶撮儴绛涢€夊尯 -->
<view class="filter-card">
<view class="filter-row">
<view class="filter-item">
<text class="filter-label">时间选择:</text>
<input class="date-input" type="text" v-model="timeRangeText" placeholder="请选择时间范围" />
<text class="filter-label">鏃堕棿閫夋嫨:</text>
<input class="date-input" type="text" v-model="timeRangeText" placeholder="璇烽€夋嫨鏃堕棿鑼冨洿" />
</view>
<view class="filter-item">
<text class="filter-label">提现状态:</text>
<text class="filter-label">鎻愮幇鐘舵€?</text>
<picker mode="selector" :range="statusOptions" range-key="text" @change="statusChange">
<view class="picker-view">
<text>{{ statusLabel }}</text>
@@ -17,7 +17,7 @@
</picker>
</view>
<view class="filter-item">
<text class="filter-label">提现方式:</text>
<text class="filter-label">鎻愮幇鏂瑰紡:</text>
<picker mode="selector" :range="methodOptions" range-key="text" @change="methodChange">
<view class="picker-view">
<text>{{ methodLabel }}</text>
@@ -26,14 +26,14 @@
</picker>
</view>
<view class="filter-item search-wrap">
<text class="filter-label">搜索:</text>
<input class="search-input" v-model="searchKeyword" placeholder="微信昵称/姓名/支付宝账号/银行卡号" />
<text class="filter-label">鎼滅储:</text>
<input class="search-input" v-model="searchKeyword" placeholder="寰俊鏄电О/濮撳悕/鏀粯瀹濊处鍙?閾惰鍗″彿" />
</view>
<button class="btn-query" @click="handleQuery">查询</button>
<button class="btn-query" @click="handleQuery">鏌ヨ</button>
</view>
</view>
<!-- 统计指标网格 -->
<!-- 缁熻鎸囨爣缃戞牸 -->
<view class="stats-grid">
<view class="stat-card" v-for="(item, index) in stats" :key="index">
<view class="icon-circle" :class="item.colorClass">
@@ -46,27 +46,27 @@
</view>
</view>
<!-- 操作按钮区 -->
<!-- 鎿嶄綔鎸夐挳鍖?-->
<view class="action-section">
<view class="btn-record">
<text class="btn-record-txt">佣金记录</text>
<text class="btn-record-txt">浣i噾璁板綍</text>
</view>
</view>
<!-- 数据表格 (使用 Flex 模拟以确保兼容性和精度) -->
<!-- 鏁版嵁琛ㄦ牸 (浣跨敤 Flex 妯℃嫙浠ョ‘淇濆吋瀹规€у拰绮惧害) -->
<view class="table-container">
<view class="table-header">
<view class="th col-id"><text class="th-txt">ID</text></view>
<view class="th col-user"><text class="th-txt">用户信息</text></view>
<view class="th col-amount"><text class="th-txt">提现金额</text></view>
<view class="th col-fee"><text class="th-txt">提现手续费</text></view>
<view class="th col-net"><text class="th-txt">到账金额</text></view>
<view class="th col-method"><text class="th-txt">提现方式</text></view>
<view class="th col-qr"><text class="th-txt">收款码</text></view>
<view class="th col-time"><text class="th-txt">申请时间</text></view>
<view class="th col-remark"><text class="th-txt">备注</text></view>
<view class="th col-status"><text class="th-txt">审核状态</text></view>
<view class="th col-ops"><text class="th-txt">操作</text></view>
<view class="th col-user"><text class="th-txt">鐢ㄦ埛淇℃伅</text></view>
<view class="th col-amount"><text class="th-txt">鎻愮幇閲戦</text></view>
<view class="th col-fee"><text class="th-txt">鎻愮幇鎵嬬画璐?/text></view>
<view class="th col-net"><text class="th-txt">鍒拌处閲戦</text></view>
<view class="th col-method"><text class="th-txt">鎻愮幇鏂瑰紡</text></view>
<view class="th col-qr"><text class="th-txt">鏀舵鐮?/text></view>
<view class="th col-time"><text class="th-txt">鐢宠鏃堕棿</text></view>
<view class="th col-remark"><text class="th-txt">澶囨敞</text></view>
<view class="th col-status"><text class="th-txt">瀹℃牳鐘舵€?/text></view>
<view class="th col-ops"><text class="th-txt">鎿嶄綔</text></view>
</view>
<view class="table-body">
@@ -79,7 +79,7 @@
</view>
<view class="user-detail">
<text class="user-nickname">{{ item.nickname }}</text>
<text class="user-id">用户id:{{ item.userId }}</text>
<text class="user-id">鐢ㄦ埛id:{{ item.userId }}</text>
</view>
</view>
</view>
@@ -88,26 +88,26 @@
<view class="td col-net"><text class="td-txt green-txt">{{ item.netAmount }}</text></view>
<view class="td col-method">
<view class="method-box">
<text class="m-line">姓名:{{ item.name }}</text>
<text class="m-line">濮撳悕:{{ item.name }}</text>
<text class="m-line">{{ item.type }}:{{ item.account }}</text>
<text v-if="item.bank" class="m-line">银行开户地址:{{ item.bank }}</text>
<text v-if="item.bank" class="m-line">閾惰寮€鎴峰湴鍧€:{{ item.bank }}</text>
</view>
</view>
<view class="td col-qr">
<view class="qr-box" v-if="item.id === 57">
<text class="qr-icon-txt">■</text>
<text class="qr-icon-txt">鈻?/text>
</view>
</view>
<view class="td col-time"><text class="td-txt">{{ item.time }}</text></view>
<view class="td col-remark"><text class="td-txt">{{ item.remark || '' }}</text></view>
<view class="td col-status"><text class="td-txt">申请中</text></view>
<view class="td col-status"><text class="td-txt">鐢宠涓?/text></view>
<view class="td col-ops">
<view class="ops-box">
<text class="op-btn blue">编辑</text>
<text class="op-btn blue">缂栬緫</text>
<text class="op-sep">|</text>
<text class="op-btn blue">通过</text>
<text class="op-btn blue">閫氳繃</text>
<text class="op-sep">|</text>
<text class="op-btn blue">驳回</text>
<text class="op-btn blue">椹冲洖</text>
</view>
</view>
</view>
@@ -126,61 +126,61 @@ const methodValue = ref('all')
const searchKeyword = ref('')
const statusOptions = ref([
{ value: 'all', text: '全部' },
{ value: '0', text: '待审核' },
{ value: '1', text: '已通过' },
{ value: '-1', text: '已驳回' }
{ value: 'all', text: '鍏ㄩ儴' },
{ value: '0', text: '寰呭鏍? },
{ value: '1', text: '宸查€氳繃' },
{ value: '-1', text: '宸查┏鍥? }
])
const methodOptions = ref([
{ value: 'all', text: '全部' },
{ value: 'alipay', text: '支付宝' },
{ value: 'bank', text: '银行卡' },
{ value: 'weixin', text: '微信' }
{ value: 'all', text: '鍏ㄩ儴' },
{ value: 'alipay', text: '鏀粯瀹? },
{ value: 'bank', text: '閾惰鍗? },
{ value: 'weixin', text: '寰俊' }
])
const statusLabel = computed(() => {
const item = statusOptions.value.find((opt: any) => opt.value === statusValue.value)
return item ? item.text : '全部'
return item ? item.text : '鍏ㄩ儴'
})
const methodLabel = computed(() => {
const item = methodOptions.value.find((opt: any) => opt.value === methodValue.value)
return item ? item.text : '全部'
return item ? item.text : '鍏ㄩ儴'
})
const stats = ref([
{ label: '佣金总金额', value: '676809.25', icon: '$', colorClass: 'blue' },
{ label: '待提现金额', value: '71', icon: '¥', colorClass: 'orange' },
{ label: '已提现金额', value: '68879.25', icon: '$', colorClass: 'green' },
{ label: '未提现金额', value: '607930.00', icon: '¥', colorClass: 'pink' }
{ label: '浣i噾鎬婚噾棰?, value: '676809.25', icon: '$', colorClass: 'blue' },
{ label: '寰呮彁鐜伴噾棰?, value: '71', icon: '', colorClass: 'orange' },
{ label: '宸叉彁鐜伴噾棰?, value: '68879.25', icon: '$', colorClass: 'green' },
{ label: '鏈彁鐜伴噾棰?, value: '607930.00', icon: '', colorClass: 'pink' }
])
const tableData = ref([
{
id: 57,
nickname: '用户昵称: 177****766',
nickname: '鐢ㄦ埛鏄电О: 177****766',
userId: '58837',
amount: '20.00',
fee: '0.00',
netAmount: '20.00',
name: '接口',
type: '支付宝',
name: '鎺ュ彛',
type: '鏀粯瀹?,
account: '1195953899',
time: '2025-10-24 16:04',
remark: ''
},
{
id: 56,
nickname: '用户昵称: 测试员的',
nickname: '鐢ㄦ埛鏄电О: 娴嬭瘯鍛樼殑',
userId: '20695',
amount: '1.00',
fee: '0.00',
netAmount: '1.00',
name: '123',
type: '银行卡',
type: '閾惰鍗?,
account: '4001231221',
bank: '中国银行',
bank: '涓浗閾惰',
time: '2025-07-04 15:11',
remark: ''
}
@@ -206,7 +206,7 @@ const handleQuery = () => {
min-height: 100vh;
}
/* 筛选样式更新 */
/* 绛涢€夋牱寮忔洿鏂?*/
.filter-card {
background-color: #fff;
padding: 24px;
@@ -284,7 +284,7 @@ const handleQuery = () => {
margin-bottom: 16px;
}
/* 统计卡片样式 */
/* 缁熻鍗$墖鏍峰紡 */
.stats-grid {
display: flex;
flex-direction: row;
@@ -338,7 +338,7 @@ const handleQuery = () => {
margin-top: 6px;
}
/* 操作区域 */
/* 鎿嶄綔鍖哄煙 */
.action-section {
margin-bottom: 12px;
display: flex;
@@ -359,9 +359,9 @@ const handleQuery = () => {
font-size: 13px;
}
/* 表格容器样式 (Flex 模拟) */
/* 琛ㄦ牸瀹瑰櫒鏍峰紡 (Flex 妯℃嫙) */
.table-container {
background-color: #fff;
border-radius: 4px;
overflow: hidden;
display: flex;
@@ -411,7 +411,7 @@ const handleQuery = () => {
color: #606266;
}
/* 列宽定义 (与截图匹配) */
/* 鍒楀瀹氫箟 (涓庢埅鍥惧尮閰? */
.col-id { width: 60px; }
.col-user { width: 180px; justify-content: flex-start; }
.col-amount { width: 100px; }
@@ -424,7 +424,7 @@ const handleQuery = () => {
.col-status { width: 100px; }
.col-ops { width: 160px; }
/* 用户信息单元格 */
/* 鐢ㄦ埛淇℃伅鍗曞厓鏍?*/
.user-info-box {
display: flex;
flex-direction: row;
@@ -463,7 +463,7 @@ const handleQuery = () => {
color: #909399;
}
/* 提现方式单元格 */
/* 鎻愮幇鏂瑰紡鍗曞厓鏍?*/
.method-box {
display: flex;
flex-direction: column;
@@ -480,7 +480,7 @@ const handleQuery = () => {
font-weight: 600;
}
/* 收款码 */
/* 鏀舵鐮?*/
.qr-box {
width: 40px;
height: 40px;
@@ -496,7 +496,7 @@ const handleQuery = () => {
font-size: 16px;
}
/* 操作项 */
/* 鎿嶄綔椤?*/
.ops-box {
display: flex;
flex-direction: row;
@@ -515,3 +515,4 @@ const handleQuery = () => {
font-size: 12px;
}
</style>