前言
整个业务流程主要分为两大块:分别是数据上传与获取展示。
1. 数据上传
数据上传例图这方面主要有四种类型数据需要处理。
在文件类型方面有两种,分别是基础表单数据与文件数据;在上传次数方面也有两种,分别是单次与组合(多次)。
文件类型与上传次数两两组合便有四种,从易到难的实现方式分别是:
- 表单数据单次上传(基础信息、联系方式、关键词等);
- 表单数据组合上传(教育经历、工作经历、荣誉证书)
- 文件数据单次上传(用户头像);
- 文件数据组合上传(证书证明)。
处理这些数据的大体思路是先用前端交互vue框架创建一个v1对象,将数据保存在v1对象里,封装成各个部分后提交给后端,后端进行非空判断以及其他处理,将有效数据存入数据库。
下面将具体说说笔者对这四种文件数据上传方式的设计。
1.1 基础信息单次上传
基础信息单次上传首先是第一、五、六页的基础信息单次上传。
这部分单单拎出来说比较简单,但将整体考虑进来就有个值得思考的地方,那就是如何把后续填写的信息将用户基础信息绑定起来;
换句话说如果基础数据与后续一起提交给服务器,在数据库同时生成多个表,那后续数据怎么找到基础数据的用户并与之绑定。
这里有多种解决方案,比如将所有数据存在一张表,但这样会对组合文件不友好。亦或者在每张表设置一个uid,所有数据一起绑定。
基于后者这种思路,我的解决方案是用户在前端提交基础信息后马上反馈给后端并存入数据库,并获得主键编号uid存入session域中并反馈给前端,前端各个部分数据可以增添一个uid属性,在提交阶段一并交给后端,最后在数据库通过外键方式进行绑定。
这就是为什么至少需要填写姓名才能进行后续操作的原因(为了获取用户唯一编号uid)。而联系方式、关键词与特长信息的提交就没有这么复杂了。
1.2 表单数据组合上传
表单数据组合上传接着就是第三、四、(七)页的表单数据组合上传。
这部分也比较简单,在前端用Arrary数组将各条数据储存起来,在提交时遍历数组,逐个提交即可。
1.3 头像图片单次上传
头像图片单次上传需要掉头发的地方是第二页的头像图片单次上传功能。
一开始笔者想用boostrap原生的〈input type="file"〉
组件实现,可原生组件样式实在是太丑了,于是找到了boostrap-fileinput
插件。
这款插件网上的中文资料很少,笔者尝试根据别人的博客复制了几个案例,无一成功。只能上英文官网查阅,Ctrl CV官网案例就成功了。
使用fileinput插件首先需要引入依赖文件,这里需要注意文件次序;引入后需要对fileinput初始化,即自己创建一个js文件;最后标签内还要加上class="file"
。
在查阅官方文档的过程中,笔者发现一个有趣的小知识。boostrap4及以后开始对icon图标收费,不再免费提供。
而fileinput插件需要用到这些小图标,这该怎么办呢?万能的网友给出了答案:将3.3.x版本的icon图标复制过来,随后在css文件里增加相应样式即可。
这里又有一个小细节,boostrap的icon文件夹要与css文件夹放在同一个目录下,笔者在调整文件夹目录时又出了些小问题。以上都是笔者踩过的坑。
1.4 PDF文件多次上传
PDF文件多次上传由于笔者对fileinput还是不太熟悉,在处理文件上传业务时有相应策略。
其中就有上传文件与提交表单数据不同步问题,也就是说文件上传请求优先于表单请求。对于单文件(头像)上传,先发送/upload/mask
请求将文件重命名后保存在相应目录下,获取文件全路径后存入到session域中。
后续提交表单时对session域中的相应key做非空判断与赋值,与联系方式一同存入数据库。
多文件上传的复杂之处就在于如何将文件与文件信息对应绑定(文件数<=信息数)。这里需要考虑的情况有很多种组合,比如这个用户可能全不提交文件,另一个用户可能全提交文件,另另一个用户可能部分提交文件。
这里笔者的设计是给honorBean
里添加了两个int属性haveFile
(初始0)与fileCode
(初始-1,fileCode有一层含义),分别对应是否有文件与文件顺序。
由于文件上传请求优先于表单提交请求,笔者先将上传的文件存入对应文件夹中,用ArrayList数组保存文件所在目录,再存入session域中。在前端的处理时如果用户选了需要提交文件,则给haveFile
赋1,将fileCode
自增后赋值;否则haveFile
为0,fileCode不做处理。
这样,在后端处理表单请求时先根据haveCode是否为1判断是否有文件,有则从ArrayList中获取下标为fileCode的路径值,该路径保存下的文件与该表单信息填写的文件数据绑定,一同存入数据库。在haveFile
为1的情况下,fileCode
的另一层含义是:它是该文件在ArrayList中的下标。
2. 数据展示
接着就是第三、四、(七)页的表单数据组合上传。
数据展示部分就比较简单了,大体思路就是前端发送/info/{uid}
请求,后端接到请求后根据uid查询用户的八大信息,做些处理(如计算年龄等),封装到result
的data
里,最后返回给前端。
前端解析后端传来的JSON字符串,以按需加载为原则(用户填了什么信息,就展示什么信息),先根据自定义的HTTP状态码是否为204进行错误判定,判定为204则进入错误页面。反之进入正确页面,在正确页面里根据是否有对应值进行页面展示与否,例如:如果解析出联系方式contact为空,则不显示“联系我”页面。
上述部分在个人主页系列文章《前端 | 个人主页项目HTML页面解析》已经详细说明,本篇将讲讲 左显示框与主页、关于我、经历、荣誉、联系我、留言以及错误页,共七大页面的具体设计。
2.1 左显示框与主页
左边为左显示框,右为主页这部分是最简单的,由于至少需要输入姓名才能生成个人主页,“主页”是必须显示的。
左边部分的显示框为固定页面,从上到下依次为用户头像、用户姓名、可跳转的联系方式、Email me以及联系笔者。
这几个部分也是按需加载等,用户如果没有填写对应联系方式则不会显示对应小图标。如果用户上传了头像则为用户上传头像,如果没有则根据用户所填写的性别进行默认配置。
2.2 关于我
“关于我”子页面“关于我”页面主要做的是基础信息展示,从上到下从左到右依次为:个人简介、基本信息、基本联系方式与擅长领域。
个人简介与基础信息按7:5的比例固定占位。
由于如果用户未填个人简介会导致画面中间部分空洞,因此会填写笔者默认添加的句子。
基本信息与擅长领域部分按需加载,年龄是后端根据生日计算而来。擅长领域用到了list的遍历。
2.3 经历
“经历”子页面“经历部分”主要由三部分组成,分别是教育经历、工作经历与稳定关键字。
其中左边的教育工作经历与右边的关键字按7: 5的比例固定排列。
教育工作经历也是按需加载,其中竖线左边为时间与教育工作单位,时间的“至”字会根据用户填写的时间按需加载;右边为职位与职位说明。
右边关键字部分会用空格将用户填写的内容分割,遍历展示。同理,因为是固定排列,当用户填了关键字而没填经历时会显示笔者默认句子;当经历和关键字都没填时,“经历”页面不会显示。
2.4 荣誉
“荣誉”子页面“荣誉子页面”用来展示用户填写的一些证书,分为三类:荣誉证书、职业资格与专业技术。
同样左右边比例为7: 5,同样按需加载,同样当用户只填写荣誉证书时会展示笔者默认句子。不同之处在于这部分可以跳转至用户上传的文件,即上图蓝色字体部分,作为证明材料展示。
2.5 联系我
“联系我”子页面“联系我”页面用来展示用户的联系方式,也是按需加载。
这里笔者对联系方式做了个分类,第一列为最常用的电话和邮箱,第二列为腾讯类,第三列为可跳转类。可跳转类顾名思义,能根据点击联系方块下方的蓝色字体进行页面跳转,而其他除了邮箱只能复制黏贴,后续如有发现更便捷的方法会进行改进。
2.6 留言
“留言”子页面留言页可是最有意思的页面了,用来发布与展示留言.。
考虑到可能会有用户会担心别人留言语言攻击,因此这部分可以在填写资料时手动开启关闭。留言必须要填写内容才能成功,没有写明留言者则为(无名侠)。留言采用半匿名式,即可以匿名也可以不匿名,用户不知道是谁留的言。哎,就是玩,玩的就是惊喜!玩的就是刺激(bushi 留言块最上面为最新留言,最后一条为笔者留言。
在设计留言时笔者考虑过用户可以删除留言等操作,但这需要一个类似“密码”的功能才能实现,不然谁都可以进行删除操作,只有“密码”才能证明是用户本身。这点以后再加上吧。
除此之外还考虑过对留言进行回复功能,实现起来比较简单,大概就是在数据库的留言表里添加一个“回复”字段,然后在前端页面进行非空校验与显示。不过笔者做个人主页的初衷只是给自己使用,定位还是类似简历那样的存在,不便加太多社交元素进去。
2.7 错误页
“错误”子页面“错误页”就是对错误信息进行说明。
这里笔者只针对一种错误进行了处理,即查询用户不存在的情况。出现这种错误信息大概是因为网址不正确,具体说就是/info/{uid}
中的uid在数据库中找不到。这时可以查看网址是否输入正确或重新生成。
如果发现其他错误还请联系笔者,感激不尽!
网友评论