import React, { useState, useEffect } from 'react'; import type { EvaluationPoint } from '~/models/evaluation_points'; import type { EvaluationPointGroup } from '~/models/evaluation_point_groups'; interface BasicInfoProps { onChange?: (data: Record) => void; initialData?: EvaluationPoint; evaluationPointGroups?: EvaluationPointGroup[]; riskOptions?: Array<{value: string, label: string}>; } // 评查点基本信息组件 export function BasicInfo({ onChange, initialData, evaluationPointGroups = [], riskOptions = [] }: BasicInfoProps) { const [formData, setFormData] = useState({ risk: 'medium', // 风险等级 默认中风险 is_enabled: true, // 是否启用 默认启用 references_laws: { name: '', articles: [], content: '' }, ...(initialData || {}) // 合并初始数据 }); // 找到当前评查点类型对应的code const getCheckpointTypeCode = () => { if (!formData.evaluation_point_groups_pid) return ""; const typeGroup = evaluationPointGroups.find( group => group.id === formData.evaluation_point_groups_pid && group.pid === 0 ); return typeGroup?.code || ""; }; // 评查点描述与法律依据 展开状态 const [isDescExpanded, setIsDescExpanded] = useState(false); // 条款号临时输入字符串(不会触发自动分割) const [lawArticlesText, setLawArticlesText] = useState(''); // 根据选择的评查点类型筛选可用的规则组 const filteredRuleGroups = evaluationPointGroups.filter(group => formData.evaluation_point_groups_pid && group.pid === formData.evaluation_point_groups_pid && group.is_enabled ); // 获取评查点类型选项(pid=0的数据) const getCheckpointTypeOptions = () => { if (!evaluationPointGroups || evaluationPointGroups.length === 0) { return ( <> ); } const typeGroups = evaluationPointGroups.filter(group => group.pid === 0 && group.is_enabled); return ( <> {typeGroups.map(group => ( ))} ); }; // 评查点描述与法律依据 展开状态 const handleToggleDescription = () => { setIsDescExpanded(!isDescExpanded); }; // 处理表单输入变化 const handleInputChange = (e: React.ChangeEvent) => { const { id, value } = e.target; const newData = { ...formData }; // 映射id到表单字段名 switch(id) { case 'rule-name': newData.name = value; break; case 'rule-code': newData.code = value; break; case 'risk-level': newData.risk = value; break; case 'is-enabled': newData.is_enabled = value === 'true'; break; case 'rule-description': newData.description = value; break; case 'law-name': newData.references_laws = { ...formData.references_laws, name: value }; break; case 'law-content': newData.references_laws = { ...formData.references_laws, content: value }; break; case 'evaluation-point-group': newData.evaluation_point_groups_id = value ? parseInt(value) : null; break; case 'checkpoint-type': // 处理评查点类型选择 if (value) { // 找到选中的类型组 const selectedType = evaluationPointGroups.find(group => group.code === value && group.pid === 0); if (selectedType) { newData.evaluation_point_groups_pid = selectedType.id; } } else { newData.evaluation_point_groups_pid = null; newData.evaluation_point_groups_id = null; // 清空规则组选择 } break; } setFormData(newData); if (onChange) { onChange(newData); } }; // 处理条款号输入框变化 const handleLawArticlesChange = (e: React.ChangeEvent) => { // 设置临时字符串状态,这样不会触发任何处理 setLawArticlesText(e.target.value); }; // 处理条款号输入框失去焦点 const handleLawArticlesBlur = () => { if (!lawArticlesText) return; // 将输入的文本转换为数组 const articles = lawArticlesText .split(',') .map(article => article.trim()) .filter(article => article !== ''); // 创建一个新的引用法律对象,保留现有字段 const referencesLaws = { ...(formData.references_laws || {}), articles: articles.length > 0 ? articles : [] }; // 更新表单数据 const newData = { ...formData, references_laws: referencesLaws }; setFormData(newData); if (onChange) { onChange(newData); } }; // 初始化条款号文本字段 useEffect(() => { if (formData.references_laws?.articles && formData.references_laws.articles.length > 0) { setLawArticlesText(formData.references_laws.articles.join(',')); } }, [formData.references_laws?.articles]); // 检查是否需要自动展开描述区域 useEffect(() => { // 如果描述或法律依据相关字段有值,则自动展开 if ( formData.description || formData.references_laws?.name || (formData.references_laws?.articles && formData.references_laws.articles.length > 0) || formData.references_laws?.content ) { setIsDescExpanded(true); } }, [formData]); // 注释掉自动选择规则组的逻辑,避免无限循环 // 原因:此 useEffect 依赖 onChange 和 filteredRuleGroups,每次渲染都可能触发 // 导致 onChange -> 父组件更新 -> BasicInfo 重新渲染 -> useEffect 再次触发 -> 无限循环 // useEffect(() => { // if (onChange && filteredRuleGroups.length === 1) { // onChange({ evaluation_point_groups_id: filteredRuleGroups[0].id }); // } // }, [filteredRuleGroups, onChange]); return (

基本信息

请使用简洁明了的名称,不超过30个字符
用于系统标识的唯一编码
请定义评查点的风险等级
评查点类型用于分类管理,便于规则统一调用
{!formData.evaluation_point_groups_pid ? "请先选择评查点类型" : filteredRuleGroups.length === 0 ? "该类型下暂无可用规则组" : "选择评查点所属的规则组"}
创建后是否立即启用此评查点
{ if (e.key === 'Enter' || e.key === ' ') { handleToggleDescription(); } }} tabIndex={0} role="button" >
详细描述有助于其他用户了解该评查点的用途
{/* 引用法典输入区域 */}
多个条款用逗号分隔,将自动转换为数组格式
引用的法律条文将在评查结果中显示,帮助用户理解评查规则的法律依据
{/* 预览区域 */}
预览效果
{formData.references_laws?.name || '《中华人民共和国民法典》'}
{formData.references_laws?.articles && formData.references_laws.articles.length > 0 ? formData.references_laws.articles.map((article, index) => ( {article} )) : ( <> 第五百八十五条 第五百八十六条 )}
{formData.references_laws?.content || '当事人应当按照约定全面履行自己的义务。'}
); }