目录
接口编辑功能
基本设置:
- 接口名称
- 选择分类
- 请求方法
- 接口地址
请求参数设置,去api_request_param表中去取:
- Query
- Body
- Headers
备注:
apiEdit.html的代码修改
selected="true"等价于selected=“selected”
<div class="del-interpre del-interedit">
<div class="basicinfo-interpre basicset-interedit">
<div class="comtit-interpre notop">基本设置</div>
<div class="setlist-interedit">
<div class="line-interedit line-com">
<label><span>*</span>接口名称:</label>
<div class="ipt-interedit">
<input name="name" :value="api.name" placeholder="接口名称" type="text">
</div>
</div>
<div class="line-interedit line-com">
<label><span>*</span>选择分类:</label>
<div class="ipt-interedit">
<select name="apiClassificationId" id="">
<option :value="apiClassification.id" v-for="apiClassification in apiClassifications" :selected="api.apiClassificationId==apiClassification.id">{{apiClassification.name}}</option>
<!-- <option value="cs2">测试1</option>
<option value="cs3">测试2</option> -->
</select>
</div>
</div>
<div class="line-interedit line-com">
<label><span>*</span>请求方法<i class="icon-doubt"></i>:</label>
<div class="ipt-interedit">
<select name="method" id="" class="reqtype-interedit"
style="width:15%;margin-right:0;">
<option value="get" :selected="api.method=='get'">GET</option>
<option value="post" :selected="api.method=='post'">POST</option>
<option value="put" :selected="api.method=='put'">PUT</option>
<option value="delete" :selected="api.method=='delete'">DELETE</option>
<option value="head" :selected="api.method=='head'">HEAD</option>
<option value="option" :selected="api.method=='option'">OPTION</option>
<option value="patch" :selected="api.method=='patch'">PATCH</option>
</select>
</div>
</div>
<div class="line-interedit line-com">
<label><span>*</span>接口地址<i class="icon-doubt"></i>:</label>
<div class="ipt-interedit">
<input placeholder="/path" name="url" :value="api.url" type="text">
</div>
</div>
</div>
</div>
接口编辑页的效果图
注册接口编辑页的效果图:
登录接口编辑页的效果图:
apiEdit.html请求参数部分的代码修改
注释掉写死的这部分代码:
接口编辑页的请求参数设置的效果图
注册接口的请求参数设置的效果图:
登录接口的请求参数设置的效果图:
toApiView的接口请求与响应
请求:
Request URL: http://admin.ck.org/lemon/api/toApiView?apiId=2
返回:
{
"status": "1",
"data": {
"id": 2,
"apiClassificationId": 1,
"name": "注册",
"method": "post",
"url": "/futureloan/mvc/api/member/register",
"description": "",
"createUser": 2,
"createTime": "2019-08-16T06:23:28.000+0000",
"createUsername": "[email protected]",
"host": null,
"requestParams": [{
"id": 88,
"apiId": 2,
"name": "mobilephone",
"paramType": "string",
"type": 2,
"exampleData": "",
"description": ""
}, {
"id": 93,
"apiId": 2,
"name": "pwd",
"paramType": "string",
"type": 2,
"exampleData": "",
"description": ""
}, {
"id": 94,
"apiId": 2,
"name": "Content-Type",
"paramType": "string",
"type": 3,
"exampleData": "application/x-www-form-urlencoded;charset=utf-8",
"description": ""
}],
"queryParams": [],
"bodyParams": [],
"headerParams": [],
"bodyRawParams": []
},
"message": null
}
接口更新和保存功能
- edit接口的请求和响应
请求:
Request URL: http://www.ck.org/lemon/api/edit
请求体:
id: 4
name: %E6%B3%A8%E5%86%8C
apiClassificationId: 1
method: post
url: %2Ffutureloan%2Fmvc%2Fapi%2Fmember%2Fregister
requestParams%5B0%5D.id: 88
requestParams%5B0%5D.apiId: 2
requestParams%5B0%5D.type: 2
requestParams%5B0%5D.name: mobilephone
requestParams%5B0%5D.paramType: string
requestParams%5B0%5D.exampleData:
requestParams%5B0%5D.description: %E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0
requestParams%5B1%5D.id: 93
requestParams%5B1%5D.apiId: 2
requestParams%5B1%5D.type: 2
requestParams%5B1%5D.name: pwd
requestParams%5B1%5D.paramType: string
requestParams%5B1%5D.exampleData:
requestParams%5B1%5D.description: %E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0
requestParams%5B2%5D.id: 94
requestParams%5B2%5D.apiId: 2
requestParams%5B2%5D.type: 3
requestParams%5B2%5D.name: Content-Type
requestParams%5B2%5D.paramType: string
requestParams%5B2%5D.exampleData:
requestParams%5B2%5D.description: %E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0
apiEdit.html的代码再次修改
<script src="/lemon/js/vue.js"></script>
<script src="/lemon/js/axios.min.js"></script>
<script type="text/javascript" src="/lemon/js/jquery.cookie.js" charset="UTF-8"></script>
<script type="text/javascript">
var app = new Vue({
el: ".del-interpre",
data: {
api: {},
apiClassifications: []
},
methods: {
showClassification() {
let projectId = sessionStorage.getItem("projectId");
var url = lemon.config.global.adminUrl + "/apiClassification/findAll";
axios.get(url,
{
headers: { "Authorization": $.cookie("sessionId") },
params: { "projectId": projectId }
})
.then(response => {
this.apiClassifications = response.data.data;
});
},
showApi() {
let apiId = sessionStorage.getItem("apiId");
axios.get(lemon.config.global.adminUrl + "/api/toApiView", {
headers: { "Authorization": $.cookie("sessionId") },
params: { "apiId": apiId }
}).then(response => {
this.api = response.data.data;
if (this.api.status == 1 & this.api.message == "未登陆") {
location.href = lemon.config.global.rootUrl + "/html/login.html";
}
let requestParams = this.api.requestParams;
for (let i = 0; i < requestParams.length; i++) {
let param = requestParams[i];
let str = `<div class="line-interedit line-com">
<input name="requestParams[${i}].id" value="${param.id}" type="hidden">
<input name="requestParams[${i}].apiId" value="${param.apiId}" type="hidden">
<input name="requestParams[${i}].type" value="${param.type}" type="hidden">
<input placeholder="name" name="requestParams[${i}].name" value="${param.name}"
style="width:20%" type="text">
<select name="requestParams[${i}].paramType" id="" style="width:12%">
<option value="string" selected="${param.paramType=='string'}">string</option>
<option value="int" ${param.paramType=='int'?'selected':''}>int</option>
</select>
<textarea name="requestParams[${i}].exampleData" id="" value="${param.exampleData}" placeholder="参数示例"
style="width:20%"></textarea>
<textarea name="requestParams[${i}].description" id="" value="${param.description}" placeholder="备注"
style="width:29%">表单提交参数</textarea>
<i class="icon icon-delete f-l"></i>
</div>`;
if (param.type == 1) {
$("#reqpQuery .linebox-interedit").append(str);
} else if (param.type == 2) {
$("#reqpBody .linebox-interedit").append(str);
} else if (param.type == 3) {
$("#reqpHeaders .linebox-interedit").append(str);
} else {
}
}
});
}
},
created() {
this.showClassification();
this.showApi();
}
})
</script>
<script type="text/javascript" src="/lemon/js/base.js"></script>
<script type="text/javascript" src="/lemon/js/apiEdit.js"></script>
接口编辑和保存功能的思路
- 接口基本信息,编辑完成保存,要做更新操作。
- 如果请求参数,数据库无数据,要做插入操作(insert api_request_param表)。
- 如果请求参数,数据库有数据,要做更新操作(update api_request_param表)。
- 无论是插入还是更新操作,都根据apiId先做一遍delete from api_request_param表操作,就可以统一操作,都进行insert插入操作,就少了一次判断操作,很难去判断有值还是没有值。从业务角度上来讲,是有插入和更新两种可能行的。但是在操作层面上来将,可以降低判断成本。
- 不根据主键id去删除,根据外键apiId进行删除,删除得较为干净,也比较容易查询出来。
addAll(list)
整个子集的数据,都追加到历史集合的数据当中。
add只可以加一个,addAll(list)就可以加一个集合。
最终的结果就是,子集把它的值给到总的集合。
为什么要这么做?
原因是因为如果没有添加的话,全部是requestParams。
但是用户如果做了额外的操作,点击了添加。
用了前端设计的,分成了Query、Body和Header。
这些值相对独立,所以用这个方法。
//3.insert apiRequestParam
apiEdit.getRequestParams().addAll(apiEdit.getQueryParams());
apiEdit.getRequestParams().addAll(apiEdit.getHeaderParams());
apiEdit.getRequestParams().addAll(apiEdit.getBodyParams());
apiEdit.getRequestParams().addAll(apiEdit.getBodyRawParams());
apiRequestParamService.saveBatch(apiEdit.getRequestParams());
后端ApiController.java的代码修改
package com.one.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.one.common.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.one.common.ApiListVO;
import com.one.common.ApiVO;
import com.one.service.ApiRequestParamService;
import com.one.service.ApiService;
/**
* <p>
* 前端控制器
* </p>
*
* @author annie
* @since 2020-02-16
*/
@RestController
@RequestMapping("/api")
public class ApiController {
@Autowired
ApiService apiService;
@Autowired
ApiRequestParamService apiRequestParamService;
@GetMapping("/showApiUnderProject")
public Result showApiListByProject(Integer projectId){
List<ApiListVO> list = apiService.showApiListByProject(projectId);
Result result = new Result("1",list);
return result;
}
@GetMapping("/showApiUnderApiClassification")
public Result showApiUnderApiClassification(Integer apiClassificationId){
List<ApiListVO> list = apiService.showApiListByApiClassification(apiClassificationId);
Result result = new Result("1",list);
return result;
}
@GetMapping("/toApiView")
public Result findApiViewVO(Integer apiId){
ApiVO api = apiService.findApiViewVO(apiId);
Result result = new Result("1",api);
return result;
}
@PutMapping("/edit")
public Result toApiEdit(ApiVO apiEdit){
//1.直接根据apiId进行更新api
apiService.updateById(apiEdit);
//2.delete原来的apiRequestParam
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("api_id", apiEdit.getId());
apiRequestParamService.remove(queryWrapper);
//3.insert apiRequestParam
apiEdit.getRequestParams().addAll(apiEdit.getQueryParams());
apiEdit.getRequestParams().addAll(apiEdit.getHeaderParams());
apiEdit.getRequestParams().addAll(apiEdit.getBodyParams());
apiEdit.getRequestParams().addAll(apiEdit.getBodyRawParams());
apiRequestParamService.saveBatch(apiEdit.getRequestParams());
Result result = new Result("1","更新成功");
return result;
}
}
apiEdit.js的代码修改
更新保存按钮的代码如下:
//保存按钮
$(".comfirm-interedit").find(".btn-com").click(function(){
$.ajax({
headers:{"Authorization":$.cookie("sessionId")},
url:lemon.config.global.adminUrl+"/api/edit",
data:$("[name='apiEditForm']").serialize(),
type:'put',
dataType:'json',
success:function(ret){
if(ret!=null){
alert(ret.message);
}
}
});
});
遇到的问题汇总
问题:发现编辑后保存,要更新的apiId不正确,apiId始终传的是4。
解决方法:
查看apiEdit.html的代码,如下value写死了,需要把value="4"
修改成:value="api.id"
,api.id通过隐藏表单传过去。
且需要将代码<input name="id" :value="api.id" type="hidden">
修改放在vue的挂载点<div class="del-interpre del-interedit">
下面。
<form name="apiEditForm">
<div class="del-interpre del-interedit">
<input name="id" :value="api.id" type="hidden">