欢迎来到林龙星的博客

返回顶部

结对作业二

这个作业属于哪个课程 2021春软件工程实践|W班(福州大学)
这个作业要求在哪里 结对作业二
结对学号 221801204 、 221801239
这个作业的目标 记录PSP表格 论文查询网站的编码实现
其他参考文献 vue.js elementUI、Echarts

目录:

  1. Github项目地址
  2. PSP表格
  3. 云服务器地址
  4. 成品展示
  5. 结对讨论过程
  6. 设计实现过程
  7. 关键代码
  8. 心路历程
  9. 队友评价

1.Github项目地址

Github项目地址

代码规范

2.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
• Estimate • 估计这个任务需要多少时间 2850 3345
Development 开发
• Analysis • 需求分析 (包括学习新技术) 1200 1080
• Design Spec • 生成设计文档 60 90
• Design Review • 设计复审 60 45
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 30 30
• Design • 具体设计 60 45
• Coding • 具体编码 1200 1400
• Code Review • 代码复审 120 180
• Test • 测试(自我测试,修改代码,提交修改) 240 300
Reporting 报告
• Test Repor • 测试报告 60 50
• Size Measurement • 计算工作量 60 50
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 30 30
合计 2850 3330

3. 云服务器地址

由于能力有限以及时间有限,我们没有将项目部署到服务器上

4. 成品展示

1.用户没用登录,无法进入其他页面。用户如果没有账号,就点击立即注册。用户输入信息后点击注册按钮,如果用户名没有重复就注册成功,页面跳转至登录界面。

登录和注册界面

2.论文列表界面

论文列表总览和搜索功能

论文列表总览

论文搜索功能

其他一些不完善的功能

5. 结对讨论过程

1.对问题的讨论

在刚刚拿到题目之后,我们就马上讨论用什么语言、什么框架来完成这次作业。我们虽然在之前有一些Web基础,但是开发这样的Web项目要学习不少新技术。所以我们先确定了前端用Vue框架来实现,后端用Spring Boot来实现。确定了前后端的框架之后,我们就分工开始学习技术。

2.遇到的困难

1.虽然上学期学习过Web的一些框架,之前也学过java,但是这次决定使用的Vue+Spring boot这两个框架我们都基本上都不会用,所以都要学习新知识。

2.前端网页分为不同部分,不同部件之间的传值比较困难,比如论文列表中的查看论文,需要父组件将数据传给子组件然后进行渲染。在写到这部分时进度卡住了。

3.后端困难:之前对于后端其实只有一个很浅的理解,停留在简单的编写java程序之上,很少使用框架,而后端框架素有配置地狱一说,在配置springboot和mybatis的那些文件的时候花了我很多时间,并且因为配置不过关引发了很多bug,改了半天。

4.前后端接口写好了之后,怎么交互也是个问题,在测试交互的过程中我们遇到了跨域问题、找不到网页等一系列问题。

3.解决方案

1.通过在b站搜索教程、百度上查找知识、求助有经验的同学学会了vue和spring boot的使用

2.通过阅读百度上一些论坛的专业回答,找到了问题的根源并且解决了父子组件、兄弟组件之间的传值问题

3.反复跟着网上的视频敲配置代码,bug改到后面看到提示就知道是哪里出问题了...

4.多进行交流沟通,一起查询资料来解决交互出现的问题。

4.讨论照片



6. 设计实现过程

1.首页

用户可以在首页进行登录和注册,用户只有登录了之后才可以查看论文,登录之后可以点击右上角退出登录按钮退出。登录和注册需要将表单传到后端验证,然后后端查询数据库,用户存在就且密码正确就可以登录。

2.论文列表

用户可以在论文列表中查看全部论文,还可以通过论文题目、关键词、论文发表时间等进行模糊搜索。在进入论文列表界面时,前端请求后端,将所有论文读取到前端,然后前端实现论文分页以及将查询的论文结果展示给用户。
论文列表中的摘要只显示部分,点击查看按钮可以查看论文详细信息,点击相应论文的删除可以将论文删除(并不影响数据库)。论文列表的分页在前端通过过滤器filter来实现

3.关键词图谱

用户可以在这个界面查看Top10的关键词词云。词云的字体大小体现出了不同关键词之间数量关系。用户点击词云,可以在页面下方查看与关键词有关的论文。前端利用Echart的词云组件来实现,后端处理完的数据返回给前端。

4.热度走势图

用户可以在这个界面查看三大峰会的论文数量趋势对比。通过柱状图的形式展现出来。实现方式为:前端利用Echart来绘制柱状图,后端处理数据后传给前端进行页面渲染。

7. 关键代码

前端登录界面表单以及请求后端的代码:

//登录按钮对应的函数
doLogin() {
      this.$axios.get('http://localhost:8083/login', {
        params: {
          username: this.username,
          password: this.password
        }
      }, {headers: {'Content-Type': 'application/x-www-form-urlencoded format'}})
        .then(res => {
          if (res.data === 1) {
            this.state.status = 1;
            this.state.index = 1;

            bus.$emit('sendStatus', this.state);
            this.$router.replace('/Search');
          } else if (res.data === -1) {
            alert("用户未注册,请注册后再登录")
          }
        })
        .catch(failResponse => {
        })

    },

前端请求后端的代码:

//注册按钮对应的函数
	  submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$axios
            .get('http://localhost:8083/register', {
              params: {
                username: this.ruleForm.user,
                password: this.ruleForm.pass
              }
            }, {headers: {'Content-Type': 'application/x-www-form-urlencoded format'}})
            .then(res => {
              if (res.data === 1) {
                this.$message.success("注册成功")
                this.$router.replace({path: '/Login'})
              } else {
                this.$message.error("注册失败,用户名已被注册!")
              }

            }).catch(failResponse => {
          })

        } else {
          this.$message.error("信息填写有误!请重新填写")
          return false;
        }
      });
    },

登录界面的点击滑动的页面。

<template>
  <div class="out">
    <button class="btn blt" @click="cLeft"></button>
    <button class="btn mid" @click="cMid"></button>
    <button class="btn rit" @click="cRi"></button>
    <img class="pic" v-bind:src="picArr[num]" alt=""/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 0,
      picArr: [
        require("../assets/images/first.png"),
        require("../assets/images/second.png"),
        require("../assets/images/third.png"),
      ],
    };
  },
  methods: {
    cLeft() {
      this.num = 0;
    },
    cRi() {
      this.num = 2;
    },
    cMid() {
      this.num = 1;
    },
  },
};

加载数据库的论文数据到前端

query() {
      this.$axios
        .get('http://localhost:8083/getPapers', {})
        .then(res => {
          this.listArray = res.data
          this.searchArray = this.listArray
          this.showArray = this.listArray
          this.divideList()
        })
        .catch(failResponse => {
        })
    },

根据搜索框旁边的下拉框来决定按什么方式搜索:

	getList() {
      if (this.content !== "") {
        if (this.value === "论文名") {
          this.searchArray = this.listArray.filter((item, index) =>
            item.title.includes(this.content));
        } else if (this.value === "关键词") {
          this.searchArray = this.listArray.filter((item, index) =>
            item.keyword.indexOf(this.content) > -1);

        } else if (this.value === "发布时间") {
          this.searchArray = this.listArray.filter((item, index) =>
            item.publication_year === this.content);

        } else {
          this.searchArray = this.listArray
        }
      }
    },
	
	

对论文数据进行分页展示

	divideList() {
      this.showArray = this.searchArray.filter(
        (item, index) =>
          index < (this.pageNum + 1) * this.pageSize &&
          index >= this.pageSize * this.pageNum
      );
    },
	
	nextPage() {
      if ((this.pageNum + 1) * this.pageSize > this.searchArray.length) {
        alert("已经到最后一页了!");
      } else {
        this.pageNum++;
        this.divideList();
      }
    },
    formerPage() {
      if (this.pageNum > 0) {
        this.pageNum--;
        this.divideList();
      } else {
        alert("已经在第一页了!");
      }
    }
  },
  

用词云来直观展示关键词的数量多少:


  initChart() {
    let chart
    if (chart != null) {
      chart.dispose()
    }
    chart = echarts.init(document.getElementById("myWordCloud"));

    chart.setOption({
      title: {
        text: "Top10热词词云图",
        x: "center"
      },
      series: [
        {
          type: "wordCloud",
          gridSize: 10,
          sizeRange: [14, 50],
          rotationRange: [0, 0],
          textStyle: {
            normal: {
              color: function () {
                return (
                  "rgb(" +
                  Math.round(Math.random() * 255) +
                  ", " +
                  Math.round(Math.random() * 255) +
                  ", " +
                  Math.round(Math.random() * 255) +
                  ")"
                );
              }
            }
          },
          left: "center",
          top: "center",
          right: null,
          bottom: null,
          width: "200%",
          height: "200%",
          //数据
          data: this.wordData
        }
      ]
    })
    chart.on('click', (params) => {
      this.query()
    });

用柱状图来体现趋势(未完全实现)

drawLine() {
      // 基于准备好的dom,初始化echarts实例
      const myChart = echarts.init(document.getElementById('myChart'))
      // 绘制图表
      myChart.setOption({
        title: {
          text: '',
          //textAlign: 'center',
          //padding: 0
        },
        xAxis: {
          data: this.data1,
          inverse: true,
          animationDuration: 600,
          animationDurationUpdate: 600,
        },
        yAxis: {max: 'dataMax'},
        series: [
          {
            name: '',
            type: 'bar',
            data: this.data2,
            realtimeSort: true,
            label: {
              show: true,
              position: 'top',
              valueAnimation: true
            }
          }
        ],
        legend: {
          show: true,
          data: ['ECCV']
        },
        color: ['#1685ff'],
        animationDuration: 0,
        animationDurationUpdate: 3000,
        animationEasing: 'linear',
        animationEasingUpdate: 'linear'

      })
    },

后端登录部分mybatis xml代码

        select * from xjbs.user where username = #{username};
    </select>

    <select id = "getPassword"  parameterType = "string" resultType = "string">
        select password from xjbs.user where username = #{username};

后端注册部分mybatis xml代码

<mapper namespace="com.mapper.RegisterMapper">
    <select id = "getUserByName" parameterType = "string" resultType = "_int">
        select count(*) from xjbs.user where username = #{username};
    </select>

    <insert id = "addUser" parameterType = "User">
        insert into xjbs.user (username, password) VALUES (#{username},#{password});
    </insert>
</mapper>

后端论文有关部分mybatis xml代码

<mapper namespace="com.mapper.PaperMapper">
<select id="getTopWords" resultType="Keyword">
    select keyword,count from xjbs.keyword_count ORDER BY count DESC limit 0,10;
</select>

    <select id="getPapers" resultType="Paper">
        select * from xjbs.paper;
    </select>

    <select id="getMeetingInfo" resultType="meetinginfo">
        select magazine,count(*) as number,publication_year from xjbs.paper group by magazine,publication_year ORDER BY publication_year;
    </select>
</mapper>

8. 心路历程及收获

HWY的感受:

一个字,累!这次做了Springboot的后端,最大的感受就是,后端的编码、编写逻辑其实不是很难,只占据了编程总时间中较少的一部分,真正麻烦的是各种框架的配置,“配置地狱”不是开玩笑的,尽管框架有整合,但是Springboot和Mybatis的配置我还是弄了很久,然后最多的时间是改bug,从一开始爆个bug毫无头绪到后面能熟练根据异常定位出错位置,我的debug能力肉眼可见地提高了。第一次尝试前后端分离写项目也是一种很奇妙的体验。

LLX的感受和收获:

有了第一次的结对经历,并且第一次已经完成了原型设计,我心里对第二次结对作业的难度有了大致的认识。这次作业对于我本人来说难度不小,一开始我是觉得做趋势分析那块内容会比前面复杂的多,但是后来我发现Vue框架的功能可太完整了,各种组件库任你选择。
而且前端开发可以看到页面的样子。我从什么都不会到搭建出一个个页面,心中莫名有种自豪感。但是编写页面的布局让我有些时候让人头疼。做前端让我感受到了一种甲方的感觉,一直在向后端提出需求。这次作业我收获不少,首先是巩固了Web的知识;其次,我还
了解了一些springboot的语法,可以理解一些简单的语句。这对我以后的后端之路有一定帮助。

9.队友评价

HWY ==> LLX

龙星做事一如既往地认真了高效率,结对作业开始后那几天每次去他们宿舍他一定是在进行vue的学习,这令我也感到责任重大,不敢拖拉,尽早开始学习Springboot的知识,在接口的参数和返回值等方面上我们交流许多,这让我们双方编写代码都省去了很多不必要的麻烦,编程过程中出现了很多的bug,但我们大量讨论解决,这使我们双方的debug能力都有了很大的提升。

LLX ==> HWY

我自认为后端的工作是非常复杂的,但是伟源一开始就主动承担了后端的工作。他在我们讨论完分工后就开始学习相关知识。这次后端最复杂的就是论文数据的处理,伟源也花了好几天才解决,效率挺高的。在实现设计的过程中,我提出的需求他也基本都实现了,第二次结对作业也结束了,我从中学到了不少知识。

posted @ 2021-03-31 22:43  221801239_林龙星  阅读(134)  评论(14编辑  收藏  举报