前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSM框架版本的CRM项目实战教程【crm客户管理系统】

SSM框架版本的CRM项目实战教程【crm客户管理系统】

原创
作者头像
晴天娃娃只会笑不会哭
发布2022-02-22 15:59:46
1.7K0
发布2022-02-22 15:59:46
举报
文章被收录于专栏:Javaweb笔记

客户关系管理(CRM)在当今企业运营中扮演着重要角色,公司为提高核心竞争力,利用相应的信息技术以及互联网技术来协调企业与顾客间在销售、营销和服务上的交互,从而提升其管理方式,向客户提供创新式的个性化的客户交互和服务的过程。其最终目标是吸引新客户、保留老客户以及将已有客户转为忠实客户,增加市场份额。 分不同角色登录不同的页面实现不同的功能; 数据库只添加了几个用户其他数据为空自己导入;

本文主要是完成市场活动的相关操作。比如给创建市场活动按钮绑定事件、还有最重要的pageList()方法,即:分页操作。一起来学习吧!

1.为创建按钮绑定事件

这个地方要注意的就是,因为打开的是模态窗口,然后里面有些内容是需要从后台上取数据之后铺上去的。

所以我们就正常发起ajax请求从后台取得数据就行,这里取得user表的name,但是必须是去所有的,返回的就是userList,然后在前端去拼接就行。然后默认选择当前登录用户作为显示的结果:

代码语言:javascript
复制
//默认选中当前登录的用户=====应当是里面有内容之后再选择,一开始我放在上面了
var id = "${user.id}";
$("#create-owner").val(id);

这里需要注意的一个点是:这里的选择默认的值,是在你拼好select标签里面的内容之后才执行的,我做的时候,上面的代码直接放在了前面。

我在这里也给推荐一套教程,最新上传的一套:https://www.bilibili.com/video/BV1tZ4y1d7kg

2.为创建市场活动模态窗口的 保存 按钮绑定事件

这个需求也是比较简单的,文本框填好值,前端取到值,后端去接收就行。然后调用dao执行数据库的保存操作就行。

这里里面需要用到日历控件,直接复制添加就行:

代码语言:javascript
复制
$(".time").datetimepicker({
			minView: "month",
			language:  'zh-CN',
			format: 'yyyy-mm-dd',
			autoclose: true,
			todayBtn: true,
			pickerPosition: "bottom-left"
	});

这里做的时候,出现乱码了,最后只能把jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js这个文件里面的内容放到js代码中才解决。

然后要用这个日历控件的话,直接在需要用的地方的class属性后面加上time就行

3.最重要的pageList()方法

因为查询条件不一定有,所以我们要使用到mybatis的动态sql。中间的那部分内容有6个地方需要刷他

(1)点击左侧菜单中的"市场活动"超链接,需要刷新市场活动列表,调用pageList方法

(2)添加,修改,删除后,需要刷新市场活动列表,调用pageList方法

(3)点击查询按钮的时候,需要刷新市场活动列表,调用pageList方法

(4)点击分页组件的时候,调用pageList方法

pageList(pageNo,pageSize)是有参数的:

pageNo:页码

pageSize:每页展现的记录数

另外,前端有分页插件,需要总记录条数,所以从后台取得值应该是这样的{“total”:total,[{市场活动1},{市场活动2}…]},发的是ajax请求,取数据就行了

代码语言:javascript
复制
function pageList(pageNo,pageSize){  //第几页,展现几条
		//将隐藏域中的内容放到search框里面
		$("#search-name").val($.trim($("#hidden-name").val()));
		$("#search-owner").val($.trim($("#hidden-owner").val()));
		$("#hsearch-startDate").val($.trim($("#hidden-startDate").val()));
		$("#search-endDate").val($.trim($("#hidden-endDate").val()));

		var name = $.trim($("#search-name").val());
	    var owner = $.trim($("#search-owner").val());
	    var startDate = $.trim($("#search-startDate").val());
	    var endDate = $.trim($("#search-endDate").val());

		$.ajax({
			url:"workbench/activity/pageList.do",
			data:{"pageNoStr":pageNo,
                "pageSizeStr":pageSize,
                "name":name,
                "owner":owner,
                "startDate":startDate,
                "endDate":endDate
            },
			type:"GET",
			dataType:"json",    //预期服务器返回的数据类型
			success:function (data){
				// {dataList: activityList, total: 总记录条数分页插件要用到}
				var html = "";
				$.each(data.dataList,function (i,n){
					html += '<tr class="active">';
					html += '<td><input type="checkbox" name="xuanze" value="'+n.id+'" /></td>';
					html += '<td><a style="text-decoration: none; cursor: pointer;" οnclick="window.location.href=\'detail.jsp\';">'+n.name+'</a></td>';
					html += '<td>'+n.owner+'</td>';
					html += '<td>'+n.startDate+'</td>';
					html += '<td>'+n.endDate+'</td>';
					html += '</tr>';
				})

				$("#activityBody").html(html);

				//计算出下面需要的总页数
				var totalPages = data.total%pageSize==0?data.total/pageSize:parseInt(data.total/pageSize)+1;

				//数据处理完毕后,结合分页查询,对前端展现分页信息----下面的代码直接从文档赋值
				$("#activityPage").bs_pagination({
					currentPage: pageNo, // 页码
					rowsPerPage: pageSize, // 每页显示的记录条数
					maxRowsPerPage: 20, // 每页最多显示的记录条数
					totalPages: totalPages, // 总页数
					totalRows: data.total, // 总记录条数

					visiblePageLinks: 3, // 显示几个卡片

					showGoToPage: true,
					showRowsPerPage: true,
					showRowsInfo: true,
					showRowsDefaultInfo: true,

					onChangePage : function(event, data){
						pageList(data.currentPage , data.rowsPerPage);
					}
				});
			}
		})
	}

因为这个分页在很多模块都需要使用,所以在后端往前端返回对象的时候,我们直接封装了一个PaginationVO对象,使用泛型的方式,你给T什么,这个对象里面就是什么。

在controller里面

代码语言:javascript
复制
	@ResponseBody
    @RequestMapping("/workbench/activity/pageList.do")
    public PaginationVO<Activity> pageList(String pageNoStr,String pageSizeStr,
                                       String name,String owner,String startDate,String endDate){
        System.out.println("=====市场活动控制器,执行分页方法=========");

        Integer pageNo = Integer.valueOf(pageNoStr);
        Integer pageSize = Integer.valueOf(pageSizeStr);
        //计算出略过的记录数
        int skipCount = (pageNo-1)*pageSize;
        System.out.println("pageNo,"+pageNo+"pageSize,"+pageSize+"name,"+name+"owner,"+owner+"startDate,"+startDate+"endDate,"+endDate);
        PaginationVO<Activity> paginationVO = activityService.pageList(skipCount,pageSize,name,owner,startDate,endDate);
        return paginationVO;
    }

在service实现类里面

代码语言:javascript
复制
	@Override
    public PaginationVO<Activity> pageList(int skipCount, Integer pageSize, String name, String owner, String startDate, String endDate) {
        PaginationVO<Activity> paginationVO = new PaginationVO<>();

        //获取总条数
        int count = activityDao.getTotalByCondition(name,owner,startDate,endDate);
        //获取市场活动记录
        List<Activity> activityList = activityDao.getActivityListByCondition(skipCount,pageSize,name,owner,startDate,endDate);

        paginationVO.setTotal(count);
        paginationVO.setDataList(activityList);

        return paginationVO;
    }

注意,在访问数据库的时候,因为需要展现的所有者user的名字,这就涉及到了多表联查,而且查询条件不一定有,就有了动态sql。

代码语言:javascript
复制
<select id="getActivityListByCondition" resultType="Activity">
        select
            a.id,
            u.name as owner,
            a.name,
            a.startDate,
            a.endDate
        from tbl_activity a
        join tbl_user u
        on a.owner=u.id
        <where>
            <if test="name != null and name != ''">
                a.name like '%' #{name} '%'
            </if>
            <if test="owner != null and owner != ''">
                and u.name like '%' #{owner} '%'
            </if>
            <if test="startDate != null and startDate != ''">
                and a.startDate &gt; #{startDate}
            </if>
            <if test="endDate != null and endDate != ''">
                and a.endDate &lt; #{endDate}
            </if>
        </where>
        order by a.createTime desc
        limit #{skipCount},#{pageSize}
    </select>

在getTotalByCondition()里面也是如此。

上面基本上可以查询出来了。但还存在一些小问题。后面说。

在做这个的时候,我踩到了一个超级大坑。就是在原来的jsp页面的,查询条件的文本框的内容是在form表单里面的,而且这个时候的type属性是submit,必须要把他改成button,不然点的时候,他最后都会提交一张没有任何参数的表单,而且是在你触发了你的按钮的click方法之后才提交的,导致你最后在查询条件里面输入什么都不好使,因为最终查出来的肯定是没有任何条件的数据。坑死我了。。。。。。。。。找了好久,吃完饭回来找到了。发现每次我遇到一个超级大坑,吃完饭回来之后找到原因的可能性最大。

4.前端的分页插件

1.首先引入外部文件,复制文件到jquery里面。

2.在jsp页面引入资源,记得pom文件刷一下。

3.然后把原来的分页组件删掉,成对的删。

4.在pageList.do处理ajax返回值后,加入分页组件(代码直接复制)

代码语言:javascript
复制
$("#activityPage").bs_pagination({
			currentPage: pageNo, // 页码
			rowsPerPage: pageSize, // 每页显示的记录条数
			maxRowsPerPage: 20, // 每页最多显示的记录条数
			totalPages: totalPages, // 总页数
			totalRows: data.total, // 总记录条数

			visiblePageLinks: 3, // 显示几个卡片

			showGoToPage: true,
			showRowsPerPage: true,
			showRowsInfo: true,
			showRowsDefaultInfo: true, 
					
			onChangePage : function(event, data){
				pageList(data.currentPage , data.rowsPerPage);
			}
	 });

这里的 totalPages 要使用后台传回来的total算一下

然后应该就可以了。

5.隐藏域的使用

上面处理完之后,还处在一些问题:

问题1:

在查询框中输入内容,不点击查询按钮

点击分页按钮

结果为查询框中的内容生效了

问题2:

在查询框中输入内容,点击查询按钮

再在查询框中输入内容,不点击查询按钮

点击分页按钮

结果为新的查询框中的内容生效了

解决上面的问题,就需要使用到隐藏域的内容。做法:

将查询条件放到隐藏域当中,每一次翻页的时候,条件都从隐藏域当中取。

什么时候更新隐藏域?

(1)点击查询按钮的时候将查询框中的内容更新(保存内容到)隐藏域。

hidden–>search 将查询的保存到隐藏域中

(2)执行pageList的时候,将隐藏域中的内容更新熬查询框。

search–>hidden 将隐藏域中的内容保存到查询文本框

6.全选框和复选框的操作

1.挑全选,下面的两个自动选择。

----可以拿到全选框的jQuery对象,调用click方法实现需求

代码语言:javascript
复制
$("#qx").click(function () {
	$("input[name=xz]").prop("checked",this.checked);
})

2.下面两个选择了,全选也挑上。一个取消选,全选取消。

这里需要注意一个问题,因为下面的两个是动态拼接的。

因为动态生成的元素,是不能够以普通绑定事件的形式来进行操作的。动态生成的元素,我们要以on方法的形式来触发事件

语法:

$(需要绑定元素的有效的外层元素).on(绑定事件的方式,需要绑定的元素的jquery对象,回调函数)

代码语言:javascript
复制
$("#activityBody").on("click",$("input[name=xz]"),function () {
	$("#qx").prop("checked",$("input[name=xz]").length==$("input[name=xz]:checked").length);
})

好啦!差不多就是这些了!!!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.为创建按钮绑定事件
  • 2.为创建市场活动模态窗口的 保存 按钮绑定事件
  • 3.最重要的pageList()方法
  • 4.前端的分页插件
  • 5.隐藏域的使用
  • 6.全选框和复选框的操作
  • 好啦!差不多就是这些了!!!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档