| | |
| | | id: null, |
| | | scenicCode: '', |
| | | scenicName: '', |
| | | grade: '', |
| | | cityId: null, |
| | | cityName: '', |
| | | createdAt: '', |
| | |
| | | { key: 'privateFast', title: '包团 快讲', group: false }, |
| | | { key: 'privatePremium', title: '包团 精讲', group: false }, |
| | | ] |
| | | const gradeOptions = ['5A', '4A', '3A', '2A', '1A'] |
| | | |
| | | const formatDateTime = (value) => value ? value.replace('T', ' ').slice(0, 19) : '-' |
| | | const loadCities = async () => { |
| | |
| | | const addMeetingPoint = () => { |
| | | form.meetingPoints.push({ |
| | | pointName: `汇合点${form.meetingPoints.length + 1}`, |
| | | address: '', |
| | | longitude: null, |
| | | latitude: null, |
| | | status: 1, |
| | |
| | | markingIndex.value = index |
| | | ElMessage.info('请在下方地图点击需要标注的位置') |
| | | } |
| | | const markPoint = ({ index, longitude, latitude }) => { |
| | | const markPoint = ({ index, longitude, latitude, address }) => { |
| | | if (markingIndex.value !== index || !form.meetingPoints[index]) return |
| | | form.meetingPoints[index].longitude = longitude |
| | | form.meetingPoints[index].latitude = latitude |
| | | form.meetingPoints[index].address = address || '' |
| | | markingIndex.value = null |
| | | ElMessage.success('汇合点已标注') |
| | | if (address) { |
| | | ElMessage.success('汇合点及具体地址已标注') |
| | | } else { |
| | | ElMessage.warning('汇合点已标注,但未识别到具体地址,请重新标注') |
| | | } |
| | | } |
| | | const placeMeetingPoint = (index, { longitude, latitude }) => { |
| | | markPoint({ index, longitude, latitude }) |
| | | const placeMeetingPoint = (index, { longitude, latitude, address }) => { |
| | | markPoint({ index, longitude, latitude, address }) |
| | | } |
| | | const syncMeetingPointAddress = (index, { address }) => { |
| | | if (form.meetingPoints[index] && address) form.meetingPoints[index].address = address |
| | | } |
| | | |
| | | const validateForm = () => { |
| | |
| | | for (const point of form.meetingPoints) { |
| | | if (!point.pointName.trim()) return '请输入汇合点名称' |
| | | if (point.longitude == null || point.latitude == null) return `请标注汇合点“${point.pointName}”` |
| | | if (!point.address || !point.address.trim()) return `未识别到汇合点“${point.pointName}”的具体地址,请重新标注` |
| | | } |
| | | if (form.meetingPoints.length > 0 && form.meetingPoints.filter((point) => point.isDefault === 1).length !== 1) { |
| | | return '请选择一个默认汇合点' |
| | |
| | | const payload = { |
| | | scenicCode: form.scenicCode.trim(), |
| | | scenicName: form.scenicName.trim(), |
| | | grade: form.grade ? form.grade.trim() : '', |
| | | cityId: form.cityId, |
| | | groupFast: { ...form.groupFast }, |
| | | groupPremium: { ...form.groupPremium }, |
| | | privateFast: { ...form.privateFast, maxParticipants: null }, |
| | | privatePremium: { ...form.privatePremium, maxParticipants: null }, |
| | | meetingPoints: form.meetingPoints.map(({ pointName, longitude, latitude, status, isDefault }) => ({ |
| | | pointName: pointName.trim(), longitude, latitude, status, isDefault, |
| | | meetingPoints: form.meetingPoints.map(({ pointName, address, longitude, latitude, status, isDefault }) => ({ |
| | | pointName: pointName.trim(), address: address.trim(), longitude, latitude, status, isDefault, |
| | | })), |
| | | firstOrderLeadMinutes: form.firstOrderLeadMinutes, |
| | | visitorNoOrderMinutes: form.visitorNoOrderMinutes, |
| | |
| | | </el-form-item> |
| | | <el-form-item label="景区名称"> |
| | | <el-input v-model="form.scenicName" maxlength="128" placeholder="请输入景区名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="景区等级"> |
| | | <el-select v-model="form.grade" clearable placeholder="请选择景区等级"> |
| | | <el-option v-for="grade in gradeOptions" :key="grade" :label="grade" :value="grade" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="新建时间"> |
| | | <el-input :model-value="form.createdAt ? formatDateTime(form.createdAt) : '保存后生成'" disabled /> |
| | |
| | | 标注汇合点 |
| | | </el-button> |
| | | </div> |
| | | <div class="meeting-address-row"> |
| | | <span class="meeting-label">定位地址</span> |
| | | <el-input :model-value="point.address" disabled placeholder="标注后自动获取地图具体地址" /> |
| | | </div> |
| | | <div class="meeting-map-row"> |
| | | <AmapMeetingPointMap |
| | | class="meeting-map" |
| | |
| | | :show-search="false" |
| | | compact |
| | | @place="placeMeetingPoint(index, $event)" |
| | | @address-resolved="syncMeetingPointAddress(index, $event)" |
| | | /> |
| | | <el-button class="meeting-delete-button" type="primary" :icon="Delete" @click="removeMeetingPoint(index)"> |
| | | 删除 |
| | |
| | | .meeting-label { color: #475467; font-size: 14px; font-weight: 500; } |
| | | .meeting-toolbar :deep(.el-input__wrapper) { background: #f5f7fa; box-shadow: none; } |
| | | .meeting-toolbar :deep(.el-button) { width: 120px; margin: 0; } |
| | | .meeting-address-row { display: grid; grid-template-columns: 92px minmax(0, 397px); align-items: center; gap: 14px; margin-top: 14px; } |
| | | .meeting-address-row :deep(.el-input__wrapper) { background: #eef1f5; box-shadow: none; } |
| | | .meeting-map-row { display: grid; grid-template-columns: minmax(0, 504px) 88px; align-items: end; gap: 18px; margin-top: 24px; } |
| | | .meeting-map { min-width: 0; } |
| | | .meeting-delete-button { width: 88px; margin: 0; } |
| | |
| | | @media (max-width: 760px) { |
| | | .meeting-toolbar { grid-template-columns: 82px minmax(0, 1fr); } |
| | | .meeting-toolbar :deep(.el-button) { grid-column: 2; } |
| | | .meeting-address-row { grid-template-columns: 82px minmax(0, 1fr); } |
| | | .meeting-map-row { grid-template-columns: minmax(0, 1fr) 88px; } |
| | | } |
| | | </style> |