基于SpringBoot + Vue的流浪天使乐园管理系统设计与实现

前言

💛博主介绍:
     作为资深全栈程序员🎉,我专注于为大学生提供毕业设计支持。凭借丰富的开发经验和深入的技术解析,我在此分享实用的编程资源、源代码,并提供定制化技术咨询💡。致力于协助学生在毕业设计中取得成功我的目标是让技术学习变得更高效、更有趣。欢迎关注👋,一起在计算机科学的海洋中乘风破浪⛵️,共创辉煌🏆。
👇🏻 精选专栏,推荐订阅👇🏻
计算机毕业设计最强指南
计算机最全毕设项目推荐
文末附上源码及联系方式
     欢迎各位同学在评论区或通过私信提出关于毕业设计的问题,我将尽我所能,为大家提供有价值的建议和指导,帮助每位学生在毕业设计的道路上少走弯路,更高效地完成毕设!

一、详细操作演示视频

        在文章的尾声,您会发现一张电子名片👤,欢迎通过名片上的联系方式与我取得联系,以获取更多关于项目演示的详尽视频内容。视频将帮助您全面理解项目的关键点和操作流程。期待与您的进一步交流!
        承诺所发文章的项目皆有视频和源码,若发现任何不实之处,我将无条件为您提供完全免费的技术支持,涵盖软件开发等各项服务!❗️❗️❗️

二、具体实现截图

当访问系统网址的游客首次登陆,映入眼帘的是起始页。此页面上,"流浪天使乐园"网站管理系统呈现出导航菜单,包括首页、流浪动物板块、领养信息、论坛讨论区、养护指南、在线支持以及个人账户选项。如图4.1所示描绘了系统首页的布局。

img

图4.1系统首页界面

4.1.2注册登录

在用户能够执行前台系统的任何操作之前,必须先完成注册和登录步骤。在注册页面,用户需填写账号名、真实姓名、设定密码、重复密码、联系电话、性别、年龄及上传头像等个人信息。前端将这些数据打包成HTTP请求发送至Java后台。后台接收到后,会核实用户名的唯一性,并把新的用户资料保存到MySQL数据库中。一旦处理完毕,后台会向前端发送注册成功的信号,接着前端会提示用户注册已成功。这一流程确保了新用户数据的收集、验证和安全储存。如图4.2所示。

img

图4.2用户注册界面图

在账户登录过程中,使用者需于登录界面上输入其账户名及密码,从而启动登陆程序。初始阶段,用户在Vue驱动的前端界面上填入相应的登录信息。随后,这些数据以HTTP请求的形式被传送至Java后台系统。后台接收到请求后,会与MySQL数据库进行沟通,对用户的凭据进行核实。一旦验证通过,服务器将生成一个授权令牌,如JWT,并将其回传至前端。这个令牌使得用户有权进入系统,整个流程涵盖了从用户输入到系统验证及反馈的全部步骤。如图4.3所示。

img

图4.3用户登录界面图

4.1.3流浪动物页面

在流浪动物板块,用户可以在搜索框中输入特定的动物名称、类别、性别和生存状况,以便进行详细搜寻。此外,页面展示的详情包括各类动物、它们的品种、图片、性别、年龄、习性、体重(以公斤为单位)、状态、公布日期、浏览次数、评论数量以及点赞数。用户可以根据需求选择进行收养申请或收藏等互动操作,如图4.4所示。

img

图4.4流浪动物页面

4.1.4收养信息页面

在收养信息界面,用户能利用搜索框通过输入各种条件,如标题、类别、性别、收养状况或特定名称,来执行搜索操作。此外,页面展示的详细信息包括不同类型的动物、它们的图片、品种、年龄、性格特征、当前的收养状态、注意事项、账户信息、领养人姓名及联系方式。用户还有权限对信息发表评论或选择将其收藏,如图4.5所示。

img

图4.5收养信息页面

4.1.5个人中心页面

在个人中心的界面,用户能够执行各种功能,包括更新个人资料和更改密码。此外,此页面还允许用户对诸如密码重置、认领信息、被领养信息、我的发布以及我的收藏等事项进行深入管理,如图4.6所示。

img

图4.6个人中心界面图

在管理员界面,核心操作涵盖了主页操控、个人档案管理、用户权限管理、物种资料管理、流浪生物治理、领养与收养记录管控、论坛互动以及系统设置等多个模块,如图4.8清晰展示。

img

图4.8管理员主界面

用户操作流程主要在视图界面执行,例如通过“新增”图标或填写用户详细表格,这些操作信号会被视图层即时捕捉并转化为指令传递至控制中枢——控制器层。控制器接收到请求后,会激活服务模块,负责执行业务规则,如验证数据的准确性和与数据库的连通性。服务模块执行完任务后,进一步与数据处理模块(Data Access Object, DAO)沟通,这一环节专注于实际的数据操作,包括搜索、增加、修改或删除用户信息,并将处理结果返回给控制器。最后,基于这些反馈,控制器驱动视图层更新,确保用户信息功能能实时显示最新数据或操作反馈。在用户信息浏览页面,通过输入用户标识和姓名,系统能够展示详尽的用户详情,并允许用户执行查看、增删改等操作,如图4.9所示。

img

图4.9用户管理界面

在虚拟界面环境中,与流浪动物相关的交互活动巧妙地融入了视图模块。例如,当用户轻触“新增”图标或填写详细的动物档案时,这些实时操作会被视图模块敏锐地捕捉,并转化为请求信号传递至控制中心模块(controller)。该中心模块犹如指挥调度,接收到请求后,会立即激活服务模块的服务流程,包括对输入数据的严谨验证和数据库的操作协调。服务模块在执行完核心业务逻辑后,会进一步与数据操作核心(Data Access Object, DAO)模块进行深度合作。DAO模块承担着实际的数据操作使命,诸如搜索、录入、修改或移除流浪动物的信息,然后将处理后的反馈回馈给控制中心。最后,控制中心根据这些实时更新的结果,重新调整视图模块的展示,确保流浪动物功能界面能即时反映出最新状态或操作反馈

在流浪动物详情页上,用户只需输入动物的昵称、品种、性别和生存状况,系统便会立即响应,显示出详尽的动物资料。同时,用户还拥有权限进行添加、修改或删除操作,整个流程如图4.10所示,既直观又高效。

img

图4.10流浪动物管理界面

在管理员界面,选择动物类别管理功能,他们能在相应的页面中录入关于动物种类的详细资料,并执行搜索、新增或移除等操作。如图4.11所示。

img

图4.11动物种类管理界面

当管理员选择领养信息管理,他们会进入一个页面,这里能处理领养申请的各种详情,包括领养编号、宠物别名、动物类型、动物图片、类别、性别、年龄、性格、用户账号、申请人姓名、联系电话、领养日期、审核反馈以及审核状态等。管理员可进行查询、审核或删除等管理工作。如图4.12所示。

img

图4.12领养信息管理界面

三、技术栈

请留意,技术选型应依据实际项目需求而定,以下内容仅供参考!

1.前端-Vue.js

        Vue.js 是由尤雨溪在 2014 年推出的轻量级前端 JavaScript 框架,以其易学易用和高效的数据绑定机制而广受欢迎。它专注于视图层,易于与其他库或现有项目集成,特别适合中小型项目。
        Vue.js 的响应式数据绑定是其核心特性之一,它允许开发者通过声明式的数据绑定,自动更新 DOM,从而简化了前端开发流程,使开发者能够更专注于业务逻辑。此外,Vue.js 提供了强大的组件系统,支持单文件组件,使得开发者能够以模块化方式构建复杂的用户界面,提高了代码的可复用性和可维护性。
        Vue.js 的生态系统包括 Vuex 状态管理和 Vue Router 路由管理等工具,这些工具极大地方便了单页应用(SPA)的开发。Vue 3 的推出,引入了 Composition API、改进的响应式系统和性能优化,进一步提升了开发体验和应用性能。

2.后端-SpringBoot

        Spring Boot 是 Spring 框架的扩展,旨在简化 Spring 应用的创建和开发。它通过提供“Starters”来简化依赖管理和配置,使得开发者能够快速启动和运行应用。Spring Boot 遵循“约定优于配置”的原则,自动配置了许多常见的设置,如内嵌的 Tomcat 服务器,从而减少了手动配置的需要。
        Spring Boot 的自动配置功能能够根据项目依赖自动调整应用配置,如数据库连接和实体管理,极大地提高了开发效率。此外,它还包含了 Actuator 模块,用于监控和管理应用,提供应用健康状态、度量信息和环境信息等,这对于生产环境中的监控和问题诊断至关重要。
        Spring Boot 也支持微服务架构,与 Spring Cloud 集成,使得构建分布式系统变得简单。Spring Cloud 提供了服务发现、配置管理、断路器等微服务组件,帮助开发者构建和管理复杂的微服务系统。

3.数据库-MySQL

        MySQL 是一种广泛使用的开源关系型数据库管理系统(RDBMS),基于 SQL(Structured Query Language)进行数据管理。它最初由瑞典的 MySQL AB 开发,后来被 Sun Microsystems 收购,最终成为 Oracle 公司的产品。MySQL 是最流行的数据库技术之一,特别适用于 Web 应用开发,因其高性能、可靠性和易用性而受到青睐。
        MySQL 的核心特性包括支持多种操作系统平台、提供强大的数据安全和备份功能、以及拥有一个活跃的社区支持。它支持广泛的应用程序,从小型应用到大型企业级应用,都能够提供有效的数据存储解决方案。
        作为一个关系型数据库,MySQL 使用表格来组织数据,并通过索引来优化查询性能。它支持多种数据类型,包括数值、日期和时间、字符串等,能够满足不同应用场景的需求。MySQL 还提供了事务处理、子查询、触发器和存储过程等高级数据库功能,这些功能使得开发者能够构建复杂的数据库逻辑。

4.系统架构-B/S

        B/S(Browser/Server)架构是现代网络应用开发中的主流模型,它将用户界面集中在浏览器端,而服务器端则负责处理业务逻辑和数据存储。这种架构的优势在于其跨平台性和易维护性,用户无需在本地安装软件,只需通过浏览器即可访问应用,无论其操作系统如何。
        在 B/S 架构中,前端技术如 HTML、CSS 和 JavaScript 用于构建用户界面,而后端则处理数据和业务逻辑。前后端通过 HTTP 或 HTTPS 协议通信,通常使用 JSON 或 XML 格式交换数据。这种分离的模式促进了前后端独立开发,提高了开发效率和应用性能。
        随着技术进步,B/S 架构不断演进,单页应用(SPA)的流行使得用户体验更加流畅。同时,前后端分离的开发模式允许团队独立工作,加速了开发流程。为了优化性能,B/S 架构广泛应用了缓存、负载均衡和 CDN 等技术,而容器化和微服务架构的兴起,如 Docker 和 Kubernetes,进一步推动了应用的高效部署和管理。

四、系统测试

1.系统测试概述

        系统测试通常按照功能模块来组织,包括用户界面测试、管理员界面测试以及用户功能测试等关键环节。这些测试针对不同的用户群体或角色,目的是验证系统内各个功能模块的运行情况,并确保它们能够满足用户的期望和需求。
        用户界面测试包括新用户注册、登录、参与考试、观看视频、发表评论、浏览错题集等操作。管理员界面测试则关注于系统管理功能,如视频内容管理、用户账户管理、发布公告等任务。通过细致地测试不同的功能模块,可以从多个角度评估系统的表现,这包括功能性、特性、稳定性以及用户交互体验等方面。识别并解决潜在的问题,有助于确保系统的质量和可靠性。

2.系统功能测试

(1)用户端功能测试

表4-1 用户测试表
编号测试功能测试用例预测结果测试结果是否通过
1注册输入用户名1的用户信息注册成功注册成功
2登录输入用户名1的账号密码登录成功登录成功
3在线考试点击开始考试添加答案提交成功提交成功提交
4视频信息点击视频标题1开始播放成功播放成功播放
5论坛点击论坛标题1并且评论评论成功评论成功
6错题本点击我的错题本查看成功查看成功

(2)管理端功能测试

表4-2管理员测试表
编号测试功能测试用例预测结果测试结果是否通过
1登录输入管理员账号密码登录成功登录成功
2查询用户搜索用户名1成功搜索成功搜索
3新增公告点击新增论坛填写标题和内容并提交添加成功添加成功
4修改视频1的备课详情点击视频1的信息页面修改内容点击提交修改成功修改成功
5删除试题点开试题管理和点击试题1的删除按钮并确定删除成功删除成功

3.系统测试结论

        本系统主要采用黑盒测试方法,通过模拟用户操作来构建测试用例,并对系统的各项功能进行验证。这种测试方法旨在确保系统流程的准确性和完整性。系统测试是提升系统质量的关键环节,它有助于提高系统的可用性和用户满意度。
        进行系统测试的目的是为了检验系统的功能模块是否达到了设计初衷,以及这些模块的逻辑是否准确无误。本系统追求简洁易用,避免复杂的逻辑处理,以便用户能够轻松操作。测试的焦点始终是用户体验,确保所有测试场景都紧密贴合用户的实际需求,不偏离既定目标。在遇到问题时,测试团队需从用户的角度出发,深入思考解决方案。通过这一系列的测试流程,我们能够获得最终的测试结果,这些结果将展示系统在功能和性能上是否达到了预期的设计标准。

五、项目代码参考

@IgnoreAuth
@PostMapping(value = "/login")
public R login(String username, String password, String captcha, HttpServletRequest request) {
   UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
   if(user==null || !user.getPassword().equals(password)) {
      return R.error("账号或密码不正确");
   }
   String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());
   return R.ok().put("token", token);
}

	@Override
	public String generateToken(Long userid,String username, String tableName, String role) {
		TokenEntity tokenEntity = this.selectOne(new EntityWrapper<TokenEntity>().eq("userid", userid).eq("role", role));
		String token = CommonUtil.getRandomString(32);
		Calendar cal = Calendar.getInstance();   
    	cal.setTime(new Date());   
    	cal.add(Calendar.HOUR_OF_DAY, 1);
		if(tokenEntity!=null) {
			tokenEntity.setToken(token);
			tokenEntity.setExpiratedtime(cal.getTime());
			this.updateById(tokenEntity);
		} else {
			this.insert(new TokenEntity(userid,username, tableName, role, token, cal.getTime()));
		}
		return token;
	}



/**
 * 权限(Token)验证
 */
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    public static final String LOGIN_TOKEN_KEY = "Token";

    @Autowired
    private TokenService tokenService;
    
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		//支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
	// 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态
	if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
        	response.setStatus(HttpStatus.OK.value());
            return false;
        }
        
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        
        /**
         * 不需要验证权限的方法直接放过
         */
        if(annotation!=null) {
        	return true;
        }
        
        TokenEntity tokenEntity = null;
        if(StringUtils.isNotBlank(token)) {
        	tokenEntity = tokenService.getTokenEntity(token);
        }
        
        if(tokenEntity != null) {
        	request.getSession().setAttribute("userId", tokenEntity.getUserid());
        	request.getSession().setAttribute("role", tokenEntity.getRole());
        	request.getSession().setAttribute("tableName", tokenEntity.getTablename());
        	request.getSession().setAttribute("username", tokenEntity.getUsername());
        	return true;
        }
        
		PrintWriter writer = null;
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		try {
		    writer = response.getWriter();
		    writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
		} finally {
		    if(writer != null){
		        writer.close();
		    }
		}
//				throw new EIException("请先登录", 401);
		return false;
    }
}

六、数据库代码参考

-- MySQL dump 10.13  Distrib 5.7.31, for Linux (x86_64)
--
-- Host: localhost    Database: springbootm3ord
-- ------------------------------------------------------
-- Server version	5.7.31

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Current Database: `springbootm3ord`
--

/*!40000 DROP DATABASE IF EXISTS `springbootm3ord`*/;

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `springbootm3ord` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `springbootm3ord`;

--
-- Table structure for table `aboutus`
--

DROP TABLE IF EXISTS `aboutus`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `aboutus` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `title` varchar(200) NOT NULL COMMENT '标题',
  `subtitle` varchar(200) DEFAULT NULL COMMENT '副标题',
  `content` longtext NOT NULL COMMENT '内容',
  `picture1` longtext COMMENT '图片1',
  `picture2` longtext COMMENT '图片2',
  `picture3` longtext COMMENT '图片3',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='关于我们';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `aboutus`
--

LOCK TABLES `aboutus` WRITE;
/*!40000 ALTER TABLE `aboutus` DISABLE KEYS */;
INSERT INTO `aboutus` VALUES (1,'2023-03-05 09:51:25','关于我们','ABOUT US','不管你想要怎样的生活,你都要去努力争取,不多尝试一些事情怎么知道自己适合什么、不适合什么呢?\n你说你喜欢读书,让我给你列书单,你还问我哪里有那么多时间看书;你说自己梦想的职业是广告文案,问我如何成为一个文案,应该具备哪些素质;你说你计划晨跑,但总是因为学习、工作辛苦或者身体不舒服第二天起不了床;你说你一直梦想一个人去长途旅行,但是没钱,父母觉得危险。其实,我已经厌倦了你这样说说而已的把戏,我觉得就算我告诉你如何去做,你也不会照做,因为你根本什么都不做。','upload/aboutus_picture1.jpg','upload/aboutus_picture2.jpg','upload/aboutus_picture3.jpg');
/*!40000 ALTER TABLE `aboutus` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `config`
--

DROP TABLE IF EXISTS `config`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `config` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(100) NOT NULL COMMENT '配置参数名称',
  `value` varchar(100) DEFAULT NULL COMMENT '配置参数值',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='配置文件';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `config`
--

LOCK TABLES `config` WRITE;
/*!40000 ALTER TABLE `config` DISABLE KEYS */;
INSERT INTO `config` VALUES (1,'picture1','upload/picture1.jpg'),(2,'picture2','upload/picture2.jpg'),(3,'picture3','upload/picture3.jpg');
/*!40000 ALTER TABLE `config` ENABLE KEYS */;
UNLOCK TABLES;

七、项目论文示例

image-20240720221221532

image-20240725212125784

image-20240725212137200

八、一站式毕设支持服务

        十年专注于毕业设计领域,我们致力于为学生提供全面的编程软件资源。本站拥有丰富的源代码库定期更新,以确保技术内容的时效性实用性。此外,我们还提供免费源代码的定期分享,旨在帮助学生在毕业设计过程中获取必要的支持。
        本平台致力于提供一站式毕业设计支持服务,涵盖从项目启动到最终答辩的各个环节。 我们不仅供应技术资源和项目案例,还提供包括毕业设计开题报告撰写指南学术论文写作技巧答辩演示文稿制作技巧,以及系统开发中常见问题的解决策略。我们的目标是打造一个全面、权威的信息资源库,以辅助学生顺利完成学业成果展示。
        点进我的网站,查看“我的优势”栏目,即可让您明白为什么选择我们❗️❗️❗️

个人网站: xiaozhucoding

image-20240912231155541

结语

撰写不易
请大家多多点赞、收藏、关注、评论👏
文章下方名片联系我即可
查看👇🏻获取联系方式👇🏻
以获取更多资源和一站式毕设服务指导!
多多关注!

基于SpringBootVue的微人事管理系统设计实现如下: 1. 架构设计:系统采用前后端分离的架构,前端使用Vue框架,后端使用SpringBoot框架。前后端之间通过RESTful API进行数据交互。 2. 功能设计:系统包含员工管理、部门管理、职位管理、薪资管理、请假管理等基本功能。员工管理包括员工信息的增删改查,部门管理包括部门的添加和删除,职位管理包括职位的添加和删除,薪资管理包括工资的计算和发放,请假管理包括请假申请和审批等。 3. 数据库设计:系统采用MySQL数据库存储数据,设计了员工表、部门表、职位表、工资表和请假表等几个核心表。具体表结构根据具体需求设计。 4. 后端实现后端使用SpringBoot框架进行开发,通过使用Spring Data JPA进行数据库访问,使用Spring Security进行权限控制。后端实现了RESTful API接口,提供给前端进行数据交互。 5. 前端实现:前端使用Vue框架进行开发,使用Vue Router进行路由管理,使用Element UI进行页面布局和组件使用。前端通过发送Http请求与后端进行交互,展示数据、进行操作等。 6. 部署与测试:系统可以部署在云服务器上,使用Nginx进行反向代理,保证系统的稳定性和安全性。使用Postman进行接口测试,保证系统的正确性和健壮性。 通过基于SpringBootVue的微人事管理系统设计实现,可以实现对员工的全生命周期管理,提高人力资源管理的效率和准确性。系统具有良好的扩展性和灵活性,可以根据需求进行功能拓展和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值