knowledgebase_influencer/src/components/CreateKnowledgeBaseModal.jsx
2025-04-15 21:51:27 -04:00

288 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import SvgIcon from './SvgIcon';
// 部门和组别的映射关系
const departmentGroups = {
达人部门: ['达人'],
商务部门: ['商务'],
样本中心: ['样本'],
产品部门: ['产品'],
AI自媒体: ['AI自媒体'],
HR: ['HR'],
技术部门: ['技术'],
};
// 部门列表
const departments = Object.keys(departmentGroups);
/**
* 创建知识库模态框组件
* @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 - 提交表单的回调函数
* @param {Object} props.currentUser - 当前用户信息
*/
const CreateKnowledgeBaseModal = ({
show,
formData,
formErrors,
isSubmitting,
onClose,
onChange,
onSubmit,
currentUser,
}) => {
// 根据用户角色确定可以创建的知识库类型
const isAdmin = currentUser?.role === 'admin';
const isLeader = currentUser?.role === 'leader';
// 获取当前用户的部门和组别
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;
// 获取当前用户可以创建的知识库类型
const getAvailableTypes = () => {
if (isAdmin) {
return [
{ value: 'admin', label: '公共知识库' },
{ value: 'leader', label: '组长级知识库' },
{ value: 'member', label: '组内知识库' },
{ value: 'private', label: '私有知识库' },
{ value: 'secret', label: '私密知识库' },
];
} else if (isLeader) {
return [
{ value: 'admin', label: '公共知识库' },
{ value: 'member', label: '组内知识库' },
{ value: 'private', label: '私有知识库' },
];
} else {
return [
{ value: 'admin', label: '公共知识库' },
{ value: 'private', label: '私有知识库' },
];
}
};
const availableTypes = getAvailableTypes();
// 判断是否需要选择组别
const needDepartmentAndGroup = formData.type === 'member' || formData.type === 'leader';
const needSelectGroup = needDepartmentAndGroup;
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>
<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>
))}
</div>
{!isAdmin && !isLeader && (
<small className='text-muted d-block mt-1'>
您可以创建公共知识库所有人可访问或私有知识库仅自己可访问
</small>
)}
{formErrors.type && <div className='text-danger small mt-1'>{formErrors.type}</div>}
</div>
{/* 仅当不是私有知识库且需要部门和组别时才显示部门选项 */}
{needDepartmentAndGroup && (
<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>
)}
{/* 仅当不是私有知识库且需要部门和组别时才显示组别选项 */}
{needDepartmentAndGroup && (
<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>
)}
</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;