数据库

关于app端用户相关的内容较多,可以单独设置一个库leadnews_user

表名称 说明
ap_user APP用户信息表
ap_user_fan APP用户粉丝信息表
ap_user_follow APP用户关注信息表
ap_user_realname APP实名认证信息表

下载数据库文件:

数据库创建命令

leadnews_user.sql
CREATE DATABASE IF NOT EXISTS leadnews_user DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE leadnews_user;
SET NAMES utf8;
/*
Navicat MySQL Data Transfer

Source Server : localhost
Source Server Version : 50721
Source Host : localhost:3306
Source Database : leadnews_user

Target Server Type : MYSQL
Target Server Version : 50721
File Encoding : 65001

Date: 2021-04-12 13:58:42
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for ap_user
-- ----------------------------
DROP TABLE IF EXISTS `ap_user`;
CREATE TABLE `ap_user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`salt` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码、通信等加密盐',
`name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名',
`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码,md5加密',
`phone` varchar(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',
`image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像',
`gender` tinyint(1) unsigned DEFAULT NULL COMMENT '0 男\r\n 1 女\r\n 2 未知',
`is_certification` tinyint(1) unsigned DEFAULT NULL COMMENT '0 未\r\n 1 是',
`is_identity_authentication` tinyint(1) DEFAULT NULL COMMENT '是否身份认证',
`status` tinyint(1) unsigned DEFAULT NULL COMMENT '0正常\r\n 1锁定',
`flag` tinyint(1) unsigned DEFAULT NULL COMMENT '0 普通用户\r\n 1 自媒体人\r\n 2 大V',
`created_time` datetime DEFAULT NULL COMMENT '注册时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP用户信息表';

-- ----------------------------
-- Records of ap_user
-- ----------------------------
INSERT INTO `ap_user` VALUES ('1', 'abc', 'zhangsan', 'abc', '13511223453', null, '1', null, null, '1', '1', '2020-03-19 23:22:07');
INSERT INTO `ap_user` VALUES ('2', 'abc', 'lisi', 'abc', '13511223454', '', '1', null, null, '1', '1', '2020-03-19 23:22:07');
INSERT INTO `ap_user` VALUES ('3', 'sdsa', 'wangwu', 'wangwu', '13511223455', null, null, null, null, null, '1', null);
INSERT INTO `ap_user` VALUES ('4', '123abc', 'admin', '81e158e10201b6d7aee6e35eaf744796', '13511223456', null, '1', null, null, '1', '1', '2020-03-30 16:36:32');
INSERT INTO `ap_user` VALUES ('5', '123', 'suwukong', 'suwukong', '13511223458', null, '1', null, null, '1', '1', '2020-08-01 11:09:57');
INSERT INTO `ap_user` VALUES ('6', null, null, null, null, null, null, null, null, null, null, null);

-- ----------------------------
-- Table structure for ap_user_fan
-- ----------------------------
DROP TABLE IF EXISTS `ap_user_fan`;
CREATE TABLE `ap_user_fan` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` int(11) unsigned DEFAULT NULL COMMENT '用户ID',
`fans_id` int(11) unsigned DEFAULT NULL COMMENT '粉丝ID',
`fans_name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '粉丝昵称',
`level` tinyint(1) unsigned DEFAULT NULL COMMENT '粉丝忠实度\r\n 0 正常\r\n 1 潜力股\r\n 2 勇士\r\n 3 铁杆\r\n 4 老铁',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`is_display` tinyint(1) unsigned DEFAULT NULL COMMENT '是否可见我动态',
`is_shield_letter` tinyint(1) unsigned DEFAULT NULL COMMENT '是否屏蔽私信',
`is_shield_comment` tinyint(1) unsigned DEFAULT NULL COMMENT '是否屏蔽评论',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP用户粉丝信息表';

-- ----------------------------
-- Records of ap_user_fan
-- ----------------------------

-- ----------------------------
-- Table structure for ap_user_follow
-- ----------------------------
DROP TABLE IF EXISTS `ap_user_follow`;
CREATE TABLE `ap_user_follow` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` int(11) unsigned DEFAULT NULL COMMENT '用户ID',
`follow_id` int(11) unsigned DEFAULT NULL COMMENT '关注作者ID',
`follow_name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '粉丝昵称',
`level` tinyint(1) unsigned DEFAULT NULL COMMENT '关注度\r\n 0 偶尔感兴趣\r\n 1 一般\r\n 2 经常\r\n 3 高度',
`is_notice` tinyint(1) unsigned DEFAULT NULL COMMENT '是否动态通知',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP用户关注信息表';

-- ----------------------------
-- Records of ap_user_follow
-- ----------------------------

-- ----------------------------
-- Table structure for ap_user_realname
-- ----------------------------
DROP TABLE IF EXISTS `ap_user_realname`;
CREATE TABLE `ap_user_realname` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` int(11) unsigned DEFAULT NULL COMMENT '账号ID',
`name` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '用户名称',
`idno` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '资源名称',
`font_image` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '正面照片',
`back_image` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '背面照片',
`hold_image` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手持照片',
`live_image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '活体照片',
`status` tinyint(1) unsigned DEFAULT NULL COMMENT '状态\r\n 0 创建中\r\n 1 待审核\r\n 2 审核失败\r\n 9 审核通过',
`reason` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '拒绝原因',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`submited_time` datetime DEFAULT NULL COMMENT '提交时间',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP实名认证信息表';

-- ----------------------------
-- Records of ap_user_realname
-- ----------------------------
INSERT INTO `ap_user_realname` VALUES ('1', '1', 'zhangsan', '512335455602781278', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg', '9', '', '2019-07-30 14:34:28', '2019-07-30 14:34:30', '2019-07-12 06:48:04');
INSERT INTO `ap_user_realname` VALUES ('2', '2', 'lisi', '512335455602781279', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg', '1', '', '2019-07-11 17:21:18', '2019-07-11 17:21:20', '2019-07-12 06:48:04');
INSERT INTO `ap_user_realname` VALUES ('3', '3', 'wangwu6666', '512335455602781276', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg', '9', '', '2019-07-11 17:21:18', '2019-07-11 17:21:20', '2019-07-12 06:48:04');
INSERT INTO `ap_user_realname` VALUES ('5', '5', 'suwukong', '512335455602781279', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbHSAQlqFAAXIZNzAq9E126.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbF6AR16RAAZB2e1EsOg460.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9bbDeAH2qoAAbD_WiUJfk745.jpg', 'http://161.189.111.227/group1/M00/00/00/rBFwgF9ba9qANVEdAAS25KJlEVE291.jpg', '1', '', '2020-08-01 11:10:31', '2020-08-01 11:10:34', '2020-08-01 11:10:36');

搭建项目

删除leadnews-service中的src文件,创建子模块leadnews-user

项目结构如下:

leadnews-service
├── leadnews-user
│ ├── src
│ │ ├── main
│ │ │ ├──/java/com.swx.user
│ │ │ │ ├── config
│ │ │ │ ├── controller.v1
│ │ │ │ ├── mapper
│ │ │ │ ├── service
│ │ │ │ └── UserApplication.java
│ │ │ └── resource
│ │ │ ├── bootstrap.yaml
│ │ │ └── logback.xml
│ │ └── test
│ └── pom.xml
└── pom.xml

添加依赖

在父工程的pom文件中添加如下依赖

pom.xml
<properties>
<leadnew-feign-api.version>0.0.1-SNAPSHOT</leadnew-feign-api.version>
<spring.alibaba.version>2.2.5.RELEASE</spring.alibaba.version>
<mybatis-plus.version>3.4.1</mybatis-plus.version>
<mysql-version>8.0.30</mysql-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.swx</groupId>
<artifactId>leadnews-feign-api</artifactId>
<version>${leadnew-feign-api.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

leadnews-model模块中添加如下依赖:

pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

leadnews-service模块中添加如下依赖:

pom.xml
<dependency>
<groupId>com.swx</groupId>
<artifactId>leadnews-common</artifactId>
</dependency>
<dependency>
<groupId>com.swx</groupId>
<artifactId>leadnews-model</artifactId>
</dependency>
<dependency>
<groupId>com.swx</groupId>
<artifactId>leadnews-feign-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

完善项目

leadnews-service模块的子模块leadnews-user中创建包com.swx.user

创建启动类

UserApplication
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.swx.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}

配置文件

创建配置文件resources/bootstrap.yaml

bootstrap.yaml
server:
port: 51801
spring:
application:
name: leadnews-user
cloud:
nacos:
discovery:
server-addr: xxx.xxx.xxx.xxx:8848
config:
server-addr: xxx.xxx.xxx.xxx:8848
file-extension: yml

其他配置信息使用Nacos配置中心配置,配置完成点击发布即可

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_user?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: root
password: xxxxxx
mybatis-plus:
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.swx.model.user.pojo

配置输入日志,在resources下创建logback.xml

logback.xml
<?xml version="1.0" encoding="UTF-8" ?>

<configuration>
<!-- 定义日志文件的存储地址,使用绝对路径 -->
<property name="LOG_HOME" value="/Users/swcode/Documents/IdeaProjects/server-log" />

<!-- 控制台输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<endcoder>
<!-- 格式化输出:%d表示日期。 %thread表示线程名,%-5level:表示级别从左显示5个字符,%msg:消息日志,%n:换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf8</charset>
</endcoder>
</appender>

<!-- 按照每天生成日志 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志输出的文件名 -->
<fileNamePattern>${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<endcoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</endcoder>
</appender>

<!-- 异步输出 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志,默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能,默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILE" />
</appender>

<logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="org.springframework.boot" level="DEBUG" />
<root level="info">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

接口定义

说明
接口路径 /api/v1/login/login_auth
请求方式 POST
参数 LoginDto
响应结果 R
{
"host": null,
"code": 200,
"message": "操作成功",
"data": {
"user": {
"id": 4,
"name": "admin",
"phone": "13511223456"
},
"token": "...."
}
}

创建实体类

leadnews-model模块下创建com.swx.model.user

user.pojo包下创建ApUser

mojo.ApUser
/**
* <p>
* APP用户信息表
* </>
*
* @author swcode
*/
@Data
@TableName("ap_user")
public class ApUser implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

/**
* 密码、通信加密盐
*/
@TableField("salt")
private String salt;

/**
* 用户名
*/
@TableField("name")
private String name;

/**
* 密码,md5加密
*/
@TableField("password")
private String password;

/**
* 手机号
*/
@TableField("phone")
private String phone;

/**
* 头像
*/
@TableField("image")
private String image;

/**
* 性别 0 男 1 女 2 未知
*/
@TableField("gender")
private Integer gender;

/**
* 是否认证 0 未 1 是
*/
@TableField("is_certification")
private Integer isCertification;

/**
* 是否身份认证
*/
@TableField("is_identity_authentication")
private Integer isIdentityAuthentication;

/**
* 账号状态 0正常 1锁定
*/
@TableField("status")
private Integer status;

/**
* 用户标识 0 普通用户 1 自媒体人 2 大V
*/
@TableField("flag")
private Integer flag;

/**
* 注册时间
*/
@TableField("created_time")
private Date createdTime;
}

user.dto包下创建LoginDTO

user.dto.LoginDTO
@Data
public class LoginDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 手机号
*/
private String phone;
/**
* 密码
*/
private String password;

public LoginDTO() {

}

public LoginDTO(String phone, String password) {
this.phone = phone;
this.password = password;
}
}

user.vo包下创建ApUserVo

vo.ApUserVo
@Data
public class ApUserVo {

private Integer id;
private String name;
private String phone;
private String image;
}

创建Mapper

创建com.swx.user.mapper包,在该包下创建ApUserMapper

ApUserMapper
@Mapper
public interface ApUserMapper extends BaseMapper<ApUser> {

}

创建Service

创建com.swx.user.service包,在该包下创建ApUserService

ApUserService
public interface ApUserService extends IService<ApUser> {

/**
* APP端登陆功能
* @param loginDTO 登陆信息
* @return 用户信息
*/
public Map<String, Object> login(LoginDTO loginDTO);
}

创建com.swx.user.service.impl包,在该包下创建ApUserServiceImpl

ApUserServiceImpl
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

@Override
public Map<String, Object> login(LoginDTO loginDTO) {
if (StringUtils.isBlank(loginDTO.getPhone()) && StringUtils.isBlank(loginDTO.getPassword())) {
// 1. 正常登陆,用户名密码
// 1.1 根据手机号查询用户信息
ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, loginDTO.getPhone()));
if (dbUser == null) {
throw new BizException(ResultCodeEnum.DATA_NOT_EXIST.code(), "用户信息不存在");
}

// 1.2 比对密码
String salt = dbUser.getSalt();
String password = loginDTO.getPassword();
String saltPwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());
if (!saltPwd.equals(dbUser.getPassword())) {
throw new BizException(ResultCodeEnum.LOGIN_PWD_ERROR);
}

// 1.3 返回数据 token
ApUserVo userVo = new ApUserVo();
BeanUtils.copyProperties(dbUser, userVo);
HashMap<String, Object> data = new HashMap<>();
data.put("token", "");
data.put("user", userVo);
return data;
} else {
HashMap<String, Object> data = new HashMap<>();
data.put("token", "");
return data;
}
}
}

创建Controller

创建com.swx.user.controller包,在该包下创建ApUserLoginController

ApUserLoginController
@ResponseResult
@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {

private final ApUserService apUserService;

public ApUserLoginController(ApUserService apUserService) {
this.apUserService = apUserService;
}

@PostMapping("/login_auth")
public Map<String, Object> login(@RequestBody LoginDTO loginDTO) {
return apUserService.login(loginDTO);
}

}