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

前言

这是《数据挖掘》课程的作业,虽然叫做数据挖掘,前半学期还是在学数据库的知识。这次大作业算是一次检验吧。其实我觉得,数据库的部分并不多,难到我的都是呈现部分…可能是资历还太浅,总觉得数据库保存数据就好了,无需主键外键级联什么的约束关系,具体的实现部分放在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函数都是重复写的,虽然每个页面都有不同的需求和不同的显示格式,我还是觉得应该有一个很好的方法组织好这些代码。此刻我更加迫切的觉得应该认认真真的看看《代码整洁之道》了。

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

全局快捷键

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

代码如下:



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


网页的动态响应部分


收银台实时计算找零

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

代码如下:

HTML部分:

收现:





找零:



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



这个是减法运算式的那条横线,用了一个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代码如下:



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;//把商品编号添加到这个 URL
	url = url + "&itemNum=" + document.getElementById("itemNum").value;//把商品数量添加到 URL

	url = 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部分:

>>>>>>>>>>>>>>>>收银台后台程序<<<<<<<<<<<<<<<
//----------------------------------------------

	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";
		}
	}
	else
		echo "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这个吧...搁着吧..


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

你可能感兴趣的:(sql,php,Javascript,html)