分类

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

资源列表

  • 基于ASP.NET和Sql Server实现的读书平台网站

    1 课程设计目的综合运用软件工程思想、面向对象分析和设计方法、ASP.NET、数据库等基础知识,完成一个B/S架构的Web应用程序,掌握应用ASP.NET技术开发中小型网站的相关知识和技术。
    2 课程设计内容针对一个咸鱼读书网系统项目需求,利用数据库管理系统(Microsoft Sql Server 2012),构建项目数据库系统。利用 Visual Studio 集成开发环境,采用ASP.NET技术、C#语言、WEB Forms窗体设计技术、LINQ数据访问技术、三层架构等,完成系统界面设计和功能开发,并对系统进行功能测试。
    3 课程设计工具和平台
    Microsoft Sql Server 2012
    Microsoft Visual Studio 2013
    Windows 7操作系统
    PC机一台
    实验/课程设计项目指导书和相关参考书籍,网络资源等

    4 项目开发步骤逻辑层的逻辑判断和数据层的部分判断。大致有用户登录信息的匹配,用户注册是否重复,用户留言是否多次对同一本留言,按时间或者评分对图书的排序,评分的计算方法,留言内容的写入。
    一开始的时候只想到数据层访回图书类组给逻辑层,但是没想到当查询数量为空时的返回值,所以当时我就走去在数据层自己写几个关于结果为空时的返回函数,这也是分工前对自己的需求不明确导致后来大家都有点乱和耽误了进度。
    4.1 需求分析(功能模块分析与数据库设计)4.1.1 系统功能分析从实体类中得知类的类名和有关的数据类型,完成以下逻辑功能。
    当进入页面的导航栏有三个有关按序查书的功能


    读书:按数据库的默认查询排序
    最新书籍:按图书的上传时间排序(由大到小)
    精彩书籍:按图书的评分排序(由高到低)

    其中首页中的图书显示也是根据这两个排序取靠前几个来完成展示:最新书籍的六本流水形式展示的图书是按照最新书籍的类组的前六个类组显示,同理,精彩图书则按照精彩书籍的类组的前三个类组显示。
    用户登录与留言评分
    在查询书本信息之前需要登录用户,评论的信息将会存到一个表中,如果重复评论打分一本书则会出现相应的提示。

    图书信息

    通过页面反馈ISBN码进行图书信息查询,获得图书类,图片显示和作品简介都是以文件路径的形式在数据库储存,所以获取之后还要进行一番读文件流。

    按需查询书籍
    通过LINQ进行模糊查询,自动适应书名、作者或者ISBN的关键字查询功能。

    4.1.2 数据库和表设计建立构建数据库:主要有书籍信息表,留言表和用户表。

    书籍信息表:书名,作者,出版社,时间,页数,价格,ISBN,图片地址,评分,简介地址。



    字段名
    数据类型
    备注




    BookName
    varchar(50)
    主键


    Writer
    varchar(50)



    PublishingHouse
    varchar(50)



    Time
    date



    Page
    int



    price
    float



    ISBN
    char(15)



    Photo
    varchar(500)



    Score
    float



    Introduction
    varchar(500)



    留言表:有ISBN码标识所留言的书本,留言板会显示用户名,留言信息,时间和打分分数,最后在设置一个自增的number,如果没有这个自增number作为主键。起初使用UserID为主键,可能所有书都存在都一表中,所以写留言到数据库留言表的时候,会发生主键冲突,所以设置这个自增量number。



    字段名
    数据类型
    备注




    ISBN
    char(40)



    UserID
    char(5)



    TextContent
    char(100)



    PostTime
    date



    Score
    float



    number
    int
    主键



    用户表:用户的账号和密码,其中可填写Email。



    字段名
    数据类型
    备注




    UserID
    char(5)
    主键


    PassWord
    char(15)



    Email
    char(20)
    允许为空



    在最后一天整合代码时发生一个关于图片的路径的问题,因为我在逻辑层写函数使用GridView控件调试数据,在GridView中图片路径使用“~\img\xxxx.jpg”带有波浪号形式的路径是可以在GridView中正确显示相对路径的图片,但在前端的src上就显示不了,得使用“\img\xxx.jpg”去掉“~”的形式才能正确找到相对路径的图片。
    数据库导入关系和各表的主键设计

    4.2 系统设计与实现4.2.1 用户逻辑的实现用户登录与注册的信息判断(ID和密码匹配,注册账号不重复)。
    从数据库中通过LINQ 在表中查询是否存在匹配的信息,返回return或者false用户处理信息。相关代码如下:
    public class UserOperation{ //登录操作 public bool Sign_in(Customer register) { UserData user = new UserData(); //判断登录是否成功 if (user.JudgeUser(register)) { return true; } else { return false; } } //注册操作 public bool Sign_up(Customer register) { UserData user = new UserData(); //账号或者密码不能为空 if(String.IsNullOrEmpty(register.UserID) || String.IsNullOrEmpty(register.PassWord)) { return false; } //当前账号不存在时 if (user.JudgeRegister(register)) { user.Add(register); return true; } else { } }
    4.2.2 图书排序的实现图书的排序(最新图书和精彩图书)
    //时间比较int CompareTime(BookMessage a, BookMessage b){ return b.Time.CompareTo(a.Time);}//评分比较int CompareScore(BookMessage a,BookMessage b){ return b.Score.CompareTo(a.Score);}
    4.2.3 模糊查询的实现模糊查询

    相关代码如下:
    //模糊查询(ISBN,书名,作者)public IList<BookMessage> Fuzzy_Search(string text){ List<BookMessage> search_books = new List<BookMessage>(); //定义书本数组 //根据书本的ISBN、书名、作者 关键字 进行查询 var result = from r in BookDB.Book where (r.ISBN.Contains(text)) || (r.BookName.Contains(text)) || (r.Writer.Contains(text)) select r; foreach(var r in result) { BookMessage bookmessage = new BookMessage(); bookmessage.ISBN = r.ISBN; //ISBN bookmessage.BookName = r.BookName; //书名 bookmessage.Writer = r.Writer; //作者 bookmessage.Time = r.Time; //上传时间 bookmessage.Page = r.Page; //页数 bookmessage.PublishingHouse = r.PublishingHouse; //出版社 bookmessage.Price = (float)r.price; //价钱 ??(不强转float报错)?? bookmessage.Photo = r.Photo; //书本图片路径 bookmessage.Introduction = r.Introduction; //简介 bookmessage.Score = (float)r.Score; //评分默认为0 search_books.Add(bookmessage); //增加这个书本到数组 } return search_books; //返回书本BookMessage的数组}
    4.2.4 留言评分的实现发送留言以及分数计算

    相关代码如下:
    //发送留言public void PostLWord(LWord lword){ string LwordContent = lword.Leave_word; float LwordScore = lword.Score; string LwordISBN = lword.Getbook.ISBN; string LwordUserID = lword.Getcustomer.UserID; string LwordEmai = lword.Getcustomer.Email; DateTime LwordPostTime = new DateTime(); LwordPostTime = DateTime.Now; (new UserData()).PostLeaveWord(lword); (new BookData()).Average_Score((new BookData()).GetBook(LwordISBN)); //更新书本评分}//评分计算public void Average_Score(BookMessage book){ var result = from r in BookDB.LeaveWord where r.ISBN == book.ISBN select r; float sum = 0; //总分 float aver; //平均分 foreach(var r in result) { sum = sum + (float)r.Score; } aver = sum / (result.Count()); //算出平均分数 //找出图书 var result_book = from r in BookDB.Book where r.ISBN == book.ISBN select r; foreach(Book r in result_book) { r.Score = aver; //修改评分 } BookDB.SubmitChanges();}
    5 系统运行结果及测试分析成功完成咸鱼读书网系统的开发,并对系统进行了功能测试,系统运行和测试结果如下:

    留言系统能够正确录入数据库,但是时间获取失败。
    按需查询排序能够正确显示:

    原本打算读取文本在逻辑层完成,但是基于实力原因在相对路径问题上出现些解决不了的问题,在逻辑层的相关测试代码如下:
    // 读取书本简介文本转换string类型public string GetIntroductionByISBN(string isbn){ string content = ""; BookMessage getbook = (new BookData()).GetBook(isbn); // 获取书本信息 string filepath = getbook.Introduction; // 获取文本路径 using (FileStream fs = new FileStream(filepath, FileMode.open, FileAccess.Read)) { interface fsLen = (int)fsLen.Length; byte[] heByte = new byte[fsLen]; int r = fsLen.Read(heByte, 0, heByte.Length); content = System.Text.Encoding.UTF8.GetString(heByte); } return content; }protected void Button1_Click(object sender, EventArgs e){ BookOperation introduction = new BookOperation(); string i = introduction.GetIntroductionByISBN("9787510862885"); Response.Write(i);}
    不知道出于什么原因,相对路径是在IIS的路径下,但当这些代码在.aspx中写的时候,便能正确访问相对路径,最终我们将代码写在aspx以实现功能,其原因还在探讨。

    6 总结和展望这次的ASP.NET程序设计实训,虽然时间比较紧凑,却让我所学到了很多实际运用的技能和拓展了很多课外的知识,特别是我第一次用三层架构形式小组合作,虽然在结合功能那天我们出现了一些因为沟通的漏缺和主键的问题的Bug,但是我们都积极修改代码一起合作将网站以最好的形式展现,在修改的时候更能发现小组合作的重要性,只要沟通理解正确,他们在改前端或数据库的同时我只要知道哪个值需求有更改就去改哪个值和返回什么值,在这种合作的形式下很多Bug都修好了。
    虽然这次的实训实现的功能未能如期实现,例如用户的收藏图书功能和管理员增删改图书的功能,因为这些代码在合并时都出现未能及时解决的Bug,这也是一种遗憾未能将我们的读书网以更好的形式展示,但是从中我也体会到合作成员之间明确的需求沟通重要性,在项目开始之前我们必须清楚自己需要什么参数,需要得到什么类型的值,需要返回什么类型的值等等。这些本来可以避免的问题最终还是出现了,经一事长一智,我相信通过本次三层架构的小组合作,在以后的合作实训项目会变得更好更清楚自己需要什么自己要做什么。
    1 评论 38 下载 2019-03-19 10:28:59 下载需要15点积分
  • 基于QT和websocket协议的多线程文件传输

    一、目的与要求
    做两个程序,实现文件收发
    发送端放两个按钮,点击后打开电脑目录选择所要传输的文件,选好以后,把文件名和路径显示在界面上,点击第二个按钮,把文件传到远程机器(或者虚拟机)上由接收端接收
    编写一接收端,把文件接收下来,存进指定的某个目录里
    要能测试通过三个发送端同时发100M的文件,接收端能分别接收
    使用多线程实现

    二、工具/准备工作
    Qt开发环境
    websocket传输协议库
    Win10_x64

    三、分析UI界面设计,使用qtdesigner工具,设计界面如下:
    Server端

    Client端


    多线程实现
    Qt中提供了创建线程的基类,并且新创建dialog默认为多线程,利用此特性,可以实现通过创建多个dialog从而实现多个client与服务器同时传输文件。
    文件传输协议
    使用Websocket协议,实现客户端与服务端的长连接,并且可以双方相互主动推送文本消息或文件流。
    四、实现步骤
    创建项目
    编写客户端主线程程序,为按钮添加创建窗口消息相应事件



    子线程程序


    文件传输协议代码
    /********************************************************************************************************************************************************/#include "sslechoclient.h"#include <QtCore/QDebug>#include <QtWebSockets/QWebSocket>#include <QCoreApplication>#include <iostream>#include <QDebug>#include <QFile>#include <QJsonObject>#include <QJsonDocument>#include <QMessageBox>#include <QTextStream>#include <QPushButton>#include <QFileInfo>using namespace std;QT_USE_NAMESPACE//! [constructor]SslEchoClient::SslEchoClient(const QUrl &url, QObject *parent) : QObject(parent){ ssl_dia.show(); QCoreApplication::processEvents(); connect(&m_webSocket, &QWebSocket::connected, this, &SslEchoClient::onConnected); typedef void (QWebSocket:: *sslErrorsSignal)(const QList<QSslError> &); connect(&m_webSocket, static_cast<sslErrorsSignal>(&QWebSocket::sslErrors), this, &SslEchoClient::onSslErrors); m_webSocket.open(QUrl(url));}void SslEchoClient::onConnected(){ m_webSocket.sendTextMessage(QStringLiteral("Hello, world! Server,I'am client!")); connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &SslEchoClient::onTextMessageReceived); connect(ssl_dia.m_pushButton, &QPushButton::clicked,this, &SslEchoClient::sendMessage); connect(ssl_dia.m_pushButton_2, &QPushButton::clicked,this, &SslEchoClient::sendFile);}void SslEchoClient::onTextMessageReceived(QString message){ ssl_dia.m_textEdit->setPlainText(message);}void SslEchoClient::onSslErrors(const QList<QSslError> &errors){ Q_UNUSED(errors); // WARNING: Never ignore SSL errors in production code. // The proper way to handle self-signed certificates is to add a custom root // to the CA store. qDebug() << "ssl Error!"; m_webSocket.ignoreSslErrors();}void SslEchoClient::sendMessage(){ QString message = ssl_dia.m_textEdit->toPlainText(); m_webSocket.sendTextMessage(message);}void SslEchoClient::sendFile(){ try{ QString path = QFileDialog::getOpenFileName(&ssl_dia, tr("Select File To Send"),".",tr("File(*)")); if(path.length()<1) return; QFileInfo info(path); QString file_name = info.fileName(); //文件发送消息标记协议 m_webSocket.sendTextMessage("f:" + file_name); QFile file(path); if(!file.open(QIODevice::ReadOnly)) { qDebug() << "Can't open file for writing"; return; }// out.setVersion(QDataStream::Qt_5_8); qDebug() << "read"; QByteArray byte = file.readAll(); m_webSocket.sendBinaryMessage(byte); qDebug() << "send"; file.close(); }catch(exception e){ e.what(); }}

    服务端消息发送预处理程序
    /********************************************************************************************************/#include "sslechoclient.h"#include <QtCore/QDebug>#include <QtWebSockets/QWebSocket>#include <QCoreApplication>#include <iostream>#include <QDebug>#include <QFile>#include <QJsonObject>#include <QJsonDocument>#include <QMessageBox>#include <QTextStream>#include <QPushButton>#include <QFileInfo>using namespace std;QT_USE_NAMESPACE//! [constructor]SslEchoClient::SslEchoClient(const QUrl &url, QObject *parent) : QObject(parent){ ssl_dia.show(); QCoreApplication::processEvents(); connect(&m_webSocket, &QWebSocket::connected, this, &SslEchoClient::onConnected); typedef void (QWebSocket:: *sslErrorsSignal)(const QList<QSslError> &); connect(&m_webSocket, static_cast<sslErrorsSignal>(&QWebSocket::sslErrors), this, &SslEchoClient::onSslErrors); m_webSocket.open(QUrl(url));}void SslEchoClient::onConnected(){ m_webSocket.sendTextMessage(QStringLiteral("Hello, world! Server,I'am client!")); connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &SslEchoClient::onTextMessageReceived); connect(ssl_dia.m_pushButton, &QPushButton::clicked,this, &SslEchoClient::sendMessage); connect(ssl_dia.m_pushButton_2, &QPushButton::clicked,this, &SslEchoClient::sendFile);}void SslEchoClient::onTextMessageReceived(QString message){ ssl_dia.m_textEdit->setPlainText(message);}void SslEchoClient::onSslErrors(const QList<QSslError> &errors){ Q_UNUSED(errors); // WARNING: Never ignore SSL errors in production code. // The proper way to handle self-signed certificates is to add a custom root // to the CA store. qDebug() << "ssl Error!"; m_webSocket.ignoreSslErrors();}void SslEchoClient::sendMessage(){ QString message = ssl_dia.m_textEdit->toPlainText(); m_webSocket.sendTextMessage(message);}void SslEchoClient::sendFile(){ try{ QString path = QFileDialog::getOpenFileName(&ssl_dia, tr("Select File To Send"),".",tr("File(*)")); if(path.length()<1) return; QFileInfo info(path); QString file_name = info.fileName(); //文件发送消息标记协议 m_webSocket.sendTextMessage("f:" + file_name); QFile file(path); if(!file.open(QIODevice::ReadOnly)) { qDebug() << "Can't open file for writing"; return; }// out.setVersion(QDataStream::Qt_5_8); qDebug() << "read"; QByteArray byte = file.readAll(); m_webSocket.sendBinaryMessage(byte); qDebug() << "send"; file.close(); }catch(exception e){ e.what(); }}
    五、测试服务器窗口

    客户端主程序窗口

    客户端简历连接后窗口

    建立多个线程

    选择发送文件

    文件发送成功

    六、总结
    熟悉了网络传输协议WEBSOCKET,该协议可以在客户端与服务器之间建立长连接,并且可以双方互发信息,相比于HTTP协议,该协议更适合用于作为如聊天工具、视频直播等数据交互的领域
    进一步熟悉了QT编程,大一的时候使用过VC编写图形化界面,相比之下,QT更简单高效,并且轻量化,个人更倾向于使用QT编程
    2 评论 22 下载 2018-10-31 10:27:43 下载需要11点积分
  • 基于C++的库存管理系统设计与实现

    一 需求分析1.1 总体要求运用面向对象程序设计知识,利用C++语言设计和实现一个“库存管理系统设计”,主要完成对商品的销售、统计和简单管理。在实现过程中,需利用面向对象程序设计理论的基础知识,充分体现出C++语言关于类、继承和封装等核心概念,每一个类应包含数据成员和成员函数。
    1.2 功能分析超市中商品分为四类,分别是食品、化妆品、日用品和饮料。每种商品都包含商品名称、价格、库存量和品牌等信息。
    本系统要求具备如下主要功能:
    1.2.1 商品简单管理功能
    添加功能:主要完成商品基本信息的添加
    查询功能:可按商品类别、商品名称、生产厂家、进货日期进行查询。若存在相应信息,输出所查询的信息,若不存在该记录,则提示“该记录不存在!”
    修改功能:可根据查询结果对相应的记录进行修改
    删除功能:主要完成商品信息的删除。先输入商品类别,再输入要删除的商品名称,根据查询结果删除该物品的记录,如果该商品不在物品库中,则提示“该商品不存在”

    1.2.2 进货功能按要求添加相应商品的信息到库存中。可按要求输入商品编号,商品名称,生产厂家,商品价格,商品数量,商品类别,入库时间等商品基本信息。
    1.2.3 出货功能出货时可按照商品名称查找相应商品,显示相关商品库存量等基本信息。若有库存量则输入出售数量,出售价格以及出库时间,计算销售额,利润。如果库存量不足则提示出货失败,结束出货。
    1.2.4 统计功能输出当前库存中所有商品的总数及详细信息;能统计每种商品一周时间内的销售额和利润;能统计每类商品的一周时间内的销售额和利润。输出统计信息时,要按从大到小进行排序。(根据个人能力,至少实现一种统计功能)
    二 程序设计与实现2.1 概要设计在定义商品的类别时采用了枚举类型,并定义Food=1,因此在程序中阿拉伯数字1,2,3,4即分别代表食品,化妆品,日用品,饮料这四种商品。
    系统类的关系图如下所示:

    2.1.1 系统的类层次在定义商品基本信息时采用了结构体类型,即定义了一个structGoods,其中包含类别,名称,品牌,价格,数量等信息,同时包含struct Date表示入库时间,包含enum GoodsType表示商品类别。
    定义class GoodsManage包含各成员函数进行对商品信息的管理,其中包含DisplayMainMenu(),AddGoodsInfo(),DisplayGoodsInfo(),SearchByCode()等成员函数。
    系统的类层次关系图如下图所示:


    2.1.2 主程序流程如下图所示:

    2.2 详细设计2.2.1 各类的描述商品类别
    //商品类别enum GoodsType{ Food=1, //食品 Cosmetic, //化妆品 Commodity, //日用品 Drink //饮料};
    入库时间
    //入库时间struct Date{ int year; int month; int day;};
    ((商品基本信息**
    //商品基本信息struct Goods{ string code; //商品编号 string name; //商品名称 string brand; //生产厂家 double price; //商品价格 int num; //商品数量 GoodsType type;//商品类别 Date date; //入库时间 Goods *next;};
    商品售出信息
    //商品售出信息struct SellRecord{ Goods sellGoods; //已出售的商品 int sellNum; //出售数量 double sellPrice;//出售价格 Date date; //出库日期 SellRecord *next;};
    商品管理
    //商品管理class GoodsManage{public: GoodsManage(); ~GoodsManage(){} void DisplayMainMenu(); //主菜单显示 void AddGoodsInfo(); //添加商品信息 void DisplayGoodsInfo();//浏览商品信息 void SearchByCode(); //按照商品编号搜索商品信息 void SearchByName(); //按照商品名称搜索商品信息 void SearchByType(); //按照商品类别搜索商品信息 void SearchByBrand(); //按照商品品牌搜索商品信息 void EditGoodsInfo(); //编辑商品信息 void DeleteGoodsInfo(); //删除商品信息 void SellGoodsInfo(); //出售商品信息 void SaveGoodsInfo(); //保存商品信息private: int amount; //商品量 int DeleteAmount; Goods *head; Goods *DeleteHead;};
    2.2.2 成员函数定义构造函数
    //定义构造函数GoodsManage::GoodsManage(){ amount=0; DeleteAmount=0; head=new Goods; head->next=NULL; DeleteHead=new Goods; DeleteHead->next=NULL;}
    2.主菜单显示函数
    //定义主菜单函数void GoodsManage::DisplayMainMenu(){ cout<<" ━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆━═☆\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 欢迎使用商品库存管理系统 ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【商品进货】…(a) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【商品编辑】…(b) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【商品删除】…(c) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ ┋【按照编号查询】…(d) ┋\n"; cout<<" ┋ ┋ ┋\n"; cout<<" ┋ ┋【按照名称查询】…(e) ┋\n"; cout<<" ┋ 【商品查询】┋ ┋\n"; cout<<" ┋ ┋【按照类别查询】…(f) ┋\n"; cout<<" ┋ ┋ ┋\n"; cout<<" ┋ ┋【按照品牌查询】…(g) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【商品出货】…(h) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【商品统计】…(i) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 【信息保存】…(j) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ ┋\n"; cout<<" ┋ 退出系统…(k) ┋\n"; cout<<" ┋ ┋\n"; cout<<" ━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆┈━═☆━═☆\n"; cout<<"\n 请输入你要进行的操作编号:";}
    添加商品信息函数
    //定义添加商品信息函数voidGoodsManage::AddGoodsInfo(){ char c,c1; Goods tail=head,p; bool flag; cout<<" ☆☆☆☆☆☆现在进行商品信息的添加☆☆☆☆☆☆ "<<endl; while(tail->next!=NULL) tail=tail->next; do { flag=0; p=new Goods; cout<<"请选择商品类别:"<<endl; cout<<"1.食品 2.化妆品3.日用品 4.饮料"<<endl; cout<<"请输入相应编号:"; do { cin>>c1; if(c1>='1'&&c1<='4')//判断用户输入编号是否存在 flag=1; else { cout<<"您输入的编号不存在!"<<endl; cout<<"请选择正确的商品类别:"<<endl; } }while(flag==0);//输入编号存在时跳出循环 if(c1=='1') p->type=Food; if(c1=='2') p->type=Cosmetic; if(c1=='3') p->type=Commodity; if(c1=='4') p->type=Drink; cout<<"商品类别("<<p->type<<")"<<endl;//表示商品类别 cout<<"请输入商品编号: "; cin>>p->code; do { Goods *q=head->next; while(q!=NULL&&q->code!=p->code) q=q->next; if(q==NULL) flag=1; else { cout<<"存在该编号的货物!!!请重新输入编号:"; cin>>p->code; } }while(flag==0); cout<<"请输入商品名称:"; cin>>p->name; cout<<"请输入生产厂家:"; cin>>p->brand; cout<<"请输入商品价格:"; cin>>p->price; cout<<"请输入商品数量:"; cin>>p->num; cout<<"请输入入库时间(年/月/日):"; cin>>p->date.year>>p->date.month>>p->date.day; tail->next=p; p->next=NULL; tail=p; amount++;//商品量加一 cout<<"数据输入成功!!!想继续添加吗(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!!!<请输入y/n>"<<endl; cout<<"数据添加成功!!!想继续输入吗(y/n):"; cin>>c; } }while(c=='y'); cout<<endl; cout<<"……信息处理完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    统计商品信息函数
    //定义商品信息浏览函数void GoodsManage::DisplayGoodsInfo(){ Goods *p=head; cout<<" ☆☆☆☆☆☆现在进行商品信息的浏览☆☆☆☆☆☆ "<<endl; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; while(p->next!=NULL) { p=p->next; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } cout<<endl; cout<<"……信息统计完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    按照编号查找商品信息函数
    //按照商品编号查找商品信息void GoodsManage::SearchByCode(){ char c; Goods *p; bool flag; string FoundCode; cout<<" ☆☆☆☆☆☆现在进行商品信息的查找☆☆☆☆☆☆ "<<endl; do { p=head; flag=0; cout<<"请输入您要查找的商品编号:"; cin>>FoundCode; while(p->next!=NULL) { p=p->next; if(p->code==FoundCode) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; break; } if(flag==0) { cout<<"对不起,您查询的商品不存在!!!"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; } } } }while(c=='y'); cout<<endl; cout<<"……信息查找完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    按照名称查找商品信息函数
    //按照商品名称查找商品信息void GoodsManage::SearchByName(){ char c; Goods *p; bool flag; string FoundName; cout<<" ☆☆☆☆☆☆现在进行商品信息的查找☆☆☆☆☆☆ "<<endl; do { p=head; flag=0; cout<<"请输入您要查找的商品名称:"; cin>>FoundName; while(p->next!=NULL) { p=p->next; if(p->name==FoundName) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; break; } if(flag==0) { cout<<"对不起,您查询的商品不存在!!!"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; } } } }while(c=='y'); cout<<endl; cout<<"……信息查找完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    按照类别查找商品信息函数
    //按照商品类别查找商品信息void GoodsManage::SearchByType(){ char c; Goods *p; bool flag; int FoundType; cout<<" ☆☆☆☆☆☆现在进行商品信息的查找☆☆☆☆☆☆ "<<endl; do { p=head; flag=0; cout<<"请输入您要查找的商品类别:"; cin>>FoundType; while(p->next!=NULL) { p=p->next; if(FoundType==1&&p->type==Food) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } else if(FoundType==2&&p->type==Cosmetic) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } else if(FoundType==3&&p->type==Commodity) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } else if(FoundType==4&&p->type==Drink) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } if(flag==0) { cout<<"对不起,您查询的商品不存在!!!"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; } } } }while(c=='y'); cout<<endl; cout<<"……信息查找完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); etchar();}
    按照品牌查找商品信息函数
    //按照品牌查找商品信息void GoodsManage::SearchByBrand(){ char c; Goods *p; bool flag; string FoundBrand; cout<<" ☆☆☆☆☆☆现在进行商品信息的查找☆☆☆☆☆☆ "<<endl; do { p=head; flag=0; cout<<"请输入您要查找的商品品牌:"; cin>>FoundBrand; while(p->next!=NULL) { p=p->next; if(p->brand==FoundBrand) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; break; } if(flag==0) { cout<<"对不起,您查询的商品不存在!!!"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续查找吗(y/n):"; cin>>c; } } } }while(c=='y'); cout<<endl; cout<<"……信息查找完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    编辑商品信息函数
    //定义编辑商品信息函数void GoodsManage::EditGoodsInfo(){ char c; Goods *p; bool flag=0; string EditCode; cout<<" ☆☆☆☆☆☆现在进行商品信息的编辑☆☆☆☆☆☆ "<<endl; do { p=head->next; flag=0; cout<<"请输入您要修改的货物编号:"; cin>>EditCode; while(p->next!=NULL&&p->code!=EditCode) p=p->next; if(p->code==EditCode) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; cout<<"确认修改吗?<y/n>"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!!<请输入y/n>:"; cin>>c; } if(c=='y') { cout<<"请输入商品名称:"; cin>>p->name; cout<<"请输入生产厂家:"; cin>>p->brand; cout<<"请输入商品价格:"; cin>>p->price; cout<<"请输入商品数量:"; cin>>p->num; cout<<"请输入入库时间(年/月/日):"; cin>>p->date.year>>p->date.month>>p->date.day; cout<<"修改成功!"<<endl; } else cout<<"取消成功!"<<endl; } if(flag==0) { cout<<"对不起,您修改的货物不存在!!"<<endl; } cout<<"您想要继续修改吗?(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续修改吗?(y/n):"; cin>>c; } }while(c=='y'); cout<<endl; cout<<"……信息编辑完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    删除商品信息函数
    //定义商品信息删除函数void GoodsManage::DeleteGoodsInfo(){ Goods q=head,p,*tail=DeleteHead; p=new Goods; char c; string Dename; bool flag=0; while(tail->next!=NULL) tail=tail->next; cout<<" ☆☆☆☆☆☆现在进行商品信息的删除☆☆☆☆☆☆ "<<endl; do { cout<<"请输入您要删除的商品名称:"; cin>>Dename; while(q->next!=NULL&&q->next->name!=Dename) q=q->next; if(q->next!=NULL) { flag=1; cout<<"确认删除吗?<y/n>"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!!<请输入y/n>:"; cin>>c; } if(c=='y') { p=q->next; q->next=q->next->next; tail->next=p; tail=p; tail->next=NULL; DeleteAmount++; amount--; cout<<"删除成功!!"<<endl; } else cout<<"取消成功!!!"<<endl; } if(flag==0) { cout<<"对不起,您删除的商品不存在!!!"<<endl; } cout<<"您想要继续删除吗?(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续删除吗?(y/n):"; cin>>c; } flag=0; q=head; }while(c=='y'); cout<<endl; cout<<"……信息删除完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    出售商品信息函数
    //定义商品出库函数void GoodsManage::SellGoodsInfo(){ int sellNum,year,month,day; doublesellPrice,sum=0.0,profit=0.0; char c; Goods *p; bool flag=0; string EditName; cout<<" ☆☆☆☆☆☆现在进行商品的出售☆☆☆☆☆☆ "<<endl; do { p=head->next; flag=0; cout<<"请输入您要出售的商品名称:"; cin>>EditName; while(p->next!=NULL&&p->name!=EditName) p=p->next; if(p->name==EditName) { flag=1; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; cout<<"确认出售吗?<y/n>"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!!<请输入y/n>:"; cin>>c; } if(c=='y') { cout<<"请输入出售的商品数量:"; cin>>sellNum; if(sellNum<=p->num) { p->num=p->num-sellNum; cout<<"请输入出售的商品价格:"; cin>>sellPrice; cout<<"请输入出货日期:"; cin>>year>>month>>day; sum=sellNum*sellPrice; profit=sellNum*(sellPrice-p->price); cout<<"此次销售额为: "<<sum<<endl; cout<<"此次利润为: "<<profit<<endl; cout<<"出货日期为:"<<year<<"/"<<month<<"/"<<day<<endl; } else { cout<<"库存不足!出库失败!"<<endl; } } else cout<<"取消成功!"<<endl; } if(flag==0) { cout<<"对不起,您出售的货物不存在!!"<<endl; } cout<<"您想要继续出售吗?(y/n):"; cin>>c; while(c!='y'&&c!='n') { cout<<"指令错误!!!<请输入y/n>:"<<endl; cout<<"您想要继续出售吗?(y/n):"; cin>>c; } }while(c=='y'); cout<<endl; cout<<"……出库完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar();}
    保存商品信息函数
    //定义商品信息保存函数void GoodsManage::SaveGoodsInfo(){ Goods *p=head; cout<<" ☆☆☆☆☆☆现在进行商品信息的保存☆☆☆☆☆☆ "<<endl; ofstream output("货物信息.txt",ios::out);//定义输出文件"货物信息.txt" if(!output) { cerr<<"打开文件<货物信息.txt>失败!!!"<<endl; } output<<amount<<"\n"; cout<<setiosflags(ios::left)<<setw(10)<<"编号"<<setw(16)<<"名称"<<setw(10)<<"生产厂家"<<setw(10)<<"价格"<<setw(10)<<"商品类别"<<setw(10)<<"数量"<<setw(10)<<"入库时间"<<endl; while(p->next!=NULL) { p=p->next; output<<p->code<<"\t"<<p->name<<"\t"<<p->brand<<"\t"<<p->price<<"\t"<<p->num<<"\t"<<p->type<<"\t"<<p->date.year<<"\t"<<p->date.month<<"\t"<<p->date.day<<"\n"; cout<setiosflags(ios::left)<<setw(10)<<p-code<<setw(16)<<p->name; cout<<setw(10)<<p->brand<<setw(10)<<p->price<<setw(10)<<p->type; cout<<setw(10)<<p->num<<p->date.year<<"/"<<p->date.month<<"/"<<p->date.day<<endl; } cout<<endl; cout<<"成功将货物信息保存到<货物信息.txt>"<<endl; cout<<"……信息保存完毕……"<<endl; cout<<"……按任意键返回主菜单……"<<endl; getchar(); getchar(); output.close();//关闭输出文件}
    2.2.3 算法流程图添加商品信息函数流程如下所示:

    浏览商品信息函数流程如下所示:

    按照商品编号搜索商品信息函数流程如下所示:

    按照商品名称搜索商品信息函数流程如下所示:

    按照商品类别搜索商品信息函数流程如下所示:

    按照商品品牌搜索商品信息函数流程如下所示:

    编辑商品信息函数流程如下所示:

    删除商品信息函数流程如下所示:

    出售商品信息函数流程如下所示:

    保存商品信息函数流程如下所示:

    三 运行测试程序主菜单

    添加商品信息

    编辑商品信息

    删除商品信息

    按照编号搜索商品信息

    按照类别搜索商品信息

    按照名称搜索商品信息

    按照品牌搜索商品信息

    出售商品信息

    保存商品信息

    统计商品信息
    5 评论 95 下载 2018-10-18 22:21:00 下载需要14点积分
  • 基于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 评论 16 下载 2018-09-26 18:38:29 下载需要21点积分
  • linux下实现的ping程序

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

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

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

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

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

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

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

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

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

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

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

    Ping 域名 如:ping www.sougou.com





    Ping –n 如:ping 14.215.177.37 –n 2

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

    Ping ?

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

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

    1 需求分析1.1 数据结构分析图书管理系统中图书管理模块包括图书类型定义:书号(int),现存量(int),总存量(int),出版时间(int),价格(float),书名,作者名为字符型,借阅指针为读者类型;
    读者类型定义:ID号(int),姓名为字符型。
    B树(2-3树)类型定义:关键字个数和关键字数组为整型,另外还有指向双亲的指针,指向子树的指针;
    B树查找结果类型定义:结点指针,关键字序号和查找标志变量为整型。
    1.2 输出的形式输出界面以用户于计算机的交互方式进行,在输出窗口上显示“特定的提示信息”之后,由用户按提示在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在下面。由于时间和能力有限,该管理系统没有用文件存放数据,所有数据放在内存中存放(后来做了改进版就有了),但是选做的功能就还没有实现。其基本业务都是以书号为关键字进行,采用了(2-3树)对书号建立索引,以提高效率。
    1.3 程序所能达到的功能1.3.1 采编入库
    新书购入,将书号,书名,作者,册数,出版时间以及价格添加入图书管理系统中,如果这种书在系统中已存在,则只将总库存量增加,每增加一个书号则以凹入表的形式显示B树形状。
    1.3.2 清除库存
    实现某本书的全部信息删除操作,每清除一个书号则以凹入表的形式显示B树形状。
    1.3.3 图书借阅
    如果树的库存量大于零时则执行出借,登记借阅者的图书证号和姓名。
    1.3.4 图书归还
    注销借阅者信息,并改变该书的现存量。
    1.3.5 查看图书馆全部图书
    用表格输出所有图书的信息。
    1.3.6 查看某图书信息
    查看指定某一本书的全部信息。
    1.3.7 查看某本书的借阅者信息
    表格输出某本书的全部借阅者信息。
    1.3.8 读取图书信息
    从文件中读取所有图书的信息以及所有借阅者的信息
    1.4 测试数据
    入库书号:35, 16, 18, 70, 5, 50, 22, 60, 13, 17, 12 , 45, 25, 42, 15, 90, 30, 7
    然后清除:45, 90, 50, 22, 42
    其余数据自行设计。由空树开始,每插入删除一个关键字后就显示B树的状态。

    2 概要设计2.1 所有数据类型的定义采用KeyType类型(本次实验默认为int)为元素类型实现抽象数据类型BTree。
    ADT BTree{
    数据对象
    T是具有相同特征的数据元素集合。
    数据关系
    若D为空集,则称为空树;

    树中每个结点最多含有m棵子树
    若根结点不是叶子结点,则至少有2个子树
    除根结点之外的所有非终端结点至少有┌m/2┐棵子树
    每个非终端结点中包含信息:(n,A0,K1,A1,K2,A2,…,Kn,An)。其中:

    Ki(1<=i<=n)为关键字,且关键字按升序排序指针Ai(0<=i<=n)指向子树的根结点,Ai-1指向子树中所有结点的关键字均小于Ki,且大于Ki-1
    关键字的个数n必须满足:┌m/2┐-1<=n<=m-1。 (5)所有的叶子节点都在同一层,子叶结点不包含任何信息


    基本操作
    result SearchBTree(BTree T, int k);

    初始条件:树T存在
    操作结果:在m阶B数T上查找关键字k,返回p{pt,i,tag}

    Status InsertBTree(BTree &T, int k, BTree q, int i, Record *recptr);

    初始条件:树T存在
    操作结果:在B树T上结点p->pt的key[i]和key[i+1]之间插入关键字k

    Status DeleteBTree(BTree &T, int k);

    初始条件:B树上p结点存在
    操作结果:删除B树T上结点p->pt的关键字k

    void BTreeTraverse(BTree T, void(*visit)(BTree));

    初始条件:树T存在
    操作结果:用visit()函数遍历B树

    void DestroyBTree(BTree T);

    初始条件:树T存在操作结果:销毁B树
    } ADT BTree
    ADT Library{
    数据对象
    T是具有相同特征的数据元素集合。
    数据关系
    数据元素同属于一个集合。
    基本操作
    void InitLibrary(BTree &L);

    操作结果:初始化书库L为空书库
    void InsertBook(BTree &L, BookType B, result res);

    初始条件:书库L和B存在,result包含B书在书库中的位置或应该插入的位置
    操作结果:如果书库中已存在B树,则只将B树库存量增加,否则插入B书到书库L中

    int DeleteBook(BTree &L, BookType B);

    初始条件:书库L和B存在
    操作结果:如果书库中存在B书,则从书库中删除B书的信息,并返回OK,否则返回ERROR

    void BorrowBook(BTree L, BookType B, ReaderType R);

    初始条件:书库L存在,B书时书库中的书并且可被读者R借阅
    操作结果:借出一本B书,并登记借阅者信息

    int ReturnBook(BTree L, int booknum, int IDnum, BookType &B, ReaderType &R);

    初始条件:书库L存在
    操作结果:若书库L中有读者R借阅B书的记录,则注销该记录,改变B书现存量,并返回OK,书不存在或物该读者记录则返回ERROR

    void PrintAllbooks(BTree L);

    初始条件:书库L存在
    操作结果:显示所有图书的信息

    int ShowBookinfo(BTree L, int booknum);

    初始条件:书库L存在
    操作结果:若书库L中存在书B,则显示B书基本信息并返回OK,否则返回ERROR

    void PrintBorrower(ReaderType R);

    操作结果:输出某本书所有借阅者的信息
    } ADT Library
    2.2 主程序的流程
    2.3 各程序模块之间的调用关系
    3 详细设计函数和过程的调用关系图

    4 调试分析4.1 调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析此次的课程设计的重难点应该在于B树的定义以及删除操作,由于我设计性实验选的也是B树,有几个操作函数大同小异,不过要在原来的基础上增加一些东西,例如在原有的关键字的基础上加上与关键字对应的图书结点,因此算法需要一些小改动。
    一开始程序跑不起来,一看居然68个错误,可是大致看下来都是不太正常的提示,所以在这个地方卡了蛮久的时间,好在经过不断的调试,发现是头文件里各个数据结构的顺序放倒了,更改顺序后只剩下寥寥几个小错误,大大增长了把程序做好的希望。
    此次实验的不足在于这个图书管理系统的存储是建立在内存上的,故程序退出数据得不到保存,每次都得重新输入(经过改进已经解决这个问题)。每个功能比较独立,相互联系不算多,仅仅是完成各部分需求的算法,采编入库,清除库存和显示信息相对逻辑关系强一点。由于个人能力的局限以及时间上的紧迫,此次的选做要求没有实现,系统功能的不够完整和联系不够紧密是我以后要提高的地方。
    4.2 算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的分析)和改进设想设B树的阶为m,(书号)关键字个数为N

    SearchBTree最好情况为O(1),最坏时比较的结点数不超过log[m/2]((N+1)/2)+1
    因为B树总是在最后一层插入,因此InsertBTree操作比较的结点数也不超过log[m/2]((N+1)/2)+1
    DeleteBTree最好情况为被删关键字在最下层结点而且删除后该结点关键字个数不小于m/2,时间复杂度O(1);最坏情况为删除后需要合并父节点直到到根节点,需比较2 *(log[m/2]((N+1)/2)+1)次
    InsertBook、DeleteBook时间复杂度与B树的插入和删除基本相同
    BorrowBook、ReturnBook除了需要SearchBTree,还与该书借阅人数成正比

    4.3 经验和体会
    按照指导书给出的实习报告规范的步骤,先进行需求分析、概要设计,再进行详细设计,能使实际问题从抽象到具体,能从整体上把握程序的功能方向
    通过划分成几个模块,单独编写每个模块的基本操作,再组合在一起,细分了程序的功能,降低设计的难度,方便了程序的调试、修改和组合
    本次设计实在被B树的指针折磨透了,我深深的体会到:编码时必须对程序的算法了如指掌,对可能出现的每一种情况都处理周到,不然对于复杂的(像B树的删除)函数将会无所适从
    编码时就应该尽量把程序写正确,避免产生错误,这样可能远比调试时才来发现问题、解决问题用的时间少得多,效率高得多
    测试时要注意测试的完备性
    编码时要形成一种自己的风格,同时要注意这种风格应该是大众所接受的,要保持程序的可读性

    5 用户使用说明
    本程序的运行环境为Windows 10操作系统,编译环境是VS 2015
    执行文件为BTree_Library.exe,打开BTree_Library.exe,显示欢迎界面



    输入管理员密码:5372


    进入图书管理系统


    选择1新书入库后提示输入入库书号,读入书号后程序会查找是否已存在,如已存在则提示输入新增加数量,如不存在则提示输入图书其他书名、著者、等信息,插入后显示B树状态
    选择2清除库存后,提示输入删除书号,如果存在该书则提示是否确认删除,如无该书则提示不存在。删除后显示B树状态
    选择3图书出借后,提示输入书号,如该书存在则显示该书,提示输入借阅证号和借阅者姓名,判断如果能借阅则输出借阅成功,否则输出不能借阅;如无该书则提示不存在该书
    选择4图书归还后,提示输入归还书号和借阅证号,如存在该借阅记录则提示还书成功,否则提示不存在该书或无该读者借书记录
    选择5查看图书馆所有图书后,以表格形式输出图书管理系统的总库存
    选择6查看某图书信息后,以表格形式输出该图书的库存情况以及作者等相关信息
    选择7查看某树借阅者信息后,以表格形式输出该图书的所有借阅者的信息
    选择8将文件中的图书内容和借阅者资料导入
    选择0则退出系统

    6 测试结果列出你的测试结果,包括输入和输出。这里的测试数据应该完整和严格,最好多于需求分析中所列。
    将全部数据输入后用凹入表形式显示B树:

    使用功能5:用表格输出图书馆总库存:

    选择功能2:清空某一本书的库存

    清除45后的凹入表:

    用功能2依次清除:45, 90, 50, 22, 42后的凹入表表示如下:

    选择功能3:借阅图书,输入要借的图书号,借阅者的姓名和ID号

    选择功能6:查看某一本图书的信息,并以表格形式输出。

    选择功能4:归还图书

    当图书号不存在时,输出书库中不存在此书

    当借书时该图书的库存已空,则提示库存不足,借阅失败!

    选择功能7:查看某本书的借阅者信息

    输入功能8:从文件中导入图书信息和借阅者信息
    2 评论 178 下载 2018-11-05 22:49:53 下载需要10点积分
  • 基于MFC实现的图形绘图编辑系统

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

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


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


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

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



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




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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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



    程序流程图

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

    数据成员:

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

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

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

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

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

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

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

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

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

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

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














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

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

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

    摘 要餐饮管理系统作为一个餐饮的基本管理,是餐饮服务业对职工以及餐饮的日常管理。开发餐饮管理系统,正是完善餐饮业信息化管理的重要环节。人工操作已很难满足餐饮业信息化管理的要求,面对庞大的信息量,该方式现存在很多弊端。因此,建立现代化的智能管理系统势在必行。这样也大大减轻了餐饮业内部人员的工作量,提高了工作效率,使原本复杂和枯燥无味的工作变得简约而轻松。
    在系统设计中包括系统整体设计,逻辑框架与数据流程,各个功能模块划分,系统功能模块的设计与具体实现等部分。该系统侧重于顾客开台,点菜和结帐,通过已编制好的程序,完成对管理员的登录、桌台信息和职工信息的添加、查询,以及管理员的增、删、改、查等,本系统使用的开发工具是.NET开发程序,采用SQL Server2005数据库。实现餐饮数据及职工的数据采集、数据统计和信息查询过程,完善餐饮管理现代化,方便管理人员统计、考查员工工作情况,方便餐饮业管理部门查询宾馆一段时间内盈余情况,准确地掌握餐饮业近期情况和相关数据。
    关键词:餐饮管理;Visual C#.NET;SQL Server2005数据库
    1 项目介绍针对系统来说主要任务是设计一个餐饮管理系统,实现顾客的开台,点菜,结帐,和餐饮业职工的管理等功能。具体的设计任务如下:

    实现用户登录及修改密码及创建用户帐户
    能查看、查询、输入、添加职工基本信息
    能查看、查询、输入、添加桌台和包间基本信息
    能及时开台,为顾客点菜以及结帐
    能及时备份数据和恢复数据
    有一些辅助工具如日历计算机等

    2 需求分析餐饮管理系统是一个饮食产业不可缺少的一部分,它对于餐饮业的决策者和管理者来说都非常重要。本系统主要包括桌台显示、消费查询、人事档案及权限等几大部分,本系统具有良好的用户接口,使用方便。具有完善的查询,对维护系统起到辅助决策的作用,能及时、方便、灵活地进行查询、修改、删除等维护性操作。餐饮管理系统有足够的存储容量,满足酒店每日营业的变动,另外对于操作用户有一定的管理,并对用户的权限有一定的设置。
    餐饮管理系统的功能模块包括基本信息、辅助工具、系统维护、系统设置模块,其中系统设置模块可以实现口令修改和锁定系统。此模块通过修改密码和锁定系统提高系统安全性也方便工作人员操作。
    2.1 功能需求2.1.1 基本功能需求本课题要实现的是餐饮宾馆管理系统,在设计时应该有友好的用户界面,便于用户的操作,系统应有基本功能如下:

    用户登录功能
    职工和桌台相关信息的管理功能
    开台,点菜,结帐的功能
    查询功能
    用户信息管理功能

    2.1.2 用户界面需求对于一个好的软件有一个友好的用户界面是很重要的。用户界面应尽量做的简单、层次清晰明了,以最大限度为用户提供操作方便。如尽量减少用户输入次数,多使用快捷按扭等。
    2.1.3 开发环境介绍本系统使用的开发语言是Visual C# .net,数据库采用的是SQL Server2005,以Windows XP系统为操作平台。
    3 系统设计3.1 登陆模块3.1.1 模块功能本模块主要起登陆作用,判断用户何不合法,可不可以使用本软件,是本系统的第一个界面
    3.1.2 模块功能图
    3.1.3数据表数据库使用Microsoft SQL SERVER 2005,新建数据库命名为db_MrCy,在数据库中创建了6个数据表用于存储不同的信息,本系统设置模块用到的数据表是表tb_user,用于存放用户信息,如下:



    字段名
    数据类型
    长度
    主键
    描述




    id
    int
    4

    系统标号


    username
    varchar
    50

    用户登录名


    userpwd
    varchar
    50

    用户登录密码


    power
    int
    10

    用户权限



    3.1.4 模块技术分析
    该窗体用到的主要控件如下:

    两个TextBox控件:前一个用于输入用户账号,后一个用于输入登录密码
    两个Bottom控件:确定按钮用于确认登陆,取消按钮用于退出系统

    输入账号或密码为空,则跳出提示窗口:

    若输入账号密码错误,则跳出提示窗口:

    输入账号密码一致,进入下一窗口。
    点击退出按钮,跳出提示窗口:

    单击确定,退出系统。
    3.2 主界面模块3.2.1 模块功能用户通过登录界面登录之后,进入主模块界面。主模块界面上显示基础信息、辅助设计、系统维护、系统设置、帮助和退出菜单,方便用户进行相关操作。此外,主模块界面上通过两幅不同的图片形象的显示桌台或者大厅的空闲状态,用户通过双击图片可以进入另一个界面。如果用户双击的是表示空闲状态的图片,会提示“您已经开过台!请选择加点菜或者退出!”,那么进入另一个界面,就可以点击开台单、点/加菜和退出菜单,并进行相关操作。如果用户双击的是表示非空闲状态的图片,会提示“您没用开台!请选择开台!”,那么进入另一个界面上就不能点击开台单菜单,只能点击点/加菜和退出菜单,并进行相关操作。
    3.2.2 模块数据流图
    3.2.3 数据表


    字段名
    数据类型
    长度
    主键
    描述




    ID
    int
    4

    系统编号


    roomname
    char
    10

    桌台名称


    roomjc
    char
    10

    桌台简称


    roombjf
    decimal
    9

    桌台包间费


    roomwz
    char
    10

    桌台位置


    roomzt
    char
    10

    桌台状态


    roomtype
    char
    10

    桌台类型


    roombz
    varchar
    50

    桌台备注


    roomqt
    varchar
    50

    桌台其它信息


    guestname
    varchar
    50

    顾客姓名


    zhangdandate
    varchar
    50

    开台时间


    num
    int
    4

    顾客人数


    watername
    varchar
    50

    操作员姓名



    3.2.4 模块技术分析开发主模块中的桌台显示时,主要通过ListView控件实现的,系统首先从数据库中检索出每个桌台的状态,然后根据不同的状态通过ListView控件的Items属性中的ADD方法向控件中添加项目集合。
    主模块界面

    主模块用到的控件主要有:

    6个MenuScrip控件:分别用于点击基础信息、辅助工具、系统设置、关于、帮助和退出,方便用户进行相关操作
    1个ImageList控件:用于显示代表桌台状态的图片
    1个ListView控件:用于显示所有桌台

    主模块功能

    主模块提供基础信息、辅助工具、系统设置、关于、帮助和退出菜单,方便用户点击,进行相关操作
    若双击任意表示非空闲状态的图片,弹出以下对话框,提示用户已经开台


    点击确定,进入如图2.5界面,可以进行点/加菜或者退出操作。

    若双击表示空闲状态的界面,弹出以下对话框,提示用户,没有开台。

    点击确定,进入如图2.7界面,进行开台、点/加菜或者退出操作。

    3.3 开台模块3.3.1 模块功能在进入主模块界面之后,选择要进行开台的桌台号或者大厅号,双击图片进入另一个界面。在另一个界面上,单击开台单菜单,进入开台单模块界面。用户可以在该界面上选择服务员、输入顾客名称、用餐人数和备注,点击保存按钮,提示“已经保存成功!”。同时,返回到主模块界面上时,用户刚选择进行开台的桌台号或者大厅号的图片会变化为表示非空闲状态的图片,这样可以提示用户该桌台号或者大厅号已经开台。如果用户没有输入顾客名称和用餐人数,点击保存按钮后,会提示“顾客名称和用餐人数不能为空!”;点击退出按钮,返回到主模块界面。
    3.3.2 模块数据流图
    3.3.3 模块技术分析在开台单模块中用户可以对桌台编号、账单日期、顾客名称、用餐人数、服务员和备注进行录入或更改。数据库录入或修改完毕后,单击“保存”按钮完成开台单的操作。在开发此模块时,主要用到了数据库的更新技术。
    开台单模块界面

    开台单模块用到的控件主要有:

    4个TextBox控件:分别用于输入顾客名称、账单日期、用餐人数和备注
    2个ComboBox控件:分别用于显示桌台编号和服务员
    2个Button控件:分别用于保存数据和退出返回到主模块界面

    开台单模块功能

    选择桌台编号,服务员,并输入顾客名称、用餐人数和备注

    点击保存按钮,会弹出以下对话框,提示已经保存成功,即开台成功。

    如果用户没有输入顾客名称和用餐人数,点击保存按钮,会弹出以下对话框,提示顾客名称和用餐人数不能为空。


    点击退出按钮,返回到主模块界面。
    3.4 点菜结帐模块3.4.1 模块功能服务员在已开台的桌台单击进入点加菜窗体,根据顾客需要从菜品类别中选取菜,在信息文本中会显示菜品的信息,服务员只需输入菜的数量和选取负责服务员的名字,保存信息后系统记录顾客所点的菜品的信息,如果顾客不再需要,服务员可以立即删除记录,另外服务员还可以根据具体要求添加备注。在顾客享用过程中,如有需要服务员还可以再次调出桌台信息,记录顾客加菜的信息。在顾客享用完后,服务员只需点击桌台弹出点加菜窗体,确定信息完整正确,点击结账按钮弹出结账窗体,系统自动结算了顾客消费清单,列出了详细具体的消费情况供顾客查询,此外,系统还有为服务员计算找零的功能,提高了操作效率。
    3.4.2 模块数据流图
    3.4.3 数据表


    字段名
    数据类型
    数据长度
    主键
    数据描述




    ID
    Int
    4

    系统编号


    Foodnum
    Char
    10

    菜品编号


    Foodname
    Varchar
    50

    菜品名称


    Foodsum
    Char
    10

    菜品数量


    Foodallprice
    Decimal
    18

    菜单总价


    Waitername
    Varchar
    50

    服务员名


    Beizhu
    Varchar
    50

    备注


    Zhuotai
    Char
    10

    桌台


    Datatime
    Datetime
    50

    日期



    3.4.4 模块技术分析
    在桌台主界面菜单按钮点加菜菜单,激发单击事件,载入点加菜窗体。
    菜品分类列表

    创建treeview控件,读取数据库中数据,根据类别创建节点。
    菜品信息

    读取数据库中顾客菜品信息,将数据显示在datagridview控件中,服务员输入菜品数量,完整信息,否则系统自动提示。
    菜品记录

    点击保存按钮,将文本中的菜品信息写入数据库中,并保存桌台信息。
    删除记录

    选中下表中顾客数据,点击删除按钮删除数据表中数据。
    结账模块

    点击结账按钮,弹出结账窗体,弹出结账窗体,并在label控件中显示消费情况。
    消费情况

    在datagridview控件中调取数据库中顾客点菜数据。
    找零

    根据消费总额及各科支付的金额,系统给出找零金额。
    3.5 桌台信息管理模块3.5.1 模块功能桌台信息模块主要实现的功能是对桌台信息的添加、查询、修改和删除。选择该窗体以后,如果需要添加信息,用户需要填写添加的内容,然后按添加按钮进行添加,修改信息时,用户需要先从显示数据中选择需要修改的数据,将相关修改信息填写完成后点击修改按钮,查询时输入桌台号,点击查询,即可显示详细信息的窗口,选择数据后可直接点击删除,桌台信息即从数据库中删除成功,若要取消操作,直接点击取消即可。
    3.5.2 模块功能图
    3.5.3 数据表数据库使用Microsoft SQL SERVER 2005,新建数据库命名为MrCy,在数据库中创建了2个数据表用于存储桌台和职员的信息。



    字段名
    数据类型
    长度
    主键
    描述




    Id
    int
    4

    系统编号


    Roomname
    char
    10

    桌台名称


    Roomjc
    char
    10

    桌台简称


    Roombjf
    decimal
    9

    桌台包间费


    Roomwz
    char
    10

    桌台位置


    Roomzt
    char
    10

    桌台状态


    Roomtype
    char
    10

    桌台类型


    Roombz
    varchar
    50

    桌台备注


    Roomqt
    varchar
    50

    桌台其他信息


    Guestname
    varchar
    50

    顾客姓名


    Zhagndandate
    varchar
    50

    开台时间


    Num
    int
    4

    顾客人数


    Waitername
    varchar
    50

    操作员姓名



    3.5.4 模块技术分析新建一个Windows窗口,命名为ZTXX.cs,主要用于实现对数据库中桌台信息的操作,界面如下图所示。

    该窗体用到的主要控件如下:

    6个TextBox控件,用途:接收输入或是从数据库中选择的数据,显示选择的数据
    6个Label控件,用途:标记文本框的内容
    1个DataGridView控件,用途:显示数据库内容
    6个Button控件,用途:分别实现添加、修改、取消、查询、删除、退出的功能

    在查询功能中还调用了ZTXXXX.cs窗口,如下图所示。

    该窗体的主要控件如下:

    9个Label控件,用途:标记文本框的内容
    9个TextBox控件,用途:显示所查询的用户的详细信息
    1个Button控件,用途:退出该窗口,回到上一级窗口

    3.6 职工信息管理模块3.6.1 模块功能职员信息模块的功能和桌台信息模块基本相似。
    3.6.2 模块功能图
    3.6.3 数据表


    字段名
    数据类型
    长度
    主键
    描述




    Id
    Int
    4

    系统编号


    Waitername
    Varchar
    50

    职员姓名


    Cardnum
    Varchar
    50

    身份证号码


    Waiternum
    Char
    10

    职员编号


    Sex
    Char
    10

    性别


    Age
    Char
    10

    年龄


    Tel
    Varchar
    50

    电话



    3.6.4 模块技术分析新建一个Windows窗口,命名为ZYXX.cs,主要用于实现对数据库中职员信息的操作,界面如下图所示。

    同样在查询时也调用了ZYXXXX.cs窗口,如下图所示。

    该模块用到的主要控件基本和桌台信息模块的相同。
    3.7 系统设置模块3.7.1 模块功能系统设置模块主要实现的功能是对管理员的添加、查询、修改和删除,以及软件的锁定和数据库的备份和还原。选择该窗体以后,如果需要添加管理员,用户需要填写添加的内容,然后按添加按钮进行添加,修改信息时,用户需要输入管理员名称,将相关修改信息填写完成后点击修改按钮,查询时点击查询,即可显示所有管理员的窗口,数据库的备份和操作只需点击相应按钮就好,点击锁定软件后必须键入管理员密码才可解锁。
    3.7.2 模块功能图
    3.7.3 数据表数据库使用Microsoft SQL SERVER 2005,新建数据库命名为db_MrCy,在数据库中创建了6个数据表用于存储不同的信息,本系统设置模块用到的数据表是表tb_user,用于存放用户信息,如下:



    字段名
    数据类型
    长度
    主键
    描述




    id
    int
    4

    系统标号


    username
    varchar
    50

    用户登录名


    userpwd
    varchar
    50

    用户登录密码


    power
    int
    10

    用户权限



    3.7.4 模块系统分析用户管理模块界面:

    该窗体用到的主要控件如下:

    2个TextBox控件:前一个用于输入新密码,后一个用于重新输入密码以确认
    2个Bottom控件:确定按钮用于确认修改密码,取消按钮用于退出设置

    用户管理模块功能:

    添加用户:该模块可以添加用户,重复输入密码,如不一致出现出错提醒,各项均为必填。


    修改用户:该模块可修改用户的各项信息,重复输入密码,如不一致出现出错提醒,各项均为必填。


    删除用户:该模块可删除用户,通过用户名来匹配要删除的用户,通过密码来核对,如密码错误则提醒出错。


    查看用户信息

    锁定模块界面:

    该窗体用到的主要控件如下:

    1个TextBox控件:用于输入解锁密码
    1个Bottom控件:解锁按钮用于确认解锁

    系统流程图该窗体用到的主要控件如下:

    2个TextBox控件:前一个用于输入新密码,后一个用于重新输入密码以确认
    2个Bottom控件:确定按钮用于确认修改密码,取消按钮用于退出设置

    锁定系统模块功能:

    输入解锁密码,若密码与登录用户密码不符,则弹出提示框:

    系统维护模块界面

    备份系统

    该模块可以及时的备份数据库,以免出现不可抗拒的因素使得数据丢失。
    恢复系统

    数据得到备份后利用该模块可以使得数据库得以及时的恢复。
    3.8 辅助工具和关于以及帮助模块3.8.1 模块功能本模块主要提供一下小软件,方便用户使用,只需单击主界面上相应按钮即可。
    3.8.2 模块界面
    4 总 结本次实习已接近尾声,经过近一周的艰苦奋战,我们的系统终于基本完成,虽然感到比较累,但看到自己亲手做出的系统,心中却充满了喜悦。这周对我来说是比较累,却很充实的一段时光。期间,有苦,有乐。这是我第一次进行团队合作并完成系统,让我学到了很多,明白了很多,进步了很多,成熟了很多。我作为我们小组的组长,刚开始觉得自己身上的胆子比较重,但是组员相信我,给我信心让我勇于挑战。
    记得刚开始,对这个系统还很陌生,有很多领域知识都不知道,经过老师的讲解和在网上搜索,我们知道了餐饮业的基本运行情况,管理软件在宾馆运营的作用及地位,管理软件要实现的基本功能。之后,在老师的指导要求下我们开始进行需求分析及任务分工。接下来就是分配编写代码任务,刚开始以为基本任务也不过如此,决定在三天内完成,由于我的数据库设计有些失误,导致我们六个人在编写时有些矛盾的思想,六个人的实现功能与计划不一致,三个模块的功能不统一,认识到问题之后我进行深刻的反省,此后我深刻明白在团队的合作中,任何人的一点点失误,就有可能对整个团队造成重大损失;个人不能搞独立,必须融入团队中,再强编程能力的人自己也很难完成一个功能良好的软件。
    在最后阶段,随着各项工作逐渐完成,欢乐的心情也像清流一样缓缓淌入心中,看着这个经过自己团队努力终于等到的丰收的成果。我在这期间不仅学到了书本上没有的东西,还掌握了一些学习方法,奋斗的经验,也认识到在平时的课外生活中,取各方面营养,这样,才有更多的勇气勇于面对未来的生活中挑战。
    参考文献[1] 马煜,Visual C#.NET案例开发集锦,北京:电子工业出版社,2005
    [2] 李乃文 傅游,C#程序设计实践教程,北京:清华大学出版社,2007
    [3] 郭东恩,数据库原理与应用,河南:河南科学技术出版社,2008
    3 评论 89 下载 2018-11-16 12:33:21 下载需要7点积分
  • 基于C语言的银行业务模拟系统

    1.需求分析1.1 问题描述客户业务分为两种。第一种是申请从银行得到一笔资金,即取款或借款。第二种是向银行投入一笔资金,即存款或还款。银行有两个服务窗口,相应地有两个队列。客户到达银行后先排第一个队。处理每个客户业务时,如果属于第一种,且申请额超出银行现存资金总额而得不到满足,则立刻排入第二个队等候,直至满足时才离开银行;否则业务处理完后立刻离开银行。每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的队尾。注意,在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客户(第二种业务)被接待之前的数额,或者本次已将第二个队列检查或处理了一遍,就停止检查(因为此时已不可能还有能满足者)转而继续接待第一个队列的客户。任何时刻都只开一个窗口。假设检查不需要时间。营业时间结束时所有客户立即离开银行。
    写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。
    1.2 测试数据一天营业开始时银行拥有的款额为10000(元),营业时间为600(分钟)。其他模拟参量自定,注意测定两种极端的情况:一是两个到达事件之间的间隔时间很短,而客户的交易时间很长,另一个恰好相反,设置两个到达事件的间隔时间很长,而客户的交易时间很短。
    1.3 实现提示事件有两类:到达银行和离开银行。初始时银行现存资金总额为total。开始营业后的第一个事件是客户到达,营业时间从0到closetime。到达事件发生时随机地设置此客户的交易时间和距下一到达事件之间的时间间隔。每个客户要办理的款额也是随机确定的,用负值和正值分别表示第一类和第二类业务。变量total、closetime以及上述两个随机量的上下界均交互地从终端读入,作为模拟参数。
    两个队列和一个事件表均要用动态存储结构实现。注意弄清应该在什么条件下设置离开事件,以及第二个队列用怎样的存储结构实现时可以获得较高的效率。注意:事件表是按时间顺序有序的。
    1.4 设计任务本程序是模拟银行存取款的流程。模拟客户在银行办理存取款的排队以及办理过程,并计算出客户总的逗留时间。
    程序的设计是需要实现两个排队队列(Q1、Q2),一个事件队列(Q_en)。队列1(Q1)和队列2(Q2)用于模拟客户的排队情况,客户从队尾开始排队,从队头出队。事件队列(Q_en)用于记录客户的到达/离开事件,客户到达时记录到达事件,客户办理完存取款后离开时记录离开事件。到达事件记录客户的序列号、办理金额、到达时间;离开事件记录客户的序列号、办理金额、离开时间。
    客户的到达时间是随机确定的(以客户最大到达时间arriveMaxTime为上界,客户最小到达时间arriveMinTime为下界)。客户若办理完存取款离开则离开时间由客户的到达时间加上交易时间(交易时间由dealMaxTime和dealMinTime随机确定)。客户的交易额由最大交易额上限(MaxMoney)随机确定,规定负数为取款,正数为存款。
    开始时,客户到达银行进入队列1(Q1)排队同时记录客户的到达事件将事件存到事件队列(Q_en)。如果客户办理存款,则更新银行的存款(total_money),然后将客户结点从队列1(Q1)删除,同时事件表(Q_en)记录客户的离开事件。如果客户办理取款,当银行当前的金额(total_money)能够满足客户的取款需求,则更新银行的存款(total_money),然后将客户结点从队列1(Q1)删除,同时事件表(Q_en)记录客户的离开事件。当银行当前的金额(total_money)不能够满足客户的取款需求,则将客户移到队列2(Q2)进行等待。每当队列1(Q1)办理完一次存款操作的时候就顺序检查队列2(Q2),查找能够完成取款操作的客户,当队列2(Q2)当前客户完成取款则更新银行存款(total_money),然后将客户从队列2(Q2)中删除,同时事件表(Q_en)记录客户的离开事件,接着转到队列1(Q1)接待客户。如果队列2(Q2)中当前客户无法完成取款则将队客户移到队列2(Q2)的队尾继续排队,接着检查下一个客户。
    当银行营业结束,检查队列1(Q1)和队列2(Q2)将还在排队的客户删除同时更新客户总逗留时间和接待客户总数。最后输出客户排队情况、接待客户总人数(counter)、需要存款的人数(n_p)、成功存款的人数(s_p)、需要取款的人数(n_g)、成功取款的人数(s_g)、客户逗留总时间(totalTime)、客户逗留平均时间(totalTime/ counter)以及银行现存金额(total_money)。
    1.5 输入的形式和输入值的范围银行模拟程序需要用户输入以下几个参量:

    银行初始存款(total_money)
    银行营业时间(closeTime)
    客户最大到达时间间隔(arriveMaxTime)
    客户最小到达时间间隔(arriveMinTime)
    业务最大处理时间(dealMaxTime)
    业务最小处理时间(dealMinTime)
    最大交易额上限(MaxMoney)

    参量输入要求用户从终端输入。
    total_money、closeTime、arriveMaxTime、dealMaxTime、MaxMoney、arriveMinTime、dealMinTime要求是一个大于零的整数。
    同时arriveMinTime不能大于 arriveMaxTime,dealMinTime不能大于dealMaxTime。
    以及arriveMinTime、arriveMaxTime、dealMinTime、dealMaxTime均不能大于closeTime
    1.6 输出的形式银行模拟程序通过dos界面输出银行营业过程的整个排队结果以及银行办理业务的结果。
    输出:

    需要存款的客户人数(n_p)
    需要取款的客户人数(n_g)
    成功存款的客户人数(s_p)
    成功取款的客户人数(s_g)
    客户逗留总时间(totalTime)
    接待客户总数(counter)
    客户逗留平均时间(totalTime/counter)
    银行结业余额(total_money)

    1.7 程序所能达到的功能程序可以根据用户自定输入的合法参量(银行初始存款(total_money)、银行营业时间(closeTime)、客户最大到达时间间隔(arriveMaxTime)、客户最小到达时间间隔(arriveMinTime)、业务最大处理时间(dealMaxTime)、业务最小处理时间(dealMinTime)、最大交易额上限(MaxMoney))来模拟银行的存取款业务。通过模拟输出结果包括客户排队情况、接待客户总人数(counter)、需要存款的人数(n_p)、成功存款的人数(s_p)、需要取款的人数(n_g)、成功取款的人数(s_g)、客户逗留总时间(totalTime)、客户逗留平均时(totalTime/ counter)以及银行现存金额(total_money)。
    1.8 测试数据1.8.1 第一次测试
    银行初始存款(total_money):10000
    银行营业时间(closeTime):600
    客户最大到达时间间隔(arriveMaxTime):20
    客户最小到达时间间隔(arriveMinTime):10
    业务最大处理时间(dealMaxTime):20
    业务最小处理时间(dealMinTime):10
    最大交易额上限(MaxMoney):5000


    输出结果

    1.8.2 第二次测试让两个到达事件之间的间隔时间很短,而客户的交易时间很长。

    银行初始存款(total_money):10000
    银行营业时间(closeTime):600
    客户最大到达时间间隔(arriveMaxTime):5
    客户最小到达时间间隔(arriveMinTime):3
    业务最大处理时间(dealMaxTime):50
    业务最小处理时间(dealMinTime):40
    最大交易额上限(MaxMoney):5000


    输出结果

    1.8.3 第三次测试让两个到达事件之间的间隔时间很长,而客户的交易时间很短。

    银行初始存款(total_money):10000
    银行营业时间(closeTime):600
    客户最大到达时间间隔(arriveMaxTime):50
    客户最小到达时间间隔(arriveMinTime):40
    业务最大处理时间(dealMaxTime):5
    业务最小处理时间(dealMinTime):3
    最大交易额上限(MaxMoney):5000


    输出结果

    1.8.4 第四次测试测试输入非法数据的情况。

    2.概要设计2.1 数据类型的定义2.1.1 结构体定义/*客户/事件结构体*/typedef struct event{ int type;//事件类型到达或者离开 0为到达,1为离开 int arriveTime;//到达时间 int leaveTime;//离开时间 int money;//存款数,正数为存款,复数为取款 int num;//客户编号 event* next;}event,*eventLink;/*队列结构体*/typedef struct QNode{ eventLink front;//队头指针 eventLink rear; //队尾指针 }QNode,*Queue;
    2.1.2 队列抽象数据类型的定义ADT Queue{ 数据对象:D={ ai | ai∈event, i=1,2,...,n, n≥0 } 数据关系:R1={ <ai-1, ai>|ai-1, ai∈D, i=2,...,n } 基本操作: eventLink get_front(Queue &q); 初始条件:队列q存在 操作结果:返回队头结点指针 void push(Queue &q,eventLink e); 初始条件:队列q存在,结点指针e存在 操作结果:将e指向的结点插入到队列q的队尾 void destoryQueue(Queue &q); 初始条件:队列q存在 操作结果:销毁队列q,释放空间 void pop(Queue &q); 初始条件:队列q存在 操作结果:删除对头结点并释放结点的空间}ADT Queue
    2.1.3 全局变量的定义int total_money; //银行现存款int closeTime; //银行结束营业的时间int arriveMaxTime; //两个到达事件的时间间隔上限int arriveMinTime; //两个到达事件的时间间隔下限int dealMaxTime; //客户交易之间的时间上限int dealMinTime; //客户交易之间的时间下限int MaxMoney; //交易额上限int currentTime=0; //当前时间int totalTime; //客户逗留总时间int counter=0; //客户总数int number=1; //客户初始号码int flag=1; //判断是否有窗口在处理int TimeOfDeal; //交易时间int MaxTime; //到达时间Queue Q_en; //事件队列 Queue Q1; //队列一 Queue Q2; //队列二
    2.1.4 函数类型定义/** 结束函数 当银行营业结束的时候调用此函数,清理释放申请的空间*/void closeBank();/** 到达函数 当客户到达时调用此函数,随机生成客户信息以及相应的到达事件,分别加入队列1和事件队列。*/void arrive();/** 存款函数 当客户办理存款的时候调用此函数*/void putMoney();/** 取款函数 当客户办理取款的时候调用此函数*/void getMoney();/** 查找函数 查找队列q中第一个可以满足取款的结点并返回,若是查找失败则返回NULL*/eventLink search(Queue &q,int m);/** 处理函数 对通过【查找函数】找到的结点进行取款处理,生成相应的离开事件*/void findAndDeal();/** 初始化函数 初始化三个队列,为三个队列分配空间*/void initQueue();/** 主函数*/int main();
    2.2 主程序的流程主程序首先先接收用户的数据输入,并对用户输入的数据进行验证,如果输入的数据不合法则要求用户重新输入。
    当用户输入的数据合法后开始主要程序的运行。首先先调用initQueue()函数对队列进行初始化,以及根据客户到达时间的上下界随机生成第一个客户的到达时间。当当前时间(currentTime)小于银行结业时间(closeTime)时进行循环。每循环一次当前时间加1。
    在每一次循环当中进行四次判断。

    当交易时间(TimeOfDeal)小于当前时间(currentTime)的时候,让交易时间等于当前时间
    当交易时间等于当前时间时,让flag为1表示当前有窗口在办理业务
    当到达时间(MaxTime)等于当前时间(currentTime)的时候调用arrive()函数让客户到达加入队列1(Q1)排队并在事件表(Q_en)中加入到达事件,同时随机生成下一个客户到达时间(MaxTime)
    当窗口处于交易状态(flag=1)且队列1(Q1)不为空。则进行客户交易处理,当客户是存款类型的时候调用putMoney()进行存款操作,同时调用findAndDeal()函数对队列2(Q2)进行检查是否有满足取款的客户并进行处理。当客户是取款类型的时候调用getMoney()进行取款处理

    每一次循环当前时间(currentTime)加1,直到银行营业结束退出循环,输出模拟结果,最后调用closeBank()函数结束程序。
    2.3 各模块的调用关系程序分成主程序模块、存款模块、取款模块、检查处理模块、事件处理模块。主程序模块负责调用存款模块、取款模块和事件处理模块。存款模块调用事件处理模块、检查处理模块。取款模块和检查处理模块调用事件处理模块。
    3.详细设计3.1 数据类型的实现3.1.1 队列抽象数据结构的实现//入队操作void push(Queue &q,eventLink e){ if(e==NULL){//结点指针为空 return; } if(q->front==NULL){//队列为空 q->front=e; q->rear=e; }else{ q->rear->next=e; q->rear=q->rear->next; }}//销毁队列void destoryQueue(Queue &q){ eventLink e,e1; e=q->front; if(q->front==q->rear==NULL){//队空 return; } while(e!=NULL){ e1=e->next; free(e); e=NULL; e=e1; } }//删除队首元素 void pop(Queue &q){ eventLink e; e = q->front; if(q->front==NULL){//队列为空 return; }else if(q->front->next==NULL){//队列只有一个元素 q->front=q->rear=NULL; }else{ q->front=q->front->next; } free(e);//释放空间 e=NULL;}//返回队首元素 eventLink get_front(Queue &q){ return q->front; }
    3.1.2 函数类型的实现/** 结束函数 当银行营业结束的时候调用此函数,清理释放申请的空间/void closeBank(){ //调用destoryQueue()函数销毁三个队列Q1、Q2、Q_en destoryQueue(Q1); destoryQueue(Q2); destoryQueue(Q_en);}/** 到达函数 当客户到达时调用此函数,随机生成客户信息以及相应的到达事件,分别加入队列1和事件队列。*/void arrive(){ //声明两个eventLink结点指针e、e1 //用malloc函数为两个结点指针分配空间 if(e为空或者e1为空){ //退出函数}//用(rand()%(2*MaxMoney)-MaxMoney)随机生成e和e1的办理金额//将当前时间(currentTime)作为e和e1的到达时间//将(number)作为e和e1的序列号,number++//将e1的类型设置为0(到达)//将e加入队列1(Q1)//将e1加入事件队列(Q_en)}/** 存款函数 当客户办理存款的时候调用此函数*/void putMoney(){ //声明两个eventLink结点指针e、e1 //用malloc函数为结点指针e1分配空间 if(e1为空){ //退出函数 } //用get_front()函数获取队列1的队头元素 //更新银行金额total_money //利用获得到的对头元素信息设置离开事件e1 //e1的离开时间为客户的到达时间+随机的处理时间 //e1加入事件队列 //删除队列1对头元素 //增加客户的总逗留时间(客户的离开时间-客户的到达时间) //接待客户人数加1 //客户的离开时间为交易时间 //将窗口设置为空闲状态}/** 取款函数 当客户办理取款的时候调用此函数*/void getMoney(){ //声明两个eventLink结点指针e、e1 //用malloc函数为结点指针e1分配空间 if(e1为空){ //退出函数 } //用get_front()函数获取队列1的队头元素 if(客户的取款金额大于银行现存金额){ //取款失败 //e1为队列2客户元素 //将客户从队列1删除,让客户进入队列2继续排队 }else{ //取款成功 //更新银行现存金额 //向事件队列添加相应的离开事件e1 //将客户从队列1删除 //接待客户人数加1 //增加客户的总逗留时间(客户的离开时间-客户的到达时间) //客户的离开时间为交易时间 //将窗口设置为空闲状态 }}/** 查找函数 查找队列q中第一个可以满足取款的结点并返回,若是查找失败则返回NULL*/eventLink search(Queue &q,int m){ //声明两个eventLink结点指针e、e1 //取队列的队头元素e while(队头元素不为空){//遍历队列 if(客户办理金额小于等于银行现存金额){ if(队列只有一个元素){ //队列头尾指针置空 //返回客户指针e1 }else{ //队头指针移动一位 //返回客户指针e1 } }else{//资金不足,查找下一个客户 if(队列只有一个元素){ //不做操作 }else{ //将队头结点放到队尾 } } if(队列遍历了一遍){ //返回NULL } } //返回NULL}/** 处理函数 对通过【查找函数】找到的结点进行取款处理,生成相应的离开事件*/void findAndDeal(){ //声明两个eventLink结点指针e、e1 while(调用search函数查找客户结点e){ //用malloc函数为结点指针e1分配空间 //更新银行现存款total_money //离开事件e1的离开时间为当前时间+随机处理时间 //设置离开事件e1加入事件表(Q_en) //接待客户人数增加 //交易时间加上处理时间 //增加客户总逗留时间(客户的离开时间-客户的到达时间) //释放结点e的空间 } //将交易状态设为空闲状态}/** 初始化函数 初始化三个队列,为三个队列分配空间*/void initQueue(){ //为三个队列Q1、Q2、Q_en分配空间 if(Q1、Q2、Q_en其中一个为空){ //退出函数 } //将三个队列的头尾指针置空}
    3.1.3 主函数的实现int main(){ while(用户选择进入模拟程序){ //用户输入模拟数据 //初始化三个队列 //随机产生到达时间(MaxTime)用来确定第一个到达的客户 while(当前时间<银行结业时间){ //当前时间加1 if(当交易时间<当前时间){ //让交易时间等于当前时间 } if(交易时间==当前时间){ //让flag为1 } if(到达时间==当前时间){ //调用到达函数arrive() //随机生成下一个到达时间(MaxTime) } if(flag==1并且队列1不为空){ if(队列1队头客户办理存款){ //调用存款函数putMoney() //调用查找函数findAndDeal() }else{//办理取款 //调用取款函数getMoney() } } } //输出事件队列信息 while(事件队列队头不为空){//遍历事件队列 if(事件为离开类型){ //输出事件信息 if(事件为存款类型){ //成功存款人数加1 }else{ //事件为取款类型 //成功取款人数加1 } }else{ //事件为到达类型 //输出事件信息 if(事件为存款类型){ //需要存款人数加1 }else{ //事件为取款类型 //需要存款人数加1 } } //删除事件队列队头元素 } //事件队列遍历结束 while(队列1队头元素不为空){ //更新总逗留时间 //接待客户人数加一 //删除事件队列1队头元素 } while(队列2队头元素不为空){ //更新总逗留时间 //接待客户人数加一 //删除事件队列2队头元素 } //调用结束函数closeBank() //输出最终模拟营业结果 }//退出循环}//main
    3.2 程序模块调用关系图程序分成主程序模块、存款模块、取款模块、检查处理模块、事件处理模块。

    3.3 银行业务模拟程序的流程图
    4.调试分析4.1 调试过程中遇到的问题以及解决办法程序调试阶段中遇到了几个问题,下面将对遇到的问题进行描述以及给出解决办法
    4.1.1 问题1问题:在运行程序的一开始就无法运行。
    解决过程:首先排除输入数据的错误,我取了几组正常的数据进行验证,排除是输入的数据的错误。接着我在程序中设置调试输出语句进行调试,发现程序在调用存款函数的时候出错。经过检查发现是在使用节点的时候,忘记给结点指针分配空间。
    解决方法:给待使用的结点指针分配空间。
    4.1.2 问题2问题:在输出结果的时候发现需要存款和需要取款的人数之和有时候会小于总的客户接待数量。
    解决过程:首先我是想到可能是在存款和取款函数里添加离开事件的时候忘记更新客户总数。在对存取款函数进行排查后发现并不是这个问题。接着我对更新需要存款和需要取款的人数进行检查,发现这两个变量的增加是符合逻辑的,并没有错误。最后我通过不断的调试和判断发现原来是在营业结束后没有对队列2里面还在排队的客户进行计算。
    解决方法:在结束模拟营业后增加一个循环对队列2还存在的客户进行计算、更新总逗留时间并释放空间。
    4.1.3 问题3问题:在程序运行到搜索函数的时候会出错,程序无法运行。
    解决过程:我对搜索函数进行调试发现函数陷入循环里面无法退出循环,在对程序的逻辑进行研究后我发现我的逻辑存在问题,在对队列2进行遍历的时候忘记在遍历一遍之后强制退出循环。
    解决办法:在处理函数的循环语句中增加一个判断,当队列遍历一遍后退出寻环
    4.2 算法的时空分析以及改进设想下面给出程序中各个操作的时间复杂度和空间复杂度的分析。
    4.2.1 get_front(Queue &q)//返回队首元素由函数的操作可以看出此操作只需要返回队列头指针,所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.2 push(Queue &q,eventLink e)//入队操作由函数的操作可以看出来函数里没有循环语句只有简单的判断语句,没有额外的空间,只有指针的赋值操作。所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.3 destoryQueue(Queue &q)// 销毁队列在这个函数中存在循环用以遍历队列,所以这个操作的时间复杂度为O(n),函数 没有额外的空间,所以空间复杂度为O(1)。
    4.2.4 pop(Queue &q)// 删除队首元素通过分析可以知道函数的操作可以看出来函数里没有循环语句只有简单的判断语句,没有额外的空间,只有指针的操作。所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.5 closeBank()//结束函数函数只是调用了三个函数而调用的函数时间复杂度为O(n),所以函数时间复杂度为O(n),空间复杂度为O(1)。
    4.2.6 arrive();//到达函数通过对函数操作的分析可以知道,这个函数与问题规模无关所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.7 putMoney()//存款函数通过对函数操作的分析可以知道,这个函数与问题规模无关所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.8 getMoney()//取款函数通过对函数操作的分析可以知道,这个函数与问题规模无关所以时间复杂度为O(1),空间复杂度也为O(1)。
    4.2.9 search(Queue &q,int m)// 搜索函数通过分析可以知道函数里面存在一个循环用来遍历队列,所以这个操作的时间复杂度为O(n),函数 没有额外的空间,所以空间复杂度为O(1)。
    4.2.10 findAndDeal()//处理函数通过分析可以知道函数里面存在一个循环用来调用查找函数,所以这个操作的时间复杂度为O(n),函数 没有额外的空间,所以空间复杂度为O(1)。
    4.2.11 initQueue()//队列初始化通过对函数操作的分析可以知道,这个函数与问题规模无关所以时间复杂度为O(1),空间复杂度也为O(1)。
    5.经验和体会一开始在选这个课题的时候其实心里挺没底的,因为没有完整的用c语言做过一个课题。在看完这个课题的要求之后发现这个题目主要是需要用队列进行实现。所以我先把队列这部分的知识认真的复习了一遍。之后通过反复看设计需求大致了解了题目的设计要求,在对要求存在疑问的地方我也通过和同学讨论逐渐解决了疑惑。
    在对要求有了一个大致的了解后,我通过写伪代码和思维导图逐渐理清设计思路。接着就是通过题目具体的要求设计了数据结构,和一些基本模块。在经过认真编写后程序的架构基本完成。
    1 评论 2 下载 2019-12-23 12:10:48 下载需要11点积分
  • 基于JAVA和SQL SERVER数据库实现的个人财务管理系统

    一、需求分析个人财务管理系统是智能化简单化个人管理的重要的组成部分。并且随着计算机技术的飞速发展,计算机在管理方面应用的旁及,利用计算机来实现个人财务管理势在必行。本文首先介绍了个人财务管理系统的开发目的,其次对个人财务管理系统的需求分析做了详细的描述。接着,又对系统数据库设计和功能结构的划分做了详细论述。然后又对个人财务管理系统的实现做了详尽的说明。在报告的最后给出了项目的测试结果以及结果分析。
    本系统是对个人的收支情况做一个简单的管理,其中宝库哦个人信息管理以及收支信息管理。 其中,个人信息管理包括用户对自己的信息进行增删查改的一些操作,同样,收支信息管理包括用户对收支情况的信息进行增删查改的管理。
    1.1 系统业务需求该系统具体需求应该有用户登录模块,用户修改信息模块,用户修改信息模块,收支查询模块,收支删除模块,收支添加模块,收支修改模块。
    1.2 系统技术目标该系统的目标主要是能对个人信息以及收支信息进行较快的增删查改,同时也能对收支信息进行各种方式的查询。
    1.3 系统的具体需求根据以上对系统的任务和目标的分析,系统的具体需求如下:

    个人信息:用户名(唯一),密码,姓名,性别,出生日期,工作,身份证号,电话号码
    收支信息:收支编号(唯一),收支日期,收支方式,收支项目,收入金额,支出金额,,总金额

    二、软件功能结构分析由需求分析可知,软件的功能应包括:个人信息管理,收支信息管理。其中,个人信息应包括,个人信息的增删查该,登录时候验证功能。收支信息管理应包括对对收支信息的各种方式查询,以及对收支信息的增加,修改以及删除功能。当然,每个用户应对应其各自的收支信息。
    2.1 个人信息功能在登录界面用户输入用户名以及密码,如果用户与密码都输入正确则可以登录进系统,如果其中任何一项与数据库中的数据不匹配则要求重新输入。当用户没有账户时候,可以点击登录界面的注册按钮注册。成功进入系统后,可以进行个人信息的查询以及修改。
    具体流程图如下:

    2.2 收支管理功能用户登录成功后进入主界面后可以选择查询方式,全部查询:查询用户所有收入支出的信息;收入查询:查询用户收入信息;支出查询:查询用户支出信息;按日期查询:查询用户当天的收入支出信息。用户也可以对收入支出信息进行修改和删除以及添加。
    具体流程图如下:

    三、数据库设计经过以上的需求的分析以及系统功能的分析,需要建立出该系统数据库的各种模型,为建立一个好的,完善的数据库做准备。
    3.1 概念模型由于该系统涉及的较少,只涉及到用户以及财务管理,所以设计比较简单。一个用户可以有多条收支记录,所以用户表与收支表是一对多的关系。通过PowerDesigner工具设计出的概念数据模型如下:

    其对应的E-R模型如下图:

    3.2 逻辑模型联系转换
    一个用户可以有多条记录,而一条记录只能对应一个用户,所以用户与记录之间是一对多的关系。
    其逻辑结构设计如下

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    关系模式

    个人信息(用户名,密码,姓名,性别,出生日期,工作,身份证号,电话号码)
    收支信息(收支编号,收支日期,收支方式,收支项目,收入金额,支出金额,总金额)

    3.3 物理模型通过PowerDesigner中的概念模型生成物理模型如下:

    3.4 表结构设计用户表

    收支信息表

    四、软件代码设计本系统是对个人财政的管理,下面给出具体的功能模块以及代码实现。
    4.1 功能模块登录界面模块

    说明:

    该界面为登录界面,如果没有账户,则可以点击注册按钮注册
    当用户输入的用户名或者密码输入错误时,会提示用户名或者密码输入错误
    当点击登录时,如果用户名以及密码都正确则会提示登录成功,并跳转到主界面

    用户注册模块

    说明:

    该界面为用户注册模块
    用户填入信息,其中用户名唯一,当用户名重复时会提示“用户名已存在,请重新输入”

    主界面模块

    说明:
    该界面为用户主信息界面

    用户可以有多种查询方式:全部查询(查询全部收支信息)、收入查询(只查询收入信息)、支出管理(只查询支出信息)、日期查询(查询当天收支信息)
    显示用户所有的收入总计、支出总计以及收入支出总计

    个人信息显示模块

    说明:

    该界面为用户显示模块
    用户如果不想使用该系统可以注销掉自己的账户

    个人信息修改模块
    说明:

    修改界面与个人信息查询界面在同一模块
    用户名不能修改

    收支信息插入模块
    说明:

    该界面为添加收支信息界面
    当点击主界面的插入按钮时候,会跳转到该界面
    收支编号不能重复


    收支信息修改界面

    说明:

    该界面为收支信息修改界面
    当点击主界面中的修改按钮时(必须选中一行),跳转到该界面
    收支编号不能修改

    收支信息删除界面
    说明:

    该功能与在主界面上
    选中一行,然后点击删除,即可提示删除成功

    4.2 代码实现登录界面主要功能实现(Login.java)
    jb1.addActionListener(new ActionListener() {//登陆按钮 public void actionPerformed(ActionEvent e) { jLabel5.setVisible(false); String ad = jf1.getText(); String pass = jf2.getText(); int i=0; String sc = "select userName,passWord from admin where userName='"+ad+"'"; try { ResultSet rs = st.executeQuery(sc); while (rs.next()) { i++; String userName = rs.getString("userName"); System.out.println(userName+"sdgdfgdf"); String password = rs.getString("passWord"); if (!ad.equals(userName)||userName.equals("")) { jLabel5.setVisible(true); } else if (!pass.equals(password)) { jLabel6.setVisible(true); } else { JOptionPane.showMessageDialog(null, "登陆成功!"); Show show = new Show(); show.s=jf1.getText(); show.setVisible(true); setVisible(false); } } System.out.println(i+"sdfd"); } catch (SQLException ex) { Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); } if(i==0){ jLabel5.setVisible(true); } } });
    说明:该代码实现了登录界面的登录、判断用户名与密码输入是否正确。当用户名或者密码输入错误的时候会提示用户名或者密码错误。同时还添加了一个注册按钮让没有账户的用户注册账户。
    用户注册功能实现(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { String s1 = jf1.getText();//y用户名 String s2 = jf2.getText();//姓名 String s12 = jf7.getText();//密码 String s3 = (String) jcb.getSelectedItem();//性别 String s5 = jf4.getText();//职业 String s6 = jf5.getText();//身份证号码 String s7 = jf6.getText();//电话号码 String s8 = (String) jcb1.getSelectedItem(); String s9 = (String) jcb2.getSelectedItem(); String s10 = (String) jcb3.getSelectedItem(); String s11 = s8 + "-" + s9 + "-" + s10;//出生日期 ResultSet rs; String str ="select userName from admin where userName='"+s1+"'"; rs = st.executeQuery(str); int i=0; while (rs.next()) { i++; } if (i == 0) { if (s6.length() != 18 || s7.length() != 11) { if (s6.length() != 18) { jLabel5.setVisible(true); } if (s7.length() != 11) { jLabel14.setVisible(true); } } else { String sql = "insert into admin Values ('" + s1 + "','" + s12 + "','" + s2 + "','" + s3 + "','" + s11 + "','" + s7 + "','" + s5 + "','" + s6 + "')"; st.executeUpdate(sql); JOptionPane.showMessageDialog(null, "注册成功"); setVisible(false); } } else{ jLabel15.setVisible(true); } } catch (SQLException ex) { Logger.getLogger(UserInsert.class.getName()).log(Level.SEVERE, null, ex); } } });
    说明:该代码实现了个人信息的注册,其中用户名唯一,重复会给出提示“用户名已存在”,并且判断身份证与电话号码填写的格式是否正确。*
    全部查询实现函数(Show.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收入查询实现函数(Show.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    支出查询实现函数(Show.java)
    jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    日期查询实现函数(Show.java)
    jb4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息查询功能模块(Show.java)
    jb9.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息修改功能模块(User.java)
    jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    个人信息删除功能模块(User.java)
    Jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息插入功能模块(UserInsert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息添加功能模块(Insert.java)
    jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    收支信息删除功能模块(show.java)
    Jb7.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ....... ....... } });
    五、总结通过该课程设计,我认识到软件设计是基于需求分析和可行性分析的基础上的,软件设计阶段需要合理的分析需求分析中的细节部分的实现,既要考虑到关键处代码的可实现性,又要考虑到开发过程中遇到的问题。刚开始觉得该 项目建立的数据库比较简单,没有认真进行需求分析,所有导致后面举步维艰。后来重新进行需求分析,一步一步来,最终完成了该课程设计。软件设计是把需求分析中的问题抽象化,又要把抽象化了的需求形象的从预期的实现中体现出来。 本小组的个人财务管理系统系统的设计实现了预期的功能,对个人消费进行记录,个人的收入进行统计,对个人收支进行汇总并给出相应的理财提示信息。在这次的个人财务管理系统设计中将理论知识应用到实际中使得对理论知识的理解有了更进一步的理解,如果仅仅只是运用理论知识,是远远不够的。必须理论联系实际,才能很好的将各门课程学好,并用于实际案例中。
    这次设计使我的编程水平提高了一大步。由于这次设计涉及到数据库,我的学到了不少编程工具与数据库连接的知识,对数据库的操作有了进一步的了解。这次设计对我的综合能力是一次很好的锻炼,自己的能力和知识还很有限。所以今后我的学习道路还是很漫长的。
    3 评论 179 下载 2018-10-25 21:36:27 下载需要6点积分
  • 基于PHP实现的WEB图片共享系统

    摘 要本系统主要从现代社会电脑化观念出发,通过对现有资料的分析、研究和整理,确定了在基于现存的WEB2.0模式下开发图片共享系统的可行性、紧迫性和必要性。在现阶段,国内基于WEB2.0的图片共享系统才刚起步,该市场还有很大的介入空间。其中,在国外,已经有了很成熟的图片共享平台。在WEB2.0时代,信息由以前的服务器发布变成了用户发布。也就是从以前的通过服务器搜集资源并且发布变成了通过用户提供资源,服务器进行整理,分类,发布的模式。而且这种模式对于一个网站的用户吸引度也远远高于传统模式。
    本论文旨在详细说明如何在基于PHP以及Ajax框架的环境下,使用MVC的开发模式,完成一个具有完整功能的图片上传以及图片管理系统,并能够实现方便的添加,删除图片以及分类,后台主要实现对用户以及用户的图片进行管理;能实现相关个人的设置更改。并且系统中对于图片上传需要有比较直观的进度显示,图片的呈现使用比较友善的显示效果。
    关键词:模型-视图-控制器;图片共享;Ajax
    AbstractThis system mainly embarks from the modern societycomputerization. Based on existence information analysis, the research and the reorganization,we considered the pressing and the necessity of implementing order form developingpicture share system base on WEB2.0.At the present stage, the domestic pictureshare system based on WEB2.0 is just underway. There is expansive to take part in this field, at the same time, maturepicture share system aboard is already exist for a long time. In WEB2.0 period,the style of information publishing turned from server publishing to userpublishing .In another word, it is changed from server publishing informationto user providing information, and in this case, servers only need to coordinating,sorting and republishing. Furthermore, in this model, a website is much friendlierto user.
    This thesis mainly describes how to developing fullyfunctional pictures upload and picture management system. This system can easyto add, delete pictures and categories. In the backstage management, is mainlyto implementing user and pictures management and user information changing. Inthis system, picture uploading is intuitionisticly showing, and the picture isneed to be shown user friendly.
    Key words:MVC; Picture Share; Ajax
    1. 引言随着前段时间WEB2.0的热潮,整个BS开发方向和WEB的运营模式渐渐开始向另一个方向转变。随着AJAX的重新使用,大大提高了用户的WEB体验。其页面局部刷新的方式在很大程度上减少了用户访问页面时所花的时间。并且让用户在提高体验的同时,也能够参与的内容的提供者里面来。在传统的WEB系统中,都是有某个网站的管理员,或者类似的人去收集网站所需要的资源,并且将这些资源发布出去,但是随着WEB2.0的兴起,分享和体验逐渐占据了网站发展的重要的位置。于是,网站从以前的集中发布式,渐渐的转变成了用户提供资源,网站整理发布的模式。其中最为常见的就是BLOG,WIKI这些形势。其中图片共享是很有发展潜力的一个方向。首先,中国拥有数码相机的人群正在以一个稳定的数值在不断增长,但是,目前没有多少网站注意到了这片市场的潜力。当用户拍了照片后,他们会找一个可以方便的共享自己所拍的照片的地方。但是,现在传统的网站,要么操作太复杂,要么就是不方便共享,比如163,不支持外部连接图片,虽然这样做的确可以明显的降低服务器的负担,但是对用户体验却大大折扣。试想,当一个用户想直接给朋友看他某个相册里面的某一张图片的时候,他还必须将自己的相册连接给对方,然后对方还要在相册里面找到那张图片后才能查看。而且163上的图片没有专门针对数码照片的整理和分类,也就是说多而不精。导致资源无法有效利用。国内目前在这方面兴起的网站还不多,国外也有比较出名的,例如:Flikre:www.flikre.com ,巴巴变:www.bababian.com 等。其中巴巴变基本仿照FLIKRE改版过来。就目前看来,该市场还有比较大的介入空间。
    就目前看来,图片共享系统现在需要解决的问题主要是如何更快的让用户上传图片。如何以更快的形式显示图片。其中,影响到系统开发的主要有以下问题:1、市场竞争,2、软件的可用性,稳定性,3、时间限制。由于目前已经有部分市场被前期对手抢占,所以需要在尽可能短的时间内开发出一个可用的网站系统。该系统初步分为两个部分,一个是作为WEB界面的WEB端,还有一个部分是用来通过C/S模式远程上传本地图片的客户端工具。
    2. 系统概述在对于由经用户提交的的方式来实现图片共享,首要就是提高用户上传效率,以及用户上传体验和用户的浏览是否方便。一般的图片共享网站都是通过很单一的上传页面对文件进行上传,并且展现形式单一化,不方便用户使用和查看。在WEB2.0下,诞生了大批用于增强用户体验的控件,使得图片共享比传统的形式更加的美观以及人性化。
    而且除了需要良好的用户体验外,还需要良好的系统支持。不仅仅是程序,而是随着用户需求可以不断拓展的业务平台,以及发展流程。本毕业设计就是根据目前WEB2.0的需求和特点有针对的利用现在比较成熟的框架所编写。
    应用WEB2.0中已经成熟的框架接口可以大大加快目前高可用性应用的开发以及设计。并且能够从用户角度来设计一个应用。大大减轻了设计的压力以及风险。该系统能够通过多种方式来对用户的图片进行上传以及管理。并且使用了现在比较流行的视觉框架来实现图片的呈现,大大改进了用户体验。
    3. 总体设计3.1 系统需求分析图片共享,有三个方面需要考虑:

    一,用户应该以什么方式上传图片
    二,用户可以上传的图片有哪些类型
    三,应该以什么方式展示这些图片

    另外,还应该实现对图片的简单整理以及统计。因此,将上传图片的用户和浏览图片的用户作为系统服务的主要目标,对系统的功能提出了如下需求:
    3.1.1 图片上传需要支持的方式图片上传应该支持目前使用最多的页面表单方式。并且可以对其进行简单的处理。
    除此之外,最好还要支持客户端方式。并且需要实现在用户不安装客户端的情况下,在WEB上实现批量上传图片。
    3.1.2 用户上传图片需要支持的格式一种是JPEG一种是PNG,现在大多数的数码相机都是使用JPEG格式保存图片,但是考虑到版权问题,也应提供PNG格式图片的支持。
    3.1.3 分类图片上传后,根据图片的标签以及图片所在任务自动将图片按照标签以及任务进行分类。
    3.1.4 图片管理图片管理应该包括的基本内容:图片的删除,图片的添加,图片分类的添加以及删除,图片任务的添加以及删除,图片标签的添加以及删除。
    同时,在图片管理中,用户能够以比较直观的方式查看自己上传的图片。
    3.1.5 图片展现应该能够很直观的展示给最终用户进行查看。
    3.1.6 查询功能用户需要了解自己的分类下的图片总量以及任务下的图片情况,又因为用户可能需要根据不同的情况下,对自己的分类,任务下的图片情况做统计,因此该系统还应具有分类,任务,标签的多条件组合查询功能。
    3.1.7 由于该系统为多用户系统,系统后台还应该具有用户管理功能用户管理包括的功能如下:用户的添加,删除,查询。以及对用户图片的查看,删除;对用户的分类的查看,删除;对用户标签的查看,删除。
    3.2 总体结构图片共享系统主要功能模块结构示意图如下:

    图片共享系统包括两大部分:用户界面和后台管理,其中用户界面为用户可视并且可使用的功能,后台管理为管理员所能使用的功能。
    3.3 图片共享系统流程图片共享系统流程设计思想如下:

    用户(这里主要指直接使用本系统的最终用户,不包括后台具有管理功能的用户)根据自己的图片格式,选择合适的图片上传到本系统的处理端
    系统在接到用户上传的图片后,应根据系统当前所允许上传的图片的类型判断用户所上传的文件是否符合系统的要求,确定用户为上传图片所分配的标签,依据上传图片的设置对图片进行分类以及更改格式,此时的图片并非最后存储在系统中的图片,该图片在经过裁减以及根据系统设定更改后的格式进行存储。(这样做,是为了统一图片的格式,便于输出的处理以及图片入库时统一处理接口。)
    图片添加成功后,将上传的图片直接缓存到用户所在的文件夹下,按照上传日期排列,并且同时在数据库中保存图片的副本
    图片在存储后,同时在前台显示已经上传的图片,并且将图片添加到所设定的标签下,并且按照任务对图片进行分批显示
    用户在用户管理台里面可以对当前所有图片进行管理,用户删除图片时,可以按照单个图片,分类,标签,以及任务对图片进行删除操作
    已经上传的图片,可以通过用户查看图片的连接直接提供给第三方用户进行查看。或者直接通过系统生成的连接发送给第三方用户进行查看
    后台管理员可以通过系统提供的功能直接对管理用户进行添加以及更改。当需要具体赋予用户某个功能时,可以通过更改后台用户的细节设定来更改用户权限
    管理员在需要删除某个用户的上传图片时,也可通过统一的图片管理接口对用户的图片,分类,标签以及任务进行删除

    图片共享系统流程图如下:

    3.4 图片共享系统模块功能介绍图片共享系统,主要完成图片的添加,删除以及图片标签的添加,删除功能。以及对多用户的管理以及在后台对用户的图片进行管理。以下是子模块划分以及各模块的功能介绍。
    3.4.1 用户界面子模块划分
    用户界面子模块 — 密码修改
    密码修改,作为用户界面子模块的一部分,主要完成用户密码修改的工作。执行流程是:用户在登陆到主界面后,点击导航栏上的密码修改,转向到修改用户密码的界面。在输入当前使用密码以及修改的密码并且重复输入一次修改的密码,最后填入该操作的验证码(为了方便用户,验证码已经由后台自动填入)。当以上操作完成后,用户点击提交以对密码进行修改。
    在用户提交修改内容时,页面内的代码首先检测用户两次修改的密码是否一致。如果不一致,将提示用户密码不一致。当该检查通过后,信息提交到后台系统。后台系统首先判断验证码是否相同,如果相同,将比较用户输入的当前密码散列是否和数据库中的密码散列一致。当两个散列一致时,后台系统将修改用户当前的密码为用户修改后的密码。如果用户没有输入验证码或者验证码出错,当前用户密码散列无法和数据库中的密码散列对应,系统将给出对应的出错提示。并要求用户重新填写。
    用户界面子模块 — 上传图片
    上传图片,在用户登陆系统后,点击导航栏上的上传图片,进入上传图片功能页面。此时,用户可以根据自己的需要选择单个图片进行上传或者直接批量上传多个图片。1)对单个页面进行上传:这种上传需要用户自己过滤不符合系统需求的图片,当前系统只支持JPEG以及PNG。如果图片格式不符合要求,系统将给出出错提示。当用户所选择的图片格式无误,并点击“开始上传”,此时,系统会弹出一个设置图片信息的对话框,需要用户选择该图片的类型,以及设置该图片的标签还有该图片的名称等信息。当一切设置完毕后,点击“提交上传”,用户图片开始上传到系统中。2)直接批量上传多个图片:用户点击“批量上传”标签,系统提示该功能需要JAVA运行时支持,确认后,进入批量图片信息设定页面,该页面用于设置接下来所上传的图片的名称,描述,分类,标签等信息。接下来将转入批量上传界面。具体的操作步骤说明在批量上传页面中有详细的说明。
    用户界面子模块 — 管理图片
    管理图片,在用户登陆系统后,点击导航栏上的上传图片,进入图片管理页面。该页面分为上中下3个部分,分别为用户图片按照任务,分类,标签进行分类后的图片列表。在这个列表里,用户可以对图片按照任务,分类,或者标签等批量对图片进行操作。同时,在该功能页面中,也可以对分类,任务,标签进行删除操作。
    3.4.2 管理后台子模块划分
    管理后台子模块 — 系统管理
    系统管理作为后台管理的一个重要部分,主要是用于设置当前系统的环境变量,以及一些说明性的信息。主要是由后台管理员对系统进行维护以及系统初始化的时候确定这些设置。在设置完成后,如果不是系统性能问题或者系统迁移,均可以保持设定的信息。
    这个功能为系统提供了比较方便的扩展系统环境变量的方法。便于后期对系统的常规设定的修改以及方便系统的简单迁移,例如系统更换域名或者更改其他系统环境信息。
    系统信息表中记录了系统的每个设定,对该模块进行修改最后将反馈到系统信息表中。
    管理后台子模块 — 管理员管理
    管理员管理,主要是用于设置能够对当前系统后台的功能进行操作的用户,以及设置这些用户可以使用后台哪些功能。该功能使得后台管理更为灵活,可以方便的进行权限托管。并且可以设置对某个功能专门进行操作的管理人员,简化了管理的复杂程度。
    这个功能为系统提供了比较方便的扩展系统管理团队的方法。以便于在中后期对某个功能管理达到一定要求时可以对该功能赋予专用人员。
    同时,该模块也提供了修改管理员信息的功能。可以方便的使该管理员在各个功能之间实现切换以及更改现有权限。
    管理后台子模块 — 用户管理
    用户管理用于管理当前系统中已经正常注册并且使用本系统的图片共享功能的用户。用户要注册该系统,除了可以在前台提供的注册页面注册外,也可以由具有用户管理权限的后台管理员在后台进行添加。除了用户能在自己的管理面板修改自己的信息之外,管理员可以通过该模块的用户编辑功能对用户信息进行修改。同时,可以通过搜索功能来定位特定用户名的用户,便于更快的找到需要操作的用户。
    管理后台子模块 — 图片管理
    图片管理用于管理当前系统中已经正常注册并且使用本系统的图片共享功能的用户所上传的图片。在该模块中,后台管理员可以根据单个用户对该用户所上传的图片进行管理。管理用户图片的界面和用户前台的管理界面相同。另外,和用户管理一样,后台管理员也可以通过搜索特定的用户名来快速定位到某个用户,并且对他所上传的图片进行管理。
    在用户上传图片的过程中,有可能由于用户的误操作导致用户所上传的图片没有分类或者没有标签,这种情况下,管理员可以使用图片清理功能将这些图片清理掉。避免冗余以及错误数据导致的系统不稳定或者统计数据出错。
    4. 方案选择4.1 方案比较4.1.1 系统模式比较目前开发模式主要有C/S结构和B/S结构:
    C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势。
    B/S结构,即Browser/Server(浏览器/服务器)结构,是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现。B/S结构利用不断成熟和普及的浏览器技术实现原来需要复杂专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件系统构造技术。
    4.1.2 程序语言比较目前流行的程序开发语言主要有ASP 和 JSP和PHP:
    ASP全名Active Server Pages,是一个WEB服务器端的开发环境,利用它可以产生和执行动态的、互动的、高性能的WEB服务应用程序。ASP采用脚本语言VBScript(Java script)作为自己的开发语言。
    JSP是Sun公司推出的新一代网站开发语言,Java Server Page。JSP可以在Serverlet和JavaBean的支持下,完成功能强大的站点程序。
    PHP,即“PHP: Hypertext Preprocessor”,是一种被广泛使用的开放源代码多用途脚本语言,尤其适用于 web 开发并可以嵌入到 HTML 中去。
    三者都提供在 HTML代码中混合某种程序代码、由语言引擎解释执行程序代码的能力。但JSP代码被编译成 Servlet并由Java虚拟机解释执行,这种编译操作仅在对JSP页面的第一次请求时发生。在PHP、ASP 、JSP环境下,HTML代码主要负责描述信息的显示样式,而程序代码则用来描述处理逻辑。普通的 HTML页面只依赖于Web服务器,而PHP、ASP 、JSP页面需要附加的语言引擎分析和执行程序代码。程序代码的执行结果被重新嵌入到HTML代码中,然后一起发送给浏览器。PHP、ASP 、JSP两者都是面向Web服务器的技术,客户端浏览器不需要任何附加的软件支持。
    然而,相较与ASP , JSP,PHP有其便于部署,可快速开发并且使用灵活等特点。比较适合于做中小型系统的快速开发,同等相较于JSP,PHP由于没有那么复杂的处理,所以在一定程度上执行速度优于JSP。
    4.2 方案选择综上所述,本系统开发选择方案如下:
    本图片共享系统采用PHP、JavaScript作为主要程序开发语言,采用smarttemplate + 独立后台管理模版的构架, mysql数据库。采用B/S结构。系统界面美观内容丰富,很好的实现了与用户的交互。
    4.3 系统技术平台
    开发环境:WindowsServer2003 Datacenter Edition SP1、MySql 4.2、Apache2
    开发工具:ZendStudio、 DreamweaverMX、PhotoShop、记事本
    系统构架:PHP+Smarttemplate+JavaScript+MySql4.2
    开发语言:PHP5

    4.4 开发环境搭建配置PHP 5
    将从网络上下载下来的文件解包,然后需要以下操作:
    打开php.ini文件,修改以下内容:
    max_execution_time = 600;max_input_time = 600;memory_limit = 16Mpost_max_size = 20Mfile_uploads = Onupload_max_filesize = 20Mdefault_socket_timeout = 60以上选项避免由于用户上传过大的图片导致PHP处理超时。register_globals = Offmagic_quotes_gpc = On以上选项为防止用户恶意提交。extension_dir = "D:\PHP\PHP\ext"以上选项用于设定PHP的扩展所在文件夹。extension=php_mbstring.dll该扩展用于支持长字符集extension=php_exif.dll该扩展用于支持PHP读取图片的EXIF信息。extension=php_gd2.dll该扩展用于PHP对图片的操作以及验证码的生成操作。extension=php_mysql.dllextension=php_mysqli.dll以上两项用于PHP对MYSQL的支持extension=php_sockets.dll该扩展用于PHP对SOCKET的支持,主要用于支持上传时显示上传进度的UPU库 Apache 2.0
    将从网络上下载下来的文件解包,然后需要以下操作:
    1)修改Apache的配置文件:

    进入到解包根目录下的conf目录。打开httpd.conf文件,修改以下内容:设置执行超时: Timeout 300设置监听80端口: Listen 80开启APACHE对PHP的支持:LoadModule php5_module d:/php/php/php5apache2.dll开启URL重写功能:LoadModule rewrite_module modules/mod_rewrite.so设定WEB服务的根目录: DocumentRoot “E:\web”设置URL重写所生效的范围:<Directory />Options FollowSymLinksAllowOverride ALL</Directory>设置中文支持:AddLanguage zh-CN .zh-cnAddLanguage zh-TW .zh-twAddLanguage zh-cn .cn设置默认语言AddDefaultCharset GB2312设置默认索引页:DirectoryIndex index.html index.html.var index.htm index.php设置APACHE对PHP文件进行解析:AddType application/x-httpd-php .php

    2)将APACHE安装为服务:
    进入命令行,转到APACHE文件夹下的BIN文件夹,执行以下命令:

    apache -k install

    3)启动APACHE服务器
    执行以下命令:

    net start apache2

    mysql安装
    1)将从网上下载的MYSQL解包,然后修改其配置文件如下:

    default-character-set=utf8 //由于整个系统均使用UTF-8,故数据库也统一文字编码key_buffer_size=20Mmax_allowed_packet=15M //以上设置用于处理将图片存入数据库的大量信息数据。

    2)运行MySQLInstanceConfig.exe对MYSQL进行初始化设置。
    3)安装MYSQL服务
    执行mysqld-nt.exe –install将MYSQL进程作为系统服务运行。
    4)使用MYSQLADMIN对MYSQL的管理员进行管理
    PHPMYADMIN配置
    找到phpmysdmin的配置文件,修改以下地方。

    $cfg[‘Servers’][$i][‘host’] = ‘localhost’;//设置为本机(只做调试用)$cfg[‘Servers’][$i][‘port’] = ‘3306’;//MySQL的端口$cfg[‘Servers’][$i][‘connect_type’] = ‘tcp’;//设置与MySQL连接的方式$cfg[‘Servers’][$i][‘compress’] = FALSE;//使用压缩协议进行传输$cfg[‘Servers’][$i][‘auth_type’] = ‘config’;//如果PHP安装模式为Apache,可以使用http和cookie;如果PHP安装模式为CGI,可以使用cookie;默认为config$cfg[‘Servers’][$i][‘user’] = ‘root’;//MySQL连接用户$cfg[‘Servers’][$i][‘password’] = ‘’;//MySQL连接密码

    5. 实现技术与数据结构5.1 系统架构设计5.1.1 网络架构整个网络架构体系如下图:

    5.1.2 系统逻辑服务器在逻辑上可以将使用的服务器分为三类,每类服务器均有不同的功能:
    Web服务器:该服务器进行Web发布,提供用于普通用户业务工作的操作界面(网页),亦将用户的操作参数通过处理后生成的数据库查询传递回数据库服务器,同时亦将结果在经过解析以及重新编码后生成的数据通过网页的方式返回到用户前端。同时,该WEB服务器还负责解析用户的请求以及动态的生成用户所能看见的Web页面。
    数据库服务器:该服务器上安装了MySQL数据库系统,数据库系统的设计主要针对该服务器。在此存放着所有的原始数据及用于系统的其它结构数据,所有的用户及管理者对信息的新增,修改,删除最终都将反映在该服务器上。同时,该服务器需要处理通过WEB服务器传输来的查询请求,并将查询结果返回给应用服务器。
    5.2 系统处理流程本系统采用B/S模式,Smartemplate构架,用户使用本系统时,只需要安装上网的浏览器即可,不需要安装其它任何软件。系统处理流程如下图所示:

    5.2.1 基于MVC的Smartemplate架构本系统采用基于MVC的构架实现。模型由实现业务逻辑的PHP解析脚本构成,控制器由SmartTemplate来实现,视图由一组含有SmartTemplate格式标签的HTML文件构成。下图简要描述了工作流程。

    MVC是一种设计模式,它强制性的把应用程序的输入、处理和输出分开。MVC把应用程序分成三个核心模块:模型、视图和控制器,它们之间的相互关系如下图所示:

    5.2.2 SmartTemplate技术概述在这个系统制作过程中,大量采用了SmartTemplate技术,现就自己对SmartTemplate技术的理解表述如下:
    SmartTemplate是一个支持大型WEB应用程序的模板引擎,是由服务器端调用和执行的PHP库。SmartTemplate本身与协议无关。
    要理解SmartTemplate,首先需要理解模板引擎的工作方式。
    普通模板引擎工作方式: 你的PHP脚本指定一个HTML模板,指定动态内容并显示。模板分析器使用指派的内容替换模板内所有的占位符,然后显示给用户。
    SmartTemplate 的工作方式类似模板编译,他把模板转换为可执行的PHP脚本,并且保存起来以备以后重用。当一个新的模板在第一次被使用时,模板内所有的占位符被替换为简单的可输出指定内容的PHP代码元素。举个例子,模板片断 <H3>{TITLE}</H3>,将被转换为 <H3><?php echo $TITLE; ?></H3>. 如果你指定内容给正确的变量, 将再也不需要进行模板分析了. 程序要做的仅仅是自己包含并执行编译后的模板. 这种缓存方式能大大减少模板引擎的运行时间。
    5.2.3 SmartTemplate与html模版之间的关系为了增强系统的移植性,使系统能在Windows 、NT、UNIX及Linux环境下运行而不进行源代码的修改,采用PHP技术。开发基于WEB的软件系统,采用PHP脚本 工具,用PHP的动态库连接访问数据库,将一些对象的属性和方法封装在PHP类库中,客户端界面可用HTML与JavaScript配合完成,服务器端的应用处理可用PHP脚本+SmartTemplate引擎来具体实现。
    html模版主要用来定义最终的表现页面,而PHP脚本主要用来完成大量的逻辑处理,SmartTemplate用于将处理后的数据动态的封装到html模版中,最终显示的页面有PHP解析后发送到客户端。也就是说,经过封装以及解析的html模版主要用来发送给前端的用户,而PHP脚本主要来响应用户的请求,完成请求的逻辑处理,同时,充当着控制者的角色,用来负责响应的事务处理。SmartTemplate本身没有任何的业务处理逻辑,它只是简单地检索PHP脚本定义的对象,再将动态的内容插入到预定义的html模版中。
    PHP脚本创建SmartTemplate需要的变量和对象,再根据用户的行为,决定处理哪个html模版并发送给用户。
    在实际开发过程中,往往是先把html模版开发出来,然后再将html模版中需要动态生成的部分用SmartTemplate预定义的标签代替。这样做的好处是充分利用了HTML的页面表现能力,避免了PHP脚本在页面表现方面的不足,大大缩短了开发周期,各尽所能。以下是节选程序代码中的HTML模版转换为最终的页面对象:
    首先,用HTML编辑工具开发出HTML页面
    <form action="search.php" id="find_photo" method="post"><div align="left">搜索图片: <input type="text" name="key" size="24" /><input id="findbutton" type="submit" name="find_photo" value="搜索" /></div></form><!--this is the content of the slidshow--><!-- do not modify the id of the father of dojoslidshow--->{flash_slideshow}</div><!--agl:cssobject id="indexphotolist" type="Three Columns" /--><!-- BEGIN img_thb_block --><div class="threecolbox_indexphotolist"><a href="{org_link}" class="thickbox" rel="gallery-plants"><img src="{link}" alt="" width="70" height="70" border="0" /></a></div><!-- END img_thb_block -->
    通过PHP解析将对应内容填充到HTML模版内
    <?phpif (!empty($_obj['img_thb_block'])){if (!is_array($_obj['img_thb_block']))$_obj['img_thb_block']=array(array('img_thb_block'=>$_obj['img_thb_block']));$_tmp_arr_keys=array_keys($_obj['img_thb_block']);if ($_tmp_arr_keys[0]!='0')$_obj['img_thb_block']=array(0=>$_obj['img_thb_block']);$_stack[$_stack_cnt++]=$_obj;foreach ($_obj['img_thb_block'] as $rowcnt=>$img_thb_block) {$img_thb_block['ROWCNT']=$rowcnt;$img_thb_block['ALTROW']=$rowcnt%2;$img_thb_block['ROWBIT']=$rowcnt%2;$_obj=&$img_thb_block;?><div class="threecolbox_indexphotolist"><a href="<?phpecho $_obj['org_link'];?>" class="thickbox" rel="gallery-plants"><img src="<?phpecho $_obj['link'];?>" alt="" width="70" height="70" border="0" /></a></div>
    5.3 数据库设计
    上图是根据需求设计出十二个数据表,分别是:系统设定表(setting),管理员操作记录表(adminlog),管理员信息表(admin_info),图片缓存记录表(hash_cache),缩略图表(photothumbs),图片表(photo),用户组表(group_setting),用户信息表(member_info),用户登陆记录表(loginlog),图片分类表(sort_setting),用户上传相册表(job)以及标签表(tags_setting)。该表主要分为以下几个部分:
    管理员相关表:

    系统设置表:

    用户组设置表:

    图片信息表:

    相册分类以及标签表:

    5.3.1 前台用户主要数据库表结构设计用户上传相册表(job)用于存储用户上传某批图片的基础信息



    Name
    Type
    Description




    job_id
    BIGINT(11)
    编号


    Article
    MEDIUMTEXT
    该相册的内容描述


    article_title
    TINYTEXT
    相册标题


    article_info
    TINYTEXT
    相册简介


    Author
    varchar(40)
    作者


    Authored
    BIGINT(11)
    作者ID


    sort_id
    BIGINT(11)
    分类ID


    album_id
    BIGINT(11)
    相册ID


    Hits
    mediumint(7)
    点击次数


    Replies
    mediumint(7)
    回复次数


    replies_page
    mediumint(7)
    回复分页数


    Lastpost
    BIGINT(11)
    最后回复


    Lastposter
    varchar(30)
    最后回复者


    Lastposterid
    BIGINT(11)
    最后回复用户ID


    Posttime
    BIGINT(11)
    发表时间


    Hidden
    int(2)
    是否隐藏


    Isparseurl
    int(2)
    是否引用


    Ipaddress
    varchar(16)
    发表用户的IP



    用户信息表(member_info)用于图片上传用户的详细情况信息——与图片表是一对多的关系:



    Name
    Type
    Description




    Id
    BIGINT(11)
    用户编号


    reg_time
    BIGINT(11)
    注册时间


    Name
    varchar(32)
    用户名


    photo_album_name
    varchar(32)
    图片名称


    Blog_album_describe
    BLOB(100)
    描述


    Gander
    char(1)
    性别


    Pwd
    varchar(64)
    用户密码


    Gid
    mediumint(6)
    用户所在组ID


    Email
    varchar(64)
    用户邮箱



    5.3.2 管理后台数据库表结构设计系统设定表(setting)用于存储系统基本设定信息



    Name
    Type
    Description




    Id
    int(5)
    编号


    Varname
    varchar(255)
    设定名


    Setting
    varchar(255)
    设定描述


    Value
    TEXT
    设定值


    Type
    varchar(20)
    设定类型



    管理员操作记录表(adminlog),用于存储管理员对后台的操作记录



    Name
    Type
    Description




    Adminlogid
    int(5)
    记录编号


    Uid
    BIGINT(11)
    管理员编号


    user_name
    varchar(32)
    管理员名称


    Action
    varchar(50)
    进行操作的名称


    Script
    varchar(255)
    该操作所调用的脚本


    Date
    int(10)
    执行该操作的时间


    Ipaddress
    varchar(16)
    执行该操作的管理员的IP地址



    管理员信息表(admin_info),用于存储管理员的基本信息(为了降低系统复杂度,这里将管理员的权限直接和管理员信息写入同一表中,不独立分为两个表)



    Name
    Type
    Description




    Aid
    BIGINT(11)
    管理员编号


    admin_name
    varchar(32)
    管理员名称


    Pwd
    varchar(64)
    管理员密码


    Gid
    mediumint(6)
    管理员组ID(预留)


    can_admin
    int(1)
    执行系统管理的权限


    can_user
    int(1)
    执行用户管理的权限


    can_category
    int(1)
    执行分类管理的权限


    can_setting
    int(1)
    执行设定管理的权限



    6. 特殊问题解决办法本系统在设计和开发过程中,也遇到了不少的问题,就其中较特殊问题分析及解决方案描述如下:
    6.1 乱码问题在做设计的时候,遇到了乱码问题。在页面间传递时汉字会乱码,如果直接从数据库添加数据显示没有乱码,但是从后台管理添加数据就会在添加成功后的显示页面出现在乱码。对于这个问题,原因是开发平台在WINDOWS下,WINDOWS默认的编码格式是GB2312,但是运行环境却是UTF-8环境,要避免乱码,必须统一整个开发环境的字符编码:
    首先,统一在数据库中的编码
    在创建数据库以及查询数据库时,将编码首先置为UTF-8

    SET CHARACTER_SET_CLIENT = utf8,CHARACTER_SET_CONNECTION = utf8,CHARACTER_SET_DATABASE = utf8,CHARACTER_SET_RESULTS = utf8,CHARACTER_SET_SERVER = utf8,COLLATION_CONNECTION = utf8_general_ci,COLLATION_DATABASE = utf8_general_ci,COLLATION_SERVER = utf8_general_ci,AUTOCOMMIT=1”;

    在HTML模版的HEADER部分注明编码标准

    <meta http-equiv="content-type" content="text/html;charset=utf-8" />



    在PHP输出前在HEADER内容中申明所用的字符流编码:

    header(‘Content-Type: text/html; charset=utf-8’);

    6.2 动态显示上传进度通过表单上传有一个缺陷,就是不能动态的显示当前文件上传了多少。这样在用户上传比较大的图片时很不方便用户判断上传所耗时间以及浏览器是否超时。解决方法:经过查找,发现一个通过JAVASCRIPT以及PHP的SOCKET库动态生成上传进度的PHP库:UGiA PHP UPLOADER。该库的使用方法很简单,下面具体说明其调用方法:
    调用方法:

    对于upu/misc/upu.js, 修改var basePath = “/upload/upu/“; 为upu相对于网站根目录的路径
    然后在包含上传表单的页面中加入


    <script type="text/javascript" src="upu/misc/upu.js"></script>,这里的upu/misc/upu.js为upu.js的路径,然后在<form>标签中加入onsubmit=”return upuInit(this)”


    在你文件上传后处理的页面中使用$_POST来获取表单数据
    upu/temp为上传临时文件存放目录, upu/files为文件存放目录,这两个目录可以在upu.class.php中指定。
    <form>中要有enctype=”multipart/form-data”这个属性,action为文件上传成功后的处理页面,也就是说你的<form>完全按照正常的思路来写就可以了,唯一不同的是需要加入onsubmit=”return upuInit(this)”
    上传成功后,可以使用$_POST来获取表单数据,如果是普通表单,直接$_POST[‘表单名称’]即可获得其值,如果是一个文件,则返回这样一个数组

    $_POST['表单名字'] = Array ( [filename] => [clientpath] => [savepath] => [filetype] => [filesize] => [extension] => )
    6.3 图片随意批量上传问题一般的表单上传模式中,虽然可以动态的生成并且随意添加提供文件上传的表单,但是会给用户带来很多不便,而且导致后台的处理变得更加复杂,故最好的方法是利用后台已有的对单个文件处理的接口来实现随意批量上传的问题。经过具体比较,最终选择jupload的Applet库用作对图片批量上传的中间处理。同时,为了实现对批量上传的文件进行处理,还需要手工编写对上传后的文件进行处理的回调脚本,具体实现原理如下:
    首先,jupload在上传一个文件后便会自动调用一个回调脚本来处理上传过后的文件。通过这个回调脚本,可以将上传后的图片手工构造成符合5.2节中的$_POST[表单名称]变量。
    具体代码如下:
    <?php include_once('../sys.php'); function message_sender($can_save){ // send error response to jupload // format depends on API version switch(php_sapi_name()) { case 'cgi': case 'cgi-fcgi': $sz_htstatus = 'Status: '; break; default: $sz_htstatus = 'HTTP/1.0: '; break; } // fake error message // if jupload gets != 200 status code, it prints out the error message if (!$can_save) { $sz_message='406 It is not acceptable to save this file'; } else { $sz_message='200 JUpload uploaded ok'; } header($sz_htstatus.$sz_message); } //未登陆的直接退出 $result = $_GET['jid']; if (!is_numeric($result) || $result <= 0) { message_sender(false); exit(0); } $_SESSION['job_title'] = $_GET['job_title']; $_SESSION['job_cat'] = $_GET['job_cat']; $_SESSION['job_content'] = $_GET['job_content']; $_SESSION['job_tags'] = $_GET['job_tags']; $_SESSION['jid'] = $_GET['jid']; $_SESSION['uid'] = $_GET['uid']; $uptp = $_SESSION['job_title'] . '|' . $_SESSION['job_cat'] . "|" . $_SESSION['job_content'] . "|" . $_SESSION['job_tags']; //处理APPlet字符集编码问题 $uptp = auto_decoding($uptp); $jid = $_SESSION['jid']; //$hash_path = $_GET['hashdir']; //$i = 0; foreach($_FILES as $tagname=>$objekt) { //构造UPU数组 $save_path = ROOT_PATH . 'sys/upu/files/'; $_POST['FileUp']['clientpath'] = $objekt['name']; $_POST['FileUp']['filesize'] = $objekt['size']; $_POST['FileUp']['filename'] = basename($objekt['name']); $_POST['FileUp']['filetype'] = $objekt['type']; $ext = explode('.',basename($objekt['name'])); $ext = $ext[(count($ext) - 1)]; $_POST['FileUp']['extension'] = $ext; $_POST['FileUp']['savepath'] = $save_path . sha1(basename($objekt['name']) . time()) . mt_rand(100,999) . '.' . $ext; // move them to the upu directory if (!file_exists($_POST['FileUp']['savepath'])) { move_uploaded_file($objekt['tmp_name'],$_POST['FileUp']['savepath']); } $_POST['jid'] = $jid; $_POST['uptp'] = $uptp; save_pic(false); } //缓存信息 //file_put_contents($hash_path,$post_str); //构造伪应答信息 if (count($_FILES) == 0){ $can_save = false; } else { $can_save = true; } message_sender($can_save); ?>
    其中,构造UPU数组段,就是通过对上传后的文件进行构造的代码。通过该代码,后台处理便能直接进行后续处理,不用在单独重写对该内容进行处理的脚本。
    以下为处理上传后图片的脚本(整个图片处理抽象为单独的一个类,由于代码太多,故略去)
    $pic_info = $_POST['uptp']; $pic_info = explode('|',$pic_info,4); $pic_title = trim($pic_info[0]); $pic_cat = trim($pic_info[1]); $pic_des = trim($pic_info[2]); //注意这里的TAG是数组 $pic_tags = explode(',',trim($pic_info[3])); //用户ID就是相册ID $album_id = $_SESSION['uid']; if ($album_id == '') { $album_id = $_GET['uid']; } //处理上传文件 $photo = get_photo_obj($_POST['FileUp'],$db_settings,'DGBN_B6.TTF',80,80); //得到上传文件的物理路径 $result = $photo->save_pic($db_settings,$pic_cat,$jid,$album_id,'',$pic_title,$pic_des,true,true); if ($result < 0) { if ($with_error_exit) { show_normal_mesR('非法图片<br />您的图片类型为:' . $_POST['FileUp']['filetype'],'非法图片','图片上传'); } else return; }
    其中,粗体部分为从之前构造的数组中提取有效信息的代码。
    7. 结果测试、性能分析7.1 运行模块组合系统根据业务需求,分配相应的模块操作权限、数据库操作权限即相关的角色,所授予的模块和数据库操作权限通过菜单框架结构和页面组合,形成用户操作平台及操作界面。
    7.2 系统登陆界面
    7.3 模块应用举例用户主页

    搜索结果页面

    图片管理界面

    用户信息修改界面

    图片批量上传界面

    上传图片信息设置界面

    图片上传过程界面
    1 评论 8 下载 2019-01-16 16:07:31 下载需要5点积分
  • 基于JAVA和SQL SERVER数据库实现的人力资源管理系统

    一、系统开发平台1.1 介绍人力资源管理系统, 通过提高内部员工的满意度、忠诚度,从而提高员工贡献度,即绩效,帮助管理者通过有效组织管理降低成本和加速增长来创造价值链利润。随着企业的规模不断扩大,员工数量急剧增加,有关员工的各种信息量也成倍增长。面对庞大的信息量需要有人力资源管理系统来提高员工管理工作的效率。一个完善的人力资源信息管理系统能够极大地提高员工信息管理的效率。
    1.2 开发环境
    开发语言:Java

    用Java做设计流程清晰、结构合理,有良好的可扩充性和耦合性
    开发工具:Eclipse V4.5.0 JDK 1.8
    数据库:Microsoft SQL Sever 2012
    操作系统:Microsoft Windows 10

    二、数据库规划2.1 任务陈述人力资源管理系统是一个企业不可缺少的部分,它的内容对于企业的决策者和管理者来说都至关重要。随着企业的规模不断扩大,员工数量急剧增加,有关员工的各种信息量也成倍增长。面对庞大的信息量需要有人力资源管理系统来提高员工管理工作的效率。一个完善的人力资源信息管理系统能够极大地提高员工信息管理的效率,具有检索迅速、查找方便、可靠性高、存储量大、更新快、寿命长、成本低等优点。
    企业在正常的运营中需要对员工档案信息、部门资料、企业报表进行管理,利用人力资源管理系统及时了解各个环节中信息的变更,有利于提高管理效率。
    2.2 任务目标本系统主要可以实现以下任务目标:

    系统在员工进入公司时为员工建立人事档案,人事档案应该包括:

    员工基本信息:编号、姓名、性别、邮箱、电话、员工进入公司的时间、员工级别、员工所在部门和员工级别等员工技能情况:员工接受的培训、具备的技能等
    员工的工资应该包括基本工资和奖金两个部分:

    基本工资根据员工的级别划分(试用员工、普通员工、组长、部门经理、总经理)奖金应根据员工的业绩由其直接或更高级领导确定
    员工在来到公司上班时应该首先登录公司系统签到,离开公司时登录系统签离。如果办事外出或者出差应由上级领导确认考勤情况。缺勤或者迟到按一定数额罚款,迟到2小时以上算缺勤
    员工离职应保留员工的历史信息,以备日后查询
    系统还应该提供强大数据统计、查询、报表生成以及打印等功能
    用户权限管理
    异常处理

    三、需求分析3.1 用户需求说明3.1.1 数据需求公司有一名总经理,多名试用员工、普通员工、组长、部门经理。总经理负责公司的管理,部门经理与组长负责按级别管理员工,分配工作,管理员负责更新信息。
    职工号在公司内唯一。

    员工基本信息:职工号、密码、姓名、性别、邮箱、电话、员工进入公司的时间、员工职位级别(FK)、员工所属部门(FK)、是否离职
    公司部门:部门号、部门名字、部门经理
    公司职位:职位号、职位名、职位级别、部门号(FK)
    员工工资:职工号、职位级别、基本工资、业绩等级、奖金
    培训表:培训号、培训名、培训描述
    技能表:技能号、技能名、技能描述
    培训联系:员工号、培训号、培训名、成绩
    技能联系:员工号、技能号、技能名、熟练度

    员工在来到公司上班时应该首先登录公司系统签到。缺勤或者迟到按一定数额罚款,迟到2小时以上算缺勤。由管理员定时统计签到情况。

    签到表:职工号、年份、月份、日期、时刻、是否迟到
    考勤表:职工号、迟到次数、缺勤次数、罚款数

    3.1.2 事务需求
    管理员

    数据录入

    录入新员工基本信息录入公司部门信息录入职位信息录入员工业绩工资信息录入员工受培训信息录入员工技能信息录入员工考勤情况
    数据更新

    更新/删除员工基本信息更新/删除公司部门信息更新/删除职位信息更新/删除员工业绩工资信息更新/删除员工受培训信息更新/删除员工技能信息更新/删除员工考勤情况
    数据查询

    查询员工基本信息查询公司部门信息查询职位信息查询员工业绩工资信息查询员工受培训信息查询员工技能信息查询员工考勤情况查询员工签到情况

    员工

    查询员工基本信息查询公司部门信息查询职位信息查询员工业绩工资信息查询员工受培训信息查询员工技能信息查询员工考勤情况查询员工签到情况进行签到修改下级员工的工资

    3.2 系统需求说明3.2.1 初始数据库大小
    大约有1000名员工,分属于约20个部门中,每个部门有5个以下的职位
    公司提供10余种培训,员工最多可选择5种
    员工技能10余种,每人最多5种
    很多考勤条目

    3.2.2 网络和共享需求
    所有部门必须安全的和总部中央数据库网络互连
    必须能够支持至少100名成员同时访问.需要考虑大数量并发访问的许可需求
    3.2.3 性能单个记录查询时间少于1秒,高峰期少于5秒
    多个记录查询时间少于5秒,高峰期少于10秒
    更新/保存记录时间少于1秒,高峰期少于5秒

    3.2.4 安全性
    数据库必须有口令保护
    每个用户分配特定的用户视图所应有的访问权限
    用户只能在适合他们完成工作的需要的窗口中看到需要的数据

    3.2.5 备份和恢复
    每天24点备份
    用户界面

    菜单驱动联机帮助
    法律问题

    对员工信息管理,遵守法律

    四、数据库逻辑设计4.1 ER图
    该ER图包括员工、部门、职位、工资、培训、技能、考勤七个实体和工作于、包含、属于、得到、选择、拥有、进行七个关系。
    4.2 数据字典4.2.1 系统实体描述员工表



    属性
    描述
    数据类型和长度
    是否允许空值




    Employee_id
    职工号
    Varchar 50



    Password
    密码
    Varchar 50



    Sex
    性别
    Varchar 2



    Name
    姓名
    Varchar 50



    Position_rank
    职位级别
    Int 4



    Branch_id
    部门号 (外码)
    Varchar 32



    Position_id
    职位号 (外码)
    Varchar 32



    Email
    邮箱
    Varchar 50



    Phone
    电话
    Varchar 50



    Hiredate
    入职时间
    Varchar 50



    Service_state
    是否离职
    Varchar 2




    部门表



    属性
    描述
    数据类型和长度
    是否允许空值




    Branch_id
    部门号
    Varchar 50



    Branch_name
    部门名
    Varchar 50



    Manager_id
    经理职工号 (外码)
    Varchar 50




    职位表



    属性
    描述
    数据类型和长度
    是否允许空值




    Position_id
    职位号
    Varchar 50



    Position_rank
    职位级别
    Int 4



    Position_name
    职位名
    Varchar 50



    Branch_id
    部门号 (外码)
    Varchar 50




    培训表



    属性
    描述
    数据类型和长度
    是否允许空值




    Course_id
    培训课程号
    Varchar 50



    Course_name
    培训课程名
    Varchar 50



    Course_detail
    培训描述
    Varchar 128




    技能表



    属性
    描述
    数据类型和长度
    是否允许空值




    Skill_id
    技能号
    Varchar 50



    Skill_name
    技能名
    Varchar 50



    Skill_detail
    技能描述
    Varchar 128




    工资表



    属性
    描述
    数据类型和长度
    是否允许空值




    Employee_id
    职工号
    Varchar 50



    Position_rank
    职位级别
    Int 4



    Base_salary
    基本工资
    Int 4



    Achievement
    业绩级别
    Varchar 50



    Bonus
    奖金
    Int 4




    考勤表



    属性
    描述
    数据类型和长度
    是否允许空值




    Employee_id
    职工号
    Varchar 50



    Late
    迟到次数
    Int 4



    Absence
    缺勤次数
    Int 4



    Fine
    罚款数额
    Int 4




    签到表



    属性
    描述
    数据类型和长度
    是否允许空值




    Employee_id
    职工号
    Varchar 50



    Year

    Varchar 50



    Month

    Varchar 50



    Day

    Varchar 50



    Time
    时间
    Varchar 50



    Late
    是否迟到
    Varchar 50




    4.2.2 从数据字典中抽取出来的联系的描述:


    实体
    多样性
    联系
    多样性
    实体




    员工
    m
    工作于
    1
    部门


    员工
    m
    属于
    1
    职位


    员工
    m
    选择
    n
    培训


    员工
    m
    拥有
    n
    技能


    部门
    1
    包含
    m
    职位



    4.3 关系表
    五、应用程序设计5.1 功能模块5.1.1 管理员
    登录系统
    查询员工基本信息、公司部门职位、员工技能培训、员工工资、签到考勤信息
    添加以上信息的新条目
    修改以上数据
    定时查询签到表并对员工迟到缺勤情况进行更新

    5.1.2 员工
    登录系统
    查询以上信息
    签到并查询签到和考勤情况
    根据职位级别赋予修改下级员工奖金的权限

    5.2 界面设计5.2.1 登录根据职位等级,管理员与用户账号进入的界面不同,操作权限也不同。

    若用户名或密码为空。

    若用户名不存在。

    若密码错误。

    5.2.2 用户界面填写上方条件进行查询。

    不填写条件则默认为查询整个表。


    只能修改下级员工的奖金。

    每天签到一次,第二次不再更新时间。

    5.2.3 2.管理员界面管理员可以添加修改信息。



    管理员定时进行员工迟到缺勤情况的考勤并罚款。

    六、总结6.1 经验体会本次课程设计使我深切体会到了知识面狭窄的弊端,痛心地吸取了教训。由于对网页程序的编写一窍不通,此前也没有学习过任何有关html、css等的相关知识,我对开发网页数据库界面的信心不足,导致我最终只编写出一个连接了数据库的Java程序,采用了Java自带的图形界面功能,既不美观也不方便用户使用,我对此感到十分惭愧难过。
    但在为期两周的设计过程中,我也学习到了不少技巧。例如,设计数据库应该实事求是,与时俱进,妄想一次性将理论设计完成、写完文档再去实现功能代码是不正确的,应该一边编写一边修改,逐渐将程序和文档都完善起来。但是一味地进行实践而不去分析理论也是不可行的,最基本的要做到按照老师给的设计提纲,先进行目标明确,任务分析,再是需求分析,ER图,关系表,然后才是数据库逻辑设计,数据库物理设计,最后是应用的实现与完善。把握好用户需求,并不断地修改完善,才能设计开发出优秀的软件。
    6.2 系统特色本程序基本实现了人力资源管理中所应用的大体功能。对于用户来说可以查询本公司各部门各职位各个职员的基本信息、工资情况、签到考勤等,上级职位等级还可以决定下级员工的奖金情况。对于管理员具有各种查询修改添加信息的权限,并进行签到考勤评测。
    主要倾向于统计和展示人力资源的基本信息,界面简洁清晰,操作简便明了。
    6.3 系统完善系统除了展示添加修改信息与签到考勤外没有其他的功能,用作公司的人力资源管理系统尚显不足。如果需要完善,应添加信息注销删除、工资发放、出差安排、职位部门调动、报表生成以及打印、权限管理及异常处理等功能。
    5 评论 249 下载 2018-11-26 21:51:22 下载需要5点积分
  • 基于PHP的网上商城

    第一章 需求分析1.1 引言伴随着Internet的蓬勃发展,网络购物中心作为电子商务的一种形式正以其高 效、低成本的优势,逐步成为新兴的经营模式和理念,人们已不再满足于信息浏览 和发布,而是渴望着能够充分享受网络所带来的更多的便利。的确,客户足不出户 便可以方便快捷的选购自己喜欢的商品,这正是网络购物中心为客户带来的好处。 网络商城将传统的商务流程电子化、数字化,一方面以电子流代替了实物流,可以大量减少人力、物力,降低了成本;另一方面突破了时间和空间的限制,使得 交易活动可以在任何时间、任何地点进行,从而大大提高了效率网络商城所具有的 开放性和全球性的特点,为企业创造了更多的贸易机会。网络商城使企业可以以相 近的成本进入全球电子化市场, 使得中小企业有可能拥有和大企业一样的信息资源, 提高了中小企业的竞争能力。网络商城重新定义了传统的流通模式,减少了中间环节,使得生产者和消费者的直接交易成为可能,从而在一定程度上改变了整个社会 经济运行的方式。网络商城一方面破除了时空的壁垒,另一方面又提供了丰富的信 息资源,为各种社会经济要素的重新组合提供了更多的可能,这将影响到社会的经 济布局和结构。 现在的购物商场成蓬勃向上发展的。
    1.2 需求分析一个网络购物系统,首先我们要保证客户能够很方便进行商品选择,系统应该具有分类选择商品功能,系统要实现购买功能。在系统的后台,管理员能够管理商品,商品分类,以及客户购买订单。 因此分析,本系统主要由前台和后台两部分组成,前台为客户端,顾客可以在此处购买商品,后台为商品管理端,实现对商品和订单的管理。
    第二章 系统分析2.1 开发环境根据用户的需求和实际的考察与分析,确定商城的开发环境,具体如下:

    服务器:从稳定性、广泛性及安全性方面综合考虑,采用市场主流的Web服务器软件Apache服务器
    数据库:采用最受欢迎的开源SQL数据库管理系统和被誉为PHP黄金搭档的MySQL
    开发框架:选用具有快速、兼容、开源、简单易学等特点的轻量级国产PHP开发框架—ThinkPHP

    2.4 系统运行环境该网上商城可运行在分辨率为1920×1080的chrome浏览器下。
    2.3 功能结构商城分为前台模块和后台模块。下面分别给出前、后台的功能结构图。


    2.4 目录结构目录结构即为think php 目录结构,再次不做介绍。
    第三章 数据库设计3.1 商品分类表(itcast_category)


    字段名
    数据类型
    描述




    cid
    Int unsigned
    主键ID,自动增长


    cname
    varchar(20)
    商品分类名称


    pcname
    varchar(20)
    父类分类名称



    3.2 商品表(itcast_goods)


    字段名
    数据类型
    描述




    gid
    varchar(255)
    主键ID,自动增长


    gname
    varchar(255)
    商品名称


    price
    int
    商品价格


    thumb
    varchar(255)
    商品图片路径


    status
    Enum(‘no’,’yes’)
    是否上下架,上架为yes,否则为no


    description
    text
    商品描述


    stock
    int
    商品库存


    cid
    Int unsigned
    商品分类ID


    sales
    int
    商品销量


    turn
    Int unique
    排序码,自动增长



    3.3 会员信息表(itcast_member)


    字段名
    数据类型
    描述




    mid
    Int unsigned
    主键ID,自动增长


    user
    varchar(20)
    会员昵称


    email
    varchar(30)
    会员电子邮件地址


    pwd
    char(32)
    会员登陆密码


    birthday
    date
    会员生日



    3.4 会员收货地址表(itcast_address)


    字段名
    数据类型
    描述




    aid
    Int unsigned
    主键ID,自动增长


    mid
    Int unsigned
    会员ID


    consignee
    varchar(20)
    收货人姓名


    phone
    varchar(11)
    电话号码


    postcode
    varchar(6)
    邮政编码


    address
    varchar(255)
    收货地址


    freight
    int
    运费



    3.5 购物车表(itcast_shopcart)


    字段名
    数据类型
    描述




    scid
    Int unsigned
    主键ID,自动增长


    mid
    Int unsigned
    会员ID


    addTime
    timestamp
    加入购物车时间


    gid
    varchar(255)
    商品ID


    num
    tinyint(3)
    商品数量



    3.6 购买记录表(itcast_record)


    字段名
    数据类型
    描述




    rid
    Int unsigned
    主键ID,自动增长


    mid
    Int unsigned
    会员ID


    time
    timestamp
    购买时间


    gid
    varchar(255)
    商品ID


    num
    tinyint(3)
    商品数量


    price
    Int unsigned
    商品单价



    3.7 折扣商品表(itcast_discountgoods)


    字段名
    数据类型
    描述




    dgid
    Int unsigned
    主键ID,自动增长


    gid
    varchar(255)
    商品ID


    discount
    int
    折扣



    第四章 具体功能实现4.1 前台具体功能4.1.1 公共部分

    显示登录后的用户昵称、退出登录
    分类搜索商品
    进入各个功能模块
    登录按钮
    登录后查看购买记录、进入购物车



    购物车简要信息:总价(折扣前)、数量
    商品分类,点击即可查看该分类下的商品



    显示当前销量最高的商品


    网站相关信息
    联系方式

    4.1.2 主页
    滚动广告


    推荐商品


    新品推荐

    4.1.3 商品列表页
    商品列表页
    例如,在任一页面的导航栏的搜索框中输入关键词——手机,选择“手机”分类,点击“搜索”按钮。

    之后就可进入商品列表页,该页面显示了所有在指定分类下与关键词相关的商品。

    此时可点击排序下拉菜单,对商品进行排序(默认按照新品排序),例如按照价格升序排列

    类似还可进行:“新品”、“价格降序”、“销量”方式排序。

    折扣商品列表页
    若点击导航栏的“特价优惠”链接,即进入折扣商品列表页

    4.1.4 商品详情页
    查看商品信息
    在任何页面的商品列表点击指定商品,即可查看该商品的详细信息。

    此时,点击“相关商品”按钮,可查看该与该商品相关的其他商品。
    有两种查看方式:



    加入购物车
    会员登录后,在详情页选择购买数量,点击“加入购物车”按钮即可将选择的商品加入购物车。
    4.1.5 会员注册、登录在任一页面的导航栏点击“登录”按钮,即可进入下图所示页面:

    左部为注册框,右部为登录框。

    注册
    在注册框中输入要创建账户的邮箱地址,点击“创建”按钮

    进入下图所示页面填写会员详细信息。

    点击“注册”按钮,即完成了会员注册操作。

    登录
    在登录页面填写正确的邮箱、密码和验证码,点击“登录”按钮即可成功登录。

    若验证码填写错误,页面将显示如下提示信息,并返回登录页面。
    若用户名或密码填写错误,页面将显示如下提示信息,并返回登录页面。
    4.1.6 购物车
    简介
    登录成功后即进入购物车页面(新用户购物车为空),用户可在该页面对加入购物车的商品进行购买。

    假设会员已将自己心仪的商品加入到购物车,购物车页面将自动计算总价。


    更改购物车商品
    此时,会员可通过点击每个商品的“+”、“-”按钮对该商品数量进行增加和减少操作。

    若会员不想购买某件商品,可点击“×”按钮从购物车中删除该商品。


    购买商品
    点击“购买”按钮即将购物车中的商品全部购买。

    4.1.7 购买记录点击上方导航栏的“购买记录”按钮或点击下方页脚的“购买记录”超链接

    即可进入购买记录页查看购买记录。

    4.2 后台具体功能4.2.1 登录页面在登录页面填写正确的用户名、密码和验证码,点击“登录”按钮即可成功登录。

    若验证码填写错误,页面将显示如下提示信息,并返回登录页面。
    若用户名或密码填写错误,页面将显示如下提示信息,并返回登录页面。
    4.2.2 公共部分
    显示标题
    显示管理员名称
    “前台首页”超链接
    “退出登录”按钮



    左部导航栏,点击链接可进入相对应模块
    4.2.3 首页欢迎页面,引导管理员进行操作。

    4.2.4 商品添加在左侧导航栏点击“商品添加”链接进入商品添加页面。
    依次按要求填写商品信息,上传图片。

    点击“确定”按钮,即完成商品添加操作。
    若商品编号重复,则不添加该商品,直接进入商品修改页修改该商品。

    4.2.5 商品查看、修改、删除
    查看
    在左侧导航栏点击“商品列表”链接进入商品列表页面。

    管理员可对指定分类下的商品进行排序(默认对所有商品按照新品排序),例如对“手机—手机”分类按照价格升序排序:


    修改
    点击“修改”可以对指定商品属性进行修改(商品编号不可修改)。


    删除
    点击“删除”

    点击“确定”

    可以看到商品列表中编号为“562390304003”的商品已经被删除。

    4.2.6 查看、添加、删除商品分类
    查看商品分类
    在左侧导航栏点击“商品分类”链接进入商品分类列表页面


    添加商品分类
    点击商品分类列表页的“添加分类”按钮,即可进入商品分类添加页面。例如,选择一级分类为“电脑/办公”,分类名称为“服务器”


    删除商品分类
    点击商品分类列表页每一个商品分类对应的的“删除”
    可以看到商品分类列表页中名为“服务器”的商品分类已经被删除。

    查看会员信息
    在左侧导航栏点击“会员管理”链接进入会员信息列表页面

    点击每个会员的“查看详情”操作,可以查看该会员的详细信息和购买记录

    第五章 总结与心得体会通过这次网上商城开发,让我清楚认识到软件工程的重要程度,软件项目涉及到以下阶段,即计划阶段、需求分析、软件设计、编码、测试阶段、运行维护等。经过一段时间的努力,我们终于完成了网上商城网站系统,基本实现了题目的基本要求。总的来说,在做这个毕业设计的过程中,我们查阅了大量关于网上销售的相关资料,切实地按照软件工程的步骤,从需求分析,概要设计,详细设计,数据库设计,再到编码,调试运行,测试等步骤。从中我学到了很多东西,对我们来说,无论是理论还是实践上都是一个较大幅度的提高,可以说是理论到实践的一个飞跃。我还了解了软件开发的大体过程,在当今竞争激烈的社会中只有学到本领才能有立足之地,通过这次综合实验也使我们知道做软件开发的辛苦,首先要有足够的耐心,要勇于面对密密麻麻的代码,无数遍的调试,和无数遍的修改,但是,当调试成功时,你就会感到这些努力的意义,成功的喜悦。软件开发,还要注意借鉴,查看已有的例子的代码,这样可以节省大量的时间,同时也实现了代码重用。此外,我知道了基础课的重要,要学好一门编程语言,一定要动手,实践是最好的方法!
    2 评论 69 下载 2019-05-23 17:50:58 下载需要13点积分
  • 基于C#和Sql Server的餐厅点餐系统

    1 需求分析1.1 信息要求目前大多数酒店由于规模的限制,忽略了点菜系统的重要性。点菜系统专为具有一定规模和经济条件的 大型酒店设计,通过集成从顾客定桌、点菜、上菜到结账等一系列功能,为每个环节明确分工,并通过可视 化的软件支持,有效减小人为差错的概率,代之以高效、便捷、准确的数字化服务系统,使酒店的管理更加 规范化。 因此该系统应当可以对餐桌信息、菜谱信息、职工信息以及顾客信息进行管理,同时点菜系统少不了订 单,因此也应该能对订单包括过去、现在、未来订单进行管理。
    1.2 处理要求系统应当允许对服务员信息、菜单信息、厨师信息、房间信息、餐桌信息的管理:

    查询、增、删、改及预定服务:顾客可以根据自己的需求,预定不同型号的房间或大厅,餐桌和时间就餐
    点菜功能:顾客可以自行点菜,也可以让管理员代为服务,点菜后能生成订单为对其进行后序的做菜上菜结账评价等服务
    厨师做菜服务:厨师会根据订单状态主动工作。厨师和菜分别分组,每组厨师和一组菜一一对应,该组 每位厨师会做该组所有的菜。厨师做菜管理:厨师可以获得自己的待做菜单,并对已做的菜进行标记
    结账、评价服务:审核菜单,协助顾客结账。结账完成后可以对订单进行评价,选出自己喜欢的菜。在查看自己个人信息时可以看到自己常点的菜。评价除了是对菜的评价,也是对做这道菜的厨师进行评价,方便日后拓展对厨师业绩进行考核的功能

    1.3 安全性与完整性要求顾客能对自己的信息进行编辑,不能对其他信息进行任何编辑。对于房间和餐桌信息也只能看到可用的 房间和餐桌。而且无法获取职工的信息包括其工作状态。同时顾客没有任何删除数据的权限,即使是自己的 数据也无法删除。管理员用于几乎对所有实体信息进行编辑,包括增、删、查、改。当然在操作前应当检查操作的数据是 否合法,例如增加顾客时,顾客联系方式应当是数字,且固话应当是 8 位或 12 位,手机应当是 11 位等。 这些理应属于数据库的用户定义完整性约束,但在此交由高级语言实现。 但是对于部分信息只能由系统产生和修改,例如订单号的生成是自动完成的,管理员也无法干预。顾客评价后系统会对相应的菜谱和厨师进行业绩属性的修改,这也是系统自动完成的。与订单相关的信息目前 只能由系统增加和更改其状态(是否上菜或结账),这部分信息为了保证完整新和安全性,是无法删除的。 再例如房间和餐桌的信息,房间中的餐桌数和使用情况也是有系统自动更新完成,为防止用户不当操作,不允许管理员直接对这部分信息进行修改。 数据库设计时应当考虑实体有实体完整性约束,实体之间联系产生的表具有参照完整新约束,对于部分 属性有根据语义定义的用户定义完整性约束。
    2 概念结构设计2.1 六个实体根据需求分析,本系统共有六个实体,即服务员,厨师,顾客,房间,餐桌,菜谱,他们的属性如
    2.3 中的 E-R 图所示2.2 实体之间的联系大部分联系是多对多的联系,如服务员服务顾客等;也有一对一联系,如一个顾客只能坐一张桌子;一 对多的联系主要体现在一个房间可以有多张餐桌。大部分联系是二元联系,而且会产生其他属性,如顾客和餐桌的联系会产生一个订单号。
    2.3 完整 E-R 图
    3 逻辑结构设计3.1 实体对应的关系模式
    Chref ( COid, COname, COsex, COjob, COifwork, CObethumbup )
    Waiter (Wid, Wname, Wsex, Wifwork )
    Desk ( Did, Droomid, Dpersoncount, Difuse )
    Room (Rid, Rname, Rdeskcount, Rpersoncount, Rusedesks )
    Customer ( Ctellphone, Cname, Csex, Ccometimes, Cregularfood1, Cregularfood2, Cregularfood3 )
    Menu ( Fid, Ftype, Fname, Fprice, Fcooktime, Fthumbup )

    3.2 联系对应的关系模式
    厨师工作记录:ChrefMenu (COid, Fid, Ordernum, Ifthumbup )
    订单记录:CustomerDesk ( Ctellphone, Did, Ordernum, Orderdate, Ifcheckout, Ordermoney)
    顾客点菜历史:CustomerMenu (Ctellphone, Fid, Lastordertime, Ordercount, Ifthumbup )
    上菜状态记录:DeskMenu (Did, Fid, Ordernum, Ifservedish )

    4 数据库实施4.1 数据库的创建4.1.1 表的创建其中包含了实体完整性,即主码必须唯一且不为空。默认违约处理是拒绝插入和修改。详细表的建立见 如下截图。


    4.1.2 用户定义完整性(CHECK)对于部分属性,其值有语义要求,因而需要定义 CHECK 约束,如顾客、职工的性别(只能是男或女), 职工的工作状态(只能是空闲或繁忙),上菜状态和订单结账(只能是是或否),部分截图如下:



    4.1.3 参照完整性参照完整性约束主要是外键的定义。在本系统中,除顾客表外其他表的顾客联系方式都是外键,被参照 关系是顾客表。除订单表外的订单号都是外键,被参照关系是订单表,厨师编号、菜编号、房间号同理,它 们对应的被参照关系是厨师表,菜谱表,房间表。下图是 sql server 中自动生成的数据库关系图,比较直观 地看到参照完整性情况。

    4.2 数据库的操作根据需求分析知道具体要对具体表的操作。
    4.2.1 增(插入,insert)顾客预订或点菜后,实际上是只要顾客选择好座位后会生成订单并插入到订单表中,对应的的插入语句 是:为了方便日后维护,参数化 sql 的语句的建立不用 string 类而是用 StringBuilder 类,该类在处理大量字 符串时效率低,但是应对 sql 语句这种不长的字符串不会对效率产生副作用,而且建立过程十分直观,方便日后维护。
    4.2.2 删(delete)删除操作顾客是没有的,只有管理员,而且仅仅限于对顾客信息,职工信息,餐桌信息,房间信息。其 他信息是无法删除的。由于考虑到参照完整性约束,这些删除操作都不是独立的,应当考虑到参照表。
    4.2.3 查(select)查询是最常见的数据库操作,本系统允许用户根据需求查询,例如点击某类菜的种类,就能看到该种类 下的菜谱,再例如点击对应的厨师,应当能显示该厨师的工作记录等。同时点菜时支持对菜名的模糊查询。
    4.2.4 改(update)管理员对数据的修改和删除一样限制在几个表中,顾客其实也可以间接修改数据,例如点赞某道菜的时 候实际上是在修改点赞情况。其他的修改操作均有系统自动完成,例如上菜状态更新,账单状态更新等,还有对顾客常点的菜的更新和厨师被点赞的次数都是系统完成。
    5 数据库运行和维护5.1 数据库与 C#的连接将连接字符串保存在配置文件中,调用时直接调用配置文件中的信息这样做的好处是程序移植时只需要修改配置文件中的连接字符串即可,不需要修改任何程序,同时也方便程序编写时的调用。连接字符串的修改也非常简单,可以有系统自动生成。

    连接字符串使用 C#提供的 SqlConnection 类,包含在命名空间 system.Data.SqlClient 中,调用构造函数时 需要传参,参数是连接字符串。
    5.2 高级语言 C#对数据库的操作引用较为典型的 ADO.NET 结构图,其中为了能尽可能的练习 sql 语句,本次实验没有用到 DataAdapter 下的 4 个 Command 对象,这些方法是系统根据用户直接在 DataAdapter 上的修改操作自动生成对应的 sql 语句去更新数据库,但仅限于当个表的数据。同时也没有使用右边的 DataSet 和 XML,因为 DataSet 是针对 需要连接外服务器数据库而设定的本地高速缓冲区,但实验所用的数据库是本地的,而且操作量不大, DataSet 本身也比较占用资源。

    5.3 防止非法数据插入数据库的提示这部分主要是通过 C#提供的 MessageBox 控件和下拉框完成。非法数据的来源主要是用户的不正当操 作,例如数据长度不正确,格式不正确等。下面展示在新增顾客时,顾客输入联系方式时意外输入非数字字 符的情况,这是通过 MessageBox 完成提示。以及新增餐桌时需要输入餐桌所在的房间,这是通过下拉框实 现。


    5.4 意外退出系统后重起系统的初始化操作由于厨师做菜等功能并非由数据库完成,而是存放在内存中,系统一旦退出数据无法存入到数据库(例如做菜剩余的时间)。如果再次进入系统时不对还没完成的订单进行检索,那么这些订单的没上的菜在系统 中将一直不会被厨师烹饪。因此进入系统后会先检索是否还有没上的菜,有的话会加入到做菜队列,并触发 厨师做菜的事件。核心代码如下:
    5.5 正常退出系统的数据库更新操作正常注销退出系统时,会对已完成订单和菜进行归总,更新厨师被点赞次数以及更新顾客常点的菜,保证数据的完整性。
    6 系统演示、使用手册6.1 开始界面开始界面有当前时间,欢迎词,还有使用者身份选择。进入管理员需要输入账号和密码。

    6.2 顾客界面6.2.1 添加顾客信息不需要注册,顾客只需要输入自己的信息,系统会自动检索数据库,如果没有则自动插入,有则把信息 查找出来并显示。信息包括姓名、联系方式、常点的菜。

    6.2.2 修改顾客信息点击修改信息,左边的框会可以以输入,修改完信息后点击确定即可。
    6.2.3 预定功能在菜单栏中选择“进入用户界面”

    在弹出的窗口中输入信息,点击“确定”

    选择“预定”

    填写预定信息,然后点击“预约”,即可完成预约

    6.2.4 就餐(选座,就餐)就餐步骤前两步同预约操作前两步,完成后进入如下页面





    6.3 管理员界面上面是菜单栏,点击对应的按钮会显示相应的界面,下面是状态栏,显示单位、时间以及作者。详细功 能见下面描述。

    6.4 房间和餐桌管理6.4.1 增加和修改房间信息

    若要修改房间信息,只需要选中要修改的房间,点击“修改房间信息”,然后修改房间名即可。
    6.4.2 增加餐桌进入“房间和餐桌信息”页面,在“当前房间的餐桌概况”中选择“添加餐桌”,录入餐桌信息后,点 击“确定”,即可完成操作

    6.4.3 删除房间和餐桌
    6.5 职工管理6.5.1 界面介绍职工管理界面分为三部分:服务员信息,厨师基本信息,做菜历史。“服务员信息”栏和“厨师基本信息”栏都提供三种功能:雇佣、解雇、编辑功能。管理员可以雇佣和解雇员工,或者修改员工的信息。“做 菜历史”栏可以查看厨师的做菜信息,查看该厨师做的菜是否被点赞。

    6.5.2 对职工信息的操作(增、删、改)以添加厨师信息为例:点击“雇佣”,在弹窗输入员工信息,点击添加,即可完成操作。删除操作只需 要选中要删除的员工,点击解雇,即可删除。编辑操作只需选中要修改信息的员工,点击修改,填写新的信息,即可完成 。

    6.6 订单管理6.6.1 界面介绍当在用户界面内,完成前面的操做提交订单之后,即可点击“订单管理”进入订单管理页面对订单进行 管理。如下图所示:在“当前订单”页面我们可以看到当前正在处理的订单,点击正在处理的订单,我们可 以在右侧查看该订单内所点的菜是否已经全部上菜。若菜已经全部显示“是”则表示菜已全部上齐,则顾客结账时可以点击结账按钮,进行结账。除此之外我们同样可以在订单管理页面对历史订单进行查看(该部分 在下面会单独介绍)。

    6.6.2 查看历史订单在订单管理中我们同样可以查看历史订单的情况,方便餐厅管理人员对老顾客所喜爱的菜色进行统计, 以达到可以为用户推荐菜色的功能。在“历史订单”窗口中我们可以对历史订单进行点击查看历史订单中所 包含的菜的种类以及菜的价格。在历史订单中我们可以对日期进行选择查看具体某一天之前的订单,当取 消对该项的选择时,则表示只查看当天的订单情况。

    6.6.3 点菜功能订单管理页面中同样存在点菜的选项,该选项是为了给使用预约功能的顾客点菜所使用的。当根据订单 号查询到该预约信息时,我们可以点击点菜,为该订单进行点菜。

    6.6.4 结账功能当订单中的菜,全部上完后。点击结账(如下图:)会弹出下图左侧的页面,方便用户对订单中的菜进行核对,以及对价格存在问题的菜进行查看,确定所应付款金额。

    6.6.5 点评功能
    6.7 顾客管理6.7.1 界面介绍在主页面中点击“顾客管理”页面可以对顾客的信息进行操作和分析。顾客管理页面由所有顾客信息, 当前顾客信息,顾客的光顾记录,和点菜历史四部分组成。通过这四部分我们可以完成对所有顾客的信息和订单进行管理。各部分具体的功能在下面会有具体的介绍:

    6.7.2 对顾客信息的操作(增、删、改)在所有顾客信息部分我们可以对顾客的信息进行增加、删除、和修改的操作。下面,我们以删除顾客信 息的操作进行详细讲解。在所有顾客信息窗口中点击要删除的用户,就可以在当前顾客信息中看到顾客的 具体信息,此时,点击删除顾客信息,就会弹出操作确认的信息窗口,避免使用者错误操作,造成用户信息 的丢失。若该操作无误,则点击确认即可删除当前所选的顾客的信息;点击顾客之后即可在当前顾客信息处 完成对顾客信息的修改;点击新增顾客后输入当前顾客信息即可完成新增顾客的操作。

    6.7.3 光顾功能选中顾客信息后,点击光顾即可为顾客添加新的订单。在当前顾客信息下面点击光顾按键,则会弹出房间和餐桌信息界面,此界面下的操作和介绍我们在之前都有介绍,在此处就不再赘述。

    6.7.4 光顾历史记录在所有顾客信息部分,点击某个顾客。在光顾记录部分会显示该顾客在本餐厅的所有的订单情况。以及 该顾客的所有点菜历史,其中包括每种菜被点的次数和该顾客对这种菜的评价信息。该部分主要被用于数 据库有用信息的挖掘,了解顾客对每种菜的喜爱程度,从而做到为顾客推荐本店所添加的新的菜色,以及对餐厅未来菜色的发展策略提供理论依据。

    6.8 菜谱管理6.8.1 界面介绍菜谱管理主要是为了完成对餐厅菜谱的菜进行增加、删除、和修改而创建的,该页面除了完成最初设立 的功能外,还可以根据不同菜的具体信息对菜进行查找。同时还可以查询点过这道菜的顾客都有哪些。最主要的是该也也可以调用已有的用户信息为用户点菜提供便利。

    6.8.2 对菜谱的基本操作(增、删、改)在菜谱中点击一种菜之后点击修改,会弹出图中所示的窗口,使用者只要输入所要修改的信息之后,再 次点击修改菜谱窗口中的修改,即可确认对菜的信息进行修改,此时菜谱中就会显示修改后的信息。点击添 加按键,录入菜的信息后再次确认即可完成对菜的添加;对菜的删除,选中一种菜后点击删除再次确认即可 完成对菜的删除。

    6.8.3 快速查找和模糊查找快速查找和模糊查找,是为了避免客户点菜时总是要翻阅全部菜单浪费时间而设计的。因为快速查找只 要输入菜的名字就可以对菜进行定位比较简单,所以这里我们对它不再做过多的介绍;模糊查找用户只要 输入部分信息,系统既可以对数据库进行访问,然后返回能够匹配到用户输入的关键字的菜。

    6.8.4 快速下单快速下单是为了方便用户的点菜而设计的。只要在菜谱管理页面,点击“点菜”,即可选择数据库中已 有的顾客,为他选择餐桌。在该页面直接就可以为顾客点菜。因为具体点菜操作在前面我们都已经详细介绍 过了,在这里我们就不再对其进行赘述。
    7 体会一开始走入了一个误区,那就是为了省空间而尽量少的建立表,其实这是一个极端。举个例子,当时我 一致认为顾客的订单中的菜可以通过视图来查看,因为视图在数据库中属于外模式,不会占用磁盘存储空 间,而且能用有效地限制用户的权限,而视图名就是订单号,这样通过订单号就能对订单进行操作。实际上 这个想法是不好的,因为订单承载了很多信息,从系统可拓展性来说,这是不利的,而且实际上对视图的操 作不仅仅会限制用户的操作,也会限制自身编程的操作。因此我们前后期大部分修改了我们的需求分析和 概念结构设计。
    对于数据库的建立,我深深地每个表建立一个唯一的 id 标识是很重要的,这个 id 标识是主属性。即使 实体中原本的属性就有能唯一标识元组的属性,但也不应该直接设置为主码,而应该再设置一个 id,使用关 系数据库自身提供的自增长类型即可,这样无论什么用户都不能对这个 id 修改,插入元组时数据库会自动 生成。这样做的好处是因为主码的值是可能修改的,例如顾客的联系方式,没有 id 的话不利于参照完整性 的实现,尤其是修改操作。
    本次实验的核心工作是高级语言 C#编码与数据库的连接,之前没接触过 C#,纯属是现学现用,感觉学 到了很多,也提高了自己的自学能力。同时让我基本入门了一门语言,C#真是一门有趣的高级语言。也就是 在编程的时候和书上所学的知识结合起来,才进一步领略到数据库的重要性和数据库的应用,以及进一步 理解书上的知识,例如游标的概念,其实和高级语言中的流是一个道理的,这种东西在使用时有一定的规则 需要注意,例如不能两个同一对象流一起使用等。实验使我对高级语言的编写和调试以及一个项目的过程,
    数据库的设计都有了进一步的掌握。实际应用中的数据库设计会比我们课程设计要复杂得多,这次实验也 让我们对流程有所了解,方便日后的深入学习。 在实际编程时候,sql 语句往往是动态的,需要根据动态参数设定,这当中最容易出错的是字符串,由 于 sql sever 查询语句中的字符串时用单引号的,但是高级语言一般都是双引号的,这方面容易出错。在者 就是再编辑 sql 语句的时候容易把单引号漏掉,导致数据库操作异常。该问题本质上还是 sql 语句的练习不 够多而造成的,因此平常要注意多加练习。 当然我也认识到我们的系统还是有很多不足,除了数据库设计上的不足外,还有系统本身功能的不足, 例如顾客如果订很多张餐桌的话,每个单子的菜必须一致,且确定订单和结账都要操作多次,不利于用户体 验,再者不能重复点菜。各个表的主码中,只有订单号是系统自动生成,其他均由顾客自己输入,不利于管理。许多过程不可逆,例如无法没有取消订单功能等。还有很多细节上的还有缺陷,日后应当多加学习。
    5 评论 107 下载 2019-03-12 11:55:16 下载需要14点积分
  • 基于JAVA实现的农夫过河问题

    1 题目要求一个农夫带着一只狼,一只羊和一个白菜,身处河的两岸。他要把这些东西全部运到北岸。他面前只有一条小船,船只能容下他和一件物品,另外只有农夫才能撑船。如果农夫在场,则狼不能吃羊,羊不能吃白菜,否则狼会吃羊,羊会吃白菜,所以农夫不能留下羊和白菜自己离开,也不能留下狼和羊自己离开。请求出农夫将所有的定西运过来的方案。
    最终的状态表描述出来就可以了。
    测试与运行
    使用状态表,程序应在屏幕上得到如下表所示的结果。

    2 设计思路利用九个硬币的原理,设计农夫过河问题
    类图

    3 测试
    测试环境

    Windows10JDK1.8IDEA2017.2
    测试结果

    1 评论 19 下载 2018-12-06 14:53:35 下载需要6点积分
显示 60 到 75 ,共 15 条
eject