636 lines
13 KiB
Vue
636 lines
13 KiB
Vue
<template>
|
|
<view>
|
|
<!-- 导航栏 -->
|
|
<view class="li-work-nav">
|
|
<SafeAreaTop />
|
|
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
|
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
|
@click="toPages({type:'nav'})"></text>
|
|
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mr-6 li-mb-8"
|
|
@click="toPages({type:'home'})"></text>
|
|
<text class="li-text-42">我的工单</text>
|
|
</view>
|
|
<!-- 搜索框 -->
|
|
<view class="li-w-90% li-mx-auto li-mt-15 li-mb-25">
|
|
<wd-search placeholderStyle="color:#d9d9d9" v-model="query.ticket_no" placeholder="工单编号查询" hide-cancel
|
|
placeholder-left @search="search"></wd-search>
|
|
</view>
|
|
<!-- 工单类型tabs -->
|
|
<view class="li-flex li-items-center">
|
|
<wd-tabs v-model="activeTab" slidable="auto" :slidable-num="4" :map-num='4' @click="tabChange">
|
|
<block v-for="(item, index) in tabList" :key="index">
|
|
<wd-tab :title="item.name" :badge-props="item.badgeProps"></wd-tab>
|
|
</block>
|
|
</wd-tabs>
|
|
</view>
|
|
</view>
|
|
<view class="li-flex li-items-center li-mx-auto li-w-92% li-mt-check-costom">
|
|
<text v-for="(item,index) in orderStatusList" :key="index"
|
|
:class="item.id==query.status?'space-check':'space-checkOut'" @click="handleStatusChange(item.id)">
|
|
{{item.title}}
|
|
</text>
|
|
</view>
|
|
|
|
<!-- 工单列表 -->
|
|
<view class="li-w-92% li-mx-auto li-mt-list-costom">
|
|
<view v-for="(item, index) in taskList" :key="index" @click="toPages({type:'detail',value:item})"
|
|
class="order-card">
|
|
<!-- 订单头部 -->
|
|
<view class="order-header">
|
|
<view class="order-id">
|
|
<text class="ri-file-list-line id-icon"></text>
|
|
<text class="id-text">{{item.ticket_no}}</text>
|
|
<text class="ri-file-copy-line copy-icon"></text>
|
|
</view>
|
|
<view class="order-status" :style="{
|
|
color: getStatusColor(item.status),
|
|
backgroundColor: getStatusBgColor(item.status)
|
|
}">
|
|
{{getStatusText(item.status)}}
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 订单内容 -->
|
|
<view class="order-content">
|
|
<view class="info-row">
|
|
<text class="row-label">工单类型</text>
|
|
<view class="type-tag" :class="'type-'+item.type">
|
|
<text class="tag-icon" :class="{
|
|
'ri-truck-line': item.type == 'F2',
|
|
'ri-tools-line': item.type == 'F6',
|
|
'ri-ruler-line': item.type == 'F4'
|
|
}"></text>
|
|
<text v-if="item.type == 'F2'">配送</text>
|
|
<text v-if="item.type == 'F6'">维修</text>
|
|
<text v-if="item.type == 'F4'">量房</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="info-row">
|
|
<text class="row-label">小区名称</text>
|
|
<text class="row-value">{{item.order.village_name}}</text>
|
|
</view>
|
|
|
|
<view class="contact-info">
|
|
<view class="contact-row">
|
|
<text class="contact-icon ri-user-3-line"></text>
|
|
<text class="contact-label">联系人:</text>
|
|
<text class="contact-name">{{item.order.name}}</text>
|
|
</view>
|
|
<view class="contact-row">
|
|
<text class="contact-icon ri-phone-line"></text>
|
|
<text class="contact-phone">{{item.order.mobile}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 订单底部 -->
|
|
<view class="order-footer">
|
|
<view class="time-info">
|
|
<text class="time-icon ri-time-line"></text>
|
|
<text class="time-text">{{item.create_time}}</text>
|
|
</view>
|
|
<view class="detail-btn" v-if="item.status === 1">详情</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="taskList.length==0" class="!li-mt-300">
|
|
<wd-status-tip :image="uni.$globalData?.RESOURCE_URL+'tip/search.png'" tip="您还没有待处理的订单哦~" />
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { onLoad, onShow, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
|
|
import SafeAreaTop from '@/components/SafeAreaTop/index.vue'
|
|
import { useNavigation } from '@/hooks/useNavigation'
|
|
import { myTicketList } from '@/api/ticket'
|
|
// 使用导航 composable
|
|
const {
|
|
hasMultiplePages, // 是否有多个页面在路由栈中
|
|
isTabBarPage, // 当前页面是否为 tabBar 页面
|
|
checkRouteStack // 检查当前路由栈状态的方法
|
|
} = useNavigation()
|
|
interface QueryParams {
|
|
page : number;
|
|
limit : number;
|
|
type : string;
|
|
status : string | number;
|
|
ticket_no : string;
|
|
}
|
|
|
|
const query = ref<QueryParams>({
|
|
page: 1,
|
|
limit: 10,
|
|
type: 'ALL',
|
|
status: 1,
|
|
ticket_no: ''
|
|
})
|
|
|
|
const poolList = async () => {
|
|
loading.value = true
|
|
const res = await myTicketList(query.value)
|
|
loading.value = false
|
|
if (res.data.length < query.value.limit) {
|
|
finish.value = true
|
|
}
|
|
taskList.value.push(...res.data)
|
|
}
|
|
|
|
|
|
|
|
const finish = ref<boolean>(false)
|
|
const loading = ref<boolean>(false)
|
|
const keyword = ref('')
|
|
const activeTab = ref(0)
|
|
const status = ref('0')
|
|
const taskList = ref([])
|
|
|
|
// tab列表
|
|
const tabList = ref([
|
|
{
|
|
name: '全部',
|
|
value: 0,
|
|
badgeProps: {
|
|
modelValue: 0,
|
|
right: '-8px'
|
|
}
|
|
},
|
|
{
|
|
name: '商品配送',
|
|
value: 1,
|
|
badgeProps: {
|
|
modelValue: 0,
|
|
right: '-8px'
|
|
}
|
|
},
|
|
{
|
|
name: '维修工单',
|
|
value: 2,
|
|
badgeProps: {
|
|
modelValue: 0,
|
|
right: '-8px'
|
|
}
|
|
},
|
|
{
|
|
name: '量房工单',
|
|
value: 3,
|
|
badgeProps: {
|
|
modelValue: 0,
|
|
right: '-8px'
|
|
}
|
|
}
|
|
])
|
|
|
|
|
|
const orderStatusList = ref([
|
|
// {
|
|
// title: '全部',
|
|
// id: 'ALL'
|
|
// },
|
|
{
|
|
title: '待完成',
|
|
id: 1
|
|
},
|
|
{
|
|
title: '已完成',
|
|
id: 2
|
|
}
|
|
])
|
|
|
|
const tabChange = () => {
|
|
switch (activeTab.value) {
|
|
case 1:
|
|
query.value.type = 'F2'
|
|
break;
|
|
case 2:
|
|
query.value.type = 'F6'
|
|
break;
|
|
case 3:
|
|
query.value.type = 'F4'
|
|
break;
|
|
default:
|
|
query.value.type = 'ALL'
|
|
break;
|
|
}
|
|
query.value.page = 1
|
|
taskList.value = []
|
|
poolList()
|
|
}
|
|
|
|
const search = async () => {
|
|
query.value.page = 1
|
|
taskList.value = []
|
|
poolList()
|
|
}
|
|
|
|
const toPages = (item) => {
|
|
console.log(item);
|
|
switch (item.type) {
|
|
case 'nav':
|
|
uni.navigateBack({
|
|
delta: 1
|
|
});
|
|
break;
|
|
case 'home':
|
|
uni.switchTab({
|
|
url: '/pages/index/index'
|
|
})
|
|
break;
|
|
case 'detail':
|
|
uni.navigateTo({
|
|
url: '/pagesA/my_order/detail?ticket_id=' + item.value.ticket_id
|
|
})
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 状态颜色配置
|
|
const getStatusColor = (status) => {
|
|
const colorMap = {
|
|
0: '#ff9d00', // 待配送
|
|
1: '#37A5FF', // 未入库
|
|
2: '#00b42a', // 已完成
|
|
3: '#F42429' // 已取消
|
|
}
|
|
return colorMap[status] || '#666666'
|
|
}
|
|
|
|
// 状态背景色配置
|
|
const getStatusBgColor = (status) => {
|
|
const bgColorMap = {
|
|
0: '#fff6e9', // 待配送
|
|
1: '#e8f4ff', // 未入库
|
|
2: '#e8ffea', // 已完成
|
|
3: '#ffe8e8' // 已取消
|
|
}
|
|
return bgColorMap[status] || '#f5f5f5'
|
|
}
|
|
|
|
// 状态文字配置
|
|
const getStatusText = (status) => {
|
|
const textMap = {
|
|
0: '待接单',
|
|
1: '待完成',
|
|
2: '已完成',
|
|
3: '已取消'
|
|
}
|
|
return textMap[status] || '未知状态'
|
|
}
|
|
|
|
const handleStatusChange = (id) => {
|
|
query.value.status = id
|
|
tabChange()
|
|
}
|
|
|
|
|
|
|
|
onLoad((options) => {
|
|
checkRouteStack()
|
|
if (options.type) {
|
|
activeTab.value = Number(options.type)
|
|
// handleStatusChange(Number(options.status))
|
|
query.value.status = Number(options.status)
|
|
} else {
|
|
activeTab.value = 0
|
|
query.value.status = 1
|
|
// handleStatusChange('ALL')
|
|
}
|
|
})
|
|
|
|
onShow(() => {
|
|
tabChange()
|
|
})
|
|
|
|
onPullDownRefresh(() => {
|
|
query.value.page = 1
|
|
taskList.value = []
|
|
poolList()
|
|
setTimeout(() => {
|
|
uni.stopPullDownRefresh()
|
|
}, 300)
|
|
})
|
|
|
|
onReachBottom(() => {
|
|
if (finish.value) return
|
|
query.value.page++
|
|
poolList()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
background-color: #F7F8FA;
|
|
}
|
|
|
|
.li-work-nav {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 100;
|
|
background: linear-gradient(135deg,
|
|
rgba(200, 228, 255, 0.95) 0%,
|
|
rgba(220, 238, 255, 0.95) 45%,
|
|
rgba(235, 245, 255, 0.95) 100%);
|
|
|
|
}
|
|
|
|
::v-deep .wd-search {
|
|
background-color: transparent !important;
|
|
padding: 0 !important;
|
|
border-radius: 10rpx !important;
|
|
}
|
|
|
|
::v-deep .wd-search__block {
|
|
background-color: rgba(255, 255, 255, 0.8) !important;
|
|
width: 480rpx !important;
|
|
padding: 4rpx !important;
|
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.015);
|
|
}
|
|
|
|
::v-deep .uni-input-placeholder,
|
|
.uni-input-input {
|
|
width: auto !important;
|
|
}
|
|
|
|
::v-deep .wd-tabs {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
::v-deep .wd-badge__content {
|
|
border: none !important;
|
|
}
|
|
|
|
::v-deep .wd-tabs__map-btn {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
::v-deep .wd-tabs__map-nav-btn.is-active {
|
|
color: #009aff !important;
|
|
border: solid 1px #009aff !important;
|
|
}
|
|
|
|
.li-mt-check-costom {
|
|
/* #ifdef APP*/
|
|
padding-top: 380rpx;
|
|
/* #endif */
|
|
/* #ifdef MP-WEIXIN */
|
|
padding-top: 400rpx;
|
|
/* #endif */
|
|
/* #ifdef H5 */
|
|
padding-top: 350rpx;
|
|
/* #endif */
|
|
}
|
|
|
|
.li-mt-list-costom {
|
|
/* #ifdef APP*/
|
|
margin-top: 40rpx;
|
|
/* #endif */
|
|
/* #ifdef MP-WEIXIN */
|
|
margin-top: 40rpx;
|
|
/* #endif */
|
|
/* #ifdef H5 */
|
|
margin-top: 40rpx;
|
|
/* #endif */
|
|
}
|
|
|
|
|
|
.order-card {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 24rpx 30rpx;
|
|
margin-bottom: 24rpx;
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
&:active {
|
|
transform: scale(0.99);
|
|
transition: transform 0.2s;
|
|
}
|
|
|
|
/* 工单头部 */
|
|
.order-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
padding-bottom: 20rpx;
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
|
|
.order-id {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.id-icon {
|
|
font-size: 32rpx;
|
|
color: #999;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.id-text {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.copy-icon {
|
|
font-size: 28rpx;
|
|
color: #009aff;
|
|
margin-left: 16rpx;
|
|
}
|
|
}
|
|
|
|
.order-status {
|
|
font-size: 22rpx;
|
|
padding: 4rpx 18rpx;
|
|
border-radius: 20rpx;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
/* 工单内容 */
|
|
.order-content {
|
|
padding: 10rpx 0 16rpx;
|
|
|
|
.info-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
|
|
.row-label {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.row-value {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
max-width: 65%;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.type-tag {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 4rpx 12rpx;
|
|
border-radius: 12rpx;
|
|
font-size: 24rpx;
|
|
font-weight: 500;
|
|
color: #009aff;
|
|
background-color: rgba(0, 154, 255, 0.08);
|
|
|
|
&.type-F2 {
|
|
color: #ff9d00;
|
|
background-color: rgba(255, 157, 0, 0.08);
|
|
}
|
|
|
|
&.type-F6 {
|
|
color: #00b42a;
|
|
background-color: rgba(0, 180, 42, 0.08);
|
|
}
|
|
|
|
&.type-F4 {
|
|
color: #643bed;
|
|
background-color: rgba(100, 59, 237, 0.08);
|
|
}
|
|
|
|
.tag-icon {
|
|
margin-right: 6rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.contact-info {
|
|
padding: 16rpx 20rpx;
|
|
background-color: rgba(0, 154, 255, 0.03);
|
|
border-radius: 12rpx;
|
|
|
|
.contact-row {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 12rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.contact-icon {
|
|
font-size: 28rpx;
|
|
color: #009aff;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.contact-label {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.contact-name {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.contact-phone {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 工单底部 */
|
|
.order-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
border-top: 1px dashed rgba(0, 0, 0, 0.05);
|
|
padding-top: 16rpx;
|
|
|
|
.time-info {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.time-icon {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-right: 6rpx;
|
|
}
|
|
|
|
.time-text {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.detail-btn {
|
|
padding: 8rpx 30rpx;
|
|
background: linear-gradient(to right, #7bbfff, #009aff);
|
|
color: #fff;
|
|
font-size: 24rpx;
|
|
border-radius: 30rpx;
|
|
box-shadow: 0 4rpx 8rpx rgba(0, 154, 255, 0.15);
|
|
}
|
|
}
|
|
}
|
|
|
|
::v-deep .space {
|
|
padding: 2rpx 20rpx !important;
|
|
border-radius: 15rpx !important;
|
|
font-size: 22rpx !important;
|
|
transition: all 0.3s ease;
|
|
border: none !important;
|
|
}
|
|
|
|
|
|
::v-deep .space-check {
|
|
padding: 10rpx 40rpx !important;
|
|
margin-right: 20rpx !important;
|
|
border-radius: 30rpx !important;
|
|
font-size: 24rpx !important;
|
|
transition: all 0.3s ease;
|
|
color: #ffffff !important;
|
|
background: linear-gradient(to right, #7bbfff, #009aff) !important;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
::v-deep .space-checkOut {
|
|
padding: 10rpx 40rpx !important;
|
|
margin-right: 20rpx !important;
|
|
border-radius: 30rpx !important;
|
|
font-size: 24rpx !important;
|
|
transition: all 0.3s ease;
|
|
color: #4c4c4c !important;
|
|
background: linear-gradient(to right, #FFFFFF, #FFFFFF) !important;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
::v-deep .wd-tabs__nav {
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
::v-deep .wd-tabs__line {
|
|
background: #009aff !important;
|
|
}
|
|
|
|
::v-deep .wd-radio__label {
|
|
font-size: 26rpx !important;
|
|
}
|
|
</style> |