lanan-repair-app/pages-home/service/todoDetail.vue
2024-11-15 16:59:26 +08:00

542 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<VNavigationBar background-color="#fff" :title="title" title-color="#333"></VNavigationBar>
<view class="body">
<view class="repairInfo">
<view class="header">
申请人
</view>
<view class="repairItem">
<view class="grid">
<view style="grid-area: a" class="girdItem">
<text class="label">岗位</text>
<text class="value">{{ info.repairWork }}</text>
</view>
<view style="grid-area: b" class="girdItem">
<text class="label">姓名</text>
<text class="value">{{ info.repairName }}</text>
</view>
<view style="grid-area: c" class="girdItem">
<text class="label">服务顾问</text>
<text class="value">{{ info.adviserName }}</text>
</view>
<view style="grid-area: d" class="girdItem">
<text class="label">时间</text>
<text class="value">{{ getDateFormat(info.createTime) }}</text>
</view>
</view>
</view>
</view>
<view class="repairInfo">
<view class="header">
客户信息
</view>
<view class="repairItem">
<view class="grid">
<view style="grid-area: a" class="girdItem">
<text class="label">车牌号</text>
<text class="value">{{ info.licenseNumber }}</text>
</view>
<view style="grid-area: b" class="girdItem">
<text class="label">车系</text>
<text class="value">{{ info.carBrandName }}</text>
</view>
<view style="grid-area: c" class="girdItem">
<text class="label">姓名</text>
<text class="value">{{ info.userName }}</text>
</view>
<view style="grid-area: d" class="girdItem">
<text class="label">电话</text>
<text class="value">{{ info.userMobile }}</text>
</view>
</view>
</view>
</view>
<view class="repairInfo" v-if="imageUrls && imageUrls.length > 0">
<view class="header">
配件申请表
</view>
<view class="repairItem">
<image
v-for="(url, index) in imageUrls"
:key="index"
:src="url"
class="image-item"
@click="showFullScreen(index)"
/>
</view>
</view>
<view class="repairInfo">
<view class="header">
配件信息
<view v-if="canOperate" style="float: right; color: #0174F6" @click="addWares">添加配件</view>
</view>
<view @click="changeChoose(item)" class="repairItem" v-for="(item, index) in repairList" :key="index">
<view class="repairName">
<radio v-if="canOperate" :value="item.id" :checked="item.selected"/>
{{ item.waresName }}
<text class="repairNum">×{{ item.waresCount }}</text>
</view>
<view class="grid">
<view style="grid-area: a" class="girdItem">
<text class="label">配件分类</text>
<text class="value">{{ item.typeName }}</text>
</view>
<view style="grid-area: b" class="girdItem">
<text class="label">当前库存</text>
<text class="value">{{ item.wares.stock }}</text>
</view>
<view style="grid-area: c" class="girdItem">
<text class="label">单位</text>
<text class="value">{{ item.wares.unit }}</text>
</view>
<!-- <view style="grid-area: d" class="girdItem">-->
<!-- <text class="label">编码</text>-->
<!-- <text class="value">{{ item.wares.code || ""}}</text>-->
<!-- </view>-->
<view style="grid-area: d" class="girdItem">
<text class="label">售价</text>
<text class="value"><input type="number" placeholder="请输入售价" v-model="item.wares.price"/></text>
</view>
<view style="grid-area: e" class="girdItem">
<text class="label">状态</text>
<text :class="getWaresStatusClass(item.waresStatus)">{{ getWaresStatus(item.waresStatus) }}</text>
</view>
<view style="grid-area: f" class="girdItem">
<text class="label">审核人</text>
<text class="value">{{ item.handleName }}</text>
</view>
</view>
</view>
</view>
</view>
<view v-if="canOperate" class="footer">
<view class="no" @click="confirmOpe('no')">
{{ backText }}
</view>
<view class="yes" @click="confirmOpe('yes')">
{{ yesText }}
</view>
</view>
<!-- 全屏查看弹窗 -->
<view v-if="showFullscreen" class="fullscreen-container" @click="closeFullscreen">
<image :src="currentImage" class="fullscreen-image" @click.stop />
</view>
</view>
</template>
<script>
import VNavigationBar from "@/components/VNavigationBar.vue";
import request from '@/utils/request';
import {getDictTextByCodeAndValue, formatTimestampCustom} from "@/utils/utils";
import config from "@/config";
export default {
components: {
VNavigationBar
},
data() {
return {
viewType: "",
id: "",
title: "",
canOperate: false,
backText: "",
yesText: "",
repairList: [
// {
// name: '7字小钩',
// num: 3,
// type: '机电',
// unit: '桶',
// total: 35,
// code: 'XCQHCJYS7 SPI SP 5W30 4L'
// },
// {
// name: '7字小钩',
// num: 3,
// type: '机电',
// unit: '桶',
// total: 35,
// code: 'XCQHCJYS7 SPI SP 5W30 4L'
// }
],
selectWares: [],
info: {},
imageUrls: [],
showFullscreen: false,
currentImage: ''
};
},
onShow(){
this.getTicketWares()
this.getDetail()
},
onLoad(data) {
this.canOperate = data.canOperate
this.id = data.id
this.getTicketWares()
this.getDetail()
},
methods: {
addWares(){
//配件申请
uni.navigateTo({
url: '/pages-repair/apply/applyForm?twId=' + this.id
})
},
showFullScreen(index) {
this.currentImage = this.imageUrls[index];
this.showFullscreen = true;
},
closeFullscreen() {
this.showFullscreen = false;
},
getDateFormat(val) {
return formatTimestampCustom(val);
},
async getTicketWares() {
try {
const url = "/admin-api/repair/tw/getById?id=" + this.id
const res = await request({
url: url,
method: 'get'
})
this.info = res.data
if (this.info.repairWork){
this.getWorkToText()
}
await this.getTicketById(this.info.ticketId)
if (this.info.images && this.info.images.length > 0) {
this.getImageUrls(this.info.images)
}
}catch{}
},
getWorkToText(){
getDictTextByCodeAndValue('repair_work_type', this.info.repairWork).then(value => {
this.info.repairWork = value
}).catch(() => {
this.info.repairWork = "未知"
})
},
getImageUrls(val) {
this.imageUrls = [...val.split(",").map(item => {
return config.baseImageUrl + item
})]
},
async getTicketById(id) {
const res = await request({
url: '/admin-api/repair/tickets/get?id=' + id,
method: 'get',
})
this.info.carBrandName = res.data.carBrandName
},
changeChoose(val) {
const flag = this.selectWares.findIndex(item => item.id === val.id)
if (flag === -1) {
val.selected = true
this.selectWares.push(val)
} else {
val.selected = false
this.selectWares.splice(flag, 1)
}
if (this.selectWares && this.selectWares.length > 0) {
this.yesText = "通过"
this.backText = "驳回"
} else {
this.yesText = "通过全部"
this.backText = "驳回全部"
}
},
getWaresStatus(val) {
switch (val) {
case "1":
return "通过";
case "0":
return "不通过";
default:
return "待定"
}
},
getWaresStatusClass(val) {
switch (val) {
case "1":
return "pass";
case "0":
return "no_pass";
default:
return ""
}
},
getDetail() {
let url;
let params = {};
this.title = "配件申请单详情"
//配件申请单
url = "/admin-api/repair/twi/list"
params.twId = this.id
this.yesText = "通过全部"
this.backText = "驳回全部"
request({
url: url,
method: 'get',
params: params
}).then((res) => {
if (res.code == 200) {
this.repairList = res.data
if (this.canOperate && this.repairList && this.repairList.length > 0) {
this.repairList = this.repairList.filter(item => item.waresStatus === '').map(item => {
return {
...item,
selected: false
}
})
}
}
})
},
confirmOpe(type) {
// let forSign = true
// if (type == 'yes') {
// this.repairList.map(item=>{
// if (item.wares.price == null || item.wares.price == ''){
// uni.showToast({
// title: '售价不能为空!',
// icon: 'none'
// })
// forSign = false
// return;
// }
// })
// }
// if (!forSign) {
// return;
// }
let url = '/admin-api/repair/tw/audit'
let dataObj = {
id: this.id,
type: "01",
status: "yes" == type ? "01" : "02"
}
if (this.selectWares && this.selectWares.length > 0) {
dataObj.items = [...this.selectWares.map(item => {
return {
id: item.id
}
})]
} else {
dataObj.items = [...this.repairList.map(item => {
return {
id: item.id
}
})]
}
request({
url: url,
method: 'POST',
data: dataObj
}).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '审批成功!',
icon: 'none'
})
setTimeout(() => {
uni.navigateBack()
}, 700)
}
})
},
}
}
</script>
<style lang="less" scoped>
.container {
height: 100%;
background: #F3F5F7;
display: flex;
flex-direction: column;
}
.body {
flex: 1;
height: 0;
overflow: auto;
.todoInfo {
margin: 20rpx 32rpx;
background-color: #fff;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding: 30rpx;
.todoName {
font-weight: bold;
font-size: 32rpx;
color: #333333;
margin-bottom: 16rpx;
}
.todoDate {
font-size: 24rpx;
color: #858BA0;
margin-bottom: 30rpx;
}
.line {
height: 1rpx;
background-color: #DDDDDD;
margin: 30rpx 0;
}
.grid {
display: grid;
grid-template-areas:
'a b'
'c c';
gap: 20rpx;
.gridItem {
display: flex;
flex-direction: column;
row-gap: 10rpx;
font-size: 28rpx;
.gridItemLabel {
color: #858BA0;
}
.gridItemValue {
color: #333333;
}
}
}
}
.repairInfo {
margin: 20rpx 32rpx;
background-color: #fff;
border-radius: 8rpx 8rpx 8rpx 8rpx;
.header {
padding: 30rpx;
border-bottom: 1rpx solid #DDDDDD;
}
.repairItem {
padding: 30rpx;
border-bottom: 1rpx solid #DDDDDD;
&:last-child {
border-bottom: none;
}
}
.repairName {
display: flex;
align-items: center;
column-gap: 20rpx;
font-size: 32rpx;
color: #333333;
margin-bottom: 30rpx;
.repairNum {
font-size: 28rpx;
color: #0174F6;
}
}
.grid {
display: grid;
grid-template-areas:
'a b'
'c d'
'e f';
grid-template-columns: 1fr 1fr;
gap: 30rpx;
.girdItem {
display: flex;
flex-direction: column;
row-gap: 12rpx;
font-size: 28rpx;
.label {
color: #858BA0;
}
.value {
color: #333333;
}
}
}
}
}
.footer {
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 32rpx;
.yes, .no {
width: 310rpx;
height: 76rpx;
border-radius: 38rpx 38rpx 38rpx 38rpx;
display: flex;
align-items: center;
justify-content: center;
column-gap: 10rpx;
}
.yes {
background: #0174F6;
color: #FFFFFF;
}
.no {
border: 2rpx solid #858BA0;
color: #858BA0;
}
}
.pass {
color: #2979FF;
}
.no_pass {
color: #E8A321;
}
.image-item {
width: 100rpx;
height: 100rpx;
border-radius: 8rpx;
object-fit: cover;
margin-right: 10rpx; /* 增加右边距,使图片之间有间隔 */
}
.fullscreen-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.fullscreen-image {
max-width: 90vw; /* 最大宽度为视口宽度的90% */
max-height: 90vh; /* 最大高度为视口高度的90% */
object-fit: contain; /* 保持宽高比 */
cursor: pointer;
margin: 0 20rpx; /* 增加左右边距,使图片距离屏幕边缘有一定距离 */
}
</style>