开发记录_小型自选商场综合管理系统

来源:互联网 发布:windows bash如何用 编辑:程序博客网 时间:2024/05/21 10:09

前言

这是《数据挖掘》课程的作业,虽然叫做数据挖掘,前半学期还是在学数据库的知识。这次大作业算是一次检验吧。其实我觉得,数据库的部分并不多,难到我的都是呈现部分…可能是资历还太浅,总觉得数据库保存数据就好了,无需主键外键级联什么的约束关系,具体的实现部分放在PHP中足够了。

这次最自豪的地方在于所有的工具仅限于Chrome浏览器和Sublime Text 2编辑器,没有用任何网页排版软件比如Dreamweaver。感谢Chrome,有了这个神器,配合Sublime Text 2 我才能迅速的修改并调试Javascript代码,具体的调试方法我决定另写一篇博客。

先来看看最终效果吧,已经搬上SAE了,相关的数据库连接什么的也改了改,提醒大家,在connect了之后要立刻mysql_select_db(),真心不能含糊...

链接地址:小型自选商场综合管理系统

最初做了一个版本的,用了表格排版,做了还没一半实在是觉得太丑,还不如之前的绩效考核系统,正巧在网上看到一个侧边栏动态效果,就把这个侧边栏拿下来,自定义了一下,在main里边加入自己的内容,做成了这个网站,用了div来排版,主体配色还是原来的侧边栏,新增加的配色尽量配合了原有的。

实现过程

HTML & CSS

这次全部采用了div排版,配合css设定样式,需要小幅修改的地方,用Chrome实时的修改调整,再把调整好的内容复制到代码里,这样就不用反复的在Sublime里边修改了。

Javascript

Javascript的部分我觉得写重复了好多,由于第一次应用AJAX技术,现学现卖,有些不确定的地方不太敢自作主张,还是利用了教程里的代码,这就使得代码重复的部分确实很多,每一个页面都需要AJAX技术和后台程序通讯,每一个页面的Javascript函数都是重复写的,虽然每个页面都有不同的需求和不同的显示格式,我还是觉得应该有一个很好的方法组织好这些代码。此刻我更加迫切的觉得应该认认真真的看看《代码整洁之道》了。

具体一点来说,有这么几个主要的部分:

全局快捷键

全局快捷键的设置是考虑到用户在输入商品编号、数量之后,再去点击按钮,使用起来不方便,所以想要加一个全局快捷键,当用户输入完成后,按下回车,即可调用对应的函数提交表单。

代码如下:

<script type="text/javascript">document.onkeydown=function() {  ss()  }function ss(){if(event.keyCode == 13){sendItem();}}</script>


其中sendItem()是被调用的函数,每当用户在网页上按下一个键,就会检查一次是否是回车,如果是,则调用函数。


网页的动态响应部分


收银台实时计算找零

因为考虑到找零的内容无需在后台完成,也不用存入数据库,因此完全可以在前台显示,并不做存储。在前台完成还有一个优点,运行速度不受网速的限制,立刻就能完成。

代码如下:

HTML部分:

<form><p class="math">收现:</p><input type="text" placeholder="请输入 现金" id="cash"  onkeyup="showResult(this.value)"/><br></br><p id="minus">—<span id="totalMoney"></span></p><br></br><div id="hr"><span></span></div><p id="equal">找零:<span id="result"></span></p><input type="button" name="add" class="button" id="deal" value="结账" onclick="finish()"/></form>


其中<span id=“totalMoney”></span>和<span id=“result”></span>是占位符,给它一个id,我们就能在Javascript里边对它的内容进行操作了。totalMoney是AJAX返回的当前总价,result是找零的结果。

<div id="hr"><span></span></div>


这个是减法运算式的那条横线,用了一个div附加上阴影,就有了一根线,再设定好宽度就好了。


Javascript部分:

function showResult (cash)//计算找零{if (cash.length == 0 || cash == 0)//如果{  document.getElementById("result").innerHTML = ""; return ;}var result = cash - document.getElementById("totalMoney").innerHTML;if (result<0){  document.getElementById("result").innerHTML = "不足";}else{  document.getElementById("result").innerHTML = result;}}


调整页面元素的内容和属性

这里的应用主要在表格的隐藏和显示,另一个应用在于利用占位符动态的填充信息。

表格的显示是考虑到,在默认的情况下,表格头不显示,当有查询结果的时候,显示表格头并在下边添加新的行,显示查询结果。主要的实现方法就是在HTML中设定这一部分的div属性为style="display:none;font-size: 18px”,当这个display更改为block的时候就会显示里边的内容。


HTML代码如下:

<div class="List" id="List" style="display:none;font-size: 18px"><table id="showList" class="showTable" cellspacing="5px" style="min-height: 40px;"><th>商品编码</th><th>商品名称</th><th>商品数量</th><th>订单时间</th><th>单项总计</th><th>收银员</th><tbody id="itemList"></tbody></table></div>


Javascript相关代码如下:

//显示列表(通过设置display属性)document.getElementById("List").style.display = ‘block';


动态生成表格添加新的行

这部分用于动态的生成新的行,用于收银台实时显示当前订单的所有项目。主要是将AJAX返回的数据格式化显示到表格里,这里主要用tbody作占位,给它id之后对它操作,以收银台为例,HTML的代码上边就有,

Javascript代码如下(截取相关部分):

//动态建立表格var newItem = afterSplit[1].split(",");var table = document.getElementById("itemList");var newRow = table.insertRow(table.rows.length);//通过获得当前行数把新的行插到最下边for (var i=0; i < newItem.length ;i++){newRow.insertCell(i).innerHTML= newItem[i];}


split是分词函数,它会把字符串用参数里的符号分割,将各部分返回为数组,可以多次分割。


AJAX发送和接收部分

AJAX真心是琢磨了一会儿的,但上手了之后又会感叹AJAX的牛X之处,利用原有的技术,进行挖掘,实现从未有过的功能,异步Javascript和XML..你值得拥有。


Javascript部分:

function sendItem(){var addDeal = 0;if(!document.getElementById("itemID").value){return ;}xmlHttp = GetXmlHttpObject();if (xmlHttp == null){alert("不好意思~你的浏览器不支持AJAX技术诶...");return ;}if(isfirst == 1){addDeal = 1;isfirst = 0;}var url = "../itemInsert.php";//定义要发送到服务器的 URL(文件名)url = url + "?addDeal=" + addDeal;url = url + "&itemID=" + document.getElementById("itemID").value;//把商品编号添加到这个 URLurl = url + "&itemNum=" + document.getElementById("itemNum").value;//把商品数量添加到 URLurl = url + "&sid=" + Math.random();//添加一个随机数,以防服务器使用缓存文件xmlHttp.onreadystatechange = responseItem;//调用 GetXmlHttpObject 函数来创建 XMLHTTP 对象,//并在事件被触发时告知该对象执行名为 stateChanged 的函数xmlHttp.open("GET", url, true);//用给定的 URL 来打开打开这个 XMLHTTP 对象xmlHttp.send(null);//向服务器发送 HTTP 请求clearInput();//清除输入框document.getElementById('itemID').focus();//重新定位焦点}//每当 XMLHTTP 对象的状态发生改变,则执行该函数。//在状态变成 4 (或 "complete")时,执行内容。function responseItem(){if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete"){var result = xmlHttp.responseText;if(result == "IDfail"){alert("您输入的 商品编号 有误,请重新输入");return ;}if(result == "Insertfail"){alert("数据库插入错误");return ;}if(result == "notEnough"){alert("货源不足");return ;}if(result == "updateFail"){alert("数据库更新错误");return ;}var afterSplit = result.split(";");document.getElementById("totalMoney").innerHTML = afterSplit[0];//显示列表(通过设置display属性)document.getElementById("List").style.display = 'block';//动态建立表格var newItem = afterSplit[1].split(",");var table = document.getElementById("itemList");var newRow = table.insertRow(table.rows.length);//通过获得当前行数把新的行插到最下边for (var i=0; i < newItem.length ;i++){newRow.insertCell(i).innerHTML= newItem[i];}}}


后台PHP部分:

<?php//----------------------------------------------//>>>>>>>>>>>>>>>>>收银台后台程序<<<<<<<<<<<<<<<//----------------------------------------------require_once "database.php";$itemID=$_GET["itemID"];$itemNum=$_GET["itemNum"];$addDeal=$_GET["addDeal"];$salesmanNo = 1;$con = initialise();$lastest = query("select dealID from ItemOut order by saleTime desc");//分辨是否新订单$lastest = mysql_fetch_array($lastest);if($lastest[0]){if($addDeal == 1){$dealID = $lastest[0] + 1;}else{$dealID = $lastest[0];}}else{$dealID = 1;}//检查库存并修改$storeNum = query("select itemNum from Item where itemID='".$itemID."'");$storeNum = mysql_fetch_array($storeNum);$result = $storeNum[0] - $itemNum;if($result >= 0){if(!query("update Item set itemNum=".$result." where itemID='".$itemID."'")){echo "updateFail";return ;}}else{echo "notEnough";return ;}$itemPrice = mysql_query("select itemPrice from Item where itemID='". $itemID ."'");$itemPrice = mysql_fetch_array($itemPrice);if($itemPrice[0]){$totalPrice = $itemPrice[0] * $itemNum;//检查insert语句//echo "insert into ItemOut (dealID,itemID,itemNum,totalPrice,saleTime) values (". $dealID .",'". $itemID ."',". $itemNum .",". $totalPrice .",'". date('Y-m-d') ."')";if(query("insert into ItemOut (dealID,itemID,itemNum,totalPrice,saleTime,salesmanNo) values (". $dealID .",'". $itemID ."',". $itemNum .",". $totalPrice .",'". date("Y-m-d H:i:s") ."',".$salesmanNo.")")){//如果添加成功了,先返回总价$sum = query("select sum(totalPrice) from ItemOut where dealID=".$dealID);$sum = mysql_fetch_array($sum);$response = $sum[0] .";";//然后返回新的商品信息//dealID对用户无意义$response = $response ."".  $itemID;//itemID$name = query("select itemName from Item where itemID=". $itemID);//取出商品名mysql_query('set names utf8');$name = mysql_fetch_array($name);$response = $response .",".  $name[0];//itemName$response = $response .",". $itemNum;//itemNum$response = $response .",". date("Y-m-d H:i:s");//saleTime$response = $response .",". $totalPrice;//totalPrice$name = query("select salesmanName from Employee where salesmanNo=". $salesmanNo);//取出商品名mysql_query('set names utf8');$name = mysql_fetch_array($name);$response = $response .",". $name[0];//salesmanNo$response = $response .";"   ;//每行的分割echo $response;}else{echo "Insertfail";}}elseecho "IDfail";?>



PHP & MySQL

PHP主要是当做后台的服务端,接收前端发来的内容,操作MySQL数据库,格式化返回的数据并返回给前端。

另外销售清单页面用php操作数据库直接生成了网页,这里没有用到新的技术。

后台程序的代码上边就有。

SQL语句还是用的很低级...没有用到join之类的。现在网站还很小,无所谓。将来网站如果访问量上去了,这样写SQL查询语句消耗的资源很多,如果要计费的话,成本会很高。

遇到的问题与解决办法

AJAX技术

AJAX技术因为以前没有接触过,这次现学现卖,遇到问题了还不知道解决起来还是挺费时间的。

发送和接收数据包遇到的问题

这里主要要注意的地方,在于前端Javascript调用response函数的时候,只有函数名没有括号,像这样:

xmlHttp.onreadystatechange = responseStore;

之前不知道,加了括号之后怎么都没法调用后边的函数,用Chrome查错之后才发现问题,在对比了N遍教程代码之后才发现…原来是多了一对括号。

编码解码的问题

 前端往后端发内容的时候用了GET方式,后端发回来一整个字符串,需要重新分割成各个部分,一开始想要用JSON编码,后来发现数据量很小,用字符串再分割也可以。具体的例子上边也有。

前端动态响应部分

动态响应部分主要是根据后台发来的数据,格式化之后添加到现有的网页里,主要是动态添加新的行。原本想要实现新的行添加到表头之后,始终无法实现,后来想想,HTML是静态的,已经生成的内容无法更改,是无法将新的行插入到最前边的,只能在后边添加。

订单号保存

这个问题一开始并没有尝试解决,而是留到最后才做的,最初的想法是在前端记录订单号,当点击“结账”之后,订单号自动增加1,订单号发送到后台存储,后来发现,前端的网页关闭再打开之后,就又回到1号订单了,会和之前的记录重复,这样计算总价的时候会有问题。

最后这一部分的实现结合了前端和后端。前端定义全局变量isFirst,初始值是1,增加一个判断,如果isFirst是1,则告诉后台,这是个新订单,同时将isFirst置0,这样第二次就不会进这一部分了,在结账按钮对应的函数里,把isFirst再次置1,这样就相当于,传递的数据负责告诉后台,这是不是一个新订单,如果是,则dealID加1,如果不是,则按照日期寻找最新的订单号,用这个订单号继续存储。

反思

总得来讲,这次的网站要比之前的绩效考核系统好看,有动画,按钮也好看一些,采用了CSS样式表描述网页。学了一些新的技术并且应用进去,学到了不少。

在运用SAE的时候试了试SVN,发现确实,版本控制是个应当学习的东西,有了这个还真方便…

之所以没有用jQuery是因为考虑到AJAX已经是个新技术了,jQuery需要学习的内容还很多,选择器什么的都和原本的操作不太一样,因此就没有学习这个库,不过听说这个库实现AJAX技术很方便,也找到了些例子,接下来有空的话要学习一下这个类库。

SQL语句还是太低端,效率很低,显得很没水平。

没有考虑到安全方面的问题,没有相关的处理函数,这个可以慢慢加进去。

近期项目预告

1.微信公众平台,已经将接口设置好了,用了SAE服务器,响应迅速,利用微信的例子代码实现了自动回复功能,目前在研究微信的API,研究其他网站的API,希望能添加一些功能进来。

2.iOS开发,目前在跟最新的斯坦福iOS教程,认真的做笔记,我想有空的时候把笔记搬到博客里来,让大家不看视频也能学到重点。

3.Alfred这个吧...搁着吧..


最主要的是下周四要检查操作系统大实验了……我还只做了一丁点…不幸福..

原创粉丝点击