DeepSeek帮我做的口语闪卡

跟DeepSeek交流了几轮,他帮我做了一个口语闪卡程序。先看图,再看核心提示词,最后是代码。

先上传Excel格式的笔记
点卡片的任意位置可翻页看中文意思
点右下解的随机切换,可换另一张卡片

核心提示词

ROUND 1

这是我整理的简单口语笔记,请帮我生成一个Flashcard的互动网页,辅助记忆。
界面要求精美直观,卡片可以翻转。
在合理的位置放置按钮,用于随机切换下一句子。
请使用主流的CSS框架,配色请采用粉色为主色调,字体要清晰美观;
请使用一个灵活的方式来引用Excel文件中的笔记,因为我会持续更新这个笔记。

ROUND 2

似乎不能用。因为我没有相应的JSON文件吗?Excel转JSON不能在这个页面内实现吗?

ROUND 3

好的,这个版本可用。但是界面很丑。首先,卡片没有边界;其次,卡片内的文字与卡片也没有留白。另外,卡片与按钮之间的距离太远。能不能优化一下?

ROUND 4

不不不,请返回完整的代码

下面是完整的代码,不明觉厉!!!

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>口语记忆卡片 - 优化版</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
    <style>
        :root {
            --primary-pink: #FF69B4;
            --secondary-pink: #FFB6C1;
            --text-dark: #2E2E2E;
        }

        body {
            font-family: 'Poppins', sans-serif;
            background: linear-gradient(135deg, #FFF0F5 0%, #FFE4E1 100%);
            min-height: 100vh;
            padding: 2rem 0;
        }

        .main-container {
            max-width: 800px;
            margin: 0 auto;
        }

        /* 卡片容器 */
        .card-container {
            perspective: 1000px;
            width: 100%;
            height: 450px;
            margin-bottom: 1.5rem;
        }

        .flashcard {
            transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
            transform-style: preserve-3d;
            background: white;
            border-radius: 20px;
            border: 2px solid var(--primary-pink);
            box-shadow: 0 12px 24px rgba(255,105,180,0.15);
            height: 100%;
        }

        .card-front, .card-back {
            backface-visibility: hidden;
            position: absolute;
            width: 100%;
            height: 100%;
            padding: 3rem;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .card-front {
            border-radius: 20px;
            background: linear-gradient(135deg, white 0%, #FFF5F9 100%);
        }

        .card-back {
            transform: rotateY(180deg);
            background: linear-gradient(45deg, var(--primary-pink), var(--secondary-pink));
            color: white;
        }

        .flipped {
            transform: rotateY(180deg);
        }

        /* 文字排版 */
        .card-front h2 {
            font-size: 2.25rem;
            color: var(--text-dark);
            margin-bottom: 1.5rem;
            line-height: 1.4;
            text-align: center;
            font-weight: 600;
        }

        .card-back h3 {
            font-size: 1.75rem;
            margin-bottom: 2rem;
            line-height: 1.5;
            text-align: center;
            padding: 0 2rem;
            font-weight: 500;
        }

        /* 按钮样式 */
        .btn-pink {
            background: var(--primary-pink);
            color: white;
            padding: 0.8rem 2rem;
            border-radius: 30px;
            border: none;
            font-weight: 500;
            transition: all 0.3s ease;
        }

        .btn-pink:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(255,105,180,0.3);
        }

        /* 上传区域 */
        .upload-section {
            border: 2px dashed var(--primary-pink);
            border-radius: 20px;
            padding: 2rem;
            background: rgba(255,255,255,0.9);
            transition: all 0.3s;
            cursor: pointer;
        }

        .upload-section:hover {
            background: rgba(255,182,193,0.1);
            transform: translateY(-3px);
        }

        /* 进度显示 */
        .counter {
            color: var(--primary-pink);
            font-weight: 600;
            font-size: 1.1rem;
        }

        /* 加载状态 */
        .loading-text {
            color: var(--primary-pink);
            font-size: 1.2rem;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0%, 100% { opacity: 0.6; }
            50% { opacity: 1; }
        }
    </style>
</head>
<body>
    <div class="main-container" id="app">
        <!-- 标题 -->
        <h1 class="text-center mb-4" style="color: var(--primary-pink);">
            📖 口语记忆卡片
            <div class="h6 mt-2 text-muted">点击卡片查看翻译</div>
        </h1>

        <!-- 上传区域 -->
        <div class="text-center mb-5" v-if="!cards.length">
            <label class="upload-section">
                <input type="file" id="excelFile" accept=".xlsx" hidden @change="handleFile">
                <div class="h4 mb-3">📤 点击上传Excel文件</div>
                <div class="text-muted">支持标准Excel格式(.xlsx)</div>
                <div class="mt-3 loading-text" v-if="isLoading">正在加载数据...</div>
            </label>
        </div>

        <!-- 卡片区域 -->
        <div v-else>
            <div class="card-container" @click="flipCard">
                <div class="flashcard" :class="{flipped: isFlipped}">
                    <div class="card-front">
                        <h2>{{ currentCard.en }}</h2>
                        <small class="text-muted mt-2">点击翻转卡片</small>
                    </div>
                    <div class="card-back">
                        <h3>{{ currentCard.cn }}</h3>
                        <div class="counter mt-3">ID: {{ currentCard.id }}</div>
                    </div>
                </div>
            </div>

            <!-- 控制区域 -->
            <div class="d-flex justify-content-between align-items-center px-3">
                <div class="counter">
                    {{ currentIndex + 1 }} / {{ cards.length }}
                </div>
                <button class="btn btn-pink" @click="randomCard">
                    🔀 随机切换
                </button>
            </div>
        </div>
    </div>

    <script src="https://unpkg.com/vue@3.2.36/dist/vue.global.prod.js"></script>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    cards: [],
                    currentIndex: 0,
                    isFlipped: false,
                    isLoading: false
                }
            },
            computed: {
                currentCard() {
                    return this.cards[this.currentIndex] || {}
                }
            },
            methods: {
                async handleFile(event) {
                    const file = event.target.files[0];
                    if (!file) return;

                    this.isLoading = true;
                    const reader = new FileReader();
                    
                    reader.onload = (e) => {
                        try {
                            const data = new Uint8Array(e.target.result);
                            const workbook = XLSX.read(data, {type: 'array'});
                            const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
                            
                            // 转换Excel数据
                            const cards = XLSX.utils.sheet_to_json(firstSheet, {
                                header: ['id', 'en', 'cn'],
                                range: 1
                            }).filter(card => card.id && card.en);

                            this.cards = cards;
                            this.currentIndex = 0;
                        } catch (error) {
                            console.error('文件解析错误:', error);
                        } finally {
                            this.isLoading = false;
                        }
                    };
                    reader.readAsArrayBuffer(file);
                },

                flipCard() {
                    this.isFlipped = !this.isFlipped
                },

                randomCard() {
                    const newIndex = Math.floor(Math.random() * this.cards.length);
                    this.currentIndex = newIndex;
                    this.isFlipped = false;
                }
            }
        }).mount('#app')
    </script>
</body>
</html>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容