Init
29
.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
### IntelliJ IDEA ###
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
.idea
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
24
Guestbook.iml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="web" name="Web">
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web/WEB-INF/web.xml" />
|
||||||
|
</descriptors>
|
||||||
|
<webroots>
|
||||||
|
<root url="file://$MODULE_DIR$/web" relative="/" />
|
||||||
|
</webroots>
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="libs" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
libs/commons-lang3-3.12.0.jar
Normal file
BIN
libs/fastjson-1.2.79.jar
Normal file
BIN
libs/jakarta.servlet.jsp.jstl-2.0.0.jar
Normal file
BIN
libs/jakarta.servlet.jsp.jstl-api-2.0.0.jar
Normal file
BIN
libs/mysql-connector-j-8.0.31.jar
Normal file
BIN
libs/servlet-api.jar
Normal file
42
src/com/landaiqing/dao/AdminUserDao.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.landaiqing.dao;
|
||||||
|
|
||||||
|
import com.landaiqing.entity.AdminUserEntity;
|
||||||
|
import com.landaiqing.utils.JdbcUtils;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
public class AdminUserDao {
|
||||||
|
private AdminUserEntity adminUserEntity=new AdminUserEntity();
|
||||||
|
/**
|
||||||
|
* 管理员登录
|
||||||
|
* */
|
||||||
|
public AdminUserEntity login(String userName, String userPwd) {
|
||||||
|
ResultSet resultSet = null;
|
||||||
|
PreparedStatement preparedStatement = null;
|
||||||
|
Connection connection = null;
|
||||||
|
try {
|
||||||
|
connection = JdbcUtils.getConnection();
|
||||||
|
String loginSql = "select * from admin where adminUserName=? and adminPassword=?;";
|
||||||
|
preparedStatement = connection.prepareStatement(loginSql);
|
||||||
|
preparedStatement.setString(1, userName);
|
||||||
|
preparedStatement.setString(2, userPwd);
|
||||||
|
resultSet = preparedStatement.executeQuery();
|
||||||
|
if (!resultSet.next()) { // 查询不到用户数据
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 将db中数据 返回给客户端 查询到数据
|
||||||
|
Integer id = resultSet.getInt(1);
|
||||||
|
String dbUserName = resultSet.getString(2);
|
||||||
|
String dbUserPwd = resultSet.getString(3);
|
||||||
|
AdminUserEntity adminUserEntity = new AdminUserEntity(dbUserName, dbUserPwd);
|
||||||
|
return adminUserEntity;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
JdbcUtils.closeConnection(resultSet, preparedStatement, connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
src/com/landaiqing/entity/AdminUserEntity.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package com.landaiqing.entity;
|
||||||
|
|
||||||
|
public class AdminUserEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*CREATE TABLE `admin-user` (
|
||||||
|
* `adminId` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||||
|
* `adminUserName` varchar(25) NOT NULL COMMENT '管理员账号',
|
||||||
|
* `adminPassword` varchar(255) DEFAULT NULL COMMENT '管理员密码',
|
||||||
|
* PRIMARY KEY (`adminId`) USING BTREE
|
||||||
|
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
private Integer adminId;
|
||||||
|
private String adminUserName;
|
||||||
|
private String adminPassword;
|
||||||
|
|
||||||
|
public Integer getAdminId() {
|
||||||
|
return adminId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdminId(Integer adminId) {
|
||||||
|
this.adminId = adminId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAdminUserName() {
|
||||||
|
return adminUserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdminUserName(String adminUserName) {
|
||||||
|
this.adminUserName = adminUserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAdminPassword() {
|
||||||
|
return adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdminPassword(String adminPassword) {
|
||||||
|
this.adminPassword = adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdminUserEntity(Integer adminId, String adminUserName, String adminPassword) {
|
||||||
|
this.adminId = adminId;
|
||||||
|
this.adminUserName = adminUserName;
|
||||||
|
this.adminPassword = adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdminUserEntity(String adminUserName, String adminPassword) {
|
||||||
|
this.adminUserName = adminUserName;
|
||||||
|
this.adminPassword = adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdminUserEntity(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
48
src/com/landaiqing/filter/UserSessionFilter.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//package com.landaiqing.filter;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//import jakarta.servlet.*;
|
||||||
|
//import jakarta.servlet.annotation.WebFilter;
|
||||||
|
//import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
//import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
//import jakarta.servlet.http.HttpSession;
|
||||||
|
//
|
||||||
|
//import java.io.IOException;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * 过滤器
|
||||||
|
// */
|
||||||
|
//@WebFilter("/*")// 过滤器所有的请求
|
||||||
|
//public class UserSessionFilter implements Filter {
|
||||||
|
// private String[] excludeUrls = new String[]{"/login", "/register", "/VerifycodeServlet"};
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
// // 从session获取到用户的会话信息 判断用户是否登录过
|
||||||
|
// HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
||||||
|
// HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
|
||||||
|
// String contextPath = httpServletRequest.getContextPath();
|
||||||
|
// // 定义一个数组 哪些 请求是需要排除的
|
||||||
|
// for (int i = 0; i < excludeUrls.length; i++) {
|
||||||
|
// String excludeUrl = contextPath + excludeUrls[i];
|
||||||
|
// String requestURI = httpServletRequest.getRequestURI();
|
||||||
|
// if (excludeUrl.equals(requestURI)) {
|
||||||
|
// // 放行请求
|
||||||
|
// filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 排除请求
|
||||||
|
// HttpSession session = httpServletRequest.getSession();
|
||||||
|
// Object user = session.getAttribute("user");
|
||||||
|
// if (user == null) {
|
||||||
|
// // 当前用户没有登录或者登录会话失效
|
||||||
|
// // 重定向到登录页面
|
||||||
|
// httpServletResponse.sendRedirect(contextPath+"/login");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// // 用户已经登录了 正常放行请求
|
||||||
|
// filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
15
src/com/landaiqing/service/AdminUserService.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.landaiqing.service;
|
||||||
|
|
||||||
|
import com.landaiqing.dao.AdminUserDao;
|
||||||
|
import com.landaiqing.entity.AdminUserEntity;
|
||||||
|
|
||||||
|
public class AdminUserService {
|
||||||
|
private AdminUserDao adminUserDao=new AdminUserDao();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员登录
|
||||||
|
* */
|
||||||
|
public AdminUserEntity login(String userName, String userPwd) {
|
||||||
|
return adminUserDao.login(userName,userPwd);
|
||||||
|
}
|
||||||
|
}
|
80
src/com/landaiqing/servlet/AdminLoginServlet.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package com.landaiqing.servlet;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.landaiqing.entity.AdminUserEntity;
|
||||||
|
import com.landaiqing.service.AdminUserService;
|
||||||
|
import com.landaiqing.utils.RandomValidateCode;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.annotation.WebServlet;
|
||||||
|
import jakarta.servlet.http.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员登录
|
||||||
|
*/
|
||||||
|
@WebServlet("/login")
|
||||||
|
public class AdminLoginServlet extends HttpServlet {
|
||||||
|
private AdminUserService adminUserService = new AdminUserService();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
// 转发login页面
|
||||||
|
req.getRequestDispatcher("login.jsp").forward(req, resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
// 点击登录的时候 获取到用户的参数
|
||||||
|
String userName = req.getParameter("username");
|
||||||
|
if (StringUtils.isEmpty(userName)) {
|
||||||
|
//转发到错误页面
|
||||||
|
req.setAttribute("errorMsg", "用户名称不能够是为空!");
|
||||||
|
req.getRequestDispatcher("error.jsp").forward(req, resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String userPwd = req.getParameter("password");
|
||||||
|
// 参数验证
|
||||||
|
if (StringUtils.isEmpty(userPwd)) {
|
||||||
|
//转发到错误页面
|
||||||
|
req.setAttribute("errorMsg", "userPwd不能够是为空!");
|
||||||
|
req.getRequestDispatcher("error.jsp").forward(req, resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String userCode = req.getParameter("code"); // 用户输入的图形验证码
|
||||||
|
// 从session中获取图形验证码
|
||||||
|
HttpSession session = req.getSession();
|
||||||
|
String sessionCode = (String) session.getAttribute(RandomValidateCode.RANDOMVALIDATECODE);
|
||||||
|
if (!sessionCode.equalsIgnoreCase(userCode)) {
|
||||||
|
req.setAttribute("errorMsg", "图形验证码不正确,请重新输入!");
|
||||||
|
req.getRequestDispatcher("error.jsp").forward(req, resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 在调用业务逻辑层
|
||||||
|
AdminUserEntity adminUserEntity = adminUserService.login(userName, userPwd);
|
||||||
|
if (adminUserEntity == null) {
|
||||||
|
// 用户名称或者密码错误!
|
||||||
|
req.setAttribute("errorMsg", "用户名称或者是密码错误!");
|
||||||
|
req.getRequestDispatcher("error.jsp").forward(req, resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 判断用户是否记住密码
|
||||||
|
String rememberPassword = req.getParameter("remember");
|
||||||
|
if ("on".equals(rememberPassword)) {
|
||||||
|
// 如果有记住密码则 将密码保存在cookie中
|
||||||
|
Cookie userNameCookie = new Cookie("userName", userName);
|
||||||
|
Cookie userPwdCookie = new Cookie("userPwd", userPwd);
|
||||||
|
resp.addCookie(userNameCookie);
|
||||||
|
resp.addCookie(userPwdCookie);
|
||||||
|
}
|
||||||
|
// 能够db中查询到对象 登录成功了 将用户数据存放在session中
|
||||||
|
session = req.getSession();
|
||||||
|
session.setAttribute("user", adminUserEntity);
|
||||||
|
// 在转发到首页(重定向到首页)
|
||||||
|
// req.getRequestDispatcher("index.jsp").forward(req, resp);
|
||||||
|
resp.sendRedirect("./System/index.jsp");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
src/com/landaiqing/servlet/VerifycodeServlet.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.landaiqing.servlet;
|
||||||
|
|
||||||
|
import com.landaiqing.utils.RandomValidateCode;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.annotation.WebServlet;
|
||||||
|
import jakarta.servlet.http.HttpServlet;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前台验证码处点击刷新,发送到该servlet的请求,
|
||||||
|
* 该servlet调用生成验证码的工具类返回一个图像验证码
|
||||||
|
*/
|
||||||
|
@WebServlet(name = "VerifycodeServlet", urlPatterns = "/VerifycodeServlet")
|
||||||
|
public class VerifycodeServlet extends HttpServlet {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
|
||||||
|
response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
|
||||||
|
//做浏览器兼容
|
||||||
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
|
response.setDateHeader("Expire", 0);
|
||||||
|
RandomValidateCode randomValidateCode = new RandomValidateCode();
|
||||||
|
try {
|
||||||
|
randomValidateCode.getRandcode(request, response);//输出图片方法
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
doGet(request, response);
|
||||||
|
}
|
||||||
|
}
|
132
src/com/landaiqing/utils/JdbcUtils.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package com.landaiqing.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class JdbcUtils {
|
||||||
|
|
||||||
|
private JdbcUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.定义工具类 需要 声明 变量
|
||||||
|
*/
|
||||||
|
private static String driverClass;
|
||||||
|
private static String url;
|
||||||
|
private static String user;
|
||||||
|
private static String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*3.使用静态代码快 来给我们声明好 jdbc变量赋值(读取config.properties)
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
// 1.读取config.properties IO 路径 相对路径
|
||||||
|
InputStream resourceAsStream = JdbcUtils.class.getClassLoader().
|
||||||
|
getResourceAsStream("config.properties");
|
||||||
|
// 2.赋值给我们声明好的变量
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(resourceAsStream);
|
||||||
|
driverClass = properties.getProperty("driverClass");
|
||||||
|
url = properties.getProperty("url");
|
||||||
|
user = properties.getProperty("user");
|
||||||
|
password = properties.getProperty("password");
|
||||||
|
// 3.注册驱动类
|
||||||
|
Class.forName(driverClass);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4.封装连接方法
|
||||||
|
*/
|
||||||
|
public static Connection getConnection() throws SQLException {
|
||||||
|
Connection connection = DriverManager.getConnection(url, user, password);
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5.封装释放连接方法 (重载)
|
||||||
|
*/
|
||||||
|
public static void closeConnection(ResultSet resultSet, Statement statement, Connection connection) {
|
||||||
|
// 1.查询 释放连接 resultSet statement connection
|
||||||
|
try {
|
||||||
|
if (resultSet != null)
|
||||||
|
resultSet.close();
|
||||||
|
if (statement != null)
|
||||||
|
statement.close();
|
||||||
|
if (connection != null)
|
||||||
|
connection.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增删改---释放jdbc资源
|
||||||
|
*
|
||||||
|
* @param statement
|
||||||
|
* @param connection
|
||||||
|
*/
|
||||||
|
public static void closeConnection(Statement statement, Connection connection) {
|
||||||
|
// 1.查询 释放连接 resultSet statement connection
|
||||||
|
closeConnection(null, statement, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启事务
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static void beginTransaction(Connection connection) throws SQLException {
|
||||||
|
connection.setAutoCommit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交事务
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public static void commitTransaction(Connection connection) throws SQLException {
|
||||||
|
connection.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回滚事务
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
*/
|
||||||
|
public static void rollBackTransaction(Connection connection) {
|
||||||
|
if (connection != null) {
|
||||||
|
try {
|
||||||
|
connection.rollback();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭事务
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
*/
|
||||||
|
public static void endTransaction(Connection connection) {
|
||||||
|
if (connection != null) {
|
||||||
|
try {
|
||||||
|
connection.setAutoCommit(true);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
105
src/com/landaiqing/utils/RandomValidateCode.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package com.landaiqing.utils;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具类,生成随机验证码
|
||||||
|
*/
|
||||||
|
public class RandomValidateCode {
|
||||||
|
public static final String RANDOMVALIDATECODE = "RandomValidateCode";// 放到session中的key
|
||||||
|
private Random random = new Random();
|
||||||
|
private String randString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生的字符串
|
||||||
|
private int width = 100;// 图片宽度
|
||||||
|
private int height = 26;// 图片高度
|
||||||
|
private int lineSize = 40;// 干扰线数量
|
||||||
|
private int stringNum = 4;// 随机产生的字符数量
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得字体
|
||||||
|
*/
|
||||||
|
private Font getFont() {
|
||||||
|
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得颜色
|
||||||
|
*/
|
||||||
|
private Color getRandColor(int fc, int bc) {
|
||||||
|
if (fc > 255)
|
||||||
|
fc = 255;
|
||||||
|
if (bc > 255)
|
||||||
|
bc = 255;
|
||||||
|
int r = fc + random.nextInt(bc - fc - 16);
|
||||||
|
int g = fc + random.nextInt(bc - fc - 14);
|
||||||
|
int b = fc + random.nextInt(bc - fc - 18);
|
||||||
|
return new Color(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机图片
|
||||||
|
*/
|
||||||
|
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
|
||||||
|
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,该对象可以在图像上进行各种绘制操作
|
||||||
|
g.fillRect(0, 0, width, height);
|
||||||
|
g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
|
||||||
|
g.setColor(getRandColor(110, 133));
|
||||||
|
// 绘制干扰线
|
||||||
|
for (int i = 0; i <= lineSize; i++) {
|
||||||
|
drowLine(g);
|
||||||
|
}
|
||||||
|
// 绘制随机字符
|
||||||
|
String randomString = "";
|
||||||
|
for (int i = 1; i <= stringNum; i++) {
|
||||||
|
randomString = drowString(g, randomString, i);
|
||||||
|
}
|
||||||
|
session.removeAttribute(RANDOMVALIDATECODE);
|
||||||
|
session.setAttribute(RANDOMVALIDATECODE, randomString);
|
||||||
|
g.dispose();
|
||||||
|
try {
|
||||||
|
ImageIO.write(image, "JPEG", response.getOutputStream());// 将内存中的图片通过流动形式输出到客户端
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制字符串
|
||||||
|
*/
|
||||||
|
private String drowString(Graphics g, String randomString, int i) {
|
||||||
|
g.setFont(getFont());
|
||||||
|
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random.nextInt(121)));
|
||||||
|
String rand = getRandomString(random.nextInt(randString.length()));
|
||||||
|
randomString += rand;
|
||||||
|
g.translate(random.nextInt(3), random.nextInt(3));
|
||||||
|
g.drawString(rand, 13 * i, 16);
|
||||||
|
return randomString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制干扰线
|
||||||
|
*/
|
||||||
|
private void drowLine(Graphics g) {
|
||||||
|
int x = random.nextInt(width);
|
||||||
|
int y = random.nextInt(height);
|
||||||
|
int xl = random.nextInt(13);
|
||||||
|
int yl = random.nextInt(15);
|
||||||
|
g.drawLine(x, y, x + xl, y + yl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取随机的字符
|
||||||
|
*/
|
||||||
|
public String getRandomString(int num) {
|
||||||
|
return String.valueOf(randString.charAt(num));
|
||||||
|
}
|
||||||
|
}
|
4
src/config.properties
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
driverClass=com.mysql.cj.jdbc.Driver
|
||||||
|
url=jdbc:mysql://127.0.0.1:3306/webguestbook?serverTimezone=GMT%2B8
|
||||||
|
user=root
|
||||||
|
password=1611
|
140
web/System/index.jsp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: LDQ
|
||||||
|
Date: 2023/6/8
|
||||||
|
Time: 19:48
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>留言本管理</title>
|
||||||
|
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<!-- 引入 layui.css -->
|
||||||
|
<link href="//unpkg.com/layui@2.8.0/dist/css/layui.css" rel="stylesheet">
|
||||||
|
<meta name="renderer" content="webkit">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<%-- <script type="text/javascript" src="./static/layui/layui.js"></script>--%>
|
||||||
|
<%-- <link rel="stylesheet" type="text/css" href="./static/layui/css/layui.css">--%>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="layui-layout layui-layout-admin">
|
||||||
|
<div class="layui-header">
|
||||||
|
<div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
|
||||||
|
<!-- 头部区域(可配合layui 已有的水平导航) -->
|
||||||
|
<ul class="layui-nav layui-layout-left">
|
||||||
|
<!-- 移动端显示 -->
|
||||||
|
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
|
||||||
|
<i class="layui-icon layui-icon-spread-left"></i>
|
||||||
|
</li>
|
||||||
|
<li class="layui-nav-item layui-hide-xs"><a href="javascript:;">nav 1</a></li>
|
||||||
|
<li class="layui-nav-item layui-hide-xs"><a href="javascript:;">nav 2</a></li>
|
||||||
|
<li class="layui-nav-item layui-hide-xs"><a href="javascript:;">nav 3</a></li>
|
||||||
|
<li class="layui-nav-item">
|
||||||
|
<a href="javascript:;">nav groups</a>
|
||||||
|
<dl class="layui-nav-child">
|
||||||
|
<dd><a href="javascript:;">menu 11</a></dd>
|
||||||
|
<dd><a href="javascript:;">menu 22</a></dd>
|
||||||
|
<dd><a href="javascript:;">menu 33</a></dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="layui-nav layui-layout-right">
|
||||||
|
<li class="layui-nav-item layui-hide layui-show-sm-inline-block">
|
||||||
|
<a href="javascript:;">
|
||||||
|
<img src="https://unpkg.com/outeres@0.0.10/img/layui/icon-v2.png" class="layui-nav-img">
|
||||||
|
tester
|
||||||
|
</a>
|
||||||
|
<dl class="layui-nav-child">
|
||||||
|
<dd><a href="javascript:;">Your Profile</a></dd>
|
||||||
|
<dd><a href="javascript:;">Settings</a></dd>
|
||||||
|
<dd><a href="javascript:;">Sign out</a></dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
|
||||||
|
<a href="javascript:;">
|
||||||
|
<i class="layui-icon layui-icon-more-vertical"></i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="layui-side layui-bg-black">
|
||||||
|
<div class="layui-side-scroll">
|
||||||
|
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
|
||||||
|
<ul class="layui-nav layui-nav-tree" lay-filter="test">
|
||||||
|
<li class="layui-nav-item layui-nav-itemed">
|
||||||
|
<a class="" href="javascript:;">menu group 1</a>
|
||||||
|
<dl class="layui-nav-child">
|
||||||
|
<dd><a href="javascript:;">menu 1</a></dd>
|
||||||
|
<dd><a href="javascript:;">menu 2</a></dd>
|
||||||
|
<dd><a href="javascript:;">menu 3</a></dd>
|
||||||
|
<dd><a href="javascript:;">the links</a></dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
<li class="layui-nav-item">
|
||||||
|
<a href="javascript:;">menu group 2</a>
|
||||||
|
<dl class="layui-nav-child">
|
||||||
|
<dd><a href="javascript:;">list 1</a></dd>
|
||||||
|
<dd><a href="javascript:;">list 2</a></dd>
|
||||||
|
<dd><a href="javascript:;">超链接</a></dd>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
<li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
|
||||||
|
<li class="layui-nav-item"><a href="javascript:;">the links</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-body">
|
||||||
|
<!-- 内容主体区域 -->
|
||||||
|
<div style="padding: 15px;">
|
||||||
|
<blockquote class="layui-elem-quote layui-text">
|
||||||
|
Layui 框体布局内容主体区域
|
||||||
|
</blockquote>
|
||||||
|
<div class="layui-card layui-panel">
|
||||||
|
<div class="layui-card-header">
|
||||||
|
下面是充数内容,为的是出现滚动条
|
||||||
|
</div>
|
||||||
|
<div class="layui-card-body">
|
||||||
|
充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>充数内容<br>你还真滑到了底部呀
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-footer">
|
||||||
|
<!-- 底部固定区域 -->
|
||||||
|
底部固定区域
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="/cdn.staticfile.org/layui/2.8.0/layui.js"></script>
|
||||||
|
<script>
|
||||||
|
//JS
|
||||||
|
layui.use(['element', 'layer', 'util'], function(){
|
||||||
|
var element = layui.element;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var util = layui.util;
|
||||||
|
var $ = layui.$;
|
||||||
|
//头部事件
|
||||||
|
util.event('lay-header-event', {
|
||||||
|
menuLeft: function(othis){ // 左侧菜单事件
|
||||||
|
layer.msg('展开左侧菜单的操作', {icon: 0});
|
||||||
|
},
|
||||||
|
menuRight: function(){ // 右侧菜单事件
|
||||||
|
layer.open({
|
||||||
|
type: 1
|
||||||
|
,title: '更多'
|
||||||
|
,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
|
||||||
|
,area: ['260px', '100%']
|
||||||
|
,offset: 'rt' //右上角
|
||||||
|
,anim: 'slideLeft'
|
||||||
|
,shadeClose: true
|
||||||
|
,scrollbar: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
6
web/WEB-INF/web.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
version="4.0">
|
||||||
|
</web-app>
|
16
web/error.jsp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: LDQ
|
||||||
|
Date: 2023/6/9
|
||||||
|
Time: 1:32
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${errorMsg}
|
||||||
|
</body>
|
||||||
|
</html>
|
450
web/index.jsp
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
<%--
|
||||||
|
Created by IntelliJ IDEA.
|
||||||
|
User: landaiqing
|
||||||
|
Date: 2023/6/8
|
||||||
|
Time: 19:20
|
||||||
|
To change this template use File | Settings | File Templates.
|
||||||
|
--%>
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>留言本</title>
|
||||||
|
<%-- Lay-ui组件库--%>
|
||||||
|
<%-- <script type="text/javascript" src="./static/layui/layui.js"></script>--%>
|
||||||
|
<%-- <%– Lay-ui样式–%>--%>
|
||||||
|
<%-- <link rel="stylesheet" type="text/css" href="./static/layui/css/layui.css">--%>
|
||||||
|
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||||
|
<!-- 引入 layui.css -->
|
||||||
|
<link href="//unpkg.com/layui@2.8.0/dist/css/layui.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- 引入 layui.js -->
|
||||||
|
<script src="//unpkg.com/layui@2.8.0/dist/layui.js">
|
||||||
|
|
||||||
|
// <link rel="stylesheet" href="./static/css/index.css" type="text/css">
|
||||||
|
|
||||||
|
// <script language=JavaScript type="text/javascript" src="static/js/index.js"></script>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
@IMPORT url("./static/css/index.css");
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<div class="header">
|
||||||
|
<div style="display: flex;flex-direction: row;flex-wrap: nowrap;align-items: center;">
|
||||||
|
<div style="width: 570px;height: 45px;">
|
||||||
|
<span style="font-size: 2rem;font-weight: 700;font-family: FZShuTi;color:coral;">留 言 本</span>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="layui-btn layui-btn-warm layui-btn-radius" lay-on="wrap">
|
||||||
|
<i class="layui-icon layui-icon-edit"></i>
|
||||||
|
发布留言
|
||||||
|
</button>
|
||||||
|
<!-- <button type="button" class="layui-btn layui-btn-radius" lay-on="admin">
|
||||||
|
<i class="layui-icon layui-icon-set-fill"></i>
|
||||||
|
管理
|
||||||
|
</button> -->
|
||||||
|
<div>
|
||||||
|
<ul class="layui-nav" style="background: transparent;">
|
||||||
|
<li class="layui-nav-item" lay-unselect>
|
||||||
|
<a href="javascript:;">
|
||||||
|
<img src="./static/img/touxiang.png" class="layui-nav-img">
|
||||||
|
</a>
|
||||||
|
<dl class="layui-nav-child">
|
||||||
|
<button type="button" class="layui-btn layui-btn-radius" lay-on="admin">
|
||||||
|
<i class="layui-icon layui-icon-set-fill"></i>
|
||||||
|
管理
|
||||||
|
</button>
|
||||||
|
</dl>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<blockquote class="layui-elem-quote layui-text">
|
||||||
|
留言列表
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<!-- 管理员登陆 -->
|
||||||
|
<div class="layui-form" id="adminform" lay-filter="filter-test-layer" style="margin: 16px;display: none;">
|
||||||
|
<form action="/Guestbook_war_exploded/login" method="post">
|
||||||
|
<div class="demo-login-container">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-username"></i>
|
||||||
|
</div>
|
||||||
|
<input type="text" name="username" value="" lay-verify="required" placeholder="用户名"
|
||||||
|
lay-reqtext="请填写用户名" autocomplete="off" class="layui-input" lay-affix="clear">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-password"></i>
|
||||||
|
</div>
|
||||||
|
<input type="password" name="password" value="" lay-verify="required" placeholder="密 码"
|
||||||
|
lay-reqtext="请填写密码" autocomplete="off" class="layui-input" lay-affix="eye">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col-xs7">
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-vercode"></i>
|
||||||
|
</div>
|
||||||
|
<input type="text" name="code" value="" lay-verify="required" placeholder="验证码"
|
||||||
|
lay-reqtext="请填写验证码" autocomplete="off" class="layui-input" lay-affix="clear">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-col-xs5">
|
||||||
|
<div style="margin-left: 10px;">
|
||||||
|
<img src=VerifycodeServlet
|
||||||
|
onclick="this.src='VerifycodeServlet?'+ new Date().getTime();">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<input type="checkbox" name="remember" lay-skin="primary" title="记住密码">
|
||||||
|
</div>
|
||||||
|
<%-- <div class="layui-form-item">--%>
|
||||||
|
<%-- <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo-login">登录</button>--%>
|
||||||
|
<%-- </div>--%>
|
||||||
|
<input type="submit" value="注册"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 发布留言的主体 -->
|
||||||
|
<div class="wrap" id="warp" style="display: none;">
|
||||||
|
<div class="userIfo">
|
||||||
|
<div class="layui-panel">
|
||||||
|
<div style="padding: 32px;" class="panel">
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-username"></i>
|
||||||
|
</div>
|
||||||
|
<input type="text" placeholder="昵称" class="layui-input">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-login-qq"></i>
|
||||||
|
</div>
|
||||||
|
<input type="text" placeholder="QQ" class="layui-input">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-input-wrap">
|
||||||
|
<div class="layui-input-prefix">
|
||||||
|
<i class="layui-icon layui-icon-email"></i>
|
||||||
|
</div>
|
||||||
|
<input type="text" placeholder="Email" class="layui-input">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-panel">
|
||||||
|
<div class="wrap-head">
|
||||||
|
<div class="head-logo">
|
||||||
|
<img src="./static/img/留言.png" style="height: 20px;width: 20px;" />
|
||||||
|
</div>
|
||||||
|
<div class="head-txt">
|
||||||
|
<a class="title-txt"
|
||||||
|
href="javascript:void(0)">111111111111111111111111111 热门</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main-txt">
|
||||||
|
<textarea name="" rows="" cols="" class="main-area"></textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="warp-footer">
|
||||||
|
<div class="warp-icon-cont">
|
||||||
|
<ul>
|
||||||
|
<li><img src="./static/img/发表情.png" alt="" />
|
||||||
|
<a href="javascript:void(0)">表情</a>
|
||||||
|
</li>
|
||||||
|
<li><img src="./static/img/图片_填充.png" alt="" />
|
||||||
|
<a href="javascript:void(0)">图片</a>
|
||||||
|
</li>
|
||||||
|
<li><img src="./static/img/视频_填充.png" alt="" />
|
||||||
|
<a href="javascript:void(0)">视频</a>
|
||||||
|
</li>
|
||||||
|
<li><img src="./static/img/话题选中.png" alt="" />
|
||||||
|
<a href="javascript:void(0)">话题</a>
|
||||||
|
</li>
|
||||||
|
<li><img src="./static/img/文章.png" alt="" />
|
||||||
|
<a href="javascript:void(0)">文章</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="warp-footer-btns">
|
||||||
|
<div class="release-btn">
|
||||||
|
<a href="javascript:void(0)">发布</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 显示留言的主体 -->
|
||||||
|
<div class="show">
|
||||||
|
<div class="show-content">
|
||||||
|
<div class="show-name">
|
||||||
|
<div class="avtors"><img src="./static/img/touxiang.png" alt="" style="width: 40px;height: 40px;border-radius: 50%;"></div>
|
||||||
|
<span style="margin-left: 10px;font-size: 1rem;">Xx</span>
|
||||||
|
</div>
|
||||||
|
<div class="show-txt">
|
||||||
|
<p class="">这是内容111111111111111111111111111111111111111111111111111111111</p>
|
||||||
|
</div>
|
||||||
|
<div class="show-time">2018年10月24日</div>
|
||||||
|
<!-- <button type="button" class="layui-btn layui-btn-xs" lay-on="wrap">
|
||||||
|
<i class="layui-icon layui-icon-release"></i> 回复
|
||||||
|
</button> -->
|
||||||
|
<div class="layui-panel">
|
||||||
|
|
||||||
|
<div class="comments">
|
||||||
|
|
||||||
|
<div class="comment-wrap">
|
||||||
|
<div class="photo">
|
||||||
|
<div class="avatar" style="background-image: url('./static/img/touxiang.png')"></div>
|
||||||
|
</div>
|
||||||
|
<div class="comment-block">
|
||||||
|
<form action="">
|
||||||
|
<textarea name="" id="" cols="30" rows="3" placeholder="Say somthing..." style="resize:none"></textarea>
|
||||||
|
<button type="button" class="layui-btn layui-btn-xs">
|
||||||
|
<i class="layui-icon layui-icon-release"></i> 回复
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="comment-wrap">
|
||||||
|
<div class="photo">
|
||||||
|
<div class="avatar" style="background-image: url('./static/img/touxiang.png')"></div>
|
||||||
|
</div>
|
||||||
|
<div class="comment-block">
|
||||||
|
<p class="comment-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto temporibus iste nostrum dolorem natus recusandae incidunt voluptatum. Eligendi voluptatum ducimus architecto tempore, quaerat explicabo veniam fuga corporis totam reprehenderit
|
||||||
|
quasi sapiente modi tempora at perspiciatis mollitia, dolores voluptate. Cumque, corrupti?</p>
|
||||||
|
<div class="bottom-comment">
|
||||||
|
<div class="comment-date">23.5 2014</div>
|
||||||
|
<ul class="comment-actions">
|
||||||
|
<li class="complain">Complain</li>
|
||||||
|
<li class="reply">Reply</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="show-close">x</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(function () {
|
||||||
|
var $ = layui.$;
|
||||||
|
var layer = layui.layer;
|
||||||
|
var util = layui.util;
|
||||||
|
var form = layui.form;
|
||||||
|
|
||||||
|
util.on('lay-on', {
|
||||||
|
|
||||||
|
'wrap': function () {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
resize: true,
|
||||||
|
title: '发表留言',
|
||||||
|
shade: false, // 不显示遮罩
|
||||||
|
content: $('#warp'), // 捕获的元素
|
||||||
|
end: function () {
|
||||||
|
// layer.msg('关闭后的回调', {icon:6});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'admin': function () {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
area: '350px',
|
||||||
|
resize: false,
|
||||||
|
shadeClose: true,
|
||||||
|
title: '管理员登录',
|
||||||
|
content: $('#adminform'),
|
||||||
|
}, )
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 匿名函数包裹,防止外界操作的修改
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
// 还能输入的字得个数
|
||||||
|
var able_count = 140;
|
||||||
|
// 是否可以发布留言
|
||||||
|
var release_able = false;
|
||||||
|
// 右上角文字
|
||||||
|
var $title_txt = $('.title-txt');
|
||||||
|
// 留言框
|
||||||
|
var $main_area = $('.main-area');
|
||||||
|
// 发布按钮
|
||||||
|
var $release_btn = $('.release-btn');
|
||||||
|
|
||||||
|
// 输入框获取焦点
|
||||||
|
$main_area.focus(function () {
|
||||||
|
console.log("获取焦点");
|
||||||
|
$(this).parent().addClass('outline');
|
||||||
|
$title_txt.addClass('title');
|
||||||
|
if (able_count >= 0) {
|
||||||
|
$title_txt.html("还可以输入" + able_count + "个字");
|
||||||
|
} else {
|
||||||
|
$title_txt.html("你以超出" + (-able_count) + "个字");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 输入框失去焦点
|
||||||
|
$main_area.blur(function () {
|
||||||
|
console.log("失去焦点");
|
||||||
|
$(this).parent().removeClass('outline');
|
||||||
|
$title_txt.removeClass('title');
|
||||||
|
$title_txt.html("111");
|
||||||
|
})
|
||||||
|
|
||||||
|
// 输入框文本修改
|
||||||
|
$main_area.on('input', function () {
|
||||||
|
console.log("文本修改");
|
||||||
|
// 剩余可输入的字个数
|
||||||
|
able_count = 140 - $main_area.val().length;
|
||||||
|
// console.log(able_count);
|
||||||
|
// 根据可输入字的个数决定右上角文本的提示 与 是否能发布的状态
|
||||||
|
if (able_count >= 0 && able_count <= 140) {
|
||||||
|
$title_txt.html("还可以输入" + able_count + "个字");
|
||||||
|
if (able_count != 140) {
|
||||||
|
release_able = true;
|
||||||
|
} else {
|
||||||
|
release_able = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$title_txt.html("你以超出" + (-able_count) + "个字");
|
||||||
|
release_able = false;
|
||||||
|
}
|
||||||
|
// 根据发布状态决定发布按钮的样式
|
||||||
|
if (release_able) {
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: "orange",
|
||||||
|
borderColor: "orange"
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: "#ffc09f",
|
||||||
|
borderColor: "#ffc09f"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发布事件
|
||||||
|
$release_btn.click(function () {
|
||||||
|
console.log("发布");
|
||||||
|
if (release_able) {
|
||||||
|
console.log('可以发布');
|
||||||
|
// 创建show对象的各个部位
|
||||||
|
var $showContent = $('<div class="show-content"></div>'),
|
||||||
|
$showName = $('<div class="show-name"></div>'),
|
||||||
|
$showTxt = $('<div class="show-txt"></div>'),
|
||||||
|
$showTime = $('<div class="show-time"></div>'),
|
||||||
|
$showClose = $('<div class="show-close"></div>'),
|
||||||
|
$showP = $('<p class=""></p>');
|
||||||
|
|
||||||
|
var date = new Date();
|
||||||
|
// 设置,对象结构内内容
|
||||||
|
$showName.text("XxXx");
|
||||||
|
$showP.text($main_area.val());
|
||||||
|
$showTime.text(date);
|
||||||
|
$showClose.text("x");
|
||||||
|
// 添加进入主结构
|
||||||
|
$showTxt.append($showP);
|
||||||
|
$showContent.append($showName);
|
||||||
|
$showContent.append($showTxt);
|
||||||
|
$showContent.append($showTime);
|
||||||
|
$showContent.append($showClose);
|
||||||
|
|
||||||
|
// 向所有匹配元素内部的开始处插入内容
|
||||||
|
$('.show').prepend($showContent);
|
||||||
|
|
||||||
|
// 添加动画
|
||||||
|
// 位置从输入框处下移
|
||||||
|
$showContent.css({
|
||||||
|
top: '-150px'
|
||||||
|
})
|
||||||
|
$showContent.animate({
|
||||||
|
top: 0
|
||||||
|
}, 200)
|
||||||
|
|
||||||
|
// 删除事件
|
||||||
|
$showClose.click(function () {
|
||||||
|
// 显示插入的索引位置
|
||||||
|
// console.log($(this).parent().index());
|
||||||
|
// console.log($showContent.index());
|
||||||
|
|
||||||
|
|
||||||
|
// 删除操作为顺便
|
||||||
|
// $showContent.remove();
|
||||||
|
|
||||||
|
// 使用删除动画,创建效果
|
||||||
|
$showContent.animate({
|
||||||
|
height: 0
|
||||||
|
}, 200, function () {
|
||||||
|
// 动画结束后将自身从dom中移除
|
||||||
|
$showContent.remove();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发布成功后收尾工作
|
||||||
|
$main_area.val(""); //输入框清空
|
||||||
|
able_count = 140; //输入框可输入内容数重置
|
||||||
|
release_able = false;
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: '#ffc09f',
|
||||||
|
borderColor: '#ffc09f'
|
||||||
|
}) //按钮点击事件重置
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
351
web/static/css/index.css
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
body, ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* main */
|
||||||
|
.main {
|
||||||
|
width: 800px;
|
||||||
|
height: 100%;
|
||||||
|
/* background-color: #eb7350; */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* header */
|
||||||
|
|
||||||
|
.header{
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
/* background-color: #ddd; */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
/* align-items: center; */
|
||||||
|
/* justify-content: flex-end; */
|
||||||
|
}
|
||||||
|
.userIfo {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.panel{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-panel {
|
||||||
|
background:transparent;
|
||||||
|
}
|
||||||
|
.admin {
|
||||||
|
width: 350px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
/* 管理员登陆 */
|
||||||
|
.demo-login-container{width: 320px; margin: 21px auto 0;}
|
||||||
|
.demo-login-other .layui-icon{position: relative; display: inline-block; margin: 0 2px; top: 2px; font-size: 26px;}
|
||||||
|
|
||||||
|
|
||||||
|
/*最外层*/
|
||||||
|
.wrap {
|
||||||
|
width: 700px;
|
||||||
|
height: 325px;
|
||||||
|
margin: 20px auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
/* border: 1px solid #ddd; */
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap-head {
|
||||||
|
width: 100%;
|
||||||
|
height: 24px;
|
||||||
|
padding-top: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo {
|
||||||
|
width: 40%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-logo img {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-txt {
|
||||||
|
padding: 4px 0;
|
||||||
|
width: 60%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-txt a {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #eb7350;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.title-txt.title {
|
||||||
|
text-align: right;
|
||||||
|
color: black;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*内层设计,输入框*/
|
||||||
|
.main-txt {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
width: 98%;
|
||||||
|
height: 68px;
|
||||||
|
margin: 4px 0 0;
|
||||||
|
padding: 5px;
|
||||||
|
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-txt textarea {
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 66px;
|
||||||
|
outline: none;
|
||||||
|
resize: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.main-txt.outline {
|
||||||
|
outline: 2px orange solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*下层设计*/
|
||||||
|
.warp-footer {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
margin: 6px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-icon-cont {
|
||||||
|
width: 65%;
|
||||||
|
float: left;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-icon-cont ul li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-icon-cont a {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
text-decoration: none;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: 5px;
|
||||||
|
display: block;
|
||||||
|
width: 25px;
|
||||||
|
float: right;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-icon-cont a:hover {
|
||||||
|
color: #eb7350;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-icon-cont img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warp-footer-btns {
|
||||||
|
width: 35%;
|
||||||
|
float: right;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-btn {
|
||||||
|
width: 80px;
|
||||||
|
height: 28px;
|
||||||
|
float: right;
|
||||||
|
background-color: #ffc09f;
|
||||||
|
border: 4px solid #fbbd9e;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.release-btn a {
|
||||||
|
display: block;
|
||||||
|
color: #fff;
|
||||||
|
width: 80px;
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*后期添加的留言框*/
|
||||||
|
.show {
|
||||||
|
width: 800px;
|
||||||
|
/* margin: 20px auto; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-content {
|
||||||
|
width: 775px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-name {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-txt {
|
||||||
|
width: 100%;
|
||||||
|
color: #444;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-txt p {
|
||||||
|
width: 100%;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #808080;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #ccc;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-close:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* html,
|
||||||
|
body {
|
||||||
|
background-color: #f0f2fa;
|
||||||
|
font-family: "PT Sans", "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
|
||||||
|
color: #555f77;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
} */
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-family: "PT Sans", "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #555f77;
|
||||||
|
}
|
||||||
|
input::-webkit-input-placeholder,
|
||||||
|
textarea::-webkit-input-placeholder {
|
||||||
|
color: #ced2db;
|
||||||
|
}
|
||||||
|
input::-moz-placeholder,
|
||||||
|
textarea::-moz-placeholder {
|
||||||
|
color: #ced2db;
|
||||||
|
}
|
||||||
|
input:-moz-placeholder,
|
||||||
|
textarea:-moz-placeholder {
|
||||||
|
color: #ced2db;
|
||||||
|
}
|
||||||
|
input:-ms-input-placeholder,
|
||||||
|
textarea:-ms-input-placeholder {
|
||||||
|
color: #ced2db;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 1.3125rem;
|
||||||
|
}
|
||||||
|
.comments {
|
||||||
|
margin: 2.5rem auto 0;
|
||||||
|
max-width: 60.75rem;
|
||||||
|
padding: 0 1.25rem;
|
||||||
|
}
|
||||||
|
.comment-wrap {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 5.3125rem;
|
||||||
|
}
|
||||||
|
.photo {
|
||||||
|
padding-top: 0.625rem;
|
||||||
|
display: table-cell;
|
||||||
|
width: 3.5rem;
|
||||||
|
}
|
||||||
|
.photo .avatar {
|
||||||
|
height: 2.25rem;
|
||||||
|
width: 2.25rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
.comment-block {
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: #fff;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: top;
|
||||||
|
border-radius: 0.1875rem;
|
||||||
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
.comment-block textarea {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.comment-text {
|
||||||
|
margin-bottom: 1.25rem;
|
||||||
|
}
|
||||||
|
.bottom-comment {
|
||||||
|
color: #acb4c2;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
.comment-date {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.comment-actions {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.comment-actions li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.comment-actions li.complain {
|
||||||
|
padding-right: 0.625rem;
|
||||||
|
border-right: 1px solid #e1e5eb;
|
||||||
|
}
|
||||||
|
.comment-actions li.reply {
|
||||||
|
padding-left: 0.625rem;
|
||||||
|
}
|
BIN
web/static/img/touxiang.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
web/static/img/发表情.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
web/static/img/图片_填充.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
web/static/img/文章.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
web/static/img/留言.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
web/static/img/视频_填充.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
web/static/img/话题选中.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
142
web/static/js/index.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// 匿名函数包裹,防止外界操作的修改
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
// 还能输入的字得个数
|
||||||
|
var able_count = 140;
|
||||||
|
// 是否可以发布留言
|
||||||
|
var release_able = false;
|
||||||
|
// 右上角文字
|
||||||
|
var $title_txt = $('.title-txt');
|
||||||
|
// 留言框
|
||||||
|
var $main_area = $('.main-area');
|
||||||
|
// 发布按钮
|
||||||
|
var $release_btn = $('.release-btn');
|
||||||
|
|
||||||
|
// 输入框获取焦点
|
||||||
|
$main_area.focus(function () {
|
||||||
|
console.log("获取焦点");
|
||||||
|
$(this).parent().addClass('outline');
|
||||||
|
$title_txt.addClass('title');
|
||||||
|
if (able_count >= 0) {
|
||||||
|
$title_txt.html("还可以输入" + able_count + "个字");
|
||||||
|
} else {
|
||||||
|
$title_txt.html("你以超出" + (-able_count) + "个字");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 输入框失去焦点
|
||||||
|
$main_area.blur(function () {
|
||||||
|
console.log("失去焦点");
|
||||||
|
$(this).parent().removeClass('outline');
|
||||||
|
$title_txt.removeClass('title');
|
||||||
|
$title_txt.html("111");
|
||||||
|
})
|
||||||
|
|
||||||
|
// 输入框文本修改
|
||||||
|
$main_area.on('input', function () {
|
||||||
|
console.log("文本修改");
|
||||||
|
// 剩余可输入的字个数
|
||||||
|
able_count = 140 - $main_area.val().length;
|
||||||
|
// console.log(able_count);
|
||||||
|
// 根据可输入字的个数决定右上角文本的提示 与 是否能发布的状态
|
||||||
|
if (able_count >= 0 && able_count <= 140) {
|
||||||
|
$title_txt.html("还可以输入" + able_count + "个字");
|
||||||
|
if (able_count != 140) {
|
||||||
|
release_able = true;
|
||||||
|
} else {
|
||||||
|
release_able = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$title_txt.html("你以超出" + (-able_count) + "个字");
|
||||||
|
release_able = false;
|
||||||
|
}
|
||||||
|
// 根据发布状态决定发布按钮的样式
|
||||||
|
if (release_able) {
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: "orange",
|
||||||
|
borderColor: "orange"
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: "#ffc09f",
|
||||||
|
borderColor: "#ffc09f"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发布事件
|
||||||
|
$release_btn.click(function () {
|
||||||
|
console.log("发布");
|
||||||
|
if (release_able) {
|
||||||
|
console.log('可以发布');
|
||||||
|
// 创建show对象的各个部位
|
||||||
|
var $showContent = $('<div class="show-content"></div>'),
|
||||||
|
$showName = $('<div class="show-name"></div>'),
|
||||||
|
$showTxt = $('<div class="show-txt"></div>'),
|
||||||
|
$showTime = $('<div class="show-time"></div>'),
|
||||||
|
$showClose = $('<div class="show-close"></div>'),
|
||||||
|
$showP = $('<p class=""></p>');
|
||||||
|
|
||||||
|
var date = new Date();
|
||||||
|
// 设置,对象结构内内容
|
||||||
|
$showName.text("XxXx");
|
||||||
|
$showP.text($main_area.val());
|
||||||
|
$showTime.text(date);
|
||||||
|
$showClose.text("x");
|
||||||
|
// 添加进入主结构
|
||||||
|
$showTxt.append($showP);
|
||||||
|
$showContent.append($showName);
|
||||||
|
$showContent.append($showTxt);
|
||||||
|
$showContent.append($showTime);
|
||||||
|
$showContent.append($showClose);
|
||||||
|
|
||||||
|
// 向所有匹配元素内部的开始处插入内容
|
||||||
|
$('.show').prepend($showContent);
|
||||||
|
|
||||||
|
// 添加动画
|
||||||
|
// 位置从输入框处下移
|
||||||
|
$showContent.css({
|
||||||
|
top: '-150px'
|
||||||
|
})
|
||||||
|
$showContent.animate({
|
||||||
|
top: 0
|
||||||
|
}, 200)
|
||||||
|
|
||||||
|
// 删除事件
|
||||||
|
$showClose.click(function () {
|
||||||
|
// 显示插入的索引位置
|
||||||
|
// console.log($(this).parent().index());
|
||||||
|
// console.log($showContent.index());
|
||||||
|
|
||||||
|
|
||||||
|
// 删除操作为顺便
|
||||||
|
// $showContent.remove();
|
||||||
|
|
||||||
|
// 使用删除动画,创建效果
|
||||||
|
$showContent.animate({
|
||||||
|
height: 0
|
||||||
|
}, 200, function () {
|
||||||
|
// 动画结束后将自身从dom中移除
|
||||||
|
$showContent.remove();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发布成功后收尾工作
|
||||||
|
$main_area.val(""); //输入框清空
|
||||||
|
able_count = 140; //输入框可输入内容数重置
|
||||||
|
release_able = false;
|
||||||
|
$release_btn.css({
|
||||||
|
backgroundColor: '#ffc09f',
|
||||||
|
borderColor: '#ffc09f'
|
||||||
|
}) //按钮点击事件重置
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
1
web/static/layui/css/layui.css
Normal file
BIN
web/static/layui/font/iconfont.eot
Normal file
405
web/static/layui/font/iconfont.svg
Normal file
After Width: | Height: | Size: 322 KiB |