Java框架_Spring5_day06_转账案例(事务)

Spring5中文文档 Spring5中文文档,带书签!想学Spring的同学可以看一看! 立即下载

八、转账案例(添加事务)

8.1 导入坐标,pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.cpz</groupId>
    <artifactId>spring_account</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.8</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>

8.2 创建接口 AccountDao.java、AccountService.Dao

AccountDao.java

package com.cpz.dao;

import com.cpz.domain.Account;

public interface AccountDao {

    public Account findByName(String name);

    public void updateAccount(Account account);

}

AccountService.Dao

package com.cpz.service;

public interface AccountService {

    public void transfer(String sourceName,String targetName,Float money);

}

8.3 账户的实体类

package com.cpz.domain;

public class Account {
    private Integer id;
    private String name;
    private Float money;

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getMoney() {
        return money;
    }

    public void setMoney(Float money) {
        this.money = money;
    }
}

8.4 ConnectionUtils.java

作用:连接的工具类,它用于数据源中获取一个连接,并且实现和线程的绑定。

package com.cpz.utils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionUtils {
    // 让当前线程和Connection绑定
    private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    // 获取连接对象,并与本地线程绑定
    public Connection getThreadConnection(){
        // 获取线程中的Connection
        Connection connection = tl.get();
        // 线程第一次执行数据操作
        if (connection == null){
            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            // 线程绑定
            tl.set(connection);
        }
        return connection;
    }

    // 如果线程结束,解绑
    public void releaseConnection(){
        tl.remove();
    }
}

8.5 TransactionManager.java

作用:和事务管理相关的工具类,包含了开启、提交、回滚事务和释放连接。

package com.cpz.utils;

import java.sql.SQLException;

public class TransactionManager {

    private ConnectionUtils connectionUtils;

    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }

    // 开启事务
    public void beginTransaction(){
        try {
            connectionUtils.getThreadConnection().setAutoCommit(false);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 提交事务
    public void commit(){
        try {
            connectionUtils.getThreadConnection().commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 回滚事务
    public void rollback(){
        try {
            connectionUtils.getThreadConnection().rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 删除事务
    public void close(){
        try {
            connectionUtils.getThreadConnection().close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

8.6 AccountDaoImpl.java

作用:注入连接工具对象,使得操作数据库从同一个连接中获取

package com.cpz.dao.impl;

import com.cpz.dao.AccountDao;
import com.cpz.domain.Account;
import com.cpz.utils.ConnectionUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class AccountDaoImpl implements AccountDao {

    QueryRunner queryRunner;
    ConnectionUtils connectionUtils;

    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }

    public void setQueryRunner(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }

    public Account findByName(String name) {
        try {
            List<Account> list = queryRunner.query(connectionUtils.getThreadConnection(),"select * from account where name = ?", new BeanListHandler<Account>(Account.class), name);
            if (list == null || list.size() == 0){
                return null;
            }else if (list.size() > 1){
                throw new RuntimeException("结果集不唯一,数据有问题!");
            }
            return list.get(0);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void updateAccount(Account account) {
        try {
            queryRunner.update(connectionUtils.getThreadConnection(),"update account set money = ? where id = ?", account.getMoney(), account.getId());
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

8.7 AccountServiceImpl.java

作用:注入事务管理器对象,对每个操作都需要开启事务、提交事务、关闭事务,如果抛出异常,需要回滚事务

package com.cpz.service.impl;

import com.cpz.dao.AccountDao;
import com.cpz.domain.Account;
import com.cpz.service.AccountService;
import com.cpz.utils.TransactionManager;

public class AccountServiceImpl implements AccountService {

    AccountDao accountDao;
    TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void transfer(String sourceName, String targetName, Float money) {
        try {
            // 开启事务
            transactionManager.beginTransaction();
            // 执行操作
            //1.根据名称查询转出账户
            Account sourceAccount = accountDao.findByName(sourceName);
            //2.根据名称查询转入账户
            Account targetAccount = accountDao.findByName(targetName);
            //3.转出账户减钱
            sourceAccount.setMoney(sourceAccount.getMoney() - money);
            // 设置异常
            int i = 10 / 0;
            //4.转入账户加钱
            targetAccount.setMoney(targetAccount.getMoney() + money);
            //5.更新转出账户
            accountDao.updateAccount(sourceAccount);
            //6.更新转入账户
            accountDao.updateAccount(targetAccount);
            // 提交事务
            transactionManager.commit();
        }catch (Exception e) {
            e.printStackTrace();
            // 回滚操作
            transactionManager.rollback();
        }finally {
            // 释放连接
            transactionManager.close();
        }

    }
}

8.8 ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <bean id="transactionManager" class="com.cpz.utils.TransactionManager">
        <property name="connectionUtils" ref="connectionUtils"></property>
    </bean>

    <bean id="connectionUtils" class="com.cpz.utils.ConnectionUtils">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="accountService" class="com.cpz.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

    <bean id="accountDao" class="com.cpz.dao.impl.AccountDaoImpl">
        <property name="queryRunner" ref="queryRunner"></property>
        <property name="connectionUtils" ref="connectionUtils"></property>
    </bean>

    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
        <!--这里要去掉queryRunner的默认连接池配置,由ConnectionUtils 获取连接-->
    </bean>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

</beans>

8.9 测试类

package com.cpz.test;

import com.cpz.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringTest {

    @Autowired
    AccountService accountService;

    @Test
    public void transfer(){
        accountService.transfer("aaa","bbb",100f);
    }
}

 

银行取款转账系统(Java编写) 这是用Java编写的一个简单的银行转账系统,包括取款,存款,转账等功能,其中用到了数据库的连接,采用Eclipse编写,包含数据库的设计文件。非常适合有一定基础的Java初学者使用。 package com.gujunjia.bank; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.sql.*; /** * * @author gujunjia */ public class DataBase { static Connection conn; static PreparedStatement st; static ResultSet rs; /** * 加载驱动 */ public static void loadDriver() { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { System.out.println("加载驱动失败"); } } /** * 创建数据库的连接 * * @param database * 需要访问的数据库的名字 */ public static void connectionDatabase(String database) { try { String url = "jdbc:mysql://localhost:3306/" + database; String username = "root"; String password = "gujunjia"; conn = DriverManager.getConnection(url, username, password); } catch (SQLException e) { System.out.println(e.getMessage()); } } /** * 关闭数据库连接 */ public static void closeConnection() { if (rs != null) { // 关闭记录集 try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { // 关闭声明 try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { // 关闭连接对象 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } package com.gujunjia.bank; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * 本类主要实现整个系统的界面 * * @author gujunjia */ public class MainFrame extends JFrame implements ActionListener, FocusListener { /** * */ private static final long serialVersionUID = 1L; public static String userId; JTextField userIdText; JPasswordField passwordText; JButton registerButton; JButton logInButton; public MainFrame() { super("个人银行系统"); this.setSize(400, 500); this.setLocation(getMidDimension(new Dimension(400, 500))); getAppearance(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } /** * 获取屏幕的中间尺寸 * * @param d * Dimension类型 * @return 一个Point类型的参数 */ public static Point getMidDimension(Dimension d) { Point p = new Point(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); p.setLocation((dim.width - d.width) / 2, (dim.height - d.height) / 2); return p; } /** * 布局 * * @return Container */ public Container getAppearance() { Container container = this.getContentPane(); container.setLayout(new GridLayout(4, 0)); JLabel label1 = new JLabel("个人银行系统"); label1.setFont(new Font("楷体", Font.BOLD, 40)); JLabel label2 = new JLabel("账号:"); label2.setFont(new Font("楷体", Font.PLAIN, 15)); JLabel label3 = new JLabel("密码:"); label3.setFont(new Font("楷体", Font.PLAIN, 15)); userIdText = new JTextField(20); userIdText.addFocusListener(this); passwordText = new JPasswordField(20); passwordText.addFocusListener(this); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); JPanel jp4 = new JPanel(); jp1.add(label1); jp2.add(label2); jp2.add(userIdText); jp3.add(label3); jp3.add(passwordText); registerButton = new JButton("注册"); registerButton.addActionListener(this); registerButton.setFont(new Font("楷体", Font.BOLD, 15)); logInButton = new JButton("登录"); logInButton.addActionListener(this); logInButton.setFont(new Font("楷体", Font.BOLD, 15)); jp4.add(registerButton); jp4.add(logInButton); container.add(jp1); container.add(jp2); container.add(jp3); container.add(jp4); return container; } public void actionPerformed(ActionEvent e) { Object btn = e.getSource(); if (btn == registerButton) { new Register(); } else if (btn == logInButton) { String id = userIdText.getText().trim(); String password = new String(passwordText.getPassword()); Bank bank = new Bank(); if (id.equals("") || password.equals("")) { JOptionPane.showMessageDialog(null, "请输入账号和密码"); } else { String dPassword = bank.getPassword(id); if (password.equals(dPassword)) { userId = id; this.dispose(); new UserGUI(); } else { JOptionPane.showMessageDialog(this, "密码或用户名错误", "错误", JOptionPane.ERROR_MESSAGE); } } } } @Override public void focusGained(FocusEvent e) { Object text = e.getSource(); if (text == userIdText) { userIdText.setText(""); userIdText.setFont(new Font("宋体", Font.BOLD, 15)); } else if (text == passwordText) { passwordText.setText(""); } } @Override public void focusLost(FocusEvent e) { Object text = e.getSource(); if (text == userIdText) { if (userIdText.getText().equals("")) { userIdText.setText("请输入账号"); userIdText.setFont(new Font("楷体", Font.ITALIC, 15)); } } } } 立即下载

相关推荐

java8-spring5部分技术与工具介绍

java8-spring5部分技术与工具介绍 java8-spring5部分技术与工具介绍

【学习笔记】事务+存储过程实现用户转账功能

1.数据库端(Navicat)实现事务和存储过过程的函数。 IN `fromuser` varchar(20),IN `touser` varchar(20),IN `balance` float,OUT `flag` varchar(20) BEGIN -- Routine body goes here... -- 定义变量t DECLARE t FLOAT; -- 开启事务 start TRANSACTION; -- 转入金额 UPDATE trans SET balance=balan

kevin_g的博客 853

银行的简单转账代码(java)

就是大二我们上讨论课用的简单代码,希望以后的学弟们能用的着

银行转账案例-Spring纯注解模式代码示例

一. 资源文件(resources) SpringConfig package com.lagou.edu; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.*; import javax.sql.DataSource; /** * @aut

舞鹤白沙编码日志 431

单笔转账到支付宝账户接口JAVA版本demo

提供支付宝开放平台的单笔转账到支付宝账户接口JAVA版本demo 望大家共同进步

数字后端DRC Violation定位与自动化修复:Innovus与Calibre协同实战

设计规则检查(DRC)是芯片tapeout前确保版图可制造性的关键验证环节。在数字后端流程中,Calibre作为signoff级物理验证工具,会依据代工厂SVRF规则文件对GDS进行严格几何检查;而Innovus则提供快速迭代的in-design DRC反馈。两者协同成为工程师定位violation、保障流片成功的主流工作流。面对成千上万条DRC violation,高效的定位与分类思路、跨工具映射技巧,以及基于Tcl脚本的自动化修复方法,能大幅缩短物理验证周期。本文从DRC的分层定位出发,结合Innovu

weixin_29185167的博客 335

java 事务处理代码_Java事务(四) - 使用模板模式改造事务处理

一. 前言:在上一篇博文中, 我们使用TransactionManager和ThreadLocal完成线程安全的事务管理,不知大家有没有发现,AccountService代码充斥着很多事务处理的代码,其实这些代码在很多方法里面都是重复出现,我们可以使用Template模式进行优化。二. 实现:1. 写一个模板类:TransactionTemplate/*** 模板类*/public abstrac...

weixin_33670640的博客 357

Matlab GUIDE -- 串口操作

1、首先新建-->应用程序-->GUIDE。 2、绘制一个简单的UI。 3、然后右击“打开串口”图标-->查看回调-->callback,即可打开此图标的回调函数,此回调函数是press button时执行(可按需要选择其他回调)。 4、在回调函数中添加打开串口的代码。 delete(instrfindall); %删除所有串口 s3 = serial('CO

Asgard-X 2837

04 spring : 07.银行转账案例&&Java动态代理的两种实现方式

07.银行转账案例 2 案例中添加转账方法并演示事务问题 3 分析事务的问题并编写ConnectionUtils、4 编写事务管理工具类并分析连接和线程解绑 5 编写业务层和持久层事务控制代码并配置spring的ioc、6 测试转账并分析案例中的问题 7 代理的分析、8 基于接口的动态代理回顾、9 基于子类的动态代理、10 使用动态代理实现事务控制 代码 day02_eesy_0...

Marlon康 579

【自动驾驶】汽车智能驾驶计算芯片

本文介绍汽车智能驾驶计算芯片的软硬件要求、 可靠性和安全性要求、 性能要求,和相应的试验方法。除了用于汽车智能驾驶, 其他领域的计算芯片可参照执行。

Mr.Cssust的博客 2631

AC7811无感FOC实战:从开环到闭环的电机控制调试全记录

本文详细记录了基于国产AC7811芯片实现无感FOC电机控制的全过程。从硬件软件环境搭建、开环I/F启动调试,到滑模观测器参数整定,再到平滑切入闭环及双环PID调节,提供了完整的实战步骤与参数调试心法。文章重点分享了无感控制从开环到闭环切换的关键技巧与常见问题排查清单,为工程师提供了一份避坑指南。

kotlin6android的博客 713

Java_Spring:7. AOP 的相关概念

AOP:全称是面向切面编程。简单的说它就是把程序重复代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对已有方法进行增强。

JiangTao_qjww的博客 970

发那科机器人抓手与物料搬运阀的配置与优化实践

本文详细介绍了发那科机器人抓手与物料搬运阀的配置与优化实践,包括基础配置指南、阀岛与输入模块的详细设置、测试程序编写与验证技巧,以及常见问题排查与性能优化建议。通过实际案例和经验分享,帮助技术人员快速掌握关键配置步骤,提升物料搬运系统的稳定性和效率。

weixin_33738555的博客 384

hibernate框架 多少钱_Java高级框架 - Spring学习(04) Day06

Spring第四天讲义今日内容1. Spring的事务管理2. Spring和MyBatis框架的集成1. Spring的事务管理1.1. 事务是什么?在操作数据库时(增删改),如果同时操作多次数据,我们从业务希望,要不全部成功,要不全部失败。这种情况称为事务处理。A转账给B。第一步,扣除A君账号要转的金额第二步,增加B君账号的金额事务:指单个逻辑操作单元的集合1.2. Spring事务控制我们要...

weixin_39900286的博客 72

Windows正在配置Xftp6在下面的框输入包含安装程序包“Xftp 6.msi“的文件夹的路径

Windows正在配置Xftp6在下面的框输入包含安装程序包“Xftp 6.msi"的文件夹的路径

m0_56588258的博客 2471

接入 deepseek 实现AI智能问诊

必须包含user角色,用于传递用户输入。system角色可选,用于设置对话背景。多轮对话需要将历史记录添加到messages中。

weixin_51326478的博客 6541

Spring-学习笔记10【Spring事务控制】

Spring-学习笔记10【Spring事务控制】

upward 836

【学习系列】SAP RAP 2:创建第一个RAP应用

本文介绍了从零开始创建基于SAP RAP(ABAP RESTful Application Programming Model)的Fiori应用的完整流程。首先说明了学习RAP需要结合官方文档和教程,并提供了相关资源链接。文章详细讲解了开发环境的准备要求,包括系统版本、开发工具和基本知识。重点演示了如何通过8个步骤创建支持CRUD操作和草稿功能的RAP应用:1)创建数据库表;2)定义CDS视图实体;3)创建投影视图;4)定义行为;5)创建行为投影;6)定义服务;7)绑定服务;8)添加UI注解。

DeveloperMrMeng的博客 1498

Spring-学习笔记01【Spring框架简介】

Spring-学习笔记01【Spring框架简介】

upward 633

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring-学习笔记06【Spring的新注解】

Spring-学习笔记06【Spring的新注解】

upward 557

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

spring基于注解的声明式事务控制

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://m...

Leon_Jinhai_Sun的博客 221

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Spring-学习笔记06【spring_day02资料_dbutils】

Spring-学习笔记06【spring_day02资料_dbutils】

upward 541

事务,事务的特点,事务并发带来的问题,实现事务管理

事务,事务的特点,事务并发带来的问题,实现事务管理

weixin_51635918的博客 1111

Spring-学习笔记05【基于XML的IOC的案例】

Spring-学习笔记05【基于XML的IOC的案例】

upward 1186

Spring-学习笔记09【JdbcTemplate的基本使用】

Spring-学习笔记09【JdbcTemplate的基本使用】

upward 744

采用DBUtil框架实现AOP(面向切面编程)对事务的处理

项目中个文件的结构: 1。导包: commons-dbcp-1.4.jar commons-dbutils-1.4.jar commons-pool-1.5.6.jar mysql-connector-java-5.0.8-bin.jar 2.dbcpconfig.properties配置文件:#\u8FDE\u63A5\u8BBE\u7F6E driverClassName=com

wangyanming123的博客 941
上一篇: Java框架_Spring5_day05_IOC(注解)
下一篇: Java框架_Spring5_day07_AOP(面向切面编程)
chipeize
博客等级 码龄10年 23粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值