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

10 months ago
<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>
10 months ago
<view class="tabbar_item flex-c-c flex1" @click="()=> handleClickTabbar(4)">
处理记录
</view>
10 months ago
<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" />
10 months ago
<!-- 处理记录 -->
<DutyList v-show="details.tabbarCode === 4" :pageInfo="details.pageInfo" :info="details.info" />
10 months ago
</scroll-view>
<view class="footer">
10 months ago
<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>
9 months ago
<view class="button primaryColor" @click="handleConfirmCompletion">
确认到货
</view>
10 months ago
<view class="button primaryColor" v-if="details.buttonPermissionObj.confirmSignfor"
@click="handleCheckAndAccept">
确认验收
</view>
<view class="button subColor" v-if="details.buttonPermissionObj.confirmAssign"
10 months ago
@click="handleAssignATask">
10 months ago
确认指派
</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"
10 months ago
import DutyList from './dutyList.vue';
10 months ago
export default {
// 页面组件
components: {
// 客户信息
ClientInfo,
// 服务内容
AfterSalesInfo,
// 节点信息
NodeInfo,
// 签收记录
10 months ago
SiginLog,
DutyList
10 months ago
}
}
</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: "工厂补单",
}
],
10 months ago
/** 用户信息 */
userInfo: (uni.getStorageSync('userInfo') || {}),
10 months ago
/** 按钮权限 */
buttonPermissionObj: {
/*
0 -- 待确认
1 -- 待指派
2 -- 已指派
3 -- 已到货
4 -- 服务中
5 -- 已完成
6 -- 已验收
7 -- 已完结
8 -- 已关闭
*/
10 months ago
/** 提交修改 */
submitChangeBtn: computed(() => {
10 months ago
const { installSales } = details.info as any
if (utils.getObjType(installSales) !== 'object') return false
const _status = Number(installSales.status)
10 months ago
const whiteArr = [0]
10 months ago
if (whiteArr.includes(_status)) return true
return false
}),
/** 签到 */
siginBtn: computed(() => {
10 months ago
const { id } = details.userInfo
10 months ago
10 months ago
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
10 months ago
const _status = Number(installSales.status)
const whiteArr = [4]
if (whiteArr.includes(_status)) return true
return false
}),
/** 开工 */
openWorkBtn: computed(() => {
10 months ago
const { id } = details.userInfo
10 months ago
10 months ago
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));
10 months ago
const _status = Number(installSales.status)
10 months ago
10 months ago
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(() => {
10 months ago
const { id } = details.userInfo
10 months ago
10 months ago
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
10 months ago
const _status = Number(installSales.status)
const whiteArr = [4]
if (whiteArr.includes(_status)) return true
return false
}),
/** 确认验收 */
confirmSignfor: computed(() => {
10 months ago
// 安装负责人存在验收权限
const _roleWhite = [3, 4]
if (!_roleWhite.includes(Number(details.userInfo.role_code))) return false
10 months ago
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(() => {
10 months ago
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
10 months ago
const { installSales } = details.info as any
if (utils.getObjType(installSales) !== 'object') return false
10 months ago
console.log('111 :>> ', 111);
10 months ago
const _status = Number(installSales.status)
10 months ago
console.log('_status :>> ', _status);
10 months ago
const whiteArr = [1, 2, 3]
if (whiteArr.includes(_status)) return true
10 months ago
console.log('111 :>> ', 222);
10 months ago
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'
10 months ago
})
/** 扫描执行回调 */
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
10 months ago
basicContainer.value.startPullDownRefresh()
10 months ago
} catch (err) {
console.log('err :>> ', err);
//TODO handle the exception
} finally {
option.pageLoading = false
}
// 关闭弹窗
},
cancel() {
tip.value.setdetails({ isshow: false })
}
})
}
/** 确认完工 */
const handleConfirmCompletion = () => {
10 months ago
uni.setStorageSync('installWork', details.info.installWork)
10 months ago
uni.navigateTo({
url: '/pagesHome/pages/ParticularsOfCompletionBySales/ParticularsOfCompletionBySales?id=' + details.pageInfo.id
})
}
/** 验收 */
const handleCheckAndAccept = () => {
10 months ago
uni.setStorageSync('installWork', details.info.installWork)
10 months ago
uni.navigateTo({
url: '/pagesHome/pages/checkAndAccept/checkAndAccept?id=' + details.pageInfo.id + '&pageType=installSales'
})
}
10 months ago
/** 指派 */
const handleAssignATask = () => {
uni.setStorageSync('installWork', details.info.installWork)
uni.navigateTo({
url: '/pagesHome/pages/AssignATask/AssignATask?id=' + details.pageInfo.id + '&pageType=installSales'
})
}
10 months ago
/** 设置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 {
10 months ago
width: 20%;
10 months ago
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;
10 months ago
.button {
height: 80upx;
10 months ago
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;
10 months ago
font-weight: bold;
&.subColor {
// border-color: var(--subjectColor);
// color: var(--subjectColor);
background-color: var(--subjectColor);
color: #fff;
border: none;
10 months ago
}
&.primaryColor {
// border-color: var(--primaryColor);
// color: var(--primaryColor);
background-color: var(--primaryColor);
color: #fff;
border: none;
10 months ago
}
&.errColor {
// border-color: var(--errColor);
// color: var(--errColor);
background-color: var(--errColor);
color: #fff;
border: none;
10 months ago
}
}
}
</style>