dma-work-h5/src/views/appDir/appWorkOrder.vue
2026-04-08 09:51:49 +08:00

197 lines
6.4 KiB
Vue

<template>
<div ref="scrollDistance" class="ui-appWorkOrder" @scroll="handleScroll">
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" @load="getList">
<div v-if="loadingState && list.length == 0">
<img class="ui-no-data-icon" src="https://image.fulllinkai.com/202306/07/247d8ae6b90334457d1b39129cd5c490.png" alt="" />
<div class="color6 font_30 text-center">暂无工单</div>
</div>
<div v-else>
<div v-for="(item, index) in list" :key="index" class="ui-work-order-box">
<div class="ui-work-order-item">
<div class="f-fbc">
<div class="color3 font_26">工单号:{{ item.work_order }}</div>
<div v-if="item.status == 0" class="font_26 f-fcc colorTheme">已提交</div>
<div v-else-if="item.status == 1" class="font_26 f-fcc color3">处理中</div>
<div v-else-if="item.status == 2" class="font_26 f-fcc colorTheme">已处理</div>
<div v-else class="font_26 f-fcc colorPrice">已取消</div>
</div>
<div class="ui-line-between"></div>
<div class="ui-container">
<div class="font_28 color3 bold">工单说明</div>
<div class="ui-explain-text font_28 color3">{{ item.desc }}</div>
<div v-if="item.images && item.images.length > 0" class="ui-explain-pic-box f-fcl">
<img v-for="(itemV2, indexV2) in item.images" :key="indexV2" class="ui-explain-pic" :src="itemV2" alt="" @click="ImagePreview(item.images, indexV2)" />
</div>
<div v-if="item.deal_remark">
<div class="font_28 color3 bold ui-pt-40">解决方案</div>
<div class="ui-explain-text font_28 color3">{{ item.deal_remark }}</div>
<div v-if="item.deal_images && item.deal_images.length > 0" class="ui-explain-pic-box f-fcl">
<img v-for="(itemV2, indexV2) in item.deal_images" :key="indexV2" class="ui-explain-pic" :src="itemV2" alt="" @click="ImagePreview(item.deal_images, indexV2)" />
</div>
</div>
</div>
</div>
</div>
<div v-if="noMore" class="ui-no-more font_24 color6 text-center">我也是有底线的</div>
</div>
<div class="ui-add-btn f-fcc colorF font_30 bold" @click="jumpPath('appAddWorkOrder')">添加工单</div>
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, onActivated } from 'vue';
import { useUserStore } from '@/store/modules/user';
import weChat from '@/utils/weChat';
import router from '@/router';
defineOptions({ name: 'AppWorkOrder' });
const userStore = useUserStore() as any; // pinia状态缓存数据
const loadingState = ref<any>(false); // 页面数据加载完成判断
const list = ref<any[]>([]); // 数据存储
const noMore = ref(false); // 没有更多数据
const refreshing = ref(false); // 上拉刷新false表示加载完成
const finished = ref(false); // true表示数据全部加载完成
const loading = ref(false); // false表示数据加载完成
const page = ref(1); // 数据分页
const scrollValue = ref(0); // 记录页面列表的滚动距离
const scrollDistance = ref<any>(null);
// 获取工单列表
const getList = () => {
weChat({ url: `/h5/get/work/order?page=${page.value}&chat_id=${userStore.chatId}`, method: 'get' })
.then((res) => {
const result = res.data;
if (list.value.length === 0 || page.value === 1) {
list.value = result.data;
} else if (list.value.length >= 15) {
result.data.forEach((item) => {
list.value.push(item);
});
}
refreshing.value = false;
loading.value = false;
if (list.value.length < 15 || result.data.length < 15) {
finished.value = true;
noMore.value = true;
}
loadingState.value = true;
page.value++;
})
.catch((err) => {
loadingState.value = true;
console.log(err);
});
};
// 上拉初始化数据
const onRefresh = () => {
page.value = 1;
noMore.value = false;
finished.value = false;
loading.value = true;
getList();
};
const jumpPath = (url) => {
router.push({
name: url,
});
};
// 监听页面滚动距离
const handleScroll = (event) => {
scrollValue.value = event.target.scrollTop;
};
onActivated(() => {
let route = router.currentRoute.value.query;
// 提交工单后重新请求接口
if (route.state) {
onRefresh();
} else {
// 赋值离开时的滚动距离
scrollDistance.value.scrollTop = scrollValue.value;
}
});
onMounted(() => {});
</script>
<style lang="scss" scoped>
.ui-appWorkOrder {
background: #f8f8f8;
overflow-y: auto;
height: 100vh;
}
.ui-work-order-box {
margin: px2rem(24) px2rem(30) px2rem(30) px2rem(30);
padding: px2rem(30);
background: #ffffff;
border-radius: px2rem(24);
.ui-work-order-item {
background: #ffffff;
border-radius: px2rem(24);
.ui-line-between {
width: 100%;
height: px2rem(2);
background: #f8f8f8;
margin-top: px2rem(24);
}
.ui-container {
padding-top: px2rem(30);
.ui-explain-text {
white-space: pre-wrap;
word-wrap: break-word;
word-break: normal;
padding-top: px2rem(16);
}
.ui-explain-pic-box {
flex-flow: wrap;
.ui-explain-pic {
width: px2rem(140);
height: px2rem(140);
display: block;
object-fit: cover;
object-position: center;
margin-right: px2rem(16);
margin-top: px2rem(16);
border-radius: px2rem(12);
}
}
}
}
}
.ui-no-data-icon {
width: px2rem(270);
height: px2rem(200);
display: block;
margin: 24vh auto px2rem(20) auto;
}
.ui-no-more {
padding: px2rem(20) px2rem(20) px2rem(220) px2rem(20);
}
.ui-add-btn {
position: fixed;
bottom: px2rem(80);
left: 50%;
transform: translateX(-50%);
width: px2rem(560);
height: px2rem(80);
background: #5ac7a0;
border-radius: px2rem(40);
}
</style>