|
|
@@ -0,0 +1,665 @@
|
|
|
+<template>
|
|
|
+ <div class="add-container">
|
|
|
+ <el-dialog v-model="dialogVisible" title="新建" width="800px" :close-on-click-modal="false" @close="handleClose">
|
|
|
+ <el-form ref="formRef" :model="formData" :rules="rules" label-width="140px" label-position="right">
|
|
|
+ <!-- 需求标题 -->
|
|
|
+ <el-form-item label="需求标题" prop="requirementTitle" required>
|
|
|
+ <el-input v-model="formData.requirementTitle" placeholder="请输入" maxlength="100" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 装修类型 -->
|
|
|
+ <el-form-item label="装修类型" prop="renovationType">
|
|
|
+ <el-radio-group v-model="formData.renovationType">
|
|
|
+ <el-radio :label="1">新房装修</el-radio>
|
|
|
+ <el-radio :label="2">旧房改造</el-radio>
|
|
|
+ <el-radio :label="3">局部装修</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 房屋面积 -->
|
|
|
+ <el-form-item label="房屋面积(㎡)" prop="houseArea" required>
|
|
|
+ <el-input-number
|
|
|
+ v-model="formData.houseArea"
|
|
|
+ :min="0"
|
|
|
+ :max="99999"
|
|
|
+ :precision="2"
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 装修预算 -->
|
|
|
+ <el-form-item label="装修预算(万元)" prop="renovationBudget" required>
|
|
|
+ <el-input-number
|
|
|
+ v-model="formData.renovationBudget"
|
|
|
+ :min="0"
|
|
|
+ :max="99999"
|
|
|
+ :precision="2"
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 详细需求 -->
|
|
|
+ <el-form-item label="详细需求" prop="detailedRequirement">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.detailedRequirement"
|
|
|
+ type="textarea"
|
|
|
+ :rows="4"
|
|
|
+ placeholder="请输入"
|
|
|
+ maxlength="500"
|
|
|
+ show-word-limit
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 期望装修时间 -->
|
|
|
+ <el-form-item label="期望装修时间" prop="expectedRenovationTime" required>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.expectedRenovationTime"
|
|
|
+ type="date"
|
|
|
+ placeholder="请选择"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 上传房屋图纸 -->
|
|
|
+ <el-form-item label="上传房屋图纸" prop="attachmentUrls" required>
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ action="#"
|
|
|
+ list-type="picture-card"
|
|
|
+ :limit="9"
|
|
|
+ :on-preview="handlePictureCardPreview"
|
|
|
+ :on-remove="handleRemove"
|
|
|
+ :on-exceed="handleExceed"
|
|
|
+ :before-upload="beforeUpload"
|
|
|
+ :http-request="handleImageUpload"
|
|
|
+ accept="image/*"
|
|
|
+ multiple
|
|
|
+ >
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
+ </el-upload>
|
|
|
+ <div class="upload-tip">({{ fileList.length }}/9)</div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 联系人 -->
|
|
|
+ <el-form-item label="联系人" prop="contactName" required>
|
|
|
+ <el-input v-model="formData.contactName" placeholder="请输入" maxlength="50" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 联系电话 -->
|
|
|
+ <el-form-item label="联系电话" prop="contactPhone" required>
|
|
|
+ <el-input v-model="formData.contactPhone" placeholder="请输入" maxlength="20" clearable />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 所在城市 -->
|
|
|
+ <el-form-item label="所在城市" prop="city" required>
|
|
|
+ <el-input
|
|
|
+ v-model="formData.city"
|
|
|
+ placeholder="请选择"
|
|
|
+ readonly
|
|
|
+ @click="showCityDialog = true"
|
|
|
+ clearable
|
|
|
+ @clear="handleCityClear"
|
|
|
+ >
|
|
|
+ <template #suffix>
|
|
|
+ <el-icon class="cursor-pointer" @click="showCityDialog = true"><ArrowDown /></el-icon>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 详细地址 -->
|
|
|
+ <el-form-item label="详细地址" prop="detailedAddress">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.detailedAddress"
|
|
|
+ type="textarea"
|
|
|
+ :rows="3"
|
|
|
+ placeholder="请输入"
|
|
|
+ maxlength="200"
|
|
|
+ show-word-limit
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 服务协议确认 -->
|
|
|
+ <el-form-item prop="agreementConfirmed">
|
|
|
+ <el-checkbox v-model="formData.agreementConfirmed" :true-label="1" :false-label="0">
|
|
|
+ 我已阅读并同意
|
|
|
+ <el-link type="primary" :underline="false" @click="handleShowAgreement">《用户服务协议》</el-link>
|
|
|
+ 和
|
|
|
+ <el-link type="primary" :underline="false" @click="handleShowPrivacy">《隐私政策》</el-link>
|
|
|
+ ,允许装修商家查看我的需求信息并与我联系
|
|
|
+ </el-checkbox>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="handleClose">返回</el-button>
|
|
|
+ <el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 城市选择对话框 -->
|
|
|
+ <el-dialog v-model="showCityDialog" title="选择城市" width="600px">
|
|
|
+ <div class="city-selector">
|
|
|
+ <el-select
|
|
|
+ v-model="selectedProvince"
|
|
|
+ placeholder="请选择省"
|
|
|
+ clearable
|
|
|
+ style="width: 100%; margin-bottom: 10px"
|
|
|
+ @change="handleProvinceChange"
|
|
|
+ >
|
|
|
+ <el-option v-for="province in provinceOptions" :key="province.adcode" :label="province.name" :value="province.adcode" />
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="selectedCity"
|
|
|
+ placeholder="请选择市"
|
|
|
+ clearable
|
|
|
+ style="width: 100%; margin-bottom: 10px"
|
|
|
+ :disabled="!selectedProvince"
|
|
|
+ @change="handleCitySelect"
|
|
|
+ >
|
|
|
+ <el-option v-for="city in cityOptions" :key="city.adcode" :label="city.name" :value="city.adcode" />
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="selectedDistrict"
|
|
|
+ placeholder="请选择区"
|
|
|
+ clearable
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="!selectedCity"
|
|
|
+ @change="handleDistrictSelect"
|
|
|
+ >
|
|
|
+ <el-option v-for="district in districtOptions" :key="district.adcode" :label="district.name" :value="district.adcode" />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="showCityDialog = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="handleConfirmCity">确定</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 图片预览 -->
|
|
|
+ <el-image-viewer
|
|
|
+ v-if="imageViewerVisible"
|
|
|
+ :url-list="imageViewerUrlList"
|
|
|
+ :initial-index="imageViewerInitialIndex"
|
|
|
+ @close="imageViewerVisible = false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts" name="decorationAdd">
|
|
|
+import { ref, reactive, onMounted } from "vue";
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
+import { ElMessage, type FormInstance, type UploadFile, type UploadProps, type UploadRequestOptions } from "element-plus";
|
|
|
+import { Plus, ArrowDown } from "@element-plus/icons-vue";
|
|
|
+import { saveOrUpdateDecoration, getDistrict, uploadDecorationImage } from "@/api/modules/storeDecoration";
|
|
|
+import { localGet } from "@/utils";
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+const dialogVisible = ref(true);
|
|
|
+const formRef = ref<FormInstance>();
|
|
|
+const submitLoading = ref(false);
|
|
|
+
|
|
|
+const formData = reactive({
|
|
|
+ requirementTitle: "",
|
|
|
+ renovationType: 1,
|
|
|
+ houseArea: null as number | null,
|
|
|
+ renovationBudget: null as number | null,
|
|
|
+ detailedRequirement: "",
|
|
|
+ expectedRenovationTime: "",
|
|
|
+ attachmentUrls: [] as string[],
|
|
|
+ contactName: "",
|
|
|
+ contactPhone: "",
|
|
|
+ city: "",
|
|
|
+ cityAdcode: "",
|
|
|
+ detailedAddress: "",
|
|
|
+ agreementConfirmed: 0,
|
|
|
+ storeId: localGet("createdId") || 0
|
|
|
+});
|
|
|
+
|
|
|
+const fileList = ref<UploadFile[]>([]);
|
|
|
+const imageViewerVisible = ref(false);
|
|
|
+const imageViewerUrlList = ref<string[]>([]);
|
|
|
+const imageViewerInitialIndex = ref(0);
|
|
|
+
|
|
|
+// 城市选择相关
|
|
|
+const showCityDialog = ref(false);
|
|
|
+const selectedProvince = ref("");
|
|
|
+const selectedCity = ref("");
|
|
|
+const selectedDistrict = ref("");
|
|
|
+const provinceOptions = ref<any[]>([]);
|
|
|
+const cityOptions = ref<any[]>([]);
|
|
|
+const districtOptions = ref<any[]>([]);
|
|
|
+const selectedProvinceName = ref("");
|
|
|
+const selectedCityName = ref("");
|
|
|
+const selectedDistrictName = ref("");
|
|
|
+
|
|
|
+// 表单验证规则
|
|
|
+const rules = reactive({
|
|
|
+ requirementTitle: [{ required: true, message: "请输入需求标题", trigger: "blur" }],
|
|
|
+ houseArea: [{ required: true, message: "请输入房屋面积", trigger: "blur" }],
|
|
|
+ renovationBudget: [{ required: true, message: "请输入装修预算", trigger: "blur" }],
|
|
|
+ expectedRenovationTime: [{ required: true, message: "请选择期望装修时间", trigger: "change" }],
|
|
|
+ attachmentUrls: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ // 检查所有文件是否都已上传成功
|
|
|
+ const successFiles = fileList.value.filter((file: UploadFile) => file.status === "success");
|
|
|
+ if (successFiles.length === 0) {
|
|
|
+ callback(new Error("请上传房屋图纸"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ contactName: [{ required: true, message: "请输入联系人", trigger: "blur" }],
|
|
|
+ contactPhone: [
|
|
|
+ { required: true, message: "请输入联系电话", trigger: "blur" },
|
|
|
+ { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ city: [{ required: true, message: "请选择所在城市", trigger: "change" }],
|
|
|
+ agreementConfirmed: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (formData.agreementConfirmed !== 1) {
|
|
|
+ callback(new Error("请阅读并同意用户服务协议和隐私政策"));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+});
|
|
|
+
|
|
|
+// 获取省份数据
|
|
|
+const getProvinceData = async () => {
|
|
|
+ try {
|
|
|
+ const res: any = await getDistrict();
|
|
|
+ if (res && res.data && res.data.districts && Array.isArray(res.data.districts) && res.data.districts.length > 0) {
|
|
|
+ const chinaData = res.data.districts[0];
|
|
|
+ if (chinaData && chinaData.districts && Array.isArray(chinaData.districts)) {
|
|
|
+ provinceOptions.value = chinaData.districts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取省份数据失败:", error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 省份变化时获取城市数据
|
|
|
+const handleProvinceChange = async (provinceCode: string) => {
|
|
|
+ selectedCity.value = "";
|
|
|
+ selectedDistrict.value = "";
|
|
|
+ cityOptions.value = [];
|
|
|
+ districtOptions.value = [];
|
|
|
+ selectedCityName.value = "";
|
|
|
+ selectedDistrictName.value = "";
|
|
|
+
|
|
|
+ if (!provinceCode) {
|
|
|
+ selectedProvinceName.value = "";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const province = provinceOptions.value.find(p => p.adcode === provinceCode);
|
|
|
+ selectedProvinceName.value = province ? province.name : "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res: any = await getDistrict({ adCode: provinceCode });
|
|
|
+ if (res && res.data && res.data.districts && Array.isArray(res.data.districts) && res.data.districts.length > 0) {
|
|
|
+ const provinceData = res.data.districts[0];
|
|
|
+ if (provinceData && provinceData.districts && Array.isArray(provinceData.districts)) {
|
|
|
+ cityOptions.value = provinceData.districts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取城市数据失败:", error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 城市变化时获取区县数据
|
|
|
+const handleCitySelect = async (cityCode: string) => {
|
|
|
+ selectedDistrict.value = "";
|
|
|
+ districtOptions.value = [];
|
|
|
+ selectedDistrictName.value = "";
|
|
|
+
|
|
|
+ if (!cityCode) {
|
|
|
+ selectedCityName.value = "";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const city = cityOptions.value.find(c => c.adcode === cityCode);
|
|
|
+ selectedCityName.value = city ? city.name : "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res: any = await getDistrict({ adCode: cityCode });
|
|
|
+ if (res && res.data && res.data.districts && Array.isArray(res.data.districts) && res.data.districts.length > 0) {
|
|
|
+ const cityData = res.data.districts[0];
|
|
|
+ if (cityData && cityData.districts && Array.isArray(cityData.districts)) {
|
|
|
+ districtOptions.value = cityData.districts;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("获取区县数据失败:", error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 区县选择
|
|
|
+const handleDistrictSelect = (districtCode: string) => {
|
|
|
+ if (!districtCode) {
|
|
|
+ selectedDistrictName.value = "";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const district = districtOptions.value.find(d => d.adcode === districtCode);
|
|
|
+ selectedDistrictName.value = district ? district.name : "";
|
|
|
+};
|
|
|
+
|
|
|
+// 确认城市选择
|
|
|
+const handleConfirmCity = () => {
|
|
|
+ if (!selectedProvince.value || !selectedCity.value) {
|
|
|
+ ElMessage.warning("请至少选择省和市");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 构建城市名称:省+市+区(如果有区)
|
|
|
+ let cityName = selectedProvinceName.value + selectedCityName.value;
|
|
|
+ if (selectedDistrictName.value) {
|
|
|
+ cityName += selectedDistrictName.value;
|
|
|
+ }
|
|
|
+ formData.city = cityName;
|
|
|
+ formData.cityAdcode = selectedDistrict.value || selectedCity.value || selectedProvince.value;
|
|
|
+ showCityDialog.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+// 清除城市选择
|
|
|
+const handleCityClear = () => {
|
|
|
+ formData.city = "";
|
|
|
+ formData.cityAdcode = "";
|
|
|
+ selectedProvince.value = "";
|
|
|
+ selectedCity.value = "";
|
|
|
+ selectedDistrict.value = "";
|
|
|
+ selectedProvinceName.value = "";
|
|
|
+ selectedCityName.value = "";
|
|
|
+ selectedDistrictName.value = "";
|
|
|
+ cityOptions.value = [];
|
|
|
+ districtOptions.value = [];
|
|
|
+};
|
|
|
+
|
|
|
+// 图片上传前验证
|
|
|
+const beforeUpload: UploadProps["beforeUpload"] = (rawFile: File) => {
|
|
|
+ const isImage = rawFile.type.startsWith("image/");
|
|
|
+ const isLt10M = rawFile.size / 1024 / 1024 < 10;
|
|
|
+
|
|
|
+ if (!isImage) {
|
|
|
+ ElMessage.error("只能上传图片文件!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!isLt10M) {
|
|
|
+ ElMessage.error("图片大小不能超过 10MB!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+// 图片上传 - 点击加号时调用 /file/uploadMore 接口
|
|
|
+const handleImageUpload = async (options: UploadRequestOptions) => {
|
|
|
+ // 获取文件对象,可能是 options.file 或 options.file.raw
|
|
|
+ const file = options.file.raw || options.file;
|
|
|
+
|
|
|
+ if (!file) {
|
|
|
+ console.error("文件对象不存在");
|
|
|
+ ElMessage.error("文件对象不存在");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log("开始上传文件:", file.name, "类型:", file.type, "大小:", file.size);
|
|
|
+
|
|
|
+ const uploadFormData = new FormData();
|
|
|
+ uploadFormData.append("file", file);
|
|
|
+
|
|
|
+ options.file.status = "uploading";
|
|
|
+ options.file.percentage = 0;
|
|
|
+
|
|
|
+ try {
|
|
|
+ console.log("调用 /alienStore/file/uploadMore 接口上传文件");
|
|
|
+ // 调用 /alienStore/file/uploadMore 接口上传文件
|
|
|
+ const result: any = await uploadDecorationImage(uploadFormData);
|
|
|
+ console.log("上传接口返回结果:", result);
|
|
|
+
|
|
|
+ if (result?.code === 200 || result?.code === 0) {
|
|
|
+ let fileUrl = "";
|
|
|
+
|
|
|
+ // 处理不同的返回格式
|
|
|
+ if (Array.isArray(result.data) && result.data.length > 0) {
|
|
|
+ fileUrl = result.data[0];
|
|
|
+ } else if (typeof result.data === "string") {
|
|
|
+ fileUrl = result.data;
|
|
|
+ } else if (result.data?.fileUrl) {
|
|
|
+ fileUrl = result.data.fileUrl;
|
|
|
+ } else if (result.data?.url) {
|
|
|
+ fileUrl = result.data.url;
|
|
|
+ } else if (result.fileUrl) {
|
|
|
+ fileUrl = result.fileUrl;
|
|
|
+ } else if (result.url) {
|
|
|
+ fileUrl = result.url;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fileUrl) {
|
|
|
+ options.file.status = "success";
|
|
|
+ options.file.percentage = 100;
|
|
|
+ options.file.url = fileUrl;
|
|
|
+ options.file.response = { url: fileUrl };
|
|
|
+
|
|
|
+ // 获取图片路径后,记录到 attachmentUrls 数组中,提交时会传递给保存接口
|
|
|
+ if (!formData.attachmentUrls.includes(fileUrl)) {
|
|
|
+ formData.attachmentUrls.push(fileUrl);
|
|
|
+ console.log("文件上传成功,路径已记录:", fileUrl);
|
|
|
+ console.log("当前附件列表:", formData.attachmentUrls);
|
|
|
+ }
|
|
|
+ options.onSuccess?.(result);
|
|
|
+ // 触发表单验证
|
|
|
+ formRef.value?.validateField("attachmentUrls");
|
|
|
+ } else {
|
|
|
+ console.error("上传接口返回数据格式错误:", result);
|
|
|
+ throw new Error("上传接口返回数据格式错误");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new Error(result?.msg || result?.message || "文件上传失败");
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ console.error("文件上传失败:", error);
|
|
|
+ options.file.status = "fail";
|
|
|
+ if (options.file.url && options.file.url.startsWith("blob:")) {
|
|
|
+ URL.revokeObjectURL(options.file.url);
|
|
|
+ }
|
|
|
+ const index = fileList.value.findIndex(f => f.uid === options.file.uid);
|
|
|
+ if (index > -1) {
|
|
|
+ fileList.value.splice(index, 1);
|
|
|
+ }
|
|
|
+ ElMessage.error(error?.message || "文件上传失败");
|
|
|
+ options.onError?.(error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 图片预览
|
|
|
+const handlePictureCardPreview = (file: UploadFile) => {
|
|
|
+ if (file.url) {
|
|
|
+ imageViewerUrlList.value = fileList.value.map((item: UploadFile) => item.url || "").filter(Boolean);
|
|
|
+ imageViewerInitialIndex.value = fileList.value.findIndex((item: UploadFile) => item.uid === file.uid);
|
|
|
+ imageViewerVisible.value = true;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 删除图片
|
|
|
+const handleRemove = (file: UploadFile) => {
|
|
|
+ if (file.url) {
|
|
|
+ const index = formData.attachmentUrls.indexOf(file.url);
|
|
|
+ if (index > -1) {
|
|
|
+ formData.attachmentUrls.splice(index, 1);
|
|
|
+ console.log("删除图片,路径已移除:", file.url);
|
|
|
+ console.log("当前附件列表:", formData.attachmentUrls);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 触发表单验证
|
|
|
+ formRef.value?.validateField("attachmentUrls");
|
|
|
+};
|
|
|
+
|
|
|
+// 超出限制
|
|
|
+const handleExceed = () => {
|
|
|
+ ElMessage.warning("最多只能上传9张图片");
|
|
|
+};
|
|
|
+
|
|
|
+// 显示服务协议
|
|
|
+const handleShowAgreement = () => {
|
|
|
+ // TODO: 打开服务协议页面
|
|
|
+ ElMessage.info("服务协议");
|
|
|
+};
|
|
|
+
|
|
|
+// 显示隐私政策
|
|
|
+const handleShowPrivacy = () => {
|
|
|
+ // TODO: 打开隐私政策页面
|
|
|
+ ElMessage.info("隐私政策");
|
|
|
+};
|
|
|
+
|
|
|
+// 提交表单
|
|
|
+const handleSubmit = async () => {
|
|
|
+ if (!formRef.value) return;
|
|
|
+
|
|
|
+ await formRef.value.validate(async valid => {
|
|
|
+ if (!valid) return;
|
|
|
+
|
|
|
+ submitLoading.value = true;
|
|
|
+ try {
|
|
|
+ // 确保 attachmentUrls 是数组格式,包含所有上传成功的图片路径
|
|
|
+ const attachmentUrlsList = Array.isArray(formData.attachmentUrls)
|
|
|
+ ? formData.attachmentUrls.filter(url => url && url.trim() !== "")
|
|
|
+ : [];
|
|
|
+
|
|
|
+ console.log("提交时的附件列表:", attachmentUrlsList);
|
|
|
+
|
|
|
+ // 构建提交参数 - attachmentUrls 字段存储图片路径数组
|
|
|
+ const params: any = {
|
|
|
+ id: 0, // 新建时传0
|
|
|
+ requirementTitle: formData.requirementTitle,
|
|
|
+ renovationType: formData.renovationType,
|
|
|
+ houseArea: formData.houseArea || 0,
|
|
|
+ renovationBudget: formData.renovationBudget || 0,
|
|
|
+ detailedRequirement: formData.detailedRequirement || "",
|
|
|
+ expectedRenovationTime: formData.expectedRenovationTime,
|
|
|
+ // 将上传获取的图片路径数组存入 attachmentUrls 字段,传递给保存接口
|
|
|
+ attachmentUrls: attachmentUrlsList,
|
|
|
+ contactName: formData.contactName,
|
|
|
+ contactPhone: formData.contactPhone,
|
|
|
+ city: formData.city,
|
|
|
+ cityAdcode: formData.cityAdcode || "",
|
|
|
+ detailedAddress: formData.detailedAddress || "",
|
|
|
+ agreementConfirmed: formData.agreementConfirmed,
|
|
|
+ storeId: formData.storeId || 0,
|
|
|
+ auditStatus: 0,
|
|
|
+ status: 0,
|
|
|
+ hasCommunicated: false,
|
|
|
+ inquiryCount: 0,
|
|
|
+ viewCount: 0,
|
|
|
+ createdTime: "",
|
|
|
+ updatedTime: "",
|
|
|
+ storeAddress: "",
|
|
|
+ storeAvatar: "",
|
|
|
+ storeBlurb: "",
|
|
|
+ storeName: "",
|
|
|
+ storeTel: ""
|
|
|
+ };
|
|
|
+
|
|
|
+ console.log("提交参数:", params);
|
|
|
+ const res: any = await saveOrUpdateDecoration(params);
|
|
|
+
|
|
|
+ if (res.code == 200 || res.code == 0) {
|
|
|
+ ElMessage.success("创建成功");
|
|
|
+ // 返回到列表页面
|
|
|
+ router.push("/storeDecorationManagement/decorationManagement");
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg || "创建失败");
|
|
|
+ // 创建失败也返回到列表页面
|
|
|
+ router.push("/storeDecorationManagement/decorationManagement");
|
|
|
+ }
|
|
|
+ } catch (error: any) {
|
|
|
+ ElMessage.error(error?.msg || error?.message || "创建失败");
|
|
|
+ // 创建失败也返回到列表页面
|
|
|
+ router.push("/storeDecorationManagement/decorationManagement");
|
|
|
+ } finally {
|
|
|
+ submitLoading.value = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 关闭对话框
|
|
|
+const handleClose = () => {
|
|
|
+ dialogVisible.value = false;
|
|
|
+ // 返回到列表页面
|
|
|
+ router.push("/storeDecorationManagement/decorationManagement");
|
|
|
+};
|
|
|
+
|
|
|
+// 初始化
|
|
|
+onMounted(() => {
|
|
|
+ getProvinceData();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.add-container {
|
|
|
+ :deep(.el-dialog__body) {
|
|
|
+ padding: 20px;
|
|
|
+ max-height: 70vh;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-form-item) {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-radio-group) {
|
|
|
+ display: flex;
|
|
|
+ gap: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .upload-tip {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-footer {
|
|
|
+ text-align: center;
|
|
|
+ padding: 20px 0 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-upload--picture-card) {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-upload-list--picture-card .el-upload-list__item) {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .city-selector {
|
|
|
+ padding: 10px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cursor-pointer {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|