lanan-repair-app/pages-order/addOrder/addOrder.vue
许允枞 56305348d1 1.增加通过车牌号、车架号查询客户信息
2.增加创建工单钱用户签名
2024-10-28 16:37:28 +08:00

718 lines
21 KiB
Vue

<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>
<view class="footer">
<view class="btn" @click="submit">创建工单</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";
export default {
components: {
ProjectPicker,
VNavigationBar,
},
data() {
return {
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 != '') {
this.listUserInfo()
}
},
methods: {
createUniqueCodeByHead(head = '') {
const min = 100; // 最小值
const max = 999; // 最大值
return head.toString() + Date.now().toString() + Math.floor(Math.random() * (max - min + 1)) + min;
},
//新增工单
submit() {
if (this.userInfo === null || this.carList.length === 0 || this.selectedProj.length === 0) {
uni.showToast({
title: '请完善信息',
icon: 'none'
})
return
}
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)
}
uni.navigateTo({
url: '/pages-repair/signature/signature?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
}
request({
url: '/admin-api/base/carMain/page',
method: 'GET',
params: params
}).then(res => {
this.carList = res.data.records
console.log('车列表', this.carList)
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 => {
item.inspectionDate = formatTimestampCustom(item.inspectionDate)
item.insuranceDate = formatTimestampCustom(item.insuranceDate)
item.carRegisterDate = formatTimestampCustom(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) {
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>
.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>