作者:田超凡
原创博文,严禁复制转载,仿冒必究
项目计划
第三天:
- 前台系统搭建
- 商城首页展示
- Cms系统的实现
- 内容分类管理
- 内容管理
- 前台内容动态展示
1. 商城首页展示
系统架构:
页面位置:
以上静态资源请到我的资源下载并解压:Java高级开发0-1项目实战-青鸟商城-day03静态资源
1.1 工程搭建
可以参考qingniao-manager-web工程搭建
1.2 功能分析
请求的url:/index
Web.xml中的欢迎页配置:
http://localhost:8082/index.html
参数:没有
返回值:String 逻辑视图
@Controller public class IndexController { @RequestMapping("/index") public String showIndex() { return "index"; } } |
2. 首页动态展示分析
内容信息要从数据库中获得
2.1 动态展示分析
- 内容需要进行分类
- 分类下有子分类,需要动态管理。
- 分类下有内容列表
- 单点的内容信息
- 有图片
- 有链接
- 有标题
- 有价格
- 包含大文本类型,可以作为公告
需要一个内容分类表和一个内容表。内容分类和内容表是一对多的关系。
内容分类表,需要存储树形结构的数据。
内容分类表:tb_content_category
内容表:tb_content
需要有后台来维护内容信息。Cms系统。
需要创建一个内容服务系统。可以参考qingniao-manager创建。
qingniao-content:聚合工程打包方式pom
|--qingniao-content-interface jar
|--qingniao-content-Service war
3. 内容服务系统创建
3.1 qingniao-content
3.1.1 Pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qingniao</groupId> <artifactId>qingniao-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.qingniao</groupId> <artifactId>qingniao-content</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <dependencies> <!-- common --> <dependency> <groupId>com.qingniao</groupId> <artifactId>qingniao-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <!-- 配置tomcat插件 --> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>8083</port> <path>/</path> </configuration> </plugin> </plugins> </build> </project> |
3.2 qingniao-content-interface
3.2.1 Pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qingniao</groupId> <artifactId>qingniao-content</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>qingniao-content-interface</artifactId> <dependencies> <dependency> <groupId>com.qingniao</groupId> <artifactId>qingniao-manager-pojo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project> |
3.3 qingniao-content-service
3.3.1 Pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.qingniao</groupId> <artifactId>qingniao-content</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>qingniao-content-service</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.qingniao</groupId> <artifactId>qingniao-manager-dao</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.qingniao</groupId> <artifactId>qingniao-content-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- spring的依赖 --> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!-- dubbo相关 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <exclusions> <exclusion> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>netty</artifactId> <groupId>org.jboss.netty</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> </dependencies> </project> |
3.4 框架整合
参考qingniao-manager
4. Cms系统实现
4.1 内容分类管理
4.1.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)}]
业务逻辑:
- 取查询参数id,parentId
- 根据parentId查询tb_content_category,查询子节点列表。
- 得到List<TbContentCategory>
- 把列表转换成List<EasyUITreeNode>
Dao层
使用逆向工程
Service
参数: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; } } |
发布服务
表现层
引用服务
qingniao-manager-web
依赖taotao-content-interface模块
Controller
@Controller public class ContentCategoryController { @Autowired private ContentCategoryService contentCategoryService;
@RequestMapping("/content/category/list") @ResponseBody public List<EasyUITreeNode> getContentCategoryList(@RequestParam(value="id",defaultValue="0")long parentId){ List<EasyUITreeNode> list = contentCategoryService.getContentCategoryList(parentId); return list; } } |
4.1.2 新增节点
功能分析
请求的url:/content/category/create
请求的参数:
Long parentId
String name
响应的结果:
json数据,QingNiaoResult,其中包含一个对象,对象有id属性,新生产的内容分类id
业务逻辑:
- 接收两个参数:parentId、name
- 向tb_content_category表中插入数据。
- 创建一个TbContentCategory对象
- 补全TbContentCategory对象的属性
- 向tb_content_category表中插入数据
- 判断父节点的isparent是否为true,不是true需要改为true。
- 需要主键返回。
- 返回QingNiaoResult,其中包装TbContentCategory对象
Dao层
可以使用逆向工程。
需要添加主键返回:
注意:修改完代码后,需要向本地仓库安装qingniao-manager-dao包
Service层
参数:parentId、name
返回值:返回QingNiaoResult,其中包装TbContentCategory对象
@Override public TaotaoResult addContentCategory(long parentId, String name) { // 1、接收两个参数:parentId、name // 2、向tb_content_category表中插入数据。 // a)创建一个TbContentCategory对象 TbContentCategory tbContentCategory = new TbContentCategory(); // b)补全TbContentCategory对象的属性 tbContentCategory.setIsParent(false); tbContentCategory.setName(name); tbContentCategory.setParentId(parentId); //排列序号,表示同级类目的展现次序,如数值相等则按名称次序排列。取值范围:大于零的整数 tbContentCategory.setSortOrder(1); //状态。可选值:1(正常),2(删除) tbContentCategory.setStatus(1); tbContentCategory.setCreated(new Date()); tbContentCategory.setUpdated(new Date()); // c)向tb_content_category表中插入数据 contentCategoryMapper.insert(tbContentCategory); // 3、判断父节点的isparent是否为true,不是true需要改为true。 TbContentCategory parentNode = contentCategoryMapper.selectByPrimaryKey(parentId); if (!parentNode.getIsParent()) { parentNode.setIsParent(true); //更新父节点 contentCategoryMapper.updateByPrimaryKey(parentNode); } // 4、需要主键返回。 // 5、返回TaotaoResult,其中包装TbContentCategory对象 return TaotaoResult.ok(tbContentCategory); } |
发布服务。
表现层
请求的url:/content/category/create
请求的参数:
Long parentId
String name
响应的结果:
json数据,TaotaoResult
@RequestMapping("/content/category/create") @ResponseBody public QingNiaoResult addContentCategory(long parentId,String name){ return contentCategoryService.addContentCategory(parentId, name); } |
4.1.3 内容分类重命名、删除
重命名
请求的url:/content/category/update
参数:id,当前节点id。name,重命名后的名称。
业务逻辑:根据id更新记录。
返回值:返回QingNiaoResult.ok()
删除节点
请求的url:/content/category/delete/
参数:id,当前节点的id。
响应的数据:json。QingNiaoResult。
业务逻辑:
- 根据id删除记录。
- 判断父节点下是否还有子节点,如果没有需要把父节点的isparent改为false
- 如果删除的是父节点,子节点要级联删除。
两种解决方案:
- 如果判断是父节点不允许删除。
- 递归删除。
4.2 内容管理
4.2.1 功能点分析
- 内容列表查询
- 新增内容
- 编辑内容
- 删除内容
4.2.2 内容列表查询
请求的url:/content/query/list
参数:categoryId 分类id
响应的数据:json数据
{total:查询结果总数量,rows[{id:1,title:aaa,subtitle:bb,...}]}
EasyUIDataGridResult
描述商品数据List<TbContent>
查询的表:tb_content
业务逻辑:
根据内容分类id查询内容列表。要进行分页处理。
4.2.3 新增内容
功能分析
新增内容,必须指定一个内容分类。
提交表单请求的url:/content/save
参数:表单的数据。使用pojo接收TbContent
返回值:QingNiaoResult(json数据)
业务逻辑:
1、把TbContent对象属性补全。
2、向tb_content表中插入数据。
3、返回QingNiaoResult
Dao
逆向工程
Service
参数:TbContent
返回值:QingNiaoResult
@Override public QingNiaoResult addContent(TbContent content) { // TODO Auto-generated method stub content.setCreated(new Date()); content.setUpdated(new Date()); contentMapper.insert(content); return QingNiaoResult.ok(); } } |
发布服务
引用服务
Toatao-manager-web工程中引用。
Controller
提交表单请求的url:/content/save
参数:表单的数据。使用pojo接收TbContent
返回值:TaotaoResult(json数据)
@RequestMapping("/content/save") @ResponseBody public QingNiaoResult addContent(TbContent content){ return contentService.addContent(content); } |
5. 首页轮播图展示
qingniao-portal-web工程中,动态展示内容信息。
5.1 功能分析
只需要动态生成一个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 } ] |
从tb_content表中取数据,根据内容分类id查询列表。内容分类id固定,需要配置在属性文件中。
List<TbContent>
图片的width、height配置在属性文件中。
Alt属性从title中取。
Src->pic
srcB->pic2
Href->url
需要创建一个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; } |
5.2 Dao层
从tb_content表中取数据,根据内容分类id查询列表。
可以使用逆向工程
5.3 Service层
参数: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; } |
5.3.1 发布服务
5.4 表现层
Taotao-portal-web中实现。
5.4.1 引用服务
5.4.2 Controller
在首页展示之前,对数据进行处理,然后展示首页,需要在IndexController中实现。
@Controller public class IndexController {
@Value("${AD1_CATEGORY_ID}") private long AD1_CATEGORY_ID; @Value("${AD1_WIDTH}") private String AD1_WIDTH; @Value("${AD1_WIDTH_B}") private String AD1_WIDTH_B; @Value("${AD1_HEIGHT}") private String AD1_HEIGHT; @Value("${AD1_HEIGHT_B}") private String AD1_HEIGHT_B; @Autowired private ContentService contentService; @RequestMapping("/index") public String showIndex(Model model){ List<TbContent> list = contentService.getContentList(AD1_CATEGORY_ID); List<BigAD> ads = new ArrayList<>(); for(TbContent content : list){ BigAD ad = new BigAD(); ad.setAlt(content.getTitle()); ad.setHref(content.getUrl()); ad.setSrc(content.getPic()); ad.setSrcB(content.getPic2()); ad.setHeight(AD1_HEIGHT); ad.setHeightB(AD1_HEIGHT_B); ad.setWidth(AD1_WIDTH); ad.setWidthB(AD1_WIDTH_B); ads.add(ad); } String json = JsonUtils.objectToJson(ads); model.addAttribute("ad1",json); return "index"; } } |
原创博文,严禁复制转载,仿冒必究