<template> <view class="incidentList"> <view class="head"> <view class="tab" :class="{active: tab.id === dataInfo.tabActiveId}" v-for="tab in dataInfo.tabs" :key="tab.id" @click="clickTab(tab.id)"> {{tab.name}}<text v-if="tab.num !== ''">({{tab.num}})</text> </view> <view class="filter" @click="filterClick"> <text class="newicon newicon-shaixuan"></text> </view> </view> <view class="body" v-if="dataInfo.list.length"> <view class="body_item" v-for="data in dataInfo.list" :key="data.id" @click="toIncidentDetail(data)"> <view class="body_item_head ellipsis-multiline"> <text :style="priorityStyle(data.priority)">{{data.priority ? data.priority.name + ' ' : ''}}</text>{{data.description}} </view> <view class="body_item_content"> <view class="body_item_content_p" v-if="data.department"> <text class="name ellipsis">报修科室:{{data.department.dept}}</text> <view class="status" :style="stateStyle(data.state)">{{data.state ? data.state.name : ''}}</view> </view> <view class="body_item_content_p" v-if="data.place || data.houseNumber"> <text class="name ellipsis">详细地址:{{data.place ? data.place.building.buildingName : ''}}{{data.place ? data.place.floorName : ''}}{{data.houseNumber}}</text> </view> <view class="body_item_content_p" v-if="data.currentLog && data.currentLog.extra1DTO && data.currentLog.extra2 && data.currentLog.startTime"> <text class="name ellipsis">延期处理:{{currentLogOverTime(data.currentLog)}}</text> </view> <view class="body_item_content_p"> <text class="name" v-if="data.assigneeName"> 处理人:{{data.assigneeName}}<template v-if="computedSynergetic(data.synergetic)">,{{computedSynergetic(data.synergetic)}}</template> </text> <text class="name" v-else-if="data.candidateGroupsName"> 处理组:{{data.candidateGroupsName}}<template v-if="computedSynergetic(data.synergetic)">,{{computedSynergetic(data.synergetic)}}</template> </text> <text class="name" v-else> <template v-if="computedSynergetic(data.synergetic)">,{{computedSynergetic(data.synergetic)}}</template> </text> <view class="icon_all" @click.stop="attachmentClick(data)"> <uni-icons type="mic-filled" class="mic-filled" :size="22" color="#949494" v-if="data.callID"></uni-icons> <uni-icons type="image-filled" class="image-filled" :size="22" color="#949494" v-if="data.reqAttachment"></uni-icons> </view> </view> </view> <view class="body_item_foot"> <view class="foot_info"> <view class="name" @click.stop="makePhoneCall(data.contactsInformation)">联系电话:{{data.contactsInformation}}<uni-icons type="phone-filled" class="phone-filled" :size="18" :color="primaryColor"></uni-icons></view> <text class="date">{{formatDate(data.acceptDate, 'MM-dd HH:mm')}}</text> </view> <view class="btns"> <button @click.stop="handler('changeUser', data.id)" type="default" class="primaryButton btn" v-if="data.state.value === 'pending' || data.state.value === 'handler' || (data.state.value === 'reassign' && assignFlag)">换人处理</button> <button @click.stop="handler('handler', data.id)" type="default" class="primaryButton btn" v-if="data.state.value === 'handler' && data.handlingPersonnelUser && data.handlingPersonnelUser.id == loginUserStore.loginUser.user.id">处理</button> <button @click.stop="receive(data)" type="default" class="primaryButton btn" v-if="computedReceive(data)">接单</button> </view> </view> </view> </view> <view class="zanwu" v-else> <text class="newicon newicon-zanwu"></text> </view> <IncidentListFilter v-if="dataInfo.isFilter" @cancelEmit="cancelFilter" @confirmEmit="conformFilter" :evt="dataInfo.evtFilter"></IncidentListFilter> <IncidentAttachment v-if="dataInfo.isAttachment" @knowEmit="knowAttachment" :incidentData="dataInfo.incidentData"></IncidentAttachment> </view> </template> <script setup> import IncidentListFilter from '@/components/IncidentListFilter.vue'; import IncidentAttachment from '@/components/IncidentAttachment.vue'; import { startOfDay, endOfDay, format, add } from 'date-fns' import { ref, reactive, computed } from 'vue' import { onLoad, onPullDownRefresh, onReachBottom, onTabItemTap } from '@dcloudio/uni-app' import { api_getDictionary, api_incident, api_incident_count, api_incidentTask } from "@/http/api.js" import { filterFormatDate } from '@/filters/filterFormatDate.js' import { computedPriorityStyle } from '@/filters/computedPriorityStyle.js' import { computedStateStyle } from '@/filters/computedStateStyle.js' import { computedCurrentLogOverTime } from '@/filters/computedCurrentLogOverTime.js' import { defaultColor } from '@/static/js/theme.js' import { useSetTitle } from '@/share/useSetTitle.js' import { useMakePhoneCall } from '@/share/useMakePhoneCall.js' import { useSetTabbar } from '@/share/useSetTabbar.js' import { useLoginUserStore } from '@/stores/loginUser' import { useIncidentNumStore } from '@/stores/incidentNum' import { useIncidentListSearchStore } from '@/stores/incidentListSearch' import { useHandlerStore } from '@/stores/handler' useSetTitle(); const loginUserStore = useLoginUserStore(); const incidentNumStore = useIncidentNumStore(); const incidentListSearchStore = useIncidentListSearchStore(); const { formatDate } = filterFormatDate(); const { priorityStyle } = computedPriorityStyle(); const { stateStyle } = computedStateStyle(); const { currentLogOverTime } = computedCurrentLogOverTime(); const { makePhoneCall } = useMakePhoneCall(); const { setTabbar } = useSetTabbar(); const handlerStore = useHandlerStore(); // 主题颜色 const primaryColor = ref(defaultColor) const assignFlag = ref(false);//指派权限 const qiangdan = ref(false);//接单权限 // 判断是否显示接单按钮 const computedReceive = computed(() => (data) => { let inUser = data.handlingPersonnelUser && data.handlingPersonnelUser.id == loginUserStore.loginUser.user.id; let inUser2 = data.currentLog.workerId == loginUserStore.loginUser.user.id; let inGroup = false; if(loginUserStore.loginUser.user&&loginUserStore.loginUser.user.group){ loginUserStore.loginUser.user.group.forEach(item => { if(data.currentLog){ if (item.id == data.currentLog.groupId) { inGroup = true; } } }) } return data.state.value === 'pending' && (inUser2 || inGroup) && qiangdan.value; }) // 转换协同人 const computedSynergetic = computed(() => (synergetic) => { return (synergetic && synergetic.length) ? synergetic.map(v => v.name).join(',') : '' }) // 数据 const dataInfo = reactive({ tabs: [{id: 0, name: '全部', value: 'all', num: ''}], tabActiveId: 0,//当前选择的tab list: [],//工单列表 idx: 0,//页码 hasMore: true,//是否有更多数据 isFilter: false,//筛选框开关 isAttachment: false,//图片和录音开关 incidentId: undefined, evtFilter: { hospital: {}, selected: 'todoingAll', area: {id: 0, area: '全部'}, category: {id: 0, category: '全部'}, acceptDate: [], },//筛选框数据 }) // 工单详情 function toIncidentDetail(data){ uni.navigateTo({ url: `/pages/incidentDetail/incidentDetail?incidentId=${data.id}` }) } // 获取tab选项 function getTabs(){ uni.showLoading({ title: "加载中", mask: true, }); api_getDictionary({ "type": "list", "key": "incident_status" }).then(res => { uni.hideLoading(); let incidentStatusList = res || []; let pending = incidentStatusList.find(v => v.value === 'pending'); let handler = incidentStatusList.find(v => v.value === 'handler'); dataInfo.tabs = [{id: 0, name: '全部', value: 'all', num: ''}]; pending && dataInfo.tabs.push({...pending, ...{num: ''}}); handler && dataInfo.tabs.push({...handler, ...{num: ''}}); getList(0); }) } // 点击tab function clickTab(tabId){ dataInfo.tabActiveId = tabId; getList(0); } // 点击筛选 function filterClick(){ dataInfo.isFilter = true; } // 确认筛选 function conformFilter(evtFilter){ dataInfo.evtFilter = evtFilter; dataInfo.isFilter = false; getList(0); } // 关闭筛选 function cancelFilter(){ dataInfo.isFilter = false; } // 点击图片和录音 function attachmentClick(incidentData){ dataInfo.incidentData = incidentData; dataInfo.isAttachment = true; } // 知道了图片和录音 function knowAttachment(){ dataInfo.isAttachment = false; } // 处理按钮 function handler(type, incidentId){ handlerStore.clearHandlerData(); uni.navigateTo({ url: `/pages/${type}/${type}?incidentId=${incidentId}` }) } // 接单调用方案 function receiveFn(incidentData){ let placeId = JSON.parse(JSON.stringify(incidentData.place.id)) uni.showLoading({ title: "加载中", mask: true, }); let postData = { incident: incidentData, } postData.incident.place = {} postData.incident.place.id = placeId api_incidentTask('receive', postData).then(res => { uni.hideLoading(); if(res.state == 200){ getList(0); uni.showToast({ icon: 'none', title: '接单成功', }); }else{ uni.showToast({ icon: 'none', title: res.msg || '请求数据失败!' }); } }) } // 接单按钮 function receive(incidentData){ uni.showModal({ title: '提示', content: `您确认要接单吗?`, confirmColor: defaultColor, confirmText: '确认', success: function(res) { if (res.confirm) { receiveFn(incidentData); } } }); } // 获取列表信息 function getList(idx){ uni.showLoading({ title: "加载中", mask: true, }); dataInfo.idx = idx === undefined ? dataInfo.idx : idx; if(dataInfo.idx === 0){ dataInfo.list = []; } let postData = { "idx": dataInfo.idx, "sum": 10, "incident": { "queryTask": dataInfo.evtFilter.selected || undefined, "assignee": loginUserStore.loginUser.user.id, "statusId": dataInfo.tabActiveId || undefined, } } // 请求参数调整 if(!postData.incident){ postData.incident = {}; } let hospital = loginUserStore.loginUser.user.currentHospital? loginUserStore.loginUser.user.currentHospital: loginUserStore.loginUser.hospital[0] if(postData.incident.queryTask === 'all' || postData.incident.queryTask === 'callback'){ if(hospital.type && hospital.type.value == 6){ // 当前是责任科室 postData.incident.duty = hospital; }else{ // 当前是院区 postData.incident.hosId = hospital.id; } }else{ delete postData.incident.duty; delete postData.incident.hosId; } if(postData.incident.queryTask === 'todo' || postData.incident.queryTask === 'owns' || postData.incident.queryTask === 'todoingAll'){ if(loginUserStore.loginUser.user && loginUserStore.loginUser.user.group){ postData.incident.candidateGroups = loginUserStore.loginUser.user.group.map(v => v.id).toString(); } }else{ delete postData.incident.candidateGroups; } if(dataInfo.evtFilter && dataInfo.evtFilter.category){ postData.incident.levelCategory = { id: dataInfo.evtFilter.category.value }; } if(dataInfo.evtFilter && Array.isArray(dataInfo.evtFilter.acceptDate) && dataInfo.evtFilter.acceptDate.length){ postData.incident.acceptDate = format(startOfDay(new Date(dataInfo.evtFilter.acceptDate[0])), 'yyyy-MM-dd HH:mm:ss'); postData.incident.acceptDateEnd = format(endOfDay(dataInfo.evtFilter.acceptDate[1]), 'yyyy-MM-dd HH:mm:ss'); } if(dataInfo.evtFilter && dataInfo.evtFilter.area && dataInfo.evtFilter.area.id){ let id = dataInfo.evtFilter.area.id // postData.incident.area = dataInfo.evtFilter.area postData.incident.area = {id:id} } incidentListSearchStore.setIncidentListSearchData(dataInfo); api_incident(postData).then(res => { uni.hideLoading(); uni.stopPullDownRefresh(); if(res.status == 200){ let list = res.list || []; if(list.length){ dataInfo.hasMore = true; dataInfo.list = dataInfo.idx === 0 ? list : dataInfo.list.concat(list); }else{ dataInfo.hasMore = false; } }else{ uni.showToast({ icon: 'none', title: res.msg || '请求数据失败!' }); } }) getCount(postData.incident); } // 获取列表数量 function getCount(incident = {}){ let postData = { wxCount: 'true', incidentList: [], } dataInfo.tabs.forEach(v => { postData.incidentList.push({...incident, ...{statusId: v.id || undefined}}); }) api_incident_count(postData).then(res => { if(res.state == 200){ let myData = res.data || []; dataInfo.tabs.forEach((v, i) => { v.num = myData[i]; }) }else{ uni.showToast({ icon: 'none', title: res.msg || '请求数据失败!' }); } }) } // 初始化 function onLoadFn(){ // 我的-数量跳转 if(incidentNumStore.incidentNum.data){ dataInfo.evtFilter.selected = incidentNumStore.incidentNum.data.queryTask; dataInfo.tabActiveId = incidentNumStore.incidentNum.data.statusId; incidentNumStore.clearIncidentNumData(); }else if(incidentListSearchStore.incidentListSearch.data){ // 缓存的搜索条件 Object.assign(dataInfo, incidentListSearchStore.incidentListSearch.data); } for (let i = 0; i < loginUserStore.loginUser.menu.length; i++) { if (loginUserStore.loginUser.menu[i].link == "assign") { assignFlag.value = true; } if (loginUserStore.loginUser.menu[i].link == "receive") { qiangdan.value = true } } getTabs(); } onLoad((option) => { for(let i = 0; i<6; i++){ setTabbar(i) } onLoadFn(); }) onTabItemTap(e => { onLoadFn(); }) onPullDownRefresh(() => { getList(0) }) onReachBottom(() => { dataInfo.idx += 1; if (dataInfo.hasMore) { getList(); // 当触底时加载更多数据 } }) </script> <style lang="scss" scoped> page{ height: calc(100vh - var(--window-bottom)); } .incidentList{ display: flex; flex-direction: column; justify-content: space-between; .head{ height: 88rpx; display: flex; position: fixed; z-index: 99; width: 100%; background-color: #fff; font-size: 30rpx; .tab{ flex: 1; display: flex; justify-content: center; align-items: center; border-bottom: 4rpx solid transparent; &.active{ color: $uni-primary; border-color: $uni-primary; } } .filter{ width: 84rpx; display: flex; justify-content: center; align-items: center; .newicon-shaixuan{ font-size: 36rpx; color: #2C2C2C; } } } .body{ margin-bottom: var(--window-bottom); margin-top: 88rpx; border-top: 6rpx solid #EBEBEB; .body_item{ border-bottom: 8rpx solid #EBEBEB; .body_item_head{ word-break: break-all; text-align: justify; text-align: left; margin: 24rpx; font-size: 30rpx; } .body_item_content{ border-top: 1rpx solid #D8D8D8; padding: 24rpx 24rpx 24rpx 48rpx; .body_item_content_p{ color: #6A6A6A; font-size: 26rpx; display: flex; justify-content: space-between; align-items: center; margin-bottom: 24rpx; &:last-of-type{ margin-bottom: 0; } .name{ flex: 1; } .status{ padding: 4rpx 10rpx; border-radius: 20rpx; background-color: #DBE8FE; font-size: 22rpx; color: #006CF9; } .icon_all{ .mic-filled, .image-filled { margin-left: 16rpx; } } } } .body_item_foot{ border-top: 1rpx solid #D8D8D8; font-size: 26rpx; padding: 24rpx; .foot_info{ display: flex; justify-content: space-between; align-items: center; .phone-filled{ margin-left: 5rpx; } } } } } .zanwu{ box-sizing: border-box; margin-bottom: var(--window-bottom); margin-top: 88rpx; border-top: 6rpx solid #EBEBEB; height: calc(100vh - var(--window-bottom) - 88rpx); display: flex; justify-content: center; background-color: #F7F7F7; .newicon-zanwu{ font-size: 256rpx; color: #D6D6D6; margin-top: 140rpx; } } } </style>