detection-business/pages/index/neworderStatistic.vue
2025-03-03 17:58:44 +08:00

660 lines
17 KiB
Vue

<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: 10,
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>