package com.pomelo.backend.qbank.service.impl;
import com.pomelo.backend.qbank.tools.Const;
import com.pomelo.backend.qbank.domain.BaseResponse;
import com.pomelo.backend.qbank.repository.model.User;
import com.pomelo.backend.qbank.repository.mapper.UserMapper;
import com.pomelo.backend.qbank.service.UserService;
import com.pomelo.backend.qbank.tools.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author shishusheng
* @date 2018/5/14 16:00
*/
@Service("UserService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
*
* @param phone
* @param token
* @return
*/
@Override
public BaseResponse login(String phone,String token) {
// 先判断手机号是否存在
int phoneResultCount = userMapper.checkPhone(phone);
// 不存在该手机号则实现 注册逻辑
if(phoneResultCount == 0 ){
User user = new User();
user.setPhone(phone);
// 注册默认普通会员权限
user.setRole(Const.Role.ROLE_CUSTOMER);
// 生成 token
user.setToken(TokenUtil.writeLoginToken(phone));
// 存入 DB
int userResultCount = userMapper.insert(user);
if(userResultCount == 0){
return BaseResponse.newFailResponse().errorMsg("注册失败").errorCode(200).build();
}
}
// 存在该手机号则实现 登录逻辑
// 查token有效性,即是否能根据 phone 及 token 查得存在用户
User user = userMapper.selectLogin(phone,token);
// 失效(不存在)
if(user == null){
return BaseResponse.newFailResponse().errorMsg("token 失效,请重新登录").build();
}
// token有效(存在) : 直接登录
return BaseResponse.newSuccResponse().errorMsg("登录成功").result(user).build();
}
}
<?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="com.pomelo.backend.qbank.repository.mapper.UserMapper" >
<resultMap id="BaseResultMap" type="com.pomelo.backend.qbank.repository.model.User" >
<id column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<result column="phone" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="token" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="nickname" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="role" jdbcType="INTEGER" javaType="java.lang.Integer" />
<result column="status" jdbcType="INTEGER" javaType="java.lang.Integer" />
<result column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
<result column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
</resultMap>
<sql id="Base_Column_List" >
id, phone, nickname, image, role, status, create_time, update_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from user
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from user
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.pomelo.backend.qbank.repository.model.User" >
insert into user (id, phone, nickname, image, role, status, create_time, update_time)
values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{role,jdbcType=INTEGER}, now(),
now())
</insert>
<insert id="insertSelective" parameterType="com.pomelo.backend.qbank.repository.model.User" >
insert into user
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="role != null" >
role,
</if>
<if test="createTime != null" >
create_time,
</if>
<if test="updateTime != null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="username != null" >
#{username,jdbcType=VARCHAR},
</if>
<if test="password != null" >
#{password,jdbcType=VARCHAR},
</if>
<if test="email != null" >
#{email,jdbcType=VARCHAR},
</if>
<if test="phone != null" >
#{phone,jdbcType=VARCHAR},
</if>
<if test="question != null" >
#{question,jdbcType=VARCHAR},
</if>
<if test="answer != null" >
#{answer,jdbcType=VARCHAR},
</if>
<if test="role != null" >
#{role,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
now(),
</if>
<if test="updateTime != null" >
now(),
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.pomelo.backend.qbank.repository.model.User" >
update user
<set >
<if test="username != null" >
username = #{username,jdbcType=VARCHAR},
</if>
<if test="password != null" >
password = #{password,jdbcType=VARCHAR},
</if>
<if test="email != null" >
email = #{email,jdbcType=VARCHAR},
</if>
<if test="phone != null" >
phone = #{phone,jdbcType=VARCHAR},
</if>
<if test="question != null" >
question = #{question,jdbcType=VARCHAR},
</if>
<if test="answer != null" >
answer = #{answer,jdbcType=VARCHAR},
</if>
<if test="role != null" >
role = #{role,jdbcType=INTEGER},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
update_time = now(),
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.pomelo.backend.qbank.repository.model.User" >
update user
set username = #{username,jdbcType=VARCHAR},
phone = #{phone,jdbcType=VARCHAR},
role = #{role,jdbcType=INTEGER},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = now()
where id = #{id,jdbcType=INTEGER}
</update>
<select id="checkPhone" resultType="int" parameterType="string" >
select count(1) from user
where phone = #{phone}
</select>
<select id="selectLogin" resultMap="BaseResultMap" parameterType="map">
SELECT
<include refid="Base_Column_List" />
from user
where phone = #{phone}
and token = #{token}
</select>
</mapper>
#Redis (RedisProperties)
# Redis服务器地址
spring.redis.host=203.195.158.94
# Redis服务器连接密码(默认为空)
spring.redis.password=12345
# Redis服务器连接端口
spring.redis.port=6379
# Redis数据库索引(默认为0)
spring.redis.database=1
# 连接池最大连接数(使用负值或0表无限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=1
# 连接超时时间(毫秒)
spring.redis.timeout=0
#从jedis连接池获取连接时,校验并返回可用的连接
redis.test.borrow=true
#把连接放回jedis连接池时,校验并返回可用的连接
redis.test.return=false
#Redis config end
package com.pomelo.backend.qbank.service;
import com.pomelo.backend.qbank.domain.BaseResponse;
import com.pomelo.backend.qbank.repository.model.User;
/**
* @author shishusheng
* @date 2018/5/14 14:52
*/
public interface UserService {
/**
* 注册/登录
*
* @param phone
* @param token
* @return
*/
BaseResponse login(String phone,String token);
}
package com.pomelo.backend.qbank.tools;
/**
* 所需的各种常量
*
* @author shishusheng
* @date 2018/5/16 15:31
*/
public class Const {
public static final String TOEKN_PREFIX = "token_";
public interface Role{
/**
* 普通用户
*/
int ROLE_CUSTOMER = 0;
/**
* vip 会员
*/
int ROLE_VIP = 1;
}
public interface RedisCacheExtime{
/**
* token有效期 30h
*/
int REDIS_SESSION_EXTIME = 60 * 60 * 30;
}
}
package com.pomelo.backend.qbank.tools;
import java.security.MessageDigest;
/**
* @author shishusheng
* @date 2018/5/17 13:22
*/
public class Md5Util {
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 返回大写MD5
*
* @param origin
* @param charsetName
* @return
*/
private static String MD5Encode(String origin, String charsetName) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetName == null || "".equals(charsetName)) {
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} else {
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetName)));
}
} catch (Exception exception) {
}
return resultString.toUpperCase();
}
private static final String[] hexDigits={"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}
package com.pomelo.backend.qbank.tools;
/**
* @author shishusheng
* @date 2018/5/17 08:59
*/
public class TokenUtil {
/**
* 注册/失效登录 时生成 token
*
* @param phone
*/
public static String writeLoginToken(String phone) {
Long now = System.currentTimeMillis();
String token = phone + now.toString();
return token;
}
}
package com.pomelo.backend.qbank.repository.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* @author shishusheng
* @date 2018/5/14 14:55
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
/**
* 用户主键
*/
private Integer id;
/**
* 用户的手机号,默认作用户名用
*/
private String phone;
/**
* 客户端 token
*/
private String token;
/**
* QQ 网名
*/
private String nickName;
/**
* 用户 QQ 头像
*/
private String image;
/**
* 用户角色权限
*
* 0 : 普通用户
* 1 : vip 会员
*/
private Integer role;
/**
* 用户账户状态
*
* 0 : 正常
* 1 : 封禁
*/
private Integer status;
/**
* 用户注册时间
*/
private Date createTime;
/**
* 用户数据更新时间
*/
private Date updateTime;
}
package com.pomelo.backend.qbank.api.controller;
import com.pomelo.backend.qbank.domain.BaseResponse;
import com.pomelo.backend.qbank.repository.model.User;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author shishusheng
* @date 2018/5/14 14:27
*/
@Api(value="API - UserController",tags={"用户模块接口详情"})
@RestController("/user/")
public class UserController {
@Autowired
private UserService userService;
/**
* 注册 / 登录
*
* @param phone
* @param token
* @return 成功:返回 token
*/
@RequestMapping(value = "login.do", method = RequestMethod.POST)
@ResponseBody
public BaseResponse login(String phone, String token) {
BaseResponse<User> response = userService.login(phone,token);
return response;
}
}
package com.pomelo.backend.qbank.repository.mapper;
import com.pomelo.backend.qbank.repository.model.User;
import org.apache.ibatis.annotations.Param;
/**
* @author shishusheng
* @date 2018/5/14 16:12
*/
public interface UserMapper {
/**
* 检查数据库是否已有此手机号
*
* @param phone
* @return
*/
int checkPhone(String phone);
int deleteByPrimaryKey(Integer id);
/**
* 插入一条新的用户
*
* @param record
* @return
*/
int insert(User record);
User selectLogin(@Param("phone") String phone, @Param("token")String token);
int insertSelective(User record);
User selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(User record);
int updateByPrimaryKey(User record);
}
-- auto-generated definition
create table user
(
id int not null
primary key,
phone varchar(11) null
comment '手机号,默认作用户名用',
nickname varchar(12) null
comment '昵称(默认 QQ 名)',
role char default '0' null,
createtime int null,
update_time datetime null,
image blob null
comment '用户头像',
status tinyint default '0' null
comment '账号状态',
social_type tinyint default '0' null
comment '社交登录绑定类型,默认0:绑定QQ',
social_uuid varchar(20) null,
token varchar(20) null
)
comment '基本用户表';
#Redis (RedisProperties)
# Redis服务器地址
spring.redis.host=203.195.158.94
# Redis服务器连接密码(默认为空)
spring.redis.password=12345
# Redis服务器连接端口
spring.redis.port=6379
# Redis数据库索引(默认为0)
spring.redis.database=1
# 连接池最大连接数(使用负值或0表无限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=1
# 连接超时时间(毫秒)
spring.redis.timeout=0
#从jedis连接池获取连接时,校验并返回可用的连接
redis.test.borrow=true
#把连接放回jedis连接池时,校验并返回可用的连接
redis.test.return=false
#Redis config end