完成组织架构

This commit is contained in:
lijun 2025-11-08 16:11:52 +08:00
parent dcabee0975
commit fd6f4ef9b1
4 changed files with 210 additions and 21 deletions

2
auto-imports.d.ts vendored
View File

@ -1,5 +1,5 @@
// Generated by 'unplugin-auto-import' // Generated by 'unplugin-auto-import'
export {} export {}
declare global { declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
} }

2
components.d.ts vendored
View File

@ -50,6 +50,7 @@ declare module '@vue/runtime-core' {
ElRow: typeof import('element-plus/es')['ElRow'] ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
ElSelector: typeof import('element-plus/es')['ElSelector']
ElSlider: typeof import('element-plus/es')['ElSlider'] ElSlider: typeof import('element-plus/es')['ElSlider']
ElSpace: typeof import('element-plus/es')['ElSpace'] ElSpace: typeof import('element-plus/es')['ElSpace']
ElStatistic: typeof import('element-plus/es')['ElStatistic'] ElStatistic: typeof import('element-plus/es')['ElStatistic']
@ -69,6 +70,7 @@ declare module '@vue/runtime-core' {
ElTour: typeof import('element-plus/es')['ElTour'] ElTour: typeof import('element-plus/es')['ElTour']
ElTourStep: typeof import('element-plus/es')['ElTourStep'] ElTourStep: typeof import('element-plus/es')['ElTourStep']
ElTransfer: typeof import('element-plus/es')['ElTransfer'] ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeV2: typeof import('element-plus/es')['ElTreeV2'] ElTreeV2: typeof import('element-plus/es')['ElTreeV2']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
ElWatermark: typeof import('element-plus/es')['ElWatermark'] ElWatermark: typeof import('element-plus/es')['ElWatermark']

View File

@ -87,6 +87,34 @@ export const AdminAddUserRequestService = (Data) => {
} }
}) })
} }
export const AdminDeleteUserRequestService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
params.append(key, Data[key])
}
let token = localStorage.getItem("token") || "";
return request.post('/user/delete', params,{
headers: {
'token': token,
}
})
}
export const UpdateUserCatalogueService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
params.append(key, Data[key])
}
let token = localStorage.getItem("token") || "";
return request.post('/user/catalogue', params,{
headers: {
'token': token,
}
})
}
export const getFriendReqService = (Data) => { export const getFriendReqService = (Data) => {
const params = new URLSearchParams(); const params = new URLSearchParams();
for (let key in Data) { for (let key in Data) {
@ -94,7 +122,7 @@ export const getFriendReqService = (Data) => {
} }
return request.post('/im/get_friend_request', params, { return request.post('/im/get_friend_request', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }
@ -106,12 +134,12 @@ export const GetUserInfoService = (Data) => {
} }
return request.post('/user/info', params, { return request.post('/user/info', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }
//闂備礁鎲$敮鐐寸箾閳ь剚绻涢崨顓烆劉缂佽桨绮欓幐濠冨緞婵犲倸娈ら梻浣烘嚀閻°劑鎮ч悙鍝勭劦妞ゆ巻鍋撻柟铏姍瀹曟濮€閵忋垻锛滈梺璺ㄥ櫐閹凤拷
export const DelFGService =(Data) =>{ export const DelFGService =(Data) =>{
const params = new URLSearchParams(); const params = new URLSearchParams();
for (let key in Data) { for (let key in Data) {
@ -119,7 +147,7 @@ export const DelFGService =(Data) =>{
} }
return request.post('/im/del_friend_or_group', params, { return request.post('/im/del_friend_or_group', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }
@ -131,7 +159,7 @@ export const updateUserInfoService = (Data) => {
} }
return request.post('/user/update', params, { return request.post('/user/update', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備浇娉曢崰鎰板几婵犳艾绠柣鎴f缁犲弶銇勯顐㈠绩缂佲偓鐎n喗鐓欐い鏂挎惈婵℃寧绻涢崼鐔风仸缂佸倹甯℃俊鍫曞炊瑜滈弶娲⒑缁嬪簱搴烽柟鍑ゆ嫹 'token': Data.token,
} }
}) })
} }
@ -143,7 +171,7 @@ export const acceptInviteService =(Data)=> {
} }
return request.post('/im/accept_invite', params, { return request.post('/im/accept_invite', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }
@ -154,7 +182,7 @@ export const rejectInviteService =(Data)=> {
} }
return request.post('/im/reject_invite', params, { return request.post('/im/reject_invite', params, {
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }
@ -166,7 +194,7 @@ export const SearchUserService = (Data) => {
} }
return request.post('/user/search', params,{ return request.post('/user/search', params,{
headers: { headers: {
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷 'token': Data.token,
} }
}) })
} }

View File

@ -6,7 +6,7 @@
:delFunc="handleDelete" :changePage="changePage" :currentPage="page.index" :editFunc="handleEdit"> :delFunc="handleDelete" :changePage="changePage" :currentPage="page.index" :editFunc="handleEdit">
<template #toolbarBtn> <template #toolbarBtn>
<el-button type="warning" :icon="CirclePlusFilled" @click="visible_add = true">新增</el-button> <el-button type="warning" :icon="CirclePlusFilled" @click="visible_add = true">新增</el-button>
<el-button type="primary" @click="visible_system = true">查看组织架构</el-button> <el-button type="primary" @click="showUserTreeVisibale">查看组织架构</el-button>
</template> </template>
</TableCustom> </TableCustom>
@ -23,17 +23,65 @@
<TableDetail :data="viewData"></TableDetail> <TableDetail :data="viewData"></TableDetail>
</el-dialog> </el-dialog>
<el-dialog title="组织架构" v-model="visible_system" width="700px" destroy-on-close> <el-dialog title="调整组织架构" v-model="visible_change_group" width="500px" destroy-on-close>
<div> <div>
<el-tree-v2 <el-row>
<p>当前用户/用户组{{ currentNode.name }}</p>
</el-row>
<el-row style="margin-top: 20px;">
<p>用户组</p>
<el-select v-model="currentNode.prev" placeholder="选择类型">
<el-option v-for="opt in opts_group" :label="opt.label" :value="opt.value"></el-option>
</el-select>
</el-row>
<el-row style="margin-top: 20px;">
<el-button type="primary" @click="updateUserCatalogue(currentNode)"> </el-button>
</el-row>
</div>
</el-dialog>
<el-dialog title="组织架构" v-model="visible_system" width="900px" destroy-on-close>
<div>
<el-tree
ref="treeRef" ref="treeRef"
style="max-width: 300px" style="max-width: 800px;"
:data="treeData" :data="treeData"
:props="treeProps" :props="treeProps"
:filter-method="filterMethod" :filter-method="filterMethod"
:height="200" :height="400"
/> show-checkbox
</div> default-expand-all
:expand-on-click-node="false"
>
<template #default="{ node, data }">
<div class="custom-tree-node">
<span>{{ node.label }}</span>
<div>
<el-button type="primary" link @click="handleNodeClick(data)">
调整
</el-button>
<el-button type="primary" link @click="append_user(data)" v-if="data.type != 0">
添加用户
</el-button>
<el-button type="primary" link @click="append_group(data)" v-if="data.type != 0">
添加用户组
</el-button>
<el-button
style="margin-left: 4px"
type="danger"
link
@click="remove(node, data)"
>
删除
</el-button>
</div>
</div>
</template>
</el-tree>
</div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -44,7 +92,7 @@ import { ElMessage } from 'element-plus';
import { CirclePlusFilled } from '@element-plus/icons-vue'; import { CirclePlusFilled } from '@element-plus/icons-vue';
import { UserInfo } from '@/types/user'; import { UserInfo } from '@/types/user';
import { fetchUserData } from '@/api'; import { fetchUserData } from '@/api';
import { SearchUserService,AdminAddUserRequestService } from "@/api/user"; import { SearchUserService,AdminAddUserRequestService,UpdateUserCatalogueService,AdminDeleteUserRequestService } from "@/api/user";
import {GetUserInfoService} from "@/api/user"; import {GetUserInfoService} from "@/api/user";
import {updateUserInfoService} from "@/api/user"; import {updateUserInfoService} from "@/api/user";
import TableCustom from '@/components/table-custom.vue'; import TableCustom from '@/components/table-custom.vue';
@ -52,7 +100,17 @@ import TableDetail from '@/components/table-detail.vue';
import TableSearch from '@/components/table-search.vue'; import TableSearch from '@/components/table-search.vue';
import { FormOption, FormOptionList } from '@/types/form-option'; import { FormOption, FormOptionList } from '@/types/form-option';
import {getAllDefaultUsers} from '@/api/user'; import {getAllDefaultUsers} from '@/api/user';
import { tr, vi } from 'element-plus/es/locale';
import { group } from 'console';
interface Tree {
id: number
label: string
children?: Tree[]
}
const opts_group = ref([]);
const currentNode = ref(null);
const currentPrev = ref(0); // ID
const treeData = ref([]); const treeData = ref([]);
const treeProps = ref({ const treeProps = ref({
id: 'id', // id id: 'id', // id
@ -64,6 +122,31 @@ const query = reactive({
name: '', name: '',
}); });
const showUserTreeVisibale = async () => {
await GetAllDefaultUsers();
visible_system.value = true;
};
const updateUserCatalogue = async (data) => {
try {
let req={
user_id: data.id,
group_id: data.prev,
}
let result = await UpdateUserCatalogueService(req);
if (result["code"] === 0) {
ElMessage.success("调整成功");
closeDialog();
} else {
ElMessage.error("调整失败:"+result["message"]);
}
} catch (error) {
console.error('调整组织架构失败:', error);
}
GetAllDefaultUsers();
};
const GetAllDefaultUsers = async () => { const GetAllDefaultUsers = async () => {
try { try {
const response = await getAllDefaultUsers(); const response = await getAllDefaultUsers();
@ -72,12 +155,60 @@ const GetAllDefaultUsers = async () => {
return; return;
} }
buildTree(response['data']); buildTree(response['data']);
opts_group.value = [];
for (const item of response['data']) {
if (item.type === 1) { // 1
opts_group.value.push({ label: item.name, value: item.id });
}
}
opts_group.value.unshift({ label: '根目录', value: 0 });
} catch (error) { } catch (error) {
console.error('获取默认用户失败:', error); console.error('获取默认用户失败:', error);
} }
}; };
GetAllDefaultUsers(); const visible_change_group = ref(false);
const handleNodeClick = (data) => {
currentPrev.value = data.id;
currentNode.value = data;
visible_change_group.value = true;
};
// GetAllDefaultUsers();
const append_user = (data) => {
currentPrev.value = data.id;
visible_add.value = true;
};
const append_group = (data) => {
currentPrev.value = data.id;
visible_add.value = true;
};
const remove = async (node, data) => {
await AdminDelUser(data);
await GetAllDefaultUsers();
// if(data.prev === 0){
// node.remove();
// return;
// }
// const parent = node.parent;
// if (parent) {
// const index = parent.data.children.findIndex(item => item.id === data.id);
// if (index !== -1) {
// parent.data.children.splice(index, 1);
// }
// } else {
// // treeData
// const index = treeData.value.findIndex(item => item.id === data.id);
// if (index !== -1) {
// treeData.value.splice(index, 1);
// }
// }
};
const buildTree = (data) => { const buildTree = (data) => {
// 1. map key idvalue 便 // 1. map key idvalue 便
@ -193,7 +324,7 @@ const addData = async (data) => {
let result ={} let result ={}
try{ try{
let req={ let req={
prev: currentPrev.value,
name: data.Name, name: data.Name,
email: data.Email, email: data.Email,
password: data.Password, password: data.Password,
@ -209,7 +340,8 @@ const addData = async (data) => {
}catch(e){ }catch(e){
console.log(e); console.log(e);
} }
getData(); getData();
GetAllDefaultUsers();
}; };
const changePage = (val: number) => { const changePage = (val: number) => {
@ -364,10 +496,37 @@ const handleView =async (row: UserInfo) => {
visible1.value = true; visible1.value = true;
}; };
const AdminDelUser =async (data) => {
console.log("删除用户:",data);
try{
let req={
id: data.id,
}
let result = await AdminDeleteUserRequestService(req);
if (result["code"] === 0) {
ElMessage.success("删除成功");
}else{
ElMessage.error("删除失败:"+result["message"]);
}
}catch(e){
console.log(e);
}
};
// //
const handleDelete = (row: UserInfo) => { const handleDelete = (row: UserInfo) => {
ElMessage.success('删除成功'); ElMessage.success('删除成功');
} }
</script> </script>
<style scoped></style> <style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>