1. 表结构
tb_content_category 广告分类表
字段 | 类型 | 长度 | 含义 |
id | Bigint |
| 主键 |
name | Varchar | 255 | 广告分类名称 |
tb_content 广告表
字段 | 类型 | 长度 | 含义 |
id | Bigint |
| 主键 |
category_id | Bigint |
| 广告分类ID |
title | varchar | 200 | 广告标题 |
url | varchar | 500 | 广告链接 |
pic | varchar | 300 | 图片地址 |
status | varchar | 1 | 状态 |
sort_order | int |
| 排序 |
2. 广告列表
2.1 后端
在pinyougou-manager-web中添加代码,参考之前的方式做就可以了
2.2 前端
参考pinyougou-shop-web中的代码完成
3. 广告管理
3.1 广告图片上传
将pinyougou-shop-web的以下资源拷贝到pinyougou-manager-web
(1)UploadController.java
(2)uploadService.js
(3)application.properties
(4)fdfs_client.conf
在pinyougou-manager-web 的springmvc.xml中添加配置
<!-- 配置多媒体解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值 5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
在contentController.js引入uploadService
在content.html 引入uploadService.js
在contentController.js编写代码
//上传广告图
$scope.uploadFile=function(){
uploadService.uploadFile().success(
function(response){
if(response.success){
$scope.entity.pic=response.message;
}else{
alert("上传失败!");
}
}
).error(
function(){
alert("上传出错!");
}
);
}
修改content.html实现上传功能
<tr>
<td>图片</td>
<td>
<input type="file" id="file">
<button ng-click="uploadFile()">上传</button>
<img alt="" src="{{entity.pic}}" height="100px" width="200px">
</td>
</tr>
列表中显示图片
<img alt="" src="{{entity.pic}}" height="50px" width="100px">
3.2 广告类目选择
将contentCategoryService引入contentController
在content.html 引入contentCategoryService.js
在contentController.js中添加代码
//加载广告分类列表
$scope.findContentCategoryList=function(){
contentCategoryService.findAll().success(
function(response){
$scope.contentCategoryList=response;
}
);
}
在content.html 初始化调用此方法
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="contentController" ng-init="findContentCategoryList()">
将广告分类改为下拉列表
<select class="form-control" ng-model="entity.categoryId" ng-options="item.id as item.name for item in contentCategoryList"></select>
4. 网站首页-广告展示
创建war模块pinyougou-portal-web ,此工程为网站前台的入口,参照其它war模块编写配置文件。不需要添加SpringSecurity框架
pom.xml中配置tomcat启动端口为9103
界面原型与插件的引入
4.1 后端
在pinyougou-content-service工程ContentServiceImpl类增加方法
@Override
public List<TbContent> findByCategoryId(Long categoryId) {
//根据广告分类ID查询广告列表
TbContentExample contentExample=new TbContentExample();
Criteria criteria2 = contentExample.createCriteria();
criteria2.andCategoryIdEqualTo(categoryId);
criteria2.andStatusEqualTo("1");//开启状态
contentExample.setOrderByClause("sort_order");//排序
return contentMapper.selectByExample(contentExample);
}
在pinyougou-portal-web创建控制器类 ContentController
@RestController
@RequestMapping("/content")
public class ContentController {
@Reference
private ContentService contentService;
/**
* 根据广告分类ID查询广告列表
* @param categoryId
* @return
*/
@RequestMapping("/findByCategoryId")
public List<TbContent> findByCategoryId(Long categoryId) {
return contentService.findByCategoryId(categoryId);
}
}
4.2 前端
在pinyougou-portal-web工程创建contentService.js
app.service("contentService",function($http){
//根据分类ID查询广告列表
this.findByCategoryId=function(categoryId){
return $http.get("content/findByCategoryId.do?categoryId="+categoryId);
}
});
在pinyougou-portal-web创建contentController.js
//广告控制层(运营商后台)
app.controller("contentController",function($scope,contentService){
$scope.contentList=[];//广告集合
$scope.findByCategoryId=function(categoryId){
contentService.findByCategoryId(categoryId).success(
function(response){
$scope.contentList[categoryId]=response;
}
);
}
});
界面头文件导入与指令添加
修改首页轮播图
<!--banner轮播-->
<div id="myCarousel" data-ride="carousel" data-interval="4000" class="sui-carousel slide">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="{{$index}}" class="{{$index==0?'active':''}}" ng-repeat="item in contentList[1]" ></li>
</ol>
<div class="carousel-inner">
<div class="{{$index==0?'active':''}} item" ng-repeat="item in contentList[1]">
<a href="{{item.url}}">
<img src="{{item.pic}}" />
</a>
</div>
</div>
<a href="#myCarousel" data-slide="prev" class="carousel-control left">
‹</a><a href="#myCarousel" data-slide="next" class="carousel-control right">›</a>
</div>
测试:
5. 广告缓存的处理
现在我们首页的广告每次都是从数据库读取,这样当网站访问量达到高峰时段,对数据库压力很大,并且影响执行效率。我们需要将这部分广告数据缓存起来
5.1 读取缓存
因为缓存对于我们整个的系统来说是通用功能。广告需要用,其它数据可能也会用到,所以我们将配置放在公共组件层(pinyougou-common)中较为合理
1)依赖的引入
<!-- 缓存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
2)配置文件
3)pinyougou-content-service依赖pinyougou-common
3)修改 pinyougou-content-service的ContentServiceImpl
/* 根据分类ID查询广告
*/
@Override
public List<TbContent> findByCategoryId(Long categoryId) {
List<TbContent> list = null;
try {
list = (List<TbContent>) redisTemplate.boundHashOps("content").get(categoryId);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(null == list){
TbContentExample example = new TbContentExample();
Criteria createCriteria = example.createCriteria();
createCriteria.andCategoryIdEqualTo(categoryId);
// 设置排序字段
example.setOrderByClause("sort_order");
list = contentMapper.selectByExample(example );
try {
// 将查询的数据存入缓存中
redisTemplate.boundHashOps("content").put(categoryId, list);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("数据来自数据库");
} else {
System.out.println("数据来自缓存。。。");
}
return list;
}
5.2 更新缓存
当广告数据发生变更时,需要将缓存数据清除,这样再次查询才能获取最新的数据
5.3.1 新增广告后清除缓存
修改pinyougou-content-service工程ContentServiceImpl.java 的add方法
/**
* 增加
*/
@Override
public void add(TbContent content) {
contentMapper.insert(content);
try {
redisTemplate.boundHashOps("content").delete(content.getCategoryId());
} catch (Exception e) {
System.out.println("redis出错了!");
}
}
5.3.2 修改广告后清除缓存
考虑到用户可能会修改广告的分类,这样需要把原分类的缓存和新分类的缓存都清除掉。
/**
* 修改
*/
@Override
public void update(TbContent content){
try {
// 删除之前的分类缓存
TbContent selectByPrimaryKey = contentMapper.selectByPrimaryKey(content.getId());
redisTemplate.boundHashOps("content").delete(selectByPrimaryKey.getCategoryId());
} catch (Exception e) {
System.out.println("redis出错了!");
}
contentMapper.updateByPrimaryKey(content);
try {
redisTemplate.boundHashOps("content").delete(content.getCategoryId());
} catch (Exception e) {
System.out.println("redis出错了!");
}
}
5.3.3 删除广告后清除缓存
/**
* 批量删除
*/
@Override
public void delete(Long[] ids) {
for(Long id:ids){
try {
TbContent content = contentMapper.selectByPrimaryKey(id);
redisTemplate.boundHashOps("content").delete(content.getCategoryId());
} catch (Exception e) {
System.out.println("redis出错了!");
}
// 删除广告
contentMapper.deleteByPrimaryKey(id);
}
}