ASP.NET网络商店销售管理系统的设计与实现

news2024/9/24 3:22:27

摘  要

随着软件技术的不断进步和发展,信息化的管理方式越来越广泛的应用于各个领域,对于任何网站系统的管理来说开发一套现代化的成员管理软件是十分必要的。通过这样的软件系统,可以做到成员的规范管理和快速查询,从而减少管理方面的工作量。有效的管理所有成员的信息就是成员管理系统完成的功能。销售管理系统是使用MS.NET平台中的ASP.NET开发基于B/S体系结构的Web应用程序,在Microsoft Visual Studio .NET 环境下,使用 C# 编程语言并结合Microsoft SQL Server 2000 数据库开发出一套网络版的销售管理系统。该系统由前端输入和后端管理组成。前端实现了用户注册,用户登录,购物车,定单查询,商品浏览(包括热门商品和新到商品),商品搜索等。后台实现了用户信息管理,管理员信息管理,商品信息管理,销售管理。通过这个系统,可以大大的提高网络管理者的工作效率和工作精度。

关键词网络商店;销售管理系统;模块;控件;C#.NET

1.4相关软件及技术介绍

1.4.1 ASP.NET技术

ASP.NET 是一种建立在通用语言上的程序构架,能被用于一台Web服务器来建立强大的Web应用程序。ASP.NET构架是可以用Microsoft(R)公司最新的产品 Visual Studio开发环境进行开发ASP.NET是基于通用语言的编译运行的程序,可以使它运行在Web应用软件开发者的几乎全部的平台上。通用语言的基本库,消息机制,数据接口的处理都能无缝的整合到ASP.NET的Web应用中。

1.4.2 SQL Server 

SQL Server 是一个具备完全 Web 支持的数据库产品,提供了对可扩展标记语言 (XML) 的核心支持以及在 Internet 上和防火墙外进行查询的能力,提供了以 Web 标准为基础的扩展数据库编程功能。

1.4.3 Visual Studio.net 2003

它是Microsoft推出.NET应用程序开发工具。它易学易用的特性得到很多的好评。Microsoft又推出新版的.NET应用程序开发工具 Visual Studio.NET 2005,加入更多的好用功能,是.net的好开发工具。

2.项目模块及框图

2.1 系统功能模快设计

系统主体采用B/ S(Browser/ Server ,浏览器/ 服务器) 结构,即采用目前分布式系统流行的3 层软件结构,即在传统的客户和服务器之间加入应用服务器(Application server) ,3 层即是表现层(浏览器) 、业务逻辑层(Web 服务器) 、数据层(数据服务器) ,系统简图如图2-1所示。数据服务器与Web 服务器是完全分开的,分开之后的3 层软件结构功能明确:客户层只提供应用程序的用户界面,负责与用户交互;业务逻辑层是应用系统的关键,它负责处理所有用户请求,进行具体的运算和决定程序的流程,并把处理结果返回给表现层;服务器层仍然提供的是数据库支持、维护和更新应用程序的数据。

2.2  网络销售管理流程图

图1 网络销售管理系统数据流程

2.3网络销售管理系统模块组织图

图2A系统模块组织图

图2B系统模块组织图

4.模块设计、分析、开发

4.1主页面设计

主页面是直接展示给用户的部分。在这一模块中,主要包括以下自定义控件和页面的实现:

页面头部控件(HeadMenu.ascx):主要包括登录链接和搜索框

商品分类导航控件(CategoryList.ascx):显示所有商品的列表,作为页面的左侧导航目录。

4.1.1页面头部控件设计

页面头部控件是为了方便用户快速导航到某个页面的,在HeaderMenu.ascx的设计中,具有技巧性的地方是如何展示给登录用户和匿名用户不同的导航条,为了区别登录用户和匿名用户,在HeaderMenu.ascx中将匿名用户所拥有的链接放在一个Span容器中,并将Span设为“Runat=Server”,这样就方便在代码中对去是否可见进行控制。同样,将登录用户需要的链接也放在另一个Span中。另
外,“搜索”也是一个超级链接,但它并非链接到某个Url。而是执行一条JavaScript语句“javascript:searh.submit()”,即把页面提交。如下图所示:

图3登录用户导航条                      图 4匿名用户导航条

控件代码的实现

在HeaderMenu的代码中,主要是判断用户的情况并控制Span容器的可见性。在HeaderMenu.ascx.cs中定义了下面的方法:

void showButton()

              {

                     //是否是匿名用户

                     if (Request.IsAuthenticated != true)

                     {

                            //登录用户区域不可见

                            areaLoggedIn.Visible = false;

                            //匿名用户区域可见

                            areaLoggedOut.Visible = true;

                     }

                     else

{

                            areaLoggedIn.Visible = true;

                            areaLoggedOut.Visible = false;

                     }

               }

这样在窗体加载即执行Pvage_Load()是调用上面的方法就可以实现效果了:

Private void Page_Load(object sender,System.EventArgs e)

{

     showButton();

}

4.1.2 商品分类导航控件的设计

     该控件显示所有商品的分类,单击目录中某个商品类别是将显示相应类别的商品列表页面。在CategoryList.ascx中主要用到了DataList控件,它用来绑定数据源。

控件代码的实现

private void Page_Load(object sender, System.EventArgs e)

              {

                     // 设置目录的选定项

                     string selectionID = Request.Params["selection"];

                     if ( selectionID != null)

           {

                            MyList.SelectedIndex = Int32.Parse(selectionID);

                     }

                     //将数据源绑定至DataList控件

                     MyList.DataSource = BLL.Product.GetCategoryList();

                     MyList.DataBind();

              }

可以看到,MyList的绑定数据源是方法GetCategoryList()的返回值,这个方法在BLL层中的Product类中,他调用数据库的存储过程GetCatergoryList。

4.2 商品信息模块页面

分类显示商品显示某种类型的所有商品。

ProductList.aspx页面的布局和首页基本相似,不同的是,在页面的中心位置放置了一个Reperter控件来绑定数据源,Repeater控件中用一个表格的第一行作为它的HeaderTemplate,而ItemTempmlate项中绑定了数据源的相应字段。“购物”也是通过超级链接来实现页面的传递。主要代码如下:

       //页的大小

              private static int PageSize = 5;

              private void Page_Load(object sender, System.EventArgs e)

              {

                     if (!Page.IsPostBack)

                     {

                            //显示第一页的记录

                            ShowResult(0, PageSize);

                     }

              }

              void ShowResult(int pageIndex, int pageSize)

              {

/绑定Repeater控件

products.DataSource = BLL.Product.GetProductsByCategory(int.Parse(Request.QueryString["categoryId"](pageSize, pageIndex);

                     products.DataBind();

                     //调用Product类中的方法获得该类商品的总数

                      int resultCount = BLL.Product.GetProductCountByCategory(int.Parse(Request.QueryString["categoryId"]));

                     int count;

                     //如果查询结果总数是页大小的整数倍

                     if (resultCount%PageSize == 0)

                     {

                            count = resultCount/PageSize;

                            PageCount.Text = count.ToString();

                     }

                     else

                     {

                            count = resultCount/PageSize+1;

                            PageCount.Text = count.ToString();

                     }

                     page.Items.Clear();

                     //绑定页码到DropDownList控件

                     for(int i=0; i<count; i++)

                     {

                            ListItem item = new ListItem((i+1).ToString(), i.ToString());

                            page.Items.Add(item);

                     }

                     page.SelectedIndex = pageIndex;

              }

4.3 用户信息管理模块设计


4.3.1登录页面设计

图5 用户登录界面

在这个系统中采用Froms验证方式,当自定义的验证程序确认用户身份时,可以让Froms验证系统发出Cookie,Cookie中除了包含验证票据之外,还可以通过程序写入被验证用户的标识信息,比如用户编号,然后使用该Cookie访问个人的信息。Forms验证方式还可以保证有权限要求的页面无法被匿名用户访问。例如,密码修改页面(ChangePwd.aspx)不能被匿名用户访问,要达到上诉目标,需要在配置文件Web。Config里面创建一个项。代码如下:

<!_验证方式为Forms_>

<authentication mode=”Forms”>

  <formsname=”eshop” loginUrl=”signIn.aspx”protecon=”all”path=”/”/>

</authentication>

     需要注意的是,<forms>标记中,name的值为验证系统所发出的Cookie的名称,loginUrl表示匿名用户被重定向到的页面的地址。如何防止ChangPwd不被匿名用户直接访问呢,也需要创建下面的项:

<location path=”ChangePwd.aspx”>

<system.web>

    <authorization>

          <!--拒绝匿名用户-->

          <deny user=”?”/>

  </authorization>

  </system.web>

</location>

同样,用户可以注销验证信息,注销页面(SignOut.aspx)代码如下:

     private void Page_Load(object sender, System.EventArgs e)

              {

                     //注销验证信息

                     System.Web.Security.FormsAuthentication.SignOut();

                     //清空Session

                     Session.Clear();

                     //返回首页

                     Response.Redirect("default.aspx");

            }

4.3.2 注册页面的设计


    注册新用户时候,仅需输入最基本的信息,个人详细资料在注册之后再进行修改,Register.aspx的界面主要是接收一些用户输入的文本框,以及相应的验证控件、“注册”按钮和显示提示信息的Lable控件。

图6 注册页面

代码的实现:通过存储过程AddNewUser实现注册的功能:

CREATE  PROCEDURE AddNewUser

(

         @username nvarchar(50),

         @password nvarchar(50),

         @question nvarchar(50),

         @answer nvarchar(50),

         @result int output

)

AS

      /*是否存在相同的用户名*/

      if not exists (SELECT * FROM USERINFO WHERE USERNAME=@USERNAME )

      BEGIN

            /*插入新的用户记录*/

            INSERT INTO USERINFO (USERNAME, USERPWD, QUESTION, ANSWER)

                   VALUES (@USERNAME, @PASSWORD, @question, @answer)

            /*将Result赋值为新添加用户的UserId*/

            SELECT @result = SCOPE_IDENTITY()

       END

        ELSE

       BEGIN

            SET @RESULT = -1

       END

     该存储过程带有输出参数,如果有相同的用户存在,输出参数为-1,否则,输出的参数的值为该用户的UserID。在User类中定义方法AddNewUser()调用AddNewUser存储过程,

4.4购物车功能的设计与实现

在前面的流程图中,我们可以看到这个购物流程是不允许匿名用户拥有购物车的,匿名用户注册并登录之后,才能使用购物车。登录用户的购物车编号CartID为用户编号。CartID生成过程中用到了Cookie,Cookie是用来保存个人信息的对象,它存在于客户端。针对购物车的功能,设计了ShoppingCart类,其中定义了GetShoppingCartID(),代码如下:

public String GetShoppingCartID()

        {

            HttpContext Context = HttpContext.Current;

// 如果该用户已经通过验证后登录了系统,

那么以该用户的UserID作为购物车ID

            if (Context.User.Identity.Name != "")

            {

                Response.Redirect("/esop/SignIn.aspx");

             }

             if (Context.Request.Cookies["ShoppingCartID"] != null)

            {

                return Context.Request.Cookies["ShoppingCartID"].Value;

             }

在数据库中定义了存储过程ShoppingCartAddItem,实现向购物车添加商品的功能,代码如下:

CREATE Procedure ShoppingCartAddItem

(

    @CartID nvarchar(50),

    @ProductID int,

    @Quantity int

)

As

DECLARE @CountItems int

SELECT

    @CountItems = Count(ProductID)

FROM

    ShoppingCart

WHERE

    ProductID = @ProductID

  AND

    CartID = @CartID

IF @CountItems > 0  /* 该购物车中已有该商品的记录,更新数量 */

    UPDATE

       ShoppingCart

    SET

        Quantity = (@Quantity + ShoppingCart.Quantity)

    WHERE

      ProductID = @ProductID

      AND

        CartID = @CartID

ELSE  /* 该购物车中没有这个商品的记录,插入新记录 */

    INSERT INTO ShoppingCart

    (

        CartID,

        Quantity,

        ProductID

    )

    VALUES

    (

        @CartID,

        @Quantity,

        @ProductID

    )

GO


4.5 购物车的结算设计与实现

图 7 商品结算界面

如果用户的预存款金额不足够支付本次购物,则会出现“存款不足”的提示如果能够支付,则生成新的订单,实现预存款支付订单的存储过程代码如下:CREATE PROCEDURE PayOrder

@userId int,

@totalcost decimal,

@result int output

 AS

       DECLARE @tmp decimal

       /*@tmp为当前用户预存款金额*/

       SELECT @tmp =  acount

       FROM UserInfo

       WHERE userID = @userId

       /*如果预存款不足*/

       IF @tmp <@totalcost

       BEGIN

              /*置标志为-1*/

              SET @result = -1

       END

       /*预存款足够支付,扣除相应的金额*/

       ELSE

       BEGIN

              UPDATE UserInfo

              SET acount = acount -@totalcost

              WHERE userId= @userId

              /*置标志为1*/

              SET @result = 1

       END

GO

4.6查询销售情况页面的设计

 模块的查询支持按月查询、日查询。查询的结果是每种商品的相关的定单数、售出数量和销售收入。页面主要包括3个DropDownList,分别用来选择年、月、日,两个按钮分别进行按月查询和按日查询,以及显示查询的结果的DataGrid。页面第一次加载时,显示日期为当前日期,并绑定到当前的销售情况。


图8销售情况图

代码的实现

查询销售情况的存储过程定义为GetSails,有3个输入参数,分别为@year(年)、@month(月)、@day(日)。当@day为0时,表示查询月记录,否则为查询当日记录。

  在adminDB类中定义GetSails()方法调用上面的GetSails存储过程,并返回记录集。代码如下:

    public  DataSet GetSails(string year, string month, string day)

              {

                     SqlParameter[] para = {

                       new SqlParameter("@year", int.Parse(year)),

                       new SqlParameter("@month", int.Parse(month)),

                       new SqlParameter("@day", int.Parse(day))

                                                                           };

                            return eshop.DAL.SQLHelper.ExecuteDataset(eshop.DAL.SQLHelper.CONN_STRING, CommandType.StoredProcedure, "GetSails", para);

              }

在用户表示层,首先需要绑定选择日期的DropDownList。定义BindDate()方法,代码如下:

void BindDate()

              {

                     //绑定年

                     for (int i=2007; i<2020; i++)

                     {

ListItem item = new ListItem(Convert.ToString(i),Convert.ToString(i));

                      Year.Items.Add(item);

                     }

                     //绑定月

                     for (int i = 1 ; i<13 ; i++)

                     {

ListItem item1 =  new ListItem(Convert.ToString(i),Convert.ToString(i));

                       Month.Items.Add(item1);

                     }

                     //绑定日

                     for (int i=1; i<32; i++)

                     {

                            ListItem item2 =  new;

                            Day.Items.Add(item2);

                     }

              }

此外,定义绑定DataGrid的方法BindGrid():

void BindGrid(string year, string month, string day)

              {

                     GridSails.DataSource = new AdminDB().GetSails(year, month, day);

                     GridSails.DataBind();

              }

在页面加载时间处理方法Page_Load()中对数据进行绑定,并显示当前日期以及当日销售记录:

         private void Page_Load(object sender, System.EventArgs e)

              {

                     if (!Page.IsPostBack)

                     {

                            BindDate();

                            //绑定当天记录

                            BindGrid(DateTime.Now.Year.ToString(), DateTime.Now.Month.ToString(),

DateTime.Now.Day.ToString());

                            //显示为当前日期

                            Year.SelectedValue = DateTime.Now.Year.ToString();

                            Month.SelectedValue =  DateTime.Now.Month.ToString();

                            Day.SelectedValue = DateTime.Now.Day.ToString();

//插入日志

AdminDB.InsertAction("查看当日销售记录", System.DateTime.Now, User.Identity.Name);

                     }

              }

最后,在两个按钮单击事件处理方法中添加绑定数据以及插入日志的代码:

//查询所选日期的月销售记录

         private void QueryMonth_Click(object sender, System.EventArgs e)

              {

BindGrid(Year.SelectedValue, Month.SelectedValue, "0");

AdminDB.InsertAction("查看"+Year.SelectedValue+"年"+Month.SelectedValue+"月"

                            + "的销售记录", System.DateTime.Now, User.Identity.Name);

               }

              //查询所选日期的日销售记录

private void QueryDay_Click(object sender, System.EventArgs e)

{

BindGrid(Year.SelectedValue, Month.SelectedValue, Day.SelectedValue);

AdminDB.InsertAction("查看"+Year.SelectedValue+"年"+Month.SelectedValue+"月"

+ Day.SelectedValue +"日的销售记录",  System.DateTime.Now,User.Identity.Name 

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1645090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具

文章目录 小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具概述笔记效果编译AStyle的DLL初次使用接口的小疑惑测试程序 - 头文件测试程序 - 实现文件测试程序 - RC备注END 小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具 概述 上一个实验(vs2019 - ast…

记对MYSQL蜜罐的溯源反制研究

Mysql蜜罐的利用 Mysql任意文件读取 mysql蜜罐通过搭建一个简单的mysql服务&#xff0c;如果攻击者对目标客户进行3306端口爆破&#xff0c;并且用navicat等工具连接蜜罐服务器&#xff0c;就可能被防守方读取本地文件&#xff0c;包括微信配置文件和谷歌历史记录等等&#x…

LNMP一键安装包

LNMP一键安装包是什么? LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin/Alibaba/Amazon/Mint/Oracle/Rocky/Alma/Kali/UOS/银河麒麟/openEuler/Anolis OS Linux VPS或独立主机安装LNMP(Nginx/MySQL/PHP)、LNMPA(Nginx/MySQ…

sql中索引的使用分析

主要学习和记录sql中索引的使用 1.批量在库里插入了27W条数据 CREATE DEFINERroot% PROCEDURE 批量插入() BEGIN #Routine body goes here... DECLARE i int; SET i1; WHILE (i<100000) DO insert into kucun_info (shop_name,shop_code,shop_price,sh…

C#图像:1.图像区域分割与提取

&#xff08;1&#xff09;创建一个名为SplitImage的窗体的应用程序&#xff0c;将窗体改名为FormSplitImage。 &#xff08;2&#xff09;创建一个名为ImageProcessingLibrary的类库程序&#xff0c;为该工程添加名为ImageProcessing的静态类 &#xff08;3&#xff09;为Imag…

Video2Game:革新游戏开发,重塑虚拟世界的未来

Video2Game&#xff1a;革新游戏开发&#xff0c;重塑虚拟世界的未来 一、Video2Game的提出与意义二、Video2Game的核心技术三、Video2Game的实现与应用四、代码实例与未来展望 在数字化和虚拟化日益盛行的今天&#xff0c;高质量的交互式虚拟环境&#xff0c;如游戏和模拟器&a…

【精品毕设推荐】基于Javaee的影视创作论坛的设计与实现

点击下载原文及代码 摘 要 随着时代的发展&#xff0c;互联网的出现&#xff0c;给传统影视行业带来的最大便利就是&#xff0c;方便了影视从业人员以及爱好者的交流和互动&#xff0c;而为用户提供一个书写影评&#xff0c;阅读影评以及回复影评的平台&#xff0c;以影评为…

云原生专栏丨基于K8s集群网络策略的应用访问控制技术

在当今云计算时代&#xff0c;Kubernetes已经成为容器编排的事实标准&#xff0c;它为容器化应用提供了强大的自动化部署、扩展和管理能力。在Kubernetes集群中&#xff0c;网络策略(Network Policy)作为对Pod间通信进行控制的关键功能&#xff0c;对保障应用安全和隔离性起到了…

R可视化:不同分页界面分组添加显著性标记符号

介绍 对不同分页界面的分组数据添加显著性标记符号,虽然也可以通过ggpubr包的stat_compare_means()添加分组显著性标记符号,但它要求x轴必须是分组变量,不能对fill映射出来的分组做处理。为应对不同分组的fill映射分组,我们需要另寻他法。本文通过geom_text, geom_segment…

Linux编译内核模块生成.KO驱动示例

现在的Linux内核十分庞大&#xff0c;驱动繁多&#xff0c;但是仍有一些是内核所不包含的&#xff0c;或者我们前期进行了内核裁剪&#xff0c;但后面又需要添加一些驱动&#xff0c;但是又不想重新烧录内核&#xff0c;这时候就可以使用内核模块功能&#xff0c;对内核驱动进行…

Linux图形化界面怎么进入?CentOS 7图形界面切换

CentOS 7默认只安装命令行界面。要切换到图形界面&#xff0c;需要先检查系统是否安装图形界面&#xff0c;在终端输入以下命令&#xff1a; systemctl get-default若是返回结果是“multi-user.target”表示系统没有安装图形界面&#xff1b;若是返回结果是“graphical.target…

等保测评—Linux-CentOS标准范例截图

密码输入错误无法登录 用户账户情况包含root、guanli、shenji 查看审计用户权限 身份鉴别&#xff1a; cat /etc/passwd&#xff0c;核查用户名和 UID&#xff0c;是否存在同样的用户名和 UID cat /etc/shadow&#xff0c;查看文件中各用户名状态 &#xff0c; 核查密码一栏为…

文件批量改名字怎么改(怎样批量修改文件名)

文件批量改名字怎么改&#xff08;怎样批量修改文件名&#xff09; 批量重命名文件可以通过多种方法实现&#xff0c;具体取决于用户的操作系统和熟练程度。 以下是一些常见的方法&#xff1a; 下载地址https://download.csdn.net/download/dhyuan_88/89237041 使用操作系统自带…

On Hold 频发!又3本期刊被标记为On Hold ,大家谨慎投递!

【SciencePub学术】On Hold 频发&#xff01;小编在查阅资料的时候发现又有3本期刊被标记为On Hold 了&#xff0c;今天小编给大家详细介绍一下这3本期刊。 来源&#xff1a;科睿唯安官网 Results in Physics 1 期刊概况 【期刊简介】IF&#xff1a;5.3&#xff0c;JCR1区&am…

C++ stack and queue

1. stack模拟实现 CSTL中的栈是一种容器适配器&#xff0c;它是将vector/list进行封装&#xff0c;push/pop等接口直接调用vector/list的接口即可&#xff0c;不需要像C语言那样&#xff0c;从头开始造轮子 namespace byh {template<class T, class Container deque<T&…

python实验二 函数与类的应用

实验二 实验题目 1、请编写一个函数SDSearch(txt, word)&#xff0c;其中&#xff0c;txt是一段文本&#xff0c;word是给定的词汇&#xff0c;函数SDSearch可以找到word在txt中的所有位置&#xff0c;并将它们做为返回值返回&#xff0c;编写函数main()调用SDSearch(txt, wo…

连锁收银系统批量调整商品价格教程

1、进入系统后台&#xff0c;系统后台登录网址&#xff1a; 2、点击商品>商品调价 3、将按模板整理好的商品价格数据导入即可。 Tips&#xff1a;每次导入的商品数量不要超过6000 条。

英语翻译中文,如何找专业的翻译公司?

在国际交流日益频繁的今天&#xff0c;翻译业务如雨后春笋般崭露头角&#xff0c;众多翻译公司如百花争艳般崭露头角。然而&#xff0c;国内翻译公司水平层参不齐。为了确保翻译的质量和准确性&#xff0c;选择一家专业的翻译公司至关重要。那么&#xff0c;英语翻译中文&#…

Case中default的综合结果

在使用case语句时&#xff0c;不完备的case语句会导致Vivado综合时推断出锁存器。下面通过实例来详细看看各种情况下的综合结果&#xff1a; 1.完备的case语句 下述的verilog对应的电路结构是一个8选一的多路复用器&#xff1a; module case_test(input [2:0]sel,input data…

学习如何使用PyQt5实现notebook功能

百度搜索“pyqt5中notebook控件”&#xff0c;AI自动生成相应例子的代码。在 PyQt5 中&#xff0c;QTabWidget 类被用作 Notebook 控件。以下是一个简单的示例&#xff0c;展示如何创建一个带有两个标签的 Notebook 控件&#xff0c;并在每个标签中放置一些文本。 import sys f…