Steps + Input.TextArea 实现弹窗内容
目标:
-
以链路时间线的形式展示人才特征模型更新记录;
-
每一条记录都需要展示候选人/更新时间,支持编辑与实时保存;
-
列表无限向下滑动分页。
<Modaltitle="人才特征模型"open={modalOpen}centeredonCancel={() => {setModalOpen(false); setEditingItemId(null);}}footer={null}width={800}maskClosable={false}classNames={{header: styles.modalHeader,content: styles.modal,}}>// 根据 modelDesc 判断 DOM 内容显示{!modelDesc || modelDesc.length === 0 ? (<div className={styles.emptyTip}>暂无人才特征模型数据</div>) : (<div className={styles.timelineContainer}>{/* Steps 放在 map 外部,统一渲染所有步骤 */}<Stepsdirection="vertical"className={styles.steps}progressDotstyle={{ width: '100%' }}>{modelDesc.map((item, index) => (<Steps.Stepkey={index}status="finish"title={<Flex justify="space-between" align="center" className={styles.infoBar}><div style={{ width: 500 }}><Flex gap={20} align="center"><span className={styles.infoItem} style={{ width: '45%' }}><imgsrc="https://xingge-ai.oss-cn-shenzhen.aliyuncs.com/fusi/Users Group Two Rounded.png"style={{ marginRight: 4, verticalAlign: 'middle' }}alt="" width={18} height={18}/>候选人:{item.sourcePosition}</span><span className={styles.infoItem} style={{ width: '65%' }}><imgsrc="https://xingge-ai.oss-cn-shenzhen.aliyuncs.com/fusi/Clock Circle.png"style={{ marginRight: 4, verticalAlign: 'middle' }}alt="" width={18} height={18}/>更新时间:{item.updateTime}</span></Flex></div><div style={{ width: '30%', textAlign: 'right' }}>{editingItemId === item.id ? (<><Buttonsize="small"type="text"style={{ color: '#0057FF' }}onClick={() => saveEdit(item)}loading={modalLoading}>保存</Button><Buttonsize="small"type="text"onClick={() => cancelEdit(item.id)}>取消</Button></>) : (<Buttonicon={<EditOutlined style={{ color: '#0057FF' }} />}size="small"type="text"style={{ color: '#0057FF' }}onClick={() => startEdit(item)}>编辑</Button>)}</div></Flex>}description={<div className={styles.timelineContentWrapper}>{editingItemId === item.id ? (<Input.TextAreavalue={editContents[item.id] || ''}onChange={(e) =>setEditContents((prev) => ({...prev,[item.id]: e.target.value,}))}autoSize={{ minRows: 10, maxRows: 10 }}/>) : (<divdangerouslySetInnerHTML={{ __html: md.render(item.modelContent) }}className={styles.markdownContent}/>)}</div>}/>))}</Steps>{modalLoading && <div className={styles.loading}>加载中...</div>}</div>)}</Modal>
const mockData = {'code': 200,'data': [{'id': 1,'sourcePosition': "王强海",'updateTime': "2025/10/16 14:30",'modelContent': `null\n- 熟练掌握Langchain、RAG等框架,主导AI全链路验证项目,实现百万级PDF结构化处理,精准匹配测试覆盖率95%以上需求。 \n- 具备Q1期刊论文与发明专利科研背景,持续学习AI新技术,高效优化测试流程,提升自动化效率30%以上。 \n- 拥有跨模态处理与系统级工程思维,快速识别集成问题,支持每周1-2次发布评审与全链路验证任务。\n- 熟练使用JIRA、TestRail管理测试流程,主导AI模型全链路验证,确保95%以上覆盖率,精准匹配项目节点交付。 \n- 掌握Langchain、RAG框架,开发自动化测试脚本,优化测试效率30%以上,支持每周1-2次发布评审与跨团队问题解决。 \n- 具备性能压力测试实战经验,持续学习AI新技术,快速识别集成问题,保障AI解决方案稳定部署。\n- 具备抗压能力,学习能力强。\n- 具备抗压能力,学习能力强。\n- 具备抗压能力,学习能力强`},{'id': 2,'sourcePosition': "王强海",'updateTime': "2025/10/16 14:50",'modelContent': `null\n- 熟练掌握Langchain、RAG等框架,主导AI全链路验证项目,实现百万级PDF结构化处理,精准匹配测试覆盖率95%以上需求。 \n- 具备Q1期刊论文与发明专利科研背景,持续学习AI新技术,高效优化测试流程,提升自动化效率30%以上。 \n- 拥有跨模态处理与系统级工程思维,快速识别集成问题,支持每周1-2次发布评审与全链路验证任务。\n- 熟练使用JIRA、TestRail管理测试流程,主导AI模型全链路验证,确保95%以上覆盖率,精准匹配项目节点交付。 \n- 掌握Langchain、RAG框架,开发自动化测试脚本,优化测试效率30%以上,支持每周1-2次发布评审与跨团队问题解决。 \n- 具备性能压力测试实战经验,持续学习AI新技术,快速识别集成问题,保障AI解决方案稳定部署。\n- 具备抗压能力,学习能力强`},{'id': 3,'sourcePosition': "王强海",'updateTime': "2025/10/16 15:30",'modelContent': `null\n- 熟练掌握Langchain、RAG等框架,主导AI全链路验证项目,实现百万级PDF结构化处理,精准匹配测试覆盖率95%以上需求。 \n- 具备Q1期刊论文与发明专利科研背景,持续学习AI新技术,高效优化测试流程,提升自动化效率30%以上。 \n- 拥有跨模态处理与系统级工程思维,快速识别集成问题,支持每周1-2次发布评审与全链路验证任务。\n- 熟练使用JIRA、TestRail管理测试流程,主导AI模型全链路验证,确保95%以上覆盖率,精准匹配项目节点交付。 \n- 掌握Langchain、RAG框架,开发自动化测试脚本,优化测试效率30%以上,支持每周1-2次发布评审与跨团队问题解决。 \n- 具备性能压力测试实战经验,持续学习AI新技术,快速识别集成问题,保障AI解决方案稳定部署。\n- 具备抗压能力,学习能力强`},{'id': 4,'sourcePosition': "王强海",'updateTime': "2025/10/16 16:30",'modelContent': `null\n- 熟练掌握Langchain、RAG等框架,主导AI全链路验证项目,实现百万级PDF结构化处理,精准匹配测试覆盖率95%以上需求。 \n- 具备Q1期刊论文与发明专利科研背景,持续学习AI新技术,高效优化测试流程,提升自动化效率30%以上。 \n- 拥有跨模态处理与系统级工程思维,快速识别集成问题,支持每周1-2次发布评审与全链路验证任务。\n- 熟练使用JIRA、TestRail管理测试流程,主导AI模型全链路验证,确保95%以上覆盖率,精准匹配项目节点交付。 \n- 掌握Langchain、RAG框架,开发自动化测试脚本,优化测试效率30%以上,支持每周1-2次发布评审与跨团队问题解决。 \n- 具备性能压力测试实战经验,持续学习AI新技术,快速识别集成问题,保障AI解决方案稳定部署。\n- 具备抗压能力,学习能力强`},],'total': 4
};
// 处理模型弹窗const handleModal = async (id) => {setModalOpen(true);try {// const res = await getPersonalityModel({// jobId: id,// });const res = mockDataconsole.log('mockData', res);if (res.code === 200) {// const timelineMarkdown = res.data.map((item, index) => {// return `${item.modelContent}`;// }).join('\n');setModelDesc(res.data || '');return;} else {message.warning('当前职位不存在人才特征模型');setModalOpen(false);return;}} catch (error) {console.log(error);}}const loadMore = async () => {setModalLoading(true);try {const nextPage = currentPage + 1;const startIndex = (nextPage - 1) * pageSize;const res = mockData;if (res.code === 200) {const newData = res.data.slice(startIndex, startIndex + pageSize);setModelDesc([...modelDesc, ...newData]);setCurrentPage(nextPage);}} catch (error) {console.log(error);} finally {setModalLoading(false);}};const startEdit = (item) => {setEditingItemId(item.id);setEditContents((prev) => ({...prev,[item.id]: item.modelContent,}));};const cancelEdit = (itemId) => {setEditingItemId(null);setEditContents((prev) => {const newState = { ...prev };delete newState[itemId];return newState;});};const saveEdit = async (item) => {setModalLoading(true);try {// const res = await savePersonalityModel({// id: item.id,// modelContent: editContents[item.id] || ''// });// 模拟保存接口,实际需替换为真实接口await new Promise((resolve) => setTimeout(resolve, 500));const updatedData = modelDesc.map((modelItem) => {if (modelItem.id === item.id) {return { ...modelItem, modelContent: editContent };}return modelItem;});setModelDesc(updatedData);setEditingItemId(null);message.success('保存成功');} catch (error) {console.log(error);message.error('保存失败');} finally {setModalLoading(false);}};
.modalHeader {background-color: transparent !important;border-bottom: none !important;
}.modal {background-image: url('https://xingge-ai.oss-cn-shenzhen.aliyuncs.com/fusi/image 28.png');background-size: 500px 350px;background-repeat: no-repeat;background-position: right top;min-height: 900px;
}.emptyTip {color: #333;font-size: 16px;font-weight: 500;text-align: center;margin-top: 50%;
}.timelineContainer {max-height: 780px;overflow-y: auto;overflow-x: hidden;padding: 20px 20px 20px 0;
}.timelineItem {display: flex;margin-bottom: 30px;position: relative;
}.steps {margin-right: 10px;:global(.ant-steps-item-title) {color: #000000 !important;padding: 0;width: 700px;}
}.timelineContentWrapper {margin-top: 10px;flex: 1;
}.infoBar {width: 100%;flex-wrap: nowrap;overflow: hidden;.infoItem {color: #767676;font-size: 16px;font-weight: 500;}.actionButtons {}
}.markdownContent {line-height: 1.6;
}.loading {text-align: center;padding: 20px 0;
}
注意⚠:本文只是提供参考,还未联调完善!!!!!