结对作业二

作业的基本信息
这个作业属于哪个课程 2021春软件工程实践S班
这个作业要求在哪里 结对作业二
结对信息 221801206毛依婷&221801216汪碧桢
这个作业的目标 熟练使用github以及了解web页面的编码与设计

一、Github仓库地址

1.1 Github仓库地址

点我前往仓库

1.2 代码规范

代码规范

二、PSP表格

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

三、成品展示

3.1 成品功能完成情况一览

功能点 是否完成 备注
展示待导入的论文
可以选择论文导入到论文列表
展示论文列表
对论文列表进行查看和删除操作
输入查找条件对论文列表进行精确查询和模糊查询
展示查询后的结果
根据论文广场中的论文信息,提取top10个热门领域或热门研究方向
根据论文广场中的论文信息,形成关键词列表,点击某个关键词可展现相关的论文
以动图的形式呈现多年间、不同顶会的热词呈现热度走势对比 x 尝试把echart表导入yii,但是没有学会,退而求次以表格形式展示不同年份的top10关键词
部署到云服务器上 x

3.2 成品视频展示

 

四、结对讨论过程描述

4.1 技术和框架的决定

 项目开始初期,双方结合给出的需求查阅了相关资料,最后因为之前有用Yii2.0框架和Apache开发Web实践的经历,对Yii2.0框架有一定的了解,并发现Yii2.0与其他框架相比,有如下几个优点:
- 和其他PHP框架相比,Yii实现了MVC(Model-View-Controller)设计模式并基于该模式组织代码。
- Yii代码简单优雅。
- Yii是一个全栈框架,对关系型和NoSQL数据库都提供了查询生成器和ActiveRecord;多层缓存支持,等等。
- Yii代码简介,高性能始终是Yii的首要目标之一。
于是决定用Yii2.0框架来开发此次项目。

4.2 开发过程

 决定了基于yii2.0框架的advanced模板进行论文网站的开发方向后,我们观看魏曦Yii2.0框架教学视频进行学习,同时写代码进行功能的实现。
 在开发过程中遇到了很多问题,比如写的页面点击跳转后404了、页尾出现了奇怪的符号、想导入一篇论文到论文列表结果把整页的论文都导到论文列表了······。期间还经历了github实战,连着几天1点多才睡,我们做的是网站,掉的是头发。但是幸好,功夫不负掉发有心人,在多次修改代码、不断运行、上网寻找解决方法、多次观看教学视频后这些问题都解决了。

4.3 讨论合影

线下讨论
线上截图1
线上截图2
线上截图3

五、设计实现过程

5.1 数据库和数据表设计

数据表 作用 字段
papersearchlist 存放论文广场论文数据 id,storeID,displayTitle,abstract,year,pubdate,link,keyword
paperstore 存放论文列表论文数据 storeID,displayTitle,abstract,year,pubdate,link,keyword
keywords 存放论文广场论文关键词 keywordname,keyWordCount
eccvkey_16 存放ECCV2016年论文的关键词 wordname,wordcount
eccvkey_18 存放ECCV2018年论文的关键词 wordname,wordcount
eccvkey_20 存放ECCV2020年论文的关键词 wordname,wordcount
eccv 生成Eccv(model),EccvController(controller) id

5.2 页面设计

页面设计

5.3 具体功能设计

功能点 设计思路
展示待导入的论文 调用Gii生成的Papersearchlist模型方法,在加载论文广场页面时通过获取actionIndex返回的dataProvider以列表形式展示
选择要导入的论文到论文列表 在paperstore的控制器方法中添加actionAddpaper,用户选择导入后把当前要导入的论文id作为参数传递给actionAddpaper
展示论文列表 使用GridView::Widget,获取paperstore控制器方法的actionIndex传回的dataProvider展示论文列表
对论文列表进行查看和删除操作 ActionColumn
输入查找条件对论文列表进行精确查询和模糊查询 filterModel自动搜索机制
展示查询后的结果 filterModel
根据论文广场中的论文信息,提取top10个热门领域或热门研究方向 在加载数据的时候把关键词按年份存入对应数据表
根据论文广场中的论文信息,形成关键词列表,点击某个关键词可展现相关的论文 本来是想参照魏曦Yii2.0框架教学视频中的标签云实现,但是关键词太多了比较困难,最后选择以列表形式在论文广场页面展示关键词
以动图的形式呈现多年间、不同顶会的热词呈现热度走势对比 yii导入echart表

六、代码说明

  • 论文广场(papersearchlist)部分代码说明

1.数据导入
加载论文广场页面时,会执行PapersearchlistController中的actionIndex,该方法的代码如下:

    public function actionIndex()
    {
        $searchModel = new PapersearchlistSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
            //$c=2941;
        	//$filepath="F:\jsonData\ECCV41";
            //get_json($filepath,$c);
            //$filename="F:\\eccvjson\\eccv20\\21";
            //$tname="eccvkey_20";
            //get_ek($filename,$tname);
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
           
    }

 其中注释部分中的get_json($filename,$c)是我们用于解析本地json数据到数据表中的自定义函数,该函数解析json过程中还会对关键词进行存储。由于文件量过大,一次性解析3000+的json文件会进行频繁的读取文件、连接数据库操作,这就导致我们初次读取数据的时候报错,对此我们的解决方法是将文件分成多份,少量多次读入。
 get_json中用到的update_key和add_key用于处理json数据中的关键词,如果keywords表中已有该关键词,则关键词次数+1,否则添加该关键词到keywords表中,这两个函数写在common/keyfunc.php中,代码很简单也很好理解,如果要查看,可以前往我们的 Github仓库查看,这里就不加展示了。
 get_ek函数则是用于处理不同年份的论文数据,代码同样可以在我们的Github仓库中查看。

	$count+=1;
	
    $jsonfile = $filepath."/".$filename;                 
    $json_data=file_get_contents($jsonfile);
    $json_d=json_decode($json_data,true);
	$tocpid="";
	$keyarr = $json_d['关键词']; 
	$topicid=implode(',',$keyarr);//implode keywords
	//import paper to papersearchlist table
	Yii::$app->db->createCommand()->insert('papersearchlist', [
			'id'=>$count,
			'storeID' => $count,
			'displayTitle' => $json_d['论文名称'],
			'abstract'=>$json_d['摘要'],
			'year'=>$json_d['会议和年份'],
			'pubdate'=>$json_d['发布时间'],
			'link'=>$json_d['原文链接'],
			'keyword'=>$topicid,
			])->execute();
	//import keys to keywords table
	$length=count($keyarr);
	for($x=0;$x<$length;$x++)
	{   $kstr='select * from keywords where keywordname=\''.$keyarr[$x].'\'';
		$k_exist=Yii::$app->db->createCommand($kstr)->queryAll();
		if($k_exist!=NULL)
		{
			update_key($keyarr[$x],1);
		}
		else
		{
			add_key($keyarr[$x]);
		}
	}

2.列表展示
使用ListView进行展示:

    <?= ListView::widget([
          'id'=>'papersearchlist',
          'dataProvider'=>$dataProvider,
          'itemView'=>'_listitem',//子视图,显示一篇文章的标题等内容.

           'layout'=>'{items} {pager}',
           'pager'=>[
                   'maxButtonCount'=>10,
                          'nextPageLabel'=>Yii::t('app','下一页'),
                          'prevPageLabel'=>Yii::t('app','上一页'),
                    ],
           ])?>

其中子视图listitem代码如下:

<div class="paper">
	<div class="test">
        <div class="title" >
        <br>
        <span  style="font-weight:bold" aria-hidden="true"></span>
        <em>
                <p class="glyphicon glyphicon-time" aria-hidden="true"></p>
                <em><?= '发布时间:'.$model->pubdate."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";?></em>
                <p><?= '论文名称:'.Html::encode($model->displayTitle)?></p>    
                <?=Html::a('导入到论文列表',['/paperstore/addpaper','_id'=>$model->storeID],['onclick'=>'return confirm("是否确认导入到列表?")'])?>
                <br>
        </em><hr>
        </div>
	</div>	
</div>

3.按标题搜索
获取文本框输入内容,作为参数传递给PapersearchlistSearch的搜索,并重新加载论文广场页面完成展示内容的刷新,代码如下:

        <div class="col-md-3">
            <div class="searchbox">
                <ul class="list-group">
                <li class="list-group-item">
                <span class="glyphicon glyphicon-search" aria-hidden="true"></span> 查找文章(
                    <?= Papersearchlist::find()->count();?>
                    )
                </li>
                <li class="list-group-item">
                    <form class="form-inline" action="index.php?r=papersearchlist/index" id="w0" method="get">
                        <div class="form-group">
                            <input type="text" class="form-control" name="PapersearchlistSearch[displayTitle]" id="w0input" placeholder="按标题">
                        </div>
                      <button type="submit" class="btn btn-default">搜索</button>
                    </form>
                  </li>
                </ul>	
      
            </div>

3.关键词搜索
和searchbox相似但有不同,具体不同在展示上,除了和searchbox相似的传递参数、调用方法、刷新页面外,还使用了keyWordWidget进行关键词列表的展示,代码如下:

//papersearchlist.php
  <div class="keywordType">
    <ul class="list-group">
      <li class="list-group-item">
        <span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>  关键词<br>(仅展示出现次数>=10的关键词)
      </li>
      <li class="list-group-item">
		<?= keyWordWidget::widget();?>
	</li>
    </ul>
</div> 


//keyWordWidget.php
<?php
namespace frontend\components;

use yii\base\Widget;
use yii\helpers\Html;
use common\models\Keywords;
use Yii;

class keyWordWidget extends Widget
{
	
	public function init()
	{
		parent::init();
	}
	
	public function run()
	{
		$keyString='';
		$keys = Keywords::find()->all();
		foreach ($keys as $key)
		{
			$url = Yii::$app->urlManager->createUrl(['papersearchlist/index','PapersearchlistSearch[keyword]'=>$key->keywordname]);
			$keyString .= '<a href="'.$url.'">'
			.' <h2 style="margin:10px 0;panding:0;"><span class="label label-info" style="background:#00e0e0;'
			.'display:inline-block;width:100%;">'
			.$key->keywordname.'</span></h2'.'></a>';
			//echo $typeString;
		}
		return $keyString;
		
	}	
}
?>

4.导入到论文列表
起初的想法:写一个自定义函数,放一个按钮,点击就运行函数。想象很美好,现实很折磨,尝试这样做之后发生了什么呢?点击了一次按钮,不断的提交参数导致整页的论文都被导到了列表,这可怎么办,不断查找后找到了解决方法。只要在paperstore中增加一个页面,并在控制器中添加相应的页面响应方法actionAddpaper,该方法接收从论文广场传来的论文id参数,在列表中搜索后返回表示是否存在的added参数,页面根据added参数展示不同的导入结果。代码如下:

//papersearchlist _listitem
<?=Html::a('导入到论文列表',['/paperstore/addpaper','_id'=>$model->storeID],['onclick'=>'return confirm("是否确认导入到列表?")'])?>

//addpaper.php
        <div class="row">
                <ol class="breadcrumb">
                <li><a href="<?= Yii::$app->homeUrl;?>">首页</a></li>
                <li>导入结果</li>
                </ol>
                <br><br>
                <?php if($added){?>
                    <h4>导入成功!是否前去论文列表查看?</h4>
                <?php  }else{?>
                    <h4>导入失败,论文列表中已有该篇论文。</h4> 
                <?php }?>
                <br><br><hr>
                <?=Html::a('回到论文广场',['/papersearchlist/index'])."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"?>
                <?=Html::a('查看论文列表',['index'])?>
        </div>

//actionAddpaper(&_id):
   public function actionAddpaper($_id){
        $added=1;
        $searchstr='select * from paperstore where storeID=\''.$_id.'\'';
        $_exist=Yii::$app->db->createCommand($searchstr)->queryAll();
        if(!($_exist))
        {     
            $resstr='select * from papersearchlist where storeID=\''.$_id.'\'';
            $res=Yii::$app->db->createCommand($resstr)->queryOne();
            $_title=$res['displayTitle'];
            $_abstract=$res['abstract'];
            $_y=$res['year'];
            $_pub=$res['pubdate'];
            $_link=$res['link'];
            $_key=$res['keyword'];

            Yii::$app->db->createCommand()->insert('paperstore', [
            'storeID' => $_id,
            'displayTitle' => $_title,
            'abstract'=>$_abstract,
            'year'=>$_y,
            'pubdate'=>$_pub,
            'link'=>$_link,
            'keyword'=>$_key,
            ])->execute();

            $this->added=1;
        }
        else{
            $this->added=0;           
        }
        return $this->render('addpaper',['added'=>$this->added]);

    }

  • 论文列表(paperstore)部分代码说明

这部分实现起来最简单,通过使用Gii生成模型和Search模型和控制器方法,再使用GridView进行展示就完事了,在教学视频中也有和该页面相似的页面教学。

   <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'options' => [
            'style'=>'overflow: auto; word-wrap: normal;'
        ],
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'storeID',
            'displayTitle:ntext',
        //    'abstract:ntext',
            'year:ntext',
         //   'pubdate:ntext',
            'keyword:ntext',
            // 'link:ntext',
            ['class' => 'yii\grid\ActionColumn','header'=>'Operation','template' => '{view}  {delete}',], 
    ]]); 
    ?> 
  • ECCV热词统计(eccv)部分代码说明

在尝试n次echart无果后,选择以表格方式展示ECCV。经历了导入论文列表功能的折磨后,展示TOP10关键词功能就轻松了起来。和导入功能相似,建立ECCV页面,控制器中修改actionIndex方法,通过导航栏传入的参数_y获取不同数据表的数据并通过GridView::Widget展示。代码如下:

//nav(layouts/main.php):
    ['label' => 'ECCV热词统计', 'options'=>['class'=>'ycn-banner'], 'items'=>[
        ['label' => '<i class="key1-tag"></i> ECCV2016', 'url' => ['/eccv/index','_y'=>'1'],'encode'=>false],
        ['label' => '<i class="key2-tag"></i> ECCV2018', 'url' => ['/eccv/index','_y'=>'2'],'encode'=>false],
        ['label' => '<i class="key2-tag"></i> ECCV2020', 'url' => ['/eccv/index','_y'=>'3'],'encode'=>false],
    ]]

//actionIndex($_y):
   public function actionIndex($_y)
    {
        if($_y==1)
        {   
            $dataProvider = new SqlDataProvider([
                'sql' => 'select * from eccvkey_16 order by wordcount desc',
                'params' => [
                    ':limit'=>10,
                ],
                'totalCount' => 10,
                'sort' => [ ],
                'pagination' => [
                    'pageSize' => 10,
                ],
            ]);
               
        }
        else{
            if($_y==2)
           {   
            $dataProvider = new SqlDataProvider([
                'sql' => 'select * from eccvkey_18 order by wordcount desc',
                'params' => [
                    ':limit'=>10,
                ],
                'totalCount' => 10,
                'sort' => [ ],
                'pagination' => [
                    'pageSize' => 10,
                ],
            ]);               
            }
            else{
                $dataProvider = new SqlDataProvider([
                    'sql' => 'select * from eccvkey_20 order by wordcount desc',
                    'params' => [
                        ':limit'=>10,
                    ],
                    'totalCount' => 10,
                    'sort' => [ ],
                    'pagination' => [
                        'pageSize' => 10,
                    ],
                ]);
            }
        }

        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);      
    }

//GridView(index.php):
       <?= GridView::widget([
           'dataProvider' => $dataProvider,
           'columns' => [
               'wordname',
               'wordcount',
    ]]); 
   ?>

七、心路历程与收获

221801206毛依婷:
 本以为用yii2.0框架实现很简单,然后我掉的头发狠狠的打了我的脸。在逐步实现功能的过程中我的心情变化be like:
看了视频,觉得这样理论上好像可以(自信)→尝试失败(疑惑)→怎么不可以了,再看一遍视频,难道是这样(疑惑)→再次尝试失败(呆滞)→上网搜索→方法很多,逐个尝试(麻木)→成了(狂喜)
 收获就是对yii2.0框架的认识+++++,并且对php语言也有了更多了解。
 本次作业的感受:知识不够怎么办,学!

221801216汪碧桢:
 此次刚看到题目,里面推荐的技术很多都不了解,所以刚开始会比较迷茫,因为要学习新的技术,而且要在摸索中写代码。后来经过讨论确定框架后,也是渐渐摸索(一边看视频一边debug),更加深刻地学习了一门新技术,当功能点完成时,会很有成就感,而且以前不了解前后端如何接起来,这次比较了解了,是新的收获呢。而且以前对于结对编程没什么概念,但这次结对编程让我感觉到通过随时复审和交流,程序设计和debug都更快了。

八、评价结对队友

221801206毛依婷 to 221801216汪碧桢:
 虽然小汪同学说大多数代码是我打的,但这些代码的背后也有小汪同学不少的功劳,比如解析json数据并导入到数据表就是小汪同学完成的,数据导的很完美。本次作业多亏了小汪同学的陪伴,我才有坚持下去的意志。如果这是个人作业我肯定就因为麻烦草草了事了,但结对的方式让我用认真的态度对待并完成了它。

221801216汪碧桢 to 221801206毛依婷:
 小毛是一个很有责任感又相对耐心的人(对比我),这次项目绝大多数都是她在努力顽强地debug,不管是页面数据的传递或是功能方法的编写,都是她熬夜打代码debug不断尝试解决出来的,真的很respect。

posted @ 2021-03-31 17:55  MEating  阅读(139)  评论(14编辑  收藏  举报