数据分组展示的实现

一、实现效果

点击日期组件,选择日期进行查询,将查询到的数据以门店和配送点进行分组展示

 二、实现思路

调用接口,从接口中获取需要的数据,接口返回的数据格式如下所示:

 可以看到后端接口返回的数据,里面包含了门店信息和配送点信息,而我们在前端,需要处理后端返回的数据,将同一门店和配送点的数据一同展示,所以需要对数据进行分组

首先,创建一个空对象 grouped ,它的键是字符串类型,值可以是任意类型,用于存储分组后的数据。

 const grouped: { [key: string]: any } = {}

接着通过 result.forEach 遍历接口返回的订单数据数组 result ,对于每一个订单数据项 item 生成分组键

const key = `${item.shopname}-${item.peisongdianName}`

通过将门店名称 item.shopname 和配送点名称 item.peisongdianName 用 '-' 连接起来,生成一个唯一标识该分组的键。

接着初始化分组数据

if (!grouped[key]) {
    // 初始化分组数据
    grouped[key] = {
        shopid: item.shopid,
        shopname: item.shopname,
        peisongdianId: item.peisongdianId,
        peisongdianName: item.peisongdianName,
        order_list: [],
        order_nums: item.order_nums,
        actual_paymeny: item.actual_paymeny
    }
}

检查以 key 为键在 grouped 对象中是否已经存在对应分组。如果不存在,就初始化该分组的数据。将当前订单数据项中的门店 ID、门店名称、配送点 ID、配送点名称、订单数、实收金额等信息提取出来,存入 grouped[key] 中,并将 order_list 初始化为空数组,用于后续存放该分组下的餐品和数量信息。

并且合并餐品和数量数据:

grouped[key].order_list = grouped[key].order_list.concat(item.order_list)

将当前订单数据项中的餐品和数量信息(item.order_list ,它是一个包含餐品和对应数量的数组)合并到 grouped[key] 的 order_list 中。这样,同一个门店和配送点组合(即同一个分组)下的所有餐品和数量信息都会被累积起来。

通过上述代码,即完成数据的分组,接着在页面中进行渲染就好了

三、完整代码

<template>
  <div class="container">
    <div class="query-form">
      <el-form ref="formRef" :model="queryForm" inline>
        <el-form-item>
          <el-date-picker
            v-model="queryForm.value1"
            :clearable="false"
            type="date"
            placeholder="请选择日期"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 遍历分组后的数据进行展示 -->
    <div v-if="groupedData.length > 0">
      <div v-for="(group, index) in groupedData" :key="index" class="group-container">
        <el-table :show-header="false" :data="[{label: '门店', value: group.shopname}, {label: '配送点', value: group.peisongdianName}]" border style="width: 100%; margin-bottom: 10px;">
          <el-table-column prop="label" label="" width="120" />
          <el-table-column prop="value" label="" />
          <template #header>
            <tr style="display: none;"></tr> <!-- 隐藏默认表头 -->
          </template>
        </el-table>
        <el-table :data="group.order_list" border style="width: 100%; margin-bottom: 10px;">
          <el-table-column label="餐品" prop="meal" />
          <el-table-column label="数量" prop="count" />
          <template #header>
            <tr style="display: none;"></tr> <!-- 隐藏默认表头 -->
          </template>
        </el-table>
        <el-table :show-header="false" :data="[{label: '订单数', value: group.order_nums}, {label: '实收金额', value: group.actual_paymeny}]" border style="width: 100%">
          <el-table-column prop="label" label="" width="120" />
          <el-table-column prop="value" label="" />
          <template #header>
            <tr style="display: none;"></tr> <!-- 隐藏默认表头 -->
          </template>
        </el-table>
      </div>
    </div>
    <div v-else class="no-data-message">暂无数据</div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { getMealCenters } from '@/api/mealCenter'
import { getMealOrderstatic } from '@/api/orderStatistics'
import { ElMessage } from 'element-plus'

type OrderStatisticsResponse = {
  shopid: string
  shopname: string
  peisongdianId: number
  peisongdianName: string
  order_list: {
    meal: string
    count: number
  }[]
  order_nums: number
  actual_paymeny: number
}

// 查询表单数据
const queryForm = ref({
  value1: '',
})

// 分组后的数据
const groupedData = ref<any[]>([])

// 加载门店数据
const loadMealCenters = async () => {
  try {
    const { result } = await getMealCenters()
    if (result) {
      // 如果需要使用门店数据,可以在这里处理
    }
  } catch (error) {
    console.error('获取门店数据失败:', error)
  }
}

// 处理查询
const handleQuery = async () => {
  init()
  const res = await getMealOrderstatic(queryForm.value.value1)
  const { code, result } = await getMealOrderstatic(queryForm.value.value1)
  console.log(result);
  console.log(res);
  
  
  if (code === '200') {
    ElMessage.success('查询成功')
    const grouped: { [key: string]: any } = {}
    result.forEach((item: OrderStatisticsResponse) => {
      const key = `${item.shopname}-${item.peisongdianName}`
      if (!grouped[key]) {
        // 初始化分组数据
        grouped[key] = {
          shopid: item.shopid,
          shopname: item.shopname,
          peisongdianId: item.peisongdianId,
          peisongdianName: item.peisongdianName,
          order_list: [],
          order_nums: item.order_nums,
          actual_paymeny: item.actual_paymeny
        }
      }
      // 合并餐品和数量数据
      grouped[key].order_list = grouped[key].order_list.concat(item.order_list)
    })
    groupedData.value = Object.values(grouped)
  } else {
    ElMessage.error('查询失败')
  }
}

// 初始化数据
const init = () => {
  groupedData.value = []
}

// 页面加载时初始化数据
onMounted(() => {
  loadMealCenters()
})
</script>

<style scoped>
.container {
  background-color: white;
  padding: 20px;
}
.query-form {
  display: flex;
  justify-content: space-between;
  padding-right: 30px;
}
.group-container {
  margin-bottom: 20px;
  border: 1px solid #eaeaea;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
el-table {
  border-collapse: collapse; /* 合并表格边框,去除单元格间距 */
}
el-table__body tr {
  padding: 0; /* 去除表格行的内边距 */
  height: 1px;
}
.el-table thead {
  height: 1px;
}
el-table__cell {
  padding: 0; /* 去除表格单元格的内边距 */
  margin: 0; /* 去除表格单元格的外边距 */
}
.no-data-message {
  text-align: center;
  color: #999;
  padding: 20px;
}
</style>    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值