lanan-repair-app/pages-repair/home/home.vue
2024-10-21 20:36:02 +08:00

546 lines
13 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="container">
<!--<VNavigationBar style="position: relative;z-index: 99;" leftTitle="true" backgroundColor="rgba(0,0,0,0)" title-color="#fff" title=" "></VNavigationBar>-->
<view class="bodyTopBg"></view>
<view class="body">
<view class="userInfoBox" @click="showUserDetail">
<image style="width: 104rpx;height: 104rpx;border-radius: 50%;" v-if="''==userInfo.avatar || null == userInfo.avatar" :src="defaultAvatar" mode="scaleToFill" @error="avatarErr"></image>
<image style="width: 104rpx;height: 104rpx;border-radius: 50%;" v-else :src="imgUrlPrex+userInfo.avatar" mode="scaleToFill" @error="avatarErr"></image>
<view class="userInfo">
<text class="userName">{{ userInfo.nickname }}</text>
<text class="userType">{{ userInfo.roleNames }}</text>
</view>
<image style="width: 48rpx;height: 48rpx" src="/static/icons/more.png" mode="aspectFita"></image>
</view>
<view class="body-card">
<view class="title">审批单处理</view>
<view class="title-box">
<view class="title-box-item">
<view class="titleDesc">已提交</view>
<view class="titleNumber">4</view>
<image class="titleImg" src="@/static/images/nothing.png" ></image>
</view>
<view class="title-box-item">
<view class="titleDesc">未通过</view>
<view class="titleNumber">1</view>
<image class="titleImg" src="@/static/images/nothing.png" ></image>
</view>
<view class="title-box-item">
<view class="titleDesc">已通过</view>
<view class="titleNumber">6</view>
<image class="titleImg" src="@/static/images/nothing.png" ></image>
</view>
</view>
</view>
<view class="todoListBox">
<view class="title">
维修工单
<text class="titleDesc">当前共
<text class="titleCount"> {{total}} </text>
项工单需要处理
</text>
</view>
<view class="todoList">
<scroll-view scroll-y="true" class="itemContent" bindscrolltolower="onReachBottom"
refresher-enabled @refresherrefresh="onRefresherrefresh" :refresher-triggered="isTriggered">
<order-card v-for="(item, index) in orderList" :key="index" :order="item" @childEvent="onRefresherrefresh" @startWork="startWork"></order-card>
<view style="text-align: center" v-if="orderList.length==0">
<image class="" src="@/static/images/nothing.png" ></image>
</view>
</scroll-view>
</view>
</view>
</view>
<tabBarVue msg="1"></tabBarVue>
</view>
</template>
<script>
import tabBarVue from '@/components/tabBar/tabBar.vue'
import VNavigationBar from '@/components/VNavigationBar.vue'
import OrderCard from "@/components/repairCard.vue";
import config from '@/config'
import request from '@/utils/request';
import {formatTimestamp,getOrderStatusText,builderOrder,saveTicketsRecords} from "@/utils/utils";
import {
getToken,
getUserInfo,
getStrData,
getTenantId
} from '@/utils/auth'
export default {
components: {
OrderCard,
tabBarVue,
VNavigationBar
},
data() {
return {
imgUrlPrex:config.baseImageUrl,
userInfo: {
avatar: undefined,
nickname: ''
},
bannerIndex: 0,
shopList: [],
bannerList: [],
richTextHtml: null,
pageNo: 1,
pageSize: 10,
total: 0,
//下来刷新状态
isTriggered:false,
orderList: [
],
defaultAvatar: require('@/static/icons/avatar.png')
}
},
onLoad(){
if(!getToken()){
uni.reLaunch({
url: '/pages/login/login'
})
}else{
if(!this.$msgSocket){
this.$startMsgSocket(getTenantId(),getStrData("userId"))
}
}
},
onShow() {
if(!getToken()){
uni.reLaunch({
url: '/pages/login/login'
})
}else{
//直接取缓存中的用户信息
this.userInfo = getUserInfo()
this.onRefresherrefresh()
}
},
methods: {
/**
* 上滑加载数据
*/
onReachBottom() {
//判断 如果页码*页容量大于等于总条数,提示该页数据加载完毕
if (this.pageNo * this.pageSize >= this.total) {
uni.$u.toast('没有更多数据了')
return
}
//页码+1,调用获取数据的方法获取第二页数据
this.pageNo++
//此处调用自己获取数据列表的方法
this.getOrderList()
},
/**
* 下拉刷新数据
*/
onRefresherrefresh(){
this.isTriggered = true
this.pageNo = 1
this.total = 0
this.orderList = []
this.getOrderList()
},
/**
* 开始施工
*/
startWork(id){
let paramsObj = {ticketId:id}
//先查当前用户在本工单下有几个维修项目
request({
url: '/admin-api/repair/titem/listProject',
method: 'get',
params:paramsObj
}).then((res) => {
console.log(res)
if (res.code == 200 && res.data.length>0) {
if(res.data.length==1){
//只有1个直接开始施工
this.startWorkRequest(id,"02",res.data[0].id,"02","kssg","开始施工")
}else{
uni.showActionSheet({
itemList: res.data.map(m => m.itemName),
success: ({
tapIndex
}) => {
this.startWorkRequest(id,"02",res.data[tapIndex].id,"02","kssg","开始施工")
}
})
}
}else{
uni.showToast({
title: '操作失败,请联系管理员',
icon: 'none'
})
}
})
},
/**
* 开始施工请求后台
*/
async startWorkRequest(id,ticketsWorkStatus,itemId,itemStatus,recordType,remark){
try {
const result = await saveTicketsRecords(id,ticketsWorkStatus,itemId,itemStatus,recordType,remark,null);
console.error("result",result);
this.onRefresherrefresh()
} catch (error) {
console.error(error);
}
},
/**
* 查本人待处理工单
*/
getOrderList(){
let paramsObj = {pageNo: this.pageNo, pageSize: this.pageSize, isFinish: "0"}
request({
url: '/admin-api/repair/tickets/pageType',
method: 'get',
params:paramsObj
}).then((res) => {
console.log(res)
if (res.code == 200) {
let thisPageRecords = []
if(res.data && res.data.hasOwnProperty("records")){
for (let i = 0; i < res.data.records.length; i++) {
let order = res.data.records[i]
let viewOrder = builderOrder(order)
if(order.booking){
viewOrder['appointDate'] = formatTimestamp(order.createTime)
}
let projectList = []
if(order.itemList){
for (let j = 0; j < order.itemList.length; j++) {
let itemObj = order.itemList[j]
if("01"==itemObj.itemType){
projectList.push({
id:itemObj.id,
name:itemObj.itemName
})
}
}
}
viewOrder['projectList'] = projectList
thisPageRecords.push(viewOrder)
}
}
//判断 如果获取的数据的页码不是第一页,就让之前赋值获取过的数组数据 concat连接 刚获取的第n页数据
if (this.pageNo != 1) {
this.orderList = this.orderList.concat(thisPageRecords)
} else {
this.orderList = thisPageRecords
}
//将获取的总条数赋值
if(res.data){
this.total = res.data.total
}
this.isTriggered = false
}
})
},
gotoPage(menu) {
uni.navigateTo({
url: menu.path
})
},
avatarErr(err) {
console.log('err', err)
this.userInfo.avatar = this.defaultAvatar
},
showUserDetail() {
uni.navigateTo({
url: '/pages/my/myInfo'
})
}
}
}
</script>
<style lang="less" scoped>
* {
box-sizing: border-box;
}
.container {
height: 100%;
//background: linear-gradient(180deg, #0174F6 0%, rgba(1, 116, 246, 0) 100%);
display: flex;
flex-direction: column;
position: relative;
padding-top: 60rpx;
background-color: #F3F5F7;
.bodyTopBg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 500rpx;
background-image: url("@/static/bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
.body {
position: relative;
z-index: 10;
flex: 1;
height: 0;
overflow: auto;
padding-bottom: 30rpx;
}
.userInfoBox {
margin: 0 32rpx 40rpx;
display: flex;
column-gap: 20rpx;
align-items: center;
.userInfo {
flex: 1;
width: 0;
.userName {
font-weight: bold;
font-size: 36rpx;
color: #333333;
display: block;
margin-bottom: 16rpx;
}
.userType {
font-size: 24rpx;
color: #0174F6;
display: inline-block;
border-radius: 24rpx 24rpx 24rpx 24rpx;
border: 1rpx solid #0174F6;
padding: 8rpx 16rpx;
}
}
}
.body-card {
border-radius: 6px 6px 6px 6px;
margin: 18px;
padding: 15px;
background: #FFFFFF;
.title {
margin-bottom: 30rpx;
font-weight: bold;
font-size: 32rpx;
color: #113A68;
}
.title-box{
display: flex;
justify-content: space-around;
.title-box-item{
width: 33%;
text-align: center;
.titleDesc {
font-weight: 500;
font-size: 24rpx;
color: #858BA0;
}
.titleNumber{
font-weight: 500;
font-size: 40rpx;
color: #333333;
margin: 4px;
}
.titleImg{
width: 48rpx;
height: 48rpx;
}
}
}
}
.todoListBox {
margin: 40rpx 32rpx;
.title {
margin-bottom: 30rpx;
font-weight: bold;
font-size: 32rpx;
color: #113A68;
.titleDesc {
margin-left: 20rpx;
font-weight: 500;
font-size: 24rpx;
color: #858BA0;
}
.titleCount {
color: #0174F6;
}
}
.todoList {
display: flex;
flex-direction: column;
row-gap: 20rpx;
}
}
.body-top-banner {
text-align: center;
}
.banner {
margin: 24rpx 0 0;
width: 686rpx;
height: 100%;
border-radius: 12rpx 12rpx 12rpx 12rpx;
background-color: #0174F6;
}
.menus {
margin: 30rpx auto 0;
box-sizing: border-box;
width: 686rpx;
padding: 40rpx 38rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(10, 54, 104, 0.1);
border-radius: 12rpx 12rpx 12rpx 12rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.menu-item {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
row-gap: 22rpx;
font-size: 24rpx;
.menu-icon {
width: 48rpx;
height: 48rpx;
}
}
.info {
width: 686rpx;
margin: 38rpx auto 0;
display: flex;
align-items: center;
column-gap: 20rpx;
.info-icon {
width: 80rpx;
height: 80rpx;
}
.infoList {
flex: 1;
width: 0;
.infoItem {
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 10rpx;
}
.infoIndex {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background-color: #333;
}
.infoText {
flex: 1;
width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 24rpx;
}
}
.more-icon {
width: 24rpx;
height: 24rpx;
}
}
.repairShop {
width: 686rpx;
margin: 38rpx auto 0;
.title {
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
.shopList {
.shopItem {
padding: 30rpx 0;
border-bottom: 1rpx solid #DDDDDD;
display: flex;
align-items: center;
column-gap: 20rpx;
}
.shopImg {
width: 160rpx;
height: 100rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background-color: #999;
}
.shopInfo {
flex: 1;
width: 0;
}
.shopTitle {
font-weight: 500;
font-size: 28rpx;
color: #333333;
margin-bottom: 20rpx;
}
.shopDetail {
display: flex;
align-items: center;
font-size: 24rpx;
color: #666666;
column-gap: 10rpx;
}
.shopAddress {
flex: 1;
width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.line {
width: 2rpx;
height: 24rpx;
background-color: #858BA0;
}
.shopDistance {
flex-shrink: 0;
}
}
}
}
</style>