Files
emsapp/pages/ticket/list.vue

245 lines
4.9 KiB
Vue
Raw Normal View History

2026-02-08 17:26:51 +08:00
<template>
<view class="container">
<view class="status-bar"></view>
2026-02-08 21:51:10 +08:00
<view class="page-title">工单</view>
2026-02-08 17:26:51 +08:00
<view class="btn-list">
<uni-row>
<uni-col :span="12">
<button type="default" class="btns" :class="{'active-btn' : active === 'undone'}"
@click="changeTab('undone')">待处理</button>
</uni-col>
<uni-col :span="12">
<button type="default" class="btns" :class="{'active-btn' : active === 'done'}"
@click="changeTab('done')">已处理</button>
</uni-col>
</uni-row>
</view>
<view v-if="list.length===0" class="no-data">暂无数据</view>
<view class="content scroll-y" v-else>
<view class="item-list" v-for="item in list" :key="item.ticketNo+'ticket'" @click="toDetail(item.id)">
<view class="item-title" :class="item.status === 3 ? 'done' : item.status === 2 ? 'doing' : 'undone'">
工单号{{item.ticketNo}}
<view class="item-status">{{ticketStatusOptions[item.status]}}</view>
</view>
<view class="item-content">
<view class="item-info">工单标题:
<text class="info-value">{{item.title}}</text>
</view>
<view class="item-info">问题描述:
<text class="info-value">{{item.content}}</text>
</view>
<view class="item-info">预期完成时间:
<text class="info-value">{{item.expectedCompleteTime || '-'}}</text>
</view>
<view class="item-info">处理人:
<text class="info-value">
{{item.workName || '-'}}
</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from 'vuex'
import {
listTicket
} from 'api/ems/ticket'
export default {
computed: {
...mapState({
ticketStatusOptions: (state) => state.ems.ticketStatusOptions
})
},
data() {
return {
active: 'undone',
total: 0,
list: [],
pageNum: 1,
pageSize: 20
}
},
methods: {
changeTab(active) {
if (active === this.active) return
this.active = active
this.reset()
this.init()
},
init() {
//1: '待处理', 2: '处理中', 3: '已处理'
let url = `/ticket/list?pageNum=${this.pageNum}&pageSize=${this.pageSize}`
if (this.active === 'done') {
url += `&status=3`
} else {
url += `&status=1&status=2`
}
uni.showLoading()
return listTicket(url).then(response => {
const data = JSON.parse(JSON.stringify(response?.rows || []))
this.list = this.list.concat(data)
this.total = response?.total || 0
}).finally(() => {
uni.hideLoading()
})
},
toDetail(id) {
this.$tab.navigateTo(`/pages/ticket/index?id=${id}`)
},
reset() {
this.list = []
this.total = 0
this.pageNum = 1
}
},
onReachBottom() {
if (this.list.length >= this.total) {
return console.log('数据已经加载完成')
}
this.pageNum += 1;
this.init().catch(() => {
this.pageNum -= 1
})
},
onShow() {
this.reset()
this.init()
}
}
</script>
<style scoped lang="scss">
.container {
position: relative;
background-color: #f5f6f7;
.no-data {
padding-top: 180rpx;
}
}
uni-button:after {
border: none;
border-radius: 0;
}
.btn-list {
position: fixed;
2026-02-08 21:51:10 +08:00
top: calc(var(--status-bar-height) + 56rpx);
2026-02-08 17:26:51 +08:00
left: 0;
width: 100%;
z-index: 2;
padding: 20rpx 30rpx;
background: #ffffff;
.btns {
border: none;
border-radius: 40rpx;
width: 90%;
font-size: 26rpx;
line-height: 64rpx;
color: #19242d;
background: #d9e7fc;
&.active-btn {
background: #4c7af3;
color: #fff;
}
}
}
.content {
2026-02-08 21:51:10 +08:00
padding: 120px 30rpx 120rpx 30rpx;
2026-02-08 17:26:51 +08:00
z-index: 1;
}
2026-02-08 21:51:10 +08:00
.page-title {
position: fixed;
top: var(--status-bar-height);
left: 0;
width: 100%;
z-index: 3;
padding: 16rpx 30rpx 10rpx;
font-size: 32rpx;
font-weight: 700;
color: #19242d;
background: #ffffff;
text-align: center;
}
2026-02-08 17:26:51 +08:00
// 工单列表
.item-list {
color: #4b4951;
border-radius: 14rpx;
box-shadow: 0 0 20rpx rgba(0, 0, 0, .1), 0 0 0 rgba(0, 0, 0, .5);
font-size: 26rpx;
line-height: 40rpx;
margin-bottom: 30rpx;
border: 1px solid #eee;
background: #ffffff;
// 标题
.item-title {
border-radius: 14rpx 14rpx 0 0;
border-bottom: 1px solid #eee;
padding: 20rpx 30rpx;
font-weight: 700;
position: relative;
.item-status {
position: absolute;
right: 0;
top: 0;
padding: 2rpx 20rpx;
color: #ffffff;
font-size: 22rpx;
}
&.done {
.item-status {
background-color: #30be95;
}
}
&.doing {
.item-status {
background-color: #3c68e7;
}
}
&.undone {
.item-status {
background-color: #ed7876;
}
}
}
// 内容
.item-content {
padding: 20rpx 30rpx;
font-size: 24rpx;
.item-info {
margin-bottom: 20rpx;
.info-value {
padding-left: 10rpx;
}
}
}
.item-content .item-info:last-child {
margin-bottom: 0;
}
}
.content .item-list:last-child {
margin-bottom: 0;
}
2026-02-08 21:51:10 +08:00
</style>