小金库
配套视频地址:https://www.bilibili.com/video/BV1gQ4y1r7ah
资源下载地址:https://download.csdn.net/download/qq_24330181/85624846
数据库设计
创建数据库
DROP DATABASE IF EXISTS `xiaojinku`;
CREATE DATABASE `xiaojinku` DEFAULT CHARACTER SET utf8 ;
USE `xiaojinku`;
select database();
创建收入表
DROP TABLE IF EXISTS `tb_income`;
CREATE TABLE `tb_income` (
`in_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '收入编号',
`in_title` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
`in_money` decimal(10, 2) NULL DEFAULT NULL COMMENT '收入金额',
`in_mode` int UNSIGNED NULL DEFAULT NULL COMMENT '收款方式',
`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
`u_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '用户ID',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` timestamp NULL DEFAULT NULL COMMENT '修改时间',
`create_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人ID',
`modified_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人ID',
`deleted` tinyint UNSIGNED NULL DEFAULT NULL COMMENT '逻辑删除标识(0、否 1、是)',
PRIMARY KEY (`in_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建支出表
DROP TABLE IF EXISTS `tb_paid`;
CREATE TABLE `tb_paid` (
`pay_id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,
`pay_title` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题',
`pay_money` decimal(10, 2) NULL DEFAULT NULL COMMENT '支出金额',
`pay_mode` int(0) UNSIGNED NULL DEFAULT NULL COMMENT '支付方式',
`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
`u_id` bigint(0) UNSIGNED NULL DEFAULT NULL COMMENT '用户ID',
`create_time` timestamp(0) NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` timestamp(0) NULL DEFAULT NULL COMMENT '修改时间',
`create_account_id` bigint(0) UNSIGNED NULL DEFAULT NULL COMMENT '创建人ID',
`modified_account_id` bigint(0) UNSIGNED NULL DEFAULT NULL COMMENT '修改人ID',
`deleted` tinyint(0) UNSIGNED NULL DEFAULT NULL COMMENT '逻辑删除标识(0、否 1、是)',
PRIMARY KEY (`pay_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建收支方式表
DROP TABLE IF EXISTS `tb_mode`;
CREATE TABLE `tb_mode` (
`mode_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '收支方式ID',
`mode_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收支方式名称',
PRIMARY KEY (`mode_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建资源表
DROP TABLE IF EXISTS `tb_resource`;
CREATE TABLE `tb_resource` (
`resouce_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '资源ID',
`parent_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '父ID',
`title` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单名称',
`icon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单图标',
`href` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '链接',
`target` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '_self' COMMENT '链接打开方式',
`sort` int UNSIGNED NULL DEFAULT NULL COMMENT '菜单排序',
`status` int NULL DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注信息',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` timestamp NULL DEFAULT NULL COMMENT '修改时间',
`create_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人ID',
`modified_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人ID',
`deleted` tinyint UNSIGNED NULL DEFAULT NULL COMMENT '逻辑删除标识(0、否 1、是)',
PRIMARY KEY (`resouce_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建角色表
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`role_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`role_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色名称',
`remark` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` datetime NULL DEFAULT NULL COMMENT '修改时间',
`create_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人',
`modified_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人',
`deleted` tinyint UNSIGNED NULL DEFAULT 0 COMMENT '逻辑删除标识(0、否 1、是)',
PRIMARY KEY (`role_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建角色资源关联表
DROP TABLE IF EXISTS `tb_role_resource`;
CREATE TABLE `tb_role_resource` (
`role_id` bigint UNSIGNED NOT NULL COMMENT '角色id',
`resource_id` bigint UNSIGNED NOT NULL COMMENT '资源id',
PRIMARY KEY (`role_id`, `resource_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建用户表
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`u_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`u_account` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户账号',
`u_password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户密码',
`u_nickname` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
`head_sculpture` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户头像',
`u_realname` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户真实姓名',
`u_id_card` varchar(18) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户身份证号码',
`u_mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户手机号',
`role_id` bigint UNSIGNED NOT NULL DEFAULT 2 COMMENT '角色ID',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`modified_time` timestamp NULL DEFAULT NULL COMMENT '修改时间',
`create_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人ID',
`modified_account_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人ID',
`deleted` tinyint UNSIGNED NULL DEFAULT NULL COMMENT '逻辑删除标识(0、否 1、是)',
PRIMARY KEY (`u_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
插入数据
角色数据
INSERT INTO `xiaojinku`.`tb_role` (`role_id`, `role_name`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (1, '管理员', '管理员', '2019-03-15 16:51:37', '2019-03-15 16:51:37', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_role` (`role_id`, `role_name`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (2, '使用者', '普通用户', '2019-03-15 16:51:37', '2019-03-15 16:51:37', 1, 1, 0);
用户数据
INSERT INTO `xiaojinku`.`tb_user` (`u_id`, `u_account`, `u_password`, `u_nickname`, `head_sculpture`, `u_realname`, `u_id_card`, `u_mobile`, `role_id`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (1, 'admin', '123456', '管理员', NULL, '管理员', NULL, NULL, 1, '2021-09-09 06:06:06', '2021-09-09 06:06:06', 1, 1, 0);
资源数据
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (1, 0, '系统管理', 'layui-icon layui-icon-set', NULL, '_self', 1, 1, NULL, '2021-09-09 02:58:25', '2021-09-09 02:58:25', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (2, 0, '统计报表', 'layui-icon layui-icon-chart', NULL, '_self', 2, 1, NULL, '2021-09-09 02:59:54', '2021-09-09 02:59:54', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (3, 0, '收入管理', 'layui-icon layui-icon-rmb', NULL, '_self', 3, 1, NULL, '2021-09-09 03:00:38', '2021-09-09 03:00:38', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (4, 0, '支出管理', 'layui-icon layui-icon-cart', NULL, '_self', 4, 1, NULL, '2021-09-09 03:01:46', '2021-09-09 03:01:46', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (5, 1, '用户管理', 'layui-icon layui-icon-user', '/user.html', '_blank', 1, 1, NULL, '2021-09-09 03:04:47', '2021-09-09 03:04:47', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (6, 3, '收入明细', 'layui-icon layui-icon-table', '/income.html', '_blank', 1, 1, NULL, '2021-09-09 03:07:56', '2021-09-09 03:08:01', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (7, 4, '支出明细', 'layui-icon layui-icon-table', '/pay.html', '_blank', 1, 1, NULL, '2021-09-09 03:09:14', '2021-09-09 03:09:14', 1, 1, 0);
INSERT INTO `xiaojinku`.`tb_resource` (`resouce_id`, `parent_id`, `title`, `icon`, `href`, `target`, `sort`, `status`, `remark`, `create_time`, `modified_time`, `create_account_id`, `modified_account_id`, `deleted`) VALUES (8, 2, '收支报表', 'layui-icon layui-icon-table', '/balance.html', '_blank', 1, 1, NULL, '2021-09-09 03:10:56', '2021-09-09 03:10:56', 1, 1, 0);
角色资源关联数据
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 1);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 2);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 3);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 4);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 5);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 6);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (1, 7);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 2);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 3);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 4);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 5);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 6);
INSERT INTO `xiaojinku`.`tb_role_resource` (`role_id`, `resource_id`) VALUES (2, 7);
收支方式数据
INSERT INTO `tb_mode` (`mode_id`,`mode_name`) VALUES (1, '现金');
INSERT INTO `tb_mode` (`mode_id`,`mode_name`) VALUES (2, '支付宝');
INSERT INTO `tb_mode` (`mode_id`,`mode_name`) VALUES (3, '微信');
INSERT INTO `tb_mode` (`mode_id`,`mode_name`) VALUES (4, '银行卡');
INSERT INTO `tb_mode` (`mode_id`,`mode_name`) VALUES (5, '信用卡');
开发流程
- 新建项目
- 导入依赖
- 导入工具类
- 根据数据库生成pojo类
- 导入Mybatis核心配置文件
- 编写持久层接口
- 编写映射配置文件
- 编写业务层接口
- 编写业务层接口实现类
- 测试
- 编写REST接口
- POSTMAN测试
- 编写页面
新建项目
倒入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jdyxk</groupId>
<artifactId>xiaojinku</artifactId>
<version>1.0-SNAPSHOT</version>
<name>xiaojinku</name>
<packaging>war</packaging>
<properties>
<jdk.version>17</jdk.version>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.test.skip>true</maven.test.skip>
<commons-io.version>2.11.0</commons-io.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<c3p0.version>0.9.5.5</c3p0.version>
<druid.version>1.2.6</druid.version>
<fastjson.version>1.2.78</fastjson.version>
<hutool-all.version>5.7.10</hutool-all.version>
<junit.version>5.7.2</junit.version>
<java-testdata-generator.version>1.1.2</java-testdata-generator.version>
<javax.servlet.version>4.0.1</javax.servlet.version>
<jakarta.servlet.version>5.0.0</jakarta.servlet.version>
<jackson.version>2.12.5</jackson.version>
<jersey.version>2.34</jersey.version>
<lombok.version>1.18.20</lombok.version>
<mybatis.version>3.5.7</mybatis.version>
<mysql.version>8.0.26</mysql.version>
<pagehelper.version>5.2.1</pagehelper.version>
<spring.version>5.3.9</spring.version>
<kotlin.version>1.5.30</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<!--junit-jupiter-api-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--junit-jupiter-engine-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--java-testdata-generator-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>java-testdata-generator</artifactId>
<version>${java-testdata-generator.version}</version>
</dependency>
<!--hutool-all-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool-all.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- 设置编译字符编码 -->
<encoding>UTF-8</encoding>
<!-- 设置编译jdk版本 -->
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<!-- 编译级别 -->
<!-- 打包的时候跳过测试junit begin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<!-- tomcat7插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>6633</port>
<path>/lhz</path>
<uriEncoding>UTF-8</uriEncoding>
<!-- tomcat热部署 -->
<username>admin</username>
<password>admin</password>
<url>http://192.168.18.65:8080/manager/text</url>
</configuration>
</plugin>
<!-- jetty插件 -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.43.v20210629</version>
<configuration>
<webApp>
<contextPath>/lhz</contextPath>
</webApp>
<httpConnector>
<port>6633</port>
</httpConnector>
</configuration>
</plugin>
</plugins>
</build>
</project>
导入工具类
从之前的项目导入commons包
根据数据库生成pojo类
收入类Income
package com.jdyxk.xiaojinku.pojo;
import com.jdyxk.commons.bean.BaseBean;
import java.time.LocalDateTime;
public class Income extends BaseBean {
private static final long serialVersionUID = -7427056136058996958L;
/**
* 收入ID
*/
private long inId;
/**
* 收入标题
*/
private String inTitle;
/**
* 收入金额
*/
private double inMoney;
/**
* 收款方式
*/
private long inMode;
/**
* 备注
*/
private String remark;
public Income() {
}
public Income(String inTitle, double inMoney, long inMode, String remark) {
this.inTitle = inTitle;
this.inMoney = inMoney;
this.inMode = inMode;
this.remark = remark;
}
public Income(long inId, String inTitle, double inMoney, long inMode, String remark) {
this.inId = inId;
this.inTitle = inTitle;
this.inMoney = inMoney;
this.inMode = inMode;
this.remark = remark;
}
public Income(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, String inTitle, double inMoney, long inMode, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.inTitle = inTitle;
this.inMoney = inMoney;
this.inMode = inMode;
this.remark = remark;
}
public Income(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long inId, String inTitle, double inMoney, long inMode, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.inId = inId;
this.inTitle = inTitle;
this.inMoney = inMoney;
this.inMode = inMode;
this.remark = remark;
}
public long getInId() {
return inId;
}
public void setInId(long inId) {
this.inId = inId;
}
public String getInTitle() {
return inTitle;
}
public void setInTitle(String inTitle) {
this.inTitle = inTitle;
}
public double getInMoney() {
return inMoney;
}
public void setInMoney(double inMoney) {
this.inMoney = inMoney;
}
public long getInMode() {
return inMode;
}
public void setInMode(long inMode) {
this.inMode = inMode;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
支出类Paid
package com.jdyxk.xiaojinku.pojo;
import com.jdyxk.commons.bean.BaseBean;
import java.time.LocalDateTime;
public class Paid extends BaseBean {
private static final long serialVersionUID = 7252360803387247980L;
/**
* 支出ID
*/
private long payId;
/**
* 支出标题
*/
private String payTitle;
/**
* 付款金额
*/
private double payMoney;
/**
* 付款方式
*/
private long payMode;
/**
* 备注
*/
private String remark;
/**
* 用户ID
*/
private long uId;
public Paid() {
}
public Paid(String payTitle, double payMoney, long payMode, String remark, long uId) {
this.payTitle = payTitle;
this.payMoney = payMoney;
this.payMode = payMode;
this.remark = remark;
this.uId = uId;
}
public Paid(long payId, String payTitle, double payMoney, long payMode, String remark, long uId) {
this.payId = payId;
this.payTitle = payTitle;
this.payMoney = payMoney;
this.payMode = payMode;
this.remark = remark;
this.uId = uId;
}
public Paid(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, String payTitle, double payMoney, long payMode, String remark, long uId) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.payTitle = payTitle;
this.payMoney = payMoney;
this.payMode = payMode;
this.remark = remark;
this.uId = uId;
}
public Paid(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long payId, String payTitle, double payMoney, long payMode, String remark, long uId) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.payId = payId;
this.payTitle = payTitle;
this.payMoney = payMoney;
this.payMode = payMode;
this.remark = remark;
this.uId = uId;
}
public long getPayId() {
return payId;
}
public void setPayId(long payId) {
this.payId = payId;
}
public String getPayTitle() {
return payTitle;
}
public void setPayTitle(String payTitle) {
this.payTitle = payTitle;
}
public double getPayMoney() {
return payMoney;
}
public void setPayMoney(double payMoney) {
this.payMoney = payMoney;
}
public long getPayMode() {
return payMode;
}
public void setPayMode(long payMode) {
this.payMode = payMode;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public long getuId() {
return uId;
}
public void setuId(long uId) {
this.uId = uId;
}
}
收支方式类TbMode
package com.jdyxk.xiaojinku.pojo;
import java.io.Serializable;
public class TbMode implements Serializable {
private static final long serialVersionUID = 4370817402583042740L;
/**
* 收支方式ID
*/
private long modeId;
/**
* 收支方式名称
*/
private String modeName;
public TbMode() {
}
public TbMode(String modeName) {
this.modeName = modeName;
}
public TbMode(long modeId, String modeName) {
this.modeId = modeId;
this.modeName = modeName;
}
public long getModeId() {
return modeId;
}
public void setModeId(long modeId) {
this.modeId = modeId;
}
public String getModeName() {
return modeName;
}
public void setModeName(String modeName) {
this.modeName = modeName;
}
}
资源类Resource
package com.jdyxk.xiaojinku.pojo;
import com.jdyxk.commons.bean.BaseBean;
import java.time.LocalDateTime;
public class Resource extends BaseBean {
private static final long serialVersionUID = 7533789308521929296L;
/**
* 资源ID
*/
private long resouceId;
/**
* 父亲ID
*/
private long parentId;
/**
* 菜单名称
*/
private String title;
/**
* 菜单图标
*/
private String icon;
/**
* 链接
*/
private String href;
/**
* 链接打开方式
*/
private String target;
/**
* 排序
*/
private long sort;
/**
* 状态 (0禁用 1启用)
*/
private long status;
/**
* 备注
*/
private String remark;
public Resource() {
}
public Resource(long parentId, String title, String icon, String href, String target, long sort, long status, String remark) {
this.parentId = parentId;
this.title = title;
this.icon = icon;
this.href = href;
this.target = target;
this.sort = sort;
this.status = status;
this.remark = remark;
}
public Resource(long resouceId, long parentId, String title, String icon, String href, String target, long sort, long status, String remark) {
this.resouceId = resouceId;
this.parentId = parentId;
this.title = title;
this.icon = icon;
this.href = href;
this.target = target;
this.sort = sort;
this.status = status;
this.remark = remark;
}
public Resource(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long parentId, String title, String icon, String href, String target, long sort, long status, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.parentId = parentId;
this.title = title;
this.icon = icon;
this.href = href;
this.target = target;
this.sort = sort;
this.status = status;
this.remark = remark;
}
public Resource(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long resouceId, long parentId, String title, String icon, String href, String target, long sort, long status, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.resouceId = resouceId;
this.parentId = parentId;
this.title = title;
this.icon = icon;
this.href = href;
this.target = target;
this.sort = sort;
this.status = status;
this.remark = remark;
}
public long getResouceId() {
return resouceId;
}
public void setResouceId(long resouceId) {
this.resouceId = resouceId;
}
public long getParentId() {
return parentId;
}
public void setParentId(long parentId) {
this.parentId = parentId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public long getSort() {
return sort;
}
public void setSort(long sort) {
this.sort = sort;
}
public long getStatus() {
return status;
}
public void setStatus(long status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
角色类Role
package com.jdyxk.xiaojinku.pojo;
import com.jdyxk.commons.bean.BaseBean;
import java.time.LocalDateTime;
public class Role extends BaseBean {
private static final long serialVersionUID = -3999451314479463795L;
/**
* 角色ID
*/
private long roleId;
/**
* 角色名称
*/
private String roleName;
/**
* 备注
*/
private String remark;
public Role() {
}
public Role(String roleName, String remark) {
this.roleName = roleName;
this.remark = remark;
}
public Role(long roleId, String roleName, String remark) {
this.roleId = roleId;
this.roleName = roleName;
this.remark = remark;
}
public Role(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, String roleName, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.roleName = roleName;
this.remark = remark;
}
public Role(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long roleId, String roleName, String remark) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.roleId = roleId;
this.roleName = roleName;
this.remark = remark;
}
public long getRoleId() {
return roleId;
}
public void setRoleId(long roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
角色资源关联类RoleResource
package com.jdyxk.xiaojinku.pojo;
import java.io.Serializable;
public class RoleResource implements Serializable {
private static final long serialVersionUID = -8979651404368559508L;
/**
* 角色ID
*/
private long roleId;
/**
* 资源ID
*/
private long resourceId;
public RoleResource() {
}
public RoleResource(long roleId, long resourceId) {
this.roleId = roleId;
this.resourceId = resourceId;
}
public long getRoleId() {
return roleId;
}
public void setRoleId(long roleId) {
this.roleId = roleId;
}
public long getResourceId() {
return resourceId;
}
public void setResourceId(long resourceId) {
this.resourceId = resourceId;
}
}
用户类User
package com.jdyxk.xiaojinku.pojo;
import com.jdyxk.commons.bean.BaseBean;
import java.time.LocalDateTime;
public class User extends BaseBean {
private static final long serialVersionUID = -9101171691965729598L;
/**
* 用户ID
*/
private long uId;
/**
* 用户账号
*/
private String uAccount;
/**
* 用户密码
*/
private String uPassword;
/**
* 用户昵称
*/
private String uNickname;
/**
* 用户头像
*/
private String headSculpture;
/**
* 用户真实姓名
*/
private String uRealname;
/**
* 用户身份证号
*/
private String uIdCard;
/**
* 用户手机号
*/
private String uMobile;
/**
* 角色ID
*/
private long roleId;
public User() {
}
public User(String uAccount, String uPassword) {
this.uAccount = uAccount;
this.uPassword = uPassword;
}
public User(String uAccount, String uPassword, String uNickname, String headSculpture, String uRealname, String uIdCard, String uMobile, long roleId) {
this.uAccount = uAccount;
this.uPassword = uPassword;
this.uNickname = uNickname;
this.headSculpture = headSculpture;
this.uRealname = uRealname;
this.uIdCard = uIdCard;
this.uMobile = uMobile;
this.roleId = roleId;
}
public User(long uId, String uAccount, String uPassword, String uNickname, String headSculpture, String uRealname, String uIdCard, String uMobile, long roleId) {
this.uId = uId;
this.uAccount = uAccount;
this.uPassword = uPassword;
this.uNickname = uNickname;
this.headSculpture = headSculpture;
this.uRealname = uRealname;
this.uIdCard = uIdCard;
this.uMobile = uMobile;
this.roleId = roleId;
}
public User(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, long uId, String uAccount, String uPassword, String uNickname, String headSculpture, String uRealname, String uIdCard, String uMobile, long roleId) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.uId = uId;
this.uAccount = uAccount;
this.uPassword = uPassword;
this.uNickname = uNickname;
this.headSculpture = headSculpture;
this.uRealname = uRealname;
this.uIdCard = uIdCard;
this.uMobile = uMobile;
this.roleId = roleId;
}
public User(LocalDateTime createTime, LocalDateTime modifiedTime, Long createAccountId, Long modifiedAccountId, Integer deleted, String uAccount, String uPassword, String uNickname, String headSculpture, String uRealname, String uIdCard, String uMobile, long roleId) {
super(createTime, modifiedTime, createAccountId, modifiedAccountId, deleted);
this.uAccount = uAccount;
this.uPassword = uPassword;
this.uNickname = uNickname;
this.headSculpture = headSculpture;
this.uRealname = uRealname;
this.uIdCard = uIdCard;
this.uMobile = uMobile;
this.roleId = roleId;
}
public long getuId() {
return uId;
}
public void setuId(long uId) {
this.uId = uId;
}
public String getuAccount() {
return uAccount;
}
public void setuAccount(String uAccount) {
this.uAccount = uAccount;
}
public String getuPassword() {
return uPassword;
}
public void setuPassword(String uPassword) {
this.uPassword = uPassword;
}
public String getuNickname() {
return uNickname;
}
public void setuNickname(String uNickname) {
this.uNickname = uNickname;
}
public String getHeadSculpture() {
return headSculpture;
}
public void setHeadSculpture(String headSculpture) {
this.headSculpture = headSculpture;
}
public String getuRealname() {
return uRealname;
}
public void setuRealname(String uRealname) {
this.uRealname = uRealname;
}
public String getuIdCard() {
return uIdCard;
}
public void setuIdCard(String uIdCard) {
this.uIdCard = uIdCard;
}
public String getuMobile() {
return uMobile;
}
public void setuMobile(String uMobile) {
this.uMobile = uMobile;
}
public long getRoleId() {
return roleId;
}
public void setRoleId(long roleId) {
this.roleId = roleId;
}
}
导入Mybatis核心配置文件
src/main/resources/mybatis/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 外部 properties 配置文件 -->
<properties resource="db.properties"/>
<settings>
<!--驼峰命名与下划线自动转换-->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!--log日志-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<typeAliases>
<!--
别名
type 类的完全限定名
alias 别名
-->
<!--<typeAlias alias="person" type="com.jdyxk.pojo.Person"/>-->
<package name="com.jdyxk.xiaojinku.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务类型 -->
<transactionManager type="JDBC"/>
<!-- 数据源 即数据库连接池 -->
<!--<dataSource type="POOLED">-->
<dataSource type="com.jdyxk.commons.datasource.druid.DruidDataSourceFactory">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.jdbcUrl}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--单独加载某个映射配置文件-->
<!--<mapper resource="com/jdyxk/mapper/PersonMapper.xml"/>-->
<!--加载某包下所有的映射配置文件-->
<package name="com.jdyxk.xiaojinku.mapper"/>
</mappers>
</configuration>
src/main/resources/db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///xiaojinku?useUnicode=true&characterEncoding=UTF8&useSSL=false&useServerPrepStmts=false&rewriteBatchedStatements=true&cachePrepStmts=true&allowMultiQueries=true&serverTimeZone=Aisa/Shanghai
jdbc.user=root
jdbc.password=123456
用户登录
用户登录持久层接口
package com.jdyxk.xiaojinku.mapper;
import com.jdyxk.xiaojinku.pojo.User;
/**
* @author 李昊哲
* @version 1.0
* @Description 用户持久层操作
* @createTime 2021/9/9 下午12:14
*/
public interface UserMapper {
/**
* 用户根据账号密码登录
* @param user 登录参数
* @return User信息
*/
User selectByAccountAndPassword(User user);
}
用户登录持久层映射配置文件
src/main/resources/com/jdyxk/xiaojinku/mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
mapper 映射配置
namespace 命名空间 对应接口的名字
-->
<mapper namespace="com.jdyxk.xiaojinku.mapper.UserMapper">
<!--
select 用于查询
id 与接口中方法的名字同名 即调用接口中方法的时候 该方法会找到该配置文件中对应的SQL
resultType 返回值数据类型
-->
<!--用户登录-->
<select id="selectByAccountAndPassword" parameterType="user" resultType="user">
SELECT `u_id`,`role_id`,`u_nickname`,`deleted` FROM `tb_user`
<where>
`deleted` = 0 and u_account = #{uAccount} and u_password = #{uPassword}
</where>
</select>
</mapper>
用户登录业务层接口
package com.jdyxk.xiaojinku.service;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.xiaojinku.pojo.User;
/**
* @author 李昊哲
* @version 1.0
* @Description 用户业务操作
* @createTime 2021/9/9 下午12:19
*/
public interface UserService {
/**
* 用户根据账号密码登录
*
* @param user 登录参数
* @return
*/
ResponseResult<User> loginByAccountAndPassword(User user);
}
用户登录业务层接口实现类
package com.jdyxk.xiaojinku.service.impl;
import com.jdyxk.commons.mybatis.MybatisUtil;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.commons.result.ResultCode;
import com.jdyxk.xiaojinku.mapper.UserMapper;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.UserService;
import org.apache.ibatis.session.SqlSession;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 上午10:38
*/
public class UserServiceImpl implements UserService {
@Override
public ResponseResult<User> loginByAccountAndPassword(User user) {
// 默认登录失败
ResponseResult<User> responseResult = new ResponseResult<>(ResultCode.LOGIN_FAILED.getCode(), ResultCode.LOGIN_FAILED.getMsg());
// 获取数据库连接
SqlSession sqlSession = MybatisUtil.openSqlSession();
// 获取持久层接口代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用持久层方法
user = userMapper.selectByAccountAndPassword(user);
// 归还数据库连接
MybatisUtil.close();
if (user != null) {
// 如果返回的user 不为空 则代码登录成功
// 封装放回数据
responseResult.setCode(ResultCode.SUCCESS.getCode());
responseResult.setMsg(ResultCode.SUCCESS.getMsg());
// 跳转地址
responseResult.setLocation("/app.do?methodName=toDataPage");
// 返回数据
responseResult.setData(user);
}
return responseResult;
}
}
用户登录业务层测试
package com.jdyxk.xiaojinku.service;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.impl.UserServiceImpl;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 上午10:48
*/
public class UserServiceRTest {
private static final UserService userService = new UserServiceImpl();
@Test
public void loginByAccountAndPassword() {
User user = new User("admin","123456");
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
switch (responseResult.getCode()) {
case "200":
System.out.println(responseResult.getData().getuNickname());
System.out.println(responseResult.getLocation());
break;
default:
System.out.println(responseResult.getMsg());
break;
}
}
}
用户登录数据接口
原始Servlet方式
package com.jdyxk.xiaojinku.controller;
/**
* @author 李昊哲
* @Description
* @version 1.0
* @createTime 2021/9/13 上午10:59
*/
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.commons.result.ResultCode;
import com.jdyxk.commons.string.StringUtil;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.UserService;
import com.jdyxk.xiaojinku.service.impl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "LoginController", value = "/LoginController")
public class LoginController extends HttpServlet {
private static final long serialVersionUID = 5288199692040985171L;
private static final UserService userService = new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 实例化ObjectMapper 便于就送转换
ObjectMapper objectMapper = new ObjectMapper();
// 防止post请求中文乱码
request.setCharacterEncoding("UTF-8");
// 处理响应数据中文乱码
response.setCharacterEncoding("UTF-8");
// 设置返回数据的MIME类型
// response.addHeader("Content-Type","application/json;charset=UTF-8");
response.setContentType("application/json;charset=UTF-8");
// 获取账号的值
String uAccount = request.getParameter("uAccount");
// 获取密码的值
String uPassword = request.getParameter("uPassword");
PrintWriter writer = response.getWriter();
if (StringUtil.isBlank(uAccount)) {
// 账号为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
// 将对象转换为json格式字符串
String json = objectMapper.writeValueAsString(responseResult);
// 将结果向用户发送
writer.println(json);
} else if (StringUtil.isBlank(uPassword)) {
// 密码为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
// 将对象转换为json格式字符串
String json = objectMapper.writeValueAsString(responseResult);
// 将结果向用户发送
writer.println(json);
} else {
// 封装请求参数
User user = new User(uAccount, uPassword);
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果向用户发送
writer.println(objectMapper.writeValueAsString(responseResult));
}
// 刷新缓存
writer.flush();
// 关闭输出流
writer.close();
}
}
POSTMAN测试登录
测试链接:http://localhost:6633/lhz/LoginController
contont-type: x-www-form-urlencoded
测试参数:
name | value |
---|---|
uAccount | admin |
uPassword | 123456 |
账号为空返回结果:
{
"code": "601",
"msg": "账号不能为空",
"location": null,
"token": null,
"data": null
}
密码为空返回结果:
{
"code": "602",
"msg": ",密码不能为空",
"location": null,
"token": null,
"data": null
}
返回失败结果:
{
"code": "10002",
"msg": "登录失败",
"location": "/login",
"token": null,
"data": null
}
返回成功结果:
{
"code": "200",
"msg": "操作成功",
"location": "/app.do?methodName=toDataPage",
"token": null,
"data": {
"createTime": null,
"modifiedTime": null,
"createAccountId": null,
"modifiedAccountId": null,
"deleted": 0,
"headSculpture": null,
"roleId": 1,
"uid": 1,
"uaccount": null,
"upassword": null,
"unickname": "管理员",
"urealname": null,
"uidCard": null,
"umobile": null
}
}
BaseServlet简化方式
package com.jdyxk.xiaojinku.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.commons.result.ResultCode;
import com.jdyxk.commons.servlet.BaseServlet;
import com.jdyxk.commons.string.StringUtil;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.UserService;
import com.jdyxk.xiaojinku.service.impl.UserServiceImpl;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 上午11:33
*/
@WebServlet(urlPatterns = "/user.do")
public class UserController extends BaseServlet {
private static final long serialVersionUID = -6435689556122295219L;
private static final UserService userService = new UserServiceImpl();
/**
* 用户登录
*
* @param request HttpServletRequest
* @param response HttpServletResponse
* @throws IOException IOException
*/
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取账号的值
String uAccount = request.getParameter("uAccount");
// 获取密码的值
String uPassword = request.getParameter("uPassword");
if (StringUtil.isBlank(uAccount)) {
// 账号为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
printJsonObject(response, responseResult);
} else if (StringUtil.isBlank(uPassword)) {
// 密码为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
printJsonObject(response, responseResult);
} else {
// 封装请求参数
User user = new User(uAccount, uPassword);
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果转换为json格式字符串向用户发送
printJsonObject(response, responseResult);
}
}
}
POSTMAN测试登录
测试链接:http://localhost:6633/lhz/user.do?methodName=loginByAccountAndPassword
contont-type: x-www-form-urlencoded
测试参数:
name | value |
---|---|
uAccount | admin |
uPassword | 123456 |
账号为空返回结果:
{
"code": "601",
"msg": "账号不能为空",
"location": null,
"token": null,
"data": null
}
密码为空返回结果:
{
"code": "602",
"msg": ",密码不能为空",
"location": null,
"token": null,
"data": null
}
返回失败结果:
{
"code": "10002",
"msg": "登录失败",
"location": "/login",
"token": null,
"data": null
}
返回成功结果:
{
"code": "200",
"msg": "操作成功",
"location": "/app.do?methodName=toDataPage",
"token": null,
"data": {
"createTime": null,
"modifiedTime": null,
"createAccountId": null,
"modifiedAccountId": null,
"deleted": 0,
"headSculpture": null,
"roleId": 1,
"uid": 1,
"uaccount": null,
"upassword": null,
"unickname": "管理员",
"urealname": null,
"uidCard": null,
"umobile": null
}
}
Jersey方式
package com.jdyxk.xiaojinku.action;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.commons.result.ResultCode;
import com.jdyxk.commons.string.StringUtil;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.UserService;
import com.jdyxk.xiaojinku.service.impl.UserServiceImpl;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 下午12:02
*/
// 该类的urlPatterns
@Path("/user")
public class UserAction {
private static final UserService userService = new UserServiceImpl();
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/loginByAccountAndPassword")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public ResponseResult<User> loginByAccountAndPassword(@FormParam("uAccount") String uAccount,
@FormParam("uPassword") String uPassword) {
if (StringUtil.isBlank(uAccount)) {
// 账号为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
return responseResult;
} else if (StringUtil.isBlank(uPassword)) {
// 密码为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
return responseResult;
} else {
// 封装请求参数
User user = new User(uAccount, uPassword);
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果 将登录结果转换为json格式字符串向用户发送
return userService.loginByAccountAndPassword(user);
}
}
}
jersey 表单登录测试
测试链接:http://localhost:6633/lhz/api/user/loginByAccountAndPassword
contont-type: x-www-form-urlencoded
测试参数:
name | value |
---|---|
uAccount | admin |
uPassword | 123456 |
账号为空返回结果:
{
"code": "601",
"msg": "账号不能为空"
}
密码为空返回结果:
{
"code": "602",
"msg": "密码不能为空"
}
返回失败结果:
{
"code": "10002",
"msg": "登录失败"
}
返回成功结果:
{
"code": "200",
"data": {
"createAccountId": 0,
"deleted": 0,
"modifiedAccountId": 0,
"roleId": 1,
"uId": 1,
"uNickname": "管理员"
},
"location": "/app.do?methodName=toDataPage",
"msg": "操作成功"
}
jersey json登录测试
测试链接:http://localhost:6633/lhz/api/user/login
contont-type: application/json
测试参数:
{
"uAccount":"admin",
"uPassword":"123456"
}
账号为空返回结果:
{
"code": "601",
"msg": "账号不能为空"
}
密码为空返回结果:
{
"code": "602",
"msg": "密码不能为空"
}
返回失败结果:
{
"code": "10002",
"msg": "登录失败"
}
返回成功结果:
{
"code": "200",
"data": {
"createAccountId": 0,
"deleted": 0,
"modifiedAccountId": 0,
"roleId": 1,
"uId": 1,
"uNickname": "管理员"
},
"location": "/app.do?methodName=toDataPage",
"msg": "操作成功"
}
设置默认主页
src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
src/main/webapp/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:forward page="WEB-INF/login.jsp"></jsp:forward>
</body>
</html>
登录页面
src/main/webapp/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>小金库管理系统</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--可无视-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/lib/bootstrap-4.6.0/css/bootstrap.min.css">
<!--主要样式-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/lib/layui/css/layui.css">
<script src="${pageContext.request.contextPath}/lib/layui/layui.js"></script>
</head>
<body>
<div class="container" align="center">
<div class="col-md-6" style="margin-top: 20%;">
<div class="inset">
<form name="login" id="login" method="post">
<input type="hidden" name="enews" value="login">
<div>
<h2>小金库管理系统</h2>
<span style="text-align: left;text-indent: 0.4em;"><label>用户名</label></span>
<span><input type="text" name="uAccount" id="uAccount" value="" class="textbox" autocomplete="off"></span>
</div>
<div>
<span style="text-align: left;text-indent: 0.4em;"><label>密码</label></span>
<span><input name="uPassword" id="uPassword" value="" type="password" class="password"></span>
</div>
<div class="sign">
<input type="reset" class="submit" value="重置"/>
<input type="submit" id="submitBtn" value="登录" class="submit"/>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
<script src="${pageContext.request.contextPath}/js/login.js" type="module"></script>
测试地址:http://192.168.18.65:6633/lhz’
登录JavaScript文件
src/main/webapp/js/login.js
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
// console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 布尔值,表示请求是否异步处理。默认是 true。
async: true,
// 发送请求前运行的函数。
beforeSend: function (xhr) {
layer.msg('加载中', {
icon: 16,
shade: 0.01,
time: 0
});
},
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
console.log(response);
switch (response.code) {
case '200':
layer.msg(response.msg, { icon: 1, shade: 0.3 });
window.location.replace(serverURL + response.location);
break;
case '601':
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
break;
case '602':
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
break;
default:
$('#uPassword').focus();
layer.msg(response.msg, { icon: 2, shade: 0.3 });
break;
}
},
error: function (xhr, status, error) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
// console.log(error);
},
// 设置本地的请求超时时间(以毫秒计)。
timeout: 3000,
// 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。
complete: function (xhr, status) {
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
if (status == 'timeout') {
layer.msg('请求超时', { icon: 5, shade: 0.3 });
}
}
});
}
// 防止表单同步提交
return false;
});
});
JavaScript公共模块
src/main/webapp/js/commons.js
// 数据接口服务器地址 注意主页不可以使用http://localhost:6633/lhz访问会造成AJAX跨域
const serverURL = 'http://192.168.18.65:6633/lhz';
// 图片服务器地址
const imgServerURL = 'http://192.168.18.65:6633/lhz';
/**
* 身份证解析
* @type {{getAge: (function(*): number), getBirthday: (function(*): string), getGender: (function(*): number)}}
*/
const idCardUtil = {
/**
* 获取出生日期
* @param idCard
* @returns {string}
*/
getBirthday: function (idCard) {
return idCard.substring(6, 10) + '-' + idCard.substring(10, 12) + '-' + idCard.substring(12, 14);
},
/**
* 获取年龄
* @param {*} idCard
* @returns
*/
getAge: function (idCard) {
let date = new Date();
let age = date.getFullYear() - idCard.substring(6, 10) - 1;
let month = date.getMonth() + 1;
if (idCard.substring(10, 12) < month || idCard.substring(10, 12) == month && idCard.substring(10, 12) <= date.getDate()) {
age++;
}
return age;
},
/**
* 获取性别
* @param {*} idCard
* @returns 1代表男性 0代表女性
*/
getGender: function (idCard) {
return idCard.substr(16, 1) % 2 == 1 ? 1 : 0;
},
}
// 便于解构赋值 单独引用
export {serverURL, imgServerURL, idCardUtil}
// 简单暴露 与上面单独暴露二选一即可
export default {
serverURL: serverURL,
imgServerURL: imgServerURL,
idCardUtil: idCardUtil
}
账号密码非空判断
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
}else{
// 如果账号和密码不为空 异步提交
console.log(uAccount + uPassword);
}
// 防止表单同步提交
return false;
});
});
账号为空
密码为空
ajax登录
禁用登录按钮
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)){
// 如果密码为空 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
}else{
console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled',true);
// 如果账号和密码不为空 异步提交
}
// 防止表单同步提交
return false;
});
});
封装ajax请求数据
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
},
error: function (xhr, status, error) {
console.log(error);
}
});
}
// 防止表单同步提交
return false;
});
});
登录中
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 布尔值,表示请求是否异步处理。默认是 true。
async: true,
// 发送请求前运行的函数。
beforeSend: function (xhr) {
layer.msg('加载中', {
icon: 16,
shade: 0.01,
time: 0
});
},
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
console.log(response);
},
error: function (xhr, status, error) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
console.log(error);
}
});
}
// 防止表单同步提交
return false;
});
});
登录超时
package com.jdyxk.xiaojinku.action;
import com.jdyxk.commons.response.ResponseResult;
import com.jdyxk.commons.result.ResultCode;
import com.jdyxk.commons.string.StringUtil;
import com.jdyxk.xiaojinku.pojo.User;
import com.jdyxk.xiaojinku.service.UserService;
import com.jdyxk.xiaojinku.service.impl.UserServiceImpl;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 下午12:02
*/
// 该类的urlPatterns
@Path("/user")
public class UserAction {
private static final UserService userService = new UserServiceImpl();
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/loginByAccountAndPassword")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public ResponseResult<User> loginByAccountAndPassword(@FormParam("uAccount") String uAccount,
@FormParam("uPassword") String uPassword) {
if (StringUtil.isBlank(uAccount)) {
// 账号为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
return responseResult;
} else if (StringUtil.isBlank(uPassword)) {
// 密码为空 封装返回数据
ResponseResult responseResult = new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
// 将结果转换为json格式字符串向用户发送
return responseResult;
} else {
// 封装请求参数
User user = new User(uAccount, uPassword);
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
}
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 布尔值,表示请求是否异步处理。默认是 true。
async: true,
// 发送请求前运行的函数。
beforeSend: function (xhr) {
layer.msg('加载中', {
icon: 16,
shade: 0.01,
time: 0
});
},
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
// console.log(response);
},
error: function (xhr, status, error) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
// console.log(error);
},
// 设置本地的请求超时时间(以毫秒计)。
timeout: 3000,
// 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。
complete: function (xhr, status) {
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
if (status == 'timeout') {
layer.msg('请求超时', {icon: 5, shade: 0.3});
}
}
});
}
// 防止表单同步提交
return false;
});
});
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRiec1VB-1655082514742)(img/image-
.png)]
登录失败
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
// console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 布尔值,表示请求是否异步处理。默认是 true。
async: true,
// 发送请求前运行的函数。
beforeSend: function (xhr) {
layer.msg('加载中', {
icon: 16,
shade: 0.01,
time: 0
});
},
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
console.log(response);
switch (response.code) {
case '200':
break;
case '601':
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
break;
case '602':
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
break;
default:
$('#uPassword').focus();
layer.msg(response.msg, { icon: 2, shade: 0.3 });
break;
}
},
error: function (xhr, status, error) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
// console.log(error);
},
// 设置本地的请求超时时间(以毫秒计)。
timeout: 3000,
// 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。
complete: function (xhr, status) {
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
if (status == 'timeout') {
layer.msg('请求超时', { icon: 5, shade: 0.3 });
}
}
});
}
// 防止表单同步提交
return false;
});
});
登录成功
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
// 导入公共模块
// import commons from './js/commons.js'
import { serverURL } from './commons.js'
// 引入layui 弹出层模块 和jQuery模块
layui.use(['layer', 'jquery'], function () {
// 引入layui 弹出层模块 和jQuery模块
var layer = layui.layer, $ = layui.jquery;
// 页面加载完成后账号获取焦点
$('#uAccount').focus();
// 点击登录按钮 异步登录
$('#submitBtn').click(function (e) {
e.preventDefault();
// 获取账号的值
let uAccount = $('#uAccount').val();
// 获取密码的值
let uPassword = $('#uPassword').val();
if ('' == uAccount || '' == $.trim(uAccount)) {
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
} else if ('' == uPassword || '' == $.trim(uPassword)) {
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
} else {
// console.log(uAccount + uPassword);
// 禁用登录按钮
$('#submitBtn').addClass('layui-btn-disabled').attr('disabled', true);
// 将参数封装为对象
let data = {
// :属性名:属性值
uAccount: $.trim(uAccount),
uPassword: $.trim(uPassword),
};
// 如果账号和密码不为空 异步提交
$.ajax({
// 规定请求的类型(GET 或 POST),新增 PUT PATCH DELETE HEAD OPTIONS CONNECT TRACE
type: "post",
// 规定发送请求的 URL。默认是当前页面。
url: serverURL + "/api/user/login",
// 布尔值,表示请求是否异步处理。默认是 true。
async: true,
// 发送请求前运行的函数。
beforeSend: function (xhr) {
layer.msg('加载中', {
icon: 16,
shade: 0.01,
time: 0
});
},
// 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
contentType: "application/json;charset=UTF-8",
// 规定要发送到服务器的数据。
data: JSON.stringify(data),
// 预期的服务器响应的数据类型。 text xml json 等
dataType: "json",
success: function (response, status, xhr) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
console.log(response);
switch (response.code) {
case '200':
layer.msg(response.msg, { icon: 1, shade: 0.3 });
break;
case '601':
// 如果账号为空
$('#uAccount').focus();
// 页面提示
layer.open({
type: 4,
content: ['账号不能为空', '#uAccount'],
time: 2000
});
break;
case '602':
// 如果密码为空
$('#uPassword').focus();
// 页面提示
layer.open({
type: 4,
content: ['密码不能为空', '#uPassword'],
time: 2000
});
break;
default:
$('#uPassword').focus();
layer.msg(response.msg, { icon: 2, shade: 0.3 });
break;
}
},
error: function (xhr, status, error) {
// 疯狂模式,关闭所有层
layer.closeAll()
// 启动登录按钮
// $('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
// $('#submitBtn').removeAttr('disabled');
// console.log(error);
},
// 设置本地的请求超时时间(以毫秒计)。
timeout: 3000,
// 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。
complete: function (xhr, status) {
// 启动登录按钮
$('#submitBtn').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submitBtn').removeAttr('disabled');
if (status == 'timeout') {
layer.msg('请求超时', { icon: 5, shade: 0.3 });
}
}
});
}
// 防止表单同步提交
return false;
});
});
跳转数据页面
// 接受数据请求方式
@POST
// 返回值MIME类型
@Produces(MediaType.APPLICATION_JSON)
// 该类的urlPatterns的子url
@Path("/login")
// 解析数据类型格式
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> login(User user,
@Context HttpServletRequest request) {
if (StringUtil.isBlank(user.getuAccount())) {
// 账号为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.ACCOUNT_ISNULL.getCode(), ResultCode.ACCOUNT_ISNULL.getMsg());
} else if (StringUtil.isBlank(user.getuPassword())) {
// 密码为空 封装返回数据 将结果转换为json格式字符串向用户发送
return new ResponseResult(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else {
// 调用业务层获取登录结果
ResponseResult<User> responseResult = userService.loginByAccountAndPassword(user);
// 获取登录人对象
user = responseResult.getData();
if (user != null) {
// 如果登录人对象不为空则将登录人信息存储到session域
request.getSession().setAttribute("operator",user);
}
// 将登录结果转换为json格式字符串向用户发送
return responseResult;
}
}
主入口类App
package com.jdyxk.xiaojinku.controller;
import com.jdyxk.commons.servlet.BaseServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/10 上午11:53
*/
@WebServlet(urlPatterns = {"/app.do"})
public class App extends BaseServlet {
/**
* 跳转数据页面
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void toDataPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
forwordToWEB_INF_SuffixJSP(request,response,"data");
}
}
数据页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>小金库管理系统</title>
</head>
<body>
操作者:${sessionScope.operator.uNickname}
</body>
</html>
数据页面
页面布局
主体布局
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>小金库管理系统</title>
<link rel="stylesheet" href="./lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo layui-hide-xs layui-bg-black">小金库管理系统</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<!-- <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
<li class="layui-nav-item layui-hide-xs"><a href="">控制台</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">商品管理</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">用户</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd><a href="">邮件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授权管理</a></dd>
</dl>
</li> -->
<li class="layui-nav-item layadmin-flexible" lay-unselect>
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
</a>
</li>
<li class="layui-nav-item layui-hide-xs" lay-unselect>
<a href="https://space.bilibili.com/480308139" target="_blank" title="李昊哲-小课">
<i class="layui-icon layui-icon-website"></i>
</a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" layadmin-event="refresh" title="刷新">
<i class="layui-icon layui-icon-refresh-3"></i>
</a>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="./images/qq1.png" class="layui-nav-img">
李昊哲-小课
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:void(0)" id="userInfoBtn">个人资料</a></dd>
<dd><a href="javascript:void(0)" id="modifypasswordBtn">修改密码</a></dd>
<dd><a href="">退出系统</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item">
<a class="" href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">用户列表</a></dd>
<dd><a href="javascript:;">添加用户</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">统计报表</a></li>
<li class="layui-nav-item">
<a href="javascript:;">收入管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">收入明细</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">支出管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">支出明细</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
©jdyxk.com - 桃李不言下自成蹊
</div>
</div>
<!-- 修改用户信息 -->
<div style="display: none;" id="userinfo">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="userinfo_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="userinfo_form">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" name="uAccount" id="account" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" name="uNickname" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><button type="button" class="layui-btn"
id="selectImg">选择头像</button></label>
<div class="layui-input-block">
<input type="text" name="headSculpture" id="headImg" value="" autocomplete="off"
class="layui-input layui-hide">
<img id="preview" src="./images/qq1.png" width="150px">
<img id="thumbImagePath" width="150px">
<img id="fullPath" width="150px">
<div class="layui-progress layui-progress" lay-showpercent="true" lay-filter="demo" id="demo"
style="display: none ;width: 450px;">
<div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
</div>
<p id="demoText"></p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-inline">
<input type="text" name="uRealname" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">身份证号</label>
<div class="layui-input-inline">
<input type="text" name="uIdCard" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="tel" name="uMobile" id="mobile" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="submit_userinfo" id="submit_userinfo">立即提交</button>
</div>
</div>
</form>
</div>
<!-- 修改密码 -->
<div id="modifypassword" style="display: none;">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="modifypassword_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="modifypassword_form">
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" placeholder="请输入新密码" lay-verify="required|pass"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" name="reuPassword" placeholder="请确认新密码" lay-verify="required|repass"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="password" name="originalPassword" placeholder="请输入原密码" lay-verify="required|opass"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="formModifyPassword">立即提交</button>
</div>
</div>
</form>
</div>
<script src="./lib/layui/layui.js"></script>
<script>
//JS
layui.use(['element', 'layer', 'util'], function () {
var element = layui.element
, layer = layui.layer
, util = layui.util
, $ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function (othis) {
layer.msg('展开左侧菜单的操作', { icon: 0 });
}
, menuRight: function () {
layer.open({
type: 1
, content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
, area: ['260px', '100%']
, offset: 'rt' //右上角
, anim: 5
, shadeClose: true
});
}
});
});
</script>
<script src="./js/operator.js" type="module"></script>
</body>
</html>
修改密码页面
<!-- 修改密码 -->
<div id="modifypassword" style="display: none;">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="modifypassword_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="modifypassword_form">
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" placeholder="请输入新密码" lay-verify="required|pass"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" name="reuPassword" placeholder="请确认新密码" lay-verify="required|repass"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="password" name="originalPassword" placeholder="请输入原密码" lay-verify="required|opass"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="formModifyPassword" id="formModifyPassword">立即提交</button>
</div>
</div>
</form>
</div>
$('#userInfoBtn').click(function (e) {
e.preventDefault();
// 点击修改密码按钮 弹出修改密码页面
layer.open({
type: 1,
content: $('#userinfo'),
title:'个人资料',
area: ['660px', '480px'],
closeBtn: 2,
shadeClose: false,
success: function (layero, index) {
// console.log(layero, index);
$('#userinfo_title').text('个人资料');
},
cancel: function () {
$('#userinfo').css('display', 'none');
}
});
});
修改资料页面
<!-- 修改用户信息 -->
<div style="display: none;" id="userinfo">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="userinfo_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="userinfo_form">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" name="uAccount" id="account" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" name="uNickname" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><button type="button" class="layui-btn"
id="selectImg">选择头像</button></label>
<div class="layui-input-block">
<input type="text" name="headSculpture" id="headImg" value="" autocomplete="off"
class="layui-input layui-hide">
<img id="preview" src="./images/qq1.png" width="150px">
<img id="thumbImagePath" width="150px">
<img id="fullPath" width="150px">
<div class="layui-progress layui-progress" lay-showpercent="true" lay-filter="demo" id="demo"
style="display: none ;width: 450px;">
<div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
</div>
<p id="demoText"></p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-inline">
<input type="text" name="uRealname" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">身份证号</label>
<div class="layui-input-inline">
<input type="text" name="uIdCard" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="tel" name="uMobile" id="mobile" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="submit_userinfo" id="submit_userinfo">立即提交</button>
</div>
</div>
</form>
</div>
头像上传
data.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>小金库管理系统</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo layui-hide-xs layui-bg-black">小金库管理系统</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<!-- <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
<li class="layui-nav-item layui-hide-xs"><a href="">控制台</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">商品管理</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">用户</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd><a href="">邮件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授权管理</a></dd>
</dl>
</li> -->
<li class="layui-nav-item layadmin-flexible" lay-unselect>
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
</a>
</li>
<li class="layui-nav-item layui-hide-xs" lay-unselect>
<a href="https://space.bilibili.com/480308139" target="_blank" title="李昊哲-小课">
<i class="layui-icon layui-icon-website"></i>
</a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" layadmin-event="refresh" title="刷新">
<i class="layui-icon layui-icon-refresh-3"></i>
</a>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="./images/qq1.png" class="layui-nav-img">
<span id="operatorName">${sessionScope.operator.uNickname}</span>
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:void(0)" id="userInfoBtn">个人资料</a></dd>
<dd><a href="javascript:void(0)" id="modifypasswordBtn">修改密码</a></dd>
<dd><a href="${pageContext.request.contextPath}/app.do?methodName=logout">退出系统</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item">
<a class="" href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">用户列表</a></dd>
<dd><a href="javascript:;">添加用户</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">统计报表</a></li>
<li class="layui-nav-item">
<a href="javascript:;">收入管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">收入明细</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">支出管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">支出明细</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
©jdyxk.com - 桃李不言下自成蹊
</div>
</div>
<!-- 修改用户信息 -->
<div style="display: none;" id="userinfo">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="userinfo_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="userinfo_form">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" name="uAccount" id="account" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" name="uNickname" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><button type="button" class="layui-btn"
id="selectImg">选择头像</button></label>
<div class="layui-input-block">
<input type="text" name="headSculpture" id="headImg" value="" autocomplete="off"
class="layui-input layui-hide">
<img id="preview" src="./images/qq1.png" width="150px">
<img id="thumbImagePath" width="150px">
<img id="fullPath" width="150px">
<div class="layui-progress layui-progress" lay-showpercent="true" lay-filter="demo" id="demo"
style="display: none ;width: 450px;">
<div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
</div>
<p id="demoText"></p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-inline">
<input type="text" name="uRealname" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">身份证号</label>
<div class="layui-input-inline">
<input type="text" name="uIdCard" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="tel" name="uMobile" id="mobile" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="submit_userinfo" id="submit_userinfo">立即提交</button>
</div>
</div>
</form>
</div>
<!-- 修改密码 -->
<div id="modifypassword" style="display: none;">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="modifypassword_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="modifypassword_form">
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" id="uPassword" placeholder="请输入新密码" lay-verify="required|pass" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" name="reuPassword" id="reuPassword" placeholder="请确认新密码" lay-verify="required|repass" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="password" name="originalPassword" id="originalPassword" placeholder="请输入原密码" lay-verify="required|opass" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="formModifyPassword" id="formModifyPassword">立即提交</button>
</div>
</div>
</form>
</div>
<script src="${pageContext.request.contextPath}/lib/layui/layui.js"></script>
<script>
// 将登录者ID与全局对象绑定
var uId = ${sessionScope.operator.uId};
//JS
layui.use(['element', 'layer', 'util'], function () {
var element = layui.element
, layer = layui.layer
, util = layui.util
, $ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function (othis) {
layer.msg('展开左侧菜单的操作', { icon: 0 });
}
, menuRight: function () {
layer.open({
type: 1
, content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
, area: ['260px', '100%']
, offset: 'rt' //右上角
, anim: 5
, shadeClose: true
});
}
});
});
</script>
<%--自定义公共模块--%>
<script>
layui.config({
base: '${pageContext.request.contextPath}/js/'
}).use('laymod');
</script>
<%--登录者操作--%>
<script src="${pageContext.request.contextPath}/js/operator.js" type="module"></script>
</body>
</html>
退出系统
package com.jdyxk.xiaojinku.controller;
import com.jdyxk.commons.servlet.BaseServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/14 上午11:04
*/
@WebServlet(urlPatterns = {"/app.do"})
public class App extends BaseServlet {
/**
* 跳转数据页面
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void toDataPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
forwordToWEB_INF_SuffixJSP(request, response, "data");
}
/**
* 注销 退出系统
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取HttpSession对象
HttpSession session = request.getSession();
// 当前session失效
session.invalidate();
// 返回登录页面 注意此处使用网页重定向 避免参数传递
redirectSuffixJSP(request, response, "login");
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>小金库管理系统</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/lib/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo layui-hide-xs layui-bg-black">小金库管理系统</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<!-- <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
<li class="layui-nav-item layui-hide-xs"><a href="">控制台</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">商品管理</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">用户</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<dd><a href="">邮件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授权管理</a></dd>
</dl>
</li> -->
<li class="layui-nav-item layadmin-flexible" lay-unselect>
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
</a>
</li>
<li class="layui-nav-item layui-hide-xs" lay-unselect>
<a href="https://space.bilibili.com/480308139" target="_blank" title="李昊哲-小课">
<i class="layui-icon layui-icon-website"></i>
</a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" layadmin-event="refresh" title="刷新">
<i class="layui-icon layui-icon-refresh-3"></i>
</a>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="./images/qq1.png" class="layui-nav-img">
${sessionScope.operator.uNickname}
</a>
<dl class="layui-nav-child">
<dd><a href="javascript:void(0)" id="userInfoBtn">个人资料</a></dd>
<dd><a href="javascript:void(0)" id="modifypasswordBtn">修改密码</a></dd>
<dd><a href="${pageContext.request.contextPath}/app.do?methodName=logout">退出系统</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item">
<a class="" href="javascript:;">系统管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">用户列表</a></dd>
<dd><a href="javascript:;">添加用户</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">统计报表</a></li>
<li class="layui-nav-item">
<a href="javascript:;">收入管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">收入明细</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">支出管理</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">支出明细</a></dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
©jdyxk.com - 桃李不言下自成蹊
</div>
</div>
<!-- 修改用户信息 -->
<div style="display: none;" id="userinfo">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="userinfo_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="userinfo_form">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" name="uAccount" id="account" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" name="uNickname" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><button type="button" class="layui-btn"
id="selectImg">选择头像</button></label>
<div class="layui-input-block">
<input type="text" name="headSculpture" id="headImg" value="" autocomplete="off"
class="layui-input layui-hide">
<img id="preview" src="./images/qq1.png" width="150px">
<img id="thumbImagePath" width="150px">
<img id="fullPath" width="150px">
<div class="layui-progress layui-progress" lay-showpercent="true" lay-filter="demo" id="demo"
style="display: none ;width: 450px;">
<div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
</div>
<p id="demoText"></p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-inline">
<input type="text" name="uRealname" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">身份证号</label>
<div class="layui-input-inline">
<input type="text" name="uIdCard" value="" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="tel" name="uMobile" id="mobile" value="" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="submit_userinfo" id="submit_userinfo">立即提交</button>
</div>
</div>
</form>
</div>
<!-- 修改密码 -->
<div id="modifypassword" style="display: none;">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="modifypassword_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="modifypassword_form">
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" required lay-verify="required" placeholder="请输入新密码"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" name="reuPassword" required lay-verify="required" placeholder="请确认新密码"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" required lay-verify="required" placeholder="请输入原密码"
autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn lay-submit">立即提交</button>
</div>
</div>
</form>
</div>
<script src="${pageContext.request.contextPath}/lib/layui/layui.js"></script>
<script>
//JS
layui.use(['element', 'layer', 'util'], function () {
var element = layui.element
, layer = layui.layer
, util = layui.util
, $ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function (othis) {
layer.msg('展开左侧菜单的操作', { icon: 0 });
}
, menuRight: function () {
layer.open({
type: 1
, content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
, area: ['260px', '100%']
, offset: 'rt' //右上角
, anim: 5
, shadeClose: true
});
}
});
});
</script>
<%--登录者操作--%>
<script src="${pageContext.request.contextPath}/js/operator.js" type="module"></script>
</body>
</html>
修改密码
修改密码持久层
/**
* 根据用户ID获取用户信息
*
* @param uId 用户主键ID
* @return 用户信息
*/
User selectByUid(@Param("uId") Long uId);
<!--根据用户ID获取用户信息-->
<select id="selectByUid" parameterType="java.lang.Long" resultType="user">
SELECT *
FROM `tb_user`
WHERE `u_id` = #{uId}
</select>
/**
* 根据用户ID获取用户信息
*
* @param uId 用户主键ID
* @return 用户信息
*/
Integer updatePaswordByUid(@Param("uId") Long uId,@Param("uPassword") String uPassword);
<!--修改密码-->
<update id="updatePaswordByUid">
UPDATE `tb_user`
SET `u_password` = #{uPassword}
WHERE `u_id` = #{uId}
</update>
修改密码业务层
/**
* 根据用户ID获取用户信息
*
* @param uId
* @return
*/
ResponseResult<Integer> modifyPassword(Long uId,String uPassword,String originalPassword);
@Override
public ResponseResult<Integer> modifyPassword(Long uId, String uPassword, String originalPassword) {
// 获取数据库连接
SqlSession sqlSession = MybatisUtil.openSqlSession();
// 获取持久层接口代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用持久层方法
User user = userMapper.selectByUid(uId);
if (user != null) {
if (!user.getuPassword().equals(originalPassword)) {
// 原始密码不正确
MybatisUtil.close();
return new ResponseResult<>(ResultCode.PASSWORD_ERROR.getCode(), ResultCode.PASSWORD_ERROR.getMsg(), null, 0);
}else if(user.getuPassword().equals(uPassword)){
// 姓名与原密码一致
MybatisUtil.close();
return new ResponseResult<>(ResultCode.PASSWORD_NOCHANGE.getCode(), ResultCode.PASSWORD_NOCHANGE.getMsg(), null, 0);
}else{
// 调用持久层修改密码
Integer count = userMapper.updatePaswordByUid(uId, uPassword);
MybatisUtil.commitAndClose();
if (count > 0) {
return new ResponseResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null, count);
}else{
return new ResponseResult<>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg(), null, count);
}
}
}
return new ResponseResult<>(ResultCode.DATA_EMPTY.getCode(), ResultCode.DATA_EMPTY.getMsg(), null, 0);
}
修改密码业务处测试
@Test
public void modifyPassword(){
// Long uId = 2L;
Long uId = 1L;
// String originalPassword = "654321";
// String uPassword = "123456";
String uPassword = "20212021";
String originalPassword = "123456";
ResponseResult<Integer> responseResult = userService.modifyPassword(uId, uPassword, originalPassword);
System.out.println(responseResult.getMsg());
}
修改密码数据接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7hNNgisU-1655082514745)(img/image-20210915090845652.png)]
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/modifyPassword/{uId}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public ResponseResult<Integer> modifyPassword(@PathParam("uId") Long uId,
@FormParam("uPassword") String uPassword,
@FormParam("reuPassword") String reuPassword,
@FormParam("originalPassword") String originalPassword,
@Context HttpServletRequest request) {
User user = (User) request.getSession().getAttribute("operator");
long uid = user.getuId();
if (uid != uId) {
return new ResponseResult<>(ResultCode.NO_LOGIN.getCode(), ResultCode.NO_LOGIN.getMsg());
} else if (StringUtil.isBlank(uPassword)) {
// if (StringUtil.isBlank(uPassword)) {
return new ResponseResult<>(ResultCode.PASSWORD_ISNULL.getCode(), ResultCode.PASSWORD_ISNULL.getMsg());
} else if (StringUtil.isBlank(reuPassword)) {
return new ResponseResult<>(ResultCode.REPASSWORD_ISNULL.getCode(), ResultCode.REPASSWORD_ISNULL.getMsg());
} else if (StringUtil.isBlank(originalPassword)) {
return new ResponseResult<>(ResultCode.OPASSWORD_ISNULL.getCode(), ResultCode.OPASSWORD_ISNULL.getMsg());
} else {
if (!uPassword.equals(reuPassword)) {
return new ResponseResult<>(ResultCode.INCONSISTENT_PASSWORDS.getCode(), ResultCode.INCONSISTENT_PASSWORDS.getMsg());
}
return userService.modifyPassword(uId, uPassword, originalPassword);
}
}
Postman测试
测试地址:http://localhost:6633/lhz/api/user/modifyPassword/1
修改密码测试参数:
注意:JSESSIONID
请求方式:post
name | value |
---|---|
uPassword | 123456 |
reuPassword | 123456 |
originalPassword | 123 |
新密码为空
{
"code": "602",
"msg": "密码不能为空",
"location": null,
"token": null,
"data": null
}
确认密码为空
{
"code": "603",
"msg": "确认密码不能为空",
"location": null,
"token": null,
"data": null
}
原始密码为空
{
"code": "604",
"msg": "原始密码不能为空",
"location": null,
"token": null,
"data": null
}
新密码与确认密码不一致
{
"code": "606",
"msg": "新密码与确认密码不一致",
"location": null,
"token": null,
"data": null
}
密码错误
{
"code": "607",
"msg": "密码错误",
"location": null,
"token": null,
"data": 0
}
新密码与原始密码一致
{
"code": "605",
"msg": "新密码与原始密码一致,无需修改",
"location": null,
"token": null,
"data": 0
}
成功修改密码
{
"code": "200",
"msg": "操作成功",
"location": null,
"token": null,
"data": 1
}
页面测试
页面效果
// 点击修改密码按钮
$('#modifypasswordBtn').click(function (e) {
e.preventDefault();
// 点击修改密码按钮 弹出修改密码页面
layer.open({
type: 1,
content: $('#modifypassword'),
title: '修改密码',
area: ['660px', '320px'],
closeBtn: 2,
shadeClose: false,
success: function (layero, index) {
// console.log(layero, index);
$('#modifypassword_title').text('修改密码');
// 修改密码提交按钮事件触发
form.on('submit(formModifyPassword)', function (data) {
// console.log(data.field);
$.ajax({
type: "POST",
url: serverURL + "/api/user/modifyPassword/" + uId,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
beforeSend: function () {
$('#formModifyPassword').addClass('layui-btn-disabled').attr('disabled', true);
},
data: data.field,
dataType: "json",
success: function (response) {
// 启动登录按钮
$('#formModifyPassword').removeClass('layui-btn-disabled').attr('disabled', false);
$('#formModifyPassword').removeAttr('disabled');
switch (response.code) {
case '200':
// 关闭当前弹出层
layer.msg(response.msg, { icon: 1, shade: 0.3 });
setTimeout(() => {
layer.close(index);
// $('#uPassword').val('');
// $('#reuPassword').val('');
// $('#originalPassword').val('');
form.val('modifypassword_form', {
// "name": "value"
"uPassword": "",
"reuPassword": "",
"originalPassword": ""
});
}, 2000);
break;
case '602':
$('#uPassword').focus();
layer.tips(response.msg, '#uPassword', {
tips: [1, '#FA9090']
});
break;
case '603':
$('#reuPassword').focus();
layer.tips(response.msg, '#reuPassword', {
tips: [1, '#FA9090']
});
break;
case '604':
$('#originalPassword').focus();
layer.tips(response.msg, '#originalPassword', {
tips: [3, '#FA9090']
});
break;
case '605':
$('#uPassword').focus();
layer.tips(response.msg, '#uPassword', {
tips: [1, '#FA9090']
});
break;
case '606':
$('#reuPassword').focus();
layer.tips(response.msg, '#reuPassword', {
tips: [1, '#FA9090']
});
break;
case '607':
$('#originalPassword').focus();
layer.tips(response.msg, '#originalPassword', {
tips: [3, '#FA9090']
});
break;
default:
break;
}
}
});
return false;
});
},
cancel: function () {
form.val('modifypassword_form', {
// "name": "value"
"uPassword": "",
"reuPassword": "",
"originalPassword": ""
});
$('#modifypassword').css('display', 'none');
}
});
});
新密码为空
确认密码为空
原始密码为空
密码错误
新密码与确认密码不一致
新密码与原始密码一致
成功修改密码
layui自定义校验规则
layui.define(['form', 'layedit', 'laydate', 'jquery', 'layer'], function (exports) {
var form = layui.form, layer = layui.layer, layedit = layui.layedit, laydate = layui.laydate, layer = layui.layer, $ = layui.jquery;
//自定义验证规则
form.verify({
title: function (value) {
if (value.length < 5) {
return '标题至少得5个字符啊';
}
},
pass: [
/^[\S]{6,12}$/,
'密码必须6到12位,且不能出现空格'
],
repass: function (value) {
if ($('input[type=password]').val() != value) {
return '两次密码输入不一致!';
}
},
opass: function (value) {
if ($('input[type=password]').val() == value) {
return '新密码与原始密码一致,无需修改';
}
}
});
exports('laymod', {});
});
<script>
layui.config({
base: '${pageContext.request.contextPath}/js/'
}).use('laymod');
</script>
<div id="modifypassword" style="display: none;">
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend><span id="modifypassword_title"></span></legend>
</fieldset>
<form class="layui-form" action="" lay-filter="modifypassword_form">
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="uPassword" id="uPassword" placeholder="请输入新密码" lay-verify="required|pass" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" name="reuPassword" id="reuPassword" placeholder="请确认新密码" lay-verify="required|repass" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原密码</label>
<div class="layui-input-inline">
<input type="password" name="originalPassword" id="originalPassword" placeholder="请输入原密码" lay-verify="required|opass" autocomplete="off" class="layui-input">
</div>
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="formModifyPassword" id="formModifyPassword">立即提交</button>
</div>
</div>
</form>
</div>
新密码为空
密码长度错误
确认密码为空
原始密码为空
密码错误
新密码与确认密码不一致
新密码与原始密码一致
成功修改密码
修改个人资料
业务流程
读取个人资料
读取个人资料持久层
/**
* 根据用户ID获取用户信息
*
* @param uId 用户主键ID
* @return 用户信息
*/
User selectByUid(@Param("uId") Long uId);
<!--根据用户ID获取用户信息-->
<select id="selectByUid" parameterType="java.lang.Long" resultType="user">
SELECT *
FROM `tb_user`
WHERE `u_id` = #{uId}
</select>
读取个人资料业务层
/**
* 根据用户ID获取用户信息
*
* @param uId
* @return
*/
ResponseResult<Integer> modifyPassword(Long uId,String uPassword,String originalPassword);
@Override
public ResponseResult<User> getByUid(Long uId) {
// 默认登录失败
ResponseResult<User> responseResult = new ResponseResult<>(ResultCode.DATA_EMPTY.getCode(), ResultCode.DATA_EMPTY.getMsg());
// 获取数据库连接
SqlSession sqlSession = MybatisUtil.openSqlSession();
// 获取持久层接口代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用持久层方法
User user = userMapper.selectByUid(uId);
if (user != null) {
// 封装放回数据
responseResult.setCode(ResultCode.SUCCESS.getCode());
responseResult.setMsg(ResultCode.SUCCESS.getMsg());
// 返回数据
user.setuPassword("");
responseResult.setData(user);
}
return responseResult;
}
读取个人资料业务层测试
@Test
public void getByUid(){
ResponseResult<User> result = userService.getByUid(1L);
if (result.getData() != null) {
System.out.println(result.getData().getuNickname());
}else{
System.out.println(result.getMsg());
}
}
读取个人资料数据接口
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/getByUid")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public ResponseResult<User> getByUid(@HeaderParam("uId") Long uId,
@HeaderParam("oId") Long oId,
@Context HttpServletRequest request) {
User user = (User) request.getSession().getAttribute("operator");
long uid = user.getuId();
if (oId == null || uid != oId) {
// 判断查询着是否登录
return new ResponseResult<>(ResultCode.NO_LOGIN.getCode(), ResultCode.NO_LOGIN.getMsg());
} else if (uId == null || uId == 0) {
return new ResponseResult<>(ResultCode.PARAM_ERROR.getCode(), ResultCode.PARAM_ERROR.getMsg());
} else {
return userService.getByUid(uId);
}
}
Postman测试:
http://192.168.18.65:6633/lhz/api/user/getByUid
请求方式:get
headers | |
---|---|
oId | 1 |
uId | 1 |
未登录返回结果:
{
"code": "10009",
"msg": "未登录状态",
"location": null,
"token": null,
"data": null
}
参数错误:
{
"code": "10001",
"msg": "参数错误",
"location": null,
"token": null,
"data": null
}
未查询到数据:
{
"code": "50000",
"msg": "未查询到数据",
"location": null,
"token": null,
"data": null
}
正常返回:
{
"code": "200",
"msg": "操作成功",
"location": null,
"token": null,
"data": {
"createTime": [
2021,
9,
9,
6,
6,
6
],
"modifiedTime": [
2021,
9,
9,
6,
6,
6
],
"createAccountId": 1,
"modifiedAccountId": 1,
"deleted": 0,
"uId": 1,
"uAccount": "admin",
"uPassword": "",
"uNickname": "管理员",
"headSculpture": null,
"uRealname": "管理员",
"uIdCard": null,
"uMobile": null,
"roleId": 1
}
}
日期格式化:
// @JSONField(format = "yyyy-MM-dd HH-mm-ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH-mm-ss", locale = "zh", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH-mm-ss",iso = DateTimeFormat.ISO.DATE_TIME)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
{
"code": "200",
"msg": "操作成功",
"location": null,
"token": null,
"data": {
"createTime": "2021-09-09 06-06-06",
"modifiedTime": "2021-09-09 06-06-06",
"createAccountId": 1,
"modifiedAccountId": 1,
"deleted": 0,
"uId": 1,
"uAccount": "admin",
"uPassword": "",
"uNickname": "管理员",
"headSculpture": null,
"uRealname": "管理员",
"uIdCard": null,
"uMobile": null,
"roleId": 1
}
}
页面ajax请求:
// 点击个人资料按钮
$('#userInfoBtn').click(function (e) {
e.preventDefault();
// 点击个人资料按钮 弹出修改密码页面
layer.open({
type: 1,
content: $('#userinfo'),
title: '个人资料',
area: ['660px', '480px'],
closeBtn: 2,
shadeClose: false,
success: function (layero, index) {
$('#userinfo_title').text('个人资料');
$.ajax({
type: "get",
url: serverURL + "/api/user/getByUid",
beforeSend: function (xhr) {
// 将用户ID存储在请求头中
// oId 操作人ID
xhr.setRequestHeader('oId', uId);
// uId 被查询的用户ID
xhr.setRequestHeader('uId', uId);
layer.msg('加载中', {
icon: 16,
shade: 0.01,
});
},
dataType: "json",
success: function (response) {
switch (response.code) {
case '200':
let user = response.data;
form.val('userinfo_form', {
// "name": "value"
"uAccount": user.uAccount,
"uNickname": user.uNickname,
"headSculpture": user.headSculpture,
"uRealname": user.uRealname,
"uIdCard": user.uIdCard,
"uMobile": user.uMobile
});
break;
default:
break;
}
}
});
// 修改个人资料提交按钮事件触发
form.on('submit(submit_userinfo)', function (data) {
let userinfo = data.field;
return false;
});
},
cancel: function () {
sessionStorage.removeItem('muid');
form.val('userinfo_form', {
// "name": "value"
"uAccount": "",
"uNickname": "",
"headSculpture": "",
"uRealname": "",
"uIdCard": "",
"uMobile": ""
});
$('#userinfo').css('display', 'none');
}
});
});
保存个人资料
保存个人资料持久层:
/**
* 根据账号获取主键ID
* @param uAccount
* @return
*/
Long selectByAccount(String uAccount);
/**
* 更新用户信息
*
* @param user
* @return
*/
Integer updateUser(@Param("user") User user);
}
<!--查询账号是否存在-->
<select id="selectByAccount" parameterType="java.lang.String" resultType="java.lang.Long">
SELECT `u_id`
FROM `tb_user`
WHERE `u_account` = #{uAccount}
</select>
<!--修改密码-->
<update id="updateUser" parameterType="user">
UPDATE `tb_user`
<trim prefix="SET" suffixOverrides=",">
<if test="user.uAccount != null and user.uAccount != ''">`u_account` = #{user.uAccount},</if>
<if test="user.uNickname != null and user.uAccount != ''">`u_nickname` = #{user.uNickname},</if>
<if test="user.headSculpture != null and user.uAccount != ''">`head_sculpture` = #{user.headSculpture},</if>
<if test="user.uRealname != null and user.uRealname != ''">`u_realname` = #{user.uRealname},</if>
<if test="user.uIdCard != null and user.uIdCard != ''">`u_id_card` = #{user.uIdCard},</if>
<if test="user.uMobile != null and user.uMobile != ''">`u_mobile` = #{user.uMobile},</if>
<if test="user.roleId != null and user.roleId != ''">`role_id` = #{user.roleId},</if>
<if test="user.createTime != null">`create_time` = #{user.createTime},</if>
<if test="user.modifiedTime != null">`modified_time` = #{user.modifiedTime},</if>
<if test="user.createAccountId != null and user.createAccountId != ''">`create_account_id` = #{user.createAccountId},</if>
<if test="user.modifiedAccountId != null and user.modifiedAccountId != ''">`modified_account_id` = #{user.modifiedAccountId},</if>
<if test="user.deleted != null and user.deleted != ''">`deleted` = #{user.deleted},</if>
</trim>
WHERE `u_id` = #{user.uId}
</update>
保存个人资料业务层:
/**
* 修改用户信息
*
* @param user 修改信息
* @param oId 修改人ID
* @return
*/
ResponseResult<Integer> modifyUser(User user,Long oId);
}
@Override
public ResponseResult<Integer> modifyUser(User user, Long oId) {
// 获取数据库连接
SqlSession sqlSession = MybatisUtil.openSqlSession();
// 获取持久层接口代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
if (!StringUtil.isBlank(user.getuAccount())) {
// 如果修改的信息包含账号 那么 先验证该账号是否存在
Long uid = userMapper.selectByAccount(user.getuAccount());
if (uid != null && uid.equals(user.getuId())) {
// 如果该账号是自己的账号 则设置账号为空
user.setuAccount(null);
}else{
// 如果账号不是自己的 说明账号重复了
MybatisUtil.close();
return new ResponseResult<>(ResultCode.ACCOUNT_EXISTS.getCode(), ResultCode.ACCOUNT_EXISTS.getMsg(), null, 0);
}
}
// 设置当前服务器时间为修改时间
user.setModifiedTime(LocalDateTime.now());
if (!oId.equals(user.getuId())) {
// 不是本人修改设置修改人ID
user.setModifiedAccountId(oId);
}
// 调用持久层方法修改个人信息
Integer count = userMapper.updateUser(user);
MybatisUtil.commitAndClose();
if (count > 0) {
return new ResponseResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null, count);
} else {
return new ResponseResult<>(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg(), null, count);
}
}
保存个人资料数据接口:
@PATCH
@Produces(MediaType.APPLICATION_JSON)
@Path("/modifyUser")
@Consumes(MediaType.APPLICATION_JSON)
public ResponseResult<User> modifyUser(@HeaderParam("oId") Long oId,
User user,
@Context HttpServletRequest request) {
User operator = (User) request.getSession().getAttribute("operator");
Long oid = operator.getuId();
if (oId == null || oid != oId) {
// 判断查询着是否登录
return new ResponseResult<>(ResultCode.NO_LOGIN.getCode(), ResultCode.NO_LOGIN.getMsg());
}else {
ResponseResult<Integer> result = userService.modifyUser(user, oId);
if (result.getData() > 0) {
ResponseResult<User> responseResult = userService.getByUid(user.getuId());
User data = responseResult.getData();
// 判断是不是本人修改
if (oid.equals(data.getuId())) {
// 如果是本人修改 则更新 session中的 登录人信息
operator.setRoleId(data.getRoleId());
operator.setuNickname(data.getuNickname());
request.getSession().setAttribute("operator", operator);
}
return responseResult;
}else{
return new ResponseResult<>(result.getCode(), result.getMsg());
}
}
}
保存个人资料页面:
// 点击个人资料按钮
$('#userInfoBtn').click(function (e) {
e.preventDefault();
// 点击个人资料按钮 弹出修改密码页面
layer.open({
type: 1,
content: $('#userinfo'),
title: '个人资料',
area: ['660px', '480px'],
closeBtn: 2,
shadeClose: false,
success: function (layero, index) {
$('#userinfo_title').text('个人资料');
$.ajax({
type: "get",
url: serverURL + "/api/user/getByUid",
beforeSend: function (xhr) {
// 将用户ID存储在请求头中
// oId 操作人ID
xhr.setRequestHeader('oId', uId);
// uId 被查询的用户ID
xhr.setRequestHeader('uId', uId);
layer.msg('加载中', {
icon: 16,
shade: 0.01,
});
},
dataType: "json",
success: function (response) {
switch (response.code) {
case '200':
let user = response.data;
// 将获取到用户ID保存在临时存储中
sessionStorage.setItem('muid', user.uId);
form.val('userinfo_form', {
// "name": "value"
"uAccount": user.uAccount,
"uNickname": user.uNickname,
"headSculpture": user.headSculpture,
"uRealname": user.uRealname,
"uIdCard": user.uIdCard,
"uMobile": user.uMobile
});
break;
default:
break;
}
}
});
// 修改个人资料提交按钮事件触发
form.on('submit(submit_userinfo)', function (data) {
let userinfo = data.field;
// 从临时存储中获取用户ID
userinfo.uId = sessionStorage.getItem('muid');
$.ajax({
type: "PATCH",
url: serverURL + "/api/user/modifyUser",
beforeSend: function (xhr) {
$('#submit_userinfo').addClass('layui-btn-disabled').attr('disabled', true);
// 将用户ID存储在请求头中
xhr.setRequestHeader("oId", uId);
layer.msg('加载中', {
icon: 16,
shade: 0.01,
});
},
contentType: "application/json;charset=UTF-8",
data: JSON.stringify(userinfo),
dataType: "json",
success: function (response) {
// 启动登录按钮
$('#submit_userinfo').removeClass('layui-btn-disabled').attr('disabled', false);
$('#submit_userinfo').removeAttr('disabled');
switch (response.code) {
case '200':
// 更新页面显示的登录人昵称
$('#operatorName').text(response.data.uNickname);
// 关闭当前弹出层
layer.msg(response.msg, { icon: 1, shade: 0.3 });
setTimeout(() => {
layer.close(index);
form.val('userinfo_form', {
// "name": "value"
"uAccount": "",
"uNickname": "",
"headSculpture": "",
"uRealname": "",
"uIdCard": "",
"uMobile": ""
});
}, 2000)
break;
default:
break;
}
}
});
return false;
});
},
cancel: function () {
sessionStorage.removeItem('muid');
form.val('userinfo_form', {
// "name": "value"
"uAccount": "",
"uNickname": "",
"headSculpture": "",
"uRealname": "",
"uIdCard": "",
"uMobile": ""
});
$('#userinfo').css('display', 'none');
}
});
});
异步验证账号
异步验证手机号
异步验证身份证件号
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/188786.html