Files
sunProduct/src/views/community/AddCommunity.vue
2026-04-18 18:14:07 +08:00

428 lines
14 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="box">
<div class="header">
<span>智慧物业后台管理系统</span>
<navbar ref="navbarRef" />
</div>
<div class="container AddBuildingBox">
<PageHeader :title="isedit ? '编辑小区' : '添加小区'"> </PageHeader>
<el-form inline class="formBody" ref="formRef" :model="form" :rules="rules" label-width="100px">
<div class="AddBuildingBody">
<div class="title">基本信息</div>
<div class="addBuildingFormBody">
<el-form-item label="小区名称" prop="villageName">
<el-input v-model.trim="form.villageName" placeholder="请输入小区名称" />
</el-form-item>
<el-form-item label="小区编号" prop="villageCode">
<el-input v-model.trim="form.villageCode" placeholder="请输入小区编号" />
</el-form-item>
<el-form-item label="所在城市" prop="city">
<el-cascader :options="pcaTextArrlist" v-model="city" @change="cityChange"> </el-cascader>
</el-form-item>
<el-form-item label="详细地址" prop="buildingArea">
<el-input v-model.trim="form.address" placeholder="请输入详细地址" />
</el-form-item>
<el-form-item label="建成时间" prop="buildingArea">
<el-date-picker v-model="builtTime" type="date" placeholder="选择建成时间" value-format="YYYY-MM-DD" @change="changeBuiltTime" />
</el-form-item>
<el-form-item label="房屋用途" prop="buildingArea">
<el-select v-model="form.houseUse" placeholder="请选择房屋用途" style="width: 240px">
<el-option v-for="item in houseUserList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="小区面积" prop="villageArea">
<el-input v-model.trim.number="form.villageArea" placeholder="请输入小区面积"><template #append>㎡</template> </el-input>
</el-form-item>
<!-- <el-form-item label="小区楼栋" prop="buildingArea">
<el-input v-model="form.buildingArea" placeholder="请输入小区楼栋"><template #append>栋</template> </el-input>
</el-form-item>
<el-form-item label="小区房屋" prop="buildingArea">
<el-input v-model="form.buildingArea" placeholder="请输入小区房屋"><template #append>间</template> </el-input>
</el-form-item>
<el-form-item label="小区面积" prop="buildingArea">
<el-input v-model="form.buildingArea" placeholder="请输入小区面积"><template #append>㎡</template> </el-input>
</el-form-item> -->
<el-form-item label="车位数量" prop="parkingSpaceCount">
<el-input v-model.trim.number="form.parkingSpaceCount" placeholder="请输入车位数量">
<template #append>个</template>
</el-input>
</el-form-item>
<el-form-item style="width: 100%" label="小区图片">
<el-upload
accept=".jpg, .png"
ref="uploadRef"
:action="uploadfileurl"
:headers="headerToken()"
list-type="picture-card"
:file-list="villageImg"
:auto-upload="false"
@change="handleUploadChange"
@before-upload="handleBeforeUpload"
>
<el-icon><Plus /></el-icon>
<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<el-icon><Delete /></el-icon>
</span>
</span>
</div>
</template>
<template #tip>
<div class="el-upload__tip">支持jpg, png等格式文件上传,文件大小不超过10MB,可上传多张</div>
</template>
</el-upload>
</el-form-item>
<el-form-item style="width: 100%" label="小区简介">
<el-input v-model.trim="form.remark" :rows="5" type="textarea" placeholder="小区简介" />
</el-form-item>
</div>
</div>
<div class="AddBuildingBody">
<div class="title">负责人信息</div>
<div class="addBuildingFormBody addBuildingForm_User_Body">
<el-form-item label="姓名">
<el-input v-model.trim="form.manageName" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="电话">
<el-input v-model.trim="form.managePhone" placeholder="请输入电话" />
</el-form-item>
<el-form-item label="微信">
<el-input v-model.trim="form.manageVx" placeholder="请输入微信"> </el-input>
</el-form-item>
<el-form-item label="QQ">
<el-input v-model.trim="form.manageQq" placeholder="请输入QQ"> </el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model.trim="form.manageEmail" placeholder="请输入邮箱"> </el-input>
</el-form-item>
<div class="pl-100px">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="cancelForm">取消</el-button>
</div>
</div>
</div>
</el-form>
</div>
</div>
</template>
<script setup lang="ts">
import Navbar from '@/layout/components/Navbar.vue';
import { ref } from 'vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { pcaTextArr } from 'element-china-area-data';
import type { DataItem } from 'element-china-area-data';
import { useUserStore } from '@/store/modules/user';
import { CascaderValue } from 'element-plus';
import { addVillageAPI, editVillageAPI, getVillageByIdAPI, uploadVillageImageAPI } from '@/api/system/community/index';
import { communitylist_rows_type } from '@/api/system/community/type';
const route = useRoute();
const router = useRouter();
const editId = ref(route.query.id as string);
const isedit = computed(() => Boolean(editId.value));
const apipriex = import.meta.env.VITE_APP_BASE_API;
const uploadfileurl = `${apipriex}/village/uploadImages`;
// 获取省 市 区
const pcaTextArrlist = ref<DataItem[]>(pcaTextArr);
// 获取小区用途
const houseUserList = ref([
{
value: 0,
label: '住宅'
},
{
value: 1,
label: '商住两用'
},
{
value: 2,
label: '商业'
},
{
value: 3,
label: '办公'
}
]);
const formRef = ref();
const uploadRef = ref();
const form = ref<communitylist_rows_type>({
villageId: null,
villageName: '',
villageCode: '',
address: '',
houseUse: null,
villageArea: 0,
remark: '',
parkingSpaceCount: 0,
villageImageUrl: '',
city: '',
status: '0',
choiceStatus: 1, // 0 选择 1未选择
manageName: '',
managePhone: '',
manageVx: '',
manageEmail: '',
manageQq: '',
completDate: ''
});
const builtTime = ref(null);
const city = ref<string[]>([]);
const villageImg = ref([]);
// 表单验证
const rules = ref({
villageName: [{ required: true, message: '请输入小区名称', trigger: 'blur' }],
villageCode: [{ required: true, message: '请输入小区编号', trigger: 'blur' }],
city: [{ required: true, message: '请选择城市', trigger: 'blur' }]
});
/** 获取编辑小区的信息 */
function getCommunityinfo() {
const id = Number(editId.value);
getVillageByIdAPI(id).then((res) => {
city.value = (res.data.city as string).split('/');
if (res.data.villageImageUrl) {
villageImg.value = res.data.villageImageUrl
.split(',')
.filter((item) => item !== '')
.map((item) => {
return {
name: item.split('/').pop(),
url: item
};
});
}
builtTime.value = res.data.completDate.split(' ')[0];
form.value = {
...res.data,
completDate: builtTime.value
};
});
}
if (isedit.value) {
console.log('编辑小区id', editId.value, typeof editId.value, Boolean(editId.value));
getCommunityinfo();
}
// 请求头
function headerToken() {
const useStore = useUserStore();
return {
Authorization: 'Bearer ' + useStore.token
};
}
/** 检测文件大小和格式 */
function handleBeforeUpload(file: UploadFile): Promise<boolean | { file: UploadFile; type: string }> {
return new Promise((resolve, reject) => {
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isLt10M) {
reject({
type: '文件大小错误',
file: file
});
} else if (file.raw.type !== 'image/jpeg' && file.raw.type !== 'image/png') {
reject({
type: '文件类型错误',
file: file
});
} else {
resolve(true);
}
});
}
/** 上传狗子 */
async function handleUploadChange(file: UploadFile) {
const isupload = await handleBeforeUpload(file);
if (typeof isupload === 'object') {
ElMessage.error(isupload.type);
return;
} else if (typeof isupload === 'boolean' && isupload === true) {
villageImg.value.push(file.raw);
}
}
/** 移除钩子 */
const handleRemove = (file: UploadFile) => {
villageImg.value = villageImg.value.filter((item) => item.uid !== file.uid);
};
// 改变时间
const changeBuiltTime = (value: string) => {
form.value.completDate = value;
};
const cityChange = (value: CascaderValue[]) => {
form.value.city = value.join('/');
};
const reg = {
phone: /^1[3-9]\d{9}$/,
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
qq: /^[1-9]\d{4,11}$/,
wechat: /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/
};
// 上传图片
const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 1) 将图片拆分为“新上传文件”和“已有图片URL”
const newFiles: File[] = [];
const existingUrls: string[] = [];
villageImg.value.forEach((item: any) => {
// 新增图片:handleUploadChange push 进来的是 File
if (item instanceof File) {
newFiles.push(item);
return;
}
// 编辑态已有图片:通常是 { name, url } 结构
if (item && typeof item === 'object' && typeof item.url === 'string') {
existingUrls.push(item.url);
return;
}
// 兜底:如果有字符串URL也兼容
if (typeof item === 'string') {
existingUrls.push(item);
}
});
// 2) 没有新文件:不调用上传接口,直接用已有URL提交
if (newFiles.length === 0) {
form.value.villageImageUrl = existingUrls.join(',');
submitFormInfo();
return;
}
// 3) 有新文件:先上传新文件,再与已有URL合并
const formdata = new FormData();
newFiles.forEach((file) => formdata.append('files', file));
uploadVillageImageAPI(formdata).then((res) => {
const uploadedUrls = res.data.map((x) => x.url).filter(Boolean);
// 4) 最终图片 = 已有图片 + 新上传图片(避免覆盖)
form.value.villageImageUrl = [...existingUrls, ...uploadedUrls].join(',');
submitFormInfo();
});
}
});
};
function submitFormInfo() {
if (form.value.managePhone.trim()) {
if (!reg.phone.test(form.value.managePhone)) {
ElMessage.error('请输入正确的手机号码');
return;
}
}
if (form.value.manageVx.trim()) {
if (!reg.wechat.test(form.value.manageVx)) {
ElMessage.error('请输入正确的微信号');
return;
}
}
if (form.value.manageQq.trim()) {
if (!reg.qq.test(form.value.manageQq)) {
ElMessage.error('请输入正确的QQ号码');
return;
}
}
if (form.value.manageEmail.trim()) {
if (!reg.email.test(form.value.manageEmail)) {
ElMessage.error('请输入正确的邮箱号码');
return;
}
}
if (isedit.value) {
console.log('编辑小区提交的数据', form.value);
editVillageAPI<communitylist_rows_type>(form.value).then((res) => {
ElMessage.success('编辑成功');
cancelForm();
});
} else {
addVillageAPI<communitylist_rows_type>(form.value).then((res) => {
ElMessage.success('添加成功');
cancelForm();
});
}
}
const cancelForm = () => {
router.push({
path: '/community'
});
};
</script>
<style scoped lang="scss">
.box {
.header {
display: flex;
align-items: center;
height: 50px;
line-height: 50px;
background-color: #1a75ff;
background-color: #dfedff;
& > div {
flex: 1;
}
& > span {
padding-left: 20px;
font-size: 20px;
color: white;
}
}
}
.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: 50px;
}
.addBuildingFormBody {
width: 900px;
margin: 0 auto;
padding-bottom: 40px;
.el-form-item {
width: 46%;
margin-bottom: 20px;
&:deep(.el-input, .el-date-editor.el-input) {
width: 300px;
}
}
.el-button {
width: 80px;
height: 35px;
margin-right: 20px;
}
}
}
.addBuildingForm_User_Body {
width: 900px;
margin: 0 auto;
.el-button {
width: 80px;
height: 35px;
line-height: 35px;
}
}
</style>