【Java程序设计实训】基于B/S架构的MyShop商城


声明:未经允许,请勿转载

实验目的

本次实验旨在通过开发一个基于 B/S 架构的电商平台,深入理解 Web 开发技术,掌握相关知识和技能。具体实验目的如下:

  1. 学习和掌握 Web 开发的基本知识和技术,包括前端技术、后端技术、数据库技术等,理解 B/S架构的基本原理和优势。
  2. 掌握常用的 Web 开发框架和工具,了解它们的作用和使用方法。
  3. 熟悉电商平台的业务流程和功能需求,掌握系统开发的基本方法和流程,包括需求分析、系统设计、系统开发等环节。

实验概述

• 系统名称:基于 B/S 架构的 MyShop 商城
• 系统开发背景:
对于用户来说,MyShop 商城的创作目的是为其提供一个完整的电商购物平台,让用户能够方便、快捷地购买自己所需的商品。用户可以通过该平台进行商品浏览、购物车管理、订单管理、支付等操作,同时也可以享受到平台提供的优惠活动和促销信息。MyShop 商城还会为用户提供一个安全、可靠的购物环境。平台会采取各种措施来保护用户的个人信息和支付安全,例如加密传输、防止 SQL 注入、防止 XSS 攻击等。同时,平台也会对商家进行审核和监管,确保商品的质量和售后服务的质量,保障用户的权益。

• 系统用户:会员,游客,管理员。
• 编程环境:Java、Tomcat、MySQL,jsp、CSS、JavaScript 等,其中使用 C3P0 连接池技术管理数据库连接,

系统功能概述

Myshop 商城概述

MyShop 商城是一个完整的电商购物平台,可通过正确的用户名及其密码进入系统购物。系统分为七大模块,商品展示模块、用户模块、购物车模块、订单模块、支付模块、后台模块。该系统分为用户端和管理端两部分。
• 用户端:主要功能包括浏览商品,加入购物车,支付订单,查询订单。
• 管理端:主要功能包括增加、删除、修改、查找会员、订单信息。

该系统有三个参与者,分别为会员、游客和管理员。会员登录后可以浏览商品信息,将商品加入购物车,下单,支付订单;游客可以浏览商品信息,但在加入购物车时会弹出会员登录注册窗口;管理员登录后可以管理商品信息、会员信息以及订单信息。

系统开发分析

需求分析:
首先,需要对 Myshop 商城的需求进行分析,明确商城的功能和特点。商城的主要功能包括用户注册、登录、浏览商品、购物车、下单、支付、订单管理等。商城的特点是需要具备良好的用户体验、安全性、性能等方面的要求。
2. 技术选型:
根据项目需求,选择合适的开发框架和技术。在该项目中,我们选择了 jsp、CSS、js 和 Java 技术作为前端和后端的主要技术栈。这些技术都具有较高的性能和可扩展性,可以满足项目的需求。
3. 开发环境:
在选择好技术栈之后,需要搭建相应的开发环境。我们选用了 IntelliJ IDEA 集成开发环境
4. 数据库设计:
根据项目需求,设计合适的数据库结构,包括商品信息、用户信息、订单信息等, 在设计数据库时,需要考虑到商城的数据量和数据结构,以及数据的安全性和性能。
5. 系统架构设计:
在系统架构设计方面,需要考虑到商城的各个模块之间的交互和调用关系,以及系统的可扩展性和可维护性。可以采用分层架构,将系统分为表示层、业务逻辑层、数据访问层等多个层次,实现各个层之间的解耦。
6. 编码实现:
在代码实现方面,需要按照需求分析和系统架构设计的要求,完成各个模块的代码实现。可以先实现用户注册、登录等基本功能,然后再逐步实现商品浏览、购物车、下单、支付、订单管理等功能。在代码实现过程中,需要注意代码的规范性、可读性和可维护性。
7. 测试调试:
在编码实现完成之后,需要进行测试和部署。在该项目中,我们采用了单元测试和集成测试等测试方式,保证系统的质量。同时,需要将系统部署到服务器上,并进行性能测试和安全测试等,确保各个模块的功能正常运行和系统的稳定性和安全性。
8. 优化完善与维护:
对项目进行优化和完善,提高系统的性能和用户体验, 及时修复系统中出现的问题。

功能列表

在这里插入图片描述

系统用例图

在这里插入图片描述
在这里插入图片描述

系统活动图

在这里插入图片描述

数据库设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

运作·界面展示

用户管理模块

新用户注册

在这里插入图片描述

用户登录

在这里插入图片描述

商城首页与用户退出

点击注销,实现用户退出功能退出后返回首页
在这里插入图片描述

商品模块

商品分页展示

在这里插入图片描述
在这里插入图片描述

查看商品详情信息

在这里插入图片描述

购物车模块

空购物车页面

在这里插入图片描述

加入商品到购物车

在这里插入图片描述

订单模块

提交订单并显示订单信息

在这里插入图片描述

支付页面

在这里插入图片描述

地址模块

查看收货地址

在这里插入图片描述

后台模块

管理员登录页面

在这里插入图片描述

管理员中用户管理页面

在这里插入图片描述

管理员之商品管理页面

在这里插入图片描述

管理员之商品添加页面

在这里插入图片描述

项目代码展示

注:本项目代码参考B站一位博主写的

项目结构

在这里插入图片描述

UserController.java

package com.itqf.controller;

import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.service.impl.UserServiceImpl;
import com.itqf.utils.Base64Utils;
import com.itqf.utils.Constants;
import com.itqf.utils.MD5Utils;
import com.itqf.utils.RandomUtils;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Map;

/**
 * 用户用户模块的controller
 */
@WebServlet("/user")
public class UserController extends BaseServlet {

    public String check(HttpServletRequest request, HttpServletResponse response) throws SQLException {
        //1.获取用户名
        String username = request.getParameter("username");
        if (username == null) {
            return Constants.HAS_USER; //不能注册
        }
        // 2.调用业务逻辑判断用户名是否存在
        UserService userService = new UserServiceImpl();
        boolean b = userService.checkedUser(username);
        // 3.响应字符串  存在:1 不存在:0
        if (b) {
            //用户存在
            return Constants.HAS_USER;
        }
        return Constants.NOT_HAS_USER;
    }

    //注册
    public String register(HttpServletRequest request, HttpServletResponse response) throws SQLException {
        //1.获取用户信息
        Map<String, String[]> parameterMap = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user, parameterMap); //映射到user
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //2.完善用户信息
        user.setUstatus(Constants.USER_NOT_ACTIVE); //默认未激活状态0,激活1
        user.setUrole(Constants.ROLE_CUSTOMER); //普通客户0 管理员1
        user.setCode(RandomUtils.createActive());//激活码
        // 密码加密,md5进行加密
        user.setUpassword(MD5Utils.md5(user.getUpassword()));

        //3.调用用户业务逻辑进行注册
        UserService userService = new UserServiceImpl();
        try {
            userService.registerUser(user);
        } catch (SQLException e) {
            e.printStackTrace();
            request.setAttribute("registerMsg", "注册失败!");
            return Constants.FORWARD + "/register.jsp";
        }

        //4.响应 注册成功跳转激活页面
        return Constants.FORWARD + "/registerSuccess.jsp";
    }

    public String active(HttpServletRequest request, HttpServletResponse response) throws SQLException {
        //1.获取激活码
        //已经转成base64
        String c = request.getParameter("c");
        System.out.println("c="+c);
        //base64翻转
        String code = Base64Utils.decode(c);
        //2.调用激活的业务逻辑
        UserService userService = new UserServiceImpl();
        int i = userService.activeUser(code);

        //3.响应(激活失败(code没有找到) 已经激活 激活成功)
        if (i == Constants.ACTIVE_FAIL) {
            request.setAttribute("msg", "未激活成功!");
        } else if (i == Constants.ACTIVE_SUCCESS) {
            request.setAttribute("msg", "激活成功,请登录!");
        } else {
            request.setAttribute("msg", "已经激活");
        }
        return Constants.FORWARD + "/message.jsp";
    }

    /**
     * 1.前端提交账号密码和验证码
     * 2.对比验证码 成功 ---》 对比账号密码
     * 3.对比账号密码
     * 失败: --》 回到登录页面 进行提示
     * 成功: --》 未激活  登录页面 进行提示
     * --》 已激活  程序的首页  将用户放入session共享域
     */

    public String login(HttpServletRequest request, HttpServletResponse response) throws SQLException {

        //1.获取请求参数(用户名,密码,验证码)
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");//用户输入的验证码
        String auto = request.getParameter("auto"); //自动登录标识
        //正确的验证码
        HttpSession session = request.getSession();
        String codestr = (String) session.getAttribute("code");


        //2.判断验证码是否正确
        // 不考虑大小写比较
//        System.out.println("输入:"+code);
//        System.out.println("正确"+codestr);
//        System.out.println(code == null || !code.equalsIgnoreCase(codestr));

        if (code == null || !code.equalsIgnoreCase(codestr)) {
            request.setAttribute("msg", "验证码错误");
            return Constants.FORWARD + "/login.jsp";
        }
        //3.调用业务逻辑判断账户密码
        UserService userService = new UserServiceImpl();
        User user = userService.login(username, password);

        //4.响应
        //user 等于null证明账号或者密码错误
        //user 不为null 但是user的状态是未激活状态
        if (user == null) {
            request.setAttribute("msg", "账号或者密码错误");
            return Constants.FORWARD + "/login.jsp";
        }
        if (user.getUstatus().equals(Constants.USER_NOT_ACTIVE)) {
            request.setAttribute("msg", "账号未激活!");
            return Constants.FORWARD + "/login.jsp";
        }
        //把用户放在共享域session中
        session.setAttribute("loginUser", user);

        //判断是否勾选自动登录
        if (auto == null) {
            //没有勾选
            //将本地浏览器的存储的cookie清空
            Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
            cookie.setPath("/");//将 Cookie 的路径设置为根路径,表示该 Cookie 对于整个网站都是可见的
            cookie.setMaxAge(0);//最大存活时间设置为 0
            response.addCookie(cookie);
        } else {
            String content = username + Constants.FLAG + password;
            content = Base64Utils.encode(content);
            //自动登录数据库存储2周
            Cookie cookie = new Cookie(Constants.AUTO_NAME, content);
            cookie.setPath("/");
            cookie.setMaxAge(14 * 24 * 60 * 60);
            response.addCookie(cookie);
        }

        return Constants.REDIRECT + "/index.jsp";
    }

    /**
     * 注销登录!清空数据!跳转到登录页面
     *
     * @param request
     * @param response
     * @return
     */
    public String logOut(HttpServletRequest request, HttpServletResponse response) {
        //1.清空session中用户数据
        HttpSession session = request.getSession();
        session.removeAttribute("loginUser");

        //2.清空和覆盖cooki存储的自动登录
        Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
        cookie.setPath("/");
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        //3.转发到登录页面
        request.setAttribute("msg", "注销登录成功");
        return  Constants.FORWARD + "/login.jsp";
    }

}

UserDao.java

package com.itqf.dao;


import com.itqf.entity.User;

import java.sql.SQLException;

/**
 * 负责用户模块数据库访问的接口
 */
public interface UserDao {
    /**
     * 根据用户名查询用户是否存在
     * @param username 查询的条件
     * @return 返回对应的用户数据
     */
    User  selectUserByUname(String username) throws SQLException;

    /**
     * 插入用户数据
     * @param user
     * @return
     * @throws
     */
    int insertUser(User user) throws SQLException;

    /**
     * 根据 激活码code 返回 User
     * @param code
     * @return
     */
    User selectUserByCode(String code) throws SQLException;

    /**
     * 激活更新数据
     * @param uid
     * @return
     */
    int updataStatusByid(int uid) throws SQLException;



}

UserDaoImpl.java

package com.itqf.dao.impl;

import com.itqf.dao.UserDao;
import com.itqf.entity.User;
import com.itqf.utils.C3P0Utils;
import com.itqf.utils.Constants;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

/**
 * 数据库访问实现类
 */
public class UserDaoImpl implements UserDao {
    @Override
    public User selectUserByUname(String username) throws SQLException {
        //1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        //2.执行SQL语句
        String sql = "select u_id as uid , u_name as username , u_password as upassword" +
                ", u_sex as usex , u_status as ustatus , u_code as code , u_email as email " +
                ", u_role as urole from user where u_name = ?";
        User user = queryRunner.query(sql,new BeanHandler<User>(User.class),username); //将查询结果映射到一个Java对象中

        return user;
    }

    @Override
    public int insertUser(User user) throws SQLException {
        //1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        //2.执行SQL语句 插入数据
        String sql = "insert into user (u_name,u_password,u_sex,u_status," +
                "u_code,u_email,u_role) value (?,?,?,?,?,?,?)";

        int rows = queryRunner.update(sql, user.getUsername(), user.getUpassword(), user.getUsex(),
                user.getUstatus(), user.getCode(), user.getEmail(), user.getUrole());
        return rows;

    }

    @Override
    public User selectUserByCode(String code) throws SQLException {
        //1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        //2.执行SQL语句
        String sql = "select u_id as uid , u_name as username , u_password as upassword" +
                ", u_sex as usex , u_status as ustatus , u_code as code , u_email as email " +
                ", u_role as urole from user where u_code = ?";
        User user = queryRunner.query(sql,new BeanHandler<User>(User.class),code); //将查询结果映射到一个Java对象中

        return user;
    }

    @Override
    public int updataStatusByid(int uid) throws SQLException {
        //1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
        String sql = "update user set u_status = ? where u_id = ?";

        int row = queryRunner.update(sql, Constants.USER_ACTIVE, uid);
        return row;
    }
}

User.java

package com.itqf.entity;

import java.io.Serializable;
/**
 * 对应数据库的用户表
 */
public class User implements Serializable {
    private static  final long serialVersionUID = 1L;

    private int uid; //用户ID
    private String username;  //对应的是数据库的uname字段 用户账号
    private String upassword; //密码
    private String usex; //性别
    private String ustatus; //用户的激活状态 0 未激活 1 激活
    private String code; //邮箱激活码
    private String email; //对应的是数据库的uemail字段 邮箱
    private int urole; //用户 0 管理员 1

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", username='" + username + '\'' +
                ", upassword='" + upassword + '\'' +
                ", usex='" + usex + '\'' +
                ", ustatus='" + ustatus + '\'' +
                ", code='" + code + '\'' +
                ", email='" + email + '\'' +
                ", urole=" + urole +
                '}';
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUpassword() {
        return upassword;
    }

    public void setUpassword(String upassword) {
        this.upassword = upassword;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }

    public String getUstatus() {
        return ustatus;
    }

    public void setUstatus(String ustatus) {
        this.ustatus = ustatus;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getUrole() {
        return urole;
    }

    public void setUrole(int urole) {
        this.urole = urole;
    }
}

UserService.java

package com.itqf.service;


import com.itqf.entity.User;

import java.sql.SQLException;

/**
 * 用户模块对应的业务逻辑接口类
 */
public interface UserService {
    /**
     * 检测用户名是够存在
     * @param username 被检测的用户名
     * @return boolean true存在 false不存在
     */
    boolean checkedUser(String username) throws SQLException;

    /**
     * 注册的业务逻辑
     * @param user
     * @return 插入数据影响的行数
     */
    int registerUser(User user) throws SQLException;

    /**
     * 激活方法
     * @param code 根据激活码进行激活
     * @return 三个状态 0激活失败 1激活成功 2已经激活
     */
    int activeUser(String code) throws SQLException;

    /**
     * 登录业务
     * @param username
     * @param password
     * @return
     */
    User login(String username,String password) throws SQLException;
}


UserServiceImpl.java

package com.itqf.service.impl;

import com.itqf.dao.UserDao;
import com.itqf.dao.impl.UserDaoImpl;
import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.utils.Constants;
import com.itqf.utils.EmailUtils;
import com.itqf.utils.MD5Utils;

import java.sql.SQLException;

public class UserServiceImpl implements UserService {

    /**
     * 验证注册用户名是否可用
     * @param username 被检测的用户名
     * @return
     * @throws SQLException
     */
    @Override
    public boolean checkedUser(String username) throws SQLException {
        //1.创建dao访问对象
        UserDao userDao = new UserDaoImpl();
        //2.执行结果
        User user = userDao.selectUserByUname(username);
        //3.处理返回值
        if (user != null) {
            return true;
        }
        return false;
    }

    /**
     * 用户注册逻辑
     * @param user
     * @return
     * @throws SQLException
     */
    @Override
    public int registerUser(User user) throws SQLException {

        //1.用户保存到数据库
        UserDao userDao = new UserDaoImpl();

        int row = userDao.insertUser(user);

        //2.发送一封邮件
        EmailUtils.sendEmail(user);
        return row;
    }

    /**
     * 激活
     * @param code 根据激活码进行激活
     * @return
     * @throws SQLException
     */
    @Override
    public int activeUser(String code) throws SQLException {
        UserDao userDao = new UserDaoImpl();
        //1.根据激活码查找用户
        User user =userDao.selectUserByCode(code);
        if (user==null){
            return  Constants.ACTIVE_FAIL;//0激活失败
        }
        //2.判断用户是否激活
        if(user.getUstatus().equals(Constants.USER_ACTIVE)){
            return Constants.ACTIVE_ALREADY;
        }
        //3.进行激活操作
        int i =userDao.updataStatusByid(user.getUid());
        if(i>0){
            return Constants.ACTIVE_SUCCESS;
        }
        return Constants.ACTIVE_FAIL;
    }

    /**
     * 登录业务
     * @param username
     * @param password
     * @return
     */
    @Override
    public User login(String username, String password) throws SQLException {
        //1.需要密码用md5处理
        String md5password = MD5Utils.md5(password);

        //2.根据用户名查找用户
        UserDao userDao = new UserDaoImpl();
        User user = userDao.selectUserByUname(username);

        if (user != null && user.getUpassword().equals(md5password)) {
            return user;
        }

        return null;
    }
}

完整报告与代码下载

下载链接

https://download.csdn.net/download/weixin_66397563/87977577

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
很抱歉,由于这个项目需要涉及到很多的技术和模块,我无法在这里提供完整的代码。但是,我可以给您提供一些基本的代码框架和思路,供您参考。 1. 项目结构 在这个项目中,您可以按照以下结构来组织您的代码: ``` - app.py # 主程序入口 - templates/ # 前端页面模板 - static/ # 静态文件,如CSS、JS等 - models.py # 数据库模型定义 - utils.py # 工具函数 - config.py # 配置文件 ``` 2. 主程序入口 在主程序入口`app.py`中,您需要引入相应的模块和框架,如Flask、NLTK、MySQLdb等,然后根据用户的请求,调用相应的函数进行处理。以下是一个简单的代码示例: ```python from flask import Flask, request, render_template import nltk import MySQLdb from utils import * app = Flask(__name__) app.config.from_object('config') db = MySQLdb.connect(host=app.config['DB_HOST'], user=app.config['DB_USER'], password=app.config['DB_PASSWORD'], db=app.config['DB_DATABASE'], charset=app.config['DB_CHARSET']) cursor = db.cursor() @app.route('/') def index(): return render_template('index.html') @app.route('/search', methods=['POST']) def search(): keyword = request.form['keyword'] results = search_products(keyword) return render_template('search.html', results=results) @app.route('/product/<int:product_id>') def product_detail(product_id): product = get_product(product_id) return render_template('product_detail.html', product=product) if __name__ == '__main__': app.run() ``` 在这个示例代码中,我们引入了Flask框架、NLTK库和MySQLdb模块,然后定义了三个路由函数,分别处理首页、搜索和商品详情页的请求。在这里,我们使用了一些工具函数,如`search_products`和`get_product`,用于从数据库中获取相应的商品数据。 3. 数据库模型定义 在`models.py`中,您需要定义相应的数据库模型,包括用户信息、商品信息、交易记录等。以下是一个简单的代码示例: ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) email = db.Column(db.String(50), nullable=False) password = db.Column(db.String(50), nullable=False) class Product(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) brand = db.Column(db.String(50), nullable=False) price = db.Column(db.Float, nullable=False) category = db.Column(db.String(50), nullable=False) class Transaction(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False) quantity = db.Column(db.Integer, nullable=False) total_price = db.Column(db.Float, nullable=False) timestamp = db.Column(db.DateTime, nullable=False) ``` 在这个示例代码中,我们使用了Flask-MySQLdb扩展来连接MySQL数据库,并定义了三个模型,分别对应用户、商品和交易记录。 4. 工具函数 在`utils.py`中,您需要定义一些工具函数,用于处理用户的请求和业务逻辑。以下是一个简单的代码示例: ```python import nltk from models import * def search_products(keyword): products = Product.query.filter(Product.name.like('%{}%'.format(keyword))).all() return products def get_product(product_id): product = Product.query.filter_by(id=product_id).first() return product ``` 在这个示例代码中,我们定义了两个工具函数,分别用于搜索商品和获取商品详情。在这里,我们使用了NLTK库来进行自然语言处理和关键词提取。 5. 配置文件 在`config.py`中,您需要定义一些配置参数,如数据库连接参数、调试模式等。以下是一个简单的代码示例: ```python DEBUG = True DB_HOST = 'localhost' DB_USER = 'root' DB_PASSWORD = 'password' DB_DATABASE = 'myshop' DB_CHARSET = 'utf8mb4' ``` 在这个示例代码中,我们定义了调试模式为True,并指定了MySQL数据库的连接参数。 总之,这只是一个简单的代码框架和思路,您需要根据具体的业务需求和技术栈来进行相应的修改和调整。希望这个示例能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汐ya~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值