分类

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

资源列表

  • 基于Android系统手机通讯录管理软件的设计与开发

    摘要谷歌在安卓领域投入了大量精力来开发,使得安卓技术得以广泛推广,现安卓移动平台设备在市场上已经得到大量推广及普及。在Android移动终端操作系统的快速发展,Android的各种手机软件也大量增长。当然,在手机终端中,手机通讯录是手机终端必不可少的基础功能,其质量直接影响着用户对手机使用的体验与感觉。手机通讯管理软件不仅仅只是能够简单添加联系人以及联系方式的功能,而今已发展成为多种形式,丰富了联系人的信息,存储了更多的内容。此课程设计研究的这个项目,主要实现添加联系人的多种联系方式的功能。
    本软件采用Android Studio+Android SDK集成环境,应用程序编程语言采用Java高级语言开发。通过对通讯录中的联系人的管理,来方便用户通讯更加便捷,联系人的数据保存更加安全。在对Android手机通讯管理软件进行详细的系统设计时,对功能进行详细的划分并对其功能做了详细的介绍,列出了一些主要功能流程图。
    关键词:通讯录 Android 数据库 SQLite
    第一章 绪论1.1 项目研究背景经过多年的发展,移动终端不再仅是通讯网络的终端,还将成为互联网的终端。因此,移动终端的应用软件和需要的服务将会有很大的发展空间。
    Android是一套真正意义上的开放性移动设备综合平台,它包括操作系统、中间件和一些关键的平台应用。Android最大特点在于它是一个开放的体系架构,具有非常好的开发和调试环境,而且还支持各种可扩展的用户体验,Android里面具有非常丰富的图形系统,对多媒体的支持功能和非常强大的浏览器。
    Android平台的开放性等特点既能促进技术的创新,又有助于降低开发成本,还可以使运营商能非常方便地制定特色化的产品。
    1.2 项目研究的目的及意义随着4G网络的使用,移动终端不再仅是通讯网络的终端,还将成为互联网的终端。在Google和Android手机联盟的共同推动下,Android在众多手机操作系统中脱颖而出,受到广大消费者的欢迎。
    手机通讯录作为手机的基本功能之一,每天我们都在频繁地使用着。根据手机功能使用调查显示,有9成以上的消费者使用手机通讯录功能。随着手机通讯录功能的不断加强与完善,手机通讯录对于人们的意义,已不仅仅像记事簿一样显示通讯地址,而是向着个性化、人性化的方向发展。通讯录从无到有,大大丰富了内容,同时结构也发生了革命性变化,而且随着手机的发展,相信更优秀的通讯录会越来越受到社会各层人士的喜爱。
    1.3 系统主要实现内容通过对Android技术的相关研究,了解Android源码实现原理以及过程,从而设计出一款能够使用的手机通讯录。
    这款手机通讯录实现的相关内容如下:

    简洁、实用的操作界面
    联系人的增删改查
    分类的增删改查
    呼叫联系人
    登录、注册、修改密码
    群组的增删改查
    导入导出联系人
    支持模糊查询手机通讯录

    第二章 系统分析2.1 系统可行性分析2.1.1 技术可行性Java 应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java 应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译一次,就可以在各种系统中运行。
    本软件用的是Java开发语言,在Android Studio集成开发环境下,调试容易。当前的计算机硬件配置或则现有安卓手机的硬件配置也完全能满足开发的需求,因此技术上是绝独可行的。
    2.1.2 经济可行性开发该系统所需的相关资料可以通过已存在的相关系统进行调查采集,所需的软件系统、硬件平台等都易于获得,且不需要Android平台机器,用模拟器即可实现开发研究,开发成本低,容易实现,从经济角度来看,该系统可行。
    2.1.3 操作可行性不管是安卓平台的手机,还是计算机,其成本的下降,导致计算机,安卓手机购买成本的降低.这套系统是利用自己的计算机,且使用安卓模拟器,使开发出来的系统有友好的用户界面、操作简单,因此在操作上是可行的。
    2.2 Android通讯录的使用意义该系统针对的主要用户是Android手机用户。Android手机通信管理系统包括以下主要内容:联系人增删改查、呼叫联系人、分类增删改查、多条件搜索、导入导出联系人、修改密码等功能。要设计一个良好的手机通讯录,就必须首先明确该应用环境对系统的要求。
    第三章 系统概要设计3.1 系统总体设计Android手机通讯管理软件主要功能模块包括:联系人增删改查、呼叫联系人、分类增删改查、多条件搜索、导入导出联系人、修改密码等。

    3.2 处理流程设计3.2.1 业务流程图用户首次进入手机通讯管理软件后,会进入用户注册界面,当用户注册成功之后,输入密码即可看到联系人列表界面。联系人列表界面右下方显示增加联系人按钮。上方可以进行联系人的多条件搜索。同时长按某个联系人可实现编辑删除功能。当然点击联系人也可以看到详细信息。界面中显示我的群组列表,打开之后即可进行群组的增删改查功能。点击菜单键,显示通讯录的导入导出功能以及修改密码功能。
    3.2.2 数据增加流程图添加联系人时,数据由用户输入,点击确定按钮,判断数据是否合法(及用户名是否为空),合法则插入到数据库;不合法,提示错误信息,让用户重新输入。流程如图所示:

    3.2.3 数据修改流程图编辑联系人时,点击编辑联系人菜单,输入修改后的数据,点击确定按钮,判断数据是否合法,合法,则更新数据库;不合法,则返回错误信息。 流程如图所示:

    3.2.4 数据删除流程当用户选定一个联系人时,单击删除联系人菜单,提示用户是否删除,点击确定按钮,则从数据库中删除此条记录。数据删除流程如图所示:

    3.3 数据库设计3.3.1 SQLite数据库简介SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低。
    本系统采用的是Android系统自带的SQLite轻型数据库数据库。因此占用资源非常小。
    3.3.3 数据库表结构首先创建数据库,在数据库中创建表用来存储联系人数据,其中包括联系人姓名、手机号、群组ID、地址等联系方式。创建群组表用来保存ID和群组名称等信息。两个表联合配合。表结构如图所示:

    第四章 系统详细设计4.1 联系人浏览模块进入手机通讯管理软件后,看到的第一个界面是联系人列表界面。该列表是由ListView控件生成的,打开数据库(如果数据库不存在则创建数据库,并创建数据表),查找数据库中所有的联系人,并把联系人姓名和移动电话号码以及职位这填充到ListView的adapter中。每一行显示一个联系人的姓名和手机号码,联系人的显示的顺序是根据插入数据库的顺序显示的。点击某个联系人会进入查看联系人界面,可以查看联系人的详细信息,对联系人进行编辑、删除、拨打电话、导入导出通讯录等。

    点击[菜单]按钮时,就会显示主菜单项,其中包括:修改密码、导出数据、导入数据。
    点击添加按钮,会进入添加联系人界面,可以输入联系人相关信息,完成联系人添加功能。点击上方搜索栏目,会进入联系人查找界面,可以进行联系人查找,搜索想要找的联系人。
    点击菜单按钮,打开修改密码、导出通讯录、导出通讯录等功能。

    长按列表的某一行时,会弹出长按菜单,其中包括:拨号、编辑联系人、删除联系人。点击查看联系人菜单会进入查看联系人界面。点击编辑联系人菜单会进入编辑联系人编辑界面。点击删除联系人时,会弹出对话框,询问是否删除联系人,点击确定,则从数据库中删除该联系人。

    4.2 查看联系人模块在联系人浏览界面点击某个联系人,则会跳转到该界面。该界面使用TextView把从数据库中调出的联系人的详细信息显示出来,这里面包括联系人姓名、手机号、地址等详细信息。

    4.3 编辑联系人模块编辑联系人界面使用EditView控件显示并修改联系人的详细信息。联系人的所有信息,处于可编辑状态,手机号和座机号的EditView设定为只能输入数字。修改完信息后点击确定按钮,触发确定按钮点击监听事件,从而对数据库中该联系人的信息进行更新, 然后自动返回联系人浏览界面。点击取消按钮会返回联系人浏览界面。

    4.4 查找联系人模块这里采用的查找方法是SQL模糊查询,可以只输入联系人姓名中的一部分,即可查找到所有包含该部分的联系人,并在ListView中显示出来所有的联系人的姓名和手机号码。可实现查找职位、手机号码、名字等信息。

    4.5 修改密码点击菜单,可以查看该软件的修改密码、导入导出等情况。并可实现全部功能。

    4.6 分类管理点击我的群组界面,可以查看群组并且显示群组。在里面可以对群组进行增删改查操作。
    4 评论 65 下载 2019-01-30 17:26:14 下载需要12点积分
  • JAVA实现的基于内容的图像检索系统设计与实现

    1 图像检索系统工作流程基于内容的图像检索技术是对输入的图像进行分析并分类统一建模,提取其颜色、形状、纹理、轮廓和空间位置等特征,建立特征索引, 存储于特征数据库中。检索时,用户提交查询的源图像,通过用户接口设置查询条件,可以采用一种或几种的特征组合来表示,然后在图像数据库中提取出查询到的所需关联图像,按照相似度从大到小的顺序,反馈给用户。用户可根据自己的满意程度,选择是否修改查询条件,继续查询,以达到满意的查询结果。
    2 图像检索系统框架基于内容的图像检索系统框架如图1所示。系统的核心是图像特征数据库。图像特征既可以从图像本身提取得到, 又可以通过用户交互获得, 并用于计算图像之间的相似度计算。系统框架应主要包含以下几个基本功能模块:检索方法设置、检索结果浏览、数据库管理维护等。其逻辑结构如图2所示。


    3 数据库构建与实现图像数据库包括两个部分:图像库和特征库。图像库是图像的集合,存储数字化的图像信息,具体在系统实现中,可以存放图像的路径和文件名称来表示;特征库存储图像中提取出的特征表达的相关信息,并为提取出的各个特征简历索引,且和图像间存在一一对应的关系。
    3.1 图像数据库图像是图像元灰度值的纪录, 以行列数据矩阵表示, 一般信息量比较大。直接读取图像的信息存入数据库中, 不但增加了数据库的容量, 而且增加了计算机的负担。若直接根据图像的路径名称建立图像地址库, 可有效提高计算机的计算效率。当需要提取图像时, 再根据图像的地址, 对图像进行检索, 平时, 只需对图像的基本信息进行管理。数据库的基本功能包括: 增加删除图像、图像统计、图像的显示等。cusers12801desktopstarfish.txt示例如图3所示。

    3.2 图像索引库的建立与实现3.2.1 数据组织说明由于图库中有大量的图像,每一张图像中有许多像素点,每个像素点又有许多特征值,如果都将其放入内存中,是不可能实现的。因此本实训项目将提取出的特征值存放到txt文件中,每打开应用系统,就可以直接从外存中读取文件,构建图像特征索引库。分别实现图像颜色、纹理和特征值的提取及txt文件的生成,生成结果文件分别如图4 所示。此步骤需要用户先完成图像特征提取后,再来构建图像特征索引库。


    cusers12801desktopstarfish.txt主要存的是图库中每张图像的路径,匹配时程序可以根据这个路径找到图库中图像所在的路径
    RGBHcusers12801desktopstarfish.txt保存的是直方图相交法的特征值
    CMcusers12801desktopstarfish.txt保存的是HSV中心距法的特征值
    EDcusers12801desktopstarfish.txt保存的是欧式距法的特征值
    BHcusers12801desktopstarfish.txt保存的是巴氏系数法的特征值


    3.2.2 图像特征数据库设计说明分别以颜色、纹理、形状特征为例,说明创建各特征表时的工作过程。
    以颜色特征为例,说明创建该表时需要包括的字段如下(实际处理过程中,用户选择的特征描述方法不同,所得到的颜色特征值的数量也不同,由用户酌情处理):



    字段名称
    字段描述
    字段类型
    备注




    ID
    数据库中的编号
    int
    Primary Key


    Name
    图像名称
    string
    NOT NULL


    Color
    颜色特征值
    float
    NOT NULL


    Path
    储存图像的位置
    string
    NOT NULL



    以纹理特征为例,说明创建该表时需要包括的字段如下(实际处理过程中,用户选择的特征描述方法不同,所得到的纹理特征值的数量也不同,由用户酌情处理。



    字段名称
    字段描述
    字段类型
    备注




    ID
    数据库中的编号
    int
    Primary Key


    Name
    图像名称
    string
    NOT NULL


    shape0
    形状特征值
    float
    NOT NULL


    shape1
    形状特征值
    float
    NOT NULL


    shape2
    形状特征值
    float
    NOT NULL


    shape3
    形状特征值
    float
    NOT NULL


    shape4
    形状特征值
    float
    NOT NULL


    shape5
    形状特征值
    float
    NOT NULL


    shape6
    形状特征值
    float
    NOT NULL


    shape7
    形状特征值
    float
    NOT NULL


    Path
    储存图像的位置
    string
    NOT NULL



    4 图像特征的提取与表达图像特征的提取与表达是基于内容的图像检索技术的基础。广义而言,图像的特征包括基于文本的特征(关键字、注释等)和视觉特征( 如色彩、纹理、形状、对象表面等) 两类。视觉特征又分为通用的视觉特征和领域相关的视觉特征。前者描述所有图像共有的特征,与图像的具体类型或内容无关,主要包括色彩、纹理和形状,后者建立在对所描述图像内容的某些先验知识(或假设)基础上,与具体的应用紧密有关。
    4.1 图像预处理主要的参考步骤如下:

    统一图像大小,使得每一幅待检索图像大小一致
    图像降噪,避免图像噪声带来的影响。可使用数字图像处理课程中所学各种方法,如高斯模板、中值滤波等来实现
    图像增强,主要用来增强对比度等。可使用数字图像处理课程中所学各种方法,如直方图均衡化等方法实现

    但是本次实验的图片是专用的图库,因此不需要进行预处理。
    4.2 图像颜色特征颜色特征是在图像检索中应用最为广泛的视觉特征,主要原因在于颜色往往和图像中所包含的物体或场景十分相关。此外, 颜色特征对图像本身的尺寸、方向、视角的依赖性较小, 从而具有较高的检索性。利用颜色特征进行检索的方法主要基于直方图,如:直方图相交法,比例直方图法,距离法,参考颜色表法和聚类算法,累计直方图法,此外,还有HSI中心矩法。
    5 图像特征匹配在基于内容的图像检索中,两幅图像是否相似是指图像的特征向量是否相似。常用的图像相似性测度通常采用几何模型,将图像特征看作是向量空间中的点,通过计算两个点之间的接近程度来衡量图像特征之间的相似度。基于内容的图像检索算法主要有最邻近查询算法和区间查询算法,它们都依赖于距离函数或者相似性度量。
    算法步骤

    按照前文方法,计算出待检索图像的特征
    利用距离度量函数计算待检索图像特征和图像特征库间的距离
    对计算出的距离值按照相似性大小进行高低排序
    对检索出的结果图像进行输出显示

    6 所采用算法思想6.1 直方图的相交法算法步骤

    图像灰度化Gray=R[i]/R+G[i]/G+B[i]/B
    两图像之间的匹配值P(Q, D)可借助直方图相交来实现



    将特征值存放在图像特征数据库中
    6.2 欧氏距离(EuclideanDistance)算法步骤

    图像灰度化Gray=R[i]/R+G[i]/G+B[i]/B
    两图像之间的匹配值P(Q, D)可借助直方图相交来实现



    将特征值存放在图像特征数据库中
    6.3 巴氏系数法算法步骤

    图像灰度化Gray=R[i]/R+G[i]/G+B[i]/B
    其中P, P’分别代表源与候选的图像直方图数据,对每个相同i的数据点乘积开平方以后相加,得出的结果即为图像相似度值(巴氏系数因子值),范围为0到1之间



    将特征值存放在图像特征数据库中
    6.4 中心矩法算法步骤

    图像灰度化Gray=0.30*R+0.59*G+0.11*B
    将图像从RGB颜色空间转至HSI颜色空间
    以HSI空间的Hue分量为例,如果记Hue(pi)为图像P的第i个像素的Hue值,则其前三阶中心矩分别为:



    度量函数


    将特征值存放在图像特征数据库中
    7 详细实现过程主窗口的设计实现代码如下(MainFrame.java),该文件是程序刚运行时加载的窗口。

    图像存储窗口的设计实现如下(IDBMDialog.java),该文件主要实现了用户将指定的文件夹存入数据库中。

    图片特征值存储数据库窗口的实现如下(ICDBMDialog.java),该文件主要实现了待检所图片与数据库中图片基于颜色特征的处理及匹配数据的存储。

    人脸识别的窗口设计如下(LBPDialog.java)。

    帮助窗口设计如下(HelpDialog.java),该文件是程序的说明书。

    Centralmoment.java实现了中心矩法,HistogramRetrieval.java实现了相交法、欧氏距离法和巴氏系数法,interface_main.java是主函数所在的类,MysqlConnect.java实现了java与mysql的连接,MapSort.java和Math.java是图像处理算法中的工具类。线程保证了图片加载与用户操作能同时进行,因为遇到图片很多的时候加载时间较长,这是应仍能允许用户进行其他操作。XLabel.java实现了JLabel类,使得图片能按照自定义的方式显示。
    8 实验结果分析传统的直方图相交法运行效果图

    直方图相交欧式距离法运行效果图

    巴氏系数法运行效果图

    中心矩法运行效果图

    人脸识别运行效果图

    人脸识别的方法:使用haartraining.exe来训练分类器,获取XML文件,从而获得人脸的数据信息,根据该信息就可以识别人脸。
    在本次实训程序中,颜色特征的匹配都能成功运行,形状特征的方法由于计算方法未得到优化,导致数据存储过程中出现数据库中全是0值的情况,因此未能成功展示,纹理特征由于时间关系未能实现。
    9 实训总结和心得通过本次实训,我了解到了CBIR以及实现了其中的一小部分典型功能。基于内容的图像检索系统(Content Based Image Retrieval, 以下简称CBIR),是计算机视觉领域中关注大规模数字图像内容检索的研究分支。是指直接采用图像内容进行图像信息查询的检索,即在图像数据库中检索与用户所提交样本图像在内容上一致或相似的图像集合的过程,通过对图像底层特征的比较来实现检索。主要研究技术包括特征抽取、相似度量、图像匹配、用户反馈。基于色彩特征的检索方法是CBIR的主要方法之一,它所抽取的特征向量是颜色直方图,虽然能够较好地反映图像中各种颜色的频率分布,而且对图像中对象的旋转以及观察位置的变化不敏感,但无法保留各像素。这项技术是为了解决报刊等媒体集团大量图片检索的难题而衍生出来的。
    本次实训目的是完成CBIR的一些典型功能,具体包括:

    实现基于颜色信息的图像检索,可通过颜色直方图、颜色矩、颜色一致性矢量等方法来实现实现基于纹理特征的图像检索,可从四个方面进行:统计法、结构法、模型法、频谱法实现基于形状特征的图像检索,可分别从图像的边缘信息和区域信息来实现实现基于综合信息的图像检索
    在了解完实训要求以及项目要求之后,结合java中的awt框架技术,jdbc链接数据库以及图像处理算法最后终于完成了一些最基本的功能,还抽出了部分时间尝试着完成了一个最简单的人脸识别功能(利用opencv识别技术)。在本次实训中既让我复习了之前学习的java程序设计和数字图像处理等课程,也开阔了我的视野,学习了一些基于内容的图像检索的相关技术,当然了由于自身能力有限,本次实验得以成功完成离不开指导书以及网上的资源。总之本次实训十分有意义,让我受益颇多。
    10 参考文献[1] 翟瑞芳、彭辉、周雄辉、高俊祥.CBIR实训指导书[M/CD]. 武汉:2017
    2 评论 88 下载 2018-11-04 22:53:22 下载需要7点积分
  • 基于QT和UDP Socket实现的即时通信软件

    摘 要随着计算机应用技术的快速发展和日益普及,网络也遍及到我们生活的每个角落,为我们的学习和工作带来极大的方便。现很多人都使用网络通讯软件来进行聊天、交流,这种软件极大地缩短了人与人之间的沟通距离,使人们能够随时随地的进行交流。因此,一个即时通讯软件的设计是有必要的。
    而本设计是基于Qt的开发平台上开发的一款即时通讯软件,通过网络编程SOCKET函数以实现同局域网内的文字传输。
    关键词:通讯软件;网络编程;文字传输
    第一章 设计内容设计一个类似QQ的聊天软件,实现在同一局域网内不同用户之间的即时通信,程序具体功能有:

    sqlite3数据库插入用户表
    登录界面:数据库验证登录
    用户主界面:数据库匹配用户好友列表
    聊天界面:在同一局域网内采用UDP的方式实现即时通信
    聊天记录以文件“.txt”的形式保存

    第二章 总体设计2.1 模块化设计为实现系统功能,本程序主要分为四个模块。他们分别是:登录界面、用户主界面、好友列表界面、聊天界面。这四个模块是通过主函数实例化一个不显示的空用户主界面,在用户主界面的构造函数里还会实例化一个登录界面,当登录界面用户登录成功后,用户主界面转为显示状态并更新登录的用户信息(显示登录账号,更新用户好友列表),双击对应好友就可弹出聊天窗口,实现即时聊天。
    主函数(main)
    // 实例化用户主界面MainWindowmainwin
    登录界面类(logonscreen)
    // 构造函数LogonScreen(QWidget *parent = 0); // 创建数据库连接createConnection(); // 创建用户表,添加可登陆用户createTable();// 查询用户表,显示所有用户selectTable(); // 验证登录信息verify(const Qstring, const QString); // 登录按键的槽on_pushButton_login_clicked(); // 退出按键的槽on_pushButton_close_clicked(); // 自定义用户登录信号,向用户主界面传输当前登录账号值user_signal(QString value);
    用户主界面类(mainwindow)
    // 构造函数MainWindow(QWidget *parent = 0);// 创建数据库连接createConnection();// 匹配用户好友,更新好友列表matchUserFriend(); // 注销按钮的槽,返回登录界面on_pushButton_quit_clicked();// 获取用户登录信号响应的槽getUserValue(QString value); // 鼠标移动事件,单击移动界面mouseMoveEvent(QMouseEvent *event);
    好友列表界面类(userwidget)
    // 原构造函数userwidget(QWidget *parent = 0);// 构造函数的重载userwidget(int receive_port,QString send_ip ,int send_port,QString send_account,QWidget *parent = 0); // 鼠标双击事件mouseDoubleClickEvent(QMouseEvent *event);
    聊天界面类(chatwindow)
    // 原构造函数ChatWindow(QWidget *parent = 0); // 构造函数的重载ChatWindow(int receive_port,QString send_ip,int send_port,QString send_account,QWidget *parent = 0);// 键盘按下事件(ctrl+Enter)keyPressEvent(QKeyEvent *event); // 键盘释放事件keyReleaseEvent(QKeyEvent *event); // udp数据报接收processPendingDatagram(); // 发送按钮的槽,发送udp数据报on_pushButton_send_clicked(); // 关闭按钮的槽,关闭窗口on_pushButton_close_clicked(); // 聊天记录按钮的槽,显示隐藏的界面on_pushButton_chatdata_toggled(bool checked);
    2.2 程序运行示意图
    第三章 详细设计3.1 登录界面设计3.1.1 登录界面UI设计
    3.1.2 登录界面类设计在登录界面类的构造函数里,会做连接sqlite3数据库,创建用户表和查询用户表并显示查询结果于调试窗口的操作。当用户在登录界面输入账号时,就会触发QT的自动补全功能(QCompleter),补全内容为在查询用户表时记录的用户账号(QStringList),方便用户输入体验。当用户输入密码时,lineEdit_password里的值会以密码的形式显示(setEchoMdoe)。用户键入完成,点击登录按钮,调试窗口显示键入内容,并调用verify(account, password)函数,把键入的账号密码作为数据库查询的where条件。如果查询结果存在,则发送accept()信号允许登录,并且还会发送一个自定义的emit user_signal(account)信号给用户主界面,传入当前登录账号值,作为主界面更新该用户好友列表的判断依据;否则,弹出一个dialog提示账号或密码错误。
    3.2 用户主界面设计3.2.1 用户主界面UI设计
    3.2.2 用户主界面类设计当实例化用户主界面时,主界面是不会show() 出来的,用户主界面类构造函数首先会实例化一个登录界面类的指针对象。然后,关联(connect)这个对象的自定义信号user_signal(account),使用户主界面收到这个信号时,能转到槽getUsrValue(QString),获取信号传进来的当前登录账号值。接着,显示登录界面,等待用户在登录界面的操作。最后,用户主界面会等待登录界面的用户登录成功后的Accepted信号,如果收到Accepted信号,主界面show() 出来,并且调用matchUserFriend()函数,匹配当前登录账号的好友列表。
    更新好友列表的功能实现是通过在用户主界面的toolBox部件的page_friend里添加一个垂直布局(QBoxLayout),然后在matchUserFriend()函数里查询数据库里的用户表,查到一个好友则在垂直布局里实例化一个QT设计师类userwidget的指针对象。
    3.3 好友列表界面设计3.3.1 好友列表UI界面
    3.3.2 好友列表类设计这个类是在用户主界面matchUserFriend()函数里实例化使用的,结果是会在用户主界面的toolBox部件里的好友列表显示出来。因为要实现鼠标双击这个类(好友)就会弹出和这个好友的聊天窗口。所以这时候就需要考虑这个聊天窗口的接收UDP数据报的绑定端口和发送UDP数据报的目标IP、目标端口。为要解决这个问题,我这个类使用了构造函数的重载,在实例化该类的过程中同时传入接收端口、发送目标IP、发送目标端口和发送目标的名字。
    好友列表类重载的构造函数主要做记录传入接收端口、发送目标IP、发送目标端口和发送目标的账号,并根据传进来的发送目标的账号从QT资源文件里查找对应的头像、昵称和签名。最后在鼠标双击事件里再用同样的方法把这些值传进聊天窗口界面。
    3.4 聊天界面设计3.4.1 聊天界面UI设计
    3.4.2 聊天界面类设计聊天界面类重载的构造函数,首先记录从好友列表类传进来的接收端口、发送目标IP、发送目标端口和发送目标的账号。然后隐藏聊天记录的textEdit部件,调整窗口的大小。最后绑定接收UDP数据包的端口和IP,关联QudpSocket::readyRead信号,当收到UDP数据报时,触发槽processPendingDatagram(),使收到的数据显示在listWidget上,并写入名为发送对象的txt文件里作为聊天记录保存起来。
    发送按钮的槽函数,把当前时间(QDateTime::currentDateTime())和发送内容里(textEdit里面的数据)一起以UDP数据报发送出去,同时也写入到对应txt文件里面。
    聊天记录按钮的槽函数,点击聊天记录按钮,检查按钮当前状态,如果按钮checked值为true,则显示隐藏的textEdit,并重新调整聊天界面大小,textEdit里面的值为从对应txt文件里读取的全部内容。
    第四章 调试与测试4.1 调试过程中的主要问题
    用户登录成功后,登录界面类的当前登录值怎么传进用户主界面?
    最后的解决方法是在用户主界面实例化登录界面指针对象,然后使用信号和槽传输登录账号值。
    用户主界面收到登录界面发来的信号后,已经知道当前登录账号了,怎么在该用户好友列表显示出来?
    最后的解决办法是新建QT设计师类(好友列表类),查询数据库,查到一个实例化一个好友列表类指针对象到toolBox部件里的垂直布局里。
    鼠标双击好友列表里的一个好友,弹出聊天窗口,聊天窗口的UDP数据报的接收端口和发送IP、发送端口的值怎么获取?
    最后解决办法是通过构造函数的重载,在实例化的过程中传进对应参数。

    4.2 具体测试过程4.2.1 登录界面
    4.2.2 用户主界面
    4.2.3 聊天界面

    5 心得体会通过这次课程设计,我学会了使用Qt制作一个简易的聊天工具,学到了Qt的UI布局、数据库操作、多界面的切换、信号与槽、socket编程、UDP通讯以及文件操作等,希望以后能进一步的深造学习。
    参考文献[1] 陈维兴 林小茶, C++面向对象程序设计教程(第3版). 北京: 清华大学出版社, 2009年5月
    [2] 闫锋欣 曾泉人 张志强 译, C++ GUI Qt4 编程(第2版). 电子工业出版社, 2013年5月
    [3] 金大颐 翻译:张红艳, Qt5开发实践. 北京: 人民邮电出版社, 2015年9月
    1 评论 26 下载 2018-12-13 09:31:56 下载需要5点积分
  • 基于JSP和SSH框架实现的班级管理系统

    1 系统需求的分析1.1 需求分析本项目所开发的班级管理系统完成学校对学生的班级信息的统计与管理,减少数据漏掉的情况,同时也节约人力、物力和财力,告别以往的人工统计。方便学生使用,学生可以在线查看班级信息,学生信息,课程信息,成绩信息,信息修改。
    1.1.1 系统管理员需求分析
    班级管理:管理员在登录之后可以对系统内的班级进行管理,包括对班级的信息进行增加、查询、修改和删除等操作
    课程管理:管理员在登录之后可以对系统内的课程进行管理,包括对课程的信息进行增加、查询、修改和删除等操作
    学生管理:管理员在登录之后可以对系统内学生进行管理,包括对学生的信息进行增加、查询、修改和删除等操作

    1.1.2 教师需求分析基本信息管理:

    成绩录入:管理员在后台添加、编辑成绩,进行成绩录入
    统计查询:统计某一个学生的所修课程信息、汇总出学分、不及格课程(标红)统计每一门课程的最高分、最低分和平均分

    1.2 任务概述1.2.1 目标本系统是为了更好管理班级信息而设计的。由于学校的学生繁多,包含的信息量大且复杂,有必要建立一个班级管理系统,使选班级管理工作规范化,系统化,程序化,提高信息处理的速度和准确性,能够及时、准确、有效的查询和修改选课排课相关信息。
    1.2.2 运行环境服务器配置包括硬件配置和软件配置,它们各自都有详细的要求,下面将分别进行介绍。

    硬件配置安装本软件之前,需要确保计算机具有如下配置,这也是最低硬件要求: 酷睿i5或更高的微处理器(或与之相当的处理器) 使用2G内存
    软件配置安装本软件之前,需要确保计算机已安装:Micorsoft Win10的操作系统

    1.3 系统完整性、安全性1.3.1 对服务的要求为保证该系统平稳、安全地运行,系统为用户提供的服务要有以下限制:

    管理员具有该系统的最高权限,负责系统维护,更新 教师可以查看个人的全部信息,修改个人信息,若要修改课程信息需向教务处申报,由管理员修改学生能查看个人的全部信息、自己的选课结果、修改个人信息,若要修改选课信息,需向教务处申报,由教务处修改
    1.3.2 对性能的要求
    此系统的数据输入大多数为字符串类型,也有表示成绩的浮点数,精度为6
    响应时间:对于管理人员输入的用户信息应该在人们所能接受的等待时间来确定,通常为1-2秒
    更新处理时间要求 :用户输入数据后,对于该操作人员输入的数据处理时间应该是毫秒级的。数据的转换和传输也应该在人们的接受的等待时间内

    灵活性

    在操作方式上若发生变化,如无法使用浏览器进入系统,那么,可以使用命令方式进入如:可以通过编写java程序与数据库联接,实现登录
    因为本系统开发是使用jsp实现,这种开发技术具有java一样的很好的系统移植性
    对于数据精度方面,应在数据库中加以限制;实现实体完整性,用户自定义完整性约束
    在设计界面结构和数据结构是应留有对以后扩充系统功能的余地,如可以在每个数据字段上设计多个自定义字段

    2 系统设计2.1 系统概要设计在需求明确、准备开始编码之前,要做概要设计。概要设计的主要任务是把需求分析得到的DFD转换为软件结构和数据结构。设计软件结构的具体任务是:将一个复杂系统按功能进行模块划分、建立模块的层次结构及调用关系、确定模块间的接口及人机界面等。数据结构设计包括数据特征的描述、确定数据的结构特性、以及数据库的设计。概要设计有多种方法。在早期有模块化方法、功能分解方法;在60年代后期提出了面向数据流和面向数据结构的设计方法;近年来又提出面向对象的设计方法等。本系统采用模块化软件设计,自顶向下逐层把软件系统划分成若干模块。每个模块完成一个特定的功能,最后将所有模块按照某种方法组合成一个整体,达到整个播放器所要求的功能。
    2.2 系统功能设计及描述本选课系统不仅要实现常见的选课功能,而且还要有友好的用户界面。其最终设计目标是:多用户可以同时对系统进行操作、实现学生选课及对个人信息的修改,实现老师可以查看学生选课情况及对个人信息的修改,实现管理员对教师,学生信息修改及对课程的管理、运行平台要求不高、界面美观舒适、操作简单、易维护、高稳定性,能满足用户的常见需求。
    主要划分为以下几个功能模块,每个功能模块的作用描述如下:

    班级管理:主要用来管理班级情况
    课程管理:管理员可以对课程进行管理确定课程的数量
    学生管理:管理员可以对学生进行管理,可以对学生增加或者删除
    成绩录入:将成绩提交到数据库
    统计查询:统计某一个学生的所修课程信息、汇总出学分、不及格课程(标红)统计每一门课程的最高分、最低分和平均分

    3 系统功能的实现3.1 学生登录界面
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>班级信息管理系统登陆界面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <link rel="stylesheet" type="text/css" href="styles.css"> <link href="/Wopop_files/style_log.css" rel="stylesheet" type="text/css"> <link rel="stylesheet" type="text/css" href="/Wopop_files/style.css"> <link rel="stylesheet" type="text/css" href="/Wopop_files/userpanel.css"> <link rel="stylesheet" type="text/css" href="/Wopop_files/jquery.ui.all.css"> <script src="/Wopop_files/login.js"></script> <script src="/Wopop_files/JQuery.cookie.js"></script> <script src="/Wopop_files/google_jquery.min.js"></script> <script src="/Wopop_files/google_jquery-ui.min.js"></script><script language="JavaScript">function chkvalue(txt) { if(txt.value=="") alert("文本框里必须填写内容!");}</script></head> <body class="login" id="myform" method="post"><div class="login_m"><div class="login_logo"><h1><strong>班级信息管理系统</strong></h1></div><div class="login_boder"><div class="login_padding" id="login_model"> <h2>用户名</h2> <label> <input type="text" id="username" name="username" class="txt_input txt_input2" onfocus="if(this.value=='请输入用户名'){this.value='';}" onblur="if(this.value==''){this.value='请输入用户名';}" value="请输入用户名" value="${sid}"> </label> <h2>密码</h2> <label> <input type="password" name="password" id="password" class="txt_input" onfocus="if(this.value=='*******'){this.value='';}" onblur="if(this.value==''){this.value='*******';}" value="*******" value="${spassword}"> </label> <font size="3px;" style="color: red"> ${msg} </font> <div class="rem_sub"> <div class="rem_sub_l"> <p class="pull-left" align="right"><a id="iforget" href="register.action"> 注册</a></p> </div> <p class="forgot" ><a id="iforget" href="../index.jsp">忘记密码 ?     </a></p> </div> <div class="rem_sub"> <div class="rem_sub_l"> <input type="checkbox" name="checkbox" id="save_me"> <label for="checkbox">记住用户信息</label> </div> <label> <input type="submit" class="sub_button" name="button" id="button" value="登 录" style="opacity: 0.7;" onClick="IMG1_onclick2()" > </label> </div></div><div id="forget_model" class="login_padding" style="display:none"><br> <h1>Forgot password</h1> <br> <div class="forget_model_h2">(Please enter your registered email below and the system will automatically reset users’ password and send it to user’s registered email address.)</div> <label> <input type="text" id="usrmail" class="txt_input txt_input2"> </label> <div class="rem_sub"> <div class="rem_sub_l"> </div> <label> <input type="submit" class="sub_buttons" name="button" id="Retrievenow" value="Retrieve now" style="opacity: 0.7;">     <input type="submit" class="sub_button" name="button" id="denglou" value="Return" style="opacity: 0.7;">   </label> </div></div><!--login_padding Sign up end--></div><!--login_boder end--></div><!--login_m end--><br> <br> <p align="center"> 班级信息管理系统 <a href="http://www.stdu.edu.cn/" target="_blank" title="铁大官网"></a> - Made by <a >陈鹏</a></p></body><script type="text/javascript"> function IMG1_onclick2() { var sid = document.getElementById("username"); var spassword = document.getElementById("password"); var url = "login_check.action?sid=" + escape(sid.value) + "&spassword=" + escape(spassword.value); if (sid.value == "") { alert("用户名不能为空"); } else if (spassword.value == "") { alert("密码不能为空"); } else if (sid.value.length > 20 ||sid.value.length < 6) { alert("用户名小于6位或大于20位"); } else if (spassword.value.length > 20 || spassword.value.length < 6) { alert("密码小于6位或大于20位"); } else if (spassword.value=="******"||sid.value == "请输入用户名") { alert("请输入正确的用户信息"); } else if (CheckCode(sid.value) && CheckCode(sid.value) ) { alert("有特殊字符请重新填写!"); sid.value = ""; spassword.value = ""; }else { /* alert(0); */ window.location.href = url; } } function CheckCode(s) //有特殊字符为true { var containSpecial = RegExp(/[(\ )(\~)(\!)(\#)(\$)(\%)(\^)(\&)(\*)(\()(\))(\-)(\_)(\+)(\=)(\[)(\])(\{)(\})(\|)(\\)(\;)(\:)(\')(\")(\,)(\.)(\/)(\<)(\>)(\?)(\)]+/); return (containSpecial.test(s)); }</script></html>
    3.2 主页
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>班级信息管理系统</title> <%@include file="/WEB-INF/Z-views/common/head.jsp"%> <%-- <script type="text/javascript" src="/js/jquery1.js"></script> --%> <script type="text/javascript"> $(document).ready( function() { $(".div2").click( function() { $(this).next("div").slideToggle("slow").siblings( ".div3:visible").slideUp("slow"); }); }); function openurl(url) { var rframe = parent.document.getElementById("rightFrame"); rframe.src = url; }</script><style type="text/css">body { margin: 0; font-family: 微软雅黑; background-image: url(images/.jpg); background-repeat: no-repea; background-size: cover; background-attachment: fixed;}.top1 { position: absolute; top: 0px; width: 100%; height: 20px; text-align: center; color: black; font-size: 17px; font-height: 20px; font-family: 楷体;}.title {float:left; margin:-32px 20px; font-size: 35px; color: black; font-height: 30px; font-family: 隶书;}.top2 { position: absolute; top: 20px; width: 100%; height: 77px; text-align: center; color: #ccffff;}.left { position: absolute; left: 0px; top: 97px; width: 200px; height: 85%; border-right: 1px solid #9370DB; color: #000000; font-size: 20px; text-align: center;}.right { position: absolute; left: 200px; top:97px; width: 85.2%; height: 85%; border-top: 0px solid #484860; font-size: 14px; text-align: center;}.end { position: absolute; bottom: 0px; width: 100%; height: 30px; text-align: center; color: #556B2F; font-size: 17px; font-height: 20px; font-family: 楷体; background-color:ABD6E0}.div1 { text-align: center; width: 200px; padding-top: 10px;}.div2 { height: 40px; line-height: 40px; cursor: pointer; font-size: 18px; position: relative; border-bottom: #ccc 0px dotted;}.div3 { display: none; cursor: pointer; font-size: 15px;}.div3 ul { margin: 0; padding: 0;}.div3 li { height: 30px; line-height: 30px; list-style: none; border-bottom: #ccc 1px dotted; text-align: center;}.a { text-decoration: none; color: #000000; font-size: 15px;}.a1 { text-decoration: none; color: #000000; font-size: 18px;}</style> </head> <body> <div class="top1"> <marquee scrollAmount=2 width=300>欢迎使用该系统!</marquee> </div> <div class="top2"> <div class="title" > <br/> <span style="size:18px"> 班级信息管理系统</span> <br/> </div> <div class="fr top-links" align="right" > <br/> <br/> <a href="javascript:void(0);" onClick="openurl('help');"> <i class="ti-user"></i> <span style="color: black">登录用户:DeathGhost</span></a> </div> </div> <div class="left"> <div class="div1"> <a class="a" href="javascript:void(0);" onClick="openurl('student_Studentlist.action');"> <div class="div2"> <i class="ti-user"></i> 学生信息 </div> </a> <a class="a" href="javascript:void(0);" onClick="openurl('banji_Banlist.action');"> <div class="div2"> <i class="ti-view-list-alt"></i> 班级信息 </div> </a> <a class="a" href="javascript:void(0);" onClick="openurl('kecheng_KeChenglist.action');"> <div class="div2"> <i class="ti-text"></i> 课程信息 </div> </a> <a class="a" href="javascript:void(0);" onClick="openurl('score_ChengJilist.action');"> <div class="div2"> <i class="ti-pencil-alt2"></i> <span>成绩录入</span> </div> </a> <a class="a" href="javascript:void(0);" onClick="openurl('tongji');"> <div class="div2"> <i class="ti-map"></i> 统计查询 </div> </a> <a class="a" href="javascript:void(0);" onClick="openurl('help.action');"> <div class="div2"> <i class="ti-bell"></i> 系统信息 </div> </a> <a class="a" href="login.action" onclick="Exit_onclick()"> <div class="div2"> <i class="ti-export"></i> 退出系统 </div> </a> </div> </div> <div class="right"> <iframe id="rightFrame" name="rightFrame" width="100%" height="100%" scrolling="auto" marginheight="0" marginwidth="0" align="top" style="border: 0px solid #CCC; margin: 0; padding: 0;"> </iframe> <div class="copyright pull-right"> <p style="color:black"> 班级信息管理系统 <a href="http://www.stdu.edu.cn/" target="_blank" title="铁大官网">   </a></p> </div> </div> </body> <!-- 退出系统的验证 --> <script language="JavaScript"> function Exit_onclick() { if (confirm("确定退出系统吗?")) { return true; } else{ return false; } } </script></html>
    3.3 查看学生信息
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>学生信息管理界面</title> <%@include file="/WEB-INF/Z-views/common/head.jsp"%> </head><body><s:debug/><br/> <br/> <center> <s:form id="domainForm" action="student_Studentlist" theme="simple"> 名称: <s:textfield name="baseQuery.sname" placeholder="名称" />   <a href="javascript:;" onclick="go(1);" class="add">搜索 </a>   <a href="student_input.action" class="add">添加</a> <br /> <br /> <table border="1" align="center"> <tr style="background-color: PowderBlue;"><!--style="background-color: DodgerBlue;" --> <th width="15%" ><span><strong>学 号</strong></span></th> <th width="15%" ><span><strong>姓名</strong></span></th> <th width="12%" ><span><strong>性别</strong></span></th> <th width="15%" ><span><strong>密码</strong></span></th> <th width="11%" ><span><strong>联系电话</strong></span></th> <th width="11%" ><span><strong>家庭住址</strong></span></th> <th colspan="2" width="11%" align="center"><span><strong>操作</strong></span></th> </tr> <s:iterator value="pageList.rows" var="t"> <tr style="background-color: white;"> <td><s:property value='sid'/></td> <td><s:property value='sname'/></td> <td><s:property value='ssex'/></td> <td><s:property value='spassword'/></td> <td><s:property value='slxdh'/></td> <td><s:property value='sjtzz'/></td> <td><button type="button" class="btn1" onclick="updateDomain('student_updateAction.action?sid=<s:property value='sid'/>');">编辑</button></td> <td><button type="button" class="btn1" onclick="deleteDomain('student_delete.action?sid=<s:property value='sid'/>');">删除</button></td> </tr> </s:iterator> </table> <%@include file="/WEB-INF/Z-views/common/page.jsp"%> </s:form> </center></body><%-- <%@include file="/WEB-INF/Z-views/common/tail.jsp"%> --%></html>
    3.4 班级信息
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head> <title>班级信息管理界面</title><%@include file="/WEB-INF/Z-views/common/head.jsp"%> </head><body><s:debug></s:debug><br/><br/> <center> <s:form id="domainForm" action="banji_Banlist.action" theme="simple"> 名称: <s:textfield name="baseQuery.bname" placeholder="名称" />   <a href="javascript:;" onclick="go(1);" class="add">搜索 </a>   <a href="banji_input.action" class="add">添加</a> <br /> <br /> <table border="1" > <tr style="background-color: ;"> <th width="20%" ><span><strong>编 号</strong></span></th> <th width="40%" ><span><strong>名 称</strong></span></th> <th colspan="2" width="20%"><span><strong>操作</strong></span></th> </tr> <s:iterator value="pageList.rows" var="st"> <tr style="background-color: white;"> <th><s:property value='bid'/> </th> <th><s:property value='bname'/></th> <td ><button type="button" class="" onclick="updateDomain('banji_actionUpdate.action?bid=<s:property value='bid'/>');">编辑</button></td> <td><button type="button" class="" onclick="deleteDomain('banji_delete.action?bid=<s:property value='bid'/>');">删除</button></td> </tr> </s:iterator> </table> <%@include file="/WEB-INF/Z-views/common/page.jsp"%> </s:form> </center></body><%-- <%@include file="/WEB-INF/Z-views/common/tail.jsp"%> --%><center></center></html>
    3.5 课程信息
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>课程信息管理界面</title> <%@include file="/WEB-INF/Z-views/common/head.jsp"%> </head><body><s:debug></s:debug><br/><br/> <center> <s:form id="domainForm" action="kecheng_KeChenglist" theme="simple"> 名称: <s:textfield name="baseQuery.kname" placeholder="名称" />   <a href="javascript:;" onclick="go(1);" class="add">搜索 </a>   <a href="kecheng_input.action" class="add">添加</a> <br /> <br /> <table border="1" > <tr style="background-color: PowderBlue;"> <th width="20%" ><span><strong>课程编号</strong></span></th> <th width="20%" ><span><strong>课程名称</strong></span></th> <th width="20%" ><span><strong>课程性质</strong></span></th> <th width="20%" ><span><strong>课程学分</strong></span></th> <th colspan="2" width="20%" ><span><strong>操作</strong></span></th> </tr> <s:iterator value="pageList.rows" status="st"> <tr style="background-color: white;"> <td><s:property value='kid'/></td> <td><s:property value='kname'/></td> <td><s:property value='knature'/></td> <td><s:property value='kxf'/></td> <td><button type="button" class="btn1" onclick="updateDomain('kecheng_actionUpdate.action?kid=<s:property value='kid'/>');">编辑</button></td> <td><button type="button" class="btn1" onclick="deleteDomain('kecheng_delete.action?kid=<s:property value='kid'/>');">删除</button></td> </tr> </s:iterator> </table> <%@include file="/WEB-INF/Z-views/common/page.jsp"%> </s:form> </center></body><%@include file="/WEB-INF/Z-views/common/tail.jsp"%></html>
    3.7 成绩录入
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head> <title>学生成绩信息管理界面</title><%@include file="/WEB-INF/Z-views/common/head.jsp"%> <script type="text/javascript" src="/js/model/score.js"></script></head><body><s:debug/><br/><br/> <center> <s:form id="domainForm" action="chengji_ChengJilist.action" theme="simple"> 学生学号: <s:textfield name="baseQuery.sid" placeholder=" 学生学号" />     课程名称: <s:select onchange='$("#domainForm").submit();' style="height:23px;" list="#allCnames" name="baseQuery.kid" listValue="kname" listKey="kid" headerKey="-1 " headerValue="------------请选择------------" />  <a href="javascript:;" onclick="go(1);" style="position: relative; left: 3%">搜索 </a>   <br /> <br /> <table border="1" > <tr style="background-color: PowderBlue;"> <th width="18%" ><span><strong>学生学号</strong></span></th> <th width="18%" ><span><strong>学生姓名</strong></span></th> <th width="18%" ><span><strong>学生班级</strong></span></th> <th width="25%" ><span><strong>所选课程</strong></span></th> <th width="10%" ><span><strong>课程成绩</strong></span></th> <th colspan="2" width="5%"><span><strong>操作</strong></span></th> </tr> <s:iterator value="pageList.rows"><!-- var="t" --> <tr style="background-color: white;"> <td><s:property value="STable.sid"/></td> <td><s:property value="STable.sname"/></td> <td><s:property value="STable.BTable.bname"/></td> <td><s:property value="KTable.kname"/></td> <td><!-- <s:property value='ccj'/> --> <input name="ccj" id="ccj" value="${ccj}" /> </td> <td ><a onclick="update(this)"><button type="button">保存 </button></a></td> </tr> </s:iterator> </table> <%@include file="/WEB-INF/Z-views/common/page.jsp"%> </s:form> </center></body></html>
    3.8 统计查询
    关键代码
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>课程信息管理界面</title> <%@include file="/WEB-INF/Z-views/common/head.jsp"%> </head><body><br/> <s:form> <table border="1" align="center"> <tr ><!--style="background-color: DodgerBlue;" --> <th width="11%" ><span><strong>学 号</strong></span></th> <th width="11%" ><span><strong>姓名</strong></span></th> <th width="8%" ><span><strong>性别</strong></span></th> <th width="11%" ><span><strong>出生日期</strong></span></th> <th width="11%" ><span><strong>密码</strong></span></th> <th width="11%" ><span><strong>联系电话</strong></span></th> <th width="11%" ><span><strong>家庭住址</strong></span></th> <th width="11%" ><span><strong>班级编号</strong></span></th> <th colspan="2" width="11%" ><span><strong>操作</strong></span></th> </tr> <s:iterator value="pageList.rows" status="st"> <tr style="background-color: white;"> <td>${sid}</td> <td>${sname}</td> <td>${ssex}</td> <td>${spassword}</td> <td>${slxdh}</td> <td>${sjtzz}</td> <td>${sName}</td> <td><button type="button" class="btn1" onclick="updateDomain('role_input.action?roleId=${roleId}');">编辑</button></td> <td><button type="button" class="btn1" onclick="deleteDomain('role_delete.action?roleId=${roleId}');">删除</button></td> </tr> </s:iterator> </table> </s:form></body><%@include file="/WEB-INF/Z-views/common/tail.jsp"%></html>
    4 心得体会通过这次使用SSH框架编写大作业,初期对于搭框架就遇到了不少问题,后来问同学+百度解决了问题,在后来进行删除操作,涉及到了级联操作,添加的时候也存在主外键约束,有时候查程序感觉是对的,但是运行结果总是不对,就开始调试,在控制台打印文字,根据这些调试和打印出的文字,来使程序能够正确运行,总之,这次还是有不少收获,中间遇到的问题,以及需要注意的地方写了一个TXT文件,也方便以后查看。
    3 评论 59 下载 2018-11-05 17:04:45 下载需要6点积分
  • 基于C#与SQL SERVER数据库的学生选课及成绩查询管理系统的设计与开发

    1 项目背景学生选课及成绩查询系统是一个学校不可缺少的部分,传统的人工管理档案的方式存在着很多的缺点,如:效率低、保密性差等,所以开发一套综合教务系统管理软件很有必要,它应该具有传统的手工管理所无法比拟的优点,如:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大的提高学校的管理效率,有助于推进学校的信息化建设。
    2 技术选型本系统未采用C#实现MDI——多文档窗口,因为考虑到C#的该技术与java类似,而暑期java实训时,曾用过类似的方法做过停车场管理系统,所以想为这次的系统注入一点新鲜的血液,所以本系统设计的主题采用了了C#的C#TreeView 实现。
    3 需求分析本系统包括两类用户:学生、管理员。管理员可以通过系统来添加管理员信息、修改管理员信息、添加学生信息、修改学生信息;开设课程、查询课程、录入成绩、统计成绩、修改成绩、修改个人密码等,而学生则可以通过系统来选择课程、查询课程、显示自己的课表、查询自己的成绩单、修改个人密码等等。
    3.1 系统实现的功能流程
    3.2 管理员角色拥有的功能3.2.1 管理员信息管理
    添加管理员信息

    管理员可以添加其他的管理员信息
    修改管理员信息

    管理员可以删除其他的管理员信息

    3.2.2 学生信息管理
    添加学生信息

    管理员可以添加学生信息,这些信息包括学生的学号,密码,年级,专业,出生日期等等
    修改学生信息

    管理员可以修改学生的信息

    3.2.3 课程管理
    开设课程

    管理员可以录入课程信息,学生就可以浏览到这些课程信息,从而选课
    查询课程

    可以通过学期查询课程,或通过学期和课程结合的方式查询课程

    3.2.4 成绩管理
    录入成绩

    管理员可以录入学生的成绩
    统计成绩

    管理员可以通过学期和课程信息来统计某门课的学生成绩,平均分、最高分、最低分以及可以通过成绩区间来查询某个学期某门课的学生的成绩信息。并且可以实现排序功能
    修改成绩

    管理员可以对成绩出错的学生的成绩进行修改
    修改个人密码

    管理员可以修改自己的密码

    3.3 学生角色拥有的功能3.3.1 课程管理
    选择课程

    学生可以根据本学期管理员发布的课程来选课
    查询课程

    可以通过学期查询课程,或通过学期和课程结合的方式查询课程
    显示课表

    学生可以根据自己的选课情况来查询自己的课表

    3.3.2 成绩管理
    我的成绩单

    学生可以根据学期来查询自己某个学期所有选修课程的成绩信息
    修改个人密码

    学生可以修改自己的密码

    4 数据库设计4.1 数据库关系图
    4.2 完成系统中数据表的结构设计学生信息表



    字段名称
    数据类型
    可空
    默认值
    说明




    stuid
    int
    不可

    主键,学生id,无实际意思,每次自增1


    stuname
    Nvarchar(30)
    不可

    学生姓名


    stuxuehao
    Nvarchar(30)
    不可

    学生学号,不能重复,登陆时的用户名默认是学号。


    stupasswd
    Nvarchar(30)
    不可

    学生密码


    stugrade
    Nvarchar(30)


    学生年级


    stumajor
    Nvarchar(30)


    学生专业


    stusex
    varchar(2)


    学生性别


    stuborn
    Nvarchar(30)


    学生出生日期


    role
    Nvarchar(30)

    学生
    角色,学生


    stuhometown
    Nvarchar(30)


    学生籍贯



    管理员信息表



    字段名称
    数据类型
    可空
    默认值
    说明




    manid
    int
    不可

    主键,管理员id,无实际意思,每次自增1


    manname
    Nvarchar(30)
    不可

    管理员用户名


    role
    Nvarchar(30)
    不可
    管理员
    角色,管理员


    manpasswd
    Nvarchar(30)
    不可

    管理员密码



    课程表



    字段名称
    数据类型
    可空
    默认值
    说明




    claid
    int
    不可

    主键,课程id,无实际意思,每次自增1


    claname
    Nvarchar(30)
    不可

    课程名


    term
    Nvarchar(30)
    不可

    开课的学期


    teacher
    Nvarchar(30)
    不可

    开课的教师



    课程细节表



    字段名称
    数据类型
    可空
    默认值
    说明




    sctimeid
    int
    不可

    主键,课程细节id,无实际意思,每次自增1


    claid
    int
    不可

    外键,课程号


    sctime
    Nvarchar(30)
    不可

    课程上课的时间


    location
    Nvarchar(30)
    不可

    课程上课的地点



    选课表



    字段名称
    数据类型
    可空
    默认值
    说明




    scid
    int
    不可

    主键,选课id,无实际意思,每次自增1


    stuid
    int
    不可

    外键,学生id


    claid
    int
    不可

    外键,课程id


    grades
    int
    不可

    学生成绩



    5 界面设计登录界面

    5.1 管理员角色管理员主界面

    管理员———-添加管理员界面

    管理员——修改管理员界面

    管理员——开设课程界面

    管理员——查询课程界面

    管理员——录入成绩界面

    管理员——统计成绩页面

    管理员——修改成绩界面

    管理员——添加学生信息界面

    管理员——修改学生信息界面

    管理员——修改密码界面

    5.2 学生界面学生登录主界面

    学生——选择课程界面

    学生——查询课程界面

    学生——显示课表界面

    学生——我的成绩单

    学生——密码修改界面

    6 关键技术的介绍6.1 选项使用treeview实现点击不同的选项,在右侧面板中显示不同的界面。
    具体代码如下:
    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { switch (this.treeView1.SelectedNode.Text) { case"录入成绩": Form2 f = new Form2(); f.TopLevel = false; f.FormBorderStyle = FormBorderStyle.None; f.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f); f.Show(); break; case"我的成绩单": searchgradeForm f1 = new searchgradeForm(); f1.TopLevel = false; f1.FormBorderStyle = FormBorderStyle.None; f1.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f1); f1.Show(); break; case"统计成绩": countForm f2 = new countForm(); f2.TopLevel = false; f2.FormBorderStyle = FormBorderStyle.None; f2.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f2); f2.Show(); break; case"开设课程": kaisheForm f3 = new kaisheForm(); f3.TopLevel = false; f3.FormBorderStyle = FormBorderStyle.None; f3.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f3); f3.Show(); break; case"选择课程": chooseForm f4 = new chooseForm(); f4.TopLevel = false; f4.FormBorderStyle = FormBorderStyle.None; f4.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f4); f4.Show(); break; case"查询课程": searchclassForm f5 = new searchclassForm(); f5.TopLevel = false; f5.FormBorderStyle = FormBorderStyle.None; f5.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f5); f5.Show(); break; case"添加管理员信息": addmanForm f6 = new addmanForm(); f6.TopLevel = false; f6.FormBorderStyle = FormBorderStyle.None; f6.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f6); f6.Show(); break; case"修改管理员信息": modifymanForm f7 = new modifymanForm(); f7.TopLevel = false; f7.FormBorderStyle = FormBorderStyle.None; f7.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f7); f7.Show(); break; case"添加教师信息": addteacForm f8 = new addteacForm(); f8.TopLevel = false; f8.FormBorderStyle = FormBorderStyle.None; f8.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f8); f8.Show(); break; case"修改教师信息": modifyteacForm f9 = new modifyteacForm(); f9.TopLevel = false; f9.FormBorderStyle = FormBorderStyle.None; f9.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f9); f9.Show(); break; case"添加学生信息": addstuForm f10 = new addstuForm(); f10.TopLevel = false; f10.FormBorderStyle = FormBorderStyle.None; f10.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f10); f10.Show(); break; case"修改学生信息": modifystuForm f11 = new modifystuForm(); f11.TopLevel = false; f11.FormBorderStyle = FormBorderStyle.None; f11.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f11); f11.Show(); break; case"关于": aboutForm f12 = new aboutForm(); f12.TopLevel = false; f12.FormBorderStyle = FormBorderStyle.None; f12.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f12); f12.Show(); break; case "退出系统": Application.Exit(); break; case "显示课表": showkebiaoForm f13 = new showkebiaoForm(); f13.TopLevel = false; f13.FormBorderStyle = FormBorderStyle.None; f13.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f13); f13.Show(); break; case "修改密码": modifymimaForm f14 = new modifymimaForm(); f14.TopLevel = false; f14.FormBorderStyle = FormBorderStyle.None; f14.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f14); f14.Show(); break; case "修改成绩": modifygradeFram f15 = new modifygradeFram(); f15.TopLevel = false; f15.FormBorderStyle = FormBorderStyle.None; f15.WindowState = FormWindowState.Maximized; panel2.Controls.Add(f15); f15.Show(); break; } }
    6.2 在其他的窗口得到在登录窗口输入的信息实现方法:在loginFram中设置两个方法,在其他类中只需要引用loginFram的这些方法即可。
    具体实现如下:
    public static String getStudent() { String stuxuehao = ""; stuxuehao = loginForm.name; return stuxuehao; } public static String getRole() { String role1 = ""; role1 = role; return role1; }
    6.3 管理员开设课程异常处理管理员开设课程时,对于同一时间该教室有课的情况怎么做出异常处理。集体实现如下:
    private void button1_Click(object sender, EventArgs e) { string teacher = textBoxteacher.Text; string classes = textBoxclass.Text; string term = comboBoxterm.SelectedItem.ToString(); string flags = "1"; SqlConnection conn = new SqlConnection(loginForm.connectionString); conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; //将开课信息插入到开课表里 //MessageBox.Show("开设课程成功!"); string sql = ""; //得到上课的地点 string didian = comboBoxdidian.SelectedItem.ToString(); //checkedListBoxtime for (int i = 0; i < checkedListBoxtime.Items.Count; i++) { if (checkedListBoxtime.GetItemChecked(i)) { String time = checkedListBoxtime.GetItemText(checkedListBoxtime.Items[i]); sql = "select * from sctime where sctime = '" + time + "'and location = '" + didian + "'"; SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataSet ds = new DataSet(); adp.Fill(ds); if (ds.Tables[0].Rows.Count > 0) { flags = "2"; MessageBox.Show("该时间该教室已经有课!"); break; } else { flags = "1"; break; } } } if (flags == "1") { sql = "insert into class (claname,term,teacher) values ('" + classes + "','" + term + "','" + teacher + "')"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); for (int i = 0; i < checkedListBoxtime.Items.Count; i++) { if (checkedListBoxtime.GetItemChecked(i)) { string time = checkedListBoxtime.GetItemText(checkedListBoxtime.Items[i]); //将开课表的id得到 sql = "select claid from class where claname = '" + classes + "' and term = '" + term + "' and teacher = '" + teacher + "'"; cmd.CommandText = sql; String id1 = cmd.ExecuteScalar().ToString(); int id = 0; int.TryParse(id1, out id); sql = "insert into sctime values(" + id + ",'" + time + "','" + didian + "')"; cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } MessageBox.Show("开设课程成功!"); } conn.Close(); }
    6.4 学生选择课程异常处理学生选择课程时,对选择一门课程与已选择的课程出现上课时间冲突的情况的异常处理。集体实现如下:
    private void button1_Click(object sender, EventArgs e) { string flags = "1"; //得到stuid string stuxuehao = textBox1.Text; SqlConnection conn = new SqlConnection(loginForm.connectionString); conn.Open(); string sql = "select stuid from student where stuxuehao = '" + stuxuehao + "'"; SqlCommand cmd = new SqlCommand(sql, conn); String id1 = cmd.ExecuteScalar().ToString(); int.TryParse(id1, out stuid); //得到课程的id int claid = 0; int.TryParse(textBoxid.Text, out claid); //查询你在该时间是否有课 sql = "select sctime from sctime where claid =" + claid; SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataSet ds = new DataSet(); adp.Fill(ds); for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { DataRow dr = ds.Tables[0].Rows[i]; string time = dr[0].ToString();//第一列 sql = "select * from sc,sctime,class where class.claid = sc.claid and class.claid = sctime.claid and sctime = '" + time + "' and sc.stuid =" + stuid; SqlDataAdapter adp1 = new SqlDataAdapter(sql, conn); DataSet ds1 = new DataSet(); adp1.Fill(ds1); if (ds1.Tables[0].Rows.Count > 0) { flags = "2"; MessageBox.Show("课程上课时间冲突!"); break; } } if (flags == "1") { sql = "insert into sc(claid,stuid) values(" + claid + "," + stuid + ")"; cmd.CommandText = sql; if (cmd.ExecuteNonQuery() > 0) { MessageBox.Show("选课成功!"); } } if (listBox1.Items.Count > 0) {//清空所有项 listBox1.Items.Clear(); } sql = "select class.claname from sc,class where sc.claid = class.claid and stuid=" + stuid; SqlDataAdapter adp2 = new SqlDataAdapter(sql, conn); DataSet ds2 = new DataSet(); adp2.Fill(ds2); foreach (DataRow row in ds2.Tables[0].Rows) { listBox1.Items.Add(row[0].ToString()); } conn.Close(); }
    7 系统测试怎么提高访问数据库的速度
    改进方法:引入视图、触发器、函数、存储过程,优化表结构,建立索引。
    8 完成情况总结通过几周的努力,从前期的需求分析与架构设计到实际的编码阶段,我完成了学生选课及成绩管理系统的开发与设计。已经大致完成了主要的功能,不过还有一些亟待完善的方面,例如对数据的存储采用加密的措施,UI设计并不是很出色等等,这些问题都需要我再以后的时间里去慢慢弥补,还有刚开始,我对treeview并不熟悉,所以先建立了几个原型来测试,领会了treeview的使用方法后才切入正题进行开发。
    在这开发的过程中,我收获很大,相比前几次的开发,我真正重视起测试在软件开发中的作用,在软件开发的后期,我专门建立一个bug列表,将出现的bug详细记录在列表中,并在软件调试的后期对照列表认真改进软件,考虑以后使用软件来做相关方面的管理。当然,我也遇到不少代码编写的问题,有时要花较长的时间来解决问题,这也是自己平时编写代码较少的原因。通过这次软件的开发,在编写代码上有了一定的提高,同时也知道了软件开发过程中需要注意的问题。比如,开发逻辑思维要清晰,不然可能会把问题想的复杂化。平时多和项目成员交流,这样你才能知道自己的想法有那些出入,利于软件的开发。
    通过这次实验,使我对软件开发有了更深一步的了解。在软件开发中应注意的问题和考虑的问题都能较好的做到。
    2 评论 11 下载 2018-11-06 16:45:43 下载需要5点积分
  • 基于Power Bulider和Oracle数据库实现的学生教务管理系统

    一、分析与建模1.1 系统业务流程图
    项目用例图



    1.2 功能需求分析与建模


    1.3 数据需求分析与建模体之间的联系:学生信息表(student)、教师信息表(teacher)、管理员信息表(Administrator)、课程表(course)、选课表(curricula_variable)、成绩表(score)、公告发布表(announcement)。

    管理员(Administrator):管理号、姓名、性别、年龄、联系电话、密码、邮箱
    公告(announcement):通知编号、管理号、通知标题、 通知内容
    学生(student):学号、姓名、性别 、民族、入学时间、专业、培养层次、学生联系电话、学生QQ、密码、邮箱
    成绩(score):学生编号、 课程编号、教师编号、学期、分数
    教师(teacher):教师编号、教师姓名、教师姓名、职称、所在学院、教师联系电话、教师QQ、密码、邮箱
    选课表(curricula_variable):选课编号、学号、课程号、学生编号、教师编号、上课时间、学生姓名、教师姓名、是否选课、教师审核
    课程(course):课程号、课程名、学分、课程简介

    二、系统设计2.1 功能设计根据学生选课排课—成绩查询管理的需要,学生成绩管理系统从功能上共分几大模块,其结构如图:

    系统管理员模块:可以进行管理员、教师、学生等不同身份选择性的登陆,对用户权限进行限制,方便不同级别用户工作
    学生管理模块:该模块主要功能是完成查看学生成绩信息、打印成绩报表。修改个人信息、查看公告和选课学习课程等功能
    教师管理模块:该模块主要功能是审核学生的选课,查看,学生成绩、选课、当有挂科时候,发布公告通知、以及对相关学生的成绩的录入合提交给管理员管理功能
    数据库管理员模块:该模块主要功能是查看、审核学生的选课情况、发布公告通知学生和教师,以及删除过于陈旧、误发布的公告。新增加、删除、修改、查询学生教师用户的个人信息。审核教师提交的学生成绩。还附带开发出完成数据的备份、,误删除以及恢复功能

    2.2 数据库设计在学生成绩管理数据库中需建立至少7个必要的数据表:学生信息表(student)、教师信息表(teacher)、管理员信息表(Administrator)、课程表(course)、选课表(curricula_variable)、成绩表(score)、公告发布表(announcement)。
    2.3 系统实现对系管理员而言,进入登陆界面后,可直接调用数据库中数据修改、查询本系统现有学生成绩信息等;对教师而言,进入登陆界面后,不仅有对教师自身信息能够得取得相关的权限外,可对全校学生成绩修改、查询,统计补考人员,打印成绩单等的操作。对于学生而言,可以实现自己的选课功能,成绩查询和预览、打印成绩单,查看公告。
    2.4 数据库设计
    三、系统开发与维护中的重难点3.1 系统开发与维护环境近几年来,随着学院新校建设、办学、招生规模的扩大,学校校生从 几千余人增加到 几万余人。与之对应的学生成绩信出现了几何式的增长, 使学校的的教务管理工作变的异常繁重,经常出现成绩查询不准确、补考学生统计不全等情况,采用传统的管理模式不适应学院当前的要求,因此学生成绩管理自动化、信息化也被提上了日程。在学校教务工作中占有很大比重的一项就是每学期末的成绩录入、成绩打印工作,以及部分选课在网上选课,采用传统的人工进行管理不仅任务重、效率低,而且易出错、不易查询、难于维护。
    学生成绩管理系统正是为了减轻教务人员工作量,实现学校管理自动化,解决学院学生成绩管理难这一难题的办公软件。本系统以中文版 Power bulider 12.5 为前台开发工具,PowerDesign 15.1和使用目前到2018年为止的最新的Oracle 11g数据库作为后台数据库。系统对操作人员的计算机水平要求不高,对他们几乎不加培训便能掌握系统的大部分功能使用。

    硬件环境:windows XP/win7 x86 x64/win10 x86 x64
    软件开发环境:Power bulider 12.5/ PowerDesign 15.1/Oracle 11g

    选择原因
    开发时候,因为大部分时间都需要在机房里面进行编写,而XP的系统现在还有一部分在计算机机房存在,所以要考虑到兼容,还有主要占领大部分份额的win7和现在正在推行的外win10的操作系统,都是需要考虑的能够兼容运行的。而实际上面我们开发了中考虑到了PowerBuilder提供了对目前流行的大多数关系数据库管理系统的支持,并且在PowerBuilder的应用程序中对数据库访问的部分一般采用国际化标准数据库查询语言SQL,方便我们使用PowerBuilder开发的应用程序的时候,可以不做修改或者只做少量的修改就可以在不同的后台数据库管理系统上使用。并且PowerBuilder开发的应用程序是独立于服务器上的数据库管理系统的。使用PowerDesigner不仅可以加速了开发的过程,而且也向最终的用户提供了管理和访问项目的信息的一个有效的结构方式。它允许我们编码时候创建和管理数据的结构,和开发和利用数据的结构针时候,使用开发工具环境快速地生成应用对象和数据敏感的组件。后台的数据库使用Oracle 11g则是考虑了它提供的高性能、伸展性、可用性和安全性,并且更方便地在低成本服务器和存储设备组成的网格上运行 ,相对过往版本而言,Oracle 11g具有了与众不同的特性。
    3.2 系统开发与维护的重难点3.2.1 教师登录界面

    user1=sle_1.textpsw1=sle_2.textusername=user1… if rb_2.checked=true then select count(*) into :count1 from teachers where tno= :user1; select count(*) into :count2 from teachers where tno=:user1 and tpsw=:psw1 ; if count2=1 then open(w_teacher_main)close(parent)else if count1=1 then messagebox("提示","密码错误!") count0=count0+1 if count0=3 then messagebox("提示","错误三次!") close(parent) else end if else messagebox("提示","用户名不存在!") count0=count0+1 if count0=3 then messagebox("提示","错误三次!") close(parent) else end if end ifend if3.2.2 课程信息管理:上传课程信息、检查课程信息

    dw_1.dataobject="d_student_view_course"dw_1.settransobject(sqlca)dw_1.insertrow(0)dw_1.retrieve("%")dw_1.settransobject(sqlca)dw_1.getrow()dw_1.retrieve("%"+sle_1.text+"%")integer imessagebox("提示","课程信息上传成功!")dw_1.update()commit;i=dw_1.insertrow(0)dw_1.scrolltorow(i)dw_1.settransobject(sqlca)dw_1.insertrow(0)close(parent)3.2.3 成绩管理:录入学生成绩、查看学生成绩、打印学生成绩


    dw_1.settransobject(sqlca)dw_1.insertrow(0)integer imessagebox("提示","成绩录入成功!")dw_1.update()commit;i=dw_1.insertrow(0)dw_1.scrolltorow(i)close(parent)dw_1.dataobject="d_select_chengji"dw_1.settransobject(sqlca)//dw_1.insertrow(0)dw_1.retrieve("%")dw_1.retrieve("%"+sle_1.text+"%")dw_1.settransobject(sqlca)dw_1.getrow()dw_1.dataobject="d_select_chengji"dw_1.settransobject(sqlca)dw_1.retrieve("%")dw_1.object.datawindow.print.preview=truedw_1.print()3.2.4 个人信息管理:密码修改、查看个人信息

    string psw1username=sle_1.text select tpsw into :psw1 from teachers where tno=:username; if sle_2.text=psw1 then if sle_3.text=sle_4.text then update teachers set tpsw=:sle_3.text where tno=:username; messagebox("提示","密码修改成功") close(parent) else messagebox("提示","两次密码不一致") end if else messagebox("提示","原密码错误")end ifdw_1.settransobject(sqlca)dw_1.retrieve(username)dw_1.settransobject(sqlca)dw_1.getrow()3.2.5 公告管理模块:发布、查看、删除、打印公告


    dw_1.settransobject(sqlca)dw_1.insertrow(0)integer imessagebox("提示","公告插入成功!")dw_1.update()commit;i=dw_1.insertrow(0)dw_1.scrolltorow(i)dw_1.settransobject(sqlca)dw_1.insertrow(0)dw_1.dataobject="d_gonggao1"dw_1.settransobject(sqlca)dw_1.retrieve("%")dw_1.retrieve("%"+sle_1.text+"%")dw_1.deleterow(dw_1.getrow())dw_1.update()3.2.6 选课管理:查看学生选课
    dw_1.dataobject="d_teacher_view_course1"dw_1.settransobject(sqlca)dw_1.insertrow(0)dw_1.retrieve("%")dw_1.settransobject(sqlca)dw_1.getrow()五、总结通过为期五周的课程小学期实训教程的临近结束,有一开始的有一个大概的了解数据库,到后来模糊知道了使用PowerBuild编写界面程序,发现它是能够如此之快的在短时间类完成相关的一个带界面的管理类程序软件。
    随着信息技术的发展,办公自动化已成为社会发展的主要趋势,学生选课—成绩管理系统的开发也就必不可少了,因此在这次的实践活动中,我们决定采用目前流行的PowerBuilder12.5 + Oracle11g + PowerDesign15.0设计了一个小型的学生选课–成绩查询系统,以增加对于项目的经验积累。完成项目之后,且对设计结果进行了一定的总结。总结如下:
    对于E_R图,生成表、和表与表之间的联系一定要正确,最好不要有大的问题。可以在设计过程中反复修改,以达到完美。而学生选课—成绩查询管理因为其日常事务比较繁琐,在设计数据库表之前一定要对系统的设计有一个整体的认识,对学生信息和课程信息进行整理,设计好各功能模块的E-R图。这样,在后期的编码设计时,避免了在后期便编写源码的过程中反复更改之前设计的表和相关E-R图。尤其是注意一点,千千万万不要命名使用英文和拼音混合,不然的话会是一个很悲伤的故事,还经常找不到相关的设计。
    对于公共部分的源码,窗口控件和布局都可以设计成具有通用性质,以提高编写的性能和缩短研发速度。还要注意代码的健壮性、稳定性和测试时候的一些边缘值的测试。在设计各个功能模块时,要考虑和其他模块的联系,更要结合实际情况对窗口要放置的空间进行分析,尤其在编制代码是要充分考虑各种限制条件,对不同的身份规定其不同的登录权限。
    还要注意与组员之间的沟通和交流,毕竟每个小组都是分工合作的。当组员出现了bug的时候,要能够帮助其找出错误,向互联网和组长和老师寻求帮助,以提高团队的氛围和整体水平,还可以促进大家之间的情感交流。何乐而不为?
    最后通过本小学期实践教学环节,我们不仅掌握了设计的基本步骤,懂得了编程的规范化,习惯和命名的规范化,设计初期的重要性和严谨性,编写的源码程序具有容错性和健壮性。并且在这五周之中,也离不开老师的耐心辅导,总是为了我们的知识的完备性,讲着更多的知识点,希望我们能够学的更好,辛苦劳累。最后通过这次的学习,加深了我们对软件开发的认识与理解。也为今后的开发打下了坚实基础和宝贵的经验。
    1 评论 1 下载 2019-07-04 10:08:52 下载需要12点积分
  • 基于JAVA和SQL SERVER数据库实现的酒店管理系统

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

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

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


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

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

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

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

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

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

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

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

    也可以更新:

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

    一、设计内容及要求1.1 设计内容聊天工具大多数由客户端程序和服务器程序外加服务器端用于存放客户数据的数据库组成,本程序采用客户机/服务器架构模式。通过Java提供的Socket类来连接客户机和服务器并使客户机和服务器之间相互通信,由于聊天是多点对多点的而Java提供的多线程功能。用多线程可完成多点对多点的聊天。
    1.2 设计要求主要有两个应用程序,分别为服务器程序和客户端程序。服务器应用程序主要用于消息转发、客户登录信息的管理以及向所有用户发送系统消息等;客户端应用程序主要用于客户聊天记录的显示和信息输入。采用Client/Server(C/S)体系结构,即客户机/服务器体系结构。聊天服务器专门用于监控用户状态和转发消息,客户端负责接收消息的用户序列和消息文本发送到服务器。该聊天系统实现私聊,群聊,用户注册,登陆,退出聊天系统等功能。
    二、系统需求分析2.1 系统介绍在当今信息时代,有许多的聊天工具,例如QQ、微信等。本程序就是利用Java网络编程的知识,采用客户机/服务器架构模式来实现客户端与客户端之间的通讯。
    2.2 开发背景在当今信息时代,越来越多的聊天工具被应用,Java语言是当今流行的网络编程语言,它具有面对对象、跨平台、安全、多线程等特点。使用Java语言不仅可以实现大型企业级的分布式系统应用,还能为小型的、嵌入式设备进行应用程序开发。面对对象的开发方法是当今最流行的开发方法,它不仅更贴近现实,而且有利于软件的维护和继承。为了进一步巩固课堂上所学到的知识,深刻把握Java语言的重要概念及面对对象的特性,锻炼我们熟练的应用面对对象的思想和设计方法解决实际问题的能力,所以我选择了开发Java多人聊天程序。
    三、系统总体设计3.1 系统功能结构图
    3.2 系统数据流程图
    四、系统详细设计4.1 本设计所涉及技术和知识点
    C/S体系结构:采用Client/Server(C/S)体系结构,即客户机/服务器体系结构。其中客户端用了发送和接受收显示聊天消息,服务器用来监听客户端的消息,并将接收到的数据转发到所用的客户端上,这样实现群聊功能。Socket套接字:作为多人聊天程序,网络编程的知识必不可少,其中用到了Socket套接字、IP地址、端口号等网络编程的知识。客户端与服务器的窗口用到Java Swing图形用户界面知识,其中包括界面的布局、组件的使用以及各种监听事件的使用。多线程:为了是客户端与客户端之间的消息、客户端发送与接收的消息不发生冲突,将每个客户端的发送和接收用不同的线程。IO流:聊天时客户端与服务器之间肯定有数据的输入输出,所以IO流的知识在这里也十分重要。
    4.2 功能模块详细设计
    客户端:运行客户端时,弹出登录客户端界面,这是需要设置用户名、IP地址和端口号,其中IP和端口号必须和服务器的对应,否则连接不上服务器。登录后进入客户端聊天界面窗口。这时可以与其他客户端之间在一个聊天室中聊天,若想私聊某人,只需在聊天内容前加上@该用户的姓名+:就可以了。点击右上角的下线按钮即退出该聊天室。
    发送消息:当点击发送按钮时,将消息通过DataOutputStream流中的writeUTF发送到服务端,服务端通过DataInputStream中的readUTF接受客户端的消息,紧接着服务端通过DataOutputStream中的writeUTF发送个所有客户端。
    私聊:当用户登录后,在没有点击发送按钮前,先将该客户端的姓名发送到服务器,服务器先接收到用户的姓名,然后在接收聊天消息。
    服务器:启动服务器,弹出设置服务器的窗口,填写服务器的IP地址和端口号,点击确定后,服务器启动,并不断监听客户端的连接和接收客户端发来的消息。

    五、编码与实现5.1 具体功能模块实现该多人聊天程序包括8个文件,功能如下:
    1. Client.java 包含Client类,其中有main、connectServer函数,是客户端启动的入口。在main函数中通过创建一个ClientLogin对象,来打开登陆窗口。 ClientLogin login = newClientLogin();
    2. ClientFrame.java
    包含ClientFrame类,该类继承于Jframe类,用来创建客户端的窗口。 其中包括窗口中的各个组件、布局以及组件的监听事件。
    sendButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { msg = msgText.getText().toString(); ClientSend.send(); msgText.setText(null); });
    发送按钮的监听事件,当点击发送时,将发送栏中的消息保存在字符串msg中,在,然后调用 ClientSend.send()函数,将该字符串发送到服务器。
    3. ClientLogin.java
    包含ClientLogin类,该类继承于Jframe类,用来创建客户端登录窗口,其中包括设置IP地址、端口号、用户姓名的各种组件,和登录按钮的监听事件:
    btn_login.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { name = jtf_userName.getText().toString(); ip = jtf_ip.getText().trim(); port = Integer.parseInt(jtf_port.getText().toString()); //点击登录后,客户端连接服务器 try { Client.connectServer(); } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } //隐藏当前窗口 dispose(); //关闭 //打开客户端 new ClientFrame(); } });
    点击登录按钮时,将窗口中用户姓名、IP地址和端口号分别赋值给字符串name、ip、port变量,然后调用Client.connctServer()来连接服务器,并且关闭该窗口,创建ClientFrame对象来打开客户端窗口。
    4. ClientReceive.java
    包含ClientReceive类,该类中有Runnable接口,用于创建一个用户接受服务器消息的客户端接受线程。
    线程体:
    public void run() { String msg = null; while(isRunning){ //将接受信息输出到客户端窗口中 msg = receive(); System.out.println(msg); ClientFrame.msgRecordText.append(msg+"\n"); } }
    该线程处于死循环中,其中receive()函数用来接收服务器的消息,并通过ClientFrame.msgReceordText.append(msg+”\n”)将消息显示在客户端的窗口聊天记录面板上。
    5. ClientSend.java
    包含ClientReceive类,该类中有Runnable接口,用于发送消息,该线程的线程体为空:
    public void run() { }
    当用户点击客户端窗口中的发送按钮时,会调用该类中的send函数,用于将消息发送到服务器。
    6. Server.java
    包含Server类,其中包含main、setServer方法和List<ServerForward>集合类。
    其中main函数是服务器的入口,用来打开服务器设置窗口。
    main函数:
    ServerFrame serverFrame = new ServerFrame();
    setServer函数:
    public static void setServer() throws IOException { //从服务器窗口获取ip和端口号 String ip = ServerFrame.ip; int port = ServerFrame.port; ServerSocket server = new ServerSocket(port, 0,InetAddress.getByName(ip)); while(true) { Socket client = server.accept(); System.out.println("连接成功"); ServerForward serverForward = new ServerForward(client); allClient.add(serverForward); Thread thread = new Thread(serverForward); thread.start(); } }
    启动服务器,不断的监听客户端的连接,当有客户端连接上时,在List<ServerForward>集合类中添加该线程,并启动该线程。
    7. ServerForward.java
    包含ServerForward类,服务器接受一个客户端得信息,再转发给其他客户端。该类中主要包括receive、send函数,用于转发客户端的消息。
    线程体:
    public void run() { //接受用户的昵称 while(isRunning) { if (name == null) name = getClientName(); else break; } while(isRunning) { sendToClient(receive()); } }
    因为服务器的工作不间断的,所以用无限循环。getClientName()从客户端中接受用户的姓名,并保存字符串name中。sendToClient(receive())接收一个客户端的消息,并转发给所有客户端。
    8. ServerFrame.java
    包含serverFrame类,该类继承于JFrame,用于创建服务器设置界面,其中包括设置IP地址、端口号,和确认按钮的监听事件:
    btn_set.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ip = jtf_ip.getText().trim(); port = Integer.parseInt(jtf_port.getText().toString()); //关闭窗口 dispose(); //点击确定后,设置服务器ip和端口号 try { Server.setServer(); } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } });
    将服务器设置窗口中的IP地址和端口信息ip、port字符串中,并调用Server.setServer函数,开始启动服务器。
    5.2 演示界面5.2.1 服务器设置窗口
    5.2.2 客户端登录窗口
    5.2.3 客户端窗口
    5.2.4 群聊和私聊
    3 评论 148 下载 2018-10-21 14:43:22 下载需要4点积分
  • 基于JSP的车险模拟系统的设计与实现

    摘 要随着科技的发展和时代的进步,使用管理系统来提高工作效率成为各大企业的选择。一个保险企业在日常经营中,如果采用传统的人工管理方式去管理大量的客户和保单信息,往往会造成工作挤压和员工情绪不满的现象。车险管理系统的出现,解决了以往保单理赔审核复杂的问题,公正、客观、快捷地对客户的保单进行管理,实现以人为本的管理战略,提高保险管理工作的效率。
    本文提出的车险管理系统基于B/S模式开发,根据数据建模,结合车险保单理赔管理的实际需求,设计系统架构。后端采用Java技术,选择关系型数据库MYSQL进行信息存储。本系统经过严格的功能性测试,取得了良好的运行效果。系统实现了客户管理,保单管理,理赔,保单情况统计等功能。车险管理系统的实施,满足了用户需求,在实际工作中逐渐完善,对车险管理效果有了显著改善。
    关键词:车险管理;JSP;数据库;B/S模式;Java
    AbstractWith the development of technology, major enterprises have chosen management system to improve working efficiency. If we use traditional manual method to manage large quantities of client and policy information, it will cause work squeeze and dissatisfaction of employees in daily life. The use of vehicle insurance management system has solved the problems of complex claims in the past. It can help manage the policies more fairly, objectively and quickly. It will also realize the people-oriented management strategy and improve the efficiency of insurance management.
    The vehicle insurance management system proposed in this article is based on B/S mode. The system is designed according to data modeling and combined with the actual demand of policy claims in vehicle insurance. The back-end adopts Java technology and chooses MYSQL which is a relational database to store information. This system has passed the strict function test and obtained the good running effect. The system achieves the function of customer management, policy management, claims, policy statistics and so on. The implementation of the vehicle insurance management system has met the needs of users and gradually improved in the actual work. It has also significantly improved the effect of vehicle insurance management.
    Key words: Vehicle insurance management; JSP;Database;B / S structure;Java
    一、绪论1.1 选题背景近年来,随着我国汽车行业的快速发展,我国汽车生产和销售量已经连续三年位居世界第一。在汽车产业迅速发展的同时,我国的汽车保有量随之迅猛提升,截至2018年6月,中国已经成为仅次于美国的世界第二大汽车拥有国。随着中国汽车市场的日益火爆,与之密不可分的车险市场也快速发展起来。近年机动车辆保险已经逐步发展成我国财产保险市场需求量最大的险种。车险管理系统的出现可以帮助各大保险公司更有效地保存客户的数据,为公司的业务管理带来巨大的便利。
    1.2 国内外现状从上世纪末开始,汽车保险在全球范围内都是财产保险的第一大险种,并一直保持高增长率,同时,中国的汽车保险业务进入了高速发展的时期,各大保险公司纷纷推出了各种类型的车险。随着时代的进步,国外的保险公司率先开启电子保单的管理,渐渐国内的保险公司渐渐从开始的纸质化保单过渡到电子保单的管理。车险管理系统主要用来帮助保险公司进行专业的保单管理,公司可以通过无纸化操作来按照客户的需求对每份保单进行创建及一系列的修改,既方便了公司的业务管理工作,又方便客户线上提出理赔,能让顾客得到更高效的服务。
    1.3 目的及主要研究内容本文研究目的在于分析并设计一个模拟车险管理系统来帮助保险公司提高工作效率,更便捷地管理客户的保单数据。并且可以让客户也登录系统,查看自己的个人信息及保单信息,提出取消保单和理赔申请。本文计划首先进行需求分析,确定系统想要实现的功能,分析可行性,确定所需的技术架构,然后逐步完善系统。
    1.4 本论文主要工作与章节安排
    第一章:本章主要介绍了本篇论文的选题背景,国内外现状,主要研究内容以及章节的安排
    第二章:本章主要介绍了本系统所运用的相关技术,对所采用技术进行了简单的说明
    第三章:本章主要介绍了系统的分析及设计,叙述了系统拟实现的模块功能,简述了系统的技术架构及数据库的主要设计逻辑,并且进行了可行性分析。
    第四章:本章主要介绍了系统实现的过程,具体介绍了系统各个模块的功能,包括管理员登录和客户登录两大部分
    第五章:本章主要介绍了所进行的系统测试过程,保证了系统能够顺利运行并实现拟实现的功能
    第六章:本章是本文的总结与展望,总结了实现本系统及完成本论文的心得,并表达了对未来学习及工作的展望与期待

    二.相关技术概述2.1 B/S架构B/S架构的中文全称为浏览器和服务器架构模式。它是继Web兴起后的又一种网络体系结构模式,其中Web浏览器是客户端的主要应用软件。B/S架构是以服务器为核心的系统,将客户端统一,并简化了系统的开发、维护和使用。客户端上只安装了一个浏览器,如Google或Internet Explorer,服务器上安装了Oracle、MySQL或SQL Server。浏览器在此模式下通过Web服务器和数据库发生关联,这种操作模式简化了客户端的负载,大大降低系统维护和开发的成本以及工作人员的总体工作量。
    2.2 HTML语言及CSS样式表HTML是超文本标记语言,是一种在标准通用标记语言下的应用。它也是用来标记网页的是一种标准和规范。HTML语言类似于在一个文本文件中添加标记,然后浏览器识别到这些标记后就能在网页上显示其内容。
    CSS样式表,是可以与HTML语言组合使用的一种语言,其中文名为层叠样式表。CSS通常可以用来静态地修改网页,稍复杂些CSS还可以动态地格式化网页元素,这需要使用各种脚本语言来实现。CSS的优点在于可以近似于像素级别地精确控制网页中元素的位置,支持几乎所有字体大小的样式,并且能够编辑Web对象和模型样式。
    2.3 Java语言Java是面向对象的编程语言。Java语言在囊括C++优点的同时,也淘汰了C++语言中比较难以理解的多继承和指针的概念。因此,Java语言具有功能强大、使用方便的特点。Java语言将面向对象的编程语言以静态方式完美实现,让程序员在编程过程中能够条理清晰的写出解决问题的方法。
    2.4 JSPJSP全名为Java Server Pages,中文名称是Java服务器页面。它基本上是一个简化的Servlet设计。它将类似HTML的标记写在Java编程语言中,进行包装处理逻辑生成动态网页。用户也可以通过网页的标记和脚本来访问服务器的现有资源。JSP实现了页面逻辑和显示的分离,使基于Web的应用程序开发起来更加快捷方便。
    2.5 My EclipseMy Eclipse是加入插件开发的一个基于Eclipse的功能强大的集成开发环境,它主要是为Java,Java EE和移动应用的发展而出现。My Eclipse可以支持Java Servlet,AJAX,JSP,JSF,Struts,Spring,Hibernate,EJB3,JDBC数据库链接工具等多项功能。
    2.6 MySQLMySQL是Oracle旗下的一个关系型数据库管理系统,该系统将数据存储在不同的表中,提高速度和灵活性。MySQL具有开放源码的特点,因此一般是中小型系统开发中较常用的一种数据库技术。
    三.系统分析与设计3.1 需求分析及设计3.1.1 管理员登录

    客户信息模块:本模块可以添加新的客户,查看/编辑/删除已有客户的信息
    添加保单模块:本模块可以选择客户进行添加保单操作,输入车辆信息,选择险种,输入保金,生效期和失效期(保期为一年),并完成保单
    查询保单模块:本模块可以通过输入客户的身份证号码查询出客户的个人信息及保单信息
    取消保单模块:本模块可以看到客户提出的取消保单申请,输入需要退回的保费,成功完成取消保单操作
    理赔模块:本模块可以看到客户提交的理赔申请,进行受理,同时回复赔偿金额,完成理赔操作
    保单情况统计模块:本模块可以能统计出什么牌子的车投保次数最多,理赔次数最多,便于保险公司进行数据统计

    3.1.2 客户登录

    修改登录密码模块:在本模块客户可以进行修改登录密码操作
    客户信息模块:在本模块客户可以看到自己的个人信息,并且允许进行修改操作
    保单信息模块:在本模块客户可以查看自己的保单信息,也可以提出取消保单申请,如果管理员批准取消成功,客户可以看到退回保费的情况
    理赔页面模块:在本模块客户可以进行理赔操作,包括选择报案时间,理赔项目,添加附件(可以上传照片),而且同时也可以看见已提交理赔的受理情况及回复的赔偿金额
    理赔范围介绍模块:在本模块客户可以查看现有的7个险种(交强险,第三者责任险,车损险,盗抢险,不计免赔险,玻璃险,座位险)的理赔范围

    3.2 总体方案3.2.1 技术架构
    车险管理系统拟使用面向对象开发方法,运用Java技术和MYSQL数据库制作。本系统使用MVC结构开发,可以大大缩短开发进程,这种架构在运行方面也很优秀,速度也比较快,主要包括View、Controller、Model层。
    View层提供了用户接口,使用CSS/JSP等技术制作,通过HTTP发送请求给Controller层,并得到POST的响应后,通过JSP方法或者Java标签显示到界面列表。
    Controller层处理前端发送来的请求,使用过滤器处理拦截信息,通过XML配置文件进行路由转发,寻找到对应的业务层的具体处理事件,完成业务逻辑。注入搭配AOP中,进行事务控制,根据权限信息完成操作,并记录操作日志。
    通过Controller层注入方法,提供数据流处理,通过Hibernate实现持久化对象操作,完成数据存储,再返回数据流到业务逻辑层。
    3.2.2 数据库设计本系统共设计了5个表,分别为用户表(t_admin),客户表(t_kehu),保单表(t_baodan),保单细节表(t_baodandetail),理赔表(t_lipei)。
    用户表(t_admin)
    用户表共有3个字段,userId,username,userPw,如表1所示:



    序号
    字段名称
    说明
    数据类型
    是否主键
    长度
    可否为空




    1
    userId
    用户ID号
    int

    11



    2
    username
    用户姓名
    varchar

    50



    3
    userPw
    用户密码
    varchar

    50




    客户表(t_kehu)
    客户表共有11个字段,kehu_id,kehu_name,kehu_sex,kehu_age,kehu_xueli,kehu_zhiwei,kehu_address,kehu_tel,kehu_email,kehu_login_Pw,type如表2所示:



    序号
    字段名称
    说明
    数据类型
    是否主键
    长度
    可否为空




    1
    kehu_id
    客户ID
    int

    11



    2
    kehu_name
    客户姓名
    varchar

    50



    3
    kehu_sex
    客户性别
    varchar

    50



    4
    kehu_age
    客户年龄
    int

    11



    5
    kehu_xueli
    客户学历
    varchar

    50



    6
    kehu_zhiwei
    客户职位
    varchar

    50



    7
    kehu_address
    客户地址
    varchar

    50



    8
    kehu_tel
    客户电话
    varchar

    50



    9
    kehu_email
    客户邮箱
    varchar

    50



    10
    kehu_login_Pw
    客户密码
    varchar

    50



    11
    type
    客户身份证
    varchar

    50




    保单表(t_baodan)
    用户表共有9个字段,id,kehuID,kehuName,baodanName,kaishishijian,jieshushijian,chepai,qicheppai,qichexinghao,如表3所示:



    序号
    字段名称
    说明
    数据类型
    是否主键
    长度
    可否为空




    1
    id
    保单ID(按客户)
    int

    11



    2
    kehuID
    客户ID
    varchar

    255



    3
    kehuName
    客户姓名
    varchar

    255



    4
    baodanName
    保单名称
    varchar

    255



    5
    kaishishijian
    开始时间
    varchar

    255



    6
    jieshushijian
    结束时间
    varchar

    255



    7
    chepai
    车牌号码
    varchar

    255



    8
    qicheppai
    汽车品牌
    varchar

    255



    9
    qichexinghao
    汽车型号
    varchar

    255




    保单细节表(t_baodandetail)
    保单细节表共有5个字段,id,baodanID,baodanName,leixing,je,如表4所示:



    序号
    字段名称
    说明
    数据类型
    是否主键
    长度
    可否为空




    1
    id
    保单ID(唯一)
    int

    11



    2
    baodanID
    保单ID(按客户)
    varchar

    255



    3
    baodanName
    保单名称
    varchar

    255



    4
    leixing
    险种
    varchar

    255



    5
    je
    金额
    double

    255




    理赔表(t_lipei)
    用户表共有8个字段,id,kehuname,shenfenzheng,riqi,xiangmu,fujian,lipeiqingkuang,jine,如表5所示:



    序号
    字段名称
    说明
    数据类型
    是否主键
    长度
    可否为空




    1
    id
    理赔ID
    int

    11



    2
    kehuname
    客户姓名
    varchar

    255



    3
    shenfenzheng
    身份证号码
    varchar

    255



    4
    riqi
    日期
    varchar

    255



    5
    xiangmu
    理赔项目
    varchar

    255



    6
    fujian
    附件
    varchar

    255



    7
    lipeiqingkuang
    理赔情况
    varchar

    2550



    8
    jine
    金额
    varchar

    255




    3.3 可行性分析3.3.1 技术可行性此系统拟采用B/S结构,与C/S结构相比更加简化,开发、维护等核心工作集中在服务器端执行。Java语言较其他语言更加稳定可靠,可以避免许多编程错误。
    3.3.2 经济可行性开发过程使用现有的开发环境,只需一台PC机就可完成开发。使用时在浏览器打开网址就可使用系统。
    3.3.3 社会可行性此系统作为课题研究使用,不涉及任何盈利行为,且所有过程不涉及任何知识产权问题。
    四.系统实现4.1 登录页面设计设置Tomcat服务器后,运行系统。车险管理系统需要先登录后才能进行操作。登录界面是系统运行后的第一个界面。输入用户信息后点击确定后进行登录,这里会进行密码的校验,若输入密码不正确会给出警告,直到输入正确的密码才能成功登入系统。
    程序运行效果图如图4所示

    输入正确的用户名和密码后,点击登录,页面跳转到管理主界面。在主界面中,可以进行一系列的操作。
    登录界面使用div和html进行布局,用户名和密码等输入项为表单,输入信息后,后台可以获取表单value值,通过获取的界面信息进行数据库查询操作。
    管理员登录中,通过点击button按钮,调用check1方法,通过IF判断用户名和密码是否输入,后调用loginService.login的方法,进行数据库查询,返回是或者否。
    4.2 管理员登录后的页面4.2.1 管理员登录后的首页系统通过登录验证后,页面跳转到主界面,界面有导航菜单,包括密码修改,客户管理,保单管理,保单取消,理赔管理,保单情况统计这六大模块,点击每个菜单可以进入相应的界面。
    程序运行效果图如图6所示

    车险管理系统的用户角色不同,对应的菜单也不相同。菜单由两个div组成,用户登录后,把用户角色保存到session服务器对象中,菜单页面通过读取权限信息,判断对应的登录用户显示哪个div,即可控制用户权限。
    主界面的框架由frameset组成,frameset有多个属性,可以设置frameset的边框,是否可以滚动以及name。在点击菜单链接后,通过设置target=’main’来控制对象显示到什么位置中。管理系统的后台一般都是有这种frameset控制,方便制定整体的界面风格,减少开发工作量。
    4.2.2 修改登录密码管理员成功登录系统之后,点击左侧菜单“修改登录密码”,系统跳转到修改登录密码子界面,在这里需要输入正确的原密码和设置新密码,才能实现修改操作,若输入的原密码不正确,会给出警告“输入的密码不正确”。
    程序运行效果图如图7所示

    4.2.3 客户信息管理在此页面添加客户信息,其中用户名,密码,姓名,性别,年龄,身份证号码为必填项,如果不填写就提交会进行校验,提示必须输入。其他学历,职位,住址,tel,email为选填项,不填写也可以提交。
    程序效果图如图8所示

    管理员点击左侧的菜单“客户管理”,页面跳转到客户管理界面,这里显示了所添加客户的个人信息。在右侧有删除和编辑按钮,可以删除该客户,也可以对客户信息进行修改。在下方有添加客户的button,可以添加新的客户,还有导出Excel的功能,可以将现有客户的个人信息导出至Excel表格中。
    程序效果图如下图9所示

    点击客户查询,可以通过输入客户姓名查询到客户的个人信息,在查询页面也可以对客户信息进行编辑,删除,添加以及导出Excel文件。
    程序效果图如下图10所示

    4.2.4 保单信息管理在此页面添加保单信息,包括填写或选择客户名称,车牌,汽车品牌,汽车型号,总金额,开始生效日期等,其中在开始生效日期默认为当前日期,旁边有写明,有效期为一年。
    程序效果图如图11所示

    管理员点击客户信息列表的“保单管理”,页面跳转到保单信息管理界面,这里展示了客户的姓名,身份证号以及保单车辆的信息。上方有一个查询功能,可以通过客户的身份证号码查询到保单信息,右边有修改和删除button,管理员可以修改和删除保单。用红字标出的是添加明细功能,在这里可以选择需要添加的险种以及具体险种的金额,当添加的险种的总金额大于保单总金额时会发生校验提示错误。
    程序效果图如下图12所示

    4.2.5 取消保单管理员在这里可以看到客户的部分信息,保单信息,和客户提出的取消保单申请,上方有一个查询功能,可以通过客户的身份证号码查询到保单信息,红色字体标出的查看明细可以查看到保单的具体信息。右方的取消保单button可以对客户提出的取消申请进行同意,之后保单状态会变为取消成功。
    程序效果图如下图13所示

    4.2.6 理赔管理管理员点击左侧的菜单“理赔管理”,页面跳转到理赔信息管理界面,管理员可以看到客户提出的理赔申请,包括客户的部分信息和车辆的理赔信息,上方有一个查询功能,可以通过客户的身份证号码查询到保单的理赔信息,红色字体的预览可以看到客户上传的事故照片,右边的事故理赔button可以对理赔进行处理,回复赔偿金额。
    程序效果图如下图14,15所示


    4.2.7 保单情况统计在这里可以显示保单的情况统计以及理赔的情况统计,可以看到每种车型的添加保单和理赔的数量,可以方便保险公司分析数据。
    程序效果图如图16所示

    4.3 客户登陆后的页面4.3.1 客户登录后的首页系统通过登录验证后,页面跳转到主界面,界面有导航菜单,包括我的资料,我的密码,我的保单,理赔管理,理赔范围介绍这五大模块,点击每个菜单可以进入相应的界面。
    程序运行效果图如图17所示

    4.3.2 我的资料修改首先客户输入自己的姓名及密码登录,在此可以修改个人信息并保存。
    程序效果图如下图18所示

    4.3.3 我的密码修改客户可以修改自己的登录密码,在这里需要输入正确的原密码和设置新密码,才能实现修改操作,若输入的密码不正确,会给出提示“密码不正确”。
    程序效果图如下图19所示

    4.3.4 我的保单情况客户在这里可以看到自己的部分个人资料及保单信息,右方红字的保单明细查看里客户可以看到保单的具体所加险种和金额。
    程序效果图如下图20所示

    客户在这里可以看到自己的保单信息,红色字的保单明细查看里客户可以看到保单的具体所加险种和金额,右方的取消保单button可以对保单提出取消申请。
    程序效果图如下图21所示

    客户提出取消保单的申请后,在这里可以看到自己的保单是否成功取消以及具体的退款情况,红色字的保单明细查看里客户可以看到保单具体所加的险种和金额。
    程序效果图如下图22所示

    4.3.5 理赔管理当发生事故,需要进行理赔申请时客户在这里可以上传事故的具体原因,发生日期,还可以上传事故图片,当管理员登录系统时能看见客户上传的事故图片。
    程序效果图如下图23所示

    客户在这里可以看到自己已经上传过的理赔申请,点击预览查看上传的事故图片,也可以修改或删除本条申请。
    程序效果图如下图24所示

    客户提出理赔申请后,在这里可以看到自己的保单是否成功受理理赔,若没有受理,理赔情况和理赔金额显示的是null,若成功受理则会显示管理员回复的具体理赔情况和金额,红色字的预览还可以查看上传的事故图片。
    程序效果图如下图25所示

    4.3.6 理赔范围介绍在这里客户可以看到保险公司提供的险种,包括交强险,第三者责任险,车损险,盗抢险,不计免赔险,玻璃险,座位险在内的7个险种,点击查看可以了解每项险种的具体理赔范围。
    五.系统测试进行车险管理系统的测试前,需要编写具体的测试用例,根据测试用例进行逐条测试,并记录测试结果,修正问题,完善功能。其中车险管理系统的部分测试用例如下。
    系统登录测试过程和预期结果,如表6所示:
    输入正确信息:用户名:1;密码:123456;选择角色:管理员输入错误信息:用户名:1;密码:111111;选择角色:管理员输入错误信息:用户名:2;密码:123456;选择角色:管理员输入错误信息:用户名:1;密码:123456;选择角色:客户输入错误信息:用户名:1;密码:123456;不选择角色点击登录,查询数据库,返回结果。
    打开数据库,查看返回的结果是否和数据库数据一致。
    预期结果:输入正确信息可以成功登录,输入错误信息提示无权限。
    测试结果:与预期结果一致,功能正确实现。
    添加客户测试过程和预期结果,如表7所示:

    点击客户录入页面链接,跳转到客户录入界面。使用多个浏览器进行操作
    不输入所有必填项,进行保存
    输入所有必填项,比对客户需求,查看是否都进行了相关验证
    保存信息到数据库中,查看数据库数据是否和录入的信息一致,包括默认值是否输入
    在客户信息列表中,读取到刚添加的客户信息

    预期结果:当不输入所有必填项时,给出warning提示必须输入此项;当输入所有必填项时可以成功添加客户,并保存到数据库,显示到客户列表。
    测试结果:和预期结果一致,功能正确实现。
    删除客户测试过程和预期结果,如表8所示:

    打开客户管理界面,通过查询所有客户信息,点击某条客户记录,进行删除操作
    提示是否确定删除后,点击确定,客户列表中,删除选择的记录
    查询数据库中客户数据,确认真实删除了该客户

    预期结果:可以成功删除客户,客户列表和数据库中均删除成功。
    测试结果:和预期结果一致,功能正确实现。
    编辑客户测试过程和预期结果,如表9所示:

    打开客户管理界面,通过查询所有客户信息,点击某条客户记录,进行修改操作
    跳转到客户编辑界面。使用多个浏览器进行测试,查看页面是否正确显示
    完成修改录入,点击提交数据
    保存信息到数据库中,查看数据库数据是否和修改的信息一致。列表是否更新

    预期结果:可以成功编辑客户,并保存到数据库,显示到客户列表。
    测试结果:和预期结果一致,功能正确实现。
    添加保单测试过程和预期结果,如表10所示:

    打开保单录入界面,填入所有保单信息,点击提交
    跳转到保单管理界面,有此保单信息
    保存信息到数据库中,查看数据库数据是否和添加的信息一致。列表是否更新

    预期结果:可以成功添加保单,并保存到数据库,显示到保单管理列表中。
    测试结果:和预期结果一致,功能正确实现。

    打开上传事故界面,填入所有事故发生日期,理赔项目,添加事故图片,点击提交
    跳转到事故列表界面,有此理赔申请信息
    保存信息到数据库中,查看数据库数据是否和添加的信息一致。列表是否更新

    预期结果:可以成功提出理赔申请,并保存到数据库,显示到事故列表中。
    测试结果:和预期结果一致,功能正确实现。
    六.总结与展望首先,我从专业实习中得到了本次系统设计的灵感,我实习的项目是越南GIC保险公司的车险项目,于是我将选课定为研究中国车险市场的系统设计。在完成系统设计的这段日子里,我查阅了许多Java开发,数据库方面的资料,以及车险项目有关的资料, 我学习到了很多Java开发技术以及数据库的实现方法。除此以外,我也了解了车险有关的知识。
    通过几个月的分析和研究,我的研究课题车险管理系统已经完成并且能够实现基本的功能,通过了实践测试。现在我的系统能够实现添加用户,添加/取消保单,理赔申请/受理,统计理赔情况等功能。不过由于毕业设计的时间有限,我一边进行学习,一边设计系统,我目前掌握的技术还不能使我的系统非常完美。从数据库来看,我的表设计还不够精简,还存在一定的冗余;从系统功能来看,一些功能还不够细致,还有进一步完善的空间。希望在未来的空余时间,我还能继续加工我的作品。
    通过毕业设计,我感受了系统开发的整个过程。毕业设计不仅是对我在大学所学知识的一个综合运用,对我实践能力进行的检测,也是一次增长知识和经验的好机会,同时也使我学会了许多处理、解决问题的方法,我也大大提高了自己的动手能力,使自己得到提升。我希望我在未来的学习和工作遇到困难的时候,都能保持不骄不躁的态度,学会冷静地解决问题。
    参考文献[1]徐雷明.车险智能审核系统的设计与实现[D].硕士学位论文.大连理工大学,2016.
    [2]詹薇.国内互联网车险发展研究[D].硕士学位论文.江西财经大学,2018.
    [3]李政宵,孟生旺.相依风险条件下的汽车保险定价模型[J].保险研究, 2016(7):68-77.
    [4]程阳.互联网车险UBI产品的设计[J].南方农机,2018(2):139-139.
    [5]魏丽,杨斐滟.我国商业车险改革评析[J].保险研究,2018,No.361(5):18-34.
    [6]夏超群.MyEclipse与数据库连接的实现[J].武汉工程职业技术学院学报,2013, 25(2):48-50.
    [7]佚名.“翻转课堂”本科教育实践——以《汽车保险与理赔》课程为例[J].教育教学论坛,2018(17):206-207.
    [8]陈文书.大数据视角下共享汽车保险定价机制研究——与UBI车险对比论证[J].中国商论,2018,No.758(19):14-15.
    [9]秦杨.加强和改善车险理赔服务问题探析[J].纳税,2018,No.198(18):192.
    [10]何宝晶.基于智能化理赔流程的车险理赔风控和反欺诈研究[D].硕士学位论文.兰州交通大学,2018.
    [11]李俊杰.华安财产保险运营信息管理系统设计与实现[D].硕士学位论文.大连理工大学,2016.
    [12]陈宏钊.车辆保险业务系统的设计与实现[D].硕士学位论文.东北大学,2015.
    [13]王东.机动车辆保险出单与决策系统的设计与实现[J].科技经济导刊,2017(2).
    [14]张钟浩,魏金海,彭章友.基于SSM的车辆保险系统设计和实现[J].工业控制计算机, 2017,30(5):141-142.
    [15]佚名.论我国学生平安保险的功能定位与法制完善[J].金融理论与实践,2019(1).
    [16]张晓甜.浅谈我国互联网保险[J].山东纺织经济,2018(4):25-27.
    [17]佚名.保险理赔的新科技应用与展望[J].纳税,2018, 12(27):203.
    [18]郗宏伟,汪爱丽.对汽车保险理赔中查勘定损的模式分析[J].中国市场,2018(6):129-130.
    [19]刘冬.车险理赔难与消费者权益保护研究[J].现代营销(下旬刊),2018(04):249-250.
    [20]薛煜睿.中国机动车车辆理赔风险管控对策探究[J].北方经贸,2018(4):100-101.
    0 评论 5 下载 2019-07-02 21:54:40 下载需要12点积分
  • 基于C语言的小型超市库存与销售管理系统

    1 需求分析1.1 登陆管理员和售货员可通过各自的账号、密码分别进入管理员和售货员的子系统。对于输入不在系统所存储的账号或输入的账号密码不匹配时,要求用户重新输入。
    1.2 用户管理管理员用户可浏览系统内所有的用户的账号、密码、权限类别,可添加用户,可删除用户。
    1.3 库存管理管理员可手动添加商品,也可从文件中批量导入商品,可查看库存内的全部商品信息,对于库存内商品数为0的商品可进行批量清理。
    1.4 查询商品管理员和售货员可通过商品名称、商品生产商、名称和生产商的方式查询商品信息。管理员可获取全部商品信息(商品ID、商品名称、进价、售价、生产厂商、余量),售货员可获取出进价以外的商品信息。查询可支持模糊查找、仅输入前缀。
    1.5 销售商品管理员和售货员可对库存内商品进行销售,对销售请求进行检查,销售后对库存相应商品的余量进行更新,同时记录销售的商品信息、销售时间,更新销售记录数据文件。
    1.6 销售统计管理员可浏览某天的或日期区间内的所有销售记录,可对指定日期区间内的销售记录进行综合统计,统计每种商品的销量、收入,统计总收入,可通过销量、销售额筛选统计结果。
    2 概要设计2.1 数据结构单个商品数据用Goods结构体存储,多个商品用链表存储。
    typedef struct { int id; char name[MAXGOODSNAME]; double buying_price; double selling_price; char manufacturer[MAXMANUFACTURERNAME]; int quantity;} Goods;typedef struct GoodsListNode *GoodsList;struct GoodsListNode{ Goods goods; GoodsList next;};
    单个销售数据用SoldGoodsRecord结构体存储,多个销售数据用链表存储。
    typedef struct{ int id; char name[MAXGOODSNAME]; double buying_price; double selling_price; int sold_quantity; SoldDate date;}SoldGoodsRecord;typedef struct RecordsListNode *RecordsList;struct RecordsListNode{ SoldGoodsRecord record; RecordsList next;};
    2.2 模块划分2.2.1 管理商品模块 manage_goods.c对商品进行操作的函数集。
    // 初始化商品链表GoodsList InitGoodsList();// 销毁商品链表void DeleteGoodsList(GoodsList head);// 向链表添加商品int AddGoodsToList(GoodsList head, Goods goods); // 遍历商品链表void TraverseGoodsList(GoodsList head, void(*Fun)(Goods *));// 显示商品信息void DisplayGoodsInfo(Goods *goods);// 显示商品基本信息void DisplayBasicGoodsInfo(Goods *goods);// 添加某商品数量:int IncreaseGoodsQuantity(GoodsList head, int id, int quantity);// 减少某商品数量:int ReduceGoodsQuantity(GoodsList head, int id, int quantity);// 从文件中导入商品void ImportGoodsFromFile(GoodsList head, FILE *fp);// 导出商品至文件void ExportGoodsToFile(GoodsList head, FILE *fp);// 清空数量为0商品void RemoveZeroQuantityGoods(GoodsList head);// 根据ID查找商品GoodsList FindGoodsByID(GoodsList head, int id);// 打开商品文件FILE* OpenGoodsFile(char *mod);
    2.2.2 管理销售记录模块 manage_records.c// 初始化销售记录链表RecordsList InitRecordsList();// 销毁销售记录链表void DeleteRecordsList(RecordsList head);// 遍历销售记录链表void TraverseRecordsList(RecordsList head, void(*Fun)(SoldGoodsRecord *));// 显示一条销售记录信息void DisplayARecordInfo(SoldGoodsRecord *record);// 向文件追加一条销售记录void AppendARecordToFile(SoldGoodsRecord record, FILE *fp);// 向链表条件一条销售记录void AddRecordToList(RecordsList head, SoldGoodsRecord record);// 从文件中导入销售记录数据至链表void ImportRecordsFromFile(RecordsList head, FILE *fp);// 获取当前销售时间SoldDate GetNowDate();// 打开销售记录文件FILE* OpenRecordsFile(char *mod);
    2.2.3 查询模块 query.c// 按名字在链表中查找商品GoodsList QueryGoodsByName(GoodsList head, char *name);// 按生产商在链表中查找商品GoodsList QueryGoodsByManufacturer(GoodsList head, char *manufacturer)// 按名字和生产商在链表中查找商品GoodsList QueryGoodsByNameAndManufacturer(GoodsList head, char *goods_name, char *manufacturer);// 按日期区间查找销售记录void QuerySoldRecordsByDate(RecordsList head, SoldDate start, SoldDate end);
    2.2.4 统计模块 statistics.c// 按日期区间对销售商品进行统计,通过销量、销售额筛选统计结果void SoldStatisticsByDate(RecordsList head, SoldDate start, SoldDate end, int min_sold_cnt, int min_earnings);
    2.2.5 售货员模块 salesman.c// 判断是否为销售员用户int IsSalesmanAccount(char *account, char *password);// 显示待售商品void DisplaySoldGoods(GoodsList head);// 销售商品void SoldGoods(GoodsList head);// 销售员初始化菜单void SalesmanInitMenu();// 查询商品菜单void SalesmanLookUpGoods(GoodsList head);// 按名称查询商品void SalesmanLookUpGoodsByName(GoodsList head);// 按生产商查询商品void SalesmanLookUpGoodsByManufacturer(GoodsList head);// 按名称和生产商查询商品void SalesmanLookUpGoodsByNameAndManufacturer(GoodsList head);
    2.2.6管理员模块 admin_user.c// 判断是否为管理员用户int IsAdminAccount(char *account, char *password);// 添加用户int AddAccount(UserAccount* user);// 删除用户int DeleteAccount(char *account);// 显示所有用户信息int DisplayAccountInfo();// 管理员初始菜单void AdminInitMenu();// 库存管理菜单void StockManagement();// 添加商品void AddGoodsToStock(GoodsList head);// 商品批量入库void BatchedStock(GoodsList head);// 查看库存商品void LookOverStock(GoodsList head);// 查询商品菜单void LookUpGoods(GoodsList head);// 按名称查询商品void LookUpGoodsByName(GoodsList head);// 按生产商查询商品void LookUpGoodsByManufacturer(GoodsList head);// 按名称和生产商查询商品void LookUpGoodsByNameAndManufacturer(GoodsList head);// 清理库存void ClearStock(GoodsList head);// 用户管理菜单void UserManagement();// 查看用户void LookOverUser();// 添加用户void AddUser();// 删除用户void DeleteUser();// 销售商品void SoldManagement();// 销售统计菜单void SoldStatistics();// 浏览单天销售记录void SingleDaySoldRecords(RecordsList head);// 浏览多天销售记录void DaysSoldRecords(RecordsList head);// 按日期区间浏览销售统计void DaysSoldStatistics(RecordsList head);
    2.2.7 外部Hash模块 uthash.c开源Hash模块,实现商品按id哈希处理,进行销售统计。
    2.3 程序总体框架
    3 详细设计部分重要底层函数:
    3.1 管理商品模块 manage_goods.c//初始化商品链表 创建带头结点的链表GoodsList InitGoodsList(){ GoodsList head = (GoodsList)malloc(sizeof(struct GoodsListNode)); head->next = NULL; return head;}//销毁链表void DeleteGoodsList(GoodsList head){ GoodsList next; while (head) { next = head->next; free(head); head = next; }}//在商品链表中添加一条商品信息,原有此商品数量合并,返回1//原没有,在链表末尾添加,返回0int AddGoodsToList(GoodsList head, Goods goods){ int id = goods.id; GoodsList p = head->next; while (p) { if (p->goods.id == id) { p->goods.quantity += goods.quantity; return 1; } p = p->next; } GoodsList newNode = (GoodsList)malloc(sizeof(struct GoodsListNode)); newNode->goods = goods; newNode->next = head->next; head->next = newNode; return 0;}//从文件中导入商品数据void ImportGoodsFromFile(GoodsList head, FILE *fp){ Goods goods; while (!feof(fp)) {fscanf(fp,"%d%s%lf%lf%s%d\n",&goods.id,goods.name,&goods.buying_price,&goods.selling_price,goods.manufacturer, &goods.quantity); AddGoodsToList(head, goods); } fclose(fp);}
    3.2 管理销售记录模块 manage_records.cconst char GOODS_SALES_RECORD_PATH[50] = "Data\\sold_goods_list.txt";//初始化销售记录裂变,创建带头结点的链表RecordsList InitRecordsList(){ RecordsList head = (RecordsList)malloc(sizeof(struct RecordsListNode)); head->next = NULL; return head;}//销毁销售记录链表void DeleteRecordsList(RecordsList head){ GoodsList next; while (head) { next = head->next; free(head); head = next; }}//在销售记录链表尾部增加一条销售记录信息void AddRecordToList(RecordsList head, SoldGoodsRecord record){ RecordsList newNode = (RecordsList)malloc(sizeof(struct RecordsListNode)); newNode->record = record; newNode->next = NULL; RecordsList p = head; while (p->next) p = p->next; p->next = newNode;}//向文件中新增加一条销售记录数据void AppendARecordToFile(SoldGoodsRecord record, FILE *fp){fprintf(fp, "%d %s %.2f %.2f %d %d-%d-%d-%d:%d:%d\n", record.id, record.name,record.buying_price,record.selling_price,record.sold_quantity,record.date.year,record.date.month,record.date.day,record.date.hour,record.date.min,record.date.second); fclose(fp);}//从文件中导出销售记录数据void ImportRecordsFromFile(RecordsList head, FILE *fp){ SoldGoodsRecord record; while (!feof(fp)) { fscanf(fp, "%d %s %lf %lf %d %d-%d-%d-%d:%d:%d\n", &record.id, record.name,&record.buying_price, &record.selling_price,&record.sold_quantity,&record.date.year, &record.date.month,&record.date.day,&record.date.hour, &record.date.min,&record.date.second); AddRecordToList(head, record); } fclose(fp);}
    3.3 查询模块 query.c//按照商品名和生产厂商前缀查询商品,输出商品基本信息GoodsList QueryGoodsByNameAndManufacturer(GoodsList head, char *goods_name, char *manufacturer){ if (head->next == NULL) return NULL; GoodsList queried_goods = InitGoodsList(); GoodsList p = head->next; while (p) { char goods_name_prefix[MAXGOODSNAME] = { 0 }; char manufacturer_prefix[MAXMANUFACTURERNAME] = { 0 }; strncpy(goods_name_prefix, p->goods.name, strlen(goods_name)); strncpy(manufacturer_prefix,p->goods.manufacturer, strlen(manufacturer)); if(strcmp(goods_name_prefix,goods_name) == 0 && strcmp(manufacturer_prefix, manufacturer) == 0) { GoodsList newNode = (GoodsList)malloc(sizeof(struct GoodsListNode)); newNode->goods = p->goods; newNode->next = queried_goods->next; queried_goods->next = newNode; } p = p->next; } return queried_goods;}
    3.4 统计模块 statistics.cvoid SoldStatisticsByDate(RecordsList head, SoldDate start, SoldDate end, int min_sold_cnt, int min_earnings){ CountStatistics *s, *goods = NULL; RecordsList p = head->next; while (p) { if (CompareDate(p->record.date, start) >= 0 && CompareDate(p->record.date, end) <= 0) { HASH_FIND_INT(goods, &p->record.id, s); if (s) { s->cnt += p->record.sold_quantity; s->earnings += (p->record.selling_price – p->record.buying_price) * p->record.sold_quantity; } else { s = (CountStatistics*)malloc(sizeof(CountStatistics)); s->id = p->record.id; strcpy(s->name, p->record.name); s->cnt = p->record.sold_quantity; s->earnings = (p->record.selling_price- p->record.buying_price) * p->record.sold_quantity; HASH_ADD_INT(goods, id, s); } } p = p->next; } double total_earnings = 0; int total_goods_cnt = 0; printf("----------------------------------------\n"); printf("%-5s %-12s %-6s %-6s\n", "ID", "名称", "销量", "收入"); for (s = goods; s != NULL; s = (CountStatistics*)(s->hh.next)) { if (s->cnt >= min_sold_cnt && s->earnings >= min_earnings) { total_earnings += s->earnings; total_goods_cnt++; printf("%-5d %-12s %-6d %-6.2f\n", s->id, s->name, s->cnt, s->earnings); } } printf("\n总商品数:%d 总收入:%.2f元\n", total_goods_cnt, total_earnings); printf("----------------------------------------\n");}
    3.5 售货员模块 salesman.c//购买商品,并更新商品,销售记录void SoldGoods(GoodsList head){ int id, cnt; GoodsList found_goods; while (1) { system("cls"); DisplaySoldGoods(head); printf("\n输入待销售的商品ID (输入-1退出)\n>"); scanf("%d", &id); if (id < 0) break; found_goods = FindGoodsByID(head, id); if (found_goods) { DisplayBasicGoodsInfo(&found_goods->goods); printf("输入销售数量\n>"); scanf("%d", &cnt); if (cnt <= 0) { printf("商品数量有误\n"); system("pause"); continue; } else { FILE *goods_fp = OpenGoodsFile("w"); FILE *records_fp = OpenRecordsFile("a"); if (goods_fp && records_fp) { if (!ReduceGoodsQuantity(head, id, cnt)) { printf("该商品库存不足\n"); system("pause");; continue; } ExportGoodsToFile(head, goods_fp); SoldGoodsRecord record; record.id = found_goods->goods.id; strcpy(record.name, found_goods->goods.name); record.selling_price = found_goods->goods.selling_price; record.sold_quantity = cnt; record.buying_price = found_goods->goods.buying_price; record.date = GetNowDate(); AppendARecordToFile(record, records_fp); printf("销售成功\n"); system("pause"); continue; } else { if (goods_fp) fclose(goods_fp); if (records_fp) fclose(records_fp); printf("连接系统数据失败\n"); system("pause"); break; } } } else { printf("无此商品\n"); system("pause"); continue; } }}
    3.6 管理员模块 admin_user.c//判断是否为管理员账户,无法打开文件返回-1,是返回1,否返回0int IsAdminAccount(char *account, char *password){ FILE *fp = fopen("Data\\user.dat", "rb"); if (fp == NULL) return -1; fseek(fp, 0, SEEK_END); int size = ftell(fp)/sizeof(UserAccount); fseek(fp, 0, SEEK_SET); UserAccount* user = (UserAccount*)malloc(size * sizeof(UserAccount)); for (int i = 0; i < size; i++) { fread(user + i, sizeof(UserAccount), 1, fp); if (strcmp(account, user[i].account) == 0 && strcmp(password, user[i].password) == 0 &&user[i].permission_level == 1) return 1; } free(user); fclose(fp); return 0;}//增加账户信息,无法打开返回-1,成功返回1,账户已存在返回0(更改密码)int AddAccount(UserAccount *newInfo){ FILE *fp = fopen("Data\\user.dat", "rb+"); if (fp == NULL) return -1; fseek(fp, 0, SEEK_END); int size = ftell(fp) / sizeof(UserAccount); fseek(fp, 0, SEEK_SET); int index = -1; UserAccount *user = (UserAccount*)malloc((size + 1) * sizeof(UserAccount)); for (int i = 0; i < size; i++) { fread(user + i, sizeof(UserAccount), 1, fp); if (strcmp(user[i].account, newInfo->account) == 0) { return 0; } } user[size] = *newInfo; fseek(fp, 0, SEEK_SET); for (int i = 0; i <= size; i++) { fwrite(user + i, sizeof(UserAccount), 1, fp); } free(user); fclose(fp); return 1;}
    4 调试分析
    问题1:链表操作易出错

    解决:为链表增加空的头结点,便于操作。销毁函数用于销毁链表,避免内存泄漏。对于同一级均要操作的链表的,在该级初始化链表,在返回上级时销毁
    问题2:需要读取多个文件

    解决:将文件读取封装为函数调用,对于售货功能,需要同时更新商品文件和销售记录文件,两个文件需要同时可打开时才可写入,采用类似原子操作思想
    问题3:交互逻辑使用不便。

    解决:改进交互逻辑,提供跳转功能、选择错误处理
    问题4:销售记录是分散记录,难于以商品为单位整合统计

    解决:采用开源的Hash库,通过Hash算法以商品id为key进行整合,算出该id商品的总销量和总收入
    问题5:指定日期区间查询或统计时不便

    解决:构造日期结构体,设置日期比较规则

    程序改进

    改进操作逻辑,使得操作更加方便
    增强大量数据时的处理能力
    采用数据库管理信息
    考虑多用户并发问题
    增加程序鲁棒性
    改进交互

    5 测试结果








    6 参考文献[1] 甘勇,李晔,卢冰.C语言程序设计[M].北京:中国铁道出版社,2014
    [2] 谭浩强. C程序设计[M]. 北京:高等教育出版社,2010
    [3] 苏小红,王宇颖,孙志岗. C语言程序设计[M]. 北京:高等教育出版社,2011
    [4] 王新,孙雷. c语言课程设计[M]. 北京:高等教育出版社,2009
    3 评论 86 下载 2018-11-04 14:56:40 下载需要5点积分
  • 基于C++的餐厅管理程序的设计与实现

    摘 要随着计算机应用技术的快速发展和日益普及,网络也遍及到我们生活的每个角落,为我们的学习和工作带来极大的方便。很多人都使用过传统的文字,纸张管理手段,与之不同的另外一种管理方式就是利用电脑程序管理餐厅。主要对追求工作高效、稳定、便捷的餐厅管理人员,电脑程序管理餐厅是一种很好的新型管理手段,它能提高工作效率和方便使用,餐厅管理程序就涉及到了文字、数字、项目信息的输入、读取、修改以及保存。
    本程序针对真实餐厅工作状况进行分析,讨论工作平台的环境影响,比较后采用在VS开发平台下,调用文件读写函数以实现Windows系统下信息的更新和保存。通过同类型软件测试比较可得:餐厅管理系统软件的设计具有先进性,可靠性。
    关键词:餐厅管理;文件读写;数据更新、保存
    第一章 设计内容设计一个模拟实现餐厅管理系统的程序,输入你需要的操作(选择相对的括号里的阿拉伯数字)程序具体功能有:

    查看菜单
    新增菜单
    删除菜单
    修改菜单(含名称及价格)
    查看座位剩余量
    修改座位剩余量
    查看预定情况
    新增预定(含菜式预定)
    查看顾客积分
    顾客兑换积分

    第二章 总体设计2.1 模块化设计为实现系统功能,本程序主要分为八个模块。它们分别为:查看菜单、新增菜单、删除菜单、修改菜单、查看座位剩余量、修改座位剩余量、查看预定情况、新增预定。这八个函数再通过主函数调用分别得以实现。
    主函数,首先提供了程序运行时的友好界面,提供客户选择的菜单。然后,通过执行多分支选择语句——switch语句,分别实现其它各个函数的调用功能。
    其它各个函数的功能分别如下:
    check() // 查看菜单函数add() // 新增菜单函数decrease() // 删除菜式函数change() // 修改菜式函数seat_check() // 查看座位剩余量函数seat_change() // 修改座位剩余量函数booking_check() // 查看预定情况函数booking_add() // 新增预定座位函数draw_check() // 查看顾客积分draw_check2() // 查看礼品列表 draw_main() // 兑换功能
    2.2 程序运行示意图
    第三章 详细设计3.1 数据结构设计本程序中,运用了多种数据结构。首先进入了主界面,查看菜单、新增菜单、删除菜单、修改菜单、查看座位剩余量、修改座位剩余量、查看预定情况、新增预定。在主函数中分别调用各项的函数。
    对于主要数据结构的举例如下:
    //定义菜单类class menu{private: //基本元素 int num,price;//菜式序号、价格 char name[20];//菜式名称 //用于功能实现的元素 int mealnum,delnum,changenum,changeprice;//菜式总数目、删除序号、修改序号、修改菜式序号 char changename[20];//修改菜式名字public: menu(); ~menu();//析构函数 void check();//查看菜单 void add();//新增菜单 void decrease();//删除菜单 void change();//修改菜单,包括修改菜式名称和菜式价格 void change_name();//修改菜式名称 void change_price();//修改菜式价格};//座位类class seat{private: //基本元素 int num,rest;//座位序号,座位剩余量 char size[20];//座位大小 //用于功能实现的元素 int seatnum,changenum,rerest;//座位种类数目,修改序号,剩余量public: seat(int); ~seat();//析构函数 void seat_check();//座位查看 void seat_change();//座位剩余量修改};//预定类class booking:public seat{private: //基本元素 int bnum,phone,peoplenum; char bname[20],bmeal[100]; //功能实现的元素 int bookingnum,cancelnum;//预约信息总数目、取消的序号public: booking(); ~booking();//析构函数 void booking_check();//预约查看功能 void booking_add();//新增预约};//主菜单void working(){ cout<<"======餐厅管理程序======"<<endl; cout<<endl<<"====菜式项目===="<<endl<<"1.查看菜式 "<<"2.新增菜式 "<<"3.删减菜式 "<<"4.修改菜式"<<endl; cout<<endl<<"====桌位项目===="<<endl<<"5.查看桌位 "<<"6.修改桌位剩余量 "<<endl; cout<<endl<<"====预定项目===="<<endl<<"7.查看预定 "<<"8.新增预定"<<endl; cout<<endl<<"====输入0退出系统===="<<endl;}//福利类class draw{private: char dname[20];//名称 int dnum,dphone,dpoint,total,dchange,duse;//序号,手机尾号,积分数目,记录表的总人数,兑换人号码,兑换礼品的序号public: draw(); ~draw(); void draw_check();//查看积分 void draw_check2();//查看奖品 void draw_main();//使用积分};void select(){ menu A; seat B; booking C; int chiose; while(1) { system("cls"); working(); cout<<endl<<"请输入你要实现的功能的序号:"; cin>>chiose; cout<<endl; switch(chiose) { case 0: exit(0); break; case 1: A.check(); break; case 2: A.add(); break; case 3: A.decrease(); break; case 4: A.change(); break; case 5: B.seat_check(); break; case 6: B.seat_change(); break; case 7: C.booking_check(); break; case 8: C.booking_add(); break; default: cout<<"输入无效请重新输入!"<<endl; cout<<endl; break; } getchar(); getchar(); }}
    3.2 程序模块设计本程序执行的入口是main函数,在main函数中首先调用了界面类中的各项操作的函数,在界面类中选择所需要进行的操作,在switch语句进行界面显示,实现对餐厅管理系统算法的操作。其中涉及到被调用的方法有:
    void working(){ cout<<"======餐厅管理程序======"<<endl; cout<<endl<<"====菜式项目===="<<endl<<"1.查看菜式 "<<"2.新增菜式 "<<"3.删减菜式 "<<"4.修改菜式"<<endl; cout<<endl<<"====桌位项目===="<<endl<<"5.查看桌位 "<<"6.修改桌位剩余量 "<<endl; cout<<endl<<"====预定项目===="<<endl<<"7.查看预定 "<<"8.新增预定"<<endl; cout<<endl<<"====输入0退出系统===="<<endl;}void select(){ menu A; seat B; booking C; int chiose; while(1) { system("cls"); working(); cout<<endl<<"请输入你要实现的功能的序号:"; cin>>chiose; cout<<endl; switch(chiose) { case 0: exit(0); break; case 1: A.check(); break; case 2: A.add(); break; case 3: A.decrease(); break; case 4: A.change(); break; case 5: B.seat_check(); break; case 6: B.seat_change(); break; case 7: C.booking_check(); break; case 8: C.booking_add(); break; default: cout<<"输入无效请重新输入!"<<endl; cout<<endl; break; } getchar(); getchar(); }}void main(){ select(); system("pause");}
    3.3 流程图查看菜单

    新增菜单

    删除菜单

    修改菜单(价格和名称)

    查看座位剩余量

    修改座位剩余量

    查看预定信息

    新增预定

    查看积分

    福利兑换

    第四章 调试与测试4.1 调试过程中的主要问题本程序,即餐厅关系系统程序,是涉及到了有关文件的读取、修改、清除、关闭等多个不同方面的操作,其中对文本文件的读取并输出到屏幕、修改最为棘手,同时这也是本程序的核心,关键内容。在开始的时候,我并无头绪,后来在网络上参考了网友的问题和解决方案后,找到了解决问题的思路,即打开文件-保存内容到数组中-清除文件内容-关闭文件-按需求修改数组内容-打开文件(已为空)-数组内容写入文件-关闭文件。使用这思路,简单明了,易于理解,便于操作,思路清晰,解决问题的相关代码也随之而出,复杂的核心问题得到解决,其他内容也就迎刃而解。
    4.2 具体测试过程主界面

    显示菜单

    新增菜单


    删除菜单


    修改菜单(价格)


    修改菜单(价格)


    查看座位剩余量

    修改座位剩余量


    查看预定情况

    新增预定

    查看积分

    兑换功能


    参考文献[1] 陈维兴 林小茶,C++面向对象程序设计教程(第3版)。北京:清华大学出版社,2009年5月
    [2] 严蔚敏 吴伟民,数据结构(C语言版)。北京:清华大学出版社,2011年5月
    [3] Thomas H.Cormen Charles E.leiserson Ronald L.Rivest Clifford Stein, 算法导论。机械工业出版社,2010年11月
    [4] 王晓东,计算机算法设计与分析(第4版)北京:电子工业出版社,2012年2月
    2 评论 26 下载 2018-11-05 09:11:35 下载需要5点积分
  • 基于C语言实现的超市管理系统

    1 需求分析超市随着市场经济和现代信息技术的的发展,不可必要的要卷入信息现代化的大潮,如何使用现代化的工具,使企业和经营者个人在最小的投入下获取最大的回报,成为每一个人的梦想。因此,在超市管理中引进现代化的办公软件,就成为时下最好的解决办法。使用软件办公,不仅能使经营者的劳力资本减少,同时能使超市的管理更规范更合理,解决了超市中用于管理进出货以及购买、库存等众多繁琐、工作量巨大从而导致耗费人员过多,超市经营紊乱等众多问题。
    1.1 主要功能
    超级管理员模块:(需帐号登录)

    添加管理员删除管理员
    管理员模块:(需帐号登录)

    商品信息录入(编号、名称、单价、库存)商品信息修改(修改商品的各种信息)商品信息查询(根据所输入的商品名字,编码查询库存信息)商品信息删除(从商品文件中删除商品信息)商品信息排序(按编号,单价,库存3种模式进行排序)输出商品全部库存信息删除普通用户功能(管理员有权限删除普通用户帐号)
    普通用户模块:(需帐号登录)

    新用户注册用户登录:
    商品查询商品排序输出商品全部库存信息购买商品(通过用户余额来进行购买)充值(通过输入充值卡卡号对用户余额充值)修改用户密码


    1.2 运行环境
    操作系统:Windows NT/2000/XP/VISTA/WIN7/WIN8/WIN10
    开发平台:Microsoft Visual Studio 2012

    1.3 文件说明
    程序源代码(超市管理系统.cpp)
    程序运行文件(超市管理系统.exe)
    管理员信息(管理员信息.txt)
    普通用户信息(普通用户信息.txt)
    商品信息(商品信息.txt)

    2 总体方案设计2.1 设计方案整个超市管理系统分为3个模块,超级管理员+管理员+普通用户,其中:

    管理员可以实现商品信息的录入,修改,查询等管理操作,同时还拥有对普通用户帐号的管理
    超级管理员是最高执行者,拥有对管理员帐号的操作权限,可以对管理员帐号进行添加或删除
    普通用户模块,由于考虑到该程序的真实性,所以实现了普通用户的注册和登录功能,用户要进行购物,必须使用帐号(可自行注册,无须经过管理员),其中普通用户具有商品查询等一部分功能。特色功能是具有帐号余额功能,同时购物可以进行充值功能(输入充值卡卡号,类似于购买充值卡来充值)

    2.2 主要结构
    超级管理员模块:(需帐号登录)

    添加管理员删除管理员
    管理员模块:(需帐号登录)

    商品信息录入(编号、名称、单价、库存)商品信息修改(修改商品的各种信息)商品信息查询(根据所输入的商品名字,编码查询库存信息)商品信息删除(从商品文件中删除商品信息)商品信息排序(按编号,单价,库存3种模式进行排序)输出商品全部库存信息删除普通用户功能(管理员有权限删除普通用户帐号)
    普通用户模块:(需帐号登录)

    新用户注册用户登录:
    商品查询商品排序输出商品全部库存信息购买商品(通过用户余额来进行购买)充值(通过输入充值卡卡号对用户余额充值)修改用户密码


    2.3 程序功能和流程图由于本程序模块功能较多,有超级管理员,管理员和普通用户,共3个模式的功能,流程图较大,因此分为3个子图。
    超级管理员模块

    管理员模块

    普通用户模块

    2.4 数据结构和算法的设计说明本程序有3个数据结构:管理员,普通用户,商品共3个结构体。其中程序拥有超级管理员、管理员和普通用户共3种身份,运用链表来存储和读取所保存的信息。
    2.4.1 结构体类型一开始选择模块,输入帐号和密码,进行验证,是否正确。正确就进入功能模块。
    typedef struct custom* cpointer;//结点指针类型struct custom{ string custom_ID;//帐号 string custom_name;//姓名 string custom_mima;//密码 double money;//账户余额 cpointer next;};typedef cpointer clklist;//单链表类型,即头指针类型
    其中,管理员、普通用户、商品都是定义结构体,而后进入系统,一开始便定义相对应的链表进行存储和获取已保存的信息。
    2.4.2 算法设计排序算法
    for(int i=0;i<Goodnum;i++){ for(int j=Goodnum;j>=i+1;j--){ if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID) {//比较编号大小,小的在前面,大的在后面 flag=1; p=Go.Good[j]; Go.Good[j]=Go.Good[j-1]; Go.Good[j-1]=p; } }
    通过对相邻2个商品的编号不断比较,排序,运用2个for循环,比较编号大小,小的在前面,大的在后面。不断变换,最终排序完成。
    2.5 程序关键源代码说明程序中拥有3个身份:超级管理员,管理员,普通用户。不同身份之间函数都差不多,因此将函数直接展示,不说明为哪个身份的权限功能。
    custom_ender函数:登录验证函数。对输入的帐号和密码进行验证检索,正确就进入对应的身份模块。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后对p进行检索,如果p链表中的用户信息与输入的用户信息(帐号+密码)相同,就返回1;不同就显示“用户帐号不存在”,同时返回0。
    int custom_ender(clklist &head,string ID,string mima){ cpointer p; p=head; while(p!=NULL) { if(p->custom_ID==ID&&p->custom_mima==mima) return 1; else p=p->next; } cout<<"用户帐号不存在!"<<endl; return 0;}
    custom_creat函数:注册函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p,而后输入注册用户的各种信息(帐号,密码,姓名),如果输入的帐号ID与已保存的用户帐号相同,就显示已存在,提示重新输入。最后将输入的新注册用户信息运用头插法插入,保存到”普通用户信息.txt”文件中保存
    void custom_creat(clklist &head){ cpointer s,p; string ID,name,mima; int sign=1,flat=1; while(sign!=0){ flat=1; cout<<"请输入用户帐号"<<endl; cin>>ID; p=head->next; while(p!=NULL){ if(p->custom_ID==ID) flat=0; p=p->next; } if(flat==0) { cout<<"用户帐号已存在,请重新输入"<<endl; continue; } cout<<"请输入用户密码"<<endl; cin>>mima; cout<<"请输入用户姓名"<<endl; cin>>name; s=new custom; s->custom_ID=ID; s->custom_name=name; s->custom_mima=mima; s->money=0; s->next=head->next;//使用头插法建表 head->next=s; buyernum++;//输入一个用户信息,buyernum自加1 custom_save(head); cout<<"是否继续注册?<继续>请按1 <结束>请按0"<<endl; cin>>sign;//while循环判断条件,所以不需要用if }}
    custom_get函数:从文件获取用户信息函数。先定义一个普通用户结构体类型cpointer对象p,把包含普通用户全部信息的单链表head赋值给p, 而后运用一个for循环,将用户信息从“普通用户信息.txt“全部导入到p链表中,返回给系统。
    clklist custom_get(clklist &buyer){ cpointer s,p;//s用于存储用户信息,p用于buyer的连接 string numname; string ID,name,mima; double money; buyer->next=NULL; p=buyer; ifstream ifile("C:\\普通用户信息.txt",ios::in); if(!ifile){ cerr<<"用户信息查询出错"<<endl;return 0; } ifile>>numname; ifile>>buyernum;//从文件中提取用户个数,用于for循环 for(int i=1;i<=buyernum;i++){ ifile>>ID; ifile>>name; ifile>>mima; ifile>>money; s=new custom; s->custom_ID=ID; s->custom_name=name; s->custom_mima=mima; s->money=money; s->next=p->next; p->next=s; } buyer=p; ifile.close(); return buyer;}
    Good_add函数:商品信息录入函数。把包含商品信息的链表Goods传入该函数,输入商品编号,if(Good_ender1(Goods,ID)==0)进行检索是否商品已存在,存在就提示重新输入,不存在就继续录入商品信息,导入到Goods链表中,最后运用Good_save(Goods)保存全部信息到“商品信息.txt”文件中。
    void Good_add(sqlist &Goods){ string ID,name; double piece; int last,sign,flat=1;//last为商品库存,sign用于判断选择 fstream ifile("C:\\商品信息.txt",ios::in); for(;flat!=0;) { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==0) { cout<<"请输入商品名称:"; cin>>name; if(Good_ender2(Goods,name)==0) { cout<<"请输入商品单价:"; cin>>piece; cout<<"请输入商品数量:"; cin>>last; Goods.Good[Goodnum].Good_ID=ID; Goods.Good[Goodnum].Good_name=name; Goods.Good[Goodnum].piece=piece; Goods.Good[Goodnum].last=last; Goodnum++;//添加完信息就自加1 Good_save(Goods);//添加完就保存至商品信息.txt cout<<"是否继续录入?<继续>请按1 <结束>请按0"<<endl; cin>>sign; if(sign==0) break; } else {cout<<"商品名称已存在!<重新输入>请按1 <结束>请按0"<<endl; cin>>flat;} } else {cout<<"商品编号已存在!<重新输入>请按1 <结束>请按0"<<endl; cin>>flat;} }}
    Good_change函数:商品信息修改函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种修改模式(按编号检索修改,还是按名称检索修改)。如果选择按编号检索修改,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输入修改后的商品信息,保存至文件中;按名称检索修改类似。最后修改完后,会提示是否继续修改,如果不继续就返回用户功能界面,执行其他功能。
    void Good_change(sqlist &Goods){ string ID,name; int sign;//sign用于定位要修改商品的位置 int a,flat=1;//a用于switch for(;flat!=0;){ cout<<"<输入要修改的商品编号>请按1 <输入要修改的商品名称>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl; cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl; cout<<"商品单价:"<<Goods.Good[sign].piece<<endl; cout<<"商品库存:"<<Goods.Good[sign].last<<endl; cout<<"请输入修改后的信息:"<<endl; cout<<"商品编号:"; cin>>Goods.Good[sign].Good_ID; cout<<"商品名称:"; cin>>Goods.Good[sign].Good_name; cout<<"商品单价:"; cin>>Goods.Good[sign].piece; cout<<"商品库存:"; cin>>Goods.Good[sign].last; Good_save(Goods);//保存信息 cout<<"修改成功"<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"<继续修改>请按1 <退出>请按0"<<endl; cin>>flat; }//for循环的}
    Good_inquire函数:商品信息查询函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种查询方式(按编号检索查询,还是按名称检索查询)。如果选择按编号检索查询,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后输出该商品信息的全部信息;按名称检索查询类似。最后查询完后,会提示是否继续查询,如果不继续就返回用户功能界面,执行其他功能。
    void Good_inquire(sqlist &Goods){ string ID,name; int a,sign,flat=1; for(;flat!=0;){ cout<<"<按商品编号查询>请按1 <按商品名称查询>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"商品编号:"<<Goods.Good[sign].Good_ID<<endl; cout<<"商品名称:"<<Goods.Good[sign].Good_name<<endl; cout<<"商品单价:"<<Goods.Good[sign].piece<<endl; cout<<"商品库存:"<<Goods.Good[sign].last<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"是否继续查询?<继续>请按1 <结束>请按0"<<endl; cin>>flat; if(flat==0) break; }//for循环的}
    Good_delete函数:商品信息删除函数。把包含商品信息的链表Goods传入该函数,考虑到用户可能只记得商品编号或者商品名称,因此编写了2种删除方式(按编号检索删除,还是按名称检索删除)。如果选择按编号检索删除,同样对编号进行检索,如果在Goods链表中找到该商品编号,就运用 sign=Good_locate1(Goods,ID);定位记录下该商品在文件中的位置,而后使用for(int i=sign; i\<Goodnum; i++)将该位置后的商品全部前移1位,覆盖掉该位置,最后保存删除后的商品信息至“商品信息.txt”中;按名称检索删除类似。最后删除完后,会提示是否继续删除,如果不继续就返回用户功能界面,执行其他功能。
    void Good_delete(sqlist &Goods){ int a,sign,flat=1; string ID,name; for(;flat!=0;){ cout<<"<输入要删除的商品编号>请按1 <输入要删除的商品名称>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { cout<<"请输入要删除的商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1){ sign=Good_locate1(Goods,ID); for(int i=sign;i<Goodnum;i++){ Goods.Good[i]=Goods.Good[i+1]; } Goodnum--; Good_save(Goods); cout<<"删除成功!"<<endl; } else cout<<"商品不存在!"<<endl; break; } case 2: 大致与编号模式相同 else cout<<"商品不存在!"<<endl; break; } }//switch的 cout<<"是否继续删除?<继续>请按1 <结束>请按0"<<endl; cin>>sign; if(sign==0) break; }//for循环的}
    Good_range函数:商品信息排序函数。把包含商品信息的链表Go传入该函数,选择排序模式(按编号,单价,库存进行排序),运用2层for循环,使用冒泡法进行排序,从尾部向头部进行对比检索,小的放前面,大的放后面,排序完之后就将排序后的商品信息显示给用户;3种模式大致相同。最后排序完后,会提示是否继续执行,如果不继续就返回用户功能界面,执行其他功能。
    void Good_range(sqlist Go){ Goods p; p.piece=0; p.last=0; int a,flag=0,flat=1; for(;flat!=0;){ cout<<"<按商品编号排序>请按1 <按商品单价排序>请按2 <按库存数量排序>请按3 <退出>请按0"<<endl; cin>>a; if(a!=0&&a!=1&&a!=2&&a!=3) {cout<<"选择有误,请重新输入"<<endl;continue;} switch(a){ case 1: { for(int i=0;i<Goodnum;i++){ for(int j=Goodnum;j>=i+1;j--){ if(Go.Good[j].Good_ID<Go.Good[j-1].Good_ID){//比较编号大小,小的在前面,大的在后面 flag=1; p=Go.Good[j]; Go.Good[j]=Go.Good[j-1]; Go.Good[j-1]=p; } }//jfor的 if(!flag) break; }//ifor的 cout<<"商品编号"<<setw(10)<<"商品名称"<<setw(10)<<"商品单价"<<setw(10)<<"商品库存"<<endl; for(int i=1;i<=Goodnum;i++){ cout<<Go.Good[i].Good_ID<<setw(13)<<Go.Good[i].Good_name<<setw(8)<<Go.Good[i].piece<<setw(10)<<Go.Good[i].last<<endl; } break; } case 2: 大致与编号模式相同 case 3: 大致与编号模式相同 case 0:return; }//switch的 }//最外层for的
    Good_buy函数:购买商品函数。把包含商品信息的链表Goods以及包含用户信息的链表head传入该函数,选择购买模式(输入编号或名称进行购买),如果输入的商品编号与Goods中的商品信息相同,就提示购买数量,这时如果购买数量超过库存数量会提示“库存不足”,然后重新输入;如果购买商品所支付的钱超过用户的余额,则提示“余额不足”,是否前往充值页面进行充值。充值模块下面会展示。购买完商品后,用户可以继续购买,也可以返回用户功能界面。
    void Good_buy(sqlist &Goods,clklist &head,string cID){//cID为用户帐号 string ID,name; int a,shu,sign,flat=1; cpointer p; p=custom_locate(head,cID); for(;flat!=0;){ cout<<"<输入商品编号购买>请按1 <输入商品名称购买>请按2"<<endl; cin>>a; if(a!=1&&a!=2) {cout<<"输入有误,请重新输入"<<endl;continue;} switch (a) { case 1: { cout<<"请输入商品编号:"; cin>>ID; if(Good_ender1(Goods,ID)==1) { sign=Good_locate1(Goods,ID); cout<<"请输入购买数量:"; cin>>shu; if(shu<=Goods.Good[sign].last){ if(p->money<Goods.Good[sign].piece*shu) {cout<<"余额不足,请充值!"<<endl; cout<<"是否前往充值?<充值>请按1 <否>请按0"<<endl; cin>>flat; if(flat==0) break; if(flat==1) return;} Goods.Good[sign].last=Goods.Good[sign].last-shu; cout<<"购买成功"<<endl; p->money=p->money-Goods.Good[sign].piece*shu;//账户余额减少,扣费成功 custom_save(head); cout<<"账户余额:"<<p->money<<endl; Good_save(Goods); } else cout<<"库存不足!"<<endl; } else cout<<"找不到相应商品,购买失败"<<endl; break; } case 2:与编号模式类似 }//switch的 cout<<"是否继续购物?<继续>请按1 <结束>请按0"<<endl; cin>>flat; if(flat==0) break; }//for的}
    custom_addmoney函数:余额充值函数。余额是用户帐号中的一个成员,初始为0,用户在购物的时候余额会减少,如果余额不足就无法进行购物,需要进行充值,充值是输入系统给定的充值卡卡号进行充值,这是本系统的一大亮点。把包含用户信息的链表head传入该函数,运用 p=custom_locate(head,ID);定位是哪个用户的帐号要进行充值,其中,系统设定了2种充值卡“asd500”和“asd1000”分别可以充值500和1000元,这类似与用户购买不同的充值卡给自己的账户进行充值。用户输入充值卡卡号,进行检索是否与系统设定的充值卡卡号相同,如果相同就充值相应的金额;如果不同,就提示“充值卡无效”。最后充值后,用户可以选择继续充值或者返回用户功能界面进行购物等其他操作。
    void custom_addmoney(clklist &head,string ID){ cpointer p; int sign=1; p=custom_locate(head,ID); string acard,card1="asd500",card2="asd1000"; while(sign!=0){ cout<<"请输入您获得的充值卡卡号:"; cin>>acard;//acard是用户获得的充值卡 if(acard!=card1&&acard!=card2) cout<<"充值卡无效"<<endl; if(acard==card1) { p->money+=500; cout<<"充值成功!"<<endl; cout<<"账户余额:"<<p->money<<endl; }; if(acard==card2) { p->money+=1000; cout<<"充值成功!"<<endl; cout<<"账户余额:"<<p->money<<endl; }; custom_save(head);//充值成功 cout<<"是否继续充值?<继续>请按1 <结束>请按0"<<endl; cin>>sign;//while循环判断条件,所以不需要用if }
    3 程序功能测试一开始进入系统,初次使用会提示文件打开失败,是正常的,不影响功能。由于原本的“管理员信息.txt”“普通用户信息.txt”“商品信息.txt”是空的,当录入信息就不会有提示了。进入身份选择(都要帐号和密码)

    选择1进入超级管理员,(帐号:asd,密码123),先添加管理员。

    选择1,添加管理员信息(帐号+密码+姓名),添加完后可以选择继续添加或返回

    选择2,输入要删除的管理员帐号,直接删除管理员

    添加完管理员后,可返回主菜单,进入管理员模式,输入刚刚添加的管理员帐号+密码,进入管理员模式

    功能1,进入商品录入功能,输入商品的信息(编号,名称,单价,库存),当录入成功之后,管理员可以选择继续录入或返回(该模块当录入编号和名称和已录入的信息相同会提示出错,重新录入)

    功能2,可进行商品修改,有2种模式进行选择,输入商品编号101后,显示“商品信息.txt“文件中的商品信息,而后管理员可以输入修改后的信息

    功能3,可以进行商品信息查询,可以查询到刚刚修改的联想笔记本

    功能4,可以进行删除已录入的商品信息,例如,删除刚录入的联想笔记本

    删除后,进入查询功能查看联想笔记本,不存在,表明删除成功~ ~

    功能5,进行已录入商品信息排序,可选择(编号,单价,库存)进行从小到大排序,编号也是可以的

    功能6,输出全部商品信息

    功能7,删除普通用户,如果已经有普通用户,只需要输入普通用户的帐号就可以直接删除
    进入普通用户模块,如果没有帐号是无法查看和购物的,因此消费者可以自行注册

    注册完,就可以登录进入用户模块进行购物了

    其中,商品查询,排序,库存是和管理员一样的,就不展示了
    功能4,购买商品,一开始,由于没充值时,用户余额为0,余额不足,无法购买,用户可以返回,进行充值后购买。如果充值后,余额充足就可以购买了,购买后,余额相应减少

    这里我先前往充值2000元,后购买如下,主机单价50,购买后余额为1950,扣费成功

    功能5,用户可以随时修改自己的账户密码,保护自己的财产
    功能6,就是充值了,输入系统给定的充值卡卡号,有(asd500和asd1000)

    由于刚余额1950,现在输入卡号asd1000,成功充值1000,剩余2950
    4 总结这次选择了做“超市管理系统”,在完成基本功能之后,觉得要真正实现成功的超市管理系统,必须要有个人的帐号,因此增加了普通用户注册和帐号模式,同时管理员和超级管理员也都是用帐号+密码进入。普通用户可以自行注册,拥有自己的私人帐号。同时,超市管理系统普通用户在进行购买之后,应该是要有余额的,因此添加了余额成员。拥有余额成员之后,就想到,用户需要购买东西,余额不足就需要进行充值,为了实现真实性,就选定,用户需要输入充值卡卡号进行充值。最终完美实现。
    这个系统,是使用链表实现的,由于之前的大作业是使用文件流,不是使用链表,因此这次的大作业就决定说要使用链表来实现。在编程过程中,也发现了很多的bug,最终还是一一解决。感觉自己的编程能力在不断的提高,无论是什么bug都可以自行调试解决。
    同时,在思考程序的框架功能时,也逐渐重视用户体验,人机交互。编写大作业,不再只是仅仅满足基本功能,在基本功能上,还添加其余用户体验好的功能(比如帐号登录,充值等等功能),感觉大作业让我学会了很多。
    3 评论 74 下载 2018-10-31 11:28:48 下载需要12点积分
  • 基于Nuxt2实现的个人博客系统

    摘 要当下流行的博客系统大多为开源的,用户可以根据自己的喜好配置不同风格的个人博客,但配置复杂度高,时间消耗量大。随着扁平化设计风格和前端UI框架的快速发展,打造轻量级、简约、扁平化风格同时突出核心功能的博客系统成为一大趋势。
    本文重点研究了前后端数据交互技术,用Vue框架搭建前端页面、Node.js写后端服务,Nuxt连接前端Vue和后端Node.js搭建脚手架。针对用户发表文章,不同用户用GitHub授权登录进行评论这一特定场景提出了一些具有创新性的技术方法—使用OAuth协议实现第三方授权。为程序员这类主要用户群体搭建出配置简单、内置支持Markdown语法编辑器、用户之间可进行信息交互出的扁平化个人博客系统,该系统取得了良好的运行效果。
    关键词:博客;扁平化;OAuth协议;Vue框架;Node.js
    AbstractMost popular blog systems are open source, users can configure different styles of personal blogs according to their own preferences, but the configuration complexity, time consumption is large. With the rapid development of flat design styles and front-end UI frameworks, blogging systems that create lightweight, minimalist, flat styles while highlighting core functionality have become a major trend.
    This paper focuses on the front-end data interaction technology, using Vue framework to build front-end pages, Node.js write back-end services, Nuxt connection front-end Vue and back-end Node.js to build scaffolding. In the specific scenario of posting articles for users and different users using GitHub to log in for comments, some innovative technical methods have been proposed—using the OAuth protocol to implement third-party authorization. A flat personal blog system with simple configuration, built-in support for the Markdown grammar editor, and information exchange between users has been built for a major user group such as a programmer. The system has achieved good operational results.
    Keywords: blog; flattening; OAuth protocol; Vue framework; Nod
    一、绪论1.1 课题研究背景与意义随着计算机和互联网的快速发展,传统的书信交流和现代的媒体社交方式有巨大的区别,进入信息化时代以来,涌现了很多优秀的社交网站,人们的工作、学习和交友方式发生了翻天覆地的变化。博客是一个新型的个人互联网出版工具,博客使用者可以很方便的用文字、链接、影音、图片建立起个性化的网络世界。博客秉承了个人网站的自由精神,但是综合了激发创造的新模式,使其更具开放和建设性。伴随着我国市场经济的高度发展,用户越来越依赖于大型网站提供的博客系统,如新浪博客、微博、CSDN博客等。虽然这种大型的博客系统有着设计下良好、稳定性高、知名度高等特点,但是它们不符合互联网推崇个性化发展的理念。现在越来越多的人希望有自己的站点,通过搭建真正属于自己的个人博客,提升自己的价值、更好的展现自己。
    本文的研究意义旨在如何设计出前端UI扁平化、结构清晰、核心功能齐全、技术先进的博客系统。
    1.2 国内外研究现状扁平化风格博客系统包括扁平化的设计以及博客系统的搭建,接下来将介绍扁平化设计风格和博客系统的研究现状,并介绍相应的技术进展。
    1.2.1 扁平化设计风格的研究现状在互联网快速发展和设计风格多样化的现代,扁平化设计作为一种新型的设计理念,受到越来越多人的青睐,因此扁平化设计理念越来越流行,应用范围也越来越广,从早期盛行的拟物化到现代极简主义的扁平化,这一发展历程见证了设计风格的转变以及发展趋势。扁平化设计最初是作为拟物化设计的对立面出现的。拟物化是一种对现实世界的物体或过程进行再现的风格,这种大量使用投影、真实感纹理、反射、斜面和浮雕效果。而扁平化设计不是三维的,它的名称来源于二维的特征,扁平化设计不包含任何能够带来厚度和立体感的细节特征,比如阴影、高亮或是纹理。
    当今社会信息极度爆炸,用户经常会陷入各种数据的包围中,在无限的信息中选取自己需要的内容需要消耗用户的时间和精力,扁平化的设计可以减少无用的视觉负载,优化用户对产品的使用体验感。2014年,谷歌在其I/O发布会上提出了Material Design,其设计规范覆盖了布局,控件,动画效果等多个层面,给多个平台的开发者提供了优秀的设计参考。Material Design最大的创新点是加入了卡片式设计,提升了视觉层次的清晰度,并且引入了Z轴的概念,使得各个层次的布局更加清晰。2017年微软提出了新的设计规范——Fluent Design System,改规范包含了五大核心元素,包括Light(光感)、Depth(深度)、Motion(动画)、Material(材质)和 Scale(缩放),这些元素旨在为安装Windows系统的设备提供整合交互模式、空间和全新元素的设计范式的设计语言,提升用户的使用体验。
    Material Design的加入使得安卓系统的美观度提升了一个档次,Fluent Design System的提出改善了用户对于Windows系统UI系统设计一成不变的刻板印象。
    1.2.2 国内外博客系统的发展现状随着计算机科学技术和互联网的不断发展,国内外涌现了很多优秀的博客平台,这些博客平台也多种多样,网站变得越来越简单,越来越轻量级。一般来说,用户可以借助博客平台发布博文,或者借助博客搭建工具自行搭建并发布博客。国内外比较出名的博客平台有:

    简书。简书是国内一个比较具有代表性的创作社区,任何人均可以在其上进行创作。简书提供方便易用的iOS、安卓app和网页端版本,简单优雅的设计给用户带来愉快体验感的同时还支持Markdown,使得分享交流更加方便快捷
    emlog。emlog是every memory log的简称,翻译为点滴记忆。是一款基于PHP和MySQL的功能强大的博客及CMS建站系统,致力于为用户提供快速、稳定且在使用上及其简单舒适的内容创作及站点的搭建服务
    SegmentFault。SegmentFault是中国知名地开发者社区,为为中文开发者提供一个纯粹、高质的技术交流平台。SegmentFault包括了问答平台、活动平台、个人笔记等模块,此平台基于Typecho Framework 开源框架进行开发,并使用了采用 Redis、MySQL进行数据存储,保证了该平台的稳定性。

    比较出名的博客搭建工具有:

    WordPress。WordPress开发于2003年。WordPress是一个让拥有有限技术经验的用户可以“开箱即用”使用的博客开发系统,该系统基于PHP和MySQL,核心思想是以最少的设置工作让可以专注于自由分享故事,产品或服务。WordPress能够构建任何类型的网站,包括博客,如果使用自托管的WordPress,则可以接触到数以千计的插件和主题资源,精通技术的用户可以用非凡的方式对其进行定制。WordPress方便地为用户提供了创建和分享的机会,从手工制作的个人轶事到改变世界的动作
    Hexo。Hexo是基于node.js开发的静态博客开发框架,拥有依赖少,易于安装使用等特点。Hexo可以从markdown文件中方便的生成静态网页托管在GitHub和Coding上,直接在GitHub平台托管博客,用户可以安心的去写作而不需要定期维护。使用hexo搭建博客,用户还可通过hexo添加各种功能,包括搜索的SEO,阅读量统计、访问量统计和评论系统等,极大地提升了用户的博客使用体验

    1.3 本论文主要工作与章节安排本文共分为八章,各章节内容安排如下:

    第一章主要叙述了基于 Vue 和 express 的扁平化个人博客系统的选题背景、扁平化设计风格的研究现状以及博客系统的国内外发展现状、相关的工作安排
    第二章主要叙述了本系统使用到的主要技术介绍
    第三章主要叙述了本系统设计思路以及需求分析
    第四章主要叙述了系统的结构设计,包括前端UI、API接口、服务器的配置
    第五章主要叙述了系统如何使用mongodb数据库进行数据存储以及表结构的设计
    第六章主要叙述了系统各个模块的实现以及主要功能
    第七章主要叙述了如何将系统从本地部署到服务器上
    第八章是本文的总结与展望,是对本文内容的整体性总结以及对未来工作的展望

    二、技术介绍为了更好的了解本系统,以下将对本文用到的技术及框架一一进行简介:
    2.1 Vue框架简介Vue是一套用于构建用户界面的前端渐进式框架。Vue使用声明式渲染技术,能够将数据绑定到DOM文本或者特性。在绑定到DOM之后,Vue提供了一个强大的过渡效果系统,可以在元素发生位置变换的时候,自动地应用过渡效果。并且,Vue以组件化的思想去构建前端页面,一个组件可以是一个页面,也可以是一个通用的元素,不同的组件之间可以相互传参(如子组件间传参、父组件间传参,子组件向父组件传参,父组件向子组件传参),以完成必要的数据传输工作。在本设计中,定义了多个Vue的组件用于博客系统的搭建,组件的应用使得系统的实现变得高效而具有模块复用性。
    2.2 NuxtNuxt.js是一个基于Vue.js的通用应用框架。通过对客户端/服务端基础架构的抽象组织,Nuxt.js主要关注的是应用的UI渲染。Nuxt.js 集成了Vue2、Vue-Router、Vuex、Vue-Meta,用于开发完整而强大的 Web 应用。Nuxt.js是一个基于Vue.js的通用应用框架。通过对客户端/服务端基础架构的抽象组织,Nuxt.js主要关注的是应用的UI渲染。Nuxt.js 集成了Vue2、Vue-Router、Vuex、Vue-Meta,用于开发完整而强大的 Web 应用。Nuxt.js使用Webpack和vue-loader、babel-loader来处理代码的自动化构建工作(如打包、代码分层、压缩等等)。
    2.3 Node.jsnodejs是基于Chrome的V8内核引擎开发的一个JavaScript解释器,目的是提供一个可以让JavaScript高性能运行的环境。 Nodejs底层使用C++进行编写,拥有强大的I/O性能,并且Nodejs拥有完善的时间处理机制,天然可处理DOM,使得JavaScript书写的程序拥有较高的性能。拥有最早Node.js主要是安装在服务器上,后来Node.js在前端也大放异彩,带来了Web前端开发的革命。
    2.4 Mongoose数据库MongoDB是一个非关系型数据库。由于关系型数据库需要满足三范式,不存储冗余数据,数据量较大需要做关联查询时效率较低,而非关系型数据库不需要严格满足三范式,可以将相关的数据存在同一个文件中,提高查询效率。和传统的关系型数据库不一样,MongoDB不需要显式地在系统中某一处创建数据库,而是在用户第一次向数据库写入数据时会,将会在指定的目录下自动创建数据库,并在磁盘上分配一系列数据库文件集合,包括所有的集合、索引以及其他元数据。
    Mongodb使用BSON进行数据的存储,BSON与JSON格式有相似的结构,都是以object、key-value格式进行数据的存储。由于现在互联网中大多数项目的前后端都是通过API请求来进行数据交互,而JSON是当前主流的交互数据格式, 使用Mongodb作为数据的存储平台,使得在使用API进行数据交互时不需要额外的数据格式转换,大大方便了开发人员的开发体验
    2.5 OAuth协议OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源,如照片、视频、联系人列表,而无需将用户名和密码提供给第三方应用。OAuth授权流程如图2-1所示:

    流程图说明:

    用户点击客户端提供的授权请求
    客户端请求服务的授权页面呈现给用户,用户点击确认授权后服务端返回授权许可凭证给客户端
    客户端通过步骤二接收到的授权许可凭证及在服务端注册的应用信息请求服务端
    如果步骤三验证通过服务端则返回 access token 给客户端
    客户端通过第四步获取的 access token 请求服务端获取资源
    如果服务端校验 access token 成功,则返回指定资源给客户端

    三、系统需求分析3.1 设计目标本文旨在设计出一款前端UI页面扁平化、架构扁平化(组件之间相互独立,可复用)、支持markdown语法、核心功能突出的个人博客系统,一键注册拥有自己的个人博客系统,无需繁琐的搭建、配置过程,降低操作的复杂度。本系统的目标用户程序员,支持Markdown语法这一特性使得程序员写技术博客时代码区域有高亮效果,代码和其他的文本区分开来,在视觉上阅读更加的方便。
    3.2 系统的用户角色及权限本系统的用户角色分为三类,分别是管理员、注册用户以及游客,以下是阐述不同的用户角色拥有的权限:

    管理员

    可删除任何用户发布的文章可删除任何用户的评论
    注册用户

    可新建文章可删除或编辑自己发布的文章可查看、编辑或删除自己的草稿可设置自己的个人信息及修改密码
    游客

    可查看所有已发布的文章可通过GitHub登录对文章进行评论

    3.3 模块需求分析本系统一共分为八大模块,分别是登录、注册、文章发布、文章管理、草稿、评论、标签、设置模块,以下是对各个模块需求的详细分析:
    3.3.1 登录模块登录模块的功能分为前端界面的设计和后端账户数据的存储及校验。前端UI界面要求界面简洁、颜色以清新风格为主,可采用大片纯色填充的方式。后端数据存储,要求将用户名和密码存在user表中,且密码采用MD5加密算法加密成等长的字符串后存储在user表中,从数据安全性角度来看,不允许密码采用明文的方式直接存储,加密后的等长字符串能提高用户数据的安全性。
    3.3.2 注册模块注册模块的功能分为前端页面的设计和后端新账户数据的存储,以及注册新账户遵守以下校验点:

    用户名和数据库中已经存在账户进行比对,若已存在此用户则不能创建成功
    若用户名和密码为空,则不能创建成功
    新账户的密码长度不能低于3位

    3.3.3 新建文章模块用户通过新建文章模块进行文章的编辑和发布,文章编辑区的编辑器支在线编辑和Markdown语法,这也是本博客系统和传统的博客系统不一样的地方,现在比较受程序员欢迎的博客系统有Hexo等,但不支持在线编辑,只能在本地编辑好文章再通过git命令发布到博客上。
    3.3.4 文章管理模块文章管理是本系统的核心功能之一,管理好文章的渲染以及分类,提高用户的体验感,文章管理遵循以下要求:

    用户发布文章有种方式可选择:置顶、首页显示、标签页显示、草稿
    选择置顶的文章显示在首页列表的最顶部
    首页显示的文章渲染在首页列表中,未登录的游客浏览本博客系统时也可以看得到所有用户发的文章
    标签页显示的文章在标签页根据标签分类显示
    草稿类的文章渲染在草稿页面,这部分的功能是暂时存储未完成编辑的文章,方便用户下次继续编辑

    3.3.5 草稿模块在草稿模块,将所有用户编辑文章时选择为草稿存储的文章归类整理显示在草稿页面,用户可以继续编辑或删除,编辑完成后再发布显示在首页文章列表。
    3.3.6 评论模块评论模块记录所有用户或者游客通过GitHub授权登录后对文章进行的评论,这一部分的数据是不同用户交互最直接的体现。与其他博客系统不一样的地方是,游客对本系统的文章进行评论后,系统会给文章的作者发邮件通知,邮件格式为“XXX对你的文章进行了评论”“XXX回复了你的评论”。
    3.3.7 标签模块用户在新建文章页的底部通过回车创建标签,这些标签除了在文章编辑器底部显示之外,还要在标签页将标签的内容以及创建时间显示出来,点击每一个标签,能将该标签下的所有文章显示出来。
    3.3.8 设置模块设置模块分为两部分,第一部分是用户的基本信息设置,其中一个输入框,在代码里的变量名为Nickname的字段,也译为这个博客头部的别名显示,用户可根据自己的喜好给自己的博客系统命名;第二部分是修改密码,用户通过此部分修改密码功能改自己账户的密码。
    四、系统结构设计4.1 系统页面架构设计本系统的前端页面设计分为三级,第一级为登录注册页面,第二级为首页和标签页,第三级为首页中的四个子页面,分别为新建文章页、高草页面、评论页面和设置页面;标签页面包含一个子页面标签文章页。本系统总体架构图如图4-1所示:

    4.2 系统技术架构设计本系统用了Nuxt.js框架,Nuxt.js分为客户端(Client)和服务器端(Server)如图4-2所示。以下将从客户端和服务端进行阐述:
    客户端:使用Vue框架,以组件的方式设计页面,Vuex记录参数状态,方便组件间的传参,通过API接口在服务器端去调用数据库里的数据,最后将数据渲染在UI页面上。
    服务器端:采用Node.js来写后端的API接口以及构建服务器,API接口去调用Mongodb的数据,最后传给对应的前端页面。

    4.3 系统数据流设计本系统的数据流分为用户名和密码、文章在不同的页面上的渲染、标签的渲染以及评论数据的渲染,数据流如图4-3所示:

    五、数据库设计5.1 表设计本系统主要的用到的表有Article、User、tags、Comment。以首页看到的一篇文章为例,url=http://8.6.8.244:3000/detail/5c98f79cad892945422d15df 。其中“5c98f79cad892945422d15df”是数据写入时数据库自动生成的_id,用来标识这篇文章。当我们请求这篇读取某篇文章时,会先拿到以上所述的_id,然后在Article表中进行比对,找到对应的_id,并且在Article里根据author这个字段去拿到User表中的用户信息,根据comment这个字段拿到Comment表中的信息,根据tags这个字段去拿到tags表中相关的信息。如图5-1所示:

    5.2 表实现本系统用Mongodb数据库进行数据存储,Mongodb的存储格式是BSON形式,以配置文件的形式而非表格的形式存储。每个表都有对应的Schema,一个Schema对应一个表,并且有不同的字段进行信息分类存储。图5-2为Mongodb的管理界面:

    本系统一共设计了三个表,分别为文章表、标签表、用户表。
    5.2.1 文章表文章表以BSON格式存储着所有发布的文章,一共有13个字段:_id、views、flag、like、comments、tags、previous article、next article、title、content、created、created at、update at、_v.

    5.2.2 标签表标签表一共有5个字段:_id、name、created at、updated at、_v

    5.2.3 用户表用户表一共有14个字段:_id、role、email、nickname、motto、avatar、following、followers、like、username、password、created_at、update_at、_v。


    六、系统的实现6.1 登录模块登录模块UI页面如图6-1所示,由<h2>标题LOGIN和两个\<input\>标签以及带高亮的登录按钮和白色透明的注册按钮组成,登录按钮进行高亮的设计,体现在登录页面登录优先级更高于注册,背景为大片的白色填充,简单的视觉设计给用户减少不必要的视觉负担。

    用户进行登录时,输入已经在数据库存在的用户名和密码,系统首先对用户输入的用户名进行查找,若数据库中存在次用户名,则进一步的对用户输入的密码进行校验。本系统的密码采用MD5加密,生成一串等长的加密后的字符串存在数据库中,用户在前端输入密码后,后台将密码用MD5算法加密后,用加密后的字符串在数据库中进行查询比对,若存在一样的加密后的字符串,则校验成功,用户可以登录成功。由图6-2、6-3可以看到,不同的密码加密后的字符串是不一样且唯一的。


    6.2 注册模块注册模块UI页面如图6-4所示,由<h2>标题REGISTER和两个<input>标签以及带高亮的注册按钮和白色透明的登录按钮组成,注册按钮进行高亮的设计,体现在注册页面注册优先级更高于登录,背景为大片的白色填充,简单的视觉设计给用户减少不必要的视觉负担。
    遵循本系统“一键注册拥有个人博客系统”的核心思想,用户在注册模块中的操作很简单,只需输入用户名和密码后点击注册就能拥有属于自己的博客系统。

    用户输入用户名和密码进行注册时,系统有以下提示点:用户名和密码不能为空,如图6-5所示:

    6.3 文章管理模块首页是用户发布的所有文章列表,如图6-8所示。置顶的设置可以提醒浏览博客的用户重点的去查看此篇文章。

    首页的顶部有搜索功能,支持关键字模糊查询,用户可以直接输入关键字去搜索到自己想看的文章,而不需要一页一页的翻,如图6-9所示:

    6.4 支持Markdown语法的编辑器新建文章模块内置支持Markdown语法的编辑器,有置顶、首页显示、标签页显示、草稿四种选项,可上传图片、进入预览模式、以及一键保存按钮。在编辑器的底部有“回车创建标签”的输入框,完成文章的编辑后可给此文章添加一个标签,有回车新建标签和选择现有的标签两种方式,添加标签后,该文章在标签页对应的标签分类下显示,归类管理文章能让用户快速的找到自己想看的内容,也使得整个系统的文章管理井然有序

    编辑器支持Markdown语法,左边是编辑区,右边是渲染后的结果,如图6-11所示。以下介绍几种基本的markdown语法:

    分点显示 输入*后空格
    代码高亮 ``` 代码区域 ```
    一级标题 #
    二级标题 ##
    三级标题 ###
    引用 > XXX


    6.5 草稿模块草稿页面显示所有未完成编辑的文章,用户可对草稿类的文章进行编辑或删除操作,编辑完成之后点击发布即可在首页文章列表显示。

    6.6 评论模块用户对文章进行评论,首先,先进行GitHub授权登录,如图6-13、6-14所示:

    GitHub授权登录成功后,可对文章进行评论。如图6-15所示:
    所有用户的评论都被渲染在前端的评论页面,如下图所示,评论的内容及评论的时间,点击评论可跳转到相应的文章,不同的用户通过GitHub授权登录后在评论区进行学术的交流以及信息的互动。

    6.7 OAuth授权协议过程用户通过GitHub账号登录进行评论的核心技术是OAuth授权,详细过程如图6-17所示。以下是对于本系统使用的OAuth授权过程做详细的介绍:

    用户点击页面上的“GitHub授权”按钮后,后台调用API接口login/Oauth/authorise
    拿到Client id和callback URL和生成的Code,根据拿到的callback URL跳转到GitHub登录页面,用户数据GitHub用户名和密码点击登录时,Code导出并调用API接口OAuth/access token,拿到生成的token去访问GitHub的用户信息,授权成功

    以上的授权过程主要分为网站和GitHub的协商以及用户和GitHub的协商
    网站和GitHub的协商:

    GitHub会对用户的权限进行分类,如读写仓库信息的权限、读取用户信息的权限、修改用户信息的权限。如果某网站需要获取GitHub用户的信息,那么GitHub先要求本系统在GitHub平台上注册一个应用,并且填写系统的域名和标明期望获取的用户信息,此时GitHub只允许该域名能获取到用户信息,系统和GitHub达成共识,拿到Client id和Client Secret
    用户和GitHub的协商:

    用户点击GitHub登录按钮时,本系统把拿到的Client id交给用户,进入GitHub授权页面时通过Client id的认证,告知用户本系统想读取用户信息,若用户点击授权登录,则GitHub把用户信息发送给系统,认证成功,否则认证失败
    6.8 标签模块标签模块页显示所有被创建的标签,标签的名字及创建的时间,管理员可对此标签进行编辑或删除。点击某一个标签可以显示该标签下所有的文章。

    6.9 设置模块设置模块分为两个部分,第一部分是修改个人信息,第二部分是修改密码,用户可以在设置页面进行密码的修改,数据库会随之更新用户的密码,用MD5加密算法加密后存储在数据库中。
    6.10 侧边栏模块侧边栏有四个按钮,分别是返回登录页面、查看xml文件配置、跳转到github首页、返回顶部按钮。如图6-20所示:

    七、系统部署到服务器上7.1 硬件配置vultr是以服务器的使用时长计费的服务器提供商,其拥有较好的网络带宽和能提供稳定的服务器。考虑到本系统需要使用较新版本的nodejs及npm包,并且需要使用比较现代的前端框架,故在vultr选配了64位的Ubuntu系统虚拟服务器。其拥有1GB的运行内存和25GB的高速硬盘,足以应付一个博客系统。
    7.2 登录服务器我们使用 SSH 的方法访问远程服务器,接着进行相关的环境配置。现有一款全平台通用的终端工具Termius,其支持通过SSH的方式访问vultr服务器,添加一个服务器步骤如下:
    点击添加一个host,如图7-2所示:

    填写ip地址、用户名和密码等, 如图7-3所示:

    打开“SSH”,填写完毕后按”SAVE”按钮进行保存, 如图7-4所示:

    尝试登陆到远程服务器, 如图7-5所示:

    7.3 部署Node.js环境打开ssh终端后,在终端下依次输入:
    更新远程服务器安装包索引缓存
    sudo apt update从安装包索引库中安装 Nodejs
    sudo apt install nodejs安装npm命令行工具
    sudo apt install npm可输入打印版本号验证安装成功性
    ➜ ~ node -vv8.10.0➜ ~ npm -v6.9.07.4 部署Mongodb数据库打开ssh终端后,在终端下输入:sudo apt install mongodb,此时,mongodb的核心服务、命令行工具都会被成功安装,使用打印版本号命令验证安装成功性:
    ➜ ~ mongo -versionMongoDB shell version v3.6.3git version: 9586e557d54ef70f9ca4b43c26892cd55257e1a5OpenSSL version: OpenSSL 1.1.0g 2 Nov 2017allocator: tcmallocmodules: nonebuild environment: distarch: x86_64 target_arch: x86_64安装完毕后,在/下创建数据库存储文件夹/data/db
    7.5 文件上传到服务器使用 filezllia工具将文件上传到服务器,按照以下步骤添加服务器:

    点击”连接”,filezllia将会连接站点
    连接到远程站点后,把需要上传的文件拖拽到需要上传到的文件夹内即可。

    7.6 数据库迁移使用mongodump和mongorestore分别完成本地数据库的压缩备份和还原。
    从本地mongo数据库中执行压缩备份,如对于”essay”数据库
    mongodump --db essay接着将会得到 dump.zip,内部结构为
    dump/ └── essay ├── articles.bson ├── articles.metadata.json ├── tags.bson ├── tags.metadata.json ├── users.bson └── users.metadata.json将导出文件通过filezilla上传到远程服务器,并解压为essay 文件夹
    从解压文件夹中还原数据到远程服务器mongo数据库中,如恢复essay数据库
    mongorestore -d essay /dump/essay进入mongo命令行,查看是否成功导入
    ➜ ~ mongo...> show dbsessay 0.000GB八、总结和展望8.1 本文总结本文针对当下流行的扁平化设计风格搭建个人博客系统进行了一系列研究,重点对如何构建一个前端UI设计扁平化、核心功能突出、第三方授权以及不同用户能够进行信息交互等关键问题进行了深入的研究。本文的主要工作和创新点如下:

    针对已存在的博客平台配置复杂度高的不足之处,开发出了一键注册拥有个人博客的系统
    针对个人博客使用者大多数为学习技术的程序员,且当前的博客系统没有支持markdown语法的在线编辑器的这一现象,开发出支持在线编辑支持Markdown语法的博客系统
    针对博客文章传播途径较窄这一痛点问题提出了支持github第三方授权登录进行信息交互,提高文章的传播率的解决方案

    8.2 不足之处和未来的工作计划现今计算机科学技术和互联网发展越来越快,前端领域的框架和技术层数不穷,许多优秀的框架和技术能开发出更优秀完美的博客系统。轻量级的产品现在越来越流行,但要做到轻量级而又功能齐全,体验极佳还有待提高技术水平以及优化设计。以下是本文提出的搭建博客系统中的不足之处以及下一步工作计划:

    本文提出的扁平化设计虽然比其他博客平台都要更简洁,但是再UI的设计上还未达到使用户除了使用舒适的同时有很棒的视觉冲击。下一步,我们将进一步探索更优秀的扁平化UI设计,在各个页面和整体设计上进行优化,进一步提高本系统的视觉冲击力
    本文提出的不同用户信息交互只能通过GitHub账户登录授权才能进行,这使得不是github用户的人在本系统上无法和其他用户进行信息的交互。下一步,我们将尝试添加更多的授权登录方式,如支持社交账号登录授权等
    本文的博客系统首页显示的文章是用户发布的所有文章的列表,置顶状态的文章也是发布者手动设置的,在当今信息爆炸的时代,提高用户的使用体验感的途径之一是根据用户的浏览喜好推荐与当前用户最匹配的数据,并渲染在首页顶端,本文的系统目前还未做到引入推荐算法,没有智能推荐文章功能。下一步,我们将对推荐算法进行深入的学习并把它引入本系统中来

    参考文献[1]微博客传播特性及盈利模式分析[J].卢金珠.现代传播(中国传媒大学学报).2010
    [2]陈沛捷.个人博客系统设计与实现[D].硕士学位论文天津大学,2017.
    [3]殷红梅.基于扁平化艺术设计风格的UI设计探究[J].电脑编程技巧与维护,2018. [4]任葆轩.试论拟物化与扁平化在UI设计中的比较[J].艺术科技.2017(11)
    [5]钱瑜.浅析UI设计中拟物化和扁平化的发展[J].新丝路(下旬).2016(05)
    [6]张思南.极简主义在扁平化风格UI设计中的应用与研究[J].美术教育研究.2018(02)
    [7]陈琳.如何购买WordPress网站域名及绑定域名[J].计算机与网络,2018,44(10):35.
    [8]殷丽萍.Tumblr:互联网上的“极简”奇迹[J].中外管理,2015(03):36-37.
    [9]王丹阳.浅析简书的商业模式[J].新闻研究导刊,2019,10(01):212-213.
    [10]梁额.《Vue.js实战》,清华大学出版社,2017.
    [11]梁睿坤.《Vue2实践揭秘》,电子工业出版社,2017.4ISBN978-7-121-31068-3
    [12]《Vue.js2Web Development Projects》,Copyright © 2017.
    [13]《Full-Stack Web Development with Vue.js and Node》,Copyright © 2018.
    [14]亚历克斯 • 杨 布拉德利 • 马克 麦克 • 坎特伦蒂姆 • 奥克斯利 马克 • 哈特 T.J. 霍洛瓦丘 内森 • 拉伊利赫,《Node.js实战》,—北京:人民邮电出版社,2018.08
    [15]邹竞莹. Node.JS博客系统的设计与实现[D].硕士学位论文黑龙江大学,2016.
    [16]吴德,应毅,毛道鹤.基于OAuth2.0的认证授权方案设计与优化[J].软件,2018
    [17]沈桐,王勇,刘俊艳.基于OAuth2.0,OpenID Connect和UMA的用户认证授权系统架构[J].软件,2017,38(11):160-167.
    [18]李纪伟,段中帅,王顺晔.非结构化数据库MongoDB的数据存储[J].电脑知识与技术,2018,14(27):7-9.
    [19]杨怀,宋俊芳,王聪华.浅谈MD5加密算法在网络安全中的应用[J].网络安全技术与应用,2018(09):40.
    [20]徐跃,吴晓刚.一种改进的MD5加密算法及应用[J].现代计算机(专业版),2018.
    [21]任杰麟.MD5加密算法的安全性分析与改进[J].农业图书情报学刊,2017.
    0 评论 2 下载 2019-07-01 23:13:02 下载需要15点积分
  • 基于C#和SQL SERVER的汽车配件仓储管理系统

    摘 要汽车配件信息管理网站建设是汽车配件信息进行有效管理的重要工具。本次设计以建设汽车配件信息管理网站为目标,同时结合现今对信息管理相关网站建设方面的需求,建设相关后台数据库及相应的交互性界面。
    为了实现有效率的对汽车配件信息进行管理,本论文以网站建设为主体架构,详细的介绍了汽车配件信息管理网站的需求,具体描述了整个网站的开发过程,分析了汽车配件信息管理网站的功能。并以业务流程图的形式详细的介绍了系统的各个功能的模块及各个模块的数据库表,并详细的记录了各个功能测试的情况信息。对于汽车配件管理系统迅速发展的信息化时代,通过规范、统一的网站式管理对相关信息进行整合,不仅方便了管理,而且提高了工作效率。
    本毕业设计的内容是设计并且实现一个汽车配件信息管理网站设计,用Microsoft Visual Studio作为开发工具,以SQLServer作为数据库,使用C#语言开发。该系统界面友好、操作简单,容易维护,适合公司管理者以及员工使用。
    关键词:汽车配件信息;网站式管理;MicrosoftVisual Studio;SQL Server
    AbstractThe construction site is automobile fittings information management of autoparts information to efficient management. The design of the construction ofauto parts information management website as the goal, combined with thecurrent information management related to website construction needs, theconstruction of relevant background database and the corresponding interactiveinterface.
    In order to realize the efficient management of auto parts information, thewebsite construction as the main structure, detailed introduces the auto partsinformation management needs of the site, the specific description of thedevelopment process of the entire site, analysis of the auto parts information managementfunctions of the website. And the business process diagram in the form ofdetailed description of the module and each module of the system each functionof the database table, and detailed records of each function test information.In the information age, the rapid development of auto parts management systemthrough the website management standard, unified integration of relevantinformation, not only convenient management, but also improve the workEfficiency at
    The content of this graduation design is to design and implement an autoparts information management website design, using Microsoft Visual Studio as adevelopment tool, using SQL as the database Server, using C# languagedevelopment. The system has a friendly interface, simple operation, easymaintenance, suitable for company managers and employees.
    Key words: auto partsinformation; Web site management; Microsoft Visual Studio; SQL Server
    引言随着计算机技术的快速发展,许多企业事业单位的管理都实现了办公自动化,这种自动化管理方式不仅管理简单,而且效率非常高。为了能够高效而且有效地管理汽车配件的管理信息,汽车配件经营者提出使用计算机进行汽车配件信息的管理,使汽车配件管理科学化,最大限度地减少信息损失,提高汽车配件的利益。
    使用计算机管理汽车配件相对人工记录,有很多的有点。首先,用计算机进行金额计算时速度快,可信度高。而且查询时不必要逐个查找,只需要输入相关信息就可快速得到结果。然后,汽车配件信息存储在计算机,可以作到数据的永久保存,安全可靠。最重要的是,汽车配件数据存储在计算机中,由于计算机存储容量非常大,所以清单的内容在输入电脑后,对数据的操作是非常方便的,而且避免了频繁的使用清单。
    汽车部件仓储管理已经渐渐的走向稳定发展的趋势,更加具有企业化的概念,在体制上,汽车部件仓储管理已经开始慢慢的健全它的体制,对公司人员进行培训,将业务进行熟练化,这样大大的提高了汽车部件管理在世界中的发展,并且使它的地位明显的上升,也进一步的满足了大家的需求。为了更好的发展,企业渐渐的从整体中分离开来建立自己的发展模块,不断的寻求发展模式,扩大自己的经营模式。
    本网站使用.net+Microsoft Visual Studio+SQL Server的组合,使用计算机浏览器实现了网站的基本功能,网站对汽车配件的信息进行管理,不但可以使用工程的、规范的管理过程,而且可以有效的提高了工作人员的工作效率,直观的、科学的管理汽车配件信息,进而完成公司的业务,这对汽车配件信息的管理的发展及信息化的管理具有极其重要的意义。
    第1章 绪 论1.1 论文背景1.基于汽车配件管理的相关背景
    汽车配件管理系统的目的是为企业提供一个计算机化的管理平台,实践企业内部科学有效的管理,促进企业管理信息化,规范化,将能使管理人员从繁琐的杂务工作中解脱出来,真正从事管理工作。
    目前汽车配件销售企业大多数在其连锁店的管理还是手工进行,随着汽车配件行业的迅速发展,手工管理的种种弊端暴露无疑,给销售企业的发展带来了不必要的麻烦。为了规范企业内部管理,提高企业业务管理水平,更好的为客户服务,应采用计算机来管理汽车配件的进销存业务。
    汽车部件仓储管理已经渐渐的走向稳定发展的趋势,更加具有企业化的概念,在体制上,汽车部件仓储管理已经开始慢慢的健全它的体制,对公司人员进行培训,将业务进行熟练化,这样大大的提高了汽车部件管理在世界中的发展,并且使它的地位明显的上升,也进一步的满足了大家的需求。为了更好的发展,企业渐渐的从整体中分离开来建立自己的发展模块,不断的寻求发展模式,扩大自己的经营模式。
    2.数据管理技术
    随着互联网发展进程的加快, 信息资源网络化成为一大潮流。与传统信息资源相比, 网络信息资源在 数量、结构、内涵、类型、载体形态、分布和传播范围、控制机制、传递手段等方面都与传统信息资源有显著的差异, 呈现出许多新的特点。这些新的特点赋予网 络环境下信息资源管理许多新的内涵。网络信息资 源管理建立在新的社会基础结构即信息网络的基础之上, 适应了信息化社会信息组织和管理的需要是一个新的生长点。
    数据管理技术就是指人们对数据进行收集、组织、存储、加工、传播和利用的一系列活动的总和,经历了人工管理、文件管理、数据库管理三个阶段[4]。每一阶段的发展以数据存储冗余不断减小、数据独立性不断增强、数据操作更加方便和简单为标志,各有各的特点。其中现今就处于数据库管理为主流的阶段,节省的大量的人力资源,对于信息化网络化的现在数据库管理技术的共享性、大量数据存储显示、数据处理快速而且具有很高的安全性和完整性,其并发控制和恢复性都不会让数据轻易丢失
    3..NET技术
    ASP.NET是由微软在.NET Framework框架中所提供,开发Web应用程序的类库,封装在System.Web.dll文件中,显露出System.Web名字空间,并提供ASP.NET网页处理、扩充以及HTTP通道的应用程序与通信处理等工作,以及Web Service的基础架构。ASP.NET是ASP技术的后继者,但它的发展性要比ASP技术要强大许多。
    ASP.NET可以运行在安装了.NET Framework的IIS服务器上,若要在非微软的平台上运行,则需要使用Mono平台[2],ASP.NET在2.0版本已经定型,在.NET Framework 3.5上则加上了许多功能,像是ASP.NET AJAX、ASP.NET MVC Framework、ASP.NET Dynamic Data与Microsoft Silverlight的服务器控件等。
    很多人都把 ASP.NET 当做是一种编程语言,但它实际上只是一个由 .NET Framework提供的一种开发平台 (development platform),并非编程语言。也可认为ASP.NET是.NET组件,任何.NET语言,例如C#,可以引用该组件,创建网页或Web服务。
    为了因应云化所诱发的多作业平台集成与开发能力,微软特别开发一个新一代的 ASP.NET,称为 ASP.NET vNext,并于 2014 年命名为 ASP.NET 5,但随后于 2016 年将它更名为 ASP.NET Core,由于架构上的差异颇大,因此未来 ASP.NET 与 ASP.NET Core 将是分别发展与维护,Windows 平台的 ASP.NET 4.6 以上版本仍维持 Windows Only,但 ASP.NET Core 则是具有跨平台 (Windows, Mac OSX 与 Linux) 的能力。
    1.2 系统开发的意义随着计算机技术的快速发展,许多企业事业单位的管理都实现了办公自动化,这种自动化管理方式不仅管理简单,而且效率非常高。为了能够高效而且有效地管理汽车配件的管理信息,汽车配件经营者提出使用计算机进行汽车配件信息的管理,使汽车配件管理科学化,最大限度地减少信息损失,提高汽车配件的利益。
    使用计算机管理汽车配件相对人工记录,有很多的优点。首先,用计算机进行金额计算时速度快,可信度高。而且查询时不必要逐个查找,只需要输入相关信息就可快速得到结果。然后,汽车配件信息存储在计算机,可以作到数据的永久保存,安全可靠。最重要的是,汽车配件数据存储在计算机中,由于计算机存储容量非常大,所以清单的内容在输入电脑后,对数据的操作是非常方便的,而且避免了频繁的使用清单。
    1.3 研究现状和发展趋势1.研究现状
    现在我国的企业特别是汽车配件企业的管理水平还停留在纸介质或半自动(由电脑处理一部分数据,由人工处理一部分数据)的基础上,这样的机制已经不能适应时代的发展,因为它浪费了许多人力和物力,在信息时代这种传统的管理方式必然会被以计算机为基础的信息管理所取代。软件作为一项有力的工具,只能当此种工具,与我们的实践相结合起来的时候,才具有重大的社会价值及使用价值。因此根据企业目前实际的汽车配件管理系统情况开发一套汽车配件管理系统是十分有必要的。
    2.发展趋势
    汽车部件仓储管理已经渐渐的走向稳定发展的趋势,更加具有企业化的概念,在体制上,汽车部件仓储管理已经开始慢慢的健全它的体制,对公司人员进行培训,将业务进行熟练化,这样大大的提高了汽车部件管理在世界中的发展,并且使它的地位明显的上升,也进一步的满足了大家的需求。为了更好的发展,企业渐渐的从整体中分离开来建立自己的发展模块,不断的寻求发展模式,扩大自己的经营模式。
    通过计算机进行货物的进入和销售数量的统计,使管理者不必再为统计数量而感到烦恼,可以利用节省出来的时间全身心的投入到其他事情当中,也对管理制度进行了优化和改良,集中对零部件进行统计和分配,这样不仅减少我们使用的资源,也大大的降低了我们的劳动成本,节省了财力,使管理人员更加专心的从事管理工作,使管理制度更加合理化和规范化。
    1.4 论文的基本结构此次论文详细的介绍了汽车配件信息管理网站设计及实现的过程以及相关功能解说、研究思路、思想总结等部分。着重介绍了这个网站的设计思想、技术路线、开发平台的选择、总体框架、程序流程、本网站应实现的功能以及具体的实现方法和步骤,并且讨论类似网站存在的局限性和解决的思路。其主要基本结构如下:

    绪论,用来详细解说该系统的背景、研究意义及研究前景。
    系统开发平台的介绍,用来详细介绍该系统用到的开发工具,如Microsoft VisualStudio,SQLServer。
    第1章是需求分析,用来分析经济、技术、操作上的可行性,重点介绍系统的功能分析、业务流程图以及ER图等。
    第2章是系统设计,用来详细介绍各个模块的功能,并设计数据库,展示系统界面。
    第3章是实现部分功能的主要代码及系统的整体及相关功能测试,用来展示系统的核心代码以及展示系统测试的效果。

    第2章 系统开发工具及相关技术本章将对本次汽车配件信息管理网站的开发平台进行简要的介绍,同时介绍在开发过程中采用的一些Ajax技术。
    2.1 开发工具简介本次网站设计主要采用的是学校中通用的软件,操作系统是Windows,主要Web端和后端的开发都是在Microsoft Visual Studio中操作实现,数据库采用的是Sql Server数据库。下面将对两个软件简要介绍:
    1.Microsoft Visual Studio
    Microsoft Visual Studio(简称VS)是微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。所写的目标代码适用于微软支持的所有平台,包括MicrosoftWindows、Windows Phone、WindowsCE、.NET Framework、.NET CompactFramework和Microsoft Silverlight。
    而Visual Studio .NET是用于快速生成企业级ASP.NET Web应用程序和高性能桌面应用程序的工具。Visual Studio包含基于组件的开发工具(如Visual C#、Visual J#、VisualBasic和Visual C++),以及许多用于简化基于小组的解决方案的设计、开发和部署的其他技术。
    2.Sql Server
    SQL Server一开始并不是微软自己研发的产品,而是当时为了要和IBM竞争时,与Sybase合作所产生的,其最早的发展者是Sybase[1],同时微软也和Sybase合作过SQL Server 4.2版本的研发,微软亦将SQL Server 4.2移植到Windows NT(当时为3.1版),在与Sybase终止合作关系后,自力开发出SQL Server 6.0版,往后的SQL Server即均由微软自行研发。
    Sql Server是一个关系数据库管理系统。具有易用性、适合分布式组织的可伸缩性、用于决策支持的数据仓库功能、与许多其他服务器软件紧密关联的集成性、良好的性价比等。为数据管理与分析带来了灵活性,允许单位在快速变化的环境中从容响应,从而获得竞争优势。
    维基百科给的解释是这样的,Microsoft SQL Server是由美国微软公司所推出关系数据库解决方案,最新的版本是SQL Server 2016,已经在2016年6月1日发布。 数据库的内置语言原本是采用美国标准局(ANSI)和国际标准组织(ISO)所定义的SQL语言,但是微软公司对它进行了部分扩充而成为作业用SQL(Transact-SQL)。几个初始版本适用于中小企业数据库管理,但是近年来它的应用范围有所扩展,已经触及到大型、跨国企业的数据库管理。
    2.2 .net 平台介绍.NET就是微软用来实现XML,Web Services,SOA(面向服务的体系结构service-oriented architecture)和敏捷性的技术。对技术人员,想真正了解什么是.NET,必须先了解.NET技术出现的原因和它想解决的问题,必须先了解为什么他们需要XML,Web Services 和 SOA。技术人员一般将微软看成一个平台厂商。微软搭建技术平台,而技术人员在这个技术平台之上创建应用系统。从这个角度,.NET也可以如下来定义:.NET是微软的新一代技术平台,为敏捷商务构建互联互通的应用系统,这些系统是基于标准的,联通的,适应变化的,稳定的和高性能的。从技术的角度,一个.NET应用是一个运行于.NET Framework之上的应用程序。(更精确的说,一个.NET应用是一个使用.NET Framework类库来编写,并运行于公共语言运行时Common Language Runtime之上的应用程序。)如果一个应用程序跟.NETFramework无关,它就不能叫做.NET程序。比如,仅仅使用了XML并不就是.NET应用,仅仅使用SOAPSDK调用一个Web Service也不是.NET应用。.NET是基于Windows操作系统运行的操作平台,应用于互联网的分布式。
    2.3 相关技术1.B/S结构
    B/S结构是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server 应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。
    根据实际开发的需要,位置信息管理网站设计的开发中选择了B/S结构开发web应用程序,通过浏览器访问服务器的的方式实现远程操作和数据共享。
    2.Ajax技术
    AJAX即“AsynchronousJavaScript and XML”(异步JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术。Ajax的概念由杰西·詹姆士·贾瑞特所提出[1]。
    传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求。服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML码往往是相同的。由于每次应用的沟通都需要向服务器发送请求,应用的回应时间依赖于服务器的回应时间。这导致了用户界面的回应比本机应用慢得多。
    与此不同,AJAX应用可以仅向服务器发送并取回必须的数据,并在客户端采用JavaScript处理来自服务器的回应。因为在服务器和浏览器之间交换的数据大量减少(大约只有原来的5%)来源请求,服务器回应更快了。同时,很多的处理工作可以在发出请求的客户端机器上完成,因此Web服务器的负荷也减少了。
    类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。虽然其名称包含XML,但实际上数据格式可以由JSON代替,进一步减少数据量,形成所谓的AJAJ。而客户端与服务器也并不需要异步。一些基于AJAX的“派生/合成”式(derivative/composite)的技术也正在出现,如AFLAX。
    第3章 系统需求分析3.1 系统业务描述根据相应的需求及对应功能的完善实现,汽车配件仓储管理网站设计业务流程主要包括以下几个方面:

    一级管理,通过登录界面,判定是一级管理员后,进入一级管理界面。可以查看配件信息,供应商信息,需求商信息,二管理员信息以及二级管理员的操作日志。并且可以通过切换不同的界面,可以对相应的信息进行添加,删除,修改各个部分的信息。在汽车配件信息界面,可以通过链接查看该零件的生产单位等多种操作。
    二级管理员管理,通过登录界面,判定是二级管理员后,进入二级管理界面。二级管理界面可以查询配件信息以及需求商的基本信息。主要进行入库/出库操作而且额外可以添加需求商户。

    至此,本系统业务流程结束。
    3.2 可行性分析可行性分析应从经济可行性,技术可行性和操作可行性三个方面考虑,以下是对本系统具体的可行性分析。
    1.经济可行性
    利用本校现有的校园网、计算机及配套设备就可使用本系统进行配件的信息管理;对系统的使用都是简单的操作;软件系统由本人在指导老师的帮助下完成的,不要任何费用。
    2.技术可行性
    系统采用B/S架构,前台采用html+css+js编码实现页面的可视化与交互性,后端使用C#实现对SQL Server数据库进行数据的存储、修改、删除等操作,该数据库具有方便、灵活的特点,适应该系统的开发。本系统要求的硬件标准不高,一般的硬件设备足够运行系统。
    3.操作可行性
    使用汽车配件仓储管理系统网站,只需要输入网址就能进入登录界面。然后就是管理首页,主要的管理功能是一级管理员对配件信息,供应商信息,需求商信息,二级管理员信息的增、删、改、查以及对操作日志的查看。其次功能是二级管理员的查询,入库、出库操作以及添加新的需求商功能,实用简单。
    综上所述,开发汽车配件仓储管理网站设计在经济上、技术上、操作上都是可行的。
    3.3 功能需求分析汽车配件仓储信息管理网站设计的使用和相关者有:

    一级管理员:一级管理员对配件信息,供应商信息,需求商信息,二级管理员信息的增、删、改、查以及对操作日志的查看。
    二级管理员:二级管理员能够对配件信息进行查询所搜,主要进行入库、出库操作。同时,可以对需求商的信息进行查询,得到是否有需求商正等待发货而进行出库,也可以添加新的需求商用户。

    汽车配件仓储信息管理网站设计应该满足如下功能需求:
    管理员登陆:能让管理员方便的使用密码登陆系统,从而进行一系列的操作。

    一级管理员可以对配件信息进行增、删、改、查,并且由该配件信息获取其生产单位的相关信息。
    一级管理员对供应商的信息管理。
    一级管理员对二级管理员的信息管理。
    一级管理员对需求商的信息管理。
    一级管理员对日志的查看。
    二级管理员进行出库、入库操作。
    二级管理员添加新的需求商。

    3.4 分析模型3.4.1 业务流程图业务流程图(Transaction Flow Diagram, TFD)就是用一些规定的符号及连线来表示某个具体业务处理过程。是一种物理模型。业务流程图主要是描述业务走向,比如说去ATM机取款,首先得打开自助银行的门走进去,然后找到 一台ATM机,再插入卡输入相应的密码,最后钱才能出来被你取走(当然需要余额充足)。利用它可以帮助分析人员找出业务流程中的不合理流向,业务流程图描述的是完整的业务流程,以业务处理过程为中心,一般没有数据的概念。
    1.数据管理
    数据管理业务流程图如图3-1所示:

    2.设备管理
    设备管理业务流程图如图3-2所示:

    3.汽车配件信息查看
    汽车配件信息查看业务流程图如图3-3所示:

    3.4.2 实体模型图(ER图)E-R图也称实体-联系图(EntityRelationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。
    系统总ER图如图3-4所示:

    管理员实体用来存储管理员的基本信息,其ER图如图3-5所示:

    供应单位实体用来存储供应单位的相关信息,其ER图如图3-6所示:

    需求单位实体用来存储需求单位的相关信息,其ER图如图3-7所示:

    汽车配件实体存储汽车配件的相关信息,其ER图如图3-8所示:

    操作日志实体存储相关操作的信息,其ER图如图3-9所示:

    3.4.3 系统用例图1.总用例图
    总用例图如图3-10所示:

    2.子用例图
    一级管理员配件信息管理如图3-11所示:

    二级管理员配件信息管理如图3-12所示:

    第4章 系统设计4.1概要设计系统的各部分功能模块独立开发、调试,然后利用系统集成的方法将各个模块信息传入数据库。各个功能模块采用事件驱动的方式 与应用程序进行交互,系统部分程序的应用执行是在后台进行的。汽车配件仓储管理网站设计的系统总体结构设计如图4-1所示。

    各模块的结构:
    1.二级管理员管理模块:
    该模块有如下功能:二级管理员可添加需求商信息,并且可以对汽车配件进行出库入库操作。其模块功能图如图4-2所示:

    2.一级管理员管理模块:
    该模块有如下功能:一级管理员可对该模块进行管理,可以查看所有汽车配件,供应商,需求商,管理员的信息,并且可以对信息进行添加,修改,删除,而且可以查看日志信息。其模块功能图如图4-3所示:

    4.2 数据库设计通过以上的对网站的综合分析,本网站选择SQL Server作为网站的数据库,数据库中包括管理员信息、供应商基本信息、需求商基本信息、二级管理员信息、操作日志信息。
    管理员信息表



    表名:Users
    备注:管理员信息表







    字段名称
    数据类型
    自增主键
    允许为空
    默认值


    UserId
    int





    UserName
    nvarchar(50)





    Password
    nvarchar(50)





    Type
    nvarchar(50)





    LoginTime
    Datetime





    Department
    nvarchar(50)





    汽车配件信息表



    表名:CarParts
    备注:汽车配件信息表







    字段名称
    数据类型
    自增主键
    允许为空
    默认值


    PartId
    int





    PartName
    nvarchar(50)





    FromDepartId
    nvarchar(50)





    Num
    nvarchar(50)





    InTime
    Datetime





    UnitPrice
    decimal(18, 2)





    Quantity
    int





    供应单位信息表



    表名: Supplies
    备注:供应商信息表







    字段名称
    数据类型
    自增主键
    允许为空
    默认值


    Id
    int





    Name
    nvarchar(50)





    Principal
    nvarchar(50)





    Address
    nvarchar(50)





    Phone
    nvarchar(50)





    Ways
    nvarchar(50)





    Num
    nvarchar(50)





    供应单位信息表



    表名: NeedMerchant
    备注:需求商信息表







    字段名称
    数据类型
    自增主键
    允许为空
    默认值


    Id
    int





    Num
    nvarchar(50)





    Name
    nvarchar(50)





    Principal
    nvarchar(50)





    Phone
    nvarchar(50)





    IsDeliver
    bit





    Address
    nvarchar(50)





    NeedPartName
    nvarchar(50)





    NeedNum
    int





    操作日志信息表



    表名: Log
    备注:操作日志信息表







    字段名称
    数据类型
    自增主键
    允许为空
    默认值


    Id
    int





    Operator
    nvarchar(50)





    Time
    Datetime





    Details
    Nverchar(1000)





    Type
    nvarchar(50)





    IP
    nvarchar(50)





    4.3 功能模块设计流程图位置信息管理网站设计其功能已详细介绍,本节将详细介绍各个功能模块的设计流程图。其中登录界面程序流程图,如图4-9所示:

    网站中很多功能都涉及到修改数据,修改数据信息主要是实现前端数据与后台数据库的交互,以ID为判断条件将修改后的信息用SQL语句调用数据库修改相应的数据,刷新数据库及相应页面,显示数据库的信息。修改数据流程图如图4-11所示,

    删除数据信息,实现主要是根据删除按钮或是全选删除按钮的点击事件获取相应的要删除信息的ID,然后根据ID利用SQL语句删除数据库中的数据,更新数据库。删除程序主要流程图,如图4-12所示:

    增加数据信息的功能主要是将表单中的数据提交到后台数据库中,在由后台对数据做相应的判断,若不符合要求,则显示增加不成功,不保存到数据库,否则将数据保存到相应数据库。增加数据信息的程序流程图,如图4-14所示:

    4.4 软件界面设计本节将系统展示位置信息管理网站设计完成后页面的完成情况,及大致的布局。其中登录界面如图4-16所示:

    第5章 系统编码与测试5.1 系统编码1.数据库连接代码
    <add name="MainConn"connectionString="server=.;database=CarParts;user=sa;pwd=0301;Max Pool Size=512;" provider Name="System.Data.SqlClient"/>
    2.登录界面核心代码
    <form> <label for="username">用户名</label> <input name="username" type="text" placeholder="请输入用户名" id="name"/> <label for="pass">密码</label> <input name="pass" type="password" placeholder="请输入密码" id="password"/> <input value="登录" id="submit" /></form>
    3.登录后台核心代码
    using System.Data;using System.Data.SqlClient;using System.Linq;using System.Text;using System.Web;using System.Web.SessionState;namespace WebApp{ /// <summary> /// LoginHandler 的摘要说明 /// </summary> public class LoginHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //获取用户名和密码 string name = context.Request["name"]; string password = context.Request["password"]; //获取数据库数据,放置在ds中 StringBuilder sb = new StringBuilder(); sb.AppendLine("SELECT TOP 1 UserId,UserName,Password,Type,LoginTime,Department "); sb.AppendLine("FROM Users"); sb.AppendLine("WHERE UserName = @UserName AND Password = @Password; "); SqlParameter[] pms = { new SqlParameter("@UserName",SqlDbType.NVarChar,50), new SqlParameter("@Password",SqlDbType.NVarChar,50) }; pms[0].Value = name; pms[1].Value = password; DataSet ds = DbHelperSQL.Query(sb.ToString(),pms); //判断表中是否存在数据,如果有数据则登录成功,如果没有数据,则登录失败 if (ds.Tables[0].Rows.Count > 0) { //根据判断选择进入哪个主页,无论进来的管理员或者是普通用户都记录下操作者的ID,方便记录日志 if (ds.Tables[0].Rows[0]["Type"].ToString() == "1") { context.Session["Id"] = ds.Tables[0].Rows[0]["UserId"].ToString(); context.Session["LoginTime"] = DateTime.Now.ToString(); context.Response.Write("ok1:登录成功"); } else { context.Session["Id"] = ds.Tables[0].Rows[0]["UserId"].ToString(); context.Session["LoginTime"] = DateTime.Now.ToString(); context.Response.Write("ok2:登录成功"); } } //验证失败弹出提示框 else { context.Response.Write("用户名或密码错误,请重新登录"); } } public bool IsReusable { get { return false; } } }}
    4.一级管理员首页界面前端核心代码
    <div class="easyui-layout" style="width:960px; height:800px;margin:50px auto;"> <%--采用easy-ui布局--%> <%--头部导航--%> <div data-options="region:'north',border:false" class="top_bar"> <h1>汽车仓储管理系统</h1> </div> <%--头部导航结束--%> <%--左侧的切换选择--%> <div data-options="region:'west',split:true,title:'信息总览'" class="left_nav"> <ul class="main_nv"> <li class="nv_item"><a href="javascript:void(0)" class="linkToPage" url="InfoPage/PartsInfo.aspx">配件信息</a></li> <li class="nv_item"><a href="javascript:void(0)" class="linkToPage" url="InfoPage/Supplies.aspx">供应商信息</a></li> <li class="nv_item"><a href="javascript:void(0)" class="linkToPage" url="InfoPage/NeedMerchant.aspx">需求商信息</a></li> <li class="nv_item"><a href="javascript:void(0)" class="linkToPage" url="InfoPage/Manager.aspx">管理员信息</a></li> <li class="nv_item"><a href="javascript:void(0)" class="linkToPage" url="InfoPage/Log.aspx">操作日志</a></li> </ul> </div> <%--左侧的切换选择结束--%> <%--底部标注信息--%> <div data-options="region:'south',border:false" class="bottom_bar"> <h3>此系统仅供本公司人员使用</h3> </div> <%--底部标注信息结束--%> <%--核心内容展示区域--%> <div data-options="region:'center',title:'信息管理'" class="right"> <div class="easyui-tabs" style="width:700px;height:250px;" class="right" fit="true" id="tt"> <div title="配件信息" style="padding:10px;overflow:hidden;"class="right"> <iframe src="InfoPage/PartsInfo.aspx" scrolling="no" width="100%" height="100%" frameborder="0"></iframe> </div> </div> </div> <%--核心内容展示区域结束--%></div>
    5.二级管理员首页界面核心代码
    <h1 class="top_title" style="margin-bottom:100px;text-align:center;">汽车配件的出库/入库</h1> <form id="form1" runat="server"> <div> <%--<asp:Button ID="btnAdd" runat="server" Text="添加" />--%><%---------------------------------需求商信息--------------------------------------------------%> <asp:GridView ID="gvNeedMer" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" AllowPaging="True" OnPageIndexChanging="gvParts_PageIndexChanging"> <Columns> <asp:CheckBoxField DataField="IsDeliver" HeaderText="已发货" /> <asp:BoundField DataField="Num" HeaderText="编号" /> <asp:TemplateField HeaderText="单位名称"> <ItemTemplate> <a id="linkToPartInfoEdit" target="_blank" href="javascript:linkToPart(<%# Eval("Id") %>)"> <%#Eval("Name") %> </a> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="Principal" HeaderText="负责人" /> <asp:BoundField DataField="Address" HeaderText="地址" /> <asp:BoundField DataField="Phone" HeaderText="联系电话" /> <asp:TemplateField HeaderText="添加"> <ItemTemplate> <input type="button" id="btnAdd" value="添加"/> </ItemTemplate> </asp:TemplateField> </Columns> <%--添加分页--%> <PagerTemplate> 当前第: <%--//((GridView)Container.NamingContainer)就是为了得到当前的控件--%> <asp:Label ID="LabelCurrentPage" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageIndex + 1 %>"></asp:Label> 页/共: <%-- //得到分页页面的总数--%> <asp:Label ID="LabelPageCount" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageCount %>"></asp:Label> 页 <%--//如果该分页是首分页,那么该连接就不会显示了.同时对应了自带识别的命令参数CommandArgument--%> <asp:LinkButton ID="LinkButtonFirstPage" runat="server" CommandArgument="First" CommandName="Page" Visible='<%#((GridView)Container.NamingContainer).PageIndex != 0 %>'>首页</asp:LinkButton> <asp:LinkButton ID="LinkButtonPreviousPage" runat="server" CommandArgument="Prev" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != 0 %>'>上一页</asp:LinkButton> <%--//如果该分页是尾页,那么该连接就不会显示了--%> <asp:LinkButton ID="LinkButtonNextPage" runat="server" CommandArgument="Next" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>下一页</asp:LinkButton> <asp:LinkButton ID="LinkButtonLastPage" runat="server" CommandArgument="Last" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>尾页</asp:LinkButton> 转到第 <asp:TextBox ID="txtNewPageIndex" runat="server" Width="20px" Text='<%# ((GridView)Container.Parent.Parent).PageIndex + 1 %>'/>页 <%--//这里将CommandArgument即使点击该按钮e.newIndex 值为3--%> <asp:LinkButton ID="btnGo" runat="server" CausesValidation="False" CommandArgument="-2" CommandName="Page" Text="Go"/> </PagerTemplate> </asp:GridView><%---------------------------------需求商信息结束--------------------------------------------------%><%---------------------------------配件信息表--------------------------------------------------%> <div class="input_info" style="width:620px;margin:15px auto;color:white;"> <span>操作类型:</span> <asp:DropDownList ID="ddlType" runat="server"> <asp:ListItem>入库</asp:ListItem> <asp:ListItem>出库</asp:ListItem> </asp:DropDownList> <span>编号:</span> <asp:TextBox runat="server" ID="txtNum"></asp:TextBox> <span>数量:</span> <asp:TextBox runat="server" ID="txtQuantity"></asp:TextBox> <div class="direction"> <span>需求商编号:</span> <asp:TextBox runat="server" ID="txtNeedMerchant"></asp:TextBox> </div> <asp:Button runat="server" Text="确认" ID="btnConfirm" OnClick="btnConfirm_Click"></asp:Button> </div> <asp:GridView ID="gvParts" runat="server" DataKeyNames="PartId" AutoGenerateColumns="False" AllowPaging="True" OnPageIndexChanging="gvParts_PageIndexChanging"> <Columns> <asp:BoundField DataField="Num" HeaderText="编号" /> <asp:BoundField DataField="PartName" HeaderText="名称" /> <asp:BoundField DataField="Name" HeaderText="生产单位" /> <asp:BoundField DataField="InTime" HeaderText="入库时间" /> <asp:BoundField DataField="Quantity" HeaderText="数量" /> <asp:BoundField DataField="UnitPrice" HeaderText="单价" /> </Columns> <%--添加分页--%> <PagerTemplate> 当前第: <%--//((GridView)Container.NamingContainer)就是为了得到当前的控件--%> <asp:Label ID="LabelCurrentPage" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageIndex + 1 %>"></asp:Label> 页/共: <%-- //得到分页页面的总数--%> <asp:Label ID="LabelPageCount" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageCount %>"></asp:Label> 页 <%--//如果该分页是首分页,那么该连接就不会显示了.同时对应了自带识别的命令参数CommandArgument--%> <asp:LinkButton ID="LinkButtonFirstPage" runat="server" CommandArgument="First" CommandName="Page" Visible='<%#((GridView)Container.NamingContainer).PageIndex != 0 %>'>首页</asp:LinkButton> <asp:LinkButton ID="LinkButtonPreviousPage" runat="server" CommandArgument="Prev" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != 0 %>'>上一页</asp:LinkButton> <%--//如果该分页是尾页,那么该连接就不会显示了--%> <asp:LinkButton ID="LinkButtonNextPage" runat="server" CommandArgument="Next" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>下一页</asp:LinkButton> <asp:LinkButton ID="LinkButtonLastPage" runat="server" CommandArgument="Last" CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>尾页</asp:LinkButton> 转到第 <asp:TextBox ID="txtNewPageIndex" runat="server" Width="20px" Text='<%# ((GridView)Container.Parent.Parent).PageIndex + 1 %>'/>页 <%--//这里将CommandArgument即使点击该按钮e.newIndex 值为3--%> <asp:LinkButton ID="btnGo" runat="server" CausesValidation="False" CommandArgument="-2" CommandName="Page" Text="Go"/> </PagerTemplate> </asp:GridView> </div></form>
    6.二级管理员首页后台核心代码
    protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindData(); } } //绑定gvParts和gvNeed public void BindData() { //查询数据 StringBuilder sb = new StringBuilder(); sb.AppendLine("SELECT C.PartId,C.Num,C.PartName,S.Name,C.InTime,C.Quantity,C.UnitPrice"); sb.AppendLine("FROM CarParts AS C INNER JOIN Supplies AS S"); sb.AppendLine("ON C.FromDepartId = S.Id;"); DataSet ds = DbHelperSQL.Query(sb.ToString()); //将数据绑定到gvParts上展示 gvParts.DataSource = ds.Tables[0]; gvParts.DataBind(); //查询数据并绑定显示,绑定需求商表 string sql = "SELECT Id,IsDeliver,Num,Name,Principal,Address,Phone FROM NeedMerchant;"; DataSet dsNeed = DbHelperSQL.Query(sql); gvNeedMer.DataSource = dsNeed; gvNeedMer.DataBind(); } //分页 protected void gvParts_PageIndexChanging(object sender, GridViewPageEventArgs e) { // 得到该控件 GridView theGrid = sender as GridView; int newPageIndex = 0; if (e.NewPageIndex == -3) { //点击了Go按钮 TextBox txtNewPageIndex = null; //GridView较DataGrid提供了更多的API,获取分页块可以使用BottomPagerRow 或者TopPagerRow,当然还增加了HeaderRow和FooterRow GridViewRow pagerRow = theGrid.BottomPagerRow; if (pagerRow != null) { //得到text控件 txtNewPageIndex = pagerRow.FindControl("txtNewPageIndex") as TextBox; } if (txtNewPageIndex != null) { //得到索引 newPageIndex = int.Parse(txtNewPageIndex.Text) - 1; } } else { //点击了其他的按钮 newPageIndex = e.NewPageIndex; } //防止新索引溢出 newPageIndex = newPageIndex < 0 ? 0 : newPageIndex; newPageIndex = newPageIndex >= theGrid.PageCount ? theGrid.PageCount - 1 : newPageIndex; //得到新的值 theGrid.PageIndex = newPageIndex; //重新绑定 BindData(); } protected void btnConfirm_Click(object sender, EventArgs e) { //为操作日志做好准备 //获取输入编号数量和出库方向 string Num = txtNum.Text; int Quantity = Convert.ToInt32(txtQuantity.Text); string NeederNum = txtNeedMerchant.Text; //根据写入的编号获取配件的名称 string sqlGetPName = "Select PartName from CarParts where Num = @Num;"; SqlParameter[] pmsGetPName = { new SqlParameter("@Num",SqlDbType.NVarChar,50), }; pmsGetPName[0].Value = Num; DataSet dsGetPName = DbHelperSQL.Query(sqlGetPName, pmsGetPName); string pName = dsGetPName.Tables[0].Rows[0]["PartName"].ToString(); //根据写入的编号获取需求商的名称 string nName = ""; if (NeederNum != "") { string sqlGetNName = "Select Name from NeedMerchant where Num = @Num;"; SqlParameter[] pmsGetNName = { new SqlParameter("@Num",SqlDbType.NVarChar,50), }; pmsGetNName[0].Value = NeederNum; DataSet dsGetNName = DbHelperSQL.Query(sqlGetNName, pmsGetNName); nName = dsGetNName.Tables[0].Rows[0]["Name"].ToString(); } //获取用户登录的Id,并获取登录用户的相关信息 int id = Convert.ToInt32(Session["Id"]); DateTime date = Convert.ToDateTime(Session["LoginTime"]); if (id == 0) { id = 2; } string sqlUsers = "Select UserName,Department from Users where UserId = @id;"; SqlParameter[] pms = { new SqlParameter("@id",SqlDbType.Int), }; pms[0].Value = id; DataSet ds = DbHelperSQL.Query(sqlUsers,pms); string type = ddlType.SelectedValue; //插入日志列表 string sqlInsertLog = "insert into Log(Operator,Department,Type,Details,Time,IP)" + " Values(@Operator,@Department,@Type,@Details,getDate(),@IP)"; SqlParameter[] pmsInsertLog = { new SqlParameter("@Operator",SqlDbType.NVarChar,50), new SqlParameter("@Department",SqlDbType.NVarChar,50), new SqlParameter("@Type",SqlDbType.NVarChar,50), new SqlParameter("@Details",SqlDbType.NVarChar,50), new SqlParameter("@IP",SqlDbType.NVarChar,50) }; pmsInsertLog[0].Value = ds.Tables[0].Rows[0]["UserName"]; pmsInsertLog[1].Value = ds.Tables[0].Rows[0]["Department"]; pmsInsertLog[2].Value = type; if (type == "入库") { pmsInsertLog[3].Value = Num + pName + type + Quantity + "件"; } else { pmsInsertLog[3].Value = Num + pName + type + "至" + nName + Quantity + "件"; } pmsInsertLog[4].Value = GetIP(); DbHelperSQL.ExecuteSql(sqlInsertLog,pmsInsertLog); //根据下拉选择不同,有出库和入库两个选择,然后进行不同的操作 //入库操作 if (ddlType.SelectedValue == "入库") { //更改数据库数据 string sql = "update CarParts set Quantity = Quantity + @Quantity where Num = @Num"; SqlParameter[] pms2 = { new SqlParameter("@Quantity",SqlDbType.Int), new SqlParameter("@Num",SqlDbType.NVarChar,50) }; pms2[0].Value = Quantity; pms2[1].Value = Num; DbHelperSQL.ExecuteSql(sql,pms2); //插入操作日志 Response.Redirect("Index2.aspx"); } //出库操作 else { string sql = "update CarParts set Quantity = Quantity - @Quantity where Num = @Num"; SqlParameter[] pms1 = { new SqlParameter("@Quantity",SqlDbType.Int), new SqlParameter("@Num",SqlDbType.NVarChar,50) }; pms1[0].Value = Quantity; pms1[1].Value = Num; DbHelperSQL.ExecuteSql(sql, pms1); //更改需求商的是否发货状态 string sqlUpdate = "update NeedMerchant set IsDeliver = 'True' where Num = @NeedNum;"; SqlParameter[] pars = { new SqlParameter("@NeedNum",SqlDbType.NVarChar,50) }; pars[0].Value = NeederNum; DbHelperSQL.ExecuteSql(sqlUpdate,pars); Response.Redirect("Index2.aspx"); } } //获取Ip public string GetIP() { string result = String.Empty; result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (string.IsNullOrEmpty(result)) { result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } if (string.IsNullOrEmpty(result)) { result = HttpContext.Current.Request.UserHostAddress; } if (string.IsNullOrEmpty(result)) { return "127.0.0.1"; } return result; }
    5.2 系统测试为了保证设计完成后的软件是有效的,健壮的,在软件开发的生命周期中要对软件进行测试,测试工作可以验证软件的需求是否都得以实现,软件是否正确地提供了需要的功能,以及软件是否能健壮稳定地运行。所以,本网站的测试主要以如下几方面为切入点:

    一、功能验收测试:对应软件的需求分析和详细设计文档,检查系统所应该实现的功能是否已经实现。对于一个软件,完成并能够使用的最基本条件是所有的功能都能覆盖,并且功能能够成功执行。 二、集成验收测试:在保证了每个功能都实现并可用之后,需要验证系统的每个功能的正确性,于是进一步的测试则要保证每一个功能的每种可能执行方式 都能得到正确的结果。这样我们才可以说,对外发布的系统是一个正确的系统。 三、健壮性、稳定性及性能测试:为了让系统能够稳定的高效运行,需要对系统进行以下的测试。如,选择一些非正常的输入,这时系统需要能继续稳定运 行,或者很容易从错误中自动恢复;当长时间的进行持续的操作时,系统对资源 的消耗应该处于稳定的,可接受的范围内,尤其要避免内存泄露等问题带来的风险;系统还要达到需求分析文档中所规定的性能指标,所以还要针对实际情况进 行性能测试;最后系统还要根据需要对不同平台、不同环境的兼容性进行测试。 整个系统需要测试的模块主要有登录模块,一级管理员的管理模块,二级管理员的管理模块。
    系统测试:功能测试、性能测试、验收测试。目的是为了保证所实现的系统确实是用户所需要的。
    登录验证,当用户名或密码不输入时提示用户重新输入,以及当用户输入的用户名和密码不匹配时,提示重新输入。当输入的是一级管理员则进入一级管理员首页,当输入的是二级管理员进入二级管理员首页。

    添加配件

    点击配件名称,弹出编辑界面

    勾选点击删除按钮便可以对信息进行删除

    填写入库信息后点击确定,该汽车配件数量增加
    参考文献[1] Karli Watson著,齐立波译,C#入门经典(第6版),2014-8
    [2] (美)内格尔(Nagel.C)等所著,C#高级编程,2008-10-1
    [3] 明日科技 著,ASP.NET从入门到精通,2012-09
    [4] 王珊,萨师煊.数据库系统概论(第四版).高等教育出版社,2006.5
    [5] ASP.NET 入门经典(第9版),2016-11
    [6] Baron Scbwartz.高性能MySQL(第3版)[M].电子工业出版社,2013
    [7] (美)加洛韦 等著,ASP.NET MVC5高级编程(第5版),2015-02
    [8] 构建之法 现代软件工程(第二版),2015-07
    [9] 王国辉,王毅.数据库系统开发案例精选[M].人民邮电出版社,2006
    [10] 软件工程:实践者的研究方法(原书第8版),2016-11
    1 评论 8 下载 2018-09-26 18:38:29 下载需要21点积分
  • 基于C语言的外卖管理系统

    一. 设计目的此次课设我的主题是外卖管理系统,则希望可以模拟网上订餐,店家工作,专人管理的过程。并实现注册与登录以及基本信息的输出。
    二. 设计内容系统分为三端登录,分别为管理员,用户以及店主;两端注册,分别为用户以及店铺,其中店铺的注册成功需要得到管理员的审核。
    管理员可以实现店铺的增删改查以及自己信息的查看修改和处理,其中,密码修改需要输入旧的密码,三次错误可以找回密码,输入手机号,若手机号匹配得当,则可产生三位数的随机验证码,输入验证码可修改密码。用户可以实现菜品查看与购买,订单查看以及修改,(但对于已超过三分钟的订单不能修改,因为已经配送),本人信息查看以及修改,若查看订单时统计总消费为0,则提示去购买菜品。店家可以实现菜品增加删除查看,业绩的查看,业绩为0时可提示自我反思和提升。
    在本系统中,限制了用户的余额,当购买时余额不足时,需要进行账户的充值,而购买结束后,账户的余额也会相应的减少,这也正是本系统的重要部分,因为网上订餐主要就是体现在其的购买上。
    三.概要设计
    管理员端可以查看店铺信息,店铺信息修改(分为增删改查),处理申请店铺,和修改本人信息
    用户端分为用户相关(为用户本人对自己信息的操作),查看订单,查看菜品,购买菜品,以及订单排序
    管理员端为增添菜品,删除菜品,修改菜品,查看菜品以及业绩查看(统计总订单与总收入)
    注册分为用户注册和点击注册,其中店家注册需要的到管理员的认证,认证通过之后才可登录

    3.1 功能模块图
    3.2 各个模块详细的功能描述
    管理员登录:管理员可以查看店铺信息,处理店铺(包括店铺的增加删除和录入),认证店铺(认证申请的店铺),查看本人信息,修改本人信息(分为修改电话,修改地址,修改密码,其中修改密码需输入就得密码,当时那次输入不正确的时候可以找回密码)
    用户登录:用户可以查看所有的菜品,可以够买菜品(购买时字需要输入菜的种类或者菜名就可以搜索到相应的菜,购买之后需扣除余额,余额不足时会提示购买失败,以及月充值)。查看订单,即统计输出所有的订单,当没有订单时会提示去购买。订单排序分为按才菜名升序以及按总价降序
    店家登录:可以查看本家的菜品,可以增加或者删除本家的菜品,可以修改菜品的名称,单价以及菜系,查看业绩,即统计输出用户在本店产生的所有的订单
    注册:分为用户注册以及店家注册,其中用户注册时当用户名有重复时提示重新输入,当设置的密码不足8位时提示可以修改或者放弃修改,输入完基本信息之后需要绑定银行卡和设置支付密码,当银行卡不足15位时提示重新输入。注册成功之后即可返回登录。店家输入完基本信息之后,需要得到管理员的审核,当审核成功之后才可登录

    四、详细设计4.1 功能函数的调用关系图
    4.2 各功能函数的数据流程图4.2.1 用户申请
    4.2.2 店铺删除
    4.2.3 菜品查找
    4.2.4 店铺订单统计
    4.3 重点设计及编码4.3.1 找回密码修改密码连续三次输错旧密码可以找回密码,输入绑定的电话号正确即可发送验证码到文件,输入正确的验证码即可重新输入新密码。

    4.3.2 购买时余额不足提示充值
    4.3.3 通过调用时间函数修改订单的数量时有时间限制,超过三分钟即提示订单已经配送不可修改,为超过三分钟则提示尽快修改
    五、测试数据及运行结果5.1 正常测试数据和运行结果5.1.1 输出店铺
    5.1.2 删除店铺
    5.1.3 输出并统计店铺订单
    5.1.4 查看本家店铺菜品
    5.1.5 添加菜品
    5.2 异常测试数据及运行结果5.2.1 注册用户
    5.2.2 购买菜品余额不足时
    2 评论 91 下载 2018-10-21 15:23:43 下载需要13点积分
显示 45 到 60 ,共 15 条
eject