冲刺记录16

今天任务:创建数据库是想朋友圈功能,将每项记录存储到数据库,每个用户都可以点赞评论

遇到困难:无

<template>
    <div class="background-container">
        <!-- 模糊查询输入框 -->
        <input type="text" v-model="searchQuery" placeholder="请输入搜索关键字" class="search-input">
        <!-- 排序按钮 -->
        <div class="sorting-buttons">
            <button @click="sortByDate" class="sort-btn">按日期排序</button>
            <button @click="sortByLikes" class="sort-btn">按点赞数排序</button>
        </div>
        <!-- 展示从数据库中读取的所有结果 -->
        <div v-for="item in sortedItems" :key="item.id" class="item-container">
            <img :src="item.photo" alt="照片" class="photo">
            <p>地点: {{ item.place }}</p>
            <p>备注: {{ item.remark }}</p>
            <p>时间: {{ item.date }}</p>
            <!-- 操作按钮容器 -->
            <div class="action-buttons">
                <!-- 点赞按钮 -->
                <button @click="toggleLike(item)" :class="{ 'liked': likedItems.includes(item.id) }" class="like-btn">
                    <svg class="heart-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path v-if="likedItems.includes(item.id)" class="red-heart"
                            d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
                        <path v-else class="gray-heart"
                            d="M16.5 3C14.76 3 13.09 3.81 12 5.09 10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.64 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 6.14-7.9 10.05z" />
                    </svg>
                    {{ item.likes }}
                </button>
                <!-- 查看评论按钮 -->
                <button @click="toggleComment(item)" class="comment-btn">查看发表评论</button>
            </div>
            <!-- 评论输入框 -->
            <div v-if="item.showComment" class="comment-modal" @click="closeModal(item)">
                <div class="modal-content">
                    <textarea v-model="item.comment" placeholder="请输入评论,恶语伤人哟" class="comment-input"></textarea>
                    <button @click="addComment(item)" class="comment-btn">发表评论</button>
                    <!-- 评论区域 -->
                    <div v-if="item.comments.length > 0" class="comments-section">
                        <div v-for="(comment, index) in item.comments" :key="index" class="comment">
                            {{ comment }}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                items: [], // 用于存储从数据库读取的所有结果
                likedItems: [], // 用于存储用户已经点赞的项目的 id
                searchQuery: '', // 用于存储用户的模糊查询关键字
                sortBy: '', // 用于存储排序选项
            };
        },
        mounted() {
            // 页面加载后立即获取后端数据
            this.fetchData();
            // 从本地存储中加载用户点赞数据
            this.loadLikedItems();
        },
        computed: {
            // 根据用户输入的搜索关键字过滤项目列表
            filteredItems() {
                return this.items.filter(item => {
                    return (
                        (item.place?.toLowerCase() ?? '').includes(this.searchQuery.toLowerCase()) ||
                        (item.remark?.toLowerCase() ?? '').includes(this.searchQuery.toLowerCase()) ||
                        (item.date?.toLowerCase() ?? '').includes(this.searchQuery.toLowerCase())
                    );
                });
            },
            // 根据sortBy属性对过滤后的项目列表进行排序
            sortedItems() {
                let sortedData = this.filteredItems;
                if (this.sortBy === 'date') {
                    sortedData.sort((a, b) => new Date(b.date) - new Date(a.date));
                } else if (this.sortBy === 'likes') {
                    sortedData.sort((a, b) => b.likes - a.likes);
                }
                return sortedData;
            },
        },
        methods: {
            async toggleComment(item) {
                item.showComment = !item.showComment;
                if (item.showComment) {
                    await this.look(item);
                }
            },
            async look(item) {
                try {
                    const response = await fetch(`http://192.168.1.176:8081/book/${item.id}/comments`);
                    if (response.ok) {
                        const commentsData = await response.json();
                        if (typeof commentsData.comment === 'string') {
                            item.comments = [commentsData.comment];
                        } else {
                            console.error('获取评论数据格式错误:', commentsData);
                            item.comments = [];
                        }
                    } else {
                        console.error('获取评论失败:', response.statusText);
                        alert('获取评论失败,请稍后重试!');
                    }
                } catch (error) {
                    console.error('请求失败:', error);
                    alert('请求失败,请稍后重试!');
                }
            },
            async fetchData() {
                try {
                    const response = await fetch('http://192.168.1.176:8081/book');
                    if (response.ok) {
                        const data = await response.json();
                        data.forEach(item => {
                            item.likes = item.likes;
                            item.comment = '';
                            item.comments = [];
                            item.showComment = false;
                        });
                        this.items = data;
                    } else {
                        console.error('获取数据失败:', response.statusText);
                        alert('获取数据失败,请稍后重试!');
                    }
                } catch (error) {
                    console.error('请求失败:', error);
                    alert('请求失败,请稍后重试!');
                }
            },
            toggleLike(item) {
                if (!this.likedItems.includes(item.id)) {
                    item.likes++;
                    this.likedItems.push(item.id);
                    this.likeBook(item.id);
                    this.saveLikedItems();
                } else {
                    item.likes--;
                    const index = this.likedItems.indexOf(item.id);
                    if (index > -1) {
                        this.likedItems.splice(index, 1);
                    }
                    this.unlikeBook(item.id);
                    this.saveLikedItems();
                }
            },
            likeBook(id) {
                return fetch(`http://192.168.1.176:8081/book/${id}/like`, {
                    method: 'PUT',
                }).then(response => {
                    if (!response.ok) {
                        console.error('点赞失败:', response.statusText);
                        alert('点赞失败,请稍后重试!');
                    }
                }).catch(error => {
                    console.error('请求失败:', error);
                    alert('请求失败,请稍后重试!');
                });
            },
            unlikeBook(id) {
                return fetch(`http://192.168.1.176:8081/book/${id}/unlike`, {
                    method: 'PUT',
                }).then(response => {
                    if (!response.ok) {
                        console.error('取消点赞失败:', response.statusText);
                        alert('取消点赞失败,请稍后重试!');
                    }
                }).catch(error => {
                    console.error('请求失败:', error);
                    alert('请求失败,请稍后重试!');
                });
            },
            addComment(item) {
                fetch(`http://192.168.1.176:8081/book`, {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        id: item.id,
                        comment: item.comment
                    })
                }).then(response => {
                    if (response.ok) {
                        item.comment = '';
                        item.showComment = false;
                    } else {
                        console.error('写入失败:', response.statusText);
                        alert('写入失败,请稍后重试!');
                    }
                }).catch(error => {
                    console.error('请求失败:', error);
                    alert('请求失败,请稍后重试!');
                });
            },
            closeModal(item) {
                const target = event.target;
                const modal = target.closest('.modal-content');
                if (!modal) {
                    item.showComment = false;
                }
            },
            saveLikedItems() {
                localStorage.setItem('likedItems', JSON.stringify(this.likedItems));
            },
            loadLikedItems() {
                const likedItems = localStorage.getItem('likedItems');
                if (likedItems) {
                    this.likedItems = JSON.parse(likedItems);
                }
            },
            sortByDate() {
                this.sortBy = 'date';
            },
            sortByLikes() {
                this.sortBy = 'likes';
            }
        }
    };
</script>

<style scoped>
    .background-container {
        padding: 20px;
        background-image: url('/static/111.jpg');
        background-size: cover;
        background-position: center;
        min-height: 100vh;
        background-attachment: fixed;
        overflow-y: auto;
    }

    .item-container {
        border: 1px solid #ccc;
        padding: 10px;
        margin-bottom: 20px;
    }

    .photo {
        max-width: 100%;
        height: auto;
    }

    .action-buttons {
        display: flex;
        align-items: center;
    }

    .like-btn,
    .comment-btn {
        background-color: transparent;
        border: none;
        cursor: pointer;
        display: inline-block;
        margin-right: 10px;
    }

    .like-btn svg {
        width: 20px;
        height: 20px;
        vertical-align: middle;
    }

    .comment-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .modal-content {
        width: 200px;
        background-image: url('/static/222.jpg');
        background-size: cover;
        padding: 20px;
        border-radius: 5px;
    }

    .comment-input {
        width: 100%;
        resize: vertical;
    }

    .comments-section {
        margin-top: 10px;
    }

    .comment {
        margin-bottom: 5px;
    }

    .liked .red-heart {
        fill: red;
    }

    .search-input {
        margin-bottom: 10px;
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 5px;
        width: 100%;
    }

    .sorting-buttons {
        display: flex;
        margin-bottom: 10px;
    }

    .sort-btn {
        margin-right: 10px;
    }
</style>
posted @ 2024-05-09 21:12  徐星凯  阅读(10)  评论(0编辑  收藏  举报