From 61ee43ae04367bcb8f1060535683e28da40b2ff4 Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 16 Jan 2026 16:37:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(componentAudit):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=AE=A1=E6=A0=B8=E5=8A=9F=E8=83=BD=E5=92=8C?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/componentMarket.ts | 18 +- src/api/interface/index.ts | 20 +- .../componentList/compAudit.tsx | 477 +++++++++++++++--- 3 files changed, 441 insertions(+), 74 deletions(-) diff --git a/src/api/componentMarket.ts b/src/api/componentMarket.ts index cdf8490..1a31c27 100644 --- a/src/api/componentMarket.ts +++ b/src/api/componentMarket.ts @@ -1,5 +1,11 @@ import axios from 'axios'; -import { ComponentMarketParams, PublishComponentParams, ReviewGroup } from '@/api/interface'; +import { + ComponentHistoryReview, + ComponentMarketParams, + ComponentReviewNew, + PublishComponentParams, + ReviewGroup +} from '@/api/interface'; // 公共路径 const urlPrefix = '/api/v1/bpms-workbench'; @@ -9,6 +15,16 @@ export function getReviewGroupByNew(params: ReviewGroup) { return axios.get(`${urlPrefix}/componentMarket/reviewGroupByNew`, { params }); } +// 获取组件历史审核记录 +export function getComponentHistoryReview(params: ComponentHistoryReview) { + return axios.get(`${urlPrefix}/componentMarket/reviewGroupVersion`, { params }); +} + +// 管理员审核接口 +export function reviewComponentMarket(params: ComponentReviewNew) { + return axios.post(`${urlPrefix}/componentMarket/compoentReviewNew`, params); +} + // 复制组件设计 export function copyDesignMarket(params) { return axios.post(`${urlPrefix}/componentMarket/copyDesign`, params); diff --git a/src/api/interface/index.ts b/src/api/interface/index.ts index 28ea901..9176c31 100644 --- a/src/api/interface/index.ts +++ b/src/api/interface/index.ts @@ -38,9 +38,9 @@ export interface queryParams { } export interface historyPageParams { - "pageSize": number, - "currPage": number, - "appId": string + 'pageSize': number, + 'currPage': number, + 'appId': string } export interface apiResData { @@ -271,6 +271,20 @@ export interface ReviewGroup { size?: number; } +export interface ComponentHistoryReview { + identifier: string; + componentVersion: number; + size?: number; + current?: number; +} + +export interface ComponentReviewNew { + id: number; + reason: string; + reviewResult: number; + stars: number; +} + export interface ComponentMarketParams { componentClassify: string; keyword: string; diff --git a/src/pages/componentDevelopment/componentList/compAudit.tsx b/src/pages/componentDevelopment/componentList/compAudit.tsx index ca44e28..c4c99b0 100644 --- a/src/pages/componentDevelopment/componentList/compAudit.tsx +++ b/src/pages/componentDevelopment/componentList/compAudit.tsx @@ -1,7 +1,20 @@ import React, { useEffect, useState } from 'react'; -import { Pagination, Table, Tag, Button, Space, Message, Rate } from '@arco-design/web-react'; +import { + Pagination, + Table, + Tag, + Button, + Space, + Message, + Rate, + Modal, + Select, + Radio, + Input, + Form +} from '@arco-design/web-react'; import styles from '@/pages/componentDevelopment/componentList/style/index.module.less'; -import { getReviewGroupByNew } from '@/api/componentMarket'; +import { getReviewGroupByNew, getComponentHistoryReview, reviewComponentMarket } from '@/api/componentMarket'; import dayjs from 'dayjs'; // 审核记录接口定义 @@ -23,12 +36,26 @@ interface ReviewRecord { updateTime: string; } +// 历史审核记录接口定义 +interface HistoryAuditRecord { + reviewOpinion: string; + reviewUserName: string; + createTime: string; + publicStatus: number; +} + +interface HistoryRecord { + main: ReviewRecord; + historyAudit: HistoryAuditRecord[]; +} + // 发布状态映射 const PUBLIC_STATUS_MAP = { - 0: { text: '待审核', color: 'orange' }, - 1: { text: '审核通过', color: 'green' }, - 2: { text: '审核拒绝', color: 'red' }, - 3: { text: '已发布', color: 'arcoblue' } + '-1': { text: '未发布', color: 'orange' }, + 0: { text: '未发布', color: 'orange' }, + 1: { text: '已发布', color: 'green' }, + 2: { text: '审核中', color: 'arcoblue' }, + 3: { text: '审核被拒', color: 'red' } }; const CompAudit = () => { @@ -41,6 +68,115 @@ const CompAudit = () => { currPage: 1 }); + // 历史记录弹窗状态 + const [historyModalVisible, setHistoryModalVisible] = useState(false); + const [historyLoading, setHistoryLoading] = useState(false); + const [historyData, setHistoryData] = useState([]); + const [currentRecord, setCurrentRecord] = useState(null); + + // 审核弹窗状态 + const [reviewModalVisible, setReviewModalVisible] = useState(false); + const [reviewLoading, setReviewLoading] = useState(false); + const [form] = Form.useForm(); + + const RadioGroup = Radio.Group; + const TextArea = Input.TextArea; + + // 历史记录表格列定义 + const historyColumns = [ + { + title: '组件名称', + dataIndex: 'name', + width: 150, + render: (_, record: HistoryRecord) => record.main.name + }, + { + title: '分类', + dataIndex: 'componentClassify', + width: 120, + render: (_, record: HistoryRecord) => record.main.componentClassify + }, + { + title: '组件标识', + dataIndex: 'identifier', + width: 180, + render: (_, record: HistoryRecord) => record.main.identifier + }, + { + title: '组件版本', + dataIndex: 'componentVersion', + width: 100, + render: (_, record: HistoryRecord) => `v${record.main.componentVersion}` + }, + { + title: '发布状态', + dataIndex: 'publicStatus', + width: 120, + render: (_, record: HistoryRecord) => { + const statusInfo = PUBLIC_STATUS_MAP[record.main.publicStatus] || { text: '未知', color: 'gray' }; + return {statusInfo.text}; + } + }, + { + title: '组件评分', + dataIndex: 'stars', + width: 200, + render: (_, record: HistoryRecord) => { + if (record.main.stars < 0) return 暂无评分; + return ; + } + }, + { + title: '组件介绍', + dataIndex: 'recommend', + width: 100, + render: (_, record: HistoryRecord) => record.main.recommend + }, + { + title: '审核人', + dataIndex: 'reviewUserName', + width: 120, + render: (_, record: HistoryRecord) => record.main.reviewUserName + }, + { + title: '审核结果', + dataIndex: 'reviewOpinion', + render: (_, record: HistoryRecord) => record.main.reviewOpinion || '-' + }, + { + title: '组件附件', + dataIndex: 'attachmentAddress', + width: 120, + render: (_, record: HistoryRecord) => { + if (!record.main.attachmentAddress) return '-'; + return ( + + ); + } + } + // { + // title: '操作', + // dataIndex: 'operations', + // width: 100, + // fixed: 'right' as const, + // render: (_, record: HistoryRecord) => ( + // + // ) + // } + ]; + const columns = [ { title: '组件名称', @@ -75,21 +211,16 @@ const CompAudit = () => { { title: '组件评分', dataIndex: 'stars', - width: 150, + width: 200, render: (stars: number) => { if (stars < 0) return 暂无评分; - return ; + return ; } }, { - title: '推荐度', + title: '组件介绍', dataIndex: 'recommend', - width: 100, - render: (recommend: string) => { - const level = parseInt(recommend); - const colors = ['red', 'orange', 'blue', 'green', 'arcoblue']; - return 等级 {recommend}; - } + width: 100 }, { title: '审核人', @@ -97,17 +228,11 @@ const CompAudit = () => { width: 120 }, { - title: '审核意见', + title: '审核结果', dataIndex: 'reviewOpinion', - width: 200, + // 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', @@ -118,37 +243,17 @@ const CompAudit = () => { - {record.publicStatus === 0 && ( - <> - - - - )} - {record.attachmentAddress && ( + {record.publicStatus === 2 && ( )} @@ -166,10 +271,8 @@ const CompAudit = () => { size: pagination.pageSize }); - console.log('组件审核列表:', res); - if (res.code === 200 && res.data) { - setData(res.data.records || []); + setData(res.data.list || []); setPagination({ totalCount: res.data.total || 0, pageSize: res.data.size || 10, @@ -188,31 +291,177 @@ const CompAudit = () => { } }; - // 查看详情 - const handleViewDetail = (record: ReviewRecord) => { - // TODO: 实现查看详情逻辑 - console.log('查看详情:', record); - Message.info('查看详情功能待实现'); + // 下载组件附件 + const handleDownloadAttachments = (attachmentAddress: string) => { + if (!attachmentAddress) { + Message.warning('暂无附件'); + return; + } + + // 按逗号分割多个文件地址 + const fileUrls = attachmentAddress.split(',').map(url => url.trim()).filter(url => url); + + if (fileUrls.length === 0) { + Message.warning('暂无附件'); + return; + } + + // 下载所有文件 + fileUrls.forEach((url, index) => { + // 延迟下载,避免浏览器阻止多个下载 + setTimeout(() => { + // 使用 fetch 下载文件 + fetch(url) + .then(response => response.blob()) + .then(blob => { + const blobUrl = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = blobUrl; + link.download = url.split('/').pop() || `attachment-${index + 1}`; + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + // 释放 blob URL + window.URL.revokeObjectURL(blobUrl); + }) + .catch(error => { + console.error('下载失败:', error); + // 如果 fetch 失败,尝试直接打开链接 + window.open(url, '_blank'); + }); + }, index * 500); // 每个文件间隔500ms + }); + + Message.success(`开始下载 ${fileUrls.length} 个文件`); }; - // 审核通过 - const handleApprove = (record: ReviewRecord) => { - // TODO: 实现审核通过逻辑 - console.log('审核通过:', record); - Message.success('审核通过操作待实现'); + // 组件审核 + const handleViewReview = (record: ReviewRecord) => { + setCurrentRecord(record); + setReviewModalVisible(true); + // 初始化表单 + form.setFieldsValue({ + reviewResult: 1, // 默认通过 + stars: 0, + reason: '' + }); + }; + + // 提交审核 + const handleSubmitReview = async () => { + try { + const values = await form.validate(); + + if (!currentRecord) { + Message.error('当前记录不存在'); + return; + } + + setReviewLoading(true); + + const params = { + id: Number(currentRecord.id), + reviewResult: values.reviewResult, + stars: values.stars, + reason: values.reason || '' + }; + + const res: any = await reviewComponentMarket(params); + + if (res.code === 200) { + Message.success('审核成功'); + setReviewModalVisible(false); + form.resetFields(); + // 刷新列表 + fetchComponentReview(); + } + else { + Message.error(res.msg || '审核失败'); + } + } catch (error) { + console.error('审核失败:', error); + if (error?.errors) { + // 表单验证失败 + return; + } + Message.error('审核失败'); + } finally { + setReviewLoading(false); + } }; - // 审核拒绝 - const handleReject = (record: ReviewRecord) => { - // TODO: 实现审核拒绝逻辑 - console.log('审核拒绝:', record); - Message.warning('审核拒绝操作待实现'); + + // 查看审核历史 + const handleGetHistory = async (record: ReviewRecord) => { + setCurrentRecord(record); + setHistoryModalVisible(true); + setHistoryLoading(true); + + try { + const res: any = await getComponentHistoryReview({ + identifier: record.identifier, + componentVersion: record.componentVersion + }); + + if (res.code === 200 && res.data) { + setHistoryData(res.data.list || []); + } + else { + Message.error(res.msg || '获取审核历史失败'); + } + } catch (error) { + console.error('获取审核历史失败:', error); + Message.error('获取审核历史失败'); + } finally { + setHistoryLoading(false); + } }; - // 下载附件 - const handleDownloadAttachment = (record: ReviewRecord) => { - if (record.attachmentAddress) { - window.open(record.attachmentAddress, '_blank'); + // 查看历史记录详情 + const handleViewHistoryDetail = (record: HistoryRecord) => { + // 展开显示历史审核记录 + if (record.historyAudit && record.historyAudit.length > 0) { + Modal.info({ + title: '历史审核记录', + style: { width: 800 }, + content: ( +
+ dayjs(time).format('YYYY-MM-DD HH:mm:ss') + }, + { + title: '审核人', + dataIndex: 'reviewUserName' + }, + { + title: '审核状态', + dataIndex: 'publicStatus', + render: (status: number) => { + const statusInfo = PUBLIC_STATUS_MAP[status] || { text: '未知', color: 'gray' }; + return {statusInfo.text}; + } + }, + { + title: '审核意见', + dataIndex: 'reviewOpinion', + render: (opinion: string) => opinion || '-' + } + ]} + data={record.historyAudit} + pagination={false} + border + /> + + ) + }); + } + else { + Message.info('暂无历史审核记录'); } }; @@ -255,6 +504,94 @@ const CompAudit = () => { sizeCanChange /> + + {/* 审核历史弹窗 */} + setHistoryModalVisible(false)} + footer={null} + style={{ width: '90%', maxWidth: 1400, minWidth: 800 }} + > +
+
+ + + + {/* 组件审核弹窗 */} + { + setReviewModalVisible(false); + form.resetFields(); + }} + onOk={handleSubmitReview} + confirmLoading={reviewLoading} + okText="确定" + cancelText="取消" + > +
+ + {currentRecord?.attachmentAddress ? ( + + ) : ( + 暂无附件 + )} + + + + + + + + + 通过 + 拒绝 + + + + +