mirror of
https://github.com/201206030/novel-plus.git
synced 2025-07-01 07:16:39 +00:00
Compare commits
146 Commits
release_v1
...
v3.0.2
Author | SHA1 | Date | |
---|---|---|---|
2ce51d5fc0 | |||
2f4b671d84 | |||
6ffd8d90d7 | |||
1e2b6f4103 | |||
24c7175872 | |||
a6b009cc84 | |||
04afa759a7 | |||
1be39a0f13 | |||
2fd0349a80 | |||
79fd85ab9b | |||
0b22bbb111 | |||
7f4d315f25 | |||
f7375c5779 | |||
194461f729 | |||
6bf6b44493 | |||
cffa00a54a | |||
b279763383 | |||
cfe19854a5 | |||
28cebad48d | |||
68a1ece57c | |||
77645da2bd | |||
36376aa623 | |||
9e98665cca | |||
9a19a33406 | |||
a4f7042b87 | |||
31aa3192fd | |||
cd11854eff | |||
85f5048fd9 | |||
f625ee38e1 | |||
2c3e346ea7 | |||
66093cb065 | |||
beba6e5154 | |||
04d3aef82b | |||
018daf8d37 | |||
8e0f1f12a4 | |||
165c96cd48 | |||
e343134ce2 | |||
a1adb2c7df | |||
81a82d8e72 | |||
1d33094bd7 | |||
4cccea5d75 | |||
fbfb68583f | |||
655957904b | |||
99e973091d | |||
5fdf618223 | |||
03c4e6c54b | |||
29527301cf | |||
29d03a7a22 | |||
ad4199dc4e | |||
4f7f9af6a9 | |||
ee2a0f514f | |||
70f04bd37c | |||
9d621edaec | |||
56c0a81c1b | |||
6b3b88c147 | |||
894ee67f56 | |||
a88891b72f | |||
5c7724c813 | |||
79c9f3e0f1 | |||
575142f9f3 | |||
83c2460c83 | |||
c7642ac2ef | |||
5af570a514 | |||
0d96ff81b6 | |||
7733cf1e3f | |||
c9c714e71e | |||
3cbb6bf3fb | |||
750e234f60 | |||
c1d485c42b | |||
0e2e6229cd | |||
f8a669eb01 | |||
6d56399d0f | |||
1a0c1f864b | |||
b193aca288 | |||
7a6d7a4442 | |||
5505840b6e | |||
8eb3048b91 | |||
1b138c2aad | |||
f5e2dbaa6b | |||
b6cb9aaedc | |||
f9f1e474ec | |||
06bf848e99 | |||
6e171d20ed | |||
c62acc288e | |||
9975faed01 | |||
8fde3a3725 | |||
430504ee28 | |||
16447c60ec | |||
be7cbe2d6f | |||
8f1ed88b07 | |||
9b9851e7ab | |||
a55edf0408 | |||
856c4c0667 | |||
e4dd5bcb71 | |||
5dbddbdd96 | |||
73be43e1c5 | |||
ce2a3b4647 | |||
68abdeca93 | |||
0b505a3922 | |||
353cb8c536 | |||
e1e1310b9e | |||
4c42ac0d29 | |||
d025d3d514 | |||
a0fb8e481a | |||
80b933db8d | |||
87a060280a | |||
9c78f400dc | |||
c2cdf73893 | |||
a13ea78c3f | |||
0144b77983 | |||
07b9ffde96 | |||
002a0723f7 | |||
8a628f081f | |||
4aa6b82143 | |||
c80b02caf0 | |||
5e16119880 | |||
231b94f1da | |||
92ce982899 | |||
8c2e43c04f | |||
f553d23fb9 | |||
9773b73475 | |||
5543b905cd | |||
e273906441 | |||
83dc04c50b | |||
b4f5b18e93 | |||
fe80c21812 | |||
4c2a7f12c1 | |||
e24e87b546 | |||
b8b074d40a | |||
a662f42bcf | |||
0fa929f9de | |||
401d23871d | |||
4878f17de8 | |||
e9ab6d8bb0 | |||
c8d7a10d9f | |||
d30c6bfd6e | |||
334f3e17a6 | |||
a202100818 | |||
84814e0792 | |||
dde10c983e | |||
c9428bf0e7 | |||
0e2e610d18 | |||
9df69edc2c | |||
16aa925521 | |||
320d693238 | |||
ca9fd1c2f7 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -10,3 +10,9 @@
|
||||
/novel-front/novel-front.iml
|
||||
/novel-crawl/novel-crawl.iml
|
||||
/novel-crawl/target
|
||||
/novel-admin/target
|
||||
/*.iml
|
||||
/novel-admin/*.iml
|
||||
.DS_Store
|
||||
/novel-admin/cachedata
|
||||
/novel-admin/logs
|
||||
|
@ -0,0 +1,135 @@
|
||||
package com.java2nb.system.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import com.java2nb.system.service.UserService;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2020-12-01 03:46:33
|
||||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/system/user")
|
||||
public class UserController {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("system:user:user")
|
||||
String User() {
|
||||
return "system/user/user";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取列表", notes = "获取列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("system:user:user")
|
||||
public R list(@RequestParam Map<String, Object> params) {
|
||||
//查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<UserDO> userList = userService.list(query);
|
||||
int total = userService.count(query);
|
||||
PageBean pageBean = new PageBean(userList, total);
|
||||
return R.ok().put("data", pageBean);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "新增页面", notes = "新增页面")
|
||||
@GetMapping("/add")
|
||||
@RequiresPermissions("system:user:add")
|
||||
String add() {
|
||||
return "system/user/add";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改页面", notes = "修改页面")
|
||||
@GetMapping("/edit/{id}")
|
||||
@RequiresPermissions("system:user:edit")
|
||||
String edit(@PathVariable("id") Long id, Model model) {
|
||||
UserDO user = userService.get(id);
|
||||
model.addAttribute("user", user);
|
||||
return "system/user/edit";
|
||||
}
|
||||
|
||||
@ApiOperation(value = "查看页面", notes = "查看页面")
|
||||
@GetMapping("/detail/{id}")
|
||||
@RequiresPermissions("system:user:detail")
|
||||
String detail(@PathVariable("id") Long id, Model model) {
|
||||
UserDO user = userService.get(id);
|
||||
model.addAttribute("user", user);
|
||||
return "system/user/detail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ApiOperation(value = "新增", notes = "新增")
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("system:user:add")
|
||||
public R save( UserDO user) {
|
||||
if (userService.save(user) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@ApiOperation(value = "修改", notes = "修改")
|
||||
@ResponseBody
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("system:user:edit")
|
||||
public R update( UserDO user) {
|
||||
userService.update(user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@ApiOperation(value = "删除", notes = "删除")
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("system:user:remove")
|
||||
public R remove( Long id) {
|
||||
if (userService.remove(id) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@ApiOperation(value = "批量删除", notes = "批量删除")
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("system:user:batchRemove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
userService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.system.dao;
|
||||
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2020-12-01 03:46:33
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserDao {
|
||||
|
||||
UserDO get(Long id);
|
||||
|
||||
List<UserDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(UserDO user);
|
||||
|
||||
int update(UserDO user);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
package com.java2nb.system.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2020-12-01 03:46:33
|
||||
*/
|
||||
public class UserDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
//主键
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long id;
|
||||
//登录名
|
||||
private String username;
|
||||
//登录密码
|
||||
private String password;
|
||||
//昵称
|
||||
private String nickName;
|
||||
//用户头像
|
||||
private String userPhoto;
|
||||
//用户性别,0:男,1:女
|
||||
private Integer userSex;
|
||||
//账户余额
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long accountBalance;
|
||||
//用户状态,0:正常
|
||||
private Integer status;
|
||||
//创建时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
//更新时间
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 设置:主键
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* 获取:主键
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* 设置:登录名
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
/**
|
||||
* 获取:登录名
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
/**
|
||||
* 设置:登录密码
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
/**
|
||||
* 获取:登录密码
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
/**
|
||||
* 设置:昵称
|
||||
*/
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
/**
|
||||
* 获取:昵称
|
||||
*/
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
/**
|
||||
* 设置:用户头像
|
||||
*/
|
||||
public void setUserPhoto(String userPhoto) {
|
||||
this.userPhoto = userPhoto;
|
||||
}
|
||||
/**
|
||||
* 获取:用户头像
|
||||
*/
|
||||
public String getUserPhoto() {
|
||||
return userPhoto;
|
||||
}
|
||||
/**
|
||||
* 设置:用户性别,0:男,1:女
|
||||
*/
|
||||
public void setUserSex(Integer userSex) {
|
||||
this.userSex = userSex;
|
||||
}
|
||||
/**
|
||||
* 获取:用户性别,0:男,1:女
|
||||
*/
|
||||
public Integer getUserSex() {
|
||||
return userSex;
|
||||
}
|
||||
/**
|
||||
* 设置:账户余额
|
||||
*/
|
||||
public void setAccountBalance(Long accountBalance) {
|
||||
this.accountBalance = accountBalance;
|
||||
}
|
||||
/**
|
||||
* 获取:账户余额
|
||||
*/
|
||||
public Long getAccountBalance() {
|
||||
return accountBalance;
|
||||
}
|
||||
/**
|
||||
* 设置:用户状态,0:正常
|
||||
*/
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
/**
|
||||
* 获取:用户状态,0:正常
|
||||
*/
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
/**
|
||||
* 设置:更新时间
|
||||
*/
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
/**
|
||||
* 获取:更新时间
|
||||
*/
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.java2nb.system.service;
|
||||
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2020-12-01 03:46:33
|
||||
*/
|
||||
public interface UserService {
|
||||
|
||||
UserDO get(Long id);
|
||||
|
||||
List<UserDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(UserDO user);
|
||||
|
||||
int update(UserDO user);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.java2nb.system.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.system.dao.UserDao;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import com.java2nb.system.service.UserService;
|
||||
|
||||
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
@Override
|
||||
public UserDO get(Long id){
|
||||
return userDao.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserDO> list(Map<String, Object> map){
|
||||
return userDao.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map){
|
||||
return userDao.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(UserDO user){
|
||||
return userDao.save(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(UserDO user){
|
||||
return userDao.update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id){
|
||||
return userDao.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return userDao.batchRemove(ids);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
<?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.java2nb.system.dao.UserDao">
|
||||
|
||||
<select id="get" resultType="com.java2nb.system.domain.UserDO">
|
||||
select `id`,`username`,`password`,`nick_name`,`user_photo`,`user_sex`,`account_balance`,`status`,`create_time`,`update_time` from user where id = #{value}
|
||||
</select>
|
||||
|
||||
<select id="list" resultType="com.java2nb.system.domain.UserDO">
|
||||
select `id`,`username`,`password`,`nick_name`,`user_photo`,`user_sex`,`account_balance`,`status`,`create_time`,`update_time` from user
|
||||
<where>
|
||||
<if test="id != null and id != ''"> and id = #{id} </if>
|
||||
<if test="username != null and username != ''"> and username = #{username} </if>
|
||||
<if test="password != null and password != ''"> and password = #{password} </if>
|
||||
<if test="nickName != null and nickName != ''"> and nick_name = #{nickName} </if>
|
||||
<if test="userPhoto != null and userPhoto != ''"> and user_photo = #{userPhoto} </if>
|
||||
<if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if>
|
||||
<if test="accountBalance != null and accountBalance != ''"> and account_balance = #{accountBalance} </if>
|
||||
<if test="status != null and status != ''"> and status = #{status} </if>
|
||||
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
|
||||
<if test="updateTime != null and updateTime != ''"> and update_time = #{updateTime} </if>
|
||||
</where>
|
||||
<choose>
|
||||
<when test="sort != null and sort.trim() != ''">
|
||||
order by ${sort} ${order}
|
||||
</when>
|
||||
<otherwise>
|
||||
order by id desc
|
||||
</otherwise>
|
||||
</choose>
|
||||
<if test="offset != null and limit != null">
|
||||
limit #{offset}, #{limit}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="count" resultType="int">
|
||||
select count(*) from user
|
||||
<where>
|
||||
<if test="id != null and id != ''"> and id = #{id} </if>
|
||||
<if test="username != null and username != ''"> and username = #{username} </if>
|
||||
<if test="password != null and password != ''"> and password = #{password} </if>
|
||||
<if test="nickName != null and nickName != ''"> and nick_name = #{nickName} </if>
|
||||
<if test="userPhoto != null and userPhoto != ''"> and user_photo = #{userPhoto} </if>
|
||||
<if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if>
|
||||
<if test="accountBalance != null and accountBalance != ''"> and account_balance = #{accountBalance} </if>
|
||||
<if test="status != null and status != ''"> and status = #{status} </if>
|
||||
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
|
||||
<if test="updateTime != null and updateTime != ''"> and update_time = #{updateTime} </if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<insert id="save" parameterType="com.java2nb.system.domain.UserDO">
|
||||
insert into user
|
||||
(
|
||||
`id`,
|
||||
`username`,
|
||||
`password`,
|
||||
`nick_name`,
|
||||
`user_photo`,
|
||||
`user_sex`,
|
||||
`account_balance`,
|
||||
`status`,
|
||||
`create_time`,
|
||||
`update_time`
|
||||
)
|
||||
values
|
||||
(
|
||||
#{id},
|
||||
#{username},
|
||||
#{password},
|
||||
#{nickName},
|
||||
#{userPhoto},
|
||||
#{userSex},
|
||||
#{accountBalance},
|
||||
#{status},
|
||||
#{createTime},
|
||||
#{updateTime}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="saveSelective" parameterType="com.java2nb.system.domain.UserDO">
|
||||
insert into user
|
||||
(
|
||||
<if test="id != null"> `id`, </if>
|
||||
<if test="username != null"> `username`, </if>
|
||||
<if test="password != null"> `password`, </if>
|
||||
<if test="nickName != null"> `nick_name`, </if>
|
||||
<if test="userPhoto != null"> `user_photo`, </if>
|
||||
<if test="userSex != null"> `user_sex`, </if>
|
||||
<if test="accountBalance != null"> `account_balance`, </if>
|
||||
<if test="status != null"> `status`, </if>
|
||||
<if test="createTime != null"> `create_time`, </if>
|
||||
<if test="updateTime != null"> `update_time` </if>
|
||||
)
|
||||
values
|
||||
(
|
||||
<if test="id != null"> #{id}, </if>
|
||||
<if test="username != null"> #{username}, </if>
|
||||
<if test="password != null"> #{password}, </if>
|
||||
<if test="nickName != null"> #{nickName}, </if>
|
||||
<if test="userPhoto != null"> #{userPhoto}, </if>
|
||||
<if test="userSex != null"> #{userSex}, </if>
|
||||
<if test="accountBalance != null"> #{accountBalance}, </if>
|
||||
<if test="status != null"> #{status}, </if>
|
||||
<if test="createTime != null"> #{createTime}, </if>
|
||||
<if test="updateTime != null"> #{updateTime} </if>
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.java2nb.system.domain.UserDO">
|
||||
update user
|
||||
<set>
|
||||
<if test="username != null">`username` = #{username}, </if>
|
||||
<if test="password != null">`password` = #{password}, </if>
|
||||
<if test="nickName != null">`nick_name` = #{nickName}, </if>
|
||||
<if test="userPhoto != null">`user_photo` = #{userPhoto}, </if>
|
||||
<if test="userSex != null">`user_sex` = #{userSex}, </if>
|
||||
<if test="accountBalance != null">`account_balance` = #{accountBalance}, </if>
|
||||
<if test="status != null">`status` = #{status}, </if>
|
||||
<if test="createTime != null">`create_time` = #{createTime}, </if>
|
||||
<if test="updateTime != null">`update_time` = #{updateTime}</if>
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="remove">
|
||||
delete from user where id = #{value}
|
||||
</delete>
|
||||
|
||||
<delete id="batchRemove">
|
||||
delete from user where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -0,0 +1,107 @@
|
||||
var E = window.wangEditor;
|
||||
$("[id^='contentEditor']").each(function (index, ele) {
|
||||
var relName = $(ele).attr("id").substring(13);
|
||||
var editor = new E('#contentEditor' + relName);
|
||||
// 自定义菜单配置
|
||||
editor.customConfig.menus = [
|
||||
'head', // 标题
|
||||
'bold', // 粗体
|
||||
'fontSize', // 字号
|
||||
'fontName', // 字体
|
||||
'italic', // 斜体
|
||||
'underline', // 下划线
|
||||
'strikeThrough', // 删除线
|
||||
'foreColor', // 文字颜色
|
||||
//'backColor', // 背景颜色
|
||||
//'link', // 插入链接
|
||||
'list', // 列表
|
||||
'justify', // 对齐方式
|
||||
'quote', // 引用
|
||||
'emoticon', // 表情
|
||||
'image', // 插入图片
|
||||
//'table', // 表格
|
||||
//'video', // 插入视频
|
||||
//'code', // 插入代码
|
||||
'undo', // 撤销
|
||||
'redo' // 重复
|
||||
];
|
||||
editor.customConfig.onchange = function (html) {
|
||||
// html 即变化之后的内容
|
||||
$("#" + relName).val(html);
|
||||
}
|
||||
editor.customConfig.uploadImgShowBase64 = true;
|
||||
editor.create();
|
||||
|
||||
})
|
||||
|
||||
$("[id^='picImage']").each(function (index, ele) {
|
||||
var relName = $(ele).attr("id").substring(8);
|
||||
layui.use('upload', function () {
|
||||
var upload = layui.upload;
|
||||
//执行实例
|
||||
var uploadInst = upload.render({
|
||||
elem: '#picImage' + relName, //绑定元素
|
||||
url: '/common/sysFile/upload', //上传接口
|
||||
size: 1000,
|
||||
accept: 'file',
|
||||
done: function (r) {
|
||||
$("#picImage" + relName).attr("src", r.fileName);
|
||||
$("#" + relName).val(r.fileName);
|
||||
},
|
||||
error: function (r) {
|
||||
layer.msg(r.msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$().ready(function () {
|
||||
validateRule();
|
||||
});
|
||||
|
||||
$.validator.setDefaults({
|
||||
submitHandler: function () {
|
||||
save();
|
||||
}
|
||||
});
|
||||
function save() {
|
||||
$.ajax({
|
||||
cache: true,
|
||||
type: "POST",
|
||||
url: "/system/user/save",
|
||||
data: $('#signupForm').serialize(),// 你的formid
|
||||
async: false,
|
||||
error: function (request) {
|
||||
parent.layer.alert("Connection error");
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
parent.layer.msg("操作成功");
|
||||
parent.reLoad();
|
||||
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
|
||||
parent.layer.close(index);
|
||||
|
||||
} else {
|
||||
parent.layer.alert(data.msg)
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
function validateRule() {
|
||||
var icon = "<i class='fa fa-times-circle'></i> ";
|
||||
$("#signupForm").validate({
|
||||
ignore: "",
|
||||
rules: {
|
||||
},
|
||||
messages: {
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
var E = window.wangEditor;
|
||||
$("[id^='contentEditor']").each(function (index, ele) {
|
||||
var relName = $(ele).attr("id").substring(13);
|
||||
var editor = new E('#contentEditor' + relName);
|
||||
// 自定义菜单配置
|
||||
editor.customConfig.menus = [
|
||||
'head', // 标题
|
||||
'bold', // 粗体
|
||||
'fontSize', // 字号
|
||||
'fontName', // 字体
|
||||
'italic', // 斜体
|
||||
'underline', // 下划线
|
||||
'strikeThrough', // 删除线
|
||||
'foreColor', // 文字颜色
|
||||
//'backColor', // 背景颜色
|
||||
//'link', // 插入链接
|
||||
'list', // 列表
|
||||
'justify', // 对齐方式
|
||||
'quote', // 引用
|
||||
'emoticon', // 表情
|
||||
'image', // 插入图片
|
||||
//'table', // 表格
|
||||
//'video', // 插入视频
|
||||
//'code', // 插入代码
|
||||
'undo', // 撤销
|
||||
'redo' // 重复
|
||||
];
|
||||
editor.customConfig.onchange = function (html) {
|
||||
// html 即变化之后的内容
|
||||
$("#" + relName).val(html);
|
||||
}
|
||||
editor.customConfig.uploadImgShowBase64 = true;
|
||||
editor.create();
|
||||
editor.txt.html($("#" + relName).val());
|
||||
|
||||
})
|
||||
|
||||
$("[id^='picImage']").each(function (index, ele) {
|
||||
var relName = $(ele).attr("id").substring(8);
|
||||
layui.use('upload', function () {
|
||||
var upload = layui.upload;
|
||||
//执行实例
|
||||
var uploadInst = upload.render({
|
||||
elem: '#picImage' + relName, //绑定元素
|
||||
url: '/common/sysFile/upload', //上传接口
|
||||
size: 1000,
|
||||
accept: 'file',
|
||||
done: function (r) {
|
||||
$("#picImage" + relName).attr("src", r.fileName);
|
||||
$("#" + relName).val(r.fileName);
|
||||
},
|
||||
error: function (r) {
|
||||
layer.msg(r.msg);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$().ready(function () {
|
||||
validateRule();
|
||||
});
|
||||
|
||||
$.validator.setDefaults({
|
||||
submitHandler: function () {
|
||||
update();
|
||||
}
|
||||
});
|
||||
function update() {
|
||||
$.ajax({
|
||||
cache: true,
|
||||
type: "POST",
|
||||
url: "/system/user/update",
|
||||
data: $('#signupForm').serialize(),// 你的formid
|
||||
async: false,
|
||||
error: function (request) {
|
||||
parent.layer.alert("Connection error");
|
||||
},
|
||||
success: function (data) {
|
||||
if (data.code == 0) {
|
||||
parent.layer.msg("操作成功");
|
||||
parent.reLoad();
|
||||
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
|
||||
parent.layer.close(index);
|
||||
|
||||
} else {
|
||||
parent.layer.alert(data.msg)
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
function validateRule() {
|
||||
var icon = "<i class='fa fa-times-circle'></i> ";
|
||||
$("#signupForm").validate({
|
||||
ignore: "",
|
||||
rules: {
|
||||
},
|
||||
messages: {
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
var prefix = "/system/user"
|
||||
$(function () {
|
||||
load();
|
||||
});
|
||||
|
||||
function load() {
|
||||
$('#exampleTable')
|
||||
.bootstrapTable(
|
||||
{
|
||||
method: 'get', // 服务器数据的请求方式 get or post
|
||||
url: prefix + "/list", // 服务器数据的加载地址
|
||||
// showRefresh : true,
|
||||
// showToggle : true,
|
||||
// showColumns : true,
|
||||
iconSize: 'outline',
|
||||
toolbar: '#exampleToolbar',
|
||||
striped: true, // 设置为true会有隔行变色效果
|
||||
dataType: "json", // 服务器返回的数据类型
|
||||
pagination: true, // 设置为true会在底部显示分页条
|
||||
// queryParamsType : "limit",
|
||||
// //设置为limit则会发送符合RESTFull格式的参数
|
||||
singleSelect: false, // 设置为true将禁止多选
|
||||
// contentType : "application/x-www-form-urlencoded",
|
||||
// //发送到服务器的数据编码类型
|
||||
pageSize: 10, // 如果设置了分页,每页数据条数
|
||||
pageNumber: 1, // 如果设置了分布,首页页码
|
||||
//search : true, // 是否显示搜索框
|
||||
showColumns: false, // 是否显示内容下拉框(选择显示的列)
|
||||
sidePagination: "server", // 设置在哪里进行分页,可选值为"client" 或者 "server"
|
||||
queryParams: function (params) {
|
||||
//说明:传入后台的参数包括offset开始索引,limit步长,sort排序列,order:desc或者,以及所有列的键值对
|
||||
var queryParams = getFormJson("searchForm");
|
||||
queryParams.limit = params.limit;
|
||||
queryParams.offset = params.offset;
|
||||
return queryParams;
|
||||
},
|
||||
// //请求服务器数据时,你可以通过重写参数的方式添加一些额外的参数,例如 toolbar 中的参数 如果
|
||||
// queryParamsType = 'limit' ,返回参数必须包含
|
||||
// limit, offset, search, sort, order 否则, 需要包含:
|
||||
// pageSize, pageNumber, searchText, sortName,
|
||||
// sortOrder.
|
||||
// 返回false将会终止请求
|
||||
responseHandler: function (rs) {
|
||||
|
||||
if (rs.code == 0) {
|
||||
return rs.data;
|
||||
} else {
|
||||
parent.layer.alert(rs.msg)
|
||||
return {total: 0, rows: []};
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
title: '序号',
|
||||
formatter: function () {
|
||||
return arguments[2] + 1;
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: '主键'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'username',
|
||||
title: '登录名'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'password',
|
||||
title: '登录密码'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'nickName',
|
||||
title: '昵称'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'userPhoto',
|
||||
title: '用户头像'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'userSex',
|
||||
title: '用户性别,0:男,1:女'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'accountBalance',
|
||||
title: '账户余额'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'status',
|
||||
title: '用户状态,0:正常'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'createTime',
|
||||
title: '创建时间'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
field: 'updateTime',
|
||||
title: '更新时间'
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: '操作',
|
||||
field: 'id',
|
||||
align: 'center',
|
||||
formatter: function (value, row, index) {
|
||||
var d = '<a class="btn btn-primary btn-sm ' + s_detail_h + '" href="#" mce_href="#" title="详情" onclick="detail(\''
|
||||
+ row.id
|
||||
+ '\')"><i class="fa fa-file"></i></a> ';
|
||||
var e = '<a class="btn btn-primary btn-sm ' + s_edit_h + '" href="#" mce_href="#" title="编辑" onclick="edit(\''
|
||||
+ row.id
|
||||
+ '\')"><i class="fa fa-edit"></i></a> ';
|
||||
var r = '<a class="btn btn-warning btn-sm ' + s_remove_h + '" href="#" title="删除" mce_href="#" onclick="remove(\''
|
||||
+ row.id
|
||||
+ '\')"><i class="fa fa-remove"></i></a> ';
|
||||
return d + e + r;
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
function reLoad() {
|
||||
$('#exampleTable').bootstrapTable('refresh');
|
||||
}
|
||||
function add() {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '增加',
|
||||
maxmin: true,
|
||||
shadeClose: false, // 点击遮罩关闭层
|
||||
area: ['800px', '520px'],
|
||||
content: prefix + '/add' // iframe的url
|
||||
});
|
||||
}
|
||||
function detail(id) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '详情',
|
||||
maxmin: true,
|
||||
shadeClose: false, // 点击遮罩关闭层
|
||||
area: ['800px', '520px'],
|
||||
content: prefix + '/detail/' + id // iframe的url
|
||||
});
|
||||
}
|
||||
function edit(id) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '编辑',
|
||||
maxmin: true,
|
||||
shadeClose: false, // 点击遮罩关闭层
|
||||
area: ['800px', '520px'],
|
||||
content: prefix + '/edit/' + id // iframe的url
|
||||
});
|
||||
}
|
||||
function remove(id) {
|
||||
layer.confirm('确定要删除选中的记录?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function () {
|
||||
$.ajax({
|
||||
url: prefix + "/remove",
|
||||
type: "post",
|
||||
data: {
|
||||
'id': id
|
||||
},
|
||||
success: function (r) {
|
||||
if (r.code == 0) {
|
||||
layer.msg(r.msg);
|
||||
reLoad();
|
||||
} else {
|
||||
layer.msg(r.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function resetPwd(id) {
|
||||
}
|
||||
function batchRemove() {
|
||||
var rows = $('#exampleTable').bootstrapTable('getSelections'); // 返回所有选择的行,当没有选择的记录时,返回一个空数组
|
||||
if (rows.length == 0) {
|
||||
layer.msg("请选择要删除的数据");
|
||||
return;
|
||||
}
|
||||
layer.confirm("确认要删除选中的'" + rows.length + "'条数据吗?", {
|
||||
btn: ['确定', '取消']
|
||||
// 按钮
|
||||
}, function () {
|
||||
var ids = new Array();
|
||||
// 遍历所有选择的行数据,取每条数据对应的ID
|
||||
$.each(rows, function (i, row) {
|
||||
ids[i] = row['id'];
|
||||
});
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
data: {
|
||||
"ids": ids
|
||||
},
|
||||
url: prefix + '/batchRemove',
|
||||
success: function (r) {
|
||||
if (r.code == 0) {
|
||||
layer.msg(r.msg);
|
||||
reLoad();
|
||||
} else {
|
||||
layer.msg(r.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, function () {
|
||||
|
||||
});
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
-- 菜单SQL
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
VALUES ('1', '', 'system/user', 'system:user:user', '1', 'fa', '6');
|
||||
|
||||
-- 按钮父菜单ID
|
||||
set @parentId = @@identity;
|
||||
|
||||
-- 菜单对应按钮SQL
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '查看', null, 'system:user:detail', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '新增', null, 'system:user:add', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '修改', null, 'system:user:edit', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '删除', null, 'system:user:remove', '2', null, '6';
|
||||
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
|
||||
SELECT @parentId, '批量删除', null, 'system:user:batchRemove', '2', null, '6';
|
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head th:include="include :: header"></head>
|
||||
<body class="gray-bg">
|
||||
<div class="wrapper wrapper-content ">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-content">
|
||||
<form class="form-horizontal m-t" id="signupForm">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="username" name="username"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录密码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="password" name="password"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">昵称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="nickName" name="nickName"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户头像:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="userPhoto" name="userPhoto"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户性别,0:男,1:女:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="userSex" name="userSex"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">账户余额:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="accountBalance" name="accountBalance"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户状态,0:正常:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="status" name="status"
|
||||
class="form-control"
|
||||
type="text">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">创建时间:</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="laydate-icon layer-date form-control"
|
||||
id="createTime"
|
||||
name="createTime"
|
||||
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
|
||||
style="background-color: #fff;" readonly="readonly"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">更新时间:</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="laydate-icon layer-date form-control"
|
||||
id="updateTime"
|
||||
name="updateTime"
|
||||
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
|
||||
style="background-color: #fff;" readonly="readonly"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-8 col-sm-offset-3">
|
||||
<button type="submit" class="btn btn-primary">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:include="include::footer"></div>
|
||||
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
|
||||
<script type="text/javascript" src="/js/appjs/system/user/add.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head th:include="include :: header"></head>
|
||||
<body class="gray-bg">
|
||||
<div class="wrapper wrapper-content ">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-content">
|
||||
<form class="form-horizontal m-t" id="signupForm">
|
||||
<input id="id" name="id" th:value="${user.id}"
|
||||
type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录名:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.username}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录密码:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.password}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">昵称:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.nickName}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户头像:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.userPhoto}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户性别,0:男,1:女:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.userSex}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">账户余额:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.accountBalance}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户状态,0:正常:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.status}">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">创建时间:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.createTime}==null?null:${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">更新时间:</label>
|
||||
|
||||
<div style="padding-top:8px" class="col-sm-8"
|
||||
th:text="${user.updateTime}==null?null:${#dates.format(user.updateTime,'yyyy-MM-dd HH:mm:ss')}">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:include="include::footer"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head th:include="include :: header"></head>
|
||||
<body class="gray-bg">
|
||||
<div class="wrapper wrapper-content ">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-content">
|
||||
<form class="form-horizontal m-t" id="signupForm">
|
||||
<input id="id" name="id" th:value="${user.id}"
|
||||
type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="username" name="username"
|
||||
th:value="${user.username}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">登录密码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="password" name="password"
|
||||
th:value="${user.password}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">昵称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="nickName" name="nickName"
|
||||
th:value="${user.nickName}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户头像:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="userPhoto" name="userPhoto"
|
||||
th:value="${user.userPhoto}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户性别,0:男,1:女:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="userSex" name="userSex"
|
||||
th:value="${user.userSex}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">账户余额:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="accountBalance" name="accountBalance"
|
||||
th:value="${user.accountBalance}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">用户状态,0:正常:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="status" name="status"
|
||||
th:value="${user.status}"
|
||||
class="form-control"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">创建时间:</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="laydate-icon layer-date form-control"
|
||||
id="createTime"
|
||||
name="createTime"
|
||||
th:value="${user.createTime}==null?null:${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"
|
||||
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
|
||||
style="background-color: #fff;" readonly="readonly"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">更新时间:</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="laydate-icon layer-date form-control"
|
||||
id="updateTime"
|
||||
name="updateTime"
|
||||
th:value="${user.updateTime}==null?null:${#dates.format(user.updateTime,'yyyy-MM-dd HH:mm:ss')}"
|
||||
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
|
||||
style="background-color: #fff;" readonly="readonly"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-8 col-sm-offset-3">
|
||||
<button type="submit" class="btn btn-primary">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:include="include::footer"></div>
|
||||
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
|
||||
<script type="text/javascript" src="/js/appjs/system/user/edit.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head th:include="include :: header"></head>
|
||||
<body class="gray-bg">
|
||||
<div class="wrapper wrapper-content ">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox">
|
||||
<div class="ibox-body">
|
||||
<div class="fixed-table-toolbar">
|
||||
<div class="columns pull-left">
|
||||
<button shiro:hasPermission="system:user:add" type="button"
|
||||
class="btn btn-primary" onclick="add()">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i>添加
|
||||
</button>
|
||||
<button shiro:hasPermission="system:user:batchRemove" type="button"
|
||||
class="btn btn-danger"
|
||||
onclick="batchRemove()">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>删除
|
||||
</button>
|
||||
</div>
|
||||
<div class="columns pull-right">
|
||||
<button class="btn btn-success" onclick="reLoad()">查询</button>
|
||||
</div>
|
||||
|
||||
<form id="searchForm">
|
||||
<div class="columns pull-right col-md-2">
|
||||
<input id="id" name="id" type="text" class="form-control"
|
||||
placeholder="主键">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<table id="exampleTable" data-mobile-responsive="true">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--shiro控制bootstraptable行内按钮看见性 -->
|
||||
<div>
|
||||
<script type="text/javascript">
|
||||
var s_detail_h = 'hidden';
|
||||
var s_edit_h = 'hidden';
|
||||
var s_remove_h = 'hidden';
|
||||
</script>
|
||||
</div>
|
||||
<div shiro:hasPermission="test:order:detail">
|
||||
<script type="text/javascript">
|
||||
s_detail_h = '';
|
||||
</script>
|
||||
</div>
|
||||
<div shiro:hasPermission="system:user:edit">
|
||||
<script type="text/javascript">
|
||||
s_edit_h = '';
|
||||
</script>
|
||||
</div>
|
||||
<div shiro:hasPermission="system:user:remove">
|
||||
<script type="text/javascript">
|
||||
var s_remove_h = '';
|
||||
</script>
|
||||
</div>
|
||||
<div th:include="include :: footer"></div>
|
||||
<script type="text/javascript" src="/js/appjs/system/user/user.js"></script>
|
||||
</body>
|
||||
</html>
|
159
README.md
159
README.md
@ -1,16 +1,29 @@
|
||||
[](https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console)
|
||||
[]( https://cloud.tencent.com/act/cps/redirect?redirect=1052&cps_key=736e609d66e0ac4e57813316cec6fd0b&from=console )
|
||||
|
||||
# 小说精品屋-plus
|
||||
|
||||
#### 新项目:小说精品屋-微服务版
|
||||
|
||||
基于小说精品屋-plus构建的Spring Cloud 微服务小说门户平台。
|
||||
|
||||
Gitee仓库地址: https://gitee.com/xiongxyang/novel-cloud
|
||||
|
||||
GitHub仓库地址: https://github.com/201206030/novel-cloud
|
||||
|
||||
#### 演示地址
|
||||
|
||||
[点击前往](http://47.106.243.172:8888/)
|
||||
|
||||
|
||||
#### 前言
|
||||
|
||||
小说精品屋-plus致力于打造一个完整的商用小说门户平台。
|
||||
小说精品屋-plus致力于打造一个完整的商用小说门户平台,使用前建议先阅读此文档。
|
||||
|
||||
#### 项目介绍
|
||||
|
||||
[小说精品屋](https://github.com/201206030/fiction_house)是一个多平台(web、安卓app、微信小程序)、功能完善的小说弹幕网站,包含精品小说专区、轻小说专区和漫画专区。包括小说/漫画分类、小说/漫画搜索、小说/漫画排行、完本小说/漫画、小说/漫画评分、小说/漫画在线阅读、小说/漫画书架、小说/漫画阅读记录、小说下载、小说弹幕、小说/漫画自动爬取、小说内容自动分享到微博、邮件自动推广、链接自动推送到百度搜索引擎等功能。包含电脑端、移动端、微信小程序等多个平台,现已开源web端、安卓端、小程序端源码。
|
||||
小说精品屋-plus是在[小说精品屋](https://github.com/201206030/fiction_house)的基础上,去除了漫画和弹幕模块,专注于小说,是一个多端(PC、移动)阅读、功能完善的小说原创/爬虫网站项目,既包含了作家专区供原创作者上传小说,又提供了爬虫工具通过规则多线程全自动采集任意小说网站数据(已兼容99%的小说网站),新书自动入库,老书自动更新。
|
||||
|
||||
小说精品屋-plus是在小说精品屋的基础上,重新进行了数据库设计、代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性。主要升级如下:
|
||||
小说精品屋-plus重新进行了数据库设计、代码重构和功能增强,提升了程序整体的可读性和性能,增加了很多商用特性。主要升级如下:
|
||||
|
||||
- [x] 数据库重新设计,结构调整。
|
||||
- [x] 服务端代码重构,MyBatis3升级为MyBatis3DynamicSql。
|
||||
@ -20,9 +33,10 @@
|
||||
- [x] 排行榜。
|
||||
- [x] 小说评论模块。
|
||||
- [x] 阅读主题模块。
|
||||
- [ ] 作家专区。
|
||||
- [ ] 充值。
|
||||
- [ ] 后台管理系统。
|
||||
- [x] 作家专区。
|
||||
- [x] 充值。
|
||||
- [x] 订阅。
|
||||
- [x] 后台管理系统。
|
||||
- [x] 爬虫管理系统。
|
||||
|
||||
#### 项目结构
|
||||
@ -36,53 +50,119 @@ novel-plus -- 父工程
|
||||
```
|
||||
|
||||
#### 技术选型
|
||||
Springboot+Mybatis+Mysql+Ehcache+Thymeleaf+Layui
|
||||
|
||||
| 技术 | 说明
|
||||
| -------------------- | ---------------------------
|
||||
| SpringBoot | Spring应用快速开发脚手架
|
||||
| MyBatis | 持久层ORM框架
|
||||
| MyBatis Dynamic SQL | Mybatis动态sql
|
||||
| PageHelper | MyBatis分页插件
|
||||
| MyBatisGenerator | 持久层代码生成插件
|
||||
| Sharding-Jdbc | 代码层分库分表中间件
|
||||
| JJWT | JWT登录支持
|
||||
| SpringSecurity | 安全框架
|
||||
| Shiro | 安全框架
|
||||
| Ehcache | Java进程内缓存框架(默认缓存)
|
||||
| Redis | 分布式缓存(缓存替换方案,默认关闭,一行配置开启)
|
||||
| ElasticSearch | 搜索引擎(搜索增强方案,默认关闭,一行配置开启)
|
||||
| RabbitMq | 消息队列(流量削峰,默认关闭,一行配置开启)
|
||||
| OSS | 阿里云对象存储服务(图片存储方式之一,一行配置即可切换)
|
||||
| FastDfs |开源轻量级分布式文件系统(图片存储方式之一,一行配置即可切换)
|
||||
| Redisson | 实现分布式锁
|
||||
| Lombok | 简化对象封装工具
|
||||
| Docker | 应用容器引擎
|
||||
| Mysql | 数据库服务
|
||||
| Thymeleaf | 模板引擎
|
||||
| Layui | 前端UI
|
||||
|
||||
|
||||
#### PC站截图
|
||||
|
||||
1. 首页
|
||||
|
||||

|
||||
|
||||

|
||||
2. 分类索引页
|
||||
|
||||

|
||||
|
||||
3. 搜索页
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
4. 排行榜
|
||||
|
||||

|
||||

|
||||
|
||||
5. 详情页
|
||||
|
||||

|
||||
|
||||
6. 阅读页
|
||||
|
||||

|
||||
|
||||
7. 用户中心
|
||||
|
||||

|
||||
|
||||
8. 充值
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
9. 作家专区
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
10. 购买
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### 手机站截图
|
||||
|
||||
1. 首页
|
||||
|
||||

|
||||
<img src="https://s3.ax1x.com/2020/12/04/DbsSoj.jpg" alt="index" style="zoom:33%;" />
|
||||
|
||||
|
||||
2. 小说列表页
|
||||
|
||||
2. 小说详情页
|
||||
<img src="https://s3.ax1x.com/2020/12/04/DbrfsO.jpg" alt="微信图片_20190904181558" style="zoom: 33%;" />
|
||||
|
||||

|
||||
3. 小说详情页
|
||||
|
||||
|
||||
|
||||
3. 目录页
|
||||
|
||||

|
||||
<img src="https://s3.ax1x.com/2020/12/04/DbsklV.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
|
||||
|
||||
4. 小说阅读页
|
||||
|
||||

|
||||
|
||||
|
||||
<img src="https://s3.ax1x.com/2020/12/04/Dbsew4.jpg" alt="QQ图片20191018161901" style="zoom:33%;" />
|
||||
|
||||
#### 爬虫管理系统截图
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
#### 后台管理系统截图
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
#### 安装步骤
|
||||
|
||||
@ -107,9 +187,13 @@ Springboot+Mybatis+Mysql+Ehcache+Thymeleaf+Layui
|
||||
|
||||
**喜欢此项目的可以给我的GitHub和Gitee加个Star支持一下 。**
|
||||
|
||||
#### 演示地址
|
||||
#### 其他安装教程
|
||||
|
||||
[点击前往](http://www.java2nb.com)(前台门户)
|
||||
包安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4272630)
|
||||
|
||||
宝塔安装教程(非官方):[点击前往](https://www.daniao.org/9166.html)
|
||||
|
||||
docker安装教程:[点击前往](https://my.oschina.net/java2nb/blog/4271989)
|
||||
|
||||
#### 代码仓库
|
||||
|
||||
@ -119,16 +203,29 @@ Springboot+Mybatis+Mysql+Ehcache+Thymeleaf+Layui
|
||||
|
||||
#### QQ交流群
|
||||
|
||||

|
||||

|
||||
|
||||
#### 捐赠支持
|
||||
#### 微信公众号(发布最新更新资讯)
|
||||
|
||||
开源项目不易,若此项目能得到你的青睐,可以捐赠支持作者持续开发与维护。
|
||||

|
||||
|
||||

|
||||
#### 赞赏支持
|
||||
|
||||
开源项目不易,若此项目能得到你的青睐,那么你可以赞赏支持作者持续开发与维护。
|
||||
|
||||
- 服务器的费用也是一笔开销
|
||||
- 为用户提供更好的开发环境
|
||||
- 一杯咖啡
|
||||
|
||||

|
||||
|
||||
### 免责声明
|
||||
|
||||
本项目提供的爬虫工具仅用于采集项目初期的测试数据,请勿用于商业盈利。
|
||||
用户使用本系统从事任何违法违规的事情,一切后果由用户自行承担,作者不承担任何责任。
|
||||
|
||||
#### 备注
|
||||
|
||||
精品小说屋所有相关项目均已在开源中国公开,感兴趣的可进入[开源中国](https://www.oschina.net/p/fiction_house)按关键字`精品小说屋`搜索。
|
||||
|
||||
[](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
|
||||
[](https://www.aliyun.com/minisite/goods?userCode=uf4nasee )
|
||||
|
BIN
assets/QQ20200520-215756.png
Normal file
BIN
assets/QQ20200520-215756.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 62 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 185 KiB |
82
es/index_create.txt
Normal file
82
es/index_create.txt
Normal file
@ -0,0 +1,82 @@
|
||||
PUT /novel
|
||||
{
|
||||
"mappings" : {
|
||||
"book" : {
|
||||
"properties" : {
|
||||
"id" : {
|
||||
"type" : "long"
|
||||
},
|
||||
"authorId" : {
|
||||
"type" : "long"
|
||||
},
|
||||
"authorName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 1.9
|
||||
},
|
||||
|
||||
"bookName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 2
|
||||
},
|
||||
|
||||
"bookDesc" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 0.1
|
||||
},
|
||||
|
||||
"bookStatus" : {
|
||||
"type" : "short"
|
||||
},
|
||||
|
||||
"catId" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
||||
"catName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 1.0
|
||||
},
|
||||
|
||||
"lastIndexId" : {
|
||||
"type" : "long"
|
||||
},
|
||||
|
||||
"lastIndexName" : {
|
||||
"type" : "text",
|
||||
"analyzer": "ik_smart",
|
||||
"boost": 0.1
|
||||
},
|
||||
|
||||
"lastIndexUpdateTime" : {
|
||||
"type": "keyword"
|
||||
},
|
||||
|
||||
"picUrl" : {
|
||||
"type" : "keyword"
|
||||
},
|
||||
|
||||
"score" : {
|
||||
"type" : "float"
|
||||
},
|
||||
|
||||
"wordCount" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
||||
"workDirection" : {
|
||||
"type" : "short"
|
||||
},
|
||||
|
||||
"visitCount" : {
|
||||
"type": "long"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6
novel-admin/Dockerfile
Normal file
6
novel-admin/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
FROM java:8
|
||||
ADD novel-admin-1.0.0.jar /root
|
||||
ENV dburl=""
|
||||
ENV username=""
|
||||
ENV password=""
|
||||
ENTRYPOINT ["sh","-c","java -Dspring.datasource.url=${dburl} -Dspring.datasource.username=${username} -Dspring.datasource.password=${password} -jar /root/novel-admin-1.0.0.jar"]
|
264
novel-admin/pom.xml
Normal file
264
novel-admin/pom.xml
Normal file
@ -0,0 +1,264 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.java2nb</groupId>
|
||||
<artifactId>novel-admin</artifactId>
|
||||
<version>2.11.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>novel-admin</name>
|
||||
<description>小说精品屋后台管理</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<activiti.version>5.22.0</activiti.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!--web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<!-- NekoHTML 是一个简单地HTML扫描器和标签补偿器(tag balancer) ,使得程序能解析HTML文档并用标准的XML接口来访问其中的信息。
|
||||
这个解析器能投扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档过程中常犯的错误。
|
||||
NekoHTML 能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。
|
||||
NekoHTML 的开发使用了Xerces Native Interface (XNI),后者是Xerces2的实现基础。-->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.nekohtml</groupId>
|
||||
<artifactId>nekohtml</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>3.4.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<!--druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.0.28</version>
|
||||
</dependency>
|
||||
<!--commons -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<version>1.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
<!--shiro -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<!-- shiro ehcache -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-ehcache</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.31</version>
|
||||
</dependency>
|
||||
<!--velocity代码生成使用模板 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<version>1.7</version>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
<!-- quartz -->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-cache</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>net.sf.ehcache</groupId>-->
|
||||
<!--<artifactId>ehcache</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-devtools</artifactId>-->
|
||||
<!--<optional>true</optional>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
<!--swagger2-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 添加redis支持-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ehchache -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--war包部署需要-->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-web</artifactId>-->
|
||||
<!--<!– 移除嵌入式tomcat插件 –>-->
|
||||
<!--<exclusions>-->
|
||||
<!--<exclusion>-->
|
||||
<!--<groupId>org.springframework.boot</groupId>-->
|
||||
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
|
||||
<!--</exclusion>-->
|
||||
<!--</exclusions>-->
|
||||
<!--</dependency>-->
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>javax.servlet</groupId>-->
|
||||
<!--<artifactId>javax.servlet-api</artifactId>-->
|
||||
<!--<version>3.1.0</version>-->
|
||||
<!--<scope>provided</scope>-->
|
||||
<!--</dependency>-->
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<!--<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<!--SpringBoot项目默认使用spring-boot-maven-plugin,要打成被其他项目引用的jar包,需要更换此插件-->
|
||||
<!-- <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<!--<distributionManagement>
|
||||
<repository>
|
||||
<id>nexus_release</id>
|
||||
<name>release</name>
|
||||
<url>http://47.106.243.172:8081/nexus/content/repositories/releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>nexus_snapshots</id>
|
||||
<name>snapshots</name>
|
||||
<url>http://47.106.243.172:8081/nexus/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>-->
|
||||
</project>
|
25
novel-admin/src/main/java/com/java2nb/AdminApplication.java
Normal file
25
novel-admin/src/main/java/com/java2nb/AdminApplication.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.java2nb;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
//关闭SpringSecurity的功能
|
||||
@EnableAutoConfiguration(exclude = {
|
||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
|
||||
})
|
||||
@EnableTransactionManagement
|
||||
@ServletComponentScan
|
||||
@MapperScan("com.java2nb.*.dao")
|
||||
@SpringBootApplication
|
||||
@EnableCaching
|
||||
public class AdminApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AdminApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Log {
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package com.java2nb.common.aspect;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.java2nb.common.annotation.Log;
|
||||
import com.java2nb.common.dao.LogDao;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.utils.HttpContextUtils;
|
||||
import com.java2nb.common.utils.IPUtils;
|
||||
import com.java2nb.common.utils.JSONUtils;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class LogAspect {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
|
||||
|
||||
@Autowired
|
||||
LogService logService;
|
||||
|
||||
|
||||
@Pointcut("@annotation(com.java2nb.common.annotation.Log)")
|
||||
public void logPointCut() {
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
// 执行方法
|
||||
Object result = point.proceed();
|
||||
// 执行时长(毫秒)
|
||||
long time = System.currentTimeMillis() - beginTime;
|
||||
//异步保存日志
|
||||
saveLog(point, time);
|
||||
return result;
|
||||
}
|
||||
|
||||
void saveLog(ProceedingJoinPoint joinPoint, long time) throws InterruptedException {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
LogDO sysLog = new LogDO();
|
||||
Log syslog = method.getAnnotation(Log.class);
|
||||
if (syslog != null) {
|
||||
// 注解上的描述
|
||||
sysLog.setOperation(syslog.value());
|
||||
}
|
||||
// 请求的方法名
|
||||
String className = joinPoint.getTarget().getClass().getName();
|
||||
String methodName = signature.getName();
|
||||
sysLog.setMethod(className + "." + methodName + "()");
|
||||
// 请求的参数
|
||||
Object[] args = joinPoint.getArgs();
|
||||
try {
|
||||
String params = JSONUtils.beanToJson(args[0]).substring(0, 4999);
|
||||
sysLog.setParams(params);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
// 获取request
|
||||
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||
// 设置IP地址
|
||||
sysLog.setIp(IPUtils.getIpAddr(request));
|
||||
// 用户名
|
||||
UserDO currUser = ShiroUtils.getUser();
|
||||
if (null == currUser) {
|
||||
if (null != sysLog.getParams()) {
|
||||
sysLog.setUserId(-1L);
|
||||
sysLog.setUsername(sysLog.getParams());
|
||||
} else {
|
||||
sysLog.setUserId(-1L);
|
||||
sysLog.setUsername("获取用户信息为空");
|
||||
}
|
||||
} else {
|
||||
sysLog.setUserId(ShiroUtils.getUserId());
|
||||
sysLog.setUsername(ShiroUtils.getUser().getUsername());
|
||||
}
|
||||
sysLog.setTime((int) time);
|
||||
// 系统当前时间
|
||||
Date date = new Date();
|
||||
sysLog.setGmtCreate(date);
|
||||
// 保存系统日志
|
||||
logService.save(sysLog);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.java2nb.common.aspect;
|
||||
|
||||
import com.java2nb.common.utils.HttpContextUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class WebLogAspect {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
|
||||
|
||||
@Pointcut("execution( * com.java2nb..controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
|
||||
public void logPointCut() {
|
||||
}
|
||||
|
||||
|
||||
@Before("logPointCut()")
|
||||
public void doBefore(JoinPoint joinPoint) throws Throwable {
|
||||
// 接收到请求,记录请求内容
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
// 记录下请求内容
|
||||
logger.info("请求地址 : " + request.getRequestURL().toString());
|
||||
logger.info("HTTP METHOD : " + request.getMethod());
|
||||
// 获取真实的ip地址
|
||||
//logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
|
||||
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
|
||||
+ joinPoint.getSignature().getName());
|
||||
logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
|
||||
// loggger.info("参数 : " + joinPoint.getArgs());
|
||||
|
||||
}
|
||||
|
||||
@AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
|
||||
public void doAfterReturning(Object ret) throws Throwable {
|
||||
// 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
|
||||
logger.debug("返回值 : " + ret);
|
||||
}
|
||||
|
||||
@Around("logPointCut()")
|
||||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Object ob = pjp.proceed();// ob 为方法的返回值
|
||||
logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
|
||||
return ob;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
* <p>
|
||||
* Email 122741482@qq.com
|
||||
* <p>
|
||||
* Describe:
|
||||
*/
|
||||
@Component
|
||||
public class ApplicationContextRegister implements ApplicationContextAware {
|
||||
private static Logger logger = LoggerFactory.getLogger(ApplicationContextRegister.class);
|
||||
private static ApplicationContext APPLICATION_CONTEXT;
|
||||
/**
|
||||
* 设置spring上下文
|
||||
* @param applicationContext spring上下文
|
||||
* @throws BeansException
|
||||
* */
|
||||
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
logger.debug("ApplicationContext registed-->{}", applicationContext);
|
||||
APPLICATION_CONTEXT = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器
|
||||
* @return
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return APPLICATION_CONTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取容器对象
|
||||
* @param type
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getBean(Class<T> type) {
|
||||
return APPLICATION_CONTEXT.getBean(type);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.SessionListener;
|
||||
|
||||
public class BDSessionListener implements SessionListener {
|
||||
|
||||
private final AtomicInteger sessionCount = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void onStart(Session session) {
|
||||
sessionCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(Session session) {
|
||||
sessionCount.decrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExpiration(Session session) {
|
||||
sessionCount.decrementAndGet();
|
||||
|
||||
}
|
||||
|
||||
public int getSessionCount() {
|
||||
return sessionCount.get();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
public class Constant {
|
||||
//演示系统账户
|
||||
public static String DEMO_ACCOUNT = "test";
|
||||
//自动去除表前缀
|
||||
public static String AUTO_REOMVE_PRE = "true";
|
||||
//停止计划任务
|
||||
public static String STATUS_RUNNING_STOP = "stop";
|
||||
//开启计划任务
|
||||
public static String STATUS_RUNNING_START = "start";
|
||||
//通知公告阅读状态-未读
|
||||
public static String OA_NOTIFY_READ_NO = "0";
|
||||
//通知公告阅读状态-已读
|
||||
public static int OA_NOTIFY_READ_YES = 1;
|
||||
//部门根节点id
|
||||
public static Long DEPT_ROOT_ID = 0l;
|
||||
//缓存方式
|
||||
public static String CACHE_TYPE_REDIS ="redis";
|
||||
|
||||
public static String LOG_ERROR = "error";
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
@Configuration
|
||||
public class DateConverConfig {
|
||||
@Bean
|
||||
public Converter<String, Date> stringDateConvert() {
|
||||
return new Converter<String, Date>() {
|
||||
@Override
|
||||
public Date convert(String source) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf.parse((String) source);
|
||||
} catch (Exception e) {
|
||||
SimpleDateFormat sdfday = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
date = sdfday.parse((String) source);
|
||||
} catch (ParseException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.java2nb.common.config;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.support.http.StatViewServlet;
|
||||
import com.alibaba.druid.support.http.WebStatFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Created by PrimaryKey on 17/2/4.
|
||||
*/
|
||||
@SuppressWarnings("AlibabaRemoveCommentedCode")
|
||||
@Configuration
|
||||
public class DruidDBConfig {
|
||||
private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
|
||||
@Value("${spring.datasource.url}")
|
||||
private String dbUrl;
|
||||
|
||||
@Value("${spring.datasource.username}")
|
||||
private String username;
|
||||
|
||||
@Value("${spring.datasource.password}")
|
||||
private String password;
|
||||
|
||||
@Value("${spring.datasource.driverClassName}")
|
||||
private String driverClassName;
|
||||
|
||||
@Value("${spring.datasource.initialSize}")
|
||||
private int initialSize;
|
||||
|
||||
@Value("${spring.datasource.minIdle}")
|
||||
private int minIdle;
|
||||
|
||||
@Value("${spring.datasource.maxActive}")
|
||||
private int maxActive;
|
||||
|
||||
@Value("${spring.datasource.maxWait}")
|
||||
private int maxWait;
|
||||
|
||||
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
|
||||
private int timeBetweenEvictionRunsMillis;
|
||||
|
||||
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
|
||||
private int minEvictableIdleTimeMillis;
|
||||
|
||||
@Value("${spring.datasource.validationQuery}")
|
||||
private String validationQuery;
|
||||
|
||||
@Value("${spring.datasource.testWhileIdle}")
|
||||
private boolean testWhileIdle;
|
||||
|
||||
@Value("${spring.datasource.testOnBorrow}")
|
||||
private boolean testOnBorrow;
|
||||
|
||||
@Value("${spring.datasource.testOnReturn}")
|
||||
private boolean testOnReturn;
|
||||
|
||||
@Value("${spring.datasource.poolPreparedStatements}")
|
||||
private boolean poolPreparedStatements;
|
||||
|
||||
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
|
||||
private int maxPoolPreparedStatementPerConnectionSize;
|
||||
|
||||
@Value("${spring.datasource.filters}")
|
||||
private String filters;
|
||||
|
||||
@Value("{spring.datasource.connectionProperties}")
|
||||
private String connectionProperties;
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close") //声明其为Bean实例
|
||||
@Primary //在同样的DataSource中,首先使用被标注的DataSource
|
||||
public DataSource dataSource() {
|
||||
DruidDataSource datasource = new DruidDataSource();
|
||||
|
||||
datasource.setUrl(this.dbUrl);
|
||||
datasource.setUsername(username);
|
||||
datasource.setPassword(password);
|
||||
datasource.setDriverClassName(driverClassName);
|
||||
|
||||
//configuration
|
||||
datasource.setInitialSize(initialSize);
|
||||
datasource.setMinIdle(minIdle);
|
||||
datasource.setMaxActive(maxActive);
|
||||
datasource.setMaxWait(maxWait);
|
||||
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
||||
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
|
||||
datasource.setValidationQuery(validationQuery);
|
||||
datasource.setTestWhileIdle(testWhileIdle);
|
||||
datasource.setTestOnBorrow(testOnBorrow);
|
||||
datasource.setTestOnReturn(testOnReturn);
|
||||
datasource.setPoolPreparedStatements(poolPreparedStatements);
|
||||
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
|
||||
try {
|
||||
datasource.setFilters(filters);
|
||||
} catch (SQLException e) {
|
||||
logger.error("druid configuration initialization filter", e);
|
||||
}
|
||||
datasource.setConnectionProperties(connectionProperties);
|
||||
|
||||
return datasource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean druidServlet() {
|
||||
ServletRegistrationBean reg = new ServletRegistrationBean();
|
||||
reg.setServlet(new StatViewServlet());
|
||||
reg.addUrlMappings("/druid/*");
|
||||
reg.addInitParameter("allow", ""); //白名单
|
||||
return reg;
|
||||
}
|
||||
|
||||
@Bean public FilterRegistrationBean filterRegistrationBean() {
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(new WebStatFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
|
||||
filterRegistrationBean.addInitParameter("profileEnable", "true");
|
||||
filterRegistrationBean.addInitParameter("principalCookieName","USER_COOKIE");
|
||||
filterRegistrationBean.addInitParameter("principalSessionName","USER_SESSION");
|
||||
filterRegistrationBean.addInitParameter("DruidWebStatFilter","/*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix="java2nb")
|
||||
public class JnConfig {
|
||||
//上传路径
|
||||
private String uploadPath;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
public String getUploadPath() {
|
||||
return uploadPath;
|
||||
}
|
||||
|
||||
public void setUploadPath(String uploadPath) {
|
||||
this.uploadPath = uploadPath;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("all")
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
|
||||
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
|
||||
|
||||
|
||||
template.setConnectionFactory(factory);
|
||||
|
||||
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
|
||||
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
|
||||
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
|
||||
|
||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
|
||||
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
|
||||
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
|
||||
|
||||
// key采用String的序列化方式
|
||||
|
||||
|
||||
template.setKeySerializer(stringRedisSerializer);
|
||||
|
||||
|
||||
// hash的key也采用String的序列化方式
|
||||
|
||||
|
||||
template.setHashKeySerializer(stringRedisSerializer);
|
||||
|
||||
|
||||
// value序列化方式采用jackson
|
||||
|
||||
|
||||
template.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
|
||||
// hash的value序列化方式采用jackson
|
||||
|
||||
|
||||
template.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
|
||||
template.afterPropertiesSet();
|
||||
|
||||
|
||||
return template;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@EnableAutoConfiguration(exclude = {
|
||||
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
|
||||
})
|
||||
@Configuration
|
||||
public class SecuityConfig {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
|
||||
import com.java2nb.common.redis.shiro.RedisCacheManager;
|
||||
import com.java2nb.common.redis.shiro.RedisManager;
|
||||
import com.java2nb.common.redis.shiro.RedisSessionDAO;
|
||||
import com.java2nb.system.shiro.UserRealm;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.session.SessionListener;
|
||||
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
|
||||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
@Value("${spring.redis.host}")
|
||||
private String host;
|
||||
@Value("${spring.redis.password}")
|
||||
private String password;
|
||||
@Value("${spring.redis.port}")
|
||||
private int port;
|
||||
@Value("${spring.redis.timeout}")
|
||||
private int timeout;
|
||||
|
||||
@Value("${spring.cache.type}")
|
||||
private String cacheType ;
|
||||
|
||||
@Value("${server.session-timeout}")
|
||||
private int tomcatTimeout;
|
||||
|
||||
@Bean
|
||||
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
|
||||
return new LifecycleBeanPostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ShiroDialect shiroDialect() {
|
||||
return new ShiroDialect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||
shiroFilterFactoryBean.setLoginUrl("/login");
|
||||
shiroFilterFactoryBean.setSuccessUrl("/index");
|
||||
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
|
||||
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
||||
filterChainDefinitionMap.put("/login","anon");
|
||||
filterChainDefinitionMap.put("/getVerify","anon");
|
||||
filterChainDefinitionMap.put("/css/**", "anon");
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/fonts/**", "anon");
|
||||
filterChainDefinitionMap.put("/img/**", "anon");
|
||||
filterChainDefinitionMap.put("/docs/**", "anon");
|
||||
filterChainDefinitionMap.put("/layuimini/**", "anon");
|
||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||
filterChainDefinitionMap.put("/upload/**", "anon");
|
||||
filterChainDefinitionMap.put("/files/**", "anon");
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
filterChainDefinitionMap.put("/blog", "anon");
|
||||
filterChainDefinitionMap.put("/blog/open/**", "anon");
|
||||
filterChainDefinitionMap.put("/**", "authc");
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityManager securityManager() {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
//设置realm.
|
||||
securityManager.setRealm(userRealm());
|
||||
// 自定义缓存实现 使用redis
|
||||
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
|
||||
securityManager.setCacheManager(rediscacheManager());
|
||||
} else {
|
||||
securityManager.setCacheManager(ehCacheManager());
|
||||
}
|
||||
securityManager.setSessionManager(sessionManager());
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
UserRealm userRealm() {
|
||||
UserRealm userRealm = new UserRealm();
|
||||
return userRealm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启shiro aop注解支持.
|
||||
* 使用代理方式;所以需要开启代码支持;
|
||||
*
|
||||
* @param securityManager
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
|
||||
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
|
||||
return authorizationAttributeSourceAdvisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置shiro redisManager
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public RedisManager redisManager() {
|
||||
RedisManager redisManager = new RedisManager();
|
||||
redisManager.setHost(host);
|
||||
redisManager.setPort(port);
|
||||
redisManager.setExpire(1800);// 配置缓存过期时间
|
||||
//redisManager.setTimeout(1800);
|
||||
redisManager.setPassword(password);
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* cacheManager 缓存 redis实现
|
||||
* 使用的是shiro-redis开源插件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public RedisCacheManager rediscacheManager() {
|
||||
RedisCacheManager redisCacheManager = new RedisCacheManager();
|
||||
redisCacheManager.setRedisManager(redisManager());
|
||||
return redisCacheManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* RedisSessionDAO shiro sessionDao层的实现 通过redis
|
||||
* 使用的是shiro-redis开源插件
|
||||
*/
|
||||
@Bean
|
||||
public RedisSessionDAO redisSessionDAO() {
|
||||
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
|
||||
redisSessionDAO.setRedisManager(redisManager());
|
||||
return redisSessionDAO;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionDAO sessionDAO() {
|
||||
if (Constant.CACHE_TYPE_REDIS.equals(cacheType)) {
|
||||
return redisSessionDAO();
|
||||
} else {
|
||||
return new MemorySessionDAO();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shiro session的管理
|
||||
*/
|
||||
@Bean
|
||||
public DefaultWebSessionManager sessionManager() {
|
||||
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
||||
sessionManager.setGlobalSessionTimeout(tomcatTimeout * 1000);
|
||||
sessionManager.setSessionDAO(sessionDAO());
|
||||
Collection<SessionListener> listeners = new ArrayList<SessionListener>();
|
||||
listeners.add(new BDSessionListener());
|
||||
sessionManager.setSessionListeners(listeners);
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EhCacheManager ehCacheManager() {
|
||||
EhCacheManager em = new EhCacheManager();
|
||||
em.setCacheManager(cacheManager());
|
||||
return em;
|
||||
}
|
||||
|
||||
@Bean("cacheManager2")
|
||||
CacheManager cacheManager(){
|
||||
return CacheManager.create();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class SpringAsyncConfig {
|
||||
// @Bean
|
||||
// public AsyncTaskExecutor taskExecutor() {
|
||||
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
// executor.setMaxPoolSize(10);
|
||||
// return executor;
|
||||
// }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
/**
|
||||
* ${DESCRIPTION}
|
||||
*
|
||||
* @author xiongxy
|
||||
* @create 2019-11-02 23:53
|
||||
*/
|
||||
@EnableSwagger2
|
||||
@Configuration
|
||||
public class Swagger2Config {
|
||||
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
//为当前包路径
|
||||
.apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
//构建 api文档的详细信息函数
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
//页面标题
|
||||
.title("功能测试")
|
||||
//创建人
|
||||
.contact(new Contact("xiongxy", "1179705413@qq.com", "1179705413@qq.com"))
|
||||
//版本号
|
||||
.version("1.0")
|
||||
//描述
|
||||
.description("API 描述")
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.java2nb.common.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@Component
|
||||
class WebConfigurer extends WebMvcConfigurerAdapter {
|
||||
@Autowired
|
||||
JnConfig jnConfig;
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/files/**").addResourceLocations("file:///"+ jnConfig.getUploadPath());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
@Controller
|
||||
public class BaseController {
|
||||
public UserDO getUser() {
|
||||
return ShiroUtils.getUser();
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return getUser().getUserId();
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return getUser().getUsername();
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.common.service.DictService;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/common/dict")
|
||||
public class DictController extends BaseController {
|
||||
@Autowired
|
||||
private DictService dictService;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("common:dict:dict")
|
||||
String dict() {
|
||||
return "common/dict/dict";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("common:dict:dict")
|
||||
public PageBean list(@RequestParam Map<String, Object> params) {
|
||||
// 查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<DictDO> dictList = dictService.list(query);
|
||||
int total = dictService.count(query);
|
||||
PageBean pageBean = new PageBean(dictList, total);
|
||||
return pageBean;
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
String add() {
|
||||
return "common/dict/add";
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
@RequiresPermissions("common:dict:edit")
|
||||
String edit(@PathVariable("id") Long id, Model model) {
|
||||
DictDO dict = dictService.get(id);
|
||||
model.addAttribute("dict", dict);
|
||||
return "common/dict/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
public R save(DictDO dict) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
if (dictService.save(dict) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("common:dict:edit")
|
||||
public R update(DictDO dict) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
dictService.update(dict);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:dict:remove")
|
||||
public R remove(Long id) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
if (dictService.remove(id) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:dict:batchRemove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
dictService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/type")
|
||||
@ResponseBody
|
||||
public List<DictDO> listType() {
|
||||
return dictService.listType();
|
||||
};
|
||||
|
||||
// 类别已经指定增加
|
||||
@GetMapping("/add/{type}/{description}")
|
||||
@RequiresPermissions("common:dict:add")
|
||||
String addD(Model model, @PathVariable("type") String type, @PathVariable("description") String description) {
|
||||
model.addAttribute("type", type);
|
||||
model.addAttribute("description", description);
|
||||
return "common/dict/add";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list/{type}")
|
||||
public List<DictDO> listByType(@PathVariable("type") String type) {
|
||||
// 查询列表数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
map.put("type", type);
|
||||
List<DictDO> dictList = dictService.list(map);
|
||||
return dictList;
|
||||
}
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.java2nb.common.config.JnConfig;
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
import com.java2nb.common.service.FileService;
|
||||
import com.java2nb.common.utils.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/common/sysFile")
|
||||
public class FileController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private FileService sysFileService;
|
||||
|
||||
@Autowired
|
||||
private JnConfig jnConfig;
|
||||
|
||||
@GetMapping()
|
||||
@RequiresPermissions("common:sysFile:sysFile")
|
||||
String sysFile(Model model) {
|
||||
Map<String, Object> params = new HashMap<>(16);
|
||||
return "common/file/file";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("common:sysFile:sysFile")
|
||||
public PageBean list(@RequestParam Map<String, Object> params) {
|
||||
// 查询列表数据
|
||||
Query query = new Query(params);
|
||||
List<FileDO> sysFileList = sysFileService.list(query);
|
||||
int total = sysFileService.count(query);
|
||||
PageBean pageBean = new PageBean(sysFileList, total);
|
||||
return pageBean;
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
// @RequiresPermissions("common:bComments")
|
||||
String add() {
|
||||
return "common/sysFile/add";
|
||||
}
|
||||
|
||||
@GetMapping("/edit")
|
||||
// @RequiresPermissions("common:bComments")
|
||||
String edit(Long id, Model model) {
|
||||
FileDO sysFile = sysFileService.get(id);
|
||||
model.addAttribute("sysFile", sysFile);
|
||||
return "common/sysFile/edit";
|
||||
}
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@RequestMapping("/info/{id}")
|
||||
@RequiresPermissions("common:info")
|
||||
public R info(@PathVariable("id") Long id) {
|
||||
FileDO sysFile = sysFileService.get(id);
|
||||
return R.ok().put("sysFile", sysFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("common:save")
|
||||
public R save(FileDO sysFile) {
|
||||
if (sysFileService.save(sysFile) > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@RequestMapping("/update")
|
||||
@RequiresPermissions("common:update")
|
||||
public R update(@RequestBody FileDO sysFile) {
|
||||
sysFileService.update(sysFile);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ResponseBody
|
||||
// @RequiresPermissions("common:remove")
|
||||
public R remove(Long id, HttpServletRequest request) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
String fileName = jnConfig.getUploadPath() + sysFileService.get(id).getUrl().replace("/files/", "");
|
||||
if (sysFileService.remove(id) > 0) {
|
||||
boolean b = FileUtil.deleteFile(fileName);
|
||||
if (!b) {
|
||||
return R.error("数据库记录删除成功,文件删除失败");
|
||||
}
|
||||
return R.ok();
|
||||
} else {
|
||||
return R.error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/batchRemove")
|
||||
@ResponseBody
|
||||
@RequiresPermissions("common:remove")
|
||||
public R remove(@RequestParam("ids[]") Long[] ids) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
sysFileService.batchRemove(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/upload")
|
||||
R upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
|
||||
if ("test".equals(getUsername())) {
|
||||
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
|
||||
}
|
||||
Date date = new Date();
|
||||
String year = DateUtils.format(date,DateUtils.YEAR_PATTERN);
|
||||
String month = DateUtils.format(date,DateUtils.MONTH_PATTERN);
|
||||
String day = DateUtils.format(date,DateUtils.DAY_PATTERN);
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
String fileDir = year+"/"+month+"/"+day + "/";
|
||||
fileName = FileUtil.renameToUUID(fileName);
|
||||
FileDO sysFile = new FileDO(FileType.fileType(fileName), "/files/" + fileDir + fileName, date);
|
||||
try {
|
||||
FileUtil.uploadFile(file.getBytes(), jnConfig.getUploadPath()+fileDir, fileName);
|
||||
} catch (Exception e) {
|
||||
return R.error();
|
||||
}
|
||||
|
||||
if (sysFileService.save(sysFile) > 0) {
|
||||
return R.ok().put("fileName",sysFile.getUrl());
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*/
|
||||
@RequestMapping(value = "/download")
|
||||
public void fileDownload(String filePath,String fileName, HttpServletResponse resp) throws Exception {
|
||||
String realFilePath = jnConfig.getUploadPath() + filePath;
|
||||
InputStream in = new FileInputStream(realFilePath);
|
||||
//设置响应头,对文件进行url编码
|
||||
fileName = URLEncoder.encode(fileName, "UTF-8");
|
||||
resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
|
||||
|
||||
resp.setContentLength(in.available());
|
||||
|
||||
OutputStream out = resp.getOutputStream();
|
||||
byte[] b = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = in.read(b)) != -1) {
|
||||
out.write(b, 0, len);
|
||||
}
|
||||
out.flush();
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import com.java2nb.common.service.GeneratorService;
|
||||
import com.java2nb.common.utils.GenUtils;
|
||||
import com.java2nb.common.utils.PageBean;
|
||||
import com.java2nb.common.utils.R;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequestMapping("/common/generator")
|
||||
@Controller
|
||||
public class GeneratorController {
|
||||
String prefix = "common/generator";
|
||||
@Autowired
|
||||
GeneratorService generatorService;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@GetMapping()
|
||||
String generator() {
|
||||
return prefix + "/list";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
List<Map<String, Object>> list(String tableName) {
|
||||
List<Map<String, Object>> list = generatorService.list(tableName);
|
||||
return list;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
@RequestMapping("/downLoadCode/{tableName}")
|
||||
public void downLoadCode(HttpServletRequest request, HttpServletResponse response,
|
||||
@PathVariable("tableName") String tableName) throws IOException {
|
||||
String[] tableNames = new String[]{tableName};
|
||||
byte[] data = generatorService.downloadCode(tableNames);
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"java2nb.zip\"");
|
||||
response.addHeader("Content-Length", "" + data.length);
|
||||
response.setContentType("application/octet-stream; charset=UTF-8");
|
||||
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/genCode")
|
||||
public R genCode(String tableName) {
|
||||
String[] tableNames = new String[]{tableName};
|
||||
generatorService.generatorCode(tableNames);
|
||||
return R.ok("代码生成成功,请到本地项目中查看!");
|
||||
}
|
||||
|
||||
@RequestMapping("/batchDownload")
|
||||
public void batchDownload(HttpServletRequest request, HttpServletResponse response, String tables) throws IOException {
|
||||
String[] tableNames = new String[]{};
|
||||
tableNames = JSON.parseArray(tables).toArray(tableNames);
|
||||
byte[] data = generatorService.downloadCode(tableNames);
|
||||
response.reset();
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"java2nb.zip\"");
|
||||
response.addHeader("Content-Length", "" + data.length);
|
||||
response.setContentType("application/octet-stream; charset=UTF-8");
|
||||
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/batchCode")
|
||||
public R batchCode(String tables) {
|
||||
String[] tableNames = new String[]{};
|
||||
tableNames = JSON.parseArray(tables).toArray(tableNames);
|
||||
generatorService.generatorCode(tableNames);
|
||||
return R.ok("代码批量生成成功,请到本地项目中查看!");
|
||||
}
|
||||
|
||||
@GetMapping("/edit")
|
||||
public String edit(Model model) {
|
||||
Configuration conf = GenUtils.getConfig();
|
||||
Map<String, Object> property = new HashMap<>(16);
|
||||
property.put("author", conf.getProperty("author"));
|
||||
property.put("email", conf.getProperty("email"));
|
||||
property.put("package", conf.getProperty("package"));
|
||||
property.put("autoRemovePre", conf.getProperty("autoRemovePre"));
|
||||
property.put("tablePrefix", conf.getProperty("tablePrefix"));
|
||||
property.put("srcPath", conf.getProperty("srcPath"));
|
||||
model.addAttribute("property", property);
|
||||
return prefix + "/edit";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/update")
|
||||
R update(@RequestParam Map<String, Object> map) {
|
||||
try {
|
||||
PropertiesConfiguration conf = new PropertiesConfiguration("generator.properties");
|
||||
conf.setProperty("author", map.get("author"));
|
||||
conf.setProperty("email", map.get("email"));
|
||||
conf.setProperty("package", map.get("package"));
|
||||
conf.setProperty("autoRemovePre", map.get("autoRemovePre"));
|
||||
conf.setProperty("tablePrefix", map.get("tablePrefix"));
|
||||
conf.setProperty("srcPath", map.get("srcPath"));
|
||||
conf.save();
|
||||
} catch (ConfigurationException e) {
|
||||
return R.error("保存配置文件出错");
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@GetMapping("/genColumns")
|
||||
String genColumns(String tableName, Model model) {
|
||||
model.addAttribute("tableName", tableName);
|
||||
return "common/genColumns/genColumns";
|
||||
}
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/genColumns/list")
|
||||
@SneakyThrows
|
||||
public R genColumnsList(String tableName) {
|
||||
List<GenColumnsDO> genColumns = generatorService.listColumnsByTableName(tableName);
|
||||
int total = genColumns.size();
|
||||
PageBean pageBean = new PageBean(genColumns, total);
|
||||
return R.ok().put("data", pageBean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@ApiOperation(value = "新增", notes = "新增")
|
||||
@ResponseBody
|
||||
@PostMapping("/genColumns/save")
|
||||
public R save(@RequestBody List<GenColumnsDO> list) {
|
||||
generatorService.genColumnsSave(list);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.java2nb.common.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.Query;
|
||||
import com.java2nb.common.utils.R;
|
||||
|
||||
@RequestMapping("/common/log")
|
||||
@Controller
|
||||
public class LogController {
|
||||
@Autowired
|
||||
LogService logService;
|
||||
String prefix = "common/log";
|
||||
|
||||
@GetMapping()
|
||||
String log() {
|
||||
return prefix + "/log";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
PageDO<LogDO> list(@RequestParam Map<String, Object> params) {
|
||||
Query query = new Query(params);
|
||||
PageDO<LogDO> page = logService.queryList(query);
|
||||
return page;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/remove")
|
||||
R remove(Long id) {
|
||||
if (logService.remove(id)>0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/batchRemove")
|
||||
R batchRemove(@RequestParam("ids[]") Long[] ids) {
|
||||
int r = logService.batchRemove(ids);
|
||||
if (r > 0) {
|
||||
return R.ok();
|
||||
}
|
||||
return R.error();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface DictDao {
|
||||
|
||||
DictDO get(Long id);
|
||||
|
||||
List<DictDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(DictDO dict);
|
||||
|
||||
int update(DictDO dict);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
List<DictDO> listType();
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface FileDao {
|
||||
|
||||
FileDO get(Long id);
|
||||
|
||||
List<FileDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(FileDO file);
|
||||
|
||||
int update(FileDO file);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-22 10:39:29
|
||||
*/
|
||||
@Mapper
|
||||
public interface GenColumnsDao {
|
||||
|
||||
|
||||
GenColumnsDO get(Long id);
|
||||
|
||||
List<GenColumnsDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(GenColumnsDO genColumns);
|
||||
|
||||
int update(GenColumnsDO genColumns);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
|
||||
void saveBatch(List<GenColumnsDO> list);
|
||||
|
||||
void deleteByTableName(@Param("tableName") String tableName);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
public interface GeneratorMapper {
|
||||
@Select("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables"
|
||||
+ " where table_schema = (select database()) and table_name like concat('%',#{tableName},'%')")
|
||||
List<Map<String, Object>> list(@Param("tableName") String tableName);
|
||||
|
||||
@Select("select count(*) from information_schema.tables where table_schema = (select database())")
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
@Select("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables \r\n"
|
||||
+ " where table_schema = (select database()) and table_name = #{tableName}")
|
||||
Map<String, String> get(String tableName);
|
||||
|
||||
@Select("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns\r\n"
|
||||
+ " where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position")
|
||||
List<Map<String, String>> listColumns(String tableName);
|
||||
|
||||
@Select("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns\r\n"
|
||||
+ " where table_name = #{tableName} and table_schema = (select database()) and column_key = 'PRI' limit 1")
|
||||
Map<String, String> getPriColumn(String tableName);
|
||||
}
|
32
novel-admin/src/main/java/com/java2nb/common/dao/LogDao.java
Normal file
32
novel-admin/src/main/java/com/java2nb/common/dao/LogDao.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.dao;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 系统日志
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-10-03 15:45:42
|
||||
*/
|
||||
@Mapper
|
||||
public interface LogDao {
|
||||
|
||||
LogDO get(Long id);
|
||||
|
||||
List<LogDO> list(Map<String,Object> map);
|
||||
|
||||
int count(Map<String,Object> map);
|
||||
|
||||
int save(LogDO log);
|
||||
|
||||
int update(LogDO log);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
/**
|
||||
* 列的属性
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ColumnDO {
|
||||
// 列名
|
||||
private String columnName;
|
||||
// 列名类型
|
||||
private String dataType;
|
||||
// 列名备注
|
||||
private String comments;
|
||||
|
||||
// 属性名称(第一个字母大写),如:user_name => UserName
|
||||
private String attrName;
|
||||
// 属性名称(第一个字母小写),如:user_name => userName
|
||||
private String attrname;
|
||||
// 属性类型
|
||||
private String attrType;
|
||||
// auto_increment
|
||||
private String extra;
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setDataType(String dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public String getAttrname() {
|
||||
return attrname;
|
||||
}
|
||||
|
||||
public void setAttrname(String attrname) {
|
||||
this.attrname = attrname;
|
||||
}
|
||||
|
||||
public String getAttrName() {
|
||||
return attrName;
|
||||
}
|
||||
|
||||
public void setAttrName(String attrName) {
|
||||
this.attrName = attrName;
|
||||
}
|
||||
|
||||
public String getAttrType() {
|
||||
return attrType;
|
||||
}
|
||||
|
||||
public void setAttrType(String attrType) {
|
||||
this.attrType = attrType;
|
||||
}
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ColumnDO{" +
|
||||
"columnName='" + columnName + '\'' +
|
||||
", dataType='" + dataType + '\'' +
|
||||
", comments='" + comments + '\'' +
|
||||
", attrName='" + attrName + '\'' +
|
||||
", attrname='" + attrname + '\'' +
|
||||
", attrType='" + attrType + '\'' +
|
||||
", extra='" + extra + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
221
novel-admin/src/main/java/com/java2nb/common/domain/DictDO.java
Normal file
221
novel-admin/src/main/java/com/java2nb/common/domain/DictDO.java
Normal file
@ -0,0 +1,221 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
public class DictDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//编号
|
||||
private Long id;
|
||||
//标签名
|
||||
private String name;
|
||||
//数据值
|
||||
private String value;
|
||||
//类型
|
||||
private String type;
|
||||
//描述
|
||||
private String description;
|
||||
//排序(升序)
|
||||
private BigDecimal sort;
|
||||
//父级编号
|
||||
private Long parentId;
|
||||
//创建者
|
||||
private Integer createBy;
|
||||
//创建时间
|
||||
private Date createDate;
|
||||
//更新者
|
||||
private Long updateBy;
|
||||
//更新时间
|
||||
private Date updateDate;
|
||||
//备注信息
|
||||
private String remarks;
|
||||
//删除标记
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 设置:编号
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* 获取:编号
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* 设置:标签名
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* 获取:标签名
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* 设置:数据值
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
/**
|
||||
* 获取:数据值
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 设置:类型
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* 获取:类型
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* 设置:描述
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
/**
|
||||
* 获取:描述
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* 设置:排序(升序)
|
||||
*/
|
||||
public void setSort(BigDecimal sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
/**
|
||||
* 获取:排序(升序)
|
||||
*/
|
||||
public BigDecimal getSort() {
|
||||
return sort;
|
||||
}
|
||||
/**
|
||||
* 设置:父级编号
|
||||
*/
|
||||
public void setParentId(Long parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
/**
|
||||
* 获取:父级编号
|
||||
*/
|
||||
public Long getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
/**
|
||||
* 设置:创建者
|
||||
*/
|
||||
public void setCreateBy(Integer createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
/**
|
||||
* 获取:创建者
|
||||
*/
|
||||
public Integer getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
/**
|
||||
* 设置:更新者
|
||||
*/
|
||||
public void setUpdateBy(Long updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
/**
|
||||
* 获取:更新者
|
||||
*/
|
||||
public Long getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
/**
|
||||
* 设置:更新时间
|
||||
*/
|
||||
public void setUpdateDate(Date updateDate) {
|
||||
this.updateDate = updateDate;
|
||||
}
|
||||
/**
|
||||
* 获取:更新时间
|
||||
*/
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
/**
|
||||
* 设置:备注信息
|
||||
*/
|
||||
public void setRemarks(String remarks) {
|
||||
this.remarks = remarks;
|
||||
}
|
||||
/**
|
||||
* 获取:备注信息
|
||||
*/
|
||||
public String getRemarks() {
|
||||
return remarks;
|
||||
}
|
||||
/**
|
||||
* 设置:删除标记
|
||||
*/
|
||||
public void setDelFlag(String delFlag) {
|
||||
this.delFlag = delFlag;
|
||||
}
|
||||
/**
|
||||
* 获取:删除标记
|
||||
*/
|
||||
public String getDelFlag() {
|
||||
return delFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DictDO{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", sort=" + sort +
|
||||
", parentId=" + parentId +
|
||||
", createBy=" + createBy +
|
||||
", createDate=" + createDate +
|
||||
", updateBy=" + updateBy +
|
||||
", updateDate=" + updateDate +
|
||||
", remarks='" + remarks + '\'' +
|
||||
", delFlag='" + delFlag + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
104
novel-admin/src/main/java/com/java2nb/common/domain/FileDO.java
Normal file
104
novel-admin/src/main/java/com/java2nb/common/domain/FileDO.java
Normal file
@ -0,0 +1,104 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
public class FileDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//
|
||||
private Long id;
|
||||
// 文件类型
|
||||
private Integer type;
|
||||
// URL地址
|
||||
private String url;
|
||||
// 创建时间
|
||||
private Date createDate;
|
||||
|
||||
|
||||
public FileDO() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public FileDO(Integer type, String url, Date createDate) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.url = url;
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置:
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:
|
||||
*/
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:文件类型
|
||||
*/
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:文件类型
|
||||
*/
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:URL地址
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:URL地址
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置:创建时间
|
||||
*/
|
||||
public void setCreateDate(Date createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:创建时间
|
||||
*/
|
||||
public Date getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FileDO{" +
|
||||
"id=" + id +
|
||||
", type=" + type +
|
||||
", url='" + url + '\'' +
|
||||
", createDate=" + createDate +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-11-22 18:03:46
|
||||
*/
|
||||
public class GenColumnsDO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//主键
|
||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||
//所以通过序列化成字符串来解决
|
||||
@JsonSerialize(using = LongToStringSerializer.class)
|
||||
private Long id;
|
||||
//表名
|
||||
private String tableName;
|
||||
//列名
|
||||
private String columnName;
|
||||
//列类型
|
||||
private String columnType;
|
||||
//映射java类型
|
||||
private String javaType;
|
||||
//列注释
|
||||
private String columnComment;
|
||||
//列排序(升序)
|
||||
private Integer columnSort;
|
||||
//列标签名
|
||||
private String columnLabel;
|
||||
//页面显示类型:1、文本框 2、下拉框 3、数值4、日期 5、文本域6、富文本 7、上传图片【单文件】 8、上传图片【多文件】9、上传文件【单文件】 10、上传文件【多文件】11、隐藏域 12、不显示
|
||||
private Integer pageType;
|
||||
//是否必填
|
||||
private Integer isRequired;
|
||||
//页面显示为下拉时使用,字典类型从字典表中取出
|
||||
private String dictType;
|
||||
|
||||
// 属性名称(第一个字母大写),如:user_name => UserName
|
||||
private String attrName;
|
||||
// 属性名称(第一个字母小写),如:user_name => userName
|
||||
private String attrname;
|
||||
|
||||
private String extra;
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getColumnType() {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
public void setColumnType(String columnType) {
|
||||
this.columnType = columnType;
|
||||
}
|
||||
|
||||
public String getJavaType() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
public void setJavaType(String javaType) {
|
||||
this.javaType = javaType;
|
||||
}
|
||||
|
||||
public String getColumnComment() {
|
||||
return columnComment;
|
||||
}
|
||||
|
||||
public void setColumnComment(String columnComment) {
|
||||
this.columnComment = columnComment;
|
||||
}
|
||||
|
||||
public Integer getColumnSort() {
|
||||
return columnSort;
|
||||
}
|
||||
|
||||
public void setColumnSort(Integer columnSort) {
|
||||
this.columnSort = columnSort;
|
||||
}
|
||||
|
||||
public String getColumnLabel() {
|
||||
return columnLabel;
|
||||
}
|
||||
|
||||
public void setColumnLabel(String columnLabel) {
|
||||
this.columnLabel = columnLabel;
|
||||
}
|
||||
|
||||
public Integer getPageType() {
|
||||
return pageType;
|
||||
}
|
||||
|
||||
public void setPageType(Integer pageType) {
|
||||
this.pageType = pageType;
|
||||
}
|
||||
|
||||
public Integer getIsRequired() {
|
||||
return isRequired;
|
||||
}
|
||||
|
||||
public void setIsRequired(Integer isRequired) {
|
||||
this.isRequired = isRequired;
|
||||
}
|
||||
|
||||
public String getDictType() {
|
||||
return dictType;
|
||||
}
|
||||
|
||||
public void setDictType(String dictType) {
|
||||
this.dictType = dictType;
|
||||
}
|
||||
|
||||
public String getAttrName() {
|
||||
return attrName;
|
||||
}
|
||||
|
||||
public void setAttrName(String attrName) {
|
||||
this.attrName = attrName;
|
||||
}
|
||||
|
||||
public String getAttrname() {
|
||||
return attrname;
|
||||
}
|
||||
|
||||
public void setAttrname(String attrname) {
|
||||
this.attrname = attrname;
|
||||
}
|
||||
}
|
112
novel-admin/src/main/java/com/java2nb/common/domain/LogDO.java
Normal file
112
novel-admin/src/main/java/com/java2nb/common/domain/LogDO.java
Normal file
@ -0,0 +1,112 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class LogDO {
|
||||
private Long id;
|
||||
|
||||
private Long userId;
|
||||
|
||||
private String username;
|
||||
|
||||
private String operation;
|
||||
|
||||
private Integer time;
|
||||
|
||||
private String method;
|
||||
|
||||
private String params;
|
||||
|
||||
private String ip;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date gmtCreate;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username == null ? null : username.trim();
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation == null ? null : operation.trim();
|
||||
}
|
||||
|
||||
public Integer getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Integer time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method == null ? null : method.trim();
|
||||
}
|
||||
|
||||
public String getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(String params) {
|
||||
this.params = params == null ? null : params.trim();
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip == null ? null : ip.trim();
|
||||
}
|
||||
|
||||
public Date getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Date gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LogDO{" +
|
||||
"id=" + id +
|
||||
", userId=" + userId +
|
||||
", username='" + username + '\'' +
|
||||
", operation='" + operation + '\'' +
|
||||
", time=" + time +
|
||||
", method='" + method + '\'' +
|
||||
", params='" + params + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PageDO<T> {
|
||||
|
||||
private int offset;
|
||||
private int limit;
|
||||
private int total;
|
||||
private Map<String, Object> params;
|
||||
private String param;
|
||||
private List<T> rows;
|
||||
|
||||
public PageDO() {
|
||||
super();
|
||||
this.offset = 0;
|
||||
this.limit = 10;
|
||||
this.total = 1;
|
||||
this.params = new HashMap<>();
|
||||
this.param = "";
|
||||
this.rows = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public List<T> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<T> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
public String getParam() {
|
||||
return param;
|
||||
}
|
||||
|
||||
public void setParam(String param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PageDO{" +
|
||||
"offset=" + offset +
|
||||
", limit=" + limit +
|
||||
", total=" + total +
|
||||
", params=" + params +
|
||||
", param='" + param + '\'' +
|
||||
", rows=" + rows +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表数据
|
||||
*
|
||||
* @author chenshun
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public class TableDO {
|
||||
//表的名称
|
||||
private String tableName;
|
||||
//表的备注
|
||||
private String comments;
|
||||
//表的主键
|
||||
private GenColumnsDO pk;
|
||||
//表的列名(不包含主键)
|
||||
private List<GenColumnsDO> columns;
|
||||
|
||||
//类名(第一个字母大写),如:sys_user => SysUser
|
||||
private String className;
|
||||
//类名(第一个字母小写),如:sys_user => sysUser
|
||||
private String classname;
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public GenColumnsDO getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setPk(GenColumnsDO pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public List<GenColumnsDO> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setColumns(List<GenColumnsDO> columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getClassname() {
|
||||
return classname;
|
||||
}
|
||||
|
||||
public void setClassname(String classname) {
|
||||
this.classname = classname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableDO{" +
|
||||
"tableName='" + tableName + '\'' +
|
||||
", comments='" + comments + '\'' +
|
||||
", pk=" + pk +
|
||||
", columns=" + columns +
|
||||
", className='" + className + '\'' +
|
||||
", classname='" + classname + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
151
novel-admin/src/main/java/com/java2nb/common/domain/Tree.java
Normal file
151
novel-admin/src/main/java/com/java2nb/common/domain/Tree.java
Normal file
@ -0,0 +1,151 @@
|
||||
package com.java2nb.common.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
/**
|
||||
* tree TODO <br>
|
||||
*
|
||||
* @author xiongxy
|
||||
*
|
||||
*/
|
||||
public class Tree<T> {
|
||||
/**
|
||||
* 节点ID
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 显示节点文本
|
||||
*/
|
||||
private String text;
|
||||
/**
|
||||
* 节点状态,open closed
|
||||
*/
|
||||
private Map<String, Object> state;
|
||||
/**
|
||||
* 节点是否被选中 true false
|
||||
*/
|
||||
private boolean checked = false;
|
||||
/**
|
||||
* 节点属性
|
||||
*/
|
||||
private Map<String, Object> attributes;
|
||||
|
||||
/**
|
||||
* 节点的子节点
|
||||
*/
|
||||
private List<Tree<T>> children = new ArrayList<Tree<T>>();
|
||||
|
||||
/**
|
||||
* 父ID
|
||||
*/
|
||||
private String parentId;
|
||||
/**
|
||||
* 是否有父节点
|
||||
*/
|
||||
private boolean hasParent = false;
|
||||
/**
|
||||
* 是否有子节点
|
||||
*/
|
||||
private boolean hasChildren = false;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Map<String, Object> getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(Map<String, Object> state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public List<Tree<T>> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Tree<T>> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public boolean isHasParent() {
|
||||
return hasParent;
|
||||
}
|
||||
|
||||
public void setHasParent(boolean isParent) {
|
||||
this.hasParent = isParent;
|
||||
}
|
||||
|
||||
public boolean isHasChildren() {
|
||||
return hasChildren;
|
||||
}
|
||||
|
||||
public void setChildren(boolean isChildren) {
|
||||
this.hasChildren = isChildren;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public Tree(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
|
||||
List<Tree<T>> children, boolean isParent, boolean isChildren, String parentID) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.text = text;
|
||||
this.state = state;
|
||||
this.checked = checked;
|
||||
this.attributes = attributes;
|
||||
this.children = children;
|
||||
this.hasParent = isParent;
|
||||
this.hasChildren = isChildren;
|
||||
this.parentId = parentID;
|
||||
}
|
||||
|
||||
public Tree() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 自定义业务异常
|
||||
*/
|
||||
@Data
|
||||
public class BusinessException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code;
|
||||
|
||||
public BusinessException(int code,String msg) {
|
||||
//不调用父类Throwable的fillInStackTrace()方法生成栈追踪信息,提高应用性能
|
||||
//构造器之间的调用必须在第一行
|
||||
super(msg, null, false, false);
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.HttpServletUtils;
|
||||
import com.java2nb.common.utils.R;
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
public class CommonExceptionHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
@Autowired
|
||||
LogService logService;
|
||||
|
||||
/**
|
||||
* 自定义业务异常处理
|
||||
*/
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public R handleBusinessException(BusinessException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error(e.getCode(),e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public R handleDuplicateKeyException(DuplicateKeyException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error("数据库中已存在该记录");
|
||||
}
|
||||
|
||||
@ExceptionHandler(org.springframework.web.servlet.NoHandlerFoundException.class)
|
||||
public R noHandlerFoundException(org.springframework.web.servlet.NoHandlerFoundException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
return R.error(404, "没找找到页面");
|
||||
}
|
||||
|
||||
@ExceptionHandler(AuthorizationException.class)
|
||||
public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) {
|
||||
logger.error(e.getMessage(), e);
|
||||
if (HttpServletUtils.jsAjax(request)) {
|
||||
return R.error(403, "未授权");
|
||||
}
|
||||
return new ModelAndView("error/403");
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler({Exception.class})
|
||||
public Object handleException(Exception e, HttpServletRequest request) {
|
||||
LogDO logDO = new LogDO();
|
||||
logDO.setGmtCreate(new Date());
|
||||
logDO.setOperation(Constant.LOG_ERROR);
|
||||
logDO.setMethod(request.getRequestURL().toString());
|
||||
logDO.setParams(e.toString());
|
||||
UserDO current = ShiroUtils.getUser();
|
||||
if(null!=current){
|
||||
logDO.setUserId(current.getUserId());
|
||||
logDO.setUsername(current.getUsername());
|
||||
}
|
||||
logService.save(logDO);
|
||||
logger.error(e.getMessage(), e);
|
||||
if (HttpServletUtils.jsAjax(request)) {
|
||||
return R.error(500, "服务器错误,请联系管理员");
|
||||
}
|
||||
return new ModelAndView("error/500");
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.java2nb.common.exception;
|
||||
|
||||
|
||||
import com.java2nb.common.utils.R;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.boot.web.servlet.error.ErrorController;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
public class MainsiteErrorController implements ErrorController {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
private static final String ERROR_PATH = "/error";
|
||||
|
||||
@Autowired
|
||||
ErrorAttributes errorAttributes;
|
||||
|
||||
@RequestMapping(
|
||||
value = {ERROR_PATH},
|
||||
produces = {"text/html"}
|
||||
)
|
||||
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
|
||||
int code = response.getStatus();
|
||||
if (404 == code) {
|
||||
return new ModelAndView("error/404");
|
||||
} else if (403 == code) {
|
||||
return new ModelAndView("error/403");
|
||||
} else if (401 == code) {
|
||||
return new ModelAndView("login");
|
||||
} else {
|
||||
return new ModelAndView("error/500");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = ERROR_PATH)
|
||||
public R handleError(HttpServletRequest request, HttpServletResponse response) {
|
||||
response.setStatus(200);
|
||||
int code = response.getStatus();
|
||||
if (404 == code) {
|
||||
return R.error(404, "未找到资源");
|
||||
} else if (403 == code) {
|
||||
return R.error(403, "没有访问权限");
|
||||
} else if (401 == code) {
|
||||
return R.error(403, "登录过期");
|
||||
} else {
|
||||
return R.error(500, "服务器错误");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorPath() {
|
||||
// TODO Auto-generated method stub
|
||||
return ERROR_PATH;
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.java2nb.common.interceptor;
|
||||
|
||||
import com.java2nb.common.utils.ShiroUtils;
|
||||
import com.java2nb.system.domain.DataPermDO;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.apache.ibatis.cache.CacheKey;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Intercepts({@Signature(
|
||||
type = Executor.class,
|
||||
method = "query",
|
||||
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
|
||||
), @Signature(
|
||||
type = Executor.class,
|
||||
method = "query",
|
||||
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
|
||||
)})
|
||||
@Component
|
||||
public class DataPermInterceptor implements Interceptor {
|
||||
|
||||
|
||||
public DataPermInterceptor() {
|
||||
super();
|
||||
}
|
||||
|
||||
//插件运行的代码,它将代替原有的方法
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
Object[] args = invocation.getArgs();
|
||||
MappedStatement mappedStatement = (MappedStatement) args[0];
|
||||
String sqlId = mappedStatement.getId();
|
||||
String methodName = sqlId.substring(sqlId.lastIndexOf(".") + 1);
|
||||
if (methodName.endsWith("ByPerm")) {
|
||||
Object parameter = args[1];
|
||||
RowBounds rowBounds = (RowBounds) args[2];
|
||||
ResultHandler resultHandler = (ResultHandler) args[3];
|
||||
Executor executor = (Executor) invocation.getTarget();
|
||||
CacheKey cacheKey;
|
||||
BoundSql boundSql;
|
||||
if (args.length == 4) {
|
||||
boundSql = mappedStatement.getBoundSql(parameter);
|
||||
cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
|
||||
} else {
|
||||
cacheKey = (CacheKey) args[4];
|
||||
boundSql = (BoundSql) args[5];
|
||||
}
|
||||
Class<BoundSql> boundSqlClass = BoundSql.class;
|
||||
Field field = boundSqlClass.getDeclaredField("sql");
|
||||
field.setAccessible(true);
|
||||
String lastSql = boundSql.getSql();
|
||||
Pattern tableNamePattern = Pattern.compile("\\s+from\\s+([^\\s]+)\\s*");
|
||||
Matcher tableNameMatcher = tableNamePattern.matcher(lastSql);
|
||||
if (tableNameMatcher.find()) {
|
||||
String tableName = tableNameMatcher.group(1);
|
||||
if(!tableName.contains("_")){
|
||||
if(tableNameMatcher.find()) {
|
||||
tableName = tableNameMatcher.group(1);
|
||||
}
|
||||
}
|
||||
UserDO user = ShiroUtils.getUser();
|
||||
List<DataPermDO> perms = user.getDataPerms().get(tableName);
|
||||
String pageSql = "";
|
||||
int limitIndex = lastSql.indexOf(" limit ");
|
||||
if (limitIndex != -1) {
|
||||
pageSql = lastSql.substring(limitIndex);
|
||||
lastSql = lastSql.substring(0, limitIndex);
|
||||
}
|
||||
String orderSql = "";
|
||||
int orderIndex = lastSql.indexOf(" order ");
|
||||
if (orderIndex == -1) {
|
||||
orderIndex = lastSql.indexOf(" ORDER ");
|
||||
}
|
||||
if (orderIndex != -1) {
|
||||
orderSql = lastSql.substring(orderIndex);
|
||||
lastSql = lastSql.substring(0, orderIndex);
|
||||
}
|
||||
|
||||
String linkSql = " WHERE ";
|
||||
String permSql = "";
|
||||
boolean allPerms= false;
|
||||
if (perms != null && perms.size() > 0) {
|
||||
|
||||
Class userClass = UserDO.class;
|
||||
for (DataPermDO perm : perms) {
|
||||
if (allPerms) {
|
||||
break;
|
||||
}
|
||||
|
||||
String attrName = perm.getCrlAttrName();
|
||||
String columnName = perm.getCrlColumnName();
|
||||
String permCode = perm.getPermCode();
|
||||
|
||||
switch (permCode.substring(0, permCode.indexOf("_"))) {
|
||||
case "all": {
|
||||
allPerms = true;
|
||||
break;
|
||||
}
|
||||
case "own": {
|
||||
Field attrNameField = userClass.getDeclaredField(attrName);
|
||||
attrNameField.setAccessible(true);
|
||||
String attrValue = attrNameField.get(user) + "";
|
||||
permSql += ("or " + columnName + "=" + attrValue + " ");
|
||||
break;
|
||||
}
|
||||
case "sup": {
|
||||
Field supAttrNameField = userClass.getDeclaredField("sup" + (attrName.substring(0, 1).toUpperCase() + attrName.substring(1)) + "s");
|
||||
supAttrNameField.setAccessible(true);
|
||||
String supAttrValue = (String) supAttrNameField.get(user);
|
||||
permSql += ("or " + columnName + " in(" + supAttrValue + ") ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (!allPerms) {
|
||||
if(permSql.length()==0){
|
||||
permSql = "0";
|
||||
}else{
|
||||
permSql = permSql.replaceFirst("or","");
|
||||
}
|
||||
lastSql = lastSql + linkSql + "(" + permSql + ")";
|
||||
}
|
||||
lastSql += (orderSql + pageSql);
|
||||
|
||||
}
|
||||
|
||||
field.set(boundSql, lastSql);
|
||||
return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
// 拦截类型StatementHandler
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.java2nb.common.jsonserializer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LongToStringSerializer extends JsonSerializer<Long> {
|
||||
@Override
|
||||
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
|
||||
if(value != null){
|
||||
jsonGenerator.writeString(value+"");
|
||||
}else{
|
||||
jsonGenerator.writeNull();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheException;
|
||||
import org.apache.shiro.util.CollectionUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RedisCache<K, V> implements Cache<K, V> {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The wrapped Jedis instance.
|
||||
*/
|
||||
private RedisManager cache;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for the sessions
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_session:";
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过一个JedisManager实例构造RedisCache
|
||||
*/
|
||||
public RedisCache(RedisManager cache){
|
||||
if (cache == null) {
|
||||
throw new IllegalArgumentException("Cache argument cannot be null.");
|
||||
}
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a cache instance with the specified
|
||||
* Redis manager and using a custom key prefix.
|
||||
* @param cache The cache manager instance
|
||||
* @param prefix The Redis key prefix
|
||||
*/
|
||||
public RedisCache(RedisManager cache,
|
||||
String prefix){
|
||||
|
||||
this( cache );
|
||||
|
||||
// set the prefix
|
||||
this.keyPrefix = prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得byte[]型的key
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private byte[] getByteKey(K key){
|
||||
if(key instanceof String){
|
||||
String preKey = this.keyPrefix + key;
|
||||
return preKey.getBytes();
|
||||
}else{
|
||||
return SerializeUtils.serialize(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) throws CacheException {
|
||||
logger.debug("根据key从Redis中获取对象 key [" + key + "]");
|
||||
try {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}else{
|
||||
byte[] rawValue = cache.get(getByteKey(key));
|
||||
@SuppressWarnings("unchecked")
|
||||
V value = (V)SerializeUtils.deserialize(rawValue);
|
||||
return value;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) throws CacheException {
|
||||
logger.debug("根据key从存储 key [" + key + "]");
|
||||
try {
|
||||
cache.set(getByteKey(key), SerializeUtils.serialize(value));
|
||||
return value;
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(K key) throws CacheException {
|
||||
logger.debug("从redis中删除 key [" + key + "]");
|
||||
try {
|
||||
V previous = get(key);
|
||||
cache.del(getByteKey(key));
|
||||
return previous;
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() throws CacheException {
|
||||
logger.debug("从redis中删除所有元素");
|
||||
try {
|
||||
cache.flushDB();
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
try {
|
||||
Long longSize = new Long(cache.dbSize());
|
||||
return longSize.intValue();
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Set<K> keys() {
|
||||
try {
|
||||
Set<byte[]> keys = cache.keys(this.keyPrefix + "*");
|
||||
if (CollectionUtils.isEmpty(keys)) {
|
||||
return Collections.emptySet();
|
||||
}else{
|
||||
Set<K> newKeys = new HashSet<K>();
|
||||
for(byte[] key:keys){
|
||||
newKeys.add((K)key);
|
||||
}
|
||||
return newKeys;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
try {
|
||||
Set<byte[]> keys = cache.keys(this.keyPrefix + "*");
|
||||
if (!CollectionUtils.isEmpty(keys)) {
|
||||
List<V> values = new ArrayList<V>(keys.size());
|
||||
for (byte[] key : keys) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V value = get((K)key);
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(values);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new CacheException(t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheException;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RedisCacheManager implements CacheManager {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(RedisCacheManager.class);
|
||||
|
||||
// fast lookup by name map
|
||||
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
|
||||
|
||||
private RedisManager redisManager;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for caches
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_cache:";
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
|
||||
logger.debug("获取名称为: " + name + " 的RedisCache实例");
|
||||
|
||||
Cache c = caches.get(name);
|
||||
|
||||
if (c == null) {
|
||||
|
||||
// initialize the Redis manager instance
|
||||
redisManager.init();
|
||||
|
||||
// create a new cache instance
|
||||
c = new RedisCache<K, V>(redisManager, keyPrefix);
|
||||
|
||||
// add it to the cache collection
|
||||
caches.put(name, c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public RedisManager getRedisManager() {
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
public void setRedisManager(RedisManager redisManager) {
|
||||
this.redisManager = redisManager;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RedisManager {
|
||||
|
||||
@Value("${spring.redis.host}")
|
||||
private String host = "127.0.0.1";
|
||||
|
||||
@Value("${spring.redis.port}")
|
||||
private int port = 6379;
|
||||
|
||||
// 0 - never expire
|
||||
private int expire = 0;
|
||||
|
||||
//timeout for jedis try to connect to redis server, not expire time! In milliseconds
|
||||
@Value("${spring.redis.timeout}")
|
||||
private int timeout = 0;
|
||||
|
||||
@Value("${spring.redis.password}")
|
||||
private String password = "";
|
||||
|
||||
private static JedisPool jedisPool = null;
|
||||
|
||||
public RedisManager() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化方法
|
||||
*/
|
||||
public void init() {
|
||||
if (jedisPool == null) {
|
||||
if (password != null && !"".equals(password)) {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password);
|
||||
} else if (timeout != 0) {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout);
|
||||
} else {
|
||||
jedisPool = new JedisPool(new JedisPoolConfig(), host, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get value from redis
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public byte[] get(byte[] key) {
|
||||
byte[] value = null;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
value = jedis.get(key);
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* set
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public byte[] set(byte[] key, byte[] value) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.set(key, value);
|
||||
if (this.expire != 0) {
|
||||
jedis.expire(key, this.expire);
|
||||
}
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* set
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param expire
|
||||
* @return
|
||||
*/
|
||||
public byte[] set(byte[] key, byte[] value, int expire) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.set(key, value);
|
||||
if (expire != 0) {
|
||||
jedis.expire(key, expire);
|
||||
}
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* del
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void del(byte[] key) {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.del(key);
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* flush
|
||||
*/
|
||||
public void flushDB() {
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
jedis.flushDB();
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* size
|
||||
*/
|
||||
public Long dbSize() {
|
||||
Long dbSize = 0L;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
dbSize = jedis.dbSize();
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return dbSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* keys
|
||||
*
|
||||
* @param regex
|
||||
* @return
|
||||
*/
|
||||
public Set<byte[]> keys(String pattern) {
|
||||
Set<byte[]> keys = null;
|
||||
Jedis jedis = jedisPool.getResource();
|
||||
try {
|
||||
keys = jedis.keys(pattern.getBytes());
|
||||
} finally {
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
public void setExpire(int expire) {
|
||||
this.expire = expire;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.UnknownSessionException;
|
||||
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
public class RedisSessionDAO extends AbstractSessionDAO {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
|
||||
/**
|
||||
* shiro-redis的session对象前缀
|
||||
*/
|
||||
private RedisManager redisManager;
|
||||
|
||||
/**
|
||||
* The Redis key prefix for the sessions
|
||||
*/
|
||||
private String keyPrefix = "shiro_redis_session:";
|
||||
|
||||
@Override
|
||||
public void update(Session session) throws UnknownSessionException {
|
||||
this.saveSession(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* save session
|
||||
* @param session
|
||||
* @throws UnknownSessionException
|
||||
*/
|
||||
private void saveSession(Session session) throws UnknownSessionException{
|
||||
if(session == null || session.getId() == null){
|
||||
logger.error("session or session id is null");
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] key = getByteKey(session.getId());
|
||||
byte[] value = SerializeUtils.serialize(session);
|
||||
session.setTimeout(redisManager.getExpire()*1000);
|
||||
this.redisManager.set(key, value, redisManager.getExpire());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Session session) {
|
||||
if(session == null || session.getId() == null){
|
||||
logger.error("session or session id is null");
|
||||
return;
|
||||
}
|
||||
redisManager.del(this.getByteKey(session.getId()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Session> getActiveSessions() {
|
||||
Set<Session> sessions = new HashSet<Session>();
|
||||
|
||||
Set<byte[]> keys = redisManager.keys(this.keyPrefix + "*");
|
||||
if(keys != null && keys.size()>0){
|
||||
for(byte[] key:keys){
|
||||
Session s = (Session)SerializeUtils.deserialize(redisManager.get(key));
|
||||
sessions.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable doCreate(Session session) {
|
||||
Serializable sessionId = this.generateSessionId(session);
|
||||
this.assignSessionId(session, sessionId);
|
||||
this.saveSession(session);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session doReadSession(Serializable sessionId) {
|
||||
if(sessionId == null){
|
||||
logger.error("session id is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
Session s = (Session)SerializeUtils.deserialize(redisManager.get(this.getByteKey(sessionId)));
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得byte[]型的key
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private byte[] getByteKey(Serializable sessionId){
|
||||
String preKey = this.keyPrefix + sessionId;
|
||||
return preKey.getBytes();
|
||||
}
|
||||
|
||||
public RedisManager getRedisManager() {
|
||||
return redisManager;
|
||||
}
|
||||
|
||||
public void setRedisManager(RedisManager redisManager) {
|
||||
this.redisManager = redisManager;
|
||||
|
||||
/**
|
||||
* 初始化redisManager
|
||||
*/
|
||||
this.redisManager.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Redis session keys
|
||||
* prefix.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getKeyPrefix() {
|
||||
return keyPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Redis sessions key
|
||||
* prefix.
|
||||
* @param keyPrefix The prefix
|
||||
*/
|
||||
public void setKeyPrefix(String keyPrefix) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.java2nb.common.redis.shiro;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @version V1.0
|
||||
*/
|
||||
public class SerializeUtils {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
|
||||
|
||||
/**
|
||||
* 反序列化
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static Object deserialize(byte[] bytes) {
|
||||
|
||||
Object result = null;
|
||||
|
||||
if (isEmpty(bytes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
|
||||
try {
|
||||
ObjectInputStream objectInputStream = new ObjectInputStream(byteStream);
|
||||
try {
|
||||
result = objectInputStream.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new Exception("Failed to deserialize object type", ex);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new Exception("Failed to deserialize", ex);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to deserialize",e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(byte[] data) {
|
||||
return (data == null || data.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static byte[] serialize(Object object) {
|
||||
|
||||
byte[] result = null;
|
||||
|
||||
if (object == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
try {
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
|
||||
try {
|
||||
if (!(object instanceof Serializable)) {
|
||||
throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
|
||||
"but received an object of type [" + object.getClass().getName() + "]");
|
||||
}
|
||||
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
|
||||
objectOutputStream.writeObject(object);
|
||||
objectOutputStream.flush();
|
||||
result = byteStream.toByteArray();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new Exception("Failed to serialize", ex);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("Failed to serialize",ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典表
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-29 18:28:07
|
||||
*/
|
||||
public interface DictService {
|
||||
|
||||
DictDO get(Long id);
|
||||
|
||||
List<DictDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(DictDO dict);
|
||||
|
||||
int update(DictDO dict);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
List<DictDO> listType();
|
||||
|
||||
String getName(String type,String value);
|
||||
|
||||
/**
|
||||
* 获取爱好列表
|
||||
* @return
|
||||
* @param userDO
|
||||
*/
|
||||
List<DictDO> getHobbyList(UserDO userDO);
|
||||
|
||||
/**
|
||||
* 获取性别列表
|
||||
* @return
|
||||
*/
|
||||
List<DictDO> getSexList();
|
||||
|
||||
/**
|
||||
* 根据type获取数据
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
List<DictDO> listByType(String type);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @author xiongxy
|
||||
* @email 1179705413@qq.com
|
||||
* @date 2019-09-19 16:02:20
|
||||
*/
|
||||
public interface FileService {
|
||||
|
||||
FileDO get(Long id);
|
||||
|
||||
List<FileDO> list(Map<String, Object> map);
|
||||
|
||||
int count(Map<String, Object> map);
|
||||
|
||||
int save(FileDO sysFile);
|
||||
|
||||
int update(FileDO sysFile);
|
||||
|
||||
int remove(Long id);
|
||||
|
||||
int batchRemove(Long[] ids);
|
||||
|
||||
/**
|
||||
* 判断一个文件是否存在
|
||||
* @param url FileDO中存的路径
|
||||
* @return
|
||||
*/
|
||||
Boolean isExist(String url);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @Time 2019-10-20 11:23:09
|
||||
* @description
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public interface GeneratorService {
|
||||
List<Map<String, Object>> list(String tableName);
|
||||
|
||||
void generatorCode(String[] tableNames);
|
||||
|
||||
byte[] downloadCode(String[] tableNames);
|
||||
|
||||
|
||||
List<GenColumnsDO> listColumnsByTableName(String tableName);
|
||||
|
||||
boolean genColumnsSave(List<GenColumnsDO> list);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.java2nb.common.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.utils.Query;
|
||||
@Service
|
||||
public interface LogService {
|
||||
void save(LogDO logDO);
|
||||
PageDO<LogDO> queryList(Query query);
|
||||
int remove(Long id);
|
||||
int batchRemove(Long[] ids);
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import com.java2nb.common.utils.StringUtils;
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.java2nb.common.dao.DictDao;
|
||||
import com.java2nb.common.domain.DictDO;
|
||||
import com.java2nb.common.service.DictService;
|
||||
|
||||
|
||||
@Service
|
||||
public class DictServiceImpl implements DictService {
|
||||
@Autowired
|
||||
private DictDao dictDao;
|
||||
|
||||
@Override
|
||||
public DictDO get(Long id) {
|
||||
return dictDao.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> list(Map<String, Object> map) {
|
||||
return dictDao.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map) {
|
||||
return dictDao.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(DictDO dict) {
|
||||
return dictDao.save(dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(DictDO dict) {
|
||||
return dictDao.update(dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id) {
|
||||
return dictDao.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids) {
|
||||
return dictDao.batchRemove(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public List<DictDO> listType() {
|
||||
return dictDao.listType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(String type, String value) {
|
||||
Map<String, Object> param = new HashMap<String, Object>(16);
|
||||
param.put("type", type);
|
||||
param.put("value", value);
|
||||
String rString = dictDao.list(param).get(0).getName();
|
||||
return rString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> getHobbyList(UserDO userDO) {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", "hobby");
|
||||
List<DictDO> hobbyList = dictDao.list(param);
|
||||
|
||||
if (StringUtils.isNotEmpty(userDO.getHobby())) {
|
||||
String userHobbys[] = userDO.getHobby().split(";");
|
||||
for (String userHobby : userHobbys) {
|
||||
for (DictDO hobby : hobbyList) {
|
||||
if (!Objects.equals(userHobby, hobby.getId().toString())) {
|
||||
continue;
|
||||
}
|
||||
hobby.setRemarks("true");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hobbyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> getSexList() {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", "sex");
|
||||
return dictDao.list(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictDO> listByType(String type) {
|
||||
Map<String, Object> param = new HashMap<>(16);
|
||||
param.put("type", type);
|
||||
return dictDao.list(param);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import com.java2nb.common.config.JnConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.java2nb.common.dao.FileDao;
|
||||
import com.java2nb.common.domain.FileDO;
|
||||
import com.java2nb.common.service.FileService;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@Service
|
||||
public class FileServiceImpl implements FileService {
|
||||
@Autowired
|
||||
private FileDao sysFileMapper;
|
||||
|
||||
@Autowired
|
||||
private JnConfig jnConfig;
|
||||
@Override
|
||||
public FileDO get(Long id){
|
||||
return sysFileMapper.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileDO> list(Map<String, Object> map){
|
||||
return sysFileMapper.list(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count(Map<String, Object> map){
|
||||
return sysFileMapper.count(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int save(FileDO sysFile){
|
||||
return sysFileMapper.save(sysFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(FileDO sysFile){
|
||||
return sysFileMapper.update(sysFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id){
|
||||
return sysFileMapper.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return sysFileMapper.batchRemove(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isExist(String url) {
|
||||
Boolean isExist = false;
|
||||
if (!StringUtils.isEmpty(url)) {
|
||||
String filePath = url.replace("/files/", "");
|
||||
filePath = jnConfig.getUploadPath() + filePath;
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
isExist = true;
|
||||
}
|
||||
}
|
||||
return isExist;
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import com.java2nb.common.dao.GenColumnsDao;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.dao.GeneratorMapper;
|
||||
import com.java2nb.common.service.GeneratorService;
|
||||
import com.java2nb.common.utils.GenUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
@Service
|
||||
public class GeneratorServiceImpl implements GeneratorService {
|
||||
@Autowired
|
||||
GeneratorMapper generatorMapper;
|
||||
|
||||
@Autowired
|
||||
GenColumnsDao genColumnsDao;
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> list(String tableName) {
|
||||
List<Map<String, Object>> list = generatorMapper.list(tableName);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generatorCode(String[] tableNames) {
|
||||
for (String tableName : tableNames) {
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table, columns, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] downloadCode(String[] tableNames) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ZipOutputStream zip = new ZipOutputStream(outputStream);
|
||||
for (String tableName : tableNames) {
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table, columns, zip);
|
||||
}
|
||||
IOUtils.closeQuietly(zip);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<GenColumnsDO> listColumnsByTableName(String tableName) {
|
||||
Map<String, Object> query = new HashMap<>();
|
||||
query.put("tableName", tableName);
|
||||
query.put("sort", "column_sort");
|
||||
query.put("order", "asc");
|
||||
List<GenColumnsDO> columnList = genColumnsDao.list(query);
|
||||
if (columnList.size() == 0) {
|
||||
//查询列信息
|
||||
List<Map<String, String>> columns = generatorMapper.listColumns(tableName);
|
||||
|
||||
int columnSort = 0;
|
||||
for (Map<String, String> column : columns) {
|
||||
GenColumnsDO genColumnsDO = transGenColumnDO(tableName,column,++columnSort);
|
||||
|
||||
if(!"PRI".equalsIgnoreCase(column.get("columnKey"))) {
|
||||
columnList.add(genColumnsDO);
|
||||
}else{
|
||||
genColumnsDO.setColumnSort(0);
|
||||
genColumnsDO.setPageType(11);
|
||||
columnList.add(0,genColumnsDO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
Map<String, String> column = generatorMapper.getPriColumn(tableName);
|
||||
GenColumnsDO genColumnsDO = transGenColumnDO(tableName,column,0);
|
||||
genColumnsDO.setPageType(11);
|
||||
columnList.add(0,genColumnsDO);
|
||||
}
|
||||
return columnList;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public boolean genColumnsSave(List<GenColumnsDO> list) {
|
||||
GenColumnsDO pkColumn = list.get(0);
|
||||
String tableName = pkColumn.getTableName();
|
||||
genColumnsDao.deleteByTableName(tableName);
|
||||
list.remove(0);
|
||||
genColumnsDao.saveBatch(list);
|
||||
//查询表信息
|
||||
Map<String, String> table = generatorMapper.get(tableName);
|
||||
//生成代码
|
||||
GenUtils.generatorCode(table,pkColumn, list);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public GenColumnsDO transGenColumnDO(String tableName,Map<String, String> column,int columnSort){
|
||||
GenColumnsDO genColumnsDO = new GenColumnsDO();
|
||||
genColumnsDO.setTableName(tableName);
|
||||
genColumnsDO.setColumnName(column.get("columnName"));
|
||||
genColumnsDO.setColumnType(column.get("dataType"));
|
||||
genColumnsDO.setColumnComment(column.get("columnComment"));
|
||||
PropertiesConfiguration conf = new PropertiesConfiguration("generator.properties");
|
||||
genColumnsDO.setJavaType(conf.getString(column.get("dataType")));
|
||||
genColumnsDO.setColumnSort(columnSort);
|
||||
genColumnsDO.setExtra(column.get("extra"));
|
||||
genColumnsDO.setIsRequired(0);
|
||||
if ("Date".equals(conf.getString(column.get("dataType")))) {
|
||||
genColumnsDO.setPageType(4);
|
||||
|
||||
} else {
|
||||
genColumnsDO.setPageType(1);
|
||||
}
|
||||
genColumnsDO.setColumnLabel(column.get("columnComment"));
|
||||
return genColumnsDO;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.java2nb.common.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.java2nb.common.dao.LogDao;
|
||||
import com.java2nb.common.domain.LogDO;
|
||||
import com.java2nb.common.domain.PageDO;
|
||||
import com.java2nb.common.service.LogService;
|
||||
import com.java2nb.common.utils.Query;
|
||||
|
||||
@Service
|
||||
public class LogServiceImpl implements LogService {
|
||||
@Autowired
|
||||
LogDao logMapper;
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void save(LogDO logDO) {
|
||||
logMapper.save(logDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageDO<LogDO> queryList(Query query) {
|
||||
int total = logMapper.count(query);
|
||||
List<LogDO> logs = logMapper.list(query);
|
||||
PageDO<LogDO> page = new PageDO<>();
|
||||
page.setTotal(total);
|
||||
page.setRows(logs);
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remove(Long id) {
|
||||
int count = logMapper.remove(id);
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchRemove(Long[] ids){
|
||||
return logMapper.batchRemove(ids);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/**
|
||||
* 自定义异常
|
||||
*
|
||||
*/
|
||||
public class BDException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String msg;
|
||||
private int code = 500;
|
||||
|
||||
public BDException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public BDException(String msg, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public BDException(String msg, int code) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BDException(String msg, int code, Throwable e) {
|
||||
super(msg, e);
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class Base64Utils {
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.java2nb.common.domain.Tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BuildTree {
|
||||
|
||||
public static <T> Tree<T> build(List<Tree<T>> nodes) {
|
||||
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
List<Tree<T>> topNodes = new ArrayList<Tree<T>>();
|
||||
|
||||
for (Tree<T> children : nodes) {
|
||||
|
||||
String pid = children.getParentId();
|
||||
if (pid == null || "0".equals(pid)) {
|
||||
topNodes.add(children);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Tree<T> parent : nodes) {
|
||||
String id = parent.getId();
|
||||
if (id != null && id.equals(pid)) {
|
||||
parent.getChildren().add(children);
|
||||
children.setHasParent(true);
|
||||
parent.setChildren(true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Tree<T> root = new Tree<T>();
|
||||
if (topNodes.size() == 1) {
|
||||
root = topNodes.get(0);
|
||||
} else {
|
||||
root.setId("-1");
|
||||
root.setParentId("");
|
||||
root.setHasParent(false);
|
||||
root.setChildren(true);
|
||||
root.setChecked(true);
|
||||
root.setChildren(topNodes);
|
||||
root.setText("顶级节点");
|
||||
Map<String, Object> state = new HashMap<>(16);
|
||||
state.put("opened", true);
|
||||
root.setState(state);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static <T> List<Tree<T>> buildList(List<Tree<T>> nodes, String idParam) {
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
List<Tree<T>> topNodes = new ArrayList<Tree<T>>();
|
||||
|
||||
for (Tree<T> children : nodes) {
|
||||
|
||||
String pid = children.getParentId();
|
||||
if (pid == null || idParam.equals(pid)) {
|
||||
topNodes.add(children);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Tree<T> parent : nodes) {
|
||||
String id = parent.getId();
|
||||
if (id != null && id.equals(pid)) {
|
||||
parent.getChildren().add(children);
|
||||
children.setHasParent(true);
|
||||
parent.setChildren(true);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return topNodes;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 日期处理
|
||||
*/
|
||||
public class DateUtils {
|
||||
private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
|
||||
public final static String YEAR_PATTERN = "yyyy";
|
||||
public final static String MONTH_PATTERN = "MM";
|
||||
public final static String DAY_PATTERN = "dd";
|
||||
/**
|
||||
* 时间格式(yyyy-MM-dd)
|
||||
*/
|
||||
public final static String DATE_PATTERN = "yyyy-MM-dd";
|
||||
/**
|
||||
* 时间格式(yyyy-MM-dd HH:mm:ss)
|
||||
*/
|
||||
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static String format(Date date) {
|
||||
return format(date, DATE_PATTERN);
|
||||
}
|
||||
|
||||
public static String format(Date date, String pattern) {
|
||||
if (date != null) {
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(date);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离现在多久,非精确
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeBefore(Date date) {
|
||||
Date now = new Date();
|
||||
long l = now.getTime() - date.getTime();
|
||||
long day = l / (24 * 60 * 60 * 1000);
|
||||
long hour = (l / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
String r = "";
|
||||
if (day > 0) {
|
||||
r += day + "天";
|
||||
} else if (hour > 0) {
|
||||
r += hour + "小时";
|
||||
} else if (min > 0) {
|
||||
r += min + "分";
|
||||
} else if (s > 0) {
|
||||
r += s + "秒";
|
||||
}
|
||||
r += "前";
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离现在多久,精确
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeBeforeAccurate(Date date) {
|
||||
Date now = new Date();
|
||||
long l = now.getTime() - date.getTime();
|
||||
long day = l / (24 * 60 * 60 * 1000);
|
||||
long hour = (l / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
String r = "";
|
||||
if (day > 0) {
|
||||
r += day + "天";
|
||||
}
|
||||
if (hour > 0) {
|
||||
r += hour + "小时";
|
||||
}
|
||||
if (min > 0) {
|
||||
r += min + "分";
|
||||
}
|
||||
if (s > 0) {
|
||||
r += s + "秒";
|
||||
}
|
||||
r += "前";
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过去第几天的日期
|
||||
*
|
||||
* @param past
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String getPastDate(int past,Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
|
||||
Date today = calendar.getTime();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return sdf.format(today);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过去几天的日期集合
|
||||
*
|
||||
* @param past
|
||||
* @return
|
||||
*/
|
||||
public static List<String> getDateList(int past,Date date) {
|
||||
List<String> result = new ArrayList<>(past);
|
||||
for(int i = past - 1 ; i > 0 ; i--){
|
||||
result.add(getPastDate(i,date));
|
||||
}
|
||||
//今天的日期
|
||||
result.add(new SimpleDateFormat("yyyy-MM-dd").format(date));
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class ExceptionUtils {
|
||||
public static String getExceptionAllinformation(Exception ex) {
|
||||
String sOut = "";
|
||||
StackTraceElement[] trace = ex.getStackTrace();
|
||||
for (StackTraceElement s : trace) {
|
||||
sOut += "\tat " + s + "\r\n";
|
||||
}
|
||||
return sOut;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/* author:zss
|
||||
* 日期:2017年3月31日
|
||||
* 功能:根据文件名称判断类型
|
||||
* 接受参数类型:String
|
||||
* 返回参数类型:String
|
||||
* 备注:文件类型不完善,有需要的自行添加
|
||||
*/
|
||||
public class FileType {
|
||||
public static int fileType(String fileName) {
|
||||
if (fileName == null) {
|
||||
fileName = "文件名为空!";
|
||||
return 500;
|
||||
|
||||
} else {
|
||||
// 获取文件后缀名并转化为写,用于后续比较
|
||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
|
||||
// 创建图片类型数组0
|
||||
String[] img = { "bmp", "jpg", "jpeg", "png", "tiff", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd",
|
||||
"cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "wmf" };
|
||||
for (int i = 0; i < img.length; i++) {
|
||||
if (img[i].equals(fileType)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建文档类型数组1
|
||||
String[] document = { "txt", "doc", "docx", "xls", "htm", "html", "jsp", "rtf", "wpd", "pdf", "ppt" };
|
||||
for (int i = 0; i < document.length; i++) {
|
||||
if (document[i].equals(fileType)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// 创建视频类型数组2
|
||||
String[] video = { "mp4", "avi", "mov", "wmv", "asf", "navi", "3gp", "mkv", "f4v", "rmvb", "webm" };
|
||||
for (int i = 0; i < video.length; i++) {
|
||||
if (video[i].equals(fileType)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
// 创建音乐类型数组3
|
||||
String[] music = { "mp3", "wma", "wav", "mod", "ra", "cd", "md", "asf", "aac", "vqf", "ape", "mid", "ogg",
|
||||
"m4a", "vqf" };
|
||||
for (int i = 0; i < music.length; i++) {
|
||||
if (music[i].equals(fileType)) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//4
|
||||
return 99;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
|
||||
File targetFile = new File(filePath);
|
||||
if (!targetFile.exists()) {
|
||||
targetFile.mkdirs();
|
||||
}
|
||||
FileOutputStream out = new FileOutputStream(filePath + fileName);
|
||||
out.write(file);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static boolean deleteFile(String fileName) {
|
||||
File file = new File(fileName);
|
||||
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
|
||||
if (file.exists() && file.isFile()) {
|
||||
if (file.delete()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String renameToUUID(String fileName) {
|
||||
return UUID.randomUUID() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
}
|
376
novel-admin/src/main/java/com/java2nb/common/utils/GenUtils.java
Normal file
376
novel-admin/src/main/java/com/java2nb/common/utils/GenUtils.java
Normal file
@ -0,0 +1,376 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
|
||||
import com.java2nb.common.config.Constant;
|
||||
import com.java2nb.common.domain.ColumnDO;
|
||||
import com.java2nb.common.domain.GenColumnsDO;
|
||||
import com.java2nb.common.domain.TableDO;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.ConfigurationException;
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 代码生成器 工具类
|
||||
*/
|
||||
public class GenUtils {
|
||||
|
||||
|
||||
public static List<String> getTemplates() {
|
||||
List<String> templates = new ArrayList<String>();
|
||||
templates.add("templates/common/generator/domain.java.vm");
|
||||
templates.add("templates/common/generator/Dao.java.vm");
|
||||
//templates.add("templates/common/generator/Mapper.java.vm");
|
||||
templates.add("templates/common/generator/Mapper.xml.vm");
|
||||
templates.add("templates/common/generator/Service.java.vm");
|
||||
templates.add("templates/common/generator/ServiceImpl.java.vm");
|
||||
templates.add("templates/common/generator/Controller.java.vm");
|
||||
templates.add("templates/common/generator/list.html.vm");
|
||||
templates.add("templates/common/generator/add.html.vm");
|
||||
templates.add("templates/common/generator/edit.html.vm");
|
||||
templates.add("templates/common/generator/detail.html.vm");
|
||||
templates.add("templates/common/generator/list.js.vm");
|
||||
templates.add("templates/common/generator/add.js.vm");
|
||||
templates.add("templates/common/generator/edit.js.vm");
|
||||
templates.add("templates/common/generator/menu.sql.vm");
|
||||
|
||||
//templates.add("templates/common/generator/menu.sql.vm");
|
||||
return templates;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*/
|
||||
|
||||
|
||||
public static void generatorCode(Map<String, String> table,
|
||||
List<Map<String, String>> columns, ZipOutputStream zip) {
|
||||
/*//封装模板数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
|
||||
|
||||
//配置信息
|
||||
Configuration config = getConfig();
|
||||
//表信息
|
||||
TableDO tableDO = new TableDO();
|
||||
tableDO.setTableName(table.get("tableName"));
|
||||
tableDO.setComments(table.get("tableComment"));
|
||||
//表名转换成Java类名
|
||||
String className = tableToJava(tableDO.getTableName(), config.getString("tablePrefix"), config.getString("autoRemovePre"));
|
||||
tableDO.setClassName(className);
|
||||
tableDO.setClassname(StringUtils.uncapitalize(className));
|
||||
|
||||
//列信息
|
||||
List<ColumnDO> columsList = new ArrayList<>();
|
||||
for (Map<String, String> column : columns) {
|
||||
ColumnDO columnDO = new ColumnDO();
|
||||
columnDO.setColumnName(column.get("columnName"));
|
||||
columnDO.setDataType(column.get("dataType"));
|
||||
columnDO.setComments(column.get("columnComment"));
|
||||
columnDO.setExtra(column.get("extra"));
|
||||
|
||||
//列名转换成Java属性名
|
||||
String attrName = columnToJava(columnDO.getColumnName());
|
||||
columnDO.setAttrName(attrName);
|
||||
columnDO.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
|
||||
//列的数据类型,转换成Java类型
|
||||
String attrType = config.getString(columnDO.getDataType(), "unknowType");
|
||||
switch (attrType) {
|
||||
case "BigDecimal": {
|
||||
map.put("hasBigDecimal", true);
|
||||
break;
|
||||
}
|
||||
case "Date": {
|
||||
map.put("hasDate", true);
|
||||
break;
|
||||
}
|
||||
case "Long": {
|
||||
map.put("hasLong", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
columnDO.setAttrType(attrType);
|
||||
|
||||
//是否主键
|
||||
if ("PRI".equalsIgnoreCase(column.get("columnKey")) && tableDO.getPk() == null) {
|
||||
tableDO.setPk(columnDO);
|
||||
}
|
||||
|
||||
columsList.add(columnDO);
|
||||
}
|
||||
tableDO.setColumns(columsList);
|
||||
|
||||
//没主键,则第一个字段为主键
|
||||
if (tableDO.getPk() == null) {
|
||||
tableDO.setPk(tableDO.getColumns().get(0));
|
||||
}
|
||||
|
||||
//设置velocity资源加载器
|
||||
Properties prop = new Properties();
|
||||
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
Velocity.init(prop);
|
||||
|
||||
|
||||
map.put("tableName", tableDO.getTableName());
|
||||
map.put("comments", tableDO.getComments());
|
||||
map.put("pk", tableDO.getPk());
|
||||
map.put("className", tableDO.getClassName());
|
||||
map.put("classname", tableDO.getClassname());
|
||||
map.put("pathName", config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
|
||||
map.put("columns", tableDO.getColumns());
|
||||
map.put("package", config.getString("package"));
|
||||
map.put("author", config.getString("author"));
|
||||
map.put("email", config.getString("email"));
|
||||
map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
|
||||
VelocityContext context = new VelocityContext(map);
|
||||
|
||||
//获取模板列表
|
||||
List<String> templates = getTemplates();
|
||||
for (String template : templates) {
|
||||
//渲染模板
|
||||
StringWriter sw = new StringWriter();
|
||||
Template tpl = Velocity.getTemplate(template, "UTF-8");
|
||||
tpl.merge(context, sw);
|
||||
|
||||
try {
|
||||
String fileName = getFileName(template, tableDO.getClassname(), tableDO.getClassName(), config.getString("package"));
|
||||
if (zip != null) {
|
||||
//添加到zip
|
||||
zip.putNextEntry(new ZipEntry(fileName));
|
||||
IOUtils.write(sw.toString(), zip, "UTF-8");
|
||||
IOUtils.closeQuietly(sw);
|
||||
zip.closeEntry();
|
||||
} else {
|
||||
String srcPath = config.getString("srcPath");
|
||||
fileName = srcPath + File.separator + fileName;
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
file = new File(fileName + 1);
|
||||
}
|
||||
File parentCatelog = file.getParentFile();
|
||||
if (!parentCatelog.exists()) {
|
||||
parentCatelog.mkdirs();
|
||||
}
|
||||
OutputStream fos = new FileOutputStream(file);
|
||||
IOUtils.write(sw.toString(), fos, "UTF-8");
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("渲染模板失败,表名:" + tableDO.getTableName(), e);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 列名转换成Java属性名
|
||||
*/
|
||||
public static String columnToJava(String columnName) {
|
||||
return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 表名转换成Java类名
|
||||
*/
|
||||
public static String tableToJava(String tableName, String tablePrefix, String autoRemovePre) {
|
||||
if (Constant.AUTO_REOMVE_PRE.equals(autoRemovePre)) {
|
||||
tableName = tableName.substring(tableName.indexOf("_") + 1);
|
||||
}
|
||||
if (StringUtils.isNotBlank(tablePrefix)) {
|
||||
tableName = tableName.replace(tablePrefix, "");
|
||||
}
|
||||
|
||||
return columnToJava(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
*/
|
||||
public static Configuration getConfig() {
|
||||
try {
|
||||
return new PropertiesConfiguration("generator.properties");
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException("获取配置文件失败,", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
*/
|
||||
public static String getFileName(String template, String classname, String className, String packageName) {
|
||||
String moduleName = packageName.substring(packageName.lastIndexOf(".") + 1);
|
||||
|
||||
String javaPackagePath = "main" + File.separator + "java" + File.separator;
|
||||
//String modulesname=config.getString("packageName");
|
||||
if (StringUtils.isNotBlank(packageName)) {
|
||||
javaPackagePath += packageName.replace(".", File.separator) + File.separator;
|
||||
}
|
||||
|
||||
if (template.contains("domain.java.vm")) {
|
||||
return javaPackagePath + "domain" + File.separator + className + "DO.java";
|
||||
}
|
||||
|
||||
if (template.contains("Dao.java.vm")) {
|
||||
return javaPackagePath + "dao" + File.separator + className + "Dao.java";
|
||||
}
|
||||
|
||||
// if(template.contains("Mapper.java.vm")){
|
||||
// return packagePath + "dao" + File.separator + className + "Mapper.java";
|
||||
// }
|
||||
|
||||
if (template.contains("Service.java.vm")) {
|
||||
return javaPackagePath + "service" + File.separator + className + "Service.java";
|
||||
}
|
||||
|
||||
if (template.contains("ServiceImpl.java.vm")) {
|
||||
return javaPackagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
|
||||
}
|
||||
|
||||
if (template.contains("Controller.java.vm")) {
|
||||
return javaPackagePath + "controller" + File.separator + className + "Controller.java";
|
||||
}
|
||||
|
||||
if (template.contains("Mapper.xml.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "mybatis" + File.separator + moduleName + File.separator + className + "Mapper.xml";
|
||||
}
|
||||
|
||||
if (template.contains("list.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + classname + ".html";
|
||||
// + "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".html";
|
||||
}
|
||||
if (template.contains("add.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "add.html";
|
||||
}
|
||||
if (template.contains("edit.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "edit.html";
|
||||
}
|
||||
if (template.contains("detail.html.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
|
||||
+ moduleName + File.separator + classname + File.separator + "detail.html";
|
||||
}
|
||||
|
||||
if (template.contains("list.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + classname + ".js";
|
||||
// + "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".js";
|
||||
}
|
||||
if (template.contains("add.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + "add.js";
|
||||
}
|
||||
if (template.contains("edit.js.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
|
||||
+ "appjs" + File.separator + moduleName + File.separator + classname + File.separator + "edit.js";
|
||||
}
|
||||
if (template.contains("menu.sql.vm")) {
|
||||
return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "sql"
|
||||
+ File.separator + moduleName + File.separator + classname + File.separator + "menu.js";
|
||||
}
|
||||
|
||||
// if(template.contains("menu.sql.vm")){
|
||||
// return className.toLowerCase() + "_menu.sql";
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void generatorCode(Map<String, String> table, GenColumnsDO pkColumn, List<GenColumnsDO> list) {
|
||||
//封装模板数据
|
||||
Map<String, Object> map = new HashMap<>(16);
|
||||
|
||||
|
||||
//配置信息
|
||||
Configuration config = getConfig();
|
||||
//表信息
|
||||
TableDO tableDO = new TableDO();
|
||||
tableDO.setTableName(table.get("tableName"));
|
||||
tableDO.setComments(table.get("tableComment"));
|
||||
//表名转换成Java类名
|
||||
String className = tableToJava(tableDO.getTableName(), config.getString("tablePrefix"), config.getString("autoRemovePre"));
|
||||
tableDO.setClassName(className);
|
||||
tableDO.setClassname(StringUtils.uncapitalize(className));
|
||||
|
||||
|
||||
|
||||
Collections.sort(list, Comparator.comparingInt(GenColumnsDO::getColumnSort));
|
||||
|
||||
for(GenColumnsDO genColumnsDO : list){
|
||||
String attrName = columnToJava(genColumnsDO.getColumnName());
|
||||
genColumnsDO.setAttrName(attrName);
|
||||
genColumnsDO.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
}
|
||||
|
||||
String attrName = columnToJava(pkColumn.getColumnName());
|
||||
pkColumn.setAttrName(attrName);
|
||||
pkColumn.setAttrname(StringUtils.uncapitalize(attrName));
|
||||
|
||||
tableDO.setPk(pkColumn);
|
||||
|
||||
list.add(0,pkColumn);
|
||||
tableDO.setColumns(list);
|
||||
|
||||
//设置velocity资源加载器
|
||||
Properties prop = new Properties();
|
||||
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
Velocity.init(prop);
|
||||
|
||||
|
||||
map.put("tableName", tableDO.getTableName());
|
||||
map.put("comments", tableDO.getComments());
|
||||
map.put("pk", tableDO.getPk());
|
||||
map.put("className", tableDO.getClassName());
|
||||
map.put("classname", tableDO.getClassname());
|
||||
map.put("pathName", config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
|
||||
map.put("columns", tableDO.getColumns());
|
||||
map.put("package", config.getString("package"));
|
||||
map.put("author", config.getString("author"));
|
||||
map.put("email", config.getString("email"));
|
||||
map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
|
||||
VelocityContext context = new VelocityContext(map);
|
||||
|
||||
//获取模板列表
|
||||
List<String> templates = getTemplates();
|
||||
for (String template : templates) {
|
||||
//渲染模板
|
||||
StringWriter sw = new StringWriter();
|
||||
Template tpl = Velocity.getTemplate(template, "UTF-8");
|
||||
tpl.merge(context, sw);
|
||||
|
||||
try {
|
||||
String fileName = getFileName(template, tableDO.getClassname(), tableDO.getClassName(), config.getString("package"));
|
||||
|
||||
String srcPath = config.getString("srcPath");
|
||||
fileName = srcPath + File.separator + fileName;
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
file = new File(fileName + 1);
|
||||
}
|
||||
File parentCatelog = file.getParentFile();
|
||||
if (!parentCatelog.exists()) {
|
||||
parentCatelog.mkdirs();
|
||||
}
|
||||
OutputStream fos = new FileOutputStream(file);
|
||||
IOUtils.write(sw.toString(), fos, "UTF-8");
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("渲染模板失败,表名:" + tableDO.getTableName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
public class HttpContextUtils {
|
||||
public static HttpServletRequest getHttpServletRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class HttpServletUtils {
|
||||
public static boolean jsAjax(HttpServletRequest req){
|
||||
//判断是否为ajax请求,默认不是
|
||||
boolean isAjaxRequest = false;
|
||||
if(!StringUtils.isBlank(req.getHeader("x-requested-with")) && req.getHeader("x-requested-with").equals("XMLHttpRequest")){
|
||||
isAjaxRequest = true;
|
||||
}
|
||||
return isAjaxRequest;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class IPUtils {
|
||||
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
|
||||
|
||||
/**
|
||||
* 获取IP地址
|
||||
*
|
||||
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
|
||||
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
|
||||
}
|
||||
|
||||
}
|
163
novel-admin/src/main/java/com/java2nb/common/utils/IdWorker.java
Normal file
163
novel-admin/src/main/java/com/java2nb/common/utils/IdWorker.java
Normal file
@ -0,0 +1,163 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* <p>名称:IdWorker.java</p>
|
||||
* <p>描述:分布式自增长ID</p>
|
||||
* <pre>
|
||||
* Twitter的 Snowflake JAVA实现方案
|
||||
* </pre>
|
||||
* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
|
||||
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
|
||||
* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
|
||||
* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
|
||||
* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
|
||||
* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
|
||||
* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
|
||||
* <p>
|
||||
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
|
||||
*
|
||||
*/
|
||||
public class IdWorker {
|
||||
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
|
||||
private final static long twepoch = 1288834974657L;
|
||||
// 机器标识位数
|
||||
private final static long workerIdBits = 5L;
|
||||
// 数据中心标识位数
|
||||
private final static long datacenterIdBits = 5L;
|
||||
// 机器ID最大值
|
||||
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
||||
// 数据中心ID最大值
|
||||
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
||||
// 毫秒内自增位
|
||||
private final static long sequenceBits = 12L;
|
||||
// 机器ID偏左移12位
|
||||
private final static long workerIdShift = sequenceBits;
|
||||
// 数据中心ID左移17位
|
||||
private final static long datacenterIdShift = sequenceBits + workerIdBits;
|
||||
// 时间毫秒左移22位
|
||||
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
||||
|
||||
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
|
||||
/* 上次生产id时间戳 */
|
||||
private static long lastTimestamp = -1L;
|
||||
// 0,并发控制
|
||||
private long sequence = 0L;
|
||||
|
||||
private final long workerId;
|
||||
// 数据标识id部分
|
||||
private final long datacenterId;
|
||||
|
||||
public IdWorker(){
|
||||
this.datacenterId = getDatacenterId(maxDatacenterId);
|
||||
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
|
||||
}
|
||||
/**
|
||||
* @param workerId
|
||||
* 工作机器ID
|
||||
* @param datacenterId
|
||||
* 序列号
|
||||
*/
|
||||
public IdWorker(long workerId, long datacenterId) {
|
||||
if (workerId > maxWorkerId || workerId < 0) {
|
||||
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
||||
}
|
||||
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
||||
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
||||
}
|
||||
this.workerId = workerId;
|
||||
this.datacenterId = datacenterId;
|
||||
}
|
||||
/**
|
||||
* 获取下一个ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized long nextId() {
|
||||
long timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
if (lastTimestamp == timestamp) {
|
||||
// 当前毫秒内,则+1
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (sequence == 0) {
|
||||
// 当前毫秒内计数满了,则等待下一秒
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
}
|
||||
} else {
|
||||
sequence = 0L;
|
||||
}
|
||||
lastTimestamp = timestamp;
|
||||
// ID偏移组合生成最终的ID,并返回ID
|
||||
long nextId = ((timestamp - twepoch) << timestampLeftShift)
|
||||
| (datacenterId << datacenterIdShift)
|
||||
| (workerId << workerIdShift) | sequence;
|
||||
|
||||
return nextId;
|
||||
}
|
||||
|
||||
private long tilNextMillis(final long lastTimestamp) {
|
||||
long timestamp = this.timeGen();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = this.timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
private long timeGen() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 获取 maxWorkerId
|
||||
* </p>
|
||||
*/
|
||||
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
|
||||
StringBuffer mpid = new StringBuffer();
|
||||
mpid.append(datacenterId);
|
||||
String name = ManagementFactory.getRuntimeMXBean().getName();
|
||||
if (!name.isEmpty()) {
|
||||
/*
|
||||
* GET jvmPid
|
||||
*/
|
||||
mpid.append(name.split("@")[0]);
|
||||
}
|
||||
/*
|
||||
* MAC + PID 的 hashcode 获取16个低位
|
||||
*/
|
||||
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据标识id部分
|
||||
* </p>
|
||||
*/
|
||||
protected static long getDatacenterId(long maxDatacenterId) {
|
||||
long id = 0L;
|
||||
try {
|
||||
InetAddress ip = InetAddress.getLocalHost();
|
||||
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
|
||||
if (network == null) {
|
||||
id = 1L;
|
||||
} else {
|
||||
byte[] mac = network.getHardwareAddress();
|
||||
id = ((0x000000FF & (long) mac[mac.length - 1])
|
||||
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
|
||||
id = id % (maxDatacenterId + 1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(" getDatacenterId: " + e.getMessage());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImageUtils {
|
||||
/***
|
||||
* 剪裁图片
|
||||
* @param file 图片
|
||||
* @param x 起点横坐标
|
||||
* @param y 纵坐标
|
||||
* @param w 长
|
||||
* @param h 高
|
||||
* @throws IOException
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public static BufferedImage cutImage(MultipartFile file, int x, int y, int w, int h,String prefix) {
|
||||
|
||||
Iterator iterator = ImageIO.getImageReadersByFormatName(prefix);
|
||||
try {
|
||||
ImageReader reader = (ImageReader)iterator.next();
|
||||
//转换成输入流
|
||||
InputStream in = file.getInputStream();
|
||||
ImageInputStream iis = ImageIO.createImageInputStream(in);
|
||||
reader.setInput(iis, true);
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
Rectangle rect = new Rectangle(x, y, w,h);
|
||||
param.setSourceRegion(rect);
|
||||
BufferedImage bi = reader.read(0,param);
|
||||
return bi;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/***
|
||||
* 图片旋转指定角度
|
||||
* @param bufferedimage 图像
|
||||
* @param degree 角度
|
||||
* @return
|
||||
* @date 2019-09-25 15:09:21
|
||||
*/
|
||||
public static BufferedImage rotateImage(BufferedImage bufferedimage, int degree) {
|
||||
int w = bufferedimage.getWidth();
|
||||
int h = bufferedimage.getHeight();
|
||||
int type = bufferedimage.getColorModel().getTransparency();
|
||||
BufferedImage img;
|
||||
Graphics2D graphics2d;
|
||||
(graphics2d = (img = new BufferedImage(w, h, type))
|
||||
.createGraphics()).setRenderingHint(
|
||||
RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
graphics2d.setPaint(Color.WHITE);
|
||||
graphics2d.fillRect(0, 0, w, h);
|
||||
graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);
|
||||
graphics2d.drawImage(bufferedimage, 0, 0,Color.WHITE, null);
|
||||
graphics2d.dispose();
|
||||
return img;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class JSONUtils {
|
||||
/**
|
||||
* Bean对象转JSON
|
||||
*
|
||||
* @param object
|
||||
* @param dataFormatString
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJson(Object object, String dataFormatString) {
|
||||
if (object != null) {
|
||||
if (StringUtils.isEmpty(dataFormatString)) {
|
||||
return JSONObject.toJSONString(object);
|
||||
}
|
||||
return JSON.toJSONStringWithDateFormat(object, dataFormatString);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean对象转JSON
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJson(Object object) {
|
||||
if (object != null) {
|
||||
return JSON.toJSONString(object);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String转JSON字符串
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String stringToJsonByFastjson(String key, String value) {
|
||||
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>(16);
|
||||
map.put(key, value);
|
||||
return beanToJson(map, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将json字符串转换成对象
|
||||
*
|
||||
* @param json
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object jsonToBean(String json, Object clazz) {
|
||||
if (StringUtils.isEmpty(json) || clazz == null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(json, clazz.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* json字符串转map
|
||||
*
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> jsonToMap(String json) {
|
||||
if (StringUtils.isEmpty(json)) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(json, Map.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
public class MD5Utils {
|
||||
private static final String SALT = "1qazxsw2";
|
||||
|
||||
private static final String ALGORITH_NAME = "md5";
|
||||
|
||||
private static final int HASH_ITERATIONS = 2;
|
||||
|
||||
public static String encrypt(String pswd) {
|
||||
String newPassword = new SimpleHash(ALGORITH_NAME, pswd, ByteSource.Util.bytes(SALT), HASH_ITERATIONS).toHex();
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public static String encrypt(String username, String pswd) {
|
||||
String newPassword = new SimpleHash(ALGORITH_NAME, pswd, ByteSource.Util.bytes(username + SALT),
|
||||
HASH_ITERATIONS).toHex();
|
||||
return newPassword;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
|
||||
//System.out.println(MD5Utils.encrypt("admin", "1"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author xiongxy
|
||||
*/
|
||||
public class PageBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private int total;
|
||||
private List<?> rows;
|
||||
|
||||
public PageBean(List<?> list, int total) {
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<?> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<?> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*/
|
||||
public class Query extends LinkedHashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
//
|
||||
private int offset;
|
||||
// 每页条数
|
||||
private int limit;
|
||||
|
||||
public Query(Map<String, Object> params) {
|
||||
this.putAll(params);
|
||||
// 分页参数
|
||||
this.offset = Integer.parseInt(params.get("offset").toString());
|
||||
this.limit = Integer.parseInt(params.get("limit").toString());
|
||||
this.put("offset", offset);
|
||||
this.put("page", offset / limit + 1);
|
||||
this.put("limit", limit);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.put("offset", offset);
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
}
|
50
novel-admin/src/main/java/com/java2nb/common/utils/R.java
Normal file
50
novel-admin/src/main/java/com/java2nb/common/utils/R.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class R extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public R() {
|
||||
put("code", 0);
|
||||
put("msg", "操作成功");
|
||||
}
|
||||
|
||||
public static R error() {
|
||||
return error(1, "操作失败");
|
||||
}
|
||||
|
||||
public static R error(String msg) {
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
public static R error(int code, String msg) {
|
||||
R r = new R();
|
||||
r.put("code", code);
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(String msg) {
|
||||
R r = new R();
|
||||
r.put("msg", msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok(Map<String, Object> map) {
|
||||
R r = new R();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static R ok() {
|
||||
return new R();
|
||||
}
|
||||
|
||||
@Override
|
||||
public R put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
public class RandomValidateCodeUtil {
|
||||
|
||||
|
||||
public static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";//放到session中的key
|
||||
private String randString = "0123456789";//随机产生只有数字的字符串 private String
|
||||
//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
|
||||
//private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
|
||||
private int width = 95;// 图片宽
|
||||
private int height = 25;// 图片高
|
||||
private int lineSize = 40;// 干扰线数量
|
||||
private int stringNum = 4;// 随机产生字符数量
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class);
|
||||
|
||||
private Random random = new Random();
|
||||
|
||||
/**
|
||||
* 获得字体
|
||||
*/
|
||||
private Font getFont() {
|
||||
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得颜色
|
||||
*/
|
||||
private Color getRandColor(int fc, int bc) {
|
||||
if (fc > 255) {
|
||||
fc = 255;
|
||||
}
|
||||
if (bc > 255) {
|
||||
bc = 255;
|
||||
}
|
||||
int r = fc + random.nextInt(bc - fc - 16);
|
||||
int g = fc + random.nextInt(bc - fc - 14);
|
||||
int b = fc + random.nextInt(bc - fc - 18);
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机图片
|
||||
*/
|
||||
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
|
||||
HttpSession session = request.getSession();
|
||||
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
|
||||
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
|
||||
g.fillRect(0, 0, width, height);//图片大小
|
||||
g.setFont(new Font("Default", Font.ROMAN_BASELINE, 18));//字体大小
|
||||
g.setColor(getRandColor(110, 133));//字体颜色
|
||||
// 绘制干扰线
|
||||
for (int i = 0; i <= lineSize; i++) {
|
||||
drowLine(g);
|
||||
}
|
||||
// 绘制随机字符
|
||||
String randomString = "";
|
||||
for (int i = 1; i <= stringNum; i++) {
|
||||
randomString = drowString(g, randomString, i);
|
||||
}
|
||||
logger.info(randomString);
|
||||
//将生成的随机字符串保存到session中
|
||||
session.removeAttribute(RANDOMCODEKEY);
|
||||
session.setAttribute(RANDOMCODEKEY, randomString);
|
||||
g.dispose();
|
||||
try {
|
||||
// 将内存中的图片通过流动形式输出到客户端
|
||||
ImageIO.write(image, "JPEG", response.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制字符串
|
||||
*/
|
||||
private String drowString(Graphics g, String randomString, int i) {
|
||||
g.setFont(getFont());
|
||||
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
|
||||
.nextInt(121)));
|
||||
String rand = String.valueOf(getRandomString(random.nextInt(randString
|
||||
.length())));
|
||||
randomString += rand;
|
||||
g.translate(random.nextInt(3), random.nextInt(3));
|
||||
g.drawString(rand, 13 * i, 16);
|
||||
return randomString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制干扰线
|
||||
*/
|
||||
private void drowLine(Graphics g) {
|
||||
int x = random.nextInt(width);
|
||||
int y = random.nextInt(height);
|
||||
int xl = random.nextInt(13);
|
||||
int yl = random.nextInt(15);
|
||||
g.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机的字符
|
||||
*/
|
||||
public String getRandomString(int num) {
|
||||
return String.valueOf(randString.charAt(num));
|
||||
}
|
||||
}
|
@ -0,0 +1,601 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public final class RedisUtil {
|
||||
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
|
||||
|
||||
public boolean expire(String key, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key 获取过期时间
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @return 时间(秒) 返回0代表为永久有效
|
||||
*/
|
||||
|
||||
|
||||
public long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
|
||||
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param key 可以传一个值 或多个
|
||||
*/
|
||||
public void del(String... key) {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public long incr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递增因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要减少几(小于0)
|
||||
* @return
|
||||
*/
|
||||
public long decr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递减因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
|
||||
// ================================Map=================================
|
||||
|
||||
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object hget(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> hmget(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HashSet 并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @param time 时间(秒)
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除hash表中的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 可以使多个 不能为null
|
||||
*/
|
||||
|
||||
|
||||
public void hdel(String key, Object... item) {
|
||||
redisTemplate.opsForHash().delete(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断hash表中是否有该项的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hHasKey(String key, String item) {
|
||||
return redisTemplate.opsForHash().hasKey(key, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public double hincr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, by);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要减少记(小于0)
|
||||
* @return
|
||||
*/
|
||||
public double hdecr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据key获取Set中的所有值
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Set<Object> sGet(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据value从一个set中查询,是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean sHasKey(String key, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将数据放入set缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSet(String key, Object... values) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将set数据放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSetAndTime(String key, long time, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取set缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long sGetSetSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除值为value的
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long setRemove(String key, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头, 第二个元素,依次类推;index<0时,-,表尾,-倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||
return remove;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import com.java2nb.system.domain.UserToken;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.mgt.eis.SessionDAO;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import com.java2nb.system.domain.UserDO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ShiroUtils {
|
||||
@Autowired
|
||||
private static SessionDAO sessionDAO;
|
||||
|
||||
public static Subject getSubjct() {
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
public static UserDO getUser() {
|
||||
Object object = getSubjct().getPrincipal();
|
||||
return (UserDO)object;
|
||||
}
|
||||
public static Long getUserId() {
|
||||
return getUser().getUserId();
|
||||
}
|
||||
public static void logout() {
|
||||
getSubjct().logout();
|
||||
}
|
||||
|
||||
public static List<Principal> getPrinciples() {
|
||||
List<Principal> principals = null;
|
||||
Collection<Session> sessions = sessionDAO.getActiveSessions();
|
||||
return principals;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
//package com.java2nb.common.utils;
|
||||
//
|
||||
//import org.apache.commons.lang3.Validate;
|
||||
//import org.slf4j.Logger;
|
||||
//import org.slf4j.LoggerFactory;
|
||||
//import org.springframework.beans.factory.DisposableBean;
|
||||
//import org.springframework.context.ApplicationContext;
|
||||
//import org.springframework.context.ApplicationContextAware;
|
||||
//import org.springframework.context.annotation.Lazy;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//
|
||||
///**
|
||||
// * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext.
|
||||
// *
|
||||
// */
|
||||
//@Service
|
||||
//@Lazy(false)
|
||||
//public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||
//
|
||||
// private static ApplicationContext applicationContext = null;
|
||||
//
|
||||
// private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
|
||||
//
|
||||
// /**
|
||||
// * 取得存储在静态变量中的ApplicationContext.
|
||||
// */
|
||||
// public static ApplicationContext getApplicationContext() {
|
||||
// assertContextInjected();
|
||||
// return applicationContext;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
// */
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static <T> T getBean(String name) {
|
||||
// assertContextInjected();
|
||||
// return (T) applicationContext.getBean(name);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||
// */
|
||||
// public static <T> T getBean(Class<T> requiredType) {
|
||||
// assertContextInjected();
|
||||
// return applicationContext.getBean(requiredType);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 清除SpringContextHolder中的ApplicationContext为Null.
|
||||
// */
|
||||
// public static void clearHolder() {
|
||||
// if (logger.isDebugEnabled()) {
|
||||
// logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
|
||||
// }
|
||||
// applicationContext = null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 实现ApplicationContextAware接口, 注入Context到静态变量中.
|
||||
// */
|
||||
// @Override
|
||||
// public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
// SpringContextHolder.applicationContext = applicationContext;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 实现DisposableBean接口, 在Context关闭时清理静态变量.
|
||||
// */
|
||||
// @Override
|
||||
// public void destroy() throws Exception {
|
||||
// SpringContextHolder.clearHolder();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 检查ApplicationContext不为空.
|
||||
// */
|
||||
// private static void assertContextInjected() {
|
||||
// Validate.validState(applicationContext != null,
|
||||
// "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
|
||||
// }
|
||||
//}
|
@ -0,0 +1,7 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
/**
|
||||
* @author xiongxy
|
||||
*/
|
||||
public class StringUtils extends org.apache.commons.lang3.StringUtils{
|
||||
}
|
@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
|
||||
*/
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 时间计算工具类
|
||||
|
||||
*/
|
||||
public class TimeUtils {
|
||||
|
||||
public static String toTimeString(long time) {
|
||||
TimeUtils t = new TimeUtils(time);
|
||||
int day = t.get(TimeUtils.DAY);
|
||||
int hour = t.get(TimeUtils.HOUR);
|
||||
int minute = t.get(TimeUtils.MINUTE);
|
||||
int second = t.get(TimeUtils.SECOND);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (day > 0){
|
||||
sb.append(day).append("天");
|
||||
}
|
||||
if (hour > 0){
|
||||
sb.append(hour).append("时");
|
||||
}
|
||||
if (minute > 0){
|
||||
sb.append(minute).append("分");
|
||||
}
|
||||
if (second > 0){
|
||||
sb.append(second).append("秒");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“秒”
|
||||
*/
|
||||
public final static int SECOND = 0;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“分”
|
||||
*/
|
||||
public final static int MINUTE = 1;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“时”
|
||||
*/
|
||||
public final static int HOUR = 2;
|
||||
|
||||
/**
|
||||
* 时间字段常量,表示“天”
|
||||
*/
|
||||
public final static int DAY = 3;
|
||||
|
||||
/**
|
||||
* 各常量允许的最大值
|
||||
*/
|
||||
private final int[] maxFields = { 59, 59, 23, Integer.MAX_VALUE - 1 };
|
||||
|
||||
/**
|
||||
* 各常量允许的最小值
|
||||
*/
|
||||
private final int[] minFields = { 0, 0, 0, Integer.MIN_VALUE };
|
||||
|
||||
/**
|
||||
* 默认的字符串格式时间分隔符
|
||||
*/
|
||||
private String timeSeparator = ":";
|
||||
|
||||
/**
|
||||
* 时间数据容器
|
||||
*/
|
||||
private int[] fields = new int[4];
|
||||
|
||||
/**
|
||||
* 无参构造,将各字段置为 0
|
||||
*/
|
||||
public TimeUtils() {
|
||||
this(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时、分构造一个时间
|
||||
* @param hour 小时
|
||||
* @param minute 分钟
|
||||
*/
|
||||
public TimeUtils(int hour, int minute) {
|
||||
this(0, hour, minute, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时、分、秒构造一个时间
|
||||
* @param hour 小时
|
||||
* @param minute 分钟
|
||||
* @param second 秒
|
||||
*/
|
||||
public TimeUtils(int hour, int minute, int second) {
|
||||
this(0, hour, minute, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用一个字符串构造时间<br/>
|
||||
* Time time = new Time("14:22:23");
|
||||
* @param time 字符串格式的时间,默认采用“:”作为分隔符
|
||||
*/
|
||||
public TimeUtils(String time) {
|
||||
this(time, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用时间毫秒构建时间
|
||||
* @param time
|
||||
*/
|
||||
public TimeUtils(long time){
|
||||
this(new Date(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用日期对象构造时间
|
||||
* @param date
|
||||
*/
|
||||
public TimeUtils(Date date){
|
||||
this(DateFormatUtils.formatUTC(date, "HH:mm:ss"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用天、时、分、秒构造时间,进行全字符的构造
|
||||
* @param day 天
|
||||
* @param hour 时
|
||||
* @param minute 分
|
||||
* @param second 秒
|
||||
*/
|
||||
public TimeUtils(int day, int hour, int minute, int second) {
|
||||
initialize(day, hour, minute, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用一个字符串构造时间,指定分隔符<br/>
|
||||
* Time time = new Time("14-22-23", "-");
|
||||
* @param time 字符串格式的时间
|
||||
*/
|
||||
public TimeUtils(String time, String timeSeparator) {
|
||||
if(timeSeparator != null) {
|
||||
setTimeSeparator(timeSeparator);
|
||||
}
|
||||
parseTime(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间字段的值
|
||||
* @param field 时间字段常量
|
||||
* @param value 时间字段的值
|
||||
*/
|
||||
public void set(int field, int value) {
|
||||
if(value < minFields[field]) {
|
||||
throw new IllegalArgumentException(value + ", time value must be positive.");
|
||||
}
|
||||
fields[field] = value % (maxFields[field] + 1);
|
||||
// 进行进位计算
|
||||
int carry = value / (maxFields[field] + 1);
|
||||
if(carry > 0) {
|
||||
int upFieldValue = get(field + 1);
|
||||
set(field + 1, upFieldValue + carry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得时间字段的值
|
||||
* @param field 时间字段常量
|
||||
* @return 该时间字段的值
|
||||
*/
|
||||
public int get(int field) {
|
||||
if(field < 0 || field > fields.length - 1) {
|
||||
throw new IllegalArgumentException(field + ", field value is error.");
|
||||
}
|
||||
return fields[field];
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间进行“加”运算,即加上一个时间
|
||||
* @param time 需要加的时间
|
||||
* @return 运算后的时间
|
||||
*/
|
||||
public TimeUtils addTime(TimeUtils time) {
|
||||
TimeUtils result = new TimeUtils();
|
||||
int up = 0; // 进位标志
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
int sum = fields[i] + time.fields[i] + up;
|
||||
up = sum / (maxFields[i] + 1);
|
||||
result.fields[i] = sum % (maxFields[i] + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间进行“减”运算,即减去一个时间
|
||||
* @param time 需要减的时间
|
||||
* @return 运算后的时间
|
||||
*/
|
||||
public TimeUtils subtractTime(TimeUtils time) {
|
||||
TimeUtils result = new TimeUtils();
|
||||
int down = 0; // 退位标志
|
||||
for (int i = 0, k = fields.length - 1; i < k; i++) {
|
||||
int difference = fields[i] + down;
|
||||
if (difference >= time.fields[i]) {
|
||||
difference -= time.fields[i];
|
||||
down = 0;
|
||||
} else {
|
||||
difference += maxFields[i] + 1 - time.fields[i];
|
||||
down = -1;
|
||||
}
|
||||
result.fields[i] = difference;
|
||||
}
|
||||
result.fields[DAY] = fields[DAY] - time.fields[DAY] + down;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得时间字段的分隔符
|
||||
* @return
|
||||
*/
|
||||
public String getTimeSeparator() {
|
||||
return timeSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间字段的分隔符(用于字符串格式的时间)
|
||||
* @param timeSeparator 分隔符字符串
|
||||
*/
|
||||
public void setTimeSeparator(String timeSeparator) {
|
||||
this.timeSeparator = timeSeparator;
|
||||
}
|
||||
|
||||
private void initialize(int day, int hour, int minute, int second) {
|
||||
set(DAY, day);
|
||||
set(HOUR, hour);
|
||||
set(MINUTE, minute);
|
||||
set(SECOND, second);
|
||||
}
|
||||
|
||||
private void parseTime(String time) {
|
||||
if(time == null) {
|
||||
initialize(0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
String t = time;
|
||||
int field = DAY;
|
||||
set(field--, 0);
|
||||
int p = -1;
|
||||
while((p = t.indexOf(timeSeparator)) > -1) {
|
||||
parseTimeField(time, t.substring(0, p), field--);
|
||||
t = t.substring(p + timeSeparator.length());
|
||||
}
|
||||
parseTimeField(time, t, field--);
|
||||
}
|
||||
|
||||
private void parseTimeField(String time, String t, int field) {
|
||||
if(field < SECOND || t.length() < 1) {
|
||||
parseTimeException(time);
|
||||
}
|
||||
char[] chs = t.toCharArray();
|
||||
int n = 0;
|
||||
for(int i = 0; i < chs.length; i++) {
|
||||
if(chs[i] <= ' ') {
|
||||
continue;
|
||||
}
|
||||
if(chs[i] >= '0' && chs[i] <= '9') {
|
||||
n = n * 10 + chs[i] - '0';
|
||||
continue;
|
||||
}
|
||||
parseTimeException(time);
|
||||
}
|
||||
set(field, n);
|
||||
}
|
||||
|
||||
private void parseTimeException(String time) {
|
||||
throw new IllegalArgumentException(time + ", time format error, HH"
|
||||
+ this.timeSeparator + "mm" + this.timeSeparator + "ss");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(16);
|
||||
sb.append(fields[DAY]).append(',').append(' ');
|
||||
buildString(sb, HOUR).append(timeSeparator);
|
||||
buildString(sb, MINUTE).append(timeSeparator);
|
||||
buildString(sb, SECOND);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private StringBuilder buildString(StringBuilder sb, int field) {
|
||||
if(fields[field] < 10) {
|
||||
sb.append('0');
|
||||
}
|
||||
return sb.append(fields[field]);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 31;
|
||||
int result = 1;
|
||||
result = PRIME * result + Arrays.hashCode(fields);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final TimeUtils other = (TimeUtils) obj;
|
||||
if (!Arrays.equals(fields, other.fields)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.java2nb.common.utils;
|
||||
|
||||
public class UploadUtils {
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.java2nb.common.xss;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
private HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 假如有有html 代码是自己传来的 需要设定对应的name 不过滤
|
||||
*/
|
||||
private static final List<String> noFilterNames = Arrays.asList("attach","push_ip","content");
|
||||
|
||||
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String value = request.getParameter(name);
|
||||
if (!StringUtils.isEmpty(value) && !noFilterNames.contains(name)) {
|
||||
value = htmlEncodeByRegExp(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameterValues = super.getParameterValues(name);
|
||||
if (parameterValues == null || noFilterNames.contains(name)) {
|
||||
return parameterValues;
|
||||
}
|
||||
for (int i = 0; i < parameterValues.length; i++) {
|
||||
String value = parameterValues[i];
|
||||
if (!StringUtils.isEmpty(value)){
|
||||
parameterValues[i] = htmlEncodeByRegExp(value);
|
||||
}
|
||||
}
|
||||
return parameterValues;
|
||||
}
|
||||
|
||||
|
||||
private String htmlEncodeByRegExp(String str) {
|
||||
String temp = "" ;
|
||||
temp = str
|
||||
//.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">");
|
||||
//.replaceAll("\\s", " ")
|
||||
//.replaceAll("\'", "'")
|
||||
//.replaceAll("\"", """);
|
||||
return temp;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user