美文网首页
taotao 商城 -4

taotao 商城 -4

作者: LiuliuZhang | 来源:发表于2018-02-07 15:46 被阅读0次

    1 商城首页

    1.1 工程搭建

    创建taotao-portal-web工程,web.xml拦截<url-pattern>*.html</url-pattern>,css/js等文件放到webapp下将不被拦截,因此不需要在springmvc.xml中配拦截器

    1.2 首页展示

    一般不直接展示,通过controller forward到jsp上。web.xml中配置首页<welcome-file>index.html</welcome-file>,如果只访问域名不加后缀,系统找不到该文件,将被拦截器拦截

    @Controller
    public class IndexController {
        @RequestMapping("/index")
        public String showIndex(Model model) {
            return "index";
        }
    }
    

    2 CMS系统实现

    2.1 项目分析

    内容信息从数据库中获得,需要一个内容分类表和一个内容表,内容分类表存储树形结构的数据,内容表存储图片/链接/标题/价格/大文本类型。
    创建一个内容服务系统

    Taotao-content:聚合工程打包方式pom
    |--taotao-content-interface jar
    |--taotao-content-Service  war
    

    2.2 内容分类管理

    2.2.1 内容分类展示

    功能分析
    请求的url:/content/category/list
    请求的参数:id,当前节点的id(第一次请求是没有参数,需要给默认值“0”)
    响应数据:List<EasyUITreeNode>(@ResponseBody)

    Json数据。
    [{id:1,text:节点名称,state:open(closed)},
    {id:2,text:节点名称2,state:open(closed)},
    {id:3,text:节点名称3,state:open(closed)}]
    
    <div>
         <ul id="contentCategory" class="easyui-tree"></ul>
    </div>
    ...
    <script type="text/javascript">
    $(function(){
        $("#contentCategory").tree({
            url : '/content/category/list',
            animate: true,
            method : "GET",
            onContextMenu: function(e,node){
                e.preventDefault();
                $(this).tree('select',node.target);
                $('#contentCategoryMenu').menu('show',{
                    left: e.pageX,
                    top: e.pageY
                });
            },
    

    业务逻辑:
    1、取查询参数id,parentId
    2、根据parentId查询tb_content_category,查询子节点列表。
    3、得到List<TbContentCategory>
    4、把列表转换成List<EasyUITreeNode>
    DAO层
    使用逆向工程
    在common项目中创建返回结构的POJO EasyUITreeNode

    public class EasyUITreeNode implements Serializable{
        private long id;
        private String text;
        private String state;
        public long getId() {
            return id;
        }
      ...   
    }
    

    Service层
    创建ContentCategoryServiceImpl,参数:long parentId,返回值:List<EasyUITreeNode>

    @Service
    public class ContentCategoryServiceImpl implements ContentCategoryService {
    
        @Autowired
        private TbContentCategoryMapper contentCategoryMapper;
        
        @Override
        public List<EasyUITreeNode> getContentCategoryList(long parentId) {
            // 1、取查询参数id,parentId
            // 2、根据parentId查询tb_content_category,查询子节点列表。
            TbContentCategoryExample example = new TbContentCategoryExample();
            //设置查询条件
            Criteria criteria = example.createCriteria();
            criteria.andParentIdEqualTo(parentId);
            //执行查询
            // 3、得到List<TbContentCategory>
            List<TbContentCategory> list = contentCategoryMapper.selectByExample(example);
            // 4、把列表转换成List<EasyUITreeNode>ub
            List<EasyUITreeNode> resultList = new ArrayList<>();
            for (TbContentCategory tbContentCategory : list) {
                EasyUITreeNode node = new EasyUITreeNode();
                node.setId(tbContentCategory.getId());
                node.setText(tbContentCategory.getName());
                node.setState(tbContentCategory.getIsParent()?"closed":"open");
                //添加到列表
                resultList.add(node);
            }
            return resultList;
        }
    }
    

    使用dubbo发布服务,注意端口要与common-service项目区分开

        <!-- 配置包扫描器,扫描所有带@Service注解的类 -->
        <context:component-scan base-package="com.taotao.content.service"/>
        <!-- 发布dubbo服务 -->
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="taotao-content" />
        <!-- 注册中心的地址 -->
        <dubbo:registry protocol="zookeeper" address="192.168.25.175:2181" />
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20881" />
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="com.taotao.content.service.ContentCategoryService" ref="contentCategoryServiceImpl" timeout="300000"/>
    

    表现层
    引用服务:taotao-manager-web项目添加依赖taotao-content-interface,在springmvc.xml文件中,添加服务引用<dubbo:reference interface="com.taotao.content.service.ContentCategoryService" id="contentCategoryService" />
    创建ContentCategoryController

    @Controller
    @RequestMapping("/content/category")
    public class ContentCategoryController {
        @Autowired
        private ContentCategoryService contentCategoryService;  
        @RequestMapping("/list")
        @ResponseBody
        public List<EasyUITreeNode> getContentCatList(
                @RequestParam(value="id", defaultValue="0") Long parentId) {        
            List<EasyUITreeNode> list = contentCategoryService.getContentCategoryList(parentId);
            return list;
        }
    }
    

    2.2.2 新增节点

    功能分析
    请求的url:/content/category/list
    请求的参数:parentId name
    响应的结果: json数据,TaotaoResult,其中包含一个对象,对象有id属性,新生产的内容分类id

    <div>
         <ul id="contentCategory" class="easyui-tree">
        </ul>
    </div>
    <div id="contentCategoryMenu" class="easyui-menu" style="width:120px;" data-options="onClick:menuHandler"> //添加onClick事件
        <div data-options="iconCls:'icon-add',name:'add'">添加</div>    //右击菜单内容
        <div data-options="iconCls:'icon-remove',name:'rename'">重命名</div>
        <div class="menu-sep"></div>
        <div data-options="iconCls:'icon-remove',name:'delete'">删除</div>
    </div>
    <script type="text/javascript">
    $(function(){
        $("#contentCategory").tree({
            url : '/content/category/list',
            animate: true,
            method : "GET",
            onContextMenu: function(e,node){        //右击展示菜单事件,传入事件及该节点
                e.preventDefault();
                $(this).tree('select',node.target);     //当前节点变成选中状态
                $('#contentCategoryMenu').menu('show',{  //菜单的位置
                    left: e.pageX,
                    top: e.pageY
                });
            },
            onAfterEdit : function(node){       //编辑结束触发事件
                var _tree = $(this);
                if(node.id == 0){
                    // 新增节点id为0
                    $.post("/content/category/create",{parentId:node.parentId,name:node.text},function(data){
                        if(data.status == 200){  //返回结果中包含status
                            _tree.tree("update",{
                                target : node.target,
                                id : data.data.id
                            });
                        }else{
                            $.messager.alert('提示','创建'+node.text+' 分类失败!');
                        }
                    });
                }else{
                    $.post("/content/category/update",{id:node.id,name:node.text});
                }
            }
        });
    });
    function menuHandler(item){             //item表示选中哪一项
        var tree = $("#contentCategory");
        var node = tree.tree("getSelected");
        if(item.name === "add"){
            tree.tree('append', {           //{}中内容为新节点定义
                parent: (node?node.target:null),
                data: [{
                    text: '新建分类',
                    id : 0,
                    parentId : node.id
                }]
            }); 
            var _node = tree.tree('find',0);    //找id为0的节点
            tree.tree("select",_node.target).tree('beginEdit',_node.target);    //选中节点,变成可编辑状态
        }else if(item.name === "rename"){
            tree.tree('beginEdit',node.target);
        }else if(item.name === "delete"){
            $.messager.confirm('确认','确定删除名为 '+node.text+' 的分类吗?',function(r){
                if(r){
                    $.post("/content/category/delete/",{parentId:node.parentId,id:node.id},function(){
                        tree.tree("remove",node.target);
                    }); 
                }
            });
        }
    }
    </script>
    

    业务逻辑:
    1、接收两个参数:parentId、name
    2、向tb_content_category表中插入数据。
    a) 创建一个TbContentCategory对象
    b) 补全TbContentCategory对象的属性
    c) 向tb_content_category表中插入数据
    3、判断父节点的isparent是否为true,不是true需要改为true。
    4、需要主键返回。
    5、返回TaotaoResult,其中包装TbContentCategory对象
    DAO层
    可以使用逆向工程。需要添加主键返回,在TbContentCategoryMapper.xml中,在inser及insertSelctive中添加<selectKey>标签

      <insert id="insert" parameterType="com.taotao.pojo.TbContentCategory" >
        <selectKey keyProperty="id" resultType="long" order="AFTER">
            SELECT LAST_INSERT_ID();
        </selectKey>
    

    Service层
    ContentCategoryServiceImpl类添加addContentCategory方法,参数:parentId/name,返回值:TaotaoResult,其中包装TbContentCategory对象

        @Override
        public TaotaoResult addContentCategory(Long parentId, String name) {
            //创建一个pojo对象
            TbContentCategory contentCategory = new TbContentCategory();
            //补全对象的属性
            contentCategory.setParentId(parentId);
            contentCategory.setName(name);
            //状态。可选值:1(正常),2(删除)
            contentCategory.setStatus(1);
            //排序,默认为1
            contentCategory.setSortOrder(1);
            contentCategory.setIsParent(false);
            contentCategory.setCreated(new Date());
            contentCategory.setUpdated(new Date());
            //插入到数据库
            contentCategoryMapper.insert(contentCategory);
            //判断父节点的状态
            TbContentCategory parent = contentCategoryMapper.selectByPrimaryKey(parentId);
            if (!parent.getIsParent()) {
                //如果父节点为叶子节点应该改为父节点
                parent.setIsParent(true);
                //更新父节点
                contentCategoryMapper.updateByPrimaryKey(parent);
            }       
            //返回结果
            return TaotaoResult.ok(contentCategory);
        }
    

    表现层
    请求的url:/content/category/create
    请求的参数: parentId/name
    响应的结果:json数据,TaotaoResult
    ContentCategoryController类添加addContentCategory方法

        @RequestMapping("/content/category/create")
        @ResponseBody
        public TaotaoResult addContentCategory(Long parentId, String name) {
            TaotaoResult result = contentCategoryService.addContentCategory(parentId, name);
            return result;
        }
    

    2.2.3 新增内容

    功能分析
    提交表单请求的url:/content/save
    参数:表单的数据。使用pojo接收TbContent
    返回值:TaotaoResult(json数据)
    业务逻辑:
    1、把TbContent对象属性补全。
    2、向tb_content表中插入数据。
    3、返回TaotaoResult

    //content.jsp中,指定工具栏事件 toolbar:contentListToolbar
    ...
        <div data-options="region:'center'" style="padding:5px">
                <table class="easyui-datagrid" id="contentList" data-options="toolbar:contentListToolbar,singleSelect:false,collapsible:true,pagination:true,method:'get',pageSize:20,url:'/content/query/list',queryParams:{categoryId:0}">
                <thead>
                    <tr>
                        <th data-options="field:'id',width:30">ID</th>
    ...
    
    var contentListToolbar = [{
        text:'新增',
        iconCls:'icon-add',
        handler:function(){
            var node = $("#contentCategoryTree").tree("getSelected");
            if(!node || !$("#contentCategoryTree").tree("isLeaf",node.target)){
                $.messager.alert('提示','新增内容必须选择一个内容分类!');
                return ;
            }
            TT.createWindow({
                url : "/content-add"
            }); 
        }
    },{
        text:'编辑',
        iconCls:'icon-edit',
        handler:function(){
    ...
    
    //content-add.jsp中提交表单
        var contentAddPage  = {
                submitForm : function (){
                    if(!$('#contentAddForm').form('validate')){
                        $.messager.alert('提示','表单还未填写完成!');
                        return ;
                    }
                    contentAddEditor.sync();
                    
                    $.post("/content/save",$("#contentAddForm").serialize(), function(data){
                        if(data.status == 200){
                            $.messager.alert('提示','新增内容成功!');
                            $("#contentList").datagrid("reload");
                            TT.closeCurrentWindow();
                        }
                    });
                },
    

    DAO层
    使用逆向工程
    Service层
    创建ContentServiceImpl类,添加addContent方法,参数:TbContent,返回值:TaotaoResult

    @Service
    public class ContentServiceImpl implements ContentService {
        @Autowired
        private TbContentMapper contentMapper;  
        @Override
        public TaotaoResult addContent(TbContent content) {
            //补全属性
            content.setCreated(new Date());
            content.setUpdated(new Date());
            //插入数据
            contentMapper.insert(content);
            return TaotaoResult.ok();
        }
    
    }
    

    发布服务<dubbo:service interface="com.taotao.content.service.ContentService" ref="contentServiceImpl" timeout="300000"/>
    表现层
    引用服务<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
    创建ContentController

    @Controller
    public class ContentController {
        @Autowired
        private ContentService contentService;
        @RequestMapping("/content/save")
        @ResponseBody
        public TaotaoResult addContent(TbContent content) {
            TaotaoResult result = contentService.addContent(content);
            return result;
        }
    }
    

    2.2.4 首页轮播图展示

    功能分析
    只需要动态生成一个json数据,轮播图就可以动态展示,Json数据格式:

    [
        {
            "srcB": "http://image.taotao.com/images/2015/03/03/2015030304360302109345.jpg",
            "height": 240,
            "alt": "",
            "width": 670,
            "src": "http://image.taotao.com/images/2015/03/03/2015030304360302109345.jpg",
            "widthB": 550,
            "href": "http://sale.jd.com/act/e0FMkuDhJz35CNt.html?cpdad=1DLSUE",
            "heightB": 240
    }
    ]
    

    DAO层
    从tb_content表中取数据,根据内容分类id查询列表。可以使用逆向工程。
    web项目创建一个pojo转换成页面需要的json数据格式

    public class Ad1Node {
        private String srcB;
        private String height;
        private String alt;
        private String width;
        private String src;
        private String widthB;
        private String href;
        private String heightB;
    }
    
    

    Service层
    ContentServiceImpl类添加getContentByCid方法,参数:long categoryId,返回值:List<TbContent>。

    @Override
        public List<TbContent> getContentList(long cid) {
            //根据cid查询内容列表
            TbContentExample example = new TbContentExample();
            //设置查询条件
            Criteria criteria = example.createCriteria();
            criteria.andCategoryIdEqualTo(cid);
            //执行查询
            List<TbContent> list = contentMapper.selectByExample(example);
            return list;
        }
    

    表现层
    Taotao-portal-web中实现,引用服务<dubbo:reference interface="com.taotao.content.service.ContentService" id="contentService" />
    在resource.properties文件中添加内容

    AD1_CATEGORY_ID=89
    AD1_WIDTH=670
    AD1_WIDTH_B=550
    AD1_HEIGHT=240
    AD1_HEIGHT_B=240
    

    在首页展示之前,对数据进行处理,然后展示首页,需要在IndexController中实现。

    @Controller
    public class IndexController {
    
        @Autowired
        private ContentService contentService;
        
        @Value("${AD1_CID}")
        private Long AD1_CID;
        @Value("${AD1_HEIGHT}")
        private Integer AD1_HEIGHT;
        @Value("${AD1_WIDTH}")
        private Integer AD1_WIDTH;
        @Value("${AD1_HEIGHT_B}")
        private Integer AD1_HEIGHT_B;
        @Value("${AD1_WIDTH_B}")
        private Integer AD1_WIDTH_B;
        
        @RequestMapping("/index")
        public String showIndex(Model model) {
            //取轮播图的内容信息
            List<TbContent> contentList = contentService.getContentList(AD1_CID);
            //转换成Ad1NodeList
            List<Ad1Node> ad1List = new ArrayList<>();
            for (TbContent tbContent : contentList) {
                Ad1Node node = new Ad1Node();
                node.setAlt(tbContent.getTitle());
                node.setHeight(AD1_HEIGHT);
                node.setHeightB(AD1_HEIGHT_B);
                node.setWidth(AD1_WIDTH);
                node.setWidthB(AD1_WIDTH_B);
                node.setHref(tbContent.getUrl());
                node.setSrc(tbContent.getPic());
                node.setSrcB(tbContent.getPic2());
                //添加到列表
                ad1List.add(node);
            }
            //把数据传递给页面。
            model.addAttribute("ad1", JsonUtils.objectToJson(ad1List));
            
            return "index";
        }
    }
    
    

    相关文章

      网友评论

          本文标题:taotao 商城 -4

          本文链接:https://www.haomeiwen.com/subject/lcawzxtx.html