• 使用canvas制作炫彩背景【转】
    1.定义canvas标签:1<canvas id="canvas"></canvas>2.开始js部分,先定义变量:123456789101112131415161718/* 获取画布 */var canvas = document.querySelector("#canvas");var ctx = canvas.getContext('2d');/* 定义一个字符串数组,后面字符串会从里随机选值 */var text = "SAFAF1D56FLK43F7PHM76VC9XNJ23";/* 定义 w为窗口宽度,h为窗体高度 */var w=window.innerWidth;var h=window.innerHeight;/* 设置len为20,其为背景里每条字符串的长度 */var len = 20;/* 设置num为100,窗口一共显示100条字符串 */var num = 100;/* 定义数组,里面存取每条字符串的字符与位置 */var arr=[];/* 画布宽等于窗口宽 */canvas.width=window.innerWidth;/* 画布高等于窗口高 */canvas.height=window.innerHeight;3.初始化字符串数组,先给每条字符串位置,字符先不给:123456789101112/* 初始化字符串数组 */        for(let i=0;i<num;i++){            /* 用.push方法给arr数组添加值 */            arr.push({                /* 字符先为空 */                str:[],                /* x轴位置为窗口宽度乘上一个0带1的随机数 */                x: parseInt(w*Math.random()),                /* y轴位置为窗口高度乘上一个0带1的随机数,再减个150把,可以为负数 */                y: parseInt(h*Math.random()-150)            })        }4.绘制每条字符串:123456789101112131415161718192021222324252627282930/* 绘制每条字符串 */       function txt(){           /* 给个循环,共绘制num条 */           for(let i=0;i<num;i++){               /* 设置变量letter为当前arr数组里的第i条字符串 */               var letter = arr[i];               /* 让字符串的字符为空 */               letter.str = [];               /* 给个循环,一个字符一个字符的拼接成字符串 */               for(let k=0;k<len;k++){                   /* 随机选取text里的一个字符 */                   letter.str.push(text[Math.floor(Math.random() * text.length)]);               }               /* 再来循环,开始绘制渲染字符串的每个字符 */               for(let j=0;j<len;j++){                   if(j==len-1){                       /* 第一个字符为白色 */                       ctx.fillStyle = `rgb(255, 255, 255)`;                   }else{                       /* 后面的为绿色,慢慢变不透明 */                       ctx.fillStyle = `rgba(0, 255, 21,${j*0.15})`;                   }                        /* 渲染字符 */                    ctx.font = "20px FangSong";                    ctx.fillText(letter.str[j],letter.x,letter.y+j*15);               }           }           /* 调用更新 */           move();       }5.更新字符串:12345678910111213141516/* 让字符串移动,若某字符串出了可视区,则重新生成 */       function move(){           /* 来个循环,给全部字符串更新位置 */           for(let j=0;j<num;j++){               /* y轴位置加3 */               arr[j].y=arr[j].y+3;               /* 如果改字符已经走出窗口了重新赋值 */               if(arr[j].y>=h){                   arr[j]={                       str:[],                x: parseInt(w*Math.random()),                y: parseInt(h*Math.random()-150)                   }               }           }       }6.设置动画过程:12345678setInterval(function(){            /* 清屏 */           ctx.clearRect(0,0,w,h);           /* 渲染 */           move();           /* 更新 */           txt();        },50); 7.在窗口大小改变时,设置canvas画布能实时铺满屏幕:123456789101112131415/* 绑定窗口大小发生改变事件,重新绘制字符串数组,让canvas随时铺满浏览器可视区 */        window.onresize=resizeCanvas;        function resizeCanvas(){            w=canvas.width=window.innerWidth;            h=canvas.height=window.innerHeight;            /* 重新给全部字符串赋值 */            for(let j=0;j<num;j++){                    arr[j]={                        str:[],                 x: parseInt(w*Math.random()),                 y: parseInt(h*Math.random()-150)                    }                }            }               resizeCanvas();转载自https://www.jb51.net/article/279297.htm
  • [技术干货] 两个函数相互调用如何防止死循环【转】
    最近碰到了一个问题,就是两个函数相互调用遭遇死循环的问题,想了半天终于想出了一个算法破解,姑且叫它熵递减算法。问题的抽象代码如下1234567891011/**  methodA 和 methodB 循环调用,是死循环* */function methodA() {    console.log('A的事情');    methodB();}function methodB() {    console.log('B的事情');    methodA();}不论调用哪个方法,都会产生死循环。我想要的效果是:如果触发A方法时,也执行一下B方法,到此为止不再循环下去,反之亦然。因此,必须能判断方法是主动发起的,还是被动的。抽象代码如下:12345678910111213141516171819/**  解决问题的关键在于,判断方法是主动发起的,还是被动的* */function methodA() {    console.log('A的事情');    if('A是主动的'){        methodB();    }else{        // 不再调用下去    }}function methodB() {    console.log('B的事情');    if('B是主动的'){        methodA();    }else{        // 不再调用下去    }}解法,就是熵递减算法,如下1234567891011121314151617181920212223/** 熵递减算法* */var pairMethodStep = 2;function methodA() {    pairMethodStep --;    console.log('A的事情');    if(pairMethodStep === 1){        methodB();    }else{        pairMethodStep = 2;    }}function methodB() {    pairMethodStep --;    console.log('B的事情');    if(pairMethodStep === 1){        methodA();    }else{        pairMethodStep = 2;    }}熵递减算法的说明:给一个全局变量,叫做总步数pairMethodStep ,初始值为2。任一个方法执行时,做完自己的事情后,把pairMethodStep减成1。然后,判断此时的pairMethodStep,如果是1, 就调用另一个方法;如果是0了,就不再继续调用了,而是把pairMethodStep恢复成2。我们分析一下代码执行的过程。主动的方法执行前,pairMethodStep的值是2,它做完自己的事后,把pairMethodStep的值变成了1,紧跟着就会执行被动的方法;被动的方法执行前,pairMethodStep的值是1,被动的方法做完自己的事情后,把pairMethodStep的值减成了0,不会再调用另一个方法了(不会发生死循环了),而仅仅是把pairMethodStep还原成2。目的达到。熵递减算法,能完美地解决两个函数相互调用的问题。js函数互相调用碰到的问题项目场景两个函数互相调用时(当一个系统比较大时,尤其是涉及到一些复杂的算法时,很有可能会碰到死循环的情况发生,造成系统的CPU飙升)12345678        function a1() {            console.log("a1");            b1();        }        function b1() {            console.log("b1");            a1();        }问题描述会进入死循环原因分析就类似for循环,或者递归函数如果没有退出条件就会一直执行解决方案1234567891011121314151617181920        let flagNum = 1;          function a1() {            flagNum--;            console.log("a1");            if (flagNum === 0) {                b1();            } else {                flagNum = 1;            }        }        function b1() {            flagNum--;            console.log("b1");            if (flagNum === 0) {                a1();            } else {                flagNum = 1;            }        }总结以上为个人经验,希望能给大家一个参考转载自https://www.jb51.net/article/279298.htm
  • [技术干货] JS内存泄漏的原因及解决办法
    什么是内存泄漏?程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能:变慢,延迟大等 ,重则导致进程崩溃。我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。内存泄漏的识别方法1、使用快捷键 F12 或者 Ctrl+Shift+J 打开 Chrome 浏览器的「开发者工具」。2、选择 Performance(老版为Timeline) 选项卡,在 Capture 选项中,只勾选 Memory。3、设置完成后,点击最左边的 Record 按钮,然后就可以访问网页了。4、打开一个网站,例如:www.taobao.com,当网页加载完成后,点击 Stop,等待分析结果。5、然后在 ChartView 上寻找内存急速下降的部分,查看对应的 EventLog,可以从中找到 GC 的日志。具体过程如下图所示:内存泄露的常见原因及处理方式常见原因:1. 意外的全局变量下面代码中变量bar在foo函数内,但是bar并没有声明.JS就会默认将它变为全局变量,这样在页面关闭之前都不会被释放.function foo(){ bar=2 console.log('bar没有被声明!')}b 没被声明,会变成一个全局变量,在页面关闭之前不会被释放.使用严格模式可以避免.2. dom清空时,还存在引用很多时候,为了方便存取,经常会将 DOM 结点暂时存储到数据结构中.但是在不需要该DOM节点时,忘记解除对它的引用,则会造成内存泄露.var element = { shotCat: document.getElementById('shotCat')};document.body.removeChild(document.getElementById('shotCat'));// 如果element没有被回收,这里移除了 shotCat 节点也是没用的与此类似情景还有: DOM 节点绑定了事件, 但是在移除的时候没有解除事件绑定,那么仅仅移除 DOM 节点也是没用的3. 定时器中的内存泄漏var someResource = getData();setInterval(function() { var node = document.getElementById('Node'); if(node) { node.innerHTML = JSON.stringify(someResource)); }}, 1000);如果没有清除定时器,那么 someResource 就不会被释放,如果刚好它又占用了较大内存,就会引发性能问题. 但是 setTimeout ,它计时结束后它的回调里面引用的对象占用的内存是可以被回收的. 当然有些场景 setTimeout 的计时可能很长, 这样的情况下也是需要纳入考虑的.4. 不规范地使用闭包例如下面的例子: 相互循环引用.这是经常容易犯的错误,并且有时也不容易发现.function foo() { var a = {}; function bar() { console.log(a); }; a.fn = bar; return bar; };bar和a形成了相互循环引用.可能有人说bar里不使用console.log(a)不就没有引用了吗就不会造成内存泄露了.NONONO,bar作为一个闭包,即使它内部什么都没有,foo中的所有变量都还是隐式地被 bar所引用。 即使bar内什么都没有还是造成了循环引用,那真正的解决办法就是,不要将a.fn = bar.避免策略:减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收(即赋值为null);注意程序逻辑,避免“死循环”之类的 ;避免创建过多的对象 原则:不用了的东西要记得及时归还。减少层级过多的引用
  • [问题求助] 预约会议后的回调函数缺少对应的返回参数
    返回的对象里,对应param属性里缺少confBaseInfo属性,这个属性里会有对应的会议号等信息
  • [技术干货] 基于Java+SpringBoot+vue+element驾校管理系统设计和实现-转载
     一、前言介绍:         随着社会的发展和科学技术的进步,互联网技术越来越受欢迎。网络传播的生活方式逐渐受到广大人民群众的喜爱。越来越多的互联网爱好者开始在互联网上满足他们的基本需求,同时逐渐进入各个用户的生活起居。互联网具有许多优点,例如便利性,速度,高效率和低成本。因此,类似于驾校管理,满足用户工作繁忙的需求,不仅是方便用户随时查看信息的途径,而且还能提高管理效率。本文首先以驾校管理过程的基本问题作为研究对象。在开发系统之前,我们对现有状况进行了详细的调查和分析。最后,我们利用计算机技术开发了一套完整合适的驾校管理。该系统的实现主要优势是:该系统主要采用计算机技术开发,它方便快捷;系统可以通过管理员界面查看系统所涉及的驾校管理所有信息管理。          驾校管理软件是一款方便、快捷、实用的信息服务查询软件。随着智能网络在全球市场的不断普及以及各种智能平台的使用,作为中国主流智能的技术开发系统,自然需要这样的软件来满足更多用户的需求和体验。系统的开发与人们的日常需求相关,如通过管理系统获取到个人中心、学员管理、驾校教练管理、预约教练管理、预约教练管理、评价教练管理、考试成绩管理、考试通知管理、报考信息管理、练车通知管理、预约练车管理、驾考套餐管理、报名信息管理、车辆信息管理等信息详细情况,了解最新资讯信息等。  二、主要技术:  2.1  Spring Boot框架介绍:         Spring框架是Java平台上的一种开源应用框架,提供具有控制反转特性的容器。尽管Spring框架自身对编程模型没有限制,但其在Java应用中的频繁使用让它备受青睐,以至于后来让它作为EJB(EnterpriseJavaBeans)模型的补充,甚至是替补。Spring框架为开发提供了一系列的解决方案,比如利用控制反转的核心特性,并通过依赖注入实现控制反转来实现管理对象生命周期容器化,利用面向切面编程进行声明式的事务管理,整合多种持久化技术管理数据访问,提供大量优秀的Web框架方便开发等等。Spring框架具有控制反转(IOC)特性,IOC旨在方便项目维护和测试,它提供了一种通过Java的反射机制对Java对象进行统一的配置和管理的方法。Spring框架利用容器管理对象的生命周期,容器可以通过扫描XML文件或类上特定Java注解来配置对象,开发者可以通过依赖查找或依赖注入来获得对象。Spring框架具有面向切面编程(AOP)框架,SpringAOP框架基于代理模式,同时运行时可配置;AOP框架主要针对模块之间的交叉关注点进行模块化。Spring框架的AOP框架仅提供基本的AOP特性,虽无法与AspectJ框架相比,但通过与AspectJ的集成,也可以满足基本需求。Spring框架下的事务管理、远程访问等功能均可以通过使用SpringAOP技术实现。Spring的事务管理框架为Java平台带来了一种抽象机制,使本地和全局事务以及嵌套事务能够与保存点一起工作,并且几乎可以在Java平台的任何环境中工作。  2.2 MYSQL数据库:                 数据库是系统开发过程中不可或缺的一部分。 在WEB应用方面,MySQL AB开发了一个具有很大优势的MySQL关系数据库管理系统。 MySQL可以将数据存储在不同的表中,这非常灵活,并且还可以提高系统在实际应用中的速度。 数据库访问最常用于标准SQL语言,MySQL用于SQL语言,因此它具有高度兼容性。数据库的操作是必不可少的,包括对数据库表的增加、删除、修改、查询等功能。现如今,数据库可以分为关系型数据库和非关系型数据库,Mysql属于关系性数据库,Mysql数据库是一款小型的关系型数据库,它以其自身特点:体积小、速度快、成本低等,Mysql数据库是目前最受欢迎的开源数据库。          在WEB应用技术中, Mysql数据库支持不同的操作系统平台,虽然在不同平台下的安装和配置都不相同,但是差别也不是很大,Mysql在Windows平台下两种安装方式,二进制版和免安装版。安装完Mysql数据库之后,需要启动服务进程,相应的客户端就可以连接数据库,客户端可通过命令行或者图形界面工具登录数据库。  三、系统设计: 3.1 系统架构设计: ​  3.2 登录时序图设计: ​  四、功能截图:  4.1 登录注册:  4.2 前端页面: 4.2.1 系统首页:   4.2.2 教练模块:   4.2.3 考试须知:   4.2.4 预约练车:   4.2.5 车辆信息:  4.2.6 系统公告信息:  4.2.7 个人中心模块:   4.2.8 用户后台模块:  4.3 后端管理:  4.3.1 教练管理:  4.3.2 考试通知:  4.3.3 报名管理:  4.3.4 车辆信息:  4.3.5 系统公告等  五、代码实现:     /**  * 登录相关  */ @RequestMapping("users") @RestController public class UserController{          @Autowired     private UserService userService;          @Autowired     private TokenService tokenService;       /**      * 登录      */     @IgnoreAuth     @PostMapping(value = "/login")     public R login(String username, String password, String captcha, HttpServletRequest request) {         UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));         if(user==null || !user.getPassword().equals(password)) {             return R.error("账号或密码不正确");         }         String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());         return R.ok().put("token", token);     }          /**      * 注册      */     @IgnoreAuth     @PostMapping(value = "/register")     public R register(@RequestBody UserEntity user){ //        ValidatorUtils.validateEntity(user);         if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {             return R.error("用户已存在");         }         userService.insert(user);         return R.ok();     }       /**      * 退出      */     @GetMapping(value = "logout")     public R logout(HttpServletRequest request) {         request.getSession().invalidate();         return R.ok("退出成功");     }          /**      * 密码重置      */     @IgnoreAuth     @RequestMapping(value = "/resetPass")     public R resetPass(String username, HttpServletRequest request){         UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));         if(user==null) {             return R.error("账号不存在");         }         user.setPassword("123456");         userService.update(user,null);         return R.ok("密码已重置为:123456");     }          /**      * 列表      */     @RequestMapping("/page")     public R page(@RequestParam Map<String, Object> params,UserEntity user){         EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();         PageUtils page = userService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.allLike(ew, user), params), params));         return R.ok().put("data", page);     }       /**      * 列表      */     @RequestMapping("/list")     public R list( UserEntity user){            EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();           ew.allEq(MPUtil.allEQMapPre( user, "user"));          return R.ok().put("data", userService.selectListView(ew));     }       /**      * 信息      */     @RequestMapping("/info/{id}")     public R info(@PathVariable("id") String id){         UserEntity user = userService.selectById(id);         return R.ok().put("data", user);     }          /**      * 获取用户的session用户信息      */     @RequestMapping("/session")     public R getCurrUser(HttpServletRequest request){         Long id = (Long)request.getSession().getAttribute("userId");         UserEntity user = userService.selectById(id);         return R.ok().put("data", user);     }       /**      * 保存      */     @PostMapping("/save")     public R save(@RequestBody UserEntity user){ //        ValidatorUtils.validateEntity(user);         if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {             return R.error("用户已存在");         }         userService.insert(user);         return R.ok();     }       /**      * 修改      */     @RequestMapping("/update")     public R update(@RequestBody UserEntity user){ //        ValidatorUtils.validateEntity(user);         UserEntity u = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername()));         if(u!=null && u.getId()!=user.getId() && u.getUsername().equals(user.getUsername())) {             return R.error("用户名已存在。");         }         userService.updateById(user);//全部更新         return R.ok();     }       /**      * 删除      */     @RequestMapping("/delete")     public R delete(@RequestBody Long[] ids){         userService.deleteBatchIds(Arrays.asList(ids));         return R.ok();     } }      @Configuration public class InterceptorConfig extends WebMvcConfigurationSupport{          @Bean     public AuthorizationInterceptor getAuthorizationInterceptor() {         return new AuthorizationInterceptor();     }          @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");         super.addInterceptors(registry);     }          /**      * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法      */     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/**")         .addResourceLocations("classpath:/resources/")         .addResourceLocations("classpath:/static/")         .addResourceLocations("classpath:/admin/")         .addResourceLocations("classpath:/front/")           .addResourceLocations("classpath:/public/");         registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/work/");           super.addResourceHandlers(registry);     } }  ———————————————— 版权声明:本文为CSDN博主「java李杨勇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_39709134/article/details/128781905 
  • [技术干货] Object.assign详解
    一、Object.assign是什么?       首先了解下Object.assign()是什么。我们先看看ES6官方文档是怎么介绍的?       Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。       简单来说,就是Object.assign()是对象的静态方法,可以用来复制对象的可枚举属性到目标对象,利用这个特性可以实现对象属性的合并。 二、用法:       Object.assign(target, ...sources)   参数:target--->目标对象       source--->源对象   返回值:target,即目标对象 三、使用示例: 1、目标对象和源对象无重名属性 var target={name:'guxin',age:18}; var source={state:'single'} var result=Object.assign(target,source); console.log(target,target==result); 我们可以看到source上的state属性合并到了target对象上。如果只是想将两个或多个对象的属性合并到一起,不改变原有对象的属性,可以用一个空的对象作为target对象。像下面这样: var result=Object.assign({},target,source); 2、目标对象和源对象有重名属性 上面的示例目标对象和源对象是没有重名属性的,那么如果他们有重名属性又会怎样呢?是后面的属性覆盖前面的还是前面的属性覆盖后面的呢?我们接下来看下一个例子: var target={name:'guxin',age:18} var source={state:'signle',age:22} var result=Object.assign(target,source) console.log(target)  可以看到如果有同名属性的话,后面的属性值会覆盖前面的属性值。 3、有多个源对象 前面的示例都是只有一个源对象,那么如果有多个源对象情况会不会不同呢?我们继续看下面的例子:         var target={name:'guxin',age:18}         var source1={state:'signle',age:22}         var source2={mood:'happy',age:25}         var result=Object.assign(target,source1,source2)         console.log(target) 可以看到有多个源对象情况也是和一个源对象一样的。没有同名的属性会直接复制到目标对象上,同名的属性后面的属性值会覆盖前面的同名属性值。  四、注意事项: 1、Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象,继承属性和不可枚举属性是不能拷贝的。 2、针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。 3、目标对象自身也会改变 4、异常会打断后续拷贝任务  五、兼容性 目前IE浏览器不兼容Object.assign(),如果需要兼容IE的话最好不要直接使用这个方法。  六、与$.extend()的比较 我们通过一个简单的示例来比较两者有什么不同,          var target={name:'guxin',age:18}         var source1={state:'signle',age:22}         var source2={mood:'happy',age:25}         var result=Object.assign(target,source1,source2)         console.log(target,'assign')         var targetObj={name:'guxin',age:18}         var sourceObj1={state:'signle',age:22}         var sourceObj2={mood:'happy',age:25}         var result=$.extend(targetObj,sourceObj1,sourceObj2)         console.log(targetObj,'extend') 可以看到两者得到的结果是一样的。所以,我认为这两个方法,除了兼容性应该是一样的。 ———————————————— 原文链接:https://blog.csdn.net/guxin_duyin/article/details/88916106 
  • [技术干货] javascript中将xml转为json的方法
    这篇文章将为大家详细讲解有关javascript中将xml转为json的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。javascript中将xml转换为json字符串的方法:首先通过XML字符串或请求XML文件来获取XML的DOM对象;然后通过遍历和递归来获取子元素的nodeValue值;最后拼接出JSON字符串即可。利用JavaScript将XML转换为JSON首先通过XML字符串来生成XML的DOM对象:/**  * 通过传入xml的内容字符串来解析xml  * @param xmlString xml字符串  * @returns xml的Document对象  */ function getXmlDocumentByXmlString(xmlString) {     var xmlDoc = null;     if (window.DOMParser) {         var parser = new DOMParser();         xmlDoc = parser.parseFromString(xmlString, "text/xml");     } else {         //IE         xmlDoc = new ActiveXObject("Microsoft.XMLDOM");         xmlDoc.async = "false";         xmlDoc.loadXML(xmlString);     }     return xmlDoc; }或者通过请求XML文件来获取XML的DOM对象:/**  * 通过传入xml文件路径来解析xml文档  * @param xmlFilePath xml文档路径,如:files/test.xml  * @returns xml的Document对象  */ function getXmlDocumentByFilePath(xmlFilePath) {     //xmlDocument对象     var xmlDoc = null;     //xmlhttp对象     var xmlhttp = null;     if (window.XMLHttpRequest) {         //IE7+, FireFox, Chrome, Opera, Safari         xmlhttp = new XMLHttpRequest();     } else {         //IE6, IE5         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");     }     xmlhttp.open("GET", xmlFilePath, false);     xmlhttp.send();     xmlDoc = xmlhttp.responseXML;     return xmlDoc; }接下来就是重点的部分了,通过遍历和递归获取子元素的nodeValue,来拼接出JSON字符串,实现将XML转换成JSON字符串:/**  * 将XML的Document对象转换为JSON字符串  * @param xmlDoc xml的Document对象  * @return string  */ function convertToJSON(xmlDoc) {     //准备JSON字符串和缓存(提升性能)     var jsonStr = "";     var buffer = new Array();     buffer.push("{");     //获取xml文档的所有子节点     var nodeList = xmlDoc.childNodes;     generate(nodeList);     /**      * 中间函数,用于递归解析xml文档对象,并附加到json字符串中      * @param node_list xml文档的的nodeList      */     function generate(node_list) {         for (var i = 0; i < node_list.length; i++) {             var curr_node = node_list[i];             //忽略子节点中的换行和空格             if (curr_node.nodeType == 3) {                 continue;             }             //如果子节点还包括子节点,则继续进行遍历             if (curr_node.childNodes.length > 1) {                 buffer.push("\"" + curr_node.nodeName + "\": {");                 generate(curr_node.childNodes);             } else {                 var firstChild = curr_node.childNodes[0];                 if (firstChild != null) {                     //nodeValue不为null                     buffer.push("\"" + curr_node.nodeName + "\":\"" + firstChild.nodeValue + "\"");                 } else {                     //nodeValue为null                     buffer.push("\"" + curr_node.nodeName + "\":\"\"");                 }             }             if (i < (node_list.length - 2)) {                 buffer.push(",");             } else {                 break;             }         }         //添加末尾的"}"         buffer.push("}");     }     jsonStr = buffer.join("");     return jsonStr; }使用方式:通过getXmLDocumentByFilePath(xmlFilePath)或者getXmlDocumentByXmlString(xmlString)获取XML的Document对象,然后通过调用convertToJSON(xmlDocument)传入xml的Ducument对象即可得到转换后的JSON字符串。适用范围:不含有attribute的任意XML文档。关于“javascript中将xml转为json的方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。原文链接:https://m.yisu.com/zixun/446969.html
  • [技术干货] vue中async和await异步编程
    async&await是Promise的语法糖,使用他的目的就是用同步的写法,写异步的操作。async 是“异步”的简写, async 用于申明一个异步的 function,await 可以认为是 async wait 的简写,await 用于等待一个异步方法执行完成。当我们函数中需要返回值是promise对象时通常用async和await简化。          async作为一个关键字放到函数之前,表示函数是异步的函数,异步函数也就意味着该函数的执行不会阻塞后面代码的执行,等async 函数返回一个promise 对象。  1.async async可以作用在任何方法前, 返回值是一个Promise对象  async function a(){  } console.log(a());   var b = (async () => {       }) console.log(b()); async函数内部return的返回值, 会成为then回调函数的参数  async function a() {     return 123 } a().then(res=>{     console.log(res); }) async作用的方法,如果内部出现报错,可以被promise的catch方法捕获  async function a() {     console.log(a);     let a = 123; } a().catch(err=>{     console.log(err); }) 2. await await只能作用在async修饰的方法中,不能单独使用,如果使用报错、  function a(){     await //报错:await is not defined     console.log(123); } a() 正常情况 await后面跟着一个Promise对象,返回的是Promise对象的成功后结果  async function a(){     var b = await new Promise((resolve,reject)=>{         resolve('123')     })     return b } a().then(res=>{     console.log(res); }) ———————————————— 原文链接:https://blog.csdn.net/qq_44858608/article/details/124332167 
  • [技术干货] async和await用法介绍
     一;async 1.函数前面加上 async 关键字,则该函数会返回一个结果为 promise 的对象。 2. async 函数返回 promise 对象的状态。 2.1:如果返回的是一个非 Promise 类型的数据, 则async 函数返回 promise 的状态 为 fulfilled 成功。 2.2:如果返回的是一个 Promise对象,则 async 函数返回 promise 的状态由返回的Promise对象的状态决定。 2.3:如果 throw Errow 抛出异常,则 async 函数返回 promise 的状态为 rejected 失败。 二;await 1.await 右侧的表达式一般为 promise 对象。 2.await 是在等一个表达式的结果,等一个返回值(回调成功的内容) 3.如果 await 右侧是一个 promise 对象,则 await 返回的是 promise 成功的值。 注意: 1.await 必须写在 async 函数中,但 async 函数中可以没有 await。 2.如果 await 的 promise 失败了,就会抛出异常,该异常需要通过 try catch 捕获处理。 3.如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。  三;async 和 await 结合发送 ajax   1.封装一个 发送GET请求的 promise  function sendAjax(url) {             return new Promise((resolve, reject) => {                 const xhr = new XMLHttpRequest()                 xhr.open('GET', url)                 xhr.send()                 // 处理返回结果                 xhr.onreadystatechange = function () {                     if (xhr.readyState == 4) {                         // 判断状态码                         if (xhr.readyState >= 200 && xhr.readyState < 300) {                             resolve(xhr.response)                         }else {                             reject(xhr.status)                         }                     }                 }             })         } 2.async和await结合发送ajax请求  // 触发点击事件发送ajax请求         let btn = document.querySelector('#btn')         btn.addEventListener('click', async function () {             try {                 let res = await sendAjax('get请求地址')                 console.log(res);             } catch (error) {                 console.log(error);             }         }) ———————————————— 原文链接:https://blog.csdn.net/Allurewuhui/article/details/123434870 
  • [技术干货] JavaScript开发小技巧
    1、使用var声明变量如果给一个没有声明的变量赋值,默认会作为一个全局变量(即使在函数内赋值)。要尽量避免不必要的全局变量。2、行尾使用分号虽然JavaScript允许省略行尾的分号,但是有时不注意的省略,会导致不必要的错误。建议在可用可不用行尾分号的地方加上分号。3、获取指定范围内的随机数var getRandom = function(max, min) {min = arguments[1] || 0;return Math.floor(Math.random() * (max - min + 1) + min);};上面的函数接受一个你希望的随机最大数和一个你希望的随机最小数。4、打乱数字数组的顺序var sortArray = array.sort(function(){ return Math.random() - 0.5;});5、取出数组中的随机项var ran = array[Math.floor(Math.random() * array.length)];6、去除字符串的首尾空格var s = string.trim();7、类数组对象转为数组比如:类数组对象遍历:Array.prototype.forEach.call(argumens,function(value){})DOM的NodeList和HTMLCollection也是类数组对象8、获取数组中的最大值和最小值var max = Math.max.apply(Math, array);var min = Math.min.apply(Math, array);9、清空数组array.length = 0;array = [];10、保留指定小数位var num = num.toFixed(2);返回字符串,保留两位小数11、使用for-in循环来遍历对象的属性for(var key in object) { // object[key]}不要用for-in来遍历数据12、获取某月天数function getMonthDay(date){ date = date || new Date(); if(typeof date === 'string') { date = new Date(date); }; date.setDate(32); return 32 - date.getDate();}传入date参数,可以是字符串、日期对象实例;为空表示当月天数13、浮点数问题0.1 + 0.2 = 0.30000000000000004 != 0.3JavaScript的数字都遵循IEEE 754标准构建,在内部都是64位浮点小数表示14、JSON序列化和反序列化使用JSON.stringify()来将JavaScript对象序列化为有效的字符串。使用JSON.parse()来将有效的字符串转换为JavaScript对象。在AJAX传输数据时很有用15、使用“===”替换“==”相等运算符(==)在比较时会将操作数进行相应的类型转换,而全等运算符(===)不会进行类型转换。16、避免使用with()使用with()可以把变量加入到全局作用域中,因此,如果有其它的同名变量,一来容易混淆,二来值也会被覆盖。17、不要使用eval()或函数构造器eval()和函数构造器(Function consturctor)的开销较大,每次调用,JavaScript引擎都要将源代码转换为可执行的代码。18、简化if语句if (condition) { fn();}可替换成:condition && fn();19、给可能省略的参数赋默认值function test(a, b){ a = a || '1';}20、给数组循环中缓存length的值如果你确定循环中数组的长度不会变化,那么你可以这样:var length = array.length;for(var i = 0; i < length; i++) {}可以避免在每次迭代都将会重新计算数组的大小,提高效率21、合并数组对于小数组,我们可以这样:var arr1 = [1,2,3];var arr2 = [4,5,6];var arr3 = arr1.concat(arr2); // [1,2,3,4,5,6]不过,concat()这个函数并不适合用来合并两个大型的数组,因为其将消耗大量的内存来存储新创建的数组。在这种情况之个,可以使用Array.prototype.push.apply(arr1,arr2)来替代创建一个新数组。这种方法不是用来创建一个新的数组,其只是将第一个第二个数组合并在一起,同时减少内存的使用:Array.prototype.push.apply(arr1, arr2); console.log(arr1); // [1,2,3,4,5,6]22 枚举对象“自身”的属性for...in除了枚举对象“自身”的属性外,还会枚举出继承过来的属性。var hasOwn = Object.prototype.hasOwnProperty;var obj = {name: 'tg', age: 24};for(var name in obj) { if (hasOwn.call(obj, name)) { console.log(name + ':' + obj[name]); }}// name:tg// age:24转载自http://bbs.jeecms.com/java/83762.jhtml
  • [技术干货] 基于Java+SpringBoot+vue等疫情期间在线网课管理系统详细设计实现-转载
     一、前言介绍: 1.1 背景及意义         疫情网课也都将通过计算机进行整体智能化操作,对于疫情网课管理系统所牵扯的管理及数据保存都是非常多的,例如管理员;首页、个人中心、学生管理、教师管理、班级管理、课程分类管理、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理、论坛交流、系统管理,学生;首页、个人中心、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理,教师;首页、个人中心、学生管理、班级管理、课程分类管理、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理、系统管理,前台首页;首页、课程表、论坛交流、学校公告、个人中心、后台管理、师生聊天等功能,这给管理者的工作带来了巨大的挑战,面对大量的信息,传统的管理系统,都是通过笔记的方式进行详细信息的统计,后来出现电脑,通过电脑输入软件将纸质的信息统计到电脑上,这种方式比较传统,而且想要统计数据信息比较麻烦,还受时间和空间的影响,所以为此开发了疫情网课管理系统;为学生提供了方便管理平台,方便管理员查看及维护,并且可以通过需求进行内容的编辑及维护等;对于学生和教师而言,可以随时进行查询所需信息,管理员可以足不出户就可以获取到系统的数据信息等,而且还能节省学生和教师很多时间,所以开发疫情网课管理系统给管理者带来了很大的方便,同时也方便管理员对学生及教师信息进行处理。          本论文疫情网课管理系统主要牵扯到的程序,数据库与计算机技术等。覆盖知识面大,可以大大的提高系统人员工作效率。  1.2 系统运行环境  开发系统:Windows10  架构模式:MVC/前后端分离  JDK版本:Java JDK1.8  开发工具:IDEA  数据库版本: mysql5.7  数据库可视化工具: navicat for mysql  服务器:SpringBoot自带 apache tomcat  主要技术:Java,Springboot,mybatis,mysql,jquery,html,vue,elementui等  二、系统设计: 2.1 系统架构设计 ​  2.2 角色功能图 ​  2.3 登录时序图设计 ​  三、功能截图:  3.1 登录注册: 管理员通过用户名和密码、验证码、角色填写完成后进行登录  ​  学生注册,在学生注册页面可以填写学号、密码、学生、年龄、手机、邮箱等信息进行注册   ​  3.2 前台首页: 学生点击进入到系统操作界面可以查看首页、个人中心、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理等功能模块,个人信息:通过列表可以获取学号、学生、性别、年龄、手机、邮箱、班级、照片等信息并进行修改操作。  ​   ​   课程表信息:  ​  可以下载和收藏操作   ​ 论讨交流,可以发布论讨文章和进行评论交流等  ​  学校公告:  ​  个人中心:  ​ 师生聊天:  ​   用户后端:  ​  3.3 后台管理:  管理员登录成功后进入到系统操作界面,可以对首页、个人中心、学生管理、教师管理、班级管理、课程分类管理、课程表管理、课程信息管理、作业信息管理、请假信息管理、上课签到管理、论坛交流、系统管理等功能模块进行相对应操作。  学生管理:  ​   课程表管理:  ​  作业信息管理:  ​ 学校公告:  ​  四、数据设计: 每个数据库的应用它们都是和区分开的,当运行到一定的程序当中,它就会与自己相关的协议与客户端进行通讯。那么这个系统就会对使这些数据进行连接。当我们选择哪个桥段的时候,接下来就会简单的叙述这个数据库是如何来创建的。当点击完成按钮的时候就会自动在对话框内弹出数据源的名称,在进行点击下一步即可,直接在输入相对应的身份验证和登录密码。   ​  五、代码实现: /**  * 登录相关  */ @RequestMapping("users") @RestController public class UserController{          @Autowired     private UserService userService;          @Autowired     private TokenService tokenService;       /**      * 登录      */     @IgnoreAuth     @PostMapping(value = "/login")     public R login(String username, String password, String captcha, HttpServletRequest request) {         UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));         if(user==null || !user.getPassword().equals(password)) {             return R.error("账号或密码不正确");         }         String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());         return R.ok().put("token", token);     }          /**      * 注册      */     @IgnoreAuth     @PostMapping(value = "/register")     public R register(@RequestBody UserEntity user){ //        ValidatorUtils.validateEntity(user);         if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {             return R.error("用户已存在");         }         userService.insert(user);         return R.ok();     }       /**      * 退出      */     @GetMapping(value = "logout")     public R logout(HttpServletRequest request) {         request.getSession().invalidate();         return R.ok("退出成功");     }          /**      * 密码重置      */     @IgnoreAuth     @RequestMapping(value = "/resetPass")     public R resetPass(String username, HttpServletRequest request){         UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));         if(user==null) {             return R.error("账号不存在");         }         user.setPassword("123456");         userService.update(user,null);         return R.ok("密码已重置为:123456");     }          /**      * 列表      */     @RequestMapping("/page")     public R page(@RequestParam Map<String, Object> params,UserEntity user){         EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();         PageUtils page = userService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.allLike(ew, user), params), params));         return R.ok().put("data", page);     }       /**      * 列表      */     @RequestMapping("/list")     public R list( UserEntity user){            EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();           ew.allEq(MPUtil.allEQMapPre( user, "user"));          return R.ok().put("data", userService.selectListView(ew));     }     /**      * 信息      */     @RequestMapping("/info/{id}")     public R info(@PathVariable("id") String id){         UserEntity user = userService.selectById(id);         return R.ok().put("data", user);     }          /**      * 获取用户的session用户信息      */     @RequestMapping("/session")     public R getCurrUser(HttpServletRequest request){         Long id = (Long)request.getSession().getAttribute("userId");         UserEntity user = userService.selectById(id);         return R.ok().put("data", user);     }     /**      * 保存      */     @PostMapping("/save")     public R save(@RequestBody UserEntity user){         if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {             return R.error("用户已存在");         }         userService.insert(user);         return R.ok();     }       /**      * 修改      */     @RequestMapping("/update")     public R update(@RequestBody UserEntity user){         UserEntity u = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername()));         if(u!=null && u.getId()!=user.getId() && u.getUsername().equals(user.getUsername())) {             return R.error("用户名已存在。");         }         userService.updateById(user);//全部更新         return R.ok();     }       /**      * 删除      */     @RequestMapping("/delete")     public R delete(@RequestBody Long[] ids){         userService.deleteBatchIds(Arrays.asList(ids));         return R.ok();     } }  ———————————————— 版权声明:本文为CSDN博主「java李杨勇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_39709134/article/details/128438852 
  • [技术干货] 基于Java+Springboot+Vue+elememt社区疫情返乡管控系统设计实现-转载
    前言介绍:          随着国内经济形势的不断发展,中国互联网进入了一个难得的高峰发展时期,这使得中外资本家纷纷转向互联网市场。然而,许多管理领域的不合理结构,人员不足以及市场管理需求的增加使得更多的人具备了互联网管理的意识。在当今高度发达的信息中,信息管理改革已成为一种更加广泛和全面的趋势。“社区疫情返乡人员防控管理平台系统”是基于Mysql5.7版本数据库,在Springboot程序设计的基础上实现的。                  该系统具有首页、个人中心、用户管理、物资捐赠管理。物资申请管理、物资捐赠审核、反人员管理、外出报备管理、投诉信息管理、体温上报管理、商品代买管理、商品配送管理、社区论坛、系统管理等功能。通过用户模块来管理自己的信息。用户注册登陆本社区疫情后,可以进入个人后台来管理首页、个人中心、返乡报备管理、外出报备管理、投诉信息管理、体温上报管理、商品代买管理、商品配送管理等功能。最后在主页页面,增加了推送功能,使用户可以直接快速接触到最丰富的内容、通过对此项目的练习、设计、学习、代码编写、让自己熟练的运用Java主流相关的一系列技术、比如、系统前期的调研、数据库的反复设计和修改、字段长度的控制、类型的掌控、编码的设计、以及代码规范、接口调试、前端页面样式代码编写、前端后端对接、以及跨域问题和其他权限问题的解决。为以为从事Java开发或相关工作打下巩固基础。  此社区疫情基本上实现了整个社区疫情返乡人员防控管理平台信息管理的过程,向大众提供了一个安全、动态、高效的社区疫情防控管理平台系统。  二、系统设计: 系统整体架构: ​​  主要研究方法: 本系统采用基于Java语言B/S架构模式实现的,即Java启动运行的客户端与服务器的结构,基于 J2EE的基本标准,Tomcat7.0及以上作为运行服务器支持,基于、java、springboot、vue等主要技术设计,idea作为开发环境,数据库采用Mysql 5.0以上。  (1)项目调查法:参考基于java社区疫情返乡人员防控管理平台系统相关的系统设计和实现、结合这次毕业设计的自己的系统需求调研,设计出本系统的主要功能设计和架构。  (2)文献参考法:通过查阅阅读最近三年基于java社区疫情返乡人员防控管理平台有关的优质文献参考和相关书籍、了解基于java社区疫情返乡人员防控管理平台的现状和涉及的技术情况  (3)经验总结法:经过网络搜索查看、老师的指导、自己的学习开发经验结合、对系统开发整理、具体情况,进行归纳、分析总结,满足系统的各项可行性分析,使系统设计和实现的合理化、标准化。  (4)实证测试法:通过自己对前面资料的查询、阅读、以及利用自己所学习的计算机相关技术来完成编码实现、进行系统功能测试、代码编写、完成功能模块开发。最后进行测试  登录模块设计: ​  三、功能截图:  登录注册: 用户后台登录:  ​  系统首页: 社区疫情防控管理平台系统,用户输入进入到系统首页可以查看首页、社区论坛、社区公告、个人中心、后台管理等内容进行操作。    物资申请: 物资申请列表,这里的物资是用户捐赠的一些疫情防疫物资等、点击查看详情和申请操作。   申请详情: 比如常用的口罩信息等。  ​​  公告列表 点击可以查看公告详情,这里的数据是后台管理员编辑上传就行。    公告详情  社区论坛: 点击查看社区论坛列表和详情,用户登录后可以添加社区论坛信息,可以进行论坛信息进行评论等操作。   点击查看详情,用户登录后可以进行评论操作。    后台管理: 管理员登录进入社区疫情防控管理平台系统可以查看首页、个人中心、用户管理、物资捐赠管理,物资申请管理,返乡报备管理、外出报备管理、投诉信息管理、体温上报管理、商品代买管理、商品配送管理、社区论坛、系统管理等内容进行详细操作   捐赠物资管理:  返乡报备管理 : 在返乡报备管理页面可以对出发地点、返乡时间、体温、身体状态、近15天轨迹、核酸报告、经过疫区、报备时间、用户姓名、姓名、用户手机、详细住址、审核回复、审核状态、审核等信息进行详情,修改或删除等操作。   外出申请管理: 在外出报备管理页面可以对外出事由、外出地点、经过疫区、外出时间、返回时间、外出报备出行方式、随行人员、用户姓名、姓名、用户手机、详细住址、审核回复、审核状态、审核等信息进行详情,修改或删除等操作。   投诉信息管理:  核酸检测管理: 在核酸检测管理页面可以对用户姓名、姓名、性别、年龄、体温、健康码、是否咳嗽、是否腹泻、是否乏力、是否就医、其他情况、上报时间等信息进行详情,修改或删除等操作   商品代买管理: 在商品代买管理页面可以对用户姓名、姓名、用户手机、详细住址、申请时间、备注、审核回复、审核状态、审核等信息进行详情,修改或删除等操作。   商品配送管理:  社区论坛管理:  返乡公告管理:  四、数据设计: 主要数据库表字段设计: 用户信息:主键id、用户id、用户姓名、表名、角色、密码、新增时间、过期时间  物资捐赠:物资名称,物资介绍,物资图片,捐赠地址,捐赠数量,捐赠对象,发布时间,捐赠内容。审核状态,审核回复,备注等。  物资申请:物资名称,物资信息,申请人,申请时间,申请数量,用户账号,审核状态,审核回复  疫情社区论坛信息:主键id、创建日期、帖子标题名称、帖子内容、父节点id、用户id、用户姓名、状态  返乡报备:主键id、创建日期、出发地点、返乡时间、体温、身体状态、近15天轨迹、核酸报告、经过疫区、报备时间、用户姓名、姓名、用户手机、详细住址、是否审核、审核回复  用户信息:主键id、创建日期、用户姓名、密码、姓名、头像、性别、年龄、详细住址、用户手机、邮箱、身份证  外出报备:主键id、创建日期、外出事由、外出地点、经过疫区、外出时间、返回时间、外出报备出行方式、随行人员、用户姓名、姓名、用户手机、详细住址、是否审核、审核回复  投诉信息:(主键id、创建日期、标题名称、名称、类型、图片信息、投诉内容、投诉日期、用户姓名、姓名、用户手机、详细住址、是否审核、审核回复  体温上报信息:主键id、创建日期、用户姓名、姓名、性别、年龄、体温、健康码、是否咳嗽、是否腹泻、是否乏力、是否就医、其他情况、上报时间  商品配送信息:主键id、创建日期、用户姓名、姓名、用户手机、详细住址、商品金额、配送状态、更新时间、是否支付  社区疫情公告信息:主键id、创建日期、标题名称、简介、图片信息内容  数据库实体设计: 用户管理结构图: ​  投诉信息管理实体: ​体温上报管理实体: ​  五、代码实现: 用户登录: <div id="app" class="login">         <form id="loginForm" class="layui-form login-form" :style='{"padding":"20px","boxShadow":"0 0 0px rgba(255,0,0,.8)","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"rgba(255, 255, 255, 1)","borderRadius":"20px","borderWidth":"2px","width":"400px","borderStyle":"solid","justifyContent":"center","height":"auto"}'>             <h1 class="logo" v-if="false" :style='{"padding":"5px 0","boxShadow":"0 0 6px rgba(255,0,0,.8)","borderColor":"rgba(0,0,0,.3)","backgroundColor":"#fff","borderRadius":"6px","borderWidth":"0","borderStyle":"solid"}'><img :style='{"boxShadow":"0 0 6px rgba(255,0,0,.8)","margin":"0 auto","borderColor":"rgba(0,0,0,.3)","borderRadius":"100%","borderWidth":"1px","width":"44px","borderStyle":"solid","height":"44px"}' src="$template2.front.login.logo.backgroundImage"></h1>                          <div class="msg-warn hide title" v-if="true" :style='{"padding":"0 10px","boxShadow":"0 0 6px rgba(255,0,0,.8)","margin":"10px auto","borderColor":"rgba(0,0,0,1)","backgroundColor":"#f7f7f7","color":"red","isshow":true,"borderRadius":"8px","borderWidth":"0","width":"auto","lineHeight":"32px","fontSize":"12px","borderStyle":"solid"}'>公共场所不建议自动登录,以防账号丢失</div>             <div :style='{"padding":"0","boxShadow":"0 0 6px rgba(255,0,0,0)","margin":"0 auto","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"rgba(213, 195, 195, 0.49)","borderRadius":"20px","borderWidth":"0 0 0px 0","width":"80%","borderStyle":"solid","height":"64px"}' class="form-item">                 <label v-if="false" :style='{"padding":"0 10px","boxShadow":"0 0 6px rgba(255,0,0,0)","borderColor":"rgba(0,0,0,0)","backgroundColor":"transparent","color":"#333","borderRadius":"0","textAlign":"right","borderWidth":"0","width":"84px","fontSize":"16px","borderStyle":"solid"}' class="form-label">账号</label>                 <input :style='{"padding":"0 10px","boxShadow":"0 0 6px rgba(0,0,0,.5)","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"#fff","color":"#333","borderRadius":"8px","textAlign":"left","borderWidth":"1px","width":"100%","fontSize":"14px","borderStyle":"solid","height":"44px"}' type="text" name="username" required lay-verify="required" placeholder="请输入账号" autocomplete="off" class="layui-input">             </div>             <div :style='{"padding":"0","boxShadow":"0 0 6px rgba(255,0,0,0)","margin":"0 auto","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"rgba(213, 195, 195, 0.49)","borderRadius":"20px","borderWidth":"0 0 0px 0","width":"80%","borderStyle":"solid","height":"64px"}' class="form-item">                 <label v-if="false" :style='{"padding":"0 10px","boxShadow":"0 0 6px rgba(255,0,0,0)","borderColor":"rgba(0,0,0,0)","backgroundColor":"transparent","color":"#333","borderRadius":"0","textAlign":"right","borderWidth":"0","width":"84px","fontSize":"16px","borderStyle":"solid"}' class="form-label">密码</label>                 <input :style='{"padding":"0 10px","boxShadow":"0 0 6px rgba(0,0,0,.5)","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"#fff","color":"#333","borderRadius":"8px","textAlign":"left","borderWidth":"1px","width":"100%","fontSize":"14px","borderStyle":"solid","height":"44px"}' type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">             </div>                 <div class="form-item codes" :style='{"padding":"0","boxShadow":"0 0 6px rgba(255,0,0,0)","margin":"0 auto","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"rgba(213, 195, 195, 0.49)","borderRadius":"20px","borderWidth":"0 0 0px 0","width":"80%","borderStyle":"solid","height":"64px"}'>                   <input style="flex: 1;" type="text" id="code" placeholder="请输入验证码">                   <div class="nums" id="nums" style="display: flex;justify-content: center;align-items: center;">                                        </div>                 </div>               <div :style='{"padding":"0","boxShadow":"0 0 6px rgba(255,0,0,0)","margin":"0 auto","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"#fff","borderRadius":"0","borderWidth":"0 0 1px 0","width":"80%","borderStyle":"solid","height":"44px"}' class="form-item l-redio">                 <input v-if="item.hasFrontLogin=='是'" v-for="(item,index) in menu" v-bind:key="index" type="radio" name="role" id="role" :value="item.tableName" :title="item.roleName">             </div>             <button :style='{"padding":"0 10px","boxShadow":"0 0px 0px rgba(255, 0, 0, 1)","margin":"10px auto","borderColor":"rgba(0, 112, 126, 1)","backgroundColor":"rgba(38, 155, 158, 1)","color":"#fff","borderRadius":"8px","borderWidth":"0","width":"60%","fontSize":"14px","borderStyle":"solid","height":"44px"}' class="layui-btn layui-btn-fluid layui-btn-danger btn-submit" lay-submit lay-filter="login">登录</button>             <p :style='{"color":"rgba(255, 0, 0, 1)","textAlign":"left","fontSize":"12px"}' class="txt"><a style="color: inherit;font-size: inherit;" v-if="item.hasFrontRegister=='是'" v-for="(item,index) in menu" v-bind:key="index" :href="'javascript:registerClick(\''+item.tableName+'\')'">注册{{item.roleName.replace('注册','')}}</a></p>         </form>     </div>  物资申请:     /**  * 申请物资  * 后端接口  * @author   * @email   * @date 2021210-11 19:15:03  */ @RestController @RequestMapping("/juanzengdingdan") public class JuanzengdingdanController {     @Autowired     private JuanzengdingdanService juanzengdingdanService;          /**      * 后端列表      */     @RequestMapping("/page")     public R page(@RequestParam Map<String, Object> params,JuanzengdingdanEntity juanzengdingdan,         HttpServletRequest request){         String tableName = request.getSession().getAttribute("tableName").toString();         String username = (String)request.getSession().getAttribute("username");         EntityWrapper<JuanzengdingdanEntity> ew = new EntityWrapper<JuanzengdingdanEntity>();         if(tableName.equals("jigou")) {             juanzengdingdan.setJigouzhanghao((String)request.getSession().getAttribute("username"));         }         if(tableName.equals("yonghu")) {             juanzengdingdan.setYonghuzhanghao((String)request.getSession().getAttribute("username"));         }         PageUtils page = juanzengdingdanService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, juanzengdingdan), params), params));           return R.ok().put("data", page);     }             /**      * 列表      */     @RequestMapping("/lists")     public R list( JuanzengdingdanEntity juanzengdingdan){            EntityWrapper<JuanzengdingdanEntity> ew = new EntityWrapper<JuanzengdingdanEntity>();           ew.allEq(MPUtil.allEQMapPre( juanzengdingdan, "juanzengdingdan"));          return R.ok().put("data", juanzengdingdanService.selectListView(ew));     }        /**      * 查询      */     @RequestMapping("/query")     public R query(JuanzengdingdanEntity juanzengdingdan){         EntityWrapper< JuanzengdingdanEntity> ew = new EntityWrapper< JuanzengdingdanEntity>();          ew.allEq(MPUtil.allEQMapPre( juanzengdingdan, "juanzengdingdan"));          JuanzengdingdanView juanzengdingdanView =  juanzengdingdanService.selectView(ew);         return R.ok("查询申请物资成功").put("data", juanzengdingdanView);     }             /**      * 前端详情      */     @RequestMapping("/detail/{id}")     public R detail(@PathVariable("id") Long id){         JuanzengdingdanEntity juanzengdingdan = juanzengdingdanService.selectById(id);         return R.ok().put("data", juanzengdingdan);     }              /**      * 前端保存      */     @RequestMapping("/add")     public R add(@RequestBody JuanzengdingdanEntity juanzengdingdan, HttpServletRequest request){         juanzengdingdan.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());         juanzengdingdan.setJuanzengshijian(new Date());         juanzengdingdanService.insert(juanzengdingdan);         return R.ok();     }       /**      * 修改      */     @RequestMapping("/update")     public R update(@RequestBody JuanzengdingdanEntity juanzengdingdan, HttpServletRequest request){         //ValidatorUtils.validateEntity(juanzengdingdan);         juanzengdingdanService.updateById(juanzengdingdan);//全部更新         return R.ok();     }          /**      * 删除      */     @RequestMapping("/delete")     public R delete(@RequestBody Long[] ids){         juanzengdingdanService.deleteBatchIds(Arrays.asList(ids));         return R.ok();     }         }  配置拦截:    @Configuration public class InterceptorConfig extends WebMvcConfigurationSupport{          @Bean     public AuthorizationInterceptor getAuthorizationInterceptor() {         return new AuthorizationInterceptor();     }          @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");         super.addInterceptors(registry);     }          /**      * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法      */     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/**")         .addResourceLocations("classpath:/resources/")         .addResourceLocations("classpath:/static/")         .addResourceLocations("classpath:/admin/")         .addResourceLocations("classpath:/front/")         .addResourceLocations("classpath:/public/");         registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/work/");         super.addResourceHandlers(registry);     } }  ———————————————— 版权声明:本文为CSDN博主「java李杨勇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_39709134/article/details/128124580 
  • [技术干货] Spring注解开发-转载
     1、Spring注解开发 1 注解开发定义Bean对象【重点】 目的:xml配置Bean对象有些繁琐,使用注解简化Bean对象的定义  问题导入 问题1:使用什么标签进行Spring注解包扫描?  问题2:@Component注解和@Controller、@Service、@Repository三个衍生注解有什么区别?  1.1 基本使用 【第一步】在applicationContext.xml中开启Spring注解包扫描  <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:context="http://www.springframework.org/schema/context"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">      <!--扫描com.itheima包及其子包下的类中注解-->     <context:component-scan base-package="com.lfs"/> </beans> 【第二步】在类上使用@Component注解定义Bean。  //@Component定义bean @Component("bookDao") public class BookDaoImpl implements BookDao {     public void save() {         System.out.println("book dao save ...");     } } @Component public class BookServiceImpl implements BookService {     private BookDao bookDao;      public void setBookDao(BookDao bookDao) {         this.bookDao = bookDao;     }      public void save() {         System.out.println("book service save ...");         bookDao.save();     } } 补充说明:如果@Component注解没有使用参数指定Bean的名称,那么类名首字母小写就是Bean在IOC容器中的默认名称。例如:BookServiceImpl对象在IOC容器中的名称是bookServiceImpl。  【第三步】在测试类中获取Bean对象  public class AppForAnnotation {     public static void main(String[] args) {         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");         BookDao bookDao = (BookDao) ctx.getBean("bookDao");         System.out.println(bookDao);         //按类型获取bean         BookService bookService = ctx.getBean(BookService.class);         System.out.println(bookService);     } } 注意:在测试类中不要调用bookService的save方法,因为还没有给BookServiceImpl中的bookDao赋值,调用bookService的save方法会出现空指针异常。  1.2 @Component三个衍生注解 说明:加粗的注解为常用注解  Spring提供**@Component**注解的三个衍生注解 @Controller:用于表现层bean定义 @Service:用于业务层bean定义 @Repository:用于数据层bean定义 @Repository("bookDao") public class BookDaoImpl implements BookDao { }  @Service public class BookServiceImpl implements BookService { } 2 纯注解开发模式【重点】 问题导入 问题1:配置类上使用什么注解表示该类是一个配置类?  问题2:配置类上使用什么注解进行Spring注解包扫描?  2.1 纯注解开发模式介绍 Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道 Java类代替Spring核心配置文件 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cGOu29Re-1670647827838)(assets/image-20210803192052811.png)]  @Configuration注解用于设定当前类为配置类 @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式 @ComponentScan({com.itheima.service","com.lfs.dao"}) 1 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象 //加载配置文件初始化容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //加载配置类初始化容器 ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); 2.2 代码演示 【第一步】定义配置类代替配置文件  //声明当前类为Spring配置类 @Configuration //Spring注解扫描,相当于<context:component-scan base-package="com.itheima"/> @ComponentScan("com.itheima") //设置bean扫描路径,多个路径书写为字符串数组格式 //@ComponentScan({"com.itheima.service","com.lfs.dao"}) public class SpringConfig { } 【第二步】在测试类中加载配置类,获取Bean对象并使用  public class AppForAnnotation {     public static void main(String[] args) {         //AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器         ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);         BookDao bookDao = (BookDao) ctx.getBean("bookDao");         System.out.println(bookDao);         //按类型获取bean         BookService bookService = ctx.getBean(BookService.class);         System.out.println(bookService);     } } 3 注解开发Bean作用范围和生命周期管理 问题导入 在类上使用什么注解定义Bean的作用范围?  3.1 bean作用范围注解配置 使用@Scope定义bean作用范围 @Repository @Scope("singleton") public class BookDaoImpl implements BookDao { } 3.2 bean生命周期注解配置 使用@PostConstruct、@PreDestroy定义bean生命周期 @Repository @Scope("singleton") public class BookDaoImpl implements BookDao {     public BookDaoImpl() {         System.out.println("book dao constructor ...");     }     @PostConstruct     public void init(){         System.out.println("book init ...");     }     @PreDestroy     public void destroy(){         System.out.println("book destory ...");     } } 注意:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk9开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。  <dependency>   <groupId>javax.annotation</groupId>   <artifactId>javax.annotation-api</artifactId>   <version>1.3.2</version> </dependency> 4 注解开发依赖注入【重点】 问题导入 问题1:请描述@Autowired注解是如何进行自动装配的?  问题2:请描述@Qualifier注解的作用  4.1 使用@Autowired注解开启自动装配模式(按类型) @Service public class BookServiceImpl implements BookService {     //@Autowired:注入引用类型,自动装配模式,默认按类型装配     @Autowired     private BookDao bookDao;      public void save() {         System.out.println("book service save ...");         bookDao.save();     } } 说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称  注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。  4.2 使用@Qualifier注解指定要装配的bean名称 目的:解决IOC容器中同类型Bean有多个装配哪一个的问题  @Service public class BookServiceImpl implements BookService {     //@Autowired:注入引用类型,自动装配模式,默认按类型装配     @Autowired     //@Qualifier:自动装配bean时按bean名称装配     @Qualifier("bookDao")     private BookDao bookDao;      public void save() {         System.out.println("book service save ...");         bookDao.save();     } } 注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用  4.3 使用@Value实现简单类型注入 @Repository("bookDao") public class BookDaoImpl implements BookDao {     //@Value:注入简单类型(无需提供set方法)     @Value("${name}")     private String name;      public void save() {         System.out.println("book dao save ..." + name);     } } 以上@Value注解中使用${name}从属性文件中读取name值,那么就需要在配置类或者配置文件中加载属性文件。  @Configuration @ComponentScan("com.itheima") //@PropertySource加载properties配置文件 @PropertySource({"classpath:jdbc.properties"}) //{}可以省略不写 public class SpringConfig { } 注意:@PropertySource()中加载多文件请使用数组格式配置,不允许使用通配符*  5 注解开发管理第三方Bean【重点】 问题导入 导入自己定义的配置类有几种方式?  【第一步】单独定义配置类 public class JdbcConfig {     //@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中     @Bean     public DataSource dataSource(){         DruidDataSource ds = new DruidDataSource();         ds.setDriverClassName("com.mysql.jdbc.Driver");         ds.setUrl("jdbc:mysql://localhost:3306/spring_db");         ds.setUsername("root");         ds.setPassword("root");         return ds;     } } 【第二步】将独立的配置类加入核心配置 方式1:@Import注解导入式 @Configuration @ComponentScan("com.itheima") //@Import:导入配置信息 @Import({JdbcConfig.class}) public class SpringConfig { } 方式2:@ComponentScan扫描式 @Configuration @ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"})  //只要com.itheima.config包扫到了就行,三个包可以合并写成com.itheima public class SpringConfig { } 6 注解开发为第三方Bean注入资源【重点】 问题导入 配置类中如何注入简单类型数据,如何注入引用类型数据?  6.1 简单类型依赖注入 public class JdbcConfig {     //1.定义一个方法获得要管理的对象     @Value("com.mysql.jdbc.Driver")     private String driver;     @Value("jdbc:mysql://localhost:3306/spring_db")     private String url;     @Value("root")     private String userName;     @Value("root")     private String password;     //2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中     @Bean     public DataSource dataSource(){         DruidDataSource ds = new DruidDataSource();         ds.setDriverClassName(driver);         ds.setUrl(url);         ds.setUsername(userName);         ds.setPassword(password);         return ds;     } } 说明:如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。  6.2 引用类型依赖注入 //Spring会自动从IOC容器中找到BookDao对象赋值给参数bookDao变量,如果没有就会报错。 @Bean  public DataSource dataSource(BookDao bookDao){     System.out.println(bookDao);     DruidDataSource ds = new DruidDataSource();     ds.setDriverClassName(driver);     ds.setUrl(url);     ds.setUsername(userName);     ds.setPassword(password);     return ds; } 说明:引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象 ———————————————— 版权声明:本文为CSDN博主「楠慧」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_64071654/article/details/128263980 
  • [技术干货] 执行js代码(executeScript)命令使用技巧
    Js中定位操作元素1.使用控制台定位1.右击需要定位的元素,选择Copy选项,再选择Copy JS path的子选项复制上元素定位路径。 2.切换到Console面板,粘贴上前面复制的信息,即可在第二行预览定位元素的情况。 3.这里使用的是CSS的定位方式,如果觉得控制台生成的定位路径不好用,那么可以修改上图中红色字体的定位信息 2.使用XPATH方式定位xpath的通常格式是:document.evaluate('......', document).iterateNext()其中的......表示的是xpath语句xpath语句可以右击操作元素,选择Copy选项,再选择Copy XPath的子选项复制上元素定位路径。 也可以手动书写相关xpath语句,不过最好在Elements面板中通过Ctrl+f组合键唤出搜索栏(下图中红色部分),然后写上自己的xpath语句进行验证,确保定位的元素是唯一的(下图中绿色部分)。使用场景1.执行点击动作先定位操作元素,再执行click方法上图中使用了JS path2.获取元素数量1.通过querySelectorAll方法获取元素数量......使用的是CSS语法return document.querySelectorAll(".......").length在Studio中获取js的返回值需要使用return关键词 2.通过evaluate方法获取元素数量......使用的是XPATH语法return document.evaluate('......', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE).snapshotLength同理在Studio中获取js的返回值需要使用return关键词3.获取元素文本先定位操作元素,再执行获取方法,相关的方法较多,可以逐一尝试// 方法1 document.querySelector("span#content").value // 方法2 document.querySelector("span#content").innerHTML // 方法3 document.querySelector("span#content").innerText // 方法4 document.querySelector("span#content").textContent // 方法5 document.querySelector("span#content").nodeValue对于一个元素,不一定每种方法都可以获取到文本值,选择一个可用的就行 同理在Studio中获取js的返回值需要使用return关键词 更多使用场景欢迎在下面补充注意事项1.iframe框架的选取在拾取的时候,如果js操作的目标元素不在iframe中,那么可以拾取整个页面,但是如果目标元素位于某层iframe中,那么就需要具体拾取到那一层iframe元素上。
  • [技术干货] top.location.href和localtion.href有什么不同
    window.location.href、location.href是本页面跳转 parent.location.href是上一层页面跳转 top.location.href是最外层的页面跳转 top.location.href=”url” 在顶层页面打开url(跳出框架)   self.location.href=”url” 仅在本页面打开url地址   parent.location.href=”url”   在父窗口打开Url地址    this.location.href=”url”    用法和self的用法一致 if (top.location == self.location) 判断当前location 是否为顶层来 禁止frame引用  如果页面当中有自定义的frame的话, 也可以将parent self top换为自定义frame的名称 效果就是在自定义frame窗口打开url地址实际中可能这样使用        if(top !== self){             top.location.href = location.href;         }   禁止frame引用 以下是从网上找到的一个例子,不是很直观, 我加了上面那三行代码, 可以先去掉, 再加上, 看一下效果,就很清楚了 以下是top.htm 代码
总条数:74 到第
上滑加载中