文章目录

目录

文章目录

一、环境搭配

注意!

二、登录模块编写

登陆验证

三、跳转到业务主页面

四.进入市场活动主页面

跳转到市场活动页面

五.添加市场活动

五.刷新市场活动列表 分页查询 市场活动列表

六 批量删除市场活动

七.修改市场活动

八.跳转市场活动详情页面

九.发送并保存市场活动备注信息

十.删除备注信息

十一.修改某条市场备注信息

总结



提示:以下是本篇文章正文内容,下面案例可供参考

一、环境搭配

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.判断是否可以登录@Overridepublic 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域//如果要记住密码 则往外写入cookieif ("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>&nbsp;&nbsp;&nbsp;&nbsp;<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 {@Overridepublic 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;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic 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();
  @Overridepublic 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">所有者<spanstyle="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 - @mbggeneratedThis 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")@ResponseBodypublic 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,//设置是否显示"今天"按钮,默认是falseclearBtn: 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_byfrom tbl_activity ajoin tbl_user u1 on a.owner=u1.idjoin tbl_user u2 on a.create_by=u2.idleft 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&gt;=#{startDate}</if><if test="endDate != null and endDate!=''">and a.end_date&lt;=#{endDate}</if></where>order by a.create_time desclimit #{beginNo},#{pageSize}</select>
 //根据条件分页查询 封装参数  返回json给前端 一个list集合 和统计的查询总行数@RequestMapping("/workbench/activity/selectPages.do")@ResponseBodypublic 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 ajoin tbl_user u1 on a.owner=u1.idjoin tbl_user u2 on a.create_by=u2.idleft 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&gt;=#{startDate}</if><if test="endDate != null and endDate!=''">and a.end_date&lt;=#{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,//当前页号,相当于pageNorowsPerPage: pageSize,//每页显示条数,相当于pageSizetotalRows: data.rowCount,//总条数totalPages: totalPages,  //总页数,必填参数.visiblePageLinks: 5,//最多可以显示的卡片数showGoToPage: true,//是否显示"跳转到"部分,默认true--显示showRowsPerPage: true,//是否显示"每页显示条数"部分。默认true--显示showRowsInfo: true,//是否显示记录的信息,默认true--显示//用户每次切换页号,都自动触发本函数;//每次返回切换页号之后的pageNo和pageSizeonChangePage: 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")@ResponseBodypublic 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 的idvar 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_byfrom tbl_activity ajoin tbl_user u1 on a.owner=u1.idjoin tbl_user u2 on a.create_by=u2.idleft join tbl_user u3 on a.edit_by=u3.idwhere id = #{id}</select>
 //根据 id查出 该市场活动的信息 显示到 修改市场活动 的模态窗口中@RequestMapping("/workbench/activity/queryActivityById.do")@ResponseBodypublic Object queryActivityById(String id) {MarketingActivities activity = activityService.queryActivityById(id);return activity;}
  // 4. 给修改添加单击事件/*** 1.用户点击要选择修改的框 ,选中以后 点击修改* 2.点多个或者不点提示 重新选择* 3.选中以后 点击修改 此时 显示该活动的信息*/$("#updateActivityBtn").click(function () {//收集参数 获取列表选中的checkboxvar 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_activityset 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")@ResponseBodypublic 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_flagfrom tbl_activity_remark arjoin tbl_user u1 on ar.create_by = u1.idleft join tbl_user u2 on ar.edit_by = u2.idwhere 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_byfrom tbl_activity ajoin tbl_user u1 on a.owner=u1.idjoin tbl_user u2 on a.create_by=u2.idleft join tbl_user u3 on a.edit_by=u3.idwhere 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="data: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> <smallstyle="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);"><spanclass="glyphicon glyphicon-edit" style="font-size: 20px; color: #E6E6E6;"></span></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class="myHref" name="deleteA" remarkId="${remark.id}" href="javascript:void(0);"><spanclass="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")@ResponseBodypublic 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 += "&nbsp;&nbsp;&nbsp;&nbsp;";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")@ResponseBodypublic 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")@ResponseBodypublic 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);}}});});

总结

提示:这是市场活动页面所要做的处理过程

CRM 项目 各个模块相关推荐

  1. Crm项目总结-营销模块-机会数据管理

    Crm项目总结 文章目录 Crm项目总结 营销模块-机会数据管理 机会数据管理业务场景 机会数据管理表结构 机会管理模块功能实现 机会管理模块实现效果图 机会数据展示 机会数据添加 机会数据更新 机会 ...

  2. CRM项目开发【实操篇----市场活动模块】

    CRM项目开发[实操篇----市场活动模块] 前言:本项目来源于B站动力节点视频,CRM项目开发 使用的后端技术栈主要是SSM框架,不涉及boot,老师讲的非常细致,推荐 关于流程图部分,由于是老师创 ...

  3. CRM项目第一天(2021-12-16)1

    CRM项目第一天(2021-12-16)1 1.CRM项目介绍: 从0到1的项目开发. 涉及到的技术点: 1.前后端交互. 2.UI 3.jQuery 4.Ajax 5.Spring 6.Spring ...

  4. CRM 项目实战-笔记

    CRM项目: 编程思想和编程习惯 web项目的开发:如何分析.设计.编码.测试 技术架构 视图层(View) 展示数据,跟用户交互 html,css,js,jquery,bootstrap(ext|e ...

  5. CRM项目(idea)-1-环境搭建.

    搭建CRM项目的开发环境: 1 设置字体 * 设置工作区的字符集为utf-8* 这个是针对本次工程设置. 以后项目中可以点击other setting 2 创建Maven项目前的准备工作 使用sett ...

  6. 第一章:第1章 CRM核心业务介绍--概述,crm架构,公司组织结构,软件开发的生命周期,crm项目的核心业务介绍。...

    第一章:第1章 CRM核心业务介绍 1. 什么是crm项目: 1,CRM(Customer Relationship Management)客户关系管理是管理企业与客户之间关系的新型管理机制.终极目标 ...

  7. Java实现CRM项目过程中的细节记录(一)

    CRM项目实现过程中的细节记录(一) 文章目录 CRM项目实现过程中的细节记录(一) 一.数据库相关细节 1. 表名 2. 表字段说明 3. 不使用主外键约束 4. 不使用主键自动增长 UUID 5. ...

  8. 悟空CRM项目实战(6)

    新的一周开始,我们的悟空CRM项目系统测试也进入一个新的阶段--测试用例执行阶段,针对上周的测试用例编写情况,本着交叉执行的原则,我分到了前台的项目管理和客户管理两个模块,由于是新的模块,所以我对其也 ...

  9. 第2章搭建CRM项目开发环境(搭建开发环境)

    2.2搭建开发环境 2.2.1创建crm项目 使用IDEA创建Empty Project,作为项目的工作空间 2.2.2创建crm模块 创建maven类型的模块,作为开发工程 2.2.3为项目添加me ...

最新文章

  1. Arm收购进展、元宇宙、GPU涨价……听听黄仁勋怎么说
  2. 去水印--《On the Effectiveness of Visible Watermarks》
  3. 实现基于Keepalived主从高可用集群网站架构
  4. 3.11课·········异常语句与for循环重复
  5. Golang入门教程(二)Ubuntu16.04下安装golang(实例:Golang 定时任务管理器)
  6. 20170505思考点--编写案例时是以功能为主还是业务为主要
  7. PHP入门part1
  8. VMbox复制虚拟机后网卡问题-bring up interface eth0:Device eth0 does not seem to be present
  9. 在Android中实现一个简易的Http服务器
  10. 2009北海市东盟杯导游大赛,渤锐软件为其提供了计分及抽奖整体解决方案
  11. 自动换挡型数字频率计
  12. Word设置每页不同的页眉/修改或去掉页眉横线/页眉标题在横线上下方的设置
  13. Nodejs: redis客户端通过mset方法一次性批量写入多个key的值
  14. Python - PyMuPDF (fitz) 处理 PDF
  15. 使用阿里云的ip地址查询服务-购买ip地址查询服务
  16. 【无标题】智慧校园管理系统-毕设项目(包含数据库)
  17. nginx: [warn] conflicting server name “xxx“ on 0.0.0.0:80解决
  18. 计算机的常用外设有,计算机常用外部设备.ppt
  19. firefox浏览器window.event is undefined问题
  20. 海外直播、聊天交友APP的开发及上架GooglePlay体验【Compose版】

热门文章

  1. 计算机毕业设计—火锅店在线点餐小程序
  2. 自己动手写CPU——第一篇
  3. 【日志】最后的时光③
  4. GD32移植CoreMark实现性能测评
  5. 基于linux嵌入式浏览,基于Linux的嵌入式浏览器的实现
  6. 前端学习(396):京东制作页面5三大标签优化
  7. python爬虫初步了解 定时任务 以及浏览器自动工作
  8. Web jsp开发学习——网上直播聊天室的简单开发
  9. Zuul服务网关二个功能请求的路由和过滤器使用
  10. 花旗私人银行发布2019年展望报告