django美食推荐系统--附源码23872


 

随着人们生活水平的提高和消费需求的多样化,餐饮行业面临着更为复杂的选择问题。消费者在面对众多餐厅和菜品时,往往难以迅速找到符合个人口味的最佳选择。为了解决这一问题,基于Python的美食推荐系统通过分析用户的历史数据和偏好,提供个性化的餐饮推荐。利用Python语言的丰富生态和灵活性,结合Django框架的高效开发能力,系统能够有效地管理用户信息、菜品分类和餐厅数据,实现精准的推荐功能。通过对用户行为的深度分析,系统能够推荐符合用户口味的餐饮选项,不仅提升了用户的就餐体验,还增强了餐饮平台的用户粘性和活跃度。同时,Django框架的优越性能和扩展性确保了系统在处理大量数据时的稳定运行,为美食推荐提供了强有力的技术保障。

关键词:Django框架;美食推荐系统;Python语言;MySQL

Abstract

With the improvement of people's living standards and the diversification of consumer demands, the catering industry is facing more complex choice problems. Consumers often find it difficult to quickly find the best choice that suits their personal taste when faced with numerous restaurants and dishes. To address this issue, a Python based food recommendation system provides personalized food recommendations by analyzing users' historical data and preferences. By utilizing the rich ecosystem and flexibility of Python language, combined with the efficient development capabilities of Django framework, the system can effectively manage user information, dish classification, and restaurant data, and achieve accurate recommendation functions. Through in-depth analysis of user behavior, the system can recommend catering options that meet the user's taste, which not only enhances the user's dining experience, but also increases the user stickiness and activity of the catering platform. Meanwhile, the superior performance and scalability of the Django framework ensure stable operation of the system when processing large amounts of data, providing strong technical support for food recommendations.

Keywords: Django framework; Food recommendation system; Python language; MySQL

目  录

1 绪  论

1.1 研究背景

1.2 研究目的和意义

1.3 国内外研究现状

1.4 论文结构与章节安排

2 关键技术介绍

2.1 B/S体系结构

2.2 Django框架

2.3 MySQL数据库

2.4 Python语言

3 系统分析

3.1 可行性分析

3.1.1 技术可行性

3.1.2 经济可行性

3.1.3 操作可行性

3.2 系统功能需求分析

3.3 系统用例分析

3.3.1 注册用户用例分析

3.3.2 管理员用例分析

3.4 非功能需求分析

3.5 系统流程分析

3.5.1 用户注册流程图

3.5.2 用户登录流程图

3.5.3 程序操作流程

4 系统设计

4.1 系统架构设计

4.2 功能模块设计

4.3 数据库设计

4.3.1 概念设计

4.3.2 逻辑设计

5 系统实现

5.1 前台用户模块的实现

5.1.1 用户注册界面

5.1.2 用户登录界面

5.1.3 前台首页界面

5.1.4 美食资讯界面

5.1.5 美食信息界面

5.1.6 个人中心界面

5.2 后台管理模块的实现

5.2.1 后台登录界面

5.2.2 后台首页界面

5.2.3 系统用户界面

5.2.4 美食信息管理界面

5.2.5 系统管理界面

5.2.6 资源管理界面

6 系统测试

6.1 测试目的

6.2 测试用例

6.3 测试结果

结  论

参考文献

附 录

系统关键代码

1绪  论

1.1研究背景

随着现代社会生活节奏的加快和人们对饮食要求的多样化,传统的餐饮选择方式已无法满足消费者对个性化和高效服务的需求。在信息技术飞速发展的背景下,餐饮行业开始逐步转向智能化、个性化的服务模式,以便更好地适应消费者日益增长的需求。面对繁多的餐厅和菜品选择,用户往往难以快速找到最适合自己的餐饮选项,提升选择效率成为行业亟待解决的问题。与此同时,餐饮平台的竞争也日益激烈,如何通过技术手段增强用户体验、提高用户粘性和满意度,成为了商家关注的重点。因此,基于用户兴趣和偏好的餐饮推荐系统,逐渐成为餐饮平台发展的关键方向之一。通过利用现有技术,能够有效整合用户行为数据、餐饮信息和偏好分析,进而提供个性化的餐饮推荐,为用户带来更加便捷、精准的选择体验。

1.2研究目的和意义

基于Python的美食推荐系统,为餐饮行业带来更加智能化和个性化的服务解决方案。随着消费者需求的多样化以及餐饮行业竞争的加剧,传统的餐饮选择方式逐渐无法满足用户对便捷、高效、精准推荐的期待。美食推荐系统通过对用户历史偏好、评价数据、位置和其他相关信息的综合分析,能够为每位用户提供符合其口味和需求的餐饮推荐,显著提高选择的效率,减少决策时间,从而增强用户的使用体验。

此项研究的意义不仅在于技术层面的创新和应用,还体现在提升餐饮平台整体服务质量和用户满意度方面。通过个性化的推荐,系统能够帮助用户发现更多符合自己口味的餐厅和菜品,避免了传统餐饮选择中的盲目性和信息过载。同时,餐饮平台可以通过分析推荐系统产生的数据,深入了解用户需求,进一步优化菜品和服务内容,增加客户的忠诚度和平台的长期粘性。个性化推荐的实现,也为商家提供了更多的营销机会和精准广告投放方式,推动了商业转化和平台收益的提升。

1.3国内外研究现状

在国内,美食推荐系统的研究起步较晚,但随着互联网和智能手机的普及,餐饮行业的线上化和信息化进程加速。各大餐饮平台和技术公司纷纷涉足个性化推荐领域。随着大众点评、美团等平台的兴起,基于用户评价和餐饮数据的推荐技术逐渐获得了广泛应用。国内的研究主要集中在如何通过用户的历史评价、消费记录和偏好分析,为用户提供更精准的餐饮推荐。

国内的研究方向较为多样化,包括基于协同过滤、基于内容的推荐算法等传统推荐技术,也有一些学者开始探索结合地理信息、社交网络以及用户行为数据的混合推荐方法。特别是在餐饮行业,基于位置的推荐技术得到了较多关注,许多平台结合用户的当前位置,实时推送附近的优质餐厅,提升了用户的使用体验。近年来,国内一些餐饮平台也开始注重与社交媒体的结合,通过社交网络中的用户行为来进一步优化推荐系统。此外,国内的研究还特别关注算法的计算效率和用户隐私保护问题,随着平台数据量的增长,如何平衡推荐精度和系统性能,成为了国内研究的一个重要课题。

总体来看,国内在美食推荐系统的应用方面起步较晚,但随着市场需求的增加,相关技术不断成熟,推荐系统的个性化、实时性和智能化水平逐步提升。随着人工智能技术的发展,未来国内的美食推荐系统有望在用户体验和商业价值的实现上迈上新台阶。

1.4论文结构与章节安排

本文的结构按逻辑顺序分为以下几个章节:

第1章绪论,本章节介绍研究背景和意义,回顾当前研究现状,并阐明本文主要组织结构。

第2章系统关键技术,本章节将对美食推荐系统的实现关键技术进行简要介绍。

第3章系统分析,本章节基于市场调研,分析美食推荐系统的可行性、功能、角色、性能等需求,明确各模块的业务需求。

第4章系统设计,本章节详细阐述系统的整体架构设计,包括前后端结构、数据库设计及功能模块的设计思路。

第5章系统实现,本章节介绍系统各主要模块的具体实现,包括代码示例、业务逻辑及界面设计等。

第6章系统测试,本章节描述系统的测试方法及结果,分析系统的性能、稳定性及用户反馈。

第7章结论,本章节对主要对研究成果进行总结。


2 关键技术介绍

2.1B/S体系结构 

B/S体系[1],即Browser/Server体系,是一种常见的网络应用程序架构。其工作原理基于客户端与服务器之间的请求-响应模型。用户通过浏览器向服务器发送请求,服务器接收到请求后进行处理,并生成相应的响应结果,最终将响应返回给客户端。浏览器接收到服务器返回的响应后,解析其中的标记语言(如HTML[2]),并根据CSS样式表和PythonScript脚本来渲染页面,呈现给用户。用户可以与页面进行交互,例如点击链接、填写表单等操作,这些操作会触发新的请求,循环执行上述过程。

2.2Django框架

Django是一个使用Python语言开发的Web应用程序框架[3]。它提供了一种简单而强大的方式来构建复杂的网站和应用程序。通过使用Django,开发人员可以更轻松地处理数据库、创建用户界面和处理用户请求。它还提供了一个自动生成管理界面的功能,使得管理后台数据变得更加简单。Django还具有强大的安全功能,可以保护网站免受常见的网络攻击[4]。总之,Django是一个非常实用和易于学习的框架,适用于各种规模的Web项目。无论你是初学者还是经验丰富的开发人员,都可以从Django的便利性和灵活性中受益。

2.3MySQL数据库

MySQL是一种广泛使用的开源关系型数据库管理系统[5](RDBMS),其稳定性、可靠性和卓越性能使其成为众多应用程序的首选数据库。MySQL支持标准SQL语法,并提供丰富的功能和特性,如事务处理、触发器和存储过程等,以满足开发者对数据管理和操作的需求。MySQL具有良好的可扩展性,支持主从复制、分布式架构和集群部署,适用于各种规模和负载的应用场景。作为一个开源项目,MySQL拥有庞大的用户社区和活跃的开发者社区,为用户提供了丰富的文档、教程和支持资源。总之,MySQL是一款可靠、强大且灵活的关系型数据库管理系统[6],通过其卓越性能和可扩展性,帮助开发者高效地管理和操作数据,并得到了广大用户的认可和应用。

2.4Python语言

Python是一种简洁易读、跨平台且功能强大的编程语言[7]。它拥有庞大而活跃的社区,提供了丰富的第三方库和框架,如NumPy、Pandas和Django,使开发人员能够快速构建各种应用程序。Python在数据处理和科学计算方面表现出色,通过相关库和工具,可以进行数据分析、机器学习和科学计算等任务。此外,Python广泛应用于Web开发[8]、自动化脚本、网络爬虫等领域,其多样性使其成为一个全能的编程语言。无论你是初学者还是有经验的开发者,Python的简单语法、跨平台性以及强大的社区支持都能为你提供高效、优雅和可靠的编程体验。总之,Python是一个强大而灵活的编程语言,深受开发人员喜爱,并在各个领域得到广泛应用。


3 系统分析

3.1可行性分析

3.1.1技术可行性

在技术可行性方面,选择使用Python作为开发语言,结合相应的框架Django,以实现系统的功能需求。Python作为一种简洁而强大的编程语言,具有丰富的库支持和成熟的开发社区,可以满足美食推荐系统的开发需求。Django作为Python的Web框架,提供了高度可扩展的开发环境,使得系统的设计和实现更加便捷和高效。

3.1.2经济可行性

系统开发采用开源技术栈,降低了软件授权与工具采购成本。Django框架简化了开发流程,缩短了项目周期,减少了人力投入。此外,借助云计算资源部署系统,可根据实际需求灵活调整服务器配置,进一步降低硬件成本。总体而言,该方案在经济上具有较高性价比,适合中小型企业或初创团队实施。

3.1.3操作可行性

在操作可行性方面,本系统设计注重用户体验,采用了直观易用的界面设计,并提供详细的帮助文档支持,确保用户可以轻松上手使用各项功能。无论是用户还是后台管理员,都能通过简洁明了的操作流程完成信息查询和管理等任务。因此,从用户操作的角度来看,本系统具备良好的操作可行性。

3.2系统功能需求分析

本系统旨在满足美食信息的多样化运营需求,针对注册用户和管理员两大角色提供全面的功能支持。注册用户可通过系统实现商品浏览、购物车管理、书籍租借及个人中心操作,享受便捷的消费体验;管理员则负责后台数据维护、订单审核、库存管理和系统配置等任务,确保书店高效运营。通过功能模块的精细化设计,系统实现了业务流程的自动化与智能化,为美食信息的数字化转型提供了技术支持。具体描述如下:

  1. 注册用户模块:

首页:用户通过首页可以快速浏览到平台的最新美食推荐、热门餐厅、特价优惠及活动信息,提供直观的导航功能,使得用户可以迅速找到感兴趣的内容并进入具体页面,帮助提升用户的使用体验和互动参与度,确保平台内容的高效展示和用户的便捷操作。

网站公告:网站公告功能展示平台的最新动态和通知,例如系统更新、活动预告、重要政策变动等,确保用户能够及时了解平台的各种重要信息,增强与用户的沟通,提升透明度,帮助用户更好地掌握平台运营的动态,提升信任度。

美食资讯:美食资讯功能提供最新的餐饮行业新闻、饮食健康资讯及美食文化内容,帮助用户获取行业动态、饮食建议及热门趋势,使得平台不仅仅是一个餐饮推荐平台,还能成为一个信息共享和知识传播的渠道,增强平台的附加价值。

美食信息:美食信息功能展示详细的菜品介绍、餐厅资料、营养成分等相关信息,帮助用户在选择餐厅或菜品时获取所需的详细背景信息,提升决策的准确性,并通过详细的餐饮信息进一步满足用户对食品质量和饮食需求的多样化关注。

我的账户:用户账户功能包含个人资料管理、历史订单查看、积分和优惠券使用等内容,帮助用户更方便地管理个人信息和消费记录,同时也为用户提供个性化的服务和推荐,通过账号管理提升用户的使用便捷性和平台粘性。

个人中心:个人中心是用户管理个人信息的核心区域,提供个人首页、收藏、评论管理等功能,允许用户查看和编辑个人资料、收藏喜爱的餐厅或菜品、管理和发布个人评价,增强用户与平台的互动,提升用户体验的个性化和深度。

  1. 管理员模块:

后台首页:管理员后台首页是系统管理的控制中心,展示平台的运营概况,包括用户活跃度、订单量、商品流行趋势等关键数据,通过数据仪表板帮助管理员实时监控平台运行状态,制定运营策略,有效支持决策和业务优化。

系统用户(管理员、注册用户):系统用户管理功能允许管理员对平台的用户进行管理,区分管理员和普通注册用户,设置不同权限,确保后台数据安全和操作权限的分配合理,同时提供用户信息的查看、修改和管理功能,保障系统的稳定和高效运行。

美食分类管理:美食分类管理功能帮助管理员对平台中的美食进行分类和维护,包括对菜品种类、餐厅类型的设定和调整,确保平台中美食的分类清晰合理,提升用户查找菜品的便捷性和准确性,确保信息架构的清晰性和用户体验的优化。

美食信息管理:美食信息管理功能使管理员能够更新、编辑和删除餐厅和菜品的详细信息,包括名称、价格、简介、图片等,确保平台展示的菜品信息始终保持准确、清晰和最新,提升用户选择时的决策效率和平台内容的可用性。

系统管理(轮播图管理):系统管理中的轮播图管理功能使管理员可以对平台首页的广告轮播图进行添加、删除和更新,确保首页的动态展示始终与当前的促销活动或热点内容一致,提升平台的吸引力和用户的参与度,同时优化页面布局和用户导航。

网站公告管理:网站公告管理功能使管理员能够发布、编辑和删除平台上的公告信息,及时传达重要事项、系统维护、活动预告等,保障平台与用户之间的高效沟通,提升信息流通的及时性和准确性,同时增强平台的专业性和用户信任度。

资源管理(美食资讯、资讯分类):资源管理功能帮助管理员维护和更新平台的美食资讯栏目,包括对资讯分类、内容更新和管理等,确保平台上的信息始终紧跟行业热点、饮食趋势和用户兴趣,增强平台的内容价值和知识共享功能,提升用户的持续关注度。

3.3系统用例分析

3.3.1注册用户用例分析

用户通过平台可以轻松浏览到最新的美食推荐、餐厅信息以及优惠活动等,通过首页、网站公告、美食资讯等功能获取及时的饮食信息,同时还能管理个人账户,查看订单、收藏餐厅与菜品,参与评论和互动,提升个性化体验。整体而言,平台为用户提供了一个便捷、高效的餐饮信息获取与管理中心,让用户能够随时随地做出理想的就餐决策,并享受个性化的服务和推荐。注册用户角色用例图如下所示。

图3-1 注册用户用例图

3.3.2管理员用例分析

管理员通过后台系统进行平台的全面管理,包括用户信息、餐饮内容、公告发布以及系统设置等。管理员可以随时更新美食分类、餐厅和菜品信息,调整轮播图和公告内容,确保平台内容的时效性和准确性。同时,后台提供详尽的数据分析,帮助管理员及时了解平台的运行情况,优化用户体验和运营策略,确保平台的高效运营和用户的满意度。

管理员角色用例图如下所示。

图3-2 管理员用例图

3.4非功能需求分析

系统非功能需求指的是性能需求,对一个系统的性能需求进行分析和定义的过程。在进行性能需求分析时,因此美食推荐系统的设计与实现主要需要考虑以下几个方面的性能需求:

响应时间:响应时间是指系统在接收到请求后,作出响应的时间。根据具体的业务需求和用户体验要求,可以确定系统在不同场景下的响应时间要求。

吞吐量:吞吐量是指系统在一定时间内处理的事务或请求的数量。根据业务需求和用户量的估计,可以确定系统需要支持的最大吞吐量。

并发用户数:并发用户数是指系统在同时使用的用户数量。根据预期的用户量和并发访问需求,可以确定系统需要支持的最大并发用户数。

可扩展性:可扩展性是指系统在面对用户量增加或并发访问需求增加时,能否通过增加硬件资源或调整系统架构来满足需求。根据预期的用户增长和扩展计划,可以确定系统需要具备的可扩展性要求。

故障处理能力:系统对故障的处理能力是指在出现错误或故障时,系统能够快速、准确地识别、定位并处理故障的能力。根据业务的重要性和对故障处理的要求,可以确定系统需要具备的故障处理能力。

安全性:系统在性能需求分析中,也需考虑安全方面的需求,如数据的保密性、完整性和可用性等。根据具体的安全需求和合规要求,可以确定系统需要满足的安全性需求。

通过对这些性能需求进行详细分析和定义,可以为美食推荐系统的设计和开发提供指导,确保系统在满足预期的性能需求的同时,具备良好的性能和可靠性。

3.5系统流程分析

3.5.1用户注册流程图

注册的过程,第一部分是账号的注册,第二部分是信息完善。在业务开展过程中,管理员可对用户信息进行修改等管理操作,注册流程如图3-3用户注册流程图所示。

图3-3用户注册流程图

3.5.2用户登录流程图

登录时,用户填写用户名、密码、选择身份进行登录,在登录过程中后端会对发送过来的信息进行验证和判断,具体的登录流程如图3-4用户登录流程图所示。

图3-4用户登录流程图

3.5.3 程序操作流程

用户访问平台网站,可以选择进行注册或登录操作。注册成功后,用户可以使用注册的账号登录平台。登录后的用户可以进入系统功能界面,使用自己权限内的功能操作。具体程序操作流程图如图3-5所示。

图3-5程序操作流程图

4系统设计

4.1系统架构设计

从技术角度来看,美食推荐系统的架构设计至关重要。我们将采用MVC架构,包括表现层、业务逻辑层和数据访问层。表现层负责用户界面展示,业务逻辑层处理核心功能逻辑,数据访问层负责数据库交互。通过三层架构模式,确保系统的可靠性和可扩展性。

系统架构图如图4-1所示。

图4-1 系统架构图

4.2功能模块设计

通过整体功能模块设计,我们将根据需求分析的结果,将系统的功能划分为不同的模块。每个模块负责实现特定的功能,并与其他模块进行协作。我们将详细定义每个模块的输入、输出、处理逻辑和相互依赖关系。系统总体功能模块图如下图所示。

图4-2 系统功能模块图

4.3数据库设计

4.3.1概念设计

借助先进的系统,E-R图使其他用户可以快速轻松地了解系统的功能以及他们之间的关系。根据美食推荐系统分析结果,本美食推荐系统总体E-R图如下图所示。

图4-3 系统总体E-R图

4.3.2逻辑设计

所有系统的应用数据相互区分。一旦在相应的系统中实现,它们将与自己相应的网络和服务器通信。所以这个系统可以连接这些数据。当我们选择桥梁截面时,以下将简要介绍如何建立系统。在单击上一个按键的时候,就会自动在对话框中弹出数据源的名字,之后再单击下一个按键时,就在填写相对应的身份验证和登录信息。按照系统功能设计的特点与职能模块的分类,美食推荐系统的总体设计和实施过程一共涉及到了几个资料表格。

根据E-R图,建立各个实体的数据表。由于本系统数据库数据表数量较多,所以只选取部分表单作为案列,如下所示:

表 4-1-access_token(登陆访问时长)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

token_id

int

临时访问牌ID

2

token

varchar

64

临时访问牌

3

info

text

65535

信息

4

maxage

int

最大寿命:默认2小时

5

create_time

timestamp

创建时间

6

update_time

timestamp

更新时间

7

user_id

int

用户编号

表 4-2-article(文章)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

article_id

mediumint

文章id

2

title

varchar

125

标题

3

type

varchar

64

文章分类

4

hits

int

点击数

5

praise_len

int

点赞数

6

create_time

timestamp

创建时间

7

update_time

timestamp

更新时间

8

source

varchar

255

来源

9

url

varchar

255

来源地址

10

tag

varchar

255

标签

11

content

longtext

4294967295

正文

12

img

varchar

255

封面图

13

description

text

65535

文章描述

表 4-3-article_type(文章分类)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

type_id

smallint

分类ID

2

display

smallint

显示顺序

3

name

varchar

16

分类名称

4

father_id

smallint

上级分类ID

5

description

varchar

255

描述

6

icon

text

65535

分类图标

7

url

varchar

255

外链地址

8

create_time

timestamp

创建时间

9

update_time

timestamp

更新时间

表 4-4-auth(用户权限管理)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

auth_id

int

授权ID

2

user_group

varchar

64

用户组

3

mod_name

varchar

64

模块名

4

table_name

varchar

64

表名

5

page_title

varchar

255

页面标题

6

path

varchar

255

路由路径

7

parent

varchar

64

父级菜单

8

parent_sort

int

父级菜单排序

9

position

varchar

32

位置

10

mode

varchar

32

跳转方式

11

add

tinyint

是否可增加

12

del

tinyint

是否可删除

13

set

tinyint

是否可修改

14

get

tinyint

是否可查看

15

field_add

text

65535

添加字段

16

field_set

text

65535

修改字段

17

field_get

text

65535

查询字段

18

table_nav_name

varchar

500

跨表导航名称

19

table_nav

varchar

500

跨表导航

20

option

text

65535

配置

21

create_time

timestamp

创建时间

22

update_time

timestamp

更新时间

表 4-5-code_token(验证码)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

code_token_id

int

验证码ID

2

token

varchar

255

令牌

3

code

varchar

255

验证码

4

expire_time

timestamp

失效时间

5

create_time

timestamp

创建时间

6

update_time

timestamp

更新时间

表 4-6-collect(收藏)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

collect_id

int

收藏ID

2

user_id

int

收藏人ID

3

source_table

varchar

255

来源表

4

source_field

varchar

255

来源字段

5

source_id

int

来源ID

6

title

varchar

255

标题

7

img

varchar

255

封面

8

create_time

timestamp

创建时间

9

update_time

timestamp

更新时间

表 4-7-comment(评论)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

comment_id

int

评论ID

2

user_id

int

评论人ID

3

reply_to_id

int

回复评论ID

4

content

longtext

4294967295

内容

5

nickname

varchar

255

昵称

6

avatar

varchar

255

头像地址

7

create_time

timestamp

创建时间

8

update_time

timestamp

更新时间

9

source_table

varchar

255

来源表

10

source_field

varchar

255

来源字段

11

source_id

int

来源ID

表 4-8-food_classification(美食分类)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

food_classification_id

int

美食分类ID

2

food_classification

varchar

64

美食分类

3

create_time

datetime

创建时间

4

update_time

timestamp

更新时间

表 4-9-food_information(美食信息)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

food_information_id

int

美食信息ID

2

food_name

varchar

64

美食名称

3

food_code

varchar

64

美食编号

4

food_classification

varchar

64

美食分类

5

food_pictures

varchar

255

美食图片

6

food_details

text

65535

美食详情

7

hits

int

点击数

8

praise_len

int

点赞数

9

collect_len

int

收藏数

10

comment_len

int

评论数

11

recommend

int

智能推荐

12

create_time

datetime

创建时间

13

update_time

timestamp

更新时间

表 4-10-hits(用户点击)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

hits_id

int

点赞ID

2

user_id

int

点赞人

3

create_time

timestamp

创建时间

4

update_time

timestamp

更新时间

5

source_table

varchar

255

来源表

6

source_field

varchar

255

来源字段

7

source_id

int

来源ID

表 4-11-notice(公告)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

notice_id

mediumint

公告ID

2

title

varchar

125

标题

3

content

longtext

4294967295

正文

4

create_time

timestamp

创建时间

5

update_time

timestamp

更新时间

表 4-12-praise(点赞)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

praise_id

int

点赞ID

2

user_id

int

点赞人

3

create_time

timestamp

创建时间

4

update_time

timestamp

更新时间

5

source_table

varchar

255

来源表

6

source_field

varchar

255

来源字段

7

source_id

int

来源ID

8

status

tinyint

点赞状态:1为点赞,0已取消

表 4-13-registered_user(注册用户)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

registered_user_id

int

注册用户ID

2

user_name

varchar

64

用户姓名

3

user_gender

varchar

64

用户性别

4

contact_information

varchar

16

联系方式

5

label_recommend

varchar

64

标签推荐

6

examine_state

varchar

16

审核状态

7

user_id

int

用户ID

8

create_time

datetime

创建时间

9

update_time

timestamp

更新时间

表 4-14-schedule(日程管理)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

schedule_id

smallint

日程ID

2

content

varchar

255

日程内容

3

scheduled_time

datetime

计划时间

4

user_id

int

用户ID

5

create_time

datetime

创建时间

6

update_time

datetime

更新时间

表 4-15-score(评分)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

score_id

int

评分ID

2

user_id

int

评分人

3

nickname

varchar

64

昵称

4

score_num

double

评分

5

create_time

timestamp

创建时间

6

update_time

timestamp

更新时间

7

source_table

varchar

255

来源表

8

source_field

varchar

255

来源字段

9

source_id

int

来源ID

表 4-16-slides(轮播图)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

slides_id

int

轮播图ID

2

title

varchar

64

标题

3

content

varchar

255

内容

4

url

varchar

255

链接

5

img

varchar

255

轮播图

6

hits

int

点击量

7

create_time

timestamp

创建时间

8

update_time

timestamp

更新时间

表 4-17-upload(文件上传)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

upload_id

int

上传ID

2

name

varchar

64

文件名

3

path

varchar

255

访问路径

4

file

varchar

255

文件路径

5

display

varchar

255

显示顺序

6

father_id

int

父级ID

7

dir

varchar

255

文件夹

8

type

varchar

32

文件类型

表 4-18-user(用户账户)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

user_id

int

用户ID

2

state

smallint

账户状态:(1可用|2异常|3已冻结|4已注销)

3

user_group

varchar

32

所在用户组

4

login_time

timestamp

上次登录时间

5

phone

varchar

11

手机号码

6

phone_state

smallint

手机认证:(0未认证|1审核中|2已认证)

7

username

varchar

16

用户名

8

nickname

varchar

16

昵称

9

password

varchar

64

密码

10

email

varchar

64

邮箱

11

email_state

smallint

邮箱认证:(0未认证|1审核中|2已认证)

12

avatar

varchar

255

头像地址

13

open_id

varchar

255

针对获取用户信息字段

14

create_time

timestamp

创建时间

表 4-19-user_group(用户组)

编号

字段名

类型

长度

是否非空

是否主键

注释

1

group_id

mediumint

用户组ID

2

display

smallint

显示顺序

3

name

varchar

16

名称

4

description

varchar

255

描述

5

source_table

varchar

255

来源表

6

source_field

varchar

255

来源字段

7

source_id

int

来源ID

8

register

smallint

注册位置

9

create_time

timestamp

创建时间

10

update_time

timestamp

更新时间


5 系统实现

5.1前台用户模块的实现

5.1.1用户注册界面

用户可以通过注册功能创建个人账号,填写包括用户名、密码、邮箱或手机号等基本信息完成注册流程。系统会对输入信息进行校验,确保唯一性和格式正确性,并将用户数据存储至数据库中,同时发送验证邮件或短信以确认账户有效性。用户注册界面如下图所示。

图5-1 用户注册界面

5.1.2用户登录界面

用户登录模块为前台用户提供安全快捷的访问方式。登录页面设计简洁明了,用户只需输入用户名及密码即可完成身份验证。登录成功后,用户将被重定向至系统首页页面。对于忘记密码的用户,提供了找回密码功能,通过邮箱或手机号接收重置链接,保障账户安全。用户登录界面如下图所示。

图5-2 用户登录界面    

5.1.3前台首页界面

前台首页界面是用户访问系统的入口页面,它应该展示平台的主要功能和特色,并提供导航链接以便用户浏览和搜索。首页界面的设计应注重页面的美观性和用户体验,同时也需要考虑页面的加载速度和响应性能。系统前台首页以上中下的布局进行展示,正上方是提供系统搜索功能和系统功能导航栏,中间是轮播图,下面是展示平台的美食推荐、网站公告展示等内容。前台首页界面如下图所示。

图5-3 前台首页界面

5.1.4美食资讯界面

美食资讯提供了餐饮行业的最新动态、饮食健康、餐饮趋势等信息,让用户不仅能够找到餐厅推荐,还能了解更多关于饮食的知识,提升平台的综合价值,吸引用户进行多维度的内容消费。美食资讯界面如下图所示。

图5-4 美食资讯界面

5.1.5美食信息界面

美食信息功能展示了详细的美食介绍、餐厅资料、营养成分等相关信息,帮助用户在选择餐厅或菜品时做出更为科学的决策,确保用户能够得到满足其需求的详细餐饮信息,提升选择效率。美食信息展示界面如下图所示。

图5-5 美食信息商品展示界面

5.1.6个人中心界面

个人中心是用户管理个人信息的核心区域,提供个人首页、收藏、评论管理等功能,允许用户查看和编辑个人资料、收藏喜爱的餐厅或菜品、管理和发布个人评价,增强用户与平台的互动,提升用户体验的个性化和深度。个人中心界面如下图所示。

图5-6 个人中心界面

5.2后台管理模块的实现

5.2.1后台登录界面

管理员通过后台登录模块验证身份后进入管理系统,该模块支持账号密码登录,并可选择记住登录状态或进行双因素认证以增强安全性。登录失败时提供错误提示,确保管理员账户的安全性。界面如下图所示。

图5-7 后台登录界面

5.2.2后台首页界面

管理员后台首页是系统管理的控制中心,展示平台的运营概况,制定运营策略,有效支持决策和业务优化。后台首页界面如下图所示。

图5-8 后台首页界面

5.2.3系统用户界面

系统用户模块用于管理员对注册用户账号进行统一管理,包括新增、编辑、删除用户信息以及调整用户权限状态。管理员可以通过搜索功能快速定位目标用户,并批量导入或导出用户数据。此外,模块还支持用户状态管理,确保系统的安全性与规范性。系统用户界面如下图所示。

图5-9 系统用户界面

5.2.4美食信息管理界面

美食信息管理功能使管理员能够更新、编辑和删除餐厅和菜品的详细信息,包括名称、价格、简介、图片等,确保平台展示的菜品信息始终保持准确、清晰和最新,提升用户选择时的决策效率和平台内容的可用性。美食信息管理界面如下图所示。

图5-10 美食信息管理界面

5.2.5系统管理界面

轮播图模块为管理员提供管理首页展示内容的功能,支持上传图片、设置链接地址以及调整显示顺序。管理员可以通过该模块灵活更新平台的宣传内容,吸引更多用户关注。系统通过后端接口将数据存储至数据库,确保前端展示效果与后台配置一致。轮播图管理界面如下图所示。

图5-11 轮播图管理界面

5.2.6资源管理界面

资源管理功能帮助管理员维护和更新平台的美食资讯栏目,包括对资讯分类、内容更新和管理等,确保平台上的信息始终紧跟行业热点、饮食趋势和用户兴趣,增强平台的内容价值和知识共享功能,提升用户的持续关注度。资源管理界面如下图所示。

图5-12 资源管理界面


6 系统测试

6.1测试目的

测试是为了验证系统在功能、性能、安全性和用户体验等方面的表现。通过测试,可以发现并修复潜在的问题和缺陷,确保系统的正常运行和稳定性。功能验证确保各项功能按设计要求运行;性能评估评估系统的响应时间和并发处理能力;安全检测确保系统的身份认证和数据传输安全;用户体验评估提升界面友好性和操作流程;兼容性测试确保系统在不同设备和浏览器上的兼容性。通过全面的测试,系统将更可靠地支持用户需求,并提供优质的用户体验。

6.2测试用例

对以下功能进行测试,包括包括用户注册、用户登录、美食信息商品搜索、美食信息商品查看、美食信息商品添加具体测试用例如下表所示。

6-1 用户注册测试用例表

用例编号

用例名称

测试步骤

测试结果

6-1

用户注册

1. 输入有效注册信息,包括用户名、密码和联系方式。

注册成功,系统保存用户信息。

2. 点击注册按钮进行提交。

跳转至登录页面。

3. 检查是否成功注册并跳转至登录页面。

用户成功注册,可以登录使用。

6-2 用户登录测试用例表

用例编号

用例名称

测试步骤

测试结果

6-2

用户登录

1. 输入正确用户名和密码。

登录成功,系统验证通过。

2. 点击登录按钮进行验证。

跳转至用户首页。

3. 检查是否成功登录并跳转至用户首页。

用户成功登录,进入用户首页。

6-3 美食信息商品搜索测试用例表

用例编号

用例名称

测试步骤

测试结果

6-3

美食信息商品搜索

1. 在搜索框输入关键词,如商品名称。

显示相关商品列表。

2. 点击搜索按钮进行搜索。

匹配关键词的美食信息商品显示在搜索结果中。

3. 检查是否显示相关美食信息商品列表。

用户看到与搜索关键词匹配的美食信息商品

6-4 美食信息商品查看测试用例表

用例编号

用例名称

测试步骤

测试结果

6-3

美食信息商品搜索

1. 点击美食信息商品

显示所有美食信息商品列表。

2. 进入详情页浏览

展示美食信息商品详情页

3. 检查是否显示美食信息商品是否正常展示

美食信息商品展示正常

6-5 美食信息商品添加测试用例表

用例编号

用例名称

测试步骤

测试结果

6-4

美食信息商品添加

1. 进入后台美食信息管理界面,点击添加按钮

显示美食信息商品信息添加页面

2. 正确填写并提交相关信息

信息填写完整准确。

3. 检查是否提交成功,并检查美食信息商品信息是否成功添加至平台。

美食信息商品信息成功添加至平台。

6.3测试结果

在测试过程中注册功能表现正常,用户可以顺利填写必要信息并完成注册,注册后自动进入平台首页。登录功能也无异常,用户凭借正确的账号和密码顺利登录,能够访问个人中心和平台功能。美食信息商品搜索功能能够准确地根据用户输入的关键词快速返回相关结果,搜索效率高。美食信息商品查看功能在测试中顺畅运行,用户可以查看商品的详细信息,包括名称、价格、描述及图片等,且页面加载迅速。最后,美食信息商品添加功能在后台操作时无问题,管理员能够成功添加新的菜品信息,所有数据也能实时更新到前端展示。总体来说,所有功能均顺利通过测试,用户体验流畅,系统稳定。

  

基于Python的美食推荐系统通过结合用户偏好、历史行为和菜品特点,成功地实现了个性化推荐功能。系统通过数据分析和机器学习算法,能够为用户提供精准的美食推荐,提高了用户在平台上的互动性和满意度。通过使用Python的强大数据处理和分析能力,系统不仅能够实时更新用户的口味偏好,还能根据不同的需求推荐符合用户口味的餐厅和菜品。总的来说,该美食推荐系统有效提升了用户体验,并为平台带来了更高的用户粘性和活跃度,展示了智能推荐在餐饮领域的巨大潜力。

参考文献

  1. 黄维.基于B/S模式的虚拟网络实验室安全管理体系分析[J].信息系统工程,2024,(05):4-7.
  2. 张宇薇.HTML5在Web前端开发中的应用[J].集成电路应用,2024,41(04):274-276.
  3. 邱红丽,张舒雅.基于Django框架的web项目开发研究[J].科学技术创新,2021,(27):97-98.
  4. 段艺,涂伟忠.Django开发从入门到实践[M].机械工业出版社:202211.635.
  5. 李艳杰.MySQL数据库下存储过程的综合运用研究[J].现代信息科技,2023,7(11):80-82+88.
  6. 肖睿,李鲲程,范效亮,等.MySQL数据库应用技术及实践[M].人民邮电出版社:202206.228.
  7. 明日科技.快速上手Python[M].化学工业出版社:202211.337.
  8. 明日科技.Python Web开发手册[M].化学工业出版社:202201.411.
  9. [1]Zhang G ,Wang J ,Huang X , et al.Uncovering a New Concept of Foodnality in Diet Recommendations for Chinese Aging Populations Based on Systematic and Bibliometric Review[J].Foods,2024,13(24):4062-4062.
  10. [2]Sweidan S ,Askar S ,Abouhawwash M , et al.A hybrid healthy diet recommender system based on machine learning techniques[J].Computers in Biology and Medicine,2025,184109389-109389.
  11. [3]陈南平.融合情境感知特征的就餐推荐模型研究[J].信息与电脑(理论版),2023,35(14):48-51.
  12. [4]张新宇.基于知识图谱的健康饮食推荐系统研究与开发[D].天津科技大学,2023.DOI:10.27359/d.cnki.gtqgu.2023.000631.
  13. [5]林帅伽,俞婷,程芳颖.基于协同过滤的美食店铺推荐算法[J].电脑知识与技术,2022,18(30):51-53.DOI:10.14004/j.cnki.ckt.2022.1963.
  14. [6]刘锐,徐鲁辉.基于Flink的智能餐饮推荐系统研究[J].信息技术与信息化,2022,(10):204-207.
  15. [7]刘江伟.基于深度学习的推荐系统关键技术研究[D].西安建筑科技大学,2022.DOI:10.27393/d.cnki.gxazu.2022.002126.
  16. [8]李凯.基于项目特征与用户偏好的美食推荐系统的设计与实现[D].北京邮电大学,2022.DOI:10.26969/d.cnki.gbydu.2022.001535.
  17. [9]刘业成.美食广场智慧餐饮平台的设计与实现[D].东南大学,2021.DOI:10.27014/d.cnki.gdnau.2021.004910.
  18. [10]傅金京.个性化推荐系统的精准推荐策略研究[D].南京邮电大学,2021.DOI:10.27251/d.cnki.gnjdc.2021.000563.


致  谢

眨眼之间,大学生活就要结束了。在本文的最后,我要感谢我和蔼可亲的导师、团结有爱的同学的帮助和鼓励。此刻,我找不到感谢之词可以用来表达我最深切的感激之情。尤其感谢我的指导老师,在选题的过程中与我进行了深入的交流,在毕业设计期间给我提供了一些指导。四年的学习生活让我受益良多,老师们的丰富的学术知识、认真负责的学习态度让我受益匪浅。在此,我深深地感谢那些曾经给予我帮助和指导的老师!

我的论文得益于许多学者的贡献,他们的研究成果为我提供了宝贵的指导,使我能够更好地完成这篇文章。感谢我的同学和朋友在我的写作以及排版过程中给予热情的帮助,才使得我比较顺利的完成了这篇论文。

感谢大学里遇见的朋友,你们在我这四年里留下无数的温暖和快乐,让我对这个校园多了一份留念。最后,感谢我的父母、辅导员、班长,以及室友们对我大学生活上的关心和理解,让我能保持乐观和追求我所热爱的。尽管我的能力有限,但我仍然尽力去完善这篇论文,并且诚挚地希望各位老师和学友能够给予宝贵的指导与意见!


附 录

系统关键代码

登录代码如下:

 def Login(self, ctx):

        print("===================登录=====================")

        ret = {

            "error": {

                "code": 70000,

                "message": "账户不存在",

            }

        }

        body = ctx.body

        password = md5hash(body["password"]) or ""

        obj = service_select("user").Get_obj(

            {"username": body["username"]}, {"like": False}

        )

        if obj:

            user_group = service_select("user_group").Get_obj({'name': obj['user_group']}, {"like": False})

            if user_group and user_group['source_table'] != '':

                user_obj = service_select(user_group['source_table']).Get_obj({"user_id": obj['user_id']},                                                                       {"like": False})

                if user_obj['examine_state'] == '未通过':

                    ret = {

                        "error": {

                            "code": 70000,

                            "message": "账户未通过审核",

                        }

                    }

                    return ret

                if user_obj['examine_state'] == '未审核':

                    ret = {

                        "error": {

                            "code": 70000,

                            "message": "账户未审核",

                        }

                    }

                    return ret

            if obj["state"] == 1:

                if obj["password"] == password:

                    timeout = timezone.now()

                    timestamp = int(time.mktime(timeout.timetuple())) * 1000

                    token = md5hash(str(obj["user_id"]) + "_" + str(timestamp))

                    ctx.request.session[token] = obj["user_id"]

                    service_select("access_token").Add(

                        {"token": token, "user_id": obj["user_id"]}

                    )

                    obj["token"] = token

                    ret = {

                        "result": {"obj": obj}

                    }

                else:

                    ret = {

                        "error": {

                            "code": 70000,

                            "message": "密码错误",

                        }

                    }

            else:

                ret = {

                    "error": {

                        "code": 70000,

                        "message": "用户账户不可用,请联系管理员",

                    }

                }

        return ctx.response(json.dumps(ret, ensure_ascii=False))

注册代码如下:

    def Register(self, ctx):

        print("===================注册=====================")

        userService = service_select("user")

        body = ctx.body

        if "username" not in body and body["username"] == '':

            return ctx.response(json.dumps({

                "error": {

                    "code": 70000,

                    "message": "用户名不能为空",

                }

            }, ensure_ascii=False))

        if "user_group" not in body and body["user_group"] == '':

            return ctx.response(json.dumps({

                "error": {

                    "code": 70000,

                    "message": "用户组不能为空",

                }

            }, ensure_ascii=False))

        if "password" not in body and body["password"] == '':

            return ctx.response(json.dumps({

                "error": {

                    "code": 70000,

                    "message": "密码不能为空",

                }

            }, ensure_ascii=False))

        post_param = body

        post_param['nickname'] = body["nickname"] or ""

        post_param['password'] = md5hash(body["password"])

        obj = userService.Get_obj({"username": post_param['username']}, {"like": False})

        if obj:

            return ctx.response(json.dumps({

                "error": {

                    "code": 70000,

                    "message": "用户名已存在",

                }

            }, ensure_ascii=False))

        ret = {

            "error": {

                "code": 70000,

                "message": "注册失败",

            }

        }

        bl = userService.Add(post_param)

        if bl:

            ret = {

                "result": {

                    "bl": True,

                    "message": "注册成功"

                }

            }

        return ctx.response(json.dumps(ret, ensure_ascii=False))

找回密码代码如下:

 def Forget_password(self, ctx):

        print("===================修改密码=====================")

        ret = {

            "error": {

                "code": 70000,

                "message": "用户信息不能没有"

            }

        }

        body = ctx.body

        if not body["code"]:

            return {

                "error": {

                    "code": 70000,

                    "message": "验证码不存在或者错误"

                }

            }

        obj = service_select("user").Get_obj(

            {"username": body["username"]}, {"like": False}

        )

        if not obj:

            return {

                "error": {

                    "code": 70000,

                    "message": "用户名不存在或者错误"

                }

            }

        password = md5hash(body["password"])

        if not password:

            return {

                "error": {

                    "code": 70000,

                    "message": "密码不存在或者错误"

                }

            }

        bl = service_select("user").Set({"user_id": obj["user_id"]}, {"password": password})

        if bl:

            ret = {"result": {"bl": True, "message": "修改成功"}}

        else:

            ret = {

                "error": {

                    "code": 70000,

                    "message": "修改失败",

                }

            }

        return ctx.response(json.dumps(ret, ensure_ascii=False))

修改密码代码如下:

 def Change_password(self, ctx):

        print("===================修改密码=====================")

        ret = {

            "error": {

                "code": 70000,

                "message": "账号未登录",

            }

        }

        request = ctx.request

        headers = request.headers

        if ("x-auth-token" in headers) and headers["x-auth-token"]:

            token = headers["x-auth-token"]

            user_id = tokenGetUserId(token, request)

            userService = service_select("user")

            body = ctx.body

            password = md5hash(body["o_password"])

            obj = userService.Get_obj({"user_id": user_id, "password": password}, {"like": False})

            if obj:

                password = md5hash(body["password"])

                bl = userService.Set({"user_id": user_id}, {"password": password})

                if bl:

                    ret = {"result": {"bl": True, "message": "修改成功"}}

                else:

                    ret = {

                        "error": {

                            "code": 70000,

                            "message": "修改失败",

                        }

                    }

            else:

                ret = {

                    "error": {

                        "code": 70000,

                        "message": "密码错误",

                    }

                }

        else:

            ret = {

                "error": {

                    "code": 70000,

                    "message": "账户未登录",

                }

            }

        return ctx.response(json.dumps(ret, ensure_ascii=False))

增删查改代码如下:

def Add(self, ctx):

body = ctx.body

unique = self.config.get("unique")

obj = None

if unique:

qy = {}

for i in range(len(unique)):

key = unique[i]

qy[key] = body.get(key)

obj = self.service.Get_obj(qy)

if not obj:

error = self.Add_before(ctx)

if error["code"]:

return {"error": error}

error = self.Events("add_before", ctx, None)

if error["code"]:

return {"error": error}

result = self.service.Add(body, self.config)

if self.service.error:

return {"error": self.service.error}

res = self.Add_after(ctx, result)

if res:

result = res

res = self.Events("add_after", ctx, result)

if res:

result = res

return {"result": result}

else:

return {"error": {"code": 10000, "message": "已存在"}}

def Del(self, ctx):

if len(ctx.query) == 0:

errorMsg = {"code": 30000, "message": "删除条件不能为空!"}

return errorMsg

result = self.service.Del(ctx.query, self.config)

if self.service.error:

return {"error": self.service.error}

return {"result": result}

def Set(self, ctx):

error = self.Set_before(ctx)

if error["code"]:

return {"error": error}

error = self.Events("set_before", ctx, None)

if error["code"]:

return {"error": error}

query = ctx.query

if 'page' in query.keys():

del ctx.query['page']

if 'size' in query.keys():

del ctx.query['size']

if 'orderby' in query.keys():

del ctx.query['orderby']

result = self.service.Set(ctx.query, ctx.body, self.config)

if self.service.error:

return {"error": self.service.error}

res = self.Set_after(ctx, result)

if res:

result = res

res = self.Events("set_after", ctx, result)

if res:

result = res

return {"result": result}

查多条数据:

def Get_list(self, ctx):

query = dict(ctx.query)

config_plus = {}

if "field" in query:

field = query.pop("field")

config_plus["field"] = field

if "page" in query:

config_plus["page"] = query.pop("page")

if "size" in query:

config_plus["size"] = query.pop("size")

if "orderby" in query:

config_plus["orderby"] = query.pop("orderby")

if "like" in query:

config_plus["like"] = query.pop("like")

if "groupby" in query:

config_plus["groupby"] = query.pop("groupby")

count = self.service.Count(query)

lst = []

if self.service.error:

return {"error": self.service.error}

elif count:

lst = self.service.Get_list(query,

obj_update(self.config, config_plus))

if self.service.error:

return {"error": self.service.error}

self.interact_list(ctx, lst)

return {"result": {"list": lst, "count": count}}

查一条数据:

def Get_obj(self, ctx):

query = dict(ctx.query)

config_plus = {}

if "field" in query:

field = query.pop("field")

config_plus["field"] = field

obj = self.service.Get_obj(query, obj_update(self.config, config_plus))

if self.service.error:

return {"error": self.service.error}

if obj:

self.interact_obj(ctx, obj)

return {"result": {"obj": obj}}

请关注点赞+私信博主,免费领取项目源码

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值