|
|
|
|
@ -0,0 +1,355 @@
|
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { Modal, Select, Button, Message, Table, Space } from '@arco-design/web-react';
|
|
|
|
|
import { IconDelete } from '@arco-design/web-react/icon';
|
|
|
|
|
import { getUserList } from '@/api/user';
|
|
|
|
|
import {
|
|
|
|
|
getCollaboratorList,
|
|
|
|
|
addCollaborator,
|
|
|
|
|
deleteCollaborator
|
|
|
|
|
} from '@/api/componentCollaborator';
|
|
|
|
|
import { ComponentItem } from '@/api/interface';
|
|
|
|
|
|
|
|
|
|
interface ShareCollaborationModalProps {
|
|
|
|
|
visible: boolean;
|
|
|
|
|
componentInfo: ComponentItem | null;
|
|
|
|
|
onCancel: () => void;
|
|
|
|
|
onSuccess?: () => void;
|
|
|
|
|
isReadOnly?: boolean; // 是否为只读模式(协同组件tab下)
|
|
|
|
|
currentPermission?: string; // 当前用户的权限(在协同组件tab下使用)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface User {
|
|
|
|
|
id: string;
|
|
|
|
|
username: string;
|
|
|
|
|
account?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface Collaborator {
|
|
|
|
|
id: string;
|
|
|
|
|
collaboratorId: string;
|
|
|
|
|
collaboratorName: string;
|
|
|
|
|
permission: string;
|
|
|
|
|
createTime?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ShareCollaborationModal: React.FC<ShareCollaborationModalProps> = ({
|
|
|
|
|
visible,
|
|
|
|
|
componentInfo,
|
|
|
|
|
onCancel,
|
|
|
|
|
onSuccess,
|
|
|
|
|
isReadOnly = false,
|
|
|
|
|
currentPermission = 'write'
|
|
|
|
|
}) => {
|
|
|
|
|
const [userList, setUserList] = useState<User[]>([]);
|
|
|
|
|
const [collaboratorList, setCollaboratorList] = useState<Collaborator[]>([]);
|
|
|
|
|
const [selectedUserId, setSelectedUserId] = useState<string>('');
|
|
|
|
|
const [selectedPermission, setSelectedPermission] = useState<string>('write');
|
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [tableLoading, setTableLoading] = useState(false);
|
|
|
|
|
|
|
|
|
|
// 判断是否可以添加协作者(我的组件 或 协同组件中的admin权限)
|
|
|
|
|
const canAdd = !isReadOnly || currentPermission === 'admin';
|
|
|
|
|
// 判断是否可以编辑/删除(只有我的组件可以)
|
|
|
|
|
const canEdit = !isReadOnly;
|
|
|
|
|
|
|
|
|
|
// 权限选项
|
|
|
|
|
const permissionOptions = [
|
|
|
|
|
{ label: '管理', value: 'admin' },
|
|
|
|
|
{ label: '读', value: 'read' },
|
|
|
|
|
{ label: '写', value: 'write' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 获取用户列表
|
|
|
|
|
const fetchUserList = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await getUserList();
|
|
|
|
|
if (res.code === 200 && res.data) {
|
|
|
|
|
setUserList(res.data.records);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取用户列表失败:', error);
|
|
|
|
|
Message.error('获取用户列表失败');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 获取协作者列表
|
|
|
|
|
const fetchCollaboratorList = async () => {
|
|
|
|
|
if (!componentInfo?.id) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
setTableLoading(true);
|
|
|
|
|
const res: any = await getCollaboratorList(componentInfo.id);
|
|
|
|
|
if (res.code === 200 && res.data) {
|
|
|
|
|
setCollaboratorList(res.data);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取协作者列表失败:', error);
|
|
|
|
|
Message.error('获取协作者列表失败');
|
|
|
|
|
} finally {
|
|
|
|
|
setTableLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 添加协作者
|
|
|
|
|
const handleAddCollaborator = async () => {
|
|
|
|
|
if (!selectedUserId) {
|
|
|
|
|
Message.warning('请选择协作者');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!componentInfo?.id) {
|
|
|
|
|
Message.error('组件信息不完整');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否已经添加过该用户
|
|
|
|
|
const existingCollaborator = collaboratorList.find(
|
|
|
|
|
c => c.collaboratorId === selectedUserId
|
|
|
|
|
);
|
|
|
|
|
if (existingCollaborator) {
|
|
|
|
|
Message.warning('该用户已经是协作者');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
const res: any = await addCollaborator({
|
|
|
|
|
componentBaseId: componentInfo.id,
|
|
|
|
|
collaboratorId: selectedUserId,
|
|
|
|
|
permission: selectedPermission
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
Message.success('添加协作者成功');
|
|
|
|
|
setSelectedUserId('');
|
|
|
|
|
setSelectedPermission('write');
|
|
|
|
|
fetchCollaboratorList();
|
|
|
|
|
onSuccess?.();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Message.error(res.msg || '添加协作者失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('添加协作者失败:', error);
|
|
|
|
|
Message.error('添加协作者失败');
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 删除协作者
|
|
|
|
|
const handleDeleteCollaborator = async (collaboratorId: string) => {
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '确认移除',
|
|
|
|
|
content: '确定要移除该协作者吗?',
|
|
|
|
|
okButtonProps: { status: 'danger' },
|
|
|
|
|
onOk: async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await deleteCollaborator({ id: collaboratorId });
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
Message.success('移除协作者成功');
|
|
|
|
|
fetchCollaboratorList();
|
|
|
|
|
onSuccess?.();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Message.error(res.msg || '移除协作者失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('移除协作者失败:', error);
|
|
|
|
|
Message.error('移除协作者失败');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 更新协作者权限
|
|
|
|
|
const handleUpdatePermission = async (collaborator: Collaborator, newPermission: string) => {
|
|
|
|
|
if (!componentInfo?.id) {
|
|
|
|
|
Message.error('组件信息不完整');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await addCollaborator({
|
|
|
|
|
componentBaseId: componentInfo.id,
|
|
|
|
|
collaboratorId: collaborator.collaboratorId,
|
|
|
|
|
permission: newPermission
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
Message.success('权限更新成功');
|
|
|
|
|
fetchCollaboratorList();
|
|
|
|
|
onSuccess?.();
|
|
|
|
|
} else {
|
|
|
|
|
Message.error(res.msg || '权限更新失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('权限更新失败:', error);
|
|
|
|
|
Message.error('权限更新失败');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 表格列定义
|
|
|
|
|
const columns = [
|
|
|
|
|
{
|
|
|
|
|
title: '用户账号',
|
|
|
|
|
dataIndex: 'collaboratorAccount',
|
|
|
|
|
width: 200
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作权限',
|
|
|
|
|
dataIndex: 'permission',
|
|
|
|
|
width: 150,
|
|
|
|
|
render: (permission: string, record: Collaborator) => {
|
|
|
|
|
const permissionMap = {
|
|
|
|
|
read: '读',
|
|
|
|
|
write: '写',
|
|
|
|
|
admin: '管理'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 不可编辑时只显示文本
|
|
|
|
|
if (!canEdit) {
|
|
|
|
|
return <span>{permissionMap[permission] || permission}</span>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 可编辑时显示下拉框
|
|
|
|
|
return (
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="操作权限"
|
|
|
|
|
value={permission}
|
|
|
|
|
onChange={(newPermission) => handleUpdatePermission(record, newPermission)}
|
|
|
|
|
style={{ width: 120 }}
|
|
|
|
|
>
|
|
|
|
|
{permissionOptions.map(option => (
|
|
|
|
|
<Select.Option key={option.value} value={option.value}>
|
|
|
|
|
{option.label}
|
|
|
|
|
</Select.Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
dataIndex: 'operations',
|
|
|
|
|
width: 100,
|
|
|
|
|
render: (_: any, record: Collaborator) => {
|
|
|
|
|
// 不可编辑时不显示删除按钮
|
|
|
|
|
if (!canEdit) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
type="text"
|
|
|
|
|
status="danger"
|
|
|
|
|
icon={<IconDelete />}
|
|
|
|
|
onClick={() => handleDeleteCollaborator(record.id)}
|
|
|
|
|
>
|
|
|
|
|
移除
|
|
|
|
|
</Button>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 当弹窗打开时,获取数据
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (visible) {
|
|
|
|
|
fetchUserList();
|
|
|
|
|
fetchCollaboratorList();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// 关闭时重置状态
|
|
|
|
|
setSelectedUserId('');
|
|
|
|
|
setSelectedPermission('write');
|
|
|
|
|
}
|
|
|
|
|
}, [visible, componentInfo?.id]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Modal
|
|
|
|
|
title="选择协作者"
|
|
|
|
|
visible={visible}
|
|
|
|
|
onCancel={onCancel}
|
|
|
|
|
footer={null}
|
|
|
|
|
style={{ width: 700 }}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ marginBottom: 20 }}>
|
|
|
|
|
<div style={{
|
|
|
|
|
marginBottom: 16,
|
|
|
|
|
padding: '12px 16px',
|
|
|
|
|
background: '#f7f8fa',
|
|
|
|
|
borderRadius: 4
|
|
|
|
|
}}>
|
|
|
|
|
<div style={{ fontWeight: 500, marginBottom: 4 }}>
|
|
|
|
|
协同成员 ({collaboratorList.length})
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 添加协作者表单 - 我的组件或协同组件admin权限可以添加 */}
|
|
|
|
|
{canAdd && (
|
|
|
|
|
<Space style={{ width: '100%', marginBottom: 16 }}>
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="请选择协作者"
|
|
|
|
|
value={selectedUserId}
|
|
|
|
|
onChange={setSelectedUserId}
|
|
|
|
|
style={{ width: 300 }}
|
|
|
|
|
showSearch
|
|
|
|
|
filterOption={(inputValue, option) => {
|
|
|
|
|
const children = option.props?.children;
|
|
|
|
|
if (!children || typeof children !== 'string') return false;
|
|
|
|
|
return children.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{userList.map(user => (
|
|
|
|
|
<Select.Option key={user.id} value={user.id}>
|
|
|
|
|
{user.account || user.username}
|
|
|
|
|
</Select.Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="操作权限"
|
|
|
|
|
value={selectedPermission}
|
|
|
|
|
onChange={setSelectedPermission}
|
|
|
|
|
style={{ width: 150 }}
|
|
|
|
|
>
|
|
|
|
|
{permissionOptions.map(option => (
|
|
|
|
|
<Select.Option key={option.value} value={option.value}>
|
|
|
|
|
{option.label}
|
|
|
|
|
</Select.Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
onClick={handleAddCollaborator}
|
|
|
|
|
loading={loading}
|
|
|
|
|
>
|
|
|
|
|
添加
|
|
|
|
|
</Button>
|
|
|
|
|
</Space>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* 协作者列表 */}
|
|
|
|
|
<Table
|
|
|
|
|
columns={columns}
|
|
|
|
|
data={collaboratorList}
|
|
|
|
|
loading={tableLoading}
|
|
|
|
|
pagination={false}
|
|
|
|
|
border={{
|
|
|
|
|
wrapper: true,
|
|
|
|
|
cell: true
|
|
|
|
|
}}
|
|
|
|
|
noDataElement={
|
|
|
|
|
<div style={{ padding: '40px 0', textAlign: 'center', color: '#999' }}>
|
|
|
|
|
暂无协作者
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default ShareCollaborationModal;
|