LayUI记录单

界面问题

  • 数据重新加载table.reload时,toolbar消失:

    • 将tableIns.reload({where: getQueryParams(), page: {curr: recodePage}});改为:

      1
      tableIns.reload('maintainTable',{where: getQueryParams(), page: {curr: currentPage}}, true);
    • 还需要注意命名问题,id尽量不要多重复/冲突

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <script type="text/html" id="toolbarMaintainFinancial">
      <div class="layui-btn-container">
      <div class="layui-btn layui-btn-sm febs-bg-font-blue" lay-event="add">

      <i class="layui-icon layui-icon-addition "></i>&nbsp;新增
      </div>
      <!--<div class="layui-btn layui-btn-sm febs-bg-blue" lay-event="open">
      <i class="layui-icon layui-icon-plus-square"></i>&nbsp;展开
      </div>
      <div class="layui-btn layui-btn-sm febs-bg-orange" lay-event="close">
      <i class="layui-icon layui-icon-minus-square"></i>&nbsp;关闭
      </div>-->
      </div>
      </script>
    • 完整重载

      1
      table.reload(id, options, deep);
      • 参数 id : table 渲染时的 id 属性值
      • 参数 options : 为基础属性配置项
      • 参数 deep 2.6+ : 是否采用深度重载(即重载时始终携带初始时及上一次重载时的参数),默认 false。
    • 总结

      • 有些他妈的傻逼问题,理性分析还真tm难找出来,本来还想着是不是table.reload()侵入性太大了,对toolbar生成造成了影响?纯纯的命名冲突,你妈隔壁,
      • toolbar的id最好就一个文件就两个,一个用来定义,一个用来绑定!以免造成不必要的误会。

Layui技巧

  • 获取表单数据

    • 需要在form上有一个lay-filetr,例如:

      1
      <form class="layui-form" style="margin: 0 auto;max-width: 460px;padding-top: 40px;" lay-filter="step-form-01">
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    - 取数据,var data = form.val('step-form-01');

    示例:

    ```javascript
    // 获取按钮元素
    var button1 = document.getElementById('formStep1');
    // 添加点击事件监听器
    button1.addEventListener('click', handleClick1);
    function handleClick1() {
    // 主要是这两行
    var data = form.val('step-form-01');
    console.info('data', data)
    if (data.usableCity !== null && data.usableCity !== "") {
    step.next('#stepForm');
    }
    // step.pre('#stepForm');
    }
  • 根据某字段判断是否显示tool某按钮

    • 示例,其中d就是该行这一条数据的完整信息

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      {{# if (d.recommendProductBtnShow === "0") { }}
      <a lay-event="recommend">
      <div class="layui-btn layui-btn-xs opt-but">
      &nbsp;推荐产品
      </div>
      </a>
      {{# } else { }}
      <a lay-event="recommend">
      <div class="layui-btn layui-btn-xs opt-but layui-hide">
      &nbsp;推荐产品
      </div>
      </a>
      {{# } }}
    • 示例二(layui社区)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <script type="text/html" id="barDemo">
      <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>
      {{# if (d.某字段 <= 1) { }}
      <a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled" disabled>删除</a>
      <a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled" disabled>重置密码</a>
      {{# } else { }}
      <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
      <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="reset">重置密码</a>
      {{# } }}
      </script>
  • 获取表格当前页数

    • 主要是后面的done方法,即数据加载完后执行的方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      initTable();
      function initTable() {
      tableIns = febs.table.init({
      elem: $view.find('table'),
      id: 'maintainTable',
      page: true,
      limit:10,
      limits:[5,10,20,30],
      url: ctx + "tFpFinanceProduct/list",
      toolbar: '#toolbarMaintain',
      where:getQueryParams(),
      defaultToolbar: [{
      title: '展开',
      layEvent: 'open',
      icon: 'layui-icon-plus-square'
      }, {
      title: '关闭',
      layEvent: 'close',
      icon: 'layui-icon-minus-square'
      }, {
      title: '刷新',
      layEvent: 'refresh',
      icon: 'layui-icon-refresh'
      }, 'filter', 'print', 'exports'],
      cols: [[
      {field: 'name', align: 'center', title: '产品名称', minWidth: 220},
      {
      title: '产品logo', width: 180, templet: function (d) {
      //return '<img width=auto height=auto src='+ctx + 'api/download?fileId=' + d.fileId + '&download=false'+'>';
      return '<img class="product-logo" width=24px height=24px src=' + ctx + 'api/download?fileId=' + d.fileId + '&download=false' + '>';
      }
      },
      {
      align: 'center', title: '专项贷', minWidth: 230, templet: function (d) {
      if (!d.specialLoanType) {
      return "无";
      }
      return febs.selectDictColorName(special_loan_type, d.specialLoanType);
      }
      },
      {
      align: 'center', title: '贷款额度(万元)', minWidth: 190, templet: function (d) {
      return d.loanMoney + "-" + d.loanMoneyMax;
      }
      },
      {
      align: 'center', title: '参考利率(%)', minWidth: 160, templet: function (d) {
      return d.loanRate + "%-" + d.loanRateMax + "%";
      }
      },
      {
      align: 'center', title: '贷款期限(月)', minWidth: 160, templet: function (d) {
      return d.loanTerm + "-" + d.loanTermMax;
      }
      },
      {field: 'version',align: 'center', title: '版本号', width: 350},
      {
      align: 'center', title: '状态', minWidth: 130, templet: function (d) {
      return febs.selectDictColorName(product_status, d.status);
      }
      },
      {align: 'center',fixed:'right' ,title: '操作', minWidth: 400, toolbar: '#toolbarmaintain-option'}
      ]],done: function(res, curr, count){
      //如果是异步请求数据方式,res即为你接口返回的信息。
      //如果是直接赋值的方式,res即为:{data: [], count: 99} data为当前页数据、count为数据总长度
      // console.log(res);
      //得到当前页码
      // console.log(curr);
      currentPage = curr
      //得到数据总量
      // console.log(count);
      }
      });
    • 我看之前那个人通过选择器筛选的方法似乎也可以?

      1
      2
      var recodePage = $(".layui-laypage-skip .layui-input")[0].value;
      tableIns.reload({where: getQueryParams(), page: {curr: recodePage}});
  • 添加自定义校验

    • 示例

      1
      2
      <input type="input" placeholder="请输入最大参考利率" class="layui-input"
      id="maxRate" oninput="interestRate()" name="loanRateMax" style="width:285px;margin-left: 10px" lay-verify="decimal">
    • js部分

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      // 自定义验证规则
      form.verify({
      integer: function (value, item) {
      if (value && !/^\d+$/.test(value)) {
      return '请输入大于等于0的整数';
      }
      },
      decimal: function(value, item) {
      if (!/^\d+(\.\d+)?$/.test(value)) {
      return '请输入合法的小数';
      }
      if (parseFloat(value) <= 0) {
      return '请输入大于0的小数';
      }
      }
      });
  • 弹出层表单修改/提交

    • 主页面,示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      if (layEvent === 'perfect' || layEvent === 'perfect-admin') {
      febs.modal.open('融资意向完善', 'financial/demandPrimaryPerfect/' + data.financeDemandId, {
      area:["900px","90%"],
      btn: ['完成', '保存','取消'],
      yes: function (index, layero) {
      $("#febs-demandPrimaryPerfect").find("#submit").click();
      },
      btn2:function (index, layero) {
      $("#febs-demandPrimaryPerfect").find("#submit-save").click();
      return false;
      }
      });
      }

      #febs-demandPrimaryPerfect : 代表弹出层view的定义

    • 弹出表单,按钮:

      1
      2
      <button lay-submit lay-filter="demandPrimaryPerfect-submit" id="submit" hidden>提交信息</button>
      <button lay-submit lay-filter="demandPrimaryPerfect-submit-save" id="submit-save" hidden>保存信息</button>
    • 弹出层数据绑定,接收Model传输过来的数据,额外开一个script:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <script th:inline="javascript">
      var categorySelect =[[${@category.getCategorySelect()}]];
      var financeDemand = [[${financeDemand}]];
      var categoryNums = [[${categoryNums}]];
      var guaranteeWays = [[${guaranteeWays}]];
      var paymentWays = [[${paymentWays}]];
      var guarantee_way = [[${@dict.getType('guarantee_way')}]];
      var payment_way = [[${@dict.getType('payment_way')}]];
      </script>
    • 对应提交/保存方法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
       form.on('submit(demandPrimaryPerfect-submit-save)', function (data) {
      data.field.firstLoanStatus = '02';
      data.field.categoryNum=getSelectValue(demo1);
      let a=duoXuanCheck(data.field.categoryNum,"行业分类")
      data.field.guaranteeWay=getSelectValue(guaranteeWaySelect);
      let b =duoXuanCheck(data.field.guaranteeWay,'担保方式')
      data.field.paymentWays=getSelectValue(paymentWaySelect);
      // let c =duoXuanCheck(data.field.paymentWays,'还款方式')
      if (a&&b){
      febs.post(ctx + 'demandPrimary/perfect', data.field, function (res) {
      layer.closeAll();
      febs.alert.success('操作成功');
      $('#febs-demandPrimary').find('#query').trigger('click');
      });
      }
      return false;
      });

      form.on('submit(demandPrimaryPerfect-submit)', function (data) {
      data.field.categoryNum=getSelectValue(demo1);
      data.field.firstLoanStatus = '01';
      data.field.status = '5'
      data.field.guaranteeWay=getSelectValue(guaranteeWaySelect);
      data.field.paymentWays=getSelectValue(paymentWaySelect);
      let a=duoXuanCheck(data.field.categoryNum,"行业分类")
      let b =duoXuanCheck(data.field.guaranteeWay,'担保方式')
      // let c =duoXuanCheck(data.field.paymentWays,'还款方式')
      if (a&&b) {
      febs.post(ctx + 'demandPrimary/perfect', data.field, function (res) {
      layer.closeAll();
      febs.alert.success('操作成功');
      $('#febs-demandPrimary').find('#query').trigger('click');
      });
      }
      return false;
      });

      **$(‘#febs-demandPrimary’).find(‘#query’).trigger(‘click’);**:其中#febs-demandPrimary代表原来界面的view定义,找到id为query的按钮,进行点击。

  • 两个输入框,看实现/颜色弹出 提高效率 冒险精神 maintain

    • 添加颜色

      1
      2
      3
      4
      5
      6
      7
      if (eval(num1) > eval(num2) && num2 != 0) {
      $("#moneyCapital").html("最小贷款数不能大于最大贷款数量").css("color", "red");
      numericalComparison = false;
      } else {
      $("#moneyCapital").html(toChineseNum1 + "到" + toChineseNum2).css("color", "red");
      numericalComparison = true;
      }
  • 样式

    • 自己往右挪动,但不影响右边的输入框,添加属性:

      1
      style="margin-left: 9px; margin-right: -9px"
  • layer

    • 弹出消息提示框

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      //eg1
      layer.msg('只想弱弱提示');
      //eg2
      layer.msg('有表情地提示', {icon: 6});
      //eg3
      layer.msg('关闭后想做些什么', function(){
      //do something
      });
      //eg
      layer.msg('同上', {
      icon: 1,
      time: 2000 //2秒关闭(如果不配置,默认是3秒)
      }, function(){
      //do something
      });
  • 文件管理

    • mapper
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <select id="findfileid" resultType="java.lang.String">
    SELECT
    b.file_id
    FROM

    t_bs_common_material as b
    where

    (select finance_product_logo_id from t_fp_finance_product where finance_product_id=#{id})=b.material_id

    </select>

    • Mpper.java

      1
      String findfileid(String id);
    • bean

      1
      2
      3
      4
      5
      /**
      * fileid
      */
      @TableField(exist = false)
      private String fileId;
    • Service

      1
      2
      3
      //获取fileid
      String findfileid = tFpFinanceProductMapper.findfileid(financeProductId.toString());
      tFpFinanceProduct.setFileId(findfileid);
    • Service Interface

      1
      TFpFinanceProduct tFpFinanceProductEdit(Long financeProductId) throws BusException;
    • Controller

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
          @GetMapping("tFpFinanceProduct/edit/{financeProductId}")
      @ResponseBody
      // @RequiresPermissions("tFpFinanceProduct:view")
      public Result tFpFinanceProductEdit(@PathVariable String financeProductId) throws BusException {
      try {
      TFpFinanceProduct tFpFinanceProduct = tFpFinanceProductService.tFpFinanceProductEdit(Long.valueOf(financeProductId));
      return new Result().success().data(tFpFinanceProduct);
      } catch (BusException e) {
      String message = MessageConstant.GET_FAIL_MSG;
      log.error(message, e);
      throw new BusException(message);
      }
      }
    • html

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      $.get(ctx + "tFpFinanceProduct/edit/" + [[${financeProductId}]],function(data){

      if (data.data.ynPolicy == '0'){
      $("#ynPolicyRadio").removeAttr("style")
      }
      if (data.data.recommended == '0'){
      $("#recommendedSortingRadio").removeAttr("style")
      }
      if (data.data.ynAccuracy == '1') {
      $("#otherRateRadio").removeAttr("style")
      } else {
      $("#interestRateRadio").removeAttr("style")
      }
      $("#moneyCapital").text(data.data.moneyCapital)
      param.financeProductId = data.data.financeProductId;
      param.usableCity = data.data.usableCity;
      param.paymentWay=data.data.paymentWay;
      industrySelected = data.data.serviceIndustryId;
      guaranteeWaySelected = data.data.guaranteeWay;
      citySelected = data.data.usableCity;
      paymentWayed =data.data.paymentWay;
      status = data.data.status;
      initFormValue1(data.data);
      initFormValue2(data.data);
      initFormValue3(data.data);


      var xhr = new XMLHttpRequest();
      xhr.open("GET", ctx + 'api/download?fileId=' + data.data.fileId+'&download=false');
      xhr.responseType = "blob"; // 将响应类型设置为blob
      xhr.onload = function(r) {
      if (xhr.status === 200) {
      var blob = xhr.response;
      var url = URL.createObjectURL(blob); // 创建Object URL
      var imgPreview = document.getElementById("demo1");
      imgPreview.src = url; // 将Object URL赋值给img元素的src属性
      var imgPreview2 = document.getElementById("img-preview4");
      imgPreview2.src = url; // 将Object URL赋值给img元素的src属性
      }
      };
      xhr.send();
      })
    • Html add

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      $("#generateCode").click(function () {
      if (channelUrl !== '' && channelUrl != null) {
      $.get(ctx + 'channelQrCode/generateCode/' + channelUrl, function (res) {
      let img = ' <img class="product-logo" width=200px src=' + ctx + 'api/download?fileId=' + res.data.fileId + '&download=false' + '>'
      $("#code").html(img);
      form.val("financingChannel-add-form", {
      "materialId": res.data.materialId,
      "snowflake": res.data.snowflake
      });
      });
      generateCodeClickCount ++;
      } else {
      layer.msg("请先输入链接,再点击生成二维码");
      }
      return false;
      });
  • 点击按钮,填充表单数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $("#generateCode").click(function () {
    if (channelUrl !== '' && channelUrl != null) {
    $.get(ctx + 'channelQrCode/generateCode/' + channelUrl, function (res) {
    let img = ' <img class="product-logo" width=200px src=' + ctx + 'api/download?fileId=' + res.data.fileId + '&download=false' + '>'
    $("#code").html(img);
    form.val("financingChannel-add-form", {
    "materialId": res.data.materialId, // 填充字段name为materialId的字段
    "snowflake": res.data.snowflake // 同上
    });
    });
    generateCodeClickCount ++;
    } else {
    layer.msg("请先输入链接,再点击生成二维码");
    }
    return false;
    });
  • LayUI校验:

    • 当不是必填,但是填了之后必须要校验他填的对不对的时候

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // 自定义验证规则
      form.verify({
      telOrPhone: function (value, item) {
      if (value) {
      if (!/^1[3456789]\d{9}$/.test(value) && !/^0\d{2,3}-?\d{7,9}$/.test(value)) {
      return '电话号码格式不正确';
      }
      }
      }
      });
    • 行内元素冲到屏幕之外,转化为块级元素

      1
      2
      3
      4
      <div class="companyInfo">
      <span id="productLink4" style="display: block; width: 300px; word-wrap: break-word;">
      </span>
      </div>

      word-wrap: break-word; 是一个 CSS 样式属性,用于在需要时强制将长单词或长字符串进行换行。

      当文本内容中的单词或字符串过长且没有空格或分隔符时,正常情况下它们将超出容器的边界并溢出显示。使用 word-wrap: break-word; 可以让这些长单词或长字符串在必要时自动换行,以便完整地显示在容器内部,而不会溢出到容器之外。

  • VUE:

    • 输入框下拉时,可以在输入框中输入关键字来缩小下拉范围

      1
      2
      3
      <el-select v-model="selectedValue" filterable clearable>
      <!-- 下拉选项 -->
      </el-select>

      在上述代码中,filterable 属性启用了下拉选项的过滤功能,用户可以在输入框中输入内容来缩小下拉选项的范围。而 clearable 属性会在输入框右侧显示一个清空按钮,用户可以点击该按钮来清空选择框中的选项。

      通过同时使用 clearablefilterable,可以方便地清空选择框中的选项并进行过滤操作,提供更好的用户交互体验。

  • Temp

    • 文件管理

      1
      2
      3
      console.log("logoId", logoId)
      let img = ' <img class="product-logo" width=200px src=' + ctx + 'api/download?fileId=' + logoId + '&download=false' + '>'
      $("#code").html(img);
    • 待分配60 待受理70 待授信审核80 授信审核不通过81 / 银行 已经有产品和银行对接,不用推荐

    • 已保存 待审核 审核不通过 审核通过 银行退回 待企业确认 可以推荐

    • thymleaf显示技巧

      1
      2
      3
      4
      5
      6
      <div class="layui-form-item">
      <label class="layui-form-label">参考利率</label>
      <div class="value-value">
      [[${financeApply.financeProduct.loanRateMax == 0 ? '暂未填写' : financeApply.financeProduct.loanRate + '% ~ ' + financeApply.financeProduct.loanRateMax + '%'}]]
      </div>
      </div>
    • 其他

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
        {{# if (d.recommendProductBtnShow === "0") { }}
      <a lay-event="recommend">
      <div class="layui-btn layui-btn-xs opt-but">
      &nbsp;推荐产品
      </div>
      </a>
      {{# } else { }}
      <a lay-event="recommend">
      <div class="layui-btn layui-btn-xs opt-but layui-hide">
      &nbsp;推荐产品
      </div>
      </a>
      {{# } }}
    • 地区

      1
      2
      3
      4
      5
      6
      7
      <select id="getAreaTree" resultType="com.delin.system.entity.Area">
      SELECT * FROM t_bs_area WHERE parent_id IN (SELECT area_id FROM t_bs_area WHERE area_number = '420100')
      </select>

      <select id="getAreaTrees" resultType="com.delin.system.entity.Area">
      SELECT area_name as areaName FROM t_bs_area WHERE area_id=#{id} and parent_id IN (SELECT area_id FROM t_bs_area WHERE area_number = '420100')
      </select>
  • 项目端口访问问题

    流程?

    主要知识点:端口访问 路由 数据库 controller

    二维码:实际上就是一个存储信息的载体 在本项目中具体就是一个地址

    1. 后台拼接生成二维码/网址: ip + 端口 + /firstLoanDemand + id=?
    2. 首先根据ip+端口 访问指定项目 测试环境的protol项目 firstLoanDemand + id 路由到指定页面 (即用户看到的界面)
    3. 指定页面调用created方法,访问protol controller后端接口 获取qr数据 进行tootal+1操作 在进行update
    4. 刷新数据库,可以查看到改写的数据

    为什么会报错当时?

    1. 需要访问的是9000 前台的一个界面,之后会调用后台7070的方法 -> vue方法请求 -> controller -> 数据库

    2. 可能?9000前端项目没有启动,即使你的二维码地址是正确的,也无法访问到页面

    3. 访问到页面后报错?9000访问7070端口出错/100%是这个原因 7070项目出错

    4. 根据id查询,可能为空吗?不可能,因为只要生成二维码的平台端连接的数据库qr表中id 和 7070获取数据访问的数据库一致,就不可能为空,除非有脏数据?数据已经删除了,再扫码肯定是没有的,但是数据都删除了,二维码如何显示呢?

    总结

    1. 计算机网路很重要,端口的访问这是最基础的,之后可能还有更复杂的问题。