组织管理接口初步调试

This commit is contained in:
LovableCat
2025-03-18 21:19:02 +08:00
parent 945e11b0ae
commit 26c594c9d4
3 changed files with 233 additions and 128 deletions

View File

@@ -1,50 +1,45 @@
import request from '@/utils/request'; import request from '@/utils/request';
import {
type CreateOrganizationApiResultType,
type OrganizationMemberItemType,
type UnitRes
} from "@/api/organizationManage/organizationManageType";
// TODO 获取组织信息功能 没有相关接口,待对齐 export function createOrganizationApi(params: { groupName: string, groupDesc: string }): Promise<UnitRes<CreateOrganizationApiResultType>> {
export function getOrganizationInfoApi(params) {
return request({ return request({
url: ``, url: `/api/v1/group/create`,
method: 'post',
data: params,
});
}
export function updateOrganizationInfoApi(params: { id: number, name: string, desc: string }): Promise<UnitRes<CreateOrganizationApiResultType>> {
return request({
url: `/api/v1/group/update`,
method: 'post',
data: params,
});
}
export function getOrganizationMemberListApi(params: { groupId: number }): Promise<UnitRes<any>> {
return request({
url: `/api/v1/group/member/list`,
method: 'get', method: 'get',
params, params,
}); });
} }
export function createOrganizationApi(params) { export function inviteOrganizationMemberApi(params: { groupId: number, username: string, roleCode: string }): Promise<UnitRes<boolean>> {
return request({ return request({
url: `/api/v1/user/group/create`, url: `/api/v1/group/member/invite `,
method: 'post', method: 'post',
data: params, data: params,
}); });
} }
// TODO 更新组织信息功能 没有相关接口,待对齐 export function deleteOrganizationMemberApi(params: { groupId: number, username: string }): Promise<UnitRes<boolean>> {
export function updateOrganizationInfoApi(params) {
return request({ return request({
url: `/api/v1/user/group/create`, url: `/api/v1/group/member/remove`,
method: 'post',
data: params,
});
}
export function getOrganizationMemberListApi(params) {
return request({
url: `/api/v1/user/group/member/list`,
method: 'get',
params,
});
}
export function inviteOrganizationMemberApi(params) {
return request({
url: `/api/v1/user/group/member/invite `,
method: 'post',
data: params,
});
}
export function deleteOrganizationMemberApi(params) {
return request({
url: `/api/v1/user/group/member/remove`,
method: 'delete', method: 'delete',
data: params, data: params,
}); });

View File

@@ -1,12 +1,65 @@
import { type AxiosResponse } from "axios";
export interface ApiDefaultType<T> {
data?: {
data?: T;
}
}
export interface CommonRes<T> {
code: number;
msg: string;
data: T;
}
export type UnitRes<T> = AxiosResponse<CommonRes<T>>;
export interface CreateOrganizationApiResultType {
id: number;
name: string;
ext: null;
status: null;
deleted: null;
createUser: string;
createTime: string;
updateTime: null;
}
export interface OrganizationInfoType { export interface OrganizationInfoType {
groupId: number;
organizationName: string; organizationName: string;
organizationProfile: string; organizationProfile: string;
} }
export interface OrganizationMemberItemType { export interface UserInfoType {
id: string; username: string;
userName: string; mobile: null;
role: string;
email: string; email: string;
joinDate: string; avatar: string;
noticeUnreadNum: number;
inviteNum: number;
groupId: null | number;
groupName: null | string;
groupDesc: null | string;
}
export enum OrganizationMemberRoleEnum {
OWNER = 'OWNER',
MEMBER = 'MEMBER',
}
export enum OrganizationMemberStatusEnum {
TO_ACCEPTED = 0,
ACCEPTED = 1,
}
export interface OrganizationMemberItemType {
id: number;
groupId: number;
name: string; // 组织名称
username: string;
roleCode: OrganizationMemberRoleEnum;
status: OrganizationMemberStatusEnum;
createTime: string;
updateTime: string;
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="mt-3"> <div v-loading="searchOrganizationLoading" class="mt-3">
<div v-if="hasOrganization"> <div v-if="hasOrganization">
<d-card class="mb-[16px] bg-white" shadow="never"> <d-card class="mb-[16px] bg-white" shadow="never">
<div class="text-[14px] w-full flex items-center justify-between"> <div class="text-[14px] w-full flex items-center justify-between">
@@ -36,19 +36,20 @@
</div> </div>
<d-table <d-table
:data="memberTableData" :data="memberTableData"
:show-loading="memberListSearchLoading"
class="w-full mb-[20px] organ-table" class="w-full mb-[20px] organ-table"
:fix-header="memberTableData.length > 0" :fix-header="memberTableData.length > 0"
header-bg header-bg
max-height="500px" max-height="500px"
> >
<d-column field="userName" header="成员名" /> <d-column field="username" header="成员名" />
<d-column field="role" header="角色"> <d-column field="roleCode" header="角色">
<template #default="{ row }"> <template #default="{ row }">
{{ memberRoleMap[row.role] ?? '' }} {{ memberRoleMap[row.roleCode] ?? '' }}
</template> </template>
</d-column> </d-column>
<d-column field="email" header="邮箱" /> <d-column field="email" header="邮箱" />
<d-column field="joinDate" header="加入时间" /> <d-column field="createTime" header="加入时间" />
<d-column header="操作"> <d-column header="操作">
<template #default="{ row }"> <template #default="{ row }">
<d-button size="sm" variant="text" color="primary" class="p-0 justify-start" @click="openDeleteModal(row)">删除</d-button> <d-button size="sm" variant="text" color="primary" class="p-0 justify-start" @click="openDeleteModal(row)">删除</d-button>
@@ -66,6 +67,8 @@
:can-view-total="true" :can-view-total="true"
:can-change-page-size="true" :can-change-page-size="true"
:max-items="5" :max-items="5"
@page-index-change="pagerIndexChange"
@page-size-change="pagerSizeChange"
/> />
</d-card> </d-card>
</div> </div>
@@ -89,7 +92,7 @@
</d-form> </d-form>
<div class="flex justify-center"> <div class="flex justify-center">
<d-button variant="solid" class="mr-[8px]" @click="confirmCreateOrganizationBtnClick">确定</d-button> <d-button :loading="createOrganizationLoading" variant="solid" class="mr-[8px]" @click="confirmCreateOrganizationBtnClick">确定</d-button>
<d-button @click="closeOrganizationModal">取消</d-button> <d-button @click="closeOrganizationModal">取消</d-button>
</div> </div>
</d-modal> </d-modal>
@@ -107,15 +110,15 @@
</d-form> </d-form>
<div class="flex justify-center"> <div class="flex justify-center">
<d-button variant="solid" class="mr-[8px]" @click="inviteMemberConfirmBtnClick">确定</d-button> <d-button variant="solid" class="mr-[8px]" :loading="inviteMemberLoading" @click="inviteMemberConfirmBtnClick">确定</d-button>
<d-button @click="closeInviteMemberModal">取消</d-button> <d-button @click="closeInviteMemberModal">取消</d-button>
</div> </div>
</d-modal> </d-modal>
<d-modal v-model="deleteMemberModalCtrl" title="删除成员" class="w-[600px]"> <d-modal v-model="deleteMemberModalCtrl" title="删除成员" class="w-[600px]">
<div class="mb-[20px]">即将删除成员‘{{ deleteRow.userName }}’,请确认是否继续?</div> <div class="mb-[20px]">即将删除成员‘{{ deleteRow.username }}’,请确认是否继续?</div>
<div class="flex justify-center"> <div class="flex justify-center">
<d-button variant="solid" class="mr-[8px]" @click="deleteMember">确定</d-button> <d-button variant="solid" class="mr-[8px]" :loading="deleteMemberLoading" @click="deleteMember">确定</d-button>
<d-button @click="closeDeleteMemberModal">取消</d-button> <d-button @click="closeDeleteMemberModal">取消</d-button>
</div> </div>
</d-modal> </d-modal>
@@ -123,24 +126,38 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, shallowRef } from 'vue'; import { reactive, ref, shallowRef } from 'vue';
import { Message } from 'vue-devui';
import NoData from '@/components/NoData/NoData.vue'; import NoData from '@/components/NoData/NoData.vue';
import { import {
createOrganizationApi, createOrganizationApi,
deleteOrganizationMemberApi, deleteOrganizationMemberApi,
getOrganizationInfoApi,
getOrganizationMemberListApi, getOrganizationMemberListApi,
inviteOrganizationMemberApi, inviteOrganizationMemberApi,
updateOrganizationInfoApi updateOrganizationInfoApi
} from '@/api/organizationManage/organizationManageApi'; } from '@/api/organizationManage/organizationManageApi';
import { import {
type OrganizationInfoType, type OrganizationInfoType,
type OrganizationMemberItemType type OrganizationMemberItemType,
OrganizationMemberRoleEnum,
type UserInfoType,
} from '@/api/organizationManage/organizationManageType'; } from '@/api/organizationManage/organizationManageType';
import table from '@/components/AIRepair/Table.vue'; import {getUserInfo} from "@/api/user";
const userInfo = shallowRef<UserInfoType>({
username: '',
mobile: null,
email: '',
avatar: '',
noticeUnreadNum: 0,
inviteNum: 0,
groupId: null,
groupName: null,
groupDesc: null,
});
const searchOrganizationLoading = ref(false); const searchOrganizationLoading = ref(false);
const hasOrganization = ref(false); const hasOrganization = ref(false);
const organizationInfo = shallowRef<OrganizationInfoType>({ const organizationInfo = shallowRef<OrganizationInfoType>({
groupId: 0,
organizationName: '', organizationName: '',
organizationProfile: '' organizationProfile: ''
}); });
@@ -158,6 +175,8 @@ const editLoading = ref(false);
const memberListSearchLoading = ref(false); const memberListSearchLoading = ref(false);
const memberListSearchParam = ref(''); const memberListSearchParam = ref('');
let originMemberList: OrganizationMemberItemType[] = [];
let filterMemberList: OrganizationMemberItemType[] = [];
const memberTableData = shallowRef<OrganizationMemberItemType[]>([]); const memberTableData = shallowRef<OrganizationMemberItemType[]>([]);
const pager = reactive({ const pager = reactive({
pageSize: 10, pageSize: 10,
@@ -177,45 +196,40 @@ const inviteMemberFormData = reactive({
role: '' role: ''
}); });
const inviteMemberSelectOptions = [ const inviteMemberSelectOptions = [
{ name: '创建者', value: 'creator' }, { name: '创建者', value: OrganizationMemberRoleEnum.OWNER },
{ name: '成员', value: 'member' } { name: '成员', value: OrganizationMemberRoleEnum.MEMBER }
]; ];
const memberRoleMap = { const memberRoleMap = {
creator: '创建者', [OrganizationMemberRoleEnum.OWNER]: '创建者',
member: '成员' [OrganizationMemberRoleEnum.MEMBER]: '成员'
}; };
const mockTableData = [ init();
{ userName: '张三', role: 'member', email: '111@gmail.com', joinDate: '2090-02-30', id: '1' }, function init() {
{ userName: '李四', role: 'creator', email: '111@gmail.com', joinDate: '2090-02-30', id: '2' }, queryUserInfo();
{ userName: '王五', role: 'member', email: '111@gmail.com', joinDate: '2090-02-30', id: '3' },
{ userName: '赵六', role: 'member', email: '111@gmail.com', joinDate: '2090-02-30', id: '4' },
{ userName: '秦七', role: 'member', email: '111@gmail.com', joinDate: '2090-02-30', id: '5' }
];
// -------------------- 获取组织信息 --------------------
async function getOrganizationInfo() {
const params = {
organizationName: createFormData.organizationName,
organizationProfile: createFormData.organizationProfile
};
searchOrganizationLoading.value = true;
try {
const res = await getOrganizationInfoApi(params);
} catch (e) {}
searchOrganizationLoading.value = false;
getMemberList();
// TODO 待接口定义好后删除下面两行固定赋值语句
hasOrganization.value = true;
organizationInfo.value = {
organizationName: createFormData.organizationName,
organizationProfile: createFormData.organizationProfile
};
} }
// -------------------- 获取成员信息 -------------------- // -------------------- 获取组织信息 --------------------
async function getOrganizationMember(organizationId: string) { async function queryUserInfo() {
const params = {}; searchOrganizationLoading.value = true;
try {
const res = await getUserInfo();
if (res.data?.data?.code === 200) {
userInfo.value = res.data?.data.data;
}
if (userInfo.value.groupId) {
hasOrganization.value = true;
organizationInfo.value = {
groupId: userInfo.value.groupId,
organizationName: userInfo.value.groupName as string,
organizationProfile: userInfo.value.groupDesc as string,
};
getMemberList();
}
} catch (e) {
Message.error('查询用户信息失败');
}
searchOrganizationLoading.value = false;
} }
// -------------------- 创建组织 -------------------- // -------------------- 创建组织 --------------------
@@ -229,16 +243,21 @@ function confirmCreateOrganizationBtnClick() {
async function createOrganization() { async function createOrganization() {
const params = { const params = {
organizationName: createFormData.organizationName, groupName: createFormData.organizationName,
organizationProfile: createFormData.organizationProfile groupDesc: createFormData.organizationProfile
}; };
createOrganizationLoading.value = true; createOrganizationLoading.value = true;
try { try {
const res = await createOrganizationApi(params); const res = await createOrganizationApi(params);
} catch (e) {} if (res.data?.code !== 200) {
Message.error(res.data?.msg || '创建失败');
} else {
closeOrganizationModal(); closeOrganizationModal();
// TODO 待接口定义好后删除下面调用逻辑 queryUserInfo();
getOrganizationInfo(); }
} catch (e) {
Message.error('接口错误,创建失败');
}
createOrganizationLoading.value = false; createOrganizationLoading.value = false;
} }
@@ -247,31 +266,46 @@ function openCreateOrganizationModal() {
} }
function closeOrganizationModal() { function closeOrganizationModal() {
createFormData.organizationName = '';
createFormData.organizationProfile = '';
createOrganizationModalCtrl.value = false; createOrganizationModalCtrl.value = false;
} }
// -------------------- 编辑组织信息 -------------------- // -------------------- 编辑组织信息 --------------------
function editIconClick() { function editIconClick() {
createFormData.organizationName = organizationInfo.value.organizationName;
createFormData.organizationProfile = organizationInfo.value.organizationProfile;
isEdit.value = true; isEdit.value = true;
} }
async function editOrganizationConfirm() { async function editOrganizationConfirm() {
if (!createFormData.organizationName || !createFormData.organizationProfile) {
Message.warning('组织名称和组织简介不能为空');
return;
}
editLoading.value = true; editLoading.value = true;
const params = { const params = {
organizationName: createFormData.organizationName, id: organizationInfo.value.groupId,
organizationProfile: createFormData.organizationProfile name: createFormData.organizationName,
desc: createFormData.organizationProfile
}; };
try { try {
const res = await updateOrganizationInfoApi(params); const res = await updateOrganizationInfoApi(params);
} catch (e) {} if (res.data?.code === 200) {
organizationInfo.value = {
groupId: organizationInfo.value.groupId,
...createFormData,
};
createFormData.organizationName = '';
createFormData.organizationProfile = '';
} else {
Message.error(res.data?.msg || '更新失败');
}
} catch (e) {
Message.error('接口错误,更新失败');
}
editLoading.value = false; editLoading.value = false;
isEdit.value = false; isEdit.value = false;
// TODO 待接口定义好后删除下面两行固定赋值语句
hasOrganization.value = true;
organizationInfo.value = {
organizationName: createFormData.organizationName,
organizationProfile: createFormData.organizationProfile
};
} }
function editOrganizationCancel() { function editOrganizationCancel() {
@@ -282,21 +316,41 @@ function editOrganizationCancel() {
// -------------------- 邀请、查询成员 -------------------- // -------------------- 邀请、查询成员 --------------------
async function getMemberList() { async function getMemberList() {
const params = {
organizationName: createFormData.organizationName,
pageIndex: pager.pageIndex,
pageSize: pager.pageSize,
searchParam: memberListSearchParam.value
};
memberListSearchLoading.value = true; memberListSearchLoading.value = true;
try { try {
const res = await getOrganizationMemberListApi(params); const res = await getOrganizationMemberListApi({ groupId: organizationInfo.value.groupId });
} catch (e) {} if (res.data?.code === 200) {
memberTableData.value = mockTableData; originMemberList = res.data?.data;
pager.total = 6; updateFilterTableList();
} else {
Message.warning(res.data?.msg || '查询失败');
}
} catch (e) {
Message.error('接口错误,查询失败');
}
memberListSearchLoading.value = false; memberListSearchLoading.value = false;
} }
function updateFilterTableList() {
const queryStr = memberListSearchParam.value;
filterMemberList = queryStr ? originMemberList.filter(item => item.username.includes(queryStr)) : originMemberList;
updateCurrentPageTableList();
}
function updateCurrentPageTableList() {
const endIndex = pager.pageIndex * pager.pageSize;
memberTableData.value = filterMemberList.slice(endIndex - pager.pageSize, endIndex);
}
function pagerIndexChange() {
updateCurrentPageTableList();
}
function pagerSizeChange() {
pager.pageIndex = 1;
updateCurrentPageTableList();
}
function openInviteMemberModal() { function openInviteMemberModal() {
inviteMemberModalCtrl.value = true; inviteMemberModalCtrl.value = true;
} }
@@ -309,7 +363,6 @@ function openDeleteModal(row: any) {
function inviteMemberConfirmBtnClick() { function inviteMemberConfirmBtnClick() {
inviteMemberFormRef.value.validate((isValid: boolean) => { inviteMemberFormRef.value.validate((isValid: boolean) => {
if (isValid) { if (isValid) {
console.log('aaaaaaaa');
inviteMember(); inviteMember();
} }
}); });
@@ -317,24 +370,24 @@ function inviteMemberConfirmBtnClick() {
async function inviteMember() { async function inviteMember() {
const params = { const params = {
userName: inviteMemberFormData.userName, groupId: organizationInfo.value.groupId,
role: inviteMemberFormData.role username: inviteMemberFormData.userName,
roleCode: inviteMemberFormData.role
}; };
inviteMemberLoading.value = true; inviteMemberLoading.value = true;
try { try {
const res = await inviteOrganizationMemberApi(params); const res = await inviteOrganizationMemberApi(params);
} catch (e) {} if (res.data?.data) {
Message.success('邀请成功');
getMemberList();
} else {
Message.warning(res.data?.msg || '邀请失败');
}
} catch (e) {
Message.warning('接口错误,邀请失败');
}
inviteMemberLoading.value = false; inviteMemberLoading.value = false;
closeInviteMemberModal(); closeInviteMemberModal();
// TODO 待接口定义好后删除下面调用逻辑
mockTableData.unshift({
userName: inviteMemberFormData.userName,
role: inviteMemberFormData.role,
joinDate: new Date().toDateString(),
id: String(pager.total++),
email: `${inviteMemberFormData.userName}@gmail.com`
});
memberTableData.value = [...mockTableData];
} }
function closeInviteMemberModal() { function closeInviteMemberModal() {
@@ -343,19 +396,23 @@ function closeInviteMemberModal() {
async function deleteMember() { async function deleteMember() {
const params = { const params = {
id: deleteRow.value.id groupId: organizationInfo.value.groupId,
username: deleteRow.value.username
}; };
deleteMemberLoading.value = true; deleteMemberLoading.value = true;
try { try {
const res = await deleteOrganizationMemberApi(params); const res = await deleteOrganizationMemberApi(params);
} catch (e) {} if (res.data?.data) {
Message.success('删除成功');
getMemberList();
} else {
Message.error(res.data?.msg || '删除失败');
}
} catch (e) {
Message.warning('接口错误,删除失败');
}
deleteMemberLoading.value = false; deleteMemberLoading.value = false;
closeDeleteMemberModal(); closeDeleteMemberModal();
// TODO 待接口定义好后删除下面调用逻辑
const index = mockTableData.findIndex((item) => item.id === deleteRow.value.id);
mockTableData.splice(index, 1);
memberTableData.value = [...mockTableData];
pager.total--;
} }
function closeDeleteMemberModal() { function closeDeleteMemberModal() {