刘秀芳 пре 5 дана
родитељ
комит
246ac2ba62

BIN
src/assets/images/map/owner1.png


BIN
src/assets/images/map/owner2.png


BIN
src/assets/images/map/status/selected.png


+ 54 - 10
src/views/customTree/index.vue

@@ -54,9 +54,18 @@
                                 BTY-A25
                                 <span class="type-tag">综合:94分</span>
                                 <span class="type-tag">生态:92分</span>
-                                <span class="type-tag">树龄:5年</span>
+                                <!-- <span class="type-tag">树龄:5年</span> -->
                             </div>
-                            <div class="center-item p-t-2">单价:<span>12元/斤</span></div>
+                            <div class="center-item p-t-2 age-line">
+                                <div class="age-wrap">
+                                    <div class="has-age">
+                                        <div class="age">树龄:<span class="unit">5年</span></div>
+                                    </div>
+                                    <div class="sort-line"></div>
+                                </div>
+                                单价:<span class="unit">12元/斤</span>
+                            </div>
+                            <!-- <div class="center-item p-t-2">单价:<span>12元/斤</span></div> -->
                             <div class="center-item" v-show="ROLE==1">总认养斤数:<span>215斤</span></div>
                             <div class="center-item progress-wrap" v-show="ROLE==2">
                                 剩余可购:
@@ -83,20 +92,20 @@
                             />
                         </el-select>
                     </div>
-                    <div class="custom-user">
+                    <div class="custom-user" v-show="ROLE == 2">
                         平均斤数:
-                        <el-select v-model="selectUser" placeholder="选择客户" style="width: 256px">
+                        <el-select v-model="selectNum" placeholder="请选择" style="width: 256px">
                             <el-option
-                                v-for="item in userOptions"
+                                v-for="item in numOptions"
                                 :key="item.value"
                                 :label="item.label"
                                 :value="item.value"
                             />
                         </el-select>
                     </div>
-                    <div class="total">总斤数为<span>250</span>斤</div>
+                    <div class="total" v-show="ROLE == 2">总斤数为<span class="main-unit">250</span>斤</div>
                     <div class="selected-tree" v-show="selectedItems.length">
-                        <div class="tree-text">选择果树:</div>
+                        <div class="tree-text">{{ ROLE === 1 ? "选择果树:" : "优先分配果树:" }}</div>
                         <div
                             class="list-item selected"
                             @click="removeFromSelected(item)"
@@ -126,7 +135,7 @@
                     <!-- 渐变主色按钮 -->
                     <div class="btn-group" v-show="selectedItems.length">
                         <div class="btn cancel-btn">取消</div>
-                        <div class="btn edit-btn">保存</div>
+                        <div class="btn edit-btn">确认定制</div>
                     </div>
                 </div>
             </div>
@@ -165,10 +174,17 @@ const ageOptions = ref([
 const selectUser = ref(null);
 const userOptions = ref([
     { label: "张一", value: 1 },
-    { label: "张二", value: 3 },
+    { label: "张二", value: 2 },
     { label: "张三", value: 3 },
 ]);
 
+const selectNum = ref(null)
+const numOptions = ref([
+    { label: "25 斤/人", value: 1 },
+    { label: "50 斤/人", value: 2 },
+    { label: "100 斤/人", value: 3 },
+]);
+
 const selectedItems = ref([]);
 function selecteTree(id) {
     if (!selectedItems.value.includes(id)) {
@@ -213,7 +229,8 @@ function goBack() {
 
     .back-icon {
         position: absolute;
-        left: 405px;
+        // left: 405px;
+        left: 485px;
         top: 38px;
         cursor: pointer;
         margin-right: 20px;
@@ -309,6 +326,8 @@ function goBack() {
             margin-top: 12px;
             border: 1px solid transparent;
             cursor: pointer;
+            width: calc(25% - 8px);
+            box-sizing: border-box;
             &.selected {
                 background: rgba(243, 193, 29, 0.1);
                 border-color: #f2d677;
@@ -360,6 +379,22 @@ function goBack() {
                         }
                     }
                 }
+                
+                .age-line {
+                    display: flex;
+                    align-items: center;
+                    padding-top: 4px;
+                    .age-wrap {
+                        display: flex;
+                        align-items: center;
+                        .sort-line {
+                            margin: 0 10px;
+                            height: 10px;
+                            width: 1px;
+                            background: #6C6C6C;
+                        }
+                    }
+                }
                 .progress-wrap {
                     display: flex;
                     align-items: center;
@@ -421,6 +456,15 @@ function goBack() {
                         }
                     }
                 }
+                .custom-user + .custom-user {
+                    margin-top: 12px;
+                }
+            }
+            .total {
+                padding-top: 12px;
+            }
+            .main-unit {
+                color: #F3C11D;
             }
             .selected-tree {
                 // display: flex;

+ 3 - 0
src/views/home/components/applyList.vue

@@ -267,6 +267,9 @@ onMounted(() => {console.log('ROLE', ROLE);});
                     .team-time {
                         color: #999999;
                         font-size: 12px;
+                        span {
+                            padding-left: 4px;
+                        }
                     }
                 }
             }

+ 56 - 18
src/views/home/homeMap.vue

@@ -25,6 +25,7 @@ import { Circle, Fill, Stroke, Style, Text } from "ol/style.js";
 import { Cluster, Vector as VectorSource } from "ol/source.js";
 import { boundingExtent } from "ol/extent.js";
 import RegionLayer from "./map/regionLayer";
+import eventBus from "@/api/eventBus";
 
 import { onMounted, ref } from "vue";
 import { useStore } from "vuex";
@@ -114,6 +115,7 @@ function addCluster(treeListData, distanceVal) {
     for (let item of treeListData) {
         let point = newPoint(item);
         features.push(point);
+        console.log('item', item.icon, item);
     }
     const source = new VectorSource({
         features: features,
@@ -169,12 +171,24 @@ function addCluster(treeListData, distanceVal) {
                     }
                     // styleCache[key] = style;
                 }
+                const imgIcon = featureOne.get('icon')
+                console.log('imgIcon', imgIcon);
+                if (imgIcon) {
+                    style = new Style({
+                        image: new Icon({
+                            src: require("@/assets/images/map/owner1.png"),
+                            scale: 1,
+                        }),
+                    });
+                }
                 return style;
             }
             // 多个点位聚合,循环处理得到图标
             const featureObj = feature.get("features")[0];
             // let pointId = featureObj.get('fosterStatus')
             // let style = styleCache[pointId];
+                const imgIcon = featureObj.get('icon')
+                console.log('imgIcon22222', imgIcon);
             let style = false;
             if (!style) {
                 testStyle = new Style({
@@ -198,25 +212,36 @@ function addCluster(treeListData, distanceVal) {
                         }),
                     });
                 } else {
-                    style = new Style({
-                        image: new Circle({
-                            radius: featureObj.get("fosterStatus") === 0 || !featureObj.get("fosterStatus") ? 10 : 12,
-                            fill: new Fill({
-                                color:
-                                    featureObj.get("fosterStatus") === 0
-                                        ? "#ffffff00"
-                                        : featureObj.get("fosterStatus") === 1
-                                        ? "#EEEEEE"
-                                        : featureObj.get("fosterStatus") === 2
-                                        ? "#F0AC37"
-                                        : "#ffffff00",
+                    // 已认养--显示图标
+                    if (imgIcon) {
+                        style = new Style({
+                            image: new Icon({
+                                src: require("@/assets/images/map/owner1.png"),
+                                scale: 1,
                             }),
-                            stroke: new Stroke({
-                                color: "#fff",
-                                width: 1,
+                            zIndex: 22,
+                        });
+                    } else {
+                        style = new Style({
+                            image: new Circle({
+                                radius: featureObj.get("fosterStatus") === 0 || !featureObj.get("fosterStatus") ? 10 : 12,
+                                fill: new Fill({
+                                    color:
+                                        featureObj.get("fosterStatus") === 0
+                                            ? "#ffffff00"
+                                            : featureObj.get("fosterStatus") === 1
+                                            ? "#EEEEEE"
+                                            : featureObj.get("fosterStatus") === 2
+                                            ? "#F0AC37"
+                                            : "#ffffff00",
+                                }),
+                                stroke: new Stroke({
+                                    color: "#fff",
+                                    width: 1,
+                                }),
                             }),
-                        }),
-                    });
+                        });
+                    }
                 }
                 // styleCache[pointId] = style;
             }
@@ -234,15 +259,29 @@ function addCluster(treeListData, distanceVal) {
     listenKey = kmap.on("click", (e) => {
         if (treeClusterLayer) {
             treeClusterLayer.layer.getFeatures(e.pixel).then((clickedFeatures, layer) => {
+                let hasFeatures = false
                 if (clickedFeatures.length) {
                     const features = clickedFeatures[0].get("features");
                     if (features.length > 1) {
+                        hasFeatures = true
                         const extent = boundingExtent(features.map((r) => r.getGeometry().getCoordinates()));
                         kmap.getView().fit(extent, { duration: 1000, padding: [250, 250, 250, 250] });
+
+                        const currentZoom = kmap.getView().getZoom();
+                        if (currentZoom > 17) {
+                            // this.kmap.getView().setZoom(16);
+                            // kmap.getView().animate({
+                            //     zoom: 14,
+                            //     duration: 0 // 动画持续时间,单位为毫秒
+                            // });
+                            kmap.getView().setZoom(17)
+                        }
                     }
                     if (isDrawing.value) {
                         features[0].set("highlight", true);
                         // features[0].setStyle(selectedStyle)
+                    } else if (!hasFeatures) {
+                        eventBus.emit("clickMapPoint", features[0])
                     }
                 }
             });
@@ -270,7 +309,6 @@ defineExpose({ addCluster, enableBoxSelect, stopBoxSelect, initAreaMap });
 // 分区
 let regionLayer = null;
 function initAreaMap(arr) {
-    console.log('aaa', arr);
     regionLayer.initData(arr);
 }
 </script>

+ 20 - 2
src/views/home/index.vue

@@ -40,14 +40,18 @@
                     <img src="@/assets/images/map/status/wry.png" alt="" />
                     未开放认养
                 </div>
-                <div class="item">
+                <div class="item" v-show="!checkShow">
                     <img src="@/assets/images/map/status/dry.png" alt="" />
                     待认养
                 </div>
-                <div class="item">
+                <div class="item" v-show="!checkShow">
                     <img src="@/assets/images/map/status/yry.png" alt="" />
                     已认养
                 </div>
+                <div class="item selected-item" v-show="checkShow">
+                    <img src="@/assets/images/map/status/selected.png" alt="" />
+                    已选择
+                </div>
             </div>
 
             <div class="tips" v-show="checkShow">
@@ -102,6 +106,7 @@ const router = useRouter();
 const mapRef = ref(null);
 
 const activeName = ref('认养列表')
+// 用户角色
 store.commit("home/SET_USER_ROLE", 2);
 onMounted(() => {
     //区域切换监听事件
@@ -123,6 +128,14 @@ const getPointList = () =>{
         // })
         if(mapRef.value){
             nextTick(() => {
+                data[0].icon = "123"
+                data[1].icon = "123"
+                data[100].icon = "123"
+                data[170].icon = "123"
+                data[190].icon = "123"
+                data[10].icon = "123"
+                data[20].icon = "123"
+                data[30].icon = "123"
                 mapRef.value.addCluster(data)
                 // mapRef.value.initData(arr)
                 // mapRef.value.initMap(arr, () =>  mapRef.value.getRegionList(organId.value))
@@ -427,6 +440,11 @@ function backHome() {
                     margin-right: 6px;
                 }
             }
+            .selected-item {
+                img {
+                    width: 24px;
+                }
+            }
             .legend-title {
                 border-bottom: 1px solid rgba(102, 102, 102, 0.35);
             }

+ 146 - 3
src/views/home/map/regionLayer.js

@@ -64,12 +64,33 @@ class RegionLayer {
                         }),
                     }),
                 });
-                return [style1];
-            },
+                // let style2 = that.textBgStyle("#FFD887","#ED9E1E")
+                // 创建带渐变背景的文字样式
+const style2 = that.createTextWithGradientBg(
+    '245/283',  // 文字内容
+    '#FFD887',      // 渐变起始色(蓝色)
+    '#ED9E1E',      // 渐变结束色(深蓝)
+    {
+        offsetX: 50,  // 向右偏移
+        offsetY: -30, // 向上偏移(Y轴向下为正,故用负值)
             });
+                return [style1, style2];
+            },
+        });
+
+        this.textBgStyleCache = {}
+        this.numPointLayer = new KMap.VectorLayer("numLayer", 100, {
+            minZoom: 15,
+            maxZoom: 22,
+            source: new VectorSource({}),
+            style: (feature) => {
+                return that.textBgStyle("#FFD887","#ED9E1E")
+            },
+        });
 
         map.addLayer(this.regionLayer.layer);
         map.addLayer(this.gardenPointLayer.layer);
+        // map.addLayer(this.numPointLayer.layer);
         this.initData(this.farmId);
     }
 
@@ -103,7 +124,6 @@ class RegionLayer {
     }
 
     initData(data) {
-        console.log('da', data);
         if (!data) return
         let that = this;
         let features = [];
@@ -114,6 +134,8 @@ class RegionLayer {
 
             item.wkt = item.pointWkt
             this.gardenPointLayer.source.addFeature(newPoint(item, "wktVal", "myGarden"))
+
+            // this.numPointLayer.source.addFeature(newPoint(item, "wkt", "myGarden"))
         }
         that.area = features
         const source = new VectorSource({
@@ -133,6 +155,127 @@ class RegionLayer {
             this.regionLayer.layer.getSource().clear();
         }
     }
+
+
+/**
+ * 创建带渐变背景的文字样式
+ * @param {string} text - 要显示的文字
+ * @param {string} startColor - 渐变起始颜色(如 '#00c6ff')
+ * @param {string} endColor - 渐变结束颜色(如 '#0072ff')
+ * @param {string} textColor - 文字颜色(默认白色)
+ * @param {number} fontSize - 文字大小(像素,默认12)
+ * @return {Style} OpenLayers 样式对象
+ */
+createTextWithGradientBg(
+    text,
+    startColor,
+    endColor,
+    { textColor = '#fff', fontSize = 12, offsetX = 0, offsetY = 0 } = {}
+  ) {
+    const cacheKey = `${text}_${startColor}_${endColor}_${textColor}_${fontSize}_${offsetX}_${offsetY}`;
+  
+    if (this.textBgStyleCache[cacheKey]) {
+      return this.textBgStyleCache[cacheKey];
+    }
+  
+    const style = new Style({
+      renderer: (coordinates, state) => {
+        const ctx = state.context;
+        const pixelRatio = state.pixelRatio;
+        const x = coordinates[0] + offsetX * pixelRatio; // 应用水平偏移
+        const y = coordinates[1] + offsetY * pixelRatio; // 应用垂直偏移
+  
+        // 文字测量
+        ctx.font = `${fontSize * pixelRatio}px Arial`;
+        const textWidth = ctx.measureText(text).width;
+        const padding = 8 * pixelRatio;
+  
+        // 背景参数
+        const bgWidth = textWidth + 2.5 * padding;
+        const bgHeight = fontSize * 2 * pixelRatio;
+        const cornerRadius = 4 * pixelRatio;
+  
+        // 渐变
+        const gradient = ctx.createLinearGradient(
+          x - bgWidth / 2,
+          y - bgHeight / 2,
+          x + bgWidth / 2,
+          y + bgHeight / 2
+        );
+        gradient.addColorStop(0, startColor);
+        gradient.addColorStop(1, endColor);
+  
+        // 绘制圆角矩形背景
+        this.roundRect(ctx, x - bgWidth / 2, y - bgHeight / 2, bgWidth, bgHeight, cornerRadius);
+        ctx.fillStyle = gradient;
+        ctx.fill();
+  
+        // 绘制文字
+        ctx.fillStyle = textColor;
+        ctx.textAlign = 'center';
+        ctx.textBaseline = 'middle';
+        ctx.fillText(text, x, y);
+      },
+      zIndex: 2,
+    });
+  
+    this.textBgStyleCache[cacheKey] = style;
+    return style;
+  }
+
+/** 辅助函数:绘制圆角矩形 */
+roundRect(ctx, x, y, width, height, radius) {
+  ctx.beginPath();
+  ctx.moveTo(x + radius, y);
+  ctx.lineTo(x + width - radius, y);
+  ctx.arcTo(x + width, y, x + width, y + radius, radius);
+  ctx.lineTo(x + width, y + height - radius);
+  ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
+  ctx.lineTo(x + radius, y + height);
+  ctx.arcTo(x, y + height, x, y + height - radius, radius);
+  ctx.lineTo(x, y + radius);
+  ctx.arcTo(x, y, x + radius, y, radius);
+  ctx.closePath();
+}
+
+    textBgStyle(startColor,endColor){
+        let key = startColor + endColor
+        let style = this.textBgStyleCache[key]
+        if (!style) {
+            style = new Style({
+                renderer: function (coordinates, state) {
+                    let ctx = state.context;
+                    // 矩形的参数
+                    const x = coordinates[0]; // 矩形中心点的x坐标
+                    const y = coordinates[1] - 60 * state.pixelRatio; // 矩形中心点的y坐标
+                    const width = 50 * state.pixelRatio; // 矩形的宽度
+                    const height = 20 * state.pixelRatio; // 矩形的高度
+                    const cornerRadius = 4 * state.pixelRatio; // 圆角半径
+                    // 创建渐变
+                    const gradient = ctx.createLinearGradient(x - width / 2, y, x + width / 2, y);
+                    gradient.addColorStop(0, startColor);   // 渐变起始颜色
+                    gradient.addColorStop(1, endColor);  // 渐变结束颜色
+                    // 绘制圆角矩形
+                    ctx.beginPath();
+                    ctx.moveTo(x - width / 2 + cornerRadius, y - height / 2); // 左上角
+                    ctx.lineTo(x + width / 2 - cornerRadius, y - height / 2); // 上边
+                    ctx.arc(x + width / 2 - cornerRadius, y - height / 2 + cornerRadius, cornerRadius, -Math.PI / 2, 0); // 右上角
+                    ctx.lineTo(x + width / 2, y + height / 2 - cornerRadius); // 右边
+                    ctx.arc(x + width / 2 - cornerRadius, y + height / 2 - cornerRadius, cornerRadius, 0, Math.PI / 2); // 右下角
+                    ctx.lineTo(x - width / 2 + cornerRadius, y + height / 2); // 下边
+                    ctx.arc(x - width / 2 + cornerRadius, y + height / 2 - cornerRadius, cornerRadius, Math.PI / 2, Math.PI); // 左下角
+                    ctx.lineTo(x - width / 2, y - height / 2 + cornerRadius); // 左边
+                    ctx.arc(x - width / 2 + cornerRadius, y - height / 2 + cornerRadius, cornerRadius, Math.PI, -Math.PI / 2); // 左上角
+                    ctx.closePath();
+                    ctx.fillStyle = gradient;                // 填充颜色
+                    ctx.fill();
+                },
+                zIndex:2
+            })
+            this.textBgStyleCache[key] = style
+        }
+        return style
+    }
 }
 
 export default RegionLayer;