Selaa lähdekoodia

fix: 对接接口

lxf 1 päivä sitten
vanhempi
commit
214b8d77e1

+ 9 - 0
src/api/modules/manage_interface.js

@@ -29,4 +29,13 @@ module.exports = {
         url: config.base_url + "species_item/list",
         type: "get",
     },
+    fetchUserList: {
+        url: config.base_url + "z_sample_lighten_card_offline_take/page/{page}/{limit}",
+        type: "get",
+    },
+    fetchGardenImgs: {
+        url: config.base_url + "adm/images/{organId}/{areaId}",
+        type: "get",
+    },
+
 }

BIN
src/assets/images/user/tree.png


+ 155 - 0
src/components/editClientPopup.vue

@@ -0,0 +1,155 @@
+<template>
+    <div>
+        <!-- 新增客户、编辑客户 -->
+        <popup v-model:show="showClient" closeable round class="popup-client">
+            <div class="popup-title">{{ typePopup === "add" ? "新增客户" : "编辑客户" }}</div>
+            <div class="popup-content">
+                <el-form
+                    ref="ruleFormRef"
+                    :model="ruleForm"
+                    :rules="rules"
+                    label-width="auto"
+                    class="rule-form"
+                    size="large"
+                >
+                    <el-form-item label="姓名" prop="name">
+                        <el-input class="input" v-model="ruleForm.name" size="large" placeholder="请输入姓名" />
+                    </el-form-item>
+                    <el-form-item label="电话" prop="tel">
+                        <el-input class="input" v-model="ruleForm.tel" size="large" placeholder="请输入电话号码" />
+                    </el-form-item>
+                    <el-form-item label="地址" prop="address">
+                        <el-input class="input" v-model="ruleForm.address" size="large" placeholder="请输入地址" />
+                    </el-form-item>
+                    <el-form-item label="头像" prop="photo">
+                        <upload></upload>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <div class="popup-footer">
+                <div class="cancel" @click="resetForm">取消</div>
+                <div @click="submitForm">添加</div>
+            </div>
+        </popup>
+    </div>
+</template>
+
+<script setup>
+import { Popup } from "vant";
+import { reactive, ref } from 'vue';
+import { ElMessage } from "element-plus";
+import upload from "@/components/common/upload.vue";
+
+const showClient = ref(false);
+const ruleForm = reactive({
+    name: "",
+    tel: "",
+    address: "",
+});
+const rules = reactive({
+    name: { required: true, message: "请输入用户名称", trigger: ["blur", "change"] },
+    tel: { required: true, message: "请输入电话号码", trigger: ["blur", "change"] },
+});
+
+const ruleFormRef = ref(null);
+const submitForm = async () => {
+    if (!ruleFormRef.value) return;
+    await ruleFormRef.value.validate((valid, fields) => {
+        if (valid) {
+            ElMessage.success("添加成功");
+            showClient.value = false;
+        } else {
+            console.log("error submit!");
+        }
+    });
+};
+
+
+//新增客户
+const typePopup = ref("add");
+
+const resetForm = () => {
+    if (!ruleFormRef.value) return;
+    ruleFormRef.value.resetFields();
+    showClient.value = false;
+};
+
+// 打开弹窗-类型
+function openClientPopup(type, data) {
+    console.log('data', data);
+    if (type === "edit") {
+        ruleForm.name = data.name;
+        ruleForm.tel = data.tel;
+        ruleForm.address = data.address;
+    } else {
+        ruleForm.name = "";
+        ruleForm.tel = "";
+        ruleForm.address = "";
+    }
+    typePopup.value = type;
+    showClient.value = true;
+}
+
+defineExpose({
+    openClientPopup,
+});
+</script>
+
+<style lang="scss" scoped>
+.popup-client {
+    // width: 24%;
+    width: 504px;
+    padding: 31px 25px;
+    box-sizing: border-box;
+    background: #fff;
+    ::v-deep {
+        .van-popup__close-icon {
+            // color: #ffffff;
+        }
+    }
+    .popup-title {
+        text-align: center;
+        color: #000;
+        font-size: 24px;
+        margin-bottom: 15px;
+    }
+    .popup-content {
+        width: 100%;
+        ::v-deep {
+            .el-form-item__label {
+                color: rgba(0, 0, 0, 0.4);
+            }
+            .el-input__wrapper {
+                background: transparent;
+                box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.46) inset;
+            }
+        }
+        .input {
+            height: 46px;
+            font-size: 16px;
+        }
+    }
+    .popup-footer {
+        width: 100%;
+        display: flex;
+        border-top: 1px solid rgba(0, 0, 0, 0.1);
+        margin-top: 30px;
+        padding-top: 25px;
+        div {
+            flex: 1;
+            background: linear-gradient(120deg, #ffd887, #ed9e1e);
+            border-radius: 6px;
+            padding: 13px;
+            font-size: 20px;
+            color: #000;
+            text-align: center;
+            cursor: pointer;
+        }
+        .cancel {
+            color: #000;
+            background: #f3f3f3;
+            margin-right: 30px;
+        }
+    }
+}
+</style>

+ 67 - 55
src/views/customTree/index.vue

@@ -39,31 +39,31 @@
                 <div class="tree-list">
                     <div
                         class="list-item"
-                        :class="{ selected: selectedItems.includes(item.id) }"
-                        @click="selecteTree(item.id)"
+                        :class="{ selected: selectedItems.includes(item), disabled: !isSelectable(item) && !selectedItems.includes(item) }"
+                        @click="selecteTree(item)"
                         v-for="(item, index) in allTrees"
                         :key="index"
                     >
                         <div class="tree-icon">
                             <img class="tree-img" src="@/assets/images/foster-home/tree-item.png" alt="" />
-                            <div class="tree-type-name-tag">白糖罂</div>
+                            <div class="tree-type-name-tag">{{ item.pz }}</div>
                         </div>
                         <div class="item-center">
                             <div class="center-t">
-                                BTY-A25
+                                {{ item.fosterCode }}
                                 <!-- <span class="type-tag">综合:94分</span>
                                 <span class="type-tag">生态:92分</span> -->
                             </div>
                             <div class="center-item p-t-2 age-line">
                                 <div class="age-wrap">
                                     <div class="has-age">
-                                        <div class="age">栽种时间:<span class="unit">2025.02.15</span></div>
+                                        <div class="age">栽种时间:<span class="unit">{{item.plantDate || '--'}}</span></div>
                                     </div>
                                     <div class="sort-line"></div>
                                 </div>
-                                树龄:<span class="unit">5年</span>
+                                树龄:<span class="unit">{{ (item.age && item.age+'年') || '--' }}</span>
                             </div>
-                            <div class="center-item">栽种区域:<span>2区</span></div>
+                            <div class="center-item">栽种区域:<span>{{ (item.area && item.area + '区') || '--' }}</span></div>
                         </div>
                     </div>
                 </div>
@@ -75,19 +75,19 @@
                 </div>
                 <div class="custom-detail">
                     <div class="custom-user">
-                        <div class="user-name">选择客户(15人)</div>
+                        <div class="user-name">选择客户({{visibleItems.length}}人)</div>
                         <div class="user-list">
                             <div class="user-item" v-for="(ele, idx) in visibleItems" :key="idx">
                                 <div class="item-flex">
-                                    <img class="photo" src="@/assets/images/foster-home/image.png" alt="" />
+                                    <img class="photo" :src="ele.icon || 'https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png'" alt="" />
                                     <div class="item-text">
                                         <div class="name">
                                             <span>{{ ele.name }}</span>
-                                            <el-icon class="icon" @click.stop="handlePerson('edit')" color="#2199F8" size="16"
+                                            <el-icon class="icon" @click.stop="handlePerson('edit', ele)" color="#2199F8" size="16"
                                                 ><Edit/></el-icon>
                                         </div>
-                                        <div><span class="item-title">电话:</span>19875236548</div>
-                                        <div><span class="item-title">地址:</span>湖北省武汉市富里唱鑫园5023</div>
+                                        <div><span class="item-title">电话:</span>{{ ele.tel }}</div>
+                                        <div><span class="item-title">地址:</span>{{ ele.address }}</div>
                                     </div>
                                     <div class="item-icon">
                                         <el-icon size="24" color="#E04C4C"><CircleCloseFilled /></el-icon>
@@ -106,7 +106,7 @@
                     </div>
                     <div class="box-line"></div>
                     <div class="selected-tree">
-                        <div class="user-name">选择果树({{ selectedItems.length }}棵)</div>
+                        <div class="user-name">选择果树({{ selectedItems.length }}/{{ maxSelectable }}棵)</div>
                         <div class="tree-wrap" v-show="selectedItems.length">
                             <div
                                 class="list-item selected right-tree-list"
@@ -116,24 +116,24 @@
                             >
                                 <div class="tree-icon">
                                     <img class="tree-img" src="@/assets/images/foster-home/tree-item.png" alt="" />
-                                    <div class="tree-type-name-tag">白糖罂</div>
+                                    <div class="tree-type-name-tag">{{ item.pz }}</div>
                                 </div>
                                 <div class="item-center">
                                     <div class="center-t">
-                                        BTY-A25
+                                        {{ item.fosterCode }}
                                         <!-- <span class="type-tag">综合:94分</span>
                                         <span class="type-tag">生态:92分</span> -->
                                     </div>
                                     <div class="center-item p-t-2 age-line">
                                         <div class="age-wrap">
                                             <div class="has-age">
-                                                <div class="age">栽种时间:<span class="unit">2025.02.15</span></div>
+                                                <div class="age">栽种时间:<span class="unit">{{ item.plantDate || '--' }}</span></div>
                                             </div>
                                             <div class="sort-line"></div>
                                         </div>
-                                        树龄:<span class="unit">5年</span>
+                                        树龄:<span class="unit">{{ (item.age && item.age+'年') || '--' }}</span>
                                     </div>
-                                    <div class="center-item">栽种区域:<span>2区</span></div>
+                                    <div class="center-item">栽种区域:<span>{{ (item.area && item.area + '区') || '--' }}</span></div>
                                 </div>
                                 <div class="item-icon">
                                     <el-icon size="24" color="#E04C4C"><CircleCloseFilled /></el-icon>
@@ -152,11 +152,14 @@
             </div>
         </div>
     </div>
+    <!-- 新增客户、编辑客户 -->
+    <edit-client-popup ref="editClientRef"></edit-client-popup>
 </template>
 
 <script setup>
-import { ref, computed } from "vue";
+import { ref, computed, onMounted } from "vue";
 import { useRouter } from "vue-router";
+import editClientPopup from "@/components/editClientPopup.vue";
 import { useStore } from "vuex";
 let store = useStore();
 
@@ -179,13 +182,29 @@ const ageOptions = ref([
     { label: "10-20年", value: 2 },
 ]);
 
+// 计算最大可选数量(等于客户数)
+const maxSelectable = computed(() => defalutList.value.length);
+
+// 判断是否可选
+const isSelectable = (item) => {
+  return (
+    selectedItems.value.includes(item) || 
+    selectedItems.value.length < maxSelectable.value
+  );
+};
+
 const selectedItems = ref([]);
-function selecteTree(id) {
-    if (!selectedItems.value.includes(id)) {
-        selectedItems.value.push(id);
-    }
+// 修改后的选择方法
+function selecteTree(item) {
+  if (
+    !selectedItems.value.includes(item) &&
+    selectedItems.value.length < maxSelectable.value
+  ) {
+    selectedItems.value.push(item);
+  }
 }
 
+
 const allTrees = ref([
     { id: 1 },
     { id: 2 },
@@ -210,40 +229,22 @@ function goBack() {
     router.go(-1);
 }
 
+onMounted(() => {
+    if (router.currentRoute.value.query.type === "single") {
+        const data = JSON.parse(router.currentRoute.value.query.data);
+        defalutList.value = [data];
+    }
+    getSamplePage()
+})
+
+function getSamplePage() {
+    VE_API.manage_interface.fetchSamplePage({farmId: 766, page: 1, limit: 1000}).then(({data}) => {
+        allTrees.value = data
+    })
+}
 
-const defalutList = ref([
-    {
-        id: "3",
-        name: "周浩",
-        checked: false,
-    },
-    {
-        id: "4",
-        name: "王丽丽",
-        checked: false,
-    },
 
-    {
-        id: "5",
-        name: "李莉",
-        checked: false,
-    },
-    {
-        id: "6",
-        name: "陈林",
-        checked: false,
-    },
-    {
-        id: "7",
-        name: "陈林1",
-        checked: false,
-    },
-    {
-        id: "8",
-        name: "陈林2",
-        checked: false,
-    },
-]);
+const defalutList = ref([]);
 
 
 const isExpanded = ref(false);
@@ -256,6 +257,10 @@ const toggleExpand = () => {
   isExpanded.value = !isExpanded.value;
 };
 
+const editClientRef = ref(null);
+const handlePerson = (type, data) => {
+    editClientRef.value.openClientPopup(type, data);
+};
 </script>
 
 <style lang="scss" scoped>
@@ -336,6 +341,8 @@ const toggleExpand = () => {
                 display: flex;
                 flex-wrap: wrap;
                 padding-top: 8px;
+                height: calc(100% - 32px - 32px);
+                overflow: auto;
             }
         }
         .list-item {
@@ -357,6 +364,11 @@ const toggleExpand = () => {
                 background: rgba(33, 153, 248, 0.1);
                 border-color: #2199F8;
             }
+            &.disabled {
+                opacity: 0.5;
+                cursor: not-allowed;
+                border-color: #ccc !important;
+            }
             &.right-tree-list {
                 margin-top: 0px;
             }

+ 22 - 1
src/views/home/album_compoents/albumCarousel.vue

@@ -47,7 +47,21 @@
                                     label-width="92px"
                                 >
                                     <el-form-item label="品种" prop="pz">
-                                        <el-input v-model="ruleForm.pz" placeholder="请输入品种" style="width: 240px;" />
+                                        <!-- <el-input v-model="ruleForm.pz" placeholder="请输入品种" style="width: 240px;" /> -->
+                                        <el-select
+                                            class="blue-select"
+                                            v-model="ruleForm.pz"
+                                            filterable
+                                            style="width: 240px"
+                                            placeholder="请选择品种"
+                                        >
+                                            <el-option
+                                                v-for="(species, index) in speciesList"
+                                                :key="index"
+                                                :label="species.name"
+                                                :value="species.name"
+                                            />
+                                        </el-select>
                                     </el-form-item>
                                     <el-form-item label="树龄" prop="age">
                                         <el-input-number
@@ -310,6 +324,13 @@ async function saveEdit(isToSave) {
         dialogVisible.value = false
     }
 }
+
+const speciesList = ref([]);
+onMounted(() => {
+    VE_API.manage_interface.speciesList({ farmId: 80865 }).then(({ data }) => {
+        speciesList.value = data;
+    });
+})
 </script>
 
 <style lang="scss" scoped>

+ 200 - 102
src/views/home/components/adoptList.vue

@@ -24,12 +24,22 @@
         </div>
 
         <div class="many-setting select-wrap" v-show="isManySetting">
-            <el-select class="select-item many-select" v-model="settingType" placeholder="选中设置项" style="width: 88px">
+            <el-select
+                class="select-item many-select"
+                v-model="settingType"
+                placeholder="选中设置项"
+                style="width: 88px"
+            >
                 <template #label="{ label, value }">
-                    <span v-show="value!=='total'">设置</span>
+                    <span v-show="value !== 'total'">设置</span>
                     <span>{{ label }}</span>
                 </template>
-                <el-option v-for="(item, index) in settingTypeOptions" :key="index" :label="item.name" :value="item.value" />
+                <el-option
+                    v-for="(item, index) in settingTypeOptions"
+                    :key="index"
+                    :label="item.name"
+                    :value="item.value"
+                />
             </el-select>
             <div v-if="settingType === 'age'">
                 <el-input-number
@@ -69,51 +79,86 @@
             <div class="list-item" v-for="(item, index) in adoptList" :key="index">
                 <div class="list-info">
                     <div class="tree-icon">
-                        <div class="tree-tag" v-show="!item.offlineTakeSelected">未守护</div>
-                        <div class="tree-tag wait" v-show="item.offlineTakeSelected">已守护</div>
-                        <!-- <img class="tree-img" src="@/assets/images/foster-home/tree-item.png" alt="" /> -->
-                        <img class="tree-img" :src="item.icon || require(`@/assets/images/foster-home/list/1.png`)" alt="" />
+                        <div class="tree-tag" v-show="!item.miniUserId">未守护</div>
+                        <div class="tree-tag wait" v-show="item.miniUserId">已守护</div>
+                        <img class="tree-img" src="@/assets/images/foster-home/tree-item.png" alt="" />
+                        <!-- <img class="tree-img" :src="item.icon || require(`@/assets/images/foster-home/list/1.png`)" alt="" /> -->
                         <div class="tree-type-name-tag">{{ item.pz }}</div>
                     </div>
                     <div class="item-center">
                         <div class="center-t">
-                            {{item.fosterCode}}
+                            {{ item.fosterCode }}
                             <!-- <span class="type-tag">综合:{{item.zh||94}}分</span>
                             <span class="type-tag">生态:{{item.st||92}}分</span> -->
                         </div>
-                        
+
                         <!-- 批量设置树龄或单项设置 -->
-                        <div class="center-item p-t-2 has-input" v-show="(isManySetting && settingType === 'age') || item.settingPrice">
+                        <div
+                            class="center-item p-t-2 has-input"
+                            v-show="(isManySetting && settingType === 'age') || item.settingPrice"
+                        >
                             <span class="edit-label">树龄:</span>
-                            <el-input-number @change="settingSinglePrice" class="number-input" :controls="false" v-model="item.age" :min="0" />
+                            <el-input-number
+                                @change="settingSinglePrice"
+                                class="number-input"
+                                :controls="false"
+                                v-model="item.age"
+                                :min="0"
+                            />
                             <span class="unit">年</span>
                         </div>
                         <!-- 不是编辑状态 -->
                         <div class="center-item p-t-2 age-line" v-show="!isManySetting && !item.settingPrice">
                             <div class="age-wrap">
                                 <div class="has-age">
-                                    <div class="age">栽种时间:<span class="unit">{{ item.time || '--' }}</span></div>
+                                    <div class="age">
+                                        栽种时间:<span class="unit">{{ item.time || "--" }}</span>
+                                    </div>
                                 </div>
                                 <div class="sort-line"></div>
                             </div>
-                            树龄:<span class="unit"><span class="unit">{{item.age||'--'}}年</span></span>
+                            树龄:<span class="unit"
+                                ><span class="unit">{{ item.age || "--" }}年</span></span
+                            >
                         </div>
-                        <div class="center-item" v-show="isManySetting && settingType !== 'age'"><span class="edit-label">树龄:</span><span class="unit">{{item.age||'--'}}年</span></div>
-                        <div class="center-item edit-item" v-show="isManySetting && settingType !== 'price'"><span class="edit-label">品种:</span><span class="unit">{{item.pz}}</span></div>
-                        
-                        <div class="center-item p-t-2 has-input edit-item" v-show="(isManySetting && settingType === 'price') || item.settingPrice">
+                        <div class="center-item" v-show="isManySetting && settingType !== 'age'">
+                            <span class="edit-label">树龄:</span><span class="unit">{{ item.age || "--" }}年</span>
+                        </div>
+                        <div class="center-item edit-item" v-show="isManySetting && settingType !== 'price'">
+                            <span class="edit-label">品种:</span><span class="unit">{{ item.pz }}</span>
+                        </div>
+
+                        <div
+                            class="center-item p-t-2 has-input edit-item"
+                            v-show="(isManySetting && settingType === 'price') || item.settingPrice"
+                        >
                             <span class="edit-label">品种:</span>
-                            
 
-                            <el-select v-model="item.pz" filterable style="width: 140px;" placeholder="请选择品种">
-                                <el-option v-for="(species, index) in speciesList" :key="index" :label="species.name" :value="species.name" />
+                            <el-select
+                                class="blue-select"
+                                v-model="item.pz"
+                                filterable
+                                style="width: 140px"
+                                placeholder="请选择品种"
+                            >
+                                <el-option
+                                    v-for="(species, index) in speciesList"
+                                    :key="index"
+                                    :label="species.name"
+                                    :value="species.name"
+                                />
                             </el-select>
                             <!-- <el-input @change="settingSinglePrice" style="width: 140px" class="number-input" v-model="item.pz" /> -->
                         </div>
 
-                        <div class="center-item" v-show="(isManySetting && settingType !== 'total')"><span class="edit-label">栽种时间:</span><span class="unit">{{item.time}}</span></div>
+                        <div class="center-item" v-show="isManySetting && settingType !== 'total'">
+                            <span class="edit-label">栽种时间:</span><span class="unit">{{ item.time }}</span>
+                        </div>
 
-                        <div class="center-item p-t-2 has-input date-input" v-show="(isManySetting && settingType === 'total') || item.settingPrice">
+                        <div
+                            class="center-item p-t-2 has-input date-input"
+                            v-show="(isManySetting && settingType === 'total') || item.settingPrice"
+                        >
                             <span class="edit-label">栽种时间:</span>
                             <!-- <el-input-number @change="settingSinglePrice" class="number-input" :controls="false" v-model="item.total" :min="0" /> -->
                             <el-date-picker
@@ -126,27 +171,46 @@
                             />
                         </div>
 
-                        <div class="center-item p-t-2 user-wrap" v-show="item.status === 0 && !isManySetting && !item.settingPrice">
-                            <img src="@/assets/images/foster-home/user.png" alt="">
+                        <div
+                            class="center-item p-t-2 user-wrap"
+                            v-show="item.status === 0 && !isManySetting && !item.settingPrice"
+                        >
+                            <img src="@/assets/images/foster-home/user.png" alt="" />
                             选择守护人
 
-                            <el-select v-model="offlineTakeSelected" filterable style="width: 240px;" placeholder="请选择守护人">
-                                <el-option v-for="(user, index) in userList" :key="index" :label="user.name" :value="{value: user.tel, ...user}" />
+                            <el-select
+                                v-model="offlineTakeSelected"
+                                filterable
+                                style="width: 240px"
+                                placeholder="请选择守护人"
+                            >
+                                <el-option
+                                    v-for="(user, index) in userList"
+                                    :key="index"
+                                    :label="user.name"
+                                    :value="{ value: user.tel, ...user }"
+                                />
                             </el-select>
                         </div>
-                        <div class="center-item p-t-2 progress-wrap" v-show="item.status === 1 && !isManySetting && !item.settingPrice">
+                        <div
+                            class="center-item p-t-2 progress-wrap"
+                            v-show="item.status === 1 && !isManySetting && !item.settingPrice"
+                        >
                             守护人:
                             <span class="unit">
                                 <div class="user-item">
                                     <div class="user-detail" v-for="(owner, oI) in owners" :key="oI">
                                         {{ owner.userName }}
-                                        <span v-show="oI<owners.length-1">/</span>
+                                        <span v-show="oI < owners.length - 1">/</span>
                                     </div>
                                 </div>
                             </span>
                         </div>
                     </div>
-                    <div v-show="!isManySetting && !item.settingPrice && ROLE == 1" @click="toSettingSinglePrice(index, true)">
+                    <div
+                        v-show="!isManySetting && !item.settingPrice && ROLE == 1"
+                        @click="toSettingSinglePrice(index, true)"
+                    >
                         <img src="@/assets/images/common/edit-icon.png" alt="" />
                     </div>
                 </div>
@@ -157,7 +221,15 @@
                 </div>
             </div>
             <div class="pagination-wrap">
-                <el-pagination background :page-size="20" :pagerCount="5" v-model:current-page="currentPage" @current-change="getSamplePage" layout="prev, pager, next" :total="totalVal" />
+                <el-pagination
+                    background
+                    :page-size="20"
+                    :pagerCount="5"
+                    v-model:current-page="currentPage"
+                    @current-change="getSamplePage"
+                    layout="prev, pager, next"
+                    :total="totalVal"
+                />
             </div>
         </div>
 
@@ -218,33 +290,34 @@ const statusOptions = ref([
 
 const adoptList = ref([]);
 
-const owners = ref([{userName: "王丽丽", value: 50}])
+const owners = ref([{ userName: "王丽丽", value: 50 }]);
 
-
-const offlineTakeSelected = ref(null)
-const userList = ref([])
-const speciesList = ref([])
+const offlineTakeSelected = ref(null);
+const userList = ref([]);
+const speciesList = ref([]);
 function getUserList() {
-    VE_API.manage_interface.offlineTakeList({farmId: 766}).then(({data}) => {
-        userList.value = data
-    })
-    VE_API.manage_interface.speciesList({farmId: 766}).then(({data}) => {
-        speciesList.value = data
-    })
+    VE_API.manage_interface.offlineTakeList({ farmId: 80865 }).then(({ data }) => {
+        userList.value = data;
+    });
+    VE_API.manage_interface.speciesList({ farmId: 80865 }).then(({ data }) => {
+        speciesList.value = data;
+    });
 }
 onMounted(() => {
-    getSamplePage()
-    getUserList()
+    getSamplePage();
+    getUserList();
 });
 
-const currentPage = ref(1)
-const totalVal = ref(0)
+const currentPage = ref(1);
+const totalVal = ref(0);
 
 function getSamplePage() {
-    VE_API.manage_interface.fetchSamplePage({farmId: 80865, page: currentPage.value, limit: 20}).then(({data, count}) => {
-        adoptList.value = data
-        totalVal.value = count
-    })
+    VE_API.manage_interface
+        .fetchSamplePage({ farmId: 80865, page: currentPage.value, limit: 20 })
+        .then(({ data, count }) => {
+            adoptList.value = data;
+            totalVal.value = count;
+        });
 }
 
 // 批量设置
@@ -253,11 +326,11 @@ const batchPrice = ref(null);
 const batchTotal = ref(null);
 const isManySetting = ref(false);
 const settingTypeOptions = [
-    {name: "树龄", value: "age"},
-    {name: "品种", value: "price"},
-    {name: "栽种时间", value: "total"},
-]
-const settingType = ref("age")
+    { name: "树龄", value: "age" },
+    { name: "品种", value: "price" },
+    { name: "栽种时间", value: "total" },
+];
+const settingType = ref("age");
 function manySetPrice() {
     isManySetting.value = true;
 }
@@ -269,34 +342,34 @@ function saveManySetting(isToSave) {
 }
 
 function setManyPrice(v) {
-//   adoptList.value.map(item => item.price = v)
+    //   adoptList.value.map(item => item.price = v)
 }
 
 // 设置单棵树单价
 
 function toSettingSinglePrice(i, val, toSave = false) {
-  console.log('tototot');
-  const data = adoptList.value[i]
-  if (toSave) {
-    const params = {
-        sampleId: data.sampleId,
-        pz: data.pz,
-        age: data.age,
-        plantDate: data.plantDate,
-        offlineTakeSelected: {...offlineTakeSelected.value}
+    console.log("tototot");
+    const data = adoptList.value[i];
+    if (toSave) {
+        const params = {
+            sampleId: data.sampleId,
+            pz: data.pz,
+            age: data.age,
+            plantDate: data.plantDate,
+            offlineTakeSelected: { ...offlineTakeSelected.value },
+        };
+        VE_API.manage_interface.editFosterSample(params).then((res) => {
+            if (res.code === 0) {
+                ElMessage.success("修改成功");
+                adoptList.value[i].settingPrice = val;
+            }
+        });
+    } else {
+        adoptList.value[i].settingPrice = val;
     }
-    VE_API.manage_interface.editFosterSample(params).then((res) => {
-        if (res.code === 0) {
-            ElMessage.success("修改成功")
-            adoptList.value[i].settingPrice = val
-        }
-    })
-  } else {
-    adoptList.value[i].settingPrice = val
-  }
 }
 function settingSinglePrice() {
-  console.log('sss');
+    console.log("sss");
 }
 </script>
 
@@ -361,6 +434,7 @@ function settingSinglePrice() {
             }
         }
     }
+
     .list-wrap {
         padding: 12px 0;
         margin-bottom: 60px;
@@ -442,9 +516,9 @@ function settingSinglePrice() {
                 }
 
                 .user-wrap {
-                    color: #F0AC37;
+                    color: #f0ac37;
                 }
-                
+
                 .progress-wrap {
                     display: flex;
                     align-items: center;
@@ -456,7 +530,7 @@ function settingSinglePrice() {
                         font-size: 12px;
                         color: #999999;
                         .over {
-                            color: #FFD489;
+                            color: #ffd489;
                         }
                     }
                     ::v-deep {
@@ -494,14 +568,33 @@ function settingSinglePrice() {
                     }
                 }
                 .small-btn-group {
-                  display: flex;
-                  font-size: 12px;
+                    display: flex;
+                    font-size: 12px;
                 }
             }
         }
         .list-item + .list-item {
             margin-top: 8px;
         }
+        .blue-select {
+            ::v-deep {
+                .el-select__wrapper {
+                    background: rgba(33, 153, 248, 0.08);
+                    box-shadow: 0 0 0 1px #2199f8 inset;
+                    font-size: 13px;
+                    .el-select__input {
+                        color: #2199f8;
+                    }
+                    .el-select__placeholder {
+                        color: #2199f8;
+                        text-align: center;
+                    }
+                    .el-select__caret {
+                        color: #2199f8;
+                    }
+                }
+            }
+        }
     }
     .unit {
         padding-left: 5px;
@@ -509,12 +602,12 @@ function settingSinglePrice() {
     }
     .many-setting {
         background: rgba(33, 153, 248, 0.1);
-        border: 1px solid #2199F8;
+        border: 1px solid #2199f8;
         border-radius: 5px;
-        color: #2199F8;
+        color: #2199f8;
         padding: 12px 8px;
         margin: 12px 8px 0 12px;
-        color: #0064B3;
+        color: #0064b3;
         ::v-deep {
             .many-select {
                 margin-right: 10px;
@@ -523,17 +616,19 @@ function settingSinglePrice() {
                     box-shadow: none;
                     background: none;
                 }
-                .el-select__placeholder, .el-select__caret {
-                    color: #0064B3;
+                .el-select__placeholder,
+                .el-select__caret {
+                    color: #0064b3;
                 }
             }
             .number-input-setting {
                 .el-input__wrapper {
-                    box-shadow: 0 0 0 1px #2199F8 inset;
+                    box-shadow: 0 0 0 1px #2199f8 inset;
                     border-radius: 6px;
                 }
-                .el-input__inner, .el-input__inner::placeholder {
-                    color: #2199F8;
+                .el-input__inner,
+                .el-input__inner::placeholder {
+                    color: #2199f8;
                     text-align: center;
                 }
             }
@@ -545,10 +640,11 @@ function settingSinglePrice() {
     .number-input {
         // margin: 0 12px;
         ::v-deep {
-            &.el-input-number, &.el-input {
+            &.el-input-number,
+            &.el-input {
                 width: 90px;
                 background: rgba(33, 153, 248, 0.08);
-                border: 1px solid #2199F8;
+                border: 1px solid #2199f8;
                 border-radius: 5px;
             }
             .el-input__wrapper {
@@ -558,8 +654,9 @@ function settingSinglePrice() {
             .el-input-number.is-without-controls .el-input__wrapper {
                 padding: 0 8px;
             }
-            .el-input__inner, .el-input__inner::placeholder {
-                color: #2199F8;
+            .el-input__inner,
+            .el-input__inner::placeholder {
+                color: #2199f8;
                 text-align: center;
             }
         }
@@ -569,13 +666,14 @@ function settingSinglePrice() {
             .el-date-editor {
                 .el-input__wrapper {
                     background: rgba(33, 153, 248, 0.08);
-                    box-shadow: 0 0 0 1px #2199F8 inset;
+                    box-shadow: 0 0 0 1px #2199f8 inset;
                 }
-                .el-input__inner, .el-input__inner::placeholder {
-                    color: #2199F8;
+                .el-input__inner,
+                .el-input__inner::placeholder {
+                    color: #2199f8;
                 }
                 .el-input__prefix {
-                    color: #2199F8;
+                    color: #2199f8;
                 }
             }
         }
@@ -588,13 +686,13 @@ function settingSinglePrice() {
         bottom: 64px;
         left: 50%;
         transform: translateX(-50%);
-        color: #FFFFFF;
+        color: #ffffff;
         border-radius: 20px;
         font-size: 14px;
         padding: 7px 10px;
         cursor: pointer;
         border: 1px solid #fff;
-        background: linear-gradient(180deg, #84C9FF, #2199F8);
+        background: linear-gradient(180deg, #84c9ff, #2199f8);
         width: 194px;
         box-sizing: border-box;
         text-align: center;
@@ -618,15 +716,15 @@ function settingSinglePrice() {
             padding: 12px 36px;
             font-size: 14px;
             border-radius: 4px;
-            border: 1px solid #2199F8;
-            color: #2199F8;
+            border: 1px solid #2199f8;
+            color: #2199f8;
         }
         .cancel-btn {
-            color: #2199F8;
+            color: #2199f8;
         }
         .edit-btn {
-            background: #2199F8;
-            color: #FFFFFF;
+            background: #2199f8;
+            color: #ffffff;
         }
         .btn + .btn {
             margin-left: 12px;

+ 273 - 153
src/views/home/components/applyList.vue

@@ -1,131 +1,143 @@
 <template>
     <div class="apply-list">
         <div class="list-wrap">
-            <div class="list-item" v-for="(item, index) in 10" :key="index">
-              <div class="item-info">
-                <div class="tree-icon">
-                    <img class="tree-img" src="@/assets/images/foster-home/tree-item.png" alt="" />
-                    <div class="tree-type-name-tag">白糖罂</div>
-                </div>
-                <div class="item-center">
-                    <div class="center-t">
-                        BTY-A25
-                        <span class="type-tag">综合:94分</span>
-                        <span class="type-tag">生态:92分</span>
-                    </div>
-
-                    <div class="center-item p-t-2 age-line">
-                        <div class="age-wrap">
-                            <div class="has-age">
-                                <div class="age">树龄:<span class="unit">5年</span></div>
+            <div class="list-item" v-for="(item, index) in defalutList" :key="index">
+                <div class="item-box">
+                    <div class="item-flex">
+                        <img class="photo" :src="item.icon || 'https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png'" alt="" />
+                        <div class="item-text">
+                            <div class="name-info">
+                                <span class="item-title">守护人:</span>
+                                <span>{{ item.name }}</span>
+                                <el-icon class="edit-icon" @click.stop="handlePerson('edit', item)" color="#2199F8" size="16"
+                                    ><Edit
+                                /></el-icon>
+                            </div>
+                            <div class="p-4"><span class="item-title">电话:</span>{{ item.tel }}</div>
+                            <div>
+                                <span class="item-title">地址:</span>{{ item.address || "--" }}
                             </div>
-                            <div class="sort-line"></div>
                         </div>
-                        单价:<span class="unit">{{item.status === 0 ? "--" : item.price||12}}元/斤</span>
                     </div>
-
-                    <div class="center-item">截至分配时间:<span>2025.05.15</span></div>
-                </div>
-              </div>
-
-              <div class="apply-wrap" v-show="ROLE == 1">
-                <div class="apply-item" v-for="(item, index) in 2" :key="index">
-                    <div class="apply-users">
-                        <div class="user-item">
-                            <el-avatar :size="32" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                            <div class="user-name">华国伟</div>
-                        </div>
-                        <div class="user-item">
-                            <el-avatar :size="32" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                            <div class="user-name">华国伟</div>
-                        </div>
-                        <div class="user-item">
-                            <el-avatar :size="32" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                            <div class="user-name">华国伟</div>
+                    <div class="tree-info">
+                        <div class="info-header">
+                            <div class="header-l">
+                                <img class="tree-icon" src="@/assets/images/user/tree.png" alt="" />
+                                守护详情
+                            </div>
+                            <div class="header-r">
+                                <div class="header-btn red" @click="warningMessage(item)">取消守护权限</div>
+                                <!-- <div class="header-btn" @click="toCustomOneTree(item)">更换守护树</div> -->
+                            </div>
                         </div>
-                    </div>
-                    <div class="apply-time">2025.03.29</div>
-                    <div class="apply-btn">
-                        确认分配
-                    </div>
-                </div>
-              </div>
-
-              <!-- 团长 -->
-              <div class="team-wrap" v-show="ROLE == 2">
-                <div class="team-box">
-                    <div class="team-apply">
-                        <div class="apply-total">已分配给15人</div>
-                        <div class="apply-tooltip">
-                            <el-tooltip
-                                class="box-item"
-                                effect="dark"
-                                content="Top Center prompts info"
-                                placement="top"
-                            >
-                            <template #content>
-                                <div class="user-wrap">
-                                    <div class="user-detail" v-for="(owner, oI) in owners" :key="oI">
-                                        {{ owner.userName }}
-                                        <span v-show="oI<owners.length-1">/</span>
-                                    </div>
+                        <div class="info-content">
+                            <div class="tree-icon">
+                                <img
+                                    class="tree-img"
+                                    :src="item.icon || require(`@/assets/images/foster-home/list/1.png`)"
+                                    alt=""
+                                />
+                                <!-- <div class="tree-type-name-tag">{{ item.pz }}</div> -->
+                                <div class="tree-type-name-tag">白糖罂</div>
+                            </div>
+                            <div class="center-item p-t-2 age-line">
+                                <div class="tree-name">
+                                    <span>BTY-A305245</span>
                                 </div>
-                            </template>
-                            <div class="tooltip-user-item">
-                                <div class="user-detail" v-for="(owner, oI) in owners" :key="oI">
-                                    {{ owner.userName }}
-                                    <span v-show="oI<owners.length-1">/</span>
+                                <div class="tree-one">
+                                    <div class="age-wrap">
+                                        <div class="has-age">
+                                            <div class="age">
+                                                栽种时间:<span class="unit">2025-06-15</span>
+                                            </div>
+                                        </div>
+                                        <div class="sort-line"></div>
+                                    </div>
+                                    树龄:<span class="unit"
+                                        ><span class="unit">5年</span></span
+                                    >
                                 </div>
+                                
+                                <div class="tree-btn" @click="showTreeDialog(item)">点击查看详情</div>
                             </div>
-                            </el-tooltip>
                         </div>
                     </div>
-                    
-                    <div class="progress-wrap" v-show="ROLE==2 && item.status !== 2">
-                        剩余可购:
-                        <el-progress :percentage="60" color="#FFD887"><span class="progress-text"><span class="over">150</span>/215斤</span></el-progress>
-                    </div>
                 </div>
-
-                <div class="team-users apply-wrap">
-                    <div class="apply-item" v-for="(item, index) in 2" :key="index">
-                    <div class="apply-users">
-                        <div class="user-item">
-                            <el-avatar :size="32" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
-                        </div>
-                        <div class="team-info">
-                            <div class="team-name">华国伟</div>
-                            <div class="team-time">3/25<span>10:08:32</span></div>
-                        </div>
-                    </div>
-                    <div class="apply-time">购买<span class="main-unit">15斤</span></div>
-                    <div class="apply-btn">
-                        确认分配
-                    </div>
-                </div>
-                </div>
-              </div>
             </div>
         </div>
     </div>
+    <!-- 新增客户、编辑客户 -->
+    <edit-client-popup ref="editClientRef"></edit-client-popup>
 </template>
 
 <script setup>
 import { onMounted, ref } from "vue";
-import { useStore } from "vuex";
-let store = useStore();
+import editClientPopup from "@/components/editClientPopup.vue";
+import eventBus from "@/api/eventBus";
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { useRouter } from "vue-router";
+const router = useRouter();
+
+const editClientRef = ref(null);
+const handlePerson = (type, data) => {
+    editClientRef.value.openClientPopup(type, data);
+};
 
-const owners = ref([{userName: "王丽丽", value: 50}, {userName: "张山", value: 30}, {userName: "刘珊珊", value: 30}, {userName: "张山2", value: 30}, {userName: "刘珊珊2", value: 30}])
+const defalutList = ref([]);
 
-const ROLE = store.state.home.userRole;
+onMounted(() => {
+    getUserList();
+});
+
+function getUserList() {
+    VE_API.manage_interface.offlineTakeList({ farmId: 766 }).then(({ data }) => {
+        defalutList.value = data;
+    });
+}
+
+function showTreeDialog(item) {
+    eventBus.emit("click:point", { 
+        farmId: 766, 
+        sampleId: 110851, 
+        data: {
+            "nodeType": "tree",
+            "age": 20,
+            "fosterCode": "LCNMC-GZCH_LBY0801",
+            "isRenyang": 1,
+            "pz": "糯米糍",
+            "sampleId": 110851,
+            "currentTree": true
+        }
+    });
+}
+
+// 取消守护权限
+function warningMessage(item) {
+    ElMessageBox.confirm(`确认取消 ${item.name} 的守护权限吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+    }).then(() => {
+        // 这里可以添加取消守护的逻辑
+        ElMessage({
+            type: 'success',
+            message: `已取消 ${item.name} 的守护权限`,
+        });
+    }).catch(() => {});
+}
+
+
+function toCustomOneTree(data) {
+    router.push(`/layout/customTree?type=single&data=${JSON.stringify(data)}`);
+}
 
-onMounted(() => {console.log('ROLE', ROLE);});
 </script>
 
 <style lang="scss" scoped>
 .apply-list {
     height: 100%;
     overflow: auto;
+    color: #000000;
 
     .type-tag {
         color: #ffd489;
@@ -137,65 +149,175 @@ onMounted(() => {console.log('ROLE', ROLE);});
     }
     .list-wrap {
         .list-item {
-            background: rgba(255, 255, 255, 0.08);
-            padding: 8px 10px;
-            border-radius: 5px;
-            .item-info {
-              display: flex;
-              justify-content: space-between;
-              align-items: center;
+            padding: 0 10px;
+            font-size: 14px;
+            &.active {
+                .item-box {
+                    background: rgba(33, 153, 248, 0.1);
+                    border-color: #2199F8;
+                }
+                .tree-info {
+                    border-color: #2199F8;
+                    background: #fff;
+                }
+            }
+            .item-box {
+                border: 1px solid #c7c7c7;
+                border-radius: 10px;
+                padding: 10px;
             }
-            .tree-icon {
-                position: relative;
-                .tree-type-name-tag {
-                    position: absolute;
-                    left: 0;
-                    bottom: 0;
-                    background: rgba(0, 0, 0, 0.6);
-                    border-radius: 0 5px 5px 0;
-                    font-size: 10px;
-                    width: 100%;
-                    text-align: center;
-                    padding: 1px;
-                    backdrop-filter: blur(2px);
+
+            .item-flex {
+                display: flex;
+                align-items: center;
+                width: 100%;
+                .blue-btn {
+                    cursor: pointer;
+                    color: #ffffff;
+                    font-size: 12px;
+                    padding: 5px 15px;
+                    border-radius: 20px;
+                    background: #2199f8;
                 }
-                .tree-img {
+
+                .photo {
                     width: 63px;
                     height: 63px;
                     border-radius: 5px;
-                    object-fit: cover;
+                    margin-right: 12px;
                 }
-            }
-            .item-center {
-                flex: 1;
-                padding: 0 12px;
-                color: #fff;
-                .center-t {
-                    font-size: 14px;
+                .p-4 {
+                    padding: 4px 0;
                 }
-                .center-item {
-                    color: #6c6c6c;
+                .item-text {
                     font-size: 12px;
-                    padding-top: 2px;
-                    span {
-                        color: #fff;
+                }
+                .name-info {
+                    display: flex;
+                    align-items: center;
+                    font-size: 14px;
+                    .edit-icon {
+                        padding-left: 8px;
                     }
                 }
-                
-                .age-line {
+            }
+
+            .item-title {
+                color: #666666;
+            }
+            .tree-info {
+                margin-top: 10px;
+                background: #f6f6f6;
+                border-radius: 8px;
+                padding: 8px;
+                border: 1px solid #F6F6F6;
+                .info-header {
                     display: flex;
                     align-items: center;
-                    .age-wrap {
+                    justify-content: space-between;
+                    padding-bottom: 5px;
+                    .header-l {
                         display: flex;
                         align-items: center;
-                        .sort-line {
-                            margin: 0 10px;
-                            height: 10px;
-                            width: 1px;
-                            background: #6C6C6C;
+                        color: #000000;
+                        font-size: 14px;
+                        font-family: "PangMenZhengDao";
+                        .tree-icon {
+                            width: 10px;
+                            margin-right: 5px;
+                        }
+                    }
+                    .header-r {
+                        display: flex;
+                        font-size: 10px;
+                        .header-btn {
+                            padding: 5px 10px;
+                            border-radius: 20px;
+                            cursor: pointer;
+                            background: rgba(33, 153, 248, 0.12);
+                            color: #2199F8;
+                            &.red {
+                                color: #F04337;
+                                background-color: rgba(240, 67, 55, 0.1);
+                            }
+                        }
+                        .header-btn + .header-btn {
+                            margin-left: 10px;
                         }
                     }
                 }
+                .info-content {
+                    display: flex;
+                    align-items: center;
+
+                    .tree-icon {
+                        align-self: baseline;
+                        position: relative;
+                        .tree-type-name-tag {
+                            position: absolute;
+                            left: 0;
+                            bottom: 0;
+                            background: rgba(0, 0, 0, 0.6);
+                            border-radius: 0 0 5px 5px;
+                            font-size: 10px;
+                            width: 100%;
+                            text-align: center;
+                            height: 18px;
+                            line-height: 18px;
+                            backdrop-filter: blur(4px);
+                            color: #fff;
+                        }
+                        .tree-img {
+                            width: 63px;
+                            height: 63px;
+                            border-radius: 5px;
+                            object-fit: cover;
+                        }
+                    }
+
+                    .center-item {
+                        color: #6c6c6c;
+                        font-size: 12px;
+                        padding-top: 2px;
+                    }
+
+                    .age-line {
+                        padding-left: 12px;
+                        .tree-one {
+                            padding-top: 4px;
+                            display: flex;
+                            align-items: center;
+                        }
+                        .age-wrap {
+                            display: flex;
+                            align-items: center;
+                            .sort-line {
+                                margin: 0 10px;
+                                height: 10px;
+                                width: 1px;
+                                background: rgba(0, 0, 0, 0.66);
+                            }
+                        }
+                    }
+
+                    .tree-name {
+                        display: flex;
+                        align-items: center;
+                        font-size: 14px;
+                        color: #000000;
+                        .edit-icon {
+                            padding-left: 8px;
+                            cursor: pointer;
+                        }
+                    }
+
+                    .tree-btn {
+                        color: #2199F8;
+                        font-size: 14px;
+                        text-decoration: underline;
+                        cursor: pointer;
+                    }
+                }
             }
         }
         .list-item + .list-item {
@@ -204,7 +326,7 @@ onMounted(() => {console.log('ROLE', ROLE);});
     }
     .unit {
         padding-left: 5px;
-        color: #fff;
+        color: #000000;
     }
 
     .apply-wrap {
@@ -232,19 +354,19 @@ onMounted(() => {console.log('ROLE', ROLE);});
                 font-size: 14px;
                 color: #999999;
                 .main-unit {
-                    color: #FFD489;
+                    color: #ffd489;
                 }
             }
             .apply-btn {
                 padding: 4px 7px;
-                border: 1px solid #FFD489;
+                border: 1px solid #ffd489;
                 border-radius: 20px;
-                color: #FFD489;
+                color: #ffd489;
                 font-size: 12px;
                 cursor: pointer;
             }
         }
-        
+
         .apply-item + .apply-item {
             margin-top: 8px;
         }
@@ -289,18 +411,18 @@ onMounted(() => {console.log('ROLE', ROLE);});
             display: flex;
             align-items: center;
             .apply-total {
-                color: #F2D677;
+                color: #f2d677;
                 font-size: 14px;
                 padding-right: 10px;
             }
             .apply-tooltip {
                 padding: 0px 10px;
                 border-radius: 20px;
-                background: #3B3B3B;
+                background: #3b3b3b;
                 .tooltip-user-item {
                     display: inline-block;
                     font-size: 12px;
-                    color: #F2D677;
+                    color: #f2d677;
                     max-width: 182px;
                     white-space: nowrap;
                     overflow: hidden;
@@ -313,8 +435,7 @@ onMounted(() => {console.log('ROLE', ROLE);});
                 }
             }
         }
-        
-                
+
         .progress-wrap {
             padding-top: 8px;
             display: flex;
@@ -328,7 +449,7 @@ onMounted(() => {console.log('ROLE', ROLE);});
                 font-size: 12px;
                 color: #999999;
                 .over {
-                    color: #FFD489;
+                    color: #ffd489;
                 }
             }
             ::v-deep {
@@ -341,7 +462,6 @@ onMounted(() => {console.log('ROLE', ROLE);});
     }
 }
 
-                    
 .user-wrap {
     display: flex;
 }

+ 16 - 152
src/views/home/components/clientList.vue

@@ -3,17 +3,17 @@
         <div class="list-content">
             <div class="list-item" v-for="(ele, idx) in defalutList" :key="idx">
                 <div class="item-flex">
-                    <img class="photo" src="@/assets/images/foster-home/image.png" alt="" />
+                    <img class="photo" :src="ele.icon || 'https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png'" alt="" />
                     <div class="item-text">
                         <div class="name">
                             <span>{{ ele.name }}</span>
-                            <el-icon class="icon" @click.stop="handlePerson('edit')" color="#2199F8" size="16"
+                            <el-icon class="icon" @click.stop="handlePerson('edit', ele)" color="#2199F8" size="16"
                                 ><Edit/></el-icon>
                         </div>
                         <div><span class="item-title">电话:</span>{{ ele.tel }}</div>
-                        <div><span class="item-title">地址:</span>{{ ele.address || "湖北省武汉市富里唱鑫园5023" }}</div>
+                        <div><span class="item-title">地址:</span>{{ ele.address || "--" }}</div>
                     </div>
-                    <div class="blue-btn">去分配</div>
+                    <div class="blue-btn" @click="toCustomOneTree(ele)">去分配</div>
                 </div>
             </div>
         </div>
@@ -22,114 +22,34 @@
         <div class="center-btn" @click="toCustomPage">一键分配</div>
     </div>
     <!-- 新增客户、编辑客户 -->
-    <popup v-model:show="showClient" closeable round class="popup-custom">
-        <div class="popup-title">{{ typePopup === "add" ? "新增客户" : "编辑客户" }}</div>
-        <div class="popup-content">
-            <el-form
-                ref="ruleFormRef"
-                :model="ruleForm"
-                :rules="rules"
-                label-width="auto"
-                class="rule-form"
-                size="large"
-            >
-                <el-form-item label="姓名" prop="name">
-                    <el-input class="input" v-model="ruleForm.name" size="large" placeholder="请输入姓名" />
-                </el-form-item>
-                <el-form-item label="电话" prop="tel">
-                    <el-input class="input" v-model="ruleForm.tel" size="large" placeholder="请输入电话号码" />
-                </el-form-item>
-                <el-form-item label="地址" prop="adress">
-                    <el-input class="input" v-model="ruleForm.adress" size="large" placeholder="请输入地址" />
-                </el-form-item>
-                <el-form-item label="头像" prop="photo">
-                    <!-- <upload></upload> -->
-                </el-form-item>
-            </el-form>
-        </div>
-        <div class="popup-footer">
-            <div class="cancel" @click="resetForm">取消</div>
-            <div @click="submitForm">添加</div>
-        </div>
-    </popup>
+    <edit-client-popup ref="editClientRef"></edit-client-popup>
 </template>
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
-import { Collapse, CollapseItem, Checkbox, Popup, showConfirmDialog } from "vant";
-import { useRouter } from "vue-router";
-import { ElMessage } from "element-plus";
+import { Collapse, CollapseItem, Checkbox, Popup } from "vant";
 import { deepClone } from "@/common/commonFun";
-import upload from "@/components/common/upload.vue";
+import EditClientPopup from "@/components/editClientPopup.vue";
+import { useRouter } from "vue-router";
 const router = useRouter();
 
 // const curIndex = ref(0)
-//新增客户
-const typePopup = ref("");
-const handlePerson = (type) => {
-    typePopup.value = type;
-    showClient.value = true;
+const handlePerson = (type, data) => {
+    editClientRef.value.openClientPopup(type, data)
 };
 
+const editClientRef = ref(null);
 
-const showClient = ref(false);
-const ruleForm = reactive({
-    name: "",
-    tel: "",
-    adress: "",
-});
-const rules = reactive({
-    name: { required: true, message: "请输入用户名称", trigger: ["blur", "change"] },
-    tel: { required: true, message: "请输入电话号码", trigger: ["blur", "change"] },
-});
-
-const ruleFormRef = ref(null);
-const submitForm = async () => {
-    if (!ruleFormRef.value) return;
-    await ruleFormRef.value.validate((valid, fields) => {
-        if (valid) {
-            ElMessage.success("添加成功");
-            showClient.value = false;
-        } else {
-            console.log("error submit!");
-        }
-    });
-};
-
-const resetForm = () => {
-    if (!ruleFormRef.value) return;
-    ruleFormRef.value.resetFields();
-    showClient.value = false;
-};
-
-const defalutList = ref([
-    {
-        id: "3",
-        name: "周浩",
-        checked: false,
-    },
-    {
-        id: "4",
-        name: "王丽丽",
-        checked: false,
-    },
-
-    {
-        id: "5",
-        name: "李莉",
-        checked: false,
-    },
-    {
-        id: "6",
-        name: "陈林",
-        checked: false,
-    },
-]);
+const defalutList = ref([]);
 
 function toCustomPage() {
     router.push("/layout/customTree");
 }
 
+function toCustomOneTree(data) {
+    router.push("/layout/customTree?type=single&data=" + JSON.stringify(data));
+}
+
 onMounted(() => {
     getUserList()
 })
@@ -394,60 +314,4 @@ function getUserList() {
         }
     }
 }
-.popup-custom {
-    // width: 24%;
-    width: 504px;
-    padding: 31px 25px;
-    box-sizing: border-box;
-    background: #232323;
-    ::v-deep {
-        .van-popup__close-icon {
-            color: #ffffff;
-        }
-    }
-    .popup-title {
-        text-align: center;
-        color: #ffffff;
-        font-size: 24px;
-        margin-bottom: 15px;
-    }
-    .popup-content {
-        width: 100%;
-        ::v-deep {
-            .el-form-item__label {
-                color: rgba(255, 255, 255, 0.4);
-            }
-            .el-input__wrapper {
-                background: transparent;
-                box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.46) inset;
-            }
-        }
-        .input {
-            height: 46px;
-            font-size: 16px;
-        }
-    }
-    .popup-footer {
-        width: 100%;
-        display: flex;
-        border-top: 1px solid rgba(0, 0, 0, 0.1);
-        margin-top: 30px;
-        padding-top: 25px;
-        div {
-            flex: 1;
-            background: linear-gradient(120deg, #ffd887, #ed9e1e);
-            border-radius: 6px;
-            padding: 13px;
-            font-size: 20px;
-            color: #fff;
-            text-align: center;
-            cursor: pointer;
-        }
-        .cancel {
-            color: #000;
-            background: #f3f3f3;
-            margin-right: 30px;
-        }
-    }
-}
 </style>

+ 7 - 64
src/views/home/components/leftTabs/imgManage.vue

@@ -15,7 +15,7 @@
                 <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
         </div>
-        <div class="fly-box">
+        <!-- <div class="fly-box">
             <img class="icon" src="@/assets/images/home/fly-icon.png" alt="" />
             <div class="fly-r">
                 <div class="text">
@@ -24,7 +24,7 @@
                 </div>
                 <div class="btn">立即巡飞</div>
             </div>
-        </div>
+        </div> -->
         <div class="photo-list">
             <div class="photo-item" v-for="(item, index) in imageList" :key="index">
                 <album-carousel-item
@@ -83,66 +83,9 @@ const options = [
 
 const imageList = ref([]);
 const geImgaeList = () => {
-    // VE_API.image.imageList({ date: dateTime.value }).then((res) => {
-    let imgsArr = [];
-    const obj = [
-        {
-            address: "",
-            angle: "",
-            baseMap: "",
-            bigPeriodId: null,
-            bigPeriodName: "",
-            blueZoneId: null,
-            detail1: null,
-            detail2: null,
-            district: '"广州市增城区"',
-            gardenId: null,
-            gardenImgCount: null,
-            gardenImgIndex: null,
-            gardenName: "农场2",
-            growText: '当前属于<span style="color: #f8c404">小果</span>,未检测到生长异常<br/>未发现病虫害',
-            id: "710541621225066496",
-            imageCode: null,
-            localPath: "",
-            localResPath: "",
-            location: "POINT (113.740975 23.468493)",
-            markText: "",
-            miniUserId: null,
-            miniUserName: "",
-            modelId: null,
-            pingzhong: "",
-            planId: null,
-            regionId: null,
-            regionImgCount: null,
-            regionImgIndex: null,
-            regionName: "",
-            resFilename: "",
-            shotCode: "",
-            smallPeriodId: null,
-            smallPeriodName: "",
-            source: "app",
-            sourceCode: "",
-            speciesId2: "02-02",
-            status: null,
-            sysId: null,
-            treeGeoHash: "ws0vs0rdjkcd",
-            treeId: 164701,
-            uploadDate: "2025-05-14",
-            watermarks: [],
-            weather: null,
-            workspaceId: "",
-            code: formatDatePart("2505111813_T_WSPM_110.802_21.473"),
-            treeCode: "2505111813_T_WSPM_110.802_21.473",
-            sampleId: "873",
-            filename: "shuichan/DJI_20250511181340_0001_T_code-w7yf1kgwzqhb.JPG",
-            url: "https://birdseye-img.sysuimars.com/shuichan/DJI_20250514163710_0004_T_code-w7ydmzr9ctry.JPG?imageView/1/w/240/h/240",
-        },
-    ];
-    // res.data.map((item) => {
-    //     imgsArr.push({ ...obj, uploadDate: formatDatePart(item.code), treeCode: item.code, filename: item.url });
-    // });
-    imageList.value = obj;
-    // });
+    VE_API.manage_interface.fetchGardenImgs({ organId: 766, areaId: 2, limit: 10, page: 10 }).then((res) => {
+        imageList.value = res.data;
+    });
 };
 
 onMounted(() => {
@@ -240,7 +183,7 @@ function formatDatePart(originalStr) {
         flex-wrap: wrap;
         overflow: auto;
         width: 100%;
-        height: calc(100% - 100px);
+        height: calc(100% - 60px);
         .photo-item {
             width: calc(50% - 5px);
             .img {
@@ -258,7 +201,7 @@ function formatDatePart(originalStr) {
                 }
             }
         }
-        .photo-item:nth-last-child(2n) {
+        .photo-item:nth-last-child(2n+1) {
             margin-left: 10px;
             margin-bottom: 10px;
         }

+ 20 - 8
src/views/user/index.vue

@@ -72,18 +72,19 @@
             </div>
         </div>
         <div class="table-wrap">
-            <el-table :data="tableData" style="width: 100%" @selection-change="handleTableSelect">
+            <el-table :data="tableData" style="width: 100%" @selection-change="handleTableSelect" height="600px">
                 <el-table-column type="selection" width="55" />
-                <el-table-column property="code" label="用户编码" />
-                <el-table-column property="name" label="用户昵称">
+                <el-table-column property="code" label="用户编码" width="120" />
+                <el-table-column property="name" label="用户昵称" width="120">
                     <template #default="scope">
                         <div class="user-info">
-                            <el-avatar :size="24" src="https://birdseye-img-ali-cdn.sysuimars.com/birdseye-look-mini/91754/1750583672619.png" />
+                            <!-- <el-avatar :size="24" src="https://birdseye-img-ali-cdn.sysuimars.com/birdseye-look-mini/91754/1750583672619.png" /> -->
+                            <el-avatar :size="24" :src="scope.row.icon || 'https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png'" />
                             <span class="ml-10">{{ scope.row.name }}</span>
                         </div>
                     </template>
                 </el-table-column>
-                <el-table-column property="tel" label="联系电话" />
+                <el-table-column property="tel" label="联系电话" width="120" />
                 <el-table-column
                     property="address"
                     label="具体住址"
@@ -96,14 +97,14 @@
                         <span :class="['level-tag', 'level-'+scope.row.level]">{{ levelObj[scope.row.level] }}</span>
                     </template>
                 </el-table-column>
-                <el-table-column property="treeCode" label="守护树编号" />
+                <el-table-column property="fosterCode" label="守护树编号" />
                 <el-table-column label="状态">
                     <template #default="scope">
                         <span :class="['status-text', 'status-'+scope.row.status]">{{ statusObj[scope.row.status] }}</span>
                     </template>
                 </el-table-column>
                 <el-table-column label="日期" sortable>
-                    <template #default="scope">{{ scope.row.date }}</template>
+                    <template #default="scope">{{ scope.row.fosterDate }}</template>
                 </el-table-column>
                 <el-table-column label="操作" width="260">
                     <template #default="scope">
@@ -123,7 +124,7 @@
 </template>
 
 <script setup>
-import { ref } from 'vue';
+import { onMounted, ref } from 'vue';
 import { Search } from '@element-plus/icons-vue'
 
 const searchVal = ref(null)
@@ -226,6 +227,17 @@ const levelOptions = ref([
     {label: "青铜守护", value: "青铜守护"},
     {label: "白银守护", value: "白银守护"},
 ])
+
+onMounted(() => {
+    getTableData()
+})
+
+function getTableData() {
+    // 模拟获取数据
+    VE_API.manage_interface.fetchUserList({farmId: 766, page: 1, limit: 10}).then(({data}) => {
+        tableData.value = data;
+    });
+}
 </script>
 
 <style lang="scss" scoped>