案例:送水系统4

1送水历史列表

点击“送水历史管理”,显示“送水历史”列表。送水历史列表查询工作涉及到三张表联合查询,我们使用MyBatis-plus映射文件(HistoryMapper.xml)代替MyBatis-Plus提供的内置查询方法。

sql  

SELECT h.hid,w.worker_name,h.send_water_time,c.cust_name,h.send_water_count
FROM tb_history h,tb_worker w ,tb_customer c
WHERE h.worker_id = w.wid and h.cust_id = c.cid;

涉及到送水工、客户管理、以及我们的提成

1.1 编写YML文件

配置Mapper映射文件的路径和包别名 (mybatis-plus的扫包,以及扫它的mapper.xml)

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: auto
  # 配置Mapper.xml文件的路径,此时所有Mapper.xml映射文件都定义在resources/mapper路径下
  mapper-locations: classpath:/mapper/*Mapper.xml
  # 配置指定包中(com.shouyi.entities)不包括包名的简单类名作为包括包名的别名
  type-aliases-package: com.shouyi.entities

1.2 编写History实体类

package com.shouyi.entities;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * TODO 送水历史管理实体类
 * @author caojie
 * @version 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_history")
public class History {
    /**
     * 送水历史ID
     */
    private Integer hid;
    /**
     * 关联送水工
     */
    private Worker worker;
    /**
     * 关联客户
     */
    private Customer customer;

    /**
     * 送水时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date sendWaterTime;
    /**
     * 送水数量
     */
    private Integer sendWaterCount;
}

1.3 编写Mapper接口

package com.shouyi.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.shouyi.entities.History;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * TODO: 送水历史相关的映射器
 * @author caojie
 * @version 1.0
 */
@Repository
public interface HistoryMapper extends BaseMapper<History> {
    /**
     * 自定义查询方法来代替MyBaits-Plus内置的查询方法,查询所有的送水历史信息。
     * @return 送水历史列表
     */
    List<History> listHistory();
}

1.4 编写Mapper映射文件

我们使用自定义查询方法来代替MyBaits-Plus内置的查询方法,所以要编写HistoryMapper接口对应的映射文件HistoryMapper.xml。该映射文件在resources/mapper路径下定义

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shouyi.mapper.HistoryMapper">
<!--   我们使用三张表进行联合查询,所以查询的送水历史列表返回一个结果集,将三张表查询的结果封装到resultMap结果集中。resultMap类似于JDBC的ResultSet对象
	   resultMap有两个核心属性:
		1) id表示resultMap在整个配置文件中的唯一性
		2) type表示返回值的全限定类名,我们在yml配置文件中配置了type-aliases-package: com.shouyi.entities。所以type属性值可以返回类型别名(省略了包名)	
	-->
    <resultMap id="selectHistoryMap" type="History">
        <id property="hid" column="hid" />
        <result column="send_water_time" property="sendWaterTime" />
        <result column="send_water_count" property="sendWaterCount"/>
<!--        送水历史关联送水工-->
        <association property="worker" javaType="com.lxyk.pojo.Worker">
            <id column="wid" property="wid"></id>
            <result column="worker_name" property="workerName"></result>
        </association>
<!--        送水历史关联客户-->
        <association property="customer" javaType="com.lxyk.pojo.Customer">
            <id column="cid" property="cid"></id>
            <result column="cust_name" property="custName"></result>
        </association>
    </resultMap>

    <!--
	select节点表示一个查询方法
	id属性必须跟HistoryMapper接口的方法名一致
	-->
    <select id="listHistory" resultMap="selectHistoryMap">
        SELECT h.hid,w.worker_name,h.send_water_time,c.cust_name,h.send_water_count
        FROM tb_history h, tb_worker w, tb_customer c
        WHERE h.worker_id = w.wid and h.cust_id = c.cid
    </select>
</mapper>

 注意:

javaType(结果集)要加上全限定名,不然可能出现找不到实体类的问题

一定要文档注释,写sql语句时会有提示 

1.5 编写Service接口

package com.shouyi.service;

import com.shouyi.entities.History;

import java.util.List;

/**
 * TODO 送水历史管理业务逻辑接口
 * @author caojie
 * @version 1.0
 */
public interface HistoryService {
    /**
     查询所有送水历史信息
    */
    List<History> listHistory() ;
}

1.6 编写Service接口实现类

package com.shouyi.service.impl;

import com.shouyi.entities.History;
import com.shouyi.mapper.HistoryMapper;
import com.shouyi.service.HistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * TODO:送水历史管理接口实现类
 * @author caojie
 * @version 1.0
 */
@Service
public class HistoryServiceImpl implements HistoryService {

    @Autowired
    private HistoryMapper historyMapper;
	/**
     查询所有送水历史信息
    */
    @Override
    public List<History> listHistory() {
        return historyMapper.listHistory();
    }
}

1.7 编写Controller控制器

package com.shouyi.controller;

import com.shouyi.entities.History;
import com.shouyi.service.HistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * TODO
 *
 * @author caojie
 * @version 1.0
 * @date 2021/10/25 20:20
 */
@RequestMapping("/history")
@Controller
@Slf4j
public class HistoryController {

    @Autowired
    private HistoryService historyService;
	/**
	点击“送水历史管理”,调用HistoryService对象查询所有送水历史信息,然后将信息渲染到前端。最后返回“送水历史”页面
	*/
    @RequestMapping("/listHis")
    public String listHistory(Model model) {
        List<History> hisList = historyService.listHistory();
        log.info("history list size = "+hisList.size());
        model.addAttribute("hisList",hisList);
        return "historyList";
    }
}

1.8 编写送水历史管理列表页面

resources/water路径下创建客户管理列表页面historyList.html,显示送水历史信息。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title> 冯宝宝送水后台管理系统</title>

    <!--Bootstrap固定框架-->
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
    <!--图标库-->
    <link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
    <!--核心样式-->
    <link rel="stylesheet" th:href="@{/css/style.css}">
    <script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
    <script>
        $(function() {
            // 为“全选/全不选”复选框绑定单击事件,一旦触发该事件要么“全选”送水历史复选框,要么全不选
            $("#selectAll").click(function() {
                // 使用元素属性选择器选择所有的“送水历史复选框”  prop---> property
                $("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
            })

            // 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
            $("#batchDelete").click(function(){
                // 获取所有选中的“送水历史”复选框
                let chkList = $("input[name=chkHistory]:checked");
                // 条件成立:表示一个都没有选择,终止批量删除操作
                if(chkList.length == 0) {
                    alert("请至少选择一项");
                    return;
                }
                // 存储复选框的id属性值
                let ids = "";
                // 获取所有选中的“送水历史”复选框id值
                $(chkList).each(function(){
                    let id = $(this).val();
                    // 对选中的ID进行拼接
                    ids += ","+id;
                })
                // 使用异步ajax技术,向后端发起批量删除请求
                $.ajax({
                    url:'/history/batchDeleteHistory',
                    data:{
                        idList:ids
                    },
                    method:'POST',
                    success: function(data,status) {
                        if (data == "OK") {
                            alert("批量删除成功");
                            window.location.href = "/history/listHis";
                        } else {
                            alert("批量删除失败");
                        }
                    }
                })
            })
        })
    </script>
</head>
<body>

<div id="viewport">

    <!-- Sidebar
    客户列表页面使用th:replace属性替换成主菜单的侧边栏,让代码能够复用
    th:replace="waterMainMenu::sidebar"
    waterMainMenu表示主菜单页面的文件名称
    sidebar表示主菜单页面的片段名称
    -->
    <div id="sidebar" th:replace="waterMainMenu::sidebar">

    </div>

    <!-- Content -->
    <div id="content">
        <!--
th:replace="waterMainMenu::navbar"表示将nav标签里面所有的内容替换为主页面的navbar片段
        -->
        <nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">

        </nav>
        <div class="container-fluid">
            <div class="row">

                <div class="col-md-12">
                    <div class="col-md-4">
<!--                        点击“添加”按钮跳转到“添加送水历史”页面-->
                        <a class="btn btn-primary" href="/history/preSaveHis">添加</a>
                        <a class="btn btn-danger" href="#" id="batchDelete">批量删除</a>
                    </div>
                </div>
                <div class="col-md-12">
                    <table class="table table-hover table-striped">
                        <thead>
                        <tr>
                            <td>
                                <input type="checkbox" name="selectAll" id="selectAll" /> 全选/全不选
                            </td>
                            <td>送水历史编号</td>
                            <td>送水工名称</td>
                            <td>送水时间</td>
                            <td>客户名称</td>
                            <td>送水数量</td>
                            <td>操作</td>
                        </tr>
                        </thead>
                        <tbody>
                        <tr th:each="his : ${hisList}">
                            <td>
                                <input type="checkbox" th:value="${his.hid}" name="chkHistory"/>
                            </td>
                            <td th:text="${his.hid}"></td>
                            <td th:text="${his.worker.workerName}"></td>
                            <td th:text="${#dates.format(his.sendWaterTime,'yyyy-MM-dd')}"></td>
                            <td th:text="${his.customer.custName}"></td>
                            <td th:text="${his.sendWaterCount}"></td>
                            <td>
                                <a class="glyphicon glyphicon-edit" th:href="@{'/history/preUpdateHis/'+${his.hid}}"></a>
                            </td>
                        </tr>
                        </tbody>
                    </table>
                </div>
            </div>

        </div>
    </div>

</div>

</body>
</html>
<td th:text="${his.worker.workerName}"></td>workerName是在worker表里的

1.9 编写主页面

修改主页面waterMainMenu.html,在“送水历史管理”菜单里面定义超链接

    <li>
        <a th:href="@{/history/listHis}">
          <i class="zmdi zmdi-widgets"></i> 送水历史管理
        </a>
      </li>

2 添加送水历史信息

添加页面选择对应的“送水工”和“客户”,输入”送水时间“和“送水数量”  

2.1编写Mapper接口

由于History涉及到三张表,我们无法使用Mapper内置的添加方法。必须在HistoryMapper接口里面定义saveHistory方法来添加“送水历史”信息。

    /**
     * 添加送水历史
     * @param history 送水历史信息
     * @return  受影响行数,大于0添加成功,否则添加失败
     */
    int saveHistory(History history);

2.2 编写Mapper映射文件

 在HistoryMapper.xml映射文件中定义insert节点,添加“送水历史”信息。

    <insert id="saveHistory" >
        insert into tb_history(worker_id,cust_id,send_water_time,send_water_count)
        values(#{worker.wid},#{customer.cid},#{sendWaterTime},#{sendWaterCount})
    </insert>

2.3 编写Service接口

 /**
     * 添加送水历史
     * @param history 表单采集的送水历史信息
     * @return 手影响行数,大于0添加成功,否则添加失败
     */
    int saveHistory(History history);

2.4 编写接口实现类

    /**
     * 添加送水历史
     *
     * @param history 表单采集的送水历史信息
     * @return 受影响行数,大于0添加成功,否则添加失败
     */
    @Override
    public int saveHistory(History history) {
        return historyMapper.saveHistory(history);
    }

2.5 编写Controller

/**
 	送水历史需要用到客户信息,自动装配CustomerService对象
 	*/
	@Autowired
    private CustomerService customerService;
 	/**
 	送水历史需要用到送水工信息,自动装配WorkerService对象
 	*/
    @Autowired
    private WorkerService workerService;

	/**
	点击“添加”按钮执行预修改操作
	步骤:
	1 查询客户列表和送水工列表
	2 将客户列表和送水工列表渲染到前端页面
	3 返回送水历史页面
	*/
    @RequestMapping("/preSaveHis")
    public String preSaveHistory(Model model) {
        // 查询客户列表和送水工列表,渲染到前端
        List<Customer> custList = customerService.listCustomer();
        List<Worker> workerList = workerService.listWorker();

        model.addAttribute("custList",custList);
        model.addAttribute("workerList",workerList);
        return "historySave";
    }
	/**
     * 在“添加送水历史页面”点击“提交”按钮,将送水历史信息持久化(insert插入)到数据库中,然后返回“送水历史列表”,重新
     * 查询送水历史列表显示新添加的数据
     * 步骤:
     * 1 将客户ID和送水工ID注入到History对象
     * 2 调用HistoryService对象的saveHistory方法将表单采集的数据持久化到数据库
     * 3 重新“查询送水历史信息”,显示新添加的数据
     * @param  workerId 表单采集的送水工编号
     * @param  custId 表单采集的客户编号
     * @param history 表单采集的送水历史信息
     * @return 重定向到送水历史列表路径
     */
    @RequestMapping(value="/saveHis",method = RequestMethod.POST)
    public String saveHistory(Integer workerId,Integer custId,History history) {
        log.info("save History workerId = "+workerId);
        log.info("save History customerId = "+custId);
        log.info("History history = "+history);
        // 将送水工编号和客户编号注入到History对象
        Worker worker = new Worker();
        worker.setWid(workerId);

        Customer customer = new Customer();
        customer.setCid(custId);

        history.setCustomer(customer);
        history.setWorker(worker);
        // 将History对象持久化到数据库
        int rows =historyService.saveHistory(history);
        log.info("save History rows = "+rows);
        return "redirect:/history/listHis";
    }

2.6 编写送水历史列表页面

在送水历史列表页面新增加一个“添加”按钮,单击“添加”按钮跳转到“添加送水历史”页面

<div class="col-md-12">
                    <div class="col-md-4">
                        <a class="btn btn-primary"
                            th:href="@{/history/preSaveHis}">添加</a>
                    </div>
                </div>

2.7 编写添加送水历史页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title> 冯宝宝送水后台管理系统</title>

    <!--Bootstrap固定框架-->
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
    <!--图标库-->
    <link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
    <!--核心样式-->
    <link rel="stylesheet" th:href="@{/css/style.css}">

</head>
<body>

<div id="viewport">

    <!-- Sidebar -->
    <div id="sidebar" th:replace="waterMainMenu::sidebar">

    </div>

    <!-- Content -->
    <div id="content">
        <nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">

        </nav>
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <form class="form-horizontal" method="post" th:action="@{/history/saveHis}" >
                        <div class="form-group">
                            <label  class="col-sm-2 control-label">送水工名称</label>
                            <div class="col-sm-5">
                                <select name="workerId" class="form-control">
<!--                                    遍历每一个送水工选择-->
                                    <option th:each="worker : ${workerList}"
                                        th:value="${worker.wid}"
                                        th:text="${worker.workerName}"/>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <label  class="col-sm-2 control-label">送水时间</label>
                            <div class="col-sm-5">
                                <input type="date" class="form-control"
                                       name="sendWaterTime"  placeholder="送水时间">
                            </div>
                        </div>

                        <div class="form-group">
                            <label  class="col-sm-2 control-label">客户名称</label>
                            <div class="col-sm-5">
<!--                                以下拉列表框的形式展示所有的客户信息,实际的值是客户ID,显示的文本是客户名称-->
                                <select name="custId" class="form-control">
<!--                                    遍历客户信息-->
                                    <option th:each="cust : ${custList}"
                                            th:value="${cust.cid}" th:text="${cust.custName}"/>
                                </select>
                            </div>
                        </div>
                        <div class="form-group" >
                            <label  class="col-sm-2 control-label">送水数量</label>
                            <div class="col-sm-5">
                                <input type="text" class="form-control"
                                       name="sendWaterCount"  placeholder="送水数量"/>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-sm-5">
                                <input type="submit" class="btn btn-primary" name="submit"  value="提交">
                                &nbsp;&nbsp;
                                <input type="reset" class="btn btn-warning" name="reset"  value="取消">
                            </div>

                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</div>

</body>
</html>

3 修改送水历史信息

修改"送水历史"流程如下:  

3.1 编写Mapper接口

 /**
     * 根据送水历史ID查询对应的送水历史
     * 用途:修改之前的数据回显
     * @param hid 送水历史ID
     * @return 送水历史信息
     */
    History getHistoryById(Integer hid);

 /**
     * 修改送水历史
     * @param history 表单采集的的送水历史信息
     * @return update语句受影响行数,大于0修改成功,否则修改失败
     */
    int updateHistory(History history);

3.2 编写Mppaer映射文件

<!--
       根据id查询对应的送水历史信息
       id="getHistoryById" 对应HistoryMapper接口的getHistoryById方法
       resultMap="selectHistoryMap"表示select查询语句返回的结果集是selectHistoryMap
       parameterType="int" 表示getHistoryById方法的参数类型是Integer类型
   -->
    <sql id="selectHistory" >
        SELECT h.hid, w.worker_name, h.send_water_time, c.cust_name, h.send_water_count
        FROM tb_history h,tb_worker w, tb_customer c
    </sql>

    <select id="getHistoryById" resultMap="selectHistoryMap" parameterType="int" >
        <include refid="selectHistory"></include>
        WHERE h.worker_id = w.wid and h.cust_id = c.cid and hid = #{hid}
    </select>
    <!-- 修改“送水历史信息"
        id="updateHistory"对应HistoryMapper接口的updateHistory方法
        parameterType="History"表示HistoryMapper接口的updateHistory方法参数类型为History
    -->
    <update id="updateHistory" parameterType="History">
        update tb_history
        set worker_id = #{worker.wid}, cust_id = #{customer.cid},
            send_water_time = #{sendWaterTime}, send_water_count = #{sendWaterCount}
        where hid = #{hid}
    </update>

3.3 编写Service接口

 /**
     * 根据送水历史ID查询对应的送水历史
     * 用途:修改之前的数据回显
     * @param hid 送水历史ID
     * @return 送水历史信息
     */
    History getHistoryById(Integer hid);

    /**
     * 修改送水历史
     * @param history 表单采集的的送水历史信息
     * @return update语句受影响行数,大于0修改成功,否则修改失败
     */
    int updateHistory(History history);

3.4 编写Service接口实现类

/**
     * 根据送水历史ID查询对应的送水历史
     * 用途:修改之前的数据回显
     *
     * @param hid 送水历史ID
     * @return 送水历史信息
     */
    @Override
    public History getHistoryById(Integer hid) {
        return historyMapper.getHistoryById(hid);
    }

    /**
     * 修改送水历史
     *
     * @param history 表单采集的的送水历史信息
     * @return update语句受影响行数,大于0修改成功,否则修改失败
     */
    @Override
    public int updateHistory(History history) {
        return historyMapper.updateHistory(history);
    }

3.5 编写Controller控制器

/**
     * 在“送水历史列表”页面,点击“修改”按钮,根据ID查询对应的“送水历史”信息,然后将信息渲染到前端页面
     * 步骤:
     *  1 查询所有客户信息
     *  2 查询所有送水工信息
     *  3 根据ID查询对应的送水历史信息
     *  4 将以上信息渲染到前端页面上
     *  5 跳转到“修改送水历史”页面
     * @param hid  送水历史ID
     * @param model
     * @return “修改送水历史”页面
     */
    @RequestMapping("/preUpdateHis/{hid}")
    public String preUpdateHistory(@PathVariable("hid") Integer hid, Model model) {
        List<Customer> custList = customerService.listCustomer();
        List<Worker> workerList = workerService.listWorker();
        History history = historyService.getHistoryById(hid);
        // 将查询的数据渲染到前端页面,完成数据的回显
        model.addAttribute("custList",custList);
        model.addAttribute("workerList",workerList);
        model.addAttribute("history",history);
        // 跳转到“修改送水历史”页面
        return "historyUpdate";
    }

    /**
     * 点击“提交”按钮修改送水历史信息,修改完毕重定向执行“送水历史列表”,显示已修改的“送水历史信息”
     * 步骤:
     *  1 将送水工ID和客户ID注入到History对象
     *  2 调用HistoryService对象的updateHistory方法完成修改
     *  3 修改完毕重定向执行“送水历史列表”
     * @param workerId 送水历史对应的送水工ID
     * @param custId   送水历史对应的客户ID
     * @param history 送水历史信息
     * @return 重定向执行“送水历史列表”
     */
    @RequestMapping(value="/updateHis",method=RequestMethod.POST)
    public String updateHistory(Integer workerId,Integer custId,History history) {
        log.info(" update custId id = "+custId);
        log.info(" update worker id = "+workerId);
        log.info(" update History = "+history);
        Worker worker = new Worker();
        worker.setWid(workerId);

        Customer customer = new Customer();
        customer.setCid(custId);
        history.setCustomer(customer);
        history.setWorker(worker);
        // 修改送水历史,返回受影响行数
        int rows = historyService.updateHistory(history);
        log.info("update history rows = "+rows);
        return "redirect:/history/listHis";
    }

3.6 编写送水历史列表页面 historyUpdate.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title> 冯宝宝送水后台管理系统</title>

    <!--Bootstrap固定框架-->
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
    <link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
    <!--图标库-->
    <link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
    <!--核心样式-->
    <link rel="stylesheet" th:href="@{/css/style.css}">

</head>
<body>

<div id="viewport">

    <!-- Sidebar -->
    <div id="sidebar" th:replace="waterMainMenu::sidebar">

    </div>

    <!-- Content -->
    <div id="content">
        <nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">

        </nav>
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-12">
                    <form class="form-horizontal" method="post" th:action="@{/history/updateHis}" >
<!--                type="hidden"表示提交表单将送水历史的hid作为隐藏域传入到后端的Controller
                    type="hidden" 特征:隐藏在表单内部,浏览器看不见hid
        -->
                        <input type="hidden" th:value="${history.hid}" name="hid" />
                        <div class="form-group">
                            <div class="col-sm-2">送水工名称</div>
                            <div class="col-sm-5">
                                <select name="workerId" class="form-control">
                                    <!--                                    遍历每一个送水工选择
                                    th:selected="${history.worker.wid eq worker.wid}"
                                    条件成立:就将worker对象设置为选中状态
                                    -->
                                    <option th:each="worker : ${workerList}"
                                            th:selected="${history.worker.workerName eq worker.workerName}"
                                            th:value="${worker.wid}"
                                            th:text="${worker.workerName}"/>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-sm-2">送水时间</div>
                            <div class="col-sm-5">
                                <input type="date" class="form-control"
                                       th:value="${#dates.format(history.sendWaterTime,'yyyy-MM-dd')}"
                                       name="sendWaterTime"  placeholder="送水时间">
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-sm-2">客户名称</div>
                            <div class="col-sm-5">
                                <!--                                以下拉列表框的形式展示所有的客户信息,实际的值是客户ID,显示的文本是客户名称-->
                                <select name="custId" class="form-control">
                                    <!--                                    遍历客户信息-->
                                    <option th:each="cust : ${custList}"
                                            th:selected="${cust.custName eq history.customer.custName}"
                                            th:value="${cust.cid}" th:text="${cust.custName}"/>
                                </select>
                            </div>
                        </div>
                        <div class="form-group" >
                            <div class="col-sm-2">送水数量</div>
                            <div class="col-sm-5">
                                <input type="text" class="form-control"
                                       th:value="${history.sendWaterCount}"
                                       name="sendWaterCount"  placeholder="送水数量"/>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-sm-5">
                                <input type="submit" class="btn btn-primary" name="submit"  value="提交">
                                &nbsp;&nbsp;
                                <input type="reset" class="btn btn-warning" name="reset"  value="取消">
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</div>

</body>
</html>

4 批量删除

4.1 编写Mapper接口

int batchDeleteHistory(@Param("ids") List<Integer> ids);

4.2 编写Mppaer映射文件

<delete id="batchDeleteHistory" parameterType="list">
        delete from tb_history
        where hid in
        <foreach collection="ids" item="hid"  open="(" close=")" separator=",">
            #{hid}
        </foreach>
    </delete>
批量删除就是in(sql语句: delete from tb_history where hid in (1,2,3))

<foreach>标签:该标签的作用是遍历集合类型的条件

    item表示集合中每一个元素进行迭代时的别名.

    index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置.

    open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符.

    close表示以什么结束
 

用来循环 collection(集合的父类) : 用来指定循环的数据的类型 可以填的值有:array,list,map item 

4.3 编写Service接口

 /**
     * 批量删除
     * @param idList 需要批量删除的送水历史id列表
     * @return 受影响行数,大于0批量删除成功,否批量删除失败
     */
    int batchDeleteHistory(String idList);

4.4 编写Service接口实现类

 /**
     * 批量删除
     *
     * @param idList 需要批量删除的送水历史id列表
     * @return 受影响行数,大于0批量删除成功,否批量删除失败
     */
    @Override
    public int batchDeleteHistory(String idList) {
        // 字符串转换为List集合
        String[] split = StrUtil.split(idList, ",");
        List<Integer> ids = new ArrayList<>();
        for (String id : split) {
            if (StrUtil.isNotEmpty(id)) {
                ids.add(Integer.parseInt(id));
            }
        }
        return historyMapper.batchDeleteHistory(id);
    }

4.5 编写Controller控制器

/**
     * 处理批量删除请求
     * @param idList 前端传入的要删除的送水历史id列表
     * @return OK 批量删除成功,Fail表示批量删除失败
     */
    @RequestMapping(value="/batchDeleteHistory",method = RequestMethod.POST)
    @ResponseBody
    public String batchDeleteHistory(String idList) {
        // 调用业务逻辑层方法进行批量删除
        int rows = historyService.batchDeleteHistory(idList);
        if (rows > 0) {
            return "OK";
        } else {
            return "Fail";
        }
    }

historyList.html页面添加删除js

注意:怎么实现批量删除?首先要思考选中全选后,所有的数据都要被选中

1.要有一个主函数

2.全选和全不选的单击事件

3.找到批量删除的按钮和全选/全不选的按钮

 <a class="btn btn-danger" href="#" id="batchDelete">批量删除</a>

 再找到

                <div class="col-md-12">
                    <table class="table table-hover table-striped">
                        <thead>
                        <tr>
                            <td>
                                <input type="checkbox" name="selectAll" id="selectAll" /> 全选/全不选
                            </td>
                            <td>送水历史编号</td>
                            <td>送水工名称</td>
                            <td>送水时间</td>
                            <td>客户名称</td>
                            <td>送水数量</td>
                            <td>操作</td>
                        </tr>
                        </thead>
                        <tbody>
                        <tr th:each="his : ${hisList}">
                            <td>
                                <input type="checkbox" th:value="${his.hid}" name="chkHistory"/>
                            </td>
                            <td th:text="${his.hid}"></td>
                            <td th:text="${his.worker.workerName}"></td>
                            <td th:text="${#dates.format(his.sendWaterTime,'yyyy-MM-dd')}"></td>
                            <td th:text="${his.customer.custName}"></td>
                            <td th:text="${his.sendWaterCount}"></td>
                            <td>
                                <a class="glyphicon glyphicon-remove" th:href="@{'/history/delHis/'+${his.hid}}"></a>
                                <a class="glyphicon glyphicon-edit" th:href="@{'/history/preUpdateHis/'+${his.hid}}"></a>
                            </td>
                        </tr>
                        </tbody>
                    </table>
                </div>

4.获取两个按钮的id,怎么获取呢?用#{ }

5.然后再入口函数中写js代码()

<script>   
 $(function () {
        //全不选或全选的单击事件
        $("#selectAll").click(function () {
            
        })
    })
</script>   

 6.在id选择器中用元素选择器去全选

<script>
    $(function () {
        //全不选或全选的单击事件
        $("#selectAll").click(function () {
            // 使用元素属性选择器选择所有的“送水历史复选框”  prop---> property
            $("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
        })
    })
</script>

prop是自身的方法 ,checked:选中

7.点击批量删除按钮触发事件

<script>
$(function() {
// 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
            $("#batchDelete").click(function(){
                // 获取所有选中的“送水历史”复选框
                let chkList = $("input[name=chkHistory]:checked");
                // 条件成立:表示一个都没有选择,终止批量删除操作
                if(chkList.length == 0) {
                    alert("请至少选择一项");
                    return;
                }
                // 存储复选框的id属性值
                let ids = "";
                // 获取所有选中的“送水历史”复选框id值
                    $(chkList).each(function(){                                  //循环遍历复选框id值
                    let id = $(this).val();                                  //获取到所有的
                    // 对选中的ID进行拼接
                    ids += ","+id;                                           //回想一下sql删除语句 :delete from tb_history where hid in (1,2,3)
                })
                // 使用异步ajax技术,向后端发起批量删除请求 (拿到id之后,就是删除)
                $.ajax({
                    url:'/history/batchDeleteHistory',                       //向后台发送的删除请求接口
                    data:{                                                   //参数
                        idList:ids                                           //后端方法需要传的参数
                    },
                    method:'POST',                                           //请求方式
                    success: function(data,status) {                         //success:成功   data:数据(需要删除的)status:状态(删除后返回的状态)
                        if (data == "OK") {
                            alert("批量删除成功");
                            window.location.href = "/history/listHis";
                        } else {
                            alert("批量删除失败");
                        }
                    }
                })
            })
        })
</script>
// 获取所有选中的“送水历史”复选框
let chkList = $("input[name=chkHistory]:checked");

 input:  标签

[name=chkHistory]:标签名称

checked:方法(自带)

8.拿到id之后就是删除了(需要我们使用的Ajax) 

<script>
        $(function() {
            // 为“全选/全不选”复选框绑定单击事件,一旦触发该事件要么“全选”送水历史复选框,要么全不选
            $("#selectAll").click(function() {
                // 使用元素属性选择器选择所有的“送水历史复选框”  prop---> property
                $("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
            })


            // 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
            $("#batchDelete").click(function(){
                // 获取所有选中的“送水历史”复选框
                let chkList = $("input[name=chkHistory]:checked");
                // 条件成立:表示一个都没有选择,终止批量删除操作
                if(chkList.length == 0) {
                    alert("请至少选择一项");
                    return;
                }
                // 存储复选框的id属性值
                let ids = "";
                // 获取所有选中的“送水历史”复选框id值
                $(chkList).each(function(){
                    let id = $(this).val();
                    // 对选中的ID进行拼接
                    ids += ","+id;
                })
                // 使用异步ajax技术,向后端发起批量删除请求
                $.ajax({
                    url:'/history/batchDeleteHistory',
                    data:{
                        idList:ids
                    },
                    method:'POST',
                    success: function(data,status) {
                        if (data == "OK") {
                            alert("批量删除成功");
                            window.location.href = "/history/listHis";
                        } else {
                            alert("批量删除失败");
                        }
                    }
                })
            })
        })
    </script>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
公司的每一分钱都来源于客户,在商业竞争日益激烈的今天,谁的服务好,抓住了客户,谁就抓住了财 富,就能在商业竞争中立于不败这地,邦仁客户管理系统帮您管理好销售的每个环节,管理好您的客户。 邦仁桶装水配送管理软件根据上千家成功企业独到管理经验开发而成,软件一上市便受到了业内专家 和客户的高度赞许与肯定。实用性的功能模块完全按照水店配送管理行业流程设计。已成为业内一流的软 件产品,产品的业务流程、先进的配送管理实施已成为水店配送管理软件行业的领头羊。软件把电脑与电 话功能集成,电脑上安装客户管理软件及来电接收器, 当客户来电时,电脑会在资料库中查询客户资料 , 并在电话第二声响铃时在电脑屏幕上弹出客户资料,让你在一接电话时就能叫出客户的名字, 客户一 定会感觉很惊喜,同时,与该客户的相关业务记录、财务信息、服务反馈及来电记录也同时显示出来,相 信软件必定会大大地帮您提高工作效率, 客户的满意度也会大大的提高。 软件特点 来电弹出客户,通话自动录音,缩短订水时间,提高订水数量和准确度; 支持多部电话同时来电同时弹出,多客户可以同时开单,缩短开单时间,比市面上队列式弹出更先进 提醒客户预约和订水频率提醒等多种提醒功能,防止客户流失 及时了解客户财务信息-欠桶,欠款,欠票,押桶 可以同时支持一路、两路及多路电话叠加 无需人工输入,自动填写派工单与回单 同时支持手机短讯派单,飞信,QQ等派单方式; 操作简便,点点鼠标就可以完成工作 防止假水假水票 支持市面上所有的Pos打印机(58/75/80等型号)和所有宽行打印机,打印店名地址配送电话等自已设置 ,自已设置字体大小; 独有的接线机器人功能,自动打印派工单 用户可自定义设置来电提示音功能,软件可以在无人值守的情况,语音提示用户,完成订水过程,并自动 打印配送单(订水机器人是额外收费的) 完善的进销存功能 方便简洁的短信单发和群发功能(向公司申请开通此功能) 多角度的报表输出和分析功能 支持多店连锁管理(联锁呼叫中心方案向我公司索要) 支持多用户协同工作 支持现金,月结,水票,水卡,签单等所有结算方式 功能介绍 是一个专业的电话服务系统 来电号码和客户资料自动弹出,多个电话同时打来,软件可以同时弹出,不用 输入客户编号就可得知客户地址,订水品牌,剩余水票,定购总金额,欠桶数量,押金,最后订购时间等 情况。让客户的资料一目了然,陌生客户第一次来电还可弹出来电归属地。 基本资料设置 1.配送的水种品牌、进货价、销售价、初始库存、初始空瓶等设置,可让软件识别我们做的业务,同时让 软件自动为我们管理各个品水牌的库存,及时准确的了解库存; 2.员工管理 设置员工为业务员或配送员,当设置成业务员/配送员时我们可以通过软件报表统计统计业 务员的提成,而且可以看到业务员/配送员历史与当天的任一时间的销售配送和提成状况。 3.片区设置 根据自己客户的实际情况分配片区,灵活实用的片区销售报表可以帮你看到各个片区的任何 时间内的销售情况,让我们对桶装水配送做出更合理的优化方案。 4.供应商管理 将自己的供应商录入软件内,方便我们查找供应商,同时了解与供应商的财务信息情况 5.工作模式设置 单机版本和网络版本合二为一, 购买一套在一台电脑上运行就是单机版本,购买多套 在多台电脑运行,简单的设置一下就可以实现数据共享,行成网络版本 6.操作员管理 设置成不同用户、不同权限登入软件使客户资料更安全。在system超级用户名下设置其他 的用户可对其他的用户权限划分,修改客户、删除客户、修改供应商、删除供应商、修改销售单、删除销 售单、开进货单、浏览销售统计报表、删除来电日志、导出客户资料等,勾选代表赋予权限 7.用户信息设置 设置自己公司或水站自己的名称、地址、电话、其他说明等,可个性化打印出自己喜爱 的打印小票 8.录音及外线设置 可设置软件是否自动录音,根据自己电脑硬盘大小设置录音文件是否删除,删除的话 留存多少天删除。特有的外线过滤功能可设置任意外线号码,轻松过滤来电前的外线 9.客户资料的录入 可通过软件快捷键迅速新建客户,对客户的卡号、地址、联系人、开卡日、电话(可 设无数个)、收款方式、片区、月结日、订水频度、洗机情况、销户日期、业务员/配送员及提成、借机 、押瓶、喜爱品牌及价格、备注和客户财务信息等设置  强大的提醒功能 根据客户实际的订水周期设定天数,超过该频率未订水的客户,软件里都会有提醒。对 于预约订水的客户,可以设置具体的时间提醒、多少时间提醒。月结客户的月结提醒,方便我们合理分配 时间; 客户订水操作 客户订单编号自动生成 格式如下:SH080103-00001,080103:年月日, 00001:当天的订单号,每天都会从 00001开始自动编起,比如:sh080101-00001 表示2008年1月1日的第一张订单; 订水订单处理 当客户用客户资料里的其中一个电话打过来的时候,多个电话同时打过来软件会同时弹出 所有客户资料且自动记录该客户的订水品牌、数量和价格。跟客户校对后点“立即送水”按钮,软件会自 动填写配送单且客户资料里的财务信息会自动积累欠款数量、欠票数量、欠桶数量等,这时我们可以选择 打印软件预设的不打印/窄行打印/宽行打印3种模式中的一种,以后软件会自动选择该打印方式打印小票 。配送员便可以凭借小票配送和回款及回瓶。而且订水如果洗机会主动更新客户的最新洗机时间 订单修改 当出现客户要改订其他水或打印机卡纸时,我们可以双击该单进行修改、重新打印和删除该单重新做新单 。当出现客户退单时,我们可以直接删除该单和选择软件快捷按钮进行销售退货; 订水回单处理 配送员送完水以后我们就要做回单操作了,点“回单”按钮软件会自动根据客户的收款方式不同自动填写 回单,你只要核对客户的已收款,已收水票,已回桶,送水提成,基本无需录入,客户财务信息里会自动累 计 欠款金额、欠票数量、欠桶数量等。且没有回单跟回了单的订单有颜色区分(红色的代表没有回单, 白色的代表已经回了单),同时软件会对每个商品的空桶统计,总的空桶统计等; 水票处理 可以对水票客户进行快速充值,客户财务信息里会自动累加水票总数,可以管理每张水票的票号,收票后 可以查询水票号,防止假水票,在报表里有客户在任一段时间充水票的详细情况,你也可以快速查询水票 客户剩余水票情况; 进销存管理 实时显示当前所有产品的库存数,空瓶数量。销售自动出库,并自动更新库存,出库统计,入库统计,自 动累计,每一供应商的未付款,欠瓶等; 经营状况分析 强大的经营分析报表,业务员,配送员的配送明细表与提成报表,每日销售配送报表,水票统计报表,配 送员洗机报表,每个客户的欠桶统计表; 销售明细报表 可对任何时间段内的配送员、各类水品牌和客户作为条件索引查询销售情况,实时掌控经营状况,及准确 算出配送员的工资提成。同时也方便对帐; 客户财务统计表 可统计所有客户订水品牌及单价、押金、欠瓶、欠款、未收水票等,方便掌控客户资讯; 多角度销售统计报表 可通过时间查询各个时间段内的产品销售情况,提供年、月、日、配送员、产品和客户等多个索引查询, 轻松做到甩手老板; 所有报表可导出,供打印或二次编辑个性化样式; 客户资料的方便查询(支持模糊查询)和录入修改 来电日志的管理 可通过时间查询各个时间段内的来电客户的时间、电话、地址、订购品牌、接线员和事由等。也可删除你 的来电,亦可通过时间打印个时间段内的来电记录; 软件可最小化到计算机右下脚的托盘中不影响用户进行其他操作,一旦来电,自动弹出小窗口,并捕捉来 电进行订单录入操作 客户资料导入和导出 正式版软件可将客户资料直接导入本软件,免去录入资料的步骤。有权限的用户可迅速导出软件方便自己 编辑个性化资料。 短信单发和群发 可以给送水员发送短信来实现送水信息的传递,也可以实现对客户在节假日群发祝福短信或平时的促销短 信,还可以定时发送,到了该时间软件会自动给设定的客户发送。 试用版登录帐号 用户名:system 密码:空 适用对象 桶装水配送店及煤气配送点。 软件价格及服务 服务: 终身电话、Email终身免费支持,软件终身免费升级,硬件三个月内有问题包换。 历史版本更新 -------------------------------------------------------------------------------- 10.1版改进 1、增加退单查询报表 2、宽行打印有表格线输出,打印格式更漂亮 3、录单文件存放路径支持自己设置 4、开进货单放宽限制,开入库单时充许数量为0 5、工具栏和订单区右键增加“派单”按钮,派单操作更简单直接 6、对数据进行加密处理,数据更安全 7、来电区来电记录更改排序算法,未处理来按电话先后自动上排,防止来电遗漏处理 8、增加来电区对陌客户开单提醒,有效防止人为误操作 9、增加软件对配送单在不同配送阶段的软件识别,引导用户进入下一步操作,有效避免错误操作 10、优化主界面客户搜索的功能智性,直接输入关键字回车,既可完成模糊搜索 11、回单窗口可直接录入备注 12、更新操作视频教程 10.0版改进 1、增加对现金出入里,对回桶,收现付现金的统计,作为其它收入和其它回瓶显示在主界面的统计栏里 2、增加库与库对导时,出入库记录,充票记录,供应商,操作员等其它数据表的自动导入 3、增加对收到的所有水票的核销功能,防止同号水票重复所用,防假水票更易操作 9.2版改进 1、增加录音文件存放目录自已设置支持 2、增加预先地址设置,录入客户时选地址 3、弹出客户资料窗口增加欠桶明细报表 4、增加水票核销功能,当现金客户用其它水票客户赠送的水票来结算时,可用些功能来核销掉原水票客 户的剩余水票 5、导入数据时,增加库与库对导的选项,方便用户升级 6、开配送单时,支持飞信通知配送员 9.1版改进 1、充水票未付清款自动产生欠款 2、现金出入增加其它收款和其它付款 3、修改了客户欠瓶明表不显示的BUG 4、打印字体大小支持自定义 5、押金条打印支持窄行打印和宽行打印 9.0版改进 1、增加多个客户共用一个电话的解决,会弹一个小窗口列出该电话对应的所有配送地址,选择地址后弹 出再做单 2、弹出窗口里直接显示历史送水记录 3、增加回单时,客户欠桶时收客户押金的支持 4、对每个客户都增加现金出入的功能,用以解决没送水但收到月结款,买水票水卡款,收支押金款,并 计入当日所收现金报表 5、增加产品销售利润报表,每日现金出入流量利润平衡表等多个报表 -------------------------------------------------------------------------------- 8.0版改进 1、软件界面全新设计 2、软件退出前增加备份数据的是提示 3、数据导入,备份数据,恢复数据等功能增加进度提示 -------------------------------------------------------------------------------- 7.1版改进 1、窄行打印的打印格式增加了店名、配送电话、配送地址和广告语的打印; 2、打印设置里,增加了打印的格式设置(不打印,宽行打印,窄行打印),开单时,系统会自动按设定 的打印格式打印小票; 3、更正了以往版本里更改客户编号,销售记录里的客户编号不随之更改的BUG; -------------------------------------------------------------------------------- 7.0版改进 1、系统增加押金条打印功能; 2、系统退桶和退押金功能,空桶自动更新库存; 3、宽行打印和窄行打印的单上增加欠桶、欠款和欠票等项目; 4、修改6.X版里客户资料的排序方式,改回按录入顺序的排序; 5、修改6.X版里订水记录的排序方式,未配送完的单排上面(有颜色区分),配送完的单按时间先后排下 面; 6、增加销售订单的备注查询; -------------------------------------------------------------------------------- 6.1版改进 1、系统增加对充水票记录的修改和删除; -------------------------------------------------------------------------------- 6.0版改进 1、系统增加对支装水、饮水机和纸杯等勿需回瓶的产品销售支持; 2、建订水记录时,增加了短讯自动通知送水工上门配送的功能; 3、更换了短讯发送网关,解决以往版本发短讯有延时的问题; 4、支持多用户联网群发短讯; 5、改进了客户与订单的索引方式,查询速度更快; 6、增加了版本升级时,导入销售数据的支持,解决以往版本升级时,销售数据无法导入的问题,此功能 适用6.0以上的版,从6.0以下的版本升级到6.0及以上版本时,不适用; 7、系统增加了数据操作工具,数据备份、恢复和清理维护等工作更简单、方便; -------------------------------------------------------------------------------- 5.2版改进 1、订单状态增加颜色区分,未回单的订单红色显示; 2、增加了操作权限的显示和修改功能; -------------------------------------------------------------------------------- 5.1版改进 1、增加业务员提成及业务员提成报表; 2、修改了以往版本在修改和删除订单时不更新客户财务信息和库存的BUG; 3、修改了以往有客户反应在有些系统上,选择时间不显示日历的现象; 4、订水如果洗机会主动更新客户的最新洗机时间 5、客户资料里加入押桶品牌 -------------------------------------------------------------------------------- 5.0版改进 1、客户资料增加累计总金额,累计总数量,弹出客户显示订水时间; 2、增加用户信息自定义设置,设置后,宽行打印订单时会打印出用户信息; 3、打印可以同时支持窄行打印(小票)和宽行打印,打印格式自动记忆; 4、订单号改成流水号,并自动生成,方便用户对单; 5、增加销售退单功能,退单自动重新计算库存; 6、增加每个商品的空桶统计,总的空桶统计等; 7、增加送水提成的计算,可根据客遍及户远近设置不同的提成; 8、修改了以往版本导入数据时,不导入客户财务数据的问题; 9、增加了各种报表都可以导出到excel文件,供二次编辑打印; 10、库存报表增加了进货金额,库存总量及库存总金额的计算; 11、增加了销售明细表,此表可生成配送员配送明细表,客户的销售明细表,产品的销售明细表等; 12、修改以往版本的销售订单不可以重复打印问题; 13、增加了每个客户的欠桶统计表,可统计出每个品牌的欠桶和数量; 14、增加配送员洗机报表;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值