|
|
|
<template>
|
|
|
|
<BasicContainer ref="basicContainer" :option="option">
|
|
|
|
<!-- 头部 -->
|
|
|
|
<template #head></template>
|
|
|
|
|
|
|
|
<!-- 主体 -->
|
|
|
|
<template #body>
|
|
|
|
<view class="main">
|
|
|
|
<scroll-view class="scvmabx" :style="{height: details.scrollheight}" @scrolltolower="() => {}"
|
|
|
|
scroll-y="true" @touchmove.stop>
|
|
|
|
<template v-if="details.pageType === 'install'">
|
|
|
|
<block v-for="(item, index) in details.pageArr" :key="item.title">
|
|
|
|
<view :class="{mt20: index !== 0}" v-if="item.list.length > 0">
|
|
|
|
<PullDownBox ref="imgPullDownRefList">
|
|
|
|
<template #title>
|
|
|
|
<view class="server_list_container_header">
|
|
|
|
<view class="row flex-c-sb border-none">
|
|
|
|
<view class="title">
|
|
|
|
{{ item.title }}
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template #content>
|
|
|
|
<view class="server_list_container_info">
|
|
|
|
<block v-for="(val, i) in item.list">
|
|
|
|
<view :class="{info_item: true, mt20: i !== 0}">
|
|
|
|
<view class="title info_item_title flex-c-sb">
|
|
|
|
<view class="flex-c-c">
|
|
|
|
<view class="fwb mr20">
|
|
|
|
<text>
|
|
|
|
{{ item.title + ' - ' }}
|
|
|
|
</text>
|
|
|
|
<text>
|
|
|
|
{{ i + 1 }}
|
|
|
|
</text>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view class="info_item_container imgList flex">
|
|
|
|
<block v-for="(value, j) in val.imgList">
|
|
|
|
<!-- 单个图片 -->
|
|
|
|
<view class="image_conatiner mr20 mb20">
|
|
|
|
<view class="">
|
|
|
|
<image :src="value.url" mode=""></image>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</block>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</block>
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
</PullDownBox>
|
|
|
|
</view>
|
|
|
|
</block>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<template v-else>
|
|
|
|
<view class="row pr20 pl20 pt20">
|
|
|
|
<view class="info_item_container imgList flex">
|
|
|
|
<block v-for="(value, j) in details.imgList">
|
|
|
|
<!-- 单个图片 -->
|
|
|
|
<view class="image_conatiner mr20 mb20">
|
|
|
|
<view class="">
|
|
|
|
<image :src="value.url" mode=""></image>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</block>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view class="row pr20 pl20 pb20 flex">
|
|
|
|
<text>完结备注:</text>
|
|
|
|
<text>{{ details.form.remark }}</text>
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<!-- <view class="pd20 mt20 row">
|
|
|
|
<view class="mb20">验收备注</view>
|
|
|
|
|
|
|
|
<u-textarea v-model="details.form.reason" placeholder="请输入"></u-textarea>
|
|
|
|
</view> -->
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
<view class="footer">
|
|
|
|
<view class="button" @click="() => handleSubmit(0)">驳 回</view>
|
|
|
|
|
|
|
|
<view class="button subColor" @click="() => handleSubmit(1)">通 过</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
</BasicContainer>
|
|
|
|
|
|
|
|
<tips ref="tip" />
|
|
|
|
|
|
|
|
<PopUp ref="checkPopUpRef">
|
|
|
|
<view class="pd20 mt20 row">
|
|
|
|
<!-- 验收图片 -->
|
|
|
|
<view class="mb20">
|
|
|
|
验收图片
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view class="flex imgList mb20">
|
|
|
|
<!-- 单个图片 -->
|
|
|
|
<block v-for="(item, index) in details.checkAndAcceptImgList" :key="item">
|
|
|
|
<view class="image_conatiner mr20 pd20">
|
|
|
|
<image :src="item.url" mode=""></image>
|
|
|
|
|
|
|
|
<!-- 删除 -->
|
|
|
|
<view class="removeIcon" @click="()=> handleRmove(index)">
|
|
|
|
<u-icon name="close-circle-fill" color="#666" size="50"></u-icon>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</block>
|
|
|
|
|
|
|
|
<!-- 添加图片 -->
|
|
|
|
<view class="image_conatiner addImg flex-c-c" @click="handleUploadFile">
|
|
|
|
<u-icon name="photo-fill" color="#999" size="100"></u-icon>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<!-- 备注 -->
|
|
|
|
<view class="mb20">验收备注</view>
|
|
|
|
|
|
|
|
<u-textarea v-model="details.form.reason" placeholder="请输入"></u-textarea>
|
|
|
|
</view>
|
|
|
|
</PopUp>
|
|
|
|
|
|
|
|
<!-- #ifdef APP -->
|
|
|
|
<!-- <saomiao2 :ishidestop="scanState !== 0"></saomiao2> -->
|
|
|
|
<!-- #endif -->
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
import {
|
|
|
|
postInstallSalesAcceptance,
|
|
|
|
postInstallAcceptance,
|
|
|
|
postInstallWorkingInfo,
|
|
|
|
} from '@/api/user.js'
|
|
|
|
import { onLoad, onShow, onHide, onUnload } from '@dcloudio/uni-app'
|
|
|
|
import { nextTick, reactive, ref, toRefs } from 'vue'
|
|
|
|
import utils from '@/utils/utils.js'
|
|
|
|
// import useSystemSettingsStore from '@/store/useSystemSettingsStore';
|
|
|
|
// import { storeToRefs } from 'pinia';
|
|
|
|
// const { scanState } = storeToRefs(useSystemSettingsStore())
|
|
|
|
|
|
|
|
// 组件实例
|
|
|
|
const basicContainer = ref()
|
|
|
|
const tip = ref()
|
|
|
|
const imgPullDownRefList = ref()
|
|
|
|
const checkPopUpRef = ref()
|
|
|
|
|
|
|
|
let details = reactive({
|
|
|
|
/** 扫描的码值 */
|
|
|
|
scancode: '',
|
|
|
|
scrollheight: '80vh',
|
|
|
|
form: {
|
|
|
|
/** 完结描述 */
|
|
|
|
remark: '',
|
|
|
|
/** 结果描述 */
|
|
|
|
reason: '',
|
|
|
|
},
|
|
|
|
/** 页面类型 -- install: 安装; installSales: 售后 */
|
|
|
|
pageType: 'install' as 'install' | 'installSales',
|
|
|
|
/** 页面信息 */
|
|
|
|
pageInfo: {
|
|
|
|
// 安装任务Id
|
|
|
|
install_id: '',
|
|
|
|
// 安装售后id
|
|
|
|
install_sales_id: '',
|
|
|
|
},
|
|
|
|
pageArr: [
|
|
|
|
{
|
|
|
|
title: '客厅',
|
|
|
|
prop: 'parlor',
|
|
|
|
tag: '1',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '卧室',
|
|
|
|
tag: '2',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '厨房',
|
|
|
|
prop: 'kitchen',
|
|
|
|
tag: '3',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '卫生间',
|
|
|
|
prop: 'toilet',
|
|
|
|
tag: '4',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '书房',
|
|
|
|
prop: 'study',
|
|
|
|
tag: '5',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '阳台',
|
|
|
|
prop: 'balcony',
|
|
|
|
tag: '6',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: '其它',
|
|
|
|
tag: '7',
|
|
|
|
prop: 'other',
|
|
|
|
list: [],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
imgList: [],
|
|
|
|
renderArr: [],
|
|
|
|
/** 验收图片 */
|
|
|
|
checkAndAcceptImgList: []
|
|
|
|
})
|
|
|
|
|
|
|
|
// 组件配置
|
|
|
|
const option = reactive({
|
|
|
|
// 标题
|
|
|
|
title: details.pageType === 'install' ? '安装验收' : '售后验收',
|
|
|
|
// 下拉刷新回调函数
|
|
|
|
async pullDownRefreshInitPage() {
|
|
|
|
return null
|
|
|
|
},
|
|
|
|
// 触底加载回到函数
|
|
|
|
reachBottomInitPage: async () => {
|
|
|
|
return null
|
|
|
|
},
|
|
|
|
haveData: true,
|
|
|
|
isEnd: false,
|
|
|
|
pageLoading: false,
|
|
|
|
})
|
|
|
|
|
|
|
|
onLoad(e => {
|
|
|
|
console.log('e :>> ', e)
|
|
|
|
details.pageType = e.pageType
|
|
|
|
details.pageType === 'install'
|
|
|
|
? (details.pageInfo.install_id = e.id)
|
|
|
|
: (details.pageInfo.install_sales_id = e.id)
|
|
|
|
|
|
|
|
if (details.pageType === 'install') initpage()
|
|
|
|
else if (details.pageType === 'installSales') {
|
|
|
|
const _info = uni.getStorageSync('installWork') || {}
|
|
|
|
console.log('_info :>> ', _info)
|
|
|
|
details.form.remark = _info.remark
|
|
|
|
details.imgList = _info.images
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
onUnload(() => {
|
|
|
|
uni.removeStorageSync('installWork')
|
|
|
|
})
|
|
|
|
|
|
|
|
onShow(async () => {
|
|
|
|
// // #ifdef APP
|
|
|
|
// // 初始化关闭监听
|
|
|
|
// uni.$off('scancodedate')
|
|
|
|
// // init()
|
|
|
|
// uni.$on('scancodedate', function (code) {
|
|
|
|
// console.log('code :>> ', code);
|
|
|
|
// if (code) {
|
|
|
|
// console.log(code);
|
|
|
|
// details.scancode = code
|
|
|
|
// scandata()
|
|
|
|
// }
|
|
|
|
// })
|
|
|
|
// // #endif
|
|
|
|
|
|
|
|
await nextTick()
|
|
|
|
// basicContainer.value.startPullDownRefresh()
|
|
|
|
const _height = await utils.getViewDistanceFormTop('.scvmabx')
|
|
|
|
|
|
|
|
details.scrollheight = Number(_height.replace('px', '')) - 100 + 'px'
|
|
|
|
})
|
|
|
|
|
|
|
|
const scandata = () => { }
|
|
|
|
|
|
|
|
/** 初始化获取数据 */
|
|
|
|
const initpage = async () => {
|
|
|
|
try {
|
|
|
|
option.pageLoading = true
|
|
|
|
const res = await postInstallWorkingInfo({ install_id: details.pageInfo.install_id })
|
|
|
|
|
|
|
|
const { code, data } = res
|
|
|
|
if (code !== 200) return
|
|
|
|
console.log('data :>> ', data)
|
|
|
|
|
|
|
|
if (utils.getObjType(data) !== 'object') return
|
|
|
|
|
|
|
|
const { reamrk, workImages } = data
|
|
|
|
|
|
|
|
details.form.remark = reamrk
|
|
|
|
|
|
|
|
if (utils.getObjType(workImages) !== 'array') return
|
|
|
|
|
|
|
|
for (let i = 0; i < workImages.length; i++) {
|
|
|
|
const value = workImages[i]
|
|
|
|
|
|
|
|
let _item
|
|
|
|
|
|
|
|
for (let i = 0; i < details.pageArr.length; i++) {
|
|
|
|
const _value = details.pageArr[i]
|
|
|
|
|
|
|
|
if (_value.tag !== value.room_tag + '') continue
|
|
|
|
_item = _value
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_item) continue
|
|
|
|
|
|
|
|
console.log('_item :>> ', _item)
|
|
|
|
|
|
|
|
const _index = Number(value.room_name.split(' - ')[1]) - 1
|
|
|
|
|
|
|
|
_item.list.splice(_index, 1, {
|
|
|
|
...value,
|
|
|
|
imgList: value.images,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
console.log('err :>> ', err)
|
|
|
|
//TODO handle the exception
|
|
|
|
} finally {
|
|
|
|
await nextTick()
|
|
|
|
const timer = setTimeout(() => {
|
|
|
|
console.log('imgPullDownRefList.value :>> ', imgPullDownRefList.value)
|
|
|
|
|
|
|
|
if (utils.getObjType(imgPullDownRefList.value) !== 'array') return
|
|
|
|
|
|
|
|
for (let iterator of imgPullDownRefList.value) {
|
|
|
|
console.log('iterator :>> ', iterator)
|
|
|
|
iterator.handleShowPullDown && iterator.handleShowPullDown(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
clearTimeout(timer)
|
|
|
|
}, 100)
|
|
|
|
option.pageLoading = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 上传验收图片 */
|
|
|
|
/** 上传文件 */
|
|
|
|
const handleUploadFile = () => {
|
|
|
|
const successByUpload = (res) => {
|
|
|
|
console.log('res :>> ', res);
|
|
|
|
const { data } = res
|
|
|
|
const _data = JSON.parse(data)
|
|
|
|
|
|
|
|
console.log('_data :>> ', _data);
|
|
|
|
const { code, data: img } = _data
|
|
|
|
|
|
|
|
details.checkAndAcceptImgList.push({ url: img, name: img })
|
|
|
|
}
|
|
|
|
|
|
|
|
utils.handleUploadFile({
|
|
|
|
successByUpload
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 移除图片 */
|
|
|
|
const handleRmove = (index) => {
|
|
|
|
tip.value.setdetails({
|
|
|
|
isshow: true,
|
|
|
|
content: '确认移除',
|
|
|
|
cancelTxt: '取消',
|
|
|
|
confirmTxt: '确认',
|
|
|
|
success() {
|
|
|
|
details.imgList.splice(index, 1)
|
|
|
|
|
|
|
|
// 关闭弹窗
|
|
|
|
tip.value.setdetails({ isshow: false })
|
|
|
|
},
|
|
|
|
cancel() {
|
|
|
|
// 关闭弹窗
|
|
|
|
tip.value.setdetails({ isshow: false })
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 提交
|
|
|
|
* @param {number} result 结果 1 -- 通过, 0 -- 驳回
|
|
|
|
*/
|
|
|
|
const handleSubmit = (result : 0 | 1) => {
|
|
|
|
console.log('result :>> ', result)
|
|
|
|
|
|
|
|
checkPopUpRef.value.setDetails({
|
|
|
|
showPopUp: true,
|
|
|
|
title: '确认' + (result === 0 ? '驳回' : '通过'),
|
|
|
|
async success() {
|
|
|
|
if (result === 0 && details.checkAndAcceptImgList.length === 0) return utils.handleToast('最少上传一张驳回图片')
|
|
|
|
if (result === 0 && !details.form.reason) return utils.handleToast('请输入驳回原因')
|
|
|
|
|
|
|
|
try {
|
|
|
|
option.pageLoading = true
|
|
|
|
const submitData : {
|
|
|
|
// 验收或驳回
|
|
|
|
result : number
|
|
|
|
// 验收意见
|
|
|
|
reason : string
|
|
|
|
// 安装任务id
|
|
|
|
install_id ?: string
|
|
|
|
// 安装售后id
|
|
|
|
install_sales_id ?: string
|
|
|
|
// 验收图片
|
|
|
|
images : { url : string, name : string }[]
|
|
|
|
} = {
|
|
|
|
result,
|
|
|
|
reason: details.form.reason,
|
|
|
|
images: details.checkAndAcceptImgList
|
|
|
|
}
|
|
|
|
|
|
|
|
details.pageType === 'install'
|
|
|
|
? (submitData.install_id = details.pageInfo.install_id)
|
|
|
|
: (submitData.install_sales_id = details.pageInfo.install_sales_id)
|
|
|
|
|
|
|
|
const res =
|
|
|
|
details.pageType === 'install'
|
|
|
|
? // 安装验收
|
|
|
|
await postInstallAcceptance(submitData)
|
|
|
|
: // 售后验收
|
|
|
|
await postInstallSalesAcceptance(submitData)
|
|
|
|
|
|
|
|
const { code, data } = res
|
|
|
|
|
|
|
|
if (code !== 200) return
|
|
|
|
|
|
|
|
uni.navigateBack()
|
|
|
|
} catch (err) {
|
|
|
|
console.log('err :>> ', err)
|
|
|
|
//TODO handle the exception
|
|
|
|
} finally {
|
|
|
|
option.pageLoading = false
|
|
|
|
// 关闭弹窗
|
|
|
|
tip.value.setdetails({ isshow: false })
|
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
@import url('@/utils/style/common.scss');
|
|
|
|
|
|
|
|
// 主体内容
|
|
|
|
.main {
|
|
|
|
position: relative;
|
|
|
|
border-top-right-radius: 20upx;
|
|
|
|
border-top-left-radius: 20upx;
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
|
|
.scvmabx {
|
|
|
|
background-color: #f5f5f6;
|
|
|
|
|
|
|
|
:deep(.Pulldown-title-container) {
|
|
|
|
padding: 20upx;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.Pulldown_content) {
|
|
|
|
padding: 20upx;
|
|
|
|
padding-bottom: 0;
|
|
|
|
background: #f5f5f6;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.PullDownBox) {
|
|
|
|
border-radius: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.info_item {
|
|
|
|
border-radius: 20upx;
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
.info_item_title {
|
|
|
|
background-color: var(--subjectColor);
|
|
|
|
color: #fff;
|
|
|
|
padding: 25upx 20upx;
|
|
|
|
}
|
|
|
|
|
|
|
|
.info_item_container {
|
|
|
|
background-color: #fff;
|
|
|
|
padding: 20upx;
|
|
|
|
padding-bottom: 0upx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.addBtn {
|
|
|
|
color: #2f8dff;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 图片列表
|
|
|
|
// .imgList {
|
|
|
|
// flex-wrap: wrap;
|
|
|
|
|
|
|
|
// image {
|
|
|
|
// width: 160upx;
|
|
|
|
// height: 160upx;
|
|
|
|
// border-radius: 20upx;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
// 图片列表
|
|
|
|
.imgList {
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
.image_conatiner {
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
.removeIcon {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
right: 0;
|
|
|
|
transform: translate(40%, -40%);
|
|
|
|
opacity: 0.9;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.addImg {
|
|
|
|
width: 160upx;
|
|
|
|
height: 160upx;
|
|
|
|
border-radius: 20upx;
|
|
|
|
box-sizing: border-box;
|
|
|
|
border: 2upx solid #eee;
|
|
|
|
}
|
|
|
|
|
|
|
|
image {
|
|
|
|
width: 160upx;
|
|
|
|
height: 160upx;
|
|
|
|
border-radius: 20upx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 底部
|
|
|
|
.footer {
|
|
|
|
box-sizing: border-box;
|
|
|
|
height: 100px;
|
|
|
|
padding-top: 30upx;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
.button {
|
|
|
|
height: 80upx;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
flex: 1;
|
|
|
|
// margin: 10upx;
|
|
|
|
border: 2upx solid #b5babf;
|
|
|
|
border-radius: 80upx;
|
|
|
|
margin: 0 10upx;
|
|
|
|
padding: 0 10upx;
|
|
|
|
font-size: 0.9rem;
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
|
|
&.subColor {
|
|
|
|
// border-color: var(--subjectColor);
|
|
|
|
// color: var(--subjectColor);
|
|
|
|
background-color: var(--subjectColor);
|
|
|
|
color: #fff;
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.primaryColor {
|
|
|
|
// border-color: var(--primaryColor);
|
|
|
|
// color: var(--primaryColor);
|
|
|
|
background-color: var(--primaryColor);
|
|
|
|
color: #fff;
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
&.errColor {
|
|
|
|
// border-color: var(--errColor);
|
|
|
|
// color: var(--errColor);
|
|
|
|
background-color: var(--errColor);
|
|
|
|
color: #fff;
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.row {
|
|
|
|
background-color: #fff;
|
|
|
|
}
|
|
|
|
</style>
|