detection-business/pages/index/neworderStatistic.vue
2025-05-30 16:54:55 +08:00

808 lines
21 KiB
Vue

<template>
<view class="content">
<headersVue :titles="titles" style="position: static !important;">
<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">
<!-- <scroll-view class="school-scroll" scroll-y @scrolltolower="onReachBottomCus"
:style="{ height: scrollHeight + 'px' }" refresher-enabled @refresherrefresh="onRefresherrefresh"
:refresher-triggered="isTriggered"> -->
<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" @click="goDetail(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.businessChannel || '暂无' }}</view>
</view>
<view class="d_s">
<view class="h_">客户来源:</view>
<view class="n_">{{ item.customerSource }}</view>
</view>
</view>
<view class="d_b">
<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 class="d_s">
<view class="h_">检测次数:</view>
<view class="n_">{{ item.inspectionCount }}
</view>
</view>
</view>
</view>
</view>
</view>
<!-- </scroll-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>
<view style="margin-top: 20rpx">
<uni-datetime-picker
v-model="queryParams.datetimeRange"
type="daterange"
rangeSeparator="至"
/>
</view>
<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 style="display: flex;justify-content: space-between">
<!-- 检测时长选择 -->
<view class="filter-section">
<text>检测时长选择</text>
<view class="options" @click="handleInspectionTimeClick">
<text>
{{ inspectionTimeName || '请选择检测时长' }}
</text>
<u-icon v-if="inspectionTimeName" 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>
<u-number-box v-model="queryParams.carYear" :min="0" :max="100"></u-number-box>
</view>
</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 appTypes" :key="index"
@click="selectType(item.value)"
:class="{ selected: queryParams.type === 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 class="filter-section">
<text>检测项目</text>
<view class="options">
<text class="options_content" v-for="(item, index) in skuNames" :key="index"
@click="selectInspectionSkuName(item.value)"
:class="{ selected: queryParams.skuName === 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-picker :show="isShowInspectionTime" :columns="[inspectionTimeArr]" keyName="label" closeOnClickOverlay
@cancel="isShowInspectionTime = false" @close="isShowInspectionTime = false"
@confirm="handleInspectionTimeConfirm" :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: 20,
chooseStatus: "1",
skuName: "",
payType: "",
datetimeRange: null,
startTime: null,
endTime: null,
carModelOrCarYear: null,
customerSource: null,
goods: null,
carYear: 0,
type: "",
inspectionTime: "",
},
loading: false, // 加载更多时的标志位
tableData: {},
pages: 0,
isShowPop: false,
isShowCustomer: false,
payTypes: [],
inspectionStatus: [{
label: "全部",
value: "1",
},
{
label: "检测中",
value: "2",
},
{
label: "已完成",
value: "3",
},
{
label: "退办理",
value: "4",
},
{
label: "重检",
value: "5",
},
{
label: "复检",
value: "6",
},
],
appTypes: [{
label: "全部",
value: "",
},
{
label: "预约",
value: "1",
},
],
inspectionTimeArr: [{
label: '0-1小时',
value: ['0', '60']
}, {
label: '1-2小时',
value: ['60', '120']
}, {
label: '2-3小时',
value: ['120', '180']
}, {
label: '3-8小时',
value: ['180', '480']
}, {
label: '8小时',
value: ['480']
}, ],
skuNames: [{
label: "全部",
value: "",
},
{
label: "年审",
value: "年审",
},
{
label: "上户",
value: "上户",
},
{
label: "非定检",
value: "非定检",
},
{
label: "双燃料",
value: "双燃料",
},
{
label: "其他检测",
value: "其他检测",
},
],
selectedPayType: null, // 选中的支付方式
selectedInspectionStatus: null, // 选中的检测状态
inspectionTimeName: null, // 选中的检测状态
customerSource: [],
selectedCustomerSource: null, // 选中的客户来源
selectTime: new Date().toString(),
goodsList: [],
isShowGoods: false,
isShowInspectionTime: false,
isTriggered: false,
goodsName: null,
windowsHeight: 600,
scrollHeight: 0
}
},
onReachBottom() { // 当用户滚动到底部时触发
if (!this.loading && this.queryParams.pageNum < this.pages) {
this.queryParams.pageNum += 1;
this.getTableData(true);
} else {
uni.showToast({
title: '没有下一页数据',
icon: 'none'
})
}
},
components: {
headersVue
},
onLoad(options) {
if (options.chooseStatus) {
this.queryParams.chooseStatus = options.chooseStatus
}
if (options.skuName) {
this.queryParams.skuName = options.skuName
}
},
onReady() {
uni.getSystemInfo({
success: function(res) {
this.windowsHeight = res.windowHeight;
console.log('屏幕高度:', res.windowHeight);
}
});
// 动态计算滚动区域高度
this.calculateScrollHeight();
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; // 完成加载
this.isTriggered = false
}).catch(err => {
console.error('获取订单数据失败', err);
this.loading = false; // 出错也停止加载
this.isTriggered = false
});
},
calculateScrollHeight() {
// 获取屏幕高度
const screenHeight = uni.getSystemInfoSync().windowHeight;
// 获取顶部区域高度
const topHeight = 170;
// 计算滚动区域高度
this.scrollHeight = screenHeight - topHeight;
},
/**
* 上滑加载数据
*/
onReachBottomCus() {
//判断 如果页码*页容量大于等于总条数,提示该页数据加载完毕
if (this.queryParams.pageNum >= this.totalPages) {
uni.$u.toast('没有更多数据了')
return
}
//页码+1,调用获取数据的方法获取第二页数据
this.queryParams.pageNum++
//此处调用自己获取数据列表的方法
this.getTableData()
},
/**
* 下拉刷新数据
*/
onRefresherrefresh() {
this.isTriggered = true
this.queryParams.pageNum = 1
this.tableData = 0
this.tableData = []
this.getTableData()
},
goDetail(inspectionInfoId) {
uni.navigateTo({
url: "/pages/index/orderdetails?inspectionInfoId=" + inspectionInfoId
})
},
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;
},
selectType(value) {
this.queryParams.type = value;
},
selectInspectionStatus(value) {
this.queryParams.chooseStatus = value;
},
selectInspectionSkuName(value) {
this.queryParams.skuName = 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; // 关闭选择器
},
handleInspectionTimeConfirm(e) {
this.queryParams.inspectionTime = e.value[0].value; // 获取用户选择的客户来源
this.inspectionTimeName = e.value[0].label; // 获取用户选择的客户来源
this.isShowInspectionTime = 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;
}
},
handleInspectionTimeClick() {
if (this.queryParams.inspectionTime) {
this.queryParams.inspectionTime = null;
this.inspectionTimeName = null
} else {
this.isShowInspectionTime = 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,
type: "",
skuName: ""
}
this.getTableData()
this.inspectionTimeName = ''
this.goodsName = ''
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>