网站开发 · 2025年4月24日

ecshop属性表attribute商品属性表goods_attr货品表prduct 商品数量的联系

一个ecshop商城的商品属性存放在属性表(attribute)里 ,每个商品对应的属性在goods_attr里 goods_attr与(attribute)想关联,商品表里有商品数量的字段goods_number

为什么有这个货品表呢?

 因为 某件商品有多种属性的时候,那这个商品就成为了货品,也就是说不同属性的相同商品应该也存在差异,所以当设置商品属性的attr_type=1(表示单选属性)的时候,

在 前台include/lib_comment.php 函数sort_goods_attr_id_array将 goods_attr_id 的序列按照 attr_id 重新排序 可以找到 非规格属性的id会被排除这句话,在连接这个函数写的sql语句

/重新排序

    $sql = “SELECT a.attr_type, v.attr_value, v.goods_attr_id

            FROM ” .$GLOBALS[‘ecs’]->table(‘attribute’). ” AS a

            LEFT JOIN ” .$GLOBALS[‘ecs’]->table(‘goods_attr’). ” AS v

                ON v.attr_id = a.attr_id

                AND a.attr_type = 1

            WHERE v.goods_attr_id ” . db_create_in($goods_attr_id_array) . ”

            ORDER BY a.attr_id $sort”;

我个人觉得attr_type=1表示规格属性,然后就是由于这样的处理,导致attr_type=0 attr_type=2的商品 他们虽然有商品数量,但是货品库存查不出来从而导致到货通知这个功能出现异常

首先我们来看看这个到货通知是怎样处理的:

    从模板goods.dwt里我们找到

        function changePrice()

{

  var attr = getSelectedAttributes(document.forms[‘ECS_FORMBUY’]);

  var qty = document.forms[‘ECS_FORMBUY’].elements[‘number’].value;

if(qty <=0 ){

 document.forms[‘ECS_FORMBUY’].elements[‘number’].value = 1;

 qty = 1;

}

  Ajax.call(‘goods.php’, ‘act=price&id=’ + goodsId + ‘&attr=’ + attr + ‘&number=’ + qty, changePriceResponse, ‘GET’, ‘JSON’);

}

/**

 * 接收返回的信息

 */

function changePriceResponse(res)

{

  if (res.err_msg.length > 0)

  {

    alert(res.err_msg);

  }

  else

  {

        document.forms[‘ECS_FORMBUY’].elements[‘number’].value = res.qty;

        if (document.getElementById(‘ECS_GOODS_AMOUNT’)){

          document.getElementById(‘ECS_GOODS_AMOUNT’).innerHTML = res.result;

        }

       if(document.getElementById(‘ECS_GOODS_NUMBER’)){

        document.getElementById(‘ECS_GOODS_NUMBER’).innerHTML = res.goods_attr_number;

            if(res.goods_attr_number > 0){

                document.getElementById(‘ECS_ADD_TO_CART’).style.display=”block”;

                document.getElementById(‘ECS_ONE_STEP_BUY’).style.display=”block”;

                document.getElementById(‘ECS_DAOHUO’).style.display=”none”;

            }else{

                document.getElementById(‘ECS_ADD_TO_CART’).style.display=”none”;

                document.getElementById(‘ECS_ONE_STEP_BUY’).style.display=”none”;

                document.getElementById(‘ECS_DAOHUO’).style.display=”block”;

            }

就是这里,通过发送一个ajax请求回传到goods.php里,得到最终的attr,然后在goods.php里通过:

//– 改变属性、数量时重新计算商品价格

/*—————————————————— */

if (!empty($_REQUEST[‘act’]) && $_REQUEST[‘act’] == ‘price’)

{

    include(‘includes/cls_json.php’);

    $json   = new JSON;

    $res    = array(‘err_msg’ => ”, ‘result’ => ”, ‘qty’ => 1);

    $attr_id    = isset($_REQUEST[‘attr’])&&!empty($_REQUEST[‘attr’]) ? explode(‘,’, $_REQUEST[‘attr’]) : array();

    $number     = (isset($_REQUEST[‘number’])) ? intval($_REQUEST[‘number’]) : 1;

    if ($goods_id == 0)

    {

        $res[‘err_msg’] = $_LANG[‘err_change_attr’];

        $res[‘err_no’]  = 1;

    }

    else

    {

        if ($number == 0)

        {

            $res[‘qty’] = $number = 1;

        }

        else

        {

            $res[‘qty’] = $number;

        }

        $exclusive = $GLOBALS[‘db’]->getOne(“select exclusive from “.$GLOBALS[‘ecs’]->table(‘goods’).” where goods_id = $goods_id”);

        $shop_price  = get_final_price($goods_id, $number, true, $attr_id);

        $res[‘is_exclusive’]  = is_exclusive($exclusive,$shop_price);

        $res[‘result’] = price_format($shop_price * $number);

        $res[‘result_jf’] = floor($shop_price * $number);

        $res[‘goods_attr_number’] = get_product_attr_num($goods_id,$_REQUEST[‘attr’]);

回传json数据到模板,通过if(document.getElementById(‘ECS_GOODS_NUMBER’)){

        document.getElementById(‘ECS_GOODS_NUMBER’).innerHTML = res.goods_attr_number;

            if(res.goods_attr_number > 0){

                document.getElementById(‘ECS_ADD_TO_CART’).style.display=”block”;

                document.getElementById(‘ECS_ONE_STEP_BUY’).style.display=”block”;

                document.getElementById(‘ECS_DAOHUO’).style.display=”none”;

            }else{

                document.getElementById(‘ECS_ADD_TO_CART’).style.display=”none”;

                document.getElementById(‘ECS_ONE_STEP_BUY’).style.display=”none”;

                document.getElementById(‘ECS_DAOHUO’).style.display=”block”;

            }就可以实现到货通知

我们在来看看这个 goods_attr_number在php页面是怎样得到的

$res[‘goods_attr_number’] = get_product_attr_num($goods_id,$_REQUEST[‘attr’]);—-attr是ajax调来的数据,往上找会看到它的处理

继续找get_product_attr_num

get_product_attr_num 获取相关属性的库存* @param int $goodid 商品id * @param string(array) $attrids 商品属性id的数组或者逗号分开的字符串

仔细看函数的流程,我们发现如果一个商品没有属性,那它的attrid就是空的,又一个商品有多个属性,那就对应多个goods_attr_id

在这里的话  goods_attr_number =就直接等于商品表里goods_number对应的数量

好了,再往下看,如果有属性,那么就  重新排序 就是我上面提到的方法

问题就在这里了,那我们在看看后台商品属性功能

在编辑属性处有这样三个单选,属性是否可选:唯一属性  单选属性  复选属性    而这里就是attr_type对应 的三种值

在页面有这样的说明:

选择”单选/复选属性”时,可以对商品该属性设置多个值,同时还能对不同属性值指定不同的价格加价,用户购买商品时需要选定具体的属性值。选择”唯一属性”时,商品的该属性值只能设置一个值,用户只能查看该值。

但是 出现问题来了,如果没有选择单单选属性 那么在商品列表里或者再添加商品的时候这个商品的属性不是单选属性那么就不会出现货品管理这个功能

因为在这个功能处也有个逻辑

在后台的goods.php里找到:

/* 获取商品规格列表 */

    $attribute = get_goods_specifications_list($goods_id);

在lib_goods.php里找到里这个函数

/**

 * 获取商品类型中包含规格的类型列表

 *

 * @access  public

 * @return  array

 */

function get_goods_type_specifications()

{

    // 查询

    $sql = “SELECT DISTINCT cat_id

            FROM ” .$GLOBALS[‘ecs’]->table(‘attribute’). ”

            WHERE attr_type = 1″;

    $row = $GLOBALS[‘db’]->GetAll($sql);

    $return_arr = array();

    if (!empty($row))

    {

        foreach ($row as $value)

        {

            $return_arr[$value[‘cat_id’]] = $value[‘cat_id’];

        }

    }

    return $return_arr;

}

不难发现,这里也只有attr_type = 1 才会出现货品这个功能