03_CMS頁面管理開發(fā)


鏈接:本日資料 https://pan.baidu.com/s/1QMuaC6j0MsNA3DnE1i9tIA&shfl=sharepset 提取碼:e1oi??

1 自定義條件查詢

1.1 需求分析

在頁面輸入查詢條件,查詢符合條件的頁面信息。

查詢條件如下:

站點(diǎn)Id:精確匹配

模板Id:精確匹配

頁面別名:模糊匹配

1.2 服務(wù)端

1.2.1 Dao

使用 CmsPageRepository中的findAll(Example<S> var1, Pageable var2)方法實(shí)現(xiàn),無需定義。

下邊測試fifindAll方法實(shí)現(xiàn)自定義條件查詢:

==================================

//自定義條件查詢測試

@Test

public void testFindAll() {

//條件匹配器

ExampleMatcher exampleMatcher = ExampleMatcher.matching();

exampleMatcher = exampleMatcher.withMatcher("pageAliase",

ExampleMatcher.GenericPropertyMatchers.contains());

//頁面別名模糊查詢,需要自定義字符串的匹配器實(shí)現(xiàn)模糊查詢

//ExampleMatcher.GenericPropertyMatchers.contains() 包含

//ExampleMatcher.GenericPropertyMatchers.startsWith()//開頭匹配

//條件值

CmsPage cmsPage = new CmsPage();

//站點(diǎn)ID

cmsPage.setSiteId("5a751fab6abb5044e0d19ea1");

//模板ID

cmsPage.setTemplateId("5a962c16b00ffc514038fafd");

// cmsPage.setPageAliase("分類導(dǎo)航");

//創(chuàng)建條件實(shí)例

Example<CmsPage> example = Example.of(cmsPage, exampleMatcher);

Pageable pageable = new PageRequest(0, 10);

Page<CmsPage> all = cmsPageRepository.findAll(example, pageable);

System.out.println(all);

}

?

=================================

1.2.2 Service

在PageService的fifindlist方法中增加自定義條件查詢代碼

===============================

/**

* 頁面列表分頁查詢

* @param page 當(dāng)前頁碼

* @param size 頁面顯示個數(shù)

* @param queryPageRequest 查詢條件

* @return 頁面列表

*/

public QueryResponseResult findList(int page,int size,QueryPageRequest queryPageRequest){

//條件匹配器

//頁面名稱模糊查詢,需要自定義字符串的匹配器實(shí)現(xiàn)模糊查詢

ExampleMatcher exampleMatcher = ExampleMatcher.matching()

.withMatcher("pageAliase", ExampleMatcher.GenericPropertyMatchers.contains());

//條件值

CmsPage cmsPage = new CmsPage();

//站點(diǎn)ID

if(StringUtils.isNotEmpty(queryPageRequest.getSiteId())){

cmsPage.setSiteId(queryPageRequest.getSiteId());

}

//頁面別名

if(StringUtils.isNotEmpty(queryPageRequest.getPageAliase())){

cmsPage.setPageAliase(queryPageRequest.getPageAliase());

}

//創(chuàng)建條件實(shí)例

Example<CmsPage> example = Example.of(cmsPage, exampleMatcher);

//頁碼

page = page‐1;

//分頁對象

Pageable pageable = new PageRequest(page, size);

//分頁查詢

Page<CmsPage> all = cmsPageRepository.findAll(example,pageable);

QueryResult<CmsPage> cmsPageQueryResult = new QueryResult<CmsPage>();

cmsPageQueryResult.setList(all.getContent());

cmsPageQueryResult.setTotal(all.getTotalElements());

//返回結(jié)果

return new QueryResponseResult(CommonCode.SUCCESS,cmsPageQueryResult);

}

================================

1.2.3 Controller

無需修改

1.2.4 測試

使用SwaggerUI測試



1.3 前端

1.3.1 頁面

1、增加查詢表單

========================

<!‐‐查詢表單‐‐>

<el‐form :model="params">

<el‐select v‐model="params.siteId" placeholder="請選擇站點(diǎn)">

<el‐option

v‐for="item in siteList"

:key="item.siteId"

:label="item.siteName"

:value="item.siteId">

</el‐option>

</el‐select>

頁面別名:<el‐input v‐model="params.pageAliase" style="width: 100px"></el‐input>

<el‐button type="primary" v‐on:click="query" size="small">查詢</el‐button>

</el‐form>

=======================

2、數(shù)據(jù)模型對象

增加siteList、pageAliase、siteId,如下:

=======================

data() {

return {

siteList:[],//站點(diǎn)列表

list:[],

total:50,

params:{

siteId:'',

pageAliase:'',

page:1,//頁碼

size:2//每頁顯示個數(shù)

}

}

}

=======================

3、在鉤子方法中 構(gòu)建siteList站點(diǎn)列表

==========================

mounted() {

//默認(rèn)查詢頁面

this.query()

//初始化站點(diǎn)列表

this.siteList = [

{

siteId:'5a751fab6abb5044e0d19ea1',

siteName:'門戶主站'

},

{

siteId:'102',

siteName:'測試站'

}

]

}

==========================

1.3.2 Api調(diào)用

1、向服務(wù)端傳遞查詢條件,修改 cms.js,如下:

============================

//public是對axios的工具類封裝,定義了http請求方法

import http from './../../../base/api/public'

import querystring from 'querystring'

let sysConfig = require('@/../config/sysConfig')

let apiUrl = sysConfig.xcApiUrlPre;

export const page_list = (page,size,params) => {

//將json對象轉(zhuǎn)成key/value對

let query = querystring.stringify(params)

return http.requestQuickGet(apiUrl+'/cms/page/list/'+page+'/'+size+'/?'+query)

}

}?

=============================

2 新增頁面

2.1 新增頁面接口定義

1、定義響應(yīng)模型

=======================

@Data

public class CmsPageResult extends ResponseResult {

CmsPage cmsPage;

public CmsPageResult(ResultCode resultCode,CmsPage cmsPage) {

super(resultCode);

this.cmsPage = cmsPage;

}

}

======================

2、定義添加Api

在api工程中添加接口:

====================

@ApiOperation("添加頁面")

public CmsPageResult add(CmsPage cmsPage);

===================

2.2 新增頁面服務(wù)端開發(fā)

2.2.1 頁面唯一索引

在cms_page集中上創(chuàng)建頁面名稱、站點(diǎn)Id、頁面webpath為唯一索引

1:打開studip3t?

2:找到 cms_page 右鍵 點(diǎn)擊add index

3:點(diǎn)擊 add Filed


4:選擇pageName pageWebPath,siteld 在 勾選上Unique



2.2.2 Dao ?

1、添加根據(jù)頁面名稱、站點(diǎn)Id、頁面webpath查詢頁面方法,此方法用于校驗(yàn)頁面是否存在

========================

public interface CmsPageRepository extends MongoRepository<CmsPage,String> {

//根據(jù)頁面名稱、站點(diǎn)id、頁面訪問路徑查詢

CmsPage findByPageNameAndSiteIdAndPageWebPath(String pageName,String siteId,String

pageWebPath);

=========================

2、使用 CmsPageRepository提供的save方法 。

2.2.3 Service

=======================

//添加頁面

public CmsPageResult add(CmsPage cmsPage){

//校驗(yàn)頁面是否存在,根據(jù)頁面名稱、站點(diǎn)Id、頁面webpath查詢

CmsPage cmsPage1 =

cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(),

cmsPage.getSiteId(), cmsPage.getPageWebPath());

if(cmsPage1==null){

cmsPage.setPageId(null);//添加頁面主鍵由spring data 自動生成

cmsPageRepository.save(cmsPage);

//返回結(jié)果

CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS,cmsPage);

return cmsPageResult;

}

return new CmsPageResult(CommonCode.FAIL,null);

}

======================

2.2.4 Controller

==========================

//添加頁面

@Override

@PostMapping("/add")

public CmsPageResult add(@RequestBody CmsPage cmsPage) {

return pageService.add(cmsPage);

}


==========================

2.2.5 接口測試

使用postman測試


post請求:http://localhost:31001/cms/page/add

請求內(nèi)容為json數(shù)據(jù),測試數(shù)據(jù)如下

==========================

{

"dataUrl": "string",

"htmlFileId": "string",

"pageAliase": "string",

"pageCreateTime": "2018‐06‐11T02:01:25.667Z",

"pageHtml": "string",

"pageName": "測試頁面",

"pageParameter": "string",

"pagePhysicalPath": "string",

"pageStatus": "string",

"pageTemplate": "string",

"pageType": "string",

"pageWebPath": "string",

"siteId": "string",

"templateId": "string"

}

==========================:

2.3 新增頁面前端開發(fā)

2.3.1 新增頁面

2.3.1.1 編寫page_add.vue頁面

使用Element-UI的form組件編寫添加表單內(nèi)容,頁面效果如下:


1、創(chuàng)建page_add.vue頁面

2、配置路由

在cms模塊的路由文件中配置“添加頁面”的路由:

{path:'/cms/page/add',name:'新增頁面',component: page_add,hidden:true}

注意:由于“添加頁面”不需要顯示為一個菜單,這里hidden設(shè)置為true隱藏菜單。

================================

import Homefrom '@/module/home/page/home.vue';

import page_listfrom '@/module/cms/page/page_list.vue';

import page_addfrom '@/module/cms/page/page_add.vue';

export default [{

path:'/',

? ? component: Home,

? ? name:'CMS',? // 菜單名稱

? ? hidden:false,

? children:[ {path:'/cms/page/list',name:'頁面列表',component: page_list,hidden:false},// 子菜單

? ? {path:'/cms/page/add',name:'新增頁面',component: page_add,hidden:true}

]

},

]

================================

測試,在瀏覽器地址欄輸入http://localhost:11000/#/cms/page/add

3、在頁面列表添加“添加頁面”的按鈕

實(shí)際情況是用戶進(jìn)入頁面查詢列表,點(diǎn)擊“新增頁面”按鈕進(jìn)入新增頁面窗口。

在查詢按鈕的旁邊添加:

======================

<router‐link class="mui‐tab‐item" :to="{path:'/cms/page/add/'}">

<el‐button type="primary" size="small">新增頁面</el‐button>

</router‐link>

========================

說明:router-link是vue提供的路由功能,用于在頁面生成路由鏈接,最終在html渲染后就是<a標(biāo)簽。

to:目標(biāo)路由地址

4、完善頁面內(nèi)容:

代碼如下:

==============================

<el‐form :model="pageForm" label‐width="80px" >

<el‐form‐item label="所屬站點(diǎn)" prop="siteId">

<el‐select v‐model="pageForm.siteId" placeholder="請選擇站點(diǎn)">

<el‐option

v‐for="item in siteList"

:key="item.siteId"

:label="item.siteName"

:value="item.siteId">

</el‐option>

</el‐select>

</el‐form‐item>

<el‐form‐item label="選擇模版" prop="templateId">

<el‐select v‐model="pageForm.templateId" placeholder="請選擇">

<el‐option

v‐for="item in templateList"

:key="item.templateId"

:label="item.templateName"

:value="item.templateId">

</el‐option>

</el‐select>

</el‐form‐item>

<el‐form‐item label="頁面名稱" prop="pageName">

<el‐input v‐model="pageForm.pageName" auto‐complete="off" ></el‐input>

</el‐form‐item>

<el‐form‐item label="別名" prop="pageAliase">

<el‐input v‐model="pageForm.pageAliase" auto‐complete="off" ></el‐input>

</el‐form‐item>

<el‐form‐item label="訪問路徑" prop="pageWebPath">

<el‐input v‐model="pageForm.pageWebPath" auto‐complete="off" ></el‐input>

</el‐form‐item>

<el‐form‐item label="物理路徑" prop="pagePhysicalPath">

<el‐input v‐model="pageForm.pagePhysicalPath" auto‐complete="off" ></el‐input>

</el‐form‐item>

<el‐form‐item label="類型">

<el‐radio‐group v‐model="pageForm.pageType">

<el‐radio class="radio" label="0">靜態(tài)</el‐radio>

<el‐radio class="radio" label="1">動態(tài)</el‐radio>

</el‐radio‐group>

</el‐form‐item>

<el‐form‐item label="創(chuàng)建時間">

<el‐date‐picker type="datetime" placeholder="創(chuàng)建時間" v‐model="pageForm.pageCreateTime">

</el‐date‐picker>

</el‐form‐item>

</el‐form>

<div slot="footer" class="dialog‐footer">

<el‐button type="primary" @click="addSubmit" >提交</el‐button>

</div>

==============================

Form Attributes說明:

model 表單數(shù)據(jù)對象

rules 表單驗(yàn)證規(guī)則

Form-Item Attributes說明:

prop 表單域 model 字段,在使用 validate、resetFields 方法的情況下,該屬性是必填的

label 標(biāo)簽文本

詳情屬性及事件參考http://element.eleme.io/#/zh-CN/component/form

5、數(shù)據(jù)對象

=======================

data(){

return {

siteList:[],

//模版列表

templateList:[],


//新增界面數(shù)據(jù)

pageForm: {

siteId:'',

templateId:'',

pageName: '',

pageAliase: '',

pageWebPath: '',

pageParameter:'',

pagePhysicalPath:'',

pageType:'',

pageCreateTime: new Date()

}

}

},

methods:{

addSubmit(){

alert("提交")

}

},

mounted() {

//初始化站點(diǎn)列表

this.siteList = [

{

siteId:'5a751fab6abb5044e0d19ea1',

siteName:'門戶主站'

},

{

siteId:'102',

siteName:'測試站'

}

]

//模板列表

this.templateList = [

{

templateId:'5a962b52b00ffc514038faf7',

templateName:'首頁'

},

{

templateId:'5a962bf8b00ffc514038fafa',

templateName:'輪播圖'

}

]

=======================

2.3.1.2 添加返回

進(jìn)入新增頁面后只能通過菜單再次進(jìn)入頁面列表,可以在新增頁面添加“返回”按鈕,點(diǎn)擊返回按鈕返回到頁面列

表。

1) 新增頁面按鈕帶上參數(shù)

===============

<router‐link class="mui‐tab‐item" :to="{path:'/cms/page/add/',query:{

page: this.params.page,

siteId: this.params.siteId}}">

<el‐button type="primary" size="small">新增頁面</el‐button>

</router‐link>

================

說明:query表示在路由url上帶上參數(shù)

2)定義返回方法

在page_add.vue上定義返回按鈕

<el‐button type="primary" @click="go_back" >返回</el‐button>

在page_add.vue上定義返回方法

========================

go_back(){

this.$router.push({

path: '/cms/page/list', query: {

page: this.$route.query.page,

siteId:this.$route.query.siteId

}

})

}

========================

說明:this.$route.query 表示取出路由上的參數(shù)列表,有兩個取路由參數(shù)的方法:

===============

a、通過在路由上添加key/value串使用this.$route.query來取參數(shù),例如:/router1?id=123 ,/router1?id=456

可以通過this.$route.query.id獲取參數(shù)id的值。

b、通過將參數(shù)作為路由一部分進(jìn)行傳參數(shù)使用this.$route.params來獲取,例如:定義的路由為/router1/:id ,請

求/router1/123時可以通過this.$route.params.id來獲取,此種情況用this.$route.query.id是拿不到的。

f

===============

3)查詢列表支持回顯

進(jìn)入查詢列表,從url中獲取頁碼和站點(diǎn)id并賦值給數(shù)據(jù)模型對象,從而實(shí)現(xiàn)頁面回顯。

url例子:http://localhost:12000/#/cms/page/list?page=2&siteId=5a751fab6abb5044e0d19ea1

====================

created() {

//從路由上獲取參數(shù)

this.params.page = Number.parseInt(this.$route.query.page||1);

this.params.siteId = this.$route.query.siteId||'';

}

====================

小技巧:使用 ||返回第一個有效值

2.3.1.3 表單校驗(yàn)

1、配置校驗(yàn)規(guī)則:

Element-UI的Form組件提供表單校驗(yàn)的方法:

在form屬性上配置rules(表單驗(yàn)證規(guī)則)

<el‐form :model="pageForm" :rules="pageFormRules" label‐width="80px" >

在數(shù)據(jù)模型中配置校驗(yàn)規(guī)則:

============================

添加到pageForm:

pageFormRules: {

siteId:[

{required: true, message: '請選擇站點(diǎn)', trigger: 'blur'}

],

templateId:[

{required: true, message: '請選擇模版', trigger: 'blur'}

],

pageName: [

{required: true, message: '請輸入頁面名稱', trigger: 'blur'}

],

pageWebPath: [

{required: true, message: '請輸入訪問路徑', trigger: 'blur'}

],

pagePhysicalPath: [

{required: true, message: '請輸入物理路徑', trigger: 'blur'}

]

}

============================

更多的校驗(yàn)規(guī)則參考http://element.eleme.io/#/zh-CN/component/form中“表單驗(yàn)證”的例子。

?2、點(diǎn)擊提交按鈕觸發(fā)校驗(yàn)

1)在form表單上添加 ref屬性(ref="pageForm")在校驗(yàn)時引用此表單對象

<el‐form :model="pageForm" :rules="pageFormRules" label‐width="80px" ref="pageForm">

2)執(zhí)行校驗(yàn)? 復(fù)制到提交方法中

this.$refs.pageForm.validate((valid) => {

if (valid) {

alert('提交');

} else {

alert('校驗(yàn)失敗');

return false;

}

})

====================

2.3.2 Api調(diào)用

1、在cms.js中定義page_add方法。

====================

/*頁面添加*/

export const page_add = params => {

return http.requestPost(apiUrl+'/cms/page/add',params)

}

====================

2、添加事件

本功能使用到兩個UI組件:

1、使用element-ui的message-box組件彈出確認(rèn)提交窗口?

http://element.eleme.io/#/zh-CN/component/message-box

======================

this.$confirm('確認(rèn)提交嗎?', '提示', {}).then(() => {})

=====================

2、使用 message組件提示操作結(jié)果 (http://element.eleme.io/#/zh-CN/component/message)

=====================

this.$message({

message: '提交成功',

type: 'success'

})


=====================

完整的代碼如下:

addSubmit(){

this.$refs.pageForm.validate((valid) => {

if (valid) {

this.$confirm('確認(rèn)提交嗎?', '提示', {}).then(() => {

cmsApi.page_add(this.pageForm).then((res) => {

console.log(res);

if(res.success){

this.$message({

message: '提交成功',

type: 'success'

});

this.$refs['pageForm'].resetFields();

}else{

this.$message.error('提交失敗');

}

});

});

}

});

}

===============

3 修改頁面

修改頁面用戶操作流程:

1、用戶進(jìn)入修改頁面,在頁面上顯示了修改頁面的信息

2、用戶修改頁面的內(nèi)容,點(diǎn)擊“提交”,提示“修改成功”或“修改失敗”

3.1 修改頁面接口定義

修改頁面需要定義的API如下:

============

@ApiOperation("通過ID查詢頁面")

public CmsPage findById(String id);

@ApiOperation("修改頁面")

public CmsPageResult edit(String id,CmsPage cmsPage);

============

說明:提交數(shù)據(jù)使用post、put都可以,只是根據(jù)http方法的規(guī)范,put方法是對服務(wù)器指定資源進(jìn)行修改,所以這

里使用put方法對頁面修改進(jìn)行修改。

3.2 修改頁面服務(wù)端開發(fā)

使用 Spring Data提供的fifindById方法完成根據(jù)主鍵查詢 。

使用 Spring Data提供的save方法完成數(shù)據(jù)保存 。

3.2.2Service

===========================

//根據(jù)id查詢頁面

public CmsPage getById(String id){

Optional<CmsPage> optional = cmsPageRepository.findById(id);

if(optional.isPresent()){

return optional.get();

}

//返回空

return null;

}

//更新頁面信息

public CmsPageResult update(String id,CmsPage cmsPage) {

//根據(jù)id查詢頁面信息

CmsPage one = this.getById(id);

if (one != null) {

//更新模板id

? ??one.setTemplateId(cmsPage.getTemplateId());

//更新所屬站點(diǎn)

one.setSiteId(cmsPage.getSiteId());

//更新頁面別名

one.setPageAliase(cmsPage.getPageAliase());

//更新頁面名稱

one.setPageName(cmsPage.getPageName());

//更新訪問路徑

one.setPageWebPath(cmsPage.getPageWebPath());

//更新物理路徑

one.setPagePhysicalPath(cmsPage.getPagePhysicalPath());

//執(zhí)行更新

CmsPage save = cmsPageRepository.save(one);

if (save != null) {

//返回成功

CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS, save);

return cmsPageResult;

}

}

//返回失敗

return new CmsPageResult(CommonCode.FAIL,null);

}


===========================

3.2.3Controller

1、根據(jù)id查詢頁面

=======================

@Override

@GetMapping("/get/{id}")

public CmsPage findById(@PathVariable("id") String id) {

return pageService.getById(id);

}

========================

2、保存頁面信息

========================

@Override

@PutMapping("/edit/{id}")//這里使用put方法,http 方法中put表示更新

public CmsPageResult edit(@PathVariable("id") String id, @RequestBody CmsPage cmsPage) {

return pageService.update(id,cmsPage);

}

========================

3.3 修改頁面前端開發(fā)

3.3.1 頁面處理流程

頁面的處理流程如下:

1、進(jìn)入頁面,通過鉤子方法請求服務(wù)端獲取頁面信息,并賦值給數(shù)據(jù)模型對象

2、頁面信息通過數(shù)據(jù)綁定在表單顯示

3、用戶修改信息點(diǎn)擊“提交”請求服務(wù)端修改頁面信息接口

3.3.3 修改頁面

3.3.3.1 編寫page_edit頁面

修改頁面的布局同添加頁面,可以直接復(fù)制添加頁面,在添加頁面基礎(chǔ)上修改。

下邊編寫頁面內(nèi)容:

1、編寫page_edit.vue

資料中找

2、配置路由

進(jìn)入修改頁面?zhèn)魅雙ageId

=================

import page_edit from '@/module/cms/page/page_edit.vue';

{ path: '/cms/page/edit/:pageId', name:'修改頁面',component: page_edit,hidden:true},

==================

3、在頁面列表添加“編輯”鏈接

參考table組件的例子,在page_list.vue上添加“操作”列?

在 創(chuàng)建時間后面添加

=======================

<el‐table‐column label="操作" width="80">

<template slot‐scope="page">

<el‐button

size="small"type="text"

@click="edit(page.row.pageId)">編輯

</el‐button>

</template>

</el‐table‐column>

=======================

編寫edit方法

========================

//修改

edit:function (pageId) {

this.$router.push({ path: '/cms/page/edit/'+pageId,query:{

page: this.params.page,

siteId: this.params.siteId}})

}

=======================

3.3.3.2 頁面內(nèi)容顯示

本功能實(shí)現(xiàn):進(jìn)入修改頁面立即顯示要修改的頁面信息。

1、定義api方法

=================

/*頁面查詢*/

export const page_get = id => {

return http.requestQuickGet(apiUrl+'/cms/page/get/'+id)

}

==================

2、定義數(shù)據(jù)對象

進(jìn)入修改頁面?zhèn)魅雙ageId參數(shù),在數(shù)據(jù)模型中添加pageId。

===============

data(){

return {

......

//頁面id

pageId:'',

......

}

}


===============

3、在created鉤子方法 中查詢頁面信息

=======================

created: function () {

//頁面參數(shù)通過路由傳入,這里通過this.$route.params來獲取

this.pageId=this.$route.params.pageId;

//根據(jù)主鍵查詢頁面信息

cmsApi.page_get(this.pageId).then((res) => {

console.log(res);

if(res.success){

this.pageForm = res.cmsPage;

}

});

}

?======================

7、預(yù)覽頁面回顯效果


3.3.4 Api調(diào)用

1、定義api方法

=====================

/*頁面修改,采用put方法*/

export const page_edit = (id,params) => {

return http.requestPut(apiUrl+'/cms/page/edit/'+id,params)

}

======================

2、提交按鈕方法

添加提交按鈕事件:

<el‐button type="primary" @click="editSubmit" >提交</el‐button>

3、提交按鈕事件內(nèi)容:?

editSubmit(){

this.$refs.pageForm.validate((valid) => {

if (valid) {

this.$confirm('確認(rèn)提交嗎?', '提示', {}).then(() => {

cmsApi.page_edit(this.pageId,this.pageForm).then((res) => {

console.log(res);

if(res.success){

this.$message({

message: '修改成功',

type: 'success'

});

//自動返回

this.go_back();

}else{

this.$message.error('修改失敗');

}

});

});

}

});

}

===================

4 刪除頁面

用戶操作流程:

1、用戶進(jìn)入用戶列表,點(diǎn)擊“刪除”

2、執(zhí)行刪除操作,提示“刪除成功”或“刪除失敗”

4.1 刪除頁面接口定義

====================

@ApiOperation("通過ID刪除頁面")

public ResponseResult delete(String id);

====================

4.2 刪除頁面服務(wù)端開發(fā)

?4.2.1Dao

使用 Spring Data提供的deleteById方法完成刪除操作 。

4.2.2 Service

============

//刪除頁面

public ResponseResult delete(String id){

CmsPage one = this.getById(id);

if(one!=null){

//刪除頁面

cmsPageRepository.deleteById(id);

return new ResponseResult(CommonCode.SUCCESS);

}

return new ResponseResult(CommonCode.FAIL);

}

===========

4.2.3Controller

@DeleteMapping("/del/{id}") //使用http的delete方法完成崗位操作

public ResponseResult delete(@PathVariable("id") String id) {

return pageService.delete(id);

}

4.3 刪除頁面前端開發(fā)

4.3.1 Api方法

=====================

/*頁面刪除*/

export const page_del = id => {

return http.requestDelete(apiUrl+'/cms/page/del/'+id)

}

=====================

4.3.2編寫頁面

1、在page_list.vue頁面添加刪除按鈕

==================================

<el‐table‐column label="操作" width="120">

<template slot‐scope="page">

<el‐button

size="small"type="text"

@click="edit(page.row.pageId)">編輯

</el‐button>

<el‐button

size="small"type="text"

@click="del(page.row.pageId)">刪除

</el‐button>

</template>

</el‐table‐column>

=================================

2、刪除事件

del:function (pageId) {

this.$confirm('確認(rèn)刪除此頁面嗎?', '提示', {}).then(() => {

cmsApi.page_del(pageId).then((res)=>{

if(res.success){

this.$message({

type: 'success',

message: '刪除成功!'

});

//查詢頁面

this.query()

}else{

this.$message({

type: 'error',

message: '刪除失敗!'

});

}

})

})

}

=====================

5 異常處理

5.1 異常處理的問題分析

從添加頁面的service方法中找問題:

=====================================

//添加頁面

public CmsPageResult add(CmsPage cmsPage){

//校驗(yàn)頁面是否存在,根據(jù)頁面名稱、站點(diǎn)Id、頁面webpath查詢

CmsPage cmsPage1 =

??cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(),

cmsPage.getSiteId(), cmsPage.getPageWebPath());

if(cmsPage1==null){

cmsPage.setPageId(null);//添加頁面主鍵由spring data 自動生成

cmsPageRepository.save(cmsPage);

//返回結(jié)果

CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS,cmsPage);

return cmsPageResult;

}

return new CmsPageResult(CommonCode.FAIL,null);

}

=============

問題:

1、上邊的代碼只要操作不成功僅向用戶返回“錯誤代碼:11111,失敗信息:操作失敗”,無法區(qū)別具體的錯誤信

息。

2、service方法在執(zhí)行過程出現(xiàn)異常在哪捕獲?在service中需要都加try/catch,如果在controller也需要添加

try/catch,代碼冗余嚴(yán)重且不易維護(hù)。

解決方案:

1、在Service方法中的編碼順序是先校驗(yàn)判斷,有問題則拋出具體的異常信息,最后執(zhí)行具體的業(yè)務(wù)操作,返回成

功信息。

2、在統(tǒng)一異常處理類中去捕獲異常,無需controller捕獲異常,向用戶返回統(tǒng)一規(guī)范的響應(yīng)信息。

代碼模板如下:

===========================

//添加頁面

public CmsPageResult add(CmsPage cmsPage){

//校驗(yàn)cmsPage是否為空

if(cmsPage == null){

//拋出異常,非法請求

//...

}

//根據(jù)頁面名稱查詢(頁面名稱已在mongodb創(chuàng)建了唯一索引)

CmsPage cmsPage1 =

cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(),

cmsPage.getSiteId(), cmsPage.getPageWebPath());

//校驗(yàn)頁面是否存在,已存在則拋出異常

if(cmsPage1 !=null){

//拋出異常,已存在相同的頁面名稱

//...

}

cmsPage.setPageId(null);//添加頁面主鍵由spring data 自動生成

CmsPage save = cmsPageRepository.save(cmsPage);

//返回結(jié)果

CmsPageResult cmsPageResult = new CmsPageResult(CommonCode.SUCCESS,save);

return cmsPageResult;

}


===========================

5.2 異常處理流程


系統(tǒng)對異常的處理使用統(tǒng)一的異常處理流程:

1、自定義異常類型。

2、自定義錯誤代碼及錯誤信息。

3、對于可預(yù)知的異常由程序員在代碼中主動拋出,由SpringMVC統(tǒng)一捕獲。

可預(yù)知異常是程序員在代碼中手動拋出本系統(tǒng)定義的特定異常類型,由于是程序員拋出的異常,通常異常信息比較

齊全,程序員在拋出時會指定錯誤代碼及錯誤信息,獲取異常信息也比較方便。

4、對于不可預(yù)知的異常(運(yùn)行時異常)由SpringMVC統(tǒng)一捕獲Exception類型的異常。

不可預(yù)知異常通常是由于系統(tǒng)出現(xiàn)bug、或一些不要抗拒的錯誤(比如網(wǎng)絡(luò)中斷、服務(wù)器宕機(jī)等),異常類型為

RuntimeException類型(運(yùn)行時異常)。

5、可預(yù)知的異常及不可預(yù)知的運(yùn)行時異常最終會采用統(tǒng)一的信息格式(錯誤代碼+錯誤信息)來表示,最終也會隨

請求響應(yīng)給客戶端。

異常拋出及處理流程:


1、在controller、service、dao中程序員拋出自定義異常;springMVC框架拋出框架異常類型

2、統(tǒng)一由異常捕獲類捕獲異常,并進(jìn)行處理

3、捕獲到自定義異常則直接取出錯誤代碼及錯誤信息,響應(yīng)給用戶。

4、捕獲到非自定義異常類型首先從Map中找該異常類型是否對應(yīng)具體的錯誤代碼,如果有則取出錯誤代碼和錯誤

信息并響應(yīng)給用戶,如果從Map中找不到異常類型所對應(yīng)的錯誤代碼則統(tǒng)一為99999錯誤代碼并響應(yīng)給用戶。

5、將錯誤代碼及錯誤信息以Json格式響應(yīng)給用戶。

?5.3 可預(yù)知異常處理

5.3.1 自定義異常類

在common工程定義異常類型。

=============================

package com.xuecheng.framework.exception;

import com.xuecheng.framework.model.response.ResultCode;

public class CustomException extends RuntimeException {

private ResultCode resultCode;

public CustomException(ResultCode resultCode) {

//異常信息為錯誤代碼+異常信息

super("錯誤代碼:"+resultCode.code()+"錯誤信息:"+resultCode.message());

this.resultCode = resultCode;

}

public ResultCode getResultCode(){

return this.resultCode;

}

}


=============================

5.3.2 異常拋出類

==============================

package com.xuecheng.framework.exception;

import com.xuecheng.framework.model.response.ResultCode;

public class ExceptionCast {

//使用此靜態(tài)方法拋出自定義異常

public static void cast(ResultCode resultCode){

throw new CustomException(resultCode);

}

}

==============================

5.3.3 異常捕獲類

使用 @ControllerAdvice和@ExceptionHandler注解來捕獲指定類型的異常

============================

package com.xuecheng.framework.exception;

import com.xuecheng.framework.model.response.ResponseResult;

import com.xuecheng.framework.model.response.ResultCode;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice //控制器增強(qiáng)

public class ExceptionCatch {

private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);

//捕獲 CustomException異常

@ExceptionHandler(CustomException.class)

@ResponseBody

public ResponseResult customException(CustomException e) {

Logger.error("catch exception : {}\r\nexception: ",e.getMessage(), e);

ResultCode resultCode = e.getResultCode();

ResponseResult responseResult = new ResponseResult(resultCode);

return responseResult;

}

}

============================

5.3.4異常處理測試

5.3.4.1定義錯誤代碼

每個業(yè)務(wù)操作的異常使用異常代碼去標(biāo)識。

===========================

package com.xuecheng.framework.domain.cms.response;

import com.xuecheng.framework.model.response.ResultCode;

import lombok.ToString;

@ToString

public enum CmsCode implements ResultCode {

CMS_ADDPAGE_EXISTS(false,24001,"頁面已存在!");

//操作結(jié)果

boolean success;

//操作代碼

int code;

//提示信息

String message;

private CmsCode(boolean success, int code, String message){

this.success = success;

this.code = code;

this.message = message;

}

@Override

public boolean success() {

return success;

}

@Override

public int code() {

return code;

}

@Override

public String message() {

return message;

}

}


=============================

5.3.4.2 異常處理測試

1、拋出異常

在controller、service、 dao中都可以拋出異常。

修改PageService的add方法,添加拋出異常的代碼

?/校驗(yàn)頁面是否存在,根據(jù)頁面名稱、站點(diǎn)Id、頁面webpath查詢

=====================

CmsPage cmsPage1 =

cmsPageRepository.findByPageNameAndSiteIdAndPageWebPath(cmsPage.getPageName(),

cmsPage.getSiteId(), cmsPage.getPageWebPath());

if(cmsPage1 !=null){

//校驗(yàn)頁面是否存在,已存在則拋出異常

ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTS);

}

=====================

2、啟動工程,掃描到異常捕獲的類ExceptionCatch

在springBoot的啟動類中添加

@ComponentScan(basePackages="com.xuecheng.framework")//掃描common工程下的類

3、前端展示異常信息

服務(wù)端響應(yīng)信息如下:


頁面提取異常處理?

===============================

addSubmit(){

this.$refs.pageForm.validate((valid) => {

if (valid) {

this.$confirm('確認(rèn)提交嗎?', '提示', {}).then(() => {

cmsApi.page_add(this.pageForm).then((res) => {

console.log(res);

if(res.success){

this.$message({

message: '提交成功',

type: 'success'

});

this.$refs['pageForm'].resetFields();

}else if(res.message){

this.$message.error(res.message);

}else{

this.$message.error('提交失敗');

}

});

});

}

});

}

===============================

5.4 不可預(yù)知異常處理

5.4.1 定義異常捕獲方法

5.4.1.1 異常拋出測試

使用postman測試添加頁面,不輸入cmsPost信息,提交,報(bào)錯信息如下:

org.springframework.http.converter.HttpMessageNotReadableException

此異常是springMVC在進(jìn)行參數(shù)轉(zhuǎn)換時報(bào)的錯誤。

具體的響應(yīng)的信息為:

=====================

{

"timestamp": 1528712906727,

"status": 400,

"error": "Bad Request",

"exception": "org.springframework.http.converter.HttpMessageNotReadableException",

"message": "Required request body is missing: public

com.xuecheng.framework.domain.cms.response.CmsPageResult

com.xuecheng.manage_cms.web.controller.CmsPageController.add(com.xuecheng.framework.domain.cms.C

msPage)",

"path": "/cms/page/add"

}


=====================

上邊的響應(yīng)信息在客戶端是無法解析的。

在異常捕獲類中添加對Exception異常的捕獲:

================

@ExceptionHandler(Exception.class)

@ResponseBody

public ResponseResult exception(Exception exception){

//記錄日志

LOGGER.error("catch exception:{}",exception.getMessage());

return null;

}

================

5.4.1.2 異常捕獲方法

針對上邊的問題其解決方案是:

1、我們在map中配置HttpMessageNotReadableException和錯誤代碼。

2、在異常捕獲類中對Exception異常進(jìn)行捕獲,并從map中獲取異常類型對應(yīng)的錯誤代碼,如果存在錯誤代碼則返

回此錯誤,否則統(tǒng)一返回99999錯誤。

具體的開發(fā)實(shí)現(xiàn)如下:

1、在通用錯誤代碼類CommCode中配置非法參數(shù)異常

INVALID_PARAM(false,10003,"非法參數(shù)!"),

?2、在異常捕獲類中配置 HttpMessageNotReadableException 為非法參數(shù)異常。

異常捕獲類代碼如下:

======================================

package com.xuecheng.framework.exception;

import com.google.common.collect.ImmutableMap;

import com.xuecheng.framework.model.response.CommonCode;

import com.xuecheng.framework.model.response.ResponseResult;

import com.xuecheng.framework.model.response.ResultCode;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.http.converter.HttpMessageNotReadableException;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;


@ControllerAdvice

public class ExceptionCatch {

private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);

//使用EXCEPTIONS存放異常類型和錯誤代碼的映射,ImmutableMap的特點(diǎn)的一旦創(chuàng)建不可改變,并且線程安全

private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;

//使用builder來構(gòu)建一個異常類型和錯誤代碼的異常

protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder =

ImmutableMap.builder();

//捕獲Exception異常

@ResponseBody

@ExceptionHandler(Exception.class)

public ResponseResult exception(Exception e) {

LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);

if(EXCEPTIONS == null)

EXCEPTIONS = builder.build();

}

? ResultCode resultCode = EXCEPTIONS.get(e.getClass());

? ResponseResult responseResult;

if (resultCode != null) {

responseResult = new ResponseResult(resultCode);

} else {

responseResult = new ResponseResult(CommonCode.SERVER_ERROR);

}

return responseResult;

}

//捕獲 CustomException異常

@ExceptionHandler(CustomException.class)

@ResponseBody

public ResponseResult customException(CustomException e) {

LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);

ResultCode resultCode = e.getResultCode();

ResponseResult responseResult = new ResponseResult(resultCode);

return responseResult;

}

static{

//在這里加入一些基礎(chǔ)的異常類型判斷

builder.put(HttpMessageNotReadableException.class,CommonCode.INVALIDPARAM);

}

======================================

5.4.3 異常處理測試

仍然模擬“問題測試”中的測試步驟,異常結(jié)果為“非法參數(shù)”。



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容