Commit 8ae1cefd by yuwei

项目初始化

parent af3e0d59
...@@ -2,13 +2,23 @@ package cn.datax.common.config; ...@@ -2,13 +2,23 @@ package cn.datax.common.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@Configuration @Configuration
public class RestTemplateConfig { public class RestTemplateConfig {
@Bean @Bean
public RestTemplate restTemplate() { public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(); return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);
factory.setConnectTimeout(5000);
return factory;
} }
} }
...@@ -108,6 +108,18 @@ spring: ...@@ -108,6 +108,18 @@ spring:
args: args:
name: dataApiMappingHystrix name: dataApiMappingHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
# 数据服务集成
- id: datax-service-data-integration
uri: lb://datax-service-data-integration
predicates:
- Path=/data/service/**
filters:
- SwaggerHeaderFilter
- StripPrefix=2
- name: Hystrix
args:
name: dataIntegrationHystrix
fallbackUri: forward:/fallback
# 数据可视化 # 数据可视化
- id: datax-service-data-visual - id: datax-service-data-visual
uri: lb://datax-service-data-visual uri: lb://datax-service-data-visual
...@@ -191,4 +203,4 @@ spring: ...@@ -191,4 +203,4 @@ spring:
- name: Hystrix - name: Hystrix
args: args:
name: workflowHystrix name: workflowHystrix
fallbackUri: forward:/fallback fallbackUri: forward:/fallback
\ No newline at end of file
...@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
/** /**
...@@ -46,4 +47,9 @@ public class ServiceIntegrationDto implements Serializable { ...@@ -46,4 +47,9 @@ public class ServiceIntegrationDto implements Serializable {
private String serviceSoap; private String serviceSoap;
@ApiModelProperty(value = "服务方法") @ApiModelProperty(value = "服务方法")
private String serviceMethod; private String serviceMethod;
@ApiModelProperty(value = "状态")
@NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String status;
@ApiModelProperty(value = "备注")
private String remark;
} }
...@@ -28,6 +28,8 @@ public class ServiceLogDto implements Serializable { ...@@ -28,6 +28,8 @@ public class ServiceLogDto implements Serializable {
private String id; private String id;
@ApiModelProperty(value = "服务id") @ApiModelProperty(value = "服务id")
private String serviceId; private String serviceId;
@ApiModelProperty(value = "服务名称")
private String serviceName;
@ApiModelProperty(value = "调用者id") @ApiModelProperty(value = "调用者id")
private String callerId; private String callerId;
@ApiModelProperty(value = "调用者ip") @ApiModelProperty(value = "调用者ip")
...@@ -44,4 +46,6 @@ public class ServiceLogDto implements Serializable { ...@@ -44,4 +46,6 @@ public class ServiceLogDto implements Serializable {
private Long time; private Long time;
@ApiModelProperty(value = "信息记录") @ApiModelProperty(value = "信息记录")
private String msg; private String msg;
@ApiModelProperty(value = "状态:0:失败,1:成功")
private String status;
} }
...@@ -39,6 +39,11 @@ public class ServiceLogEntity implements Serializable { ...@@ -39,6 +39,11 @@ public class ServiceLogEntity implements Serializable {
private String serviceId; private String serviceId;
/** /**
* 服务名称
*/
private String serviceName;
/**
* 调用者id * 调用者id
*/ */
private String callerId; private String callerId;
......
package cn.datax.service.data.market.api.query;
import cn.datax.common.base.BaseQueryParams;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* api调用日志信息表 查询实体
* </p>
*
* @author yuwei
* @since 2020-08-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ApiLogQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
private String apiName;
}
...@@ -17,4 +17,6 @@ import lombok.EqualsAndHashCode; ...@@ -17,4 +17,6 @@ import lombok.EqualsAndHashCode;
public class ServiceLogQuery extends BaseQueryParams { public class ServiceLogQuery extends BaseQueryParams {
private static final long serialVersionUID=1L; private static final long serialVersionUID=1L;
private String serviceName;
} }
...@@ -23,7 +23,6 @@ public class ServiceIntegrationVo implements Serializable { ...@@ -23,7 +23,6 @@ public class ServiceIntegrationVo implements Serializable {
private String status; private String status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime; private LocalDateTime createTime;
private String createDept;
private String serviceNo; private String serviceNo;
private String serviceName; private String serviceName;
private String serviceType; private String serviceType;
......
...@@ -22,6 +22,7 @@ public class ServiceLogVo implements Serializable { ...@@ -22,6 +22,7 @@ public class ServiceLogVo implements Serializable {
private String id; private String id;
private String status; private String status;
private String serviceId; private String serviceId;
private String serviceName;
private String callerId; private String callerId;
private String callerIp; private String callerIp;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
......
package cn.datax.service.data.market.integration.async;
import cn.datax.service.data.market.api.dto.ServiceLogDto;
import cn.datax.service.data.market.integration.service.ServiceLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 异步处理
*/
@Slf4j
@Component
public class AsyncTask {
@Autowired
private ServiceLogService serviceLogService;
@Async("taskExecutor")
public void doTask(ServiceLogDto serviceLog) {
serviceLogService.saveServiceLog(serviceLog);
}
}
package cn.datax.service.data.market.integration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@EnableAsync
@Configuration
public class AsyncConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(30);
executor.setThreadNamePrefix("datax-async-service-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
package cn.datax.service.data.market.integration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);
factory.setConnectTimeout(5000);
return factory;
}
}
package cn.datax.service.data.market.integration.config;
import cn.datax.common.core.DataConstant;
import cn.datax.common.utils.IPUtil;
import cn.datax.common.utils.MD5Util;
import cn.datax.common.utils.RequestHolder;
import cn.datax.service.data.market.api.dto.ServiceExecuteDto;
import cn.datax.service.data.market.api.dto.ServiceLogDto;
import cn.datax.service.data.market.integration.async.AsyncTask;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@Aspect
@Component
public class ServiceLogAspect {
@Autowired
private AsyncTask asyncTask;
@Pointcut("execution(* cn.datax.service.data.market.integration.controller.ServiceExecuteController.execute(..))")
public void logPointCut() {}
/**
* 通知方法会将目标方法封装起来
*
* @param joinPoint 切点
*/
@Around(value = "logPointCut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
ServiceLogDto log = getLog();
log.setTime(endTime - startTime);
handleLog(joinPoint, log);
return result;
}
/**
* 通知方法会在目标方法抛出异常后执行
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
ServiceLogDto log = getLog();
log.setStatus(DataConstant.EnableState.DISABLE.getKey());
log.setMsg(e.getMessage());
handleLog(joinPoint, log);
}
private ServiceLogDto getLog() {
ServiceLogDto log = new ServiceLogDto();
HttpServletRequest request = RequestHolder.getHttpServletRequest();
String serviceKey = request.getHeader("service_key");
String secretKey = request.getHeader("secret_key");
MD5Util mt = null;
try {
mt = MD5Util.getInstance();
String serviceId = mt.decode(serviceKey);
String userId = mt.decode(secretKey);
log.setCallerId(userId);
log.setServiceId(serviceId);
} catch (Exception e) {}
String ipAddr = IPUtil.getIpAddr(request);
log.setCallerIp(ipAddr);
log.setCallerDate(LocalDateTime.now());
log.setStatus(DataConstant.EnableState.ENABLE.getKey());
return log;
}
protected void handleLog(final JoinPoint joinPoint, ServiceLogDto log) {
ServiceExecuteDto arg = (ServiceExecuteDto) joinPoint.getArgs()[0];
log.setCallerSoap(arg.getSoap());
log.setCallerHeader(arg.getHeader());
log.setCallerParam(arg.getParam());
asyncTask.doTask(log);
}
}
...@@ -5,6 +5,8 @@ import cn.datax.service.data.market.integration.service.ServiceExecuteService; ...@@ -5,6 +5,8 @@ import cn.datax.service.data.market.integration.service.ServiceExecuteService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController @RestController
public class ServiceExecuteController { public class ServiceExecuteController {
...@@ -12,8 +14,8 @@ public class ServiceExecuteController { ...@@ -12,8 +14,8 @@ public class ServiceExecuteController {
private ServiceExecuteService serviceExecuteService; private ServiceExecuteService serviceExecuteService;
@PostMapping("/execute") @PostMapping("/execute")
public Object execute(@RequestBody ServiceExecuteDto serviceExecuteDto) { public Object execute(@RequestBody ServiceExecuteDto serviceExecuteDto, HttpServletRequest request) {
Object obj = serviceExecuteService.execute(serviceExecuteDto); Object obj = serviceExecuteService.execute(serviceExecuteDto, request);
return obj; return obj;
} }
} }
...@@ -9,6 +9,7 @@ import cn.datax.service.data.market.api.vo.ServiceLogVo; ...@@ -9,6 +9,7 @@ import cn.datax.service.data.market.api.vo.ServiceLogVo;
import cn.datax.service.data.market.api.query.ServiceLogQuery; import cn.datax.service.data.market.api.query.ServiceLogQuery;
import cn.datax.service.data.market.integration.mapstruct.ServiceLogMapper; import cn.datax.service.data.market.integration.mapstruct.ServiceLogMapper;
import cn.datax.service.data.market.integration.service.ServiceLogService; import cn.datax.service.data.market.integration.service.ServiceLogService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
...@@ -71,6 +72,7 @@ public class ServiceLogController extends BaseController { ...@@ -71,6 +72,7 @@ public class ServiceLogController extends BaseController {
@GetMapping("/page") @GetMapping("/page")
public R getServiceLogPage(ServiceLogQuery serviceLogQuery) { public R getServiceLogPage(ServiceLogQuery serviceLogQuery) {
QueryWrapper<ServiceLogEntity> queryWrapper = new QueryWrapper<>(); QueryWrapper<ServiceLogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StrUtil.isNotBlank(serviceLogQuery.getServiceName()), "service_name", serviceLogQuery.getServiceName());
IPage<ServiceLogEntity> page = serviceLogService.page(new Page<>(serviceLogQuery.getPageNum(), serviceLogQuery.getPageSize()), queryWrapper); IPage<ServiceLogEntity> page = serviceLogService.page(new Page<>(serviceLogQuery.getPageNum(), serviceLogQuery.getPageSize()), queryWrapper);
List<ServiceLogVo> collect = page.getRecords().stream().map(serviceLogMapper::toVO).collect(Collectors.toList()); List<ServiceLogVo> collect = page.getRecords().stream().map(serviceLogMapper::toVO).collect(Collectors.toList());
JsonPage<ServiceLogVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); JsonPage<ServiceLogVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
......
...@@ -2,7 +2,9 @@ package cn.datax.service.data.market.integration.service; ...@@ -2,7 +2,9 @@ package cn.datax.service.data.market.integration.service;
import cn.datax.service.data.market.api.dto.ServiceExecuteDto; import cn.datax.service.data.market.api.dto.ServiceExecuteDto;
import javax.servlet.http.HttpServletRequest;
public interface ServiceExecuteService { public interface ServiceExecuteService {
Object execute(ServiceExecuteDto serviceExecuteDto); Object execute(ServiceExecuteDto serviceExecuteDto, HttpServletRequest request);
} }
...@@ -13,15 +13,13 @@ import com.fasterxml.jackson.core.JsonProcessingException; ...@@ -13,15 +13,13 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity; import org.springframework.http.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
...@@ -39,7 +37,13 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService { ...@@ -39,7 +37,13 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService {
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@Override @Override
public Object execute(ServiceExecuteDto execute) { public Object execute(ServiceExecuteDto execute, HttpServletRequest request) {
// 密钥校验
String serviceKey = request.getHeader("service_key");
String secretKey = request.getHeader("secret_key");
if (StrUtil.isBlank(serviceKey) || StrUtil.isBlank(secretKey)) {
throw new DataException("service_key或secret_key空");
}
if (StrUtil.isBlank(execute.getServiceNo())) { if (StrUtil.isBlank(execute.getServiceNo())) {
throw new DataException("服务编号不能为空"); throw new DataException("服务编号不能为空");
} }
...@@ -87,7 +91,7 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService { ...@@ -87,7 +91,7 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService {
try { try {
response = restTemplate.exchange(serviceIntegrationEntity.getServiceUrl(), httpMethod, httpEntity, String.class); response = restTemplate.exchange(serviceIntegrationEntity.getServiceUrl(), httpMethod, httpEntity, String.class);
} catch (Exception e) { } catch (Exception e) {
throw new DataException("服务调用出错"); throw new DataException(e.getMessage());
} }
} else if (ServiceType.WEBSERVICE.getKey().equals(serviceIntegrationEntity.getServiceType())) { } else if (ServiceType.WEBSERVICE.getKey().equals(serviceIntegrationEntity.getServiceType())) {
// webservice服务 // webservice服务
...@@ -97,7 +101,7 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService { ...@@ -97,7 +101,7 @@ public class ServiceExecuteServiceImpl implements ServiceExecuteService {
try { try {
response = restTemplate.exchange(serviceIntegrationEntity.getServiceWsdl(), HttpMethod.POST, entity, String.class); response = restTemplate.exchange(serviceIntegrationEntity.getServiceWsdl(), HttpMethod.POST, entity, String.class);
} catch (Exception e) { } catch (Exception e) {
throw new DataException("服务调用出错"); throw new DataException(e.getMessage());
} }
} }
return response.getBody(); return response.getBody();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<result column="id" property="id" /> <result column="id" property="id" />
<result column="status" property="status" /> <result column="status" property="status" />
<result column="service_id" property="serviceId" /> <result column="service_id" property="serviceId" />
<result column="service_name" property="serviceName" />
<result column="caller_id" property="callerId" /> <result column="caller_id" property="callerId" />
<result column="caller_ip" property="callerIp" /> <result column="caller_ip" property="callerIp" />
<result column="caller_date" property="callerDate" /> <result column="caller_date" property="callerDate" />
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, id,
status, status,
service_id, caller_id, caller_ip, caller_date, caller_header, caller_param, caller_soap, time, msg service_id, service_name, caller_id, caller_ip, caller_date, caller_header, caller_param, caller_soap, time, msg
</sql> </sql>
</mapper> </mapper>
package cn.datax.service.data.market.mapping.async;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.mapping.service.ApiLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 异步处理
*/
@Slf4j
@Component
public class AsyncTask {
@Autowired
private ApiLogService apiLogService;
@Async("taskExecutor")
public void doTask(ApiLogDto apiLogDto) {
apiLogService.saveApiLog(apiLogDto);
}
}
package cn.datax.service.data.market.mapping.config; package cn.datax.service.data.market.mapping.config;
import cn.datax.service.data.market.mapping.async.AsyncTask;
import cn.datax.service.data.market.mapping.handler.MappingHandlerMapping; import cn.datax.service.data.market.mapping.handler.MappingHandlerMapping;
import cn.datax.service.data.market.mapping.handler.RequestHandler; import cn.datax.service.data.market.mapping.handler.RequestHandler;
import cn.datax.service.data.market.mapping.handler.RequestInterceptor; import cn.datax.service.data.market.mapping.handler.RequestInterceptor;
import cn.datax.service.data.market.mapping.service.ApiLogService;
import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine; import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -19,18 +19,18 @@ public class ApiMappingConfig { ...@@ -19,18 +19,18 @@ public class ApiMappingConfig {
ApiMappingEngine apiMappingEngine, ApiMappingEngine apiMappingEngine,
RedisTemplate redisTemplate, RedisTemplate redisTemplate,
ObjectMapper objectMapper, ObjectMapper objectMapper,
ApiLogService apiLogService) { AsyncTask asyncTask) {
MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping(); MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping();
mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, redisTemplate, objectMapper, apiLogService)); mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, redisTemplate, objectMapper, asyncTask));
mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping); mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping);
return mappingHandlerMapping; return mappingHandlerMapping;
} }
@Bean @Bean
public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, RedisTemplate redisTemplate, ObjectMapper objectMapper, ApiLogService apiLogService) { public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, RedisTemplate redisTemplate, ObjectMapper objectMapper, AsyncTask asyncTask) {
RequestHandler handler = new RequestHandler(); RequestHandler handler = new RequestHandler();
handler.setApiMappingEngine(apiMappingEngine); handler.setApiMappingEngine(apiMappingEngine);
handler.setApiLogService(apiLogService); handler.setAsyncTask(asyncTask);
handler.setObjectMapper(objectMapper); handler.setObjectMapper(objectMapper);
handler.setRequestInterceptor(new RequestInterceptor(redisTemplate)); handler.setRequestInterceptor(new RequestInterceptor(redisTemplate));
return handler; return handler;
......
package cn.datax.service.data.market.mapping.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@EnableAsync
@Configuration
public class AsyncConfig {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(30);
executor.setThreadNamePrefix("datax-async-service-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
package cn.datax.service.data.market.mapping.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.ApiLogEntity;
import cn.datax.service.data.market.api.query.ApiLogQuery;
import cn.datax.service.data.market.api.vo.ApiLogVo;
import cn.datax.service.data.market.mapping.mapstruct.ApiLogMapper;
import cn.datax.service.data.market.mapping.service.ApiLogService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* api调用日志信息表 前端控制器
* </p>
*
* @author yuwei
* @since 2020-08-21
*/
@Api(tags = {"api调用日志信息表"})
@RestController
@RequestMapping("/apiLogs")
public class ApiLogController extends BaseController {
@Autowired
private ApiLogService apiLogService;
@Autowired
private ApiLogMapper apiLogMapper;
/**
* 通过ID查询信息
*
* @param id
* @return
*/
@ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
public R getApiLogById(@PathVariable String id) {
ApiLogEntity apiLogEntity = apiLogService.getApiLogById(id);
return R.ok().setData(apiLogMapper.toVO(apiLogEntity));
}
/**
* 分页查询信息
*
* @param apiLogQuery
* @return
*/
@ApiOperation(value = "分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "apiLogQuery", value = "查询实体apiLogQuery", required = true, dataTypeClass = ApiLogQuery.class)
})
@GetMapping("/page")
public R getApiLogPage(ApiLogQuery apiLogQuery) {
QueryWrapper<ApiLogEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StrUtil.isNotBlank(apiLogQuery.getApiName()), "api_name", apiLogQuery.getApiName());
IPage<ApiLogEntity> page = apiLogService.page(new Page<>(apiLogQuery.getPageNum(), apiLogQuery.getPageSize()), queryWrapper);
List<ApiLogVo> collect = page.getRecords().stream().map(apiLogMapper::toVO).collect(Collectors.toList());
JsonPage<ApiLogVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
return R.ok().setData(jsonPage);
}
/**
* 添加
* @param apiLog
* @return
*/
@ApiOperation(value = "添加信息", notes = "根据apiLog对象添加信息")
@ApiImplicitParam(name = "apiLog", value = "详细实体apiLog", required = true, dataType = "ApiLogDto")
@PostMapping()
public R saveApiLog(@RequestBody @Validated({ValidationGroups.Insert.class}) ApiLogDto apiLog) {
ApiLogEntity apiLogEntity = apiLogService.saveApiLog(apiLog);
return R.ok().setData(apiLogMapper.toVO(apiLogEntity));
}
/**
* 修改
* @param apiLog
* @return
*/
@ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "apiLog", value = "详细实体apiLog", required = true, dataType = "ApiLogDto")
})
@PutMapping("/{id}")
public R updateApiLog(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) ApiLogDto apiLog) {
ApiLogEntity apiLogEntity = apiLogService.updateApiLog(apiLog);
return R.ok().setData(apiLogMapper.toVO(apiLogEntity));
}
/**
* 删除
* @param id
* @return
*/
@ApiOperation(value = "删除", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
public R deleteApiLogById(@PathVariable String id) {
apiLogService.deleteApiLogById(id);
return R.ok();
}
/**
* 批量删除
* @param ids
* @return
*/
@ApiOperation(value = "批量删除角色", notes = "根据url的ids来批量删除对象")
@ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path")
@DeleteMapping("/batch/{ids}")
public R deleteApiLogBatch(@PathVariable List<String> ids) {
apiLogService.deleteApiLogBatch(ids);
return R.ok();
}
}
...@@ -6,7 +6,7 @@ import cn.datax.common.database.core.PageResult; ...@@ -6,7 +6,7 @@ import cn.datax.common.database.core.PageResult;
import cn.datax.common.utils.ThrowableUtil; import cn.datax.common.utils.ThrowableUtil;
import cn.datax.service.data.market.api.dto.ApiLogDto; import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.DataApiEntity; import cn.datax.service.data.market.api.entity.DataApiEntity;
import cn.datax.service.data.market.mapping.service.ApiLogService; import cn.datax.service.data.market.mapping.async.AsyncTask;
import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine; import cn.datax.service.data.market.mapping.service.impl.ApiMappingEngine;
import cn.datax.service.data.market.mapping.utils.ThreadUtil; import cn.datax.service.data.market.mapping.utils.ThreadUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
...@@ -31,7 +31,7 @@ public class RequestHandler { ...@@ -31,7 +31,7 @@ public class RequestHandler {
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
private ApiLogService apiLogService; private AsyncTask asyncTask;
public void setRequestInterceptor(RequestInterceptor requestInterceptor) { public void setRequestInterceptor(RequestInterceptor requestInterceptor) {
this.requestInterceptor = requestInterceptor; this.requestInterceptor = requestInterceptor;
...@@ -45,8 +45,8 @@ public class RequestHandler { ...@@ -45,8 +45,8 @@ public class RequestHandler {
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
public void setApiLogService(ApiLogService apiLogService) { public void setAsyncTask(AsyncTask asyncTask) {
this.apiLogService = apiLogService; this.asyncTask = asyncTask;
} }
@ResponseBody @ResponseBody
...@@ -93,7 +93,7 @@ public class RequestHandler { ...@@ -93,7 +93,7 @@ public class RequestHandler {
ApiLogDto apiLogDto = ThreadUtil.getInstance().get(); ApiLogDto apiLogDto = ThreadUtil.getInstance().get();
log.info("ApiLogDto信息={}", apiLogDto); log.info("ApiLogDto信息={}", apiLogDto);
if (apiLogDto != null) { if (apiLogDto != null) {
apiLogService.saveApiLog(apiLogDto); asyncTask.doTask(apiLogDto);
} }
ThreadUtil.getInstance().remove(); ThreadUtil.getInstance().remove();
} }
......
...@@ -4,7 +4,17 @@ import cn.datax.common.base.BaseService; ...@@ -4,7 +4,17 @@ import cn.datax.common.base.BaseService;
import cn.datax.service.data.market.api.dto.ApiLogDto; import cn.datax.service.data.market.api.dto.ApiLogDto;
import cn.datax.service.data.market.api.entity.ApiLogEntity; import cn.datax.service.data.market.api.entity.ApiLogEntity;
import java.util.List;
public interface ApiLogService extends BaseService<ApiLogEntity> { public interface ApiLogService extends BaseService<ApiLogEntity> {
void saveApiLog(ApiLogDto apiLogDto); ApiLogEntity saveApiLog(ApiLogDto apiLog);
ApiLogEntity updateApiLog(ApiLogDto apiLog);
ApiLogEntity getApiLogById(String id);
void deleteApiLogById(String id);
void deleteApiLogBatch(List<String> ids);
} }
...@@ -11,6 +11,8 @@ import org.springframework.stereotype.Service; ...@@ -11,6 +11,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service @Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ApiLogServiceImpl extends BaseServiceImpl<ApiLogDao, ApiLogEntity> implements ApiLogService { public class ApiLogServiceImpl extends BaseServiceImpl<ApiLogDao, ApiLogEntity> implements ApiLogService {
...@@ -23,8 +25,35 @@ public class ApiLogServiceImpl extends BaseServiceImpl<ApiLogDao, ApiLogEntity> ...@@ -23,8 +25,35 @@ public class ApiLogServiceImpl extends BaseServiceImpl<ApiLogDao, ApiLogEntity>
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveApiLog(ApiLogDto apiLogDto) { public ApiLogEntity saveApiLog(ApiLogDto apiLogDto) {
ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto); ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto);
apiLogDao.insert(apiLog); apiLogDao.insert(apiLog);
return apiLog;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ApiLogEntity updateApiLog(ApiLogDto apiLogDto) {
ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto);
apiLogDao.updateById(apiLog);
return apiLog;
}
@Override
public ApiLogEntity getApiLogById(String id) {
ApiLogEntity apiLogEntity = super.getById(id);
return apiLogEntity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteApiLogById(String id) {
apiLogDao.deleteById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteApiLogBatch(List<String> ids) {
apiLogDao.deleteBatchIds(ids);
} }
} }
import request from '@/utils/request'
export function pageApiLog(data) {
return request({
url: '/data/api/apiLogs/page',
method: 'get',
params: data
})
}
export function getApiLog(id) {
return request({
url: '/data/api/apiLogs/' + id,
method: 'get'
})
}
export function delApiLog(id) {
return request({
url: '/data/api/apiLogs/' + id,
method: 'delete'
})
}
export function delApiLogs(ids) {
return request({
url: '/data/api/apiLogs/batch/' + ids,
method: 'delete'
})
}
import request from '@/utils/request'
export function getApiHeader(id) {
return request({
url: '/data/api/apis/' + id + '/header',
method: 'get'
})
}
export function getApiCall(url, header, data) {
return request({
url: '/data/api/' + url,
method: 'get',
headers: header,
params: data
})
}
export function postApiCall(url, header, data) {
return request({
url: '/data/api/' + url,
method: 'post',
headers: header,
data: data
})
}
import request from '@/utils/request' import request from '@/utils/request'
export function listDataApi (data) { export function listDataApi(data) {
return request({ return request({
url: '/data/market/dataApis/list', url: '/data/market/dataApis/list',
method: 'get', method: 'get',
...@@ -8,7 +8,7 @@ export function listDataApi (data) { ...@@ -8,7 +8,7 @@ export function listDataApi (data) {
}) })
} }
export function pageDataApi (data) { export function pageDataApi(data) {
return request({ return request({
url: '/data/market/dataApis/page', url: '/data/market/dataApis/page',
method: 'get', method: 'get',
...@@ -16,28 +16,28 @@ export function pageDataApi (data) { ...@@ -16,28 +16,28 @@ export function pageDataApi (data) {
}) })
} }
export function getDataApi (id) { export function getDataApi(id) {
return request({ return request({
url: '/data/market/dataApis/' + id, url: '/data/market/dataApis/' + id,
method: 'get' method: 'get'
}) })
} }
export function delDataApi (id) { export function delDataApi(id) {
return request({ return request({
url: '/data/market/dataApis/' + id, url: '/data/market/dataApis/' + id,
method: 'delete' method: 'delete'
}) })
} }
export function delDataApis (ids) { export function delDataApis(ids) {
return request({ return request({
url: '/data/market/dataApis/batch/' + ids, url: '/data/market/dataApis/batch/' + ids,
method: 'delete' method: 'delete'
}) })
} }
export function addDataApi (data) { export function addDataApi(data) {
return request({ return request({
url: '/data/market/dataApis', url: '/data/market/dataApis',
method: 'post', method: 'post',
...@@ -45,7 +45,7 @@ export function addDataApi (data) { ...@@ -45,7 +45,7 @@ export function addDataApi (data) {
}) })
} }
export function updateDataApi (data) { export function updateDataApi(data) {
return request({ return request({
url: '/data/market/dataApis/' + data.id, url: '/data/market/dataApis/' + data.id,
method: 'put', method: 'put',
...@@ -53,7 +53,7 @@ export function updateDataApi (data) { ...@@ -53,7 +53,7 @@ export function updateDataApi (data) {
}) })
} }
export function sqlParse (data) { export function sqlParse(data) {
return request({ return request({
url: '/data/market/dataApis/sql/parse', url: '/data/market/dataApis/sql/parse',
method: 'post', method: 'post',
...@@ -61,56 +61,31 @@ export function sqlParse (data) { ...@@ -61,56 +61,31 @@ export function sqlParse (data) {
}) })
} }
export function copyDataApi (id) { export function copyDataApi(id) {
return request({ return request({
url: '/data/market/dataApis/' + id + '/copy', url: '/data/market/dataApis/' + id + '/copy',
method: 'post' method: 'post'
}) })
} }
export function releaseDataApi (id) { export function releaseDataApi(id) {
return request({ return request({
url: '/data/market/dataApis/' + id + '/release', url: '/data/market/dataApis/' + id + '/release',
method: 'post' method: 'post'
}) })
} }
export function cancelDataApi (id) { export function cancelDataApi(id) {
return request({ return request({
url: '/data/market/dataApis/' + id + '/cancel', url: '/data/market/dataApis/' + id + '/cancel',
method: 'post' method: 'post'
}) })
} }
export function word (id) { export function word(id) {
return request({ return request({
url: '/data/market/dataApis/word/' + id, url: '/data/market/dataApis/word/' + id,
method: 'post', method: 'post',
responseType: 'blob' responseType: 'blob'
}) })
} }
export function getApiHeader (id) {
return request({
url: '/data/api/apis/' + id + '/header',
method: 'get'
})
}
export function getApiCall (url, header, data) {
return request({
url: '/data/api/' + url,
method: 'get',
headers: header,
params: data
})
}
export function postApiCall (url, header, data) {
return request({
url: '/data/api/' + url,
method: 'post',
headers: header,
data: data
})
}
import request from '@/utils/request'
export function pageDataService(data) {
return request({
url: '/data/service/services/page',
method: 'get',
params: data
})
}
export function getDataService(id) {
return request({
url: `/data/service/services/${id}`,
method: 'get'
})
}
export function delDataService(id) {
return request({
url: `/data/service/services/${id}`,
method: 'delete'
})
}
export function delDataServices(ids) {
return request({
url: `/data/service/services/batch/${ids}`,
method: 'delete'
})
}
export function addDataService(data) {
return request({
url: '/data/service/services',
method: 'post',
data: data
})
}
export function updateDataService(data) {
return request({
url: `/data/service/services/${data.id}`,
method: 'put',
data: data
})
}
import request from '@/utils/request'
export function pageDataServiceLog(data) {
return request({
url: '/data/service/serviceLogs/page',
method: 'get',
params: data
})
}
export function getDataServiceLog(id) {
return request({
url: '/data/service/serviceLogs/' + id,
method: 'get'
})
}
export function delDataServiceLog(id) {
return request({
url: '/data/service/serviceLogs/' + id,
method: 'delete'
})
}
export function delDataServiceLogs(ids) {
return request({
url: '/data/service/serviceLogs/batch/' + ids,
method: 'delete'
})
}
...@@ -32,6 +32,16 @@ export default { ...@@ -32,6 +32,16 @@ export default {
.content { .content {
padding: 6px; padding: 6px;
min-height: calc(100vh - 39px - 107px); min-height: calc(100vh - 39px - 107px);
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
} }
} }
.fixed-header+.app-main { .fixed-header+.app-main {
......
<template>
<div>
<el-card class="box-card" shadow="always">
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" label-width="80px" disabled>
<el-form-item label="接口名称" prop="apiName">
<el-input v-model="form.apiName" />
</el-form-item>
<el-form-item label="调用者ip" prop="callerIp">
<el-input v-model="form.callerIp" />
</el-form-item>
<el-form-item label="调用接口url" prop="callerUrl">
<el-input v-model="form.callerUrl" />
</el-form-item>
<el-form-item label="调用参数" prop="callerParams">
<el-input v-model="form.callerParams" />
</el-form-item>
<el-form-item label="调用时间" prop="callerDate">
<el-input v-model="form.callerDate" />
</el-form-item>
<el-form-item label="调用耗时" prop="time">
<el-input v-model="form.time" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-input v-model="form.status" />
</el-form-item>
<el-form-item label="信息记录" prop="msg">
<el-input v-model="form.msg" />
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import { getApiLog } from '@/api/market/apilog'
export default {
name: 'ApiLogDetail',
props: {
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
classCardbody: {
overflow: 'auto',
height: document.body.offsetHeight - 240 + 'px'
},
title: '接口日志详情',
// 展示切换
showOptions: {
data: {},
showList: true,
showDetail: false
},
// 表单参数
form: {}
}
},
created() {
console.log('id:' + this.data.id)
},
mounted() {
this.getLog(this.data.id)
},
methods: {
showCard() {
this.$emit('showCard', this.showOptions)
},
/** 获取详情 */
getLog: function(id) {
getApiLog(id).then(response => {
if (response.success) {
this.form = response.data
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item label="接口名称" prop="apiName">
<el-input
v-model="queryParams.apiName"
placeholder="请输入接口名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row type="flex" justify="space-between">
<el-col :span="12">
<el-button-group>
<el-button
type="info"
icon="el-icon-view"
size="mini"
:disabled="single"
@click="handleDetail"
>详情</el-button>
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleBatchDelete"
>删除</el-button>
</el-button-group>
</el-col>
<el-col :span="12">
<div class="right-toolbar">
<el-tooltip content="密度" effect="dark" placement="top">
<el-dropdown trigger="click" @command="handleCommand">
<el-button circle size="mini">
<svg-icon class-name="size-icon" icon-class="colum-height" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="medium">正常</el-dropdown-item>
<el-dropdown-item command="small">中等</el-dropdown-item>
<el-dropdown-item command="mini">紧凑</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
<el-tooltip content="刷新" effect="dark" placement="top">
<el-button circle size="mini" @click="handleRefresh">
<svg-icon class-name="size-icon" icon-class="shuaxin" />
</el-button>
</el-tooltip>
<el-tooltip content="列设置" effect="dark" placement="top">
<el-popover placement="bottom" width="100" trigger="click">
<el-checkbox-group v-model="checkedTableColumns" @change="handleCheckedColsChange">
<el-checkbox
v-for="(item, index) in tableColumns"
:key="index"
:label="item.prop"
>{{ item.label }}</el-checkbox>
</el-checkbox-group>
<span slot="reference">
<el-button circle size="mini">
<svg-icon class-name="size-icon" icon-class="shezhi" />
</el-button>
</span>
</el-popover>
</el-tooltip>
</div>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="logList"
border
tooltip-effect="dark"
:size="tableSize"
:height="tableHeight"
style="width: 100%;margin: 15px 0;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(item, index) in tableColumns">
<el-table-column
v-if="item.show"
:key="index"
:prop="item.prop"
:label="item.label"
:formatter="item.formatter"
align="center"
show-overflow-tooltip
/>
</template>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popover
placement="left"
trigger="click"
>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleDetail(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<el-button slot="reference">操作</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="queryParams.pageNum"
:page-size.sync="queryParams.pageSize"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
</div>
</template>
<script>
import { pageApiLog, delApiLog, delApiLogs } from '@/api/market/apilog'
export default {
name: 'ApiLogList',
data() {
return {
tableHeight: document.body.offsetHeight - 340 + 'px',
// 展示切换
showOptions: {
data: {},
showList: true,
showDetail: false
},
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 表格头
tableColumns: [
{ prop: 'apiName', label: '接口名称', show: true },
{ prop: 'callerIp', label: '调用者ip', show: true },
{ prop: 'callerSize', label: '调用数据量', show: true },
{ prop: 'time', label: '调用耗时', show: true },
{
prop: 'status',
label: '状态',
show: true,
formatter: this.statusFormatter
},
{ prop: 'callerDate', label: '调用时间', show: true }
],
// 默认选择中表格头
checkedTableColumns: [],
tableSize: 'medium',
// 日志表格数据
logList: [],
// 总数据条数
total: 0,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
apiName: ''
},
// 状态数据字典
statusOptions: []
}
},
created() {
this.getDicts('sys_normal_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getList()
},
mounted() {
this.initCols()
},
methods: {
/** 查询日志列表 */
getList() {
this.loading = true
pageApiLog(this.queryParams).then(response => {
this.loading = false
if (response.success) {
const { data } = response
this.logList = data.data
this.total = data.total
}
})
},
initCols() {
this.checkedTableColumns = this.tableColumns.map(col => col.prop)
},
handleCheckedColsChange(val) {
this.tableColumns.forEach(col => {
if (!this.checkedTableColumns.includes(col.prop)) {
col.show = false
} else {
col.show = true
}
})
},
handleCommand(command) {
this.tableSize = command
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.$refs['queryForm'].resetFields()
this.handleQuery()
},
/** 刷新列表 */
handleRefresh() {
this.getList()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 详情按钮操作 */
handleDetail(row) {
this.showOptions.data.id = row.id || this.ids[0]
this.showOptions.showList = false
this.showOptions.showDetail = true
this.$emit('showCard', this.showOptions)
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm('选中数据将被永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delApiLog(row.id)
}).then(() => {
this.$message.success('删除成功')
this.getList()
}).catch(() => {
})
},
/** 批量删除按钮操作 */
handleBatchDelete() {
if (!this.ids.length) {
this.$message({
message: '请先选择需要操作的数据',
type: 'warning'
})
}
this.$message.warning('不支持批量删除')
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`)
this.queryParams.pageNum = 1
this.queryParams.pageSize = val
this.getList()
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`)
this.queryParams.pageNum = val
this.getList()
},
statusFormatter(row, column, cellValue, index) {
const dictLabel = this.selectDictLabel(this.statusOptions, cellValue)
if (cellValue === '1') {
return <el-tag type='success'>{dictLabel}</el-tag>
} else {
return <el-tag type='warning'>{dictLabel}</el-tag>
}
}
}
}
</script>
<style lang="scss" scoped>
.right-toolbar {
float: right;
}
</style>
<template>
<div class="app-container">
<transition name="el-zoom-in-center">
<log-list v-if="options.showList" @showCard="showCard" />
</transition>
<transition name="el-zoom-in-bottom">
<log-detail v-if="options.showDetail" :data="options.data" @showCard="showCard" />
</transition>
</div>
</template>
<script>
import LogList from './LogList'
import LogDetail from './LogDetail'
export default {
name: 'ApiLog',
components: { LogList, LogDetail },
data() {
return {
options: {
data: {},
showList: true,
showDetail: false
}
}
},
methods: {
showCard(data) {
Object.assign(this.options, data)
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-plus" round :loading="loadingOptions.loading" :disabled="loadingOptions.isDisabled" @click="submitForm">{{ loadingOptions.loadingText }}</el-button>
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="form.serviceName" placeholder="请输入服务名称" />
</el-form-item>
<el-form-item label="服务类型" prop="serviceType">
<el-select v-model="form.serviceType">
<el-option
v-for="item in serviceTypeOptions"
:key="item.id"
:label="item.itemValue"
:value="item.itemText"
/>
</el-select>
</el-form-item>
<template v-if="form.serviceType === '1'">
<el-form-item label="服务请求地址" prop="serviceUrl">
<el-input v-model="form.serviceUrl" placeholder="请输入服务请求地址" />
</el-form-item>
<el-form-item label="服务请求头" prop="serviceHeader">
<el-input v-model="form.serviceHeader" placeholder="请输入服务请求头,如{key:val}格式" />
</el-form-item>
<el-form-item label="服务请求参数" prop="serviceParam">
<el-input v-model="form.serviceParam" placeholder="请输入服务请求参数,如{key:val}格式" />
</el-form-item>
<el-form-item label="服务请求方式" prop="serviceHttpMethod">
<el-select v-model="form.serviceHttpMethod" placeholder="请选择请求方式">
<el-option
v-for="dict in httpMethodOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
/>
</el-select>
</el-form-item>
</template>
<template v-if="form.serviceType === '2'">
<el-form-item label="服务wsdl地址" prop="serviceWsdl">
<el-input v-model="form.serviceWsdl" placeholder="请输入服务wsdl地址" />
</el-form-item>
<el-form-item label="服务命名空间" prop="serviceTargetNamespace">
<el-input v-model="form.serviceTargetNamespace" placeholder="请输入服务命名空间" />
</el-form-item>
<el-form-item label="服务方法" prop="serviceMethod">
<el-input v-model="form.serviceMethod" placeholder="请输入服务方法" />
</el-form-item>
<el-form-item label="服务请求报文" prop="serviceSoap">
<el-input v-model="form.serviceSoap" type="textarea" placeholder="请输入服务请求报文" />
</el-form-item>
</template>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.id"
:label="dict.itemText"
>{{ dict.itemValue }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import { addDataService } from '@/api/market/dataservice'
export default {
name: 'DataServiceAdd',
props: {
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
classCardbody: {
overflow: 'auto',
height: document.body.offsetHeight - 240 + 'px'
},
title: '服务集成新增',
// 展示切换
showOptions: {
data: {},
showList: true,
showAdd: false,
showEdit: false,
showDetail: false
},
// 保存按钮
loadingOptions: {
loading: false,
loadingText: '保存',
isDisabled: false
},
// 表单参数
form: {
serviceType: '1',
status: '1'
},
// 表单校验
rules: {
serviceName: [
{ required: true, message: '服务名称不能为空', trigger: 'blur' }
],
serviceType: [
{ required: true, message: '服务类型不能为空', trigger: 'change' }
],
serviceUrl: [
{ required: true, message: '服务请求地址不能为空', trigger: 'blur' }
],
serviceHttpMethod: [
{ required: true, message: '服务请求方式不能为空', trigger: 'blur' }
],
serviceWsdl: [
{ required: true, message: '服务wsdl地址不能为空', trigger: 'blur' }
],
serviceTargetNamespace: [
{ required: true, message: '服务命名空间不能为空', trigger: 'blur' }
],
serviceSoap: [
{ required: true, message: '服务请求报文不能为空', trigger: 'blur' }
],
serviceMethod: [
{ required: true, message: '服务方法不能为空', trigger: 'blur' }
]
},
// 状态数据字典
statusOptions: [],
serviceTypeOptions: [],
httpMethodOptions: []
}
},
created() {
this.getDicts('sys_common_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getDicts('data_service_type').then(response => {
if (response.success) {
this.serviceTypeOptions = response.data
}
})
this.getDicts('data_req_method').then(response => {
if (response.success) {
this.httpMethodOptions = response.data
}
})
},
methods: {
showCard() {
this.$emit('showCard', this.showOptions)
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
addDataService(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
// 2秒后跳转列表页
this.$emit('showCard', this.showOptions)
}, 2000)
} else {
this.$message.error('保存失败')
this.loadingOptions.loading = false
this.loadingOptions.loadingText = '保存'
this.loadingOptions.isDisabled = false
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" label-width="80px" disabled>
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="form.serviceName" placeholder="请输入服务名称" />
</el-form-item>
<el-form-item label="服务编号" prop="serviceNo">
<el-input v-model="form.serviceNo" />
</el-form-item>
<el-form-item label="服务类型" prop="serviceType">
<el-select v-model="form.serviceType">
<el-option
v-for="item in serviceTypeOptions"
:key="item.id"
:label="item.itemValue"
:value="item.itemText"
/>
</el-select>
</el-form-item>
<template v-if="form.serviceType === '1'">
<el-form-item label="服务请求地址" prop="serviceUrl">
<el-input v-model="form.serviceUrl" placeholder="请输入服务请求地址" />
</el-form-item>
<el-form-item label="服务请求头" prop="serviceHeader">
<el-input v-model="form.serviceHeader" placeholder="请输入服务请求头" />
</el-form-item>
<el-form-item label="服务请求参数" prop="serviceParam">
<el-input v-model="form.serviceParam" placeholder="请输入服务请求参数" />
</el-form-item>
<el-form-item label="服务请求方式" prop="serviceHttpMethod">
<el-select v-model="form.serviceHttpMethod" placeholder="请选择请求方式">
<el-option
v-for="dict in httpMethodOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
/>
</el-select>
</el-form-item>
</template>
<template v-if="form.serviceType === '2'">
<el-form-item label="服务wsdl地址" prop="serviceWsdl">
<el-input v-model="form.serviceWsdl" placeholder="请输入服务wsdl地址" />
</el-form-item>
<el-form-item label="服务命名空间" prop="serviceTargetNamespace">
<el-input v-model="form.serviceTargetNamespace" placeholder="请输入服务命名空间" />
</el-form-item>
<el-form-item label="服务方法" prop="serviceMethod">
<el-input v-model="form.serviceMethod" placeholder="请输入服务方法" />
</el-form-item>
<el-form-item label="服务请求报文" prop="serviceSoap">
<el-input v-model="form.serviceSoap" type="textarea" placeholder="请输入服务请求报文" />
</el-form-item>
</template>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.id"
:label="dict.itemText"
>{{ dict.itemValue }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import { getDataService } from '@/api/market/dataservice'
export default {
name: 'DataServiceDetail',
props: {
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
classCardbody: {
overflow: 'auto',
height: document.body.offsetHeight - 240 + 'px'
},
title: '服务集成详情',
// 展示切换
showOptions: {
data: {},
showList: true,
showAdd: false,
showEdit: false,
showDetail: false
},
// 表单参数
form: {},
// 状态数据字典
statusOptions: [],
serviceTypeOptions: [],
httpMethodOptions: []
}
},
created() {
console.log('id:' + this.data.id)
this.getDicts('sys_common_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getDicts('data_service_type').then(response => {
if (response.success) {
this.serviceTypeOptions = response.data
}
})
this.getDicts('data_req_method').then(response => {
if (response.success) {
this.httpMethodOptions = response.data
}
})
},
mounted() {
this.getDataService(this.data.id)
},
methods: {
showCard() {
this.$emit('showCard', this.showOptions)
},
/** 获取详情 */
getDataService: function(id) {
getDataService(id).then(response => {
if (response.success) {
this.form = response.data
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-plus" round :loading="loadingOptions.loading" :disabled="loadingOptions.isDisabled" @click="submitForm">{{ loadingOptions.loadingText }}</el-button>
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="form.serviceName" placeholder="请输入服务名称" />
</el-form-item>
<el-form-item label="服务编号" prop="serviceNo">
<el-input v-model="form.serviceNo" :disabled="true" />
</el-form-item>
<el-form-item label="服务类型" prop="serviceType">
<el-select v-model="form.serviceType">
<el-option
v-for="item in serviceTypeOptions"
:key="item.id"
:label="item.itemValue"
:value="item.itemText"
/>
</el-select>
</el-form-item>
<template v-if="form.serviceType === '1'">
<el-form-item label="服务请求地址" prop="serviceUrl">
<el-input v-model="form.serviceUrl" placeholder="请输入服务请求地址" />
</el-form-item>
<el-form-item label="服务请求头" prop="serviceHeader">
<el-input v-model="form.serviceHeader" placeholder="请输入服务请求头" />
</el-form-item>
<el-form-item label="服务请求参数" prop="serviceParam">
<el-input v-model="form.serviceParam" placeholder="请输入服务请求参数" />
</el-form-item>
<el-form-item label="服务请求方式" prop="serviceHttpMethod">
<el-select v-model="form.serviceHttpMethod" placeholder="请选择请求方式">
<el-option
v-for="dict in httpMethodOptions"
:key="dict.id"
:label="dict.itemValue"
:value="dict.itemText"
/>
</el-select>
</el-form-item>
</template>
<template v-if="form.serviceType === '2'">
<el-form-item label="服务wsdl地址" prop="serviceWsdl">
<el-input v-model="form.serviceWsdl" placeholder="请输入服务wsdl地址" />
</el-form-item>
<el-form-item label="服务命名空间" prop="serviceTargetNamespace">
<el-input v-model="form.serviceTargetNamespace" placeholder="请输入服务命名空间" />
</el-form-item>
<el-form-item label="服务方法" prop="serviceMethod">
<el-input v-model="form.serviceMethod" placeholder="请输入服务方法" />
</el-form-item>
<el-form-item label="服务请求报文" prop="serviceSoap">
<el-input v-model="form.serviceSoap" type="textarea" placeholder="请输入服务请求报文" />
</el-form-item>
</template>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in statusOptions"
:key="dict.id"
:label="dict.itemText"
>{{ dict.itemValue }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import { getDataService, updateDataService } from '@/api/market/dataservice'
export default {
name: 'DataServiceEdit',
props: {
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
classCardbody: {
overflow: 'auto',
height: document.body.offsetHeight - 240 + 'px'
},
title: '服务集成编辑',
// 展示切换
showOptions: {
data: {},
showList: true,
showAdd: false,
showEdit: false,
showDetail: false
},
// 保存按钮
loadingOptions: {
loading: false,
loadingText: '保存',
isDisabled: false
},
// 表单参数
form: {},
// 表单校验
rules: {
serviceName: [
{ required: true, message: '服务名称不能为空', trigger: 'blur' }
],
serviceType: [
{ required: true, message: '服务类型不能为空', trigger: 'change' }
],
serviceUrl: [
{ required: true, message: '服务请求地址不能为空', trigger: 'blur' }
],
serviceHttpMethod: [
{ required: true, message: '服务请求方式不能为空', trigger: 'blur' }
],
serviceWsdl: [
{ required: true, message: '服务wsdl地址不能为空', trigger: 'blur' }
],
serviceTargetNamespace: [
{ required: true, message: '服务命名空间不能为空', trigger: 'blur' }
],
serviceSoap: [
{ required: true, message: '服务请求报文不能为空', trigger: 'blur' }
],
serviceMethod: [
{ required: true, message: '服务方法不能为空', trigger: 'blur' }
]
},
// 状态数据字典
statusOptions: [],
serviceTypeOptions: [],
httpMethodOptions: []
}
},
created() {
console.log('id:' + this.data.id)
this.getDicts('sys_common_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getDicts('data_service_type').then(response => {
if (response.success) {
this.serviceTypeOptions = response.data
}
})
this.getDicts('data_req_method').then(response => {
if (response.success) {
this.httpMethodOptions = response.data
}
})
},
mounted() {
this.getDataService(this.data.id)
},
methods: {
showCard() {
this.$emit('showCard', this.showOptions)
},
/** 获取详情 */
getDataService: function(id) {
getDataService(id).then(response => {
if (response.success) {
this.form = response.data
}
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
this.loadingOptions.loading = true
this.loadingOptions.loadingText = '保存中...'
this.loadingOptions.isDisabled = true
updateDataService(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
setTimeout(() => {
// 2秒后跳转列表页
this.$emit('showCard', this.showOptions)
}, 2000)
} else {
this.$message.error('保存失败')
this.loadingOptions.loading = false
this.loadingOptions.loadingText = '保存'
this.loadingOptions.isDisabled = false
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="app-container">
<transition name="el-zoom-in-center">
<data-service-list v-if="options.showList" @showCard="showCard" />
</transition>
<transition name="el-zoom-in-top">
<data-service-add v-if="options.showAdd" :data="options.data" @showCard="showCard" />
</transition>
<transition name="el-zoom-in-top">
<data-service-edit v-if="options.showEdit" :data="options.data" @showCard="showCard" />
</transition>
<transition name="el-zoom-in-bottom">
<data-service-detail v-if="options.showDetail" :data="options.data" @showCard="showCard" />
</transition>
</div>
</template>
<script>
import DataServiceList from './DataServiceList'
import DataServiceAdd from './DataServiceAdd'
import DataServiceEdit from './DataServiceEdit'
import DataServiceDetail from './DataServiceDetail'
export default {
name: 'DataSource',
components: { DataServiceList, DataServiceAdd, DataServiceEdit, DataServiceDetail },
data() {
return {
options: {
data: {},
showList: true,
showAdd: false,
showEdit: false,
showDetail: false
}
}
},
methods: {
showCard(data) {
Object.assign(this.options, data)
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<div slot="header" class="clearfix">
<span>{{ title }}</span>
<el-button-group style="float: right;">
<el-button size="mini" icon="el-icon-back" round @click="showCard">返回</el-button>
</el-button-group>
</div>
<div :style="classCardbody">
<el-form ref="form" :model="form" label-width="80px" disabled>
<el-form-item label="服务名称" prop="serviceName">
<el-input v-model="form.serviceName" />
</el-form-item>
<el-form-item label="调用者ip" prop="callerIp">
<el-input v-model="form.callerIp" />
</el-form-item>
<el-form-item label="调用请求头" prop="callerHeader">
<el-input v-model="form.callerHeader" />
</el-form-item>
<el-form-item label="调用请求参数" prop="callerParam">
<el-input v-model="form.callerParam" />
</el-form-item>
<el-form-item label="调用报文" prop="callerSoap">
<el-input v-model="form.callerSoap" />
</el-form-item>
<el-form-item label="调用时间" prop="callerDate">
<el-input v-model="form.callerDate" />
</el-form-item>
<el-form-item label="调用耗时" prop="time">
<el-input v-model="form.time" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-input v-model="form.status" />
</el-form-item>
<el-form-item label="信息记录" prop="msg">
<el-input v-model="form.msg" />
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import { getDataServiceLog } from '@/api/market/dataservicelog'
export default {
name: 'ServiceLogDetail',
props: {
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
classCardbody: {
overflow: 'auto',
height: document.body.offsetHeight - 240 + 'px'
},
title: '服务日志详情',
// 展示切换
showOptions: {
data: {},
showList: true,
showDetail: false
},
// 表单参数
form: {}
}
},
created() {
console.log('id:' + this.data.id)
},
mounted() {
this.getLog(this.data.id)
},
methods: {
showCard() {
this.$emit('showCard', this.showOptions)
},
/** 获取详情 */
getLog: function(id) {
getDataServiceLog(id).then(response => {
if (response.success) {
this.form = response.data
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<el-card class="box-card" shadow="always">
<el-form ref="queryForm" :model="queryParams" :inline="true">
<el-form-item label="服务名称" prop="serviceName">
<el-input
v-model="queryParams.serviceName"
placeholder="请输入服务名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row type="flex" justify="space-between">
<el-col :span="12">
<el-button-group>
<el-button
type="info"
icon="el-icon-view"
size="mini"
:disabled="single"
@click="handleDetail"
>详情</el-button>
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleBatchDelete"
>删除</el-button>
</el-button-group>
</el-col>
<el-col :span="12">
<div class="right-toolbar">
<el-tooltip content="密度" effect="dark" placement="top">
<el-dropdown trigger="click" @command="handleCommand">
<el-button circle size="mini">
<svg-icon class-name="size-icon" icon-class="colum-height" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="medium">正常</el-dropdown-item>
<el-dropdown-item command="small">中等</el-dropdown-item>
<el-dropdown-item command="mini">紧凑</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-tooltip>
<el-tooltip content="刷新" effect="dark" placement="top">
<el-button circle size="mini" @click="handleRefresh">
<svg-icon class-name="size-icon" icon-class="shuaxin" />
</el-button>
</el-tooltip>
<el-tooltip content="列设置" effect="dark" placement="top">
<el-popover placement="bottom" width="100" trigger="click">
<el-checkbox-group v-model="checkedTableColumns" @change="handleCheckedColsChange">
<el-checkbox
v-for="(item, index) in tableColumns"
:key="index"
:label="item.prop"
>{{ item.label }}</el-checkbox>
</el-checkbox-group>
<span slot="reference">
<el-button circle size="mini">
<svg-icon class-name="size-icon" icon-class="shezhi" />
</el-button>
</span>
</el-popover>
</el-tooltip>
</div>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="logList"
border
tooltip-effect="dark"
:size="tableSize"
:height="tableHeight"
style="width: 100%;margin: 15px 0;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" width="55" align="center">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<template v-for="(item, index) in tableColumns">
<el-table-column
v-if="item.show"
:key="index"
:prop="item.prop"
:label="item.label"
:formatter="item.formatter"
align="center"
show-overflow-tooltip
/>
</template>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-popover
placement="left"
trigger="click"
>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleDetail(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<el-button slot="reference">操作</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="queryParams.pageNum"
:page-size.sync="queryParams.pageSize"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
</div>
</template>
<script>
import { pageDataServiceLog, delDataServiceLog, delDataServiceLogs } from '@/api/market/dataservicelog'
export default {
name: 'ServiceLogList',
data() {
return {
tableHeight: document.body.offsetHeight - 340 + 'px',
// 展示切换
showOptions: {
data: {},
showList: true,
showDetail: false
},
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 表格头
tableColumns: [
{ prop: 'serviceName', label: '服务名称', show: true },
{ prop: 'callerIp', label: '调用者ip', show: true },
{ prop: 'time', label: '调用耗时', show: true },
{
prop: 'status',
label: '状态',
show: true,
formatter: this.statusFormatter
},
{ prop: 'callerDate', label: '调用时间', show: true }
],
// 默认选择中表格头
checkedTableColumns: [],
tableSize: 'medium',
// 日志表格数据
logList: [],
// 总数据条数
total: 0,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
serviceName: ''
},
// 状态数据字典
statusOptions: []
}
},
created() {
this.getDicts('sys_normal_status').then(response => {
if (response.success) {
this.statusOptions = response.data
}
})
this.getList()
},
mounted() {
this.initCols()
},
methods: {
/** 查询日志列表 */
getList() {
this.loading = true
pageDataServiceLog(this.queryParams).then(response => {
this.loading = false
if (response.success) {
const { data } = response
this.logList = data.data
this.total = data.total
}
})
},
initCols() {
this.checkedTableColumns = this.tableColumns.map(col => col.prop)
},
handleCheckedColsChange(val) {
this.tableColumns.forEach(col => {
if (!this.checkedTableColumns.includes(col.prop)) {
col.show = false
} else {
col.show = true
}
})
},
handleCommand(command) {
this.tableSize = command
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.$refs['queryForm'].resetFields()
this.handleQuery()
},
/** 刷新列表 */
handleRefresh() {
this.getList()
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 详情按钮操作 */
handleDetail(row) {
this.showOptions.data.id = row.id || this.ids[0]
this.showOptions.showList = false
this.showOptions.showDetail = true
this.$emit('showCard', this.showOptions)
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm('选中数据将被永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delDataServiceLog(row.id)
}).then(() => {
this.$message.success('删除成功')
this.getList()
}).catch(() => {
})
},
/** 批量删除按钮操作 */
handleBatchDelete() {
if (!this.ids.length) {
this.$message({
message: '请先选择需要操作的数据',
type: 'warning'
})
}
this.$message.warning('不支持批量删除')
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`)
this.queryParams.pageNum = 1
this.queryParams.pageSize = val
this.getList()
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`)
this.queryParams.pageNum = val
this.getList()
},
statusFormatter(row, column, cellValue, index) {
const dictLabel = this.selectDictLabel(this.statusOptions, cellValue)
if (cellValue === '1') {
return <el-tag type='success'>{dictLabel}</el-tag>
} else {
return <el-tag type='warning'>{dictLabel}</el-tag>
}
}
}
}
</script>
<style lang="scss" scoped>
.right-toolbar {
float: right;
}
</style>
<template>
<div class="app-container">
<transition name="el-zoom-in-center">
<log-list v-if="options.showList" @showCard="showCard" />
</transition>
<transition name="el-zoom-in-bottom">
<log-detail v-if="options.showDetail" :data="options.data" @showCard="showCard" />
</transition>
</div>
</template>
<script>
import LogList from './LogList'
import LogDetail from './LogDetail'
export default {
name: 'ServiceLog',
components: { LogList, LogDetail },
data() {
return {
options: {
data: {},
showList: true,
showDetail: false
}
}
},
methods: {
showCard(data) {
Object.assign(this.options, data)
}
}
}
</script>
<style lang="scss" scoped>
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment