mirror of
https://github.com/Funkoala14/KnowledgeBase_OOIN.git
synced 2025-06-08 05:28:16 +08:00
[dev]pending approve
This commit is contained in:
parent
56c4878065
commit
4c4bfe7e56
@ -20,18 +20,29 @@ export default function AccessRequestModal({
|
|||||||
isSubmitting = false,
|
isSubmitting = false,
|
||||||
}) {
|
}) {
|
||||||
const [accessRequestData, setAccessRequestData] = useState({
|
const [accessRequestData, setAccessRequestData] = useState({
|
||||||
accessType: '只读访问',
|
permissions: {
|
||||||
duration: '一周',
|
can_read: true,
|
||||||
|
can_edit: false,
|
||||||
|
can_delete: false,
|
||||||
|
},
|
||||||
|
duration: '30', // 默认30天
|
||||||
reason: '',
|
reason: '',
|
||||||
});
|
});
|
||||||
const [accessRequestErrors, setAccessRequestErrors] = useState({});
|
const [accessRequestErrors, setAccessRequestErrors] = useState({});
|
||||||
|
|
||||||
const handleAccessRequestInputChange = (e) => {
|
const handleAccessRequestInputChange = (e) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
setAccessRequestData((prev) => ({
|
if (name === 'duration') {
|
||||||
...prev,
|
setAccessRequestData((prev) => ({
|
||||||
[name]: value,
|
...prev,
|
||||||
}));
|
[name]: value,
|
||||||
|
}));
|
||||||
|
} else if (name === 'reason') {
|
||||||
|
setAccessRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[name]: value,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// Clear error when user types
|
// Clear error when user types
|
||||||
if (accessRequestErrors[name]) {
|
if (accessRequestErrors[name]) {
|
||||||
@ -42,6 +53,17 @@ export default function AccessRequestModal({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePermissionChange = (permissionType) => {
|
||||||
|
setAccessRequestData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
permissions: {
|
||||||
|
can_read: true, // 只读权限始终为true
|
||||||
|
can_edit: permissionType === '编辑权限',
|
||||||
|
can_delete: false, // 管理权限暂时不开放
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const validateAccessRequestForm = () => {
|
const validateAccessRequestForm = () => {
|
||||||
const errors = {};
|
const errors = {};
|
||||||
|
|
||||||
@ -59,17 +81,27 @@ export default function AccessRequestModal({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算过期日期
|
||||||
|
const expirationDate = new Date();
|
||||||
|
expirationDate.setDate(expirationDate.getDate() + parseInt(accessRequestData.duration));
|
||||||
|
const expiresAt = expirationDate.toISOString();
|
||||||
|
|
||||||
// 调用父组件的提交函数
|
// 调用父组件的提交函数
|
||||||
onSubmit({
|
onSubmit({
|
||||||
id: knowledgeBaseId,
|
knowledge_base: knowledgeBaseId,
|
||||||
title: knowledgeBaseTitle,
|
permissions: accessRequestData.permissions,
|
||||||
...accessRequestData,
|
reason: accessRequestData.reason,
|
||||||
|
expires_at: expiresAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
setAccessRequestData({
|
setAccessRequestData({
|
||||||
accessType: '只读访问',
|
permissions: {
|
||||||
duration: '一周',
|
can_read: true,
|
||||||
|
can_edit: false,
|
||||||
|
can_delete: false,
|
||||||
|
},
|
||||||
|
duration: '30',
|
||||||
reason: '',
|
reason: '',
|
||||||
});
|
});
|
||||||
setAccessRequestErrors({});
|
setAccessRequestErrors({});
|
||||||
@ -123,9 +155,8 @@ export default function AccessRequestModal({
|
|||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
className='form-select'
|
className='form-select'
|
||||||
name='accessType'
|
value={accessRequestData.permissions.can_edit ? '编辑权限' : '只读访问'}
|
||||||
value={accessRequestData.accessType}
|
onChange={(e) => handlePermissionChange(e.target.value)}
|
||||||
onChange={handleAccessRequestInputChange}
|
|
||||||
>
|
>
|
||||||
<option value='只读访问'>只读访问</option>
|
<option value='只读访问'>只读访问</option>
|
||||||
<option value='编辑权限'>编辑权限</option>
|
<option value='编辑权限'>编辑权限</option>
|
||||||
@ -143,11 +174,13 @@ export default function AccessRequestModal({
|
|||||||
value={accessRequestData.duration}
|
value={accessRequestData.duration}
|
||||||
onChange={handleAccessRequestInputChange}
|
onChange={handleAccessRequestInputChange}
|
||||||
>
|
>
|
||||||
<option value='一周'>一周</option>
|
<option value='7'>7天</option>
|
||||||
<option value='一个月'>一个月</option>
|
<option value='15'>15天</option>
|
||||||
<option value='三个月'>三个月</option>
|
<option value='30'>30天</option>
|
||||||
<option value='六个月'>六个月</option>
|
<option value='60'>60天</option>
|
||||||
<option value='永久'>永久</option>
|
<option value='90'>90天</option>
|
||||||
|
<option value='180'>180天</option>
|
||||||
|
<option value='365'>365天</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className='mb-3'>
|
<div className='mb-3'>
|
||||||
|
@ -127,7 +127,7 @@ export default function HeaderWithNav() {
|
|||||||
<Link
|
<Link
|
||||||
className='dropdown-item'
|
className='dropdown-item'
|
||||||
to='#'
|
to='#'
|
||||||
onClick={() => setShowSettings(true)}
|
// onClick={() => setShowSettings(true)}
|
||||||
>
|
>
|
||||||
个人设置
|
个人设置
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -235,8 +235,8 @@ export default function ChatWindow({ chatId, knowledgeBaseId }) {
|
|||||||
<div
|
<div
|
||||||
key={message.id}
|
key={message.id}
|
||||||
className={`d-flex ${
|
className={`d-flex ${
|
||||||
message.role === 'user' ? 'justify-content-end' : 'justify-content-start'
|
message.role === 'user' ? 'align-item-end' : 'align-item-start'
|
||||||
} mb-3`}
|
} mb-3 flex-column`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`chat-message p-3 rounded-3 ${
|
className={`chat-message p-3 rounded-3 ${
|
||||||
@ -248,9 +248,9 @@ export default function ChatWindow({ chatId, knowledgeBaseId }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className='message-content'>{message.content}</div>
|
<div className='message-content'>{message.content}</div>
|
||||||
<div className='message-time small text-muted mt-1'>
|
</div>
|
||||||
{message.created_at && new Date(message.created_at).toLocaleTimeString()}
|
<div className='message-time small text-muted mt-1'>
|
||||||
</div>
|
{message.created_at && new Date(message.created_at).toLocaleTimeString()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -333,7 +333,7 @@ export default function SettingsTab({ knowledgeBase }) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* User Permissions Manager */}
|
{/* User Permissions Manager */}
|
||||||
<UserPermissionsManager knowledgeBase={knowledgeBase} />
|
{/* <UserPermissionsManager knowledgeBase={knowledgeBase} /> */}
|
||||||
|
|
||||||
{/* Delete confirmation modal */}
|
{/* Delete confirmation modal */}
|
||||||
<DeleteConfirmModal
|
<DeleteConfirmModal
|
||||||
|
@ -260,7 +260,13 @@ const KnowledgeBaseForm = ({
|
|||||||
'保存设置'
|
'保存设置'
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button type='button' className='btn btn-danger' onClick={onDelete} disabled={isSubmitting}>
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn btn-danger'
|
||||||
|
onClick={onDelete}
|
||||||
|
disabled='true'
|
||||||
|
// disabled={isSubmitting}
|
||||||
|
>
|
||||||
删除知识库
|
删除知识库
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -381,17 +381,10 @@ export default function KnowledgeBase() {
|
|||||||
setIsSubmittingRequest(true);
|
setIsSubmittingRequest(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 使用权限服务发送请求
|
// 使用权限服务发送请求 - 通过dispatch调用thunk
|
||||||
await requestKnowledgeBaseAccess(requestData);
|
await dispatch(requestKnowledgeBaseAccess(requestData)).unwrap();
|
||||||
|
|
||||||
dispatch(
|
// Close modal after success
|
||||||
showNotification({
|
|
||||||
message: '权限申请已提交',
|
|
||||||
type: 'success',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Close modal
|
|
||||||
setShowAccessRequestModal(false);
|
setShowAccessRequestModal(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(
|
dispatch(
|
||||||
|
@ -18,11 +18,11 @@ export default function PermissionsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='permissions-container'>
|
<div className='permissions-container'>
|
||||||
<div className='permissions-section mb-4'>
|
<div className='permissions-section mb-4 container my-4'>
|
||||||
<PendingRequests />
|
<PendingRequests />
|
||||||
</div>
|
</div>
|
||||||
{user && user.role === 'admin' && (
|
{user && user.role === 'admin' && (
|
||||||
<div className='permissions-section'>
|
<div className='permissions-section container my-4'>
|
||||||
<UserPermissions />
|
<UserPermissions />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -24,7 +24,7 @@ export default function PendingRequests() {
|
|||||||
|
|
||||||
// 从Redux store获取权限申请列表状态
|
// 从Redux store获取权限申请列表状态
|
||||||
const {
|
const {
|
||||||
results: pendingRequests,
|
results: permissionRequests,
|
||||||
status: fetchStatus,
|
status: fetchStatus,
|
||||||
error: fetchError,
|
error: fetchError,
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
@ -185,32 +185,69 @@ export default function PendingRequests() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 根据状态渲染不同的状态标签
|
||||||
|
const renderStatusBadge = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'approved':
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className='badge bg-success-subtle text-success d-flex align-items-center gap-1'
|
||||||
|
style={{ width: 'fit-content' }}
|
||||||
|
>
|
||||||
|
<SvgIcon className='circle-check' />
|
||||||
|
已批准
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
case 'rejected':
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className='badge bg-danger-subtle text-danger d-flex align-items-center gap-1'
|
||||||
|
style={{ width: 'fit-content' }}
|
||||||
|
>
|
||||||
|
<SvgIcon className='circle-xmark' />
|
||||||
|
已拒绝
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
case 'pending':
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className='badge bg-warning-subtle text-warning d-flex align-items-center gap-1'
|
||||||
|
style={{ width: 'fit-content' }}
|
||||||
|
>
|
||||||
|
待处理
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染加载状态
|
// 渲染加载状态
|
||||||
if (fetchStatus === 'loading' && pendingRequests.length === 0) {
|
if (fetchStatus === 'loading' && permissionRequests.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className='text-center py-5'>
|
<div className='text-center py-5'>
|
||||||
<div className='spinner-border' role='status'>
|
<div className='spinner-border' role='status'>
|
||||||
<span className='visually-hidden'>加载中...</span>
|
<span className='visually-hidden'>加载中...</span>
|
||||||
</div>
|
</div>
|
||||||
<p className='mt-3'>加载待处理申请...</p>
|
<p className='mt-3'>加载权限申请...</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染错误状态
|
// 渲染错误状态
|
||||||
if (fetchStatus === 'failed' && pendingRequests.length === 0) {
|
if (fetchStatus === 'failed' && permissionRequests.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className='alert alert-danger' role='alert'>
|
<div className='alert alert-danger' role='alert'>
|
||||||
{fetchError || '获取待处理申请失败'}
|
{fetchError || '获取权限申请失败'}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染空状态
|
// 渲染空状态
|
||||||
if (pendingRequests.length === 0) {
|
if (permissionRequests.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className='alert alert-info' role='alert'>
|
<div className='alert alert-info' role='alert'>
|
||||||
暂无待处理的权限申请
|
暂无权限申请记录
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -219,12 +256,14 @@ export default function PendingRequests() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='d-flex justify-content-between align-items-center mb-3'>
|
<div className='d-flex justify-content-between align-items-center mb-3'>
|
||||||
<h5 className='mb-0'>待处理申请</h5>
|
<h5 className='mb-0'>权限申请列表</h5>
|
||||||
<div className='badge bg-danger'>{total}个待处理</div>
|
<div className='badge bg-danger'>
|
||||||
|
{permissionRequests.filter((req) => req.status === 'pending').length}个待处理
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='pending-requests-list'>
|
<div className='pending-requests-list'>
|
||||||
{pendingRequests.map((request) => (
|
{permissionRequests.map((request) => (
|
||||||
<div key={request.id} className='pending-request-item' onClick={() => handleRowClick(request)}>
|
<div key={request.id} className='pending-request-item' onClick={() => handleRowClick(request)}>
|
||||||
<div className='request-header'>
|
<div className='request-header'>
|
||||||
<div className='user-info'>
|
<div className='user-info'>
|
||||||
@ -235,7 +274,10 @@ export default function PendingRequests() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='request-content'>
|
<div className='request-content'>
|
||||||
<p className='mb-2'>申请访问:{request.knowledge_base.name}</p>
|
<div className='d-flex justify-content-between align-items-start mb-2'>
|
||||||
|
<p className='mb-0'>申请访问:{request.knowledge_base.name}</p>
|
||||||
|
{renderStatusBadge(request.status)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{request.permissions.can_edit ? (
|
{request.permissions.can_edit ? (
|
||||||
<span
|
<span
|
||||||
@ -264,32 +306,53 @@ export default function PendingRequests() {
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{request.response_message && (
|
||||||
|
<div className='mt-2'>
|
||||||
|
<small className='text-muted'>审批意见: {request.response_message}</small>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className='request-actions'>
|
<div className='request-actions'>
|
||||||
<button
|
{request.status === 'pending' ? (
|
||||||
className='btn btn-outline-danger btn-sm'
|
<>
|
||||||
onClick={(e) => {
|
<button
|
||||||
e.stopPropagation();
|
className='btn btn-outline-danger btn-sm'
|
||||||
handleDirectProcess(request.id, false);
|
onClick={(e) => {
|
||||||
}}
|
e.stopPropagation();
|
||||||
disabled={processingId === request.id && approveRejectStatus === 'loading'}
|
handleDirectProcess(request.id, false);
|
||||||
>
|
}}
|
||||||
{processingId === request.id && approveRejectStatus === 'loading' && !isApproving
|
disabled={processingId === request.id && approveRejectStatus === 'loading'}
|
||||||
? '处理中...'
|
>
|
||||||
: '拒绝'}
|
{processingId === request.id &&
|
||||||
</button>
|
approveRejectStatus === 'loading' &&
|
||||||
<button
|
!isApproving
|
||||||
className='btn btn-outline-success btn-sm'
|
? '处理中...'
|
||||||
onClick={(e) => {
|
: '拒绝'}
|
||||||
e.stopPropagation();
|
</button>
|
||||||
handleDirectProcess(request.id, true);
|
<button
|
||||||
}}
|
className='btn btn-outline-success btn-sm'
|
||||||
disabled={processingId === request.id && approveRejectStatus === 'loading'}
|
onClick={(e) => {
|
||||||
>
|
e.stopPropagation();
|
||||||
{processingId === request.id && approveRejectStatus === 'loading' && isApproving
|
handleDirectProcess(request.id, true);
|
||||||
? '处理中...'
|
}}
|
||||||
: '批准'}
|
disabled={processingId === request.id && approveRejectStatus === 'loading'}
|
||||||
</button>
|
>
|
||||||
|
{processingId === request.id && approveRejectStatus === 'loading' && isApproving
|
||||||
|
? '处理中...'
|
||||||
|
: '批准'}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className='status-text'>
|
||||||
|
{request.status === 'approved' ? '已批准' : '已拒绝'}
|
||||||
|
{request.updated_at && (
|
||||||
|
<small className='text-muted d-block'>
|
||||||
|
{new Date(request.updated_at).toLocaleDateString()}
|
||||||
|
</small>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -13,6 +13,7 @@ export default function UserPermissions() {
|
|||||||
const [selectedUser, setSelectedUser] = useState(null);
|
const [selectedUser, setSelectedUser] = useState(null);
|
||||||
const [showDetailsModal, setShowDetailsModal] = useState(false);
|
const [showDetailsModal, setShowDetailsModal] = useState(false);
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
|
const [statusFilter, setStatusFilter] = useState('all'); // 'all', 'pending', 'approved', 'rejected'
|
||||||
|
|
||||||
// 分页状态
|
// 分页状态
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -62,6 +63,11 @@ export default function UserPermissions() {
|
|||||||
setCurrentPage(1); // 重置到第一页
|
setCurrentPage(1); // 重置到第一页
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleStatusFilterChange = (e) => {
|
||||||
|
setStatusFilter(e.target.value);
|
||||||
|
setCurrentPage(1); // 重置到第一页
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageChange = (page) => {
|
const handlePageChange = (page) => {
|
||||||
if (page > 0 && page <= totalPages) {
|
if (page > 0 && page <= totalPages) {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
@ -76,17 +82,27 @@ export default function UserPermissions() {
|
|||||||
|
|
||||||
// 过滤用户列表
|
// 过滤用户列表
|
||||||
const getFilteredUsers = () => {
|
const getFilteredUsers = () => {
|
||||||
if (!searchTerm.trim()) {
|
let filtered = users;
|
||||||
return users;
|
|
||||||
|
// 应用状态过滤
|
||||||
|
if (statusFilter !== 'all') {
|
||||||
|
filtered = filtered.filter((user) =>
|
||||||
|
user.permissions.some((permission) => permission.status === statusFilter)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return users.filter(
|
// 应用搜索过滤
|
||||||
(user) =>
|
if (searchTerm.trim()) {
|
||||||
user.user_info?.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
filtered = filtered.filter(
|
||||||
user.user_info?.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
(user) =>
|
||||||
user.user_info?.department.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
user.user_info?.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
user.user_info?.role.toLowerCase().includes(searchTerm.toLowerCase())
|
user.user_info?.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
);
|
user.user_info?.department.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
user.user_info?.role.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredUsers = getFilteredUsers();
|
const filteredUsers = getFilteredUsers();
|
||||||
@ -196,22 +212,35 @@ export default function UserPermissions() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{/* <div className='mb-3 d-flex justify-content-between align-items-center'>
|
<div className='mb-3 d-flex justify-content-between align-items-center'>
|
||||||
<div className='search-bar' style={{ maxWidth: '300px' }}>
|
<div className='d-flex gap-3'>
|
||||||
<div className='input-group'>
|
<div className='search-bar' style={{ maxWidth: '300px' }}>
|
||||||
<span className='input-group-text bg-light border-end-0'>
|
<div className='input-group'>
|
||||||
<SvgIcon className='search' />
|
<span className='input-group-text bg-light border-end-0'>
|
||||||
</span>
|
<SvgIcon className='search' />
|
||||||
<input
|
</span>
|
||||||
type='text'
|
<input
|
||||||
className='form-control border-start-0'
|
type='text'
|
||||||
placeholder='搜索用户...'
|
className='form-control border-start-0'
|
||||||
value={searchTerm}
|
placeholder='搜索用户...'
|
||||||
onChange={handleSearchChange}
|
value={searchTerm}
|
||||||
/>
|
onChange={handleSearchChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<select
|
||||||
|
className='form-select'
|
||||||
|
value={statusFilter}
|
||||||
|
onChange={handleStatusFilterChange}
|
||||||
|
style={{ width: 'auto' }}
|
||||||
|
>
|
||||||
|
<option value='all'>全部状态</option>
|
||||||
|
<option value='pending'>待处理</option>
|
||||||
|
<option value='approved'>已批准</option>
|
||||||
|
<option value='rejected'>已拒绝</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div>
|
||||||
|
|
||||||
{loading === 'loading' ? (
|
{loading === 'loading' ? (
|
||||||
<div className='text-center my-5'>
|
<div className='text-center my-5'>
|
||||||
|
@ -214,4 +214,21 @@ export const switchToRealApi = async () => {
|
|||||||
return isServerUp;
|
return isServerUp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 权限相关API
|
||||||
|
export const applyPermission = (data) => {
|
||||||
|
return post('/permissions/', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updatePermission = (data) => {
|
||||||
|
return post('/permissions/update_permission/', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const approvePermission = (permissionId) => {
|
||||||
|
return post(`/permissions/approve_permission/${permissionId}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rejectPermission = (permissionId) => {
|
||||||
|
return post(`/permissions/reject_permission/${permissionId}`);
|
||||||
|
};
|
||||||
|
|
||||||
export { get, post, put, del, upload };
|
export { get, post, put, del, upload };
|
||||||
|
@ -31,7 +31,8 @@ export const calculateExpiresAt = (duration) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 申请知识库访问权限
|
* 申请知识库访问权限(已废弃,请使用store/knowledgeBase/knowledgeBase.thunks中的requestKnowledgeBaseAccess)
|
||||||
|
* @deprecated 请使用Redux thunk版本
|
||||||
* @param {Object} requestData - 请求数据
|
* @param {Object} requestData - 请求数据
|
||||||
* @param {string} requestData.id - 知识库ID
|
* @param {string} requestData.id - 知识库ID
|
||||||
* @param {string} requestData.accessType - 访问类型,如 '只读访问', '编辑权限'
|
* @param {string} requestData.accessType - 访问类型,如 '只读访问', '编辑权限'
|
||||||
@ -39,7 +40,7 @@ export const calculateExpiresAt = (duration) => {
|
|||||||
* @param {string} requestData.reason - 申请原因
|
* @param {string} requestData.reason - 申请原因
|
||||||
* @returns {Promise} - API 请求的 Promise
|
* @returns {Promise} - API 请求的 Promise
|
||||||
*/
|
*/
|
||||||
export const requestKnowledgeBaseAccess = async (requestData) => {
|
export const legacyRequestKnowledgeBaseAccess = async (requestData) => {
|
||||||
const apiRequestData = {
|
const apiRequestData = {
|
||||||
knowledge_base: requestData.id,
|
knowledge_base: requestData.id,
|
||||||
permissions: {
|
permissions: {
|
||||||
|
@ -165,15 +165,17 @@ export const changeKnowledgeBaseType = createAsyncThunk(
|
|||||||
/**
|
/**
|
||||||
* 申请知识库访问权限
|
* 申请知识库访问权限
|
||||||
* @param {Object} params - 参数
|
* @param {Object} params - 参数
|
||||||
* @param {string} params.knowledgeBaseId - 知识库ID
|
* @param {string} params.knowledge_base - 知识库ID
|
||||||
|
* @param {Object} params.permissions - 权限对象
|
||||||
|
* @param {string} params.reason - 申请原因
|
||||||
|
* @param {string} params.expires_at - 过期时间
|
||||||
* @returns {Promise} - Promise对象
|
* @returns {Promise} - Promise对象
|
||||||
*/
|
*/
|
||||||
export const requestKnowledgeBaseAccess = createAsyncThunk(
|
export const requestKnowledgeBaseAccess = createAsyncThunk(
|
||||||
'knowledgeBase/requestAccess',
|
'knowledgeBase/requestAccess',
|
||||||
async (params, { rejectWithValue, dispatch }) => {
|
async (params, { rejectWithValue, dispatch }) => {
|
||||||
try {
|
try {
|
||||||
const { knowledgeBaseId } = params;
|
const response = await post('/permissions/', params);
|
||||||
const response = await post(`/knowledge-bases/${knowledgeBaseId}/request_access/`);
|
|
||||||
dispatch(
|
dispatch(
|
||||||
showNotification({
|
showNotification({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
Loading…
Reference in New Issue
Block a user