2020软件工程第二次结对作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2020/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277
GitHub 仓库地址 https://github.com/Chenyang-1024/031802201-031802203
这个作业的目标 学习前端知识,web 页面实现学术家族树
学号 031802201
031802203

队友分工:

学号 姓名 分工
031802203 陈洋 思路及网页的实现和单元测试等
031802201 畅继军 博客园编写和文本的解析等

一、PSP表格:

PSP2.1 Personal Software Process Stages 预估耗时(h/小时) 实际耗时(h/小时)
Planning 计划 1 1
Estimate 估计这个任务需要多少时间 1 1
Development 开发 4.5 5
Analysis 需求分析 (包括学习新技术) 10 18
Design Spec 生成设计文档 2 2
Design Review 设计复审 2 1.5
Coding Standard 代码规范 (为目前的开发制定合适的规范) 2 2
Design 具体设计 2 3.5
Coding 具体编码 10 18
Code Review 代码复审 1 2
Test 测试(自我测试,修改代码,提交修改) 5 4
Reporting 报告 2 3
Test Repor 测试报告 1 1.5
Size Measurement 计算工作量 1 1.5
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 2 1
合计 46.5 65

二、解题思路描述与设计实现说明

解题思路

在读完题目,1.0想法是 文本框->输入文本->读取文本->文本解析 ,然后怎么根据有效信息生成树状结构没有头绪,后来百度了一下,jstree 可以用 json 数据生成树状结构,虽然树形丑了点,但好歹有方向了, 文本解析->有效信息按照一定格式存入数组->数组转化为 json 字符串->利用 jstree 生成树。初步流程图和数据流图如下:

流程图

数据流图

三、关键节点的算法及代码:

第一个 html 核心代码

// JS 数组转化为 JSON 字符串
        function tojson (arr) {
            if (!arr.length) {
                return null;
            }
            var i = 0,
                len = arr.length,
                array = [];
            for (; i<len; i++) {
                array.push({"id" : arr[i][0], "parent" : arr[i][1], "text" : arr[i][0]});
            }
            return JSON.stringify(array);
        };

        // 文本分割及有效信息的提取
        function textResolve () {
            var T = $('#textarea').val();
            var root = "#",
                jarr = [],
                skill = [];
            // var myJSON = [];
            var text = T.split('\n\n\n');
            // console.log(text);
            for (let i = 0; i < text.length; i++) {
                let Supervisor = "",
                    year = "",
                    name = "";
                let lines = text[i].split('\n');
                for (let j = 0; j < lines.length; j++) {
                    // jarr[i] = [];
                    if (lines[j]) {
                        if (lines[j].includes("导师:")) {
                            let temp = lines[j].split(":");
                            Supervisor = temp[1];
                            let Stext = Supervisor; 
                            jarr.push([Supervisor, root, Stext]);
                            // console.log([Supervisor, root, Stext]);
                        }
                        else if (lines[j].includes("生:")) {
                            let temp = lines[j].split(":");
                            year = temp[0];
                            var Syear = temp[0];
                            jarr.push([year, Supervisor, Syear]);
                            // console.log([year, Supervisor, Syear]);
                            let sname = temp[1].split("、");
                            for (let k = 0; k < sname.length; k++) {
                                var t = sname[k],
                                    Sname = sname[k];
                                jarr.push([t, year, Sname]);
                                // console.log([t, year, Sname]);
                            }
                            
                        }
                        else if (lines[j].includes(":")) {
                            let temp = lines[j].split(":");
                            name = temp[0];
                            let skill = temp[1].split("、");
                            for (let k = 0; k < skill.length; k++) {
                                var t = skill[k],
                                    Sskill = skill[k];
                                jarr.push([t, name, Sskill]);
                                // console.log([t, name, Sskill]);
                            }
                        }
                    }
                }
                // console.log(jarr);
            }
            myJSON = tojson(jarr);
            // console.log(myJSON);

            // 将 JSON 字符串传输到另一个 web 页面,并链接跳转
            localStorage.setItem("jsonString", myJSON);
            window.location.href = "TreeWeb.html?jsonString=" + escape(myJSON);
        };

第二个 html 核心代码

<!-- 接收传输的数据 -->
<script>
        // 获取url中的参数
        var request={
            getUrlParam:function(name){
                var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
                var r = window.location.search.substr(1).match(reg); //匹配目标参数
                if (r != null) return unescape(r[2]);
                return null; //返回参数值
            }
        }

        // 接收 InputWeb.html 传过来的 JSON 字符串
        var temp = request.getUrlParam("jsonString");
        var jsondata = JSON.parse(unescape(temp));
        JSON.parse(localStorage.getItem("jsonString"));
           
</script>

关于上传文件,只做到了读取内容,其他的时间不太够。。

<script>
        var inputElement = document.getElementById("files");
        inputElement.addEventListener("change", handleFiles, false);
        function handleFiles() {
            var selectedFile = document.getElementById("files").files[0];//获取读取的File对象
            // var name = selectedFile.name;//读取选中文件的文件名
            // var size = selectedFile.size;//读取选中文件的大小
            // console.log("文件名:"+name+"大小:"+size);
            var reader = new FileReader();//这里是核心!!!读取操作就是由它完成的。
            reader.readAsText(selectedFile, 'utf-8');//读取文件的内容
            reader.onload = function () {
                var docText = this.result;
                // console.log(docText);
                // 实现一半。。。
            };           
        }
    </script>

五、附加特点与设计展示:

右键菜单(展示的只是默认的菜单,可修改)

  • 展示

    结点重命名后,依旧可以搜索得到


    结点可拖拽

  • 相关代码

// 生成树状结构
$('#maketree').jstree({
           "core" : {
                'themes' : {
                    'stripes' : true
                },
                'check_callback' : true,      // 不写则默认为 false ,若为 false 则不允许任何对树的操作
                'data' : jsondata
                // 'icon' : // 这个是结点的图标
            },
            // 配件 dnd 允许拖拽,配件 contextmenu 右键菜单,配件 search 允许搜索结点
            "plugins" : ["dnd", "contextmenu" , "search"]
        });

搜索结点(简陋。。)

  • 展示
  • 相关代码
<form id="s">
        <input type="search" id="q" />
        <button type="submit">Search</button>
</form>
<script>
      $("#s").submit(function(e) {
            e.preventDefault();
            $("#maketree").jstree(true).search($("#q").val());
      });
</script>

六、单元测试及实现成果展示:

  • 采用的测试框架是 mocha
  • 新手教程(以我自己的步骤描述的,具体有不对的地方欢迎交流指正)
    • 首先安装 node.js ,我去官网下载结果慢的要死,没办法就另外搜了一下,用了这个下载地址 http://nodejs.cn/download/
    • 下载完安装,点点点完安装 node.js 以后,控制台输入 npm install --gobal mocha 以安装 mocha
    • 在根目录下创建你自己的 test 文件夹,具体参考 https://www.liaoxuefeng.com/wiki/1022910821149312/1101756368943712
    • 对于 package.json ,上面教程并不是很清楚,我就搜了一下,我用的方法是:在 test 文件夹所在目录下,输入 npm init ,然后它会一步步提醒,自己根据自己的情况按照提醒配置,完成后它就帮你配置好了 package.json(emmmmm讲得好像不太清楚)具体如下图
    • 所在根目录下,输入 mocha,开始单元测试
  • 相关测试代码
没时间写那个测试代码了,先白盒测试一下。。。
  • 白盒测试
    • 正常情况

    • 技能缺失,可见点击刘六并不会展开技能

    • 技能人员不存在,陈一不存在,搜索陈一技能字节跳动,可见搜索不到

    • 删除结点天一以后,可见再搜索不到该结点

七、GitHub 签入记录截图:

八、仓库目录和使用说明:

主要文件目录

  ├── README.md
  ├── css/
  │    ├─ inputweb.css
  │    └─ bootstrap.min.css
  ├── html/
  │    ├── InputWeb.html
  │    └── TreeWeb.html
  ├── image/
  │     └── background.jpg
  ├── jstree/
  │     ├── jstree.js
  │     ├── jstree.min.js
  │     └── themes/
  └── js/
      ├── bootstrap.min.js  
      ├── bootstrap.js
      └── jquery.js

使用说明

打开InputWeb 页面文本框输入文本,点击创建,页面将自动跳转到 TreeWeb 页面,双击结点或者点击前面的小三角可进行结点的缩放,搜索框输入相关关键词,若该树包含该结点,将该结点显示。

九、困难及解决办法:

- 构思部分

  • 问题
    • 如何按关键词解析出有效信息?
    • 如何将有效信息创建成树状结构?
  • 解决方法
    • JS 的 split() 方法可以将字符串切割成数组,虽然该方法很常见很容易想到,但因为是第一次做前端任务,还是查了半天才找到并采用该方法解决。
    • 使用 jQuery 的插件 jstree ,将数据转成 JSON 字符串后,传给 jstree ,调用 $('').jstree() ,生成树状结构。

- 编程部分

  • 问题
    • JS 使用不熟悉,不知道如何将数据传到另一个页面
    • 创建按钮点击以后没反应,该按钮有打 a 标签,但是就是不会跳转
  • 解决方法
    • 百度
    • 不会跳转后来发现是因为我放在了 form 表单里面,运行顺序是表单先提交了,就造成了即使打了 a 标签也不跳转的问题,后来就把表单结构撤了

- 单元测试

  • 问题
    • mocha 的配置问题
    • 用于进行测试的 js 文件没写好,只能先进行了白盒测试
  • 解决方法
    • mocha 的配置多看看教程,package.json 的配置可以使用 npm init自动配置

十、感想与收获

  • 学会了初步使用HTML+css+JavaScript的初步使用,jQuery 插件 jstree 的入门使用,通过本次结对编程作业,提升了我们对于前端实现的初步认知。
    10.评价队友:
    --队友陈洋:完美的中国好队友,学习能力和解决问题的能力极强,本次作业的编码部分主要由他来完成。在整个实践过程中积极进取,他能够实时快速处理许多问题。他是妥妥的优秀!
    --自评:我作为他的队友,我完全就是个菜鸡,太能拖后腿了,辜负了这么好的队友。
posted @ 2020-10-12 13:47  dihua  阅读(101)  评论(0编辑  收藏