Spring Security认证授权练手小项目 腾讯视频VIP权限管理功能

1、项目功能视频演示

腾讯视频VIP权限管理功能演示

2、需求与设计

1、需求

所有视频必须登录才能看。

免费角色(ROLE_free)可观看免费视频列表。

为每个用户分配一个普通会员角色(general_{username}),该角色继承免费角色,购买的视频(资源)会绑定到这个普通会员角色上。

青铜vip角色继承免费角色,并且可观看青铜vip独享视频。

白银vip角色继承青铜vip角色,并且可以观看白银vip独享视频。

可扩展角色,如黄金vip继承白银vip,铂金vip继承黄金vip,以此类推。

每个用户至少有一个与之绑定的普通会员角色,和多个vip角色。

提供一个admin角色,可管理后台(目前仅有踢人功能)。

2、功能概要

在这里插入图片描述

3、接口设计

AppController 不用登录就能访问的资源

UserController 需要登录才能访问的资源

AdminController 需要admin角色才能访问的资源

CustomController 基于数据库表的动态URL权限管理

3、项目源码结构

F:.
│  pom.xml
│  readme.md
│  
└─src
    └─main
        ├─java
        │  └─com
        │      └─bobo
        │          └─springbootsecurity
        │              │  SpringbootSecurityApp.java
        │              │  
        │              ├─config
        │              │      CaptchaConfig.java
        │              │      HttpSessionConfig.java
        │              │      SessionSerializerConfig.java
        │              │      SpringSessionConfig.java
        │              │      WebSecurityConfig.java
        │              │      
        │              ├─controller
        │              │      AdminController.java
        │              │      AppController.java
        │              │      CustomController.java
        │              │      UserController.java
        │              │      
        │              ├─entity
        │              │      TencentVideoPermissions.java
        │              │      TencentVideoPermissionsExample.java
        │              │      TencentVideoRolePermission.java
        │              │      TencentVideoRolePermissionExample.java
        │              │      TencentVideoRoles.java
        │              │      TencentVideoRolesExample.java
        │              │      TencentVideoRoleUrls.java
        │              │      TencentVideoRoleUrlsExample.java
        │              │      TencentVideos.java
        │              │      TencentVideosExample.java
        │              │      TencentVideoUserRole.java
        │              │      TencentVideoUserRoleExample.java
        │              │      TencentVideoUsers.java
        │              │      TencentVideoUsersExample.java
        │              │      
        │              ├─exception
        │              │      CaptchaCheckException.java
        │              │      
        │              ├─handler
        │              │      CustomAuthenticationProvider.java
        │              │      CustomSecurityMetadataSource.java
        │              │      CustomUserDetailService.java
        │              │      JsonAuthenticationFailureHandler.java
        │              │      JsonAuthenticationSuccessHandler.java
        │              │      MySecurityExpressionRoot.java
        │              │      SecurityUser.java
        │              │      VideoPermissionExpression.java
        │              │      
        │              ├─mapper
        │              │      TencentVideoPermissionsMapper.java
        │              │      TencentVideoRolePermissionMapper.java
        │              │      TencentVideoRolesMapper.java
        │              │      TencentVideoRoleUrlsMapper.java
        │              │      TencentVideosMapper.java
        │              │      TencentVideoUserRoleMapper.java
        │              │      TencentVideoUsersMapper.java
        │              │      
        │              └─util
        │                      Result.java
        │                      
        └─resources
            │  application.yml
            │  generatorConfig.xml
            │  jdbc.properties
            │  
            ├─mappers
            │      TencentVideoPermissionsMapper.xml
            │      TencentVideoRolePermissionMapper.xml
            │      TencentVideoRolesMapper.xml
            │      TencentVideoRoleUrlsMapper.xml
            │      TencentVideosMapper.xml
            │      TencentVideoUserRoleMapper.xml
            │      TencentVideoUsersMapper.xml
            │      
            └─static
                    common.js
                    index.html
                    jquery-3.4.1.js
                    login.html
                    redirect.html

4、项目源码下载

https://download.csdn.net/download/xl_1803/87354994 无需积分。

5、项目部署

注意:以下部署教程均在windows操作系统上进行。

1、部署架构

在这里插入图片描述
避坑:要在服务节点上通过Spring Security配置跨域,负载均衡nginx不需要配置跨域,否则请求会出现某些错误。

2、数据库环境准备

数据库初始化脚本:

CREATE TABLE t_tencent_video_users (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  username varchar(255) DEFAULT NULL,
  password varchar(255) DEFAULT NULL,
  sex varchar(255) DEFAULT NULL,
  birthday date DEFAULT NULL,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频用户表';

CREATE TABLE t_tencent_video_user_role (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id int(10) DEFAULT NULL,
  role_id int(10) DEFAULT NULL,
  expire datetime DEFAULT NULL COMMENT '有效期至',
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频用户角色关联表';

CREATE TABLE t_tencent_video_roles (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  role varchar(255) DEFAULT NULL COMMENT '角色标识',
  role_name varchar(255) DEFAULT NULL COMMENT '角色名称',
  parent_role_id int(10) DEFAULT NULL COMMENT '父角色',
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频角色表';

CREATE TABLE t_tencent_video_role_permission (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  role_id int(10) DEFAULT NULL,
  permission_id int(10) DEFAULT NULL,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频角色权限关联表';

CREATE TABLE t_tencent_video_permissions (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  permission varchar(255) DEFAULT NULL COMMENT '权限标识',
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频权限表';

CREATE TABLE t_tencent_videos (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  video_name varchar(255) DEFAULT NULL,
  video_permission varchar(255) DEFAULT NULL COMMENT '视频权限标识',
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频视频表';

CREATE TABLE t_tencent_video_role_urls (
  id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  role_id int(10) DEFAULT NULL,
  url varchar(255) DEFAULT NULL,
  PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT '腾讯视频动态URL权限管理表';


-- 初始化数据
-- ----------------------------
-- Records of t_tencent_video_permissions
-- ----------------------------
INSERT INTO t_tencent_video_permissions VALUES (1, 'video_86xiyou:*');
INSERT INTO t_tencent_video_permissions VALUES (2, 'video_86xiyou:comment');
INSERT INTO t_tencent_video_permissions VALUES (3, 'video_86xiyou:download');
INSERT INTO t_tencent_video_permissions VALUES (4, 'video_86xiyou:read');
INSERT INTO t_tencent_video_permissions VALUES (5, 'video_daomu:*');
INSERT INTO t_tencent_video_permissions VALUES (6, 'video_daomu:comment');
INSERT INTO t_tencent_video_permissions VALUES (7, 'video_daomu:download');
INSERT INTO t_tencent_video_permissions VALUES (8, 'video_daomu:read');
INSERT INTO t_tencent_video_permissions VALUES (9, 'video_first:*');
INSERT INTO t_tencent_video_permissions VALUES (10, 'video_first:comment');
INSERT INTO t_tencent_video_permissions VALUES (11, 'video_first:download');
INSERT INTO t_tencent_video_permissions VALUES (12, 'video_first:read');
INSERT INTO t_tencent_video_permissions VALUES (13, 'video_gong:*');
INSERT INTO t_tencent_video_permissions VALUES (14, 'video_gong:comment');
INSERT INTO t_tencent_video_permissions VALUES (15, 'video_gong:download');
INSERT INTO t_tencent_video_permissions VALUES (16, 'video_gong:read');
INSERT INTO t_tencent_video_permissions VALUES (17, 'video_hu_shediao:*');
INSERT INTO t_tencent_video_permissions VALUES (18, 'video_hu_shediao:comment');
INSERT INTO t_tencent_video_permissions VALUES (19, 'video_hu_shediao:download');
INSERT INTO t_tencent_video_permissions VALUES (20, 'video_hu_shediao:read');
INSERT INTO t_tencent_video_permissions VALUES (21, 'video_huang_dragon:*');
INSERT INTO t_tencent_video_permissions VALUES (22, 'video_huang_dragon:comment');
INSERT INTO t_tencent_video_permissions VALUES (23, 'video_huang_dragon:download');
INSERT INTO t_tencent_video_permissions VALUES (24, 'video_huang_dragon:read');
INSERT INTO t_tencent_video_permissions VALUES (25, 'video_huaqiangu:*');
INSERT INTO t_tencent_video_permissions VALUES (26, 'video_huaqiangu:comment');
INSERT INTO t_tencent_video_permissions VALUES (27, 'video_huaqiangu:download');
INSERT INTO t_tencent_video_permissions VALUES (28, 'video_huaqiangu:read');
INSERT INTO t_tencent_video_permissions VALUES (29, 'video_langya:*');
INSERT INTO t_tencent_video_permissions VALUES (30, 'video_langya:comment');
INSERT INTO t_tencent_video_permissions VALUES (31, 'video_langya:download');
INSERT INTO t_tencent_video_permissions VALUES (32, 'video_langya:read');
INSERT INTO t_tencent_video_permissions VALUES (33, 'video_lovehouse:*');
INSERT INTO t_tencent_video_permissions VALUES (34, 'video_lovehouse:comment');
INSERT INTO t_tencent_video_permissions VALUES (35, 'video_lovehouse:download');
INSERT INTO t_tencent_video_permissions VALUES (36, 'video_lovehouse:read');
INSERT INTO t_tencent_video_permissions VALUES (37, 'video_new3country:*');
INSERT INTO t_tencent_video_permissions VALUES (38, 'video_new3country:comment');
INSERT INTO t_tencent_video_permissions VALUES (39, 'video_new3country:download');
INSERT INTO t_tencent_video_permissions VALUES (40, 'video_new3country:read');
INSERT INTO t_tencent_video_permissions VALUES (41, 'video_shenhua:*');
INSERT INTO t_tencent_video_permissions VALUES (42, 'video_shenhua:comment');
INSERT INTO t_tencent_video_permissions VALUES (43, 'video_shenhua:download');
INSERT INTO t_tencent_video_permissions VALUES (44, 'video_shenhua:read');
INSERT INTO t_tencent_video_permissions VALUES (45, 'video_shuihu:*');
INSERT INTO t_tencent_video_permissions VALUES (46, 'video_shuihu:comment');
INSERT INTO t_tencent_video_permissions VALUES (47, 'video_shuihu:download');
INSERT INTO t_tencent_video_permissions VALUES (48, 'video_shuihu:read');
INSERT INTO t_tencent_video_permissions VALUES (49, 'video_su_yitian:*');
INSERT INTO t_tencent_video_permissions VALUES (50, 'video_su_yitian:comment');
INSERT INTO t_tencent_video_permissions VALUES (51, 'video_su_yitian:download');
INSERT INTO t_tencent_video_permissions VALUES (52, 'video_su_yitian:read');
INSERT INTO t_tencent_video_permissions VALUES (53, 'video_weizhuang:*');
INSERT INTO t_tencent_video_permissions VALUES (54, 'video_weizhuang:comment');
INSERT INTO t_tencent_video_permissions VALUES (55, 'video_weizhuang:download');
INSERT INTO t_tencent_video_permissions VALUES (56, 'video_weizhuang:read');
INSERT INTO t_tencent_video_permissions VALUES (57, 'video_wind11:*');
INSERT INTO t_tencent_video_permissions VALUES (58, 'video_wind11:comment');
INSERT INTO t_tencent_video_permissions VALUES (59, 'video_wind11:download');
INSERT INTO t_tencent_video_permissions VALUES (60, 'video_wind11:read');
INSERT INTO t_tencent_video_permissions VALUES (61, 'video_windgirl:*');
INSERT INTO t_tencent_video_permissions VALUES (62, 'video_windgirl:comment');
INSERT INTO t_tencent_video_permissions VALUES (63, 'video_windgirl:download');
INSERT INTO t_tencent_video_permissions VALUES (64, 'video_windgirl:read');
INSERT INTO t_tencent_video_permissions VALUES (65, 'video_xian3:*');
INSERT INTO t_tencent_video_permissions VALUES (66, 'video_xian3:comment');
INSERT INTO t_tencent_video_permissions VALUES (67, 'video_xian3:download');
INSERT INTO t_tencent_video_permissions VALUES (68, 'video_xian3:read');
INSERT INTO t_tencent_video_permissions VALUES (69, 'video_xianjian:*');
INSERT INTO t_tencent_video_permissions VALUES (70, 'video_xianjian:comment');
INSERT INTO t_tencent_video_permissions VALUES (71, 'video_xianjian:download');
INSERT INTO t_tencent_video_permissions VALUES (72, 'video_xianjian:read');
INSERT INTO t_tencent_video_permissions VALUES (73, 'video_xuanyuan:*');
INSERT INTO t_tencent_video_permissions VALUES (74, 'video_xuanyuan:comment');
INSERT INTO t_tencent_video_permissions VALUES (75, 'video_xuanyuan:download');
INSERT INTO t_tencent_video_permissions VALUES (76, 'video_xuanyuan:read');
INSERT INTO t_tencent_video_permissions VALUES (77, 'video_yumeng:*');
INSERT INTO t_tencent_video_permissions VALUES (78, 'video_yumeng:comment');
INSERT INTO t_tencent_video_permissions VALUES (79, 'video_yumeng:download');
INSERT INTO t_tencent_video_permissions VALUES (80, 'video_yumeng:read');
-- ----------------------------
-- Records of t_tencent_video_role_permission
-- ----------------------------
INSERT INTO t_tencent_video_role_permission VALUES (1, 1, 2);
INSERT INTO t_tencent_video_role_permission VALUES (2, 1, 4);
INSERT INTO t_tencent_video_role_permission VALUES (3, 1, 6);
INSERT INTO t_tencent_video_role_permission VALUES (4, 1, 8);
INSERT INTO t_tencent_video_role_permission VALUES (5, 2, 1);
INSERT INTO t_tencent_video_role_permission VALUES (6, 2, 5);
INSERT INTO t_tencent_video_role_permission VALUES (7, 2, 9);
INSERT INTO t_tencent_video_role_permission VALUES (8, 2, 13);
INSERT INTO t_tencent_video_role_permission VALUES (9, 2, 17);
INSERT INTO t_tencent_video_role_permission VALUES (10, 2, 21);
INSERT INTO t_tencent_video_role_permission VALUES (11, 2, 25);
INSERT INTO t_tencent_video_role_permission VALUES (12, 2, 29);
INSERT INTO t_tencent_video_role_permission VALUES (13, 3, 33);
INSERT INTO t_tencent_video_role_permission VALUES (14, 3, 37);
INSERT INTO t_tencent_video_role_permission VALUES (15, 3, 41);
INSERT INTO t_tencent_video_role_permission VALUES (16, 3, 45);
INSERT INTO t_tencent_video_role_permission VALUES (17, 3, 49);
INSERT INTO t_tencent_video_role_permission VALUES (18, 3, 53);
INSERT INTO t_tencent_video_role_permission VALUES (19, 3, 57);
INSERT INTO t_tencent_video_role_permission VALUES (20, 3, 61);
-- ----------------------------
-- Records of t_tencent_video_roles
-- ----------------------------
INSERT INTO t_tencent_video_roles VALUES (1, 'free', '大众会员', NULL);
INSERT INTO t_tencent_video_roles VALUES (2, 'qingtong_vip', '青铜会员',1);
INSERT INTO t_tencent_video_roles VALUES (3, 'baiyin_vip','白银会员', 2);
INSERT INTO t_tencent_video_roles VALUES (5, 'general_bobo','普通会员', 1);
INSERT INTO t_tencent_video_roles VALUES (6, 'admin', '网站管理员',NULL);
-- ----------------------------
-- Records of t_tencent_video_user_role
-- ----------------------------
INSERT INTO t_tencent_video_user_role VALUES (1, 1, 5, '2099-12-31 23:59:59');
INSERT INTO t_tencent_video_user_role VALUES (2, 2, 6, '2099-12-31 23:59:59');
-- ----------------------------
-- Records of t_tencent_video_users
-- ----------------------------
INSERT INTO t_tencent_video_users VALUES (1, 'bobo', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
INSERT INTO t_tencent_video_users VALUES (2, 'boboadmin', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
-- ----------------------------
-- Records of t_tencent_videos
-- ----------------------------
INSERT INTO t_tencent_videos VALUES (1, '86版西游记', 'video_86xiyou');
INSERT INTO t_tencent_videos VALUES (2, '新三国', 'video_new3country');
INSERT INTO t_tencent_videos VALUES (3, '琅琊榜', 'video_langya');
INSERT INTO t_tencent_videos VALUES (4, '黄日华版天龙八部', 'video_huang_dragon');
INSERT INTO t_tencent_videos VALUES (5, '苏有朋版倚天屠龙记', 'video_su_yitian');
INSERT INTO t_tencent_videos VALUES (6, '仙剑奇侠传', 'video_xianjian');
INSERT INTO t_tencent_videos VALUES (7, '仙剑奇侠传三', 'video_xian3');
INSERT INTO t_tencent_videos VALUES (8, '新版水浒传', 'video_shuihu');
INSERT INTO t_tencent_videos VALUES (9, '花千骨', 'video_huaqiangu');
INSERT INTO t_tencent_videos VALUES (10, '宫', 'video_gong');
INSERT INTO t_tencent_videos VALUES (11, '天下第一', 'video_first');
INSERT INTO t_tencent_videos VALUES (12, '胡歌版射雕英雄传', 'video_hu_shediao');
INSERT INTO t_tencent_videos VALUES (13, '轩辕剑之天之痕', 'video_xuanyuan');
INSERT INTO t_tencent_videos VALUES (14, '神话', 'video_shenhua');
INSERT INTO t_tencent_videos VALUES (15, '伪装者', 'video_weizhuang');
INSERT INTO t_tencent_videos VALUES (16, '旋风十一人', 'video_wind11');
INSERT INTO t_tencent_videos VALUES (17, '盗墓笔记', 'video_daomu');
INSERT INTO t_tencent_videos VALUES (18, '爱情公寓', 'video_lovehouse');
INSERT INTO t_tencent_videos VALUES (19, '情深深雨濛濛', 'video_yumeng');
INSERT INTO t_tencent_videos VALUES (20, '旋风少女', 'video_windgirl');
-- ----------------------------
-- Records of t_tencent_video_role_urls
-- ----------------------------
INSERT INTO t_tencent_video_role_urls VALUES (1, 1, '/custom/daily_recommend');
INSERT INTO t_tencent_video_role_urls VALUES (2, 2, '/custom/favorite');
INSERT INTO t_tencent_video_role_urls VALUES (3, 3, '/custom/handpick');

3、redis环境准备

使用单机redis即可,监听localhost:6379。

4、Spring Boot服务准备

项目导入IDEA,运行Spring Boot启动类SpringbootSecurityApp即可启动项目。

通过修改application.yml中的server.port,在单机上运行两个节点,分别监听localhost:8151、localhost:8152。

5、nginx负载均衡准备

# http模块下
http {
	upstream webservers{
		server  localhost:8151;
		server  localhost:8152;
	}
    server {
        listen       8070;
        location / {
			proxy_pass http://webservers;
        }
    }
}

然后启动nginx。

6、nginx静态资源服务器准备

将静态资源文件拷贝到nginx目录下的html/SpringbootSecurity目录下,如下图所示。
在这里插入图片描述
配置nginx.conf:

# server模块下;root为静态资源存放目录
server {
        listen       80;
        location / {
            root   html/SpringbootSecurity;
            index  index.html index.htm;
        }
}

然后启动nginx。

到此为止,所有的部署工作均已完成。浏览器访问 http://localhost/login.html 即可开始使用此系统。

6、项目介绍

1、技术架构

主框架为Spring Boot+Spring Security+Mybatis+Spring Session。

关系型数据库采用Mysql。使用Redis主要存储分布式Session数据。

使用kaptcha生成图形验证码。另外使用了lombok、fastjson、hutool等工具。

通过mybatis-generator自动生成数据库映射文件。

前端主要使用html+jquery框架,请求使用jquery ajax。

2、技术汇总

本文不具体介绍项目中使用的技术,而是我会将项目中Spring Security的一些实现细节再写几篇博客分开讲解,以下是可能要讲解的主题:

  • 会话管理
  • 图形验证码
  • 静态URL权限管理、动态URL权限管理、方法注解权限管理
  • spring security集成spring session实现分布式会话

待博文完成后,我会在这里添加上链接,敬请期待吧。

7、配置数据开发

如何增加一个video?

-- 必要
INSERT INTO t_tencent_videos VALUES ('视频名称', 'video_视频标识符');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:*');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:comment');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:download');
INSERT INTO t_tencent_video_permissions VALUES ('video_视频标识符:read');
-- 非必要(与某个vip角色或ROLE_free角色关联)
INSERT INTO t_tencent_video_role_permission VALUES (角色ID, 权限ID);

如何新增一个vip角色?

-- 必要
INSERT INTO t_tencent_video_roles VALUES ('角色标识符_vip', '角色名称',父VIP角色ID);
-- 非必要
-- 给角色绑定用户
INSERT INTO t_tencent_video_user_role VALUES (用户ID, 角色ID, '2099-12-31 23:59:59');
-- 给角色绑定权限
INSERT INTO t_tencent_video_role_permission VALUES (角色ID, 权限ID);
-- 给角色绑定URL(目前动态管理的URL在CustomController中)
INSERT INTO t_tencent_video_role_urls VALUES (角色ID, 'URL');

如何新增一个用户?

-- 必要
INSERT INTO t_tencent_video_users VALUES ('用户名', '$2a$04$lpCeAK7Hv0Wrx2eCg9jS4ubncXYunvDrrAmHOOoMF.7M.pbBNY/lW', '男', '2001-09-16');
INSERT INTO t_tencent_video_roles VALUES ('general_用户名','普通会员', 1);

如何新增一个基于数据库表权限管理的URL?

-- 基于/custom
INSERT INTO t_tencent_video_role_urls VALUES (角色ID, '/custom/类型标识');
-- 在index.html的【更多精彩】中,添加一个按钮
-- <button class="customVideoBtn" custom="类型标识">类型名</button>

-- 不基于/custom
-- 可以随意写controller,然后在index.html写一些按钮监听点击事件去访问这些controller,
-- 然后将这些controller方法对应的url通过数据库表与角色关联起来
-- 但最好不要与WebSecurityConfig静态配置的URL Pattern(/user/**、/admin/**、/app/**)重复
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值