货无忧安装平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

763 lines
16 KiB

<template>
<BasicContainer :option="option">
<template #body>
<view class="main">
<view class="tabbar flex">
<view :class="{'tabbar_item': true, 'flex-c-c': true, 'flex1': true, active: details.tabbarCode === 0}"
@click="()=> handleClickTabbar(0)">
</view>
<view :class="{'tabbar_item': true, 'flex-c-c': true, 'flex1': true, active: details.tabbarCode === 1}"
@click="()=> handleClickTabbar(1)">
</view>
<view class="tabbar_active flex-c-c" :style="`transform: translateX(${details.tabbarCode * 100 +'%'})`">
<view class="line">
</view>
</view>
</view>
<view class="flex-c-sa search_row">
<!-- 大区 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
大区
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 时间 -->
<!-- <view class="flex1 flex-c-c" @click="() => handleShowChooseTime('month')">
<text class="mr10">
{{ details.time.year + '.' + details.time.month }}
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view> -->
<!-- 项目组 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
项目组
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 名称 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
名称
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 筛选 -->
<view class="flex1 flex-c-c" @click="()=> handleShowMoreSearch(true)">
<text class="mr10">
筛选
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
</view>
<scroll-view class="scvmabx" :style="{height: details.scrollheight}" @scrolltolower="()=>{}" scroll-y="true"
@touchmove.stop>
<view class="list_container">
<!-- 工人 -->
<block v-for="(item, index) in details.renderData" :key="item.id">
<template v-if="details.tabbarCode === 0">
<view :class="{'box': true, first: false, second: true, third: false}"
@click="()=> handleGoDetails(item)">
<view class="title flex-c-sb">
<view class="">预计<text>{{item.estimated_finish_time}}</text>完成</view>
<view class="tip">{{item.status_map}}</view>
</view>
<view class="info">
<view class="">客户联系人:{{item.name}}</view>
<view class="mt20">指派人:{{item.work_users}}</view>
<view class="mt20">安装单号:{{item.no}}</view>
<view class="mt20 flex-c-sb">
<text>
任务类型:{{item.typeName}}
</text>
<text>
状态:{{item.statusName}}
</text>
</view>
</view>
</view>
</template>
</block>
</view>
</scroll-view>
</view>
</template>
</BasicContainer>
<!-- 蒙层 -->
<view :class="details.maskClassName">
<view class="mask_container">
<view class="flex-c-sa search_row">
<!-- 大区 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
大区
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 时间 -->
<!-- <view class="flex1 flex-c-c" @click="() => handleShowChooseTime('month')">
<text class="mr10">
{{ details.time.year + '.' + details.time.month }}
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view> -->
<!-- 项目组 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
项目组
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 名称 -->
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
名称
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<!-- 筛选 -->
<view class="flex1 flex-c-c" @click="()=> handleShowMoreSearch(false)">
<text class="mr10">
筛选
</text>
<u-icon name="arrow-up-fill" color="#000" size="20"></u-icon>
</view>
</view>
<view class="mask_row flex-c-sb">
<view class="">
城市
</view>
<view class="flex">
<view class="flex-c-c mr20" @click="() => handleShowChooseTime('year')">
<text class="mr10">
省份
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
<view class="flex1 flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
</view>
</view>
<view class="mask_row flex-c-sb">
<view class="">
类型
</view>
<view class="flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
省份
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
</view>
<view class="mask_row flex-c-sb">
<view class="">
装态
</view>
<view class="flex-c-c" @click="() => handleShowChooseTime('year')">
<text class="mr10">
省份
</text>
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon>
</view>
</view>
<view class="flex button_row">
<view class="flex-c-c mr20" @click="()=>handleShowMoreSearch(false)">
关 闭
</view>
<view class="flex-c-c subBtn">
确 认
</view>
</view>
</view>
</view>
<MyDrawer ref="myDrawerByTime">
<template #content>
<picker-view v-if="details.visible" :indicator-style="details.indicatorStyle" :immediate-change="true"
:value="details.value" @change="bindChangeByTime" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item, index) in details.years" :key="index">
{{ item }}
</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item, index) in details.months" :key="index">
{{ item }}
</view>
</picker-view-column>
</picker-view>
</template>
</MyDrawer>
</template>
<script lang="ts" setup>
import { onLoad, onShow, onHide, onUnload, onPullDownRefresh } from '@dcloudio/uni-app'
// import Tabber from '@/compoment/Tabber/Tabber.vue'
import { nextTick, ref, reactive } from 'vue'
import utils from '@/utils/utils'
import { getMasterTaskList, getCenterInstallSalesTaskList, getCneterInstallTaskList } from '@/api/user.js'
// 组件实例
const tip = ref(null)
const calendar = ref()
const myDrawerByTime = ref()
const option = reactive({
// 标题
title: '待审核',
// 下拉刷新回调函数
async pullDownRefreshInitPage() {
return null
},
// 触底加载回到函数
reachBottomInitPage: async () => { return null },
haveData: true,
isEnd: false,
pageLoading: true
})
const details = reactive({
/** 列表容器高度 */
scrollheight: '60vh',
/** picker被选中的索引位置 */
value: [3],
/** picker行高度 */
indicatorStyle: `height: 40px;`,
/** 年 */
years: [],
/** 月 */
months: [],
/** 当前picker使用的数组 */
pickerArr: [],
/** 当前时间 */
time: {
year: '',
month: '',
},
visible: false,
pageType: 2,
/** 渲染数据 */
renderData: [],
/** 输入框搜索的值 */
searchText: '',
/** 蒙层类名 */
maskClassName: {
mask: true,
show: false,
done: false
},
tabbarCode: 0,
/** 类型 */
typeArr: [
{ label: '安装单', value: '0' },
{ label: '合同安装单', value: '1' },
{ label: '转安装单', value: '2' },
{ label: '维修', value: '3' },
],
/** 状态 */
statusArr: [
{ label: '待报价', value: '1' },
{ label: '待指派', value: '2' },
{ label: '已指派', value: '3' },
{ label: '服务中', value: '4' },
{ label: '已完成', value: '5' },
{ label: '验收', value: '6' },
{ label: '已完结', value: '7' },
{ label: '已关闭', value: '8' },
],
})
onShow(async () => {
if (details.maskClassName.done) details.maskClassName.done = false
await nextTick()
details.scrollheight = await utils.getViewDistanceFormTop('.scvmabx')
})
onLoad(() => {
})
// 初始化设置时间
const initTime = () => {
// 获取当前时间
const now = new Date()
// 获取当前年份
const year = now.getFullYear()
for (let index = 1990; index <= year + 1; index++) {
details.years.push(index + '')
}
// 获取当前月份
const month = now.getMonth() + 1
for (let index = 1; index <= 12; index++) {
details.months.push(index < 10 ? '0' + index : index + '')
}
// 设置默认时间
details.time.year = year + ''
details.time.month = month < 10 ? '0' + month : '' + month
}
initTime()
/** 去详情 */
const handleGoDetails = (item) => {
const jupPatch =
details.tabbarCode === 1
? // 任务详情
'/pagesHome/pages/taskDetails/taskDetails?pageInfo=' + JSON.stringify(item)
: // 异常详情
'/pagesHome/pages/afterSalesDetails/afterSalesDetails?pageInfo=' + JSON.stringify(item)
uni.navigateTo({
url: jupPatch,
})
}
/** 转译 */
const translationValue = (key, value) => {
let _value = {}
const _arr = details[key + 'Arr']
for (let i = 0; i < _arr.length; i++) {
const item = _arr[i]
if ((value + '') !== item.value) continue
_value = item
break
}
return _value
}
/** 获取安装任务 */
const handleGetTaskList = async (submitData) => {
const res = await getCneterInstallTaskList(submitData)
const { code, data } = res
if (code !== 200) return
details.renderData = data || []
for (let i = 0; i < details.renderData.length; i++) {
const _value = details.renderData[i]
const { type, status } = _value
// if (type)
// 转译类型
const _itemType = translationValue('type', type)
_value.typeName = _itemType.label || '暂无'
const _itemStatus = translationValue('status', status)
_value.statusName = _itemStatus.label || '暂无'
}
}
/** 获取下属列表 */
const handleGetSubordinateList = async (submitData) => {
const res = await getCenterInstallSalesTaskList(submitData)
const { code, data } = res
if (code !== 200) return
details.renderData = data || []
for (let i = 0; i < details.renderData.length; i++) {
const _value = details.renderData[i]
const { type, status } = _value
// if (type)
// 转译类型
const _itemType = translationValue('type', type)
_value.typeName = _itemType.label || '暂无'
const _itemStatus = translationValue('status', status)
_value.statusName = _itemStatus.label || '暂无'
}
}
/** 获取页面数据 */
const initPage = async () => {
try {
option.pageLoading = true
details.renderData = []
const submitData = {
status: 7,
month: details.time.year + '-' + details.time.month,
}
// const res = await getMasterTaskList(submitData)
details.tabbarCode === 0 ? await handleGetTaskList(submitData) : await handleGetSubordinateList(submitData)
// const { code, data } = res
// if (code !== 200) return
// details.renderData = data || []
} catch (err) {
console.log('err :>> ', err)
//TODO handle the exception
} finally {
option.pageLoading = false
}
}
initPage()
/** tabbar点击事件 */
const handleClickTabbar = (code : number) => {
details.tabbarCode = code
initPage()
}
/** picker切换时执行 -- 时间 */
const bindChangeByTime = function (e) {
details.value = e.detail.value
}
/** 选择时间 */
const handleShowChooseTime = (type : 'year' | 'month' | 'day') => {
details.pickerArr = details[type + 's']
const _time = details.time[type]
console.log('details.time.year :>> ', details.time.year);
const { year, month } = details.time
for (let i = 0; i < details.years.length; i++) {
const value = details.years[i]
if (value !== year) continue
details.value[0] = i
break
}
for (let i = 0; i < details.months.length; i++) {
const value = details.months[i]
if (value !== month) continue
details.value[1] = i
break
}
details.visible = true
console.log('details.value :>> ', details.value);
myDrawerByTime.value.setDetails({
showPopUp: true,
title: '选择时间',
async success() {
details.time.year = details.years[details.value[0]]
details.time.month = details.months[details.value[1]]
myDrawerByTime.value.details.showPopUp = false
initPage()
await nextTick()
details.visible = false
},
async close() {
myDrawerByTime.value.details.showPopUp = false
await nextTick()
details.visible = false
}
})
}
/** 显示更多筛选搜索条件 */
const handleShowMoreSearch = (_flag : boolean) => {
if (_flag) {
details.maskClassName.show = true
details.maskClassName.done = false
}
else {
details.maskClassName.show = false
details.maskClassName.done = true
}
}
</script>
<style lang="scss" scoped>
@import url('@/utils/style/common.scss');
.header_title {
background-color: var(--subjectColor);
color: #fff;
height: 100upx;
}
// tabbar
.tabbar {
height: 100upx;
background-color: #fff;
position: relative;
$tabbarTime: 0.3s;
font-size: 1rem;
.tabbar_item {
font-weight: bold;
color: #000;
transition: all $tabbarTime;
&.active {
color: var(--subjectColor);
}
}
.tabbar_active {
height: 8upx;
position: absolute;
width: 50%;
bottom: 0;
transition: all $tabbarTime;
&::after {
content: '';
display: block;
width: 2rem;
height: 100%;
background-color: var(--subjectColor);
border-radius: 4upx;
}
}
}
// 时间行
.search_row {
background: #F5F5F6;
// border-bottom: 2upx solid #eee;
&>view {
padding: 20upx 0;
}
}
.main {
font-size: 0.9rem;
position: relative;
// padding: 20upx;
// 任务列表
.list_container {
position: relative;
color: #000;
z-index: 10;
// padding: 20upx;
// 工人样式
.box {
border-radius: 10upx;
overflow: hidden;
margin: 20upx;
&:last-child {
margin-bottom: 0;
}
.title {
padding: 20upx 20upx;
background: linear-gradient(90deg, #d8f7f2 0%, #fff 100%);
font-weight: 600;
.tip {
font-weight: normal;
color: #3ad8bc;
}
}
.info {
padding: 30upx 20upx;
background-color: #fff;
font-size: 0.9rem;
}
// 待签收
&.first {
.title {
background: linear-gradient(90deg, #fee8d0 0%, #fff 100%);
.tip {
color: var(--subjectColor);
}
}
}
// 服务中
&.second {
.title {
background: linear-gradient(90deg, #cde7fc 0%, #fff 100%);
.tip {
color: var(--primaryColor);
}
}
}
// 已指派
&.third {
.title {
background: linear-gradient(90deg, #d8f7f2 0%, #fff 100%);
.tip {
color: #3ad8bc;
}
}
}
}
}
}
// picker样式
.picker-view {
height: 40vh;
.item {
text-align: center;
line-height: 40px;
}
}
@keyframes ShowMaskAn {
0% {
// display: block;
opacity: 0;
transform: translateY(-100%);
}
40% {
transform: translateY(5%);
opacity: 1;
}
60% {
transform: translateY(-5%);
}
80% {
transform: translateY(1%);
}
100% {
// display: block;
transform: translateY(0%);
}
}
@keyframes DoneMaskAn {
0% {
// display: block;
opacity: 1;
transform: translateY(0%);
}
100% {
// display: block;
opacity: 0;
transform: translateY(-100%);
}
}
// 蒙层
.mask {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
padding-top: 44px;
/* #ifdef MP-WEIXIN */
padding-top: 64px;
/* #endif */
background: rgba(0, 0, 0, 0.5);
font-size: 0.9rem;
z-index: 10;
transform: translate(-100%);
$animationTime: 0.6s;
&.show {
animation: ShowMaskAn 1s forwards;
}
&.done {
animation: DoneMaskAn $animationTime forwards;
}
.mask_container {
background-color: #fff;
// 蒙层行
.mask_row {
padding: 20upx 60upx;
border-bottom: 2upx solid #eee;
}
// 按钮行
.button_row {
padding: 20upx 60upx;
&>view {
height: 80upx;
flex: 1;
border-radius: 40upx;
background-color: #f5f5f6;
&.subBtn {
color: #fff;
background-color: var(--subjectColor);
}
}
}
}
}
</style>