feat(C-04):AI图片放大页+搜索结果跳转修复

新增/utility/image-upscaler页(2x/4x上传放大、积分扣费402余额不足分支、blob下载);Search页响应体剥层对齐(成功码10000)、q截断100、结果URL对齐后端现行路由(/post、/utility、/course-learn、/open-api-detail)。
This commit is contained in:
chunyu
2026-09-15 15:26:51 +08:00
parent e90b787730
commit af18085f40
3 changed files with 258 additions and 19 deletions
+26 -19
View File
@@ -96,9 +96,11 @@ const Search: React.FC = () => {
useEffect(() => {
const fetchHotKeywords = async () => {
try {
const res = await api_request.search.hotKeywords();
if (res.data?.code === 0) {
setHotKeywords(res.data.data);
const res: any = await api_request.search.hotKeywords();
// axios 拦截器已剥掉一层:res 即响应体 {data, code},成功码 10000
const body = res?.data?.code !== undefined ? res.data : res;
if (body?.code === 10000 && Array.isArray(body?.data)) {
setHotKeywords(body.data);
}
} catch {
setHotKeywords(["React Hooks", "RESTful API", "TypeScript", "Docker部署", "GraphQL", "微服务架构", "CI/CD", "性能优化"]);
@@ -118,16 +120,18 @@ const Search: React.FC = () => {
try {
const filterToUse = searchFilter !== undefined ? searchFilter : activeFilter;
const sortToUse = searchSort !== undefined ? searchSort : sort;
const res = await api_request.search.global({
q: q.trim(),
const res: any = await api_request.search.global({
q: q.trim().slice(0, 100),
type: filterToUse === 'all' ? undefined : filterToUse,
page: pageNum,
page_size: pageSize,
sort: sortToUse,
});
if (res.data?.code === 0) {
setResults(res.data.data.results || []);
setTotal(res.data.data.total || 0);
// axios 拦截器已剥掉一层:res 即响应体 {data, code},成功码 10000
const body = res?.data?.code !== undefined ? res.data : res;
if (body?.code === 10000 && body?.data) {
setResults(body.data.results || []);
setTotal(body.data.total || 0);
setCurrentPage(pageNum);
}
} catch {
@@ -174,9 +178,11 @@ const Search: React.FC = () => {
return;
}
try {
const res = await api_request.search.suggestions({ q: keyword.trim(), limit: 8 });
if (res.data?.code === 0) {
setSuggestions(res.data.data || []);
const res: any = await api_request.search.suggestions({ q: keyword.trim(), limit: 8 });
// axios 拦截器已剥掉一层:res 即响应体 {data, code},成功码 10000
const body = res?.data?.code !== undefined ? res.data : res;
if (body?.code === 10000) {
setSuggestions(body?.data || []);
}
} catch {
setSuggestions([]);
@@ -225,19 +231,20 @@ const Search: React.FC = () => {
const getResultUrl = (item: SearchResult) => {
if (item.url) return item.url;
if (item.type === '文章') return `/articles/${item.id}`;
if (item.type === '工具') return `/tools/${item.id}`;
if (item.type === '课程') return `/courses/${item.id}`;
if (item.type === '文章') return `/post/${item.id}`;
if (item.type === '工具') return '/utility';
if (item.type === '课程') return `/course-learn?id=${item.id}`;
if (item.type === 'API') return `/open-api-detail/${item.id}`;
return '/search';
};
const categories = [
{ name: t('search.typeApi'), icon: <ApiOutlined />, gradient: "linear-gradient(135deg, #667eea, #764ba2)", path: "/api" },
{ name: t('search.typeApi'), icon: <ApiOutlined />, gradient: "linear-gradient(135deg, #667eea, #764ba2)", path: "/open-api" },
{ name: t('search.typeArticle'), icon: <FileTextOutlined />, gradient: "linear-gradient(135deg, #f093fb, #f5576c)", path: "/articles" },
{ name: t('search.typeCourse'), icon: <BookOutlined />, gradient: "linear-gradient(135deg, #4facfe, #00f2fe)", path: "/courses" },
{ name: t('search.typeTool'), icon: <ToolOutlined />, gradient: "linear-gradient(135deg, #43e97b, #38f9d7)", path: "/api" },
{ name: t('search.typeFrontend'), icon: <CodeOutlined />, gradient: "linear-gradient(135deg, #fa709a, #fee140)", path: "/frontend" },
{ name: t('search.typeBackend'), icon: <CloudOutlined />, gradient: "linear-gradient(135deg, #a18cd1, #fbc2eb)", path: "/backend" },
{ name: t('search.typeCourse'), icon: <BookOutlined />, gradient: "linear-gradient(135deg, #4facfe, #00f2fe)", path: "/learn" },
{ name: t('search.typeTool'), icon: <ToolOutlined />, gradient: "linear-gradient(135deg, #43e97b, #38f9d7)", path: "/utility" },
{ name: t('search.typeFrontend'), icon: <CodeOutlined />, gradient: "linear-gradient(135deg, #fa709a, #fee140)", path: "/open-api" },
{ name: t('search.typeBackend'), icon: <CloudOutlined />, gradient: "linear-gradient(135deg, #a18cd1, #fbc2eb)", path: "/learn" },
];
const filterTabs = [