<template> <view class="content"> <headersVue :titles="titles"> <u-icon name="arrow-left" color="#fff" size="18"></u-icon> </headersVue> <view class="top_"> <view class="t_left" @click="isShowPop = true">全部订单 <u-icon name="arrow-down-fill" color="#327DFB" size="14"></u-icon> </view> <view class="" style="display:flex;" @click="cleanSelectTime" v-if="queryParams.startTime"> 清除时间 <u-icon name="close-circle" size="24" color="#327DFB" style="margin-left: 10rpx" ></u-icon> </view> </view> <view class="container" v-if="tableData"> <view class="box_" v-for="(records, date) in tableData" :key="date"> <view class="title_" @click="show = true">{{ formatDateChinese(date) }} <u-icon name="arrow-down" size="14"></u-icon> </view> <view class="box_cont"> <view class="box_hang" v-for="(item, index) in records" :key="item.id"> <view class="d_s"> <view class="num_">{{ index + 1 }}</view> <view class="name_">{{ item.carNum }}</view> <view class="icon_" v-if="item.carModel">{{ item.carModel }}</view> </view> <view class="d_b"> <view class="d_s"> <view class="h_">业务来源:</view> <view class="n_">{{ item.customerSource }}</view> </view> <view class="d_s"> <view class="h_">检测状态:</view> <view class="n_">{{ item.status }}</view> </view> <view class="d_s"> <view class="h_">支付方式:</view> <view class="n_">{{ item.pay == '未支付' ? item.pay : getPayType(item.payType) }}</view> </view> </view> </view> </view> </view> </view> <view class="container" v-else style="margin: 430rpx 0"> <u-empty mode="order" > </u-empty> </view> <u-popup round="55" :show="isShowPop" @close="closePop" @open="openPop" :key="windowsHeight"> <view class="popup-content" :style="{'height':windowsHeight + 'px'}"> <view class="popup-header"> <text>选择筛选项</text> <view style="display: flex;justify-content: space-between" @click="clearSelection"> <u-icon name="close-circle" size="18" color="#327DFB" ></u-icon> <text style="color:#327DFB;">清除筛选项</text> </view> </view> <u-search placeholder="请输入车辆品牌或车牌号" v-model="queryParams.carModelOrCarYear" @custom="search" @search="search"></u-search> <scroll-view scroll-y="true" class="scroll_view_style"> <view class="popup-body"> <view style="display: flex;justify-content: space-between"> <!-- 客户来源选择 --> <view class="filter-section"> <text>客户来源</text> <view class="options" @click="handleClick"> <text> {{ queryParams.customerSource || '请选择客户来源' }} </text> <u-icon v-if="queryParams.customerSource" name="close-circle" size="24" color="#327DFB" ></u-icon> <u-icon v-else name="arrow-down" size="14" color="#327DFB" ></u-icon> </view> </view> <!-- 车型选择 --> <view class="filter-section"> <text>车型</text> <view class="options" @click="handleGoodsClick"> <text> {{ goodsName || '请选择车型' }} </text> <u-icon v-if="queryParams.goods" name="close-circle" size="24" color="#327DFB" ></u-icon> <u-icon v-else name="arrow-down" size="14" color="#327DFB" ></u-icon> </view> </view> </view> <!-- 车龄选择 --> <view class="filter-section"> <text>车龄选择</text> <u-number-box v-model="queryParams.carYear" :min="0" :max="100"></u-number-box> </view> <!-- 支付方式选择 --> <view class="filter-section"> <text>支付方式</text> <view class="options"> <text class="options_content" v-for="(item, index) in payTypes" :key="index" @click="selectPayType(item.value)" :class="{ selected: queryParams.payType === item.value }" > {{ item.label }} </text> </view> </view> <!-- 检测状态选择 --> <view class="filter-section"> <text>检测状态</text> <view class="options"> <text class="options_content" v-for="(item, index) in inspectionStatus" :key="index" @click="selectInspectionStatus(item.value)" :class="{ selected: queryParams.chooseStatus === item.value }" > {{ item.label }} </text> </view> </view> </view> </scroll-view> <view class="popup-footer"> <u-button @click="closePop" style="background: #F7F8FC;color: black">取消</u-button> <u-button @click="submitPop">确定</u-button> </view> </view> </u-popup> <u-picker :show="isShowCustomer" :columns="[customerSource]" keyName="label" closeOnClickOverlay @cancel="isShowCustomer = false" @close="isShowCustomer = false" @confirm="handleCustomerSourceConfirm" :overlay-style="{ zIndex: '10080' }" style="z-index: 10072" ></u-picker> <u-picker :show="isShowGoods" :columns="[goodsList]" keyName="label" closeOnClickOverlay @cancel="isShowGoods = false" @close="isShowGoods = false" @confirm="handleGoodsConfirm" :overlay-style="{ zIndex: '10080' }" style="z-index: 10072" ></u-picker> <u-datetime-picker :show="show" v-model="selectTime" mode="date" @close="show = false" @cancel="show = false" closeOnClickOverlay @confirm="confirmTime" ></u-datetime-picker> </view> </template> <script> import headersVue from '../../components/header/headers.vue'; import request from "@/utils/request"; import {formatDate, formatDateChinese, formatDateTimeToMinute, getDictDataByType} from "@/utils/utils"; export default { data() { return { titles: "订单统计", msg: "1", List: [], show: false, status: 'loading', columns: [ ['选项', '选项', '选项'] ], queryParams: { queryTime: null, pageNum: 1, pageSize: 50, chooseStatus: "1", payType: "", startTime: null, endTime: null, carModelOrCarYear: null, customerSource: null, goods: null, carYear: 0, }, loading: false, // 加载更多时的标志位 tableData: {}, pages: 0, isShowPop: false, isShowCustomer: false, payTypes: [], inspectionStatus: [ { label: "全部", value: "1", }, { label: "检测中", value: "2", }, { label: "已完成", value: "3", }, ], selectedPayType: null, // 选中的支付方式 selectedInspectionStatus: null, // 选中的检测状态 customerSource: [], selectedCustomerSource: null, // 选中的客户来源 selectTime: new Date().toString(), goodsList: [], isShowGoods: false, goodsName: null, windowsHeight:600, } }, onReachBottom() { // 当用户滚动到底部时触发 if (!this.loading && this.queryParams.pageNum < this.pages) { this.queryParams.pageNum += 1; this.getTableData(true); } else { uni.showToast({ title: '没有下一页数据', icon: 'none' }) } }, components: { headersVue }, onReady() { uni.getSystemInfo({ success: function(res) { this.windowsHeight = res.windowHeight; console.log('屏幕高度:', res.windowHeight); } }); this.getTableData(); this.getDictData(); this.getCustomerSource(); // this.disabledScroll() }, methods: { formatDateChinese, getTableData(isLoadMore = false) { this.loading = true; // 开始加载更多 request({ url: '/partnerOwn/partner/getOrderByDate', method: 'get', params: this.queryParams }).then(res => { this.pages = res.data.pages let newData = res.data.records || []; if (isLoadMore) { newData = newData.concat(this.extractAllEntries(this.tableData)) this.tableData = this.groupByDate(newData); // 合并新旧数据 } else { this.tableData = null if (newData.length !== 0) { this.tableData = newData; // 初始加载或搜索时替换数据 this.tableData = this.groupByDate(this.tableData) } } this.loading = false; // 完成加载 }).catch(err => { console.error('获取订单数据失败', err); this.loading = false; // 出错也停止加载 }); }, getPayType(type) { if (!this.payTypes || this.payTypes.length === 0) { this.getDictData() } if (type) { const index = this.payTypes.findIndex(item => item.value === type) if (index !== -1) { return this.payTypes[index].label } } }, async getDictData() { if (!this.payTypes || this.payTypes.length === 0) { this.payTypes = [ { label: "全部", value: "", } ] this.payTypes = this.payTypes.concat(await getDictDataByType("pay_type")) } }, groupByDate(records) { return Object.entries(records.reduce((acc, item) => { const dateKey = item.createTime.split(" ")[0]; // 取 "yyyy-MM-dd" if (!acc[dateKey]) { acc[dateKey] = []; } acc[dateKey].push(item); return acc; }, {})) .sort(([a], [b]) => b.localeCompare(a)) // 根据 dateKey 倒序排序 .reduce((sortedAcc, [key, value]) => { sortedAcc[key] = value; return sortedAcc; }, {}); }, extractAllEntries(data) { return Object.values(data).flat(); // 提取所有子数组并展平为一个大数组 }, closePop() { this.isShowPop = false; this.queryParams.payType = ""; this.queryParams.chooseStatus = "1"; this.queryParams.carModelOrCarYear = null; }, submitPop() { this.queryParams.pageNum = 1; this.tableData = null this.getTableData(); this.isShowPop = false; }, openPop() { this.isShowPop = true; }, selectPayType(value) { this.queryParams.payType = value; }, selectInspectionStatus(value) { this.queryParams.chooseStatus = value; }, async getCustomerSource() { let res = await request({ url: '/partnerOwn/partner/getCustomerSource', method: 'get', }) this.customerSource = res.data //商品类型 let resx = await request({ url: '/system/inspectionGoods/partnerGoodsListCol', method: 'get', }) this.goodsList = resx.data.goodsList }, handleCustomerSourceConfirm(e) { this.queryParams.customerSource = e.value[0].value; // 获取用户选择的客户来源 this.isShowCustomer = false; // 关闭选择器 }, handleGoodsConfirm(e) { this.queryParams.goods = e.value[0].value; // 获取用户选择的客户来源 this.goodsName = e.value[0].label; // 获取用户选择的客户来源 this.isShowGoods = false; // 关闭选择器 }, search() { this.getTableData(); this.isShowPop = false; }, clearCustomerSource() { this.$nextTick(() => { this.queryParams.customerSource = null; // 清空客户来源 }) }, handleClick() { if (this.queryParams.customerSource) { this.clearCustomerSource(); } else { this.isShowCustomer = true; } }, handleGoodsClick() { if (this.queryParams.goods) { this.queryParams.goods = null; this.goodsName = null } else { this.isShowGoods = true; } }, confirmTime(e) { const time = formatDate(e.value) this.queryParams.startTime = time this.queryParams.endTime = time this.getTableData() this.show = false }, cleanSelectTime() { this.queryParams.startTime = null this.queryParams.endTime = null this.getTableData() }, clearSelection() { this.queryParams = { queryTime: null, pageNum: 1, pageSize: 10, chooseStatus: "1", payType: "", startTime: null, endTime: null, carModelOrCarYear: null, customerSource: null, goods: null, carYear: 0, } this.getTableData() this.isShowPop = false }, // disabledScroll(){ // const container = document.querySelector('.content'); content.scrollTop = 0; // console.log('container',container) // }, } } </script> <style lang="scss" scoped> .content { width: 100%; box-sizing: border-box; padding-top: 200rpx; background: #f4f5f6; height: 100vh; } .container { box-sizing: border-box; background: #f4f5f6; } .t_left { width: 200rpx; border: 2px solid #327DFB; background: #e3ecfb; color: #327DFB; font-size: 28rpx; box-sizing: border-box; padding: 5px 10px; border-radius: 50px; display: flex; align-items: center; justify-content: center; margin: 30rpx; } .title_ { display: flex; align-items: center; font-weight: 400; font-size: 32rpx; color: #101A3E; padding-left: 15rpx; } .box_ { margin-bottom: 30rpx; } .box_cont { box-sizing: border-box; padding: 30rpx; border-radius: 8px; background: #fff; width: 100%; margin-top: 30rpx; } .d_s { display: flex; align-items: center; } .d_b { display: flex; align-items: center; justify-content: space-between; margin-top: 20rpx; } .num_ { width: 36rpx; height: 36rpx; background: #327DFB; color: #fff; display: flex; align-items: center; border-radius: 50%; justify-content: center; margin-right: 10px; } .name_ { margin-right: 10px; font-size: 32rpx; color: #101A3E; } .icon_ { background: #e3ecfb; color: #327DFB; font-size: 28rpx; box-sizing: border-box; padding: 5rpx 20rpx; border-radius: 50px; display: flex; align-items: center; justify-content: center; } .h_ { font-size: 28rpx; color: #8D90A6; } .n_ { font-size: 28rpx; color: #101A3E; display: inline-block; max-width: 3em; /* 约等于4个汉字的宽度 */ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .box_hang { box-sizing: border-box; padding-bottom: 20rpx; border-bottom: 2rpx solid #F5F5F5; margin-bottom: 20rpx; } .popup-content { padding: 20rpx 20rpx 20rpx 20rpx; overflow-y: scroll; background: white; border-radius: 20rpx; //height: 80vh; } .popup-header { font-size: 32rpx; color: #101A3E; margin-bottom: 40rpx; display: flex; justify-content: space-between; } .popup-body { font-size: 28rpx; color: #101A3E; } .filter-section { margin-top: 30rpx; } .filter-section text { display: block; margin-bottom: 10rpx; } .options { display: flex; flex-wrap: wrap; align-items: center; //justify-content: space-between; margin-top: 30rpx; } .options text { margin-right: 20rpx; margin-bottom: 10rpx; } .popup-footer { display: flex; justify-content: space-between; margin-top: 60rpx; margin-bottom: 30rpx; } .popup-footer button { padding: 10rpx 20rpx; margin: 0 10rpx; border-radius: 5px; background-color: #327DFB; color: #fff; border: none; } .options_content { background: #F7F8FC; border-radius: 15rpx; width: 210rpx; height: 90rpx; line-height: 90rpx; text-align: center; border: 2rpx solid transparent; margin-top: 10rpx; transition: all 0.3s ease; &.selected { border-color: #327DFB; background-color: rgba(50, 125, 251, 0.1); color: #327DFB; } } .filter-section .options u-icon { margin-left: 10rpx; } .top_ { display: flex; justify-content: space-between; align-items: center; //position: fixed; //background: coral; width: 100%; //margin-bottom: 1rpx; } </style>