第二天的项目需求
需求分析
管理后台,检查项管理
1、新增检查项
主要还是在前端进行业务处理,Vue的新增会弹出添加窗口
- 除了前端的窗口自带的rules校验规则,还需要进行表单校验this.$refs['表格名称'].validate((valid)=>{ 参数是布尔值}),校验通过异步处理,不通过
- 异步进行请求,发到后端的请求要进行try..catch 处理 这个处理会接收到后端任何位置出现的异常
1 @RequestMapping("/add") 2 public Result add(@RequestBody CheckItem checkItem) { 3 try { 4 checkItemService.add(checkItem); 5 return new Result(true, MessageConstant.ADD_CHECKITEM_SUCCESS); 6 } catch (Exception e) { 7 e.printStackTrace(); 8 return new Result(false, MessageConstant.ADD_CHECKITEM_FAIL); 9 } 10 }
- 前端接收到数据要进行判断,通过message这个来提示用户,成功与失败(这里是因为后端封装了一个Result对象,很巧妙)
1 handleAdd: function () { 2 /*console.log(this.formData);*/ 3 //在进行添加的时候先对,表单进行校验,防止因为不填写数据,直接保存的空数据 4 this.$refs['dataAddForm'].validate((valid) => { 5 if (valid) { 6 //隐藏添加的窗口 7 this.dialogFormVisible = false; 8 //异步将数据传递 9 axios.post("/checkitem/add.do", this.formData).then((res) => { 10 11 if (res.data.flag) { 12 this.findPage(); 13 /*this.$message({ 14 message: res.data.message, 15 type: 'success' 16 })*/ 17 this.$message.success(res.data.message) 18 } else {//执行失败 19 this.$message.error(res.data.message); 20 } 21 }) 22 } else { 23 //校验不通过 24 this.$message.error("数据校验不通过,请重新输入"); 25 26 return false; 27 } 28 }); 29 30 }
注意:弹出的添加框需要将校验规则清楚,否则会一直保留 this.$refs['表'].clearValidate() 可以是重置
2、分页及查看所有
- 前端封装分页参数,查询条件 异步传递给后端
- 后端分页插件处理
1 /** 2 * 查询所有的查询项 3 * @param queryPageBean 4 * @return 5 */ 6 public PageResult findPage(QueryPageBean queryPageBean) { 7 Integer currentPage = queryPageBean.getCurrentPage(); 8 Integer pageSize = queryPageBean.getPageSize(); 9 String queryString = queryPageBean.getQueryString(); 10 11 PageHelper.startPage(currentPage,pageSize); 12 Page<CheckItem> page = checkItemDao.selectByCondition(queryString); 13 return new PageResult(page.getTotal(),page.getResult()); 14 }
3、删除检查项
- 点击删除提示用户,删除操作是危险的。用户确认后调用ajax
1 // 删除 2 handleDelete(row) { 3 this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', { 4 confirmButtonText: '确定', 5 cancelButtonText: '取消', 6 type: 'warning' 7 }).then(() => { 8 axios.get("/checkitem/delete.do?id="+ row.id).then((res) => { 9 if (res.data.flag) { 10 this.$message.success(res.data.message) 11 } else { 12 this.$message.error(res.data.message); 13 } 14 }).catch((r) => { //axios对象请求的catch, 网络请求不是2xx 15 this.showMessage(r); 16 }).finally(()=>{ 17 this.findPage(); 18 }) 19 }).catch(() => { 20 /*this.$message({ 21 type: 'info', 22 message: '已取消删除' 23 });*/ 24 this.$message.info("已取消删除") 25 }); 26 }
- 后端接收到数据,因为该表是与其他表进行关联的,所以删除是删除不了的,需要判断是否与其他表进行了关联,如果关联了,就不删除,没有关联就删除
1 /** 2 * 通过id删除检查项,删除之前需要判断是否有中间关联表 3 * @param id 4 */ 5 public void delete(Integer id) { 6 int account = checkItemDao.findCheckItemCountById(id); 7 if (account<=0){ 8 checkItemDao.delete(id); 9 } 10 }
4、编辑检查项
- 前端点击编辑按钮,弹出编辑框,此处需要回显数据,这里有3中方式,各有利弊
1 // 弹出编辑窗口 2 handleUpdate(row) { 3 //弹出编辑窗口 4 this.dialogFormVisible4Edit = true; 5 //将编辑editFormData中的数据清空 6 this.editFormData = {}; 7 //判断是否开启编辑窗口 8 this.openEdit = true; 9 10 //将数据进行深度拷贝,监听器会触发 watch 11 this.editFormData = this.deepClone(row); 12 //将数据进行深度拷贝,监听器会触发 watch 13 this.deepCloneObj = this.deepClone(row); 14 //这里可以不写 15 this.formDataChange = false; 16 }, 17 18 watch: {//监听器 当指定的数据发生改变时 记录 第一次不记录 19 editFormData: { 20 deep: true,//深度监听 当为复杂的对象时,比如user 当username发生改变时,也能监听到 21 handler: function (newVal, oldVal) { 22 if (this.openEdit) { 23 this.openEdit = false; 24 return; 25 } 26 this.formDataChange = !this.isObjectValueEqual(newVal, this.deepCloneObj); 27 } 28 } 29 } 30 31 //深拷贝 32 deepClone(obj) { 33 /* let target = {}; 34 for (let key in obj) { 35 if (Object.prototype.hasOwnProperty.call(obj, key)) { 36 if (typeof obj[key] === 'object') { 37 target[key] = this.deepClone(obj[key]); 38 } else { 39 target[key] = obj[key]; 40 } 41 } 42 } 43 return target; 44 */ 45 if (obj === null) return null; 46 if (typeof obj != 'object') return obj; 47 if (obj.constructor === Date) return new Date(obj); 48 let target = new obj.constructor(); 49 for (let key in obj) { 50 if (obj.hasOwnProperty(key)) { 51 let val = obj[key]; 52 target[key] = typeof val === 'object' ? arguments.callee(val) : val; 53 } 54 } 55 return target; 56 /* return JSON.parse(JSON.stringify(obj));*/ 57 //这样的意思是,将obj进行序列化,保存到磁盘上,ran后通过反序列化,再获取到该对象,该对象将是个新对象,并不会影响到原来的 58 // 这样写也是有问题的, 59 // 1.如果有时间对象,时间对象会被转换成一个字符串 60 //2.如果有正则表达式,或者error对象,序列化会为空 61 //3.如果对象中有循环引用无法实现正常拷贝 62 } 63 64 //判断对象值是否相等 65 isObjectValueEqual(x, y) { 66 var i, l, leftChain, rightChain; 67 68 function compare2Objects(x, y) { 69 var p; 70 71 // remember that NaN === NaN returns false 72 // and isNaN(undefined) returns true 73 if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') { 74 return true; 75 } 76 77 // Compare primitives and functions. 78 // Check if both arguments link to the same object. 79 // Especially useful on the step where we compare prototypes 80 if (x === y) { 81 return true; 82 } 83 84 // Works in case when functions are created in constructor. 85 // Comparing dates is a common scenario. Another built-ins? 86 // We can even handle functions passed across iframes 87 if ((typeof x === 'function' && typeof y === 'function') || 88 (x instanceof Date && y instanceof Date) || 89 (x instanceof RegExp && y instanceof RegExp) || 90 (x instanceof String && y instanceof String) || 91 (x instanceof Number && y instanceof Number)) { 92 return x.toString() === y.toString(); 93 } 94 95 // At last checking prototypes as good as we can 96 if (!(x instanceof Object && y instanceof Object)) { 97 return false; 98 } 99 100 if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) { 101 return false; 102 } 103 104 if (x.constructor !== y.constructor) { 105 return false; 106 } 107 108 if (x.prototype !== y.prototype) { 109 return false; 110 } 111 112 // Check for infinitive linking loops 113 if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) { 114 return false; 115 } 116 117 // Quick checking of one object being a subset of another. 118 // todo: cache the structure of arguments[0] for performance 119 for (p in y) { 120 if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { 121 return false; 122 } else if (typeof y[p] !== typeof x[p]) { 123 return false; 124 } 125 } 126 127 for (p in x) { 128 if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) { 129 return false; 130 } else if (typeof y[p] !== typeof x[p]) { 131 return false; 132 } 133 134 switch (typeof (x[p])) { 135 case 'object': 136 case 'function': 137 138 leftChain.push(x); 139 rightChain.push(y); 140 141 if (!compare2Objects(x[p], y[p])) { 142 return false; 143 } 144 145 leftChain.pop(); 146 rightChain.pop(); 147 break; 148 149 default: 150 if (x[p] !== y[p]) { 151 return false; 152 } 153 break; 154 } 155 } 156 157 return true; 158 } 159 160 if (arguments.length < 1) { 161 return true; //Die silently? Don't know how to handle such case, please help... 162 // throw "Need two or more arguments to compare"; 163 } 164 165 for (i = 1, l = arguments.length; i < l; i++) { 166 167 leftChain = []; //Todo: this can be cached 168 rightChain = []; 169 170 if (!compare2Objects(arguments[0], arguments[i])) { 171 return false; 172 } 173 } 174 175 return true; 176 } 177 }
异步回显数据,对数据库进行操作,数据库脆弱,减少操作较好 深度拷贝,虽然减少 了对数据库的操作,但是确会对服务器的性能产生消耗
- 后端进行修改