Files
SmartParks_uniapp/pages/sys/workbench/order/order.vue

369 lines
8.3 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="order-container">
<view class="filter">
<view class="filter-btn" @click="togglePopup">工单类型
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
</view>
<view class="filter-btn">工单状态
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
</view>
<view class="filter-btn">处理人
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
</view>
</view>
<!-- tab栏 -->
<view class="order-tabs">
<view v-for="(tab, idx) in tabs" :key="idx" :class="['order-tab', {active: idx === activeTab}]"
@click="changeTab(idx)">
{{ tab }}
<view v-if="idx === activeTab" class="tab-underline"></view>
</view>
</view>
<!-- 列表区 -->
<scroll-view scroll-y class="order-list" @scroll="handleScroll">
<view v-for="(item, idx) in list" :key="idx" class="order-card" @click="goDetail(item)">
<view class="order-row">
<view class="order-no">工单号{{ item.orderNo }}</view>
<view class="order-status" :class="getStatusColor(item.status)">
{{ getStatusLabel(item.status) }}
</view>
</view>
<image class="order-line-image" src="/static/ic_my_repair_03.png" />
<view class="order-info">工单名称{{ item.orderName }}</view>
<view class="order-info">工单类型{{ item.typeName }}</view>
<view class="order-info">创建时间{{ item.createTime }}</view>
<view class="order-info"> {{ item.createTime }}-{{item.planCompleTime}}</view>
<view v-if="item.statusText === '已结束'" class="order-eval-btn eval-btn-right">服务评价</view>
</view>
</scroll-view>
<!-- 悬浮新增按钮 -->
<image v-if="false" src="/static/ic_my_repair_02.png"
:class="['order-add-btn-fixed', { 'hide': isAddBtnHidden }]" @click="addOrder" />
<!-- 工单类型弹窗 -->
<u-popup v-model="showPopup" mode="bottom">
<view class="popup-content">
<view class="popup-header">
<text @click="closePopup">取消</text>
<text>选择工单类型</text>
<text @click="confirmSelection">确定</text>
</view>
<view class="popup-body">
<u-cell-group>
<u-cell title="全部" @click="selectType('全部')"></u-cell>
<u-cell title="报修" @click="selectType('报修')"></u-cell>
<u-cell title="投诉" @click="selectType('投诉')"></u-cell>
</u-cell-group>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
tabs: ['待办', '全部'],
activeTab: 1,
tabData: [
[],
[]
], // 每个tab的数据
tabLoaded: [false, false], // 每个tab是否已加载
loading: false,
lastScrollTop: 0,
isAddBtnHidden: false,
showPopup: false,
selectedType: ''
}
},
computed: {
list() {
return this.tabData[this.activeTab];
}
},
created() {
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
},
methods: {
goBack() {
uni.navigateBack();
},
addOrder() {
uni.navigateTo({
url: '/pages/sys/workbench/order/addOrder'
});
},
handleScroll(e) {
const scrollTop = e.detail.scrollTop;
// 为了避免过于频繁的触发,可以设置一个阈值
if (Math.abs(scrollTop - this.lastScrollTop) < 20) {
return;
}
if (scrollTop > this.lastScrollTop && scrollTop > 50) {
// 向下滚动,隐藏按钮
this.isAddBtnHidden = true;
} else {
// 向上滚动,显示按钮
this.isAddBtnHidden = false;
}
this.lastScrollTop = scrollTop;
},
async changeTab(idx) {
this.activeTab = idx;
if (!this.tabLoaded[idx]) {
await this.loadTabData(idx);
}
},
async loadTabData(idx) {
this.loading = true;
// 模拟接口请求不同tab返回不同mock数据
let params = {}
if (idx === 0) {
params = {}
}
let data = [];
let res = await this.$u.api.getOrderList(params);
if (res.code == '200') {
data = res.rows
}
this.$set(this.tabData, idx, data);
this.$set(this.tabLoaded, idx, true);
this.loading = false;
},
getStatusLabel(status) {
const statusMap = {
0: '创建工单',
1: '已接单',
2: '已接单',
3: '处理中',
4: '已完成'
};
return statusMap[status] || '';
},
getStatusColor(status) {
const statusMap = {
0: 'orange',
1: 'doing',
2: 'doing',
3: 'doing',
4: 'done'
};
return statusMap[status] || '';
},
goDetail(item) {
// 将item对象转换为JSON字符串并进行编码然后通过URL参数传递
const itemStr = encodeURIComponent(JSON.stringify(item));
uni.navigateTo({
url: '/pages/sys/workbench/order/orderDetail?item=' + itemStr
});
},
togglePopup() {
this.showPopup = !this.showPopup;
},
selectType(type) {
this.selectedType = type;
},
closePopup() {
this.showPopup = false;
},
confirmSelection() {
if (this.selectedType) {
// 处理确认逻辑,例如更新筛选条件
console.log('Selected type:', this.selectedType);
}
this.showPopup = false;
}
}
}
</script>
<style scoped>
.order-container {
height: 100vh;
background: #f7f7f7;
display: flex;
flex-direction: column;
}
.filter {
display: flex;
flex-direction: row;
background: #fff;
padding-left: 36rpx;
padding-top: 15rpx;
padding-bottom: 15rpx;
}
.filter-btn {
padding: 15rpx 22rpx 15rpx 22rpx;
background: #F7F7F7;
border-radius: 25rpx;
height: 58rpx;
color: #9A9A9A;
font-size: 28rpx;
display: flex;
justify-content: center;
align-items: center;
margin-right: 24rpx;
}
.filter-img {
width: 18rpx;
height: 10rpx;
margin-left: 8rpx;
}
.order-tabs {
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
height: 80rpx;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
/* 防止被压缩 */
}
.order-tab {
flex: 1;
text-align: center;
font-size: 30rpx;
color: #888;
position: relative;
font-weight: 500;
padding: 0 0 10rpx 0;
/* tab点击事件 */
cursor: pointer;
}
.order-tab.active {
color: #2186FF;
font-weight: bold;
}
.tab-underline {
width: 60rpx;
height: 6rpx;
background: #2186FF;
border-radius: 3rpx;
margin: 0 auto;
margin-top: 8rpx;
}
.order-list {
margin: 32rpx 0 0 0;
padding: 0 24rpx;
flex: 1;
/* 占据所有剩余空间 */
overflow-y: auto;
/* 内容超出时,开启垂直滚动 */
padding-bottom: 30rpx;
/* 为底部按钮留出空间 */
height: calc(100vh - 80rpx - 32rpx);
/* 减去tab栏高度和margin-top */
}
.order-card {
background: #fff;
border-radius: 12rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
padding-top: 25rpx;
padding-bottom: 32rpx;
}
.order-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12rpx;
margin-top: 25rpx;
margin-left: 19rpx;
margin-right: 50rpx;
}
.order-no {
font-size: 24rpx;
color: #0B0B0B;
font-weight: 500;
}
.order-status {
font-size: 24rpx;
font-weight: 500;
}
.order-line-image {
margin: left 29rpx;
margin-right: 39rpx;
height: 2rpx;
margin-bottom: 29rpx;
}
.order-status.orange {
color: #F3AB44;
}
.order-status.doing {
color: #00C9AA;
}
.order-status.done {
color: #8A8A8A;
}
.order-info {
font-size: 24rpx;
color: #888;
margin-bottom: 30rpx;
margin-left: 47rpx;
}
.order-add-btn-fixed {
position: fixed;
right: 40rpx;
bottom: 80rpx;
width: 100rpx;
height: 100rpx;
z-index: 100;
transition: transform 0.3s ease;
transform: translateX(0);
}
.order-add-btn-fixed.hide {
transform: translateX(200%);
}
.popup-content {
background-color: #fff;
width: 100%;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
border-bottom: 1px solid #f0f0f0;
}
.popup-header text {
color: #2186FF;
font-size: 30rpx;
}
.popup-body {
padding: 20rpx;
}
</style>