feat(component): 实现组件审核功能并优化项目标识验证

master
钟良源 2 months ago
parent 42021a122d
commit fd9da62ad8

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef, useCallback } from 'react';
import { import {
Modal, Modal,
Form, Form,
@ -184,13 +184,17 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'c
if (res.code === 200) setTagsList(res.data); if (res.code === 200) setTagsList(res.data);
}; };
// 防抖 timer ref
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
// 验证项目标识函数
const validateProjectId = async (projectId: string) => { const validateProjectId = async (projectId: string) => {
if (!projectId) return; if (!projectId) return;
try { try {
const res = await compProjectValidate(projectId); const res = await compProjectValidate(projectId);
if (res.data === false) { if (res.data === false) {
// 项目标识已存在设置表单字段错误 // 项目标识已存在,设置表单字段错误
form.setFields({ form.setFields({
projectId: { projectId: {
value: projectId, value: projectId,
@ -201,7 +205,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'c
}); });
} }
else { else {
// 项目标识可用清除错误 // 项目标识可用,清除错误
form.setFields({ form.setFields({
projectId: { projectId: {
value: projectId, value: projectId,
@ -222,6 +226,28 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'c
} }
}; };
// 防抖后的验证函数
const debouncedValidateProjectId = useCallback((projectId: string) => {
// 清除之前的定时器
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
// 设置新的定时器
debounceTimerRef.current = setTimeout(() => {
validateProjectId(projectId);
}, 500); // 500ms 防抖延迟
}, [form]);
// 组件卸载时清除定时器
useEffect(() => {
return () => {
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current);
}
};
}, []);
const onSubmit = async (showMessage = true) => { const onSubmit = async (showMessage = true) => {
try { try {
await form.validate(); await form.validate();
@ -593,7 +619,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'c
allowClear allowClear
placeholder="请输入代码标识" placeholder="请输入代码标识"
disabled={created || isEditMode} disabled={created || isEditMode}
onChange={(e) => validateProjectId(e)} onChange={(e) => debouncedValidateProjectId(e)}
/> />
</FormItem> </FormItem>
</Grid.Col> </Grid.Col>

@ -0,0 +1,262 @@
import React, { useEffect, useState } from 'react';
import { Pagination, Table, Tag, Button, Space, Message, Rate } from '@arco-design/web-react';
import styles from '@/pages/componentDevelopment/componentList/style/index.module.less';
import { getReviewGroupByNew } from '@/api/componentMarket';
import dayjs from 'dayjs';
// 审核记录接口定义
interface ReviewRecord {
id: string;
identifier: string;
componentBaseId: string;
componentClassify: string;
name: string;
reviewOpinion: string;
componentVersion: number;
recommend: string;
attachmentAddress: string;
publicStatus: number;
stars: number;
reviewUserName: string;
filesName: string;
createTime: string;
updateTime: string;
}
// 发布状态映射
const PUBLIC_STATUS_MAP = {
0: { text: '待审核', color: 'orange' },
1: { text: '审核通过', color: 'green' },
2: { text: '审核拒绝', color: 'red' },
3: { text: '已发布', color: 'arcoblue' }
};
const CompAudit = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState<ReviewRecord[]>([]);
const [pagination, setPagination] = useState({
totalCount: 0,
pageSize: 10,
totalPage: 0,
currPage: 1
});
const columns = [
{
title: '组件名称',
dataIndex: 'name',
width: 150
},
{
title: '分类',
dataIndex: 'componentClassify',
width: 120
},
{
title: '组件标识',
dataIndex: 'identifier',
width: 180
},
{
title: '组件版本',
dataIndex: 'componentVersion',
width: 100,
render: (version: number) => `v${version}`
},
{
title: '发布状态',
dataIndex: 'publicStatus',
width: 120,
render: (status: number) => {
const statusInfo = PUBLIC_STATUS_MAP[status] || { text: '未知', color: 'gray' };
return <Tag color={statusInfo.color}>{statusInfo.text}</Tag>;
}
},
{
title: '组件评分',
dataIndex: 'stars',
width: 150,
render: (stars: number) => {
if (stars < 0) return <span style={{ color: '#999' }}></span>;
return <Rate disabled value={stars} />;
}
},
{
title: '推荐度',
dataIndex: 'recommend',
width: 100,
render: (recommend: string) => {
const level = parseInt(recommend);
const colors = ['red', 'orange', 'blue', 'green', 'arcoblue'];
return <Tag color={colors[level - 1] || 'gray'}> {recommend}</Tag>;
}
},
{
title: '审核人',
dataIndex: 'reviewUserName',
width: 120
},
{
title: '审核意见',
dataIndex: 'reviewOpinion',
width: 200,
render: (opinion: string) => opinion || '-'
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180,
render: (time: string) => dayjs(time).format('YYYY-MM-DD HH:mm:ss')
},
{
title: '操作',
dataIndex: 'operations',
width: 200,
fixed: 'right' as const,
render: (_, record: ReviewRecord) => (
<Space>
<Button
type="text"
size="small"
onClick={() => handleViewDetail(record)}
>
</Button>
{record.publicStatus === 0 && (
<>
<Button
type="text"
size="small"
status="success"
onClick={() => handleApprove(record)}
>
</Button>
<Button
type="text"
size="small"
status="danger"
onClick={() => handleReject(record)}
>
</Button>
</>
)}
{record.attachmentAddress && (
<Button
type="text"
size="small"
onClick={() => handleDownloadAttachment(record)}
>
</Button>
)}
</Space>
)
}
];
// 获取组件审核列表数据
const fetchComponentReview = async () => {
setLoading(true);
try {
const res: any = await getReviewGroupByNew({
queryType: 'create',
current: pagination.currPage,
size: pagination.pageSize
});
console.log('组件审核列表:', res);
if (res.code === 200 && res.data) {
setData(res.data.records || []);
setPagination({
totalCount: res.data.total || 0,
pageSize: res.data.size || 10,
totalPage: res.data.pages || 0,
currPage: res.data.current || 1
});
}
else {
Message.error(res.msg || '获取审核列表失败');
}
} catch (error) {
console.error('获取审核列表失败:', error);
Message.error('获取审核列表失败');
} finally {
setLoading(false);
}
};
// 查看详情
const handleViewDetail = (record: ReviewRecord) => {
// TODO: 实现查看详情逻辑
console.log('查看详情:', record);
Message.info('查看详情功能待实现');
};
// 审核通过
const handleApprove = (record: ReviewRecord) => {
// TODO: 实现审核通过逻辑
console.log('审核通过:', record);
Message.success('审核通过操作待实现');
};
// 审核拒绝
const handleReject = (record: ReviewRecord) => {
// TODO: 实现审核拒绝逻辑
console.log('审核拒绝:', record);
Message.warning('审核拒绝操作待实现');
};
// 下载附件
const handleDownloadAttachment = (record: ReviewRecord) => {
if (record.attachmentAddress) {
window.open(record.attachmentAddress, '_blank');
}
};
// 分页变化处理
const handlePageChange = (page: number, pageSize?: number) => {
setPagination({
...pagination,
currPage: page,
pageSize: pageSize || pagination.pageSize
});
};
// 监听分页变化
useEffect(() => {
fetchComponentReview();
}, [pagination.currPage, pagination.pageSize]);
return (
<>
<Table
columns={columns}
data={data}
loading={loading}
pagination={false}
scroll={{ x: 1800, y: 'calc(100vh - 280px)' }}
border={{
wrapper: true,
cell: true
}}
rowKey="id"
/>
<div className={styles['pagination-container']}>
<Pagination
current={pagination.currPage}
pageSize={pagination.pageSize}
total={pagination.totalCount}
onChange={handlePageChange}
showTotal
showJumper
sizeCanChange
/>
</div>
</>
);
};
export default CompAudit;

@ -10,13 +10,14 @@ import {
getImportComponentInfo, getImportComponentInfo,
importComponent importComponent
} from '@/api/componentBase'; } from '@/api/componentBase';
import { getReviewGroupByNew, deleteComponentMarket } from '@/api/componentMarket'; import { deleteComponentMarket } from '@/api/componentMarket';
import { componentRelease, componentRevoke } from '@/api/componentRelease'; import { componentRelease, componentRevoke } from '@/api/componentRelease';
import { ComponentItem } from '@/api/interface'; import { ComponentItem } from '@/api/interface';
import AddComponentModal from '@/pages/componentDevelopment/componentList/addComponentModal'; import AddComponentModal from '@/pages/componentDevelopment/componentList/addComponentModal';
import PublishComponentModal from '@/pages/componentDevelopment/componentList/publishComponentModal'; import PublishComponentModal from '@/pages/componentDevelopment/componentList/publishComponentModal';
import ImportComponentModal from '@/pages/componentDevelopment/componentList/importComponentModal'; import ImportComponentModal from '@/pages/componentDevelopment/componentList/importComponentModal';
import HandleButtonGroup from '@/pages/componentDevelopment/componentList/handleButtonGroup'; import HandleButtonGroup from '@/pages/componentDevelopment/componentList/handleButtonGroup';
import CompAudit from '@/pages/componentDevelopment/componentList/compAudit';
import { import {
componentStatusConstant, componentStatusConstant,
componentStatusDict, componentStatusDict,
@ -253,9 +254,6 @@ const GlobalVarContainer = () => {
fetchComponentData(); fetchComponentData();
}, 0); }, 0);
} }
else if (selectedItem === '组件审核') {
fetchComponentReview();
}
}, [selectedItem, searchValue]); }, [selectedItem, searchValue]);
// 监听来自其他页面的搜索关键词 // 监听来自其他页面的搜索关键词
@ -284,7 +282,7 @@ const GlobalVarContainer = () => {
if (res.code === 200) { if (res.code === 200) {
setShowOffSaleModal(false); setShowOffSaleModal(false);
setOffSaleComponent(null); setOffSaleComponent(null);
fetchComponentReview(); fetchComponentData();
} }
else { else {
Modal.error({ Modal.error({
@ -307,7 +305,8 @@ const GlobalVarContainer = () => {
Message.success('取消发布成功'); Message.success('取消发布成功');
// 重新获取数据以更新状态 // 重新获取数据以更新状态
fetchComponentData(); fetchComponentData();
} else { }
else {
Message.error(res.message || '取消发布失败'); Message.error(res.message || '取消发布失败');
} }
} catch (error) { } catch (error) {
@ -417,17 +416,6 @@ const GlobalVarContainer = () => {
} }
}; };
// 获取组件审核列表数据
const fetchComponentReview = async () => {
const res: any = await getReviewGroupByNew({
queryType: 'create',
current: pagination.currPage,
size: pagination.pageSize
});
console.log('组件审核列表:', res);
};
const handlePageChange = (page: number, pageSize?: number) => { const handlePageChange = (page: number, pageSize?: number) => {
setPagination({ setPagination({
...pagination, ...pagination,
@ -543,6 +531,8 @@ const GlobalVarContainer = () => {
))} ))}
</div> </div>
<div className={styles['comp-list-content']}> <div className={styles['comp-list-content']}>
{selectedItem !== '组件审核' && (
<>
{/*头部*/} {/*头部*/}
<div className={styles['comp-list-header']}> <div className={styles['comp-list-header']}>
<div className={styles['comp-list-search']}> <div className={styles['comp-list-search']}>
@ -617,7 +607,7 @@ const GlobalVarContainer = () => {
</div> </div>
{/*数据列表*/} {/*数据列表*/}
{selectedItem !== '组件审核' && (<div className={styles['comp-list-list']}> <div className={styles['comp-list-list']}>
<Table <Table
columns={columns} columns={columns}
data={componentData} data={componentData}
@ -637,7 +627,13 @@ const GlobalVarContainer = () => {
onChange={handlePageChange} onChange={handlePageChange}
/> />
</div> </div>
</div>)} </div>
</>
)}
{selectedItem === '组件审核' && (
<CompAudit />
)}
</div> </div>
</div> </div>

Loading…
Cancel
Save