fix:联调成员新增接口

This commit is contained in:
liangdong
2026-01-12 21:24:45 +08:00
parent a4bb81dc0a
commit c6a4604d1f
5 changed files with 84 additions and 82 deletions

View File

@@ -36,6 +36,7 @@
value-key="id" value-key="id"
v-select-more="handleLoadMore" v-select-more="handleLoadMore"
@change="changeMember" @change="changeMember"
popper-class="standard-select-dropdown-height"
> >
<el-option <el-option
v-for="item in selectOptions" v-for="item in selectOptions"
@@ -73,7 +74,7 @@
</el-select> </el-select>
</div> </div>
<el-scrollbar <el-scrollbar
height="calc(100vh - 216px)" height="calc(100vh - 220px)"
@end-reached="loadMoreList" @end-reached="loadMoreList"
ref="listRef" ref="listRef"
> >

View File

@@ -1,7 +1,7 @@
import { ref, shallowRef, computed, watch } from 'vue'; import { ref, shallowRef, computed, watch } from 'vue';
export function useLocalManager<T>(initialDataGetter: () => T[], pageSize = 20) { export function useLocalManager<T>(initialDataGetter: () => T[], pageSize = 20) {
// 1. 全量数据池(使用 shallowRef 保证 1W 条数据操作不卡顿) // 1. 全量数据池
const fullData = shallowRef<T[]>([]); const fullData = shallowRef<T[]>([]);
// 2. 内部展示条数 // 2. 内部展示条数
@@ -10,10 +10,18 @@ export function useLocalManager<T>(initialDataGetter: () => T[], pageSize = 20)
// 3. 监听初始数据的变化(处理后端异步返回) // 3. 监听初始数据的变化(处理后端异步返回)
watch(initialDataGetter, (newVal) => { watch(initialDataGetter, (newVal) => {
if (Array.isArray(newVal)) { if (Array.isArray(newVal)) {
fullData.value = [...newVal]; // 全量去重,确保内部池子纯净
displayCount.value = pageSize; const map = new Map();
newVal.forEach(item => { if((item as any).id) map.set((item as any).id, item) });
const uniqueData = Array.from(map.values()) as T[];
fullData.value = uniqueData;
// 如果数据被删减到小于当前水位,重置水位
if (uniqueData.length < displayCount.value) {
displayCount.value = Math.max(pageSize, uniqueData.length);
}
} }
}, { immediate: true }); }, { immediate: true,deep:true });
// 4. 切片数据UI 渲染对象) // 4. 切片数据UI 渲染对象)
const displayData = computed(() => { const displayData = computed(() => {
@@ -28,22 +36,10 @@ export function useLocalManager<T>(initialDataGetter: () => T[], pageSize = 20)
displayCount.value += pageSize; displayCount.value += pageSize;
}; };
// 移除
const remove = (id: string | number, key = 'id') => {
fullData.value = fullData.value.filter(item => (item as any)[key] !== id);
};
// 新增
const add = (item: T) => {
fullData.value = [item, ...fullData.value];
};
return { return {
fullData,
displayData, displayData,
displayCount,
loadMore, loadMore,
noMore, noMore,
remove,
add
}; };
} }

View File

@@ -27,7 +27,7 @@
.permission-scroll-area{ .permission-scroll-area{
padding: 0 var(--common-padding); padding: 0 var(--common-padding);
box-sizing: border-box; box-sizing: border-box;
height: calc(100vh - 190px); //设置固定的高度 height: calc(100vh - 194px); //设置固定的高度
overflow-y: auto; overflow-y: auto;
} }
@@ -66,7 +66,7 @@
.permission-row { .permission-row {
display: flex; display: flex;
align-items: center; align-items: flex-start;
margin-bottom: 12px; margin-bottom: 12px;
.row-label { .row-label {

View File

@@ -27,48 +27,44 @@
</div> </div>
</template> </template>
</stageBreadcrumbs> </stageBreadcrumbs>
<template v-if="[1, 2].includes(activeTab)"> <!-- 表格 -->
<!-- 表格 --> <CommonTable
<CommonTable ref="tableRef"
ref="tableRef" :columns="tableColumns"
:columns="tableColumns" v-model:data="dataList"
v-model:data="dataList" v-model:total="total"
v-model:total="total" pagination
pagination :request-api="getTableData"
:request-api="getTableData" >
> <!-- 状态 -->
<!-- 状态 --> <template #status="{ row }">
<template #status="{ row }"> <div
<div class="mj-status-dot"
class="mj-status-dot" :style="{
:style="{ '--data-status-color': PermissionManage.roleDictColor[row.status],
'--data-status-color': PermissionManage.roleDictColor[row.status], }"
}" @click="handleDictStatus(row)"
@click="handleDictStatus(row)" >
> {{ PermissionManage.roleDict[row.status] }}
{{ PermissionManage.roleDict[row.status] }} </div>
</div> </template>
</template>
<!-- 类型 --> <!-- 类型 -->
<template #type="{ row }"> <template #type="{ row }">
<el-tag type="primary">{{ row.type }}</el-tag> <el-tag type="primary">{{ row.type }}</el-tag>
</template> </template>
<!-- 成员数量 --> <!-- 成员数量 -->
<template #member="{ row }"> <template #member="{ row }">
<el-button <el-button
link link
icon="UserFilled" icon="UserFilled"
type="primary" type="primary"
@click.stop="addMember(row)" @click.stop="addMember(row)"
>{{ row.memberCount }}</el-button >{{ row.memberCount }}</el-button
> >
</template> </template>
</CommonTable> </CommonTable>
</template>
<!-- 前线配置模块内容 -->
<template v-else> 权限配置模块 </template>
</div> </div>
<!-- 成员管理 --> <!-- 成员管理 -->
@@ -105,9 +101,10 @@ import {
enableRole, enableRole,
disableRole, disableRole,
getRoleMemberList, getRoleMemberList,
copyRolePermission copyRolePermission,
batchSaveRole
} from "@/api/stage/permission/index.ts"; } from "@/api/stage/permission/index.ts";
import { useLocalManager } from '@/hooks/useLocalManager'; import { useLocalManager } from "@/hooks/useLocalManager";
defineOptions({ name: "PermissionManagement" }); defineOptions({ name: "PermissionManagement" });
const activeTab = ref(1); const activeTab = ref(1);
const tableRef = ref(null); const tableRef = ref(null);
@@ -119,6 +116,7 @@ const showMember = ref(false);
const showRoles = ref(false); const showRoles = ref(false);
const detailId = ref(""); const detailId = ref("");
const showPermission = ref(false); const showPermission = ref(false);
const selectMember = ref({}); //当前选择的成员数量数据
const tabList = [ const tabList = [
{ {
label: "角色与权限", label: "角色与权限",
@@ -126,14 +124,8 @@ const tabList = [
}, },
]; ];
const { const { fullData, displayData, loadMore, noMore, remove, add } =
fullData, useLocalManager(() => memberList.value);
displayData,
loadMore,
noMore,
remove,
add
} = useLocalManager(()=>memberList.value);
const roleColumns = [ const roleColumns = [
{ {
@@ -229,7 +221,7 @@ const roleColumns = [
ElMessage.success("复制成功"); ElMessage.success("复制成功");
tableRef.value.refresh(); tableRef.value.refresh();
} catch (error) { } catch (error) {
console.log('copy error',error); console.log("copy error", error);
} }
}, },
}, },
@@ -286,12 +278,24 @@ const tableColumns = computed(() => {
// 当前成员数量 // 当前成员数量
const addMember = (row) => { const addMember = (row) => {
showMember.value = true; showMember.value = true;
selectMember.value = row;
getMemberList({ id: row.id }); getMemberList({ id: row.id });
}; };
// 保存成员数量 // 保存成员数量
const handleSaveMember = async () => { const handleSaveMember = async (row) => {
console.log("保存成员数量",memberList.value); const { id } = selectMember.value;
const userIds = memberList.value.map((item) => item.id);
try {
await batchSaveRole(id,{userIds})
ElMessage.success("保存成功");
const currentRow = dataList.value.find(item => item.id === id);
if (currentRow) {
currentRow.memberCount = memberList.value.length;
}
} catch (error) {
console.log('batch save error',error);
}
}; };
// 刷新列表 // 刷新列表
@@ -332,17 +336,12 @@ const getTableData = async (params) => {
} }
}; };
// TODO: 后面会修改成全部获取获取成员角色列表 (分页获取) // 后面会修改成全部获取获取成员角色列表
const getMemberList = async (params) => { const getMemberList = async (params) => {
// 获取成员角色列表
const queryParams = {
roleId: "",
pageNo: 1,
pageSize: 10,
};
try { try {
const res = await getRoleMemberList(params.id); const response = await getRoleMemberList(params.id);
memberList.value = res.records; memberList.value = response;
} catch (error) { } catch (error) {
console.log("error", error); console.log("error", error);
} }

View File

@@ -195,3 +195,9 @@
--el-overlay-color-lighter: rgba(0, 0, 0, .12); --el-overlay-color-lighter: rgba(0, 0, 0, .12);
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
} }
.standard-select-dropdown-height{
.el-select-dropdown__wrap{
min-height: 240px;
}
}