分类

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

资源列表

  • 基于C语言实现的聊天室

    一、设计背景该课程设计的初衷是想要实现一个游戏,这个游戏我曾使用易语言实现过,它是一个可多人在线对战的规则简单的棋类游戏,我想用 C 重写它。
    与易语言不同,在 C 中,网络通信和图形界面只能从底层开始实现。
    于是,我花了一个星期简单学习了 socket 接口,将其封装为一个静态库,并提供给小组成员,方便他们调用,大大减少了工作量。
    而后,我又花了一个星期去学习 win32 接口,没想到的是,win32 的体系太过庞大,其中很多细节和历史遗留问题盘根错节,而且一个功能常常可以有多个看似相同而在某些方面隐约不同的接口实现。
    这时我意识到,实现游戏的工作量太大,于是组内临时改变目标:实现一个聊天室。
    相对来讲,聊天室的 UI 简单,客户端与服务端之间的协议等于无,于是我们就顺着这个路线开发,最终实现了我们的课程设计。
    二、设计过程2.1 主要内容2.1.1 两套封装好的 Socket 静态库含有:
    (在 C 中实现面向对象封装的类库)
    Gao_socket_Class.cGao_socket_Class.hGao_socket_Class.lib
    (普通库)
    Gao_socket.cGao_socket.hGao_socket.lib
    2.1.2 服务端(Server.c)
    使用库 Gao_socket.lib
    2.1.3 客户端(Client.c)
    使用库 Gao_socket_Class.lib
    2.2 额外知识
    win32 接口socket 接口回调函数的思想静态库的封装及头文件的内容面向对象的程序设计思想
    2.3 其他说明我们的课程设计提供了两个封装好的 socket 静态库,其中一个我称之为“类库”,他是另一个库的改进版本。它当然不是真的封装了一个类,而是一个大大的结构体,我通过结构体来实现 C++ 或者 Java 之类支持面向对象的语言的类的功能。
    为什么会有两个版本?在最初,我先实现了那个普通的 socket 库,后来发现了一些问题。通过请教老师(非常感谢吕老师对我的指导),我在原来的基础上重构了它,把它变成了一个“类库”。
    因为我考虑到组内成员尚未接触面向对象的思想,所以仍然让他们使用原来的库。
    至于我发现了什么问题,这里简单说一下。静态库提供的主要接口仅有两个,一个是创建服务端(Create_serversock()),一个是创建客户端(Create_clientsock()),其他接口均在上述两个函数被调用后才能够被调用,如发送数据,取对象,关闭对象等等。两个主要接口其内部封装了从 socket()到 listen()(或 connect())的所有步骤,并且开始监听端口(或接收数据)。重要的是,程序内部的变量只有一份,也就是说这套接口实际上可以看作是某类的一个实例化,那么它的局限性就凸显出来了:一个进程只能创建和使用仅一个客户端和服务端,试图多次调用创建客户端/服务端函数只会导致变量数据混乱。
    于是我通过结构体来实现面向对象的类库。
    其中较原来的库多了一个接口,它用来包装和初始化程序员创建的对象,从而所有接口内部使用的变量由程序员提供或是存在于栈空间里,多线程访问时不会发生冲突。
    还将原来一些接口的参数删去,包装在类实例的成员中。
    C 的结构体没有私有成员这个概念。对于这个问题,我在头文件中将重要的成员名均注明 private。(可以通过匿名位域解决这个问题,但首先匿名位域成员不存在内存对齐,其次写死了成员长度会使库不具有移植性)
    三、难点及解决方案3.1 socket 接口3.1.1 ws2_32.lib 链接问题由于我使用的 IDE 为 VS 2019,在最初的阶段,代码总是报错无法编译,多次搜索后找到解决办法:
    在 VS 2008 及以上版本中,使用 Socket 时需要链接库: Ws2_32.lib
    #pragma comment(lib,"ws2_32.lib")
    3.1.2 Socket 初始化问题在学习了一些前置知识后,我开始尝试调用 winsock2.h 提供的 API。
    但在最初阶段,我调用 socket() 获取文件描述符时总是返回-1(出错)。原因是:在 Wndows 下使用 Socket 需要先注册,或者叫绑定 Socket API,它过函数 WSAStartup()实现。
    MSDN 对 WSAStartup()给出如下解释:

    The WSAStartup function initiates use of the Winsock DLL by a process.

    关键部分:

    The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup.

    在最后还需要调用 WSACleanup() 函数注销自身:

    The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll).

    网上大部分较系统的讲解 Socket 的博客基本上都是在 Linux 下的,而在 Linux 下是不需要初始化 Socket API 的。所以这个问题确实困扰了我一小段时间。
    3.1.3 select() 对阻塞 socket 实现非阻塞操作socket 分为阻塞和非阻塞两种模式,Windows 下所有创建的 socket(包括 accept()返回的 socket 描述符)均为阻塞模式,这也就导致我们无法同时干多件事。例如:1. 服务端无法在接收数据时接受用户的连接请求。2. 客户端无法在用户输入时接收数据。
    而我们并不知道客户到底什么时候想要干什么,于是程序的设计思路就非常麻烦了。
    这时候需要用到 select() 轮询所有我想要监视的 socket。当服务端开始监听端口后,整个程序就会跑在一个大 while 中。传入 select 中一个时间结构 timeval 作为超时时间,然后他就会在必要的时候提醒我们哪个 socket 可以操作了,或者是超过超时时间,让我们处理一些我们想要处理的东西。
    我为什么不选择使用非阻塞模式的 socket,第一是因为麻烦,想要实现非阻塞的 socket,需要很多比较麻烦的技巧。第二是因为浪费资源,这种异步的思想,总会让我的程序在函数返回后疯狂检测执行状态,这显然有些浪费资源。第三是因为没必要,select()已经满足了我们课程设计开发的需要,没必要去故弄玄虚(或者说炫技),这是大炮打蚊子的做法。
    3.1.4 面向对象实现在上一大节我们提到了那个“类库”,实际上,这套接口的实现并不顺利。主要是在原理上。
    最初我认为,每个对象的方法在调用时都是新的,即创建对象时整个类涉及的成员和方法都被 copy 了一遍。这句话的前半句话是对的,而后半句是错的。这导致我一直在寻找一个办法来 copy 一个函数在内存中的实现数据。
    后来查到:同一个类的实例调用的方法的代码段在内存中均相同,这时我就非常疑惑不解。在支持面向对象的编程语言中,总会有多线程调用同类实例的同一方法的情况,而它却不会出现数据混乱。
    再后来,我请教老师,了解到:当线程执行到内存中某个位置需要调用函数时,线程会把函数段 copy 到栈空间中执行。这时候一切都豁然开朗了。
    原理问题解决了,后面就都是一些具体实现的细节问题了。我在头文件中向调用者提供了一个结构体,程序员首先声明这个结构体然后通过将其交给我们提供的包装接口初始化其方法来创建对象。当程序员调用某方法时,当前线程仅使用了这个结构体的成员及一些存在于当前线程栈中的数据。
    到这里,就完成了这个面向对象的静态库,程序员可以在一个进程中创建多于一个的客户端及服务端而不会产生数据冲突。
    最后,基于对 socket 的非常浅显的了解,我把它总结在了这篇博客里:
    3.1.5 和 10053 错误MSDN 对 WSAENOTSOCK(10038)的解释:

    Socket operation on nonsocket.An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.

    这个错误仅出现在客户端服务器共同单步调试的过程中,猜测是断点破坏了 socket 内核的一些逻辑。
    这个错误没什么影响,之后也再没出现过。
    MSDN 对 WSAECONNABORTED(10053)的解释:

    Software caused connection abort.An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error.

    错误很难重现,不过出现的概率也很低。
    总是在我连接上远程桌面后,看到服务端疯狂被 error 回调函数刷屏。但奇怪的是,此时客户端仍然可以正常使用。
    不知道为什么,服务端监听的端口总是有 Http 请求,像下面这样:


    由于服务端监听的端口总是有 Http 请求,而且出现错误的周期也很长很长,所以到底是哪个客户的哪个行为导致了这个错误,就很难定位
    后来猜测是一些 Http 请求导致的问题,于是我让服务端记录日志,看看到底是客户端访问导致的还是 Http 请求导致的,但到目前为止还没触发过 10053 错误,所以仍然原因不明。
    为了尽量避免这个问题,我在最终完成的课设中改了端口。
    3.2 win32 接口3.2.1 文本框(EDIT)换行这个问题贯穿着客户端部分的整个开发过程,直到接近完成时才终于解决。
    当我改变 Windows 窗口的尺寸时,文本框中原本已经整整齐齐的文本会突然缩在一起——所有换行符莫名其妙地消失了。
    网上查资料查了很久很久都未果,身边也没有任何一个研究过 win32 的人。开发过程中我一度把窗口风格中的可调尺寸去掉。直到一次偶然,具体细节记不清了,我在单步调试文本拼接的问题时突然发现:在文本框中,换行是“\r\n”而非“\n”。
    于是问题就这么解决了,可能看起来我很轻描淡写,而且原因居然如此简单,但这个问题确实困扰了我非常久。
    至于为什么在窗口尺寸未改变时,文本框的输出换行是正常的,这个尚未解决,我也没有任何思路。
    3.2.2 字符集的选择我经常在别人的代码里见到 TEXT()这个宏。根据我对 win32 的浅显了解,相应的还有_T() 、_TEXT()和“在字符串前加一个 L”。它们的作用相同,仅有微小的区别。但想要说明白他我甚至需要再写一篇文章,所以不再赘述。大概来讲,它们表示将 ANSI 字符串转换为 Unicode 字符串。
    我在学习一个新技术时总是喜欢一边写一遍看,于是不管是 Socket 还是 win32,每次在基本结束学习时都会有一个几百到一千行的源文件,里面包含着我调试各种功能的代码。
    然而当我新建了一个工程然后真正开始写客户端的界面时,出现了令人百思不得其解的问题:所有地方都出现了乱码问题,而且还是韩文。所有子窗口(窗口控件)都没有创建成功。倒是窗口的消息队列还正常运转着,窗口并没有卡死。
    然而我仔细对比了两段代码的调用顺序,看不出任何区别。我甚至把两段代码从头到尾单步运行了一遍,不知道什么原因,客户端在创建子窗口时总是出错,返回一个 NULL,而其他一切正常,除了乱码。
    后来,我把两段代码交换了位置,用来调试学习的工程完美运行,客户端的工程还是出错乱码。这时候我意识到可能是环境配置的问题,于是我打开两个工程的属性页,一条一条对比,终于发现了问题所在:在客户端工程下,我使用的是 Unicode 字符集,而在用来调试学习的工程下我使用的是多字节字符集(MBCS),当我把它改成多字节字符集后,一切都正常了。
    多字节字符集这种说法实际上是错误的,应该叫“多字节字符系统”。从这里可以看出来,多字节字符系统与 Unicode 字符集并不是并列关系,它是一种编码类型,而 Unicode 是一种具体的编码方案。
    多字节字符系统(Multi-Byte Chactacter System),指由 ANSI 的 ASCII 字符集派生(或扩充)来的一系列字符集。这些字符集种类繁多,不便于在国际上交流时的转换,于是出现了 Unicode 这样统一的字符集。
    在使用 win32 接口进行图形界面的编程时就需要注意,如果我们使用的是 Unicode 字符集,那么就必须将所有字符串通过上述提到的宏来处理,否则就会出现令人抓狂的乱码问题。
    3.2.3 文本框消息由于 Enter 键的限制(实际上是因为懒),我的发送文本框设计为不可换行,也就是每次仅可发送一行数据,其显示范围我也让其恰好显示一行文本。
    我想在 Windows 的消息回调函数中判断 Enter 键的按下状态,然后发送数据。于是我查了窗口按键的消息,有很多,其中一个大概是 WM_KEYDOWN。然而我却发现,我在文本框按键后根本没有触发这些消息。后来我分析了所有传入回调函数的消息,发现全部是针对父窗口的,子窗口的消息在分发消息之前就已经被处理了。
    于是我找到了主函数中的 Getmessage(),既然它的作用是从消息队列中取一条消息出来,那么他这里的消息一定包含有我想要的消息,于是我尝试直接判断传入实参的 MSG 结构来判断子窗口的消息。
    在 MSG 结构下的 hwnd 是当前消息目标窗口的句柄,message 是消息,剩下的是该消息的参数,这就很好办了,通过判断该消息的目标窗口句柄和该消息类型及消息的相应参数即可捕捉到我们想要的事件。
    键盘消息拦截已经解决,然而又出现了新问题:每次按下 Enter 后,文本框中总会留下一个换行符。这让非常疑惑,同时也感受到了 win32 接口其其体系之复杂,细节之繁复。我很难定位这个换行到底是在哪里被发送到文本框的。
    经过不断地各种断点调试修改,最终定位了问题所在。
    我们知道,就像固定格式一样,在处理 Windows 窗口消息时,我们通常会写一个 while,然后让 GetMessage()跑在里面,紧接着下面就是翻译消息(TranslateMessage())和分派消息给回调函数(DispatchMessage())。而我的消息拦截则放在了以上三个函数的下面。尝试过各种方法无果后,我尝试改变他们的位置,然后不断地获取文本框的内容,同时监视着 msg->message 的值。
    这次我猜对了,是翻译和消息分发函数的问题。
    我发现,如果我拦截消息前后调用了上述两个函数,那么下一次循环取到的消息会是 258(WM_CHAR)
    MSDN 对该消息的解释:

    Posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. The WM_CHAR message contains the character code of the key that was pressed.

    也就是说,在下一次循环时,该消息会通过分发消息函数被发送到指定窗口。于是在我拦截了键盘消息的后一次循环中,一个换行符被发送到了文本框中。
    WM_KEYDOWN(或 WM_KEYFIRST,两消息等值)是键盘消息的第一个消息,如果在最开始就把他拦截下,跳过 TranslateMessage(),那么这个事件就相当于没被触发过。
    所以解决方法就是先拦截消息,然后直接 continue。
    3.2.4 创建子窗口失败这个问题折磨了我一个晚上。
    最初,我在学习 win32 接口时尝试创建了很多控件,一切正常。然而当我准备一次性创建所有我需要用到的控件时,所有控件的创建均失败了。通过 GetLastError()我获得了错误码 1406,意外的是,百度根本都查不到。
    MSDN 上的解释:

    1406 (0x57E)Cannot create a top-level child window.

    这个解释很模糊,无法创建上层子窗口,我确实是没能创建这个子窗口,没有具体原因。
    我在 Bing,Google 上查了很久,确实找不到相关信息。于是只能靠自己了。
    我从头到尾单步运行了几遍,检查了每个变量和参数的传递情况,最终发现,当我试图调用 CreateWindow()创建控件时,参数 hWndParent(父窗口句柄)的实参是 NULL。
    实参是一个全局变量,它在主函数中由 CreateWindow()返回。然而我是在 windows 的回调函数的 WM_CREAT 消息下开始创建控件的,这个消息在窗口创建完毕时被发送到该窗口。这时候我意识到,也许此时主函数中的 CreateWindow()尚未返回。
    我突然想到了易语言中的窗口创建完毕事件,在那个回调函数下执行代码时窗口还没有显示。其实这也就对应着尚未调用 ShowWindow()及 UpdateWindow()(这个函数可不写,仅为绕过队列发送一个重画消息)函数,那么很可能此时 CreateWindow()确实还未返回。带着这些关键字在百度上查了一下,果然如此。
    解决方法很简单,就是使用 windows 回调函数传入的第一个参数 hWnd,它就是该窗口的句柄。
    四、总结这次课程设计,整个小组都学到了很多东西,
    了解了网络通信和 Windows 下的图形界面编程,还有一些编程思想,同时也增强了自身的学习能力和 Debug 能力。
    1 评论 3 下载 2021-07-07 07:55:39 下载需要8点积分
  • 基于QT实现的数独游戏

    1 简介Sudoku 是一款利用 Qt 实现的数独游戏,提供了多达 10 个难度的关卡选择,同时还有丰富的功能来帮助玩家更加高效地求解数独问题,例如候选数、高亮相同数字、高亮选中的行列、撤销当前操作以及提示等功能。玩家还可以手动输入数独题目利用 Sudoku 帮助求解。
    除了传统 9×9 的数独游戏以外,还提供了更高难度的 16×16 的数独游戏。



    9x9数独
    16x16数独









    2 功能Sudoku 提供了多个方便的按钮:

    新游戏:玩家可以开始一局新的游戏
    重玩:玩家可以重新开始本局游戏
    暂停:玩家可以暂停该局游戏(即暂停计时)
    提示:如果当前已经确定的数都是正确的,玩家将会得到一个未填空格的正确数字;如果当前已经确定的数和答案矛盾,导致整个数独无解,那么所有与答案矛盾的数字将会被粗体标出
    清除:清除当前选中格子的所有数字
    撤销:撤销前一步的操作,以及取消撤销(最多可支持 50 步撤销)

    同时可以通过菜单来实现多达 10 种难度的游戏选择,可以求解任意用户输入的数独问题。



    (a) 最低难度的数独
    (b) 最高难度的数独








    (c) 一个玩家任意输入的游戏
    (d) 利用算法计算出的答案







    (a, b) 上方的按钮从左到右分别为:新游戏、重完、暂停/开始、提示、清除、 撤销和取消撤销。黑色的数字表示初始时题目所给出的数字,大号红色数字表示用户已 经确定的数字,小号红色数字表示候选的数字。当前选中的格子以及与其所在相同行或 列的格子被高亮显示,同时右侧数字栏中已经选择的数字被加粗显示,可以方便进行操 作。另外,对于已经确定的数字,其余与其相同并且也已经确定的数字会被加粗显示, 如 (b)。玩家对于重要的数字可以进行标记,标记为在格子左上角打上一个三角(例如 (a) 中的数字 3)。
    玩家在空格中填入的数字分为确定数(采用正常大小的字体表示)以及候选数(采用 小号字体表示)。确定数只能存在一个,候选数可以存在多个,并且确定数和候选数不能同时存在。
    玩家可以通过多种方式进行格子的选择:

    通过鼠标直接点击格子进行选中
    通过键盘方向键来进行当前选中格子的切换
    通过 Tab 键快速切换到下一个格子

    玩家可以用鼠标右键点击格子来对其进行标记。
    玩家在选中一个格子之后,如果该格子的数字已经确定,那么所有与该数相同的数 将会被加粗显示,以方便确认是否满足数独的条件。同时,所有与该格在相同行或列的 格子都会被高亮显示。此外,无论该格子数字确定与否,右侧数字列表中该格子的所有 数都会被加粗。
    玩家可以通过多种方式在空格中填入数字:

    通过键盘直接输入数字将填入对应的确定数,如果 Ctrl 键被按下,那么填入的将 会是候选数
    通过鼠标点击右侧数字列表填入。使用鼠标左键点击将会填入确定数,右键点击 则会填入候选数

    玩家也可以通过多种方式在空格中填入数字:

    通过键盘删除键删除格子中的一个数字
    通过鼠标点击右侧数字列表已经选中的数进行删除
    通过“清除”功能键来清除该格子所有的数字

    3 难度选择算法我们认为一个数独游戏的难度可以根据行列空格数的最大值以及给定数字的数量来确定。 行列空格数的最大值越小玩家拥有的信息量就越多,同样给定数字越多玩家也能获得更 多的信息。
    在我们的难度中,最简单的关卡给出的数字至少有 50 个,并且行列空格数不会超过 4 个。然而,在最困难的关卡中,最少只会给出 20 个数字,并且可能会有某些行或列全 部是空格。在最简单和最困难中间这两个影响难度的因素平滑过渡。
    为了生成一个满足条件的数独,可以按照以下步骤来实现:

    在空白棋盘随机填入数十个数
    利用求解算法获得一个合法解,如果不存在合法解,转到 1
    生成一个随机的格子排列
    按照这个序列来尝试一个个删除所填入的数字,如果删除后能保证解唯一并且满 足之前的条件,那么就删除,否则不删除
    如果删除了足够的数字,则返回。否则跳到 1

    为了实现快速的数独问题求解,我们利用 Dancing Link 来优化搜索。
    4 GUI 部分实现主要的游戏棋盘是通过 3×3 的 QGridLayout,每个 QGridLayout 里再套一个 3×3 的 QGridLayout 来实现的。
    功能按钮的鼠标移入以及点击的效果是通过 QPainter::drawImage 里图片的混合 选项来实现的,通过多次混合以及不同的混合参数就可以实现颜色的深浅变化:
    void ToolButton::paintEvent(QPaintEvent *) { QPainter p(this); QPixmap bg(image_path); p.drawPixmap(QPoint(0, 0), bg); if(is_mouse_pressed) { p.setCompositionMode(QPainter::CompositionMode_Multiply); p.drawPixmap(QPoint(0, 0), bg); } else if(is_mouse_over) { p.setCompositionMode(QPainter::CompositionMode_HardLight); p.drawPixmap(QPoint(0, 0), bg); }}
    另外,关于窗口大小的固定,由于在切换数独棋盘大小时窗口大小也会随之改变, 可以利用 minimumSizeHint() 来直接进行计算:
    setFixedSize(window->minimumSizeHint() + ui->menuBar->minimumSizeHint());
    4 评论 320 下载 2018-11-06 14:28:52 下载需要10点积分
  • 基于SSH和MySql的医院在线挂号系统设计与实现

    摘 要互联网技术迅速的发展给我们的生活带来很大的方便,同时也让许多行业迅速的发展起来。互联网技术已走向科技发展的巅峰期,我们要做的就是合理的使用互联网技术让我们的各个行业得到更快速的发展。
    就医疗领域来说,如今看病难已成为我们生活中的一大难题,传统的医院挂号中,我们需要用手动方式来处理信息,这种方式需要我们的医护工作人员和管理人员花费大量的时间来处理事务性信息,不仅劳动强度大,而且浪费时间。患者长时间的排队等候不仅延误了患者病情,而且不利于医院秩序的维护。所以在这里我的论文对医院挂号系统的设计和实现进行了详细的描述与设计,专为解决挂号难,排队时间长的问题,通过此网站患者可以快速方便的找到自己所需挂号的科室信息,并进行在线预约挂号。对于此网站,采用的是较为成熟的SSH框架,主要包括了业务逻辑层、数据持久层,表示层,模块层四个层次,这些层次可以帮助开发人员对搭建结构,维护系统,框架重用等,也可以给开发人员提供一个清晰、易懂,简洁明了的设计思路,SSH框架可复用性好、维护方便,使系统更加好用,同时让系统的实施和维护更加方便。对于数据库设计我们采用了MySql数据库,由MySQL的发展已经很健壮、成熟,而且具有很好的安全性,操作简单,成为了开发数据库设计的首选。
    医院挂号系统主要角色有:患者和系统管理员;患者可以对医院信息的查询、对医生信息查询、登录注册、预约挂号、取消挂号、更改个人信息等;管理员可以登录系统,更新数据库内医院信息、医生信息、医院公告,也可对个人信息进行修改。网页设计了相关的导航,对新用户进行全面的引导,使得用户使用更加方便,对用户注册登录和管理员登录进行了分离,防止用户和管理员登录冲突,总体测试结果显示,网站设计基本符合用户需求,能够达到用户满意度。
    关键字: SSH ;JSP ;MYSQL ;MyEclipse ;预约挂号
    AbstractThe Internet technology development rapidly, make our life more and more conveniently, simultaneously also lets many profession development rapidly. The Internet technology becomes the social development front technology already, we had to do something to make it reasonable to use the Internet technology let our each profession obtain a faster development.
    On the field of medic, it is very difficult to go to see a doctor, this is a social problem, In the traditional hospital ,we need to use the manual way to deal with a large of information, we have to make a appointment by line up , This way need our medical staff and managers spend a lot of time to deal with transactional information, not only the intensity of labor is big, but also a waste of time. Long queues of patients not only delay the patient’s illness but also harm the maintenance of hospital order. So here my thesis on the hospital registration system design and implementation of the detailed description and design, designed to solve the registered, queuing time, patients through this website can be quickly and easily find their registration department of the information needed, and to make an appointment online. For this site, the more mature SSH framework is adopted, which makes it easier to implement and maintain the system.
    The main role of hospital registration system is: Patient and system administrator. The patient may inquire about the information of the hospital, inquire into the doctor’s information, sign up for registration, make an appointment, cancel the registration number, change the personal information, etc. The administrator can log in to the system, update the information about the hospital in the database, the doctor’s information, the hospital announcement, or modify the personal information. Web design related navigation, a comprehensive guide to new users, allows users to use more convenient, to the user registration, registration, the administrator login and separation, prevent users and administrators login conflict, the overall test results show that the website design basic meet user requirements, to achieve customer satisfaction.
    Key words: SSH; JSP; MYSQL; MyEclipse; appointment register
    绪 论在信息化的时代,我们生活的节奏变得非常快,做每一件事几乎都是匆忙的完成。因此人们对生活节奏要求越来越高,人们不再允许自己的时间大量的浪费在无用的事情上;计算机在我们生活中几乎已经普及,优惠的价格但是功能却很强大,我们的生活越来越离不开互联网,同时互联网技术也在不断地渗入到各个邻域,如医疗,教育,管理等方面,它的广泛使用给我们的生活带来了极大的方便。但是,就医疗界来讲,在目前调查看来,我们很多医院都采用的是人工挂号的方式,导致我们需要花费很长的时间排队等候去挂号,医院的医生、护士等工作人员也需要很多时间去人工处理患者的信息,这样下去,不仅会耽误患者的病情,而且造成医院拥挤秩序混乱,人力物力成本高等一系列的问题;所以我们需要合理的将互联网技术引用到医院,让它来方便我们的生活,方便患者挂号的同时,可以解决医院资源分配的问题,不仅可以便民而且让医院有了一个更好的效益,人们不用在担心自己的时间浪费,医院不用担心人力资源不够等一系列问题。患者只需在家轻轻动动手指访问网站即可实现在线挂号,这样双赢的结果是我们每个人所期待的,所以挂号系统的实施,对人类来说是一个很大的进步。
    挂号是我们看病就医的第一步,通过收集病人信息,协调专家管理,控制病人和医师人员的流量。通过网站的方式来挂号是很新型的一种挂号方式。在这种网站上,病人可以不出门直接在家对自己的病情初步判断,查询医院医生的信息来进行预约,进行注册登录挂号,减去了人们排队等候时间的同时也提高了医院的管理效率从而提高了医院的经济效益。是建设卫生信息化的必由之路。
    目前看来,医院门诊质量和效率不高的原因主要有一下几个:集中式挂号,来医院排队挂号的人数很明显地由不确定的特点,从而出现了明显的看病高峰和低谷。高峰期病人挂号要排很长的队伍,甚至有一些专家,帮助自己的熟人插队,造成医院现场混乱患者情绪不稳定,专家问诊不仔细、没有耐心,不想长时间和病人交流等现象。在低谷期,专家没有事情做、溜号等,造成医院资浪费。这些现象严重的损害到患者的权益,也影响到了医院的声誉。文献[9]介绍了这种问题需要一个很好的挂号平台来解决,它可以减少病人浪费的时间,同时,也可以帮助病人全面的了解医生信息,选择自己期望的医生来为自己看病。不但解决了病人对医生相关信息了解不多盲目性问题。同时医院采用网上挂号的方式,患者可以在家就可以问诊挂号,方便了患者的同时也方便了医院的管理。本论文就如何实现在线医院挂号系统的设计细节以及实现方式技术和系统的测试结果进行了全面详细的论述。
    针对国内外文献的研究发现,在网上实现预约挂号系统已经不再是一个梦想,我们运用所学的语言,便可以完成挂号网站的实现,大部分文献中指出:医院网上挂号系统以Java为开发语言,框架部分主要使用了Spring,hibernate,Struts2框架开发。Spring通过使用IOC容器的方式,来对整个项目的复杂依赖进行管理,Hibernate是一种应用很广泛的ORM框架,使得开发人员可以将数据库中的数据映射到一个具体的Java对象中,简化数据库相关的开发工作。Struts属于实现MVC开发模式的一个框架,要让Model层,View层,Controller层三个层次分别列出来使用的是Structs,分层的代码更易维护和迭代。MySQL是对数据进行存储的数据库。在接下来的论文中我们会具体介绍医院挂号系统中所使用到的一些关键技术,以及实现方法和设计思路。
    1 系统描述与技术介绍1.1 MyEclipse介绍构建网上预约挂号系统使用的是MyEclipse编辑器,MyEclipse 是开发人员特别偏爱的一种开发工具, Eclipse 中的J2EE是一种插件集合;MyEclips开发工具有很强大的力量,它对JavaServlet,AJAX,JSP,Struts,JSF,Spring、Hibernate等的支持使得开发变得非常容易,同时还具备了EJB3的功能,JDBC数据库连接的功能。所以说MyEclipse是所有开源工具开发的好帮手,更重要的是Myeclipse还具备了完整的编码、测试、发布功能,那够很全面去支持html Javascript,JSP,CSS, MySQL, Hibernate等语言的开发,所以发展成为了最受欢迎的开发工具。
    1.2 MySql数据库介绍MySQL数据库作为一种开源的关系型数据库,在目前是使用最广泛,最受欢迎的一种数据库,MySQL是由MySQL AB公司进行开发的但是后来最后被Sun公司收购了,目前已经成为了IBM的一个项目。
    MySQL的发展已经很健壮、成熟,SQL数据库。通过维护一个线程池,MySQL可以提供高并发、稳定可靠的数据存储和查询服务。在世界范围内,各大互联网公司有着非常广泛的使用。
    MySQL在开发人员眼中就像是一种数据库管理系统的角色。MySQL数据库可以对所有的东西结构化,我们可以认为它是一种数据的结构化的集合。可以访问,也可以更新数据到数据库,或对访问,对于已经修改过的数据还可以再次修改保存等,MySQL服务器可以用来对即将要使用的数据进行全面的处理。计算机对于我们来说本来就是用来处理数据的对象,所以数据库管理系统MySQL数据库的实现是计算机不可或缺的组成部分。
    我们也可以把MySQL数据库看成一种很方便的服务器。对MySQL数据库的设计需要开发人员和客户进行沟通确认才能进行合理的设计;通过MySQL数据库与其他数据库的对比就会发现。MySQL服务器的开发背景比较强大,具有更快的解决方案速度,使用更加方便高效,以及他的广泛使用得到了人们的一致好评。MySQL数据库也在很快的照着人们使用更简洁的方向去发展,这使得MySQL具有了更好的的安全性,不断地完善是其受欢迎的根本原因,这样,人们可以更加方便,快速,安全的对Internet上的数据进行访问,处理等。MySQL是开源的,意味着所有人都可以使用和修改该软件。针对自己的应用场景,可以在其基础上进行修改,提升服务的稳定性和可扩展性。
    1.3 JavaScript介绍JavaScript也是开发人员很喜欢的脚本语言,它是通过解释执行的动态的语言是面向对象的语言。被Chrome浏览器、IE、FireFox等很多浏览器支持。JavaScript使用的是面向对象的编程方式,也基于原型,还可以用命令式编程的方式,特点之一就是可以使用函数的方来编程。函数功能很强大,为文本的控制提供了约束,正则表达式等,但是JavaScript有一个缺点是不支持I/O,但是我们可以通过宿主环境的方式来解决这一问题。
    很多人会觉得Java语言和JavaScript语言有很多共同之处,其实从本质上来看这两个语言是有很大的区别的,首先JavaScript的语言设计主要受Self(基于原型的编程语言)和Scheme(函数式编程语言)两种语言的影响。在语法结构上其实是受C语言的影响较多,所以在语法上跟C语言很像,这些都是由于历史发展因素而产生的,所以相似的语言其实也存在很多本质上的差异。JavaScript语言常用来编写脚本,而且JavaScript语言在现在很瘦大家的喜爱,比如:游戏开发,桌面APP的设计等,总之,JavaScript的使用使得整个开发过程变得更加方便快捷。
    既然JavaScript可以认为是一种解释性语言所以我们必须考虑它的放置地方,通常来说JavaScript可以放在网页的任何地方,如果将其放在body的代码中会在网页加载的时候就开始执行,如果你不需要在加载的时候就运行他,可以将其放置在head中,这时就会在函数调用时才执行。总之,javaScript语言使用很简便,而且很安全,主要它还是一种动态执行的代码块,只是用来显示网页的效果,进行实时交互的语言,是开发者很好的选择。
    1.4 JSP技术介绍JSP也是一种Java语言,它是java语言中的一种的特殊语言,Jsp是通过加入引擎的方式来实现页面的动态交互,这样,可以让客户不用去接触复杂的Servlet,还没有开始执行就需要加入代码的难题。JSP的使用让基于Web的服务客户端更加灵活,如引入文件,网页跳转,这些工作都是由引入的java Servlet 自动生成的,而且这些应用程序能和Web服务器、应用服务器、浏览器和开发工具共同工作。 从而使我们第一次运行JSP时cpu运行可以达到很高的状态。
    Jsp时一种跨平台的语言,可以在不同的系统环境下运行,Windows、linux、Mac下都可以。同时这种跨平台的特性使得他实现了一次编写多次使用的特点;通过向传统网页HTML文件中加入Scriptlet和tag标记,就建成了JSP网页文件。一般情况下使用Html来设计网页的静态部分,而使用Jsp来实现网页的动态部分,从而就实现了业务代码的分离,我们可以通过Servlet,来处理业务代码,或者可以交给JavaBean来处理业务代码,这样,Jsp就用来实现显示数据部分就可以了,这样的化如果我们需要修改业务层的代码就不会对Jsp显示层的代码有影响了。每次服务器只要接受到JSP网页发送的请求消息时,它会去执行一些代码块,用可视化的方式在传给用户,通常是Html的形式。javaBean时Jsp常用的组件,用来分装业务代码,或者作为存储模型。
    JSP的使用为动态Web页面的开发带来了很大的方便,主要有一下几点的总结:

    将业务代码和数据显示层分离
    强调可重用的组件
    采用标识简化页面开发
    技术分析:常见的动态网页开发技术还有ASP。形式上和Jsp及其相似,但是ASP仅仅用于NT、IIS;而且ASP功能是由限制的;需要用COM来扩展,所以实现很难,所以经过分析会发现,二者在根本上有很大的差异,包括安全性,组件的使用等

    JSP的安全性更高,速度更快JSP的组件方式更方便JSP的跨平台特性使得平台更广

    通过向Jsp中插入的Java程序可以插入,删除,更新数据库的内容、URL新定向等,从而让网页变得动态灵活。JSP在服务器端运行,客户端只需要有浏览器就可以访问。JSP也具备Servlet的一些功能,通常要开发比较大型的Web应用程序,就需要两者相互配才能成功的完成。
    Jsp的特点主要总结为一下几点:

    一次编写,到处运行。使用了JavaBean组件,使得开发代码与试图显示代码分离开来,所以使得开发代码修改更加方便
    系统的多平台支持。Jsp可以不用修改便运行在各种平台中,可以随意的扩展,同时不同的操作系统的数据库也可以对JSP有所帮助。通过JDBC数据库连接来操作数据库,所以就提高了代码的可移植性
    强大的可伸缩性。Java具有很强的生命力,Jar文件存在就可以执行JSP代码块,多台服务器的继承来进行事务处理、消息处理
    多样化
    支持JavaBean等组件复用性。Web应用程序要成功的执行,就需要功能很强的服务器端组件,web 页面需要程序开发者用其他的工具来设计实现一些很繁琐的功能的组件来使用,目的是为了加强system性能。而JSP正好可以使用这些组件

    JSP内部对象主要有以下九个:request 客户端发出请求消息,请求主要是用GET/POST方法来传递的; response,主要是指服务器端对客户端的响应以及处理结果;session 用户的会话; pageContext 网页属性的管理;application servlet正在运行的内容都存储在这里;out 输出流; config 是为代码的配置对象;page JSP; exception 对网页的异常进行捕获。
    1.5 MVC模式介绍MVC是一种设计模式。它使得application program的输出,处理和输入强制分开。使用MVC application program 被划分成三个核心部分:控制器和视图还有模型。它们各自都有处理自己的任务。
    为了应对system对安全性、先进性。可扩展性、跨平台型、分布式、可以执性等方面等方面的需求,system的总体构架设计采用了比较先进的B/S的三层体系结构。
    三层体系结构由浏览器、web服务器和数据库组成,并结合HTML语言、jsp、JavaScript脚本语言、Ajax、ODBC等技术,后台的数据库采用微软的MySQL 2005,MVC的特点主要有:
    1、低耦合性业务层和低视图层相分离,这样就可以允许修改视图层code,而不用再一次变异控制器和模型code。所以,MVC层模型变化了,就可以实现应用的业务规则和业务流程的变化。由于视图,控制器,模型三者是分离的状态,所以application program得date层和业务规则很容易被更改。
    2、重用性高随着技术一直以来的进步和发展,application program需要用更加多样的方式来访问。MVC模式下不同的界面可以使用同一个构件,由于MVC模式下对同一个构件的访问往往使用的是多种多样的界面来实现的,多样的视图可以共享一个模型,这些构件涵盖所有的web浏览器和远程浏览器无线端。例如,顾客可以使用手机或者个人PC来选购某些产品,即便是他们使用的不同的浏览器不同的平台,但本质上他们购买的方式是一样的;因为MVC模型对用户所返回的代码没有改变所以本质上是一样的。
    3、部署块mvc模式之所以会使得开发的时间得到降低,是因为它将程序员的精力转移到视图层,开发人员无需花费很大的时间去研究组件功能等。
    4、增强维护性不同的层次有不同的功能但是也会有些功能具有相似之处,很有利于更具化管理模式。我们可以用控制器连接不一样的视图和模型等,在完成用户的需求,application program提供的一些手段就此就可以得到很好的使用。同时,控制器为我们提供了一些可以重复使用的模型等并对其进行不同的处理,最后展示给客户。
    缺点
    要完全的理解MVC需要有名明确的定义要想真正的理解MVC模式就要投入很长的时间去细心研究它复杂的内部结构。调试程序相对较为困难,由于控制层和试图层时分离的,所以阅读较为困难。进而对控件的修改就变得不时很简单
    对于小、中规模的application program 并不合适使用。因为将会浪费过多的时间将MVC应用到小、中规模的情况,效果不好
    增添System结构与实现的复杂度,设计较为简单的用户界面,如果也是严格遵循MVC模式,让其视图、模型和控制器分开三个层次,无形中加大了简单程序设计的复杂度,甚至会使得用户操作困难和运行困难等问题
    控制器与视图之间太过紧密;对于一些要求视图和控制器联系不要过于紧密的程序设计我们会发现,视图要是和控制器分开单独存在,会变得很局限。反过来也是这样,所以遇到需求不同的时候就会影响程序开发


    视图不能高效的访问数据,由于模型操作接口之间会存在一些差异;视图要想显示用户所需的数据可能需要多次调用接口。如果在没有更新的情况下;用户会做很多次的无用访问,从而使得用户体验下降
    通常常用的UI工具,或者构造器不能够支持模式的改造此类工具,用来适应MVC所需求和构筑离散的部件的成本是非常不低的,以至于影响MVC在应用上的难易度

    1.6 SSH框架介绍SSH框架是一种被大众所喜爱的开源性框架。主要包括了业务逻辑层、数据持久层,表示层,模块层四个层次,这些层次可以帮助开发人员对搭建结构,维护系统,框架重用等,也可以给开发人员提供一个清晰、易懂,简洁明了的设计思路。价值SSH框架可复用性好、维护方便使之更加好用。
    SSH框架中Struts作为整体框架的基础实现MVC分离的任务,在它对应的部分,常常用来实现业务跳转功能;Hibernate框架负责数据持久化;管理数据Spring,同时也对struts和hibernate管理,使得系统变得有条不紊,文献[1]了具体的实现过程是:Spring根据需求提出一些模型,然后实现Java对象,再去编写Data Access Objects接口最后给DAO实现在作出请求;最后把这些都统一交给Spring管理。
    我们对各个框架做一个详细的解释:
    Spring框架Spring Framework 是用Apache许可的形式来发布的,是一个开源的Java/Java EE应用程序框架,同时是一种全功能的栈;也有一切其他平台的移植版本;Spring Framework使开发变得简单容易了很多,这种简单的开发方式就会让那些产生可能使底层代码复杂混乱的代码不会出现。避免了大量的复杂类和文件的产生。本系统主要使用了Spring的IOC容器进行对象依赖的管理,同时使用了Spring提供的AOP功能来进行登陆权限判断、异常处理等。
    Hibernate框架Hibernate的设计是数据持久化的保证,着一层为我们提供了基于Java语言的对象关系,和一些映射解决的方案;万望要实现面向对象领域的模型到传统关系型数据库映射模型的手就需要用到这个层次,开发人员可以通过使用Hibernate,对我们来说设计草案,遗留数据库构建都变得非常简单快捷。
    Hibernate让开发人员从手动处理数据映射的方式种解放了出来;文献[2]介绍了它可以将数据Java类映射到到数据库表;可以实现从Java数据类型到SQL数据类型的映射,最重要的是它具有面向对象的数据查询检索机制,开发人员不需要手动的去连接数据库,这样就缩短了开发的周期。
    Struts框架同时MVC设计模式产生的一种成果性项目;Struts框架通过Jsp和Java Servlet 技术实现了MVC模式设计,是一种开源项目。并且在2004年成为ASF的顶级项目;同时还实现了基于Java EE Web应用的应用框架。MVC模式的具体实现,离不开Struts的使用;MVC主要有Model层(模型)、View(视图)、Controller(控制管理)三个层次结构,这样业务代码,三视图代码,控制代码分开来实现,变得简介明了,给开发人员和用户都带来了好的体验。
    2 需求分析与设计2.1 可行性分析在技术上医院挂号系统使用的java语言,java语言简单易学。开发平台用的是myeclipse和mysql数据库。数据库作为系统设计的核心技术也是很容易学习操作,在大学期间主修的是软件工程专业所以本系统开发实现在技术上是可行的。
    经济上本系统无需安装任何软件,只要在可以访问Internet的环境下,在客户浏览器端输入网址即可访问,所以经济上是可行的。
    法律上本系统使用的都是开源的代码,且不存在侵权等问题所以法律上是可行的。
    2.2 需求分析2.2.1 概述需求分析是指通过开发者和用户的沟通来成系统应该做什么,并且评估出软件的资金使用和可能存在的风险,是整个系统实现的关键一步。
    就本系统而言,文献[3]医院挂号系统有很大的用户需求,由于目前来看有很大一部分医院任然使用的是人工挂号的方式来排队挂号,给医院的就诊以及病人就医带来很大的困扰,由于需要人工处理以及长时间的排队,人员流通性和不确定性从而引发了就医的高峰和低谷,在高峰期人多导致医生脾气暴躁,就医时间短,不仔细等问题,甚至存在一些医生走关系的不良现象;而低谷时期排队的人少,导致专家无所事事,医院资源浪费等;通过医院挂号系统,我们可以很快地解决这些问题,可以减轻医护人员对信息管理的负担,同时减少了患者不必要的等待,以及时间的浪费,同时有利于医院治安管理提高医院的管理,提高医院的效益。
    医院挂号系统是指患者可以通过访问网站的方式来预约看病的系统。其意义在于方便患者就医,提高医院医生资源的利用率,提高医疗服务水平等;他的使用将会给医疗界带来新的革命。对所有医院施行预约挂号系统服务后不仅患者进行就医咨询变得很是方便,而且对意愿来讲,能够合理的分配医院的医生资源且不浪费,从侧面看,极大的提升了医院的管理水平,还可以很大程度的提高医生工作效率,解决看病问题,便利民生问题的同时还带来了经济上的发展。
    在我们国家也有很多医院已使用了在线挂号系统;文献[4]中说明,从使用情况分析,我们对系统的管理方面还存在很大的弊端,比如有个人或者团体通过此种方式来谋取暴力;导致,医院预约挂号系统服务没有的到正真的合理使用,这样没有给病人就诊带来方便、没有给医院带来方便,还被很多病人和医院管理者,医护人员反感抵制。
    所以,对每一次系统的实施,我们需要办法一些相关的规章制度,约束这些不合理的使用现象。不仅要正确的让医院开展预约挂号系统的实施,而且要文明绿色的实行这些工作的计划;全面提高人们对预约挂号服务工作的认识、全面加强对预约挂号服务工作的管理计划、认真搞好相关组织工作的内容;一切都要坚持本方便群众就医,搞好医疗事业建设,合理的运用前沿技术来服务农民,发展社会。
    2.2.2 挂号用户网上预约挂号要实现较好的网站设计,首先这个网站必须具有良好的稳定性和较高的安全性,对开发的后期来说要易于维护;对网站首页的设计要有基本的菜单导航设计来引导新用户的正确操作,方便患者的使用。
    对于医院的信息设计部分;经过对不同科室的信息进行细致的分类方便用户对照自己的症状合理,正确的来挂号;对不同医院的专家信息进行分类,专家情况信息介绍要详细全面,防止患者对信息理解错误挂号错误的现象发生,进而让用户能作出正确选择;用户通过查看专家信息,选择专家,选择挂号日期;实名填写个人信息、家庭住址、联系方式等信息成功的实现网上预约挂号。

    挂号方式患者通过在浏览器端输入网址进入预约挂号系统的首页,查询医院医生信息,点击预约挂号,填写个人信息,实现网上成功预约之后,根据自己的预约信息去医院就诊。
    2.2.3预约须知对在线医院预约挂号系统的总体说明主要有一下几点:愉悦着要提前看网站对挂号者预约所注意事项、以及预约挂号人的权利和义务,权责声明、对于自己不清楚的地方要及时的查看系统使用帮助。
    进入网上预约挂号的平台后,根据自己所在地区选择需要挂号的医院。进入医院网站首页,初次登陆系统预约的用户,需要先注册才能登陆系统进行操作挂号;如果是复诊输入用户名和密码,即可登陆系统。系统可以自动核对登陆者的信息,登陆成功后,可进入预约挂号程序。
    需求分析种我们会发现,医院预约挂号系统中需要管理的信息主要有以下几种:

    医生:姓名、性别、科别、擅长、年龄、就诊时间
    挂号单:科别、挂号单号、编号、费用
    病人:姓名、性别、年龄、联系方式、症状、挂号单号

    对于单号的处理部分,一张挂号单只可以对应一个医生;一个医生可以有多张挂号单,但是日期时间不能冲突,一张单号也只能对应一个病人,一个病人在同一时间只可以预约一张单号、一个患者可以选择多个医生,一个医生可以看多个病人。
    2.3 开发环境医院挂号系统采用的是Myeclipse软件开发平台,mysql数据库以及SSH框架技术,开发环境为windows xp 系统用户无需安装任何软件,只需在浏览器端输入网址即可使用,使用非常方便,对开发人员的维护工作也很方便。
    3 系统分析与设计3.1 系统概述系统设计是继需求分析之后的重要一步,目的是根据对用户的需求分析将其逻辑方案转换成物理方案。同时要注意系统设计的内外环境以及主观条件和客观条件,未来确保系统总体目标的实现,我们要考虑到经济,技术各方面的条件,来做出合理的技术方案,选择出合适的设计平台以及开发环境。系统设计要坚持阶段性开发原则对不同的阶段设计出不同的实现功能;其次要本着为客户服务的原则,尽可能的坚强客户使用的难度,同事要坚强管理人员的负担,尽量使用自动化的处理方式来处理数据,以及要具有良好的设计体验;对用户的需求变更要及时的处理,同时,最重要的是实现系统的可扩展性,减少各个模块的耦合性,使系统便于扩展与维护;系统设计中很多工作是有技术性的,再设计过程中要考虑到用户需求的变更,是系统设计完成的一个必要阶段。
    3.2 系统功能系统功能主要是实现患者在线预约挂号,对网站来讲,我们将其分为前台功能和后台功能两个模块。
    系统前台功能图如下图所示,我们又将前台功能细分为三大块功能,分别是:信息展示模块、系统应用模块、用户模块。


    信息展示:展示出专家的信息,医院信息等
    系统使用:完成登录注册等功能
    用户:登录,查询、预约挂号等


    我们对后台模块功能分析如下:

    修改密码:用户、管理员对自己的个人密码进行修改操作
    系统公告的管理:管理员来实现医院公告的管理
    专家信息管理:对专家信息进行添加和删除等操作
    注册用户管理:对用户的个人信息进行管理
    医院信息管理:对医院的信息进行添加和删除等操作

    3.3 用例图3.3.1 会员用例图用户可以:在线注册会员,在线查询医生信息,在线预约挂号等。

    3.3.2 管理员用例图
    管理员可以对医生信息的数据库信息进行合理的变更;对医院的信息进行添加或删除,对会员的信息进行和管理以及对医院公告的信息进行更改等。
    3.4 流程图
    用户可以在网站的主页看到信息查询的按钮并对想要查找的信息进行填写,然后根据查询结果进行预约挂号填写个人信息,同时如果不想预约,可以进行取消预约的操作。

    管理员在系统首页的“系统管理员登录”出输入自己的账号和密码进行登录,然后进入管理员界面,可以对医院的信息以及医生的信息进行添加和删除操作;同时也可以管理用户的信息。
    4 数据库设计4.1 数据库设计概述MySQL是一种SQL数据库的管理系统,受到很多人都欢迎因为其具有开源性的特点。它是由一家商业公司MySQL AB进行了设计开发和发布的,这家公司主要是对MySQL数据库开发,这家公司的注册商标就是Mysql;它拥有成功的商业模式,巧妙地使用了其开源性,方法论的第二代开源公司对于MySQL AB公司的发展历史我们在这里就不做过多的赘述了。
    MySQL是一个快速的、多线程、多用户和健壮的SQL数据库服务器。文献[8]中介绍MySQL服务器支持关键任务、重负载生产系统的使用,也可以将它嵌入到一个大配置(mass-deployed)的软件中去。MySQL网站( http://www.mysql.com )提供了关于MySQL和MySQL AB的最新的消息。
    数据库在动态网页设计中发挥了重要的作用,文献[6]中介绍到它好比一个大仓库,对网站的重要信息进行存储,由于网站的网页不是一成不变的,他需要及时的变更,所以要使用到数据库,有了数据库开发人员对网站内容的管理更加方便,维护也更加方便,所以数据库的设计是系统成功实现的关键之处。该系统的设计主要是用了mysql 数据库来设计数据库,简单方便,下面我们主要说明下数据表和数据表结构。
    4.1.1 表说明主要的数据表有db_guahao表,此表又包含t_gonggao系统公告,t_zhuanjia 专家信息,t_guahao医院信息;,t_yiyuan医院信息管理系统,t_use注册用户的信息;r,t_admin管理员信息;t_keshi科室信息表等。

    4.1.2 表结构说明


    5 系统的实现5.1 网站首页设计网站设计的首页设计是至关重要。因为第一个映入用户眼睑的就是网站的首页,它的好坏直接影响了用户对网站的喜爱程度;在对首页设计上我们要内容丰富的同时又要有一定的色彩搭配以及上下呼应等特色,以下是本网站的首页:

    5.2 网站引导设计网站的导航视为了使用户使用更加方便灵活,能使网站有一个较好的用户体验,提高用户的满意度,他是网站的路标,可以提示用户如何操作,就像字典查询需要目录一样,网站设计也需要这样的“目录”,从而让用户更加明确的知道下一步该如何操作,以及自己所处的位置;网站导航主要可以通过文字导航、按钮导航、Flash导航等,本网站的导航设置如下图所示:

    5.3医生信息模块本网站的主要功能是患者挂号功能,刚进入网站用户需要对自己的病情进行分析以及查询相关的医生才能更准确的完成预约挂号,所以医生信息也是网站设计的一个重要元素,专家展示模块主要包括显示医生列表、显示医生详细信息两个部分。
    患者点击相关的医院便会出现该医院的相应专家信息如图所示:

    该页面的设计代码如下:
    zhuanjiaAllByYiyuan:主要是通过数据库查询获取相关信息然后通过JSP页面传递给用户:
    public String zhuanjiaAllByYiyuan(){ String sql="from TZhuanjia where del='no' and yiyuanId="+yiyuanId; List zhuanjiaList =zhuanjiaDAO.getHibernateTemplate().find(sql); for(int i=0;i<zhuanjiaList.size();i++) { TZhuanjia zhuanjia=(TZhuanjia)zhuanjiaList.get(i); zhuanjia.setKeshi(keshiDAO.findById(zhuanjia.getKeshiId())); zhuanjia.setYiyuan(yiyuanDAO.findById(zhuanjia.getYiyuanId())); } Map request=(Map)ServletActionContext.getContext().get("request"); request.put("zhuanjiaList", zhuanjiaList); return ActionSupport.SUCCESS;}public String zhuanjiaDetailQian(){ TZhuanjia zhuanjia=zhuanjiaDAO.findById(id); zhuanjia.setKeshi(keshiDAO.findById(zhuanjia.getKeshiId())); zhuanjia.setYiyuan(yiyuanDAO.findById(zhuanjia.getYiyuanId())); Map request=(Map)ServletActionContext.getContext().get("request"); request.put("zhuanjia", zhuanjia); return ActionSupport.SUCCESS;}
    5.4 用户注册挂号模块用户查看相应的医生信息后可以对自己喜欢的医生进行预约,点击预约挂号按钮后会出现挂号注册页面,如下图所示:

    用户可以在相应的位置填写所患疾病,姓名,联系方式,和选择挂号日期来完成挂号。
    5.5 管理员登录页面管理员在网站里的主要作用是对患者挂号信息,医生信息,医院信息等进行管理,所以需要单独的来设计一个界面与用户区分开来,用户的登录界面在网站首页右侧,而管理员可以在网站首页下方找到管理员登录的图标,点击即可进入管理员登录的界面,登录界面中登录进入后才可以对网站信息进行修改管理等。管理员在网站的下方点击管理员登录按钮,输入自己的账号,密码进行校验后即可进入管理员登录界面,如下图所示:

    对管理员进行校验的代码:
    public String login(String userName,String userPw,int userType){ try { Thread.sleep(700); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String result="no"; if(userType==0)//系统管理员登陆 { String sql="from TAdmin where userName=? and userPw=?"; Object[] con={userName,userPw}; List adminList=adminDAO.getHibernateTemplate().find(sql,con); if(adminList.size()==0) { result="no"; } else { WebContext ctx = WebContextFactory.get(); HttpSession session=ctx.getSession(); TAdmin admin=(TAdmin)adminList.get(0); session.setAttribute("userType", 0); session.setAttribute("admin", admin); result="yes"; } } return result;}
    校验成功后可进入管理员主页面如图所示:

    管理员在这个页面能对自己密码修改,可以对医院的信息,医生信息,会员信息进行增加删除等,完成相应的操作后即可点击注销退出系统来退出管理员页面。
    5.6 医生信息管理模块医生信息管理是需要系统管理员来完成的,主要是让系统管理员对医生信息及时的更新,在上一步的页面中点击医生信息管理,即可实现对医生信息的添加,修改,删除等操作,界面如下图所示:


    医生信息处理模块的代码主要有:
    zhuanjiaAction:public String zhuanjiaAdd(){ TZhuanjia zhuanjia=new TZhuanjia(); //zhuanjia.setId(0);] zhuanjia.setYiyuanId(yiyuanId); zhuanjia.setKeshiId(keshiId); zhuanjia.setXingming(xingming); zhuanjia.setXingbie(xingbie); zhuanjia.setNianling(nianling); zhuanjia.setShanchang(shanchang); zhuanjia.setLeixing(leixing); zhuanjia.setFujian(fujian); zhuanjia.setDel("no"); zhuanjiaDAO.save(zhuanjia); Map request=(Map)ServletActionContext.getContext().get("request"); request.put("msg", "信息添加完毕"); return "msg";}public String zhuanjiaMana(){ String sql="from TZhuanjia where del='no' order by yiyuanId,keshiId"; List zhuanjiaList =zhuanjiaDAO.getHibernateTemplate().find(sql); for(int i=0;i<zhuanjiaList.size();i++) { TZhuanjia zhuanjia=(TZhuanjia)zhuanjiaList.get(i); zhuanjia.setKeshi(keshiDAO.findById(zhuanjia.getKeshiId())); zhuanjia.setYiyuan(yiyuanDAO.findById(zhuanjia.getYiyuanId())); } Map request=(Map)ServletActionContext.getContext().get("request"); request.put("zhuanjiaList", zhuanjiaList); return ActionSupport.SUCCESS;}public String zhuanjiaDel(){ String sql="update TZhuanjia set del='yes' where id="+id; zhuanjiaDAO.getHibernateTemplate().bulkUpdate(sql); Map request=(Map)ServletActionContext.getContext().get("request"); request.put("msg", "信息删除完毕"); return "msg";}
    5.7综合查询平台5.7.1 医院信息,科室信息,医生信息查询对不同的医院进行查询,对不同科室信息查询、对所有专家信息的查询,可以按照网站的导航进行大概的查询,每次查询不用特别精确的填写所有信息,但是如果患者希望可以精准的查询就必须填写完整的信息来查询。

    5.7.2 预约状态查询和取消预约对于患者查看自己的预约信息以及是否预约成功,时间是否过期,事件是否正确,以及预约的具体信息等。对于用户临时会发生的冲突事件如在预约后,又有了新的事情冲突不能去就诊,患者可以登录系统点击信息管理,查看自己的网上预约挂号信息,修改自己的信息或者取消预约。对于取消预约的操作只能在预约日期之前进行过期后就不可以取消了,取消时需要患者填写姓名、取消原因等信息,信息填写完毕后就完成了取消预约的操作。
    5.7.3 停诊信息查询查询医院最近的就诊情况、自己所在区域的医院公告,包括停诊信息,方便患者能及时的正确的作出选择。
    5.7.4 注册信息查询 用户注册后有自己的主页,可以点击个人信息管理来实现注册信息的查询更改等。

    5.8 退出管理登录页面退出后台管理模块是管理员用于退出后台管理系统的。管理员退出后台管理系统之后,需要单击【退出】按钮,此时虽然还在后台中但已不能对数据库进行操作;这时候单击其他功能模块时,将弹出后台登录窗口要求用户输入正确的用户名、密码以及验证码。

    总结经过自己不断的努力以及老师同学的细心帮助我完成此次毕业设计,同时也学会了很多只是,通过对各种文献资料的查阅,使我增长了不少的知识;医院挂号系统的成功完成过程是艰苦的,但是结果是令人欣慰的,在此过程中我学习了很多新的知识,比如数据库设计方面,jsp 、javascripts编程等。让我成长了很多。虽然此次完成毕业设计老师没有给我吗分组,但是这实际上并不是我一个人努力的结果,有老师同学的帮助让我能真正的完成毕业设计,真心的感谢他们,同时让我总结出至关重要的一点就是要及时的与老师同学进行沟通交流,要互相团结,我意识到团队意识的重要性,这次毕设让我有了一定的实践基础,很有利与我动手能力的提高。同学老师的各种意见使我完成医院挂号系统的设计,他们的想法设计思路也对我有很大的帮助。
    写毕业论文期间,我深刻的认识到实践到理论的重要性!在实践到理论的转化中,我将自己的工作过程清晰的展现在面前,对资料的查询,如何很好的笔记等有了很大的收获,获得了一些必要的知识的同时,也掌握了很多获取知识的重要途径。在繁杂的设计中,我能够清晰的找准自己的目标,各种系统的设计计划,以及选用标准,各种语言的用途等等,这些内容都是我在不断深化论文的过程中不断的熟悉和应用的,有了老师们的指导以及同学之间的思想交流,让我对论文设计有了更加丰富的理解和掌握。同时,在自我总结中更加全面的改正自己存在的缺陷和风险,让自己在大学四年里所学的理论知识得到很好的发挥;更重要的是,我意识到在信息化的时代,我们需要正确的使用我们的高科技,争取在今后的工作中不断的学习不断的进步,为社会的发展作出自己的一点点贡献,面对压力挑战能像这次毕业设计完成一样去解决所有的问题、困难;面对问题不胆怯不懦弱。对自己的工作一定要一丝不苟,脚踏实地的去做每一次任务,在软件领域发出自己的光芒。
    3 评论 71 下载 2020-07-16 12:29:44 下载需要13点积分
  • 基于JAVA EE的失物招领系统

    摘 要随着社会、经济和科学技术的不断进步发展,快节奏的生活方式让学生在校园生活中频繁出现丢失物品的状况,使学生遭受了经济和精神上的伤害。如今,丢失物品已经成为一个普通存在的问题,追寻一种高效率且有秩序的失物招领管理方式是当前社会共同向往的。失物招领工作信息化管理的实现有了必要性,只有信息化手段的介入,才能成为失物招领的一个方便可行的解决方案。本系统设计了基于JAVA EE开发的嘉园失物招领系统,失主可以通过网络进入到本系统的Web客户端查询自己丢失的物品是否已经发布到失物招领系统上,或者可以发布自己丢失的物品信息,使拾取到物品的人可以联系到失主,捡到物品的人同样可以发布拾取物品信息。管理员通过系统Web管理后台对寻物信息,招领信息,失物类别进行管理。一个良好的信息交流平台,使师生和工作人员能够及时找到失物,给校园生活带来了极大的方便。
    关键词:失物招领,系统设计,Web端,Java语言
    AbstractWith the continuous advancement of society, economy and science and technology, the fast-paced lifestyle has caused students to frequently lose items in campus life, causing students to suffer economic and mental damage. Nowadays, lost items have become a common problem. Pursuing an efficient and orderly management method of lost and found is the common aspiration of the current society. It is necessary to realize the information management of lost and found work. Only the intervention of information technology can become a convenient and feasible solution for lost and found. This system has designed the Jiayuan Lost and Found system based on JAVA EE development. The owner can access the Web client of the system through the network to check whether the lost items have been released to the lost and found system, or can publish the information of their lost items. The person who picks up the item can contact the owner, and the person who picks up the item can also post the items information. The administrator manages the search for information, claim information, and lost property category by web management backstage. A good information exchange platform enables teachers and students and staff to find lost property in time, bringing great convenience to campus life.
    Keywords: lost and found, system design, Web, Java
    引 言在如今信息发达的时代,快节奏的生活方式让学生在校园生活中频繁出现丢失物品的状况,使学生遭受了经济和精神上的伤害;从古至今,丢失物品就是一个普通存在的问题,追寻一种高效率且有秩序的失物招领管理方式是当前社会共同向往的。失物招领工作信息化管理的实现有了必要性,只有信息化手段的介入,才能成为失物招领的一个方便可行的解决方案。一个良好的信息交流平台,使学生失主能够及时找到失物,给校园生活带来了极大的方便。
    本系统采用了基于JAVA EE开发的嘉园失物招领系统,此失物招领系统是为失主和捡到物品的人搭建的一个信息交流平台,失主可以通过网络进入到本系统的Web客户端查询自己丢失的物品是否已经发布到失物招领系统上,或者可以发布自己丢失的物品信息,使拾取到物品的人可以联系到失主;捡到物品的人同样可以发布拾取物品信息;管理员通过系统Web管理后台对寻物信息,招领信息,失物类别进行管理。
    第1章 绪论1.1 项目背景当今,各大高校地域范围广、人口密度大,在校园生活中,学校师生经常来往于教师、图书馆、食堂等场所,随身物品如书籍、钥匙、饭卡、银行卡等生活用品难免容易丢失。即使有时丢失的是一些小物品,却可能对于失主来说有特别的意义和重要性或者包含失主的重要隐私。在信息技术时代,传统寻物招领方式已经不能满足人们的需要。传统张贴寻物启事、招领启事,其效率低、保密性差、管理不集中。易使失主遗忘,难以获取相关信息;从而给失主造成不必要的经济损失,同时也增大了管理人员的工作量。随着信息技术的迅速普及, 校园也慢慢地利用信息化技术进行管理[1]。开发校园失物招领系统,极大地提高认领率,减小失主经济损失,从而能够更好的服务于学校师生和工作人员。
    在国内外,失物招领系统在一些地区已经有了一定了发展,而且各地区有独自的特色的失物招领管理系统。相对于了国内,国外的失物招领系统开发较早,关注性强,用户通过账号密码登录系统查询失物,对于失物采取了现代信息化管理,具备了完善的失物数据库,管理效率高。在亚洲地区,各种失物招领机构遍布,可是依然采用人工管理的方式,其工作量巨大,物品运送规格难度艰巨,而建立一个网络数据库,可以免于失主奔波于各个失物招领机构。我国对于失物招领系统的建设工作也很重视,很多高校和地区同样建立了自己的失物招领管理系统。
    1.2 项目目的和意义开发该项目的目的是为了对于失物招领工作进行更加信息化、系统化、平台化的建设,而拾金不昧可以在一定层面上反映出学生的精神文明素质、道德修养水平、综合素质深度,对于拾金不昧的学生给予表扬和宣传是对当代大学生在道德修养、精神文明上的一种激励,一种正能量的鼓舞,使校园文化建设更加顺畅和谐。开发失物招领管理系统是一件迫在眉睫的事情, 并且该系统是基于网络的, 失主可以在网络上查询和报失以及确认[2]。通过功能模块的优化组合实现可以让失主在网络上发布失物,更加有利于找回自己的物品,拾取者也可发布失物信息,失主通过失物招领网络平台可以确定失物信息并招领,失物招领在线交易平台是为失主与拾获者之间进行失物招领提供的一个平台。有效的减少了工作量,便利了广大的师生及工作人员。失物招领网络平台的开发可以解决校园师生丢失物品的管理, 可以让失物招领部门工作人员高效的管理丢失物品, 降低工作人员的工作量, 以及方便全校师生, 使得师生在丢失物品后能够及时找回[3]。
    1.3 论文主要内容和结构安排本文介绍了基于JAVA EE的嘉园失物招领系统的设计与开发。

    第一章是绪论部分,对失物招领系统大致情况进行了简要介绍,简述了项目背景、项目目的和意义
    第二章是系统设计的技术和开发环境,介绍了系统开发所用到的关键技术,开发使用的语言和使用的开发环境
    第三章是对系统进行了整体的需求分析,工作流程的详细分解,功能模块的整体介绍
    第四章是系统的总体设计和详细设计分解,阐述了系统的各个功能模块的业务逻辑和数据结构
    第五章包括对系统的功能测试,整体研究工作的总结,对系统开发的过程和结果进行总结和展望

    第2章 系统涉及的技术和开发环境2.1 前端2.1.1 HTML超文本标记语言(HyperText Markup Language),标准通用标记语言下的一个应用。是网页制作必备的编程语言。“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。超文本标记语言的结构包括“头”部分(英语:Head)、和“主体”部分(英语:Body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容。
    2.1.2 CSS正层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。
    2.1.3 JqueryjQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。jQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
    2.1.4 AngularJSAngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVC(Model–view–controller)、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。
    2.2 后端2.2.1 JavaJava是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
    2.2.2 MySQLMySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
    2.2.3 XML语言XML全称是Extensible Markup Language,即可扩展标记语言。XML技术是W3C组织发布的,目前推荐的国家标准是W3C组织于2000年发布的XML1.0规范[4]。
    2.3 开发环境2.3.1 MyEclispeMyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java、Java EE以及移动应用的开发。MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持相当不错。
    2.3.2 Navicat PremiumNavicat premium是一款数据库管理工具,是一个可多重连线资料库的管理工具,它可以让你以单一程式同时连线到 MySQL、SQLite、Oracle 及 PostgreSQL 资料库,让管理不同类型的资料库更加的方便。
    第3章 系统需求分析3.1 系统总体功能
    3.2 系统功能概述失物招领系统主要为了让在校师生及工作人员能够便于发布寻物信息和拾取物品的信息,还有通过失物招领系统进行丢失物品的检索等一些问题。大学生课外活动较多, 随身物品较多, 经常活动于不同的场所, 遗失物品的现象时有发生[5]。但是由于没有任何便利的平台来发布失物信息,使得很多人无法获取与之相关的信息,太多的失物,尤其是那些对失主很重要、但对拾得人却毫无价值意义的物品,如有效证件、钥匙,却再也找不回来[6]。这便使传统的失物招领工作中心带来了极大的工作量。而本系统的设计正是让在校师生及工作人员可以快速的对于失物进行检索和发布。
    3.3 系统需求概述失物招领系统服务于校园内的学生、教师和工作人员,该系统运行与校园网内,由失物招领处进行管理维护。失物者通过网络接入Web服务器, 向Web服务器发送各种请求[7]然后发布寻物启事信息,系统针对于每一个寻物启事提供相应的评论功能,其他人员可以访问系统查看各个寻物启事为失物者提供相关信息及线索。失物者在发布寻物启事信息的时候会要求填写管理密码,失物者可以通过该管理密码对相应的启事进行删除、修改操作,如若失物者已经获取了失物的相关线索,可以对该寻物启事进行删除操作,以保证失物者以及线索提供者的信息安全。拾物者可以发布招领启事信息, 拾物者在捡到失物的时候可以访问该系统,发布招领启事信息,填写信息或亦可上传相关图片等待他人认领。失主在失物招领系统中检索到自己的失物可以通过该招领启事信息中的联系人与拾物者联系。拾物者在确认物品已经被失物者领走以后,就可以访问系统将该招领启事信息删除。为了用户的信息安全,本系统对数据进行优化处理,如果发布的启事信息在六个月内未被删除,则启事信息的所有联系方式将成为报名状态,如果一年内未被删除,则启事信息将会被系统自动删除。
    管理员同样可以发布失物招领信息,同时,管理员可以登录失物招领管理后台,用户所有启事发布都会经过管理员审核,只有当管理员审核通过时,启事信息才会发布到系统上。管理员也是可以对失物分类、寻物启事、招领启事进行管理操作。
    3.4 功能需求分析3.4.1 管理员登录模块针对于校园环境的特殊性,管理员一般为校园失物招领处的负责人,只有知道管理员登录用户名和密码才可以进入失物招领管理后台。登录过程中实现安全登录,避免恶意登录、暴力破解或者通过直接输入路径进入失物招领管理后台。
    修改密码,如果管理员要进行密码修改,只有通过安全登录到失物招领后台才可进行修改密码操作,通过输入原密码和两次新密码即可完成修改密码操作。
    登录状态验证内部实现,用于验证管理员是否已经登录为能否正常使用功能的前提条件。
    3.4.2 物品审核模块当用户发布寻物启事或者招领启事时,并不会立即发布到失物招领系统上,而是需要经过管理员通过失物管理后台物品审核模块对于新发布的启事信息进行审核。管理员可以查看新发布启事信息详情,审核通过则发布启事信息,审核不通过则从数据库上删除该启事信息。
    3.4.3 首页展示模块管理员成功登录失物招领管理后台后,则显示失物管理后台首页,首页总共展示四项统计数据,分别为未审核寻物启事信息数量,总发布寻物启事信息数量,未审核招领启事信息数量,总发布招领启事信息数量。管理员可立即看到这四项统计数据,更加方便对于管理员快速对于待审核数据进行审核,提高用户体验性。
    3.4.3 数据统计模块对于失物信息数据的统计,不仅仅只包含首页展示模块中的数据统计。该数据统计模块,同样另外统计了四项数据,分别为寻找中寻物启事信息数量,已失效寻物启事信息数量,寻找中招领启事信息数量,已失效寻物启事数量。
    3.4.4 失物分类模块用户在失物招领系统中,在发布失物信息或者检索失物信息时,其失物分类是通过复选框来进行选择。失物分类的添加、修改、删除等操作则由管理员进行管理更新。
    3.4.5 寻物管理模块管理员对寻物启事信息进行管理,但管理员在失物管理后台不能够进行修改或者添加寻物启事信息,仅能进行查询和删除操作,显示页仅显示部分寻物启事信息,通过查看详情即可查看更多寻物启事信息。
    3.4.5 招领管理模块管理员对招领启事信息进行管理,但管理员在失物管理后台不能够进行修改或者添加招领启事信息,仅能进行查询和删除操作,显示页仅显示部分招领启事信息,通过查看详情即可查看更多招领启事信息。
    3.4.6 失物展示模块失物招领系统的失物展示, 用户进入系统主界面后即可查看到最新发布的失物招领信息,首页仅显示最新一周内发布的失物招领信息,如果首页没有查看到要寻找的物品,可以通过导航栏中的寻物启事或招领启事中进入完整启事信息列表,即可通过精准查询检索到需要寻找的物品。如果用户需要进行快速检索操作,可以进入导航栏通过快速检索输入物品特征进行快速搜索。
    3.4.7 失物添加模块用户通过访问失物招领系统首页即可查看到寻物启事发布、招领启事发布两个按钮,根据需求选择需要发布的信息按钮,进入信息发布页面,信息发布页面中有多条信息需要填写,其中带星号标识的表单是必须填写的。
    3.4.8 失物详情模块通过失物展示模块可以查看失物详情,每个失物展示模块都且仅有一个对应的失物详情链接。失物详情页面显示了该失物的所有信息包括图片。在失物详情模块中可以进行评论操作,管理启事操作。
    3.4.9 失物操作模块在用户发布启事信息时,要求用户填写相应的管理密码,在对启事信息进行相应的修改操作或删除操作时将会用到。用户通过点击管理启事而出现的下拉框中选择删除或修改操作后,输入相应的密码即可进行操作。当用户选择修改操作时,输入正确的管理密码后,则出现弹窗,用户选择需要进行修改的数据进行修改即可完成操作。当用户选择删除操作时,输入正确的密码后,可以进行删除操作,系统会再次提醒用户是否确认删除,用户进行相应的选择即可完成删除操作。
    忘记密码,用户在忘记自己当初设置的管理密码时,可以在填写密码的表单中点击忘记密码链接,则会出现一个弹窗,该弹窗会要求用户输入启事信息相应的信息编号,信息编号在启事详情信息中有显示,发送信息编号后,管理密码会发送到改启事信息用户的预留邮箱,邮箱为用户在添加启事信息时的必填项。
    3.4.10 评论操作模块当其他人员浏览启事信息时,可以对相应的启事信息进行评论。评论主要目的就是提供失物的线索,方便失主可以找回自己的物品。
    3.3 非功能性需求系统非功能性需求主要包括以下几个方面:
    (1)界面需求友好性
    Web模式长期使用时需要保证用户进入系统后可以寻找到主要的关注点,就是直接在首页显示一周内的失物招领信息,在页面变化时添加过渡动画,在加载数据量大的内容时需要显示加载动画,提高人机交互体验性。需要有简洁清晰的界面来形象的显示。
    (2)操作需求准确性
    所有操作应当简便易用,所有涉及数据操作的内容都需要对用户操作进行判断限制,所有关键操作如删除、新增、修改等都需要用户进行确认,防止用户误操作导致数据错误。
    (3)用户体验感
    简洁清晰的页面,整体交互简单直接,各页面之间切换流畅,可保留已打开的页面,所有信息保持时效性,保有充分的用户操作提示信息。
    第4章 系统设计与实现4.1 系统设计目标对于当今校园失物招领工作的独特性,工作量较大,工作繁琐性等特征,同样, 捡到物品的学生也因为缺少相应的平台而难以将物品归还给失主[8]。同学们在丢失物品之后不知道怎么有效找寻丢失的物品,很多的大学的论坛,qq群,微信群等等地方有很多这种消息,但是通过QQ群这些方式发送寻物启事和失物招领的消息受用户权限限制,传播效率并不高[9]。本文主要设计和实现校园失物招领系统。充分利用校园网络坏境,使用校园网,发挥信息化手段的特性,使失物招领信息传播速度快,发布和检索方便实时且支持Web端等特点,最大效率上保证了丢失物品和被拾取物品的信息快速发布,让校园内师生及其工作人员快速得到失物信息。
    4.2 系统总体功能设计模块失物招领管理系统主要分为两个部分,涉及前台和后台,主要的技术是基于Java语言,用户界面是bootstrap框架,可运行于Windows操作系统。主要包括管理员登录模块、失物招领模块、寻物启事模块等,系统整体功能模块划分流程图如下图4-1所示。

    本系统分为两个子系统,分别为Web前台子系统、Web后台子系统,两个子系统使用同一个数据库。Web前台子系统主要是用户使用来发布启事信息、浏览启事信息等操作,Web后台子系统增加了管理员操作部分,具有管理员登录、管理失物类别等操作。
    4.2.1 系统开发环境与平台
    运行环境: windows XP/win7/win8/win10
    开发环境:Windows 10
    使用语言:Java,javascrip
    引用框架:Spring、SpringMVC、Mybatis
    关键工具包:httpclient(调用系统服务)
    开发工具:MyEclipse 2017 CI和Navicat Premium
    数据库:MySQL
    引用开源库:Jquery、日期和时间库、Json解析库和单元测试库等

    4.3 系统架构设计4.3.1 传统架构采用这种架构存在的问题,模块之间耦合度太高,其中一个升级其他都得升级,开发困难,各个团队开发最后都要整合一起,系统的扩展性差,不能灵活的进行分布式部署。
    4.3.2 分布式架构把系统拆分成多个工程,要完成系统的工程需要多个工程协作完成。这种形式叫做分布式。采用这种架构的优点,把模块拆分,使用接口通信,降低模块之间的耦合度。把项目拆分成若干个子项目,不同的团队负责不同的子项目。增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。可以灵活的进行分布式部署。采用这种架构的缺点,系统之间交互需要使用远程通信,接口开发增加工作量。
    4.3.3 系统选用架构本系统采用的架构就是分布式架构,大大降低了系统的耦合度,可以对系统进行灵活的分布式部署。系统的结构主要分成为三层:数据层、服务层和用户层。数据库用于存储数据,使用数据库来实现。用户层通过HttpClient来调用服务层的提供的服务,服务层用于解析用户层的请求并根据数据库的信息处理Web前台客户端的请求。服务层运行于Java虚拟机上,用户层主要运行于Web浏览器上,负责信息的呈现和引导用户进行操作,服务层和数据层直接与数据库进行通信。服务层和用户层之间则通过网络进行通信。

    数据层以数据库的方式来实现,Web前台客户端和Web后台管理端使用的是同一个数据库,因此无需考虑信息同步问题服务层分为数据处理层和网络层,数据处理层从网络层得到用户层发送过来的请求进行处理并将处理结果通过网络层发送至用户层服务层和数据层之间的数据传输通过数据处理使用SQL查询语句和Mybatis框架的使用来访问数据库,数据层返回结果集合到服务层服务层和用户层的数据传输格式需要统一,因此服务层和数据层传输数据时统一使用JSON格式。即发生放将数据转换成JSON格式再发送出来。然后从JSON中提取出所需的数据
    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

    Model层主要负责实现具体业务功能的类
    View层是与用户的交互层,负责提交用户的请求和数据,并将后端的响应的结果返回给用户层,同时提供用户提交信息的验证功能
    Controller层负责项目中的业务功能实现流程的管理工作,哪些类来实现具体业务功能,结果在哪显示等由Controller层控制,同时还负责其他两层的通信,协助传递信息和负责重定向与转发操作

    4.4 系统数据库设计4.4.1 管理员登录管理员表中给出了各个属性的数据类型、长度及主外键说明。管理员信息中采用的Spring Security框架默认的BCrypt算法加密存储登录密码。
    BCrypt,是一个跨平台的文件加密工具。由它加密的文件可在所有支持的操作系统和处理器上进行转移。它的口令必须是8至56个字符,并将在内部被转化为448位的密钥,所提供的所有字符都具有十分重要的意义。密码越强大,您的数据就越安全。管理员信息表的设计如表4-1 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    管理员编号
    主键
    Bigint(20)
    不为空


    username
    用户名

    varchar(50)
    不为空


    password
    密码

    varchar(100)
    不为空


    phone
    手机号码

    Varchar(20)



    email
    联系邮箱

    varchar(50)



    4.4.2 失物分类当用户添加启事信息或者检索启事信息时,用户将采用下拉框的形式来选择失物分类,因此,失物分类由后台添加,主要有主键和分类名称两个属性组成,失物分类信息表中给出了各个属性的数据类型、长度及主外键说明。失物分类信息表的设计如表4-2 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    分类编号
    主键
    Bigint(20)
    不为空


    category_name
    物品分类名称

    varchar(50)
    不为空



    4.4.3 寻物启事寻物信息表除了包含失物所包含的属性数据类型、对应字段、长度、主键外,还包含了外键,表中详细的定义了失物的各类属性名称,还有两个比较特殊的属性,一个是审核状态,两一个是管理密码,审核状态包含0表示未审核,1表示审核通过,2表示审核未通过。寻物启事信息表的设计如表4-3 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    启事编号
    主键
    Bigint(20)
    不为空


    category_id
    分类编号
    外键
    Bigint(20)
    不为空


    lost_place
    失物地点

    varchar(50)
    不为空


    lost_time
    丢失时间

    datetime
    不为空


    infoTitle
    信息标题

    varchar(100)
    不为空


    rewards
    悬赏金额

    varchar(100)



    description
    详情描述

    text
    不为空


    images
    物品图片

    varchar(255)



    status
    审核状态

    int(1)
    不为空


    contacts
    联系人

    varchar(255)



    tel
    手机号码

    varchar(50)



    QQ
    QQ号码

    varchar(50)



    email
    联系邮箱

    varchar(50)
    不为空


    address
    联系地址

    varchar(255)



    password
    管理密码

    varchar(20)
    不为空



    4.4.4 招领启事招领启事信息表与寻物招领启事表类似,但是唯一一个不同的招领启事不含有悬赏金额属性,其除了常规的属性名称对应字段、类型长度的定义外,也是同样包含了一个失物分类信息表的外键,说明了外键关联表和其定义。招领启事信息表的设计如表4-4 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    启事编号
    主键
    Bigint(20)
    不为空


    category_id
    分类编号
    外键
    Bigint(20)
    不为空


    found_place
    拾物地点

    varchar(50)
    不为空


    found_time
    拾取时间

    datetime
    不为空


    infoTitle
    信息标题

    varchar(100)
    不为空


    description
    详情描述

    text
    不为空


    images
    物品图片

    varchar(255)



    status
    审核状态

    int(1)
    不为空


    contacts
    联系人

    varchar(255)



    tel
    手机号码

    varchar(50)



    QQ
    QQ号码

    varchar(50)



    email
    联系邮箱

    varchar(50)
    不为空


    address
    联系地址

    varchar(255)



    password
    管理密码

    varchar(20)
    不为空



    4.4.5 评论管理基于为了让物品找回能够有多种方式,实现了在查看物品详情信息后可以在详情信息底下留下失物信息,可以在不使用其他方式的情况下以另一种形式通知失主。评论信息表包含常规的属性名称对应字段、类型长度的定义。评论信息表的设计如表4-5 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    启事编号
    主键
    Bigint(20)
    不为空


    goods_id
    物品编号

    Bigint(20)
    不为空


    comment_text
    评论内容

    text
    不为空


    comment_time
    评论时间

    datetime
    不为空



    4.4.6 详情信息当我们查看失物的基本信息后,想要深入的了解失物的详情信息时,便可以点击失物进入详情信息页面,详情信息表包含常规的属性名称对应字段、类型长度的定义。详情信息表的设计如表4-6 所示。



    字段名
    说明
    键值
    数据类型
    备注




    id
    启事编号
    主键
    Bigint(20)
    不为空


    goods_id
    物品编号

    Bigint(20)
    不为空


    publish_time
    发布时间

    datetime
    不为空


    page_view
    浏览次数

    int(11)
    不为空


    status
    启事状态

    int(1)
    不为空



    4.5 Web管理后台功能模块实现4.5.1 登录模块的设计与实现登录模块的设计,众所周知想要对Web资源和其他后端内部信息进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。所以Spring Security框架在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全。所以,我们设计了Web管理后台的安全登录,采用了Spring Security框架具体实现。
    登录模块的实现,一个能够为基于Spring的企业应用系统提供声明式的安全防问控制解决方式的安全框架,简单说是对访问权限进行控制,应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。 spring security的主要核心功能为 认证和授权,所有的架构也是基于这两个核心功能去实现的。下图4-2就是权限认证未通过登录状态效果图。

    管理员输入正确的用户名和密码成功经过Spring Security框架权限认证后直接进入首页,登录后页面如下图4-3成功登录效果图。

    管理员安全登录系统之后,如若想要修改密码,可通过界面点击修改密码按钮,按标准填写原密码与新密码即可完成操作。下图4-4为修改密码效果图。

    4.5.2 启事审核模块的设计与实现启事审核的设计,关于这模块的设计是为了防止用户恶意刷数据,还有用户发布的数据存在问题等一些问题,导致数据库无效数据的大量堆积,造成用户的体验感极低,网站的负荷、数据库的压力过大。那么,我们应该考虑一种从最优的角度去避免这样的情况发生,就是每次用户发布的寻物启事信息或者招领启事信息都经过管理员审核,虽然从另一种角度来看,增加了失物招领处的工作量,但是利大于弊,保证了用户发布的失物信息的质量和有效性。
    启事审核的实现,了解了启事审核模块的目的和整体设计,关于启事审核模块的实现,首先,寻物启事信息表和招领启事信息表都有一个status属性字段,其中当status值为0时,为未审核状态,当status值为1时,为审核通过状态,而当status值为2时,为审核未通过状态。
    我们默认用户发布的寻物启事信息或者招领启事信息的status值为0,失物招领后台管理系统将会拦截所有审核状态status值为0的数据,要求进行审核,才能发布到失物招领前台客户端。拦截的数据通过管理员经过严格审核之后,审核状态status值为1的数据则放行,而审核状态status值为2的数据则将其从后台数据库删除。下图4-5为启事审核流程图,图4-6为启事审核效果图。


    4.5.3 失物分类管理模块的设计与实现失物分类管理模块的设计,用户在失物招领系统中,在发布失物信息或者检索失物信息时,其失物分类并不是自己填写而是通过复选框来进行选择,所有失物类别的数据由后台进行管理。
    失物分类管理模块的实现,主要实现了对失物分类的增加、删除、修改与查询,失物可批量删除,查询数据方面通过输入分类名称进行模糊查询相关数据。显示数据方面实现了分页显示,管理员可以设置一页显示的数量等。下图4-7为分类管理效果图。

    4.5.4 寻物启事管理模块的设计与实现寻物启事管理模块的设计,首先考虑到保证用户数据的安全性等其他问题,失物招领后台管理不允许对用户的启事信息进行修改操作,添加失物信息则在失物招领前台客户端实现。所以,后台仅实现了对于启事信息的删除和查询操作。招领启事管理模块类似于此。
    寻物启事管理模块的实现,对于启事信息分页显示,实现了批量删除操作,考虑删除操作的危险性,使用layer弹窗框架显示警示提醒。查询数据实现精准查询,用户可以选择失物分类,选择日期开始时间,日期结束时间,关键字进行查询。日期组件选择了angular ui-bootstrap日期控件,引入了中文文件,方便用户操作。下图4-8为启事信息管理模块效果图。

    4.5.5 数据统计模块的设计与实现数据统计模块的设计,数据统计的首要就是简要明了,让管理员能够清晰的统计数据信息,失物招领管理后台的数据统计主要设计了已失效招领启事数据统计,已失效寻物启事数据统计,寻找中招领启事数据统计,寻找中寻物启事数据统计。
    数据统计模块的实现,通过前端请求数据,后端响应的数据以echarts数据饼状图图形化的形式展示,ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9 /10/11,chrome,firefox,Safari等),底层依赖轻量级的Canvas类库ZRender,提供直观,生动,可交互,可高度个性化定制的数据可视化图表。创新的拖拽重计算、数据视图、值域漫游等特性大大增强了用户体验,赋予了用户对数据进行挖掘、整合的能力。ECharts为百度的推出一款相对较为成功的开源项目,总体上来说有这样的一些优点,ECharts容易使用,ECharts支持按需求打包,ECharts开源支持中国地图功能。下图4-9为数据统计效果图。

    4.6 Web前台客户端功能模块实现4.6.1 失物招领首页设计与实现失物招领的首页设计主要以美观简洁易操作为主旨,通过首页导航栏可进入寻物启事、招领启事、发布信息和快速检索等页面,下图4-10为失物招领首页效果图,图4-11为最新一周寻物招领启事资讯效果图。
    g)

    4.6.2 快速检索模块的设计与实现为了让用户快速查找到目标、提升用户的搜索体验和输入效率,本系统实现了搜索关键字智能提示。下图4-12为快速检索效果图。

    4.6.3 启事信息发布的设计与实现用户发布启事信息时,部分信息为必填项,其余选填,启事添加实现了添加图片插件BootStrap FileInput和日期选择插件angular ui-bootstrap,两者样式非常美观,提升了用户的体验感。下图4-13为启事信息发布效果图。

    4.6.4 启事详情信息的设计与实现通过查看物品启事时,可点击查看详情信息页面,可进入物品详情页面,在物品详情页面可以查看物品的所有信息,包括详情信息浏览次数、物品图片、物品详情页面评论信息、物品详情描述、管理启事操作等。下图4-14为物品详情信息效果图,图4-15为物品详情信息页面评论信息效果图。


    4.6.5 管理启事的设计与实现管理启事主要设计了删除启事功能、修改启事功能与忘记密码操作功能。当用户发布寻物启事信息或招领启事信息时,会要求用户必须填写管理密码,这在用户对其发布的启事信息进行修改操作或删除操作时使用,用户必须输入正确的管理密码才能进行此项操作,如若用户忘记密码,可通过点击忘记密码链接后弹窗输入启事信息编号,则管理密码将会发送到当用户发布寻物启事信息或招领启事信息时要求用户必须填写的邮箱上,用户收到邮箱信息信息即可得到管理密码。下图4-16为管理启事效果图,图4-17为忘记密码操作效果图,图4-18为修改启事信息效果图。



    第5章 系统测试与结果分析失物管理系统的测试主要是为了保证系统各功能模块的正常运行,保证系统能满足功能,并且防止在用户进行操作时放置出现不在系统限制的范围内,需要对系统进行一些功能测试,目的在于发现错误和不满足需求的部分,并对发现的问题进行修复。
    5.1 系统测试环境选择
    客户端硬件:PC
    客户端软件环境:Windows 10
    数据库:MySQL
    版本控制:GIT

    5.2 测试计划系统完成后,需要对其进行各功能模块进行测试,下面以寻物启事管理模块为例,进行测试计划。寻物启事模块具体如表5-1所示。



    功能
    输入
    输出




    新增寻物启事
    点击发布寻物启事信息
    跳转到寻物启事发布页面,显示待填写表单。



    输入必填信息




    点击发布按钮
    提示操作结果,刷新页面


    启事信息审核
    点击审核处理
    弹出启事审核弹窗,显示启事信息



    点击审核结果选项
    提示操作结果,刷新待审核启事信息表


    修改寻物启事
    点击启事详细信息,点击管理启事,输入管理密码,点击修改启事
    弹出待修改启事所有信息弹窗并回显图片



    输入修改信息




    点击修改按钮
    提示操作结果,刷新页面


    搜索寻物启事
    选择搜索条件,输入搜索关键字




    点击搜索按钮
    显示所需的寻物启事信息


    删除寻物启事
    选择需删除寻物启事或全选本页寻物启事




    点击删除按钮
    提示操作结果,刷新页面



    5.3 测试用例测试用例主要由以下几张表构成为寻物启事管理模块测试。新增寻物启事功能如表5-2所示,审核寻物启事功能测试如表5-3,搜索寻物启事功能测试如表5-4所示,修改寻物启事功能测试如表5-5所示,删除寻物启事功能测试如表5-6所示。
    表5-2 新增寻物启事功能测试



    测试用例
    Test01




    测试项目
    新增寻物启事


    输入
    1. 点击发布寻物启事按钮 2. 点击选择失物分类 3. 寻物启事信息必填项 4. 点击选择图片 5. 点击选择日期 6. 点击发布按钮


    执行步骤
    1. 进入失物招领首页 2. 点击发布寻物启事按钮 3. 进入寻物启事发布页 4. 选择失物分类为“宠物” 5. 选择图片并上传“宠物图片” 6. 选择丢失日期为“2019-3-5” 7. 输入寻物启事信息必填项 8. 点击提交按钮


    预计输出
    1. 正确完成填写所有必填项,显示“发布成功”弹窗,选择返回首页,或继续发布信息。 2. 若填写发生错误,提示错误信息。



    表5-3 审核寻物启事功能测试



    测试用例
    Test02




    测试项目
    审核寻物启事


    输入
    1、 点击寻物审核 2、 选择寻物启事点击审核处理 3、 点击审核结果(审核通过或未通过)按钮


    执行步骤
    1、 进入失物招领管理后台首页 2、 首页显示未审核寻物启事数量 3、 点击物品审核选择寻物启事审核 4、 选择要审核的寻物启事点击审核处理 5、 浏览审核寻物启事 6、 点击审核通过按钮


    预计输出
    1、 审核通过,提示“审核通过”,刷新待审核寻物启事列表,列表中审核的寻物启事消失,审核通过的寻物启事成功发布。



    表5-4 搜索寻物启事功能测试



    测试用例
    Test03




    测试项目
    搜索寻物启事


    输入
    1. 选择失物分类 2. 选择开始日期 3. 选择结束日期 4. 关键字 5. 点击搜索按钮


    执行步骤
    1. 进入寻物启事页面 2. 选择失物分类为“钱包” 3. 选择开始日期为“2019-3-1” 4. 选择结束日期为“2019-3-12” 5. 输入关键字“粉色钱包” 6. 点击搜索按钮


    预计输出
    1、显示寻物启事失物分类为钱包,日期范围在2019-3-1到2019-3-12,物品特征为粉色钱包的记录。



    表5-5 修改寻物启事功能测试



    测试用例
    Test04




    测试项目
    修改寻物启事功能测试


    输入
    1、 输入管理密码 2、 点击前往修改 3、 修改失物地点 4、 修改丢失日期 5、 点击确认修改


    执行步骤
    1、 选择寻物启事 2、 点击查看详情 3、 点击管理启事 4、 选择修改启事 5、 输入管理密码 6、 点击前往修改 7、 修改失物地点为“主五#402” 8、 修改丢失日期为“2019-03-03” 9、 点击确认修改


    预计输出
    1、 提示修改成功,并刷新寻物启事详情页面,修改信息成功显示到寻物启事详情页面。 2、 发生错误,寻物启事详情未发生改变,提示错误信息。



    表5-6 删除寻物启事功能测试



    测试用例
    Test05




    测试项目
    删除寻物启事功能测试


    输入
    1. 点击管理启事 2. 点击删除按钮 3. 进入删除页面 4. 输入管理密码 5. 点击确认删除按钮


    执行步骤
    1. 进入寻物启事详情页面 2. 点击管理启事 3. 点击删除按钮 4. 进入删除页面 5. 输入管理密码“123456” 6. 点击确认删除按钮 7. 弹窗提示确认操作 8. 点击确定按钮


    预计输出
    1. 提示“删除成功”,刷新失物招领首页,选择的寻物启事已被删除掉 2. 提示“密码错误请重新输入”,重新输入。



    5.4 测试结果与分析通过一系列的功能测试,所有模块的测试结果与预计输出一致,符合预期的功能需求。
    结 论通过对校园失物招领所碰到的实际问题的具体分析,联系国内外失物招领网站的特征,开发和设计了失物招领系统。该系统不仅融合了校园信息化工作的特征,将传统的失物招领工作信息化,网络化,依靠全校学生的力量就能够很快地找到所失之物, 从而减少经济及精神损失, 规范学校的校风校貌, 有利于创建一个“无遗”的和谐校园[10]。
    本文主要阐明了失物招领系统的设计与实现,从该项目的背景,到该系统开发所用的技术框架和系统运行环境,再到系统的需求分析和功能的详细描述和实现过程。本系统主要重点部分在于启事信息的发布和查询浏览,通过对启事信息模块化的显示,使用户浏览更加便利,顺应了当前校园坏境下对系统的要求和实际需求,通过系统网络化的方式可以提高系统在校园坏境下的使用率,可以真正的提高校园寻回失物的机会。
    失物招领系统实现了启事信息发布、启事信息的快速查询、启事信息的精准查询、启事信息的审核功能、启事信息的数据统计等功能。通过本系统可以大大缓解高校失物招领工作中的一些繁复流程,提升了效率,有一定的应用和推广价值[11]。
    参考文献
    [1]吴江平.高校失物招领管理系统的研究与分析[J].科技广场, 2015年11期:32-35.
    [2]董伟东.失物招领系统的建立[J].计算机光盘软件与应用, 2014年01期: 251-252.
    [3]谭伟,林俊存.基于JSP的高校失物招领网络平台的设计与实现[J].电子世界, 2016年21期:109-110.
    [4]唐志婧.基于Android的校园失物招领平台的设计与实现[D].内蒙古自治区:内蒙古大学,2017.
    [5]周梦萍.基于J2EE的高校失物招领系统的开发设计[J].福建电脑,2018年04期:125-126.
    [6]陈玲.遗失物招领付费之研究[J].成都理工大学学报(社会科学版), 2016年01期:34-38.
    [7]刘莹.校园失物招领公益性管理系统[J].福建电脑, 2017年11期:128.
    [8]邹骅.基于微信公众平台的校园失物招领系统设计[J].河北软件职业技术学院学报,2017年03期:228.
    [9]查玉华,胡开华,张玉静.基于Web的校园寻物网站设计[J].电脑知识与技术, 2016年32期:49-50.
    [10] 张瑾,马皎,史伶丽,丁学翠,董莉霞.校园失物招领管理网页的开发[J]. 机电信息,2018年33期:118-119.
    [11]高越.高校失物招领系统的设计与实现[D].吉林省:吉林大学,2017.
    10 评论 256 下载 2020-06-07 09:48:33 下载需要13点积分
  • 基于Python的Django框架和Sqlite3数据库实现的机票预订系统

    一、项目介绍1.1 题目要求要求实现的基本功能如下:

    班机基本信息的管理
    航班信息的管理
    旅客预定机票、取消预约、付款取票、退票的管理
    查询航班信息、航班预定情况、旅客信息,计算航班满座率
    统计每周、每月,每年营业收入情况

    1.2 开发环境
    语言:Python 3.5
    框架:Django 1.10.6
    前端设计:HTML, CSS, JavaScript
    开发环境:PyCharm

    二、需求分析2.1 具体需求为方便旅客出行,某航空公司(CSU Airlines)拟开发一个机票预定系统。旅客可通过网上订票平台查询公司航班情况,通过输入起飞地、目的地、起飞时间等信息系统为旅客安排航班,旅客可根据自身需要,按照起飞时间和机票价位来选择航班。订票成功之后,系统为旅客生成订单信息,旅客可以再个人信息页面查看自己的订票信息,并且可以向系统提出退票要求,系统针对具体情况计算手续费后进行相应退票处理。
    2.2 功能分析2.2.1 用户界面
    查询:用户对航班信息进行查询操作
    排序:用户根据自己的需求对查询结果进行排序筛选
    订票:对用户订票需求进去处理并记录旅客预定信息和更新数据库信息
    退票:对用户退票需求进行处理并更新数据库
    查看个人信息:用户查看自己的个人票务信息
    帮助:提供系统使用帮助文档
    退出:关闭当前页面

    2.2.2 管理员界面
    航班信息管理:可对航班信息进行增删改查操作
    旅客信息管理:可对旅客信息进行增删改查操作
    财务信息管理:可以统计航空公司每周、每月,每年营业收入情况
    帮助:提供系统使用帮助文档
    退出:关闭当前页面

    2.3 系统主功能图
    2.4 系统数据流图
    三、逻辑设计3.1 ER图
    3.2 数据库表3.2.1 航班信息表
    3.2.2 旅客信息表
    旅客信息表继承了 Django 模板中默认的 User 类,所以有一些继承来的别的字段,我们的 Passenger 对象只需要 id,username,password 即可。
    3.2.3 实体间多对多关系
    通过在两表之间建立一张新表的方式,将 booksystem_flight 表和 auth_user 表的主键联系在一起,实现了多对多关系。
    四、功能设计本系统采用的 Python + Django + Sqlite 的设计方法,后台功能写在 views.py 文件中。
    4.1 用户模块4.1.1 订票模块在用户订票的过程中,首先判定用户是否登录,如果没有登录,就加载登录页面;如果用户已经登陆了,通过前端用户选择的航班传入flight.id,然后判断如果用户已经订过这次航班,就反馈冲突信息,如果没有,订票成功,数据库更新,显示订票成功页面。
    # 免除csrf@csrf_exemptdef book_ticket(request, flight_id): if not request.user.is_authenticated(): # 如果没登录就render登录页面 return render(request, 'booksystem/login.html') else: flight = Flight.objects.get(pk=flight_id) # 查看乘客已经订购的flights booked_flights = Flight.objects.filter(user=request.user) # 返回 QuerySet if flight in booked_flights: return render(request, 'booksystem/book_conflict.html') # book_flight.html 点确认之后,request为 POST 方法,虽然没有传递什么值,但是传递了 POST 信号 # 确认订票,flight数据库改变 # 验证一下,同样的机票只能订一次 if request.method == 'POST': if flight.capacity > 0: flight.book_sum += 1 flight.capacity -= 1 flight.income += flight.price flight.user.add(request.user) flight.save() # 一定要记着save # 传递更改之后的票务信息 context = { 'flight': flight, 'username': request.user.username } return render(request, 'booksystem/book_flight.html', context)
    4.1.2 查询模块前端表单接收用户传入的出发地、目的地和出发时间,然后在航班数据库中寻找满足条件的航班,分两步:

    寻找出发地和目的地相同的航班
    寻找航班出发日期与旅客出发日期相同的航班

    为了给用户良好的体验,满足条件的航班信息按照不同的 key 值(起飞时间、降落时间、机票价格)进行升序排列。
    # 搜索结果页面def result(request): if request.method == 'POST': form = PassengerInfoForm(request.POST) # 绑定数据至表单 if form.is_valid(): passenger_lcity = form.cleaned_data.get('leave_city') passenger_acity = form.cleaned_data.get('arrive_city') passenger_ldate = form.cleaned_data.get('leave_date') # print(type(passenger_ldate)) # 全设为naive比较 # china_tz = pytz.timezone('Asia/Shanghai') # passenger_ltime = datetime.datetime( # year=passenger_ldate.year, # month=passenger_ldate.month, # day=passenger_ldate.day, # hour=0, minute=0, second=0, # tzinfo=china_tz # ) # 全设为aware比较 passenger_ltime = datetime.datetime.combine(passenger_ldate, datetime.time()) print(passenger_ltime) # filter 可用航班 all_flights = Flight.objects.filter(leave_city=passenger_lcity, arrive_city=passenger_acity) usable_flights = [] for flight in all_flights: # off-set aware flight.leave_time = flight.leave_time.replace(tzinfo=None) # replace方法必须要赋值。。笑哭 if flight.leave_time.date() == passenger_ltime.date(): # 只查找当天的航班 usable_flights.append(flight) # 按不同的key排序 usable_flights_by_ltime = sorted(usable_flights, key=attrgetter('leave_time')) # 起飞时间从早到晚 usable_flights_by_atime = sorted(usable_flights, key=attrgetter('arrive_time')) usable_flights_by_price = sorted(usable_flights, key=attrgetter('price')) # 价格从低到高 # 转换时间格式 time_format = '%H:%M' # for flight in usable_flights_by_ltime: # flight.leave_time = flight.leave_time.strftime(time_format) # 转成了str # flight.arrive_time = flight.arrive_time.strftime(time_format) # # for flight in usable_flights_by_atime: # flight.leave_time = flight.leave_time.strftime(time_format) # 转成了str # flight.arrive_time = flight.arrive_time.strftime(time_format) # 虽然只转换了一个list,其实所有的都转换了 for flight in usable_flights_by_price: flight.leave_time = flight.leave_time.strftime(time_format) # 转成了str flight.arrive_time = flight.arrive_time.strftime(time_format) # 决定 search_head , search_failure 是否显示 dis_search_head = 'block' dis_search_failure = 'none' if len(usable_flights_by_price) == 0: dis_search_head = 'none' dis_search_failure = 'block' context = { # 搜多框数据 'leave_city': passenger_lcity, 'arrive_city': passenger_acity, 'leave_date': str(passenger_ldate), # 搜索结果 'usable_flights_by_ltime': usable_flights_by_ltime, 'usable_flights_by_atime': usable_flights_by_atime, 'usable_flights_by_price': usable_flights_by_price, # 标记 'dis_search_head': dis_search_head, 'dis_search_failure': dis_search_failure } if request.user.is_authenticated(): context['username'] = request.user.username return render(request, 'booksystem/result.html', context) # 最前面如果加了/就变成根目录了,url错误 else: return render(request, 'booksystem/index.html') # 在index界面提交的表单无效,就保持在index界面 else: context = { 'dis_search_head': 'none', 'dis_search_failure': 'none' } return render(request, 'booksystem/result.html', context)
    4.1.3 退票模块退票时需要更新数据库,更新航班的(capacity, book_sum, income)字段,并且在 booksystem_flight_user 表中删除这个订单。
    # 退票def refund_ticket(request, flight_id): flight = Flight.objects.get(pk=flight_id) flight.book_sum -= 1 flight.capacity += 1 flight.income -= flight.price flight.user.remove(request.user) flight.save() return HttpResponseRedirect('/booksystem/user_info')
    4.1.4 个人信息模块由于管理员和用户共用一个登录窗口,所以在显示用户信息时,需要对登录的用户身份进行判定,如果登录的用户是管理员,则加载管理页面,如果是普通用户,则加载用户个人的订单页面。
    # 显示用户订单信息# 航班信息,退票管理def user_info(request): if request.user.is_authenticated(): # 如果用户是管理员,render公司航班收入统计信息页面 admin_finance if request.user.id == ADMIN_ID: context = admin_finance(request) # 获取要传入前端的数据 return render(request, 'booksystem/admin_finance.html', context) # 如果用户是普通用户,render用户的机票信息 user_info else: booked_flights = Flight.objects.filter(user=request.user) # 从 booksystem_flight_user 表过滤出该用户订的航班 context = { 'booked_flights': booked_flights, 'username': request.user.username, # 导航栏信息更新 } return render(request, 'booksystem/user_info.html', context) return render(request, 'booksystem/login.html') # 用户如果没登录,render登录页面
    4.2 管理员模块4.2.1 航班信息管理
    航班对象继承了 models.Model,航班信息管理在 Django 默认的后台管理界面中实现。
    from django.contrib.auth.models import Permission, Userfrom django.db import models# Create your models here.# 添加primary_key会覆盖掉默认的主键class Flight(models.Model): user = models.ManyToManyField(User, default=1) # 有了这个字段之后,默认的后台添加失效,必须要自定义Form,除去这个字段 name = models.CharField(max_length=100) # 班次 南方航空CZ3969 leave_city = models.CharField(max_length=100, null=True) # 离开城市 arrive_city = models.CharField(max_length=100, null=True) # 到达城市 leave_airport = models.CharField(max_length=100, null=True) # 离开的机场 arrive_airport = models.CharField(max_length=100, null=True) # 到达的机场 leave_time = models.DateTimeField(null=True) # DateTimeField包括了DateField信息,并且添加了时间 arrive_time = models.DateTimeField(null=True) capacity = models.IntegerField(default=0, null=True) # 座位总数 price = models.FloatField(default=0, null=True) # 价格 book_sum = models.IntegerField(default=0, null=True) # 订票总人数 income = models.FloatField(default=0, null=True) # 收入 def __str__(self): return self.name
    在使用 Django 默认的后台管理时,由于 Flight 中多了字段 user,而 user 对象是不能从后台输入的,所以在 Django 默认的表单管理中出去 user,因为 Flight 与 User 之间关系是多对多,所以 Django 建立的 book_system 表中是没有 user 字段的,通过下面的方法解决。
    # 自定义Flight对象的输入信息class FlightForm(forms.ModelForm): class Meta: model = Flight exclude = ['user'] # user信息不能从后台输入
    4.2.2 旅客信息管理旅客继承了 django.contrib.auth.User 类,我们只需要自定义用户表单需要输入的对象,其他默认生成的字段不用考虑。
    # 用户需要输入的字段class UserForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput) class Meta: model = User fields = ['username', 'email', 'password']
    4.2.3 航空公司财务统计统计航空公司每周、每月、每年的收入,并且显示所有的订单信息。
    # 管理员后台财务管理# 统计航空公司每周、每月,每年营业收入情况。def admin_finance(request): all_flights = Flight.objects.all() all_flights = sorted(all_flights, key=attrgetter('leave_time')) # 将所有航班按照起飞时间排序 # 将航班每天的输入打上不同的时间标签 [周,月,日] week_day_incomes = [] month_day_incomes = [] year_day_incomes = [] # 用set存储所有的 周,月,年 week_set = set() month_set = set() year_set = set() for flight in all_flights: if flight.income > 0: # 只统计有收入的航班 # 打上周标签 this_week = flight.leave_time.strftime('%W') # datetime获取周 week_day_incomes.append((this_week, flight.income)) # 添加元组(week, income) week_set.add(this_week) # 打上月标签 this_month = flight.leave_time.strftime('%m') # datetime获取月 month_day_incomes.append((this_month, flight.income)) # 添加元组(month, income) month_set.add(this_month) # 打上年标签 this_year = flight.leave_time.strftime('%Y') # datetime获取年 year_day_incomes.append((this_year, flight.income)) # 添加元组(year, income) year_set.add(this_year) # 存储每周收入 # 将每周的收入用 IncomeMetric 类型存储在 week_incomes List中 week_incomes = [] for week in week_set: income = sum(x[1] for x in week_day_incomes if x[0] == week) # 同周次的income求和 flight_sum = sum(1 for x in week_day_incomes if x[0] == week) # 同周次的航班总数目 week_income = IncomeMetric(week, flight_sum, income) # 将数据存储到IncomeMetric类中,方便jinja语法 week_incomes.append(week_income) week_incomes = sorted(week_incomes, key=attrgetter('metric')) # 将List类型的 week_incomes 按周次升序排列 # 存储每月收入 # 将每月的收入用 IncomeMetric 类型存储在 month_incomes List中 month_incomes = [] for month in month_set: income = sum(x[1] for x in month_day_incomes if x[0] == month) flight_sum = sum(1 for x in month_day_incomes if x[0] == month) month_income = IncomeMetric(month, flight_sum, income) month_incomes.append(month_income) month_incomes = sorted(month_incomes, key=attrgetter('metric')) # 将List类型的 month_incomes 按月份升序排列 # 存储每年收入 # 将每年的收入用 IncomeMetric 类型存储在 year_incomes List中 year_incomes = [] for year in year_set: income = sum(x[1] for x in year_day_incomes if x[0] == year) flight_sum = sum(1 for x in year_day_incomes if x[0] == year) year_income = IncomeMetric(year, flight_sum, income) year_incomes.append(year_income) year_incomes = sorted(year_incomes, key=attrgetter('metric')) # 将List类型的 year_incomes 按年份升序排列 # 存储order信息 passengers = User.objects.exclude(pk=1) # 去掉管理员 order_set = set() for p in passengers: flights = Flight.objects.filter(user=p) for f in flights: route = f.leave_city + ' → ' + f.arrive_city order = Order(p.username, f.name, route, f.leave_time, f.price) order_set.add(order) # 信息传给前端 context = { 'week_incomes': week_incomes, 'month_incomes': month_incomes, 'year_incomes': year_incomes, 'order_set': order_set } return context
    五、界面设计5.1 欢迎界面
    拟定一趟行程

    5.2 查询界面用户 Let’s Go 之后,加载查询结果页面。

    默认的机票信息按照价格升序排列,用户通过点击机票信息上方的字段可以选择按照起飞时间或者到达时间升序排列,如下图,注意后两行的变化。

    如果用户需要的航班数据库中不存在,就反馈错误信息。
    将用户的目的地修改成中国(数据库中没有这趟航班)进行测试。

    5.3 订票界面
    用户注册完账号直接加载到查询页面。

    用户再次点击订票,如果用户尚未订过该趟航班,加载订票确认页面,如果用户已经订过了,加载订票冲突页面。

    在正常订票页面点击确认,完成订票。

    在个人中心用户可以查看自己的订票信息。

    如果用户选择了自己已经订过的机票,加载订票冲突页面。

    5.4 退票界面在用户的个人中心,可以进行退票。

    选择确认,完成退票,用户订票信息刷新。

    5.5 管理员界面
    在前面的 login_user 函数中已经有过判定,如果登录用户是管理员,加载航空公司的财务页面。

    管理员登录成功。

    5.6 后台管理界面链接尾部输入 admin 进入后台管理。

    后台数据,包括 Flight,User 和 Django 默认生成的数据。

    航班信息管理,显示所有航班信息,可以增删改查。

    旅客信息管理,操作同航班信息管理,注册的用户的信息都会保存在这里。

    六、结束语其实从大三上的寒假开始,我就在为这次的数据库课设做准备,从学长们那里了解到了数据库课设最好的实现方法是写网站,于是寒假回去我就学习了基础的 html, css, js,对网站前端有了基本认识,又结合我目前常用的 Python 语言,学习了 Django 网页开发框架,对网站后端处理有了深层认识。虽然对网站前后端的交互还有点模糊,但是经过这次数据库课设之后,我很多的疑问得到了解答,对 Python + Django + Sqlite 开发更加熟练了。
    这次数据库我用的是 Django 默认的数据库 Sqlite,这是一个轻量级的数据库,除了自带的一些指令与其他数据库有差异,大部分 SQL 语句与主流数据库都相同,但是 Sqlite 是一个本地型的数据库,无需安装和管理配置,并且占用空间非常小,用来做小型的网站开发完全够用。
    在建设机票预订系统时,主要的问题就是建立实体,并确定实体之间的关系,一个旅客可以订购多架飞机,一个飞机可以承载多个用户,飞机和旅客之间是多对多关系,清楚这一点的前提下,才能建设合理的数据库完成事务需求。
    另外,有一点很深的收获是,在用 web 开发的时候,对数据库的操作已经不是 SQL 语句了,而是通过高级语言(如Python)的语法来完成对数据库的增删改查操作。
    举个简单的例子,在查询 booksystem_flight 表中的所有航班信息时:
    SQL: select * from booksystem_flight;Django: Flight.objects.all( )
    可见高级语言和数据库的结合开发使得很多底层的数据操作也转化成了开发人员熟悉的高级语言程序,但无论如何,仍然是对数据库进行了操作,传统的 SQL 语句依然有用,方便我们验证代码逻辑是否正确,总之,收获很多。
    8 评论 255 下载 2018-12-19 11:27:22 下载需要13点积分
  • 基于ASP.NET和Sql Server 2008实现的学籍管理系统

    1 引言1.1 项目目标学籍管理系统是一个教育单位不可缺少的部分,它的内容对于学校的决策者和管理者来说都至关重要,所以学籍管理系统应该能够为用户提供充足的信息和快捷的查询手段。但一直以来人们使用传统人工的方式管理文件档案,这种管理方式存在着许多缺点,如:效率低、保密性差,另外时间一长,将产生大量的文件和数据,这对于查找、更新和维护都带来了不少的困难。
    学生学籍管理系统具体目标如下:

    提高学生信息管理效率,节约管理成本,增强学生管理的安全性
    满足学校学生管理的人员、老师和学生的不同层次和不同方面的需要
    为学校将来的信息化建设提供必要的支持

    总之,通过该系统的建设来提高学校的学生信息管理效率,使得学校的发展能够适应当前的教育信息化建设的中体发展趋势。
    1.2 项目背景
    名称:学籍管理系统 V1.0
    用户:已注册学生、老师和系统管理维护人员

    1.3 定义
    Microsoft Windows Server 2008:微软服务器专用操作系统
    Sql Server:数据库开发管理工具
    Database:数据库

    2 运行环境2.1 硬设备可联网的普通 PC 机或者移动端设备。
    2.2 支持软件
    运行环境:Windows server 2008
    数据库:Sql Server 2008、2010

    3 概要设计学生学籍管理系统是一个较为复杂的系统。在功能需求方面,它要实现学生基本信息管理、学生课表管理、学生选课管理、学生成绩管理、学生学分管理以及学生奖惩情况管理等功能;在性能上要求该系统能够方便快捷地完成学生信息管理的各项工作,录入数据合法性的校检程度高,数据查询速度快;为了系统的安全和保密,要求系统对不同权限的用户提供不同的功能模块,对历史数据的更改和新数据的添加只有一定权限的用户才能进行操作,一般的用户只能进行查询操作。
    4 开发流程具体描述4.1 开发环境搭建学生学籍信息管理系统其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面,对于前者要求建立起数据库一致性和完整性、安全性好的数据库。而对于后者则要求应用程序功能完备,易使用的特点。
    由于采用 ASP.NET 技术,因此前端主要使用微软提供的 Visual Studio 开发工具,数据库采用 SqlServer。利用其提供的集成开发工具和数据库可视化操作界面,短时间内可快速开发出项目版本。
    4.2 系统分析4.2.1 系统功能分析学籍管理系统主要面向用户有注册学生,老师和系统管理人员,因此在通过登录验证之后进入主界面,注册学生只提供查询功能,可查看个人信息和个人相关科目成绩,也可以使用辅助功能进行在线查询。老师可进行学生信息和学生成绩管理,包括增、删、改、查等。系统管理员还可以修改数据库。以上用户均提供密码修改功能。
    4.2.2 业务流程
    4.3 系统架构设计4.3.1 总体结构设计用于描述系统总体功能

    4.3.2 独立模块设计用于描述各独立模块具体功能


    4.3.3 数据库设计用于描述数据库概要设计

    4.3.4 界面设计登录页面设计

    系统主界面

    学生信息查询页面

    学生成绩查询页面

    学生信息录入页面

    成绩统计页面

    奖励统计页面

    在线查询页面

    密码修改页面

    4.4 系统实现4.4.1 数据库建立根据 ER 图建立符合系统设计的数据库,主要数据表设计如下:

    Student 表

    Score 表

    Admin 表

    Scholarship 表

    User 表

    数据库表间关系

    数据填充

    4.4.2 程序编码项目文件结构图

    页面代码举例

    5 系统评价及功能完善
    完成基本项目所需功能,包括登录验证,以及权限限制等
    信息查询功能完善,统计查询功能查询效率较高
    数据库设计合理
    需要注意数据库后台防止 SQL 恶意注入,需添加数据库后台安全机制
    成绩模块要增强可扩展性
    1 评论 18 下载 2021-02-15 10:23:05 下载需要11点积分
  • 基于C#和SQL Server 2012房屋买卖租赁系统

    摘 要随着我国经济的快速发展和人们生活水平的不断提高,人们对房屋的需求也日益增长,这极大的增加了房屋买卖租赁公司门店服务人员的工作量,大量信息的流动和处理使得数据不易管理和分类。
    房屋买卖租赁系统利用信息技术对大量复杂的信息进行有效的管理和分类,极大的减少了房屋买卖租赁公司人力的开销,简化了大量信息的流动和处理。该系统主要实现房产经纪人对房源登记、客户需求、看房记录、交易记录、客户数据的信息录入以及对房屋信息、客户信息查询等功能,人事管理员对公司人员进行账号分配和管理的功能。
    该系统是基于C#的应用程序设计,使用Microsoft Visual Studio2012和Microsof SQL Sever2012数据库作为开发工具。该系统的开发主要包括需求分析和实现两个阶段,需求分析阶段主要使用的技术是:利用E-R图对概念模型进行分析,利用数据流图对需求分析进行分析,利用Microsof SQL Sever2012数据库对关系模型进行实现。实现阶段主要使用的技术是:利用三层架构+EF框架进行前台页面和后台功能的实现。
    一、开发背景随着经济和房地产业的迅猛发展,连带着房屋租赁买卖行业也在快速发展。在这个计算机技术快速发展的时代背景下,各行各业都在逐渐实现管理的现代化,房屋租赁买卖管理的现代化也势在必行。
    开发本系统主要就是为了解决房屋租赁公司在房屋租赁信息管理中的一些不规范,使得房屋租赁信息的管理向着规范化、简单化、有效化得方向发展。
    二、需求分析2.1 用户基本需求描述本系统的主要使用者是房屋买卖租赁公司的门店服务人员(房产经纪人),主要是实现房源登记、供求匹配、看房交易、客户数据登记管理和房产经纪人信息管理等功能。房产经纪人使用该系统对客户信息、房源信息、看房记录和交易记录等数据进行登记和有效管理,能快速查询历史记录和供求双方匹配的房源数据。人事管理员使用该系统管理人员信息,分配帐号和密码。
    2.2 数据流图分析
    整个系统从整体上分为以下三个部分:

    用户数据管理:包括客户数据(承租客户、房东)和房产经纪人数据
    房屋信息管理:房屋的租赁买卖信息记录
    记录管理:承租客户的看房记录、客户的需求记录和交易记录


    该系统的主要功能为:

    需求处理:记录客户的需求
    供求匹配:根据客户需求查询符合客户需求的房源信息
    看房记录:对客户看房之后的信息进行记录
    交易记录:看房之后,如果用户要买房/租房,对交易记录进行记录
    修改房屋信息:对已交易的房屋信息及时进行修改(已售出的房屋信息及时删除)


    该分层图是对客户的需求信息进行处理,根据客户的需求查询房源信息,如若有房源信息匹配,房产经纪人带客户看房。

    此分层图为房产经纪人带客户看房后,对看房记录进行登记,如若客户满意,同意交易,房产经纪人对客户的交易信息进行处理。

    此分层图是房产经纪人对客户的买房/租房交易信息进行处理。

    此分层图是房产经纪人根据已经交易的房源信息对房源信息记录进行修改
    2.3 数据字典数据流条目



    数据流名称
    别名
    简述
    来源
    去向
    组成




    客户需求信息
    客户需求
    客户对房屋提出的需求
    客户
    加工1“登记客户的需求信息”
    编号+户型+位置+楼层+类型


    房屋信息供求匹配结果
    房屋信息匹配供求
    根据客户提出的需求查询房屋信息
    房产经纪人
    加工1“根据需求查询房屋信息”
    True\
    False


    修改的房屋信息
    修改房屋信息
    对房屋信息的修改
    房产经纪人
    加工1“房屋信息管理”
    房屋编号+位置+楼层+状态+户型+类型


    添加看房信息
    记录看房记录
    登记客户的看房记录
    房产经纪人
    加工1“看房记录管理”
    客户编号+房屋编号+记录编号+时间+结果+客户反馈


    添加交易信息

    记录客户买房/租房的交易信息
    房产经纪人
    加工1“交易记录管理”
    客户编号+房屋编号+编号+时间+类型+价格+佣金比例



    数据存储条目



    数据存储条目
    别名
    简述
    组织方式
    查询方式




    需求记录

    存放所有客户需求信息
    索引文件,以客户需求编号为关键字
    要求能立即查询


    房屋记录

    存放所有房屋信息
    索引文件,以房屋编号为关键字
    要求能立即查询


    看房记录

    存放所有客户看房记录
    索引文件,以看房记录编号为关键字
    要求能立即查询


    交易记录

    存放所有客户的交易记录
    索引文件,以交易记录编号为关键字
    要求能立即查询



    数据项条目



    数据项条目
    别名
    简述
    类型
    长度




    客户编号
    clientID
    房屋买卖租赁公司客户的编号
    int



    客户名字
    clientName
    房屋买卖租赁公司客户的名字
    varchar
    20


    客户性别
    clientSex
    房屋买卖租赁公司客户的性别
    char
    2


    客户电话
    clientPhone
    房屋买卖租赁公司客户的电话号码
    char
    11


    客户地址
    clientAddress
    房屋买卖租赁公司客户的地址
    varchar
    50


    客户角色
    clientRole
    房屋买卖租赁公司客户的身份(买主\
    房东)
    char
    4



    三、详细设计3.1 概念模型设计
    3.2 关系模型设计
    客户(ID,姓名,性别,电话号码,地址,角色)
    房屋(ID,位置,楼层,户型,类型,状态)
    看房记录(ID,时间,结果,客户反馈,客户ID,房屋ID)
    交易记录(ID,时间,类型,价格,佣金比例,客户ID,房屋ID)
    员工(ID,姓名,性别,电话,地址,密码)
    需求(ID,户型,位置,楼层,类型,客户ID)

    3.3 物理模型设计客户表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    clientID
    客户编号
    int


    PK


    clientName
    客户名字
    varchar
    20




    clientSex
    客户性别
    char
    2




    clientPhone
    客户电话
    char
    11




    clientAddress
    客户地址
    varchar
    50




    clientRole
    客户角色
    char
    4




    员工表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    agentID
    员工编号
    int


    PK


    agentName
    员工名字
    varchar
    20




    agentSex
    员工性别
    char
    2




    agentPhone
    员工电话
    char
    11




    agentAddress
    员工地址
    varchar
    20




    agentPassword
    员工密码
    char
    6




    staff
    员工职别
    int


    FK



    看房记录表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    lookHouseID
    记录编号
    int


    PK


    lookTime
    看房时间
    datetime





    lookResult
    看房结果
    varchar
    50




    clientBack
    客户反馈
    varchar
    50




    clientID
    客户编号
    int





    houseID
    房屋编号
    int


    FK



    交易记录表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    dealID
    记录编号
    int


    PK


    dealTime
    交易时间
    date





    dealType
    交易类型
    varchar
    10




    dealPrice
    交易价格
    decimal
    (10, 2)




    commmissionRate
    佣金比例
    decimal
    (6, 2)




    clienID
    房产经纪人ID
    int





    houseID
    房屋ID
    int


    FK



    房屋表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    houseID
    房屋编号
    int


    PK


    houseType
    房屋户型
    varchar
    10




    houseFloor
    房屋楼层
    tinyint





    housePlace
    房屋位置
    varchar
    20




    houseGenre
    房屋类型
    char
    6




    houseStatus
    房屋状态
    char
    4




    clientID
    客户编号
    int


    FK



    客户需求表



    学段名
    中文名
    类型
    长度
    允许为空
    约束




    demandID
    需求编号
    int


    PK


    demandType
    需求户型
    varchar
    50




    demandPlace
    需求位置
    varchar
    50




    demandFloor
    需求楼层
    varchar
    20




    demandGenre
    需求类型
    char
    6




    clientID
    需求编号
    int


    FK



    四、系统功能模块说明4.1 用户登录模块此模块的主要功能是实现用户登录。系统的用户必须拥有管理员分配的合法账号才能登录系统进行对应的操作。

    输入:用户编号、密码
    输出:进入主页

    4.2 房屋信息管理模块此模块的主要功能是房产经纪人对房东提供的房屋信息进行管理,包括对信息的增加、更新、删除和查询。

    输入:房屋编号,户型,楼层、位置、类型、状态、房东
    输出:房屋信息记录

    4.3 客户信息管理模块此模块的主要功能是房产经纪人对客户的信息进行管理,包括对信息的增加、修改、删除和查询。

    输入:客户姓名、性别、联系方式、地址、身份、负责的房产经纪人
    输出:客户信息记录

    4.4 需求管理模块此模块的主要功能是房产经纪人对客户提出的需求信息进行管理,包括对信息的增加、修改、删除和查询。

    输入:需求户型、需求楼层、需求位置、需求类型、提出需求的客户
    输出:需求信息记录

    4.5 看房管理模块此模块的主要功能是房产经纪人对客户的看房信息进行管理,包括对信息的增加、修改、删除和查询。

    输入:看房时间、看房结果、反馈、房屋编号、看房的客户
    输出:看房信息记录

    4.6 交易管理模块此模块的主要功能是房产经纪人对客户买房/租房的交易信息进行管理,包括对信息的增加、修改、删除和查询。

    输入:交易时间、交易类型、交易价格、佣金比例、房屋编号、客户
    输出:交易信息记录

    4.7 人员信息维护模块此模块的主要功能是人事管理员对人员的信息进行管理,包括对信息的增加、修改、删除和查询。

    输入:帐号、姓名、性别、地址、联系方式、密码、职务
    输出:人员信息记录

    五、系统实现5.1 解决方案
    5.2 主界面
    此主界面为房产经纪人登录后可操作的功能模块,分为房源管理、客户管理、需求管理、看房管理、交易管理五个模块。

    此主界面为人事管理员登录主界面,主要是人事管理员为房产经纪人分配帐号密码。
    5.3 登录模块
    房产经纪人和人事管理员在此页面使用自己的帐号密码登录,分别进入各自的主页进行相应的操作。
    5.4 房源管理模块
    房产经纪人在此页面对房源数据进行维护,可对房源进行增加、修改和删除操作,还可按相应的关键字进行查询。
    5.5 客户管理模块
    房产经纪人在此页面对客户数据进行管理,可对客户信息进行增加、修改和删除操作,还可按客户的名字快速查询客户的信息。
    5.6 需求管理模块
    房产经纪人在此页面对客户提出的需求进行管理,可对客户提出的需求进行增加、修改和删除操作,也可按相应的关键字进行查询。
    5.7 看房管理模块
    房产经纪人在此页面对客户的看房记录进行管理,可对看房记录进行增加、修改和删除,也可按相应的关键字进行查询。
    5.8 交易管理模块
    房产经纪人在此页面对客户的交易信息进行管理,可在此页面对交易信息进行增加、修改和删除操作,也可按相应的关键字进行查询。
    5.9 人员信息维护模块
    人事管理员可在此页面对房产经纪人信息进行管理,可增加、修改和删除房产经纪人信息,并为房产经纪人分配帐号密码。
    总 结通过此次数据库课程设计,提高了自己对项目的需求分析能力,熟悉并加强了画ER、数据流图的步骤以及对数据关系和业务关系的处理,熟悉并掌握了ER-关系模型的转换,掌握了数据库的创建库、创建表和约束的T-SQL命令,进一步熟悉了数据库与应用程序的连接以及在项目中的应用。
    熟练掌握了MVC+EF框架以及easyui的使用,对于实现程序有了进一步的成长,也对数据库课程进行了巩固学习,更好的消化了上课所学习的知识理论,能够更好的分析程序之间的逻辑,梳理主体与主体直接存在的直接或间接联系。对于系统实现程序有了更好的掌握与认识。
    通过此次课程设计,对上课所学习的内容进行新的复习与巩固,熟悉了前台页面的设计,对页面布局美化有了进一步的了解,熟悉了画ER图与数据流图的步骤,但是对于其他方面能力尚且不足,今后会继续努力。
    参考文献[1] 曾登高..NET系统架构与开发[M].电子工业出版社:北京,2003:103-105.
    [2] 张海藩.软件工程导论[M].清华大学出版社:北京,2003:87-100.   
    [3] 萨师煊,王珊.数据库系统概论[M].高等教育出版社:北京,2002年:3-460.
    [4] 周佩德.数据库原理及应用[M].电子工业出版社:北京,2004:18-24.  
    [5] 张莉,韩其睿.浅谈C#编程语言的特点及潜在的新功能[J].仪器仪表用户,2005,5:83-85.
    [6] 顼宇峰.ASP.NET+SQL Server 典型网站建设案例[M].清华大学出版社出版:北京,2006:56-89.
    [7] 彭连刚,张震等.管理系统中计算机应用[M].上海交通大学出版社:上海,2008:5-11.
    [8] 郑人杰,马素霞,殷人昆.软件工程概论[M].机械工业出版社:北京,2009:53-109.
    [9] 陈志波,王春玲.数据库原理及应用教程[M].人民邮电出版社:北京,2008:24-99.
    [10] 王小科,李继业.C#开发宝典[M].北京工业出版社:北京,2012:88-120.
    2 评论 49 下载 2020-08-05 10:47:24 下载需要13点积分
  • 基于QT实现的图的遍历演示

    1 问题分析和任务定义1.1 问题描述很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示在连通的无向图上访问全部结点的操作。
    1.2 基本要求以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。
    1.3 测试数据任选国内城市,起点为合肥,暂时忽略里程。
    1.4 问题分析及任务定义此程序需要完成以下操作:使用文件读取数据,以邻接多重表为存储结构,构成一个连通的图。用户输入一个起始点,从起始点开始对图分别进行深度优先和广度优先遍历。分别输出每种遍历下的结点访问序列和相应的生产树的边集。
    程序的执行流程如下图所示。

    1.5 实现本程序需要解决的问题
    如何利用从文件读取的数据构成无向图
    如何实现从用户指定的点开始遍历
    遍历完后如何输出遍历过得点的序列和边集
    如何利用图形化动态的演示遍历过程
    如何提高用户体验

    本程序的难点在于如何创建邻接多重表,和如何遍历所有城市。
    设图的结点20-30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。通过输入图的全部边(存于数据文件中,从文件读写)输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制。注意,生成树的边是有向边,端点顺序不能颠倒。
    2 数据结构的选择和概要设计城市与城市之间是没有方向的,构成的无向图采用邻接多重表来实现,主要表示无向图的的各个边和结点,并通过对邻接多重表的操作实现对无向图的深度优先和广度优先遍历。创建AMLGraph类,其包含的属性和方法如下图所示。

    其中adjMulList是顶点数组指针,所用的顶点结点以顺序方式存储在一维数组中;vexnum和edgenum是无向图的结点个数和边个数;cityMap类是用来存储所有从文件中读取的城市名和坐标信息的类,points、dfs_str、bfs_str是用来存储遍历的城市的坐标和名称的变量。
    GreatAMLGraph函数用来构建邻接多重表,LocationVex函数通过城市名找到该城市在表结点的位置。AMLGraph、~AMLGraph函数分别是类的构造函数和析构函数,BFS_Traverse、DFS_Traverse分别是广度优先和深度优先遍历的函数。
    VexNode结构体是点结点(城市结点),name是城市的名称,firstEdge是EdgeNode类型的指针,指向该顶点的第一条边的结点。
    EdgeNode结构体是边结点,isVisited为标志域,用来标记该条边是否已被访问过;ivex为顶点域,指示依附于这条边的一个顶点的位置(序号);jvex指示另一个顶点的位置;ilink为链域,指向依附于第一条边的结点。
    3 详细设计和编码3.1 邻接多重表的建立
    从文件中读取所有城市名、坐标和线路信息。利用头插法建立邻接多重表。
    for (int i = 0; i < edgenum; ++i){ EdgeNode * e = new EdgeNode; e->isVisited = false; string v1, v2; inFile >> v1 >> v2; int a = LocationVex(v1); int b = LocationVex(v2); e->ivex = a; e->jvex = b; e->ilink = adjMulList[a].firstEdge; e->jlink = adjMulList[b].firstEdge; adjMulList[a].firstEdge = e; adjMulList[b].firstEdge = e;}
    3.2 深度优先遍历先调用DFS_Traverse函数,初始化visited[i]数组,再调用DFS(i),其中i为用户指定城市的索引。在DFS函数中,先访问表结点中第i个点,在判断该顶点的另一端是否被访问,如果没有访问,就在调用DFS(i->jvex),形成递归,直到访问到该顶点的另一端被访问过后,在访问与i相连的其它边,当与i相连的所有边都被访问完时,结束循环。
    while (e){ if (e->ivex == i) { if (!visited[e->jvex]) DFS(e->jvex); e = e->ilink; } else { if (!visited[e->ivex]) DFS(e->ivex); e = e->jlink; }}
    e为EdgeNode类型的指针变量。时间复杂度为O(n+edgeNum)。
    3.3 广度优先遍历先调用BFS_Traverse函数,初始化visited[i]数组,再调用BFS(i),其中i为用户指定城市的索引。BFS函数中,先访问表结点中第i个点,并将该点放入队列q中,在循环中不断取出队列的第一个元素,直到队列为空时,所以点遍历完成,结束该循环。取出队列第一个元素后,再判断该顶点的另一端是否被访问,如果没有访问,就遍历该点,并将该点放入队列,当队列第一个元素的所有相连的点都被访问过后,循环结束,再从队列中取出第一个元素,进行循环遍历。
    while (!q.empty()){ p = q.front(); q.pop(); EdgeNode * e = adjMulList[p].firstEdge; while(e) { if (e->ivex == p) { if (!visited[e->jvex]) { visited[e->jvex] = 1; //std::cout << adjMulList[e->jvex].name + " "; bfs_str.append(adjMulList[e->jvex].name.substr(0, 2) + "->"); q.push(e->jvex); } e = e->ilink; } else if (e->jvex == p) { if (!visited[e->ivex]) { visited[e->ivex] = 1; bfs_str.append(adjMulList[e->ivex].name.substr(0, 2) + "->"); q.push(e->ivex); } e = e->jlink; } }}
    分析上面算法,每个顶点至多进一次队列,遍历过程实质上仍是寻找每个顶点的邻接点的过程,因此时间复杂度和深度优先搜素一样。
    4 上机调试过程调试过程中,一方面是解决产生的bug,另一个面是调整文件中的数据,保证数据的合理性。
    点的名称及坐标

    无向图的边

    5 测试结果及其分析程序运行界面

    遍历演示


    本程序以图形化的形式演示,用户能够任意指定起始点开始遍历,遍历的结果也清晰可见。其中显示了两种遍历的城市编号的序列和遍历的边集。
    6 用户使用说明本程序是在windows7下的Qt creator5.4.1环境下编写的,因为Qt本身就是跨平台图形界面软件,所以本程序支持跨平台运行,支持的平台包括Windows、Mac OS、Linux等桌面操作系统。
    执行本程序后,窗口上回现实所有城市的名称、编号和路线,输入框中默认填写的合肥的编号,该输入框支持模糊查询,可以输入城市名称、城市编号或编号加名称。点击按钮“演示”后,会以文本形式显示遍历城市的序列,以图形化的方式,显示遍历的城市之间的连线。并且可以反复搜索遍历,具有良好的用户体验。在该可执行文件目录下的map.txt是本程序的所依赖的数据来源,文件中的数据可供用户或开发者调整修改。
    参考文献[1] 王昆仑, 李红. 数据结构与算法. 北京: 中国铁道出版社, 2006年5月
    [2] Kay_Sprint. 邻接多重表存储无向图以及有关操作[EB/OL]. http://www.2cto.com/database/201111/110964.html, 2011-11-13/2017-2-16
    15 评论 103 下载 2018-10-31 11:48:00 下载需要12点积分
  • 基于C语言的PL0编译器

    一、添加注释
    块注释由/*和*/包含,不允许嵌套
    行注释由//开始直到行结束符(回车)


    这部分代码比较简单,唯一值得注意的是/* */注释结束的判断标准是碰到了*字符,而且下一个字符为/,这时表示此部分注释结束
    二、扩展PL/0 中“条件”:这种修改包括:
    增加逻辑运算符 && 、|| 和 !
    把PL/0 语言中的“条件”概念一般化为C 语言那样(表达式值非零即为“真”)
    “条件”的短路计算
    增加逻辑运算符 && 、|| 和 !:



    把PL/0 语言中的“条件”概念一般化为C 语言那样(表达式值非零即为“真”)
    这部分主要依托JNZ指令实现,JNZ指令判断栈顶值,非零时跳转

    例子1

    这是一个最简单的例子,可以看到,代码第九行有JNZ 0 11指令,说明i!=0时会执行赋值,而第十行有JMP 0 13指令,说明JNZ若非真(i=0)则不赋值。运行结果也与期望一样。
    例子2

    这个例子用到了后面短路计算的一些内容,首先是指令翻转,我设计时考虑了每遇到一个&&,则前后的指令都要翻转,由于我把添加的六个指令”JZ”, “JG”, “JL”, “JE”,”JNE”, “JGE”, “JLE”, “JNZ”写成了对称的形式,因此只要code[cx - 1].f = 37 - code[cx- 1].f;(首尾enum和为37)即可。
    回到这个例子,第九行指令为JZ 0 12说明若j等于0,可以跳过后面i的判断直接对j的值进行判断,而十一行指令为JZ 0 15说明&&前的值已为真(因为前面的JZ没有执行),如果&&后的值为真,即可直接进行赋值,十三十四行的结构与例子1完全一样,不再赘述。
    Not的实现在短路计算时一并详细叙述:
    “条件”的短路计算
    首先,当语句碰到&&时条件是需要翻转的(提供了跳出的途径),添加了8个指令”JZ”, “JG”, “JL”, “JE”,”JNE”, “JGE”, “JLE”, “JNZ”,写成对称形式便于翻转。

    由于&&,||,!三者优先级不同,将condition改成condition,condition_and,condotion_1三个部分,将condition_1的返回值改成int类型,以便判断条件表达式里面是否有括号,以便短路计算的设计。





    我的设计是将truelist,falselist,i_false(falselist的个数),i_true(truelist的个数设为全局变量)设置成全局变量
    观察代码

    如果i_false!=0说明or前面的语句中有falselist的值,则可以在这里进行回填,同时由于or总是伴随着truelist,则在这里要将cx-1放入truelist中。

    if (!flag && sym == SYM_AND),说明碰到&&时是没有括号表达式的,可以直接对指令翻转,并放入falselist中
    condition_1中增加了notexist变量记录前面是否有!符号

    Condition_1函数的最后,如果notexist非零,则将truelist回填,falselist转移给truelist。

    如果此时i_false的值为零,则需要产生一条jmp指令强制跳转,,否则处理完括号表达式程序将不知道自己将跳往何处。此时可以将truelist同时回填。
    处理if表达式时类似:


    第十行产生了JMP指令,强制跳转。
    处理嵌套的if时,需要设置一个变量save_ifalse保存i_false的值,处理完之后再放回去。

    elif中处理情况类似,不再赘述
    while指令唯一的区别在于设置了cx1保存当前代码序号,处理完while内容之后会跳回cx1继续执行。
    for语句类似,不再赘述。


    例子1

    第一层if中产生了两条jz 0 18 说明i或j等于0都会导致程序停止执行,第二层if中产生了jl 0 16指令,说明这层条件正确时会进行赋值,不正确时会产生JMP指令强制跳转。
    例子2

    十五行产生了JMP 0 8表示跳回第八行进行判断
    三、添加数组主要把数组作为一组特殊变量和若干常量(维度范围)来处理。
    添加了函数arraydeclaration()以及函数addr(),修改了getsym()使之能读取’[’和’]’,修改了enter()函数使之能把同一名字下的数据作为数组读入,修改了vardeclaration()函数使之能判断并调用arraydeclaration()定义数组,同时修改了所有使用变量的地方,若读到’[’则调用addr定位数组元素位置。
    以下为部分代码:
    else if(ch == '[') { getch(); sym = SYM_DIMSTART; } else if(ch == ']') { getch(); sym = SYM_DIMEND;}//dim tokens,属于getsym() if(position(id)>0) { mk = (mask*)&table[tx]; mk->level = level; mk->address = dx++; }//属于enter() if(position(id)>0) { mk = (mask*)&table[tx]; mk->level = level; mk->address = dx++; }//same name ,array,nothing changed but the address add 1 if (sym == SYM_IDENTIFIER) { getsym(); if(sym == SYM_DIMSTART) arraydeclaration();//if '[' ,deal with array else enter(ID_VARIABLE);//属于vardeclarationvoid addr(mask*mk){ static int space = 0; int i,j; j=position(id);//名字表中位置 getsym(); if(sym == SYM_NUMBER) { space = space*table[j].value+num; j++; getsym(); if(sym == SYM_DIMEND) { getsym(); if(sym == SYM_DIMSTART) addr(mk); while(space>0) { space--; mk->address++; } getsym(); } else error(28); } else if(sym == SYM_IDENTIFIER) { space = space*table[j].value+num; j++; expression(sym); gen(STO,0,&i); space = space*table[j].value+i; getsym(); if(sym == SYM_DIMEND) { getsym(); if(sym == SYM_DIMSTART) addr(mk); while(space>0) { space--; mk->address++; } getsym(); } else error(28); }}//address the element of array case ID_VARIABLE: mk = (mask*) &table[i]; getsym(); if(sym == SYM_DIMSTART)//array element , deal with address { addr(mk); }//定位
    四、参数传递。实现传值调用,如传递常量值,或普通变量/数组元素的值。
    并进行简单的语义检查(如实参和形参个数/类型的对应等)
    语法分析:

    实现方式:
    这里实现参数传递的方法是将需要传递的参数当作是过程的变量,如p(a, b),就将a, b声明为过程p的两个局部变量。在调用过程的时候,把各个参数的值先依次放在栈顶,然后通过指令PAS把栈顶的参数的值都向上移动三位,然后再进行CAL,这就达到了把参数传递进去的目的。
    在block中读到ID_PROCEDUCE时,先将过程的名字记下来为tem,变量个数n初始化为0,并且把此时的dx存到save_dx上,把dx赋值为3,level ++。这是为了在后面声明变量的时候把变量声明到下一个level中,并且有着正确的偏移地址,另外声明变量时需要用n记录变量的个数。声明完毕变量之后,将之前存的dx恢复,然后将之前的过程名tem放入id中,并且将过程名进表。之后调用新的block的时候一开始就将dx = 3 + n,这是因为变量在上一个level中声明,在这里把dx补回。
    需要调用时,读到过程名就直接调用函数call。这个函数的作用就是将各个参数的值放在栈顶,生成PAS指令和CAL指令,完成调用的需求。其中PAS中会指定参数的个数,如在p(a, b, c)时,GEN(PAS, 0, 3),PAS指令如下,就可以留出三个位置留给等会CAL指令放置信息。
    源码分析:

    添加的PAS指令如上

    上图是在block中声明过程做的改动
    可见在读到参数名的时候先将其存起来然后进行语法分析并且声明参数,最后再将过程名放入表中。

    上图是statement里面,当读到ID_PROCEDURE时,直接调用函数call

    上图是call函数的内容,读到左括号之后,将每一个参数当成一个expression,使用while循环把每个参数的值放在栈顶,在其间用n来记录参数的个数。读完SYM_RPAREN之后,就先生成PAS最后生成CAL。
    测试例子:
    例子1

    程序和运行结果如上所示
    可见在每一次CAL之前都会进行一次PAS指令,并且PAS中含有参数的个数,为了可以确认移动参数的个数。而在PAS之前的指令,是将所要传递的值放在栈的顶部,传递顺序是过程括号内靠左的参数先放在栈顶。
    例子2

    可见源程序是一个简单的递归程序,本例子测试了过程的递归调用是否可行,在这里看到输出结果是3 2 1 0,则显然得到了正确的结果。
    五、添加语句实现if-elif-else结构语句
    else if (sym == SYM_IF) { // if statement ifAppear = 1; getsym(); set1 = createset(SYM_THEN, SYM_DO, SYM_NULL); set = uniteset(set1, fsys); condition(set); if (!i_false) { falselist[i_false++] = cx; gen(JMP, 0, 0); } while(i_true) { i_true--; code[truelist[i_true]].a = cx; } if (sym == SYM_THEN) { getsym(); } else { error(16); // 'then' expected. } set2 = createset(SYM_ELSE, SYM_ELIF, SYM_NULL); set3 = uniteset(set2, fsys); save_ifalse = 0; while (save_ifalse < i_false) { save_falseList[save_ifalse] = falselist[save_ifalse]; save_ifalse++; } i_false = 0; statement(set3); while (i_false < save_ifalse) { falselist[i_false] = save_falseList[i_false]; i_false++; } while (sym == SYM_ELIF) { jumpList[list++] = cx; gen(JMP, 0, 0); while(i_false) { i_false--; code[falselist[i_false]].a = cx; } getsym(); condition(set); if (!i_false) { falselist[i_false++] = cx; gen(JMP, 0, 0); } while (i_true) { i_true--; code[truelist[i_true]].a = cx; } if (sym == SYM_THEN) { getsym(); } else { error(16); // 'then' expected. } save_ifalse = 0; while (save_ifalse < i_false) { save_falseList[save_ifalse] = falselist[save_ifalse]; save_ifalse++; } i_false = 0; statement(set3); while (i_false < save_ifalse) { falselist[i_false] = save_falseList[i_false]; i_false++; } } destroyset(set); destroyset(set1); if (sym == SYM_ELSE) { jumpList[list++] = cx; gen(JMP, 0, 0); while(i_false) { i_false--; code[falselist[i_false]].a = cx; } getsym(); statement(fsys); } while(i_false) { i_false--; code[falselist[i_false]].a = cx; } while (list--) code[jumpList[list]].a = cx; destroyset(set3); destroyset(set2); }
    其中本人设计if-elif-else的语法规则是整个if-elif-else语句以分号作为结尾,比如
    if i>0 then j:=1;
    在这种情况下if语句当做终结,不能再跟elif和else,如需elif和else,则需要加begin-end,如下所示:
    if i=0 then begin j:=0; end elif i>0 then begin j:=1; end else j:=-1;
    程序示例和运行结果如下:
    vari,j,k,l; begin i:= -2; if i=0 then begin j:=0; end elif i>0 then begin j:=1; end else j:=-1; end

    生成代码介绍:第六行为if条件判断开始,条件为真转入第8行赋值,赋值完成后跳到第21行结束,条件为假,进入第10行强制跳转到elif条件判断开始处,即第11行,条件为真则跳到第15行赋值,赋值完成后跳到第21行结束,条件为假,进入第10行强制跳转到else后的语句进行赋值,然后顺序退出。
    C程序实现:在原来if的基础上,读入if符号后,完成条件判断和语句执行,则用一个while循环判断其后是否有elif,elif的条件判断和语句执行与if的写法类似,最后判断是否有else,在完成对语句的翻译。其中最大的改进是利用了短路运算的结果,再结合回填实现多处跳转,摒弃了JPC指令。同时由于每个if或者elif后的语句执行完成后都要强制跳转到整个if-elif-else语句后面,所以用一个jumplist来保存要回填的强制跳转地址,在这之前还要强制生成一条JMP指令,正如上述运行结果所述。
    for结构语句以及自增自减
    else if (sym == SYM_FOR) { getsym(); if (sym == SYM_LPAREN) { getsym(); if (sym != SYM_SEMICOLON) statement(fsys); if (sym != SYM_SEMICOLON) error(10); getsym(); if (sym != SYM_SEMICOLON) { cx1 = cx; condition(fsys); if (!i_false) { falselist[i_false++] = cx; gen(JMP, 0, 0); } } if (sym != SYM_SEMICOLON) error(10); getsym(); cx4 = cx; if (sym != SYM_RPAREN) { set1 = createset(SYM_RPAREN, SYM_NULL); set = uniteset(fsys, set1); statement(set); destroyset(set); destroyset(set1); gen(JMP, 0, cx1); } else { cx--; cx4 = cx1; } if (sym != SYM_RPAREN) error(22); getsym(); while (i_true) { i_true--; code[truelist[i_true]].a = cx; } save_ifalse = 0; while (save_ifalse < i_false) { save_falseList[save_ifalse] = falselist[save_ifalse]; save_ifalse++; } i_false = 0; statement(fsys); while (i_false < save_ifalse) { falselist[i_false] = save_falseList[i_false] ; i_false++; } gen(JMP, 0, cx4); while (i_false) { i_false--; code[falselist[i_false]].a = cx; } } else { error(26); } }
    for语句设计完全参照C语言语法规则,读入for关键字之后,对for后面括号内的语句进行解析,三个语句均可缺省,先执行第一个分号前的语句(如果为空不用执行),然后执行第二个语句的条件判断(为空则不用执行),然后读入第三个语句,对其进行解析,之后执行整个循环体。处理for的关键是各个基本块的跳转。首先执行第一个初始化语句,然后执行条件判断,为真转入循环体,循环体结束后强制跳转到for后面括号中的第三个语句,执行完强制跳转到条件判断,如此不断循环,知道条件判断为假之后跳出循环体,整个for结构语句执行结束。
    程序示例和运行结果如下:
    var i,j,k; begin k:=0; j:=0; for(i:=0;i<3;++i) begin for(k:=0;k<3;++k) j:=j+1; end; end.
    以外层循环为例,第8行开始是条件判断,正确则进入循环体,第15行开始则是整个循环体,循环体语句执行结束后跳转到第12行执行增值语句,如第29行所示,在第12行完成增值之后跳转到第8行进行条件判断,知道条件判断为假,跳转到第30行,整个循环结束。
    自增自减的实现
    首先在符号表中添加了++、—,在设计上是每读入一个’+’(或者’-’)就会判断下一个输入符号是不是’+’(或者’-’),如果是,则将sym赋值为SYM_INC(或者SYM_DEC)。由于类似i++、++i都可以做为语句和因子,所以在statement和factor函数中都添加了关于++、—的解析。在statement还有所区别,就是如果是在statement完成自增自减,由于其值会保存在栈顶,所以需要弹出,在factor部分则不需要。
    程序实现如下(factor和statement处理方式类似,区别在于是否生成弹栈指令):
    if (sym == SYM_IDENTIFIER) { // variable assignment mask* mk; if (!(i = position(id))) { error(11); // Undeclared identifier. } else if (table[i].kind == ID_CONSTANT) { error(12); // Illegal assignment. i = 0; } else if (table[i].kind == ID_PROCEDURE) { call(i, fsys); gen(POP, 0, 0); } else { getsym(); mk = (mask*)&table[i]; if (sym == SYM_BECOMES) { getsym(); expression(fsys); gen(STO, level - mk->level, mk->address); } else if (sym == SYM_INC) { gen(LOD, level - mk->level, mk->address); gen(INC, level - mk->level, mk->address); gen(POP, 0, 1); getsym(); } else if (sym == SYM_DEC) { gen(LOD, level - mk->level, mk->address); gen(DEC, level - mk->level, mk->address); gen(POP, 0, 1); getsym(); } } } else if (sym == SYM_INC) { getsym(); if (sym == SYM_IDENTIFIER) { if ((i = position(id)) == 0) { error(11); // Undeclared identifier. } else { if (table[i].kind == ID_VARIABLE) { mask *mk; mk = (mask *)&table[i]; gen(INC, level - mk->level, mk->address); gen(LOD, level - mk->level, mk->address); gen(POP, 0, 1); } else error(12); } } else error(14); getsym(); } else if (sym == SYM_DEC) { getsym(); if (sym == SYM_IDENTIFIER) { if ((i = position(id)) == 0) { error(11); // Undeclared identifier. } else { if (table[i].kind == ID_VARIABLE) { mask *mk; mk = (mask *)&table[i]; gen(DEC, level - mk->level, mk->address); gen(LOD, level - mk->level, mk->address); gen(POP, 0, 1); } else error(12); } } else error(14); getsym(); }
    其中利用了新添加的INC和DEC指令,其作用是利用变量的层差和偏移修改其在栈中的值。程序的实现还区别了自增自减运算符是位于标识符前还是表示符后,如果是在标识符前,则先INC(或者DEC)后LOD,如果是在标识符后,则先INC(或者DEC)后LOD。还需要说明一点的是添加了POP指令,POP指令适用于两种情况的弹栈,一种是函数返回值的弹栈,一种是用于自增自减的弹栈,这两种方式的a域不同,前者的a域为0,后者的a域为1
    POP指令实现如下:
    case POP: if (i.a) top--; else if (use) { top--; use = 0; } break;
    程序示例和运行结果如下:

    exit语句的实现
    程序实现如下:
    else if (sym == SYM_EXIT) { gen(STP, 0, 0); getsym(); }
    当读入exit语句时会产生停机指令,即STP(stop)指令,STP指令翻译如下:
    if (i.f == STP){ printf("The program exited\n"); break;}
    首先判断指令的指令域是否为STP,如果是就跳出interpret中的循环,整个pl0处理机结束运行。
    程序示例和运行结果如下所示:
    var i,j;begin i:=0; j:=(++i)+(++i)+(++i); exit; i:=0; j:=(i++)+(i++)+(i++);end.

    可以看出一共有四条赋值语句只执行两条,因为在执行第二条赋值语句之后就产生了停机指令,后面的赋值语句停止执行。
    return语句和返回值
    程序实现如下:
    else if (sym == SYM_RETURN) { getsym(); expression(fsys); gen(REV, 0, 0); }//REV指令翻译: case REV: temp = stack[top]; top = b; pc = stack[top + 2]; b = stack[top + 1]; stack[top] = temp; use = 1; printf("%d\n", stack[top]); break;
    当读入return关键字之后会处理后面的表达式,然后产生一条REV指令,REV指令的作用就是退出当前函数栈,控制权回到调用者,同时将表达式的值做为临时变量放在栈顶,同时输出该值,将use值设为1,供弹栈的时候判断。如果函数返回值作为因子的话,那么在使用时会自动退栈,如果作为语句的会产生一条弹栈指令弹出该值,从而不占用栈空间。设计弹栈指令时会利用产生返回值时设置的use值来决定是否要弹栈,弹栈完成后还会将该值复位。
    程序示例和运行结果如下:
    var i,j;procedure p(i)begin return i+1;end;procedure q(i)begin j:=i;end;begin j:=p(5); p(6); q(5);end.

    当返回值做为因子时没有产生POP指令,而单独做为语句时产生了POP指令弹栈。输出中第一个6出现是因为遇到REV指令,输出栈顶的值,第二个6是返回值赋值给j,7是第二次调用p时产生的返回值,5是调用q时内部的赋值。
    六、给PL/0 添加内置函数random和printRandom函数的实现依赖于,每当发现random指令时,创建一条RDM命令,i.a的值就是括号内的值(括号内没有数时i.a缺省)

    同时,在处理RDM指令时调用c库的rand(函数)


    Print函数设计成可以打印空行(OPR_WLT)与可以打印任意参数个数字(OPR_PRT)


    可以看到,在打印一个空行之后,i与j的值在同一行中打印了
    七、更多的C风格的运算表达式实现在本拓展中实现了c语言风格表达式中的>>, <<, +=, -=, /=, *=运算符和赋值表达式:=的多重赋值。下面分成三个部分进行介绍。
    左移和右移(<<, >>)

    首先看上图中的一个例子,由输出结果可知程序运行正确

    首先定义了OPR_LS和OPR_RS,分别是将次栈顶的值左/右移栈顶的值的次数。

    然后新加入函数expression,将原来的expression改成expression2。在这个函数中生成了左移和右移的操作。
    八、此部分分为(goto)与(break、continue)两部分int labeltotal = 0;int gotototal = 0;char labelchar[10][11];int labelcx[10];char gotochar[10][11];int gotocx[10];//记录goto的和goto点的地址和名称//把SYM_GOTO添到statbegsys和对应位置 if (sym == SYM_IDENTIFIER) { // variable assignment mask* mk; if (!(i = position(id))) { getsym(); if(sym == SYM_COLON) { set1 = createset(SYM_COLON,SYM_NULL); fsys = uniteset(set1, fsys); destroyset(set1); flag=0; for(j=0;j<labeltotal;j++) { if(!strcmp(labelchar[j],id)) flag=1; } if(flag) error(31); else{ strcpy(labelchar[labeltotal],id); if(labeltotal >= 10) error(33); else { labelcx[labeltotal] = cx; labeltotal++; } } getsym(); } else error(11); test(fsys, phi, 19); statement(fsys);//statement中若是不明标示符开头并接:为goto的可能点,记录位置和名称 else if ( sym == SYM_GOTO) { flag = 0; getsym(); if(sym != SYM_IDENTIFIER) error(8); else { getsym(); if(sym != SYM_SEMICOLON) error(5); else { strcpy(gotochar[gotototal],id); gotocx[gotototal]=cx; gotototal++; gen(JMP,0,0); } }//statement中出现goto,记录位置和名称 block(set); for(i=0;i<gotototal;i++) { for(j=0;j<labeltotal;j++) if(!strcmp(gotochar[i],labelchar[j])) code[gotocx[i]].a = labelcx[j]; }
    主函数block后面回填jmp地址Break、continue:
    break语句
    代码实现如下所示:
    PART1:
    else if (sym == SYM_BREAK) { if (!loopLevel) error(28); else { getsym(); breakList[breakCount].cx = cx; breakList[breakCount].level = loopLevel; breakCount++; gen(JMP, 0, 0); } }
    PART2:
    while (breakCount) { if (breakList[breakCount - 1].level == loopLevel) { breakCount--; code[breakList[breakCount].cx].a = cx; } else break; }
    其中PART1是对break语句的解析,每次读到break之后,先判断其是否在循环中(即第一个if判断),如果不在循环中则报错,如果在循环中则进行后续操作,首先有一个breakList保存待回填的break语句对应的代码行数,同时还保存其所在的循环层级,PART2出现在处理while语句与for语句中的循环语句后,处理完循环体之后开始回填,只回填当层循环的break语句,其中looplevel就保存了当前的循环层级。
    程序示例如下:
    var i,j;begin for(i:=1;i<5;i++) begin j:=i; if j=3 then break; end;end.

    从结果上看,当j为3的时候跳出循环,运行结果正确。
    continue语句
    代码实现如下所示:
    else if (sym == SYM_CONTINUE) { if (!loopLevel) error(28); else { getsym(); gen(JMP, 0, loopStart); } }
    其中loopStart保存了当前循环开始所在的代码行数,同时考虑循环嵌套,会用到下面的代码,
    saveLoopStart = loopStart;statement(fsys);loopStart = saveLoopStart;
    其做法就是保存当前的循环开始的行数,在处理statement语句之后再恢复该数。
    程序示例如下:
    var i,j, k,l;begin i:=0; k:=0; for( ;i<5; ) begin i++; if i=2 then continue; for ( ;k<2;k++) begin if k=1 then continue; l:=100;end; j:=i; end;end.

    内层continue会导致只输出一次100(在没有continue的情况下会输出两次),外层的continue导致i为2时没有对j执行赋值,所以没有输出2,所以运行结果正确。
    九、read函数此read函数支持读入20个以内的变量,可以存入数组中,statement里加入如下语句



    3 评论 127 下载 2018-11-01 21:02:08 下载需要8点积分
  • 基于Qt和SQL Server 2014的学生管理系统

    摘 要随着学校规模的不断扩大,学生数量的急剧增加,有关学生的各种信息量也 在不断成倍增长。面对庞大的信息量,就需要有学生成绩管理系统来提高学生管 理工作的效率。通过这样的系统,我们可以做到信息的规范管理和快速查询,从 而减少了管理方面的工作量。本系统以 SQL Server 2014 数据库作为后台数据库 支撑,采用 Qt Creator 作为前台界面开发。核心是添加、修改和删除学生信息, 每一个表的修改都将联动的影响其它的表。系统有完整的添加、删除和密码修改功能。
    关键字:学生管理系统;数据库;Qt Creator
    前 言项目开发目的学生管理系统让数据的查询变得简单化。让每个人都能在任何时刻都可以 了解到数据的变更。这样就可以使学生更方便的查询到自己的学号、考勤、考试 成绩等信息,也能使学校更好的对学生进行更全面的管理。
    项目开发背景随着学生数量的增加,带来学生信息量的剧增。同时每个学生的信息都 在不断地变化着,采用人工的方式进行操作整理,带来诸多不便,并且效率低下, 出错率高。
    项目开发定义本系统主要用于学校学生信息管理,总体任务是实现学生信息关系的系 统化、规范化和自动化,其主要任务是用计算机对学生各种信息进行日常管理, 如查询、修改 、增加、删除,另外还考虑到学生选课,针对这些要求设计了学 生信息管理系统;本系统主要用于学校学生信息管理,总体任务是实现学生信息 关系的系统化、规范化和自动化,其主要任务是用计算机对学生各种信息进行日 常管理,如查询、修改 、增加、删除,另外还考虑到学生选课,针对这些要求 设计了学生信息管理系统。
    项目开发平台
    QtCreator
    Qt4.7
    SQL Server 2014

    第1章 项目开发计划书1.1 项目范围本系统主要包括学生信息管理、学生成绩管理、学生考勤管理和学生课程四 个部分。其功能主要有:

    学生主要信息的管理,包括学生基本信息等
    学生成绩的管理,包括学生所学课程成绩等
    学生考勤管理信息的管理,包括学生的课程签到等
    学生课程管理,包括学生课程、上课时间、地点等

    1.2 客户资料本系统的主要客户为学校的学生与教师。本系统服务于学校,用来方便学校 管理学生资料方便学生查询自己的信息。
    第2章 需求规格说明书2.1 问题陈述本设计采用 C++语言编码实现,学生成绩管理模块主要由学生成绩的录入、 修改、删除、查询等四部分部分构成。通过本设计令读者掌握使用 QT 开发的简 单电子产品。熟悉软件设计、优化以及系统调试的基本方法,为进一步设计开发 更为复杂的管理系统打下一定的基础。
    2.2 要达到的目标本系统主要用于学校学生信息管理,总体任务是实现学生信息关系的系统 化、规范化和自动化,其主要任务是用计算机对学生各种信息进行日常管理,如 查询、修改、增加、删除。
    2.3 具体的分析系统功能描述:当开始进入时初始化登录界面,用户可以选择以管理员或者 普通用户进入系统。按下登录功能键后程序开始运行,系统开始逻辑运行。
    第3章 系统设计书3.1 命名规则
    函数命名规则:用该函数功能动词或动词短语命名方法
    变量的命名规则:用变量实现的作用名词来表示该变量
    宏的命名规则:用宏实现的作用名词来表示该变量

    3.2 构架图
    3.3 数据库设计本系统涉及到的信息主要有 5 类:学生信息、成绩信息、课程信息、考勤 信息以及账号密码信息。按以上分析,将系统的数据库设计为一个:学生数据库 该数据库其中包含以下各表: 学生信息表:记录学生的基本信息,是进行学生及其他各类信息处理的基础。 学生成绩表:记录学生的平时、期末课程的成绩。 课程表:记录各专业各年级开课情况。 考勤表:记录学生平时的课程考勤情况。 账号密码表:记录学生和管理员的账号及密码信息。
    student 学生信息表



    字段名
    数据类型
    是否可空
    说明




    ID
    varchar(11)
    N
    学号(主关键字)


    name
    varchar(6)
    N
    学生姓名


    class
    varchar(20)
    N
    班级编号


    age
    varchar(2)
    N
    年龄


    sex
    varchar(2)
    N
    性别


    birthday
    date
    Y
    生日


    address
    varchar(20)
    Y
    籍贯



    takes 学生成绩表



    字段名
    数据类型
    是否可空
    说明




    ID
    varchar(11)
    N
    学号


    course_id
    varchar(5)
    N
    课程编号


    ps_grade
    varchar(4)
    N
    平时成绩


    qm_grade
    varchar(4)
    N
    期末成绩



    course 课程信息表



    字段名
    数据类型
    是否可空
    说明




    course_id
    varchar(5)
    N
    课程编号(主关键字)


    course_name
    varchar(10)
    N
    课程名


    course_time
    smallint
    N
    课程时间


    credits
    int
    N
    学分


    time
    time(7)
    N
    上课时间



    attendeance 考勤表



    字段名
    数据类型
    是否可空
    说明




    course_id
    varchar(5)
    N
    课程名


    ID
    varchar(11)
    N
    学号(外部关键字)


    name
    varchar(20)
    N
    学生姓名


    att_time
    time(7)
    N
    签到时时间



    pwd 账号密码表



    字段名
    数据类型
    是否可空
    说明




    ID
    varchar(5)
    N
    登录账号


    mm
    varchar(20)
    N
    登录密码



    3.4 数据库关系图
    3.5 时序图
    第4章 操作手册登陆模块操作

    登陆界面分为管理员登录与普通用户登录,管理员用设置的特殊账号进行管 理员模式登陆,而普通用户使用自己的学号进行登陆,初始密码为 123456,可 在登陆界面选择修改密码。
    成绩管理模块

    用管理员登陆后,进入成绩管理模块可以选择增加成绩按钮进行对学生成绩 的录入,增加完成后按保存键保存新增成绩。点击方框内的一行在按删除可进行 删除操作,删除成功后按保存键。双击方框内容即可进行修改,修改成功后按保 存键。输入学号在点击查询可查询该学号的学生信息。

    普通用户登录后进入查询平台,点击下拉框可选择进入成绩查询。点击查询 全部可查询全部成绩信息。输入学号后点击查询可查询该学号的所有课程成绩。
    课程管理

    用管理员登陆后,进入课程管理模块可以选择增加课程按钮进行对课程的录 入,增加完成后按保存键保存新增课程。点击方框内的一行在按删除可进行删除 操作,删除成功后按保存键。双击方框内容即可进行修改,修改成功后按保存键。 输入课程编号在点击查询可查询该课程的信息。

    普通用户登录后进入查询平台,点击下拉框可选择进入课程查询。点击查询 全部可查询全部课程信息。
    学生基本信息模块

    用管理员登陆后,进入学生基本信息管理模块可以选择输入学生基本信息点 击提交信息进行录入学生基本信息,输入学号在按删除可进行删除操作输入学 号,再输入新的信息,点击修改信息进行修改。

    普通用户登录后进入查询平台,点击下拉框可选择进入学生基本信息查询。 点击查询全部可查询全部学生基本信息。输入学号后点击查询可查询该学号学生 的基本信息。
    考勤管理模块

    普通用户登录后进入查询平台,点击查询全部可以对学生的所有学生考勤查 询,输入学号可以对该学号的学生的考勤进行查询。

    管理员用户登录进入管理平台,点击增加信息、删除信息、保存、刷新可以 对学生信息进行操作,输入上课的时间点击迟到查询可以查询出迟到的学生。
    2 评论 90 下载 2020-08-15 22:36:52 下载需要12点积分
  • 基于Java的考勤管理系统

    摘 要该考勤信息管理系统用于实现学校对在校学生的考勤信息的管理,是典型的管理信息系统。学生考勤信息的手工登记查询,是一项非常繁重而枯燥的劳动。在计算机技术飞速发展的今天,应用数据库技术实现学生考勤信息统计的管理是行之有效的。
    本报告系统地介绍了一个基于java的学生考勤信息管理系统,论述了一个基于java的学生/老师考勤信息管理系统的设计原理、设计思想及具体的实现过程,对部分架构及设计思想和设计过程作了详细阐述。系统具有师生个人信息查询、请假、随堂点到等功能,信息管理模块、考勤管理模块和考勤系统模块。
    本系统开发主要包括后台数据的简历以及前端应用程序代码的开发两部分。其一要求建立起的数据库具有完整性和一致性,并具有一定的数据安全性;其二要求程序界面友好、功能完备,通俗易懂。本次课程设计着重讨论了用java开发考勤管理系统时的数据库访问技术和面对对象程序开发技术,并给出了部分实现代码。
    关键词:Java;面对对象;学生考勤管理系统
    一、开发背景随着社会的发展,计算机科学日渐成熟,计算机越来越深入到我们的日常生活中,成为我们不可或缺的辅助工具。其强大的功能已为人们深刻认识,它已进入人类社会的各个领域,并发挥着越来越重要的作用,各行各业的人们无需经过特别的训练就能够使用计算机完成许许多多复杂的工作。
    随着我国人口的增长,高校的生源也日益增加。学校考勤信息的管理作为高校管理的一项日常工作,也随着学生人数的管理而变得繁琐起来。与此同时,计算机技术的发展也是与时俱进一日千里,于是,使用计算机代替人工记录管理学生的考勤信息自然而然的进入了人们的视野里。
    二、需求分析我们需要设计一个系统可以实现学生基本信息的查看和管理等功能。在主菜单界面中有输入学生信息、根据ID好查询学生信息、显示数据库中的学生信息、学生请假经过老师审批、学生修改密码、老师查看学生考勤信息等功能,通过不同的选择进入到不同的功能,根据提示进行输入操作。
    三、模块说明根据分析整个系统主要划分为4个功能模块,分别执行要求中的功能。数据管理中实现对学生的基本信息、学生考缺课的查询,以及具体缺课内容,是迟到、早退、请假、旷课。查询管理通过根据学生学号等信息,来达到我们需求的目的。
    3.1 用户登录模块
    功能描述:此模块的主要功能是实现用户登录。系统的用户必须在登录系统后才能进行对应的操作。用户在登录页面正确输入账号、密码时就可以成功登录。当密码错误时,用户根据系统的提示进行密码的修改重新进行登录
    输入:用户学号、密码、新密码、旧密码
    输出:

    欢迎使用考勤信息系统请输入旧密码请输入新密码请再次输入新密码修改成功两次密码不一致,请重新输入密码输入错误,请重输

    3.2 用户查询模块
    功能描述:此模块的主要功能是实现用户查询信息。学生在登录系统后查询自己的考勤信息,以此得到自己的出勤情况;老师通过该模块
    输入:学号、专业班级、个人信息等
    输出:用户考勤信息或学生个人考勤信息

    3.3 请假模块
    功能描述:请假分为学生请假申请、老师请假审批、学生请假状态查询;学生提交的请假申请需要老师的审批,只有批准之后学生请假信息方可录入学生状态查询。学生通过此功能模块进行在线请假及查看请假记录信息;老师在线审批学生请假及查看请假记录信息
    输入:学生姓名、请假原因、请假时间、老师批准选项等
    输出:

    请假条:某某同学因某某原因所以请假,请假时间为:xxx,希望老师批准请老师选择:同意(agree) or 不同意(disagree )老师已同意、不同意某某学生的请假选择错误!请老师重新选择决定

    3.4 考勤记录模块
    功能描述:系统具备考勤管理系统、考勤修改系统、后台管理系统这三大主要功能。其中在考勤管理系统中任课老师通过该系统对学生的考勤信息进行录入、修改、统计,在线管理学生出勤信息;学生在线查看自己所有全年的出勤信息。该模块的功能是学生考勤信息统计的实现、查看及管理,涉及学生和老师用户中的所有用户
    输入:老师录入学生需要修改的考勤信息,其中包括学号、信吗、专业班级及考勤情况
    输出:学生个人考勤信息及修改后的学生考勤信息

    四、详细设计本系统是基于数据库的学生考勤信息管理系统,实现了连接数据库,增加、删除、查询、修改学生信息的功能。通过Java语言设计一个学生考勤管理系统,包括学生查询信息、老师管理查看信息以及学生请假老师审批的设计。
    4.1 学生信息(Student)类
    类名:Student
    继承父类:无
    实现接口:无
    概述:学生在线查看自己所有的出勤信息;对密码进行修改等
    属性及说明:
    public String number; //定义一个学号public String major = "computer";// 专业初始化public String class1 = "1804";//班级初始化public String name = "xxx";//姓名初始化private String password;//定义一个密码public String att_s = "暂无考勤信息";//考勤信息初始化
    方法及说明:
    public void set_password(String password);//修改密码public void check_show(String password);//输出学生信息

    4.2 请假(Leave)类
    类名:Leave
    继承父类:无
    实现接口:无
    概述:学生提交的请假申请需要老师的审批,只有批准之后学生请假信息方可录入学生状态查询
    属性及说明:
    String name = "小栋", time ="3,4节课", reason = "感冒发烧,要打点滴";//初始化姓名、时间、原因String chooice = "agree";//初始化请假单的状态
    方法及说明:
    public void showStudent();//学生填写请假单public void showTeacher();//老师对请假单的操作public void LeaveStates();//学生查看请假单的状态

    4.3 老师信息(Teacher)类
    类名:Teacher
    继承父类:Student
    实现接口:无
    概述:老师对学生的考勤信息进行录入、修改、统计,在线管理学生出勤信息
    属性及说明:
    private String number1; //账号private String password1;// 密码public Teacher();//默认的构造函数public Teacher(String number,String name,String major,String class1,String att_s)//带参数的构造函数
    方法及说明:
    public void get_pass(String number,String password);//储存登录密码public void set_pass(String password);//修改密码public void check_in();//考勤录入public int check_set(String num);//考勤修改public void check_s();//考勤统计

    4.4 测试(Main)类
    类名:Main
    继承父类:无
    实现接口:无
    概述:对学生查询信息、老师管理查看信息以及学生请假老师审批的设计在主菜单中的实现
    属性及说明:
    String number;//登录账号(老师的职工号;学生的学号)String password;//登录密码Teacher get = new Teacher();//构建Teacher类的对象(储存老师的账号和密码)Student got = new Student();//构建Student类的对象Leave stu = new Leave();//构建Leave类的对象
    方法及说明:
    get.get_pass(number, password);//使用账号和密码登录get.set_pass("...");//修改密码stu.showTeacher();//老师审批请假条for(int c = 3;;)check[c].check_in();//用循环多次录入学生考勤

    五、系统实现学生考勤管理系统的主要任务是用计算机对学生、出勤状况等信息进行日常的管理。如查询、修改、增加、删除以及存储等,迅速准确地完成各种信息的统计计算和汇总工作,针对系统服务对象的具体要求,设计了学生考勤管理系统。该系统除了能实现信息的录入,删除,插入,更新,打印等基本功能之外,还能够根据用户的需要进行操作。
    该系统实现的流程图如下:

    5.1 主界面
    登录考勤系统界面,通过该界面选择用户身份为老师后登录;输入功能选择,系统自动加入相应操作的界面。

    登录考勤系统界面,通过该界面选择用户身份为老师或学生后登录到各自相应的菜单功能界面;输入功能选择,系统自动加入相应操作的界面。(模块未注明用户为老师用户)
    5.2 修改密码模块

    修改密码时,系统提示输入旧密码,但旧密码错误时,系统自动判断提示:密码输入错误,请重输。修改密码需要进行两次输入新密码才能进行操作,从而使密码修改成功。

    当旧密码输入成功时,系统自动进行下一步操作实现修改密码。
    5.3 请假模块
    老师用户在选择请假批准功能时,系统将学生上传的请假条进行展示,给老师审批;输入agree代表同意,输入disagree带表不同意;系统根据用户输入的信息判断程序下一步的运行状况。


    学生用户通过选择用户身份登录主菜单后选择功能2请假申请,用户根据系统提示写请假条,请假成功。

    功能3请假情况查询为学生通过请假申请录入请假信息后得到的学生请假条。
    5.4 考勤模块
    当老师用户选择功能3考勤录入时,系统提示输入需要输入考勤的学生信息,包括学号、姓名、专业、班级、考勤情况;系统提示用户继续录入按数字1,不录入按任意键返回。

    学生通过功能4考勤情况查询自己的考勤信息;该学生信息暂未由老师录入,所以该学生的考勤信息暂无,考勤情况可由老师用户登录进行录入、修改和删除。

    老师用户选择其相应的功能菜单功能4考勤修改时自动提示用户输入需要修改考勤信息学生的学号,系统后台数据库将该学生的考勤信息进行调用给用户查看,提示用户依次输入要修改考勤学生的学号、姓名、专业班级、考勤情况等信息。 
    老师用户在修改学生考勤信息之后,选择功能5考勤统计查看所有修改、添加、原有的学生考勤信息。
    总 结课程设计顺利完成,题目所要求的功能也都一一实现,可以对学生的缺课信息进行添加、修改、删除以及查询的显示。但这个程序还有些不够完善,例如不能类中很好的进行承接。
    参考文献[1] 张利锋,孙丽.Java语言与面向对象程序设计[M].清华大学出版社,2015.
    [2] 黄平牧 编.面向对象与Java程序设计[M].清华大学出版社,2015.
    [3] 严莉,刘丹.Java面向对象程序设计实验教程[M].华中师范大学出版社,2015.
    [4] 李恩临.基于JAVA的面向对象开发技术[M].中国财富出版社,2016.
    [5] 张永强.计算机软件Java编程特点及其技术分析[J].计算机产品与流通,2019(01):25.
    [6] 魏华.计算机软件开发的JAVA编程语言与实际应用分析[J].数码世界,2018(8).
    [7] 王娟.基于计算机软件开发的JAVA编程语言分析[J].数字通信世界,2017(12).
    [8] 高阳.JAVA编程语言在计算机软件开发中的应用[J].电脑迷,2018,No.94(05):55.
    [9] 邢如意.Java语言中对象的理解与应用[J].软件工程,2017(4).
    [10] 刘妍东[1].Java类的继承[J].科教导刊(电子版),2017:175.
    5 评论 207 下载 2020-08-09 11:03:49 下载需要10点积分
  • 基于JSP和MySQL实现的图书管理系统

    摘要本设计以图书管理业务为对象,系统实现用的前台开发工具是eclipse,后台数据库为MySQL。设计过程中的重点和难点是对整个系统的需求分析和数据库详细设计。
    该系统对数据进行保存、修改、删除等管理。为用户提供了一个友好、简单快捷的运行操作平台。该系统对数据进行保存、修改、删除等管理,为用户提供了一个友好、简单快捷的运行操作平台。本系统的各界面设计友好、流程正确、功能也较为完善,旨在为用户提供方便快捷的服务,使人们走近书籍,走进书籍,热爱读书。
    本次设计意在为图书管理行业提供一个简便、易操作、可靠的借还管理系统,实现图书借阅、书店人员的更新及管理。
    关键词:MySQL;图书管理系统;借书还书;排行榜;问题反馈
    1 前言随着社会经济的迅速发展和科学技术的全面进步以及计算机事业的飞速发展,以计算机科学与通信技术为基础的信息管理系统IE处于蓬勃发展的时期。随着经济文化水平的显著提高,人们对生活质量及工作环境的要求也越来越高,但伴随着人的劳动强度的增大,以及社交活动的广泛开展,如何来提高人民纸质书本阅读量,是一个很现实的问题。无疑,科技的蓬勃发展使更多人依赖电子书,逐渐失去了对阅读纸质书本重要性的理解。如今书籍的发展,也继承了信息化的发展道路,网络的兴起,给了人们各种各样不同的选择。与此同时,为了管理好一个书店的正常营运,管理问题也就提上了日程。随着图书借阅问题的白热化,管理难度也越来越大,如何优化书店的日常管理也就成为了一个大众化的课题。
    在计算机飞速发展的今天,将计算机这一信息处理利器应用于书店的日常管理已是势必所然,面且这也将为商店管理带来前所未有的改变,它可以带来意想不到的效益,同时也会为书店的飞速发展提供无限潜力。采用计算机管理信息系统已书店管理科学化和现代化的重要标志。要想在激烈的市场竞争中立于不败之地,没有现代化的管理是万万不行的。
    通过对书店管理日常工作的详细调查,搜集了大量的资料,从系统结构的组织,功能的实现,技术的要求以及可行性等多方面进行考虑,我认为本课题是一个适应现今书店信息管理需求的计算机信息管理系统,具有一定的实际开发价值和使用价值。
    2 概述2.1 系统主要功能
    读者:登录注册,借阅还书,查询书籍,查看当前借阅信息以及历史借阅信息,查看、查询读者借阅榜以及借阅书籍借阅榜,问题反馈以及查询反馈结果等功能
    管理员:对图书、图书分类、读者信息的增删改查,查看全部读者当前借阅信息以及借阅历史,查看、查询书籍借阅榜及读者借阅榜,查看、查询用户反馈信息并修改反馈状态(未解决或已解决)
    超级管理员:除管理员权限外,新增管理员权限。对管理员信息进行增删改功能。为书店员工定制个人账号,方便管理

    2.2 系统相关说明为图书管理行业提供一个简便、易操作、可靠的借还管理系统,实现图书借阅、书店人员的更新及管理。
    本设计以图书管理业务为对象,系统实现所用前台开发工具是eclipse,后台数据库为MySQL。设计过程中的重点及难点是对整个系统的需求分析和数据库详细设计。
    该系统对数据进行保存、修改、删除等管理,为用户提供了一个友好、简单快捷的运行操作平台。本系统的各界面设计友好、流程正确、功能也较为完善,旨在为用户提供方便快捷的服务,使人们走近书籍,走进书籍,热爱读书。
    3 运行环境3.1 系统的运行环境3.1.1 系统运行硬件环境
    CPU:PIV1.6G以上
    内存:256M以上
    硬盘:40G以上
    其他:光驱、3.5英寸软驱、鼠标

    3.1.2 系统运行软件环境
    操作系统配置:Windows 10
    开发软件:eclipse
    编译环境:JDK1.8
    服务器:Tomcat
    驱动:JDBC
    数据库:MySQL
    框架:bootstrap

    3.2 网络环境本系统需要运行在单位局域网,要求服务器、客户端计算机连接在此网络上。
    4 安装与配置4.1 安装
    eclipse的安装
    Tomcat服务器的安装
    MySQL数据库的安装

    4.2 配置
    Windows 10操作系统的配置
    JDK1.8环境的配置
    Tomcat服务器的配置
    JDBC驱动的配置
    MySQL数据库的配置

    5 操作说明该系统是基于eclipse的系统软件,在Tomcat服务器上运行主页面:http://localhost:8080/books/login.jsp(直接运行功能页面会报错)
    根据输入的学号/工号及密码进入不同的主页面,主页面附有本项目各页面的操作简介,方便用户进行操作。
    每个界面相应的功能再后续介绍中会一一指出,如有疑问或建议也可以进入反馈页面告知管理员,管理员会尽快联系您并解决问题。操作完毕后单机右上角的“退出”模糊框退出系统。
    5.1 进入登录界面输入账号(学号/工号)、密码及验证码进行登录,后台根据不同的账号密码识别到用户身份进入相应的主页面。尚未注册点击“注册即可快速注册”,也可以联系管理员添加账号。
    登陆界面

    注册页面

    登陆失败(密码、验证码错误)

    5.2 进入系统5.2.1 读者界面系统界面由图书查询、借阅信息、借阅历史、热门推荐、最佳读者、问题反馈构成。左上角“欢迎使用图书管理系统”字样在每一个功能页中都有,单击可以跳转到当前页面(主页面),右上角的模糊框(图5.5)内有以下三个功能:修改个人资料(图5.6),修改密码(图5.7),退出系统。
    读者界面

    模糊框

    修改个人资料

    修改密码

    5.2.2 管理员与超级管理员界面系统界面由图书管理、读者管理、图书分类管理、图书借阅信息、图书归还信息、管理员管理(需登录)(图5.9)、热门推荐、最佳读者、读者反馈构成。其中管理员管理功能为超级管理员管理权限(图5.10)。左上角“欢迎使用图书管理系统”字样在每一个功能页中都有,单击可以跳转到当前页面(主页面),右上角的模糊框内功能与读者页面功能相同。
    管理员界面

    超级管理员登录

    超级管理员权限

    5.3 图书查询列出馆内所有图书的信息,包括图书号、图书类型、图书名称、作者名称、出版社、总数量。可以根据书名、作者、图书分类查询图书(图5.12),点击借阅按钮弹窗确认借阅,完成借阅图书操作(图5.13)。
    图书查询功能页

    查询图书

    借阅图书弹窗

    5.4 借阅信息展示当前登录的读者正在借阅的图书信息。记录借阅日期与截至还书日期,延长期限需联系管理员,通过管理员权限进行延期操作。点击还书按钮弹窗确认还书,完成还书操作。
    借阅信息功能页

    确认还书弹窗

    5.5 借阅历史展示当前登录的读者历史借阅的图书信息。记录借阅日期与还书日期。
    借阅历史功能页

    5.6 热门推荐根据借阅次数由高到低实时排序,展示图书的所有信息,可以根据书名、作者、图书分类查询图书,点击借阅按钮弹窗确认借阅,完成借阅图书操作。

    5.7 最佳读者根据借阅量由高到低实时排序,展示读者的ID、姓名、账号,可以根据以上信息查询读者借阅量以及当前排名。

    5.8 问题反馈根据给出的提示信息填写反馈内容,提交后转到反馈结果页面(图5.20),3s后自动跳转到“我的反馈”(图5.21),查看当前登录账号的历史反馈记录以及反馈信息的状态(未解决或已解决)。也可以在反馈页面直接链接跳转到“我的反馈”进行查看。
    问题反馈功能页

    反馈结果页面

    我的反馈页面

    5.9 图书管理列出馆内所有图书的信息,包括图书号、图书类型、图书名称、作者名称、出版社、总数量。可以根据书名、作者、图书分类查询图书。添加图书弹出模糊框(图5.23)。点击修改按钮模糊框内修改图书信息(图5.24),点击删除按钮弹窗确认删除,完成删除图书操作(图5.25)。
    图书管理功能页

    添加图书模糊框

    修改图书信息模糊框

    删除图书弹窗

    5.10 图书管理列出记录的所有读者的信息,包括ID、账号、姓名、邮箱、手机号、可借阅天数、最大可借数。添加读者弹出模糊框(图5.27)。点击修改按钮模糊框内修改读者信息,点击删除按钮弹窗确认删除,完成删除读者操作。
    读者管理功能

    添加读者模糊框

    5.11 图书分类管理列出馆内所有图书分类信息,包括ID和图书分类名称。添加分类弹出模糊框(图5.29)。点击修改按钮模糊框内修改图书分类信息,点击删除按钮弹窗确认删除,完成删除图书分类操作。
    图书分类管理功能页

    添加分类模糊框

    5.12 图书借阅信息展示所有读者正在借阅的图书信息。记录图书、读者信息与借阅日期、截至还书日期,还书按钮帮助读者还书,点击还书按钮弹窗确认还书,完成还书操作。延期按钮修改截至还书日期(图5.31),一般以月为单位。
    图书借阅信息功能页

    延期模糊框

    5.13 图书归还信息展示所有读者已归还的图书信息。记录图书、读者信息与借阅日期、还书日期。

    5.14 管理员管理(需登录)图示已在5.2.2中给出,此选项仅供超级管理员使用,进入本页面需再次登录,且指定唯一账户密码(即为超级管理员账户密码),其中,添加管理员弹出模糊框(图5.33)。

    5.15 热门推荐根据借阅次数由高到低实时排序,展示图书的所有信息,可以根据书名、作者、图书分类查询图书。

    5.16 最佳读者根据借阅量由高到低实时排序,展示读者的ID、姓名、账号,可以根据以上信息查询读者借阅量以及当前排名。

    5.17 读者反馈列出记录的所有读者反馈信息,包括ID、读者ID、标题、问题页面、问题描述、联系电话及问题状态。可以根据读者ID、标题、问题页面、问题描述以及问题状态信息查询反馈信息。点击修改按钮模糊框内修改问题状态(图5.37),点击删除按钮弹窗确认删除,完成删除图书操作。
    图书借阅信息功能页

    修改问题状态模糊框

    6 数据库信息6.1 读者 admin表设置读者ID aid自10000起自动增长,账号 username非空(用于登录),借阅量 times默认为0,身份 status默认为1(读者),超级管理员添加管理员时将该项初始为2(管理员)。
    DROP TABLE IF EXISTS `admin`;CREATE TABLE `admin` ( `aid` int(0) NOT NULL AUTO_INCREMENT, `username` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `name` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` char(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `email` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `phone` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `times` int(0) NULL DEFAULT 0, `status` int(0) NULL DEFAULT 1, `lend_num` int(0) NULL DEFAULT NULL, `max_num` int(0) NULL DEFAULT NULL, PRIMARY KEY (`aid`, `username`) USING BTREE, INDEX `username`(`username`) USING BTREE, INDEX `name`(`name`) USING BTREE, INDEX `status`(`status`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 10006 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    6.2 图书 book表设置图书ID bid自2000001起自动增长,书名 name、书号 card、图书数量 num非空,借阅量 times默认为0。
    DROP TABLE IF EXISTS `book`;CREATE TABLE `book` ( `bid` int(0) NOT NULL AUTO_INCREMENT, `name` char(205) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `card` char(205) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `autho` char(205) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `num` int(0) NOT NULL, `press` char(205) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `type` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `times` int(0) NULL DEFAULT 0, PRIMARY KEY (`bid`) USING BTREE, INDEX `card`(`card`) USING BTREE, INDEX `name`(`name`) USING BTREE, INDEX `type`(`type`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 2000007 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    6.3 图书分类 booktype表设置图书分类ID tid自3001起自动增长,分类名 name非空。
    DROP TABLE IF EXISTS `booktype`;CREATE TABLE `booktype` ( `tid` int(0) NOT NULL AUTO_INCREMENT, `name` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (`tid`) USING BTREE, INDEX `name`(`name`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 3005 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    6.4 历史记录 history表设置记录ID hid自400001起自动增长,记录状态 status已归还为0,未归还为1。
    DROP TABLE IF EXISTS `history`;CREATE TABLE `history` ( `hid` int(0) NOT NULL AUTO_INCREMENT, `aid` int(0) NULL DEFAULT NULL, `bid` int(0) NULL DEFAULT NULL, `card` int(0) NULL DEFAULT NULL, `bookname` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `adminname` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `username` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `begintime` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `endtime` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `status` int(0) NULL DEFAULT NULL, PRIMARY KEY (`hid`) USING BTREE, INDEX `status`(`status`) USING BTREE, INDEX `aid`(`aid`) USING BTREE, INDEX `bid`(`bid`) USING BTREE, INDEX `bookname`(`bookname`) USING BTREE, INDEX `adminname`(`adminname`) USING BTREE, INDEX `username`(`username`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 400010 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    6.5 反馈信息 problem表设置信息ID pid自5000001起自动增长,问题状态 status默认为“未解决”。
    DROP TABLE IF EXISTS `problem`;CREATE TABLE `problem` ( `pid` int(0) NOT NULL AUTO_INCREMENT, `aid` int(0) NULL DEFAULT NULL, `name` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `page` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `body` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `phone` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `status` char(5) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '未解决', PRIMARY KEY (`pid`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 5000002 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    7 类图7.1 用户管理
    7.2 系统信息
    7.3 操作及反馈信息
    总结经过一个学期对《Javaweb开发技术》的学习,我学习到了更多的理论知识,学习了HTML表单、CSS技术、JS前台校验技术、JavaScript方法调用、JSP的基本语法、JSP内置对象的使用、servlet方法、页面的跳转等技术。这些技术都为我的课程实践和进一步的学习打下了坚实的基础。
    14 评论 96 下载 2020-11-11 14:31:50 下载需要12点积分
  • 基于C++实现的小型超市管理系统

    1.系统设计说明1.1 需求分析本次设计主题为小型超市管理系统,根据研究分析,该管理系统主要是对商品不同种类信息进行分别储存,修改,查询,增加,删除,对于库存和销量的排序以及文件的读取。对此我们应该明确需求,从而能够合理设计程序。
    1.2 系统功能描述主菜单一共有七个功能,分别是:商品录入和修改(对商品信息进行录入和二次修改),商品的的增加(重新增加商品),商品的删除(删除原有商品信息),商品的查询(查询已有商品),商品的排序(对商品的库存和利润进行排序),信息储存(将商品信息存如txt文件)和信息读取(从txt文件中读取商品信息)。
    功能模块图

    1.3 系统流程分析增加商品流程图

    商品录入、修改、删除流程图

    2.存储数据结构设计说明2.1 数据结构分析和设计设计了一个基类,里面有价格,名字,成本,结余,入货日期等变量,同时还有输入、输出、计算总利润等函数。同时派生出六个派生类。每个类都有相同的成员函数实现多态。


    class basic//基类

    double price;//价格 char name[n];//名字 double cost;//成本 int surp;//结余 long int date;//入货日期 char unit[n];//计量单位char unit1[n];//计量单位2double getmoney()//计算利润void setdata()//输入信息void display()//展示信息
    class fvm :public basic//水果蔬菜和肉类

    char fvmnumber[n];//编号int fvmtimes;//批次long int fvmdate[max];//入货日期 int fvminnumber[max];//入货数量void ssetdata()//输入所有数据 void setin()//输入进货批次,日期和进货量 void set(){//更改数据 void sdisplay()//输出数据

    其他类和水果蔬菜和肉类类似。
    2.2 数据记录如何创建通过类定义数组,输入数据进行创建。
    outfile.open(文件名,ios::out);if(!outfile){ cerr<<"open error"<<endl; return -1;}for (int i=0;i<a1;i++){ outfile<<文件内容;}
    3.应用界面设计说明界面列表

    各界面中主要变量、函数:

    录入:void ssetdata()
    增加:利用for循环
    删除:利用for循环对数据删除
    cout<< "请输入要删除的商品编号"; cin>>c;itemp =-1;for(int i=0;i<a3;i++){ if(strcmp(c,snacksji[i].snumber)==0) { cout<<"成功查询"; itemp =i; }}if(itemp!=-1){ for(int a=itemp+1;a<a3;a++) { snacksji[a-1]=snacksji[a];} a3=a3-1; cout<<"删除成功"<<endl;}else cout<<"没有找到该编号"<<endl;
    查询:void sdisplay()//输出数据
    排序:定义新数组
    typedef struct { int sell;//库存 double money;//利润 char tname[n];//名字 }rectype;进行排序算法
    文件储存
    outfile.open(文件名,ios::out);if(!outfile){ cerr<<"open error"<<endl; return -1;}for (int i=0;i<a1;i++){ outfile<<文件内容;}
    文件读取
    FILE *fp;if((fp = fopen("fvm.txt","r")) == NULL){ fprintf(stderr," 文件打开失败!\n"); exit(0); } cin>>a1;for(int i=0; i<a1; i++) //循环读取{ fscanf(fp,"%s%lf%lf%d%d",&a[i].tname,&a[i].p,&a[i].c,&a[i].sell,&a[i].d); cout<<文件信息;}fclose(fp);

    4.遗留问题数组定义太复杂太多,类继承整理不清晰。对于原来文件的和类的定义还是很模糊。代码过于冗杂,而且设计思路有所欠缺。
    2 评论 115 下载 2020-06-09 15:00:23 下载需要10点积分
  • 基于JSP+Servlet+MySQL校园二手交易平台

    摘 要本系统采用JSP/servlet技术,是使用Java编程语言编写的一套校园网二手交易平台软件。系统采用的是最近几年流行的B/S开发模式,以互联网方式运行,服务器端只需要安装本系统,而客户端用户只要可以上网,就可以非常方便快捷的通过浏览器访问系统,浏览和发布二手交易信息,免去了传统的C/S模式下复杂的安装、配置、维护等操作。同时由于使用面向对象的Java语言,所以本系统也具有Java语言的面向对象、与平台无关、安全性高、稳定性高、多线程等特性,以及Java语言对网络编程技术的支持。使得本系统具有很高的使用价值。
    系统开发采用了实现MVC模式的Web应用组件:Struts,实现数据持久化功能的ORM组件:Hibernate,用JSP+HTML+JavaScript进行界面处理,数据库采用比较稳定的MySQL 5.0,并用JDBC进行数据库访问。
    关键词:JSP,Struts,Hibernate,MySQL,二手交易平台
    ABSTRACTThis system is a set of platform software of the campus-wide system secondhand transaction. It adopts the JSP/J2EE technique, and programmed with Java programming language. It also adopts the B/S development mode, which is based on Web and popularize in recent years. It runs in internet ways. Only when the server install this system and the client can visit it, browse and release some secondhand conveniently and speedily when they go on-line. And so it dispenses with such operation as the complicated installing, installment and support in traditional C/S mode. At the same time, it uses the Java language which towards the OOP(object-oriented programming).So the system has the specific property of towarding OOP, irrelevant with the platform ,the Java language’s support to the network programming technique makes the system have high practical value.
    The System using the components of Web applications: Struts to achieve MVC model, using the ORM components: Hibernate to achieve data persistence features, using JSP + HTML + JavaScript to Show page. using Relatively stable database MySQL 5.0, and use JDBC to visit.
    KEY WORDS: JSP,Struts,Hibernate,MySQL,Campus Secondhand Merchandise
    1 系统分析1.1 开发背景随着全世界互联网技术的不断发展,各种基于互联网技术的网络应用不断涌现,网络技术正在不断的深入人们的生活。人们从Internet上获取信息、享受生活、交流感情、网上工作等。Internet正在迅速改变着人们的生活方式。
    经过我国改革开放多年以后,随着与国际社会的接轨,各种资源的商品化已经逐渐成为了我们这个社会的代名词。在这这情势下,校园二手商品资源也已极大的丰富起来,如何解决一类问题,争取最大利用率的交流这类商品的信息便是一个存在中的问题。本毕业设计便是解决该问题的。
    1.2 目的和要求在当前社会上,许多的各种类型的电子商务类网站纷纷建立,可以很大程度上的解决人们信息资源的闭塞以及地域上的限制。作为大学校园,伴随着学生的购买能力的提高和每年的升学和毕业,也存在的许多各种类型的二手商品,由于信息交流的落后,很多只限于于校园公告栏或者请人代为宣传的方式进行交易。这种方式有很多局限性和偶然性,并不能满足二手商品畅通交流的要求。于是一种新的二手商品信息交流的方式出现了,就是基于Web的校园网二手商品交易系统。通过这个系统,可以发现每一个校园网用户都是系统的主人,大家可以非常方便的发布自己的信息,浏览别人的发布的信息,还可以对各种二手商品信息作出横向比较,作出自己的最佳选择。由此可见,该系统只是一个交流二手商品信息的平台,与一般的电子商务类网站又有本质的区别。
    1.3 可行性研究设计这样一个系统,从根本上解决了传统的校园二手信息发布交流方式的弊端,使得校园各种二手商品信息得到了有效的整合,方便了广大用户。且拥有的客户通常只是大学校园网的用户,所有系统规模上来讲不会很大,从经济上来说,由于选择的开发工具和服务器几乎全部为免费的开源软件,并且由于是开发成本较低的基于Web的B/S模式,而非成本费用相对较高的C/S模式,所以从经济上来讲是可行的。从技术上来说,由于是基于Web的,可以相对比较容易面对用户的实际需求而开发。而在现今,各种网络应用的开发已经相当成熟,出现了几大主流的开发语言和工具,都可以非常有效的支持开发这样一个系统。同时作为本系统,也有许多成功的电子商务类网站的经验可以借鉴,所以从技术的角度来说,也是可行的。从运行上来说,由于客户端仅仅只是需要一个浏览器,通过浏览器来登陆系统,而服务器端也只需要一台服务器,服务器要求一个数据库环境和一个网络应用开发的环境,实现起来比较容易,所以从运行上来说是可行的。同时这样一个系统,在系统管理员合法管理和用户的自觉配合下,不会违规进行任何的不法的活动和交易,发布具有危害性和不适宜的信息,也不存在任何非法牟利的行为,在法律上也是可行的。在各种可行性研究保证和基于用户需求要求下,开发系统的方案经过不断论证和假设,确定出了一个最佳方案。
    2 开发技术及开发环境2.1 Java语言简介Java语言是美国Sun公司于1995年推出的一种简单的、面向对象的、分布式的、可解释的、键壮的、安全的、结构的、中立的、可移植的、性能很优异的多线程的、动态的语言。其前身为OAK语言,是SUN公司为一些消费性电子产品而设计的一个通用环境。他们最初的目的只是为了开发一种独立于平台的软件技术。经过Sun公司的工程师的不懈努力以及全世界无数的编程爱好者的使用,Java终于发展成为今天这样一个集桌面(J2SE)、网络(J2EE)、移动平台(J2ME)应用为一体的功能强大的编程语言。目前Java由于其平台无关及分布式特性,最重要的应用是在网络应用上[1]。
    2.2 J2EE技术介绍J2EE技术是Java网络应用的技术,广泛应用于企业级的应用。它是由一套规范(shannin,2001)和建立在J2SE平台上的应用编程接口(API)组成。J2EE拥有Sun公司提供免费开发工具,称为J2EE软件开发工具包(Software Development Kit,SDK )( http://java.sun.com/j2ee )。J2EE技术是一种Java网络应用技术的组合,包含有远程方法调用(Remote Method Invocation,RMI)、Java消息服务(Java Message Service,JMS)、JavaMail等通信服务,JDBC、Java命名和目录接口(Java naming and Directory Interface,JNDI)、Java连接器体系结构(Java Connector Architecture,JCA)、Java事务API/Java事务服务(JTA/JTS)、XML处理API等通用服务以及Servlet、Java服务器页面(JSP)、企业级JavaBean(EJB)等组件技术。任何J2EE的实现都必须要在其特定容器中实现。
    2.3 Servlet/JSP技术Servlet是JSP技术的基础,JSP本身就是预先被编译成Servlet,然后再运行的,而且大型的Web应用程序的开发需要Java Servlet和JSP配合才能完成。 Servlet其实和传统的CGI程序和ISAPI、NSAPI等Web程序开发工具的作用是相同的,在使用Java Servlet以后,用户不必再使用效率低下的CGI方式,也不必使用只能在某个固定Web服务器平台运行的API方式来动态生成Web页面。许多Web服务器都支持Servlet,即使不直接支持Servlet的Web服务器也可以通过附加的应用服务器和模块来支持Servlet。JSP(JavaServer Pages)是一种基于Java的脚本技术。在JSP 的众多优点之中,其中之一是它能将 HTML 编码从 Web 页面的业务逻辑中有效地分离出来。用 JSP 访问可重用的组件,如 Servlet、JavaBean 和基于 Java 的 Web 应用程序。JSP 还支持在 Web 页面中直接嵌入 Java 代码。可用两种方法访问 JSP 文件:浏览器发送 JSP 文件请求、发送至 Servlet 的请求。

    JSP 文件访问 Bean 或其它能将生成的动态内容发送到浏览器的组件
    发送至 Servlet 的请求生成动态内容,并调用 JSP 文件将内容发送到浏览器。该访问使得将内容生成从内容显示中分离出来更为方便

    JSP最大的优点在于其与平台无关性,具有“一次编写,处处运行”的特点。
    2.4 MVC 简介模型-视图-控告器(MVC)是20世纪80年代Smalltalk-80出的一种软件模式,现在已经被广泛使用。

    模型(Model):模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑
    视图(View):视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面
    控制器(Controller):控制器的工作就是根据用户的输入,控制用户界面显示和更新模型对象的状态

    典型的MVC模式所包含的模块、每个模块的功能以及模块之间的关系如图2-1所示[2]:

    MVC模式的出现不仅实现的功能模块和显示模块的分离,同是赛马场还提高了应用系统的可维护性、可扩展性、可移植性和组件的可利用性。
    在早期的程序中,如果不注意对数功能和显示的解耦合,常常估导致程序的复杂及难以维护,像VB,Delphi等RAD程序都有这种问题。甚至现在有C#,Java有时候也会出现把业务逻辑写在显示模块中的现象。
    尽管MVC设计模式很早的提出了,但在Web项目的开发中引入MVC却是步履艰难。主要原因是在早期的Web项目开发中,程序语言和Html的分离一直难以实现,CGI程序以字条串输出的形式动态的生成html内容。直到基于J2EE的JSP Model2问世时才得以改观。它用JSP技术实现视图的功能,用Servlet技术实现控制器的功能,用JavaBean实现模型的功能。JSP Model2 结构如图2-2所示:

    在Model 2这种框架结构中,Servlet作为控制器负责处理用户的请求以及创建JSP页面中所有要使用的Bean对象,并且还要根据用户的请求来返回到不同的JSP页面。
    在使用Model 2开发框架时,一定要保证在JSP页面中不能包含任何的业务处理逻辑。它只是简单地得到对象或者在Servlet中创建的Bean,然后通过这些动态的内容来生成动态显示的页面。
    Struts 本质上就是在Model 2的基础上实现一个MVC架构,它只有一个中心控制器,采用定制转向的URL并采用Action来处理逻辑。
    2.5 Struts 技术Struts是一个为开发基于模型(Model)-视图(View)-控制器(Controller)(MVC)模式的应用架构的开源框架,是利用Java Servlet和JSP构建Web应用的一项非常有用的技术。首先事件是指从客户端页面(浏览器)由用户操作触发的事件,Struts使用Action来接受浏览器表单提交的事件,这里使用了Command模式,每个继承Action的子类都必须实现一个方法execute。
    struts重要的表单对象是ActionForm,它代表了一种应用,这个对象中至少包含几个字段,这些字段是Jsp页面表单中的input字段,因为一个表单对应一个事件,所以,当我们需要将事件粒度细化到表单中这些字段时,也就是说,一个字段对应一个事件时,单纯使用Struts就不太可能,当然通过结合JavaScript也是可以转弯实现的。
    Struts是一个基于Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的。Struts把Servlet、JSP、自定义标签和信息资源(message resources)整合到一个统一的框架中,开发人员利用其进行开发时不用再自己编码实现全套MVC模式,极大的节省了时间。
    Struts包含了一组想相互协作的类、Servlet和JSP标记,它们共同组成了一个可重用的MVC模板。通过定义可以看出,Struts是Web应用的开发框架,Struts包含丰富的标记库和独立于该框架工作的实用程序类。图2-3 显示了Struts的基本结构。

    通过图 2¬-3可以看出,采用Struts框架结构的Web应用程序主要由控制器、业务逻辑、模型和视图组成。其中的控制器、模型和视图为Struts框架的主要组成部分,而事务逻辑则是我们需要实现的系统业务逻辑处理部分。
    2.6 Hibernate 技术2.6.1 应用程序的分层体系结构随着计算机应用软件的发展,应用程序逐渐由单层体系结构发展为多层体系结构。其中,三层结构是目前典型的一种应用软件结构。

    表述层:提供与用户交互的界面,如GUI(图形用户界面),web页面等
    业务逻辑层:负责各种业务逻辑,直接访问数据库,提供对业务数据的保存、更新、删除和查询操作
    数据库层:负责存放管理应用的持久性业务数据

    三层结构的特点:所有下层向上层提供调用的接口,具体实现细节对上层透明。层与层之间存在自上而下的依赖关系,即上层会访问下层的API,但下层不依赖于上层。
    分离出的持久化层封装了数据访问细节,为业务逻辑层提供了面向对象的API[2]。
    持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
    持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。
    三层软件结构如图2-4所示:

    数据库的读写是一个很耗费时间和资源的操作,当大量用户同时直接访问数据库的时候,效率将非常低,如果将数据持久化就不需要每次从数据库读取数据,直接在内存中对数据进行操作,这样就节约了数据库资源,而且加快了系统的反映速度。增加持久化层提高了开发的效率,使软件的体系结构更加清晰,在代码编写和系统维护方面变得更容易。特别是在大型的应用里边,会更有利。同时,持久化层作为单独的一层,人们可以为这一层独立的开发一个软件包,让其实现将各种应用数据的持久化,并为上层提供服务。从而使得各个企业里做应用开发的开发人员,不必再来做数据持久化的底层实现工作,而是可以直接调用持久化层提供的API。
    2.6.2 Hibernate的应用及API简介Hibernate是一种Java语言下的对象关系映射解决方案。它是一种自由、开源的软件。它用来把对象模型表示的对象映射到基于SQL的关系模型结构中去,为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架。
    Hibernate不仅管理Java类到数据库表的映射(包括从Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。
    Hibernate对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合,它既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。最具革命意义的是,Hibernate可以在应用EJB(EnterpriseJavaBeans是Java应用于企业计算的框架)的J2EE架构中取代CMP,完成数据持久化的重任。
    Hibernate使用 Java 反射机制 而不是字节码增强程序来实现透明性。Hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。Hibernate支持各种关系数据库,从一对一到多对多的各种复杂关系。Hibernate核心接口如图2-5所示:

    2.7 开发环境及环境配置2.7.1 Java/JSP系统环境开发及测试的系统环境,我选择了Microsoft Windows Advanced Server 2000。由于其本身就是为服务器版的,适合用于搭设成为服务器端。要开发JSP,首先必须要求有Java环境,我选择了JavaTM Platform, Standard Edition 6 Development Kit。
    作为JSP的容器,选择了目前非常流行的Tomcat 6.0。而IDE工具则选择了Eclipse(MyEclips)。
    2.7.2 JSP环境的安装和环境变量的设置
    首先安装JDK,安装Tomcat
    接下来配置环境变量:右键点击“我的电脑”,在弹出的菜单中点“属性”,在系统特性里选择“高级”,找到“环境变量”,点击进入后,“系统变量”就是我们需要设置的地方

    新建变量CATALINA_HOME,变量值为:D:\apache-tomcat-6.0.18新建JAVA_HOME变量,然后在变量值中输入以下内容:C:\Program Files\Java\jdk1.6.0_12编辑path变量,在原有的变量值后添加JDK的BIN目录:%JAVA_HOME%\bin;%CATALINA_HOME%\BIN

    2.7.3 Eclipse开发工具Eclipse平台体系结构主要由5部分组成,分别是平台运行库、工作区、工作台、团队支持和帮助。
    在运行时内核是整个架构的核心,其他部件都是以插件方式来实现的。Eclipse采用动态加载机制,即只有需要的才加载,这样可以降低启动时间,提高资源使用效率。
    工作空间插件即所谓的工作区,主要负责管理用户资源,例如用户创建项目的管理、文件变更等,并负责通知其他插件关于资源变更的信息。
    工作台插件是Eclipse 提供的用户界面。它使用标准窗口工具包(SWT)和一个更高级的API(JFace)构建的。SWT是Java的Swing/AWT的非标准替代者,JFace则以SWT为基础,但更易于使用。
    团队支持插件负责提供版本控制和配置管理支持。它允许用户根据需要添加视图,并与允许用户使用的任何版本控制系统交互。
    帮助插件允许以HTML文件形式添加文档,并提供了一个附加的导航结构以便用户使用帮助功能搜索相关信息。
    2.7.4 Tomcat服务器Tomcat是Sun的JSWDK(Java Server Web Development Kit)中Servlet的运行环境(servlet容器)。Tomcat是Apache Jakarta软件组织的一个子项目,Tomcat是一个JSP/Servlet容器,它是在SUN公司的JSWDK(Java Server Web Development Kit)基础上发展起来的一个JSP和Servlet规范的标准实现,使用Tomcat可以体验JSP和Servlet的最新规范。经过多年的发展,Tomcat不仅是JSP和Servlet规范的标准实现,而且具备了很多商业Java Servlet容器的特性,并被一些企业用于商业用途[4]。
    Tomcat目录如下:
    Tomcat_home|---bin Tomcat:存放启动和关闭tomcat脚本|---conf Tomcat:存放不同的配置文件(server.xml和web.xml)|---doc:存放Tomcat文档|---lib/japser/common:存放Tomcat运行需要的库文件(JARS)|---logs:存放Tomcat执行时的LOG文件|---src:存放Tomcat的源代码|---webapps:Tomcat的主要Web发布目录(包括应用程序示例)|---work:存放jsp编译后产生的class文件2.8 数据库开发工具选择及配置目前数据库的开发工具,大、中、小型的有很多,比如Oracle、MS SQL Server2000、DB2、MySQL、Access等等许多关系数据库,在系统开发初期,我用SQL server2000 进行数据库连接,因为可以于Windows 2000服务器系统很好的兼容,并且对大并发访问有很好支持,功能强大且使用简单,然而在后期的开发中,由于经常更换设计环境,而且自己用到Hibernate,对软件有一定要求,每次系统移植都要花很多时间配置环境,所以又更换了移植性很好的MySQL做数据库。
    MySQL是一个小型关系型数据库管理系统,被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。
    与其他的大型数据库例如Oracle、DB2、SQL Server等相比,MySQL自有它的不足之处,如规模小、功能有限(MySQL Cluster的功能和效率都相对比较差)等,但是这丝毫也没有减少它受欢迎的程度。对于一般的个人使用者和中小型企业来说,MySQL提供的功能已经绰绰有余,而且由于MySQL是开放源码软件,因此可以大大降低总体拥有成本[3]。
    在本系统中,对MySQL的配置最重要是数据库字符编码设置,因为数据库的录入的大多是中文字符,默认编码为GBK会减少许多操作,配置如下:
    default-character-set=gbk3 系统需求分析及设计3.1 系统需求分析3.1.1 系统功能需求本系统主要面向于大学校园网用户,依托校园网提供给这些用户一个发布和交流二手商品信息的平台。在大学校园里,存在着很多的二手商品,但是由于信息资源的不流通以及传统二手商品信息交流方式的笨拙,导致了很多仍然具有一定价值或者具有非常价值的二手商品的囤积,乃至被当作废弃物处理。现在通过校园网进入到本系统,可以方便快捷的发布和交流任何二手商品的信息,并且可以通过留言方式进行深一步的交流。由于每个大学的校园网都基本篇布校园的每一个地方,因此,只要宣传得当,理论上来说,每一个人都可以让他所发布的信息让全校所了解,争取到了信息资源的最大化利用。
    系统完成的主要功能有:用户设置功能、发布信息功能、信息管理功能、搜索信息功能,留言功能,及系统管理功能,具体业务功能包括如下:

    用户注册:学生可利用自已学号进行注册,注册实现实名制
    用户登录:只有登录用户才能进行信息发布。管理员登录后可以进行系统管理
    发布信息:普通用户和管理员登录后都可以发布信息
    修改信息:普通用户可以修改自己发布的信息,管理员可以修改所有信息
    删除信息:普通用户可以删除自己发布的信息,管理员可以删除所有信息
    浏览信息:游客、普通用户和管理员可以浏览所有发布的信息
    搜索信息:游客、普通用户和管理员可以用关键字搜索所有发布的信息。普通用户可以搜索自己发布的所有信息
    发表留言:普通用户和管理员登录后都可以对发布信息进行留言
    查看留言:游客、普通用户和管理员都可以查看发布信息的留言
    删除留言:管理员可以删除留言
    添加二手指南:管理员可以添加二手指南
    查看二手指南:游客、普通用户和管理员都可以查看二手指南
    修改二手指南:管理员可以修改二手指南
    删除二手指南:管理员可以删除二手指南

    3.1.2 系统界面要求由于系统主要面向大学生,系统界面要求不能过古板,要能体现大学校园的自由,创新。系统界面设计应体现人性化,界面清晰简捷,操作简单流畅,提高管理效果。不需要任何专业培训,不需要配备专门的电脑操作人员,无电脑知识一样运用自如。关键在于系统的框架式设计简单明晰。
    3.2 概要设计3.2.1 系统体系结构设计本系统是一个典型的三层应用——浏览器通过Web服务器实现对数据库的各种操作。图3-1 展示了整个系统的体系结构。

    在这个系统体系结构中,并不是直接JDBC来访问数据库和进行数据库中相关表的操作,而是通过一系列持久层的Java对象来完成数据库的操作。
    映射文件相当于持久层的Java对象和数据库的表之间的桥梁,它所描述的是这两都之间的对应关系。而且,持久层的Java对象和数据库表之间的关系也是一一对应的。
    3.2.2 系统功能模块设计系统主要设计了用户设置功能、发布信息功能、信息管理功能、搜索信息功能,留言功能,及系统管理功能模块。

    用户设置功能:主要是用户注册必须填写所要求的个人资料,完成个人资料登入
    发布信息功能:主要是为已注册用户的服务,登陆的用户可以即时发布自己的二手商品信息,立刻就能浏览到。这是本系统的主要功能
    信息管理功能:是帮助已发表信息的的用户管理自身发布的二手商品信息的同时也管理短消息信息。此项功能也主要是服务于注册用户
    搜索信息功能:是面向所有登陆到本系统的人员的,采用模糊查询的方法,遍历所有二手商品信息,搜索出浏览者感兴趣的内容
    留言功能:是对某一二手商品信息进行留言,还可以查看该信息的其他留言
    系统管理功能:是系统管理员对系统所有信息资源进行统一管理的一个模块

    系统功能结构如图3-2所示:

    3.2.3 功能设计的目标与原则本二手交易平台的主要目的是服务于学生,方便学生进行网上交易。其原则是做到界面友好,操作简单且可靠。
    具体做到:

    架构清晰,界面友好美观,简捷,实用性强
    动态式信息发布:为充分展现网站的时实性,二手交易平台采用动态网页技术实现内容发布
    提供多种信息搜索及查看方式。全面自动化管理
    全面整合买家和卖家之间的信息,提供一个交流沟通的平台
    可用性,目标系统功能齐全,能够完全满足业务需求

    3.3 数据库设计3.3.1 数据库需求分析对于数据库的需求主要体现在对数据库的提交信息、更新信息、删除信息、保存信息等。这些信息的存在都取决于各个功能模块的对信息的需求。通过对功能模块的具体操作,实现对数据库中信息的输入和输出。所以,针对各个功能模块的需求,设计如下的数据表和数据结构:

    Maste 类表:用于实现平台用户我实名制及平台基本信息

    学院信息:包括学院编号,学院名,描述等班级信息:包括班级编号,班级名,学院编号,描述等学生信息:包括学号,姓名,班级编号,学院编号等类型信息:包括类型编号,类型名,类型描述等交易地区信息:包括地区编号,地区名,地区描述等
    Temp 类表:用于实现平台各模块

    用户信息:包括用户编号、用户名、密码、学号,及用户的其它相关信息等商品信息:商品编号、信息标题、信息内容,发布信息的用户,信息相关内容等商品留言信息:包括留言编号、商品信息编号、留言内容等

    3.3.2 数据库概念结构设计概念模型是对于信息世界的建模,是现实世界到信息世界的抽象,是数据库设计人员和用户之间进行交流的语言。它具有简洁明晰、易于理解和修改、便于向各种数据模型转换,从而生成相应的逻辑模式。
    概念设计的目的是要确定系统的概念模型,因为概念模型是数据库系统的核心和基础,所以概念设计是数据库设计的关键。
    3.3.3 数据库逻辑表设计数据库的概念结构设计完毕后,现在可以将上面的数据库概念结构转化为某种数据库所支持的实际数据模型,也就是数据库的逻辑结构。
    在本次设计开发中,考虑到系统的规模,以及系统的功能、稳定性、性能和效率等方面,特别的对系统可移植性的考虑,我使用MySQL数据库系统。
    依照3.3.1中的数据库需求分析设计各数据库表,各个表中都用ID做主键,困为用到Hibernate自动生成主键,所以这里主键ID类型设置为VARCHAR(50)。其它字段也都有各自的约束条件。
    各个表的具体逻辑结构如下:
    学院表 (m_dep)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    学院编号


    DEP_NAME
    VARCHAR(10)
    UNIQUE
    学院名


    DEP_DESC
    varchar(100)
    NOT NULL
    学院描述



    班级表(m_class)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    班级编号


    DEP_ID
    VARCHAR(50)
    Foreign Key
    学院编号


    CLASS_NAME
    VARCHAR(10)
    UNIQUE
    班级名


    CLASS_DESC
    varchar(100)
    NOT NULL
    班级描述



    学生表(m_student)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(12)
    Primary Key
    学号


    CLASS_ID
    VARCHAR(50)
    Foreign Key
    班级编号


    STU_NAME
    VARCHAR(10)
    UNIQUE
    学生姓名


    sex
    TINYINT(3)
    NOT NULL
    学生性别



    交易地区表(m_area)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    地区编号


    AREA_NAME
    VARCHAR(10)
    UNIQUE
    地区名


    AREA_DESC
    varchar(100)
    NOT NULL
    地区描述



    信息类型表(m_type)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    类型编号


    TYPE_NAME
    VARCHAR(10)
    UNIQUE
    类型名


    TYPE_DESC
    varchar(100)
    NOT NULL
    类型描述



    二手指南表(t_article)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    指南编号


    TITLE
    VARCHAR(10)
    UNIQUE
    指南标题


    CONTENT
    varchar(8000)
    NOT NULL
    指南内容



    用户表(t_user)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    用户编号


    USERNAME
    VARCHAR(10)
    UNIQUE
    用户名


    PASSWORD
    varchar(100)
    NOT NULL
    用户密码


    STU_ID
    VARCHAR(50)
    Foreign Key
    学号


    BIRTHDAY
    DATETIME
    NOT NULL
    生日


    PHOTO
    SMALLINT(5)
    NOT NULL
    照片


    QUESTION
    VARCHAR(100)
    NOT NULL
    注册问题


    ANSWER
    VARCHAR(100)
    NOT NULL
    注册答案


    EMAIL
    VARCHAR(50)
    —-
    EMAIL


    QQ
    VARCHAR(20)
    —-
    QQ


    CREATE_TIME
    DATETIME
    NOT NULL
    注册时间


    STATUS
    TINYINT(3)
    NOT NULL
    状态


    ROLE
    TINYINT(3)
    NOT NULL
    权限



    信息表(t_message)



    字段名
    数据类型
    约束条件
    说明




    ID
    VARCHAR(50)
    Primary Key
    信息编号


    MESSAGE_TITLE
    VARCHAR(50)
    UNIQUE
    信息标题


    TYPE_ID
    VARCHAR(50)
    Foreign Key
    信息类型


    AREA_ID
    VARCHAR(50)
    Foreign Key
    交易地区


    OLD_VALUE
    SMALLINT(5)
    NOT NULL
    新旧值


    PRICE
    DECIMAL(10,0)
    NOT NULL
    商品价格


    R_USER
    VARCHAR(10)
    NOT NULL
    联系人


    R_PHONE
    VARCHAR(50)
    NOT NULL
    联系电话


    R_EMAIL
    VARCHAR(50)
    —-
    EMAIL


    MESSAGE_DESC
    VARCHAR(200)
    NOT NULL
    信息详情


    MESSAGE_PHOTO
    VARCHAR(50)
    —-
    信息图片


    CREATE_TIME
    DATETIME
    NOT NULL
    新增日期


    FLAG
    TINYINT(3)
    NOT NULL
    信息标志


    TOP_VALUE
    INTEGER
    NOT NULL
    人气值


    CREATE_USER_ID
    VARCHAR(50)
    Foreign Key
    发布用户



    3.3.4 数据库逻辑结构设计对于maste表,它们都是做为别的表的外键而存在的。本系统数据库逻辑可分为两部分,一部分实现用户的实名制:实名制需要校方学生纪录,而学生又有以学院、班级,每个用户对应一个学生,其逻辑模型如图3-3所示:

    第二部分实现商品信息关联,每个商品都有商品类型、交易地区和发布用户,每个商品有多个留言,而每个留言又有发表用户,其逻辑模型如图3-4所示:

    3.4 数据库访问设计数据库访问是指对数据库进行操作,本系统使用Hibernate完成数据库表与java对象映射,并用HibernateSessionFactory进行数据库访问。
    3.4.1 数据库表模型设计所有数据库表中都有编号做为主键,在java类库中用BaseModel.java完成模型对象的基类。在BaseModel类中,属性id 做为所有表的主键,equals(Object o)是重写的父类方法,只要字符串内容相同,对象就相同;toString用于规范对象的打印格式。
    本系统包含的业务模型有:交易地区(Area),商品类型(Type),二手指南(Article),学院(Department),班级(Clazz),学生(Student),用户(User),信息(Message),留言(Comment),它们都对应于数据库中某张表。这些Java模型对象的数据类型与数据库表相对应,并都继承BaseModel,所有Model类的UMR如图3-5所示:

    3.4.2 Hibernate数据库访问配置Hibernate配置文件主要用于配置hibernate连接数据库的参数以及其它一些hibernate在运行时需要使用的各种参数的值。配置如图3-6所示:

    Hibernate是你的应用程序里连接数据库的那层,所以它需要连接用的信息。连接(connection)是通过一个也是由我们配置的JDBC连接池(connection pool)来完成的。Hibernate的发布包里包含了许多开源的(open source)连接池,但在我们例子中使用Hibernate内置的连接池。
    3.4.3 定义映射文件映射文件用于描述持久层对象以及它们的属性和数据库中的表和表的字段之间的对应关系,完成java对象和数据库中表的数据的相互转化,这里只介绍用户对象的映射配置。
    文件清单如下:
    <?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.lee.market.model"> <class name="User" table="T_USER" schema="dbo" catalog="market_1"> <id name="id" type="string"> <column name="ID" length="50" /> <generator class="uuid.hex" /> </id> <many-to-one name="MStudent" class="Student" fetch="select"> <column name="STU_ID" length="50" not-null="true" /> </many-to-one> <property name="username" type="string"> <column name="USERNAME" length="50" not-null="true" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="50" not-null="true" /> </property> <property name="birthday" type="timestamp"> <column name="BIRTHDAY" length="23" not-null="true" /> </property> <property name="photo" type="integer"> <column name="PHOTO" not-null="true" /> </property> <property name="question" type="string"> <column name="QUESTION" length="50" not-null="true" /> </property> <property name="answer" type="string"> <column name="ANSWER" length="50" not-null="true" /> </property> <property name="telephone" type="string"> <column name="TELEPHONE" length="50" /> </property> <property name="email" type="string"> <column name="EMAIL" length="50" /> </property> <property name="qq" type="string"> <column name="QQ" length="50" /> </property> <property name="create_time" type="timestamp"> <column name="CREATE_TIME" length="23" not-null="true" /> </property> <property name="status" type="integer"> <column name="STATUS" not-null="true" /> </property> <property name="role" type="integer"> <column name="ROLE" not-null="true" /> </property> <set name="TMessages" inverse="true"> <key> <column name="CREATE_USER_ID" length="50" not-null="true" /> </key> <one-to-many class="Message" /> </set> <set name="TComments" inverse="true"> <key> <column name="USER_ID" length="50" not-null="true" /> </key> <one-to-many class="Comment" /> </set> </class></hibernate-mapping>
    在hibernate-mapping标签(tag)之间, 含有一个class元素。所有的持久化实体类都需要一个这样的映射,来把类对象映射到SQL数据库里的表。id元素是标识符属性的声明,name=”id” 声明了Java属性的名字 - Hibernate会使用getId()和setId()来访问它。 column属性则告诉Hibernate, 我们使用market_1表的哪个字段作为主键。嵌套的generator元素指定了标识符生成策略,在这里我们指定uuid.hex。
    3.4.4 Hibernate Session工厂该类主要用于方便地提供Hibernate的初始化以及Hibernate的sessioon和事务的处理,HibernateSessionFactory类的结构如图3-7所示:

    在此简要介绍一下使用Hibernate进行数据库操作的过程,使用Hibernate进行持久化操作主要需要以下步骤:

    创建Configuration对象:进行配置文件的装载操作,读取所有的映射文件并进行解析
    创建 SessionFactory对象:通过创建好的Configuration对象可以创建一个SessionFactory对象的实例,它是产生Session对象的工厂,它在整个应用中是唯一的
    创建Session对象实例:Session对象类似于数据库的连接对象,可以理解为与数据库建立的一个连接,这个连接可以进行数据库的其它操作
    开始一个事务
    进行持久化操作:读取或保存java对象
    结束事务:在操作完成后要进行显示的结束事务的操作
    关闭Session:类似于释放数据库的连接

    3.4.5 定义和实现Hibernate DAO在完域模型的定义和配置工作后,要完成HibernateDAO的定义和实现。
    首先定义DAO接口,使用的接口的编程方法,可以在方法调用者和方法具体实现之间建立一个屏障,即它们不存在任何的关联,一边的修改不会影响另一边的正确运行。在本系统中,DAO接口(IBaseHibernateDAO)只有一个方法:返回Session对象。
    然后实现DAO接口,每个方法的实现,这里只介绍UserDAO、MessageDAO、CommentDAO这三个类的关系如图3-8所示:

    3.4.6 Hibernate Filter的实现在Web应用中,通过Filter来进行Hibernate事务管理并不仅仅出于处理方便,在本系统中,采用了面向对象的设计方法,每个Message对象都持有一个User对象的实例来表示这个二手信息的发布者,这与传统的结构化开发有很在区别。在结构化的开发方法中,Message对象中的属性应该是与信息存储表中的字段一一对应的,那么它就应该创建一个持有用户ID的属性来表示信息的的发布者。而在该系统中,我使用User类作为Message的属性。在面向对象的方法中,只需取得页面中需要显示的Message对象就可以了。
    通过上面获取对象的不同方法可以看出,采用面向对象的方法可以在很大程度上减少进行持久化操作所要进行的编码工作。而对于Message对象所持有的User对象则会由持久层(本系统用的是Hibernate)自动去完成相应的读取操作。
    在本系统中,通过Filter的机制,将一个用户请求中所做的所有持久化操作看成一个事务。当然,如果某个业务确实需要将这个请求分解成多个事务,那么也就可以在业务实现的方法中自选进行事务的提交可者回滚操作。也就是说,整个用户请求都是在一个Session中完成的,在响应用户请求之前会自动开始一个Session和事务。在处理完用户请求直到页面输出完毕后才提交当前的事务和关闭用户的Session。这样,就可以确保应用随时都可以通过Hibernate来获取相关对象的信息。
    另外在本系统的Filter中还进行了字符编码的控制,在每次用户请求中都将字符转化为GBK,以确保信息的正确保存。本系统用到的Filter关键代码如下:
    字符编码转化
    request.setCharacterEncoding("GBK");
    Hibernate事务处理
    session.beginTransaction();chain.doFilter(request, response);session.getTransaction().commit();
    完成Filter类后,要对该Filter进行配置和部署,Filter的配置和部署工作是在WEB-INF目录下的Web.xml中配置的,相关配置代码如下:
    <filter> <filter-name>hibernateFilter</filter-name> <filter-class>cn.lee.market.filter.HibernateFilter</filter-class></filter><filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
    4 系统功能模块的实现在本章内,将为大家详细说明系统功能模块的具体实现,系统主要使用了JSP、Javascript、Java、HTML以及DHTML语言等综合处理页面信息的显示和各个功能模块功能的设计,以及通过Hibernate对数据库的操作,完成了一个动态的校园二手交易平台。
    4.1 系统主页设计4.1.1 主页显示设计系统主页是面向平台的所有访问者,注册用户和非注册用户都可以进入到系统主页面,查看相关的二手信息及二手指南。主页面由平台Logo、登录框、搜索框和各种类型的最新二手信息列表组成。主页面效果如图4-1所示:

    4.1.2 主页后台设计系统主页面显示了最新各种类型的二手信息和二手信息top排行,这些都在进入主页前放入request,还有搜索条件中的分类下拉列表和交易地区下拉列表需要放入session中供以后使用。这些操作在IndexAction中实现,相关代码如下:
    查询各种类型的二手信息,放入request,供主页面显示:
    List typeList = tDao.findAllType();for(Type type:(List<Type>)typeList){ List<Message> typeMessage = (List<Message>)mDao.getTypeMessages(type.getId()); messageMap.put(type.getId(), typeMessage); typeMap.put(type.getId(), type.getType_desc());}request.setAttribute("messageMap", messageMap);
    查询所有分类,所有交易地区放入session,用于搜索框下拉列表及其它操作:
    request.getSession().setAttribute("typeMap", typeMap);List areaList = aDao.findAllArea();for(Area area:(List<Area>)areaList){ areaMap.put(area.getId(), area.getArea_desc());}request.getSession().setAttribute("areaMap", areaMap);
    按人气将信息排序后放入TopMessageList,供主页面显示:
    List<Message> TopMessageList = mDao.findByTop_value2();request.getSession().setAttribute("TopMessageList", TopMessageList);
    4.2 系统登录功能设计由于游客、普通用户、管理员限不同,系统实现登录功能,为普通用户、管理员的特殊操作提供接口。
    登录流程简单描述为输入->验证->返回主页。本系统为登录表单设计了ActionForm,在Action只须对接收到的ActionForm进行验证,验证其是否为用户、用户权限等,并根据不同验证结果进行相应操作。登录Struts配置如图4-2所示:

    登录成功后,普通用户、管理员都将在主页面显示用户的基本信息,并提供信息管进,发布信息,修改个人资料和用户注销的链接。登录成功效果图如图4-3所示:

    4.3 系统搜索功能设计系统搜索时也用ActionForm(searchConditionForm)接收搜索表单,在Action中用Dao对象操作ActionFromr返回搜索结果,搜索Struts配置如图4-4所示:

    Dao对searchConditionForm的操作代码如下:
    public List findBySearchCondition(SearchConditionForm searchConditionForm) { String keyword = searchConditionForm.getKeyword(); String typeid = searchConditionForm.getTypeid(); int flag = searchConditionForm.getFlag(); String areaid = searchConditionForm.getAreaid(); try { String queryString = "from Message where (message_title like '%" + keyword +"%'" +"or message_desc like '%" + keyword +"%')"; if(typeid!=null&&!"allType".equals(typeid)) queryString += " and MType = '"+ typeid +"'"; if(flag==1||flag==0) queryString += " and flag = "+ flag +""; if(areaid!=null&&!"allArea".endsWith(areaid)) queryString += " and MArea = '"+ areaid +"'"; queryString += " order by id desc"; System.out.println(queryString); Query queryObject = getSession().createQuery(queryString); return (List)queryObject.list(); } catch (RuntimeException re) { log.error("get failed", re); throw re; }}
    搜索结果的显示实现了分页显示功能,搜索效果如图4-5所示:

    在该系统中,页面中所有信息列表的显示均使用JSTL标签进行处理,这里仅对搜索结果显示的代码作一下分析,关键代码如下:
    <c:forEach items="${searchMessageList }" var="message" begin="${first }"end="${last }"><TR align=middle><TD> <c:if test="${message.flag == 0 }">[出售]</c:if> <c:if test="${message.flag == 1 }">[求购]</c:if></TD><TD style="WIDTH: 40%"><A href="${ctx}/message.do?messageid=${message.id }">${fn:substring(message.message_title,0,20) }${fn:length(message.message_title) le 20?"":"..."}</a></TD><TD>${message.MArea.area_desc} </TD> <TD><fmt:formatDate value="${message.create_time}" type="date" dateStyle="medium"/></TD> <TD> ${message.old_value }成新</TD><TD>${message.price }RMB</TD><TD>${message.top_value }</TD></TR></c:forEach>
    说明:searchMessageList是从Action中返回的信息列表,在此用C标签进行循环打印,字段值的输出使用EL表达式,使页面代码简洁,容易理解,修改[4]。
    4.4 用户注册功能设计本系统用户注册实现了学生实名制,注册前要先同意平台协议,然后在注册输入界面输入相关信息,系统收集到用户注册人信息,验证通过后注册成功,进入注册成功页面。
    4.4.1 用户注册页面设计注册页面包括表单和表单验证。注册页面所涉及的表单元素如表4-1所示:



    名称
    元素类型
    重要属性
    含义




    Username
    Text
    maxLength=16 onblur=”checkUsernameFormat(this)”
    平台帐号


    stu_id
    Text
    maxLength=12
    学号


    Birthday
    Text
    onclick=”GetCalendar(this,’birthday’);” src=”../images/calendar/calendar.gif”
    生日


    email
    Text
    前台验证: isEmail(this)
    E-mail


    password
    password
    maxLength=20
    密码


    repassword
    password
    maxLength=20
    确认密码


    question
    Text
    id=txtTipQuestion
    密码问题


    answer
    Text
    id=txtTipAnswer
    密码答案



    注册表单提交前使用javascript脚本进行验证,核心代码如下:
    if(!checkUsernameFormat(f.username)) return false; if(!isNumeric(f.stu_id,'学号格式不正确!')) return false; if(!isEmail(f.email)) return false; if(f.repassword.value != f.password.value){ alert('两次输入的密码不相同!'); f.repassword.value=""; f.password.value=""; f.password.focus(); return false; } if(!isNotEmpty(f.question, '密码查询问题不能为空!')) return false; if(!isNotEmpty(f.answer, '密码查询答案不能为空!')) return false; return true;
    注册验证效果如图4-6所示:

    4.4.2 用户注册后台设计用户注册后台操作在Action中进行,后台实现了将用户信息插入数据库并将新注册用户以及用户权限放入session。用户注册Struts配置如图4-7所示:

    4.5 发布、修改信息设计信息的发布和修改是该系统的最主要功能,只有注册用户或管理员才有权限进行信息发布,普通用户只能修改自己发布的信息,管理员可以修改所有信息。
    信息的发布和修改共用了同一个页面,页面中包含表单和表单验证。表单通过ActionForm接收,在Action中对表单的操作根据信息编号参数值判断执行发布或修改。
    信息发布页面效果如图4-8:

    信息表单元素如表4-2所示:



    名称
    元素类型
    重要属性
    含义




    postForm
    from
    action=”post.do” method=”post” onsubmit=”return(post_check(this))”
    表单


    messageid
    hidden
    —-
    信息编号


    message_title
    Text
    maxLength=30
    信息标题


    old_value
    DropDown
    onclick=”GetCalendar(this,’birthday’);” src=”../images/calendar/calendar.gif”
    新旧程度


    flag
    DropDown
    —-
    交易类型


    typeid
    DropDown
    遍历${typeMap } value=”${type.key }”
    所属类别


    areaid
    DropDown
    遍历${areaMap } value=” ${area.key }”
    交易地区


    price
    Text
    maxLength=10
    物品价格


    r_user
    Text
    maxLength=10
    联系人


    r_email
    Text
    maxLength=20
    E-mail


    r_phone
    TEXTAREA
    —-
    联系方式


    message_desc
    TEXTAREA
    —-
    物品简介


    submit
    submit
    value=”提交”
    提交按钮


    reset
    reset
    value=”重置”
    重置按钮



    信息发布、修改的具体操作在Action中进行,Action中首先验证是否为用户,非用户则弹出消息返回主页,反之执行相应操作。信息发布、修改Struts配置如图4-9所示:

    4.6 信息管理设计信息管理分为普通用户个人信息管理和管理员会员信息管理。管理页面显示了要管理信息的重要信息,并提供链接可进入详细信息页面。每个信息都有修改、删除按钮。这里只介绍个人信息管理页面,页面效果如图4-10所示:

    4.7 信息留言设计登录用户可以对信息进行留言,留言会立刻显示在信息详细下面。留言输入界面显示有登录用户的相关信息(用户名和邮箱),这些信息会连同留言表单内容传入Action中进行插入操作。留言界面效果如图4-11所示:

    留言成功后返回到信息详细页,信息最后显示该信息的所有留言,效果如图4-12所示:

    4.8 二手指南设计二手指南是平台为用户提供的二手帮助指南,游客和普通用户都只能对其进行浏览操作。二手指南的增加,修改,删除都是管理员来操作。在该模块,因为二手指南只有标题和内容两个字段,所有没有必要用ActionForm来接收表单,操作仍然写在Action中。
    5 总结本次毕业设计工作在最初选题过后,我选择了JSP,它是真正的跨平台,实现动态功能的一种技术。JSP+Servlet+JavaBeans/EJB,能够让人非常简单方便地构建安全高速的WEB应用。同时可以通过JDBC(Java DataBase Comnectivity)接口,访问几乎所有数据库,并且可以使用数据库连接池技术,有效控制连接数,确保系统的正常运转。从发展的眼光来看,JSP的前途一片光明。在数据库的选择上,我也使用近些年发展很好的MySQL,充分实现系统的跨平台性。
    在这个系统开发过程中,我对Hibernate的学习从零开始,作过许多小测试。每次的新发现我都运用到这个系统中,在运用中,对它的掌握也更加熟练。还是系统运用Struts框架,在该系统的开发过程中,参阅了很多相关的书籍,特别的Apache官方网站的帮助文档,不仅解决了很多问题,也提高了自己的英文水平。系统中所有的页面,我都争取只写显示代码,用到了JSTL标签和EL表达式,使页面上代码简捷,易懂,易改。
    7 评论 115 下载 2020-07-31 16:55:17 下载需要12点积分
  • 基于C语言的AES加密系统

    一、课程设计功能简介题目
    对称算法AES的实现,在深入理解AES加密/解密算法理论的基础上,设计一个AES加密/解密软件系统。
    功能要求

    编程实现算法的加密过程、解密过程和密钥生成过程
    完成一个明文分组的加密、解密,明文和密钥是ASCII码。进行加密后,能够进行正确的解密
    提供良好的用户界面,界面有有加密/解密选择、输入明文/密文栏、密钥栏、和加/解密结果显示栏

    二、技术要求运用所掌握的数据结构、以及编程语言对各种密码学算法进行分析和设计,加深学生对密码算法的理解,提高学生算法设计与分析的能力。提高学生在应用C语言、数据结构编写大型算法的能力。
    三、软件模块设计流程
    AES加密函数中,首先进行密钥扩展,然后把128位长度的字符串读进一个4*4的整数数组中,这个数组就是状态矩阵。例如,pArray[0][0] = S0,pArray[1][0] = S1, pArray[0][1] = S4。这个读取过程是通过 convertToIntArray()函数来实现的。每个轮操作的函数都对pArray进行修改,也就是对状态矩阵进行混淆。在执行完10轮加密后,会把pArray转换回字符串,再存入明文p的字符数组中,所以,在加密完后,明文p的字符串中的字符就是加密后的字符了。这个转换过程是通过convertArrayToStr()函数来实现的。

    3.1 密钥扩展的实现在开始加密前,必须先获得第一轮加密用到的密钥,故先实现密钥扩展。
    下面是密钥扩展函数的实现,这个函数传入密钥key的字符串表示,然后从字符串中读取W[0]到W[3],函数getWordFromStr()用于实现此功能。读取后,就开始扩展密钥,当i是4的倍数的时候,就会调用T()函数来进行扩展,因为T函数的行为与加密的轮数有关,故要把加密的轮数 j 作为参数传进去。
    3.2 字节代换的实现字节代换的代码很简单,就是把状态矩阵中的每个元素传进getNumFromSBox()函数中,然后取得前面8位中的高4位作为行值,低4位作为列值,然后返回S[row][col],这里的S是储存S盒的数组。
    3.3 行移位的实现行移位的时候,首先把状态矩阵中第2,3,4行复制出来,然后对它们行进左移相应的位数,然后再复制回去状态矩阵array中。
    3.4 列混合的实现列混合函数中,先把状态矩阵初始状态复制一份到tempArray中,然后把tempArray与colM矩阵相乘,colM为存放要乘的常数矩阵的数组。其中的GFMul()函数定义了矩阵相乘时的乘法,加法则直接通过异或来实现。GFMul()通过调用乘以各个数对应的函数来实现乘法。例如,S1 2 刚通过调用GFMul2(S1)来实现。S1 3 刚通过GFMul3(S1)来实现。在这里,主要实现GFMul2()函数就行了,其它的都可以通过GFMul2()的组合来实现。举个例子吧,为计算下面这条等式,需要像下面这样调用函数:
    s = GFMul3(0xC9) ^ 0x7A ^ 0x63 ^ GFMul2(0xB0)3.5 轮密钥加的实现轮密钥加的实现很简单,就是根据传入的轮数来把状态矩阵与相应的W[i]异或运算。

    AES解密过程,解密过程仍为10轮,每一轮的操作是加密操作的逆操作。由于AES的4个轮操作都是可逆的,因此,解密操作的一轮就是顺序执行逆行移位、逆字节代换、轮密钥加和逆列混合。同加密操作类似,最后一轮不执行逆列混合,在第1轮解密之前,要执行1次密钥加操作。
    四、测试结果


    五、总结本次课程设计,让我获益匪浅,不仅更深入的了解密码学这门学科,整个设计过程是不断学习,不断发现问题、分析问题、解决问题的过程使我受益良多。设计期间有很多感触、想法,使自己有了继续探索的兴趣,对以后的学习、工作有很大的益处。
    于个人而言,在程序设计的过程中,我深感“认真严谨”这个词的重要性,一点点小的马虎,便会导致整个程序不能正常运行。在今后的学习中,我定将“认真严谨”对待。总之,此次课程设计在我今后的学习生涯中起到了至关重要的作用。
    6 评论 118 下载 2019-06-04 09:58:07 下载需要10点积分
显示 45 到 60 ,共 15 条
eject