守望博客是支持創建專欄的功能,即可以將一系列相關的文章歸檔到專欄中,方便用戶管理和查閱文章。這里主要講解專欄的創建、修改和刪除功能,至於專欄還涉及其它的功能,例如關注專欄等后續會穿插着介紹。
1、創建專欄
接收和處理專欄相關功能的操作的方法會放在GroupController類中,首先創建專欄的頁面為:
這里有兩個地方需要特別說明:
第一這個分類數據,此處分類數據正是本博客網站的分類數據,這個分類數據是系統初始化時加入的,這個初始化的功能后續會加入,目前此處就是提前將數據先寫入到數據庫中,例如本博客作為技術類博客,則分類有:前端、架構、區塊鏈、雲計算等。
然后這個分類信息數據一般初始化后,就不會有修改,則這個數據是放入緩存中,即,CategoryCache:
/**
* 緩存分類信息
* 分類信息放到系統永久緩存中,存放形式為:"_CATEGORY" + categoryId為key,value為分類信息對象
*
* @author lzj
* @since 1.0
* @date [2019-07-22]
*/
@Slf4j
@DependsOn("categoryService")
@Component("categoryCache")
public class CategoryCache implements ICache<List<Category>> {
/**
* 注入基於Spring提供的Cache接口實例,默認由Ehcache實現
* TODO 以后也可以是Redis、Memcached提供實現
*/
@Autowired
private CacheManager cacheManager;
@Autowired
private ICategoryService categoryService;
/**
* 緩存實例
*/
private Cache cache;
/**
* key的前綴
*/
private String keyPrefix = "_CATEGORY";
/**
* 分類信息根節點ID
*/
public static final String ROOT_CATEGORY_ID = "0";
@PostConstruct
public void init() {
// 獲取系統永久緩存實例
cache = cacheManager.getCache(Const.CACHE_SYSTEM_ETERNAL);
log.info("獲取系統永久緩存實例");
log.debug("開始加載父分類信息");
List<Category> categorys = categoryService.getByParentId(ROOT_CATEGORY_ID);
if (categorys != null && !categorys.isEmpty()) {
put(keyPrefix + ROOT_CATEGORY_ID, categorys);
}
log.debug("加載完畢父分類信息");
}
@Override
public List<Category> get(Object key) {
Cache.ValueWrapper valueWrapper = cache.get(keyPrefix + key);
if (valueWrapper == null) {
// 從數據庫重新加載一次
List<Category> categorys = categoryService.getByParentId((String) key);
if (categorys == null) {
return null;
}
// 再次放到緩存中
put(key, categorys);
return categorys;
}
return (List<Category>) valueWrapper.get();
}
@Override
public void put(Object key, List<Category> value) {
cache.put(keyPrefix + key, value);
}
@Override
public void remove(Object key) {
cache.evict(keyPrefix + key);
}
}
第二需要說明的是,此處的上傳控制是用的webuploader,利用webuploader處理的上傳文件的話,需要按如下方式初始化:
$(function() {
var _list = $('#fileList');
var ratio = window.devicePixelRatio || 1;
var thumbnailWidth = 100 * ratio;
var thumbnailHeight = 100 * ratio;
// 初始化Web Uploader
var uploader = WebUploader.create({
// 選完文件后,是否自動上傳。
auto: true,
// swf文件路徑
swf: '${rc.contextPath}/static/plugins/webuploader/Uploader.swf',
// 文件接收服務端。
server: '${rc.contextPath}/upload',
// 選擇文件的按鈕。可選。
// 內部根據當前運行是創建,可能是input元素,也可能是flash.
pick: '#filePicker',
fileVal: "_uploadFile",
formData: {
_distId:'_distId',
_distType:'_groupLogo',
},
// 只允許選擇圖片文件。
accept: {
title: 'Images',
extensions: 'gif,jpg,jpeg,png',
mimeTypes: 'image/*'
},
fileNumLimit: 1,
fileSizeLimit: 2 * 1024 * 1024, // 2 M
fileSingleSizeLimit: 2 * 1024 * 1024 // 2 M
});
// 當有文件添加進來的時候
uploader.on( 'fileQueued', function( file ) {
var li = $(
'<div id="' + file.id + '" class="file-item thumbnail text-center">' +
'<img>' +
// '<div class="info">' + file.name + '</div>' +
'</div>'
),
img = li.find('img');
// _list為容器jQuery實例
_list.append( li );
// 創建縮略圖
// 如果為非圖片文件,可以不用調用此方法。
// thumbnailWidth x thumbnailHeight 為 100 x 100
uploader.makeThumb( file, function( error, src ) {
if ( error ) {
img.replaceWith('<span>不能預覽</span>');
return;
}
img.attr( 'src', src );
}, thumbnailWidth, thumbnailHeight );
});
// 文件上傳過程中創建進度條實時顯示。
uploader.on( 'uploadProgress', function( file, percentage ) {
});
// 文件上傳成功,給item添加成功class, 用樣式標記上傳成功。
uploader.on( 'uploadSuccess', function(file, response) {
$( '#'+file.id ).addClass('upload-state-done');
$( '#'+file.id ).append('<a class="del" href="javascript:void(0);">刪除</a>' )
$("#logo").val(response.url);
});
// 文件上傳失敗,顯示上傳出錯。
uploader.on( 'uploadError', function( file ) {
var li = $( '#'+file.id ),
error = li.find('div.error');
// 避免重復創建
if ( !error.length ) {
error = $('<div class="error"></div>').appendTo( li );
}
error.text('上傳失敗');
});
// 完成上傳完了,成功或者失敗,先刪除進度條。
uploader.on( 'uploadComplete', function( file ) {
});
// 執行刪除方法
_list.on('click', '.del', function () {
var Id = $(this).parent().attr('id');
//刪除該圖片
uploader.removeFile(uploader.getFile(Id, true));
$(this).parent().remove();
$("#logo").val("");
});
});
這里后台需要處理專欄的Logo圖片的信息,根據上一章節的方式處理,即有UploadGroupLogoHandler類,如:
/**
* 上傳專欄Logo處理類
*
* @author lzj
* @since 1.0
* @date [2019-07-23]
*/
@Slf4j
@Component("_groupLogo")
public class UploadGroupLogoHandler implements IUploadHandler {
@Resource(name = "configCache")
private ICache<Config> configCache;
@Override
public Object upload(MultipartFile file, String distType, String userId) throws Exception {
Map<String, Object> result = new HashMap<String, Object>();
try {
// 獲取圖片的原始名稱
String originalName = file.getOriginalFilename();
// 判斷圖片的類型
if (!(originalName.endsWith(".jpg") || originalName.endsWith(".JPG") || originalName.endsWith(".png") || originalName.endsWith(".PNG") || originalName.endsWith(".gif") || originalName.endsWith(".GIF") || originalName.endsWith(".jpeg") || originalName.endsWith(".JPEG"))) {
throw new TipException("您上傳的圖片類型有誤,請上傳格式為jpg、png或gif");
}
// 獲取圖片的大小
long fileSize = file.getSize();
// 圖片大小不能超過2M, 2M = 2 * 1024 * 1024B = 2097152B
if (fileSize > 2097152L) {
throw new TipException("您上傳的圖片超過2M");
}
Config config = configCache.get(Config.CONFIG_IMG_GROUP_LOGO_PATH);
// 保存頭像的根目錄
String basePath = config.getConfigValue();
if (!(basePath.endsWith("/") || basePath.endsWith("\\"))) {
basePath += "/";
}
// 根據當前時間構建yyyyMM的文件夾,建立到月的文件夾
String dateDirName = DateUtil.date2Str(new Date(), DateUtil.YEAR_MONTH_FORMAT);
basePath += dateDirName;
File imageDir = new File(basePath);
if (!imageDir.exists()) {
imageDir.mkdirs();
}
String fileNewName = IdGenarator.guid() + originalName.substring(originalName.lastIndexOf("."));
FileUtil.copy(file.getInputStream(), new FileOutputStream(new File(imageDir, fileNewName)));
result.put("url", dateDirName + "/" + fileNewName);
result.put("msg", "上傳成功");
} catch (TipException e) {
result.put("url", "");
result.put("msg", e.getMessage());
} catch (Exception e) {
log.error("上傳失敗", e);
result.put("url", "");
result.put("msg", "上傳失敗");
}
return result;
}
@Override
public void download(String fileId, HttpServletResponse response) throws Exception {
}
@Override
public Object list(String distType, String userId) throws Exception {
return null;
}
}
最后創建專欄的核心代碼如下:
/**
* 創建專欄
*
* @param request
* @param session
* @return
*/
@RequestMapping(value = "/user/group/add", method = RequestMethod.POST)
@ResponseBody
public Result add(HttpServletRequest request, HttpSession session) {
Result result = new Result();
try {
// 接收參數
String categoryId = request.getParameter("categoryId");
String name = request.getParameter("name");
String logo = request.getParameter("logo");
String introduce = request.getParameter("introduce");
// 校驗參數
if (StringUtils.isEmpty(categoryId) || StringUtils.isEmpty(name) || StringUtils.isEmpty(logo) || StringUtils.isEmpty(introduce)) {
throw new TipException("缺少必要參數");
}
// 獲取登錄信息
User tempUser = (User) session.getAttribute(Const.SESSION_USER);
String userId = tempUser.getUserId();
// 構建專欄對象
Group group = new Group();
group.setGroupId(IdGenarator.longIdStr());
group.setName(name);
group.setLogo(logo);
group.setIntroduce(introduce);
group.setCategoryId(categoryId);
group.setCreator(userId);
group.setCreateTime(new Date());
// 從系統配置項獲取專欄是否審核
Config config = configCache.get(Config.CONFIG_GROUP_AUDIT);
if (config != null && "1".equals(config.getConfigValue())) {
// 需要審核
group.setStatus(Group.STATUS_NO);
} else {
// 不需要審核
group.setStatus(Group.STATUS_SUCCESS);
}
// 保存專欄信息
boolean flag = groupService.save(group);
if (!flag) {
throw new TipException("創建專欄失敗");
}
result.setCode(Result.CODE_SUCCESS);
result.setMsg("成功創建專欄");
} catch (TipException e) {
result.setCode(Result.CODE_EXCEPTION);
result.setMsg(e.getMessage());
} catch (Exception e) {
log.error("創建專欄失敗", e);
result.setCode(Result.CODE_EXCEPTION);
result.setMsg("創建專欄失敗");
}
return result;
}
2、修改專欄
有了前面新增專欄的基礎,其實修改專欄的功能就相對簡單很多了,此處只列出處理修改的核心代碼即可,如:
/**
* 修改專欄
*
* @param groupId
* @param request
* @param session
* @return
*/
@RequestMapping(value = "/user/group/edit/{groupId}", method = RequestMethod.POST)
@ResponseBody
public Result edit(@PathVariable("groupId") String groupId, HttpServletRequest request, HttpSession session) {
Result result = new Result();
try {
// 根據id獲取專欄信息
Group group = groupService.getById(groupId);
if (group == null || StringUtils.isEmpty(group.getGroupId())) {
log.error("groupId: " + groupId + ": 該專欄不存在");
throw new TipException("該專欄不存在");
}
// 獲取用戶信息
User tempUser = (User) session.getAttribute(Const.SESSION_USER);
String userId = tempUser.getUserId();
if (!userId.equals(group.getCreator())) {
log.error("userId: " + userId + "修改別人的groupId: " + groupId);
throw new TipException("不能修改別人的專欄");
}
// 接收參數
String categoryId = request.getParameter("categoryId");
String name = request.getParameter("name");
String introduce = request.getParameter("introduce");
String logo = request.getParameter("logo");
// 校驗參數
if (StringUtils.isEmpty(categoryId) || StringUtils.isEmpty(name) || StringUtils.isEmpty(introduce)) {
throw new TipException("缺少必要參數");
}
group.setCategoryId(categoryId);
group.setName(name);
group.setIntroduce(introduce);
if (!StringUtils.isEmpty(logo)) {
group.setLogo(logo);
}
group.setUpdateTime(new Date());
// 修改
boolean flag = groupService.updateById(group);
if (!flag) {
throw new TipException("修改專欄失敗");
}
result.setCode(Result.CODE_SUCCESS);
result.setMsg("修改專欄成功");
} catch (TipException e) {
result.setCode(Result.CODE_EXCEPTION);
result.setMsg(e.getMessage());
} catch (Exception e) {
log.error("修改專欄失敗", e);
result.setCode(Result.CODE_EXCEPTION);
result.setMsg("修改專欄失敗");
}
return result;
}
3、刪除專欄
刪除專欄功能是很簡單的,但是需要考慮到,刪除專欄后,需要處理其它與之關聯的數據信息,此處由於其它模塊還沒有完成,所以先將加一個TODO,后續會再處理。那刪除專欄的核心代碼如下:
/**
* 根據ID刪除專欄
*
* @param groupId
* @param session
* @return
*/
@RequestMapping(value = "/user/group/delete/{groupId}", method = RequestMethod.GET)
@ResponseBody
public Result delete(@PathVariable("groupId") String groupId, HttpSession session) {
Result result = new Result();
try {
// 根據id獲取專欄信息
Group group = groupService.getById(groupId);
if (group == null || StringUtils.isEmpty(group.getGroupId())) {
log.error("groupId: " + groupId + ": 該專欄不存在");
throw new TipException("該專欄不存在");
}
// 獲取用戶信息
User tempUser = (User) session.getAttribute(Const.SESSION_USER);
String userId = tempUser.getUserId();
if (!userId.equals(group.getCreator())) {
log.error("userId: " + userId + "刪除別人的groupId: " + groupId);
throw new TipException("不能刪除別人的專欄");
}
// 刪除
boolean flag = groupService.removeById(groupId);
if (!flag) {
throw new TipException("刪除專欄失敗");
}
// TODO 刪除專欄后,需要處理其它關聯的數據,由於其它模塊還沒有,此處后續處理
result.setCode(Result.CODE_SUCCESS);
result.setMsg("刪除專欄成功");
} catch (TipException e) {
result.setCode(Result.CODE_EXCEPTION);
result.setMsg(e.getMessage());
} catch (Exception e) {
log.error("刪除專欄失敗", e);
result.setCode(Result.CODE_EXCEPTION);
result.setMsg("刪除專欄失敗");
}
return result;
}
關注我
以你最方便的方式關注我:
微信公眾號: