lanan-repair-app/pages-order/addOrder/addOrder.vue
2024-11-04 14:32:41 +08:00

794 lines
24 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">
<view class="containerBody">
<VNavigationBar background-color="rgba(0,0,0,0)" title="新建工单" title-color="#333"></VNavigationBar>
<view class="body">
<view class="card phone">
<view class="phoneHeader">
<view class="title">查找手机号|车牌号|车架号</view>
<view class="desc">根据手机号查找|车牌号|车架号/建立客户信息</view>
</view>
<view class="phoneBody">
<view class="searchBox">
<input v-model="phone" placeholder="请输入手机号码|车牌号|车架号" type="tel">
</view>
<view class="btn" @click="listUserInfo">
<image class="btnIcon" mode="aspectFit" src="/pages-order/static/search.png"></image>
确认查找
</view>
</view>
</view>
<view class="card" style="padding-bottom: 20rpx">
<view class="carTitle">单据类型</view>
<radio-group @change="handleChange" style="padding: 0 20rpx">
<label v-for="(option, index) in options" :key="index" class="radio-label">
<radio :value="option.value" :checked="option.value === ticketType"/>
<text>{{ option.label }}</text>
</label>
</radio-group>
</view>
<view :class="{ 'none': !carList || carList.length === 0 }" class="card cardInfo carCard">
<template v-if="!carList || carList.length === 0">
<image class="cardNoneIcon" mode="widthFix" src="/pages-order/static/carNoneIcon.png"></image>
<view class="btn">
<image mode="aspectFit" src="/pages-order/static/addIcon.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="editCarInfo()">添加车辆信息</text>
</view>
</template>
<template v-else>
<view class="carTitle">车辆信息</view>
<scroll-view scroll-x="true">
<view class="carListTab">
<view v-for="(item, index) in carList" :key="index" :class="{'active': activeCarIndex === index}"
class="carTabItem" @click="() => activeCarIndex = index">
<image :src="imgUrlPrex + item.logoImg" class="carImage" mode="aspectFit"></image>
<text>{{ item.licenseNumber }}</text>
</view>
<view class="carTabItemNew" @click="editCarInfo()">
<text>+</text>
</view>
</view>
</scroll-view>
<view class="carDetail">
<view class="carHeader">
<image :src="imgUrlPrex + carList[activeCarIndex].logoImg" class="carImage" mode="aspectFill"></image>
<view class="carHeaderRight">
<text class="carNumber">{{ carList[activeCarIndex].licenseNumber }}</text>
<text class="carType">{{
(carList[activeCarIndex].brandStr == null ? '' : carList[activeCarIndex].brandStr) + ' ' + (carList[activeCarIndex].modelStr == null ? '' : carList[activeCarIndex].modelStr)
}}
</text>
</view>
</view>
<view class="carBody">
<view style="display: flex;align-items: center">
<view class="infoItem" style="flex: 1">
<view class="label">车架号</view>
<view class="value">{{ carList[activeCarIndex].vin }}</view>
</view>
<view class="infoItem" style="flex: 1">
<view class="label">发动机号</view>
<view class="value">{{ carList[activeCarIndex].engineNumber }}</view>
</view>
</view>
<view style="display: flex;align-items: center">
<view class="infoItem" style="flex: 1">
<view class="label">年检时间</view>
<view class="value">{{ carList[activeCarIndex].inspectionDate }}</view>
</view>
<view class="infoItem" style="flex: 1">
<view class="label">保险时间</view>
<view class="value">{{ carList[activeCarIndex].insuranceDate }}</view>
</view>
</view>
<view class="infoItem">
<view class="label">注册日期</view>
<view class="value">{{ carList[activeCarIndex].carRegisterDate }}</view>
</view>
</view>
<view class="carFoot">
<image mode="aspectFit" src="/static/icons/edit.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="editCarInfo(activeCarIndex)">修改信息</text>
</view>
</view>
</template>
</view>
<view :class="{ 'none': !userInfo }" class="card cardInfo userCard">
<template v-if="!userInfo">
<image class="cardNoneIcon" mode="widthFix" src="/pages-order/static/userNone.png"></image>
<view class="btn">
<image mode="aspectFit" src="/pages-order/static/addIcon.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="editUserInfo()">添加客户信息</text>
</view>
</template>
<template v-else>
<view class="userTitle">客户信息</view>
<view class="userContainer">
<view style="display: flex;align-items: center">
<view class="infoItem" style="flex: 1">
<text class="label">姓名</text>
<text class="value">{{ userInfo.cusName }}</text>
</view>
<view class="infoItem" style="flex: 1">
<text class="label">性别</text>
<text class="value">{{ userInfo.sex === '1' ? '女' : '男' }}</text>
</view>
</view>
<view style="display: flex;align-items: center">
<view class="infoItem" style="flex: 1">
<text class="label">联系方式</text>
<text class="value">{{ userInfo.phoneNumber }}</text>
</view>
<view class="infoItem" style="flex: 1">
<text class="label">出生年月</text>
<text class="value">{{ userInfo.birthday }}</text>
</view>
</view>
<view class="infoItem">
<text class="label">联系地址</text>
<text class="value">
{{ userInfo.provinceName }} {{ userInfo.cityName }} {{ userInfo.areaName }} {{ userInfo.address }}
</text>
</view>
</view>
<view class="userFoot">
<image mode="aspectFit" src="/static/icons/edit.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="editUserInfo(userInfo)">修改信息</text>
</view>
</template>
</view>
<view :class="{ 'none': !selectedProj || selectedProj.length === 0 }" class="card cardInfo projCard">
<template v-if="!selectedProj || selectedProj.length === 0">
<image class="cardNoneIcon" mode="widthFix" src="/pages-order/static/projectNone.png"></image>
<view class="btn">
<image mode="aspectFit" src="/pages-order/static/addIcon.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="addProj()">添加维修项目</text>
</view>
</template>
<template v-else>
<view class="projTitle">维修项目</view>
<view class="projList">
<view v-for="item in selectedProj" :key="item.id" class="projItem">
{{ item.name }}
</view>
</view>
<view class="projFoot">
<image mode="aspectFit" src="/static/icons/edit.png" style="width: 28rpx;height: 28rpx"></image>
<text @click="addProj(selectedProj)">修改信息</text>
</view>
</template>
</view>
<project-picker ref="proj" @confirm="projConfirm"></project-picker>
</view>
<!-- 普通弹窗---拍照上传 -->
<uni-popup ref="popup" background-color="#fff">
<view class="popup-content">
<view class="dl-avatar-box">
<uni-file-picker :value="fileList" :sizeType="sizeType" @select="afterRead" @delete="deleteFile" limit="9" title="请上传车辆照片最多选择9张图片"></uni-file-picker>
</view>
<button type="primary" @click="submit">保存</button>
</view>
</uni-popup>
<view class="footer">
<view class="btn" @click="submitUpload">创建工单</view>
</view>
</view>
</view>
</template>
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import ProjectPicker from "@/components/projectPicker.vue";
import {bus} from "@/utils/eventBus";
import request from "@/utils/request";
import {getToken, setUserInfo, getUserInfo} from '@/utils/auth.js'
import config from "@/config";
import {formatTimestamp, formatTimestampCustom} from "@/utils/utils";
import upload from "@/utils/upload";
export default {
components: {
ProjectPicker,
VNavigationBar,
},
data() {
return {
//上传的图片数组
fileList: [],
sizeType:['compressed'],
phone: '',
carList: [],
activeCarIndex: 0,
userInfo: null,
selectedProj: [],
typeList: [],
ticketType: '01',
options: [
{label: 'A单', value: '01'},
{label: 'B单', value: '02'}
],
imgUrlPrex: config.baseImageUrl,
ticketNo: '',
}
},
onLoad(data) {
this.ticketNo = this.createUniqueCodeByHead('GD')
if (data.phone) {
this.phone = data.phone
this.listUserInfo()
}
setTimeout(() => {
if (data.carId) {
for (let i = 0; i < this.carList.length; i++) {
if (data.carId == this.carList[i].id) {
this.activeCarIndex = i
break
}
}
}
}, 500)
},
onShow() {
if (this.phone != '') {
setTimeout(() => {
this.listUserInfo()
}, 500)
}
},
methods: {
afterRead(file) {
for (let i = 0; i < file.tempFilePaths.length; i++) {
upload({
url:'/admin-api/infra/file/upload',
filePath: file.tempFilePaths[i]
}).then((res)=>{
this.fileList.push({
url: config.baseImageUrl+res.data
})
console.log(this.fileList)
})
}
},
deleteFile(file, index) {
this.fileList.splice(index, 1);
},
saveWorkingItem(){
console.log(this.fileList,145)
},
createUniqueCodeByHead(head = '') {
const min = 100; // 最小值
const max = 999; // 最大值
return head.toString() + Date.now().toString() + Math.floor(Math.random() * (max - min + 1)) + min;
},
/**
* 创建工单前上传图片
*/
submitUpload(){
if (this.userInfo === null || this.carList.length === 0 || this.selectedProj.length === 0) {
uni.showToast({
title: '请完善信息',
icon: 'none'
})
return
}
this.$refs.popup.open("bottom");
},
//新增工单
submit() {
let fileStr = this.fileList.map(item=>item.url.replace(config.baseImageUrl,"")).join(",")
const data = {
userId: this.userInfo.id,
ticketNo: this.ticketNo,
userName: this.userInfo.cusName,
userMobile: this.userInfo.phoneNumber,
carId: this.carList[this.activeCarIndex].id,
carNo: this.carList[this.activeCarIndex].licenseNumber,
carVin: this.carList[this.activeCarIndex].vin,
carBrandId: this.carList[this.activeCarIndex].carBrand,
carBrandName: this.carList[this.activeCarIndex].brandStr,
carBrandType: this.carList[this.activeCarIndex].brandType,
adviserId: getUserInfo().id,
adviserName: getUserInfo().nickname,
ticketType: this.ticketType,
itemList: this.formatItem(this.selectedProj),
fileStr:fileStr
}
uni.navigateTo({
// url: '/pages-repair/signature/signature?data=' + JSON.stringify(data)
url: '/pages-repair/sign/sign?data=' + JSON.stringify(data)
})
// request({
// url: '/admin-api/repair/tickets/create',
// method: 'POST',
// data: {
// userId: this.userInfo.id,
// ticketNo: this.ticketNo,
// userName: this.userInfo.cusName,
// userMobile: this.userInfo.phoneNumber,
// carId: this.carList[this.activeCarIndex].id,
// carNo: this.carList[this.activeCarIndex].licenseNumber,
// carVin: this.carList[this.activeCarIndex].vin,
// carBrandId: this.carList[this.activeCarIndex].carBrand,
// carBrandName: this.carList[this.activeCarIndex].brandStr,
// carBrandType: this.carList[this.activeCarIndex].brandType,
// adviserId: getUserInfo().id,
// adviserName: getUserInfo().nickname,
// ticketType: this.ticketType,
// itemList: this.formatItem(this.selectedProj)
// }
// }).then(res => {
// uni.showToast({
// title: '创建成功',
// icon: 'success'
// })
// uni.navigateTo({
// url: `/pages-order/orderDetail/orderDetail?id=${res.data.id}&isDetail=0`
// });
// })
},
listUserInfo() {
this.carList = []
this.userInfo = null
this.activeCarIndex = 0
if (this.phone != '') {
const params = {
phoneOrCar: this.phone
}
request({
url: '/admin-api/base/custom/page',
method: 'GET',
params: params
}).then(res => {
if (res.data.records.length > 0) {
this.userInfo = res.data.records[0]
this.getCarList()
}
})
} else {
uni.showToast({
title: '请输入手机号|车牌号|车架号',
icon: 'none'
})
}
},
// 子表信息预处理
formatItem(list) {
if (!(list && list.length > 0)) {
return []
}
return list.map(item => {
const temp = {
...item,
itemName: item.name,
itemCount: 1,
itemUnit: item.unit,
itemPrice: item.price,
itemMoney: item.price,
itemTypeId: item.type,
remark: item.remark,
itemStatus: item.itemStatus,
itemType: "01",
projectId: item.id,
id: null
}
return temp;
})
},
handleChange(event) {
this.ticketType = event.detail.value;
},
getCarList() {
const params = {
userId: this.userInfo.userId,
pageNo: 1,
pageSize: 100000
}
request({
url: '/admin-api/base/carMain/page',
method: 'GET',
params: params
}).then(res => {
this.carList = res.data.records
for (let i = 0; i < this.carList.length; i++) {
if (this.carList[i].licenseNumber.toLowerCase() == this.phone.toLowerCase()) {
this.activeCarIndex = i
break
} else if (this.carList[i].vin.toLowerCase() == this.phone.toLowerCase()) {
this.activeCarIndex = i
break
}
}
//将时间戳转换
this.carList.forEach(item => {
if (item.inspectionDate) {
item.inspectionDate = formatTimestampCustom(item.inspectionDate)
}else {
item.inspectionDate = ''
}
if (item.insuranceDate) {
item.insuranceDate = formatTimestampCustom(item.insuranceDate)
}else {
item.insuranceDate = ''
}
if (item.carRegisterDate) {
item.carRegisterDate = formatTimestampCustom(item.carRegisterDate)
}else {
item.carRegisterDate = ''
}
})
})
},
editCarInfo(index) {
bus.$off('updateCarInfo')
bus.$on('updateCarInfo', (carInfo) => {
if (index) {
this.carList[index] = carInfo
} else {
this.carList.push(carInfo)
}
})
if (this.userInfo == null) {
//弹窗提示请选择客户
uni.showToast({
title: '请先选择客户',
icon: 'none'
})
} else {
uni.navigateTo({
url: `/pages/myCar/carDetail?car=${index >= 0 ? encodeURIComponent(JSON.stringify(this.carList[index])) : ''}&userInfo=${encodeURIComponent(JSON.stringify(this.userInfo))}`
});
}
},
editUserInfo(userInfo) {
if (this.phone == '') return uni.showToast({
title: '请先输入手机号,再添加客户',
icon: 'none'
})
bus.$off('updateUserInfo')
bus.$on('updateUserInfo', (userInfo) => {
this.userInfo = userInfo
})
uni.navigateTo({
url: `/pages/userInfo/editUserInfo?userInfo=${userInfo ? encodeURIComponent(JSON.stringify(userInfo)) : ''}`
})
},
addProj(projList = []) {
this.$refs.proj.open(projList)
},
projConfirm(proj) {
this.selectedProj = proj
}
}
}
</script>
<style lang="less" scoped>
.popup-content {
@include flex;
align-items: center;
justify-content: center;
padding: 15px;
height: auto;
background-color: #fff;
}
.container {
height: 100%;
background-color: #F3F5F7;
.containerBody {
height: 100%;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #C1DEFF 0%, rgba(193, 222, 255, 0) 100%);
background-size: 100% 500rpx;
background-repeat: no-repeat;
}
.body {
flex: 1;
height: 0;
overflow: auto;
.card {
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
margin: 20rpx 32rpx;
}
.phone {
background: #0174F6;
.phoneHeader {
padding: 20rpx 30rpx;
.title {
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
margin-bottom: 10rpx;
}
.desc {
font-weight: 500;
font-size: 24rpx;
color: rgba(255, 255, 255, 0.7);
}
}
.phoneBody {
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding: 0 30rpx;
.searchBox {
padding: 40rpx 0;
border-bottom: 1rpx solid #EEEEEE;
}
.btn {
padding: 40rpx 0;
display: flex;
align-items: center;
justify-content: center;
column-gap: 10rpx;
font-weight: 500;
font-size: 32rpx;
color: #0174F6;
.btnIcon {
width: 32rpx;
height: 32rpx;
}
}
}
}
.cardInfo {
&.none {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
.cardNoneIcon {
width: 336rpx;
}
.btn {
position: absolute;
bottom: 40rpx;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
column-gap: 10rpx;
font-weight: 500;
font-size: 28rpx;
color: #0174F6;
}
}
}
.projTitle, .userTitle, .carTitle {
padding: 30rpx;
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
.carCard {
.carListTab {
display: flex;
align-items: center;
column-gap: 32rpx;
padding: 0 26rpx 22rpx;
.carTabItem {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 10rpx;
font-weight: 500;
font-size: 24rpx;
color: #333333;
&.active {
.carImage {
border: 2rpx solid #0174F6;
}
color: #0174F6;
}
.carImage {
width: 128rpx;
height: 80rpx;
background: #F2F2F7;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
}
.carTabItemNew {
display: flex;
flex-direction: column;
align-items: center;
row-gap: 10rpx;
font-weight: 500;
font-size: 24rpx;
color: #333333;
border: 2rpx solid #0174F6; /* 默认边框颜色为透明 */
justify-content: center; /* 垂直居中 */
font-weight: bold;
font-size: 32rpx;
padding: 10rpx; /* 可以根据需要调整内边距 */
width: 128rpx; /* 与 .carImage 宽度一致 */
height: 80rpx; /* 与 .carImage 高度一致 */
border-radius: 8rpx 8rpx 8rpx 8rpx;
margin-top: -37rpx;
}
}
.carDetail {
background: linear-gradient(180deg, rgba(1, 116, 246, 0.15) 0%, rgba(255, 255, 255, 0) 100%) no-repeat;
background-size: 100% 184rpx;
padding: 30rpx 30rpx 0;
.carHeader {
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
column-gap: 20rpx;
padding-bottom: 30rpx;
.carImage {
width: 192rpx;
height: 120rpx;
background: #F2F2F7;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
.carHeaderRight {
display: flex;
flex-direction: column;
row-gap: 20rpx;
font-weight: bold;
font-size: 32rpx;
color: #333333;
.carType {
font-weight: 500;
font-size: 28rpx;
color: #858BA0;
}
}
}
.carBody {
display: flex;
flex-direction: column;
row-gap: 30rpx;
padding-top: 30rpx;
border-top: 1rpx solid #DDDDDD;
}
.carFoot {
}
}
}
.projCard {
.projList {
padding: 0 30rpx;
display: flex;
gap: 20rpx;
flex-wrap: wrap;
.projItem {
padding: 10rpx 16rpx;
border-radius: 4rpx 4rpx 4rpx 4rpx;
border: 2rpx solid #0174F6;
font-weight: 500;
font-size: 24rpx;
color: #0174F6;
}
}
}
.userCard {
.userContainer {
display: flex;
flex-direction: column;
row-gap: 30rpx;
margin: 0 30rpx;
}
}
.infoItem {
display: flex;
flex-direction: column;
.label {
font-weight: 500;
font-size: 28rpx;
color: #858BA0;
}
.value {
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
}
.projFoot, .userFoot, .carFoot {
padding: 30rpx;
font-weight: 500;
font-size: 28rpx;
color: #0174F6;
display: flex;
align-items: center;
justify-content: center;
column-gap: 6rpx;
}
}
.footer {
height: 136rpx;
background: #FFFFFF;
border-radius: 0rpx 0rpx 0rpx 0rpx;
display: flex;
align-items: center;
justify-content: center;
.btn {
width: 510rpx;
height: 76rpx;
background: #0174F6;
border-radius: 38rpx 38rpx 38rpx 38rpx;
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
}
}
.radio-label {
//display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.radio-label text {
margin-left: 10rpx;
}
}
</style>