bike/pages_adminSet/Parking_set.vue
2024-12-21 15:41:58 +08:00

495 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>