後臺管理系統CMS模組-後端實現

chengqiuming發表於2020-12-20

一 資料庫設計

1 資料庫

建立資料庫:guli_cms

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/cms

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

介面

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);
}

實現

@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

介面

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

介面

@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);
}

降級實現

/**
* @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("呼叫超時");
    }
}

 

相關文章