|
@@ -0,0 +1,669 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="store-info-container">
|
|
|
|
|
+ <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px" class="store-form">
|
|
|
|
|
+ <div class="form-content">
|
|
|
|
|
+ <!-- 左侧列 -->
|
|
|
|
|
+ <div class="form-left">
|
|
|
|
|
+ <!-- 店铺名称 -->
|
|
|
|
|
+ <el-form-item label="店铺名称" prop="storeName">
|
|
|
|
|
+ <el-input v-model="formData.storeName" placeholder="请输入店铺名称" clearable maxlength="50" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 容纳人数 -->
|
|
|
|
|
+ <el-form-item label="容纳人数" prop="storeCapacity">
|
|
|
|
|
+ <el-input-number v-model="formData.storeCapacity" :min="1" :max="10000" style="width: 100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 门店电话 -->
|
|
|
|
|
+ <el-form-item label="门店电话" prop="storePhone">
|
|
|
|
|
+ <el-input v-model="formData.storePhone" placeholder="请输入门店电话" clearable maxlength="20" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 门店面积 -->
|
|
|
|
|
+ <el-form-item label="门店面积" prop="storeArea">
|
|
|
|
|
+ <el-radio-group v-model="formData.storeArea">
|
|
|
|
|
+ <el-radio value="小于20平米"> 小于20平米 </el-radio>
|
|
|
|
|
+ <el-radio value="20-50平米"> 20-50平米 </el-radio>
|
|
|
|
|
+ <el-radio value="50-100平米"> 50-100平米 </el-radio>
|
|
|
|
|
+ <el-radio value="100-300平米"> 100-300平米 </el-radio>
|
|
|
|
|
+ <el-radio value="300-500平米"> 300-500平米 </el-radio>
|
|
|
|
|
+ <el-radio value="500-1000平米"> 500-1000平米 </el-radio>
|
|
|
|
|
+ <el-radio value="大于1000平米"> 大于1000平米 </el-radio>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 营业状态 -->
|
|
|
|
|
+ <el-form-item label="营业状态" prop="businessStatus">
|
|
|
|
|
+ <el-radio-group v-model="formData.businessStatus">
|
|
|
|
|
+ <div class="radio-item">
|
|
|
|
|
+ <el-radio value="正常营业">
|
|
|
|
|
+ <span class="radio-label">正常营业</span>
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ <div class="radio-desc">门店正常开放,能够为顾客提供服务</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="radio-item">
|
|
|
|
|
+ <el-radio value="暂停营业">
|
|
|
|
|
+ <span class="radio-label">暂停营业</span>
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ <div class="radio-desc">门店因节假日、装修等原因,短期内止营业,预计一段时问后可恢复营业</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="radio-item">
|
|
|
|
|
+ <el-radio value="筹建中">
|
|
|
|
|
+ <span class="radio-label">筹建中</span>
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ <div class="radio-desc">门店正在筹备阶段,暂时不能提供服务,完成准备后可以证实为顾客提供服务</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="radio-item">
|
|
|
|
|
+ <el-radio value="永久关门">
|
|
|
|
|
+ <span class="radio-label">永久关门</span>
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ <div class="radio-desc">门店已经关门、转让或搬迁,长时间没有回复营业的计划,无法提供服务</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 所在地区 -->
|
|
|
|
|
+ <el-form-item label="所在地区" required>
|
|
|
|
|
+ <div class="region-selector">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.province"
|
|
|
|
|
+ placeholder="请选择省"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 33.33%"
|
|
|
|
|
+ @change="handleProvinceChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="province in provinceOptions"
|
|
|
|
|
+ :key="province.adcode"
|
|
|
|
|
+ :label="province.name"
|
|
|
|
|
+ :value="province.adcode"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.city"
|
|
|
|
|
+ placeholder="请选择市"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 33.33%"
|
|
|
|
|
+ :disabled="!formData.province"
|
|
|
|
|
+ @change="handleCityChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option v-for="city in cityOptions" :key="city.adcode" :label="city.name" :value="city.adcode" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.district"
|
|
|
|
|
+ placeholder="请选择区"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ style="width: 33.33%"
|
|
|
|
|
+ :disabled="!formData.city"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="district in districtOptions"
|
|
|
|
|
+ :key="district.adcode"
|
|
|
|
|
+ :label="district.name"
|
|
|
|
|
+ :value="district.adcode"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 详细地址 -->
|
|
|
|
|
+ <el-form-item label="详细地址" prop="storeAddress">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.storeAddress"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="3"
|
|
|
|
|
+ placeholder="请输入详细地址"
|
|
|
|
|
+ maxlength="200"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 右侧列 -->
|
|
|
|
|
+ <div class="form-right">
|
|
|
|
|
+ <!-- 门店简介 -->
|
|
|
|
|
+ <el-form-item label="门店简介" prop="storeBlurb">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.storeBlurb"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="4"
|
|
|
|
|
+ placeholder="请输入门店简介"
|
|
|
|
|
+ maxlength="500"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 经纬度查询 -->
|
|
|
|
|
+ <el-form-item label="经纬度查询" prop="locationQuery">
|
|
|
|
|
+ <el-input v-model="formData.locationQuery" placeholder="请输入地址进行查询" clearable @blur="handleLocationQuery">
|
|
|
|
|
+ <template #append>
|
|
|
|
|
+ <el-button :icon="Search" @click="handleLocationQuery"> 查询 </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 经营板块 -->
|
|
|
|
|
+ <el-form-item label="经营板块" prop="businessSection">
|
|
|
|
|
+ <el-radio-group v-model="formData.businessSection">
|
|
|
|
|
+ <div v-for="section in businessSectionList" :key="section.id || section.value" class="businessSection-item">
|
|
|
|
|
+ <el-radio :value="section.id || section.value" :label="section.name || section.label">
|
|
|
|
|
+ {{ section.name || section.label }}
|
|
|
|
|
+ </el-radio>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-radio-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 经营种类 -->
|
|
|
|
|
+ <el-form-item label="经营种类" prop="businessTypes">
|
|
|
|
|
+ <el-checkbox-group v-model="formData.businessTypes" style=" display: flex; flex-wrap: wrap;width: 100%">
|
|
|
|
|
+ <div class="businessSection-item" v-for="type in businessTypeList" :key="type.id || type.value">
|
|
|
|
|
+ <el-checkbox :value="type.id || type.value" :label="type.name || type.label">
|
|
|
|
|
+ {{ type.name || type.label }}
|
|
|
|
|
+ </el-checkbox>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-checkbox-group>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 到期时间(只读) -->
|
|
|
|
|
+ <el-form-item label="到期时间">
|
|
|
|
|
+ <el-input v-model="formData.expirationTime" disabled class="readonly-input">
|
|
|
|
|
+ <template #prefix>
|
|
|
|
|
+ <el-icon>
|
|
|
|
|
+ <Lock />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 食品经营许可证到期时间(只读) -->
|
|
|
|
|
+ <el-form-item label="食品经营许可证到期时间">
|
|
|
|
|
+ <el-input v-model="formData.foodLicenseExpirationTime" disabled class="readonly-input">
|
|
|
|
|
+ <template #prefix>
|
|
|
|
|
+ <el-icon>
|
|
|
|
|
+ <Lock />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 保存按钮 -->
|
|
|
|
|
+ <div class="form-footer">
|
|
|
|
|
+ <el-button type="primary" size="large" :loading="loading" @click="handleSubmit"> 保存 </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, reactive, onMounted, watch } from "vue";
|
|
|
|
|
+import { ElMessage, ElNotification } from "element-plus";
|
|
|
|
|
+import type { FormInstance, FormRules } from "element-plus";
|
|
|
|
|
+import { Search, Lock } from "@element-plus/icons-vue";
|
|
|
|
|
+import {
|
|
|
|
|
+ getBusinessSection,
|
|
|
|
|
+ getBusinessSectionTypes,
|
|
|
|
|
+ getInputPrompt,
|
|
|
|
|
+ getDistrict,
|
|
|
|
|
+ saveStoreInfo,
|
|
|
|
|
+ editStoreInfo,
|
|
|
|
|
+ getStoreDetail
|
|
|
|
|
+} from "@/api/modules/storeUser";
|
|
|
|
|
+import { useRoute } from "vue-router";
|
|
|
|
|
+
|
|
|
|
|
+const route = useRoute();
|
|
|
|
|
+const formRef = ref<FormInstance>();
|
|
|
|
|
+const loading = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+// 表单数据
|
|
|
|
|
+const formData = reactive({
|
|
|
|
|
+ id: "",
|
|
|
|
|
+ storeName: "重庆老火锅",
|
|
|
|
|
+ storeCapacity: 200,
|
|
|
|
|
+ storePhone: "13000010002",
|
|
|
|
|
+ storeArea: "50-100平米",
|
|
|
|
|
+ businessStatus: "正常营业",
|
|
|
|
|
+ province: "",
|
|
|
|
|
+ city: "",
|
|
|
|
|
+ district: "",
|
|
|
|
|
+ storeAddress: "中信丰悦大厦",
|
|
|
|
|
+ storeBlurb: "位于港湾广场地铁站直线500米",
|
|
|
|
|
+ locationQuery: "中信丰悦大厦",
|
|
|
|
|
+ businessSection: "美食",
|
|
|
|
|
+ businessTypes: ["小吃快餐", "火锅"] as string[],
|
|
|
|
|
+ expirationTime: "2025/06/11",
|
|
|
|
|
+ foodLicenseExpirationTime: "2025/06/11",
|
|
|
|
|
+ longitude: "",
|
|
|
|
|
+ latitude: ""
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 表单验证规则
|
|
|
|
|
+const rules = reactive<FormRules>({
|
|
|
|
|
+ storeName: [{ required: true, message: "请输入店铺名称", trigger: "blur" }],
|
|
|
|
|
+ storeCapacity: [{ required: true, message: "请输入容纳人数", trigger: "blur" }],
|
|
|
|
|
+ storePhone: [
|
|
|
|
|
+ { required: true, message: "请输入门店电话", trigger: "blur" },
|
|
|
|
|
+ { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ storeArea: [{ required: true, message: "请选择门店面积", trigger: "change" }],
|
|
|
|
|
+ businessStatus: [{ required: true, message: "请选择营业状态", trigger: "change" }],
|
|
|
|
|
+ province: [{ required: true, message: "请选择省", trigger: "change" }],
|
|
|
|
|
+ city: [{ required: true, message: "请选择市", trigger: "change" }],
|
|
|
|
|
+ district: [{ required: true, message: "请选择区", trigger: "change" }],
|
|
|
|
|
+ storeAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
|
|
|
|
|
+ storeBlurb: [{ required: true, message: "请输入门店简介", trigger: "blur" }],
|
|
|
|
|
+ locationQuery: [{ required: true, message: "请输入地址进行经纬度查询", trigger: "blur" }],
|
|
|
|
|
+ businessSection: [{ required: true, message: "请选择经营板块", trigger: "change" }],
|
|
|
|
|
+ businessTypes: [{ required: true, message: "请选择经营种类", trigger: "change", type: "array" }]
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 地区选项
|
|
|
|
|
+const provinceOptions = ref<any[]>([]);
|
|
|
|
|
+const cityOptions = ref<any[]>([]);
|
|
|
|
|
+const districtOptions = ref<any[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// 经营板块列表(根据UI图静态数据)
|
|
|
|
|
+const businessSectionList = ref<any[]>([
|
|
|
|
|
+ { id: "美食", name: "美食", value: "美食" },
|
|
|
|
|
+ { id: "酒店/民宿", name: "酒店/民宿", value: "酒店/民宿" },
|
|
|
|
|
+ { id: "KTV", name: "KTV", value: "KTV" },
|
|
|
|
|
+ { id: "洗浴汗蒸", name: "洗浴汗蒸", value: "洗浴汗蒸" },
|
|
|
|
|
+ { id: "按摩足疗", name: "按摩足疗", value: "按摩足疗" },
|
|
|
|
|
+ { id: "丽人美发", name: "丽人美发", value: "丽人美发" },
|
|
|
|
|
+ { id: "运动健身", name: "运动健身", value: "运动健身" },
|
|
|
|
|
+ { id: "医美医疗", name: "医美医疗", value: "医美医疗" }
|
|
|
|
|
+]);
|
|
|
|
|
+
|
|
|
|
|
+// 经营种类列表(根据UI图静态数据)
|
|
|
|
|
+const businessTypeList = ref<any[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// 经营板块对应的经营种类数据(根据UI图)
|
|
|
|
|
+const businessTypeMap: Record<string, any[]> = {
|
|
|
|
|
+ 美食: [
|
|
|
|
|
+ { id: "小吃快餐", name: "小吃快餐", value: "小吃快餐" },
|
|
|
|
|
+ { id: "鱼鲜海鲜", name: "鱼鲜海鲜", value: "鱼鲜海鲜" },
|
|
|
|
|
+ { id: "烧烤烤串", name: "烧烤烤串", value: "烧烤烤串" },
|
|
|
|
|
+ { id: "自助餐", name: "自助餐", value: "自助餐" },
|
|
|
|
|
+ { id: "面包蛋糕甜品", name: "面包蛋糕甜品", value: "面包蛋糕甜品" },
|
|
|
|
|
+ { id: "水果生鲜", name: "水果生鲜", value: "水果生鲜" },
|
|
|
|
|
+ { id: "火锅", name: "火锅", value: "火锅" },
|
|
|
|
|
+ { id: "特色菜", name: "特色菜", value: "特色菜" },
|
|
|
|
|
+ { id: "中餐", name: "中餐", value: "中餐" },
|
|
|
|
|
+ { id: "西餐", name: "西餐", value: "西餐" },
|
|
|
|
|
+ { id: "烤肉", name: "烤肉", value: "烤肉" },
|
|
|
|
|
+ { id: "韩式料理", name: "韩式料理", value: "韩式料理" },
|
|
|
|
|
+ { id: "地方菜系", name: "地方菜系", value: "地方菜系" },
|
|
|
|
|
+ { id: "日式料理", name: "日式料理", value: "日式料理" },
|
|
|
|
|
+ { id: "轻食", name: "轻食", value: "轻食" }
|
|
|
|
|
+ ]
|
|
|
|
|
+ // 其他经营板块的经营种类可以根据实际需求添加
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取省份数据
|
|
|
|
|
+const getProvinceData = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { data } = await getDistrict();
|
|
|
|
|
+ const dataAny = data as any;
|
|
|
|
|
+
|
|
|
|
|
+ // 根据API返回结构:data.districts[0] 是"中华人民共和国",data.districts[0].districts 是省份列表
|
|
|
|
|
+ if (dataAny && dataAny.districts && Array.isArray(dataAny.districts) && dataAny.districts.length > 0) {
|
|
|
|
|
+ const chinaData = dataAny.districts[0];
|
|
|
|
|
+ if (chinaData && chinaData.districts && Array.isArray(chinaData.districts)) {
|
|
|
|
|
+ provinceOptions.value = chinaData.districts;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取省份数据失败:", error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 省份变化时获取城市数据
|
|
|
|
|
+const handleProvinceChange = async (provinceCode: string) => {
|
|
|
|
|
+ formData.city = "";
|
|
|
|
|
+ formData.district = "";
|
|
|
|
|
+ cityOptions.value = [];
|
|
|
|
|
+ districtOptions.value = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (!provinceCode) return;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 根据adcode查询下级(城市)
|
|
|
|
|
+ const { data } = await getDistrict({ adCode: provinceCode } as any);
|
|
|
|
|
+ const dataAny = data as any;
|
|
|
|
|
+
|
|
|
|
|
+ // 根据API返回结构:data.districts[0] 是省份,data.districts[0].districts 是城市列表
|
|
|
|
|
+ if (dataAny && dataAny.districts && Array.isArray(dataAny.districts) && dataAny.districts.length > 0) {
|
|
|
|
|
+ const provinceData = dataAny.districts[0];
|
|
|
|
|
+ if (provinceData && provinceData.districts && Array.isArray(provinceData.districts)) {
|
|
|
|
|
+ cityOptions.value = provinceData.districts;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取城市数据失败:", error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 城市变化时获取区县数据
|
|
|
|
|
+const handleCityChange = async (cityCode: string) => {
|
|
|
|
|
+ formData.district = "";
|
|
|
|
|
+ districtOptions.value = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (!cityCode) return;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 根据adcode查询下级(区县)
|
|
|
|
|
+ const { data } = await getDistrict({ adCode: cityCode } as any);
|
|
|
|
|
+ const dataAny = data as any;
|
|
|
|
|
+
|
|
|
|
|
+ // 根据API返回结构:data.districts[0] 是城市,data.districts[0].districts 是区县列表
|
|
|
|
|
+ if (dataAny && dataAny.districts && Array.isArray(dataAny.districts) && dataAny.districts.length > 0) {
|
|
|
|
|
+ const cityData = dataAny.districts[0];
|
|
|
|
|
+ if (cityData && cityData.districts && Array.isArray(cityData.districts)) {
|
|
|
|
|
+ districtOptions.value = cityData.districts;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取区县数据失败:", error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取经营板块列表(使用静态数据,也可以从API获取后合并)
|
|
|
|
|
+const getBusinessSectionData = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 如果API有数据,可以合并或替换静态数据
|
|
|
|
|
+ const { data } = await getBusinessSection();
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ const dataAny = data as any;
|
|
|
|
|
+ let apiData: any[] = [];
|
|
|
|
|
+ // 处理不同的返回格式
|
|
|
|
|
+ if (Array.isArray(dataAny)) {
|
|
|
|
|
+ apiData = dataAny;
|
|
|
|
|
+ } else if (dataAny.list && Array.isArray(dataAny.list)) {
|
|
|
|
|
+ apiData = dataAny.list;
|
|
|
|
|
+ } else if (dataAny.data && Array.isArray(dataAny.data)) {
|
|
|
|
|
+ apiData = dataAny.data;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果API返回了数据,可以选择使用API数据或合并
|
|
|
|
|
+ // 这里保持使用静态数据,确保UI图的数据显示
|
|
|
|
|
+ // businessSectionList.value = apiData.length > 0 ? apiData : businessSectionList.value;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取经营板块失败:", error);
|
|
|
|
|
+ // 使用静态数据作为后备
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 监听经营板块变化,获取对应的经营种类
|
|
|
|
|
+const handleBusinessSectionChange = async (sectionId: string) => {
|
|
|
|
|
+ if (!sectionId) {
|
|
|
|
|
+ businessTypeList.value = [];
|
|
|
|
|
+ formData.businessTypes = [];
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 优先使用静态数据
|
|
|
|
|
+ if (businessTypeMap[sectionId] && businessTypeMap[sectionId].length > 0) {
|
|
|
|
|
+ businessTypeList.value = businessTypeMap[sectionId];
|
|
|
|
|
+ formData.businessTypes = [];
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果静态数据中没有,尝试从API获取
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { data } = await getBusinessSectionTypes({ parentId: sectionId });
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ const dataAny = data as any;
|
|
|
|
|
+ // 处理不同的返回格式
|
|
|
|
|
+ if (dataAny.list && Array.isArray(dataAny.list)) {
|
|
|
|
|
+ businessTypeList.value = dataAny.list;
|
|
|
|
|
+ } else if (Array.isArray(dataAny)) {
|
|
|
|
|
+ businessTypeList.value = dataAny;
|
|
|
|
|
+ } else if (dataAny.data && Array.isArray(dataAny.data)) {
|
|
|
|
|
+ businessTypeList.value = dataAny.data;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ businessTypeList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ businessTypeList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ // 清空已选择的经营种类
|
|
|
|
|
+ formData.businessTypes = [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取经营种类失败:", error);
|
|
|
|
|
+ businessTypeList.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 经纬度查询
|
|
|
|
|
+const handleLocationQuery = async () => {
|
|
|
|
|
+ if (!formData.locationQuery) {
|
|
|
|
|
+ ElMessage.warning("请输入地址进行查询");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { data } = await getInputPrompt({ keywords: formData.locationQuery } as any);
|
|
|
|
|
+ const dataArray = Array.isArray(data) ? data : data ? [data] : [];
|
|
|
|
|
+ if (dataArray.length > 0) {
|
|
|
|
|
+ const location = dataArray[0];
|
|
|
|
|
+ if (location.location) {
|
|
|
|
|
+ const coords = location.location.split(",");
|
|
|
|
|
+ formData.longitude = coords[0] || "";
|
|
|
|
|
+ formData.latitude = coords[1] || "";
|
|
|
|
|
+ }
|
|
|
|
|
+ if (location.name) {
|
|
|
|
|
+ formData.storeAddress = location.name;
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success("查询成功");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.warning("未找到相关地址信息");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("经纬度查询失败:", error);
|
|
|
|
|
+ ElMessage.error("查询失败,请稍后重试");
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 表单提交
|
|
|
|
|
+const handleSubmit = async () => {
|
|
|
|
|
+ if (!formRef.value) return;
|
|
|
|
|
+
|
|
|
|
|
+ await formRef.value.validate(async valid => {
|
|
|
|
|
+ if (!valid) {
|
|
|
|
|
+ ElMessage.warning("请完善表单信息");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ loading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const submitData = {
|
|
|
|
|
+ id: formData.id,
|
|
|
|
|
+ storeName: formData.storeName,
|
|
|
|
|
+ storeCapacity: formData.storeCapacity,
|
|
|
|
|
+ storePhone: formData.storePhone,
|
|
|
|
|
+ storeArea: formData.storeArea,
|
|
|
|
|
+ businessStatus: formData.businessStatus,
|
|
|
|
|
+ province: formData.province || "",
|
|
|
|
|
+ city: formData.city || "",
|
|
|
|
|
+ district: formData.district || "",
|
|
|
|
|
+ storeAddress: formData.storeAddress,
|
|
|
|
|
+ storeBlurb: formData.storeBlurb,
|
|
|
|
|
+ businessSection: formData.businessSection,
|
|
|
|
|
+ businessTypes: formData.businessTypes,
|
|
|
|
|
+ longitude: formData.longitude,
|
|
|
|
|
+ latitude: formData.latitude
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ let result;
|
|
|
|
|
+ if (formData.id) {
|
|
|
|
|
+ // 编辑
|
|
|
|
|
+ result = await editStoreInfo(submitData);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 新增
|
|
|
|
|
+ result = await saveStoreInfo(submitData);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (result && result.code === 200) {
|
|
|
|
|
+ ElNotification({
|
|
|
|
|
+ title: "保存成功",
|
|
|
|
|
+ type: "success",
|
|
|
|
|
+ duration: 3000
|
|
|
|
|
+ });
|
|
|
|
|
+ // 如果是新增,获取返回的ID
|
|
|
|
|
+ if (result.data && result.data.id) {
|
|
|
|
|
+ formData.id = result.data.id;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(result?.msg || "保存失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ console.error("保存失败:", error);
|
|
|
|
|
+ ElMessage.error(error?.msg || "保存失败,请稍后重试");
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 获取店铺详情(编辑时使用)
|
|
|
|
|
+const getStoreDetailData = async () => {
|
|
|
|
|
+ const id = route.query.id as string;
|
|
|
|
|
+ if (!id) return;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { data } = await getStoreDetail({ id } as any);
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ const storeData = data as any;
|
|
|
|
|
+ formData.id = storeData.id || "";
|
|
|
|
|
+ formData.storeName = storeData.storeName || "";
|
|
|
|
|
+ formData.storeCapacity = storeData.storeCapacity || 0;
|
|
|
|
|
+ formData.storePhone = storeData.storePhone || "";
|
|
|
|
|
+ formData.storeArea = storeData.storeArea || "";
|
|
|
|
|
+ formData.businessStatus = storeData.businessStatus || "";
|
|
|
|
|
+ formData.storeAddress = storeData.storeAddress || "";
|
|
|
|
|
+ formData.storeBlurb = storeData.storeBlurb || "";
|
|
|
|
|
+ formData.expirationTime = storeData.expirationTime || "";
|
|
|
|
|
+ formData.foodLicenseExpirationTime = storeData.foodLicenseExpirationTime || "";
|
|
|
|
|
+ formData.longitude = storeData.longitude || storeData.storePositionLongitude || "";
|
|
|
|
|
+ formData.latitude = storeData.latitude || storeData.storePositionLatitude || "";
|
|
|
|
|
+
|
|
|
|
|
+ // 设置地区
|
|
|
|
|
+ if (storeData.province) {
|
|
|
|
|
+ formData.province = storeData.province;
|
|
|
|
|
+ await handleProvinceChange(storeData.province);
|
|
|
|
|
+ if (storeData.city) {
|
|
|
|
|
+ formData.city = storeData.city;
|
|
|
|
|
+ await handleCityChange(storeData.city);
|
|
|
|
|
+ if (storeData.district) {
|
|
|
|
|
+ formData.district = storeData.district;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 设置经营板块和种类
|
|
|
|
|
+ if (storeData.businessSection) {
|
|
|
|
|
+ formData.businessSection = storeData.businessSection;
|
|
|
|
|
+ await handleBusinessSectionChange(storeData.businessSection);
|
|
|
|
|
+ if (storeData.businessTypes) {
|
|
|
|
|
+ formData.businessTypes = Array.isArray(storeData.businessTypes) ? storeData.businessTypes : [storeData.businessTypes];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("获取店铺详情失败:", error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 监听经营板块变化
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => formData.businessSection,
|
|
|
|
|
+ newValue => {
|
|
|
|
|
+ if (newValue) {
|
|
|
|
|
+ handleBusinessSectionChange(newValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ await getProvinceData();
|
|
|
|
|
+ await getBusinessSectionData();
|
|
|
|
|
+ // 如果默认选中了经营板块,自动加载对应的经营种类
|
|
|
|
|
+ if (formData.businessSection) {
|
|
|
|
|
+ await handleBusinessSectionChange(formData.businessSection);
|
|
|
|
|
+ }
|
|
|
|
|
+ await getStoreDetailData();
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.store-info-container {
|
|
|
|
|
+ min-height: calc(100vh - 100px);
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ .store-form {
|
|
|
|
|
+ .form-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 40px;
|
|
|
|
|
+ margin-bottom: 40px;
|
|
|
|
|
+ .form-left,
|
|
|
|
|
+ .form-right {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .radio-item {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ .radio-label {
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ }
|
|
|
|
|
+ .radio-desc {
|
|
|
|
|
+ margin-top: 4px;
|
|
|
|
|
+ margin-left: 24px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .readonly-input {
|
|
|
|
|
+ :deep(.el-input__inner) {
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+ background-color: #f5f7fa;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .region-selector {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ .el-select {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .form-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ padding-top: 20px;
|
|
|
|
|
+ border-top: 1px solid #ebeef5;
|
|
|
|
|
+ .el-button {
|
|
|
|
|
+ min-width: 120px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 响应式布局
|
|
|
|
|
+@media (width <= 1200px) {
|
|
|
|
|
+ .store-info-container {
|
|
|
|
|
+ .store-form {
|
|
|
|
|
+ .form-content {
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.businessSection-item {
|
|
|
|
|
+ width: 33%;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|