货无忧安装平台
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

<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>