DiscuzNT 交易插件设计之商品添加,编辑和删除(CUD)

     在上一篇文章中,大略说明了一个商品交易插件的一些功能上的东西和具体的文件分布。本文章将会
以上文中的“管理商品”用例来说明一下商品的添加,编辑和删除方面的设计。

     首先看一下商品添加功能。我们打开一个商品添加页面如下:

 

 

 
     上图中说明了发布商品时要填写的内容和数据约束项,其中的"商品类目"一侧的“选择”链接点击后效果如下图所示:


 

    

      当填写完相应的商品信息,并通过JS和aspx.cs数据校验之后,就会在postgoods.aspx.cs中执行下面

语句,以便向商品列表中添加数据:

    
goodsinfo.Goodsid = Goods.CreateGoods(goodsinfo);
     

     其中的CreateGoods方法内容如下(discuz.mall项目的App_Code文件夹下的Goods.cs文件)

     
/// <summary>
/// 创建商品数据信息
/// </summary>
/// <param name="goodsinfo">商品信息</param>
/// <returns>创建商品的id</returns>
public static int CreateGoods(Goodsinfo goodsinfo)
{
            
int goodsid = DbProvider.GetInstance().CreateGoods(goodsinfo);

            
//当成功创建商品信息且可在前台正常显示时
            if (goodsid > 0 && goodsinfo.Displayorder>=0)
            {

                DbProvider.GetInstance().UpdateCategoryGoodsCounts(goodsinfo.Categoryid, 

                                                                                          goodsinfo.Parentcategorylist, 1);

 

 

            }
            
return goodsid;
}
        
    而上面方法中的DbProvider.GetInstance().CreateGoods(goodsinfo)即是向数据库中添加相应商品的
sql语句(相应内容参见discuz.mall项目的Data文件夹下的SqlDataProvider.cs文件中的相应方法).

    上面代码中还包括一个更新当前添加商品所属分类的商品数的语句。这里面有必要介绍一个商品分类表,

因为要更新的字段即是该表中的goodscount字段(分类的商品数),见下图:

 

 



    当然到这里只是完成了初始化添加商品数据的功能。而商品标签,附件等功能还需要通过上面方法的

返回值即新创建的商品id来进行添加,请看下面代码(postgoods.aspx.cs):

 

 

    

    
if (enabletag && tagsArray != null && tagsArray.Length > 0)
    {

        DbProvider.GetInstance().CreateGoodsTags(string.Join(" ", tagsArray), goodsinfo.Goodsid, userid, 

                                                                   curdatetime);

 

 

        GoodsTags.WriteGoodsTagsCacheFile(goodsinfo.Goodsid);
    }

    

    
    上面代码即是将当前商品的标签添加到商品标签列表中的语句(注:这部分代码将来可能要重构)。
    其中的CreateGoodsTags方法是直接向数据库中插入指定商品的标签,并根据标签是否已存在来更新已有标签的使用数。
    
    而第二个方法即:GoodsTags.WriteGoodsTagsCacheFile(goodsinfo.Goodsid)则是将标签写入缓存文件,以便加快
页面浏览速度。其方法内容如下:


      
        /// <summary>
        
/// 写入主题标签缓存文件
        
/// </summary>
        
/// <param name="tagsArray">标签数组</param>
        
/// <param name="topicid">主题Id</param>
        public static void WriteGoodsTagsCacheFile(int goodsid)
        {
            StringBuilder dir 
= new StringBuilder();
            dir.Append(BaseConfigs.GetForumPath);
            dir.Append(
"cache/goods/magic/");
            dir.Append((goodsid 
/ 1000 + 1).ToString());
            dir.Append(
"/");
            
string filename = Utils.GetMapPath(dir.ToString() + goodsid.ToString() + "_tags.config");

#if NET1
            TagInfoCollection tags 
= GetTagsListByGoods(goodsid);
#else
            List
<TagInfo> tags = GetTagsListByGoods(goodsid);
#endif

            Tags.WriteTagsCacheFile(filename, tags, 
string.Empty, false);
        }

        
        
    完成了标签(文件)的创建之后。下面是商品附件的上传和数据添加(postgoods.aspx.cs):    
  

 

  Goodsattachmentinfo[] attachmentinfo = Discuz.Mall.MallUtils.SaveRequestFiles(categoryid, 

             config.Maxattachments, usergroupinfo.Maxsizeperday, usergroupinfo.Maxattachsize, 

             MaxTodaySize, attachextensions, watermarkstatus, config, "postfile");

 

 

  if (attachmentinfo != null)
  {
      
if (attachmentinfo.Length > config.Maxattachments)
      {
          AddErrLine(
"系统设置为每个商品附件不得多于" + config.Maxattachments + "");
          
return;
      }

      int errorAttachment = GoodsAttachments.BindAttachment(attachmentinfo, goodsinfo.Goodsid, sb, 

                                                                                    goodsinfo.Categoryid, userid);

 

 

      int[] aid = GoodsAttachments.CreateAttachments(attachmentinfo);
      
string tempMessage = GoodsAttachments.FilterLocalTags(aid, attachmentinfo, goodsinfo.Message);

      goodsinfo.Goodspic 
= (attachmentinfo.Length > 0? attachmentinfo[0].Filename : "";
      
if (!tempMessage.Equals(goodsinfo.Message))
      {
          goodsinfo.Message 
= tempMessage;
          goodsinfo.Aid 
= aid[0];
      }
      Goods.UpdateGoods(goodsinfo);

      UserCredits.UpdateUserCreditsByUploadAttachment(userid, aid.Length 
- errorAttachment);
  }

  
//加入相册
  #region 相册
  
if (config.Enablealbum == 1 && apb != null)
  {
      sb.Append(apb.CreateAttachment(attachmentinfo, usergroupid, userid, username));
  }
  
#endregion

 
       因为使用了与版块下上传附件所相似的逻辑代码,这里就不多加说明了,要注意的是因为商品交易
  插件也支持远程附件功能,因此我们也需要在后台设置相应的FTP信息后才会启用,而有关这部分的内
  容请参见我之前的一篇文章:
 
 
       这样,“添加商品”的主要的流程应该就走的差不多了,当然还有一些功能如添加HTML标题,商品所在
  地数据js文件绑定,商品分类的js数据绑定等就暂不介绍了,大家找到相应的js文件或CS文件一看便知。
      
       下面要介绍是“编辑商品”这个功能。当我们正常发布商品(选择“上架”且不需“审核”)时,该商品

  在发布之后,会重定向到“商品显示”页面,如下图:

 

 

 

   

      当我们点击“编辑商品”链接后,会进入商品编辑页面,如下

 

 

      
      大家可能看出了,这个页面与添加页面的差异不大,主要是(如果有附件的话)多了编辑附件的功能。
  而这部分差异也体现在了editgoods.cs文件中,因为这里面的代码逻辑有些复杂,主要是判断用户是否修
  改过附件信息(如阅读权限,上传文件)等,以便进行更新或删除已废掉的附件内容等:

 
//编辑帖子时如果进行了批量删除附件
string delAttId = DNTRequest.GetFormString("deleteaid");
if (delAttId != string.Empty)
{
    
if (Utils.IsNumericArray(delAttId.Split(',')))//如果要删除的附件ID列表为数字数组
    {
        GoodsAttachments.DeleteGoodsAttachment(delAttId);

    }
}
//编辑帖子时如果进行了更新附件操作
string updatedAttId = DNTRequest.GetFormString("attachupdatedid");//被更新的附件Id列表
string updateAttId = DNTRequest.GetFormString("attachupdateid");//所有已上传的附件Id列表
string[] descriptionArray = DNTRequest.GetFormString("attachupdatedesc").Split(',');//所有已上传的附件的描述
string[] readpermArray = DNTRequest.GetFormString("attachupdatereadperm").Split(',');//所有已上传得附件的阅读权限

ArrayList updateAttArrayList 
= new ArrayList();
if (updateAttId != string.Empty)
{
    
foreach (string s in updateAttId.Split(','))
    {
        
if (!Utils.InArray(s, delAttId, ","))//已上传的附件Id不在被删除的附件Id列表中时
        {
            updateAttArrayList.Add(s);
        }
    }
}

string[] updateAttArray = (string[])updateAttArrayList.ToArray(typeof(string));

if (updateAttId != string.Empty)//原来有附件
{

    
int watermarkstate = config.Watermarkstatus;

    
if (forum.Disablewatermark == 1)
        watermarkstate 
= 0;

    
string[] updatedAttArray = updatedAttId.Split(',');

    
string filekey = "attachupdated";

    
//保存新的文件
    Goodsattachmentinfo[] attArray = Discuz.Mall.MallUtils.SaveRequestFiles(
                                    goodsinfo.Categoryid, config.Maxattachments 
+ updateAttArray.Length,
                                    usergroupinfo.Maxsizeperday, usergroupinfo.Maxattachsize, MaxTodaySize,
                                    attachextensions, watermarkstate, config, filekey);

    
if (Utils.IsNumericArray(updateAttArray))
    {
           
for (int i = 0; i < updateAttArray.Length; i++//遍历原来所有附件
           {
               
string attachmentId = updateAttArray[i];
               
if (Utils.InArray(attachmentId, updatedAttArray)) //附件文件被更新
               {
                   
if (Utils.InArray(attachmentId, delAttId, ","))//附件进行了删除操作, 则不操作此附件,即使其也被更新
                   {
                       
continue;
                   }
                   
//更新附件
                   int attachmentUpdatedIndex = GetAttachmentUpdatedIndex(attachmentId, updatedAttArray);//获取此次上传的被更新附件在数组中的索引
                   if (attachmentUpdatedIndex > -1)//附件索引存在
                   {
                       
if (attArray[attachmentUpdatedIndex].Sys_noupload.Equals(string.Empty)) //由此属性为空可以判断上传成功
                       {
                           
//获取将被更新的附件信息
                           Goodsattachmentinfo attachmentInfo =

                               GoodsAttachments.GetGoodsAttachmentsByAid(

                                          Utils.StrToInt(updatedAttArray[attachmentUpdatedIndex], 0));

 

 

                           if (attachmentInfo != null)
                           {
                               
if (attachmentInfo.Filename.Trim().ToLower().IndexOf("http"< 0)
                               {
                                   
//删除原来的文件
                                   File.Delete(
                                       Utils.GetMapPath(BaseConfigs.GetForumPath 
+ "upload/" +
                                                        attachmentInfo.Filename));
                               }

                               
//记住Aid以便稍后更新
                               attArray[attachmentUpdatedIndex].Aid = attachmentInfo.Aid;
                               attArray[attachmentUpdatedIndex].Description 
= descriptionArray[i];
                               
int att_readperm = Utils.StrToInt(readpermArray[i], 0);
                               att_readperm 
= att_readperm > 255 ? 255 : att_readperm;
                               attArray[attachmentUpdatedIndex].Readperm 
= att_readperm;
                               attArray[attachmentUpdatedIndex].Categoryid 
= attachmentInfo.Categoryid;
                               attArray[attachmentUpdatedIndex].Goodscount 
= attachmentInfo.Goodscount;
                               attArray[attachmentUpdatedIndex].Goodsid 
= attachmentInfo.Goodsid;

                               GoodsAttachments.SaveGoodsAttachment(attArray[attachmentUpdatedIndex]);
                           }
                       }
                       
else //上传失败的附件,稍后提示
                       {
                           sb.Append(
"<tr><td align=\"left\">");
                           sb.Append(attArray[attachmentUpdatedIndex].Attachment);
                           sb.Append(
"</td>");
                           sb.Append(
"<td align=\"left\">");
                           sb.Append(attArray[attachmentUpdatedIndex].Sys_noupload);
                           sb.Append(
"</td></tr>");
                       }
                   }
               }
               
else //仅修改了阅读权限和描述等
               {
                   
if (Utils.InArray(updateAttArray[i], delAttId, ","))
                   {
                       
continue;
                   }
                   
if ((attachmentlist[i].Readperm.ToString() != readpermArray[i]) ||
                       (attachmentlist[i].Description.Trim() 
!= descriptionArray[i]))
                   {
                       
int att_readperm = Utils.StrToInt(readpermArray[i], 0);
                       att_readperm 
= att_readperm > 255 ? 255 : att_readperm;
                       GoodsAttachments.SaveGoodsAttachment(Utils.StrToInt(updateAttArray[i], 
0), att_readperm,
                                                    descriptionArray[i]);
                   }
               }
           }
     }
}



int watermarkstatus = config.Watermarkstatus;
if (forum.Disablewatermark == 1)
{
    watermarkstatus 
= 0;
}

Goodsattachmentinfo[] attachmentinfo = Discuz.Mall.MallUtils.SaveRequestFiles(forumid, 

            config.Maxattachments, usergroupinfo.Maxsizeperday, usergroupinfo.Maxattachsize, 

            MaxTodaySize, attachextensions, watermarkstatus, config, "postfile");

 

 

if (attachmentinfo != null)
{
    
if (attachmentinfo.Length > config.Maxattachments)
    {
        AddErrLine(
"系统设置为每个商品附件不得多于" + config.Maxattachments + "");
        
return;
    }

    int errorAttachment = GoodsAttachments.BindAttachment(attachmentinfo, goodsinfo.Goodsid, sb, 

                                                                                  goodsinfo.Categoryid, userid);

 

 

    int[] aid = GoodsAttachments.CreateAttachments(attachmentinfo);
    
string tempMessage = GoodsAttachments.FilterLocalTags(aid, attachmentinfo, goodsinfo.Message);
    
if (attachmentinfo.Length == (System.Web.HttpContext.Current.Request.Files.Count-2))
    {
        goodsinfo.Goodspic 
= attachmentinfo[0].Filename;
        goodsinfo.Aid 
= aid[0];
    }
    
if (!tempMessage.Equals(goodsinfo.Message))
    {
        goodsinfo.Message 
= tempMessage;
    }
    Goods.UpdateGoods(goodsinfo);

    UserCredits.UpdateUserCreditsByUploadAttachment(userid, aid.Length 
- errorAttachment);

}
      
 
     当然,如果我们修改了商品分类,则在我们编辑完商品并提交后,系统会对商品原来所在分类进行减1操作,而对所选择
 的目标分类进行加1操作,如下所示(discuz.mall项目的App_Code文件夹下的Goods.cs文件):
 
 
/// <summary>
/// 更新指定商品数据信息
/// </summary>
/// <param name="goodsinfo">商品信息</param>
/// <param name="oldgoodscategoryid">商品分类原值</param>
/// <param name="oldparentcategorylist">商品父分类原值</param>
public static void UpdateGoods(Goodsinfo goodsinfo, int oldgoodscategoryid, string oldparentcategorylist)
{
    
if (goodsinfo.Categoryid != oldgoodscategoryid && goodsinfo.Categoryid >0)
    {
        DbProvider.GetInstance().UpdateCategoryGoodsCounts(goodsinfo.Categoryid, goodsinfo.Parentcategorylist, 
1);
        DbProvider.GetInstance().UpdateCategoryGoodsCounts(oldgoodscategoryid, oldparentcategorylist, 
-1);
    }

    DbProvider.GetInstance().UpdateGoods(goodsinfo);
}

 
 
     当然,如果商品发生“上架”或“下架”变化时,也会执行类似的操作,以确保前台商品列表页面中的商品分类数准备。
 如下(discuz.mall项目的Pages文件夹下的editgoods.cs文件):

 
if (displayorder != goodsinfo.Displayorder) //当发生变化时
{
    
if (displayorder < 0 && goodsinfo.Displayorder > 0//该商品转为上架
    {

        DbProvider.GetInstance().UpdateCategoryGoodsCounts(goodsinfo.Categoryid, 

                                                                                  goodsinfo.Parentcategorylist, 1);

    }
    
else if (displayorder >= 0 && goodsinfo.Displayorder < 0//该商品转为下架(或进入回收站/待审核状态)
    {

        DbProvider.GetInstance().UpdateCategoryGoodsCounts(goodsinfo.Categoryid, 

                                                                                  goodsinfo.Parentcategorylist, -1);

    }
}


     当然,我们在管理后台还提供了“分类商品数”数据维护的功能,以确保其数值准确。如下图:

 

 

      

    

     到这时,编辑商品的主要功能介绍完了。下面说一下删除商品的功能。

 

     我们可以在“用户中心”中的“我的商品”下的全部商品中找到删除商品的功能(批量删除),如下图:

 

 

 

     
     
     当系统确认当前用户即是该商品的发布人时,会执行的如下逻辑:     
    
     if (Goods.IsSeller(goodsidlist, userid))
     {
         Goods.DeleteGoods(goodsidlist, 
false);

         SetUrl(
"usercpmygoods.aspx?item=" + item + "&filter=" + filter);
         SetMetaRefresh();
         AddMsgLine(
"操作成功. <br />(<a href=""usercpmygoods.aspx?item=" + item + "&filter=" + filter + """>点击这里返回</a>)<br />");
     }
     
else
     {
         AddErrLine(
"你不是当前商品的卖家,因些无法删除该商品");
         
return;
     }

     
     其中的DeleteGoods方法将会运行如下操作:     
    
/// <summary>
/// 在数据库中删除指定商品
/// </summary>
/// <param name="goodsidlist">商品id列表</param>
/// <param name="subtractCredits">是否减少用户积分(0不减少,1减少)</param>
/// <param name="reserveAttach">是否保留附件</param>
/// <returns>删除个数</returns>
public static int DeleteGoods(string goodsidlist, int subtractCredits, bool reserveAttach)
{
    
if (!Utils.IsNumericArray(goodsidlist.Split(',')))
    {
        
return -1;
    }

    
if (!reserveAttach)
    {
        IDataReader reader 
= DbProvider.GetInstance().GetGoodsAttachmentList(goodsidlist);

        
while (reader.Read())
        {
            
if (reader["filename"].ToString().Trim().ToLower().IndexOf("http"< 0)
            {

                if ((Utils.FileExists(Utils.GetMapPath(BaseConfigs.GetForumPath + "upload/mall/" + 

                                                                  reader["filename"].ToString()))))

                {

                    File.Delete(Utils.GetMapPath(BaseConfigs.GetForumPath + "upload/mall/" + 

                                                                  reader["filename"].ToString()));

 

 

                }
            }
        }
        reader.Close();
        DbProvider.GetInstance().DeleteGoodsAttachments(goodsidlist);
    }

    
foreach (DataRow dr in Goods.GetGoodsList(goodsidlist).Rows)
    {

        DbProvider.GetInstance().UpdateCategoryGoodsCounts(Convert.ToInt32(dr["categoryid"].ToString()), 

                                                                         dr["parentcategorylist"].ToString().Trim(), -1);

    }

    
int reval = DbProvider.GetInstance().DeleteGoods(goodsidlist);

    
return reval;
}
        
      主要是对商品附件的删除,用户积分以及分类商品数等的相关操作,代码比较简单,这里就不多说了:)
      
     
      好了,今天的内容就先到这里了,因为一些细节暂未详细描述,只是粗略的浏览了一遍,如果大家感兴趣
 欢迎在回复中讨论。

 
    


    作者:代震军,daizhj

    网站:http://daizhj.cnblogs.com/

    原文链接:http://www.cnblogs.com/daizhj/archive/2008/08/12/1260333.html

posted @ 2008-08-12 08:57  代震军  阅读(3753)  评论(13编辑  收藏  举报