feat: 后台友情链接管理

This commit is contained in:
xiongxiaoyang 2023-04-14 16:32:05 +08:00
parent 3b0edd8e1f
commit c76df15a7f
20 changed files with 1605 additions and 880 deletions

View File

@ -36,3 +36,31 @@ VALUES (1, 300);
INSERT INTO sys_role_menu (role_id, menu_id) INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 301); VALUES (1, 301);
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (310, 300, '友情链接', 'novel/friendLink', 'novel:friendLink:friendLink', '1', 'fa', '16');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (311, 310, '查看', null, 'novel:friendLink:detail', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (312, 310, '新增', null, 'novel:friendLink:add', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (313, 310, '修改', null, 'novel:friendLink:edit', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (314, 310, '删除', null, 'novel:friendLink:remove', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (315, 310, '批量删除', null, 'novel:friendLink:batchRemove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 310);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 311);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 312);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 313);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 314);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 315);

View File

@ -2866,4 +2866,33 @@ VALUES (301, 300, '网站信息', 'novel/websiteInfo', 'novel:websiteInfo:websit
INSERT INTO sys_role_menu (role_id, menu_id) INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 300); VALUES (1, 300);
INSERT INTO sys_role_menu (role_id, menu_id) INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 301); VALUES (1, 301);
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (310, 300, '友情链接', 'novel/friendLink', 'novel:friendLink:friendLink', '1', 'fa', '16');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (311, 310, '查看', null, 'novel:friendLink:detail', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (312, 310, '新增', null, 'novel:friendLink:add', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (313, 310, '修改', null, 'novel:friendLink:edit', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (314, 310, '删除', null, 'novel:friendLink:remove', '2', null, '6');
INSERT INTO `sys_menu` (menu_id, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (315, 310, '批量删除', null, 'novel:friendLink:batchRemove', '2', null, '6');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 310);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 311);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 312);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 313);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 314);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 315);

View File

@ -0,0 +1,73 @@
package com.java2nb.common.config;
/**
* @author 11797
*/
public interface CacheKey {
/**
* 首页小说设置
*/
String INDEX_BOOK_SETTINGS_KEY = "indexBookSettingsKey";
/**
* 首页新闻
*/
String INDEX_NEWS_KEY = "indexNewsKey";
/**
* 首页点击榜单
*/
String INDEX_CLICK_BANK_BOOK_KEY = "indexClickBankBookKey";
/**
* 首页友情链接
*/
String INDEX_LINK_KEY = "indexLinkKey";
/**
* 首页新书榜单
*/
String INDEX_NEW_BOOK_KEY = "indexNewBookKey";
/**
* 首页更新榜单
*/
String INDEX_UPDATE_BOOK_KEY = "indexUpdateBookKey";
/**
* 模板目录保存key
*/
String TEMPLATE_DIR_KEY = "templateDirKey";
;
/**
* 正在运行的爬虫线程存储KEY前缀
*/
String RUNNING_CRAWL_THREAD_KEY_PREFIX = "runningCrawlTreadDataKeyPrefix";
/**
* 上一次搜索引擎更新的时间
*/
String ES_LAST_UPDATE_TIME = "esLastUpdateTime";
/**
* 搜索引擎转换锁
*/
String ES_TRANS_LOCK = "esTransLock";
/**
* 上一次搜索引擎是否更新过小说点击量
*/
String ES_IS_UPDATE_VISIT = "esIsUpdateVisit";
/**
* 累积的小说点击量
*/
String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount";
/**
* 测试爬虫规则缓存
*/
String BOOK_TEST_PARSE = "testParse";
}

View File

@ -1,82 +0,0 @@
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;
}
}

View File

@ -1,601 +0,0 @@
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;
}
}
}

View File

@ -0,0 +1,135 @@
package com.java2nb.novel.controller;
import com.java2nb.common.config.CacheKey;
import com.java2nb.common.utils.PageBean;
import com.java2nb.common.utils.Query;
import com.java2nb.common.utils.R;
import com.java2nb.novel.domain.FriendLinkDO;
import com.java2nb.novel.service.FriendLinkService;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-14 15:12:25
*/
@Controller
@RequestMapping("/novel/friendLink")
public class FriendLinkController {
@Autowired
private FriendLinkService friendLinkService;
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@GetMapping()
@RequiresPermissions("novel:friendLink:friendLink")
String FriendLink() {
return "novel/friendLink/friendLink";
}
@ApiOperation(value = "获取列表", notes = "获取列表")
@ResponseBody
@GetMapping("/list")
@RequiresPermissions("novel:friendLink:friendLink")
public R list(@RequestParam Map<String, Object> params) {
//查询列表数据
Query query = new Query(params);
List<FriendLinkDO> friendLinkList = friendLinkService.list(query);
int total = friendLinkService.count(query);
PageBean pageBean = new PageBean(friendLinkList, total);
return R.ok().put("data", pageBean);
}
@ApiOperation(value = "新增页面", notes = "新增页面")
@GetMapping("/add")
@RequiresPermissions("novel:friendLink:add")
String add() {
return "novel/friendLink/add";
}
@ApiOperation(value = "修改页面", notes = "修改页面")
@GetMapping("/edit/{id}")
@RequiresPermissions("novel:friendLink:edit")
String edit(@PathVariable("id") Integer id, Model model) {
FriendLinkDO friendLink = friendLinkService.get(id);
model.addAttribute("friendLink", friendLink);
return "novel/friendLink/edit";
}
@ApiOperation(value = "查看页面", notes = "查看页面")
@GetMapping("/detail/{id}")
@RequiresPermissions("novel:friendLink:detail")
String detail(@PathVariable("id") Integer id, Model model) {
FriendLinkDO friendLink = friendLinkService.get(id);
model.addAttribute("friendLink", friendLink);
return "novel/friendLink/detail";
}
/**
* 保存
*/
@ApiOperation(value = "新增", notes = "新增")
@ResponseBody
@PostMapping("/save")
@RequiresPermissions("novel:friendLink:add")
public R save(FriendLinkDO friendLink) {
if (friendLinkService.save(friendLink) > 0) {
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
return R.ok();
}
return R.error();
}
/**
* 修改
*/
@ApiOperation(value = "修改", notes = "修改")
@ResponseBody
@RequestMapping("/update")
@RequiresPermissions("novel:friendLink:edit")
public R update(FriendLinkDO friendLink) {
friendLinkService.update(friendLink);
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
return R.ok();
}
/**
* 删除
*/
@ApiOperation(value = "删除", notes = "删除")
@PostMapping("/remove")
@ResponseBody
@RequiresPermissions("novel:friendLink:remove")
public R remove(Integer id) {
if (friendLinkService.remove(id) > 0) {
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
return R.ok();
}
return R.error();
}
/**
* 删除
*/
@ApiOperation(value = "批量删除", notes = "批量删除")
@PostMapping("/batchRemove")
@ResponseBody
@RequiresPermissions("novel:friendLink:batchRemove")
public R remove(@RequestParam("ids[]") Integer[] ids) {
friendLinkService.batchRemove(ids);
redisTemplate.delete(CacheKey.INDEX_LINK_KEY);
return R.ok();
}
}

View File

@ -0,0 +1,32 @@
package com.java2nb.novel.dao;
import com.java2nb.novel.domain.FriendLinkDO;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
/**
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-14 15:12:25
*/
@Mapper
public interface FriendLinkDao {
FriendLinkDO get(Integer id);
List<FriendLinkDO> list(Map<String,Object> map);
int count(Map<String,Object> map);
int save(FriendLinkDO friendLink);
int update(FriendLinkDO friendLink);
int remove(Integer id);
int batchRemove(Integer[] ids);
}

View File

@ -0,0 +1,163 @@
package com.java2nb.novel.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 2023-04-14 15:12:25
*/
public class FriendLinkDO implements Serializable {
private static final long serialVersionUID = 1L;
//主键
private Integer id;
//链接名
private String linkName;
//链接url
private String linkUrl;
//排序号
private Integer sort;
//是否开启0不开启1开启
private Integer isOpen;
//创建人id
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long createUserId;
//创建时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
//更新者用户id
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long updateUserId;
//更新时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 设置主键
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取主键
*/
public Integer getId() {
return id;
}
/**
* 设置链接名
*/
public void setLinkName(String linkName) {
this.linkName = linkName;
}
/**
* 获取链接名
*/
public String getLinkName() {
return linkName;
}
/**
* 设置链接url
*/
public void setLinkUrl(String linkUrl) {
this.linkUrl = linkUrl;
}
/**
* 获取链接url
*/
public String getLinkUrl() {
return linkUrl;
}
/**
* 设置排序号
*/
public void setSort(Integer sort) {
this.sort = sort;
}
/**
* 获取排序号
*/
public Integer getSort() {
return sort;
}
/**
* 设置是否开启0不开启1开启
*/
public void setIsOpen(Integer isOpen) {
this.isOpen = isOpen;
}
/**
* 获取是否开启0不开启1开启
*/
public Integer getIsOpen() {
return isOpen;
}
/**
* 设置创建人id
*/
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
/**
* 获取创建人id
*/
public Long getCreateUserId() {
return createUserId;
}
/**
* 设置创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取创建时间
*/
public Date getCreateTime() {
return createTime;
}
/**
* 设置更新者用户id
*/
public void setUpdateUserId(Long updateUserId) {
this.updateUserId = updateUserId;
}
/**
* 获取更新者用户id
*/
public Long getUpdateUserId() {
return updateUserId;
}
/**
* 设置更新时间
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
* 获取更新时间
*/
public Date getUpdateTime() {
return updateTime;
}
}

View File

@ -0,0 +1,30 @@
package com.java2nb.novel.service;
import com.java2nb.novel.domain.FriendLinkDO;
import java.util.List;
import java.util.Map;
/**
*
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-14 15:12:25
*/
public interface FriendLinkService {
FriendLinkDO get(Integer id);
List<FriendLinkDO> list(Map<String, Object> map);
int count(Map<String, Object> map);
int save(FriendLinkDO friendLink);
int update(FriendLinkDO friendLink);
int remove(Integer id);
int batchRemove(Integer[] ids);
}

View File

@ -0,0 +1,55 @@
package com.java2nb.novel.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.novel.dao.FriendLinkDao;
import com.java2nb.novel.domain.FriendLinkDO;
import com.java2nb.novel.service.FriendLinkService;
@Service
public class FriendLinkServiceImpl implements FriendLinkService {
@Autowired
private FriendLinkDao friendLinkDao;
@Override
public FriendLinkDO get(Integer id){
return friendLinkDao.get(id);
}
@Override
public List<FriendLinkDO> list(Map<String, Object> map){
return friendLinkDao.list(map);
}
@Override
public int count(Map<String, Object> map){
return friendLinkDao.count(map);
}
@Override
public int save(FriendLinkDO friendLink){
return friendLinkDao.save(friendLink);
}
@Override
public int update(FriendLinkDO friendLink){
return friendLinkDao.update(friendLink);
}
@Override
public int remove(Integer id){
return friendLinkDao.remove(id);
}
@Override
public int batchRemove(Integer[] ids){
return friendLinkDao.batchRemove(ids);
}
}

View File

@ -5,15 +5,16 @@ import com.java2nb.common.config.Constant;
import com.java2nb.common.controller.BaseController; import com.java2nb.common.controller.BaseController;
import com.java2nb.common.domain.Tree; import com.java2nb.common.domain.Tree;
import com.java2nb.common.service.DictService; import com.java2nb.common.service.DictService;
import com.java2nb.common.utils.*; import com.java2nb.common.utils.MD5Utils;
import com.java2nb.common.utils.PageBean;
import com.java2nb.common.utils.Query;
import com.java2nb.common.utils.R;
import com.java2nb.system.domain.DeptDO; import com.java2nb.system.domain.DeptDO;
import com.java2nb.system.domain.RoleDO; import com.java2nb.system.domain.RoleDO;
import com.java2nb.system.domain.UserDO; import com.java2nb.system.domain.UserDO;
import com.java2nb.system.service.RoleService; import com.java2nb.system.service.RoleService;
import com.java2nb.system.service.SysUserService; import com.java2nb.system.service.SysUserService;
import com.java2nb.system.vo.UserVO; import com.java2nb.system.vo.UserVO;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -21,6 +22,7 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,217 +30,219 @@ import java.util.Map;
@RequestMapping("/sys/user") @RequestMapping("/sys/user")
@Controller @Controller
public class SysUserController extends BaseController { public class SysUserController extends BaseController {
private String prefix="system/user" ;
@Autowired
SysUserService userService;
@Autowired
RoleService roleService;
@Autowired
DictService dictService;
@Autowired
RedisUtil redisUtil;
@RequiresPermissions("sys:user:user") private String prefix = "system/user";
@GetMapping("") @Autowired
String user(Model model) { SysUserService userService;
return prefix + "/user"; @Autowired
} RoleService roleService;
@Autowired
DictService dictService;
@GetMapping("/list") @RequiresPermissions("sys:user:user")
@ResponseBody @GetMapping("")
PageBean list(@RequestParam Map<String, Object> params) { String user(Model model) {
// 查询列表数据 return prefix + "/user";
Query query = new Query(params); }
List<UserDO> sysUserList = userService.list(query);
int total = userService.count(query);
PageBean pageUtil = new PageBean(sysUserList, total);
return pageUtil;
}
@RequiresPermissions("sys:user:add") @GetMapping("/list")
@Log("添加用户") @ResponseBody
@GetMapping("/add") PageBean list(@RequestParam Map<String, Object> params) {
String add(Model model) { // 查询列表数据
List<RoleDO> roles = roleService.list(); Query query = new Query(params);
model.addAttribute("roles", roles); List<UserDO> sysUserList = userService.list(query);
return prefix + "/add"; int total = userService.count(query);
} PageBean pageUtil = new PageBean(sysUserList, total);
return pageUtil;
}
@RequiresPermissions("sys:user:edit") @RequiresPermissions("sys:user:add")
@Log("编辑用户") @Log("添加用户")
@GetMapping("/edit/{id}") @GetMapping("/add")
String edit(Model model, @PathVariable("id") Long id) { String add(Model model) {
UserDO userDO = userService.get(id); List<RoleDO> roles = roleService.list();
model.addAttribute("user", userDO); model.addAttribute("roles", roles);
List<RoleDO> roles = roleService.list(id); return prefix + "/add";
model.addAttribute("roles", roles); }
return prefix+"/edit";
}
public static void main(String[] args) { @RequiresPermissions("sys:user:edit")
System.out.println(MD5Utils.encrypt("admin", "admin")); @Log("编辑用户")
} @GetMapping("/edit/{id}")
String edit(Model model, @PathVariable("id") Long id) {
UserDO userDO = userService.get(id);
model.addAttribute("user", userDO);
List<RoleDO> roles = roleService.list(id);
model.addAttribute("roles", roles);
return prefix + "/edit";
}
@RequiresPermissions("sys:user:add") public static void main(String[] args) {
@Log("保存用户") System.out.println(MD5Utils.encrypt("admin", "admin"));
@PostMapping("/save") }
@ResponseBody
R save(UserDO user) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
}
user.setPassword(MD5Utils.encrypt(user.getUsername(), user.getPassword()));
if (userService.save(user) > 0) {
return R.ok();
}
return R.error();
}
@RequiresPermissions("sys:user:edit") @RequiresPermissions("sys:user:add")
@Log("更新用户") @Log("保存用户")
@PostMapping("/update") @PostMapping("/save")
@ResponseBody @ResponseBody
R update(UserDO user) { R save(UserDO user) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) { if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序"); return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
if (userService.update(user) > 0) { user.setPassword(MD5Utils.encrypt(user.getUsername(), user.getPassword()));
return R.ok(); if (userService.save(user) > 0) {
} return R.ok();
return R.error(); }
} return R.error();
}
@RequiresPermissions("sys:user:edit")
@Log("更新用户")
@PostMapping("/update")
@ResponseBody
R update(UserDO user) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
}
if (userService.update(user) > 0) {
return R.ok();
}
return R.error();
}
@RequiresPermissions("sys:user:edit") @RequiresPermissions("sys:user:edit")
@Log("更新用户") @Log("更新用户")
@PostMapping("/updatePeronal") @PostMapping("/updatePeronal")
@ResponseBody @ResponseBody
R updatePeronal(UserDO user) { R updatePeronal(UserDO user) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) { if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序"); return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
if (userService.updatePersonal(user) > 0) { if (userService.updatePersonal(user) > 0) {
return R.ok(); return R.ok();
} }
return R.error(); return R.error();
} }
@RequiresPermissions("sys:user:remove") @RequiresPermissions("sys:user:remove")
@Log("删除用户") @Log("删除用户")
@PostMapping("/remove") @PostMapping("/remove")
@ResponseBody @ResponseBody
R remove(Long id) { R remove(Long id) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) { if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序"); return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
if (userService.remove(id) > 0) { if (userService.remove(id) > 0) {
return R.ok(); return R.ok();
} }
return R.error(); return R.error();
} }
@RequiresPermissions("sys:user:batchRemove") @RequiresPermissions("sys:user:batchRemove")
@Log("批量删除用户") @Log("批量删除用户")
@PostMapping("/batchRemove") @PostMapping("/batchRemove")
@ResponseBody @ResponseBody
R batchRemove(@RequestParam("ids[]") Long[] userIds) { R batchRemove(@RequestParam("ids[]") Long[] userIds) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) { if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序"); return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
int r = userService.batchremove(userIds); int r = userService.batchremove(userIds);
if (r > 0) { if (r > 0) {
return R.ok(); return R.ok();
} }
return R.error(); return R.error();
} }
@PostMapping("/exit") @PostMapping("/exit")
@ResponseBody @ResponseBody
boolean exit(@RequestParam Map<String, Object> params) { boolean exit(@RequestParam Map<String, Object> params) {
// 存在不通过false // 存在不通过false
return !userService.exit(params); return !userService.exit(params);
} }
@RequiresPermissions("sys:user:resetPwd") @RequiresPermissions("sys:user:resetPwd")
@Log("请求更改用户密码") @Log("请求更改用户密码")
@GetMapping("/resetPwd/{id}") @GetMapping("/resetPwd/{id}")
String resetPwd(@PathVariable("id") Long userId, Model model) { String resetPwd(@PathVariable("id") Long userId, Model model) {
UserDO userDO = new UserDO(); UserDO userDO = new UserDO();
userDO.setUserId(userId); userDO.setUserId(userId);
model.addAttribute("user", userDO); model.addAttribute("user", userDO);
return prefix + "/reset_pwd"; return prefix + "/reset_pwd";
} }
@Log("提交更改用户密码") @Log("提交更改用户密码")
@PostMapping("/resetPwd") @PostMapping("/resetPwd")
@ResponseBody @ResponseBody
R resetPwd(UserVO userVO) { R resetPwd(UserVO userVO) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) { if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序"); return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
try{ try {
userService.resetPwd(userVO,getUser()); userService.resetPwd(userVO, getUser());
return R.ok(); return R.ok();
}catch (Exception e){ } catch (Exception e) {
return R.error(1,e.getMessage()); return R.error(1, e.getMessage());
} }
} }
@RequiresPermissions("sys:user:resetPwd")
@Log("admin提交更改用户密码")
@PostMapping("/adminResetPwd")
@ResponseBody
R adminResetPwd(UserVO userVO) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
}
try{
userService.adminResetPwd(userVO);
return R.ok();
}catch (Exception e){
return R.error(1,e.getMessage());
}
} @RequiresPermissions("sys:user:resetPwd")
@GetMapping("/tree") @Log("admin提交更改用户密码")
@ResponseBody @PostMapping("/adminResetPwd")
public Tree<DeptDO> tree() { @ResponseBody
Tree<DeptDO> tree = new Tree<DeptDO>(); R adminResetPwd(UserVO userVO) {
tree = userService.getTree(); if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return tree; return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} }
try {
userService.adminResetPwd(userVO);
return R.ok();
} catch (Exception e) {
return R.error(1, e.getMessage());
}
@GetMapping("/treeView") }
String treeView() {
return prefix + "/userTree";
}
@GetMapping("/personal") @GetMapping("/tree")
String personal(Model model) { @ResponseBody
UserDO userDO = userService.get(getUserId()); public Tree<DeptDO> tree() {
model.addAttribute("user",userDO); Tree<DeptDO> tree = new Tree<DeptDO>();
model.addAttribute("hobbyList",dictService.getHobbyList(userDO)); tree = userService.getTree();
model.addAttribute("sexList",dictService.getSexList()); return tree;
return prefix + "/personal"; }
}
@ResponseBody @GetMapping("/treeView")
@PostMapping("/uploadImg") String treeView() {
R uploadImg(@RequestParam("avatar_file") MultipartFile file, String avatar_data, HttpServletRequest request) { return prefix + "/userTree";
if ("test".equals(getUsername())) { }
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
} @GetMapping("/personal")
Map<String, Object> result = new HashMap<>(); String personal(Model model) {
try { UserDO userDO = userService.get(getUserId());
result = userService.updatePersonalImg(file, avatar_data, getUserId()); model.addAttribute("user", userDO);
} catch (Exception e) { model.addAttribute("hobbyList", dictService.getHobbyList(userDO));
return R.error("更新图像失败!"); model.addAttribute("sexList", dictService.getSexList());
} return prefix + "/personal";
if(result!=null && result.size()>0){ }
return R.ok(result);
}else { @ResponseBody
return R.error("更新图像失败!"); @PostMapping("/uploadImg")
} R uploadImg(@RequestParam("avatar_file") MultipartFile file, String avatar_data, HttpServletRequest request) {
} if ("test".equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
}
Map<String, Object> result = new HashMap<>();
try {
result = userService.updatePersonalImg(file, avatar_data, getUserId());
} catch (Exception e) {
return R.error("更新图像失败!");
}
if (result != null && result.size() > 0) {
return R.ok(result);
} else {
return R.error("更新图像失败!");
}
}
} }

View File

@ -0,0 +1,131 @@
<?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.novel.dao.FriendLinkDao">
<select id="get" resultType="com.java2nb.novel.domain.FriendLinkDO">
select `id`,`link_name`,`link_url`,`sort`,`is_open`,`create_user_id`,`create_time`,`update_user_id`,`update_time` from friend_link where id = #{value}
</select>
<select id="list" resultType="com.java2nb.novel.domain.FriendLinkDO">
select `id`,`link_name`,`link_url`,`sort`,`is_open`,`create_user_id`,`create_time`,`update_user_id`,`update_time` from friend_link
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="linkName != null and linkName != ''"> and link_name = #{linkName} </if>
<if test="linkUrl != null and linkUrl != ''"> and link_url = #{linkUrl} </if>
<if test="sort != null and sort != ''"> and sort = #{sort} </if>
<if test="isOpen != null and isOpen != ''"> and is_open = #{isOpen} </if>
<if test="createUserId != null and createUserId != ''"> and create_user_id = #{createUserId} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
<if test="updateUserId != null and updateUserId != ''"> and update_user_id = #{updateUserId} </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 friend_link
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="linkName != null and linkName != ''"> and link_name = #{linkName} </if>
<if test="linkUrl != null and linkUrl != ''"> and link_url = #{linkUrl} </if>
<if test="sort != null and sort != ''"> and sort = #{sort} </if>
<if test="isOpen != null and isOpen != ''"> and is_open = #{isOpen} </if>
<if test="createUserId != null and createUserId != ''"> and create_user_id = #{createUserId} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
<if test="updateUserId != null and updateUserId != ''"> and update_user_id = #{updateUserId} </if>
<if test="updateTime != null and updateTime != ''"> and update_time = #{updateTime} </if>
</where>
</select>
<insert id="save" parameterType="com.java2nb.novel.domain.FriendLinkDO">
insert into friend_link
(
`id`,
`link_name`,
`link_url`,
`sort`,
`is_open`,
`create_user_id`,
`create_time`,
`update_user_id`,
`update_time`
)
values
(
#{id},
#{linkName},
#{linkUrl},
#{sort},
#{isOpen},
#{createUserId},
#{createTime},
#{updateUserId},
#{updateTime}
)
</insert>
<insert id="saveSelective" parameterType="com.java2nb.novel.domain.FriendLinkDO">
insert into friend_link
(
<if test="id != null"> `id`, </if>
<if test="linkName != null"> `link_name`, </if>
<if test="linkUrl != null"> `link_url`, </if>
<if test="sort != null"> `sort`, </if>
<if test="isOpen != null"> `is_open`, </if>
<if test="createUserId != null"> `create_user_id`, </if>
<if test="createTime != null"> `create_time`, </if>
<if test="updateUserId != null"> `update_user_id`, </if>
<if test="updateTime != null"> `update_time` </if>
)
values
(
<if test="id != null"> #{id}, </if>
<if test="linkName != null"> #{linkName}, </if>
<if test="linkUrl != null"> #{linkUrl}, </if>
<if test="sort != null"> #{sort}, </if>
<if test="isOpen != null"> #{isOpen}, </if>
<if test="createUserId != null"> #{createUserId}, </if>
<if test="createTime != null"> #{createTime}, </if>
<if test="updateUserId != null"> #{updateUserId}, </if>
<if test="updateTime != null"> #{updateTime} </if>
)
</insert>
<update id="update" parameterType="com.java2nb.novel.domain.FriendLinkDO">
update friend_link
<set>
<if test="linkName != null">`link_name` = #{linkName}, </if>
<if test="linkUrl != null">`link_url` = #{linkUrl}, </if>
<if test="sort != null">`sort` = #{sort}, </if>
<if test="isOpen != null">`is_open` = #{isOpen}, </if>
<if test="createUserId != null">`create_user_id` = #{createUserId}, </if>
<if test="createTime != null">`create_time` = #{createTime}, </if>
<if test="updateUserId != null">`update_user_id` = #{updateUserId}, </if>
<if test="updateTime != null">`update_time` = #{updateTime}</if>
</set>
where id = #{id}
</update>
<delete id="remove">
delete from friend_link where id = #{value}
</delete>
<delete id="batchRemove">
delete from friend_link where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -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: "/novel/friendLink/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: {
}
})
}

View File

@ -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: "/novel/friendLink/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: {
}
})
}

View File

@ -0,0 +1,205 @@
var prefix = "/novel/friendLink"
$(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排序列orderdesc或者,以及所有列的键值对
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: 'linkName',
title: '链接名'
},
{
field: 'linkUrl',
title: '链接url'
},
{
field: 'sort',
title: '排序号'
},
{
field: 'isOpen',
title: '是否开启',
formatter: function (value, row, index) {
return formatDict("yes_no", value);
}
},
{
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 () {
});
}

View File

@ -0,0 +1,18 @@
-- 菜单SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES ('1', '', 'novel/friendLink', 'novel:friendLink:friendLink', '1', 'fa', '6');
-- 按钮父菜单ID
set @parentId = @@identity;
-- 菜单对应按钮SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '查看', null, 'novel:friendLink:detail', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '新增', null, 'novel:friendLink:add', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '修改', null, 'novel:friendLink:edit', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '删除', null, 'novel:friendLink:remove', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '批量删除', null, 'novel:friendLink:batchRemove', '2', null, '6';

View File

@ -0,0 +1,67 @@
<!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="linkName" name="linkName"
class="form-control"
type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">链接url</label>
<div class="col-sm-8">
<input id="linkUrl" name="linkUrl"
class="form-control"
type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序号:</label>
<div class="col-sm-8">
<input id="sort" name="sort"
class="form-control"
type="number" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">是否开启:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="isOpen"
name="isOpen"
class="form-control chosen-select" tabindex="2"
dict-type="yes_no" required>
</select>
</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/novel/friendLink/add.js">
</script>
</body>
</html>

View File

@ -0,0 +1,100 @@
<!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="${friendLink.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="${friendLink.linkName}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">链接url</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${friendLink.linkUrl}">
</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="${friendLink.sort}">
</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 dict-type" dict-type="yes_no"
th:attr="dict-value=${friendLink.isOpen}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">创建人id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${friendLink.createUserId}">
</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="${friendLink.createTime}==null?null:${#dates.format(friendLink.createTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">更新者用户id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${friendLink.updateUserId}">
</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="${friendLink.updateTime}==null?null:${#dates.format(friendLink.updateTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
</body>
</html>

View File

@ -0,0 +1,69 @@
<!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="${friendLink.id}"
type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">链接名:</label>
<div class="col-sm-8">
<input id="linkName" name="linkName"
th:value="${friendLink.linkName}"
class="form-control"
type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">链接url</label>
<div class="col-sm-8">
<input id="linkUrl" name="linkUrl"
th:value="${friendLink.linkUrl}"
class="form-control"
type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">排序号:</label>
<div class="col-sm-8">
<input id="sort" name="sort"
th:value="${friendLink.sort}"
class="form-control"
type="number" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">是否开启:</label>
<div class="col-sm-8">
<select data-placeholder="--选择--" id="isOpen"
name="isOpen"
class="form-control chosen-select" tabindex="2"
dict-type="yes_no"
th:attr="dict-value=${friendLink.isOpen}" required>
</select>
</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/novel/friendLink/edit.js">
</script>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!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="novel:friendLink:add" type="button"
class="btn btn-primary" onclick="add()">
<i class="fa fa-plus" aria-hidden="true"></i>添加
</button>
<button shiro:hasPermission="novel:friendLink: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>
</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="novel:friendLink:edit">
<script type="text/javascript">
s_edit_h = '';
</script>
</div>
<div shiro:hasPermission="novel:friendLink:remove">
<script type="text/javascript">
var s_remove_h = '';
</script>
</div>
<div th:include="include :: footer"></div>
<script type="text/javascript" src="/js/appjs/novel/friendLink/friendLink.js"></script>
</body>
</html>