liujie
2026-09-11 4f6f15b818704079ff2e4e4719b798f48d68a335
frontend/src/views/ScenicSpotDetailView.vue
@@ -30,6 +30,7 @@
  id: null,
  scenicCode: '',
  scenicName: '',
  grade: '',
  cityId: null,
  cityName: '',
  createdAt: '',
@@ -48,6 +49,7 @@
  { 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 () => {
@@ -69,6 +71,7 @@
const addMeetingPoint = () => {
  form.meetingPoints.push({
    pointName: `汇合点${form.meetingPoints.length + 1}`,
    address: '',
    longitude: null,
    latitude: null,
    status: 1,
@@ -86,15 +89,23 @@
  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 = () => {
@@ -113,6 +124,7 @@
  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 '请选择一个默认汇合点'
@@ -130,13 +142,14 @@
    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,
@@ -169,6 +182,11 @@
        </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 />
@@ -216,6 +234,10 @@
              标注汇合点
            </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"
@@ -225,6 +247,7 @@
              :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)">
              删除
@@ -281,6 +304,8 @@
.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; }
@@ -297,6 +322,7 @@
@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>