Browse Source

feat:添加农事名称页面

wangsisi 4 days ago
parent
commit
0680562cba

+ 0 - 115
src/components/farmSteps.vue

@@ -1,115 +0,0 @@
-<template>
-    <div class="steps-container">
-        <div
-            v-for="(step, index) in steps"
-            :key="index"
-            class="step-item"
-            :class="{ completed: index < currentStep, active: index === currentStep }"
-        >
-            <div class="step-circle">
-                <el-icon v-if="index < currentStep"><Select /></el-icon>
-                <span v-else class="step-number">{{ index + 1 }}</span>
-            </div>
-            <div class="step-label">{{ step.label }}</div>
-            <div v-if="index < steps.length - 1" class="step-line" :class="{ completed: index < currentStep }"></div>
-        </div>
-    </div>
-</template>
-
-<script setup>
-import { ref, defineProps } from "vue";
-
-const props = defineProps({
-    currentStep: {
-        type: Number,
-        default: 2,
-    },
-});
-
-const steps = ref([
-    { label: "触发农事" },
-    { label: "农事确认" },
-    { label: "农事执行" },
-    { label: "农事复核" },
-]);
-</script>
-
-<style lang="scss" scoped>
-.steps-container {
-    display: flex;
-    align-items: flex-start;
-    justify-content: space-between;
-    position: relative;
-    .step-item {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        position: relative;
-        flex: 1;
-        z-index: 2;
-        .step-circle {
-            width: 25px;
-            height: 25px;
-            border-radius: 50%;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin-bottom: 8px;
-            transition: all 0.3s ease;
-            .step-number {
-                font-size: 14px;
-            }
-        }
-        .step-label {
-            font-size: 12px;
-            text-align: center;
-            line-height: 1.2;
-            max-width: 60px;
-        }
-        .step-line {
-            position: absolute;
-            top: 13px;
-            left: 74%;
-            width: calc(100% - 38px);
-            height: 2px;
-            background-color: rgba(0, 0, 0, 0.22);
-            z-index: 1;
-        }
-        &.completed {
-            .step-circle {
-                background-color: #1890ff;
-                color: white;
-            }
-            .step-line {
-                background-color: #1890ff;
-            }
-        }
-        &.active {
-            .step-circle {
-                background-color: #1890ff;
-                color: white;
-            }
-        }
-    }
-}
-.step-item:not(.completed):not(.active) .step-circle {
-    background-color: #FFFFFF;
-    color: #999;
-}
-.step-item.completed .step-label,
-.step-item.active .step-label {
-    color: #333;
-    font-weight: 500;
-}
-
-.step-item:not(.completed):not(.active) .step-label {
-    color: rgba(0, 0, 0, 0.5);
-}
-
-.step-line.completed {
-    background-color: #1890ff;
-}
-.step-item:last-child .step-line {
-    display: none;
-}
-</style>

+ 0 - 254
src/components/pageComponents/FarmInfoCard.vue

@@ -1,254 +0,0 @@
-<template>
-    <div class="farm-info-card" :class="{ 'has-footer': showFooter }" @click="handleClick">
-        <div class="item-content">
-            <div class="item-left" :class="{'no-action': data.noAction}">
-            <!-- <div class="item-left" :style="{ width: data.maxWidth ? 'calc(100% - 80px)' : 'auto' }"> -->
-                <img class="map-img" src="@/assets/img/home/farm.png" alt="地图" />
-                <div class="item-info">
-                    <div class="item-header">
-                        <div class="farm-name van-ellipsis" :style="{ maxWidth: data.maxWidth || 'calc(100% - 90px)' }">
-                            {{ data.farmName || data.name }}
-                        </div>
-                        <div class="tags">
-                            <span
-                                class="tag"
-                                :class="data.className || 'tag-variety'"
-                                v-show="data.variety || data.roleName"
-                                >{{ data.variety || data.roleName }}</span
-                            >
-                            <span
-                                class="tag"
-                                :class="data.className || data.area ? 'tag-gray' : 'tag-role'"
-                                v-show="data.area || data.userType"
-                                >{{ data.area || data.userType == 1 ? '普通客户' : '托管客户' }}</span
-                            >
-                        </div>
-                    </div>
-                    <div class="farm-address van-ellipsis">
-                        {{ data.address || '手机号:'+ data.phone || '--' }}
-                    </div>
-                </div>
-            </div>
-            <!-- 右侧按钮插槽 -->
-            <div v-if="hasRightSlot" :class="data.customRight ? data.customRight : 'item-right-btn'" @click.stop>
-                <slot name="right"></slot>
-            </div>
-        </div>
-        <slot name="footerData"></slot>
-        <!-- 底部内容:服务次数或自定义内容 -->
-        <div v-if="showFooter" :class="{ 'item-footer': data.serviceCount != 0 }">
-            <slot name="footer">
-                <template v-if="data.serviceCount != 0">
-                    农事服务过<span class="service-count">{{ data.serviceCount }}</span
-                    >次
-                    <span class="view-detail">查看详情</span>
-                </template>
-            </slot>
-        </div>
-        <!-- 底部提示框:需求信息和预计收益 -->
-        <template v-if="data.broadcasts && data.broadcasts.length > 0">
-            <slot name="bottomTip">
-                <div class="item-footer remind-footer">
-                    <div class="remind-cont" v-html="data.broadcasts[0].content"></div>
-                    <span class="remind-text" @click.stop="handleRemind">提醒他</span>
-                </div>
-            </slot>
-        </template>
-        <upload-execute ref="uploadExecuteRef" :onlyShare="true" />
-    </div>
-</template>
-
-<script setup>
-import { computed, useSlots, ref } from "vue";
-import uploadExecute from "@/views/old_mini/task_condition/components/uploadExecute.vue";
-const props = defineProps({
-    data: {
-        type: Object,
-        default: () => ({}),
-    },
-});
-
-const emit = defineEmits(["click"]);
-const slots = useSlots();
-const showFooter = computed(() => {
-    return props.data.serviceCount !== undefined || !!slots.footer;
-});
-
-const hasRightSlot = computed(() => {
-    return !!slots.right;
-});
-
-const handleClick = () => {
-    emit("click", props.data);
-};
-
-const uploadExecuteRef = ref(null);
-const handleRemind = () => {
-    // const data = {
-    //     ...props.data,
-    //     farmMiniUserId: props.data.receiveUserId,
-    //     farmId: props.data.id,
-    //     type: "remindUser"
-    // }
-    // uploadExecuteRef.value.showPopup(data);
-};
-</script>
-
-<style lang="scss" scoped>
-.farm-info-card {
-    background: #fff;
-    border-radius: 8px;
-    position: relative;
-
-    &.has-footer {
-        padding: 12px 10px;
-        border-radius: 5px;
-    }
-
-    &:not(.has-footer) {
-        padding: 12px 12px;
-        display: flex;
-        flex-direction: column;
-        align-items: stretch;
-    }
-
-    .item-content {
-        width: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-
-        .map-img {
-            width: 40px;
-            height: 40px;
-            border-radius: 6px;
-            object-fit: cover;
-        }
-        .item-left {
-            display: flex;
-            align-items: center;
-            gap: 8px;
-            width: calc(100% - 80px);
-            &.no-action {
-                width: 100%;
-            }
-        }
-        .item-info {
-            width: 100%;
-            .item-header {
-                display: flex;
-                gap: 10px;
-                font-size: 14px;
-                margin-bottom: 4px;
-                .farm-name {
-                    font-weight: 600;
-                    color: #000;
-                    max-width: calc(100% - 90px);
-                    // max-width: 100px;
-                }
-                .tags {
-                    flex: none;
-                    display: flex;
-                    gap: 6px;
-                    align-items: center;
-                    .tag {
-                        padding: 1px 8px;
-                        border-radius: 2px;
-                        font-size: 12px;
-                        &.tag-gray {
-                            background: rgba(243, 243, 243, 0.5);
-                            color: #7d7d7d;
-                        }
-                        &.tag-role {
-                            background: rgba(255, 149, 61, 0.2);
-                            color: #ff953d;
-                        }
-                        &.tag-variety {
-                            background: rgba(232, 243, 255, 1);
-                            color: #2199f8;
-                        }
-                    }
-                }
-            }
-            .farm-address {
-                font-size: 12px;
-                color: #86909c;
-                width: auto;
-                max-width: 190px;
-            }
-        }
-    }
-
-    .item-footer {
-        background: linear-gradient(90deg, rgba(33, 153, 248, 0.2) 0%, transparent 100%);
-        padding: 6px 8px;
-        display: flex;
-        align-items: center;
-        border-radius: 4px;
-        margin-top: 10px;
-        color: #2e2e2e;
-        font-size: 12px;
-        &.remind-footer {
-            justify-content: space-between;
-        }
-        .remind-cont {
-            width: calc(100% - 42px);
-            ::v-deep {
-                p {
-                    margin: 0;
-                }
-            }
-        }
-        .remind-text {
-            color: #2199f8;
-            font-weight: 500;
-            width: 40px;
-        }
-        .service-count {
-            margin: 0 2px;
-        }
-        .view-detail {
-            margin-left: 10px;
-        }
-        .remind-text {
-            font-weight: 400;
-        }
-    }
-
-    .tag-right {
-        align-self: baseline;
-    }
-
-    .item-right-btn {
-        text-align: center;
-        color: #888b8d;
-        font-size: 12px;
-        padding: 5px 12px;
-        border-radius: 20px;
-        border: 1px solid #888b8d;
-    }
-
-    .item-bottom-tip {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        background: linear-gradient(90deg, rgba(254, 164, 94, 0.2) 0%, transparent 100%);
-        span {
-            color: #eb7b20;
-            font-weight: 500;
-        }
-        .income-text {
-            color: #efb789;
-        }
-    }
-}
-
-.farm-info-card + .farm-info-card {
-    margin-top: 12px;
-}
-</style>
-<style>
-.share-sheet {
-    bottom: 50px;
-}
-</style>

+ 0 - 123
src/components/pageComponents/LocationSearch.vue

@@ -1,123 +0,0 @@
-<template>
-    <el-select
-        v-model="locationVal"
-        filterable
-        remote
-        clearable
-        reserve-keyword
-        placeholder="搜索位置"
-        :remote-method="remoteMethod"
-        :loading="loading"
-        @change="handleSearchRes"
-        popper-class="location-search-popper"
-        :class="customClass"
-        @clear="handleClear"
-    >
-        <el-option
-            v-for="(item, index) in locationOptions.list"
-            :key="index"
-            :label="item.title"
-            :value="{ value: item.point, item }"
-        >
-            <span>{{ item.title }}</span>
-            <span class="sub-title">{{ item.province }}{{ item.city }}{{ item.district }}</span>
-        </el-option>
-    </el-select>
-</template>
-
-<script setup>
-import { ref, reactive } from "vue";
-import { transformFromGCJToWGS } from "@/utils/WSCoordinate.js";
-
-const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
-
-const props = defineProps({
-    userLocation: {
-        type: String,
-        default: "113.61702297075017,23.584863449735067",
-    },
-    customClass: {
-        type: String,
-        default: "",
-    },
-});
-
-const emit = defineEmits(["change"]);
-
-const locationVal = ref(null);
-const locationOptions = reactive({
-    list: [],
-});
-const loading = ref(false);
-
-const remoteMethod = async (keyword) => {
-    if (keyword) {
-        locationOptions.list = [];
-        loading.value = true;
-        const params = {
-            key: MAP_KEY,
-            keyword,
-            location: props.userLocation,
-        };
-        await VE_API.old_mini_map.getCtiyList({ word: keyword }).then(({ data }) => {
-            if (data && data.length) {
-                data.forEach((item) => {
-                    item.point = item.location.lat + "," + item.location.lng;
-                    locationOptions.list.push(item);
-                });
-            }
-        });
-        VE_API.old_mini_map.search(params).then(({ data }) => {
-            loading.value = false;
-            data.forEach((item) => {
-                item.point = item.location.lat + "," + item.location.lng;
-                locationOptions.list.push(item);
-            });
-        });
-    } else {
-        locationOptions.list = [];
-    }
-};
-
-const handleSearchRes = (v) => {
-    if (!v) return;
-    const parts = v.value.split(",");
-    let { latitude, longitude } = transformFromGCJToWGS(parseFloat(parts[0]), parseFloat(parts[1]));
-    const coordinateArray = [longitude, latitude];
-    
-    emit("change", {
-        coordinateArray,
-        point: `POINT (${coordinateArray[0]} ${coordinateArray[1]})`,
-        address: v.item?.title || v.item?.address,
-        pointAddress: v.item?.province + v.item?.city + v.item?.district,
-        city: v.item?.city + v.item?.district || '',
-        item: v.item,
-    });
-};
-
-const handleClear = () => {
-    emit("change", {
-        coordinateArray: null,
-        point: null,
-        address: null,
-    });
-    locationVal.value = null;
-    locationOptions.list = [];
-    loading.value = false;
-};
-</script>
-
-<style lang="scss">
-.location-search-popper {
-    .el-select-dropdown__list {
-        max-width: 96vw;
-        overflow-x: auto;
-    }
-    .sub-title {
-        padding-left: 6px;
-        font-size: 12px;
-        color: #ccc;
-    }
-}
-</style>
-

+ 0 - 292
src/components/pageComponents/PlanList.vue

@@ -1,292 +0,0 @@
-<template>
-    <div class="expert-prescription">
-        <div class="plan-menu">
-            <el-anchor :container="containerRef" direction="vertical" type="default" @click="handleClick">
-                <el-menu :default-active="defaultActive" class="el-menu-vertical-demo">
-                    <el-sub-menu v-for="(menu, index) in menuData" :key="index" :index="String(menu.phenologyId)">
-                        <template #title>
-                            <img class="menu-icon" :src="require(`@/assets/img/gallery/icon-${index}.png`)" />
-                            <span class="menu-text">{{ menu.phenologyName }}</span>
-                        </template>
-                        <el-menu-item
-                            v-for="item in menu.farmWorkList"
-                            :key="item.id"
-                            :index="`${menu.phenologyId}-${item.id}`"
-                        >
-                            <el-anchor-link
-                                :href="'#' + menu.phenologyName + item.name"
-                                :title="item.name"
-                            />
-                        </el-menu-item>
-                    </el-sub-menu>
-                </el-menu>
-            </el-anchor>
-        </div>
-        <div class="expert-content" :style="{ height: curRole == 2 ? `calc(100% - 50px)` : 'calc(100% - 20px)' }" ref="containerRef">
-            <slot :menuData="menuData">
-                <div v-for="(section, index) in menuData" :key="index" class="content-section">
-                    <div
-                        class="section-item"
-                        v-for="(sub, subI) in section.farmWorkList"
-                        :key="index + '-' + subI"
-                    >
-                        <div class="section-id" :id="section.phenologyName + sub.name"></div>
-                        <record-item :record-item-data="sub" @click="handleEdit(sub)">
-                            <template #title>
-                                <div class="box-title">
-                                    <div class="title-l">
-                                        {{ sub.name }}
-                                        <span class="parent-text">{{ getFarmTypeText(sub.type) }}</span>
-                                    </div>
-                                    <div class="title-r" v-if="curRole == 2 && isEdit">
-                                        <el-icon color="#2199F8" size="16"><Edit /></el-icon>
-                                    </div>
-                                    <div class="title-r" v-if="isCheck">
-                                        <radio
-                                                :name="`${section.id}-${sub.id}`"
-                                                v-model="selectedItem"
-                                            />
-                                    </div>
-                                </div>
-                            </template>
-                        </record-item>
-                    </div>
-                </div>
-            </slot>
-        </div>
-    </div>
-</template>
-
-<script setup>
-import { ref, onMounted, watch } from "vue";
-import recordItem from "@/components/recordItem.vue";
-import { useRouter } from "vue-router";
-import { Radio } from "vant";
-
-const router = useRouter();
-
-const props = defineProps({
-    farmId: {
-        type: [Number, String],
-        default: null,
-    },
-    isEdit: {
-        type: Boolean,
-        default: false,
-    },
-    defaultActive: {
-        type: String,
-        default: "1-1",
-    },
-    schemeId : {
-        type: [Number, String],
-        default: null,
-    },
-    containerId: {
-        type: [Number, String],
-        default: null,
-    },
-    isCheck: {
-        type: Boolean,
-        default: false,
-    },
-});
-
-const emit = defineEmits(["selectionChange"]);
-
-// 选中状态
-const selectedItem = ref("");
-
-const curRole = localStorage.getItem("SET_USER_CUR_ROLE")
-const menuData = ref([]);
-const containerRef = ref(null);
-
-function getPlanWorkList() {
-    VE_API.monitor
-        .listByFarmId({ farmId: props.farmId })
-        .then(({ data }) => {
-            menuData.value = data;
-        });
-}
-
-watch(() => props.farmId, (newVal) => {
-    if(newVal){
-        getPlanWorkList();
-    }
-});
-
-
-onMounted(() => {
-    if(props.farmId){
-        getPlanWorkList();
-    }
-});
-
-
-const getFarmTypeText = (type) => {
-    const value = typeof type === "string" ? type.trim() : type;
-    if (value === 0 || value === "0") return "预警农事";
-    if (value === 1 || value === "1") return "标准农事";
-    if (value === 2 || value === "2") return "建议农事";
-    return "";
-};
-
-const handleEdit = (sub) => {
-    if(curRole == 2 && props.isEdit){
-        router.push({
-            path: "/edit_plan",
-            query: { arrangeId: sub.arrangeId }
-        });
-    }
-    if(props.isCheck){
-        selectedItem.value = `${sub.phenologyId}-${sub.id}`;
-        emit("selectionChange", sub);
-    }
-};
-
-watch(() => (props.schemeId || props.containerId), (newVal) => {
-    if(newVal){
-        getListBySchemeId();
-    }
-});
-
-const getListBySchemeId = () => {
-    VE_API.home.listBySchemeId({ schemeId: props.schemeId,containerId: props.containerId }).then(({ data }) => {
-        menuData.value = data;
-    });
-};
-
-const handleClick = (e) => {
-    e.preventDefault();
-};
-</script>
-
-<style scoped lang="scss">
-.expert-prescription {
-    display: flex;
-    width: 100%;
-    height: 100%;
-    .plan-menu {
-        width: 100px;
-        height: 100%;
-        overflow: auto;
-        box-sizing: border-box;
-        background: #fff;
-        .menu-icon {
-            width: 13px;
-        }
-        .menu-text {
-            padding: 0 4px;
-        }
-        ::v-deep {
-            .el-anchor {
-                height: 100%;
-                background: none;
-            }
-            .el-anchor__marker {
-                display: none;
-            }
-            .el-menu {
-                background: none;
-                border: none;
-                .el-sub-menu__title {
-                    background: none;
-                    padding: 0 2px;
-                    justify-content: center;
-                }
-                .el-sub-menu__title {
-                    height: 32px;
-                }
-                .el-sub-menu .el-sub-menu__icon-arrow {
-                    position: static;
-                    padding-top: 6px;
-                }
-                .el-sub-menu {
-                    margin-bottom: 16px;
-                    &.is-opened {
-                        .el-sub-menu__icon-arrow {
-                            padding-bottom: 6px;
-                            padding-top: 0;
-                        }
-                    }
-                    .el-menu-item {
-                        height: 32px;
-                        line-height: 32px;
-                        margin: 4px 8px;
-                        padding: 0 2px;
-                        justify-content: center;
-                        background: none;
-                    }
-                    .el-menu-item.is-active {
-                        background: none;
-                        color: #fff;
-                    }
-                    .el-anchor__item {
-                        width: 100%;
-                        text-align: center;
-                    }
-                    .el-anchor__link {
-                        color: #666666;
-                    }
-                    .el-anchor__link.is-active {
-                        background: rgba(33, 153, 248, 0.1);
-                        border-radius: 20px;
-                        color: #2199f8;
-                        border: 1px solid #2199f8;
-                    }
-                }
-            }
-            .el-anchor__list {
-                padding-left: 0;
-            }
-        }
-    }
-    .expert-content {
-        width: calc(100% - 100px);
-        height: calc(100% - 50px);
-        overflow: auto;
-        box-sizing: border-box;
-        .content-section {
-            position: relative;
-            margin: 0 10px;
-            .section-item {
-                position: relative;
-                border-radius: 14px;
-            }
-            .section-item + .section-item{
-                margin-top: 10px;
-            }
-            .section-id {
-                position: absolute;
-                top: 0;
-                width: 100%;
-                height: 1px;
-            }
-        }
-        .content-section + .content-section{
-            margin-top: 10px;
-        }
-        .box-title {
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-            padding-bottom: 8px;
-            border-bottom: 1px solid #f5f5f5;
-            margin-bottom: 8px;
-            .title-l {
-                font-size: 16px;
-                font-weight: 600;
-                color: #000;
-                .parent-text {
-                    margin-left: 5px;
-                    font-size: 12px;
-                    font-weight: normal;
-                    padding: 4px 6px;
-                    border-radius: 14px;
-                    background: rgba(119, 119, 119, 0.1);
-                }
-            }
-        }
-    }
-}
-</style>

+ 0 - 979
src/components/popup/priceSheetPopup.vue

@@ -1,979 +0,0 @@
-<template>
-    <popup class="price-sheet-popup" :overlay-style="{'z-index': 9999}" v-model:show="showPopup" teleport="body">
-        <div class="price-sheet-content">
-            <div class="price-sheet-content-inner" ref="contentEl">
-                <!-- 顶部标题区域 -->
-                <div class="header-section">
-                    <div class="header-left">
-                        <div class="main-title">服务报价单</div>
-                    </div>
-                    <div class="header-right">
-                        <div class="qr-icon">
-                            <img src="@/assets/img/home/qrcode.png" alt="" />
-                        </div>
-                        <div class="qr-text">扫码查看详情</div>
-                    </div>
-                </div>
-                <div class="sheet-content" v-loading="loading">
-                    <!-- 报价详情区域 -->
-                    <div class="quotation-info">
-                        <div class="info-item">
-                            <span class="info-label">报价组织</span>
-                            <span class="info-value">{{ priceData.agriculturalName || '--' }}</span>
-                        </div>
-                        <div class="info-item">
-                            <span class="info-label">报价农事</span>
-                            <span class="info-value">{{ priceData?.name || '--' }}</span>
-                        </div>
-                        <div class="info-item">
-                            <span class="info-label">执行时间</span>
-                            <span class="info-value">{{ priceData?.executeDate || quotationData?.executeDate || '--' }}</span>
-                        </div>
-                        <div class="info-item catalog-label">
-                            <span class="info-label">报价目录</span>
-
-                            <div class="edit-btn-box">
-                                <div class="edit-btn" @click="handleEdit">编辑报价</div>
-                            </div>
-                        </div>
-                        <div class="total-bar">
-                            <span class="total-label">报价合计:</span>
-                            <span class="total-value">{{ totalCost ? formatArea(totalCost) : "--" }}</span>
-                            <span class="total-unit">元</span>
-                        </div>
-                    </div>
-    
-                    <!-- 药肥费用区域 -->
-                    <div class="fertilizer-cost-section">
-                        <div class="section-header" v-if="priceData?.prescription?.pesticideFertilizerList?.length">
-                            <div class="section-title">药肥费用</div>
-                            <div class="section-total">{{ pesticideCostTotal ? formatArea(pesticideCostTotal) : "--" }}<span class="unit-text">元</span></div>
-                        </div>
-                        <price-table :prescription-data="priceData?.prescription" :area="priceData?.farm?.mianji" />
-                        <!-- <div class="cost-table">
-                            <div class="table-header">
-                                <div class="col-1">类型</div>
-                                <div class="col-2">名称</div>
-                                <div class="col-3">品牌</div>
-                                <div class="col-4">单价</div>
-                                <div class="col-5">用量</div>
-                                <div class="col-6">总价</div>
-                            </div>
-                            <div 
-                                class="table-row"
-                                v-for="(item, index) in priceData?.prescription?.pesticideFertilizerList || []"
-                                :key="index"
-                            >
-                                <div class="col-1">{{ item.typeName || '--' }}</div>
-                                <div class="col-2">{{ item.name || item.pesticideFertilizerName || '--' }}</div>
-                                <div class="col-3">{{ item.brand || '--' }}</div>
-                                <div class="col-4">{{ item.price || '--' }}</div>
-                                <div class="col-5">{{ item.dosage ? item.dosage + item.unit : '--' }}</div>
-                                <div class="col-6">¥{{ getTotal(item) }}</div>
-                            </div>
-                        </div> -->
-                    </div>
-    
-                    <!-- 服务费用区域 -->
-                    <div class="service-cost-section">
-                        <div class="section-header">
-                            <div class="section-title">服务费用</div>
-                            <div class="section-total">{{ priceData?.serviceMuPrice ? serviceCostTotal : '--' }}<span class="unit-text">元</span></div>
-                        </div>
-                        <div class="service-details">
-                            <div class="detail-item">
-                                <div class="detail-value">{{ priceData?.executionMethodName || '人工' }}</div>
-                                <div class="detail-label">执行方式</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="detail-value">{{ (priceData?.serviceMuPrice ? priceData?.serviceMuPrice + '元/亩' : '--') }}</div>
-                                <div class="detail-label">亩单价</div>
-                            </div>
-                            <div class="detail-item">
-                                <div class="detail-value">{{ priceData?.farm?.mianji ? (formatArea(priceData?.farm?.mianji) + '亩') : '--' }}</div>
-                                <div class="detail-label">亩数</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <!-- 底部操作按钮 -->
-            <div class="bottom-actions" @click.stop="showPopup = false">
-                <div class="action-buttons">
-                    <!-- <div class="action-btn blue-btn" @click.stop="handleShare">
-                        <div class="icon-circle">
-                            <img src="@/assets/img/home/bird.png" alt="" />
-                        </div>
-                        <span class="btn-label">飞鸟用户</span>
-                    </div> -->
-                    <div class="action-btn green-btn" @click.stop="handleWechat">
-                        <div class="icon-circle">
-                            <img src="@/assets/img/home/wechat.png" alt="" />
-                        </div>
-                        <span class="btn-label">微信</span>
-                    </div>
-                    <div class="action-btn orange-btn" @click.stop="handleSaveImage">
-                        <div class="icon-circle">
-                            <el-icon :size="24"><Download /></el-icon>
-                        </div>
-                        <span class="btn-label">保存图片</span>
-                    </div>
-                </div>
-                <div class="cancel-btn" @click="handleCancel">取消</div>
-            </div>
-        </div>
-    </popup>
-
-    <!-- 图片预览弹窗 -->
-    <popup class="sheet-cavans-popup" v-model:show="showImagePopup">
-        <div class="cavans-content">
-            <img class="current-img" :src="pageImg" alt="" />
-        </div>
-        <!-- 底部操作按钮 -->
-        <div class="bottom-actions" @click.stop="showImagePopup = false">
-            <div class="action-buttons">
-                <div class="action-btn text-btn">
-                    &lt;&lt;长按图片保存&gt;&gt;
-                </div>
-            </div>
-            <div class="cancel-btn" @click="handleCancelImage">取消</div>
-        </div>
-    </popup>
-</template>
-
-<script setup>
-import { Popup } from "vant";
-import { ref, computed, onActivated, watch, nextTick } from "vue";
-import { useRouter, useRoute } from "vue-router";
-import { ElMessage } from "element-plus";
-import wx from "weixin-js-sdk";
-import html2canvas from "html2canvas";
-import { formatArea } from "@/common/commonFun";
-import PriceTable from "@/views/old_mini/agri_work/components/priceTable.vue";
-
-const router = useRouter();
-const route = useRoute();
-const showPopup = ref(false);
-const showImagePopup = ref(false);
-const contentEl = ref(null);
-const pageImg = ref(null);
-
-// 报价数据
-const quotationData = ref({});
-const priceData = ref({});
-const queryData = ref({});
-onActivated(() => {
-    if (ids.value?.id) {
-        getDetail();
-    }
-    queryData.value = route.query?.miniJson ? JSON.parse(route.query?.miniJson) : {};
-})
-
-const getTotal = (item) => {
-    const price = Number(item?.price ?? 0);
-    const dosage = Number(item?.dosage ?? 0);
-    const area = Number(priceData.value?.farm?.mianji ?? 0);
-    if (!price || !dosage || !area) return '--';
-    return (price * dosage * area).toFixed(2);
-}
-
-
-// 药肥费用总计:∑(单价 * 单亩用量 * 亩数)
-const pesticideCostTotal = computed(() => {
-    const list = priceData.value?.prescription?.pesticideFertilizerList || [];
-    const area = Number(priceData.value?.farm?.mianji || 0);
-    if (!list.length || !area) return 0;
-
-    const sum = list.reduce((acc, item) => {
-        const price = Number(item?.price || 0);
-        const dosage = Number(item?.dosage || 0);
-        if (!price || !dosage) return acc;
-        return acc + price * dosage * area;
-    }, 0);
-
-    return Number(sum.toFixed(2));
-});
-
-// 报价合计 = 药肥费用 + 服务费用
-const totalCost = computed(() => {
-    const pesticide = Number(pesticideCostTotal.value || 0);
-    const service = Number(serviceCostTotal.value || 0);
-    if (!pesticide && !service) return '--';
-    return Number((pesticide + service).toFixed(2));
-});
-
-
-const ids = ref({});
-const handleShowPopup = ({id, farmId}) => {
-    if (id) {
-        loading.value = true;
-        ids.value = {id, farmId};
-        getDetail();
-    }
-    showPopup.value = true;
-};
-
-const loading = ref(false);
-function fetchPriceData(id) {
-    
-    // VE_API.z_farm_work_record_cost.getByRecordId({ farmWorkRecordId: quotationData.value.id }).then(({ data }) => {
-    //     priceData.value = data;
-    // }).catch(() => {
-    //     // 获取价格数据失败
-    // }).finally(() => {
-    //     loading.value = false;
-    // });
-}
-
-const userInfoStr = localStorage.getItem("localUserInfo");
-const userInfo = userInfoStr ? JSON.parse(userInfoStr) : {};
-
-const getDetail = async () => {
-    const { id, farmId } = ids.value;
-    const { data, code } = await VE_API.farm.getFarmWorkLib({ id, farmId, agriculturalId: userInfo?.agriculturalId });
-    if(code === 0) {
-        priceData.value = data;
-        const pesticideFertilizerCodes = data?.prescription?.pesticideFertilizerList.map(item => item.code);
-        getPriceList(data.schemeId, pesticideFertilizerCodes);
-        loading.value = false;
-    }
-}
-
-const getPriceList = async (schemeId, pesticideFertilizerCodes) => {
-    const { data } = await VE_API.farm.getPriceList({ schemeId, pesticideFertilizerCodes });
-    if (!data || !Array.isArray(data)) return;
-
-    priceData.value.prescription.pesticideFertilizerList.forEach((item) => {
-        const priceInfo = data.find((p) => p.pesticideFertilizerCode === item.code);
-        if (!priceInfo) return;
-        item.price = priceInfo.price ?? item.price;
-        item.brand = priceInfo.brand ?? item.brand;
-    });
-};
-
-// 检查 itemsList 是否都有价格和品牌
-function checkItemsListHasPrice() {
-    if (!priceData.value?.prescription?.pesticideFertilizerList || !Array.isArray(priceData.value.prescription.pesticideFertilizerList) || priceData.value.prescription.pesticideFertilizerList.length === 0) {
-        return false;
-    }
-    // 检查所有项是否都有 price 且 price 不为 0,以及 brand 有值
-    return priceData.value.prescription.pesticideFertilizerList.every(item => {
-        const hasPrice = item.price != null && item.price !== '' && item.price !== 0;
-        const hasBrand = item.brand && item.brand.trim() !== '';
-        return hasPrice && hasBrand;
-    });
-}
-
-async function checkOrder() {
-    // 如果没有 id,需要检查 itemsList 是否都有价格
-    if (!checkItemsListHasPrice()) {
-        return false; // 没有价格,返回 false
-    }
-    
-    // 有 id 且都有价格,返回 true
-    return true;
-}
-
-const handleShare = async () => {
-    // 检查订单状态,如果返回 false 说明数据不完整
-    const canProceed = await checkOrder();
-    if (!canProceed) {
-        ElMessage.warning('请补全报价数据');
-        setTimeout(() => {
-            handleEdit();
-        }, 1000);
-        return;
-    }
-    const userId = priceData.value.farmMiniUserId;
-    const parmasPage = {
-        farmWorkOrderId:priceData.value.orderId,
-        farmMiniUserId:userId,
-        farmMiniUserName:priceData.value.farmMiniUserName,
-        farmId:priceData.value.farmId,
-        farmWorkName:priceData.value.farmWorkName,
-        id:priceData.value.id,
-        type:'quotation'
-    }
-    if(userId){
-        router.push(`/chat_frame?userId=${userId}&farmId=${parmasPage.farmId}&pageParams=${JSON.stringify(parmasPage)}`);
-    }else{
-        ElMessage.warning('尚未绑定用户,暂时无法分享')
-    }   
-};
-
-const handleWechat = async () => {
-    // 检查订单状态,如果返回 false 说明数据不完整
-    const canProceed = await checkItemsListHasPrice();
-    if (!canProceed) {
-        ElMessage.warning('请补全报价数据');
-        return;
-    }
-    // router.push({
-    //     path: "/completed_work",
-    //     query: { id: quotationData.value.id, farmWorkOrderId: quotationData.value.orderId, isAssign: true },
-    // });
-    // const query = { askInfo: {title: "服务报价单", content: "是否分享该服务报价单给好友"}, shareText: "向您发送了一张 服务报价单", id: quotationData.value.id, farmWorkOrderId: quotationData.value.orderId, isAssign: true }
-
-    // wx.miniProgram.navigateTo({
-    //     url: `/pages/subPages/share_page/index?pageParams=${JSON.stringify(query)}&type=priceSheet`,
-    // });
-
-    const query = {
-        askInfo: { title: "服务报价单", content: "是否分享该服务报价单给好友" },
-        shareText: "向您发送了一张 服务报价单",
-        targetUrl: `detail_work`,
-        paramsPage: JSON.stringify({ id: ids.value.id, arrangeId: queryData.value.arrangeId, farmId: ids.value.farmId, goBack: true }),
-        imageUrl: 'https://birdseye-img.sysuimars.com/temp/price.png',
-    };
-    wx.miniProgram.navigateTo({
-        url: `/pages/subPages/share_page/index?pageParams=${JSON.stringify(query)}&type=sharePage`,
-    });
-};
-
-// 服务费用总计(数值):亩单价 * 亩数
-const serviceCostTotal = computed(() => {
-    const price = Number(priceData.value?.serviceMuPrice || 0);
-    const area = Number(priceData.value?.farm?.mianji || 0);
-    if (!price || !area) return 0;
-    return Number((price * area).toFixed(2));
-});
-
-const handleSaveImage = async () => {
-    setTimeout(async () => {
-        try {
-            if (!contentEl.value) return;
-            const element = contentEl.value;
-            const scroller = element.querySelector('.sheet-content');
-            const editBtn = element.querySelector('.edit-btn-box');
-
-            // 记录原样式
-            const prev = {
-                elementOverflow: element.style.overflow,
-                elementMaxHeight: element.style.maxHeight,
-                elementHeight: element.style.height,
-                scrollerOverflow: scroller ? scroller.style.overflow : undefined,
-                scrollerMaxHeight: scroller ? scroller.style.maxHeight : undefined,
-                scrollerHeight: scroller ? scroller.style.height : undefined,
-                editBtnDisplay: editBtn ? editBtn.style.display : undefined,
-            };
-
-            // 隐藏编辑按钮
-            if (editBtn) {
-                editBtn.style.display = 'none';
-            }
-
-            // 展开内容,去除滚动限制,确保截图包含全部内容
-            element.style.overflow = 'visible';
-            element.style.maxHeight = 'none';
-            element.style.height = 'auto';
-            if (scroller) {
-                scroller.style.overflow = 'visible';
-                scroller.style.maxHeight = 'none';
-                scroller.style.height = 'auto';
-            }
-
-            handleCancel()
-
-            // 等待样式应用
-            await nextTick();
-
-            const canvas = await html2canvas(element, {
-                scrollY: -window.scrollY, // 处理滚动条位置
-                allowTaint: true, // 允许跨域图片
-                useCORS: true, // 使用CORS
-                scale: 2, // 提高分辨率(2倍)
-                height: element.scrollHeight, // 设置完整高度
-                width: element.scrollWidth, // 设置完整宽度
-                backgroundColor: '#ffffff',
-            });
-
-            // 转换为图片并显示
-            const image = canvas.toDataURL('image/png');
-            pageImg.value = image;
-            nextTick(() => {
-                showImagePopup.value = true;
-            });
-
-            // 还原样式
-            element.style.overflow = prev.elementOverflow;
-            element.style.maxHeight = prev.elementMaxHeight;
-            element.style.height = prev.elementHeight;
-            if (scroller) {
-                scroller.style.overflow = prev.scrollerOverflow;
-                scroller.style.maxHeight = prev.scrollerMaxHeight;
-                scroller.style.height = prev.scrollerHeight;
-            }
-            if (editBtn) {
-                editBtn.style.display = prev.editBtnDisplay || '';
-            }
-        } catch (e) {
-            // 保存图片失败
-        }
-    }, 100);
-};
-
-// 检查是否有"转入农事"权限
-const hasPlanPermission = computed(() => {
-    try {
-        const userInfoStr = localStorage.getItem("localUserInfo");
-        if (!userInfoStr) return false;
-        const userInfo = JSON.parse(userInfoStr);
-        const permissions = userInfo.agriculturalPermissions || [];
-        return permissions.includes("转入农事");
-        // return userInfo.agriculturalRole !== 3;
-    } catch (error) {
-        console.error("解析用户信息失败:", error);
-        return false;
-    }
-});
-
-const handleEdit = () => {
-    if (!hasPlanPermission.value) {
-        ElMessage.warning("您暂无权限操作");
-        return;
-    }
-    // 编辑报价逻辑
-    // 可以触发编辑事件或打开编辑页面
-    router.push({
-        path: "/modify",
-        query: {
-            isEdit: true,
-            onlyPrice: true,
-            farmId: priceData.value.farm.id,
-            arrangeId: queryData.value.arrangeId,
-            farmWorkId: priceData.value.id,
-        },
-    });
-    // router.push({
-    //     path: "/price_detail",
-    //     query: { data: JSON.stringify(quotationData.value), priceData: JSON.stringify(priceData.value) },
-    // });
-};
-
-// 清空数据
-const clearData = () => {
-    // quotationData.value = {};
-    // priceData.value = {};
-};
-
-// 监听弹窗关闭,清空数据
-// watch(showPopup, (newVal) => {
-//     if (!newVal) {
-//         clearData();
-//     }
-// });
-
-const handleCancel = () => {
-    showPopup.value = false;
-};
-
-const handleCancelImage = () => {
-    showImagePopup.value = false;
-};
-
-defineExpose({
-    handleShowPopup,
-});
-</script>
-
-<style lang="scss" scoped>
-.price-sheet-popup {
-    z-index: 9999 !important;
-    width: 90%;
-    max-height: 90vh;
-    background: none;
-    border-radius: 12px;
-    overflow: hidden;
-    display: flex;
-    flex-direction: column;
-    backdrop-filter: 4px;
-
-    ::v-deep {
-        .van-popup__close-icon {
-            color: #000;
-            font-size: 18px;
-            top: 12px;
-            right: 12px;
-        }
-    }
-}
-
-.price-sheet-content {
-    display: flex;
-    flex-direction: column;
-    max-height: 90vh;
-    // height: 95vh;
-    .price-sheet-content-inner {
-        background: #fff;
-        border-radius: 12px;
-        display: flex;
-        flex-direction: column;
-        height: 100%;
-        overflow: hidden;
-    }
-}
-
-// 顶部标题区域
-.header-section {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding: 16px 10px 12px 16px;
-    // background: linear-gradient(180deg, rgba(33, 153, 248, 0) 8%, rgba(139, 199, 252, 0.519) 94%, rgba(237, 241, 255, 1) 100%);
-    background: linear-gradient(180deg, rgba(33, 153, 248, 0) 2%, rgba(139, 199, 252, 0.519) 50%, #c4e3fd);
-    flex-shrink: 0;
-
-    .header-left {
-        flex: 1;
-
-        .main-title {
-            font-family: "PangMenZhengDao";
-            font-size: 28px;
-            color: #0387EF;
-        }
-    }
-
-    .header-right {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        margin-left: 16px;
-
-        .qr-icon {
-            color: #2199F8;
-            margin-bottom: 4px;
-            img {
-                width: 40px;
-                height: 40px;
-            }
-        }
-
-        .qr-text {
-            font-size: 12px;
-            color: #171717;
-        }
-    }
-}
-
-.sheet-content {
-    padding: 24px 16px 12px 16px;
-    flex: 1;
-    overflow-y: auto;
-    overflow-x: hidden;
-    position: relative;
-}
-
-// 报价详情区域
-.quotation-info {
-    margin-bottom: 12px;
-
-    .info-item {
-        font-size: 16px;
-        color: #000;
-        margin-bottom: 8px;
-
-        .info-label {
-            padding-right: 8px;
-            color: rgba(0, 0, 0, 0.5);
-        }
-
-        .info-value {
-            color: #000;
-        }
-
-        &.catalog-label {
-            font-weight: bold;
-            margin-top: 10px;
-            margin-bottom: 10px;
-            position: relative;
-
-            .info-label {
-                color: #000;
-            }
-        }
-    }
-
-    .total-bar {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background: rgba(33, 153, 248, 0.1);
-        border: 1px solid rgba(33, 153, 248, 0.5);
-        height: 38px;
-        border-radius: 4px;
-
-        .total-label {
-            font-size: 14px;
-            color: #000000;
-        }
-
-        .total-value {
-            font-size: 22px;
-            font-weight: bold;
-            color: #2199F8;
-        }
-
-        .total-unit {
-            font-size: 14px;
-            color: #000;
-            margin-left: 4px;
-        }
-    }
-}
-
-// 药肥费用区域
-.fertilizer-cost-section {
-    margin-bottom: 10px;
-
-    .section-header {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin-bottom: 8px;
-
-        .section-title {
-            font-size: 14px;
-            color: #000;
-        }
-
-        .section-total {
-            font-size: 16px;
-            font-weight: bold;
-            color: #000;
-
-            .unit-text {
-                padding-left: 2px;
-                font-size: 12px;
-                font-weight: normal;
-            }
-        }
-    }
-
-    .cost-table {
-        border: 1px solid rgba(225, 225, 225, 0.5);
-        border-radius: 5px;
-        overflow: hidden;
-
-        .table-header {
-            display: flex;
-            background: rgba(241, 241, 241, 0.4);
-            padding: 8px 6px;
-            font-size: 12px;
-            color: #767676;
-            border-bottom: 1px solid rgba(225, 225, 225, 0.5);
-
-            .col-1 {
-                width: 40px;
-                text-align: center;
-            }
-
-            .col-2 {
-                flex: 1;
-                text-align: center;
-            }
-
-            .col-3 {
-                width: 52px;
-                text-align: center;
-            }
-
-            .col-4 {
-                width: 56px;
-                text-align: center;
-            }
-
-            .col-5 {
-                width: 52px;
-                text-align: center;
-            }
-
-            .col-6 {
-                width: 52px;
-                text-align: center;
-            }
-        }
-
-        .table-row {
-            display: flex;
-            padding: 8px 6px;
-            font-size: 11px;
-            color: rgba(0, 0, 0, 0.6);
-            background: #fff;
-            border-bottom: 1px solid rgba(225, 225, 225, 0.3);
-
-            &:last-child {
-                border-bottom: none;
-            }
-
-            .col-1,
-            .col-2,
-            .col-3,
-            .col-4,
-            .col-5,
-            .col-6 {
-                display: flex;
-                align-items: center;
-                justify-content: center;
-            }
-
-            .col-1 {
-                width: 40px;
-            }
-
-            .col-2 {
-                flex: 1;
-            }
-
-            .col-3 {
-                width: 52px;
-            }
-
-            .col-4 {
-                width: 56px;
-            }
-
-            .col-5 {
-                width: 52px;
-            }
-
-            .col-6 {
-                width: 52px;
-            }
-        }
-    }
-}
-
-// 服务费用区域
-.service-cost-section {
-    position: relative;
-
-    .section-header {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin-bottom: 12px;
-
-        .section-title {
-            font-size: 14px;
-            color: #000;
-        }
-
-        .section-total {
-            font-size: 16px;
-            font-weight: bold;
-            color: #000;
-
-            .unit-text {
-                padding-left: 2px;
-                font-size: 12px;
-                font-weight: normal;
-            }
-        }
-    }
-
-    .service-details {
-        display: flex;
-        align-items: center;
-        border: 1px solid rgba(206, 206, 206, 0.5);
-        padding: 8px 0;
-        border-radius: 4px;
-        margin-bottom: 10px;
-
-        .detail-item {
-            font-size: 14px;
-            flex: 1;
-            text-align: center;
-
-            .detail-label {
-                color: rgba(0, 0, 0, 0.2);
-                margin-top: 6px;
-            }
-
-            .detail-value {
-                color: rgba(0, 0, 0, 0.8);
-            }
-        }
-        .detail-item + .detail-item {
-            position: relative;
-            &::before {
-                content: '';
-                position: absolute;
-                left: 0;
-                top: 50%;
-                transform: translateY(-50%);
-                width: 1px;
-                height: 20px;
-                background: rgba(0, 0, 0, 0.1);
-            }
-        }
-    }
-}
-.edit-btn-box {
-    display: flex;
-    justify-content: end;
-    position: absolute;
-    right: 0;
-    top: -8px;
-    z-index: 10;
-}
-.edit-btn {
-    background: rgba(33, 153, 248, 0.1);
-    color: #2199F8;
-    padding: 6px 16px;
-    border-radius: 20px;
-    font-size: 14px;
-    width: fit-content;
-    cursor: pointer;
-    font-weight: 500;
-}
-
-// 底部操作按钮
-.bottom-actions {
-    flex-shrink: 0;
-
-    .action-buttons {
-        padding: 16px;
-        display: flex;
-        justify-content: space-around;
-
-        .action-btn {
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            cursor: pointer;
-
-            .icon-circle {
-                width: 48px;
-                height: 48px;
-                border-radius: 50%;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                color: #fff;
-                margin-bottom: 4px;
-
-                .el-icon {
-                    color: #fff;
-                }
-                img {
-                    width: 50px;
-                }
-            }
-
-            &.blue-btn .icon-circle {
-                background: #2199F8;
-            }
-
-            &.green-btn .icon-circle {
-                background: #07C160;
-            }
-
-            &.orange-btn .icon-circle {
-                background: #FF790B;
-            }
-
-            .btn-label {
-                font-size: 12px;
-                color: #fff;
-            }
-        }
-    }
-
-    .cancel-btn {
-        text-align: center;
-        font-size: 18px;
-        color: #fff;
-        cursor: pointer;
-    }
-}
-
-.sheet-cavans-popup {
-    width: calc(100% - 20px);
-    max-width: 100%;
-    max-height: 92vh;
-    background: none;
-    border-radius: 12px;
-    overflow: auto;
-    display: flex;
-    flex-direction: column;
-    backdrop-filter: 4px;
-    .cavans-content {
-        text-align: center;
-        padding: 0;
-        height: fit-content;
-        overflow: auto;
-        .current-img {
-            max-width: 100%;
-            width: auto;
-            height: auto;
-            display: block;
-            margin: 0 auto;
-        }
-    }
-
-    // 底部操作按钮
-    .bottom-actions {
-        flex-shrink: 0;
-
-        .action-buttons {
-            padding: 12px 0 4px 0;
-            display: flex;
-            justify-content: space-around;
-
-            .action-btn {
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                cursor: pointer;
-                &.text-btn {
-                    font-size: 12px;
-                    color: rgba(255, 255, 255, 0.7);
-                }
-
-                .icon-circle {
-                    width: 48px;
-                    height: 48px;
-                    border-radius: 50%;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    color: #fff;
-                    margin-bottom: 4px;
-
-                    .el-icon {
-                        color: #fff;
-                    }
-                    img {
-                        width: 50px;
-                    }
-                }
-
-                &.blue-btn .icon-circle {
-                    background: #2199f8;
-                }
-
-                &.green-btn .icon-circle {
-                    background: #07c160;
-                }
-
-                &.orange-btn .icon-circle {
-                    background: #ff790b;
-                }
-
-                .btn-label {
-                    font-size: 12px;
-                    color: #fff;
-                }
-            }
-        }
-
-        .cancel-btn {
-            text-align: center;
-            font-size: 18px;
-            color: #fff;
-            cursor: pointer;
-        }
-    }
-}
-</style>

+ 0 - 186
src/components/reportPopup.vue

@@ -1,186 +0,0 @@
-<template>
-    <Popup v-model:show="show" class="report-popup">
-        <div class="popup-content-box">
-            <div class="report-bg">
-                <img class="box-bg" src="@/assets/img/home/box-bg.png" alt="">
-            </div>
-            <div class="report-content">
-                <div class="report-garden">
-                    <img class="garden-icon" src="https://birdseye-img.sysuimars.com/birdseye-look-mini/Group%201321316260.png" alt="">
-                    荔枝博览园
-                </div>
-                <div class="report-time">2025.02.15农场报告</div>
-                <div class="report-address">广东省广州市从化区</div>
-                <div class="report-img">
-                    <img class="report-img-dom" src="https://birdseye-img-ali-cdn.sysuimars.com/16926861-1e20-4cbd-8bf2-90208db5a2d0/806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_202509010800_001_806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_20250901080536_0045_V_code-ws0fsmge97gh.jpeg" alt="">
-                </div>
-                <div class="report-line"></div>
-                <div class="report-desc">
-                    当前位于广州市从化区荔枝博览园,共 <span class="main-text">12000棵</span>树,有 <span class="main-text">7659棵</span> 树触发了农事。
-                </div>
-                <div class="report-info">
-                    <div class="info-item">
-                        <span class="item-dotted"></span>
-                        物候进程
-                        <span class="item-text">花期短暂,果期集中,成熟迅速</span>
-                    </div>
-                    <div class="info-item">
-                        <span class="item-dotted"></span>
-                        生长异常
-                        <span class="item-text">花而不实,落果严重,品质下降</span>
-                    </div>
-                    <div class="info-item">
-                        <span class="item-dotted"></span>
-                        病虫异常
-                        <span class="item-text">虫蛀果裂,病斑密布,落叶早衰</span>
-                    </div>
-                </div>
-            </div>
-        </div>
-        
-        <div class="bottom-btn">
-            <div class="btn-item secondary-btn" @click="toPage">分享给</div>
-            <div class="btn-item primary-btn" @click="triggerClick">保存图片</div>
-        </div>
-    </Popup>
-</template>
-
-<script setup>
-import { Popup } from "vant";
-import { ref } from "vue";
-
-const show = ref(false);
-
-const handleShow = () => {
-    show.value = true;
-};
-
-const handleClose = () => {
-    show.value = false;
-};
-
-defineExpose({handleClose,handleShow});
-</script>
-
-<style lang="scss" scoped>
-.report-popup {
-    width: 343px;
-    border-radius: 12px;
-    background: transparent;
-    .popup-content-box {
-        position: relative;
-        background: #FFFFFF;
-        border-radius: 12px;
-        .report-bg {
-            .box-bg {
-                position: absolute;
-                top: 0;
-                left: 0;
-                z-index: 0;
-                width: 100%;
-                height: 203px;
-            }
-        }
-        .report-content {
-            position: relative;
-            z-index: 2;
-            padding: 12px 12px 20px 12px;
-            .report-garden {
-                background: rgba(0, 0, 0, 0.6);
-                color: #fff;
-                height: 28px;
-                display: flex;
-                align-items: center;
-                width: fit-content;
-                padding: 0 8px 0 2px;
-                border-radius: 20px;
-                font-size: 14px;
-                .garden-icon {
-                    width: 24px;
-                    height: 24px;
-                    border-radius: 50%;
-                    box-sizing: border-box;
-                    // border: 1px solid #fff;
-                    margin-right: 6px;
-                }
-            }
-            .report-time {
-                padding-top: 42px;
-                font-size: 22px;
-                color: #000000;
-                font-weight: bold;
-            }
-            .report-address {
-                font-size: 16px;
-                color: rgba(0, 0, 0, 0.5);
-            }
-            .report-img {
-                padding: 16px 0 12px 0;
-                .report-img-dom {
-                    width: 100%;
-                    height: 152px;
-                    border-radius: 12px;
-                    object-fit: cover;
-                }
-            }
-            .report-line {
-                border-bottom: 1px dotted rgba(0, 0, 0, 0.1);
-            }
-            .report-desc {
-                padding: 17px 10px 8px 10px;
-                font-size: 14px;
-                color: #333333;
-                .main-text {
-                    color: #2199F8;
-                }
-            }
-            .report-info {
-                padding: 5px 8px;
-                font-size: 14px;
-                .info-item {
-                    display: flex;
-                    align-items: center;
-                    color: #999999;
-                    padding-bottom: 2px;
-                    .item-dotted {
-                        width: 4px;
-                        height: 4px;
-                        border-radius: 50%;
-                        background: #BBBBBB;
-                        margin-right: 8px;
-                    }
-                    .item-text {
-                        padding-left: 12px;
-                        color: #000000;
-                    }
-                }
-            }
-        }
-    }
-    .bottom-btn {
-        width: 100%;
-        text-align: center;
-        margin-top: 20px;
-        display: flex;
-        .btn-item {
-            flex: 1;
-            text-align: center;
-            height: 38px;
-            line-height: 38px;
-            border-radius: 30px;
-            font-size: 14px;
-            &.secondary-btn {
-                background: #FFFFFF;
-                color: #000000;
-            }
-            &.primary-btn {
-                background: linear-gradient(180deg, #76C3FF, #2199F8);
-                color: #FFFFFF;
-            }
-        }
-        .btn-item + .btn-item {
-            margin-left: 12px;
-        }
-    }
-}
-</style>

+ 7 - 15
src/router/globalRoutes.js

@@ -75,13 +75,6 @@ export default [
         name: "FarmManageDetail",
         component: () => import("@/views/old_mini/home/index.vue"),
     },
-    // 专家-我的主页
-    {
-        path: "/expert_homepage",
-        name: "ExpertHomepage",
-        meta: { keepAlive: true },
-        component: () => import("@/views/old_mini/expert_detail/index.vue"),
-    },
     // 气象预警详情/农事预警详情
     {
         path: "/warning_detail",
@@ -115,13 +108,6 @@ export default [
         meta: { keepAlive: true },
         component: () => import("@/views/old_mini/monitor/subPages/agriculturalDetail.vue"),
     },
-    // 相册识别
-    {
-        path: "/album_recognize",
-        name: "AlbumRecognize",
-        meta: { keepAlive: true },
-        component: () => import("@/views/old_mini/album_recognize/index.vue"),
-    },
     // 处方页面
     {
         path: "/prescription",
@@ -238,7 +224,6 @@ export default [
         meta: { keepAlive: true },
         component: () => import("@/views/old_mini/create_farm/selectCrop.vue"),
     },
-
     // 农事档案
     {
         path: "/agri_file",
@@ -246,4 +231,11 @@ export default [
         meta: { showTabbar: true, keepAlive: true },
         component: () => import("@/views/old_mini/agri_file/index.vue"),
     },
+    // 农事记录详情
+    {
+        path: "/record_details",
+        name: "RecordDetails",
+        meta: { keepAlive: true },
+        component: () => import("@/views/old_mini/recordDetails/index.vue"),
+    },
 ];

+ 12 - 2
src/views/old_mini/agri_record/index.vue

@@ -15,7 +15,7 @@
         <!-- 作物档案 -->
         <div class="archives-time-line" v-show="activeGardenTab === 'current'">
             <div class="trend-monitor-list">
-                <div class="trend-monitor-card" v-for="(item, index) in trendMonitorMockList" :key="index">
+                <div class="trend-monitor-card" @click="handleTrendMonitorCardClick(item)" v-for="(item, index) in trendMonitorMockList" :key="index">
                     <div class="card-header">
                         <div class="header-left">
                             <span class="title">{{ item.title }}</span>
@@ -47,10 +47,12 @@ import customHeader from "@/components/customHeader.vue";
 import { ref, computed, onActivated, onMounted } from "vue";
 import { useStore } from "vuex";
 import weatherInfo from "@/components/weatherInfo.vue";
-import { useRoute } from "vue-router";
+import { useRoute, useRouter } from "vue-router";
 import ArchivesFarmTimeLine from "@/components/pageComponents/ArchivesFarmTimeLine.vue";
 import gardenList from "@/components/gardenList.vue";
 
+const router = useRouter();
+
 // 品种选择(作物档案内)- 根据主体ID动态获取分区列表
 const varietyTabs = ref([]);
 const activeVariety = ref(0);
@@ -184,6 +186,14 @@ const changeGarden = ({ id }) => {
 const handleCardClick = () => {
     sessionStorage.setItem('activeVariety', activeVariety.value);
 }
+
+const handleTrendMonitorCardClick = (item) => {
+    router.push({
+        path: "/record_details",
+        query: { recordId: item.id },
+    });
+    console.log(item);
+}
 </script>
 
 <style scoped lang="scss">

+ 0 - 464
src/views/old_mini/album_recognize/index-fn.vue

@@ -1,464 +0,0 @@
-<template>
-    <div class="diseases-dictionary-detail">
-        <div class="page-title" @click="goBack">
-            <el-icon class="title-icon" color="rgba(0, 0, 0, 0.8)" size="16"><ArrowLeftBold /></el-icon>
-            识别结果
-        </div>
-        <div class="detail-content">
-            <div class="detail-img">
-                <Swipe class="card-swipe-wrapper" :show-indicators="imgKey && imgKey.length > 1" :loop="false">
-                    <SwipeItem v-for="(img, index) in imgKey" :key="index">
-                        <div class="card-item">
-                            <div class="ing-wrap" v-if="isRecognize">
-                                <div>
-                                    <el-icon size="20" class="is-loading">
-                                        <Loading />
-                                    </el-icon>
-                                </div>
-                                正在识别,请稍后...
-                            </div>
-                            <img class="card-bg" :src="displayUrls[index]" />
-                            <div class="card-content" v-if="!isRecognize && resultsByIndex[index]?.status === 'ok'">
-                                <div class="title-ques">
-                                    <div class="ques-text">病虫名称:{{ resultsByIndex[index]?.data?.name }}</div>
-                                </div>
-                                <div class="dialog-famous">管理方法:</div>
-                                <div class="dialog-answer">
-                                    {{ resultsByIndex[index]?.data?.cure }}
-                                </div>
-                                <div v-if="resultsByIndex[index]?.data?.info" class="advice-wrap">
-                                    <div class="item-tag">基本信息</div>
-                                    <div v-html="resultsByIndex[index]?.data?.info"></div>
-                                </div>
-                                <div class="famous-info" @click="toDetail(index)">
-                                    <img src="@/assets/img/home/link-icon.png" />
-                                    <span>点击查看农事详情</span>
-                                </div>
-                            </div>
-                            <div class="card-content no-data" v-if="!isRecognize && resultsByIndex[index]?.status === 'nodata'">
-                                <img src="@/assets/img/home/good-fill.png" />
-                                长势良好,并未发现病虫害
-                            </div>
-                        </div>
-                    </SwipeItem>
-                </Swipe>
-            </div>
-            <div class="btn-wrap" v-if="!isRecognize">
-                <div class="btn primary" @click="goBack">咨询专家</div>
-            </div>
-        </div>
-    </div>
-    <!-- 农事信息弹窗 -->
-    <detail-dialog ref="detailDialogRef" :show-success-only="true"></detail-dialog>
-    <!-- 上传弹窗组件 -->
-    <active-upload-popup></active-upload-popup>
-</template>
-
-<script setup>
-import { onMounted, ref } from "vue";
-import { Swipe, SwipeItem } from "vant";
-import { useRouter, useRoute } from "vue-router";
-import { base_img_url2 } from "@/api/config.js";
-import { ElMessage } from "element-plus";
-import MqttClient from "@/mqtt/MqttClient";
-import detailDialog from "@/components/detailDialog.vue";
-import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
-
-let resize = "?x-oss-process=image/resize,w_300";
-const route = useRoute();
-const json = JSON.parse(route.query.json || "{}");
-// const json = JSON.parse(
-//     `{"imgKey":["birdseye-look-mini/766/1761968109259.png","birdseye-look-mini/766/1761968110225.png"],"farmId":766,"id":"65","imageIds":["772470289337421824","772470289337421825"],"token":"bcc0e12d-bff6-4f1f-8edc-2ab80b19af41"}`)
-const imgKey = json.imgKey;
-const farmId = json.farmId;
-const imageIds = json.imageIds || [];
-
-const isRecognize = ref(true);
-const noData = ref(false);
-const resultsByIndex = ref({});
- 
-// 存储每张图片的 farmWorkLibId,用于后续接口请求
-const farmWorkLibIdsByIndex = ref({});
-
-// 预置显示地址:默认使用传入的 cloudFilename
-const displayUrls = ref(imgKey.map((p) => base_img_url2 + p + resize));
-const detailDialogRef = ref(null);
-onMounted(() => {
-    const mqttClient = new MqttClient(["farm/pest_recognition/task/" + farmId], mqttListener);
-    mqttClient.connect();
-});
-
-const mqttListener = (topic, message) => {
-    let resData = JSON.parse(message);
-    if (json.id == resData.taskId) {
-        if (resData.status === 1) {
-            const resultMap = resData.result || {};
-            // 初始化每张图片的结果状态
-            const fetchPromises = [];
-            imageIds.forEach((imgId, index) => {
-                const resultData = resultMap[imgId];
-                // 新数据结构:可能是 null 或数组,数组中的对象包含 farmWorkLibId 和 pestDiseaseId
-                if (Array.isArray(resultData) && resultData.length > 0) {
-                    // 提取 pestDiseaseId 和 farmWorkLibId
-                    const pestDiseaseIds = [];
-                    const farmWorkLibIdList = [];
-                    
-                    resultData.forEach((item) => {
-                        if (item && item.pestDiseaseId) {
-                            pestDiseaseIds.push(item.pestDiseaseId);
-                        }
-                        if (item && item.farmWorkLibId) {
-                            farmWorkLibIdList.push(item.farmWorkLibId);
-                        }
-                    });
-                    
-                    // 按索引保存 farmWorkLibId 数组
-                    if (farmWorkLibIdList.length > 0) {
-                        farmWorkLibIdsByIndex.value[index] = farmWorkLibIdList;
-                    }
-                    
-                    // 使用 pestDiseaseId 调用病虫详情接口
-                    if (pestDiseaseIds.length > 0) {
-                        const p = VE_API.home.fetchDiseaseDetail(pestDiseaseIds).then(({ data, code: respCode }) => {
-                            if (respCode === 0) {
-                                const detail = Array.isArray(data) ? data[0] : data;
-                                resultsByIndex.value = {
-                                    ...resultsByIndex.value,
-                                    [index]: { status: 'ok', data: detail }
-                                };
-                            } else {
-                                resultsByIndex.value = {
-                                    ...resultsByIndex.value,
-                                    [index]: { status: 'nodata' }
-                                };
-                            }
-                        }).catch(() => {
-                            resultsByIndex.value = {
-                                ...resultsByIndex.value,
-                                [index]: { status: 'nodata' }
-                            };
-                        });
-                        fetchPromises.push(p);
-                    } else {
-                        // 没有 pestDiseaseId,但有 farmWorkLibId,可能只有农事信息
-                        resultsByIndex.value = {
-                            ...resultsByIndex.value,
-                            [index]: { status: 'nodata' }
-                        };
-                    }
-                } else {
-                    // 结果为 null 或空数组
-                    resultsByIndex.value = {
-                        ...resultsByIndex.value,
-                        [index]: { status: 'nodata' }
-                    };
-                }
-            });
-
-            VE_API.farm.listByIds(resData.imageIds).then(({ data, code: respCode }) => {
-                if (respCode === 0) {
-                    // 按 imageIds 顺序,为每张图优先选择 cloudResFilename,否则 cloudFilename
-                    const idToRecord = {};
-                    (data || []).forEach((item) => {
-                        if (item && item.id) idToRecord[item.id] = item;
-                    });
-                    const urls = [...displayUrls.value];
-                    imageIds.forEach((id, idx) => {
-                        const rec = idToRecord[id];
-                        if (rec) {
-                            const path = (rec.cloudResFilename && rec.cloudResFilename.trim() !== '')
-                                ? rec.cloudResFilename
-                                : (rec.cloudFilename || imgKey[idx]);
-                            urls[idx] = base_img_url2 + path + resize;
-                        }
-                    });
-                    displayUrls.value = urls;
-                }
-            });
-
-            if (fetchPromises.length > 0) {
-                Promise.allSettled(fetchPromises).finally(() => {
-                    isRecognize.value = false;
-                });
-            } else {
-                // 全部无病虫
-                noData.value = true;
-                isRecognize.value = false;
-            }
-        }
-    }
-};
-
-const router = useRouter();
-const goBack = () => {
-    // router.go(-1);
-    router.push(`/home`);
-};
-
-const toDetail = (index) => {
-    // 根据当前图片的索引获取对应的 farmWorkLibId
-    const farmWorkLibIdList = farmWorkLibIdsByIndex.value[index];
-    const farmWorkLibId = Array.isArray(farmWorkLibIdList) && farmWorkLibIdList.length > 0 
-        ? farmWorkLibIdList[0] 
-        : null;
-    
-    // 调用子组件方法,传递 farmWorkLibId 参数
-    if (farmWorkLibId) {
-        detailDialogRef.value.showDialog(farmWorkLibId);
-    } else {
-        ElMessage.warning('暂无农事详情');
-    }
-};
-</script>
-
-<style lang="scss" scoped>
-.diseases-dictionary-detail {
-    position: relative;
-    width: 100%;
-    height: 100vh;
-    overflow: hidden;
-    background: #fff;
-
-    .page-title {
-        height: 44px;
-        line-height: 44px;
-        text-align: center;
-        font-size: 17px;
-        font-weight: bold;
-        // border-bottom: 1px solid #ededed;
-        .title-icon {
-            cursor: pointer;
-            position: absolute;
-            left: 16px;
-            top: 13px;
-        }
-    }
-    .detail-content {
-        height: calc(100% - 44px - 20px);
-        overflow: auto;
-        .detail-img {
-            height: calc(100% - 100px);
-            position: relative;
-            padding: 4px 16px 30px 16px;
-            .card-swipe-wrapper {
-                width: 100%;
-                height: 100%;
-                border-radius: 24px 0 36px 4px;
-                overflow: hidden;
-                :deep(.van-swipe-item) {
-                    width: 100%;
-                    height: 100%;
-                    display: flex;
-                    flex-direction: column;
-                }
-                :deep(.van-swipe__indicators) {
-                    bottom: 10px;
-                }
-                :deep(.van-swipe__indicator) {
-                    width: 6px;
-                    height: 6px;
-                    background-color: #cccccc;
-                    border-radius: 50%;
-                    margin: 0 4px;
-                    transition: all 0.3s;
-                }
-                :deep(.van-swipe__indicator--active) {
-                    width: 20px;
-                    height: 6px;
-                    background-color: #2199f8;
-                    border-radius: 3px;
-                }
-            }
-            .card-item {
-                width: 100%;
-                height: 100%;
-                position: relative;
-                .ing-wrap {
-                    color: #fff;
-                    position: absolute;
-                    left: 0;
-                    right: 0;
-                    top: 50%;
-                    transform: translateY(-50%);
-                    margin: 0 auto;
-                    background: rgba(0, 0, 0, 0.6);
-                    border-radius: 12px;
-                    width: 164px;
-                    height: 95px;
-                    display: flex;
-                    flex-direction: column;
-                    align-items: center;
-                    justify-content: center;
-                    z-index: 10;
-                }
-                .card-bg {
-                    border-radius: 24px 0 36px 4px;
-                    width: 100%;
-                    height: 100%;
-                    object-fit: cover;
-                }
-                .no-data {
-                    color: #fff;
-                    text-align: center;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    img {
-                        width: 17px;
-                        margin-right: 4px;
-                    }
-                }
-                .card-content {
-                    position: absolute;
-                    bottom: 0;
-                    left: 0;
-                    padding: 12px 12px 26px 12px;
-                    border-radius: 24px 0 36px 4px;
-                    color: #ffffff;
-                    background: rgba(0, 0, 0, 0.6);
-                    backdrop-filter: blur(4px);
-                    max-height: calc(100% - 38px);
-                    overflow: auto;
-                    width: 100%;
-                    box-sizing: border-box;
-                    &.no-data {
-                        padding: 16px 0 20px 0;
-                    }
-                    .ques-text {
-                        color: #ffd786;
-                        font-size: 18px;
-                        position: relative;
-                        padding-left: 12px;
-                    }
-                    .ques-text:after {
-                        content: "";
-                        position: absolute;
-                        width: 4px;
-                        height: 15px;
-                        top: 5px;
-                        left: 0;
-                        border-radius: 2px;
-                        background: #ffd186;
-                    }
-                    .dialog-famous {
-                        padding: 8px 0 4px 0;
-                        color: #ffd786;
-                        font-size: 16px;
-                    }
-                    .dialog-answer {
-                        line-height: 24px;
-                    }
-                    .advice-wrap {
-                        padding-top: 12px;
-                    }
-                    .item-tag {
-                        width: fit-content;
-                        padding: 4px 10px;
-                        border-radius: 20px;
-                        color: #ffd786;
-                        background: rgba(255, 215, 134, 0.2);
-                        margin-bottom: 6px;
-                    }
-                    .info {
-                        padding: 10px 10px 6px 0;
-                        font-size: 15px;
-                    }
-                    .desc {
-                        font-size: 14px;
-                        line-height: 24px;
-                    }
-                    .famous-info {
-                        display: flex;
-                        align-items: center;
-                        color: #ffd786;
-                        font-size: 16px;
-                        padding: 8px 0 0px 0;
-                        img {
-                            width: 16px;
-                            height: 16px;
-                            margin-right: 4px;
-                        }
-                    }
-                }
-            }
-        }
-        .btn-wrap {
-            width: 100%;
-            height: 56px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin: 0 auto;
-            padding: 0 16px;
-            box-sizing: border-box;
-            .btn {
-                height: 40px;
-                line-height: 40px;
-                font-size: 16px;
-                text-align: center;
-                color: #000;
-                border-radius: 4px;
-                &.primary {
-                    flex: 1;
-                    color: #fff;
-                    background: #2199f8;
-                }
-                &.share {
-                    background: #fff;
-                    width: 20%;
-                    min-width: 80px;
-                    text-align: center;
-                    border: 1px solid #8e8e8e;
-                }
-            }
-            .btn + .btn {
-                margin-left: 15px;
-            }
-        }
-        .box-title {
-            font-size: 16px;
-            font-weight: bold;
-            color: #000;
-            padding: 16px 2px 16px 0;
-        }
-        .padding-t {
-            padding-top: 26px;
-        }
-        .expert-box {
-            .expert-item {
-                display: flex;
-                justify-content: space-between;
-            }
-            .expert-l {
-                display: inline-flex;
-                align-items: center;
-                .expert-name {
-                    padding-left: 10px;
-                }
-                .expert-tag {
-                    background: #f7ecc7;
-                    padding: 2px 6px;
-                    color: #ae7d22;
-                    width: fit-content;
-                    border-radius: 4px;
-                    font-size: 12px;
-                    display: flex;
-                    align-items: center;
-                    margin-left: 10px;
-                }
-                img {
-                    width: 40px;
-                    height: 40px;
-                    border-radius: 50%;
-                }
-            }
-            .line {
-                margin: 16px;
-                width: calc(100% - 32px);
-                height: 1px;
-                background: #f1f1f1;
-            }
-        }
-    }
-}
-</style>

+ 0 - 384
src/views/old_mini/album_recognize/index.vue

@@ -1,384 +0,0 @@
-<template>
-    <div class="diseases-dictionary-detail">
-        <div class="page-title" @click="goBack">
-            <el-icon class="title-icon" color="rgba(0, 0, 0, 0.8)" size="16"><ArrowLeftBold /></el-icon>
-            识别结果
-        </div>
-        <div class="detail-content">
-            <div class="detail-img">
-                <Swipe class="card-swipe-wrapper" :show-indicators="imgKey && imgKey.length > 1" :loop="false">
-                    <SwipeItem v-for="(img, index) in imgKey" :key="index">
-                        <div class="card-item">
-                            <div class="ing-wrap" v-if="isRecognize">
-                                <div>
-                                    <el-icon size="20" class="is-loading">
-                                        <Loading />
-                                    </el-icon>
-                                </div>
-                                正在识别,请稍后...
-                            </div>
-                            <img class="card-bg" :src="displayUrls[index]" />
-                            <div class="card-content" v-if="!isRecognize">
-                                <div class="title-ques">
-                                    <div class="ques-text">病虫名称:{{ recognizeResult[index]?.diseaseName }}</div>
-                                </div>
-                                <div class="dialog-famous">管理方法:</div>
-                                <div class="dialog-answer">
-                                    {{ recognizeResult[index]?.managementMethod }}
-                                </div>
-                                <div v-if="recognizeResult[index]?.basicInfo" class="advice-wrap">
-                                    <div class="item-tag">基本信息</div>
-                                    <div v-html="recognizeResult[index]?.basicInfo"></div>
-                                </div>
-                                <!-- <div class="famous-info" @click="toDetail(index)">
-                                    <img src="@/assets/img/home/link-icon.png" />
-                                    <span>点击查看农事详情</span>
-                                </div> -->
-                            </div>
-                            <!-- <div class="card-content no-data" v-if="!isRecognize && recognizeResult[index]?.status === 'nodata'">
-                                <img src="@/assets/img/home/good-fill.png" />
-                                长势良好,并未发现病虫害
-                            </div> -->
-                        </div>
-                    </SwipeItem>
-                </Swipe>
-            </div>
-            <!-- <div class="btn-wrap" v-if="!isRecognize">
-                <div class="btn share" @click="toConsult">咨询专家</div>
-            </div> -->
-        </div>
-    </div>
-    <!-- 农事信息弹窗 -->
-    <detail-dialog ref="detailDialogRef" :show-success-only="true"></detail-dialog>
-    <!-- 上传弹窗组件 -->
-    <active-upload-popup></active-upload-popup>
-</template>
-
-<script setup>
-import { onMounted, ref } from "vue";
-import { Swipe, SwipeItem } from "vant";
-import { useRouter, useRoute } from "vue-router";
-import { base_img_url2 } from "@/api/config.js";
-import { ElMessage } from "element-plus";
-import detailDialog from "@/components/detailDialog.vue";
-import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
-import { toRaw } from 'vue'
-
-let resize = "?x-oss-process=image/resize,w_300";
-const route = useRoute();
-const miniJson = toRaw(route.query.miniJson);
-const json = JSON.parse(miniJson || "{}");
-// const json = JSON.parse(
-//     `{"imgKey":["birdseye-look-mini/766/1761968109259.png","birdseye-look-mini/766/1761968110225.png"],"farmId":766,"id":"65","imageIds":["772470289337421824","772470289337421825"],"token":"bcc0e12d-bff6-4f1f-8edc-2ab80b19af41"}`)
-const imgKey = json.imgKey?.split(",") || [];
-
-const isRecognize = ref(true);
- 
-// 存储每张图片的 farmWorkLibId,用于后续接口请求
-const farmWorkLibIdsByIndex = ref({});
-
-// 预置显示地址:默认使用传入的 cloudFilename
-const displayUrls = imgKey.map((p) => base_img_url2 + p + resize);
-const detailDialogRef = ref(null);
-
-const recognizeResult = ref([]);
-onMounted(() => {
-    VE_API.ali.AIRecognize({
-        imageUrls: displayUrls,
-    }).then(({data}) => {
-        recognizeResult.value = data;
-        isRecognize.value = false;
-    });
-});
-
-
-const router = useRouter();
-const goBack = () => {
-    // router.go(-1);
-    router.push(`/home`);
-};
-
-const toDetail = (index) => {
-    // 根据当前图片的索引获取对应的 farmWorkLibId
-    const farmWorkLibIdList = farmWorkLibIdsByIndex.value[index];
-    const farmWorkLibId = Array.isArray(farmWorkLibIdList) && farmWorkLibIdList.length > 0 
-        ? farmWorkLibIdList[0] 
-        : null;
-    
-    // 调用子组件方法,传递 farmWorkLibId 参数
-    if (farmWorkLibId) {
-        detailDialogRef.value.showDialog(farmWorkLibId);
-    } else {
-        ElMessage.warning('暂无农事详情');
-    }
-};
-
-const currentFarmId = localStorage.getItem('selectedFarmId')
-const toConsult = async () => {
-    const userId = await getNearStore();
-    router.push(`/chat_frame?userId=${userId}&farmId=${currentFarmId}`);
-};
-
-async function getNearStore() {
-    const params = {
-        farmId: currentFarmId,
-    };
-    const {data} = await VE_API.z_agricultural_store.getStoreItem(params);
-    return data.miniUserId;
-}
-</script>
-
-<style lang="scss" scoped>
-.diseases-dictionary-detail {
-    position: relative;
-    width: 100%;
-    height: 100vh;
-    overflow: hidden;
-    background: #fff;
-
-    .page-title {
-        height: 44px;
-        line-height: 44px;
-        text-align: center;
-        font-size: 17px;
-        font-weight: bold;
-        // border-bottom: 1px solid #ededed;
-        .title-icon {
-            cursor: pointer;
-            position: absolute;
-            left: 16px;
-            top: 13px;
-        }
-    }
-    .detail-content {
-        height: calc(100% - 44px);
-        overflow: auto;
-        .detail-img {
-            height: calc(100% - 34px);
-            position: relative;
-            padding: 4px 16px 30px 16px;
-            .card-swipe-wrapper {
-                width: 100%;
-                height: 100%;
-                border-radius: 24px 0 36px 4px;
-                overflow: hidden;
-                :deep(.van-swipe-item) {
-                    width: 100%;
-                    height: 100%;
-                    display: flex;
-                    flex-direction: column;
-                }
-                :deep(.van-swipe__indicators) {
-                    bottom: 10px;
-                }
-                :deep(.van-swipe__indicator) {
-                    width: 6px;
-                    height: 6px;
-                    background-color: #cccccc;
-                    border-radius: 50%;
-                    margin: 0 4px;
-                    transition: all 0.3s;
-                }
-                :deep(.van-swipe__indicator--active) {
-                    width: 20px;
-                    height: 6px;
-                    background-color: #2199f8;
-                    border-radius: 3px;
-                }
-            }
-            .card-item {
-                width: 100%;
-                height: 100%;
-                position: relative;
-                .ing-wrap {
-                    color: #fff;
-                    position: absolute;
-                    left: 0;
-                    right: 0;
-                    top: 50%;
-                    transform: translateY(-50%);
-                    margin: 0 auto;
-                    background: rgba(0, 0, 0, 0.6);
-                    border-radius: 12px;
-                    width: 164px;
-                    height: 95px;
-                    display: flex;
-                    flex-direction: column;
-                    align-items: center;
-                    justify-content: center;
-                    z-index: 10;
-                }
-                .card-bg {
-                    border-radius: 24px 0 36px 4px;
-                    width: 100%;
-                    height: 100%;
-                    object-fit: cover;
-                }
-                .no-data {
-                    color: #fff;
-                    text-align: center;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    img {
-                        width: 17px;
-                        margin-right: 4px;
-                    }
-                }
-                .card-content {
-                    position: absolute;
-                    bottom: 0;
-                    left: 0;
-                    padding: 12px 12px 26px 12px;
-                    border-radius: 24px 0 36px 4px;
-                    color: #ffffff;
-                    background: rgba(0, 0, 0, 0.6);
-                    backdrop-filter: blur(4px);
-                    max-height: calc(100% - 38px);
-                    overflow: auto;
-                    width: 100%;
-                    box-sizing: border-box;
-                    &.no-data {
-                        padding: 16px 0 20px 0;
-                    }
-                    .ques-text {
-                        color: #ffd786;
-                        font-size: 18px;
-                        position: relative;
-                        padding-left: 12px;
-                    }
-                    .ques-text:after {
-                        content: "";
-                        position: absolute;
-                        width: 4px;
-                        height: 15px;
-                        top: 5px;
-                        left: 0;
-                        border-radius: 2px;
-                        background: #ffd186;
-                    }
-                    .dialog-famous {
-                        padding: 8px 0 4px 0;
-                        color: #ffd786;
-                        font-size: 16px;
-                    }
-                    .dialog-answer {
-                        line-height: 24px;
-                    }
-                    .advice-wrap {
-                        padding-top: 12px;
-                    }
-                    .item-tag {
-                        width: fit-content;
-                        padding: 4px 10px;
-                        border-radius: 20px;
-                        color: #ffd786;
-                        background: rgba(255, 215, 134, 0.2);
-                        margin-bottom: 6px;
-                    }
-                    .info {
-                        padding: 10px 10px 6px 0;
-                        font-size: 15px;
-                    }
-                    .desc {
-                        font-size: 14px;
-                        line-height: 24px;
-                    }
-                    .famous-info {
-                        display: flex;
-                        align-items: center;
-                        color: #ffd786;
-                        font-size: 16px;
-                        padding: 8px 0 0px 0;
-                        img {
-                            width: 16px;
-                            height: 16px;
-                            margin-right: 4px;
-                        }
-                    }
-                }
-            }
-        }
-        .btn-wrap {
-            width: 100%;
-            height: 56px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin: 0 auto;
-            padding: 0 16px;
-            box-sizing: border-box;
-            .btn {
-                height: 40px;
-                line-height: 40px;
-                font-size: 16px;
-                text-align: center;
-                color: #000;
-                border-radius: 4px;
-                &.primary {
-                    flex: 1;
-                    color: #fff;
-                    background: #2199f8;
-                }
-                &.share {
-                    flex: 1;
-                    background: #fff;
-                    // width: 20%;
-                    min-width: 80px;
-                    text-align: center;
-                    border: 1px solid #8E8E8E;
-                    color: #000;
-                    border-radius: 20px;
-                }
-            }
-            .btn + .btn {
-                margin-left: 15px;
-            }
-        }
-        .box-title {
-            font-size: 16px;
-            font-weight: bold;
-            color: #000;
-            padding: 16px 2px 16px 0;
-        }
-        .padding-t {
-            padding-top: 26px;
-        }
-        .expert-box {
-            .expert-item {
-                display: flex;
-                justify-content: space-between;
-            }
-            .expert-l {
-                display: inline-flex;
-                align-items: center;
-                .expert-name {
-                    padding-left: 10px;
-                }
-                .expert-tag {
-                    background: #f7ecc7;
-                    padding: 2px 6px;
-                    color: #ae7d22;
-                    width: fit-content;
-                    border-radius: 4px;
-                    font-size: 12px;
-                    display: flex;
-                    align-items: center;
-                    margin-left: 10px;
-                }
-                img {
-                    width: 40px;
-                    height: 40px;
-                    border-radius: 50%;
-                }
-            }
-            .line {
-                margin: 16px;
-                width: calc(100% - 32px);
-                height: 1px;
-                background: #f1f1f1;
-            }
-        }
-    }
-}
-</style>

+ 0 - 518
src/views/old_mini/expert_detail/index.vue

@@ -1,518 +0,0 @@
-<template>
-    <div class="farm-page">
-        <custom-header :name="query.isStore ? '查看详情' : '我的主页'"></custom-header>
-        <div class="farm-list">
-            <div class="box-wrap expert-info">
-                <div class="expert-top">
-                    <div class="top-l" v-if="query.isStore">
-                        <img class="expert-icon store-icon" src="@/assets/img/home/nz.png" alt="">
-                        <div class="l-info store-info">
-                            <div class="info-name">
-                                <div class="expert-name">{{ storeDetail?.storeName }}</div>
-                            </div>
-                            <div class="info-bottom">
-                                <el-rate
-                                    v-model="storeDetail.score"
-                                    disabled
-                                    :colors="['#FF953D', '#FF953D', '#FF953D']"
-                                    disabled-void-color="#DDDDDD"
-                                    size="small"
-                                    show-score
-                                    text-color="#FF953D"
-                                    score-template="{value} 分"
-                                />
-                            </div>
-                        </div>
-                    </div>
-                    <div class="top-l" v-else>
-                        <img class="expert-icon" src="https://birdseye-img.sysuimars.com/birdseye-look-vue/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250411150343.png" alt="">
-                        <div class="l-info">
-                            <div class="info-name">
-                                <div class="expert-name">韦帮稳</div>
-                                <span class="expert-tag">
-                                    <img class="expert-img" src="@/assets/img/home/expert-icon.png" alt="">
-                                    专家
-                                </span>
-                            </div>
-                            <div class="info-bottom">
-                                <div
-                                    class="fruit-tag"
-                                    v-for="(ele, eleIndex) in tagList"
-                                    :key="eleIndex"
-                                >
-                                    {{ ele.name }}
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <!-- <div class="top-r">编辑信息</div> -->
-                </div>
-                <div class="expert-list">
-                    <div class="page-title">
-                        <img class="title-icon" src="@/assets/img/home/man.png" alt="">
-                        {{ query.isStore ? '基本简介' : '专家简介' }}
-                    </div>
-                    <div class="list-one" v-if="query.isStore">
-                        <div class="one-info">
-                            <span class="one-name">服务类型:</span>
-                            <span v-for="(item, index) in storeDetail?.serviceTypeJson" :key="index">
-                                {{ item }}
-                                <span v-if="index !== storeDetail?.serviceTypeJson.length - 1">、</span>
-                            </span>
-                            <span v-if="!storeDetail?.serviceTypeJson || storeDetail?.serviceTypeJson.length === 0">--</span>
-                        </div>
-                        <div class="one-info">
-                            <span class="one-name">服务作物:</span>
-                            <span v-for="(item, index) in storeDetail?.serviceCropsJson" :key="index">
-                                {{ item }}
-                                <span v-if="index !== storeDetail?.serviceCropsJson.length - 1">、</span>
-                            </span>
-                            <span v-if="!storeDetail?.serviceCropsJson || storeDetail?.serviceCropsJson.length === 0">--</span>
-                        </div>
-                        <div class="one-info">
-                            <span class="one-name">服务区域:</span>{{ storeDetail?.address || "--" }}
-                        </div>
-                        <div class="one-info">
-                            <span class="one-name">农机设备:</span>
-                            <span v-for="(item, index) in storeDetail?.agriculturalEquipmentJson" :key="index">
-                                {{ item }}
-                                <span v-if="index !== storeDetail?.agriculturalEquipmentJson.length - 1">、</span>
-                            </span>
-                            <span v-if="!storeDetail?.agriculturalEquipmentJson || storeDetail?.agriculturalEquipmentJson.length === 0">--</span>
-                        </div>
-                    </div>
-                    <div class="list-one" v-else>
-                        <div class="one-info">
-                            <span class="one-name">职称:</span>广州荔博园种业有限公司董事长
-                        </div>
-                        <div class="one-info">
-                            <span class="one-name">单位:</span>广州市从化区荔枝文化博览园
-                        </div>
-                        <div class="one-info">
-                            <span class="one-name">擅长:</span>荔枝的病虫害防治、生长异常调节、物候期调 节等等...
-                        </div>
-                        <div class="one-info last-one">
-                            <span class="one-name">服务品类:</span><div class="more">更多<el-icon class="more-icon"><ArrowRightBold /></el-icon></div>
-                        </div>
-                        <div class="one-type">
-                            <div class="type-item" v-for="item in 5" :key="item">
-                                <img class="type-img" src="@/assets/img/gallery/icon-0.png" alt="">
-                                <div class="type-name">荔枝</div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="box-wrap list-wrap">
-                <div class="list-title">
-                    <div class="page-title">
-                        <img class="garden-icon" src="@/assets/img/home/garden-title.png" alt="">
-                        {{ query.isStore ? '服务农场' : '定点基地' }}
-                    </div>
-                    <div class="more" v-if="farmList && farmList.length > 9">更多<el-icon class="more-icon"><ArrowRightBold /></el-icon></div>
-                </div>
-                <div class="list-content">
-                    <div class="list-item" v-for="item in farmList" :key="item">
-                        <div class="item-info">
-                            <div class="item-top">
-                                <div class="left-img">
-                                    <img class="img-dom" src="https://birdseye-img-ali-cdn.sysuimars.com/16926861-1e20-4cbd-8bf2-90208db5a2d0/806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_202509010800_001_806080da-1a30-4b5b-b64b-b22e722c6cb6/DJI_20250901080536_0045_V_code-ws0fsmge97gh.jpeg?x-oss-process=image/resize,w_1000" alt="">
-                                </div>
-                                <div class="left-content">
-                                    <div class="content-title">
-                                        <span>{{ item.farmName }}</span>
-                                    </div>
-                                    <div class="content-desc">
-                                        <div>果园面积:{{ item.mianji || "--" }}亩</div>
-                                        <div>服务作物:{{ item.typeName }}</div>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="item-btn" v-if="!query.isStore">查看详情</div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="bottom-btn" v-if="query.isStore">
-            <div class="share-btn" @click="handleFreeConsult">免费咨询</div>
-        </div>
-        <div class="bottom-btn" v-else>
-            <div class="share-btn">分享</div>
-        </div>
-    </div>
-</template>
-
-<script setup>
-import { useRouter } from "vue-router";
-import customHeader from "@/components/customHeader.vue";
-import { onActivated, ref } from "vue";
-import { useRoute } from "vue-router";
-
-const router = useRouter();
-let query = ref(useRoute().query);
-
-onActivated(() => {
-    query.value = useRoute().query;
-    if (query.value.id && query.value.isStore) {
-        getStoreDetail();
-        getFarmList();
-    }
-});
-
-const getStoreDetail = () => {
-    const params = {
-        id: query.value.id,
-    };
-    VE_API.z_agricultural_store.getStoreDetail(params).then((res) => {
-        storeDetail.value = res.data || {};
-        storeDetail.value.score = res.data.score || 5;
-    });
-};
-
-const farmList = ref([]);
-const getFarmList = () => {
-    const params = {
-        id: query.value.id,
-    };
-    VE_API.z_agricultural_store.getStoreList(params).then((res) => {
-        farmList.value = res.data || [];
-    });
-};
-const storeDetail = ref({});
-const tagList = [{name: "荔枝"}, {name: "龙眼"}]
-const handleFreeConsult = () => {
-    router.push(`/chat_frame?userId=${storeDetail.value.managers[0].miniUserId}`);
-};
-</script>
-
-<style scoped lang="scss">
-.farm-page {
-    width: 100%;
-    height: 100vh;
-    .farm-list {
-        width: 100%;
-        height: calc(100% - 40px - 52px);
-        overflow: auto;
-        background-color: #f7f7f7;
-        padding: 12px;
-        box-sizing: border-box;
-        .page-title {
-            display: flex;
-            align-items: center;
-            font-size: 16px;
-            color: #000000;
-            font-weight: bold;
-            .title-icon {
-                width: 16px;
-                height: 16px;
-                padding-right: 8px;
-            }
-            .garden-icon {
-                width: 16px;
-                padding-right: 8px;
-            }
-        }
-        
-        .more {
-            display: flex;
-            align-items: center;
-            color: #999999;
-        }
-        .box-wrap {
-            background: #ffffff;
-            border-radius: 12px;
-            padding: 12px;
-            &.expert-info {
-                .expert-top {
-                    display: flex;
-                    align-items: flex-start;
-                    justify-content: space-between;
-                    .top-l {
-                        display: flex;
-                    }
-                    .top-r {
-                        display: flex;
-                        align-items: center;
-                        padding: 4px 10px;
-                        color: #2199F8;
-                        font-size: 12px;
-                        background: rgba(33, 153, 248, 0.12);
-                        border-radius: 20px;
-                    }
-                    .l-info {
-                        padding-left: 7px;
-                        &.store-info {
-                            padding-left: 10px;
-                            .info-bottom {
-                                background: rgba(255, 149, 61, 0.1);
-                                border-radius: 4px;
-                                margin-top: 2px;
-                                padding: 0px 4px 2px 4px;
-                                ::v-deep{
-                                    .el-rate .el-rate__icon {
-                                        margin-right: 2px;
-                                    }
-                                    .el-rate--small {
-                                        height: 20px;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    .info-name {
-                        display: flex;
-                        align-items: center;
-                    }
-                    .info-bottom {
-                        padding-top: 8px;
-                        display: flex;
-                    }
-                    
-                    .fruit-tag {
-                        margin-left: 5px;
-                        padding: 0 8px;
-                        height: 20px;
-                        line-height: 20px;
-                        background: #cae7ff;
-                        border-radius: 2px;
-                        font-size: 12px;
-                        color: #2199f8;
-                        // &.pest {
-                        //     background: #eedaff;
-                        //     color: #ac4dff;
-                        // }
-                        &:nth-child(2) {
-                            background: #eedaff;
-                            color: #ac4dff;
-                        }
-                    }
-                    .expert-icon {
-                        width: 68px;
-                        height: 68px;
-                        border-radius: 8px;
-                        object-fit: cover;
-                        &.store-icon {
-                            width: 50px;
-                            height: 50px;
-                        }
-                    }
-                    .info-flex{
-                        display: flex;
-                        align-items: center;
-                    }
-                    .expert-name {
-                        color: #000;
-                        font-size: 16px;
-                        font-weight: bold;
-                    }
-                    .expert-tag {
-                        height: 20px;
-                        width: 48px;
-                        display: flex;
-                        align-items: center;
-                        justify-content: center;
-                        color: #C77D05;
-                        background: #FFECAD;
-                        border-radius: 4px;
-                        font-size: 12px;
-                        margin-left: 8px;
-                        line-height: 20px;
-                        .expert-img {
-                            width: 12px;
-                            padding-right: 2px;
-                        }
-                    }
-                    .btn-text{
-                        font-size: 12px;
-                        color: #A8A8A8;
-                        padding: 2px 12px;
-                        border-radius: 20px;
-                        border: 1px solid #A8A8A8;
-                        background: rgba(220, 220, 220, 0.1);
-                        &.actice{
-                            color: #F3C11D;
-                            border-color: #F3C11D;
-                            background: rgba(243, 193, 29, 0.1);
-                        }
-                    }
-                }
-                .expert-list {
-                    padding-top: 16px;
-                    font-size: 14px;
-                    .list-one {
-                        padding-top: 8px;
-                        .one-info {
-                            // display: flex;
-                            color: #666666;
-                            line-height: 18px;
-                            padding-bottom: 4px;
-                            .one-name {
-                                flex: none;
-                                color: rgba(102, 102, 102, 0.5);
-                            }
-                            &.last-one {
-                                padding-top: 6px;
-                                display: flex;
-                                align-items: center;
-                                justify-content: space-between;
-                            }
-                        }
-                        .one-type {
-                            padding-top: 8px;
-                            display: flex;
-                            justify-content: space-around;
-                            .type-item {
-                                width: 20%;
-                                display: flex;
-                                flex-direction: column;
-                                justify-content: center;
-                                align-items: center;
-                                .type-img {
-                                    width: 48px;
-                                    height: 48px;
-                                    border-radius: 50%;
-                                    border: 1px solid #E5E5E5;
-                                }
-                                .type-name {
-                                    padding-top: 2px;
-                                    color: #666666;
-                                    font-size: 12px;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            &.list-wrap {
-                margin-top: 12px;
-                .list-title {
-                    padding-bottom: 12px;
-                    display: flex;
-                    justify-content: space-between;
-                    align-items: center;
-                    border-bottom: 1px solid #F5F5F5;
-                }
-            }
-        }
-        .list-content {
-            padding: 12px 0;
-        }
-        .list-item {
-            background-color: #fff;
-            border-radius: 10px;
-            // padding: 10px;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            .item-info {
-                .item-top {
-                    display: flex;
-                    align-items: center;
-                    gap: 12px;
-                    .left-img {
-                        width: 68px;
-                        height: 68px;
-                        border-radius: 8px;
-                        .img-dom {
-                            border-radius: 8px;
-                            width: 100%;
-                            height: 100%;
-                            object-fit: cover;
-                        }
-                    }
-                    .left-content {
-                        .content-title {
-                            display: flex;
-                            align-items: center;
-                            gap: 10px;
-                            margin-bottom: 4px;
-                            font-size: 16px;
-                            font-weight: 500;
-                            .content-tag {
-                                background-color: #2199f8;
-                                color: #fff;
-                                padding: 2px 8px;
-                                border-radius: 15px;
-                                font-size: 12px;
-                                font-weight: 400;
-                            }
-                            .content-text {
-                                font-size: 12px;
-                                color: #2199F8;
-                                font-weight: 400;
-                            }
-                        }
-                        .content-desc {
-                            font-size: 12px;
-                            color: #999999;
-                            line-height: 18px;
-                        }
-                    }
-                }
-                .select {
-                    width: 105px;
-                    margin-left: 80px;
-                    margin-top: 10px;
-                    ::v-deep{
-                        .el-select__wrapper{
-                            border: 1px solid #2199F8;
-                            box-shadow: none;
-                        }
-                        .el-select__placeholder,.el-select__caret{
-                            color: #2199F8;
-                        }
-                        .el-select__selection {
-                            flex: none;
-                            width: fit-content;
-                        }
-                        .el-select__placeholder {
-                            position: static;
-                            transform: none;
-                            width: fit-content;
-                        }
-                    }
-                }
-            }
-            .item-btn {
-                color: #2199F8;
-                padding: 4px 8px;
-                border: 1px solid #2199F8;
-                border-radius: 4px;
-            }
-        }
-        .list-item + .list-item {
-            margin-top: 10px;
-            padding-top: 10px;
-            border-top: 1px solid #F5F5F5;
-        }
-    }
-    .bottom-btn {
-        height: 52px;
-        width: 100%;
-        padding: 6px 32px;
-        box-sizing: border-box;
-        &.flex-between {
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            .forward-btn {
-                background: #fff;
-                border: 1px solid rgba(153, 153, 153, 0.5);
-                color: #666666;
-                padding: 8px 20px;
-            }
-            .free-btn {
-                padding: 8px 20px;
-            }
-        }
-        .share-btn {
-            color: #fff;
-            text-align: center;
-            border-radius: 20px;
-            padding: 8px;
-            background: linear-gradient(180deg, #76C3FF, #2199F8);
-        }
-    }
-}
-</style>

+ 232 - 0
src/views/old_mini/recordDetails/index.vue

@@ -0,0 +1,232 @@
+<template>
+    <div class="record-wrap">
+        <custom-header name="农事名称"></custom-header>
+        <div class="record-content">
+            <div class="record-header">
+                <span>物候跟踪记录</span>
+                <div class="question">具体问题具体问题具体问题具体问题具体问题具体</div>
+            </div>
+            <div class="record-body">
+                <div class="card-wrap">
+                    <div class="card-item">
+                        <span class="item-label">农情研判:</span>
+                        <span class="item-value">互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因互动原因</span>
+                    </div>
+                    <div class="card-item">
+                        <span class="item-label">巡园要点:</span>
+                        <span class="item-value">巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点巡园要点</span>
+                    </div>
+                    <div class="card-item">
+                        <span class="item-label">表型特征:</span>
+                        <span class="item-value">表型特征</span>
+                    </div>
+                </div>
+                <div class="card-wrap">
+                    <div class="map-wrap">
+                        <div class="question-box">
+                            <span>问题问题问题问题问题问题</span>
+                            <el-input class="input" v-model="input" size="large" type="number">
+                                <template #suffix>
+                                    <span>%</span>
+                                </template>
+                            </el-input>
+                        </div>
+                        <div class="my-map">
+                            <div class="map-container" ref="mapContainer">
+                                <div class="tip">点击勾画新发生区域</div>
+                            </div>
+                            <div class="confirm-btn">确认上传</div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="custom-bottom-fixed-btns">
+            <div class="bottom-btn secondary-btn">转发记录</div>
+        </div>
+
+        <div class="phenology-tip-banner">
+            <div class="banner__left">
+                <div class="banner__title">物候不整齐?</div>
+                <span class="banner__desc">
+                    如果区域长势不同,会降低病虫害防治功效,
+                    建议根据长势拆分区域,进行分区精细管理,
+                    达到减药减肥的目的
+                </span>
+            </div>
+            <div class="banner__btn" @click="goPartitionManage">
+                分区管理
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import customHeader from "@/components/customHeader.vue";
+import { ref, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import IndexMap from "./map/index.js";
+
+const router = useRouter();
+
+function goPartitionManage() {
+    console.log('goPartitionManage');
+    // router.push({ name: 'Monitor' });
+}
+
+const indexMap = new IndexMap();
+const mapContainer = ref(null);
+const location = ref(null);
+const input = ref('');
+
+onMounted(() => {
+    location.value = "POINT(113.6142086995688 23.585836479509055)";
+    indexMap.initMap(location.value, mapContainer.value);
+});
+
+</script>
+
+<style scoped lang="scss">
+.record-wrap {
+    height: 100vh;
+    background: #f2f3f5;
+
+    .record-content {
+        height: calc(100% - 120px);
+        overflow: auto;
+        padding-bottom: 120px;
+
+        .record-header {
+            color: #fff;
+            background: #2199F8;
+            padding: 10px;
+            font-size: 22px;
+
+            .question {
+                font-size: 14px;
+                color: #2199F8;
+                margin-top: 10px;
+                padding: 4px 5px;
+                border-radius: 2px;
+                background: #ffffff;
+            }
+        }
+
+        .record-body {
+            padding: 10px;
+
+            .card-wrap {
+                background: #fff;
+                border-radius: 8px;
+                padding: 10px;
+
+                .card-item {
+                    padding: 5px 10px;
+                    border-radius: 5px;
+                    background: #F6F6F6;
+
+                    .item-label {
+                        color: rgba(60, 60, 60, 0.5);
+                    }
+                }
+
+                .card-item+.card-item {
+                    margin-top: 8px;
+                }
+
+                .map-wrap {
+                    border-radius: 8px;
+                    border: 0.5px solid #2199F8;
+                    padding: 10px;
+
+                    .question-box {
+                        border: 1px solid #2199F8;
+                        border-radius: 5px;
+                        padding: 8px;
+                        color: #5A5A5A;
+
+                        .input {
+                            margin-top: 10px;
+                            width: 100%;
+                        }
+                    }
+
+                    .my-map {
+                        width: 100%;
+
+                        .map-container {
+                            width: 100%;
+                            height: 170px;
+                            margin: 10px 0;
+                            clip-path: inset(0px round 5px);
+                            position: relative;
+
+                            .tip {
+                                position: absolute;
+                                top: 0;
+                                left: 0;
+                                color: #fff;
+                                padding: 5px 10px;
+                                border-radius: 5px;
+                                background: rgba(0, 0, 0, 0.6);
+                                z-index: 2;
+                            }
+                        }
+
+                        .confirm-btn {
+                            text-align: center;
+                            background: #2199F8;
+                            color: #fff;
+                            border-radius: 5px;
+                            font-size: 16px;
+                            padding: 8px;
+                        }
+                    }
+                }
+            }
+
+            .card-wrap+.card-wrap {
+                margin-top: 10px;
+            }
+        }
+    }
+
+    .phenology-tip-banner {
+        position: fixed;
+        left: 12px;
+        right: 12px;
+        bottom: calc(90px + env(safe-area-inset-bottom, 0px));
+        z-index: 99;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        gap: 8px;
+        padding: 10px 14px;
+        border-radius: 12px;
+        background: linear-gradient(180deg, #CCE8FF 0%, #ffffff 60%);
+        box-shadow: 0 2px 8px rgba(33, 153, 248, 0.12);
+
+        .banner__left {
+            flex: 1;
+
+            .banner__title {
+                font-size: 16px;
+                font-weight: 600;
+                color: #1890ff;
+            }
+
+            .banner__desc {
+                font-size: 12px;
+                color: rgba(0, 0, 0, 0.4);
+            }
+        }
+
+        .banner__btn {
+            padding: 7px 16px;
+            border-radius: 25px;
+            color: #ffffff;
+            background: linear-gradient(180deg, #5cb8ff 0%, #2e90ff 100%);
+        }
+    }
+}
+</style>

+ 98 - 0
src/views/old_mini/recordDetails/map/index.js

@@ -0,0 +1,98 @@
+import * as KMap from "@/utils/ol-map/KMap";
+import * as util from "@/common/ol_common.js";
+import config from "@/api/config.js";
+import Style from "ol/style/Style";
+import Icon from "ol/style/Icon";
+import { Point } from 'ol/geom';
+import Feature from "ol/Feature";
+import { reactive } from "vue";
+
+export let mapLocation = reactive({
+  data: null,
+});
+
+/**
+ * @description 地图层对象
+ */
+class IndexMap {
+  constructor() {
+    let that = this;
+    let vectorStyle = new KMap.VectorStyle();
+    this.vectorStyle = vectorStyle;
+
+    // 位置图标
+    this.clickPointLayer = new KMap.VectorLayer("clickPointLayer", 9999, {
+      style: (f) => {
+        return new Style({
+          image: new Icon({
+            src: require("@/assets/img/home/garden-point.png"),
+            scale: 0.5,
+            anchor: [0.5, 0.5],
+          }),
+        });
+      },
+    });
+  }
+
+  initMap(location, target) {
+    let level = 16;
+    let coordinate = util.wktCastGeom(location).getFirstCoordinate();
+    this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 8, 22);
+    let xyz2 = config.base_img_url3 + "map/lby/{z}/{x}/{y}.png";
+    this.kmap.addXYZLayer(xyz2, { minZoom: 8, maxZoom: 22 }, 2);
+    this.kmap.addLayer(this.clickPointLayer.layer);
+    this.setMapPoint(coordinate)
+    this.addMapSingerClick()
+  }
+
+  setMapPosition(center) {
+    this.kmap.getView().animate({
+      center,
+      zoom: 16,
+      duration: 0,
+    });
+    this.setMapPoint(center)
+  }
+
+  setMapPoint(coordinate) {
+    this.clickPointLayer.source.clear()
+    let point = new Feature(new Point(coordinate))
+    this.clickPointLayer.addFeature(point)
+  }
+
+  // 地图点击事件
+  addMapSingerClick() {
+    let that = this;
+    that.kmap.on("singleclick", (evt) => {
+      // that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
+      //   if ( layer instanceof VectorLayer && layer.get("name") === "reportPolygonLayer" ) {
+      //     areaId.data = feature.get("id")
+      //   }
+      // });
+      that.setMapPoint(evt.coordinate)
+      mapLocation.data = evt.coordinate
+    });
+  }
+
+  clearLayer() {
+    // this.kmap.removeLayer(this.clickPointLayer.layer)
+    this.kmap.polygonLayer.source.clear();
+  }
+
+  setAreaGeometry(geometryArr) {
+    this.clearLayer()
+    let that = this
+    geometryArr.map(item => {
+      that.kmap.setLayerWkt(item)
+    })
+    this.fitView()
+  }
+
+  fitView(){
+    let extent = this.kmap.polygonLayer.source.getExtent()
+    // 地图自适应到区域可视范围
+    this.kmap.getView().fit(extent, { duration: 500, padding: [100, 100, 100, 100] });
+  }
+}
+
+export default IndexMap;