文章目录
目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、环境搭配
1.利用maven构建一个webApp
配置pom文件
<?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>com.bjpowernode</groupId>
<artifactId>springmvc_ssm</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>springmvc_ssm Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--集中定义依赖版本号-->
<!--单元测试的依赖-->
<junit.version>4.13.2</junit.version>
<!--spring的相关依赖-->
<spring.version>5.3.21</spring.version>
<!--mybatis的相关依赖-->
<mybatis.version>3.5.6</mybatis.version>
<!--mybatis与spring整合的依赖-->
<mybatis.spring.version>1.3.1</mybatis.spring.version>
<!--mybatis支持的分页插件的依赖 使用jsp写前端用得到 使用vue用不到 这次用不到-->
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<!--mysql的依赖-->
<mysql.version>8.0.28</mysql.version>
<!--日志的依赖-->
<slf4j.version>1.6.4</slf4j.version>
<!--数据库连接池的依赖-->
<druid.version>1.2.8</druid.version>
<!--分页插件自己的依赖 这次用不到-->
<pagehelper.version>5.3.0</pagehelper.version>
<!--jsp标准标签库的依赖-->
<jstl.version>1.2</jstl.version>
<!--servlet的依赖-->
<servlet-api.version>4.0.1</servlet-api.version>
<!--jsp依赖 加不加都可以-->
<jsp-api.version>2.0</jsp-api.version>
<!--jackson的依赖,springmvc框架默认进行JSON转换的依赖工具-->
<jackson.version>2.13.2</jackson.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis.paginator.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
<version>${jsp-api.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<!-- poi依赖-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
</dependencies>
<build>
<finalName>springmvc_ssm</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<!--识别所有的配置文件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
引入完毕后构建相对应的包结构
.因为webapp目录下 image 和jquery 两个包都是 引入的 不重要的资源 可以直接访问
但WEB-INF下的资源不可直接访问 必须通过Controller层 来跳转
.java层的包 和 pages下的包一一对应方便管理 每一个前端模块都有对应的 四个domain mapper service web(controller)这四个子包
.接下就是资源文件的配置 里面包含 配置视图解析器等等 连接数据库等等
注意!
小猫咪的配置必须和项目名一致!!!!!!!!!(要不然出问题,亲测)
二、登录模块编写
1. 梳理客户需求 画出流程图
先从被依赖的底层写起
观察user表
mapper层
接口和xml
User selectByPwd(Map<String,Object> map);
<!--1.查找:根据用户账号密码返回用户User 对象 传进来的参数用map封装-->
<select id="selectByPwd" parameterType="map" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from tbl_user where login_act = #{loginAct} and login_pwd = #{loginPwd}
</select>
UserService层
User selectByPwd(Map<String,Object> map);
public User selectByPwd(Map<String, Object> map) {
return userMapper.selectByPwd(map);
}
//1.判断是否可以登录
@Override
public Object isLogin(Map<String, Object> map, HttpServletRequest request, HttpServletResponse response, String isRemPwd) {
User user = selectByPwd(map);
returnObject returnObject = new returnObject(); //给前端的数据对象
if (user == null) {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("用户名密码错误,请重新输入");
} else {
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String nowTime = sdf.format(new Date());
if ( DataUtils.format(new Date()).compareTo(user.getExpireTime())>0) {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("登录失败,账号注册时间过期");
}else if (!user.getAllowIps().contains(request.getRemoteAddr())){
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage(contant.RETURN_CODE_FAIL);
} else if ("0".equals(user.getLockState())) {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("登录失败,状态锁定");
}else {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
returnObject.setMessage("登陆成功");
HttpSession session = request.getSession();
session.setAttribute(contant.SESSION_USER,user); //传入session域
//如果要记住密码 则往外写入cookie
if ("true".equals(isRemPwd)){
System.out.println(isRemPwd);
Cookie c1 = new Cookie("loginAct", user.getLoginAct());
c1.setMaxAge(10*24*60*60);
response.addCookie(c1);
Cookie c2 = new Cookie("loginPwd", user.getLoginPwd());
c2.setMaxAge(10*24*60*60);
response.addCookie(c2);
}else {
//把没有过期的cookie删除
Cookie c1 = new Cookie("loginAct", "1");
c1.setMaxAge(0);
Cookie c2 = new Cookie("loginPwd", "2");
c2.setMaxAge(0);
response.addCookie(c1);
response.addCookie(c2);
}
}
}
return returnObject;
}
controller层
@RequestMapping("/settings/qx/user/Login.do")
尽量和前端资源路径 保持一致
@ResponseBody
为了返回returnObject 加上的
@RequestMapping("/settings/qx/user/Login.do")
@ResponseBody
public Object StartLogin(String loginAct, String loginPwd, HttpServletRequest request, HttpServletResponse response,String isRemPwd){
Map<String, Object> map = new HashMap<>();
map.put("loginAct",loginAct);
map.put("loginPwd",loginPwd);
return userLoginService.isLogin(map,request,response,isRemPwd);
}
前端
<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
<div style="position: absolute; top: 0px; right: 60px;">
<div class="page-header">
<h1>登录</h1>
</div>
<form action="workbench/index.html" class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<div style="width: 350px;">
<input class="form-control" id="loginAct" type="text" value="${cookie.loginAct.value}" placeholder="用户名">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" id="loginPwd" type="password" value="${cookie.loginPwd.value}" placeholder="密码">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd" checked>
</c:if>
<c:if test="${empty cookie.loginAct or empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd">
</c:if>
十天内免登录
</label>
<span id="msg"></span>
</div>
<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block"
style="width: 350px; position: relative;top: 45px;">登录
</button>
</div>
</form>
</div>
</div>
收集参数 表单验证 发送异步请求
$(function () { <%--给登录按钮添加单击事件--%> $("#loginBtn").click(function () { //收集参数 var loginAct = $.trim($("#loginAct").val()); var loginPwd = $.trim($("#loginPwd").val()); var isRemPwd = $("#isRemPwd").prop("checkbox"); //表单验证 if (loginAct == "") { alert("用户名不能为空"); return; } if (loginPwd == "") { alert("密码不能为空"); return; } //开始发送ajax请求给后端controller $.ajax({ url: 'settings/qx/user/Login.do', data: { loginAct: loginAct, loginPwd: loginPwd, isRemPwd: isRemPwd }, type: 'post', dataType: 'json', // 成功后接收返回的json对象 success: function (data) { if (data.code == "1") { //登录成功,跳转到业务页面 因为业务主页面在web-inf目录下,所以先到controller再转发 window.location.href = "workbench/index.do"; } else { //返回提示信息 $("#msg").text(data.message); } }, beforeSend:function (){//执行ajax向后台发送请求之前 true发送 $("#msg").text("正在努力验证"); return true; } }) }) })
用户提出需求 要使用 回车也能实现登录
在前端 上加上监听事件 用回车 模拟产生单击事件
$(window).keydown(function (e){ //如果是回车键 模拟产生单击事件 if(e.keyCode==13){ $("#loginBtn").click(); } });
登陆验证
在每个请求前都加入过滤器看是否登陆过 没登陆过让其跳回主页面
简单用过滤器 写个类实现filter方法 init 是之前 配置文件中 设置过滤器有效的 范围
复杂用如下这种主要是验证session域中是否已经存入user对象 没有就是没登陆
package com.bjpowernode.ssm.settings.web.INTERCEPTOR;
import com.alibaba.druid.sql.visitor.functions.Concat;
import com.bjpowernode.ssm.commons.contants.contant;
import com.bjpowernode.ssm.settings.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//进行登录验证,登录成功session域中有 user对象
HttpSession session = request.getSession();
User user = (User)session.getAttribute(contant.SESSION_USER);
if (user == null){
//没有登录,回到登录页面
response.sendRedirect(request.getContextPath());
return false;
}
return true;
}
@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 {
}
}
<!--拦截试图解析器下面 以settings和workbench开头的所有请求 放行登录请求 和请求验证--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/settings/**"/> <mvc:mapping path="/workbench/**"/> <mvc:exclude-mapping path="/settings/qx/user/toLogin.do"/> <mvc:exclude-mapping path="/settings/qx/user/Login.do"/> <bean class="com.bjpowernode.ssm.settings.web.INTERCEPTOR.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
三、跳转到业务主页面
响应上面的同步请求
@Controller public class workbenchIndexController { @RequestMapping("/workbench/index.do") public String index(){ return "workbench/index"; } }
到业务主页面的欢迎页面下
采用的是页面分割技术
在导航栏中可以通过controller再次跳转只有内部分割的会跳转 修改href 来到controller 再做进一步跳转到 WEB-INF目录下的资源
<ul id="no1" class="nav nav-pills nav-stacked">
<li class="liClass"><a href="workbench/main/index.do" target="workareaFrame"><span class="glyphicon glyphicon-home"></span> 工作台</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-tag"></span> 动态</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-time"></span> 审批</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户公海</a></li>
<li class="liClass"><a href="workbench/activity/activity.do" target="workareaFrame"><span class="glyphicon glyphicon-play-circle"></span> 市场活动</a></li>
<li class="liClass"><a href="workbench/clue/toClue.do" target="workareaFrame"><span class="glyphicon glyphicon-search"></span> 线索(潜在客户)</a></li>
<li class="liClass"><a href="customer/index.html" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户</a></li>
<li class="liClass"><a href="contacts/index.html" target="workareaFrame"><span class="glyphicon glyphicon-earphone"></span> 联系人</a></li>
<li class="liClass"><a href="transaction/index.html" target="workareaFrame"><span class="glyphicon glyphicon-usd"></span> 交易(商机)</a></li>
<li class="liClass"><a href="visit/index.html" target="workareaFrame"><span class="glyphicon glyphicon-phone-alt"></span> 售后回访</a></li>
<li class="liClass">
四.进入市场活动主页面
mapper
List<User> selectAllUsers();
<!--查询所有用户列表的sql-->
<select id="selectAllUsers" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from tbl_user where lock_state='1'
</select>
service
List<User> selectAllUsers();
@Override
public List<User> selectAllUsers() {
return userMapper.selectAllUsers();
}
controller
@RequestMapping("/workbench/activity/activity.do")
public String queryAllUsers(HttpServletRequest request) {
List<User> users = userLoginService.selectAllUsers();
request.setAttribute(contant.USER_LIST, users);
return "workbench/activity/index";
}
<div class="form-group"> <label for="create-marketActivityOwner" class="col-sm-2 control-label">所有者<span style="font-size: 15px; color: red;">*</span></label> <div class="col-sm-10" style="width: 300px;"> <select class="form-control" id="create-marketActivityOwner"> <%--开始动态从request域中获取list集合 用jstl获取--%> <c:forEach items="${userList}" var="user"> <option value="${user.id}"> ${user.name}</option> </c:forEach> </select> </div>
跳转到市场活动页面
五.添加市场活动
<insert id="insertSelective" parameterType="com.bjpowernode.ssm.workbench.domain.MarketingActivities">
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Wed Mar 22 20:37:12 CST 2023.
-->
insert into tbl_activity
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="owner != null">
owner,
</if>
<if test="name != null">
name,
</if>
<if test="startDate != null">
start_date,
</if>
<if test="endDate != null">
end_date,
</if>
<if test="cost != null">
cost,
</if>
<if test="description != null">
description,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="createBy != null">
create_by,
</if>
<if test="editTime != null">
edit_time,
</if>
<if test="editBy != null">
edit_by,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=CHAR},
</if>
<if test="owner != null">
#{owner,jdbcType=CHAR},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="startDate != null">
#{startDate,jdbcType=CHAR},
</if>
<if test="endDate != null">
#{endDate,jdbcType=CHAR},
</if>
<if test="cost != null">
#{cost,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=CHAR},
</if>
<if test="createBy != null">
#{createBy,jdbcType=VARCHAR},
</if>
<if test="editTime != null">
#{editTime,jdbcType=CHAR},
</if>
<if test="editBy != null">
#{editBy,jdbcType=VARCHAR},
</if>
</trim>
</insert>
@RequestMapping("/workbench/activity/save.do")
@ResponseBody
public Object saveActivity(MarketingActivities activities, HttpSession session) {
//封装参数
activities.setId(UUIDUtils.getUUID());
User user = (User) session.getAttribute(contant.SESSION_USER);
activities.setCreateBy(user.getId()); //一对多 一个user可能创建 多个表 用唯一标识
activities.setCreateTime(DataUtils.format(new Date()));
returnObject returnObject = new returnObject();
try {
int count = activityService.insertSelective(activities);
if (count > 0) {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
} else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~,请稍后重试");
}
} catch (Exception e) {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~,请稍后重试");
}
return returnObject;
}
前端
// 给创建市场活动 按钮加单击事件
$("#creatActivityBtn").click(function () {
//1.弹出模态窗口前的准备工作,初始化..
// 重置表单.
$("#activityFrom").get(0).reset();
//调用模态窗口
$("#createActivityModal").modal("show");
});
//3.出来模态窗口后,给保存键添加单击事件
$("#saveCreateActivityBtn").click(function () {
//点了这个按钮 发送异步请求
//1.收集参数
var owner = $("#create-marketActivityOwner").val();
var name = $.trim($("#create-marketActivityName").val());
var startDate = $("#create-startTime").val(); //日期时间都有格式,后面有日历
var endDate = $("#create-endTime").val();
var cost = $.trim($("#create-cost").val());
var description = $.trim($("#create-describe").val());
//2.表单验证
if (owner == "") {
alert("所有者不能为空");
return;
}
if (name == "") {
alert("名称不能为空");
return;
}
if (startDate != "" && endDate != "") {
if (endDate < startDate) {
alert("结束日期不能比开始日期小");
return;
}
}
var regExp = /^(([1-9]\d*)|0)$/; //验证 非负数正则表达式
if (!regExp.test(cost)) {
alert("成本只能为非负数");
return;
}
//开始发送ajax请求
$.ajax({
url: 'workbench/activity/save.do',
data: {
owner: owner,
name: name,
startDate: startDate,
endDate: endDate,
cost: cost,
description: description
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//成功了,关闭模态窗口 刷新列表
$("#createActivityModal").modal("hide");
//刷新市场活动列表
//刷新活动列表
queryActivityByCondition(1, $("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
} else {
//失败,提示信息
alert(data.message);
//模态窗口不关闭
$("#createActivityModal").modal("show");
}
}
});
});
日期插件的调用
三步:1.引入开发包 2. 创建容器3.容器加载完毕调用工具函数
<div class="form-group">
<label for="create-startTime" class="col-sm-2 control-label">开始日期</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control mydate" name="mydate" id="create-startTime" readonly>
</div>
<label for="create-endTime" class="col-sm-2 control-label">结束日期</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control mydate" name="mydate" id="create-endTime" readonly>
</div>
</div>
<div class="form-group">
//当容器加载完成之后,对容器调用工具函数 //$("input[name='mydate']").datetimepicker({ $(".mydate").datetimepicker({ language: 'zh-CN', //语言 format: 'yyyy-mm-dd',//日期的格式 minView: 'month', //可以选择的最小视图 initialDate: new Date(),//初始化显示的日期 autoclose: true,//设置选择完日期或者时间之后,日否自动关闭日历 todayBtn: true,//设置是否显示"今天"按钮,默认是false clearBtn: true//设置是否显示"清空"按钮,默认是false });
五.刷新市场活动列表 分页查询 市场活动列表
mapper
<!-- 根据条件,进行分页查询-->
<select id="selectActivityByPre" parameterType="map" resultMap="BaseResultMap">
select a.id ,u1.name as owner,a.name,a.start_date,a.end_date,a.cost,a.description,a.create_time,
u2.name as create_by,a.edit_time,u3.name as edit_by
from tbl_activity a
join tbl_user u1 on a.owner=u1.id
join tbl_user u2 on a.create_by=u2.id
left join tbl_user u3 on a.edit_by=u3.id
<where>
<if test="name != null and name!=''">
and a.name like '%' #{name} '%'
</if>
<if test="owner != null and owner !=''">
and u1.name like '%' #{owner} '%'
</if>
<if test="startDate != null and startDate!='' ">
and a.start_date>=#{startDate}
</if>
<if test="endDate != null and endDate!=''">
and a.end_date<=#{endDate}
</if>
</where>
order by a.create_time desc
limit #{beginNo},#{pageSize}
</select>
//根据条件分页查询 封装参数 返回json给前端 一个list集合 和统计的查询总行数
@RequestMapping("/workbench/activity/selectPages.do")
@ResponseBody
public Object selectPages(String owner, String name, String startDate, String endDate, int pageNo, int pageSize) {
HashMap<String, Object> map = new HashMap<>();
map.put("owner", owner);
map.put("name", name);
map.put("startDate", startDate);
map.put("endDate", endDate);
map.put("beginNo", (pageNo - 1) * pageSize);
map.put("pageSize", pageSize);
System.out.println(map.get("startDate"));
List<MarketingActivities> activitiesList = activityService.queryActivityByPre(map);
int rowCount = activityService.queryCountByPre(map);
// returnObjectPage returnObjectPage = new returnObjectPage(activitiesList,rowCount);
//
//return returnObjectPage;
HashMap<String, Object> retMap = new HashMap<>();
retMap.put("activitiesList", activitiesList);
retMap.put("rowCount", rowCount);
return retMap;
}
<!-- 根据条件 查询总行数-->
<select id="selectCountByPre" parameterType="map" resultType="int">
select count(*)
from tbl_activity a
join tbl_user u1 on a.owner=u1.id
join tbl_user u2 on a.create_by=u2.id
left join tbl_user u3 on a.edit_by=u3.id
<where>
<if test="name != null and name!=''">
and a.name like '%' #{name} '%'
</if>
<if test="owner != null and owner !=''">
and u1.name like '%' #{owner} '%'
</if>
<if test="startDate != null and startDate!='' ">
and a.start_date>=#{startDate}
</if>
<if test="endDate != null and endDate!=''">
and a.end_date<=#{endDate}
</if>
</where>
</select>
前端:
// 定义一个函数 来封装 查询市场活动列表
function queryActivityByCondition(pageNo, pageSize) {
var name = $("#query-name").val();
var owner = $("#query-owner").val();
var startDate = $("#query-startDate").val();
var endDate = $("#query-endDate").val();
//2.发送请求
$.ajax({
url: 'workbench/activity/selectPages.do',
data: {
name: name,
owner: owner,
startDate: startDate,
endDate: endDate,
pageNo: pageNo,
pageSize: pageSize,
},
type: 'post',
dataType: 'json',
success: function (data) {
//显示总条数
// $("#totalRowsB").text( data.rowCount);
//显示列表
var htmlStr = "";
$.each(data.activitiesList, function (index, obj) {
htmlStr += "<tr class=\"active\">";
htmlStr += " <td><input type=\"checkbox\" value=\"" + obj.id + "\"/></td>";
htmlStr += " <td><a style=\"text-decoration: none; cursor: pointer;\"onclick=\"window.location.href='workbench/activity/toDetail.do?id="+obj.id+"'\">" + obj.name + "</a></td>";
htmlStr += " <td>" + obj.owner + "</td>";
htmlStr += " <td>" + obj.startDate + "</td>";
htmlStr += " <td>" + obj.endDate + "</td>";
htmlStr += " </tr>";
});
$("#tbody").html(htmlStr);
//拼完后取消全选按钮
$("#checkAll").prop("checked", false);
//计算总页数
var totalPages = 1;
if (data.rowCount % pageSize == 0) {
totalPages = data.rowCount / pageSize;
} else {
totalPages = parseInt(data.rowCount / pageSize) + 1;
}
//对容器调用bs_pagination工具函数,显示翻页信息
$("#demo_pag1").bs_pagination({
currentPage: pageNo,//当前页号,相当于pageNo
rowsPerPage: pageSize,//每页显示条数,相当于pageSize
totalRows: data.rowCount,//总条数
totalPages: totalPages, //总页数,必填参数.
visiblePageLinks: 5,//最多可以显示的卡片数
showGoToPage: true,//是否显示"跳转到"部分,默认true--显示
showRowsPerPage: true,//是否显示"每页显示条数"部分。默认true--显示
showRowsInfo: true,//是否显示记录的信息,默认true--显示
//用户每次切换页号,都自动触发本函数;
//每次返回切换页号之后的pageNo和pageSize
onChangePage: function (event, pageObj) { // returns page_num and rows_per_page after a link has clicked
//js代码
//alert(pageObj.currentPage);
//alert(pageObj.rowsPerPage);
queryActivityByCondition(pageObj.currentPage, pageObj.rowsPerPage);
}
});
}
});
六 批量删除市场活动
<!-- 根据id数组来批量删除数据-->
<delete id="deleteActivities" parameterType="string">
delete from tbl_activity where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
//批量删除
//前台传来的参数 为id=..&id=... 后端接收 数组也要变为 id
@RequestMapping("/workbench/activity/deleteActivities.do")
@ResponseBody
public Object deleteActivities(String[] id) {
returnObject returnObject = new returnObject();
try {
int deleteCount = activityService.deleteActivities(id);
//删除成功
if (deleteCount > 0) {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
} else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~请稍后");
}
} catch (Exception e) {
e.printStackTrace();
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~请稍后");
}
return returnObject;
}
前端
//3.给删除按钮 添加单击事件
$("#deleteActivityBtn").click(function () {
//收集被选中的checkbox 的id
var checkedIds = $("#tbody input[type='checkbox']:checked");
if (checkedIds.size() == 0) {
alert("请选择要删除的市场活动");
return;
}
if (window.confirm("确定删除吗?")) {
//给后端发送异步请求 id=.&id=..&id=.. 形式的
var ids = "";
$.each(checkedIds, function () {
ids += "id=" + this.value + "&";
});
ids = ids.substr(0, ids.length - 1);//id=xxxx&id=xxx&.....&id=xxx
//发送请求
$.ajax({
url: 'workbench/activity/deleteActivities.do',
data: ids,
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//删除成功 刷新市场活动列表,显示第一页数据,每一页显示条数不变
queryActivityByCondition(1, $("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
} else {
//弹出失败信息
alert(data.message);
}
}
});
}
});
七.修改市场活动
<!-- 根据id 查出 单条信息 -->
<select id="selectById" parameterType="string" resultMap="BaseResultMap">
select a.id ,u1.name as owner,a.name,a.start_date,a.end_date,a.cost,a.description,a.create_time,
u2.name as create_by,a.edit_time,u3.name as edit_by
from tbl_activity a
join tbl_user u1 on a.owner=u1.id
join tbl_user u2 on a.create_by=u2.id
left join tbl_user u3 on a.edit_by=u3.id
where id = #{id}
</select>
//根据 id查出 该市场活动的信息 显示到 修改市场活动 的模态窗口中
@RequestMapping("/workbench/activity/queryActivityById.do")
@ResponseBody
public Object queryActivityById(String id) {
MarketingActivities activity = activityService.queryActivityById(id);
return activity;
}
// 4. 给修改添加单击事件
/**
* 1.用户点击要选择修改的框 ,选中以后 点击修改
* 2.点多个或者不点提示 重新选择
* 3.选中以后 点击修改 此时 显示该活动的信息
*/
$("#updateActivityBtn").click(function () {
//收集参数 获取列表选中的checkbox
var checkedIds = $("#tbody input[type='checkbox']:checked");
if (checkedIds.size() == 0) {
alert("请选择要修改的市场活动");
return;
}
if (checkedIds.size() > 1) {
alert("请选择唯一要更改的市场活动");
return;
}
var id = checkedIds[0].value;
//发送请求
$.ajax({
url: 'workbench/activity/queryActivityById.do',
data: {
id: id
},
type: 'post',
dataType: 'json',
success: function (data) {
//1.先给隐藏域 中设置 传过来的id
$("#edit-id").val(data.id);
//2.拿到后台传过来的activity对象,将其写入模态窗口中
$("#edit-marketActivityOwner").val(data.owner);
$("#edit-marketActivityName").val(data.name);
$("#edit-startTime").val(data.startDate);
$("#edit-endTime").val(data.endDate);
$("#edit-cost").val(data.cost);
$("#edit-describe").val(data.description);
//3.弹出模态窗口
$("#editActivityModal").modal("show");
}
})
});
弹出原有信息的模态窗口后
<update id="updateActivityById" parameterType="com.bjpowernode.ssm.workbench.domain.MarketingActivities">
update tbl_activity
set owner=#{owner},name=#{name},start_date=#{startDate},end_date=#{endDate},cost=#{cost},description=#{description},
edit_time=#{editTime},edit_by=#{editBy}
where id=#{id}
</update>
//根据隐藏的id 来进行修改此条记录
@RequestMapping("/workbench/activity/editActivityById.do")
@ResponseBody
public Object editActivityById(MarketingActivities activity, HttpSession session) {
User editUser = (User) session.getAttribute(contant.SESSION_USER);
activity.setEditBy(editUser.getId());
activity.setEditTime(DataUtils.format(new Date()));
//调用service 来修改
returnObject returnObject = new returnObject();
// System.out.println(activity);
//
// System.out.println("=========");
try {
int ret = activityService.editActivityById(activity);
if (ret > 0) {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
} else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙请稍后");
}
} catch (Exception e) {
e.printStackTrace();
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙请稍后");
}
return returnObject;
}
前端
//给更新按钮 添加 单击事件
$("#updateActBtn").click(function () {
//收集参数
var id = $("#edit-id").val();
var owner = $("#edit-marketActivityOwner").val();
var name = $("#edit-marketActivityName").val();
var startDate = $("#edit-startTime").val();
var endDate = $("#edit-endTime").val();
var cost = $("#edit-cost").val();
var description = $("#edit-describe").val();
//表单验证
if (owner == "") {
alert("所有者不能为空");
return;
}
if (name == "") {
alert("名称不能为空");
return;
}
if (startDate != "" && endDate != "") {
if (endDate < startDate) {
alert("结束日期不能比开始日期小");
return;
}
}
//发送请求
$.ajax({
url: 'workbench/activity/editActivityById.do',
data: {
id: id,
owner: owner,
name: name,
startDate: startDate,
endDate: endDate,
cost: cost,
description: description
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//修改成功 刷新市场活动列表,显示第一页数据,每一页显示条数不变
$("#editActivityModal").modal("hide");
queryActivityByCondition(1, $("#demo_pag1").bs_pagination('getOption', 'rowsPerPage'));
} else {
//弹出失败信息
alert(data.message);
$("#editActivityModal").modal("show");
}
}
});
});
八.跳转市场活动详情页面
分页查询函数中 拼接出来的 前面显示超链接 带id信息到controller
$.each(data.activitiesList, function (index, obj) {
htmlStr += "<tr class=\"active\">";
htmlStr += " <td><input type=\"checkbox\" value=\"" + obj.id + "\"/></td>";
htmlStr += " <td><a style=\"text-decoration: none; cursor: pointer;\"onclick=\"window.location.href='workbench/activity/toDetail.do?id="+obj.id+"'\">" + obj.name + "</a></td>";
htmlStr += " <td>" + obj.owner + "</td>";
htmlStr += " <td>" + obj.startDate + "</td>";
htmlStr += " <td>" + obj.endDate + "</td>";
htmlStr += " </tr>";
});
<!-- /根据市场活动id查多条 remarkList-->
<select id="selectRemarkById" resultMap="BaseResultMap" parameterType="string">
select ar.id,
ar.note_content,
ar.create_time,
u1.name as create_by,
ar.edit_time,
u2.name as edit_by,
ar.edit_flag
from tbl_activity_remark ar
join tbl_user u1 on ar.create_by = u1.id
left join tbl_user u2 on ar.edit_by = u2.id
where ar.activity_id = #{id}
</select>
<!-- 根据id 查出 单条信息 -->
<select id="selectById" parameterType="string" resultMap="BaseResultMap">
select a.id ,u1.name as owner,a.name,a.start_date,a.end_date,a.cost,a.description,a.create_time,
u2.name as create_by,a.edit_time,u3.name as edit_by
from tbl_activity a
join tbl_user u1 on a.owner=u1.id
join tbl_user u2 on a.create_by=u2.id
left join tbl_user u3 on a.edit_by=u3.id
where id = #{id}
</select>
//详情
@RequestMapping("/workbench/activity/toDetail.do")
public String toDetail(String id, HttpServletRequest request) {
MarketingActivities activity = activityService.queryActivityById(id);
List<MarketingActivitiesRemark> remarks = remarkService.queryRemarkById(id);
//将得到的数据放在作用域
request.setAttribute("activity", activity);
request.setAttribute("remarks", remarks);
//跳转到 detail.jsp 页面
return "workbench/activity/detail";
}
将两个放在request中后 跳转
在详情页中显示出来
${activity.name} ${activity.startDate} ~ ${activity.endDate}
<%-- 遍历remarkList,显示所有的备注--%>
<c:forEach items="${remarks}" var="remark">
<div id="div_${remark.id}" class="remarkDiv" style="height: 60px;">
<img title="${remark.createBy}" src="image/user-thumbnail.png" style="width: 30px; height:30px;">
<div style="position: relative; top: -40px; left: 40px;">
<h5>${remark.noteContent}</h5>
<font color="gray">市场活动</font> <font color="gray">-</font> <b>${activity.name}</b> <small
style="color: gray;"> ${remark.editFlag=='1'?remark.editTime:remark.createTime}
由${remark.editFlag=='1'?remark.editBy:remark.createBy}${remark.editFlag=='1'?'修改':'创建'}</small>
<div style="position: relative; left: 500px; top: -30px; height: 30px; width: 100px; display: none;">
<a class="myHref" name="editA" remarkId="${remark.id}" href="javascript:void(0);"><span
class="glyphicon glyphicon-edit" style="font-size: 20px; color: #E6E6E6;"></span></a>
<a class="myHref" name="deleteA" remarkId="${remark.id}" href="javascript:void(0);"><span
class="glyphicon glyphicon-remove" style="font-size: 20px; color: #E6E6E6;"></span></a>
</div>
</div>
</div>
</c:forEach>
很巧妙的设定 将id和div绑定起来
九.发送并保存市场活动备注信息
<insert id="insertActivityRemark" parameterType="com.bjpowernode.ssm.workbench.domain.MarketingActivitiesRemark">
insert into tbl_activity_remark (id, note_content, create_time,
create_by, edit_time, edit_by,
edit_flag, activity_id)
values
(#{id}, #{noteContent}, #{createTime},
#{createBy,jdbcType=VARCHAR}, #{editTime,jdbcType=CHAR}, #{editBy,jdbcType=VARCHAR},
#{editFlag,jdbcType=CHAR}, #{activityId,jdbcType=CHAR})
</insert>
//保存一条市场活动备注 信息
@RequestMapping("/workbench/activity/detail/saveActivityRemark.do")
@ResponseBody
public Object saveActivityRemark(MarketingActivitiesRemark remark, HttpSession session) {
User user = (User) session.getAttribute(contant.SESSION_USER);
remark.setId(UUIDUtils.getUUID());
remark.setCreateTime(DataUtils.format(new Date()));
remark.setCreateBy(user.getId());
remark.setEditFlag(contant.REMARK_EDIT_NO_FLAG);
returnObject returnObject = new returnObject();
try {
int ret = remarkService.saveActivityRemark(remark);
if (ret > 0) {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
returnObject.setRetData(remark);
} else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~");
}
} catch (Exception e) {
e.printStackTrace();
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~");
}
return returnObject;
}
将新建的remark带到前端也动态刷出来
前端
//给保存按钮 添加单击事件
$("#saveRemarkBtn").click(function () {
//收集参数
var noteContent = $.trim($("#remark").val());
var activityId = '${activity.id}';
//表单验证
if (noteContent == "") {
alert("备注内容不能为空");
return;
}
//发送异步ajax请求
$.ajax({
url: 'workbench/activity/detail/saveActivityRemark.do',
data: {
noteContent: noteContent,
activityId: activityId
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//保存成功 清除输入内容 动态刷新
//1.清空
$("#remark").val("");
//2.刷新列表
var htmlStr = "";
htmlStr += "<div id=\"div_" + data.retData.id + "\" class=\"remarkDiv\" style=\"height: 60px;\">";
htmlStr += "<img title=\"${sessionScope.sessionUser.name}\" src=\"image/user-thumbnail.png\" style=\"width: 30px; height:30px;\">";
htmlStr += "<div style=\"position: relative; top: -40px; left: 40px;\" >";
htmlStr += "<h5>" + data.retData.noteContent + "</h5>";
htmlStr += "<font color=\"gray\">市场活动</font> <font color=\"gray\">-</font> <b>${activity.name}</b> <small style=\"color: gray;\"> " + data.retData.createTime + " 由${sessionScope.sessionUser.name}创建</small>";
htmlStr += "<div style=\"position: relative; left: 500px; top: -30px; height: 30px; width: 100px; display: none;\">";
htmlStr += "<a class=\"myHref\" name=\"editA\" remarkId=\"" + data.retData.id + "\" href=\"javascript:void(0);\"><span class=\"glyphicon glyphicon-edit\" style=\"font-size: 20px; color: #E6E6E6;\"></span></a>";
htmlStr += " ";
htmlStr += "<a class=\"myHref\" name=\"deleteA\" remarkId=\"" + data.retData.id + "\" href=\"javascript:void(0);\"><span class=\"glyphicon glyphicon-remove\" style=\"font-size: 20px; color: #E6E6E6;\"></span></a>";
htmlStr += "</div>";
htmlStr += "</div>";
htmlStr += "</div>";
$("#remarkDiv").before(htmlStr);
} else {
alert(data.message);
}
}
});
});
十.删除备注信息
<delete id="deleteRemarkActivityById" parameterType="string" >
delete from tbl_activity_remark where id=#{id}
</delete>
//删除某条备注信息
@RequestMapping("/workbench/activity/detail/delete.do")
@ResponseBody
public Object deleteRemarkById(String id) {
returnObject returnObject = new returnObject();
try {
int ret = remarkService.deleteRemarkActivityById(id);
if (ret > 0) {
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
} else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙请稍后");
}
} catch (Exception e) {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙请稍后");
}
return returnObject;
}
//给所有的删除按钮添加单击事件
$("#remarkDivList").on("click", "a[name='deleteA']", function () {
//收集参数
var id = $(this).attr("remarkId");
//发送请求
$.ajax({
url: 'workbench/activity/detail/delete.do',
data: {
id: id
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//成功 刷新备注列表
$("#div_" + id).remove();
} else {
alert(data.message);
}
}
});
});
十一.修改某条市场备注信息
<!-- 修改市场活动内容对象-->
<update id="updateRemarkActivity" parameterType="com.bjpowernode.ssm.workbench.domain.MarketingActivitiesRemark">
update tbl_activity_remark set note_content=#{noteContent},edit_flag=#{editFlag}, edit_by=#{editBy},edit_time=#{editTime}
where id=#{id}
</update>
//修改备注信息
@RequestMapping("/workbench/activity/detail/changeRemark.do")
@ResponseBody
public Object changeRemark(MarketingActivitiesRemark remark, HttpSession session) {
User user = (User) session.getAttribute(contant.SESSION_USER);
remark.setEditBy(user.getId());
remark.setEditFlag(contant.REMARK_EDIT_YES_FLAG);
remark.setEditTime(DataUtils.format(new Date()));
returnObject returnObject = new returnObject();
try {
int ret = remarkService.changeRemark(remark);
if (ret>0){
returnObject.setCode(contant.RETURN_CODE_SUCCESS);
//成功 将修改后的remark对象携带返回
returnObject.setRetData(remark);
}else {
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~~");
}
} catch (Exception e) {
e.printStackTrace();
returnObject.setCode(contant.RETURN_CODE_FAIL);
returnObject.setMessage("系统忙~~~");
}
return returnObject;
}
//给所有修改绑定单击事件 弹出修改的模态窗口
$("#remarkDivList").on("click", "a[name='editA']", function () {
//给模态窗口里隐藏域 写id
//拿到原来的id 和内容
var id = $(this).attr("remarkId");
var noteContent = $("#div_" + id + " h5").text();
//给模态窗口里隐藏域 写id
$("#edit-id").val(id);
$("#edit-noteContent").val(noteContent);
//弹出修改市场活动的模态窗口
$("#editRemarkModal").modal("show");
});
//给更新添加单击事件
$("#updateRemarkBtn").click(function () {
//收集参数
var id = $("#edit-id").val();
var noteContent = $.trim($("#edit-noteContent").val());
//表单验证
if (noteContent == "") {
alert("备注内容不能为空");
return;
}
//发送异步请求
$.ajax({
url: 'workbench/activity/detail/changeRemark.do',
data: {
id: id,
noteContent: noteContent
},
type: 'post',
dataType: 'json',
success: function (data) {
if (data.code == "1") {
//修改成功,关闭模态窗口 刷新列表
$("#editRemarkModal").modal("hide");
//刷新备注列表
$("#div_"+data.retData.id+" h5").text(data.retData.noteContent);
$("#div_"+data.retData.id+" small").text(" "+data.retData.editTime+" 由${sessionScope.sessionUser.name}修改");
} else {
//不关闭 提示信息
$("#editRemarkModal").modal("show");
alert(data.message);
}
}
});
});
总结
提示:这是市场活动页面所要做的处理过程