Files
sunProduct/src/views/system/cars/addCars.vue
2026-07-21 17:32:22 +08:00

354 lines
11 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>
<div class="AddBuildingBox">
<PageHeader :title="userid ? '编辑车辆信息' : '添加车辆信息'"></PageHeader>
<div class="AddBuildingBody">
<div class="title">基本信息</div>
<div class="addBuildingFormBody">
<el-form class="formBody" label-position="left" ref="formRef" :model="form" :rules="rules" label-width="130px">
<!-- <el-row>
<el-col :span="11">
<el-form-item label="车辆区域" prop="areaId">
<el-select @change="changeAreaList" v-model="form.areaId" placeholder="请选择车辆区域">
<el-option v-for="item in carAreaList" :key="item.id" :label="`${item.areaName}(${item.areaCode})`" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="2"></el-col>
<el-col :span="11">
<el-form-item label="车位编号" prop="parkingId">
<el-select v-model="form.parkingId" placeholder="请选择车位编号">
<el-option v-for="item in parkingList" :key="item.id" :label="item.parkingCode" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row> -->
<el-row>
<el-col :span="11">
<el-form-item label="车牌号" prop="carNum" :validate-event="false">
<!-- <el-input v-model.trim="form.carNum" placeholder="请输入车牌号" /> -->
<LicensePlateInput ref="carNumInputRef" required v-model="form.carNum" @change="() => handleValidate()" />
</el-form-item>
</el-col>
<el-col :span="2"></el-col>
<el-col :span="11">
<el-form-item label="车辆品牌" prop="carBrand">
<el-input v-model.trim="form.carBrand" placeholder="请输入车辆品牌" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="11">
<el-form-item label="车辆型号" prop="carModel">
<el-input v-model.trim="form.carModel" placeholder="请输入补充车辆型号" />
</el-form-item>
</el-col>
<el-col :span="2"></el-col>
<el-col :span="11">
<el-form-item label="车身颜色" prop="carColor">
<el-input v-model.trim="form.carColor" placeholder="请输入车身颜色" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="车辆照片">
<el-upload
class="avatar-uploader"
ref="uploadRef"
accept=".png, .jpg"
:action="uploadUrl"
name="file"
:headers="headerToken()"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img alt="车辆照片" v-if="form.carImageUrl" :src="form.carImageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
<template #tip>
<div style="color: gray; font-size: small">支持jpg, png等格式文件上传</div>
</template>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="持有人">
<AppUser returnable="*" :isMultiple="false" ref="HolderRef" @change="handleChange">
<template #default>
<div class="residentBox" @click="choiceResidentFun">
<div class="defaultBox" v-if="form.userId === ''">
<span>请选择</span>
<el-icon><Search /></el-icon>
</div>
<div v-else class="overflow-auto overflow-hidden w-full text-ellipsis text-nowrap">
<span>姓名:{{ form.userName && form.userName.trim() !== '' ? form.userName : form.residentName }}</span>
</div>
</div>
</template>
</AppUser>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="5" v-model.trim="form.remark" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-form-item style="margin-top: 30px">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="cancelForm">返回</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import LicensePlateInput from '@/components/LicensePlateInput/index.vue';
import Holder from '@/components/Holder/index.vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { listArea } from '@/api/system/carArea';
import { listParking } from '@/api/system/parking';
import { UploadProps, UploadRawFile } from 'element-plus';
import { addCar, getCar, updateCar } from '@/api/system/cars';
import { useUserStore } from '@/store/modules/user';
import AppUser from '@/components/Holder/appUser.vue';
import { Plus } from '@element-plus/icons-vue';
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/car/uploadImage';
const router = useRouter();
const route = useRoute();
const formRef = ref();
const carNumInputRef = ref();
const form = ref({
id: null,
areaId: null, // 区域id
residentId: '', // 车位id
residentName: '', // 持有人姓名
parkingId: null, // 持有人id
carNum: '', //车牌号
carBrand: '', //车辆品牌
carModel: '', //车辆型号
carColor: '', //车身颜色
remark: '', //备注
userId: '',
userName: '',
carImageUrl: '' //车辆图片url
});
const rules = ref({
areaId: [{ required: true, message: '请选择区域', trigger: 'blur' }],
residentId: [{ required: true, message: '请选择', trigger: 'blur' }],
carNum: [
{
required: true,
message: '请输入车牌号码',
trigger: ['blur']
}
],
carBrand: [{ required: true, message: '请输入车辆品牌', trigger: 'blur' }]
});
function handleValidate() {
formRef.value.validateField('carNum');
}
function headerToken() {
const useStore = useUserStore();
return {
Authorization: 'Bearer ' + useStore.token
};
}
const userid = ref('');
const allowImgSuffix = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'heic'];
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
const type = rawFile.type.split('/').pop();
if (allowImgSuffix.includes(type)) {
if (rawFile.size / 1024 / 1024 <= 10) {
return true;
} else {
ElMessage.warning('图片大小超过10M,请重新上传');
return false;
}
} else {
ElMessage.warning('图片格式不是 png/jpg/jpeg 格式, 请重新上传');
return false;
}
};
const handleAvatarSuccess: UploadProps['onSuccess'] = (response: any) => {
form.value.carImageUrl = response.data.url;
};
// 车辆区域
const carAreaList = ref([]);
// 根据车辆区域 动态选择 车位
const parkingList = ref([]);
function init() {
listArea().then((res) => {
carAreaList.value = res.rows;
});
}
init();
if (route.query.id) {
userid.value = route.query.id as string;
form.value.id = userid.value;
getCar(userid.value).then((res) => {
form.value = {
...form.value,
...res.data
};
changeAreaList(res.data.areaId);
});
}
function changeAreaList(val: string) {
listParking({
areaId: val,
pageSize: 9999999,
pageNum: 1
}).then((res) => {
parkingList.value = res.rows;
});
}
// !== 提交 =============================================================================
// 提交
const submitForm = () => {
const plateResult = carNumInputRef.value.validate();
if (!plateResult.valid) {
// 自动聚焦到错误字段
carNumInputRef.value.focus();
return;
}
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (userid.value.trim() !== '') {
updateCar(form.value).then(() => {
ElMessage.success('编辑成功');
cancelForm();
});
} else {
addCar(form.value).then(() => {
ElMessage.success('添加成功');
cancelForm();
});
}
}
});
};
// 推出
const cancelForm = () => {
router.back();
};
const holderInfo = ref(null);
const HolderRef = ref<typeof Holder>(null);
function choiceResidentFun() {
if (form.value.userId && form.value.userId.trim() !== '') {
HolderRef.value.open([form.value.userId]);
} else {
HolderRef.value.open([]);
}
}
// 选择住户
function handleChange(pop) {
holderInfo.value = null;
holderInfo.value = pop;
form.value.userId = '';
form.value.userName = '';
if (pop !== null) {
form.value.userId = pop.user_id;
form.value.userName = pop.user_name;
}
}
</script>
<style scoped lang="scss">
.avatar {
width: 178px;
height: 178px;
vertical-align: center;
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
border-radius: 5px;
border: 1px dashed #ccc;
margin-right: 20px;
text-align: center;
}
.AddBuildingBox {
padding: 15px;
height: 100%;
width: 100%;
}
.AddBuildingBody {
margin-top: 20px;
display: flex;
flex-direction: column;
justify-content: center;
background-color: white;
padding: 15px;
.title {
height: 40px;
line-height: 40px;
padding-left: 20px;
background-color: rgba(255, 255, 255, 1);
color: rgba(16, 16, 16, 1);
border-bottom: 1px solid #bbbbbb;
margin-bottom: 60px;
}
.formBody {
width: 1050px;
margin: 0 auto;
&:deep(.el-form-item__content, .el-select, .el-input) {
width: 350px !important;
margin-right: 10px;
.el-cascader {
width: 100%;
}
}
.el-form-item {
margin-bottom: 20px;
align-items: center;
}
.el-button {
width: 80px;
height: 35px;
margin-right: 20px;
}
}
}
.residentBox {
width: 385px;
height: 35px;
line-height: 35px;
border: 1px solid #ccc;
border-radius: 5px;
padding: 0 10px;
.defaultBox {
display: flex;
align-items: center;
justify-content: space-between;
}
cursor: pointer;
&:hover {
background-color: #f4f8ff;
}
}
</style>