2025-03-25 08:04:35 +08:00
|
|
|
|
import React, { useState, useEffect } from 'react';
|
2025-03-13 09:14:25 +08:00
|
|
|
|
import SvgIcon from './SvgIcon';
|
|
|
|
|
|
2025-03-25 08:04:35 +08:00
|
|
|
|
// 部门和组别的映射关系
|
|
|
|
|
const departmentGroups = {
|
2025-04-13 01:49:41 +08:00
|
|
|
|
达人部门: ['达人'],
|
|
|
|
|
商务部门: ['商务'],
|
|
|
|
|
样本中心: ['样本'],
|
|
|
|
|
产品部门: ['产品'],
|
2025-04-13 01:37:23 +08:00
|
|
|
|
AI自媒体: ['AI自媒体'],
|
|
|
|
|
HR: ['HR'],
|
2025-04-13 01:49:41 +08:00
|
|
|
|
技术部门: ['技术'],
|
2025-03-25 08:04:35 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 部门列表
|
|
|
|
|
const departments = Object.keys(departmentGroups);
|
|
|
|
|
|
2025-03-13 09:14:25 +08:00
|
|
|
|
/**
|
|
|
|
|
* 创建知识库模态框组件
|
|
|
|
|
* @param {Object} props
|
|
|
|
|
* @param {boolean} props.show - 是否显示弹窗
|
|
|
|
|
* @param {Object} props.formData - 表单数据
|
|
|
|
|
* @param {Object} props.formErrors - 表单错误信息
|
|
|
|
|
* @param {boolean} props.isSubmitting - 是否正在提交
|
|
|
|
|
* @param {Function} props.onClose - 关闭弹窗的回调函数
|
|
|
|
|
* @param {Function} props.onChange - 表单输入变化的回调函数
|
|
|
|
|
* @param {Function} props.onSubmit - 提交表单的回调函数
|
2025-03-22 10:13:42 +08:00
|
|
|
|
* @param {Object} props.currentUser - 当前用户信息
|
2025-03-13 09:14:25 +08:00
|
|
|
|
*/
|
2025-03-25 08:04:35 +08:00
|
|
|
|
const CreateKnowledgeBaseModal = ({
|
|
|
|
|
show,
|
|
|
|
|
formData,
|
|
|
|
|
formErrors,
|
|
|
|
|
isSubmitting,
|
|
|
|
|
onClose,
|
|
|
|
|
onChange,
|
2025-03-22 10:13:42 +08:00
|
|
|
|
onSubmit,
|
2025-03-25 08:04:35 +08:00
|
|
|
|
currentUser,
|
2025-03-22 10:13:42 +08:00
|
|
|
|
}) => {
|
|
|
|
|
// 根据用户角色确定可以创建的知识库类型
|
|
|
|
|
const isAdmin = currentUser?.role === 'admin';
|
|
|
|
|
const isLeader = currentUser?.role === 'leader';
|
2025-03-25 08:04:35 +08:00
|
|
|
|
|
|
|
|
|
// 获取当前用户的部门和组别
|
|
|
|
|
const userDepartment = currentUser?.department || '';
|
|
|
|
|
|
|
|
|
|
// 可选的组别列表
|
|
|
|
|
const [availableGroups, setAvailableGroups] = useState([]);
|
|
|
|
|
|
|
|
|
|
// 当部门变化时更新可用的组别
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (formData.department && departmentGroups[formData.department]) {
|
|
|
|
|
setAvailableGroups(departmentGroups[formData.department]);
|
|
|
|
|
} else {
|
|
|
|
|
setAvailableGroups([]);
|
|
|
|
|
}
|
|
|
|
|
}, [formData.department]);
|
|
|
|
|
|
|
|
|
|
// 提前返回需要放在所有 Hooks 之后
|
|
|
|
|
if (!show) return null;
|
|
|
|
|
|
2025-03-22 10:13:42 +08:00
|
|
|
|
// 获取当前用户可以创建的知识库类型
|
|
|
|
|
const getAvailableTypes = () => {
|
|
|
|
|
if (isAdmin) {
|
|
|
|
|
return [
|
2025-03-25 09:47:30 +08:00
|
|
|
|
{ value: 'admin', label: '公共知识库' },
|
2025-03-29 09:36:38 +08:00
|
|
|
|
{ value: 'leader', label: '组长级知识库' },
|
|
|
|
|
{ value: 'member', label: '组内知识库' },
|
2025-03-22 10:13:42 +08:00
|
|
|
|
{ value: 'private', label: '私有知识库' },
|
2025-03-29 09:36:38 +08:00
|
|
|
|
{ value: 'secret', label: '私密知识库' },
|
2025-03-22 10:13:42 +08:00
|
|
|
|
];
|
|
|
|
|
} else if (isLeader) {
|
|
|
|
|
return [
|
2025-03-25 09:47:30 +08:00
|
|
|
|
{ value: 'admin', label: '公共知识库' },
|
2025-03-29 09:36:38 +08:00
|
|
|
|
{ value: 'member', label: '组内知识库' },
|
2025-03-25 08:04:35 +08:00
|
|
|
|
{ value: 'private', label: '私有知识库' },
|
2025-03-22 10:13:42 +08:00
|
|
|
|
];
|
|
|
|
|
} else {
|
2025-03-25 09:47:30 +08:00
|
|
|
|
return [
|
|
|
|
|
{ value: 'admin', label: '公共知识库' },
|
|
|
|
|
{ value: 'private', label: '私有知识库' },
|
|
|
|
|
];
|
2025-03-22 10:13:42 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const availableTypes = getAvailableTypes();
|
|
|
|
|
|
2025-03-25 08:04:35 +08:00
|
|
|
|
// 判断是否需要选择组别
|
2025-04-03 08:00:46 +08:00
|
|
|
|
const needDepartmentAndGroup = formData.type === 'member' || formData.type === 'leader';
|
|
|
|
|
const needSelectGroup = needDepartmentAndGroup;
|
2025-03-25 08:04:35 +08:00
|
|
|
|
|
2025-03-13 09:14:25 +08:00
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className='modal-backdrop'
|
|
|
|
|
style={{
|
|
|
|
|
position: 'fixed',
|
|
|
|
|
top: 0,
|
|
|
|
|
left: 0,
|
|
|
|
|
right: 0,
|
|
|
|
|
bottom: 0,
|
|
|
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
zIndex: 1050,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
className='modal-content bg-white rounded shadow'
|
|
|
|
|
style={{
|
|
|
|
|
width: '500px',
|
|
|
|
|
maxWidth: '90%',
|
|
|
|
|
padding: '20px',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className='modal-header d-flex justify-content-between align-items-center mb-3'>
|
|
|
|
|
<h5 className='modal-title m-0'>新建知识库</h5>
|
|
|
|
|
<button
|
|
|
|
|
type='button'
|
|
|
|
|
className='btn-close'
|
|
|
|
|
onClick={onClose}
|
|
|
|
|
aria-label='Close'
|
|
|
|
|
disabled={isSubmitting}
|
|
|
|
|
></button>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='modal-body'>
|
|
|
|
|
<div className='mb-3'>
|
|
|
|
|
<label htmlFor='name' className='form-label'>
|
|
|
|
|
知识库名称 <span className='text-danger'>*</span>
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
className={`form-control ${formErrors.name ? 'is-invalid' : ''}`}
|
|
|
|
|
id='name'
|
|
|
|
|
name='name'
|
|
|
|
|
value={formData.name}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
{formErrors.name && <div className='invalid-feedback'>{formErrors.name}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
<div className='mb-3'>
|
|
|
|
|
<label htmlFor='desc' className='form-label'>
|
|
|
|
|
知识库描述 <span className='text-danger'>*</span>
|
|
|
|
|
</label>
|
|
|
|
|
<textarea
|
|
|
|
|
className={`form-control ${formErrors.desc ? 'is-invalid' : ''}`}
|
|
|
|
|
id='desc'
|
|
|
|
|
name='desc'
|
|
|
|
|
rows='3'
|
|
|
|
|
value={formData.desc}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
></textarea>
|
|
|
|
|
{formErrors.desc && <div className='invalid-feedback'>{formErrors.desc}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
<div className='mb-3'>
|
|
|
|
|
<label className='form-label'>
|
|
|
|
|
知识库类型 <span className='text-danger'>*</span>
|
|
|
|
|
</label>
|
2025-03-22 10:13:42 +08:00
|
|
|
|
<div className='d-flex flex-wrap gap-3'>
|
|
|
|
|
{availableTypes.map((type, index) => (
|
|
|
|
|
<div className='form-check' key={index}>
|
|
|
|
|
<input
|
|
|
|
|
className='form-check-input'
|
|
|
|
|
type='radio'
|
|
|
|
|
name='type'
|
|
|
|
|
id={`type${type.value}`}
|
|
|
|
|
value={type.value}
|
|
|
|
|
checked={formData.type === type.value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
<label className='form-check-label' htmlFor={`type${type.value}`}>
|
|
|
|
|
{type.label}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
2025-03-13 09:14:25 +08:00
|
|
|
|
</div>
|
2025-03-22 10:13:42 +08:00
|
|
|
|
{!isAdmin && !isLeader && (
|
|
|
|
|
<small className='text-muted d-block mt-1'>
|
2025-03-25 09:47:30 +08:00
|
|
|
|
您可以创建公共知识库(所有人可访问)或私有知识库(仅自己可访问)。
|
2025-03-22 10:13:42 +08:00
|
|
|
|
</small>
|
|
|
|
|
)}
|
2025-03-13 09:14:25 +08:00
|
|
|
|
{formErrors.type && <div className='text-danger small mt-1'>{formErrors.type}</div>}
|
|
|
|
|
</div>
|
2025-03-25 08:04:35 +08:00
|
|
|
|
|
2025-04-03 08:00:46 +08:00
|
|
|
|
{/* 仅当不是私有知识库且需要部门和组别时才显示部门选项 */}
|
|
|
|
|
{needDepartmentAndGroup && (
|
2025-03-25 08:04:35 +08:00
|
|
|
|
<div className='mb-3'>
|
|
|
|
|
<label htmlFor='department' className='form-label'>
|
|
|
|
|
部门 {isAdmin && needSelectGroup && <span className='text-danger'>*</span>}
|
|
|
|
|
</label>
|
|
|
|
|
{isAdmin ? (
|
|
|
|
|
// 管理员可以选择任意部门
|
|
|
|
|
<select
|
|
|
|
|
className={`form-select ${formErrors.department ? 'is-invalid' : ''}`}
|
|
|
|
|
id='department'
|
|
|
|
|
name='department'
|
|
|
|
|
value={formData.department || ''}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
disabled={isSubmitting}
|
|
|
|
|
>
|
|
|
|
|
<option value=''>请选择部门</option>
|
|
|
|
|
{departments.map((dept, index) => (
|
|
|
|
|
<option key={index} value={dept}>
|
|
|
|
|
{dept}
|
|
|
|
|
</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
) : (
|
|
|
|
|
// 非管理员显示只读字段
|
|
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
className='form-control bg-light'
|
|
|
|
|
id='department'
|
|
|
|
|
name='department'
|
|
|
|
|
value={formData.department || ''}
|
|
|
|
|
readOnly
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{formErrors.department && (
|
|
|
|
|
<div className='text-danger small mt-1'>{formErrors.department}</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-04-03 08:00:46 +08:00
|
|
|
|
{/* 仅当不是私有知识库且需要部门和组别时才显示组别选项 */}
|
|
|
|
|
{needDepartmentAndGroup && (
|
2025-03-25 08:04:35 +08:00
|
|
|
|
<div className='mb-3'>
|
|
|
|
|
<label htmlFor='group' className='form-label'>
|
|
|
|
|
组别 {needSelectGroup && <span className='text-danger'>*</span>}
|
|
|
|
|
</label>
|
|
|
|
|
{isAdmin || (isLeader && needSelectGroup) ? (
|
|
|
|
|
// 管理员可以选择任意组别,组长只能选择自己部门下的组别
|
|
|
|
|
<select
|
|
|
|
|
className={`form-select ${formErrors.group ? 'is-invalid' : ''}`}
|
|
|
|
|
id='group'
|
|
|
|
|
name='group'
|
|
|
|
|
value={formData.group || ''}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
disabled={isSubmitting || (isAdmin && !formData.department)}
|
|
|
|
|
>
|
|
|
|
|
<option value=''>{formData.department ? '请选择组别' : '请先选择部门'}</option>
|
|
|
|
|
{availableGroups.map((group, index) => (
|
|
|
|
|
<option key={index} value={group}>
|
|
|
|
|
{group}
|
|
|
|
|
</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
) : (
|
|
|
|
|
// 普通用户显示只读字段
|
|
|
|
|
<input
|
|
|
|
|
type='text'
|
|
|
|
|
className='form-control bg-light'
|
|
|
|
|
id='group'
|
|
|
|
|
name='group'
|
|
|
|
|
value={formData.group || ''}
|
|
|
|
|
readOnly
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{formErrors.group && <div className='text-danger small mt-1'>{formErrors.group}</div>}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-03-13 09:14:25 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div className='modal-footer gap-2'>
|
|
|
|
|
<button type='button' className='btn btn-secondary' onClick={onClose} disabled={isSubmitting}>
|
|
|
|
|
取消
|
|
|
|
|
</button>
|
|
|
|
|
<button type='button' className='btn btn-dark' onClick={onSubmit} disabled={isSubmitting}>
|
|
|
|
|
{isSubmitting ? (
|
|
|
|
|
<>
|
|
|
|
|
<span
|
|
|
|
|
className='spinner-border spinner-border-sm me-2'
|
|
|
|
|
role='status'
|
|
|
|
|
aria-hidden='true'
|
|
|
|
|
></span>
|
|
|
|
|
处理中...
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
'创建'
|
|
|
|
|
)}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default CreateKnowledgeBaseModal;
|