lanan-repair-app/pages-business/businessManage/businessManage.vue
2025-10-14 20:13:29 +08:00

745 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="business-management">
<!-- 业务总览头部 -->
<view class="header" style="position: relative;">
<view style="display: flex;">
<uni-icons style="position: absolute;left: 0;" @click="goBack" type="left" color="white"
size="24"></uni-icons>
<text class="title">业务管理</text>
</view>
<view class="subtitle">
<view class="text_">
<image style="height: 40rpx;width: 8rpx;" src="/static/images/business/text_left.png"></image>
<view>
业务总览
</view>
</view>
<view>
<uni-datetime-picker v-model="queryParams.dateRange" type="daterange" @change="initData()"
rangeSeparator="至" class="">
<view class="cont_time">
<view class="cont_size">{{queryParams.dateRange[0]}}</view>
<view class="bule_size">~</view>
<view class="cont_size">{{queryParams.dateRange[1]}}</view>
<view class=""> <u-icon name="arrow-down-fill" color="#0357FF" size="12"></u-icon></view>
</view>
</uni-datetime-picker>
</view>
</view>
<!-- 数据卡片 -->
<view class="data-cards">
<!-- 选项卡 -->
<view class="tabs">
<view class="tab" :class="{'active':tapIndex == index}" v-for="(item,index) in tapList" :key="index"
@click="tapIcon(index)">
<view class="">{{item.label || "无"}}</view>
<view class="tap_img" style="display: block;width: 30rpx;" v-show="tapIndex == index">
<image src="/static/images/icon_tap.png" mode="widthFix" class="tap_icon"></image>
</view>
</view>
</view>
<view class="card-row-1">
<view class="data-card">
<text class="card-value">进厂数</text>
<text class="card-label">{{ bossNum.newOrderNum }}</text>
</view>
<view class="data-card">
<text class="card-value">维修中</text>
<text class="card-label">{{ bossNum.workingNum }}</text>
</view>
<view class="data-card">
<text class="card-value">已竣工</text>
<text class="card-label">{{ bossNum.overNum }}</text>
</view>
</view>
<view class="card-row-2">
<view class="data-card">
<text class="card-value">已交车</text>
<text class="card-label">{{ bossNum.giveCusNum }}</text>
</view>
<view class="data-card">
<text class="card-value">未结算</text>
<text class="card-label">{{ bossNum.noPayNum }}</text>
</view>
<view class="data-card">
<text class="card-value">在厂数</text>
<text class="card-label">{{ bossNum.inCompanyNum }}</text>
</view>
</view>
</view>
<view class="business_title">
<!-- 选项卡 -->
<view class="tabs">
<view class="tab" :class="{'active':busTapIndex == index}" v-for="(item,index) in busTapList"
:key="index" @click="tapBusIcon(index)">
<view class="">{{item.label || "无"}}</view>
<view class="tap_img" style="display: block;" v-show="busTapIndex == index">
<image src="/static/images/icon_tap.png" mode="widthFix" class="tap_icon"></image>
</view>
</view>
</view>
<view class="">
<uni-search-bar radius="50" bgColor="#F8F4FF" @confirm="onRefresherrefresh"
v-model="queryParams.search" @cancel="onRefresherrefresh" @clear="onRefresherrefresh"
placeholder="请输入搜索内容"></uni-search-bar>
</view>
</view>
</view>
<view class="list">
<!-- 客户列表 -->
<scroll-view class="client-list" scroll-y style="height:100%" @scrolltolower="onReachBottomCus"
refresher-enabled @refresherrefresh="onRefresherrefresh" :refresher-triggered="isTriggered">
<view class="client-item" v-for="(item,index) in busList" :key="index" @click="goDetail(item)">
<view class="last-time">
<view class="">
最近办理业务时间:{{item.bizTime}}
</view>
<view class="">
次数:{{item.consumeCount}}
</view>
</view>
<view class="card_bottom">
<view class="info_left">
<view class="user_">
<view class="client-name" v-if="busTapIndex == 0">{{item.customerName}}</view>
<view class="client-name" v-else>{{item.carNum}}</view>
<view class="agent" v-if="busTapIndex == 0">经办人:{{item.handleName}}</view>
<view class="agent" v-else>{{item.customerName}}</view>
</view>
<view class="phone">联系电话:{{item.customerPhone}}</view>
</view>
<view class="info_right">
<view class="top_text">{{item.sourceStr}}</view>
<view class="bottom_text">
最近办理业务
</view>
</view>
</view>
</view>
<view style="text-align: center" v-if="busList.length==0">
<image class="" src="@/static/images/nothing.png"></image>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import request from '../../utils/request'
import {
getDateRange
} from '../../utils/utils'
export default {
data() {
return {
searchKeyword: '',
//下来刷新状态
isTriggered: true,
tapList: [{
label: "本日",
value: "day",
},
{
label: "本月",
value: "month",
},
{
label: "全部",
value: "all",
},
],
busTapList: [{
label: "客户",
value: "customer",
},
{
label: "车辆",
value: "car",
}
],
tapIndex: 0,
busTapIndex: 0,
queryParams: {
dateRange: [],
type: 'customer',
selectType: 'today',
pageNo: 1,
pageSize: 10,
search: null
},
bossNum: {},
busList: [],
}
},
async onLoad() {
await this.setCurrentMonthRange()
await this.initData()
},
methods: {
goBack() {
uni.navigateBack()
},
async tapIcon(index) {
this.tapIndex = index
await this.slectRange(index)
await this.initData()
},
tapBusIcon(index) {
this.busTapIndex = index
this.queryParams.type = this.busTapList[index].value
this.queryParams.pageNo = 1
this.busList = []
this.getList()
},
/**
* 初始化数据
*/
initData() {
this.getNum()
this.onRefresherrefresh()
},
getNum() {
request({
url: '/admin-api/repair/tickets/getBossNumNew',
method: 'get',
params: this.queryParams
}).then((res) => {
console.log(res)
if (res.code == 200) {
this.bossNum = res.data
}
})
},
getList() {
request({
url: '/admin-api/repair/statistics/listBusiness',
method: 'get',
params: this.queryParams
}).then((res) => {
if (res.code == 200) {
if (this.queryParams.pageNo == 1) {
this.busList = res.data.records
} else {
this.busList.push(...res.data.records)
}
}
//将获取的总条数赋值
this.total = res.data.total
this.isTriggered = false
})
},
clear() {},
cancel() {},
// 设置本月起止日期:月初到今天
setCurrentMonthRange() {
// 直接使用 Date 对象
const now = new Date();
// 创建月初的 Date 对象
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
this.queryParams.dateRange = [
this.formatDate(now), // 月初
this.formatDate(now), // 今天
];
},
formatDate(d) {
// 添加类型检查,确保 d 是 Date 对象
if (!(d instanceof Date)) {
console.error("formatDate() 期望接收 Date 对象,但收到:", d);
d = new Date(d); // 尝试转换为 Date 对象
if (isNaN(d.getTime())) {
// 检查是否有效日期
d = new Date(); // 如果转换失败,使用当前日期
}
}
return `${d.getFullYear()}-${this.pad(d.getMonth() + 1)}-${this.pad(
d.getDate()
)}`;
},
// 补零1 → 01
pad(n) {
return n.toString().padStart(2, "0");
},
slectRange(index) {
this.selected = index;
console.log(index, this.selected);
const {
value
} = this.tapList[index];
console.log(value);
this.queryParams.dateRange = getDateRange(value);
},
/**
* 上滑加载数据
*/
onReachBottomCus() {
//判断 如果页码*页容量大于等于总条数,提示该页数据加载完毕
if (this.queryParams.pageNo * this.queryParams.pageSize >= this.total) {
uni.$u.toast('没有更多数据了')
return
}
//页码+1,调用获取数据的方法获取第二页数据
this.queryParams.pageNo++
//此处调用自己获取数据列表的方法
this.getList()
},
/**
* 下拉刷新数据
*/
async onRefresherrefresh() {
this.isTriggered = true
this.pageNo = 1
this.total = 0
this.busList = []
await this.getList()
},
goDetail(data) {
uni.navigateTo({
url: `/pages-business/businessInfo/businessInfo?type=${this.queryParams.type}&data=${encodeURIComponent(JSON.stringify(data))}`
})
},
}
}
</script>
<style>
/* 全局样式 */
page {
background-color: #f5f5f5;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, sans-serif;
}
.business-management {
/* padding: 20rpx; */
background: #F2F5FE;
min-height: 100vh;
}
/* 头部样式 */
.header {
margin-bottom: 30rpx;
background: linear-gradient(180deg, #1A53FF 0%, #F2F5FE 100%);
/* height: 672rpx; */
color: white;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 30rpx;
padding-top: calc(var(--status-bar-height) + 20rpx);
}
.title {
font-size: 36rpx;
font-weight: bold;
display: block;
margin-bottom: 10rpx;
}
.subtitle {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
margin-top: 20rpx;
.text_ {
display: flex;
view {
width: 112rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 800;
font-size: 28rpx;
color: #FFFFFF;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
image {
margin-right: 20rpx;
}
}
}
.date-range {
width: 386rpx;
height: 56rpx;
background: #FFFFFF;
border-radius: 36rpx;
text-align: center;
.header {
width: 124rpx;
height: 24rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 24rpx;
color: #686C7A;
line-height: 36rpx;
text-align: right;
font-style: normal;
margin: auto 0;
}
}
/* 选项卡样式 */
.tabs {
display: flex;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
}
.tab {
margin-right: 40rpx;
font-size: 28rpx;
color: #666;
padding: 10rpx 0;
width: 56rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 28rpx;
color: #707677;
line-height: 42rpx;
text-align: right;
font-style: normal;
}
.tab.active {
color: #007AFF;
font-weight: bold;
width: 56rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: bold;
font-size: 28rpx;
color: #292D2E;
line-height: 42rpx;
text-align: right;
font-style: normal;
margin-bottom: 20rpx;
}
/* 数据卡片样式 */
.data-cards {
margin: 20rpx 0;
background: linear-gradient(180deg, #E4EFFF 0%, #FFFFFF 100%);
box-shadow: 0rpx 4rpx 16rpx 0rpx rgba(167, 179, 229, 0.25);
border-radius: 8rpx;
width: 726rpx;
/* height: 366rpx; */
padding: 20rpx 10rpx;
}
.card-row-1 {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
.data-card {
height: 112rpx;
width: 226rpx;
background: linear-gradient(180deg, #D3EFFF 0%, #E3F3FF 100%);
border-radius: 8rpx;
.card-value {
width: 84rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 28rpx;
color: #14557E;
line-height: 42rpx;
text-align: center;
font-style: normal;
}
.card-label {
width: 52rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: bold;
font-size: 28rpx;
color: #3E4045;
line-height: 42rpx;
text-align: center;
font-style: normal;
}
}
}
.card-row-2 {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
.data-card {
height: 112rpx;
width: 226rpx;
background: linear-gradient(180deg, #D8E6FF 0%, #EDF6FF 100%);
border-radius: 8rpx;
}
.card-value {
width: 84rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 28rpx;
color: #14557E;
line-height: 42rpx;
text-align: center;
font-style: normal;
}
.card-label {
width: 52rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: bold;
font-size: 28rpx;
color: #3E4045;
line-height: 42rpx;
text-align: center;
font-style: normal;
}
}
.data-card {
flex: 1;
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx 20rpx;
margin: 0 10rpx;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.card-value {
font-size: 40rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.card-label {
font-size: 24rpx;
color: #666;
}
/* 客户区域样式 */
.client-section {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
}
.section-subtitle {
font-size: 24rpx;
color: #999;
}
.search-box {
display: flex;
align-items: center;
background-color: #f5f5f5;
border-radius: 10rpx;
padding: 20rpx;
}
.search-input {
flex: 1;
font-size: 28rpx;
margin-left: 15rpx;
}
.placeholder {
color: #999;
}
/* 客户列表样式 */
.client-list {
max-height: 60vh;
width: 100%;
}
.client-item {
background: #FFFFFF;
border-radius: 8rpx;
padding: 20rpx 15rpx;
margin-bottom: 30rpx
}
.client-name {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 500;
font-size: 28rpx;
text-align: left;
font-style: normal;
margin-right: 20rpx;
}
.agent {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 24rpx;
color: #0357FF;
line-height: 36rpx;
text-align: left;
font-style: normal;
background-color: #DCE7FF;
border-radius: 20rpx;
padding: 0 10rpx;
}
.phone {
width: 312rpx;
height: 28rpx;
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 28rpx;
color: #8F9197;
line-height: 42rpx;
text-align: left;
font-style: normal;
}
/*
.last-time {
font-size: 26rpx;
color: #666;
display: block;
margin-bottom: 10rpx;
} */
.last-time {
border-bottom: 1px dashed #000;
padding-bottom: 50rpx;
width: 100%;
height: 24rpx;
font-weight: 400;
font-size: 24rpx;
color: #7E8390;
line-height: 36rpx;
text-align: left;
font-style: normal;
display: flex;
justify-content: space-between;
}
.tap_img {
height: 6rpx;
text-align: center;
margin: 0 auto;
image {
width: 34rpx;
height: 12rpx;
}
}
.cont_time {
background: #F1F4F7;
border-radius: 36rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0px 30rpx;
width: 386rpx;
height: 56rpx;
background: #FFFFFF;
border-radius: 36rpx;
}
.cont_size {
font-weight: 400;
font-size: 24rpx;
color: #686C7A;
}
.business_title {
display: flex;
justify-content: space-between;
width: 100%;
height: 100rpx;
}
.user_ {
display: flex;
}
.card_bottom {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
text-align: center;
}
.info_right {
text-align: right;
color: black;
.top_text {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 500;
font-size: 28rpx;
color: #323439;
line-height: 42rpx;
}
.bottom_text {
font-family: SourceHanSansCN, SourceHanSansCN;
font-weight: 400;
font-size: 28rpx;
color: #686B71;
}
}
.list {
padding: 20rpx;
height: calc(100vh - 800rpx);
}
.tap_icon {
width: 40rpx;
height: 40rpx;
}
</style>