工作栏

This commit is contained in:
白菜
2025-07-29 23:05:58 +08:00
parent 2b4022d1d0
commit ce9b4a4ca4
13 changed files with 2173 additions and 634 deletions

View File

@ -1,165 +1,184 @@
<template>
<view class="container">
<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>
<scroll-view class="scroll-y" :scroll-y="true" @scrolltolower="lower" scrolltoupper="upper" >
<view class="content">
<view class="item-list" v-for="item in list" :key="item.ticketNo+'ticket'" @click="toDetail(item.id)">
<view class="item-title" :class="item.status === 1 ? 'done' : 'undone'" >工单号{{item.ticketNo}}</view>
<view class="item-content">
<view class="item-info">工单标题:{{item.title}}</view>
<view class="item-info">问题描述:{{item.content}}</view>
<view class="item-info">工单状态:{{ticketStatusOptions[item.status]}}</view>
<view class="item-info">预期完成时间:{{item.expectedCompleteTime || '-'}}</view>
<view class="item-info">处理人:{{item.workName || '-'}}</view>
</view>
</view>
<view v-if="list.length===0" style='text-align: center;margin-top:40px;color:#666;'>暂无数据</view>
</view>
</scroll-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:10
}
},
methods:{
changeTab(active){
if(active===this.active)return
this.active = active
this.reset()
this.init()
},
lower(){
if(this.list.length>=this.total){
return console.log('数据已经加载完成')
}
this.pageNum+=1;
this.init().catch(()=>{this.pageNum-=1})
},
init(){
//0:'待处理', 1:'已处理', 2:'处理中'
let url=`/ticket/list?pageNum=${this.pageNum}&pageSize=${this.pageSize}`
if(this.active === 'done'){
url +=`&status=1`
}else{
url +=`&status=0&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
}
},
onShow(){
this.reset()
this.init()
}
}
</script>
<style scoped lang="scss">
.container{
position: relative;
}
uni-button:after{
border:none;
border-radius: 0;
}
.btn-list{
position: fixed;
top:0;
left: 0;
width:100%;
z-index:2;
.btns{
border-radius: 0;
border:none;
border-bottom: 1px solid #eee;
width:100%;
text-align: center;
font-size: 16px;
line-height: 50px;
background-color: #fff;
&.active-btn{
background-color: #3a98ff;
color:#fff;
}
}
}
.scroll-y{
height: calc(100vh - var(--window-bottom) - var(--window-top));
z-index:1;
}
.content {
background-color: #ffffff;
padding:70px 20px 60px 20px;
}
.item-list{
border-radius: 7px;
box-shadow: 0 0 10px rgba(0,0,0,.1),0 0 0 rgba(0,0,0,.5);
font-size: 16px;
line-height: 24px;
margin-bottom: 20px;
border:1px solid #eee;
.item-title{
border-radius: 7px 7px 0 0;
font-size: 18px;
border-bottom:1px solid #eee ;
padding:10px 15px;
background-color: #FC6B69;
color:#fff;
&.done{
background-color: #05AEA3;
}
}
.item-content{
padding:15px 15px;
.item-info{
margin-bottom:20px;
}
}
.item-content .item-info:last-child{
margin-bottom:0;
}
}
.content .item-list:last-child{
margin-bottom:0;
}
</style>
<template>
<view class="container">
<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>
<scroll-view class="scroll-y" :scroll-y="true" @scrolltolower="lower" scrolltoupper="upper">
<view class="content">
<view class="item-list" v-for="item in list" :key="item.ticketNo+'ticket'" @click="toDetail(item.id)">
<view class="item-title" :class="item.status === 1 ? 'done' : 'undone'">工单{{item.ticketNo}}</view>
<view class="item-content">
<view class="item-info">工单标题:{{item.title}}</view>
<view class="item-info">问题描述:{{item.content}}</view>
<view class="item-info">工单状态:{{ticketStatusOptions[item.status]}}</view>
<view class="item-info">预期完成时间:{{item.expectedCompleteTime || '-'}}</view>
<view class="item-info">处理人:{{item.workName || '-'}}</view>
</view>
</view>
<view v-if="list.length===0" class="no-data">暂无数据</view>
</view>
</scroll-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: 10
}
},
methods: {
changeTab(active) {
if (active === this.active) return
this.active = active
this.reset()
this.init()
},
lower() {
if (this.list.length >= this.total) {
return console.log('数据已经加载完成')
}
this.pageNum += 1;
this.init().catch(() => {
this.pageNum -= 1
})
},
init() {
//0:'待处理', 1:'已处理', 2:'处理中'
let url = `/ticket/list?pageNum=${this.pageNum}&pageSize=${this.pageSize}`
if (this.active === 'done') {
url += `&status=1`
} else {
url += `&status=0&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
}
},
onShow() {
this.reset()
this.init()
}
}
</script>
<style scoped lang="scss">
.container {
position: relative;
}
uni-button:after {
border: none;
border-radius: 0;
}
.btn-list {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 2;
.btns {
border-radius: 0;
border: none;
border-bottom: 1px solid #eee;
width: 100%;
text-align: center;
font-size: 16px;
line-height: 50px;
background-color: #fff;
&.active-btn {
background-color: #3a98ff;
color: #fff;
}
}
}
.scroll-y {
height: calc(100vh - var(--window-bottom) - var(--window-top));
z-index: 1;
}
.content {
background-color: #ffffff;
padding: 70px 20px 60px 20px;
}
.item-list {
border-radius: 7px;
box-shadow: 0 0 10px rgba(0, 0, 0, .1), 0 0 0 rgba(0, 0, 0, .5);
font-size: 14px;
line-height: 24px;
margin-bottom: 20px;
border: 1px solid #eee;
.item-title {
border-radius: 7px 7px 0 0;
font-size: 16px;
border-bottom: 1px solid #eee;
padding: 10px 15px;
background-color: #FC6B69;
color: #fff;
&.done {
background-color: #05AEA3;
}
}
.item-content {
padding: 15px 15px;
.item-info {
margin-bottom: 20px;
}
}
.item-content .item-info:last-child {
margin-bottom: 0;
}
}
.content .item-list:last-child {
margin-bottom: 0;
}
</style>