From e74b7eedb860f66547aa02e99cbac6d9f0b1aced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E6=80=9D?= Date: Tue, 26 May 2026 14:23:47 +0800 Subject: [PATCH] =?UTF-8?q?ai=E8=B5=84=E6=BA=90=E5=B9=BF=E5=9C=BAbug=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ai/create/index.jsx | 56 +++++++--- src/ai/create/index.scss | 35 ++---- src/ai/detail/index.jsx | 105 +++++++++++++++--- src/ai/detail/index.scss | 25 +++++ src/ai/index.jsx | 19 +++- src/ai/list/index.jsx | 2 +- src/ai/my-resources/index.jsx | 18 ++- src/ai/my-resources/index.scss | 11 ++ src/ai/static.js | 2 +- src/components/ChunkedUpload/index.jsx | 2 +- src/components/commentsByZone/EditComment.jsx | 1 + src/forge/Information/api.js | 3 +- 12 files changed, 209 insertions(+), 70 deletions(-) diff --git a/src/ai/create/index.jsx b/src/ai/create/index.jsx index e7adddd2..b077d3ca 100644 --- a/src/ai/create/index.jsx +++ b/src/ai/create/index.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, Fragment, useRef } from "react"; -import { Input, Select, Upload, message, Form, Checkbox, Tree, Spin } from "antd"; +import { Input, Select, Upload, message, Form, Checkbox, Tree, Spin, Alert } from "antd"; import './index.scss'; import { aiCreateSteps, aiResouceType, aiResouceTypeKey, convertToTreeData } from "../static"; import { Link } from "react-router-dom"; @@ -15,7 +15,7 @@ function CreateResource(props) { const { getFieldDecorator, getFieldsValue, setFieldsValue, validateFields } = form; const type = params.type || aiResouceType[0].key; const sourceId = params.id; //资源id,编辑状态不允许筛选一级分类 - const { user_id } = current_user || {} + const { user_id, login } = current_user || {} const { id: aiZoneId } = aiZoneInfo || {} const [loading, setLoading] = useState(false); @@ -28,6 +28,7 @@ function CreateResource(props) { const [cate, setCate] = useState(); const [info, setInfo] = useState(); const [uploadedFile, setUploadedFile] = useState(null); + const [remark, setRemark] = useState(''); const uploadRef = useRef(null); const typeDetail = type && aiResouceType.find(i => i.key === type); @@ -38,6 +39,13 @@ function CreateResource(props) { const skillTreeData = fileTreeJson && convertToTreeData(JSON.parse(fileTreeJson).children) + // 登录检查:如果未登录则跳转到登录页面 + useEffect(() => { + if (!login) { + history.push(`/login?go_page=${encodeURIComponent(window.location.pathname)}`); + } + }, [login]); + // 自动滚动动画:每 5 秒切换到下一步 useEffect(() => { document.title = `发布新资源`; @@ -104,7 +112,11 @@ function CreateResource(props) { if (sourceId) { getAISourceById(sourceId).then(res => { if (res && res.data && res.data.code === 200) { - const { fileIds, extendData, name, summary, domainId, fileList } = res.data.data || {} + const { fileIds, extendData, name, summary, domainId, fileList, auditStatus, remark: remarkText } = res.data.data || {} + // 如果被驳回(auditStatus=2),保存驳回理由 + if (auditStatus === '2') { + setRemark(remarkText || "请修改后重新提交"); + } const fileInfo = { fileId: fileList[0]?.fileId, fileOriginName: fileList[0]?.fileOriginName, @@ -121,8 +133,8 @@ function CreateResource(props) { file: { response: { fileId: fileIds, - skillMdContent: extendData.skill.content, - fileTreeJson: JSON.stringify(extendData.skill.fileTree) + skillMdContent: extendData.SKILL.content, + fileTreeJson: JSON.stringify(extendData.SKILL.fileTree) } } } : fileValue.fileId = fileIds @@ -145,7 +157,7 @@ function CreateResource(props) { const compelete = (response) => { if (response && response.data && response.data.code === 200) { message.success("操作成功"); - history.push(`/ai/${type}`); + history.push(`/ai/${type}/my`); } } validateFields((err, values) => { @@ -249,6 +261,7 @@ function CreateResource(props) { if (!!sourceId) { e.preventDefault(); e.stopPropagation(); + return; } form.resetFields(); if (uploadRef.current) { @@ -290,6 +303,17 @@ function CreateResource(props) {
基本信息
{typeDetail.createIntro}
+ {remark && ( +
+ +
+ )}
/ {getFieldDecorator('name', { rules: [{ @@ -385,13 +410,13 @@ function CreateResource(props) { {codeCheckBox("ignoreFlag", ".gitignore", ignoreFlag, "ignore", gitignoreList)} {codeCheckBox("licenseFlag", "开源许可证", licenseFlag, "license", licensesList)} - {getFieldDecorator('private')( 将项目设为私有(只有项目所有人或拥有权限的项目成员才能看到) )} - + */} {codeCheckBox("categoreFlag", "项目类别", categoreFlag, "project_category", categoryList)} {codeCheckBox("languageFlag", "项目语言", languageFlag, "project_language", languageList)} : @@ -399,7 +424,7 @@ function CreateResource(props) { {getFieldDecorator('file', { rules: [{ required: true, message: "请上传文件" }], })( - fileByupload ? + responseByupload ?
{ form.setFieldsValue({ file: undefined @@ -408,7 +433,6 @@ function CreateResource(props) { : {getFieldDecorator('summary', { rules: [{ - required: true, message: '请填写简介内容' + required: false, message: '请填写简介内容' }], })( @@ -489,9 +513,11 @@ function CreateResource(props) { })( diff --git a/src/ai/create/index.scss b/src/ai/create/index.scss index c825c883..79dc91d3 100644 --- a/src/ai/create/index.scss +++ b/src/ai/create/index.scss @@ -50,34 +50,6 @@ } } - // 工具类 - .mb30 { - margin-bottom: 30px; - } - - .mb40 { - margin-bottom: 40px; - } - - .mb5 { - margin-bottom: 5px; - } - - .mb8 { - margin-bottom: 8px; - } - - .ml10 { - margin-left: 10px; - } - - .mr20 { - margin-right: 20px; - } - - .mt40 { - margin-top: 40px; - } // 主体内容 .ai_create_content { @@ -151,6 +123,13 @@ .ant-upload.ant-upload-select { width: 100%; } + + // 审核驳回提示样式 + .audit-rejected-wrapper { + .ant-alert-error { + border-radius: 8px; + } + } } .ai_create_upload { diff --git a/src/ai/detail/index.jsx b/src/ai/detail/index.jsx index 1a4f64c1..1080504d 100644 --- a/src/ai/detail/index.jsx +++ b/src/ai/detail/index.jsx @@ -1,12 +1,12 @@ -import React, { useState, useEffect } from "react"; -import { Tabs, Tag, Spin, message, Divider, Tree, Tooltip } from "antd"; -import axios from "axios"; +import React, { useState, useEffect, Fragment } from "react"; +import { Tabs, Tag, Spin, message, Divider, Tree, Tooltip, Button, Badge } from "antd"; import RenderHtml from "../../components/render-html"; import "./index.scss"; -import { getlikedSource, getAISourceById, likeAISource } from "../../forge/Information/api"; -import { aiResouceTypeKey, convertToTreeData } from "../static"; +import { getlikedSource, getAISourceById, likeAISource, editModel, editDataset } from "../../forge/Information/api"; +import { aiResouceStatus, aiResouceType, aiResouceTypeKey, convertToTreeData } from "../static"; import skillIcon from '../image/icon7.png'; import CommentsList from "../../components/commentsByZone"; +import TpmMdEditor from "../../modules/tpm/challengesnew/tpm-md-editor"; const { TabPane } = Tabs; @@ -18,18 +18,26 @@ function Detail(props) { // 状态管理 const [reload, setReload] = useState(undefined); const [detail, setDetail] = useState({}); - const [files, setFiles] = useState(undefined); - const [comments, setComments] = useState(undefined); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState("introduction"); - const [branch, setBranch] = useState("master"); const [liked, setLiked] = useState(false); + const [isEditor, setIsEditor] = useState(false); + const [editContent, setEditContent] = useState(""); + const [saving, setSaving] = useState(false); + + const { extendData={}, createBy, auditStatus } = detail; + const status = aiResouceStatus[auditStatus] || {}; + + const typeDetail = type && aiResouceType.find(i => i.key === type); + const name = typeDetail && typeDetail.name - const { extendData={} } = detail; const dataByType = extendData[aiResouceTypeKey[type]] || {} const content = dataByType.content || dataByType.readmeContent - const introContent = String(content || '
暂无 README 内容
').replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, ''); + const introContent = String(content || `
当前${name}未提供详细介绍
`).replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, ''); const treeData = dataByType && dataByType.fileTree && convertToTreeData(dataByType.fileTree.children) + + // 判断当前用户是否为发布者 + const isPublisher = login && createBy && login === createBy; // 组件挂载和 ID 变化时加载数据 useEffect(() => { @@ -60,6 +68,41 @@ function Detail(props) { }) } + // 切换编辑模式 + const handleToggleEdit = () => { + if (isEditor) { + // 取消编辑,恢复原内容 + setEditContent(content || ""); + setIsEditor(false); + } else { + // 进入编辑模式 + setEditContent(content || ""); + setIsEditor(true); + } + } + + // 保存编辑内容 + const handleSave = () => { + setSaving(true); + const editFun = type === "models" ? editModel : editDataset + editFun({ + id: +id, + readmeContent: editContent + }).then(response => { + if (response && response.data && response.data.code === 200) { + message.success("保存成功"); + setIsEditor(false); + setReload(Date.now()); + } else { + message.error(response?.data?.msg || "保存失败"); + } + }).catch(() => { + message.error("保存失败,请重试"); + }).finally(() => { + setSaving(false); + }); + } + // 格式化下载量 const formatDownloads = (num) => { if (num >= 10000) { @@ -124,6 +167,7 @@ function Detail(props) { if (!login) { showLoginDialog(); e.stopPropagation(); + e.preventDefault(); } }}>下载} history.goBack()}>返回 @@ -132,6 +176,10 @@ function Detail(props) {
+ {auditStatus !== "1" && + + + } {detail.createUser && detail.createUser.userName || "未知作者"} @@ -172,11 +220,11 @@ function Detail(props) { centered > {activeTab === "introduction" && (
-
- -
+ {/* 编辑按钮区域 - 仅发布者可见 */} + {isPublisher && ["models", "datasets"].includes(type) && !isEditor &&
+ {auditStatus === "1" ? ( + trigger.parentNode} title={当前资源是上架状态,请前往
我的资源池页面先进行下架
}> + 编辑 +
+ ) : ( + 编辑 + )} +
} + {isEditor ? ( + +
+ setEditContent(value)} + height={600} + mdID={`ai_detail_readme_editor_${id}`} + /> +
+
+ + +
+
+ ) : ( +
+ +
+ )}
)} diff --git a/src/ai/detail/index.scss b/src/ai/detail/index.scss index fc8d3125..be286aa7 100644 --- a/src/ai/detail/index.scss +++ b/src/ai/detail/index.scss @@ -356,5 +356,30 @@ font-size: 15px; color:#27264d; } + li:not(.ant-tree-treenode-switcher-close):not(.ant-tree-treenode-switcher-open) .ant-tree-node-content-wrapper{ + cursor: default; + } + } + + // 编辑工具栏 + .ai_detail_edit_toolbar { + padding: 0 4px; + text-align: right; + } + + // Markdown 编辑器容器 + .ai_detail_readme_editor { + // min-height: 500px; + + // 覆盖 TpmMdEditor 的默认样式,使其与页面风格一致 + .markdown-editor { + border-radius: 8px; + + .editor-textarea { + font-family: "Courier New", monospace; + font-size: 15px; + line-height: 1.8; + } + } } } diff --git a/src/ai/index.jsx b/src/ai/index.jsx index 051e7173..0f9f40ee 100644 --- a/src/ai/index.jsx +++ b/src/ai/index.jsx @@ -31,20 +31,29 @@ function AI(props) { const [aiZoneInfo, setAiZoneInfo] = useState(undefined); const [roleByZone, setRoleByZone] = useState("Member"); + const {id} = aiZoneInfo || {} useEffect(() => { getMainInfos("AI").then(res => { if (res && res.data && res.data.data) { setAiZoneInfo(res.data.data) - // login && getCurrentRole(res.data.data.id).then(res1 => { - // if (res1 && res1.data && res1.data.data) { } - // setRoleByZone(res1.data.data.role) - // }) + // 存储deptId,所有专区接口header带上 + sessionStorage.setItem('deptId', res.data.data.deptId) } }) - }, []) + useEffect(()=>{ + if(id && login){ + getCurrentRole(id); + // login && getCurrentRole(res.data.data.id).then(res1 => { + // if (res1 && res1.data && res1.data.data) { + // setRoleByZone(res1.data.data.role) + // } + // }) + } + }, [id, login]) + return
}
{model.name}{model.isNew && }
-
{model.desc}
+ {model.desc &&
{model.desc}
}
查看
diff --git a/src/ai/my-resources/index.jsx b/src/ai/my-resources/index.jsx index fe1bd440..eb9a4bde 100644 --- a/src/ai/my-resources/index.jsx +++ b/src/ai/my-resources/index.jsx @@ -9,9 +9,10 @@ import moment from "moment"; function MyResources(props) { const pageSize = 10; - const { match: { params }, history, aiZoneInfo, roleByZone } = props || {}; + const { match: { params }, history, aiZoneInfo, roleByZone, current_user } = props || {}; const type = params.type; const { id: aiZoneId } = aiZoneInfo || {} + const { login } = current_user || {} const [current, setCurrent] = useState(1); const [total, setTotal] = useState(0); const [reload, setReload] = useState(undefined); @@ -24,6 +25,13 @@ function MyResources(props) { document.title = `我的资源池` }, []) + // 登录检查:如果未登录则跳转到登录页面 + useEffect(() => { + if (!login) { + history.push(`/login?go_page=${encodeURIComponent(window.location.pathname)}`); + } + }, [login]); + useEffect(() => { if (aiZoneId && type) { if(type === "codes") { @@ -56,7 +64,7 @@ function MyResources(props) { } }) } - }, [aiZoneId, type]) + }, [aiZoneId, type, reload]) useEffect(() => { if(type === "codes" && aiZoneId) { @@ -176,6 +184,12 @@ function MyResources(props) { {category.name} ))} + + +
{/* 统计数据 */} diff --git a/src/ai/my-resources/index.scss b/src/ai/my-resources/index.scss index 54fcad6e..393b061f 100644 --- a/src/ai/my-resources/index.scss +++ b/src/ai/my-resources/index.scss @@ -30,6 +30,7 @@ // 分类标签 .category-tabs { display: flex; + align-items: center; margin-bottom: 30px; border: 1px solid #091221; border-radius: 24px; @@ -53,6 +54,16 @@ color: #fff; } } + .category-tab-add{ + width:34px; + height:34px; + line-height: 34px; + text-align: center; + background:#091221; + border-radius:17px; + color: white; + margin-right: 9px; + } } // 统计数据 diff --git a/src/ai/static.js b/src/ai/static.js index ef04e9cf..42c9cbee 100644 --- a/src/ai/static.js +++ b/src/ai/static.js @@ -61,7 +61,7 @@ export const convertToTreeData = (data) => { let title = node.name; if (isLeaf && node.size) { const sizeStr = formatFileSize(node.size); - title = {node.name}{sizeStr}; + title = {node.name}{sizeStr}; } return { key: node.name, diff --git a/src/components/ChunkedUpload/index.jsx b/src/components/ChunkedUpload/index.jsx index 37c5a09e..eb430354 100644 --- a/src/components/ChunkedUpload/index.jsx +++ b/src/components/ChunkedUpload/index.jsx @@ -38,7 +38,7 @@ const ChunkedUpload = forwardRef(({ hierarchy = '', chunkSize = 10 * 1024 * 1024, // 默认 10MB disabled = false, - accept = '*', + accept = '', // 空字符串表示接受所有文件类型,这是 HTML5 标准写法 maxSize = 1024 * 1024 * 1024, // 默认 1GB children, // 支持自定义未选择文件状态的内容 defaultFile, // 默认文件信息(已上传的文件),用于回显 diff --git a/src/components/commentsByZone/EditComment.jsx b/src/components/commentsByZone/EditComment.jsx index dff9a778..384b519e 100644 --- a/src/components/commentsByZone/EditComment.jsx +++ b/src/components/commentsByZone/EditComment.jsx @@ -145,6 +145,7 @@ function EditComment(props) { action={getZoneUrl(`/api/file/common/upload`)} beforeUpload={beforeUpload} onChange={changeFileList} + withCredentials={true} headers={{ Authorization: cookie.load('autologin_trustie'), }} diff --git a/src/forge/Information/api.js b/src/forge/Information/api.js index 86c03339..8c3fd2c3 100644 --- a/src/forge/Information/api.js +++ b/src/forge/Information/api.js @@ -510,10 +510,9 @@ export function takeUpSourceById(id, role="Member"){ method:"PUT" }) } -// export function drawSourceById(id){ return fetch({ - url: `/zoneFront/resource/${id}/withdraw`, + url: `/zone/zoneFront/resource/${id}/withdraw`, method:"PUT" }) }