first commit
|
@ -0,0 +1,12 @@
|
|||
# Halo 1.0 Beta
|
||||
```java
|
||||
public class GoDie{
|
||||
public static void main(String[] args){
|
||||
System.out.println("填坑开始了");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[](https://ryanc.cc)
|
||||
[](https://ryanc.cc)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
|
||||
<id>distribution</id>
|
||||
<formats>
|
||||
<format>dir</format>
|
||||
</formats>
|
||||
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>src/main/resources/</directory>
|
||||
<outputDirectory>/resources</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>bin/</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<scope>runtime</scope>
|
||||
<excludes>
|
||||
<exclude>${project.groupId}:${project.artifactId}</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
<dependencySet>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>${project.groupId}:${project.artifactId}</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
|
@ -0,0 +1,68 @@
|
|||
#!/bin/bash
|
||||
APP_NAME=halo-beta.jar
|
||||
|
||||
usage() {
|
||||
echo "用法: sh halo.sh [start|stop|restart|status]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
is_exist(){
|
||||
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
|
||||
if [ -z "${pid}" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
start(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo "${APP_NAME} is already running. pid=${pid} ."
|
||||
else
|
||||
nohup java -jar $APP_NAME > /dev/null 2>&1 &
|
||||
echo "${APP_NAME} is starting..."
|
||||
fi
|
||||
}
|
||||
|
||||
stop(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
kill -9 $pid
|
||||
echo "${pid} will be killing"
|
||||
else
|
||||
echo "${APP_NAME} is not running"
|
||||
fi
|
||||
}
|
||||
|
||||
status(){
|
||||
is_exist
|
||||
if [ $? -eq "0" ]; then
|
||||
echo "${APP_NAME} is running. Pid is ${pid}"
|
||||
else
|
||||
echo "${APP_NAME} is NOT running."
|
||||
fi
|
||||
}
|
||||
|
||||
restart(){
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
"start")
|
||||
start
|
||||
;;
|
||||
"stop")
|
||||
stop
|
||||
;;
|
||||
"status")
|
||||
status
|
||||
;;
|
||||
"restart")
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,187 @@
|
|||
<?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>cc.ryanc</groupId>
|
||||
<artifactId>halo</artifactId>
|
||||
<version>beta</version>
|
||||
<name>halo</name>
|
||||
|
||||
<description>
|
||||
halo,一个基于SpringBoot的博客系统,最求轻快,易用,以内容为中心。
|
||||
</description>
|
||||
<!-- 填坑的人 -->
|
||||
<developers>
|
||||
<developer>
|
||||
<id>RYAN0UP</id>
|
||||
<name>Ruiyuan Wang</name>
|
||||
<email>i@ryanc.cc</email>
|
||||
<url>https://ryanc.cc</url>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.8.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>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- freemarker依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- druid数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.18</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- enCache -->
|
||||
<dependency>
|
||||
<groupId>org.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- rss -->
|
||||
<dependency>
|
||||
<groupId>rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<!-- 生产环境打包配置 -->
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<build>
|
||||
<finalName>halo</finalName>
|
||||
<resources>
|
||||
<!-- 让jar包只存在字节码文件 -->
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<filtering>false</filtering>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<!-- 跳过单元测试,不然打包的时候会因为加载不了application.yaml报错 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<descriptors>
|
||||
<descriptor>assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>${project.build.directory}/dist/</outputDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- 打包成jar文件,并指定lib文件夹以及resources资源文件夹 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>cc.ryanc.halo.Application</mainClass>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<addClasspath>true</addClasspath>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Class-Path>resources/</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- 开发环境 -->
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,17 @@
|
|||
package cc.ryanc.halo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
|
||||
/**
|
||||
* @author RYAN0UP
|
||||
* SpringBoot启动类
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableCaching
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package cc.ryanc.halo.config;
|
||||
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.web.interceptor.LoginInterceptor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/1/2
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@ComponentScan(basePackages = "cc.ryanc.halo.web.controller")
|
||||
@PropertySource(value = "classpath:application.yaml",ignoreResourceNotFound = true,encoding = "UTF-8")
|
||||
public class MvcConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private LoginInterceptor loginInterceptor;
|
||||
|
||||
@Autowired
|
||||
private OptionsService optionsService;
|
||||
|
||||
/**
|
||||
* 注册拦截器
|
||||
* @param registry registry
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login").excludePathPatterns("/admin/getLogin");
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置静态资源路径
|
||||
* @param registry registry
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
|
||||
registry.addResourceHandler("/**").addResourceLocations("classpath:/templates/themes/")
|
||||
.addResourceLocations("classpath:/robots.txt");
|
||||
registry.addResourceHandler("/upload/**").addResourceLocations("classpath:/upload/");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package cc.ryanc.halo.config;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.service.AttachmentService;
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import cc.ryanc.halo.web.controller.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/22
|
||||
* @version : 1.0
|
||||
* description: Springboot启动后
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class StartupConfiguration implements ApplicationListener<ContextRefreshedEvent>{
|
||||
|
||||
@Autowired
|
||||
private OptionsService optionsService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private AttachmentService attachmentService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
this.loadActiveTheme();
|
||||
this.loadOptions();
|
||||
this.loadFiles();
|
||||
this.loadThemes();
|
||||
this.loadUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载主题设置
|
||||
*/
|
||||
private void loadActiveTheme(){
|
||||
try {
|
||||
String themeValue = optionsService.findOneOption("theme");
|
||||
if(HaloUtil.isNotNull(themeValue)){
|
||||
BaseController.THEME = themeValue;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载设置选项
|
||||
*/
|
||||
private void loadOptions(){
|
||||
try{
|
||||
Map<String,String> options = optionsService.findAllOptions();
|
||||
if(options!=null&&!options.isEmpty()){
|
||||
HaloConst.OPTIONS = options;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载所有文件
|
||||
*/
|
||||
private void loadFiles(){
|
||||
try {
|
||||
List<Attachment> attachments = attachmentService.findAllAttachments();
|
||||
if(null!=attachments){
|
||||
HaloConst.ATTACHMENTS = attachments;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadThemes(){
|
||||
|
||||
}
|
||||
|
||||
private void loadUser(){
|
||||
try {
|
||||
User user = userService.findAllUser().get(0);
|
||||
if(null!=user){
|
||||
HaloConst.USER = user;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/1/10
|
||||
* description :
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_attachment")
|
||||
public class Attachment implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer attachId;
|
||||
private String attachName;
|
||||
private String attachPath;
|
||||
private String attachSmallPath;
|
||||
private String attachType;
|
||||
private String attachSuffix;
|
||||
private Date attachCreated;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/30
|
||||
* @version : 1.0
|
||||
* description : 分类目录实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_category")
|
||||
public class Category implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer cateId;
|
||||
private String cateName;
|
||||
private String cateUrl;
|
||||
private String cateDesc;
|
||||
|
||||
@ManyToMany(mappedBy = "categories")
|
||||
@JsonIgnore
|
||||
private List<Post> posts = new ArrayList<>();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 友情链接的实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_link")
|
||||
public class Link implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer linkId;
|
||||
private String linkName;
|
||||
private String linkUrl;
|
||||
private String linkPic;
|
||||
private String linkDesc;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/19
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_logs")
|
||||
public class Logs implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer logId;
|
||||
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String logTitle;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String logContent;
|
||||
|
||||
/**
|
||||
* 产生日志的ip
|
||||
*/
|
||||
private String logIp;
|
||||
|
||||
/**
|
||||
* 产生的时间
|
||||
*/
|
||||
private Date logCreated;
|
||||
|
||||
public Logs() { }
|
||||
|
||||
public Logs(String logTitle, String logContent, String logIp, Date logCreated) {
|
||||
this.logTitle = logTitle;
|
||||
this.logContent = logContent;
|
||||
this.logIp = logIp;
|
||||
this.logCreated = logCreated;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 设置相关的实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_options")
|
||||
public class Options implements Serializable {
|
||||
@Id
|
||||
private String optionName;
|
||||
@Lob
|
||||
private String optionValue;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 文章实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_post")
|
||||
public class Post implements Serializable{
|
||||
/**
|
||||
* 文章编号
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer postId;
|
||||
|
||||
/**
|
||||
* 发表用户 多对一
|
||||
*/
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "user_id")
|
||||
private User user;
|
||||
|
||||
/**
|
||||
* 文章标题
|
||||
*/
|
||||
private String postTitle;
|
||||
|
||||
/**
|
||||
* 文章内容 Markdown格式
|
||||
*/
|
||||
@Lob
|
||||
private String postContentMd;
|
||||
|
||||
/**
|
||||
* 文章内容 html格式
|
||||
*/
|
||||
@Lob
|
||||
private String postContent;
|
||||
|
||||
/**
|
||||
* 文章路径
|
||||
*/
|
||||
@Column(unique = true)
|
||||
private String postUrl;
|
||||
|
||||
/**
|
||||
* 文章摘要
|
||||
*/
|
||||
private String postSummary;
|
||||
|
||||
/**
|
||||
* 文章所属分类
|
||||
*/
|
||||
@ManyToMany(cascade = {CascadeType.PERSIST},fetch = FetchType.LAZY)
|
||||
@JoinTable(name = "halo_posts_categories",
|
||||
joinColumns = {@JoinColumn(name = "post_id",nullable = false)},
|
||||
inverseJoinColumns = {@JoinColumn(name = "cate_id",nullable = false)})
|
||||
private List<Category> categories = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 文章所属标签
|
||||
*/
|
||||
@ManyToMany(cascade = {CascadeType.PERSIST},fetch = FetchType.LAZY)
|
||||
@JoinTable(name = "halo_posts_tags",
|
||||
joinColumns = {@JoinColumn(name = "post_id",nullable = false)},
|
||||
inverseJoinColumns = {@JoinColumn(name = "tag_id",nullable = false)})
|
||||
private List<Tag> tags = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 发表日期
|
||||
*/
|
||||
private Date postDate;
|
||||
|
||||
/**
|
||||
* 0 已发布
|
||||
* 1 草稿
|
||||
* 2 回收站
|
||||
*/
|
||||
private Integer postStatus = 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 文章详细信息实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_postmeta")
|
||||
public class PostMeta implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer metaId;
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/12
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_tag")
|
||||
public class Tag implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer tagId;
|
||||
private String tagName;
|
||||
private String tagUrl;
|
||||
|
||||
@ManyToMany(mappedBy = "tags")
|
||||
@JsonIgnore
|
||||
private List<Post> posts = new ArrayList<>();
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/1/3
|
||||
* description :
|
||||
*/
|
||||
@Data
|
||||
public class Theme implements Serializable {
|
||||
private Integer themeId;
|
||||
private String themeName;
|
||||
private String themeScreenShot;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 用户实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_user")
|
||||
public class User implements Serializable{
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer userId;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
/**
|
||||
* 显示名称
|
||||
*/
|
||||
private String userDisplayName;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String userPass;
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String userEmail;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private String userDesc;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package cc.ryanc.halo.model.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description : 用户详细信息实体类
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "halo_usermeta")
|
||||
public class UserMeta implements Serializable{
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer userMetaId;
|
||||
private Integer userId;
|
||||
private String userMetaKey;
|
||||
@Lob
|
||||
private String userMetaValue;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package cc.ryanc.halo.model.dto;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/20
|
||||
*/
|
||||
@Data
|
||||
public class Archive {
|
||||
|
||||
private String year;
|
||||
|
||||
private String month;
|
||||
|
||||
private String count;
|
||||
|
||||
private List<Post> posts;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package cc.ryanc.halo.model.dto;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import cc.ryanc.halo.model.domain.Theme;
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/29
|
||||
* @version : 1.0
|
||||
* description: 环境常量
|
||||
*/
|
||||
public class HaloConst {
|
||||
/**
|
||||
* 所有设置选项(key,value)
|
||||
*/
|
||||
public static Map<String,String> OPTIONS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
public static User USER = new User();
|
||||
|
||||
/**
|
||||
* 所有文件
|
||||
*/
|
||||
public static List<Attachment> ATTACHMENTS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 所有主题
|
||||
*/
|
||||
public static List<Theme> THEMES = new ArrayList<>();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cc.ryanc.halo.model.dto;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/19
|
||||
*/
|
||||
public interface LogsRecord {
|
||||
|
||||
String LOGIN = "登录后台";
|
||||
|
||||
String LOGIN_SUCCESS = "登录成功";
|
||||
|
||||
String LOGIN_ERROR = "登录失败";
|
||||
|
||||
String LOGOUT = "退出登录";
|
||||
|
||||
String PUSH_POST = "发表文章";
|
||||
|
||||
String REMOVE_POST = "删除文章";
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package cc.ryanc.halo.model.dto;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/24
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
public class RespStatus {
|
||||
public static final String SUCCESS = "success";
|
||||
public static final String ERROR = "error";
|
||||
public static final String EXISTS = "exists";
|
||||
public static final String NOTEXISTS = "notExists";
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/10
|
||||
*/
|
||||
public interface AttachmentRepository extends JpaRepository<Attachment,Integer>{
|
||||
@Override
|
||||
Page<Attachment> findAll(Pageable pageable);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/30
|
||||
* @version : 1.0
|
||||
* description: 分类目录持久层
|
||||
*/
|
||||
public interface CategoryRepository extends JpaRepository<Category,Integer>{
|
||||
|
||||
/**
|
||||
* 根据分类目录路径查询,用于验证是否已经存在该路径
|
||||
* @param cateUrl cateUrl
|
||||
* @return category
|
||||
*/
|
||||
Category findCategoryByCateUrl(String cateUrl);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* className: LinkRepository
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* description: 友情链接持久层
|
||||
*/
|
||||
public interface LinkRepository extends JpaRepository<Link,Integer>{
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Logs;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/19
|
||||
*/
|
||||
public interface LogsRepository extends JpaRepository<Logs,Integer> {
|
||||
|
||||
/**
|
||||
* 查询最新的五条数据
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "SELECT * FROM halo_logs ORDER BY log_id DESC LIMIT 5",nativeQuery = true)
|
||||
List<Logs> findTopFive();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Options;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description: 设置选项持久层
|
||||
*/
|
||||
public interface OptionsRepository extends JpaRepository<Options,Integer>{
|
||||
|
||||
/**
|
||||
* 根据key查询单个option
|
||||
* @param key key
|
||||
* @return String
|
||||
*/
|
||||
Options findOptionsByOptionName(String key);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.PostMeta;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
public interface PostMetaRepository extends JpaRepository<PostMeta,Integer>{
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.Archive;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description : 文章持久层
|
||||
*/
|
||||
public interface PostRepository extends JpaRepository<Post,Integer>{
|
||||
|
||||
/**
|
||||
* 查询前五条文章
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "SELECT * FROM halo_post ORDER BY post_id DESC LIMIT 5",nativeQuery = true)
|
||||
List<Post> findTopFive();
|
||||
|
||||
/**
|
||||
* 分页查询文章
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
@Override
|
||||
Page<Post> findAll(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 模糊查询
|
||||
* @param keyWord keyword
|
||||
* @param pageable pageable
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findByPostTitleLike(String keyWord,Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据文章的状态查询 分页
|
||||
* @param status status
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
Page<Post> findPostsByPostStatus(Integer status,Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据文章的状态查询
|
||||
* @param status status
|
||||
* @return List
|
||||
*/
|
||||
List<Post> findPostsByPostStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 根据路径查询文章
|
||||
* @param postUrl postUrl
|
||||
* @return Post
|
||||
*/
|
||||
Post findPostByPostUrl(String postUrl);
|
||||
|
||||
/**
|
||||
* 查询之后文章
|
||||
* @param postDate postDate
|
||||
* @param postStatus postStatus
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findByPostDateAfterAndPostStatusOrderByPostDateDesc(Date postDate, Integer postStatus);
|
||||
|
||||
|
||||
/**
|
||||
* 查询之前的文章
|
||||
* @param postDate postDate
|
||||
* @param postStatus postStatus
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findByPostDateBeforeAndPostStatusOrderByPostDateAsc(Date postDate,Integer postStatus);
|
||||
|
||||
/**
|
||||
* 查询文章归档信息
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "select year(post_date) as year,month(post_date) as month,count(*) as count from halo_post where post_status=0 group by year(post_date) DESC ,month(post_date) DESC",nativeQuery = true)
|
||||
List<Object[]> findPostGroupByDate();
|
||||
|
||||
/**
|
||||
* 根据年份和月份查询文章
|
||||
* @param year year
|
||||
* @param month month
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date desc",nativeQuery = true)
|
||||
List<Post> findPostByYearAndMonth(@Param("year") String year,@Param("month") String month);
|
||||
|
||||
/**
|
||||
* 根据年份和月份查询文章 分页
|
||||
* @param year year
|
||||
* @param month month
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
@Query(value = "select * from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by ?#{#pageable}",countQuery = "select * from halo_post",nativeQuery = true)
|
||||
Page<Post> findPostByYearAndMonth(@Param("year") String year,@Param("month") String month,Pageable pageable);
|
||||
|
||||
List<Post> findPostByCategories(Category category);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Tag;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/12
|
||||
*/
|
||||
public interface TagRepository extends JpaRepository<Tag,Integer>{
|
||||
|
||||
/**
|
||||
* 根据标签路径查询,用于验证是否已经存在该路径
|
||||
* @param tagUrl tagUrl
|
||||
* @return tag
|
||||
*/
|
||||
Tag findTagByTagUrl(String tagUrl);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.UserMeta;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version :1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
public interface UserMetaRepository extends JpaRepository<UserMeta,Integer>{
|
||||
|
||||
UserMeta findByUserMetaKey(String key);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cc.ryanc.halo.repository;
|
||||
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
public interface UserRepository extends JpaRepository<User,Integer>{
|
||||
/**
|
||||
* 根据用户名和密码查询
|
||||
* @param userName userName
|
||||
* @param userPass userPass
|
||||
* @return User
|
||||
*/
|
||||
User findByUserNameAndUserPass(String userName,String userPass);
|
||||
|
||||
/**
|
||||
* 根据用户编号和密码查询
|
||||
* @param userId userId
|
||||
* @param userPass userpass
|
||||
* @return User
|
||||
*/
|
||||
User findByUserIdAndUserPass(Integer userId,String userPass);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/10
|
||||
*/
|
||||
public interface AttachmentService {
|
||||
/**
|
||||
* 添加附件信息
|
||||
* @param attachment attachment
|
||||
* @return Attachment
|
||||
*/
|
||||
Attachment saveByAttachment(Attachment attachment);
|
||||
|
||||
/**
|
||||
* 查询所有附件信息
|
||||
* @return list
|
||||
*/
|
||||
List<Attachment> findAllAttachments();
|
||||
|
||||
Page<Attachment> findAllAttachments(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据编号查询
|
||||
* @param attachId attachId
|
||||
* @return Attachment
|
||||
*/
|
||||
Attachment findByAttachId(Integer attachId);
|
||||
|
||||
/**
|
||||
* 根据编号移除
|
||||
* @param attachId attachId
|
||||
* @return Attachment
|
||||
*/
|
||||
Attachment removeByAttachId(Integer attachId);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/30
|
||||
* @version : 1.0
|
||||
* description :
|
||||
*/
|
||||
public interface CategoryService {
|
||||
/**
|
||||
* 新增分类目录
|
||||
* @param category 分类目录
|
||||
* @return 如果插入成功,返回分类目录对象
|
||||
*/
|
||||
Category saveByCategory(Category category);
|
||||
|
||||
/**
|
||||
* 根据编号删除分类目录
|
||||
* @param cateId 分类目录编号
|
||||
* @return category
|
||||
*/
|
||||
Category removeByCateId(Integer cateId);
|
||||
|
||||
/**
|
||||
* 修改分类目录信息
|
||||
* @param category 分类目录对象
|
||||
* @return 如果修改成功 返回当前分类目录对象
|
||||
*/
|
||||
Category updateByCategory(Category category);
|
||||
|
||||
/**
|
||||
* 获取所有分类目录
|
||||
* @return 返回List集合
|
||||
*/
|
||||
List<Category> findAllCategories();
|
||||
|
||||
/**
|
||||
* 根据编号查询单个分类
|
||||
* @param cateId 分类编号
|
||||
* @return 返回category实体
|
||||
*/
|
||||
Category findByCateId(Integer cateId);
|
||||
|
||||
/**
|
||||
* 根据分类目录路径查询,用于验证是否已经存在该路径
|
||||
* @param cateUrl cateUrl
|
||||
* @return category
|
||||
*/
|
||||
Category findByCateUrl(String cateUrl);
|
||||
|
||||
List<Category> strListToCateList(List<String> strings);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
public interface LinkService {
|
||||
/**
|
||||
* 新增友情链接
|
||||
* @param link link
|
||||
* @return Link
|
||||
*/
|
||||
Link saveByLink(Link link);
|
||||
|
||||
/**
|
||||
* 根据编号删除
|
||||
* @param linkId linkId
|
||||
* @return Link
|
||||
*/
|
||||
Link removeByLinkId(Integer linkId);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
* @param link link
|
||||
* @return Link
|
||||
*/
|
||||
Link updateByLink(Link link);
|
||||
|
||||
/**
|
||||
* 查询所有
|
||||
* @return List
|
||||
*/
|
||||
List<Link> findAllLinks();
|
||||
|
||||
/**
|
||||
* 根据编号查询单个链接
|
||||
* @param linkId linkId
|
||||
* @return Link
|
||||
*/
|
||||
Link findByLinkId(Integer linkId);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
import cc.ryanc.halo.model.domain.Logs;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/19
|
||||
*/
|
||||
public interface LogsService {
|
||||
|
||||
/**
|
||||
* 保存日志
|
||||
* @param logs logs
|
||||
* @return logs
|
||||
*/
|
||||
Logs saveByLogs(Logs logs);
|
||||
|
||||
/**
|
||||
* 根据编号移除
|
||||
* @param logsId logsId
|
||||
* @return Logs
|
||||
*/
|
||||
void removeByLogsId(Integer logsId);
|
||||
|
||||
/**
|
||||
* 移除所有日志
|
||||
*/
|
||||
void removeAllLogs();
|
||||
|
||||
/**
|
||||
* 查询所有日志并分页
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
Page<Logs> findAllLogs(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 查询最新的五条日志
|
||||
* @return list
|
||||
*/
|
||||
List<Logs> findLogsLatest();
|
||||
|
||||
/**
|
||||
* 根据编号查询
|
||||
* @param logsId logsId
|
||||
* @return logs
|
||||
*/
|
||||
Logs findLogsByLogsId(Integer logsId);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Options;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description :
|
||||
*/
|
||||
public interface OptionsService {
|
||||
|
||||
|
||||
/**
|
||||
* 保存单个设置选项
|
||||
* @param key key
|
||||
* @param value value
|
||||
*/
|
||||
void saveOption(String key,String value);
|
||||
|
||||
/**
|
||||
* 保存多个设置选项
|
||||
* @param options options
|
||||
*/
|
||||
void saveOptions(Map<String,String> options);
|
||||
|
||||
void removeOption(Options options);
|
||||
|
||||
/**
|
||||
* 获取所有设置选项
|
||||
* @return map
|
||||
*/
|
||||
Map<String,String> findAllOptions();
|
||||
|
||||
/**
|
||||
* 根据key查询单个设置
|
||||
* @param key key
|
||||
* @return String
|
||||
*/
|
||||
String findOneOption(String key);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
/**
|
||||
* @className: PostMetaService
|
||||
* @author: RYAN0UP
|
||||
* @date: 2017/11/14
|
||||
* @description:
|
||||
*/
|
||||
public interface PostMetaService {
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.Archive;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description :
|
||||
*/
|
||||
public interface PostService {
|
||||
/**
|
||||
* 新增文章
|
||||
* @param post Post
|
||||
* @return Post
|
||||
*/
|
||||
Post saveByPost(Post post);
|
||||
|
||||
/**
|
||||
* 根据编号删除文章
|
||||
* @param postId postId
|
||||
* @return Post
|
||||
*/
|
||||
Post removeByPostId(Integer postId);
|
||||
|
||||
/**
|
||||
* 修改文章
|
||||
* @param post Post
|
||||
* @return Post
|
||||
*/
|
||||
Post updateByPost(Post post);
|
||||
|
||||
/**
|
||||
* 修改文章状态
|
||||
* @param postId postId
|
||||
* @param status status
|
||||
* @return Post
|
||||
*/
|
||||
Post updatePostStatus(Integer postId,Integer status);
|
||||
|
||||
/**
|
||||
* 批量修改摘要
|
||||
* @param postSummary postSummary
|
||||
*/
|
||||
void updateAllSummary(Integer postSummary);
|
||||
|
||||
/**
|
||||
* 获取文章列表 分页
|
||||
* @param pageable Pageable
|
||||
* @return Page
|
||||
*/
|
||||
Page<Post> findAllPosts(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 获取文章列表 不分页
|
||||
* @return List
|
||||
*/
|
||||
List<Post> findAllPosts();
|
||||
|
||||
/**
|
||||
* 模糊查询文章
|
||||
* @return list
|
||||
*/
|
||||
List<Post> searchPosts(String keyWord,Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据文章状态查询 分页
|
||||
* @param status status
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
Page<Post> findPostByStatus(Integer status,Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据文章状态查询
|
||||
* @param status status
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findPostByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 根据编号查询文章
|
||||
* @param postId postId
|
||||
* @return Post
|
||||
*/
|
||||
Post findByPostId(Integer postId);
|
||||
|
||||
/**
|
||||
* 根据文章路径查询
|
||||
* @param postUrl postUrl
|
||||
* @return post
|
||||
*/
|
||||
Post findByPostUrl(String postUrl);
|
||||
|
||||
/**
|
||||
* 查询前五条数据
|
||||
* @return List
|
||||
*/
|
||||
List<Post> findPostLatest();
|
||||
|
||||
/**
|
||||
* 查询Id之后的文章
|
||||
* @param postDate postDate
|
||||
* @return post
|
||||
*/
|
||||
List<Post> findByPostDateAfter(Date postDate);
|
||||
|
||||
/**
|
||||
* 查询Id之前的文章
|
||||
* @param postDate postDate
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findByPostDateBefore(Date postDate);
|
||||
|
||||
/**
|
||||
* 查询归档信息
|
||||
* @return List
|
||||
*/
|
||||
List<Archive> findPostGroupByPostDate();
|
||||
|
||||
/**
|
||||
* 根据年份和月份查询文章
|
||||
* @param year year
|
||||
* @param month month
|
||||
* @return list
|
||||
*/
|
||||
List<Post> findPostByYearAndMonth(String year,String month);
|
||||
|
||||
Page<Post> findPostByYearAndMonth(@Param("year") String year, @Param("month") String month, Pageable pageable);
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Tag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/1/12
|
||||
* description :
|
||||
*/
|
||||
public interface TagService {
|
||||
|
||||
/**
|
||||
* 新增标签
|
||||
* @param tag tag
|
||||
* @return Tag
|
||||
*/
|
||||
Tag saveByTag(Tag tag);
|
||||
|
||||
/**
|
||||
* 根据编号移除标签
|
||||
* @param tagId tagId
|
||||
* @return Tag
|
||||
*/
|
||||
Tag removeByTagId(Integer tagId);
|
||||
|
||||
/**
|
||||
* 更新标签
|
||||
* @param tag tag
|
||||
* @return tag
|
||||
*/
|
||||
Tag updateByTag(Tag tag);
|
||||
|
||||
/**
|
||||
* 获取所有标签
|
||||
* @return list
|
||||
*/
|
||||
List<Tag> findAllTags();
|
||||
|
||||
/**
|
||||
* 根据编号查询标签
|
||||
* @param tagId tagId
|
||||
* @return Link
|
||||
*/
|
||||
Tag findByTagId(Integer tagId);
|
||||
|
||||
/**
|
||||
* 根据标签路径查询
|
||||
* @param tagUrl tagUrl
|
||||
* @return tag
|
||||
*/
|
||||
Tag findByTagUrl(String tagUrl);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.UserMeta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
public interface UserMetaService {
|
||||
|
||||
/**
|
||||
* 保存单个用户附加信息
|
||||
* @param userMeta userMeta
|
||||
*/
|
||||
void saveByUserMeta(UserMeta userMeta);
|
||||
|
||||
/**
|
||||
* 批量保存用户附加信息
|
||||
* @param userMetas userMeta
|
||||
*/
|
||||
void saveByUserMetas(List<UserMeta> userMetas);
|
||||
|
||||
/**
|
||||
* 根据userMetaKey来查询,主要用于判断重复
|
||||
* @param key key
|
||||
* @return userMeta
|
||||
*/
|
||||
UserMeta findByUserMetaKey(String key);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package cc.ryanc.halo.service;
|
||||
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
public interface UserService {
|
||||
/**
|
||||
* 保存个人资料
|
||||
* @param user user
|
||||
*/
|
||||
void saveByUser(User user);
|
||||
|
||||
/**
|
||||
* 根据用户名和密码查询,用于登录
|
||||
* @param userName userName
|
||||
* @param userPass userPass
|
||||
* @return User
|
||||
*/
|
||||
User userLogin(String userName,String userPass);
|
||||
/**
|
||||
* 查询所有用户
|
||||
* @return list
|
||||
*/
|
||||
List<User> findAllUser();
|
||||
|
||||
/**
|
||||
* 根据用户编号和密码查询
|
||||
* @param userId userid
|
||||
* @param userPass userpass
|
||||
* @return user
|
||||
*/
|
||||
User findByUserIdAndUserPass(Integer userId,String userPass);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import cc.ryanc.halo.repository.AttachmentRepository;
|
||||
import cc.ryanc.halo.service.AttachmentService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/10
|
||||
*/
|
||||
@Service
|
||||
public class AttachmentServiceImpl implements AttachmentService{
|
||||
|
||||
@Autowired
|
||||
private AttachmentRepository attachmentRepository;
|
||||
|
||||
/**
|
||||
* 新增附件信息
|
||||
* @param attachment attachment
|
||||
* @return Attachment
|
||||
*/
|
||||
@Override
|
||||
public Attachment saveByAttachment(Attachment attachment) {
|
||||
return attachmentRepository.save(attachment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Attachment> findAllAttachments() {
|
||||
return attachmentRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Attachment> findAllAttachments(Pageable pageable) {
|
||||
return attachmentRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment findByAttachId(Integer attachId) {
|
||||
return attachmentRepository.findOne(attachId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment removeByAttachId(Integer attachId) {
|
||||
Attachment attachment = this.findByAttachId(attachId);
|
||||
attachmentRepository.delete(attachment);
|
||||
return attachment;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import cc.ryanc.halo.repository.CategoryRepository;
|
||||
import cc.ryanc.halo.service.CategoryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/30
|
||||
* @version : 1.0
|
||||
* description: Category业务层实现
|
||||
*/
|
||||
@Service
|
||||
public class CategoryServiceImpl implements CategoryService{
|
||||
|
||||
@Autowired
|
||||
private CategoryRepository categoryRepository;
|
||||
|
||||
private static final String CATEGORY_KEY = "'category_key'";
|
||||
|
||||
private static final String CATEGORY_CACHE_NAME = "inkCache";
|
||||
|
||||
/**
|
||||
* 保存分类目录 清除缓存
|
||||
* @param category 分类目录
|
||||
* @return ategory
|
||||
*/
|
||||
@CacheEvict(value = CATEGORY_CACHE_NAME,key = CATEGORY_KEY)
|
||||
@Override
|
||||
public Category saveByCategory(Category category) {
|
||||
return categoryRepository.save(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号移除分类目录 清除缓存
|
||||
* @param cateId 分类目录编号
|
||||
* @return Category
|
||||
*/
|
||||
@CacheEvict(value = CATEGORY_CACHE_NAME,key = CATEGORY_KEY)
|
||||
@Override
|
||||
public Category removeByCateId(Integer cateId) {
|
||||
Category category = this.findByCateId(cateId);
|
||||
categoryRepository.delete(category);
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改分类目录 缓存
|
||||
* @param category 分类目录对象
|
||||
* @return Category
|
||||
*/
|
||||
@CachePut(value = CATEGORY_CACHE_NAME,key = "#category.cateId+'cate'")
|
||||
@CacheEvict(value = CATEGORY_CACHE_NAME,key = CATEGORY_KEY)
|
||||
@Override
|
||||
public Category updateByCategory(Category category) {
|
||||
return categoryRepository.save(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有分类目录 缓存
|
||||
* @return list
|
||||
*/
|
||||
@Cacheable(value = CATEGORY_CACHE_NAME,key = CATEGORY_KEY)
|
||||
@Override
|
||||
public List<Category> findAllCategories() {
|
||||
return categoryRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号查询分类目录 缓存
|
||||
* @param cateId 分类编号
|
||||
* @return Category
|
||||
*/
|
||||
@Cacheable(value = CATEGORY_CACHE_NAME,key = "#cateId+'cate'")
|
||||
@Override
|
||||
public Category findByCateId(Integer cateId) {
|
||||
return categoryRepository.findOne(cateId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类目录路径查询,用于验证是否已经存在该路径
|
||||
*
|
||||
* @param cateUrl cateUrl
|
||||
* @return category
|
||||
*/
|
||||
@Override
|
||||
public Category findByCateUrl(String cateUrl) {
|
||||
return categoryRepository.findCategoryByCateUrl(cateUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Category> strListToCateList(List<String> strings) {
|
||||
if(null==strings){
|
||||
return null;
|
||||
}
|
||||
List<Category> categories = new ArrayList<>();
|
||||
Category category = null;
|
||||
for(String str:strings){
|
||||
category = findByCateId(Integer.parseInt(str));
|
||||
categories.add(category);
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
import cc.ryanc.halo.repository.LinkRepository;
|
||||
import cc.ryanc.halo.service.LinkService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @className: LinkServiceImpl
|
||||
* @author: RYAN0UP
|
||||
* @date: 2017/11/14
|
||||
* @description:
|
||||
*/
|
||||
@Service
|
||||
public class LinkServiceImpl implements LinkService {
|
||||
|
||||
@Autowired
|
||||
private LinkRepository linkRepository;
|
||||
|
||||
private static final String LINK_KEY = "'link_key'";
|
||||
|
||||
private static final String LINK_CACHE_NAME = "inkCache";
|
||||
|
||||
/**
|
||||
* 保存友情链接 清除缓存
|
||||
* @param link link
|
||||
* @return Link
|
||||
*/
|
||||
@CacheEvict(value = LINK_CACHE_NAME,key = LINK_KEY)
|
||||
@Override
|
||||
public Link saveByLink(Link link) {
|
||||
return linkRepository.save(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除友情链接 清除缓存
|
||||
* @param linkId linkId
|
||||
* @return link
|
||||
*/
|
||||
@CacheEvict(value = LINK_CACHE_NAME,key = LINK_KEY)
|
||||
@Override
|
||||
public Link removeByLinkId(Integer linkId) {
|
||||
Link link = this.findByLinkId(linkId);
|
||||
linkRepository.delete(link);
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改友情链接 清除缓存
|
||||
* @param link link
|
||||
* @return Link
|
||||
*/
|
||||
@CachePut(value = LINK_CACHE_NAME,key = "#link.linkId+'link'")
|
||||
@CacheEvict(value = LINK_CACHE_NAME,key = LINK_KEY)
|
||||
@Override
|
||||
public Link updateByLink(Link link) {
|
||||
return linkRepository.save(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有友情链接 缓存
|
||||
* @return list
|
||||
*/
|
||||
@Cacheable(value = LINK_CACHE_NAME,key = LINK_KEY)
|
||||
@Override
|
||||
public List<Link> findAllLinks() {
|
||||
return linkRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号查询友情链接 缓存
|
||||
* @param linkId linkId
|
||||
* @return Link
|
||||
*/
|
||||
@Cacheable(value = LINK_CACHE_NAME,key = "#linkId+'link'")
|
||||
@Override
|
||||
public Link findByLinkId(Integer linkId) {
|
||||
return linkRepository.findOne(linkId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Logs;
|
||||
import cc.ryanc.halo.repository.LogsRepository;
|
||||
import cc.ryanc.halo.service.LogsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/19
|
||||
*/
|
||||
@Service
|
||||
public class LogsServiceImpl implements LogsService {
|
||||
|
||||
@Autowired
|
||||
private LogsRepository logsRepository;
|
||||
|
||||
/**
|
||||
* 保存日志
|
||||
*
|
||||
* @param logs logs
|
||||
* @return logs
|
||||
*/
|
||||
@Override
|
||||
public Logs saveByLogs(Logs logs) {
|
||||
return logsRepository.save(logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号移除
|
||||
*
|
||||
* @param logsId logsId
|
||||
* @return Logs
|
||||
*/
|
||||
@Override
|
||||
public void removeByLogsId(Integer logsId) {
|
||||
Logs logs = this.findLogsByLogsId(logsId);
|
||||
logsRepository.delete(logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除所有日志
|
||||
*/
|
||||
@Override
|
||||
public void removeAllLogs() {
|
||||
logsRepository.deleteAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有日志并分页
|
||||
*
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
@Override
|
||||
public Page<Logs> findAllLogs(Pageable pageable) {
|
||||
return logsRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最新的五条日志
|
||||
*
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Logs> findLogsLatest() {
|
||||
return logsRepository.findTopFive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号查询
|
||||
*
|
||||
* @param logsId logsId
|
||||
* @return logs
|
||||
*/
|
||||
@Override
|
||||
public Logs findLogsByLogsId(Integer logsId) {
|
||||
return logsRepository.findOne(logsId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Options;
|
||||
import cc.ryanc.halo.repository.OptionsRepository;
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
@Service
|
||||
public class OptionsServiceImpl implements OptionsService {
|
||||
|
||||
@Autowired
|
||||
private OptionsRepository optionsRepository;
|
||||
|
||||
private static final String OPTIONS_KEY = "'options_key'";
|
||||
|
||||
private static final String OPTIONS_CACHE_NAME = "options_cache";
|
||||
|
||||
/**
|
||||
* 批量保存设置
|
||||
* @param options options
|
||||
*/
|
||||
@CacheEvict(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
|
||||
@Override
|
||||
public void saveOptions(Map<String,String> options){
|
||||
if(null != options && !options.isEmpty()){
|
||||
options.forEach((k,v) -> saveOption(k,v));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存单个设置选项
|
||||
* @param key key
|
||||
* @param value value
|
||||
*/
|
||||
@CacheEvict(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
|
||||
@Override
|
||||
public void saveOption(String key,String value){
|
||||
Options options = null;
|
||||
if("".equals(value)){
|
||||
options = new Options();
|
||||
options.setOptionName(key);
|
||||
this.removeOption(options);
|
||||
}else {
|
||||
if (HaloUtil.isNotNull(key)) {
|
||||
//如果查询到有该设置选项则做更新操作,反之保存新的设置选项
|
||||
if (null == optionsRepository.findOptionsByOptionName(key)) {
|
||||
options = new Options();
|
||||
options.setOptionName(key);
|
||||
options.setOptionValue(value);
|
||||
optionsRepository.save(options);
|
||||
} else {
|
||||
options = optionsRepository.findOptionsByOptionName(key);
|
||||
options.setOptionValue(value);
|
||||
optionsRepository.save(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除设置项
|
||||
* @param options options
|
||||
*/
|
||||
@CacheEvict(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
|
||||
@Override
|
||||
public void removeOption(Options options) {
|
||||
optionsRepository.delete(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设置选项
|
||||
* @return map
|
||||
*/
|
||||
@Cacheable(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
|
||||
@Override
|
||||
public Map<String, String> findAllOptions() {
|
||||
Map<String,String> options = new HashMap<String,String>();
|
||||
List<Options> optionsList = optionsRepository.findAll();
|
||||
if(null != optionsList){
|
||||
optionsList.forEach(option -> options.put(option.getOptionName(),option.getOptionValue()));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key查询单个设置选项
|
||||
* @param key key
|
||||
* @return String
|
||||
*/
|
||||
@Cacheable(value = OPTIONS_CACHE_NAME,key = "#key+'options'")
|
||||
@Override
|
||||
public String findOneOption(String key) {
|
||||
Options options = optionsRepository.findOptionsByOptionName(key);
|
||||
if(null!=options){
|
||||
return options.getOptionValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.service.PostMetaService;
|
||||
|
||||
/**
|
||||
* @className: PostMetaServiceImpl
|
||||
* @author: RYAN0UP
|
||||
* @date: 2017/11/14
|
||||
* @description:
|
||||
*/
|
||||
public class PostMetaServiceImpl implements PostMetaService {
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.Archive;
|
||||
import cc.ryanc.halo.repository.PostRepository;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/14
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Service
|
||||
public class PostServiceImpl implements PostService {
|
||||
|
||||
@Autowired
|
||||
private PostRepository postRepository;
|
||||
|
||||
private static final String POST_KEY = "'post_key'";
|
||||
|
||||
private static final String POST_CACHE_NAME = "inkCache";
|
||||
|
||||
/**
|
||||
* 保存文章 清除缓存
|
||||
* @param post Post
|
||||
* @return Post
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public Post saveByPost(Post post) {
|
||||
return postRepository.save(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号移除文章 清除缓存
|
||||
* @param postId postId
|
||||
* @return Post
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public Post removeByPostId(Integer postId) {
|
||||
Post post = this.findByPostId(postId);
|
||||
postRepository.delete(post);
|
||||
return post;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改文章 清除缓存
|
||||
* @param post Post
|
||||
* @return
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public Post updateByPost(Post post) {
|
||||
return postRepository.save(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改文章状态 清除缓存
|
||||
* @param postId postId
|
||||
* @param status status
|
||||
* @return Post
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public Post updatePostStatus(Integer postId, Integer status) {
|
||||
Post post = this.findByPostId(postId);
|
||||
post.setPostStatus(status);
|
||||
return postRepository.save(post);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新文章摘要
|
||||
* @param postSummary postSummary
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public void updateAllSummary(Integer postSummary) {
|
||||
List<Post> posts = this.findAllPosts();
|
||||
for(Post post:posts){
|
||||
if(!(HaloUtil.htmlToText(post.getPostContent()).length()<postSummary)){
|
||||
post.setPostSummary(HaloUtil.getSummary(post.getPostContent(),postSummary));
|
||||
postRepository.save(post);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有文章 分页
|
||||
* @param pageable Pageable
|
||||
* @return Page
|
||||
*/
|
||||
@Override
|
||||
public Page<Post> findAllPosts(Pageable pageable) {
|
||||
return postRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有文章 不分页 缓存
|
||||
* @return List
|
||||
*/
|
||||
@Cacheable(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public List<Post> findAllPosts() {
|
||||
return postRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊查询文章
|
||||
* @param keyWord keyword
|
||||
* @param pageable pageable
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Post> searchPosts(String keyWord,Pageable pageable) {
|
||||
return postRepository.findByPostTitleLike(keyWord,pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态分页查询文章 清除缓存
|
||||
* @param status status
|
||||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
|
||||
@Override
|
||||
public Page<Post> findPostByStatus(Integer status, Pageable pageable) {
|
||||
return postRepository.findPostsByPostStatus(status,pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态查询文章
|
||||
* @param status status
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Post> findPostByStatus(Integer status) {
|
||||
return postRepository.findPostsByPostStatus(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号查询文章 缓存
|
||||
* @param postId postId
|
||||
* @return post
|
||||
*/
|
||||
@Cacheable(value = POST_CACHE_NAME,key = "#postId+'post'")
|
||||
@Override
|
||||
public Post findByPostId(Integer postId) {
|
||||
return postRepository.findOne(postId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文章路径查询 缓存
|
||||
* @param postUrl postUrl
|
||||
* @return post
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(value = POST_CACHE_NAME,key = "#postUrl+'post'")
|
||||
public Post findByPostUrl(String postUrl) {
|
||||
return postRepository.findPostByPostUrl(postUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最新的5篇文章
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Post> findPostLatest() {
|
||||
return postRepository.findTopFive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询Id之后的文章
|
||||
*
|
||||
* @param postId postId
|
||||
* @return post
|
||||
*/
|
||||
@Override
|
||||
public List<Post> findByPostDateAfter(Date postDate) {
|
||||
return postRepository.findByPostDateAfterAndPostStatusOrderByPostDateDesc(postDate,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询Id之前的文章
|
||||
*
|
||||
* @param postId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Post> findByPostDateBefore(Date postDate) {
|
||||
return postRepository.findByPostDateBeforeAndPostStatusOrderByPostDateAsc(postDate,0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询归档信息
|
||||
*
|
||||
* @return List
|
||||
*/
|
||||
@Override
|
||||
public List<Archive> findPostGroupByPostDate() {
|
||||
List<Object[]> objects = postRepository.findPostGroupByDate();
|
||||
List<Archive> archives = new ArrayList<>();
|
||||
Archive archive = null;
|
||||
for(Object[] obj : objects){
|
||||
archive = new Archive();
|
||||
archive.setYear(obj[0].toString());
|
||||
archive.setMonth(obj[1].toString());
|
||||
archive.setCount(obj[2].toString());
|
||||
archive.setPosts(this.findPostByYearAndMonth(obj[0].toString(),obj[1].toString()));
|
||||
archives.add(archive);
|
||||
}
|
||||
return archives;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据年份和月份查询文章
|
||||
* @param year year
|
||||
* @param month month
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Post> findPostByYearAndMonth(String year, String month) {
|
||||
return postRepository.findPostByYearAndMonth(year,month);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Post> findPostByYearAndMonth(String year, String month, Pageable pageable) {
|
||||
return postRepository.findPostByYearAndMonth(year,month,pageable);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Tag;
|
||||
import cc.ryanc.halo.repository.TagRepository;
|
||||
import cc.ryanc.halo.service.TagService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/1/12
|
||||
* description :
|
||||
*/
|
||||
@Service
|
||||
public class TagServiceImpl implements TagService {
|
||||
|
||||
@Autowired
|
||||
private TagRepository tagRepository;
|
||||
|
||||
/**
|
||||
* 新增标签
|
||||
*
|
||||
* @param tag tag
|
||||
* @return Tag
|
||||
*/
|
||||
@Override
|
||||
public Tag saveByTag(Tag tag) {
|
||||
return tagRepository.save(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号移除标签
|
||||
*
|
||||
* @param tagId tagId
|
||||
* @return Tag
|
||||
*/
|
||||
@Override
|
||||
public Tag removeByTagId(Integer tagId) {
|
||||
Tag tag = findByTagId(tagId);
|
||||
tagRepository.delete(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新标签
|
||||
*
|
||||
* @param tag tag
|
||||
* @return tag
|
||||
*/
|
||||
@Override
|
||||
public Tag updateByTag(Tag tag) {
|
||||
return tagRepository.save(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有标签
|
||||
*
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Tag> findAllTags() {
|
||||
return tagRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编号查询标签
|
||||
*
|
||||
* @param tagId tagId
|
||||
* @return Link
|
||||
*/
|
||||
@Override
|
||||
public Tag findByTagId(Integer tagId) {
|
||||
return tagRepository.findOne(tagId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据标签路径查询
|
||||
*
|
||||
* @param tagUrl tagUrl
|
||||
* @return tag
|
||||
*/
|
||||
@Override
|
||||
public Tag findByTagUrl(String tagUrl) {
|
||||
return tagRepository.findTagByTagUrl(tagUrl);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.UserMeta;
|
||||
import cc.ryanc.halo.repository.UserMetaRepository;
|
||||
import cc.ryanc.halo.service.UserMetaService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
@Service
|
||||
public class UserMetaServiceImpl implements UserMetaService {
|
||||
|
||||
@Autowired
|
||||
private UserMetaRepository userMetaRepository;
|
||||
|
||||
@Override
|
||||
public void saveByUserMeta(UserMeta userMeta) {
|
||||
if(null==this.findByUserMetaKey(userMeta.getUserMetaKey())){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveByUserMetas(List<UserMeta> userMetas) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key值查找
|
||||
* @param key key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserMeta findByUserMetaKey(String key) {
|
||||
return userMetaRepository.findByUserMetaKey(key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package cc.ryanc.halo.service.impl;
|
||||
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.repository.UserRepository;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2017/11/14
|
||||
* description:
|
||||
*/
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
/**
|
||||
* 保存个人资料
|
||||
* @param user user
|
||||
*/
|
||||
@Override
|
||||
public void saveByUser(User user) {
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户名和密码查询
|
||||
* @param userName userName
|
||||
* @param userPass userPass
|
||||
* @return user
|
||||
*/
|
||||
@Override
|
||||
public User userLogin(String userName, String userPass) {
|
||||
return userRepository.findByUserNameAndUserPass(userName,userPass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<User> findAllUser() {
|
||||
return userRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证修改密码时,密码是否正确
|
||||
* @param userId userid
|
||||
* @param userPass userpass
|
||||
* @return User
|
||||
*/
|
||||
@Override
|
||||
public User findByUserIdAndUserPass(Integer userId, String userPass) {
|
||||
return userRepository.findByUserIdAndUserPass(userId,userPass);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,449 @@
|
|||
package cc.ryanc.halo.util;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import com.sun.syndication.feed.rss.Channel;
|
||||
import com.sun.syndication.feed.rss.Content;
|
||||
import com.sun.syndication.feed.rss.Item;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.WireFeedOutput;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/22
|
||||
* @version : 1.0
|
||||
* description:常用的方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class HaloUtil {
|
||||
|
||||
private final static Calendar NOW = Calendar.getInstance();
|
||||
|
||||
public final static String YEAR = NOW.get(Calendar.YEAR)+"";
|
||||
|
||||
public final static String MONTH = (NOW.get(Calendar.MONTH)+1)+"";
|
||||
|
||||
private static ArrayList<String> FILE_LIST = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 验证字符串是否为空
|
||||
* @param str str
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isNotNull(String str){
|
||||
return null !=str && ! "".equals(str.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压Zip文件
|
||||
* @param zipFilePath 压缩文件的路径
|
||||
* @param descDir 解压的路径
|
||||
*/
|
||||
public static void unZip(String zipFilePath,String descDir){
|
||||
File zipFile=new File(zipFilePath);
|
||||
File pathFile=new File(descDir);
|
||||
if(!pathFile.exists()){
|
||||
pathFile.mkdirs();
|
||||
}
|
||||
ZipFile zip=null;
|
||||
InputStream in=null;
|
||||
OutputStream out=null;
|
||||
try {
|
||||
zip=new ZipFile(zipFile);
|
||||
Enumeration<?> entries=zip.entries();
|
||||
while(entries.hasMoreElements()){
|
||||
ZipEntry entry=(ZipEntry) entries.nextElement();
|
||||
String zipEntryName=entry.getName();
|
||||
in=zip.getInputStream(entry);
|
||||
|
||||
String outPath=(descDir+"/"+zipEntryName).replace("\\*", "/");
|
||||
File file=new File(outPath.substring(0, outPath.lastIndexOf('/')));
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
}
|
||||
if(new File(outPath).isDirectory()){
|
||||
continue;
|
||||
}
|
||||
out=new FileOutputStream(outPath);
|
||||
byte[] buf=new byte[4*1024];
|
||||
int len;
|
||||
while((len=in.read(buf))>=0){
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解压失败:"+e.getMessage());
|
||||
}finally{
|
||||
try {
|
||||
if(zip!=null)
|
||||
zip.close();
|
||||
if(in!=null)
|
||||
in.close();
|
||||
if(out!=null)
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void zipFolder(String folder,String outPutFile){
|
||||
ZipOutputStream zip = null;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(outPutFile);
|
||||
zip = new ZipOutputStream(fileOutputStream);
|
||||
addFolderToZip("", folder, zip);
|
||||
zip.flush();
|
||||
zip.close();
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void addFileToZip(String path,String srcFile,ZipOutputStream zip) throws Exception{
|
||||
File folder = new File(srcFile);
|
||||
if (folder.isDirectory()) {
|
||||
addFolderToZip(path, srcFile, zip);
|
||||
} else {
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
FileInputStream in = new FileInputStream(srcFile);
|
||||
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
zip.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception {
|
||||
File folder = new File(srcFolder);
|
||||
if (null != path && folder.isDirectory()) {
|
||||
for (String fileName : folder.list()) {
|
||||
if ("".equals(path)) {
|
||||
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
|
||||
} else {
|
||||
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取图片
|
||||
* @param src 输入路径
|
||||
* @param dest 输出路径
|
||||
* @param w 宽度
|
||||
* @param h 长度
|
||||
* @param suffix 后缀
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void cutCenterImage(String src,String dest,int w,int h,String suffix) throws IOException{
|
||||
try{
|
||||
Iterator iterator = ImageIO.getImageReadersByFormatName(suffix);
|
||||
ImageReader reader = (ImageReader)iterator.next();
|
||||
InputStream in=new FileInputStream(src);
|
||||
ImageInputStream iis = ImageIO.createImageInputStream(in);
|
||||
reader.setInput(iis, true);
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
int imageIndex = 0;
|
||||
Rectangle rect = new Rectangle((reader.getWidth(imageIndex)-w)/2, (reader.getHeight(imageIndex)-h)/2, w, h);
|
||||
param.setSourceRegion(rect);
|
||||
BufferedImage bi = reader.read(0,param);
|
||||
ImageIO.write(bi, suffix, new File(dest));
|
||||
}catch (Exception e){
|
||||
log.error("剪裁失败,图片本身尺寸小于需要修剪的尺寸:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有文件
|
||||
* @param filePath filePath
|
||||
* @return Map
|
||||
*/
|
||||
public static ArrayList<String> getFiles(String filePath){
|
||||
try{
|
||||
//获取项目根路径
|
||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
//获取目标路径
|
||||
File targetPath = new File(basePath.getAbsolutePath(),filePath);
|
||||
File[] files = targetPath.listFiles();
|
||||
//遍历文件
|
||||
for(File file:files){
|
||||
if(file.isDirectory()){
|
||||
getFiles(filePath+"/"+file.getName());
|
||||
}else{
|
||||
String abPath = file.getAbsolutePath().substring(file.getAbsolutePath().indexOf("/upload"));
|
||||
FILE_LIST.add(abPath);
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return FILE_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String getStringDate() {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String dateString = formatter.format(new Date());
|
||||
return dateString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* @return 字符串使用下划线,用于备份文件名
|
||||
*/
|
||||
public static String getStringDateWithLine(){
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
||||
String dateString = format.format(new Date());
|
||||
return dateString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* @return 日期类型
|
||||
*/
|
||||
public static Date getDate() {
|
||||
Date date = new Date();
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取html中的文字
|
||||
* @param html html
|
||||
* @return string
|
||||
*/
|
||||
public static String htmlToText(String html) {
|
||||
if (!"".equals(html)) {
|
||||
return html.replaceAll("(?s)<[^>]*>(\\s*<[^>]*>)*", "");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取文章摘要
|
||||
* @param html html
|
||||
* @param summary summary
|
||||
* @return string
|
||||
*/
|
||||
public static String getSummary(String html,Integer summary){
|
||||
return htmlToText(html).substring(0,summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密字符串
|
||||
* @param str str
|
||||
* @return MD5
|
||||
*/
|
||||
public static String getMD5(String str) {
|
||||
String md5 = "";
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageByte = str.getBytes("UTF-8");
|
||||
byte[] md5Byte = md.digest(messageByte);
|
||||
md5 = bytesToHex(md5Byte);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* 2进制转16进制
|
||||
* @param bytes bytes
|
||||
* @return string
|
||||
*/
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuffer hexStr = new StringBuffer();
|
||||
int num;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
num = bytes[i];
|
||||
if(num < 0) {
|
||||
num += 256;
|
||||
}
|
||||
if(num < 16){
|
||||
hexStr.append("0");
|
||||
}
|
||||
hexStr.append(Integer.toHexString(num));
|
||||
}
|
||||
return hexStr.toString().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端ip地址
|
||||
* @param request request
|
||||
* @return string
|
||||
*/
|
||||
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 ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据库
|
||||
* @param hostIp ip
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @param savePath 保存路径
|
||||
* @param fileName 文件名
|
||||
* @param databaseName 数据库名
|
||||
* @return boolean
|
||||
* @throws InterruptedException InterruptedException
|
||||
*/
|
||||
public static boolean exportDatabase(String hostIp,String userName,String password,String savePath,String fileName,String databaseName) throws InterruptedException{
|
||||
File saveFile = new File(savePath);
|
||||
if(!saveFile.exists()){
|
||||
saveFile.mkdirs();
|
||||
}
|
||||
if(!savePath.endsWith(File.separator)){
|
||||
savePath = savePath+File.separator;
|
||||
}
|
||||
|
||||
PrintWriter printWriter = null;
|
||||
BufferedReader bufferedReader = null;
|
||||
try{
|
||||
printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(savePath+fileName),"utf-8"));
|
||||
Process process = Runtime.getRuntime().exec(" mysqldump -h" + hostIp + " -u" + userName + " -p" + password + " --set-charset=UTF8 " + databaseName);
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(),"utf-8");
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
String line;
|
||||
while((line = bufferedReader.readLine())!=null){
|
||||
printWriter.println(line);
|
||||
}
|
||||
printWriter.flush();
|
||||
if(process.waitFor()==0){
|
||||
return true;
|
||||
}
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
try{
|
||||
if(bufferedReader != null){
|
||||
bufferedReader.close();
|
||||
}
|
||||
if(printWriter!=null){
|
||||
printWriter.close();
|
||||
}
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void dbToFile(String data,String filePath,String fileName){
|
||||
try{
|
||||
File file =new File(filePath);
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
}
|
||||
//true = append file
|
||||
FileWriter fileWritter = new FileWriter(file.getAbsoluteFile()+"/"+fileName,true);
|
||||
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
|
||||
bufferWritter.write(data);
|
||||
bufferWritter.close();
|
||||
System.out.println("Done");
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成rss
|
||||
* @param posts posts
|
||||
* @return string
|
||||
* @throws FeedException
|
||||
*/
|
||||
public static String getRss(List<Post> posts) throws FeedException {
|
||||
Channel channel = new Channel("rss_2.0");
|
||||
if(null==HaloConst.OPTIONS.get("site_title")){
|
||||
channel.setTitle("");
|
||||
}else{
|
||||
channel.setTitle(HaloConst.OPTIONS.get("site_title"));
|
||||
}
|
||||
if(null==HaloConst.OPTIONS.get("site_url")){
|
||||
channel.setLink("");
|
||||
}else {
|
||||
channel.setLink(HaloConst.OPTIONS.get("site_url"));
|
||||
}
|
||||
if(null==HaloConst.OPTIONS.get("seo_desc")){
|
||||
channel.setDescription("");
|
||||
}else{
|
||||
channel.setDescription(HaloConst.OPTIONS.get("seo_desc"));
|
||||
}
|
||||
channel.setLanguage("zh-CN");
|
||||
List<Item> items = new ArrayList<>();
|
||||
for(Post post : posts){
|
||||
Item item = new Item();
|
||||
item.setTitle(post.getPostTitle());
|
||||
Content content = new Content();
|
||||
String value = post.getPostContent();
|
||||
char[] xmlChar = value.toCharArray();
|
||||
for (int i = 0; i < xmlChar.length; ++i) {
|
||||
if (xmlChar[i] > 0xFFFD) {
|
||||
xmlChar[i] = ' ';
|
||||
} else if (xmlChar[i] < 0x20 && xmlChar[i] != 't' & xmlChar[i] != 'n' & xmlChar[i] != 'r') {
|
||||
xmlChar[i] = ' ';
|
||||
}
|
||||
}
|
||||
value = new String(xmlChar);
|
||||
content.setValue(value);
|
||||
item.setContent(content);
|
||||
item.setLink(HaloConst.OPTIONS.get("site_url")+"/article/"+post.getPostUrl());
|
||||
item.setPubDate(post.getPostDate());
|
||||
items.add(item);
|
||||
}
|
||||
channel.setItems(items);
|
||||
WireFeedOutput out = new WireFeedOutput();
|
||||
return out.outputString(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sitemap
|
||||
* @param posts posts
|
||||
* @return string
|
||||
*/
|
||||
public static String getSiteMap(List<Post> posts){
|
||||
String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
|
||||
String urlBody="";
|
||||
String urlItem;
|
||||
String urlPath = HaloConst.OPTIONS.get("site_url")+"/article/";
|
||||
for(Post post:posts){
|
||||
urlItem = "<url><loc>"+urlPath+post.getPostUrl()+"</loc><lastmod>"+post.getPostDate()+"</lastmod>"+"</url>";
|
||||
urlBody+=urlItem;
|
||||
}
|
||||
return head+urlBody+"</urlset>";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package cc.ryanc.halo.web.controller;
|
||||
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/15
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
public abstract class BaseController {
|
||||
|
||||
/**
|
||||
* 定义默认主题
|
||||
*/
|
||||
public static String THEME = "halo";
|
||||
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
/**
|
||||
* 渲染页面
|
||||
* @param pageName pageName
|
||||
* @return 返回拼接好的模板路径
|
||||
*/
|
||||
public String render(String pageName){
|
||||
return "themes/"+THEME+"/"+pageName;
|
||||
}
|
||||
|
||||
protected void getNewComments(HttpSession session){
|
||||
session.setAttribute("postTopFive",postService.findPostLatest());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package cc.ryanc.halo.web.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.web.ErrorController;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/26
|
||||
* @version: 1.0
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
public class CommonController implements ErrorController{
|
||||
|
||||
private static final String ERROR_PATH = "/error";
|
||||
|
||||
@GetMapping(value = ERROR_PATH)
|
||||
public String handleError(HttpServletRequest request){
|
||||
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
|
||||
if(statusCode==404) {
|
||||
return "common/404";
|
||||
}else{
|
||||
return "common/500";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path of the error page.
|
||||
*
|
||||
* @return the error path
|
||||
*/
|
||||
@Override
|
||||
public String getErrorPath() {
|
||||
return ERROR_PATH;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,365 @@
|
|||
package cc.ryanc.halo.web.controller;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.domain.Tag;
|
||||
import cc.ryanc.halo.model.dto.Archive;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.service.CategoryService;
|
||||
import cc.ryanc.halo.service.LinkService;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.service.TagService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.coyote.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/11/23
|
||||
* @version : 1.0
|
||||
* description : 首页控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = {"/","index"})
|
||||
public class IndexController extends BaseController{
|
||||
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
@Autowired
|
||||
private LinkService linkService;
|
||||
|
||||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
|
||||
@Autowired
|
||||
private TagService tagService;
|
||||
|
||||
|
||||
/**
|
||||
* 请求首页
|
||||
* @param model model
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping
|
||||
public String index(Model model){
|
||||
//调用方法渲染首页
|
||||
return this.index(model,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页分页
|
||||
* @param model model
|
||||
* @param page page
|
||||
* @param size size
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = "page/{page}")
|
||||
public String index(Model model,
|
||||
@PathVariable(value = "page") Integer page){
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postDate");
|
||||
//默认显示10条
|
||||
Integer size = 10;
|
||||
//尝试加载设置选项,用于设置显示条数
|
||||
if(HaloUtil.isNotNull(HaloConst.OPTIONS.get("index_posts"))){
|
||||
size = Integer.parseInt(HaloConst.OPTIONS.get("index_posts"));
|
||||
}
|
||||
|
||||
//所有文章数据,分页
|
||||
Pageable pageable = new PageRequest(page-1,size,sort);
|
||||
Page<Post> posts = postService.findPostByStatus(0,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
|
||||
//用户信息
|
||||
model.addAttribute("user",HaloConst.USER);
|
||||
|
||||
//所有分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
|
||||
//归档数据,包含[year,month,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByPostDate();
|
||||
model.addAttribute("archives",archives);
|
||||
return this.render("index");
|
||||
}
|
||||
|
||||
/**
|
||||
* ajax分页
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "next")
|
||||
@ResponseBody
|
||||
public List<Post> ajaxIndex(@PathParam(value = "page") Integer page){
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postDate");
|
||||
//默认显示10条
|
||||
Integer size = 10;
|
||||
//尝试加载设置选项,用于设置显示条数
|
||||
if(HaloUtil.isNotNull(HaloConst.OPTIONS.get("index_posts"))){
|
||||
size = Integer.parseInt(HaloConst.OPTIONS.get("index_posts"));
|
||||
}
|
||||
|
||||
//文章数据,只获取文章,没有分页
|
||||
Pageable pageable = new PageRequest(page-1,size,sort);
|
||||
List<Post> posts = postService.findPostByStatus(0,pageable).getContent();
|
||||
return posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染文章详情
|
||||
* @param postId postId
|
||||
* @param model model
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = {"archives/{postUrl}","post/{postUrl}","article/{postUrl}"})
|
||||
public String getPost(@PathVariable String postUrl, Model model){
|
||||
Post post = postService.findByPostUrl(postUrl);
|
||||
//获得当前文章的发布日期
|
||||
Date postDate = post.getPostDate();
|
||||
try {
|
||||
//查询当前文章日期之前的所有文章
|
||||
List<Post> beforePosts = postService.findByPostDateBefore(postDate);
|
||||
|
||||
//查询当前文章日期之后的所有文章
|
||||
List<Post> afterPosts = postService.findByPostDateAfter(postDate);
|
||||
|
||||
if(null!=beforePosts&&beforePosts.size()>0){
|
||||
model.addAttribute("beforePost",beforePosts.get(beforePosts.size()-1));
|
||||
}
|
||||
if(null!=afterPosts&&afterPosts.size()>0){
|
||||
model.addAttribute("afterPost",afterPosts.get(afterPosts.size()-1));
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
model.addAttribute("post",post);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
|
||||
//用户信息
|
||||
model.addAttribute("user",HaloConst.USER);
|
||||
|
||||
//所有分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
return this.render("post");
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染关于页面
|
||||
* @param model model
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/about")
|
||||
public String about(Model model){
|
||||
model.addAttribute("about","709831589");
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
return this.render("about");
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到图库页面
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/gallery")
|
||||
public String gallery(Model model){
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
return this.render("gallery");
|
||||
}
|
||||
|
||||
/**
|
||||
* 友情链接
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/links")
|
||||
public String links(Model model){
|
||||
|
||||
//所有友情链接
|
||||
List<Link> links = linkService.findAllLinks();
|
||||
model.addAttribute("links",links);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
|
||||
//所有分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
return this.render("links");
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签
|
||||
* @param model model
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/tags")
|
||||
public String tags(Model model){
|
||||
//所有标签
|
||||
List<Tag> tags = tagService.findAllTags();
|
||||
model.addAttribute("tags",tags);
|
||||
|
||||
//所有分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
return this.render("tags");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类路径查询文章
|
||||
* @param model model
|
||||
* @param cateUrl cateUrl
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "categories/{cateUrl}")
|
||||
public String categories(Model model,
|
||||
@PathVariable("cateUrl") String cateUrl){
|
||||
List<Post> posts;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章归档
|
||||
* @param model model
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/archives")
|
||||
public String archives(Model model){
|
||||
return this.archives(model,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章归档分页
|
||||
* @param model model
|
||||
* @param page page
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/archives/page/{page}")
|
||||
public String archives(Model model,
|
||||
@PathVariable(value = "page") Integer page){
|
||||
|
||||
//所有文章数据,分页,material主题适用
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postDate");
|
||||
Pageable pageable = new PageRequest(page-1,5,sort);
|
||||
Page<Post> posts = postService.findPostByStatus(0,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
//包含[List<Post>,year,month,count]
|
||||
List<Archive> archives = postService.findPostGroupByPostDate();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
|
||||
//用户信息
|
||||
model.addAttribute("user",HaloConst.USER);
|
||||
|
||||
//所有分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
|
||||
//是否是归档页,用于判断输出链接
|
||||
model.addAttribute("isArchives","true");
|
||||
return this.render("archives");
|
||||
}
|
||||
|
||||
/**
|
||||
* 文章归档,根据年月
|
||||
* @param model model
|
||||
* @param year year
|
||||
* @param month month
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/archives/{year}/{month}")
|
||||
public String archives(Model model,
|
||||
@PathVariable(value = "year") String year,
|
||||
@PathVariable(value = "month") String month){
|
||||
|
||||
//根据年月查出的文章数据,分页
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"post_date");
|
||||
Pageable pageable = new PageRequest(0,9999,sort);
|
||||
Page<Post> posts = postService.findPostByYearAndMonth(year,month,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
//系统设置
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
|
||||
//用户信息
|
||||
model.addAttribute("user",HaloConst.USER);
|
||||
|
||||
//分类目录
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
|
||||
//是否是归档页,用于判断输出链接
|
||||
model.addAttribute("isArchives","true");
|
||||
return this.render("archives");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文章rss
|
||||
* @return rss
|
||||
*/
|
||||
@GetMapping(value = {"feed","feed.xml","atom.xml"},produces = { "application/xml;charset=UTF-8" })
|
||||
@ResponseBody
|
||||
public String feed(){
|
||||
String rssPosts = HaloConst.OPTIONS.get("rss_posts");
|
||||
if(null==rssPosts || "".equals(rssPosts)){
|
||||
rssPosts = "20";
|
||||
}
|
||||
//获取文章列表并根据时间排序
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postDate");
|
||||
Pageable pageable = new PageRequest(0,Integer.parseInt(rssPosts),sort);
|
||||
Page<Post> postsPage = postService.findPostByStatus(0,pageable);
|
||||
List<Post> posts = postsPage.getContent();
|
||||
String rss = "";
|
||||
try {
|
||||
rss = HaloUtil.getRss(posts);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rss;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sitemap
|
||||
* @return sitemap
|
||||
*/
|
||||
@GetMapping(value = {"sitemap","sitemap.xml"},produces = { "application/xml;charset=UTF-8" })
|
||||
@ResponseBody
|
||||
public String sitemap(){
|
||||
//获取文章列表并根据时间排序
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postDate");
|
||||
Pageable pageable = new PageRequest(0,999,sort);
|
||||
Page<Post> postsPage = postService.findPostByStatus(0,pageable);
|
||||
List<Post> posts = postsPage.getContent();
|
||||
return HaloUtil.getSiteMap(posts);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Logs;
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.LogsRecord;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.LogsService;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import cc.ryanc.halo.web.controller.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
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.HttpSession;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/5
|
||||
* @version : 1.0
|
||||
* description: 后台首页控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin")
|
||||
public class AdminController extends BaseController{
|
||||
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private LogsService logsService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 请求后台页面
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = {"","/index"})
|
||||
public String index(Model model,HttpSession session){
|
||||
//查询文章条数
|
||||
Integer postCount = postService.findAllPosts().size();
|
||||
model.addAttribute("postCount",postCount);
|
||||
//查询最新的文章
|
||||
List<Post> postsLatest = postService.findPostLatest();
|
||||
model.addAttribute("postTopFive",postsLatest);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
model.addAttribute("mediaCount",HaloConst.ATTACHMENTS.size());
|
||||
List<Logs> logsLatest = logsService.findLogsLatest();
|
||||
model.addAttribute("logs",logsLatest);
|
||||
this.getNewComments(session);
|
||||
return "admin/index";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理跳转到登录页的请求
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = "/login")
|
||||
public String login(HttpSession session){
|
||||
User user = (User) session.getAttribute("user");
|
||||
//如果session存在,跳转到后台首页
|
||||
if(null!=user){
|
||||
return "redirect:/admin";
|
||||
}
|
||||
return "admin/login";
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证登录信息
|
||||
* @param loginName loginName
|
||||
* @param loginPwd loginPwd
|
||||
* @param session session
|
||||
* @return String
|
||||
*/
|
||||
@PostMapping(value = "/getLogin")
|
||||
@ResponseBody
|
||||
public String getLogin(@ModelAttribute("loginName") String loginName,
|
||||
@ModelAttribute("loginPwd") String loginPwd,
|
||||
HttpSession session){
|
||||
try {
|
||||
User user = userService.userLogin(loginName, loginPwd);
|
||||
if(null!=user){
|
||||
session.setAttribute("user",user);
|
||||
log.info("用户["+user.getUserName()+"]登录成功!");
|
||||
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_SUCCESS,HaloUtil.getIpAddr(request), HaloUtil.getDate()));
|
||||
return RespStatus.SUCCESS;
|
||||
}else{
|
||||
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_ERROR,HaloUtil.getIpAddr(request),new Date()));
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("登录失败!:"+e.getMessage());
|
||||
}
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录 销毁session
|
||||
* @param session session
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/logOut")
|
||||
public String logOut(HttpSession session){
|
||||
User user = (User) session.getAttribute("user");
|
||||
log.info("用户["+user.getUserName()+"]退出登录");
|
||||
logsService.saveByLogs(new Logs(LogsRecord.LOGOUT,user.getUserName(),HaloUtil.getIpAddr(request),HaloUtil.getDate()));
|
||||
session.invalidate();
|
||||
return "redirect:/admin/login";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看所有日志
|
||||
* @param model model
|
||||
* @param page page
|
||||
* @param size size
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/logs")
|
||||
public String logs(Model model,
|
||||
@RequestParam(value = "page",defaultValue = "0") Integer page,
|
||||
@RequestParam(value = "size",defaultValue = "10") Integer size){
|
||||
try {
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"logId");
|
||||
Pageable pageable = new PageRequest(page,size,sort);
|
||||
Page<Logs> logs = logsService.findAllLogs(pageable);
|
||||
model.addAttribute("logs",logs);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/widget/_logs-all";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/logs/clear")
|
||||
public String logsClear(){
|
||||
try {
|
||||
logsService.removeAllLogs();
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Attachment;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.AttachmentService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/19
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/attachments")
|
||||
public class AttachmentController {
|
||||
|
||||
@Autowired
|
||||
private AttachmentService attachmentService;
|
||||
/**
|
||||
* 刷新HaloConst
|
||||
*/
|
||||
private void updateConst(){
|
||||
HaloConst.ATTACHMENTS.clear();
|
||||
HaloConst.ATTACHMENTS = attachmentService.findAllAttachments();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取upload的所有图片资源并渲染页面
|
||||
* @param model model
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping
|
||||
public String attachments(Model model,
|
||||
@RequestParam(value = "page",defaultValue = "0") Integer page,
|
||||
@RequestParam(value = "size",defaultValue = "18") Integer size){
|
||||
try {
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"attachId");
|
||||
Pageable pageable = new PageRequest(page,size,sort);
|
||||
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
|
||||
model.addAttribute("attachments",attachments);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "admin/attachment";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转选择附件页面
|
||||
* @param model model
|
||||
* @param page page
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/select")
|
||||
public String selectAttachment(Model model,
|
||||
@RequestParam(value = "page",defaultValue = "0") Integer page){
|
||||
try {
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"attachId");
|
||||
Pageable pageable = new PageRequest(page,18,sort);
|
||||
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
|
||||
model.addAttribute("attachments",attachments);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "admin/widget/_attachment-select";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param file file
|
||||
*/
|
||||
@RequestMapping(value = "/upload",method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public String uploadAttachment(@RequestParam("file") MultipartFile file){
|
||||
if(!file.isEmpty()){
|
||||
try{
|
||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
File mediaPath = new File(basePath.getAbsolutePath(),"upload/"+ HaloUtil.YEAR+"/"+ HaloUtil.MONTH+"/");
|
||||
if(!mediaPath.exists()){
|
||||
mediaPath.mkdirs();
|
||||
}
|
||||
file.transferTo(new File(mediaPath.getAbsoluteFile(),file.getOriginalFilename()));
|
||||
String fileName = file.getOriginalFilename();
|
||||
String nameWithOutSuffix = fileName.substring(0,fileName.lastIndexOf('.'));
|
||||
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')+1);
|
||||
|
||||
//保存在数据库
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.setAttachName(fileName);
|
||||
attachment.setAttachPath("/upload/"+HaloUtil.YEAR+"/"+HaloUtil.MONTH+"/"+fileName);
|
||||
attachment.setAttachSmallPath("/upload/"+HaloUtil.YEAR+"/"+HaloUtil.MONTH+"/"+nameWithOutSuffix+"_small."+fileSuffix);
|
||||
attachment.setAttachType(file.getContentType());
|
||||
attachment.setAttachSuffix("."+fileSuffix);
|
||||
attachment.setAttachCreated(HaloUtil.getDate());
|
||||
attachmentService.saveByAttachment(attachment);
|
||||
|
||||
//剪裁图片
|
||||
HaloUtil.cutCenterImage(mediaPath.getAbsolutePath()+"/"+fileName,mediaPath.getAbsolutePath()+"/"+nameWithOutSuffix+"_small."+fileSuffix,500,500,fileSuffix);
|
||||
|
||||
updateConst();
|
||||
log.info("上传文件["+file.getOriginalFilename()+"]到["+mediaPath.getAbsolutePath()+"]成功");
|
||||
return RespStatus.SUCCESS;
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}else {
|
||||
log.error("文件不能为空");
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理获取附件详情的请求
|
||||
* @param attachId attachId
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/attachment")
|
||||
public String attachmentDetail(Model model,@PathParam("attachId") Integer attachId){
|
||||
Attachment attachment = attachmentService.findByAttachId(attachId);
|
||||
model.addAttribute("attachment",attachment);
|
||||
return "admin/widget/_attachment-detail";
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除附件的请求
|
||||
* @param attachId attachId
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/remove")
|
||||
@ResponseBody
|
||||
public String removeAttachment(@PathParam("attachId") Integer attachId){
|
||||
Attachment attachment = attachmentService.findByAttachId(attachId);
|
||||
String delFileName = attachment.getAttachName();
|
||||
String delSmallFileName = delFileName.substring(0,delFileName.lastIndexOf('.'))+"_small"+attachment.getAttachSuffix();
|
||||
try {
|
||||
//删除数据库中的内容
|
||||
attachmentService.removeByAttachId(attachId);
|
||||
//刷新HaloConst变量
|
||||
updateConst();
|
||||
//删除文件
|
||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
File mediaPath = new File(basePath.getAbsolutePath(),attachment.getAttachPath().substring(0,attachment.getAttachPath().lastIndexOf('/')));
|
||||
File delFile = new File(mediaPath.getAbsolutePath()+"/"+delFileName);
|
||||
File delSmallFile = new File(mediaPath.getAbsolutePath()+"/"+delSmallFileName);
|
||||
if(delFile.exists() && delFile.isFile()){
|
||||
if(delFile.delete()&&delSmallFile.delete()){
|
||||
updateConst();
|
||||
log.info("删除文件["+delFileName+"]成功!");
|
||||
}else{
|
||||
log.error("删除附件["+delFileName+"]失败!");
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("删除附件["+delFileName+"]失败!"+e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
return RespStatus.SUCCESS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* description :
|
||||
* @date : 2018/1/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/backup")
|
||||
public class BackupController {
|
||||
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
|
||||
/**
|
||||
* 渲染备份页面
|
||||
* @param model model
|
||||
* @return return
|
||||
*/
|
||||
@GetMapping
|
||||
public String backup(Model model){
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/backup";
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份数据库
|
||||
* @return return
|
||||
*/
|
||||
@GetMapping(value = "/backupDb")
|
||||
public String backupDatabase(){
|
||||
String fileName = "db_backup_"+HaloUtil.getStringDateWithLine()+".sql";
|
||||
try {
|
||||
File path = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
String savePath = path.getAbsolutePath()+"/backup/database";
|
||||
HaloUtil.exportDatabase("localhost","root","123456",savePath,fileName,"testdb");
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/backup";
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份资源文件 重要
|
||||
* @return return
|
||||
*/
|
||||
@GetMapping(value = "/backupRe")
|
||||
public String backupResources(){
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份文章,导出markdown文件
|
||||
* @return return
|
||||
*/
|
||||
@GetMapping(value = "/backupPost")
|
||||
public String backupPosts(){
|
||||
List<Post> posts = postService.findAllPosts();
|
||||
try {
|
||||
File path = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
String savePath = path.getAbsolutePath()+"/backup/posts/posts_backup_"+HaloUtil.getStringDateWithLine();
|
||||
for(Post post : posts){
|
||||
HaloUtil.dbToFile(post.getPostContentMd(),savePath,post.getPostTitle()+".md");
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "redirect:/admin/backup";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.CategoryService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.websocket.server.PathParam;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/10
|
||||
* @version : 1.0
|
||||
* description : 分类目录控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/category")
|
||||
public class CategoryController {
|
||||
|
||||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
|
||||
/**
|
||||
* 查询所有分类并渲染category页面
|
||||
* @param model model
|
||||
* @return freemarker页面
|
||||
*/
|
||||
@GetMapping
|
||||
public String categories(Model model){
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/category";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增分类目录
|
||||
* @param category category对象
|
||||
* @return freemarker页面
|
||||
*/
|
||||
@PostMapping(value = "/save")
|
||||
public String saveCategory(@ModelAttribute Category category){
|
||||
try{
|
||||
Category backCate = categoryService.saveByCategory(category);
|
||||
log.info("新添加的分类目录为:"+backCate);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/category";
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证分类目录路径是否已经存在
|
||||
* @param cateUrl cateUrl
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/checkUrl")
|
||||
@ResponseBody
|
||||
public String checkCateUrlExists(@RequestParam("cateUrl") String cateUrl){
|
||||
Category category = categoryService.findByCateUrl(cateUrl);
|
||||
if(null!=category){
|
||||
return RespStatus.EXISTS;
|
||||
}else{
|
||||
return RespStatus.NOTEXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理删除分类目录的请求
|
||||
* @param cateId cateId
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = "/remove")
|
||||
public String removeCategory(@PathParam("cateId") Integer cateId){
|
||||
try{
|
||||
Category category = categoryService.removeByCateId(cateId);
|
||||
log.info("删除的分类目录:"+category);
|
||||
} catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/category";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改分类的请求
|
||||
* @param category category
|
||||
* @return redirect
|
||||
*/
|
||||
@PostMapping(value = "/update")
|
||||
public String updateCategory(@ModelAttribute Category category){
|
||||
try{
|
||||
Category beforeCate = categoryService.findByCateId(category.getCateId());
|
||||
log.info("修改之前的数据:"+beforeCate+",修改之后的数据:"+category);
|
||||
categoryService.updateByCategory(category);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/category";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到修改页面
|
||||
* @param cateId cateId
|
||||
* @param model model
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/edit")
|
||||
public String toEditCategory(Model model,@PathParam("cateId") Integer cateId){
|
||||
try{
|
||||
Category category = categoryService.findByCateId(cateId);
|
||||
model.addAttribute("category",category);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
log.info("cateId为"+cateId+"的数据为:"+category);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/_cate-update";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.web.controller.BaseController;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/10
|
||||
* @version : 1.0
|
||||
* description : 评论系统管理
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/comment")
|
||||
public class CommentController extends BaseController{
|
||||
@GetMapping
|
||||
public String comments(Model model){
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/comment";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/13
|
||||
* @version : 1.0
|
||||
* description : 设置选项控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/admin/option")
|
||||
public class OptionController {
|
||||
|
||||
@Autowired
|
||||
private OptionsService optionsService;
|
||||
|
||||
/**
|
||||
* 请求跳转到option页面并完成渲染
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping
|
||||
public String options(Model model){
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
log.info("所有的设置选项:"+HaloConst.OPTIONS);
|
||||
return "admin/option";
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存设置选项
|
||||
* @param options options
|
||||
*/
|
||||
@PostMapping(value = "/save")
|
||||
@ResponseBody
|
||||
public String saveOptions(@RequestParam Map<String,String> options){
|
||||
try {
|
||||
optionsService.saveOptions(options);
|
||||
HaloConst.OPTIONS.clear();
|
||||
HaloConst.OPTIONS = optionsService.findAllOptions();
|
||||
log.info("所保存的设置选项列表:"+options);
|
||||
return RespStatus.SUCCESS;
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:",e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Link;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.service.LinkService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/10
|
||||
* @version : 1.0
|
||||
* description :
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/page")
|
||||
public class PageController {
|
||||
|
||||
@Autowired
|
||||
private LinkService linkService;
|
||||
|
||||
@GetMapping
|
||||
public String pages(Model model){
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/page";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理添加友链的请求并渲染页面
|
||||
* @param link Link
|
||||
* @return freemarker
|
||||
*/
|
||||
@PostMapping(value = "/links/save")
|
||||
public String saveLink(@ModelAttribute Link link){
|
||||
try{
|
||||
Link backLink = linkService.saveByLink(link);
|
||||
log.info("保存成功,数据为:"+backLink);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/page/links";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理删除友情链接的请求并重定向
|
||||
* @param linkId linkId
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/links/remove")
|
||||
public String removeLink(@PathParam("linkId") Integer linkId){
|
||||
try{
|
||||
Link link = linkService.removeByLinkId(linkId);
|
||||
log.info("删除的友情链接:"+link);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/page/links";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改的请求并重定向
|
||||
* @param link Link
|
||||
* @return freemarker
|
||||
*/
|
||||
@PostMapping(value = "/links/update")
|
||||
public String updateLink(@ModelAttribute Link link){
|
||||
try {
|
||||
Link beforeLink = linkService.findByLinkId(link.getLinkId());
|
||||
linkService.updateByLink(link);
|
||||
log.info("修改友情链接页面:修改之前的数据:"+beforeLink+",修改之后的数据:"+link);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/page/links";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取友情链接列表并渲染页面
|
||||
* @param map ModelMap
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/links")
|
||||
public String links(Model model){
|
||||
List<Link> links = linkService.findAllLinks();
|
||||
model.addAttribute("links",links);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/link";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到修改页面
|
||||
* @param model model
|
||||
* @param linkId linkId
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping("/links/edit")
|
||||
public String toEditLink(Model model,@PathParam("linkId") Integer linkId){
|
||||
Link link = linkService.findByLinkId(linkId);
|
||||
model.addAttribute("link",link);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
log.info("linkId"+linkId+"的数据为:"+link);
|
||||
return "admin/_link-update";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Category;
|
||||
import cc.ryanc.halo.model.domain.Logs;
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.LogsRecord;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.CategoryService;
|
||||
import cc.ryanc.halo.service.LogsService;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import cc.ryanc.halo.web.controller.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
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.HttpSession;
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/10
|
||||
* @version : 1.0
|
||||
* description: 文章控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/posts")
|
||||
public class PostController extends BaseController{
|
||||
|
||||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
|
||||
@Autowired
|
||||
private LogsService logsService;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 处理后台获取文章列表的请求
|
||||
* @param model Model
|
||||
* @param page Page
|
||||
* @param size Size
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping
|
||||
public String posts(Model model,
|
||||
@RequestParam(value = "status",defaultValue = "0") Integer status,
|
||||
@RequestParam(value = "page",defaultValue = "0") Integer page,
|
||||
@RequestParam(value = "size",defaultValue = "10") Integer size){
|
||||
try {
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postId");
|
||||
Pageable pageable = new PageRequest(page,size,sort);
|
||||
Page<Post> posts = postService.findPostByStatus(status,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
List<Post> postsPublish = postService.findPostByStatus(0);
|
||||
model.addAttribute("publishCount",postsPublish.size());
|
||||
List<Post> postsDraft = postService.findPostByStatus(1);
|
||||
model.addAttribute("draftCount",postsDraft.size());
|
||||
List<Post> postsTrash = postService.findPostByStatus(2);
|
||||
model.addAttribute("trashCount",postsTrash.size());
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
model.addAttribute("status",status);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/post";
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊查询文章
|
||||
* @param model Model
|
||||
* @param keyword keyword
|
||||
* @param page page
|
||||
* @param size size
|
||||
* @return freemarker
|
||||
*/
|
||||
@PostMapping(value="/search")
|
||||
public String searchPost(Model model,
|
||||
@RequestParam(value = "keyword") String keyword,
|
||||
@RequestParam(value = "page",defaultValue = "0") Integer page,
|
||||
@RequestParam(value = "size",defaultValue = "10") Integer size){
|
||||
try {
|
||||
//排序规则
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"postId");
|
||||
Pageable pageable = new PageRequest(page,size,sort);
|
||||
model.addAttribute("posts",postService.searchPosts(keyword,pageable));
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/post";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理预览文章的请求
|
||||
* @param postId postId
|
||||
* @param model model
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = "/view")
|
||||
public String viewPost(@PathParam("postId") Integer postId,Model model){
|
||||
Post post = postService.findByPostId(postId);
|
||||
model.addAttribute("post",post);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return this.render("post");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理跳转到新建文章页面
|
||||
* @return freemarker
|
||||
*/
|
||||
@GetMapping(value = "/new")
|
||||
public String newPost(Model model){
|
||||
try {
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
model.addAttribute("btnPush","发布");
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/editor";
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加文章
|
||||
* @param post Post
|
||||
*/
|
||||
@PostMapping(value = "/new/push")
|
||||
@ResponseBody
|
||||
public void pushPost(@ModelAttribute Post post,@RequestParam("cateList") List<String> cateList, HttpSession session){
|
||||
try{
|
||||
for(String a:cateList){
|
||||
System.out.println(a);
|
||||
}
|
||||
//提取摘要
|
||||
int postSummary = 50;
|
||||
if(HaloUtil.isNotNull(HaloConst.OPTIONS.get("post_summary"))){
|
||||
postSummary = Integer.parseInt(HaloConst.OPTIONS.get("post_summary"));
|
||||
}
|
||||
if(HaloUtil.htmlToText(post.getPostContent()).length()>postSummary){
|
||||
String summary = HaloUtil.getSummary(post.getPostContent(), postSummary);
|
||||
post.setPostSummary(summary);
|
||||
}
|
||||
post.setPostDate(new Date());
|
||||
//发表用户
|
||||
User user = (User)session.getAttribute("user");
|
||||
post.setUser(user);
|
||||
List<Category> categories = categoryService.strListToCateList(cateList);
|
||||
post.setCategories(categories);
|
||||
postService.saveByPost(post);
|
||||
log.info("已发表新文章:"+post.getPostTitle());
|
||||
logsService.saveByLogs(new Logs(LogsRecord.PUSH_POST,post.getPostTitle(),HaloUtil.getIpAddr(request),HaloUtil.getDate()));
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理移至回收站的请求
|
||||
* @param postId postId
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping("/throw")
|
||||
public String moveToTrash(@RequestParam("postId") Integer postId){
|
||||
try{
|
||||
postService.updatePostStatus(postId,2);
|
||||
log.info("编号为"+postId+"的文章已被移到回收站");
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/posts";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理文章为发布的状态
|
||||
* @param postId postId
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping("/revert")
|
||||
public String moveToPublish(@RequestParam("postId") Integer postId,
|
||||
@RequestParam("status") Integer status){
|
||||
try{
|
||||
postService.updatePostStatus(postId,0);
|
||||
log.info("编号为"+postId+"的文章已改变为发布状态");
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/posts?status="+status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理删除文章的请求
|
||||
* @param postId postId
|
||||
* @return 转发
|
||||
*/
|
||||
@GetMapping(value = "/remove")
|
||||
public String removePost(@PathParam("postId") Integer postId){
|
||||
try{
|
||||
Post post = postService.findByPostId(postId);
|
||||
postService.removeByPostId(postId);
|
||||
log.info("删除的文章为:"+post.getPostTitle());
|
||||
logsService.saveByLogs(new Logs(LogsRecord.REMOVE_POST,post.getPostTitle(),HaloUtil.getIpAddr(request),HaloUtil.getDate()));
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/posts?status=2";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到编辑文章页面
|
||||
* @param postId postId
|
||||
* @param model Model
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/edit")
|
||||
public String editPost(@PathParam("postId") Integer postId, Model model){
|
||||
try {
|
||||
Post post = postService.findByPostId(postId);
|
||||
model.addAttribute("post",post);
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
model.addAttribute("categories",categories);
|
||||
model.addAttribute("btnPush","更新");
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/editor";
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有摘要
|
||||
* @param postSummary postSummary
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/updateSummary")
|
||||
@ResponseBody
|
||||
public String updateSummary(@PathParam("postSummary") Integer postSummary){
|
||||
try {
|
||||
postService.updateAllSummary(postSummary);
|
||||
return RespStatus.SUCCESS;
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证文章路径是否已经存在
|
||||
* @param postUrl postUrl
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/checkUrl")
|
||||
@ResponseBody
|
||||
public String checkUrlExists(@PathParam("postUrl") String postUrl){
|
||||
Post post = postService.findByPostUrl(postUrl);
|
||||
if(null!=post){
|
||||
return RespStatus.EXISTS;
|
||||
}else{
|
||||
return RespStatus.NOTEXISTS;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Tag;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.TagService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.websocket.server.PathParam;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/10
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/tag")
|
||||
public class TagController {
|
||||
|
||||
@Autowired
|
||||
private TagService tagService;
|
||||
|
||||
/**
|
||||
* 渲染标签管理页面
|
||||
* @param model model
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping
|
||||
public String tags(Model model){
|
||||
List<Tag> tags = tagService.findAllTags();
|
||||
model.addAttribute("tags",tags);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/tag";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增标签
|
||||
* @param tag tag
|
||||
* @return string
|
||||
*/
|
||||
@PostMapping(value = "/save")
|
||||
public String saveTag(@ModelAttribute Tag tag){
|
||||
try{
|
||||
Tag backTag = tagService.saveByTag(tag);
|
||||
log.info("新添加的标签为:"+backTag);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/tag";
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否存在该路径
|
||||
* @param tagUrl tagUrl
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/checkUrl")
|
||||
@ResponseBody
|
||||
public String checkTagUrlExists(@RequestParam("tagUrl") String tagUrl){
|
||||
Tag tag = tagService.findByTagUrl(tagUrl);
|
||||
if(null!=tag){
|
||||
return RespStatus.EXISTS;
|
||||
}else{
|
||||
return RespStatus.NOTEXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理删除标签的请求
|
||||
* @param tagId tagId
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/remove")
|
||||
public String removeTag(@PathParam("tagId") Integer tagId){
|
||||
try{
|
||||
Tag tag = tagService.removeByTagId(tagId);
|
||||
log.info("删除的标签:"+tag);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/tag";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到修改标签页面
|
||||
* @param model model
|
||||
* @param tagId tagId
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping(value = "/edit")
|
||||
public String toEditTag(Model model,@PathParam("tagId") Integer tagId){
|
||||
try{
|
||||
Tag tag = tagService.findByTagId(tagId);
|
||||
model.addAttribute("tag",tag);
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
log.info("tagId为"+tagId+"的数据为:"+tag);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/_tag-update";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改标签的请求
|
||||
* @param tag tag
|
||||
* @return string
|
||||
*/
|
||||
@PostMapping(value = "/update")
|
||||
public String updateTag(@ModelAttribute Tag tag){
|
||||
try {
|
||||
Tag beforeTag = tagService.findByTagId(tag.getTagId());
|
||||
log.info("修改之前的数据:"+beforeTag+",修改之后的数据:"+tag);
|
||||
tagService.updateByTag(tag);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "redirect:/admin/tag";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import cc.ryanc.halo.web.controller.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.websocket.server.PathParam;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/16
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/themes")
|
||||
public class ThemeController extends BaseController{
|
||||
|
||||
@Autowired
|
||||
private OptionsService optionsService;
|
||||
/**
|
||||
* 渲染主题设置页面
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping
|
||||
public String themes(Model model){
|
||||
try {
|
||||
model.addAttribute("theme",BaseController.THEME);
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
log.info("当前的主题为:"+BaseController.THEME);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
}
|
||||
return "admin/theme";
|
||||
}
|
||||
|
||||
/**
|
||||
* 激活主题
|
||||
* @param siteTheme siteTheme
|
||||
*/
|
||||
@GetMapping(value = "/set")
|
||||
@ResponseBody
|
||||
public String activeTheme(@PathParam("siteTheme") String siteTheme){
|
||||
try {
|
||||
//保存主题设置项在数据库
|
||||
optionsService.saveOption("theme",siteTheme);
|
||||
//设置主题
|
||||
BaseController.THEME = siteTheme;
|
||||
log.info("已将主题改变为:"+siteTheme);
|
||||
return RespStatus.SUCCESS;
|
||||
}catch (Exception e){
|
||||
log.error("主题设置失败,当前主题为:"+BaseController.THEME);
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传主题
|
||||
* @param file file
|
||||
* @return String
|
||||
*/
|
||||
@RequestMapping(value = "/upload", method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public void uploadTheme(@RequestParam("file") MultipartFile file){
|
||||
try {
|
||||
if(!file.isEmpty()) {
|
||||
//获取项目根路径
|
||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + file.getOriginalFilename());
|
||||
file.transferTo(themePath);
|
||||
log.info("上传主题成功,路径:" + themePath.getAbsolutePath());
|
||||
HaloUtil.unZip(themePath.getAbsolutePath(),new File(basePath.getAbsolutePath(),"templates/themes/").getAbsolutePath());
|
||||
}else{
|
||||
log.error("上传失败,没有选择文件");
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("上传失败:"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到主题设置
|
||||
* @param theme theme名称
|
||||
*/
|
||||
@GetMapping(value = "/options")
|
||||
public String setting(Model model,@RequestParam("theme") String theme){
|
||||
model.addAttribute("options",HaloConst.OPTIONS);
|
||||
return "themes/"+theme+"/module/options";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.RespStatus;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.HttpSession;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/24
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping(value = "/admin/profile")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 获取用户信息并跳转
|
||||
* @return string
|
||||
*/
|
||||
@GetMapping
|
||||
public String profile(Model model){
|
||||
model.addAttribute("user",userService.findAllUser().get(0));
|
||||
model.addAttribute("options", HaloConst.OPTIONS);
|
||||
return "admin/profile";
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改用户资料的请求
|
||||
* @param user user
|
||||
* @return String
|
||||
*/
|
||||
@PostMapping(value = "save")
|
||||
@ResponseBody
|
||||
public String saveProfile(@ModelAttribute User user,HttpSession session){
|
||||
try{
|
||||
if(null!=user){
|
||||
userService.saveByUser(user);
|
||||
HaloConst.USER = userService.findAllUser().get(0);
|
||||
session.invalidate();
|
||||
}else{
|
||||
log.error("用户信息不能为空值");
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:"+e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
return RespStatus.SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改密码的请求
|
||||
* @param beforePass 之前的密码
|
||||
* @param newPass 新密码
|
||||
* @return String
|
||||
*/
|
||||
@PostMapping(value = "changePass")
|
||||
@ResponseBody
|
||||
public String changePass(@ModelAttribute("beforePass") String beforePass,
|
||||
@ModelAttribute("newPass") String newPass,
|
||||
@ModelAttribute("userId") Integer userId,
|
||||
HttpSession session){
|
||||
try {
|
||||
User user = userService.findByUserIdAndUserPass(userId,HaloUtil.getMD5(beforePass));
|
||||
if(null!=user){
|
||||
user.setUserPass(HaloUtil.getMD5(newPass));
|
||||
userService.saveByUser(user);
|
||||
log.info("修改密码:成功");
|
||||
session.invalidate();
|
||||
}else{
|
||||
log.error("修改密码:原密码错误!");
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("修改密码:未知错误,"+e.getMessage());
|
||||
return RespStatus.ERROR;
|
||||
}
|
||||
return RespStatus.SUCCESS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package cc.ryanc.halo.web.interceptor;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/13
|
||||
* @version : 1.0
|
||||
* description:
|
||||
*/
|
||||
@Component
|
||||
public class LoginInterceptor implements HandlerInterceptor{
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
Object obj = request.getSession().getAttribute("user");
|
||||
//如果user不为空则放行
|
||||
if(null!=obj){
|
||||
return true;
|
||||
}
|
||||
//否则拦截并跳转到登录
|
||||
response.sendRedirect("/admin/login");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
||||
//
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
# 端口配置
|
||||
server:
|
||||
port: 8080
|
||||
spring:
|
||||
# 数据源配置 使用druid数据源
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=false
|
||||
username: root
|
||||
password: 123456
|
||||
#SQL脚本导入
|
||||
#schema: classpath:/import.sql
|
||||
#sql-script-encoding: utf-8
|
||||
|
||||
# jpa配置
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
show-sql: true
|
||||
|
||||
# freemarker配置
|
||||
freemarker:
|
||||
allow-request-override: false
|
||||
cache: false
|
||||
check-template-location: true
|
||||
charset: utf-8
|
||||
content-type: text/html
|
||||
expose-request-attributes: false
|
||||
expose-session-attributes: false
|
||||
expose-spring-macro-helpers: false
|
||||
suffix: .ftl
|
||||
http:
|
||||
multipart:
|
||||
max-file-size: 10Mb
|
||||
max-request-size: 20Mb
|
||||
# TODO config this ehcache
|
||||
cache:
|
||||
ehcache:
|
||||
config: ehcache.xml
|
||||
# 设置日志输出路径
|
||||
logging:
|
||||
file: ./logs/log.log
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
${AnsiColor.BLUE}
|
||||
__ __ __
|
||||
/ / / /___ _/ /___
|
||||
/ /_/ / __ `/ / __ \
|
||||
/ __ / /_/ / / /_/ /
|
||||
/_/ /_/\__,_/_/\____/
|
||||
${AnsiColor.BRIGHT_YELLOW}
|
||||
::: Halo (version:${application.version}) ::: Spring-Boot ${spring-boot.version}
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
|
||||
updateCheck="false">
|
||||
<diskStore path="java.io.tmpdir"/>
|
||||
<defaultCache
|
||||
eternal="false"
|
||||
maxElementsInMemory="1000"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
timeToIdleSeconds="0"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU" />
|
||||
|
||||
<cache
|
||||
name="inkCache"
|
||||
eternal="false"
|
||||
maxElementsInMemory="10000"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
timeToIdleSeconds="0"
|
||||
timeToLiveSeconds="300"
|
||||
memoryStoreEvictionPolicy="LRU" />
|
||||
|
||||
<cache
|
||||
name="options_cache"
|
||||
eternal="false"
|
||||
maxElementsInMemory="10000"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
timeToIdleSeconds="0"
|
||||
timeToLiveSeconds="300"
|
||||
memoryStoreEvictionPolicy="LRU" />
|
||||
</ehcache>
|
|
@ -0,0 +1,3 @@
|
|||
insert into options(option_name,option_value) values('site','Ryan0up Blog');
|
||||
insert into options(option_name,option_value) values('keyword','Ryan0up,Ryan0up Blog');
|
||||
insert into options(option_name,option_value) values('desc','我是Ryan');
|
|
@ -0,0 +1,3 @@
|
|||
User-agent: *
|
||||
Disallow: /admin/
|
||||
Sitemap: /sitemap.xml
|
|
@ -0,0 +1,760 @@
|
|||
/*
|
||||
* Social Buttons for Bootstrap
|
||||
*
|
||||
* Copyright 2013-2015 Panayiotis Lipiridis
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* https://github.com/lipis/bootstrap-social
|
||||
*/
|
||||
.btn-social {
|
||||
position: relative;
|
||||
padding-left: 44px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.btn-social > :first-child {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 32px;
|
||||
line-height: 34px;
|
||||
font-size: 1.6em;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-social.btn-lg {
|
||||
padding-left: 61px;
|
||||
}
|
||||
.btn-social.btn-lg > :first-child {
|
||||
line-height: 45px;
|
||||
width: 45px;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
.btn-social.btn-sm {
|
||||
padding-left: 38px;
|
||||
}
|
||||
.btn-social.btn-sm > :first-child {
|
||||
line-height: 28px;
|
||||
width: 28px;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
.btn-social.btn-xs {
|
||||
padding-left: 30px;
|
||||
}
|
||||
.btn-social.btn-xs > :first-child {
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.btn-social-icon {
|
||||
position: relative;
|
||||
padding-left: 44px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
padding: 0;
|
||||
}
|
||||
.btn-social-icon > :first-child {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 32px;
|
||||
line-height: 34px;
|
||||
font-size: 1.6em;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-social-icon.btn-lg {
|
||||
padding-left: 61px;
|
||||
}
|
||||
.btn-social-icon.btn-lg > :first-child {
|
||||
line-height: 45px;
|
||||
width: 45px;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
.btn-social-icon.btn-sm {
|
||||
padding-left: 38px;
|
||||
}
|
||||
.btn-social-icon.btn-sm > :first-child {
|
||||
line-height: 28px;
|
||||
width: 28px;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
.btn-social-icon.btn-xs {
|
||||
padding-left: 30px;
|
||||
}
|
||||
.btn-social-icon.btn-xs > :first-child {
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.btn-social-icon > :first-child {
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
.btn-social-icon.btn-lg {
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
.btn-social-icon.btn-sm {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
.btn-social-icon.btn-xs {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
.btn-adn {
|
||||
color: #ffffff;
|
||||
background-color: #d87a68;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-adn:focus,
|
||||
.btn-adn.focus {
|
||||
color: #ffffff;
|
||||
background-color: #ce563f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-adn:hover {
|
||||
color: #ffffff;
|
||||
background-color: #ce563f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-adn:active,
|
||||
.btn-adn.active,
|
||||
.open > .dropdown-toggle.btn-adn {
|
||||
color: #ffffff;
|
||||
background-color: #ce563f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-adn:active,
|
||||
.btn-adn.active,
|
||||
.open > .dropdown-toggle.btn-adn {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-adn .badge {
|
||||
color: #d87a68;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-bitbucket {
|
||||
color: #ffffff;
|
||||
background-color: #205081;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-bitbucket:focus,
|
||||
.btn-bitbucket.focus {
|
||||
color: #ffffff;
|
||||
background-color: #163758;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-bitbucket:hover {
|
||||
color: #ffffff;
|
||||
background-color: #163758;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-bitbucket:active,
|
||||
.btn-bitbucket.active,
|
||||
.open > .dropdown-toggle.btn-bitbucket {
|
||||
color: #ffffff;
|
||||
background-color: #163758;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-bitbucket:active,
|
||||
.btn-bitbucket.active,
|
||||
.open > .dropdown-toggle.btn-bitbucket {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-bitbucket .badge {
|
||||
color: #205081;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-dropbox {
|
||||
color: #ffffff;
|
||||
background-color: #1087dd;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-dropbox:focus,
|
||||
.btn-dropbox.focus {
|
||||
color: #ffffff;
|
||||
background-color: #0d6aad;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-dropbox:hover {
|
||||
color: #ffffff;
|
||||
background-color: #0d6aad;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-dropbox:active,
|
||||
.btn-dropbox.active,
|
||||
.open > .dropdown-toggle.btn-dropbox {
|
||||
color: #ffffff;
|
||||
background-color: #0d6aad;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-dropbox:active,
|
||||
.btn-dropbox.active,
|
||||
.open > .dropdown-toggle.btn-dropbox {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-dropbox .badge {
|
||||
color: #1087dd;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-facebook {
|
||||
color: #ffffff;
|
||||
background-color: #3b5998;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-facebook:focus,
|
||||
.btn-facebook.focus {
|
||||
color: #ffffff;
|
||||
background-color: #2d4373;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-facebook:hover {
|
||||
color: #ffffff;
|
||||
background-color: #2d4373;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-facebook:active,
|
||||
.btn-facebook.active,
|
||||
.open > .dropdown-toggle.btn-facebook {
|
||||
color: #ffffff;
|
||||
background-color: #2d4373;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-facebook:active,
|
||||
.btn-facebook.active,
|
||||
.open > .dropdown-toggle.btn-facebook {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-facebook .badge {
|
||||
color: #3b5998;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-flickr {
|
||||
color: #ffffff;
|
||||
background-color: #ff0084;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-flickr:focus,
|
||||
.btn-flickr.focus {
|
||||
color: #ffffff;
|
||||
background-color: #cc006a;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-flickr:hover {
|
||||
color: #ffffff;
|
||||
background-color: #cc006a;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-flickr:active,
|
||||
.btn-flickr.active,
|
||||
.open > .dropdown-toggle.btn-flickr {
|
||||
color: #ffffff;
|
||||
background-color: #cc006a;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-flickr:active,
|
||||
.btn-flickr.active,
|
||||
.open > .dropdown-toggle.btn-flickr {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-flickr .badge {
|
||||
color: #ff0084;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-foursquare {
|
||||
color: #ffffff;
|
||||
background-color: #f94877;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-foursquare:focus,
|
||||
.btn-foursquare.focus {
|
||||
color: #ffffff;
|
||||
background-color: #f71752;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-foursquare:hover {
|
||||
color: #ffffff;
|
||||
background-color: #f71752;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-foursquare:active,
|
||||
.btn-foursquare.active,
|
||||
.open > .dropdown-toggle.btn-foursquare {
|
||||
color: #ffffff;
|
||||
background-color: #f71752;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-foursquare:active,
|
||||
.btn-foursquare.active,
|
||||
.open > .dropdown-toggle.btn-foursquare {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-foursquare .badge {
|
||||
color: #f94877;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-github {
|
||||
color: #ffffff;
|
||||
background-color: #444444;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-github:focus,
|
||||
.btn-github.focus {
|
||||
color: #ffffff;
|
||||
background-color: #2b2b2b;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-github:hover {
|
||||
color: #ffffff;
|
||||
background-color: #2b2b2b;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-github:active,
|
||||
.btn-github.active,
|
||||
.open > .dropdown-toggle.btn-github {
|
||||
color: #ffffff;
|
||||
background-color: #2b2b2b;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-github:active,
|
||||
.btn-github.active,
|
||||
.open > .dropdown-toggle.btn-github {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-github .badge {
|
||||
color: #444444;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-google {
|
||||
color: #ffffff;
|
||||
background-color: #dd4b39;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-google:focus,
|
||||
.btn-google.focus {
|
||||
color: #ffffff;
|
||||
background-color: #c23321;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-google:hover {
|
||||
color: #ffffff;
|
||||
background-color: #c23321;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-google:active,
|
||||
.btn-google.active,
|
||||
.open > .dropdown-toggle.btn-google {
|
||||
color: #ffffff;
|
||||
background-color: #c23321;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-google:active,
|
||||
.btn-google.active,
|
||||
.open > .dropdown-toggle.btn-google {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-google .badge {
|
||||
color: #dd4b39;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-instagram {
|
||||
color: #ffffff;
|
||||
background-color: #3f729b;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-instagram:focus,
|
||||
.btn-instagram.focus {
|
||||
color: #ffffff;
|
||||
background-color: #305777;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-instagram:hover {
|
||||
color: #ffffff;
|
||||
background-color: #305777;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-instagram:active,
|
||||
.btn-instagram.active,
|
||||
.open > .dropdown-toggle.btn-instagram {
|
||||
color: #ffffff;
|
||||
background-color: #305777;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-instagram:active,
|
||||
.btn-instagram.active,
|
||||
.open > .dropdown-toggle.btn-instagram {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-instagram .badge {
|
||||
color: #3f729b;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-linkedin {
|
||||
color: #ffffff;
|
||||
background-color: #007bb6;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-linkedin:focus,
|
||||
.btn-linkedin.focus {
|
||||
color: #ffffff;
|
||||
background-color: #005983;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-linkedin:hover {
|
||||
color: #ffffff;
|
||||
background-color: #005983;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-linkedin:active,
|
||||
.btn-linkedin.active,
|
||||
.open > .dropdown-toggle.btn-linkedin {
|
||||
color: #ffffff;
|
||||
background-color: #005983;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-linkedin:active,
|
||||
.btn-linkedin.active,
|
||||
.open > .dropdown-toggle.btn-linkedin {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-linkedin .badge {
|
||||
color: #007bb6;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-microsoft {
|
||||
color: #ffffff;
|
||||
background-color: #2672ec;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-microsoft:focus,
|
||||
.btn-microsoft.focus {
|
||||
color: #ffffff;
|
||||
background-color: #125acd;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-microsoft:hover {
|
||||
color: #ffffff;
|
||||
background-color: #125acd;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-microsoft:active,
|
||||
.btn-microsoft.active,
|
||||
.open > .dropdown-toggle.btn-microsoft {
|
||||
color: #ffffff;
|
||||
background-color: #125acd;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-microsoft:active,
|
||||
.btn-microsoft.active,
|
||||
.open > .dropdown-toggle.btn-microsoft {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-microsoft .badge {
|
||||
color: #2672ec;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-openid {
|
||||
color: #ffffff;
|
||||
background-color: #f7931e;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-openid:focus,
|
||||
.btn-openid.focus {
|
||||
color: #ffffff;
|
||||
background-color: #da7908;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-openid:hover {
|
||||
color: #ffffff;
|
||||
background-color: #da7908;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-openid:active,
|
||||
.btn-openid.active,
|
||||
.open > .dropdown-toggle.btn-openid {
|
||||
color: #ffffff;
|
||||
background-color: #da7908;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-openid:active,
|
||||
.btn-openid.active,
|
||||
.open > .dropdown-toggle.btn-openid {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-openid .badge {
|
||||
color: #f7931e;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-pinterest {
|
||||
color: #ffffff;
|
||||
background-color: #cb2027;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-pinterest:focus,
|
||||
.btn-pinterest.focus {
|
||||
color: #ffffff;
|
||||
background-color: #9f191f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-pinterest:hover {
|
||||
color: #ffffff;
|
||||
background-color: #9f191f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-pinterest:active,
|
||||
.btn-pinterest.active,
|
||||
.open > .dropdown-toggle.btn-pinterest {
|
||||
color: #ffffff;
|
||||
background-color: #9f191f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-pinterest:active,
|
||||
.btn-pinterest.active,
|
||||
.open > .dropdown-toggle.btn-pinterest {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-pinterest .badge {
|
||||
color: #cb2027;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-reddit {
|
||||
color: #000000;
|
||||
background-color: #eff7ff;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-reddit:focus,
|
||||
.btn-reddit.focus {
|
||||
color: #000000;
|
||||
background-color: #bcddff;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-reddit:hover {
|
||||
color: #000000;
|
||||
background-color: #bcddff;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-reddit:active,
|
||||
.btn-reddit.active,
|
||||
.open > .dropdown-toggle.btn-reddit {
|
||||
color: #000000;
|
||||
background-color: #bcddff;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-reddit:active,
|
||||
.btn-reddit.active,
|
||||
.open > .dropdown-toggle.btn-reddit {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-reddit .badge {
|
||||
color: #eff7ff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.btn-soundcloud {
|
||||
color: #ffffff;
|
||||
background-color: #ff5500;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-soundcloud:focus,
|
||||
.btn-soundcloud.focus {
|
||||
color: #ffffff;
|
||||
background-color: #cc4400;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-soundcloud:hover {
|
||||
color: #ffffff;
|
||||
background-color: #cc4400;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-soundcloud:active,
|
||||
.btn-soundcloud.active,
|
||||
.open > .dropdown-toggle.btn-soundcloud {
|
||||
color: #ffffff;
|
||||
background-color: #cc4400;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-soundcloud:active,
|
||||
.btn-soundcloud.active,
|
||||
.open > .dropdown-toggle.btn-soundcloud {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-soundcloud .badge {
|
||||
color: #ff5500;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-tumblr {
|
||||
color: #ffffff;
|
||||
background-color: #2c4762;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-tumblr:focus,
|
||||
.btn-tumblr.focus {
|
||||
color: #ffffff;
|
||||
background-color: #1c2d3f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-tumblr:hover {
|
||||
color: #ffffff;
|
||||
background-color: #1c2d3f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-tumblr:active,
|
||||
.btn-tumblr.active,
|
||||
.open > .dropdown-toggle.btn-tumblr {
|
||||
color: #ffffff;
|
||||
background-color: #1c2d3f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-tumblr:active,
|
||||
.btn-tumblr.active,
|
||||
.open > .dropdown-toggle.btn-tumblr {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-tumblr .badge {
|
||||
color: #2c4762;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-twitter {
|
||||
color: #ffffff;
|
||||
background-color: #55acee;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-twitter:focus,
|
||||
.btn-twitter.focus {
|
||||
color: #ffffff;
|
||||
background-color: #2795e9;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-twitter:hover {
|
||||
color: #ffffff;
|
||||
background-color: #2795e9;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-twitter:active,
|
||||
.btn-twitter.active,
|
||||
.open > .dropdown-toggle.btn-twitter {
|
||||
color: #ffffff;
|
||||
background-color: #2795e9;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-twitter:active,
|
||||
.btn-twitter.active,
|
||||
.open > .dropdown-toggle.btn-twitter {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-twitter .badge {
|
||||
color: #55acee;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-vimeo {
|
||||
color: #ffffff;
|
||||
background-color: #1ab7ea;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vimeo:focus,
|
||||
.btn-vimeo.focus {
|
||||
color: #ffffff;
|
||||
background-color: #1295bf;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vimeo:hover {
|
||||
color: #ffffff;
|
||||
background-color: #1295bf;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vimeo:active,
|
||||
.btn-vimeo.active,
|
||||
.open > .dropdown-toggle.btn-vimeo {
|
||||
color: #ffffff;
|
||||
background-color: #1295bf;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vimeo:active,
|
||||
.btn-vimeo.active,
|
||||
.open > .dropdown-toggle.btn-vimeo {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-vimeo .badge {
|
||||
color: #1ab7ea;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-vk {
|
||||
color: #ffffff;
|
||||
background-color: #587ea3;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vk:focus,
|
||||
.btn-vk.focus {
|
||||
color: #ffffff;
|
||||
background-color: #466482;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vk:hover {
|
||||
color: #ffffff;
|
||||
background-color: #466482;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vk:active,
|
||||
.btn-vk.active,
|
||||
.open > .dropdown-toggle.btn-vk {
|
||||
color: #ffffff;
|
||||
background-color: #466482;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-vk:active,
|
||||
.btn-vk.active,
|
||||
.open > .dropdown-toggle.btn-vk {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-vk .badge {
|
||||
color: #587ea3;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.btn-yahoo {
|
||||
color: #ffffff;
|
||||
background-color: #720e9e;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-yahoo:focus,
|
||||
.btn-yahoo.focus {
|
||||
color: #ffffff;
|
||||
background-color: #500a6f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-yahoo:hover {
|
||||
color: #ffffff;
|
||||
background-color: #500a6f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-yahoo:active,
|
||||
.btn-yahoo.active,
|
||||
.open > .dropdown-toggle.btn-yahoo {
|
||||
color: #ffffff;
|
||||
background-color: #500a6f;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.btn-yahoo:active,
|
||||
.btn-yahoo.active,
|
||||
.open > .dropdown-toggle.btn-yahoo {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-yahoo .badge {
|
||||
color: #720e9e;
|
||||
background-color: #ffffff;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Plugin: Select2
|
||||
* ---------------
|
||||
*/
|
||||
.select2-container--default.select2-container--focus,
|
||||
.select2-selection.select2-container--focus,
|
||||
.select2-container--default:focus,
|
||||
.select2-selection:focus,
|
||||
.select2-container--default:active,
|
||||
.select2-selection:active {
|
||||
outline: none;
|
||||
}
|
||||
.select2-container--default .select2-selection--single,
|
||||
.select2-selection .select2-selection--single {
|
||||
border: 1px solid #d2d6de;
|
||||
border-radius: 0;
|
||||
padding: 6px 12px;
|
||||
height: 34px;
|
||||
}
|
||||
.select2-container--default.select2-container--open {
|
||||
border-color: #3c8dbc;
|
||||
}
|
||||
.select2-dropdown {
|
||||
border: 1px solid #d2d6de;
|
||||
border-radius: 0;
|
||||
}
|
||||
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
||||
background-color: #3c8dbc;
|
||||
color: white;
|
||||
}
|
||||
.select2-results__option {
|
||||
padding: 6px 12px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.select2-container .select2-selection--single .select2-selection__rendered {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
height: auto;
|
||||
margin-top: -4px;
|
||||
}
|
||||
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
|
||||
padding-right: 6px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
||||
height: 28px;
|
||||
right: 3px;
|
||||
}
|
||||
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
||||
margin-top: 0;
|
||||
}
|
||||
.select2-dropdown .select2-search__field,
|
||||
.select2-search--inline .select2-search__field {
|
||||
border: 1px solid #d2d6de;
|
||||
}
|
||||
.select2-dropdown .select2-search__field:focus,
|
||||
.select2-search--inline .select2-search__field:focus {
|
||||
outline: none;
|
||||
}
|
||||
.select2-container--default.select2-container--focus .select2-selection--multiple,
|
||||
.select2-container--default .select2-search--dropdown .select2-search__field {
|
||||
border-color: #3c8dbc !important;
|
||||
}
|
||||
.select2-container--default .select2-results__option[aria-disabled=true] {
|
||||
color: #999;
|
||||
}
|
||||
.select2-container--default .select2-results__option[aria-selected=true] {
|
||||
background-color: #ddd;
|
||||
}
|
||||
.select2-container--default .select2-results__option[aria-selected=true],
|
||||
.select2-container--default .select2-results__option[aria-selected=true]:hover {
|
||||
color: #444;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
border: 1px solid #d2d6de;
|
||||
border-radius: 0;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple:focus {
|
||||
border-color: #3c8dbc;
|
||||
}
|
||||
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
||||
border-color: #d2d6de;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||
background-color: #3c8dbc;
|
||||
border-color: #367fa9;
|
||||
padding: 1px 10px;
|
||||
color: #fff;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
|
||||
margin-right: 5px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.select2-container .select2-selection--single .select2-selection__rendered {
|
||||
padding-right: 10px;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none}.select2-container--default.select2-container--focus .select2-selection--multiple,.select2-container--default .select2-search--dropdown .select2-search__field{border-color:#3c8dbc !important}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
皮肤颜色附加
|
||||
*/
|
||||
.skin-blue .box.box-primary{
|
||||
border-top-color: #3c8dbc;
|
||||
}
|
||||
|
||||
.skin-blue .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #3c8dbc;
|
||||
}
|
||||
|
||||
.skin-blue-light .box.box-primary{
|
||||
border-top-color: #3c8dbc;
|
||||
}
|
||||
|
||||
.skin-blue-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #3c8dbc;
|
||||
}
|
||||
|
||||
.skin-black .box.box-primary{
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.skin-black .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.skin-black-light .box.box-primary{
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.skin-black-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.skin-green .box.box-primary{
|
||||
border-top-color: #00a65a;
|
||||
}
|
||||
|
||||
.skin-green .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #00a65a;
|
||||
}
|
||||
|
||||
.skin-green-light .box.box-primary{
|
||||
border-top-color: #00a65a;
|
||||
}
|
||||
|
||||
.skin-green-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #00a65a;
|
||||
}
|
||||
|
||||
.skin-purple .box.box-primary{
|
||||
border-top-color: #605ca8;
|
||||
}
|
||||
|
||||
.skin-purple .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #605ca8;
|
||||
}
|
||||
|
||||
.skin-purple-light .box.box-primary{
|
||||
border-top-color: #605ca8;
|
||||
}
|
||||
|
||||
.skin-purple-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #605ca8;
|
||||
}
|
||||
|
||||
.skin-red .box.box-primary{
|
||||
border-top-color: #dd4b39;
|
||||
}
|
||||
|
||||
.skin-red .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #dd4b39;
|
||||
}
|
||||
|
||||
.skin-red-light .box.box-primary{
|
||||
border-top-color: #dd4b39;
|
||||
}
|
||||
|
||||
.skin-red-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #dd4b39;
|
||||
}
|
||||
|
||||
.skin-yellow .box.box-primary{
|
||||
border-top-color: #f39c12;
|
||||
}
|
||||
|
||||
.skin-yellow .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #f39c12;
|
||||
}
|
||||
|
||||
.skin-yellow-light .box.box-primary{
|
||||
border-top-color: #f39c12;
|
||||
}
|
||||
|
||||
.skin-yellow-light .nav-tabs-custom > .nav-tabs > li.active{
|
||||
border-top-color: #f39c12;
|
||||
}
|
||||
.layout-boxed {
|
||||
background: url('../images/boxed-bg.jpg') repeat fixed;
|
||||
}
|
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 184 B |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 172 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 264 KiB |
After Width: | Height: | Size: 113 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* 提示框
|
||||
* @param text
|
||||
* @param icon
|
||||
* @param hideAfter
|
||||
*/
|
||||
function showMsg(text,icon,hideAfter) {
|
||||
$.toast({
|
||||
text: text,
|
||||
heading: '提示',
|
||||
icon: icon,
|
||||
showHideTransition: 'fade',
|
||||
allowToastClose: true,
|
||||
hideAfter: hideAfter,
|
||||
stack: 5,
|
||||
position: 'top-center',
|
||||
textAlign: 'left',
|
||||
loader: true,
|
||||
loaderBg: '#ffffff'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,587 @@
|
|||
/*!
|
||||
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-color: #e8e8e8;
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-color: #2e6da4;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|