<template> <view class="page"> <u-navbar :title="getTitle" :border-bottom="false" :background="bgc" title-color='#000' title-size='36' height='45'> </u-navbar> <view class="content"> <view class="form-item"> <text class="label">区域名称</text> <u-input v-model="formData.parkingName" placeholder="请输入区域名称" /> </view> <view class="form-item"> <text class="label">区域类型</text> <picker :range="typeList" range-key="text" @change="handleTypeChange"> <view class="type-selector"> <text>{{ getTypeName(formData.type) }}</text> <u-icon name="arrow-right"></u-icon> </view> </picker> </view> <view class="form-item"> <text class="label">误差范围(米)</text> <u-input v-model="formData.error" type="number" placeholder="请输入误差范围" /> </view> <view class="form-item"> <text class="label">区域图片</text> <view class="image-upload"> <image v-if="formData.picture" :src="formData.picture" mode="aspectFill" class="preview-image" @tap="previewImage" /> <view v-else class="upload-btn" @tap="chooseImage"> <u-icon name="plus" size="40"></u-icon> </view> <view v-if="formData.picture" class="delete-btn" @tap="deletePic"> <u-icon name="close" color="#fff" size="20"></u-icon> </view> </view> </view> <view class="form-item"> <text class="label">区域坐标</text> <view class="map-container"> <map id="map" :latitude="mapCenter.latitude" :longitude="mapCenter.longitude" :polygons="polygons" scale="19"></map> </view> <!-- <view class="map-tips">点击地图添加坐标点,至少需要3个点形成区域</view> --> <view class="clear-btn" @tap="toSetmap"> 修改区域 </view> </view> <view class="form-item"> <text class="label">备注</text> <u-input v-model="formData.remark" type="textarea" placeholder="请输入备注信息" /> </view> <view class="btn-group"> <u-button type="primary" @click="handleSubmit">保存</u-button> <u-button @click="goBack">取消</u-button> </view> </view> </view> </template> <script> export default { data() { return { bgc: { backgroundColor: "#fff", }, areaId: '', parkingId: '', typeList: [ { text: '停车区', value: '1' }, { text: '禁停区', value: '2' }, { text: '禁行区', value: '3' } ], formData: { parkingName: '', type: '', error: '', picture: '', remark: '', boundary: '', boundaryStr: '', longitude: '', latitude: '', }, mapCenter: { latitude: 27.105722, longitude: 120.25721 }, areaInfo: {}, polygons: [], coordinates: [], token: '', // 添加七牛云token upurl: '', // 添加上传域名 } }, computed: { getTitle() { const action = this.parkingId ? '修改' : '新增' return `${action}${this.getTypeName(this.formData.type)}` } }, onLoad(e) { this.parkingId = e.parkingId this.formData.type = e.type // 获取七牛云上传token this.getQiniuToken() this.areaId = uni.getStorageSync('adminAreaid') this.getArea() if (this.parkingId) { this.getParkingDetail() } }, methods: { getArea() { let id = this.areaId this.$u.get("/app/area/" + id).then((res) => { if (res.code == 200) { this.areaInfo = res.data } else { uni.showToast({ title: res.msg, icon: 'none', duration: 2000 }); } }); }, // 获取类型名称 getTypeName(type) { const typeMap = { '1': '停车区', '2': '禁停区', '3': '禁行区' } return typeMap[type] || '请选择区域类型' }, // 处理类型选择 handleTypeChange(e) { const index = e.detail.value this.formData.type = this.typeList[index].value }, // 获取详情 getParkingDetail() { this.$u.get(`/app/parking/${this.parkingId}`).then(res => { if (res.code === 200) { const data = res.data this.formData = { parkingName: data.parkingName, type: data.type, error: data.error, picture: data.picture, remark: data.remark, boundary: data.boundary, boundaryStr: data.boundaryStr, longitude: data.longitude, latitude: data.latitude } // 设置地图数据 if (data.boundaryStr) { this.coordinates = JSON.parse(data.boundaryStr) this.updatePolygons() } // 设置地图中心点 if (data.latitude && data.longitude) { this.mapCenter = { latitude: Number(data.latitude), longitude: Number(data.longitude) } } } }) }, // 选择图片 chooseImage() { uni.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: (res) => { this.uploadImage(res.tempFilePaths[0]) } }) }, // 获取七牛云token getQiniuToken() { this.$u.get("/common/qiniu/uploadInfo").then((res) => { if (res.code == 200) { this.token = res.token this.upurl = res.domain } }); }, // 上传图片 uploadImage(filePath) { uni.showLoading({ title: '上传中...' }) const math = 'static/' + this.$u.guid(20) uni.uploadFile({ url: 'https://up-z2.qiniup.com', filePath: filePath, name: 'file', formData: { token: this.token, key: 'bike/img/' + math }, success: (res) => { const response = JSON.parse(res.data) if (response.key) { this.formData.picture = this.upurl + '/' + response.key uni.showToast({ title: '上传成功', icon: 'success' }) } else { uni.showToast({ title: '上传失败', icon: 'none' }) } }, fail: () => { uni.showToast({ title: '上传失败', icon: 'none' }) }, complete: () => { uni.hideLoading() } }) }, // 预览图片 previewImage() { if (this.formData.picture) { uni.previewImage({ urls: [this.formData.picture] }) } }, // 删除图片 deletePic() { this.formData.picture = '' }, toSetmap() { if (this.formData.longitude && this.formData.latitude) { uni.navigateTo({ url: `/pages_adminSet/park_map?type=${this.formData.type}&boundaryStr=${encodeURIComponent(this.formData.boundaryStr || '')}&longitude=${this.formData.longitude}&latitude=${this.formData.latitude}` }) } else { uni.navigateTo({ url: `/pages_adminSet/park_map?type=${this.formData.type}&boundaryStr=${encodeURIComponent(this.formData.boundaryStr || '')}&longitude=${this.areaInfo.longitude}&latitude=${this.areaInfo.latitude}` }) } }, // 处理地图返回的数据 handleMapDataReturn(boundaryStr) { this.formData.boundaryStr = boundaryStr const coordinates = JSON.parse(boundaryStr) // 更新 boundary // this.formData.boundary = `POLYGON((${coordinates.map(coord => coord.join(' ')).join(',')}))` // 计算并更新中心点 // const center = this.calculateCenter(coordinates) // this.formData.latitude = String(center.latitude) // this.formData.longitude = String(center.longitude) // 更新地图显示 this.coordinates = coordinates this.updatePolygons() }, // 更新多边形 updatePolygons() { if (this.coordinates.length >= 3) { this.polygons = [{ points: this.coordinates.map(coord => ({ latitude: coord[1], longitude: coord[0] })), strokeWidth: 2, strokeColor: '#007AFF', fillColor: '#007AFF20' }] // 更新表单数据 this.formData.boundaryStr = JSON.stringify(this.coordinates) this.formData.boundary = `POLYGON((${this.coordinates.map(coord => coord.join(' ')).join(',')}))` // 计算中心点 const center = this.calculateCenter() this.formData.latitude = String(center.latitude) this.formData.longitude = String(center.longitude) } }, // 计算中心点 calculateCenter() { const lats = this.coordinates.map(coord => coord[1]) const lngs = this.coordinates.map(coord => coord[0]) return { latitude: (Math.max(...lats) + Math.min(...lats)) / 2, longitude: (Math.max(...lngs) + Math.min(...lngs)) / 2 } }, // 提交表单 handleSubmit() { if (!this.formData.parkingName) { return uni.showToast({ title: '请输入区域名称', icon: 'none' }) } if (!this.formData.type) { return uni.showToast({ title: '请选择区域类型', icon: 'none' }) } if (!this.formData.boundary) { return uni.showToast({ title: '请在地图上绘制区域', icon: 'none' }) } const data = { ...this.formData, areaId: this.areaId } const request = this.parkingId ? this.$u.put('/appVerify/parking', { ...data, parkingId: this.parkingId }) : this.$u.post('/appVerify/parking', data) request.then(res => { if (res.code === 200) { uni.showToast({ title: '保存成功', icon: 'success' }) setTimeout(() => { this.goBack() }, 1500) } else { uni.showToast({ title: res.msg || '保存失败', icon: 'none' }) } }) }, // 返回上一页 goBack() { uni.navigateBack() } } } </script> <style lang="scss"> page { width: 100%; height: 100%; background-color: #f5f5f5; } .page { width: 100%; height: 100%; } .content { padding: 20rpx; } .form-item { background-color: #fff; padding: 20rpx; margin-bottom: 20rpx; border-radius: 8rpx; .label { font-size: 28rpx; color: #333; margin-bottom: 10rpx; display: block; } } .type-selector { display: flex; justify-content: space-between; align-items: center; padding: 20rpx; background-color: #f8f8f8; border-radius: 8rpx; } .image-upload { position: relative; display: inline-block; .preview-image { width: 200rpx; height: 200rpx; border-radius: 8rpx; } .upload-btn { width: 200rpx; height: 200rpx; display: flex; align-items: center; justify-content: center; background-color: #f8f8f8; border-radius: 8rpx; } .delete-btn { position: absolute; top: -20rpx; right: -20rpx; width: 40rpx; height: 40rpx; background-color: rgba(0, 0, 0, 0.5); border-radius: 50%; display: flex; align-items: center; justify-content: center; } } .map-container { width: 100%; height: 500rpx; map { width: 100%; height: 100%; } } .map-tips { font-size: 24rpx; color: #999; margin-top: 10rpx; } .clear-btn { margin-top: 20rpx; text-align: center; color: #007AFF; font-size: 28rpx; } .btn-group { margin-top: 40rpx; display: flex; gap: 20rpx; .u-button { flex: 1; } } </style>