소스 검색

feat:对接团队管理页面接口

wangsisi 7 시간 전
부모
커밋
9d7b174042

+ 30 - 0
src/api/modules/mine.js

@@ -14,4 +14,34 @@ module.exports = {
         url: config.base_dev_url + "mini_session_store/save",
         type: "post",
     },
+    //查询当前农资店的成员列表
+    listManagerList: {
+        url: config.base_dev_url + "z_agricultural_store_manager/list",
+        type: "get",
+    },
+    //获取权限列表
+    listPermissionList: {
+        url: config.base_dev_url + "z_agricultural_store_manager/permissionList",
+        type: "get",
+    },
+    //保存成员信息(新增或更新)
+    saveManager: {
+        url: config.base_dev_url + "z_agricultural_store_manager/save",
+        type: "post",
+    },
+    //获取职责列表
+    listDutyList: {
+        url: config.base_dev_url + "z_agricultural_store_manager/dutyList",
+        type: "get",
+    },
+    //删除成员
+    deleteManager: {
+        url: config.base_dev_url + "z_agricultural_store_manager/delete",
+        type: "get",
+    },
+    //批量更新成员角色
+    batchSaveManager: {
+        url: config.base_dev_url + "z_agricultural_store_manager/batchUpdateRole",
+        type: "post",
+    },
 }

+ 26 - 20
src/components/pageComponents/FarmInfoCard.vue

@@ -5,13 +5,27 @@
                 <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 }}</div>
+                        <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 || 'tag-role'" v-show="data.area || data.userType">{{ data.area || data.userType }}</span>
+                            <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 || 'tag-role'"
+                                v-show="data.area || data.userType"
+                                >{{ data.area || data.userType }}</span
+                            >
                         </div>
                     </div>
-                    <div class="farm-address van-ellipsis">{{ data.address }}</div>
+                    <div class="farm-address van-ellipsis">
+                        {{ data.address || (data.dutyList && data.dutyList?.join("、")) || '--' }}
+                    </div>
                 </div>
             </div>
             <!-- 右侧按钮插槽 -->
@@ -21,7 +35,7 @@
         </div>
         <slot name="footerData"></slot>
         <!-- 底部内容:服务次数或自定义内容 -->
-        <div v-if="showFooter" :class="{'item-footer': data.serviceCount != 0}">
+        <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
@@ -49,14 +63,7 @@ import uploadExecute from "@/views/old_mini/task_condition/components/uploadExec
 const props = defineProps({
     data: {
         type: Object,
-        required: true,
-        validator: (value) => {
-            return (
-                value.farmName !== undefined &&
-                value.address !== undefined &&
-                (value.variety !== undefined || value.roleName !== undefined)
-            );
-        },
+        default: () => ({}),
     },
 });
 
@@ -146,11 +153,11 @@ const handleRemind = () => {
                         font-size: 12px;
                         &.tag-gray {
                             background: rgba(243, 243, 243, 0.5);
-                            color: #7D7D7D;
+                            color: #7d7d7d;
                         }
                         &.tag-role {
                             background: rgba(255, 149, 61, 0.2);
-                            color: #FF953D;
+                            color: #ff953d;
                         }
                         &.tag-variety {
                             background: rgba(232, 243, 255, 1);
@@ -179,10 +186,10 @@ const handleRemind = () => {
         &.remind-footer {
             justify-content: space-between;
         }
-        .remind-cont{
+        .remind-cont {
             width: calc(100% - 42px);
-            ::v-deep{
-                p{
+            ::v-deep {
+                p {
                     margin: 0;
                 }
             }
@@ -203,7 +210,6 @@ const handleRemind = () => {
         }
     }
 
-    
     .tag-right {
         align-self: baseline;
     }
@@ -237,7 +243,7 @@ const handleRemind = () => {
 }
 </style>
 <style>
-.share-sheet{
+.share-sheet {
     bottom: 50px;
 }
 </style>

+ 22 - 22
src/views/old_mini/mine/index.vue

@@ -2,11 +2,7 @@
     <div class="mine-index">
         <div class="mine-header">
             <div class="user-info-box" @click="handleUserInfoClick">
-                <el-avatar
-                    class="avatar"
-                    :size="54"
-                    :src="userInfo?.icon"
-                />
+                <el-avatar class="avatar" :size="54" :src="userInfo?.icon" />
                 <div class="user-info">
                     <div class="user-name">
                         <span v-if="curRole === 0">{{ userInfo?.nickname }}</span>
@@ -87,7 +83,7 @@ const daysSinceCreation = computed(() => {
         // 加1,因为创建当天算作第1天
         return days + 1;
     } catch (error) {
-        console.error('计算天数失败:', error);
+        console.error("计算天数失败:", error);
         return 0;
     }
 });
@@ -105,7 +101,7 @@ const objects = [
 
 onMounted(() => {
     // 仅保留 objects 中存在的角色
-    actions.value = objects.filter(obj => roles.value && roles.value.includes(obj.id));
+    actions.value = objects.filter((obj) => roles.value && roles.value.includes(obj.id));
 });
 
 const show = ref(false);
@@ -114,18 +110,18 @@ const onSelect = async (item) => {
     show.value = false;
 
     store.dispatch(`app/${SET_USER_CUR_ROLE}`, item.id);
-    localStorage.setItem('SET_USER_CUR_ROLE',item.id)
-    
+    localStorage.setItem("SET_USER_CUR_ROLE", item.id);
+
     // 保存到 session
     try {
         await VE_API.mine.saveSessionStore({
             val: item.id,
-            key: "cur_role"
+            key: "cur_role",
         });
     } catch (error) {
-        console.error('保存角色到 session 失败:', error);
+        console.error("保存角色到 session 失败:", error);
     }
-    window.location.reload()
+    window.location.reload();
 };
 
 onActivated(() => {
@@ -206,6 +202,10 @@ const cellItems = computed(() => {
     } else {
         return [
             {
+                title: "认证农资",
+                path: "/register?identity=NZ",
+            },
+            {
                 title: "系统提醒",
                 path: "/message",
             },
@@ -235,24 +235,24 @@ const cellItems = computed(() => {
 
 // 花园信息项数据
 const gardenInfoItems = ref([
-    { num: '--', label: "服务次数" },
-    { num: '--', label: "累计客户" },
-    { num: '--', label: "服务果园" },
+    { num: "--", label: "服务次数" },
+    { num: "--", label: "累计客户" },
+    { num: "--", label: "服务果园" },
 ]);
 
 onActivated(() => {
-    if(curRole.value !== 0){
+    if (curRole.value !== 0) {
         getStatistics();
     }
-})
+});
 
 const getStatistics = () => {
     VE_API.z_agricultural_store.statistics().then(({ data }) => {
-        gardenInfoItems.value[0].num = data.serviceCount || '--';
-        gardenInfoItems.value[1].num = data.customerCount || '--';
-        gardenInfoItems.value[2].num = data.serviceFarmCount || '--';
+        gardenInfoItems.value[0].num = data.serviceCount || "--";
+        gardenInfoItems.value[1].num = data.customerCount || "--";
+        gardenInfoItems.value[2].num = data.serviceFarmCount || "--";
     });
-}
+};
 
 // 处理网格项点击
 const handleGridClick = (item) => {
@@ -282,7 +282,7 @@ const handleUserInfoClick = () => {
     wx.miniProgram.navigateTo({
         url: `/pages/subPages/user_info/index?route_path=/mine`,
     });
-}
+};
 </script>
 <style lang="scss" scoped>
 .mine-index {

+ 61 - 36
src/views/old_mini/mine/pages/projectManager.vue

@@ -2,17 +2,26 @@
     <div class="authentication-page">
         <custom-header name="项目管理员"></custom-header>
         <div class="team-content">
-            <div class="team-list">
-                <farm-info-card
-                    v-for="ele in teamList"
-                    :key="ele.receiveUserId"
-                    class="list-item"
-                    :data="ele"
-                >
-                    <template #right>
-                        <div @click.stop="handleRemoveProjectManager(ele)">移除</div>
-                    </template>
-                </farm-info-card>
+            <template v-if="teamList && teamList.length">
+                <div class="team-list">
+                    <farm-info-card
+                        v-for="ele in teamList"
+                        :key="ele.id"
+                        class="list-item"
+                        :data="{
+                            ...ele,
+                            maxWidth: 'auto',
+                            roleName: '项目管理员',
+                        }"
+                    >
+                        <template #right>
+                            <div @click.stop="handleRemoveProjectManager(ele)">移除</div>
+                        </template>
+                    </farm-info-card>
+                </div>
+            </template>
+            <div v-else class="empty-wrap">
+                <div class="empty-text">暂无数据</div>
             </div>
         </div>
         <div class="custom-bottom-fixed-btns">
@@ -24,38 +33,43 @@
 <script setup>
 import customHeader from "@/components/customHeader.vue";
 import FarmInfoCard from "@/components/pageComponents/FarmInfoCard.vue";
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import { useRouter } from "vue-router";
+import { ElMessage, ElMessageBox } from "element-plus";
 const router = useRouter();
 
-const teamList = ref([
-    {
-        farmName: "张张张",
-        roleName: "项目管理员",
-        address: "广东省广州市从化区从化荔博园",
-        receiveUserId: 1,
-    },
-    {
-        farmName: "张扬",
-        roleName: "项目管理员",
-        address: "无人机驾驶员、角色222",
-        receiveUserId: 2,
-    },
-    {
-        farmName: "张扬",
-        roleName: "项目管理员",
-        address: "无人机驾驶员、角色222",
-        receiveUserId: 3,
-    },
-]);
-
-const handleRemoveProjectManager = (item) => {
-    console.log(item);
+const handleRemoveProjectManager = async (item) => {
+    ElMessageBox.confirm('确定移除该成员吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+    }).then(async () => {
+        const { code,msg } = await VE_API.mine.saveManager({id: item.id, role: 3});
+        if (code === 0) {
+            ElMessage.success("移除成功");
+            getManagerList();
+        } else {
+            ElMessage.error(msg);
+        }
+    }).catch(() => {});
 };
 
 const handleAddProjectManager = () => {
     router.push("/team_manage?add=true");
 };
+
+onMounted(() => {
+    getManagerList();
+});
+
+const teamList = ref([]);
+const getManagerList = async () => {
+    const { data } = await VE_API.mine.listManagerList();
+    if (data && data.length > 0) {
+        const list = Array.isArray(data) ? data.filter((item) => item.role == 2) : [];
+        teamList.value = list;
+    }
+};
 </script>
 
 <style lang="scss" scoped>
@@ -68,8 +82,19 @@ const handleAddProjectManager = () => {
         height: 100%;
         padding: 10px 12px;
         box-sizing: border-box;
+        .team-list {
+            width: 100%;
+        }
+        .empty-wrap {
+            padding-top: 40px;
+            text-align: center;
+            .empty-text {
+                font-size: 14px;
+                color: #86909c;
+            }
+        }
     }
-    .custom-bottom-fixed-btns{
+    .custom-bottom-fixed-btns {
         justify-content: center;
     }
 }

+ 234 - 162
src/views/old_mini/mine/pages/teamManage.vue

@@ -2,12 +2,22 @@
     <div class="team-management-page">
         <custom-header :name="route.query.add ? '选择团队成员' : '团队管理'"></custom-header>
         <div class="team-content">
-            <div class="team-title" v-show="!route.query.add">当前团队总人数(25人)</div>
+            <div class="team-title" v-show="!route.query.add">当前团队总人数({{ teamList.length || 0 }}人)</div>
             <div class="team-list">
-                <div class="list-item" v-for="ele in teamList" :key="ele.receiveUserId">
-                    <checkbox v-if="route.query.add" @change="changeCheck" v-model="ele.checked"></checkbox>
-                    <farm-info-card class="item-info" @click="handleItem(ele)" :style="{ width: !route.query.add ? '100%' : 'calc(100% - 55px)' }" :data="ele">
-                        <template #right v-if="ele.receiveUserId != 1 && !route.query.add">
+                <div class="list-item" v-for="ele in teamList" :key="ele.id">
+                    <Checkbox v-if="route.query.add" @change="changeCheck" v-model="ele.checked"></Checkbox>
+                    <farm-info-card
+                        class="item-info"
+                        @click="handleItem(ele)"
+                        :style="{ width: !route.query.add ? '100%' : 'calc(100% - 55px)' }"
+                        :data="{
+                            ...ele,
+                            roleName: ele.role == 1 ? '超级管理员' : ele.role == 2 ? '项目管理员' : '普通成员',
+                            className: ele.role == 1 ? 'tag-role' : ele.role == 2 ? '' : 'tag-gray',
+                            maxWidth: 'auto',
+                        }"
+                    >
+                        <template #right v-if="ele.role === 2 && !route.query.add">
                             <div @click.stop="handlePermission(ele)">权限设置</div>
                         </template>
                     </farm-info-card>
@@ -24,7 +34,7 @@
         </div>
 
         <!-- 新增团队成员弹窗 -->
-        <popup
+        <Popup
             v-model:show="showAddMemberPopup"
             closeable
             round
@@ -34,23 +44,30 @@
         >
             <div class="popup-content">
                 <div class="popup-title">新增团队成员</div>
-                <el-form ref="formRef" :model="formData" label-position="top" class="member-form" size="large">
-                    <el-form-item label="姓名">
+                <el-form
+                    ref="formRef"
+                    :model="formData"
+                    :rules="rules"
+                    label-position="top"
+                    class="member-form"
+                    size="large"
+                >
+                    <el-form-item label="姓名" prop="name">
                         <el-input v-model="formData.name" placeholder="请输入姓名" clearable />
                     </el-form-item>
-                    <el-form-item label="手机号">
+                    <el-form-item label="手机号" prop="phone">
                         <el-input v-model="formData.phone" placeholder="请输入手机号" clearable maxlength="11" />
                     </el-form-item>
-                    <el-form-item label="角色类型">
+                    <el-form-item label="角色类型" prop="duties">
                         <div class="role-type-grid">
                             <div
-                                v-for="role in roleTypes"
-                                :key="role.value"
+                                v-for="role in dutyList"
+                                :key="role.code"
                                 class="role-btn"
-                                :class="{ active: formData.roleType === role.value }"
-                                @click="formData.roleType = role.value"
+                                :class="{ active: formData.duties.includes(role.code) }"
+                                @click="toggleRole(role.code)"
                             >
-                                {{ role.label }}
+                                {{ role.name }}
                             </div>
                         </div>
                     </el-form-item>
@@ -60,10 +77,10 @@
                     <div class="footer-btn confirm-btn" @click="handleConfirm">确认添加</div>
                 </div>
             </div>
-        </popup>
+        </Popup>
 
         <!-- 权限设置弹窗 -->
-        <popup
+        <Popup
             v-model:show="showPermissionPopup"
             closeable
             round
@@ -75,21 +92,21 @@
                 <div class="popup-title">权限设置</div>
                 <div class="role-type-grid permission-list">
                     <div
-                        v-for="permission in permissionTypes"
-                        :key="permission.value"
+                        v-for="permission in permissionList"
+                        :key="permission.code"
                         class="role-btn"
-                        :class="{ active: permissionData.selectedPermission === permission.value }"
-                        @click="togglePermission(permission.value)"
+                        :class="{ active: selectedPermission.includes(permission.code) }"
+                        @click="togglePermission(permission.code)"
                     >
-                        {{ permission.label }}
+                        {{ permission.name }}
                     </div>
                 </div>
                 <div class="popup-footer">
-                    <div class="footer-btn cancel-admin-btn" @click="handleCancelAdmin">取消管理</div>
+                    <div class="footer-btn cancel-admin-btn" @click="handleCancelAdmin">取消管理权限</div>
                     <div class="footer-btn confirm-btn" @click="handleConfirmPermission">确认设置</div>
                 </div>
             </div>
-        </popup>
+        </Popup>
     </div>
 </template>
 
@@ -98,144 +115,212 @@ import customHeader from "@/components/customHeader.vue";
 import { ref, reactive, onMounted } from "vue";
 import { useRouter, useRoute } from "vue-router";
 import { Popup, Checkbox } from "vant";
-import { ElMessage } from "element-plus";
+import { ElMessage,ElMessageBox } from "element-plus";
 import FarmInfoCard from "@/components/pageComponents/FarmInfoCard.vue";
 
 const router = useRouter();
 const formRef = ref(null);
 const showAddMemberPopup = ref(false);
 const showPermissionPopup = ref(false);
-const currentPermissionItem = ref(null);
 const route = useRoute();
 
 onMounted(() => {
-    if (route.query.add) {
-        teamList.value = [
-            {
-                farmName: "张张张",
-                checked: false,
-                roleName: "超级管理员",
-                className: "tag-role",
-                address: "广东省广州市从化区从化荔博园",
-                receiveUserId: 1,
-            },
-            {
-                farmName: "张扬",
-                checked: false,
-                roleName: "普通成员",
-                className: "tag-gray",
-                address: "无人机驾驶员、角色222",
-                receiveUserId: 2,
-            },
-            {
-                farmName: "张扬",
-                checked: false,
-                roleName: "普通成员",
-                className: "tag-gray",
-                address: "无人机驾驶员、角色222",
-                receiveUserId: 3,
-            },
-        ];
-    } else {
-        teamList.value = [
-            {
-                farmName: "张张张",
-                roleName: "超级管理员",
-                className: "tag-role",
-                address: "广东省广州市从化区从化荔博园",
-                receiveUserId: 1,
-            },
-            {
-                farmName: "张扬",
-                roleName: "项目管理员",
-                address: "无人机驾驶员、角色222",
-                receiveUserId: 2,
-            },
-            {
-                farmName: "张扬",
-                roleName: "普通成员",
-                className: "tag-gray",
-                address: "无人机驾驶员、角色222",
-                receiveUserId: 3,
-            },
-        ];
-    }
+    getManagerList();
+    //获取职责列表
+    getDutyList();
+    //获取权限列表
+    getPermissionList();
 });
 
-const filterList = ref([]);
-const changeCheck = () => {
-    filterList.value = teamList.value.filter((item) => item.checked);
-    console.log("filterList",filterList.value);
+//职责列表
+const dutyList = ref([]);
+//获取职责列表
+const getDutyList = async () => {
+    const { data } = await VE_API.mine.listDutyList();
+    if (data && data.length > 0) {
+        dutyList.value = data;
+        // 默认选中第一个角色
+        formData.duties = [data[0].code];
+    }
 };
 
 const teamList = ref([]);
-
-// 角色类型选项
-const roleTypes = ref([
-    { label: "无人机驾驶员", value: "pilot" },
-    { label: "项目管理员", value: "admin" },
-    { label: "普通成员", value: "member" },
-    { label: "其他", value: "other" },
-]);
-
-// 表单数据
-const formData = reactive({
-    name: "",
-    phone: "",
-    roleType: "pilot", // 默认选中无人机驾驶员
-});
-
-// 权限类型选项
-const permissionTypes = ref([
-    { label: "转入农事权限", value: "transfer" },
-    { label: "增删成员", value: "member" },
-    { label: "任务接单", value: "task" },
-    { label: "农事规划", value: "plan" },
-]);
+//查询当前农资店的成员列表
+const getManagerList = async () => {
+    const { data } = await VE_API.mine.listManagerList();
+    if (data && data.length > 0) {
+        if (route.query.add) {
+            teamList.value = data.filter((item) => item.role == 3);
+        } else {
+            teamList.value = data;
+        }
+    }
+};
 
 // 权限数据
-const permissionData = reactive({
-    selectedPermission: "transfer", // 默认选中转入农事权限
-});
+const permissionList = ref([]);
+const selectedPermission = ref([]);
+const currentPermissionItem = ref(null);
+
+//获取权限列表
+const getPermissionList = async () => {
+    const { data } = await VE_API.mine.listPermissionList();
+    permissionList.value = data || [];
+};
 
 const handlePermission = (item) => {
     currentPermissionItem.value = item;
-    // TODO: 从item中获取当前用户的权限设置
-    // 这里先使用默认值
-    permissionData.selectedPermission = "transfer";
+    // 初始化选中的权限,如果item中有permissions字段,则使用它,否则为空数组
+    if (item.permissionEnumList) {
+        // 如果permissions是字符串,需要转换为数组
+        selectedPermission.value = Array.isArray(item.permissionEnumList)
+            ? [...item.permissionEnumList]
+            : typeof item.permissionEnumList === "string"
+            ? item.permissionEnumList.split(",")
+            : [];
+    } else {
+        selectedPermission.value = [];
+    }
     showPermissionPopup.value = true;
 };
 
-// 切换权限选择(单选)
+// 切换权限选择(选)
 const togglePermission = (value) => {
-    permissionData.selectedPermission = value;
+    const index = selectedPermission.value.indexOf(value);
+    if (index > -1) {
+        // 如果已选中,则移除
+        selectedPermission.value.splice(index, 1);
+    } else {
+        // 如果未选中,则添加
+        selectedPermission.value.push(value);
+    }
+};
+
+// 确认权限设置
+const handleConfirmPermission = async () => {
+    if (route.query.add) {
+        const params = {
+            ids: filterList.value.map((item) => item.id),
+            permissions: selectedPermission.value,
+            role: 2,
+        };
+        const { code, msg } = await VE_API.mine.batchSaveManager(params);
+        if (code === 0) {
+            ElMessage.success("权限设置成功");
+            showPermissionPopup.value = false;
+            router.go(-1);
+        } else {
+            ElMessage.error(msg);
+        }
+    } else {
+        const params = {
+            id: currentPermissionItem.value.id,
+            permissions: selectedPermission.value,
+        };
+        const { code, msg } = await VE_API.mine.saveManager(params);
+        if (code === 0) {
+            ElMessage.success("权限设置成功");
+            showPermissionPopup.value = false;
+            // 刷新列表
+            getManagerList();
+        } else {
+            ElMessage.error(msg);
+        }
+    }
 };
 
 // 权限弹窗关闭处理
 const handlePermissionPopupClosed = () => {
     currentPermissionItem.value = null;
-    permissionData.selectedPermission = "transfer";
+    selectedPermission.value = [];
 };
 
-// 取消管理员
-const handleCancelAdmin = () => {
-    // TODO: 实现取消管理员功能
-    showPermissionPopup.value = false;
+// 过滤选中列表
+const filterList = ref([]);
+const changeCheck = () => {
+    filterList.value = teamList.value.filter((item) => item.checked);
 };
 
-// 确认权限设置
-const handleConfirmPermission = () => {
-    // TODO: 调用API保存权限设置
-    ElMessage.success("权限设置成功");
-    showPermissionPopup.value = false;
+// 表单数据
+const formData = reactive({
+    name: "",
+    phone: "",
+    duties: [],
+});
+
+// 切换角色选择(多选)
+const toggleRole = (code) => {
+    const index = formData.duties.indexOf(code);
+    if (index > -1) {
+        // 如果已选中,则移除
+        formData.duties.splice(index, 1);
+    } else {
+        // 如果未选中,则添加
+        formData.duties.push(code);
+    }
+    // 触发校验
+    if (formRef.value) {
+        formRef.value.validateField("duties");
+    }
+};
+
+// 表单校验规则
+const rules = reactive({
+    name: [
+        { required: true, message: "请输入姓名", trigger: "blur" },
+        { min: 1, max: 20, message: "姓名长度在 1 到 20 个字符", trigger: "blur" },
+    ],
+    phone: [
+        { required: true, message: "请输入手机号", trigger: "blur" },
+        { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号", trigger: "blur" },
+    ],
+    duties: [
+        {
+            required: true,
+            validator: (rule, value, callback) => {
+                if (!value || value.length === 0) {
+                    callback(new Error("请选择角色类型"));
+                } else {
+                    callback();
+                }
+            },
+            trigger: "change",
+        },
+    ],
+});
+
+// 取消管理员
+const handleCancelAdmin = async () => {
+    ElMessageBox.confirm('确定取消管理员权限吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        zIndex: 3000,
+        type: 'warning',
+    }).then(async () => {
+        const { code, msg } = await VE_API.mine.saveManager({ id: currentPermissionItem.value.id, role: 3 });
+        if (code === 0) {
+            ElMessage.success("取消管理员权限成功");
+            teamList.value = []
+            getManagerList();
+            showPermissionPopup.value = false;
+        } else {
+            ElMessage.error(msg);
+        }
+    }).catch(() => {});
 };
 
 // 弹窗关闭处理
 const handlePopupClosed = () => {
     // 重置表单
-    formData.name = "";
-    formData.phone = "";
-    formData.roleType = "pilot";
+    if (formRef.value) {
+        formRef.value.resetFields();
+    }
+    // 重置为默认值(选中第一个角色)
+    if (dutyList.value && dutyList.value.length > 0) {
+        formData.duties = [dutyList.value[0].code];
+    } else {
+        formData.duties = [];
+    }
 };
 
 // 分享微信好友
@@ -246,39 +331,26 @@ const handleShare = () => {
 
 // 确认添加
 const handleConfirm = () => {
-    // 验证姓名
-    if (!formData.name || !formData.name.trim()) {
-        ElMessage.warning("请输入姓名");
-        return;
-    }
-
-    // 验证手机号
-    if (!formData.phone || !formData.phone.trim()) {
-        ElMessage.warning("请输入手机号");
-        return;
-    }
-
-    // 验证手机号格式
-    const phonePattern = /^1[3-9]\d{9}$/;
-    if (!phonePattern.test(formData.phone)) {
-        ElMessage.warning("请输入正确的手机号");
-        return;
-    }
-
-    // 验证角色类型
-    if (!formData.roleType) {
-        ElMessage.warning("请选择角色类型");
-        return;
-    }
-
-    // 验证通过,执行添加操作
-    // TODO: 调用API添加团队成员
-    ElMessage.success("添加成功");
-    showAddMemberPopup.value = false;
-    // 可以在这里刷新团队列表
+    if (!formRef.value) return;
+    formRef.value.validate(async (valid) => {
+        if (valid) {
+            const { code, msg } = await VE_API.mine.saveManager({ ...formData, role: 3 });
+            if (code === 0) {
+                ElMessage.success("添加成功");
+                showAddMemberPopup.value = false;
+                // 刷新列表
+                getManagerList();
+            } else {
+                ElMessage.error(msg);
+            }
+        } else {
+            // 校验失败,Element Plus 会自动显示错误信息
+            return false;
+        }
+    });
 };
 
-const handleAddTeamMember = () => {
+const handleAddTeamMember = async () => {
     if (route.query.add) {
         if (filterList.value.length) {
             showPermissionPopup.value = true;
@@ -322,16 +394,16 @@ const handleItem = (item) => {
         .team-title {
             margin-bottom: 10px;
         }
-        .team-list{
-            .list-item{
+        .team-list {
+            .list-item {
                 display: flex;
                 justify-content: space-between;
                 width: 100%;
-                .item-info{
+                .item-info {
                     width: calc(100% - 55px);
                 }
             }
-            .list-item + .list-item{
+            .list-item + .list-item {
                 margin-top: 10px;
             }
         }
@@ -395,8 +467,8 @@ const handleItem = (item) => {
                 }
             }
 
-            &.permission-list{
-                .role-btn{
+            &.permission-list {
+                .role-btn {
                     padding: 10px 0;
                 }
             }