diff --git a/src/components/AccessRequestModal.jsx b/src/components/AccessRequestModal.jsx
index 5dc4da6..6a8654c 100644
--- a/src/components/AccessRequestModal.jsx
+++ b/src/components/AccessRequestModal.jsx
@@ -20,18 +20,29 @@ export default function AccessRequestModal({
isSubmitting = false,
}) {
const [accessRequestData, setAccessRequestData] = useState({
- accessType: '只读访问',
- duration: '一周',
+ permissions: {
+ can_read: true,
+ can_edit: false,
+ can_delete: false,
+ },
+ duration: '30', // 默认30天
reason: '',
});
const [accessRequestErrors, setAccessRequestErrors] = useState({});
const handleAccessRequestInputChange = (e) => {
const { name, value } = e.target;
- setAccessRequestData((prev) => ({
- ...prev,
- [name]: value,
- }));
+ if (name === 'duration') {
+ setAccessRequestData((prev) => ({
+ ...prev,
+ [name]: value,
+ }));
+ } else if (name === 'reason') {
+ setAccessRequestData((prev) => ({
+ ...prev,
+ [name]: value,
+ }));
+ }
// Clear error when user types
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 errors = {};
@@ -59,17 +81,27 @@ export default function AccessRequestModal({
return;
}
+ // 计算过期日期
+ const expirationDate = new Date();
+ expirationDate.setDate(expirationDate.getDate() + parseInt(accessRequestData.duration));
+ const expiresAt = expirationDate.toISOString();
+
// 调用父组件的提交函数
onSubmit({
- id: knowledgeBaseId,
- title: knowledgeBaseTitle,
- ...accessRequestData,
+ knowledge_base: knowledgeBaseId,
+ permissions: accessRequestData.permissions,
+ reason: accessRequestData.reason,
+ expires_at: expiresAt,
});
// 重置表单
setAccessRequestData({
- accessType: '只读访问',
- duration: '一周',
+ permissions: {
+ can_read: true,
+ can_edit: false,
+ can_delete: false,
+ },
+ duration: '30',
reason: '',
});
setAccessRequestErrors({});
@@ -123,9 +155,8 @@ export default function AccessRequestModal({
diff --git a/src/layouts/HeaderWithNav.jsx b/src/layouts/HeaderWithNav.jsx
index 8013793..a843cf0 100644
--- a/src/layouts/HeaderWithNav.jsx
+++ b/src/layouts/HeaderWithNav.jsx
@@ -127,7 +127,7 @@ export default function HeaderWithNav() {
setShowSettings(true)}
+ // onClick={() => setShowSettings(true)}
>
个人设置
diff --git a/src/pages/Chat/ChatWindow.jsx b/src/pages/Chat/ChatWindow.jsx
index f36fe4e..e80659c 100644
--- a/src/pages/Chat/ChatWindow.jsx
+++ b/src/pages/Chat/ChatWindow.jsx
@@ -235,8 +235,8 @@ export default function ChatWindow({ chatId, knowledgeBaseId }) {
{message.content}
-
- {message.created_at && new Date(message.created_at).toLocaleTimeString()}
-
+
+
+ {message.created_at && new Date(message.created_at).toLocaleTimeString()}
))}
diff --git a/src/pages/KnowledgeBase/Detail/SettingsTab.jsx b/src/pages/KnowledgeBase/Detail/SettingsTab.jsx
index 056fb4f..ae5014b 100644
--- a/src/pages/KnowledgeBase/Detail/SettingsTab.jsx
+++ b/src/pages/KnowledgeBase/Detail/SettingsTab.jsx
@@ -333,7 +333,7 @@ export default function SettingsTab({ knowledgeBase }) {
/>
{/* User Permissions Manager */}
-
+ {/*
*/}
{/* Delete confirmation modal */}
-
diff --git a/src/pages/KnowledgeBase/KnowledgeBase.jsx b/src/pages/KnowledgeBase/KnowledgeBase.jsx
index acf91e7..723d5aa 100644
--- a/src/pages/KnowledgeBase/KnowledgeBase.jsx
+++ b/src/pages/KnowledgeBase/KnowledgeBase.jsx
@@ -381,17 +381,10 @@ export default function KnowledgeBase() {
setIsSubmittingRequest(true);
try {
- // 使用权限服务发送请求
- await requestKnowledgeBaseAccess(requestData);
+ // 使用权限服务发送请求 - 通过dispatch调用thunk
+ await dispatch(requestKnowledgeBaseAccess(requestData)).unwrap();
- dispatch(
- showNotification({
- message: '权限申请已提交',
- type: 'success',
- })
- );
-
- // Close modal
+ // Close modal after success
setShowAccessRequestModal(false);
} catch (error) {
dispatch(
diff --git a/src/pages/Permissions/PermissionsPage.jsx b/src/pages/Permissions/PermissionsPage.jsx
index 37198cb..afb8466 100644
--- a/src/pages/Permissions/PermissionsPage.jsx
+++ b/src/pages/Permissions/PermissionsPage.jsx
@@ -18,11 +18,11 @@ export default function PermissionsPage() {
return (
-
+
{user && user.role === 'admin' && (
-
+
)}
diff --git a/src/pages/Permissions/components/PendingRequests.jsx b/src/pages/Permissions/components/PendingRequests.jsx
index 47d5347..af9377f 100644
--- a/src/pages/Permissions/components/PendingRequests.jsx
+++ b/src/pages/Permissions/components/PendingRequests.jsx
@@ -24,7 +24,7 @@ export default function PendingRequests() {
// 从Redux store获取权限申请列表状态
const {
- results: pendingRequests,
+ results: permissionRequests,
status: fetchStatus,
error: fetchError,
page: currentPage,
@@ -185,32 +185,69 @@ export default function PendingRequests() {
);
};
+ // 根据状态渲染不同的状态标签
+ const renderStatusBadge = (status) => {
+ switch (status) {
+ case 'approved':
+ return (
+
+
+ 已批准
+
+ );
+ case 'rejected':
+ return (
+
+
+ 已拒绝
+
+ );
+ case 'pending':
+ return (
+
+ 待处理
+
+ );
+ default:
+ return null;
+ }
+ };
+
// 渲染加载状态
- if (fetchStatus === 'loading' && pendingRequests.length === 0) {
+ if (fetchStatus === 'loading' && permissionRequests.length === 0) {
return (
加载中...
-
加载待处理申请...
+
加载权限申请...
);
}
// 渲染错误状态
- if (fetchStatus === 'failed' && pendingRequests.length === 0) {
+ if (fetchStatus === 'failed' && permissionRequests.length === 0) {
return (
- {fetchError || '获取待处理申请失败'}
+ {fetchError || '获取权限申请失败'}
);
}
// 渲染空状态
- if (pendingRequests.length === 0) {
+ if (permissionRequests.length === 0) {
return (
- 暂无待处理的权限申请
+ 暂无权限申请记录
);
}
@@ -219,12 +256,14 @@ export default function PendingRequests() {
return (
<>
-
待处理申请
-
{total}个待处理
+
权限申请列表
+
+ {permissionRequests.filter((req) => req.status === 'pending').length}个待处理
+
- {pendingRequests.map((request) => (
+ {permissionRequests.map((request) => (
handleRowClick(request)}>
@@ -235,7 +274,10 @@ export default function PendingRequests() {
-
申请访问:{request.knowledge_base.name}
+
+
申请访问:{request.knowledge_base.name}
+ {renderStatusBadge(request.status)}
+
{request.permissions.can_edit ? (
)}
+
+ {request.response_message && (
+
+ 审批意见: {request.response_message}
+
+ )}
-
{
- e.stopPropagation();
- handleDirectProcess(request.id, false);
- }}
- disabled={processingId === request.id && approveRejectStatus === 'loading'}
- >
- {processingId === request.id && approveRejectStatus === 'loading' && !isApproving
- ? '处理中...'
- : '拒绝'}
-
-
{
- e.stopPropagation();
- handleDirectProcess(request.id, true);
- }}
- disabled={processingId === request.id && approveRejectStatus === 'loading'}
- >
- {processingId === request.id && approveRejectStatus === 'loading' && isApproving
- ? '处理中...'
- : '批准'}
-
+ {request.status === 'pending' ? (
+ <>
+
{
+ e.stopPropagation();
+ handleDirectProcess(request.id, false);
+ }}
+ disabled={processingId === request.id && approveRejectStatus === 'loading'}
+ >
+ {processingId === request.id &&
+ approveRejectStatus === 'loading' &&
+ !isApproving
+ ? '处理中...'
+ : '拒绝'}
+
+
{
+ e.stopPropagation();
+ handleDirectProcess(request.id, true);
+ }}
+ disabled={processingId === request.id && approveRejectStatus === 'loading'}
+ >
+ {processingId === request.id && approveRejectStatus === 'loading' && isApproving
+ ? '处理中...'
+ : '批准'}
+
+ >
+ ) : (
+
+ {request.status === 'approved' ? '已批准' : '已拒绝'}
+ {request.updated_at && (
+
+ {new Date(request.updated_at).toLocaleDateString()}
+
+ )}
+
+ )}
))}
diff --git a/src/pages/Permissions/components/UserPermissions.jsx b/src/pages/Permissions/components/UserPermissions.jsx
index 801226c..42dad52 100644
--- a/src/pages/Permissions/components/UserPermissions.jsx
+++ b/src/pages/Permissions/components/UserPermissions.jsx
@@ -13,6 +13,7 @@ export default function UserPermissions() {
const [selectedUser, setSelectedUser] = useState(null);
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
+ const [statusFilter, setStatusFilter] = useState('all'); // 'all', 'pending', 'approved', 'rejected'
// 分页状态
const [currentPage, setCurrentPage] = useState(1);
@@ -62,6 +63,11 @@ export default function UserPermissions() {
setCurrentPage(1); // 重置到第一页
};
+ const handleStatusFilterChange = (e) => {
+ setStatusFilter(e.target.value);
+ setCurrentPage(1); // 重置到第一页
+ };
+
const handlePageChange = (page) => {
if (page > 0 && page <= totalPages) {
setCurrentPage(page);
@@ -76,17 +82,27 @@ export default function UserPermissions() {
// 过滤用户列表
const getFilteredUsers = () => {
- if (!searchTerm.trim()) {
- return users;
+ let filtered = users;
+
+ // 应用状态过滤
+ if (statusFilter !== 'all') {
+ filtered = filtered.filter((user) =>
+ user.permissions.some((permission) => permission.status === statusFilter)
+ );
}
- return users.filter(
- (user) =>
- user.user_info?.username.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())
- );
+ // 应用搜索过滤
+ if (searchTerm.trim()) {
+ filtered = filtered.filter(
+ (user) =>
+ user.user_info?.username.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();
@@ -196,22 +212,35 @@ export default function UserPermissions() {
<>
- {/*
-
-
-
-
-
-
+
+
+
+
-
*/}
+
{loading === 'loading' ? (
diff --git a/src/services/api.js b/src/services/api.js
index 200e69d..13a9291 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -214,4 +214,21 @@ export const switchToRealApi = async () => {
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 };
diff --git a/src/services/permissionService.js b/src/services/permissionService.js
index c4141ac..a77532e 100644
--- a/src/services/permissionService.js
+++ b/src/services/permissionService.js
@@ -31,7 +31,8 @@ export const calculateExpiresAt = (duration) => {
};
/**
- * 申请知识库访问权限
+ * 申请知识库访问权限(已废弃,请使用store/knowledgeBase/knowledgeBase.thunks中的requestKnowledgeBaseAccess)
+ * @deprecated 请使用Redux thunk版本
* @param {Object} requestData - 请求数据
* @param {string} requestData.id - 知识库ID
* @param {string} requestData.accessType - 访问类型,如 '只读访问', '编辑权限'
@@ -39,7 +40,7 @@ export const calculateExpiresAt = (duration) => {
* @param {string} requestData.reason - 申请原因
* @returns {Promise} - API 请求的 Promise
*/
-export const requestKnowledgeBaseAccess = async (requestData) => {
+export const legacyRequestKnowledgeBaseAccess = async (requestData) => {
const apiRequestData = {
knowledge_base: requestData.id,
permissions: {
diff --git a/src/store/knowledgeBase/knowledgeBase.thunks.js b/src/store/knowledgeBase/knowledgeBase.thunks.js
index 97621d9..00cb565 100644
--- a/src/store/knowledgeBase/knowledgeBase.thunks.js
+++ b/src/store/knowledgeBase/knowledgeBase.thunks.js
@@ -165,15 +165,17 @@ export const changeKnowledgeBaseType = createAsyncThunk(
/**
* 申请知识库访问权限
* @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对象
*/
export const requestKnowledgeBaseAccess = createAsyncThunk(
'knowledgeBase/requestAccess',
async (params, { rejectWithValue, dispatch }) => {
try {
- const { knowledgeBaseId } = params;
- const response = await post(`/knowledge-bases/${knowledgeBaseId}/request_access/`);
+ const response = await post('/permissions/', params);
dispatch(
showNotification({
type: 'success',