标签:
目录
?
?
Ecshop
shopNC(代码部分加密)
国外:zencart,magento(麦金斗)
一般在外贸的公司,用zencart,magento用的多一些.
Magento是基于zendframework来开发的.
ecshop是上海商派网络科技有限公司(shopEx)旗下—B2C独立网店系统,适合企业及个人快速构建个性化网上商店。系统是基于php语言及mysql数据库架构开发的跨平台开源程序。
历史:
2006年6月,ecshop推出第一个版本1.0
2007年5月到6月,ecshop管理层将ecshop卖给康盛世纪。
2008年10月10日,ecshop系列软件(包括 ecshop,ecmall, maifou等),被上海商派网络科技有限公司(shopEx)整体收购。
2012年4月,发布ecshop v2.7.3 release 0411
官方网站:http://www.ecshop.com
?
?
?
?
?
?
使用的面向对象的函数式编程,使用自己简化的smarty
执行流程:
第一步:加载include/init.php文件,init.php文件中,又加载了很多的文件,对数据库和其他类进行初始化。
第二步:通过调用函数,从数据库中取出数据,执行assign()
?
第三步:$this->display();静态页面。
通过分析代码:可以理解成mvc软件架构。
c:控制器:网站根目录下面的一些php文件。
v:视图:网站根目录下面的 \themes\default里面的模板
m: 模型:在include目录下面的,以lib开头的一些php文件。
?
思路:先打开对应的php文件,根据php文件找到模板文件,根据位置,找到显示面包屑导航的变量。
(1)找php页面对应的模板页面。
(2)打开category.dwt模板文件。
(3)在library目录下面打开ur_here.lib文件。
(4)通过分析,说明{$ur_here}是显示面包屑的变量,说明在php页面中肯定有一个
$this->assign(‘ur_here‘,变量);语句
通过查找,是通过assign_ur_here函数取出数据的。
(5)寻找assign_ur_here函数
通过查找没有发现该函数咋当前页面中定义,需要在init.php文件中查找。
?
在init.php文件中,没有查到,通过分析该页面又加载了如下页面:
?
通过查找最终在lib_main.php页面中找到。并如下修改:
练习:把每个页面中的powered by ecshop去掉。
?
?
1、在项目中一些类文件,或者其他的一些文件,不想让用户直接访问,可以如下设置。
2、一个网站的一个页面,原来正常,一段时间出现了空白页面,
error_reporting(0);//禁止错误报告。
error_reporting(E_ALL)
?
3、定义网站的根目录,
?
4、当无法修改php.ini中配置时,可以在代码中自己配置。
?
5、缓存设置,在开发阶段要关闭缓存,在前台的 php页面中,几乎每一个页面有如下代码,
判断DEBUG_MODE和2求与,只要求与的结果等于2的时候,smarty缓存不起作用。
2 0010
2 0010
与运算结果是:
2 0010
通过分析我们可以把debug_mode定义成 2即可满足条件,缓存失效。
?
?
6、判断魔术引号是否开启,防止sql注入。
7、初始化数据库的类,在init.php文件中,已经对数据库的类初始化,因此在php文件中就可以直接使用。
?
$ecs->table(‘去掉前缀的表名‘)//获取表名的方法。
$db->getOne($sql)//获取单个数据
$db->getAll();//获取所有的数据
$db->getRow();//获取一行数据
?
8、载入配置文件,和语言包文件。
定义的语言包,可以实现多语言。
9、判断是搜索引擎访问还是正常的访问。
?
10、第smarty初始化。
?
用户在登录时可以使用邮箱或用户名称。
(1)找到用户登录页面的模板页面。
?
(2)找到表单,发现显示用户名的是一个语言包。因此要修改语言包
(3)打开语言包进行修改:
根据user.php页面,引入语言包的名称,进行查找,发现是语言包里面的user.php文件。
?
(4)通过表单查看提交到哪个页面。通过隐藏域发现是提交到当前页面的act_login节点。
?
?
(5)思路:对输入的用户名进行判断,如果是邮箱地址,则根据邮箱地址找出用户名称。
?
使用ecshop里面定义的一个函数:
具体代码:
?
?
1、布局规划:
2、虚拟主机的配置
3、完成项目的分组
4、admin分组的控制器建立控制器添加如下方法:
5、拷贝对应的模板文件,并修改样式和图片的路径。
?
?
?
$arr=array(
????‘商品管理‘=>array(
????????‘商品列表‘=>‘goodslist‘,
????????‘添加新商品‘=>‘addgoods‘
),
‘ 订单管理‘=>array(
????‘订单列表‘=>‘orderlist‘
)
‘会员管理‘=>array(
????‘会员列表‘=>memberlist
)
)
;
1、新建一个配置文件,定义菜单列表。
2、在主配置文件中,添加引入该配置文件的代码。
3、在index控制器下面的left方法中取出菜单内容。并遍历到静态页面:
4、定义一个语言包:
?
?
(1)建立每个按钮对应的权限:
(2)具体的代码:
public function left(){
//取出配置文件里面的内容
$menus = C(‘menus‘);
//取出按钮对应的权限
$menus_priv=C(‘menus_priv‘);
$lang = C(‘lang‘);
//取出当前登录用户的id
$user_id=$_SESSION[‘user_id‘];
$user_id=1;
//获取当前登录用户的权限
//$action_list = $_SESSION[‘acton_list‘];
$action_list = array(‘addgoods‘,‘addcategory‘);
//思路:把每个按钮的权限找出来,和 $action_list进行比较,判断按钮的权限是否在$action_list数组中。
//对按钮进行遍历
if($user_id!=1){
foreach($menus as $k=>$v){
//找出按钮对应的权限:
//判断顶级按钮是否显示
if(is_array($menus_priv[$k])){
$tmp = array_intersect($menus_priv[$k],$action_list);
//var_dump($tmp);
if(empty($tmp)){
//如果没有交集,说明该顶级按钮没有权限显示。应该从menus数组中删除。
unset($menus[$k]);
continue;//本次循环结束,继续下次循环。
}
}
//判断次级按钮是否显示。
foreach($v as $k1=>$v1){
//找出次级按钮对应的权限。
if(!in_array($menus_priv[$k1],$action_list)){
unset($menus[$k][$k1]);
}
}
}
}
?
?
$this->assign(‘menus‘,$menus);
$this->assign(‘lang‘,$lang);
$this->display();
}
先建立一个商品类型表:
create table goods_type(
id tinyint unsigned primary key auto_increment,
type_name varchar(32) not null default ‘‘ comment ‘商品类型的名称‘
)engine myisam charset utf8;
?
1、添加画一个商品类型的控制器,并拷贝对应的静态页面,修改样式,并修改好表单。
?
2、建立一个GoodsTypeModel.class.php
?
目录
4、完成给商品类型添加事件,按类型选择自己的属性。????4
7、在添加属性时,课选值列表是禁用状态,当选择列表选择按钮的时候,是开启状态。当选择手工录入是又是禁用状态。????7
?
?
?
完成建表
create table attribute(
id int primary key auto_increment,
attr_name varchar(32) not null default ‘‘ comment ‘属性的名称‘,
type_id int not null default 0 comment ‘属性所属商品类型的id‘,
attr_type tinyint unsigned not null default 0 comment ‘属性的类型 0表示是唯一属性1表示是单选属性‘,
attr_input_type tinyint unsigned not null default 0 comment ‘属性值的录入方式0表示手工录入1表示列表选择‘,
attr_value varchar(32) not null default ‘‘ comment ‘属性的默认值‘
)engine myisam charset utf8;
(1)完成添加属性表单制作。
表单效果:
(2)添加属性的模型
?
(3)添加控制器完成添加
?
在控制器中添加属性的方法
要注意在取出属性的时候,还要取出属性所属商品类型,所以要连表查询
?
模型中取出数据的方法:
控制器中的方法:
?
完成表单显示:
表单位置代码:
ajax代码:
ajax对应控制器中的方法,及方法对应的静态页面。
?
关键要统计出,所属当前类型属性的个数。
第一步:取出类型包括属性的id
select a.*,b.id from goods_type a left join attribute b on b.type_id=a.id
第二步:
select a.*,count(b.id) from goods_type a left join attribute b on b.type_id=a.id group by a.id
控制器里面的方法:
?
对应的静态页面:
?
主要思路:在遍历商品类型的时候,和传递$_GET[‘id‘]比较,若相等则显示出来。
?
具体的代码:
?
静态代码:
jquery代码:
1、建表
create table category(
id int primary key auto_increment,
cat_name varchar(32) not null default ‘‘ comment ‘商品的栏目名称‘,
parent_id int not null default 0 comment ‘上一级栏目的id‘
)engine myisam charset utf8;
2、添加栏目
(1)先创建一个栏目的模型。
?
(2)创建一个控制器,并添加添加栏目
对应模型中的方法:
(3)添加栏目表单效果:
表单代码:
?
表单效果:
3、栏目列表
(1)添加栏目列表的方法
?
(2)静态页面中显示栏目代码:
?
(1)添加会员等级的按钮和对应的权限,语言包。
(2)#创建会员级别表:
create table member_level(
id int primary key auto_increment,
level_name varchar(32) not null default ‘‘ comment ‘级别名称‘,
min_num int not null default 0 comment ‘积分下限‘,
max_num int not null default 0 comment ‘积分上限‘,
rate tinyint unsigned not null default 100 comment ‘折扣率‘
)engine myisam charset utf8;
?
(3)添加会员级别的model,完成自动验证。
要注意:验证规则:积分上限要大于积分下限,折扣率必须要大于0小于100,积分上限和积分下限必须是数字
(4)新建控制器,添加添加的方法,
?
?
?
(5)完成添加的表单的制作。
表单效果:
表单代码:
1、完成添加商品表单的制作。
2、完成商品属性标签的制作。
思路:给 selectt添加change事件,通过ajax获取 数据。
在展示出当前类型的属性时,要注意,根据attr_input_type值创建表单。
表单内容:
给select标签添加change事件,ajax获取数据的代码
ajax对应方法代码:
该方法对应的静态页面代码:
?
<table>
<?php
foreach($attrdata as $v){
if($v[‘attr_input_type‘]==0){
echo "<tr><td>".$v[‘attr_name‘]."</td><td>";
echo "<input type=‘text‘ name=‘‘/></td></tr>";
}else{
//根据列表选择选择内容
if($v[‘attr_type‘]==0){
//进入该位置表明是一个唯一属性
//根据列表值来选择
$attrs = explode(‘,‘,$v[‘attr_value‘]);//把默认值里面的内容转换 成一个数组
echo "<tr><td>".$v[‘attr_name‘]."</td><td>";
echo "<select name=‘‘>";
foreach($attrs as $v1){
echo "<option value=‘$v1‘>$v1</option>";
}
echo "</select></td></tr>";
}else{
//进入该位置表明是一个单选属性
$attrs = explode(‘,‘,$v[‘attr_value‘]);//把默认值里面的内容转换 成一个数组
echo "<tr><td><a href=‘javascript:‘ onclick=‘copysel(this)‘>[+]</a>".$v[‘attr_name‘]."</td><td>";
echo "<select name=‘‘>";
foreach($attrs as $v1){
echo "<option value=‘$v1‘>$v1</option>";
}
echo "</select>属性价格:<input type=‘text‘ name=‘‘ size=‘5‘/></td></tr>";
?
}
?
}
?
}
?>
?
</table>
<script>
function copysel(o){
//选择[+]所在的行。
var trs = $(o).parent().parent();
//在什么情况下复制一行。a标签里面的内容是[+]
if($(o).html()==‘[+]‘){
//复制一行
var newtrs = trs.clone();
//要修改新行中的a标签里面的 [+]为[-]
newtrs.find(‘a‘).html(‘[-]‘);
//复制的新行要插入到当前行的后面
trs.after(newtrs);
?
}else{
trs.remove();
}
?
}
</script>
?
?
注意:会员价格为-1时表示会员价格按会员等级折扣率计算。你也可以为每个等级指定一个固定价格
?
(1)显示效果:
?
表单代码:
(2)要建立一个存储会员等级价格的一张表:
?
#存储会员价格的表;
create table member_price(
id int primary key auto_increment,
goods_id int not null default 0 comment ‘商品的id‘,
level_id int not null default 0 comment ‘会员级别的id‘,
level_price decimal(9,2) not null default 0.0 comment ‘会员级别的价格‘
)engine myisam charset utf8;
?
?
设置表里面的存储图片的字段:
goods_img varchar(64) not null default ‘‘ comment ‘存储中图的路径‘,
goods_thumb varchar(64) not null default ‘‘ comment ‘存储小图的路径‘,
goods_ori varchar(64) not null default ‘‘ comment ‘存储原图的路径‘,
?
?
商品详情页面中的图片
?
(1)修改表单,添加上传数据的表单项。
enctype="multipart/form-data"并且是post提交,该file标签添加名称。
?
(2)写一个函数,用于上传。
public function upload(){
import(‘ORG.Net.UploadFile‘);
$upload = new UploadFile();// 实例化上传类
$upload->maxSize = 3145728 ;// 设置附件上传大小
$upload->allowExts = array(‘jpg‘, ‘gif‘, ‘png‘, ‘jpeg‘);// 设置附件上传类型
$upload->savePath = ‘./Public/Uploads/‘;// 设置附件上传目录
$upload->thumb=true;//表示生成缩略图
$upload->thumbMaxWidth=‘100,230‘;//指定缩略图 的宽度
$upload->thumbMaxHeight=‘100,230‘;//指定缩略图的高度
$upload->thumbPrefix="thumb_,img_";
$upload->autoSub=true;
$upload->subType=‘date‘;
$upload->dateFormat=‘Ym/d‘;
if(!$upload->upload()) {// 上传错误提示错误信息
$this->error($upload->getErrorMsg());
}else{// 上传成功 获取上传文件信息
$info = $upload->getUploadFileInfo();
}
// print_r($info);
//获取文件名称
echo $filename = ltrim(strrchr($info[0][‘savename‘],‘/‘),‘/‘);
//思路:组建一个数组,数组格式是:
///546fe9d3ae18c.jpg
/* $img=array(
‘goods_img‘=>中图的路径,
‘goods_thumb‘=>小图的路径
‘goods_ori‘=>原图的路径
);*/
$dir = date("Ym/d");
$img=array(
‘goods_img‘=>$dir.‘/img_‘.$filename,
‘goods_thumb‘=>$dir.‘/thumb_‘.$filename,
‘goods_ori‘=>$info[0][‘savename‘]
);
return $img;
}
?
(1)建立一个商品表,用于存储商品。
#创建商品表
create table goods(
id int primary key auto_increment,
goods_name varchar(32) not null default ‘‘ comment ‘商品的名称‘,
goods_sn varchar(32) not null default ‘‘ comment ‘商品的货号‘,
cat_id int not null default 0 comment ‘所属栏目的id‘,
shop_price decimal(9,2) not null default 0.0 comment ‘商品的价格‘,
goods_number int not null default 0 comment ‘商品的库存数量‘,
goods_img varchar(64) not null default ‘‘ comment ‘存储中图的路径‘,
goods_thumb varchar(64) not null default ‘‘ comment ‘存储小图的路径‘,
goods_ori varchar(64) not null default ‘‘ comment ‘存储原图的路径‘,
goods_desc varchar(256) not null default ‘‘ comment ‘商品的描述‘,
is_new tinyint unsigned not null default 0 comment ‘是否新品0不是新品,1表示是新品‘,
is_hot tinyint unsigned not null default 0 comment ‘是否热销0不是热销,1表示是热销‘,
is_best tinyint unsigned not null default 0 comment ‘是否精品0不是精品,1表示是精品‘,
is_sale tinyint unsigned not null default 0 comment ‘是否上架0不是上架,1表示是上架‘,
is_delete tinyint unsigned not null default 0 comment ‘是否删除0不是删除,1表示是删除‘,
goods_type tinyint unsigned not null default 0 comment ‘所属类型的id‘
)engine myisam charset utf8;
(2)修改表单,给提交到goods表的数据命名。
?
(3)完成goods表入库,代码在添加方法中。
?
?
显示会员等级的表单:
?
入库的代码:
?
(1)建立存储商品信息的属性表:
思考:要存储哪些信息:
商品的id 属性的id 属性的值 单选属性的价格
#存储商品属性的表
create table goods_attr(
id int primary key auto_increment,
goods_id int not null default 0 comment ‘商品的id‘,
attr_id int not null default 0 comment ‘商品属性的id‘,
attr_value varchar(32) not null default ‘‘ comment ‘商品属性的值‘,
attr_price int not null default 0 comment ‘商品属性的价格‘
)engine myisam charset utf8;
?
(2)修改显示属性信息的表单。
(3)入库代码:
?
完成商品添加最终代码:
public function add(){
if($this->isPost()){
$goods = D(‘Goods‘);
$goodsdata = $_POST[‘goods‘];
$img = $this->upload();
$goodsdata[‘goods_thumb‘]=$img[‘goods_thumb‘];
$goodsdata[‘goods_img‘]=$img[‘goods_img‘];
$goodsdata[‘goods_ori‘]=$img[‘goods_ori‘];
// print_r($goodsdata);exit;
if($goods_id = $goods->add($goodsdata)){
//完成添加会员等级价格入库
$memberdata = $_POST[‘member‘];
// print_r($memberdata);exit;
foreach($memberdata as $k=>$v){
$sql="insert into member_price (goods_id,level_id,level_price) values($goods_id,$k,$v)";
$goods->Execute($sql);
}
//完成添加属性信息入库
$attrdata = $_POST[‘attr‘];
$price = $_POST[‘price‘];
foreach($attrdata as $k=>$v){
if(is_array($v)){
foreach($v as $k1=>$v1){
$jia = $price[$k][$k1];
$sql="insert into goods_attr(goods_id,attr_id,attr_value,attr_price) values($goods_id,$k,‘$v1‘,$jia)";
$goods->Execute($sql);
}
}else{
$sql="insert into goods_attr(goods_id,attr_id,attr_value) values($goods_id,$k,‘$v‘)";
$goods->Execute($sql);
}
?
}
$this->success(‘添加商品成功‘,__URL__.‘/lst‘);exit;
}else{
$this->error(‘添加商品失败‘);
}
?
?
}
//取出商品的类型
$typemodel = D("GoodsType");
$typedata = $typemodel->select();
$this->assign(‘typedata‘,$typedata);
//要取出会员等级,便于输入等级的价格
$memmodel = D("MemberLevel");
$memdata = $memmodel->select();
$this->assign(‘memdata‘,$memdata);
//取出商品的栏目信息,
$catemodel = D("Category");
$catedata = $catemodel->getsort();//
$this->assign(‘catedata‘,$catedata);
$this->display();
}
public function lst(){
$this->display();
}
public function showattr(){
$id = $_GET[‘id‘]+0;
$attrmodel = D("Attribute");
$attrdata = $attrmodel->_showattr($id);
$this->assign(‘attrdata‘,$attrdata);
$this->display();
?
}
?
?
?
1、展示出前台首页。
思路:新建首页的控制器,拷贝对应的模板文件。根据模板显示出数据
2、把页面的头部给截取下来单独成立一个文件,让其他页面导入即可。
(1)在tpl/Home目录下面新建一个Public目录,该目录里面存储被包含的一些文件,比如头文件,尾部的文件,或其他的被包含的文件。头部文件命名为:head.html
(2)在index.html页面中进行引入:
(3)把头部的导航栏目给取出来。
思路:把顶级栏目信息该展示出来。
在category模型中添加一个函数,用于取出顶级栏目
(4)新建一个homeaction的控制器,用于取出导航栏目数据,让他其他控制器继承。
(5)在public:head.html文件中,把数据给展示出来。
?
?
3、把首页的商品分类给展示出来。
具体的代码:
4、要取出精品和热卖和新品的信息
思路:在goods模型中添加一个方法,用于取出该信息。
?
1、展示出栏目页面。
?
在index控制器中添加一个方法,category,该方法用于展示出栏目页面。
category对应的方法:
public function category(){
$goods = D(‘Goods‘);
//接收传递过来的参数
$id = $_GET[‘id‘];
//根据当前栏目取出所属商品。
// 如果传递的是子栏目的id,就直接查找即可。
//如果传递的是等级栏目的id,就要找到他的子栏目的 id ,根据子栏目的id查找商品。
$catemodel = D("Category");
$ids = $catemodel->getsubid($id);
if(empty($ids)){//如果为空则自己是一个子栏目。
$sub_ids=$id;
}else{
//如果不为空,则返回的子栏目id组成的一个数组。
$sub_ids = implode(",",$ids);
}
//根据栏目的id取出商品
$goodsdata = $goods->where("cat_id in($sub_ids)")->select();
?
$this->assign(‘goodsdata‘,$goodsdata);
//显示出栏目页面中的商品分类
$catedata = $catemodel->getsort();
$this->assign(‘catedata‘,$catedata);
$this->display();
?
?
}
?
在category模型中定义的函数:
2、根据当前栏目 的页面,显示出对应的样式。
思路:在循环遍历的时候,自己的id要和地址栏传递的id进行比较,如果两者一致,则说明选择自己为当前栏目页面。
?
3、在栏目页面中取出精品推荐。
?
满足的条件:(1)所属当前栏目,(2)is_best等于1
在category方法中,根据条件取出数据。
在静态页面中遍历
?
目录
2、面包屑导航:主要用在内容详情页面,和列表页面。????5
?
?
ecshop里面的后台管理员和前台的会员表。
?
1、建表:
create table member(
id int primary key auto_increment,
user_name varchar(32) not null comment ‘会员的名称‘,
password char(32) not null comment ‘会员的密码,md5加密‘,
email varchar(32) not null default ‘‘ comment ‘会员的邮箱地址‘,
level_id tinyint not null default 1 comment ‘会员的级别,默认是第一个级别‘,
rank_points int not null default 0 comment ‘会员的积分情况‘
)engine myisam charset utf8;
2、添加会员的模型,进行数据验证,。
3、添加注册的控制器,并添加注册的方法:
4、添加登录的方法。
(1)在member模型中添加验证登录的方法:
(2)在member控制器中添加登录的方法,并修改登陆的表单。
(3)如果用户已经登录,则显示出用户名称,如果没有登录则显示登录和注册
打开tpl/public/head.html 文件,进行修改:
(4)会员可以使用邮箱登录。
注意情况是:用户名称中有可能有@符号,误当做一个邮箱对待。
?
具体的代码:
//验证用户登录的方法
public function login($username,$password){
//$sql="select * from user where username=‘$username‘ and password=‘$password‘";
//根据用户名找出密码,该密码再和用户输入的密码进行比较。
//思路;判断输入的用户名是否是一个邮箱,如果是邮箱根据邮箱找出用户名。
if($this->is_email($username)){
$userinfo = $this->where("email=‘$username‘")->getField(‘user_name‘);
if(!empty($userinfo)){
$username= $userinfo;
}
}
$userinfo = $this->where("user_name=‘$username‘")->find();
if($userinfo){
if($userinfo[‘password‘]==md5($password)){
//和方法的用户,把一些信息写入到session里面。
$_SESSION[‘user_name‘]=$username;
$_SESSION[‘user_id‘]=$userinfo[‘id‘];
//把登录用户的会员级别写入到session里面,便于计算当前用户的会员价格。
$_SESSION[‘level_id‘]=$userinfo[‘level_id‘];
return true;
}
}
return false;
}
并添加一个showgoods的方法,用于取出具体的商品数据,并拷贝对应的静态页面。
?
案例:
在category模型中的代码:
在goods控制器中的showgoods方法中使用:
静态页面中遍历:
?
具体的效果;
诺基亚n73 黑色和白色 属于是两件商品(货品)
?
(1)、在商品的详情页面,展示出会员级别的价格。
思路:
计算会员级别的价格有两种方式:(1)走折扣率,(2)直接获取。
最终的数据,要遍历到页面中,要构造一个数组,便于我们遍历。
想构建如下的一个数组;
$arr=array(
????‘会员级别的id‘=>array(‘level_name=>‘‘会员的名称‘,‘level_price‘=>对应的价格)
);
?
(2)、计算会员级别的价格
写一个函数用于取出会员级别的价格:两个参数:商品的id和会员级别的id.
function getprice($goods_id,$leve_id){
????
}
在goods控制器中定义的函数具体的代码;
?
在静态页面中进行遍历:
?
4、要取出商品的单选属性,遍历到商品的详情页面,便于用户选择。
需要的信息:属性的名称,属性的值,属性的价格,
思路:哪张表:goods_attr表和attribute 表。条件是:单选属性和goods_id
?
?
$sql="select b.attr_name,a.attr_value,a.attr_price from goods_attr a left join attribute b on a.attr_id=b.id where a.goods_id=$goods_id and b.attr_type=1";
在静态页面中的代码:
?
1、新建一个购物车的表:
create table cart(
id int primary key auto_increment,
goods_id int not null default 0 comment ‘购买商品的id‘,
user_id int not null default 0 comment ‘登录会员的id‘,
session_id varchar(32) not null comment ‘当前会话的id‘,
goods_name varchar(32) not null default ‘‘ comment ‘商品的名称‘,
shop_price decimal(9,2) not null default 0.0 comment ‘商品的价格‘,
goods_number int not null default 0 comment ‘购买商品的数量‘,
goods_attr varchar(32) not null default ‘‘ comment ‘商品的属性‘,
goods_attr_price decimal(9,2) not null default 0.0 comment ‘商品属性价格‘,
goods_attr_id varchar(32) not null default ‘‘ comment ‘商品属性的id,多个id用逗号隔开‘
)engine myisam charset utf8;
2、在商品的详情页面,准备购物车表需要的信息,主要是修改表单。
添加隐藏域:
goods_id goods_name shop_price[注意:价格可以通过表单伪造,不是可信的。]
?
?
?
3、新建一个cart的控制器,添加一个add的方法。
在表单中添加加入购物车的方法,
?
?
class CartAction extends HomeAction{
public function add(){
//print_r($_POST);
$lan=$this->getlan();
$goods = D(‘Goods‘);
$goods_id = $_POST[‘goods_id‘];
$data[‘goods_id‘]= $goods_id;
$data[‘goods_name‘] = $_POST[‘goods_name‘];
$data[‘user_id‘] = $_SESSION[‘user_id‘];
$data[‘session_id‘]=session_id();
$data[‘shop_price‘]=$goods->where("id=$goods_id")->getField(‘shop_price‘);
$data[‘goods_number‘]=$_POST[‘goods_number‘];
$goods_attr=‘‘;
$goods_attr_price=‘‘;//多个属性加起来
$goods_attr_id=‘‘;
//颜色:黑色[0.00]
$attr = $_POST[‘attr‘];
foreach($attr as $k=>$v){
$attrprice =$this->getprice($goods_id,$v);
$goods_attr_price+=$attrprice;
$goods_attr.=$lan[$k].‘:‘.$v.‘[‘.$attrprice.‘]‘;
$goods_attr_id.=$k.‘,‘;//构建属性的id,多个id用逗号隔开。
}
$data[‘goods_attr‘]=$goods_attr;
$data[‘goods_attr_price‘]=$goods_attr_price;
$data[‘goods_attr_id‘]=trim($goods_attr_id,‘,‘);
print_r($data);
}
//获取属性的价格,根据goods_id和属性的名称
public function getprice($goods_id,$v){
$goods_attr=D(‘GoodsAttr‘);
$attr_price = $goods_attr->where("goods_id=$goods_id and attr_value=‘$v‘")->getField(‘attr_price‘);
return $attr_price;
}
public function getlan(){
$attr = D(‘Attribute‘);
$data = $attr->select();
$list=array();
foreach($data as $v){
$list[$v[‘id‘]]=$v[‘attr_name‘];
}
return $list;
}
}
?
?
?
?
?
?
?
?
?
王刚: 诺基亚N98 黑色 内存 2G
????????诺基亚N98 白色 内存 2G
宋江: 诺基亚N98 黑色 内存 2G
思路:使用条件如何判断是用一件商品:满足三个条件:session_Id 商品的id 属性的值。
?
?
?
?
具体的代码:
public function add(){
//print_r($_POST);
$lan=$this->getlan();
$goods = D(‘Goods‘);
$goods_id = $_POST[‘goods_id‘];
?
$goods_name= $_POST[‘goods_name‘];
$user_id= (int)$_SESSION[‘user_id‘];
$session_id=session_id();
$shop_price=$goods->where("id=$goods_id")->getField(‘shop_price‘);
$goods_number=$_POST[‘goods_number‘];
$goods_attr=‘‘;
$goods_attr_price=‘‘;//多个属性加起来
$goods_attr_id=‘‘;
//颜色:黑色[0.00]
$attr = $_POST[‘attr‘];
foreach($attr as $k=>$v){
$attrprice =$this->getprice($goods_id,$v);
$goods_attr_price+=$attrprice;
$goods_attr.=$lan[$k].‘:‘.$v.‘[‘.$attrprice.‘]<br/>‘;
$goods_attr_id.=$k.‘,‘;//构建属性的id,多个id用逗号隔开。
}
$goods_attr=trim($goods_attr,‘<br/>‘);
$goods_attr_id=trim($goods_attr_id,‘,‘);
if($this->additem($goods_id,$session_id,$goods_attr,$user_id,$goods_name,$shop_price,$goods_number,$goods_attr_price,$goods_attr_id)){
$this->success("添加购物车成功",__URL__.‘/showitem‘);exit;
}else{
$this->error("添加购物车失败");
}
?
?
}
//用于加入到购物车的一个函数:
public function additem($goods_id,$session_id,$goods_attr,$user_id,$goods_name,$shop_price,$goods_number,$goods_attr_price,$goods_attr_id){
//在商品加入购物车之前要判断一下该商品购物车里面是否存在,如果存在则数量加1,如果不存在则添加。
if($this->hasitem($goods_id,$session_id,$goods_attr)){
//存在,
$sql="update cart set goods_number=goods_number+$goods_number where goods_id=$goods_id and session_id=‘$session_id‘ and goods_attr=‘$goods_attr‘";
}else{
//不存在
$sql="insert into cart (goods_id,user_id,session_id,goods_name,shop_price,goods_number,goods_attr,goods_attr_price,goods_attr_id) values($goods_id,$user_id,‘$session_id‘,‘$goods_name‘,$shop_price,$goods_number,‘$goods_attr‘,‘$goods_attr_price‘,‘$goods_attr_id‘)";
}
//执行sql语句
$cartmodel = D(‘Cart‘);
if($cartmodel->Execute($sql)!==false){
return true;
}
return false;
?
}
?
遍历到静态页面。
(1)思路:在homeAction控制器里面写。
(2)在public目录下面的head.html静态页面中展示出购物车里面 的商品。
?
?
(1)给删除按钮添加删除的链接。
(2)在CartAction控制器里面添加删除购物车的函数
?
?
?
?
(1)添加两个图片在购买数量的输入框两边。
代码:
(2)
?
表单修改:
?
具体代码:
<script>
$(".add").click(function(){
//找出原来 的购买数量
var curr_num = parseInt($(this).parent().find("input[name=goods_number]").val());
//取出商品的小计价格
var xiaoji_price = parseFloat($(this).parent().parent().find("span").html());
//计算商品的单价
var dan_price = xiaoji_price/curr_num;
//计算新的小计价格:等于原来的小计价格+商品的单价
var new_xiaoji_price = xiaoji_price+dan_price;
//计算新的购买数量:等于原来的购买数量+1
var new_num = curr_num+1;
//取出商品的总价
var total_price = parseFloat($("#total_price").html());
//计算新的总价;等于原来的总价+商品的单价
var new_total_price = total_price+dan_price;
//获取当前购物车数据的id
var cart_id = parseInt($(this).parent().find(‘input[name=cart_id]‘).val());
var _this = $(this);
//ajax修改数据库。
$.ajax({
type:‘get‘,
url:‘__URL__/update/cart_id/‘+cart_id,
success:function(msg){
if(msg==‘ok‘){
//新的小计价格和新的数量和新的总价展示出来
//展示新的数量
_this.parent().find("input[name=goods_number]").val(new_num);
//展示新的小计价格
_this.parent().parent().find("span").html(new_xiaoji_price);
//展示新的总价
$("#total_price").html(new_total_price);
//alert(msg);
}
}
});
});
?
?
(1)在展示购物车页面,结算中心添加一个链接。
?
(2)新建一个order的控制器,添加checkout的方法。
验证是否登录,完成登录后,跳转到当前的页面。
修改login.html文件,添加隐藏域。
?
在member控制器中修改登录的方法:
(3)判断收货人的地址是否填写。
建立一张表,用户存储收货人的用户信息。
?
create table address(
id int primary key auto_increment,
user_id int not null comment ‘登录用户的id‘,
consignee varchar(32) not null default ‘‘ comment ‘收货人姓名‘,
address varchar(32) not null default ‘‘ comment ‘收货人地址‘,
email varchar(32) not null default ‘‘ comment ‘收货人邮箱‘,
tel varchar(32) not null default ‘‘ comment ‘收货人电话‘,
mobile varchar(32) not null default ‘‘ comment ‘收货人手机‘
)engine myisam charset utf8;
?
订单信息表:
?
create table order_info(
id int primary key auto_increment,
order_sn varchar(32) not null comment ‘订单的编号。‘,
user_id int not null comment ‘登录用户的id‘,
consignee varchar(32) not null default ‘‘ comment ‘收货人姓名‘,
address varchar(32) not null default ‘‘ comment ‘收货人地址‘,
email varchar(32) not null default ‘‘ comment ‘收货人邮箱‘,
tel varchar(32) not null default ‘‘ comment ‘收货人电话‘,
mobile varchar(32) not null default ‘‘ comment ‘收货人手机‘,
shipping_name varchar(12) not null comment ‘配送方式‘,
pay_name varchar(12) not null comment ‘支付方式‘,
goods_amount decimal(9,2) not null comment ‘订单金额‘
)engine myisam charset utf8;
?
商品和订单的关联表
create table order_goods(
id int primary key auto_increment,
order_id int not null comment ‘订单的id‘,
goods_id int not null comment ‘商品的id‘,
goods_name varchar(32) not null default ‘‘ comment ‘商品的名称‘,
shop_price decimal(9,2) not null default 0.0 comment ‘商品的价格‘,
goods_number int not null default 0 comment ‘购买商品的数量‘,
goods_attr varchar(32) not null default ‘‘ comment ‘商品的属性‘,
goods_attr_id varchar(32) not null default ‘‘ comment ‘商品属性的id,多个id用逗号隔开‘
)engine myisam charset utf8;
?
具体的代码在文件中:
?
?
购物的流程:(1)商品的详情页面-》加入到购物车,--》下订单-》入库(订单的信息表和订单与商品的关联表)--》清空购物车-》流程完成。
?
一件商品属性:
诺基亚N98 颜色(白色,黑色,金色) 内存(2G,4G,8G) 库存:
白色:2G 库存量
白色:4G 库存量
白色:8G 库存量
黑色:2G 库存量
黑色:4G 库存量
黑色:8G 库存量
金色:2G 库存量
金色:4G 库存量
金色:8G 库存量
货品表:
id goods_id(商品的id) (颜色,内存)
?
确定具体的一件货品:goods_id 白色,2G
?
思路:在内容详情页面中,把商品的id保存的cookie里面,在显示浏览历史的页面,把cookie里面的id取出来,根据id取出商品。
代码在页面中:
?
?
控制器:
?
?
?
代码:
<script>
$(".showgoods").mouseover(function(){
//取出当前订单 id.
var order_id = $(this).parent().parent().find("input[name=order_id]").val();
//找出鼠标所在的行的位置。
var p = $(this).parent().parent().parent().offset();//行的位置
//alert(p.top);
//根据order_id 通过ajax取出数据
$("#showgoods").show();
$.ajax({
type:‘get‘,
url:‘__URL__/getgoods/order_id/‘+order_id,
success:function(msg){
//返回的数据,在div中进行显示
// $("#showgoods").hide();
$("#showgoods").html(msg);
$("#showgoods").css(‘left‘,p.left+120);
$("#showgoods").css(‘top‘,p.top+20);
}
});
});
$(".showgoods").mouseout(function(){
$("#showgoods").hide();
});
</script>
?
?
// 有m个猴子围成一圈,每数n个数出圈一个猴子,下一个猴子再从1开始数到n再跳出....只剩下一个猴子当大王。
标签:
原文地址:http://www.cnblogs.com/yizhinageyuanfang/p/5523038.html