不要害怕孤独,因为这个世界上总有一个人在努力走向你。

上节回顾:从一个简单页面带你体验H5开发 


这一节我们来做一个稍微有点难度的页面。首先还是上原型和UI设计

前端HTML5生成后端 前端h5页面怎么开发_前端

   

前端HTML5生成后端 前端h5页面怎么开发_前端_02

 了解主要功能:(1)数据库获取列表数据展示(2)年度、季度、部门、岗位的查询(3)重置(4)点击某一项弹出评分框-获取该条数据打分详情并展示(5)点击保存按钮发送请求、提交数据(6)点击提交按钮按照年份、季度提交所有记录。

确实比昨天的复杂一些,不过一步一步来,现在就开始吧。


1. 根据设计稿先写出前端静态页面

<body>
  <div class='top'></div>
  <div id="index-mask" class="index-mask" title="测评-首页">
    <div class="dqkhzq">
      <span class="khzq">当前考核周期:</span>
    </div>
    <div class="allDiv">
      <div class="divWrap" style="position:relative">
        <div class="divLeft">年份</div>
        <div class="divRight" id="year" style="padding-right:0.4rem;"> <input placeholder='请选择' value="2021"
            style="border:none;text-align:right;" id="yearInit" />
        </div>
        <img src="./images/kaoqin/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
        top: 0.35rem;right:0.4rem;" />
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap" style="position:relative">
        <div class="divLeft">季度</div>
        <div class="divRight" id="jidu" style="padding-right:0.4rem;"> <input id="jiduInit" placeholder="请选择"
            value="第二季度" style="border:none;text-align:right;" />
        </div>
        <img src="./images/kaoqin/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
        top: 0.35rem;right:0.4rem;" />
      </div>
    </div>
    <div class='allDiv'>
      <div class="divWrap" style="position:relative">
        <div class="divLeft">部门</div>
        <div class="divRight" id="bumen" style="padding-right:0.4rem;"> <input id="bumenInit" placeholder='请选择'
            style="border:none;text-align:right;" />
        </div>
        <img src="./images/huping/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
        top: 0.35rem;right:0.4rem;" />
      </div>
      <div class="hpVertical" style="position:relative"></div>
      <div class="divWrap" style="position:relative">
        <div class="divLeft">岗位</div>
        <div class="divRight" id="gangwei" style="padding-right:0.4rem;"> <input id="gangweiInit" placeholder='请选择'
            style="border:none;text-align:right;" />
        </div>
        <img src="./images/huping/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
        top: 0.35rem;right:0.4rem;" />
      </div>
      <div class="hpVertical" style="position:relative"></div>
      <div class="divWrap" style="justify-content: flex-end;">
        <span class="btncx" onclick="getDPList()">查询</span>
        <span class="btncz" onclick="resetList()">重置</span>
      </div>
    </div>
    <div id="content_1" class="content_1"></div>
    <!-- <div class="allDiv">
      <div class="divWrap">
        <div class="divLeft">姓名</div>
        <div class="divRight">刘明</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap">
        <div class="divLeft">部门</div>
        <div class="divRight">刑事侦察大队</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap">
        <div class="divLeft">岗位</div>
        <div class="divRight">综合管理岗</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap">
        <div class="divLeft">考核类型</div>
        <div class="divRight">非领导成员公务员</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap">
        <div class="divLeft">状态</div>
        <div class="divRightBlue">待提交</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap">
        <div class="divLeft">得分</div>
        <div class="divRightBlue">95</div>
      </div>
      <div class="hpVertical"></div>
      <div class="divWrap" style="justify-content: flex-end">
        <div class="rate" data-toggle="modal" data-target="#myModal">评分</div>
      </div>
    </div> -->
    <div style="text-align: center;">
      <div class="btnSubmit" id="submitBtn" onclick="allSubmit()">提交</div>
    </div>
  </div>
  <!-- 评分模态框(Modal) -->
  <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
    style="margin-top: -1.5rem;">
    <div class="modal-dialog" style="width: 6rem;">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
            ×
          </button>
          <div class="modal-title" id="myModalLabel">测评</div>
        </div>
        <div class="modal-body" style="padding-left: 0.3rem;">
          <div class="bodycontent">分值:<input class="inputS" type="text" id="fenzhi" disabled="disabled"></div>
          <div class="bodycontent" style="margin-top: 0.3rem;">打分:<input class="inputS" id="dafen"></div>
          <div class="bodycontent" style="margin-top: 0.3rem;">说明:<textarea class="textarea" rows="3" id="explain"
              disabled="true"></textarea></div>
        </div>
        <div class="modal-footer" style="text-align: center;">
          <button type="button" class="btn btn-default" data-dismiss="modal">取消
          </button>
          <button type="button" class="btn btn-primary" style="margin-top: 0.3rem;margin-bottom: 0.31rem;"
            onclick="btnSave()" id="baocun">
            保存
          </button>
          <button type="button" class="btn btn-primary" data-dismiss="modal"
            style="margin-top: 0.3rem;margin-bottom: 0.31rem;" id="queren">
            确认
          </button>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal -->
  </div>
  <!-- 提交Modal -->
  <div class="modal fade" id="subModal" tabindex="-1" role="dialog" aria-labelledby="subModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
            ×
          </button>
          <div class="modal-title" id="subModalLabel" style="color: black; font-weight: 400;">
            提交后不可修改,是否确认提交?
          </div>
        </div>
        <!-- <div class="modal-body">
          在这里添加一些文本
        </div> -->
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">取消
          </button>
          <button type="button" class="btn btn-primary" onclick="btnSure()">
            确定
          </button>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal -->
  </div>
</body>

 2. 添加年份、季度、岗位的select下拉框信息

<script src="./js/mobileSelect.js"></script>
var year = ['2017', '2018', '2019', '2020', '2021'];
  var mobileSelect1 = new MobileSelect({
    trigger: '#year',
    title: '年份',
    wheels: [
      { data: year }
    ],
    position: [4], //初始化定位 打开时默认选中的哪个 如果不填默认为0
    transitionEnd: function (indexArr, data) {
      $("#year").val(data[0])
    },
    callback: function (indexArr, data) {
    }
  });
  var jidu = ['第一季度', '第二季度', '第三季度', '第四季度'];
  var mobileSelect2 = new MobileSelect({
    trigger: '#jidu',
    title: '季度',
    wheels: [
      { data: jidu }
    ],
    position: [1], //初始化定位 打开时默认选中的哪个 如果不填默认为0
    transitionEnd: function (indexArr, data) {
      //console.log(data);
    },
    callback: function (indexArr, data) {
      $("#jidu").val(data[0])
    }
  });
// 岗位 0:综合管理岗,1:行政事务岗,2:行政执法岗,3:专业技术岗,4:窗口服务岗
  var choosedGangweiIndex = "";
  var gangwei = ['综合管理岗', '行政事务岗', '行政执法岗', '专业技术岗', '窗口服务岗'];
  var mobileSelect4 = new MobileSelect({
    trigger: '#gangwei',
    title: '岗位',
    wheels: [
      { data: gangwei }
    ],
    position: [0], //初始化定位 打开时默认选中的哪个 如果不填默认为0
    transitionEnd: function (indexArr, data) {
      //console.log(data);
    },
    callback: function (indexArr, data) {
      // console.log(indexArr[0])
      choosedGangweiIndex = indexArr[0]
      $("#gangwei").val(data[0])
    }
  });

其实对于部门也是一个道理,但是这里,部门不是固定枚举的,而是根据用户从数据库(调接口)中获取显示,因此我们稍后再解决

 3.同上一节的介绍,需要初始化页面并添加数据到content_1

var pageNum = 1; //默认是从第一页开始访问
  var pageSize = pageSizeGlobal; //默认一页访问的条数
  var isMore = false;
  var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
  var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
  var bumen = ""
  var gangwei = ""
  //第一次进入页面,加载2021第二季度的数据。
  getList(year, jidu, pageNum, pageSize, bumen, gangwei);
function getList(year, quarter, pageNum, pageSize, departmentId, jobPost) {
    // console.log(window.localStorage.getItem("currentUser"))
    $.ajax({
      type: "post",
      url: urlGlobal + "/api/h5/assess/score/evaluation/page",
      async: true,
      dataType: "json",//后台返回值类型
      contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型 
      async: false,//异步请求
      data: JSON.stringify({
        year: year,
        quarter: quarter,
        pageNum: pageNum,
        pageSize: pageSize,
        departmentId: departmentId,
        jobDuty: jobPost
      }),
      headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
      success: function (data) {
        console.log(data)
        if (data.code === 200) {
          total = data.data.totalCount; //总
          pades = data.data.totalPage; //总页数
          //isMore,当不是最后一页的时候,为ture,若是最后一页,则为false
          // data.data.list[0].status = 0;
          if (data.data.currPage < data.data.totalPage) {
            isMore = true;
          }
          if (data.data.currPage === data.data.totalPage) {
            isMore = false;
          }
          //如果总个数===0,做暂无数据的处理。
          if (data.data.totalCount == 0) {
            $("#content_1").empty();
            // $("#content_1").append("暂无内容");
            // 没有“提交按钮”
            document.getElementById("submitBtn").style.display = "none"
          } else {
            for (var i = 0; i < data.data.list.length; i++) {
              $("#content_1").append(strlistDom(data.data.list[i]))
            }
            //当前是最后一页的时候增加全部加载完毕的提示语
            if (data.data.currPage === data.data.totalPage) {
              $("#content_1").append("<div style='margin-top:0.2rem;margin-bottom:0.4rem;text-align:center;color: #999999;font-size:0.3rem;'>数据加载完毕</div>");
            }
          }
        } else {
          alertGlobal(data.message, 3000, true)
        }
      }
    });
  }

  // 获取页面DOM元素
  function strlistDom(data) {
    // 防止先查询到无数据后又查询有数据后不显示btn按钮
    var status = data.status === 0 ? "待提交" : "已提交";
    var score = data.score ? data.score : 0;
    var pfck = status === "已提交" ? "查看" : "评分"
    if (pfck === "查看") {
      document.getElementById("submitBtn").style.display = "none"
    } else {
      document.getElementById("submitBtn").style.display = "inline-block"
    }
    var str =
      "<div class='allDiv'>" +
      "<div class='divWrap'>" +
      "<div class='divLeft'>姓名</div>" +
      "<div class='divRight'>" + data.name + "</div></div>" +
      "<div class='hpVertical'></div>" +
      "<div class='divWrap'>" +
      "<div class='divLeft'>部门</div>" +
      "<div class='divRight'>" + data.department + "</div></div><div class='hpVertical'></div>" +
      "<div class='divWrap'>" +
      "<div class='divLeft'>岗位</div>" +
      "<div class='divRight'>" + data.jobPostStr + "</div></div><div class='hpVertical'></div>" +
      "<div class='divWrap'> <div class='divLeft'>考核类型</div>" +
      "<div class='divRight'>" + data.examineeTypeStr + "</div></div><div class='hpVertical'></div>" +
      "<div class='divWrap'><div class='divLeft'>得分</div>" +
      "<div class='divRight'>" + score + "</div></div><div class='hpVertical'></div>" +
      "<div class='divWrap'><div class='divLeft'>状态</div>" +
      "<div class='divRightBlue'>" + status + "</div></div><div class='hpVertical'></div>" +
      // 评分
      // "<div class='divWrap' style='justify-content: flex-end'><div class='rate' data-toggle='modal' data-target='#myModal'>评分</div></div>"
      // 查看  
      "<div class='divWrap' style='justify-content: flex-end'>" +
      "<div class='rate' data-toggle='modal' data-target='#myModal' onclick='pingfen(\"" + data.id + "\",\"" + pfck + "\")'>" + pfck + "</div></div></div>"
    return str;
  }

 其中可以看到,对于“待提交”“已提交”做了区分处理,由于后端返回的数据是0-1,因此这里需要区分显示,并且对于“待提交”的数据可以评分,但是对于“已提交”的数据只可以进行查看。

4. 处理滚动翻页问题

$(window).scroll(function () {
    $(".content_1").each(function () {
      var scrollTop = this.scrollTop || document.body.scrollTop || document.documentElement.scrollTop;
      if (scrollTop + window.innerHeight + 20 >= this.offsetHeight) {
        if (isMore) {
          isMore = false;
          pageNum++;
          year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
          jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
          bumen = choosedDepartmentID;
          console.log(bumen)
          gangwei = choosedGangweiIndex;
          getList(year, jidu, pageNum, pageSize, bumen, gangwei);
        }
      }
    });
  });

 5. 数据库获取部门信息并显示在select

var choosedDepartmentID;
  // 加载部门所有数据显示在下拉框
  window.onload = function () {
    var organizationId = window.localStorage.getItem("unitId");  //当前登录用户的机构ID
    //获取当前机构id下的所有部门
    $.ajax({
      type: "get",
      url: urlGlobal + "/api/h5/sys/organizationList",
      async: true,
      dataType: "json",//后台返回值类型
      contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型 
      async: false,//异步请求
      data: ({
        organizationId: organizationId,
      }),
      headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
      success: function (data) {
        if (data.code === 200) {
          var bumen = []
          for (var i = 0; i < data.data.length; i++) {
            bumen.push({ id: data.data[i].id, value: data.data[i].name });
          }
          var mobileSelect3 = new MobileSelect({
            trigger: '#bumen',
            title: '部门',
            wheels: [
              { data: bumen }
            ],
            position: [0], //初始化定位 打开时默认选中的哪个 如果不填默认为0
            transitionEnd: function (indexArr, data) {
            },
            callback: function (indexArr, data) {
              choosedDepartmentID = data[0].id;
              $("#bumen").val(data[0])
            },
          });
        } else {
          alertGlobal(data.message, 3000, true)
        }
      }
    });
  }

 6. 查询函数和重置函数

//查询函数
  function getDPList() {
    console.log("search")
    pageNum = 1; //默认是从第一页开始访问
    pageSize = pageSizeGlobal;
    isMore = false;
    year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
    jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
    bumen = choosedDepartmentID;
    gangwei = choosedGangweiIndex;
    // bumen = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
    // gangwei = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
    $("#content_1").empty();
    getList(year, jidu, pageNum, pageSize, bumen, gangwei);

  }

  //重置函数
  function resetList() {
    pageNum = 1; //默认是从第一页开始访问
    pageSize = pageSizeGlobal;
    isMore = false;
    $("#year").html(yearInitGlobal); //充值下拉框的默认显示值
    $("#jidu").html("第二季度");
    $("#bumen").html('请选择');
    choosedDepartmentID = '';
    $("#gangwei").html('请选择');
    choosedGangweiIndex = '';
    $("#content_1").empty();
    getList(yearInitGlobal, quarterInitGlobal, pageNum, pageSize, '', '');
  }

至此完成了主页面的列表,其实和上一节的基本相似,只是对于一些复杂情况做了处理,接下开我们需要进行评分弹框中显示详情,以及评分保存功能,整体提交功能进行开发,先看一下接口文档。

前端HTML5生成后端 前端h5页面怎么开发_html5_03

前端HTML5生成后端 前端h5页面怎么开发_javascript_04

对于测评详情(即点击弹框后显示的数据),需要传入该测评的id,请求后会返回测评id,得分、分值、说明,把这些显示在页面上。

前端HTML5生成后端 前端h5页面怎么开发_javascript_05

而对于弹框输入后的保存,接口就比较简单,只需要传入测评id和得分即可,没有返回数据。

前端HTML5生成后端 前端h5页面怎么开发_html5_06

对于最终的批量提交功能,相对来说比较简单,直接按照年份和季度提交所有数据即可


   7. 静态页面中已经写好了Modal弹框,我们首先让点击“评分”按钮后,触发事件进行弹框显示

<div class='rate' data-toggle='modal' data-target='#myModal' onclick='pingfen(\"" + data.id + "\",\"" + pfck + "\")'>" + pfck + "</div></div></div>

 上面已经写好,而对于每次选中“评分”的这条信息,需要获取其id才可以调接口显示数据,因此在pingfen()函数中传入了data.id,评分弹框展示并显示数据的代码如下

var tempId;
  var tempScore;
  // 评分函数
  function pingfen(id, pfck) {
    tempId = id
    $.ajax({
      type: "get",
      url: urlGlobal + "/api/h5/assess/score/evaluation/" + id,
      async: true,
      dataType: "json",//后台返回值类型
      contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型 
      async: false,//异步请求
      headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
      success: function (data) {
        console.log(data)
        if (data.code === 200) {
          tempScore = data.data.presetScore  // 暂存分数-方面后面比较
          var list = data.data
          console.log(list.score)
          $("#fenzhi").val(list.presetScore)
          $("#dafen").val(list.score)
          $("#explain").val(list.remark)
          // 已提交还是待提交
          console.log(list.score)
          if (pfck === "查看") {    //已提交
            console.log("已提交")
            document.getElementById("dafen").disabled = "disabled";
            document.getElementById("baocun").style.display = "none"
            document.getElementById("queren").style.display = "inline-block"
          } else {  // 
            console.log("待提交")
            document.getElementById("queren").style.display = "none"
            document.getElementById("baocun").style.display = "inline-block"
          }
        } else {
          alertGlobal(data.message, 3000, true)
        }
      }
    });
  }

可以看到获取返回值后,把他们对应渲染到input里面就可以了。这里由于“查看”和“评分”按钮名称和功能不同,所有做了显示和隐藏的处理。

8. 评分页面后,输入相应的分数进行打分,并调用接口保存数据。

// 评分页保存
  function btnSave(id) {
    console.log(tempId)
    var dafen = $("#dafen").val()
    if (parseInt($("#dafen").val()) > tempScore) {   //判断输入正确性
      alertGlobal('评分数应小于分值', 3000, true)
    } else if (dafen == "" || isNaN(dafen)) {
      alertGlobal('评分数应非空且为数字', 3000, true)
    }
    else {
      $.ajax({
        type: "post",
        url: urlGlobal + "/api/h5/assess/score/evaluation",
        async: true,
        dataType: "json",//后台返回值类型
        contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型 
        async: false,//异步请求
        data: JSON.stringify({
          id: tempId,
          score: $("#dafen").val()
        }),
        headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
        success: function (data) {
          console.log(data)
          if (data.code === 200) {
            // 刷新页面 但保存当前年份和季度??
            var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
            var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
            bumen = choosedDepartmentID;
            gangwei = choosedGangweiIndex;
            $("#content_1").empty();
            getList(year, jidu, pageNum, pageSize, bumen, gangwei);
            alertGlobal(data.message, 3000, true)
          } else {
            alertGlobal(data.message, 3000, true)
          }
        }
      });
      //关闭评分modal
      $('#myModal').modal("hide")
    }

  }

 在评分之前,先判断“分数小于分值”“输入必须为数字且不为空”,后请求即可。并注意完成之后需要刷新页面,即:先将页面制空empty()之后,再重新获取数据放入。

9. 批量提交功能

// 全部提交弹框
  function allSubmit() {
    $('#subModal').modal({ show: true })
  }
  // 全部提交(按照年份和季度全部提交)
  function btnSure() {
    var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
    var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
    $.ajax({
      type: "post",
      url: urlGlobal + "/api/assess/score/evaluation/submit",
      async: true,
      dataType: "json",//后台返回值类型
      contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型 
      async: false,//异步请求
      data: JSON.stringify({
        year: year,
        quarter: jidu
      }),
      headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
      success: function (data) {
        if (data.code === 200) {
          alertGlobal("提交成功", 3000, true)
          // $('#subModal').modal({ show: false })
        } else {
          alertGlobal(data.message, 3000, true)
        }
      }
    });
    $('#subModal').modal("hide")
    refresh();
  }

 至此就完成了今天的页面效果

前端HTML5生成后端 前端h5页面怎么开发_前端_07

前端HTML5生成后端 前端h5页面怎么开发_html5_08

前端HTML5生成后端 前端h5页面怎么开发_html5_09

下一节,我们将实现一个更有难度的功能,批量提交,不同于本文的批量提交,需要进行选择,对于选中的项目获取对应的id和score交给后端。