Javaweb + MVC 实现企业人员管理系统全过程记录(配项目所有代码及数据库文件)

 

前言:因为研究生入学任务需要做一个企业人员管理系统,那就做呗。。。

项目及数据文件下载地址:https://download.csdn.net/download/qq_39410381/11546527

最终效果展示如下图:

管理员登录,界面如下:

 管理员输入账号和密码,进入主页面,如下图:

 管理员根据需求添加数据,(这里以部门为例,点击信息添加中部门添加),如下图:

添加完信息后,管理员可查看所有数据,(这里以部门为例),点击信息展示中的部门展示,如下图:

 管理员可根据需求在每条记录右边更改信息,更改状态。

期间遇到的问题以及解决方案记录如下:

报错:HttpServlet cannot be resolved to a type 
解决:将tomcat包下的lib文件下的servlet-api.jar复制到WEB-INF下的lib文件夹中,即可解决

报错:插入数据到数据库中,中文会变为问号
解决:在数据库连接配置时,url后面加上 ?useUnicode=true&characterEncoding=UTF-8

报错:javax.servlet.jsp.JspException cannot be resolved to a type
解决:在解决了第一个问题基础上,再将tomcat包下的lib文件下的jsp-api.jar复制到WEB-INF下的lib文件夹中,即可解决


第一部分(项目设计&数据库设计):

数据库设计:

管理员表:编号、账号、密码、状态

部门表:编号、名称、部门经理、描述、状态

职称表:编号、名称、基本工资、房补、职务补助、状态

职工表:编号、姓名、性别、出生日期、籍贯、部门、职称、状态

项目设计:非常简单,就是管理员对职工进行增删改查,职工表有部门表和职称表两个外键


第二部分(环境搭建):

①下载jdk,我下的是java9,之后就是百度配置环境变量

②下载tomcat,这个最简单,能启动就算成功

③下载ecplise,然后配置jdk和tomcat,有点复杂,耐心百度吧

④下载mysql数据库和管理工具,我用的是5.7,管理工具是workbench

最终能通过ecplise启动一个页面,打出hello world,环境就算成功了


第三部分(干活):

一、创建数据库

数据库名为 citel_4

建表

CREATE TABLE `citel_4`.`admins` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `account` VARCHAR(45) NULL,
  `password` VARCHAR(45) NULL,
  `status` INT NULL,
  PRIMARY KEY (`id`));
CREATE TABLE `citel_4`.`departments` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `manager` VARCHAR(45) NULL,
  `description` VARCHAR(45) NULL,
  `status` INT NULL,
  PRIMARY KEY (`id`));
CREATE TABLE `citel_4`.`titles` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `base_wage` VARCHAR(45) NULL,
  `room_supply` VARCHAR(45) NULL,
  `job_supply` VARCHAR(45) NULL,
  `status` INT NULL,
  PRIMARY KEY (`id`));
CREATE TABLE `citel_4`.`staffs` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `sex` CHAR(1) NULL,
  `birth` VARCHAR(45) NULL,
  `home` VARCHAR(45) NULL,
  `department` INT NULL,
  `title` INT NULL,
  `status` INT NULL,
  PRIMARY KEY (`id`));

 添加外键

ALTER TABLE `citel_4`.`staffs` 
ADD INDEX `fk_department_idx` (`department` ASC);
;
ALTER TABLE `citel_4`.`staffs` 
ADD CONSTRAINT `fk_department`
  FOREIGN KEY (`department`)
  REFERENCES `citel_4`.`departments` (`id`)
  ON DELETE CASCADE
  ON UPDATE CASCADE;

ALTER TABLE `citel_4`.`staffs` 
ADD INDEX `fk_title_idx` (`title` ASC);
;
ALTER TABLE `citel_4`.`staffs` 
ADD CONSTRAINT `fk_title`
  FOREIGN KEY (`title`)
  REFERENCES `citel_4`.`titles` (`id`)
  ON DELETE CASCADE
  ON UPDATE CASCADE;

二、搭建项目

打开ecplise,右键->new->Dynamic Web Project,项目名为InformationManageProject

最终我的项目最终结构如下图:

 

找模板、改模板

由于目标只是对后台几个表的增删改查,所以找了一个后台管理模板。

由于数据库中没有数据,所有先改数据添加的模板,由于三个表添加类似,以部门表为例述说,如图:

前端展示改好,修改web.xml

  <servlet>
  	<servlet-name>DepartmentServlet</servlet-name>
  	<servlet-class>com.sky.servlets.DepartmentServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>DepartmentServlet</servlet-name>
  	<url-pattern>*.department</url-pattern>
  </servlet-mapping>

三、实现逻辑(全部以部门表为例)

3.1 添加数据

因为刚创建数据库,什么数据都没有,所以第一步就是添加数据。

修改前端的添加表单

<form action="<%=request.getContextPath() %>/add.department" method="post">
    <input type="hidden" name="operation" value="add">
        <div class="form-group">
            <label>部门名称</label>
            <input type="text" name="name" class="form-control" placeholder="请输入部门名称">
        </div>
        <div class="form-group">
            <label>部门经理</label>
            <input type="text" name="manager" class="form-control" placeholder=" 请输入该部门经理">
        </div>
        <div class="form-group">
            <label>部门描述</label>
            <input type="text" name="description" class="form-control" placeholder="请描述该部门">
        </div>
        <div class="checkbox">
            <label>
		        <input type="checkbox"> <a href="#">同意遵守用户协议</a> 
		    </label>
        </div>
        <button type="submit" class="btn btn-primary btn-flat m-b-30 m-t-30">添加</button>
</form>

后端 DepartmentServlet

public class DepartmentServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	DepartmentDao departmentDao = new DepartmentDaoImpl();
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("utf-8");
		
		String operation = req.getParameter("operation");
		if (operation.equals("query")) {
			//test
			int id = Integer.parseInt(req.getParameter("id"));
			Departments dept = departmentDao.selectOneById(id);
			
			System.out.println("data: " + dept);
		}else if (operation.equals("add")) {
			String name = req.getParameter("name");
			String manager = req.getParameter("manager");
			String description = req.getParameter("description");
			
			boolean res = departmentDao.addOneDepartment(new Departments(name, manager, description));
			if (res) {
				//添加成功
				req.getRequestDispatcher("/index.jsp").forward(req, resp);
			} else {
				//添加失败
				req.getRequestDispatcher("/error.jsp").forward(req, resp);
			}
			
		}
	}
}

之后是Dao层(DepartmentDao)及其实现(DepartmentDaoImpl)

public interface DepartmentDao {
	
	//按ID查询部门
	Departments selectOneById(Integer id);
	
	//添加部门
	boolean addOneDepartment(Departments dept);
}
public class DepartmentDaoImpl implements DepartmentDao{
	
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	Boolean result = false;
	Departments dept = null;

	@Override
	public Departments selectOneById(Integer id) {
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("SELECT * FROM citel_4.departments where id = ?;");
			ps.setInt(1, id);
			
			rs = ps.executeQuery();
			
			if(rs.next()){
				int _id = rs.getInt(1);
				String _name = rs.getString(2);
				String _manager = rs.getString(3);
				String _description = rs.getString(4);
				int _status = rs.getInt(5);
				
				dept = new Departments(_id, _name, _manager, _description, _status);
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return dept;
	}

	@Override
	public boolean addOneDepartment(Departments dept) {
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("insert into departments values (0, ?, ?, ?, 1);");
			ps.setString(1, dept.getName());
			ps.setString(2, dept.getManager());
			ps.setString(3, dept.getDescription());
			
			result = ps.executeUpdate()>0?true:false;
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return result;
	}
	
	
}

最终添加部门效果:

3.2 展示数据

终于有了数据,接下来,当然是展示数据啦。

按照过程,第一个是主页面的部门展示的url,后面带了一个参数,表示查询全部

<li><a class="sidebar-sub-toggle"><i class="ti-layout-grid4-alt"></i> 信息展示 <span class="sidebar-collapse-icon ti-angle-down"></span></a>
    <ul>
        <li><a href="<%=request.getContextPath() %>/queryAll.department?operation=queryAll">部门展示</a></li>
        <li><a href="table-basic.html">职位展示</a></li>
        <li><a href="table-basic.html">员工展示</a></li>
    </ul>
</li>

 接下来,处理servlet

public class DepartmentServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	DepartmentDao departmentDao = new DepartmentDaoImpl();
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

                ...//省略,前面写过,后面代码一样

		}else if (operation.equals("queryAll")) {
			List<Departments> depts = departmentDao.selectAllDepartments();
			
			req.setAttribute("departments", depts);
			//请求转发跳转
			req.getRequestDispatcher("/show-department.jsp").forward(req, resp);
		}
	}
}

 然后是Dao层代码逻辑

public interface DepartmentDao {
	
        ...
	
	//查询所有部门
	List<Departments> selectAllDepartments();
}

 

public class DepartmentDaoImpl implements DepartmentDao{
	
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	Boolean result = false;
	Departments dept = null;
	List<Departments> list = null;

        ...    

	@Override
	public List<Departments> selectAllDepartments() {
		
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("SELECT * FROM departments where status=1 or status=2;");
			
			rs = ps.executeQuery();
			list = new ArrayList<Departments>();
			while (rs.next()) {
				int id = rs.getInt(1);
				String name = rs.getString(2);
				String manager = rs.getString(3);
				String description = rs.getString(4);
				int status = rs.getInt(5);
				
				Departments dept = new Departments(id, name, manager, description, status);
				list.add(dept);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return list;
	}
	
	
}

好了,到现在为止,数据获取到了,最后就是把它展示出来,所以修改部门展示页面,这里不用前面,使用EL表达式,先导入了jstl的jar包,然后构建路径,最后在页面头部写上 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 就可以了。展示页面代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="com.sky.pojo.Departments"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">

...

<table class="table table-hover ">
    <thead>
        <tr>
            <th>#</th>
            <th>名称</th>
            <th>经理</th>
            <th>描述</th>
            <th>状态</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach items="${departments}" var="department">
             <tr> 
				 <td scope="row">${department.id}</td> 
				 <td>${department.name}</td> 
				 <td>${department.manager}</td> 
                 <td>${department.description}</td>
				 <c:if test="${department.status eq '1' }">
					 <td><span class="badge badge-success">在用</span></td>
					 <td>停用</td>
				 </c:if>
				 <c:if test="${department.status eq '2' }">
					 <td><span class="badge badge-danger">停用</span></td>
					 <td>启用</td>
				 </c:if>
			 </tr>
         </c:forEach>
     </tbody>
</table>

...

 

最终效果图:

3.3 修改数据 

要想修改数据,首先出现的问题就是回显已有数据,当然在这之前,得在每个数据加上修改按钮,如下:

 这里在每个链接上接上了对应的id,依然使用的是EL表达式

<c:if test="${department.status eq '1' }">
	<td><span class="badge badge-success">在用</span></td>
	<td>
        <a href="${pageContext.request.contextPath}/download.department?operation=download&id=${department.id}">停用</a>/
		<a href="${pageContext.request.contextPath}/update.department?operation=showOne&id=${department.id}">修改</a>/
		<a href=" ${pageContext.request.contextPath}/delete.department?operation=delete&id=${department.id}">删除</a>
	</td>
</c:if>
<c:if test="${department.status eq '2' }">
	<td><span class="badge badge-danger">停用</span></td>
	<td>
		<a href="${pageContext.request.contextPath}/upload.department?operation=upload&id=${department.id}">启用</a>/
		<a href="${pageContext.request.contextPath}/showOne.department?operation=showOne&id=${department.id}">修改</a>/
		<a href="${pageContext.request.contextPath}/delete.department?operation=delete&id=${department.id}">删除</a>
	</td>
</c:if>

点击修改后,跳转到servlet,

public class DepartmentServlet extends HttpServlet {
    
        ...
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("utf-8");
		
		String operation = req.getParameter("operation");
		if (operation.equals("showOne")) {
			int id = Integer.parseInt(req.getParameter("id"));
			Departments dept = departmentDao.selectOneById(id);
			
			req.setAttribute("department", dept);
			req.getRequestDispatcher("/update-department.jsp").forward(req, resp);
		}
		
        ...        

	}
}

servlet调用Dao方法
 

public interface DepartmentDao {
	
	//按ID查询部门
	Departments selectOneById(Integer id);
	
        ...
}
public class DepartmentDaoImpl implements DepartmentDao{
	
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	Boolean result = false;
	Departments dept = null;
	List<Departments> list = null;

	@Override
	public Departments selectOneById(Integer id) {
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("SELECT * FROM departments where id = ?;");
			ps.setInt(1, id);
			
			rs = ps.executeQuery();
			
			if(rs.next()){
				int _id = rs.getInt(1);
				String _name = rs.getString(2);
				String _manager = rs.getString(3);
				String _description = rs.getString(4);
				int _status = rs.getInt(5);
				
				dept = new Departments(_id, _name, _manager, _description, _status);
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return dept;
	}
        ...
}

最终,回显数据成功,如下图 update-department.jsp

 该页面的表单改写如下:

<form action="<%=request.getContextPath() %>/update.department" method="post">
    <input type="hidden" name="operation" value="update">
    <input type="hidden" name="id" value="${department.id}">
    <input type="hidden" name="status" value="${department.status}">
    <div class="form-group">
        <label>部门名称</label>
        <input type="text" name="name" class="form-control" placeholder="请输入部门名称" value="${department.name }">
    </div>
    <div class="form-group">
        <label>部门经理</label>
        <input type="text" name="manager" class="form-control" placeholder=" 请输入该部门经理" value="${department.manager }">
    </div>
    <div class="form-group">
        <label>部门描述</label>
        <input type="text" name="description" class="form-control" placeholder="请描述该部门" value="${department.description }">
    </div>
    <button type="submit" class="btn btn-primary btn-flat m-b-30 m-t-30">确认修改</button>
</form>

然后传达修改servlet,

public class DepartmentServlet extends HttpServlet {
	    ...
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
            ...

		}else if (operation.equals("update")) { 	//修改
			int id = Integer.parseInt(req.getParameter("id"));
			String name = req.getParameter("name");
			String manager = req.getParameter("manager");
			String description = req.getParameter("description");
			int status = Integer.parseInt(req.getParameter("status"));
			
			Departments dept = new Departments(id, name, manager, description, status);
			
			res = departmentDao.updateDepartment(dept);
			if (res) {
				//修改成功
				resp.sendRedirect(req.getContextPath()+"/queryAll.department?operation=queryAll");
			} else {
				//修改失败
				req.getRequestDispatcher("/error.jsp").forward(req, resp);
			}
		}
	}
}

servlet调用底层Dao和实现

public interface DepartmentDao {
	
        ...
	
	//修改部门信息
	boolean updateDepartment(Departments newDeptDepartments);
}
public class DepartmentDaoImpl implements DepartmentDao{
	
	    ...

	@Override
	public boolean updateDepartment(Departments newDeptDepartments) {
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("update citel_4.departments set name=?, manager=?, description=?,status=? where id=?;");
			ps.setString(1, newDeptDepartments.getName());
			ps.setString(2, newDeptDepartments.getManager());
			ps.setString(3, newDeptDepartments.getDescription());
			ps.setInt(4, newDeptDepartments.getStatus());
			ps.setInt(5, newDeptDepartments.getId());
			
			result = ps.executeUpdate()>0?true:false;
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return result;
	}
	
	
}

最后修改成功后,跳转到展示所有的部门,至此修改结束。

3.4 删除数据

最后一步,删除数据相对更简单了,因为是假删除,只是更改状态就可以了,这里和同样是更改状态的“启用”和“停用”一直说了。和前面一样,前端代码如下:

<c:if test="${department.status eq '1' }">
	<td><span class="badge badge-success">在用</span></td>
	<td>
        <a href="${pageContext.request.contextPath}/download.department?operation=download&id=${department.id}">停用</a>/
		<a href="${pageContext.request.contextPath}/update.department?operation=showOne&id=${department.id}">修改</a>/
		<a href=" ${pageContext.request.contextPath}/delete.department?operation=delete&id=${department.id}">删除</a>
	</td>
</c:if>
<c:if test="${department.status eq '2' }">
	<td><span class="badge badge-danger">停用</span></td>
	<td>
		<a href="${pageContext.request.contextPath}/upload.department?operation=upload&id=${department.id}">启用</a>/
		<a href="${pageContext.request.contextPath}/showOne.department?operation=showOne&id=${department.id}">修改</a>/
		<a href="${pageContext.request.contextPath}/delete.department?operation=delete&id=${department.id}">删除</a>
	</td>
</c:if>

 发送相应的请求到servlet,代码如下:

public class DepartmentServlet extends HttpServlet {
	    ...
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		    ...
		}else if (operation.equals("upload")) {		//启用
			int id = Integer.parseInt(req.getParameter("id"));
			res = departmentDao.updatedepartmentStatus(id, 1);
			if (res) {
				resp.sendRedirect(req.getContextPath()+"/queryAll.department?operation=queryAll");
			} else {
				req.getRequestDispatcher("/error.jsp").forward(req, resp);
			}
		}else if (operation.equals("download")) {		//停用
			int id = Integer.parseInt(req.getParameter("id"));
			res = departmentDao.updatedepartmentStatus(id, 2);
			if (res) {
				resp.sendRedirect(req.getContextPath()+"/queryAll.department?operation=queryAll");
			} else {
				req.getRequestDispatcher("/error.jsp").forward(req, resp);
			}
		}else if (operation.equals("delete")) {		//删除
			int id = Integer.parseInt(req.getParameter("id"));
			res = departmentDao.updatedepartmentStatus(id, 0);
			if (res) {
				resp.sendRedirect(req.getContextPath()+"/queryAll.department?operation=queryAll");
			} else {
				req.getRequestDispatcher("/error.jsp").forward(req, resp);
			}
		}
	}
}

由上面的代码可以看出,它们公用了一个方法,改变部门的状态,其中:0:删除;1:在用;2:停用

public interface DepartmentDao {
	
        ...
	
	//修改部门状态
	boolean updatedepartmentStatus(Integer id,Integer status);
	
}
public class DepartmentDaoImpl implements DepartmentDao{

        ...

	@Override
	public boolean updatedepartmentStatus(Integer id,Integer status) {
		try {
			conn = DBUtils.getConnection();
			ps = conn.prepareStatement("update departments set status=? where id=?;");
			ps.setInt(1, status);
			ps.setInt(2, id);
			
			result = ps.executeUpdate()>0?true:false;
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, ps, conn);
		}
		return result;
	}
	
	
}

至此,关于部门的增删改查操作全部结束,而对于职称表和员工表都是一样的,只是在员工表多了两个外键,前端可使用axios,先去获取所有的部门和职称,然后让用户选择即可。

        ...
    <script src="//cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
    
    <script type="text/javascript">
    function getAllDepartments(){
    	axios.get("InformationManageProject/queryAll.department?operation=queryAllByAjax").then((response)=> {
    		dataList = response.data;
    		//console.log(dataList);
    		var root = document.getElementById('depts');
			for(var i=0;i<dataList.length;i++){
				var op = document.createElement("option");
				op.setAttribute("value", dataList[i].id);
				var node=document.createTextNode(dataList[i].name);//创建文本节点
				op.appendChild(node);
				
				root.appendChild(op);
			} 
    	});
    }

    getAllDepartments();
    </script>
        ...

而后端这边主要是把数据转换为json,这里我使用的方式是借助Gson.jar包实现转换。

    else if (operation.equals("queryAllByAjax")) {
			
	    resp.setContentType("application/json; charset=utf-8"); 
            req.setCharacterEncoding("UTF-8");
            PrintWriter out = resp.getWriter();
            
            List<Departments> depts = departmentDao.selectAllDepartments();
            
            //list转换为json
            Gson gson = new Gson(); 
            String str = gson.toJson(depts);
            
			
	    out.print(str);
	    out.flush();
	    out.close();
	}
}

最终效果图如下:

 大致的内容就是这么多,还有一些小的细节,太琐碎了,没写出来(比如防止在session放置管理员信息,每个页面判断一下是否按照正常登录后进入的,否则跳回到登录页面)。好了,暑假作业完成。


关于下载资源后如何启动,我在我的windows系统上试了下,大致如下:

1. 数据库:新建一个mysql数据库,数据库名为 citel_4 ,执行database.sql文件
2. 导入项目:打开eclipse,File -> Import -> General -> Existing Projects into Workspace -> Browse -> 选择InformationManageProject -> 选择文件夹 -> Finish
NB. 注意修改数据库连接配置信息:db-config.properties
3.1 绑定Tomcat:Window -> Preference -> Server -> Runtime Environments -> Add -> 选择Apache Tomcat v9.0 -> Apply and Close
3.2 打开Servers窗口:Window -> Show View -> Servers
3.3 在Servers窗口中:右键 -> Add and Remove -> 选择选择InformationManageProject -> Add -> Finish
4. 启动项目:在Servers窗口中选中Tomcat v9.0 -> 点击右边绿色按钮 (之后可在控制台看见启动信息)
5. 在浏览器访问项目:eg: http://localhost:8080/InformationManageProject/

  • 12
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值