分类

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

资源列表

  • 基于JAVA的迷宫游戏设计与实现

    一、问题描述1.1 课程设计题目程序开始运行时显示一个迷宫地图,迷宫中央有一只老鼠,迷宫的右下方有一个粮仓。游戏的任务是使用键盘上的方向键操纵老鼠在规定的时间内走到粮仓处。
    1.2 课程设计要求
    老鼠形象可辨认,可用键盘操纵老鼠上下左右移动
    迷宫的墙足够结实,老鼠不能穿墙而过
    正确检测结果,若老鼠在规定时间内走到粮仓处,提示成功,否则提示失败
    添加编辑迷宫功能,可修改当前迷宫,修改内容:墙变路、路变墙
    找出走出迷宫的所有路径,以及最短路径
    利用序列化功能实现迷宫地图文件的存盘和读出等功能

    二、需求分析迷宫游戏,作为一种经典的游戏,与之相关的程序可谓琳琅满目,数不胜数。在这种情况下,自己设计的程序要想有点看头,单靠黑洞洞的控制台是绝对不行的,至少要有像样一点的图形界面和简单方便的操作。
    上学期刚学过C++之后,我通过自学MFC,完成了拥有图形界面的课程设计。这学期学数据结构的同时,也学习了另外一门重要的高级语言——java,所以,也想牛刀小试,玩一下java的图形界面设计。
    为了达到题目中的要求,用java实现的话,显然需要用到它的图形界面、事件驱动、多线程等知识。前两部分内容,教材上讲的已基本上能帮我完成相关设计了,多线程的知识,教材上没有,但查阅相关资料(包括图书馆的纸质书籍和网上的各种论坛信息),也很容易找到设置时间限制的方法。
    Java工具的问题解决了,毕竟大神们把这些工具设计的很方便和漂亮,使用起来当然不会太难,所以,剩下的才是核心部分——真正实现程序设计要求的重要算法。
    用户只能自己设计迷宫玩是不太方便的,当然也不能没有这个功能,但我想在保留此功能的同时,添加一个生成随机迷宫的功能。当然这种随机不能是简单的调用java提供的random方法,这样所得到的迷宫很难保证有通路。要想设计出随机的,而且至少有一条通路的迷宫,自然要用到特殊的、巧妙的算法。另外,要求出最短路径,也是需要好的算法设计的,算法时间复杂度太高的话,用户也会等的不耐烦的。
    三、概要设计3.1 程序界面设计程序主要有两个界面,均继承自javax.swing.Jframe,它们分别是开始界面StartUI和游戏界面map。
    StartUI界面提供4个操作按钮,让用户选择游戏的场地大小,其中有一个按钮允许用户自定义场地大小。其实,这种设计完全是在模仿linux系统gnome集成桌面环境中所提供的扫雷游戏。
    map界面主要是迷宫地图和操作菜单栏,在此选择了使用动态的gif图片显示老鼠。另外,除了实现利用方向键控制老鼠外,也顺便为菜单选项设计了快捷键(反正用的是相同的事件驱动处理程序,多加几个按键响应而已)。
    3.2 总体功能框架程序总体功能大致可分为游戏模块、编辑模块、文件操作模块以及提示路径模块,另外在菜单栏中提供一些帮助信息,姑且把它看作是帮助模块吧。
    结合程序界面,程序总体功能框架如下图所示:

    程序最核心,最重要的算法主要用在游戏模块和路径提示模块中,其它模块只不过是一些简单的操作而已。
    四、详细设计4.1 数据结构设计程序源码由四个源文件组成,每个源文件有一个属性为public的类,它们分别是StartUI、map 、Operations、wrmPane。其中,StartUI和map是程序界面类,wrmPane是用于显示老鼠、路、墙、粮仓等元素的面板,Operations类中几乎提供了对迷宫进行操作的所有方法。此外,在某些类的定义里又有匿名内部类的存在,不再细述。
    虽然本程序的核心算法用到了栈和图论的思想,但我并没有定义相应的数据结构。其原因在于:对于栈来说,本来就可以通过对数组的简单操作很方便的实现压栈、出栈等功能;对于图来说,由于迷宫可以看作是一个相对来说很有特点的图,它点与点之间的关系不像一般的图那样随意,一个点只可能与它周围四个方向有确定关系的点之间具有直接联系。因此,迷宫本身自带的信息就已经构成了一种抽象一点的邻接链表或邻接矩阵(我本人感觉它更像是个邻接链表),所以也没必要再去实际构造这些数据类型来存储迷宫信息。
    为了降低求取迷宫最短路径算法的时间和空间复杂度,也就是说尽可能地优化算法,程序设计中引入了路径深度和路径深度图的概念,从而很巧妙地设计出了相对于传统的迷宫最短路径算法更易理解且效率更高的算法(当然,这种绝妙的算法思想绝不是我的小脑袋瓜所能构想出来的,这是我从一篇论文上看到的)。明白了它的思想之后,算法是很容易写出来的。这种算法虽然离不开图的思想,但还是能通过对数组的简单操作来实现。
    顺便说一下,迷宫地图的每一块最小单元,其实就是二维平面上的一个点,所以,它本来是应该以二维的坐标来标识的,不过,我设计代码总喜欢尽可能地把维数降到最低,最后在算法设计中还是把它们转化为与之一一对应的点了。其实,这次的降维对提高算法效率而言,并没有什么实质性的效果,只是能让我写代码的时候看着更舒服而已(可能我确实有点强迫症吧)。
    4.2 具体模块设计下面介绍一下各功能模块的设计。由于各功能模块的实现难易程度不同,那些简单的模块就不再详细说明了。
    4.2.1 游戏模块该模块用到了一个重要的算法,同时需要对设计关于时间控制的线程以及按键事件驱动的处理。其中使用到的最主要的方法,原型如下:
    public static void DFS(int s); public static void creatMaze();
    creatMaze方法通过调用DFS方法实现至少有一条通道的随机迷宫的生成。至于控制时间的线程,不过是继承Runnable接口后重写一下run方法进行倒计时,按键事件处理不过是根据按键不同调用相应方法,限于篇幅,它们的具体实现不再赘述。下面主要讲述一下生成随机迷宫的算法思想,并以流程图的方式大致描述一下它的代码实现。
    该算法利用了图的深度优先遍历,算法的最初设计仅适用于行数和列数均为奇数的随机迷宫生成,我做了一点修改以使它能避开行数和列数的限制,同时将老鼠的位置设为随机。算法思想不难理解,我将修改后的算法思想大致描述如下:
    首先,将所有的点初始化为墙,然后随机生成老鼠的位置,再将相应点修改成老鼠,粮仓的位置修改好;然后,从老鼠位置出发,利用深度优先遍历算法,通过随机遍历方向,将所有与老鼠位置X、Y坐标差值均为偶数的点遍历出来,并修改成路,最终连接成一条能联通所有这些点的通道。在此过程中,当我们需要由一个点连接到下一个点时,仅需要打通隔开它们的那堵墙(将它修改成路)即可。
    遍历结束后,仅能保证老鼠可以到达迷宫上与之位置坐标差值均为偶数的任意点,而对于行数和列数均为奇数,且入口和出口分别位于左上角和右下角的迷宫来说,其入口和出口恰好符合这种关系,但条件不全就不能确保迷宫有通路了,这正是原算法的缺陷所在。弥补这个缺陷的方法很简单,我借助下/图说明一下:

    假设粮仓在图2中的位置3上,很显然,田字格中必然有一个点与老鼠位置满足上述关系,也就是说,老鼠能到达该点。我们可以看到,若老鼠能到达2或4点的话,它也就能到达3了,所以唯一的问题就是位置1,我们不难发现,联通位置1和3也很简单,只需打通2或4就行了。于是,每次遍历后随机将位置2或4修改为路,就能保证迷宫在任何情况下都有通路了。
    其实,还有一个不太重要的小问题,对于不满足行列数均为奇数的迷宫,这种算法产生的随机迷宫会在某一个或两个全为墙的边,这样的迷宫看起来是有点不“协调”的,所以,我稍微修改了一下遍历前的初始化工作,让这些边上的点随机初始化为墙或路。
    通过以上步骤,就使得生成的迷宫满足随机性的同时,也至少拥有一条通道。
    下面是算法大致流程图。
    creatMaze方法流程图

    DFS方法流程图

    4.2.2 文件操作模块该模块利用文件选择器java.awt. JFileChooser.。以二进制文档方式保存或导入迷宫结构。内容比较简单,故不再详述。
    4.2.3 编辑模块编辑模块利用ActionListener接口,通过对鼠标点击事件的处理,提供了墙路互变的功能,其中对生成的随机迷宫的编辑同样调用了creatMaze方法。
    4.2.4 路径提示模块该模块在程序非常重要,包括有程序两个核心算法,而且还引入了关于图论的新概念。模块中用到的两个方法,原型如下:
    public static void sortestPath();public static void findPath();
    在讲述sortestPath方法之前先引入以下两个概念:
    路径深度——从某位置走到出口的最短路径的长度,设每一方块为单位路径长度。假定出口处路径深度为0 , 障碍处路径深度为 - 1 。
    路径深度图——与迷宫对应的图, 每一个节点值为与该节点对应的迷宫单元格的路径深度。
    基于上述概念,不难证明,迷宫最短路径必然是一条从入口处开始、到出口处结束的路径深度逐次递减1的序列。因此,如果能求出整个迷宫每个单元格的路径深度,那么求解迷宫最短路径就简单了。于是,问题的重点就在于如何求解路径深度图。
    稍作思考,我们不难理解,对于迷宫上任意一个非障碍物的点,它的路径深度值必然不大于其周围四个方向上的非障碍物点中最小路径深度值+1。sortestPath方法就是在这个结论的基础下设计的算法。算法每一个循环动态地更新所有点的路径深度直至整张图达到稳态。再通过得到的路径深度图求得最短路径。该方法的流程图如下:

    findPath方法使用传统的回溯法查找迷宫中的一条接近最短路径的通道,我感觉它有点贪心法的影子,因为总是先挑眼前看来是最容易接近出口的方向,但其实质还是深度优先搜索,只是在搜索过程中设置了四个方向的优先级。
    回溯法算法思想很简单:从当前点出发时,访问的下一个点要选择未访问过的可行方向中优先级最高的。若当前点周围所有方向上的点都不能访问,便往后退一步,继续以相同方式探路。如此循环往复,直至找到迷宫出口或完全无路可走。显然这里需要用到栈存储路径,并通过压栈和出栈操作实现探路过程中的前进和后退。
    由于回溯法是一个经典算法,有关它的资料很多,在这里就不再画它的流程图了,但这并不代表我认为它不重要,它仍然是本程序设计中的三大核心算法之一。
    4.2.5 帮助模块该模块利用消息框显示游戏使用说明和作者信息,没什么可细述的。
    五、调试运行分析5.1 经典迷宫最短路径算法与本程序新算法在时间和空间效率上的对比本程序求解最短路径的算法借助了路径深度图的思想,算法完成的工作可以分为两部分,即求解路径深度图和通过路径深度图求解最短路径。
    显然算法的主要时间开销在第一部分上,这一部分主要过程是逐步判断每个单元格是否与周围四个单元格达到稳定平衡状态,设迷宫规模为 M*N,则时间复杂度为O(4*M*N),空间方面仅需一个长度为 M*N 的数组来存储各单元格的路径深度。
    第二部分中当最短路径长度为K时,时间方面最多需要4*K次,空间方面存储路径只需长度为K队列。而K=O(M+N),故这一部分时间空间复杂度均为O(M+N)。
    综上所述,本算法的时间和空间复杂度均为O(M*N)。
    而经典迷宫最短路径算法中广度优先搜索,空间复杂度方面除了要存储迷宫单元格访问信息外,还需使用堆栈来保存大量搜索记录。时间复杂度方面和具体迷宫布局有关, 主要时间开销在探索上, 由于算法采用了递归反复探索, 通常情况下访问一个单元格后要依次访问 4 个后继方向上的单元格, 第一次找到迷宫出口的路径即为最短路径。假设最短路径长度要 N+M, 当不设置迷宫单元格访问矩阵时, 则几乎要探索 O(4^(N+M) ) 次, 时间复杂度远大于本算法。
    深度优先算法, 空间复杂度与深度优先搜索相差不大, 但时间复杂度方面, 算法要实现找出最短路径, 必须遍历出所有到达出口的路径, 比较各条路径的总长度, 从而得出最短路径,因此时间复杂度大于广度优先搜索, 自然而然远大于本算法。
    由此,可得出结论,本程序使用的新算法明显优于传统算法。
    5.2 程序运行效果演示在Windows控制台或linux终端输入指令java StartUI,即进入程序开始界面:

    可选择程序提供的迷宫场地大小,也可以自定义迷宫行数和列数:

    当输入数据有误或点击取消时,会有错误提示:

    以后程序使用过程中,用户的误操作都会有相应提示,不再提供相关截图。
    选择好正确的迷宫场地大小后,即可进入游戏界面:

    刚开始,游戏是没有时间限制的,当在游戏菜单中选择设置时间限制选项时,弹出输入对话框:

    真确设置好时间后,弹出如下消息:

    选择之后,发现上方开始倒计时:

    现在可以开始玩游戏,通过方向键控制老鼠的移动
    当剩余时间不多时,倒计时颜色改变:

    在时间限制内是否完成任务,都会有相应提示:

    在提示菜单中有显示最短路径和随意显示一个路径的子菜单,点击后会有相应路径的显示:

    文件菜单的子菜单中可选择保存迷宫结构或导入迷宫结构:


    编辑模式中,可点击某块区域使墙路互变,不再截屏。
    3 评论 74 下载 2018-10-31 10:54:10 下载需要2点积分
  • linux下实现的ping程序

    一、设计目的PING程序是我们使用的比较多的用于测试网络连通性的程序。PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。由计算机网络课程知道,ICMP是基于IP的一个协议,ICMP包通过IP的封装之后传递。
    课程设计中选取PING程序的设计,其目的是通过PING程序的设计,能初步掌握TCP/IP网络协议的基本实现方法,对网络的实现机制有进一步的认识。
    熟悉SOCKET的编程,包括基本的系统调用如SOCKET、BIND等。
    二、设计内容2.1 RAW模式的SOCKET编程PING程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。为了实现直接对IP和ICMP包进行操作,实验中使用RAW模式的SOCKET编程。
    2.2 具体内容2.2.1 定义数据结构定义IP数据报、ICMP包等相关的数据结构。
    ICMP数据头结构
    typedef struct Icmp{ unsigned char type; //类型 unsigned char code; //代码 unsigned short check_sum; //检验和 unsigned short id; //标识符 unsigned short seq; //序列号}IcmpHeader;
    IP数据包头结构
    typedef struct iphdr { unsigned int headLen:4; //首部长度 unsigned int version:4; //版本 unsigned char tos; //区分服务 unsigned short totalLen; //总长度 unsigned short ident; //标识 unsigned short fragAndFlags; //标志与片偏移 unsigned char ttl; //生存时间 unsigned char proto; //协议 unsigned short checkSum; //检验和 unsigned int sourceIP; //源地址 unsigned int destIP; //目的地址}IpHeader;
    2.2.2 程序实现在LINUX环境下实现PING程序
    2.2.3 程序功能
    ping ip 地址如ping 192.168.1.1
    ping 域名(进行DNS解析)如ping www.baidu.com
    参数“ -n 数字”进行设置ping 的次数如ping www.baidu.com –n 10
    参数 -t 无限循环如ping 192.168.1.140 -t
    分析ping到的数据报如最短时间,最长时间,平均时间和丢包率
    ping ? 提供帮助提示

    三、实验平台与语言
    平台:linux
    语言:C语言

    四、功能模块实现4.1 总体设计方案流程图

    主要代码
    // ICMP数据头结构 typedef struct Icmp{ unsigned char type; //类型 unsigned char code; //代码 unsigned short check_sum; //检验和 unsigned short id; //标识符 unsigned short seq; //序列号}IcmpHeader;//执行ping功能int ping(const char *ip, int send_count){ int rawfd; struct sockaddr_in dest_adr; char icmp_data[1024]; int size = sizeof(IcmpHeader)+32; int r, i = 0, send, recv=0, lost=0; char recv_buf[1024]; int all_time[1024] = {0}; //创建原始套接字 rawfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if(rawfd == -1) { perror("create socket failed!"); return -1; } //设置目的地址与端口 dest_adr.sin_family = AF_INET; dest_adr.sin_port = htons(80); inet_aton(ip, &dest_adr.sin_addr); //封装icmp数据包 pack_icmp(icmp_data, size); printf("\n正 Ping %s 具有%d个字节的数据:\n", ip, size-sizeof(IcmpHeader)); if(send_count == LOOP) { //无限循环 while(1) { if(ping_one(rawfd,dest_adr, ip, icmp_data , all_time) != -1) { recv++; } send++; } } else { for(i = 0; i<send_count; i++) { if(ping_one(rawfd,dest_adr, ip, icmp_data , all_time) != -1) { recv++; } send++; } } printf("\n%s 的 Ping 统计信息:\n 数据包:已发送 = %d,已接收 = %d, 丢失 = %d<%.1f%% 丢失>, \n",ip, send, recv, lost, ((float)lost/(float)send)*100); printf("往返行程的估计时间:\n 最短=%dms 最长=%dms 平均 = %dms \n\n" ,min(all_time, send), max(all_time, send), average(all_time, send)); close(rawfd); return 0;}
    4.2 DNS域名解析功能实现4.2.1 DNS 服务器
    地址:202.96.134.133
    端口:53

    #define DNS_PORT 53#define DNS_IP "202.96.134.133"#define DNS_IP2 "8.8.8.8"
    4.2.2 DNS 的实现基础:通过UDP发送查询报文给DNS 服务器,然后从服务通过UDP 返回的回应报文中解析得到对应域名的IP。
    4.2.3 DNS 报文格式
    4.2.4 首部格式
    其中标志字段:16位

    定义首部结构体
    typedef struct DNSheader{ unsigned short id; unsigned char qr_opcode_aa_tc_rd; unsigned char ra_zero_rcode; unsigned short qdcount; unsigned short ancount; unsigned short nscount; unsigned short arcount;}DnsHeader;
    4.2.5 问题记录格式

    查询名字:域名的可变长字段;其中计数字段指明每一节中的字符数
    查询类型:16位;值的意义如下表,查询ip 时为1
    查询类别:16位;定义使用DNS的特定协议, 一般为1

    查询名字打包代码:
    //把域名打包成dns数据报的数据部分 如(3www5baidu3com)//计算每段的数量for(i = 0; i < name_len; i++){ if(netname[i] == '.') { len[flg++] = i - s; s += len[flg-1]+1; }}len[flg] = i - s;i = 0;flg = 0;data[i++] = len[flg++];//加入每段字节的数量for(; i < name_len+1; i++){ if(netname[i-1] == '.') { data[i] = len[flg++]; } else { data[i] = netname[i-1]; }}
    4.2.6 资源记录格式
    资源数据:可变长;值内容取决于类型字段的值,可以是数值、域名、偏移指针、字符串。
    4.2.7 在资源数据中提取ip和原域名失败的解决方法
    由于没有查到详细的解析资料,因此通过对整个报文每个字节进行分析,发现其格式的规律:ip地址放在报文的末尾,可以通过指针快速定位。
    采样分析的域名有(www.baidu.com 和 www.sina.com),下图是对 www.baidu.com 的分析。

    代码如下:
    //直接定位ip地址Ipadr *ip =(Ipadr *) (sen_buf+(r-8-4-8-2));//如果ip地址长度不为4, 则返回if(ip->len != 0x0400){ return -1;}//次ip地址转为字符串sprintf(get_ip, "%u.%u.%u.%u", ip->a, ip->b, ip->c, ip->d);
    失败原因:过于投机取巧,取得两个分析对象不够特殊,对DNS回答格式完全不解
    新的解决方法
    通过用wireshark抓取DNS包进行分析,由于分析次数过多,此处以 www.baidu.com 为例。

    由抓取的dns包分析可得到回答部分的格式如下:
    answer1:name : 不定长,c0 0c指段偏移地址type: 16 位 0005 是别名answerclass: 16位, 0001ttl:32位data length: 16位cname: 别名,长度data lengthanswer 2name:c0 2b 指向别名type: 16位 0001 是ip answerclass : 16位 0001ttl: 32位data length:16位address: 4个字节answer 3与回应2相似 ip 不一样进一步分析
    可以发现回答部分有两个类型(只是本设计的情况,DNS有很多种类型),type 字段为5时为别名回应,为1 时为ip回应,因此通过type和上面得到的格式来进行ip和别名的获取。
    其中还发现,DNS为了减小数据报文的长度,回应部份重复的字段会省略,并通过偏移指针指向重复部分,由上面的分析可知是用c0(代替字段长度)来转义下一字节为偏移指针。
    获取代码设计
    int parse_dns_respone(unsigned char *recv_buf,unsigned char **answer_o, int data_len ,char *get_ip, const char *netname){ int asw_type; int i,j, k; static int fn = 0, fi = 0; int r; unsigned char cname[40]; unsigned char *answer = *answer_o; answer +=2;//查询域名 asw_type = ntohs(*((unsigned short*)answer)); answer +=2;//type answer +=2;//class answer +=4;//ttl if(asw_type == 5) //域名包 { bzero(cname, sizeof(cname)); //解析域名 parse_dns_name(recv_buf, &answer, cname); fn = 1; //标记已取得别名 } else if(asw_type == 1) //ip 回应包 { //解析IP parse_dns_ip(&answer ,get_ip); if(fn == 1) printf("\n---- %s(%s)",cname , get_ip); else printf("\n---- %s(%s)",netname , get_ip); fi = 1; //标记已取得IP } *answer_o = answer; if(fn != 0 && fi != 0) return 2; //已取得别名和域名。则结果 else if(fi != 0) return 1; return 0;}//解析IPvoid parse_dns_ip(unsigned char **answer_o ,char *get_ip){ unsigned char *answer = *answer_o; Ipadr *ip =(Ipadr *)answer; //取提ip sprintf(get_ip, "%u.%u.%u.%u", ip->a, ip->b, ip->c, ip->d); *answer_o = answer;}//解析域名void parse_dns_name(unsigned char *recv_buf, unsigned char **answer_o, unsigned char *cname){ int tmp_len; int d_length; int i, k; unsigned char *answer = *answer_o; d_length = ntohs(*((unsigned short*)answer));//总长度 answer +=2; //data length i=0; for(k=0; k<d_length; k++) { tmp_len = *answer++; //名字段长度 if(i != 0) cname[i++]='.'; if(tmp_len == 0xc0) //CO转义为复字段 { int tmp = *answer++; //获得偏移指针 k ++; i--; while(1) { tmp_len = recv_buf[tmp++];//跳转到偏移位置 if(tmp_len == 0) break; //偏移位置结果 cname[i++]='.'; //填充域名 get_seg_name(&recv_buf[tmp], cname+i, tmp_len); tmp += tmp_len; i += tmp_len; } continue; } if(tmp_len == 0) break; //填充域名 get_seg_name(answer, cname+i, tmp_len); k += tmp_len; i += tmp_len; //移动指针 answer += tmp_len; } cname[i] = '\0'; *answer_o = answer;}
    4.2.8 遇到的问题有多段连续的域名字段重复
    原来只考虑到有一个域名字段是重复的,但是有些是有多段连续的域名字段重复的,解决的方法是(直到len字节为0 才认为没有重复字段了)。
    while(1){ tmp_len = recv_buf[tmp++];//跳转到偏移位置 if(tmp_len == 0) break; //偏移位置结果 cname[i++]='.'; //填充域名 get_seg_name(&recv_buf[tmp], cname+i, tmp_len); tmp += tmp_len; i += tmp_len;}
    有多个域名回答
    原来只考虑到只有一个域名名回答,但有些(如 www.sina.com )是有多个域名的,因此解决方法是域名回答可以多次解析,只有取得IP地址才结束,而不是原来只解析两个回答就认为拿到了IP地址。
    4.2.9 本实现的不足
    没有完全掌握DNS 回应报文的格文
    服务器单一,没有备用服务器
    还存在未知域名不能解析的,未能确保能解析所有正确域名

    五、结果分析Ping ip 地址 如 ping 192.168.1.1

    Ping 域名 如:ping www.sougou.com





    Ping –n 如:ping 14.215.177.37 –n 2

    Ping –t 如: ping www.baidu.com -t

    Ping ?

    六、心得体会做的永远比想象中的难,修改了多次代码,刚开始想只要IP 地址,要愿意深入分析回应数据报,只是进过一些特例来定位ip 地址就好,想不到两个特例效果是一样的(www.baidu.com 和 www.sina.com ), ip 地址都是在末尾前几个字节,但是,由于DNS 的去掉重复的功能,造成只有是只有2个IP 地址的域名才能有效,多于或少于两个的都不行,因此又得花时间重新进行分析,然后才想到利用抓包软件来协助分析,又花了不少心血修正这个BUG,程序员真不好做,坐到腰酸背痛。
    但是,还情事还没那么顺利,拿多几个域名来试之后又发现了问题,具有多个别名的域名没办法正确解析,在原来的基础上又很难修改,因此决定把代码封装起来,封装多几个函数,然后在封装好的基础上解决多个别名的问题,但是在调试中又出现多个连绵的域名字段重复省略导致解析也来的域名完全的问题,又进行了一番修改。真不容易。
    总结

    DNS的格式还需要找相关资料来学习
    以后写代码如果不是用于学习的,则应该找完成的框架进行修改,这样可以省时间,且写出来的程序也会比较稳定
    写程序前最好先做出详细方案,避免一些BUG
    网络知识的学习还有很多要学,网络编程要学的知识更加多
    1 评论 2 下载 2019-06-25 11:26:26 下载需要11点积分
  • 基于JAVA和SQL SERVER数据库实现的酒店管理系统

    1 设计目标就数据库学习应用于生活,以简单数据库应用为例,本小组以制作“酒店管理系统”为目标。该管理系统已经能实现一些酒店住房管理的一些基本功能,适用于中小型宾馆使用及访问,旨在用计算机系统为操作人员提供更方便的操作,并保持很高的灵活性和易操作性,该软件具备以下特点:

    易学易用,操作简便,它是基于Java的应用程序,操作界面友好直观
    功能完善,本系统包括前台经营和后台管理,功能完善,能够实现酒店的数字化经营
    开放型好,采用标准的开发工具和技术,后台数据库采用微软SQL 2008中文版,可以提供开放的数据接口,可同其他软件交流数据
    较为完善的会员机制
    功能完善,分为 4 个主要模块,分别为:查询房间状态、加入会员、宾客入住、结账

    查询房间状态,该功能可以查询当前的房状态,查询已入住和未入住的信息,并且很好的保存了用户的隐私,实现了连接SQL Server 2008 R2数据库从所建的表中查询功能
    加入会员模块:该功能可以实现连接SQL Server 2008 R2数据库从所建的表中插入、修改功能。并且设计会员打折模块(未实现)
    来宾入住模块:该功能实现了和现实生活一样的模式,登记入住信息,连接SQL Server 2008 R2数据库从所建的表中更新功能,把来宾的个人信息插到用来存放数据看guess表中
    结账模块:该功能实现了从数据库中查询自己的入住信息,和点击结账之后的数据更新功能,结账之后更新数据库的guess表,把入住状态设为未入住等


    2 功能设计
    3 数据库设计关于数据库设计方面,我们做的不是很完善,比如设计的这个数据库,有很多的函数依赖都没有消除,主码外码等定义也不是特别完美。名为Hotel的数据库主要分为三个表,分别是:guess,vip,operater.

    其中,guess主要用来存储来访信息和用户住房登录信息的,它的构造如下图:

    数据库主要的实现查询更新插入等功能便是通过这张表。
    Vip表是用于存储用户加入会员的,而operaer则是用于登录的时候存储管理员的信息的。其中guess表是整个数据库乃至整个程序的核心部分,用的java语言只是用来进行流程控制。整个程序通过JDBC操作也主要是这个。虽然有很多不足的地方,但是我们相信,我们是可以慢慢完善的。
    4 系统实现4.1 模块一登录界面模块:通过使用Java swing组件编写的比较友好的登录界面,同时也包括了通过JDBC连接数据库查询管理员的信息,数据库中的管理员表,正确输入密码和用户名才能尽进行登录。

    4.2 模块二使用主界面,界面美观漂亮,可以通过底部的按钮实现相应的功能。

    4.3 模块三查询模块:这个模块可以查询到当前的入住信息,当前的房间状态,而且很好的保护了客户的隐私,是通过JDBC连接数据库的方式得到数据之后插入一张二维表来显示的。可以一目了然的查看当前的空房,并且在允许的情况下让用户自主选择要入住的房型和房间号.

    4.4 模块四会员模块:这个模块可以让使用者加入会员,实现优惠功能,虽然还未实现打折功能,但是相信,只要时间允许,这个打折功能是可以实现的。这个功能是通过数据库的插入操作实现的。是把所有的方法封装在一个数据访问层DAO中,它封装了所有程序中要通过JDBC操作数据库的方法,包括查询,更新,修改,删除。

    4.5 模块五来宾入住信心录入模块。该模块参照了现实生活中的宾馆入住实例,通过把宾客的信息录入到数据库的指定的表中,并且保存起来,之后还可以通过结账模块的查询功能来表现。也是通过JDBC连接数据库实用”UPDATE 表名 姓名 所选的房间等 ”,通过调用DAO(数据访问层)的更新方法来实现,既可以查询,又可以更新:

    4.6 模块六结账模块。该模块实现了查询和更新一体的操作,是通过注册按钮事件来执行数据访问层DAO里的数据查询和数据更新操作.并弹出对话框”您需要付款¥xxx”,并且在弹出的同时,通过JDBC调用DAO层的更新方法来实现重置房间状态。既是用户活动的结束,也是流程的结束。

    也可以更新:

    结账的时候更新数据,设置房间为空。
    5 分析与结论这一次的课程设计给了我们莫大的好处,让我们更熟悉了数据库和高级语言的关联性,又能做到学以致用。在这个课程设计之前,我们都很迷茫,不会学以致用,只是知道跟着老师的步伐学习。通过这次的课程设计,我们还学会了自主学习的方法,明白了怎么样才是正确的学习方法。而不是一味的乱撞,我们通过做这个项目,还参考了很多课外教科书,查找了很多的资料。通过对一个问题的实际分析,良好的综合的运用了所学的知识,既学到了知识,巩固了基础,让我们更深入的学会如何将课本上所学的知识运用到实际上。
    虽然我们做的这个小小的项目不是很完善,也不是很好,还有很多需要改进的地方,很多的bug需要去修复。在这之前,我们成天都是跟着课本上整天加加减减,没什么感觉。通过这个课程设计,有了一点成就感,也大大加深了我们努力钻研的精神,终于可以学以致用了。我们相信在以后我们会更加努力的去探讨知识,开发出更好的软件!
    参考文献【1】王珊 萨师煊第四版 数据库系统概论
    【2】王珊 萨师煊第五版 数据库系统概论
    【3】java语言程序设计
    【4】java编程思想
    【5】清华大学出版社 主编 徐琳等 java程序设计专家门诊
    【6】UML统一建模教程
    5 评论 222 下载 2018-11-06 14:36:13 下载需要8点积分
  • 基于C语言实现的仓库管理系统

    1 题目要求该系统用于实现仓库管理,系统应支持入库、出库、库存查询以及打印。用户可自定库存警戒值,库存低于警戒值时以红字显示。仓库信息需要用文件存储。
    2 需求分析根据题目要求,由于货品信息存放在文件中,所以应该提供文件的读入、输出等操作;在程序中要浏览货品信息,应提供显示、查找、排序等操作;实现货物入库功能,要提供结构体的输入操作;实现统计功能,要提供相应的统计操作;实现修改功能,要提供修改操作;另外,还要提供键盘式菜单实现功能选择。
    3 总体设计根据上面的需求分析,可以将该系统的系统的设计分为大模块,即入库模块、出库模块、查询模块、排序模块、修改模块和统计模块等。

    4 详细设计4.1 主函数
    #include<stdio.h>#include<windows.h>#include<string.h>#include<conio.h>void main(){ int sele; Re_file(); //读取货品信息 sele=1; while(sele) { system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* 1.入库 2.出库 *\n"); printf("* *\n"); printf("* 3.查询 4.排序 *\n"); printf("* *\n"); printf("* 5.修改 6.统计 *\n"); printf("* *\n"); printf("* 7.退出 *\n"); printf("* *\n"); printf("*********************************************\n"); printf("请选择功能序号:"); scanf("%d",&sele); switch(sele) { case 1:Stock_in();Display();break; case 2:Stock_out();Display();break; case 3:Query();break; case 4:Sort();Display();break; case 5:Modify();Display();break; case 6:Statistics();break; case 7:exit(0);sele=0;break; } printf("\n\n按任意键继续...\n"); getch(); } Wr_file();}
    4.2 各功能模块设计4.2.1 数据读入模块单独看各组数据信息,货品名称是字符串,可以采用字符型数组;其他数据均可用整数存放。数据信息存放在文件中,一条记录对应一种货品的信息,既符合习惯也方便信息管理。把一种货品的相关信息作为结构体成员,如果要存放若干种货品的信息就要用结构体数组。
    typedef struct{ int num; //货品编号 char name[20]; //货品名称 int stock; //原始库存 int in; //入库数目 int out; //出库数目 int amount; //最终库存 int warning_value; //警戒值 int state; //库存状态(是否低于警戒值)}goods;goods s[M]; //用于存放货品信息 goods r[M]; //用于存放入库货品信息 goods t[M]; //用于存放出库货品信息
    s[M]、r[M]、t[M]的M为货品种类数,程序中采用宏定义的方式,可以随时在源程序宏定义中修改。本程序中宏定义为:#define M 50。
    void Re_file() //读入原始库存文件{ FILE*fp; N=0; fp=fopen("goods.txt","r"); while(fscanf(fp,"%d%s%d%d%d%d%d",&s[N].num,&s[N].name,&s[N].stock,&s[N].in,&s[N].out,&s[N].amount,&s[N].warning_value)!=EOF) N++; fclose(fp); P=N;}
    4.2.2 入库模块
    该模块的功能是根据题目要求读入货品的入库数据。注意在主函数中已经读入了原始数据。
    void Stock_in() //读入入库文件{ FILE*fp; int i,j; N=0; fp=fopen("stockin.txt","r"); while(fscanf(fp,"%d%d",&r[N].num,&r[N].in)!=EOF) N++; fclose(fp); for(i=0;i<P;i++) { for(j=0;j<N;j++) { if(r[i].num==s[j].num) s[j].in=r[j].in; } } for(i=0;i<P;i++) s[i].amount=s[i].stock+s[i].in;}
    4.2.3 出库模块该模块的功能是根据题目要求读入货品的出库数据。注意在主函数中已经读入了原始数据。
    void Stock_out() //读入出库文件{ FILE*fp; int i,j; N=0; fp=fopen("stockout.txt","r"); while(fscanf(fp,"%d%d",&t[N].num,&t[N].out)!=EOF) N++; fclose(fp); for(i=0;i<P;i++) { for(j=0;j<N;j++) { if(t[i].num==s[j].num) s[j].out=t[j].out; } } for(i=0;i<P;i++) s[i].amount=s[i].stock+s[i].in-s[i].out;}
    4.2.4 浏览模块
    该模块的功能是显示所有货品的记录信息。根据货品库存数目是否低于警戒值,分别按红字显示和白字显示。采用SetConsoleTextAttribute函数改变输出字体颜色。
    void Display() //显示库存情况{ int i,j; system("cls"); Estimate(); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); for(i=0,j=1;i<P;i++,j++) { if(s[i].state==1) //库存值小于警戒值红字显示 { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value); if(j%10==0&&j!=P) //控制每次显示十行 { printf("按任意键继续..."); getch(); puts("\n"); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); } } else if(s[i].state==0) //库存值不小于警戒值白字显示 { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n", s[i].num, s[i].name, s[i].stock, s[i].in, s[i].out, s[i].amount, s[i].warning_value); if(j%10==0&&j<P) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("按任意键继续..."); getch(); puts("\n"); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); } } }}
    4.4.5 判断模块该模块用于判断货品库存数目是否小于警戒值并记录,多次在其他被模块调用。
    // 判断库存值是否小于警戒值void Estimate(){ int i; for(i=0;i<P;i++) { if(s[i].amount>=s[i].warning_value) s[i].state=0; else if(s[i].amount<s[i].warning_value) s[i].state=1; }}
    4.4.6 查询模块
    该模块的功能是根据输入的货品名称或货号查找对应的记录,找到以后,显示货品记录。同时,库存数目小于警戒值以红字显示。
    // 查询货品void Query(){ int k,m,i,j=-1; char n[20]; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.货品编号 2.货品名称 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入查询选项:"); scanf("%d",&k); if(k==1) { printf("请输入货品编号:"); scanf("%d",&m); for(i=0;i<P;i++) { if(m==i) j=m-1; } } else if(k=2) { printf("请输入货品名称:"); scanf("%s",&n); for(i=0;i<P;i++) { if(strcmp(n,s[i].name)==0) j=i; } } Estimate(); if(j==-1) { printf("\n没有找到!\n"); Printf_back(); } else { if(s[j].state==1) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n");printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[j].num,s[j].name, s[j].stock,s[j].in,s[j].out,s[j].amount,s[j].warning_value); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); Printf_back(); } else { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED| FOREGROUND_GREEN | FOREGROUND_BLUE); printf("货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值\n"); printf("%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[j].num,s[j].name, s[j].stock, s[j].in, s[j].out,s[j].amount,s[j].warning_value); Printf_back(); } }}
    4.4.7 排序模块该模块的功能是将货品记录按照最终库存升序排列。这里按照冒泡法排序。排序完成后显示货品记录,显示完成后返回主菜单
    // 商品库存总量从小到大排序void Sort() { int i,j; goods t; for(i=0;i<P-1;i++) for(j=i+1;j<P;j++) { if(s[i].amount>s[j].amount) { t=s[i]; s[i]=s[j]; s[j]=t; } } Display(); Printf_back();}
    4.4.8 修改模块
    该模块的功能是根据货品编号或货品名称找到要修改的记录,并提示用户修改该记录的哪部分信息(原始库存、入库数目、出库数目、警戒值),然后根据用户的选择修改相应的位置。最后显示货品信息供用户确认。
    // 修改货品信息void Modify() { int k,m,i,j=-1,t,h; char n[20]; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.货品编号 2.货品名称 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入修改选项:"); scanf("%d",&k); if(k==1) { printf("请输入货品编号:"); scanf("%d",&m); for(i=0;i<P;i++) { if(m==i) j=m-1; } } else if(k==2) { printf("请输入货品名称:"); scanf("%s",&n); for(i=0;i<P;i++) { if(strcmp(n,s[i].name)==0) j=i; } } if(j==-1) { printf("\n没有找到!\n"); Printf_back(); } else { printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* 1.原始库存 2.入库数目 *\n"); printf("* *\n"); printf("* 3.出库数目 4.警戒值 *\n"); printf("* *\n"); printf("*********************************************\n"); printf("请选择修改选项:"); scanf("%d",&t); if(t==1) { scanf("%d",&h); s[j].stock=h; } else if(t==2) { scanf("%d",&h); s[j].in=h; } else if(t==3) { scanf("%d",&h); s[j].out=h; } else if(t==4) { scanf("%d",&h); s[j].warning_value=h; } s[j].amount=s[j].stock+s[j].in-s[j].out; } printf("请确认核对货品信息:\n"); Display();}
    4.4.9 统计模块
    该模块的功能是根据用户的选择统计货品总数或最终库存低于警戒值的货品种数。统计结束后将所有货品信息以文件形式输出。
    // 统计数目void Statistics() { int k,i,j,m=0,n=0; system("cls"); printf("\n\n"); printf("*********************************************\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* 1.库存总数 2.库存状态 *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("*********************************************\n"); printf("\n\n请输入查询选项:"); scanf("%d",&k); if(k==1) { for(i=0;i<P;i++) m=m+s[i].amount; printf("库存总数为:%d",m); } else if(k==2) { Estimate(); for(j=0;j<P;j++) if(s[j].state==1) n=n+1; printf("低于库存警戒值的商品种数为:%d",n); } Wr_file();}
    4.4.10 数据输出模块该模块的功能是将货品信息写入文件。
    // 写输出文件int Wr_file() { FILE*fp; int i; fp=fopen("amount.txt","w"); for(i=0;i<P;i++) fprintf(fp,"%-9d %-10s%-10d%-10d%-10d%-10d%-10d\n",s[i].num,s[i].name, s[i].stock,s[i].in,s[i].out,s[i].amount,s[i].warning_value); fclose(fp); return 1;}
    5 上机操作5.1 数据源该程序的运行需要四个文件,三个用于读取货品信息,一个用于存储货品息。goods.txt文件的格式如下:
    货品编号 货品名称 原始库存 入库数目 出库数目 最终库存 警戒值1 A1 456 0 0 456 4002 A2 23 0 0 23 1003 A3 67 0 0 67 1004 A4 104 0 0 104 1005 A5 78 0 0 78 100
    用于读取货品编号、货品名称、原始库存、警戒值等货品信息。
    stockin.txt文件的格式如下:
    货品编号 入库数目1 573 784 805 236 10
    用于读取入库信息。
    stockout.txt文件的格式如下:
    货品信息 出库数目1 102 53 234 125 3
    用于读取出库信息。
    amount.txt文件用于存储货品信息。
    5.2 编译、链接和运行5.3 结果主函数界面

    入库模块

    出库模块

    查询模块

    排序模块

    修改模块

    统计模块

    6 总结通过这次课程设计,我进一步理解和运用了结构化程序设计的思想方法,初步掌握了开发小型实用系统的基本方法,学会了调试较长的程序,能够利用流程图描述算法,进一步掌握和提高利用C语言进行程序设计的能力。
    在程序的编写中,我们首先要构架好整体结构,然后再将各个模块的函数写出来。在写函数的过程中,我们要选择性地利用到所学的知识,如排序法、while循环、if语句等,实现相应的功能。一个较大的程序主要调试方法有分模块调试和分步调试。文件的数据格式很重要,要与程序读取的数据类型保持一致。程序调试通了以后,在修改其中的细节问题。
    学习好C语言这门课,能为我们以后开发出更多实用的程序打下坚实的基础。要学好C语言这门课,我们平时就要勤于实践,锻炼自己的逻辑思维能力与整体构架能力。
    9 评论 146 下载 2018-11-05 10:24:37 下载需要5点积分
  • 基于java的改良版超级玛丽

    1. 用户需求1.1 用户希望游戏要有它的创新性,有吸引力我们的这个游戏考虑到用户的这样的希望有新鲜感的心理需求。所以我们游戏首先有很多创意。从开始构思的时候我们就想基于软件园的实际生活,做一款跟我们每天的生活都息息相关的游戏。这样就产生了《逃离寝室》这样的构思,游戏主人公会从寝室之中逃出,然后越过种种障碍,闯过许多关,最后成功上完一天的课程。像这种冒险类游戏其实有很多,像是超级玛丽、temple run,地铁跑酷等等,一个游戏的灵魂不是他的游戏方法,而是其主题的定位。可以说在创意上面,我们已经占领了先机。
    1.2 用户希望有帮助等基本功能在吸引用户之后,要满足用户的对游戏的探索能力。在编写这个游戏的后期,我们小组给程序设置了帮助功能,将会给用户讲解游戏的规则以及具体的游戏方法,进一步指导用户将这个游戏玩下去。
    1.3 用户希望有好的视觉体验我们小组,为了使用户有更好的视觉体验,在游戏的编写过程中也一直在商讨关于游戏的人物障碍物背景等等的外观,以求使用户在游戏的过程中不会产生审美疲劳。也有更好的体验。
    1.4 用户希望有更好的听觉体验为了实现这个目标我们给游戏增加了背景音乐。
    1.5 用户希望游戏过程流畅为了实现这个目标我们进行了两方面的工作。第一就是游戏的障碍物的出现比例和节奏的调整,如果障碍物太多或者太少,会使游戏太难或太简单,以至于用户丧失游戏兴趣。其次就是运用了多线程的方法,使电脑的CPU合理分配,使游戏的画面更加流畅,不会出现卡机等现象。
    2. 系统设计计划做一个类似于超级玛丽之类的冒险游戏。主人公就是我们作为游戏原型。主要的任务就是主人公会试图从寝室出来赶时间去上课,途中会遇到种种困难阻碍我们上课的道路,我们需要做得就是闯过这些障碍最终顺利到达教室。我们的具体的类的大致设计和构思为:

    游戏流程:

    3. 系统实现我们每个周的任务进度:
    第一周

    我们已经想出了大体的设计方向及游戏的某些功能及流程
    已经初步做了几个像素小人
    正在做GIF形式的小人,一像素一像素的改
    做了一些图形界面的学习设计
    待解决的问题及后续的工作安排
    怎么样将真人做成人物并融合到程序里面
    具体的算法流程等还不是非常清楚,正在学习的阶段
    后续会先开始进行简单的地图的绘制以及人物和障碍物的创建

    第二周

    已完成的工作
    音效类,游戏中相应的音效
    精灵类,游戏中存在的人物形象,人物所存在的动画效果以及所拥有的特效;以及人物所产生的相应效果,满足相关的游戏性
    金币类,实现金币与人物的交互功能,实现金币的基础算法
    新增素材:下载了一些简单的人物素材和音乐背景,准备先做一个demo,再具体改
    本周遇到的问题 对GUI用户界面的一些方法还不是很熟悉
    写精灵的过程中出现精灵不能随着操作的指令做相应的动作,系统指令无效,无法实现交互。通过查阅资料以及不断地改进尝试终于发现了监听器出现了问题,最终改变监听器的错误,得到改进,精灵可以完成用户想让其进行的各种动作
    在创建金币类的过程中,出现了程序错误,不能正常实现金币的产生,后来经过debug发现是由于金币数组越界产生的,随后改变数组的定义,得到解决

    第三周

    本周完成了map背景类,将从网上搜集的图片元素加入界面中,实现界面的设计,实现界面可以随着指令发生移动而完成相应功能; 精灵碰撞类,实现精灵与地图元素的交互功能,当精灵与元素进行碰撞之后,实现相应的动画效果
    数据文件及数据库文件还未全部进行加入。正在设计基本类
    素材:像素小人已经初步捏好。从而实现创建了精灵类
    音效已经找好并自己录制了一部分。实现了音效类
    增强了小组成员的之间的融合。经过美工的PS设计,使得我们的界面更加的好看更加的友好。同时增加了交互的功能设计,比如调节音量等。下一步准备增加更多的交互式设计,实现更多的功能选择比如调节速度调节难度等等

    第四周

    进一步优化界面,加强人机交互的功能。人物素材也进行了修改,准备动作、前进动作、跳跃动作等等都进行了讨论并由美工进行了进一步的制作和修改。基本实现了游戏算法类和动画类
    游戏的完整体系已经基本完成了,大体框架已经形成,接下来进行细节处的改动即可。加入游戏开始页面以及游戏流畅性。游戏的开始界面已经结合我们的具体的功能进行了设计,并进行了编写和实现
    在编写动画类的时候出现了动画编程中的动画闪烁和图像残缺不全等现象,后来我们从网上发现是多线程的部分方法出现了问题。为了每秒中多次更新屏幕,必须创建一个线程来实现动画的循环,这个循环要跟踪当前帧并响应周期性的屏幕更新要求。应该生成一个独立的动画线程来完成图像的显示和更新。并改变了一些其他的方法,进一步优化我们的动画效果
    在编写游戏算法类的时候,具体的算法可能还是考虑的不够清楚,常常出一些运行中的错误或者出现编写的某段代码对整个项目无效的情况。经过仔细的思考逐步解决了这些问题
    初步根据我们的系统设计,写了一个游戏的思路以及规则方法
    大体的文案已经形成。

    第五周

    进一步优化界面,加强人机交互的功能。人物素材也全部完成,包括各种行进跳跃动作。把美工所有捏的小人都增加到程序中去了。正式更新了部分的原创设计。使整个界面更加人性化有设计性
    讨论设计了游戏的开始界面及结束界面并进行开发。结合内部的具体构造进行设计,力求准确美观实现各种功能.对人物进行了进一步的修改。逐渐与原来的想法进行拟合。制作开始和结束界面的时候总是有不协调性看起来很奇怪,并且有些想法无法实现。经过不断地努力和修改逐渐解决了这些问题。开始和结束界面初步成型。再做微型调整即可

    第六周

    Javadoc进行了部分修改,因难以全部传输上去,此处仅提供大体的构架和截图,我们在其内部进行了具体的修改
    所做的项目测试工作。项目总体进度
    仍存在的问题,及待提高的方面
    还有一些在测试时发现的问题没有解决,接下来需要大家一起解决代码中的bug,共同解决游戏进行的过程中出现的种种问题,种种影响游戏顺利进行或者不流畅的画面等等问题

    第七周

    本阶段的工作主要是项目的系统收尾工作
    正在进行文档的修改和最终总结报告的书写工作
    更改了一些界面上面的设计。进行系统的最终完善
    比如设计了一些夜间场景。最终的成果的效果还没有最终确定。正在进行不断地比较和修改。开始画面希望能更加完善。还未添加帮助等功能,接下来会进一步添加,尽可能的完善。尽早的提交上我们的作品
    界面、美工、素材的美化。正在进行更改。美工正在进行对素材的梅美化。以求我们的界面更加的美观并且实用,符合我的们的设计的整体风格和思路。下附我们目前的界面,当然我们还会进行不断地改善和调整

    4. 美工素材整体游戏使用了扁平化设计理念。扁平化概念的核心意义是:去除冗余、厚重和繁杂的装饰效果。而具体表现在去掉了多余的透视、纹理、渐变以及能做出3D效果的元素,这样可以让“信息”本身重新作为核心被凸显出来。同时在设计元素上,则强调了抽象、极简和符号化。模拟现实物品的造型和质感,通过叠加高光、纹理、材质、阴影等效果对实物进行再现,也可适当程度变形和夸张,界面模拟真实物体,拟物设计会让你第一眼就认出这是个什么东西。交互方式也模拟现实生活的交互方式。简约而不简单,搭配一流的网格、色彩设计,让看久了拟物化的用户感觉焕然一新;突出内容主题,减弱各种渐变、阴影、高光等拟真视觉效果对用户视线的干扰,让用户更加专注于内容本身,简单易用。设计更容易,优秀扁平的设计只需保证良好的架构、网格和排版布局,色彩的运用和高度一致性。
    在色彩搭配方面,颜色是影响整个游戏的重要因素,不同的颜色对人的感觉有不同的影响。整体颜色采用了冷色调, 多为蓝、绿等。游戏主人公使用了与背景有鲜明对比的红、橙。建筑物使用了传统的灰色调,制作了具有使其与背景整体协调。通过对游戏的各种元素、颜色、字体、图形、空白等,使用一定的规格,使得设计良好的游戏看起来应该是和谐的。游戏设计上要保持一致性,这又是很重要的一点。一致的结构设计,可以让浏览者对游戏的形象有深刻的记忆。一致的背景界面设计,可以让浏览者迅速而又有效的进入在软件中自己所需要的部分,一致的操作设计,可以让玩家快速地了解、上手游戏。建筑风格上参考纪念碑谷,给玩家带来新鲜的感觉。



    5. 收获体会以往几周的实验报告摘要
    第一周结论分析与体会:

    每一个项目的进行都需要具体的执行方案和具体的分工合作。
    好的创意和构思往往来源于生活。
    在做一个项目之前应该先想好具体的框架及模板模块,以防真正执行起来的时候出现种种难以预料的问题。
    任何创意的背后都需要强大的技术支持和不断地学习,经验的积累。

    第二周结论分析与体会:

    学习的过程是艰苦的迂回的,所有的代码都不是能够突然写出来突然完成的。
    不能太急于求成,从小的方面一点点的进行,最终实现整个类的实施,才是比较可行的方法。学习的过程是必须的,不能急躁。
    在一些容易出错的地方比如数组超界之类的问题要一开始就多加注意。写代码的时候要有给每一个模块增加注释的习惯,这样遇到问题的时候比较好随时回来改。
    debug的时候要有耐心,一遍遍的进行调试更改,不能急躁。
    要懂得合作。合作的力量是无穷的!

    第三周结论分析与体会:

    每一个程序的实现不能只是简单地大体的做一下,必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    增强游戏的功能,提供更多的交互功能。在游戏过程中能够随时进行调节。
    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    想法也要尽可能完善,尽量在初期考虑到后面的可行性。

    第四周结论分析与体会:

    必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    有了大体的框架可能更有利于下面的进一步细节的改动,有些细节不用太过拘泥,可以形成基本框架之后再进行改动。要有整体意识。

    第五周结论分析与体会:

    每一个项目的进行都需要经过不断的调试不断的改进,前面做的某些东西要根据实际的项目发展进行改变。制定目标时不能定死。多做一些动态方法。有利于项目的进行。
    有了大体的框架可能更有利于下面的进一步细节的改动。

    第六周结论分析与体会:

    必须要考虑要多种因素的影响,考虑到用户的游戏时的视觉感官体验等等。
    游戏基本完成时其测试的安排十分重要,包括测试的规划,如何进行,部署,怎么样才能发现更多的问题并且进行解决,发现问题的时候又应该如何解决,对我们来说都是一些挑战。测试前要事先做好规划,并且测试进行的过程中发现的问题要及时记录并想办法解决。

    第七周:结论分析与体会:

    每一个游戏的完成都是艰难的,只有坚持到底,不断地学习不断地进步才能实现最后的成功。
    在今后的学习生活中还要不断培养自己的自学能力,遇到各种困难都不能退缩。逐步增强自己解决问题的能力。

    最终总体体会:
    课设的构想是美妙的,但是真正做起来却是困难的。从组队确定好主题到现在我们遇到了很多很多的困难。刚开始的时候什么都不懂,经过上学期的学习,对于GUI、多线程等等就只是听说过,一点也不懂,难以想象这样的我们有一天会做出这样一个比较完整的作品。回过头来想想走过的路真是感慨万千。经过了课程设计的锻炼,我们总结出了以下这样的几个经验或者说是体会。

    首先,对于任何事物都要有一个总体的规划。对于大体要做成什么样子,必须有一个整体的规划并且向着那个明确的目标努力,不能无组织的随便乱写。必须有了正确的明确的大方向的指引,才能不断的朝这个目标努力并且最终实现。
    其次,任何事物的完成要有扎实的基本功做基础。像刚开始的我们什么都不懂。在游戏的编写过程中我们也吃了很多苦。上课的时候认真听讲做笔记,下课之后课下也要不断地对代码进行研究,研究各种资料。我们都深切的感受到,没有深厚的技术基础做保障,所有的都是空谈。
    实践出真知。很多时候只是上课好像听懂了或者是看视频看懂了其实真正自己敲起来的时候还是觉得很困难,出现了很多的bug,也都得一点点的去改,有时候很多bug发现不了也改不出来的时候特别烦躁,不过也得耐心一点点看。可以说在这个过程中我们每个人都吃了很多苦,不过也正因为这个过程我们的能力也得到了很大的提高,从一开始的什么都不会到现在的可以完成一个完整的游戏,这对我们来说已经是巨大的飞跃和提高。在这个过程中我们极大的锻炼了自己的自学能力。
    团队的力量是无穷的。自己一个人完成一个大的任务可能是困难的,但是有了小组的合作,有了大家的齐心协力任何困难都会被解决的很好。
    我们的代码可能还比较幼稚比较简单,但是我们已经付出了很多努力,不管多难,都能努力咬牙坚持去学习去尝试去自己写,而不是简单地copy网上的或者别人的代码。正因为有了这样的毅力有了这样的决心才会有进步才会有提高。我们也知道我们的能力还不足,我们也还有很大的进步的空间。在以后的学习中,生活中,我们还会继续努力,课程设计虽然即将告一段落,但是我们的学习之路还远远没有结束,将来的路还很长。我们会永远记得这段努力完成课设的时光,并继续加油、继续努力。向着我们的未来向着我们的目标不断迈进。
    0 评论 2 下载 2019-06-24 14:10:51 下载需要15点积分
  • 基于javaEE学生选课系统

    摘 要本人结合学生选课管理的实际需要,完成了对学生选课管理系统的需求分析、功能模块划分、数据库模式分析等,并由此设计了后台数据库以及前台应用程序。
    文中首先对课题背景,数据库基础理论和SQL语言进行了简单的讨论;对学生选课管理系统进行了详细分析,划分了具体的功能模块;最后,给出了学生选课系统应用程序的设计过程,以及每个功能模块的核心代码。
    系统可以实现学生选课的一些重要功能,如:课程的添加、删除,信息查询、选课、生成课表,以及学生选课管理人员、用户个人信息的维护等。学生选课系统主要是为学生选课的管理提供全面、准确、科学的管理方法,方便快捷地处理选课的管理信息;避免了信息处理错误,提高了信息管理的工作效率,便捷的网上选课,大大地节省人力和物力的开支。
    1. 开发工具选择采用一个开放源代码的、基于Java的可扩展开发平台eclipse作为主要开发工具,以及一个大型关系数据库管理系统SQL Server作为数据管理工具
    2. 开发环境
    开发系统:Win7
    系统开发平台:eclipse5.0
    系统开发语言:javaEE

    3. 本报告的主要内容本报告详细的介绍了学生选课系统的开发过程,主要涉及到的工作如下:选课的一些重要功能,如:课程的添加、删除,信息查询、选课、生成课表,以及学生选课管理人员、用户个人信息的维护,系统的总体设计、系统的概念设计、系统各模块的详细设计、系统运行与测试。
    功能要求:

    用户登录
    查看个人信息
    修改个人信息
    查看个人选课情况
    查看所有课程信息,能够选定课程
    退选课程

    4. 关系型数据库关系数据库由表组成。一个关系是由一个二维表来定义的:表的行保存事物的一组属性数据,表的列定义了事物的属性
    5. 创建数据库表设计如下所示的实体和属性的定义:

    课程信息(课程代号,课程名称,学分)
    学生信息(学号,姓名,性别,出生年月日,专业)
    学生登录信息(学号,用户名,密码,权限代号)
    学生选课信息(学号,课程代号,学期,上课时间,任课老师)
    用户权限(权限名称,权限代号)。

    学生表和专业表是单向多对多的关系专业表与学生表是一对多的关系


    6. 系统总体结构及功能模块划分6.1 功能模块设计
    6.2 struts图
    6.3 系统主要功能实现及代码6.3.1 主页面
    6.3.2 学生信息录入
    6.3.3 所有课程信息
    6.3.4 学生信息查看
    6.3.5 总体图
    总结通过这次课程设计,使我灵活应用所学javaEE知识,,结合javaEE理论知识,编写程序实现系统所需功能。初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;提高综合运用所学的理论知识和方法分析和解决问题的能力;并用系统的的观点进行系统设计,巩固、深化学生的理论知识,提高编程水平,并在此过程中培养我们严谨的科学态度和良好的编程风格。进一步加深对SSH框架的知识的理解,并能够利用SSH框架的知识实现教务管理系统。同时在这学期的实验中,培养了以专业的眼光去对待我们系统中的每一段代码,这算是一次不可多得的实践机会。在这一次的实践过程中,个人动手能力,方方面面都得到了一定程度的提高。在这个过程中,我学会了很多学习的方法。而这是日后最实用 也是最宝贵的。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这对于我们的将来也有很大的帮助。通过这次课程设计使我明白了自己知识还比较欠缺,只是学习书本知识还是远远不够的,自己不会的东西还有太多,学习需要自己长期的积累,在以后的学习、工作中都应该不断的学习,将课本的理论知识与生活中的实践知识相结合,不断提高自己文化知识和实践能力。
    0 评论 1 下载 2019-06-24 13:55:49 下载需要11点积分
  • 基于Java和Sql Server的C/S架构图书管理系统

    1 系统设计目标1.1 应用背景图书管理系统是各图书馆都需要使用的系统,它能帮助图书管理员更好地管理海量图书,尤其是在图书馆藏数量和读者数量都很大的图书馆,我们无法用手写的方式录入、管理图书信息和借阅信息,必须借助图书管理系统来完成这些工作。
    1.2 总体目标系统的使用者分为管理员和读者。管理员负责新书的录入、旧书的清理、借书审核、还书审核,以及日常的维护,有权限增删图书的信息;读者要能够根据书名查找图书,并选择中意的图书进行借阅,读完以后还可以还书;读者没有权限修改图书的信息,他对图书的操作仅限于借、还。这就是一个简单的图书管理系统的大致功能。
    2 需求分析系统总体功能需求列表如下表所示。



    功能编号
    功能名称
    功能描述
    权限




    1
    录入图书信息
    将新的书籍信息录入系统
    管理员


    2
    删除图书信息
    将损坏的图书从系统删除
    管理员


    3
    修改图书信息
    更新图书信息
    管理员


    4
    审核还书申请
    审核读者的还书请求,检查图书损坏情况并开出罚单
    管理员


    5
    审核借书申请
    审核读者是否有罚金未交,确定读者是否可借阅书籍
    管理员


    6
    查找书籍
    通过书名查找书籍信息
    读者


    7
    查询个人信息
    读者查询个人信息
    读者


    8
    查询借书记录
    读者查询借书记录
    读者


    9
    借书
    读者选择书籍进行借阅
    读者


    10
    还书
    归还借阅的书籍
    读者


    11
    续借
    继续借阅到期的书籍
    读者


    12
    交款
    缴纳罚金
    读者



    性能需求上,要求所有的操作都没有明显的延迟,这对于现在的计算机来说不算难事,所以是不用刻意考虑性能方面的因素的。
    数据完整性,具体在数据库设计中说明。
    系统的数据流图如下图所示。

    3 总体设计系统采用C/S模式实现,没有为服务器设计专门的客户端,实际上服务器就是数据库,用户是读者和管理员。主要分为两大功能板块:管理员和读者。
    实际的图书管理系统要配合扫描仪等设备进行使用,我们的系统显然不能连接外设,适当信息需要手动输入。
    系统的总体结构图如下图所示。

    3.1 管理员3.1.1 图书信息管理具体又分为两个部分:新书上架,也就是将新书的各项信息录入到数据库;查询维护,通过索书号、书名、作者等信息进行查询,得到查询结果后,可以选中并删除图书,这主要是方便管理员查找图书,找到以后还可以精准地删除图书。
    3.1.2 读者信息管理与图书信息管理类似,可以录入、查找并修改或注销读者信息。
    3.1.3 借阅管理分为借书和还书两部分。读者想要借书时,发出一个借书请求,管理员收到该请求后,查看该读者是否还存在有罚金未交的情况,若是,则拒绝读者的借书请求;否则,同意借书。读者还书时也发出还书请求,管理员收到后,查看该读者是否延期还书,或者图书损坏,若是,则开出罚单,等待读者缴费,若图书损坏,则将图书标记为损坏,否则,进行还书登记。
    3.2 读者3.2.1 借阅分为借书、还书和续借。借书时,可以根据关键字在数据库中进行查找,选择借书,此时发出借书申请,等图书管理员审核通过后才能成功借书;还书时,从借阅列表中选择尚未归还的书籍,发出还书请求,等待管理员审核,若审核发现图书有损坏,则会收到罚单;续借是将当前正在借阅的书籍再延长一个借书周期。
    3.2.2 查看报表读者可以查看个人信息、借阅信息、罚单。
    4 数据库设计4.1 ER图用Microsoft Visio2010与SQL server连接,生成的实体关系图如下图所示。

    4.2 权限控制图书馆的访问者主要是管理员和读者,所以设置两个用户。管理员有所有表的所有权限,读者的权限则要受到限制。
    在上图的6个表中,读者有权限访问馆藏表、图书表和作者表,因为读者需要查询图书;读者有权限访问读者信息表,因为他需要查看自己的个人信息;读者有权限查询和更新借阅表,因为他需要查看自己的借书记录,此外,发起借书请求时会向借阅表中增加一条记录,所以需要更新权限;读者有权限查询和更新罚单表,与前者同理,读者需要查看罚单,并且缴纳罚金时会修改罚单状态,所以需要更新权限。读者没有删除任何一个表的权限,有查询所有表的权限和修改部分表的权限。
    4.3 数据库逻辑结构设计数据库主要分成三大部分:图书信息、借阅信息和读者信息,其中借阅信息和读者信息分别可用一个表实现,但是图书信息相对较复杂。在了解了学校图书馆的图书管理系统以后,发现每一本书都有一个索书号,一个索书号可以对应该书的多本实体,每个实体只用索书号是无法区分的,图书馆采用条码进行区分,所以需要增设馆藏信息表来存放每本实体书的条码号和馆藏地点、馆藏状态等。
    同样的,一本书也可能有多个作者,所以也需要用一个单独的表来存放作者,这里我们暂不考虑作者同名的情况,所以没有给作者设置编号。出版社在一般情况下不会同名,也不设置单独的表。
    借阅信息用于存放读者的借阅记录,由于借阅过程存在罚款,所以还有一个罚款表。
    最终图书管理系统的数据库共有6个表:图书信息表、作者信息表、馆藏信息表、借阅信息表、罚款信息表、读者信息表和罚单表,表项分别如下:

    图书信息表:题名,索书号,出版社,发行时间,版本。主码为索书号,题名也不能为空
    馆藏信息表:条码,索书号,馆藏地点,状态。主码为条码,索书号为外码,来自图书信息表,馆藏状态不能为空
    作者信息表:索书号,作者。索书号为外码,来自图书信息表
    借阅信息表:条码,读者编号,借阅日期,归还日期,借阅编号,状态。主码为借阅编号,条码为来自馆藏信息表的外码,读者编号为来自读者信息表的外码
    读者信息表:编号,姓名。编号为主码
    罚款信息表:罚单号,罚金,罚款原因,状态,借阅编号。主码为罚单号,借阅编号为来自借阅信息表的外码

    除了基本表外,还需要若干个视图来实现系统的功能。

    图书视图:题名,索书号,作者,出版社,发行时间,版次,条码,馆藏地点,状态。该视图用于管理员和读者查询图书的结果显示,是图书信息表、馆藏信息表和作者表三者的连接
    借阅记录视图:借阅编号,条码,书名,读者编号,读者姓名,借阅时间。该视图用于管理员对读者的借书请求进行处理,视图中包含所有读者的所有借阅记录,是借阅信息表、图书信息表和读者信息表的连接
    借阅统计:借阅申请次数、借阅成功次数、还书申请次数、还书破损册数。该视图用于管理员的统计查询,对一段时间内的借书、还书信息进行统计
    借阅排行:索书号,书名,借阅次数。用于管理员统计一段时间内借阅次数排名前列的书籍,了解图书馆最受欢迎的书籍情况

    4.4 数据库物理设计图书表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    索书号
    char(20)
    主键






    书名
    char(100)







    出版社
    char(30)







    发行时间
    date



    合法日期



    版本
    tinyint



    正整数



    馆藏信息表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    条码
    int
    主键


    从1起自增



    索书号
    char(20)
    外键


    来自图书表



    馆藏地点
    char(100)







    状态
    tinyint



    0、1、2
    1-在馆 2-借出 0-损坏



    著作表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    索书号
    char(20)
    外键


    来自图书表



    作者
    char(20)







    读者表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    编号
    int
    主键


    从1自增



    姓名
    char(10)







    密码
    char(20)







    借阅表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    借阅编号
    int
    主键


    从1自增



    条码
    int
    外键


    来自馆藏表



    读者编号
    int
    外键


    来自读者表



    借阅日期
    datetime







    归还日期
    datetime







    状态
    tinyint



    0-4
    1-申请借阅 2-在借 3-申请归还 4-已归还 0-失效



    罚单表设计如下表所示:



    字段名
    类型
    主键/外键
    为空
    索引
    取值
    备注




    罚单号
    int
    主键


    从1自增



    借阅编号
    int
    外键


    来自借阅表



    罚金
    int







    罚款原因
    bit



    0、1
    0-过期归还罚款 1-损坏图书罚款


    状态
    bit



    0、1
    0-用户未交罚金 1-罚金已付



    5 详细设计与实现系统用Java语言实现,通过jdbc与SQL server进行连接,获取数据库中的数据。对管理员和用户分别提供了客户端,图形界面用Javafx实现。
    5.1 读者-搜索图书5.1.1 流程图算法的业务流程图如下图所示。借书功能与搜索功能是密不可分的,一般都是先搜索再借书。程序初始化时就从数据库中查找出所有的图书信息,并显示到表格上,用户可以直接选择从表中选取某一项,然后进行借阅;如果图书信息过多,直接选取较为困难,可以在输入框中输入关键字搜索,再选择图书进行操作。

    5.1.2 算法说明图书的状态,如在馆、借出等,在数据库中是用int型存储的,所以向管理员展示时,必须用汉字直观地打出,所以要将int转换成字符串;
    由于每本书都可能有多个作者,所以要对作者进行特别处理,当多条记录的索书号相同而作者不同时,要合并为一条记录,把各个作者拼接成一个字符串,中间用分号隔开;
    此外,在数据库中,如果某个字段是长度为20的字符类型,而实际只用了8个字符,那么后面12个字符会用空格填充,这虽然不影响查询的结果,但是在表格中显示时,空格也会占用空间,所以需要用Java中String.trin()去除多余的空格。
    5.1.3 数据库实现sql语句如下,其中index是搜索的关键字,关键字可以是图书的索书号的一部分、书名的一部分或者图书作者的一部分,即只要有部分字段匹配即可搜索处结果,所以where子句中用“like”进行匹配。
    sql = "select * from dbo.图书 t,dbo.馆藏 t2,dbo.著作 t3 where t.索书号=t2.索书号 " + " and t3.索书号=t.索书号 and (t.索书号='"+index +"' or t.题名 like '%"+index+"%' or t2.条码='"+index+"' or t3.作者 like " + "'%"+index+"%') order by t2.条码,t.索书号,t3.作者";
    5.2 读者-借书5.2.1 流程图图书搜索功能中,在选中了图书并申请借阅以后,要进行一系列判断审核,流程图如下图所示。

    5.2.2 算法说明从选中表项中获取该的条码号,实际上从表中可以直接获取图书的馆藏状态,但是考虑到表中数据可能未及时更新,该书在数据库中可能已经改变状态,所以不能用表中的状态。
    根据条码号从数据库中查询该书状态,如果已经借出或者已经损坏,则提示用户借书失败;否则,可以生成借阅信息,插入到借阅信息表中,并提示用户借书请求成功。这不意味着真正地借书成功,还要等待管理员审核。
    5.2.3 数据库实现插入借阅信息sql语句如下,借阅时间是当前时间,借阅编号自动生成。
    sql = "insert into dbo.借阅(条码,读者编号,借阅时间,状态," + "借阅编号) values("+barcode+",'"+Main.getUser()+"'," + "'"+df.format(new Date())+"',1,"+(count+1)+")";
    5.3 读者-续借/还书5.3.1 流程图算法流程图如下图所示。续借和还书都是以借阅记录表为基础的。虽然在需求分析中,这些功能是相互独立的,但在实际实现时,我们要把他们充分联系起来,这也是为了用户的使用方便。
    从数据库中获取该读者所有的借阅记录,读者可以选中任意一条记录,选择续借或者归还该书籍。

    5.3.2 算法说明读者查看借阅记录时,借阅记录表已经初始化好,从数据库中选取了该读者的所有历史借阅记录,记录的状态分为在借、已归还。
    读者选中某条记录后,若选择续借,则首先要判断是不是在借记录,不是则无法续借,然后还要判断该书是否过期未还,借书期限为一个月,超过期限的书是不可以续借的,若上述条件都满足,则续借成功,将数据库中的借阅时间更新为当前时间,还书期限重新计时。
    若读者选择归还,则先判断该记录是否为在借记录,若不是,则无法归还,若是,则直接申请归还,这不需要新增一条借阅记录,只需要将借阅记录中的状态从在借修改为申请还书,管理员看到以后会进行审核。
    5.4 读者-查看个人信息该选项只能查看信息,不可进行其他操作,功能简单。
    获取读者在借册数的sql语句如下:
    sql = "select count(*) total from dbo.借阅 t where t.读者编号" + "='"+usernum+"' and t.状态=2";
    获取读者总罚金数的sql语句如下:
    sql = "select sum(t.罚金) total from dbo.罚单 t,dbo.借阅 t2 " + "where t.借阅编号=t2.借阅编号 and t2.读者编号='"+usernum+"' and t.状态=1";
    5.5 读者-查看罚单该选项只能查看信息,功能简单。获取罚单的sql语句如下:
    sql = "select t.罚单号,t.罚金,t.罚款原因,t.状态,t.借阅编号,t4.题名," + "t3.借阅时间,t3.归还时间" + " from dbo.罚单 t,dbo.馆藏 t2,dbo.借阅 t3,dbo.图书 t4 " + "where t.借阅编号=t3.借阅编号 and t3.条码=t2.条码 and " + "t2.索书号=t4.索书号 and t3.读者编号='"+Main.getUser()+"'";
    5.6 管理员-查询图书管理员查询图书与读者查询图书的流程基本相同,不再赘述。
    5.7 管理员-下架旧书
    5.7.1 流程图算法流程图如上图所示。
    5.7.2 算法说明由于管理员看到的图书信息实际上是由图书信息表和馆藏信息表连接生成的,所以在进行图书下架时,既涉及到馆藏信息的删除,又有图书信息的删除。有些书籍没有馆藏信息,只有图书信息,则只需要删除图书信息表,否则只要删除馆藏信息表,不能删除图书信息表,因为该图书可能存在其他实体,我们只能一次删除馆藏信息中的一个实体,如果把图书信息也一并删除,则馆藏信息的外键引用会出错。
    5.8 管理员-录入图书5.8.1 流程图算法流程图如下图所示。

    5.8.2 算法说明录入图书时,索书号和条码号绝对不能为空,须在所有操作之前检查。录入的情况分两种:首先是索书号已经存在的,也就是说,这本书以前就在图书馆中存在,现在又购置了该种书的一批新书,所以图书信息不需要再插入,直接插入馆藏表即可;
    第二种是该书原本不存在的情况,图书馆第一次购置该种书,则需要先插入图书信息表,然后再插入馆藏信息表,不可改变插入顺序,否则外键引用出错。
    5.8.3 数据库实现插入图书信息:
    sql = "insert into dbo.图书(题名,索书号,出版社," + "发行时间,版本) " + "values ("+bname+","+isbn+","+press+","+ymd+","+version+")";
    插入馆藏信息:
    sql = "insert into dbo.馆藏(条码,索书号,馆藏地点," + "状态) " + "values ("+barcode+","+isbn+","+store+",1)";
    5.9 管理员-查询读者5.9.1 流程图算法流程图如下图所示:

    5.9.2 算法说明搜索框的输入可以是读者编号、读者姓名的一部分,在数据库中的读者信息表中查找符合要求的项,这样的项可能有多个,循环取出,依次查找他们的在借册数和罚金数额,都添加到结果表格中显示。
    5.10 管理员-修改读者5.10.1 算法说明管理员选中读者表中的某个以后,选择修改该读者的信息,由于Javafx中的表格直接修改不太方便,所以用弹窗的方式修改。将原来的读者信息在弹窗中显示,管理员选择修改,点击确认以后,将修改后的信息写入到数据库中该读者对应的条目。
    5.11 管理员-注销读者
    5.11.1 流程图算法流程图如上图所示。
    5.11.2 算法说明管理员选中某个读者,选择注销该读者,先判断读者是否有在借书籍,如果有,则不能注销,否则该读者无法还书;再判断该读者是否有罚金未交,如果有,则不可注销,否则会造成图书馆的亏损。若上述情况都没有,则直接将其从读者信息表中删除,其他在外键中引用了该读者的表项也会被触发器一并删除。
    5.12 管理员-审核借书5.12.1 流程图算法流程图如下图所示:

    5.12.2 算法说明审核读者的借书申请时,首先要检查读者已经借了多少册书,若达到上限,则不允许继续借书;然后检查该读者的罚单,如果有罚金未交,也不允许借书;再检查该读者在借记录,若有书过期未还,不允许借书。
    以上情况均不存在,则读者有借书资格,然后检查该书是否在馆,因为该书可能被前面的读者借走了,若在馆则允许借书,审核通过,否则失败。
    5.13 管理员-审核还书5.13.1 流程图算法流程图如下图所示:

    5.13.2 算法说明管理员审核还书时,先要看图书是否损坏,判断以后填写,如果损坏,则需要生成书籍损坏的罚单,还要将该图书的馆藏信息状态修改为损坏。然后再判断读者是否未按时归还该书籍,若是,则需要生成延期的罚单。最后将归还日期写入数据库,审核完成。
    5.14 数据库事务实现在进行书籍的录入时,先要向图书信息表添加数据,然后再向馆藏信息表添加数据,这两者是分两步进行的。在一般情况下,两步都会成功。但是,特殊情况下,可能插入图书信息成功,而插入馆藏信息失败,这是不应该的。为此我们要添加数据库事务,目的是,对于连续的几个数据库操作,要使其成为原子操作,也就是,要么全都执行成功,要么全都不执行。假如第一条成功了,而第二条失败了,那么要将第一条的结果回滚,部分代码如下所示:
    stmt.executeUpdate(sql_1);stmt.execteUpdate(sql_2);conn.commit();//若所有结果执行完成,则执行提交事务ps.close();conn.close()catch(ClassNotFoundException e){ e.printStackTrace();}catch(SQLException e){ e.printStackTrace(); try{ //只要有一个sql语句错误,则事务回滚 conn.rollback(); }catch(SQLException e){ e.printStackTrace(); } }
    5.15 触发器-删除空白书籍5.15.1 触发器说明书籍的信息是存放在图书信息、馆藏信息两个表中的,在录入某种书籍时,先在图书信息表种录入一条数据,再在馆藏信息表中录入多条数据,表示该种书的多个实体。假如该种书全都损坏,则馆藏表中关于该书的条目全都被删除,此时图书信息表中还残留有该书的信息,这条信息已经无效了,需要删除。为了避免手动删除,使用触发器来实现,每次更新或者删除馆藏信息后,检测图书信息表中是否有某条记录已经没有馆藏书籍,将它从图书信息表中删除。
    5.15.2 触发器实现触发器功能部分如下:
    ALTER TRIGGER [dbo].[delete_emptybook] ON [dbo].[馆藏] AFTER DELETE,UPDATEAS BEGIN SET NOCOUNT ON; delete from 图书 where 0=(select count(*) from 馆藏 where 馆藏.索书号=图书.索书号)END
    15.16 触发器-设置图书损坏5.16.1 触发器说明当读者还书时,管理员需要判定该书是否损坏,如果鉴定为损坏,则需要开具罚单,罚单中有一项表示罚款的原因是书籍损坏还是迟还,如果该项填写为书籍损坏,则自动将馆藏表中对应的书籍馆藏状态设置为损坏,省去了手动设置。
    5.16.2 触发器实现触发器功能部分实现如下:
    ALTER TRIGGER [dbo].[set_bookbroken] ON [dbo].[罚单] AFTER INSERT,DELETE,UPDATEAS BEGIN update 馆藏 set 状态=0 where exists (select * from inserted,(select * from 借阅)t where inserted.罚款原因=1 and inserted.借阅编号=t.借阅编号 and t.条码=馆藏.条码)END
    5.17 触发器-设置罚金5.17.1 触发器说明在开具罚单时,管理员只需要填写罚款原因,而罚款金额有数据库生成,规定过期还书罚款1元,书籍损坏罚款5元,自动设置罚款的触发器根据罚款原因进行罚金的设置。
    5.17.2 触发器实现触发器功能部分实现如下:
    ALTER TRIGGER [dbo].[set_fine] ON [dbo].[罚单] AFTER INSERT,DELETE,UPDATEAS declare @sake bit;BEGIN select @sake = 罚款原因 from 罚单; if @sake=0 begin update 罚单 set 罚金=1 where exists(select * from inserted where 罚单.罚单号=inserted.罚单号) end else begin update 罚单 set 罚金=5 where exists(select * from inserted where 罚单.罚单号=inserted.罚单号) endEND
    5.18 触发器-修改读者信息5.18.1 触发器说明管理员有一项功能是修改读者的信息,如果只是修改了读者姓名、密码等,那么只需要修改读者表这一个表,而如果修改了读者编号,即修改了主码,那么与该读者有关的借阅信息表中存有的该读者的编号也要进行修改,这一操作不能让管理员执行,需要用触发器实现。
    5.18.2 触发器实现触发器功能部分实现如下:
    ALTER TRIGGER [dbo].[update_aboutuser] ON [dbo].[读者] AFTER UPDATEAS declare @old char(10) declare @newuser char(10)BEGIN select @old=t.编号 from deleted t select @newuser =t.编号 from inserted t update dbo.借阅 set 读者编号=@newuser where 借阅.读者编号=@oldEND
    6 系统测试6.1 管理员-图书查询测试6.1.1 测试说明可以在选择框输入索书号、作者或者是书名,均可查询出结果。
    6.1.2 测试过程管理员的图书查询维护界面如下图所示,未执行查询时会显示所有的图书信息。

    查询可以根据索书号、书名、作者这三个关键字的全部或者部分进行查询,根据索书号查询结果如下图所示。

    根据书名查找结果如下图所示。

    根据作者查询结果如下图所示。

    查询失败结果如下图所示,书库中暂无该书。

    若输入框为空,则查询结果为所有书籍。
    6.2 管理员-图书下架测试6.2.1 测试说明任务书中要求管理员可以进行旧书下架,旧这个概念比较模糊,没法严格定义,所以我们把一本书是否已经“旧”了的决策权交给管理员,也就是说,管理员可以删除任何他认为算作旧书的书籍,所以管理员可以选择任何书籍进行删除,除非该书已借出,不在馆。
    6.2.2 测试过程选中已经借出的书籍《大卫•科波菲尔》,选择下架,弹出窗口警告该书已借出,不可删除,如下图所示。

    选择在馆图书《夏洛的网》,点击下架,结果如下图所示,删除成功。

    《夏洛的网》只有一本实体书,删除以后,馆藏信息表中已经没有该书,而图书信息表中还有该书,此时触发器检测到该书没有馆藏信息,在图书信息表中将其自动删除。
    6.3 管理员-新书上架测试6.3.1 测试说明新书上架界面如下图所示,其中索书号一栏用的是下拉框,既可以选择又可以输入,这样设计是因为,录入图书时,有两种情况:其一,图书馆购置了一批最新的书籍,馆中没有这种书,那么索书号必须要新分配,所以要输入索书号;其二,馆中已经有的书,最近又增购了一些,录入这些书籍时,就可以直接从列表中选择索书号了,我们的测试也分这两种情况进行。书籍的条码号不需要手动填写,数据库会自增生成。

    6.3.2 测试过程首先选择录入已经存在的书籍,从索书号列表中选择一个索书号,如下图所示,书名、作者等项会自动填充,且不可编辑,只有条码号和馆藏地点可以填写。

    填写好以后,点击录入,录入成功,结果如下图所示,最后一行是《兄弟》新录入的馆藏本,条码号为168。

    再测试录入馆中没有的书籍,我们录入一本计算机丛书《编译原理》,索书号为cs3,其他各项信息如下图所示。

    确定录入,录入成功,结果如下图所示,最后一行是刚录入的书籍。

    测试异常情况,不填写索书号直接录入,弹出窗口警告;不填写馆藏地点直接录入,也提示错误。
    6.4 管理员-读者查询6.4.1 测试说明读者信息查询可以根据读者编号、读者姓名的一部分或全部进行,但不能通过用户密码进行查询,因为涉及到密码的操作不太安全,实际上这里将用户密码直接显示也是不太好的,只不过我们认为管理员有一切权限,所以可以查看用户密码。
    6.4.2 测试过程读者查询维护界面初始化如下图所示,表中显示了所有的读者。

    根据读者姓名查询,在搜索框输入“张”,查询结果如下图所示。

    根据读者编号进行查询,结果如下图所示。

    查询异常情况,输入的关键字不匹配,查询结果为空,如下图所示。

    6.5 管理员-录入读者信息6.5.1 测试说明读者录入分为正常录入、读者编号重复异常、信息不全异常。
    6.5.2 测试过程录入一名读者,如下图所示。

    录入以后,在读者列表中可以看到刚刚录入的读者信息;将读者姓名、密码之中的任意一项空缺,点击录入,将提示信息填写不全
    6.6 管理员-修改读者信息6.6.1 测试说明管理员可以选择一条用户信息,选择修改。修改后点击确定,即可修改成功。不允许修改主码读者编号,因为该项是自增的,不可编辑,可以任意修改读者姓名和登录密码。
    6.6.2 测试过程选择读者“张三”,点击修改,弹出窗口如图 4 36所示。将读者姓名修改为“李四”,密码改为“lisi”,点击确定。

    6.7 管理员-注销用户6.7.1 测试说明管理员有权限删除任何一个用户,只是也要受一些限制。如果读者有借书还未归还,则不能删除;如果读者有罚金未交,则不能删除。只有读者与图书馆不存在利益关系时才可注销账户。
    6.7.2 测试过程选择3号用户蔡韬,点击删除,注销成功。
    6.8 管理员-查看报表统计报表的功能较为简单,如下图所示是借阅统计报表,可以选择开始时间和结束时间,统计该段时间内的总借阅申请、借阅成功、还书申请、还书成功数目。

    如下图所示是借阅排行榜,可以选择开始时间和结束时间,统计该段时间内,图书馆的书籍借出次数,降序排列,便于管理员掌握受欢迎的书籍种类。

    6.9 借书/还书综合测试6.9.1 测试说明由于读者的借书和管理员的借书审核、读者的还书和管理员的还书审核,互相之间是密不可分的,所以测试也不能孤立地进行,我们将读者和管理员的借书、还书操作混合交替进行,以达到测试借书、还书的目的。
    管理员审核读者的借出请求时,首先要判断读者在借册数是否超标,再判断是否有在借的书过期未还,最后判断是否有罚金还未交,以上三种情况都拒绝借书,否则审核通过,借书成功。
    借书测试计划是,先让一个用户连续申请借书4次,管理员进行审核,由于用户借书上限是3本,所以该用户的前三次请求均能通过,属于正常情况,第4次被拒绝,属于异常中的借书册数超标。然后读者申请还书,管理员很合还书时将该书鉴定为损坏,对读者开罚单,读者收到罚单后再次借书会失败,这是借书异常中的罚款未交异常。再将读者借书日期修改为超过1个月以前,这样读者再次借书也会失败,属于借书异常中的有书过期未还异常。
    6.9.2 测试过程读者请求借书,连续申请4次。在管理员一端可以看到读者“张鑫”的4次借书请求,如下图所示。

    管理员进行借书审核,读者借书成功;审核到第4本书时,系统检测到该读者已经借书3本,不可继续借书,所以弹窗警告,借书失败;紧接着,读者申请还书;管理员审核还书,管理员填写鉴定图书是否损坏,默认为正常,可以下拉选择损坏;选择损坏并点击确定,图书损坏需要罚款5元。
    由于该读者还书时被鉴定为损坏图书,所以他已经被取消了借阅资格,只有缴纳了罚金以后才会被取消限制,现在该读者再次尝试借书,管理员审核时检测到他有罚金未交,拒绝了借书请求。要恢复还书资格,读者必须缴纳罚款,读者成功缴纳5元罚金,重获借书资格并再次申请借书。管理员再次审核读者的借书请求,借书成功。
    最后一种异常情况,就是读者借书过期未还时,不可继续借书。我们设置的借书期限是一个月,考虑到测试时生成的借阅记录都是今天的,所以短时间内不会超过借书期限,为了完成测试,我们直接到SQL server中将借阅事件修改到两个月以前,这样一来,这条借阅记录就一定过期了。如下图所示,最后一条借阅记录时间为4月12日。

    该读者有书过期未还,现在再次申请借书,管理员审核借书信息时,检测到他有书过期未还,拒绝借书。读者将过期未还的书申请还书,管理员审核时,系统检测到该书过期,收取1元罚金,该读者被取消借书资格,只有缴纳罚金以后才会取消限制。
    6.9.3 结果分析以上测试过程涵盖了读者借书、读者还书、管理员审核借书、管理员审核还书。读者不管有没有借书资格,都是可以发出借书申请的,最终借书是否通过,在管理员一方决定。读者所借书籍不管是不是已经过期、是不是损坏,都是可以申请还书的,最终是否罚款,在管理员一方判断。所以说,读者借书、还书都没有异常情况。
    管理员审核借书,有三种异常情况:该读者已经有3本书在借未还;该读者有罚金未交;该读者有至少一本书过期未还。这三种情况在测试都进行了处理。
    管理员审核还书,有正常情况和两种异常情况。不论如何,都会弹出窗口要求管理员填写图书是否损坏,如果填写正常,那么直接审核通过;如果填写损坏,那么罚款5元;如果读者还书时已经超过借书期限,则罚款1元。在测试用例中上述情况都进行了测试。
    综上,读者、管理员的借书、还书综合测试成功,系统功能达到设计目标。
    6.10 读者-图书查询6.10.1 测试说明读者的图书查询与管理员稍有不同,管理员的查询是单条件查询,而为了使读者的使用体验更好,向读者提供了多条件查询。
    6.10.2 测试过程可以根据书名、作者或者出版社进行单项查找,不需要的条件直接不填即可。

    6.11 读者-查看借书记录6.11.1 测试过程如下图所示是该读者的借书记录,最后一列“在借”表示当前正在读者手中的书籍,“借阅失败”可能是因为读者有罚金未交等异常情况引起的,“已还”表示读者已经成功归还书籍。

    6.12 读者-查看基本信息6.12.1 测试过程如下图所示是当前读者的基本信息。

    6.13 读者-续借6.13.1 测试说明一本书籍在借,且为过期时,读者可以选择续借,续借成功后,借阅时间更新为当前时间,借阅期限重新计算。当书籍过期未还时不可续借,不是在借的书籍也不可续借。以下测试将对上述三种情况进行测试。
    6.13.2 测试过程当前读者的借阅记录如下图所示,有两本在借书籍,一本是4月12日借阅的,已经过期,另一本是6月13日借阅的,还未过期。

    选择续借6月13日借阅的书籍,如下图所示,续借成功。

    续借成功后,书籍的借阅时间进行了更新。选择续借4月12日借阅的书籍,系统检测到该书已过期,拒绝了续借。选择一条借阅失败的记录进行续借,系统提示该条信息不可续借。
    7 课程总结主要熟悉了SQL server的使用,学会了新增用户并设置用户权限;掌握了sql查询语句的多种用法以及较为复杂的查询逻辑的实现;掌握了触发器的简单使用;将数据库知识和实际结合,实现了一个功能比较完备的管理系统。
    实验过程中使用了MySQL和SQL server两个数据库,两者各有优劣,基本的操作都已经掌握,在以后的使用了可以灵活选择。只是对于命令行下操作数据库还不够熟悉。
    触发器的实现花费了较多时间,因为触发器的语句写法很灵活,而且Oracle、SQL server等不同数据库的触发器语法还大不相同。在编程的过程中发现,很多能够在高级语言中实现的功能,其实也可以在数据库中用触发器实现,两者对比,选择用触发器实现更好,可以减少编码量。
    在系统生成报表时,是用sql语句对多个表进行连接生成的,而没有使用视图,这方面还有待改进,用视图生成报表更加方便。
    软件功能学习部分的选做题没有完成,有时间还需要实现,加深对数据库的理解和操作的熟练程度。
    4 评论 38 下载 2019-03-14 10:30:10 下载需要15点积分
  • 基于JSP实现的课程资源管理系统网站

    一、系统需求1.1 用户信息管理
    用户:系统管理员、教师、学生
    登录:用户进行账号、密码等信息填写登陆后,教师、学生可以查看账号信息或进行课程、教学资源、作业管理等操作,系统管理员登录后可以行使增删账号的权限
    忘记密码:教师、学生填写学/工号和姓名,重置密码为学/工号后六位,系统管理员只允许后台操作重置密码
    修改密码:填写账号、当前密码、新密码

    1.2 课程管理规定每名教师可以教授多门课程,一门课程可以由多名老师授课,学生可以选修多门课程,每门课程可以被多名学生选择,课程名可以相同,但课程号唯一,对应特定的授课教师。
    1.3 教学资源的管理
    课件管理:教师每门课程只能有一个课件,每个课件可以有多个章节,教师可以上传/下载授课课程对应的课件。学生可以搜索、下载、在线查看其选修课程的课件
    作业管理:每门课程每个课时有相应的作业,教师可以发布作业要求、查看学生作业提交状态、下载学生的作业、对作业进行评分、给出批改意见并做统计分析。学生可以查看课程的作业要求,进行作业的提交,查看作业的批改情况

    1.4 教学信息发布老师可以发布其教授课程的学生成绩,或对学生的成绩进行修改。学生可以查询自己选修课程的成绩,并对教师进行教学评价。
    二、系统架构2.1 构架该系统采用表示层、业务逻辑层、数据访问层三层构架。
    在系统主页面,用户可以通过已有的账号密码进行登录,验证成功则进入个人信息页面;也可以进行忘记密码之后的重置操作,验证成功则完成重置并返回系统主页面再次登录
    在个人信息页面,用户可以修改当前账号密码,验证成功则完成修改则返回系统主页面。在此之外,不同身份的用户可以有不同的操作。

    管理员:查看现有帐号信息,对帐号进行增、删等操作
    教师:查看课程信息,包括预览、下载课件,查看作业情况(提交、批改意见、评分)等;修改课程信息,包括上传、重传课件,下载作业,提交作业批改意见、评分,发布新作业要求,更新系统公告等
    学生:查看课程信息,包括预览、下载课件,查看作业情况(提交、批改意见、评分)等;修改课程信息,包括上传、重传作业等

    2.2 系统流程
    表示层效果采用HTML5、CSS等语言和前端框架jQuery,实现用户交互界面。交互界面包括用户登录界面,个人信息展示页面,课程、课件、作业查看页面等
    业务逻辑层利用Servlet,JSP来处理来自前端的请求,获取数据库数据,并作出相应的处理,将处理数据提交到前端,显示给用户
    数据访问层利用Hibernate架构操作数据库,通过应用程序经过Hiberante持久层来访问数据库。数据访问层的关键是确定表结构和表属性,便于业务逻辑层进行对数据库的查询,良好的数据库结构,对数据操作有很大的用处

    2.3 系统结构
    三、数据库设计与构架3.1 E-R图
    3.2 物理设计admin(管理员账号信息表)



    adm_id
    password




    varchar
    varchar



    teacher(教师账号信息表)



    tea_id
    name
    password




    varchar
    varchar
    varchar



    student(学生信息表)



    stu_id
    name
    password




    varchar
    varchar
    varchar



    course(课程信息表)



    course_no
    title
    credit
    tea_id




    varchar
    varchar
    decimal(3,1)
    varchar



    stu_course(选课信息表)



    course_no
    stu_id
    grade
    tea_evaluation




    varchar
    varchar
    decimal(3,1)
    decimal(3,1)



    courseware(课件信息表)



    course_no
    file_title






    varchar
    varchar



    tea_homework(发布作业情况表)



    course_no
    homework_no




    varchar
    varchar



    stu_homework(提交作业评分表)



    course_no
    homework_no
    stu_id
    status
    grade
    opinion




    varchar
    varchar
    varchar
    bit
    decimal(3,1)
    varchar



    四、模块设计4.1 用户模块
    4.2 教学信息模块
    4.3 作业管理模块
    4.4 课件管理模块
    4 评论 121 下载 2018-11-06 12:56:48 下载需要5点积分
  • 基于JAVA的局域网聊天软件的设计与实现(仿制QQ)

    一、系统分析1.1 问题描述
    客户端

    实现简易版的局域网聊天器实现富文本内容聊天智能聊天机器人群发消息传送文件等功能
    服务器端

    实现群发通知管理聊天线程

    1.2 系统功能分析
    客户端功能

    登陆注册发送表情消息发送文本消息截取图片图片处理震动效果发送文件群发消息设置聊天文本样式
    服务器端

    广播通知

    1.3 开发平台及工具介绍
    Eclipse Mars2
    二、系统设计2.1 系统总体结构设计系统采用自己设计的网络消息传输协议,系统采用CS架构模式实现数据传送。


    2.2 系统各个类及类之间关系设计


    注:

    界面一般是继承了JFrame或JWindowJList、JTable所用的model和渲染器renderer都是自己重写的其余的一些比较琐碎的关系理起来比较复杂程序中的控件大多是自己自定义改写的
    2.3 数据存储的设计(文件等)
    采用键值对的方式存储账号密码
    截图默认保存在ScreenCut/+文件名.jpg
    用到了多种流操作,以及网络传输最关键的套接字操作

    2.4 界面设计
    自定义渲染和数据模型,实现JList、JTable的外交改变
    最长用的是在渲染器中继承JTable实现Renderer接口


    三、系统实现


    四、系统测试模块测试与系统测试:
    4.4 登陆测试
    4.5 注册测试
    4.6 表情测试
    4.7 震动测试震动效果无法截图!
    4.8 截图测试

    4.9 滤镜效果测试


    4.10 设置测试
    4.11 机器人聊天测试

    4.12 文件传输测试



    4.13 服务器管理界面测试

    五、总结通过这次的课程设计,可以说是开阔了自己的眼界,可以总结为以下几个方面:

    对JAVA体系的更深入的了解、对JAVA图像处理初步认识、对JAVA网络通信流的操作、流的套接更进一步深刻了解
    对网络通信的理解,CS、BS架构模式的了解
    对设计模式的初步认识与使用,线程管理这块单例模式的功能
    对JAVA的MVC模式的更深刻了解,层与层的分工明确,效率高,易管理,让人惊叹
    对线程的理解更深刻了,深谙UI主线程与处理耗时操作的子线程的逻辑处理关系
    对网络协议的初步了解,关于协议的定义了解,以及各种传送协议的效率比较有了大体。印象,Socket通信UDP和TCP通信机制初步了解
    对系统的架构设计有了初步认识,缓存机制,分布式系统等,虽然代码中还未实现,程序也并不是面向抽象编程和面向接口编程,代码低耦高聚效果一般,但仍然受益

    知识方面,在课程设计的任务中主要负责jlist jtable覆盖重写、基础类的继承重写、接口实现、界面设计与美化等。玩了半个假期后很多学过的知识都记不清楚了,所以打码的过程中经常翻书,让我又重温了知识;一部分知识书上没有,还需要上网查询或者找同学帮忙解决。有很多瓶颈时候,但坚持过去,看到一起完成的作品会有很大的满足感;其他方面:经过这次课程设计任务,我又一次认识到了团队合作的力量和重要性。一起讨论问题:苦恼过,失落过,兴奋过,到最后的成就感,让我成长,也对自己有了很大的信心。
    在这次课程设计,我们一起讨论要实现这个系统的哪些功能,把各自的想法说出来研究,我们还根据各自所学之长来分配工作,让我意识到在团队合作里每个人都能分享自己的想法、找到自己的位置发挥所长很重要,这样才能让我们更好地完成我们的工作。在完成我们的任务的过程中,我把每个功能逐步实现,比如在实现登录功能的时候,我会先把输入正确的账号和密码登录成功的功能实现,然后再实现判断输入的账号和密码是否一致,若不一致就返回重新输入账号密码这一功能,这让我在发现错误的时候更加容易找出并解决。在此过程虽然遇到许多困难,但是我都会去研究课本和课件里的例题或者上网去看教学视频,一步一步测试,自己实在无法解决了就去找同学帮助。
    经过这次课程设计,我对Java有了更深的了解,但这还远远不够,为了未来的发展,我必须更加努力地去学习更广更深的知识。
    3 评论 43 下载 2018-11-06 09:45:15 下载需要7点积分
  • 基于JAVA和MYSQL数据库实现的小型公司工资管理系统

    第一章 需求分析1.1 功能要求1.1.1 功能概况本次设计要求运用面向对象设计知识,利用 JAVA 语言设计实现一个“小型公司工资管理系统”。
    1.1.2 存储功能能够存储雇员的编号、姓名、性别、所在部门,级别,并进行工资的计算。 其中,雇员级别分为经理、技术人员、销售人员和销售经理。四类人员的月薪计算方法如下:经理拿固定月薪;技术人员按小时领取月薪;销售人员按其当月销售额的提成领取工资;销售经理既拿固定月薪也领取销售提成。由此要求,该项目需要利用数据库的关系表存储数据。
    1.1.3 添加功能程序能够任意添加上述四类人员的记录,可提供选择界面供用户选择所要添加的人员类别,要求员工的编号要唯一,如果添加了重复编号的记录时,则提示数据添加重复并取消添加。需要利用 Java 语言连接数据库,使用数据库添加语句。
    1.1.4 查询功能可根据编号、姓名等信息对已添加的记录进行查询,如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。利用 Java Swing 控件进行展示。
    1.1.5 编辑功能可根据查询结果对相应的记录进行修改,修改时注意编号的唯一性。
    1.1.6 删除功能主要实现对已添加的人员记录进行删除。如果当前系统中没有相应的人员记录, 则提示“记录为空!”并返回操作;否则,输入要删除的人员的编号或姓名,根据所输入的信息删除该人员记录,如果没有找到该人员信息,则提示相应的记录不存。
    1.1.7 统计功能能根据多种参数进行人员的统计。例如,统计四类人员数量以及总数,或者统计男、女员工的数量,或者统计平均工资、最高工资、最低工资等信息。利用数据库语句完成统计。
    1.1.8 界面功能利用 java 的 GUI 功能设计系统的图形用户界面,要求界面美观,易用。
    第二章 概要设计2.1 系统分析2.1.1 架构设计本系统采用架构如下图所示,主要分为三个模块:用户操作界面、身份认证中心和用户数据库。其中,用户操作界面为最顶层功能,便于用户选择以添加、修改、 删除、查询统计公司信息;身份认证中心便于鉴别不同用户,以实现映射到不同的数据库(表);用户数据库中保存用户个人存储的信息,同时实现最底层功能,即各项功能的基本操作。

    2.1.2 实体设计登陆实体作为程序的进入窗口,用户登陆时,系统会要求用户输入账号和密码,并在数据库中进行匹配分析,若用户名存在且密码正确则通过身份认证,同时映射到用户 个人的数据表中,不同用户对应不同数据表存储相关信息。
    主界面实体登录成功后的功能选择界面,包含添加、查询、显示、统计四个功能,其中,对于查询或显示的信息可直接选择并完成修改删除功能。
    添加功能实体从主界面中选择进入,负责接收用户输入的员工信息,判断员工编号是否重复、录入的员工信息格式是否正确,并将符合要求的数据项其上传至数据库,完成添加员工信息的操作。
    查询功能实体从主界面中选择进入,按照用户选择的查找方式和具体查找要求,从数据库中筛选符合条件的信息并以表格形式显示,如果未查询到相关信息会给以提示。
    修改功能实体从查询功能实体进入。查询结果会以表格的形式显示在用户面前,用户可以双击某项查询结果进入编辑界面完成修改功能,同添加功能类似,系统会判断用户修改的编号是否已经重复、修改的信息是否格式正确,并将符合要求的信息在数据 库中完成更新修改操作。
    删除功能实体从查询功能实体进入。查询结果会以表格的形式显示在用户面前,用户可以双击某项查询结果进入编辑界面,在编辑界面中可选择删除此信息,删除完成后将会予以反馈。
    统计功能实体自动统计以下内容:公司整体信息(职位分布、部门人数分布等)、各部门详细信息(男女比例、工资情况、年龄情况、职位分部等),并可由用户自行选取具体部门、具体级别并显示统计结果,所有统计结果均自动绘图显示。

    2.1.3 分层设计数据库驱动层(数据层)数据库驱动层为最底层,主要以各种 JDBC 数据库驱动语句以及各种算法组成,完成添加、修改、删除、查询、统计分析的基本功能,并完成添加修改过程中的编号查重、格式判断等异常判断。各功能成功或失败情况将传递给上层,同时,异常情况也将分类传递给上层。
    异常处理层(功能层)主要分类处理数据库反馈的结果,例如查询成功失败、添加的编号重复、修改成功等操作的反馈结果。并处理来自底层抛出的异常,捕获后生成提示信息传递给上一层。
    用户界面层(表示层)接受来自异常处理层的处理结果:对于异常,采用消息框提示的方式展示给用户;对于查询结果,以表格的形式显示在界面上;对于统计结果,自动绘制图表显示给用户;其他提示信息同样采用消息框给用户反馈。同时用户可以直接在界面上选择相应功能,底层会自动实现相应操作并反馈给用户界面层。

    2.2 程序流程2.2.1 系统流程图
    2.2.2 调用关系运行程序后,首先进入用户登陆界面,用户名与密码不匹配则登陆失败,成功则进入用户操作主界面。
    在用户操作主界面中有四个按钮供用户选择,分别是:添加记录、查询记录、显示信息、统计整理,点击不同按钮跳转至不同功能实现界面。
    添加信息模块允许用户添加新信息,系统会判断编号是否重复、各式是否正确。若通过审核则将此信息添加至数据库中,询问用户是否继续添加。如果退出则重新返回主界面。
    查询信息模块允许用户按个人需求查询相关信息,如:职员编号、姓名、性别、级别、部门等。查询得到的信息会显示在表格中,用户可以点击表格中具体某一项选择编辑信息,在编辑模块中可以修改或删除选中的信息。
    显示信息模块与查询功能类似,显示的内容会自动放入表格中同时允许编辑修改。 统计整理模块会将统计得到的信息以图表形式显示给用户,同时允许用户自行查询想要统计的信息并自动绘制图表。
    第三章 详细设计3.1 功能类定义与实现3.1.1 常量与参数的定义(Parameter 类)JDBC 数据库连接所用参数与端口JDBC(Java Data Base Connectivity,java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数据库提供统一访问,它由一组用 Java 语言编写的类和接口组成。JDBC 为数据库开发人员提供了一个标准的 API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序,并且可跨平台运行,并且不受数据库供应商的限制。
    本系统采用的是MySQL数据库,编程语言为Java语言,编译器为Eclipse Oxygen,Java连接数据库时需要用到JDBC驱动器、数据库URL以及数据库管理员账号密码等。
    根据数据库的 URL、用户名和密码,创建一个 JDBC Connection 对象。如: Connection connection = DriverManager.geiConnection(“连接数据库的 URL”, “ 用户名”, “密码”)。其中,URL=协议名+IP 地址(域名)+端口+数据库名称;用户名 和密码是指登录数据库时所使用的用户名和密码。示例创建 MySQL 的数据库连接代码如下:
    Connection connectMySQL = DriverManager.geiConnection("jdbc:mysql://localhost:3306/myuser","root" ,"root"); public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; public static final String DB_URL = "jdbc:mysql://localhost:3306/java?useSSL=true&characterEncoding=UTF8"; public static final String ACC = "root"; public static final String PWD = "zxczxc";
    职员级别对应代号本系统中将职员级别分为四种:经理、技术人员、销售人员、销售经理,其中经理拿固定月薪;技术人员按小时领取月薪;销售人员按其当月销售额的提成领取工资;销售经理既拿固定月薪也领取销售提成。若想方便统计需要将对应职位转换成相应的代号。此处经理对应 int 型数字 1,技术人员对应 2,销售人员对应 3,销售经理对应 4.具体如下:
    public static final int Manager = 1; //经理 public static final int Engineer = 2; //技术人员 public static final int Salesman = 3; //销售人员 public static final int SalesManager = 4; //销售经理
    工资自动计算所需常量由于经理拿固定月薪;技术人员按小时领取月薪;销售人员按其当月销售额的提成领取工资;销售经理既拿固定月薪也领取销售提成。若想方便计算工资,必须提前订好各种常量,如:固定的月薪、工作每小时的工资、销售额提成比例等,具体如下:
    public static final int BASE = 5000; //底薪 public static final int HOUR = 80; //每小时工资 public static final double Parameter = 0.015; //提成比例
    3.1.2 职工个人信息的定义(Person 类)职工个人信息职工个人信息包括:职工编号(唯一)、姓名、性别、年龄、电话号码、所属部 门、工作级别、月工作时间、月销售总额、月工资。其中月工资不可显式输入,自动由程序结算得到。通过构造函数直接创建对象,具体如下:
    public Person(String ID,String name,String sex,int age,String phone, String department,int kind,int hours,double sells) { this.ID = ID; this.name = name; this.sex = sex; this.age = age; this.phone = phone;this.department = department; this.kind = kind; this.hours = hours; this.sells = sells;}
    通过此方法得到私有成员变量:
    public String getID() { return ID; }
    职工工资计算方法经理拿固定月薪;技术人员按小时领取月薪;销售人员按其当月销售额的提成领取工资;销售经理既拿固定月薪也领取销售提成。具体计算方法如下:
    switch (kind) { case 1: this.salary = Parameter.BASE; break; case 2: this.salary = Parameter.HOUR*hours; break; case 3: this.salary = Parameter.Parameter*sells; break; case 4: this.salary = Parameter.BASE + Parameter.Parameter*sells; break; default: return; }
    3.1.3 数据库查询与底层算法(JDBC 类)JDBC 连接数据库在开发环境中加载指定数据库的驱动程序。使用的数据库是MySQL,所以需要下载MySQL支持JDBC的驱动程序(mysql-connector-java-5.1.18-bin.jar);而开发环境是Eclipse,将下载得到的驱动程序加载进开发环境中。
    在Java程序中加载驱动程序。在Java程序中,可以通过 “Class.forName(“指定数据库的驱动程序”)” 方式来加载添加到开发环境中的驱动程序,例如加载MySQL的数据驱动程序的代码为:
    Class.forName(“com.mysql.jdbc.Driver”);
    创建数据连接对象:通过DriverManager类创建数据库连接对象Connection。DriverManager类作用于Java程序和JDBC驱动程序之间,用于检查所加载的驱动程序是否可以建立连接,然后通过它的getConnection方法,根据数据库的URL、用户名和密码,创建一个JDBC Connection 对象。如:
    Connection connection = DriverManager.geiConnection(“连接数据库的URL", "用户名", "密码”)
    其中,URL=协议名+IP地址(域名)+端口+数据库名称;用户名和密码是指登录数据库时所使用的用户名和密码。
    创建Statement对象:Statement 类的主要是用于执行静态 SQL 语句并返 回它所生成结果的对象。通过Connection 对象的 createStatement()方法可以创建一个Statement对象。例如:
    Statement statament = connection.createStatement();
    具体示例创建Statement对象代码如下:
    Statement statamentMySQL =connectMySQL.createStatement();
    调用Statement对象的相关方法执行相对应的 SQL 语句:通过execuUpdate() 方法用来数据的更新,包括插入和删除等操作,例如向staff表中插入一条数据的代码:
    statement.excuteUpdate("INSERT INTO staff(name, age, sex,address, depart, worklen,wage)" + " VALUES ('Tom1', 321, 'M', 'china','Personnel','3','3000' ) ");
    通过调用Statement对象的executeQuery()方法进行数据的查询,而查询结果会得到 ResulSet对象,ResulSet表示执行查询数据库后返回的数据的集合,ResulSet对象 具有可以指向当前数据行的指针。通过该对象的next()方法,使得指针指向下一行,然后将数据以列号或者字段名取出。如果当next()方法返回null,则表示下一行中没有数据存在。使用示例代码如下:
    ResultSet resultSel = statement.executeQuery( "select * from staff" );
    关闭数据库连接:使用完数据库或者不需要访问数据库时,通过Connection的 close() 方法及时关闭数据连接。
    身份认证对于用户,需要先要求输入账号密码,并将账号密码传入数据库身份鉴别表进行匹配,若用户名密码均匹配成功,则映射到用户创建的表中。传入参数为账号和密码,返回判断情况:返回1为账号不存在、返回2为密码不正确、返回3为出现数据库连接异常、返回0则认证成功。
    public static int LoginCharge(String acc,String pwd) { try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); String query = "select * from `" + Parameter.COMPANY + "` where acc=\"" + acc + "\""; ResultSet rs = stat.executeQuery(query); if (!rs.next()) return 1;//账号不存在 String pwd2 = rs.getString("pwd"); if(!pwd2.equals(pwd)) return 2;//密码不正确 String table = rs.getString("table"); Parameter.TABLE = table; return 0; }catch (Exception e) { e.printStackTrace(); return 3; }
    插入信息模块中,需要判断插入的编号是否重复,如果重复则不允许插入,函数 rs.next()如果返回结果不为空,则说明已经存在此编号。输入信息为Person对象,返回判断结果:返回1为编号已存在,返回2为数据库连接异常,返回0为插入成功,具体如下:
    public static int insertIntoSql(Person p) { try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); // 判断是否已经存在编号 String query1 = "select * from `" + Parameter.TABLE + "` where no=\"" + p.getID() + "\""; ResultSet rs = stat.executeQuery(query1); if (rs.next()) { return 1; } String query = "INSERT INTO `" + Parameter.TABLE + "` VALUES (\"" + p.getID() + "\",\"" + p.getName() + "\",\"" + p.getSex() + "\",\"" + p.getAge() + "\",\"" + p.getPhone() + "\",\"" + p.getDep() + "\",\"" + p.getKind() + "\",\"" + p.getHours() + "\",\"" + p.getSells() + "\",\"" + p.getSalary() + "\")"; stat.executeUpdate(query); return 0; } catch (Exception expt) { return 2; } }
    从数据库中删除信息删除信息模块中,需要删除的编号是否存在,如果不存在则不允许删除,函数 rs.next()如果返回结果为空,则说明此编号对应的职员不存在。输入信息为职员的 编号ID,返回判断结果:返回1为编号不存在,返回2为数据库连接异常,返回0为插 入成功,具体如下:
    public static int deleteFromsql(String id) { try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); String query1 = "select * from `" + Parameter.TABLE + "` where no=\"" + id + "\""; ResultSet rs = stat.executeQuery(query1); if (!rs.next()) { return 1; } String query2 = "delete from `" + Parameter.TABLE + "` where no=\"" + id + "\""; stat.executeUpdate(query2); return 0; } catch (Exception expt) { return 2; } }
    从数据库中查询信息查询信息模块中,具体分为按照ID查询和按照其他条件查询,具体差别为ID唯一,至多只能查找到一条信息,而按照其他条件查询可能会返回多条信息,因此需要区 别处理,输入信息为职员的信息,返回值为查询结果,为空则查询失败具体如下:
    public static String searchByID(String id) {//按照ID查询 try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); String query1 = "select * from `" + Parameter.TABLE + "` where no=\"" + id + "\""; ResultSet rs = stat.executeQuery(query1); if (!rs.next()) { return null; } String name = rs.getString("name"); String sex = rs.getString("sex"); int age = rs.getInt("age"); String phone = rs.getString("phone"); String department = rs.getString("department"); int kind = rs.getInt("kind"); int hours = rs.getInt("hours"); double sells = rs.getDouble("sales"); double salary = rs.getDouble("salary"); String result = id + "@" + name + "@" + sex + "@" + age + "@" + phone + "@" + department + "@" + kind + "@" + hours + "@" + sells + "@" + salary; // 生成日志 File f = new File("log.txt"); if (!f.exists()) f.createNewFile(); PrintStream ps = new PrintStream(new FileOutputStream(f)); ps.println(result); ps.close(); return result; } catch (Exception expt) { return "Fail"; } } public static String searchByOthers(String chosen, String others) { //按照其他条件查询,chosen为条件,others为具体筛选内容 try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); String query; if (chosen.equals("age") || chosen.equals("kind")) query = "select * from `" + Parameter.TABLE + "` where " + chosen + "=\"" + Integer.parseInt(others) + "\""; else query = "select * from `" + Parameter.TABLE + "` where " + chosen + "=\"" + others + "\""; ResultSet rs = stat.executeQuery(query); if (!rs.next()) { return null; } String id = rs.getString("no"); String name = rs.getString("name"); String sex = rs.getString("sex"); int age = rs.getInt("age"); String phone = rs.getString("phone"); String department = rs.getString("department"); int kind = rs.getInt("kind"); int hours = rs.getInt("hours"); double sells = rs.getDouble("sales"); double salary = rs.getDouble("salary"); String result = id + "@" + name + "@" + sex + "@" + age + "@" + phone + "@" + department + "@" + kind + "@" + hours + "@" + sells + "@" + salary; while (rs.next()) { id = rs.getString("no"); sex = rs.getString("sex"); name = rs.getString("name"); age = rs.getInt("age"); phone = rs.getString("phone"); department = rs.getString("department"); kind = rs.getInt("kind"); hours = rs.getInt("hours"); sells = rs.getDouble("sales"); salary = rs.getDouble("salary"); result += "#" + id + "@" + name + "@" + sex + "@" + age + "@" + phone + "@" + department + "@" + kind + "@" + hours + "@" + sells + "@" + salary; } } catch (Exception expt) { expt.printStackTrace(); return "Fail"; } }
    从数据库中更新信息编辑信息模块中,如果需要修改信息,则需要启用更新操作:先判断是否修改了编号,如果修改编号则需要判断修改后的编号是否重复,如果重复则不允许修改为此编号。输入修改前的Person对象和修改后的Person对象,如果修改失败则回退操作,即把原来的Person对象恢复,具体实现如下:
    public static int UpdateFromsql(Person newP, Person oldP) { try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); if (deleteFromsql(oldP.getID()) != 0) { return 1; } String query1 = "select * from `" + Parameter.TABLE + "` where no=\"" + newP.getID() + "\""; ResultSet rs = stat.executeQuery(query1); if (rs.next()) { if (insertIntoSql(oldP) != 0) JOptionPane.showMessageDialog(null, "发生未知错误"); return 2; } if (insertIntoSql(newP) != 0) { if (insertIntoSql(oldP) != 0) JOptionPane.showMessageDialog(null, "发生未知错误"); return 3; } return 0; } catch (Exception expt) { if (insertIntoSql(oldP) != 0) JOptionPane.showMessageDialog(null, "发生未知错误"); return 4; } }
    从数据库中统计整理信息统计整理模块功能较为复杂,但实现方法大体类似,根据具体的查询条件和查询内容查询相关的信息,并返回结果,具体实现如下:
    统计数量
    public static int statisticCount(String option) { try { Class.forName(Parameter.JDBC_DRIVER); Connection conn = DriverManager.getConnection(Parameter.DB_URL, Parameter.ACC, Parameter.PWD); Statement stat = conn.createStatement(); String query = "select count(*) from `" + Parameter.TABLE + "` "+option; ResultSet rs = stat.executeQuery(query); if (!rs.next()||rs.getString(1)==null) { return 0; } int result = Integer.parseInt(rs.getString(1)); return result; } catch (Exception expt) { JOptionPane.showMessageDialog(null, "发生未知错误"); return 0; } }
    统计不同职位的人数
    public static int statisticKindCount(int kind, String option1, String option2)
    统计不同性别的人数
    public static int statisticSexCount(String sex, String option1, String option2)
    统计最高、最低、平均工资
    public static double statisticAvgSalary(String option1, String option2) public static double statisticMaxSalary(String option1, String option2) public static double statisticMinSalary(String option1, String option2)
    统计最大、最小、平均年龄
    public static double statisticAvgAge(String option1, String option2) public static int statisticMaxAge(String option1, String option2) public static int statisticMinAge(String option1, String option2)
    3.2 图形界面类定义与实现3.2.1 JFreeChart 制图(JFreeChart 类)柱形图制作传入图表的名称(标题)、Dataset 容器(存放图形参数)、以及所要绘制图形的颜色,返回绘制的 Chart 图形。
    public class CategoryChart { public static JFreeChart createChart(String name, CategoryDataset dataset,Color color) { JFreeChart chart = ChartFactory.createBarChart3D(name, null, null, dataset, PlotOrientation.VERTICAL, true, false, false); CategoryPlot plot = chart.getCategoryPlot();// 设置图的高级 属性 BarRenderer3D renderer = new BarRenderer3D();// 3D 属性修改 plot.setNoDataMessage("无 信 息"); renderer.setSeriesPaint(0,color); //设置柱的颜色 // 设置网格竖线颜色 plot.setDomainGridlinePaint(Color.gray); plot.setDomainGridlinesVisible(true); // 设置网格横线颜色 plot.setRangeGridlinePaint(Color.gray); plot.setRangeGridlinesVisible(true); // 图片背景色 plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setOutlineVisible(true); // 设置墙体颜色 renderer.setWallPaint(Color.gray); // 对 X 轴做操作 CategoryAxis domainAxis = plot.getDomainAxis(); // 对 Y 轴做操作 ValueAxis rAxis = plot.getRangeAxis(); renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setBaseItemLabelsVisible(true); renderer.setBaseItemLabelFont(new Font("黑体", Font.CENTER_BASELINE, 12), true); renderer.setBasePositiveItemLabelPosition( new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.CENTER_LEFT)); renderer.setItemLabelAnchorOffset(15); //设置距离图片左端距离 domainAxis.setUpperMargin(0.2); //设置距离图片右端距离 domainAxis.setLowerMargin(0.2); //设置柱的透明度 plot.setForegroundAlpha(0.6f); // 最后还得将 renderer 放到 plot 中 plot.setRenderer(renderer);// 将修改后的属性值保存到图中 return chart; } }
    饼图制作传入图表的名称(标题)、Dataset 容器(存放图形参数),饼图颜色自动分配,返回绘制的 Chart 图形。
    public class PieChart { public static JFreeChart createChart(String name,PieDataset piedataset) { JFreeChart jfreechart = ChartFactory.createPieChart3D(name, piedataset, true, true, false); PiePlot3D pieplot3d = (PiePlot3D) jfreechart.getPlot(); pieplot3d.setNoDataMessage("无 信 息"); pieplot3d.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{1}({2})"));//设置标签显示的格式 pieplot3d.setSectionOutlinesVisible(false); pieplot3d.setLabelBackgroundPaint(new Color(220, 220, 220));//设置标签的背景颜色。 //设置旋转角度 pieplot3d.setStartAngle(180.0); //设置旋转方向,Rotation.CLOCKWISE)为顺时针 pieplot3d.setDirection(Rotation.CLOCKWISE); //设置图表透明图 0.0~1.0 范围。0.0 为完全透明,1.0 为完全不透明 pieplot3d.setForegroundAlpha(0.9F); return jfreechart; } }
    3.2.2 Dataset 容器(JFreeChart 制图所需容器)柱形图数据集主要包括年龄统计的数据集和工资统计的数据集,对于年龄和工资,本系统统计最大值、平均值和最小值,对于这三项数据,采用柱形图绘制比较合适。代码见附录。

    饼图数据集主要包括性别比例统计的数据集和不同部门、级别人数分布统计的数据集,对于年龄比例和人数比例,本系统绘制饼图直观的展现不同种类人数所占比例的大小。代码见附录

    3.2.3 界面设计与制作(JFrame 继承子类)主要包括登陆界面、主界面、插入信息界面、查询信息界面、编辑界面(修 改删除查询详情)、显示信息界面(表格显示)、统计整理界面(自动制作柱形图、 饼图),详情见第五章。 设计界面主要使用 Java Swing 和 Java AWT,采用框架 Java BeautyEye,同 时采用事件处理等接口完成图形界面设计,做到良好的美观性以及实用性、易用性。便于用户操作。
    3.3 函数调用关系图
    程序由 LoginFrame()进入,登陆成功进入 MainFrame(),Mainframe 可以选择进入 InsertFrame、QueryFrame 和 StatisticFrame,其中 QueryFrame 调用 Delete 和 Update 函数,Statistic 调用 HandleDate、JFreeChart 和 JDBC 函数完成统计并自动将数据可视化。
    第四章 测试结果4.1 登陆界面


    4.2 程序主界面如果登陆失败,如账号不存在或密码错误,则会给以相应提示,登陆成功则跳转至程序主界面。

    4.3 添加信息界面
    如果编号重复、添加内容格式不正确,则会有一定提示:


    4.4 查询信息界面查询界面打开后默认显示全部记录,以表格形式显示

    共有五种查询方式可选择:

    在此处我们选择查询部门为技术部的所有职员,其他类似不做重复测试。可以看到表格刷新,显示出符合条件的所有记录:

    4.5 编辑信息界面在查询界面点击每条查询结果的最右侧按钮可进入编辑界面,可以修改、删除、查询详细信息

    4.6 统计整理界面



    6 评论 130 下载 2018-11-05 11:25:51 下载需要8点积分
  • 基于JSP和SSH框架实现的物流管理系统

    1 任务概述1.1 目标该项目软件的开发是为了提高物流公司的业务效率,降低人力、物理的损耗,使管理和业务操作更方便、科学。
    本软件系统一旦实施应用,公司的各项信息都可以更安全可靠的保存、查看,在业务实施过程中,可以大大的降低出错率,同时节省大量的时间和金钱,为公司赚的更多的利润。
    1.2 用户的特点
    超级管理员:拥有最大权限,可以为系统分配用户的权限,进行各项了解
    员工管理员:由超级管理员分配权限,管理公司的所有员工
    总公司配送点管理员:由超级管理员分配权限,管理公司的所有配送点
    配送点管理员:由超级管理员分配权限,管理配送点的各项事务。 其下由车辆、订单、线路、报表管理员


    1.3 运行环境软件环境




    名称
    版本
    语种




    操作系统
    Windows
    2003



    操作系统的附加功能





    数据库平台
    Oracle
    9.2i



    应用平台
    任意操作系统




    邮件系统
    pop
    3.0



    客户端软件
    IE
    7.0或6.0




    1.4 需求规定本系统是提供物流公司的日常事务管理,主要有管理用户、员工、车辆、线路、配送点、订单、报表等业务。还为客户提供在线查询等功能。
    1.4.1 系统功能层次模块图
    1.4.2.1 员工管理
    功能描述:由总公司统一管理公司员工,主要的功能有增加员工,员工信息修改,员工信息删除,员工信息查询
    增加员工:当公司有新员工入职,则新建员工信息
    员工信息修改:当员工信息变更的时候进行修改,如职位变动,工资变动等
    员工信息删除:当有员工离职的时候,删除该员工信息
    员工信息查询:供员工管理员方便管理员工


    1.4.2.2 用户管理
    功能描述:由超级管理员对用户分配不同的权限,权限包括:配送点管理员,配送点操作员
    分配权限:当新增配送点时为该配送点分配一个配送点管理员,再由该配送点管理员分配配送点操作员权限
    删除用户:当配送点用户发生变更时,根据需要删除对应的用户信息
    查询:由上级管理员查询由他分配的下级管理员的信息


    1.4.2.3 车辆管理功能描述:管理配送点拥有的所有车辆,包括新购车辆登记,车辆调度,车辆的状态记录及查询

    新购车辆登记:登记新购车辆的基本信息
    车辆调度:根据车辆的具体信息(状态,吨位,容积等)进行调度
    车辆的状态:车辆现在处于空闲,途中,维修中
    车辆查询:配送点操作员查看现有车辆的具体信息


    1.4.2.4 配送点管理功能描述:由总公司新增配送点,查看配送点信息,修改配送点信息,删除配送点

    新增配送点:当公司根据业务需求需要扩展配送规模,新开设配送点并添加配送点信息
    查看配送点信息:为了方便公司管理,随时了解配送点具体信息
    修改配送点信息:如配送点信息有变更,则修改配送点信息
    删除配送点:根据公司业务需求删除配送点
    配送价格管理:配送点根据自己的配送范围制定配送价格


    1.4.2.5 线路管理功能描述:由总公司进行线路的添加,删除和查询

    线路添加:在现有的配送点范围内,添加新线路
    线路删除;如配送点有变动,则删除该线路
    线路查询:配送点操作员调度车辆需查询线路,管理员维护线路信息,客户查看线路


    1.7.2.6 订单管理接受订单模块,订单状态修改模块,订单删除模块,生成交接单模块,以及查询订单。

    接受订单:接受用户所填写的订单输入到系统中
    订单状态维护:配送点管理员对所有的订单都应该进行审查和批复。而且应该维护订单的各种状态,包括:接受、在途(在哪个点)、在配送中、客户已收、等待支付等
    订单删除:当订单生成后,根据具体的信息或者特殊的信息,管理员来删除删除订单
    生成交接单:当货物发货时,生成交接单,当货物运送到某个配送点的时候,检查完货物,司机应该与该配送点的管理员来填写交接单,以保证货物能在各个段内安全的配送
    查询订单:订单管理员查询当日订单,当月订单,按订单号查询


    1.4.2.7 客户端
    货物状态查询:根据订单号查询货物状态
    价格查询:根据货物的重量,体积,目的地查询配送价格
    网点查询:查看配送点的配送范围和配送价格等


    2 设计思想2.1 系统构思
    2.2 运用关键技术本系统运用的是SSH所搭建成的框架,并且在局部的地方用到了Ajax技术和DWR框架,并且前台用的是Div+Css技术所搭建成的。
    2.3 数据结构Car表

    Carstate表

    Cartype表

    City表

    Deliveryspot表

    Employee表

    Line表

    Linetaile表

    Order表

    Orderstate表

    Position表

    Power表

    Province表

    Receipt表

    Receiptdetaile表

    Use表

    3 服务器端的安装及运行3.1 程序的运行环境
    要求操作系统为windows 操作系统
    对计算机硬件配置要求较高,至少要1GB内存
    服务器程序为tomcat
    数据库为oracle 9i
    要求安装有JDK 1.5

    3.2 程序的安装
    安装JDK 1.5 并且配置其环境变量
    安装tomcat服务器
    将获取的程序war包放入tomcat安装目录下的webapps文件夹下
    安装oracle服务器,并且将程序的数据库脚本导入
    启动tomcat服务器

    4 功能演示配送点管理

    员工管理


    用户管理

    线路管理


    车辆管理



    报表管理

    订单管理


    交接单管理

    投递单管理
    2 评论 46 下载 2018-11-05 18:37:42 下载需要13点积分
  • 基于QT实现的日历程序

    1 概要1.1 简介本篇设计文档主要讲述了计52班的吴启凌根据小学期第一周李国良老师所教的内容,来实现的程序Calendar的设计思路,架构,以及一些设计细节。
    1.2 实现的功能Calendar实现了日历的基本功能以及一些附加功能,主要有

    正确地按照公历显示日历。
    能够添加、删除、修改事件序列,某个事件在设置时,能够按天,按周,按月重复发生;删除事件时,能删除可重复事件的单个或全部。
    能够设置每一天的颜色。
    能够与本地文件实现拖拽交互。当用户把文件拖到某一天上时,能够保存到Calendar所在的目录下,并在当天格子内显示文件名。双击某一天能够打开一个对话框,其中显示了该天上的所有文件,并且能够拖拽到本地保存。此外,还设计了一个按钮来打开和关闭拖拽交互。
    能够使用配置文件,包括XML和ini文件来保存信息。其中,XML用于保存事件和每天的颜色,ini用于保存语言,是否打开拖拽交互的信息。信息能够通过save按钮保存,也可在关闭程序时自动保存。支持导入,导出XML文件。
    可以对日历进行整体拖拽,并设置了一个按钮来固定、解锁界面,锁定后,日历不再响应鼠标动作,并且能将鼠标事件传递到桌面。
    国际化:支持中文、英文两种模式。

    2 系统架构2.1 文件结构Calendar的代码根据界面分组,文件如下
    Mycalendar构建了日历的样式及其交互模式,Filesdialog和Listwidget用于显示日期所储存的文件,以及提供拖拽功能,Scheduledialog用于新建及编辑事件,Schedule类用于储存事件,Schedulemanager用于管理事件,而Mainwindow则作为各组件沟通的纽带。

    2.2 组件分析Schedule类用于储存事件的描述,开始、结束日期、重复模式等信息。Schedulemanager提供了对Schedule管理的接口,包括添加、编辑、删除事件,获取某天的事件列表或单个事件,以及获取全部事件。

    Scheduledialog用于向用户显示事件的描述、重复模式信息,同时接受用户的编辑。
    Listwidget重写了QListWidget的mousePressEvent事件处理函数,在用户对列表中的文件按下鼠标时,传递文件路径的信息。
    Mycalendar则是工程中较为重要的一个类,重写了父类的dragEnterEvent和dropEvent来处理鼠标拖入事件,并在鼠标拖入文件时,将文件复制到Calendar所在目录下,并显示在日期格子中。重写了paintCell来获取每个日期的外框的位置信息,以此来判断鼠标将文件拖到了哪一天内;以及在日期中显示文件名,设置日期颜色。重写了resizeEvent来重置datepos中储存的矩形信息,以免造成拖拽的误差。

    Mainwindow则是工程中的核心类,用于收集、处理、传递几乎所有的信息。三个public slots用于在三个事件按钮按下时,弹出窗口并收集事件信息;on_calendar_clicked用于在鼠标点击calendar时,在列表框中刷新事件信息,以及在colorbox,即颜色选择框内显示该天的颜色信息;on_actionLock_triggered在lock按钮按下时,固定窗口并设置鼠标穿透;on_checkBox_toggled用于读取是否开启文件拖拽按钮的信息;on_languageBox_currentTextChanged用于设置语言;最后三个槽用于保存配置信息、导入XML、导出XML。

    3 用户界面3.1 主界面界面如下图1所示,左半边区域为日历部分,中间为功能按钮,右边为事件显示区域。此外工具栏中为lock按钮,菜单栏中Calendar可以弹出下拉菜单。
    如图2,3,点击某天后,右侧列表框中会显示当天事件,用户可以点击New按钮来新建事件,或者可以点击列表框中的条目,再点击Edit或Delete按钮来编辑或删除事件,删除时,会出现确认对话框,三个选项分别对应删除单个事件、全部事件、取消删除。
    在color标签下方的下拉框中,可以设置某天的颜色。
    Language下拉框可以设置语言,设置后需要重启才能生效。需要重新设置一下翻译文件加载的路径。
    Enable drag的复选框能够开启、关闭文件拖拽功能。
    按lock按钮能够锁定日历,由于锁定后鼠标穿透,需要用快键键Ctrl + L来解锁。
    在Calendar的下拉菜单栏中,save能够保存设置,import XML能导入事件、日期颜色设置,export XML能够导出事件、日期颜色设置。
    0 评论 1 下载 2019-06-23 18:06:52 下载需要10点积分
  • 基于Android实现的减肥塑身平台APP

    摘要人们日益关注自身健康与美,好的身材更是所有人追求的目标,但塑造完美的身材塑造非易,对于体型肥胖的人来说更是难上加难。虽然目前国内有微信运动,跟我练腹肌等应用,但是这些应用缺乏个性化。论文以减肥健身为目的,根据健身者特点与健身过程成效,开发自适应的塑型系统。论文采用JAVA语言 ,MySQL数据库, Tomcat服务器 ,设计并实现制定自适应计划,摄入支出热量查询,身材变化,一分钟了解自己等功能。希望通过该平台让每一个都能实现减肥瘦身,提升自己的身体素质。
    关键词:减肥塑身,Android ,JAVA,MySQL ,tomcat
    ABSTRACTNowadays, people pay attention to health and beauty day by day. A good figure is the pursuit and goal of all people. However, it is not easy to shape a perfect figure for normal people. To shape a perfect figure is extremely difficult. Although there are APPs like WeChat Sports, Follow Me to Exercise the Abs and so on, most of those APPs lack individuality. This thesis takes weight loss and body building as goals and develops a self-adapting body building system according to body builders’ features and body building effects in the process. The thesis adopts JAVA language, MySQL database and Tomcat server to design and realize the functions of formulating self-adapting plan, query of intake and consumed heat, figure changes, knowing yourself in a minute and so on. It is expected that through this platform,every person can realize weight loss and body building, thus improving physical fitness.
    Key words: loss weight, plan , Android ,Java
    第一章 绪论第一节 背景和意义通过一套 “ 以计划为引导,明确目标;以直观的训练变化趋势,树立信心;以摄入支出平衡体系,科学减肥塑形[1] ”。但我的口诉和文章的宣传范围有限,所以我决定设计一款 基于 Android 的减肥塑身平台,让更多的用户能够通过我的方法科学健康快乐瘦身。
    随着移动移动互联网的发展,根据中国互联网络信息中心(CNNIC)发布的数据显示,仅仅中国网民就已经达到6.68亿,而手机网民规模就达到5.94亿[2]。而Android 做为使用人数最多移动开发平台,且随着android material design 全新的设计体验[3],用户体验度不断的提升,Android 将会更进一步占领市场份额[4]。
    目前在国内外,减肥健身软件发展已久,在这些数不胜数的软件中无非都是围绕着,教你减肥是什么,为什么要减肥,怎么才能减肥。随着信息技术时代飞快的发展,获取这些信息的手段已经不是难事了,人们懂得这些道理,却无法坚持下来。我认为,一个减肥健身应用做得再好,用户无法坚持也是白白浪费时间,如果能让用户坚持锻炼,并配合使用优秀的减肥健身软件,那么减肥健身将事半功倍,这将是一个很大的革命。
    第二节 国内外研究现状减肥健身应用在当前,国际上较为普遍的减肥健身应用主要有moves、Nick + Running等等。国内常见的有:微信运动,马甲线,健身宝典,跟我练腹肌,动动记步器,薄荷,美趣。随着人们生活水平的不断提高,追求美,这类减肥软件也不短不单单停留在片面的减肥健身教程上,其功能也越来越多样,服务也趋向于多元化发展,一般都提供减肥健身教程,记录运动多久,食物/运动热量查询,以健身爱好形成的社区平台等实时性功能。大体上可以分为以下几种:
    1.以减肥健身教程为主导的应用
    以减肥健身教程为主导的应用指它的用户群体或者是用途主要偏向于查询动作该如何完成,资讯相关知识,其中基于 Android 平台以减肥健身教程为主导的应用代表性的包括 健身宝典,跟我练腹肌,马甲线等。客户群主要带着明确的目的想去专门练习某些动作,已达到某种效果。
    2.以运动社区为主导的应用
    以运动社区为主导的应用指它的用户群主要通过宣泄健身心得,运动状态提供一个交流平台,其中基于 Android 平台以运动社区为主导的应用 主要以咪咕运动,keep 等,这些社区型的健身应用为用户营造了一个氛围良好的交流平台。
    3.以饮食为向导的应用
    以饮食为向导的应用指它主要以控制饮食为主要减肥手段,在女性群里中比较受欢迎,其中基于 Android平台以饮食为向导的应用为主导的应用主要以薄荷,美趣等,这些应用都以有丰富的食物库,供广大用户查询。
    4.以建立教练与学员互动为向导的应用
    以建立教练与学员互动为向导的应用主要以健身房为中心,大部分发起者是健身房的教练带动学员下载,作为健身圈的一个专属交流分区。其中基于 Android 平台以建立教练与学员互动为向导的应用主要以健盟等,这些应用内有大量的私教可供大家提问,解答健身疑惑。
    5.以树立目标,记录三围等身体变化的应用
    以树立目标,记录三围等身体变化的应用面向的用户群是那些励志要减肥,却因为种种原因无法坚持下来的人们提供一个树立信心的平台。其中基于Android 平台以树立目标,记录三围等身体变化的应用现在并不多见,这也是我们型男计划的主打方向。
    第三节 相关知识1.健身指标(1)BMI 身体质量指数(BodyMass Index)

    BMI 是目前国际上衡量一个人胖瘦程度以及健康的衡量标准;

    BMI 计算方法: BMI = 体重(kg)÷身高^2(m)
    轻体重BMI:BMI <18.5
    健康体重:18.5 < BMI < 24
    超重BMI : 24 < BMI < 28
    肥胖:28 < BMI

    (2)标准体重与健康体重范围

    标准体重是衡量一个人的健康状况的重要标志 ,无论是太胖还是太瘦都对健康不利,且不能给人美感,也是成为型男的标准之一。

    标准体重与健康体重范围计算方法:
    男性:标准体重 =(身高cm-80)×70﹪
    女性:标准体重 =(身高cm-70)×60﹪
    健康体重范围 = 标准体重的正负10%

    (3)BMR (Basal Metabolic Rate)

    BMR (Basal Metabolic Rate)是维持基本生理机能的最低热量值,BMR相当一个人处于植物人状态时所需的热量[5]。

    BMR的计算方法:BMR =体重(kg)×24
    不过BMR并不能准确的描述一个人的最低消耗热量,因为瘦肉组织与的生理代谢所需的热量多余脂肪组织,所以身材越胖其每小时的BMR会比身材瘦的人小。而且一个人无论在不爱运动,也会有轻微的运动,比如翻身睡觉,讲话等一切都是需要消耗热量的。从而引出了REE概念。

    (4)REE (Resting Energy Expenditure)

    REE 静态能量消耗值,是根据身高,体重,年龄比来进行计算的能量消耗值。所以 REE 才是一般人所需的最小热能需求量。
    REE计算方法:
    女性REE =(6.25 × 身高) +(10 × 体重)- (5 × 年龄) - 161
    男性REE=(6.25 × 身高)+ (10 × 体重) - (5 × 年龄) + 5

    (5)由活动系数计算出每天所需的热量

    根据上诉REE数据来看,在相同的体重、身高、年龄下的人,应该拥有相同的REE值;但事实上,因为每个人每天所需的热量,都会随着活动量而有所不同,因此我们必须把活动系数算进去,才能得到真正的基本热量值。
    每天所需的热量 = REE × 活动系数




    活动内容
    活动系数




    卧床(全天)
    1.2


    轻活动生活模式(多坐或缓步)
    1.3


    一般活动度
    1.5~1.75


    活动量大的生活模式(重工作者)
    2.0



    (6)减肥期间每天必须摄取的热量

    如何最健康,最有效率的减肥,一直是人们关心的重点。如果太急于求成,减肥速度过快不只对健康无益,还可能造成高危险性的酮酸中毒,而且复胖率也比较高。具权威机构调查每周减0.5-1公斤最合适[6]。
    那么如何计算每天必须摄入的热量?首先要制定计划,参考自己的理想体重,求出与当前体重的差值。然后根据每公斤体重需要减少七千七百大卡的热量值,计算出欲达到目的必须减少的总热量。在根据以每周减少0.5-1公斤的效率,决定合理减肥期间,必须减少摄入的总热量除以天数,得到每天必须减少的热量。最后,将前面计算出的由活动系数计算出每天所需的热量值,减去每天必须减少摄取的热量。得到的就是减肥期间每天必须摄入的热量。

    2.开发工具(1)Java SDK
    Java SDK是Java的运行环境,也是Java开发工具包。JavaSDK为Java开发者提供一个开发环境以及一些类库的支持等等,帮助开发者进行相关的开发活动。
    (2)Eclipse
    Eclipse是运行在Java SDK基础之上的一种可扩展的集成开发环境,帮助开发者进行开发活动。Eclipse的本体是一个框架和一组服务,最初主要用来进行Java语言的开发活动。但通过安装其他的插件组件。帮助开发者进行各种各样的开发活动。Eclipse也可以用来作为与软件开发无关的其他应用程序类型的基础。
    (3)Android Studio
    Android Studio 是google 官方推荐的android 开发工具,Android Studio 能够提供高效的android开发环境,具有实时查看内存变化,实时预览界面效果,一行代码快速依赖等功能帮助开发者快速开发。
    (4)Android SDK
    Android SDK是安卓开发工具包。Android SDK为开发者提供类库的支持以及一些常用的工具,比如命令行调试工具、数据库调试工具等,帮助开发者进行开发活动。
    第二章 减肥塑身平台的需求分析第一节 减肥塑身平台的需求分析减肥塑身系统的设计,是要开发一款运行在Android智能手机和平板上[7],通过制定计划,围绕着计划所需要付出的一系列努力和变化,以达到完成计划的目的,最终帮助用户克服难以坚持锻炼无法成功减肥的困扰。帮助人们有效的减肥。如下图减肥塑身应用系统用例图,下表为减肥塑身应用系统用例表。




    用例名称
    用例描述




    登陆
    以帐号为中心,绑定用户数据


    完善个人资料
    个人资料的完善与准确度决定了,制定计划的准确性


    一分钟了解自己
    根据个人资料计算出各个健康指数


    新增计划
    根据自身身体状况量身制定计划


    查看计划
    查看完成/未完成的计划,了解自己与目标的距离


    完成计划
    将未完成的计划更改为完成


    添加身材记录
    根据三维身材分类记录添加记录


    查看身材记录
    以折线图的形式来展现出变化趋势


    查询食物/运动热量
    本地SQLite 建立上千条数据库,方便用户查找


    添加当日饮食/运动记录
    添加当日饮食运动记录,只有当摄入大于支出才能起到减肥效果


    查看饮食记录历史
    饮食记录历史为用户为了健身付出的努力



    通过以上的用例图,可以分析出减肥塑身应用系统的用户为使app方便快速的完成了新增计划,不断去完善计划,最终得以成功减肥。
    1.会员账户系统需求分析会员帐户系统根据现今许多用户压根不了解自己的身体状况,不知道身体质量指数,所以不知道自己是否超重。不知道自己的健康体重范围和健康体重范围,所以没有奋斗目标,没有明确的方向。不知道自己每天所需要摄入的最小热量,心里没有一杆秤,没办法评估今天摄入多了还是少了,不知道自己的摄入是否已经大于支出。不知道中低强度运动心率,那么就无法知道每天的运动是否能起到减肥的效果。我们的会员帐户系统就是根据用户填写的基本数据自动计算出健康数值,方便用户查看。如下图会员帐户系统用例图,下表会员帐户系统用例表。



    用例名称
    用例描述




    体重
    以帐号为中心,绑定用户数据


    身高
    用户根据自身实际情况填写身高


    年龄
    用户根据自身实际情况填写年龄


    性别
    用户根据自身实际情况填写性别


    活动系数
    用户根据应用给出的实例对比选择对应的活动系数


    身体质量指数(BMI)
    用户根据应用给出的实例对比选择对应的BMI


    健康体重范围
    根据用户所填写的信息自动计算得出健康体重范围


    标准体重
    根据用户所填写的信息自动计算得出标准体重


    每天所需的热量
    根据用户所填写的信息自动计算得出每天所需的热量


    中低强度运动心率
    根据用户所填写的信息自动计算得出中低强度运动心率



    2.计划系统计划系统为该项目的核心,用户的一切行为都将围绕如何达成目标与达成目标的过程进行,在制定计划时我们使用减肥健身人士常常关注的几个部位,如体重,胸围,腰围等信息,并设立结束时间,以激励人们在短时间内去努力。还可以写下励志语/自己给自己定的奖惩,在未来的计划达成与未达成之间给自己相应的回报。随着时间的推移,我们的身材会产生一些变化,这时就要新增身材变化,身材变化以部位划分开,并给出了最近一次身材记录,方便大家继续填写。在经过一段时间的努力后,人们就可以清楚的看到自己每个部位/体重的变化趋势图,并与之前的计划进行对比,看是否已经达成计划,以便用户可以提早完成计划。如下图为计划系统用例图,下表为计划系统用例表。



    用例名称
    用例描述




    查看计划
    对自己定下的计划进行查看翻阅


    完成计划
    对未完成的计划进行处理,将其变为已完成状态


    新增计划
    根据自身身体状况量身制定计划


    查看身材变化趋势
    对身材变化进行查看翻阅,了解自己的付出与成果


    新增身材变化
    记录身材变化,身材包括:体重,胸围,腰围,左臂围,右臂围,肩宽



    3.摄入支出系统摄入支出平衡根据能量守恒定律当摄入小于支出时,才能有效减肥,本模块系统主要解决用户无法知道自己具体摄入与消耗热量之间的关系。如下图为摄入支出比系统用例图,下表为摄入支出系统用例表。



    用例名称
    用例描述




    查询食物热量
    查询本地内置上千条食物库热量


    添加摄入记录
    对今日摄入的多条饮食记录进行保存


    查询摄入记录
    对多日的摄入热量明细进行一个查询


    查询运动热量
    查询本地内置上千条运动库热量


    添加消耗记录
    对今日消耗的多条饮食记录进行保存


    查询消耗记录
    对多日的消耗热量明细进行一个查询



    第二节 可行性分析可行性分析的目的是在软件开发之前对新系统从经济、技术、法律、进度、文化、运行等方面进行可行性分析。可行性分析能减少开发风险,提高软件开发的成功率。
    1.经济可行性经济可行性,一方面指的是项目进行过程使用现有资源,比如人力资源、资金资源的可能性;另一方面指的是开发过程中所需要的成本和项目完成后的收益。
    硬件:

    个人电脑一台:5000元,开发人员已经拥有。
    网络设备及相关费用:50元。
    Android智能手机:Nexus5 3000元,开发人员已经拥有。

    软件:

    Java SDK、Eclipse、Android Studio、AndroidSDK:均可从与之相关的官方网站上免费下载,花费为0元。
    其他:

    参考资料、相关教程:均可从网络、图书馆等地方免费获取,花费为0元。
    收益:

    现阶段下载、使用本应用均不收取任何费用,也没有加入广告,收益为0元。
    总的来说,开发过程中主要使用的是开发者本人已经拥有或能免费获取的资源,开发该项目时需要的资金额度比较小,而且该额度在开发人员的承受范围内。现阶段没有盈利部分,盈利部分将出现在将来优化后的版本中。
    2.技术可行性技术可行性,指的是开发过程中决策和决策方案的技术,不能超出当前阶段开发组织所熟练和掌握的技术资源条件。在本次开发过程中,开发人员现有的开发技术及开发经验可以承担该开发任务,主要用到的技术有Android 开发技术、Android SDK使用技术、Java SDK使用技术等等。
    3.法律可行性法律可行性,指的是项目本身、项目开发过程、项目投入使用过程和项目报废过程中都符合我国的相关法律法规,没有违法乱纪、侵犯专利权等现象。本次开发的项目本身、项目开发过程均符合我国相关的法律法规标准,项目投入使用过程和项目报废过程经科学预计,也将符合我国相关的法律法规标准。
    4.时间可行性时间可行性,指的是开发时间不能超出当前阶段开发组织所规定的时间范围。在本次开发过程中,项目启动、应用开发到应用展示,有将近一年的时间,时间是足够的。
    第三章 减肥塑身系统的设计与实现第一节 总体设计本系统的主要载体有四个:1.Android设备、2.MySQL数据库、3. SQLite本地数据库、4. 远程服务器;
    Android端作为应用呈现给用户的主要载体,本章后续将会详细介绍。MySQL 数据库在本减肥健身应用系统中作为数据中心存储的载体[8].SQLite本地数据库存储者食物热量库与运动热量库 android 端可以直接从本地获取。远程服务器是租阿里云服务器ECS,云服务器作为连通android端和MySQL 数据库的桥梁,可以方便的调用数据库中的数据用于展现在android 端上。下图为四者的关系。
    第二节 详细设计1.服务端设计后台设计是整个系统中非常重要的部分,主要分成计划模块与用户业务模块两方面。
    (1)计划模块设计
    本应用主要以计划目标为指导,引导用户去达成目标。所以,计划是本应用的核心,所有的操作都将围绕完成计划而努力。在注册完成后必须新增计划,如果已经注册,就可以查看计划,查看的同时可以新增计划,完成计划,新增消耗/摄入热量,查看消耗/摄入热量记录。新增身材变化,查看身材变化趋势等操作。
    (2)用户业务模块设计
    用户是以设备UUID 唯一值作为区分,也就以一台android 手机对应着一个账号,用户不需要手动去输入账号密码,由服务端判断这个帐户在数据库中是否有存在,有登陆,没有则进行注册。每个用户主要具有修改个人基本资料,查看BMI与基础热量消耗等个人健康数据,新增身材变化三个业务。首先介绍修改个人基本资料,每个人的身体状态并不相同,甚至可以说是千差万别。只有掌握每个用户的基本身体状况信息,才能精确计算出该用户的身体状况。查看BMI与基础热量消耗等个人健康数据,这些数据建立在准确的用户基本资料上,通过用户的准确资料计算出BMI,基础热量消耗,与健康体重范围,让用户了解自己的身体状况。新增身材变化,通过每一条身材记录的变化,用户能够直观的体现用户锻炼减肥成效。具有账户切换,进行测量,查询历史三个业务。
    2.客户端设计客户端参考 全新的Android 5.0后的新特性 材料设计 (material design),通过模仿材料的表面以及边缘提供更加真实效果的视觉体验,以真实的触感让用户可以快速地理解和认知这一动作。材料的多样性可以让我们展现出更多反映真实世界的设计与效果,但同时不会脱离现实世界的物理规律。

    根据用户行为, 添加有意义的动画效果,有效地暗示、指引用户。通过动画效果,让物体变化以更连续流畅、更平滑的方式呈现给用户。在实际应用动画上,更加贴近现实生活环境,在交互时及时反馈,转换场景上交互动画更加优美,连贯且有层次区分,而且不能脱离功能,而要服务于功能
    在样式基础上,要考虑不同的饱和度,达到不同的展现效果,用简洁对称的集合形状,并为矩形添加了圆角设计,使得矩形更加柔和。在图片配合文字时,尽量使用图片的原型性,不能失去图片的意义。
    在布局上,按下的状态时上浮的,这样显得更有层次,在适当的时候要考虑元素的z轴空间,z轴的深度表达出了层次关系,顶部的阴影表达深度,底端的阴影表达边界。
    在使用性上,至少要确保可触摸的元素大小至少有4848像素,因为人的拇指最小的点击范围正好是4848像素。在关键的文本信息处要有足够的对比方便读者阅读。

    3.数据库设计本系统所有数据均存储在 Web 服务端上,两 Android 客户端均不涉及大数据存储,故 数据库设计仅包含 Web 服务端的数据库设计,整体数据库设计关系图如下图所示。(1)用户基本信息表
    用户基本信息表主要记录用户的基本身体状况,如身高体重昵称等信息,首次登陆成功后会将用户手机的唯一标示uuid保存认证,注册成后完善信息,具体信息如表所示。




    类型
    长度
    是否null




    userId
    int
    11
    N (key)


    nickname
    VARCHAR
    255
    Y


    authToken
    VARCHAR
    255
    N


    phone
    VARCHAR
    20
    Y


    sex
    Int
    11
    N


    birthday
    VARCHAR
    255
    N


    high
    VARCHAR
    255
    Y


    BMI
    Float
    32
    Y


    high
    Float
    32
    Y


    intakeCC
    Float
    32
    Y


    consumeCC
    Float
    32
    Y


    consumeREE
    Float
    32
    Y


    standardWeight
    Float
    32
    Y


    maxHeart
    Float
    32
    Y



    (2)消耗记录表
    用户通过查询食物库进将食物添加到消耗记录表中,以便日后观察,是否超出的摄入范围。具体信息如表所示。




    类型
    长度
    是否null




    consumeRecordId
    Int
    11
    N (key)


    userId
    Int
    11
    Y


    consumeRecordTime
    VARCHAR
    255
    Y


    consumeCC
    Float
    32
    Y


    consumeRecordType
    Int
    11
    Y


    consumeRecordContent
    VARCHAR
    255
    Y


    goalType
    Int
    11
    Y


    goalStatus
    Float
    32
    Y


    High
    Float
    32
    Y



    (3)计划信息表
    用户通过查询食物库进将食物添加到消耗记录表中,以便日后观察,是否超出的摄入范围。具体信息如表所示。




    类型
    长度
    是否null




    goalId
    Int
    11
    N (key)


    userId
    Int
    11
    Y


    startGoal
    VARCHAR
    255
    Y


    stopGoal
    VARCHAR
    255
    Y


    startTime
    VARCHAR
    255
    Y


    stopTime
    VARCHAR
    255
    Y


    goalType
    Int
    11
    Y


    goalStatus
    Float
    32
    Y


    goalDescribe
    Float
    32
    Y



    (4)身材记录信息表
    身材记录信息表主要记录每个部位或体重的变化,以便日后直观查看到变化趋势。具体信息如表所示。




    类型
    长度
    是否null




    goalRecordId
    Int
    11
    N (key)


    userId
    Int
    11
    Y


    goalRecordType
    VARCHAR
    255
    Y


    goalRecordData
    VARCHAR
    255
    Y



    (5)食物热量信息表
    食物热量信息表主要记录食物的热量与名字,用户通过模糊查询关键字便可以查到该食物的热量,具体信息如表




    类型
    长度
    是否null




    foodId
    Int
    11
    N (key)


    Name
    Float
    32
    N


    Calory
    Float
    32
    N



    (6)运动热量信息表
    运动热量信息表主要记录运动的热量与名字,用户通过模糊查询便可以查到该运动的热量,具体信息如表所示。




    类型
    长度
    是否null




    activityId
    Int
    11
    N (key)


    Name
    Float
    32
    N


    Calory
    Float
    32
    N



    第三节 功能实现1.生成计划功能通过自适应计划,让每个用户找到适合自己的计划,树立明确的减肥目标。用户通过点击想要的达成的效果或者部位,如图所示。



    生成计划页面
    生成计划详细页









    2.身材管理通过身材管理直观的看到身材变化趋势,梳理减肥信心。用户通过测量身材数据,并在app上记录身材变化如图。



    记录身材
    身材变化趋势









    3.摄入支出平衡管理通过摄入支出平衡体系用户可以方便的查询到食物热量等信息,科学健康饮食瘦身。用户在搜索栏中搜索想要查询的食物/运动并根据找到的食物选择摄入的时间与份量,如图。



    查询热量并选择份量
    当日食物列表









    4.健康管理通过基础数据帮助用户计算出个人健康状况表,用户通过修改个人资料,身高,体重等参数,如图。



    修改个人资料
    个人身体状况









    第四章 减肥塑身系统的测试系统测试为系统开发的最后一道工序,只有经过缜密的系统测试,才能保证系统性能与功能的可靠性。通过测试用例反复测试,能将系统内一些隐藏的错误挖掘出来,从而让系统及时得到修复与改善。
    第一节 系统兼容性测试系统兼容性测试包括三种类型,分别为不同Android 版本的兼容性测试、不同 Android 系统的兼容性测试以及不同屏幕分辨率的兼容性测试。

    Android 版本的兼容性测试:通过测试多个 Android 版本,如 4.1,4.3,5.0 以及 5.2 版本等目前市面上较为流行的安卓系统版本,均无出现系统崩溃异常与系统无法运转现象。
    不同 Android 系统的兼容性测试:通过测试目前市面上较为主流的 Android 系统,如 MIUI,锤子 OS,FLYME,百度云 ROM 和谷歌官方 Android 版本。测试过上述这些Android 改版系统均未出现系统崩溃异常与系统无法运转现象。
    不同屏幕分辨率的兼容性测试:通过测试目前市面上较为主流的手机屏幕,如 4 英寸、 4.7 英寸以及 5 英寸大的手机屏幕。系统均能正常运行,并且界面布局不出现混乱和排版错 误,界面图标不会走样,依旧简洁美观。
    总结:经过上述 3 种兼容性测试,得出结论,本系统兼容目前市面上的大部分手机与手机系统。

    第二节 系统功能性测试本系统采用黑盒测试。测试人员无需了解程序内部如何运作也无需了解系统如何实现。 最为核心的功能进行阐述,如表 4-1所示。并且以下测试均为手机网络通畅的情况下进行的, 网络异常测试均已通过,不在下文进行阐述。



    序号
    功能点
    测试输入
    预期结果
    实际结果




    001
    用户注册
    用户第一次打开系统,输入身高体重等基本信息
    用户注册成功,成功进入新增计划计划界面
    同预期测试结果相符


    002
    用户登录
    用非第一次打开应用
    直接进入首页并有提示
    同预期测试结果相符


    003
    新增计划
    新增计划,并选择想要的类型
    新增计划完成,并在我的任务与首页中查看到该任务
    同预期测试结果相符


    002
    完成计划
    用户对正在进行的任务进行完成操作
    用户完成计划,在我的计划与首页中消失
    同预期测试结果相符


    001
    新增身材变化
    用户根据自身真实数据输入身材变化
    添加成功,并在身材变化趋势折线图中查看
    同预期测试结果相符


    002
    查询食物/运动
    用户查询想要搜索的食物/运动
    根据用户搜索的关键字模糊查找出包含关键字的食物
    同预期测试结果相符


    001
    添加食物/运动
    对搜索的食物进行添加
    添加成功后可以在首页列表中查看到数据
    同预期测试结果相符


    002
    修改资料
    修改用户基本资料
    修改成功,用户基本资料改变,个人健康数据也随之改变
    同预期测试结果相符


    ……






    第三节 系统性能测试本系统目前部署在阿里云服务器上,CPU 1核, 内存: 2048 MB, 1Mbps(峰值),进行简单测试。通过增加 连接数量,查看系统 CPU 与内存消耗,可得出结论基于该本地服务器,可同时满足 200-300 号人同时进行请求。
    第五章 总结本文针对当前市面的减肥塑身应用存在的不足,研发了一款基于Android 平台上的新型减肥健身记录系统[15],本文先结合国内外文献,分析了当今Android和减肥健身应用市场的现状与不足后,提出了一个以计划为主导的方向,从客户端,服务端,数据库三处进行详细设计。最后研发出一个功能较为完善的减肥健身应用系统,与其它类型的减肥健身应用系统起到一个相辅相成的效果,以达成最大的减肥瘦身效果。
    未来将不断完善该应用,让这个应用成为一款具有商业价值的产品,帮助更多人减肥瘦身。
    参考文献[1] Cummings D E, Weigle D S, Frayo R S, et al.Plasma ghrelin levels after diet-induced weight loss or gastric bypass surgery[J]. New England Journal of Medicine,2002, 346(21):1623-1630.
    [2] 张璐. 我国手机网民5.94亿 超过电脑成最大上网终端[J]. 中国广播, 2016, 33(1) :6-8.
    [3] Zhangpeng. Material Design实现安卓应用的新界面[J]. 计算机与网络, 2015, 41(8):24-24.
    [4] Shabtai A, Fledel Y,Kanonov U, et al. Google Android: A Comprehensive Security Assessment[J]. IEEESecurity & Privacy, 2010, 8(2):35-44.
    [5] Hayssen V, Lacy R C. Basal metabolicrates in mammals: Taxonomic differences in the allometry of BMR and bodymass[J]. Comparative Biochemistry & Physiology Part A Physiology, 1985,81(4):741-754.
    [6] Sumithran P, Proietto J. Ketogenic dietsfor weight loss: A review of their principles, safety and efficacy[J]. ObesityResearch & Clinical Practice, 2008, 2(1):1-13.
    [7] 徐婉珍.HttpClient组件及其在Android开发中的应用探讨[J].数字技术与应用, 2013, 38(1):78-78.
    [8] Mysql A B. MySQL: TheWorld’’s Most Popular Open Source Database[J]. World Wide Web-internet &Web Information Systems, 2006, 6(8):34-34.
    [9] 杨文志.GoogleAndroid 程序设计指南[M]. 北京:电子工业出版, 2009: 18-24.
    [10] 马昭征. 基于HTTP的安卓与服务器交互方法的实现[J]. 无线互联科技,2015, 78(3):92-96.
    [11] 边清刚, 潘东华. Tomcat和Apache集成支持JSP技术探讨[J]. 计算机应用研究,2003, 20(6):12-14.
    [12] Ingale J. AndroidBased WS Security and MVC Based UI Representation of Data[J]. InternationalJournal of Computer Science Engineering & Informa, 2013, 3(1):33-38.
    [13] Mysql A B. MySQL: TheWorld’’s Most Popular Open Source Database[J]. World Wide Web-internet &Web Information Systems, 2006, 5(3): 18-13.
    [14] Noguchi M, Fukizawa K.Alternate materials reduce weight in automobiles[J]. Advanced Materials andProcesses; (United States), 1993, 143 (8):6-8.
    [15] 姚昱旻, 刘卫国. Android的架构与应用开发研究[J].计算机系统应用, 2008, 17(11):110-112.
    5 评论 70 下载 2018-09-29 23:20:17 下载需要13点积分
  • 基于JAVA和SQL SERVER数据库实现的火车票预售系统

    1 系统设计1.1 设计目的乘坐火车是我们生活中几乎不可缺少的一件事儿,每天都会有各种各样的火车班次发布与被预定。针对这个火车票预售的环节我设计了一个火车票预售系统,为购票用户与卖票管理人员之间搭建平台。让我们的用户能够通过该软件对管理人员发布的航班进行预购与查询。另一方面也可以加强我们的管理人员对班次信息与乘客的管理与查询。
    本系统的根本目的是让管理人员能够发布与查询班次信息、查询乘客信息等;用户可以通过该系统对班次进行预购、自己购票记录的查询等。
    1.2 需求分析1.2.1 信息要求该系统主要记录用户、班次、火车、银行卡之间的关系

    用户分为管理员与购票用户

    售票管理员信息:管理员编号、管理员名字、管理员电话购票用户信息:身份证号、电话号码、银行卡号
    班次信息

    班次号、火车号、出发地点、目的地、出发时间、到达时间
    火车信息

    火车号、火车节数、座位数、各种座位票价、火车车速
    银行卡信息:

    银行卡号、余额、持有人身份证号
    身份证信息

    身份证号、姓名、性别、所有者
    车票信息

    车票号、班次号、座位号、乘客身份证号、车票价钱、车厢数

    1.2.2 处理要求
    能够正确、高效、迅速地完成所有操作
    一个管理员可以管理多个班次、一个用户可以多次订购不同时间段的车票

    1.2.3 安全性与完整性需求
    安全性

    该系统需要用户进行账号的注册与登陆通过对不同的用户种类的检测来给予不同的权限与界面用户登陆自己账号后只能查询自己用户名下身份证的购票信息与个人信息用户不可对班次、火车等信息进行修改售票员能对班次信息进行修改与查询,对于用户信息只能查询不能修改
    完整性

    实体完整性

    手机号、班次号、火车号、银行卡号、身份证号、车票号分别为用户、班次、火车、银行卡、身份证、车票的主码
    参照完整性

    班次号中的火车号为火车表的主码、银行卡号中所有者号码为用户的主码、车票中的火车号与班次号分别为火车表与班次表的主码。以上外码要么为空要么是参照表中已有数据

    用户定义完整性

    性别只能是男女、车票钱不能为空、车速不能为空、班次目的地与出发地不能为空、用户类型只能是 0 与 1:0 表示普通用户、1 表示管理员用户。用户名字不能为空

    1.3 开发和运行环境选择
    开发工具

    前台开发语言为 Java后台数据库为 SQL SERVER 2017
    运行环境

    Java 1.8 版本 Windows2000 以上

    2 数据库设计2.1 数据库概念设计本系统中包括六个实体:身份证实体、银行卡实体、用户实体、车票实体、火车实体、班次实体,根据需求需求分析的结果以上六个实体对应的 ER 属性图如下图所示。

    系统整体 E-R 图

    2.2 数据库逻辑设计根据 E-R 图向关系模型的转换原则,一个实体型转换为一个关系模式,实体的属性就是关系的属性。因此按照图 2.7 中的整体 E-R 图,本数据库系统中应包括六张表:身份证、银卡、用户、车票、火车、和班次。






    3 火车票预售系统详细设计3.1 功能概述售票管理员系统主要包含如下几个功能:

    发布与删除班次及其相关信息
    查看班次详细信息
    通过班次号对班次进行详细查询
    通过身份证号码查询乘车人信息

    用户系统主要包含如下几个功能:

    通过地点、时间查询班次信息
    通过班次号查询班次详细信息
    添加和删除信用卡
    添加、修改和删除乘车人信息
    查询得到班次后可以为乘车人购买车票
    查看自己用户的购票记录

    整体功能描述图如下图所示:

    3.2 火车票预售系统详细设计3.2.1 界面设计3.2.1.1 管理员界面设计在使用管理员账号登录过后,会出现管理员主界面。在界面最上方有初始地点选择和时间选择控件,可以通过时间和地点的详细选择来针对性地发布班次信息,在点击发布后会弹出火车号填写对话框,在此处填写火车号以完成班次发布的目的,如下图在发布下方有一个查看按钮,通过在左边列表中选择想查看的班次再点击该按钮即可查看到详细的班次信息如下图所示。


    3.2.1.2 用户系统界面设计在使用用户权限帐号登录过后,会进入相应的用户界面,用户界面分为四个 fragment,第一个 fragment 通过站点和时间来查询班次列表,在查询到班次后可以通过购买按钮对车票进行购买,购买时需要选择乘车人、勾选座位信息和选择支付的信用卡,如下图所示。


    在第二个 fragment 里用户可以通过班次号来查询班次信息与购票,如下图所示,在点击查询后按钮会自动变成购票,后续购票操作和第一个 fragment 一样。


    在第三个 fragment 里用户可以查询到自己所有的购票记录,可以通过查看详细按钮进行查看,还可以通过退票按钮进行退票操作,如下图所示。


    最后是用户信息界面,用户可以在此处看到自己用户名以及邮箱号,如下图所示。用户可以在此界面增、删、改常用乘车人信息,如下图所示。也可以添加和删除信用卡,如下图所示。




    3.2.2 功能实现整体功能是通过两个 Activity 与四个 Fragment 来实现,具体实现功能顺序为下图所示。本系统大量使用 Dialog 来对详细信息填写进行管理。
    功能实现过程中使用到 UI 的类有 17 个,其中三个抽象父类用于限制所有界面的业务处理与逻辑执行顺序,其余 14 个子类用于详细界面以及功能的实现,整体界面代码框架如下图所示。
    注:Dialog 是在 Fragment 中使用,Fragment 是放置到底层 Activity 使用。

    4 系统测试发布班次示意图

    发布班次示意图

    到数据库查询如下图所示:

    购票操作示意图 1

    购票操作示意图 2

    到数据库查询如下图所示:

    退票操作示意图

    到数据库查询如下图所示:

    5 总结三个星期的时间非常快就过去了,这三个星期不敢说自己有多大的进步,获得了多少知识,但起码是了解了项目开发的部分过程。虽说上过数据库等相关的课程,但是没有亲身经历过相关的设计工作细节。这次课设证实提供了一个很好的机会。通过这次的系统设计,我在很多方面都有所提高。综合运用所学知识的理论知识实际训练从而培养和提高学生独立工作的能力,巩固所学的知识,掌握系统程序的编排和运行,使自己的独立思考能力有了显著提高。
    从各种文档的阅读到开始的需求分析、概念结构设计、逻辑结构设计、物理结构设计。亲身体验了一回系统的设计开发过程。很多东西书上写的很清楚,貌似看着也很简单,思路非常清晰。但真正需要自己想办法去设计一个系统的时候才发现其中的难度。经常做到后面突然就发现自己一开始的设计有问题,然后又回去翻工,在各种反复中不断完善自己的想法。
    我们学习并应用了SQL 语言,对数据库的创建、修改、删除方法有了一定的了解,通过导入表和删除表、更改表学会了对于表的一些操作,为了建立一个关系数据库信息管理系统,必须得经过系统调研、需求分析、概念设计、逻辑设计、物理设计、系统调试、维护以及系统评价的一般过程,为毕业设计打下基础。
    很多事情不是想象中的那么简单的,它涉及到的各种实体、属性、数据流程、数据处理等等。很多时候感觉后面的设计根本无法继续,感觉像是被前面做的各种图限制了。在做关系模型转换的时候碰到有些实体即可以认为是实体又可以作为属性,为了避免冗余,尽量按照属性处理了。
    不管做什么,我们都要相信自己,不能畏惧,不能怕遇到困难,什么都需要去尝试,有些你开始认为很难的事在你尝试之后你可能会发现原来并没有你以前觉得的那样,自己也是可以的。如果没有自信,没有目标,没有信心就不可能把事情做好,当其他人都在迷茫的时候,自己一定要坚信目标。有一个这样的感觉就是课程设计学到的东西比一个学期都多。
    参考文献[1] CSDN 论坛、简书论坛、知乎论坛
    [2] 毕广吉.Java 程序设计实例教程[M]. 北京:冶金工业出版社,2007 年
    [3] 肖成金,吕冬梅。 Java 程序开发数据库与框架应用[J]. 科技展望,2017,05:19.
    [4] 吕锋,梅细燕,周晓东;基于 JDBC 的数据库管理及其应用[J];武汉理工大学学报;2002 年 10 期
    [5] 姚永一,SQL Server 数据库实用教程,北京:电子工业出版社,2010.
    [6] 高云,崔艳春,SQL Server 2008 数据库技术实用教程,北京:清华大学出版社,2011
    [7] 何玉洁,梁琦,数据库原理与应用(第二版),北京:机械工业出版社,2011
    [8] 壮志剑,数据库原理与 SQL Server,北京:高等教育出版社,2008
    [9] 杜丁超.计算机软件 Java 编程特点及其技术分析
    [10] 萧仁惠,陈锦辉. JDBC 数据库程序设计[J].北京:中国铁道出版社,2004
    4 评论 92 下载 2018-11-20 11:12:53 下载需要17点积分
  • 基于html的火柴人羽毛球游戏

    火柴人羽毛球
    一、游戏简介
    火柴人羽毛球灵感来自于flash小游戏
    游戏中,玩家可操作画面中的火柴人来进行羽毛球比赛
    通过键盘上的左右键控制火柴人的左右移动,按上键跳跃,按下键挥拍击球
    当某一方分数达到7分即判定取胜
    玩家可以选择与其他玩家对战、与不同难度AI对战,以及观看AI对战

    二、游戏实现2.1 绘图部分该游戏为实时性游戏,为保证流畅,采用了游戏常用的60fps的帧率。每一帧绘制的内容包括背景图片、当前比分、火柴人以及羽毛球。下面分别介绍绘图部分的各个细节:

    半透明图片常见的GDI库只能绘制BMP图片,其附带的透明选项也只是选取图片左上角像素作为透明颜色,并不能实现真正的半透明绘图,画出的图片常会带有丑陋的白边。为了解决这一问题,我们使用了GDI+库,它支持各种各样的图片格式,当然也就包括含有透明通道的PNG格式。有了GDI+,我们也就实现了更为精美的游戏画面。
    双缓冲绘图绘制出图片并完成一些简单的动画后,我们发现在刷新一帧时,画面会出现闪烁。想到以前使用MFC编程时曾接触过双缓冲绘图方法。画面出现闪烁的原因是绘图时多次把像素转移到屏幕上,而双缓冲可以先在内存中建立起一块画布,等到在内存中全部绘完,再调用BitBlt函数将像素逐个复制到屏幕上。这样便避免了画面的闪烁。
    局部刷新GDI+固然比GDI功能强大,但它绘图效率低是不容忽视的问题。与Direct2D使用显卡绘图不同,GDI+使用的是CPU,再加上我们的游戏需要绘制很多元素,对绘图优化就显得很有必要。我们注意到,切换一帧时,并不是全部元素都需要重新绘制,因此也就可以使用局部刷新技术,只重绘更新了的区域。
    人物动画在FLASH中,开发者可添加一种名为影片剪辑的元素,它可以做与主时间轴异步的动画,影片剪辑可以极大地方便动画的制作。然而,汇编语言并没有强大的动画制作工具,实现精细的动画也就需要很复杂的处理。例如,绘制人物时,手臂挥拍、脚步移动、跳起时阴影保留在地面上,这些是各自独立的。我们将小人的图像拆解开来,分别画四个部分,这就实现了游戏中小人复杂的运动。



    图片旋转游戏中的羽毛球并不是圆球,因此也就涉及到了旋转。我们并没有简单地制作许多张不同角度的羽毛球素材,而是只用了一张图片。使用GDI+中的函数GdipImagePointsI,可以以图片左上、右上、左下三点为基准,规定三个新的基准点,对原有矩形做线性变换,以此来完成图像的旋转。
    2.2 逻辑部分
    运动模型现实中,羽毛球由于受到的空气阻力较大,其的运动轨迹不同于其他球类,不呈现抛物线。我们在游戏中为了还原真实性,使用了如下运动方程:
    \\[\vec a=\vec g-\gamma\cdot \vec v=\frac{{\rm d}\vec v}{{\rm d}t}\\]式子中,\(\gamma\)为空气的粘滞系数。
    碰撞判定羽毛球涉及的碰撞判定有很多:球网、地面、墙壁(球可以反弹回来!)都具有碰撞判定。在游戏中,球的运动是离散、不连续的,因此在每一帧计算时,球的判定点很难恰好处于墙壁等障碍物的平面上。对于球撞击障碍物反弹的动作,我们的处理方法是:

    使球的坐标做关于平面的对称变换
    使球垂直于平面方向的速度分量反向
    不同平面有不同的弹力系数,对应于不同的反弹速度

    有了这样的处理,球的运动才会精确反弹。
    击球判定击球是游戏中角色最主要的动作。游戏中击球的判定也很独特:人的可击球区域是球拍面挥动起来可达到的扇形圆环区域,羽毛球飞出的角度与速度是在击球瞬间由人与球的相对位置决定的。此外,根据球的高度不同,角色也可以自动判断应该从上方还是从下方击球。
    AIAI的设计可以说是本游戏的一个亮点。游戏中,分别有两个函数leftAIconsider与rightAIconsider,这些函数会根据包括羽毛球位置在内的游戏状态信息,指挥小人的行为(移动、跳跃、击球)。游戏内置了两个不同难度的AI,玩家亦可自行修改AI决策函数,利用AI-AI对战模式与内置的AI进行PK。

    三、其他亮点
    实现了背景音乐播放,并且为击球动作添加了音效
    可以屏蔽中文输入法,避免点击字母时跳出输入法
    创建窗口时,获取到屏幕分辨率,使窗口处于屏幕正中央
    0 评论 6 下载 2019-06-22 22:15:12
显示 0 到 15 ,共 15 条
eject