文件
mashangyoujiu/Application/Retail/View/Xcx/delivery_area_simple.html

371 行
13 KiB
HTML
可执行文件

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>配送区域设置</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/index.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.9/theme-chalk/index.css" rel="stylesheet">
<script src="https://map.qq.com/api/gljs?v=1.exp&key=BHHBZ-CVK3Q-PKW5B-BJBDV-PZILV-IIBJA&libraries=service,geometry"></script>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
background: #f5f7fa;
}
.delivery-container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
padding: 20px;
}
.map-wrapper {
position: relative;
height: 500px;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 20px;
}
#deliveryMap {
width: 100%;
height: 100%;
border-radius: 4px;
}
.toolbar {
position: absolute;
top: 10px;
left: 10px;
z-index: 1000;
background: white;
padding: 10px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.draw-btn {
background: #409eff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
.draw-btn:hover {
background: #66b1ff;
}
.draw-btn.active {
background: #f56c6c;
}
.area-list {
margin-top: 20px;
}
.area-item {
border: 1px solid #eee;
border-radius: 4px;
padding: 15px;
margin-bottom: 10px;
background: #fafafa;
}
.area-item h4 {
margin: 0 0 10px 0;
color: #333;
}
.area-info {
color: #666;
font-size: 14px;
}
.area-actions {
margin-top: 10px;
}
.area-actions button {
margin-right: 10px;
padding: 4px 12px;
border: 1px solid #ddd;
background: white;
border-radius: 3px;
cursor: pointer;
}
.area-actions button:hover {
background: #f0f0f0;
}
.status-info {
background: #e6f7ff;
border: 1px solid #91d5ff;
border-radius: 4px;
padding: 10px;
margin-bottom: 20px;
color: #0050b3;
}
</style>
</head>
<body>
<div id="app" class="delivery-container">
<h2>配送区域设置</h2>
<div class="status-info">
<span v-if="!isDrawing">点击"开始绘制"按钮,然后在地图上点击多个点来创建配送区域</span>
<span v-else>绘制模式:在地图上点击添加边界点,已添加 {{currentPoints.length}} 个点</span>
</div>
<div class="map-wrapper">
<div class="toolbar">
<button class="draw-btn" :class="{active: isDrawing}" @click="toggleDraw">
{{isDrawing ? '完成绘制' : '开始绘制'}}
</button>
<button class="draw-btn" @click="clearCurrent" v-if="isDrawing">取消</button>
<button class="draw-btn" @click="clearAll" v-if="deliveryAreas.length > 0">清空全部</button>
</div>
<div id="deliveryMap"></div>
</div>
<div class="area-list" v-if="deliveryAreas.length > 0">
<h3>配送区域列表 ({{deliveryAreas.length}}个)</h3>
<div class="area-item" v-for="(area, index) in deliveryAreas" :key="index">
<h4>配送区域 {{index + 1}}</h4>
<div class="area-info">
面积: {{area.area}} 平方米 | 边界点: {{area.points.length}}个
</div>
<div class="area-actions">
<button @click="locateArea(area)">定位</button>
<button @click="deleteArea(index)">删除</button>
</div>
</div>
</div>
<!-- 隐藏的表单字段,用于提交数据 -->
<input type="hidden" name="delivery_areas" :value="deliveryAreasJson">
</div>
<script>
new Vue({
el: '#app',
data: {
map: null,
isDrawing: false,
currentPoints: [],
currentPolyline: null,
deliveryAreas: [],
polygons: []
},
computed: {
deliveryAreasJson() {
return JSON.stringify(this.deliveryAreas);
}
},
mounted() {
this.initMap();
},
methods: {
// 初始化地图
initMap() {
this.map = new TMap.Map('deliveryMap', {
center: new TMap.LatLng(39.984104, 116.307503),
zoom: 12
});
// 绑定地图点击事件
this.map.on('click', this.onMapClick);
},
// 地图点击事件
onMapClick(evt) {
if (!this.isDrawing) return;
const latLng = evt.latLng;
this.currentPoints.push(latLng);
// 更新绘制线条
this.updateDrawingLine();
},
// 更新绘制线条
updateDrawingLine() {
if (this.currentPolyline) {
this.currentPolyline.setMap(null);
}
if (this.currentPoints.length > 1) {
this.currentPolyline = new TMap.MultiPolyline({
map: this.map,
styles: {
'drawing': {
color: '#3777FF',
width: 3,
borderColor: '#FFF',
borderWidth: 2
}
},
geometries: [{
styleId: 'drawing',
paths: this.currentPoints
}]
});
}
},
// 切换绘制状态
toggleDraw() {
if (this.isDrawing) {
this.finishDrawing();
} else {
this.startDrawing();
}
},
// 开始绘制
startDrawing() {
this.isDrawing = true;
this.currentPoints = [];
this.$message.success('开始绘制配送区域,请在地图上点击添加边界点');
},
// 完成绘制
finishDrawing() {
if (this.currentPoints.length < 3) {
this.$message.warning('至少需要3个点才能形成区域');
return;
}
// 创建多边形
const polygon = new TMap.MultiPolygon({
map: this.map,
styles: {
'area': {
color: 'rgba(55, 119, 255, 0.3)',
borderColor: '#3777FF',
borderWidth: 2
}
},
geometries: [{
styleId: 'area',
paths: [this.currentPoints]
}]
});
// 计算面积
const area = this.calculateArea(this.currentPoints);
// 保存区域数据
const areaData = {
points: this.currentPoints.map(p => ({lat: p.lat, lng: p.lng})),
area: Math.round(area),
polygon: polygon
};
this.deliveryAreas.push(areaData);
this.polygons.push(polygon);
// 清理绘制状态
this.clearDrawing();
this.$message.success(`配送区域创建成功,面积: ${Math.round(area)} 平方米`);
},
// 清理绘制状态
clearDrawing() {
this.isDrawing = false;
this.currentPoints = [];
if (this.currentPolyline) {
this.currentPolyline.setMap(null);
this.currentPolyline = null;
}
},
// 取消当前绘制
clearCurrent() {
this.clearDrawing();
this.$message.info('已取消绘制');
},
// 清空所有区域
clearAll() {
this.$confirm('确定要清空所有配送区域吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 清除地图上的多边形
this.polygons.forEach(polygon => {
polygon.setMap(null);
});
this.deliveryAreas = [];
this.polygons = [];
this.clearDrawing();
this.$message.success('已清空所有配送区域');
});
},
// 定位到指定区域
locateArea(area) {
if (area.points.length > 0) {
const bounds = new TMap.LatLngBounds();
area.points.forEach(point => {
bounds.extend(new TMap.LatLng(point.lat, point.lng));
});
this.map.fitBounds(bounds, {padding: 50});
}
},
// 删除指定区域
deleteArea(index) {
this.$confirm('确定要删除这个配送区域吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 从地图上移除多边形
if (this.polygons[index]) {
this.polygons[index].setMap(null);
this.polygons.splice(index, 1);
}
this.deliveryAreas.splice(index, 1);
this.$message.success('配送区域已删除');
});
},
// 计算多边形面积
calculateArea(points) {
if (points.length < 3) return 0;
let area = 0;
const earthRadius = 6371000; // 地球半径(米)
for (let i = 0; i < points.length; i++) {
const j = (i + 1) % points.length;
const lat1 = points[i].lat * Math.PI / 180;
const lat2 = points[j].lat * Math.PI / 180;
const lng1 = points[i].lng * Math.PI / 180;
const lng2 = points[j].lng * Math.PI / 180;
area += (lng2 - lng1) * (2 + Math.sin(lat1) + Math.sin(lat2));
}
area = Math.abs(area * earthRadius * earthRadius / 2);
return area;
}
}
});
</script>
</body>
</html>