feat: 🚀 用户分配角色,路由分配角色,路由修改显示状态加弹窗

This commit is contained in:
Bunny 2024-10-05 19:19:35 +08:00
parent ede79f40b0
commit 87e46ca1e2
19 changed files with 281 additions and 92 deletions

34
src/api/v1/menu.ts Normal file
View File

@ -0,0 +1,34 @@
import { http } from '@/api/service/request';
import type { BaseResult, ResultTable } from '@/api/service/types';
/** 菜单管理-列表 */
export const fetchGetMenusList = (data?: any) => {
return http.request<BaseResult<ResultTable>>('get', `router/getMenusList`, { params: data });
};
/** 菜单管理-添加菜单 */
export const fetchAddMenu = (data?: any) => {
return http.request<BaseResult<any>>('post', `router/addMenu`, { data });
};
/** 菜单管理-更新菜单 */
export const fetchUpdateMenu = (data?: any) => {
return http.request<BaseResult<any>>('put', `router/updateMenu`, { data });
};
/** 菜单管理-删除菜单 */
export const fetchDeletedMenuByIds = (data?: any) => {
return http.request<BaseResult<any>>('delete', `router/deletedMenuByIds`, { data });
};
/** 菜单管理-为菜单分配角色 */
export const fetchAssignRolesToRouter = (data: any) => {
return http.request<BaseResult<any>>('post', `routerRole/assignRolesToRouter`, { data });
};
/**
* id获取所有角色
*/
export const fetchGetRoleListByRouterId = data => {
return http.request<BaseResult<any>>('get', `routerRole/getRoleListByRouterId`, { params: data });
};

View File

@ -28,3 +28,10 @@ export const fetchUpdatePower = (data: any) => {
export const fetchDeletePower = (data: any) => {
return http.request<BaseResult<object>>('delete', 'power/deletePower', { data });
};
/**
*
*/
export const fetchGetAllPowers = () => {
return http.request<BaseResult<any>>('get', `power/getAllPowers`);
};

View File

@ -28,3 +28,17 @@ export const fetchUpdateRole = (data: any) => {
export const fetchDeleteRole = (data: any) => {
return http.request<BaseResult<object>>('delete', 'role/deleteRole', { data });
};
/**
*
*/
export const fetchGetAllRoles = () => {
return http.request<BaseResult<any>>('get', `role/getAllRoles`);
};
/**
* id获取所有角色
*/
export const fetchGetRoleListByUserId = data => {
return http.request<BaseResult<any>>('get', `userRole/getRoleListByUserId`, { params: data });
};

View File

@ -1,31 +1,11 @@
import { http } from '@/api/service/request';
import type { BaseResult, ResultTable } from '@/api/service/types';
import type { BaseResult } from '@/api/service/types';
/** 系统管理-用户路由获取 */
export const getRouterAsync = () => {
return http.request<BaseResult<any>>('get', 'router/getRouterAsync');
};
/** 菜单管理-列表 */
export const getMenusList = (data?: any) => {
return http.request<BaseResult<ResultTable>>('get', `router/getMenusList`, { params: data });
};
/** 菜单管理-添加菜单 */
export const addMenu = (data?: any) => {
return http.request<BaseResult<any>>('post', `router/addMenu`, { data });
};
/** 菜单管理-更新菜单 */
export const updateMenu = (data?: any) => {
return http.request<BaseResult<any>>('put', `router/updateMenu`, { data });
};
/** 菜单管理-删除菜单 */
export const deletedMenuByIds = (data?: any) => {
return http.request<BaseResult<any>>('delete', `router/deletedMenuByIds`, { data });
};
/** 上传文件 */
export const fetchUploadFile = (data: any) => {
return http.post<BaseResult<any>>('/files/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });

View File

@ -87,3 +87,11 @@ export const fetchUploadAvatarByAdmin = (data: any) => {
export const fetchForcedOffline = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', { data });
};
/**
*
* @param data
*/
export const fetchAssignRolesToUsers = (data: object) => {
return http.request<BaseResult<any>>('post', 'userRole/assignRolesToUsers', { data });
};

View File

@ -1,3 +1,5 @@
import { computed } from 'vue';
/**
* *
*/
@ -34,3 +36,4 @@ export const userStatus = [
* *
*/
export const pageSizes: number[] = [15, 30, 50, 100, 150, 200, 300];
export const tableSelectButtonClass = computed(() => ['!h-[20px]', 'reset-margin', '!text-gray-500', 'dark:!text-white', 'dark:hover:!text-primary']);

View File

@ -1,9 +1,9 @@
import { defineStore } from 'pinia';
import { addMenu, deletedMenuByIds, getMenusList, updateMenu } from '@/api/v1/system';
import { storeMessage } from '@/utils/message';
import { handleTree } from '@/utils/tree';
import { fetchAddMenu, fetchAssignRolesToRouter, fetchDeletedMenuByIds, fetchGetMenusList, fetchGetRoleListByRouterId, fetchUpdateMenu } from '@/api/v1/menu';
export const userRouterStore = defineStore('routerStore', {
export const userMenuStore = defineStore('menuStore', {
state() {
return {
datalist: [],
@ -18,7 +18,7 @@ export const userRouterStore = defineStore('routerStore', {
*/
async getMenuList() {
const data = { ...this.pagination, ...this.form };
const result = await getMenusList(data);
const result = await fetchGetMenusList(data);
if (result.code === 200) {
this.datalist = handleTree(result.data as any);
@ -32,7 +32,7 @@ export const userRouterStore = defineStore('routerStore', {
* @param data
*/
async addMenu(data: object) {
const result = await addMenu(data);
const result = await fetchAddMenu(data);
return storeMessage(result);
},
@ -41,7 +41,7 @@ export const userRouterStore = defineStore('routerStore', {
* @param data
*/
async updateMenu(data: object) {
const result = await updateMenu(data);
const result = await fetchUpdateMenu(data);
return storeMessage(result);
},
@ -50,7 +50,26 @@ export const userRouterStore = defineStore('routerStore', {
* @param data
*/
async deletedMenuByIds(data: object) {
const result = await deletedMenuByIds(data);
const result = await fetchDeletedMenuByIds(data);
return storeMessage(result);
},
/**
* * id获取角色列表
* @param data
*/
async getRoleListByRouterId(data: any) {
const result = await fetchGetRoleListByRouterId(data);
if (result.code !== 200) return;
return result.data;
},
/**
* *
* @param data
*/
async assignRolesToRouter(data: any) {
const result = await fetchAssignRolesToRouter(data);
return storeMessage(result);
},
},

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia';
import { fetchAddPower, fetchDeletePower, fetchGetPowerList, fetchUpdatePower } from '@/api/v1/power';
import { fetchAddPower, fetchDeletePower, fetchGetAllPowers, fetchGetPowerList, fetchUpdatePower } from '@/api/v1/power';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
@ -12,6 +12,8 @@ export const usePowerStore = defineStore('powerStore', {
return {
// 权限列表
datalist: [],
// 权限树形结构
treeList: [],
// 查询表单
form: {
// 权限编码
@ -75,5 +77,14 @@ export const usePowerStore = defineStore('powerStore', {
const result = await fetchDeletePower(data);
return storeMessage(result);
},
/**
*
*/
async getAllPowers() {
const result = await fetchGetAllPowers();
if (result.code !== 200) return;
this.treeList = result.data;
},
},
});

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia';
import { fetchAddRole, fetchDeleteRole, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role';
import { fetchAddRole, fetchDeleteRole, fetchGetAllRoles, fetchGetRoleList, fetchUpdateRole } from '@/api/v1/role';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
@ -52,6 +52,16 @@ export const useRoleStore = defineStore('roleStore', {
return pagination(result);
},
/**
* *
*/
async getAllRoles() {
const result = await fetchGetAllRoles();
if (result.code !== 200) return;
this.allRoleList = result.data.map(role => ({ key: role.id, label: role.description }));
},
/**
* *
*/
@ -75,21 +85,5 @@ export const useRoleStore = defineStore('roleStore', {
const result = await fetchDeleteRole(data);
return storeMessage(result);
},
/**
* * id获取角色列表
* @param data
*/
async getRoleListByUserId(data: any) {
console.log(data);
},
/**
* *
* @param data
*/
async assignRolesToUsers(data: any) {
console.log(data);
},
},
});

View File

@ -1,9 +1,10 @@
import { defineStore } from 'pinia';
import { resetRouter, router, routerArrays, storageLocal, store, type userType } from '../utils';
import { fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/user';
import { fetchAssignRolesToUsers, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/user';
import { useMultiTagsStoreHook } from '../multiTags';
import { type DataInfo, removeToken, setToken, userKey } from '@/utils/auth';
import { message } from '@/utils/message';
import { message, storeMessage } from '@/utils/message';
import { fetchGetRoleListByUserId } from '@/api/v1/role';
export const useUserStore = defineStore({
id: 'system-user',
@ -84,6 +85,25 @@ export const useUserStore = defineStore({
message(result.message, { type: 'error' });
return false;
},
/**
* * id获取角色列表
* @param data
*/
async getRoleListByUserId(data: any) {
const result = await fetchGetRoleListByUserId(data);
if (result.code !== 200) return;
return result.data;
},
/**
* *
* @param data
*/
async assignRolesToUsers(data: any) {
const result = await fetchAssignRolesToUsers(data);
return storeMessage(result);
},
},
});

View File

@ -127,7 +127,7 @@ export const messageBox = async (option: MessageBox = defaultBoxOption, type: an
return true;
})
.catch(() => {
message(option.cancelMessage, { type: 'warning' });
message(option.cancelMessage, { type: 'info' });
return false;
});
};

View File

@ -1,12 +1,14 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { useRoleStore } from '@/store/system/role';
import { useUserStore } from '@/store/system/user';
const props = defineProps({
userId: { type: String as PropType<String> },
});
const roleStore = useRoleStore();
const userStore = useUserStore();
//
const assignRoles = ref([]);
@ -19,11 +21,11 @@ const getRoleListByUserId = async () => {
// id
const userId = props.userId;
assignRoles.value = await roleStore.getRoleListByUserId({ userId });
assignRoles.value = await userStore.getRoleListByUserId({ userId });
};
onMounted(() => {
roleStore.getRoleList();
roleStore.getAllRoles();
getRoleListByUserId();
});

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { onMounted, ref } from 'vue';
import { columns } from '@/views/system/adminUser/utils/columns';
import PureTableBar from '@/components/TableBar/src/bar';
import AddFill from '@iconify-icons/ri/add-circle-line';
@ -17,7 +17,7 @@ import Role from '@iconify-icons/ri/admin-line';
import Password from '@iconify-icons/ri/lock-password-line';
import More from '@iconify-icons/ep/more-filled';
import { useAdminUserStore } from '@/store/system/adminUser';
import { sexConstant, userStatus } from '@/enums/baseConstant';
import { sexConstant, tableSelectButtonClass, userStatus } from '@/enums/baseConstant';
import { deviceDetection } from '@pureadmin/utils';
import Tree from '@/views/system/adminUser/tree.vue';
import Airplane from '@/assets/svg/airplane.svg';
@ -25,7 +25,6 @@ import Airplane from '@/assets/svg/airplane.svg';
const tableRef = ref();
const formRef = ref();
const adminUserStore = useAdminUserStore();
const buttonClass = computed(() => ['!h-[20px]', 'reset-margin', '!text-gray-500', 'dark:!text-white', 'dark:hover:!text-primary']);
/**
* * 当前页改变时
@ -188,16 +187,16 @@ onMounted(() => {
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<el-button :class="buttonClass" :icon="useRenderIcon(Upload)" :size="size" link type="primary" @click="onUploadAvatar(row)"> 上传头像 </el-button>
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Upload)" :size="size" link type="primary" @click="onUploadAvatar(row)"> 上传头像 </el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button :class="buttonClass" :icon="useRenderIcon(Password)" :size="size" link type="primary" @click="onResetPassword(row)"> 重置密码 </el-button>
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Password)" :size="size" link type="primary" @click="onResetPassword(row)"> 重置密码 </el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button :class="buttonClass" :icon="useRenderIcon(Role)" :size="size" link type="primary" @click="onAssignRolesToUser(row)"> 分配角色 </el-button>
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Role)" :size="size" link type="primary" @click="onAssignRolesToUser(row)"> 分配角色 </el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button :class="buttonClass" :icon="useRenderIcon(Airplane)" :size="size" link type="primary" @click="onForcedOffline(row)"> 强制下线 </el-button>
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Airplane)" :size="size" link type="primary" @click="onForcedOffline(row)"> 强制下线 </el-button>
</el-dropdown-item>
</el-dropdown-menu>
</template>

View File

@ -32,9 +32,7 @@ const defaultProps = {
children: 'children',
label: 'name',
};
const buttonClass = computed(() => {
return ['!h-[20px]', '!text-sm', 'reset-margin', '!text-[var(--el-text-color-regular)]', 'dark:!text-white', 'dark:hover:!text-primary'];
});
const buttonClass = computed(() => ['!h-[20px]', '!text-sm', 'reset-margin', '!text-[var(--el-text-color-regular)]', 'dark:!text-white', 'dark:hover:!text-primary']);
const filterNode = (value: string, data: Tree) => {
if (!value) return true;

View File

@ -6,18 +6,18 @@ import { message, messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/adminUser/utils/types';
import { $t } from '@/plugins/i18n';
import { isAddUserinfo } from '@/views/system/adminUser/utils/columns';
import { useRoleStore } from '@/store/system/role';
import ResetPasswordDialog from '@/views/system/adminUser/reset-passwords.vue';
import { deviceDetection } from '@pureadmin/utils';
import CropperPreview from '@/components/CropperPreview';
import AssignUserToRole from '@/views/system/adminUser/assign-user-to-role.vue';
import userAvatar from '@/assets/user.jpg';
import { fetchForcedOffline, fetchUploadAvatarByAdmin } from '@/api/v1/user';
import { useUserStore } from '@/store/system/user';
export const formRef = ref();
const cropRef = ref();
const assignRolesRef = ref();
const roleStore = useRoleStore();
const userStore = useUserStore();
// 上传头像信息
const avatarInfo = ref();
const adminUserStore = useAdminUserStore();
@ -232,7 +232,7 @@ export const onAssignRolesToUser = (row: any) => {
beforeSure: async (done: any) => {
// 分配用户角色
const data = { userId: row.id, roleIds: assignRolesRef.value.assignRoles };
const result = await roleStore.assignRolesToUsers(data);
const result = await userStore.assignRolesToUsers(data);
// 更新成功关闭弹窗
if (!result) return;

View File

@ -0,0 +1,48 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { useRoleStore } from '@/store/system/role';
import { userMenuStore } from '@/store/system/menu';
const props = defineProps({
routerId: { type: String as PropType<String> },
});
const roleStore = useRoleStore();
const menuStore = userMenuStore();
//
const assignRoles = ref([]);
/**
* * 根据用户id获取当前用户角色
*/
const getRoleListByRouterId = async () => {
//
assignRoles.value = [];
// id
const routerId = props.routerId;
assignRoles.value = await menuStore.getRoleListByRouterId({ routerId });
};
onMounted(() => {
roleStore.getAllRoles();
getRoleListByRouterId();
});
defineExpose({ assignRoles });
</script>
<template>
<div class="flex justify-center">
<el-transfer
v-model="assignRoles"
:button-texts="['收回', '添加']"
:data="roleStore.allRoleList"
:format="{ noChecked: '总数 ${total}', hasChecked: '${checked}/${total}' }"
:titles="['未添加', '已添加']"
class="m-3"
filter-placeholder="搜索角色"
filterable
/>
</div>
</template>

View File

@ -6,30 +6,46 @@ import Delete from '@iconify-icons/ep/delete';
import EditPen from '@iconify-icons/ep/edit-pen';
import Refresh from '@iconify-icons/ep/refresh';
import AddFill from '@iconify-icons/ri/add-circle-line';
import { handleDelete, onAdd, onSearch, onUpdate, resetForm } from '@/views/system/menu/utils/hooks';
import { assignRolesToRouter, handleDelete, onAdd, onSearch, onUpdate, resetForm } from '@/views/system/menu/utils/hooks';
import form from '@/views/system/menu/form.vue';
import PureTable from '@pureadmin/table';
import { columns } from '@/views/system/menu/utils/columns';
import { userRouterStore } from '@/store/system/router';
import { userMenuStore } from '@/store/system/menu';
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
import More from '@iconify-icons/ep/more-filled';
import { tableSelectButtonClass } from '@/enums/baseConstant';
import Upload from '@iconify-icons/ri/upload-line';
import { messageBox } from '@/utils/message';
const formRef = ref();
const tableRef = ref();
const routerStore = userRouterStore();
const routerStore = userMenuStore();
/**
* * 修改菜单是否显示
* @param val
* @param row
*/
const onchangeVisible = async (val: boolean) => {
const onchangeVisible = async (row: any) => {
//
const confirm = await messageBox({
title: $t('confirm_update_status'),
showMessage: false,
confirmMessage: undefined,
cancelMessage: $t('cancel'),
});
if (!confirm) {
row.visible = !row.visible;
return;
}
const data = {
id: val.id,
visible: val.visible,
menuType: val.menuType,
title: val.title,
name: val.name,
path: val.path,
id: row.id,
visible: row.visible,
menuType: row.menuType,
title: row.title,
name: row.name,
path: row.path,
};
await routerStore.updateMenu(data);
await onSearch();
@ -106,13 +122,26 @@ onMounted(() => {
</template>
<template #operation="{ row }">
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> 修改 </el-button>
<el-button v-show="row.menuType !== 3" :icon="useRenderIcon(AddFill)" :size="size" class="reset-margin" link type="primary" @click="onAdd(row.id)"> 新增 </el-button>
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
<el-button v-show="row.menuType !== 3" :icon="useRenderIcon(AddFill)" :size="size" class="reset-margin" link type="primary" @click="onAdd(row.id)"> {{ $t('add_new') }} </el-button>
<el-popconfirm :title="`是否确认删除菜单名称为${$t(row.title)}的这条数据${row?.children?.length > 0 ? '注意下级菜单也会一并删除,请谨慎操作' : ''}`" @confirm="handleDelete(row)">
<template #reference>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary"> 删除 </el-button>
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
{{ $t('delete') }}
</el-button>
</template>
</el-popconfirm>
<!-- 更多操作 -->
<el-dropdown>
<el-button :icon="useRenderIcon(More)" :size="size" class="ml-3 mt-[2px]" link type="primary" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<el-button :class="tableSelectButtonClass" :icon="useRenderIcon(Upload)" :size="size" link type="primary" @click="assignRolesToRouter(row)"> 分配角色 </el-button>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</pure-table>
</template>

View File

@ -43,7 +43,7 @@ export const columns: TableColumnList = [
{ label: $t('table.createTime'), prop: 'createTime', sortable: true },
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 90 },
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 90 },
{ label: '操作', fixed: 'right', width: 210, slot: 'operation' },
{ label: '操作', fixed: 'right', width: 210, slot: 'operation', width: 240 },
];
/** 自定义表单规则校验 */

View File

@ -1,16 +1,15 @@
import editForm from '../form.vue';
import { $t } from '@/plugins/i18n';
import { addDialog } from '@/components/BaseDialog/index';
import { h, reactive, ref } from 'vue';
import { h, ref } from 'vue';
import type { FormItemProps } from './types';
import { cloneDeep, deviceDetection } from '@pureadmin/utils';
import { userRouterStore } from '@/store/system/router';
import { userMenuStore } from '@/store/system/menu';
import AssignRouterToRole from '@/views/system/menu/assign-router-to-role.vue';
const routerStore = userRouterStore();
export const form = reactive({
title: '',
});
const menuStore = userMenuStore();
const assignRouterToRolesRef = ref();
export const formRef = ref();
/**
@ -33,9 +32,9 @@ export const getMenuType = (type, text = false) => {
* *
*/
export const onSearch = async () => {
routerStore.loading = true;
await routerStore.getMenuList();
routerStore.loading = false;
menuStore.loading = true;
await menuStore.getMenuList();
menuStore.loading = false;
};
export const formatHigherMenuOptions = (treeList: any) => {
@ -58,7 +57,7 @@ export function onAdd(parentId: any = 0) {
props: {
formInline: {
menuType: 0,
higherMenuOptions: formatHigherMenuOptions(cloneDeep(routerStore.datalist)),
higherMenuOptions: formatHigherMenuOptions(cloneDeep(menuStore.datalist)),
parentId,
title: '',
name: '',
@ -82,7 +81,7 @@ export function onAdd(parentId: any = 0) {
if (!valid) return;
delete curData.higherMenuOptions;
const result = await routerStore.addMenu(curData);
const result = await menuStore.addMenu(curData);
// 刷新表格数据
if (result) {
done();
@ -103,7 +102,7 @@ export const onUpdate = (row?: FormItemProps) => {
props: {
formInline: {
menuType: row?.menuType,
higherMenuOptions: formatHigherMenuOptions(cloneDeep(routerStore.datalist)),
higherMenuOptions: formatHigherMenuOptions(cloneDeep(menuStore.datalist)),
parentId: row?.parentId,
title: row?.title,
name: row?.name,
@ -129,7 +128,7 @@ export const onUpdate = (row?: FormItemProps) => {
delete curData.higherMenuOptions;
curData.id = row.id;
const result = await routerStore.updateMenu(curData);
const result = await menuStore.updateMenu(curData);
// 刷新表格数据
if (result) {
done();
@ -145,6 +144,30 @@ export const onUpdate = (row?: FormItemProps) => {
* @param row
*/
export const handleDelete = async row => {
await routerStore.deletedMenuByIds([row.id]);
await menuStore.deletedMenuByIds([row.id]);
await onSearch();
};
/**
*
* @param row
*/
export const assignRolesToRouter = (row: any) => {
addDialog({
title: `${row.name} 分配角色`,
width: '45%',
draggable: true,
closeOnClickModal: false,
fullscreenIcon: true,
contentRenderer: () => <AssignRouterToRole ref={assignRouterToRolesRef} routerId={row.id} />,
beforeSure: async (done: any) => {
// 分配用户角色
const data = { routerId: row.id, roleIds: assignRouterToRolesRef.value.assignRoles };
const result = await menuStore.assignRolesToRouter(data);
// 更新成功关闭弹窗
if (!result) return;
done();
},
});
};