hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)

1.查询时间匹配问题

原因:前端的Date类型格式与数据库(MySql)中的Date类型格式问题,所以在Controller中加如下代码解决。


//-。-这里这个方法解决时间查询时格式不统一的问题
    @InitBinder
        protected void init(HttpServletRequest request, ServletRequestDataBinder binder) {
        //这里根据不同的情况选择需要的类型 :)
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dateFormat.setLenient(false);
            binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
        }

这里也给出一种查询方法中按照日期查询
mapper中查询条件这样写

			<if test="startTime!=null and  !''.equals(startTime)  ">
			            AND DATE_FORMAT(a.START_TIME,'%y%m%d') =DATE_FORMAT(#{startTime},'%y%m%d')
			</if>

2.查询过多时放入更多查询

类似于这种
hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)
第一步。
把查询条件放入两个(queryPanel)(query-form2)div中

<div id="queryPanel" class="pull-right" style="padding-bottom:5px;">
    <div class="k-query-detail" id="query-form2">

        <div class="rows">
        <input id="evaluateTypeBox" data-bind="value:model.evaluateType" style="margin:1.2%;"
               placeholder='<@spring.message "evaluation.evaluateType"/>'type="text">
        </div>
        <div class="rows">
        <input id="evaluateDatePicker" data-bind="value:model.evaluatedDate"  style="margin:1.2%; "
               placeholder= '<@spring.message "studentevaluation.evaluateddate"/>' type="text">
        </div>

        <div class="rows">
        <input  id="appraiserLov" data-bind="value:model.evaluatedBy"   style="margin:1.2%;"
                placeholder= '<@spring.message "studentevaluation.appraiserName"/>' type="text">
        </div>
        <div class="rows">
        <input  id="appraiseeLov" data-bind="value:model.userId"  style="margin:1.2%;"
                placeholder='<@spring.message "studentevaluation.appraiseeName"/>'type="text">
        </div>

    </div>
</div>

第二步,内层div绑定数据

<script>kendo.bind($('#query-form2'), viewModel);</script>

第三步,把外层div放入更多查询的盒子

<script type="text/javascript">
    $('#queryPanel').kendoQueryPanel({
        /* queryFunction: function () {
         viewModel.queryFunction();
         },
         resetFunction: function () {
         viewModel.resetFunction();
         } */
    });
</script>

这样就把不好放的地方的查询放入了更多查询的盒子中。

3.lov联动问题

两个lov之间 后者依赖前者 这样的lov实现
hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)
第一步,写mapper配置lov。
第二步,前端调用

<div class="col-md-4">
            <input  id="studentBatchLov" data-bind="value:model.trainBatchCode" placeholder='<@spring.message "studentlearntrack.trainbatchcode"/>'type="text">
        </div>
        <div class="col-md-4">
            <input  id="routeHeadLov" data-bind="value:model.routeHeadId" placeholder='<@spring.message "studentlearntrack.routeHeadId"/>'type="text">
        </div>
        <div class="col-md-4">
            <input  id="groupLov" data-bind="value:model.groupId" placeholder='<@spring.message "evaluation.groupCode"/>'type="text">
        </div>

第三步,初始化

// 初始化学生批次的LOV
    $("#studentBatchLov")
        .kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "TRAIN_BATCH_LOV")}, {
            select: function (e) {
                if(typeof(viewModel.model.temp) != "undefined"){
                    if (viewModel.model.temp!= e.item.groupId) {
                        //这时说明groupLOV是被选过的则应该置空groupLov
                        $("#groupLov").data("kendoLov").text("");
                        $("#groupLov").data("kendoLov").value("");
                        viewModel.model.groupId= "";
                        viewModel.model.trainBatchCode= e.item.trainBatchCode;
                    }
                }
            },
            change: function (e) {
                if (e.sender._prev == null || e.sender._prev == '') {
                    viewModel.model.set("groupId", "");
                    viewModel.model.set("trainBatchCode", "");
                    $("#groupLov").data("kendoLov").text("");
                }
            }
        }));



    // 初始化学习路线的LOV
    $("#routeHeadLov")
        .kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "ROUTE_HEAD_ID_LOV")}, {
            //当选中时应当把groupLov置空
            select: function (e) {
                if(typeof(viewModel.model.temp) != "undefined"){
                    if (viewModel.model.temp!= e.item.groupId) {
                        //这时说明groupLOV是被选过的则应该置空groupLov
                        $("#groupLov").data("kendoLov").text("");
                        $("#groupLov").data("kendoLov").value("");
                        viewModel.model.groupId= "";
                        viewModel.model.routeHeadId = e.item.routeHeadId;
                    }
                }
            },
            change: function (e) {
                if (e.sender._prev == null || e.sender._prev == '') {
                    viewModel.model.set("groupId", "");
                    viewModel.model.set("routeHeadId", "");
                    $("#groupLov").data("kendoLov").text("");
                }
            }



        }));
    //初始化学习小组lov
    $("#groupLov")
        .kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "LOV_GROUPS")}, {
            query: function (e) {
                //如果#studentBatchLov和routeHeadIdLov不为空
                if(typeof(viewModel.model.routeHeadId) != "undefined" && viewModel.model.routeHeadId != ""&&typeof(viewModel.model.trainBatchCode) != "undefined" && viewModel.model.trainBatchCode != ""){
                    //把学习批次和学习路线传入
                    e.param['routeHeadId'] = viewModel.model.routeHeadId;
                    e.param['trainBatchCode'] = viewModel.model.trainBatchCode;
                }
            },
            select: function (e) {
                //temp为空则说明学习小组lov是没被选过的

                viewModel.model.set("temp", e.item.groupId);
            }
        }))

4.gird中内容过多鼠标移动上出现全部内容

类似于这种
hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)

第一步,样式设置

<!--设置tooltip的样式-->
<style>
    div[role=tooltip].k-tooltip{
        padding: 2px;
        background: #5c9acf;
    }
    .k-tooltip-content{
        padding: 4px;
        text-align: left;
        background: #fff;
        color: #666;
    }
    .k-callout {
        border-bottom-color: #5c9acf;
    }
</style>

第二步,设置数据显示样式

attributes:{style: "white-space:nowrap;text-overflow:ellipsis;"},

第三步,添加Tooltip

 //add tooltip
    $("#grid").kendoTooltip({
        show: function(e){
            if($.trim(this.content.text()) !=""){
                $('[role="tooltip"]').css("visibility", "visible");
            }
        },
        hide: function(){
            $('[role="tooltip"]').css("visibility", "hidden");
        },
        filter: "td:nth-child(n+3)",
        content: function(e){
            var element = e.target[0];
            if(element.offsetWidth < element.scrollWidth){
                var text = $(e.target).text();
                return '<div style="min-width:100px;max-width: 1000px;">' + text + '</div>';
            }else{
                $('[role="tooltip"]').css("visibility", "hidden");//解决鼠标一开始放在上面出现空模块
                return "";
            }
        }
    }).data("kendoTooltip");

此处参考https://blog.****.net/a1786223749/article/details/78330908

5.快码的使用

这里多说几句,hap框架中的快码时一个简单的表格就是value-meaning之间的储存方式,那吗快码的使用就方法多了一些。
第一种,前端绑定使用。

第一步,代码维护中配置
hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)
第二步,页面中配置

<!--学习方式的状态的快码-->
<script src="${base.contextPath}/common/code?learnStyleType=LT.LEARN_TYPE" type="text/javascript"></script>

第三步,使用
这时配置好了快码可以在learnStyleType中获取到相应的值。

  1. 前端容器
//这是放到了gird中如果
 editor: function(container, options) {
                    $('<input name="'+ options.field + '"/>')
                        .appendTo(container)
                        .kendoComboBox({
                        dataSource: learnStyleType,
                        valuePrimitive: true,
                        dataTextField: "meaning",
                        dataValueField: "value"
                    });
                },

2.也可以取值时直接显示意思

template: function (dataItem) {
                    var v = dataItem.learnStyle;
                    $.each(learnStyleType, function (i, n) {
                        if ((n.value || '').toLowerCase() == (v || '').toLowerCase()) {
                            v = n.meaning;
                            return false;
                        }
                    });
                    if(v==null){
                        return '';
                    }else{

                        return v;
                    }
                }

第二种用于前端展示时也可以子啊sql中直接与数据库中的快码表连表查出meaning。

6.前端计算开始结束时间(分钟)

这里搞得比较复杂 因为业务要求。
开始结束时间只显示时分,计算出结果自动填充时长,时长不可编辑
第一步,确定gird中数据类型(主要是必输校验和时间类型显示)

startTime:{
                        validation: {required: true},
                        type:"date"
},
  endTime:{
                        validation: {required: true},
                        type:"date"},
    

第二步,确定开始结束时间格式 进行计算 最后以时分形式显示(这里操作比较复杂没有找到好的解决方法 -.- )

{
                field: "startTime",
                title: '<@spring.message "studentlearntrack.starttime"/>',
                width: 120,
                format: "{0:HH:mm}",
                editor: function(container, options) {
                    var end = options.model.endTime;
                    var d;
                    if(end){
                        d=end;
                    }
                    $('<input name="' + options.field + '"/>')
                        .appendTo(container)
                        .kendoTimePicker({
                            max:d,
                            culture: "zh-CN",
                            timeFormat: "HH:mm",
                            interval: 5 ,//15分钟
                            change:function(){
                                if(this.value()!=null){
                                    d = this.value();
                                }else{
                                    d= new Date(1900, 0, 1, 22, 0, 0);
                                }
                            }
                        });
                },
                template:function (dataItem) {
                    var time1 = dataItem.startTime;
                    var time2 = dataItem.endTime;
                    var temp = (time2.getHours()*60 + time2.getMinutes()) - (time1.getHours()*60 + time1.getMinutes());
                    dataItem.set("learnTime",temp);
                    var hour = time1.getHours();
                    var min = time1.getMinutes();
                    if(time1.getHours()<10){
                        hour = "0"+time1.getHours()+"";
                    }
                    if(time1.getMinutes()<10){
                        min = "0"+time1.getMinutes()+"";
                    }
                    return hour+""+":"+min;
                }

            },
            {
                field: "endTime",
                title: '<@spring.message "studentlearntrack.endtime"/>',
                width: 120,
                format: "{0:HH:mm}",
                editor: function(container, options) {
                    // options.model.endTime = options.model.startTime;
                    var start = options.model.startTime;
                    var d;
                    if(start){
                        d=start;
                    }
                    $('<input name="' + options.field + '"/>')
                        .appendTo(container)
                        .kendoTimePicker({
                            format:" HH:mm",
                            culture: "zh-CN",
                            interval: 5 ,//15分钟
                            min:d,
                            change:function(){
                                if(this.value()!=null){
                                    d = this.value();
                                }else{
                                    d= new Date();
                                }

                            }
                        });
                },
                //计算学习时长的方法并且返回当前时间的格式>。<
                template:function (dataItem) {

                    var time1 = dataItem.startTime;
                    var time2 = dataItem.endTime;
                    var temp = (time2.getHours()*60 + time2.getMinutes()) - (time1.getHours()*60 + time1.getMinutes());
                    dataItem.set("learnTime",temp);
                    var hour = time2.getHours();
                    var min = time2.getMinutes();
                    //因为返回的格式并不是自己想要的类型所有设计一下返回格式-.-

                    if(time2.getHours()<10){

                        hour = "0"+time2.getHours()+"";
                    }
                    if(time2.getMinutes()<10){

                        min = "0"+time2.getMinutes()+"";
                    }
                    return hour+""+":"+min;

                }



            },
            {
                field: "learnTime",
                title: '<@spring.message "studentlearntrack.learntime"/>',
                width: 120,
                //用来计算学习时长并且页面不可编辑-.-
                editor: function (container, options) {
                    container.html(options.model.learnTime);
                    container.removeClass('k-edit-cell');
                }


            },

当然这里也可以在外面进行一步计算总学习时长,但是这里没有业务需求就没在做。

7.页面是否可编辑的函数

//col确定某一列
editable:function (col) {
                    //判断开始时间,更改是否可编辑
                    if (this.trackId !=""  && (this.startTime.getDay() != newStartTime.getDay() ||this.startTime.getMonth()!= newStartTime.getMonth()||this.startTime.getFullYear()!= newStartTime.getFullYear())) {
                        // console.log(newStartTime.getDay());
                        // console.log(newStartTime.getFullYear());
                        // console.log(newStartTime.getMonth());
                        return false;
                    } else {

                        return true;
                    }
                }

8.外部导入工具时(这里导入了Ueditor富文本编辑框)

第一步,导入文件,在前端导入如下放入文件方式
hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)
第二步,前端的应用这里可以直接去Ueditor官网去看 简单易上手

<script type="text/javascript" charset="utf-8">
    //在导入外部插件时在webapp包下新建resources包放需要引入的插件
    window.UEDITOR_HOME_URL = "/resources/js/ueditor/"; //UEDITOR_HOME_URL、config、all这三个顺序不能改变
</script>
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/ueditor.all.min.js"></script>

<!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/lang/zh-cn/zh-cn.js"></script>
<!-- 加载编辑器的容器 -->
<script id="editor" type="text/plain" name="content"></script>

<!-- 创建编辑器并设置属性 -->

<script type="text/javascript">
    //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
    //相见文档配置属于你自己的编译器
    var ue = UE.getEditor('editor');
</script>

第三步,使用
1.首先加载页面时把 数据库中的内容设置到uetior中去

	//加载方面
    //通过trackId在数据库中找到comment
    //把数据库中的comment内容在加载过程中放到Ueditor中去:)
    function load(trackId){
        $.ajax({
            type: 'POST',
            url: "${base.contextPath}/htr/student/learn/track/query",
            data: {trackId: newTrackId},
            success: function (data) {
                $.each(data.rows, function (i, item) {
                    if (trackId == item.trackId && trackId != 0) {//form填充
                        viewModel.model.set("comment", item.comment);
                        //设置内容到UEtitorz中
                        ue.ready(function () {
                            ue.setContent(viewModel.model.comment);
                        });
                    }
                });
            }
        });
    }

2.把uetior中的内容提交(这里处理比较笨重)

{
                field: "comment",
                title: '<@spring.message "studentlearntrack.comment"/>',
                width: 120,
                template:function (dataItem) {
                        if(ue.hasContents()){
                            dataItem.comment = ue.getContent();

                        }else{
                            dataItem.comment = '';
                        }

                    dataItem.dirty=true;
                    return dataItem.comment;
                },

重写了保存方法

saveFunction:function () {
            $('#grid').data('kendoGrid').saveChanges().done(function(e){
                    //需要保存成功后再次保存才能提交到数据库
                    $('#grid').data('kendoGrid').saveChanges()
                    $('#grid').data('kendoGrid').dataSource.page(1); //刷新数据
            });
        },

9.页面传值问题

第一步,设置一个超链接(这里格式一定要正确这里深坑)

 template: function (dataItem) {
                    var trainBatchCode = dataItem.trainBatchCode;
                    var rid = dataItem.routeHeadId;
                    var temp = '<@spring.message "studentgroupassign.learmTrack"/>';
                    return '<a href="javascript:void(0)" onclick="viewLearnTrack(\'' + trainBatchCode + '\',\'' + rid + '\')">' + temp + '</a>';

                }

第二步,写一个上面的方法把值通过get方法提交到下一个页面

//确定下一个页面的初始查询条件
    viewLearnTrack = function (trainBatchCode, rid) {
        var win = $('#newWin').kendoWindow({
             iframe: true,
             draggable: false,
            content: '${base.contextPath}/learnTrack/student_learn_track.html?trainBatchCode=' + trainBatchCode + '&routeHeadId=' + rid
        }).data('kendoWindow');
        win.title('<@spring.message "studentlearntrack.strudentLearnTrackContent"/>');
        win.maximize().open();
    };

第三步,下一个页面接收值

 //使用FreeMarker获取订单头地址栏传来的trainBatchCode和routeHeadId
    var newTrainBatchCode = '${RequestParameters.trainBatchCode!0}';
    var newRouteHeadId = '${RequestParameters.routeHeadId!0}';

10. 重写删除方法

function deleteData() {//自定义批量删除函数
        var checked;
        checked = grid.selectedDataItems();//获取选中的行
        if(grid.selectedDataItems().length){

            // var temp = new Date()
            // if(viewModel.startTime.getDay()==temp.getDay()){
            //
            // }else{
            //
            // }
            kendo.ui.showConfirmDialog({
                title:$l('hap.tip.info'),
                message: $l('hap.tip.delete_confirm'),

            }).done(function (event) {
                if (event.button == 'OK') {
                    $.ajax({
                        type : "POST",
                        url  : "${base.contextPath}/htr/student/learn/track/remove",
                        data : kendo.stringify(checked),//数据转json
                        dataType:"json",
                        contentType:"application/json",
                        success: function(e) {
                            if(e.message){
                                kendo.ui.showInfoDialog({
                                    message:'<@spring.message "hap.tip.dateerror"/>'
                                })
                            }else{
                                $.each(checked,function(i,v){
                                    grid.dataSource.remove(v)
                                });
                                kendo.ui.showInfoDialog({
                                    message:'<@spring.message "hap.tip.success"/>'
                                })
                            }
                        }
                    });
                }
            })
        }else{
            kendo.ui.showInfoDialog({
                message:$l('hap.tip.selectrows')
            })
        }
    };

11.后台直接向前端返回报错信息

public ResponseData saveLearnTrack(IRequest request, List<StudentLearnTrack> dto){
        //用于返回的数据类型
        ResponseData responseData = new ResponseData();
        Criteria criteria = new Criteria();
        criteria.update(new String[]{"trainBatchCode", "routeHeadId", "userId", "contentId", "startTime", "endTime", "learnTime", "learnStyle", "comment"});
        criteria.updateExtensionAttribute();
        Iterator var4 = dto.iterator();
        while(var4.hasNext()) {
            StudentLearnTrack studentLearnTrack = (StudentLearnTrack)var4.next();
            String var6 = studentLearnTrack.get__status();
            byte var7 = -1;
            switch(var6.hashCode()) {
                case -1335458389:
                    if (var6.equals("delete")) {
                        var7 = 2;
                    }
                    break;
                case -838846263:
                    if (var6.equals("update")) {
                        var7 = 1;
                    }
                    break;
                case 96417:
                    if (var6.equals("add")) {
                        var7 = 0;
                    }
            }
            switch(var7) {
                case 0:
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //开始日期
                    String ds2 = sdf.format(studentLearnTrack.getStartTime());
                    //结束日期
                    String ds3 = sdf.format(studentLearnTrack.getEndTime());
                    //开始日期雨结束日期应保持同一天
                    String ds4 = ds2.split(" ")[0]+" "+ ds3.split(" ")[1];
                    try {
                        Date date = sdf.parse(ds4);
                        studentLearnTrack.setEndTime(date);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    //如果开始结束时间在某个时间段内则开始结束时间非法
                    List<StudentLearnTrack> temp = selectStudentTrackByTime(request,studentLearnTrack);
                    //新建时应该保证一条不符合规则的内容都没有
                    if (temp ==null || temp.size()==0){
                        ((IStudentLearnTrackService)this.self()).insertSelective(request, studentLearnTrack);
                    }else{
                       // throw  new RuntimeException("开始结束时间非法");
                        //请求失败 并返回报错信息
                        responseData.setSuccess(false);
                        responseData.setMessage("开始结束时间非法");
                        return  responseData;
                    }
                    break;
                case 1:
                    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
                    //开始日期
                    String ds5 = sdf1.format(studentLearnTrack.getStartTime());
                    //当前天数
                    String ds6 = sdf1.format(new Date());
                    if(ds6.equals(ds5)){
                        List<StudentLearnTrack> temp1 = selectStudentTrackByTime(request,studentLearnTrack);
                        //当包保存时至少有一条是符合要求 因为与自身冲突
                        if (temp1.size()<= 1){
                            ((IStudentLearnTrackService)this.self()).updateByPrimaryKeyOptions(request, studentLearnTrack, (Criteria)null);
                        }else {
                            //当多余一条时说明不仅与自身冲突 还有其他的数据 所以抛出异常
                            responseData.setSuccess(false);
                            responseData.setMessage("开始结束时间非法");
                            return  responseData;
                        }
                    }else {
                        responseData.setSuccess(false);
                        responseData.setMessage("只能修改当天记录");
                        return  responseData;
                    }
                    break;
                case 2:
                    ((IStudentLearnTrackService)this.self()).deleteByPrimaryKey(studentLearnTrack);
            }
        }

        return responseData;

这是我第一次hap开发中遇到的几个问题以及问题的解决方法,虽然问题不多但是自己解决浪费不少时间希望以后可以顺利解决。