lanan-repair-app/pages-home/service/todoDetail.vue
2024-11-22 10:06:43 +08:00

658 lines
17 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="imgUrlPrex+url"
class="image-item"
@click="prviewImage(imageUrls,index)"
/>
</view>
</view>
<view class="repairInfo">
<view class="header">
配件信息
<view v-if="canOperate" style="float: right; color: #0174F6" @click="addWares">添加配件</view>
<view v-if="canOperate" style="float: right; color: #0174F6;margin-right: 1rem" @click="handleSetting">移交保险公司</view>
</view>
<uni-collapse ref="collapse">
<uni-collapse-item v-for="(groupItem, index) in repairList" :key="groupItem.groupId"
:title="groupItem.groupName+'(合计:'+groupItem.nums+'个配件'">
<view class="content">
<view @click="changeChoose(item)" v-for="item in groupItem.twItemList" :key="item.id" class="repairItem" >
<view class="repairName">
<radio v-if="canOperate && item.waresStatus === ''" :value="item.id" :checked="item.selected"/>
{{ item.waresName }}×{{ item.waresCount }}{{ item.unitText }}
</view>
<view class="grid">
<view style="grid-area: a" class="girdItem">
<text class="label">当前库存</text>
<text class="value">{{item.stock}}</text>
</view>
<view style="grid-area: b" class="girdItem">
<text class="label">售价</text>
<text class="value">{{item.salePrice}}</text>
</view>
<view style="grid-area: c" class="girdItem">
<text class="label">状态</text>
<text :class="getWaresStatusClass(item.waresStatus)">{{ getWaresStatus(item.waresStatus) }}</text>
</view>
<view v-if="item.handleName" style="grid-area: d" class="girdItem">
<text class="label">审核人</text>
<text class="value">{{ item.handleName }}</text>
</view>
<view v-if="item.handleName" style="grid-area: e" class="girdItem">
<text class="label">审核时间</text>
<text class="value">{{ item.approvalTime }}</text>
</view>
</view>
</view>
</view>
</uni-collapse-item>
</uni-collapse>
</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>
<uni-popup ref="settingPopup" type="center" :mask-click="false">
<view class="popup-content">
<view class="popup-title">设置</view>
<form @submit="doSetting">
<view class="uni-form-item">
<text class="uni-label">是否传给保险公司:</text>
<switch :checked="settingForm.toSafe === '1'" @change="toggleToSafe" />
</view>
<view class="uni-form-item" v-if="settingForm.toSafe === '1'">
<text class="uni-label">保险公司名称:</text>
<input class="uni-input" v-model="settingForm.safeName" placeholder="保险公司名称" />
</view>
<view class="uni-form-item" v-if="settingForm.toSafe === '1'">
<text class="uni-label">联系人:</text>
<input class="uni-input" v-model="settingForm.safeContact" placeholder="联系人姓名" />
</view>
<view class="uni-form-item" v-if="settingForm.toSafe === '1'">
<text class="uni-label">联系电话:</text>
<input class="uni-input" v-model="settingForm.safeMobile" placeholder="联系电话" />
</view>
<view class="popup-footer">
<button formType="submit" class="confirm-btn">确认</button>
<button @click="$refs.settingPopup.close()" class="cancel-btn">取消</button>
</view>
</form>
</view>
</uni-popup>
</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: "",
imgUrlPrex:config.baseImageUrl,
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: [],
settingForm:{
id: null,
toSafe: '0',
safeName: null,
safeContact: null,
safeMobile: null,
},
//是否可以点击
canClick:true,
subLoading: false
};
},
onLoad(data) {
this.canOperate = data.canOperate
this.id = data.id
},
onShow(){
this.getTicketWares()
this.getDetail()
},
methods: {
toggleToSafe(e){
this.settingForm.toSafe = e.detail.value ? '1' : '0';
},
doSetting(){
request({
url: '/admin-api/repair/tw/updateSafe',
method: 'post',
data: this.settingForm
}).then(res => {
this.$refs.settingPopup.close()
uni.showToast({
title: '设置成功!',
icon: 'none'
})
})
},
handleSetting(){
request({
url: "/admin-api/repair/tw/getById?id=" + this.id,
method: 'get'
}).then(res => {
const data = res.data
this.settingForm.toSafe = data.toSafe
this.settingForm.safeName = data.safeName
this.settingForm.safeContact = data.safeContact
this.settingForm.safeMobile = data.safeMobile
this.settingForm.id = this.id
this.$refs.settingPopup.open()
})
},
addWares(){
//配件申请
uni.navigateTo({
url: '/pages-repair/apply/applyForm?twId=' + this.id
})
},
/**
* 预览图片
*/
prviewImage(imgList, index) {
let urls = []
imgList.forEach(i => {
urls.push(this.imgUrlPrex+i)
})
uni.previewImage({
urls: urls,
current: index
});
},
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 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/listApp"
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
}
})
},
confirmOpe(type) {
if (!this.subLoading){
this.subLoading = true
if(this.selectWares.length==0){
uni.showToast({
title: '请选中要审核的配件!',
icon: 'none'
})
this.subLoading = false
return
}
if (this.canClick) {
this.canClick = false
let url = '/admin-api/repair/tw/audit'
let dataObj = {
id: this.id,
type: "01",
status: "yes" == type ? "01" : "02"
}
try {
if (this.selectWares && this.selectWares.length > 0) {
dataObj.items = [...this.selectWares.map(item => {
return {
id: item.id
}
})]
} else {
dataObj.items = []
this.repairList.map((groupItem) => {
groupItem.twItemList.map((item) => {
dataObj.items.push({id: item.id})
})
})
}
request({
url: url,
method: 'POST',
data: dataObj
}).then((res) => {
this.canClick = true
if (res.code == 200) {
uni.showToast({
title: '审批成功!',
icon: 'none'
})
setTimeout(() => {
uni.navigateBack()
}, 700)
}
this.subLoading = false
})
} catch (e) {
this.subLoading = false
this.canClick = true
}
}
}
},
}
}
</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: 10rpx;
.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; /* 增加左右边距,使图片距离屏幕边缘有一定距离 */
}
.popup-content {
width: 80%;
max-width: 400px;
background-color: #fff;
padding: 20px;
border-radius: 10px;
margin: auto;
}
.popup-title {
font-size: 18px;
margin-bottom: 20px;
text-align: center;
}
.uni-form-item {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.uni-label {
width: 20rem;
}
.uni-input {
padding: 2px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
height: 2rem;
width: 26rem;
}
.popup-footer {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.confirm-btn, .cancel-btn {
flex: 1;
margin: 0 5px;
height: 40px;
line-height: 40px;
border: none;
border-radius: 5px;
}
.confirm-btn {
background-color: #0174F6;
color: #fff;
}
.cancel-btn {
background-color: #f5f5f5;
color: #666;
}
</style>