分类

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

资源列表

  • 基于ASP.NET实现的大学BBS论坛

    一、分析与建模1.1 系统业务流程图
    1.2 可行性分析1.2.1 法律可行性该理工学院的BBS论坛系统是为了方便理工学院的大学生进行学习、生活、考研、就业、二手交易、心得体会交流的交流社区网上系统,且规范相关部门工作流程,也可以解决现阶段所大学生一些存在的许多问题,没有违反国家相关法律法规,该项目在法律上是完全可行的。
    1.2.2 技术可行性理工学院的BBS论坛系统,采用SQL Server数据库作为系统的数据存储容器,其强大的备份恢复机制保证了数据的安全性。同时,还是具有高效的结构化查询语言的支持,让系统可以在庞大的数据中很容易得到所需要的统计与分析。前台采用HTML+CSS+JavaScript+ASP.NET等技术,实现了较为友好的人机交互。目前,该项目所需的技术都已经有对应的产品,因此该项目在技术上是可行的。
    1.2.3 经济可行性经过有效的成本/效益分析所计算,得到的净现值是正数,说明该项目收益率为正数,有投资的价值。并且使用该理工BBS论坛系统可大大的增加我校理工的大学生在衣食住行学的多个方面的及时沟通,还可以与附近的湖北师范大学的学生一起进行思想上面的沟通,生活上面的便利交流。最为关键的是相当提供了一个有效的信息沟通平台。增加了许多的便利和一些事情的公开与透明。同时大提高学生学习的效率,缩短信息处理周期,也可以教学质量更上一个台阶,。且在还可以在成功运行试水之后,合适的话,到其他的大学进行推广。从而收取部分经济效益。达到回本和盈利的目的。综合以上分析,该系统的开发在经济上是可行的。
    1.2.4 操作可行性BBS论坛系统是完全根据我校大学生的具体需求量身定制了,在工作流上完全细心周到的服务 。此外,系统的用户交互设计较为友好,功能分明,操作简单,且提供了较为详细的用户简介使用手册和具有良好的新手指导功能。因此,该系统在操作上是可行的。
    1.3 功能需求分析与建模
    1.4 数据需求分析与建模任何一个软件系统本质上都是信息处理系统,对软件设计有深远影响,因此,必须分析系统的数据要求, 而这里为了把用户的数据要求清楚、准确地描述出来,我通过建立E-R图来进行描述,表示的是系统的E-R图。

    二、系统设计2.1 功能结构设计
    2.2 数据库设计2.2.1 实体以及相关的属性
    用户表(t_user)用户编号(唯一,自增长),邮箱,头像,手机号码,网名,密码,注册时间(唯一),性别,真实姓名,身份标识
    小板块表(t_section)小板块编号(唯一,自增长),所属大板块编号,用户编号,小版块名称,小版块标志
    大板块表(t_zone)大板块编号(唯一,自增长),大板块名称,大板块简介
    帖子表(t_topic)帖子编号(唯一,自增长),用户编号,小版块编号,帖子内容,修改帖子时间,第一次发帖时间,帖子标题,帖子点赞数,帖子置顶标记
    回帖表(t_reply)回复帖编号(唯一,自增长),最后回帖时间,回帖时间,回帖内容,回复的帖子标题

    2.2.2 实体之间的联系
    一个用户可以发表多个帖子(一对多的关系)
    一个用户也可以有回复多个回帖(一对多的关系)
    一个用户可以是多个小板块的版主(一对多的关系)
    一个小板块只能够是属于一个大板块空间的(一对一的关系)
    一个大板块空间是可以有多个小板块的(一对多的关系)
    一个帖子可以有多个回复的帖子(一对多的关系)

    2.2.3 物理模型图
    2.2.4 生成的属性信息等关系所有的表



    序号
    中文
    名称
    代码
    数据类型




    1
    回帖
    t_reply
    t_reply



    2
    小板块
    t_section
    t_section



    3
    帖子
    t_topic
    t_topic



    4
    用户
    t_user
    t_user



    5
    大板块
    t_zone
    t_zone




    所有表的属性



    序号
    中文
    名称
    代码
    数据类型




    1
    编号
    id
    id
    int


    2
    名称
    name
    name
    Variable characters (100)


    3
    描述
    description
    description
    Variable characters (200)


    4
    标号
    id
    id
    int


    5
    邮箱
    email
    email
    Variable characters (100)


    6
    头像
    face
    face
    Variable characters (200)


    7
    手机号
    mobile
    mobile
    Char(11)


    8
    网名
    nickname
    nickname
    Variable characters (50)


    9
    密码
    password
    password
    Char (20)


    10
    注册时间
    regtime
    regtime
    Data&Time


    11
    性别
    sex
    sex
    Char(2)


    12
    真实姓名
    truename
    truename
    Char(20)


    13
    身份类型
    type
    type
    Char(4)


    14
    编号
    id
    id
    int


    15
    大板块编号
    t_z_id
    t_z_id
    int


    16
    用户编号
    t_u_id
    t_u_id
    int


    17
    名称
    name
    name
    Char(50)


    18
    标志图片
    logo
    logo
    Char(20)


    19
    编号
    id
    id
    int


    20
    用户编号
    t_u_id
    t_u_id
    int


    21
    大板块编号
    t_s_id
    t_s_id
    int


    22
    内容
    content
    content
    Variable characters (1000)


    23
    修改时间
    modifytime
    modifytime
    Data&Time


    24
    回复时间
    publishtime
    publishtime
    Data&Time


    25
    标题
    title
    title
    Variable characters (100)


    26
    点赞数
    good
    good
    Char(4)


    27
    置顶标记
    top
    top
    Char(4)


    28
    编号
    id
    id
    int


    29
    帖子编号
    t_t_id
    t_t_id
    int


    30
    用户编号
    t_u_id
    t_u_id
    int


    31
    最后回复时间
    modifytime
    modifytime
    Data&Time


    32
    恢复时间
    publishtime
    publishtime
    Data&Time


    33
    内容
    content
    content
    Variable characters (100)


    34
    标题
    title
    title
    Variable characters (1000)



    2.3 关键算法设计在这里一共进行了三个相关的算法,分别是服务器异常断开、重启状态、等突发事件算法设计,头像图片上传算法设计和用户相关信息防泄漏算法与设计。
    2.3.1 服务器异常、突发事件算法设计
    2.3.2 图片文件上传算法设计
    2.3.3 用户相关信息防泄漏算法与设计
    2.4 UI设计2.4.1 用户登陆UI设计
    2.4.2 用户注册UI设计
    2.4.3 置顶、精品UI设计
    2.4.4 大板块查看UI设计
    2.4.5 小板块查看UI设计
    2.4.6 回帖跟帖UI设计
    2.4.7 发帖UI设计
    2.4.8 小板块增加删除主题UI设计
    2.4.9 删帖修改帖子UI设计
    2.4.10 个人中心UI设计
    2.4.11 后台登录UI设计
    2.4.12 大板块增加删除查询UI设计
    三、系统实现中的重难点3.1 系统实现环境该系统采用Microsoft Visual Studio 2015的.Net Frame 4.5作为框架,页面使用了Html+Javascript+ASP.Net作为B/S模式下的前台开发工具,C#作为B/S模式下的后台编码语言,ASP.NET作为B端的数据访问技术,SQL SERVER 2012作为后台的数据库,页面的加载、效果作为div+css作为网页布局。

    开发硬件环境:个人笔记本电脑
    开发软件环境:win10 x64/ Visual Studio 2015/ SQL SERVER 2012/谷歌浏览器稳定版/火狐浏览器

    3.2 系统编码重难点重难点之多条件查询
    3.2.1 界面
    3.2.2 web代码<div class="container-fluid"> <div id="tooBar" style="padding: 10px 0px 0px 10px;"> <button class="btn btn-primary" type="button" data-backdrop="static" data-toggle="modal" data-target="#dlg" onclick="return openAddDlg()">添加小板块</button>     <a href="#" role="button" class="btn btn-danger" onclick="javascrip:deleteSections()">批量删除</a> <form method="post" action="/backstage/SectionList.aspx" class="form-search" style="display: inline;">  小板块名称: <input name="sectionname" id="peisnname" value="<%=sectionname%>" type="text" class="input-medium search-query" placeholder="输入小板块名称..."/>  所属大板块: <select id="zid" name="zid"><option value="">请选择...</option> <%foreach( hua_bbs.Model.Zone zone in zoneList) {%> <option value="<%=zone.id%>" <%= zid == zone.id.ToString() ? "selected": "" %> ><%=zone.name%></option> <%} %> </select>  版主: <select id="uid" name="uid"><option value="">请选择...</option> <% foreach( hua_bbs.Model.User user in userList) {%> <option value="<%=user.id%>" <%= uid == user.id.ToString() ? "selected": ""%> ><%=user.nickname %></option> <%} %> </select>   <button type="submit" class="btn btn-primary" title="Search">查询 <i class="icon icon-search"></i></button> </form> </div> <div id="dlg" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" onclick="return resetValue()">×</button> <h3 id="myModalLabel">增加小板块</h3> </div> <div class="modal-body"> <form id="fm" action="SectionList.aspx" method="post" enctype="multipart/form-data"> <input type="hidden" value="saveOrUpdate" name="flag"/> <table> <tr> <td> <label class="control-label" for="sectionName">请输入小板块名称:</label> </td> <td> <input id="sectionName" type="text" name="ssname" placeholder="请输入…"> </td> </tr> <tr> <td> <img id="ImgPr" class="pull-left" style="width: 120px; height: 120px;" /> </td> <td> </td> </tr> <tr> <td> <label class="control-label" for="logo">上传logo:</label> </td> <td> <input type="file" id="logo" name="logo"> </td> </tr> <tr> <td> <label class="control-label" for="zone">请选择所属大板块:</label> </td> <td> <select id="zone" name="zzid"><option value="">请选择...</option> <%foreach( hua_bbs.Model.Zone zone in zoneList) {%> <option value="<%=zone.id%>"><%=zone.name%></option> <%} %> </select> </td> </tr> <tr> <td> <label class="control-label" for="masterNickName">版主:</label> </td> <td> <select id="masterNickName" name="uuid"><option value="">请选择...</option> <% foreach( hua_bbs.Model.User user in userList) {%> <option value="<%=user.id%>"><%=user.nickname %></option> <%} %> </select> <font id="info" style="color: red;"></font> </td> </tr> </table> <input id="id" type="hidden" name="ssid"> <input type="hidden" id="peipage" name="page"/> <input type="hidden" id="peizid" name="zid"/> <input type="hidden" id="peiuid" name="uid"/> <input type="hidden" id="peisectionname" name="sectionname"/> </form> </div> <div class="modal-footer"> <font id="error" style="color: red;"></font> <button class="btn" data-dismiss="modal" aria-hidden="true" onclick="return resetValue()">关闭</button> <button class="btn btn-primary" onclick="javascript:saveSection()">保存</button> <!-- <button class="btn btn-primary" type="submit">保存</button> --> </div> </div>
    3.2.3 数据库代码public bool MyUpdate(hua_bbs.Model.Section model) { StringBuilder strSql = new StringBuilder(); strSql.Append("update t_section set "); strSql.Append("name=@name,"); strSql.Append("logo=@logo,"); strSql.Append("t_u_id=@t_u_id,"); strSql.Append("t_z_id=@t_z_id"); strSql.Append(" where id=@id"); SqlParameter[] parameters = { new SqlParameter("@name", SqlDbType.VarChar,40), new SqlParameter("@logo", SqlDbType.VarChar,100), new SqlParameter("@id", SqlDbType.Int,4), new SqlParameter("@t_z_id", SqlDbType.Int,4), new SqlParameter("@t_u_id", SqlDbType.Int,4)}; parameters[0].Value = model.name; parameters[1].Value = model.logo; parameters[2].Value = model.id; parameters[3].Value = model.t_z_id; parameters[4].Value = model.t_u_id; int rows = DbHelperSQL.ExecuteSql(strSql.ToString(), parameters); if (rows > 0) { return true; } else { return false; } } /// <summary> /// 得到一个对象实体 /// </summary> public hua_bbs.Model.Section DataRowToSectionZoneUser(DataRow row) { hua_bbs.Model.Section model = new hua_bbs.Model.Section(); model._user = new Model.User(); model._zone = new Model.Zone(); if (row != null) { if (row["id"] != null && row["id"].ToString() != "") { model.id = int.Parse(row["id"].ToString()); } if (row["sname"] != null) { model.name = row["sname"].ToString(); } if (row["logo"] != null) { model.logo = row["logo"].ToString(); } //得到板主id if (row["uid"] != null && row["uid"].ToString() != "") { model.t_u_id = int.Parse(row["uid"].ToString()); } //得到主题id if (row["zid"] != null && row["zid"].ToString() != "") { model.t_z_id = int.Parse(row["zid"].ToString()); } //得到板主名称 if (row["nickname"] != null) { model._user.nickname = row["nickname"].ToString(); } //得到主题名称 if (row["zname"] != null) { model._zone.name = row["zname"].ToString(); } } return model; } //获得Section,Zone,User(3张表的)数据列表 public DataSet GetSectionZoneUserListByPage(string strWhere, string orderby, int startIndex, int endIndex) { StringBuilder strSql = new StringBuilder(); strSql.Append("SELECT * FROM ( "); strSql.Append(" SELECT ROW_NUMBER() OVER ("); if (!string.IsNullOrEmpty(orderby.Trim())) { strSql.Append("order by s." + orderby); } else { strSql.Append("order by s.id desc"); } strSql.Append(")AS Row, s.id,s.name as sname,s.logo,z.name as zname,u.nickname,z.id as zid,u.id as uid from " + "t_section s , t_zone z , t_user u where s.t_z_id = z.id and s.t_u_id = u.id "); if (!string.IsNullOrEmpty(strWhere.Trim())) { strSql.Append(strWhere); } strSql.Append(" ) TT"); strSql.AppendFormat(" WHERE TT.Row between {0} and {1}", startIndex, endIndex); return DbHelperSQL.Query(strSql.ToString()); } /// <summary> /// 获取记录总数 /// </summary> public int GetSectionZoneUserRecordCount(string strWhere) { StringBuilder strSql = new StringBuilder(); strSql.Append("select COUNT(*) from t_section s , t_zone z , t_user u where s.t_z_id = z.id and s.t_u_id = u.id "); if (strWhere.Trim() != "") { strSql.Append(strWhere); } object obj = DbHelperSQL.GetSingle(strSql.ToString()); if (obj == null) { return 0; } else { return Convert.ToInt32(obj); } }public bool MyDelete(int sectionid) { List<Topic> topicList = topicService.GetModelList("t_s_id='" + sectionid + "'"); foreach (Topic topic in topicList) { replyService.DeleteByTid(topic.id);//删除此主贴下的所有回帖 } topicDao.DeleteByTsid(sectionid);//删除此板块下的所有主贴 return dal.Delete(sectionid); } /// <summary> /// 获得数据列表(3表操作) /// </summary> public List<hua_bbs.Model.Section> DataTableToSectionZoneUserList(DataTable dt) { List<hua_bbs.Model.Section> modelList = new List<hua_bbs.Model.Section>(); int rowsCount = dt.Rows.Count; if (rowsCount > 0) { hua_bbs.Model.Section model; for (int n = 0; n < rowsCount; n++) { model = dal.DataRowToSectionZoneUser(dt.Rows[n]); if (model != null) { modelList.Add(model); } } } return modelList; }
    3.2.4 C#代码using hua_bbs.BLL;using hua_bbs.Model;using System;using System.Collections;using System.Collections.Generic;using System.IO;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace WebApplication.backstage{ public partial class SectionList : System.Web.UI.Page { public List<Section> sectionList { set; get; } public string pageCode { set; get; } public string sectionname { set; get; } public string zid { set; get; } public string uid { set; get; } public List<User> userList { set; get; } public List<Zone> zoneList { set; get; } private SectionService sectionService = new SectionService(); //入口方法 protected void Page_Load(object sender, EventArgs e) { string flag = Request["flag"]; if (flag == null || "".Equals(flag)) { this.show(sender, e); } else if ("saveOrUpdate".Equals(flag)) { this.saveOrUpdate(sender, e); } else if ("delete".Equals(flag)) { this.delete(sender, e); } } public void delete(object sender, EventArgs e) { string ids = Request["ids"]; string[] strid = ids.Split(','); for (int i = 0; i < strid.Length; i++) { sectionService.MyDelete(Int32.Parse(strid[i])); } Response.Write(true); Response.End(); } //添加或修改板块信息 public void saveOrUpdate(object sender, EventArgs e) { int ssid = 0; if (!Int32.TryParse(Request["ssid"], out ssid)) { ssid = 0; } string ssname = Request["ssname"]; int zzid = Int32.Parse(Request["zzid"]); int uuid = Int32.Parse(Request["uuid"]); HttpPostedFile file = Request.Files["logo"];//获取上传的图片 string logo = ""; //关于上传图片的代码 if (file != null && !file.FileName.Equals("")) { string fileName = file.FileName;//得到上传图片的文件名字 string ext = Path.GetExtension(fileName);//后缀名 if (ext == ".jpg" || ext == ".gif" || ext == ".png" || ext == ".jpeg") { string newFileNames = Guid.NewGuid().ToString() + ext; logo = "/images/logo/" + newFileNames; //img文件夹前面在加一个/表示为根目录(一级目录) string fileSavePath = Request.MapPath(logo); file.SaveAs(fileSavePath);//保存图片到服务器指定的目录中去 } else { logo = "/face/yyy123.gif"; } } else { logo = "/face/yyy123.gif"; } Section section = new Section(); section.id = ssid; section.name = ssname; section.t_u_id = uuid; section.t_z_id = zzid; section.logo = logo; sectionService.saveOrUpdate(section); //添加或者修改完成之后 this.show(sender, e); } //进行查询操作数据展示 protected void show(object sender, EventArgs e) { int pageNumber = 0; if (!Int32.TryParse(Request["page"], out pageNumber)) { pageNumber = 1; } uid = Request["uid"]; zid = Request["zid"]; sectionname = Request["sectionname"];
    3.3 系统测试在这一阶段的软件测试里面,在此列举系统的部分功能的测试,为了让大家都了解测试在网站设计过程中重要性,所以在这里将测试流程以及结果如下表暂时出来、并且做一点说明。对于其中开始的黑盒测试做了如下的一些测试,有效输入的等价类测试、无效输入的等价类测试、合法输出的等价类测试、非法输出的等价类测试、边界值的测试。
    测试用例表



    测试对象
    测试方法
    测试用例
    预期结果
    实际结果
    说明
    测试结果




    个人中心信息修改
    白盒测试
    点击“个人中心”“编辑”,输入要修改的信息等,点击“保存”
    弹出对话框提示“修改个人信息成功”
    弹出对话框提示“修改个人信息成功”
    测试和预期相符合
    成功


    发布公告
    黑盒测试
    点击“发布公告”,编写内容,点击“发布”
    弹出对话框提示“发布成功”
    弹出对话框提示“发布成功”
    测试和预期相符合
    成功


    密码修改
    黑盒测试
    输入Asd2345678
    密码修改成功
    密码修改成功
    修改密码,测试通过
    成功


    身份证号修改
    黑盒测试
    输入身份证号
    身份证号码修改成功
    身份证号码修改成功
    修改身份证号码为18位,测试通过
    成功


    图片文件上传
    白盒测试
    点击“发布公告”,编写内容,点击“发布”
    弹出对话框提示“你确定要上传”,“上传文件成功”
    弹出对话框提示“你确定要上传”,“上传文件成功”
    测试和预期相符合
    成功


    注册
    黑盒测试
    点击文件专区,“图片文件上传”,输入相关的文件信息,以及文件的路径,选择点击“提交”,点击“确定”
    弹出对话框提示“该用户已存在”,并且有记录
    没有弹出对话框提示“已存在信息”,也没有数据
    测试和预期相不符合
    失败


    成绩分数修改
    黑盒测试
    输入0
    学生成绩录入成功
    学生成绩录入成功
    教师录入学生成绩,测试通过
    成功


    密码轻度检测
    黑盒测试
    输入Qwe1234
    错误,密码长度太短
    错误,密码长度太短
    用户更改7位长度密码,测试通过
    成功


    分数类型校验
    黑盒测试
    输入99.9
    错误,分数必须为正整数
    错误,分数必须为正整数
    教师录入成绩有小数,测试通过
    成功


    权限设置,修改成绩
    黑盒测试
    修改成绩
    错误,你没有权限执行该操作
    错误,你没有权限执行该操作
    学生试图修改成绩,测试通过
    成功


    分数查询
    黑盒测试
    点击成绩页面,查询分数
    查询成功
    查询成功
    教师查询成绩,测试通过
    成功



    四、总结作为这一阶段的小学期课程的学习,其中的收获发感觉颇丰,在此之前直接接触的基于C/S架构的开发,然后设计过程之中,表之间的联系,数据的架构的过程比较较少。缺乏知识的完备性和完善性。而恰好借助这段时间的学习,我开始接触和了解具体怎么设计一个B/S架构的系统。 在这个里面,这是我写的多个asp.net项目面写的费时间最长, 耗费精力最大,首次商业化的使用MVC三层架构开发,其中在DAO控制层和Servicer业务层开发耗费力气比较大。在这个学习的中间,我觉得其中里面比较重点的知识点有:分页代码查询,多条件查询,多表查询,且有些功能比较重要,登录采用MD5加密,和验证码验证,还有勾选记住我,可以免密码登录在一定日期中,且普通用户具有发帖,评论等功能。版主具有回帖,发帖,删帖,修改个人信息等功能,管理员可以从右下角后台管理进入,登录,对大板块,小板块进行增加,批量删除,普通用户封号,添加还有整体的换肤,等功能。
    通过如上的一系列的功能的实现,其中大部分的设计的功能都是有实现,且通过了测试,但是作为这次的BBS论坛的设计与实现,其中的过程还是又遇到一些不会无法实现的地方,但是在学习的过程中,有老师的耐心讲解和思路上面的引导,和实例的书写,和最后的经过自己百度和谷歌,查询一些博客和资料之后,自己终于解决了,还是感觉非常开心的。在这里也,也今后的之学习路上,感觉自己还是有很多的不会,但是我相信自己,经过自己的学习,多听有着丰富经验的人的话。可以避免少走很多的弯路。让自己学的又快的又稳。展望未来。也希望自己的以后能够学习更多的知识。
    1 评论 4 下载 2019-08-15 09:00:33 下载需要12点积分
  • 基于react框架和MYSQL数据库的社团管理系统

    一、技术简介1.1 ReactReact 可以非常轻松地创建用户交互界面。为你应用的每一个状态设计简洁的视图,在数据改变时 React 也可以高效地更新渲染界面。以声明式编写UI,可以让你的代码更加可靠,且方便调试。创建好拥有各自状态的组件,再由组件构成更加复杂的界面。无需再用模版代码,通过使用JavaScript编写的组件你可以更好地传递数据,将应用状态和DOM拆分开来。
    1.2 JSX一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面。
    JSX 是在 JavaScript 内部实现的。我们知道元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。
    1.3 webpackwebpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
    1.4 npmnpm 是 JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码,管理项目依赖关系。
    1.5 YarnYarn 对代码来说是一个包管理器,可以通过它使用全世界开发者的代码, 或者分享自己的代码。Yarn 做这些快捷、安全、可靠。
    通过Yarn可以使用其他开发者针对不同问题的解决方案,使开发过程更简单。 使用过程中遇到问题,可以将其上报或者贡献解决方案。一旦问题被修复, Yarn会更新保持同步。
    1.6 iViewiView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品。
    1.7 Ant Designantd服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。
    1.8 Eggegg.js是阿里推出的基于koa的node开发框架。为企业级框架和应用而生。Egg 的插件机制有很高的可扩展性,一个插件只做一件事(比如 Nunjucks 模板封装成了 egg-view-nunjucks、MySQL 数据库封装成了 egg-mysql)。Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低。
    Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader 可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定。
    1.9 JSON Web TokenJSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。它是一个很长的字符串,中间用点(.)分隔成三个部分。客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
    1.10 KnexKnex.js是为Postgres,MSSQL,MySQL,MariaDB,SQLite3,Oracle和Amazon Redshift设计的“包含电池”SQL查询构建器,其设计灵活,便于携带并且使用起来非常有趣。它具有传统的节点样式回调以及用于清洁异步流控制的承诺接口,流接口,全功能查询和模式构建器,事务支持(带保存点),连接池 以及不同查询客户和方言之间的标准化响应。
    二、系统概要设计系统的设计主要前台和后台两个部分
    2.1 系统需求分析
    登录/登出
    社团信息管理

    新增/查询/编辑/注销社团移除社团成员关键字查询社团信息
    公告管理

    新增公告预览/查询/删除已创建的公告公告流量统计
    管理员管理

    添加/删除/编辑管理员权限验证
    个人信息管理

    用户名编辑修改密码

    2.2 可行性分析这里讲的可行性分析的任务是从技术上、经济上分析需解决的问题是否存在可行性。其目的是在尽可能短的时间内用尽可能小的代价确定问题是否有解。
    技术上的可行性分析主要分析技术条件能否顺利完成开发工作,硬、软件能否满足开发者的需要等。
    React是一个用于创建可重用且有吸引力的JavaScript框架。它非常适合代表经常变化的数据的组件。使用React,您可以通过将它们分解为组件而不是使用模板或HTML来构建可重用的用户界面。

    灵活性和响应性:它提供最大的灵活性和响应能力
    虚拟DOM:由于它基于文档对象模型,因此它允许浏览器友好地以HTML,XHTML或XML格式排列文档
    丰富的JavaScript库:来自世界各地的贡献者正在努力添加更多功能
    可扩展性:由于其灵活的结构和可扩展性,React已被证明对大型应用程序更好
    不断发展: React得到了Facebook专业开发人员的支持,他们不断寻找改进方法
    Web或移动平台: React提供React Native平台,可通过相同的React组件模型为iOS和Android开发本机呈现的应用程序

    无论是Web还是本机移动开发,React都是大多数用户界面设计平台的理想选择。
    本系统数据库使用的MySQL,MySQL是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的关系型数据库,轻量、开源、简便易用,使用Navicat Premium 12做数据库图形化管理更高效率进行前后端开发。
    2.3 Server端模型
    由前台客户端发起请求来请求数据,Egg服务器判断是否在白名单或请求头中的token是否有效,若满足条件之一,则放行请求,根据router访问对应的controller,controller为数据的处理层,将数据处理好后通过service对数据库进行访问与操作,然后将service返回的结果在controller进行再次处理与封装,然后将响应数据和状态码(默认200)返回前台
    三、数据库设计3.1 数据概念结构设计E-R模型是数据进行第一层抽象的表示方法。它的主要成分包括:实体、联系和属性。我们可以用E-R图将内容表达出来,辅助设计的实现[6]。
    3.2 数据库关系设计该系统数据库关系图如下所示:

    3.3 数据字典管理员表(admin)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    login_name
    varchar(255)





    name
    varchar(255)





    password
    varchar(255)





    role
    int(1)


    1:超级管理员 2:管理员


    isDel
    int(1)


    默认0



    学生表(student)



    字段
    类型
    主键
    允许空值
    备注




    stu_id
    varchar(255)
    P




    stu_name
    varchar(255)





    password
    varchar(255)





    sex
    int(1)


    0:男 1:女


    role
    int(1)


    0:未审核 1:家庭成员 2:业主


    tel
    varchar(255)





    社团表(community)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    title
    varchar(255)





    desp
    varchar(255)





    belong_dept
    int(11)





    manage_dept
    int(11)





    chairman_stu_id
    int(11)





    type
    int(11)





    create_time
    varchar(13)





    status
    int(1)


    0:未审核 ; 1:已审核 ; 2:已注销



    社团-学生表(community_student)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    stu_id
    int(11)





    community_id
    int(11)





    role
    int(11)


    0:成员; 1:社团管理员


    isDel
    int(11)





    社团类型表(community_type)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    type_name
    varchar(255)





    isDel
    int(11)


    默认0



    部门表(dept)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    dept_name
    varchar(255)





    isDel
    int(11)


    默认0



    公告表(notice)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    title
    varchar(255)





    author
    varchar(255)





    content
    text





    create_time
    varchar(255)





    isDel
    int(11)





    公告日志表(notice_log)



    字段
    类型
    主键
    允许空值
    备注




    id
    int(11)
    P

    自动递增


    notice_id
    int(11)





    stu_id
    int(11)





    create_time
    varchar(255)





    四、后台设计在接口设计方面,使用restful API设计原则,访问同一资源的不同操作时,使用同一命名空间,使用不同的请求方式区分不同的操作。
    数据中均没有使用物理删除,只做了逻辑删除,保证数据可回溯。
    新增与更新,都使用同一个接口,根据是否有id去判断是更新还是新增
    4.1 Egg本系统后台采用egg.js编写,egg继承于koa,操作与配置更加简洁,每个请求发送至后台时,先通过编写好的中间件(middleware),然后根据访问的路由(router)去执行对应的控制器(controller),控制器中只做数据操作,不对数据库进行直接操作,将数据整理为服务(service)所需要的形式,直接发送给对应的服务,服务对数据库进行直接操作,然后将结果直接返回给控制器,控制器再将结果响应给前台。
    如此,完成了一次请求
    4.2 权限校验已登录的用户,在请求时的请求头会带Authorization字段,若请求在白名单内,则不需要通过jwt中间件,直接放行,否则要校验此字段,字段里是bare + 登录时生成的json web token。
    jwt中间件对token进行解码后,判断是否合法并且在有效期内,通过则放行,不通过则直接返回状态码401(无权限)。
    代码实现:

    4.3 连接数据库本系统通过knex对数据库进行操作,以函数式编程的方式,简化了手写sql语句的操作,使代码更具语义化与可读性。
    配置MySQL数据库

    4.4 上传图片前端将图片以表单提交的形式传至后台,后台接受一个文件流,将其重命名后存放到目的位置,之后将完整路径发送至前端。

    五、页面设计页面采用蚂蚁金服出品的Ant Design UI 组件库,提供了完善的设计原则、最佳实践和设计资源文件(Sketch 和 Axure),来帮助业务快速设计出高质量的产品原型。
    5.1 登录页面
    输入用户名密码,点击登录,在对密码进行MD5加密后将login_name和password发送至后台,后台进行校验,匹配后将Json Web Token响应回来,将这个token存至cookie中,设定7天的过期时间,当前端再次发起其他请求时,将这个token带到请求头的Authorization字段中,供后台解析。
    若cookie中无请求头,则中止请求,使页面跳转回login页面,重新登录。

    5.2 主页
    antd支持layout和grid两种页面布局,这里采用layout布局,侧边栏通过递归一个JSON对象进行渲染对应的列表内容。

    获取到用户信息时,判断用户的角色,只有超级管理员才可显示管理员管理页签。
    顶部header下拉菜单可以直接跳转到个人信息或者退出登录。

    侧边栏通过collapsed状态进行切换开启或关闭状态。


    主题内容部分采用react-router-dom路由切换,根据url变化切换content内容。

    当页面均无法匹配到对应路由的时候,则进入noFound页面
    5.3 社团管理
    社团列表页面,做了关键字查询与分页功能,分页功能默认每页10条,可更改。

    点击编辑按钮可对当前社团进行更改。

    对每一项均做了填写校验。

    在选择社团主席时,输入学号进行远程搜索,动态选择。
    此处使用Lodash中的防抖功能对输入进行了优化,减少了多次请求造成的性能问题,也避免因请求返回次序不同造成的数据错误。



    当点击详情按钮时,可显示社团内成员,并进行了分组,可对成员进行直接移除。
    5.4 公告管理5.4.1 新增公告
    此处使用react-draft-wysiwyg富文本编辑器制作新增公告功能。编辑好的内容会以HTML标签字符串的形式发送给后台。当发送空值时内容为 ’<p></p>’,此时发布会提示没有添加正文,是否确定提交。

    由于富文本中添加图片是一个比较复杂的操作,此富文本编辑器默认仅可选择在线图片,可增加选取本地图片的选项,但是需要自己后台支持。

    在此处选择图片时,图片限制不可超过500KB并且只可选择’jpg’, ‘jpeg’, ‘png’, ‘gif’这四种格式的图片,选择成功后,会自动将图片上传至服务器,服务器会将处理好的图片的url返回至前台并显示在虚框内,点击添加即可显示到富文本编辑器中,发布时此处会变为<img />标签。
    5.4.2 公告列表
    在此处使用了骨架屏,在数据未完整请求到时,显示骨架,并且为骨架添加必要的延迟,避免白页与页面闪烁。


    当骨架结束后,页面显示内容,对数据进行必要的处理后,点击预览按钮可以显示手机模拟器,预览本条公告。

    手机页面可以进行滚动,但由于在电脑浏览器端显示滚动会有滚动条,很难去掉,有兼容性问题,为了提高体验,显示滚动条,然后将内层盒子扩大出一个滚动条的宽高,再将外层盒子进行over-flow设置为hidden,超出部分不可见,更好地实现模拟手机的滚动功能。


    点击删除按钮时会弹出提示。

    确定后才会删除(逻辑删除)
    5.4.3 流量统计
    默认显示一周以内的公告流量数据,此处使用echarts制作环形图,点击右侧可进行过滤上部时间picker可以选择时间范围,默认为一周内。通过此功能,可以对公告的阅读量进行统计,以便推出更受欢迎的公告资讯。
    5.5 管理员管理只有超级管理员可进入此tab,普通管理员进入不显示这个菜单项,如果在url处输入对应路径,会进入no permission(无权限)页面。


    进入管理员管理页面后,可操作其他管理员但不可操作自己与其他超级管理员。


    此处填写表单均做了表单校验,新增与编辑同理。
    5.6 个人信息
    此处分为基本信息模块与密码模块,基本信息模块可修改用户基本信息,此处只设置了姓名,还可以增加手机号,性别,个性签名,身份证号等等。
    密码模块必须正确输入之前的密码,两次新密码必须一致,而且要满足以字母开头,长度在6~18之间,只能包含字母、数字和下划线才可提交。


    原密码错误会提示错误。
    0 评论 3 下载 2019-08-11 08:41:12 下载需要11点积分
  • 基于JAVA的图形填充

    Overview计算机图形学期末PJ

    多边形区域填充
    3D立方体投影展示程序

    RequirementsJDK1.6
    How to run1. git clone https://github.com/whimsycwd/GemetoryPJ.git2. mvn clean compile3. mvn exec:java -Dexec.mainClass="base.FillPolygon" # 多边形填充4. mvn exec:java -Dexec.mainClass="bonus.Cube" # 3D立方体投影Hot to Operate多边形填充

    鼠标点击n个点
    最后一个点双击
    这n个点组成的的多边形内部被染色

    示例:

    3D立方体投影

    w and s : Pitch
    a and d : Yaw
    q and e : Roll

    实现算法多边形填充
    跨立实验判断线段相交
    public double cross(Point a, Point b, Point c) { return (double) (b.x - a.x) * (c.y - a.y) - (double) (b.y - a.y) * (c.x - a.x); } public int sign(double value) { if (value > 1e-8) return 1; if (value < -1e-8) return -1; return 0; } public boolean intersection(Point a, Point b, Point c, Point d) { if (sign(cross(a,b,c)) * sign(cross(a, b, d)) > 0) return false; if (sign(cross(c,d,a)) * sign(cross(c,d,b)) > 0) return false; return true; }
    针对每个像素, 采用射线法, 奇数个与多边形相交的点则为内部点.
    private void fill() { Point sp = new Point(9998, 9999); int n = nodes.size(); for (int i = 0; i < WIDTH; ++i) { for (int j = 0; j < HEIGHT; ++j) { int intersectionNumber = 0; for (int k = 0; k < nodes.size(); ++k) { if (intersection(nodes.get(k), nodes.get((k + 1) % n), new Point(i,j), sp)) { ++intersectionNumber; } } if (intersectionNumber % 2 == 1) { Graphics g = p.getGraphics(); g.drawLine(i, j, i, j); } } }3D立方体投影
    图形旋转参考右手系旋转的方式
    // rotate along axis X double [][] matrixAlpha = new double[4][4]; matrixAlpha[0][0] = 1; matrixAlpha[1][1] = Math.cos(alpha); matrixAlpha[1][2] = Math.sin(alpha); matrixAlpha[2][1] = -Math.sin(alpha); matrixAlpha[2][2] = Math.cos(alpha); matrixAlpha[3][3] = 1; // rotate along axis Y; double [][] matrixBeta = new double[4][4]; matrixBeta[0][0] = Math.cos(beta); matrixBeta[0][2] = -Math.sin(beta); matrixBeta[1][1] = 1; matrixBeta[2][0] = Math.sin(beta); matrixBeta[2][2] = Math.cos(beta); matrixBeta[3][3] = 1; double [][] matrixGamma = new double[4][4]; matrixGamma[0][0] = Math.cos(gamma); matrixGamma[0][1] = Math.sin(gamma); matrixGamma[1][0] = -Math.sin(gamma); matrixGamma[1][1] = Math.cos(gamma); matrixGamma[2][2] = 1; matrixGamma[3][3] = 1; g.setColor(Color.white); g.clearRect(p.getX(), p.getY(), p.getWidth(), p.getHeight()); Point3D [] points2 = new Point3D[8]; for (int i = 0; i < 8; ++i) { double [] row = new double[4]; row[0] = points[i].getX(); row[1] = points[i].getY(); row[2] = points[i].getZ(); row[3] = 1; row = multiply(row, matrixAlpha); row = multiply(row, matrixBeta); row = multiply(row, matrixGamma); points2[i] = new Point3D(row[0], row[1], row[2]); drawDot(g, row[0], row[1]); }
    面染色采用 P497 画家算法, 先对平面的Z重心进行排序, 由远及近进行染色.
    // fill in color double [] center = new double[6]; for (int i = 0; i < 6; ++i) { center[i] = avg(points2, facet[i]); } int [] idx = new int[6]; for (int i = 0; i < 6; ++i) { idx[i] = i; } for (int i = 0; i < 6; ++i) { for (int j = i+1; j < 6; ++j) { if (center[idx[i]] > center[idx[j]]) { int t = idx[i]; idx[i] = idx[j]; idx[j] = t; } } } for (int i = 0; i < 6; ++i) { Polygon polygon = new Polygon(); for (int j = 0; j < 4; ++j) { int nodeId = facet[idx[i]][j]; polygon.addPoint(transform(points2[nodeId].getX()), transform(points2[nodeId].getY())); } g.setColor(penColor[idx[i]]); g.fillPolygon(polygon); }遇到的困难
    Point3D类属于javafx包, 不是标准包, 最终改为自定义的类
    图形渲染闪烁问题, 从AWT转化为Swing, 用其框架自动的Double-Buffering来避免闪烁问题, 其中在画图的时候应传递同一个Graphics 否则会导致画布刷新, 从而展示不出新的东西.

    参考文献
    http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html
    http://www.cnblogs.com/muding/archive/2013/02/19/3031447.html
    http://www.vineetmanohar.com/2009/11/3-ways-to-run-java-main-from-maven/
    http://mojo.codehaus.org/exec-maven-plugin/
    http://www.ibm.com/developerworks/cn/java/l-java3d/
    0 评论 1 下载 2019-08-09 13:58:24 下载需要8点积分
  • 基于C#和SQL SERVER的企业进销存管理系统的设计和实现

    摘要进销存管理是现代企业生产经营中的重要环节,是完成企业资源配置的重要管理工作,对企业生产经营效率的最大化发挥着重要作用。本文以我国中小企业的进销存管理为研究对象,描述了企业进销存管理系统从需求分析、系统设计、系统实现到系统测试的全周期。在本次设计确定了进销存系统的基础功能需求,深入剖析了企业进销存的业务流程,完成了基础设置模块、客户管理模块、产品管理模块、进销存管理模块和系统管理模块的功能设计。分析部分对系统的概念、特点、运行环境及数据库设计进行了分析描述;设计部分根据系统的总体描述、模块及结构图提出了系统的总体设计方案内容;实现部分介绍了系统中各个模块的实现方法,做到客观实际,具有通用性。
    关键词:进销存管理系统;.NET;B/S 模式;SQL
    ABSTRACTInventory management inmodern enterprise production and management is an important aspect. It alsoplay an important role to maximize the efficiency of the production andoperation of enterprises. Taking inventory management of SMEs in China for thestudy, this page describes the enterprise inventory management system fromrequirements analysis, system design, system implementation to a full cycle ofsystem testing. In this page to determine the basis functional requirements of Invoicingsystem, in-depth analysis of the business processes of enterprises Invoicingcompleted basic settings module, customer management module, product managementmodule, inventory management module and system management module functionaldesign. Part of the concept of systems analysis, features, operatingenvironment and database design are analyzed description; according to thegeneral description of the design part, modules and structural diagram of theproposed system design program content; implementation section introduces theimplementation of the system in each module methods to achieve the objectivereality, with versatility.
    Keywords: Inventory managementsystem; .NET;B/S module; SQL
    第1章 绪论1.1 课题背景随着现代企业管理理论的发展,以及在新形势下信息化技术在现代企业管理的不断应用,许多中小企业在激烈的市场竞争中也开始注意到企业信息化管理的重要性,部署了贴合自身业务的小型管理系统。但当前许多中小企业实现的管理信息系统都是非常独立的系统,采购、销售、库存管理都有独立的系统。大量的系统不利于数据共享和综合的统计分析。因此,中小企业迫切需要部署一个综合的进销存管理系统以实现数据的统一管理。进销存管理系统以库存管理为基础,主要完成企业的采购管理、销售管理、库存管理、客户管理和产品管理等工作,通过对销货进货、库存变更等操作过程的管理,为管理者提供详细企业运营状况,帮助企业打到采购、库存、销售的平衡,降低企业成本。
    1.2 国内外现状美日韩等发达国家因工业水平和计算机技术起步较早走在了世界的前列。自 20 世纪 60 年代起发展了许多实现企业全面管理的企业资源计(ERP系统)。这些 ERP 系统中均有进销存管理相关的模块[1]。但中小企业由于规模与资金限制,只在部分业务普及了信息化。这些软件系统中均具有进销存管理的相关业务模块,例如Communication Oriented Production and Information ControlSystem (COPICS)、商业计划和控制系统(BPCS)、NIPPON TELEGRAPH AND TELEPHONECORPORATION (NTT)系统,业务模块具有较高的集中度,同时也易于扩展,全世界许多企业使用这些管理系统来完成企业的进销存管理工作。美国的一份数据统计表明采用利用软件对企业进销存管理,可减少40%的积压库存,12%的企业生产力增[2]。
    在经济化浪潮下国内也涌现出一批优秀的进销存系统,如用友软件、金蝶公司、浪潮等的 ERP 系统,都在国内得到了广应用。但当前我国进销存管理系统存在的主要缺陷:①软件功能复杂。许多进销存管理系统包括从物流、生产到财务等多个领域,但许多功能并不适用于中小企业;②进销存信息单一,且缺乏对数据的分析功能。无法对进销存信息进行实时分析;③系统网络化程度低。许多传统的进销存管理系统只支持在局域网中进行使用,更无法满足当前网络经济时代的要求。国内进销存管理系统的研究已经从点到面,又向细节逐步深入的阶段,在各方面细节上不断完善系统,为企业进销存管理打造一个坚实的根基[3]。
    1.3 课题的目的和意义本课题的目的是研究设计实现企业进销存管理系统,并通过该系统实现以下目标:

    模块化进销存业务,使企业需求更加明了,方便用户操作
    灵活分配企业员工权责,优化管理
    实现中小企业进销存管理的持续使用

    本课题的意义如下:

    实时下订单
    实时查询库存数量
    为企业管理者提供科学的决策数据

    1.4 本文组织结构
    第一章为绪论,大致介绍本课题的研究背景以及国内外进销存管理系统的现状,以及应用进销存管理系统的主要意义
    第二章为开发进销存管理系统的相关技术,本章主要介绍了开发系统时使用的技术、语言、数据库技术和软件架构等方面
    第三章为进销存管理系统的分析与设计,本章主要说明了该系统的需求、系统的模块规划,以及系统数据库的设计及相应的截图
    第四章为进销存管理系统的实现,本章主要说明了系统的开发环境,介绍了系统各个模块所实现的功能
    第五章为总结与展望,本章主要总结了本系统的开发工作,并指出系统存在的不足,有待改进

    第2章 相关技术介绍2.1 ASP.NET技术ASP.NET技术是用微软开发并推行的,是一种使嵌入网页中的脚本可由因特网服务器执行的服务器端脚本技术,可用于在服务器上生成功能强大的Web应用程序,是ASP技术的升级版。ASP.NET支持多种类型语言的编程开发,其中包括常用的Visual Basic .NET、C#、Perl等语言。因为ASP .NET是基于通用语言的编译运行的程序,其实现完全依赖于虚拟机,所以它拥有跨平台性,ASP .NET构建的应用程序可以运行在几乎全部的平台上[4]。同时,ASP.NET还有许多功能强大的组件,例如DataList、DetailList和Gridview等,可以实现快速简便地与数据库进行连接,并且它本身还自带了服务器空间,简单好用[5]。
    2.2 C#语言C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言。它是由C和C++衍生出来的,同时又综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。
    2.3 SQL Server数据库SQL Server数据库是一个关系数据库管理系统,是一个可扩展、高性能、为分布式客户机/服务器计算所设计的数据库管理系统。它实现了与WindowsNT的有机结合,提供了基于事务的企业级信息管理系统方案[6]。SQL Server数据库具有如下特点:

    高性能的设计。SQL Server数据库可以充分利用Windows NT的优势
    系统管理的先进性。它支持Windows图形化管理工具,支持本地和远程的系统管理和配置
    强大的事务处理功能。SQL Server数据库采用了多种方法,以保证数据的完整性
    支持对称多处理器结构、存储过程、ODBC,并具有自主的SQL语言。SQL Server数据库以其内置的数据复制功能和强大的管理工具,以及其与Internet的紧密集成和开放的系统结构,为广大用户、开发人员和系统集成商提供了一个出众的数据库平台

    2.4 B/S结构B/S结构(即浏览器/服务器结构)是WEB兴起后的一种网络结构模式,其主要是利用日渐成熟的WWW浏览技术,结合VBScript和JavaScript等Script语言,再加上ActiveX技术,将系统功能实现的核心部分转移到了服务器上,简化了系统的开发,是一种全新的软件系统构造技术[7]。用户通过自己电脑的浏览器就可以在家访问数据库,不需要特别安装软件,使得系统的拓展十分便利。
    2.5 AJAXAjax是一种创建交互式网页的web开发技术。它并不是一种单一的、新的技术,而是由Javascript、CSS、Dom、XMLHttpRequest这四中技术集合而成的。它由JavaScript语言写成,使用CSS控制页面的样式,通过DOM使用模型,通过XMLHttpRequest向后台发送数据。Ajax技术很多时候被用于实现页面的局部刷新,大大提高了用户体验感。
    2.6 AndroidAndroid是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。一个Android 应用是由多个Activity 组成的。这多个Activity 之间 可以进行相互跳转,例如,按下一个Button按钮后,可能会跳转到其他的Activity。和网页跳转稍微有些不一样的是,Activity 之间的跳转有可能返回值,例如,从Activity A 跳转到Activity B,那么当Activity B 运行结束的时候,有可能会给Activity A 一个返回值。这样做在很多时候是相当方便的。
    2.7 本章小结本章主要介绍了在进销存管理系统中使用的相关技术,例如C#和SQL Server数据库的相关介绍,B/S结构的简单阐述以及AJAX的原理。
    第3章 系统分析与设计3.1 系统需求分析进销存管理系统的开发过程中包括了前期准备,市场调研、系统分析、系统设计以及系统实现、测试、评价等步骤。由于调研对象主要集中在中小企业,所以其中的一些功能只做了一些简单的设计。根据系统开发的大小、规模以及应用范围的不同,各个步骤的要求和内容可能不尽相同。
    3.1.1 业务流程分析为了使用户能够更加直观地了解整个系统的业务关系、工作顺序以及相应的管理信息的流向,在此给出了本系统的业务流程图,如图3-1所示。本系统是进销存管理系统,主要实现企业库存的信息管理,设定价表、入货出货和实时查询企业库存[8]。其中,订单模块是本系统的重点。
    如图3-1所示,在本系统中,管理员拥有系统全部基础功能。如新增客户,新增产品和销售区域,新增业务代表等基础信息维护;设定价盘表,可按照不同销售区域对产品进行差异化定价;调整并审核销售单、退货单、收预收款等业务操作。管理员新增业务代表并审核通过后可由业务代表帮助客户下预售单,预售单在管理员审批通过后可由库管发货,审核期间可组合选择付款方式(预收款付款,先进结款等)。
    业务代表在本系统中扮演了重要角色,承担了企业与客户沟通的桥梁,在线下跑订单,下预售订单等都由业务代表完成。业务代表是可以关联车辆的,企业的每一辆运货车可以由一个司机加一个业务代表组合负责。司机负责货运,业务代表负责在手机APP为客户下订单,可下订单包括销售单,预售单,退货单,在手机端业务代表可任意组合自己的付款方式,灵活完成客户订单需求。
    产品价表是本系统的重点,管理员可针对不同渠道不同区域的不同产品差异化定价,尽可能符合当前区域的经济需求。管理员亦可对产品设定活动,活动包括买赠和减免,对于同一客户的下单可直接给业务代表赠送的权利,简化买赠活动为免费赠送单。灵活的定价方式可满足不同区域的消费需求。

    3.1.2 数据流程分析从业务流程图中,我们可以比较直观地了解到整个系统中各个实体以及各个模块之间的业务关系,以及作用顺序,但是对于各类信息的具体处理、存储及流向方面,则不是十分详细。而为了更加清晰地了解一个系统中的数据信息流向和处理存储过程,本文中给出了数据流程图。如图3-2所示,是本系统的数据流程图,从下图我们可以比较明确地知道整个系统的数据走向。

    3.1.3 功能性需求分析进销存管理系统的角色分为系统管理员、业务代表、司机、客户。
    系统管理员可以由系统使用方指定对象担任,人数由使用方决定,系统管理员不需要注册。系统管理员主要管理整个系统中基础信息的调整和订单审核,包括新增业务代表、新增产品、设定产品价表等。具体功能要求如下:

    管理授权:注册其他角色时需要在管理员授权
    修改权限:系统管理员可以根据需求修改系统人员和商品的信息的权限
    业务权限:系统管理员可以对订单进行审核发货和取消
    信息维护:系统管理员可以对整个系统中的信息进行维护
    审核功能:根据新增基础信息需求,审核信息

    业务代表是由管理员添加并审核通过的注册者,在系统中具有下预售单和车销单的权限。具体功能如下:

    客户管理:具有新增客户、修改已存在客户资料等功能
    车销管理:下车销订单
    预售管理:下预售订单
    库存管理:可申请移库,由主仓库移动至车仓库或由车仓库退货
    退货管理:可以查看有关自己的留言,回复他人对自己的提问
    其他信息:订单查询等

    司机是由管理员添加并审核通过的注册者,在系统中具有库存调拨的权限。具体功能如下:

    调拨管理:车销移库或退库
    订单管理:在车销订单中收款

    3.1.4 非功能性需求分析非功能性需求,指的是除了用户所需的功能要求以外,还应该满足的一些其他方面的要求。本系统以下几个方面进行分析:

    系统安全性:防止无权限人员进入系统修改相关信息[14]。若操作系统能给数据库用户分配角色,则安全性管理者必须要有修改操作系统用户安全性区域的操作系统权限
    性能需求:用户在软件响应速度、结果精度、运行时资源消耗量等方面的要求。如对计算机系统的要求,对工作频率、容量、存储量等方面的要求
    易操作需求:界面简单明了,命名明确易懂。如一些系统管理员不太熟悉电脑操作,系统界面必须一目了然、简单易懂、容易上手
    适应性:当外部条件有所改变的时候,系统根据外界因素改变。如时间变化,系统根据当前时间删除发布招募信息时过时时间的选项

    3.2 系统模块划分根据以上分析,可以将库存管理信息管理系统分为基础信息管理、采购管理、销售管理、库存管理、财务管理、报表平台等几个模块。系统管理员主要有信息的维护、审核、权限管理等功能具体,业务代表具有订单权限和新增客户权限,如图3-3所示:

    3.3 系统数据库设计在一个系统的开发过程中,数据库设计可谓是至关重要,一个数据库的设计成功与否,直接关系到整个系统的开发,甚至会影响到整个系统的成败。
    3.3.1 概念设计概念设计是由分析用户需求到生成概念产品的一系列有序的、可组织的、有目标的设计活动,它表现为一个由粗到精、由模糊到清晰、由抽象到具体的不断进化的过程。现在常用的概念模型是E-R模型。在本系统中,各实体直接的关系如图3-4所示:

    3.3.2 逻辑设计逻辑设计是将概念结构转变为某个DBMS支持的数据模型,也可称为优化。将本系统转换后就得到如下关系模型:

    商业客户基本信息表(ID,客户编号,全称,简称,行政城市,邮政编码,客户地址,送货地址,联系人姓名,电话号码,手机号码,传真,Email,企业网址,首要联系人,客户开门时间,客户打烊时间,营业执照号,组织机构代码证号,税务登记证号,客户类型,所有权属性,所有权人,备注,审核标志,新增日期,新增人,更新日期,更新人)
    供货商合作关系表(ID,客户ID,供货商,客户自编码,业务人员,客户合作状态,开始合作日期,截止合作日期,供货价盘表,渠道,区域,销售路线,拜访顺序,拜访模板,备注,审核标志,新增日期,新增人,更新日期,更新人)
    员工信息资料表(ID,姓名,性别,员工编号,身份证号,出生日期,行政城市,地址,邮编,电话号码,手机号码,电子邮件,开始工作日期,截止工作日期,管理片区,职务,在职状态,所有权属性,所有权人,备注,审核流程,审核标志,新增日期,新增人,更新日期,更新人)
    商品基本资料表(ID,产品名称,产品简称,商品编码(平台级编码),规格,整件单位,零售单位,包装系数,整件商品条码,零售商品条码,商品种类,商品品牌,商品类别,段位,整件重量,整件体积,厂家名称,生产厂商,厂家商品码,厂家商品ID,标准经销价,标准分销价,建议零售价,成本价,状态,保质期,所有权属性,所有权人,备注,审核标志,新增日期,新增人,更新日期,更新人)
    订货单信息(ID,订单号,供货商,订购商,业务员,供货价盘表,类别,状态,折扣金额,优惠金额,实际订货金额,要求送达时间,要求送达仓库,提交时间,确认时间,关联拜访记录,备注,审核标志,新增日期,新增人,更新日期,更新人)
    发货单信息(ID,单号,发货商,收货商,发货商仓库,收货商仓库,业务员,送货人,类别,制单模式,状态,供货价盘表,关联订货单,折扣金额,优惠金额,实际销售金额,送货车辆,预计送达时间,装车配货时间,发车时间,实际到达时间,关联拜访记录,备注,审核标志,新增日期,新增人,更新日期,更新人)
    实时库存表(ID,仓库,商品,批号,生产日期,数量,价格,最后更新时间,新增日期,备注)

    3.3.3 物理设计物理设计指的是根据数据库的逻辑结构来选定RDBMS,并设计和实施数据库的存储结构、存取方式等。本系统采用SQL Server数据库,根据以上的分析选取了主要的几张表展示,表之间的关系如图3-5所示

    3.4 本章小结本章节作为全文比较重要的一个章节,具体介绍了进销存管理系统的需求分析,其中包括了功能性需求分析和非功能性需求分析,分别从概念、逻辑、物理这三方面进行了说明。
    第4章 系统实现4.1 系统开发环境的选择本系统的开发是基于.NET平台,以VS2012为开发环境,将C#作为主要开发语言,SQL SERVER为数据库软件。
    4.2 系统通用方法的实现本系统是进销存管理系统,系统重心在下单及库存判断上,但是作为一个应用型系统,其他功能模块也是必不可少的。系统实现过程中运用了大量的ASP.NET控件,例如AJAX、GridView、DataList等。在本节中将介绍通用模块的实现方法。
    4.2.1 连接数据库在一个系统中,数据库的连接可以说是核心部分,至关重要。在本系统中,通过web.config文件增加数据库连接字符串[9],主要代码如下:
    <connectionStrings> <addname="VolunteerConnection"connectionString="Data Source=UGYRPLW5EAMIHEB;Initial Catalog=Volunteer;Persist Security Info=True;User ID=sa;Password=123456"providerName="System.Data.SqlClient"/></connectionStrings>
    并在App_Code文件夹中添加数据库连接方法connet(),在后续的系统功能程序编写中,全部通过调用该方法来实现数据库的连接,主要代码如下:
    privatestaticstring connectString = ConfigurationManager.ConnectionStrings["VolunteerConnection"].ConnectionString;publicstaticSqlConnection Connect(){SqlConnection con = newSqlConnection(connectString);return con;}
    4.2.2 数据的绑定显示作为一个数据管理系统,需要将系统中的部分数据展示出来,因此,数据的显示操作也是十分重要的[10]。在本系统中,数据的显示主要使用了DataList和GridView控件,控件类型的不同导致了这两种控件在使用方法上的差异。在DataList控件中,本文主要采用了DataSet方法来填充数据,该方法处理脱机数据,在多层应用程序中很有用,并且可以在任何时候查看DataSet中任意行的内容,允许修改查询结果的方法,还可以处理分级数据。在本系统中,该方法被用于每一个信息展示页面,例如订单列表页面,采购单列表页面,产品列表页面等,主要代码如下:
    SqlDataAdapter sqlda = newSqlDataAdapter(sqlstr, sqlconn);DataSet ds = newDataSet();sqlda.Fill(ds, "dtxx");
    GridView控件主要使用在系统管理员模块中,通过该控件自带的分页排序功能,可以使得管理员的操作更加简便快捷。GridView控件主要是通过使用SqlDataSource数据源控件来连接数据库的,所以在此不再累赘。
    4.2.3 分页栏DataList控件本身并不带有分页功能,为实现在使用DataList控件时也能方便分页,本系统使用了PagedDataSource数据源方法来绑定DataList控件,使其也能像GridView控件一样实现分页[11]。该方法主要通过PagedDataSource和DataSet方法相结合使用,主要代码如下:
    DataSet ds = newDataSet();sqlda.Fill(ds, "dtxx");PagedDataSource pds = newPagedDataSource();pds.DataSource = ds.Tables["dtxx"].DefaultView;this.DataList1.DataSource = pds;this.DataList1.DataBind();
    4.2.4 页面局部刷新和跳转在本系统中,因为牵涉到大量数据的分页方法,势必会造成在页面刷新过程中的卡顿和不流畅现象,为解决这一问题,本系统还使用了AJAX控件,来实现页面的局部刷新方法[12]。因为AJAX是开发环境中自带的一款封装的控件,所以在使用上也是非常方便的,主要代码如下:
    <asp:ScriptManagerID="ScriptManager1"runat="server"></asp:ScriptManager><asp:UpdatePanelID="UpdatePanel1"runat="server"><ContentTemplate> ……</ContentTemplate></asp:UpdatePanel>
    在AJAX控件中,无法使用Response.Write(“”)方法进行页面信息框的弹出提示已经页面的跳转,所以AJAX也有自己自身的一种提示方法,主要代码如下:
    ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "click", "alert('已完成下单!');location.replace('dygl.aspx');", true);
    4.3 系统主要功能的实现如上节所述,本系统是进销存管理系统,订单模块是本系统的主要模块,该模块实现了下单和查询功能,以及后续的一些统计功能[14]。
    本系统实现的功能主要由两部分组成,即订单和库存这两个模块的功能。进入本系统时需要登录,进入系统会自动根据身份出现可浏览模块。界面如图4-1和4-2所示:


    4.3.1 系统管理员功能系统管理员是由系统开发者或者系统购买者直接指定的,不需要注册,系统管理员的信息直接由开发人员写进数据库中。但是要注意的是,系统管理员的选择应该慎重[15]。在本项目中系统管理员除了可以修改自己的个人信息之外,还有以下众多主要功能:
    1.基础资料管理:企业员工注册客户成功之后就无法自行修改,如果注册时用户信息填写错误,用户可以向管理员线下提起申请,管理员通过用户信息管理界面进行用户信息的修改。系统管理员也可以在该功能模块进行用户权限的修改。该页面主要使用GridView控件实现,在一定程度上节省了开发难度和开发时间,同时使用代码和textbox控件,可以通过关键字搜索用户信息,方便管理员对用户信息的维护。基础资料页面都提供对各类信息的检索方式,如客户界面的关键字会在后台自动匹配客户的名称,编码,简称等属性,而新增日期的时间段则会自动筛选所有符合录入时间的客户,合作状态可选取一种状态,也可选择所有状态下的客户。界面如图4-3所示:

    2.商品信息管理:本系统提供了商品管理这一模块,具有商品操作权限的用户可以自行为企业添加商品,并为产品设定不同类别。每个产品都可以归属于一个类别,可通过类别对产品进行筛选。界面如图4-4所示:

    3.采购管理:企业作为盈利组织,势必要投入一部分成本,而成本的一个重要组成部分便是销售产品的采购。本系统提供企业对产品的采购功能,采购数据会纳入企业进销存体系,作为库存盘点的数据来源。录入采购单据时刻选择企业自身录入的供货商,选择企业的一个仓库作为入库仓库,已完成的采购单管理员可在后台予以确认,采购单据页面会自动罗列出所有的采购商品和采购的总金额,界面如图4-5所示:

    4.订单管理:企业要实现盈利就必须有销量,在实际业务过程中业务代表承担了销售的大部分责任。对于小规模客户业务代表可跟车进行车销现款现货交易,对于大客户业务代表则可通过拜访客户下预售订单的模式销货,预售单在管理员审核通过后可进行派单。订单页面与采购单页面相似,不同的是企业自身已作为供应商,而订购上则是企业客户。订单页面会显示下单的业务员和销售类型及各类采购产品明细,界面如图4-6所示:

    5.库存管理:系统管理员可以在该模块中查看现有个库存中各产品的数量,也可在各仓库之间进行调拨操作并按期对仓库进行盘点。界面图如图4-7所示:

    库存盘点是系统的一个重点功能,用户可在新增盘点单的界面选择需要盘点的仓库,此时界面会以GridView的形式罗列出所有在售产品的现有库存量,并提供一个下拉列表选择盘盈或者盘亏并以文本框形式输入数量。对于每一个产品的库存,对应于后台PBM_DeliveryDetail数据表中的一行数据,在保存时循环GridView的每一行在PBM_DeliveryDetail中插入数据。
    6.价表管理:价表是进销存管理系统的基础,决定了系统的复杂程度。本系统允许多张报表同时存在,默认设置第一张价表为主价表。管理员可新增自定义价表关联渠道或客户类型,也可同时与渠道和客户类型绑定。价表界面图如4-8所示:

    在价表管理页面用户可看到当前价表关联的区域和取到以及是否为默认价表。用户可根据商品分类或关键字查找在价表中或不在价表中的商品,以审核的价表,对于不需要再出现在价表中的产品允许用户进行批量删除,同时不在价表中的产品也可添加到价表并自定义价格。
    4.3.2 业务代表功能
    如图4-9所示,为业务代表操作流程图。业务代表由管理员注册并分配账号后方可登陆系统,主要进行下车销单和预售订单操作。具体操作在手机端完成。用户具体功能如图4-10所示:

    客户信息管理:客户信息管理又分为以下几个功能
    客户信息新增——业务代表可根据实际新增自己管辖范围内的新客户,如果需要修改某些自己无权修改的信息时,可以向管理员申请修改。该模块通过手机APP的形式展现。如图4-11所示:
    客户拜访管理——业务代表在自己管辖的片区内可按照预定线路拜访客户,为提高拜访真实性系统提供对客户门头拍照功能。如图4-12所示:

    订单管理:业务代表对自己线路下的客户有下单权限,具体功能如下:
    车销订单—业务代表在随车拜访客户时可帮助客户下车销单。该模块位于手机APP上,如图4-13所示:预售订单—业务代表在自己管辖区域内拜访大客户时可帮助客户下预售单。该模块位于手机APP上,界面如图4-14所示:

    订单查询——业务代表在APP下单后可在PC端对自己的下单详情查看。界面如图4-15所示:

    4.4 本章小结本章主要描述了本系统的各个模块的功能实现,通过文字叙述和截图的方式展现了本系统的功能模块,分别从系统管理员和业务代表的角度介绍了本系统的功能。
    第5章 总结与展望5.1 总结在信息化建设日益普遍的今天,信息系统的使用以及愈加广泛,为了优化进销存的管理,本文在了解了各种进销存管理系统之后,开发设计了进销存管理系统,并做出如下介绍。
    本文的第一章着重介绍了进销存管理系统这一课题的背景和意义,以及它的研究目的,同时也介绍了本文的内容结构。第二章着重介绍了本系统的一些相关的技术概念,比如ASP.NET技术,SQL数据库等。第三章是本文的一个重点,主要内容是需求分析以及数据库的设计等。第四章详细介绍了本系统的一些功能的实现。
    本系统的重点在于管理员对商品的管理,业务代表下单和库存管理等;难点是针对不同区域和渠道设定不同的产品价格,创新点有系统权限的分配,对财务管理的纳入等。
    经过这段时间的学习和实践,我对课堂掌握的知识有了一个更好地巩固,对不理解和不熟练的一些方面也有了一个更清晰的概念,比如C#语言的应用,SQLServer数据库的应用,以及DIV+CSS的网页布局等方面。
    5.2 展望当然,由于技术方面的因素,本系统的许多方面还存在不足,比如:

    前期的数据库设计问题,导致在系统开发过程中需要不断修改数据库设计,使得数据库的设计不是十分规范
    目前本系统只采用了B/S架构进行开发,并没有结合C/S架构
    由于技术和设备问题,本系统无法自动提示用户相关的信息动态,只能是让用户经常登录自己进行查询
    除此之外,由于目前手机应用日益发达,开发手机APP势在必行,但由于时间和技术问题APP开发暂时只能落于纸上

    参考文献][1]郭旭.基于.NET的企业进销存管理系统的设计与实现[D].吉林大学,2014.
    [2]王洪迪.基于ASP.NET的燃气具企业的进销存系统设计与实现[D].合肥工业大学,2012.
    [3]于瑶瑶.企业进销存管理系统的设计与实现[D].山东大学,2009.
    [4]李洪涛.面向中小家电企业进销存管理系统的设计与开发[D].合肥工业大学,2010.
    [5]赵晓霞. 进销存管理系统的设计与实现[J]. 煤炭技术,2010,01:244-246.
    [6]赵韩,李洪涛,陈科. 基于ASP的中小企业进销存管理系统研究[J]. 微计算机信息,2010,33:43-45.
    [7]庄翔翔. 基于B/S架构的中小企业进销存管理系统的设计与实现[D].中国海洋大学,2010.
    [8]张彦芳,王春艳. 进销存管理系统的设计与实现[J]. 中国管理信息化,2008,07:14-16.
    [9]张岩,张宁. 基于C/S架构的超市进销存管理系统的设计与实现[J]. 北京石油化工学院学报,2013,04:45-50.
    [10]陶俊. 基于.NET的进销存管理系统设计与开发[J]. 江汉大学学报(自然科学版),2007,01:55-57.
    [11]王会青. 医药进销存管理系统设计与实现[J]. 山西科技,2007,03:57-58.
    [12]翁国秀,李露璐. 企业产品进销存管理系统的设计与实现[J]. 电脑知识与技术,2011,07:1493-1494+1506.
    [13]朱士高,朱军,朱彩霞. 基于WEB的企业进销存管理系统的设计[J]. 淮阴工学院学报,2007,05:62-64.
    [14]Xiao-yunJIANG,Pin CHEN,Rong ZHENG Department of Management Science,Xiamen University ofTechnology,Xiamen,China. Study of Modeling and Simulation of Flexsim-basedInventory Management System[A]. 中国机械工程学会工业工程分会、IEEE北京分会.Proceedings of 2010 IEEE the 17th International Conferenceon Industrial Engineering and Engineering Management(Volume 2)[C].中国机械工程学会工业工程分会、IEEE北京分会:,2010:4.
    [15]KaiWANG. The Research of Inventory Management Modes Based on Supply ChainManagement[A]. Chinese Industrial Engineering Institution,CMES、Institute ofElectrical and Electronic Engineers、Beijing Section.Proceedings of2012 IEEE 19th International Conference on Industrial Engineering andEngineering Management(IE&EM 2012)[C].Chinese Industrial EngineeringInstitution,CMES、Institute ofElectrical and Electronic Engineers、Beijing Section:,2012:5.
    2 评论 48 下载 2018-11-13 14:09:18 下载需要7点积分
  • 基于C++的菜鸟驿站

    1 绪论1.1设计背景随着社会的发展,互联网的兴起,网络购物渐成为人们购物的新时尚。快递行业也在网络购物的带动下蓬勃发展,成为人们生活中必不可少的一部分。所以一个智能的快递管理系统,会大大的方便人们的生活,提高快递运送的效率。
    随着快递数量的不断增多,如何将快递安全、准确的送到每一位消费者手上成为了一个问题。而一个智能的快递管理系统可以提高工作人员的效率,帮助工作人员快速清点货物信息。由于快递会在每个地区都设立站点,所以我们设计了一款名为菜鸟驿站管理系统的快递管理系统,用来帮助工作人员高效的完成工作。
    1.2 设计目标针对快递管理的实际需求,采用C语言作为开发语言,使用文件.txt作为数据库,设计并且开发了一个菜鸟驿站管理系统。系统主要包括用户功能模块和管理员功能模块。用户功能模块包括用户注册、用户快递查询、用户快递领取、用户信息修改等功能。管理员功能模块包括录入用户信息、删除用户信息、查询用户信息、修改用户信息、录入快递信息、删除快递信息、修改快递信息、查询快递信息、统计快递领取情况等功能,实现快递管理的信息化,提高工作效率。
    1.3 相关技术介绍本系统采用C语言编写,使用VS2015作为编译器编写系统程序代码,整个系统以.txt作为数据存储的文件。
    1.3.1 C语言简介C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
    1.4 文档组织结构本文第一部分绪论主要说明了系统的设计背景,设计目标以及C等相关技术;第二部需求分析阐述了系统功能和可行性分析,介绍了系统各个功能模块,并描述了系统的用例图和活动图,可行性分析介绍了系统开发的必要性和可能性;第三部分系统设计则介绍了系统结构设计;第四部分系统实现主要讲了登录模块、管理员模块和用户模块实现的功能;第五部分系统的测试主要介绍了对该系统的测试方法和详细过程。
    2 需求分析2.1系统功能概述系统包括两种不同权限的用户:第一种是用户,即普通用户,这类用户能够通过手机了解最新的快递动态信息,修改自己的个人信息、查询快递信息、注册账号等;第二种是管理员用户,管理员可以管理用户信息,管理和审核账户信息,管理和审核快递信息,还负责管理维护系统等。因此系统的设计可以分成三部分,用户模块、管理员模块和登陆模块。
    普通用户:

    使用手机、电脑来使用该系统;
    使用自己的账号注册并登陆系统;
    新用户注册成功之后,使用唯一的账号作为ID来识别;
    登陆系统可以查看个人信息和快递信息、修改个人信息等;
    不使用时可以退出登陆系统;
    可以根据单号查询和领取快递;

    管理员用户:

    通过管理员的用户名和密码登陆系统的管理员端;
    登陆系统后具有管理系统用户账户信息的功能;

    登陆后具有管理用户信息的功能,可以对用户信息进行增、删、改、查等操作;
    可以管理用户的快递;
    可以统计快递的领取情况,有无滞留时间过长的快递;
    可以设置新的管理员;
    可以查看快递的其他信息等。

    2.2 系统执行流程描述通过研究快递管理系统的需求分析,可以将系统设计成了三个主要模块,这三个模块是登陆模块,管理员模块,用户模块。

    登录模块,可选择用户登录和管理员登录,用户登录界面可以选择新用户注册和老用户登录具体的活动图如图所示。


    管理员模块,通过这个模块能够查看,添加,删除以及修改用户信息,能够修改快递、删除快递、增加快递、查询快递等操作。在管理员模块里面,所有的具体操作的是嵌套的,详细的活动图如图所示。


    用户模块,用户通过这个模块能够查询或者修改个人信息,能够查询快递信息和领取快递。每一个操作都是平行和嵌套的,该活动图如图所示。

    3 系统设计3.1 系统结构设计根据系统需求分析,可以设计出整个校友信息管理系统的总体结构。由于本系统包含两种不同权限的用户,每种用户进入系统后所能用的功能和权限不一样,因此在对系统结构设计时要分别考虑。

    管理员页面结构设计


    校友用户页面结构设计

    4 系统实现4.1 登陆模块实现用户注册模块。打开系统,进入欢迎界面,选择用户,如下图4-1所示。还没有账号可以点击注册,注册的时候输入账号、手机号、密码,然后点击注册的时候系统会调用regs()方法,该方法会给用户注册,然后将注册信息插入用户信息表中,然后就可以使用该账号登陆系统了。

    用户和管理员登陆。输入账号、密码,然后选择用户或者管理员,点击登录时系统会调用stu_land()方法,该方法会通过查询数据库相应的表来判断输入的信息是否正确;如果账号和密码都成功的在数据库中匹配成功的话,系统就会自动判断输入的账号和密码都正确,然后就会自动跳转至用户界面或者管理员界面;如果账号或者密码中的其中有一个没有在数据库中匹配成功话,管理系统就会弹出提示框,并且会显示相关的错误提示。
    4.2 管理员模块实现首页模块。输入正确的管理员登陆信息之后,系统判断用户名,密码和数据库中的信息匹配之后就会跳转到本系统的管理员首页,如图所示。

    维护用户信息模块。管理员首页通过后台的add_student()、display_all_student()和dele_student()方法查询、修改数据库中的用户信息,如图所示。

    录入用户信息。录入用户的账号、手机号等信息,录完之后,输入y保存,输入n取消,最后按enter返回,如图所示。

    浏览用户信息。可以浏览到用户的账号、姓名、手机号码和登录密码等基本信息,按enter键返回,如图所示。

    删除用户信息。输入要删除的学生账号,系统会自动删除该账号内的所有信息,如果输入账号信息有误,会提示错误,按enter键返回,如图所示。

    维护货物模块。选择维护货物模块,系统就会跳转到维护货物模块页面。如图所示。

    录入货物信息。按单号、手机号,系统会实时录入货物入库时间,并付给货物未领取的状态,录完之后,输入y保存,输入n取消,最后按enter返回,如图所示。

    浏览货物信息。可以浏览到用户的快递单号、手机号、入库时间、状态和取货码等信息,按enter键返回,如图所示。

    删除货物信息模块。如图所示。

    修改货物信息模块。如图所示。

    未取货物信息模块。如图所示。

    4.3 用户模块实现用户首页模块。以用户身份登录,同时输入的账号和密码都正确就会跳转到图所示的校友用户首页,显示用户模块的所有功能。输入对应的功能数字就可以使用相应的功能。操作之后系统就会待用户操作完成后,然后就会全部数据更新到文件中。如果密码或者账号输入不正确的话,系统会提示“请输入正确的账号和密码”。

    用户使用模块。输入对应的数字,进入对应的功能使用模块,可以完成用户的需求。
    查询个人信息。如图所示。

    修改个人信息。如图所示。

    领取快递。如图所示。

    返回主界面。如图所示。

    5 系统测试5.1 系统测试概述所谓系统测试是根据软件开发各阶段的规约和软件的内部结构,精心设计一批软件测试用例,并利用这些测试用例去运行程序,用来发现软件中不符合软件质量特性要求的过程。
    系统测试过程可以看成不断进行排错、测试、修改程序和文档,然后进行回归测试,直到软件达到用户的质量特性要求的一个循环过程。
    5.2 系统测试方法目前主要使用的系统测试方法有白盒测试和黑盒测试:

    白盒测试,这个方法可以对程序内部的具体逻辑进行测试,相当于微观的看待事物,详细的说就是根据具体的每一个方法测试它是否运行正确,是否有错误等;
    黑盒测试,该方法把程序当成一个整体,相当于宏观的看待事物,具体的说就是不看内部具体方法只是根据设计的需求来测试系统,然后判断是否符合设计的要求,是否能够正常使用该系统。

    5.3 系统的测试打开VS2015,运行程序源码,然后进入系统的欢迎界面了。本系统采用黑盒测试,对每一个模块进行用例测试。

    软件中登陆界面的测试
    首先,打开菜鸟驿站管理系统登陆界面,如表所示。



    编号
    输入操作
    预期结果
    测试结果




    1
    选择老用户,输入账号“1”,密码“student”,登陆
    登陆成功,跳转到 用户页面
    通过


    2
    选择管理员,输入账号“admin”,密码“admin”,登陆
    登陆成功,跳转到 管理员页面
    通过


    3
    选择新用户,输入账号“2”,密码“student”,注册,登录
    登陆成功,跳转到 用户页面
    通过


    4
    不输入任何信息,直接点击登陆
    登陆失败,提示输入账号
    通过


    5
    只输入密码“11”,不输入账号,点击登陆
    登陆失败,提示输入账号
    通过


    6
    选择老用户,输入账号“100”,密码“student”,登陆
    登陆失败,提示输入 账号错误
    通过


    7
    选择老用户,输入账号“1”,密码“stu”,登陆
    登陆失败,提示输入 密码错误
    通过




    用户账户信息管理测试
    接下来,对账号信息管理进行测试,如表所示。



    编号
    输入操作
    预期结果
    测试结果




    1
    打开查询功能
    查到个人信息
    通过


    2
    打开修改功能,修改完成后点击保存
    可以对个人信息进行修改
    通过


    3
    打开领取快递,输入用户快递的单号
    可以领取快递
    通过


    4
    打开返回主菜单
    系统返回主菜单
    通过




    管理员维护用户信息测试
    使用管理员模块对用户信息进行管理,如表所示。



    编号
    输入操作
    预期结果
    测试结果




    1
    打开录入功能,录入用户信息
    提示用户添加成功
    通过


    2
    打开修改功能,修改用户信息
    提示用户信息修改完成
    通过


    3
    打开删除功能,删除用户信息
    提示用户信息已删除
    通过


    4
    打开浏览功能,浏览用户信息
    输出用户信息
    通过




    管理员维护货物信息
    对管理员维护货物信息功能进行测试。



    编号
    输入操作
    预期结果
    测试结果




    1
    打开录入功能,录入货物信息
    提示货物信息添加成功
    通过


    2
    打开修改功能,修改货物信息
    提示货物信息修改完成
    通过


    3
    打开删除功能,删除货物信息
    提示货物信息已删除
    通过


    4
    打开浏览功能,浏览货物信息
    输出货物信息
    通过


    5
    打开统计货物信息
    会输出未领取货物的信息
    通过



    结束语通过对这个系统的设计和实现,我对该系统的了解更加深了。本系统主要是完成了用户信息管理、快递信息的管理以及信息统计分析等功能。通过本次学年设计,我对软件项目的开发流程以及所运用的知识如C语言等有了更多的自己的理解,锻炼了自己解决工程问题的能力以及提升了自己系统分析和设计能力。另一方面,本系统的实现,仍存在不足,如本人对于统计分析这个模块理解不足,以致在实现功能时没有考虑到具体的情况,造成某些功能设计的不是很合理。
    0 评论 8 下载 2019-08-07 10:51:07 下载需要10点积分
  • 基于C#的聊天程序

    1.引言1.1目的编写详细设计说明书是软件开发过程必不可少的部分,其目的是为了在完成需求分析说明书的基础上完成需求分析说明规定的各项模块的具体实现的设计工作。
    1.2定义套接字Socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
    端点IPEndPoint:由IP地址和端口号构成,端口对应进程。这两个组合起来可以唯一的标识网络中某台主机上的某一个进程。这样就有一个唯一的身份标识,后面可以进行通信了。
    TCP协议:TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议。
    回环端口:即本机的一个虚拟端口,为IPAddress.Loopback,其IP地址为127.0.0.1
    2.总体设计2.1软件描述荆棘鸟聊天程序是基于Socket设计的一个windows桌面端多人聊天程序,采用C/S架构,服务器可以自定义监听的IP(可设置为仅能本机使用或允许联机使用),客户端也可以设置服务器的IP,但是客户端设置的IP必须与服务器监听的IP相同,否则会连接不上服务器,如果不自己设置IP,默认为只能本机使用,即127.0.0.1.
    2.2设计方法本软件采用传统的软件开发生命周期的方法,采用自顶向下,逐步求精的结构化的软件设计方法
    2.3软件结构2.3.1总体结构
    3. 模块设计说明3.1程序描述本程序分成两部分,分别是服务器端和客户端。服务器启动后,用户使用客户端连上服务器后即可进行多人聊天 。在一台机器上,服务器只能启动一个,而客户端可以启动很多个,但是客户端的总数目不得超过100个。对于服务器和客户端,均采用多线程异步处理机制,在关闭程序后会自动回收所有子线程。
    3.2功能本程序能实现多人聊天功能。服务器打开后,客户端需要通过设置正确的服务器IP来连接服务器,服务器也可以设置自己能监听的IP地址进行监听,如果客户端与服务器均不手动设置IP,那么默认的IP是本机的回环地址(IPAddress.Loopback),而且客户端的IP和服务器端的IP必须设置为相同的才能正常连接上。客户端连接服务器的要求是必须设置一个唯一的用户名,用户名若重复则会进行提示并需要重新设置一个唯一的用户名后才能连接上服务器。同时客户端也会检测用户名是否包含敏感词汇(会影响程序正常运行的词),若包含也需要重新设置用户名。客户端连上服务器后,能显示服务器状态信息(服务器是否关闭)、是否有用户上下线以及其他用户发出来的消息。服务器端能显示用户的连接与下线信息,以及服务器的状态信息。同时服务器也能恢复默认监听的IP地址,即IPaddress.Loopback(127.0.0.1),且服务器会显示当前监听的IP地址。
    3.3 性能对于1M的带宽的网络

    客户端连接上服务器的时间在10秒以内。
    客户端间通信的时间间隔不得超过10秒。

    3.4 输入项
    服务器:需要输入(选填)监听的IP,如果不填则默认是本地回环端口127.0.0.1,输入的IP必须为格式正确且服务器所能监听的IP,否则将会进行提示。
    客户端:

    需要输入唯一的用户名(前17个字符不能为“Server has closed”,否则会影响程序正常运行),且用户名不能为空。连接上服务器后用户名将不能进行修改。需要输入服务器的IP以进行连接,格式和服务器的监听的IP相同,且客户端输入的IP必须和服务器监听的IP相同,否则将无法连接上。连接上服务器后服务器的IP不可修改。允许在输入框中输入文本信息以进行多人聊天,但是仅限文本信息。

    3.5 输出项
    服务器 :

    能显示当前监听的IP,如果不自己设置监听IP,则默认为127.0.0.1。能显示服务器的状态,即时启动还是关闭。能显示客户端连接服务器的状态,当客户端连接或者断开连接时,服务器端会显示。
    客户端:

    显示服务器状态信息,即服务器是否已经关闭。显示其他用户发来的信息,即进行正常的聊天。显示其他用户的上下线信息。

    3.6 流程逻辑首先启动服务器(服务器程序打开后会自动启动,此时监听的端口为127.0.0.1)。然后启动客户端,设置用户名,设置服务器的IP(如果不设置则默认为127.0.0.1)。点击客户端的连接服务器按钮,检查用户名是否合法,不合法则直接终止并需要重新设置用户名后重试,若用户名合法,则检查客户端设置的IP格式是否正确,若不正确则中断连接并需要重新设置服务器IP。然后进行客户端与服务器端的连接。若客户端与服务器设置的IP不一样,或者服务器未开启,则会提示连接失败,服务器未打开。
    正常连接上后,其他在线的客户端会提示此用户上线了。服务器可以点击关闭服务器,此时所有客户端都会提示服务器已关闭并自动关闭客户端与服务器的连接。客户端也可以点击退出聊天,可以关闭与服务器之间的连接,此时服务器端与其他在线用户均能收到此用户已下线的消息。
    服务器端在服务器开启后会显示当前所监听IP,若选择重置,则会先断开所有客户端的连接,然后重新开启服务器,并监听所设置的IP,显示的当前监听的IP也会随之改变。此时所有客户端全部被强制下线,必须设置与服务器相同的IP并重新连接服务器后才能继续进行聊天。
    3.7 接口
    当新用户连接上服务器后,会给服务器发送 “用户名”+“$”,服务器读取到这种格式的数据会将’$’去掉之后将其当成新用户进行保存,与该用户的套接字一起以键值对形式保存在字典中,并将上线消息进行转发。
    当用户需要退出聊天时,会给服务器发送“$”,服务器读取到仅有一个‘$’的数据时会将对该用户的连接关闭,并将其从用户字典中删去,且将用户下线信息进行转发。
    clientSocket为客户端中用来连接服务器的套接字,客户端用clientSocket != null && clientSocket.Connected根据情况判断是否连接上了服务器或服务器是否关闭。
    当服务器向用户发送的消息为“#用户名#”的时候,表示该用户名已经有人使用,需要客户端更换用户名后才能重新连接。
    当服务器向客户端发送的消息的前17个字符为“Server has closed”时,表示服务器已经关闭。
    在服务器端代码中,类Broadcast的成员函数PushMessage(String msg, String uName, Boolean flag, Dictionary<String, Socket> clientList)是用来对所有客户端进行转发信息的。当flag为false时表示是系统消息,直接发送msg+DateTime.Now.ToString(),而如果是其他客户端发送的聊天信息需要转发时,则设置flag为true,会发送uName: msg+ DateTime.Now.ToString()。

    3.8 注释设计函数模块的注释放在函数的头部,关键语句的注释放在语句的上面一行或者语句的后面。对所有参考资料均在注视中标明来源网址,并抄下或者自己写下了关键性的注解。
    3.9 限制条件本程序只能在64位windows操作系统下运行,且该系统必须装有.NET 4.5及以上的框架。
    0 评论 5 下载 2019-08-05 11:45:33 下载需要5点积分
  • 基于Java的迷宫老鼠游戏

    一、功能简介迷宫老鼠系统包括以下功能:

    自定义迷宫大小
    使用图的深度遍历随机生成迷宫
    用户使用鼠标绘制自定义迷宫
    单步求解迷宫
    一键求解迷宫
    声音特效

    二、程序截图




    三、系统开发平台
    名称:迷宫老鼠
    目的:利用堆栈寻找迷宫的路径解法。

    编程语言:Java开发工具:Eclipse操作系统:Windows

    四、系统规划4.1 任务陈述现实生活中总会有各种各样的寻径问题,比如地图寻路、导航驾驶等等。本次要开发的是将日常遇到的问题抽象化后形成的系统,抽象化提出要求后,根据具体需要,可设计为游戏或者应用。本次项目的名称是迷宫老鼠,它的应用主要用于解决迷宫的寻径问题。
    4.2 任务目标
    解决迷宫问题:入口A已经给出,要求从A进入,正确的尽可能快速的从出口B走出。
    随机设计一个迷宫并且求解
    自定义一个迷宫并且求解。

    五、流程图
    六、需求分析6.1 数据结构需求数据结构主要涉及三个部分:

    顶点的数据对象:包含四个1/0整数数据表示该点四个方向的连通状况,数据之间没有联系。
    迷宫的地图:需要对迷宫的路径进行存储,大小固定,组内元素没有联系,互不影响,没有先后顺序。组内的数据类型为封装好的顶点对象类。
    迷宫求解中的路径:需要存储经过的路径,元素为封装的顶点对象。元素必须按照顺序排列,先进先出,数据大小无影响。

    6.2 操作需求6.2.1 随机模式
    6.2.2 自定义模式中
    七、 实现思想(分两部分:随机生成可解迷宫与自定义迷宫)7.1 随机生成可解迷宫首先,迷宫由n*n个方阵点组成,每个点有控制上下左右,4个方向的墙的属性值,以推倒墙的方式来构建两点间的通路。要是两点间有通路,即要使左边的正方形推倒右墙,右边的正方形推倒左墙,则形成此通路,通过设置点的属性值来保存构成迷宫的点。
    利用图的深度优先遍历原则,从起点(0,0)开始,想任意可访问的点进行随机深度遍历,直至所有点都被遍历到为止(此处遍历全部的点是为了使迷宫看起来更加和谐好看,也增加了迷宫的复杂度),深度遍历的路径即为迷宫可行走的通路,当解迷宫时只能在此规定的通路上寻求通路,也就间接的形成了迷宫。
    由于图的深度遍历的特点,起点(0,0)可以到达图中任何一个点,此处设置终点为矩阵的最后一个点,确保了起点到终点一定有通路,且通路唯一。将构成迷宫的所有点形成一个可变数组ArrayList,以供解迷宫时使用。
    解迷宫时,方向选择按照先右,后下,再左上,并且提供计算两点间在确定方向上是否存在通路的判断方法,如果该点找到了下一个可通行的点,则将该点加入堆栈,如果找不到,则从堆栈中取出一个点,即形成了回路。
    7.2 自定义迷宫首先根据输入生成m*n个方格,通过鼠标点击事件,生成点击的方格处设置障碍,由此生成迷宫。解迷宫时,在上述解迷宫的基础上,加入没有通路的判断(即到达不了终点的判断),即堆栈已经为空,但仍要从其中取出点时,表示此迷宫已经没有可以再到达的点,此时反映迷宫无通路,给予用户提示,解迷宫完成。
    八、 数据结构设计首先,利用动态数组储存迷宫的所有点类(MazePoint类),随机生成与自定义迷宫的过程中,便是通过设置这些迷宫点来构造迷宫的。
    数据结构设计关键在解迷宫时予以体现,此处我利用堆栈的思想,讲解迷宫时经过的点压入堆栈,当在一点找不到可到达的下一点时,便取出堆栈中最顶层的点,将此点设为当前点寻找可到达的点,依次进行此过程,直至到达终点或堆栈中已没有点可以被取出为止。
    以为在解迷宫的过程中,寻找过得点被唯一标识,当形成回路再寻找可到达的点时,这些被唯一标识的点不会被二次到达,以此保证迷宫不会出现死循环的状态。
    0 评论 1 下载 2019-08-04 10:07:02 下载需要10点积分
  • 基于C++的画图程序

    (实验说明:本程序是在linux系统下编写编译的,没有Windows可执行文件,所以只能给出源码,但是经测试好像源码在windows系统下opencv库有一些问题,不能正常编译,所以只能在linux下运行,编译器使用clion即可。要想在本地运行成功,需要修改画图程序main文件第98行的fopen的参数为本地的一个位置,并把图形程序mainwindow.cpp中所有的fopen(”/home/li/cghm/binary.dat”,”wb”)中的”/home/li/cghm/binary.dat”改为上面修改的路径,同时修改该文件第54行的program->start函数的参数为图形程序编译后生成的可执行文件的路径。最后图形程序和画图程序要分别编译。以后如有时间,我会写一个自动配置这些东西的脚本,目前只能用这样的方法将就运行一下。生成的图片在画图程序目录下,名字为“test.jpg”)
    用到的计算机图形学原理
    投影变换原理:在世界坐标系内构建物体,根据摄像机位置应用坐标变换,得到观察者坐标系;再利用投影矩阵得到观察到的图象。
    物体遮挡:根据z-buffer算法计算不同物体的次序,形成观察者看到的图象。

    <应用算法> 坐标变换、投影变换、z-buffer.
    主要代码实现原理一、类架构MyPoint:

    <变量> h-齐次坐标, x,y,z-三维空间位置;Distance-记录该点到观察点的距离;next-所有点组成的链表
    <函数> Assignment-复制另一个点Equal-判断两个点是否相等CalcDistance-计算距离
    MyLine:

    <变量> Start End – 起始、终止点;PointOnLine – 该直线上所有点next – 所有直线组成的链表<函数> BulidLine – 构建一条直线
    MyPlane:所有的平面都设定为三角形平面,简化类别

    <变量> Vertex-i 表示三个顶点;PointOnPlane 平面上所有点;next 一个物体中的所有平面<函数> IsExisted 判断某点是否出现在该平面上;
    MyObject:

    <变量> 记录点、线、面的数量;以链表形式存储点、线、面;存储物体颜色;<函数>添加 点、线、面。
    PointInfo:

    记录与投影平面相关的一些信息,包括某个点到投影平面的距离、该点的颜色。
    MyGraph:

    <变量> ObjectOfWorld – 世界坐标系中的物体MyView – 投影平面,设定大小是256*512;Camera – 记录摄像机的坐标;Delta – 表示摄像机在平动方向的移动距离;Rotationangle – 表示摄像机旋转的角度<函数> AddObject – 添加物体;Trans – 将其转化为图片输出。
    二、投影变换Projection:世界坐标系转换至观察者坐标系

    Displacement:摄像机平移

    Rotation:摄像机旋转

    三、进程机制为了使得每次有新的输入都会重新计算并更新图像,在主函数里采取了检查机制,每20ms检查一下输入文件里的内容是否改变,改变就执行绘图主函数,否则就等待。
    界面的编写界面用qt5编写,开发界面如下

    主要思路是start按钮用来执行第一遍画图程序,上下左右按钮调整观察点位置
    横向滑动条用来改变视角方向,垂直滑动条用来调整视角高低
    每次有动作就会更新视角角度,位置的xyz坐标等参数,写入二进制文本中,供画图程序重新画图,按钮滑动条的控制使用了qt的信号槽技术
    展示效果初始图像

    按↓平移

    再按←平移

    视角向左移动

    视角向上移动

    视角向下移动

    可改进的地方一开始写这个程序的时候没有考虑到内存的问题,“MyPoint”这个类设计的不好,投影点和原来的点是不同的对象,每次都要新建一个链表存这些对象,一幅256*512,三个几何体的图像占用内存25Mb左右,执行几十次内存就爆了。尝试过析构,但是因为中间不知道哪里写的有问题,强行析构会报运行错误。
    之后想到了更好的数据结构,让MyPoint类包含投影点坐标数据成员,这样不用新建链表,理论上内存不会变多,无论执行多少次都会维持在50Mb以下。但是由于时间仓促,而且改数据结构整个程序也要全部配合修改,没有来得及改动。打算暑假修改一下,这样可以让程序更流畅,而且显示的图形可以更多。
    改用新的数据结构后,理论上也可以应用更快的填充算法,图像可以做的分辨率更高而不占用更多资源。
    在倒数第二节课上的光线效果也提供了一个新思路,可以添加光源并计算物体表面的亮度,这个改动对于这个程序来说并不困难,也可以考虑加进来。
    还有就是图形界面与操作的优化,实际上用界面上提供的几个按钮与滑动条控制视角效果很奇怪,我在考虑换成直接在图像上拖拽的操作形式。
    以及应用上的改进,这个程序实际上有很强的应用性,可以模拟3D效果,目前想到的应用有3D魔方小游戏,4维几何体在三维空间投影的演示。
    0 评论 1 下载 2019-08-03 17:49:13 下载需要9点积分
  • 基于C语言的饭卡程序

    第1部分 实训题目与要求1. 问题提出饭堂用饭卡卖饭,不仅提高卖饭速度,还通过计算机管理,提高了管理效率和管理质量。
    2. 功能要求重复显示如图所示的主菜单,在主菜单中选择任意一项,均实现相应功能。

    在主菜单中选择1,建立名为card.dat的文件,并在其中添加若干人的饭卡号、姓名、金额、挂失信息,要求饭卡号是唯一的。
    在主菜单中选择2,要求用户输入饭卡号、饭费,然后系统自动从该人的饭卡中减去饭钱,并分别显示买饭前后的金额,如果原来饭卡中的余额不足5元,则不能买饭,而且显示“余额不够,请续钱!”,如果挂失信息为真,则显示“本卡已冻结!”。
    在主菜单中选择3,要求用户输入饭卡号、续钱额,续钱完成后分别显示续钱前后的金额。
    在主菜单中选择4,添加新饭卡,这时要求新饭卡号和已有的饭卡号不能重号。
    在主菜单中选择5,注销旧饭卡。
    在主菜单中选择6,要求用户输入饭卡号和挂失信息,然后更新该饭卡的挂失信息。
    在主菜单中选择7、8、9,此项功能学生自由发挥,根据本组爱好增加与本题目相关的新功能。
    在主菜单中选择0,显示结束信息(如“感谢使用本软件!已正常退出,按任意键结束!”),按任意键后,退出本系统。
    第2部分 设计实训题目功能1. 总体设计
    2.算法设计2.1 Input_Choice
    2.2 Build_File
    2.3 Creat_new
    2.4 Start_Card
    2.5 Insert_Card
    2.6 Use_Card
    2.7 Charge_Money
    2.8 Delete_Card
    2.9 Lost_Card
    2.10 Search_Card
    2.11 Sort_Card
    2.12 Print_Card
    2.13 Open_File&Close_File
    3. 数据结构#define C card_imf#define S struct#define I intS C{ long number; char name[20]; double money; I lost; S C *next;};
    在这个数据结构中,以long型定义的number表示饭卡号,char型定义的name代表学生的姓名,double型money代表饭卡中的余额,int型lost代表饭卡是否挂失。
    4. 程序代码设计4.1 Input_Choice用for循环+if\else语句把可视化框架打出来,接收用户的返回值赋给主函数中的switch语句。
    4.2 Build_File从无到有新建一个“card.dat”文件。
    4.3 Creat_new从内存上动态分配若干个长度为该结构数组的空间作为链表,把存储介质上 “card.dat”文件中的数据导入链表。
    4.4 Start_Card初次运行程序时输入的初始数据,由于不存在数据赋给头指针,若直接运行函数“Insert_Card”会造成错误,即群龙无首,所以增加“Start_Card”函数避免此问题。
    4.5 Insert_Card在通过“Start_Card”函数创建完成第一个结构数组的数据后,通过此函数创建更多的学生数据。
    4.6 Use_Card首先这个函数会调用“Check_Card”函数扫描一遍学生数据,判定该饭卡信息是否存在;如果不存在输出“饭卡不存在!”。如果存在,系统自动从该人的饭卡中减去饭钱,并分别显示买饭前后的金额,如果原来饭卡中的余额不足5元,或余额低于当前消费额,则不能买饭,并显示“余额不够,请续钱!”,以及如果挂失信息为真,则亦不能消费,并显示“本卡已冻结!”。
    4.7 Charge_Money首先这个函数会调用“Check_Card”函数扫描一遍学生数据,判定该饭卡信息是否存在;确定存在后会让用户输入充值额,充值后会显示充值前后的余额。以及如果挂失信息为真,则不能充值,并显示“本卡已冻结!”。
    4.8 Delete_Card首先这个函数会调用“Check_Card”函数扫描一遍学生数据,判定该饭卡信息是否存在;确定存在后使该行信息脱离链表,即删除该饭卡的信息,输出“旧饭卡注销成功!”。
    4.9 Lost_Card首先这个函数会调用“Check_Card”函数扫描一遍学生数据,判定该饭卡信息是否存在;确定存在后再输出此卡的挂失状态,由用户变更此卡的挂失状态。
    4.10 Search_Card首先这个函数会调用“Check_Card”函数扫描一遍学生数据,判定该饭卡信息是否存在;确定存在后输出该饭卡信息。
    4.11 Sort_Card由用户决定将所有信息升序&降序排列,程序将用“选择排序法”对所有链表信息进行排序,排完后将链表中的数据输出到“card.dat”文件。
    4.12 Print_Card遍历饭卡文件,输出到屏幕。
    4.13 Open_File&Close_File各函数打开“card.dat”文件的方式不同,由各函数传回的openmode决定以何种方式打开文件;开关文件若不成功,输出相应的提示语。
    5. 测试与调试


    测试数据类型
    测试数据合法性
    测试数据
    预期结果
    实测结果




    Input_Choice

    4
    跳转至Insert_Card或Start_Card函数
    跳转成功,下一步输入饭卡的详细信息


    Input_Choice

    10
    清屏
    清屏


    Use_Card

    任意数字(此时测试数据组饭卡余额为4)
    无法消费并弹出“余额不足,请充值!”字样
    与预期结果一致


    Sort_Card

    1
    所有饭卡数据降序排列,输出“已按照您的选项进行排列!”字样
    通过遍历函数输出后证明与预期结果一致


    Sort_Card

    3
    输出“请输入正确的选项编号”字样
    与预期结果一致


    Search_Card

    (输入一个文件中不存在的饭卡编号)
    输出“饭卡不存在!”字样
    与预期结果一致



    第3部分 实训总结
    通过宏定义有效减少了重复的定义名的输入,加快了编程效率;
    由于平时上课有认真听,课后也有更加深入地学习相关的编程知识,所以一路写下来基本没有遇到困难,唯一遇到的「群龙无首」问题也很快通过if-else语句解决了。
    本来想在遍历函数前写一个管理员身份验证的函数,但考虑到并没有什么卵用,毕竟“card.dat”整体未被加密,想看随时打开dat文件就能看了。再写一个验证步骤显得特别矫情。
    这里详细为大家讲解一下如何通过两个指针就能实现链表的冒泡排序:首先与对数组进行冒泡排序的思路一致,各相邻结构数组比较某个成员的大小,不符合当前大小排序条件的就两两互换;以按照饭卡号升序(由小到大)排列为例,整个链表中饭卡号最大的那个结构数组通过这样的交换会成为整个链表的最后成员,这样还剩余(所有成员数-1)个成员需要排列,这样使用双for语句嵌套循环即可完成对整个链表的排序。而指针扮演的是搬运工的角色:用p1、p2分别指向满足交换条件相邻的两个成员,然后把前一个成员的值赋给过渡成员temp,再让temp(前一个成员的值)的next指向后一个成员的next,再把后一个成员的值赋给前一个成员,把temp(前一个成员的值)的值赋给后一个成员,此时前后两个成员的值已经互换了,最后把前一个成员(值为之前的后一个成员)的next赋给后一个成员(值为之前的前一个成员)即可。这样p1、p2依然指向前后两个已经交换了位置的成员,相较于本人之前考虑直接断链再接时发生的p1、p2所指向的成员发生颠倒的情况,这种办法更为简洁有效。接下来p1、p2指向其对应的next,对下一组相邻的成员再次执行以上的成员交换,直到双循环结束。
    其实之前是想做出更好的可视化窗口的,但问了一圈各路编程大佬之后还是放弃了,他们异口同声地告诉我,现在学的C语言其实是在学核心算法,算法最重要,这些算法搞定了以后可以用其他比C更好的语言写可视化窗口。后来一想,其实道理确实是这样的,一开始我们可能做不出什么像模像样的软件,但这就是学习的必经之路,只有一步一个脚印扎扎实实把基础的编程思想学好了,以后才有能力去做那些复杂的工程。所以对于我个人而言,稍安勿躁,步步为营,把该学的学好才是重点,而不是急于求成地迫切想做出什么实质性的东西,就算做出来,也未必是最优的。
    0 评论 5 下载 2019-08-02 18:03:16 下载需要5点积分
  • 基于QT与mplayer的视频播放器

    一、课题的介绍和课题的任务1.1 课题的介绍本次课程设计我选的题目是视频播放器。目前市场上各种应用商店上有各种播放器,而且功能都很强大。一直对里面的具体实现有兴趣,所以这次就尝试着写了个视频播放器。并且加进去了一些很实用的功能,比如截屏和录屏。
    1.2 课题的任务包括视频的播放暂停、音量的加减、播放速度的设置、以及视频文件的添加删除、屏幕的截屏以及录屏。画面不卡顿。播放时进度条能刷新。
    二、设计的要求
    能进行视频的播放
    能暂停正在播放的视频
    能播放正在暂停的视频
    能调节视频播放的视频
    能进行视频播放进度的调节
    能停止正在播放的视频
    能添加新的视频文件到播放列表
    能删除播放列表中选中的视频
    能改变视频播放的速度
    能对正在播放的视频进行截屏
    能录制正在播放的视频

    三、系统的分析和系统中类的设计
    窗口类QMainWidndow
    按钮类QPushButton
    标签类QLabel
    列表类QList
    滑动条类QSilider
    显示类QWidge

    四、系统的实现及调试系统模块框架图

    程序具体实现
    4.1 添加文件进视频播放列表
    代码实现:
    void mplayer_video::on_open_clicked(){ QStringList filenames =QFileDialog::getOpenFileNames(this,tr("选择文件"),"/",tr("视频文件(*mp3 *mp4 *wma *3gp *wav *avi *flv *rmvb *mkv *ts *wmv)")); // *号和前面的要隔开至少一个空格,不能连起来。 if(filenames.count()!=0) ui->list->addItems(filenames);}
    4.2 双击列表选项进行播放
    代码实现:
    void mplayer_video::on_list_itemDoubleClicked(QListWidgetItem *item){ speed=1; ui->lupin_lable->setVisible(false); play(item->text());}void mplayer_video::play(QString fileName){ QStringList arg1; process->kill(); process=new QProcess(this); arg1 << fileName; arg1 << "-slave";//默认情况下,mplayer接受键盘的命令,而"-slave"使其不再接受键盘事件,而是作为后台程序运行, //接受以“\n”结束的命令控制,这样我们可以在进程中给他发送命令,而不需要操作键盘了. arg1 << "-quiet"; //尽可能的不打印播放信息 arg1 << "-zoom"; //视频居中,四周黑条,全屏播放 arg1 << "-wid" << QString::number((unsigned int)(ui->widget->winId())); // "-wid <窗口标识>" 是指让MPlayer依附于那个窗口, //ui->widget->winId() 这个指令就是用来获取widget的标识码 , //这样视频播放的时候,就在这个部件里播放,相当于给他固定起来。 connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->start(arg,arg1); //开始播放进程 ui->zanting->setText("暂停");}void mplayer_video::dataRecieve(){ process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); while(process->canReadLine()) { QByteArray b=process->readLine(); if(b.startsWith("ANS_TIME_POSITION")) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentStr=s.mid(18); ui->horizontalSlider->setValue(s.mid(18).toFloat()); //更新进度条 } else if((b.startsWith("ANS_LENGTH"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); totalTime=s.mid(11); ui->label_time->setText(currentStr+"秒/"+totalTime+"秒 "); //显示时间进度 ui->horizontalSlider->setRange(0,s.mid(11).toFloat()); } else if((b.startsWith("ANS_PERCENT_POSITION"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentPercent=s.mid(21); ui->percentLabel->setText(currentPercent+"%"); } }}
    4.3 播放与暂停的实现
    代码实现:
    void mplayer_video::on_zanting_clicked(){ ui->lupin_lable->setVisible(false); process->write("pause\n"); //ui->list->currentRow()!=-1 判断是否有选中某条数据 //play(ui->list->item(ui->list->currentRow())->text()); 播放选中的某条数据 if(ui->zanting->text()=="播放") { if(ui->list->count()==0) QMessageBox::warning(this,"提示","播放列表为空",QMessageBox::Yes); else { connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); ui->zanting->setText("暂停"); } } else { disconnect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); ui->zanting->setText("播放"); }}
    4.4 快进与回退代码实现:
    void mplayer_video::on_back_clicked(){ process->write("seek -10\n");}void mplayer_video::on_quick_clicked(){ process->write("seek +10\n");}
    4.5 加速与减速代码实现:
    void mplayer_video::on_back_clicked(){ process->write("seek -10\n");}void mplayer_video::on_quick_clicked(){ process->write("seek +10\n");}
    4.6 停止播放代码实现:
    void mplayer_video::on_stop_clicked(){ process->write("quit\n"); ui->horizontalSlider->setSliderPosition(0); ui->label_time->clear(); ui->percentLabel->clear(); ui->zanting->setText("播放");}
    4.7 从播放列表中删除中选中的视频
    代码实现:
    void mplayer_video::on_del_clicked(){ if(ui->list->currentRow()==-1) QMessageBox::warning(this,"提示","未选中项目或列表为空",QMessageBox::Yes); else { ui->list->takeItem(ui->list->currentRow()); process->close(); ui->horizontalSlider->setSliderPosition(0); //更新进度条 ui->label_time->clear(); ui->percentLabel->clear(); }}
    4.8 加速播放与减速播放
    代码实现:
    定义一个全局静态浮点型变量 speed并初始化为1,每次点击加速,speed的值乘以二,每次点击减速,speed的值除以2
    void mplayer_video::on_jiansu_clicked(){ speed=speed/2; process->write(QString("speed_set "+QString::number(speed)+" 2\n").toUtf8());}void mplayer_video::on_jiasu_clicked(){ speed=speed*2; process->write(QString("speed_set "+QString::number(speed)+" 2\n").toUtf8());}
    4.9 视频播放进度条的刷新这是本程序里最复杂的部分之一。
    主要实现是用connect函数链接进程与DataRecieve函数
    代码实现:
    void mplayer_video::dataRecieve(){ process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); while(process->canReadLine()) { QByteArray b=process->readLine(); if(b.startsWith("ANS_TIME_POSITION")) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentStr=s.mid(18); ui->horizontalSlider->setValue(s.mid(18).toFloat()); //更新进度条 } else if((b.startsWith("ANS_LENGTH"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); totalTime=s.mid(11); ui->label_time->setText(currentStr+"秒/"+totalTime+"秒 "); //显示时间进度 ui->horizontalSlider->setRange(0,s.mid(11).toFloat()); } else if((b.startsWith("ANS_PERCENT_POSITION"))) { b.replace(QByteArray("\n"),QByteArray("")); QString s(b); currentPercent=s.mid(21); ui->percentLabel->setText(currentPercent+"%"); } }}
    4.10 声音滑动条对声音的调节
    代码实现:
    void mplayer_video::on_voice_slider_sliderMoved(int v){ if(ui->zanting->text()=="播放") { process->write(QString("volume "+QString::number(v)+" 2\n").toUtf8()); process->write("pause\n"); } else{ process->write(QString("volume "+QString::number(v)+" 2\n").toUtf8()); }}
    4.11 设置图片按钮
    代码实现:
    QPixmap pixmap; pixmap.load("G:/mplayer_video/voice.jpg"); ui->voice->setFixedSize(pixmap.width(),pixmap.height()); ui->voice->setIcon(pixmap); ui->voice->setIconSize(QSize(pixmap.width(),pixmap.height())); ui->voice->setToolTip("音量"); ui->voice->show();
    4.12 屏幕截图
    代码实现:
    void mplayer_video::on_jietu_clicked(){ cout<<"ok"<<endl; process->write("pause\n"); if(ui->zanting->text()=="播放") { cout<<"1"<<endl; QPixmap snapImage = QPixmap::grabWindow(QApplication::desktop()->winId()); QString filename; QString slcStr; filename = QFileDialog::getSaveFileName(this,tr("保存图片"),"./未命名",tr("PNG(*.png);;JPG(*.jpg);;BMP(*.bmp)"),&slcStr);//弹出保存图片的文件窗口 if(slcStr.left(3)=="JPG") { if(filename.right(3)!="jpg") { filename+=".jpg"; } } if(slcStr.left(3)=="PNG") { if(filename.right(3)!="png") { filename+=".png"; } } if(slcStr.left(3)=="BMP") { if(filename.right(3)!="bmp") { filename+=".bmp"; } } if(filename!=NULL) { snapImage.save(filename); } } else { cout<<"2"<<endl; disconnect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); ui->zanting->setText("播放"); QPixmap snapImage = QPixmap::grabWindow(QApplication::desktop()->winId()); QString filename; QString slcStr; filename = QFileDialog::getSaveFileName(this,tr("保存图片"),"./未命名",tr("PNG(*.png);;JPG(*.jpg);;BMP(*.bmp)"),&slcStr);//弹出保存图片的文件窗口 if(slcStr.left(3)=="JPG") { if(filename.right(3)!="jpg") { filename+=".jpg"; } } if(slcStr.left(3)=="PNG") { if(filename.right(3)!="png") { filename+=".png"; } } if(slcStr.left(3)=="BMP") { if(filename.right(3)!="bmp") { filename+=".bmp"; } } if(filename!=NULL) { snapImage.save(filename); } connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(dataRecieve())); process->write("get_time_length\n"); process->write("get_time_pos\n"); process->write("get_percent_pos\n"); ui->zanting->setText("暂停"); }}
    4.13 屏幕录制代码实现:
    void mplayer_video::on_lupin_clicked(){ if(ui->lupin->text()=="录屏") { photoStart(); timer->start(50); ui->lupin->setText("停止"); } else { timer->stop(); ui->lupin->setText("录屏"); }}void mplayer_video::photoStart(){ QDir *d = new QDir(); QString dirName("D:\\video"); if(!d->exists(dirName)) { d->mkdir(dirName); }}void mplayer_video::timerUpdate(){ QPixmap p; QString dirNamee("D:\\video\\"); dirNamee=dirNamee+QString::number(number)+".jpg"; p = QPixmap::grabWindow(QApplication::desktop()->winId()); p.save(dirNamee); number+=1;}
    4.14 屏幕录屏播放代码实现:
    void mplayer_video::on_lupinstart_clicked(){ process->write("quit\n"); QString dirName("D:\\video"); qdir = new QDir(dirName); qdir->setSorting(QDir::Reversed|QDir::Time); list = qdir->entryInfoList(); number2=0; timer2->start(100);}void mplayer_video::on_stop_bofang_clicked(){ timer2->stop(); ui->lupin_lable->setVisible(false);}
    五、系统的使用说明打开程序,点击添加文件进行视频播放列表视频的添加。双击列表中某条记录进行视频的播放,播放按钮自动转换成暂停按钮。点击播放将会播放视频,点击暂停视频会暂停。除了一些视频播放器的基本功能外,本程序还加入了屏幕截图与屏幕录制的功能。具体操作用按钮可以实现。
    1 评论 123 下载 2018-11-15 11:06:06 下载需要8点积分
  • 基于javascript的银行家算法

    1. 实验目的加深了解死锁概念,体会产生死锁的原因,掌握避免死锁的具体实施方法。
    2. 实验内容编写一个系统动态分配资源的模拟程序,采用银行家算法有效地避免死锁的发生。要求程序能够在进程提出资源申请后判断系统是否处于安全状态,如果安全则打印资源分配表和安全序列;如果不安全则输出不能分配的提示。提示:

    银行家算法可参阅教材和课件。
    利用文件读写操作配置系统状态。
    利用动态内存分配解决资源和进程数量动态变化的问题。

    3. 系统开发和运行环境


    操作系统
    Windows 7




    编程语言及工具
    JavaScript(jQuery),IE9以上/FireFox/ Chrome


    配置文件
    文件目录下的testfile.txt


    备注



    4. 程序设计4.1 数据结构var Max = []var Allocation = []var Need = []var Resourcevar Availablevar Requestvar safe = []var Work_Allocation = []var P = ['P0', 'P1', 'P2', 'P3', 'P4']function run() { Work_Allocation = [] //可分配资源+进程释放的已分配资源 Max = getMaxArr() //最大需求资源 Allocation = getAllocationArr() //已分配资源 Need = getNeedArr(Max, Allocation) //需求资源 Resource = getResource() //总资源数 Available = getAvailable() //可利用资源 Request = getRequest() //请求资源}

    可利用资源向量Available。这是一个数组对象,其中的每一个属性代表一类可利用资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态的改变。如果Available.j=K,则表示系统中现有Rj类资源K个。
    最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i].j=K;则表示进程i需要Rj类资源的最大数目为K。
    分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i].j=K,则表示进程i当前已分得Rj类资源的数目为K。
    需求矩阵Need。这也是一个n*m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成任务。

    上述三个矩阵间存在下述关系:Need[i].j=Max[i].j-Allocation[i].j
    4.2 主要算法设计

    5. 程序运行演示5.1 初始化页面
    5.2 读取文件数据点击

    选择testfile.txt文件

    输出结果:

    5.3 选择进程并输入请求资源数量
    输出结果:

    5.4 重置点击重置按钮

    输出结果:

    5.5 清空点击清空按钮

    输出结果:

    6. 实验总结
    用前端的html+bootstrap+javascript+jquery完成此次实验。
    支持文件的读取操作,以文本方式读取数据。
    用bootstrap渲染页面,简洁美观。
    从文件加载数据时采用了动态内存分配方式。
    用jQuery操作DOM对象,代码量减少。
    0 评论 2 下载 2019-08-01 12:59:05 下载需要10点积分
  • 基于HTML5实现的网页汽车商店

    摘 要随着人们生活质量的提高,有车的人是越来越多,无论你是有钱人还是没钱人,要么就是去买车,要么就是在买车的路上。而在当前,互联网在人们生活中的应用越来越频繁,死守传统的销售模式而不拥抱互联网的销售手段,将越来越难以打开销量。在移动互联网的时代,将销售模式与互联网结合起来的汽车销售网页的设计,使得人们可以更加方便地了解各类汽车信息和更加方便地购买汽车产品。这次的汽车商店网页设计,是以汽车及其配件的销售为题材,用HTML5及相关手段制作的一个网上汽车销售的网页。文章先介绍了前端技术的起源历史与发展以及未来前景,然后详细介绍了制作过程,最后总结这次的制作心得。
    关键字:网页;HTML5;汽车
    一、背景通过网络进行汽车销售,是这个时代发展的必然结果,是随着网络的普及和电子商务概念的兴盛而兴起的。这种全新出现的新型汽车销售形式,与传统通过4s店面进行销售的方式相比优势显著:

    降低了汽车销售成本
    改变汽车传统的了解和购买方式,使用网络平台了解汽车信息并购买,使得商业活动没有空间和时间的限制
    汽车信息的传递更有效率和直观,新车信息上传后,人们可以立即了解咨询,交易可以马上进行,从而大大提高了汽车交易的效率

    正是由于这些巨大的优势,汽车商店网页才能得以迅速地开拓市场。汽车商店网页主要是借助网页作为交易平台,将汽车的各项指标,优势劣势,精美图片发布到网络上,人们能够借助网络登录汽车商店网页来查看各种汽车的信息并提交订单或者预定汽车,实现在线交易。
    二、前端开发技术的起源及历史所谓前端是指针对浏览器的开发,代码在浏览器运行。而与之相对的后则是针对服务器的开发,代码在服务器运行。然而在互联网发展的早期,前后端开发是一体的,前端代码是后端代码的一部分。
    早在1991年的时候HTML就已经作为前端开发的统一语言,HTML代码部门其实很简单,任何一款浏览器在打开任意网页后检查页面源代码,就可以看到由很多不同的标识表记标帜加上中间的标识表记标帜名构成的标识表记标帜的作用只有一个,就是格式化的内容,例如文字的大小、颜色、位置等,以达到网站制作者想要表达的展示效果。所以网页的早期形态大都完全基于HTML页面,并且所有内容都是静态的。
    HTML5中的5代表版本号,可以简单地理解为第五代HTML尺度,实际在此之前有非常多的非主流版本的更新,不过这一代尺度提出了很多重大的功能更新。例如:Canvas标识表记标帜,轻松地实现网页动画与游戏;直接的多媒体支持,不再需要FLASH来提供多媒体内容;WebSocket,使得用户可以不借助任何额外的插件就能够通过网页来制作游戏及其他软件。H5的诞生不是巧合也不是人为炒作,而是历史的一定选择,这是历史的潮流,不能否认当今是互联网飞速发展的年代。
    三、HTML5的国内外发展现状与前景3.1 HTML5存在的意义HTML5的优点即是“一次性开发,多次分发”,它使得一次设计适应不同终端成为可能。信息流架构应用化都是直接在WEB端抓取数据,而HTML5可以直接使用跨平台数据面不使用后台API,大大降低了研发维护成本而且呈现的效果几乎没有什么区别。HTML5最大的意义在于改变WEB文档的结构方式,借助于header, foot, section, article这些标配、标签我们可以实现更具结构化语义化的WEB文档。这样,搜索引擎更容易索引到WEB站点,我们可以搜索到更快更准备的信息。HTML5的诞生,来自对浏览器和网页开发技术的改进,是一系列Web标准草案的集合。它不仅仅局限于HTML语言本身,还包括了CSS3以及JavaScript语言里新增的函数和功能。HTML5始终坚持不断发展,并很快得到广泛认可,这与其在制定之初就确立的核心理念有很大的关系。这些核心理念就是我们今天在W3C站点上所看到的HTML5设计原理这份文档,概括起来就是——兼容性、实用性、互操作性以及普遍可访问性。
    3.2 HTML5的国内外发展现状酷炫、快速、跨平台,在HTML5出现前,这些词从未这样紧紧与网页相关联在一起。HTML5改变了人们脑海中对传统网页的印象,取而代之的是堪比桌面程序和移动原生应用程序的用户体验。相比HTML4,现在的网页可以做到的显然要更多:音频、视频不再需要插件的支持,避免插件安装失败等可能导致的问题;JavaScript能力大为增强,借助HTML中新增的Canvas元素,更是能在网页中进行2D和3D图形、图像的实时绘制;CSS3的强大和良好的支持度让网页变得更加生动,同时还可以利用浏览器本身的硬件加速完成transition、animation等动画效果以及合成;网页还可以直接通过JavaScript访问摄像头、陀螺仪等等硬件设备。等等这些,所有的目的只有一个——让网页可以做得和原生应用一样强大、一样优秀。美国的HTML5市场经过数十年的长期发展之后,早进入理性的状态,不是炒作概念或者单纯的市场宣讲活动,甚至关注度出现了下降,已经变成了在web技术各个独立领域深度探索和创新。而中国的HTML5市场在2015年的才出现第一次的火热状态,相比于美国市场出现了更进一步的延后。
    3.3 HTML5的发展前景随着HTML5技术的发展,越来越多的商家倾向于基于HTML5的游戏开发。我国拥有世界上较大的游戏市场、最多的游戏用户,然而在游戏的研发以及发行上与国际市场仍有差距。目前很多HTML5游戏发行商在找靠谱的合作伙伴和产品,优质产品是现阶段的稀缺资源,这也算是当下HTML5游戏的一个市场机遇。此外,HTML5是移动互联网前端的主流开发语言,目前还没有任何一个前端的开发语言能取代HTML5的位置,无论做手机网站还是手机app应用,前端的样式都是HTML5开发,通过手机与电脑上网的使用率来看,目前通过手机上网的用户远远高于电脑端,这些数据都足以证明未来的移动互联网的发展前景,而HTML5又作为移动互联网主流前端开发语言,所以HTML5的发展前景一片光明。
    四、设计思想这次的网页汽车商店以汽车及其配件的销售为题材,制作的一个网上汽车销售的网页。
    4.1 网页的整体设计网页的整体设计采用了课堂上学的划分区域的方式,并且采用了div + css 的排版,使得整个页面的样式丰富多彩,形式多种多样。即使同样的素材,也可以通过css不同的设置而变得多彩。同时css还将页面的版式固定,不会因为显示器的大小的变化而变化,而使得页面的兼容性增加。

    4.2 “广告”的引入为了丰富网页的多样性,使得汽车销售网页更加真实化,我还在网页的左右两边、右上脚以及中间适当处添加了广告,当然,仅仅是相应的图片。

    4.3 登录注册页面 登录和注册页面使用了javascript脚本语言,帐户名验证和密码验证,使得网站在运行时的数据交换率减少,也在一定程度上提高了网页的加载速度。同时使用javascript还能做出更多丰富多彩的,页面特效,使得页面更加绚丽。



    五、部分实现代码及注释5.1 网页中汽车外饰用品的罗列<div id="mymall" class="fl bcolor2"> <ul><h3><a name="B">外饰用品<sup><img src="../images/xinpin.gif" /></sup></a></h3> <hr width="90%"/> <li><a href="#" target="_blank"><p>车衣</p></a></li> <li><a href="#" target="_blank"><p>车贴</p></a></li> <li><a href="#" target="_blank"><p>防滑链</p></a></li> <li><a href="#" target="_blank"><p>汽车贴膜</p></a></li> <li><a href="#" target="_blank"><p>爆闪灯</p></a></li> <li><a href="#" target="_blank"><p>车牌架</p></a></li> <li><a href="#" target="_blank"><p>车标</p></a></li> <li><a href="#" target="_blank"><p>密封条</p></a></li> <li><a href="#" target="_blank"><p>晴雨挡</p></a></li> <li><a href="#" target="_blank"><p>保险杠</p></a></li> <li><a href="#" target="_blank"><p>涡轮</p></a></li> <li><a href="#" target="_blank"><p>内车轮</p></a></li> </ul></div>
    5.2 网页中汽车内饰用品的罗列<div id="mymall" class="fl bcolor1"> <ul><h3><a name="A">内饰用品<sup><img src="../images/xinpin.gif" /></sup></a></h3> <hr width="90%"/> <li><a href="#" target="_blank"><p>汽车坐垫</p></a></li> <li><a href="#" target="_blank"><p>汽车座套</p></a></li> <li><a href="#" target="_blank"><p>方向盘套</p></a></li> <li><a href="#" target="_blank"><p>汽车脚垫</p></a></li> <li><a href="#" target="_blank"><p>汽车香水</p></a></li> <li><a href="#" target="_blank"><p>汽车挂件</p></a></li> <li><a href="#" target="_blank"><p>儿童座椅</p></a></li> <li><a href="#" target="_blank"><p>汽车摆件</p></a></li> <li><a href="#" target="_blank"><p>车钥匙扣</p></a></li> <li><a href="#" target="_blank"><p>车置物箱</p></a></li> <li><a href="#" target="_blank"><p>后备箱垫</p></a></li> <li><a href="#" target="_blank"><p>车灭火器</p></a></li> <li><a href="#" target="_blank"><p>防静电物</p></a></li> <li><a href="#" target="_blank"><p>小套饰</p></a></li> </ul> </div>
    5.3 网页中立体滚动球的制作<div id="qiu" class="bcolor fr"> <a href="#A">内饰用品<sup><img src="../images/rexiao.gif"</sup></sup></a> <a href="#A">汽车坐垫<sup><img src="../images/rexiao.gif"</sup></sup></a> <a href="#A">汽车座套</a> <a href="#A">方向盘套</a> <a href="#A">汽车挂件<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#A">车灭火器</a> <a href="#A">小套饰<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#A">防静电饰品<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#A">汽车摆件</a> <a href="#A">车钥匙扣<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#B">车衣</a> <a href="#B">车贴<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#B">防滑链</a> <a href="#B">汽车贴膜</a> <a href="#B">爆闪灯</a> <a href="#B">车牌架</a> <a href="#B">车标</a> <a href="#B">密封条</a> <a href="#B">晴雨挡</a> <a href="#B">保险杠</a> <a href="#B">涡轮<sup><img src="../images/rexiao.gif" /></sup></a> <a href="#B">内车轮</a> <a href="#C">涡轮增压</a> <a href="#C">后视灯<sup><img src="../images/rexiao.gif" /></sup></a> <a href="#C">雪地胎</a> <a href="#C">疝气灯<sup><img src="../images/xinpin.gif" /></sup></a> <a href="#C">日行灯</a> <a href="#C">挡泥板</a> <a href="#C">行李架</a> <a href="#C">车位锁</a> <a href="#C">鲨鱼鳍</a> <a href="#C">倒车灯</a> <a href="#C">尾翼</a> <a href="#C">发动机护板</a> </div>
    六、制作心得通过此次网页制作的过程,我学到了很多,首先我学会了HTML网页制作语言,虽然我学到的仅仅只是一部分,但是我明白了作为网页设计语言,HTML5的强大之处,使得我对这门语言的看法发生了根本性的转变,希望可以接触到更多的关于这方面的知识。当然在网页制作的过程中,我也遇到了许许多多的问题,但是通过不懈的努力,以及同学们的互帮互助,使我克服了这些困难。更多的希望在以后的学习和生活中我都会像在这次制作设计中一样,帮助别人,请教别人。希望老师在我学习的过程中多批评、多指教,感谢老师对我的教导。
    七、不足之处这次的网页汽车商店的设计,整体的设计思想是很完善的,但是由于水平有限、经验不足等,制作出来的成品还是存在这样或那样的瑕疵。比如,虽然我在网页的顶端加上了一个搜索栏,但是具体的搜索功能还有待完善;其次,右上角的购物车、我的车库以及联系客服栏目还没具体的实现……不过,这次的网页设计极大的唤起了我对网页设计的热情,从而也使我的个人技术进一步的提升。
    八、参考文献[1] 邢增智,郭龙,杜豪,刘顺林,彭永凤,段兴悦。 基于HTML5与CSS3的工业物联网工程中心网站开发[J]. 物联网技术,2017,(03):92-93+97.
    [2] 郭鲁。 基于HTML5的Web App前端开发的前景分析[J]. 南方农机,2017,(02):92.
    [3] 盛婷婷。 基于HTML5技术的移动Web前端设计与开发分析[J]. 电子制作,2016,(19):46-47+75.
    [4] 王燕妮。 HTML5应用现状分析[J]. 无线互联科技,2016,(13):28-29.
    0 评论 2 下载 2019-07-31 09:55:02 下载需要9点积分
  • 基于C++实现公司职工管理系统

    1、管理系统需求职工管理系统可以用来管理公司内所有员工的信息,教程主要利用C++来实现一个基于多态的职工管理系统。
    公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责

    普通员工职责:完成经理交给的任务
    经理职责:完成老板交给的任务,并下发任务给员工
    老板职责:管理公司所有事务

    管理系统中需要实现的功能如下:

    退出管理程序:退出当前管理系统
    增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
    显示职工信息:显示公司内部所有职工的信息
    删除离职职工:按照编号删除指定的职工
    修改职工信息:按照编号修改职工个人信息
    查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
    按照编号排序:按照职工编号,进行排序,排序规则由用户指定
    清空所有文档:清空文件中记录的所有职工信息 (清空前需要再次确认,防止误删)

    系统界面效果图如下:

    2、创建项目创建项目步骤如下:

    创建新项目
    添加文件

    3、创建管理类管理类负责的内容如下:

    与用户的沟通菜单界面
    对职工增删改查的操作
    与文件的读写交互

    3.1 创建文件在头文件和源文件的文件夹下分别创建workerManager.h 和 workerManager.cpp文件
    3.2 头文件实现在workerManager.h中设计管理类
    代码如下:
    #pragma once#include<iostream>using namespace std;class WorkerManager{public: //构造函数 WorkerManager(); //析构函数 ~WorkerManager();};
    3.3 源文件实现在workerManager.cpp中将构造和析构函数空实现补全
    #include "workerManager.h"WorkerManager::WorkerManager(){}WorkerManager::~WorkerManager(){}
    4、菜单功能功能描述:与用户的沟通界面
    4.1 添加成员函数在管理类workerManager.h中添加成员函数 void Show_Menu();
    4.2 菜单功能实现在管理类workerManager.cpp中实现 Show_Menu()函数
    void WorkerManager::Show_Menu(){ cout << "********************************************" << endl; cout << "********* 欢迎使用职工管理系统! **********" << endl; cout << "************* 0.退出管理程序 *************" << endl; cout << "************* 1.增加职工信息 *************" << endl; cout << "************* 2.显示职工信息 *************" << endl; cout << "************* 3.删除离职职工 *************" << endl; cout << "************* 4.修改职工信息 *************" << endl; cout << "************* 5.查找职工信息 *************" << endl; cout << "************* 6.按照编号排序 *************" << endl; cout << "************* 7.清空所有文档 *************" << endl; cout << "********************************************" << endl; cout << endl;}
    4.3 测试菜单功能在职工管理系统.cpp中测试菜单功能
    代码:
    #include<iostream>using namespace std;#include "workerManager.h"int main() { WorkerManager wm; wm.Show_Menu(); system("pause"); return 0;}
    5、退出功能5.1 提供功能接口在main函数中提供分支选择,提供每个功能接口
    代码:
    int main() { WorkerManager wm; int choice = 0; while (true) { //展示菜单 wm.Show_Menu(); cout << "请输入您的选择:" << endl; cin >> choice; switch (choice) { case 0: //退出系统 break; case 1: //添加职工 break; case 2: //显示职工 break; case 3: //删除职工 break; case 4: //修改职工 break; case 5: //查找职工 break; case 6: //排序职工 break; case 7: //清空文件 break; default: system("cls"); break; } } system("pause"); return 0;}
    5.2 实现退出功能在workerManager.h中提供退出系统的成员函数 void exitSystem();
    在workerManager.cpp中提供具体的功能实现
    void WorkerManager::exitSystem(){ cout << "欢迎下次使用" << endl; system("pause"); exit(0);}
    6、创建职工类6.1 创建职工抽象类职工的分类为:普通员工、经理、老板
    将三种职工抽象到一个类(worker)中,利用多态管理不同职工种类
    职工的属性为:职工编号、职工姓名、职工所在部门编号
    职工的行为为:岗位职责信息描述,获取岗位名称
    头文件文件夹下 创建文件worker.h 文件并且添加如下代码:
    #pragma once#include<iostream>#include<string>using namespace std;//职工抽象基类class Worker{public: //显示个人信息 virtual void showInfo() = 0; //获取岗位名称 virtual string getDeptName() = 0; int m_Id; //职工编号 string m_Name; //职工姓名 int m_DeptId; //职工所在部门名称编号};
    6.2 创建普通员工类普通员工类继承职工抽象类,并重写父类中纯虚函数
    在头文件和源文件的文件夹下分别创建employee.h 和 employee.cpp文件
    employee.h中代码如下:
    #pragma once #include<iostream>using namespace std;#include "worker.h"//员工类class Employee :public Worker{public: //构造函数 Employee(int id, string name, int dId); //显示个人信息 virtual void showInfo(); //获取职工岗位名称 virtual string getDeptName();};
    employee.cpp中代码如下:
    #include "employee.h"Employee::Employee(int id, string name, int dId){ this->m_Id = id; this->m_Name = name; this->m_DeptId = dId;}void Employee::showInfo(){ cout << "职工编号: " << this->m_Id << " \t职工姓名: " << this->m_Name << " \t岗位:" << this->getDeptName() << " \t岗位职责:完成经理交给的任务" << endl;}string Employee::getDeptName(){ return string("员工");}
    6.3 创建经理类经理类继承职工抽象类,并重写父类中纯虚函数,和普通员工类似
    在头文件和源文件的文件夹下分别创建manager.h 和 manager.cpp文件
    manager.h中代码如下:
    #pragma once#include<iostream>using namespace std;#include "worker.h"//经理类class Manager :public Worker{public: Manager(int id, string name, int dId); //显示个人信息 virtual void showInfo(); //获取职工岗位名称 virtual string getDeptName();};
    manager.cpp中代码如下:
    #include "manager.h"Manager::Manager(int id, string name, int dId){ this->m_Id = id; this->m_Name = name; this->m_DeptId = dId;}void Manager::showInfo(){ cout << "职工编号: " << this->m_Id << " \t职工姓名: " << this->m_Name << " \t岗位:" << this->getDeptName() << " \t岗位职责:完成老板交给的任务,并下发任务给员工" << endl;}string Manager::getDeptName(){ return string("经理");}
    6.4 创建老板类老板类继承职工抽象类,并重写父类中纯虚函数,和普通员工类似
    在头文件和源文件的文件夹下分别创建boss.h 和 boss.cpp文件
    boss.h中代码如下:
    #pragma once#include<iostream>using namespace std;#include "worker.h"//老板类class Boss :public Worker{public: Boss(int id, string name, int dId); //显示个人信息 virtual void showInfo(); //获取职工岗位名称 virtual string getDeptName();};
    boss.cpp中代码如下:
    #include "boss.h"Boss::Boss(int id, string name, int dId){ this->m_Id = id; this->m_Name = name; this->m_DeptId = dId;}void Boss::showInfo(){ cout << "职工编号: " << this->m_Id << " \t职工姓名: " << this->m_Name << " \t岗位:" << this->getDeptName() << " \t岗位职责:管理公司所有事务" << endl;}string Boss::getDeptName(){ return string("总裁");}
    6.5 测试多态在职工管理系统.cpp中添加测试函数,并且运行能够产生多态
    测试代码如下:
    #include "worker.h"#include "employee.h"#include "manager.h"#include "boss.h"void test(){ Worker * worker = NULL; worker = new Employee(1, "张三", 1); worker->showInfo(); delete worker; worker = new Manager(2, "李四", 2); worker->showInfo(); delete worker; worker = new Boss(3, "王五", 3); worker->showInfo(); delete worker;}
    7、添加职工功能描述:批量添加职工,并且保存到文件中
    7.1 功能分析分析:
    用户在批量创建时,可能会创建不同种类的职工
    如果想将所有不同种类的员工都放入到一个数组中,可以将所有员工的指针维护到一个数组里
    如果想在程序中维护这个不定长度的数组,可以将数组创建到堆区,并利用Worker **的指针维护
    7.2 功能实现在WokerManager.h头文件中添加成员属性 代码:
    //记录文件中的人数个数 int m_EmpNum; //员工数组的指针 Worker ** m_EmpArray;
    在WorkerManager构造函数中初始化属性
    WorkerManager::WorkerManager(){ //初始化人数 this->m_EmpNum = 0; //初始化数组指针 this->m_EmpArray = NULL;}
    在workerManager.h中添加成员函数
    //增加职工 void Add_Emp();
    在WorkerManager.cpp的析构函数中,释放堆区数据
    WorkerManager::~WorkerManager(){ if (this->m_EmpArray != NULL) { delete[] this->m_EmpArray; }}
    8、文件交互 - 写文件功能描述:对文件进行读写

    在上一个添加功能中,我们只是将所有的数据添加到了内存中,一旦程序结束就无法保存了
    因此文件管理类中需要一个与文件进行交互的功能,对于文件进行读写操作

    8.1 设定文件路径首先我们将文件路径,在workerManager.h中添加宏常量,并且包含头文件 fstream
    #include <fstream>#define FILENAME "empFile.txt"
    8.2 成员函数声明在workerManager.h中类里添加成员函数 void save()
    //保存文件void save();
    8.3 保存文件功能实现void WorkerManager::save(){ ofstream ofs; ofs.open(FILENAME, ios::out); for (int i = 0; i < this->m_EmpNum; i++) { ofs << this->m_EmpArray[i]->m_Id << " " << this->m_EmpArray[i]->m_Name << " " << this->m_EmpArray[i]->m_DeptId << endl; } ofs.close();}
    9、文件交互 - 读文件功能描述:将文件中的内容读取到程序中
    虽然我们实现了添加职工后保存到文件的操作,但是每次开始运行程序,并没有将文件中数据读取到程序中
    而我们的程序功能中还有清空文件的需求
    因此构造函数初始化数据的情况分为三种

    第一次使用,文件未创建
    文件存在,但是数据被用户清空
    文件存在,并且保存职工的所有数据

    9.1 文件未创建在workerManager.h中添加新的成员属性 m_FileIsEmpty标志文件是否为空
    //标志文件是否为空 bool m_FileIsEmpty;
    修改WorkerManager.cpp中构造函数代码
    WorkerManager::WorkerManager(){ ifstream ifs; ifs.open(FILENAME, ios::in); //文件不存在情况 if (!ifs.is_open()) { cout << "文件不存在" << endl; //测试输出 this->m_EmpNum = 0; //初始化人数 this->m_FileIsEmpty = true; //初始化文件为空标志 this->m_EmpArray = NULL; //初始化数组 ifs.close(); //关闭文件 return; }}
    删除文件后,测试文件不存在时初始化数据功能
    9.2 文件存在且数据为空在workerManager.cpp中的构造函数追加代码:
    //文件存在,并且没有记录 char ch; ifs >> ch; if (ifs.eof()) { cout << "文件为空!" << endl; this->m_EmpNum = 0; this->m_FileIsEmpty = true; this->m_EmpArray = NULL; ifs.close(); return; }
    9.3 文件存在且保存职工数据9.3.1 获取记录的职工人数在workerManager.h中添加成员函数 int get_EmpNum();
    //统计人数 int get_EmpNum();
    在workerManager.cpp构造函数中继续追加代码:
    int num = this->get_EmpNum(); cout << "职工个数为:" << num << endl; //测试代码 this->m_EmpNum = num; //更新成员属性
    9.3.2 初始化数组根据职工的数据以及职工数据,初始化workerManager中的Worker ** m_EmpArray 指针
    在WorkerManager.h中添加成员函数 void init_Emp();
    //初始化员工 void init_Emp();
    10、显示职工功能描述:显示当前所有职工信息
    10.1 显示职工函数声明在workerManager.h中添加成员函数 void Show_Emp();
    //显示职工 void Show_Emp();
    11、删除职工功能描述:按照职工的编号进行删除职工操作
    11.1 删除职工函数声明在workerManager.h中添加成员函数 void Del_Emp();
    //删除职工 void Del_Emp();
    11.2 职工是否存在函数声明很多功能都需要用到根据职工是否存在来进行操作如:删除职工、修改职工、查找职工
    因此添加该公告函数,以便后续调用
    在workerManager.h中添加成员函数 int IsExist(int id);
    //按照职工编号判断职工是否存在,若存在返回职工在数组中位置,不存在返回-1 int IsExist(int id);
    11.3 职工是否存在函数实现在workerManager.cpp中实现成员函数 int IsExist(int id);
    int WorkerManager::IsExist(int id){ int index = -1; for (int i = 0; i < this->m_EmpNum; i++) { if (this->m_EmpArray[i]->m_Id == id) { index = i; break; } } return index;}
    12、修改职工功能描述:能够按照职工的编号对职工信息进行修改并保存
    12.1 修改职工函数声明在workerManager.h中添加成员函数 void Mod_Emp();
    //修改职工 void Mod_Emp();
    13、查找职工功能描述:提供两种查找职工方式,一种按照职工编号,一种按照职工姓名
    13.1 查找职工函数声明在workerManager.h中添加成员函数 void Find_Emp();
    //查找职工 void Find_Emp();
    14、排序功能描述:按照职工编号进行排序,排序的顺序由用户指定
    14.1 排序函数声明在workerManager.h中添加成员函数 void Sort_Emp();
    //排序职工 void Sort_Emp();
    15、清空文件功能描述:将文件中记录数据清空
    15.1 清空函数声明在workerManager.h中添加成员函数 void Clean_File();
    //清空文件 void Clean_File();
    0 评论 3 下载 2019-07-26 17:22:01 下载需要15点积分
  • 仿天猫电子商务(含前端后台数据库)

    一、基础1.1 项目简介1.1.1 基于J2EE整套技术本项目没有使用SSH,SSM框架,而是使用J2EE整套技术来作为解决方案,实现各种业务场景。在项目中借助反射等技术,采用了精妙的设计模式,开发效率并不低于使用框架。
    1.1.2 典型场景一个完整的J2EE应用包含的各种典型商务应用场景的需求,展示相应的解决思路与办法
    1.2 开发流程1.2.1 技术准备
    Java:java基础和java中级的内容
    前端:html,css,js,jquery
    J2EE:tomcat,servlet,jsp,filter
    数据库:mysql

    1.2.2 开发流程模仿天猫整站是一个比较大的项目,将按照商业项目的开发流程有条不紊的一一展开:
    1.2.2.1 需求分析首先确定要做哪些功能,需求分析包括前台和后台。前台又分为单纯要展示的那些功能-需求分析-展示,以及会提交数据到服务端的哪些功能-需求分析-交互。
    1.2.2.2 表结构设计接着是表结构设计,表结构设计是围绕功能需求进行,如果表结构设计有问题,那么将会影响功能的实现。除了表与表关系,建表SQL语句之外,为了更好的帮助大家理解表结构以及关系,还特意把表与页面功能一一对应起来
    1.2.2.3 原型接着是界面原型,与客户沟通顺畅的项目设计流程里一定会有原型这个环节。 借助界面原型,可以低成本,高效率的与客户达成需求的一致性。 同样的,原型分为了前台原型和后台原型。
    1.2.2.4 实体类设计接着开始实体类的设计与开发,实体类不仅仅是对数据库中的表的一一映射,同时还需要兼顾对业务功能的支持。
    1.2.2.5 DAO类设计然后是DAO类的设计,除了进行典型的ORM支持功能之外,也需要提供各种业务方法。
    1.2.2.6 业务类介绍讲解的业务类的概念,以及为什么在本项目中没有包含这一层
    1.2.2.7 后台-分类管理接下来开始进行功能开发,按照模块之间的依赖关系,首先进行后台-分类管理功能开发。严格来说,这是开发的第一个功能,所以讲解的十分详细,不仅提供了可运行的项目,还详细解释了其中用到的设计模式,JSP包含关系,以及每个具体的功能: 查询,分页,增加,删除,编辑,修改。 把每个细节都掰的很细,可以更好的理解,消化和吸收。 在把后台-分类管理 吃透之后,后续的其他后台管理功能,做起来就会更加顺畅。
    1.2.2.8 后台-其他管理在把后台-分类管理 消化吸收之后,就可以加速进行 后台其他页面的学习。
    1.2.2.9 前台-首页前台也包括许多功能, 与后台-分类管理类似的,首先把前台-首页这个功能单独拿出来,进行精讲。前台-首页 消化吸收好之后,再进行其他前台功能的开发。
    1.2.2.10 前台无需登录从前台模块之间的依赖性,以及开发顺序的合理性来考虑,把前台功能分为了 无需登录 即可使用的功能,和需要登录 才能访问的功能。 建立在前一步前台-首页的基础之上,开始进行一系列的无需登录功能开发。
    1.2.2.11 前台需要登录最后是需要登录的前台功能。 这部分功能基本上都是和购物相关的。 因此,一开始先把购物流程 单独拿出来捋清楚,其中还特别注明了购物流程环节与表关系,这样能够更好的建立对前端购物功能的理解。随着这部分功能的开发,就会进入订单生成部分,在此之前,先准备了一个 订单状态图,在理解了这个图之后,可以更好的进行订单相关功能的开发。
    1.2.2.12 总结最后总结整个项目的项目结构,都实现了哪些典型场景,运用了哪些设计模式,把学习到的知识都沉淀下来,转换,消化,吸收为自己的技能。
    二、需求分析2.1 概述以下需求都是基于模仿天猫整站整理出来的,主要分为3类:
    2.1.1 前端展示在前端页面上显示数据库中的数据,如首页,产品页,购物车,分类页面等等。
    2.1.2 前端交互这里的交互指的是通过POST,GET等http协议,与服务端进行同步或者异步数据交互。 比如购买,购物车,生成订单,登录等等功能。
    2.1.3 后台功能比如分类管理,分类属性管理,产品管理,产品图片管理,用户管理,订单管理等等。
    2.2 前台展示2.2.1 首页
    步骤 1 : 先看完整页面效果
    步骤 2 : 在横向导航栏上提供4个分类连接
    步骤 3 : 在纵向导航栏上提供全部17个分类连接
    步骤 4 : 当鼠标移动到某一个纵向分类连接的时候,显示这个分类下的推荐商品
    步骤 5 : 按照每种分类显示5个商品的方式,显示所有17种分类

    2.2.2 产品页
    步骤 1 : 显示分辨率为950x100的当前商品对应的分类图片
    步骤 2 : 显示本商品的5个单独图片
    步骤 3 : 商品的基本信息,如标题,小标题,价格,销量,评价数量,库存等
    步骤 4 : 商品详情
    步骤 5 : 评价信息
    步骤 6 : 5张商品详细图片

    2.2.3 分类页
    步骤 1 : 显示分辨率为950x100的当前分类图片
    步骤 2 : 显示本分类下的所有产品

    2.2.4 搜索结果页
    步骤 1 :显示满足查询条件的商品
    2.2.5 购物车查看页
    步骤 1 :在购物车中显示订单项
    2.2.6 结算页
    步骤 1 :在结算页面显示被选中的订单项
    2.2.7 确认支付页
    步骤 1 :确认支付页面显示本次订单的金额总数
    2.2.8 支付成功页
    步骤 1 :付款成功时,显示本次付款金额
    2.2.9 我的订单页
    步骤 1 :显示所有订单,以及对应的订单项
    2.2.10 确认收货页
    步骤 1 : 显示订单项内容
    步骤 2 : 显示订单信息,收货人地址等

    2.2.11 评价页
    步骤 1 : 显示要评价的商品信息,商品当前的总评价数
    步骤 2 : 评价成功后,显示当前商品所有的评价信息

    2.2.12 页头信息展示
    步骤 1 : 未登录状态
    步骤 2 : 已登录状态

    2.3 前台交互2.3.1 分类页排序
    步骤 1 : 按照综合,人气,新品,销量,价格排序
    步骤 2 : 进行价格筛选,这个不算,这个是做在浏览器端的,并不是和服务器端的交互

    2.3.2 立即购买
    步骤 1 : 在产品页,未登录状态时候,点击立即购买
    步骤 2 : 在产品页,如果已经登录,点击购买

    2.3.3 加入购物车
    步骤 1 : 在未登录状态,点击加入购物车
    步骤 2 : 在已登录状态,点击加入购物车

    2.3.4 调整订单项数量
    步骤 1 :在购物车页面,调整订单项数量
    2.3.5 删除订单项
    步骤 1 :在购物车页面,删除订单项
    2.3.6 生成订单
    步骤 1 :在结算页面,提交订单
    2.3.7 订单页功能
    步骤 1 :我的订单页面:订单页面上有3个按钮,付款,确认收货和评价,这些按钮都没有提交数据到服务端,而是提交到下一个页面的二次操作,才提交数据到服务端的。
    2.3.8 确认付款点击确认支付,提交本信息到服务端,服务端修改订单中的支付日期
    2.3.9 确认收货确认收货页面,点击确认支付,提交数据到服务端,并且修改订单中的确认收货日期
    2.3.10 提交评价信息提交评价信息到服务端
    2.3.11 登录输入正确账号密码,登录成功后跳转到首页,失败提示错误信息
    2.3.12 注册
    步骤 1 : 注册页面
    2.3.13 退出退出登录
    2.3.14 搜索提交关键字到服务端,服务端查询数据库,并返回匹配的产品
    2.3.15 前台需求列表2.4 后台管理2.4.1 分类管理
    步骤 1 : 分页查询
    步骤 2 : 新增分类
    步骤 3 : 编辑修改
    步骤 4 : 删除

    2.4.2 属性管理
    步骤 1 : 属性概念这里的属性,指的是产品属性。假定同一类产品,都有相同的属性
    步骤 2 : 分页查询
    步骤 3 : 新增属性
    步骤 4 : 编辑修改
    步骤 5 : 删除

    2.4.3 产品管理
    步骤 1 : 分页查询
    步骤 2 : 新增产品
    步骤 3 : 编辑修改
    步骤 4 : 删除

    2.4.4 产品图片管理
    步骤 1 : 产品图片概念一件产品,对应多条 单个图片一件产品,对应多条 详情图片
    步骤 2 : 产品图片管理

    2.4.5 产品属性管理
    步骤 1 : 产品属性值设置根据属性管理中的讲解,一种产品所具备的属性,在其对应的分类中进行了维护。那么,要修改产品的这些属性值,就在本页面进行。这里采用异步提交方式,编辑即修改,修改成功用绿色边框表示
    2.4.6 用户管理用户管理就提供了一个分页查询,做的比较简约,几个原因:

    用户是不能删除的
    用户信息的修改,应该交由前端由客户自己修改,比如密码,基本信息等
    用户的增加,是前端注册导致的,后台不负责用户的增加

    2.4.7 订单管理
    步骤 1 : 订单分页查询
    步骤 2 : 查看详情
    步骤 3 : 发货

    2.4.8 后台需求列表三、表结构设计3.1 概述在需求分析结束之后,接下来要做的不是马上开发功能,而是进行表结构的设计。
    3.2 数据库创建数据库:tmall。并且将数据库的编码设置为utf8,便于存放中文
    3.3 表与表关系3.3.1 表关系图
    3.3.2 表


    表名
    中文含义
    介绍




    Category
    分类表
    存放分类信息,如女装,平板电视,沙发等


    Property
    属性表
    存放属性信息,如颜色,重量,品牌,厂商,型号等


    Product
    产品表
    存放产品信息,如LED40EC平板电视机,海尔EC6005热水器


    PropertyValue
    属性值表
    存放属性值信息,如重量是900g,颜色是粉红色


    ProductImage
    产品图片表
    存放产品图片信息,如产品页显示的5个图片


    Review
    评论表
    存放评论信息,如买回来的蜡烛很好用,么么哒


    User
    用户表
    存放用户信息,如斩手狗,千手小粉红


    Order
    订单表
    存放订单信息,包括邮寄地址,电话号码等信息


    OrderItem
    订单项表
    存放订单项信息,包括购买产品种类,数量等



    3.3.3 表关系从最上面的表关系图中可以看到,有关系的表之间,都是一对多关系(反过来就是多对一关系),并没有一对一关系,和多对多关系。
    3.4 建表sql语句3.4.1 建表顺序在建表过程中,会设置外键约束,所以表和表之间有依赖关系。 因此会先建立被外键指向的表,比如User,Category,然后再是其他表
    3.4.2 表的字段
    用户表user主键Id,name用户名,password登陆密码
    分类表category主键id,name分类名
    属性表property主键id,名称name,外键cid指向category的id
    产品表主键id, name产品名称,subTitle小标题,orignalPrice原始价格,promotePrice优惠价格,stock库存,createDate创建日期,外键cid指向category的id
    属性值表propertyvalue主键id,属性值value,外键ptid指向property的id,外键pid指向product的id
    产品图片表主键id,type图片文件,外键pid指向product的id
    评价表主键id,content评价内容,createDate创建日期,外键pid指向product的id,外键uid指向用户表的id
    订单表

    orderCode:订单号address:收货地址post: 邮编receiver: 收货人信息mobile: 手机号码userMessage: 用户备注信息createDate: 订单创建日期payDate: 支付日期deliveryDate: 发货日期confirmDate:确认收货日期status: 订单状态外键uid,指向用户表id字段
    订单项表

    外键pid,指向产品表id字段外键oid,指向订单表id字段外键uid,指向用户表id字段number字段表示购买数量

    四、实体类4.1 概述所谓的实体类,就是对于数据库中的表的互相映射的类。 这是一种ORM的设计思想,即一个对象,对应数据库里的一条记录
    4.2 所有实体类对于一对多的表,在“一”的类中添加“多”的类集合,在“多”的类中添加“一”的类。
    五.DAO类设计5.1 概述DAO是Data Access Object的缩写,这些类专门用于进行数据库访问的操作。

    首先讲解两个工具类,DBUtil和DateUtil,因为在DAO类中会用到这两个工具类
    接着按照依赖顺序,逐个讲解不同的DAO类以及其中的方法

    5.2 工具类
    DBUtil类初始化驱动,并返回数据库连接
    DateUtil用于实体类和数据库中日期格式的转换

    5.3 DAO类六.Service6.1 通常的设计流程作为J2EE web 应用,一般会按照如图所示的设计流程进行Servlet -> Service(业务类) -> DAO -> database当浏览器提交请求到tomcat web 服务器的时候,对应的servlet的doGet/doPost方法会被调用,接着在servlet中调用Service类,然后在Service类中调用DAO类,最后在DAO中访问数据库获取相应的数据。

    6.2 不使用Service的原因在本模仿天猫整站-J2ee 版本中,不使用Service这一层。 原因是在DAO进行了比较详细的设计,已经提供了很好的支持业务的方法。
    七.后台7.1 原型-后端7.1.1 概述本项目里的后端又不仅仅是CRUD维护管理页面,还有一些其他略复杂的功能,所以还是把这些原型界面都做出来。 后续开发功能的时候,就可以基于这些原型界面进行。
    7.1.2 分类管理
    7.1.3 属性管理
    7.1.4 产品管理
    7.1.5 产品图片管理
    7.1.6 产品属性管理
    7.1.7 用户管理
    7.1.8 订单管理
    7.2 后台-分类管理7.2.1 概述开发整站的顺序,通常来说还是按照依赖性来进行,前端需要的数据,都要先通过后台的功能维护在数据库中,才可以拿到。 所以,先进行后台功能的开发,然后再是前台功能的开发。
    后台在系统设计的时候,并不是简单的每个功能对应一个Servlet,而是使用了反射的技术,结合过滤器Filter进行了封装,使得开发配置以及维护成本降低了很多。
    7.2.2 静态资源接下来,解析这个可运行项目。 首先从最简单的静态资源开始。
    7.2.3 Filter配合Servlet步骤一:每种实体类,对应了一个Servlet,而不是对应了5个,这样首先从Servlet数量上来讲,就大大的减少了。原理流程图:

    假设访问路径是 http://127.0.0.1:8080/tmall/admin_category_list
    过滤器BackServletFilter进行拦截,判断访问的地址是否以/admin_开头
    如果是,那么做如下操作

    取出两个下划线之间的值 category取出最后一个下划线之后的值 list然后根据这个值,服务端跳转到categoryServlet,并且把list这个值传递过去
    categoryServlet 继承了BaseBackServlet,其service方法会被调用。 在service中,借助反射技术,根据传递过来的值 list,调用对应categoryServlet 中的方法list()
    这样就实现了当访问的路径是 admin_category_list的时候,就会调用categoryServlet.list()方法这样一个效果

    步骤二:代码讲解-BackServletFilter:

    首先在web.xml配置文件中,让所有的请求都会经过BackServletFilter<url-pattern>/*</url-pattern>
    还是假设访问的路径是:http://127.0.0.1:8080/tmall/admin_category_list
    在BackServletFilter 中通过request.getRequestURI()取出访问的uri: /tmall/admin_category_list
    然后截掉/tmall,得到路径/admin_category_list
    判断其是否以/admin开头
    如果是,那么就取出两个_之间的字符串,category,并且拼接成/categoryServlet,通过服务端跳转到/categoryServlet
    在跳转之前,还取出了list字符串,然后通过request.setAttribute的方式,借助服务端跳转,传递到categoryServlet里去

    步骤3:代码讲解-CategoryServlet和BaseBackServlet服务端跳转/categoryServlet就到了CategoryServlet这个类里

    首先CategoryServlet继承了BaseBackServlet,而BaseBackServlet又继承了HttpServlet
    服务端跳转过来之后,会访问CategoryServlet的doGet()或者doPost()方法
    在访问doGet()或者doPost()之前,会访问service()方法
    BaseBackServlet中重写了service() 方法,所以流程就进入到了service()中
    在service()方法中有三块内容

    第一块是获取分页信息第二块是根据反射访问对应的方法第三块是根据对应方法的返回值,进行服务端跳转、客户端跳转、或者直接输出字符串。
    第一块和第三块放在后面讲解,这里着重讲解第二块是根据反射访问对应的方法

    取到从BackServletFilter中request.setAttribute()传递过来的值 list根据这个值list,借助反射机制调用CategoryServlet类中的list()方法,这样就达到了CategoryServlet.list()方法被调用的效果

    7.2.4 JSP包含关系步骤一:分类查询对应的JSP文件分类查询对应的JSP文件是listCategory.jsp,用到了4个公共包含文件:

    <%@include file=”../include/admin/adminHeader.jsp”%>
    <%@include file=”../include/admin/adminNavigator.jsp”%>
    <%@include file=”../include/admin/adminPage.jsp”%>
    <%@include file=”../include/admin/adminFooter.jsp”%>

    步骤二:每个后台页面都在开始使用了adminHeader.jsp

    html5
    jsp指令
    引入JSTL
    引入js和css
    预先定义一些判断输入框的js函数
    对于删除链接,需要进行确认操作

    步骤三:adminNavigator.jsp导航部分,包括一张图片和4个链接
    7.2.5 查询步骤1:MVC设计思想根据 MVC设计模式的思想,做J2EE web应用,从MVC的角度来看,就是把不同的数据显示在不同的页面上。数据就是 模型 ( bean, dao )、页面就是 视图 ( jsp )、控制不同的模型显示在不同的视图上,这件事,就是由控制器来完成 ( servlet )。所以分类管理,从MVC的角度来看,就是把多条分类Category数据放在一个集合里, 让listCategory.jsp 这个视图去显示出来。
    步骤2:list()方法在list()方法里做的事情是,取出数据,并且交由jsp显示。

    通过categoryDAO取得数据集合 cs
    通过request.setAttribute 放在 “thecs” 这个key中,为后续服务端跳转到jsp之后使用
    return “admin/listCategory.jsp”;

    步骤3:服务端跳转list()方法跳转到jsp页面
    步骤4:listCategory.jsp作为视图,担当的角色是显示数据。所以关键就是从第44行开始,借助JSTL的c:forEach标签遍历从CategoryServlet的list() 的request.setAttribute(“thecs”, cs); 传递过来的分类集合。
    7.2.6 分页步骤1:page.javaPage这个类专门为分页提供必要信息。
    步骤2:获取分页参数Service方法获取网页上传递来的开始位置,以及每页需要显示的数量。如果传递数据过来,开始位置取0,每页显示的数量取默认值:5.
    步骤3:基于分页参数,获取数据通过反射调用list()方法,list调用DAO获取分页数据。
    步骤4: 为page对象设置总数在分页显示的时候,依据这个总数来判断一共有多少页面,最后一页是多少。
    7.2.7 增加步骤1:增加的部分是坐在查询结果页面的。步骤2:提交数据会导致add()方法被调用。步骤3:接收数据并处理:parseUpload方法获取文件流步骤4:ImageUtil工具类:转换文件格式为jpg,改变文件大小步骤5:中文问题,在过滤器中对提交的数据进行统一编码步骤6:客户端跳转,add()方法返回@admin_category_list
    7.2.8 删除步骤1:用于删除的超链,指向地址admin_category_delete,并且会传递当前分类对象的id过去。步骤2:在adminHeader.jsp中对所有的删除连接都进行了监听。步骤 3 : 删除调用CategoryServlet.delete()方法。
    7.2.9 编辑步骤1 : 编辑超链,用于编辑的超链,指向地址admin_category_edit,并且会传递当前分类对象的id过去。步骤2 : 调用CategoryServlet.edit()方法。步骤3:服务端跳转到editCategory.jsp,在editCategory.jsp页面里,获取由CategoryServlet.edit() 通过request传递过来的Category对象,获取name和id。
    7.2.10 修改步骤1:编辑页面提交数据。步骤2:CategoryServlet.update() 方法和CategoryServlet.add()方法的处理很类似,有所不同之处在于增加操作一定会提交图片,而修改不一定提交图片。
    7.3 后台-其他管理7.3.1概述后台的其他管理页面与分类管理用到的设计思路类似。
    7.3.2 属性管理7.3.3 产品管理7.3.4 产品图片管理7.3.5 产品属性管理7.3.6 用户管理7.3.7 订单管理八. 前台8.1 原型-前端8.1.1 概述在开发功能之前,都会先有原型界面。 通常原型界面的数据不是真实的,是临时写在页面上,为用户提供一个直观的界面感受的。
    关于前端的关注点,着重落在如何获取服务端的数据,显示在页面上,以及前端页面与服务端的同步/异步数据交互上。
    8.1.2 首页
    8.1.3 分类页
    8.1.4 产品页面
    8.1.5购物车页面
    8.1.6 我的订单页面
    8.1.7 结算页面
    8.1.8 查询结果页面
    8.1.9 支付页面
    8.1.10 支付成功页面
    8.1.11 确认收货页面
    8.1.12 收货成功页面
    8.1.13 评价页面
    8.1.14 登录页面
    8.2 前台-首页8.2.1 概述8.2.1.1 前台无需登录从前台模块之间的依赖性,以及开发顺序的合理性来考虑,把前台功能分为了 无需登录 即可使用的功能,和需要登录 才能访问的功能。 建立在前一步前台-首页的基础之上,开始进行一系列的无需登录功能开发。
    8.2.1.2 前台需要登录接着是需要登录的前台功能。 这部分功能基本上都是和购物相关的。 因此,一开始先把购物流程 单独拿出来捋清楚,其中还特别注明了购物流程环节与表关系,这样能够更好的建立对前端购物功能的理解。随着这部分功能的开发,就会进入订单生成部分,在此之前,先准备了一个 订单状态图,在理解了这个图之后,可以更好的进行订单相关功能的开发
    8.2.2 静态资源步骤1:图片资源Site目录,轮播图片,分类图片,产品图片
    步骤2:css,js
    8.2.3 Filter配合Servlet步骤1:ForeServletFilter与BackServletFilter相似,如果访问路径以/fore而不是以/foreServlet开头,就跳转到foreServlet。
    步骤2:ForeServlet和BaseForeServlet在ForeServlet类里,就提供了所有前端需要用到的业务方法。BaseForeServlet与BaseBackServlet相似,不过前台没有用到分页,所以service主要是根据反射调用ForeServlet的home()方法以及根据home()的返回值进行跳转。
    8.2.4 home方法步骤1:首页展示的数据

    在横向导航栏上提供4个分类连接
    在纵向导航栏上提供全部17个分类连接
    当鼠标移动到某一个纵向分类连接的时候,显示这个分类下的推荐商品
    按照每种分类显示5个商品的方式,显示所有17种分类

    步骤2:home方法获取所有分类,为分类填充产品,推荐产品。
    8.2.5 home.jsp步骤1:包含页面根据前台页面的特点,我们把home.jsp设计成如代码所示。

    header.jsp引入标准标签库,js,css,自定义javascript函数等
    top.jsp置顶导航
    search.jsp搜索栏
    homePage.jsp首页业务页面
    footer.jsp页脚

    8.2.6 homePage.jsp步骤1:homepage.jsp所包含的页面关系

    categoryAndCarousel.jsp,分类和轮播
    categoryMenu.jsp,竖状分类菜单productsAsideCategorys.jsp,竖状分类菜单右侧的推荐产品carousel.jsp,轮播。
    homepageCategoryProducts.jsp主题的17种分类以及每种分类对应的5个产品
    步骤2:categoryAndCarousel.jspcategoryAndcarousel.jsp 页面利用ForeServlet传递过来的数据,天猫国际几个字旁边显示4个分类超链,另外包含了其他3个页面:categoryMenu.jsp、productsAsideCategorys.jsp、carousel.jsp

    8.3 前台-无需登录8.3.1 概述我们把前台功能分为两部分:

    无需登录有一些功能,无需登录也可以使用的,比如登录,注册本身,分类页面,查询,产品页面等
    需要登录有一些功能,必须建立在已经登录的基础之上,比如购买,加入购物车,查看购物车,结算页面,订单页面等等。

    8.3.2 注册与首页的home.jsp相仿,register.jsp也包含了header.jsp,top.jsp,footer.jsp等公共页面。不同的是,没有使用首页的search.jsp,而是用的简单一点的 simpleSearch.jsp。
    8.3.3 登录与register.jsp相仿,login.jsp也包含了header.jsp,footer.jsp等公共页面。中间是登录业务页面loginPage.jsp
    8.3.4 退出清除session中的user
    8.3.5 产品页product()方法用来展示产品。productPage.jsp 又由3个页面组成

    imgAndInfo.jsp:单个图片和基本信息
    productReview.jsp:评价信息
    productDetail.jsp:详情图片

    8.3.6 模态登录在未登录状态,点击购买或者加入购物车就会弹出这个模态对话框,在这个模态对话框上可以进行登录操作.
    立即购买和加入购物车这两个按钮的监听是放在imgAndInfo.jsp页面中这两个按钮都会通过JQuery的.get方法,用异步ajax的方式访问forecheckLogin,获取当前是否登录状态。如果返回的不是”success” 即表明是未登录状态,那么就会打开登录的模态窗口。
    模态窗口modal.jsp被footer.jsp所包含。
    8.3.7 分类页步骤1:5个Comparator比较器分类这个页面有排序功能,所以ForeServlet之前,先准备5个Comparator比较器:

    ProductAllComparator 综合比较器,把 销量*评价 高的放前面
    ProductReviewComparator 人气比较器,把 评价数量多的放前面
    ProductDateComparator 新品比较器,把 创建日期晚的放前面
    ProductSaleCountComparator 销量比较器,把 销量高的放前面
    ProductPriceComparator 价格比较器,把 价格低的放前面

    步骤2:ForeServlet.category()根据cid获取分类c,为c填充产品,为产品填充销量和评价。获取参数sort,进行排序。
    步骤3:categoryPage.jspcategoryPage.jsp 里有3个内容:

    显示当前分类图片
    <img src="img/category/${c.id}.jpg">排序条 sortBar.jsp
    产品列表 productsByCategory.jsp

    步骤4:sortBar.jspsortBar.jsp即排序条,作用如下:

    根据sort参数判断那个排序按钮高亮
    每个排序按钮提交到本页面,即/forecategory,并带上参数sort

    步骤5:productsByCategory.jspproductsByCategory.jsp显示当前分类下的所有产品,通过forEach遍历c.products集合里的每个产品,并把产品标题,价格,图片,评价数,成交数打印出来。categorycount是用于测试的,在访问地址的时候加这个参数可以控制显示的产品数量。
    8.3.8 搜索Search()方法进行模糊查询,将结果返回给jsp,最终在productBySearch.jsp页面中显示出来。
    8.4 前台-需要登录8.4.1 购物流程步骤1:购买的业务流程

    登录

    访问产品页
    立即购买

    进入结算页面

    加入购物车

    查看购物车

    选中购物车中的商品

    又到了第4步的结算页面
    在结算页面生成订单
    付款

    确认收货
    评价

    步骤2:购物流程环节与表观系围绕购物流程最重要的两个表是OrderItem 和 Order表,关于OrderItem的业务行为:

    立即购买 —— 新增 OrderItem
    加入购物车 —— 新增 OrderItem
    查看购物车 —— 显示未和Order关联的OrderItem
    选中购物车中的商品 —— 选中OrderItem
    结算页面 —— 显示选中的OrderItem


    生成订单 —— 新增Order
    付款 —— 修改Order状态
    我的订单 —— 显示Order
    确认收货 —— 修改Order状态

    8.4.2 立即购买步骤1:buyone()

    获取p和user
    增加订单项OrderItem或调整数量
    跳转到结算页面/forebuy

    8.4.3 结算页面步骤1:buy()

    getParamValues获取多个oiid
    根据oiid将订单项放入集合ois中
    计算ois的价格总数total
    ois放入session,total放入request
    服务端跳转到buy.jsp

    步骤2:buyPage.jsp

    遍历出订单项集合ois中的订单数据,从立即购买跳转到结算页面只会有一件产品。
    显示总金额
    提交订单项到订单

    8.4.4 加入购物车步骤1:登录之后,点击加入购物车,会使用Ajax提交数据到addCart()
    步骤2:addCart()和buyone()一样:

    获取pid,num
    从session中获取user
    新增订单项或只增加数量

    8.4.5 查看购物车页面步骤1:cart()

    获取当前用户
    获取用户的ois
    跳转到cart.jsp

    8.4.6 登录状态Filter准备一个过滤器,当访问那些需要登录才能做的页面的时候,进行是否登录的判断,如果不通过,那么就跳转到login.jsp页面去,提示用户登录。新建过滤器ForeAuthFilter,

    不需要登陆的页面注册,登录,产品,首页,分类,查询
    需要登陆的页面购买行为,加入购物车,查看购物车,查看订单

    8.4.7 购物车页面操作步骤1.调整订单数量,通过ajax访问/forechangOrderItem

    判断用户是否登录
    获取pid和number
    遍历OrderItem
    根据pid找到OrderItem,更新OrderItem
    返回success

    步骤2.删除订单项,通过ajax访问/foredeleteOrderItem

    判断用户是否登录
    获取oiid
    删除oiid对应的OrderItem数据
    返回字符串”success”

    8.4.8 订单状态图

    首先是创建订单,刚创建好之后,订单处于waitPay 待付款状态
    接着是付款,付款后,订单处于waitDelivery 待发货状态
    前两部都是前台用户操作导致的,接下来需要到后台做发货操作,发货后,订单处于waitConfirm 待确认收货状态
    接着又是前台用户进行确认收货操作,操作之后,订单处于waitReview 待评价状态
    最后进行评价,评价之后,订单处于finish 完成状态

    比较特殊的是,无论当前订单处于哪个状态,都可以进行删除操作。 像订单这样极其重要的业务数据,实际上是不运行真正从数据库中删除掉的,而是把状态标记为删除,以表示其被删掉了,所以在删除之后,订单处于 delete 已删除状态
    8.4.9 生成订单步骤1.提交订单调用createOrder()方法

    获取参数创建订单对象
    更新订单项
    跳转到确认支付页forealipay,并带上id和总金额

    步骤2:确认支付页显示总金额,支付后跳转到forepayed页面,带上id和总金额
    步骤3:支付成功页显示订单的基本信息
    8.4.10 我的订单页bought方法获取user中不是delete状态的订单集合osbought.jsp显示订单的日期、金额等信息,显示每个订单项对应的产品
    8.4.11 我的订单操作步骤1:在我的订单页面,根据订单的不同状态,可以做出如下不同的操作:

    付款 —— 已经生成,但是未付款
    确认收货 —— 通过后台发货后
    评价 —— 确认收货后, 进行评价
    删除 —— 任意状态下

    步骤2:确认收货/foreconfirmPay

    为订单对象o填充订单项,
    confirmPay.jsp显示订单的创建的时间等信息

    步骤3:确认收货成功/foreorderConfirmed

    修改订单o的状态为等待评价,修改其确认支付时间
    更新到数据库
    orderConfirmPage.jsp显示成功信息

    步骤4:评价
    步骤5:删除/foredeleteOrder

    修改状态,更新
    返回字符串success
    boughtPage.jsp的js代码隐藏当前订单

    8.4.12 评价产品步骤1:评价产品页面/foreview

    为订单o填充订单项
    获取第一个订单项的产品,显示其图片
    获取这个产品的评价集合
    为产品设置数量和销量
    把产品,订单和评价放在request上
    在reviewPage.jsp中显示产品图片,产品标题,价格,产品销量,产品评价数量,以及订单信息等。 同时还显示出了该产品所有的评价,但是默认是隐藏的

    步骤2:提交评价/foredoreview

    获取订单o,修改状态,更新到数据库
    获取产品对象p,获取参数content(评价信息),对评价信息进行转义
    获取当前用户,获取评价对象review
    为review设置评价信息等,提交到数据库
    跳转到/foreview:参数showonly=true,显示评价信息

    九.总结9.1 项目总结9.1.1 项目结构
    项目名称 tmall
    ava源代码包结构

    tmall.bean 实体类tmall.comparator 比较器tmall.dao DAO类tmall.filter 过滤器tmall.servlet servlettmall.test 测试类tmall.util 工具类
    web目录

    css css文件img 图片资源js文件admin 后台管理用到的jsp文件include 被包含的jsp文件

    9.1.2 典型场景
    购物车
    订单状态流转
    CRUD
    分页
    一类产品多属性配置
    一款产品多图片维护
    产品展示
    搜索查询
    登录、注册
    登录验证

    9.1.3 设计模式
    MVCMVC设计模式贯穿于整个后台与前台功能开发始末
    Filter+Servlet+反射采用Filter+Servlet+反射的设计模式,把原本后台需要20多个Servlet的经典Servlet设计方式,精简到了7个。把原本前台需要20多个Servlet的经典Servlet设计方式,精简到了2个。web.xml的配置文件也大大减少,降低了开发和维护的工作量,减少了出错的几率。
    统一的分页查询简化开发所有的后台都使用同一个分页机制,仅仅需要一份简化的adminPage.jsp即满足了各种分页功能的需求,简化了开发,提升了开发速度。
    模块化JSP设计从大的JSP文件中,通过JSP包含关系抽象出多个公共文件,并把业务JSP按照功能,设计为多个小的JSP文件,便于维护和理解

    9.2 改进练习还有些功能可以继续完善。

    后台管理员登陆模块
    产品图片排序
    前台分类下显示产品,提供分页功能

    等等
    2 评论 5 下载 2019-07-16 18:06:17 下载需要20点积分
  • 基于Java Web的投票管理系统

    摘 要相较于传统投票方式,在线投票是任何一-次商演(时间短、影响范围小)、电视(投入大,效果不明显)或者户外广告(不能快速吸引消费者眼球)在投入产出效率上都难以企及的。在线投票能够迅速提升活动商家的广告价值,降低商家广告成本,提高知名度以及美誉度。网络投票的主要目的就是人群放大:通过网络投票,可以吸引大量的选手及相关亲友的关注,通过以往的数据统计,一名选手参 与投票,会带动60人参与。这样可以最大程度的向客户展现实力,扩大社会影响力。
    系统分为前台和后台两部分,前台主要是对普通用户开放。普通用户将实现匿名投票操作:后台主要作用是管理员实现登录、投票管理、用户管理等操作。依据前台和后台的不同权限需求,在线投票系统主要分为普通用户和管理员两个功能模块。
    普通用户模块将实现用户登录、用户投票以及查看投票结果等功能。管理员模块将实现管理员登录、发布新投票、查看所有投票、及用户管理等功能。
    关键词:网上投票、JSP、MYSQL
    1 概述随着科技的飞速发展,计算机已经广泛的应用于各个领域之中,而且日趋普及。在计算机应用中很重要的一部分就是编程语言,编程语言的出现打开了计算机应用的新篇章。在这些编程语言中JSP占有着重要的地位,JSP 拥有Java编程语言“一-次编写,各处运行”的特点口。在当今的网络应用中JSP无处不在,在线投票系统就是JSP功能强大的-一个最好的例证。
    在线投票系统有很多传统投票方式不可比拟的优势。首先,它可以在很短的时间内,通过互联网将不同时间不同地域的用户投票组合到一起,并进行结果反馈,这是传统的投票方法完全做不到的;其次,在线投票系统的效率要比以往的传统投票方法高很多,在这个寸时如寸金的年代,在线投票系统不但省去了投票与计票环节的人力成本,还可以节省很多时间以用作处理其他更重要的事情:综上所述,在线投票系统有着快捷、经济、方便、省时省力等诸多优点都注定它将是未来投票方式的主流。
    2 课程设计任务及要求2.1 任务设计一个投票系统,实现学生对教师的匿名投票。有管理用户,实现对整个系统的管理。
    2.2 要求用户分为管理员用户和普通用户。
    普通用户提供以下功能:系统首页上显示所有投票选项的列表,显示当前登录用户并提供注销功能,用户可以通过选中某个选项并点击“投票”按钮进行投票操作。用户点击后可在当前一页面上看到各个投票选项目前的投票情况,主要包括各选项所得的票数,并且以柱形显示各选项的得票率,可以让用户从直观上看到各项的得票情况。
    管理员用户提供以下功能:显示当前登录用户并提供注销功能,提供系统管理实现用户的增删查改及重新投票等功能,还能显示用户列表及投票情况表。开发的系统数据库设计要合理,能够实现设计的全部功能,能够运行演示。能够体一个软件的基本功能。
    3 需求分析3.1 功能需求用户能够正常的登录及注销,每个用户在每一次投票中只能匿名投票一次。管理员能够新建账号、删除账号、修改账号及初始话投票。在管理员页面显示投票情况及用户情况等系统详情。
    整个系统要进行session检查,防止非法用户访问受限页面。
    3.2 硬件需求运行windows的硬件平台并装有如下软件:

    Jdk1.8
    tomcat6.0
    eclipse
    sql server 2008

    4 概要设计4.1 总体模块设计4.1.1 普通用户模块
    登录:使用普通用户账号登录到投票界面
    投票:选择投票对象并进行投票
    注销:清空用户session退回到欢迎界面

    其各部分关系图如图1所示。

    4.1.2 管理员用户模块
    登录:使用管理员账号登录到后台管理界面
    注销:清空用户session退回到欢迎界面
    用户管理:管理员可以增加、删除、修改用户账号,不能删除当前登录用户
    初始化投票:管理员可以初始化投票系统,开启下一次投票
    查看所有用户:显示系统中已存在的用户账号及其投票情况
    查看得票数:显示当前的投票情况

    其各部分关系如图2所示。

    4.2 开发工具简介在在线投票系统的设计发开过程中主要用了JSP技术,其中用到的工具有:JDK1.8、Eclipse、MySQL、Tomcat 等。
    4.2.1 JSP简介JSP技术有点类似ASP技术,它是在传统的网页HTML文件中插入Java程序段和JSP,从而形成JSP文件”。JSP技术使用Java编程语言编写类XML的tags和scriptlets,来封装产生动态网页的处理逻辑。在线投票系统用JSP将网页逻辑与网页设计和显示分离,支持可重用的基于组件的设计,使本系统基于Web的应用程序的开发变得迅速和容易。

    一次编写,到处运行。在这一一点上Java比PHP更出色,除了系统之外,代码不用做任何更改
    系统的多平台支持。基本上可以在所有平台上的任意环境中开发,在任意环境中进行系统部署,在任意环境中扩展。相比ASP/PHP的局限性是现而易见的
    强大的可伸缩性。从只有一个小的Jar文件就可以运行Servlet/JSP,到由多台服务器进行集群和负载均衡,到多台Application进行事务处理,消处理,-台服务器到无数台服务器,Java 显示了一个巨大的生命力
    多样化和功能强大的开发工具支持。这一点与ASP很像,Java已经有了许多非常优秀的开发工具,而且许多可以免费得到,并且其中许多已经可以顺利的运行于多种平台之下

    4.2.2 SQL server简介SQL Server系列软件是Microsoft 公司推出的关系型数据库管理系统。2008年10月,SQL Server 2008简体中文版在中国正式上市,SQL Server 2008 版本可以将结构化、半结构化和非结构化文档的数据直接存储到数据库中。可以对数据进行查询、搜索、同步、报告和分析之类的操作。数据可以存储在各种设备上,从数据中心最大的服务器一直到桌面计算机和移动设备,它都可以控制数据而不用管数据存储在哪里。
    此外,SQL Server 2008 允许使用 Microsoft .NET 和Visual Studio开发的自定义应用程序中使用数据,在面向服务的架构(SOA)和通过 Microsoft BizTalk Server 进行的业务流程中使用数据。信息工作人员可以通过日常使用的工具直接访问数据。
    4.3 数据库设计数据库设计是软件开发中的重要环节,是对系统数据全面的、详细的分析。数据库设计的好坏直接关系到整个项目设计的效率的高低,关系到设计的稳定性。根据在线投票系统不同模块之间的联系和前期的设计目的与需求,设计了三个不同的数据表,它们分别是用户表、投票选项表和投票主题表。
    4.3.1 用户表(T_USER)用户表包括所有用户的各种信息,如账户、密码等详细数据并规定了每个字段的类型,如表1所示。



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




    ACCOUNT
    VARCHAR
    40

    账号


    PASSWARD
    VARCHAR
    40

    密码


    UNAME
    VARCHAR
    40

    用户姓名


    ADMIN
    BIT
    1

    管理员标识


    TICKET
    INT
    255

    票数



    4.3.2 投票表(T_VOTE)投票表包括教师编号、教师姓名和得票数。如表2所示。



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




    TEACHERNO
    VARCHER
    40

    教师编号


    TEACHERNAME
    VARCHER
    40

    教师姓名


    VOTE
    INT
    255

    得票数



    5 开发与实现5.1 程序模块实现5.1.1 用户登录模块关键代码<% request.setCharacterEncoding("gb2312"); String account = request.getParameter("account"); String password = request.getParameter("password"); UserDao udao = new UserDao(); User user = udao.getUserByAccount(account); if(user == null||!user.getPassword().equals(password)){ %> <br><br><br><br><br><br> 登录失败,<a href="loginForm.jsp">返回登录页面</a> <% } else if(user.getAdmin()==true){ session.setAttribute("user", user); response.sendRedirect("admin.jsp"); } else{ session.setAttribute("user", user); response.sendRedirect("display.jsp"); }%>
    5.1.2 投票模块关键代码<% String account=user.getAccount(); String[]teacherno =request.getParameterValues("teacherno"); VoteDao vdao = new VoteDao(); UserDao udao = new UserDao(); int ticket= udao.ticket(account); if(ticket>0){ if(teacherno!=null){ vdao.updateVotes(teacherno); vdao.updateTictet(account); } response.sendRedirect("display.jsp"); } else{ response.sendRedirect("noTicket.jsp"); } %>
    5.1.3 新建用户模块关键代码<% request.setCharacterEncoding("gb2312"); String account = request.getParameter("account"); String password = request.getParameter("password"); String uname = request.getParameter("uname"); String admin =request.getParameter("admin"); UserDao udao = new UserDao(); User user2=udao.getUserByAccount(account); if(user2!=null){ %> <jsp:forward page="changeError2.jsp"></jsp:forward> <% } udao.adduser(account, password, uname, admin); %> <br><br><br><br><br><br> <p align="center">创建用户成功!<br> <a href="admin.jsp">返回</a></p>
    5.1.4 删除用户模块关键代码<% request.setCharacterEncoding("gb2312"); String account = request.getParameter("account"); String acc = user.getAccount(); if(acc.equals(account)){ %> <jsp:forward page="changeError3.jsp"></jsp:forward> <% } UserDao udao = new UserDao(); User user2=udao.getUserByAccount(account); if(user2==null){ %> <jsp:forward page="changeError.jsp"></jsp:forward> <% } udao.deluser(account); %> <br><br><br><br><br><br> <p align="center">删除用户成功!<br> <a href="admin.jsp">返回</a></p>
    5.1.5 修改用户模块关键代码<% request.setCharacterEncoding("gb2312"); String account = request.getParameter("account"); String password = request.getParameter("password"); String uname = request.getParameter("uname"); String admin =request.getParameter("admin"); UserDao udao = new UserDao(); User user2=udao.getUserByAccount(account); if(user2==null){ %> <jsp:forward page="changeError.jsp"></jsp:forward> <% } udao.changeuser(account, password, uname, admin); %> <br><br><br><br><br><br> <p align="center">修改用户成功!<br> <a href="admin.jsp">返回管理页面</a></p>
    5.1.6 初始化投票模块关键代码public void initVote() throws Exception{ initConnection(); String sql="UPDATE T_VOTE SET VOTE = 0"; PreparedStatement ps = conn.prepareStatement(sql); ps.executeUpdate(); closeConnection();}public void initTicket() throws Exception{ initConnection(); String sql="UPDATE T_USER SET TICKET = 1"; PreparedStatement ps = conn.prepareStatement(sql); ps.executeUpdate(); closeConnection();}
    5.1.7 注销登录模块关键代码<% session.invalidate(); response.sendRedirect("loginForm.jsp");%>
    5.1.8 非法用户的session检查管理员权限
    <% User user =(User)session.getAttribute("user");if(session.getAttribute("user")==null||user.getAdmin()==false { %> <jsp:forward page="loginError.jsp"></jsp:forward> <% } %>
    普通用户权限
    <%5.1.8非法用户的session检查管理员权限: User user =(User)session.getAttribute("user"); if(user==null){ %> <jsp:forward page="loginError.jsp"></jsp:forward> <% } %>
    5.1.9 防刷票的实现public int ticket(String account) throws Exception{ initConnection(); String sql ="SELECT TICKET FROM T_USER WHERE ACCOUNT= ? "; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, account); ResultSet rs = ps.executeQuery(); rs.next(); int ticket =rs.getInt("TICKET"); if(ticket==0) { closeConnection(); return 0; } else { closeConnection(); return 1; } }
    5.2 数据库与操作设计开发5.2.1 连接数据库public void initConnection() throws Exception { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");conn=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Vote;user=root;password=123456789"); }
    5.2.2 数据库操作设计public User getUserByAccount(String account) throws Exception{ User use = null; initConnection(); String sql="SELECT ACCOUNT,PASSWORD,UNAME,ADMIN FROM T_USER WHERE ACCOUNT = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, account); ResultSet rs =ps.executeQuery(); if(rs.next()) { use = new User(); use.setAccount(rs.getString("ACCOUNT")); use.setPassword(rs.getString("PASSWORD")); use.setUname(rs.getString("UNAME")); use.setAdmin(rs.getBoolean("ADMIN")); } closeConnection(); return use; }
    6 测试与部署6.1 运行环境
    平台:Windows10
    开发环境:JDK 1.8、 Eclipse4.9、 Tomcat6.0、 SQL server 2008

    6.2 功能测试6.2.1 防止非法访问功能
    功能描述:未登录的用户不能访问受限页面,已登录的普通用户不能访问管理员权限页面
    目的:防止未授权访问,保证安全性
    前提条件:无
    输入:浏览器地址栏直接输入页面地址
    输出:身份验证通过,转到要访问页面;身份验证不通过,转到拒绝访问页面
    是否实现:实现

    6.2.2 初始化投票功能
    功能描述:管理员清空当前投票
    目的:初始化投票者的票数及被投票者的得票数
    前提条件:登录到管理员页面
    输入:点击初始化投票链接
    输出:初始化成功转到管理页面
    是否实现:实现

    6.2.3 登录功能
    功能描述:输入用户名和密码登陆到系统,不同用户登录到不同界面
    目的:检验数据判断能否登陆
    前提条件:进入登陆界面
    输入:用户名和密码
    输出:数据判断成功,普通用户登陆到投票界面,管理员用户登录到后
    一台管理界面:数据判断失败,转到失败页面
    是否实现:实现

    6.2.4 注销登录功能
    功能描述:已登录到系统的用户可以通过注销来退出系统
    目的:用户退出时,清空用户session
    前提条件:用户已登录
    输入:点击注销链接
    输出:注销成功转到初始欢迎页面
    是否实现:实现

    6.2.5 投票功能
    功能描述:给相应的所选教师投票
    目的:实现数据库中相应教师得票数的数据更新
    前提条件:成功登录到投票界面
    输入:勾选教师,点击投票
    输出:相应老师的得票数加1
    是否实现:实现

    6.2.6 添加用户功能
    功能描述:管理员添加用户账号到系统中
    目的:在数据库用户表中添加用户账号信息
    前提条件:成功登录后台管理页面
    输入:新的用户数据
    输出:创建用户成功,输出成功提示转到管理界面;创建用户失败,输出相应失败提示转到管理界面
    是否实现:实现

    6.2.7 删除用户功能
    功能描述:管理员从系统中删除用户账号
    目的:在数据库用户表中删除用户账号信息
    前提条件:成功登录到后台管理页面
    输入:要删除用户的账号
    输出:删除用户成功,输出成功提示转到管理界面;删除用户失败,输出相应提示转到管理界面
    是否实现:实现

    6.2.8 修改用户功能
    功能描述:管理员修改系统中已存在的用户信息
    目的:在数据库中修改相应的用户信息
    前提条件:登录到后台管理页面
    输入:要修改的账号及新的用户信息
    输出:修改成功,输出成功提示转到管理界面;修改失败输出相应失败提示转到管理界面
    是否实现:实现-

    6.2.9 显示系统用户功能
    功能描述:在管理页面显示当前系统中已存在的账号及是信息
    目的:显示账号,账号用户及是否投票
    前提条件:登录到后台管理页面
    输入:无
    输出:系统中的账号信息
    是否实现:实现

    6.2.10 显示得票数功能
    功能描述:在管理页面及投票页面显示当前的得票情况
    目的:显示各教师的得票数,并以相应比例长的的矩形显示
    前提条件:登录到系统中
    输入:无
    输出:各教师的得票情况
    是否实现:实现

    7 结论分析为期数天的jsp集中上机课程设计让我受益匪浅。和上学期数据库课程设计不同,这次要求我们每个人都要做,主要是考查我们jsp 动手实践能力。这次的课程设计让我再一次翻起了sql课本,已经有好些知识忘了,借此机会刚好复习了一遍,由于这次时间安排的比较紧,赶在了我们期末考试这一特殊时期,所以我选择做个功能齐全的投票系统,其实也算不上齐全,但是也学了不少东西。特别是在具体功能的设计上遇到很多问题,但是经过我上网搜索资料以及寻找同学帮助,这些问题都迎刃而解了。但是不足的时还有很多想做的功能由于时间的关系没有实现,例如动态管理投票对象、更改用户可投票数、非匿名投票等等。
    经过了数天的学习研究,终于完成了该课程设计的架构到实现。从开始选定题到系统的规划实现,再到报告的完成,这次的课程设计是对于我们是一个很好的锻炼,通过本次设计,我基本明确了一个基于jsp应用系统从设计到开发的大致流程和重点关注的方向,同时对JSP, SQL语句数据库关系等都有了基本的掌握和应用能力。
    通过这次课程设计,我再一次感受到jsp的魅力,自己设计的不是特别完美,但毕竟做成果,心里很高兴,我们对学习jsp的信心也增强不少。
    参考文献[1] 郭克华、奎晓燕. Java Web程序设计 清华大学出版社2011
    [2] 明日科技 HTML5从入门到精通 清华大学出版社2012
    [3] 何玉洁 数据库基础与实践技术(SQL Server 2008) 机械工业出版社2018
    0 评论 13 下载 2019-07-25 11:35:59 下载需要5点积分
显示 105 到 120 ,共 15 条
eject