SSM 框架搭建 sckill 秒杀系统 —— step.5 web展示层建设

从专利库到Zemax:一个6mm定焦镜头从零到交付的完整设计流程(含CodeV转换技巧) 本文详细介绍了6mm定焦镜头从专利库检索到最终交付的全流程设计,重点解析了CodeV与Zemax工具链的无缝衔接技巧。通过实际案例展示规格定义、专利筛选、结构适配、非球面优化等关键步骤,帮助光学设计工程师提升设计效率和制造良率。特别包含CodeV转换Zemax的实用技巧,适用于机器视觉和安防镜头开发。 阅读详情

索引:

  1. SSM 框架搭建 sckill (秒杀系统) —— step.1 前期准备 + 框架配置
  2. SSM 框架搭建 sckill (秒杀系统) —— step.2 持久层建设
  3. SSM 框架搭建 sckill 秒杀系统 —— step.3 业务逻辑层建设
  4. SSM 框架搭建 sckill 秒杀系统 —— step.4 web控制层建设
  5. SSM 框架搭建 sckill 秒杀系统 —— step.5 web展示层建设

一、web 展示层(view)简介

        展示层是一个系统与实际用户之间的交互层级,用图形化界面的方式,将后端的业务逻辑进行包装。最终呈现给用户一个简单易懂的可交互页面。因此,通常而言,这个层级是在系统设计中占有的设计时间比编码时间要更长。(不过就本系统而言,因为更注重的是逻辑和业务的实现,所以并没有在展示层的设计上下多大功夫,只是简单的展示而已。)

二、MVC – web 展示层设计框架

        但凡设计系统前端,那么对 MVC 这个缩写一定都不陌生。MVC (model - view - controller)作为交互系统的设计框架,将交互方式分成了: 数据装载与搬运部分( model );展示与交互界面( view );和逻辑流程控制部分( controller )。在本系统的设计中,model 部分由 DTO(Data - Transfer - Object ) 承担,而 controller 部分则由 Spring 进行统一调度,至于 view 部分,则是由 jsp 进行承担。

三、web 交互界面标准化框架

        在 web - UI 界面的构建中,市面上有许多成熟、优美的开源框架,比如:Bootstrap、Vue、React 等。这些开源框架通过编写原生 HTML 、CSS、JavaScript、jQuery ,将一些通用的功能和页面设计封装成库类插件。通过调用这些开源的库类,可以省去我们很多写页面 UI 设计的时间。同样的,在该系统中,由于更注重系统逻辑编写,在交互界面的设计上,采用了简单的 bootstrap 的标准化设计。

(1)web 目录结构

        web 界面的搭建,首先是进行目录结构的规划,web 前端相关代码,均放置于与 java 同级的 webapp 文件夹下。目录内容如下:
在这里插入图片描述
        目录结构简述如下:


webapp 
│  
├─resources :用于存放 js、css 等配置文件
│  └─script
│          *.js
│          
└─WEB-INF
    │  web.xml : web 配置文件
    │  
    ├─jsp :用于放置 web 端的界面代码,将页面代码放在 WEB-INF 文件夹下的好处是,可以将 web 端页面代码保护起来,用户在访问系统时,无法通过输入 URL 绝对路径的方式对页面进行访问。
    │  │  *.jsp
    │  │  
    │  └─common :放置 web 端公有页面配置,如界面设计中的基本导入插件等。
    │          *.jsp
    │          
    └─lib :放置一些需要导入项目的 jar 包(不过在有 maven 工具和 Spring 的统一管理下,基本没什么作用。
    

(2)项目编写

        由于 web 界面较为简单,此处不再将 jsp 代码附上。在 web 前端,最核心的逻辑部分是实现交互的 JavaScript 代码,视频中给出了一种逻辑编码的新思路,即不再将编码封装成函数进行调用,而是将整个逻辑写成 json 的形式,这样做的好处是整个逻辑被封装到了一块,形成所谓的模块化,代码所有的函数形成内部调用。但个人还是不太习惯用这种方式,因为这样的写法,一个模块信息量太大,不利于后续的维护。
       以下是 JavaScript 的核心代码块。需要注意的是,在导入该 JavaScript 片段前,必须确保已经在 jsp 页面中加载了 bootstrap 框架,否则代码中引用 bootstrap 的代码块片段将会失效。

// 存放只要交互逻辑 js 代码
// javascript 模块化
var seckill = {
    // 封装秒杀相关 ajax 的url
    URL : {
        now : '/seckill/time/now',
        exposer : function (seckillId){
            return '/seckill/' + seckillId + '/exposer';
        },
        execution : function (seckillId, md5) {
            return '/seckill/' + seckillId + md5 + '/execution';
        }
    },
    validatePhone : function (phone){
        if(phone && phone.length == 11 && !isNaN(phone)){
            console.log("return true : ", phone, phone.length, isNaN(phone) );
            return true;
        }else {
            console.log("return false : ", phone, isNaN(phone) );
            return false;
        }
    },
    handleSeckill : function (seckillId, node) {
        // 处理秒杀逻辑
        node.hide()
            .html('<botton class="btn btn-primary brn-lg" id="killBtn">开始秒杀</botton>');
        $.post(seckill.URL.exposer(seckillId), {}, function (result) {
            // 在回调函数中执行交互流程
            if(result && result['success']){
                var exposer = result['data'];
                if(exposer['exposed']){
                    // 开启秒杀, 获取秒杀地址
                    var md5 =exposer['md5'];
                    var killUrl = seckill.URL.execution(seckillId, md5);
                    console.log('killURL : ' + kilUrl);
                    // 绑定一次点击事件
                    $('#killBtn').one('click', function (){
                        // 执行秒杀请求
                        // 1.禁用按钮
                        $(this).addClass('disabled');
                        // 2.发送请求执行秒杀
                        $.post(killUrl, {}, function (result) {
                            if(result && result['success']){
                                var killResult = result['data'];
                                var state = killResult['state'];
                                var stateInfo = killResult['stateInfo'];
                                // 3.显示秒杀结果
                                node.html('<span class="label label-success">' + stateInfo +'</span>');
                            };
                        });
                    });
                    node.show();
                }else{
                    // 未开启秒杀
                    var now = exposer['now'];
                    var start = exposer['start'];
                    var end = exposer['end'];
                    // 重新开始计算计时逻辑
                    seckill.countdown(seckillId, now, start, end);
                }
            }else{
                console.log('result: ' + result);
            }
        })
    },
    countdown : function (seckillId, nowTime, startTime, endTime) {
        var seckillBox = $('#seckill-box');
        // 时间判断
        if(nowTime > endTime){
            seckillBox.html('秒杀结束!');
        }else if(nowTime < startTime){
            // 秒杀未开始,计时事件绑定
            var killTime = new Date(startTime + 1000);  // 防止用户端计时时间偏移
            seckillBox.countdown(killTime, function (event){
                var format = event.strftime('秒杀倒计时: %D天 %H时 %M分 %S秒');
                seckillBox.html(format);
            }).on('finish.countdown', function () {
                // 时间完成后回调事件 -- 获取秒杀地址,实现逻辑,执行秒杀
                seckill.handleSeckill(seckillId, seckillBox);
            });
        }else {
            // 秒杀开始
            seckill.handleSeckill(seckillId, seckillBox);
        }
    },
    // 详情页秒杀逻辑
    detail : {
        // 详情页初始化
        init : function (params) {
            // 手机验证和登录,计时交互
            // 规划交互流程
            // 在cookie中查找手机号
            var killPhone = $.cookie('killPhone');
            var seckillId = params['seckillId'];
            var startTime = params['startTime'];
            var endTime = params['endTime'];
            // 验证手机号
            if(!seckill.validatePhone(killPhone)){
                // 绑定phone
                var killPhoneModel = $("#killPhoneModel");
                // 控制输出,显示弹出层
                killPhoneModel.modal({
                    show : true,  // 显示弹出层
                    backdrop : 'static',  //禁止位置关闭
                    keyboard : false  // 关闭键盘事件
                });
                $('#killPhoneBtn').click(function(){
                   var inputPhone = $('#killPhoneKey').val();
                   if(seckill.validatePhone(inputPhone)){
                       // 将 phone 写入 cookie
                       $.cookie('killPhone', inputPhone, {
                           expires : 7,
                           path : '/seckill'
                       });
                       // 刷新页面
                       window.location.reload();
                   }else {
                       $('#killPhoneMessage').hide().html('<label class="label label-danger">手机号错误</label>').show(300);
                   }
                });
            }
            // 登录之后: 计时交互
            $.get(seckill.URL.now, {}, function (result) {
                if(result && result['success']){
                    var nowTime = result['data'];
                    // 时间判断,计时交互
                    seckill.countdown(seckillId, nowTime, startTime, endTime);
                }
            });
        }
    }
}

(3)启动项目

       当代码全部编写完毕,就是项目的启动,不知道有没有人跟我踩到了同样的坑。那就是明明代码编写无误,启动时却来了个 404 !!(找不到页面,说明 URL 定向错误,这就很过分,明明页面在的说。)
在这里插入图片描述
       由于确定页面在物理上是存在的,那么可能的原因只能是 URL 在定向时发生了错误,导致页面未被索引成功。这个是视频中没被提到的,因为 IDEA 在创建 java - web 项目时,默认在服务器根目录下创建一个与项目名相同的文件夹,以此存放 web 项目,但本项目的存放位置是 root 因此无法被索引到。解决方法如下:
在菜单栏找到 Edit Configurations… 单击,在弹出的窗口中,找到对应的 Tomcat Server 启动项,选中 Deployment ,将 ‘Application context’ 改为 ‘/’ 点击 ‘OK’, 此时,修改完毕。重新启动服务器,可以看到问题解决了!
在这里插入图片描述
在这里插入图片描述
       如果成功,可以看到类似的界面,此时,功能符合预期,项目建立完毕。
在这里插入图片描述

小贴士:HTTP状态码分类

分类分类描述
1XX表服务器接收到信息请求,客户端应继续请求
2XX表成功(最佳状态),客户端的操作被成功接收并处理后返回给客户端
3XX表重定向,需要客户端进一步操作
4XX表客户端错误(最头疼的错误),说明访问资源不存在或请求无法完成
5XX表服务器错误(通常来讲就是服务器挂掉或者出现代码bug了)
【Claude Code】Claude Code 使用指南 本文介绍了AI编码助手Claude的基础和进阶操作指南。基础部分涵盖启动命令、模式切换(自动编辑/Plan/Yolo模式)、资源监控等核心功能,重点讲解了斜杠命令的使用方法。进阶操作详细说明了CLAUDE.md文件的创建与管理,包括项目规范、代码风格等内容的配置,以及如何通过该文件建立持久上下文。同时提醒了使用过程中的安全风险,建议通过配置文件限制AI对关键代码的访问权限。全文提供了完整的操作指引和安全建议,帮助开发者高效安全地使用Claude进行编码辅助。 阅读详情

相关推荐

几款支持国标GB28181的平台以及视频监控设备接入的配置方法(Web端无插件播放)

GB28181解决的一个主要问题就是如何远程、跨网络、跨区域、跨级别的访问网络中的监控设备(包括IPC、NVR等),本文介绍几款G28181平台的接入配置方法,适合有监控视频摄像头的远程接入和预览需求的人群参考使用。

一名高级工程师的博客 1万+

4.企业应用架构模式 --- Web表现层

一个单独的web服务器能够处理很多种类的程序。这些应用程序可以是动态的,把它们放置到适当的目录下就可以加载到服务器。web服务器的工作是:解释请求方的 URL并调用服务器端应用程序来处理这些请求消息。构建web服务器上应用程序的方法主要是有两种:一种是使用脚本,另一种是使用服务器页面。 脚本形式是一个程序,通常,调用函数或方法来处理http的请求调用。如CGI脚本和Java serv...

enlyhua的专栏 374

logisim实验——通过2个半加器实现1-bit全加器,通过4个一位全加器构成4-bit加法器(详解)

一、由异或门和与门所构成的半加器: 二、由两个半加器构成的1-bit全加器: ..

zep 1万+

【JavaWeb】Java三层架构写一个登录案例

Java三层架构

wang_qiu_hao的博客 1083

ANSYS APDL齿轮建模实战:从渐开线方程到完整3D模型的保姆级教程

本文详细介绍了使用ANSYS APDL进行齿轮建模的全过程,从渐开线方程的数学基础到完整3D模型的创建。通过参数化命令流实现高精度齿轮建模,特别适合机械设计和仿真分析需求。教程包含关键参数计算、APDL环境配置、单齿齿廓建模以及全齿轮阵列复制等实用技巧,帮助工程师快速掌握ANSYS APDL在齿轮建模中的应用。

lg888的博客 446

[cryoEM] cryoSPARC简介

cryoSPARC系统结构概述 cryoSPARC是一个后端和前端高性能计算软件系统,为单颗粒冷冻电镜提供数据处理和图像分析能力,以及丰富的基于浏览器的用户截面和命令行工具。 Master-worker模式 系统基于主用户模式。 主进程(web应用,核心应用程序和MongoDB数据库)一起在主节点上运行。主节点需要相对轻量级的资源(2+ CPU< 16GB+ RAM)。 工作程序进程可以在具有GPU的任何可用节点上生成,负责所有实际计算和数据处理,并由主节点调度。注意:同一节点可以同时充当主节点和辅

进阶中的程序员吃吃的博客 7797

基于ASP.NET教学辅助系统设计与实现

本系统采用三层架构, WEB展示层通过统一的接口向数据访问层发送请求,但需经过业务逻辑层将请求按照一定的逻辑规则处理后进入数据库操作,然后将从数据库返回的数据集合封装成对象的形式返回到WEB展示层,通过这样的数据处理流程,用户表现层甚至可以不知道数据的结构,只要维护与数据访问层之间的接口即可。Web展示层:系统最外层,向用户展示各种界面,用户通过界面对系统进行操作,并通过业务逻辑层来实现用户各种操作信息的添加,删除和修改。(8)课程:课程号、课程名、教师号、学分、属性、最大人数、状态、专业号、学期。

m0_60139146的博客 985

树莓派4B+DroneKit实战:手把手教你用Python控制无人机飞行(附避坑指南)

本文提供了一份详尽的树莓派4B与DroneKit配置实战指南,涵盖从硬件选型、软件环境搭建到Python编程控制无人机的完整流程。文章重点解决了ARM架构下的兼容性问题、MAVLink通信配置及端口管理等常见难题,并附带了实用的避坑指南和代码示例,帮助开发者构建稳定可靠的无人机控制系统。

weixin_29056781的博客 410

ssm框架之springMVC

什么是SpringMVC springMVC就是spring框架的一个子模块,是spring基于MVC设计模式提供的web展示层框架,通常单独拿出来作为一个框架说明,但它只是spring的一个子模块。 * 3.0后全面超越Struts2,成为最优秀MVC框架,通过一套MVC注解,只需配置一个前端控制器就可以实现以前必须实现大量接口才能得到的功能 * 全面支持REST的URL风格,而且此框架有非常不...

殷志鹏的博客 502

MATLAB实战:手把手教你用三频四步相移法搞定结构光三维重建(附完整代码)

本文详细介绍了如何使用MATLAB实现三频四步相移法进行高精度结构光三维重建。通过光栅图像预处理、相位计算、多频外差与相位解包裹等步骤,结合完整代码示例,帮助读者掌握从二维图像到三维点云的关键技术。该方法在工业检测和逆向工程中具有抗干扰能力强、高分辨率和鲁棒性等优势。

weixin_29201933的博客 338

机器人控制入门:用SAC算法让机械臂学会抓取(PyBullet仿真教程)

本文详细介绍了如何使用SAC算法在PyBullet仿真环境中训练机械臂完成抓取任务。通过强化学习中的软Actor-Critic(SAC)算法,结合熵最大化机制和双Q网络架构,有效解决了机械臂控制中的探索难题。教程包含环境搭建、算法原理、状态空间设计、奖励函数优化等核心内容,并提供了实用的训练技巧和参数调优指南。

weixin_29091105的博客 362

第四步 WEB 展示层(显示层) UserReg.aspx.cs 页 实例

  2008-01-16 16:59 using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI

tiaru的专栏 486

YOLOv8源码解析与复现:ShuffleAttention:高效的混合注意力机制 实现通道和空间混合注意力

随着深度学习在计算机视觉领域的飞速发展,卷积神经网络(CNNs)已经成为图像分类、目标检测、语义分割等任务的核心。为了进一步提升模型的性能,研究者们引入了“注意力机制”,旨在让网络能够动态地关注输入数据中最具信息量的部分。经典的注意力模块,如SE-Net(Squeeze-and-Excitation Networks)和CBAM(Convolutional Block Attention Module),通过通道注意力或结合通道与空间注意力,显著增强了模型的特征表达能力。

FJN110的博客 554

SSM 框架搭建 sckill 秒杀系统 —— step.3 业务逻辑层建设

SSM 框架搭建 sckill 秒杀系统 —— step.3 业务逻辑层建设

nightNavigation的博客 552

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SSM 框架搭建 sckill 秒杀系统 —— step.4 web控制层建设

SSM 框架搭建 sckill 秒杀系统 —— step.4 表现层创建与渲染

nightNavigation的博客 412

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

SSM 框架搭建 sckill (秒杀系统) —— step.1 前期准备 + 框架配置

SSM 框架搭建 sckill 秒杀系统 —— step.1 前期准备与DAO层搭建写在前面一、前期准备: 写在前面        初次接触 SSM 框架,是为了跟队友一起搭建项目,作为团队的“系统开发师”,老师推荐了当下极为流行的 java web 开发开源框架—— SSM(springMVC + spring + MyBatis)框架。于是乎,进行了新一轮的框架学习(“学习 + 实践” 嘛,总得先复现别人的教程,然后搭建自己的平台。

nightNavigation的博客 391

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

SSM 框架搭建 sckill (秒杀系统) —— step.2 持久层建设

SSM 框架搭建 sckill 秒杀系统 —— step.2 DAO层建设一、DAO层简介        接 “前期准备 + 框架配置”,系统搭建的关键步骤中,第二步是进行数据库的构建以及系统 DAO 层的建设。 一、DAO层简介        DAO层全称 Data Access Object ,是数据库 ...

nightNavigation的博客 515

ssm项目个人总结

SSM个人总结 该项目来源:动力节点CRM项目 1、ssm定义 ssm是指springMVC、Spring和Mybatis框架的整合,是标准的MVC模型。MVC框架有四层,mapper(dao层),service层,controller层,View层。使用spring实现业务对象的管理,springmvc对请求转发以及视图层的管理,mybatis实现对数据(库)持久化的管理。 2、MVC架构 1)持久层:Dao层(Mapper层) 作用:主要做数据持久层的工作,负责与数据库的增删改查等任务。 Dao层首

weixin_57342469的博客 1010

JavaWEB快速入门之三层架构[新闻发布系统08]【11】

开发模式: 指模式在开发过程中总结出的"套路",总结出的一套约定俗称的设计模式。 ③ 三层架构——三层架构就是为了符合“高内聚,低耦合”思想,把各个功能模块划分为表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三层架构,各层之间采用接口相互访问,并通过对象模型的实体类(Model)作为数据传递的载体,不同的对象模型的实体类一般对应于数据库的不同表 ② model2模式 ① model1模式——JSP Model1是JavaWeb早期的模型,它适合小型 三层架构的优势: 1,结构清晰、耦合

m0_67768699的博客 1370

SSM框架的各层功能以及执行流程

一、SSM框架中各层级间的作用及关系 表现层(springMVC):Controller层(Handler层) 负责具体的业务模块流程的控制 Controller层通过要调用Service层的接口来控制业务流程,控制的配置也在Spring配置文件里面。 业务层(Spring):Service层 Service层:负责业务模块的逻辑应用设计。 首先设计其接口,然后再实现他的实现类。 ...

hanshzh的博客 2620

SSM框架下各层的解释说明(Controller等)

SSM框架 SSM框架是spring MVC ,Spring和Mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层(web),controller层,service层,dao层四层,使用spring MVC负责请求的转发和视图管理。Spring实现业务对象管理,Mybatis作为数据对象的持久化引擎。 表现层(web):通俗讲就是展现给用户的界面,即用户在使用一个系统的时候他的所见所得。 业务逻辑层(service):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。 数据

CJW的博客 2万+

【Java】SSM框架简介

SSM简介 Spring+SpringMVC+Mybatis

qq_44878985的博客 3371

平台--web层之展现层

Web 上有很多事要做。还是以降低技能,提高开发效率为目的。 Web大部分事情都体现在展现层。本着减少耦合,提高重用性,展现层和后台MVC框架尽量无关,也就是说不管用什么展现技术,如,html,ajax,flash等等,数据传递处理是一个接口(这是存在的事实,偶的系统界面从html到ria,几乎都是改表现层,不动java代码);或者更换MVC框架,界面不用改(目前偶还没遇到这样的案...

小程序员 962

前端web展示服务层

部署方法: 部署web静态页面,通过nginx反向代理。因为我们公司有haproxy,因此通过了两次反向代理,域名必须在haproxy,nginx配置。如下: 部署项目:pims-admin-fed 先配置haproxy,在配置文件里添加如下内容, acl mallPims hdr(host) -ipims.daxmall.comuse_backend Pimsbackend if ma...

weixin_30765505的博客 596

web项目各层功能区分(SSH举例)

web项目各层功能区分(SSH举例)   最基本的分层方式,结合了SSH架构: modle层就是对应的数据库表的实体类。 Dao层是使用了Hibernate连接数据库、操作数据库(增删改查)。 Service层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简单的判断)。 Action层:引用对应的Service层,在这里结合Struts的配置文件,跳转到指定的页面,当...

杨杨杨~~的博客 2739

前端开发:一款近年非常受欢迎、简单的WEB弹出层组件(layer)

IT痕迹 2017-10-01 16:43 layer是一个开源免费的弹出层组件,简单易用、美观,功能强大能够满足你对弹出层的几乎所有需求,每一种模式都有自己的特色,调用简单实用性强,可轻松实现Alert、Confirm、Prompt、普通提示、页面区块、iframe、tips等几乎所有的弹出模式。此组件知名度高,在此仅介绍给不知道的新人,谢谢支持。 1、下载及初始化 /

u011277123的博客 6486
上一篇: SSM 框架搭建 sckill 秒杀系统 —— step.4 web控制层建设
揽月泛夜舟
博客等级 码龄6年 6粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

揽月泛夜舟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值