
<template>
  <div class="amap-page-container">
    <div id="map" class="amap-cavans" />
    <el-input id="search" v-model="searchBody" class="search-body" placeholder="请输入..." @keyup.enter.native="submitSearch">
      <el-button slot="append" icon="el-icon-search" @click="submitSearch" />
    </el-input>
    <div class="asider" :class="showSchool ? '' : 'hidden-school'">
      <el-card class="box-card" :body-style="{ flex: 1, 'overflow-y': 'scroll', padding: 0 }">
        <div slot="header" class="clearfix">
          <div class="map-card-title">驾校列表</div>
        </div>
        <div v-for="school in schoolList" :key="school.schoolId" style="margin:10px;" :class="currentdeptId == school.schoolId ? 'actived-school' : ''">
          <el-card :body-style="{ padding: '10px' }">
            <div slot="header" class="clearfix">
              <div class="map-card-title">{{ school.schoolName }}</div>
              <el-switch v-model="school.showInMap" v-hasPermi="['sch:place:edit']" class="add-icon" active-text="展示" inactive-text="隐藏" @change="changeSchoolStatus(school)" />
            </div>
            <el-button @click="handleClickSchool(school)">{{ `数据管理(${getCount(school.schoolId)})` }}</el-button>
            <el-tooltip v-hasPermi="['sch:place:add']" content="新增场地" placement="left" effect="dark">
              <el-button icon="el-icon-plus" class="add-place-btn" @click="handleInsertPlace(school.schoolId)" />
            </el-tooltip>
          </el-card>
        </div>
      </el-card>
      <div class="asider-sub">
        <el-tooltip content="放大" placement="left" effect="dark">
          <el-button icon="el-icon-plus" class="is-circle" :disabled="zomm >= 18" @click="bigger" />
        </el-tooltip>
        <el-tooltip content="缩小" placement="left" effect="dark">
          <el-button icon="el-icon-minus" class="is-circle" :disabled="zomm <= 8" @click="smaller" />
        </el-tooltip>
        <div class="mt10">
          <el-tooltip content="驾校" placement="left" effect="dark">
            <el-button icon="el-icon-school" class="is-circle" @click="toggleSchool" />
          </el-tooltip>
          <el-tooltip content="定位" placement="left" effect="dark">
            <el-button icon="el-icon-help" class="is-circle" @click="geolocation" />
          </el-tooltip>
          <el-tooltip content="测距" placement="left" effect="dark">
            <el-button icon="el-icon-thumb" class="is-circle" @click="ranging" />
          </el-tooltip>
          <el-tooltip content="分享" placement="left" effect="dark">
            <el-button icon="el-icon-share" class="is-circle" />
          </el-tooltip>
        </div>
      </div>
    </div>
    <el-card v-if="placeDialogShow" class="place-dialog" :body-style="{ padding: '10px' }">
      <div slot="header" class="clearfix">
        <div class="map-card-title">场地设置</div>
        <el-tooltip content="取点" placement="right" effect="dark">
          <el-button icon="el-icon-location" class="add-icon" @click="getPoint" />
        </el-tooltip>
      </div>
      <el-form ref="placeForm" :model="placeForm" label-width="70px">
        <el-form-item label="所属驾校" prop="schoolId">
          <el-select v-model="placeForm.schoolId" placeholder="请选择" clearable>
            <el-option v-for="dict in schoolList" :key="dict.schoolId" :label="dict.schoolName" :value="dict.schoolId" />
          </el-select>
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="placeForm.name" placeholder="输入名称" />
        </el-form-item>
        <el-form-item label="旗子颜色" prop="flagColor">
          <el-radio-group v-model="placeForm.flagColor">
            <el-radio v-for="(item, index) in colorOptions" :key="index" :label="item">
              <img :src="require(`@/assets/images/place/flag_${item}.png`)" width="20px">
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input v-model="placeForm.address" placeholder="输入地址" />
        </el-form-item>
        <el-form-item label="经度" prop="lng">
          <el-input v-model="placeForm.lng" placeholder="输入经度" />
        </el-form-item>
        <el-form-item label="纬度" prop="lat">
          <el-input v-model="placeForm.lat" placeholder="输入纬度" />
        </el-form-item>
        <el-form-item label="所属区域" prop="area">
          <el-select v-model="placeForm.area" placeholder="请选择" clearable size="small">
            <el-option v-for="dict in areaOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
          </el-select>
        </el-form-item>
        <el-form-item label="电话" prop="phone">
          <el-input v-model="placeForm.phone" placeholder="输入电话" />
        </el-form-item>
        <el-form-item label="负责人" prop="contact">
          <el-input v-model="placeForm.contact" placeholder="输入负责人" />
        </el-form-item>
        <el-form-item label="是否推荐" prop="contact">
          <el-radio v-model="placeForm.recommend" :label="true">是</el-radio>
          <el-radio v-model="placeForm.recommend" :label="false">否</el-radio>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="placeForm.remark" placeholder="输入备注" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" />
        </el-form-item>
        <el-form-item style="text-align:right;">
          <el-button v-hasPermi="['sch:place:edit']" type="primary" @click="onSubmit">保存</el-button>
          <el-button @click="closePlaceDialog">取消</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card :class="placeListDialogShow ? '' : 'hidden-place-list'" class="place-list-dialog" :style="{ right: showSchool ? '300px' : '0', top: fullScreenPlaceList ? '0px' : '420px' }" :body-style="{ padding: '10px', height: 'calc(100% - 52px)' }">
      <div slot="header" class="clearfix">
        <div class="map-card-title">
          {{ placeListDialogTitle }}
          <el-input v-model="tableSearch" placeholder="请输入搜索的内容" clearable />
        </div>
        <el-tooltip content="全屏" placement="top" effect="dark">
          <el-button icon="el-icon-full-screen" class="add-icon" @click="fullScreenPlaceList = !fullScreenPlaceList" />
        </el-tooltip>
        <el-tooltip content="关闭" placement="top" effect="dark">
          <el-button icon="el-icon-close" class="add-icon" @click="() => { placeListDialogShow = false; fullScreenPlaceList = false }" />
        </el-tooltip>
      </div>
      <el-table :data="placeTableData" border stripe class="place-table-list" height="100%">
        <el-table-column label="序号" type="index" fixed="left" width="50" />
        <el-table-column prop="name" label="名称" min-width="100" />
        <el-table-column prop="phone" label="电话" width="120" />
        <el-table-column prop="contact" label="负责人" width="120" />
        <el-table-column prop="address" label="地址" min-width="100" />
        <el-table-column prop="lng" label="经度" width="110" />
        <el-table-column prop="lat" label="纬度" width="110" />
        <el-table-column prop="area" label="所属区域" width="110" />
        <el-table-column label="展示" width="100">
          <template slot-scope="scope">
            <el-switch v-model="scope.row.showInMap" v-hasPermi="['sch:place:edit']" @change="changePlaceStatus(scope.row)" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template slot-scope="scope">
            <el-tooltip v-hasPermi="['sch:place:edit']" content="编辑" placement="top" effect="dark">
              <el-button icon="el-icon-edit" type="primary" style="padding: 4px 8px;" @click="handleEditPlace(scope.row)" />
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <div v-if="isPointing || isRanging" class="map-tip" :style="{ transform: 'translate3D(' + (tipPostion.x + 15) + 'px,' + (tipPostion.y - 10) + 'px, 0)' }">{{ mapHelpText }}</div>
    <i v-if="isPointing" class="el-icon-s-flag circle" :style="{ transform: 'translate3D(' + tipPostion.x + 'px,' + tipPostion.y + 'px, 0)' }" />
  </div>
</template>
<!-- eslint-disable no-undef -->
<script>
import { getMapData, addPlace, updatePlace, updateSchoolStatus } from '@/api/sch/place';
export default {
  name: 'Place',
  data() {
    return {
      aMap: null,
      zomm: 12,
      showSchool: true,
      isRanging: false,
      aMapLocation: null,
      aMouseTool: null,
      searchBody: '',
      placeSearch: null,
      placeDialogShow: false,
      isPointing: false,
      placeForm: {
        lat: undefined,
        lng: undefined,
        name: undefined,
        address: undefined,
        remark: undefined,
        phone: undefined,
        flagColor: 'red'
      },
      colorOptions: ['red', 'yellow', 'blue', 'green', 'purple', 'black'],
      mapHelpText: '',
      tipPostion: {
        x: 0,
        y: 0
      },
      geocoder: null,
      locationMarker: null,
      selectMarker: null,
      placeListDialogShow: false,
      placeListDialogTitle: '',
      fullScreenPlaceList: false,
      tableSearch: '',
      tableData: [],
      schoolList: [],
      currentdeptId: undefined,
      placeMarkerList: [],
      areaOptions: []
    };
  },
  computed: {
    placeTableData: function () {
      if (this.tableSearch) {
        return this.tableData.filter((dataNews) => {
          return (
            dataNews.schoolId === this.currentdeptId &&
            Object.keys(dataNews).some((key) => {
              return String(dataNews[key]).toLowerCase().indexOf(this.tableSearch) > -1;
            })
          );
        });
      }
      return this.tableData.filter((dataNews) => dataNews.schoolId === this.currentdeptId);
    }
  },
  mounted() {
    this.initMap();
    this.getDicts('dm_area').then((response) => {
      this.areaOptions = response.data;
    });
  },
  methods: {
    initMap() {
      window.onLoad = () => {
        this.aMap = new AMap.Map('map', {
          zoom: this.zomm,
          center: [117.226095, 31.814372],
          zooms: [8, 18]
        });
        // 监听缩放
        this.aMap.on('zoomend', () => {
          this.zomm = this.aMap.getZoom();
          this.$message('当前缩放等级:' + this.zomm);
        });
        // 监听点击
        this.aMap.on('click', (ev) => {
          if (this.isPointing) {
            this.placeForm.lat = ev.lnglat.lat;
            this.placeForm.lng = ev.lnglat.lng;
            this.regeoCode();
            if (this.selectMarker) {
              this.selectMarker.setPosition([this.placeForm.lng, this.placeForm.lat]);
            } else {
              this.locationMarker.setPosition([this.placeForm.lng, this.placeForm.lat]);
              this.aMap.add(this.locationMarker);
            }
            this.isPointing = false;
          }
        });
        // 监听移动
        this.aMap.on('mousemove', (ev) => {
          if (this.isRanging) {
            this.mapHelpText = '左键单击选点，双击/右键单击完成选点，再次点击测距按钮可退出测距模式，并清除测距结果';
            this.tipPostion = {
              x: ev.pixel.x,
              y: ev.pixel.y
            };
          } else if (this.isPointing) {
            this.mapHelpText = '点击地图添加标注';
            this.tipPostion = {
              x: ev.pixel.x,
              y: ev.pixel.y
            };
          }
        });
        // 添加地图插件
        AMap.plugin(['AMap.Scale', 'AMap.Geolocation', 'AMap.MouseTool', 'AMap.PlaceSearch', 'AMap.Autocomplete', 'AMap.Geocoder'], () => {
          this.aMap.addControl(new AMap.Scale());
          const geoLoca = new AMap.Geolocation({
            showButton: false
          });
          this.aMapLocation = geoLoca;
          this.aMap.addControl(geoLoca);
          this.aMouseTool = new AMap.MouseTool(this.aMap);
          const auto = new AMap.Autocomplete({
            input: 'search' // 前端搜索框
          });
          this.placeSearch = new AMap.PlaceSearch({
            map: this.aMap
          });
          AMap.event.addListener(auto, 'select', this.select);
          this.geocoder = new AMap.Geocoder();
          this.locationMarker = new AMap.Marker({
            icon: require(`@/assets/images/place/flag_red.png`)
          });
        });
        this.getPageData();
      };
      this.importMap();
    },
    // 导入地图
    importMap() {
      const url = 'https://webapi.amap.com/maps?v=1.4.15&key=0e62be0896c6b8d27d453445f0fb8bc4&callback=onLoad';
      var jsapi = document.createElement('script');
      jsapi.charset = 'utf-8';
      jsapi.src = url;
      document.head.appendChild(jsapi);
    },
    toggleSchool() {
      this.showSchool = !this.showSchool;
    },
    // 经纬度 -> 地址
    regeoCode() {
      this.geocoder.getAddress([this.placeForm.lng, this.placeForm.lat], (status, result) => {
        if (status === 'complete' && result.regeocode) {
          this.placeForm.address = result.regeocode.formattedAddress;
        } else {
          console.log('根据经纬度查询地址失败');
        }
      });
    },
    // 定位
    geolocation() {
      this.aMapLocation.getCurrentPosition();
    },
    // 测距
    ranging() {
      this.isPointing = false;
      this.isRanging = !this.isRanging;
      if (this.isRanging) {
        this.aMap.setDefaultCursor('crosshair');
        this.drawLine();
      } else {
        this.aMap.setDefaultCursor('default');
        this.aMouseTool.close(true);
      }
    },
    // 画线
    drawLine() {
      this.aMouseTool.rule({
        startMarkerOptions: {
          // 可缺省
          icon: new AMap.Icon({
            size: new AMap.Size(19, 31), // 图标大小
            imageSize: new AMap.Size(19, 31),
            image: 'https://webapi.amap.com/theme/v1.3/markers/b/start.png'
          })
        },
        endMarkerOptions: {
          // 可缺省
          icon: new AMap.Icon({
            size: new AMap.Size(19, 31), // 图标大小
            imageSize: new AMap.Size(19, 31),
            image: 'https://webapi.amap.com/theme/v1.3/markers/b/end.png'
          }),
          offset: new AMap.Pixel(-9, -31)
        },
        midMarkerOptions: {
          // 可缺省
          icon: new AMap.Icon({
            size: new AMap.Size(19, 31), // 图标大小
            imageSize: new AMap.Size(19, 31),
            image: 'https://webapi.amap.com/theme/v1.3/markers/b/mid.png'
          }),
          offset: new AMap.Pixel(-9, -31)
        },
        lineOptions: {
          // 可缺省
          strokeStyle: 'solid',
          strokeColor: '#FF33FF',
          strokeOpacity: 1,
          strokeWeight: 2
        },
        tmpLineOptions: {
          strokeStyle: 'dashed',
          strokeColor: '#FF33FF',
          strokeOpacity: 1,
          strokeWeight: 2
        }
      });
    },
    // 选择查询结果
    select(e) {
      this.placeSearch.setCity(e.poi.adcode);
      this.placeSearch.search(e.poi.name); // 关键字查询查询
    },
    // 查询按钮/回车事件
    submitSearch() {
      this.placeSearch.search(this.searchBody);
    },
    // 缩放
    bigger() {
      this.zomm++;
      this.aMap.setZoom(this.zomm);
    },
    smaller() {
      this.zomm--;
      this.aMap.setZoom(this.zomm);
    },

    // 点击数据管理
    handleClickSchool(item) {
      this.placeListDialogShow = true;
      this.placeListDialogTitle = `数据管理 [${item.schoolName}]`;
      this.currentdeptId = item.schoolId;
    },
    // 新增场地
    handleInsertPlace(schoolId) {
      if (this.selectMarker) {
        this.selectMarker.setAnimation('AMAP_ANIMATION_NONE');
        this.selectMarker = null;
      }
      this.placeDialogShow = true;
      this.aMap.setDefaultCursor('default');
      this.isRanging = false;
      this.placeForm = {
        lat: undefined,
        lng: undefined,
        name: undefined,
        address: undefined,
        remark: undefined,
        phone: undefined,
        schoolId: schoolId,
        showInMap: true,
        flagColor: 'red'
      };
    },
    // 编辑场地
    handleEditPlace(item) {
      this.placeDialogShow = true;
      this.aMap.setDefaultCursor('default');
      if (this.selectMarker) {
        this.selectMarker.setAnimation('AMAP_ANIMATION_NONE');
      }
      this.isRanging = false;
      this.placeForm = Object.assign({}, item);
      this.selectMarker = this.placeMarkerList.filter((marker) => marker.getExtData().placeId === item.placeId)[0];
      this.selectMarker && this.selectMarker.setAnimation('AMAP_ANIMATION_BOUNCE');
      this.aMap.setCenter([item.lng, item.lat]);
    },
    getPoint() {
      this.isPointing = !this.isPointing;
    },
    // 保存
    async onSubmit() {
      // 保存接口
      if (this.checkPlaceFormValidate()) {
        // 先访问接口，返回id插入placeForm
        const resp = this.savePlace(this.placeForm);
        if (resp.code != 200) {
          return;
        } else {
          this.$message.success('操作成功');
        }
        if (!this.placeForm.placeId && resp.data) {
          this.$set(this.placeForm, 'placeId', resp.data);
        }
        // 移除选点用 的标记
        this.aMap.remove(this.locationMarker);
        // 根据form创建新marker 并添加到地图上
        const tmpMarker = new AMap.Marker({
          map: this.aMap,
          position: [this.placeForm.lng, this.placeForm.lat],
          icon: require(`@/assets/images/place/flag_${this.placeForm.flagColor}.png`),
          label: {
            content: this.placeForm.name,
            direction: 'right'
          },
          extData: this.placeForm
        });
        // 新marker事件
        tmpMarker.on('click', this.handleClickMarker);
        // 如果当前选择的marker点存在（编辑）
        if (this.selectMarker) {
          // 地图上 移除选择的点
          this.aMap.remove(this.selectMarker);
          this.selectMarker = null;
        }
        // 关闭场地弹窗
        this.placeDialogShow = false;
        this.isPointing = false;

        // 场地列表 移除原列表中操作的场地数据
        const tmpArr = this.tableData.filter((item) => item.placeId !== this.placeForm.placeId);
        // 新增新的场地
        tmpArr.push(this.placeForm);
        // 重置场地数组
        this.tableData = tmpArr;
        // 地图marker列表 移除操作的原marker 添加新marker进数组
        const tmpArr1 = this.placeMarkerList.filter((item) => item.getExtData().placeId !== this.placeForm.placeId);
        tmpArr1.push(tmpMarker);
        this.placeMarkerList = tmpArr1;
      }
    },
    async savePlace(item) {
      if (item.placeId) {
        return updatePlace(item);
      } else {
        return addPlace(item);
      }
    },
    checkPlaceFormValidate() {
      const valid = [];
      if (!this.placeForm.name) {
        valid.push('名称');
      }
      if (!this.placeForm.address) {
        valid.push('地址');
      }
      if (!this.placeForm.lng) {
        valid.push('经度');
      }
      if (!this.placeForm.lat) {
        valid.push('纬度');
      }
      if (!this.placeForm.phone) {
        valid.push('电话');
      }
      if (valid.length == 0) {
        return true;
      } else {
        this.$message.error(`请将以下填写完整: ${valid.join(',')}`);
        return false;
      }
    },
    // 关闭场地弹窗
    closePlaceDialog() {
      this.placeDialogShow = false;
      this.isPointing = false;
      this.aMap.remove(this.locationMarker);
      if (this.selectMarker) {
        this.selectMarker.setAnimation('AMAP_ANIMATION_NONE');
        this.selectMarker = null;
      }
    },
    handleClickMarker(ev) {
      if (this.selectMarker) {
        this.selectMarker.setAnimation('AMAP_ANIMATION_NONE');
      }
      this.placeForm = ev.target.getExtData();
      this.placeDialogShow = true;
      ev.target.setAnimation('AMAP_ANIMATION_BOUNCE');
      this.selectMarker = ev.target;
    },
    getPageData() {
      getMapData().then((resp) => {
        if (resp.code == 200) {
          this.schoolList = resp.data.schoolList;
          this.tableData = resp.data.placeList;
          this.currentdeptId = this.schoolList[0].schoolId;
          this.createMarkersInMap();
        }
      });
    },
    getCount(schoolId) {
      return this.tableData.filter((item) => item.schoolId === schoolId).length;
    },
    // 重置markers
    resetMarkers() {
      this.aMap.clearMap();
      this.createMarkersInMap();
    },
    // 生成markers
    createMarkersInMap() {
      for (let i = 0; i < this.tableData.length; i++) {
        const element = this.tableData[i];
        const tempSchool = this.schoolList.filter((item) => item.schoolId === element.schoolId)[0];
        if (!element.schoolShow || !element.showInMap) {
          continue;
        }
        const tmpMarker = new AMap.Marker({
          map: this.aMap,
          position: [element.lng, element.lat],
          icon: require(`@/assets/images/place/flag_${element.flagColor}.png`),
          label: {
            content: element.name,
            direction: 'right'
          },
          extData: element
        });
        tmpMarker.on('click', this.handleClickMarker);
        this.placeMarkerList.push(tmpMarker);
      }
    },
    // 修改驾校状态
    changeSchoolStatus(item) {
      // 访问接口，成功后重置markers
      updateSchoolStatus(item).then((resp) => {
        if (resp.code == 200) {
          this.$message.success('操作成功');
          // this.aMap.clearMap()
          // this.getPageData()
          this.resetMarkers();
        }
      });
    },
    // 修改场地状态
    async changePlaceStatus(item) {
      const resp = await updatePlace(item);
      if (resp.code == 200) {
        this.resetMarkers();
      }
    }
  }
};
</script>

<style scoped>
.amap-page-container {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

.amap-cavans {
  width: 100%;
  height: 100%;
}

.asider {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
  height: 100%;
  transition: 0.3s;
  z-index: 9;
}

.box-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

::v-deep .el-card__header {
  padding: 10px 15px;
}

.clearfix {
  display: flex;
}

.clearfix .map-card-title {
  flex: 1;
  line-height: 30px;
}

.clearfix .add-icon {
  width: auto;
  height: 30px;
}

.asider-sub {
  position: absolute;
  top: 40px;
  left: -45px;
  padding: 10px 10px 0 0;
  z-index: 900;
}

.asider-sub .is-circle {
  display: block;
  margin: 0;
  padding: 10px;
  color: #464646;
  border-radius: 0;
  font-size: 16px;
  box-shadow: 2px 2px 2px rgba(80, 80, 80, 0.67);
}

.mt10 {
  margin-top: 10px;
}

.hidden-school {
  transform: translateX(300px);
}

.search-body {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 400px;
}

.add-place-btn {
  float: right;
  border: none;
  font-size: 16px;
  color: #409eff;
}

::v-deep .place-dialog {
  position: absolute;
  left: 20px;
  top: 60px;
  width: 350px;
}

.map-tip {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 150px;
  padding: 5px;
  border-radius: 2px;
  background: #000;
  color: #fff;
  opacity: 0.7;
  font-size: 12px;
  transition-duration: 1ms;
}

.circle {
  position: absolute;
  left: -8px;
  top: -25px;
  font-size: 24px;
  color: red;
  transition-duration: 1ms;
}

.place-dialog .el-form .el-form-item {
  margin-bottom: 8px;
}

.place-list-dialog {
  position: absolute;
  top: 420px;
  left: 0;
  bottom: 0;
  transition: 0.3s;
  z-index: 151;
  background: #e2e5ea;
}

.place-list-dialog .add-icon {
  font-size: 18px;
  border: none;
}

.hidden-place-list {
  transform: translateY(100%);
}

.place-list-dialog .clearfix .map-card-title {
  font-weight: bold;
}

.place-list-dialog .clearfix .map-card-title .el-input {
  margin-left: 20px;
  width: 240px;
}

.actived-school {
  border: 2px solid #409eff !important;
}

::v-deep .el-radio__label {
  vertical-align: middle;
}
</style>
