增加对不同帖子类型的工具函数
Change-Id: I725923ef606d0f2b434da3f5f4ab6927a5fe3e9a
diff --git a/src/api/torrent.ts b/src/api/torrent.ts
new file mode 100644
index 0000000..2bf412b
--- /dev/null
+++ b/src/api/torrent.ts
@@ -0,0 +1,2 @@
+export const postTorrentUpload = '/torrent/upload'
+export const getTorrentDownload = '/torrent/download/'
\ No newline at end of file
diff --git a/src/api/upload.ts b/src/api/upload.ts
deleted file mode 100644
index cb768bb..0000000
--- a/src/api/upload.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const Upload= '/user/Io';
\ No newline at end of file
diff --git a/src/components/corner/corner.tsx b/src/components/corner/corner.tsx
index 71dd772..ad80476 100644
--- a/src/components/corner/corner.tsx
+++ b/src/components/corner/corner.tsx
@@ -1,13 +1,14 @@
// src/components/BottomRightUpload.tsx
-import React from 'react';
+import React, { use } from 'react';
import styles from './corner.module.css';
import { useNavigate } from 'react-router';
-
+import { useSearchParams } from 'react-router-dom';
const BottomRightUpload: React.FC = () => {
+ const [searchParams] = useSearchParams();
const navigate = useNavigate();
-
+ const type = searchParams.get('type');
const handleUploadClick = () => {
- navigate('/postDetails', { state: { isNewPost: true } });
+ navigate('/createPost', { state: { isNewPost: true, type} });
};
return (
diff --git a/src/components/pet/index.tsx b/src/components/pet/index.tsx
new file mode 100644
index 0000000..c859b68
--- /dev/null
+++ b/src/components/pet/index.tsx
@@ -0,0 +1,94 @@
+import React, { useState, useEffect } from 'react';
+
+const petList = [
+ {
+ id: 'cat01',
+ name: '喵喵',
+ image: '/pets/cat.png',
+ mood: '开心',
+ hunger: 50,
+ },
+ {
+ id: 'dog01',
+ name: '汪汪',
+ image: '/pets/dog.png',
+ mood: '饥饿',
+ hunger: 70,
+ }
+];
+
+const PetGame = () => {
+ const [selectedPetIndex, setSelectedPetIndex] = useState(0);
+ const [petStates, setPetStates] = useState(petList);
+
+ // 定时每 5 秒减少一点饥饿值
+ useEffect(() => {
+ const timer = setInterval(() => {
+ setPetStates(prev =>
+ prev.map((pet, index) =>
+ index === selectedPetIndex
+ ? {
+ ...pet,
+ hunger: Math.min(100, pet.hunger + 2),
+ mood: pet.hunger > 80 ? '生气' : pet.mood
+ }
+ : pet
+ )
+ );
+ }, 5000);
+ return () => clearInterval(timer);
+ }, [selectedPetIndex]);
+
+ const handleFeed = () => {
+ setPetStates(prev =>
+ prev.map((pet, index) =>
+ index === selectedPetIndex
+ ? {
+ ...pet,
+ hunger: Math.max(0, pet.hunger - 20),
+ mood: '开心'
+ }
+ : pet
+ )
+ );
+ };
+
+ const handlePet = () => {
+ setPetStates(prev =>
+ prev.map((pet, index) =>
+ index === selectedPetIndex
+ ? { ...pet, mood: '超级开心' }
+ : pet
+ )
+ );
+ };
+
+ const currentPet = petStates[selectedPetIndex];
+
+ return (
+ <div style={{ textAlign: 'center', padding: 20 }}>
+ <h2>当前宠物:{currentPet.name}</h2>
+ <img
+ src={currentPet.image}
+ alt={currentPet.name}
+ style={{ width: 200, height: 200, cursor: 'pointer' }}
+ onClick={handlePet}
+ />
+ <p>情绪:{currentPet.mood}</p>
+ <p>饥饿值:{currentPet.hunger}/100</p>
+
+ <button onClick={handleFeed}>🍖 喂食</button>
+
+ <div style={{ marginTop: 20 }}>
+ <h4>切换宠物:</h4>
+ {petStates.map((pet, index) => (
+ <button key={pet.id} onClick={() => setSelectedPetIndex(index)} style={{ marginRight: 8 }}>
+ {pet.name}
+ </button>
+ ))}
+ </div>
+ </div>
+ );
+};
+
+export default PetGame;
diff --git a/src/components/selfStatus/selfStatus.tsx b/src/components/selfStatus/selfStatus.tsx
index fb25c75..0fd0636 100644
--- a/src/components/selfStatus/selfStatus.tsx
+++ b/src/components/selfStatus/selfStatus.tsx
@@ -21,7 +21,7 @@
const uploadTraffic = useAppSelector(state => state.user.uploadTraffic);
const downloadTraffic = useAppSelector(state => state.user.downloadTraffic);
const downloadPoints = useAppSelector(state => state.user.downloadPoints);
- const avatar = useAppSelector(state => state.user.avatar);
+ const avatar = useAppSelector(state => state.user.avatar) || 'https://pic.baike.soso.com/ugc/baikepic2/6664/20220301143956-1127285627_png_800_800_370852.jpg/0';
const dispatch = useAppDispatch();
const { data, refresh } = useApi(() => request.get(getUserInfo), false);
const dataRef = useRef(data);
diff --git a/src/mock/upload.js b/src/mock/upload.js
index c3f2705..a70122c 100644
--- a/src/mock/upload.js
+++ b/src/mock/upload.js
@@ -1,26 +1,26 @@
import Mock from 'mockjs';
import MockAdapter from 'axios-mock-adapter';
-import {Upload} from '@/api/upload';
+// import {Upload} from '@/api/upload';
-/**
- * 设置上传种子的 Mock 接口
- * @param {MockAdapter} mock
- */
+// /**
+// * 设置上传种子的 Mock 接口
+// * @param {MockAdapter} mock
+// */
export function setupUploadMock(mock) {
- mock.onPost(Upload).reply((config) => {
- const body = JSON.parse(config.data);
+// mock.onPost(Upload).reply((config) => {
+// const body = JSON.parse(config.data);
- console.log('收到上传请求,内容如下:');
- console.log(body);
+// console.log('收到上传请求,内容如下:');
+// console.log(body);
- return [
- 200,
- {
- code: 0,
- message: '',
- data: null
- }
- ];
- });
+// return [
+// 200,
+// {
+// code: 0,
+// message: '',
+// data: null
+// }
+// ];
+// });
}
diff --git a/src/route/index.tsx b/src/route/index.tsx
index 857118e..6f76a1e 100644
--- a/src/route/index.tsx
+++ b/src/route/index.tsx
@@ -42,7 +42,7 @@
element: <Homepage/>
},
{
- path:'/postDetails',
+ path:'/createPost',
element: <Upload/>
},
{
diff --git a/src/types/common.ts b/src/types/common.ts
index e1ca2c9..eef331f 100644
--- a/src/types/common.ts
+++ b/src/types/common.ts
@@ -181,4 +181,11 @@
69: 'music',
70: 'read',
71: 'system',
-};
\ No newline at end of file
+};
+
+export const MainTag = [
+ 'video',
+ 'Game',
+ 'music',
+ 'software'
+]
\ No newline at end of file
diff --git a/src/utils/common.ts b/src/utils/common.ts
new file mode 100644
index 0000000..cc20522
--- /dev/null
+++ b/src/utils/common.ts
@@ -0,0 +1,13 @@
+import { MainPostTag, MainPostTagParent, MainPostTagName } from '@/types/common';
+
+export const getTagsByMainTag:(main:string)=>Map<string, number> = (main:string)=>{
+ const ans = new Map<string, number>()
+ const mainTagId = MainPostTag[main as keyof typeof MainPostTag];
+ for(const key in MainPostTagParent){
+ if(MainPostTagParent[key] === mainTagId)
+ {
+ ans.set(MainPostTagName[key], Number(key));
+ }
+ }
+ return ans;
+}
\ No newline at end of file
diff --git a/src/views/frame/frame.tsx b/src/views/frame/frame.tsx
index 83106a1..ba17996 100644
--- a/src/views/frame/frame.tsx
+++ b/src/views/frame/frame.tsx
@@ -51,7 +51,7 @@
return (
<div style={{ display: 'block', height: '100vh' }}>
<header className={style.header}>
- <img className={style.logo} src={logo} alt="website logo"></img>
+ <img className={style.logo} src={logo} alt="website logo" onClick={()=>navigate('/')}></img>
{showSearch && (
// <input className={style.searchInput} placeholder="输入关键词进行搜索"/>
<input
diff --git a/src/views/pet/pet.module.css b/src/views/pet/pet.module.css
deleted file mode 100644
index e69de29..0000000
--- a/src/views/pet/pet.module.css
+++ /dev/null
diff --git a/src/views/pet/pet.tsx b/src/views/pet/pet.tsx
deleted file mode 100644
index e69de29..0000000
--- a/src/views/pet/pet.tsx
+++ /dev/null
diff --git a/src/views/upload/upload.module.css b/src/views/upload/upload.module.css
index 5a9952a..5013522 100644
--- a/src/views/upload/upload.module.css
+++ b/src/views/upload/upload.module.css
@@ -1,8 +1,9 @@
.container {
background-color: var(--card-bg);
+ box-sizing: border-box;
padding: 32px;
border-radius: 12px;
- width: 100%;
+ width:100%;
height: 100%;
margin: auto;
border: 1px solid var(--border-color);
@@ -16,7 +17,7 @@
.input,
.select,
.textarea {
- width: 100%;
+ width: 80%;
padding: 8px 12px;
margin-top: 4px;
border: 1px solid var(--border-color);
@@ -35,6 +36,7 @@
}
.charCount {
+ width: calc(80px + 80%);
text-align: right;
font-size: 12px;
color: var(--text-color);
@@ -63,7 +65,11 @@
transition: background-color 0.3s ease;
}
-.submitBtn:hover {
+.submitBtn:disabled {
+ background-color: #999;
+}
+
+.submitBtn:hover :not(:disabled) {
background-color: var(--primary-hover);
}
@@ -91,7 +97,7 @@
.input,
.textarea {
- width: 100%;
+ width: 80%;
padding: 10px;
margin-bottom: 16px;
border-radius: 6px;
@@ -145,6 +151,10 @@
transition: background-color 0.3s;
}
+.uploadButton :disabled {
+ background-color: #999;
+}
+
.uploadButton:hover {
background-color: #317ee7;
}
diff --git a/src/views/upload/upload.tsx b/src/views/upload/upload.tsx
index 4a60330..1bf096a 100644
--- a/src/views/upload/upload.tsx
+++ b/src/views/upload/upload.tsx
@@ -1,16 +1,46 @@
import instance from '@/utils/axios';
-import React, { useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import styles from './upload.module.css';
-import { Upload } from '@/api/upload';
-import { useNavigate } from 'react-router-dom'; // 用于跳转
+import {postTorrentUpload } from '@/api/torrent';
+import { useLocation, useNavigate } from 'react-router-dom'; // 用于跳转
+import { getTagsByMainTag } from '@/utils/common';
+import { Checkbox, Row, Col } from 'antd'; // 使用 antd 的 Checkbox 组件
+import { MainTag } from '@/types/common';
+import { Select } from 'antd';
+import { UploadOutlined } from '@ant-design/icons';
+import type { UploadProps } from 'antd';
+import { Button, message, Upload as UploadArea } from 'antd';
-const PostDetails = () => {
+
+const CreatePost = () => {
+ const location = useLocation();
const [postTitle, setPostTitle] = useState('');
- const [postType, setPostType] = useState('');
const [postContent, setPostContent] = useState('');
const [isChecked, setIsChecked] = useState(false);
-
+ const {type} = location.state || {type: ''}; // 获取路由传递的参数
+ const [tagIds, setTagIds] = useState<number[]>([]);
+ const [postType, setPostType] = useState<string>(type || ''); // 初始化 postType
const navigate = useNavigate();
+ const [tags, setTags] = useState<Map<string, number>>(new Map());
+
+ const props: UploadProps = {
+ name: 'file',
+ action: process.env.REACT_APP_BASE_URL + postTorrentUpload, // 替换为实际的上传接口地址
+ headers: {
+ authorization: 'authorization-text',
+ },
+ onChange(info) {
+ if (info.file.status !== 'uploading') {
+ console.log(info.file, info.fileList);
+ }
+ if (info.file.status === 'done') {
+ message.success(`${info.file.name} file uploaded successfully`);
+ } else if (info.file.status === 'error') {
+ message.error(`${info.file.name} file upload failed.`);
+ }
+ },
+ };
+
const handleSubmit = async () => {
if (!postTitle.trim() || !postType || !postContent.trim()) {
@@ -54,6 +84,17 @@
}
};
+ useEffect(() => {
+ setTags(getTagsByMainTag(type)); // 获取对应类型的标签
+ },[]);
+
+ const handlePostTypeChange = useCallback((value:string) => {
+ setPostType(value);
+ setTags(getTagsByMainTag(value)); // 更新 tags
+ setTagIds([]); // 清空已选的标签 ID
+ }, [postType, setTags, setTagIds]);
+
+
return (
<div className={styles.container}>
<div className={styles.formGroup}>
@@ -66,29 +107,42 @@
className={styles.input}
/>
</div>
+
+ <div className={styles.formGroup}>
+ <label>种子类型:</label>
+ <Select
+ value={postType}
+ onChange={handlePostTypeChange}
+
+ options ={ MainTag.map((item) => ({
+ label: item,
+ value: item
+ }))} />
+ </div>
<div className={styles.formGroup}>
<label>类型选择:</label>
- <select
- value={postType}
- onChange={(e) => setPostType(e.target.value)}
- className={styles.select}
+ <Checkbox.Group
+ value={tagIds}
+ onChange={(checkedValues) => setTagIds(checkedValues as number[])}
>
- <option value="">下拉选择</option>
- <option value="type1">类型一</option>
- <option value="type2">类型二</option>
- </select>
+ <Row gutter={[12, 12]}>
+ {[...tags.entries()].map(([name, id]) => (
+ <Col key={id} xs={12} sm={8} md={6} lg={4}>
+ <Checkbox value={id}>{name}</Checkbox>
+ </Col>
+ ))}
+ </Row>
+ </Checkbox.Group>
</div>
{/* 暂时移除上传文件表单 */}
- {/* <div className={styles.formGroup}>
+ <div className={styles.formGroup}>
<label>上传资源:</label>
- <input
- type="file"
- onChange={(e) => setFile(e.target.files?.[0] || null)}
- className={styles.upload}
- />
- </div> */}
+ <UploadArea {...props}>
+ <Button icon={<UploadOutlined />}>Upload</Button>
+ </UploadArea>
+ </div>
<div className={styles.formGroup}>
<label>内容介绍:</label>
@@ -113,11 +167,11 @@
<span>我已知晓以上内容</span>
</div>
- <button onClick={handleSubmit} className={styles.submitBtn}>
+ <button onClick={handleSubmit} className={styles.submitBtn} disabled={!isChecked}>
我已知晓
</button>
</div>
);
};
-export default PostDetails;
+export default CreatePost;