Javaweb的网络投票系统的设计与实现

目的与意义

原始的投票管理基本上是人工操作,效率低下,缺乏方便性,网上投票管理系统运用计算机和其他附加设备,不再需要手工操作,基本上是全自动化,能够节省人力,大大的提高了效率。使投票变得简单快捷。能够在极短的时间内总结出所需调查人的意见结果。大大提高了投票的质量,随着网络技术的发展,网上投票系统的作用将会越来越大。并且在投票的过程中网上投票系统对网络的要求也越来越高。网络在线投票系统还可以用于一些科学研究,因为它可以使调查过程更加客观、全面,数据结果的参考价值和使用率更加显著,而且可以直接看到统计系数,不需要过多的转化,在线网络调查。

总体设计

为了满足用户的投票需求,系统必须提供一个简单、高效和多功能的投票方式。用户可以就热点问题或主题选择一个或多个投票点,但每天只能投票一次,而且不能随意更改。如果他们觉得其中一个选项不符合他们的喜好,他们可以改变原来的选择并再次投票。简而言之,投票管理系统是为了协调不同功能模块的工作[12]。这些模块可以进行组合,以满足投票管理系统的业务要求,并提供用户体验以及投票管理。界面模块、数据库模块、投票统计模块三部分组成

基于JavaWeb的网络投票系统的设计与实现主要包括前端页面设计、后端数据处理和数据库设计。系统总体架构包括三层:表现层、业务逻辑层和数据访问层。

表现层:使用HTML、CSS和JavaScript实现用户界面,通过浏览器向服务器发送请求并接收响应,实现页面跳转和交互效果。

业务逻辑层:使用Java编程语言实现,负责处理用户请求、验证用户身份、处理业务逻辑和生成动态页面。该层包括处理用户投票请求、投票结果统计、候选人信息管理等功能。

数据访问层:使用JDBC或ORM框架连接数据库,负责与数据库进行交互。该层包括候选人信息的增删改查、用户投票记录的存储和查询等功能。

功能模块设计

管理员功能:管理员可以对调查资料进行管理,公布或更改调查主题及选择,增加调查主题(主题名称、主题类型、开始时间);结束时间和标题)、浏览主题、更改主题、移除主题。管理员也可以对查询选项进行管理。管理员还可以对查询选项进行管理。管理员还可以对查询选项进行管理。管理员可以增加选项(指定一个选项,选定一个主题)、查看、修改、删除、管理查询选项。

系统用户功能模块:在线投票模块、后台管理模块等。其中后台管理模块是本系统的中心模块。后台管理模块包括:增加普通投票、增加图片投票、查看投票等模块。其中增加普通投票和增加图片投票模块包括投票类型和投票标题设定、投票选项设定。

用户资料管理:管理员可以添加用户(编辑用户名,密码,性别,状态)、申请、修改、删除用户信息,即添加、删除、编辑。

查看投票、参与投票功能:投票题目显示功能,查看已录入数据库中的话题,包括话题类型,话题的状态是否为热门话题;参与投票功能,选择对应的话题进行投票,并查看结果;防止短时间内刷票的功能,同一问题同一用户在规定时间内不能反复的刷票。

后台管理模块:要想往投票系统里录入投票题目与选项,必须要以管理员的身份登录后台管理模块。当点击本系统前台首页的“进入后台”选项后进入后台登录页面,该登录页面是进入系统后的第一个页面,设计理念是清晰、简洁,当输入管理员用户名和密码后提交后就进入了后台管理页面。

在线投票模块:经过之前后台管理模块的投票标题的录入过程,现在就可以参加投

票了,点击前台首页的“进入投票”选项进入前台投票页面。在此页面有已经生成录入数据库中的投票标题,每个标题后面有所属的话题类型,以及投票操作选项,查看结果选项。当点击某个标题后面的“投票”选项,即可进入该标题的投票页面选择相应的选项,选择结束后,点击该页面的“投票”按钮提交本次投票,同时可以生成结果,显示在查看结果页面中[15]。查看结果又分为两种方式,一种是提交某次投票后,弹出一个对话框显示“投票成功!是否显示结果? !”当点击“确定”就可以进入查看结果页面查看饼状结果图,或者返回至前台投票页面点击某个标题后的“结果”按钮同样也可以进入查看投票结果页面查看结果。

用户管理系统设计

系统提供用户注册和管理员新增用户两个入口,默认情况下,普通用户进入系统通过需要通过自己手动注册账号,然后投票等操作;

主要包含下面步骤:

收集用户信息:通过表单收集用户信息,如用户名、电子邮件地址、密码、性别、出生日期等。

检查输入:对用户输入进行验证,确保用户输入的信息符合规范,如用户名、电子邮件地址是否已被注册等。

判断用户是否存在:对用户输入用户名已经存在的,提示用户已经存在。

判断用户类型是否允许注册:如果用户类型为admin类型则不允许注册,提示用户类型不允许注册

用户登录:如果用户注册成功,就可以使用他们刚刚创建的帐户信息登录网站。

//校验表单数据 
function validatw_add_form() {
	//1.拿到要校验的数据,使用正则表达式
	var username=$("#username_add_input").val();
	var regName=/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/; 
     if(!regName.test(username)){
    	 //alert("用户名可以是2-5位中文或者6-16位英文和数子的组合");
    	 show_validate_msg("#username_add_input","error","用户名可以是2-5位中文或者6-16位英文和数子的组合");
    	 /* $("#username_add_input").parent().addClass("has-error");
    	 $("#username_add_input").next("span").text("用户名可以是2-5位中文或者6-16位 英文和数子的组合"); */
    	 return false;
     }else{
    	 show_validate_msg("#username_add_input","success","");
    	 /* $("#username_add_input").parent().addClass("has-success");
    	 $("#username_add_input").next("span").text(""); */
     };
    //2、校验邮箱
    var email=$("#email_add_input").val();
    var regEmail=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
    if(!regEmail.test(email)){
    	//alert("邮箱格式不正确");
//应该清空这个元素之前的样式
    	show_validate_msg("#email_add_input","error","邮箱格式不正确");
    	/* $("#email_add_input").parent().addClass("has-error");
    	$("#email_add_input").next("span").text("邮箱格式不正确"); */
    	return false;
    }else{
    	show_validate_msg("#email_add_input","success","");
    	/*  $("#email_add_input").parent().addClass("has-success");
    	 $("#email_add_input").next("span").text(""); */
    };
    return true;
}

//显示校验结果的提示信息
function show_validate_msg(ele,status,msg) {
	//清除发当前元素的校验状态
	$(ele).parent().removeClass("has-success has-error");
	$(ele).next("span").text("");
	if("success"==status){
		$(ele).parent().addClass("has-success");
		$(ele).next("span").text(msg);
		
	}else if("error"==status){
		$(ele).parent().addClass("has-error");
		$(ele).next("span").text(msg);
	}
}
注册和登录后端校验逻辑
@Pattern(regexp="(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})"
    		,message="用户名必须是6-12位数字和字母的组合或者2-5为中文")
 private String userName;

    @Pattern(regexp="^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$",message="邮箱格式不正确")
    private String email;

    @NotBlank(message = "用户名密码不能为空")
    private String password;
用户或者管理员登录

@PostMapping(value = "/userlogin")
public String userlogin(@Param("user") User user, HttpServletRequest request, HttpSession session) {
    try {
        Result result = RequestUtils.checkParam(user);
        //校验参数
        if (!result.isSuccess()) {
            request.setAttribute("message", String.format("参数校验失败 code:[%s],msg:[%s]", result.getErrorCode(), result.getErrorMsg()));
            return "login";
        }
        User userlogin = userService.userlogin(user);
        if (userlogin == null) {
            request.setAttribute("message", "用户名或密码不正确");
            return "login";
        } else {
            if (TypeEnum.USER.getCode().equals(userlogin.getType())) {
                session.setAttribute("user", userlogin);
                return "user";
            } else if (TypeEnum.ADMIN.getCode().equals(userlogin.getType())) {
                session.setAttribute("user", userlogin);
                return "admin";
            } else {
                String msg = String.format("用户类型校验失败 username:[%s],type:[%s]", userlogin.getUsername(), userlogin.getType());
                log.info(msg);
                request.setAttribute("message", "用户类型校验失败");
                return "login";
            }

        }
   } catch (Exception e) {
        String msg = String.format(" login error username:[%s],type:[%s]", user.getUsername(), user.getType());
        log.error(msg, e);
        request.setAttribute("message", "系统异常,请联系管理员");
        return "login";
    }
}
用户注册逻辑
 /**
     * 用户注册  不允许注册管理员类型
     *
     * @param user
     * @param request
     * @return
     */
    @PostMapping(value = "/userregister")
    public String userregister(@Param("user") User user, HttpServletRequest request) {
        try {
            Result result = RequestUtils.checkParam(user);
            //校验参数
            if (!result.isSuccess()) {
                request.setAttribute("message", String.format("参数校验失败 code:[%s],msg:[%s]", result.getErrorCode(), result.getErrorMsg()));
            }
            User user1 = userService.query(user.getUsername());
            if (user1 == null) {
                if (TypeEnum.USER.getCode().equals(user.getType())) {
                    Integer userregister = userService.userregister(user);
                    request.setAttribute("msg", "注册成功请返回登录");
                    request.setAttribute("args", userregister);  } else {
                    request.setAttribute("msg", "用户类型不允许注册");
                }
            } else {
                request.setAttribute("msg", "该用户已经存在");
            }

        } catch (Exception e) {
            log.error(String.format("用户注册失败 username:[%s]", user.getUsername()), e);
            request.setAttribute("msg", "系统异常,请联系管理员");
        }
        return "register";
    }

用户资料管理功能设计

用户资料管理功能是指对管理员可以添加用户(编辑用户名,密码,性别,状态)、申请、修改、删除用户信息,即添加、删除、编辑。

通过用户资料管理功能,可以提高用户体验,增强系统用户黏性,同时也为管理人员提供了更好的运营支持。

主要步骤:

管理员登录系统,查看用户列表,如果有需要则对用户信息进行添加、删除、编辑等修改

管理员新增用户功能
   /**
     * 新增用户信息  管理员
     *
     * @param session
     * @return
     */
    @GetMapping(value = "/addUser")
    public String addUser(@Param("user") User user, HttpSession session, HttpServletRequest request) {
        try {
            User userlogin = (User) session.getAttribute("user");
            if (TypeEnum.ADMIN.getCode().equals(userlogin.getType())) {
                // 调用用户注册方法 进行注册
                userController.userregister(user, request);
            } else {    
request.setAttribute("msg", "只允许管理员进行新增用户");
            }
        } catch (Exception e) {
            log.error(String.format("获取登录用户类型失败 "), e);
        }
        return "addUser";
}
管理员获取用户详情
/**
     * 获取用户信息  管理员
     *
     * @return
     */
    @GetMapping(value = "/getUser")
    public void getUser(@Param("id") String id, HttpServletRequest request) {
        try {
            User user = userService.queryById(id);
            request.setAttribute("user", user);
        } catch (Exception e) {
            log.error(String.format("获取用户信息失败 "), e);
        }
    }
管理员删除用户
/**
     * 获取用户信息  管理员
     *
     * @return
     */
    @GetMapping(value = "/deleteUser")
    public void deleteUser(@Param("id") String id, HttpServletRequest request) {
        try {
            User user = userService.queryById(id);
            if (user == null) {
                request.setAttribute("msg", "用户不存在");
                return;     
}
            userService.delete(id);
            request.setAttribute("msg", "用户删除成功");
        } catch (Exception e) {
            log.error(String.format("用户删除失败 "), e);
        }
    }

投票系统设计

话题设计模块:

该模块通过新增票和删除票,提供给用户进行操作,包括是否已经投过票、设置话题是否为热门话题,方便管理查看功能;使用spring的事务机制保证数据的正常,公共的校验模块。

从而构建一个复杂而又高效的系统,既需要满足基本的操作流程,又可以通过实时监控来提高效率,而且还可以根据实际情况及时调整参与者,以确保参与者可以得到及时、准确、可靠地参与,从而使得该系统变得越来越成熟。应该尽可能采取更有效的措施来实现目标,并且强调设计的关键作用,以确保流程的公平合理。

用户进行投票
  /**
     * 增加票
     *
     * @param votenumber
     * @return
     */
    @PostMapping(value = "addVote")
    @ResponseBody
    @Transactional
    public Integer addVote(@Param("votenumber") Votenumber votenumber, HttpServletRequest request) {
        try {

            Result result = RequestUtils.checkParam(votenumber);
            //校验参数
            if (!result.isSuccess()) {
                request.setAttribute("message", String.format("参数校验失败 code:[%s],msg:[%s]", result.getErrorCode(), result.getErrorMsg()));
                return 0;
            }
// 判断话题是否存在
            Subject subject = subjectService.selectSubject(votenumber.getSubjectId());
            if (subject == null || subject.getState() == SubjectEnum.DELETE.getCode()) {
                request.setAttribute("message", "添加失败,不存在该话题");
                return 0;
            }
            //根据话题id 和 投票id  判断是否是唯一的一票
            Votenumber selectvoteonly = voteService.selectvoteonly(votenumber);
            if (selectvoteonly != null) {
                request.setAttribute("message", "已经新增过票了,请勿新增票");
                return 0;
            } else {
                // 如果不是则新增票,则新增数据
                Votenumber votenumber1 = new Votenumber();
                votenumber1.setSubjectId(votenumber.getSubjectId());
                votenumber1.setUserid(votenumber.getUserid());
                votenumber1.setState(votenumber.getState());
                Integer addvote = voteService.addvote(votenumber1);

                //更新票数
                subject.setCountVote(subject.getCountVote() + 1);
                // 设置为热门
                if (subject.getCountVote() > 100 && !subject.getState().equals(SubjectEnum.POPULAR.getCode())) {
                    subject.setState(SubjectEnum.POPULAR.getCode());
                }
                subjectService.updateSubject(subject);
                request.setAttribute("message", "新增票成功");
                return addvote;
            }   
} catch (Exception e) {
            request.setAttribute("message", "系统异常");
            log.error(String.format("新增票失败 subjectId:[%s],v:[%s]", votenumber.getSubjectId(), votenumber.getUserid()), e);
            return 0;
        }
}
用户取消投票
/**
     * 取消票
     *
     * @param votenumber
     * @return
     */
    @PostMapping(value = "deleteVote")
    @ResponseBody
    @Transactional
    public Integer deleteVote(@Param("votenumber") Votenumber votenumber, HttpServletRequest request) {
        try {

            Result result = RequestUtils.checkParam(votenumber);
            //校验参数
            if (!result.isSuccess()) {
                request.setAttribute("message", String.format("参数校验失败 code:[%s],msg:[%s]", result.getErrorCode(), result.getErrorMsg()));
                return 0;
            }

            // 判断话题是否存在
  Subject subject = subjectService.selectSubject(votenumber.getSubjectId());
            if (subject == null || subject.getState() == SubjectEnum.DELETE.getCode()) {
                request.setAttribute("message", "删除失败,不存在该话题");
                return 0;
            }
            //根据话题id 和 投票id  判断是否是唯一的一票
            Votenumber selectvoteonly = voteService.selectvoteonly(votenumber);
            if (selectvoteonly == null) {
                request.setAttribute("message", "该票不存在");
                return 0;
            } else {
                // 如果不是则新增票,则新增数据
                Votenumber votenumber1 = new Votenumber();
                votenumber1.setSubjectId(votenumber.getSubjectId());
                votenumber1.setUserid(votenumber.getUserid());
                Integer addvote = voteService.deletevote(votenumber1);

                //更新票数
                subject.setCountVote(subject.getCountVote() - 1);
                // 更新为正常
                if (subject.getCountVote() <= 100 && !subject.getState().equals(SubjectEnum.NOMAL.getCode())) {
                    subject.setState(SubjectEnum.NOMAL.getCode());
                }
                subjectService.updateSubject(subject);
                request.setAttribute("message", "删除票成功");
                return addvote;
            }
        } catch (Exception e) {
    request.setAttribute("message", "系统异常");
            log.error(String.format("删除票失败 subjectId:[%s],v:[%s]", votenumber.getSubjectId(), votenumber.getUserid()), e);
            return 0;
        }
    }

话题管理设计

话题管理模块是一种可帮助管理员管理话题、和修改话题的软件系统;查看话题活跃度等功能

该功能包括:

话题管理即添加、删除、编辑。

通过话题管理功能,可以提高用户体验,增强系统话题黏性,同时也为管理人员提供了更好的运营支持。

获取当前 话题 所有人员详情
/**
     * 获取当前 话题 所有人员详情
     *
     * @param subjectId 话题id
     * @return
     */
    @GetMapping(value = "/censusVote")
    @ResponseBody
    public Map<Integer, List<Votenumber>> censusVote(@Param("subjectId") Integer subjectId, HttpServletRequest request) {
        try {

            Subject subject = subjectService.selectSubject(subjectId);
            if (subject == null) {
                request.setAttribute("message", "未查询到话题");
                return null;
            }
            Votenumber votenumber = new Votenumber();
            votenumber.setSubjectId(subject.getId());
            List<Votenumber> votenumbers = voteService.censusstate(votenumber);

            Map<Integer, List<Votenumber>> result = new HashMap<>();
            result.put(subject.getId(), votenumbers);
    return result;
        } catch (Exception e) {
            request.setAttribute("message", "系统异常");
            log.error(String.format("获取话题的人员信息失败 subjectId:[%s]", subjectId), e);
            return null;
        }
}
新增主题
 /**
     * 新增主题
     *
     * @param subject
     * @param request
     * @return
     */
    @PostMapping(value = "/addSubject")
    public void addSubject(@Param("subject") Subject subject, HttpServletRequest request) {
        try {
            Result result = RequestUtils.checkParam(subject);
            //校验参数
            if (!result.isSuccess()) {
                request.setAttribute("message", String.format("参数校验失败 code:[%s],msg:[%s]", result.getErrorCode(), result.getErrorMsg()));
                return ;
            }
            Subject subject1 = subjectService.selectSubject(subject.getId());
            if (subject1 == null) {
                subjectService.addSubject(subject);
 request.setAttribute("msg", "该话题新增成功");
            } else {
                request.setAttribute("msg", "该话题已经存在");
            }

        } catch (Exception e) {
            log.error(String.format("新增话题失败 username:[%s]", subject.getSubjectName()), e);
            request.setAttribute("msg", "系统异常,请联系管理员");
        }
        return ;
    }
上传话题 图片 并返回 url
/**
     * 上传话题 图片 并返回 url
     *
     * @param file
     * @param model
     * @param request
     * @return
     */
    @PostMapping(value = "/fileUpload")
    public String fileUpload(@RequestParam(value = "filename") MultipartFile file, Model model, HttpServletRequest request) {
        try {
            if (file.isEmpty()) {
                request.setAttribute("msg", "上传文件为空");
                log.error("上传文件为空 fileName:" + file.getName());
                return "condidateall";
            }  String fileName = file.getOriginalFilename();  // 文件名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));  // 后缀名
            String filePath = "D://IDEAworkspace//vote//src//main//resources//static//image//"; // 上传后的路径
            fileName = UUID.randomUUID() + suffixName; // 新文件名
            File dest = new File(filePath + fileName);
            //判断父目录是否存在
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            file.transferTo(dest);
            String filename = "/image/" + fileName;
            model.addAttribute("filename", filename);

        } catch (Exception e) {
            log.error("系统异常 fileName:" + file.getName(), e);
        }
        return "condidateall";
    }

登录和管理员拦截器

功能用于校验用户是否登录和是否是管理员操作;

设计拦截器会在用户试图访问用户资源时截取该请求,检查用户是否已经登录并具有相应的管理员权限。如果用户未登录或管理员权限,则登录拦截器将重定向用户到登录页面或显示错误消息。登录拦截器使用会话管理来跟踪用户会话。

登录拦截器
@Order(Ordered.HIGHEST_PRECEDENCE)
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;

    /**
     * 登录校验
     *
     * @param request
  * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String url = request.getRequestURI();
        // 无需校验登录
        if (checkNotLogin(url)) {
            return true;
        }
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            request.setAttribute("msg", "账号未登录,请登录");
            request.getRequestDispatcher("WEB-INF/templates/login.html ").forward(request, response);
            return false;
        }
        user = userService.query(user.getUsername());
        if (user == null) {
            request.setAttribute("msg", String.format("用户类型校验失败 username:[%s],type:[%s]", user.getUsername(), user.getType()));
            request.getRequestDispatcher("WEB-INF/templates/login.html").forward(request, response);
            return false;
        }     return true;
    }

    private boolean checkNotLogin(String url) {
        return url.indexOf("/login") >= 0 || url.indexOf("/userregister") >= 0;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

    }
}
 管理员拦截器
@Slf4j
@Order()
public class AdminInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
  String url = request.getRequestURI();
        // admin账号进行校验,并且登录用户必须admin类型
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (url.indexOf("/admin") >= 0 && !TypeEnum.ADMIN.getCode().equals(user.getType())) {
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于JavaWeb的办公系统设计实现涉及以下几个方面:系统需求分析、数据设计、系统架构设计、前后端开发以及系统集成测试等。 首先,系统需求分析是确立系统功能和用户需求的过程。通过与用户的沟通和调研,明确系统所需的功能模块,如员工管理、请假管理、报销管理等。在需求分析的基础上,可以编写用例图、用户故事等文档,为后续的开发工作提供指导。 其次,数据设计设计系统的数据存储结构和表之间的关系。可以使用关系数据库管理系统(RDBMS)如MySQL、Oracle等。根据系统的实际需求,设计相应的表和表之间的关联关系,同时考虑数据的完整性和一致性。 接下来,进行系统架构设计,包括前端和后端的架构设计。前端可以使用HTML、CSS和JavaScript进行页面的布局和样式设计,同时使用框架如Bootstrap、jQuery等提高开发效率。后端可以选择使用Java的框架如Spring、SpringMVC和MyBatis等进行业务逻辑的处理和数据库操作。 然后,进行前后端开发。前端开发人员根据需求和设计文档进行页面的开发和调试。后端开发人员实现系统中的各个功能模块的业务逻辑,包括接收前端请求、处理数据、与数据库交互等。 最后,进行系统集成测试,包括单元测试和整体功能测试。单元测试是对系统中的各个功能模块进行独立测试,保证每个功能模块的正确性。整体功能测试是测试整个系统的各个功能模块之间的协同工作,以验证系统是否满足需求。 综上所述,基于JavaWeb的办公系统设计实现需要进行系统需求分析、数据设计、系统架构设计、前后端开发以及系统集成测试等工作,以确保系统的稳定性和功能完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

踩踩踩从踩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值