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.
671 lines
15 KiB
671 lines
15 KiB
<template> |
|
<BasicContainer ref='basicContainer' :option="option"> |
|
<!-- 头部 --> |
|
<template #head> |
|
<view class="background"> |
|
|
|
</view> |
|
|
|
<view class="header_title"> |
|
<view class=""> |
|
售后编号:{{details.pageInfo.no}} |
|
</view> |
|
|
|
<view class="mt20"> |
|
关联任务编号: |
|
</view> |
|
</view> |
|
|
|
</template> |
|
|
|
<!-- 主体 --> |
|
<template #body> |
|
<view class="main"> |
|
<view class="tabbar_container flex-c-sb"> |
|
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(0)"> |
|
客户信息 |
|
</view> |
|
|
|
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(1)"> |
|
售后信息 |
|
</view> |
|
|
|
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(2)"> |
|
节点记录 |
|
</view> |
|
|
|
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(3)"> |
|
签到记录 |
|
</view> |
|
|
|
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(4)"> |
|
处理记录 |
|
</view> |
|
|
|
<view class="active flex-c-c" :style="`transform: translateX(${details.tabbarCode * 100 +'%'})`"> |
|
<view class="line"> |
|
|
|
</view> |
|
</view> |
|
</view> |
|
|
|
|
|
<scroll-view class="scvmabx" :style="{height: details.scrollheight}" @scrolltolower="()=>{}" scroll-y="true" |
|
@touchmove.stop> |
|
|
|
<!-- 客户信息 --> |
|
<ClientInfo v-show="details.tabbarCode === 0" :pageInfo="details.pageInfo" :info="details.info" /> |
|
|
|
<!-- 售后信息 --> |
|
<view v-show="details.tabbarCode === 1"> |
|
<AfterSalesInfo :pageInfo="details.pageInfo" ref="afterSalesInfo" :info="details.info" |
|
:handleSetLoading="handleSetLoading" :handleRefresh="handleRefresh" |
|
:goodsTypeArr="details.goodsTypeArr" /> |
|
</view> |
|
|
|
<!-- 节点信息 --> |
|
<NodeInfo v-show="details.tabbarCode === 2" :pageInfo="details.pageInfo" :info="details.info" /> |
|
|
|
<!-- 签收记录 --> |
|
<SiginLog v-show="details.tabbarCode === 3" :pageInfo="details.pageInfo" :info="details.info" /> |
|
|
|
<!-- 处理记录 --> |
|
<DutyList v-show="details.tabbarCode === 4" :pageInfo="details.pageInfo" :info="details.info" /> |
|
</scroll-view> |
|
|
|
<view class="footer"> |
|
<view class="button" v-if="details.buttonPermissionObj.siginBtn" @click="handleSigin"> |
|
签 到 |
|
</view> |
|
|
|
<view class="button" v-if="details.buttonPermissionObj.openWorkBtn" @click="handleStartWorking"> |
|
开 工 |
|
</view> |
|
|
|
<view class="button subColor" v-if="details.buttonPermissionObj.confirmWorkBtn" |
|
@click="handleConfirmCompletion"> |
|
确认完工 |
|
</view> |
|
|
|
<view class="button primaryColor" @click="handleConfirmCompletion"> |
|
确认到货 |
|
</view> |
|
|
|
<view class="button primaryColor" v-if="details.buttonPermissionObj.confirmSignfor" |
|
@click="handleCheckAndAccept"> |
|
确认验收 |
|
</view> |
|
|
|
<view class="button subColor" v-if="details.buttonPermissionObj.confirmAssign" |
|
@click="handleAssignATask"> |
|
确认指派 |
|
</view> |
|
</view> |
|
</view> |
|
|
|
</template> |
|
</BasicContainer> |
|
|
|
<tips ref="tip"></tips> |
|
|
|
<!-- #ifdef APP --> |
|
<saomiao2 :ishidestop="scanState !== 0"></saomiao2> |
|
<!-- #endif --> |
|
</template> |
|
|
|
<script lang="ts"> |
|
import ClientInfo from "./clientInfo.vue" |
|
import AfterSalesInfo from "./afterSalesInfo.vue" |
|
import NodeInfo from "./nodeInfo.vue" |
|
import SiginLog from "./siginLog.vue" |
|
import DutyList from './dutyList.vue'; |
|
|
|
export default { |
|
// 页面组件 |
|
components: { |
|
// 客户信息 |
|
ClientInfo, |
|
// 服务内容 |
|
AfterSalesInfo, |
|
// 节点信息 |
|
NodeInfo, |
|
// 签收记录 |
|
SiginLog, |
|
DutyList |
|
} |
|
} |
|
</script> |
|
|
|
<script lang="ts" setup> |
|
import { |
|
postInstallSalesDetail, |
|
getCommonGoodsType, |
|
postInstallSalesStart |
|
} from '@/api/user.js' |
|
import { |
|
onLoad, |
|
onShow, |
|
onHide, |
|
} from '@dcloudio/uni-app' |
|
import { nextTick, reactive, ref, toRefs, computed } from "vue"; |
|
import utils from '@/utils/utils.js' |
|
import useSystemSettingsStore from '@/store/useSystemSettingsStore'; |
|
import { storeToRefs } from 'pinia'; |
|
const { scanState } = storeToRefs(useSystemSettingsStore()) |
|
// 组件配置 |
|
const option = reactive({ |
|
// 标题 |
|
title: '任务详情', |
|
// 下拉刷新回调函数 |
|
async pullDownRefreshInitPage() { |
|
await initpage(true) |
|
return null |
|
}, |
|
// 触底加载回到函数 |
|
reachBottomInitPage: () => { }, |
|
haveData: true, |
|
isEnd: false, |
|
/** 页面loading */ |
|
pageLoading: true |
|
}) |
|
|
|
// 组件实例 |
|
const basicContainer = ref() // 页面组件 |
|
const tip = ref() // 提示弹窗 |
|
const afterSalesInfo = ref() |
|
|
|
let details = reactive({ |
|
show: false, |
|
/** 时间 */ |
|
datatime: '', |
|
/** 当前页码 */ |
|
pageNum: 1, |
|
/** 页数 */ |
|
pageSize: 20, |
|
/** 渲染列表数据 */ |
|
datalist: [], |
|
/** 扫描的码值 */ |
|
scancode: '', |
|
scrollheight: '80vh', |
|
/** tabbar激活code */ |
|
tabbarCode: 0, |
|
/** 页面数据 */ |
|
pageInfo: { |
|
// 安装任务id |
|
id: '' |
|
}, |
|
/** 数据 */ |
|
info: {}, |
|
goodsTypeArr: [], |
|
type_map: [ |
|
{ |
|
value: 1, |
|
label: "调试", |
|
}, |
|
{ |
|
value: 2, |
|
label: "维修", |
|
}, |
|
{ |
|
value: 3, |
|
label: "理赔", |
|
}, |
|
{ |
|
value: 4, |
|
label: "待确认", |
|
}, |
|
{ |
|
value: 5, |
|
label: "换货", |
|
}, |
|
{ |
|
value: 6, |
|
label: "工厂补单", |
|
} |
|
], |
|
/** 用户信息 */ |
|
userInfo: (uni.getStorageSync('userInfo') || {}), |
|
/** 按钮权限 */ |
|
buttonPermissionObj: { |
|
/* |
|
0 -- 待确认 |
|
1 -- 待指派 |
|
2 -- 已指派 |
|
3 -- 已到货 |
|
4 -- 服务中 |
|
5 -- 已完成 |
|
6 -- 已验收 |
|
7 -- 已完结 |
|
8 -- 已关闭 |
|
*/ |
|
|
|
/** 提交修改 */ |
|
submitChangeBtn: computed(() => { |
|
const { installSales } = details.info as any |
|
|
|
if (utils.getObjType(installSales) !== 'object') return false |
|
|
|
const _status = Number(installSales.status) |
|
|
|
const whiteArr = [0] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
|
|
return false |
|
}), |
|
/** 签到 */ |
|
siginBtn: computed(() => { |
|
const { id } = details.userInfo |
|
|
|
console.log('id :>> ', id); |
|
|
|
const { installSales, installWork } = details.info as any |
|
|
|
if (utils.getObjType(installSales) !== 'object' || utils.getObjType(installWork) !== 'object') return false |
|
|
|
if (!installWork.work_user_ids || !installWork.work_user_ids.includes(id)) return false |
|
|
|
const _status = Number(installSales.status) |
|
|
|
const whiteArr = [4] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
|
|
return false |
|
}), |
|
/** 开工 */ |
|
openWorkBtn: computed(() => { |
|
const { id } = details.userInfo |
|
|
|
console.log('id :>> ', id); |
|
|
|
const { installSales, installWork } = details.info as any |
|
console.log('installWork :>> ', installWork); |
|
|
|
if (utils.getObjType(installSales) !== 'object' || utils.getObjType(installWork) !== 'object') return false |
|
|
|
if (!installWork.work_user_ids || !installWork.work_user_ids.includes(id)) return false |
|
|
|
console.log('installWork.work_user_ids.includes(id) :>> ', installWork.work_user_ids.includes(id)); |
|
|
|
const _status = Number(installSales.status) |
|
|
|
const _type = Number(installSales.type) |
|
|
|
// 是否为补货/换货 |
|
const isReplenishment = [5, 6] |
|
|
|
// 补货换货单 |
|
if (isReplenishment.includes(_type)) { |
|
const whiteArr = [3] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
} else { |
|
const whiteArr = [2, 3] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
} |
|
|
|
|
|
return false |
|
}), |
|
/** 确认完工 */ |
|
confirmWorkBtn: computed(() => { |
|
const { id } = details.userInfo |
|
|
|
console.log('id :>> ', id); |
|
|
|
const { installSales, installWork } = details.info as any |
|
|
|
if (utils.getObjType(installSales) !== 'object' || utils.getObjType(installWork) !== 'object') return false |
|
|
|
if (!installWork.work_user_ids || !installWork.work_user_ids.includes(id)) return false |
|
|
|
const _status = Number(installSales.status) |
|
|
|
const whiteArr = [4] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
|
|
return false |
|
}), |
|
/** 确认验收 */ |
|
confirmSignfor: computed(() => { |
|
// 安装负责人存在验收权限 |
|
const _roleWhite = [3, 4] |
|
if (!_roleWhite.includes(Number(details.userInfo.role_code))) return false |
|
|
|
const { installSales } = details.info as any |
|
|
|
if (utils.getObjType(installSales) !== 'object') return false |
|
|
|
const _status = Number(installSales.status) |
|
|
|
const whiteArr = [5] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
|
|
return false |
|
}), |
|
/** 确认指派 */ |
|
confirmAssign: computed(() => { |
|
console.log('Number(details.userInfo.role_code) :>> ', Number(details.userInfo.role_code)); |
|
// 安装负责人存在验收权限 |
|
const _roleWhite = [3, 4] |
|
if (!_roleWhite.includes(Number(details.userInfo.role_code))) return false |
|
|
|
const { installSales } = details.info as any |
|
|
|
if (utils.getObjType(installSales) !== 'object') return false |
|
console.log('111 :>> ', 111); |
|
const _status = Number(installSales.status) |
|
console.log('_status :>> ', _status); |
|
const whiteArr = [1, 2, 3] |
|
|
|
if (whiteArr.includes(_status)) return true |
|
console.log('111 :>> ', 222); |
|
return false |
|
}) |
|
} |
|
|
|
}) |
|
|
|
onLoad(async (e) => { |
|
console.log('e :>> ', e); |
|
details.pageInfo = JSON.parse(e.pageInfo) |
|
|
|
|
|
}) |
|
|
|
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 |
|
try { |
|
option.pageLoading = true |
|
|
|
await Promise.all([initGoodsTypeList(), initpage()]) |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
option.pageLoading = false |
|
} |
|
|
|
await nextTick() |
|
// basicContainer.value.startPullDownRefresh() |
|
|
|
const _height = await utils.getViewDistanceFormTop('.scvmabx') |
|
|
|
details.scrollheight = Number(_height.replace('px', '')) - 100 + 'px' |
|
}) |
|
|
|
/** 扫描执行回调 */ |
|
const scandata = () => { } |
|
|
|
/** 初始化获取页面数据 */ |
|
const initpage = async (isLoading = false) => { |
|
try { |
|
if (isLoading) option.pageLoading = true |
|
|
|
const res = await postInstallSalesDetail({ id: details.pageInfo.id }) |
|
const { code, data } = res |
|
if (code !== 200) return |
|
|
|
console.log('data :>> ', data); |
|
details.info = data |
|
|
|
|
|
setTimeout(() => { |
|
|
|
if (!afterSalesInfo.value) return |
|
|
|
// 售后信息赋值 |
|
afterSalesInfo.value.details.form = utils.deepClone(data.installSales || {}) |
|
afterSalesInfo.value.details.imgList = data.installSales.images || [] |
|
|
|
for (let i = 0; i < details.type_map.length; i++) { |
|
const value = details.type_map[i] |
|
|
|
if (value.value !== afterSalesInfo.value.details.form.type) continue |
|
console.log('value :>> ', value); |
|
afterSalesInfo.value.details.form.typeName = value.label |
|
afterSalesInfo.value.details.value = [i] |
|
break |
|
} |
|
// typeName |
|
console.log('afterSalesInfo.value :>> ', afterSalesInfo.value); |
|
}, 100) |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
if (isLoading) option.pageLoading = false |
|
} |
|
|
|
} |
|
|
|
/** 初始化获取goodsTypeList */ |
|
const initGoodsTypeList = async () => { |
|
const res = await getCommonGoodsType({}) |
|
const { code, data } = res |
|
|
|
if (code !== 200) return |
|
details.goodsTypeArr = data || {} |
|
} |
|
|
|
/** tabbar点击事件 */ |
|
const handleClickTabbar = (code : number) => { |
|
details.tabbarCode = code |
|
} |
|
|
|
/** 签到 */ |
|
const handleSigin = () => { |
|
tip.value.setdetails({ |
|
isshow: true, |
|
content: '签入 | 签出', |
|
cancelTxt: '签入', |
|
confirmTxt: '签出', |
|
success() { |
|
// 关闭弹窗 |
|
tip.value.setdetails({ isshow: false }) |
|
|
|
uni.navigateTo({ |
|
url: '/pagesHome/pages/siginIn/siginIn?type=siginOut&id=' + details.pageInfo.id + '&pageType=installSales' |
|
|
|
}) |
|
}, |
|
cancel() { |
|
// 关闭弹窗 |
|
tip.value.setdetails({ isshow: false }) |
|
|
|
uni.navigateTo({ |
|
url: '/pagesHome/pages/siginIn/siginIn?type=siginIn&id=' + details.pageInfo.id + '&pageType=installSales' |
|
}) |
|
} |
|
}) |
|
|
|
|
|
} |
|
|
|
/** 开工 */ |
|
const handleStartWorking = () => { |
|
|
|
tip.value.setdetails({ |
|
isshow: true, |
|
content: '是否确认开工', |
|
cancelTxt: '取 消', |
|
confirmTxt: '确 认', |
|
async success() { |
|
try { |
|
option.pageLoading = true |
|
tip.value.setdetails({ isshow: false }) |
|
const res = await postInstallSalesStart({ install_sales_id: details.pageInfo.id }) |
|
|
|
const { code } = res |
|
if (code !== 200) return |
|
basicContainer.value.startPullDownRefresh() |
|
} catch (err) { |
|
console.log('err :>> ', err); |
|
//TODO handle the exception |
|
} finally { |
|
option.pageLoading = false |
|
} |
|
|
|
// 关闭弹窗 |
|
}, |
|
cancel() { |
|
tip.value.setdetails({ isshow: false }) |
|
} |
|
}) |
|
} |
|
|
|
/** 确认完工 */ |
|
const handleConfirmCompletion = () => { |
|
uni.setStorageSync('installWork', details.info.installWork) |
|
|
|
uni.navigateTo({ |
|
url: '/pagesHome/pages/ParticularsOfCompletionBySales/ParticularsOfCompletionBySales?id=' + details.pageInfo.id |
|
}) |
|
} |
|
|
|
/** 验收 */ |
|
const handleCheckAndAccept = () => { |
|
uni.setStorageSync('installWork', details.info.installWork) |
|
uni.navigateTo({ |
|
url: '/pagesHome/pages/checkAndAccept/checkAndAccept?id=' + details.pageInfo.id + '&pageType=installSales' |
|
}) |
|
} |
|
|
|
/** 指派 */ |
|
const handleAssignATask = () => { |
|
uni.setStorageSync('installWork', details.info.installWork) |
|
uni.navigateTo({ |
|
url: '/pagesHome/pages/AssignATask/AssignATask?id=' + details.pageInfo.id + '&pageType=installSales' |
|
}) |
|
} |
|
|
|
/** 设置loading状态 */ |
|
const handleSetLoading = (status) => { |
|
option.pageLoading = status |
|
} |
|
|
|
/** 刷新数据 */ |
|
const handleRefresh = () => { |
|
basicContainer.value.startPullDownRefresh() |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
@import url("@/utils/style/common.scss"); |
|
|
|
.background { |
|
width: 100vw; |
|
height: 100vh; |
|
position: fixed; |
|
background-color: var(--subjectColor); |
|
} |
|
|
|
// 顶部 |
|
.header_title { |
|
padding: 40upx; |
|
background: var(--subjectColor); |
|
color: #fff; |
|
position: relative; |
|
} |
|
|
|
// 主体内容 |
|
.main { |
|
font-family: 黑体; |
|
position: relative; |
|
border-top-right-radius: 20upx; |
|
border-top-left-radius: 20upx; |
|
background-color: #fff; |
|
} |
|
|
|
// tabber |
|
.tabbar_container { |
|
height: 100upx; |
|
position: relative; |
|
border-bottom: 2upx solid #eee; |
|
|
|
.tabbar_item { |
|
height: 100%; |
|
} |
|
|
|
.active { |
|
width: 20%; |
|
position: absolute; |
|
bottom: 0; |
|
transition: all 0.3s; |
|
transform: translateX(100%); |
|
|
|
$lineHeight: 8upx; |
|
|
|
.line { |
|
width: 40%; |
|
border-radius: calc($lineHeight / 2); |
|
height: $lineHeight; |
|
background: var(--subjectColor); |
|
} |
|
} |
|
} |
|
|
|
// 底部 |
|
.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; |
|
} |
|
} |
|
} |
|
</style> |