package com.tale.service.impl; import com.blade.ioc.annotation.Inject; import com.blade.ioc.annotation.Service; import com.blade.jdbc.ar.SampleActiveRecord; import com.blade.jdbc.core.Take; import com.blade.jdbc.model.Paginator; import com.blade.kit.*; import com.tale.controller.admin.AttachController; import com.tale.dto.*; import com.tale.exception.TipException; import com.tale.ext.Theme; import com.tale.init.SqliteJdbc; import com.tale.init.TaleConst; import com.tale.model.*; import com.tale.service.*; import com.tale.utils.MapCache; import com.tale.utils.TaleUtils; import com.tale.utils.ZipUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; /** * Created by biezhi on 2017/2/23. */ @Service public class SiteServiceImpl implements SiteService { private static final Logger LOGGER = LoggerFactory.getLogger(SiteService.class); @Inject private SampleActiveRecord activeRecord; @Inject private OptionsService optionsService; @Inject private LogService logService; @Inject private MetasService metasService; @Inject private CommentsService commentsService; public MapCache mapCache = new MapCache(); @Override public void initSite(Users users) { String pwd = Tools.md5(users.getUsername() + users.getPassword()); users.setPassword(pwd); users.setScreen_name(users.getUsername()); users.setCreated(DateKit.getCurrentUnixTime()); Integer uid = activeRecord.insert(users); try { String cp = SiteServiceImpl.class.getClassLoader().getResource("").getPath(); File lock = new File(cp + "install.lock"); lock.createNewFile(); TaleConst.INSTALL = Boolean.TRUE; logService.save(LogActions.INIT_SITE, null, "", uid.intValue()); } catch (Exception e) { throw new TipException("初始化站点失败"); } } @Override public List<Comments> recentComments(int limit) { if (limit < 0 || limit > 10) { limit = 10; } Paginator<Comments> cp = activeRecord.page(new Take(Comments.class).page(1, limit, "created desc")); return cp.getList(); } @Override public List<Contents> getContens(String type, int limit) { if (limit < 0 || limit > 20) { limit = 10; } Paginator<Contents> cp = new Paginator<>(1, 1); // 最新文章 if (Types.RECENT_ARTICLE.equals(type)) { cp = activeRecord.page(new Take(Contents.class) .eq("status", Types.PUBLISH).eq("type", Types.ARTICLE).page(1, limit, "created desc")); } // 随机文章 if (Types.RANDOM_ARTICLE.equals(type)) { List<Integer> cids = activeRecord.list(Integer.class, "select cid from t_contents where type = ? and status = ? order by rand() * cid limit ?", Types.ARTICLE, Types.PUBLISH, limit); if (CollectionKit.isNotEmpty(cids)) { Integer[] inCids = cids.toArray(new Integer[cids.size()]); return activeRecord.list(new Take(Contents.class).in("cid", inCids)); } } return cp.getList(); } @Override public Statistics getStatistics() { Statistics statistics = mapCache.get(Types.C_STATISTICS); if (null != statistics) { return statistics; } statistics = new Statistics(); int articles = activeRecord.count(new Take(Contents.class).eq("type", Types.ARTICLE).eq("status", Types.PUBLISH)); int pages = activeRecord.count(new Take(Contents.class).eq("type", Types.PAGE).eq("status", Types.PUBLISH)); int comments = activeRecord.count(new Take(Comments.class)); int attachs = activeRecord.count(new Take(Attach.class)); int links = activeRecord.count(new Take(Metas.class).eq("type", Types.LINK)); int tags = activeRecord.count(new Take(Metas.class).eq("type", Types.TAG)); int categories = activeRecord.count(new Take(Metas.class).eq("type", Types.CATEGORY)); statistics.setArticles(articles); statistics.setPages(pages); statistics.setComments(comments); statistics.setAttachs(attachs); statistics.setLinks(links); statistics.setTags(tags); statistics.setCategories(categories); mapCache.set(Types.C_STATISTICS, statistics); return statistics; } @Override public List<Archive> getArchives() { String sql = "select strftime('%Y年%m月', datetime(created, 'unixepoch') ) as date_str, count(*) as count from t_contents\n" + "where type = 'post' and status = 'publish' group by date_str order by date_str desc"; List<Archive> archives = activeRecord.list(Archive.class, sql); if (null != archives) { archives.forEach(archive -> { String date_str = archive.getDate_str(); Date sd = DateKit.dateFormat(date_str, "yyyy年MM月"); archive.setDate(sd); int start = DateKit.getUnixTimeByDate(sd); Calendar calender = Calendar.getInstance(); calender.setTime(sd); calender.add(Calendar.MONTH, 1); Date endSd = calender.getTime(); int end = DateKit.getUnixTimeByDate(endSd) - 1; List<Contents> contentss = activeRecord.list(new Take(Contents.class) .eq("type", Types.ARTICLE) .eq("status", Types.PUBLISH) .gt("created", start).lt("created", end).orderby("created desc")); archive.setArticles(contentss); }); } return archives; } @Override public Comments getComment(Integer coid) { if (null != coid) { return activeRecord.byId(Comments.class, coid); } return null; } @Override public BackResponse backup(String bk_type, String bk_path, String fmt) throws Exception { BackResponse backResponse = new BackResponse(); if ("attach".equals(bk_type)) { if (StringKit.isBlank(bk_path)) { throw new TipException("请输入备份文件存储路径"); } if (!FileKit.isDirectory(bk_path)) { throw new TipException("请输入一个存在的目录"); } String bkAttachDir = AttachController.CLASSPATH + "upload"; String bkThemesDir = AttachController.CLASSPATH + "templates/themes"; String fname = DateKit.dateFormat(new Date(), fmt) + "_" + StringKit.getRandomNumber(5) + ".zip"; String attachPath = bk_path + "/" + "attachs_" + fname; String themesPath = bk_path + "/" + "themes_" + fname; ZipUtils.zipFolder(bkAttachDir, attachPath); ZipUtils.zipFolder(bkThemesDir, themesPath); backResponse.setAttach_path(attachPath); backResponse.setTheme_path(themesPath); } // 备份数据库 if("db".equals(bk_type)){ String filePath = "upload/" + DateKit.getToday("yyyyMMddHHmmss") + "_" + StringKit.getRandomNumber(8) + ".db"; String cp = AttachController.CLASSPATH + filePath; FileKit.createParentDir(cp); FileKit.copy(SqliteJdbc.DB_PATH, cp); backResponse.setSql_path("/" + filePath); // 10秒后删除备份文件 new Timer().schedule(new TimerTask() { @Override public void run() { new File(cp).delete(); } }, 10 * 1000); } return backResponse; } @Override public List<MetaDto> getMetas(String searchType, String type, int limit) { if (StringKit.isBlank(searchType) || StringKit.isBlank(type)) { return Theme.EMPTY; } if (limit < 1 || limit > TaleConst.MAX_POSTS) { limit = 10; } // 获取最新的项目 if (Types.RECENT_META.equals(searchType)) { String sql = "select a.*, count(b.cid) as count from t_metas a left join `t_relationships` b on a.mid = b.mid " + "where a.type = ? group by a.mid order by count desc, a.mid desc limit ?"; return activeRecord.list(MetaDto.class, sql, type, limit); } // 随机获取项目 if (Types.RANDOM_META.equals(searchType)) { List<Integer> mids = activeRecord.list(Integer.class, "select mid from t_metas where type = ? order by rand() * mid limit ?", type, limit); if (CollectionKit.isNotEmpty(mids)) { String in = TaleUtils.listToInSql(mids); String sql = "select a.*, count(b.cid) as count from t_metas a left join `t_relationships` b on a.mid = b.mid " + "where a.mid in "+ in + "group by a.mid order by count desc, a.mid desc"; return activeRecord.list(MetaDto.class, sql); } } return Theme.EMPTY; } @Override public Contents getNhContent(String type, Integer cid) { if(Types.NEXT.equals(type)){ return activeRecord.one(new Take(Contents.class).eq("type", Types.ARTICLE).eq("status", Types.PUBLISH).gt("cid", cid)); } if(Types.PREV.equals(type)){ return activeRecord.one(new Take(Contents.class).eq("type", Types.ARTICLE).eq("status", Types.PUBLISH).lt("cid", cid)); } return null; } @Override public Paginator<Comment> getComments(Integer cid, int page, int limit) { return commentsService.getComments(cid, page, limit); } @Override public void cleanCache(String key) { if (StringKit.isNotBlank(key)) { if ("*".equals(key)) { mapCache.clean(); } else { mapCache.del(key); } } } }