1、接口&函数锁定和解锁。2、修复无法测试上传的问题

This commit is contained in:
mxd
2021-09-09 21:50:55 +08:00
parent c7f952e60e
commit 617f15aa0b
16 changed files with 211 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
package org.ssssssss.magicapi.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -8,6 +9,7 @@ import org.ssssssss.magicapi.config.Valid;
import org.ssssssss.magicapi.interceptor.Authorization;
import org.ssssssss.magicapi.model.ApiInfo;
import org.ssssssss.magicapi.model.Backup;
import org.ssssssss.magicapi.model.Constants;
import org.ssssssss.magicapi.model.JsonBean;
import javax.servlet.http.HttpServletRequest;
@@ -33,7 +35,9 @@ public class MagicAPIController extends MagicController implements MagicExceptio
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> delete(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.DELETE, getApiInfo(id)), PERMISSION_INVALID);
ApiInfo apiInfo = getApiInfo(id);
isTrue(allowVisit(request, Authorization.DELETE, apiInfo), PERMISSION_INVALID);
isTrue(!Constants.LOCK.equals(apiInfo.getLock()), RESOURCE_LOCKED);
return new JsonBean<>(magicAPIService.deleteApi(id));
}
@@ -102,6 +106,7 @@ public class MagicAPIController extends MagicController implements MagicExceptio
// 新的分组ID
apiInfo.setGroupId(groupId);
isTrue(allowVisit(request, Authorization.SAVE, apiInfo), PERMISSION_INVALID);
isTrue(!Constants.LOCK.equals(apiInfo.getLock()), RESOURCE_LOCKED);
return new JsonBean<>(magicAPIService.moveApi(id, groupId));
}
@@ -113,10 +118,36 @@ public class MagicAPIController extends MagicController implements MagicExceptio
@Valid(readonly = false)
public JsonBean<String> save(HttpServletRequest request, @RequestBody ApiInfo info) {
isTrue(allowVisit(request, Authorization.SAVE, info), PERMISSION_INVALID);
if (StringUtils.isNotBlank(info.getId())) {
ApiInfo oldInfo = getApiInfo(info.getId());
isTrue(!Constants.LOCK.equals(oldInfo.getLock()), RESOURCE_LOCKED);
}
return new JsonBean<>(magicAPIService.saveApi(info));
}
private ApiInfo getApiInfo(String id){
/**
* 锁定接口
*/
@RequestMapping("/lock")
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> lock(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.LOCK, getApiInfo(id)), PERMISSION_INVALID);
return new JsonBean<>(magicAPIService.lockApi(id));
}
/**
* 解锁接口
*/
@RequestMapping("/unlock")
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> unlock(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.UNLOCK, getApiInfo(id)), PERMISSION_INVALID);
return new JsonBean<>(magicAPIService.unlockApi(id));
}
private ApiInfo getApiInfo(String id) {
ApiInfo apiInfo = magicAPIService.getApiInfo(id);
notNull(apiInfo, API_NOT_FOUND);
return apiInfo;

View File

@@ -1,5 +1,6 @@
package org.ssssssss.magicapi.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -7,6 +8,7 @@ import org.ssssssss.magicapi.config.MagicConfiguration;
import org.ssssssss.magicapi.config.Valid;
import org.ssssssss.magicapi.interceptor.Authorization;
import org.ssssssss.magicapi.model.Backup;
import org.ssssssss.magicapi.model.Constants;
import org.ssssssss.magicapi.model.FunctionInfo;
import org.ssssssss.magicapi.model.JsonBean;
@@ -63,6 +65,7 @@ public class MagicFunctionController extends MagicController implements MagicExc
FunctionInfo functionInfo = getFunctionInfo(id);
functionInfo.setGroupId(groupId);
isTrue(allowVisit(request, Authorization.SAVE, functionInfo), PERMISSION_INVALID);
isTrue(!Constants.LOCK.equals(functionInfo.getLock()), RESOURCE_LOCKED);
return new JsonBean<>(magicAPIService.moveFunction(id, groupId));
}
@@ -72,6 +75,10 @@ public class MagicFunctionController extends MagicController implements MagicExc
@Valid(readonly = false)
public JsonBean<String> save(HttpServletRequest request, @RequestBody FunctionInfo functionInfo) {
isTrue(allowVisit(request, Authorization.SAVE, functionInfo), PERMISSION_INVALID);
if (StringUtils.isNotBlank(functionInfo.getId())) {
FunctionInfo oldInfo = getFunctionInfo(functionInfo.getId());
isTrue(!Constants.LOCK.equals(oldInfo.getLock()), RESOURCE_LOCKED);
}
return new JsonBean<>(magicAPIService.saveFunction(functionInfo));
}
@@ -79,10 +86,34 @@ public class MagicFunctionController extends MagicController implements MagicExc
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> delete(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.DELETE, getFunctionInfo(id)), PERMISSION_INVALID);
FunctionInfo info = getFunctionInfo(id);
isTrue(allowVisit(request, Authorization.DELETE, info), PERMISSION_INVALID);
isTrue(!Constants.LOCK.equals(info.getLock()), RESOURCE_LOCKED);
return new JsonBean<>(magicAPIService.deleteFunction(id));
}
/**
* 锁定函数
*/
@RequestMapping("/function/lock")
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> lock(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.LOCK, getFunctionInfo(id)), PERMISSION_INVALID);
return new JsonBean<>(magicAPIService.lockFunction(id));
}
/**
* 解锁函数
*/
@RequestMapping("/function/unlock")
@ResponseBody
@Valid(readonly = false)
public JsonBean<Boolean> unlock(HttpServletRequest request, String id) {
isTrue(allowVisit(request, Authorization.UNLOCK, getFunctionInfo(id)), PERMISSION_INVALID);
return new JsonBean<>(magicAPIService.unlockFunction(id));
}
public FunctionInfo getFunctionInfo(String id) {
FunctionInfo functionInfo = magicAPIService.getFunctionInfo(id);
notNull(functionInfo, FUNCTION_NOT_FOUND);

View File

@@ -28,5 +28,13 @@ public enum Authorization {
/**
* 执行推送动作
*/
PUSH
PUSH,
/**
* 锁定动作
*/
LOCK,
/**
* 解锁动作
*/
UNLOCK
}

View File

@@ -264,6 +264,7 @@ public class ApiInfo extends MagicEntity {
target.setGroupId(this.getGroupId());
target.setPath(this.getPath());
target.setMethod(this.getMethod());
target.setLock(this.getLock());
return target;
}

View File

@@ -107,6 +107,10 @@ public class Constants {
public static final String UPLOAD_MODE_FULL = "full";
public static final String LOCK = "1";
public static final String UNLOCK = "0";
/**
* 执行成功的code值
*/

View File

@@ -19,6 +19,8 @@ public interface JsonCodeConstants {
JsonCode NAME_CONFLICT = new JsonCode(0, "移动后名称会重复,请修改名称后在试。");
JsonCode RESOURCE_LOCKED = new JsonCode(0, "当前资源已被锁定,请解锁后在操作。");
JsonCode REQUEST_PATH_CONFLICT = new JsonCode(0, "该路径已被映射,请换一个请求方法或路径");
JsonCode FUNCTION_PATH_CONFLICT = new JsonCode(0, "该路径已被映射,请换一个请求方法或路径");

View File

@@ -14,6 +14,8 @@ public class MagicEntity extends Attributes<Object> implements Cloneable {
protected Long updateTime;
protected String lock;
public String getId() {
return id;
}
@@ -62,6 +64,14 @@ public class MagicEntity extends Attributes<Object> implements Cloneable {
this.name = name;
}
public String getLock() {
return lock;
}
public void setLock(String lock) {
this.lock = lock;
}
public MagicEntity clone() {
try {
return (MagicEntity) super.clone();

View File

@@ -47,6 +47,14 @@ public interface MagicAPIService extends MagicModule {
*/
String saveApi(ApiInfo apiInfo);
boolean lockApi(String id);
boolean unlockApi(String id);
boolean lockFunction(String id);
boolean unlockFunction(String id);
/**
* 获取接口详情
*

View File

@@ -4,6 +4,7 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ssssssss.magicapi.adapter.Resource;
import org.ssssssss.magicapi.model.Constants;
import org.ssssssss.magicapi.model.MagicEntity;
import org.ssssssss.magicapi.utils.JsonUtils;
@@ -84,6 +85,24 @@ public abstract class StoreServiceProvider<T extends MagicEntity> {
return false;
}
public boolean lock(String id){
T info = get(id);
if(info != null){
info.setLock(Constants.LOCK);
return update(info);
}
return false;
}
public boolean unlock(String id){
T info = get(id);
if(info != null){
info.setLock(Constants.UNLOCK);
return update(info);
}
return false;
}
/**
* 查询所有(提供给页面,无需带script
*/

View File

@@ -228,6 +228,33 @@ public class DefaultMagicAPIService implements MagicAPIService, JsonCodeConstant
return info.getId();
}
@Override
public boolean lockApi(String id) {
return lockWithNotify(apiServiceProvider.lock(id), id, NOTIFY_ACTION_API);
}
@Override
public boolean unlockApi(String id) {
return lockWithNotify(apiServiceProvider.unlock(id), id, NOTIFY_ACTION_API);
}
@Override
public boolean lockFunction(String id) {
return lockWithNotify(functionServiceProvider.lock(id), id, NOTIFY_ACTION_FUNCTION);
}
@Override
public boolean unlockFunction(String id) {
return lockWithNotify(functionServiceProvider.unlock(id), id, NOTIFY_ACTION_FUNCTION);
}
private boolean lockWithNotify(boolean success, String id, int type){
if(success){
magicNotifyService.sendNotify(new MagicNotify(instanceId, id, NOTIFY_ACTION_UPDATE, type));
}
return success;
}
@Override
public ApiInfo getApiInfo(String id) {
return apiServiceProvider.get(id);

View File

@@ -11,6 +11,14 @@
-moz-osx-font-smoothing: grayscale;
}
.ma-icon-lock:before {
content: "\e64f";
}
.ma-icon-unlock:before {
content: "\e783";
}
.ma-icon-collapse:before {
content: "\e609";
}

View File

@@ -18,7 +18,8 @@
>
<i class="ma-svg-icon" v-if="item._type === 'api'" :class="['request-method-' + item.method]" />
<i class="ma-svg-icon" v-if="item._type !== 'api'" :class="['icon-function']" />
{{item.name}}<span v-show="!item.id || item.script !== item.ext.tmpScript">*</span>
{{item.name}}<i class="ma-icon ma-icon-lock" v-if="item.lock === '1'" />
<span v-show="!item.id || item.script !== item.ext.tmpScript">*</span>
<i class="ma-icon ma-icon-close" @click.stop="close(item.id || item.tmp_id)"/>
</li>
</ul>
@@ -548,7 +549,7 @@ export default {
requestConfig.headers['Content-Type'] = 'multipart/form-data';
let formData = new FormData()
Object.keys(params).forEach(key => {
let value = requestConfig.data[key];
let value = params[key];
if(value instanceof FileList){
value.forEach(file => formData.append(key, file, file.name))
}else{
@@ -958,12 +959,14 @@ ul li.draggableTargetItem {
background: var(--hover-background);
}
ul li i {
ul li i:not(.ma-icon-lock) {
color: var(--icon-color);
margin-left: 5px;
font-size: 0.5em;
}
.ma-icon-lock{
margin-left: 5px;
}
.ma-editor-container > div {
flex: 1;
}

View File

@@ -64,6 +64,7 @@
<i class="ma-svg-icon" :class="['request-method-' + item.method]" />
<label>{{ item.name }}</label>
<span>({{ item.path }})</span>
<i class="ma-icon ma-icon-lock" v-if="item.lock === '1'"></i>
</div>
</template>
</magic-tree>
@@ -320,6 +321,7 @@ export default {
parameters: null,
paths: null,
option: null,
lock: '0',
requestBody: null,
headers: null,
responseBody: null,
@@ -449,9 +451,27 @@ export default {
this.copyPathToClipboard(item, true)
}
},
{
label: `${item.lock === '1' ? '解锁' : '锁定'}`,
icon: `ma-icon-${item.lock === '1' ? 'unlock' : 'lock'}`,
onClick: () => {
let action = item.lock === '1' ? '解锁接口' : '锁定接口';
request.send(item.lock === '1' ? 'unlock' : 'lock', {id: item.id}).success(data => {
if (data) {
bus.$emit('status', `${action}${item.name}(${item.path})」`)
bus.$emit('report', `api_${item.lock === '1' ? 'unlock' : 'lock'}`)
item['lock'] = item.lock === '1' ? '0' : '1';
this.changeForceUpdate()
} else {
this.$magicAlert({content: `${action}失败`})
}
})
}
},
{
label: '刷新接口',
icon: 'ma-icon-refresh',
divided: true,
onClick: () => {
this.initData()
}

View File

@@ -62,6 +62,7 @@
<i class="ma-svg-icon icon-function" />
<label>{{ item.name }}</label>
<span>({{ item.path }})</span>
<i class="ma-icon ma-icon-lock" v-if="item.lock === '1'"></i>
</div>
</template>
</magic-tree>
@@ -319,6 +320,7 @@ export default {
path: '',
script: null,
name: '未定义名称',
lock: '0',
parameters: null,
description: null,
level: item.level + 1,
@@ -413,9 +415,27 @@ export default {
this.open(newItem)
}
},
{
label: `${item.lock === '1' ? '解锁' : '锁定'}`,
icon: `ma-icon-${item.lock === '1' ? 'unlock' : 'lock'}`,
onClick: () => {
let action = item.lock === '1' ? '解锁函数' : '锁定函数';
request.send(item.lock === '1' ? 'function/unlock' : 'function/lock', {id: item.id}).success(data => {
if (data) {
bus.$emit('status', `${action}${item.name}(${item.path})」`)
bus.$emit('report', `function_${item.lock === '1' ? 'unlock' : 'lock'}`)
item['lock'] = item.lock === '1' ? '0' : '1';
this.changeForceUpdate()
} else {
this.$magicAlert({content: `${action}失败`})
}
})
}
},
{
label: '刷新函数',
icon: 'ma-icon-refresh',
divided: true,
onClick: () => {
this.initData()
}

View File

@@ -41,10 +41,21 @@
.ma-tree-wrapper span {
color: var(--toolbox-list-span-color);
display: inline-block;
height: 22px;
line-height: 22px;
}
.ma-tree-wrapper .ma-icon-lock {
color: var(--toolbox-list-label-color);
margin-left: 5px;
}
.ma-tree-wrapper label {
color: var(--toolbox-list-label-color);
display: inline-block;
height: 22px;
line-height: 22px;
}
.ma-tree-wrapper .ma-tree-toolbar-search {