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.
683 lines
16 KiB
683 lines
16 KiB
<template> |
|
<BasicContainer :option="option"> |
|
<template #body> |
|
<view class="main" :style="{'min-height': details.scrollheight}"> |
|
<view class="flex1"> |
|
<view class="pd20 flex-c-sb"> |
|
<view class="fwb"> |
|
预计完成时间 |
|
</view> |
|
|
|
<view class="flex-c-c" @click="details.showTime = true"> |
|
<text class="mr10" style=""> |
|
{{details.form.estimated_finish_time || '请选择时间'}} |
|
</text> |
|
|
|
<u-icon name="arrow-right" size="36"></u-icon> |
|
</view> |
|
</view> |
|
|
|
<view class="pd20 flex-c-sb" @click="()=> handleChooseWork('item')"> |
|
<view class="fwb"> |
|
项目组 |
|
</view> |
|
|
|
<view class="flex-c-c"> |
|
<text class="mr10" style=""> |
|
{{details.form.item_name || '请选择'}} |
|
</text> |
|
|
|
<u-icon name="arrow-right" size="36"></u-icon> |
|
</view> |
|
</view> |
|
|
|
<view class="pd20 flex-c-sb"> |
|
<view class="fwb"> |
|
工长 |
|
</view> |
|
|
|
<view class="flex-c-c"> |
|
<text class="mr10" style=""> |
|
{{details.form.work_user_captain}} |
|
</text> |
|
|
|
<!-- <u-icon name="arrow-right" size="36"></u-icon> --> |
|
</view> |
|
</view> |
|
|
|
<view class="pd20 flex" @click="handleChooseInstall"> |
|
<view class="fwb"> |
|
安装人员 |
|
</view> |
|
|
|
<template v-if="details.chooseInstallList.length > 0"> |
|
<view class="input_box"> |
|
<block v-for="item in details.chooseInstallList"> |
|
<view class="input_box_item pd20 flex"> |
|
<text class="flex1"> |
|
{{item.name}} |
|
</text> |
|
|
|
<view @click.stop="()=> handleChooseInstallItem(item)" class="remove flex"> |
|
<u-icon name="trash" color="#f00" size="36"></u-icon> |
|
|
|
<text class="ml10"> |
|
|
|
移除 |
|
</text> |
|
</view> |
|
</view> |
|
</block> |
|
</view> |
|
</template> |
|
<template v-else> |
|
<view class="flex-c-sb flex1"> |
|
<view class=""></view> |
|
<view class="align-center"> |
|
<text class="mr10" style=""> |
|
请选择 |
|
</text> |
|
|
|
<u-icon name="arrow-right" size="36"></u-icon> |
|
</view> |
|
</view> |
|
</template> |
|
</view> |
|
</view> |
|
|
|
<view class="flex-c-c btn_conatiner mt20"> |
|
<view class="btn mr40" @click="handleback"> |
|
关 闭 |
|
</view> |
|
|
|
<view class="btn mr40 errBtn" @click="handleTurnDown" v-if="details.pageType === 'installSales'"> |
|
驳 回 |
|
</view> |
|
|
|
<view class="btn subBtn" @click="handleAssignATask"> |
|
指 派 |
|
</view> |
|
</view> |
|
</view> |
|
|
|
</template> |
|
|
|
|
|
</BasicContainer> |
|
|
|
<l-calendar v-model:value="details.showTime" :isRange="false" @hide='showCalendar' @change="onConfirm"></l-calendar> |
|
|
|
<tips ref="tip" /> |
|
|
|
<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.pickerArr" :key="index"> |
|
{{ item.label }} |
|
</view> |
|
</picker-view-column> |
|
</picker-view> |
|
</template> |
|
</MyDrawer> |
|
|
|
<MyDrawer ref="myDrawerByChooseItem"> |
|
<template #head> |
|
<view class="header_search flex-c-c"> |
|
<view class="input flex1"> |
|
<MyInput clearable v-model="details.searchText" placeholder="请输入安装人员名称" /> |
|
</view> |
|
|
|
<view class="header_search_btn flex-c-c" @click="handleSearch"> |
|
搜索 |
|
</view> |
|
</view> |
|
|
|
<view class="flex pl20"> |
|
<view class="btn subBtn mr20" |
|
@click="()=> details.chooseInstallList = [...new Set([...details.chooseInstallList,...details.renderInstallList])]"> |
|
全选 |
|
</view> |
|
|
|
<view class="btn" @click="() => details.chooseInstallList = []"> |
|
清空 |
|
</view> |
|
</view> |
|
</template> |
|
|
|
<template #content> |
|
<view class="flex-c-sb flex-wrap search_list"> |
|
<block v-for="item in details.renderInstallList"> |
|
<view @click="()=> handleChooseInstallItem(item)" |
|
:class="{'search_list_item': true, 'mb20': true, 'active': details.chooseInstallList.includes(item)}"> |
|
{{item.name}} |
|
</view> |
|
</block> |
|
</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, getCommonGetItemData, getCneterSubordinates, postInstallSalesDesignate, postInstallDesignate } from '@/api/user.js' |
|
|
|
// 组件实例 |
|
const tip = ref(null) |
|
const myDrawerByTime = ref() |
|
const myDrawerByChooseItem = ref() |
|
|
|
const option = reactive({ |
|
// 标题 |
|
title: '指派', |
|
// 下拉刷新回调函数 |
|
async pullDownRefreshInitPage() { |
|
|
|
return null |
|
}, |
|
// 触底加载回到函数 |
|
reachBottomInitPage: async () => { return null }, |
|
haveData: true, |
|
isEnd: false, |
|
pageLoading: false |
|
}) |
|
|
|
const details = reactive({ |
|
/** 列表容器高度 */ |
|
scrollheight: '60vh', |
|
/** picker被选中的索引位置 */ |
|
value: [0], |
|
/** picker行高度 */ |
|
indicatorStyle: `height: 40px;`, |
|
/** 当前picker使用的数组 */ |
|
pickerArr: [], |
|
/** 项目组 */ |
|
itemArr: [], |
|
visible: false, |
|
pageType: 'install' as 'install' | 'installSales', |
|
/** 渲染数据 */ |
|
renderData: [], |
|
/** 输入框搜索的值 */ |
|
searchText: '', |
|
/** 安装人员 */ |
|
installItemList: [], |
|
/** 渲染的安装人员 */ |
|
renderInstallList: [], |
|
/** 被选中的安装人员 */ |
|
chooseInstallList: [], |
|
showTime: false, |
|
form: { |
|
// 预计时间 |
|
estimated_finish_time: '', |
|
// 项目组 |
|
item_id: '', |
|
item_name: '', |
|
// 工长 |
|
work_user_captain: '', |
|
work_user_captain_id: '', |
|
// 安装ID |
|
install_id: '', |
|
// 售后ID |
|
install_sales_id: '', |
|
// install_sales_work_id, 修改指派时传入 |
|
id: '' |
|
} |
|
}) |
|
|
|
onShow(async () => { |
|
await nextTick() |
|
details.scrollheight = await utils.getViewDistanceFormTop('.main') |
|
}) |
|
onLoad((e) => { |
|
details.form.install_sales_id = e.id |
|
details.form.install_id = e.id |
|
details.pageType = e.pageType |
|
}) |
|
|
|
onUnload(() => { |
|
uni.removeStorageSync('installWork') |
|
}) |
|
|
|
// 显示时间 |
|
function showCalendar() { |
|
details.showTime = !details.showTime |
|
} |
|
|
|
// 选择时间 |
|
function onConfirm(e : any) { |
|
console.log(e); |
|
details.form.estimated_finish_time = e.result |
|
} |
|
|
|
// 初始化设置时间 |
|
|
|
/** 获取页面数据 */ |
|
const initPage = async () => { |
|
try { |
|
option.pageLoading = true |
|
|
|
await Promise.all([ |
|
initItem(), |
|
initItemData() |
|
]) |
|
|
|
const _info = (uni.getStorageSync('installWork') || {}) |
|
details.form.estimated_finish_time = _info.estimated_finish_time |
|
details.form.work_user_captain = _info.work_user_captain |
|
details.form.work_user_captain_id = _info.work_user_captain_id |
|
details.form.item_id = _info.item_id |
|
details.form.id = _info.id |
|
details.chooseInstallList = [] |
|
|
|
for (let i = 0; i < details.itemArr.length; i++) { |
|
const _value = details.itemArr[i] |
|
|
|
if (_value.id !== details.form.item_id) continue |
|
details.form.item_name = _value.label |
|
details.installItemList = _value.user |
|
break |
|
} |
|
|
|
for (let i = 0; i < details.installItemList.length; i++) { |
|
const _value = details.installItemList[i] |
|
|
|
if (!_info.work_user_ids.includes(_value.id)) continue |
|
details.chooseInstallList.push(_value) |
|
} |
|
|
|
console.log('_info :>> ', _info); |
|
} catch (err) { |
|
console.log('err :>> ', err) |
|
//TODO handle the exception |
|
} finally { |
|
option.pageLoading = false |
|
} |
|
} |
|
|
|
/** 获取项目组 */ |
|
const initItem = async () => { |
|
const res = await getCommonGetItemData({}) |
|
const { code, data } = res |
|
if (code !== 200) return |
|
details.itemArr = data || [] |
|
} |
|
|
|
/** 获取下属 */ |
|
const initItemData = async () => { |
|
// const res = await getCneterSubordinates({}) |
|
// const { code, data } = res |
|
// if (code !== 200) return |
|
// details.installItemList = data || [] |
|
// details.searchText = '' |
|
// handleSearch() |
|
} |
|
|
|
|
|
|
|
initPage() |
|
|
|
/** picker切换时执行 -- 时间 */ |
|
const bindChangeByTime = function (e) { |
|
details.value = e.detail.value |
|
} |
|
|
|
/** 选择项目组 */ |
|
const handleChooseWork = (key : 'work_user_captain' | 'item') => { |
|
const _value = details.form[key + '_id'] |
|
|
|
console.log('_value :>> ', _value); |
|
|
|
details.pickerArr = details[key + 'Arr'] |
|
|
|
console.log('details.pickerArr :>> ', details.pickerArr); |
|
details.value = [0] |
|
|
|
if (_value) { |
|
for (let i = 0; i < details.pickerArr.length; i++) { |
|
const item = details.pickerArr[i] |
|
if (item.value !== _value) continue |
|
|
|
details.value = [i] |
|
break |
|
} |
|
} |
|
details.visible = true |
|
|
|
console.log('details.value :>> ', details.value); |
|
|
|
myDrawerByTime.value.setDetails({ |
|
showPopUp: true, |
|
title: '选择项目组', |
|
async success() { |
|
try { |
|
const _value = details.pickerArr[details.value[0]] |
|
|
|
if (details.form[key + '_id'] === _value.value) return |
|
|
|
|
|
details.chooseInstallList = [] |
|
details.form[key + '_id'] = _value.value |
|
details.form[key + '_name'] = _value.label |
|
|
|
details.form.work_user_captain = '' |
|
details.form.work_user_captain_id = '' |
|
details.installItemList = _value.user || [] |
|
|
|
for (let i = 0; i < _value.user.length; i++) { |
|
const item = _value.user[i] |
|
|
|
if (!item.role.includes(2)) continue |
|
details.form.work_user_captain = item.name |
|
details.form.work_user_captain_id = item.id |
|
|
|
break |
|
} |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
myDrawerByTime.value.details.showPopUp = false |
|
await nextTick() |
|
details.visible = false |
|
} |
|
}, |
|
async close() { |
|
myDrawerByTime.value.details.showPopUp = false |
|
|
|
await nextTick() |
|
details.visible = false |
|
} |
|
}) |
|
} |
|
|
|
/** 开启选择弹窗 -- 安装人员 */ |
|
const handleChooseInstall = () => { |
|
handleSearch() |
|
|
|
myDrawerByChooseItem.value.setDetails({ |
|
showPopUp: true, |
|
height: '50vh', |
|
isShowButton: false |
|
}) |
|
} |
|
|
|
/** 选择安装人员 */ |
|
const handleChooseInstallItem = (item) => { |
|
for (let i = 0; i < details.chooseInstallList.length; i++) { |
|
const _value = details.chooseInstallList[i] |
|
|
|
if (_value.id === item.id) return details.chooseInstallList.splice(i, 1) |
|
} |
|
|
|
details.chooseInstallList.push(item) |
|
console.log('details.chooseInstallList :>> ', details.chooseInstallList); |
|
} |
|
|
|
/** 搜索 */ |
|
const handleSearch = () => { |
|
if (!details.searchText) details.renderInstallList = details.installItemList |
|
|
|
const _reg = new RegExp('^' + details.searchText) |
|
|
|
const _arr = [] |
|
|
|
for (let i = 0; i < details.installItemList.length; i++) { |
|
const _value = details.installItemList[i] |
|
|
|
if (!_reg.test(_value.name)) continue |
|
_arr.push(_value) |
|
} |
|
|
|
details.renderInstallList = _arr |
|
} |
|
|
|
/** 返回 */ |
|
const handleback = () => { |
|
uni.navigateBack() |
|
} |
|
|
|
/** 驳回 */ |
|
const handleTurnDown = () => { |
|
console.log('tip.value :>> ', tip.value); |
|
|
|
tip.value.setdetails({ |
|
title: '提示', |
|
isshow: true, |
|
content: '确认驳回', |
|
async success() { |
|
try { |
|
option.pageLoading = true |
|
|
|
const submitData = { |
|
result: 2, |
|
install_sales_id: details.form.install_sales_id, |
|
} |
|
|
|
const res = await postInstallSalesDesignate(submitData) |
|
|
|
const { code, data } = res |
|
|
|
if (code !== 200) return |
|
handleback() |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
tip.value.setisshow(false) |
|
option.pageLoading = false |
|
} |
|
} |
|
}) |
|
} |
|
|
|
/** 指派 */ |
|
const handleAssignATask = () => { |
|
if (!details.form.estimated_finish_time) return utils.handleToast('请选择时间') |
|
if (!details.form.item_id) return utils.handleToast('请选择项目组') |
|
if (!details.form.work_user_captain_id) return utils.handleToast('该项目组无工长,请切换项目组或维护') |
|
if (details.chooseInstallList.length === 0) return utils.handleToast('请选择安装人员') |
|
|
|
console.log('details.form :>> ', details.form); |
|
|
|
tip.value.setdetails({ |
|
title: '提示', |
|
isshow: true, |
|
content: '确认指派', |
|
async success() { |
|
try { |
|
option.pageLoading = true |
|
|
|
const submitData = { |
|
result: 1, |
|
// install_sales_id: details.form.install_sales_id, |
|
item_id: details.form.item_id, |
|
estimated_finish_time: details.form.estimated_finish_time, |
|
work_user_captain: details.form.work_user_captain, |
|
work_user_captain_id: details.form.work_user_captain_id, |
|
work_users: details.chooseInstallList.map(val => val.name).join(','), |
|
work_user_ids: details.chooseInstallList.map(val => val.id) |
|
} |
|
|
|
|
|
|
|
details.form.id && (submitData.id = details.form.id) |
|
|
|
details.pageType === 'install' ? (submitData.install_id = details.form.install_id) : (submitData.install_sales_id = details.form.install_sales_id) |
|
|
|
const res = details.pageType === 'install' ? await postInstallDesignate(submitData) : await postInstallSalesDesignate(submitData) |
|
|
|
const { code, data } = res |
|
|
|
if (code !== 200) return |
|
handleback() |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
tip.value.setisshow(false) |
|
option.pageLoading = false |
|
} |
|
} |
|
}) |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
@import url('@/utils/style/common.scss'); |
|
|
|
.main { |
|
position: relative; |
|
background-color: #fff; |
|
display: flex; |
|
flex-direction: column; |
|
|
|
// 安装人员 |
|
.input_box { |
|
flex: 1; |
|
text-align: right; |
|
margin-left: 20upx; |
|
border-radius: 5upx; |
|
|
|
.input_box_item { |
|
background: #f5f5f5; |
|
margin-bottom: 10upx; |
|
} |
|
|
|
.remove { |
|
border-left: 4upx solid; |
|
color: var(--errColor); |
|
margin-left: 20upx; |
|
padding: 0 10upx; |
|
} |
|
} |
|
} |
|
|
|
.header_search { |
|
padding: 20upx; |
|
height: 80upx; |
|
|
|
.header_search_btn { |
|
// height: 60upx; |
|
color: #fff; |
|
height: 100%; |
|
padding: 0 60upx; |
|
background: var(--subjectColor); |
|
border-radius: 10upx; |
|
} |
|
|
|
.input { |
|
background-color: #f5f5f5; |
|
margin-right: 20upx; |
|
height: 100%; |
|
font-size: 1rem; |
|
} |
|
} |
|
|
|
// 安装人员 |
|
.search_list { |
|
.search_list_item { |
|
width: 40%; |
|
padding: 20upx; |
|
background: #f5f5f5; |
|
box-sizing: border-box; |
|
position: relative; |
|
margin: 0 20upx; |
|
margin-bottom: 30upx; |
|
transition: all 0.3s; |
|
border-radius: 10upx; |
|
word-break: break-all; |
|
|
|
$width: 20upx; |
|
$borderWidth: 4upx; |
|
$activeSizing: calc(100% + 20upx); |
|
|
|
&::before { |
|
position: absolute; |
|
content: ''; |
|
width: $width; |
|
height: $width; |
|
border-top: $borderWidth solid; |
|
border-left: $borderWidth solid; |
|
border-color: var(--subjectColor); |
|
top: -10upx; |
|
left: -10upx; |
|
transition: all 0.3s; |
|
box-sizing: border-box; |
|
// border-top-left-radius: 10upx; |
|
} |
|
|
|
&::after { |
|
position: absolute; |
|
content: ''; |
|
width: $width; |
|
height: $width; |
|
border-bottom: $borderWidth solid; |
|
border-right: $borderWidth solid; |
|
border-color: var(--subjectColor); |
|
bottom: -10upx; |
|
right: -10upx; |
|
transition: all 0.3s; |
|
box-sizing: border-box; |
|
// border-bottom-right-radius: 10upx; |
|
} |
|
|
|
|
|
&.active { |
|
background: var(--subjectColor); |
|
color: #fff; |
|
|
|
&::before { |
|
width: $activeSizing; |
|
height: $activeSizing; |
|
border-radius: 10upx; |
|
} |
|
|
|
&::after { |
|
width: $activeSizing; |
|
height: $activeSizing; |
|
border-radius: 10upx; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// picker样式 |
|
.picker-view { |
|
height: 40vh; |
|
|
|
.item { |
|
text-align: center; |
|
line-height: 40px; |
|
} |
|
} |
|
|
|
.btn_conatiner { |
|
.mr40 { |
|
margin-right: 40upx; |
|
} |
|
|
|
padding-bottom: 60upx; |
|
} |
|
|
|
.btn { |
|
padding: 20upx 60upx; |
|
border-radius: 10upx; |
|
background-color: #f5f5f5; |
|
color: #000; |
|
|
|
&.errBtn { |
|
color: #fff; |
|
background-color: var(--errColor); |
|
} |
|
|
|
&.subBtn { |
|
color: #fff; |
|
background: var(--subjectColor); |
|
} |
|
} |
|
</style> |