毕业生网上跳蚤市场的设计与实现--毕设作品

5 系统详细设计

5.1 系统接口以及Action的抽取

由于各模块块之间存在一些几乎相同的操作,例如对于POJO对象的增加、删除、更改、查询操作,如果每次都重写,将会十分麻烦,因此,我们将这些方法形成接口,封装起来,并且使用泛型的方法,让它得到复用,之后,我们再为这些接口实现统一的实现方法。

首先,我们新建BaseService接口,封装保存、更新、删除、根据id查询和查询所有数据5个方法。

public interfaceBaseService<T> {

  void save(T t);

  void update(T t);

  void delete(int id);

  T get(int id);

  List<T> query();

}

新建BaseServiceImp实现BaseService,并在构造方法中获取子类的泛型对象类型,并且封装一个获取Hibernate中当前Session的getSession方法,然后,重写相应的方法。

ParameterizedType type = (ParameterizedType) this.getClass()

                               .getGenericSuperclass();

   clazz = (Class) type.getActualTypeArguments()[0];

@Override

  public void delete(int id) {

  String hql = "delete from " + clazz.getSimpleName() +" where id=:id";

  getSession().createQuery(hql).setInteger("id", id).executeUpdate();

  }

  @Override

  public T get(int id) {

     return (T)getSession().get(clazz, id);

  }

  @Override

  public List<T>query() {

     String hql = "from " + clazz.getSimpleName();

     returngetSession().createQuery(hql).list();

   }

最后,是对Action的抽取。为BaseAction实现RequestAware、SessionAware和ApplicationAware三个接口,用于实现对请求级、会话级和应用级的缓存数据存储。重写相应方法,新建request、session和application三个键值对,分别用于存储相应需求的缓存数据。同时,实现ModelDriven<T>接口,重写getModel方法,提供T类型的model对象,方便我们操作POJO,以后在请求中直接获取要操作的对象,使用泛型让子类实现时返回其类型,方便model进行转化。

将所有实现了BaseService的Service接口在BaseAction中定义。并且,BaseAction提供FileImage对象,方便存储用户发布商品时上传的照片。提供jsonList列表对象、InputStream流对象以及jsonMap映射表对象,分别用于在Action中返回列表形式的json对象、返回流信息和返回键值对形式的json信息。提供ids字符串,用于接收管理员要删除的相应数据的编号集合。提供page和rows两个字符串,用于记录页码和每页的数据量,实现后台分页查询功能。

以上所有BaseAction提供的对象,都是用protected声明,方便子类继承,并且提供get和set方法,方便Spring调用。

5.2 前台显示模块的设计与实现

前台显示模块分为游客前台显示界面和注册用户显示界面两种,分别如下图5-1和5-2所示。服务器会在启动时,自动读取数据库中的所有商品种类和部分商品信息,如果此类商品是热点商品,那么,取出此种类下最新的四条数据显示在主页面,并且每小时,系统会自动刷新,重新读取数据,并且刷新界面。实现方法如下:

首先,在web.xml中添加监听器,用于初始化数据。

<listener>

<listener-class>cn.it.listener.InitDataListener</listener-class>

</listener>

然后,新建InitDataListener类,实现ServletContextListener接口,重写contextInitialized方法。

public void contextInitialized(ServletContextEvent event) {

  context = WebApplicationContextUtils.getWebApplicationContext(event

            .getServletContext());

   productTimerTask= (ProductTimerTask) context.getBean("productTimerTask");

  productTimerTask.setApplication(event.getServletContext());

new Timer(true).schedule(productTimerTask,0, 1000*60*60);

}

新建ProductTimerTask工具类,继承TimerTask类,重写run方法,并且提供Servlet上下文对象application和商品、种类和订单三个接口对象。在run方法中,我们根据商品类别是否是热点查询返回一个商品类别数组,遍历数组,通过商品类别的编号查询出相应类别下最新上架的四条商品数据,并且,将这四条商品数据,加入bigList数组。查询商品所有类别,加入typeList数组。然后,我们将bigList和typeList通过application的setAttribute方法,加入缓存。

在jsp页面中,我们通过applicationScope获取bigList和typeList列表,并通过<c:forEach>标签遍历数组。由于bigList存放也是list,因此,我们需要嵌套<c:forEach>进行二次循环读取。当我们点击商品图片或者种类时,触发相应action分别返回商品的具体信息界面和此类别下所有商品信息页面。

类别列表:

<c:forEachitems="${applicationScope.typeList}"

var="list" varStatus="status">

<a href="product_queryByType.action?

id=${status.count}">${list.type}</a>

</c:forEach>

商品列表:

<c:forEachitems="${applicationScope.bigList}" var="list">

...

<h2>${list[0].category.type}</h2>

<c:forEachitems="${list}" var="product">

<ul><li>    <a href="${shop}/product_get.action?id=${product.id}">

<imgsrc="${shop}/image/${product.pic}" /></a>

<div>...</div>    </li></ul>

</c:forEach>

</c:forEach>

图5-1游客前台显示界面

图5-2 注册用户前台显示界面

5.3 用户注册模块的设计与实现

在游客前台首页点击“注册”按钮之后。进入注册界面。在注册界面,用户需要填写登录名,密码,真实姓名,性别,邮箱以及电话等基本信息,如图5-3所示。其中,我们使用JQuery-Validate来实现对输入数据的验证功能。其中除邮箱之外,其他数据都是必填的,当输入登录名之后,系统会返回action请求去后台查询当前输入的用户名是否存在,密码的长度被限制在6到12位,确认密码必须和密码保持一致。如果验证不正确,将在数据最后提示自定义的错误信息,即将错误信息,自定义显示到表格当前行的最后一列中。在后台的action中,除了保存用户信息之外,还需要为此用户新建一个权限,添加权限记录,并且将用户信息加入session,方便之后提取当前用户信息。

前台界面:

   $(function() {

       $("#ff").validate({

          onKeyup : true,

          errorPlacement:function(error,element){

             $(element).parent().next().html(error);

          },

          rules : {

              login : {

                 required : true,

                 remote : {

                     url : 'user_loginValidate.action',

                     type : "post"

                 }

              },

              pwd : {

                 required : true,

                 rangelength : [ 6, 12 ]

              },

              cpwd : {

                 required : true,

                 equalTo : "#pwd"

              },

              …

          },

          messages : {

              login : {

                 required : "请输入登录名",

                 remote : "登录名已存在"

              },…

          }

       });

   });

</script>

后台:

publicString register() {

       userService.save(model);

       session.put("user", model);

       Ulimit limit = new Ulimit();

       limit.setAddComment(true);

       limit.setAnsComment(true);

       limit.setUser(model);

       limitService.save(limit);

       return "loginindex";

   }

publicString loginValidate() {

       List<User> userList =userService.query();

       if (userService.loginValidate(model,userList)) {

          inputStream = newByteArrayInputStream("false".getBytes());

       } else {

          inputStream = newByteArrayInputStream("true".getBytes());

       }

       return "stream";

   }

 

 

 

 

 

 

 

 

 

 

 

图5-3用户注册页面

5.4 用户登录模块的设计与实现

点击游客前台界面的“登录”按钮,进入用户登录界面,如图5-4所示。在用户登录界面中输入账号和密码之后,提交action请求,后台查询用户名密码是否正确,如果正确,进入注册用户前台界面,如果不正确,刷新当前界面,显示登录错误信息。

由于系统支持游客选购商品,但在结账时需要账户信息,所以,点击登录之后,会出现两种情况的跳转。一种是直接返回注册用户前台界面,另一种,则是返回账单确定界面。我们使用url地址重定位的方式解决这个问题。

首先,我们需要在web.xml中添加过滤器。

<filter>

       <filter-name>userFilter</filter-name>

       <filter-class>cn.it.filter.UserFilter</filter-class>

   </filter>

   <filter-mapping>

       <filter-name>userFilter</filter-name>

       <url-pattern>/user/*</url-pattern>

   </filter-mapping>

新建一个过滤器,继承Filter,重写doFilter方法。获取当前action请求要去的url地址,用于订单确认界面在内网中,因此,我们要将url地址改写成send_*_*的格式,手动将请求转发到内网下,并将地址保存到goUrl中,存储进request中。当然,如果用户还没有登录,我们直接转发原请求即可。

@Override

publicvoid doFilter(ServletRequest request, ServletResponse response,

       FilterChain chain) throws IOException,ServletException {

       HttpServletRequest req =(HttpServletRequest) request;

       HttpServletResponse res =(HttpServletResponse) response;

       String goUrl = req.getServletPath();

       String param = req.getQueryString();

       String[] split =goUrl.split("/");

       String name = split[2].substring(0,split[2].lastIndexOf("."));

       goUrl = "/send_" + split[1] +"_" + name + ".action";

       if (param != null) {

          goUrl += goUrl + "?" +param;

       }

       req.getSession().setAttribute("goUrl",goUrl);

       if (req.getSession().getAttribute("user")== null) {

       req.getSession().setAttribute("error","非法请求,请登录!");

          res.sendRedirect(req.getContextPath()+ "/ulogin.jsp");

       } else {

          res.sendRedirect(req.getContextPath()+ goUrl);

       }

    }

      

 

 

 

 

 

 

 

 

 

 

 

图5-4用户登录界面

5.5 账户管理模块的设计与实现

用户登录之后,在注册用户前台,可以点击“账户管理”进入账户管理界面,如图5-5所示,在此界面中,我们可以修改我们当前用户的密码。首先,我们输入旧密码,当点击更新按钮之后,系统会取出session中存储的用户信息进行比对,如果一致,则将用户信息中的密码更改,并且通过Service保存POJO对象。反之,不保存。更新成功之后,返回游客前台界面。

 

 

 

 

 

 

 

 

 

图5-5 用户账户管理界面

5.6 商品发布模块的设计与实现

用户登陆后,点击“发布商品”进入商品发布界面,如图5-6所示。按照提示输入相应的商品信息,同样利用JQuery-Validation进行验证,商品价格必须为数字且大于0,商品图片的后缀名必须为jpeg、jpg或者png,所有字段都是必填字段。当点击“发布”之后,action保存商品信息,但此时“推荐”和“有效”均为false,当后台管理员审核之后,才有可能在前台显示。

 

 

 

 

 

 

 

 

 

 

 

图5-6 商品发布界面

5.7 购物车模块的设计与实现

用户登陆之后,点击“购物车”,进入购物车管理界面,如图5-7所示。此界面中显示当前用户目前已加入购物车中的商品,并且计算总共的价格。最右边的叉叉,点击之后,会通过商品id,从购物车中删除当前选中的商品。点击下方的“继续购物”按钮,返回注册用户前台继续选购商品,点击“清空购物车”按钮,清空当前购物车中所有购物项,即新建一个Forder放入session中。

图5-7购物车界面

5.8 订单确认模块的设计与实现

当用户确定要购买购物车中的商品时,点击“结账”按钮,在判定已登录情况下会返回订单确认界面,如图5-8所示。页面会显示当前购物车中的购物项信息,用户填写订单的相应信息之后,点击“确认无误,购买”,就可以进入支付界面,同时,我们保存用户的订单信息到数据库,当用户支付完成之后,我们将订单的状态从“未支付”改为“已支付”。同时,我们将当前Forder放入application中的oldForderSet中,方便在订单管理模块对订单进行操作。

由于同一个用户可能选购不同用户发布的商品,所以,我们需要在保存订单时,将不同用户发布的商品进行分类,形成不同的订单保存。同样的,由于,我们在页面中输入的数据,出入后台会保存到model中,而model中保存的sorderSet和我们获取的sorderSet并不是一个对象,我们需要新建一个Forder,然后将所有的值赋给这个Forder,最后保存这个Forder对象。

图5-8 订单确认界面

5.9 订单管理模块的设计与实现

用户登陆之后,点击“订单管理”进入订单管理界面,如图5-9所示。在订单管理界面中,会显示当前用户下,购买的并且已发货的订单以及购买的并且已经付款的订单。显示订单的编号,以及此订单编号下的购物项的具体信息。这些信息都是在用户登录时,根据用户的信息,查询application中的oldForderSet得到的,然后,在页面中通过<c:forEach>遍历展示。

当点击“确认收货”或者“确认发货”之后,后台根据oldForderSet中的信息,以及当前用户的信息,查询到其中相应的Forder,然后更改他们的订单状态,如果是“确认收货”则将订单状态从3变为4,如果是“确认发货”,则将订单状态从2变为3。然后更新相应的Forder对象,重新将oldForderSet放入application中,方便下次使用。

图5-9 订单管理界面

5.10 留言及回复模块的设计与实现

用户在登陆后,可以点击相应的商品图片,进入商品详细介绍页面,如图5-10所示,点击“留言”按钮,可以进入留言界面进行留言。用户留言时,如果此商品的发布用户是当前用户,用户的留言不会被保存。

图5-10 用户留言界面

在注册用户首页中,点击“留言回复”按钮,进入留言回复界面,如图5-11所示。此页面会显示当前用户留言的回复信息,以及其他用户对本用户发布商品的留言信息。用户在输入回复信息之后,点击“回复”按钮即可。同时,从session中获取留言列表,删除当前留言记录,并设置此对象的回复字段为true,更新留言记录,保存新的留言列表到session中。

图5-11 用户留言回复界面

5.11 后台模块的设计与实现

后台模块主要实现类别管理、商品管理、用户管理、留言管理和权限管理等功能。由于这些模块的功能相似,我们选择最具典型的类别管理进行说明,其他的模块不再进行说明。

首先,后台我们使用easyUI的框架进行搭建。分为三部分,左边显示后台系统的所有功能,当点击某一个功能时,页面进行Ajax请求跳转,在中间部分显示相应的界面,如果请求的界面存在,则选中请求的界面,如果不存在,则新建一个页面,并跳转到此界面。

代码如下:

$(function() {

$("a[title]").click(function(){

var text = $(this).text();

var href = $(this).attr("title");

if ($("#tt").tabs("exists", text)){

$("#tt").tabs("select", text);

} else {

$("#tt").tabs("add",

{ closable : true,

title : text,

content :

'<iframe title='+ text +'src='+ href +' frameboder="0"

width="100%"height="100%"/>'

});

}});

});

类别管理模块主要实现管理员对商品类别的增加,删除,更新操作,如图5-12所示。这个界面主要就是存放一个datagrid组件,将后台查询的数据以jsonMap的形式传到前台,其中包含总的记录数以及json数据。

点击“添加类别”,出现添加类别界面,如图5-13所示,同时会锁住全屏。实现方法为,在父页面中隐藏一个窗体,在子页面中调用父页面的窗体并显示,其中我们用<iFrame>将我们自己做的界面放入窗体中,实现窗体的复用。

点击“更新类别”按钮时,必须选择一条记录,不能不选择,也不能选择多条记录。之后跟新建一样出现“更新类别”界面,如图5-14所示,并且通过Ajax请求实现回写。

点击“删除类别”按钮,页面执行ajax请求,将选中的一条或者多条记录的id打包成ids返回给action,service根据ids删除相应的记录,刷新界面。

在搜索栏中输入要查询的类别,点击搜索按钮,发出ajax请求,根据查询类别名称模糊查询相应记录,从后台以jsonList的格式传到前台。

实现代码:

$(function() {$("#dg").datagrid(

{url : 'category_queryToJson.action',       type : ""},

idField : 'id',

...

pageSize : 5,

pageList : [ 5, 10, 15, 20 ],

toolbar : [{

iconCls : 'icon-add',

text : '添加类别',

handler : function() {

parent.$("#win").window({     

title : "添加类别",

...

content : '<iframe src="send_category_save.action"   … />'

});}},'-',

{ iconCls : 'icon-edit',

text : '更新类别',

handler : function() {

var rows = $('#dg').datagrid('getSelections');

if(rows.length!=1){

$.messager.show({...});

}else{

parent.$("#win").window({

title : "更新类别",

...

content : '<iframesrc="send_category_update.action " … />'

});}}},'-',

{iconCls : 'icon-remove',

text : '删除类别',

handler : function() {

var rows = $('#dg').datagrid(

if (rows.length== 0) {

$.messager.show({

...

});} else {

$.messager.confirm('删除确认对话框','是否要删除选中的记录?',

function(r) {

if (r) {

var ids ="";

for (var i = 0;i < rows.length; i++) {

ids +=rows[i].id+ ",";

}

ids =ids.substring(0,ids.lastIndexOf(","));

$.post("category_deleteByIds.action",{ids: ids},

function(result){

if (result =="true") {

$('#dg').datagrid('uncheckAll');

$('#dg').datagrid('reload');

} else {...

});} },"text");}});

}}}, '-',

{text : "<input id='ss' name='type'/>"} ],

columns : [ [

{field : 'xyz',

checkbox : true

},

{field : 'id',

title : '编号',

width : 200

},   ...  ] ]});

$("#ss").searchbox({

searcher : function(value, name) {

    $('#dg').datagrid('load',{type : value});

},

prompt : '请输入要查询的类别'});

});

其他的四个模块中,商品管理模块主要实现对商品信息的更新和删除操作,用户管理模块主要实现对用户信息的更新和删除操作,留言管理模块主要实现对留言信息的删除操作,权限管理主要实现对用户权限的更新操作。

图5-12 后台类别管理界面

图5-13 添加类别界面

图5-14 更新类别界面
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
跳蚤市场管理系统主要是为了方便用户在网上发布二手物品信息,从而实现二手物品的交易。以下是一个简单的跳蚤市场管理系统的设计实现: 1.用户管理模块 用户管理模块主要是为用户提供注册、登录、修改个人信息等功能。用户注册成功后,系统会为其生成一个唯一的用户ID,用户可以使用该ID进行登录和管理个人信息。 2.商品管理模块 商品管理模块主要是为用户提供发布、修改、删除商品信息的功能。用户可以在系统中发布二手商品的信息,包括商品名称、描述、价格、照片等。发布后,其他用户可以在系统中查看商品信息并进行购买。 3.交易管理模块 交易管理模块主要是为用户提供购买、下单、付款等功能。当用户在系统中选择要购买的商品后,可以通过交易管理模块下单并进行付款。卖家在收到订单后,可以进行发货等操作。 4.评价管理模块 评价管理模块主要是为用户提供对交易的评价功能。用户可以在交易完成后对卖家进行评价,评价内容包括商品质量、卖家服务等。评价结果会在系统中显示,并对卖家的信誉进行评估。 5.搜索管理模块 搜索管理模块主要是为用户提供快速搜索商品的功能。用户可以在系统中输入关键词对商品进行搜索,系统将返回与关键词相关的商品信息。 以上是跳蚤市场管理系统的简单设计实现,实际系统中还需要考虑到安全、性能、可扩展性等因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值