diff --git a/apps/server/src/models/share-code/share-code.service.ts b/apps/server/src/models/share-code/share-code.service.ts index b4658f2..660f184 100755 --- a/apps/server/src/models/share-code/share-code.service.ts +++ b/apps/server/src/models/share-code/share-code.service.ts @@ -20,6 +20,7 @@ export interface ShareCode { isUsed: boolean; fileName?: string | null; canUseTimes: number | null; + uploadIp?: string; } export interface GenerateShareCodeResponse { id?: string; @@ -154,7 +155,9 @@ export class ShareCodeService extends BaseService { filetype, size, } - } + }, + uploadIp, + createdAt: new Date() }; } catch (error) { this.logger.error('Failed to generate share code', error); @@ -172,6 +175,7 @@ export class ShareCodeService extends BaseService { code, isUsed: false, expiresAt: { gt: dayjs().tz('Asia/Shanghai').toDate() }, + deletedAt: null }, }); if (shareCode.canUseTimes <= 0) { @@ -280,7 +284,8 @@ export class ShareCodeService extends BaseService { this.logger.log('验证分享码结果:', shareCode); if (!shareCode) { - throw new NotFoundException('分享码无效或已过期'); + this.logger.log('分享码无效或已过期'); + return null } // 获取文件信息 @@ -308,7 +313,9 @@ export class ShareCodeService extends BaseService { meta: { filename, filetype, size } - } + }, + uploadIp: shareCode.uploadIp, + createdAt: shareCode.createdAt }; this.logger.log('返回给前端的数据:', response); // 添加日志 diff --git a/apps/web/src/app/admin/code-manage/CodeManageContext.tsx b/apps/web/src/app/admin/code-manage/CodeManageContext.tsx index 9549b4c..6a4d591 100644 --- a/apps/web/src/app/admin/code-manage/CodeManageContext.tsx +++ b/apps/web/src/app/admin/code-manage/CodeManageContext.tsx @@ -45,7 +45,8 @@ export const CodeManageProvider = ({ children }: { children: React.ReactNode }) ...(searchKeyword ? { OR: [ { fileName: { contains: searchKeyword } }, - { code: { contains: searchKeyword } } + { code: { contains: searchKeyword } }, + { uploadIp: { contains: searchKeyword } } ] } : {}) }; diff --git a/apps/web/src/app/admin/code-manage/components/CodeManageSearchBase.tsx b/apps/web/src/app/admin/code-manage/components/CodeManageSearchBase.tsx index ec87eb7..9efb8e5 100644 --- a/apps/web/src/app/admin/code-manage/components/CodeManageSearchBase.tsx +++ b/apps/web/src/app/admin/code-manage/components/CodeManageSearchBase.tsx @@ -1,11 +1,13 @@ import { Button, Form, Input } from 'antd'; import { useCodeManageContext } from '../CodeManageContext'; import { ChangeEvent, useEffect, useRef } from 'react'; +import { useSearchParams } from "react-router-dom"; export default function CodeManageSearchBase({ keyword }: { keyword?: string }) { const { setCurrentPage, searchRefetch, setSearchKeyword, searchKeyword } = useCodeManageContext(); const debounceTimer = useRef(null); const formRef = Form.useForm()[0]; // 获取表单实例 + const [searchParams, setSearchParams] = useSearchParams(); // 当 keyword 属性变化时更新表单值 useEffect(() => { @@ -14,6 +16,17 @@ export default function CodeManageSearchBase({ keyword }: { keyword?: string }) } }, [keyword, formRef]); + // 监听 searchKeyword 变化,如果 URL 参数中有 keyword 且 searchKeyword 发生变化,则清空 URL 参数 + useEffect(() => { + const urlKeyword = searchParams.get('keyword'); + if (urlKeyword && searchKeyword !== urlKeyword) { + // 创建一个新的 URLSearchParams 对象,不包含 keyword 参数 + const newParams = new URLSearchParams(searchParams); + newParams.delete('keyword'); + setSearchParams(newParams); + } + }, [searchKeyword, searchParams, setSearchParams]); + const onSearch = (value: string) => { console.log(value); setSearchKeyword(value); @@ -41,9 +54,10 @@ export default function CodeManageSearchBase({ keyword }: { keyword?: string })
diff --git a/apps/web/src/app/admin/dashboard/components/Activate.tsx b/apps/web/src/app/admin/dashboard/components/Activate.tsx index 94ba01a..589a62f 100644 --- a/apps/web/src/app/admin/dashboard/components/Activate.tsx +++ b/apps/web/src/app/admin/dashboard/components/Activate.tsx @@ -25,8 +25,11 @@ export default function Activate() { } - title={`来自${item.uploadIp}的用户上传了文件:"${item.fileName}",文件大小:${Math.max(Number(item.resource.meta.size) / 1024 / 1024, 0.01).toFixed(2)}MB,分享码:${item.code}`} time={item.createdAt?.toLocaleString()} + ip={item.uploadIp} + filename={item.fileName} + filesize={Math.max(Number(item.resource.meta.size) / 1024 / 1024, 0.01).toFixed(2)} + code={item.code} /> ))} diff --git a/apps/web/src/app/admin/dashboard/components/ActivityItem.tsx b/apps/web/src/app/admin/dashboard/components/ActivityItem.tsx index f51246e..8dc0915 100644 --- a/apps/web/src/app/admin/dashboard/components/ActivityItem.tsx +++ b/apps/web/src/app/admin/dashboard/components/ActivityItem.tsx @@ -2,11 +2,14 @@ import { motion } from 'framer-motion'; // 活动项组件 interface ActivityItemProps { icon: React.ReactNode; - title: string; time: string; + ip: string; + filename: string; + filesize: string; + code: string; } -export default function ActivityItem({ icon, title, time }: ActivityItemProps) { +export default function ActivityItem({ icon, time, ip ,filename, filesize, code }: ActivityItemProps) { return (
-
{title}
+
+ 来自{ip}的用户 + 上传了文件:"{filename}", + 文件大小:{filesize}MB, + 分享码:{code} +
{time}
diff --git a/apps/web/src/app/admin/dashboard/components/Board.tsx b/apps/web/src/app/admin/dashboard/components/Board.tsx index 598e540..0a2e39f 100644 --- a/apps/web/src/app/admin/dashboard/components/Board.tsx +++ b/apps/web/src/app/admin/dashboard/components/Board.tsx @@ -74,7 +74,7 @@ export default function Board() { className="h-full" >
- + { isShareCodeTodayLoading || isShareCodeYesterdayLoading ? diff --git a/apps/web/src/app/admin/quick-file/components/header.tsx b/apps/web/src/app/admin/quick-file/components/header.tsx index 4a6d501..6871577 100644 --- a/apps/web/src/app/admin/quick-file/components/header.tsx +++ b/apps/web/src/app/admin/quick-file/components/header.tsx @@ -13,7 +13,7 @@ export const Header: React.FC = ({ showLoginButton = true }) => { const isAdmin = hasEveryPermissions(RolePerms.MANAGE_ANY_POST) && isAuthenticated; return ( -
+
烽火快传 diff --git a/apps/web/src/app/admin/quick-file/manage.tsx b/apps/web/src/app/admin/quick-file/manage.tsx index 69dd70c..3ebb84b 100644 --- a/apps/web/src/app/admin/quick-file/manage.tsx +++ b/apps/web/src/app/admin/quick-file/manage.tsx @@ -1,7 +1,8 @@ import { useState, useEffect } from "react"; -import { Layout, Menu } from "antd"; -import { FileOutlined, DashboardOutlined } from "@ant-design/icons"; +import { Layout, Menu, Button, Space } from "antd"; +import { FileOutlined, DashboardOutlined, HomeOutlined, LogoutOutlined } from "@ant-design/icons"; import { NavLink, Outlet, useNavigate, useLocation } from "react-router-dom"; +import { useAuth } from "@web/src/providers/auth-provider"; const { Sider, Content } = Layout; @@ -10,6 +11,7 @@ export default function QuickFileManage() { const navigate = useNavigate(); const location = useLocation(); const [currentKey, setCurrentKey] = useState("1"); + const { logout } = useAuth(); useEffect(() => { // 根据当前URL路径设置currentKey @@ -28,15 +30,12 @@ export default function QuickFileManage() { onCollapse={(value) => setCollapsed(value)} theme="light" style={{ - borderRight: "1px solid #f0f0f0" + borderRight: "1px solid #f0f0f0", + display: "flex", + flexDirection: "column" }} > -
{ - navigate('/'); - }} - > +
{!collapsed && 烽火快传}
@@ -57,6 +56,27 @@ export default function QuickFileManage() { }, ]} /> +
+ + +
diff --git a/apps/web/src/app/admin/quick-file/page.tsx b/apps/web/src/app/admin/quick-file/page.tsx index fb4957f..b51ddeb 100755 --- a/apps/web/src/app/admin/quick-file/page.tsx +++ b/apps/web/src/app/admin/quick-file/page.tsx @@ -10,48 +10,38 @@ export default function QuickUploadPage() { const [form] = Form.useForm(); const uploadFileId = Form.useWatch(["file"], form)?.[0] return ( -
+
-
-
-
- 使用分享码下载文件 - +
+
+
+ 使用分享码下载文件 +
-
+
-
-
- 上传文件并生成分享码 + +
+
+ 上传文件并生成分享码
-
+
+ +
+
+ style="w-full py-8 px-4 mb-0 h-72 border-2 border-dashed border-gray-200 hover:border-blue-400 bg-gray-50 bg-opacity-50 rounded-lg transition-colors" + />
-
- -
- - {/* - - - - - - - */}
) diff --git a/apps/web/src/app/admin/quick-file/quickFileContext.tsx b/apps/web/src/app/admin/quick-file/quickFileContext.tsx index 713af04..78ded68 100644 --- a/apps/web/src/app/admin/quick-file/quickFileContext.tsx +++ b/apps/web/src/app/admin/quick-file/quickFileContext.tsx @@ -40,6 +40,15 @@ export const QuickFileProvider = ({ children }: { children: React.ReactNode }) = const [isGetingFileId, setIsGetingFileId] = useState(false); const [downloadCode, setDownloadCode] = useState(null); const saveCodeRecord = (data: ShareCodeResponse, recordName: string) => { + if (data.canUseTimes == 0) { + const existingGeneratorRecords = localStorage.getItem(recordName); + if (existingGeneratorRecords && data.code) { + const generatorRecords = JSON.parse(existingGeneratorRecords); + const filteredRecords = generatorRecords.filter((item: ShareCodeResponse) => item.code !== data.code); + localStorage.setItem(recordName, JSON.stringify(filteredRecords)); + } + return; + } const newRecord = { id: `${Date.now()}`, // 生成唯一ID code: data.code, @@ -55,7 +64,9 @@ export const QuickFileProvider = ({ children }: { children: React.ReactNode }) = filename: data.resource.meta.filename, filetype: data.resource.meta.filetype } - } + }, + uploadIp: data.uploadIp, + createdAt: data.createdAt }; // 获取已有记录并添加新记录 const existingGeneratorRecords = localStorage.getItem(recordName); diff --git a/apps/web/src/app/admin/sharecode/components/CodeRecord.tsx b/apps/web/src/app/admin/sharecode/components/CodeRecord.tsx index 844879c..25483c3 100644 --- a/apps/web/src/app/admin/sharecode/components/CodeRecord.tsx +++ b/apps/web/src/app/admin/sharecode/components/CodeRecord.tsx @@ -43,11 +43,12 @@ export default function CodeRecord({ title, btnContent, recordName ,styles,isDow localStorage.setItem(recordName, JSON.stringify(updatedRecords)); }; - const handleDownload = async (code:string) => { + const handleDownload = async (code:string,recordName:string) => { await setDownloadCode(code) const {data:result} = await refetchShareCodeWithResource() console.log('下载', result); handleValidSuccess(result.resource.url, result.fileName); + saveAndUpdateRecord(result as any as ShareCodeResponse, 'shareCodeUploadRecords'); saveAndUpdateRecord(result as any as ShareCodeResponse, 'shareCodeDownloadRecords'); }; @@ -75,7 +76,7 @@ export default function CodeRecord({ title, btnContent, recordName ,styles,isDow key={item.id} item={item} onDelete={handleDelete} - onDownload={isDownload ? handleDownload : undefined} + onDownload={() => handleDownload(item.code, recordName)} /> ))}
diff --git a/apps/web/src/app/admin/sharecode/sharecodegenerator.tsx b/apps/web/src/app/admin/sharecode/sharecodegenerator.tsx index be9c420..20ca5e3 100755 --- a/apps/web/src/app/admin/sharecode/sharecodegenerator.tsx +++ b/apps/web/src/app/admin/sharecode/sharecodegenerator.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Button, DatePicker, Form, message, Select } from 'antd'; +import { Button, DatePicker, Form, InputNumber, message } from 'antd'; import { CopyOutlined } from '@ant-design/icons'; import { useQueryClient } from '@tanstack/react-query'; import { getQueryKey } from '@trpc/react-query'; @@ -73,8 +73,8 @@ export const ShareCodeGenerator: React.FC = ({ setIsGenerate(true); setExpiresAt(dayjs(data.expiresAt).format('YYYY-MM-DD HH:mm:ss')); setCanUseTimes(data.canUseTimes); - saveCodeRecord(data,'shareCodeGeneratorRecords'); - message.success('分享码生成成功'+data.code); + saveCodeRecord(data, 'shareCodeGeneratorRecords'); + message.success('分享码生成成功' + data.code); } catch (error) { console.error('生成分享码错误:', error); message.error('生成分享码失败: ' + (error instanceof Error ? error.message : '未知错误')); @@ -92,7 +92,7 @@ export const ShareCodeGenerator: React.FC = ({ const date = dayjs().add(1, 'day').tz('Asia/Shanghai'); form.setFieldsValue({ expiresAt: date, - canUseTimes: 10 + canUseTimes: 5 }); }, [form]); @@ -116,7 +116,10 @@ export const ShareCodeGenerator: React.FC = ({ current && current < dayjs().startOf('day')} + disabledDate={(current) => + (current && current < dayjs().startOf('day')) || + (current && current > dayjs().add(7, 'day').endOf('day')) + } disabledTime={(current) => { if (current && current.isSame(dayjs(), 'day')) { return { @@ -137,16 +140,11 @@ export const ShareCodeGenerator: React.FC = ({ {"分享码的使用次数"} -