黑马智数Day5
表单校验
表单基础校验
// 1. 创建表单规则
data() {
return {
addRules: {
name: [
{ required: true, message: '企业名称为必填', trigger: 'blur' }
],
legalPerson: [
{ required: true, message: '法人为必填', trigger: 'blur' }
],
registeredAddress: [
{ required: true, message: '注册地址为必填', trigger: 'blur' }
],
industryCode: [
{ required: true, message: '所在行业为必填', trigger: 'change' }
],
contact: [
{ required: true, message: '企业联系人为必填', trigger: 'blur' }
],
contactNumber: [
{ required: true, message: '企业联系人电话为必填', trigger: 'blur' }
],
businessLicenseId: [
{ required: true, message: '请上传营业执照', trigger: 'blur' }
]
}
}
}
// 2. 绑定表单规则
<el-form :model="addForm" :rules="addRules" label-width="100px">
<el-form-item label="企业名称" prop="name">
<el-input v-model="addForm.name" />
</el-form-item>
<el-form-item label="法人" prop="legalPerson">
<el-input v-model="addForm.legalPerson" />
</el-form-item>
<el-form-item label="注册地址" prop="registeredAddress">
<el-input v-model="addForm.registeredAddress" />
</el-form-item>
<el-form-item label="所在行业" prop="industryCode">
<el-select v-model="addForm.industryCode">
<el-option
v-for="item in industryList"
:key="item.industryCode"
:value="item.industryCode"
:label="item.industryName"
/>
</el-select>
</el-form-item>
<el-form-item label="企业联系人" prop="contact">
<el-input v-model="addForm.contact" />
</el-form-item>
<el-form-item label="联系电话" prop="contactNumber">
<el-input v-model="addForm.contactNumber" />
</el-form-item>
<el-form-item label="营业执照" prop="businessLicenseId">
<el-upload
action="#"
:http-request="uploadRequest"
:before-upload="beforeUpload"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">支持扩展名:.png .jpg .jpeg,文件大小不得超过5M</div>
</el-upload>
</el-form-item>
</el-form>
统一校验
<el-form ref="ruleForm"></el-form>
<el-button type="primary" @click="confirmSubmit">确定</el-button>
confirmSubmit() {
this.$refs.ruleForm.validate(valid => {
console.log(valid)
})
}
正则校验手机号
const validatePhone = (rule, value, callback) => {
if (/^1[3-9]\d{9}$/.test(value)) {
callback()
} else {
callback(new Error('请输入正常的手机号'))
}
}
contactNumber: [
{ required: true, message: '企业联系人电话为必填', trigger: 'blur' },
{ validator: validatePhone, trigger: 'blur' }
]
上传完毕单独校验营业执照字段
async uploadRequest(data) {
// 上传逻辑...
// 单独校验表单,清除错误信息
this.$refs.ruleForm.validateField('businessLicenseId')
}
提交表单
封装新增接口
export function createExterpriseAPI(data) {
return request({
url: '/park/enterprise',
method: 'POST',
data
})
}
点击提交
confirmSubmit() {
this.$refs.ruleForm.validate(async valid => {
if (!valid) return
// 1. 调用接口
await createExterpriseAPI(this.addForm)
// 2. 返回列表页
this.$router.back()
})
}
编辑企业
携带参数跳转编辑页
<el-button
size="mini"
type="text"
@click="editRent(scope.row.id)"
>编辑</el-button>
editRent(id) {
this.$router.push({
path: '/exterpriseAdd',
query: {
id
}
})
}
根据id适配文案显示
<el-page-header
:content="`${id?'编辑企业':'添加企业'}`"
@back="$router.back()" />
computed: {
id() {
return this.$route.query.id
}
}
回填企业数据
封装接口
export function getEnterpriseDetailAPI(id) {
return request({
url: `/park/enterprise/${id}`
})
}
调用接口回填数据
async getEnterpriseDetail() {
const res = await getEnterpriseDetailAPI(this.rentId)
const { businessLicenseId, businessLicenseUrl, contact, contactNumber, industryCode, legalPerson, name, registeredAddress } = res.data
this.addForm = { businessLicenseId, businessLicenseUrl, contact, contactNumber, industryCode, legalPerson, name, registeredAddress }
}
mounted() {
// 省略代码 有合同id 调用详情接口
if (this.Id) {
this.getEnterpriseDetail()
}
}
编辑确认修改
封装编辑更新接口
export function updateExterpriseAPI(data) {
return request({
url: '/park/enterprise',
method: 'PUT',
data
})
}
区分状态接口提交
confirmSubmit() {
this.$refs.ruleForm.validate(async valid => {
console.log(valid)
if (this.id) {
// 编辑
await updateExterpriseAPI({
...this.addForm,
id: this.Id
})
} else {
// 新增
await createExterpriseAPI(this.addForm)
}
this.$router.back()
})
}
删除功能实现
封装接口函数
export function delExterpriseAPI(id) {
return request({
url: `/park/enterprise/${id}`,
method: 'DELETE'
})
}
绑定事件执行删除
<el-table-column label="操作">
<template #default="scope">
<el-button size="mini" type="text">添加合同</el-button>
<el-button size="mini" type="text">查看</el-button>
<el-button size="mini" type="text">编辑</el-button>
<el-button size="mini" type="text" @click="delExterprise(scope.row.id)">删除</el-button>
</template>
</el-table-column>
delExterprise(id) {
this.$confirm('确认删除该企业吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async() => {
await delExterpriseAPI(id)
this.getExterpriseList()
this.$message({
type: 'success',
message: '删除成功!'
})
})
}
创建合同
控制弹框打开关闭
<el-button size="mini" type="text" @click="addRent()">添加合同</el-button>
<el-dialog
title="添加合同"
:visible="rentDialogVisible"
width="580px"
@close="closeDialog"
>
<!-- 表单区域 -->
<div class="form-container">
</div>
<template #footer>
<el-button size="mini" @click="closeDialog">取 消</el-button>
<el-button size="mini" type="primary">确 定</el-button>
</template>
</el-dialog>
data(){
return {
rentDialogVisible:false
}
}
methods:{
// 打开
addRent(){
this.rentDialogVisible = true
},
// 关闭
closeDialog(){
this.rentDialogVisible = false
}
}
获取楼宇下拉框数据
封装获取楼宇列表接口
export function getRentBuildListAPI() {
return request({
url: '/park/rent/building'
})
}
打开弹框时调用接口
import { getRentBuildListAPI } from '@/apis/enterprise'
// 打开弹框
async addRent(enterpriseId) {
this.rentDialogVisible = true
// 获取楼宇下拉列表
const res = await getRentBuildListAPI()
this.buildList = res.data
}
渲染下拉列表视图模版
<el-form-item label="租赁楼宇" prop="buildingId">
<el-select v-model="rentForm.buildingId" placeholder="请选择">
<el-option
v-for="item in buildList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
上传合同文件
<el-form-item label="租赁合同" prop="contractId">
<el-upload
action="#"
:http-request="uploadHandle"
>
<el-button size="small" type="primary" plain>上传合同文件</el-button>
<div slot="tip" class="el-upload__tip">支持扩展名:.doc .docx .pdf, 文件大小不超过5M</div>
</el-upload>
</el-form-item
// 上传合同
async uploadHandle(fileData) {
// 1. 处理FormData
const { file } = fileData
const formData = new FormData()
formData.append('file', file)
formData.append('type', 'contract')
// 2. 上传并赋值
const res = await uploadAPI(formData)
const { id, url } = res.data
this.rentForm.contractId = id
this.rentForm.contractUrl = url
// 单独校验表单
this.$refs.addForm.validate('contractId')
}
提交表单创建合同
封装接口
export function createRentAPI(data) {
return request({
url: '/park/enterprise/rent',
method: 'POST',
data
})
}
补充企业id参数
<el-button size="mini" type="text" @click="addRent(row.id)">添加合同</el-button>
// 添加合同
addRent(id) {
this.dialogVisible = true
// 把企业id存入表单对象
this.rentForm.enterpriseId = id
}
处理参数提交表单
// 确认提交
confirmAdd() {
this.$refs.addForm.validate(async valid => {
if (valid) {
const { buildingId, contractId, contractUrl, enterpriseId, type } = this.rentForm
await createRentAPI({
buildingId, contractId, contractUrl, enterpriseId, type,
startTime: this.rentForm.rentTime[0],
endTime: this.rentForm.rentTime[1]
})
// 更新列表
this.getExterpriseList()
// 关闭弹框
this.rentDialogVisible = false
}
})
}
显示合同列表
获取当前合同列表
封装接口函数
export function getRentListAPI(id) {
return request({
url: `/park/enterprise/rent/${id}`
})
}
展开时获取合同数据
/ 1. 绑定事件 & 绑定数据
<el-table style="width: 100%" :data="exterpriseList"
@expand-change="expandHandle">
<el-table-column type="expand">
<template #default="{row}">
<el-table :data="row.rentList">
<el-table-column label="租赁楼宇" width="320" prop="buildingName" />
<el-table-column label="租赁起始时间" prop="startTime" />
<el-table-column label="合同状态" prop="status" />
<el-table-column label="操作" width="180">
<template #default="scope">
<el-button size="mini" type="text">续租</el-button>
<el-button size="mini" type="text">退租</el-button>
<el-button size="mini" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
// 2. 初始化时增加合同数据默认列表
async getExterpriseList() {
const res = await getEnterpriseListAPI(this.params)
this.exterpriseList = res.data.rows.map((item) => {
return {
...item,
rentList: [] // 每一行补充存放合同的列表
}
})
this.total = res.data.total
}
// 3. 只有展开时获取数据并绑定
async expandHandle(row, rows) {
console.log('展开或关闭', row, rows)
const isExpend = rows.find(item => item.id === row.id)
if (isExpend) {
const res = await getRentListAPI(row.id)
// eslint-disable-next-line require-atomic-updates
row.rentList = res.data
}
}
适配合同状态
// 格式化tag类型
formatInfoType(status) {
const MAP = {
0: 'warning',
1: 'success',
2: 'info',
3: 'danger'
}
// return 格式化之后的中文显示
return MAP[status]
}
// 格式化status
formartStatus(type) {
const TYPEMAP = {
0: '待生效',
1: '生效中',
2: '已到期',
3: '已退租'
}
return TYPEMAP[type]
}
<el-table-column label="合同状态">
<template #default="scope">
<el-tag :type="formatInfoType(scope.row.status)">
{{ formatStatus(scope.row.status) }}
</el-tag>
</template>
</el-table-column>
合同退租状态修改
封装接口
export function outRentAPI(rentId) {
return request({
url: `/park/enterprise/rent/${rentId}`,
method: 'PUT'
})
}
修改状态
<el-table-column label="操作" width="180" fixed="right">
<template #default="scope">
<el-button size="mini" type="text" @click="outRent(scope.row.id)">退租</el-button>
<el-button size="mini" type="text" >删除</el-button>
</template>
</el-table-column>
outRent(rentId) {
this.$confirm('确认退租吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async() => {
// 1. 调用接口
await outRentAPI(rentId)
// 2. 重新拉取列表
this.getEnterpriseListAPI()
this.$message({
type: 'success',
message: '退租成功!'
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
适配视图状态
<el-table-column label="操作" width="180" fixed="right">
<template #default="scope">
<el-button size="mini" type="text" :disabled="scope.row.status === 3" @click="outRent(scope.row.id)">退租</el-button>
<el-button size="mini" type="text" :disabled="scope.row.status !== 3">删除</el-button>
</template>
</el-table-column>
查看企业
准备路由
{
path: '/exterpriseDetail',
component: () => import('@/views/park/enterprise/Detail')
}
渲染列表
封装接口
export function getEnterpriseDetail(id) {
return request({
url: `/park/enterprise/${id}`,
method: 'GET'
})
}
渲染数据
<script>
import { getEnterpriseDetail } from '@/apis/enterprise'
export default {
data() {
return {
form: {}
}
},
mounted() {
this.getDetail()
},
methods: {
async getDetail() {
const res = await getEnterpriseDetail(this.$route.query.id)
this.form = res.data
}
}
}
</script>