公司简单项目中所遇到的自己不熟悉的问题

132 阅读10分钟

去年大环境不好,加上自己又比较菜(本身不是纯计算机专业,只能算是计算机相关专业,自学了java的一些相关知识),因此在去年的毕业季找工作时没有在大城市找到特别心仪的工作,再加上杭州的工作压力生活压力都很大,自己并不喜欢那种除了工作就没有自己生活的状态,就回家在家附近找了一个互联网相关的公司。公司依附于一个实体企业,算是半互联网半实体的公司,不算大,也不算小。从2月份开始实习(中间回校答辩了半个多月),到现在已经工作了大半年了,期间除了自己学习补充些所缺知识,就是在六月中旬开始跟着师父参与到项目中去。在这个项目中遇到了一些可能非常简单,但是对于当时的我来说有难度的问题,特此记录一下。主要遇到的问题在前端,因为我之前学习的大部分的东西都是后端的,而这边公司并没有做前后端分离(主要还是业务比较简单,大部分的时间都在调前端)。

前端

1.el-dialog、avue-crud点击弹窗外部不会退出窗口的属性设置

要使得点击弹窗外部不会退出窗口,那么就需要在el-dialog的属性中添加:close-on-click-modal="false",如果是想要在avue-crud的外部点击时不会退出窗口,需要添加的属性 dialogClickModal: false,

2.如何在搜索按键上添加图标

在搜索按键上加图标属性icon="el-icon-search",具体页面为外形尺寸及表面要求页面

3.v-if、v-show控制弹窗显隐

v-if 和 v-show的区别:看似效果一样,其实原理不同。v-show隐藏则是为该元素添加css--display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除

4.关于页面在新增/修改弹窗子表页面提交数据时出现污染的情况的解决方法

在对某一个页面进行开发的过程中,子表数据新增流程为点击新增,然后下表输入数据,接着点击提交;修改数据为选中数据后在下表进行修改然后点击提交;删除数据为点击数据前方的选择框然后点击删除。 具体页面如下所示:

1698127229516.png

在刚开始开发的过程中,对子表数据进行操作时,发现会出现删除、修改子表数据后再新增数据时,新数据会在前端对老数据进行污染,导致几条数据的内容完全一样,甚至在后续操作时,会出现全部被同一条数据污染的情况。

后来发现是因为开发时图省事,页面当中没用到这个id属性就给省略了没填,虽然是数据库主键但也是在后端自动生成的。但是如果不在新增子表时设置id为空,会导致在修改子表的过程中,一旦对原表数据修改了以后再进行新增操作,新增的数据id会被之前修改的数据的id污染,导致表单数据传到后端时出现数据丢失的情况,进而使得数据库中的seq字段混乱,影响后续的新增修改操作。(大致的原因是这样的,后来修改完代码后过了好几天才整理,记不清当时的实际情况是不是和下面说的一样了,但是应该差不太多。) 举个例子,之前一次的新增子表的过程中,新增进了3条数据,因此数据库中的seq字段的数据为1、2、3。然后,对子表的内容进行相关修改。首先,选中了第3条数据,对其进行了修改操作,而后又新增了一条数据。由于在新增时并没有将id置空,因此新增时的id被之前修改的数据的id所污染(为最新操作的旧数据的id)。此时数据在前端展示时正常,为四条不一样的数据,而后进行提交确认后,在进入数据库的过程中,只进入了三条数据,即第4条数据的id与第3条数据的id相同,被认为是修改操作,这导致seq字段被更新成了1、2、4,而再次进行新增操作时,前端只读到了3条数据,而新增时的seq通过++maxNo变成了4,就默认新增的1条数据和第3条数据是一条(因为seq一样),使得不管修改还是删除都会使得两条数据的内容变成一致。

5.数据校验问题

float数据类型存在计算精度问题,需要通过其他方法调整,比如先将两个数字变为字符串类型,以小数点 . 为分割符分割小数部分,然后同时乘10的幂,得到整数后加减再除乘的数,就可以得到精度较高的计算结果。

float的计算精度问题是计算机二进制表示小数所无法完美解决的。

6.新增页面输入框必填项在失焦后的message信息如何消除

写页面时,出现一个问题就是在弹窗中的必填项一开始没填写的时候会弹出红色的警示文字提醒填写,后续填写过后发现这个警示文字没有消除。后来了解到必填的规则中,trigger从trigger:"blur"改为trigger:["change","blur"]就可以输入时点击框外失焦后弹出message提示,填入数据后提示依旧存在的问题。

7.前端的数据映射问题(不一定要使用插槽)

之前碰到如果数据库中存的数据为0或1而前端需要将其进行映射成文字,是用了以前项目的前端代码中的插槽来实现的,后来发现可以在该字段下添加如下代码块:

formatter: function (row) {
              switch (row.valid) {
                case "0":
                  return "未生效";
                case "1":
                  return "已生效";
                default:
                  return "未知";
              }
            }

在进行修改时,弹窗中的select框直接读取了数据库中存的数据,如果数据是数字,则需要进行映射为文字,需要对编辑功能进行如下修改:

得到的效果和访问字典一致,区别在于一个是在字典中进行了映射,访问的是字典中的映射值,另一个是在前端进行了映射。

8.如何在前端监控中查看后端传回的数据

console.log("data", JSON.stringify(data)); 前台打印(可以看出来我之前完全不懂前端的任何操作,连debugger都是师父教的。。。。。)

9.时间范围如何返回后端

时间范围dateRange返回后端出现两个

另:后端要么DTO中添加一个List

要么直接在对象中添加timeStart、timeEnd两个属性,在mapper中进行映射

10.关于弹窗中switch开关选择合格后在主表中显示不合格的问题

问题描述:开发时将前端弹窗的switch开关映射的值根据后端数据库的定义设置为合格:不合格(2:1),但在提交弹窗过后出现原本应该设为合格的值在前端主表显示为不合格。

问题解决:switch开关的值必须是0 和 1 ,不能为1和2,因为switch开关判断的是true or false,碰到如此情况建议设为下拉选择。

11.关于数据在前端页面写死时,想要在页面载入时主表数据自动选中第一行

开发某个页面时,由于最开始没有后端,只需要前端页面的展示,因此在前端将数据写死,想直接在页面载入后主表数据自动选中第一行。但是问题是按照以前的代码进行开发时发现,并不能实现这一功能。

1698130168143.png

问题解决:首先要清楚,在载入页面时,前端展现页面是先将页面渲染完成后再载入数据,期间时间很短但是是有一个延迟的。当数据直接在前端写死时,会导致数据在页面渲染完成前就已经载入,从而导致默认第一行数据选中的情况无法实现,setCurrentRow()函数会报错;这时需要添加一个时间延迟,模拟向服务器请求数据的过程。

setTimeout(() => {
  if (this.mainData.length > 0) {
    this.$refs.mainTable.setCurrentRow(this.mainData[0]);
  }
}, 200)

13.在表格的每行的某一字段中设置switch

容器中在crud里加入插槽,重点关注@change方法,该方法中可以加参数,例如row

<template slot-scope="{ row }" slot="valid">
  <el-switch
    v-model="row.valid"
    active-color="#13ce66"
    inactive-color="#ff4949"
    active-value="1"
    inactive-value="0"
    @change="isValid(row)"
    >
  </el-switch>
</template>

其中active-value的相关属性表示生效时的状态,还可以添加active-text属性写明生效时的文本

在显示字段中加入slot:true,使得插槽位置确定

{
            label: "生效状态",
            prop: "valid",
            display: false,
            width: 200,
            // formatter: (val) => {
            //   let valid = val.valid;
            //   switch (valid) {
            //     case "0":
            //       return '<b style="color:#F56C6C">已失效</b>';
            //     case "1":
            //       return '<b style="color:#67C23A">已生效</b>';
            //   }
            // },
            slot: true,
          },

在methods方法中

//生效状态修改
    isValid(row) {
      this.loading = true;
      let params = {
        id: row.id,
        valid: row.valid,
      };
      setAuditSample(params).then(() => {
        this.onLoad(this.page);
      });
      this.loading = false;
    },

后端

1.后端数据校验,杜绝某一字段重复的数据进入数据库(业务要求)

该方法是对数据的后台校验方法,即校验表中是否存在与输入数据id不同、流水号和品名相同的数据,红框那行是为了方便更新方法调用,如果没有这行的话,在更新过程中不更新流水号和品名调用就会报错(因为本身表中就存在了流水号、品名相同的数据),因此只有当id不同且满足上述条件才拦截。红框内容要注意,调用ne方法中必须要加Fun.toStr(),否则该语句不起效,依旧会直接打入数据库。在后端数据库也要添加品名和流水号两个字段联合的唯一索引,作为最后一道保险。

2.关于前端日期数据传不回后端的问题

问题描述:前端的日期字段已设为如下格式

后端数据库的字段格式也为date,实体类的字段格式也为Date,但是仍出现Warning,并且数据传输过程中前端报Bad Request

问题解决:后端报的Warning是

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of java.sql.Time, problem: java.lang.IllegalArgumentException; nested exception is com.fasterxml.jackson.databind.exc.Val...

其异常原因是这个异常的原因是无法将JSON数据中的一个字段转换成Java对象中对应的类型(java.sql.Time)。具体地,报错信息显示传入了非法参数。

具体解决方法是在Java类中使用@JsonFormat注解指定时间格式:

@ApiModelProperty(value = "标准发布日期")
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd")
private Date stdReleaseDate;

问题的实质是前后端交互时的数据传输格式的问题。