فهرست منبع

feat:新增充值数据概览

叶静 2 هفته پیش
والد
کامیت
1ac0278a44
3فایلهای تغییر یافته به همراه138 افزوده شده و 14 حذف شده
  1. 130 11
      src/app/shop/admin/finance/recharge/index.vue
  2. 2 2
      src/app/shop/admin/finance/withdraw/index.vue
  3. 6 1
      src/locales/zh-CN/index.json

+ 130 - 11
src/app/shop/admin/finance/recharge/index.vue

@@ -3,9 +3,8 @@
     <el-header class="sa-header">
       <!-- 简化搜索组件 -->
       <div class="search-container">
-        <sa-search-simple :searchFields="searchFields" :defaultValues="defaultSearchValues"
-          v-model="currentSearchParams" @search="handleSearch" @reset="handleReset">
-        </sa-search-simple>
+        <sa-search-simple key="recharge-search" :searchFields="searchFields" :defaultValues="defaultSearchValues"
+          v-model="currentSearchParams" @search="handleSearch" @reset="handleReset" :defaultExpand="true" />
       </div>
       <!-- 状态Tab切换 -->
       <el-tabs class="sa-tabs" v-model="currentStatus" @tab-change="handleTabChange">
@@ -15,6 +14,29 @@
         <el-tab-pane :label="t('modules.recharge.failed')" name="3"></el-tab-pane>
         <el-tab-pane :label="t('modules.recharge.timeout')" name="4"></el-tab-pane>
       </el-tabs>
+      <!-- 统计数据展示 -->
+      <div class="statistics-container">
+        <div class="stat-item">
+          <div class="stat-label">{{ t('modules.recharge.orderNum') }}</div>
+          <div class="stat-value">{{ statistics.orderNum || 0 }}</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-label">{{ t('modules.recharge.orderAmount') }}</div>
+          <div class="stat-value">৳{{ statistics.orderAmount || 0 }}</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-label">{{ t('modules.recharge.successOrderNum') }}</div>
+          <div class="stat-value">{{ statistics.successNum || 0 }}</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-label">{{ t('modules.recharge.successAmount') }}</div>
+          <div class="stat-value">৳{{ statistics.successAmount || 0 }}</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-label">{{ t('modules.recharge.successRate') }}</div>
+          <div class="stat-value">{{ statistics.successRate || 0 }}%</div>
+        </div>
+      </div>
       <div class="sa-title sa-flex sa-row-between">
         <div class="label sa-flex">{{ t('modules.recharge.title') }}</div>
         <div>
@@ -187,7 +209,7 @@ const defaultSearchValues = reactive({
   methodName: '',
   channel: '',
   timeType: 1, // 默认下单时间
-  date_range: [],
+  date_range: getTodayRange(), // 默认当天
 });
 // 当前状态标签
 const currentStatus = ref('all');
@@ -195,9 +217,28 @@ const currentStatus = ref('all');
 // 当前搜索条件
 const currentSearchParams = ref({});
 
+// 获取当天日期范围
+function getTodayRange() {
+  const today = new Date();
+  const year = today.getFullYear();
+  const month = String(today.getMonth() + 1).padStart(2, '0');
+  const day = String(today.getDate()).padStart(2, '0');
+  const dateStr = `${year}-${month}-${day}`;
+  return [dateStr + ' 00:00:00', dateStr + ' 23:59:59'];
+}
+
 // 导出loading状态
 const exportLoading = ref(false);
 
+// 统计数据
+const statistics = ref({
+  orderNum: 0,
+  orderAmount: 0,
+  successNum: 0,
+  successAmount: 0,
+  successRate: 0
+});
+
 // 列表
 const table = reactive({
   data: [],
@@ -239,10 +280,21 @@ async function getData(page, searchParams = {}) {
     const { code, data } = await api.recharge.list(params, false);
 
     if (code == '200') {
-      table.data = data.list || [];
-      pageData.page = data.pageNum || 1;
-      pageData.size = data.pageSize || 20;
-      pageData.total = data.total || 0;
+      // 适配新的数据结构
+      const listData = data.list?.list || data.list || [];
+      table.data = listData;
+      pageData.page = data.list?.pageNum || data.pageNum || 1;
+      pageData.size = data.list?.pageSize || data.pageSize || 20;
+      pageData.total = data.list?.total || data.total || 0;
+
+      // 更新统计数据,successRate需要乘以100
+      statistics.value = {
+        orderNum: data.orderNum || 0,
+        orderAmount: data.orderAmount || 0,
+        successNum: data.successNum || 0,
+        successAmount: data.successAmount || 0,
+        successRate: ((data.successRate || 0) * 100).toFixed(2)
+      };
     }
   } catch (error) {
     console.error('获取数据失败:', error);
@@ -283,8 +335,16 @@ const handleSearch = (searchParams) => {
 
 // 重置处理
 const handleReset = () => {
-  // 手动清空搜索参数
-  currentSearchParams.value = {};
+  // 清空搜索参数,包括时间范围
+  currentSearchParams.value = {
+    userName: '',
+    userPhone: '',
+    orderNo: '',
+    methodName: '',
+    channel: '',
+    timeType: 1,
+    date_range: [], // 重置时清空时间范围
+  };
   // 获取当前tab的状态参数
   let statusParams = {};
   if (currentStatus.value !== 'all') {
@@ -404,7 +464,9 @@ async function getChannelList() {
 
 onMounted(() => {
   getChannelList();
-  getData();
+  // 初始化时使用默认搜索参数(包含默认时间范围)
+  currentSearchParams.value = { ...defaultSearchValues };
+  getData(1, currentSearchParams.value);
 });
 </script>
 <style lang="scss" scoped>
@@ -418,5 +480,62 @@ onMounted(() => {
       height: 100%;
     }
   }
+
+  // 统计数据容器样式
+  .statistics-container {
+    display: flex;
+    gap: 16px;
+    margin: 14px 0;
+    padding: 14px 16px;
+    background: linear-gradient(to right, #f8f9fa, #ffffff);
+    border-radius: 6px;
+    border: 1px solid #e4e7ed;
+    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+
+    .stat-item {
+      flex: 1;
+      text-align: center;
+      padding: 10px 12px;
+      background: #ffffff;
+      border-radius: 4px;
+      border-left: 3px solid #409eff;
+      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
+      transition: all 0.2s ease;
+
+      &:hover {
+        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
+        transform: translateY(-1px);
+      }
+
+      &:nth-child(2) {
+        border-left-color: #67c23a;
+      }
+
+      &:nth-child(3) {
+        border-left-color: #e6a23c;
+      }
+
+      &:nth-child(4) {
+        border-left-color: #f56c6c;
+      }
+
+      &:nth-child(5) {
+        border-left-color: #909399;
+      }
+
+      .stat-label {
+        font-size: 12px;
+        color: #606266;
+        margin-bottom: 6px;
+        font-weight: 500;
+      }
+
+      .stat-value {
+        font-size: 18px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+  }
 }
 </style>

+ 2 - 2
src/app/shop/admin/finance/withdraw/index.vue

@@ -320,13 +320,13 @@ async function getData(page, searchParams = {}) {
       pageData.size = data.list?.pageSize || data.pageSize || 20;
       pageData.total = data.list?.total || data.total || 0;
 
-      // 更新统计数据
+      // 更新统计数据,successRate需要乘以100
       statistics.value = {
         orderNum: data.orderNum || 0,
         orderAmount: data.orderAmount || 0,
         successNum: data.successNum || 0,
         successAmount: data.successAmount || 0,
-        successRate: data.successRate || 0
+        successRate: ((data.successRate || 0) * 100).toFixed(2)
       };
     }
   } catch (error) {

+ 6 - 1
src/locales/zh-CN/index.json

@@ -835,7 +835,12 @@
       "operationTime": "操作时间",
       "operator": "操作人",
       "operationType": "操作类型",
-      "remark": "备注"
+      "remark": "备注",
+      "orderNum": "充值订单",
+      "orderAmount": "充值金额",
+      "successOrderNum": "充值成功订单",
+      "successAmount": "充值成功金额",
+      "successRate": "成功率"
     },
     "withdraw": {
       "channel": "提款通道",