分类

课内:
不限
类型:
不限 毕业设计 课程设计 小学期 大作业
汇编语言 C语言 C++ JAVA C# JSP PYTHON PHP
数据结构与算法 操作系统 编译原理 数据库 计算机网络 软件工程 VC++程序设计
游戏 PC程序 APP 网站 其他
评分:
不限 10 9 8 7 6 5 4 3 2 1
年份:
不限 2018 2019

资源列表

  • 基于JSP和MYSQL数据库实现的在线考试系统

    1 系统概述1.1 功能模块教学部需要考试系统,该考试系统需要完成如下功能:

    考试系统只针对于Java课程,题目全部为单项选择,共10题
    学生注册、登录
    后台管理员功能:题库管理、录入试卷、修改试卷
    试卷生成
    考试
    试卷评分
    分数查看


    1.2 软件环境
    操作系统:WindowsXP、Windows2000 Server,windows server 2003,Linux
    数据库系统:MYSQL5.1及以上版本
    CASE工具: Rational Rose、Visio
    开发工具: Eclipse
    编程语言:Java
    支撑软件:JDK1.5及以上版本、Tomcat,JBoss或其他应用服务器

    1.3 基本设计概念和处理流程
    1.4 系统总体结构
    2 系统功能
    2.1 详细功能2.1.1 注册用户信息



    字段名
    字段类型
    说明




    用户名
    字符串
    用户名,用于登陆,用户唯一标识


    密码
    字符串
    密码要求加密存放


    姓名
    字符串
    用户真实姓名


    性别
    字符串



    电话
    字符串
    可以写多个联系方式


    邮件地址
    字符串



    备注
    字符串



    用户进入首页,如果没有注册,点击注册可以进入注册页面,注册完后,进入登陆页面,并要求自己将注册用户名填入登陆界面的用户名框内。如果已存在用户名,则返回注册界面,提示用户名已存在。

    2.1.2 用户登陆用户进入登陆页面,输入用户密码,点击登陆。登陆成功进入用户首页,登陆失败,返回登陆页面。
    2.1.3 用户密码修改用户在自己界面菜单上点击密码修改,进入密码修改界面,输入原密码,输入新密码和新确认密码,检验成功后进行修改。

    2.1.4. 用户管理
    2.1.4.1 用户查询查询条件:用户名,姓名
    查询结果:显示用户名称、用户名、性别,电话、邮件、备注
    2.1.4.2 用户删除勾选用户后,弹出确认对话框,用户确定后删除,可以进行多条删除,删除用户将删除用户所有考试信息。删除失败将进入失败页面并提示信息。
    2.1.5 题库管理题库全是选择题,选择项数至少两项,至多五项。题库题目名称不能重复。
    题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号



    选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属题目ID
    数字
    题目的ID号,在建表时设计



    2.1.5.1 题目添加管理员添加题目到题库。从查询界面点击添加按钮,进入编辑界面,填写题目名称,动态添加选项,至少两项,至多五项,点击添加完成。
    2.1.5.2 题目删除在查询界面中,勾选查询结果,进行删除,删除失败将进入失败界面。不能删除已被试卷引用的题库
    2.1.5.3 题目修改在查询界面,点击要修改的记录,进入编辑界面,修改改相关信息,进行保存。
    2.1.5.4 题目查询查询条件:题目名称
    查询结果:题目列表及选项(展现方式自定)
    2.1.6 试卷管理试卷



    字段名
    字段数据类型
    说明




    试卷名称
    字符型



    考试开始时间
    日期型



    考试结束时间
    日期型



    试卷题目



    字段名
    字段类型
    说明




    题目名称
    字符串



    答案
    字符
    A,B,C,D,E这样的单字母编号


    所属试卷ID
    数字
    试卷的ID号



    试卷选项



    字段名
    字段类型
    说明




    选项编号
    字符
    A,B,C,D这样的编号


    选项名称
    字符串
    选项名


    所属试卷题目ID
    数字
    题目的ID号,在建表时设计



    2.1.6.1 试卷录入从查询界面,点击添加按钮进入添加试卷界面,填写题目信息,从题库的题目列表中选择题目。(此处具体方式可以灵活设计),点击添加完成。
    校验:要求考试结束时间必须大于考试开始时间,考试开始时间必须大于当前(服务器)系统时间30分钟以上。
    2.1.6.2 删除试卷试卷删除时,已考过或正在考的试卷不能删除。(已考过即是在考试结果中能查到该试卷,正在考检查系统服务器时间是否在考试区间内)
    在查询界面,勾选查询结果,点击删除,用户确认删除后,删除所选试卷。删除失败将进入失败界面并提示信息.
    2.1.6.3 修改试卷从查询界面,点击某条记录进入编辑界面。修改相关信息。已考过或正在考的试卷不能再修改。
    2.1.6.4 试卷查询查询条件:试卷名称
    查询结果:试卷名称,考试开始时间,考试结束时间
    2.1.7 考试结果查询


    字段名
    字段类型
    说明




    考试试卷
    字符串



    考生姓名
    字符串



    考试分数
    字符串



    管理员选择考试试卷,点击查询,显示该考试的结果,按分数自动排名,默认查询最近一次已结束的考试排名。
    显示结果:姓名、用户名、分数、排名
    2.1.8 管理员登陆参考用户登陆
    2.1.9 管理员密码修改参考用户密码修改
    2.1.10 考试用户登陆后,在考试列表中,能够查询到当前时间可以考试的试卷。选择试卷进入考试。在时间(取系统服务器时间)未到前,用户如果做完题目可以点击提交按钮提交。在考试时间到之后,系统将自动提交用户试卷。已考过的试卷不会出现在试卷查询列表。考试结束系统计算分数,自动跳转到分数查看界面。

    2.1.11 分数查看在菜单上点击分数查看,显示用户考试科目,日期及分数。
    查询结果:考试科目,日期,分数。
    3 评论 112 下载 2018-11-05 21:01:47 下载需要5点积分
  • 基于JAVA和MYSQL数据库的大学生社团管理系统

    1 概述1.1 设计目标
    熟悉数据库设计基本原理
    熟悉数据库设计基本过程及方法
    掌握数据库设计基本技巧及设计工具
    掌握数据库设计相应的 SQL 语句操作
    增强数据库建模能力和分析能力
    通过大学生社团系统的实现增强特定领域的编程能力

    1.2 设计要求对大学生社团管理系统进行数据库设计,要包括以下内容:

    分析大学生社团管理应包含的实体、实体包含的属性。分析实体之间的关系,如强制参与、可选参与等,实体数应不低于 6 个
    对实体中相应的数据项给出详细的数据字典描述,语义要合理
    以 PowerDesigner 为建模工具,对数据库进行逻辑设计,图中含实体、属性、多样性、实体联系、主键、外键等
    设计的关系模式需进行规范化处理,每个关系模式应能达到 3NF
    针对选定的系统设计不低于 20 个事务,涉及到检索和更新等,事务要合理
    绘制事务图,使用路径指示 ER 模型支持的用户事务
    根据逻辑设计原则(多样性),转化为相应数据表,并标明主键、外键等
    相应的事务要求用 SQL 语言实现,并用到触发器、完整性约束、存储过程、视图、索引等技术和方法,以及查询、插入和修改等数据操作
    应用自己熟悉的高级程序设计语言,实现系统主要功能

    2 需求分析2.1 系统需求和必要性分析通过对各大高校实地的调查可知,一般高校的学生社团信息管理主要是依据纸质和
    手工作业处理,人工的对大量会员的基本资料进行档案式管理,此种处理方式数据量大,管理模式和方法滞后,存放时间不能长久和数据更新速度慢。
    考虑现存的情况,建立一个系统化的学生社团管理系统是十分必要的。比如由原来的档案式保存会员信息变为将信息存入数据库中进行系统管理;利用海报或者板报宣传社团活动变为直接在网上发布社团活动的时间和地点等;文件式申请社团的创建变为规范格式的网上申请,提交表格,再由系统管理员审核、批准;此系统还可以方便会员对社团动态进行查看、为社团评价打分、进行留言和会员之间的交流等。
    2.2 系统描述学生社团管理信息系统是一个操作简单、使用方便的系统。它的建立既是为了更加高效、规范地实现对社团动态进行管理,又是为了方便用户及时查看社团信息,保证信息的时效性和高效性。
    此学生社团管理信息系统应达到以下七个目标:

    系统采用人机对话操作模式,界面设计简单大方,操作简单,效率高,安全性能高,同时便于维护和管理
    在登录界面,可根据界面中的权限来选择不同用户可以对系统调用不同的功能
    迅速发布社团动态,对社团活动申请、会费管理、校外社团合作进行规范化和程序化管理
    能够大量存储社团会员信息,方便会员查看社团信息、留言、进行评分等操作
    社团管理员可以通过后台登录,对社团信息、活动、留言板和注册的用户进行查看和管理,同时对用户加入社团的申请进行审核
    通过查询、添加、修改等操作,对社团信息、用户资料、财务管理等模块进行管理
    系统管理员可以修改个人密码,可以对社团的各项活动进行管理和监督

    系统采用 MySQL 数据库,开发语言为 Java,数据库的存储容量足够大,而且比较稳定,能够较长时间保存数据。
    2.3 系统功能需求分析根据系统描述可以初步总结出系统的基本功能。
    学生社团管理系统开发任务树

    数据库设计阶段任务

    大学生社团系统模块图

    2.4 数据字典2.4.1 数据项描述格式为:数据项描述={数据项名,数据项含义说明,数据类型,长度}

    系统管理用户

    编号描述={编号,系统用户的编号,int,11}
    登录用户名描述={登陆用户名,系统用户的用户名,varchar,25}
    登录密码描述={登录密码,系统用户登陆系统的密码,varchar,10}

    大学学校学生

    学生编号描述={学生编号,大学生的学号编号,int,11}
    专业描述={专业,学生的专业班级,varchar,32}
    地址描述={地址,学生的学校和家庭地址,varchar,128}
    姓名描述{姓名,大学生的姓名,varchar,12}
    密码描述={密码,大学生登陆系统查询信息的登录密码,varchar,32}

    社团

    社团编号描述={社团编号,特定社团的编号,int,11}
    社团名称描述={社团名称,社团的名字,varchar,32}
    所属学院描述={所属学院,社团所属的学院名称,varchar,32}
    社费描述={社费,加入社团需要交纳的费用,double,64}
    社团建立时间描述={建立时间,社团开始运行的时间,tinyblob,32}

    活动

    活动编号描述={活动编号,活动的编号,int,11}
    地址描述={地址,活动开展的地址,varchar,64}
    标题描述={标题,活动开展的标题描述,varchar,64}
    内容描述={内容,活动开展的具体内容描述,varchar,256}
    开始时间描述={开始时间,活动开展的开始时间,tinyblob,32}
    结束时间描述={结束时间,活动开展的结束时间,tinyblob,32}

    社团评价

    评价编号描述={评价编号,社团评价的编号,int,11}
    评价星级描述={评价星级,对社团评价的星级,int,11}
    时间描述={时间,做出评价的时间,tinyblob,32}
    内容描述={内容,评价的具体内容描述,varchar,256}
    用户编号描述={用户编号,做出评价的用户编号,int,11}
    社团编号描述={社团编号,评价针对的社团编号,int,11}

    社团公告

    社团公告编号描述={社团公告编号,某一条社团公告记录的编号,int,11}
    社团公告标题描述={社团公告标题,某一条社团公告纪录的标题,varchar,32}
    社团公告详情描述={社团公告详情,某一条社团公告纪录的详情,varchar,255}
    社团公告发表时间描述={社团公告发表时间,某一条社团公告纪录的发表时间,datetime,10}
    社团公告发表社团编号描述={社团公告的发表社团编号,某一条社团公告的发表社团的编号,int,11}


    2.4.2 数据结构描述格式为:数据结构描述={数据结构名,含义说明,组成:{数据项或数据结构}}

    系统管理员用户数据结构描述={管理员用户,管理员用户,组成:{编号 登录用户名 登录密码}}
    大学学生结构描述={学生,学生,组成:{专业编号 姓名 性别 密码 学院 专业}}
    社团结构描述={社团,社团和成员活动等信息,组成:{社团编号 社团名称 所属专业 建立时间 社团费 社团成员社团活动 社团公告 社团评价}}
    活动结构描述={活动,社团所举行的活动描述,组成:{活动编号 活动标题 活动内容 活动开始时间 活动结束时间 活动地址 活动参与社团}}
    社团评价结构描述={社团评价,对社团的评价信息管理,组成:{社团评价编号评价星级 评价内容 评价时间 做出评价的学生 被评价的社团}}
    社团公告结构描述={社团公告,社团发出的公告信息管理,组成:{社团公告编号 公告标题 公告内容详情 公告发出时间 公告发出社团}}

    2.5 事务需求分析根据系统需求设计了 31个事务:

    数据输入事务

    添加社团信息
    添加社团评价信息
    添加社团公告信息
    添加社团
    添加社团活动项
    添加社团用户
    添加系统管理者
    添加普通大学生用户

    数据更新删除

    更新/删除社团信息
    更新/删除社团评价信息
    更新/删除社团公告信息
    更新/删除社团
    更新/删除社团活动项
    更新/删除社团用户
    更新/删除系统管理者
    更新/删除普通大学生用户

    数据输出事务

    管理员查询所有社团活动
    管理员查询某个社团所拥有的活动
    管理员查询某活动对应的所有参与社团
    管理员通过起止时间查询社团活动信息
    管理员查看某社团的社团评价信息
    管理员查查看特定星级的社团评级信息
    管理员查看某用户所有发表的评价信息
    管理员查看所有社团基本信息
    管理员查看某社团的用户列表
    管理员查询所有管理员信息
    管理员查询某社团的公告
    管理员查询某学生所参加的社团
    学生查看所有的社团基本信息
    学生查看所有社团的评价信息
    学生查看加入社团的公告


    3 概念结构设计3.1 实体关系
    一个社团会有多个活动,一个活动会有多个参与社团,所以社团和活动的关系是N:N
    一个社团评价只针对一个社团,一个社团会有多条评价,所以社团和评价的关系是 1:N
    一个社团评价只能是一个人提出,一个人可以提多条评价信息,所以社团评价和用户的关系是 N:1
    一个社团公告只可能属于一个社团,一个社团可能会发表多条公告,所以社团和公告的关系是 1:N
    一个学生可能参加多个社团,一个社团可能有多个学生,所以社团和学生的关系是 N:N

    3.2 实体间依赖关系
    添加一条社团评价时,必须指定做出评价的学生,同时必须制定评价针对的社团
    添加一条社团公告时,必须指定做出公告的社团
    添加一条社团参与记录时,必须指定学生,同时必须指定对应社团

    3.3 E-R 图

    4 逻辑结构设计4.1 关系模型1:N 关系的转换方法:在 N 端实体集中增加新属性,新属性由联系对应的 1 端实体集的码和联系自身的属性构成,新增属性后原关系的码不变。具体 E-R 图转换为关系模型如下:

    大学生:(学号,专业班级,登录密码,姓名,地址)
    管理员:(管理员编号,登陆用户名,密码)
    社团:(社团编号,社团所属学院,社团费,名称,建立时间)
    活动:(活动编号,活动地址,活动名称,活动内容,开始时间,结束时间)
    评价:(评价编号,评价星级,评价内容,评价时间,评价用户编号,针对社团编号)
    公告(公告编号,公告标题,公告内容,公告发表时间,公告发表社团编号)
    活动参与(活动编号,社团编号)
    社团用户(社团编号,学生学号)

    4.2 规范化数据库逻辑设计的结果不是唯一的。为了进一步提高数据库应用系统的性能,还应该根据应用需要适当的修改、调整数据模型的结构,这就是数据模型的优化。数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生增删改查(CRUD)操作异常。反之则是乱七八糟,不仅给数据库的编程人员制造麻烦,而且面目可憎,可能存储了大量不需要的冗余信息。
    1NF-无重复的列
    所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的个属性不能有多个值或者不能有重复的属性。
    经检查,上面所得到的表的属性都是不可分割的。
    2NF-属性完全依赖于主键
    第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。
    我们所设计的 8 个表中,每个表都只有一个主键,所以每个表的属性都完全依赖于主键,即满足 2NF。
    3NF-属性不依赖于其他非主属性
    如果关系模式 R 是第二范式,且每个非主属性都不传递依赖于 R 的候选键,则称 R为第三范式模式。
    我们所设计的 8 个表中,没有非主属性对于码的传递函数依赖,即满足 3NF。
    4.3 数据表社团活动

    社团评价

    社团

    系统管理员

    社团公告
    社团用户

    社团活动参与

    社团用户参与

    5 物理结构设计5.1 索引
    由于社团名经常出现在查询和表连接中,并且系统中社团名唯一不重复,所以在该属性上建立 B-tree 索引
    由于管理员经常登录,经常出现在表查询中,并且系统中管理员登录名唯一不重复,所以在该属性上建立 B-tree 索引
    由于大学生信息表中的学生学号经常出现在查询和表连接中,并且作为主键,它的值唯一,所以在这个属性上建立 B-tree 索引。

    B-tree索引物理原理:
    B+树是数据库系统实现索引的首选数据结构。评价一个数据结构作为索引的优劣最重要的指标是在查找过程中磁盘 IO 操作次数的渐进复杂度。
    根据 BTree 的定义,可知检索一次最多需要访问 h 个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次IO 就可以完全载入。为了达到这样的目的,每次新建节点时,直接申请一个页的空间, 这样就保证一个节点无力上也存储在一个页里,加之计算机硬盘存储分配都是按照页对齐的,就实现了一个 node 只需要一次 IO。
    6 数据库实现与维护6.1 数据库表结构建立6.1.1 活动表 Activity--------------------------------- Table structure for activity-------------------------------DROP TABLE IF EXISTS `activity`; CREATE TABLE `activity` ( `id` int(11) NOT NULL AUTO_INCREMENT, `address` varchar(255) DEFAULT NULL, `content` varchar(255) DEFAULT NULL, `end_date` tinyblob, `name` varchar(255) DEFAULT NULL, `start_date` tinyblob, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.2 社团评价表evaluation----------------------------------- Table structure for evaluation---------------------------------DROP TABLE IF EXISTS `evaluation`; CREATE TABLE `evaluation` ( `id` int(11) NOT NULL AUTO_INCREMENT, `content` varchar(255) DEFAULT NULL, `star` int(11) DEFAULT NULL, `time` tinyblob, `by_user_id` int(11) DEFAULT NULL, `to_league_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FKh2hatsg8lg8ydngqgql0unxpx` (`by_user_id`), KEY `FK89ib103ndnixgyus1ut5jr02e` (`to_league_id`), CONSTRAINT `FK89ib103ndnixgyus1ut5jr02e` FOREIGN KEY (`to_league_id`) REFERENCES `league` (`id`), CONSTRAINT `FKh2hatsg8lg8ydngqgql0unxpx` FOREIGN KEY (`by_user_id`) REFERENCES `user` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.3 社团表 league------------------------------- Table structure for league-----------------------------DROP TABLE IF EXISTS `league`; CREATE TABLE `league` ( `id` int(11) NOT NULL AUTO_INCREMENT, `academy` varchar(255) DEFAULT NULL, `club_due` double DEFAULT NULL, `name` varchar(255) NOT NULL, `start_date` tinyblob, PRIMARY KEY (`id`), UNIQUE KEY `UK_n8qcbpi2pjf8bbenfm9le3v36` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.4 社团活动参与纪录表league_activity---------------------------------------- Table structure for league_activity--------------------------------------DROP TABLE IF EXISTS `league_activity`; CREATE TABLE `league_activity` ( `league_id` int(11) NOT NULL, `activity_id` int(11) NOT NULL, KEY `FK7g2y827hegkltuycaffg8sl5c` (`activity_id`), KEY `FKgsuul4o7bix397rlv0nh2g6wm` (`league_id`), CONSTRAINT `FK7g2y827hegkltuycaffg8sl5c` FOREIGN KEY (`activity_id`) REFERENCES `activity` (`id`), CONSTRAINT `FKgsuul4o7bix397rlv0nh2g6wm` FOREIGN KEY (`league_id`) REFERENCES `league` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.5 社团用户参与纪录表league_user------------------------------------ Table structure for league_user----------------------------------DROP TABLE IF EXISTS `league_user`; CREATE TABLE `league_user` ( `league_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, KEY `FK2a17bp9p71ipbpwotxuhc5q6h` (`user_id`), KEY `FKh7auyvlq2pg4ms5q011220v25` (`league_id`), CONSTRAINT `FK2a17bp9p71ipbpwotxuhc5q6h` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), CONSTRAINT `FKh7auyvlq2pg4ms5q011220v25` FOREIGN KEY (`league_id`) REFERENCES `league` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.6 管理员表 manager--------------------------------- Table structure for manager-------------------------------DROP TABLE IF EXISTS `manager`; CREATE TABLE `manager` ( `id` int(11) NOT NULL AUTO_INCREMENT, `password` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_o0yekye62maw0eia889dcxyk7` (`username`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.7 社团公告表 post----------------------------- Table structure for post---------------------------DROP TABLE IF EXISTS `post`;CREATE TABLE `post` ( `id` int(11) NOT NULL AUTO_INCREMENT, `content` varchar(255) DEFAULT NULL, `post_time` tinyblob, `title` varchar(255) DEFAULT NULL, `by_league_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `FKdkqk8bryl5tlyugncimdkxg0s` (`by_league_id`), CONSTRAINT `FKdkqk8bryl5tlyugncimdkxg0s` FOREIGN KEY (`by_league_id`) REFERENCES `league` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.1.8 大学生用户信息表 user----------------------------- Table structure for user---------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `address` varchar(255) DEFAULT NULL, `major` varchar(255) DEFAULT NULL, `password` varchar(255) NOT NULL, `username` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_sb8bbouer5wak8vyiiy4pf2bx` (`username`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    6.2 数据库视图建立6.2.1 五星级评价社团视图创建五星级评价社团查询的视图,简化了数据库查询操作,将表连接的操作隐藏起来。当管理员查询时,可以直接查询视图。
    CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `five_star` AS select `evaluation`.`to_league_id` AS `to_league_id`, `league`.`id` AS `id`, `evaluation`.`star` AS `star` from (`evaluation` join `league` on((`evaluation`.`to_league_id` = `league`.`id`))) where (`evaluation`.`star` = 5)
    6.2.2 某学院所有社团发表公告视图创建某学院所有社团发表公告的视图,简化了数据库查询操作,将表连接的操作隐藏起来。当管理员查询记录时,可以直接查询视图。
    CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `academy_post` AS select `post`.`by_league_id` AS `by_league_id`, `league`.`id` AS `id`, `league`.`academy` AS `academy`, `post`.`title` AS `title`, `post`.`content` AS `content`, `post`.`post_time` AS `post_time` from (`post` join `league` on( (`post`.`by_league_id` = `league`.`id`)) )
    6.3 数据库存储过程建立6.3.1 社团公告查询存储过程为了方便查询某社团所有的公告信息和社团本身的信息,并且方便进行过滤,所以创建存储过程。
    CREATE DEFINER=`root`@`localhost` PROCEDURE `v2`() BEGIN SELECT * FROM post, league WHERE post.by_league_id = league.id; END
    7 社团系统 Java部分代码和运行7.1 系统实体类实现7.1.1 社团活动类 Activity实现@Entitypublic class Activity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String content; private String address; private LocalDate startDate; private LocalDate endDate; @ManyToMany(mappedBy = "activityList") private List<League> leagueList = new ArrayList<>(); @Override public String toString() { return "Activity{" + "id=" + id + ", name='" + name + '\'' + ", content='" + content + '\'' + ", address='" + address + '\'' + ", startDate=" + startDate + ", endDate=" + endDate + '}'; }}
    7.1.2 社团评价 Evaluation 类实现@Entitypublic class Evaluation implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private Integer star; private String content; private LocalDateTime time; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "to_league_id") private League toLeague; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "by_user_id") private User byUser; @Override public String toString() { return "Evaluation{" + "id=" + id + ", star=" + star + ", content='" + content + '\'' + ", time=" + time + '}'; }}
    7.1.3 社团 League 类实现@Entitypublic class League implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(unique = true, nullable = false) private String name; private String academy; private Double clubDue; private LocalDate startDate; @ManyToMany(cascade = CascadeType.PERSIST) @JoinTable(name = "league_activity", joinColumns = {@JoinColumn(name = "league_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "activity_id", referencedColumnName = "id")}) private List<Activity> activityList = new ArrayList<>(); @OneToMany(mappedBy = "toLeague") private List<Evaluation> evaluationList = new ArrayList<>(); @OneToMany(mappedBy = "byLeague") private List<Post> postList = new ArrayList<>(); @ManyToMany(cascade = CascadeType.PERSIST) @JoinTable(name = "league_user", joinColumns = {@JoinColumn(name = "league_id", referencedColumnName = "id")}, "id")}) inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = private List<User> userList = new ArrayList<>(); @Override public String toString() { return "League{" + "id=" + id + ", name='" + name + '\'' + ", academy='" + academy + '\'' + ", clubDue=" + clubDue + ", startDate=" + startDate + '}'; }}
    7.1.4 系统管理员 Manager 实现@Entitypublic class Manager implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false) private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "Manager{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; }}
    7.1.5 社团公告 Post 类实现@Entitypublic class Post implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String title; private String content; private LocalDateTime postTime; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "by_league_id") private League byLeague; @Override public String toString() { return "Post{" + "id=" + id + ", title='" + title + '\'' + ", content='" + content + '\'' + ", postTime=" + postTime + '}'; }}
    7.1.6 学生用户 User 类实现@Entitypublic class User implements Serializable, Comparable<User> { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(unique = true, nullable = false) private String username; @Column(nullable = false) private String password; private String major; private String address; @OneToMany(mappedBy = "byUser") private List<Evaluation> evaluationList = new ArrayList<>(); @ManyToMany(mappedBy = "userList") private List<League> leagueList = new ArrayList<>(); @Override public int compareTo(User o) { return id.compareTo(o.id); } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", major='" + major + '\'' + ", address='" + address + '\'' + '}'; }}
    7.2 系统界面设计与实现7.2.1 启动类实现package com.zzkun;import com.zzkun.view.MainView;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class LeagueManagerApplication implements CommandLineRunner { @Autowired private MainView mainView; public static void main(String[] args) { SpringApplication.run(LeagueManagerApplication.class, args); } @Override public void run(String... strings) throws Exception { mainView.run(); }}
    7.2.2 主界面实现package com.zzkun.view;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.Scanner; @Componentpublic class MainView { @Autowired private Scanner cin; @Autowired private ActivityView activityView; @Autowired private EvaluationView evaluationView; @Autowired private LeagueView leagueView; @Autowired private ManagerView managerView; @Autowired private PostView postView; @Autowired private UserView userView; public void run() { System.out.print("请输入管理员账号:"); String username = cin.nextLine(); System.out.print("请输入管理员密码:"); String password = cin.nextLine(); while (!("root".equals(username) && "root".equals(password))) { System.out.println("用户名或密码输入错误,请重新输入(默认 root, root)"); } mainControl(); } private void mainControl() { while (true) { printMainMenu(); int num = cin.nextInt(); switch (num) { case 1: userView.run(); break; case 2: leagueView.run(); break; case 3: activityView.run(); break; case 4: postView.run(); break; case 5: evaluationView.run(); break; case 6: managerView.run(); break; case 0: return; } } } private void printMainMenu() { System.out.println("========主菜单========"); System.out.println("1.学生用户管理"); System.out.println("2.社团管理"); System.out.println("3.社团活动管理"); System.out.println("4.社团公告管理"); System.out.println("5.社管质量(评价体系)管理"); System.out.println("6.管理员账号管理"); System.out.println("0.退出社团管理系统"); System.out.println("====================="); }}
    7.2.3 学生管理功能界面实现package com.zzkun.view;import com.zzkun.dao.UserDao;import com.zzkun.model.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.List;import java.util.Scanner;@Componentpublic class UserView { @Autowired private Scanner cin; @Autowired private UserDao userDao; public void run() { while (true) { printMenu(); int num = cin.nextInt(); if (num == 1) { showAllUser(); } else if (num == 2) { addUser(); } else { return; } } } private void showAllUser() { List<User> users = userDao.findAll(); System.out.println("所有用户信息:"); for (User user : users) { System.out.println(user); } } private void addUser() { User user = new User(); System.out.print("输入新用户学号:"); user.setUsername(cin.next()); System.out.print("输入新用户密码:"); user.setPassword(cin.next()); System.out.print("输入新用户专业:"); user.setMajor(cin.next()); System.out.print("输入新用户家庭地址:"); user.setAddress(cin.next()); try { userDao.save(user); } catch (Exception e) { System.out.println("添加新用户失败!"); } } private void printMenu() { System.out.println(" "); System.out.println("1.查看当前所有学生信息"); System.out.println("2.添加新的学生用户"); System.out.println("3.修改学生用户信息"); System.out.println("4.修改学生密码"); System.out.println("5.修改学生专业信息"); System.out.println("6.修改学生家庭地址信息"); System.out.println("0.返回上一层"); System.out.println(" "); }}
    7.2.4 Bean 配置类实现package com.zzkun.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.Scanner; @Configurationpublic class BaseConfiguration { @Bean public Scanner scanner() { return new Scanner(System.in); }}
    7.2.5 MySQL 连接配置文件spring.datasource.url=jdbc:mysql://localhost:3306/league_manager?characterEncoding=utf8&useSSL=true spring.datasource.username=root spring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.initialize=true spring.jpa.properties.hibernate.hbm2ddl.auto=create logging.level.root=error
    7.3 系统部分功能截图系统启动

    管理员登陆和系统主要功能菜单

    用户管理功能

    添加学生用户

    社团管理和社团添加

    社团查看

    社团系统退出
    3 评论 94 下载 2018-11-07 16:58:55 下载需要8点积分
  • 基于C语言的图书馆管理系统

    一 需求分析主要实现以下功能:

    分管理员和学生两种身份,不同身份操作不同

    管理员

    进购书籍决定某本书是由被借阅查看借阅情况
    学生

    借书,限制每人5本还书图书分类展示搜索不能重复借阅同一本书

    开机动画,功能就是提高逼格(可以考虑加上音效)

    二 程序设计2.1 总体设计程序总体流程如下图所示:

    2.2 管理员模块设计管理员模块运行流程如下图所示:

    2.3 学生模块设计学生模块运行流程如下图所示:

    三 程序实现3.1 系统结构层次程序结构层次如下图所示:

    3.2 储存结构储存文件分为两个:书目(book_list),借阅历史(borrow_history)

    书目只让管理员操作
    借阅历史学生可以操作

    储存文件具体描述如下:
    book_list:

    书籍编号书名分类出版社价格是否借阅余量
    borrow_history:

    历史ID借阅人书名借阅日期应还日期
    3.3 接口文档3.3.1 结构体定义书籍目录
    typedef struct { int book_no; // 三个字符,如:001 char *name; int category; int price; bool can_borrow; int remain; char *press;} book;
    借阅历史
    typedef struct { int year; int month; int day;} my_time;typedef struct { int history_id; char *borrow_by; my_time *borrow_time; my_time *return_time; char *book_name;} history;
    学生表
    typedef struct { int stu_no; char *name; // int class;} student;
    3.3.2 预设函数界面层
    void bootstrap() ;void welcome_admin(); void show_admin_menu();void welcome_student(char *name);void show_student_menu();void show_list(linklist list);void print_*();void see_you();
    IO
    bool io_input_histroy(linklist history); bool io_input_student(linklist students); bool io_input_book_list(linklist book_list) bool io_output_histroy(linklist history); bool io_output_student(linklist students); bool io_output_book_list(linklist book_list)
    数据层
    bool check_stu_no(int stu_no);bool check_admin(char *passwd);bool get_by_category(int category, linklist *get_list);bool borrow_book(char *name);bool return_book(char *name);void search(char *name,linklist list);bool see_self(int stu_no, linklist list);
    2 评论 75 下载 2018-10-24 14:51:56 下载需要5点积分
  • 基于JAVA的图书管理系统

    1 数据库设计1.1 需求分析1.1.1系统简要分析本系统的用户为图书馆工作人员,系统用户分为管理员和普通用户两种。管理员为系统的高级用户,普通用户为图书馆工作人员。管理员账号和密码预先写入数据库中,账号是每位同学的学号,密码是学号后三位。
    系统为不同用户提供不同的功能:
    1.1.2基本需求功能点分析系统为不同用户提供不同的功能:

    管理员功能:

    登陆:输入管理员帐号和密码,验证通过后可登陆系统。
    用户管理:

    添加系统普通用户为普通用户重置登陆密码。
    图书类别管理:

    添加图书类别,如:政治,经济,军事,医药等。修改图书类别名称。类别查询。
    图书管理:

    添加一本图书。图书信息包括:书名,第一作者,第一出版社,出版年份,状态(正常,报废),类别等。修改图书信息。图书查询。
    读者类别管理:

    添加读者类别,类别信息包括:类别名称,最长借阅天数,最大借阅本数等。修改读者类别名称。读者类别查询。
    读者管理:

    添加读者。读者信息包括:姓名,读者类别,身份证号,联系电话等等。修改读者信息。读者查询。
    普通用户功能:

    系统登陆和密码修改图书馆工作人员凭用户号和密码登陆系统。图书借阅为读者借书。如果该读者的借书量未达到最大借阅本书,且无超期欠费情况,则可以为其登记借书信息;如有欠费,则需先缴费还书。为读者还书。如果该读者所还图书未超期欠费,则可以为其还书;如欠费,则先计算欠费金额,付费后再还书。

    1.1.3 系统运行条件分析此软件系统需要至少一台计算机为服务器Windows操作系统SQL Server 2008 或更高版本数据库服务器
    1.1.4 数据字典


    表名
    字段序号
    字段名
    主键
    类型
    占用字节
    长度
    允许空




    t_borrowing
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10




    3
    borrowingTime

    date
    3
    10



    t_return
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10




    3
    returnTime

    date
    3
    10



    t_reader_bookRelation
    1
    readerId

    int
    4
    10




    2
    bookId

    int
    4
    10



    t_user
    1
    id

    int
    4
    10




    2
    password

    varchar
    50
    50




    3
    username

    varchar
    50
    50




    4
    usertype

    varchar
    20
    20



    t_bookType
    1
    id

    int
    4
    10




    2
    bookTypeName

    varchar
    10
    10




    3
    bookTypeDesc

    varchar
    1000
    1000



    t_book
    1
    id

    int
    4
    10




    2
    bookName

    varchar
    20
    20




    3
    author

    varchar
    20
    20




    4
    bookTypeid

    int
    4
    10




    5
    publisher

    varchar
    20
    20




    6
    publishtime

    varchar
    10
    10




    7
    state

    varchar
    10
    10




    8
    bookDesc

    varchar
    100
    100



    t_readerType
    1
    id

    int
    4
    10




    2
    readerTypeName

    varchar
    20
    20




    3
    theLongestBorrowingDay

    int
    4
    10




    4
    maximumBorrowingNumber

    int
    4
    10



    t_reader
    1
    id

    int
    4
    10




    2
    IDNumber

    varchar
    20
    20




    3
    name

    varchar
    20
    20




    4
    readerTypeid

    int
    4
    10




    5
    tel

    varchar
    11
    11




    1.2 概念结构设计系统E-R图如图

    1.3 逻辑结构设计此部分需要列出由E-R图转化得到的数据表。

    用户表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    用户id


    password
    varchar
    50
    非空
    用户登录密码


    username
    varchar
    50
    非空
    用户名


    usertype
    varchar
    20
    非空,管理员或普通用户
    用户类型




    图书类别表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书类别id


    bookTypeName
    varchar
    10
    非空
    图书类别名


    bookTypeDesc
    varchar
    1000

    图书类别描述




    图书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书id


    bookName
    varchar
    20
    非空
    图书名


    author
    varchar
    20
    非空
    作者


    bookTypeid
    int
    4
    非空,外键
    图书类别id


    publisher
    varchar
    20
    非空
    出版社


    publishtime
    varchar
    10
    非空
    出版时间


    state
    varchar
    10
    正常或报废
    图书状态


    bookDesc
    varchar
    100

    图书描述




    读者类别表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    图书id


    readerTypeName
    varchar
    20
    非空
    读者类型名


    theLongestBorrowingDays
    int
    4
    非空
    最长借阅时间


    maximumBorrowingNumber
    int
    4
    非空
    最大借阅数量




    读者表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    id
    int
    4
    主码
    读者id


    IDNumber
    varchar
    20
    非空
    身份证号


    name
    varchar
    20
    非空
    姓名


    readerTypeid
    int
    4
    非空,外键
    读者类别号


    tel
    varchar
    11

    联系方式




    借书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id


    borrowingTime
    date
    8
    主码
    借阅时间




    还书表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id


    returnTime
    date
    8
    主码
    归还时间




    读者-图书关系表,具体数据如表所示:



    列名
    数据类型
    长度
    约束
    说明




    readerId
    int
    4
    主码
    读者id


    bookId
    int
    4
    主码
    图书id



    1.4 物理结构设计数据库管理系统:SQLServer 2014
    1.5 数据库实施1.5.1 数据库表和视图清单如图所示:

    1.5.2 数据库基本表
    用户表


    图书类别表


    图书表


    读者类别表


    读者表


    借书表


    还书表


    读者-图书关系表

    1.5.3 视图1.5.3.1 view_bookType创建视图代码:
    create view view_bookTypeasselect* from t_bookType
    作用:对图书类别全部属性的查询语句,通过java代码实现可显示在图书类别维护界面的表格中。
    1.5.3.2 view_borrowing创建视图代码:
    create view view_borrowingasselect readerId,IDNumber,name,bookId,borrowingTimefrom t_reader,t_borrowingwhere t_reader.id=t_borrowing.readerId;
    作用:对借书表和读者表部分属性的查询语句,通过java代码实现可显示在图书借阅记录界面的表格中。
    1.5.3.3 view_userlist创建试图代码:
    create view view_userlistasselect * from t_user where usertype='普通用户'
    作用:查询用户类别为普通用户的用户的全部属性,通过java代码显示在重置用户密码界面的表格中。
    1.5.4 存储过程1.5.4.1 existBookByBookTypeId存储过程创建存储过程代码:
    create procedure existBookByBookTypeId(@ID int)as (select*from t_bookwhere bookTypeId=@ID)
    作用:判断指定图书类别下是否有图书
    1.5.4.2 existReaderByReaderTypeId存储过程create procedure existReaderByReaderTypeId(@ID int)as(select*from t_readerwhere readerTypeId=@ID)
    作用:判断指定读者类别下是否有读者
    1.5.5 触发器删除读者触发器
    create trigger triger_deletereaderon t_reader instead of deleteasbeginEXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'--禁用约束delete from t_borrowing where readerId=(select id from deleted)delete from t_return where readerId=(select id from deleted)delete from t_reader where id=(select id from deleted)EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL' --启用约束end
    作用:删除读者时有外键约束,触发器取消外键约束,删除借书还书记录中该读者的记录,再删除该读者,再启用约束。
    2 系统设计2.1 系统功能模块设计此部分主要描述各个模块具体实现的各项功能点以及模块之间的关系,模块结构划分如图所示:

    2.1.1 管理员用户模块该模块具体功能是管理员对图书系统进行管理,主要包括图书类别管理模块,图书管理模块,读者类别管理模块,读者管理模块,用户管理模块。

    图书类别管理模块:此模块下可进行图书类别的添加和维护,维护包括查询、删除和修改,可以对图书类别名和图书类别描述等属性进行操作。
    图书管理模块:此模块下可进行图书的添加和维护操作,维护包括查询删除和修改,可对图书名称、图书作者、图书类别、出版社、出版时间、图书状态、图书描述等属性进行操作。
    读者类别管理模块:此模块下可进行读者类别的添加和维护,维护包括查询、删除和修改,可对读者类别名称、最长借阅天数和最大借阅本数等属性进行操作。
    读者管理模块:此模块下可进行读者的添加和维护,维护包括查询、修改和删除,可对读者身份证号、姓名、联系方式、读者类别等属性进行操作。
    用户管理模块:此模块下可进行对普通用户的添加和修改普通用户密码操作。

    2.1.2 普通用户具体功能模块该模块具体功能是普通用户登录系统后进行借书和还书操作,主要包括图书借阅和图书归还模块。

    图书借阅模块:此模块下可进行图书借阅操作和对借阅记录的查询操作。图书借阅可添加图书借阅记录。
    图书归还模块:此模块下可进行图书归还操作和对归还记录的查询操作。图书归还可添加图书归还记录。

    2.2 系统功能设计本部分按系统主要功能绘制流程图,说明系统功能将如何现。如图所示:

    3 系统实现3.1系统项目清单系统项目具体所含如图所示:
    model包包含各种实体类,dao包包含各种数据库操作的类,util包包含数据库工具类和字符串工具类,model包包含各种界面类。


    3.2 登录界面登录界面由LogOnFrm.java实现,输入用户名和密码,选择用户类型为管理员或普通用户,验证成功即可进入主界面。用户名或密码错误或未输入则弹出窗体提示。如图所示。

    3.3 管理员主界面管理员主界面由MainFrm.java实现,选中菜单栏中选项选择要显示的功能窗体。如图所示:

    3.3.1 图书类别维护界面

    3.3.2 图书添加图书的添加是管理员向数据库中加入一条图书信息,若图书名称、图书作者等非空数据为空,则弹出提示图书不能为空等。图书类别为一个下拉框,其中显示图书类别表中的图书类别名称。图书状态只有正常和报废两种,用单选按钮实现。图书添加界面如图所示。

    3.3.3 图书维护图书维护界面可实现图书的查询、修改删除。没有操作时中间表格bookTable显示所有图书。进行查询操作时表格中显示查询到的结果。添加了表格行点击事件,点击指定行时,下面的表单操作中的文本框被选中内容填充,修改文本框的内容后点击修改按钮,对数据库执行update操作,修改了数据库中数据,然后界面中bookTable表刷新,显示更新后的数据。点击删除按钮时执行sql的delete操作。图书维护界面如图所示。

    3.3.4 添加普通用户在管理员主界面选择用户管理-添加普通用户弹出菜单如图3-8,输入要添加的用户名和密码,点击添加按钮,提示用户添加成功。如用户名和密码为空则弹出错误提示。重置按钮可清空两个文本框。

    3.3.5 重置用户密码菜单在管理员主界面选择用户管理-重置用户密码菜单如图,可进行查询和修改密码操作。在查询框中输入要查询的用户名,中间的userTable中将显示查询出的信息,运用视图view_userlist。点击要修改的用户所在行,该用户密码将出现在密码修改框的密码文本框中,修改内容,点击修改按钮,弹出用户密码修改成功则完成用户密码修改。选中表中用户点击删除按钮,弹出删除成功提示框,则完成了删除该普通用户操作。

    3.3.6 读者维护界面在管理员主界面选择读者管理-读者维护显示读者维护界面如图。可对读者进行查询、修改、删除操作。查询结果显示在表格中。选择表格中数据可进行修改、删除操作。修改、删除完成后提示修改成功或删除成功。删除操作运用触发器triger_deletereader同时删除被删除读者的借书记录和还书记录。

    3.3.7 读者类别维护界面在管理员主界面选择读者类别管理-读者类别维护显示读者类别维护界面如图。读者类别管理界面可实现对读者类别的查询、修改、删除操作,其中删除操作调用存储过程existReaderByReaderTypeId判断该读者类别下是否有读者。有读者时的错误提示如图。


    3.4 普通用户主界面普通用户主界面由MainFrm2.java实现,选中菜单栏中选项选择要显示的功能窗体。如图所示。

    3.4.1 图书借阅界面在普通用户主界面点击借书-图书借阅显示图书借阅界面如图。输入读者编号和图书编号点击确定,若读者编号和图书编号在t_reader和t_book表中不存在则弹出错误提示框。点击重置两文本框重新为空。借书本数超限提示如图,借书时间超限提示如图。



    3.4.2 图书借阅记录查询在普通用户主界面选择借书-借阅记录查询显示界面如图。在查询框中输入读者身份证号和图书编号,点击查询按钮,可进行查询操作。中间表格运用视图view_borrowing显示查询出来的记录,查询之前显示所有的借书记录。

    4 总结图书管理系统运用java语言,连接数据库,主要用eclipse的windowsbuilder插件完成图形化界面,数据存储在SQL server数据库中,通过SQL语句完成对数据库的操作。
    运用了视图、存储过程、触发器来完善系统。系统完成了对图书、读者、用户等对象的增删改查操作。实现了大部分图书管理系统要求的功能。
    不足:系统虽然完成了图书借阅超过期限的提示,但没有写有关的缴费界面和操作。
    3 评论 83 下载 2019-03-02 17:57:17 下载需要12点积分
  • 基于80x86汇编的俄罗斯方块游戏

    一、游戏背景介绍1.1 背景知识俄罗斯方块原本是前苏联科学家阿列克谢·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。Game Boy 版的俄罗斯方块在日本卖出 424 万套,是 Game Boy 史上卖最好的游戏。海湾战争时,也是前线美军最常拿消磨时间的游戏之一。由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。
    俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而 家喻户晓,风靡世界。俄罗斯方块原名是俄语Тетрис(英语是 Tetris),这个名字来 源于希腊语 tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。于是,他把两个词 tetra 和 tennis 合而为一,命名为 Tetris,这也就是俄罗斯方块名字的由来。自此俄罗斯方块游戏一直火热至今。在各种经典小游戏分区和分类,我们不难见其身影,经常被用来怀旧或是娱乐。
    1.2 基本功能部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。方块会从区域上方开始缓慢继续落下。玩家可以做的操作有:以 90 度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。本游戏中按 W 键可以旋转方块,控制方向。按 A 键可以左移,按 D 键可以右移,当左移或者右移到边界时,不能再移动整体的方块,按 q 键可以让方块加速下落,但不会直接下落,这种操作是为了让方块下落的更快,但不至于直接落下而失误导致游戏失误,按 S 键可以让方块直接落下,以此来节省玩家的时间。方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。每一行必须由所有行中所有列的当区域中某一列横向格子全部由方块填满,否则会一直累加直至方块行排满了所有的游戏界面,此游戏就会结束,并记录分数,如果某一行所有列都填满了方块,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。
    1.3 风靡全球的原因俄罗斯方块风靡的原因在于,未完成的任务与潜在的解决方法并存——徐徐降临的每一 种方块都有各自的安插方式。俄罗斯方块是一个简单的可视世界,通过操纵五个按键(当然是向左、向右、左转、右转和降落)能够迅速地得出解决方案。对俄罗斯方块玩家的研究结果显示,人们普遍喜欢通过旋转方块来看它们是否匹配,而不是一边看着方便降落一边思考。当然这两种方法都可行,但在俄罗斯方块的世界里永远是动作领先——这是吸引人的关键。和生活中不太相同的是,俄罗斯方块将我们处理问题时的所见所想直接联系到了一起,我们能立即对问题采取行动。
    1.4 作用可以增强人们对图形的感性认识和对位置感的锻炼,日常生活压力大。用游戏来减轻压力。许多人无聊,来打发时间。在游戏世界中相当于另外一个你,在现实生活中做不到的在游戏看可以做到,得不到的在游戏中却可以得到,获得满足感和成就感。游戏的世界可以从侧面另外玩家的道德素质。思想素质,让你可以方面的接触各种各样的人。游戏玩家群体在社会中是各个行业,各个阶层的人。你可以在里面很方便的了解到其他东西。也可以学会许多东西。益智游戏可以锻炼你的脑力,敏捷游戏可以锻炼你的敏捷能力。策略游戏可以提高你的智力等。
    进入界面后可以选择三种不同的游戏速度的游戏模式:

    Fast 为最快速度,游戏难度最高,方块下落很快,很考验反应速度,同时游戏乐趣也最大
    middle 为中等速度的模式
    slow 为缓慢游戏模式,都比较适合新手练习和平时娱乐


    选择任意一个速度的游戏模式后,游戏便进入了主界面,界面左边是游戏运行的游戏动画界面,右面有记分板和下一方块的提示,还有基本操作的提示,方便新手玩家操作。出现图形后,A 左移 D 右移 W 旋转 S 为直接下落,直至填满界面后会结束游戏。

    最后如果方块累计触到上顶线,则游戏结束,退出主程序,如图 3。

    二、核心算法思想游戏区域由许多等面积的小方块构成,这些区域状态只有满或空两种。将空间以静态二维数组实现,并预先定义其状态值。满为 1,空为 0,以此来完成游戏地图区域的空间分配。
    小方块的实现是由一个 4*2 的小数组表示,用四个存储单位空间存储当前下坠物的每一个子 块的位置来对整个下坠物件的位置进行标识,每个存储空间的大小就是一个点的坐标。每个 方块都有其对应的编号,编号按由上到下,由左到右的顺序编排。有了这些编号,方块的变 换实现起来就方便多了。再由一个宏去标识下坠物的位置。
    游戏进程需要定时器的驱动,所以很有必要在程序当中加入一个定时器机制。方块随着时间的自动下落需要一个定时器来计算时间下落,若下落速度小于屏幕时间的刷新速度,则会出现屏幕的闪动等问题,因此我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。而且计时器可以对游 戏运行时间进行如此对游戏的开始,暂停,结束控制便能够得到实现。
    游戏开始后便开始掉落方块,并且会在游戏区域上方出现下一个下坠物的形态,因此有随机物件产生这个操作。此时用户可根据需要来变换方块,向左或向右移动来调整方块位置,然后通过按下使方块加速下落。这就涉及到了四个主要操作。当方块向左或向右移动时,需要判定方块是否达到了游戏区域的边界;当方块下落时需要判定方块是否到了游戏区域的底部,或是碰到了别的方块。开始后便可用键盘上的“上下左右”来对方块进行操作。方块移动之前,要对方块的横纵坐标计算,我们在核心算法中,用两次嵌套的循环来实现横纵坐标的计算,外层对横坐标进行判断和计算,内层对纵坐标进行判断和计算,首先用大循环去计算横坐标的增减,因为横坐标要考虑的问题较多,而纵坐标比较容易实现,纵坐标只需考虑图形是否撞到了底线或者其他方块,出现触碰底线和触碰其他方块的问题后,用中断保存改变后的值即可跳出循环。首先设置一个栈,数据先入栈,中断保存信息,x 轴和 y 轴的坐标分别进各自对应的寄存器,与之前中断值作比较,纵坐标自增,此处有一个循环,若 DX 寄存器值小于 b 的纵坐标,则继续调用中断 INT 10H;用循环来实现整个纵坐标增长或减少的计算,跳出循环后 CX 寄存器值加一,进入第二个循环,该循环包括上一个循环体,判断 CX 值是否小于纵坐标,若小于,将新的纵坐标数据放入 DX 寄存器中。方块的实现七种下物都有一个共同点,就是它们占据的空间一样,都是由四个等面积的小方块构成,因此用一个整型的数组来存储每个下坠物的四个小方块的坐标位置。每个下坠物中的方块都有编号,编号按从左到右,从上到下的顺序排列。从代码中可以看出程序首先获取了当前下坠物的四个小方块坐标,然后所有纵坐标递减一格,由函数计算出改变数据的区域。这样便可完成左移命令。右移和下移的道理也是一样。但是这里涉及到一个问题,就是要对移动是否到达游戏区域的边界做出判断。左、右移的限制原理是一样的,只是方向和坐标数据有点区别。根据各种不同形态的下坠物最左边的小方块的正左(右)方区域是否为非被占用状态来判断它是否可以移动。
    界面绘制,定时器任务的发生,用户的输入(如开始,暂停,结束,级别设置,左移,右移,旋转,快速下移)的命令的响应需要用到多线程。在屏幕的绘制中,首先应该修改屏幕的颜色,其次要定义一个方块类,将生成的小方块放入其中。将前景色和背景色设置为同一种颜色,一个字符显示在屏幕上就是一个小方块。控制方块的下落速度是设计中必须实现 的功能,方块的下落速度也就是时间间隔,因此我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。因此,如何在一个程序中体现两种不同的时间控制是此模块的一个难点我们需要对键盘中上、下、 左、右键的读取实现对方块的变形、下落、右移和右移的功能。
    三、核心算法流程图进入程序后先进行屏幕初始化,之后显示调用显示边框函数,再显示新方块。检测按键状态,之后再度检测键盘状态。为了保证整个程序结构性能良好,不会出现与其他函数体同时用一个寄存器而使得程序跑飞。其中分别四个主要操作按键 WASD 都对应不同的操作,W 旋转,A 左移 D 右移,S 下落,如果键盘输入的对应寄存器的值,则输出对应的操作的值,否则便进入下一个判断条件进行判断,否则操作失效。在进入程序后先将几个主要寄存器推入堆栈,当程序退出时,又将寄存器值从堆栈中送回。堆栈采用的是先进后出的算法,所以应当注意顺序。这样接口,便于向后兼容,使用起来方便。如下,图 4。

    首先设置一个栈,数据先入栈,中断保存信息,x 轴和 y 轴的坐标分别进各自对应的寄存器,与之前中断值作比较,纵坐标自增,此处有一个循环,若 DX 寄存器值小于 b 的纵坐标,则继续调用中断 INT 10H;用循环来实现整个纵坐标增长或减少的计算,跳出循环后 CX 寄存器值加一,进入第二个循环,判断 CX 值是否小于纵坐标,若小于,将新的纵坐标数据放入 DX 寄存器中,再将坐标计算得得值传回寄存器,完成方块的消除和累积。如下,图 5。

    四、开发中遇到的问题如何能够让下落的方块在检测到下方有原先掉下来的方块或者已经到达游戏界面的底部从而停下来呢?
    建立一个静态数据二维表与游戏界面映射。栅格部分初始化为1,之后不对该静态数据位置操作。栅格部分是不会显示在屏幕上,只是在静态数据表中存在,以此方便对方块的出界,叠加等的判断。
    当一格中的方块堆满后如何实现消除?
    解决此问题的方法是用消行算法,当有出现方块不可动作,即 NOTDONECAN 对应值的为 1 时,先将 QUANOW 对应的值当前位置在静态数据表中的映射数值置为1,之后判断静态数据表 中是否有一整行为1,是则将该行以上数据整体下移一行,之后刷新显示,即通过判断静态数据表中的各个位置是否为1,为1则刷新为洋红色否则刷为黑色;如若该行有0存在,则进行下一行的判断。
    当一个或几个方块出界、叠加时候,如何判断这种情况?
    先将 QUANOW 对应的传送给与寄存器,等长的一维数据表 QUATEMP。当再将 QUATEMP 进行 一次操作,比如向下操作:将 QUATEMP 对应的中的Y 轴坐标加1,X 轴坐标不变,再调用NOTDONE 函数分别找到 QUATEMP 中四个方块位置在静态数据表中的映射,判断该位置数据是否为1,如若有一个1则,将NOTDONECAN 标志位置为1,即不可动作,否则将其置为0。
    DOWNGOON则 通过判断 NOTDONECAN 标志位来选择是否将 QUATEMP 的值传送给 QUANOW,如若NOTDONECAN为 0,即可以动作,则传送数据,同时刷新显示。否则不可动作,则将 QUANOW 当前位置在静态数 据表中的映射数据置为1,即跟新静态数据二维表。其他判断依此类推。
    如何控制下落的时间?
    一开始做游戏界面的时候,设置的默认下落时间间隔和屏幕刷新时间不合适,游戏界面消除和下落方块的时候,总是会出现闪屏的情况,对游戏影响不大,但是对玩家游戏体验影响很大,经过查阅资料和研究,我们发现屏幕的刷新速度必须快于方块的下落速度,否则会出现上述情况。控制方块的下落速度是设计中必须实现的功能,方块的下落速度也就是时间间隔,因此 我们只需定义一个时间类,设置好时间间隔即可。同时,也需要控制屏幕的刷新速度,而刷新速度必须比方块下落时间间隔快。因此,如何在一个程序中体现两种不同的时间 控制是此模块的一个难点。
    如何控制按键不重复按下向下的按键时,下落速度会加快,即放置间隔的运行间隔会减小存在问题:无论是在放置间隔外部还是内部更改速度值,都只能在清除间隔之后,才能生效,无法满足需求解决方式:将放置间隔更改为放置时间,在放置时间里调用自身,形成递归,即可实现需求, 如何检测方块位置?
    没有方块存在时,直接下落到界面底部。有方块阻挡时,停在方块上面。存在问题:如何记录已有方块的位置解决方式:获取每一个方块的 top 和left 位置,拼接成字符串,存入数组。每一次掉落时,都检测每一个方块的下一个位置是否已经存在在数组中,如果没有,就允许下落。否则停止下落,生成下一个方块。按键按下时,如何禁止重复触发?按键按下时,速度在当前值的基础上减少300,速度减少300存在问题:按键一直按住不放时,速度就会一直持续执行减法。解决方式:设置一个 flag,按键按下,flag 值就改变,当事件触发时,flag 才会变回原值。
    如何让玩家适当操作?
    根据相应的提示进行一些功能上的选择,如修改音乐,方块颜色和游戏难度。当游戏开始时,计算机将随机抽取方块的放到方格上。此游戏允许玩家旋转方块,左右移动,加速向下。程序要实现对满行的消除并记录得分以及对游戏的结束判断。
    如何更便利玩家体验该游戏?
    在 windows 环境下建立一个简单的用户界面,用户可以进行功能性的菜单选择,我们选择了fast,middle,solw 三种游戏速度模式,由难到易三种游戏模式选择。简单明了,不需要玩家输入多余命令,仅输入 1,2,3,4 即可控制界面的选择以及退出游戏。
    游戏开始后,通过指定的功能键控制方块,方块可以左右移动、落下、旋转。AD 分别为左移和右移,W 为旋转当前的方块,S 为使方块快速落下,方便于玩家的技巧性游戏。此操作在游戏运行界面右方记分板的下方显示出,方便玩家的操作。
    界面上要显示分数和游戏已经开始的时间和游戏的难度,并且预显示出下一个方块的形状,使玩家可以通过下一步的形势推断现在进行的操作,以此来增加游戏的难度和趣味性,让游戏有更多的技巧可言,游戏方式多元化,否则游戏便很枯燥单调,不会很好的吸引其他玩家。
    能进行简单的参数设置:修改音乐,改变方块颜色和难度等。
    对三个主要游戏数据的处理方块的下落,相应键盘:需要判断下键是否按下,并加快时钟周期。完成下落后,还原到原来的时钟周期形状的下落, 实现旋转:不同旋转角度显示不同方向的方块来完成的。 消去主游戏区底部填满的行:查看主游戏区底部的每行是否填满的方式是,在游戏区图 形框可以看成是由许多的小方块组成,方块运动的过程就是造型里方块显示或者隐藏,就像现在的霓虹灯效果一样,由时钟控件控制改变的速度,上一层的消失,下一层的显示,这样, 从视觉效果可以看到方块的下落运动效果方块在下落的过程中会自动判断每一行方块的属性,如果此行方块属性全部为是时,就会将这一行小方块的 visible 属性全部变成否, 同时消去此行,在将上面的小方块向下移动,利用循环语句进行判断,将所有这样情况的行改变小方块属性。当有多行同时出现这样情况时使用递归调用,实现连续消行。
    六、心得体会在这本次编写俄罗斯方块汇编游戏的中,在收获知识的同时,还收获了阅历,收获了成熟, 在此过程中,我们通过查找大量资料,请教老师和同学。使我再专业知识和动手实践方面都得了到很好的提升。在此次程序设计中,接触到了我们熟知的网络,在设计过程中总觉得好难实现,但在实现过程中,发现只要用心探索,一切皆有可能。通过课程设计,我对汇编语言有了更深一 步的了解,发现其用起来不是十分的方便,但确实是比较适合我们初学者学习的语言。这次课程设计我对游戏编程有了一定的了解,虽然自己只用了汇编,但在实际操作的过程中,也和同学们交流探讨了好多其他语言关于游戏设计的思想,集思广益,拓宽了自己的眼界。增强了自己的实际动手能力,增加了学习计算机语言的兴趣,另外在课程设计中也得到了一定的成就感。决定再今后的学习中,多看一些这类方面的书籍,来进一步的了解相关的游戏编程知识,为以后的应用做准备。
    经过本次汇编语言的学习与实践,体验了之前没有尝试过的学习模式,这种自学加上老师辅导,并和同学一组独立做出课程作业的模式,让我丛中收获到许多。首先,经过在课本上学习、在图书馆中查阅资料和在互联网上查询,我学习了不少汇编语言的基础知识和一些小技巧与应 用,与此同时,因为汇编语言这门语言更接近于硬件,它直接面向机器,我也学习和了解到不少关于计算机硬件的一些知识。其次,我们在开发过程中,先设计框架和思路,然后一起查阅相关的资料,一边学习一边测试部分的小程序,检测代码功能和编译器环境问题,虽然有不少的小麻烦和一些棘手的问题,但是经过和同学一起调试交流,成功解决了这些问题。一开始认为开发程序很简单,但在制作的过程中,感受到做一个完整完善的小程序原来也是很不容易,有很多问题要面对和解决,通过本次项目我们学习到了一种临危不乱,顽强渐进的精神,为以后的学习和 工作积累了经验,打下了良好的基础。
    0 评论 1 下载 2019-06-20 16:45:42 下载需要8点积分
  • 基于α-β剪枝算法实现的AI五子棋游戏

    一、对抗问题对抗问题:顾名思义,博弈双方是带有对抗性质的。博弈的任何一方都希望局面尽量对自己有利,同时局面也应该尽量令对方不利。通常这一类问题可以通过 Minimax 算法解决。
    Minimax 算法又名极小化极大算法,是一种找出失败的最大可能性中的最小值的算法。Minimax 算法常用于棋类等由两方较量的游戏和程序,这类程序由两个游戏者轮流,每次执行一个步骤。为了执行 Minimax 算法,我们可以通过穷举的方式,枚举所有的状态空间,从而使得我们可以在游戏刚一开始,就预测到输赢。但是,在实际情况下,游戏的状态空间都是异常庞大的。很显然,我们不能将以穷举方式实现的 Minimax 算法用于实际应用。
    二、α-β减枝通过分析可以发现,在利用穷举方法执行 Minimax 算法中有许多的无效搜索,也就是说,许多明显较劣的状态分支我们也进行搜索了。我们在进行极大值搜索的时候,我们仅仅关心,下面最大的状态,对于任何小于目前值的分支也都是完全没有必要进行进一步检查的。(α减枝)

    通过上图,我们可以发现,我们可以减去大量无用的状态检查,从而降低我们的运算量。
    同时,我们在进行极小值搜索的时候,我们仅仅关心,下面最小的状态,对于任何大于目前值的分支都是完全没有必要进行进一步检查的。(β 减枝)

    通过上图,我们可以发现,我们可以减去大量无用的状态检查,从而降低我们的运算量。
    将上述所提到的 α 减枝与 β 减枝进行综合就可以得到 α-β 减枝。对于对抗搜索而言,我们需要精心设计其估值函数,不然我们的 α-β 减枝将毫无用武之地。
    三、五子棋问题五子棋:是一种两人对弈的纯策略型棋类游戏,通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成 5 子连线者获胜。

    这里,我们采用了极大极小博弈树(MGT),来实现 AI。这里用一张井字棋的搜索示意图来说明。

    上图很清晰的展示了对局可能出现的所有情况(已经去除了等价的情况),如果让这个图延展下去,我们就相当于穷举了所有的下法,如果我们能在知道所有下法的情况下,对这些下法加以判断,我们的 AI自然就可以选择具有最高获胜可能的位置来下棋。极大极小博弈树就是一种选择方法,由于五子棋以及大多数博弈类游戏是无法穷举出所有可能的步骤的(状态会随着博弈树的扩展而呈指数级增长),所以通常我们只会扩展有限的层数,而 AI 的智能高低,通常就会取决于能够扩展的层数,层数越高,AI 了解的信息就越多,就越能做出有利于它的判断。
    为了让计算机选择那些获胜可能性高的步骤走,我们就需要一个对局面进行打分的算法,越有利,算法给出的分数越高。在得到这个算法过后,计算机就可以进行选择了,在极大极小博弈树上的选择规则是这样的:

    AI 会选择子树中具有最高估值叶子节点的路径
    USER 会选择子树中具有最小估值叶子节点的路径

    这样的原则很容易理解,作为玩家,我所选择的子一定要使自己的利益最大化,而相应的在考虑对手的时候,也不要低估他,一定要假设他会走对他自己最有利,也就是对我最不利的那一步。
    接下来,我们实现关键的局面评分步骤:直接分析整个棋面是一件很复杂的事情,为了让其具备可分析性,我们可以将其进行分解,分解成易于我们理解和实现的子问题。
    对于一个二维的期面,五子棋不同于围棋,五子棋的胜负只取决于一条线上的棋子,所以根据五子棋的这一特征,我们就来考虑将二维的棋面转换为一维的,下面是一种简单的思考方式,对于整个棋盘,我们只需要考虑四个方向即可,所以我们就按照四个方向来将棋盘转换为 15 * 6 个长度不超过 15 的一维向量(分解斜向的时候,需要分为上下两个半区),参考下图:

    我们的目的是为了为其评分,那么我们就还需要评估每个线状态,将每个线状态的评分进行汇总,当做我们的棋面评分:

    接下来我们所要做的就是评价每一条线状态,根据五子棋的规则,我们可以很容易穷举出各种可能出现的基本棋型,我们首先为这些基本棋型进行识别和评价,并且统计每个线状态中出现了多少种下面所述的棋型,并据此得出评价值,得到如下图所示的静态估值表:

    根据这个表以及我们之前所谈到的规则,我们就可以得到一个可以运行的AI了。
    四、进一步的优化注意到,如果我们搜索到第四层,总共需要搜索:224 + 224 223 + 224 223 222 + 224 223 222 221 = 2 461 884 544 个状态节点,搜索如此多的状态节点的开销是十分可观的,因此,我们提高效率的方式就锁定到了:如何减少需要搜索的状态节点。
    我们可以采取以下方法来减少需要搜索的状态节点:

    我们可以利用经典的α-β剪枝算法对博弈树剪枝
    我们可以每次搜索仅搜索落子点周围 2*2 格范围内存在棋子的位置,这样可以避免搜索一些明显无用的节点,而且可以大幅度提升整体搜索速度
    避免对必胜/负局面搜索,当搜索过程中出现了必胜/负局面的时候直接返回不再搜索,因为此时继续搜索是没有必要的,直接返回当前棋局的估价值即可
    加入随机化AI的下棋方式,普通的AI算法对于给定的玩家下棋方式会给出固定的回应,这就导致玩家获胜一次之后只要此后每次都按此方式下棋,都能够获胜。为了避免这种情况,可以在 AI选择下子位置的时候,在估值相差不多的几个位置中随机挑选一个进行放置,以此增加 AI的灵活性

    规划搜索顺序,有很多有价值的下子点存在于更靠近棋盘中央的地方,如果从棋盘中央向外搜索的话,则能够提高α-β剪枝的效率,让尽可能多的分支被排除
    五、实验成果

    六、实验总结通过本次实验,加强了组员之间的沟通协调能力,同时也提高了我们对αβ减枝算法的了解。我们更了解了五子棋相关的游戏规则以及一些技巧,拓宽了我们的知识面,有助于我们在未来的生活中更好的与人交流。
    同时,经过此次实验,我们深入了解了棋类人工智能算法,进一步的提升了我们的专业水平,有助于我们在未来的就业与科研岗位上走的更远。
    虽然α-β减枝实现起来非常容易,但是五子棋的局势估计却十分的有挑战性,其局势估计的准确与否直接影响了程序的运行结果是否令人满意,AI是否能够展现出足够的智能。
    1 评论 4 下载 2019-06-20 11:16:55 下载需要12点积分
  • 基于JAVA和MYSQL数据库的学生成绩管理系统

    一、需求分析本系统是学生成绩管理系统,所以应该做到可以录入学生成绩,修改学生成绩,删除学生成绩,查询学生成绩,以及最后的所有学生按照GPA排名。
    本系统的数据来源期末考试成绩,用来实现录入,查询,修改,删除,以及排名。
    1.1 增加学生成绩增加学生信息主要是把学生的成绩录入系统中,录入信息包括学生学号,姓名,C++成绩,电路成绩,英语听说成绩,英语读写成绩,大学物理成绩,概率论成绩,近代史成绩,形式与政策成绩,体育成绩,离散数学成绩。
    1.2 修改学生成绩修改学生成绩功能可以通过输入学生的学号,如果该学生在系统中,就弹出一个可以编辑的显示成绩的窗体,然后用户再编辑想要修改的成绩,如果该学生不在系统中,就弹出该学生不在系统中的提醒窗体。
    1.3 查询学生成绩通过查询功能输入学生的学号来查询学生的所有成绩以及GPA,总分。
    1.4 删除学生成绩通过删除学生成绩的功能输入想要删除学生的编号,然后在系统中删除该学生。
    1.5 按GPA排名通过该功能打印出所有学生的成绩,并按照GPA进行排名
    二、概要设计2.1 数据库设计
    2.2 功能模块结构图根据需求分析,为了满足用户的功能需求,将本系统主要划分为如下模块:添加、修改、查询,显示,各模块之间的关系如图所示。

    三、运行环境
    硬件环境:Macintosh电脑
    软件环境:操作系统:macOS Sierra

    四、开发工具和编程语言
    开发环境:IDEA
    编程语言:Java语言、MySQL语言

    五、详细设计在概要设计的基础上,对每个模块进行内部逻辑处理部分详细设计。下面分别列出各个模块具体实现流程图:
    5.1 增加学生信息输入学生的学号,姓名,一系列成绩。
    判断该学生的学号是否已经在系统中,如果在,重新输入,如果不在,就用链接mysql录入系统中

    5.2 修改学生信息首先输入想要修改的学生成绩的学号,然后先判断该学生是否在系统中,如果在,就弹出一个可以编辑成绩的窗体,直接在窗体上编辑就行。

    5.3 查询学生信息通过输入学号,来查找系统中是否有该学号的学生,如果有,则显示该学生的成绩,
    GPA,总分,如果不存在则重新输入。具体实现过程如图所示。

    5.4 删除学生信息通过输入学号,来查找系统中是否有该学号的学生,如果有,则删除该学生的成绩,如果不存在则重新输入。具体实现过程如图所示。

    5.5 按照GPA排名从数据库取出所有数据时候调用排序函数来把所有的学生成绩根据算出的GPA进行排序,
    然后用表格控件来接受所有数据,再输出。

    六、界面添加学生成绩

    修改成绩

    查找结果

    GPA排名
    3 评论 440 下载 2018-11-01 20:33:19 下载需要8点积分
  • 基于MFC实现的图形绘图编辑系统

    一、课程设计目的
    学完《C语言程序设计》和《面向对象可视化编程》两门课程之后,进入到实践环节,通过一个简单的MFC的绘图程序来运用自己所学的知识,学会解决编程中遇到的问题。
    本课程设计可以提供一个稍微具有规模的程序开发的例子,让同学们可以体会到程序的构思、编码以及调试的完整过程,最后并总结课程设计的过程。
    通过本次课程设计,增强了自己对程序设计的认识,在不足的方面加强学习。

    二、课程设计的内容与设计思路2.1课程设计内容
    编写一个简单的图形编辑MFC程序,可以添加,修改与删除图形元素,以形成图形画面,如图2-1所示


    图上的黑点给图元的原点,w为宽度width,h为高度height,r为半径radius,a为字符角度angle。这些为这些图元需要保存的参数,另外,每个图元是否填充,用什么模式填充
    采用单文档方式,文档中存储图形画面的各个图元数据,视图负责图形的绘制
    文档支持图形的序列化(连载),提供新建、打开、保存等操作
    视图除了绘制图形,还提供图形交互,能够按住Ctrl键再鼠标左键单击来创建图元,鼠标左键双击编辑修改图元属性,鼠标右键双击删除图元
    图元创建与修改时的参数由参数对话框来编辑,参见对话框示例图2-2,创建时以鼠标左击时光标的所在位置作为基点来创建图元


    2.2 设计思路使用图元基础类shape作为所有六个图元类的基类,设计派生各个具体的图形类,要求支持上述功能,各个类之间的关系如图2-3 所示。

    三、程序实现过程与细节3.1 程序涉及到的函数列表及程序流程图函数定义与功能一览表



    函数 序号
    函数名
    函数定义
    函数定义所在文件
    函数功能




    1
    OnInitDialog()
    BOOL WAttribute::OnInitDialog()
    WAttribute.Cpp
    初始化对话框


    2
    OnCbnSelchangeCombo()
    Void WAttribute::OnCbnSelchangeCombo()
    WAttribute.Cpp
    选择图形类型


    3
    OnBnClickedLinecolor()
    void WAttribute::OnBnClickedLinecolor()
    WAttribute.Cpp
    选择颜色


    4
    OnBnClickedOk()
    void WAttribute::OnBnClickedOk()
    WAttribute.Cpp
    ok控件消息


    5
    ~CWDemoDoc()
    CWDemoDoc::~CWDemoDoc()
    WDemoDoc.cpp
    析构动态数组


    6
    Serialize()
    void CWDemoDoc::Serialize(CArchive& ar)
    WDemoDoc.cpp
    序列化函数


    7
    OnLButtonDown()
    void CWDemoView::OnLButtonDown(UINT nFlags, CPoint point)
    WDemoView.cpp
    左键功能函数


    8
    OnDraw()
    void CWDemoView::OnDraw(CDC* pDC)
    WDemoView.cpp
    绘图函数


    9
    OnRButtonDblClk()
    Void CWDemoView::OnRButtonDblClk(UINT nFlags, CPoint point)
    WDemoView.cpp
    右键功能函数


    10
    WShape()
    WShape::WShape()
    WShape.cpp
    图元基类默认构造函数


    11
    WSquare()
    WSquare::WSquare(int x, int y, int w)
    WSquare.cpp
    正方形类有参构造函数


    12
    WRectangle()
    WRectangle::WRectangle(int x, int y, int w, int h)
    WRectangle.cpp
    矩形类有参构造函数


    13
    Wcircle()
    WCircle::WCircle(int x, int y, int r)
    WCircle.cpp
    圆形类有参构造函数


    14
    WEllipse()
    WEllipse::WEllipse(int x, int y, int hr, int vr)
    WEllipse.cpp
    椭圆形类有参构造函数


    15
    WTriangle
    WTriangle::WTriangle(int x, int y, int length)
    WTriangle.cpp
    三角形类有参构造函数


    16
    WText()
    WText::WText(int x, int y, CString content)
    WText.cpp
    文本类有参构造函数


    17
    Draw()
    Void WSquare:: Draw(CDC pDC) Void WRectangle:: Draw(CDC pDC) Void WCircle:: Draw(CDC pDC) Void WEllipse:: Draw(CDC pDC) void WTriangle::Draw(CDC pDC) void WText::Draw(CDC pDC)
    WSquare.cpp WRectangle.cpp WCircle.cpp WEllipse.cpp WTriangle.cpp WText.cpp
    各种图形的绘制函数


    18
    Serialize()
    void WSquare::Serialize(CArchive & ar) void WRectangle::Serialize(CArchive & ar) void WCircle::Serialize(CArchive & ar) void WEllipse::Serialize(CArchive & ar) void WTriangle::Serialize(CArchive & ar) void WText::Serialize(CArchive & ar)
    WSquare.cpp WRectangle.cpp WCircle.cpp WEllipse.cpp WTriangle.cpp WText.cpp
    各种图形的序列化函数


    19
    IsMatched()
    bool WSquare::IsMatched(CPoint pnt) bool WRectangle::IsMatched(CPoint pnt) bool WCircle::IsMatched(CPoint pnt) bool WEllipse::IsMatched(CPoint pnt) bool WTriangle::IsMatched(CPoint pnt) bool WText::IsMatched(CPoint pnt)
    WSquare.cpp WRectangle.cpp WCircle.cpp WEllipse.cpp WTriangle.cpp WText.cpp
    图元匹配函数


    20
    SetAttribute()
    void WSquare::SetAttribute(int nX, int nY, COLORREF nBoderColor, int nBoderType, int nBoderWidth, COLORREF nFillColor, int nFillType) … void WText::SetAttribute(int nX, int nY, COLORREF nBoderColor, int nBoderType, int nBoderWidth, COLORREF nFillColor, int nFillType)
    WSquare.cpp WRectangle.cpp WCircle.cpp WEllipse.cpp WTriangle.cpp WText.cpp
    重置图元属性值函数



    程序流程图

    3.2 课程设计实现过程3.2.1 选择高级视图由于老师平时上课时,使用的都是经典的基础视图,而课程设计文档中的视图是高级视图,对比运行的视图,我尝试着把程序的视图设为和课程设计文档里面一样的(可参见图4-1)
    3.2.2 设计类和对话框3.2.2.1 设计类
    自己创建一个WShape(以W开头便于和MFC的类区分)图元类,派生图元类单独创建.h和.cpp文件,便于管理,虽然切换有些麻烦,但后期修改很方面,我没有像示例程序里面那样把所有的类都放在shape文件里面。
    基类是WShape

    数据成员:

    原点坐标(鼠标点击的点)旋转角度(单独为文本类设计,其他图形不使用)和线以及填充有关的属性字段
    成员函数

    有参数的构造函数绘制图元的函数判断鼠标点击的位置是否在图形内部的函数,是否打开属性设计窗口序列化数据的函数重新设置图元的属性的函数

    注意:要在每个派生类的.h头文件里面声明该类型支持序列化,并在.cpp源文件里面指定序列化的版本。
    例如:
    矩形类
    DECLARE_SERIAL(WRectangle)//声明类WRectangle是支持序列化IMPLEMENT_SERIAL(WRectangle, CObject, 1)//实现类WSquare的序列化,指定版本为1
    派生类

    正方形类Square,矩形类Rectangle,对于正方形类,除了基类WShape之外的数据成员外,有一个独立的width数据,而矩形类只是在此基础上加上一个height数据,两者的绘图原理是一样的,CDC类的pDC对象中有绘制矩形的函数
    圆类Circle,椭圆类Ellipse,椭圆类既有长半轴,也有短半轴,两者的绘图原理是一样的,使用CDC类的pDC对象中绘制椭圆的函数
    三角类Triangle,使用CDC类的pDC对象中绘制多边形的Polygon函数(图片),参看微软官网上的函数用法,要把多边形的顶点放在一个坐标点数组里面,并指定多边形的顶点的个数
    文本Text类,采取自定义的字体来实现,旋转角度是自定义字体的一个参数

    解决方法
    使用CreateFontIndirect(const LOGFONT* lpLogFont)函数创建斜率字体,参数lpLogFont->lfEscapement是字体的角度。
    //创建自己的字体LOGFONT logfont;lstrcpy((LPSTR)logfont.lfFaceName,(LPSTR)"楷体_GB2312");logfont.lfWeight=700;logfont.lfWidth=40;logfont.lfHeight=70;logfont.lfEscapement=angle;//这个参数就是用来控制角度,这里是正常显示logfont.lfUnderline=FALSE;logfont.lfItalic=FALSE;logfont.lfStrikeOut=FALSE;logfont.lfCharSet=GB2312_CHARSET;hFont=CreateFontIndirect(&logfont);……// 下面就是使用该字体了hOldFont=(HFONT*)dc.SelectObject(hFont);
    3.2.2.2 设计对话框
    使用MFC的控件,来搭建对话框的界面,适当修改控件的ID值
    Combobox下拉框控件
    所用的函数GetCurSel()来获取鼠标焦点的值的序号,注意下拉框的sort属性,默认是true,会按照自然排序,这样和你添加内容的顺序就会不一样,可以改为falseAddString()来向下拉框控件里面添加内容,也可以到VS2015的属性框里面的data属性里面添加,Ctrl+Enter换行。
    Listbox列表框控件
    所用的函数GetCurSel()来获取鼠标焦点的值的序号;AddString()来向列表框控件里面添加内容。
    MFC ColorButton颜色选取控件
    所用的函数Getcolor()获取当前选择的颜色,类型是COLORREF,以RGB的形式储存
    Static Text静态文本控件
    用来制作前台界面。
    Edit Control编辑文本控件
    用来让用户输入参数值。
    3.3 View文件和Doc文件中的代码细节3.3.1 和对话框相关的功能使用控件的消息映射以及相关的成员函数来实现。
    初始化对话框(初始化函数)
    向下拉框以及列表框里面添加内容
    BOOL WAttribute::OnInitDialog()
    选择图形类型(控件消息)
    当用户选择的不是文本类型的对话框,就把和文本框有关的控件隐藏,得到下拉框所选序号,来判断是否要隐藏
    void WAttribute::OnCbnSelchangeCombo()
    选择颜色(控件消息)
    获取边框线型的颜色以及填充颜色,因为我这里定义的是颜色控件变量是control的变量类型,所以还要使用该类型的函数才能获取颜色的color值,其实如果仅是为了获取颜色值,可以直接给该控件绑定一个value的变量类型,我在这里还对颜色控件做了一些定制,详细代码见初始化对话框函数。
    void WAttribute::OnBnClickedLinecolor()
    ok控件(控件消息)
    把一些想在对话框点击确定后想保存的值:下拉框的选项,列表框的选项保存下来,供view文件使用,采取在对话框类里面自定义变量来实现
    void WAttribute::OnBnClickedOk()
    3.3.2 Doc数据文件使用一个动态数组来存放视图中绘制的图形的数组,则每个绘制图形就是数组中的一个元素。
    动态数组的实现原理:添加新的元素后,就把当前所有的元素copy以及新增的元素,再开辟一块新的内存空间来存放新的数组,实际上也是通过静态的普通数组来实现的。
    CObArray m_Elements;
    析构函数,释放每个图形的所占用的资源,以及这个动态数组。
    CWDemoDoc::~CWDemoDoc(){ //析构 父类指针指向的图形资源 函数 int i; WShape* p; if (m_Elements.GetCount() > 0) { for (i = 0; i < m_Elements.GetCount(); i++) { p = (WShape*)m_Elements[i]; delete p; } } m_Elements.RemoveAll();//释放数组}
    序列化函数,每个数组元素调用自己的序列化函数,面向对象的封装思想。
    void CWDemoDoc::Serialize(CArchive& ar){ m_Elements.Serialize(ar);}
    3.3.3 View视图文件鼠标左键加上Ctrl键弹出对话框功能

    设备坐标转化为逻辑坐标
    判断Ctrl键是否按下,来决定是否创建一个对话框
    获取鼠标点击的位置,要放在对话框对象之后,对话框弹出之前
    弹出对话框后根据用户选择的图形类型来创建相对应的图形及文本,我这里是通过比较用户选择的序号,用switch语句实现的
    每次在创建图形后要把它加入到动态数组中,最后刷新界面窗口,调用View文件的OnDraw函数绘制对应的图形

    只按下鼠标左键,而没有按下Ctrl键,则需要判断鼠标当前的落点又没在某个图形内

    把当前图形的相关参数传入到对话框中,供用户修改图形的相关的参数
    当用户按下OK键后,再把对话框界面的值传入到当前图形中,重新设置图元的属性的函数,这样刷新窗口后就改变当前图形

    void CWDemoView::OnLButtonDown(UINT nFlags, CPoint point)
    双击鼠标右键删除当前图元
    这个消息映射需要在使用时,需要注意把MFC框架自带的鼠标右键消息禁用,不然会有冲突。

    还是先把设备坐标转化为逻辑坐标
    用父类指针指向子类对象,调用子类对象的IsMatched函数,循环查找用户选中的是动态数组中的哪个图形,找到后使用动态数组对象自带的删除元素函数删除
    刷新窗口,图形消失
    绘图函数

    每次刷新完窗口后,执行这个这个函数,就会重新绘制view窗口。
    void CWDemoView::OnDraw(CDC* pDC){ CWDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 int i; WShape* p; if (pDoc->m_Elements.GetCount() > 0) { for (i = 0; i < pDoc->m_Elements.GetCount(); i++) { p = (WShape*)pDoc->m_Elements[i]; p->Draw(pDC); } }}
    四、运行效果4.1 运行初始画面
    4.2 弹出对话框画面
    4.3 创建图形和文本创建正方形,矩形,椭圆形,圆形,三角形,文本的过程。














    4.4 更改图形属性
    4.5 删除图形双击右键删除图形

    4.6 保存文档
    4.7 打开保存的文档打开刚才保存的文档,重新恢复图形画面

    五、设计小结通过这次课程设计,自己能够更好的查找网上资料,MFC的编程手册,自己独立解决问题的能力得到了提高,很感谢指导老师帮我解决我程序中的困惑之处。
    2 评论 14 下载 2019-03-08 17:39:45 下载需要9点积分
  • 基于JSP和MYSQL实现的图书馆管理系统

    一、概述基于Spring + Spring MVC + MyBatis的图书馆管理系统,使用Maven进行包管理。主要功能包括:图书查询、图书管理、图书编辑、读者管理、图书的借阅与归还以及借还日志记录等。
    二、环境配置2.1 开发环境
    Windows 10
    IntelliJ IDEA 2018.3

    2.2 运行配置
    首先安装Mysql5.7,设置用户名为root,密码为123456,并保证其在运行状态,并执行library.sql文件导入数据
    然后再配置Maven到环境变量中,在源代码目录下运行
    # mvn jetty:run
    使用浏览器访问 http://localhost:8080 即可进入系统

    三、概念设计用户分为两类:读者、图书馆管理员。图书馆管理员可以修改读者信息,修改书目信息,查看所有借还日志等;读者仅可以修改个人信息、借阅或归还书籍和查看自己的借还日志。


    四、数据库E-R图
    五、逻辑设计共有6个表:
    5.1 图书书目表book_info


    字段
    类型
    长度
    小数点
    NULL
    用途





    book_id
    bigint
    20
    0

    图书号



    name
    varchar
    20
    0

    书名



    author
    varchar
    15
    0

    作者



    publish
    varchar
    20
    0

    出版社



    ISBN
    varchar
    15
    0

    标准书号



    introduction
    text
    0
    0

    简介



    language
    varchar
    4
    0

    语言



    price
    decimal
    10
    2

    价格



    pub_date
    date
    0
    0

    出版时间



    class_id
    int
    11
    0

    分类号



    number
    int
    11
    0

    剩余数量



    5.2 数据库管理员表admin


    字段
    类型
    长度
    小数点
    NULL
    用途





    admin_id
    bigint
    20
    0

    账号



    password
    varchar
    15
    0

    密码



    username
    varchar
    15
    0

    用户名



    5.3 图书分类表class_info


    字段
    类型
    长度
    小数点
    NULL
    用途





    class_id
    int
    11
    0

    类别号



    class_name
    varchar
    15
    0

    类别名



    5.4 借阅信息表lend_list


    字段
    类型
    长度
    小数点
    NULL
    用途





    ser_num
    bigint
    20
    0

    流水号



    book_id
    bigint
    20
    0

    图书号



    reader_id
    bigint
    20
    0

    读者证号



    lend_date
    date
    0
    0

    借出日期



    back_date
    date
    0
    0

    归还日期



    5.5 借阅卡信息表reader_card


    字段
    类型
    长度
    小数点
    NULL
    用途





    reader_id
    bigint
    20
    0

    读者证号



    password
    varchar
    15
    0

    密码



    username
    varchar
    15
    0

    用户名



    5.6 读者信息表reader_info


    字段
    类型
    长度
    小数点
    NULL
    用途





    reader_id
    bigint
    20
    0

    读者证号



    name
    varchar
    10
    0

    姓名



    sex
    varchar
    2
    0

    性别



    birth
    date
    0
    0

    生日



    address
    varchar
    50
    0

    地址



    phone
    varchar
    15
    0

    电话



    六、功能展示6.1 首页登陆
    管理者账号:123456/123456
    读者账号:10000/123456


    6.2 管理员系统6.2.1 图书管理
    6.2.2 图书详情
    6.2.3 读者管理
    6.2.4 借还管理
    6.3 读者系统6.3.1 查看全部图书
    6.3.2 个人信息查看,可以修个个人信息
    6.3.3 个人借阅情况查看
    1 评论 20 下载 2019-05-09 11:00:42 下载需要13点积分
  • 基于JSP和MYSQL实现的学生成绩管理系统

    1 概述1.1 开发背景随着学生数量的日渐增多,学生教务系统的数据量也不断增加,这无疑大大增加了教务系统的负担。如果能把负责学生成绩管理的模块独立出来形成一个独立的系统,便可以有效降低教务系统的数据量,不仅可以方便管理员对于所有学生的信息进行系统的管理,而且便于教师对学生成绩进行查询和修改,学生也可以查询自己的成绩。一个好的学生管理系统,正好可以满足当前的市场需求,提高工作效率,并取得一定的经济效益。本系统的创建就是为了减少人力、物力、时间的耗费。这些优点能够极大地提高学生成绩管理的效率。因此,开发一套合适的、兼容性好的系统是很有必要的。
    1.2 开发目标在规定的时间和经济范围内,交付一个基于JSP/SEVLET的成绩管理系统,该系统具备一下要求:

    有良好的前端展示,符合商业化的要求,同时便于用户操作,可以轻松上手
    具有可靠性,系统不同角色分配的权限合理,不泄露用户信息
    可以批量录入信息,实现对信息的增删改查
    反应迅速,能及时给出反馈

    1.3 设计原则为了保持良好的用户体验,设计系统的时候需要遵循以下通用原则:

    设计适当的表示导引。在用户浏览网站的时候,随时告知访问者他们身处何处,想要找的东西在哪里,如何找到想要找的东西
    设定期望并做出反馈。当用户提交表单,点击链接的时候,成功与否都需要网页及时给出反馈,保证用户不会因为久久得不到回复而对网站不信任
    设计要基于人机工程学。无论是字体、字号、字色、字间距的选择还是按钮的放置位置,按钮的数量等,这些都要考虑到用户的身体,即手、目、耳等
    考虑标准,保持一致。设计网站切不可因为如何好看如何设计,一定要保持前后风格一致
    考虑辨识。用户不喜记忆,所以网站设计一定要具有记忆,访问前后不能靠用户去辨识记忆
    考虑用户水平不一样。我们遵循的原则是做最简单的网站,然后再在其基础上添加特殊的功能和属性

    2 关键技术分析2.1 前端2.1.1 前端界面优化为了保证良好的用户体验,我们以HTML语言与CSS样式表为基础制作页面,js进行页面与组件间的逻辑实现。在界面美化上,我们保证所有页面风格一致,并具有自适应性的功能,可以随着分辨率的大小和设备的大小而变化,同时,也注意了不同代码在浏览器兼容性上的问题,所以在相应CSS文件里添加了不同浏览器所需的备用样式。在配色和布局上参考了一些优秀网站的设计,保证良好的交互性。
    2.1.2 前端技术前端主要使用html、css、js等基本技术,此外还用到bootstrap、jQuery、jstl等技术使得前端交互性增强。页面布局多采用相对布局,放大或缩小页面,页面内容分仍保持相对位置。
    Frame框架:用于实现页面的局部加载和刷新。
    jQuery技术:为了可以直接在某条记录上动态修改数据(即直接在当前页面修改而不是重新打开一个修改数据的页面),采用了jQuery技术,实现了在记录原位置直接修改数据。
    Echarts:为了使数据可视化,我们采用了百度的Echart图表技术http://echarts.baidu.com ,将数据如学生的成绩、课程的及格率等以条形统计图、动态水球图的形式展现,使得教师可以方便直观地分析学生的成绩情况(各分数段的人数,及格率等)。
    Ajax:AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。AJAX 通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重载整个页面的情况下,对网页的某些部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个页面。
    JSON: JavaScript Object Notation(JavaScript 对象表示法)JSON 是存储和交换文本信息的语法。类似 XML,比 XML 更小、更快,更易解析,是一种轻量级的数据传输方式。
    2.2 后端2.2.1 数据访问方式(DAO)DAO (DataAccessObjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。
    DAO 模式提供了访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口。
    DAO 模式的优势就在于它实现了两次隔离。

    隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性
    隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQL 实现不用修改。这符合”开-闭”原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性

    2.2.2 后端逻辑处理使用了三层架构(web层、service层和dao层)

    Controller层:(也叫web层)Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程。
    Service层:Service层主要负责业务模块的逻辑应用设计。调用DAO层存取数据。
    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰。

    该三层架构的优点:

    开发人员可以只关注整个结构中的其中某一层
    可以很容易的用新的实现来替换原有层次的实现
    可以降低层与层之间的依赖
    有利于标准化
    利于各层逻辑的复用
    结构更加的明确
    在后期维护的时候,极大地降低了维护成本和维护时间

    2.3 数据库2.3.1 数据库的连接该系统采用mysql数据库,连接数据库用到jdbc数据库驱动。当系统比较庞大时,可以使用数据库连接池如c3p0、DBCP等。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
    2.3.2 数据库的设计该系统使用关系型数据库,建表时采用关系模型的数据结构,每个实体对应一张表,联系若有属性,也可对应一张表,如学生实体对应一张学生表,课程对应一张课程表,课程和学生之间是学习的关系,他们会产生一个属性-分数,因此也应该有一张学生课程表。
    设置表的主键、外键以及表之间的级联关系。如:成绩表中的学生必须是学生表中存在的学生,当删除学生表中某一个学生时,若两张表是级联删除关系时,成绩表中该学生的信息自动删除。更新时也一样。这样避免了后端逻辑实现的复杂性。
    2.4 服务器使用Tomcat服务器。Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。
    2.5 文件上传2.5.1 图片上传用到的工具:

    对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件。这个common-fileupload上传组件的jar包可以去apache官网上面下载common-fileupload是依赖于common-io这个包的。
    图片的储存(存取图片的相对路径而不是图片):
    如果直接将图片以二进制流的形式存到数据库中,既浪费时间有浪费空间,因而我们采用的方式是将图片的相对路径存到数据库中,这样极大地提高了访问数据库的速度,同时提高了数据库的空间利用率。
    2.5.2 批量导入数据(上传读取Excel)用到的工具:

    Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
    JXL只能对Excel进行操作,属于比较老的框架,它只支持到Excel 95-2000的版本。现在已经停止更新和维护。
    POI是apache的项目,可对微软的Word,Excel,ppt进行操作,包括office2003和2007,Excl2003和2007。poi现在一直有更新。所以现在主流使用POI。
    2.6 安全机制2.6.1 登录验证该系统有学生、教师和管理员三种不同身份的用户,系统分别为设置权限等级,当某用户登录时,系统会检索他们的等级,让他们访问对应的操作页面,学生进入学生系统模块,教师进入教师系统模块,管理员进入管理员系统模块。
    2.6.1 Filter技术用户可以通过url访问系统资源,对于一些敏感保密的资源需要有保护机制,因此采用filter技术。
    Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
    同时,为了防止页面出现乱码,该系统中添加了编码过滤器。
    在该系统中,使用了过滤器,防止用户直接通过URL地址栏直接进入该系统,实现原理是,在过滤器中添加一个判断,判断用户的身份信息是否在session中,只有通过登录身份验证正确时,用户的身份才会添加到session,否则session中无该用户信息,过滤器将阻止非法访问。
    2.7 Junit4单元测试开发过程中采用Junit4单元测试技术,分别测试各个子功能模块的功能。
    在项目开发中,主要来测试DAO层(数据持久层)的数据的查询增删改功能,确保和数据库实现正确的数据存取功能。
    public class UserDaoTest { @Test public void selectUser() throws Exception { UserDao userDao = DaoFactory.getUserDaoInstance(); System.out.println(userDao.selectUser("123", "124")); } @Test public void insertUser() throws Exception { User user = new User("41612197", "123", "3"); UserDao userDao = DaoFactory.getUserDaoInstance(); userDao.insertUser(user); }
    3 系统需求分析3.1 可行性分析本节主要从经济可行性、技术可行性、操作可行性和法律可行性进行分析。
    3.1.1 经济可行性从经济可行性分析来讲,环境拥有建立该系统所需的网络设备及软件,具备了开发Web平台系统的基本条件;系统投资成本低,回报率高;人力资源方面消耗量少;而且,系统的生存周期短、系统工作负荷量不是很大、处理速度要求快。无论从横向还是纵向相比,本系统都是可以实行的。在线购物系统的设计和开发不仅是电子商务领域的重要组成部分,也是管理信息系统应用的主要方向之一。经以上分析,该系统可行。
    3.1.2 技术可行性从技术可行性来讲,本系统是基于jsp的Web开发的,jsp 是在前段和后端分离下产生的框架技术,已经被大家公认为经典的框架。而且,Java 语言技术也具有卓越的通用性、高效性、平台移植性和安全性,比较适合这个系统的开发和应用。在软件方面,考虑到系统实施的可行性,选择了现今比较流行的开发工具intelijidea进行开发管理平台的设计,使用MySQL数据库存储数据。
    在硬件方面,系统只需要一台内存4G,硬盘在500.0G的品牌机或兼容机。经以上分析,该系统可行。
    3.1.3 操作可行性本系统界面友好、整洁,操作简易,并配有相关说明,学习方便,管理人员对开发此应用系统的态度确定。
    经过以上分析,该系统可行。
    3.1.4 法律可行性考虑到使用到的软件产品的版权问题,软件服务器所使用的软件,应该尽量使用正版软件。如果正版软件价格高得难以接受,可以采用一些能满足系统运行的免费软件来替代。开发阶段可以使用试用版软件来替代,但正式发布时建议操作系统采用正版软件。
    该平台是作为课程设计,与商业无关,又因为是自主开发设计,因此不会构成侵权,在法律上可行。
    3.2 功能模块需求分析本节主要通过系统的主功能模块划分以及系统用例图来分析系统需求。
    3.2.1 主要功能模块划分学生成绩管理系统分为三个模块:学生模块、教师模块和管理员模块。

    学生模块的功能:个人信息的查询,部分信息的修改,本人成绩的查询
    教师模块的功能:个人信息的查询,成绩的录入、修改、查看和分析
    管理员模块的功能:对学生、教师、班级、课程的增删改查,课程的安排,系统用户的添加和删除,为学生分配班级等

    对于各功能的详细介绍,如表3-1所示:

    3.2.2 系统用例图根据3.2.1的主功能模块分析,学生成绩管理系统包括三个参与者:学生、教师、管理员。根据不同身份的用户和系统的交互活动不同,可以画出如下用例图:

    3.3 非功能性需求分析3.3.1系统的安全性通常在描述学生成绩管理系统安全性时,越是薄弱的部分,则往往越会受到攻击的影响。因为在攻击者在对系统进行攻击行为时,无论其出于何种目的,往往会找出该系统最易攻击的环节,从而沿阻力最小的路径行动。
    通常我们在使用系统的时候,都会经登录,输入所需的用户名及对应密码。为防止偷窥造成的密码泄露,而在对外显示时都会以“*”作为输入字符的代号。用户在登录时所使用的账号必须是数据库中已存的,且所输入的账号密码必须与数据库中存储的账号密码一致,否则都会造成登陆失败。无论是管理员还是学生或教师,为了报障学生信息系统的安全性,都必须要经过登陆方能进入系统。
    3.3.2 系统的可靠性为了防止用户的非法操作,系统通常会对不同用户提供不同的服务,并对其设置不同的操作权限。管理员可以使用基于Web的学生成绩管理系统甚至所有功能,性能可靠稳定。
    3.3.3 系统的易实用性和可扩展性一个完善的操作系统应具备以下特点:为保证系统界面具有操作简单,界面的设计以美观大方为主;系统还应该具备展示学生信息的功能,从而方便用户进行学生课程信息的浏览或比较;为方便教师分类查找,系统应该对学生的课程分类采取规范管理;为方便教师进行修改确认行为,我们队每个用户的使用权限加以完善;让学生及教师对系统内的信息修改具有自己可以操作的部分。除此之外,还有管理员的信息查询、访问次数的信息查询、成绩排行公示等功能,此外,为了方便管理者管理与教师进行成绩更新学生信息,还设置并完善的后台管理功能。
    4 系统概要设计4.1 系统概述学生信息管理系统主要包括三大模块:学生模块、教师模块和管理员模块。学生模块的功能有:查看和修改个人信息,查看成绩。教师模块的功能有:查看和修改个人资料,录入学生成绩、查看学生成绩、成绩的统计与分析。管理员模块的功能有:学生信息管理、教师信息管理、课程信息管理、班级信息管理(班级的查询增删)、安排课程、系统用户管理等。
    4.2 系统结构图
    4.3 系统结构分析学生成绩管理系统分为学生、教师和管理员三大模块。每个模块有分为几个子功能模块。这些子模块分别实现了不同的功能,学生模块的查询成绩功能,教师模块的个人信息管理、成绩的查询录入功能、系统统计分析成绩功能,管理员的学生信息管理、教师信息管理、基本信息管理和系统用户信息管理。
    学生登录后可进行的操作:

    查看个人资料(包括姓名、学号、照片、年级、联系方式和住址等)
    修改个人资料
    查询分数

    教师登陆后可进行的操作:

    查看个人资料(包括姓名、工号、照片、学位、职位等)
    修改个人资料
    录入学生成绩(可以批量导入)
    修改成绩
    查询学生成绩(可以根据课程名查询,也可以根据学号查询)
    成绩分析统计查询(系统统计分析每门课各个成绩段分布的人数,课程的及格率等,以条形图)

    管理员登陆后可进行的操作:

    管理学生信息(学生的添加删除等,可以批量导入)
    管理教师信息(教师的添加删除)
    基本信息管理(课程添加删除、班级添加删除、课程安排)
    系统用户信息管理(添加或删除系统用户,信息包括用户名、密码和权限等)

    4.4 数据库的设计与实现本系统采用mysql数据库,系统数据库名为ccs.数据库中有10张表。下面分别介绍不同的表。
    4.4.1 数据表的概述系统中包括:学生表(student)、教师表(teacher)、班级表(class)、课程表(course)、成绩表(score)、学生班级(student_class)、教师课程(teacher_class)、教师班级(teacher_class)、课程安排表(course_arrange)、系统用户表(user)
    4.4.2 数据表的结构student(学生表)
    学生表主要存取学生的学号、姓名、性别、年龄、专业、入学年份、电话、地址、照片,表结构如表4-1所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    studentId
    int
    11
    学生编号


    2
    studentName
    varchar
    255
    学生姓名


    3
    sex
    varchar
    255
    性别


    4
    age
    int
    20
    年龄


    5
    major
    varchar
    255
    专业


    6
    yearSchool
    int
    255
    入学年份


    7
    telephone
    varchar
    255
    电话号码


    8
    address
    varchar
    255
    地址


    9
    photo
    varchar
    255
    照片



    teacher(教师表)
    教师表主要存取教师的教师号、姓名、性别、学院、职位、学位、照片表结构如表4-2所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    teacherId
    int
    11
    教师编号


    2
    teacherName
    varchar
    255
    教师姓名


    3
    sex
    varchar
    255
    性别


    4
    college
    varchar
    255
    学院


    5
    professionalTitle
    varchar
    255
    职称


    6
    degree
    varchar
    255
    学位


    7
    photo
    varchar
    255
    照片



    class(班级表)
    班级表主要存取班级号、班级名称、学院,表结构如表4-3所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    classId
    int
    11
    班级编号


    2
    className
    varchar
    255
    班级名称


    3
    ofCollege
    varchar
    255
    学院



    score(成绩表)
    成绩表主要存取学生的学号、姓名、课程号、课程名、成绩。表结构如表4-4所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    studentId
    int
    11
    学生编号


    2
    courseId
    int
    11
    课程编号


    3
    studentName
    varchar
    255
    学生姓名


    4
    courseName
    varchar
    255
    课程名称


    5
    grade
    int
    5
    分数



    studentclass(学生\班级表)
    学生班级班级表主要存取学生学号、学生姓名、班级号、班级名,表结构如表4-5所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    studentId
    int
    20
    学生编号


    2
    studentName
    varchar
    255
    学生姓名


    3
    classId
    int
    11
    班级编号


    4
    className
    varchar
    255
    班级名称



    teacherclass(教师\班级表)
    教师班级表主要存取教师号、教师姓名、班级号、班级名称,表结构如表4-6所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    teacherId
    int
    11
    教师编号


    2
    teacherName
    varchar
    255
    教师姓名


    3
    classId
    int
    11
    班级编号


    4
    className
    varchar
    255
    班级名称



    teacher_course(教师课程表)
    教师课程表主要存取教师号、教师名称、课程号、课程名,结构如表4-7所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    teacherId
    int
    11
    教师编号


    2
    teacherName
    varchar
    255
    教师姓名


    3
    courseId
    int
    11
    课程编号


    4
    courseName
    varchar
    255
    课程名称



    course_arrange(课程安排表)
    课程安排表是存取课程安排信息。主要存取教师号、教师名、课程号、课程名、班级号、班级名。结构如表4-8所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    classId
    int
    11
    班级编号


    2
    className
    varchar
    255
    班级名称


    3
    courseId
    int
    11
    课程编号


    4
    courseName
    varchar
    255
    课程名称


    5
    teacherId
    int
    11
    教师编号


    6
    teacherName
    varchar
    255
    教师姓名



    course(课程表)
    课程表存取的是课程信息,包括课程号、课程名、学分,结构如表4-9所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    courseId
    int
    11
    课程编号


    2
    courseName
    varchar
    255
    课程名称


    3
    credit
    float
    10
    课程学分



    user(系统用户表)
    系统用户表存取的是该系统的用户的账号密码信息,结构如表4-10所示:



    序号
    字段名
    类型
    长度(字符)
    描述




    1
    username
    varchar
    255
    用户名


    2
    password
    varchar
    255
    密码


    3
    superuser
    varchar
    255
    超级用户



    4.4.3 ER图(实体-联系图)系统整体的实体关系图

    班级信息实体E-R图

    学生信息实体E-R图

    教师信息实体E-R图

    课程信息实体E-R图

    成绩信息实体E-R图

    课程安排信息实体E-R图

    学生班级信息实体E-R图

    教师班级信息实体E-R图

    教师课程实体E-R图

    系统用户信息实体E-R图

    4.5 系统活动图活动图(activity diagram,动态图)是阐明了业务用例实现的工作流程。业务工作流程说明了业务为向所服务的业务主角提供其所需的价值而必须完成的工作。业务用例由一系列活动组成,它们共同为业务主角生成某些工件。工作流程通常包括一个基本工作流程和一个或多个备选工作流程。工作流程的结构使用活动图来进行说明。
    4.5.1 学生活动图
    4.5.2 教师活动图
    4.5.3 管理员活动图
    5 详细设计与实现完成系统分析与概要设计后,系统的主要功能已经确定,最后通过编写代码来实现系统的设计。本章主要介绍学生成绩管理系统的实现,从而对系统有了视觉上的了解。
    5.1 代码约定5.1.1 前端代码约定
    使用正确的文档类型:始终在文档的首行声明文档类型:<!DOCTYPE html>
    使用小写元素名:混合大小写名称容易混乱;
    关闭所有 HTML 元素,空的也要关闭
    使用小写属性名
    属性值加引号(如果属性值包含值,则必须使用引号)
    始终对图像使用alt属性
    始终定义图像尺寸,浏览器会在图像加载之前为图像预留空间,可减少闪烁,
    避免长代码行,关键代码处添加注释
    用简单的语法链接样式表与JavaScript,尽量不要写在一个文件里
    文件命名使用小写,避免大小写混用

    5.1.2 后端代码约定
    文件编码:源文件编码格式为UTF-8。
    包名使用小写字母
    import不要使用通配符。即,不要出现类似这样的import语句:import java.util.*
    列长限制:一个项目可以选择一行120个字符的列限制,超出列长限制时换行,换行时缩进至少4个空格,缩进不要用tab
    注释:注释应少而精,代码的关键处应该有注释, 注释不能误导读者
    变量声明:每次只声明一个变量,不要使用组合声明,比如int a, b;需要变量时才声明,并尽快进行初始化
    命名约定:命名应该见名知意、简洁,避免拼音与英文混用
    命名风格:类名以UpperCamelCase风格编写;非常量字段名、方法名、参数名、局部变量名以lowerCamelCase风格编写;常量名以CONSTANT_CASE风格编写
    类成员顺序:每个类应该以某种逻辑去排序它的成员,维护者应该要能解释这种排序逻辑。比如,新的方法不能总是习惯性地添加到类的结尾。


    使用log而不是System.out.println()
    大括号与if, else, for, do, while语句一起使用,即使只有一条语句(或是空),也应该把大括号写上
    减少代码嵌套: (1)合并条件;(2)利用return以省略后面的else;(3)使用子方法
    异常处理:捕获的异常不能忽视,典型的响应方式是打印日志。

    5.2 登录模块5.2.1 登录模块功能和技术实现介绍该模块是进入系统的统一入口,用户需要输入用户名和密码信息,验证通过后才能进入主系统界面。在这里,系统可以根据用户的账号识别出用户的身份,进而导航到不同的主操作界面。
    技术:判断用户输入的信息与数据库中的用户信息进行对比,判断该用户是否输入正确的验证信息,如果身份信息正确,则根据其权限等级导航到对应的主界面。
    此外用到filter技术,防止通过在URL地址栏中直接输入统一资源定位符获取到敏感页面。
    5.2.2 截图展示
    5.2.3 关键代码//验证用户身份信息并匹配不同主页面public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username); System.out.println(password); String str = loginService.login(username, password); HttpSession session = request.getSession(); session.setAttribute("username", username); session.setAttribute("superuser", str); if (str != null) { String s=null; switch (str){ case "1": s = "student"; break; case "2": s = "teacher"; break; case "3": s = "admin"; break; } String path ="/jsp/"+s+"/framework" + s + ".jsp"; request.getRequestDispatcher(request.getContextPath() +path).forward(request,response); } else { response.sendRedirect(request.getContextPath() + "/index.jsp"); }//过滤器:public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; HttpSession session = httpServletRequest.getSession(); if (session.getAttribute("username") == null || session.getAttribute("username").equals("")) { httpServletRequest.getRequestDispatcher("index.jsp").forward(servletRequest, servletResponse); }else { filterChain.doFilter(servletRequest, servletResponse); }}
    5.3 学生模块5.3.1 查询和修改个人资料功能介绍
    学生可以点击个人资料查看自己的个人信息,同时可以更新自己的照片,同时还有动态时钟显示。点击不同的指针可以查看月份、星期、时、分、秒。
    截图展示

    关键代码
    //图片上传(图片上传是上传到服务器,然后将图片的相对路径存到数据库)protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(req)) { PrintWriter writer = resp.getWriter(); writer.println("Error: 表单必须包含 enctype=multipart/form-data"); writer.flush(); return; } // 配置上传参数 DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中 factory.setSizeThreshold(MEMORY_THRESHOLD); // 设置临时存储目录 factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); ServletFileUpload upload = new ServletFileUpload(factory); // 设置最大文件上传值 upload.setFileSizeMax(MAX_FILE_SIZE); // 设置最大请求值 (包含文件和表单数据) upload.setSizeMax(MAX_REQUEST_SIZE); // 中文处理 upload.setHeaderEncoding("UTF-8"); // 构造临时路径来存储上传的文件 // 这个路径相对当前应用的目录 String uploadPath = getServletContext().getRealPath("/") + File.separator + UPLOAD_DIRECTORY; // 如果目录不存在则创建 File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); }//时钟显示(调用Echart图表,加载到该jsp文件中)部分代码:option3 = { tooltip: { // formatter: "{a}:{c}" backgroundColor: '#fff', borderColor: '#f60', borderWidth: '1px', textStyle: { color: '#333' }, formatter: function(param) { var time = Math.floor(param.value); if (param.seriesIndex === 0) { return '<em style="color:' + param.color + ';">当前小时:' + time + '</em>' } if (param.seriesIndex === 1) { return '<em style="color:' + param.color + ';">当前星期:' + time + '</em>' } if (param.seriesIndex === 2) { return '<em style="color:' + param.color + ';">当前月份:' + time + '</em>' }
    5.3.2 查询成绩功能介绍
    学生点击查询成绩可以看到自己每门课的成绩。
    截图

    关键代码
    从数据库中获取到成绩,在jsp页面中通过jstl中的遍历,将信息逐条显示。
    <% String username = (String) session.getAttribute("username"); List<Score> scoreList = (List) session.getAttribute("scoreList"); session.setAttribute("scoreList", scoreList);%><c:forEach var="sl" items="${scoreList}"> <tr> <td>${sl.studentId}</td> <td>${sl.courseId}</td> <td>${sl.studentName}</td> <td>${sl.courseName}</td> <td>${sl.grade}</td> </tr></c:forEach>
    5.4 教师模块5.4.1 查询和修改个人资料功能介绍
    教师可以查看个人信息,可以更新个人照片。
    功能截图

    5.4.2 录入学生成绩功能介绍
    教师可以通过两种方式录入学生成绩:手动一个一个输入和导入Excel成绩单。
    运行截图
    手动输入截图:

    Excel导入成绩结果:

    5.4.3 查询和修改成绩功能介绍
    教师可以输入课程名查询这门课的成绩,也可以输入学号查询某个学生的成绩,还可以直接修改成绩
    关键技术
    修改成绩时,用到了jQuery技术,遍历选中的某条记录,将其table标签变为input标签,并将原来的值保存并显示到input标签中。另外按钮的状态也在改变,有修改变为确定,点击“确定”,按钮重新变为“修改”。
    Ajax传值和json:将修改后的数据传到后端时,采用了ajax传值方式,将修改后的数据以json的形式传到后端,在后端通过解析,然后保存到数据库,将修改是否成功信息返回前端。
    运行截图



    5.4.4 统计分析学生成绩功能介绍
    教师在该功能中可以查看不同课程的各分数段人数以及该门课程的及格率。具体信息通过条形图和水球图展示。还可以同时分析多门课程的最高分、最低分、平均分等,可以查看表格数据、折线统计分析、条形堆叠统计分析、条形图统计分析等多种方式浏览分析结果,并且可以将分析结果下载为图片。
    在多门课成绩统一分析时,可以点击不同按钮,分别显示最高分、最低分、平均分等
    通过点击图表右侧的按钮,可以查看表格数据、折线统计分析、条形堆叠统计分析、条形图统计分析等多种方式浏览分析结果,并且可以将分析结果下载为图片。
    关键技术
    该功能用到了Echart技术,ajax技术,加载页面时通过ajax请求学生的成绩信息,将获取的值,赋给有JavaScript写好变量中。
    运行截图







    关键代码
    //分数统计passrate=(float) (num2+num3+num4)/(num1+num2+num3+num4);System.out.println("及格率为" + passrate);list.add(new ScorePeople("不及格", num1, passrate));list.add(new ScorePeople("60-69", num2));list.add(new ScorePeople("70-89", num3));list.add(new ScorePeople("90-100", num4));ObjectMapper mapper = new ObjectMapper();//提供java-json相互装换功能//综合分析var posList = [ 'left', 'right', 'top', 'bottom', 'inside', 'insideTop', 'insideLeft', 'insideRight', 'insideBottom', 'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'];
    5.5 管理员模块主要有四大功能木块:学生信息管理、教师信息管理、基本信息管理(班级、课程、课程安排)、系统用户信息管理
    5.5.1 学生信息管理功能介绍
    管理员可以查看、添加和删除学生信息,有两种添加方式:添加单个学生和批量导入学生信息。
    关键技术
    多级联动——在单个添加学生信息使,在选择学院、专业和班级时,使用了多级联动技术,即选择某个学院、专业的选项显示不同。班级也一样,比如选择了计算机科学学院,那么专业选项中只包含“计算机科学与技术(师范),计算机科学与技术(创新实验班),软件工程,信息系统与信息管理”4个选项。批量上传——管理员可以通过导入Excel文件,批量导入学生信息。
    运行截图

    关键代码
    //读取Excel文件导入学生信息public class ReadStudentsExcel { public List readStudentExcel(File file) { List<Student> studentList = new ArrayList<Student>(); try { InputStream inputStream = new FileInputStream(file.getAbsolutePath()); Workbook workbook = Workbook.getWorkbook(inputStream); int sheet_size = workbook.getNumberOfSheets(); List<String> eachStudent = new ArrayList<>(); Student student = null; for (int index = 0; index < sheet_size; index++) { Sheet sheet = workbook.getSheet(index); for (int i =1 ; i < sheet.getRows(); i++) { for (int j = 0; j < sheet.getColumns(); j++) { String cellinfo = sheet.getCell(j, i).getContents(); System.out.print(cellinfo+'\t'); eachStudent.add(j,cellinfo); }
    5.5.2 教师信息管理功能介绍
    管理员可以查看、添加和删除教师信息。
    运行截图

    5.5.3 基本信息管理班级信息管理
    功能介绍:查询、添加、删除班级
    运行截图:

    课程信息管理
    功能介绍:查询、添加、删除课程
    运行截图:

    安排课程
    功能介绍:管理员指定班级、课程、教师来安排课程
    运行截图:

    5.5.4 管理系统用户功能介绍:添加、删除系统用户。
    运行截图:
    2 评论 36 下载 2019-04-10 18:44:50 下载需要16点积分
  • 基于JSP技术和SSM框架的Web聊天系统的设计和开发

    摘 要随着当今社会经济的飞速发展和地球村的建设,现在的人们在平常的生活中由于平常的工作生活等原因,造成了许多亲朋长时间无法见面的情况。沟通交流的缺失造成了许多人感情的淡薄。而在现在飞速发展的网络技术的支持下,越来越多的人选择通过网络即时通讯系统来进行每天的沟通,常用的PC端的QQ,移动端的微信等。然而现在流行的通讯软件大多都需要下载安装专用的客户端才能实现通讯。
    本论文在JSP技术和MVC设计模式的基础上,对WEB即时通讯系统进行了需求分析和总体设计,框架采用Spring + Springmvc + Mybatis,前端设计使用Amaze UI,弹窗和分页使用Layer以及JQuery,数据库使用Mysql,并最终使用流行的Eclipse开发环境实现了整个系统。通过运行和测试,本聊天系统功能基本完善且运行稳定,能够满足客户在实际使用中的需求。
    关键词:WEB聊天;JSP;SSM;Eclipse;Amaze UI
    AbstractWith the rapid development of social economy and the construction ofa global village, people now in normal life due to normal working life, causedmany relatives and can’t meet for a long time.The lack of communication causedby weak feelings of many people.And with the support of the rapid developmentof network technology now, every day more and more people choose the network tocommunication, such as commonly used the PC QQ, mobile WeiXin, But now mostpopular communication software need to download and install a dedicated clientto realize communication.
    Based on JSP technology and MVC design patterns, this paper carrieson the demand analysis and the overall design on the WEB chat system., the Spring + Springmvc + Mybatis is used as theframework, Amaze UI is used as the front design, Layer and JQuery is used asthe popups and paging, Mysql is used as the database, and the whole system isrealized in the popular Eclipse development environment. The testing resultshows that the functions of the chat system is basically perfect and runsmoothly, it can meet the needs of users in actual use.
    Keywords:WEB chat; The JSP; SSM; The Eclipse; Amaze UI
    第1章 前 言1.1 论文研究的目的和意义即时会话由于人们对于信息及时性的需求成为了当前社会的一个热门技术[1]。随着计算机网络通信技术和国家网络建设的飞速发展,网络已经全方位的进入人们的日常生活中,网络购物每年的成交量和使用率都在上涨,随之而来的是物流快递行业的飞速发展。近些年来,远程教学,远程就诊也已经实现或是基本实现,而在网络世界,彼此隔着计算机的人们只有通过网络会话才能够传递自己的信息和理解别人的意思。这都离不开网络即时通讯技术。只有及时清晰的表达和理解,才能够让网络交流达到面对面交流的效果。
    即时通讯系统是指通过现有的各种电气通讯传输媒体,将人物的静态或动态图像、语音、文字、图片等多种信息分送到各个用户的计算机上,使得在地理上分散的用户可以共聚一处,运用图片,文字,声音等多种方式传递信息[2],能够更好地让交流的双方理解到对方的本意,解决非面对面沟通时信息传递的阻碍,便于人们进行远程沟通交流。即时通讯系统能够有效地传递及时准确的信息;提高各个机构工作实施的效率;便于分隔两地的人们进行交流沟通;便于集思广益,共同商讨意见和看法。这都将给使用者带来直接或者是间接的利益和便利。正是由于即时通讯系统有着上述诸多优点,使得人们对其青睐有加。自然,有了需求就会催生出各种不同的产品来满足人们的需求[3]。
    即时通讯系统在我国开始发展的初期,政府部门的应用就占据了重要位置,覆盖中央到直辖市和各省会城市的国家骨干网已经完工。自1994年9月投入使用以来,国务院等机关先后利用该网召开了三百多次全国范围的即时通讯会议。整个系统运行情况良好,得到了国家领导人和各部委领导的高度赞扬[4]。
    随着国家网络建设的发展,渐渐地即时通讯系统更广泛的应用于现代企业和人们的日常生活中。经济全球化以及地球村的建设使得所有人特别是企业都要有敏锐的嗅觉,能够及时的获得更多的信息,做出更快的反应和决策,得到最快速的实现。视频会议跨越空间,成本低,损耗小的特点自然成为人们的首选。然而,现在许多视频会话系统尤其是企业内部的即时通讯系统为了保障安全性都是基于C/S模式的,需要下载安装客户端才能运行。因此,本论文旨在运用现今流行的技术设计和开发一个不需要下载任何客户端,只需要一个浏览器就可以进行会话沟通的即时通讯聊天系统。其目的是能够让普通的人在上面畅聊交友,也可以实现与特定用户的沟通交流。
    首先,本文对JAVA进行了深入的学习和研究。其次,以JSP技术和MVC设计模式为基础,采用SSM框架对整个系统进行了需求分析和各个功能块的设计和实现,使用Amaze UI对UI界面进行设计。
    1.2 国内外研究综述随着时代的发展和网络通讯技术的飞速发展,对于高昂的长途电话费用不满的人们越来越多的选择了通过网络来进行远距离的沟通和交流。而现在的即时通讯聊天系统也已经不是多年前专为各大公司开发的内部系统了。实时,便捷,易于使用和操作成为了现今即时通讯系统的重要标杆。
    由于现在手机移动端的兴起,我国现有的即时通讯软件如QQ,微信都是支持移动端的。当然为了追求信息安全等原因PC端基于B/S结构的即时通讯系统依旧是企业和政府部门的首选,各个公司内部的软件也能够实现通信交流。
    腾讯公司的官方数据显示,我国使用QQ聊天软件的用户已经达到了2.6亿人,活跃用户接近了8000万,而同时在线的人数也已经超过了800万,所以,腾讯QQ可以说是我国使用用户数量最多的个人即时通讯软件,占我国70%左右[5]。QQ是一款十分出色的软件,不只是在PC端,在移动端也已经成为了必装应用之一。
    国外自从上世纪90年代美国在线(America Online,AOL)带动实时通讯(instant messaging,以下简称IM)风行一时以来,IM改变了人们沟通的方式[6]。目前国外最大的三个即时通讯软件分别为AOL的AIM、雅虎的Yahoo Messenger和微软的Windows Live Messenger[7] ,而前段时间微软与腾讯在中国市场的争斗也说明了了该领域蓬勃的生机。
    1.3 论文研究的内容和取得的成果本文将着重研究JSP和SSM框架,对Web聊天系统进行详细的需求分析,并使用MVC设计模式对网站系统进行设计,最终利用Eclipse 开发工具实现网站的全部功能。使用JQuery和Layer进行弹窗和分页。通过使用Amaze UI对前端的UI进行设计。通过论文研究设计取得了以下研究成果:

    熟练掌握JSP以及使用现有的UI设计框架进行开发。
    在通过对SSM框架的学习和实践,对系统整体结构有了更深入的了解。
    学习使用了My SQL数据库系统,并且使用My SQL建立了Web聊天系统网站的后台数据库系统,能够存储用户的相应信息并与前台进行交互显示。
    在分析设计的基础上使用Eclipse对网站系统后台采用JAVA语言进行了开发,实现了具有文字聊天功能,能够设置修改用户信息的聊天系统。

    第2章 即时通讯聊天系统开发涉及技术简介本系统项目使用Maven构建,采用Spring + Spring MVC + Mybatis作为框架。后台使用的语言是JAVA,数据库使用的是MySQL 前端采用Amaze UI,弹窗和分页使用的是Layer,当然还有Jquery。开发工具使用的是Eclipse。
    2.1 Spring简介Spring是轻量级的Java开发框架,最初是由Road Johnson在其著作Expen-One J2EEDevelopmentand Design中阐述的部分原理和原型衍生出来的。其目的是为了解决企业应用开发的复杂性,Spring最主要的特点就是使用基本的JavaBean来完成以前有EJB完成的事情[8]。其核心是控制反转(ioC)和面向切面(AOP)。
    IOC:inverse of Control:控制反转。本意就是不需要程序员再像以往一样通过代码来控制程序之间的关系。而是通过容器根据信息中得到的关系注入组件来确定关系。当然,依赖注入和控制反转其实就是一个东西。总之,就是通过容器来控制关系,解放程序员集中注意力到业务逻辑的实现上面,减少开发工作量。本次开发采用的是set注入方式。
    Spring除了IOC之外的另一个关键组件就是面向切面AOP,由于AOP并不是必须需要使用的组件,所以这里就不做过多介绍了。
    2.2 SpringMVC简介Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,
    Spring MVC也是服务到工作者模式的实现,但进行可优化。前端控制器是DispatcherServlet;应用控制器其实拆为处理器映射器(HandlerMapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response)方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持[9]。SpringMVC相较于Struts2来说更加的简单,便于使用者学习快速掌握。Spring MVC对比Struts2来说,前者是方法级别的拦截,一个方法对应一个request上下文,又同事和一个url对应,更容易实现restful url,并且一个方法独自享有一个request response数据,数据处理结果通过modemap直接交回给框架。
    2.3 MyBatis简介MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis 。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)[10]。
    MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录[11]。
    2.4 AmazeUI简介由于以前何绍设计前端的开发,所以在实现了系统的基本功能之后发现自己的界面真的有点丑陋,所以有了进行UI设计的想法,经过各方查找,决定使用Amaze UI来进行UI的设计。
    Amaze UI是中国第一个HTML5的开源跨屏框架。其组件式的开发方式能够让我通过基于其丰富的组件迅速的拼装出页面,所以我就是直接使用的现有的模板来设计的界面。Amaze UI JS 插件基于 jQuery 开发,所以使用之前需要先将JQuery装入。
    2.5 开发工具介绍本节主要介绍在系统开发中所使用的工具,包括:Eclipse, Tomcat, MySql。
    2.5.1 Eclipse集成开发环境Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境,2001年11月贡献给开源社区,现在它由非营利软件供应商联盟Eclipse基金会(Eclipse Foundation)管理[12]。
    Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit JDK)。
    下面简单介绍如何在Eclipse中创建一个Web工程并将其部署到Tomcat服务器上。

    打开eclipse for J2EE, 选择file—new—Dynamic Web Project,输入项目名称,然后Finish。到此,Web项目建立完成
    在生成的项目的WebContent目录下创建Jsp File。起名hello.jsp在其中写入hello world
    配置Tomcat。通过window->preference->Server->Runtime Enviroments , 在通过Add加入你所使用的Tomcat版本点击Next后在Browse中选择刚刚指定的Tomcat的所在位置

    这样就在Eclipse中创建了一个Web项目并且部署到了Tomcat服务器上。
    2.5.2 Tomcat服务器Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成[13]。
    Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器[10]。正是由于这个特点,所以本系统决定使用Tomcat作为本次开发的服务器,应为在并发访问用户数量不是很多的小型项目中,Tomcat完全能够支撑。
    第3章 即时通讯聊天系统需求分析和总体设计3.1 系统可行性分析系统是否值得投入资源进行开发,是取决于系统的可行性的[14]。在系统可行性全面发展以前很多系统在研发后期都无法继续进行下去。后来提出系统可行性分析以后,在项目前期就进行系统可行性分析,全面的从经济、技术、法律、操作四个方面进行评估。
    3.1.1 法律可行性分析本系统所使用的软件和技术都是合法的,不存在任何违法或者侵权行为。引用的代码和文字也没有超过法律规定的界限,且引用都标明出处。因此在法律方面是可行的。
    3.1.2 技术可行性分析本系统是一个使用SSM框架的Web系统。在以前的学习中,有过Java和JavaWeb的课程学习,有着一定的知识基础。本系统对于硬件也没有很高的要求。因此利用现有技术完全可以实现本系统。
    3.1.3 经济可行性分析本系统采用JavaWeb技术,对于硬件没有特殊要求,软件方面也都是使用的开源软件,没有经济负担。
    3.1.4 操作可行性分析本系统本着使用简洁的原则进行设计和开发,界面简洁明了,用户只要有基本的计算机操作基础就能够流畅的使用。
    3.2 需求分析了解用户的需求才能够做出让用户使用起来满意的产品。经过需求分析和实际使用现在市面上现有的web通讯软件,决定将整个系统分为登陆页面,聊天页面,个人信息页面,设置页面,系统日志查看页面,在线用户页面。
    3.2.1 登陆页面用户通过注册功能获得注册账号,然后通过登陆功能进行登陆,只有登陆成功才能进入主页面,否则返回登陆界面。用户用例图如图3-1所示。

    3.2.2 个人信息页面展示用户的个人信息,包括:昵称,性别,年龄,简介,注册时间,最近登录时间。能够实时根据用户在设置界面修改的信息更新对应的信息。
    3.2.3 设置页面设置通过一个下拉弹窗包括了个人设置和系统设置两个部分。个人设置展示用户基本信息,能够实现修改头像,修改密码修改基本信息等功能。系统设置展示系统基本设置,能够实现修改头像,修改密码,修改系统设置等功能。
    3.2.4 注销页面注销页面注销当前用户登陆,返回到登陆界面。
    3.2.5 用户页面用户页面包括用户资料,设置,注销功能。分别展示用户资料,用户设置,注销返回登陆。
    3.2.6 聊天页面聊天页面包括展示聊天信息,当前输入信息,发送对象,链接服务,断开服务,检查链接,清理聊天信息,发送输入信息。
    3.2.7 在线列表页面在线列表页面显示当前连接的用户信息,可对用户发起私聊。
    3.2.8 图灵机器人功能通过图灵提供的API端口实现聊天中引入图灵机器人和用户进行对话。
    3.3 系统总体设计通过SSM框架和JSP,前端的设计使用了AmazeUI,弹窗和分页使用了Layer和JQuery。
    首先,在进行开发之前,先将Amaze UI, Laye以及JQuery下载下来,导入进入工程中,如图3-2所示。

    3.3.1 SSM框架配置要使用SSM框架进行醒目开发,首先我们需要将框架进行整合,这次整合将SSM分为了两个配置文件,分别是spring-mvc.xml 和spring-mybatis.xml,前者是spring-mvc的配置文件,后者包含了spring和mybatis的配置文件。当然,还包括两个资源文件jdbc.properties和log4j2.xml。如图3-3所示。

    1.Spring和MyBatis的整合
    整合之前,首先需要导入项目开发需要的所有jar包,然后建立JDBC属性文件即jdbc.properties文件。jdbc.properties[15]文件内容如下:
    driver=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/zhoutao?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTCusername=rootpassword=123456initialSize=0maxActive=20maxIdle=20minIdle=1maxWait=60000
    建立spring-mybatis.xml整合文件,主要内容无外乎自动扫描,自动引用,配置数据库等。相关代码如下:
    <!-- 这里排除扫描Controller --> <context:component-scan base-package="com.amayadream.webchat.*" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 引入jdbc配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:config/jdbc.properties" /> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="${initialSize}"/> <!-- 连接池最大数量 --> <property name="maxActive" value="${maxActive}"/> <!-- 连接池最大空闲 --> <property name="maxIdle" value="${maxIdle}"/> <!-- 连接池最小空闲 --> <property name="minIdle" value="${minIdle}"/> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="${maxWait}"/> </bean>
    2.SpringMVC的整合
    springmvc.xml文件主要包括自动扫描控制器,视图模式,注解启动等,当然由于我需要上传文件显示,所以为了防止文件被拦截需要在其中特殊设置一下:<mvc:resources location="/"mapping="/\*\*/\*.jpg" />。主要代码如下:
    <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">… <mvc:interceptors> <!-- 登陆拦截器,负责拦截未登录的操作 --> <mvc:interceptor> <!-- 需要拦截的地址 --> <mvc:mapping path="/**"/> <!-- 需要排除拦截的地址 --> <mvc:exclude-mapping path="/static/**"/> <bean id="loginInterceptor" class="com.amayadream.webchat.interceptor.LoginInterceptor">… <!-- 开启注解模式 --> … <!-- 静态资源映射 --> … <mvc:resources location="/" mapping="/**/*.jpg" />
    最后,再在web.xml文件中对spring-mybatis.xml进行引用以及配置spring-mvc的servlet就完成了SSM框架的整合,web.xml文件相关配置没有什么值得注意的地方。
    3.3.2 即时通讯聊天系统总体设计整个系统总体设计如图3-4所示,主要分为:

    登录页面:用户在该界面进行登陆,验证账号密码正确之后之后跳转到聊天主界面
    聊天页面主页:用户进入界面默认为群聊,能够在此界面进行群聊,可以通过左边的功能栏中的进行查看个人信息,个人设置,查看系统日志等
    右边的用户列表栏显示当前链接的用户,可以选择与用户私聊和进行视频
    点击私聊可以发送信息进行私聊
    点击在线用户的视频按钮向对应用户发送视频请求,对方同意后可以进行一对一视频通话


    3.3.3 路由设计确定了本系统的总体设计之后,明确了系统所需要的界面,根据各页面设置相应的路由。在RouteCotroller使用RequestMapping()进行地质映射来实现。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。系统各页面以及对应路由如表3-1所示:



    各分类模块
    对应页面
    对应路由




    登陆
    login.jsp
    /user/login


    聊天主页
    Index.jsp
    /chat


    个人信息
    information.jsp
    /Userid


    个人设置
    Info-setting.jsp
    /userid/cofig


    日志
    log.jsp
    /log


    帮助
    help.jsp
    /help


    关于
    about.jsp
    /about


    系统设置
    systemsetting.jsp
    /systemsetting



    具体实现代码如下:
    @RequestMapping(value = "")public class RouteController { @RequestMapping(value = "") public String index() { return "redirect:/user/login"; } @RequestMapping(value = "/about") public String about() { return "about"; } @RequestMapping(value = "/help") public String help() { return "help"; } @RequestMapping(value = "/systemsetting") public String systemsetting() { return "systemsetting"; }}
    3.3.4 用户登录界面登录界面主要使用了query-2.1.4.min.js,login.css,layer.js来进行UI的设计。
    3.3.5 用户聊天主界面主聊天界面主要分为四个部分,分别是顶部的状态栏模块,左侧的功能栏模块,右侧的用户列表栏模块以及中央的聊天栏模块。
    状态栏模块
    顶部状态栏主要用于显示应用的名称以及右侧的导航下拉菜单。下拉菜单通过:下拉菜单包括个人资料,设置,注销三个功能。分别可以进入个人资料界面,个人设置界面,以及注销用户返回登陆界面。
    功能栏模块
    功能栏主要有显示个人信息,个人设置和系统设置,查看系统日志,获取帮助,关于和注销功能。整个功能栏的主要思路就是通过${user.**}来获取用户对应的字段的值。再在jsp中展示出来。其中比较重要的功能为修改用户的头像。用户的头像在个人资料,聊天信息框中均可展示。所以这个实时根据用户的选择更新还是比较重要的。
    用户列表模块
    对于右侧的列表模块,用于显示当前在线的用户名,其中还包含了一个图灵机器人功能,点击上线按钮,调用tuling提供的api接口可以让其与自己进行对话沟通。
    其次,显示出来的每一个在线用户(除开自己以外)还有两个按钮,分别是私聊和视频通话功能。私聊按钮就是点击之后将当前获取的用户名加入到to中去,实现私聊。
    用户聊天模块
    对于用户发送的信息,可以分为两个类型:massage和notice,massage表示用户输入的信息。notice表示一些提示消息,如:用户登入,用户离开以及图灵机器人的接入的接出。所以需要在传输和获取数据的时候对这两类信息分别进行处理。用户还会将用户列表中的信息一起发送,用于其他用户更新用户列表。
    对于私聊和一对多的聊天处理的想法是,用一个string 类型的对象to来存储一段文本,初始设置为空,即想所有人发送消息,当用户点击私聊按钮后,就将该按钮对应的用户的userid存放到to里面去,可以存放多个用户的userid,用“,”分隔开。这样子在发送的时候就可以使用split()方法将字符拆分存到一个数组里面再通过循环访问数组来发送消息就可以实现一条消息发送给多个指定的人了。
    3.3.6 数据库设计整个数据库的内容并不复杂,只需要两个表user和log。User表存储用户的相关信息。如:用户名,密码,昵称,头像,简介等。User表结构如图3-5所示。

    log表用于存储用户的日志,包括一个随机生成的操作id,用户名,时间,类型,动作。Log表结构如图3-6所示。

    数据库总体设计E-R图如图3-7所示。

    第4章 系统实现及效果分析4.1 用户登录界面用户登录界面是用户进入系统的第一步,所以一定要有特色,能够第一时间抓住用户的眼球,产生使用的欲望。
    整体登录界面的账号密码验证交由控制器LoginController来进行,通过@RequestMapping(value =”/login”, method = RequestMethod.POST)来获取表单数据,进行判断,跳转到对应页面。
    LoginController文件代码如下所示:
    @RequestMapping(value = "/login", method = RequestMethod.POST) public String login(String userid, String password, HttpSession session, RedirectAttributes attributes, WordDefined defined, CommonDate date, LogUtil logUtil, NetUtil netUtil, HttpServletRequest request) { String ip=netUtil.getIpAddress(request); User user = userService.selectUserByUserid(userid); if (user == null) { attributes.addFlashAttribute("error", defined.LOGIN_USERID_ERROR); return "redirect:/user/login"; } else { if (!user.getPassword().equals(password)) { attributes.addFlashAttribute("error", defined.LOGIN_PASSWORD_ERROR); return "redirect:/user/login"; } else { if (user.getStatus() != 1) { attributes.addFlashAttribute("error", defined.LOGIN_USERID_DISABLED); return "redirect:/user/login"; } else { logService.insert(logUtil.setLog(userid, date.getTime24(), defined.LOG_TYPE_LOGIN, defined.LOG_DETAIL_USER_LOGIN, netUtil.getIpAddress(request))); session.setAttribute("userid", userid); session.setAttribute("login_status", true); user.setLasttime(date.getTime24()); user.setIp(ip); userService.update(user); attributes.addFlashAttribute("message", defined.LOGIN_SUCCESS); return "redirect:/chat"; } } } }
    验证账号密码成功之后,通过return “redirect:/caht”来进入聊天界面。 登录界面效果图如图4-1所示。

    4.2 用户聊天主界面主聊天界面主要分为四个部分,分别是顶部的状态栏模块,左侧的功能栏模块,右侧的用户列表栏模块以及中央的聊天栏模块。本部分将对这三个部分进行详细的描述并给出关键实现代码。聊天主界面如图4-2所示。

    4.2.1 状态栏模块顶部状态栏主要用于显示应用的名称以及右侧的导航下拉菜单。下拉菜单包括个人资料,设置,注销三个功能。由于考虑到这一栏需要一直显示在页面最顶部,所以我将其单独写入了一个JSP文件中,其后的都直接引用该文件达到这个效果。具体代码如下:
    <button class="am-topbar-btn am-topbar-toggle am-btn am-btn-sm am-btn-success am-show-sm-only" data-am-collapse="{target: '#topbar-collapse'}"><span class="am-sr-only">导航切换</span> <span class="am-icon-bars"></span></button> ... <ul class="am-dropdown-content"> <li><a href="${ctx}/${userid}"><span class="am-icon-user"></span> 资料</a></li> <li><a href="${ctx}/${userid}/config"><span class="am-icon-cog"></span> 设置</a></li> <li><a href="${ctx}/user/logout"><span class="am-icon-power-off"></span> 注销</a></li> </ul>...
    4.2.2 功能栏模块功能栏主要有显示个人信息,个人设置和系统设置,查看系统日志,获取帮助,关于和注销功能。整个功能栏的主要思路就是通过${user.**}来获取用户对应的字段的值。再在jsp中展示出来。
    个人信息展示功能
    根据用户的userid在数据库查询出相应的信息,再通过ModelAndView selectUserByUserid()方法展示出来。效果如图4-3所示:

    个人设置功能
    个人设置功能能够在其中修改用户的昵称,性别,年龄以及个性签名。修改完成后点击提交就可以完成更新。修改头像可以修改用户的头像。修改密码能够修改用户的登陆密码,用户输入当前密码再输入新密码,验证旧密码成功后即可以完成密码的修改。其中比较重要的功能为修改用户的头像。用户的头像可以在个人资料,聊天信息框中均可展示。所以这个实时根据用户的选择更新还是比较重要的。基本思路就是首先我们上传的只能是图片文件,即后缀为”bmp”,”jpg”,”gif”,”png”的文件,那么首先要通过下列代码:
    var format = ["bmp","jpg","gif","png"];var filename = $("#file").val();var ext = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
    来获得选择的文件的后缀名,在通过jQuery.inArray(ext,format)函数来进行对比即可。如果其值不等于-1,则说明文件格式正确,否则通过layer.msg()函数来显示提示信息。最后在通过下面的代码将文件进行更新即可。
    $(function() { $('#file').on('change', function() { var fileNames = ''; $.each(this.files, function() { fileNames += '<span class="am-badge">' + this.name + '</span> '; }); $('#file-list').html(fileNames); });});

    系统日志功能
    系统日志功能能够查看当前登录的用户进行过的操作,包括登录和更新两类,跟新又分为更新头像和更新资料两种。在用户执行上述操作时,将该操作信息存放到数据库中的log表中。其与用户表的更新方式一致,不在赘述。具体实现方法如下:
    @Resource private ILogService logService; @RequestMapping(value = "{userid}/log") public ModelAndView selectAll(@PathVariable("userid") String userid, @RequestParam(defaultValue = "1") int page) { int pageSize = 5; ModelAndView view = new ModelAndView("log"); List<Log> list = logService.selectLogByUserid(userid, page, pageSize); int count = logService.selectCountByUserid(userid, pageSize); view.addObject("list", list); view.addObject("count", count); return view; }
    其余的帮助,关于以及注销功能十分简单。不做过多描述。
    4.2.3 用户列表模块对于右侧的列表模块,用于显示当前在线的用户名,其中还包含了一个图灵机器人功能,点击上线按钮,调用tuling提供的api接口可以让其与自己进行对话沟通。效果如下所示:
    其次,显示出来的每一个在线用户(除开自己以外)还有两个按钮,分别是私聊和视频通话功能。私聊按钮就是点击之后将当前获取的用户名加入到to中去,实现私聊。这个在后面的用户聊天中会详细说明。效果图如图4-5所示。

    4.2.4 用户聊天模块在进入用户聊天模块之后,用户可以在消息输入框中输入消息进行群发或者给指定的在线用户发送私聊。那么,前后台的数据交互就要有一定的格式了。经过分析,对于用户之间传递的信息可以分为聊天信息和提示信息两种,聊天信息就是用户发送的信息,可以使全局广播或是指定发送。二提示信息则是用户登录或者登出是的提示信息,这个必须是全局广播让所有在线用户接收到。能够相应的更新在线列表。定义前后台的数据交互格式如下:
    "message" : { "from" : "xxx", "to" : "xxx", "content" : "xxxxxx", "time" : "xxxx.xx.xx"},"type" : { "xxx"},"list" : { ["xx","xx"]}
    其中,message是消息部分,from是发信人用户名,to是收信人用户名(如果是群聊则置空),content是消息内容,time是发送时间,这里发信时间是前台JS获取,from和to都是直接用用户名而不是昵称。
    type是消息类型,分为两种,notice和message.notice是提示类型,比如xxx用户加入了聊天室,xxx用户离开了聊天室;message是消息类型,就是用户之间发送的消息。对于这两类的处理代码如下:
    function analysisMessage(message){ message = JSON.parse(message); if(message.type == "message"){ //会话消息 showChat(message.message); } if(message.type == "notice"){ //提示消息 showNotice(message.message); } if(message.list != null && message.list != undefined){ //在线列表 showOnline(message.list); }}
    list是当前在线的用户名的列表,只在后台触发onopen和onclose时返回list,然后更新前台的在线列表,实现实时的列表展示。实现代码如下:
    function showOnline(list){ $("#list").html(""); //清空在线列表 $.each(list, function(index, item){ //添加私聊和视频按钮 var li = "<li>"+item+"</li>"; if('${userid}' != item){ //排除自己 li = "<li>"+item+" <button type=\"button\" class=\"am-btn am-btn-xs am-btn-primary am-round\" onclick=\"addChat('"+item+"');\"><span class=\"am-icon-phone\"><span> 私聊</button>" +"<button type=\"button\" class=\"am-btn am-btn-xs am-btn-primary am-round\" onclick=\"startVideo('item');\"><span class=\"am-icon-phone\"><span> 视频</button></li>"; } $("#list").append(li); }); $("#onlinenum").text($("#list li").length); //获取在线人数 }
    在确定了信息的格式之后,为了能让各个用户之间进行信息传输,我们要建立一个websocket服务。进行信息发送的基本思路如下:首先接受客户端的massage,判断to是否为空,如果为空,则执行broadcast(message)函数,代码如下:
    public void broadcast(String message){ for(ChatServer chat: webSocketSet){ try { chat.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); continue; } } }
    如果不为空,那么执行singleSend(String message, Session session)函数给指定的用户发送信息。代码如下:
    public void singleSend(String message, Session session){ try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } }
    如果要实现一个用户同事对多个用户发送同一条信息的话,先将所有选取的用户名添加到to中通过,隔开,在发送的时候对to进行解析根据split(“,”)将这个字符串拆分成一个个用户名字符串加入到一个list里面,通过for(user:listname)就可以循环发送消息达到此效果,相关代码如下:
    public void onMessage(String _message) { JSONObject chat = JSON.parseObject(_message); JSONObject message = JSON.parseObject(chat.get("message").toString()); if(message.get("to") == null || message.get("to").equals("")){ //如果to为空,则广播;如果不为空,则对指定的用户发送消息 broadcast(_message); }else{ String [] userlist = message.get("to").toString().split(","); singleSend(_message, (Session) routetab.get(message.get("from"))); //发送给自己 for(String user : userlist){ if(!user.equals(message.get("from"))){ singleSend(_message, (Session) routetab.get(user)); //分别发送给每个指定用户 } } } }
    当获取到对方发送过来的数据时,通过JSonObject的put方法进行操作,再返回该对象给前台就可以显示出来了。方法如下:
    public String getMessage(String message, String type, List list){ JSONObject member = new JSONObject(); member.put("message", message); member.put("type", type); member.put("list", list); return member.toString(); }
    上述私聊,群发私聊,提示消息显示和更新在线用户列表如图4-6所示:

    结 论本论文通过SSM框架,运用java基础知识,结合layer进行弹窗和分页,使用amaze ui 对整个系统的界面进行UI设计并且结合数据库MySql进行系统的开发。这个架构将系统分为了持久层,业务层,表现层,Viewc层。除了view层和controller层耦合度比较高,一般当做一个整体之外,其余层之间耦合度很低,都可以单独开发。开发者只需要知道层与层之间的接口的定义,直接调用接口就可以完成所需要的逻辑应用。这种模式在小规模的开发中体现的不多,但是在开发大项目的过程中能够发挥出更大的作用。
    总的来说,完成了一个有实际用处和良好操作体验的系统。与用户能够直接通过网页访问该系统,登陆成功之后就可以和所有在线的用户进行及时的交流沟通。这个页面简介明了,使用起来没有任何的难点。色彩上也不会让人产生审美疲劳。整个系统功能较为完善,使用感不错。
    当然,webchat系统也存在这一些问题。首先,对于是否该加入好友这个功能,原本并不想做成一个类似于QQ那样只能在好友之间进行即时通讯的系统,而是所有只要登录了系统的人都能够自由的聊天,但是这样就会造成,当登录人数过多之后就没有办法在聊天信息里面准确快速的辨别出需要的信息。另外右侧的在线用户列表也会因为人数过多的问题不方便找到指定用户进行私聊和视频。
    初步解决的想法方法是,将用户列表替换成好友列表,聊天信息显示依旧不变,但是在信息展示的用户头像处,能够进行左键点击进行加好友操作,只有加成好友以后才能够进行私聊和视频,并且更新右侧用户列表。这样就能够实现和所有用户不限定的聊天,操作性上来说也更加的方便。
    通过这次的毕业设计,对于MVC模式下的系统开发有了更进一步的认识,通过结合自己以前所学习到的知识和新学习的知识,整体地提升了个人的思考学习行动能力。当然,对于在这次实际开发中暴露出来的问题,我也会在接下来的学习生活中不断改进,对于整个系统也会进一步的去完善它。
    参考文献[1]鲁耀斌,徐红梅. 即时通讯服务使用行为的影响因素实证研究[J]. 管理学报,2006,(05):614-621.
    [2] 项颖 王文生. 视频会议应用浅析[J].中国科技信息,2006().
    [3]黄科. 浅析视频会议系统的发展趋势[J]. 计算机光盘软件与应用,2012,(19):73-75.
    [4] 梁建军. 让沟通没有距离——视频会议系统市场潮流[M]. 中国计算机用户,2002(01):18-18.
    [5] 李锐. 浅谈即时通讯工具现状及其发展趋势[J]. 中国科技信息,2013(16):92-92.
    [6]邹红霆. 基于SSM框架的Web系统研究与应用[J]. 湖南理工学院学报(自然科学版),2017,(01):39-43.
    [7]李洋. SSM框架在Web应用开发中的设计与实现[J]. 计算机技术与发展,2016,(12):190-194.
    [8] 方犀超. 面向会展行业信息管理系统的设计与实施[D]. 中国优秀硕士学位论文全文数据库,2012 (12).
    [9] 周帝. Spring MVC入门知识总结[EB/OL].(2016-10-14)[ 2016-10-14]. http://www.cnblogs.com/zhoudi/p/5960683.html.
    [10] 徐雯,高建华. 基于Spring MVC及MyBatis的Web应用框架研究[J]. 微型电脑应用,2012,(07).
    [11]Tie Bin Liu. Design and Implement anApplication Development Platform Based on Open Source Technology[J]. AdvancedMaterials Research,2014,3326(989).
    [12]V.U. Chukwuma,B.J. Adekoya. Theeffects of March 20 2015 solar eclipse on the F2 layer in the mid-latitude[J].Advances in Space Research,2016.
    [13]Aleksa Vukotic,James Goodwill. UsingTomcat’s Manager Web Application[M].Apress:2011.
    [14]吴小青. JSP+TOMCAT+MYSQL开源软件整合配置初探——以揭阳职业技术学院图书馆网站服务器配置为例[J]. 齐齐哈尔大学学报(自然科学版),2012,(04):66-69.
    [15]张俐,张维玺. 改进的JDBC框架在数据持久层的应用[J]. 计算机工程与设计,2010,(08):1746-1749.
    2 评论 43 下载 2018-11-13 17:27:48 下载需要13点积分
  • 基于Android平台的个人理财软件的设计与实现

    摘要个人理财管理系统是基于Android系统开发的一款手机应用程序。它主要是为了满足人们在快节奏的生活中可以随时记下自己的收支情况的需求。个人理财管理系统与传统的记账方式相比,体现了它的便捷性、安全性及可扩展性。系统采用Eclipse+ Android Developer Tools作为开发工具,以SQLite为数据库。系统功能包括:用户账户的注册、用户切换、用户名密码修改、账户删除,语音识别记账,收入信息的增删改,支出信息的增删改,收入类型的增删,支出类型的增删,收入信息分类统计,支出信息分类统计,收入支出总额统计,数据还原、清空等等。系统具有界面简洁鲜明、功能便捷易用、操作人性化等特征。
    关键字:收支管理;Android;SQLite
    AbstractPersonal financial management system is based on the Android system developed a mobile application.It is mainly to meet those people who want to write down their income and expenditure more quickly and conveniently in the fast-paced life. Compared with the traditional method, Personal financial management system reflects more convenience,security and scalability. Especially in this day and age, people are on the side of the phone. System uses Eclipse and Android Developer Tools as a development tool and SQLite as the database. Android technology is now very mature, we can easily develop.Personal Financial Management System of the main functional modules,including: user account registration, user switching, username password changes, account deletion, Income information management,Expenditure information management,voice recognition accounting,Type of income management, Expenditure Type Manager, Income information classification statistics, expenditure information classification statistics, total income and expenditure statistics,Data reduction, data emptied and so on. The system has a simple and clear interface, easy-to-use features, user-friendly operation and other features.
    Keywords: Revenue and expenditure management; Android;SQLite
    1 绪论1.1 选题背景出门口诀“伸手要赏钱”分别代表着身份证、手机、钥匙、伞、钱。在后PC时代的今天,手机成为最重要的移动终端,是我们出门出行的必携物。以前,或许我们的手机只能为我们提供基本通信功能,而随着Android系统的诞生,我们的生活迎来了一场不亚于“工业革命”带给我们的巨大变化。基于Android系统的手机处理各类信息的能力得到了质的提升。而Android这个开源的操作系统,将享受这项优质服务的权利给了所有愿意使用它的人。?Android从08年9月的1.1版到去年的L版,一路走来,从基本走向优化,全方面地为我们提供了出色的网络、多媒体、通讯、娱乐等功能。这匹黑马,从诞生伊始到去年7月的“全球市场占有率达81.9%”,告诉我们它的出现是多么受人们欢迎。它备受追捧的原因不外乎它完全的对第三方软件开发商和我们这些开发者的开发。我们可以在它上面实现无限自主的“自定义”。它宛如一张白纸,我们可以在上面随意画出自己想要的东西。它,贵在给予了我们自由。
    1.2 课题研究的目的和意义随着高速经济化,我们的生活节奏越来越快。我们忙东忙西,总会容易忽略忘记了一些生活细节,比如收支管理。为了更好的释放一些时间来享受我们的生活,我们期待有这么一款软件来帮助管理这些小数据。建立在Android操作系统上的个人理财系统,方便我们随时随地地记录着这些零散的数据,从此我们不必再为收支费心,清心地查看数据统计结果是我们唯一要做的事。
    1.3 国内外现状和发展趋势安卓在手机上的应用使得手机的功能有了很大改善,这使得越来越多的入主要依靠手机查询大量信息,而用户们不断提高的需求也决定了越来越多的基于安卓平台的应用软件及系统的产生。
    若是基于安卓平台的个人理财系统得到广泛推广,人们能从该应用显而易见的了解到个人的财务状况,明确的使用自身钱财,了解到日常中支出比例,调整支出,正确理财。

    开放性手机平台:android是Google开发的基于Linux平台的开源手机操作系统。Google通过与运营商、设备制造商、手机公司和其他有关各方结成深层次的合作伙伴关系,希望借助建立标准化、开放式的智能手机操作系统,在移动产业内形成一个开放式的生态系统
    网络集成性很高:涵盖了生活中各个方面的网络应用,对长期使用网络、信息依赖度比较高的人群很合适
    Android具备创新性自从:Google开发出Android后,许多人认为其技术可信度要比其它操作系统略胜一筹,但这并不是用户购买Android智能手机的唯一原因。人们认为Android是一种相对较新的、又较为成熟的技术,在达到巅峰之前还有很大发展空间
    Android平台在数量上逐渐主宰市场:市场分析机构NPD发布的数据显示,2014年4-6月份发售的智能手机中,33%为Android手机,而RIM手机发售比例为28%,iPhone为22%
    Android在其它领域的拓展:android不仅促进了手机产业的发展,它的全面计算服务和丰富的功能支持,已将应用拓展到手机以外的其他领域。Android平台的通用性可以适用于不同的屏幕、有线和无线设备。Android的系统和应用程序开发人员将更多的涉足多媒体、移动互联网设备、数字视频和家庭娱乐设备、汽车、医药、网络、监测仪器和工业管理、机顶盒等新领域

    2 设计开发所用到的工具和技术2.1系统开发工具个人财务管理系统的开发及运行环境如下所述:

    操作系统:Windows7
    JDK环境:Java Development Kit version=1.7.0_45
    开发工具

    Eclipse version=4.2.0Android Software Development Kit version=4.4.2Android Developer Tools Build: v22.3.0-887826
    开发语言:Java、XML
    数据库软件:SQLite
    运行平台:Windows
    虚拟机:720P(1080x720)

    2.2 Android的介绍Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
    Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。
    该平台由操作系统、中间件、用户界面和应用软件组成。它采用软件堆层(Software Stack,又名软件叠层)的架构,主要分为三部分。底层以Linux内核工作为基础,由C语言开发,只提供基本功能;中间层包括函数库Library和虚拟机Virtual Machine,由C++开发。最上层是各种应用软件,包括通话程序,短信程序等,应用软件则由各公司自行开发,以Java作为编写程序的一部分。不存在任何以往阻碍移动产业创新的专有权障碍,号称是首个为移动终端打造的真正开放和完整的移动软件。
    android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。
    蓝色的代表java程序,黄色的代码为运行JAVA程序而实现的虚拟机,绿色部分为C/C++语言编写的程序库,红色的代码内核(linux内核+driver)。在Application Framework之下,由C/C++的程序库组成,通过JNI完成从JAVA到C的调用。

    2.3 Eclipse的介绍eclipse-galileoEclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括 Java 开发工具(Java Development Tools,JDT)。
    Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境,2001年11月贡献给开源社区,现在它由非营利软件供应商联盟Eclipse基金会(Eclipse Foundation)管理。 2003年,Eclipse 3.0选择OSGi服务平台规范为运行时架构。 2007年6月,稳定版3.3发布。2008年6月发布代号为Ganymede的3.4版。2009年7月发布代号为GALILEO的3.5版。
    Eclipse是著名的跨平台的自由集成开发环境(IDE)。最初主要用来Java语言开发,但是目前亦有人通过插件使其作为其他计算机语言比如C++和Python的开发工具。Eclipse的本身只是一个框架平台,但是众多插件的支持使得Eclipse拥有其他功能相对固定的IDE软件很难具有的灵活性。许多软件开发商以Eclipse为框架开发自己的IDE。
    Eclipse 最初由OTI和IBM两家公司的IDE产品开发组创建,起始于1999年4月。IBM提供了最初的Eclipse代码基础,包括Platform、JDT 和PDE。目前由IBM牵头,围绕着Eclipse项目已经发展成为了一个庞大的Eclipse联盟,有150多家软件公司参与到Eclipse项目中,其中包括Borland、Rational Software、Red Hat及Sybase等。Eclipse是一个开发源码项目,它其实是 Visual Age for Java的替代品,其界面跟先前的Visual Age for Java差不多,但由于其开放源码,任何人都可以免费得到,并可以在此基础上开发各自的插件,因此越来越受人们关注。近期还有包括Oracle在内的许多大公司也纷纷加入了该项目,并宣称Eclipse将来能成为可进行任何语言开发的IDE集大成者,使用者只需下载各种语言的插件即可。
    2.4 SQLite的介绍SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2015年已经有15个年头,SQLite也迎来了一个版本 SQLite 3已经发布。
    3 系统需求分析3.1 需求分析生活中记录日常花销、收入总是琐碎累心的。特别是纸质记录,除了携带不方便外,还很容易丢失损毁。
    这个时候,若是我们身边常带的手机上有这么一款可以随时记录收入和支出的软件,因为在记录收支的同时,会有一些注意事项需要标注,比如欠钱还钱注意事项。在对各项数据进行记录后,用户会希望看到对各类数据的统计,所以需要满足基本需求的统计模块。为了保证数据安全,增设账户模块。为了区分各用户的操作习惯,所以增设收入支出类型管理模块和系统设置模块。
    3.2 可行性分析3.2.1 系统可行性可行性分析实在目前市场己有的类似系统调查的基础上,辩证新系统的研发是否具备开发必要性和可能性,对新系统的研发从技术、经济、社会因素等多个方面进行相关的分析和研究,以避免造成不必要的投资失误,保证和提高新系统开发成功的把握。可行性研究的目的就是以最小的时间、金钱代价确定疑难问题是否能够妥善解决。
    3.2.2 技术可行性此系统需要在Android手机操作系统上运行,用Eclipse进行开发,数据库我选用轻量级的SqLite。开发所需的软件技术成熟稳定,且支持Android系统的手机也分布广泛,可以完全满足所以的开发需求。
    至于自己在Android方面虽然没有基础,鉴于之前有Java编程经验且时间充裕,有足够时间来学习空白的知识。
    3.2.3 经济可行性从市场经济来看,近年来,国人生活品质提升,逐渐重视生活品质,手机应用便成了人们生活的一部分。当今社会己步入了一个全新的信息时代,人类的每个活动都和“信息”紧密的联系在一起,小至个人的衣食住行,大及国家大事新闻发布,都依与信息的传播与发布,而社会中最活跃的,在市场经济高速发展的现在,手机应用普遍化,生活化,低端化成了不可阻挡的趋势。
    从技术经济来看,由于SQLite数据库和Android SDK都是开源的免费的开发学习工具,而且本系统使用灵活方便,技术也不是很复杂,开发周期较短,因此开发成本较低。市场前景非常看好,所以说技术经济方面来看,本项目也是可行的。由此可以看出本系统开发所产生的效益将大于投入,所以开发本项目是可行的、必要的。
    综上所述,个人理财系统充分利用了软硬件资源,技术成熟,成本低廉,操作简单,管理方便,使理财记账摆脱空间的限制,实现自动化处理和信息化管理,因此,本系统的实施是可行的。
    3.3 系统功能模块
    用户管理:可以设置当前用户
    类别维护:用户可以添加日常收入、日常支出的类别,并且可以删除相应的类别,填写类别详细
    日常收入:用户可以按照日常收入日期、金额、类别、备注进行数据的增添
    日常支出:用户可以按照日常支出日期、金额、类别、备注进行数据的增添
    收入支出统计:按照一定的数据查询条件,用户可以对数据进行统计


    4 系统总体设计4.1 系统总体设计分析系统设计是系统开发过程中的核心,从需求出发,总体上描述系统架构应该包含的组成要素。系统总体设计尽可能模块化,描述了各个模块之间的关联。模块化是一种很重要的设计思想,把一个复杂的系统分解为一些规模较小、功能简单的、更易于建立和修改的部分。一方面,各个模块具有相对独立性,可以分别加以设计实现;另一方面,模块之间的相互关系则通过一定的方式予以说明。各模块在这些关系的约束下共同构成一个统一的整体,完成系统的功能。
    总体设计的核心内容就是依据需求分析定义的功能,合理、有效地实现系统中定义的各种需求,包括模块设计、数据库设计等。
    4.2 系统流程图根据系统分析以及功能需求,系统的基本流程可以描述为:主界面→选择各子功能模块,如下图所示:

    4.3 系统特点
    目的明确:理财就是以管钱为中心,通过抓好赚钱、生钱、护钱,三个环节,管好自己手中的现金流动,让资产在保值的基础上,实现稳定持续的增长
    功能齐全:系统覆盖了理财所需要的功能,收支,统计
    适应性强:系统采用基于模型的设计思,用户的特点抽象出管理模型,根据模型进行系统设计,使系统具有很好的开放性的拓展性,能够高效率地适应各用户群体的需求

    4.4 数据库设计4.4.1 tb_account(账户表)tb_account用于管理系统各个用户信息。_id为用户的唯一标识,为表的主键,也为其他表的_id相对应。Username和pwd分别代表着用户名和密码。这两个是用户后期可以修改的。
    账户表中存在着一个特殊的用户:默认用户。它的用户名密码用户不可见。用户在没有登陆的情况下,数据保存在这个用户下方。



    字段名
    数据类型
    是否主键
    描述




    _id
    Integer
    Y
    用户id


    USERNAME
    VARCHAR(20)
    N
    用户名


    PWD
    VARCHAR(50)
    N
    密码



    4.4.2 tb_income(收入信息表)TYPE_ID与tb_itype表的type_id对应。No为收入信息的编号,不同用户的收入信息存入数据库的时候,都是以no=1为起始的,进而往后递增。



    字段名
    数据类型
    是否主键
    描述




    _id
    INTEGER
    N
    用户id


    NO
    INTEGER
    Y
    编号


    MONEY
    DECIMAL
    N
    收入金额


    TIME
    DATE
    N
    收入时间


    TYPE_ID
    INTEGER
    N
    收入类别


    HANDLER
    VARCHAR(100)
    N
    放款方


    MARK
    VARCHAR(200)
    N
    备注


    PHOTO
    VARCHAR(200)
    N
    照片


    KIND
    VARCHAR(10)
    N
    类别



    4.4.3 tb_pay(支出信息表)TYPE_ID与tb_ptype表的type_id对应。No为收入信息的编号,不同用户的支出信息存入数据库的时候,都是以no=1为起始的,进而往后递增。



    字段名
    数据类型
    是否主键
    描述




    _id
    INTEGER
    N
    用户id


    NO
    INTEGER
    Y
    自增


    MONEY
    DECIMAL
    N
    支出金额


    TIME
    DATE
    N
    支出时间


    TYPE_ID
    INTEGER
    N
    支出类别


    ADDRESS
    VARCHAR(100)
    N
    消费地点


    MARK
    VARCHAR(200)
    N
    备注


    PHOTO
    VARCHAR(200)
    N
    照片


    KIND
    VARCHAR(10)
    N
    类别



    4.4.4 tb_ptype(支出类型表)tb_ ptype为支出类型表。由于每个用户都有对应的用户习惯,在添加支出信息时,收入类型的种类、使用频率都会有所不同。在此设计支出类型表,可以为用户提供修改支出类型的服务,根据自己的使用频率修改支出类型。



    字段名
    数据类型
    是否主键
    可否为空
    描述




    _id
    INTEGER
    N
    N
    用户id


    no
    INTEGER
    Y
    N
    类型编号


    type_id
    INTEGER
    N
    N
    类型id



    4.4.5 tb_itype(收入类型表)tb_itype为收入类型表。由于每个用户都有对应的用户习惯,在添加收入信息时,收入类型的种类、使用频率都会有所不同。在此设计收入类型表,可以为用户提供修改收入类型的服务,根据自己的使用频率修改收入类型。



    字段名
    数据类型
    是否主键
    可否为空
    描述




    _id
    INTEGER
    N
    N
    用户id


    no
    INTEGER
    Y
    N
    类型编号


    type_id
    INTEGER
    N
    N
    类型id



    5 系统详细设计与实现5.1 主界面设计快速记个人记账软件主界面,有4个Fragment页面。

    主界面使用4个Fragment和PopupWindow生成,部分代码:
    /** * 显示PopupWindow弹出菜单 */ private void showPopupWindow(View parent) { DisplayMetrics dm = parent.getResources().getDisplayMetrics(); int w_screen = dm.widthPixels; int h_screen = dm.heightPixels; // System.out.println("你的设备w_screen:" + w_screen + " h_screen:" + // h_screen); if (popWindow == null) { LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(R.layout.popwindow_layout, null); popWinLayout = (LinearLayout) view.findViewById(R.id.popwindow); // 创建一个PopuWidow对象 float radiowith = w_screen / 480.0f; float radioheight = h_screen / 800.0f; popWindow = new PopupWindow(view, (int) (popWinLayout.getLayoutParams().width), h_screen / 4); } // 使其聚集 ,要想监听菜单里控件的事件就必须要调用此方法 popWindow.setFocusable(true); pop_voiceView = (LinearLayout) popWinLayout .findViewById(R.id.pop_voice); pop_quickView = (LinearLayout) popWinLayout .findViewById(R.id.pop_quick); pop_voiceView.setOnClickListener(this); pop_quickView.setOnClickListener(this); // 设置允许在外点击消失 popWindow.setOutsideTouchable(true); // 设置背景,这个是为了点击“返回Back”也能使其消失,并且并不会影响你的背景 popWindow.setBackgroundDrawable(new BitmapDrawable()); // 设置菜单显示的位置 int xPos = (w_screen - popWinLayout.getLayoutParams().width) / 2; popWindow.showAsDropDown(parent, xPos, 12); // popWindow.showAsDropDown(parent, Gravity.CENTER, 0); // 监听菜单的关闭事件 popWindow.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { // 改变显示的按钮图片为正常状态 changeButtonImage(); } }); // 监听触屏事件 popWindow.setTouchInterceptor(new OnTouchListener() { public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { // 改变显示的按钮图片为正常状态 changeButtonImage(); } return false; } }); } /** * 点击了“明细”按钮 */ private void clickFriendfeedBtn() { // 实例化Fragment页面 fragmentPage1 = new FragmentPage1(); // 得到Fragment事务管理器 FragmentTransaction fragmentTransaction = this .getSupportFragmentManager().beginTransaction(); // 替换当前的页面 fragmentTransaction.replace(R.id.frame_content, fragmentPage1); // 事务管理提交 fragmentTransaction.commit(); friendfeedFl.setSelected(true); friendfeedIv.setSelected(true); myfeedFl.setSelected(false); myfeedIv.setSelected(false); homeFl.setSelected(false); homeIv.setSelected(false); moreFl.setSelected(false); moreIv.setSelected(false); }
    此处省略类似的函数…
    private void clickPop_voiceBtn() { Intent intent = new Intent(MainActivity.this, AddPay.class);// 创建Intent对象 intent.putExtra("cwp.id", userid); intent.putExtra("cwp.voice", "");// 设置传递数据 startActivity(intent); } private void clickPop_quickBtn() { Intent intent = new Intent(MainActivity.this, AddPay.class);// 创建Intent对象 intent.putExtra("cwp.id", userid); startActivity(intent); } /** * 点击了中间按钮 */ private void clickToggleBtn() { showPopupWindow(plusImageView); // 改变按钮显示的图片为按下时的状态 plusImageView.setImageResource(R.drawable.toolbar_plusback); toggleImageView.setImageResource(R.drawable.toolbar_btn_pressed); } /** * 改变显示的按钮图片为正常状态 */ private void changeButtonImage() { plusImageView.setImageResource(R.drawable.toolbar_plus); toggleImageView.setImageResource(R.drawable.toolbar_btn_normal); }
    5.2 收入/支出插入数据界面添加软键盘,来添加收入/支出消费记录

    添加收/支部分代码,需要判断是添加模式还是修改模式,是添加收入还是添加支出:
    btnSaveButton.setOnClickListener(new OnClickListener() {// 为保存按钮设置监听事件 @SuppressLint("NewApi") @Override public void onClick(View arg0) { if (typemode == "add") { // 添加模式 String strMoney = txtMoney.getText().toString();// 获取金额文本框的值 if (type == "pay") { // 支出 if (!strMoney.isEmpty()) {// 判断金额不为空 // 创建InaccountDAO对象 PayDAO payDAO = new PayDAO(AddPay.this); // 创建Tb_inaccount对象 Tb_pay tb_pay = new Tb_pay( userid, payDAO.getMaxNo(userid) + 1, get2Double(strMoney), setTimeFormat(null), (spType.getSelectedItemPosition() + 1), txtAddress.getText().toString(), txtMark.getText().toString()); payDAO.add(tb_pay);// 添加收入信息 Toast.makeText(AddPay.this, "〖新增收入〗数据添加成功!", Toast.LENGTH_SHORT) .show(); gotoback(); } else { Toast.makeText(AddPay.this, "请输入收入金额!", Toast.LENGTH_SHORT).show(); } } else { // 收入 if (!strMoney.isEmpty()) {// 判断金额不为空 // 创建InaccountDAO对象 IncomeDAO incomeDAO = new IncomeDAO( AddPay.this); // 创建Tb_inaccount对象 Tb_income tb_income = new Tb_income( userid, incomeDAO.getMaxNo(userid) + 1, get2Double(strMoney), setTimeFormat(null), (spType.getSelectedItemPosition() + 1), txtInhandler.getText().toString(), txtMark.getText().toString()); System.out.println("money" + get2Double(strMoney)); incomeDAO.add(tb_income);// 添加收入信息 // 弹出信息提示 Toast.makeText(AddPay.this, "〖新增收入〗数据添加成功!", Toast.LENGTH_SHORT) .show(); gotoback(); } else { Toast.makeText(AddPay.this, "请输入收入金额!", Toast.LENGTH_SHORT).show(); } } } else { // 修改模式 if (type == "pay") { // 支出 if (!txtMoney.getText().toString().isEmpty()) {// 判断金额不为空 Tb_pay tb_pay = new Tb_pay(); // 创建Tb_pay对象 tb_pay.set_id(userid); // 设置userid tb_pay.setNo(Integer.parseInt(strno)); // 设置编号 tb_pay.setMoney(get2Double(txtMoney .getText().toString()));// 设置金额 tb_pay.setTime(setTimeFormat(txtTime .getText().toString()));// 设置时间 tb_pay.setType(spType .getSelectedItemPosition() + 1);// 设置类别 tb_pay.setAddress(txtAddress.getText() .toString());// 设置地点 tb_pay.setMark(txtMark.getText().toString());// 设置备注 payDAO.update(tb_pay);// 更新支出信息 Toast.makeText(AddPay.this, "〖数据〗修改成功!", Toast.LENGTH_SHORT).show(); gotoback(); } else { Toast.makeText(AddPay.this, "请输入收入金额!", Toast.LENGTH_SHORT).show(); } } else { // 收入 if (!txtMoney.getText().toString().isEmpty()) {// 判断金额不为空 Tb_income tb_income = new Tb_income();// 创建Tb_income对象 tb_income.set_id(userid);// 设置编号 tb_income.setNo(Integer.parseInt(strno));// 设置编号 tb_income.setMoney(get2Double(txtMoney .getText().toString()));// 设置金额 tb_income.setTime(setTimeFormat(txtTime .getText().toString()));// 设置时间 tb_income.setType(spType .getSelectedItemPosition() + 1);// 设置类别 tb_income.setHandler(txtInhandler.getText() .toString());// 设置付款方 tb_income.setMark(txtMark.getText() .toString());// 设置备注 incomeDAO.update(tb_income);// 更新收入信息 Toast.makeText(AddPay.this, "〖数据〗修改成功!", Toast.LENGTH_SHORT).show(); gotoback(); } else { Toast.makeText(AddPay.this, "请输入收入金额!", Toast.LENGTH_SHORT).show(); } } } } });
    软键盘部分代码:
    public void onKey(int primaryCode, int[] keyCodes) { Editable editable = ed.getText(); if (typemode.equals("ModifyInP")) { // 添加模式获取开始光标 ed.setSelection(editable.length()); } int start = ed.getSelectionStart(); if (primaryCode == Keyboard.KEYCODE_DELETE) { // 删除键 if (editable != null && editable.length() > 0) { if (start > 0) { editable.delete(start - 1, start); if (ed.getText().toString().indexOf(".") < 0) { a = true; } } } } else if (primaryCode == -7) { //隐藏键盘 hideKeyboard(); } else if (primaryCode == -8) { //小数点 if (start > 0 && a) { editable.insert(start, "."); a = false; } } else if (primaryCode == -9) { //语音识别 hideKeyboard(); dialogShowUtil.dialogShow("rotatebottom", "first", "", ""); } else { editable.insert(start, Character.toString((char) primaryCode)); } } }; public void showKeyboard() { //显示键盘 int visibility = keyboardView.getVisibility(); if (visibility == View.GONE || visibility == View.INVISIBLE) { keyboardView.setVisibility(View.VISIBLE); } } public void hideKeyboard() { //隐藏键盘 int visibility = keyboardView.getVisibility(); if (visibility == View.VISIBLE) { keyboardView.setVisibility(View.INVISIBLE); } }
    5.3 语音记账界面语音记账使用了百度语音识别api,通过响应用户的触发,调用api动态生成百度自定义的dialog来进行用户语音录音。当用户录入语音后,返回语音识别的数据,然后转为字符串并进行分析判断。目前主要以金额和类别来作为关键字来进行判断,首先通过将识别字符串通过跟收入/支出类别进行对比,如果存在相关类别即标记下当前录入的类别;如果没有当前这个类别,将会弹出自定义Dialog让用户去选择即使没有匹配的类别,是否依然要录入,如果“是”,该笔类型就会默认为“语音识别”类别,并会让用户去选择当前记录是“支出”还是“收入”,再去结合当前的金额录入数据;如果用户录入的类别同时存在于“收入”和“支出”之中,那么就会让用户去选择该笔记录是“收入”还是“支出”,在去结合当前的金额录入数据。另一方面,将识别字符串与自定义的列如“一”,“二”,“元”,“钱”…去对比,然后标记下这个金额的起始和结束位置,然后截取出来,并调用工具类把这个汉字的金额转变为阿拉伯数字。最后使用方法去判断当前是“添加模式”还是“修改模式”,然后再判断是“支出”还是“收入”,然后录入数据库。














    百度识别回调部分代码:
    mRecognitionListener = new DialogRecognitionListener() { // 百度识别返回数据 @Override public void onResults(Bundle results) { ArrayList<String> rs = results != null ? results .getStringArrayList(RESULTS_RECOGNITION) : null; if (rs != null && rs.size() > 0) { Recognition(rs.get(0)); // Toast.makeText(AddPay.this, rs.get(0), // Toast.LENGTH_SHORT).show(); } }};void VoiceRecognition() { // 百度语音识别// mResult.setText(null);mCurrentTheme = Config.DIALOG_THEME;if (mDialog != null) { mDialog.dismiss();}Bundle params = new Bundle();params.putString(BaiduASRDigitalDialog.PARAM_API_KEY, Constants.API_KEY); //百度语音api_keyparams.putString(BaiduASRDigitalDialog.PARAM_SECRET_KEY, Constants.SECRET_KEY);params.putInt(BaiduASRDigitalDialog.PARAM_DIALOG_THEME, //百度语音主题 Config.DIALOG_THEME);mDialog = new BaiduASRDigitalDialog(this, params); mDialog.setDialogRecognitionListener(mRecognitionListener);mDialog.getParams().putInt(BaiduASRDigitalDialog.PARAM_PROP, //百度识别类别 Config.CURRENT_PROP);mDialog.getParams().putString(BaiduASRDigitalDialog.PARAM_LANGUAGE,//百度识别语言 Config.getCurrentLanguage());mDialog.getParams().putBoolean( //百度识别音效相关 BaiduASRDigitalDialog.PARAM_START_TONE_ENABLE, Config.PLAY_START_SOUND);mDialog.getParams().putBoolean( BaiduASRDigitalDialog.PARAM_END_TONE_ENABLE, Config.PLAY_END_SOUND);mDialog.getParams().putBoolean( BaiduASRDigitalDialog.PARAM_TIPS_TONE_ENABLE, Config.DIALOG_TIPS_SOUND);mDialog.show();}/* * 识别结果处理函数 * * @param VoiceSave[0] 收入类别的值 * * @param VoiceSave[1] 金额的值 * * @param VoiceSave[3] 重复类别的值,仅用于显示提醒 * * @param VoiceSave[4] 支出类别的值 * * @param VoiceSave[5] "语音识别"类别的值 */private void Recognition(String t) { int mfirst = 100, mend = 0, temp = 0; Boolean ismoney = false, intype = false, outtype = false; String w = "", strmoney = "", inname = "1", outname = "2"; spdatalist = ptypeDAO.getPtypeName(userid); spdatalist2 = itypeDAO.getItypeName(userid); VoiceSave[2] = t; for (int i = 0; i < spdatalist.size(); i++) { // 判断是否包含支出 if (t.indexOf(spdatalist.get(i).toString()) > -1) { type = "pay"; intype = true; inname = spdatalist.get(i).toString(); VoiceSave[0] = Integer.toString(i); // VoiceSave[0]为收入类别的值 } } for (int i = 0; i < spdatalist2.size(); i++) { // 判断是否包含收入 if (t.indexOf(spdatalist2.get(i).toString()) > -1) { type = "income"; outtype = true; outname = spdatalist2.get(i).toString(); VoiceSave[4] = Integer.toString(i); // VoiceSave[4]为支出类别的值 } } for (int i = 0; i < number.length; i++) { // 判断是否包含金额,获得开头 if (t.indexOf(number[i]) > -1) { temp = t.indexOf(number[i]); if (temp < mfirst) { mfirst = temp; } } } for (int i = 0; i < money.length; i++) { // 判断是否包含金额,获得结尾 if (t.indexOf(money[i]) > -1) { temp = t.indexOf(money[i]); if (temp > -1 && temp >= mend) { mend = temp; } } } for (int i = 0; i < money2.length; i++) { // 判断是否包含金额,获得结尾 if (t.indexOf(money2[i]) > -1) { temp = t.indexOf(money2[i]); if (temp > -1 && temp >= mend) { mend = temp; } mend = mend + 1; } } if (!(mfirst == 100 || mend == 0)) { // 转换为阿拉伯数字 ismoney = true; strmoney = t.substring(mfirst, mend); DigitUtil Util = new DigitUtil(); VoiceSave[1] = Integer.toString(Util.parse(strmoney)); // 调用工具类处理汉字的金额 } if (intype && outtype) { // 如果含金额 if (outname.equals(inname)) { if (ismoney) { VoiceSave[3] = outname; // VoiceSave[3]为重复类别的值,仅用于显示提醒 dialogShowUtil.dialogShow("shake", "judge", t, w); // 如果含有金额 } else { w = "提示:\n你的话中没有包含消费或开支的<金额>\n"; dialogShowUtil.dialogShow("shake", "wrong", t, w); } } else { w = "**提示:\n一次只能记录一条记录哦\n"; // 如果含有收入并且支出的类别 dialogShowUtil.dialogShow("shake", "wrong", t, w); } } else { if (!((intype || outtype) || ismoney)) { // 如果不含金额 w = "**提示:\n你的话中没有包含<类别>(" + listToString(spdatalist, ',') + "," + listToString(spdatalist2, ',') + ")\n\n**提示:\n你的话中没有包含消费或开支的<金额>"; dialogShowUtil.dialogShow("shake", "wrong", t, w); } else if ((intype || outtype) && (!ismoney)) { w = "提示:\n你的话中没有包含消费或开支的<金额>\n"; dialogShowUtil.dialogShow("shake", "wrong", t, w); } else if ((!(intype || outtype)) && ismoney) { for (int i = 0; i < spdatalist.size(); i++) { // 判断是否包含支出 if ("语音识别".indexOf(spdatalist.get(i).toString()) > -1) { VoiceSave[5] = Integer.toString(i); VoiceSave[3] = "语音识别"; } } w = "**提示:\n你的话中没有包含<(默认)类别>(" + listToString(spdatalist, ',') + ")\n\n\n将会记录为<语音识别>类别,是否依然记录?\n"; dialogShowUtil.dialogShow("shake", "notype", t, w); } else { dialogShowUtil.dialogShow("rotatebottom", "OK", t, w); } }}
    Dialog部分处理代码:
    public void dialogShow(String showtype, String style,final String context1, String context2) {dialogBuilder = new NiftyDialogBuilder(ctx, R.style.dialog_untran); // 自定义dialogBuilderswitch (showtype) {case "rotatebottom":effect = Effectstype.RotateBottom;break;case "shake":effect = Effectstype.Shake;break;}switch (style) {case "first":dialogBuilder.withTitle("语音记账") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage("语音格式:\n早餐在餐厅食了20元。\n\n") // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def |// // isCancelable(true) .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("取消") // def gone .withButton2Text("开始语音") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); ((AddPay) act).VoiceRecognition(); } }).show();break;case "notype":dialogBuilder.withTitle("识别成功") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage("你刚刚说了“ " + context1 + "”\n\n" + context2) // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def |// .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("取消") // def gone .withButton2Text("是") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); VoiceDefault = "notype"; VoiceSave[3]=VoiceSave[3]; dialogShow("shake", "judge", context1, ""); } }).show();break;case "wrong":dialogBuilder .withTitle("识别失败") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage( "你刚刚说了“ " + context1 + "”不符合格式,请再试一次\n\n" + context2) // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def | // isCancelable(true) .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("取消") // def gone .withButton2Text("再次语音") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); ((AddPay) act).VoiceRecognition(); } }).show();break;case "OK":dialogBuilder.withTitle("识别成功") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage("成功!\n你刚刚说了“" + context1 + "”,\n是否确定要记录这条数据?") // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def | // isCancelable(true) .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("取消") // def gone .withButton2Text("确定") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); ((AddPay) act).VoiceSuccess(); } }).show();break;case "judge":dialogBuilder .withTitle("识别成功") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage( "成功!\n你刚刚说了“" + context1 + "”,\n<" + VoiceSave[3] + ">类别需要你请确认该笔是<开支>还是<收入>?\n") // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def | // isCancelable(true) .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("开支") // def gone .withButton2Text("收入") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); type = "pay"; ((AddPay) act).VoiceSuccess(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); type = "income"; ((AddPay) act).VoiceSuccess(); } }).show();break;case "quit":dialogBuilder.withTitle("退出程序") // .withTitle(null) no title .withTitleColor("#FFFFFF") // def .withDividerColor("#11000000") // def .withMessage("是否要退出程序?\n\n") // .withMessage(null) no Msg .withMessageColor("#FFFFFF") // def .withIcon(ctx.getResources().getDrawable(R.drawable.icon)) .isCancelableOnTouchOutside(false) // def | // isCancelable(true) .withDuration(700) // def .withEffect(effect) // def Effectstype.Slidetop .withButton1Text("取消") // def gone .withButton2Text("退出") // def gone .setButton1Click(new View.OnClickListener() { @Override public void onClick(View v) { dialogBuilder.dismiss(); } }).setButton2Click(new View.OnClickListener() { @Override public void onClick(View v) { SysApplication.getInstance().exit(); } }).show();break;}}
    5.4 类别维护界面增加或删除收入/支出类别,并判断类别是否重复是否为空。

    部分代码:
    private void inputTitleDialog() { final EditText inputServer = new EditText(InPtypeManager.this); inputServer.setFocusable(true); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("添加类型").setView(inputServer) .setNegativeButton("取消", null); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { inputStr = inputServer.getText().toString(); int i = (int) itypeDAO.getCount(userid) + 1; if (inputStr.trim().equals("")) { Toast.makeText(InPtypeManager.this, "输入内容不能为空!", Toast.LENGTH_LONG).show(); refresh(); } else{if(flag){Toast.makeText(InPtypeManager.this, "不可以重复插入!", Toast.LENGTH_LONG).show();}else{if (type == 0) { itypeDAO.add(new Tb_itype(userid, i, inputStr)); } else { ptypeDAO.add(new Tb_ptype(userid, i, inputStr)); }} refresh(); } }); builder.show(); }
    5.5 收入/支出统计界面收入支出统计页面,通过使用第三方开发的图表显示控件,通过从SQLite获取的数据和计算所占总数的百分比,去初始化图表显示,然后通过线程更新当前的UI。左右的按钮是调用上一个月和下一个月的数据,然后重新调用该activity来显示。另外我还添加了侧滑菜单来让用户选择是“收入图表”和“支出图表”,另外用户还能选择指定的日期范围,数据也是调用该页面显示。

    public void initView() { time = new Time("GMT+8"); time.setToNow(); defaultMonth = time.month + 1;// 设置默认月份 defaultYear = time.year; intentr = getIntent(); userid = intentr.getIntExtra("cwp.id", 100000001); defaultMonth = intentr.getIntExtra("default", defaultMonth); defaultYear = intentr.getIntExtra("defaulty", defaultYear); type = intentr.getIntExtra("type", 0);// 为0,选择上下月,为1,选择任意时间 pieView = (PieView) this.findViewById(R.id.lotteryView); myButton = (MyButton) this.findViewById(R.id.MyBt); textView = (TextView) this.findViewById(R.id.MyTV); textView2 = (TextView) this.findViewById(R.id.MyTVbottom); example_left = (ImageView) findViewById(R.id.example_left); example_right = (ImageView) findViewById(R.id.example_right); example_center = (TextView) this.findViewById(R.id.example_center); textView.setOnClickListener(this); example_left.setOnClickListener(this); example_right.setOnClickListener(this); example_center.setText(String.valueOf(defaultYear) + "年 - " + String.valueOf(defaultMonth) + "月"); //获取数据 if (type == 0) { KindDatap = payDAO.getKDataOnMonth(userid, defaultYear, defaultMonth); } else { date1 = intentr.getStringExtra("date1"); date2 = intentr.getStringExtra("date2"); KindDatap = payDAO.getKDataOnDay(userid, date1, date2); } initItem(); //初始化数据 if (!(KindDatap.size() == 0)) { //当获取到数据时 Message msg = new Message(); msg.obj = pieView.getCurrentChartProp(); handler.sendMessage(msg); //发送消息,更新UI } pieView.setChartPropChangeListener(new ChartPropChangeListener() { @Override public void getChartProp(ChartProp chartProp) { Message msg = new Message(); msg.obj = chartProp; handler.sendMessage(msg); //发送消息,更新UI } }); pieView.start();}public Handler handler = new Handler() { //创建线程 public void handleMessage(android.os.Message msg) { ChartProp chartProp = (ChartProp) msg.obj; myButton.setBackgroundPaintColor(chartProp.getColor()); textView.setText(chartProp.getName()); textView2.setText(chartProp.getName2()); textView.setTextColor(chartProp.getColor()); };};/** * * Description:初始化转盘的颜色 * */public void initItem() { int i = 0; int fivecolor[] = new int[] { Color.rgb(56, 220, 244), Color.GREEN, Color.RED, Color.YELLOW, Color.CYAN }; if (KindDatap.size() == 0) { // 没有数据的情况 amount = "暂无数据"; // 无数据下总数的提示文字 } else { // 获取数据的情况 double sum = 0.00; for (KindData kp : KindDatap) { sum += kp.getAmount();// 取得总和 i++; } // 初始化数组 String names[] = new String[i]; float percent[] = new float[i]; String names2[] = new String[i]; int color[] = new int[i]; i = 0; for (KindData kp : KindDatap) { names[i] = ptypeDAO.getOneName(userid, kp.getKindname()); if (i < fivecolor.length) { color[i] = fivecolor[i]; // 使用自定义颜色 } else { color[i] = getRandomColor(); // 使用随机生成的颜色 } java.text.NumberFormat percentFormat = java.text.NumberFormat .getPercentInstance(); percentFormat.setMaximumFractionDigits(2); // 最大小数位数 // 自动转换成百分比显示. names2[i] = percentFormat.format(kp.getAmount() / sum) + ":¥" + kp.getAmount(); percent[i] = (float) (kp.getAmount() / sum); // 计算所占百分比 i++; } amount = Double.toString(sum); // 总数的费用 // 创建图表 ArrayList<ChartProp> acps = pieView.createCharts(i); int size = acps.size(); for (int k = 0; k < size; k++) { // 把数据传入图表 ChartProp chartProp = acps.get(k); chartProp.setColor(color[k]); chartProp.setPercent(percent[k]); chartProp.setName(names[k]); chartProp.setName2(names2[k]); } pieView.initPercents(); }}private int getRandomColor() {// 分别产生RBG数值 Random random = new Random(); int R = random.nextInt(255); int G = random.nextInt(255); int B = random.nextInt(255); return Color.rgb(R, G, B);}public static String getamount() { return amount;}@Overridepublic void onClick(View v) { switch (v.getId()) { case R.id.example_left: // 上一个月的按键 if (defaultMonth != 1) defaultMonth = defaultMonth - 1; else { defaultMonth = 12; defaultYear = defaultYear - 1; } Intent intentl = new Intent(PayChart.this, PayChart.class); intentl.putExtra("defaulty", defaultYear); intentl.putExtra("default", defaultMonth); intentl.putExtra("cwp.id", userid); startActivity(intentl); break; case R.id.example_right: // 下一个月的按键 if (defaultMonth != 12) defaultMonth = defaultMonth + 1; else { defaultMonth = 1; defaultYear = defaultYear + 1; } Intent intentr = new Intent(PayChart.this, PayChart.class); intentr.putExtra("defaulty", defaultYear); intentr.putExtra("default", defaultMonth); intentr.putExtra("cwp.id", userid); startActivity(intentr); overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right); break; }}
    6 论文总结从一月开始,经过这三个月的学习奋斗,毕业设计到现在终于基本上已经完成了。在这段日子里从系统的需求分析开始,然后到对系统功能。
    进行详细设计,最后到系统的编码实现,最后到论文的完成,我通过查阅大量的图书与文献自学相关知识,同时也诚心请教同学和老师,通过与他们的交流我学到了很多专业知识和经验,让我受益匪浅,对相关专业知识有了一个新的认识,当遇到有不认识或未曾遇到过的错误,上网寻找资料,解决难题,让我懂得网上的资源是十分之多,令我获益良多,这些锻炼了我坚强的意志,同时也使我的专业知识更加扎实,让我在以后的人生职业道路上可以更加的自信和顽强。
    毕设做到现在,算是告一段落。谈起为什么选Android,我只能说感兴趣,而又没毅力。在没有压力的情况下,让我去专研一门不懂的东西可行性太低。只能说很了解自己的性子。我想通过这种方式逼自己,幸好没让自己失望。虽然此次的毕设没有很有技术含量,但还是算勉强够凑合吧。
    希望经过后期的维护肯定能达到使用要求,更好完善自己系统的功能。
    参考文献[1] FrankAbleson.Introductionto Android development[J].developerWorks,2009,10(7).
    [2] Ed Burnett, Hello, Android: Introducing Google’s Mobile Development Platform[J]. PRAGMATIC BOOKSHELF,2010.7:10-11.
    [3] 徐娜子.Android江湖 [M].电子工业出版社.2011.11
    [4] 郭志宏. Android应用开发详解[M].电子工业出版社. 2010.
    [5] 明日科技.Android从入门到精通 [M].清华大学出版社.2012.9
    [6] 杨丰盛.Android应用开发揭秘[M]. 机械工业出版社. 2010.
    [7] 孙宏明.Android手机程序设计入门、运用到精通 [M].中国水利水电出版社.2012.3
    [8] 张仕成.基于Google Android平台的应用程序开发与研究[j].电脑知识与技,术2009.(5)
    [9] 靳岩,姚尚朗. Google Android开发入门与sss实践[M].人民邮电出版社. 2009
    [10] 姚永明,吕建平. 基于Android平台的用户管理软件的设计与实现[J]. 西安文理学院学报(自然科学版),2013,01:79-83.
    [11] 武玉坤.基于Android移动学习平台的设计[J]. 计算机光盘软件与应用,2013,01:20-21+47.
    [12] 姜海岚.基于Android的多功能手机相册设计与实现[J]. 电脑知识与术,2013,15:3614-3616.
    [13] 李刚.疯狂Android讲义 [M].电子工业出版社.2011.6
    [14] 李宁.Android应用开发实战[M].第2版. 机械工业出版社.2013
    2 评论 58 下载 2019-03-24 12:23:31 下载需要19点积分
  • 基于80x86汇编的英文填字游戏程序

    一、游戏背景介绍英文作为全世界通用语言,也是当今世界上应用最广泛的语言,世界上以英语为母语的人近4亿,并且已经有约20个国家把英语作为官方语言或者第二语言使用,在国际政治、经济、军事、科技、文化、贸易等众多领域,都使用的英语进行交流。随着我国对外开放的不断扩大化,科学技术的不断进步,国际地位的不断提高,急需造就一大批精通外语的专门人才,使我国在国际事务中发挥更大更积极的作用。因此,学好英语对我国现实上述目标的实现具有重大意义。
    而对于我们普通人的生活来说,无论是求职还是深造,都离不开英语的运用,因此,无论在哪个国家,英语都受到了人们的广泛学习,其重要性不言而喻。作为一名学生,我从小学便开始学习英语单词、语法、对话等,而单词也是英文学习中最基础的部分,英文单词枯燥无味,习惯于中文表达的中国学生并不是太容易学会,所以我们要探索新的方法来更高效地学习英文,也更加深我们对单词的印象。
    在现代生活中,电脑已经和我们的工作学习息息相关,而英语也是和电脑联系最密切的语言,作为计算机相关专业的学生,我们需要阅读不少英文资料与文献,所以我们也需要较高的英文水平,才能使我们的专业水平进一步提高。
    因此,我们便用汇编语言设计了一个简单的英文填字游戏,此游戏不仅适合于初学者,也对英文程度较好的人有帮助进一笔加深记忆的功能,游戏与单词学习相结合,使英文学习更加有趣,不似普通背单词一样枯燥,使我们的学习更加有效。
    游戏刚开始时,页面中显示游戏名称English Crossword Game、生命次数为3、和第一关的单词,此时光标位于Rank1的单词中的第一个空缺字母处,用户可开始输入字母了,当用户填写正确完一关会自动出现下一关。

    编写英文填字游戏软件时,综合了复习字符输入和显示、置光标、开窗口、颜色设置、删除字符等屏幕功能;掌握分支程序中字符比较及统计数量的程序设计,循环及排序程序设计方法考察了对数组和普通变量的定义。
    当Rank1-Rank6都正确填完后,表示游戏成功,系统出现一个与所填写的单词有关的圣诞树以示祝贺。

    游戏中共有3次机会,每输错一个字母,机会减一,若3次机会用完时,未填写完所有单词,则游戏失败,显示已正确完成的单词数量。

    二、核心算法思想编写一个英文填字游戏。我们预先确定了五个常用的单词作为此游戏的所填空缺单词,当游戏开始时,首先需要在屏幕中依次出现Rank1-Rank5以及有空缺的单词,当Rank1的空缺字母全部填写正确,系统自动出现Rank2及单词,以此类推,然后用户通过观察单词以及各个单词之间的联系,初步判断应该填入哪些字母,通过上、下、左、右地移动置光标位置,表示缺字母的位置,以提示填入合适字母,每当有字母填写完成,系统判断所填写内容是否正确,若正确,光标跳转至本单词的下一个空缺位置,如果此单词已经填写完成,则光标跳转至下一个单词的首个空缺;若错误,则光标不做移动,用户可重新输入,直至输入正确,光标才可继续向下进行。
    此游戏中预设定了五个单词,分别为wish you a white christmas,添加空缺后为ish _o w_it ch_is_m_s。当游戏开始,首先显示Rank1和关卡1中已经预设的带有空缺的单词,等待参与者输入字母进行填补,参与者根据光标位置判断应该输入哪些字母使单词通顺合理,当有字母输入后,游戏通过数组来记录体验者一次游戏完成的单词量,完成一个数组自动加一,当正确填写完一个单词,则数目加一,直至游戏全部完成或者游戏中途失败。使用一个变量表示体验者的生命值,初值设置为3,表示体验者在本次游戏中共有3次机会可重新填入字母,如果填写失败一次,代表生命的变量值就自动减一,直到为0,提前退出游戏,表示游戏失败,显示出本次游戏已经完成的单词量,用户可选择者退出游戏或者重新开始新一轮的游戏,当有生命剩余且填写正确了所有单词,则表示成功通关。
    填写单词就涉及到判断填入的字母正确与否,游戏不能无限制次数地输入错误字母,而是对参与者填入的字母进行判断,如果填写正确空缺字母,则显示绿色提示,并置光标到下一个要填写的位置,等待输入,如果正确补全一个单词,则自动置光标到下一个单词的空缺处,则开始第二关游戏,重复此操作,直至顺利填完所有单词且3次机会仍有剩余,在游戏单词下方出现一个绿色圣诞树表示祝贺通关。如果输入错误字母超过三次,,并且显示填写正确的单词数。每当用户正确或错误地输入字母,系统都会将其与正确答案比对,然后给出不同提示,输入正确为绿色提示,输入错误为红色提示,当用户看到提示便可及时纠正错误或者继续填写。
    对于此次游戏的成功或是失败,我们分别设置了奖励和惩罚制度,也方便用户判断自己对单词的掌握和填写情况。在关卡1到关卡5中,一共有9个空缺需要填写,而我们设置的是若是一共有3个字母填写错误即为游戏失败,此时不可继续输入字母,退出输入并且显示挑战失败,打印出此次游戏中用户已经填写正确的单词数量,将提示字体设置为红色,更加醒目地使用户看到,提醒用户退出或者重新开始;当在游戏中用户将五个单词全都填写正确,或者只错误一次到两次,则系统判定此次游戏成功,界面中会显示一个绿色圣诞树和星星以表祝贺和鼓励,然后,游戏即可退出。
    本游戏简单直观,主要为考察参与者的单词记忆能力和游戏应变能力,同时采用英文与游戏方式结合,可大大加深用户对这些常用单词的记忆与理解,伴有奖励的游戏,可增强用户的信心,使用户更有兴趣完成本次游戏。
    游戏过程设计如下:

    设计菜单及彩色显示界面,在窗口内显示英文游戏名称,第几关卡(Rank),空缺的单词,生命总数3,剩余生命次数,光标位置设置到第一个空缺处
    每一个关卡中光标转移到空缺处,等待用户键入。如果字母填对,光标跳到同一单词的下一个空缺位置;当单词填写全对,则系统自动出现进入下一关及下一个空缺单词
    单词正右方显示生命剩余次数,每个单词后有提示显示每个单词的正确和错误填入的个数,正确字母提示为绿色小桃,错误字母提示为红色叉,生命次数减少至零后,系统直接自动退出游戏
    如果某一字母填写错误,则错误次数加一,代表生命的变量life减一,三次为限,错误三次后,游戏失败,记录已完成的单词数。按ESC键退出并打印正确的单词个数
    每填写正确一个字母,游戏自动出现一个绿色小桃,表示填写正确,当正确个数超过一定比例后,在游戏最后会在圣诞树旁边给予n个五星奖励,并有鼓励字样,当游戏在有限的生命值中全部完成,即游戏成功通过,游戏最后,出现圣诞树以示奖励

    三、核心算法流程图游戏流程主要分为两个部分,游戏成功或失败的判定,和系统对此次游戏的评价。
    当游戏开始,首先置生命次数为3,当输入字母时,系统判断输入是否正确,若正确,则继续输入下一个空缺字母,直至完成关卡,即游戏成功,若不正确,则机会减少一次,直至3次机会用完,此时游戏失败。

    游戏进行过程中,若判定了游戏成功,游戏界面出现圣诞树作为奖励;但是在机会已经用完时还没有完成单词,则游戏失败,界面显示已经完成的正确单词数。

    四、开发中遇到的问题4.1 在用户输入字母时,系统如何判断输入的内容是否与正确单词中的字母相同?游戏的核心部分就是判断用户输入的字母是否正确,以便系统给出不同的提示,用户进行英文空缺填补,输入字母,而我们已经学过,a-z每一个字母都对应有自己本身并且唯一的ASCII码值,我们抓住字母有唯一对应的ASCII码值这一特性,我们用正确得预设定字母的ASCII码与用户输入字母的ASCII码做对比,二者的ASCII码相同则输入正确,不同则判定为输入不正确。通过查表可知26个小写字母的ASCII码范围为61H—7AH,首先若是用户输入的内容不在这一范围内,则输入错误,只有当用户输入内容为小写字母时,再与预设定的字母ASCII码进行比对,判断是否与正确字母的ASCII相同,相同则输入正确,光标移动,不同则输入机会减一,光标不动。
    4.2 当用户正确输入字母后,如何令光标移动到下一个空缺位置或下一个单词的第一个空缺位置以及如何实现用户编辑时字母的删除?对光标操作时,每当上一个空缺输入正确,则光标自动移动到下一个空缺,我们采用dh和dl变化时,调用BIOS中断INT 10h(AH=2),利用10号中断的2号功能,首先预设置好每一个关卡中单词的空缺位置,当上一个空缺完成后,通过改变dh和dl的值,来设定光标的上、下、左、右的移动即可完成光标在空缺字母处的移动。在处理边界问题时,要令光标移动到行首则上移至上一个单词,光标移动到行尾是则下移至下一个单词的第一个空缺位置,再依次输入,利用了相同的方法。
    用户删除字母时,操作的实现与光标的移动大致相同,即为光标的左移,同时利用21号中断法,在相同位置输出空格键即可删除错误的字母,进行再次输入。
    4.3 我们令游戏中用户输入机会有限,如何实现当用户开始游戏后,共输错3次时,系统判定此次游戏失败?在解决这个问题时,我们原本的思路是结合以前在c++中学到的内容,利用数组表示剩余生命次数。基本原理就是寄存器相对寻址,但是由于此游戏设计中不涉及到较大的数字,采用数组记录没有必要,我们便采用更直接明了的方法,直接定义操作数life,汇编语言并不像其他高级语言一样把变量分为许多类型,它是按照长度来区分的,life的初值较小,设置为3,每当系统通过ASCII码比对判断输入字母不正确,则执行DEC life操作,即life生命数减一,同时出现红叉,再次错误则继续减一,直至life减为0,判断life为0时,游戏直接结束,这种方法我们更容易想到,且容易实现。
    4.4 游戏过程中,如何记录用户已完成的单词数量,方便在用户游戏失败时显示目前游戏已完全完成的单词数目?解决如何记录单词数量时,我们引入数组,定义此变量时,由于数量较小,所以定义的变量占一个字节的长度。首先定义一个数组变量代表完成单词数量,将数组首地址放到寄存器中,数组的下标值作为相对偏移量,并且分配的内存字节数用另一个寄存器表示。每当光标移动至当前行的下一行,或者根据关卡即Rank的增加判断数量,每当Rank加一,则数组加一。在这个数组表示中,定义数组时,只需要为开辟一个字节的内存空间来存放。当游戏最后需要读取数组元素时,通过寻找数组内存位置来找到数组。
    六、心得体会在此次英文填字游戏的设计中,既明白了更多的知识,也收获了不少阅历。这是我初次接触汇编语言,他并不像高级语言那样的通俗易懂,也没有高级语言灵活好用,这就给我的学习与设计带来了较大的困难。值得庆幸的是,在学习过程中,有同学们给我指点方向,也可在网上查到需要用到的相关资料,更有老师对我们的程序以及设计的指导,这使我的思考和动手能力得到了提升。在设计游戏过程中,我懂得了许多关于汇编语言的用法,也积极与同学们沟通,共同商量英文填字游戏的设计思想,在参考其他游戏的程序设计时,我了解到了更多有关游戏的理念,虽然在此过程中有困难、有争论、有懈怠,但是我们还是完成了此次游戏的设计与开发。只要我们用心学习,刨根问底,就一定有希望。完成了此次设计,不仅学习到了更多,也使我更有信心去完成其他课程的学习,更增强了我对计算机语言的兴趣。在今后的学习中,我会更加勤奋,为未来打下坚实的基础。
    0 评论 1 下载 2019-06-19 16:58:34 下载需要6点积分
  • 基于80x86的导弹打飞机游戏

    一、软件背景介绍1.1 背景知识飞机射击游戏最早的追溯应该是FC上的简单《小蜜蜂》了吧,那不断变换阵型的蜜蜂们和时不时来个俯冲攻击的蜜蜂,让这款游戏耐玩性十足。随后《小蜜蜂》也诞生了很多衍生产品包括大量的效仿和山寨的游戏,玩法多样化,包括有防御塔的、可以升级飞机的、彩色版本的。不得不说《小蜜蜂》是开创了打飞机游戏的鼻祖之一。
    在FC上,沙罗曼蛇、魂斗罗、赤色要塞、绿色兵团并誉为“四强”,风靡整个八十年代,为诸多80前玩家们所津津乐道。在FC上沙罗曼蛇首次采用横版的射击方式,一改以往的竖版射击,也算是开创横版射击的鼻祖游戏。对于初上手的玩家来讲,这个游戏的难度偏大。游戏中玩家控制一架飞机与敌人战斗,通过得取能量箱可改变自己的武器。在游戏设定上是其他同类游戏远远比不上的佳作。
    打飞机游戏其实有着很悠久的历史了,从开始的开发到现在的行业蓬勃发展。从最初简单的小程序到现在有的大型游戏设计,可谓是发展的也越来越好、与时俱进。而我们团队也正式此类游戏的爱好者,并愿意用己所学去开发这么一个项目。
    此游戏上手也及其简单,仅仅需要控制飞机的移动,若击中目标即可得分。这也是这么多年来它经久不衰的原因了。
    1.2 基本功能游戏的主体部分既然是打飞机,那么飞机是什么呢?飞机就是我们程序中在靠近上方的图样。飞机有两架都由三格组成,它会缓慢的移动。下面是我们的发射器。我们可以操控发射器来使他左右移动。接下来若发射器的子弹打中飞机的一部分,飞机相应的那一格就会消失,然后我们会得分。打中一次得两分。总分记录在左上角。按退出键则游戏结束。
    1.3 运行截图


    二、核心算法思想游戏区域主要由五个部分组成,分别是得分,两只飞机,导弹以及导弹射出的子弹构成。此处要注意布局,另外要注意飞机与导弹移动时的边界检测。还有数据的擦除。
    游戏开始时要先进入欢迎界面,并提示玩家如何操作导弹来打飞机,进入到游戏界面后,应该有两只飞机在屏幕上方移动,玩家可以操纵屏幕下方的导弹发射子弹,若是击中飞机则会使飞机被击中的那一部分消失,同时分数增加,分数记录在屏幕的左上角。导弹和飞机的移动以及导弹子弹的发射要通过图像的擦出来实现。
    由于两只飞机的外形相同,以及飞机和导弹的擦除;两只飞机的移动轨迹相同,所以这些问题都可以之解决一遍,另一只飞机可以看为是第一支飞机的复制体。导弹的擦除与飞机的擦除也可以看为一类问题。
    两只飞机以及导弹的外形主要由ASCII码值来确定,同时设定导弹及飞机的字符属性及行偏移以及列偏移。设定两只飞机以及导弹的起始行以及起始列。分数的数值用ASCII码显示,用二进制码来运算。设定游戏的开始界面。利用10号中断,从键盘接收字符,显示刚开始导弹及两个飞机的初始行列坐标以及外观。使用21H号中断的显示输出功能,设置分数的行列坐标,并显示分数。
    设置检测按键,此处需要自己来定义导弹的按键功能,这个游戏是将左右键设定为导弹的移动以及将空格键定义为发射子弹,通过擦除图像以及在新的位置显示图像来达到两个飞机以及导弹移动的效果。导弹发射子弹,判断是否射中飞机,若是射中飞机,则得分。显示导弹时,要先保存CPU现场,同时显示行列,设置缓冲区,设置光标,显示CPU现场,一个进程结束后跳转到下一进程,然后恢复缓冲区和CPU现场。擦除时,与画图相差无几的思想,只是将字符属性设置为黑底黑字,以实现擦除效果,
    发射子弹时,要通过保存CPU现场,以及循环、清除原来痕迹、重新设置行列坐标。子弹射出会有延迟,要保存CPU现场,设置行长度、子弹飞行距离、两个子弹的距离差,当第一个子弹飞行结束才可发射第二颗子弹,要记录子弹的发射,最后要返回函数的调用处,此时代表子弹的飞行延迟结束。同时飞机的飞行也要有延迟,以保证第一支飞机出现后第二只飞机才可以出,同样,要设置行长度,飞机飞行长度,结束时要返回调用处。
    令飞机移动时,要先保存CPU现场,通过擦除原来的飞机以及在新位置画图来实行飞机的移动。飞机移动时,要设置飞机的行列坐标以及飞机指针的缓冲区,同样通过将字符属性设置为黑底黑字来是的飞机的擦出效果实现,记录开始飞机的位置,然后飞机的所有光标均向后移动一位,此时在画出飞机,循环整个过程,记录飞机的位置,可以得出飞机整个的移动过程。
    无论飞机的移动以及导弹的移动甚至是导弹子弹的发射都用到了擦除,那么擦除的具体是如何实现的,以飞机为例来说明:先要记录飞机此时的位置,然后显示飞机的缓冲区,记录飞机的行列,移动飞机光标,调用擦除功能(即将字符属性设置为黑底黑字),之后占用缓冲区,记录移动位置,循环,缓冲区向后移动四格,循环擦除直至擦除结束,最后返回调用处。
    此游戏中一个重要组成部分就是判断子弹是否击中飞机,集中得分。这个部分首先要记录此时位置,显示列的位置,子弹的列值在飞机的列值范围内时,集中得分。然后要计算现在得分,返回分数。得到分数,跳转程序,计数器归零,存储分数,将分数的二进制码转化为ASCII码,显示分数,弹出分数到屏幕上(此处用到了栈,此处即为出栈)。此处有个需要注意的点,即二进制码转化为ASCII码,需要先找出二进制数,进行码的转换循环,若转换成功,则跳至下一步,循环此过程,结束时返回调用处。
    游戏的欢迎界面转换为游戏的游戏界面时,需要进行清屏操作,开始时要先保存CPU现场,然后使用向上滚屏功能,设置滚动行数为零,清窗口,设置左上角和右下角行列号,然后恢复CPU现场,结束清屏。
    三、核心算法流程图游戏开始时先进入显示开始菜单界面,当按下Enter键时进入游戏界面,可以开始游戏,当按Esc时,游戏结束,如图4所示。

    此游戏中,一个重要部分即为子弹击中飞机时分数增加,并且分数显示在屏幕上,此流程图显示了分数计算及显示的算法。

    四、开发中遇到的问题4.1 如何让导弹及飞机动起来解决:因为两只飞机外观相同,其移动轨迹也可以看做大致相同,所以两只飞机的移动可以大体看为一个问题,而导弹的移动由于受到键盘的按键控制,所以其可以看为另一个问题,因此这个问题就可以拆分成了两个小问题,即飞机的移动和导弹的移动。
    飞机的移动:首先先要显示出飞机的图形,先要设置出飞机的初始行列坐标,然后通过ASCII码值给定飞机的外观,通过擦除和画图来实现飞机的移动,擦除和画图的思想一样,都是通过设置新的字符属性来完成,只不过擦除是通过设置成黑底黑字的字符属性来实现的,其在新的位置显示图像来达到移动的效果,擦除后设置新的行列,然后循环 ,再次设置新的行列,往复循环,最终达到飞机的移动效果。
    导弹的移动:导弹的显示与两只飞机一样,同样是通过ASCII码来进行显示,此处就不再做过多的叙述。而导弹的移动需要受到键盘的按键控制,首先需要先检测是否有按键按下,如果有的话要检测按下什么键,并进行判断,此处设定通过左右方向键来控制导弹的移动,没有的话要循环检测,导弹移动时还要注意其会有边界的问题,要循环检测其是不是到达了边界,抵达了边界则不可再移动。导弹的移动显现也是通过擦除图像和再次画图来实现的,此处和飞机的移动相差无几,也是通过改变行列坐标和设置新的字符属性来完成的,所以不再详细叙述。
    4.2 敌方飞机与我方子弹的碰撞时该怎么办?解决:此游戏的主要部分就是导弹发射子弹击中飞机,然后得分,当导弹的子弹击中飞机时,飞机被击中的那一部分消失,那么又如何实现这个想法呢?
    在这个项目中,我是给每一个对象都创建了一个精灵层和Layer层的。方便自己管理所有的对象。所有在检测碰撞的时候。需要进行类与类之间的传值。所有就用到了之前的点击事件。先在敌方飞机的精灵的层里面抛出一个自定义事件。在我方子弹层里面接收。抛出的对象是敌方飞机。所有在我方子弹层中就可以运用传过来的敌方飞机对象。获取敌方飞机的框体。在子弹层也可以获取子弹的框体。然后运用碰撞检测就可以实现碰撞的效果。
    4.3 当子弹飞出屏幕怎么办?解决:子弹击中飞机之后,子弹并不会消失,而会继续向上飞翔,直至飞出屏幕,这是要如何实现导弹子弹的清除呢?
    我们的想法是这样:创建schedule,每隔一秒钟在自己飞机的位置创建一个向上直线飞行的子弹,当子弹超出屏幕的时候给子弹进行清除。
    先创建一个子弹移动的行为。使得子弹向y轴向上运行一个屏幕的高度。最后再在行为的后面写一个算法。就是移除父类的方法。再在运行行为的地方添加一个顺序执行的apicc.sequence(),使的程序先执行移动效果。当移动到目的位置调用移除父类的方法,给子弹进行移除。
    4.4 如何计算并显示分数解决:当子弹击中飞机之后,分数会增加,那么如何计算并将分数显示到屏幕上呢?我的想法是用二进制码来用于分数的计算,用ASCII码来用于分数的表示,这样要将二进制码转换为ASCII码。
    首先要判断子弹是否击中飞机,若是击中,则得分,记录此时位置,显示列位置,如果子弹的列值在飞机的列值范围内,则表示击中,得分,计算现在得分,返回所得的分数,得到分数之后跳转程序,将分数保存,分数的二进制码转化为ASCII码,显示出具体分数,计数器归零,记录分数,显示分数,弹出分数到屏幕上(此处用了栈,此处即为出栈),结束后要返回调用处。
    五、心得体会纸上谈来终觉浅,绝知此事要躬行。从开始得知做项目时的茫然失措,到中途研究问题时的信心渐明,再到最后做出的成就满怀。一路走来,不仅仅是我和我的队友做出了什么,更重要的而是我的心智的成熟以及专业知识技能的提高。在我感觉甚是开心喜悦与有成就感的同时,我也有了更大的自信去再接再厉、刻苦奋发。总的来说,汇编语言是一门历史悠久且值得学习的学科。在学习的过程中,我们从基础的结构了解的学习,再到语言代码的研究,最后是对整个程序的观看或审视,我也收益良多。但是往往对于我来说,把所学的汇编语言的知识与此次游戏程序的开发,也就是说把所学与实践相结合其实是有难度的。这就需要集思广益、深度思考、刻苦钻研,只有这样才能圆满的完成对自己的历练,而此次经历也培养了我的这些精神或者说态度。邓小平同志也曾说:实践是检验真理的唯一标准。通过此次的锻炼,我对这句话更是深有体会。而在此次锻炼的同时,我的各方面能力也得到了提高,我更有兴趣与信心去完成未来更多的项目。
    在这次通过汇编语言编写陆地导弹打飞机游戏过程中,通过查阅资料,向老师、同学请教,我收获了知识,同时,还增长了阅历,变得更加成熟。在学习汇编语言的过程中,我深刻地意识到相较于曾经学过的C语言,电脑等于在迁就人的思维方式,但汇编却是接近机器语言的一门语言,我们学习和编写程序时必须要去迁就电脑的思维方式,有时候还要设身处地地用电脑的角度去思考问题。在编程序的过程中,我也深刻认识到知道运行过程是一回事,根据这个过程编写出这段程序又是另外一回事,要编写出这段程序首先要对汇编语言熟悉,对编译环境熟悉,在编写过程中,最苦恼的就是:知道每条指令什么意思是一回事,如何把这堆指令整合成自己得到的程序又是另外一回事。这个过程需要我们去慢慢调试自己程序,完善自己的逻辑思想。在编写过程中我加深了对8086汇编语言的理解,学习一门语言必须经常使用,否则不能很好的体会其中的奥义。在不断探索过程中我也知道了自身的不足。
    0 评论 1 下载 2019-06-19 16:55:20 下载需要6点积分
  • 基于80x86汇编的动态tree程序设计与开发

    一、软件背景介绍随着城市化进程的加快,园林建设所涉及到的内容也更加的综合化,这让城市规划与设计的方式更具备包容性,从过去单一化的形态设计相比,当前的园林建设更应注重的是环保性。因此,在园林建设过程中,应该注意以下几点:首先是在城市功能区的划分中,交通路线和设计建筑物的总量比例、尺度等因素,城市绿化建设的水平同环境保护相比应该更好,这样才能将两者直接的联系在一起。其次,也要从根本上提高大众的环保意识,相关部门要充分利用互联网+的优势,积极的宣传绿化和环保的意义,使得广大的市民可以支持环保事业。最后,积极的开展一些全民性质的绿化活动,鼓励市民都要参与进来,真正的去体验绿化和环保的意义在程序设计中,我加入了许多绿色的元素,对美好大自然的一种向往,树木,绿色的象征,它不但能净化空气,还能起到光合作用。分别编写一个子程序显示“I LOVE NATURE,LET US GO AIRING”和一个子程序在屏幕上“画”树。这两个子程序所体现出来的事物都是的。为了实现小鸟能在空中翩翩飞舞和小汽车在林荫路上行驶每天都能听见嗡嗡的电锯声和一棵棵大树的呻吟声或倒下时发出的怒吼。原本郁郁葱葱的树木,而如今却只剩下了棕色的树干。树木在频频减少,昔日茂密的树林已剩寥寥无几了,这也使得沙漠面积在不断扩大,使得动物少了栖息的地方,使得大自然缺少了生气,最严重的则是山洪来临时,人们在也不能依靠树来抵挡了,会使得自然灾害更加猖狂,无情地来伤害人们。

    遗憾的是,许多人对于这个浅显易懂的道理却视而不见,继续为所欲为,妄顾地球家园的安危。环境科学家曲格平曾经说过这样一句话:“唯有变革,才能拯救人类的命运,也唯有变革,才能使我们的子孙后代世世代代生存下去。”里面的“变革”就是指环保。说得很对,所以如今有许多人拿着标语在街上喊空口号,却没有见过多的行动。难道这样污染就会好转吗?不!
    看,我们城市里的河流的河水发黑发臭;排成长龙的汽车放出大量的废气;成片的绿地变成“石屎森林”;那清脆的鸟叫声消失得无影无踪。如果再这样下去,中国将继续贫乏水资源,空气将变得愈来愈浑浊,本世纪将有10%的鸟类物种消失。
    人人皆知:树木能吸收二氧化碳,排放氧气,净化空气,是我们人类生存的必要的条件。但是有一些人为了金钱去乱砍滥伐树木,造成了过度的水土流失,使大地的植被受到严重的破坏,绿洲和城市也荒漠化,我们人类的生存受到了威胁。就我们平时用的一次性筷子,每天都要耗费数十亩的森林,在那些人眼中,树木除了可以做家具和建筑材料外,似乎没有任何价值。难道还有人不懂树木对我们意味着什么吗 我们居住面积已经很小了,如果再这样下去,可能连我们唯一的土地都失去。还有,我们的母亲河——黄河近年来河床和含沙量不断增高,成为全国污染最严重的几条江河之一。我们不能眼睁睁地看着黄河从我们手中枯竭,因而有许多环境学者纷纷研究治理黄河污染的方案,试图改善黄河的水质。但如果没有我们的共同参与,我们这个生命的摇篮——黄河将会走向衰竭和死亡。
    在界面第二页加入了多种元素,小鸟于大树的结合,让大自然的气息更加浓厚,带给人们对于环境的保护。

    二、核心算法思想“我爱大自然”这个程序中包含了比较多的景物,既有静态的也有动态的,其中还有一段音乐。为了节省存储空间,提高程序设计的效率和质量,使程序简洁、清晰,便于阅读,同时也为了便于修改和扩充,采用子程序设计技术和宏定义,根据程序要实现的若干主要功能及个功能块要调用的公共部分,将程序划分为若干个相对独立的模块,为每个模块编制独立的程序段,最后将这些子程序根据调用关系连成一个整体。
    这样,整个程序就被分为几个子程序的有机统一。根据BIOS中断调用原理。在存储器系统中,内存器高端8KB的ROM中存放有基本输入/输出系统BIOS例行程序。BIOs提供了最KMS15-15低最直接的硬件控制,是硬件与软件之间的接口。BIOS主要包括以下一些功能。

    系统自检及初始化:例如,系统加电启动时对硬件进行检测;对外部设备进行初始化;设置中断向量;引导操作系统等
    系统服务:为操作系统和应用程序提供系统服务,这些服务主要与V0设备有关,如读取键盘输入等。为了完成这些操作,BIOs必须直接与y0设备打交道,并通过接口与VO设备之间传送数据,使应用程序脱离具体的硬件操作
    硬件中断处理,提供硬件中断服务程序

    使用BIOs功能调用,给程序员编程带来了极大方便。程序员不必了解硬件的具体细节,通过中断来调用BIOs中例程,完成各种功能操作,所以利用BIOs功能调用编写的程序简洁,可读性好,而且易于移植。与DOS功能调用相同,用户可以直接用指令设置参数,然后中断调用BIOS中的程序,给用户编程带来极大的方便。
    对于BIOS中断调用原理举例系统启动过程主要由一下几步组成(以硬盘启动为例):

    开机
    BIOS 加电自检(Power On Self Test—POST)内存地址为0ffff:0000
    将硬盘第一个扇区(0头0道1扇区,也就是Boot Sector)读入内存地址0000:7c00处
    检查(WORD)0000:7dfe是否等于0xaa55,若不等于则转去尝试其他启动介质,如果没有其他启动介质则显示”No ROM BASIC”然后死机
    跳转到0000:7c00处执行MBR中的程序
    MBR首先将自己复制到0000:0600处,然后继续执行
    在主分区表中搜索标志为活动的分区.如果发现没有活动分区或有不止一个活动分区,则转停止
    将活动分区的第一个扇区读入内存地址0000:7c00处
    检查(WORD)0000:7dfe 是否等于0xaa55,若不等于则显示”Missing Operating System”然后停止,或尝试 软盘启动
    跳转到0000:7c00处继续执行特定系统的启动程序
    启动系统

    在此软件中,设置80×25彩色文本显示方式,分别编写一个子程序显示“I LOVE NATURE,LET US GO AIRING”和一个子程序在屏幕上“画”树。这两个子程序所体现出来的事物都是的。为了实现小鸟能在空中翩翩飞舞和小汽车在林荫路上行驶,还要调用擦除子程序和延时子程序。擦除子程序的原理是根据相对位移设置光标位置,讲原来字符属性设置为黑底黑字,以达到擦除效果。延时子程序的原理也很简单,即设置循环次数,让CPU做一些“无用功”,这样读者就能看到小鸟“飞起来”和小汽车“跑起来”。可以改变循环次数来控制延时,达到想要的效果。动态的事物就这样产生了。
    三、核心算法流程图程序运行过程中的总流程图,在流程图中给出显示步骤 ,能够清晰的反应处程序的显示部分。

    在下面子流程图中主要用循环在绘制显示各个部分的花子图形,让整个界面显示更加养眼,自然效果强烈。

    在此流程图中多次用到调用判断,对小鸟的位置必须随时记录,为显示小鸟动态效果,让光标随逻辑位置发生变化,以达到效果。

    四、开发中遇到的问题4.1 景物显示色彩设置问题在显示窗口会出现一些比较细节东西,显示位置不对称,对于显示效果大打折扣,最后运行过程中还有一些等待时间长的特性。在本程序设计初期对于颜色的使用方法不是很熟练地使用,多次出现显示问题。图文说明:在初步设计中最先设计五种颜色结合,由于各种原因,主题定义偏离,定义以主色调绿色为主。
    4.2 音乐部分的插入问题程序中出现的音乐部分处理的不是很完善,音乐插入频率有些杂乱。
    对于发音部分。PC机上的大多数输入/输出(I/O)都是由主板上的8255(或8255A)可编程序外围接口芯片(PPI)管理的。PPI包括3个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口号为60H和62H,输出寄存器分配的I/O端口号为61H。由PPI输出寄存器中的0、1两位来选择扬声器的驱动方式。连接到扬声器上的是定时器2,从上图可以看到,GATE2与端口61H的PB0相连,当PB0=1时,GATE2获得高电平,使定时器2可以在模式3(方波)下工作。定时器2的OUT2与端口61H的PB1通过一个与门与扬声器的驱动电路相连。当PB1=1时,允许OUT2的输出信号到达扬声器电路。因此,只有PB0和PB1同时为“1”时,才能驱动扬声器地声。自身硬件方面出现问题,由于电脑音响设备出现问题,对于音乐调整无法正常的发出预期效果的声音。
    4.3 程序原理的理解问题对于最重要的原理分析还是多多少少出现不少问题,分清楚DOS系统功能调用与BIOS中断调用的关系,在查阅了资料后具体了解问题:
    BIOS是系统提供的基本输入输出例行程序,它包括系统加电自检,引导装入,主要I/O设备的处理程序以及接口控制等功能模块。BIOS有两个基本用途:一是给不同系列的微处理器提供兼容的I/O服务,使程序员在编程时不必考虑不同型号机器的具体差别。二是给程序员提供文件化的,直接对硬件进行操作的子功能,程序员可不必了解硬件操作的具体细节。所以利用BIOS功能编写程序简单方便,可读性好。
    DOS是PC机上最重要的操作系统,它和BIOS一样包括有近百个设备管理、目录管理和文件管理程序,是一个功能齐全、使用方便的中断例行程序的集合。使用DOS操作比使用相应功能的BIOS操作更简易,而且对硬件的依赖性更少些。可以简单理解成利用DBMS对数据库进行操作。
    BIOS功能与DOS功能都是通过软件中断调用的。在中断调用前需要把功能号装入AH寄存器,把子功能号装入AL寄存器,除此而外,通常还需在CPU寄存器中提供专门的调用参数。一般地说,调用DOS或BIOS功能时,有以下几个基本步骤:

    把调用参数装入指定的寄存器中
    如需功能号,把它装入AH
    如需子功能号,把它装入AL
    按中断号调用DOS或BIOS中断
    检查返回参数是否正确。

    4.4 程序小错误处理问题编程过程中细节方面把握不是很到位,导致最后运行阶段不是非常顺利。对于基本知识掌握不太全面,运用起来不是很流畅。有些操作还是比较繁琐,没有用最简便的方法解决导致工作量大,实现困难。界面显示中起初出现各种小错误。经过后期查阅资料,对程序各个模块的研究发现所在的错误并改正。对于细节问题得到明显的解决,已达到预期使程序产生动态效果。
    4.5 动态效果实现的问题在程序中主要是通过界面带给用户的体验,而实现界面要产生的动态效果就需要运用到最初的程序中擦除子程序与光标实时运动(延时子程序)配合必须精密。否则会出现混乱,让效果大打折扣。
    首先让光标在界面显示画出景物的模型,将界面前后背景设置为黑色,通过擦出子程序在后续擦出。将光标向后移动。每移动一次,进行一次判断,是否进行擦除,若擦除成功光标后移。最后达到动态效果。
    五、心得体会在这次对于汇编语言的学习中,感觉到了前所未有的对于以往编程人员的敬佩,现在的编程技术虽说比较成熟,但是没有前人的辛勤劳作打下的基础就不会有现在成熟的状况。《汇编语言课程设计》是网络专业集中实践性环节之一,是学习完《汇编语言》课程后进行的一次全面的综合练习。通过这次汇编语言课程设计让我初步掌握问题分析、系统设计、程序编码、测试等基本方法和技能,提高综合运用所学的理论知识和方法的能力, 初步具备的独立分析和解决问题的能力。学完汇编这门课我也对之前的高级语言中的一些知识有了更新的认识,能够让我们更好的理解高级语言,尤其是高级语言中的C语言,汇编语言对于内存的操作都是基于内存地址的,而C语言中最令人头疼的指针概念,说白了就是内存的地址指针的学习和应用中最头疼的就是在指针这个抽象的概念和实际的内存单元之间建立思维映射,而这些恰恰是我们在汇编语言学习中频繁做的一件平常事另外,对于C语言中的数据类型形参实参函数调用全局变量局部变量等概念及操作,我们都可以用汇编语言中的一些操作相关联,把这些抽象的概念和过程,通过汇编语言形成一个具体的映像,深度剖析,。
    0 评论 0 下载 2019-06-19 16:52:30 下载需要6点积分
显示 75 到 90 ,共 15 条
eject