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.
685 lines
15 KiB
685 lines
15 KiB
<template> |
|
<BasicContainer ref="basicContainer" :option="option"> |
|
<template #body> |
|
<view class="main"> |
|
<!-- tabbar --> |
|
<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="search_container"> |
|
<view class="input_container flex-c-sb"> |
|
<view class="first_icon flex-c-c"> |
|
<u-icon name="search" color="#999" size="45"></u-icon> |
|
</view> |
|
|
|
<MyInput type="text" class="flex1 h100" :border="false" v-model="details.searchText" placeholder="请输入" |
|
clearable /> |
|
|
|
<view class="search_text flex-c-c" @click="handleSearch"> |
|
搜 索 |
|
</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()"> |
|
<text class="mr10"> |
|
{{ details.time.year && details.time.month ? 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="() => handleShowChoosePicker('type')"> |
|
<text class="mr10"> |
|
{{ details.form.typeName || '类型'}} |
|
</text> |
|
<u-icon name="arrow-down-fill" color="#000" size="20"></u-icon> |
|
</view> |
|
|
|
<!-- 状态 --> |
|
<view class="flex1 flex-c-c" @click="() => handleShowChoosePicker('status')"> |
|
<text class="mr10"> |
|
{{ details.form.statusName || '状态'}} |
|
</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> |
|
|
|
<!-- 选择弹窗 -- 时间 --> |
|
<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> |
|
|
|
<!-- 选择弹窗 -- 类型 | 状态 --> |
|
<MyDrawer ref="myDrawer"> |
|
<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.pickerArr" :key="index"> |
|
{{ item.label }} |
|
</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 { getCneterInstallTaskList } from '@/api/user.js' |
|
|
|
// 组件实例 |
|
const tip = ref(null) |
|
const myDrawerByTime = ref() |
|
const myDrawer = ref() |
|
const basicContainer = ref() |
|
|
|
const option = reactive({ |
|
// 标题 |
|
title: '下属安装任务', |
|
// 下拉刷新回调函数 |
|
async pullDownRefreshInitPage() { |
|
return await initPage() |
|
}, |
|
// 触底加载回到函数 |
|
reachBottomInitPage: async () => { return null }, |
|
haveData: true, |
|
isEnd: false, |
|
pageLoading: false |
|
}) |
|
|
|
const details = reactive({ |
|
/** 列表容器高度 */ |
|
scrollheight: '60vh', |
|
/** picker被选中的索引位置 */ |
|
value: [3], |
|
/** picker行高度 */ |
|
indicatorStyle: `height: 40px;`, |
|
/** 年 */ |
|
years: [], |
|
/** 月 */ |
|
months: [], |
|
/** 当前picker使用的数组 */ |
|
pickerArr: [], |
|
/** 当前时间 */ |
|
time: { |
|
year: '', |
|
month: '', |
|
}, |
|
form: { |
|
/** 类型 */ |
|
type: '', |
|
typeName: '', |
|
/** 状态 */ |
|
status: '', |
|
statusName: '', |
|
/** 用户ID */ |
|
user_id: '' |
|
}, |
|
/** 类型 */ |
|
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' }, |
|
], |
|
visible: false, |
|
pageType: 2, |
|
/** 渲染数据 */ |
|
renderData: [], |
|
/** 输入框搜索的值 */ |
|
searchText: '', |
|
tabbarCode: 0, |
|
/** 分页参数 */ |
|
page: { |
|
page: 1, |
|
page_size: 20, |
|
total: 0, |
|
} |
|
}) |
|
|
|
onShow(async () => { |
|
await nextTick() |
|
details.scrollheight = await utils.getViewDistanceFormTop('.scvmabx') |
|
basicContainer.value.startPullDownRefresh() |
|
}) |
|
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 : any) => { |
|
const jupPatch = |
|
details.tabbarCode === 0 |
|
? // 任务详情 |
|
'/pagesHome/pages/taskDetails/taskDetails?pageInfo=' + JSON.stringify(item) |
|
: // 异常详情 |
|
'/pagesHome/pages/afterSalesDetails/afterSalesDetails' |
|
|
|
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 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 initPage = async () => { |
|
try { |
|
option.pageLoading = true |
|
|
|
details.renderData = [] |
|
|
|
const submitData : any = { |
|
...details.page, |
|
is_my: details.tabbarCode === 0 ? 1 : 0 |
|
}; |
|
|
|
// 时间 |
|
(details.time.year && details.time.month) && (submitData.month = details.time.year + '-' + details.time.month); |
|
|
|
// 搜索的值 |
|
details.searchText && (submitData.search = details.searchText) |
|
|
|
// 状态 |
|
details.form.status && (submitData.status = details.form.status) |
|
|
|
// 类型 |
|
details.form.type && (submitData.type = details.form.type) |
|
|
|
// 用户ID |
|
details.form.user_id && (submitData.user_id = details.form.user_id) |
|
|
|
details.tabbarCode === 0 ? await handleGetTaskList(submitData) : await handleGetSubordinateList(submitData) |
|
|
|
} 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) { |
|
console.log('e :>> ', e); |
|
details.value = e.detail.value |
|
} |
|
|
|
const handleCloseNode = async (Ref) => { |
|
Ref.value.details.showPopUp = false |
|
await nextTick() |
|
details.visible = false |
|
} |
|
|
|
/** 选择时间 */ |
|
const handleShowChooseTime = async () => { |
|
const { year, month } = details.time |
|
|
|
const now = new Date() |
|
const nowYear = now.getFullYear() |
|
const nowMonth = now.getMonth() + 1 |
|
|
|
const _year = year ? year : nowYear + '' |
|
const _month = month ? month : (nowMonth < 10 ? '0' + nowMonth : '' + nowMonth) |
|
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 = false |
|
await nextTick() |
|
details.visible = true |
|
|
|
|
|
myDrawerByTime.value.setDetails({ |
|
showPopUp: true, |
|
title: '选择时间', |
|
cancelText: '清空', |
|
success() { |
|
details.time.year = details.years[details.value[0]] |
|
details.time.month = details.months[details.value[1]] |
|
handleCloseNode(myDrawerByTime) |
|
initPage() |
|
}, |
|
close() { |
|
details.time.year = '' |
|
details.time.month = '' |
|
handleCloseNode(myDrawerByTime) |
|
initPage() |
|
}, |
|
cancel() { |
|
handleCloseNode(myDrawerByTime) |
|
} |
|
}) |
|
} |
|
|
|
/** 选择状态 | 类型 */ |
|
const handleShowChoosePicker = async (type : 'status' | 'type') => { |
|
const _key = type + 'Arr' |
|
|
|
details.pickerArr = details[_key] |
|
|
|
let index = 0 |
|
|
|
for (let i = 0; i < details.pickerArr.length; i++) { |
|
const _item = details.pickerArr[i] |
|
|
|
if (_item.value !== details.form[type]) continue |
|
index = i |
|
break |
|
} |
|
|
|
details.value = [index] |
|
|
|
console.log('details.value :>> ', details.value); |
|
details.visible = false |
|
await nextTick() |
|
details.visible = true |
|
|
|
myDrawer.value.setDetails({ |
|
showPopUp: true, |
|
title: '选择' + (type === 'type' ? '类型' : '状态'), |
|
cancelText: '清空', |
|
success() { |
|
const _item = details.pickerArr[details.value[0]] |
|
details.form[type] = _item.value |
|
details.form[type + 'Name'] = _item.label |
|
|
|
console.log('details.form :>> ', details.form); |
|
|
|
handleCloseNode(myDrawer) |
|
initPage() |
|
|
|
}, |
|
close() { |
|
details.form[type] = '' |
|
details.form[type + 'Name'] = '' |
|
handleCloseNode(myDrawer) |
|
initPage() |
|
}, |
|
cancel() { |
|
handleCloseNode(myDrawer) |
|
} |
|
}) |
|
} |
|
|
|
/** 搜索 */ |
|
const handleSearch = () => { |
|
// uni.navigateTo({ |
|
// url: '/pagesUser/pages/InstallTaskList/InstallTaskList' |
|
// }) |
|
initPage() |
|
} |
|
</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; |
|
border-bottom: 2upx solid #eee; |
|
|
|
.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: 4rem; |
|
height: 100%; |
|
background-color: var(--subjectColor); |
|
border-radius: 4upx; |
|
} |
|
} |
|
} |
|
|
|
// 顶部搜索 |
|
.search_container { |
|
background: #fff; |
|
padding: 20upx; |
|
|
|
.input_container { |
|
// padding: 20upx 100upx; |
|
background: #F4F6F8; |
|
border-radius: 50upx; |
|
height: 80upx; |
|
|
|
.first_icon { |
|
width: 100upx; |
|
} |
|
|
|
input {} |
|
|
|
.search_text { |
|
width: 150upx; |
|
color: var(--subjectColor); |
|
} |
|
} |
|
} |
|
|
|
// 搜索行 |
|
.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; |
|
} |
|
} |
|
</style> |