vue2用高德地图实现绘制多边形电子围栏

vue2+高德地图实现绘制多边形电子围栏

文章如有错漏之处,还望不吝赐教,诸君共勉

文章末尾会贴出所有代码,有注释,可以直接去看
不行,我高估csdn了,他这个代码块一次粘贴不下,相信各位都有这个拼接的能力
嫌麻烦可以直接下资源

在这里插入图片描述

查询新增逻辑介绍

1.页面打开时查询已录入的电子围栏
----1.1.创建围栏实例并将表单信息塞入实例,挨个add到地图里
2.点击右上角绘制按钮绘制电子围栏
----2.1.双击左键或单机右键结束绘制,并显示信息录入表单
----2.2.禁用绘制按钮
----2.3.将信息录入完整后点击保存按钮调用新增接口
--------2.3.1.新增接口返回成功后创建高德地图Text实例,获取围栏中心 点后,将Text实例根据中心点加入地图
--------2.3.2.将表单信息塞入围栏实例中并关闭信息录入表单,解除绘制按钮禁用
----2.4.点击取消将电子围栏从地图上删除并关闭信息录入表单,解除绘制按钮禁用

接下来是编辑删除逻辑介绍

在这里插入图片描述

1.双击电子围栏进入编辑状态,将围栏携带的表单数据赋值给信息录入表单并显示
2.修改完后点击保存按钮
----2.1.接口返回后将text实例更新,并关闭编辑状态和信息录入表单
3.信息录入表单显示删除按钮
----3.1.删除后将围栏实例和Text实例从地图移除,并关闭信息录入表单

高德地图文档地址
https://lbs.amap.com/api/javascript-api-v2/guide/abc/amap-vue

下载依赖

npm i @amap/amap-jsapi-loader --save

在main.js文件中加一个高德地图key全局变量

Vue.prototype.$aMapKey = "你在高德开放平台申请的key";// 高德地图key

登录高德开放平台在浏览器地址栏里粘贴下面地址
https://console.amap.com/dev/key/app
添加Key
然后选择 Web端(JS API)

然后在vue文件中的 script 标签下引入高德地图的加载方法

import AMapLoader from '@amap/amap-jsapi-loader';

在 template 标签中添加一个 div 标签作为地图容器
切记一定要 给一个确定的宽高
经过计算的宽高会导致地图无法加载,例如css中的 calc()
我是在父容器给的
给标签设置id的时候要注意 整个项目的id不能有重复的 因为vue的节点是虚拟的,给两个一样的id可能会导致地图加载失败,echarts同理

<div v-loading="loading" id="bzdContainer" class="am-map" style="width:100%;height: 100%;"></div>

给地图加个搜索的控件,不需要可以跳过
~~ ~~
当初找这个搜索控件找了好久,裂开,索性一起说了吧
我直接掏他档间一个绝对定位给它扔到左上角
input一定要加 type=“text”

<div class="sarch-city">
  地图搜索:
  <input id="pickerInput" type="text" />
</div>

~~ ~~
接下来就是js环节了,啊……忘了一步
给页面加一个性感的绘制按钮
disabled是防止在绘制完成后录入表单时用户想不开再次点击绘制按钮

<el-button class="draw" type="success" icon="el-icon-edit" :disabled="isHave" circle @click="drawPolygon" ></el-button>

再来个绘制完后的表单录入
这个颜色更改做出来了,但是领导说没必要,我就给注了,一会儿顺便说一下

<div v-show="showPolygonForm" class="form-div" >

  <el-form ref="polygonForm" :model="polygonForm" size="mini" label-width="90px">

    <el-form-item label="停车场名称">
      <el-input v-model="polygonForm.name"></el-input>
    </el-form-item>
    <el-form-item label="联系人">
      <el-input v-model="polygonForm.lotPeople"></el-input>
    </el-form-item>
    <el-form-item label="联系电话">
      <el-input v-model="polygonForm.lotPhone"></el-input>
    </el-form-item>

    <!-- <el-form-item label="停车场颜色">
      <el-color-picker v-model="polygonForm.color" size="mini" @change="setNowColor"></el-color-picker>
    </el-form-item> -->

  </el-form>

  <!-- 新增/编辑 操作按钮-->
  <div class="form-footer" >
    <div>
      <el-button v-loading="saveLoading" type="primary" size="mini" @click="submit">保存</el-button>
      <el-button size="mini" @click="cancel" >取消</el-button>
      <el-button v-loading="saveLoading" v-show="!isNew" type="danger" size="mini" @click="doDelLot">删除</el-button>
    </div>
  </div>
</div>

接下来就是js环节了
首先 return 定义一下


// 地图loading
loading: false,
// 按钮loading
saveLoading: false,
// 显示电子停车场表单
showPolygonForm: false,
// 是否为新增
isNew: false,
// 是否正在绘制
isHave: false,

// 地图
map: null,
// 编辑工具
polyEditor: null,

// 电子停车场数据集
polygonArr: [],
// 电子停车场label数据集
labelArr: [],
// 当前电子停车场
nowPolygon: null,
// 当前电子停车场label
nowLabel: null,

// 电子停车场搜索表单
searchForm: {
  fenceName: '', // 电子停车场名称
  lotPeople: '', // 电子停车场类型
  lotPhone: '', // 电子停车场类型
},

// 电子停车场弹窗表单
polygonForm: {
  id: null,
  name: '', // 电子停车场名称
  lotPeople: '', // 联系人
  lotPhone: '', // 联系电话
  lnglat: '', //经纬度
  // color: '#409EFF'
},

然后方法
看注释吧…… 旁边有个傻gay后台一直搞我心态

// 获得图形的中心点
getCenterPoint(path) {
	let x = 0.0;
	let y = 0.0;
	for (let i = 0; i < path.length; i++) {
	 x = x + parseFloat(path[i].lng);
	 y = y + parseFloat(path[i].lat);
	}
	x = x / path.length;
	y = y / path.length;
	return new AMap.LngLat(x, y);
},

// 电子停车场加label
showText(polygon, name) {
	var point = this.getCenterPoint(polygon.getPath());  //获得中心点
	var label = new AMap.Text({
	 text: name,
	 anchor: 'center', // 设置文本标记锚点
	 style: {
	   'text-shadow': 'white 1px 0 0, white 0 1px 0, white -1px 0 0, white 0 -1px 0', 
	   'background-color': 'transparent',
	   'font-weight': 700,
	   'border-width': 0,
	   'text-align': 'center',
	   'font-size': '14px',
	   'color': '#409EFF',
	 },
	 position: point
	});
	// 将Text实例设入地图
	label.setMap(this.map);
	return label;
},
// 初始化地图
initAMap() {
  const _this = this
  // 加载高德地图
  AMapLoader.load({
      key: _this.$aMapKey,  //设置高德地图申请的key
      version: "2.0",  // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
      plugins: ['AMap.ToolBar', 'AMap.PolygonEditor'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
      AMapUI: {
          version: "1.1",
          plugins: []
      },
      Loca: {
          version: "2.0"
      },
  }).then(async (AMap) => {
      _this.map = await new AMap.Map("bzdContainer", { //设置地图容器id
          viewMode: "2D",  // 默认使用 2D 模式
          mapStyle: 'amap://styles/whitesmoke', //设置地图的显示样式
          zoom: 10 //初始化地图层级
      });

      // 地图搜索控件
      new AMapUI.loadUI(['misc/PoiPicker'], (PoiPicker) => {
        // 根据input的id创建实例
        const poiPicker = new PoiPicker({
            input: 'pickerInput'
        });
        //用户选中的poi点信息
        poiPicker.on('poiPicked', function(poiResult) {
          // 设置地图中心点
          _this.map.setCenter(poiResult.item.location);
        });
        
      });
      // 图层样式切换控件(卫星图)
      AMapUI.loadUI(['control/BasicControl'], function(BasicControl) {

        //图层切换控件
        _this.map.addControl(new BasicControl.LayerSwitcher({
            position: 'rb' // 右下角
        }));

      });

      // 初始化编辑插件
      _this.polyEditor = await new AMap.PolygonEditor(_this.map)
      _this.polyEditor._opt.createOptions = { // 创建区域的样式
        fillColor: "#409EFF", // 多边形填充颜色,使用16进制颜色代码赋值,如:#00B2D5
        fillOpacity: 0.3, // 多边形填充透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.5
        strokeWeight: 3, // 轮廓线宽度
        strokeColor: "#409EFF", // 线条颜色,使用16进制颜色代码赋值。默认值为#00D3FC
        strokeOpacity: 1, // 轮廓线透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.5
      };
      _this.polyEditor._opt.editOptions = {// 编辑区域的样式
        fillColor: "#409EFF",
        fillOpacity: 0.3,
        strokeWeight: 3,
        strokeColor: "#409EFF",
        strokeOpacity: 1,
      };

      //多边形添加
      _this.polyEditor.on('add', function (data) {
        // 获取电子停车场参数
        var polygon = data.target;
        _this.nowPolygon = polygon
        _this.showPolygonForm = true
        // 获取给停车场设置标题 不能给空字符串,不然会创建失败,给个空格可以实现新创建的停车场没有标题效果
        let label = _this.showText(polygon, " ");
        _this.nowLabel = label

        // 加个双击监听 双击图层进行编辑
        polygon.on('dblclick', () => {
          if (_this.polyEditor) {
            // 将触发的围栏实例和Text实例拿出来存好
            _this.nowPolygon = polygon
            _this.nowLabel = label
            // 打开信息录入表单
            _this.showPolygonForm = true
            // 禁用绘制按钮
            _this.isHave = true
            // 不是新增
            _this.isNew = false
            // 将围栏携带的数据复制到表单中
            _this.polygonForm.id = polygon._opts.extData.mapId
            _this.polygonForm.name = polygon._opts.extData.fenceName
            _this.polygonForm.lotPeople = polygon._opts.extData.lotPeople
            _this.polygonForm.lotPhone = polygon._opts.extData.lotPhone
            // 给编辑器设定要编辑的围栏实例
            _this.polyEditor.setTarget(polygon);
            // 打开编辑器
            _this.polyEditor.open();
          }
        })
      })
      // 获取停车场数据
      _this.getLotData()
  }).catch(e => {
      console.log(e);
  })
},

// 获取电子停车场数据并渲染
async getLotData() {
  this.loading = true
  // 先清空地图覆盖物
  await this.map.clearMap()
  let dealPolygonArr = []
  let dealLabelArr = []
  this.polygonArr = []
  this.polygonArr = []
  
  // 调用后台接口获得一堆携带经纬度的围栏数据
  const polygonRes = await listLot(this.searchForm)
  if (polygonRes.code === 200) {
    // 循环创建围栏实例
    for (let item of polygonRes.rows) {
      // 字符串转数字(这方法原来是用来计算的)
      let path = eval(item.fencePoint)
      let fence = new AMap.Polygon({
        path: path, // 经纬度
        fillColor: "#409EFF",
        fillOpacity: 0.3,
        strokeWeight: 3,
        strokeColor: "#409EFF",
        strokeOpacity: 1,
        zIndex: 1, // 围栏层级
        extData: { // 额外携带参数
          mapId: item.id,
          fenceName: item.fenceName,
          lotPeople: item.lotPeople,
          lotPhone: item.lotPhone,
        }
      })
      // 创建Text实例
      let label = this.showText(fence, item.fenceName);
      // 这里生成的围栏也得加双击监听 双击图层进行编辑
      fence.on('dblclick', () => {
        if (this.polyEditor) {
          this.nowPolygon = fence
          this.nowLabel = label
          this.showPolygonForm = true
          this.isHave = true
          this.isNew = false
          this.polygonForm.id = fence._opts.extData.mapId
          this.polygonForm.name = fence._opts.extData.fenceName
          this.polygonForm.lotPeople = fence._opts.extData.lotPeople
          this.polygonForm.lotPhone = fence._opts.extData.lotPhone
          this.polyEditor.setTarget(fence);
          this.polyEditor.open();
        }
      })
      // 将电子停车场存入集合
      dealPolygonArr.push(fence)
      this.polygonArr = dealPolygonArr
      // 将电子停车场label存入集合
      dealLabelArr.push(label)
      this.labelArr = dealLabelArr
    }
    // 地图上批量添加围栏实例
    this.map.add(this.polygonArr);
    // 缩放地图到合适的视野级别 setFitView传入什么就根据什么缩放
    // 什么都不传就根据地图上所有覆盖物进行缩放
    this.map.setFitView(this.polygonArr)
    this.loading = false
  } else {
    Message({
      type:"warning",
      message: polygonRes.msg
    })
    this.loading = false
  }
},
    // 绘制电子停车场
    drawPolygon() {
      // 禁用绘制按钮
      this.isHave = true
      // 新增状态
      this.isNew = true
      // 关闭一下编辑器,防止出bug
      this.polyEditor.close();
      // 置空编辑区即为新增
      this.polyEditor.setTarget();
      // 打开编辑器即可开始绘制
      this.polyEditor.open();
    },

    // 保存电子停车场
    async submit() {
      this.saveLoading = true
      // 验证必填
      if (this.polygonForm.name === null || this.polygonForm.name === '') {
        Message({
          type:"warning",
          message: "请输入电子停车场名称"
        })
        this.saveLoading = false
        return
      }
      // 获取电子围栏的所有点
      const arr = await this.nowPolygon.getPath()
      const pathArr = []

      // 将获取的停车场坐标点转换格式后存入数组
      for (let item of arr) {
        const list = [item.lng, item.lat]
        pathArr.push(list)
      }
      // 将坐标点集合转为json字符串
      const pointString = await JSON.stringify(pathArr)
      let obj = {
        id: this.polygonForm.id,
        fenceName: this.polygonForm.name,
        lotPeople: this.polygonForm.lotPeople,
        lotPhone: this.polygonForm.lotPhone,
        fencePoint: pointString,
        // fenceColor: this.polygonForm.color
      }
      let response = null

      // 判断是否为新增电子停车场
      if (this.isNew) {
        response = await addLot(obj)
      } else {
        response = await updateLot(obj)
      }
      // 后台新增接口返回成功时
      if(response.code === 200) {
        // 关闭编辑器
        this.polyEditor.close();
        // 新增成功后将电子停车场名称设置到地图
        if(this.isNew) {
          // 将新增的围栏加入围栏数据集中
          this.polygonArr.push(this.nowPolygon)
          // 将输入的标题设置到当前Text实例里
          this.nowLabel.setText(response.data.fenceName)
          // 设置围栏携带参数
          this.nowPolygon._opts.extData = {
            mapId: response.data.id,
            fenceName: response.data.fenceName,
            lotPeople: response.data.lotPeople,
            lotPhone: response.data.lotPhone,
          }
        } else {
          // 将输入的标题设置到当前Text实例里
          this.nowLabel.setText(obj.fenceName)
          // 更新围栏携带参数
          this.nowPolygon._opts.extData = {
            mapId: obj.id,
            fenceName: obj.fenceName,
            lotPeople: obj.lotPeople,
            lotPhone: obj.lotPhone,
          }
        }
        // 清空表单
        this.polygonForm.id = null
        this.polygonForm.name =  ""
        this.polygonForm.lotPeople =  ""
        this.polygonForm.lotPhone =  ""
        // 解除按钮禁用
        this.isHave = false
        this.isNew = false
        // 关闭信息录入表单
        this.showPolygonForm = false
        this.saveLoading = false
        Message({
          type: "success",
          message: response.msg
        })
      } else {
        Message({
          type:"warning",
          message: response.msg
        })
        this.saveLoading = false
      }
    },


    // 取消电子停车场绘制
    cancel() {
      // 如果是新增则删除刚增加的电子围栏
      if (this.isNew) {
        this.map.remove(this.nowPolygon)
      }
      // 关闭编辑器、关闭信息录入表单、重置表单
      this.polyEditor.close();
      this.showPolygonForm = false
      this.isHave = false
      this.polygonForm.id = null
      this.polygonForm.name = ""
      this.polygonForm.lotPeople =  ""
      this.polygonForm.lotPhone =  ""
      this.polygonForm.type = null
    },
    
    // 删除单子停车场
    async doDelLot() {
      this.saveLoading = true
      const response = await delLot(this.polygonForm.id)
      // 等删除接口返回成功时
      if (response.code === 200) {
        // 遍历围栏集合将删除的围栏删除
        for (let i = 0; i < this.polygonArr.length; i++) {
          const element = this.polygonArr[i];
          if(this.nowPolygon === this.polygonArr[i]){
            this.polygonArr.splice(i,1)
            break
          }
        }
        // 在地图删除围栏及标题
        this.map.remove(this.nowPolygon)
        this.map.remove(this.nowLabel)
        // 关闭编辑器、关闭信息录入表单、重置表单
        this.polyEditor.close();
        this.showPolygonForm = false
        this.isHave = false
        this.saveLoading = false
        this.polygonForm.id = null
        this.polygonForm.name = ""
        this.polygonForm.lotPeople =  ""
        this.polygonForm.lotPhone =  ""
        this.polygonForm.type = null
        Message({
          type: "success",
          message: response.msg
        })
      } else {
        this.saveLoading = false
        Message({
          type: "warning",
          message: response.msg
        })
      }
    }

如果我没有满足你,你可以去文档里找找看能不能实现
文档地址:https://lbs.amap.com/api/jsapi-v2/summary/
打开网址后点击参考手册搜索下方关键词
标题实例是 Text
多边形实例是 Polygon
用的编辑器是 PolygonEditor
地图搜索文档地址:https://lbs.amap.com/api/amap-ui/reference-amap-ui/other/poipicker

在这里插入图片描述
完活,开始补代码
首先是template


  <div :style="{height: pheight + 'px'}" class="box">
    <!-- 地图 -->
    <div v-loading="loading" id="bzdContainer" class="am-map" style="width:100%;height: 100%;"></div>

    <div class="sarch-city">
      地图搜索:
      <input id="pickerInput" type="text" />
    </div>

    <!-- 电子停车场搜索表单 -->
    <div class="search-form" >
      <el-form ref="searchForm" :model="searchForm" size="mini" style="display: flex;" label-width="90px">

        <el-form-item label="停车场名称">
          <el-input v-model="searchForm.fenceName" clearable></el-input>
        </el-form-item>

        <el-form-item label="联系人">
          <el-input v-model="searchForm.lotPeople" clearable></el-input>
        </el-form-item>

        <el-form-item label="联系人电话">
          <el-input v-model="searchForm.lotPhone" clearable></el-input>
        </el-form-item>

        <el-button type="primary" size="mini" style="margin-left: 10px;" @click="getLotData">搜索</el-button>
        
        <el-button size="mini" style="margin-left: 10px;" @click="getLotData">重置</el-button>

      </el-form>
    </div>
    

    <!-- 控制按钮组 -->
    <div class="map-button">
      
      <!-- 绘制电子停车场 -->
      <el-button class="draw" type="success" icon="el-icon-edit" :disabled="isHave" circle @click="drawPolygon" ></el-button>
      
    </div>

    <!-- 停车场表单 -->
    <div v-show="showPolygonForm" class="form-div" >

      <el-form ref="polygonForm" :model="polygonForm" size="mini" label-width="90px">

        <el-form-item label="停车场名称">
          <el-input v-model="polygonForm.name"></el-input>
        </el-form-item>
        <el-form-item label="联系人">
          <el-input v-model="polygonForm.lotPeople"></el-input>
        </el-form-item>
        <el-form-item label="联系电话">
          <el-input v-model="polygonForm.lotPhone"></el-input>
        </el-form-item>

        <!-- <el-form-item label="停车场颜色">
          <el-color-picker v-model="polygonForm.color" size="mini" @change="setNowColor"></el-color-picker>
        </el-form-item> -->

      </el-form>

      <!-- 新增/编辑 操作按钮-->
      <div class="form-footer" >
        <div>
          <el-button v-loading="saveLoading" type="primary" size="mini" @click="submit">保存</el-button>
          <el-button size="mini" @click="cancel" >取消</el-button>
          <el-button v-loading="saveLoading" v-show="!isNew" type="danger" size="mini" @click="doDelLot">删除</el-button>
        </div>
      </div>
    </div>
  </div>

OKOK 全体目光看向我 我宣布个事 接下来是script
methods里的方法我已经在上面放了,是连着的,稍微往上找找,很明显的

import AMapLoader from '@amap/amap-jsapi-loader';
import { Message } from  "element-ui"
export default {
  data() {
    return {
      // 地图loading
      loading: false,
      // 按钮loading
      saveLoading: false,
      // 显示电子停车场表单
      showPolygonForm: false,
      // 是否为新增
      isNew: false,
      // 是否正在绘制
      isHave: false,

      // 地图
      map: null,
      // 编辑工具
      polyEditor: null,

      // 电子停车场数据集
      polygonArr: [],
      // 电子停车场label数据集
      labelArr: [],
      // 当前电子停车场
      nowPolygon: null,
      // 当前电子停车场label
      nowLabel: null,

      // 电子停车场搜索表单
      searchForm: {
        fenceName: '', // 电子停车场名称
        lotPeople: '', // 电子停车场类型
        lotPhone: '', // 电子停车场类型
      },

      // 电子停车场弹窗表单
      polygonForm: {
        id: null,
        name: '', // 电子停车场名称
        lotPeople: '', // 联系人
        lotPhone: '', // 联系电话
        lnglat: '', //经纬度
        // color: '#409EFF'
      },
      
      // 地图高度
      pheight: Number(document.body.clientHeight - 85),
    }
  },

  created() {
  },

  mounted() {
    // 调用初始化地图函数
    this.initAMap();
    // 监听页面尺寸变化
    window.addEventListener(
      "resize",
      () => {
        this.pheight = Number(document.body.clientHeight - 85);
      },
      false
    );
  },

接下来 style~


<style scoped>
.box{
  position: relative;
}

.sarch-city{
  text-shadow: white 1px 0 0, white 0 1px 0, white -1px 0 0, white 0 -1px 0;
  font-size: 14px;
  color: #606266;
  font-weight: 700;
  position: absolute;
  height: 20px;
  left: 20px;
  top: 18px;
}

::v-deep .el-form-item__label {
  text-shadow: white 1px 0 0, white 0 1px 0, white -1px 0 0, white 0 -1px 0;
}

.map-button{
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
}
.search-form{
  position: absolute;
  /* background-color: white; */
  padding: 15px;
  border-radius: 10px;
  top: 0px;
  left: 250px;
  z-index: 1;
}

.search-form /deep/ .el-form-item {
  margin-bottom: 0px !important;
}


.form-div{
  position: absolute;
  background-color: white;
  box-shadow:0 0 10px #909399;
  padding: 15px;
  border-radius: 10px;
  top: 10px;
  right: 50px;
  z-index: 1;
}

.form-footer{
  display: flex;
  justify-content: center;
}

.am-map /deep/ .amap-logo{
  display: none !important;
}
.am-map /deep/ .amap-copyright{
  display: none !important;
}
</style>

行,完事了,都散了吧,有时可以留言,我如果记起来我在csdn有号的话会看的

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
Vue是一个流行的JavaScript框架,可以用于构建用户界面。高德地图是一种流行的地图服务,它提供了丰富的地图功能和API。电子围栏是一种边界区域,当特定的设备或人员进入或离开该区域时会触发警报或其他特定操作。 在Vue中使用高德地图电子围栏,首先需要在Vue项目中引入高德地图的JavaScript API,可以通过在index.html文件中引入相应的脚本来实现,然后在组件中使用Vue的生命周期钩子函数进行初始化和销毁。 在组件中,我们可以使用高德地图的API创建一个地图实例,并设置地图的中心点和缩放级别。然后,我们可以使用地图的绘图工具来创建电子围栏多边形或圆形,可以通过监听绘图结束事件来获取围栏的坐标信息。 接下来,我们可以使用高德地图的围栏服务API来创建电子围栏。可以通过调用相应的方法,传入围栏的名称、坐标信息和其他参数来创建电子围栏。可以根据需求设置围栏的类型,如圆形、多边形等,以及警报触发的条件和动作。 在Vue中,可以通过使用指令或绑定事件来实现电子围栏的交互。可以使用v-on指令来监听电子围栏的进入或离开事件,并触发相应的方法或动作。可以在方法中实现警报、通知或其他功能,以响应电子围栏的状态变化。 总之,Vue高德地图电子围栏可以通过使用高德地图的API和Vue的生命周期钩子函数,实现Vue项目中创建和管理电子围栏及其交互的功能。通过结合Vue的灵活性和高德地图的丰富功能,可以实现各种场景下的电子围栏应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值