前言

今天不小心看到之前写的 ftp功能的小网站(flask实现), 前端界面太丑了,正好利用豆包等大模型工具给它优化优化。

为什么要搞这东西,不是有微信啥的工具么?
动机: (1)方便: 用其他通讯软件,得登陆,麻烦。你在一台电脑上开启这个xftp,整个连这个局域网(例如同个路由器)下的都能访问,直接多端获取。这是其一。
(2) 快速: 你通过其他软件传,文件得先到对应软件的服务器,再传到你另一个设备,大文件会比较慢。但是局域网特别快!
(3) 私密: 其他软件传东西,会经过企业的服务器,会被存档。

注意:请不要在公司公网搭建局域网,违者责任请自行承担。
python3 macbook安了开发者工具后默认有,windows新手python用户安装python3 可以查看 Python环境配置与入门建议(面向新手文)
另外,不建议在公共场所开启这个,因为暂时没有进行身份校验功能,理论上连接同一个路由器的人,都可以下载你上传的所有文件。



功能演示

主页面
在这里插入图片描述

上传页面
在这里插入图片描述
支持选择文件或者拖拽上传
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

启动方式

在根目录下运行
在这里插入图片描述



整体架构

和之前版本 ftp功能的小网站(flask实现) 一样,只不过现在小项目我更喜欢用vscode写了。

在这里插入图片描述

app.py是整个项目的"管家",负责监听还有逻辑处理
app.py文件:

from flask import Flask, render_template, request, send_from_directory, abort
import os

app = Flask(__name__)


def getfile():
    print(os.getcwd())
    path1 = os.getcwd() + '/upload_files'
    path2 = os.getcwd()
    # 跳转目录 跳转到下载文件的目录,获得下载文件目录里面的list之后,然后再跳转出来.
   #这个跳转的步骤是为了获取到upload_files目录下的文件的名字,然后把它放进f_list中
    os.chdir(path1)
    f_list = os.listdir()
    os.chdir(path2)
    print(os.getcwd())
    return f_list


def is_Have_file(filename):
    print(os.getcwd())
    path1 = os.getcwd() + '/upload_files'
    path2 = os.getcwd()
    os.chdir(path1)
    flag = os.path.isfile(filename)
    os.chdir(path2)
    print(os.getcwd())
    return flag


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/upload')
def upload_file():
    return render_template('upload.html')


@app.route('/uploader', methods=['GET', 'POST'])
def upload_success():
    if request.method == 'POST':
        f = request.files['file']
        f.save('upload_files/' + f.filename)
        return render_template('upload_success.html', filename=f.filename)


# 显示下载文件的界面
@app.route('/down', methods=['GET'])
def download_page():
    f_list = getfile()
    return render_template('download_page.html', fl=f_list)


# 下载要下载的文件,要下载的文件是通过get方法来传递的
@app.route('/download_file', methods=['GET'])
def download_file():
    if request.method == 'GET':
        download_filename = request.args.get('filename')
        f_list = getfile()
        print()
        if is_Have_file(download_filename):
            return send_from_directory('upload_files', download_filename, as_attachment=True)
        else:
            abort(404)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

主页文件home.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FTP功能小网站</title>
    <!-- 引入Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色和字体 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5', // 主色调:靛蓝色,传达信任和专业感
                        secondary: '#8B5CF6', // 辅助色:紫色
                        neutral: '#F8FAFC', // 中性色:浅灰
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .btn-hover {
                @apply transform transition-all duration-300 hover:scale-105 hover:shadow-lg;
            }
            .card-effect {
                @apply bg-white rounded-xl shadow-md transition-all duration-300 hover:shadow-xl;
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-neutral to-blue-50 min-h-screen flex flex-col items-center justify-center p-4 font-sans text-gray-800">
    <!-- 页面容器 -->
    <div class="max-w-md w-full mx-auto text-center">
        <!-- 标题区域 -->
        <div class="mb-12 animate-fade-in">
            <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 text-primary mb-4">
                <i class="fa fa-cloud-upload text-3xl"></i>
            </div>
            <h1 class="text-[clamp(2rem,5vw,3rem)] font-bold text-primary mb-2">FTP功能小网站</h1>
            <p class="text-gray-500">简单高效的文件上传与下载服务</p>
        </div>
        
        <!-- 操作按钮区域 -->
        <div class="grid gap-6">
            <!-- 上传按钮 -->
            <a href="{{ url_for('upload_file') }}" class="card-effect p-6 flex items-center justify-center space-x-3 btn-hover group">
                <div class="w-10 h-10 rounded-full bg-green-100 flex items-center justify-center text-green-600 group-hover:bg-green-600 group-hover:text-white transition-colors">
                    <i class="fa fa-upload"></i>
                </div>
                <span class="text-lg font-medium">上传文件</span>
            </a>
            
            <!-- 下载按钮 -->
            <a href="{{ url_for('download_page') }}" class="card-effect p-6 flex items-center justify-center space-x-3 btn-hover group">
                <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 group-hover:bg-blue-600 group-hover:text-white transition-colors">
                    <i class="fa fa-download"></i>
                </div>
                <span class="text-lg font-medium">下载文件</span>
            </a>
        </div>
        
        <!-- 页脚 -->
        <footer class="mt-16 text-gray-400 text-sm">
            <p>© 2025 FTP功能小网站 - 便捷快速的文件传输服务 - AndyDennis</p>
        </footer>
    </div>
    
    <!-- 简单的动画效果脚本 -->
    <script>
        // 添加页面加载动画类
        document.addEventListener('DOMContentLoaded', () => {
            const cards = document.querySelectorAll('.card-effect');
            cards.forEach((card, index) => {
                setTimeout(() => {
                    card.classList.add('animate-slide-up');
                }, 100 * index);
            });
        });
        
        // 定义简单的CSS动画
        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(10px); }
                to { opacity: 1; transform: translateY(0); }
            }
            @keyframes slideUp {
                from { opacity: 0; transform: translateY(20px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .animate-fade-in {
                animation: fadeIn 0.6s ease-out forwards;
            }
            .animate-slide-up {
                animation: slideUp 0.5s ease-out forwards;
            }
        `;
        document.head.appendChild(style);
    </script>
</body>
</html>

上传文件页面upload.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传文件 - FTP功能小网站</title>
    <!-- 引入Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5',
                        secondary: '#8B5CF6',
                        accent: '#10B981', // 上传相关的强调色(绿色)
                    }
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .file-upload-hover {
                @apply border-accent bg-accent/5;
            }
            .btn-primary {
                @apply bg-primary text-white px-6 py-3 rounded-lg font-medium transition-all duration-300 hover:bg-primary/90 hover:shadow-lg transform hover:-translate-y-0.5;
            }
            .card {
                @apply bg-white rounded-xl shadow-md p-6 md:p-8 transition-all duration-300 hover:shadow-xl;
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-teal-50 min-h-screen font-sans">
    <div class="container mx-auto px-4 py-8 max-w-3xl">
        <!-- 页面标题 -->
        <header class="text-center mb-10 mt-6">
            <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-primary mb-2">
                <i class="fa fa-cloud-upload mr-3"></i>上传文件
            </h1>
            <p class="text-gray-500">选择并上传您需要存储的文件</p>
        </header>
        
        <!-- 上传卡片 -->
        <div class="card mb-8">
            <!-- 拖放区域 -->
            <div id="drop-area" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center mb-6 transition-all duration-300">
                <i class="fa fa-file-o text-5xl text-gray-400 mb-4"></i>
                <p class="text-gray-600 mb-4">拖放文件到此处,或</p>
                
                <!-- 文件选择表单 -->
                <form action="{{ url_for('upload_success')}}" method="POST" enctype="multipart/form-data" id="upload-form">
                    <label for="file-upload" class="btn-primary inline-flex items-center">
                        <i class="fa fa-folder-open mr-2"></i>选择文件
                        <input id="file-upload" type="file" name="file" class="hidden" accept="*/*"/>
                    </label>
                    
                    <div id="file-info" class="mt-4 hidden">
                        <p class="text-gray-700"><span id="file-name"></span></p>
                        <p class="text-sm text-gray-500 mt-1" id="file-size"></p>
                    </div>
                    
                    <div class="mt-6">
                        <button type="submit" class="btn-primary">
                            <i class="fa fa-upload mr-2"></i>开始上传
                        </button>
                    </div>
                </form>
            </div>
            
            <!-- 上传说明 -->
            <div class="text-sm text-gray-500 bg-gray-50 p-4 rounded-lg">
                <p><i class="fa fa-info-circle text-primary mr-2"></i>上传说明:</p>
                <ul class="list-disc list-inside mt-2 space-y-1">
                    <li>请确保文件符合上传规范</li>
                    <li>支持多种文件格式上传</li>
                    <li>上传完成后将自动跳转至成功页面</li>
                </ul>
            </div>
        </div>
        
        <!-- 返回按钮 -->
        <div class="text-center">
            <a href="{{ url_for('home') }}" class="inline-flex items-center text-primary hover:text-primary/80 transition-colors">
                <i class="fa fa-arrow-left mr-2"></i>返回首页
            </a>
        </div>
        
        <!-- 页脚 -->
        <footer class="mt-16 text-center text-gray-400 text-sm">
            <p>© 2025 FTP功能小网站 - 便捷快速的文件传输服务 - AndyDennis</p>
        </footer>
    </div>
    
    <!-- 交互脚本 -->
    <script>
        // 获取DOM元素
        const dropArea = document.getElementById('drop-area');
        const fileInput = document.getElementById('file-upload');
        const fileInfo = document.getElementById('file-info');
        const fileName = document.getElementById('file-name');
        const fileSize = document.getElementById('file-size');
        const uploadForm = document.getElementById('upload-form');
        
        // 处理文件选择
        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                showFileInfo(e.target.files[0]);
            }
        });
        
        // 拖放功能
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, preventDefaults, false);
        });
        
        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }
        
        ['dragenter', 'dragover'].forEach(eventName => {
            dropArea.addEventListener(eventName, highlight, false);
        });
        
        ['dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, unhighlight, false);
        });
        
        function highlight() {
            dropArea.classList.add('file-upload-hover');
        }
        
        function unhighlight() {
            dropArea.classList.remove('file-upload-hover');
        }
        
        dropArea.addEventListener('drop', handleDrop, false);
        
        function handleDrop(e) {
            const dt = e.dataTransfer;
            const file = dt.files[0];
            
            if (file) {
                // 将拖放的文件设置到文件输入中
                fileInput.files = dt.files;
                showFileInfo(file);
            }
        }
        
        // 显示文件信息
        function showFileInfo(file) {
            fileName.textContent = `文件名: ${file.name}`;
            fileSize.textContent = `文件大小: ${formatFileSize(file.size)}`;
            fileInfo.classList.remove('hidden');
            
            // 添加显示动画
            fileInfo.classList.add('animate-fade-in');
        }
        
        // 格式化文件大小
        function formatFileSize(bytes, decimals = 2) {
            if (bytes === 0) return '0 Bytes';
            
            const k = 1024;
            const dm = decimals < 0 ? 0 : decimals;
            const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
            
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            
            return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
        }
        
        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(10px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .animate-fade-in {
                animation: fadeIn 0.3s ease-out forwards;
            }
        `;
        document.head.appendChild(style);
    </script>
</body>
</html>

上传成功页面 upload_success.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传成功 - FTP功能小网站</title>
    <!-- 引入Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5',
                        success: '#10B981', // 成功状态颜色
                    }
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .btn-action {
                @apply px-6 py-3 rounded-lg font-medium transition-all duration-300 hover:shadow-lg transform hover:-translate-y-0.5;
            }
            .btn-primary {
                @apply bg-primary text-white hover:bg-primary/90;
            }
            .btn-secondary {
                @apply bg-gray-100 text-gray-700 hover:bg-gray-200;
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-teal-50 min-h-screen font-sans flex items-center justify-center p-4">
    <div class="max-w-md w-full text-center">
        <!-- 成功状态卡片 -->
        <div class="bg-white rounded-2xl shadow-lg p-8 md:p-10 transform transition-all duration-500 animate-float">
            <!-- 成功图标 -->
            <div class="w-20 h-20 mx-auto bg-success/10 rounded-full flex items-center justify-center mb-6 animate-pulse-slow">
                <i class="fa fa-check text-4xl text-success"></i>
            </div>
            
            <!-- 成功信息 -->
            <h1 class="text-[clamp(1.5rem,3vw,2rem)] font-bold text-gray-800 mb-3">上传成功!</h1>
            <p class="text-gray-600 mb-8">
                文件 <span class="font-medium text-primary">{{ filename }}</span> 已成功上传
            </p>
            
            <!-- 文件信息 -->
            <div class="bg-gray-50 rounded-lg p-4 mb-8 text-left">
                <div class="flex items-center text-sm text-gray-500">
                    <i class="fa fa-file-text-o w-5 text-gray-400"></i>
                    <span class="ml-2 truncate">{{ filename }}</span>
                </div>
            </div>
            
            <!-- 操作按钮 -->
            <div class="flex flex-col sm:flex-row gap-4 justify-center">
                <a href="{{ url_for('upload_file') }}" class="btn-action btn-primary flex items-center justify-center">
                    <i class="fa fa-upload mr-2"></i>上传另一个文件
                </a>
                <a href="{{ url_for('home') }}" class="btn-action btn-secondary flex items-center justify-center">
                    <i class="fa fa-home mr-2"></i>返回首页
                </a>
            </div>
        </div>
        
        <!-- 页脚 -->
        <footer class="mt-10 text-gray-400 text-sm">
            <p>© 2025 FTP功能小网站 - 便捷快速的文件传输服务 - AndyDennis</p>
        </footer>
    </div>
    
    <!-- 动画样式 -->
    <style>
        @keyframes float {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }
        @keyframes pulseSlow {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.05); }
        }
        .animate-float {
            animation: float 3s ease-in-out infinite;
        }
        .animate-pulse-slow {
            animation: pulseSlow 2s ease-in-out infinite;
        }
    </style>
</body>
</html>

下载页面 download_page.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>下载文件 - FTP功能小网站</title>
    <!-- 引入Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#4F46E5',
                    }
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .file-item-hover {
                @apply bg-blue-50;
            }
        }
    </style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-teal-50 min-h-screen font-sans text-gray-800">
    <div class="container mx-auto px-4 py-8 max-w-4xl">
        <!-- 页面标题 -->
        <header class="text-center mb-10 mt-6">
            <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-primary mb-2">
                <i class="fa fa-cloud-download mr-3"></i>文件下载
            </h1>
            <p class="text-gray-500">选择您需要下载的文件</p>
        </header>
        
        <!-- 文件列表卡片 -->
        <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
            <!-- 列表头部 -->
            <div class="bg-gray-50 px-6 py-4 border-b border-gray-100">
                <h2 class="font-semibold text-gray-700">可供下载的文件</h2>
            </div>
            
            <!-- 文件列表 -->
            <div class="divide-y divide-gray-100">
                {% if fl and fl|length > 0 %}
                    {% for file in fl %}
                    <div class="px-6 py-4 flex items-center justify-between transition-all duration-200 hover:file-item-hover">
                        <!-- 文件名 -->
                        <div class="flex items-center">
                            <div class="w-10 h-10 rounded bg-gray-100 flex items-center justify-center mr-4 text-gray-500">
                                <i class="fa fa-file-o"></i>
                            </div>
                            <span class="font-medium text-gray-800 truncate max-w-md">{{ file }}</span>
                        </div>
                        
                        <!-- 下载按钮 -->
                        <a href="{{ url_for('download_file', filename=file) }}" 
                           class="inline-flex items-center bg-primary/10 text-primary px-4 py-2 rounded-lg transition-all duration-200 hover:bg-primary hover:text-white">
                            <i class="fa fa-download mr-2"></i>
                            <span>下载</span>
                        </a>
                    </div>
                    {% endfor %}
                {% else %}
                    <!-- 空状态 -->
                    <div class="px-6 py-16 text-center">
                        <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-gray-100 text-gray-400 mb-4">
                            <i class="fa fa-folder-open-o text-2xl"></i>
                        </div>
                        <p class="text-gray-500">暂无可供下载的文件</p>
                    </div>
                {% endif %}
            </div>
        </div>
        
        <!-- 返回按钮 -->
        <div class="text-center">
            <a href="{{ url_for('home') }}" class="inline-flex items-center text-primary hover:text-primary/80 transition-colors">
                <i class="fa fa-arrow-left mr-2"></i>返回首页
            </a>
        </div>
        
        <!-- 页脚 -->
        <footer class="mt-16 text-center text-gray-400 text-sm">
            <p>© 2025 FTP功能小网站 - 便捷快速的文件传输服务 - AndyDennis</p>
        </footer>
    </div>
    
    <!-- 简单的动画效果 -->
    <script>
        // 添加页面加载动画
        document.addEventListener('DOMContentLoaded', () => {
            const fileItems = document.querySelectorAll('.divide-y > div');
            fileItems.forEach((item, index) => {
                setTimeout(() => {
                    item.classList.add('animate-fade-in');
                }, 100 * index);
            });
        });
        
        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(10px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .animate-fade-in {
                animation: fadeIn 0.3s ease-out forwards;
            }
        `;
        document.head.appendChild(style);
    </script>
</body>
</html>
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐