一 數據庫設計
1 數據庫
建立數據庫:guli_cmshtml
2 腳本
# 廣告 CREATE TABLE `cms_ad` ( `id` char(19) NOT NULL DEFAULT '' COMMENT 'ID', `title` varchar(20) DEFAULT '' COMMENT '標題', `type_id` char(19) NOT NULL COMMENT '類型ID', `image_url` varchar(500) NOT NULL DEFAULT '' COMMENT '圖片地址', `color` varchar(10) DEFAULT NULL COMMENT '背景顏色', `link_url` varchar(500) DEFAULT '' COMMENT '連接地址', `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序', `gmt_create` datetime NOT NULL COMMENT '建立時間', `gmt_modified` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`), UNIQUE KEY `uk_name` (`title`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='廣告推薦'; # 廣告位 CREATE TABLE `cms_ad_type` ( `id` char(19) NOT NULL COMMENT 'ID', `title` varchar(20) NOT NULL COMMENT '標題', `gmt_create` datetime NOT NULL COMMENT '建立時間', `gmt_modified` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推薦位';
二 建立內容管理微服務
1 建立模塊
service_cms前端
2 配置pom.xml
<build> <!-- 項目打包時會將java目錄中的*.xml文件也進行打包 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
3 配置application.yml
server: port: 8140 # 服務端口 spring: profiles: active: dev # 環境設置 application: name: service-cms # 服務名 cloud: nacos: discovery: server-addr: localhost:8848 # nacos服務地址 sentinel: transport: port: 8081 dashboard: localhost:8080 datasource: # mysql數據庫鏈接 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/guli_cms?serverTimezone=GMT%2B8 username: root password: 123456 #spring: jackson: #返回json的全局時間格式 date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mybatis日誌 mapper-locations: classpath:com/atguigu/guli/service/cms/mapper/xml/*.xml ribbon: ConnectTimeout: 10000 #鏈接創建的超時時長,默認1秒 ReadTimeout: 10000 #處理請求的超時時間,默認爲1秒 feign: sentinel: enabled: true
4 logback-spring.xml
修改日誌路徑爲 guli_log/cmsjava
5 建立啓動類
@SpringBootApplication @ComponentScan({"com.atguigu.guli"}) // 啓動 OpenFeign 遠程調用 @EnableFeignClients @EnableDiscoveryClient public class ServiceEduApplication { public static void main(String[] args) { SpringApplication.run(ServiceEduApplication.class, args); } }
6 建立代碼生成器並執行
三 後臺管理AdType
1 控制器
@CrossOrigin // 解決跨域問題 @Api(description = "推薦位管理") @RestController @RequestMapping("/admin/cms/ad-type") @Slf4j public class AdTypeController { @Autowired private AdTypeService adTypeService; /** * 功能描述:全部推薦類別列表 * * @return R 返回給前端的數據 * @author cakin * @date 2020/12/20 */ @ApiOperation("全部推薦類別列表") @GetMapping("list") public R listAll() { List<AdType> list = adTypeService.list(); return R.ok().data("items", list); } /** * 功能描述:推薦類別分頁列表 * * @param page 當前頁碼 * @param limit 每頁記錄數 * @return R 返回給前端的數據 * @author cakin * @date 2020/12/20 */ @ApiOperation("推薦類別分頁列表") @GetMapping("list/{page}/{limit}") public R listPage(@ApiParam(value = "當前頁碼", required = true) @PathVariable Long page, @ApiParam(value = "每頁記錄數", required = true) @PathVariable Long limit) { Page<AdType> pageParam = new Page<>(page, limit); IPage<AdType> pageModel = adTypeService.page(pageParam); List<AdType> records = pageModel.getRecords(); long total = pageModel.getTotal(); return R.ok().data("total", total).data("rows", records); } /** * 功能描述:根據ID刪除推薦類別 * * @author cakin * @date 2020/12/20 * @param id 推薦類別ID * @return R 返回給前端的數據 */ @ApiOperation(value = "根據ID刪除推薦類別") @DeleteMapping("remove/{id}") public R removeById(@ApiParam(value = "推薦類別ID", required = true) @PathVariable String id) { boolean result = adTypeService.removeById(id); if (result) { return R.ok().message("刪除成功"); } else { return R.error().message("數據不存在"); } } /** * 功能描述:新增推薦類別 * * @author cakin * @date 2020/12/20 * @param adType 推薦類別對象 * @return R 返回給前端的數據 */ @ApiOperation("新增推薦類別") @PostMapping("save") public R save(@ApiParam(value = "推薦類別對象", required = true) @RequestBody AdType adType) { boolean result = adTypeService.save(adType); if (result) { return R.ok().message("保存成功"); } else { return R.error().message("保存失敗"); } } /** * 功能描述:更新推薦類別 * * @author cakin * @date 2020/12/20 * @param adType 推薦類別對象 * @return R 返回給前端的數據 */ @ApiOperation("更新推薦類別") @PutMapping("update") public R updateById(@ApiParam(value = "講師推薦類別", required = true) @RequestBody AdType adType) { boolean result = adTypeService.updateById(adType); if (result) { return R.ok().message("修改爲功"); } else { return R.error().message("數據不存在"); } } /** * 功能描述:根據id獲取推薦類別信息 * * @author cakin * @date 2020/12/20 * @param id 推薦類別ID * @return R 返回給前端的數據 */ @ApiOperation("根據id獲取推薦類別信息") @GetMapping("get/{id}") public R getById(@ApiParam(value = "推薦類別ID", required = true) @PathVariable String id) { AdType adType = adTypeService.getById(id); if (adType != null) { return R.ok().data("item", adType); } else { return R.error().message("數據不存在"); } } }
四 後臺管理Ad
1 vo
@Data public class AdVo implements Serializable { private static final long serialVersionUID=1L; /** * id */ private String id; /** * 標題 */ private String title; /** * 排序方式 */ private Integer sort; /** * 廣告類別 */ private String type; }
2 控制器
@CrossOrigin //解決跨域問題 @Api(description = "廣告推薦管理") @RestController @RequestMapping("/admin/cms/ad") @Slf4j public class AdController { @Autowired private AdService adService; /** * 功能描述:根據ID刪除推薦 * * @author cakin * @date 2020/12/20 * @param id 廣告id * @return R 返回該前端的數據 */ @ApiOperation(value = "根據ID刪除推薦") @DeleteMapping("remove/{id}") public R removeById(@ApiParam(value = "推薦ID", required = true) @PathVariable String id) { // 刪除圖片 adService.removeAdImageById(id); // 刪除推薦 boolean result = adService.removeById(id); if (result) { return R.ok().message("刪除成功"); } else { return R.error().message("數據不存在"); } } /** * 功能描述:推薦分頁列表 * * @author cakin * @date 2020/12/20 * @param page 當前頁碼 * @param limit 每頁記錄數 * @return 返回給前端的數據 */ @ApiOperation("推薦分頁列表") @GetMapping("list/{page}/{limit}") public R listPage(@ApiParam(value = "當前頁碼", required = true) @PathVariable Long page, @ApiParam(value = "每頁記錄數", required = true) @PathVariable Long limit) { IPage<AdVo> pageModel = adService.selectPage(page, limit); List<AdVo> records = pageModel.getRecords(); long total = pageModel.getTotal(); return R.ok().data("total", total).data("rows", records); } /** * 功能描述:新增推薦 * * @author cakin * @date 2020/12/20 * @param ad 廣告 * @return R 返回給前端的數據 */ @ApiOperation("新增推薦") @PostMapping("save") public R save(@ApiParam(value = "推薦對象", required = true) @RequestBody Ad ad) { boolean result = adService.save(ad); if (result) { return R.ok().message("保存成功"); } else { return R.error().message("保存失敗"); } } /** * 功能描述:更新推薦 * * @author cakin * @date 2020/12/20 * @param ad 廣告 * @return R 返回給前端的數據 */ @ApiOperation("更新推薦") @PutMapping("update") public R updateById(@ApiParam(value = "講師推薦", required = true) @RequestBody Ad ad) { boolean result = adService.updateById(ad); if (result) { return R.ok().message("修改爲功"); } else { return R.error().message("數據不存在"); } } /** * 功能描述:根據id獲取推薦信息 * * @author cakin * @date 2020/12/20 * @param id 廣告id * @return R 返回給前端的數據 */ @ApiOperation("根據id獲取推薦信息") @GetMapping("get/{id}") public R getById(@ApiParam(value = "推薦ID", required = true) @PathVariable String id) { Ad ad = adService.getById(id); if (ad != null) { return R.ok().data("item", ad); } else { return R.error().message("數據不存在"); } } }
3 service
接口mysql
public interface AdService extends IService<Ad> { /** * 功能描述:廣告分頁查詢 * * @author cakin * @date 2020/12/20 * @param page 當前頁碼 * @param limit 每頁記錄數 * @return IPage<AdVo> 分頁信息 */ IPage<AdVo> selectPage(Long page, Long limit); /** * 功能描述:刪除廣告圖像 * * @author cakin * @date 2020/12/20 * @param id 廣告id * @return boolean 刪除是否成功 */ boolean removeAdImageById(String id); }
實現spring
@Service public class AdServiceImpl extends ServiceImpl<AdMapper, Ad> implements AdService { @Autowired private OssFileService ossFileService; /** * 功能描述:廣告分頁查詢 * * @author cakin * @date 2020/12/20 * @param page 當前頁碼 * @param limit 每頁記錄數 * @return IPage<AdVo> 分頁信息 */ @Override public IPage<AdVo> selectPage(Long page, Long limit) { QueryWrapper<AdVo> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByAsc("a.type_id", "a.sort"); Page<AdVo> pageParam = new Page<>(page, limit); // 需傳遞分頁參數和條件查詢參數 List<AdVo> records = baseMapper.selectPageByQueryWrapper(pageParam, queryWrapper); pageParam.setRecords(records); return pageParam; } /** * 功能描述:刪除廣告圖像 * * @author cakin * @date 2020/12/20 * @param id 廣告id * @return boolean 刪除是否成功 */ @Override public boolean removeAdImageById(String id) { Ad ad = baseMapper.selectById(id); if(ad != null) { String imagesUrl = ad.getImageUrl(); if(!StringUtils.isEmpty(imagesUrl)){ // 刪除圖片,遠程調用oss服務中的刪除文件 R r = ossFileService.removeFile(imagesUrl); return r.getSuccess(); } } return false; } }
4 mapper
接口sql
public interface AdMapper extends BaseMapper<Ad> { /** * 功能描述:廣告分頁查詢 * * @author cakin * @date 2020/12/20 * @param pageParam 分頁參數 * @return queryWrapper 條件查詢參數 */ List<AdVo> selectPageByQueryWrapper( Page<AdVo> pageParam, @Param(Constants.WRAPPER) QueryWrapper<AdVo> queryWrapper); }
XML數據庫
<select id="selectPageByQueryWrapper" resultType="com.atguigu.guli.service.cms.entity.vo.AdVo"> SELECT a.id, a.title, a.sort, t.title AS type FROM cms_ad a LEFT JOIN cms_ad_type t ON a.type_id = t.id ${ew.customSqlSegment} </select>
5 feign
接口apache
@Service @FeignClient(value = "service-oss", fallback = OssFileServiceFallBack.class) public interface OssFileService { /** * 功能描述:遠程刪除文件 * * @author cakin * @date 2020/12/20 * @param url * @return R 前端返回結果 */ @DeleteMapping("/admin/oss/file/remove") R removeFile(@RequestBody String url); }
降級實現json
/** * @className: OssFileServiceFallBack * @description: 文件服務遠程調用失敗降級處理 * @date: 2020/12/20 * @author: cakin */ @Service @Slf4j public class OssFileServiceFallBack implements OssFileService { /** * 功能描述:文件服務遠程調用失敗降級處理 * * @author cakin * @date 2020/12/20 * @param url 文件url地址 * @return R 遠程調用返回的結果 */ @Override public R removeFile(String url) { log.info("熔斷保護"); return R.error().message("調用超時"); } }