|
|
@@ -3,138 +3,99 @@
|
|
|
<el-card shadow="never">
|
|
|
<template #header>
|
|
|
<div class="card-header">
|
|
|
- <span>门店信息设置</span>
|
|
|
+ <span class="title">门店信息详情</span>
|
|
|
<el-select v-model="currentStoreId" placeholder="选择门店" @change="handleStoreChange" style="width: 250px">
|
|
|
<el-option v-for="store in stores" :key="store.id" :label="store.name" :value="store.id" />
|
|
|
</el-select>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
- <el-form :model="storeForm" label-width="120px" class="store-form">
|
|
|
- <!-- Logo -->
|
|
|
- <el-form-item label="门店Logo">
|
|
|
- <el-upload class="avatar-uploader" action="#" :show-file-list="false" :auto-upload="false" :on-change="handleLogoChange">
|
|
|
- <el-avatar v-if="storeForm.logo" :size="100" shape="square" :src="storeForm.logo" />
|
|
|
- <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
|
|
- </el-upload>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- License -->
|
|
|
- <el-form-item label="营业执照" required>
|
|
|
- <el-upload action="#" :show-file-list="false" :auto-upload="false" :on-change="handleLicenseChange">
|
|
|
- <el-image style="width: 150px; height: 100px; border-radius: 4px; border: 1px solid #dcdfe6" :src="storeForm.license" fit="cover">
|
|
|
- <template #error>
|
|
|
- <div
|
|
|
- style="width: 100%; height: 100%; background: #f5f7fa; display: flex; justify-content: center; align-items: center; color: #dedfe0"
|
|
|
- >
|
|
|
- <el-icon size="24"><Picture /></el-icon>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-image>
|
|
|
- </el-upload>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Name -->
|
|
|
- <el-form-item label="门店名称" required>
|
|
|
- <el-input v-model="storeForm.name" style="width: 400px" disabled />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Services -->
|
|
|
- <el-form-item label="服务项目" required>
|
|
|
- <el-checkbox-group v-model="storeForm.services" disabled>
|
|
|
- <el-checkbox v-for="service in serviceOptions" :key="service.id" :label="service.id">
|
|
|
- {{ service.name }}
|
|
|
- </el-checkbox>
|
|
|
- </el-checkbox-group>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Category -->
|
|
|
- <el-form-item label="商户分类" required>
|
|
|
- <el-input v-model="storeForm.category" style="width: 400px" disabled />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- <!– Account –>-->
|
|
|
- <!-- <el-form-item label="管理账号" required>-->
|
|
|
- <!-- <el-input v-model="storeForm.account" placeholder="用于后台登录" style="width: 400px" disabled />-->
|
|
|
- <!-- </el-form-item>-->
|
|
|
-
|
|
|
- <!-- <!– Password –>-->
|
|
|
- <!-- <el-form-item label="登录密码">-->
|
|
|
- <!-- <el-input v-model="storeForm.password" type="password" show-password placeholder="若留空则不修改密码" style="width: 400px" />-->
|
|
|
- <!-- </el-form-item>-->
|
|
|
-
|
|
|
- <!-- Business hours -->
|
|
|
- <el-form-item label="营业时间" required>
|
|
|
- <div style="width: 400px">
|
|
|
- <el-time-picker
|
|
|
- v-model="storeForm.businessHours"
|
|
|
- is-range
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始时间"
|
|
|
- end-placeholder="结束时间"
|
|
|
- format="HH:mm"
|
|
|
- value-format="HH:mm"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item label="联系人" required>
|
|
|
- <el-input v-model="storeForm.contactPerson" style="width: 400px" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item label="联系电话" required>
|
|
|
- <el-input v-model="storeForm.contactPhone" style="width: 400px" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Valid Until -->
|
|
|
- <el-form-item label="有效期至">
|
|
|
- <el-input :model-value="storeForm.validUntil" disabled style="width: 400px" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Address -->
|
|
|
- <el-form-item label="详细地址" required>
|
|
|
- <div style="width: 600px">
|
|
|
- <el-cascader
|
|
|
- v-model="storeForm.selectedArea"
|
|
|
- :options="regionData"
|
|
|
- placeholder="请选择省/市/区"
|
|
|
- style="width: 100%; margin-bottom: 10px"
|
|
|
- @change="handleAreaChange"
|
|
|
- />
|
|
|
- <el-input v-model="storeForm.address" type="textarea" placeholder="输入详细地址" />
|
|
|
- <div style="margin-top: 10px; text-align: right">
|
|
|
- <el-button type="warning" size="small" @click="handleGetLocation" icon="Location">获取经纬度</el-button>
|
|
|
+ <div v-loading="loading">
|
|
|
+ <el-descriptions :column="2" border class="store-info-descriptions">
|
|
|
+ <!-- Logo -->
|
|
|
+ <el-descriptions-item label="门店Logo" :span="2">
|
|
|
+ <el-avatar v-if="storeForm.logo" :size="80" shape="square" :src="storeForm.logo" />
|
|
|
+ <span v-else>无</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Name -->
|
|
|
+ <el-descriptions-item label="门店名称">
|
|
|
+ {{ storeForm.name || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Category -->
|
|
|
+ <el-descriptions-item label="商户分类">
|
|
|
+ {{ storeForm.category || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Services -->
|
|
|
+ <el-descriptions-item label="服务项目" :span="2">
|
|
|
+ <div class="service-tags">
|
|
|
+ <el-tag v-for="tag in selectedServiceNames" :key="tag" type="success" effect="plain">
|
|
|
+ {{ tag }}
|
|
|
+ </el-tag>
|
|
|
+ <span v-if="selectedServiceNames.length === 0">-</span>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- Lat Lng -->
|
|
|
- <el-form-item label="经纬度">
|
|
|
- <div style="display: flex; gap: 10px; width: 600px">
|
|
|
- <el-input v-model="storeForm.longitude" placeholder="经度" readonly />
|
|
|
- <el-input v-model="storeForm.latitude" placeholder="纬度" readonly />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item>
|
|
|
- <el-button type="primary" @click="handleSave" size="large">保存修改</el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Contact -->
|
|
|
+ <el-descriptions-item label="联系人">
|
|
|
+ {{ storeForm.contactPerson || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <el-descriptions-item label="联系电话">
|
|
|
+ {{ storeForm.contactPhone || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Business hours -->
|
|
|
+ <el-descriptions-item label="营业时间">
|
|
|
+ {{ storeForm.businessHours[0] && storeForm.businessHours[1] ? `${storeForm.businessHours[0]} 至 ${storeForm.businessHours[1]}` : '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Valid Until -->
|
|
|
+ <el-descriptions-item label="有效期至">
|
|
|
+ <el-tag type="warning" effect="dark">{{ storeForm.validUntil || '-' }}</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Address -->
|
|
|
+ <el-descriptions-item label="详细地址" :span="2">
|
|
|
+ {{ fullAddress || '-' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- Lat Lng -->
|
|
|
+ <el-descriptions-item label="经纬度">
|
|
|
+ <div v-if="storeForm.longitude && storeForm.latitude">
|
|
|
+ <span>经度: {{ storeForm.longitude }}</span>
|
|
|
+ <span style="margin-left: 20px">纬度: {{ storeForm.latitude }}</span>
|
|
|
+ </div>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+
|
|
|
+ <!-- License -->
|
|
|
+ <el-descriptions-item label="营业执照" :span="2">
|
|
|
+ <el-image
|
|
|
+ v-if="storeForm.license"
|
|
|
+ style="width: 200px; height: 140px; border-radius: 4px; border: 1px solid #dcdfe6"
|
|
|
+ :src="storeForm.license"
|
|
|
+ :preview-src-list="[storeForm.license]"
|
|
|
+ fit="cover"
|
|
|
+ />
|
|
|
+ <span v-else>未上传</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </div>
|
|
|
</el-card>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { reactive, ref, onMounted } from 'vue';
|
|
|
-import { ElMessage } from 'element-plus';
|
|
|
-import { Plus, Picture, Location } from '@element-plus/icons-vue';
|
|
|
+import { reactive, ref, onMounted, computed } from 'vue';
|
|
|
import { listOnMerchantStoreInfo, getStoreInfo } from '@/api/system/store';
|
|
|
import { listOnStore } from '@/api/service/list';
|
|
|
import { regionData } from 'element-china-area-data';
|
|
|
|
|
|
const currentStoreId = ref('');
|
|
|
-
|
|
|
+const loading = ref(false);
|
|
|
const stores = ref([]);
|
|
|
const serviceOptions = ref([]);
|
|
|
|
|
|
@@ -145,8 +106,6 @@ const storeForm = reactive({
|
|
|
name: '',
|
|
|
services: [],
|
|
|
category: '',
|
|
|
- account: '',
|
|
|
- password: '',
|
|
|
contactPerson: '',
|
|
|
contactPhone: '',
|
|
|
businessHours: ['', ''],
|
|
|
@@ -158,6 +117,39 @@ const storeForm = reactive({
|
|
|
selectedArea: []
|
|
|
});
|
|
|
|
|
|
+// 计算选中的服务项目名称
|
|
|
+const selectedServiceNames = computed(() => {
|
|
|
+ return storeForm.services
|
|
|
+ .map((id) => {
|
|
|
+ const option = serviceOptions.value.find((item) => item.id === id);
|
|
|
+ return option ? option.name : null;
|
|
|
+ })
|
|
|
+ .filter((name) => name !== null);
|
|
|
+});
|
|
|
+
|
|
|
+// 从 regionData 中根据 code 查找 label
|
|
|
+const findLabelByCode = (data, code) => {
|
|
|
+ if (!data || !code) return '';
|
|
|
+ for (const item of data) {
|
|
|
+ if (String(item.value) === String(code)) return item.label;
|
|
|
+ if (item.children) {
|
|
|
+ const label = findLabelByCode(item.children, code);
|
|
|
+ if (label) return label;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+};
|
|
|
+
|
|
|
+// 计算完整地址
|
|
|
+const fullAddress = computed(() => {
|
|
|
+ let areaText = '';
|
|
|
+ if (storeForm.selectedArea && storeForm.selectedArea.length > 0) {
|
|
|
+ areaText = storeForm.selectedArea.map((code) => findLabelByCode(regionData, code)).join('');
|
|
|
+ }
|
|
|
+ return areaText + (storeForm.address || '');
|
|
|
+});
|
|
|
+
|
|
|
+// 获取门店列表
|
|
|
const getStoreList = async () => {
|
|
|
try {
|
|
|
const res = await listOnMerchantStoreInfo();
|
|
|
@@ -172,6 +164,7 @@ const getStoreList = async () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 获取服务项目选项
|
|
|
const getServiceOptions = async () => {
|
|
|
try {
|
|
|
const res = await listOnStore();
|
|
|
@@ -183,8 +176,10 @@ const getServiceOptions = async () => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 切换门店加载详情
|
|
|
const handleStoreChange = async (val) => {
|
|
|
if (!val) return;
|
|
|
+ loading.value = true;
|
|
|
try {
|
|
|
const res = await getStoreInfo(val);
|
|
|
const data = res.data;
|
|
|
@@ -208,6 +203,7 @@ const handleStoreChange = async (val) => {
|
|
|
storeForm.longitude = data.longitude ? String(data.longitude) : '';
|
|
|
storeForm.latitude = data.latitude ? String(data.latitude) : '';
|
|
|
storeForm.areaCode = data.areaCode || '';
|
|
|
+
|
|
|
if (data.areaCode) {
|
|
|
if (Array.isArray(data.areaCode)) {
|
|
|
storeForm.selectedArea = data.areaCode;
|
|
|
@@ -220,6 +216,8 @@ const handleStoreChange = async (val) => {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('获取详细信息失败:', error);
|
|
|
+ } finally {
|
|
|
+ loading.value = false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -227,43 +225,6 @@ onMounted(() => {
|
|
|
getServiceOptions();
|
|
|
getStoreList();
|
|
|
});
|
|
|
-
|
|
|
-const handleLogoChange = (file) => {
|
|
|
- if (file && file.raw) {
|
|
|
- storeForm.logo = URL.createObjectURL(file.raw);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const handleLicenseChange = (file) => {
|
|
|
- if (file && file.raw) {
|
|
|
- storeForm.license = URL.createObjectURL(file.raw);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const handleAreaChange = (val) => {
|
|
|
- if (val && val.length > 0) {
|
|
|
- storeForm.areaCode = val.join(',');
|
|
|
- } else {
|
|
|
- storeForm.areaCode = '';
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const handleGetLocation = () => {
|
|
|
- if (!storeForm.selectedArea || storeForm.selectedArea.length === 0) {
|
|
|
- return ElMessage.warning('请先选择省市区');
|
|
|
- }
|
|
|
- if (!storeForm.address) {
|
|
|
- return ElMessage.warning('请先填写详细地址');
|
|
|
- }
|
|
|
-
|
|
|
- ElMessage.success('根据地址获取经纬度成功');
|
|
|
- storeForm.longitude = '116.452562';
|
|
|
- storeForm.latitude = '39.936404';
|
|
|
-};
|
|
|
-
|
|
|
-const handleSave = () => {
|
|
|
- ElMessage.success(`门店【${storeForm.name}】信息已更新`);
|
|
|
-};
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
@@ -275,23 +236,29 @@ const handleSave = () => {
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
}
|
|
|
-.store-form {
|
|
|
+.title {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #303133;
|
|
|
+}
|
|
|
+.store-info-descriptions {
|
|
|
margin-top: 20px;
|
|
|
}
|
|
|
-.avatar-uploader-icon {
|
|
|
- font-size: 28px;
|
|
|
- color: #8c939d;
|
|
|
- width: 100px;
|
|
|
- height: 100px;
|
|
|
- text-align: center;
|
|
|
- border: 1px dashed #d9d9d9;
|
|
|
- border-radius: 8px;
|
|
|
+.service-tags {
|
|
|
display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- cursor: pointer;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+:deep(.el-descriptions__label) {
|
|
|
+ width: 140px;
|
|
|
+ justify-content: center !important;
|
|
|
+ text-align: center !important;
|
|
|
+ background-color: #f8f9fb !important;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #606266;
|
|
|
}
|
|
|
-.avatar-uploader-icon:hover {
|
|
|
- border-color: #409eff;
|
|
|
+:deep(.el-descriptions__content) {
|
|
|
+ padding: 16px 20px;
|
|
|
}
|
|
|
</style>
|
|
|
+
|