[fix] 支持页面话操作网络代理

This commit is contained in:
wujiawei
2024-01-16 15:07:03 +08:00
parent a3a16394ef
commit 6980426dc0
106 changed files with 1754 additions and 16664 deletions

View File

@@ -125,6 +125,25 @@ public class ChannelContext {
}
}
/**
* 关闭通道
*
* @param clientId 客户端ID
*/
public static void clear(String clientId) {
ClientChannel clientChannel = get(clientId);
if (clientChannel != null) {
remove(clientId);
Channel channel = clientChannel.getChannel();
if (channel != null && channel.isActive()) {
channel.close();
}
} else {
// log warm
log.warn("无法通过客户ID:[{}]移除客户端", clientId);
}
}
/**
* 通过客户端ID移除客户端通道
*
@@ -140,6 +159,21 @@ public class ChannelContext {
}
}
/**
* 通过客户端ID移除客户端通道
*
* @param clientId 客户端ID
*/
public static void remove(String clientId) {
ClientChannel clientChannel = get(clientId);
if (clientChannel != null) {
channelIdClientChannelDTOConcurrentHashMap.remove(clientChannel.getChannelId());
} else {
// log warm
log.warn("无法通过客户ID:[{}]移除客户端", clientId);
}
}
/**
* 客户端通道信息

View File

@@ -1,5 +1,7 @@
package wu.framework.lazy.cloud.heartbeat.common;
import io.netty.channel.Channel;
import java.util.concurrent.ConcurrentHashMap;
/**

View File

@@ -25,7 +25,7 @@
</dependency>
<!-- 通用心跳包 -->
<dependency>
<groupId>top.wu2020</groupId>
<groupId>top.wu2020</groupId>
<artifactId>wu-lazy-cloud-heartbeat-common</artifactId>
<version>1.2.2-JDK17-SNAPSHOT</version>
</dependency>
@@ -43,9 +43,15 @@
<groupId>top.wu2020</groupId>
<artifactId>wu-database-lazy-plus-starter</artifactId>
</dependency>
<!-- 授权平台 -->
<dependency>
<groupId>top.wu2020</groupId>
<artifactId>wu-authorization-server-starter</artifactId>
<artifactId>wu-authorization-server-platform-starter</artifactId>
</dependency>
<!-- jvm -->
<dependency>
<groupId>top.wu2020</groupId>
<artifactId>wu-jvm-server-platform-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>

View File

@@ -0,0 +1,109 @@
package wu.framework.lazy.cloud.heartbeat.server.application;
import com.wu.framework.response.Result;
import com.wu.framework.response.ResultFactory;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorRemoveCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorStoryCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorUpdateCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryListCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryOneCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.dto.NettyServerVisitorDTO;
import java.util.List;
import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplication
**/
public interface NettyServerVisitorApplication {
/**
* describe 新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommand 新增服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口新增后领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> story(NettyServerVisitorStoryCommand nettyServerVisitorStoryCommand);
/**
* describe 批量新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommandList 批量新增服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口新增后领域对象集合
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<List<NettyServerVisitor>> batchStory(List<NettyServerVisitorStoryCommand> nettyServerVisitorStoryCommandList);
/**
* describe 更新服务端提前开放出来的端口
*
* @param nettyServerVisitorUpdateCommand 更新服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> updateOne(NettyServerVisitorUpdateCommand nettyServerVisitorUpdateCommand);
/**
* describe 查询单个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryOneCommand 查询单个服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitorDTO>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitorDTO> findOne(NettyServerVisitorQueryOneCommand nettyServerVisitorQueryOneCommand);
/**
* describe 查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 查询多个服务端提前开放出来的端口
* @return {@link Result <List<NettyServerVisitorDTO>>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result <List<NettyServerVisitorDTO>> findList(NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand);
/**
* describe 分页查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 分页查询多个服务端提前开放出来的端口
* @return {@link Result <LazyPage<NettyServerVisitorDTO>>} 分页服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result <LazyPage<NettyServerVisitorDTO>> findPage(int size,int current,NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand);
/**
* describe 删除服务端提前开放出来的端口
*
* @param nettyServerVisitorRemoveCommand 删除服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> remove(NettyServerVisitorRemoveCommand nettyServerVisitorRemoveCommand);
}

View File

@@ -0,0 +1,93 @@
package wu.framework.lazy.cloud.heartbeat.server.application.assembler;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorRemoveCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorStoryCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorUpdateCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryListCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryOneCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.dto.NettyServerVisitorDTO;
import org.mapstruct.factory.Mappers;
import org.mapstruct.Mapper;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyAssembler
**/
@Mapper
public interface NettyServerVisitorDTOAssembler {
/**
* describe MapStruct 创建的代理对象
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitorDTOAssembler INSTANCE = Mappers.getMapper(NettyServerVisitorDTOAssembler.class);
/**
* describe 应用层存储入参转换成 领域对象
*
* @param nettyServerVisitorStoryCommand 保存服务端提前开放出来的端口对象
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorStoryCommand nettyServerVisitorStoryCommand);
/**
* describe 应用层更新入参转换成 领域对象
*
* @param nettyServerVisitorUpdateCommand 更新服务端提前开放出来的端口对象
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorUpdateCommand nettyServerVisitorUpdateCommand);
/**
* describe 应用层查询入参转换成 领域对象
*
* @param nettyServerVisitorQueryOneCommand 查询单个服务端提前开放出来的端口对象参数
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorQueryOneCommand nettyServerVisitorQueryOneCommand);
/**
* describe 应用层查询入参转换成 领域对象
*
* @param nettyServerVisitorQueryListCommand 查询集合服务端提前开放出来的端口对象参数
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand);
/**
* describe 应用层删除入参转换成 领域对象
*
* @param nettyServerVisitorRemoveCommand 删除服务端提前开放出来的端口对象参数
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorRemoveCommand nettyServerVisitorRemoveCommand);
/**
* describe 持久层领域对象转换成DTO对象
*
* @param nettyServerVisitor 服务端提前开放出来的端口领域对象
* @return {@link NettyServerVisitorDTO} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitorDTO fromNettyServerVisitor(NettyServerVisitor nettyServerVisitor);
}

View File

@@ -67,5 +67,11 @@ public class NettyClientStateQueryListCommand {
*/
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -68,4 +68,10 @@ public class NettyClientStateQueryOneCommand {
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -67,5 +67,11 @@ public class NettyClientStateStoryCommand {
*/
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -67,5 +67,11 @@ public class NettyClientStateUpdateCommand {
*/
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryListCommand
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_query_List_command",description = "服务端提前开放出来的端口")
public class NettyServerVisitorQueryListCommand {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyQueryOneCommand
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_query_one_command",description = "服务端提前开放出来的端口")
public class NettyServerVisitorQueryOneCommand {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyRemoveCommand
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_remove_command",description = "服务端提前开放出来的端口")
public class NettyServerVisitorRemoveCommand {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyStoryCommand
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_story_command",description = "服务端提前开放出来的端口")
public class NettyServerVisitorStoryCommand {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyUpdateCommand
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_update_command",description = "服务端提前开放出来的端口")
public class NettyServerVisitorUpdateCommand {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -1,5 +1,6 @@
package wu.framework.lazy.cloud.heartbeat.server.application.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -43,6 +44,7 @@ public class InternalNetworkPenetrationMappingDTO {
*
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
@@ -64,6 +66,7 @@ public class InternalNetworkPenetrationMappingDTO {
*
* 修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;

View File

@@ -68,4 +68,11 @@ public class NettyClientStateDTO {
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.application.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDTO
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor_command_dto",description = "服务端提前开放出来的端口")
public class NettyServerVisitorDTO {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -2,6 +2,8 @@ package wu.framework.lazy.cloud.heartbeat.server.application.impl;
import wu.framework.lazy.cloud.heartbeat.common.ChannelContext;
import wu.framework.lazy.cloud.heartbeat.common.NettyVisitorContext;
import wu.framework.lazy.cloud.heartbeat.server.application.NettyClientStateApplication;
import wu.framework.lazy.cloud.heartbeat.server.application.assembler.NettyClientStateDTOAssembler;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.client.state.NettyClientStateStoryCommand;
@@ -135,7 +137,11 @@ public class NettyClientStateApplicationImpl implements NettyClientStateApplicat
@Override
public Result<NettyClientState> remove(NettyClientStateRemoveCommand nettyClientStateRemoveCommand) {
NettyClientState nettyClientState = NettyClientStateDTOAssembler.INSTANCE.toNettyClientState(nettyClientStateRemoveCommand);
return nettyClientStateRepository.remove(nettyClientState);
// 获取当前客户端通道 而后关闭
String clientId = nettyClientStateRemoveCommand.getClientId();
// 心跳关闭
ChannelContext.clear(clientId);
return nettyClientStateRepository.remove(nettyClientState);
}
}

View File

@@ -0,0 +1,144 @@
package wu.framework.lazy.cloud.heartbeat.server.application.impl;
import com.wu.framework.database.lazy.web.plus.stereotype.LazyApplication;
import wu.framework.lazy.cloud.heartbeat.server.application.NettyServerVisitorApplication;
import org.springframework.web.bind.annotation.*;
import com.wu.framework.response.Result;
import com.wu.framework.response.ResultFactory;
import org.springframework.beans.factory.annotation.Autowired;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorRemoveCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorStoryCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorUpdateCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryListCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryOneCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.assembler.NettyServerVisitorDTOAssembler;
import wu.framework.lazy.cloud.heartbeat.server.application.dto.NettyServerVisitorDTO;
import java.util.stream.Collectors;
import jakarta.annotation.Resource;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitorRepository;
import java.util.List;
import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyApplicationImpl
**/
@LazyApplication
public class NettyServerVisitorApplicationImpl implements NettyServerVisitorApplication {
@Resource
NettyServerVisitorRepository nettyServerVisitorRepository;
/**
* describe 新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommand 新增服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口新增后领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> story(NettyServerVisitorStoryCommand nettyServerVisitorStoryCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorStoryCommand);
return nettyServerVisitorRepository.story(nettyServerVisitor);
}
/**
* describe 批量新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommandList 批量新增服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口新增后领域对象集合
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<List<NettyServerVisitor>> batchStory(List<NettyServerVisitorStoryCommand> nettyServerVisitorStoryCommandList) {
List<NettyServerVisitor> nettyServerVisitorList = nettyServerVisitorStoryCommandList.stream().map( NettyServerVisitorDTOAssembler.INSTANCE::toNettyServerVisitor).collect(Collectors.toList());
return nettyServerVisitorRepository.batchStory(nettyServerVisitorList);
}
/**
* describe 更新服务端提前开放出来的端口
*
* @param nettyServerVisitorUpdateCommand 更新服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> updateOne(NettyServerVisitorUpdateCommand nettyServerVisitorUpdateCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorUpdateCommand);
return nettyServerVisitorRepository.story(nettyServerVisitor);
}
/**
* describe 查询单个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryOneCommand 查询单个服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitorDTO>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitorDTO> findOne(NettyServerVisitorQueryOneCommand nettyServerVisitorQueryOneCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorQueryOneCommand);
return nettyServerVisitorRepository.findOne(nettyServerVisitor).convert(NettyServerVisitorDTOAssembler.INSTANCE::fromNettyServerVisitor);
}
/**
* describe 查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 查询多个服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitorDTO>>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<List<NettyServerVisitorDTO>> findList(NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorQueryListCommand);
return nettyServerVisitorRepository.findList(nettyServerVisitor) .convert(nettyServerVisitors -> nettyServerVisitors.stream().map(NettyServerVisitorDTOAssembler.INSTANCE::fromNettyServerVisitor).collect(Collectors.toList())) ;
}
/**
* describe 分页查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 分页查询多个服务端提前开放出来的端口
* @return {@link Result<LazyPage<NettyServerVisitorDTO>>} 分页服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<LazyPage<NettyServerVisitorDTO>> findPage(int size,int current,NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorQueryListCommand);
return nettyServerVisitorRepository.findPage(size,current,nettyServerVisitor) .convert(page -> page.convert(NettyServerVisitorDTOAssembler.INSTANCE::fromNettyServerVisitor)) ;
}
/**
* describe 删除服务端提前开放出来的端口
*
* @param nettyServerVisitorRemoveCommand 删除服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> remove(NettyServerVisitorRemoveCommand nettyServerVisitorRemoveCommand) {
NettyServerVisitor nettyServerVisitor = NettyServerVisitorDTOAssembler.INSTANCE.toNettyServerVisitor(nettyServerVisitorRemoveCommand);
return nettyServerVisitorRepository.remove(nettyServerVisitor);
}
}

View File

@@ -0,0 +1,142 @@
package wu.framework.lazy.cloud.heartbeat.server.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import com.wu.framework.inner.layer.web.EasyController;
import org.springframework.web.bind.annotation.*;
import com.wu.framework.response.Result;
import com.wu.framework.response.ResultFactory;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.annotation.Resource;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorRemoveCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorStoryCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorUpdateCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryListCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.command.netty.server.visitor.NettyServerVisitorQueryOneCommand;
import wu.framework.lazy.cloud.heartbeat.server.application.NettyServerVisitorApplication;
import wu.framework.lazy.cloud.heartbeat.server.application.dto.NettyServerVisitorDTO;
import java.util.List;
import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyController
**/
@Tag(name = "服务端提前开放出来的端口提供者")
@EasyController("/netty/server/visitor")
public class NettyServerVisitorProvider {
@Resource
private NettyServerVisitorApplication nettyServerVisitorApplication;
/**
* describe 新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommand 新增服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口新增后领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "新增服务端提前开放出来的端口")
@PostMapping("/story")
public Result<NettyServerVisitor> story(@RequestBody NettyServerVisitorStoryCommand nettyServerVisitorStoryCommand){
return nettyServerVisitorApplication.story(nettyServerVisitorStoryCommand);
}
/**
* describe 批量新增服务端提前开放出来的端口
*
* @param nettyServerVisitorStoryCommandList 批量新增服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口新增后领域对象集合
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "批量新增服务端提前开放出来的端口")
@PostMapping("/batchStory")
public Result<List<NettyServerVisitor>> batchStory(@RequestBody List<NettyServerVisitorStoryCommand> nettyServerVisitorStoryCommandList){
return nettyServerVisitorApplication.batchStory(nettyServerVisitorStoryCommandList);
}
/**
* describe 更新服务端提前开放出来的端口
*
* @param nettyServerVisitorUpdateCommand 更新服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "更新服务端提前开放出来的端口")
@PutMapping("/updateOne")
public Result<NettyServerVisitor> updateOne(@RequestBody NettyServerVisitorUpdateCommand nettyServerVisitorUpdateCommand){
return nettyServerVisitorApplication.updateOne(nettyServerVisitorUpdateCommand);
}
/**
* describe 查询单个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryOneCommand 查询单个服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitorDTO>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "查询单个服务端提前开放出来的端口")
@GetMapping("/findOne")
public Result<NettyServerVisitorDTO> findOne(@ModelAttribute NettyServerVisitorQueryOneCommand nettyServerVisitorQueryOneCommand){
return nettyServerVisitorApplication.findOne(nettyServerVisitorQueryOneCommand);
}
/**
* describe 查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 查询多个服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitorDTO>>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "查询多个服务端提前开放出来的端口")
@GetMapping("/findList")
public Result<List<NettyServerVisitorDTO>> findList(@ModelAttribute NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand){
return nettyServerVisitorApplication.findList(nettyServerVisitorQueryListCommand);
}
/**
* describe 分页查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitorQueryListCommand 分页查询多个服务端提前开放出来的端口
* @return {@link Result<LazyPage<NettyServerVisitorDTO>>} 分页服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "分页查询多个服务端提前开放出来的端口")
@GetMapping("/findPage")
public Result<LazyPage<NettyServerVisitorDTO>> findPage(@Parameter(description ="分页大小") @RequestParam(defaultValue = "10", value = "size") int size,
@Parameter(description ="当前页数") @RequestParam(defaultValue = "1", value = "current") int current,@ModelAttribute NettyServerVisitorQueryListCommand nettyServerVisitorQueryListCommand){
return nettyServerVisitorApplication.findPage(size,current,nettyServerVisitorQueryListCommand);
}
/**
* describe 删除服务端提前开放出来的端口
*
* @param nettyServerVisitorRemoveCommand 删除服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Operation(summary = "删除服务端提前开放出来的端口")
@DeleteMapping("/remove")
public Result<NettyServerVisitor> remove(@ModelAttribute NettyServerVisitorRemoveCommand nettyServerVisitorRemoveCommand){
return nettyServerVisitorApplication.remove(nettyServerVisitorRemoveCommand);
}
}

View File

@@ -0,0 +1,66 @@
package wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomain
**/
@Data
@Accessors(chain = true)
@Schema(title = "netty_server_visitor",description = "服务端提前开放出来的端口")
public class NettyServerVisitor {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
private Integer visitorPort;
}

View File

@@ -0,0 +1,106 @@
package wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor;
import com.wu.framework.response.Result;
import com.wu.framework.response.ResultFactory;
import org.springframework.beans.factory.annotation.Autowired;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import java.util.List;
import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyDomainRepository
**/
public interface NettyServerVisitorRepository {
/**
* describe 新增服务端提前开放出来的端口
*
* @param nettyServerVisitor 新增服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口新增后领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> story(NettyServerVisitor nettyServerVisitor);
/**
* describe 批量新增服务端提前开放出来的端口
*
* @param nettyServerVisitorList 批量新增服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口新增后领域对象集合
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<List<NettyServerVisitor>> batchStory(List<NettyServerVisitor> nettyServerVisitorList);
/**
* describe 查询单个服务端提前开放出来的端口
*
* @param nettyServerVisitor 查询单个服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> findOne(NettyServerVisitor nettyServerVisitor);
/**
* describe 查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitor 查询多个服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口DTO对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<List<NettyServerVisitor>> findList(NettyServerVisitor nettyServerVisitor);
/**
* describe 分页查询多个服务端提前开放出来的端口
*
* @param size 当前页数
* @param current 当前页
* @param nettyServerVisitor 分页查询多个服务端提前开放出来的端口
* @return {@link Result<LazyPage<NettyServerVisitor>>} 分页服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<LazyPage<NettyServerVisitor>> findPage(int size,int current,NettyServerVisitor nettyServerVisitor);
/**
* describe 删除服务端提前开放出来的端口
*
* @param nettyServerVisitor 删除服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<NettyServerVisitor> remove(NettyServerVisitor nettyServerVisitor);
/**
* describe 是否存在服务端提前开放出来的端口
*
* @param nettyServerVisitor 是否存在服务端提前开放出来的端口
* @return {@link Result<Boolean>} 服务端提前开放出来的端口是否存在
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
Result<Boolean> exists(NettyServerVisitor nettyServerVisitor);
}

View File

@@ -0,0 +1,48 @@
package wu.framework.lazy.cloud.heartbeat.server.infrastructure.converter;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import wu.framework.lazy.cloud.heartbeat.server.infrastructure.entity.NettyServerVisitorDO;
import org.mapstruct.factory.Mappers;
import org.mapstruct.Mapper;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureConverter
**/
@Mapper
public interface NettyServerVisitorConverter {
/**
* describe MapStruct 创建的代理对象
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitorConverter INSTANCE = Mappers.getMapper(NettyServerVisitorConverter.class);
/**
* describe 实体对象 转换成领域对象
*
* @param nettyServerVisitorDO 服务端提前开放出来的端口实体对象
* @return {@link NettyServerVisitor} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitor toNettyServerVisitor(NettyServerVisitorDO nettyServerVisitorDO);
/**
* describe 领域对象 转换成实体对象
*
* @param nettyServerVisitor 服务端提前开放出来的端口领域对象
* @return {@link NettyServerVisitorDO} 服务端提前开放出来的端口实体对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
NettyServerVisitorDO fromNettyServerVisitor(NettyServerVisitor nettyServerVisitor);
}

View File

@@ -61,7 +61,7 @@ public class NettyClientStateDO {
* 暂存状态(开启、关闭)
*/
@Schema(description = "暂存状态(开启、关闭)", name = "staging", example = "")
@LazyTableField(name = "staging", comment = "暂存状态(开启、关闭)", columnType = "varchar(255)")
@LazyTableField(name = "staging_state", comment = "暂存状态(开启、关闭)", columnType = "varchar(255)")
private String stagingState;
/**
@@ -71,4 +71,12 @@ public class NettyClientStateDO {
@LazyTableFieldUpdateTime
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
@LazyTableField(comment = "描述")
private String describe;
}

View File

@@ -0,0 +1,81 @@
package wu.framework.lazy.cloud.heartbeat.server.infrastructure.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import com.wu.framework.inner.lazy.stereotype.LazyTableIndex;
import com.wu.framework.inner.layer.stereotype.LayerField;
import com.wu.framework.inner.layer.stereotype.LayerField.LayerFieldType;
import com.wu.framework.inner.lazy.stereotype.LazyTable;
import com.wu.framework.inner.lazy.stereotype.LazyTableField;
import com.wu.framework.inner.lazy.stereotype.*;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.lang.String;
import com.wu.framework.inner.lazy.stereotype.LazyTableFieldId;
import java.lang.Long;
import java.lang.Boolean;
import java.lang.Integer;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureEntity
**/
@Data
@Accessors(chain = true)
@LazyTable(tableName = "netty_server_visitor",schema = "lazy_cloud_netty_server",comment = "服务端提前开放出来的端口")
@Schema(title = "netty_server_visitor",description = "服务端提前开放出来的端口")
public class NettyServerVisitorDO {
/**
*
* 创建时间
*/
@Schema(description ="创建时间",name ="createTime",example = "")
@LazyTableField(name="create_time",comment="创建时间",defaultValue="CURRENT_TIMESTAMP",upsertStrategy = LazyFieldStrategy.NEVER,columnType="datetime",extra=" on update CURRENT_TIMESTAMP")
private LocalDateTime createTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
@LazyTableField(name="describe",comment="描述",columnType="varchar(255)")
private String describe;
/**
*
* 用户ID
*/
@Schema(description ="用户ID",name ="id",example = "")
@LazyTableFieldId(name = "id", comment = "用户ID")
private Long id;
/**
*
* 是否删除
*/
@Schema(description ="是否删除",name ="isDeleted",example = "")
@LazyTableField(name="is_deleted",comment="是否删除",columnType="tinyint(1)")
private Boolean isDeleted;
/**
*
* 更新时间
*/
@Schema(description ="更新时间",name ="updateTime",example = "")
@LazyTableField(name="update_time",comment="更新时间",defaultValue="CURRENT_TIMESTAMP",upsertStrategy = LazyFieldStrategy.NEVER,columnType="datetime",extra=" on update CURRENT_TIMESTAMP")
private LocalDateTime updateTime;
/**
*
* 访客端口
*/
@Schema(description ="访客端口",name ="visitorPort",example = "")
@LazyTableField(name="visitor_port",comment="访客端口",columnType="int")
private Integer visitorPort;
}

View File

@@ -0,0 +1,15 @@
package wu.framework.lazy.cloud.heartbeat.server.infrastructure.mapper;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureMapper
**/
public interface NettyServerVisitorMapper {
}

View File

@@ -0,0 +1,15 @@
package wu.framework.lazy.cloud.heartbeat.server.infrastructure.mapper;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:13 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructureMapper
**/
public interface NettyServerVisitorPortMapper {
}

View File

@@ -14,15 +14,16 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.stream.Collectors;
/**
* describe 内网穿透映射
* describe 内网穿透映射
*
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence
**/
@Repository
public class InternalNetworkPenetrationMappingRepositoryImpl implements InternalNetworkPenetrationMappingRepository {
public class InternalNetworkPenetrationMappingRepositoryImpl implements InternalNetworkPenetrationMappingRepository {
@Resource
LazyLambdaStream lazyLambdaStream;
@@ -30,9 +31,8 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
/**
* describe 新增内网穿透映射
*
* @param internalNetworkPenetrationMapping 新增内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射新增后领域对象
* @param internalNetworkPenetrationMapping 新增内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射新增后领域对象
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -47,9 +47,8 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
/**
* describe 批量新增内网穿透映射
*
* @param internalNetworkPenetrationMappingList 批量新增内网穿透映射
* @return {@link Result<List<InternalNetworkPenetrationMapping>>} 内网穿透映射新增后领域对象集合
* @param internalNetworkPenetrationMappingList 批量新增内网穿透映射
* @return {@link Result<List<InternalNetworkPenetrationMapping>>} 内网穿透映射新增后领域对象集合
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -64,9 +63,8 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
/**
* describe 查询单个内网穿透映射
*
* @param internalNetworkPenetrationMapping 查询单个内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射领域对象
* @param internalNetworkPenetrationMapping 查询单个内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射领域对象
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -81,9 +79,8 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
/**
* describe 查询多个内网穿透映射
*
* @param internalNetworkPenetrationMapping 查询多个内网穿透映射
* @return {@link Result<List<InternalNetworkPenetrationMapping>>} 内网穿透映射领域对象
* @param internalNetworkPenetrationMapping 查询多个内网穿透映射
* @return {@link Result<List<InternalNetworkPenetrationMapping>>} 内网穿透映射领域对象
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -98,29 +95,27 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
/**
* describe 分页查询多个内网穿透映射
*
* @param size 当前页数
* @param current 当前页
* @param internalNetworkPenetrationMapping 分页查询多个内网穿透映射
* @return {@link Result<LazyPage<InternalNetworkPenetrationMapping>>} 分页内网穿透映射领域对象
* @param size 当前页数
* @param current 当前页
* @param internalNetworkPenetrationMapping 分页查询多个内网穿透映射
* @return {@link Result<LazyPage<InternalNetworkPenetrationMapping>>} 分页内网穿透映射领域对象
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@Override
public Result<LazyPage<InternalNetworkPenetrationMapping>> findPage(int size,int current,InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) {
public Result<LazyPage<InternalNetworkPenetrationMapping>> findPage(int size, int current, InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) {
InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping);
LazyPage<InternalNetworkPenetrationMapping> lazyPage = new LazyPage<>(current,size);
LazyPage<InternalNetworkPenetrationMapping> internalNetworkPenetrationMappingLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO),lazyPage, InternalNetworkPenetrationMapping.class);
LazyPage<InternalNetworkPenetrationMapping> lazyPage = new LazyPage<>(current, size);
LazyPage<InternalNetworkPenetrationMapping> internalNetworkPenetrationMappingLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO), lazyPage, InternalNetworkPenetrationMapping.class);
return ResultFactory.successOf(internalNetworkPenetrationMappingLazyPage);
}
/**
* describe 删除内网穿透映射
*
* @param internalNetworkPenetrationMapping 删除内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射
* @param internalNetworkPenetrationMapping 删除内网穿透映射
* @return {@link Result<InternalNetworkPenetrationMapping>} 内网穿透映射
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -128,16 +123,15 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
@Override
public Result<InternalNetworkPenetrationMapping> remove(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) {
InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping);
// lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO));
lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO));
return ResultFactory.successOf();
}
/**
* describe 是否存在内网穿透映射
*
* @param internalNetworkPenetrationMapping 内网穿透映射领域对象
* @return {@link Result<Boolean>} 是否存在 true 存在false 不存在
* @param internalNetworkPenetrationMapping 内网穿透映射领域对象
* @return {@link Result<Boolean>} 是否存在 true 存在false 不存在
* @author Jia wei Wu
* @date 2023/12/29 05:21 下午
**/
@@ -145,7 +139,7 @@ public class InternalNetworkPenetrationMappingRepositoryImpl implements Intern
@Override
public Result<Boolean> exists(InternalNetworkPenetrationMapping internalNetworkPenetrationMapping) {
InternalNetworkPenetrationMappingDO internalNetworkPenetrationMappingDO = InternalNetworkPenetrationMappingConverter.INSTANCE.fromInternalNetworkPenetrationMapping(internalNetworkPenetrationMapping);
Boolean exists=lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO));
Boolean exists = lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(internalNetworkPenetrationMappingDO));
return ResultFactory.successOf(exists);
}

View File

@@ -124,7 +124,7 @@ public class NettyClientStateRepositoryImpl implements NettyClientStateRepositor
@Override
public Result<NettyClientState> remove(NettyClientState nettyClientState) {
NettyClientStateDO nettyClientStateDO = NettyClientStateConverter.INSTANCE.fromNettyClientState(nettyClientState);
// lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(nettyClientStateDO));
lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(nettyClientStateDO));
return ResultFactory.successOf();
}

View File

@@ -0,0 +1,150 @@
package wu.framework.lazy.cloud.heartbeat.server.infrastructure.persistence;
import wu.framework.lazy.cloud.heartbeat.server.infrastructure.entity.NettyServerVisitorDO;
import wu.framework.lazy.cloud.heartbeat.server.infrastructure.converter.NettyServerVisitorConverter;
import wu.framework.lazy.cloud.heartbeat.server.infrastructure.mapper.NettyServerVisitorMapper;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitorRepository;
import org.springframework.stereotype.Repository;
import java.util.stream.Collectors;
import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.wrapper.LazyWrappers;
import com.wu.framework.response.Result;
import com.wu.framework.response.ResultFactory;
import jakarta.annotation.Resource;
import wu.framework.lazy.cloud.heartbeat.server.domain.model.netty.server.visitor.NettyServerVisitor;
import com.wu.framework.inner.lazy.database.expand.database.persistence.stream.lambda.LazyLambdaStream;
import java.util.List;
import com.wu.framework.inner.lazy.database.expand.database.persistence.domain.LazyPage;
/**
* describe 服务端提前开放出来的端口
*
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
* @see com.wu.framework.inner.lazy.persistence.reverse.lazy.ddd.DefaultDDDLazyInfrastructurePersistence
**/
@Repository
public class NettyServerVisitorRepositoryImpl implements NettyServerVisitorRepository {
@Resource
LazyLambdaStream lazyLambdaStream;
/**
* describe 新增服务端提前开放出来的端口
*
* @param nettyServerVisitor 新增服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口新增后领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> story(NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
lazyLambdaStream.upsert(nettyServerVisitorDO);
return ResultFactory.successOf();
}
/**
* describe 批量新增服务端提前开放出来的端口
*
* @param nettyServerVisitorList 批量新增服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口新增后领域对象集合
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<List<NettyServerVisitor>> batchStory(List<NettyServerVisitor> nettyServerVisitorList) {
List<NettyServerVisitorDO> nettyServerVisitorDOList = nettyServerVisitorList.stream().map(NettyServerVisitorConverter.INSTANCE::fromNettyServerVisitor).collect(Collectors.toList());
lazyLambdaStream.upsert(nettyServerVisitorDOList);
return ResultFactory.successOf();
}
/**
* describe 查询单个服务端提前开放出来的端口
*
* @param nettyServerVisitor 查询单个服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> findOne(NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
NettyServerVisitor nettyServerVisitorOne = lazyLambdaStream.selectOne(LazyWrappers.lambdaWrapperBean(nettyServerVisitorDO), NettyServerVisitor.class);
return ResultFactory.successOf(nettyServerVisitorOne);
}
/**
* describe 查询多个服务端提前开放出来的端口
*
* @param nettyServerVisitor 查询多个服务端提前开放出来的端口
* @return {@link Result<List<NettyServerVisitor>>} 服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<List<NettyServerVisitor>> findList(NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
List<NettyServerVisitor> nettyServerVisitorList = lazyLambdaStream.selectList(LazyWrappers.lambdaWrapperBean(nettyServerVisitorDO), NettyServerVisitor.class);
return ResultFactory.successOf(nettyServerVisitorList);
}
/**
* describe 分页查询多个服务端提前开放出来的端口
*
* @param size 当前页数
* @param current 当前页
* @param nettyServerVisitor 分页查询多个服务端提前开放出来的端口
* @return {@link Result<LazyPage<NettyServerVisitor>>} 分页服务端提前开放出来的端口领域对象
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<LazyPage<NettyServerVisitor>> findPage(int size, int current, NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
LazyPage<NettyServerVisitor> lazyPage = new LazyPage<>(current, size);
LazyPage<NettyServerVisitor> nettyServerVisitorLazyPage = lazyLambdaStream.selectPage(LazyWrappers.lambdaWrapperBean(nettyServerVisitorDO), lazyPage, NettyServerVisitor.class);
return ResultFactory.successOf(nettyServerVisitorLazyPage);
}
/**
* describe 删除服务端提前开放出来的端口
*
* @param nettyServerVisitor 删除服务端提前开放出来的端口
* @return {@link Result<NettyServerVisitor>} 服务端提前开放出来的端口
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<NettyServerVisitor> remove(NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
lazyLambdaStream.delete(LazyWrappers.lambdaWrapperBean(nettyServerVisitorDO));
return ResultFactory.successOf();
}
/**
* describe 是否存在服务端提前开放出来的端口
*
* @param nettyServerVisitor 服务端提前开放出来的端口领域对象
* @return {@link Result<Boolean>} 是否存在 true 存在false 不存在
* @author Jia wei Wu
* @date 2024/01/16 02:21 下午
**/
@Override
public Result<Boolean> exists(NettyServerVisitor nettyServerVisitor) {
NettyServerVisitorDO nettyServerVisitorDO = NettyServerVisitorConverter.INSTANCE.fromNettyServerVisitor(nettyServerVisitor);
Boolean exists = lazyLambdaStream.exists(LazyWrappers.lambdaWrapperBean(nettyServerVisitorDO));
return ResultFactory.successOf(exists);
}
}

View File

@@ -1,5 +1,6 @@
package wu.framework.lazy.cloud.heartbeat.server.model.netty.client.state;
import com.wu.framework.inner.lazy.stereotype.LazyTableField;
import wu.framework.lazy.cloud.heartbeat.common.enums.NettyClientStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -67,5 +68,11 @@ public class NettyClientState {
*/
@Schema(description ="修改时间",name ="updateTime",example = "")
private LocalDateTime updateTime;
/**
*
* 描述
*/
@Schema(description ="描述",name ="describe",example = "")
private String describe;
}

View File

@@ -104,7 +104,7 @@
│ resize.js
├─plugins 插件目录
│ axios.js
│ axios-plus.js
│ element.js
│ mock.js
│ permission.js
@@ -212,7 +212,7 @@ routes.push(route);
### 接口配置
项目中对 axios 做了封装配置中添加**Global**字段用来控制是否显示全屏 load,默认为 true,如需修改添加 axios 配置可在[src\plugins\axios.js](src\plugins\axios.js)中进行
项目中对 axios 做了封装配置中添加**Global**字段用来控制是否显示全屏 load,默认为 true,如需修改添加 axios 配置可在[src\plugins\axios-plus.js](src\plugins\axios.js)中进行
#### 添加接口

View File

@@ -0,0 +1,51 @@
module.exports = {
cloudClientFindPage: {
url: "/acw-server/netty/client/state/findPage",
type: "get",
},
cloudClientFindList: {
url: "/acw-server/netty/client/state/findList",
type: "get",
},
cloudClientDelete: {
url: "/acw-server/netty/client/state/remove",
type: "delete",
},
visitorPage: {
url: "/acw-server/netty/server/visitor/findPage",
type: "get",
},
visitorList: {
url: "/acw-server/netty/server/visitor/findList",
type: "get",
},
visitorDelete: {
url: "/acw-server/netty/server/visitor/remove",
type: "delete",
},
visitorSave: {
url: "/acw-server/netty/server/visitor/story",
type: "post",
},
visitorUpdate: {
url: "/acw-server/netty/server/visitor/updateOne",
type: "put",
},
networkMappingPage: {
url: "/acw-server/internal/network/penetration/mapping/findPage",
type: "get",
},
networkMappingDelete: {
url: "/acw-server/internal/network/penetration/mapping/remove",
type: "delete",
},
networkMappingSave: {
url: "/acw-server/internal/network/penetration/mapping/story",
type: "post",
},
networkMappingUpdate: {
url: "/acw-server/internal/network/penetration/mapping/updateOne",
type: "put",
},
};

View File

@@ -262,11 +262,11 @@ const getCpu = async () => {
}
};
onMounted(async () => {
const { code, data } = await VE_API.system.shortcutsData();
if (code === 0) {
console.log(data);
shortcutsData.value = data;
}
// const { code, data } = await VE_API.system.shortcutsData();
// if (code === 0) {
// console.log(data);
// shortcutsData.value = data;
// }
await getJvmInfo();
await getCpu();
timer.value = setTimeout(() => {

View File

@@ -1,5 +1,5 @@
import { createApp } from "vue";
import axios from "@/plugins/axios";
import axios from "@/plugins/axios-plus";
import App from "@/App.vue";
import router from "@/router";
import store from "@/store";

View File

@@ -151,7 +151,7 @@ export default {
};
/**
* 默认菜单
* @type {[{name: string, icon: string, id: number, sort: number, iframe: number, menu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, menu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, menu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, menu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, menu: string, type: number, parentCode: number, url: string}, null, null, null, null, null, null, null, null, null, null, null, null, null]}
* @type {[{name: string, icon: string, id: number, sort: number, iframe: number, cloudNetworkMenu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, cloudNetworkMenu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, cloudNetworkMenu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, cloudNetworkMenu: string, type: number, parentCode: number, url: string}, {name: string, icon: string, id: number, sort: number, iframe: number, cloudNetworkMenu: string, type: number, parentCode: number, url: string}, null, null, null, null, null, null, null, null, null, null, null, null, null]}
*/
const menuList = [
{

View File

@@ -1,8 +0,0 @@
const acwMenu = {
description: "数据库管理平台",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "DataLine",
name: "数据库管理平台",
};
export default acwMenu;

View File

@@ -1,241 +0,0 @@
<template>
<div class="ve_container">
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
filterable
@change="(val) => getSchemaList(val)"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-select
v-model="schema"
filterable
placeholder="数据库实例"
@change="findInstanceSchemaColumnList"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="文件数据" prop="data">
<el-upload
name="data"
:multiple="false"
:show-file-list="true"
:on-change="onChange"
limit="1"
v-model="data"
placeholder=""
clearable
:auto-upload="false"
>
<!-- <el-button size="medium" type="primary">上传文件</el-button>-->
<div style="padding: 10px 0">
<Icon
type="ios-cloud-upload"
size="52"
style="#3399ff"
></Icon>
<p style="margin-top: 10px; font-size: 14px">
点击或拖拽文件至此即可上传文件
</p>
<p
style="
margin-top: 20px;
font-size: 14px;
color: red;
"
>
请上传10GB以内的待测对象
</p>
</div>
</el-upload>
</el-form-item>
</el-form>
<span>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库信息导入",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
analysisSchema: { name: "解析schema" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "MagicStick",
name: "数据库信息导入",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, onMounted, ref } from "vue";
const rules = {
name: [
{
required: true,
message: "请输入文件名称",
trigger: "blur",
},
],
data: [
{
required: true,
message: "请上传文件",
trigger: "blur",
},
],
type: [
{
required: true,
message: "请选择文件类型",
trigger: "blur",
},
],
};
const formRef = ref(null);
const form = reactive({
schema: "",
instanceId: "",
data: [],
});
const { schema, instanceId, data } = toRefs(form);
const serverList = ref(null);
const schemaList = ref(null);
/**
* 获取数据库实例
*/
const getInstanceList = () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
const getSchemaList = (databaseInstance = null) => {
console.log(databaseInstance);
// 查询数据schema信息
VE_API.system
.schemaList({
instanceId: instanceId.value,
})
.then((res) => {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
});
};
onMounted(async () => {
getInstanceList();
});
/**
* 计算文件大小
* @param fileSize
* @returns {string}
*/
const formatFileSize = (fileSize) => {
if (fileSize < 1024) {
return fileSize + "B";
} else if (fileSize < 1024 * 1024) {
let temp = fileSize / 1024;
temp = temp.toFixed(2);
return temp + "KB";
} else if (fileSize < 1024 * 1024 * 1024) {
let temp = fileSize / (1024 * 1024);
temp = temp.toFixed(2);
return temp + "MB";
} else {
let temp = fileSize / (1024 * 1024 * 1024);
temp = temp.toFixed(2);
return temp + "GB";
}
};
/**
* 文件更改
* */
const onChange = (file) => {
var name = file.name;
var size = file.size;
form.name = name;
form.uid = file.uid;
if (size != null) {
form.length = formatFileSize(size);
}
form.data = file.raw;
if (name !== null) {
var split = name.split(".");
form.type = split[split.length - 1];
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let fd = new FormData();
fd.append("multipartFileList", form.data); //传文件
fd.append("instanceId", form.instanceId);
fd.append("schema", form.schema);
let res = await VE_API.system.aceSchemaImportData(fd);
const { code } = res;
if (code === 0) {
console.log(code);
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,289 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="类型(1:自动产生的、2:手动添加的)" prop="type">
<el-select
v-model="type"
placeholder="类型(1:自动产生的、2:手动添加的)"
clearable
@change="getDataList"
>
<el-option label="自动产生的" value="1" />
<el-option label="手动添加的" value="2" />
</el-select>
</el-form-item>
<el-form-item label="原始表" prop="sourceTable">
<el-input
clearable
v-model="sourceTable"
placeholder="原始表"
></el-input>
</el-form-item>
<el-form-item label="原始表字段" prop="sourceTableColumn">
<el-input
clearable
v-model="sourceTableColumn"
placeholder="原始表字段"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
<el-button
v-permission="['analysisSchema']"
size="small"
type="primary"
@click="handleAnalysisSchemaEdit()"
>
{{ buttons.analysisSchema.name }}
</el-button>
</template>
<el-table-column
prop="instanceId"
label="数据库实例ID"
></el-table-column>
<el-table-column
prop="schema"
label="数据库实例schema"
></el-table-column>
<el-table-column
prop="sourceTable"
label="原始表"
></el-table-column>
<el-table-column prop="sourceTableColumn" label="原始表字段">
</el-table-column>
<el-table-column
prop="relationTable"
label="关系表"
></el-table-column>
<el-table-column
prop="relationTableColumn"
label="关系表字段"
></el-table-column>
<el-table-column prop="relation" label="关系"></el-table-column>
<el-table-column
prop="type"
label="类型(1:自动产生的、2:手动添加的)"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<acw-table-association-relation-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
<acw-table-association-relation-analysis-schema-edit
v-if="showAnalysisSchemaDialog"
:showDialog="showAnalysisSchemaDialog"
@closeDialog="handleAnalysisSchemaDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "表关联关系",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
analysisSchema: { name: "解析schema" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Flag",
name: "表关联关系管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
import AcwTableAssociationRelationEdit from "@/views/layoutpages/acw/components/AcwTableAssociationRelationEdit.vue";
import AcwTableAssociationRelationAnalysisSchemaEdit from "@/views/layoutpages/acw/components/AcwTableAssociationRelationAnalysisSchemaEdit.vue";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showAnalysisSchemaDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
type: "2",
sourceTable: "",
sourceTableColumn: "",
size: 10,
current: 1,
total: 0,
});
const { type, sourceTable, sourceTableColumn, size, current, total } =
toRefs(params);
/**
* 左侧服务器树
* @type {Ref<UnwrapRef<*[]>>}
*/
const leftServerTree = ref([]);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
const handleAnalysisSchemaEdit = () => {
showAnalysisSchemaDialog.value = true;
};
const handleAnalysisSchemaDialog = (e) => {
showAnalysisSchemaDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } =
await VE_API.system.acwTableAssociationRelationDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } =
await VE_API.system.acwTableAssociationRelationPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
record.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
leftServerTree.value = record;
}
};
onMounted(async () => {
await getDataList();
// maxHeight(pagination, queryForm, toolBar, ve_max_height);
});
</script>
<style lang="scss" scoped>
.prefix {
color: var(--el-color-primary);
margin-right: 10px;
}
.prefix.is-leaf {
color: var(--el-color-success);
}
</style>

View File

@@ -1,239 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="接口分组" prop="interfaceGroup">
<el-input
clearable
v-model="interfaceGroup"
placeholder="接口分组"
></el-input>
</el-form-item>
<el-form-item label="接口描述" prop="interfaceDescribe">
<el-input
clearable
v-model="interfaceDescribe"
placeholder="接口描述"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="tag" label="接口分组"></el-table-column>
<el-table-column
prop="description"
label="接口描述"
></el-table-column>
<el-table-column prop="method" label="接口类型"></el-table-column>
<el-table-column prop="path" label="接口地址"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['info']"
@click.prevent="handleInfo('详情', row)"
type="primary"
size="small"
>
{{ buttons.info.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<api-factory-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
<!-- 编辑组件 -->
<api-factory-edit
v-if="showInfo"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showInfo"
@closeDialog="handelInfo($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "接口工厂查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
info: { name: "详情" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Histogram",
name: "接口工厂管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import ApiFactoryEdit from "@/views/layoutpages/acw/components/ApiFactoryEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showInfo = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
interfaceGroup: "",
interfaceDescribe: "",
size: 10,
current: 1,
total: 0,
});
const { interfaceGroup, interfaceDescribe, size, current, total } =
toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.apiDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* 行信息
*/
const handleInfo = (title, row = null) => {
showInfo.value = true;
dialogTitle.value = title;
rowData.value = row;
};
const handelInfo = (e) => {
showInfo.value = e;
getDataList();
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.apiPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,344 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="服务器名称" prop="instanceName">
<el-input
clearable
v-model="instanceName"
placeholder="服务器名称"
></el-input>
</el-form-item>
<el-form-item
label="是否初始化数据库到本地"
prop="initializeToLocal"
>
<el-select
v-model="initializeToLocal"
placeholder="是否初始化数据库到本地"
clearable
@change="getDataList"
>
<el-option label="初始化数据库到本地" value="true" />
<el-option label="不初始化数据库到本地" value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column
prop="instanceName"
label="服务器名称"
></el-table-column>
<el-table-column
prop="driverClassName"
label="驱动程序类名"
></el-table-column>
<el-table-column prop="username" label="登录名"></el-table-column>
<el-table-column prop="password" label="登陆密码">
<template v-slot="{ row }">
<span>
{{
row.password &&
row.password
.split("")
.fill("*", 1, -1)
.join()
.replace(/\,/g, "")
}}
</span>
</template>
</el-table-column>
<el-table-column prop="host" label="host"></el-table-column>
<el-table-column prop="port" label="端口"></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
<el-table-column prop="sort" label="排序"></el-table-column>
<el-table-column label="数据源类型">
<template v-slot="{ row }">
<el-select
v-model="row.lazyDataSourceType"
placeholder="数据源类型"
disabled
>
<el-option label="MySQL" value="MySQL" />
<el-option label="H2" value="H2" />
<el-option label="CLICK_HOUSE" value="CLICK_HOUSE" />
<el-option label="POSTGRESQL" value="POSTGRESQL" />
</el-select>
</template>
</el-table-column>
<el-table-column label="是否初始化数据库到本地">
<template v-slot="{ row }">
<el-select
v-model="row.initializeToLocal"
placeholder="是否初始化数据库到本地"
disabled
>
<el-option label="初始化数据库到本地" :value="true" />
<el-option
label="不初始化数据库到本地"
:value="false"
/>
</el-select>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['reload']"
@click="handleDatabaseInstanceReload(row.id)"
type="primary"
size="small"
>
{{ buttons.reload.name }}
</el-button>
<el-button
v-permission="['backups']"
@click="handleBackUpsRoute(row.id)"
type="primary"
size="small"
>
{{ buttons.backups.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<database-instance-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
<!-- schema组件 -->
<database-schema-edit
v-if="showschemaDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showschemaDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库服务器查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
reload: { name: "初始化服务器" },
backups: { name: "实例备份" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Coin",
name: "数据库实例管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import databaseInstanceEdit from "./components/DatabaseInstanceEdit";
import DatabaseSchemaEdit from "./components/DatabaseSchemaEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
getAsyncRouteName,
} from "@/views/layoutpages/common";
import { useRoute, useRouter } from "vue-router";
const { proxy } = getCurrentInstance();
const route = useRoute();
const router = useRouter();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showschemaDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
instanceName: "",
initializeToLocal: "",
size: 10,
current: 1,
total: 0,
});
const { instanceName, initializeToLocal, size, current, total } =
toRefs(params);
/**
* 左侧服务器树
* @type {Ref<UnwrapRef<*[]>>}
*/
const leftServerTree = ref([]);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: 数据库实例备份信息
* @param {*}
* @return {*}
*/
const handleBackUpsRoute = async (title) => {
let path = "acw/DatabaseInstanceBackUps";
const toName = await getAsyncRouteName(title, path, "add", {
router,
route,
});
router.push({ name: toName });
};
/**
* 重新加载实例
*/
const handleDatabaseInstanceReload = async (id) => {
// 重新加载服务器
console.log("重新加载服务器:" + id);
const { code } = await VE_API.system.databaseInstanceReload({ id });
if (code === 0) {
getDataList();
}
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.databaseInstanceDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.databaseInstancePage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
record.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
leftServerTree.value = record;
}
};
onMounted(async () => {
await getDataList();
// maxHeight(pagination, queryForm, toolBar, ve_max_height);
});
</script>
<style lang="scss" scoped>
.prefix {
color: var(--el-color-primary);
margin-right: 10px;
}
.prefix.is-leaf {
color: var(--el-color-success);
}
</style>

View File

@@ -1,273 +0,0 @@
<template>
<div class="ve_container">
<!-- <el-descriptions border>-->
<!-- <el-descriptions-item label="实例名称"-->
<!-- >实例名称-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例数据库数量"-->
<!-- >实例数据库数量-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例表数量"-->
<!-- >实例表数量-->
<!-- </el-descriptions-item>-->
<!-- </el-descriptions>-->
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="params.instanceId"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['backups']"
size="small"
type="primary"
@click="handleEdit(buttons.backups.name)"
>
{{ buttons.backups.name }}
</el-button>
</template>
<el-table-column prop="id" label="记录ID"></el-table-column>
<el-table-column
prop="instanceName"
label="实例名称"
></el-table-column>
<el-table-column
prop="schemaNum"
label="数据库数量"
></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<database-instance-back-ups-add
v-if="showsBackUpsDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showsBackUpsDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import DatabaseInstanceBackUpsAdd from "@/views/layoutpages/acw/components/DatabaseInstanceBackUpsAdd";
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
components: { DatabaseInstanceBackUpsAdd },
data: () => ({
description: "数据库实例备份",
buttons: {
search: { name: "查询" },
del: { name: "删除数据库实例备份" },
backups: { name: "实例备份" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Guide",
name: "数据库实例备份",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, defineProps, onMounted } from "vue";
import databaseInstanceBackUpsAdd from "./components/DatabaseInstanceBackUpsAdd";
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const { rowData } = toRefs(props);
const queryForm = ref(null);
const tableData = ref([]);
const showsBackUpsDialog = ref(false);
const serverList = ref(null);
const params = reactive({
instanceName: "",
initializeToLocal: "",
size: 10,
current: 1,
total: 0,
});
const form = reactive({
name: "",
userName: "",
password: "",
role: "",
status: 1,
});
const { size, current, total } = toRefs(params);
const { userName, name, password, role, status } = toRefs(form);
const roleList = ref([]);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((name.value = rowData.value.name),
(userName.value = rowData.value.userName),
(password.value = rowData.value.password),
(role.value = rowData.value.role),
(status.value = rowData.value.status));
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showsBackUpsDialog.value = true;
rowData.value = row;
};
/**
* 删除数据库事例备份
*/
const handleDel = async (id) => {
const { code } = await VE_API.system.databaseInstanceBackUpDelete({
id: id,
});
if (code === 0) {
getDataList();
}
};
/**
* @description: 获取角色列表
* @param {*}
* @return {*}
*/
const getRoleList = async () => {
const { code, data } = await VE_API.system.roleList(
{
page: 1,
size: 10,
},
{ Global: false },
);
if (code === "0") {
const { list } = data;
roleList.value = list;
}
};
getRoleList();
/**
* 隐藏弹框
* */
const handelDialog = (e) => {
showsBackUpsDialog.value = e;
getDataList();
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } =
await VE_API.system.databaseInstanceBackUpPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
record.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
}
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
return serverList.value;
});
};
onMounted(async () => {
await getServerInstanceList();
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,88 +0,0 @@
<template>
<el-tabs
v-model="currentConsoleTableKey"
type="card"
closable
@tab-remove="closeCurrentConsoleTable(currentConsoleTableKey)"
>
<el-tab-pane
v-for="item in consoleTableList"
:key="item.index"
:label="item.title"
:name="item.name"
>
<database-query-console />
</el-tab-pane>
<el-tab-pane
key="lastConsoleTable"
label="新增页签"
name="新增页签name"
@onclick="addConsoleTable(currentConsoleTableKey)"
>
<el-button
size="small"
@click="addConsoleTable(currentConsoleTableKey)"
>
新增页签
</el-button>
</el-tab-pane>
</el-tabs>
</template>
<script>
import DatabaseQueryConsole from "@/views/layoutpages/acw/components/DatabaseQueryConsole.vue";
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库多表复杂查询控制台",
buttons: {
search: { name: "查询" },
downLoad: { name: "导出查询结果为Excel" },
downLoadUpsert: { name: "Upsert下载查询结果" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "IceCream",
name: "数据库多表复杂查询控制台",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { ref, onMounted } from "vue";
// 当前页
const currentConsoleTableKey = ref(0);
// 查询sql的所有列
const consoleTableList = ref([
{
index: 0,
name: 0,
title: "执行查询",
},
]);
/**
* 添加页签
*/
const addConsoleTable = (currentIndex) => {
console.log("当前标签页🏷️" + currentIndex);
currentConsoleTableKey.value = consoleTableList.value.length + 1;
consoleTableList.value.push({
name: currentConsoleTableKey.value,
title: "执行查询 (" + currentConsoleTableKey.value + ")",
});
};
/**
* 关闭当前table
*/
const closeCurrentConsoleTable = (currentIndex) => {
console.log("删除页签" + currentIndex);
consoleTableList.value.splice(currentIndex - 1, 1);
};
onMounted(async () => {});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,626 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" property="instanceId">
<el-select
v-model="instanceId"
@change="getDataList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-input
clearable
v-model="schemaName"
placeholder="数据库库名"
></el-input>
</el-form-item>
<el-form-item
label="是否初始化数据库到本地"
prop="initializeToLocal"
>
<el-select
v-model="initializeToLocal"
placeholder="是否初始化数据库到本地"
clearable
@change="getDataList"
>
<el-option label="初始化数据库到本地" value="true" />
<el-option label="不初始化数据库到本地" value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
border
style="width: 80%"
@selectionChange="handleSelectionChange"
ref="multipleTableRef"
>
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
<el-button
v-permission="['batchDel']"
size="small"
type="danger"
@click="batchDel"
>
{{ buttons.batchDel.name }}
</el-button>
<el-button
v-permission="['batchExportData']"
size="small"
type="primary"
@click="batchExportData"
>
{{ buttons.batchExportData.name }}
</el-button>
<el-button
v-permission="['schemaDeriveView']"
@click="
handleSchemaDeriveView(
buttons.schemaDeriveView.name,
row,
)
"
type="primary"
size="small"
>
{{ buttons.schemaDeriveView.name }}
</el-button>
</template>
<el-table-column type="selection" width="55" />
<!-- <el-table-column prop="id" label="ID"></el-table-column>-->
<el-table-column
prop="instanceName"
label="数据库实例"
></el-table-column>
<el-table-column
prop="schemaName"
label="数据库库名"
></el-table-column>
<el-table-column label="是否初始化数据库到本地">
<template v-slot="{ row }">
<el-select
v-model="row.initializeToLocal"
placeholder="是否初始化数据库到本地"
disabled
>
<el-option label="初始化数据库到本地" :value="true" />
<el-option
label="不初始化数据库到本地"
:value="false"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
prop="dataLength"
label="数据大小"
></el-table-column>
<el-table-column
prop="indexLength"
label="索引大小"
></el-table-column>
<!-- <el-table-column-->
<!-- prop="characterSet"-->
<!-- label="字符集"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="sortingRules"-->
<!-- label="排序规则"-->
<!-- ></el-table-column>-->
<!-- <el-table-column prop="ext" label="ext"></el-table-column>-->
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['exportData']"
@click.prevent="handleExportData(row)"
type="primary"
size="small"
>
{{ buttons.exportData.name }}
</el-button>
<el-button
v-permission="['exportStructure']"
@click.prevent="handleExportStructure(row)"
type="primary"
size="small"
>
{{ buttons.exportStructure.name }}
</el-button>
<el-button
v-permission="['exportStructureExcel']"
@click.prevent="handleExportStructureExcel(row)"
type="primary"
size="small"
>
{{ buttons.exportStructureExcel.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['reload']"
@click="handleDatabaseSchemaReload(row)"
type="primary"
size="small"
>
{{ buttons.reload.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<database-schema-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
<!-- 数据库衍生视图 -->
<database-schema-derive-view
v-if="showSchemaDeriveViewDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showSchemaDeriveViewDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库信息查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
exportData: { name: "导出数据" },
exportStructure: { name: "导出结构为SQL" },
exportStructureExcel: { name: "导出结构为Excel" },
batchDel: { name: "批量删除" },
batchExportData: { name: "批量导出数据" },
reload: { name: "初始化schema" },
schemaDeriveView: { name: "数据库衍生视图" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "IceDrink",
name: "数据库信息管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import databaseSchemaEdit from "./components/DatabaseSchemaEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
import DatabaseSchemaDeriveView from "@/views/layoutpages/acw/components/DatabaseSchemaDeriveView.vue";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showSchemaDeriveViewDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const serverList = ref(null);
// 批量删除选中的 schema
const batchSelectDatabaseSchemaList = ref([]);
const params = reactive({
instanceId: "",
schemaName: "",
initializeToLocal: false,
size: 10,
current: 1,
total: 0,
});
const { instanceId, schemaName, initializeToLocal, size, current, total } =
toRefs(params);
const multipleTableRef = ref(null);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**
*
* 批量导出数据
*/
const batchExportData = () => {
if (batchSelectDatabaseSchemaList.value.length == 0) {
proxy.$message({
type: "info",
message: "请选择一个schema",
});
return;
}
proxy
.$confirm("此操作将批量导出数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
let databaseSchemaDeleteCommandList =
batchSelectDatabaseSchemaList.value.map((item) => {
return {
instanceName: item.instanceName,
schema: item.schemaName,
};
});
let res = await VE_API.system.batchExportSchemaData(
databaseSchemaDeleteCommandList,
{
responseType: "blob",
},
);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
})
.finally(() => {
getDataList();
});
};
/**
*
* 批量删除
*/
const batchDel = () => {
if (batchSelectDatabaseSchemaList.value.length === 0) {
proxy.$message({
type: "info",
message: "请选择一个schema",
});
return;
}
proxy
.$confirm(
`此操作将批量永久删除【${batchSelectDatabaseSchemaList.value.length}】个数据库, 是否继续?`,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
},
)
.then(async () => {
let databaseSchemaDeleteCommandList =
batchSelectDatabaseSchemaList.value.map((item) => {
return {
instanceName: item.instanceName,
instanceId: item.instanceId,
schema: item.schemaName,
};
});
const { code } = await VE_API.system.batchDeleteInstanceSchema(
databaseSchemaDeleteCommandList,
);
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (row) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
if (row === undefined) {
getDataList();
} else {
let databaseSchemaDeleteCommandList = [
{
instanceName: row.instanceName,
instanceId: row.instanceId,
schema: row.schemaName,
},
];
const { code } = await VE_API.system.batchDeleteInstanceSchema(
databaseSchemaDeleteCommandList,
);
if (code === 0) {
getDataList();
}
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**导出数据
* @description:
* @param {*}
* @return {*}
*/
const handleExportData = (row) => {
proxy
.$confirm("此操作将导出数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
if (row == undefined) {
getDataList();
} else {
let databaseSchemaDeleteCommandList = [
{
instanceName: row.instanceName,
schema: row.schemaName,
},
];
let res = await VE_API.system.batchExportSchemaData(
databaseSchemaDeleteCommandList,
{
responseType: "blob",
},
);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
})
.finally(() => {
getDataList();
});
};
/**
* 导出结构
*/
const handleExportStructure = async (row) => {
let res = await VE_API.system.exportTableStructureSql(row, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 导出结构
*/
const handleExportStructureExcel = async (row) => {
let res = await VE_API.system.exportTableStructureExcel(row, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 全选事件
*
*/
const handleSelectionChange = (val) => {
batchSelectDatabaseSchemaList.value = val;
console.log(batchSelectDatabaseSchemaList.value);
};
/**
* 数据库衍生视图
* @param row
*/
const handleSchemaDeriveView = (title, row) => {
console.log(row);
showSchemaDeriveViewDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* 初始化数据库schema
* **/
const handleDatabaseSchemaReload = async (row) => {
const { code, data } = await VE_API.system.schemaReload({
instanceId: row.instanceId,
schema: row.schemaName,
});
if (code === 0) {
console.log("success");
}
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.schemaPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
if (serverList.value.length == 0) {
return;
}
params.instanceId = serverList.value[0].id;
getDataList();
});
};
onMounted(async () => {
await getServerInstanceList();
});
</script>
<style lang="scss" scoped>
.ve_container {
::v-deep
.el-table__header
.el-table-column--selection
.cell
.el-checkbox:after {
color: #606266;
content: "全选";
font-size: 12px;
margin-left: 2px;
font-weight: bold;
}
}
</style>

View File

@@ -1,348 +0,0 @@
<template>
<div class="ve_container">
<!-- <el-descriptions border>-->
<!-- <el-descriptions-item label="实例名称"-->
<!-- >实例名称-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例数据库数量"-->
<!-- >实例数据库数量-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例表数量"-->
<!-- >实例表数量-->
<!-- </el-descriptions-item>-->
<!-- </el-descriptions>-->
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaName">
<el-select
clearable
filterable
@change="getDataList"
v-model="params.schemaName"
placeholder="数据库名"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['backups']"
size="small"
type="primary"
@click="handleEdit(buttons.backups.name)"
>
{{ buttons.backups.name }}
</el-button>
</template>
<el-table-column prop="id" label="记录ID"></el-table-column>
<el-table-column
prop="instanceName"
label="实例名称"
></el-table-column>
<el-table-column
prop="schemaName"
label="数据库名称"
></el-table-column>
<el-table-column
prop="tableNum"
label="数据库表数量"
:sortable="true"
></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
<el-table-column prop="path" label="备份数据库地址"
><template #default="scope">
<a
style="color: #7099f9"
@click="downloadBackUps(scope.row)"
>{{ scope.row.path }}
</a>
</template></el-table-column
>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['down']"
@click.prevent="downloadBackUps(row)"
type="primary"
size="small"
>
{{ buttons.down.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<database-schema-back-ups-add
v-if="showsBackUpsDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showsBackUpsDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库备份",
buttons: {
search: { name: "查询" },
down: { name: "下载" },
del: { name: "删除" },
backups: { name: "数据库备份" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Ship",
name: "数据库备份",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, defineProps, onMounted } from "vue";
import databaseSchemaBackUpsAdd from "./components/DatabaseSchemaBackUpsAdd";
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const { rowData } = toRefs(props);
const queryForm = ref(null);
const tableData = ref([]);
const showsBackUpsDialog = ref(false);
const serverList = ref(null);
const schemaList = ref(null);
const params = reactive({
instanceId: "",
// status: 1,
schemaName: "",
size: 10,
current: 1,
total: 0,
});
const { size, current, total } = toRefs(params);
const form = reactive({
instanceId: "",
status: 1,
});
const { instanceId, status } = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((instanceId.value = rowData.value.instanceId),
(status.value = rowData.value.status));
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showsBackUpsDialog.value = true;
rowData.value = row;
};
/**
* 删除备份记录
* @param id
*/
const handleDel = async (id) => {
const { code } = await VE_API.system.databaseSchemaBackUpRemove({ id: id });
if (code === 0) {
getDataList();
}
};
/**
*@param row 行数据
* 下载备份数据
*
* */
const downloadBackUps = async (row) => {
// console.log(row);
let res = await VE_API.system.downLocalFile(
{ path: row.path },
{
responseType: "blob",
},
);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 隐藏弹框
* */
const handelDialog = (e) => {
showsBackUpsDialog.value = e;
getDataList();
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.databaseSchemaBackUpPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
record.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
}
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
let res;
if (instanceId == null) {
return;
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = data;
if (schemaList.value) {
// 默认第一个实例的第一个数据库
params.schemaName = schemaList.value[0].schemaName;
}
return schemaList.value;
}
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
// 默认第一个实例
if (serverList.value && serverList.value.length > 0) {
params.instanceId = serverList.value[0].id;
getSchemaList(params.instanceId);
}
return serverList.value;
});
};
onMounted(async () => {
await getServerInstanceList();
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,88 +0,0 @@
<template>
<el-tabs
v-model="currentConsoleTableKey"
type="card"
closable
@tab-remove="closeCurrentConsoleTable(currentConsoleTableKey)"
>
<el-tab-pane
v-for="item in consoleTableList"
:key="item.index"
:label="item.title"
:name="item.name"
>
<database-table-console />
</el-tab-pane>
<el-tab-pane
key="lastConsoleTable"
label="新增页签"
name="新增页签name"
@onclick="addConsoleTable(currentConsoleTableKey)"
>
<el-button
size="small"
@click="addConsoleTable(currentConsoleTableKey)"
>
新增单表查询页签
</el-button>
</el-tab-pane>
</el-tabs>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "单表查询控制台",
buttons: {
search: { name: "查询" },
downLoad: { name: "导出查询结果为Excel" },
downLoadUpsert: { name: "Upsert下载查询结果" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Finished",
name: "单表查询控制台",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { ref, onMounted } from "vue";
import DatabaseTableConsole from "@/views/layoutpages/acw/components/DatabaseTableConsole.vue";
// 当前页
const currentConsoleTableKey = ref(0);
// 查询sql的所有列
const consoleTableList = ref([
{
index: 0,
name: 0,
title: "执行查询",
},
]);
/**
* 添加页签
*/
const addConsoleTable = (currentIndex) => {
console.log("当前标签页🏷️" + currentIndex);
currentConsoleTableKey.value = consoleTableList.value.length + 1;
consoleTableList.value.push({
name: currentConsoleTableKey.value,
title: "执行查询 (" + currentConsoleTableKey.value + ")",
});
};
/**
* 关闭当前table
*/
const closeCurrentConsoleTable = (currentIndex) => {
console.log("删除页签" + currentIndex);
consoleTableList.value.splice(currentIndex - 1, 1);
};
onMounted(async () => {});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,480 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" property="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaName">
<el-select
clearable
v-model="params.schemaName"
placeholder="数据库名"
@change="getDataList"
filterable
>
<el-option
v-for="item in schemaNameList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="表名" prop="tableName">
<el-input
clearable
v-model="tableName"
placeholder="表名"
></el-input>
</el-form-item>
<el-form-item
label="是否初始化数据库到本地"
prop="initializeToLocal"
>
<el-select
v-model="initializeToLocal"
placeholder="是否初始化数据库到本地"
clearable
@change="getDataList"
>
<el-option label="初始化数据库到本地" value="true" />
<el-option label="不初始化数据库到本地" value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
@selectionChange="handleSelectionChange"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEditRoute(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
<el-button
v-permission="['batchDel']"
size="small"
type="danger"
@click="batchDelTable"
>
{{ buttons.batchDel.name }}
</el-button>
</template>
<el-table-column type="selection" width="55" />
<el-table-column
prop="schemaName"
label="数据库库名"
></el-table-column>
<el-table-column prop="tableName" label="表名称"> </el-table-column>
<el-table-column
prop="tableComment"
label="表描述"
width="120"
></el-table-column>
<el-table-column prop="tableType" label="表类型"></el-table-column>
<el-table-column
prop="tableRows"
sortable
label="表行数"
></el-table-column>
<!-- <el-table-column-->
<!-- prop="avgRowLength"-->
<!-- label="avgRowLength"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="autoIncrement"-->
<!-- label="autoIncrement"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="checkTime"-->
<!-- label="checkTime"-->
<!-- ></el-table-column>-->
<!-- <el-table-column prop="checksum" label="checksum"></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="createOptions"-->
<!-- label="createOptions"-->
<!-- ></el-table-column>-->
<!-- <el-table-column prop="dataFree" label="dataFree"></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="dataLength"-->
<!-- label="dataLength"-->
<!-- ></el-table-column>-->
<el-table-column prop="engine" label="表引擎"></el-table-column>
<el-table-column
prop="dataLength"
label="数据大小"
></el-table-column>
<el-table-column
prop="indexLength"
label="索引大小"
></el-table-column>
<!-- <el-table-column-->
<!-- prop="maxDataLength"-->
<!-- label="maxDataLength"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="rowFormat"-->
<!-- label="rowFormat"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="tableCatalog"-->
<!-- label="tableCatalog"-->
<!-- ></el-table-column>-->
<!-- <el-table-column-->
<!-- prop="tableCollation"-->
<!-- label="tableCollation"-->
<!-- ></el-table-column>-->
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column prop="version" label="版本"></el-table-column>
<el-table-column
prop="updateTime"
label="更新时间"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEditRoute(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['more']"
@click.prevent="handleShowMore(buttons.more.name, row)"
type="primary"
size="small"
>
{{ buttons.more.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<database-table-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handleDialog($event)"
/>
<!-- 更多 -->
<database-table-more
v-if="showMore"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showMore"
@closeDialog="handleShowMoreDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库表查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加表" },
edit: { name: "编辑" },
// crud: { name: "表crud操作" },
del: { name: "删除" },
batchDel: { name: "批量删除" },
more: { name: "更多" },
java_code: { name: "Java代码本地生成" },
export_insert_sql: { name: "导出insert-sql" },
export_upsert_sql: { name: "导出upsert-sql" },
export_table_excel: { name: "导出表结构.excel" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "CopyDocument",
name: "数据库表管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import DatabaseTableEdit from "./components/DatabaseTableEdit";
import DatabaseTableMore from "./components/DatabaseTableMore";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
getAsyncRouteName,
} from "@/views/layoutpages/common";
import { useRoute, useRouter } from "vue-router";
const { proxy } = getCurrentInstance();
const route = useRoute();
const router = useRouter();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showMore = ref(false);
const showJavaCodeDialog = ref(false);
const showDocumentDialog = ref(false);
const showTableColumnDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const schemaNameList = ref(null);
const serverList = ref(null);
const batchSelectDatabaseSchemaTableList = ref([]);
const params = reactive({
tableName: "",
schemaName: "",
instanceId: "",
initializeToLocal: false,
size: 10,
current: 1,
total: 0,
});
const { tableName, initializeToLocal, size, current, total } = toRefs(params);
/**
* @description: 添加页面路由式
* @param {*}
* @return {*}
*/
const handleEditRoute = async (title, row = null) => {
let path = "acw/components/DatabaseTableEdit";
const toName = await getAsyncRouteName(title, path, "add", {
router,
route,
});
router.push({
name: toName,
query: row,
});
};
/**
* 展示更多
*
* */
const handleShowMore = (title, row = null) => {
console.log(showMore.value);
showMore.value = true;
dialogTitle.value = title;
rowData.value = row;
};
const handleShowMoreDialog = (e) => {
showMore.value = e;
getDataList();
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handleDialog = (e) => {
showDialog.value = e;
showJavaCodeDialog.value = e;
showDocumentDialog.value = e;
showTableColumnDialog.value = e;
getDataList();
};
/**
* 全选事件
*
*/
const handleSelectionChange = (val) => {
batchSelectDatabaseSchemaTableList.value = val;
console.log(batchSelectDatabaseSchemaTableList.value);
};
/**
*
* 批量删除
*/
const batchDelTable = () => {
if (batchSelectDatabaseSchemaTableList.value.length == 0) {
proxy.$message({
type: "info",
message: "请选择一个表",
});
return;
}
proxy
.$confirm("此操作将批量永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
let databaseSchemaDeleteCommandList =
batchSelectDatabaseSchemaTableList.value.map((item) => {
return {
instanceId: item.instanceId,
schemaName: item.schemaName,
tableName: item.tableName,
};
});
const { code } = await VE_API.system.batchDeleteTableDelete(
databaseSchemaDeleteCommandList,
);
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (row) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.tableDelete({
instanceId: row.instanceId,
schemaName: row.schemaName,
tableName: row.tableName,
});
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
// console.log(params);
const { code, data } = await VE_API.system.tablePage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
let res;
if (instanceId == null) {
return;
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaNameList.value = data;
if (schemaNameList.value.list !== 0) {
params.schemaName = schemaNameList.value[0].schemaName;
}
}
await getDataList();
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then(async (res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
if (serverList.value.length !== 0) {
// 设置默认instance
params.instanceId = serverList.value[0].id;
getSchemaList(params.instanceId);
}
});
};
onMounted(async () => {
await getServerInstanceList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,381 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" property="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
clearable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaNameId">
<el-select
clearable
v-model="params.schemaNameId"
placeholder="数据库名"
@change="getDataList"
filterable
>
<el-option
v-for="item in schemaNameList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="表名" prop="tableName">
<el-input
clearable
v-model="tableName"
placeholder="表名"
></el-input>
</el-form-item>
<el-form-item label="填充状态" prop="status">
<el-select
v-model="status"
placeholder="填充状态"
clearable
@change="getDataList"
>
<el-option label="成功" :value="true" />
<el-option label="失败" :value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
@selectionChange="handleSelectionChange"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
<el-button
v-permission="['batchDel']"
size="small"
type="danger"
@click="batchDelDatabaseTableAutoStuffed"
>
{{ buttons.batchDel.name }}
</el-button>
</template>
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="填充记录ID"> </el-table-column>
<el-table-column
prop="instanceName"
label="数据库实例"
></el-table-column>
<el-table-column
prop="schemaName"
label="数据库库名"
></el-table-column>
<el-table-column prop="tableName" label="表名称"> </el-table-column>
<el-table-column
prop="autoStuffedNum"
label="自动填充数量"
></el-table-column>
<el-table-column prop="status" label="状态">
<template v-slot="{ row }">
<el-select
v-model="row.status"
placeholder="数据填充状态"
disabled
>
<el-option label="成功" :value="true" />
<el-option label="失败" :value="false" />
</el-select>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="更新时间"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<database-table-auto-stuffed-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handleDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "数据库表数据自动填充查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加自动填充记录" },
edit: { name: "编辑自动填充记录" },
del: { name: "删除自动填充记录" },
batchDel: { name: "批量删除自动填充记录" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "PictureRounded",
name: "数据库表数据自动填充",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import DatabaseTableAutoStuffedEdit from "./components/DatabaseTableAutoStuffedEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showJavaCodeDialog = ref(false);
const showDocumentDialog = ref(false);
const showTableColumnDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const schemaNameList = ref(null);
const serverList = ref(null);
const batchSelectDatabaseTableAutoStuffedList = ref(null);
const params = reactive({
tableName: "",
schemaNameId: "",
instanceId: "",
status: true,
size: 10,
current: 1,
total: 0,
});
const { tableName, status, size, current, total } = toRefs(params);
/**
* 全选事件
*
*/
const handleSelectionChange = (val) => {
batchSelectDatabaseTableAutoStuffedList.value = val;
console.log(batchSelectDatabaseTableAutoStuffedList.value);
};
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handleDialog = (e) => {
showDialog.value = e;
showJavaCodeDialog.value = e;
showDocumentDialog.value = e;
showTableColumnDialog.value = e;
getDataList();
};
/**
*
* 批量删除
*/
const batchDelDatabaseTableAutoStuffed = () => {
if (batchSelectDatabaseTableAutoStuffedList.value.length == 0) {
proxy.$message({
type: "info",
message: "请选择一个填充记录",
});
return;
}
proxy
.$confirm("此操作将批量永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
let ids = batchSelectDatabaseTableAutoStuffedList.value.map(
(item) => {
return item.id;
},
);
console.log(ids);
const { code } =
await VE_API.system.tableAutoStuffedRecordBatchDelete(ids);
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.tableAutoStuffedRecordDelete({
id,
});
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } =
await VE_API.system.tableAutoStuffedRecordPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
let res;
if (instanceId == null) {
res = await VE_API.system.schemaList();
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaNameList.value = data;
}
await getDataList();
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
onMounted(async () => {
await getServerInstanceList();
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,210 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="项目名称" prop="projectName">
<el-input
clearable
v-model="projectName"
placeholder="项目名称"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column
prop="projectName"
label="项目名称"
></el-table-column>
<el-table-column
prop="instanceName"
label="数据库实例"
></el-table-column>
<el-table-column prop="version" label="version"></el-table-column>
<el-table-column
prop="ormFrameEnums"
label="ORM框架"
></el-table-column>
<el-table-column
prop="uiFrameEnums"
label="UI框架"
></el-table-column>
<el-table-column prop="owner" label="项目拥有者"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<project-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "acw项目查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Mug",
name: "ACW项目管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import ProjectEdit from "./components/ProjectEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
projectName: "",
size: 10,
current: 1,
total: 0,
});
const { projectName, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.projectDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.projectPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,643 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="服务器名称" prop="instanceName">
<el-input
clearable
v-model="instanceName"
placeholder="服务器名称"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<el-button
v-permission="['addInstance']"
size="small"
type="primary"
@click="handleEdit(buttons.addInstance.name)"
>
{{ buttons.addInstance.name }}
</el-button>
<el-row v-if="tableData && tableData.length > 0">
<el-col span="8" style="margin-right: 10%">
<el-tree
:props="resourceProps"
:load="loadNode"
:data="tableData"
@node-click="checkNode"
lazy
show-checkbox
:filter-node-method="filterNode"
>
<template #default="{ data }">
<span class="custom-tree-node">
<img
v-if="data.type === 'instance'"
src="../../../../src/static/redis.png"
style="width: 16px; height: 16px"
/>
<img
v-if="data.type === 'database'"
src="../../../../src/static/database.png"
style="width: 16px; height: 16px"
/>
<img
v-if="data.type === 'key'"
src="../../../../src/static/key.png"
style="width: 16px; height: 16px"
/>
<!-- 实例展示 -->
<span v-if="data.type === 'instance'">
{{ data.name }}
</span>
<el-button
v-if="data.type === 'instance'"
v-permission="['editInstance']"
size="small"
type="primary"
@click="
handleEdit(buttons.editInstance.name, data)
"
>
{{ buttons.editInstance.name }}
</el-button>
<el-button
v-if="data.type === 'instance'"
v-permission="['delInstance']"
size="small"
type="primary"
@click="handleDel(data.id)"
>
{{ buttons.delInstance.name }}
</el-button>
<!-- 数据库展示 -->
<span v-if="data.type === 'database'">
{{ data.name }} ({{ data.keysNum }})
</span>
<!-- key展示 -->
<span v-if="data.type === 'key'">
{{ data.name }}
</span>
<el-button
v-if="data.type === 'key'"
v-permission="['delKey']"
@click.prevent="handleDelKey(data)"
type="danger"
size="small"
>
{{ buttons.delKey.name }}
</el-button>
</span>
</template>
</el-tree>
</el-col>
<el-col
span="16"
v-if="
currentClickRowData &&
(currentClickRowData.type === 'database' ||
currentClickRowData.type === 'key')
"
style="position: absolute; right: 20px"
>
<!-- 搜索key -->
<!-- <el-form ref="queryForm" :inline="true" :model="params">-->
<!-- <el-form-item label="key" prop="key">-->
<!-- <el-input-->
<!-- clearable-->
<!-- v-model="instanceName"-->
<!-- placeholder="key"-->
<!-- ></el-input>-->
<!-- </el-form-item>-->
<!-- <el-form-item>-->
<!-- <el-button-->
<!-- type="primary"-->
<!-- @click="onSubmit(params, getDataList)"-->
<!-- >-->
<!-- {{ buttons.search.name }}-->
<!-- </el-button>-->
<!-- <el-button-->
<!-- @click="resetForm(queryForm, params, getDataList)"-->
<!-- >-->
<!-- 重置-->
<!-- </el-button>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- 展示database 下多有的keys -->
<ve-table
:table="{
data: currentShowData.redisInstanceConsoleFindKeysValues,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(
val,
params,
findKeysValues(currentClickRowData.value),
),
onCurrentChange: (val) =>
handleCurrentChange(
val,
params,
findKeysValues(currentClickRowData.value),
),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['addKey']"
size="small"
type="primary"
@click="handleKeyEdit({})"
>
{{ buttons.addKey.name }}
</el-button>
</template>
<el-table-column prop="key" label="key"></el-table-column>
<el-table-column
prop="value"
label="value"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['editKey']"
@click.prevent="handleKeyEdit(row)"
type="primary"
size="small"
>
{{ buttons.editKey.name }}
</el-button>
<el-button
v-permission="['delKey']"
@click.prevent="handleDelKey(row)"
type="danger"
size="small"
>
{{ buttons.delKey.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 展示database 的keys结束 -->
</el-col>
</el-row>
<el-empty v-show="tableData.length === 0" />
<!-- 列表 -->
<!-- <ve-table-->
<!-- :table="{-->
<!-- data: tableData,-->
<!-- }"-->
<!-- :pagination="{-->
<!-- onSizeChange: (val) =>-->
<!-- handleSizeChange(val, params, getDataList),-->
<!-- onCurrentChange: (val) =>-->
<!-- handleCurrentChange(val, params, getDataList),-->
<!-- currentPage: current,-->
<!-- pageSize: size,-->
<!-- total: total,-->
<!-- }"-->
<!-- >-->
<!-- <template #tool_bar>-->
<!-- <el-button-->
<!-- v-permission="['add']"-->
<!-- size="small"-->
<!-- type="primary"-->
<!-- @click="handleEdit(buttons.add.name)"-->
<!-- >-->
<!-- {{ buttons.add.name }}-->
<!-- </el-button>-->
<!-- </template>-->
<!-- <el-table-column-->
<!-- prop="instanceName"-->
<!-- label="服务器名称"-->
<!-- ></el-table-column>-->
<!-- <el-table-column prop="username" label="登录名"></el-table-column>-->
<!-- <el-table-column prop="password" label="登陆密码">-->
<!-- <template v-slot="{ row }">-->
<!-- <span>-->
<!-- {{-->
<!-- row.password &&-->
<!-- row.password-->
<!-- .split("")-->
<!-- .fill("*", 1, -1)-->
<!-- .join()-->
<!-- .replace(/\,/g, "")-->
<!-- }}-->
<!-- </span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column prop="host" label="host"></el-table-column>-->
<!-- <el-table-column prop="port" label="端口"></el-table-column>-->
<!-- <el-table-column prop="status" label="状态"></el-table-column>-->
<!-- <el-table-column prop="sort" label="排序"></el-table-column>-->
<!-- <el-table-column fixed="right" label="操作">-->
<!-- <template v-slot:default="{ row }">-->
<!-- <el-button-->
<!-- v-permission="['edit']"-->
<!-- @click.prevent="handleEdit(buttons.edit.name, row)"-->
<!-- type="primary"-->
<!-- size="small"-->
<!-- >-->
<!-- {{ buttons.edit.name }}-->
<!-- </el-button>-->
<!-- <el-button-->
<!-- v-permission="['del']"-->
<!-- @click.prevent="handleDel(row.id)"-->
<!-- type="danger"-->
<!-- size="small"-->
<!-- >-->
<!-- {{ buttons.del.name }}-->
<!-- </el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </ve-table>-->
<!-- 编辑实例组件 -->
<redis-instance-edit
v-if="showDialog.instanceEdit"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog.instanceEdit"
@closeDialog="handelDialog($event)"
/>
<!-- 编辑key -->
<el-dialog
:title="新增或者修改key"
append-to-body
destroy-on-close
:model-value="showDialog.keyEdit"
@close="handelKeyDialog($event)"
>
<!-- 表单 -->
<el-form
:model="redisKeyData"
ref="formRef"
label-width="120px"
:inline="false"
>
<el-form-item label="数据库的key" prop="redisKeyData.key">
<el-input
v-model="redisKeyData.key"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="value" prop="redisKeyData.value">
<el-input
v-model="redisKeyData.value"
placeholder=""
clearable
></el-input>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="handelKeyDialog(false)">取消</el-button>
<el-button type="primary" @click="handelAddKey()"
>确定</el-button
>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "Redis实例管理",
buttons: {
search: { name: "查询" },
addInstance: { name: "添加Redis实例" },
addKey: { name: "添加Redis key" },
add: { name: "添加实例" },
editInstance: { name: "编辑redis实例" },
editKey: { name: "编辑Redis key" },
delKey: { name: "删除Redis key" },
delInstance: { name: "删除Redis实例" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Collection",
name: "Redis实例管理",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import redisInstanceEdit from "./components/RedisInstanceEdit.vue";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref({});
const queryForm = ref(null);
const tableData = ref([]);
const redisKeyData = ref({});
// 当前node节点对应的数据
const currentClickRowData = ref({});
const currentShowData = ref({}); // 当前展示的所有数据都在这里
const params = reactive({
instanceName: "",
size: 10,
current: 1,
total: 0,
});
const { instanceName, size, current, total } = toRefs(params);
/**
* 左侧服务器树
* @type {Ref<UnwrapRef<*[]>>}
*/
const leftServerTree = ref([]);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value.instanceEdit = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* 编辑key
*/
const handleKeyEdit = (row) => {
showDialog.value.keyEdit = true;
redisKeyData.value = row;
};
/**
* 删除key
*/
const handleDelKey = (row) => {
VE_API.system.redisInstanceConsoleRemoveKey(row);
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value.instanceEdit = e;
getDataList();
};
/**
*
* @param e
*/
const handelKeyDialog = (e) => {
showDialog.value.keyEdit = e;
getDataList();
};
/**
* 添加key
*/
const handelAddKey = async () => {
redisKeyData.value.instanceId = currentClickRowData.value.instanceId;
redisKeyData.value.database = currentClickRowData.value.database;
const { code } = await VE_API.system.redisInstanceConsoleSetKey(
redisKeyData.value,
);
if (code === 0) {
handelKeyDialog(false);
}
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.redisInstanceDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.redisInstancePage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
record.map((item) => {
item.label = item.instanceName;
item.name = item.instanceName;
item.value = item.id;
item.instanceId = item.id;
});
tableData.value = record;
leftServerTree.value = record;
}
};
onMounted(async () => {
await getDataList();
// maxHeight(pagination, queryForm, toolBar, ve_max_height);
});
const resourceProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const loadNode = async (resourceNode, resolve) => {
console.log(resourceNode);
if (resourceNode.level === 0) {
return resolve([]);
}
resourceNode.loaded = true;
const resourceNodeData = resourceNode.data;
currentClickRowData.value = resourceNodeData.data;
if (resourceNodeData.isFile) {
return resolve([]);
}
console.log(resourceNodeData);
let res;
if (resourceNodeData) {
if (resourceNodeData && resourceNodeData.type === "instance") {
// 查询database
res = await VE_API.system.redisInstanceConsoleFindDataBases({
instanceId: resourceNodeData.id,
});
if (res.code === 0) {
res.data.record.map((item) => {
item.name = item.database;
});
}
} else if (resourceNodeData.type === "database") {
// 查询key
res = await VE_API.system.redisInstanceConsoleFindKeys({
instanceId: resourceNodeData.instanceId,
database: resourceNodeData.database,
});
if (res.code === 0) {
res.data.record.map((item) => {
item.name = item.key;
});
}
} else if (resourceNodeData.type === "key") {
// 查询数据
}
if (res) {
const { code, data } = res;
if (code === 0) {
if (data == null) {
return resolve([]);
}
// resourceNode.childNodes = data;
console.log(resourceNode);
return resolve(data.record);
}
} else {
return resolve([]);
}
}
};
/**
* 点击 node节点
*/
const checkNode = (node) => {
currentClickRowData.value = node;
if (currentClickRowData.value.type === "database") {
findKeysValues(currentClickRowData.value);
}
findKeyValue(currentClickRowData.value);
console.log(currentClickRowData.value);
};
/**
* 过滤node
* @param node
*/
const filterNode = (value, tree) => {
if (!value) return true;
return tree.label.includes(value);
};
/**
* 获取所有的keys
* @param currentClickRowData
* @returns {Promise<void>}
*/
const findKeysValues = async (currentClickRowData) => {
if (currentClickRowData.type === "database") {
const res =
await VE_API.system.redisInstanceConsoleFindKeysValues(
currentClickRowData,
);
const { code, data } = res;
if (code === 0) {
currentShowData.value.redisInstanceConsoleFindKeysValues =
data.record;
console.log(currentShowData.value);
} else {
console.log(res);
}
}
};
/**
* 获取key对应的value
* @param currentClickRowData
* @returns {Promise<void>}
*/
const findKeyValue = async (currentClickRowData) => {
if (currentClickRowData.type === "key") {
const res =
await VE_API.system.redisInstanceConsoleFindKeyValue(
currentClickRowData,
);
const { code, data } = res;
if (code === 0) {
currentShowData.value.redisInstanceConsoleFindKeysValues =
data.record;
console.log(currentShowData.value);
} else {
console.log(res);
}
}
};
/**
* 初始化加载数据
*/
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped>
.prefix {
color: var(--el-color-primary);
margin-right: 10px;
}
.prefix.is-leaf {
color: var(--el-color-success);
}
</style>

View File

@@ -1,327 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" property="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
clearable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaNameId">
<el-select
clearable
v-model="params.schemaNameId"
placeholder="数据库名"
@change="getDataList"
>
<el-option
v-for="item in schemaNameList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="表名" prop="tableName">
<el-input
clearable
v-model="tableName"
placeholder="表名"
></el-input>
</el-form-item>
<el-form-item label="sql类型" prop="sqlType">
<el-select
v-model="sqlType"
placeholder="sql类型"
@change="getDataList"
>
<el-option label="查询" value="SELECT" />
<el-option label="更新" value="UPDATE" />
<el-option label="插入" value="INSERT" />
<el-option label="删除" value="DELETE" />
<el-option label="创建" value="CREATE" />
<el-option label="DDL" value="DDL" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
@selectionChange="handleSelectionChange"
>
<template #tool_bar>
<el-button
v-permission="['batchDel']"
size="small"
type="danger"
@click="batchDelSqlAudit"
>
{{ buttons.batchDel.name }}
</el-button>
<el-button
v-permission="['batchExport']"
size="small"
type="primary"
@click="batchExportSqlAudit"
>
{{ buttons.batchExport.name }}
</el-button>
</template>
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="sql执行ID" show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="applicationName"
label="应用名称"
></el-table-column>
<el-table-column prop="instanceId" label="实例ID">
<template v-slot="scope">
<el-select
v-model="scope.row.instanceId"
placeholder="实例ID"
filterable
:disabled="true"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="sqlType" label="执行类型"></el-table-column>
<el-table-column prop="schema" label="数据库"> </el-table-column>
<el-table-column prop="ip" label="ip"></el-table-column>
<el-table-column
prop="tableList"
label="操作的表"
></el-table-column>
<el-table-column
prop="executeSql"
label="执行sql"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
prop="requestId"
label="请求ID"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="更新时间"
></el-table-column>
</ve-table>
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
export default {
data: () => ({
description: "SQL审计",
buttons: {
search: { name: "查询" },
batchDel: { name: "批量删除SQL审计" },
batchExport: { name: "批量导出" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "DataLine",
name: "SQL审计",
parentMenu: acwMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const queryForm = ref(null);
const tableData = ref([]);
const schemaNameList = ref(null);
const serverList = ref(null);
const batchSelectSQLAuditList = ref(null);
const params = reactive({
tableName: "",
schemaNameId: "",
instanceId: "",
status: true,
sqlType: "",
size: 10,
current: 1,
total: 0,
});
const { tableName, size, sqlType, current, total } = toRefs(params);
/**
* 全选事件
*
*/
const handleSelectionChange = (val) => {
batchSelectSQLAuditList.value = val;
console.log(batchSelectSQLAuditList.value);
};
/**
* 批量导出
*/
const batchExportSqlAudit = async () => {
let res = await VE_API.system.slqAuditExport(params, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
*
* 批量删除
*/
const batchDelSqlAudit = () => {
if (batchSelectSQLAuditList.value.length == 0) {
proxy.$message({
type: "info",
message: "请选择一个SQL记录",
});
return;
}
proxy
.$confirm("此操作将批量永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
let ids = batchSelectSQLAuditList.value.map((item) => {
return item.id;
});
const { code } = await VE_API.system.batchDeleteSlqAudit(ids);
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.slqAuditPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
schemaNameList.value = [];
let res;
if (instanceId == null || instanceId === "") {
return;
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaNameList.value = data;
}
await getDataList();
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
onMounted(async () => {
await getServerInstanceList();
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,239 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
filterable
@change="(val) => getSchemaList(val)"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-select
v-model="schema"
filterable
placeholder="数据库实例"
@change="findInstanceSchemaColumnList"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="忽略解析字段" prop="ignoreFieldList">
<el-select
v-model="ignoreFieldList"
filterable
multiple
placeholder="忽略解析字段"
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<span style="float: left"
>{{ item.label }}{{ item.columnComment }}</span
>
<span
style="
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>{{ item.tableName }}</span
></el-option
>
</el-select>
</el-form-item>
<el-form-item label="解析阀值" prop="relationThreshold">
<el-input
v-model="relationThreshold"
placeholder="500"
clearable
></el-input>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
const rules = {
databaseSchemaId: [
{
required: true,
message: "请输入数据库库名",
trigger: "blur",
},
],
instanceId: [
{
required: true,
message: "请输入数据库服务器",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
schema: "",
instanceId: "",
relationThreshold: 99,
ignoreFieldList: [],
});
const { schema, instanceId, relationThreshold, ignoreFieldList } = toRefs(form);
const serverList = ref(null);
const schemaList = ref(null);
const tableColumnList = ref([]);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schema.value = rowData.value.schema),
(instanceId.value = rowData.value.instanceId),
(relationThreshold.value = rowData.value.relationThreshold));
onMounted(async () => {
getInstanceList();
});
/**
* 获取当前表对应的字段
* @returns {Promise<void>}
*/
const findInstanceSchemaColumnList = async () => {
// 设置表备注
tableColumnList.value = [];
let res = await VE_API.system.findInstanceSchemaColumnList({
instanceId: instanceId.value,
schemaName: schema.value,
});
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = data ? data : [];
}
};
/**
* 获取数据库实例
*/
const getInstanceList = () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
const getSchemaList = (databaseInstance = null) => {
console.log(databaseInstance);
// 查询数据schema信息
VE_API.system
.schemaList({
instanceId: instanceId.value,
})
.then((res) => {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
});
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
console.log(form);
res =
await VE_API.system.acwTableAssociationRelationAnalysisSchema(
form,
);
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,358 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="120px"
:inline="false"
>
<el-form-item label="数据库实例ID" prop="instanceId">
<el-select
v-model="instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库实例schema" prop="schema">
<el-select
v-model="schema"
placeholder="数据库名"
@change="getTableList"
filterable
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="原始表" prop="sourceTable">
<el-select
v-model="sourceTable"
placeholder="数据库表名"
@change="getDatabaseTablesColumnList(sourceTable)"
filterable
>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="原始表字段" prop="sourceColumn">
<el-select
v-model="sourceColumn"
placeholder="原始表字段"
filterable
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="关系表" prop="relationTable">
<el-select
v-model="relationTable"
placeholder="关系表"
@change="getDatabaseTablesColumnList(relationTable)"
filterable
>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="关系表字段" prop="relationTableColumn">
<el-select
v-model="relationTableColumn"
placeholder="关系表字段"
filterable
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="类型(1:自动产生的、2:手动添加的)" prop="type">
<el-select
v-model="type"
placeholder="类型(1:自动产生的、2:手动添加的)"
clearable
>
<el-option label="自动产生的" :value="1" />
<el-option label="手动添加的" :value="2" />
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
instanceId: [
{
required: true,
message: "请输入服务器名称",
trigger: "blur",
},
],
schema: [
{
required: true,
message: "请输入账户",
trigger: "blur",
},
],
sourceTable: [
{
required: true,
message: "请输入密码",
trigger: "blur",
},
],
sourceColumn: [
{
required: true,
message: "host不能为空",
trigger: "change",
},
],
relationTable: [
{
required: true,
message: "端口不能为空",
trigger: "change",
},
],
relationTableColumn: [
{
required: true,
message: "driverClassName",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
instanceId: "",
schema: "",
sourceTable: "",
sourceColumn: "",
relationTable: "",
relationTableColumn: "",
type: 2,
});
const {
instanceId,
schema,
sourceTable,
sourceColumn,
relationTable,
relationTableColumn,
type,
} = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((instanceId.value = rowData.value.instanceId),
(schema.value = rowData.value.schema),
(sourceTable.value = rowData.value.sourceTable),
(sourceColumn.value = rowData.value.sourceColumn),
(relationTable.value = rowData.value.relationTable),
(relationTableColumn.value = rowData.value.relationTableColumn),
(type.value = rowData.value.type));
const schemaList = ref(null);
const tableList = ref(null);
const tableColumnList = ref([]);
const serverList = ref(null);
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
/**
* 选择数据库实例
* @param serverInstanceId
* @returns {Promise<void>}
*/
const getSchemaList = async () => {
// 查询数据库
let res = await VE_API.system.schemaList({
instanceId: instanceId.value,
});
const { code } = res;
if (code === 0) {
if (res.data) {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
}
}
};
/**
* 获取 数据库表
* @param instanceId 数据库实例ID
* @param schemaName 数据库名称
* @returns {Promise<void>}
*/
const getTableList = async () => {
let res;
if (instanceId.value == null) {
return;
} else {
res = await VE_API.system.tableList({
instanceId: instanceId.value,
schemaName: schema.value,
});
}
const { code, data } = res;
if (code === 0) {
if (data) {
data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
tableList.value = data;
}
}
};
/**
* 获取当前表对应的字段
* @param tableIds
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async (table) => {
// 设置表备注
tableColumnList.value = [];
let res = await VE_API.system.findDatabaseTableColumnList({
instanceId: instanceId.value,
schemaName: schema.value,
tableName: table,
});
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = data ? data : [];
}
};
/**
* 页面初始化方法
*/
onMounted(async () => {
await getServerInstanceList();
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res =
await VE_API.system.acwTableAssociationRelationStory(form);
} else {
res = await VE_API.system.acwTableAssociationRelationStory({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,590 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
:width="'80%'"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="应用名称" prop="applicationId">
<el-select
v-model="applicationId"
placeholder="应用名称"
@change="changeApplication"
clearable
>
<el-option
v-for="item in applicationList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="应用表" prop="tableNameList">
<el-select
v-model="tableNameList"
placeholder="应用表"
@change="changeTable"
multiple
clearable
>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="接口分组" prop="tag">
<el-input v-model="tag" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="接口描述" prop="description">
<el-input
v-model="description"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="接口类型" prop="method">
<el-select v-model="method" placeholder="" clearable>
<el-option label="GET" value="GET" />
<el-option label="HEAD" value="HEAD" />
<el-option label="POST" value="POST" />
<el-option label="PUT" value="PUT" />
<el-option label="PATCH" value="PATCH" />
<el-option label="DELETE" value="DELETE" />
<el-option label="OPTIONS" value="OPTIONS" />
<el-option label="TRACE" value="TRACE" />
</el-select>
</el-form-item>
<el-form-item label="接口地址" prop="path">
<el-input v-model="path" placeholder="" clearable></el-input>
</el-form-item>
<div style="text-align: center" class="api_transfer_result">
<el-transfer
v-model="apiFactoryTransferData.leftValue"
style="text-align: left; display: inline-block"
filterable
:left-default-checked="[2, 3]"
:right-default-checked="[1]"
:titles="['原始数据', '接口返回数据']"
:button-texts="['移除返回数据', '添加返回数据']"
:data="tableColumnList"
:props="{ key: 'value', label: 'desc' }"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}',
}"
@change="handleTransferChange"
>
<template #default="{ option }">
<span style="float: left"
>{{ option.label }} {{ option.columnComment }}
</span>
<span style="float: right">
{{ option.tableName }}
</span>
</template>
<template #left-footer>
<el-button class="transfer-footer" size="small"
>Operation</el-button
>
</template>
<template #right-footer>
<el-button class="transfer-footer" size="small"
>Operation</el-button
>
</template>
</el-transfer>
</div>
<div>
<span>路径参数</span>
<el-button
@click="addItem(pathParamColumnIdList, 'PATH_PARAM_TYPE')"
type="primary"
style="float: right"
>增加
</el-button>
<el-empty v-show="pathParamColumnIdList.length === 0">
</el-empty>
<el-form-item
v-for="(it, index) in pathParamColumnIdList"
:key="index"
>
<el-select
v-model="pathParamColumnIdList[index].columnName"
placeholder="路径参数选择"
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<span style="float: left"
>{{ item.label }}{{
item.columnComment
}}</span
>
<span
style="
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>{{ item.tableName }}</span
></el-option
>
</el-select>
<el-select
v-model="pathParamColumnIdList[index].term"
placeholder="条件(大于、等于、模糊)"
>
<el-option label="小等于" value="<" />
<el-option label="等于" value="=" />
<el-option label="大于等于" value=">=" />
<el-option label="小于等于" value="<=" />
<el-option label="不等于" value="!=" />
<el-option label="模糊查询" value="like" />
<el-option label="in" value="in" />
</el-select>
<el-button
@click="removeItem(pathParamColumnIdList, index)"
type="danger"
style="float: right"
>删除
</el-button>
</el-form-item>
</div>
<div>
<span>请求参数</span>
<el-button
@click="
addItem(requestParamColumnIdList, 'REQUEST_PARAM_TYPE')
"
style="float: right"
type="primary"
>增加
</el-button>
<el-empty
v-show="requestParamColumnIdList.length === 0"
></el-empty>
<el-form-item
v-for="(it, index) in requestParamColumnIdList"
:key="index"
>
<el-select
v-model="requestParamColumnIdList[index].columnName"
placeholder="请求参数选择"
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<span style="float: left"
>{{ item.label }}{{
item.columnComment
}}</span
>
<span
style="
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>{{ item.tableName }}</span
></el-option
>
</el-select>
<el-select
v-model="requestParamColumnIdList[index].term"
placeholder="条件(大于、等于、模糊)"
>
<el-option label="小等于" value="<" />
<el-option label="等于" value="=" />
<el-option label="大于等于" value=">=" />
<el-option label="小于等于" value="<=" />
<el-option label="不等于" value="!=" />
<el-option label="模糊查询" value="like" />
<el-option label="in" value="in" />
</el-select>
<el-button
@click="removeItem(requestParamColumnIdList, index)"
style="float: right"
type="danger"
>删除
</el-button>
</el-form-item>
</div>
<div>
<span>请求体参数</span>
<el-button
@click="
addItem(
requestBodyParamColumnIdList,
'REQUEST_BODY_PARAM_TYPE',
)
"
style="float: right"
type="primary"
>增加
</el-button>
<el-empty
v-show="requestBodyParamColumnIdList.length === 0"
></el-empty>
<el-form-item
v-for="(it, index) in requestBodyParamColumnIdList"
:key="index"
>
<el-select
v-model="requestBodyParamColumnIdList[index].columnName"
placeholder="请选择"
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<span style="float: left"
>{{ item.label }}{{
item.columnComment
}}</span
>
<span
style="
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>{{ item.tableName }}</span
></el-option
>
</el-select>
<el-select
v-model="requestBodyParamColumnIdList[index].term"
placeholder="条件(大于、等于、模糊)"
>
<el-option label="大于" value=">" />
<el-option label="小等于" value="<" />
<el-option label="等于" value="=" />
<el-option label="大于等于" value=">=" />
<el-option label="小于等于" value="<=" />
<el-option label="不等于" value="!=" />
<el-option label="模糊查询" value="like" />
<el-option label="in" value="in" />
</el-select>
<el-button
@click="removeItem(requestBodyParamColumnIdList, index)"
type="danger"
style="float: right"
>删除
</el-button>
</el-form-item>
</div>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
applicationId: [
{
required: true,
message: "请选择应用名称",
trigger: "blur",
},
],
tableNameList: [
{
required: true,
message: "请选择表",
trigger: "blur",
},
],
tag: [
{
required: true,
message: "请输入接口分组",
trigger: "blur",
},
],
description: [
{
required: true,
message: "请输入接口描述",
trigger: "change",
},
],
method: [
{
required: true,
message: "请选择接口类型",
trigger: "change",
},
],
path: [
{
required: true,
message: "请选择接口地址",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const applicationList = ref(null);
const tableList = ref(null);
const tableColumnList = ref([]);
// api 工厂穿梭数据
const apiFactoryTransferData = ref({
leftValue: [],
});
const requestBodyParamColumnIdList = ref([]);
const pathParamColumnIdList = ref([]);
const requestParamColumnIdList = ref([]);
const application = ref();
const form = reactive({
applicationId: "",
tableNameList: [],
tag: "",
description: "",
method: "",
path: "",
apiParamQoList: [],
});
const {
applicationId,
tableNameList,
tag,
description,
method,
path,
apiParamQoList,
} = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((applicationId.value = rowData.value.applicationId),
(tag.value = rowData.value.tag),
(description.value = rowData.value.description),
(method.value = rowData.value.method),
(path.value = rowData.value.path),
(apiParamQoList.value = rowData.value.apiParamQoList),
(tableNameList.value = rowData.value.tableNameList));
const handleTransferChange = (transferItem) => {
console.log(transferItem);
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
let apiParamQoList = [];
apiParamQoList = apiParamQoList.concat(pathParamColumnIdList.value);
apiParamQoList = apiParamQoList.concat(requestBodyParamColumnIdList.value);
apiParamQoList = apiParamQoList.concat(requestParamColumnIdList.value);
apiParamQoList = JSON.parse(JSON.stringify(apiParamQoList));
form.apiParamQoList = apiParamQoList;
form.apiResultList = apiFactoryTransferData.value.leftValue;
console.log(apiFactoryTransferData);
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.apiAdd(form);
} else {
res = await VE_API.system.apiEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
onMounted(async () => {
VE_API.system.applicationList().then((res) => {
res.data.map((item) => {
item.label = item.applicationName;
item.value = item.applicationId;
});
applicationList.value = res.data ? res.data : [];
let application = res.data.find(
(item) => item.applicationId === applicationId.value,
);
if (application) {
findTable(application.applicationId);
findTableColumn(form.tableNameList);
}
});
if (apiParamQoList.value !== null && apiParamQoList.value.length > 0) {
pathParamColumnIdList.value = apiParamQoList.value.filter(
(item) => item.type === "PATH_PARAM_TYPE",
);
requestBodyParamColumnIdList.value = apiParamQoList.value.filter(
(item) => item.type === "REQUEST_BODY_PARAM_TYPE",
);
requestParamColumnIdList.value = apiParamQoList.value.filter(
(item) => item.type === "REQUEST_PARAM_TYPE",
);
}
// 选择字段列
await findTableColumn(tableNameList);
});
const changeApplication = (applicationId) => {
let applicationOne = applicationList.value.find(
(item) => item.applicationId === applicationId,
);
application.value = applicationOne;
console.log(applicationOne);
findTable(applicationOne.applicationId);
};
const changeTable = (tableNameList) => {
if (tableNameList == null || tableNameList.length === 0) {
return;
}
findTableColumn(tableNameList);
};
const findTable = async (applicationId) => {
if (null == applicationId) return;
VE_API.system
.applicationFindTables({ applicationId: applicationId })
.then((res) => {
res.data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
tableList.value = res.data ? res.data : [];
});
};
const findTableColumn = async (tableNameList) => {
console.log(tableNameList);
console.log(application.value);
if (
tableNameList === undefined ||
tableNameList.length === 0 ||
tableNameList.length === undefined ||
application.value === undefined
) {
return;
}
let tableNames = tableNameList.join();
VE_API.system
.databaseTablesColumnList({
instanceId: application.value.instanceId,
schemaName: application.value.schemaName,
tableNameList: tableNames,
})
.then((res) => {
res.data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = res.data ? res.data : [];
});
tableNameList.value = tableNameList;
console.log(tableColumnList);
};
const addItem = (paramColumnList, type = null) => {
// 1。这里为什么改变list的大小就能实现动态增加呢因为 el-form-item 遍历的是 list,list 中的每一项都是一个 el-form-item
// 也就是说因为刚开始 list:[{"oneId":''}] 中,只有一个对象,所以才会只出现一个 el-form-item
// 不信可以自己在初始化时 list 中多加入几个对象进行尝试(一定要理解,这里 list 集合的大小与 el-form-item 之间的关系)
// 2、第二个问题:el-form-item 是动态增加了,但是如果 el-select 那里写的是 v-model="oneId" 呢?会发生什么?结果你会发现,只要增加一项 el-form-item ,每一项绑定的值都是你所选中的那一个值.为什么呢?因为每一项的 el-option的 :value 值都绑定在 el-select 的 v-model 上,但这是一个全局唯一值,当下一个 el-form-item 产生后,它里面的 el-select 中绑定的 v-model 还是那个 oneId 的值,因此才会出现这样的问题.好了,我们既然找到了原因,那就要来解决一下了,怎么解决呢?很简单:因为我前面说了,每一个 list 的遍历对象,都是一项 el-form-item,即 el-form-item 项数是和 list 的下标(里面存的对象的索引下标)相关联的,而这个下标,在每一个 el-form-item 中肯定是不一样的,因此我们只需要将 oneId 与这个 下标(即此处的 index) 发生关系即可,因此我们这里将 oneId 声明为了一个数组,当你每选中一个 option 时,都将这个 option 的value放入 oneId[当前el-form-item项数下标] 数组中
console.log(type);
console.log(pathParamColumnIdList.value);
console.log(requestBodyParamColumnIdList.value);
console.log(requestParamColumnIdList.value);
if ("PATH_PARAM_TYPE" === type) {
pathParamColumnIdList.value.push({ type: type });
} else if ("REQUEST_BODY_PARAM_TYPE" === type) {
requestBodyParamColumnIdList.value.push({ type: type });
} else if ("REQUEST_PARAM_TYPE" === type) {
requestParamColumnIdList.value.push({ type: type });
}
// paramColumnList.push({ type: type });
};
const removeItem = (paramColumnList, index) => {
// 删除时,我们带两个参数,这个 it 可用可不用,因为我当时只是想看到删除的这个对象的信息,故而带上了; index 是 list 中该对象对应的下标,也是 el-form-item 的项数
// 根据这个 index 下标删除 list 中 的该对象
paramColumnList.splice(index, 1);
};
</script>
<style scoped>
/* 必需有scoped */
.api_transfer_result >>> .el-transfer-panel {
width: 450px;
}
</style>

View File

@@ -1,135 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="120px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
instanceId: [
{
required: true,
message: "请选择数据库实例",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const serverList = ref(null);
const form = reactive({
instanceId: "",
});
const { instanceId } = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value && (instanceId.value = rowData.value.instanceId);
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
res = await VE_API.system.databaseInstanceBackUp({
instanceId: instanceId.value,
});
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
return serverList.value;
});
};
onMounted(async () => {
await getServerInstanceList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,254 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="120px"
:inline="false"
>
<el-form-item label="服务器名称" prop="instanceName">
<el-input
v-model="instanceName"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input
v-model="username"
placeholder="root"
clearable
></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="password"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="host" prop="host">
<el-input
v-model="host"
placeholder="127.0.0.1"
clearable
></el-input>
</el-form-item>
<el-form-item label="端口" prop="port">
<el-input
v-model="port"
placeholder="3306"
clearable
></el-input>
</el-form-item>
<el-form-item label="驱动程序类名" prop="driverClassName">
<el-input
v-model="driverClassName"
placeholder="com.mysql.cj.jdbc.Driver"
clearable
></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-input v-model="status" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="数据源类型" prop="lazyDataSourceType">
<el-select
v-model="lazyDataSourceType"
placeholder="数据源类型"
clearable
>
<el-option label="MySQL" value="MySQL" />
<el-option label="H2" value="H2" />
<el-option label="CLICK_HOUSE" value="CLICK_HOUSE" />
<el-option label="POSTGRESQL" value="POSTGRESQL" />
</el-select>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="sort" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item
label="是否初始化数据库到本地"
prop="initializeToLocal"
>
<el-select
v-model="initializeToLocal"
placeholder="是否初始化数据库到本地"
clearable
>
<el-option label="初始化数据库到本地" :value="true" />
<el-option label="不初始化数据库到本地" :value="false" />
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button style="float: left" @click="testConnection()"
>测试连接</el-button
>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, toRefs, ref, defineProps, defineEmits } from "vue";
const rules = {
instanceName: [
{
required: true,
message: "请输入服务器名称",
trigger: "blur",
},
],
username: [
{
required: true,
message: "请输入账户",
trigger: "blur",
},
],
password: [
{
required: true,
message: "请输入密码",
trigger: "blur",
},
],
host: [
{
required: true,
message: "host不能为空",
trigger: "change",
},
],
port: [
{
required: true,
message: "端口不能为空",
trigger: "change",
},
],
driverClassName: [
{
required: true,
message: "driverClassName",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
instanceName: "",
driverClassName: "com.mysql.cj.jdbc.Driver",
username: "root",
password: "",
host: "127.0.0.1",
port: 3306,
status: "",
lazyDataSourceType: "MySQL",
sort: 1,
initializeToLocal: false,
});
const {
instanceName,
driverClassName,
username,
password,
host,
port,
status,
lazyDataSourceType,
sort,
initializeToLocal,
} = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((instanceName.value = rowData.value.instanceName),
(username.value = rowData.value.username),
(password.value = rowData.value.password),
(driverClassName.value = rowData.value.driverClassName),
(host.value = rowData.value.host),
(port.value = rowData.value.port),
(status.value = rowData.value.status),
(lazyDataSourceType.value = rowData.value.lazyDataSourceType),
(sort.value = rowData.value.sort),
(initializeToLocal.value = rowData.value.initializeToLocal));
/**
* 测试连接
*/
const testConnection = async () => {
let res = await VE_API.system.databaseInstanceTest(form);
const { code } = res;
if (code === 0) {
console.log("连接成功");
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.databaseInstanceAdd(form);
} else {
res = await VE_API.system.databaseInstanceEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,392 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form
ref="queryForm"
:inline="false"
:model="params"
:rules="rules"
label-width="100px"
>
<el-form-item>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaName">
<el-select
clearable
filterable
v-model="params.schemaName"
@change="
getTableList(params.instanceId, params.schemaName)
"
placeholder="数据库名"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-form-item>
<el-row :gutter="24">
<el-col :span="4">
<el-card>
<el-tree
:props="{
children: 'children',
label: 'tableName',
}"
:data="schemaTableList"
></el-tree>
</el-card>
</el-col>
<el-col :span="20">
<el-card>
<div class="grid-content ep-bg-purple-light">
<el-form-item label="执行的sql" prop="sql">
<el-input
type="textarea"
:rows="20"
v-model="sql"
></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sqlConsole()">
{{ buttons.search.name }}
</el-button>
</el-form-item>
<el-form-item>
<el-button @click="downLoad()" type="text">
{{ buttons.downLoad.name }}
</el-button>
<el-button
@click="downLoadUpsert()"
type="text"
>
{{ buttons.downLoadUpsert.name }}
</el-button>
</el-form-item>
<template
v-for="(tableData, index) in tableDataList"
:key="index"
>
<el-check-tag
:checked="tableData.checked"
@change="changeResultDataTag(index)"
>{{ index + 1 }}个结果集合</el-check-tag
>
</template>
<div
v-for="(tableData, index) in tableDataList"
:key="index"
v-show="tableData.checked"
>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(
val,
params,
getDataList,
),
onCurrentChange: (val) =>
handleCurrentChange(
val,
params,
getDataList,
),
currentPage: current,
pageSize: size,
total: total,
}"
>
<el-table-column
:prop="item"
:label="item"
v-for="(
item, index
) in tableData.tableHeader"
:key="index"
sortable
>
<template v-slot="scope">
<el-input
v-model="scope.row[item]"
placeholder="数据"
></el-input>
</template>
</el-table-column>
</ve-table>
</div>
</div>
</el-card>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
data: () => ({
description: "数据库查询控制台",
buttons: {
search: { name: "查询" },
downLoad: { name: "导出查询结果为Excel" },
downLoadUpsert: { name: "Upsert下载查询结果" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "IceCream",
name: "数据库查询管理",
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted } from "vue";
const rules = {
instanceId: [
{
required: true,
message: "请选择数据库实例",
trigger: "blur",
},
],
schemaName: [
{
required: true,
message: "请选择数据库",
trigger: "blur",
},
],
sql: [
{
required: true,
message: "执行SQL不能为空",
trigger: "blur",
},
],
};
//?导入公共查询方法
import {
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const queryForm = ref(null);
const tableDataList = ref([]);
const schemaList = ref(null);
const schemaTableList = ref(null);
const serverList = ref(null);
// 当前选择的表
// const currentTableName = ref(null);
const params = reactive({
schemaName: "",
instanceId: "",
instanceName: "",
sql: "show tables",
size: 10,
current: 1,
total: 0,
});
const { size, current, total, sql } = toRefs(params);
/**
* 点击结果集tag 事件
*/
const changeResultDataTag = async (index) => {
tableDataList.value.forEach((item, itemIndex) => {
if (index == itemIndex) {
item.checked = true;
} else {
item.checked = false;
}
});
console.log(index);
};
/**
* 文件下载
*/
const downLoad = async () => {
queryForm.value.validate(async (valid) => {
if (valid) {
let res = await VE_API.system.sqlConsoleExport(params, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
} else {
return false;
}
});
};
/**
* 文件下载
*/
const downLoadUpsert = async () => {
queryForm.value.validate(async (valid) => {
if (valid) {
let res = await VE_API.system.sqlConsoleUpsertExport(params, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
} else {
return false;
}
});
};
/**
* 执行sql
*/
const sqlConsole = async () => {
queryForm.value.validate(async (valid) => {
if (valid) {
let res = await VE_API.system.sqlConsole(params);
const { code } = res;
if (code === 0) {
tableDataList.value = res.data;
if (res.data.length !== 0) {
tableDataList.value.map((item) => {
item.tableHeader = Object.keys(item[0]);
item.checked = false;
});
tableDataList.value[0].checked = true;
// tableHeader.value = Object.keys(res.data[0]);
// tableHeaderList.value = Object.keys(res.data[0]);
}
console.log(res);
}
} else {
return false;
}
});
};
/**
* 获取 数据库表
* @param instanceId 数据库实例ID
* @param schemaName 数据库名称
* @returns {Promise<void>}
*/
const getTableList = async (instanceId, schemaName) => {
let res;
if (instanceId == null) {
return;
} else {
res = await VE_API.system.tableList({
instanceId: instanceId,
schemaName: schemaName,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaTableList.value = data;
return schemaList.value;
}
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
let res;
if (instanceId == null) {
return;
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = data;
if (schemaList.value) {
// 默认第一个实例的第一个数据库
params.schemaName = schemaList.value[0].schemaName;
await getTableList(instanceId, params.schemaName);
}
return schemaList.value;
}
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
// 默认第一个实例
if (serverList.value && serverList.value.length > 0) {
params.instanceId = serverList.value[0].id;
getSchemaList(params.instanceId);
}
return serverList.value;
});
};
onMounted(async () => {
await getServerInstanceList();
});
</script>
<style lang="scss" scoped>
.el-tabs__content.el-tab-pane {
display: block;
background: #409eff;
}
</style>

View File

@@ -1,217 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="120px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
@change="getSchemaList"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaName">
<el-select
clearable
filterable
v-model="schemaName"
placeholder="数据库名"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-form>
<el-progress
:text-inside="true"
:stroke-width="24"
:percentage="backUpsSchemaProgress.percentage"
:hidden="backUpsSchemaProgress.hidden"
:status="backUpsSchemaProgress.status"
>
<span>备份数据库</span>
</el-progress>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
instanceId: [
{
required: true,
message: "请选择数据库实例",
trigger: "blur",
},
],
schemaName: [
{
required: true,
message: "请选择数据库",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "数据库备份",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const serverList = ref(null);
const schemaList = ref(null);
const instanceId = ref(null);
const schemaName = ref(null);
const backUpsSchemaProgress = reactive({
hidden: true,
percentage: 0,
status: "success",
});
const form = reactive({
instanceId: "",
schemaName: "",
});
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value && (instanceId.value = rowData.value.instanceId);
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
form.schemaName = schemaName.value;
form.instanceId = instanceId.value;
formRef.value.validate(async (valid) => {
if (valid) {
backUpsSchemaProgress.hidden = false;
// 修改进度条
setInterval(() => {
backUpsSchemaProgress.percentage =
(backUpsSchemaProgress.percentage % 100) + 10;
}, 500);
let res = await VE_API.system.databaseSchemaBackUp({
instanceId: instanceId.value,
schemaName: schemaName.value,
});
const { code } = res;
if (code === 0) {
backUpsSchemaProgress.status = "success";
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
/**
* 获取 数据库
* @param instanceId 数据库实例ID
* @returns {Promise<void>}
*/
const getSchemaList = async (instanceId) => {
let res;
if (instanceId == null) {
return;
} else {
res = await VE_API.system.schemaList({
instanceId,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = data;
if (schemaList.value) {
// 默认第一个实例的第一个数据库
schemaName.value = schemaList.value[0].schemaName;
}
return schemaList.value;
}
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
// 默认第一个实例
if (serverList.value && serverList.value.length > 0) {
instanceId.value = serverList.value[0].id;
getSchemaList(instanceId.value);
}
return serverList.value;
});
};
onMounted(async () => {
await getServerInstanceList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,260 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
@change="getSchemaList"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-select
clearable
v-model="schemaName"
placeholder="数据库名"
@change="getTableList"
filterable
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据库表名" prop="sortingRules">
<el-select
clearable
v-model="tableName"
placeholder="数据库表名"
@change="getDatabaseTablesColumnList"
filterable
>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="字段名称" prop="columnName">
<el-select
v-model="columnName"
placeholder="字段名称"
filterable
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
const rules = {
schemaName: [
{
required: true,
message: "请输入数据库库名",
trigger: "blur",
},
],
instanceId: [
{
required: true,
message: "请输入数据库服务器",
trigger: "blur",
},
],
tableName: [
{
required: true,
message: "请输入字符集",
trigger: "blur",
},
],
columnName: [
{
required: false,
message: "请输入排序规则",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const tableColumnList = ref(null);
const form = reactive({
schemaName: "",
instanceId: "",
tableName: "",
columnName: "",
});
const { schemaName, instanceId, tableName, columnName } = toRefs(form);
const serverList = ref(null);
const schemaList = ref(null);
const tableList = ref(null);
/**
* 获取当前表对应的字段
* @param tableIds
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async () => {
// 获取数据
let res = await VE_API.system.findDatabaseTableColumnList({
instanceId: form.instanceId,
schemaName: form.schemaName,
tableName: form.tableName,
});
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = data ? data : [];
}
};
/**
* 获取 数据库表
* @param instanceId 数据库实例ID
* @param schemaName 数据库名称
* @returns {Promise<void>}
*/
const getTableList = async () => {
let res;
if (instanceId.value == null) {
return;
} else {
res = await VE_API.system.tableList({
instanceId: form.instanceId,
schemaName: form.schemaName,
});
}
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
tableList.value = data;
}
};
/**
* 选择数据库实例
* @param serverInstanceId
* @returns {Promise<void>}
*/
const getSchemaList = async () => {
// 查询数据库
let res = await VE_API.system.schemaList({
instanceId: form.instanceId,
});
const { code } = res;
if (code === 0) {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
}
};
onMounted(async () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res = await VE_API.system.schemaDeriveView(form);
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,255 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select v-model="instanceId" placeholder="数据库实例">
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-input
v-model="schemaName"
placeholder="数据库库名"
clearable
></el-input>
</el-form-item>
<el-form-item label="字符集" prop="characterSet">
<el-select
v-model="characterSet"
placeholder="字符集"
filterable
>
<el-option label="armscii8" value="armscii8" />
<el-option label="ascii" value="ascii" />
<el-option label="big5" value="big5" />
<el-option label="binary" value="binary" />
<el-option label="cp850" value="cp850" />
<el-option label="cp852" value="cp852" />
<el-option label="cp866" value="cp866" />
<el-option label="cp932" value="cp932" />
<el-option label="cp1250" value="cp1250" />
<el-option label="cp1251" value="cp1251" />
<el-option label="cp1256" value="cp1256" />
<el-option label="cp1257" value="cp1257" />
<el-option label="dec8" value="dec8" />
<el-option label="eucjpms" value="eucjpms" />
<el-option label="euckr" value="euckr" />
<el-option label="gb2312" value="gb2312" />
<el-option label="gb18030" value="gb18030" />
<el-option label="gbk" value="gbk" />
<el-option label="geostd8" value="geostd8" />
<el-option label="greek" value="greek" />
<el-option label="hebrew" value="hebrew" />
<el-option label="hp8" value="hp8" />
<el-option label="keybcs2" value="keybcs2" />
<el-option label="koi8r" value="koi8r" />
<el-option label="koi8u" value="koi8u" />
<el-option label="latin1" value="latin1" />
<el-option label="latin2" value="latin2" />
<el-option label="latin5" value="latin5" />
<el-option label="latin7" value="latin7" />
<el-option label="macce" value="macce" />
<el-option label="macroman" value="macroman" />
<el-option label="sjis" value="sjis" />
<el-option label="swe7" value="swe7" />
<el-option label="tis620" value="tis620" />
<el-option label="ucs2" value="ucs2" />
<el-option label="ujis" value="ujis" />
<el-option label="utf8" value="utf8" />
<el-option label="utf8mb4" value="utf8mb4" />
<el-option label="utf16" value="utf16" />
<el-option label="utf16le" value="utf16le" />
<el-option label="utf32" value="utf32" />
</el-select>
</el-form-item>
<el-form-item label="排序规则" prop="sortingRules">
<el-input
v-model="sortingRules"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="ext" prop="ext">
<el-input v-model="ext" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item
label="是否初始化数据库到本地"
prop="initializeToLocal"
>
<el-select
v-model="initializeToLocal"
placeholder="是否初始化数据库到本地"
clearable
>
<el-option label="初始化数据库到本地" :value="true" />
<el-option label="不初始化数据库到本地" :value="false" />
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
const rules = {
schemaName: [
{
required: true,
message: "请输入数据库库名",
trigger: "blur",
},
],
instanceId: [
{
required: true,
message: "请输入数据库服务器",
trigger: "blur",
},
],
characterSet: [
{
required: true,
message: "请输入字符集",
trigger: "blur",
},
],
sortingRules: [
{
required: false,
message: "请输入排序规则",
trigger: "blur",
},
],
ext: [
{
required: false,
message: "ext",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
schemaName: "",
instanceId: "",
ext: "",
characterSet: "",
sortingRules: "",
initializeToLocal: "",
});
const {
schemaName,
instanceId,
ext,
characterSet,
sortingRules,
initializeToLocal,
} = toRefs(form);
const serverList = ref(null);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schemaName.value = rowData.value.schemaName),
(instanceId.value = rowData.value.instanceId),
(characterSet.value = rowData.value.characterSet),
(sortingRules.value = rowData.value.sortingRules),
(ext.value = rowData.value.ext),
(initializeToLocal.value = rowData.value.initializeToLocal));
onMounted(async () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value == "添加") {
res = await VE_API.system.schemaAdd(form);
} else {
res = await VE_API.system.schemaEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,279 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
filterable
@change="(val) => getSchemaList(val)"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schemaName">
<el-select
v-model="schemaName"
filterable
placeholder="数据库实例"
@change="(val) => getTableList(val)"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="表名称" prop="tableNameList">
<el-select
v-model="tableNameList"
placeholder="表名称"
@change="chooseTable"
filterable
multiple
>
<el-checkbox
v-model="checked"
:indeterminate="
tableNameList.length !== tableList.length
"
@change="selectAll()"
style="margin-left: 20px"
>
全选
</el-checkbox>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="自动填充数量" prop="autoStuffedNum">
<el-input
v-model="autoStuffedNum"
placeholder=""
clearable
></el-input>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
const rules = {
databaseSchemaId: [
{
required: true,
message: "请输入数据库库名",
trigger: "blur",
},
],
instanceId: [
{
required: true,
message: "请输入数据库服务器",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
schemaName: "",
databaseSchemaId: "",
instanceId: "",
instanceName: "",
autoStuffedNum: "",
status: false,
tableNameList: [],
id: "",
});
const {
id,
schemaName,
databaseSchemaId,
instanceId,
instanceName,
autoStuffedNum,
status,
tableNameList,
} = toRefs(form);
const serverList = ref(null);
const schemaList = ref(null);
const tableList = ref([]);
const checked = ref(false);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((id.value = rowData.value.id),
(schemaName.value = rowData.value.schemaName),
(databaseSchemaId.value = rowData.value.databaseSchemaId),
(instanceId.value = rowData.value.instanceId),
(instanceName.value = rowData.value.instanceName),
(autoStuffedNum.value = rowData.value.autoStuffedNum),
(status.value = rowData.value.status),
(tableNameList.value = [rowData.value.tableName]));
onMounted(async () => {
getInstanceList();
// getSchemaList();
// getTableList();
});
const getInstanceList = () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
const getSchemaList = (databaseInstance = null) => {
console.log(databaseInstance);
// 查询数据schema信息
VE_API.system
.schemaList({
instanceId: instanceId.value,
})
.then((res) => {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
});
};
const getTableList = () => {
// 查询数据表信息
VE_API.system
.tableList({
instanceId: instanceId.value,
schemaName: schemaName.value,
})
.then((res) => {
if (res.data) {
res.data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
tableList.value = res.data ? res.data : [];
}
});
};
/**
* 选择表事件
*/
const chooseTable = () => {
let table = tableList.value.find(
(item) => item.schemaNameId === databaseSchemaId.value,
);
console.log(table);
if (table) {
instanceName.value = table.instanceName;
schemaName.value = table.schemaName;
}
};
const selectAll = () => {
console.log(checked.value);
if (checked.value) {
checked.value = false;
tableNameList.value = [];
} else {
checked.value = true;
tableNameList.value = tableList.value.map((d) => d.tableName);
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加自动填充记录") {
console.log(form);
res = await VE_API.system.tableAutoStuffedRecordBatchAdd(form);
} else {
res = await VE_API.system.tableAutoStuffedRecordEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,847 +0,0 @@
<template>
<el-descriptions title="数据库表信息" :column="4" border>
<el-descriptions-item
label="数据库实例"
label-align="right"
align="center"
property="instanceId"
>
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item
label="数据库名"
label-align="right"
align="center"
width="150px"
property="schemaName"
>
<el-select
v-model="params.schemaName"
placeholder="数据库名"
@change="getTableList"
filterable
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item
label="数据库表名"
label-align="right"
align="center"
>
<el-select
v-model="params.tableName"
placeholder="数据库表名"
@change="getDatabaseTablesColumnList"
filterable
>
<el-option
v-for="item in tableList"
:key="item.value"
:label="item.label"
:value="item.value"
><el-row>
<el-col :span="12">
<span style="float: left">{{ item.label }}</span>
</el-col>
<el-col :span="12">
<span
style="
float: right;
color: #8492a6;
font-size: 13px;
"
>{{ item.tableComment }}
</span>
</el-col>
</el-row></el-option
>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="表引擎" label-align="right" align="center">
<el-select
v-model="params.engine"
placeholder="表引擎"
filterable
:disabled="true"
>
<el-option label="ARCHIVE" value="ARCHIVE" />
<el-option label="BLACKHOLE" value="BLACKHOLE" />
<el-option label="CSV" value="CSV" />
<el-option label="InnoDB" value="InnoDB" />
<el-option label="MEMORY" value="MEMORY" />
<el-option label="MRG_MYISAM" value="MRG_MYISAM" />
<el-option label="MyISAM" value="MyISAM" />
<el-option
label="PERFORMANCE_SCHEMA"
value="PERFORMANCE_SCHEMA"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="表描述" label-align="right" align="center">
<el-input
v-model="tableComment"
placeholder="tableComment"
:disabled="true"
></el-input>
</el-descriptions-item>
<el-descriptions-item
label="查询字段"
label-align="right"
align="center"
>
<el-select
v-model="selectColumnList"
value-key="columnName"
placeholder="查询字段"
filterable
multiple
collapse-tags
style="width: 240px"
@change="selectColumnOnChange"
>
<el-checkbox
v-model="params.checked"
:indeterminate="
selectColumnList.length !== tableColumnList.length
"
@change="selectAllFields()"
style="margin-left: 20px"
>
全选
</el-checkbox>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item"
>
<el-row>
<el-col :span="12">
<span style="float: left">{{ item.label }}</span>
</el-col>
<el-col :span="12">
<span
style="
float: right;
color: #8492a6;
font-size: 13px;
"
>{{ item.columnComment }}
</span>
</el-col>
</el-row>
</el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="表头展示模式" prop="status">
<el-radio-group v-model="params.showTitleMode">
<el-radio-button label="columnName">字段名称</el-radio-button>
<el-radio-button label="columnComment"
>字段描述</el-radio-button
>
</el-radio-group>
</el-descriptions-item>
</el-descriptions>
<el-row>
<el-button @click="addColumnItem()" style="float: left" type="primary"
>添加搜索参数
</el-button>
<el-button @click="getDataList" style="float: left" type="primary"
>执行
</el-button>
<!-- <el-button-->
<!-- v-permission="['batchDel']"-->
<!-- type="danger"-->
<!-- @click="batchDelRow"-->
<!-- style="float: left"-->
<!-- >-->
<!-- {{ buttons.batchDel.name }}-->
<!-- </el-button>-->
<el-button type="danger" @click="batchDelRow" style="float: left">
{{ buttons.batchDel.name }}
</el-button>
<el-button
@click="addRowData"
style="float: left"
type="primary"
:hidden="!params.checked"
>添加数据
</el-button>
<el-button
@click="handleExportUpsertSql"
style="float: left"
type="primary"
>导出查询的upsert语句
</el-button>
<el-button
@click="handleExportResult2Md"
style="float: left"
type="primary"
>导出查询结果为.MD
</el-button>
</el-row>
<div style="padding: 10px">
<el-row
v-for="(it, index) in params.queryCriteriaColumnList"
:key="index"
>
<el-col span="3">
<el-checkbox v-model="it.checked" label=" " size="large" />
</el-col>
<el-col span="6">
<el-select
v-model="it.columnName"
placeholder="字段名称"
filterable
@change="getOnlyColumnValue(it)"
>
<el-option
v-for="item in tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<el-row>
<el-col :span="12">
<span style="float: left">{{
item.label
}}</span>
</el-col>
<el-col :span="12">
<span
style="
float: right;
color: #8492a6;
font-size: 13px;
"
>{{ item.columnComment }}
</span>
</el-col>
</el-row>
</el-option>
</el-select>
</el-col>
<el-col span="6">
<el-select
v-model="it.condition"
placeholder="条件(大于、等于、模糊)"
filterable
>
<el-option label="小等于" value="<" />
<el-option label="等于" value="=" />
<el-option label="大于等于" value=">=" />
<el-option label="小于等于" value="<=" />
<el-option label="不等于" value="!=" />
<el-option label="模糊查询" value="like" />
<el-option label="in" value="in" />
</el-select>
</el-col>
<el-col span="6">
<el-select
v-model="it.data"
style="width: 230px"
placeholder="数据"
filterable
clearable
allow-create
>
<el-option
v-for="columnUnitValue in it.columnUnitValueList"
:key="columnUnitValue"
:label="columnUnitValue"
:value="columnUnitValue"
/>
</el-select>
</el-col>
<el-col span="6">
<el-button
@click="removeColumnItem(index)"
style="float: right"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</el-col>
</el-row>
</div>
<!-- 列表 -->
<div style="height: 120%">
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
@selectionChange="handleSelectionChange"
:key="tableKey"
>
<!-- 复选框 -->
<el-table-column
v-if="tableData.length !== 0"
type="selection"
width="55"
/>
<!-- 所有的数据列表 -->
<!-- <el-table-column-->
<!-- v-for="(item, index) in tableColumnList"-->
<!-- :prop="item.columnName"-->
<!-- :label="item.columnName"-->
<!-- :key="index"-->
<!-- sortable-->
<!-- >-->
<!-- <template v-slot="scope">-->
<!-- <el-input-->
<!-- v-model="scope.row[item.columnName]"-->
<!-- placeholder="数据"-->
<!-- @change="changeRow(scope.row)"-->
<!-- ></el-input>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- 选取的返回结果 -->
<!-- 展示字段描述 -->
<el-table-column
v-for="(item, index) in selectColumnList"
:prop="dynamicColumnList[index].columnName"
:label="
params.showTitleMode === 'columnName'
? item.columnName
: item.columnComment === ''
? item.columnName
: item.columnComment
"
:key="`col_${index}`"
sortable
>
<template v-slot="scope">
<el-input
v-model="scope.row[item.columnName]"
placeholder="数据"
@change="changeRow(scope.row)"
></el-input>
</template>
</el-table-column>
</ve-table>
<div style="position: relative">
<el-input
type="textarea"
v-model="tableData.sql"
readonly
></el-input>
<el-icon
@click="copyAnswer(tableData.sql)"
style="float: right; position: absolute; right: 10px; top: 10px"
>
<DocumentCopy
/></el-icon>
</div>
</div>
<!-- <el-button @click="closeDialog()">取消</el-button>-->
<!-- <el-button type="primary" @click="onSubmit()">确定</el-button>-->
</template>
<script>
export default {
data: () => ({
description: "数据库表快捷查询",
buttons: {
del: { name: "删除字段" },
batchDel: { name: "批量删除数据" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Finished",
name: "数据库表快捷查询",
}),
};
</script>
<script setup>
//导入公共查询方法
import {
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
import { reactive, toRefs, ref, defineProps, onMounted } from "vue";
import { DocumentCopy } from "@element-plus/icons-vue";
import useClipboard from "vue-clipboard3";
const { toClipboard } = useClipboard();
import Sortable from "sortablejs";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const { rowData } = toRefs(props);
// 表字段
const tableColumnList = ref([]);
// 返回结果
const selectColumnList = ref([]);
const tableKey = ref(1);
const params = reactive({
schemaName: "",
instanceId: "",
tableComment: "",
tableName: "",
engine: "",
tableCatalog: "",
checked: true,
showTitleMode: "columnName",
// 查询条件字段
queryCriteriaColumnList: [],
//返回结果
selectColumnList: [],
current: 1,
size: 10,
total: 0,
});
const {
schemaName,
instanceId,
tableComment,
tableName,
engine,
size,
current,
total,
} = toRefs(params);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schemaName.value = rowData.value.schemaName),
(instanceId.value = rowData.value.instanceId),
(tableName.value = rowData.value.tableName));
const schemaList = ref(null);
const tableList = ref(null);
const tableData = ref([]);
const serverList = ref(null);
const batchSelectRowList = ref(null);
// const oldList = ref(JSON.parse(JSON.stringify(selectColumnList.value)));
// 动态列
const dynamicColumnList = ref([]);
//
// /**
// * 表头预览
// * @param h
// * @param column
// * @returns {*}
// */
// const renderColumnHeader = (h) => {
// // // h即为cerateElement的简写具体可看vue官方文档
// // return h("div", [
// // h("span", "column.label"),
// // h("i", {
// // class: "el-icon-question",
// // }),
// // ]);
// };
/**
* 选择行改变事件
*/
const selectColumnOnChange = () => {
console.log("selectColumnList: " + selectColumnList.value);
console.log("dynamicColumnList: " + dynamicColumnList.value);
dynamicColumnList.value = selectColumnList.value;
};
/**
* 全选字段
*
*/
const selectAllFields = () => {
console.log(params.checked);
if (params.checked) {
params.checked = true;
// selectColumnList.value = tableColumnList.value;
initColumnList(tableColumnList.value);
} else {
params.checked = false;
// selectColumnList.value = [];
initColumnList([]);
}
};
/**
* 获取惟一数据
* @returns {Promise<void>}
*/
const getOnlyColumnValue = async (rowColumn) => {
const columnName = rowColumn.columnName;
console.log(rowColumn);
let res = await VE_API.system.tableColumnSqlConsole({
instanceId: params.instanceId,
schemaName: params.schemaName,
tableName: params.tableName,
column: columnName,
current: 1,
size: 100,
});
const { code, data } = res;
if (code === 0) {
rowColumn.columnUnitValueList = data.record ? data.record : [];
// console.log(res);
}
};
/**
* 批量删除数据
*/
const batchDelRow = async () => {
console.log(batchSelectRowList.value);
let deleteBatchRow = {
schemaName: params.schemaName,
instanceId: params.instanceId,
tableName: params.tableName,
tableRowList: [],
};
for (let row of batchSelectRowList.value) {
deleteBatchRow.tableRowList.push(row);
}
console.log(deleteBatchRow);
let res = await VE_API.system.tableRowBatchDelete(deleteBatchRow);
const { code, data } = res;
if (code === 0) {
console.log(data); //
}
await getDataList();
};
/**
* 全选事件
*
*/
const handleSelectionChange = (val) => {
batchSelectRowList.value = val;
console.log(batchSelectRowList.value);
};
/**
* 行数据变更
* @param row 行数据
* @returns {Promise<void>}
*/
const changeRow = async (row) => {
let storyRow = {
schemaName: params.schemaName,
instanceId: params.instanceId,
tableName: params.tableName,
tableRow: row,
};
console.log(storyRow);
let res = await VE_API.system.tableRowStory(storyRow);
const { code, data } = res;
if (code === 0) {
console.log(data); //
await getDataList();
}
};
/**
* 新增一行数据
*/
const addRowData = () => {
tableData.value.push({});
};
/**
* 获取当前表数据
*/
const getDataList = async () => {
console.log(selectColumnList.value);
console.log(selectColumnList.value.length);
params.selectColumnList = selectColumnList.value.map((d) => d.columnName);
let res = await VE_API.system.tableSqlConsole(params);
const { code, data, ext } = res;
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
tableData.value.tableHeader = ext.tableHeader;
tableData.value.sql = ext.sql;
if (record.length === 0) {
return;
}
console.log(ext);
// tableData.value.tableHeader = Object.keys(tableData.value[0]);
// console.log(tableData.value);
}
};
/**
* 导出查询的 upsert 数据
*/
const handleExportUpsertSql = async () => {
params.selectColumnList = selectColumnList.value.map((d) => d.columnName);
let res = await VE_API.system.tableSqlConsoleUpsertExport(params, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 导出结果为md
* @returns {Promise<void>}
*/
const handleExportResult2Md = async () => {
params.selectColumnList = selectColumnList.value.map((d) => d.columnName);
let res = await VE_API.system.tableSqlConsoleMdExport(params, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
// 添加表字段
const addColumnItem = () => {
params.queryCriteriaColumnList.push({
condition: "=",
checked: true,
});
};
// 删除字段
const removeColumnItem = (index) => {
// 删除时,我们带两个参数,这个 it 可用可不用,因为我当时只是想看到删除的这个对象的信息,故而带上了; index 是 list 中该对象对应的下标,也是 el-form-item 的项数
// 根据这个 index 下标删除 list 中 的该对象
params.queryCriteriaColumnList.splice(index, 1);
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
/**
* 选择数据库实例
* @param serverInstanceId
* @returns {Promise<void>}
*/
const getSchemaList = async () => {
// 查询数据库
let res = await VE_API.system.schemaList({
instanceId: params.instanceId,
});
const { code } = res;
if (code === 0) {
if (res.data) {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
}
}
};
/**
* 获取 数据库表
* @param instanceId 数据库实例ID
* @param schemaName 数据库名称
* @returns {Promise<void>}
*/
const getTableList = async () => {
tableName.value = null;
tableComment.value = null;
let res;
if (instanceId.value == null) {
return;
} else {
res = await VE_API.system.tableList({
instanceId: instanceId.value,
schemaName: schemaName.value,
});
}
const { code, data } = res;
if (code === 0) {
if (data) {
data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
tableList.value = data;
}
}
};
/**
* 获取当前表对应的字段
* @param tableIds
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async () => {
// 设置表备注
let table = tableList.value.find(
(item) => item.tableName === tableName.value,
);
tableColumnList.value = [];
params.queryCriteriaColumnList = [];
if (table != null) {
tableComment.value = table.tableComment;
engine.value = table.engine;
} else {
return;
}
let res = await VE_API.system.findDatabaseTableColumnList({
instanceId: instanceId.value,
schemaName: schemaName.value,
tableName: tableName.value,
});
const { code, data } = res;
if (code === 0) {
data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = data ? data : [];
// 默认全选数据
initColumnList(tableColumnList.value);
}
// 获取数据
await getDataList();
};
/**
* 初始化列、动态列
*/
const initColumnList = (tableColumnList) => {
selectColumnList.value = tableColumnList;
dynamicColumnList.value = JSON.parse(JSON.stringify(tableColumnList));
//
rowDrop();
colDrop();
};
// 列表 **行拖拽
const rowDrop = async () => {
// 此时找到的元素是要拖拽元素的父容器
const tbody = document.querySelector(".el-table__body-wrapper tbody");
Sortable.create(tbody, {
// 指定父元素下可被拖拽的子元素
draggable: ".el-table__row",
onEnd({ newIndex, oldIndex }) {
const currRow = tableData.value.splice(oldIndex, 1)[0];
tableData.value.splice(newIndex, 0, currRow);
},
});
};
// 列表 **列拖拽
const colDrop = async () => {
const wrapperTr = document.querySelector(".el-table__header-wrapper tr");
Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: (evt) => {
const empty = 1;
// 跳过显示的列数量如开头我们用了一个多选框h和序号
const oldItem = dynamicColumnList.value[evt.oldIndex - empty];
dynamicColumnList.value.splice(evt.oldIndex - empty, 1);
dynamicColumnList.value.splice(evt.newIndex - empty, 0, oldItem);
// 每一次拖拽后都要重绘一次
reDrawTable();
},
});
};
const copyAnswer = async (copyData) => {
console.log("copyData", copyData);
if (copyData === "") {
ElMessage.warning("请输入文本再复制");
return;
}
try {
await toClipboard(copyData);
ElMessage.success(`复制: ${copyData} 成功!`);
} catch (error) {
ElMessage.warning(`复制失败: ${error} `);
console.error(error);
}
};
/**
* 触发表格重绘
*/
const reDrawTable = () => {
tableKey.value = Math.random();
};
/**
* 页面初始化方法
*/
onMounted(async () => {
let route = useRoute();
let row = route.query;
// await initTableData(row);
await getServerInstanceList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,128 +0,0 @@
<template>
<el-drawer
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<el-table ref="filterTable" :data="tableData" style="width: 100%">
<el-table-column
prop="date"
label="日期"
sortable
width="180"
column-key="date"
:filters="[
{ text: '2016-05-01', value: '2016-05-01' },
{ text: '2016-05-02', value: '2016-05-02' },
{ text: '2016-05-03', value: '2016-05-03' },
{ text: '2016-05-04', value: '2016-05-04' },
]"
:filter-method="filterHandler"
>
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="address" label="地址" :formatter="formatter">
</el-table-column>
<el-table-column
prop="tag"
label="标签"
width="100"
:filters="[
{ text: '家', value: '家' },
{ text: '公司', value: '公司' },
]"
:filter-method="filterTag"
filter-placement="bottom-end"
>
<template v-slot="scope">
<el-tag
:type="scope.row.tag === '家' ? 'primary' : 'success'"
disable-transitions
>{{ scope.row.tag }}</el-tag
>
</template>
</el-table-column>
</el-table>
</el-drawer>
</template>
<script>
export default {
data() {
return {
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
tag: "家",
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
tag: "公司",
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
tag: "家",
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
tag: "公司",
},
],
};
},
methods: {
resetDateFilter() {
this.$refs.filterTable.clearFilter("date");
},
clearFilter() {
this.$refs.filterTable.clearFilter();
},
formatter(row, column) {
console.log(column);
return row.address;
},
filterTag(value, row) {
return row.tag === value;
},
filterHandler(value, row, column) {
const property = column["property"];
return row[property] === value;
},
},
};
</script>
<script setup>
import { defineEmits, defineProps, onMounted, toRefs } from "vue";
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "数据库表文档",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
onMounted(async () => {});
</script>

View File

@@ -1,737 +0,0 @@
<template>
<el-descriptions title="数据库表信息" :column="4" border>
<el-descriptions-item
label="数据库实例"
label-align="right"
align="center"
property="instanceId"
>
<el-select
v-model="instanceId"
@change="changedatabaseInstance"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/> </el-select
></el-descriptions-item>
<el-descriptions-item
label="数据库名"
label-align="right"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-select
clearable
v-model="schemaName"
placeholder="数据库名"
@change="getDataList"
filterable
>
<el-option
v-for="item in schemaNameList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="表名称" label-align="right" align="center">
<el-input
v-model="tableName"
placeholder="tableName"
clearable
></el-input>
</el-descriptions-item>
<el-descriptions-item label="表引擎" label-align="right" align="center">
<el-select v-model="engine" placeholder="表引擎" filterable>
<el-option label="ARCHIVE" value="ARCHIVE" />
<el-option label="BLACKHOLE" value="BLACKHOLE" />
<el-option label="CSV" value="CSV" />
<el-option label="InnoDB" value="InnoDB" />
<el-option label="MEMORY" value="MEMORY" />
<el-option label="MRG_MYISAM" value="MRG_MYISAM" />
<el-option label="MyISAM" value="MyISAM" />
<el-option
label="PERFORMANCE_SCHEMA"
value="PERFORMANCE_SCHEMA"
/>
</el-select>
</el-descriptions-item>
<el-descriptions-item label="表描述" label-align="right" align="center">
<el-input
v-model="tableComment"
placeholder="tableComment"
clearable
></el-input
></el-descriptions-item>
</el-descriptions>
<el-tabs
v-model="activeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane label="字段" name="first">
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<ve-table
:table="{
data: form.tableColumnList,
}"
:rules="rules"
style="width: 100%"
:row-class-name="tableRowClassName"
>
<el-table-column
prop="columnName"
label="字段名称"
sortable
>
<template v-slot:default="{ row }">
<el-input
v-model="row.columnName"
placeholder="columnName"
clearable
></el-input>
</template>
</el-table-column>
<el-table-column prop="dataType" label="类型">
<template v-slot:default="{ row }">
<el-select
v-model="row.dataType"
placeholder="字段类型"
filterable
>
<el-option label="bigint" value="bigint" />
<el-option label="binary" value="binary" />
<el-option label="bit" value="bit" />
<el-option label="blob" value="blob" />
<el-option label="char" value="char" />
<el-option label="date" value="date" />
<el-option label="datetime" value="datetime" />
<el-option label="decimal" value="decimal" />
<el-option label="double" value="double" />
<el-option label="enum" value="enum" />
<el-option label="float" value="float" />
<el-option label="geometry" value="geometry" />
<el-option
label="geometrycollection"
value="geometrycollection"
/>
<el-option label="int" value="int" />
<el-option label="integer" value="integer" />
<el-option label="json" value="json" />
<el-option
label="linestring"
value="linestring"
/>
<el-option label="longblob" value="longblob" />
<el-option label="longtext" value="longtext" />
<el-option
label="mediumblob"
value="mediumblob"
/>
<el-option
label="mediumint"
value="mediumint"
/>
<el-option
label="mediumtext"
value="mediumtext"
/>
<el-option
label="multilinestring"
value="multilinestring"
/>
<el-option
label="multipoint"
value="multipoint"
/>
<el-option
label="multipolygon"
value="multipolygon"
/>
<el-option label="numeric" value="numeric" />
<el-option label="point" value="point" />
<el-option label="polygon" value="polygon" />
<el-option label="real" value="real" />
<el-option label="set" value="set" />
<el-option label="smallint" value="smallint" />
<el-option label="text" value="text" />
<el-option label="time" value="time" />
<el-option
label="timestamp"
value="timestamp"
/>
<el-option label="tinyblob" value="tinyblob" />
<el-option label="tinyint" value="tinyint" />
<el-option label="tinytext" value="tinytext" />
<el-option
label="varbinary"
value="varbinary"
/>
<el-option label="varchar" value="varchar" />
<el-option label="year" value="year" />
</el-select>
</template>
</el-table-column>
<el-table-column
prop="characterMaximumLength"
label="字段长度"
>
<template v-slot:default="{ row }">
<el-input
v-model="row.characterMaximumLength"
placeholder="characterMaximumLength"
clearable
></el-input
></template>
</el-table-column>
<el-table-column
prop="columnType"
label="字段类型"
sortable
>
<template v-slot:default="{ row }">
<el-input
v-model="row.columnType"
placeholder="columnType"
clearable
></el-input>
</template>
</el-table-column>
<el-table-column prop="generationExpression" label="小数点">
<template v-slot:default="{ row }">
<el-input
v-model="row.generationExpression"
placeholder="generationExpression"
clearable
></el-input
></template>
</el-table-column>
<el-table-column prop="isNullable" label="不是null">
<template v-slot:default="{ row }">
<el-select
v-model="row.isNullable"
placeholder="不是null"
>
<el-option label="YES" value="YES" />
<el-option label="NO" value="NO" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="numericPrecision" label="虚拟">
<template v-slot:default="{ row }">
<el-input
v-model="row.numericPrecision"
placeholder="numericPrecision"
clearable
></el-input
></template>
</el-table-column>
<el-table-column prop="numericScale" label="键">
<template v-slot:default="{ row }">
<el-input
v-model="row.numericScale"
placeholder="numericScale"
clearable
></el-input
></template>
</el-table-column>
<el-table-column prop="columnComment" label="描述">
<template v-slot:default="{ row }">
<el-input
v-model="row.columnComment"
placeholder="columnComment"
clearable
></el-input
></template>
</el-table-column>
<template #tool_bar>
<el-button
@click="addColumnItem()"
style="float: right"
type="primary"
>增加</el-button
>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()"
>确定</el-button
>
</template>
<el-table-column fixed="right" label="操作">
<template v-slot="{ $index }">
<el-button
@click="removeColumnItem($index)"
style="float: right"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button></template
>
</el-table-column>
</ve-table>
</el-form>
</el-tab-pane>
<el-tab-pane label="索引" name="second">
<ve-table
:table="{
data: form.tableColumnIndexList,
}"
:rules="rules"
style="width: 100%"
:row-class-name="tableRowClassName"
>
<el-table-column prop="indexName" label="索引名称" sortable>
<template v-slot:default="{ row }">
<el-input
v-model="row.indexName"
placeholder="indexName"
clearable
></el-input>
</template>
</el-table-column>
<el-table-column prop="columnNameList" label="索引字段">
<template v-slot:default="{ row }">
<el-select
v-model="row.columnNameList"
placeholder="索引字段"
filterable
multiple
>
<el-option
v-for="item in form.tableColumnList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="indexType" label="索引类型">
<template v-slot:default="{ row }">
<el-select
v-model="row.indexType"
placeholder="索引类型"
filterable
>
<el-option label="FULLTEXT" value="FULLTEXT" />
<el-option label="NORMAL" value="NORMAL" />
<el-option label="SPATIAL" value="SPATIAL" />
<el-option
label="UNIQUE"
value="UNIQUE"
/> </el-select
></template>
</el-table-column>
<el-table-column prop="indexType" label="索引方法">
<template v-slot:default="{ row }">
<el-select
v-model="row.indexType"
placeholder="索引方法"
filterable
>
<el-option label="BTREE" value="BTREE " />
<el-option label="HASH" value="HASH" /> </el-select
></template>
</el-table-column>
<el-table-column prop="indexComment" label="注释">
<template v-slot:default="{ row }">
<el-input
v-model="row.indexComment"
placeholder="索引注释"
/>
</template>
</el-table-column>
<template #tool_bar>
<el-button
@click="addColumnIndexItem()"
style="float: right"
type="primary"
>增加</el-button
>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()"
>确定</el-button
>
</template>
<el-table-column fixed="right" label="操作">
<template v-slot="{ $index }">
<el-button
@click="removeColumnIndexItem($index)"
style="float: right"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button></template
>
</el-table-column>
</ve-table>
</el-tab-pane>
<!-- <el-tab-pane label="外键" name="third">外键</el-tab-pane>-->
<!-- <el-tab-pane label="触发器" name="fourth">触发器</el-tab-pane>-->
<!-- <el-tab-pane label="选项" name="five">选项</el-tab-pane>-->
<!-- <el-tab-pane label="注释" name="six">注释</el-tab-pane>-->
<!-- <el-tab-pane label="SQL预览" name="seven">SQL预览</el-tab-pane>-->
</el-tabs>
</template>
<script>
export default {
data: () => ({
description: "数据库表字段设置",
buttons: {
del: { name: "删除字段" },
},
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, defineProps, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
const rules = {
instanceId: [
{
required: true,
message: "请选择数据库实例",
trigger: "blur",
},
],
characterSet: [
{
required: true,
message: "请输入字符集",
trigger: "blur",
},
],
sortingRules: [
{
required: true,
message: "请输入排序规则",
trigger: "blur",
},
],
ext: [
{
required: true,
message: "ext",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const { title, rowData } = toRefs(props);
const closeDialog = () => {
// router.go(-1);
router.back();
};
const formRef = ref(null);
const form = reactive({
id: "",
schemaName: "",
instanceName: "",
instanceId: "",
engine: "InnoDB",
autoIncrement: "",
tableComment: "",
tableName: "",
tableCatalog: "",
tableRows: "",
tableCollation: "",
maxDataLength: "",
indexLength: "",
dataLength: "",
avgRowLength: "",
createOptions: "",
checkTime: "",
checksum: "",
dataFree: "",
rowFormat: "",
tableType: "",
createTime: "",
updateTime: "",
version: "",
tableColumnList: ref([]),
tableColumnIndexList: ref([]),
});
const {
id,
schemaName,
instanceName,
instanceId,
engine,
autoIncrement,
tableComment,
tableName,
tableCatalog,
tableRows,
tableCollation,
maxDataLength,
indexLength,
dataLength,
avgRowLength,
createOptions,
checkTime,
checksum,
dataFree,
rowFormat,
tableType,
createTime,
updateTime,
version,
} = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schemaName.value = rowData.value.schemaName),
(id.value = rowData.value.id),
(instanceName.value = rowData.value.instanceName),
(instanceId.value = rowData.value.instanceId),
(engine.value = rowData.value.engine),
(autoIncrement.value = rowData.value.autoIncrement),
(tableComment.value = rowData.value.tableComment),
(tableName.value = rowData.value.tableName),
(tableCatalog.value = rowData.value.tableCatalog),
(tableRows.value = rowData.value.tableRows),
(tableCollation.value = rowData.value.tableCollation),
(maxDataLength.value = rowData.value.maxDataLength),
(indexLength.value = rowData.value.indexLength),
(dataLength.value = rowData.value.dataLength),
(avgRowLength.value = rowData.value.avgRowLength),
(createOptions.value = rowData.value.createOptions),
(checkTime.value = rowData.value.checkTime),
(checksum.value = rowData.value.checksum),
(dataFree.value = rowData.value.dataFree),
(rowFormat.value = rowData.value.rowFormat),
(tableType.value = rowData.value.tableType),
(createTime.value = rowData.value.createTime),
(updateTime.value = rowData.value.updateTime),
(version.value = rowData.value.version));
const schemaNameList = ref(null);
const serverList = ref(null);
const router = useRouter();
const activeName = ref("first");
/**
* 点标签
* @param tab 标签
* @param event 事件
* @returns {Promise<void>}
*/
const handleClick = async (tab, event) => {
console.log(tab, event);
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
let databaseInstance = serverList.value.find(
(item) => item.id === form.instanceId,
);
form.instanceName = databaseInstance.instanceName;
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.tableAdd(form);
} else {
res = await VE_API.system.tableAdd({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
router.go(-1);
}
} else {
console.log("error submit!!");
return false;
}
});
};
// 添加表字段
const addColumnItem = () => {
form.tableColumnList.push({});
};
// 删除字段
const removeColumnItem = (index) => {
// 删除时,我们带两个参数,这个 it 可用可不用,因为我当时只是想看到删除的这个对象的信息,故而带上了; index 是 list 中该对象对应的下标,也是 el-form-item 的项数
// 根据这个 index 下标删除 list 中 的该对象
form.tableColumnList.splice(index, 1);
};
// 添加表索引
const addColumnIndexItem = () => {
form.tableColumnIndexList.push({});
};
// 删除索引
const removeColumnIndexItem = (index) => {
// 删除时,我们带两个参数,这个 it 可用可不用,因为我当时只是想看到删除的这个对象的信息,故而带上了; index 是 list 中该对象对应的下标,也是 el-form-item 的项数
// 根据这个 index 下标删除 list 中 的该对象
form.tableColumnIndexList.splice(index, 1);
};
// 查询数据库实例
const getServerInstanceList = async () => {
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
/**
* 选择数据库实例
* @param serverInstanceId
* @returns {Promise<void>}
*/
const changedatabaseInstance = async (instanceId) => {
if (instanceId == null) {
return;
}
// 查询数据库
let res = await VE_API.system.schemaList({
instanceId,
});
const { code } = res;
if (code === 0) {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaNameList.value = res.data ? res.data : [];
}
};
const initTableData = async (row) => {
let instanceId = row.instanceId;
if (instanceId !== "" && instanceId !== undefined) {
form.schemaName = row.schemaName;
form.instanceId = row.instanceId;
form.instanceName = row.instanceName;
form.engine = row.engine;
form.autoIncrement = row.autoIncrement;
form.tableComment = row.tableComment;
form.tableName = row.tableName;
form.tableCatalog = row.tableCatalog;
form.tableRows = row.tableRows;
form.tableCollation = row.tableCollation;
form.maxDataLength = row.maxDataLength;
form.indexLength = row.indexLength;
form.dataLength = row.dataLength;
form.avgRowLength = row.avgRowLength;
form.createOptions = row.createOptions;
form.checkTime = row.checkTime;
form.checksum = row.checksum;
form.dataFree = row.dataFree;
form.rowFormat = row.rowFormat;
form.tableType = row.tableType;
form.createTime = row.createTime;
form.updateTime = row.updateTime;
form.version = row.version;
// 判断数据库实例
form.instanceId = instanceId;
// 获取当前表选择的数据库实例数据库列表
if (
form.instanceId !== null &&
form.instanceId !== "" &&
form.instanceId !== undefined &&
!isNaN(form.instanceId)
) {
await changedatabaseInstance(form.instanceId);
}
// 查询当前表字段
if (
form.tableName !== null &&
form.tableName !== "" &&
form.tableName !== undefined
) {
await getDatabaseTablesColumnList(
form.instanceId,
form.schemaName,
form.tableName,
);
}
}
};
/**
* 获取当前表对应的字段
* @param tableIds
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async (
instanceId,
schemaName,
tableName,
) => {
let res = await VE_API.system.databaseTableColumnList({
instanceId: instanceId,
schemaName: schemaName,
tableName: tableName,
});
const { code, data } = res;
if (code === 0) {
const { acwTableColumnDTOList, acwTableColumnIndexDTOList } = data;
if (acwTableColumnDTOList && acwTableColumnDTOList.length > 0) {
acwTableColumnDTOList.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
form.tableColumnList = acwTableColumnDTOList
? acwTableColumnDTOList
: [];
form.tableColumnIndexList = acwTableColumnIndexDTOList;
}
}
};
const tableRowClassName = async ({ row, rowIndex }) => {
// 把每一行的索引放进row
row.index = rowIndex;
};
onMounted(async () => {
let route = useRoute();
let row = route.query;
await initTableData(row);
await getServerInstanceList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,293 +0,0 @@
<template>
<el-drawer
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<el-descriptions class="margin-top" :column="3" border title="表详情">
<el-descriptions-item
label="id"
property="id"
class="contentClassName"
>
{{ this.rowData.id }}
</el-descriptions-item>
<el-descriptions-item label="数据库服务器ID">
<el-tag size="small"> {{ this.rowData.instanceId }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="数据库服务器名称">
<el-tag size="small"> {{ this.rowData.instanceName }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="数据库名称">
{{ this.rowData.schemaName }}</el-descriptions-item
>
<el-descriptions-item label="数据库ID">
{{ this.rowData.schemaNameId }}</el-descriptions-item
>
<el-descriptions-item label="表引擎">
{{ this.rowData.engine }}</el-descriptions-item
>
<el-descriptions-item label="表名称">
{{ this.rowData.tableName }}</el-descriptions-item
>
<el-descriptions-item label="表名描述">
{{ this.rowData.tableComment }}</el-descriptions-item
>
</el-descriptions>
<el-descriptions border>
<el-descriptions-item label="表字段">
<span v-for="(item, index) in tableColumnList" :key="index"
>{{ item.columnName }} <el-divider direction="vertical"
/></span>
</el-descriptions-item>
</el-descriptions>
<el-checkbox-group v-model="checkedCities" :min="1" :max="2">
<el-checkbox v-for="city in cities" :key="city" :label="city">{{
city
}}</el-checkbox>
</el-checkbox-group>
<el-timeline>
<el-timeline-item timestamp="实体" placement="top">
<el-card>
<h4>表对应的实体</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaEntity }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="实体对应xml" placement="top">
<el-card>
<h4>实体对应xml</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaMapperXml }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="控制层" placement="top">
<el-card>
<h4>表对应的控制层</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaController }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="业务接口" placement="top">
<el-card>
<h4>表对应的业务接口</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaService }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="业务接口实现" placement="top">
<el-card>
<h4>表对应的业务接口实现</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaServiceImpl }}
</p>
</el-card>
</el-timeline-item>
</el-timeline>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-drawer>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const checkedCities = ref(["swagger"]);
const cities = ["swagger", "mybatis", "lazy", "Shenzhen"];
/**
* private StringBuilder javaController;
private StringBuilder javaEntity;
private StringBuilder javaService;
private StringBuilder javaServiceImpl;
private StringBuilder javaMapper;
private StringBuilder javaMapperXml;
*/
const javaModel = ref({});
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
id: "",
schemaName: "",
schemaNameId: "",
instanceName: "",
instanceId: "",
engine: "",
autoIncrement: "",
tableComment: "",
tableName: "",
tableCatalog: "",
tableRows: "",
tableCollation: "",
maxDataLength: "",
indexLength: "",
dataLength: "",
avgRowLength: "",
createOptions: "",
checkTime: "",
checksum: "",
dataFree: "",
rowFormat: "",
tableType: "",
createTime: "",
updateTime: "",
version: "",
});
const {
id,
schemaName,
schemaNameId,
instanceName,
instanceId,
engine,
autoIncrement,
tableComment,
tableName,
tableCatalog,
tableRows,
tableCollation,
maxDataLength,
indexLength,
dataLength,
avgRowLength,
createOptions,
checkTime,
checksum,
dataFree,
rowFormat,
tableType,
createTime,
updateTime,
version,
} = toRefs(form);
const tableColumnList = ref(null);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schemaName.value = rowData.value.schemaName),
(id.value = rowData.value.id),
(schemaNameId.value = rowData.value.schemaNameId),
(instanceName.value = rowData.value.instanceName),
(instanceId.value = rowData.value.instanceId),
(engine.value = rowData.value.engine),
(autoIncrement.value = rowData.value.autoIncrement),
(tableComment.value = rowData.value.tableComment),
(tableName.value = rowData.value.tableName),
(tableCatalog.value = rowData.value.tableCatalog),
(tableRows.value = rowData.value.tableRows),
(tableCollation.value = rowData.value.tableCollation),
(maxDataLength.value = rowData.value.maxDataLength),
(indexLength.value = rowData.value.indexLength),
(dataLength.value = rowData.value.dataLength),
(avgRowLength.value = rowData.value.avgRowLength),
(createOptions.value = rowData.value.createOptions),
(checkTime.value = rowData.value.checkTime),
(checksum.value = rowData.value.checksum),
(dataFree.value = rowData.value.dataFree),
(rowFormat.value = rowData.value.rowFormat),
(tableType.value = rowData.value.tableType),
(createTime.value = rowData.value.createTime),
(updateTime.value = rowData.value.updateTime),
(version.value = rowData.value.version));
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.schemaAdd(form);
} else {
res = await VE_API.system.schemaEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === "00") {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
/**
* 获取表字段
* @param tableIds
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async (tableIds) => {
let res = await VE_API.system.databaseTablesColumnList({
tableIds,
});
const { code } = res;
if (code === 0) {
res.data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = res.data ? res.data : [];
}
};
onMounted(async () => {
VE_API.system.generateJavaModel({ id: rowData.value.id }).then((res) => {
const { code } = res;
console.log(code);
if (code === 0) {
javaModel.value = res.data;
}
});
await getDatabaseTablesColumnList(rowData.value.id);
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,526 +0,0 @@
<template>
<el-drawer
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<el-form ref="form">
<el-descriptions
class="margin-top"
:column="3"
border
title="表详情"
>
<!-- <el-descriptions-item-->
<!-- label="id"-->
<!-- property="id"-->
<!-- class="contentClassName"-->
<!-- >-->
<!-- {{ this.rowData.id }}-->
<!-- </el-descriptions-item>-->
<el-descriptions-item label="数据库服务器ID">
<el-tag size="small"> {{ this.rowData.instanceId }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="数据库服务器名称">
<el-tag size="small">
{{ this.rowData.instanceName }}</el-tag
>
</el-descriptions-item>
<el-descriptions-item label="数据库名称">
{{ this.rowData.schemaName }}</el-descriptions-item
>
<!-- <el-descriptions-item label="数据库ID">-->
<!-- {{ this.rowData.schemaNameId }}</el-descriptions-item-->
<!-- >-->
<el-descriptions-item label="表引擎">
{{ this.rowData.engine }}</el-descriptions-item
>
<el-descriptions-item label="表名称">
{{ this.rowData.tableName }}</el-descriptions-item
>
<el-descriptions-item label="表名描述">
{{ this.rowData.tableComment }}</el-descriptions-item
>
</el-descriptions>
<el-descriptions border>
<el-descriptions-item label="表字段">
<span v-for="(item, index) in tableColumnList" :key="index"
>{{ item.columnName }} <el-divider direction="vertical"
/></span>
</el-descriptions-item>
<el-descriptions-item label="生成本地Java代码地址">
<el-tree-select
v-model="javaLocalPath"
:data="resourceData"
lazy
:load="loadNode"
:props="resourceProps"
filterable
check-strictly
:render-after-expand="false"
show-checkbox
check-on-click-node
/>
</el-descriptions-item>
</el-descriptions>
<el-form-item>
<el-button
v-permission="['java_code']"
@click.prevent="handleJavaCode(buttons.java_code.name, row)"
type="primary"
size="small"
>
{{ buttons.java_code.name }}
</el-button>
<el-button
v-permission="['export_insert_sql']"
@click.prevent="
exportInsertSql(buttons.export_insert_sql.name, row)
"
type="primary"
size="small"
>
{{ buttons.export_insert_sql.name }}
</el-button>
<el-button
v-permission="['export_upsert_sql']"
@click.prevent="
exportUpsertSql(buttons.export_upsert_sql.name, row)
"
type="primary"
size="small"
>
{{ buttons.export_upsert_sql.name }}
</el-button>
<el-button
v-permission="['export_table_excel']"
@click.prevent="
exporTableExcel(buttons.export_table_excel.name, row)
"
type="primary"
size="small"
>
{{ buttons.export_table_excel.name }}
</el-button>
</el-form-item>
<el-timeline>
<el-timeline-item timestamp="实体" placement="top">
<el-card>
<h4>表对应的实体</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaEntity }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="实体对应xml" placement="top">
<el-card>
<h4>实体对应xml</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaMapperXml }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="控制层" placement="top">
<el-card>
<h4>表对应的控制层</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaController }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="业务接口" placement="top">
<el-card>
<h4>表对应的业务接口</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaService }}
</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="业务接口实现" placement="top">
<el-card>
<h4>表对应的业务接口实现</h4>
<p style="white-space: pre-wrap">
{{ javaModel.javaServiceImpl }}
</p>
</el-card>
</el-timeline-item>
</el-timeline>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()"
>确定</el-button
>
</span>
</template>
</el-form>
</el-drawer>
</template>
<script>
export default {
data: () => ({
description: "数据库表查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加表" },
java_code: { name: "Java代码生成" },
edit: { name: "编辑" },
del: { name: "删除" },
more: { name: "更多" },
export_insert_sql: { name: "导出insert-sql" },
export_upsert_sql: { name: "导出upsert-sql" },
export_table_excel: { name: "导出表结构.excel" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "CopyDocument",
name: "数据库表查询与设置更多",
}),
};
</script>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const javaLocalPath = ref();
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
/**
*
private StringBuilder javaController;
private StringBuilder javaEntity;
private StringBuilder javaService;
private StringBuilder javaServiceImpl;
private StringBuilder javaMapper;
private StringBuilder javaMapperXml;
*/
const javaModel = ref({});
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
id: "",
schemaName: "",
schemaNameId: "",
instanceName: "",
instanceId: "",
engine: "",
autoIncrement: "",
tableComment: "",
tableName: "",
tableCatalog: "",
tableRows: "",
tableCollation: "",
maxDataLength: "",
indexLength: "",
dataLength: "",
avgRowLength: "",
createOptions: "",
checkTime: "",
checksum: "",
dataFree: "",
rowFormat: "",
tableType: "",
createTime: "",
updateTime: "",
version: "",
});
const {
id,
schemaName,
schemaNameId,
instanceName,
instanceId,
engine,
autoIncrement,
tableComment,
tableName,
tableCatalog,
tableRows,
tableCollation,
maxDataLength,
indexLength,
dataLength,
avgRowLength,
createOptions,
checkTime,
checksum,
dataFree,
rowFormat,
tableType,
createTime,
updateTime,
version,
} = toRefs(form);
const tableColumnList = ref(null);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((schemaName.value = rowData.value.schemaName),
(id.value = rowData.value.id),
(schemaNameId.value = rowData.value.schemaNameId),
(instanceName.value = rowData.value.instanceName),
(instanceId.value = rowData.value.instanceId),
(engine.value = rowData.value.engine),
(autoIncrement.value = rowData.value.autoIncrement),
(tableComment.value = rowData.value.tableComment),
(tableName.value = rowData.value.tableName),
(tableCatalog.value = rowData.value.tableCatalog),
(tableRows.value = rowData.value.tableRows),
(tableCollation.value = rowData.value.tableCollation),
(maxDataLength.value = rowData.value.maxDataLength),
(indexLength.value = rowData.value.indexLength),
(dataLength.value = rowData.value.dataLength),
(avgRowLength.value = rowData.value.avgRowLength),
(createOptions.value = rowData.value.createOptions),
(checkTime.value = rowData.value.checkTime),
(checksum.value = rowData.value.checksum),
(dataFree.value = rowData.value.dataFree),
(rowFormat.value = rowData.value.rowFormat),
(tableType.value = rowData.value.tableType),
(createTime.value = rowData.value.createTime),
(updateTime.value = rowData.value.updateTime),
(version.value = rowData.value.version));
/**
* handleJavaCode 事件
* @param title
* @param row
*/
const handleJavaCode = (title, row = rowData.value) => {
// showJavaCodeDialog.value = true;
// dialogTitle.value = title;
rowData.value = row;
VE_API.system
.generateLocalJava({
instanceId: rowData.value.instanceId,
schemaName: rowData.value.schemaName,
tableList: [rowData.value.tableName],
absolutePath: javaLocalPath.value,
})
.then((res) => {
const { code } = res;
if (code === 0) {
console.log(code);
}
});
};
/***
* 导出insert sql
* */
const exportInsertSql = async (title, row = rowData.value) => {
let res = await VE_API.system.tableExportInsertSql(row, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/***
* 导出 upsert sql
* */
const exportUpsertSql = async (title, row = rowData.value) => {
let res = await VE_API.system.tableExportUpsertSql(row, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 导出表结构
* */
const exporTableExcel = async (title, row = rowData.value) => {
let res = await VE_API.system.exportTableStructureExcel(row, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.schemaAdd(form);
} else {
res = await VE_API.system.schemaEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
/**
* 获取表字段
* @returns {Promise<void>}
*/
const getDatabaseTablesColumnList = async () => {
let res = await VE_API.system.databaseTablesColumnList({
instanceId: rowData.value.instanceId,
schemaName: rowData.value.schemaName,
tableName: rowData.value.tableName,
});
const { code } = res;
if (code === 0) {
res.data.map((item) => {
item.label = item.columnName;
item.value = item.columnName;
});
tableColumnList.value = res.data ? res.data : [];
}
};
const resourceData = ref([]);
const params = reactive({
path: "/",
});
const resourceProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const loadNode = async (resourceNode, resolve) => {
if (resourceNode.level === 0) {
return resolve([]);
}
resourceNode.loaded = true;
var resourceNodeData = resourceNode.data;
if (resourceNodeData.isFile) {
return resolve([]);
}
console.log(resourceNodeData);
const { code, data } = await VE_API.system.playFileResourceList({
path:
"/" === resourceNodeData.rootPath
? "/" + resourceNodeData.name
: resourceNodeData.rootPath + "/" + resourceNodeData.name,
});
if (code === 0) {
if (data == null) {
return resolve([]);
}
data.map((item) => {
item.value = item.absolutePath;
});
// resourceNode.childNodes = data;
console.log(resourceNode);
return resolve(data);
}
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getFileList = async () => {
const { code, data } = await VE_API.system.playFileResourceList(params);
if (code === 0) {
data.map((item) => {
item.value = item.absolutePath;
});
resourceData.value = data;
}
};
onMounted(async () => {
await getFileList();
VE_API.system
.generateJavaModel({
instanceId: rowData.value.instanceId,
schemaName: rowData.value.schemaName,
tableName: rowData.value.tableName,
})
.then((res) => {
const { code } = res;
console.log(code);
if (code === 0) {
javaModel.value = res.data;
}
});
await getDatabaseTablesColumnList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,214 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="projectName"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
clearable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="项目拥有者" prop="owner">
<el-input v-model="owner" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="项目版本" prop="version">
<el-input v-model="version" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="ORM框架" prop="ormFrameEnums">
<el-select
v-model="ormFrameEnums"
placeholder="ORM框架"
clearable
>
<el-option label="Lazy" value="UPSERT" />
<el-option label="mybatis" value="MYBATIS" />
<el-option label="JPA" value="JPA" />
</el-select>
</el-form-item>
<el-form-item label="UI框架" prop="uiFrameEnums">
<el-select
v-model="uiFrameEnums"
placeholder="UI框架"
clearable
>
<el-option label="VUE" value="VUE" />
</el-select>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
projectName: [
{
required: true,
message: "请输入服务器名称",
trigger: "blur",
},
],
instanceId: [
{
required: true,
message: "请选择数据库服务器",
trigger: "blur",
},
],
version: [
{
required: true,
message: "请输入项目版本",
trigger: "blur",
},
],
ormFrameEnums: [
{
required: true,
message: "请选择ORM框架",
trigger: "change",
},
],
owner: [
{
required: true,
message: "请输入项目拥有者",
trigger: "change",
},
],
uiFrameEnums: [
{
required: true,
message: "请输入项目UI框架",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
projectName: "",
instanceId: "",
version: "",
ormFrameEnums: "",
uiFrameEnums: "",
owner: "",
});
const { projectName, instanceId, version, ormFrameEnums, uiFrameEnums, owner } =
toRefs(form);
const serverList = ref(null);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((projectName.value = rowData.value.projectName),
(instanceId.value = rowData.value.instanceId),
(version.value = rowData.value.version),
(ormFrameEnums.value = rowData.value.ormFrameEnums),
(owner.value = rowData.value.owner),
(uiFrameEnums.value = rowData.value.uiFrameEnums));
onMounted(async () => {
// 查询数据库实例
let res = await VE_API.system.databaseInstanceList();
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
serverList.value = res.data ? res.data : [];
});
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value == "添加") {
res = await VE_API.system.projectAdd(form);
} else {
res = await VE_API.system.projectEdit({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code == "00") {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,198 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="120px"
:inline="false"
>
<el-form-item label="服务器名称" prop="instanceName">
<el-input
v-model="instanceName"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input
v-model="username"
placeholder="root"
clearable
></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="password"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="host" prop="host">
<el-input
v-model="host"
placeholder="127.0.0.1"
clearable
></el-input>
</el-form-item>
<el-form-item label="端口" prop="port">
<el-input
v-model="port"
placeholder="6379"
clearable
></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-input v-model="status" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="sort" placeholder="" clearable></el-input>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button style="float: left" @click="testConnection()"
>测试连接</el-button
>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, toRefs, ref, defineProps, defineEmits } from "vue";
const rules = {
instanceName: [
{
required: true,
message: "请输入服务器名称",
trigger: "blur",
},
],
username: [
{
required: true,
message: "请输入账户",
trigger: "blur",
},
],
host: [
{
required: true,
message: "host不能为空",
trigger: "change",
},
],
port: [
{
required: true,
message: "端口不能为空",
trigger: "change",
},
],
driverClassName: [
{
required: true,
message: "driverClassName",
trigger: "change",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
instanceName: "",
username: "root",
password: "",
host: "127.0.0.1",
port: 6379,
status: "",
sort: 1,
});
const { instanceName, username, password, host, port, status, sort } =
toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((instanceName.value = rowData.value.instanceName),
(username.value = rowData.value.username),
(password.value = rowData.value.password),
(host.value = rowData.value.host),
(port.value = rowData.value.port),
(status.value = rowData.value.status),
(sort.value = rowData.value.sort));
/**
* 测试连接
*/
const testConnection = async () => {
let res = await VE_API.system.redisInstanceTest(form);
const { code } = res;
if (code === 0) {
console.log("连接成功");
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加Redis实例") {
res = await VE_API.system.redisInstanceStory(form);
} else {
res = await VE_API.system.redisInstanceStory({
id: rowData.value.id,
...form,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,8 +0,0 @@
const acwClientMenu = {
description: "自动生成代码客户端管理",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Lollipop",
name: "自动生成代码客户端管理",
};
export default acwClientMenu;

View File

@@ -1,281 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="接口分组" prop="interfaceGroup">
<el-input
clearable
v-model="interfaceGroup"
placeholder="接口分组"
></el-input>
</el-form-item>
<el-form-item label="接口描述" prop="apiComment">
<el-input
clearable
v-model="apiComment"
placeholder="接口描述"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="apiId" label="接口ID"></el-table-column>
<el-table-column
prop="apiComment"
label="接口注释"
></el-table-column>
<el-table-column prop="apiPath" label="拦截路径"></el-table-column>
<el-table-column
prop="apiMethod"
label="HttpMethod"
></el-table-column>
<el-table-column prop="apiResultType" label="api返回结果类型">
<template v-slot="scope">
<el-select
v-model="scope.row.apiResultType"
placeholder="api返回结果类型"
filterable
:disabled="true"
>
<el-option label="单个对象" :value="0" />
<el-option label="集合对象" :value="1" />
<el-option label="分页对象" :value="2" />
<el-option label="空" :value="3" />
</el-select>
</template>
</el-table-column>
<el-table-column
prop="executeType"
label="执行类型"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.apiId)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['info']"
@click.prevent="handleInfo('详情', row)"
type="primary"
size="small"
>
{{ buttons.info.name }}
</el-button>
<el-button
v-permission="['deriveCode']"
@click.prevent="deriveCode(row)"
type="primary"
size="small"
>
{{ buttons.deriveCode.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<client-api-factory-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
<!-- 编辑组件 -->
<client-api-factory-edit
v-if="showInfo"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showInfo"
@closeDialog="handelInfo($event)"
/>
</div>
</template>
<script>
import acwClientMenu from "@/views/layoutpages/acw_client/AcwClientMenu";
export default {
data: () => ({
description: "客户端API工厂",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
deriveCode: { name: "衍生代码" },
info: { name: "详情" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Lollipop",
name: "客户端API工厂",
parentMenu: acwClientMenu,
}),
};
</script>
<script setup>
import ClientApiFactoryEdit from "@/views/layoutpages/acw_client/components/ClientApiFactoryEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showInfo = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
interfaceGroup: "",
apiComment: "",
size: 10,
current: 1,
total: 0,
});
const { interfaceGroup, apiComment, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.clientApiDelete({ apiId: id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* 衍生代码
* @param row 行信息
*/
const deriveCode = (row) => {
const { code } = VE_API.system.clientApiDerivativeCode({
apiId: row.apiId,
webArchitecture: "DDD_ARCHITECTURE",
ormArchitecture: "LAZY",
});
if (code === 0) {
getDataList();
}
};
/**
* 行信息
*/
const handleInfo = (title, row = null) => {
showInfo.value = true;
dialogTitle.value = title;
rowData.value = row;
};
const handelInfo = (e) => {
showInfo.value = e;
getDataList();
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.clientApiPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,400 +0,0 @@
<template>
<div>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="instanceId"
placeholder="数据库实例"
filterable
@change="(val) => getSchemaList(val)"
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库库名" prop="schema">
<el-select
v-model="schema"
filterable
placeholder="数据库实例"
@change="getTableList"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="表名称" prop="tableList">
<el-select
v-model="tableList"
placeholder="表名称"
filterable
multiple
>
<el-option
v-for="item in schemaTableList"
:key="item.value"
:label="item.label"
:value="item.value"
>
<span style="float: left">{{ item.label }}</span>
<span
style="
float: right;
color: var(--el-text-color-secondary);
font-size: 13px;
"
>{{ item.tableComment }}</span
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="客户端地址" prop="clientId">
<el-select
v-model="clientId"
placeholder="客户端地址"
filterable
@change="(val) => getClientInstanceAlwaysUserPathList(val)"
>
<el-option
v-for="item in clientList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="文件地址" prop="absolutePath">
<el-select
v-model="absolutePath"
placeholder="文件地址"
filterable
clearable
allow-create
>
<el-option
v-for="item in clientJavaPathList"
:key="item.value"
:label="item.absolutePath"
:value="item.absolutePath"
>
<el-row>
<el-col :span="12">
<span style="float: left">{{
item.absolutePath
}}</span>
</el-col>
<el-col :span="12">
<span
style="
float: right;
color: #8492a6;
font-size: 13px;
"
>
使用的数据库 {{ item.schemaName }}
</span>
</el-col>
</el-row>
</el-option>
</el-select>
<!-- <el-input-->
<!-- v-model="absolutePath"-->
<!-- placeholder="/Users/wujiawei/IdeaProjects/wu-framework-parent/wu-freamwork-test"-->
<!-- clearable-->
<!-- ></el-input>-->
</el-form-item>
<el-form-item label="文件前缀" prop="prefix">
<el-input v-model="prefix" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="架构" prop="webArchitecture">
<el-select
v-model="webArchitecture"
placeholder="架构"
filterable
>
<el-option label="DDD" value="DDD_ARCHITECTURE" />
<el-option label="WEB_MVC" value="WEB_MVC" />
<el-option label="FEIGN" value="FEIGN_API" />
</el-select>
</el-form-item>
<el-form-item label="ORM" prop="ormArchitecture">
<el-select
v-model="ormArchitecture"
placeholder="ORM"
filterable
>
<el-option label="MYBATIS" value="MYBATIS" />
<el-option label="LAZY" value="LAZY" />
</el-select>
</el-form-item>
<el-form-item label="包名称" prop="packageName">
<el-select
v-model="packageName"
placeholder="com.alimama.demo"
filterable
clearable
allow-create
>
<el-option
v-for="item in clientJavaPathList"
:key="item.value"
:label="item.packageName"
:value="item.packageName"
>
<el-row>
<el-col :span="12">
<span style="float: left">{{
item.packageName
}}</span>
</el-col>
<el-col :span="12">
<span
style="
float: right;
color: #8492a6;
font-size: 13px;
"
>
使用的数据库 {{ item.schemaName }}
</span>
</el-col>
</el-row>
</el-option>
</el-select>
</el-form-item>
</el-form>
<span>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</div>
</template>
<script>
import acwClientMenu from "@/views/layoutpages/acw_client/AcwClientMenu";
export default {
data: () => ({
description: "客户端生成code工厂",
buttons: {
generate: { name: "生成代码" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "HotWater",
name: "客户端生成code工厂",
parentMenu: acwClientMenu,
}),
};
</script>
<script setup>
//?导入公共查询方法
import { onMounted, reactive, ref, toRefs } from "vue";
const rules = {
instanceId: [
{
required: true,
message: "请输入数据库服务器",
trigger: "blur",
},
],
schema: [
{
required: true,
message: "请选择数据库库名",
trigger: "blur",
},
],
tableList: [
{
required: true,
message: "请选择数据库表",
trigger: "blur",
},
],
clientId: [
{
required: true,
message: "请选择客户端",
trigger: "blur",
},
],
absolutePath: [
{
required: true,
message: "请输入文件输出地址",
trigger: "blur",
},
],
packageName: [
{
required: true,
message: "请输入项目包名",
trigger: "blur",
},
],
};
const formRef = ref(null);
const form = reactive({
schema: "",
instanceId: "",
tableList: [],
clientId: "",
absolutePath: "",
prefix: "",
webArchitecture: "DDD_ARCHITECTURE",
ormArchitecture: "LAZY",
packageName: "",
});
const {
schema,
instanceId,
tableList,
clientId,
absolutePath,
prefix,
webArchitecture,
ormArchitecture,
packageName,
} = toRefs(form);
const serverList = ref([]);
const schemaList = ref([]);
const schemaTableList = ref([]);
const clientList = ref([]);
const clientJavaPathList = ref([]);
onMounted(async () => {
getInstanceList();
getClientInstanceList();
});
/**
* 获取实例上的表
*/
const getTableList = () => {
// 查询数据表信息
VE_API.system
.tableList({
instanceId: instanceId.value,
schemaName: schema.value,
})
.then((res) => {
if (res.data) {
res.data.map((item) => {
item.label = item.tableName;
item.value = item.tableName;
});
schemaTableList.value = res.data ? res.data : [];
}
});
};
/**
* 获取数据库实例
*/
const getInstanceList = () => {
// 查询数据库实例
VE_API.system.databaseInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.instanceName;
item.value = item.id;
});
serverList.value = res.data ? res.data : [];
});
};
const getSchemaList = (databaseInstance = null) => {
console.log(databaseInstance);
// 查询数据schema信息
VE_API.system
.schemaList({
instanceId: instanceId.value,
})
.then((res) => {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
});
schemaList.value = res.data ? res.data : [];
});
};
/**
* 获取客户端实例
*/
const getClientInstanceList = () => {
// 获取客户端实例
VE_API.system.clientInstanceList().then((res) => {
res.data.map((item) => {
item.label = item.clientId;
item.value = item.clientId;
});
clientList.value = res.data ? res.data : [];
});
};
/**
* 获取客户端常用路径
*/
const getClientInstanceAlwaysUserPathList = (clientId) => {
VE_API.system.clientJavaPathList({ clientId: clientId }).then((res) => {
if (res.code === 0 && res.data) {
res.data.map((item) => {
item.label = item.absolutePath;
item.value = item.absolutePath;
});
clientJavaPathList.value = res.data ? res.data : [];
}
});
};
/**
* @description:提交
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
console.log(form);
res = VE_API.system.clientGenerateLocalJava({
instanceId: form.instanceId,
schemaName: form.schema,
tableList: form.tableList,
absolutePath: form.absolutePath,
packageName: form.packageName,
webArchitecture: form.webArchitecture,
prefix: form.prefix,
ormArchitecture: form.ormArchitecture,
clientId: form.clientId,
});
const { code } = res;
if (code === 0) {
console.log(res);
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,169 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="客户端名称" prop="clientId">
<el-input
clearable
v-model="clientId"
placeholder="客户端名称"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="ip" label="地址"></el-table-column>
<el-table-column
prop="clientId"
label="客户端名称"
></el-table-column>
<el-table-column prop="port" label="端口"></el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['info']"
@click.prevent="handleInfo('详情', row)"
type="primary"
size="small"
>
{{ buttons.info.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
</div>
</template>
<script>
import acwClientRegisterMenu from "@/views/layoutpages/acw_server/AcwClientRegisterMenu";
export default {
data: () => ({
description: "注册中心",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
info: { name: "详情" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Opportunity",
name: "注册中心",
parentMenu: acwClientRegisterMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const showInfo = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
clientId: "",
size: 10,
current: 1,
total: 0,
});
const { clientId, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* 行信息
*/
const handleInfo = (title, row = null) => {
showInfo.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.clientInstancePage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,8 +0,0 @@
const acwClientRegisterMenu = {
description: "注册中心",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Opportunity",
name: "注册中心",
};
export default acwClientRegisterMenu;

View File

@@ -1,224 +0,0 @@
<template>
<div class="ve_container">
<!-- <el-descriptions border>-->
<!-- <el-descriptions-item label="实例名称"-->
<!-- >实例名称-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例数据库数量"-->
<!-- >实例数据库数量-->
<!-- </el-descriptions-item>-->
<!-- <el-descriptions-item label="实例表数量"-->
<!-- >实例表数量-->
<!-- </el-descriptions-item>-->
<!-- </el-descriptions>-->
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="数据库实例" prop="instanceId">
<el-select
v-model="params.instanceId"
@change="getSchemaList"
placeholder="数据库实例"
filterable
>
<el-option
v-for="item in serverList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据库名" prop="schemaName">
<el-select
clearable
filterable
@change="getDataList"
v-model="params.schemaName"
placeholder="数据库名"
>
<el-option
v-for="item in schemaList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="id" label="自动化ID"></el-table-column>
<el-table-column prop="name" label="自动化名称"></el-table-column>
<el-table-column
prop="timeInterval"
label="处理时间间隔(空不定时处理)"
></el-table-column>
<el-table-column prop="status" label="状态"></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="更新时间"
></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
</div>
</template>
<script>
import automationMenu from "@/views/layoutpages/automation/AutomationMenu";
export default {
data: () => ({
description: "自动化配置",
buttons: {
search: { name: "查询" },
edit: { name: "编辑" },
del: { name: "删除" },
add: { name: "新增自动化配置" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "PictureRounded",
name: "自动化配置",
parentMenu: automationMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted } from "vue";
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
getAsyncRouteName,
} from "@/views/layoutpages/common";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
instanceId: "",
// status: 1,
schemaName: "",
size: 10,
current: 1,
total: 0,
});
const { size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = async (title, row = null) => {
let path = "automation/components/AutomationEdit";
const toName = await getAsyncRouteName(title, path, "add", {
router,
route,
});
if (row) {
console.log(row);
await router.push({ name: toName, query: { id: row.id } });
} else {
await router.push({ name: toName, query: {} });
}
};
/**
* 删除
* @param id
*/
const handleDel = async (id) => {
const { code } = await VE_API.system.automationRemove({ id });
if (code === 0) {
getDataList();
}
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.automationFindPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,8 +0,0 @@
const automationMenu = {
description: "自动化管理平台",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "DataLine",
name: "自动化管理平台",
};
export default automationMenu;

View File

@@ -1,567 +0,0 @@
<template>
<!-- 表单 -->
<div>
<el-button @click="automationEditData.showWhat = 'info'"
>基础信息</el-button
>
<el-button @click="automationEditData.showWhat = 'node'"
>自动化节点</el-button
>
</div>
<!--自动化信息-->
<div v-if="automationEditData.showWhat === 'info'">
<el-form
:model="automationEditData.automation"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="自动化名称" prop="name">
<el-input
v-model="automationEditData.automation.name"
placeholder="自动化名称"
clearable
></el-input>
</el-form-item>
<el-form-item
label="处理时间间隔(空不定时处理)"
prop="timeInterval"
>
<el-input
v-model="automationEditData.automation.timeInterval"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch
:loading="automationEditData.automation.status"
v-model="status"
:active-value="1"
:inactive-value="0"
active-color="#13ce66"
inactive-color="#ff4949"
>
</el-switch>
</el-form-item>
</el-form>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmitAutomation()"
>确定</el-button
>
</span>
</div>
<!--node 列表-->
<div v-if="automationEditData.showWhat === 'node'">
<div style="height: 300px">
<el-steps direction="vertical" :active="1">
<el-step title="开始节点" :icon="Picture" />
<el-step
v-for="node in automationEditData.automation
.automationNodeList"
:key="node.value"
:label="node.label"
:value="node.value"
:title="node.name"
@click="clickNode(node)"
></el-step>
<el-step title="添加" :icon="Edit" @click="addNode">
<el-image
:src="require('../../../../static/redis.png')"
style="height: 100%"
></el-image>
</el-step>
<el-step title="结束节点" :icon="Upload" />
</el-steps>
</div>
</div>
<!-- node 节点详情、动作 -->
<el-drawer
v-model="automationEditData.node.drawer"
title="I am the title"
:with-header="false"
>
<!--node节点详情-->
<!--node 动作-->
<div>
<el-button @click="automationEditData.showNodeOrAction = 'node'"
>节点信息</el-button
>
<el-button @click="automationEditData.showNodeOrAction = 'action'"
>节点动作</el-button
>
<!-- 节点信息 -->
<div v-if="automationEditData.showNodeOrAction === 'node'">
<el-form
:model="automationEditData.currentNode"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="节点名称" prop="name">
<el-input
v-model="automationEditData.currentNode.name"
placeholder="节点名称"
clearable
></el-input>
</el-form-item>
<el-form-item label="节点排序" prop="sort">
<el-input
v-model="automationEditData.currentNode.sort"
placeholder="节点排序"
clearable
></el-input>
</el-form-item>
<el-form-item label="节点类型" prop="type">
<el-switch
v-model="automationEditData.currentNode.type"
:active-value="1"
:inactive-value="0"
active-color="#13ce66"
inactive-color="#ff4949"
>
</el-switch>
</el-form-item>
</el-form>
<span>
<el-button @click="removeAutomationNode()"
>删除节点</el-button
>
<el-button type="primary" @click="onSubmitAutomationNode()"
>确定</el-button
>
</span>
</div>
<!-- 节点动作 -->
<div v-if="automationEditData.showNodeOrAction === 'action'">
<el-form
:model="automationEditData.currentAction"
label-width="80px"
:inline="false"
>
<el-form-item
label="动作类型"
prop="automationNodeActionType"
>
<el-select
v-model="
automationEditData.currentAction
.automationNodeActionType
"
placeholder=""
clearable
>
<el-option label="HTTP" value="HTTP" />
</el-select>
</el-form-item>
<el-form-item label="请求方式" prop="httpMethod">
<el-select
v-model="
automationEditData.currentAction.httpMethod
"
placeholder=""
clearable
>
<el-option label="GET" value="GET" />
<el-option label="HEAD" value="HEAD" />
<el-option label="POST" value="POST" />
<el-option label="PUT" value="PUT" />
<el-option label="PATCH" value="PATCH" />
<el-option label="DELETE" value="DELETE" />
<el-option label="OPTIONS" value="OPTIONS" />
<el-option label="TRACE" value="TRACE" />
</el-select>
</el-form-item>
<el-form-item label="地址" prop="url">
<el-input
v-model="automationEditData.currentAction.url"
placeholder=""
clearable
></el-input>
</el-form-item>
<div>
<span>请求参数</span>
<el-button
@click="
addRequestParams(
automationEditData.currentAction,
)
"
style="float: right"
type="primary"
>增加
</el-button>
<el-empty
v-show="
automationEditData.currentAction.paramList
.length === 0
"
></el-empty>
<el-row
v-show="automationEditData.currentAction.paramList"
v-for="(item, index) in automationEditData
.currentAction.paramList"
:key="index"
>
<span>key</span>
<el-input
v-model="item.key"
placeholder=""
clearable
></el-input>
<el-input
v-model="item.val"
placeholder=""
clearable
></el-input>
</el-row>
</div>
<el-form-item label="请求体" prop="body">
<el-input
v-model="automationEditData.currentAction.body"
placeholder=""
clearable
></el-input>
</el-form-item>
<div>
<span>请求头</span>
<el-button
@click="addRequestHeader()"
style="float: right"
type="primary"
>增加
</el-button>
<el-empty
v-show="
automationEditData.currentAction.headerList
.length === 0
"
></el-empty>
<el-row
v-show="automationEditData.currentAction.headerList"
v-for="(item, index) in automationEditData
.currentAction.headerList"
:key="index"
>
<span>key</span>
<el-input
v-model="item.key"
placeholder=""
clearable
></el-input>
<el-input
v-model="item.val"
placeholder=""
clearable
></el-input>
</el-row>
</div>
</el-form>
<el-row>
<span>
返回结果
{{ automationEditData.currentAction.result }}</span
>
</el-row>
<span>
<el-button @click="removeAutomationNodeAction()"
>删除节点动作</el-button
>
<el-button
type="primary"
@click="onSubmitAutomationNodeAction()"
>提交节点动作</el-button
>
<el-button
v-show="automationEditData.currentAction.id"
type="primary"
@click="executeAutomationNodeAction()"
>执行动作</el-button
>
</span>
</div>
</div>
</el-drawer>
</template>
<script setup>
import { toRefs, onMounted, ref, defineProps, defineEmits } from "vue";
import { useRoute } from "vue-router";
import { Edit, Picture, Upload } from "@element-plus/icons-vue";
const rules = {
name: [
{
required: true,
message: "请输入名称",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const formRef = ref(null);
const closeDialog = () => {
emit("closeDialog", false);
};
const automationEditData = ref({
showWhat: "info",
automation: {},
nodeList: [],
node: { drawer: false },
showNodeOrAction: "node",
currentNode: {},
currentAction: {
id: "",
paramList: [],
params: {},
headerList: [],
headers: {},
result: "",
},
});
/**
* 添加header
*/
const addRequestHeader = () => {
if (automationEditData.value.currentAction.headerList) {
automationEditData.value.currentAction.headerList.push({});
} else {
automationEditData.value.currentAction.paraheaderListmList = [];
}
};
/**
* 添加参数
*/
const addRequestParams = () => {
console.log(automationEditData.value);
if (automationEditData.value.currentAction.paramList) {
automationEditData.value.currentAction.paramList.push({});
} else {
automationEditData.value.currentAction.paramList = [];
}
};
/**
* 执行节点动作
*/
const executeAutomationNodeAction = async () => {
const { code, data } =
await VE_API.system.automationNodeHttpActionExecuteOne({
actionId: automationEditData.value.currentAction.id,
});
if (code === 0) {
automationEditData.value.currentAction.result = data;
console.log(data);
}
};
/**
* 删除动作节点
* @returns {Promise<void>}
*/
const removeAutomationNodeAction = async () => {
const { code } = await VE_API.system.automationNodeHttpActionRemove({
id: automationEditData.value.currentAction.id,
});
if (code === 0) {
await findAutomationById(automationEditData.value.automation.id);
}
};
/**
* 新增或者修改节点动作
*/
const onSubmitAutomationNodeAction = async () => {
automationEditData.value.currentAction.automationNodeId =
automationEditData.value.currentNode.id;
for (let item of automationEditData.value.currentAction.paramList) {
console.log(item.val);
automationEditData.value.currentAction.params[item.key] = item.val;
}
for (let item of automationEditData.value.currentAction.headerList) {
automationEditData.value.currentAction.headers[item.key] = item.val;
}
const { code } = await VE_API.system.automationNodeHttpActionStory(
automationEditData.value.currentAction,
);
if (code === 0) {
await findAutomationById(automationEditData.value.automation.id);
}
};
/**
* 删除节点
*/
const removeAutomationNode = async () => {
const { code } = await VE_API.system.automationNodeRemove({
id: automationEditData.value.currentNode.id,
});
if (code === 0) {
await findAutomationById(automationEditData.value.automation.id);
}
};
/**
* 保存自动化节点
*/
const onSubmitAutomationNode = async () => {
const { code } = await VE_API.system.automationNodeStory(
automationEditData.value.currentNode,
);
if (code === 0) {
await findAutomationById(automationEditData.value.automation.id);
}
};
/**
* 点击node
* @param node
*/
const clickNode = (node) => {
console.log(node);
automationEditData.value.node.drawer = true;
automationEditData.value.currentNode = node;
if (node && node.automationNodeHttpAction) {
automationEditData.value.currentAction = node.automationNodeHttpAction;
// 请求参数转换
automationEditData.value.currentAction.paramList = [];
if (node.automationNodeHttpAction.params) {
console.log(node.automationNodeHttpAction.params);
Object.keys(node.automationNodeHttpAction.params).forEach((key) => {
automationEditData.value.currentAction.paramList.push({
key: key,
val: node.automationNodeHttpAction.params[key],
});
});
} else {
automationEditData.value.currentAction.params = {};
}
// 请求头转换
automationEditData.value.currentAction.headerList = [];
if (node.automationNodeHttpAction.headers) {
Object.keys(node.automationNodeHttpAction.headers).forEach(
(key) => {
automationEditData.value.currentAction.headerList.push({
key: key,
val: node.automationNodeHttpAction.headers[key],
});
},
);
} else {
automationEditData.value.currentAction.headers = {};
}
} else {
automationEditData.value.currentAction = {
automationNodeId: automationEditData.value.currentNode.id,
paramList: [],
headerList: [],
params: {},
headers: {},
};
}
console.log(automationEditData.value);
};
/**
* 添加节点
*/
const addNode = async () => {
let automationNode = {
automationId: automationEditData.value.automation.id,
actionType: "HTTP",
status: "0",
name: "节点",
};
// 添加节点
const { code } = await VE_API.system.automationNodeStory(automationNode);
if (code === 0) {
await findAutomationById(automationEditData.value.automation.id);
}
};
const findAutomationById = async (id) => {
const { code, data } = await VE_API.system.automationFindOne({ id: id });
if (code === 0) {
automationEditData.value.automation = data;
console.log(data);
}
};
onMounted(async () => {
let route = useRoute();
let id = route.query.id;
if (id) {
console.log(id);
await findAutomationById(id);
}
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmitAutomation = async () => {
formRef.value.validate(async (valid) => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.automationStory(
automationEditData.value.automation,
);
} else {
res = await VE_API.system.automationStory({
id: rowData.value.id,
...automationEditData.value.automation,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
}
});
};
</script>
<style lang="scss" scoped>
.el-row {
margin-bottom: 20px;
}
.el-row:last-child {
margin-bottom: 0;
}
.el-col {
border-radius: 4px;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
</style>

View File

@@ -2,11 +2,11 @@
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="汉字" prop="word">
<el-form-item label="客户端ID" prop="clientId">
<el-input
clearable
v-model="word"
placeholder="汉字"
v-model="clientId"
placeholder="客户端ID"
></el-input>
</el-form-item>
<el-form-item>
@@ -39,6 +39,7 @@
>
<template #tool_bar>
<el-button
title="弹窗式"
v-permission="['add']"
size="small"
type="primary"
@@ -47,32 +48,16 @@
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="word" label="汉字"></el-table-column>
<el-table-column prop="pinYin" label="拼音"></el-table-column>
<el-table-column prop="strokes" label="笔划"></el-table-column>
<el-table-column prop="radicals" label="部首"></el-table-column>
<el-table-column prop="oldWord" label="繁体字"></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="修改时间"
></el-table-column>
<el-table-column prop="clientId" label="客户端ID"></el-table-column>
<el-table-column prop="onLineState" label="客户端在线状态">
</el-table-column>
<el-table-column prop="stagingState" label="暂存状态">
</el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
@click.prevent="handleDel(row.clientId)"
type="danger"
size="small"
>
@@ -81,40 +66,31 @@
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<tts-chinese-characters-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import ttsMenu from "@/views/layoutpages/tts/TtsMenu";
import cloudNetworkMenu from "@/views/layoutpages/cloud_network/components/CloudNetworkMenu";
export default {
data: () => ({
description: "TTS汉字管理",
description: "客户端注册信息查询",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
export: { name: "导出用户" },
},
// type 0: 1 2
type: "1",
icon: "HelpFilled",
name: "TTS汉字管理",
parentMenu: ttsMenu,
icon: "Avatar",
name: "客户端注册信息查询",
parentMenu: cloudNetworkMenu,
}),
};
</script>
<script setup>
import TtsChineseCharactersEdit from "./components/TtsChineseCharactersEdit.vue";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?
import {
@@ -125,45 +101,22 @@ import {
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
word: "",
clientId: "",
size: 10,
current: 1,
total: 0,
});
const { word, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @return {*}
* @param title
* @param row
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
const { clientId, size, current, total } = toRefs(params);
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
const handleDel = (clientId) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
@@ -171,10 +124,10 @@ const handleDel = (id) => {
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.ttsChineseCharactersRemove({
id: id,
const { code } = await VE_API.cloudNetwork.cloudClientDelete({
clientId,
});
if (code === 0) {
if (code == "00") {
getDataList();
}
})
@@ -192,7 +145,7 @@ const handleDel = (id) => {
*/
const getDataList = async () => {
const { code, data } =
await VE_API.system.ttsChineseCharactersFindPage(params);
await VE_API.cloudNetwork.cloudClientFindPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
@@ -203,6 +156,7 @@ const getDataList = async () => {
};
onMounted(async () => {
await getDataList();
// maxHeight(pagination, queryForm, toolBar, ve_max_height);
});
</script>

View File

@@ -2,11 +2,11 @@
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="应用名" prop="applicationName">
<el-form-item label="客户端ID" prop="clientId">
<el-input
clearable
v-model="applicationName"
placeholder="应用名"
v-model="clientId"
placeholder="客户端ID"
></el-input>
</el-form-item>
<el-form-item>
@@ -39,6 +39,7 @@
>
<template #tool_bar>
<el-button
title="弹窗式"
v-permission="['add']"
size="small"
type="primary"
@@ -47,18 +48,18 @@
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column
prop="projectName"
label="项目名"
></el-table-column>
<el-table-column
prop="applicationName"
label="应用名"
></el-table-column>
<el-table-column
prop="schemaName"
label="数据库名称"
></el-table-column>
<el-table-column prop="clientId" label="客户端ID"></el-table-column>
<el-table-column prop="clientTargetIp" label="客户端目标地址">
</el-table-column>
<el-table-column prop="clientTargetPort" label="客户端目标端口">
</el-table-column>
<el-table-column prop="visitorPort" label="访问端口">
</el-table-column>
<el-table-column prop="describe" label="描述"> </el-table-column>
<el-table-column prop="createTime" label="创建时间">
</el-table-column>
<el-table-column prop="updateTime" label="修改时间">
</el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
@@ -71,7 +72,7 @@
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.applicationId)"
@click.prevent="handleDel(row.visitorPort)"
type="danger"
size="small"
>
@@ -80,9 +81,8 @@
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<application-edit
<netWorkMapping-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
@@ -92,28 +92,28 @@
</div>
</template>
<script>
import acwMenu from "@/views/layoutpages/acw/AcwMenu";
import cloudNetworkMenu from "@/views/layoutpages/cloud_network/components/CloudNetworkMenu";
export default {
data: () => ({
description: "acw应用查询与设置",
description: "网络映射管理",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
export: { name: "导出用户" },
},
// type 0: 1 2
type: "1",
icon: "Histogram",
name: "ACW应用管理",
parentMenu: acwMenu,
icon: "Avatar",
name: "网络映射管理",
parentMenu: cloudNetworkMenu,
}),
};
</script>
<script setup>
import ApplicationEdit from "./components/ApplicationEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?
import {
@@ -122,30 +122,22 @@ import {
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
import NetWorkMappingEdit from "@/views/layoutpages/cloud_network/components/NetWorkMappingEdit.vue";
const { proxy } = getCurrentInstance();
const queryForm = ref(null);
const tableData = ref([]);
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
applicationName: "",
clientId: "",
size: 10,
current: 1,
total: 0,
});
const { applicationName, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
const { clientId, size, current, total } = toRefs(params);
/**
* @description: dialog事件
@@ -156,13 +148,22 @@ const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (applicationId) => {
console.log(applicationId);
const handleDel = (visitorPort) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
@@ -170,10 +171,10 @@ const handleDel = (applicationId) => {
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.applicationDelete({
id: applicationId,
const { code } = await VE_API.cloudNetwork.networkMappingDelete({
visitorPort,
});
if (code === 0) {
if (code === "00") {
getDataList();
}
})
@@ -190,7 +191,7 @@ const handleDel = (applicationId) => {
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.applicationPage(params);
const { code, data } = await VE_API.cloudNetwork.networkMappingPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;

View File

@@ -2,11 +2,11 @@
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="音色名称" prop="name">
<el-form-item label="访客端口" prop="visitorPort">
<el-input
clearable
v-model="name"
placeholder="音色名称"
v-model="visitorPort"
placeholder="访客端口"
></el-input>
</el-form-item>
<el-form-item>
@@ -47,17 +47,11 @@
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="name" label="音色名称"></el-table-column>
<el-table-column prop="code" label="音色编码"></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="修改时间"
prop="visitorPort"
label="访客端口"
></el-table-column>
<el-table-column prop="describe" label="描述"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
@@ -70,7 +64,7 @@
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
@click.prevent="handleDel(row.visitorPort)"
type="danger"
size="small"
>
@@ -81,7 +75,7 @@
</ve-table>
<!-- 编辑组件 -->
<tts-timbre-edit
<serverVisitor-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
@@ -91,11 +85,11 @@
</div>
</template>
<script>
import ttsMenu from "@/views/layoutpages/tts/TtsMenu";
import cloudNetworkMenu from "@/views/layoutpages/cloud_network/components/CloudNetworkMenu";
export default {
data: () => ({
description: "TTS音色管理",
description: "访客管理",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
@@ -104,15 +98,15 @@ export default {
},
// type 0: 1 2
type: "1",
icon: "Service",
name: "TTS音色管理",
parentMenu: ttsMenu,
icon: "Histogram",
name: "访客管理",
parentMenu: cloudNetworkMenu,
}),
};
</script>
<script setup>
import TtsTimbreEdit from "./components/TtsTimbreEdit.vue";
import ServerVisitorEdit from "./components/ServerVisitorEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?
import {
@@ -129,17 +123,16 @@ const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
name: "",
visitorPort: "",
size: 10,
current: 1,
total: 0,
});
const { name, size, current, total } = toRefs(params);
const { visitorPort, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
* @param title
* @param row
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
@@ -161,7 +154,8 @@ const handelDialog = (e) => {
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
const handleDel = (visitorPort) => {
console.log(visitorPort);
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
@@ -169,7 +163,9 @@ const handleDel = (id) => {
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.ttsTimbreRemove({ id: id });
const { code } = await VE_API.cloudNetwork.visitorDelete({
visitorPort: visitorPort,
});
if (code === 0) {
getDataList();
}
@@ -187,7 +183,7 @@ const handleDel = (id) => {
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.ttsTimbreFindPage(params);
const { code, data } = await VE_API.cloudNetwork.visitorPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;

View File

@@ -0,0 +1,8 @@
const cloudNetworkMenu = {
description: "内网穿透管理",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Tools",
name: "内网穿透管理",
};
export default cloudNetworkMenu;

View File

@@ -14,15 +14,10 @@
label-width="80px"
:inline="false"
>
<el-form-item label="项目名" prop="projectId">
<el-select
v-model="projectId"
placeholder="项目名"
@change="changeProject"
clearable
>
<el-form-item label="客户端ID" prop="clientId">
<el-select v-model="clientId" placeholder="客户端ID" clearable>
<el-option
v-for="item in projectList"
v-for="item in clientList"
:key="item.value"
:label="item.label"
:value="item.value"
@@ -30,19 +25,37 @@
/>
</el-select>
</el-form-item>
<el-form-item label="数据库" prop="schemaName">
<el-select v-model="schemaName" placeholder="数据库" clearable>
<el-form-item label="访问端口" prop="visitorPort">
<el-select
v-model="visitorPort"
placeholder="访问端口"
clearable
>
<el-option
v-for="item in serverSchemaList"
v-for="item in visitorList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="应用名" prop="applicationName">
<el-form-item label="客户端目标地址" prop="clientTargetIp">
<el-input
v-model="applicationName"
v-model="clientTargetIp"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="客户端目标端口" prop="clientTargetPort">
<el-input
v-model="clientTargetPort"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="描述" prop="describe">
<el-input
v-model="describe"
placeholder=""
clearable
></el-input>
@@ -68,24 +81,31 @@ import {
onMounted,
} from "vue";
const rules = {
projectId: [
clientId: [
{
required: true,
message: "请输入选择项目",
message: "请输入选择客户端",
trigger: "blur",
},
],
schemaName: [
clientTargetIp: [
{
required: true,
message: "请输入选择数据库",
message: "请输入客户端目标IP",
trigger: "blur",
},
],
applicationName: [
clientTargetPort: [
{
required: true,
message: "请输入应用名",
message: "请输入客户端目标端口",
trigger: "blur",
},
],
visitorPort: [
{
required: true,
message: "请选择访客端口",
trigger: "blur",
},
],
@@ -110,17 +130,17 @@ const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const projectList = ref(null);
const serverSchemaList = ref(null);
const clientList = ref(null);
const visitorList = ref(null);
const form = reactive({
applicationName: "",
projectId: "",
applicationId: "",
instanceId: "",
schemaName: "",
clientId: "",
clientTargetIp: "0.0.0.0",
clientTargetPort: "",
visitorPort: "",
describe: "",
});
const { projectId, applicationName, applicationId, instanceId, schemaName } =
const { clientId, clientTargetIp, clientTargetPort, visitorPort, describe } =
toRefs(form);
/**
@@ -129,11 +149,11 @@ const { projectId, applicationName, applicationId, instanceId, schemaName } =
* @return {*}
*/
rowData.value &&
((projectId.value = rowData.value.projectId),
(applicationId.value = rowData.value.applicationId),
(instanceId.value = rowData.value.instanceId),
(schemaName.value = rowData.value.schemaName),
(applicationName.value = rowData.value.applicationName));
((clientId.value = rowData.value.clientId),
(clientTargetIp.value = rowData.value.clientTargetIp),
(clientTargetPort.value = rowData.value.clientTargetPort),
(visitorPort.value = rowData.value.visitorPort),
(describe.value = rowData.value.describe));
/**
* @description:提交
* @param {*}
@@ -144,10 +164,10 @@ const onSubmit = () => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.applicationAdd(form);
res = await VE_API.cloudNetwork.networkMappingSave(form);
} else {
res = await VE_API.system.applicationEdit({
applicationId: rowData.value.applicationId,
res = await VE_API.cloudNetwork.networkMappingUpdate({
clientTargetPort: rowData.value.clientTargetPort,
...form,
});
}
@@ -162,41 +182,33 @@ const onSubmit = () => {
});
};
onMounted(async () => {
VE_API.system.projectList().then((res) => {
VE_API.cloudNetwork.cloudClientFindList().then((res) => {
res.data.map((item) => {
item.label = item.projectName;
item.value = item.id;
item.label = item.clientId;
item.value = item.clientId;
});
projectList.value = res.data ? res.data : [];
clientList.value = res.data ? res.data : [];
});
findVisitorPort();
});
const findSchema = async (instanceId = null) => {
if (instanceId == null) {
return;
}
//
let res = await VE_API.system.schemaList({
instanceId,
});
/**
* 获取未使用的访客端口
* @param visitorPort
* @returns {Promise<void>}
*/
const findVisitorPort = async () => {
// 使访
let res = await VE_API.cloudNetwork.visitorList();
const { code } = res;
if (code === 0) {
res.data.map((item) => {
item.label = item.schemaName;
item.value = item.schemaName;
item.label = item.describe;
item.value = item.visitorPort;
});
serverSchemaList.value = res.data ? res.data : [];
visitorList.value = res.data ? res.data : [];
// databaseSchemaId.value = serverSchemaList.value[0].id;
}
};
const changeProject = (projectId) => {
console.log(projectId);
if (projectId) {
let project = projectList.value.find((item) => item.id === projectId);
findSchema(project.instanceId);
} else {
serverSchemaList.value = [];
}
};
</script>
<style lang="scss" scoped></style>

View File

@@ -14,16 +14,19 @@
label-width="80px"
:inline="false"
>
<el-form-item label="音色名称" prop="name">
<el-form-item label="访客端口" prop="visitorPort">
<el-input
v-model="name"
placeholder="音色名称"
v-model="visitorPort"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="音色编码" prop="code">
<el-input v-model="code" placeholder="" clearable></el-input>
<el-form-item label="描述" prop="describe">
<el-input
v-model="describe"
placeholder=""
clearable
></el-input>
</el-form-item>
</el-form>
@@ -40,25 +43,30 @@
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
name: [
projectId: [
{
required: true,
message: "请输入音色名称",
message: "请输入选择项目",
trigger: "blur",
},
],
code: [
schemaName: [
{
required: true,
message: "请输入音色编码",
message: "请输入选择数据库",
trigger: "blur",
},
],
applicationName: [
{
required: true,
message: "请输入应用名",
trigger: "blur",
},
],
@@ -83,11 +91,12 @@ const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
name: "",
code: "",
visitorPort: "",
describe: "",
});
const { name, code } = toRefs(form);
const { visitorPort, describe } = toRefs(form);
/**
* @description: 初始化
@@ -95,12 +104,8 @@ const { name, code } = toRefs(form);
* @return {*}
*/
rowData.value &&
((name.value = rowData.value.name), (code.value = rowData.value.code));
onMounted(async () => {
// console.log("123");
});
((visitorPort.value = rowData.value.visitorPort),
(describe.value = rowData.value.describe));
/**
* @description:提交
* @param {*}
@@ -111,10 +116,10 @@ const onSubmit = () => {
if (valid) {
let res;
if (title.value === "添加") {
res = await VE_API.system.ttsTimbreStory(form);
res = await VE_API.cloudNetwork.visitorSave(form);
} else {
res = await VE_API.system.ttsTimbreUpdateOne({
id: rowData.value.id,
res = await VE_API.cloudNetwork.visitorUpdate({
visitorPort: rowData.value.visitorPort,
...form,
});
}
@@ -128,6 +133,7 @@ const onSubmit = () => {
}
});
};
onMounted(async () => {});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,107 +0,0 @@
<template>
<div>
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="json字符串" prop="jsonSource">
<el-input
style="height: 300px"
v-model="jsonSource"
placeholder="json字符串"
clearable
></el-input>
</el-form-item>
</el-form>
<span>
<el-button type="primary" @click="onSubmit()"
>Json转换成Excel</el-button
>
</span>
</div>
</template>
<script>
import docMenu from "@/views/layoutpages/doc/DocMenu";
export default {
data: () => ({
description: "Excel下载",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
preview: { name: "预览", toPath: true }, //topath:true 需要设置跳转路径
down: { name: "下载" }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "UploadFilled",
name: "Excel下载",
parentMenu: docMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, onMounted, ref } from "vue";
const rules = {
jsonSource: [
{
required: true,
message: "请输入JSON字符串",
trigger: "blur",
},
],
};
const formRef = ref(null);
const form = reactive({
jsonSource: "",
});
const { jsonSource } = toRefs(form);
onMounted(async () => {
console.log("1234");
});
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
// 将字符串转换为JavaScript对象
const jsonData = JSON.parse(jsonSource.value);
let res = await VE_API.system.docJson2Excel(jsonData);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,8 +0,0 @@
const docMenu = {
description: "文件管理",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "UploadFilled",
name: "文件管理",
};
export default docMenu;

View File

@@ -1,210 +0,0 @@
<template>
<div>
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="文件数据" prop="pdfList">
<el-upload
name="pdfList"
:multiple="true"
:show-file-list="true"
:on-change="onChange"
:on-remove="pdfFileRemove"
limit="1000"
v-model="pdfList"
placeholder=""
clearable
:auto-upload="false"
accept=".pdf"
class="upload-demo"
drag
>
<!-- <el-button size="medium" type="primary">上传文件</el-button>-->
<div style="padding: 10px 0">
<el-icon class="el-icon--upload"
><upload-filled
/></el-icon>
<p
style="
margin-top: 10px;
font-size: 14px;
color: #409eff;
"
>
点击或拖拽文件至此即可上传文件
</p>
<p
style="
margin-top: 20px;
font-size: 14px;
color: red;
"
>
请上传10GB以内的待测对象
</p>
</div>
</el-upload>
</el-form-item>
<el-form-item label="合并后文件名称" prop="targetName">
<el-input
v-model="targetName"
placeholder="合并后文件名称"
clearable
></el-input>
</el-form-item>
</el-form>
<span>
<el-button type="primary" @click="onSubmit()"
>合并文件并下载</el-button
>
</span>
</div>
</template>
<script>
import docMenu from "@/views/layoutpages/doc/DocMenu";
export default {
data: () => ({
description: "[DOC]PDF合并",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
preview: { name: "预览", toPath: true }, //topath:true 需要设置跳转路径
down: { name: "下载" }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "UploadFilled",
name: "[DOC]PDF合并",
parentMenu: docMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, onMounted, ref } from "vue";
import { UploadFilled } from "@element-plus/icons-vue";
const rules = {
targetName: [
{
required: true,
message: "请输入文件名称",
trigger: "blur",
},
],
pdfList: [
{
required: true,
message: "请上传文件",
trigger: "blur",
},
],
};
const formRef = ref(null);
const form = reactive({
targetName: "",
uid: "",
pdfList: [],
type: "",
length: 0,
});
const { targetName, pdfList } = toRefs(form);
onMounted(async () => {
console.log("1234");
});
/**
* 计算文件大小
* @param fileSize
* @returns {string}
*/
const formatFileSize = (fileSize) => {
if (fileSize < 1024) {
return fileSize + "B";
} else if (fileSize < 1024 * 1024) {
let temp = fileSize / 1024;
temp = temp.toFixed(2);
return temp + "KB";
} else if (fileSize < 1024 * 1024 * 1024) {
let temp = fileSize / (1024 * 1024);
temp = temp.toFixed(2);
return temp + "MB";
} else {
let temp = fileSize / (1024 * 1024 * 1024);
temp = temp.toFixed(2);
return temp + "GB";
}
};
/**
* 文件更改
* */
const onChange = (file) => {
var targetName = file.name;
var size = file.size;
form.targetName = targetName;
if (size != null) {
form.length = formatFileSize(size);
}
// form.pdfList = file.raw;
form.pdfList.push(file.raw);
if (targetName !== null) {
var split = targetName.split(".");
form.type = split[split.length - 1];
}
};
const pdfFileRemove = (file, fileList) => {
form.pdfList = fileList.map((item) => item.raw);
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let fd = new FormData();
form.pdfList.forEach((item) => {
fd.append("multipartFileList", item); //传文件
});
fd.append("targetName", form.targetName);
let res = await VE_API.system.docPdfMerge(fd, {
responseType: "blob",
});
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,271 +0,0 @@
<!--
* @Author: xujianhua
* @Date: 2021-04-01 17:06:04
* @LastEditTime: 2021-11-30 18:55:11
* @Description: file content
* @FilePath: \lazy-ui\src\views\layoutpages\leisure\Game.vue
-->
<template>
<div id="ve_puzzle">
<div
class="ve_artwork"
:style="{
backgroundImage: show_img || success ? `url(${img})` : 'none',
}"
>
<div
v-for="i in 16"
:key="i"
:class="[
've_item_box',
`pic${i}`,
`img${arr[i - 1]}`,
show_img || success ? 've_show_img' : '',
success && i == 16 ? 've_finish' : '',
]"
:style="{
backgroundImage:
i == 16
? success
? `url(${img})`
: 'none'
: `url(${img})`,
}"
:ref="
(el) => {
if (el) divs[i - 1] = el;
}
"
@click.self.stop="move_img(i - 1, $event)"
/>
</div>
<div class="ve_button">
<div class="ve_game_button">
<el-row :gutter="10">
<el-col :span="12" :offset="0">
<el-button
type="primary"
@click="get_nums()"
style="width: 100%"
>
重新开始
</el-button>
</el-col>
<el-col :span="12" :offset="0">
<el-button
style="width: 100%"
:type="show_img ? 'success' : 'info'"
@click="see_img()"
:disabled="success"
>
{{ txt }}
</el-button>
</el-col>
</el-row>
</div>
<div class="ve_upload">
<el-upload
style="width: 100%"
action=""
accept="image/png, image/jpeg"
ref="upload"
:on-change="onChange"
:auto-upload="false"
:show-file-list="false"
>
<el-button style="width: 100%" type="danger">
用我的萌照
</el-button>
</el-upload>
</div>
</div>
</div>
</template>
<script>
import leisureMenu from "@/views/layoutpages/leisure/LeisureMenu";
export default {
data: () => ({
description: "拼图小游戏",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Fries",
name: "内置游戏",
parentMenu: leisureMenu,
}),
};
</script>
<script setup>
import { ref, onBeforeUpdate } from "vue";
let url = require("../../../assets/logo.png");
const img = ref(url);
const show_img = ref(false);
const txt = ref("查看原图");
const divs = ref([]);
const arr = ref([]);
const success = ref(false); //游戏状态
/**
* @description:换图片
* @param {*}
* @return {*}
*/
const onChange = (file) => {
img.value = URL.createObjectURL(file.raw);
get_nums();
// console.log(URL.createObjectURL(file.raw));
};
/**
* @description: 查看原图
* @param {*}
* @return {*}
*/
const see_img = () => {
show_img.value = !show_img.value;
txt.value = show_img.value ? "继续游戏" : "查看原图";
};
/**
* @description:初始化,生成1-16的16个随机排列的数字
* @param {*}
* @return {*}
*/
const get_nums = () => {
txt.value = "查看原图";
show_img.value = false;
success.value = false;
arr.value.length = 0;
for (let i = 1; i < 16; i++) {
arr.value.push(i);
}
// eslint-disable-next-line no-constant-condition
while (true) {
arr.value.sort(() => 0.5 - Math.random());
if (check_nums(arr.value)) {
break;
}
}
arr.value.push(16);
};
/**
* @description: 检查打乱后的数组是否合理
* @param {*}
* @return {*}
*/
const check_nums = (arr) => {
let count = 0;
for (let i = 0; i < 15; i++) {
for (let j = i + 1; j < 15; j++) {
if (arr[j] < arr[i]) {
count++;
}
}
}
return count % 2 === 0;
};
/**
* @description:检查是否拼图成功
* @param {*}
* @return {*}
*/
const check_finish = () => {
let bool = arr.value.every((item, i) => {
return item == i + 1;
});
bool && (success.value = true);
};
/**
* @description:图片点击事件,移动图片
* @param {*}
* @return {*}
*/
const move_img = (i, e) => {
let top = e.target.offsetTop;
let left = e.target.offsetLeft;
let top_16 = divs.value[15].offsetTop;
let left_16 = divs.value[15].offsetLeft;
let x = Math.abs(left - left_16);
let y = Math.abs(top - top_16);
if ((x == 100 && top == top_16) || (y == 100 && left == left_16)) {
let a = arr.value[15];
arr.value[15] = arr.value[i];
arr.value[i] = a;
check_finish();
}
};
get_nums();
// 确保在每次更新之前重置ref
onBeforeUpdate(() => {
divs.value = [];
});
</script>
<style lang="scss" scoped>
#ve_puzzle {
margin-top: 10px;
.ve_artwork {
margin: 0 auto;
position: relative;
width: 399px;
height: 399px;
background-size: 399px;
box-shadow:
1px 1px 10px rgb(168, 168, 168),
-1px -1px 10px rgb(168, 168, 168);
.ve_item_box {
opacity: 1;
cursor: pointer;
position: absolute;
z-index: 2;
width: 99px;
height: 99px;
transition: all 0.2s;
background-repeat: no-repeat;
background-size: 399px;
&.ve_show_img {
opacity: 0;
}
}
@for $i from 1 through 4 {
@for $j from ($i - 1) * 4 + 1 through ($i - 1) * 4 + 4 {
.img#{$j} {
top: #{($i - 1) * 100}px;
}
.pic#{$j} {
background-position-y: -#{($i - 1) * 100}px;
}
}
@for $k from $i through $i + 3 {
.img#{ ($k - $i) * 4 + $i} {
left: #{($i - 1) * 100}px;
}
.pic#{ ($k - $i) * 4 + $i} {
background-position-x: -#{($i - 1) * 100}px;
}
}
}
.pic16 {
transition: none;
box-shadow:
inset 1px 1px 10px rgb(168, 168, 168),
inset -1px -1px 10px rgb(168, 168, 168);
z-index: 1;
&.ve_finish {
box-shadow: none;
}
}
}
.ve_button {
width: 409px;
margin: 0 auto;
.ve_game_button {
margin: 10px 0;
}
}
& :deep(.el-upload--text) {
width: 100%;
}
}
</style>

View File

@@ -1,8 +0,0 @@
const leisureMenu = {
description: "内置游戏",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Fries",
name: "内置游戏",
};
export default leisureMenu;

View File

@@ -1,55 +0,0 @@
<template>
<div id="myecharts" ref="chart"></div>
</template>
<script>
import mapMenu from "@/views/layoutpages/map/MapMenu";
export default {
data: () => ({
description: "Earchats地图",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "LocationInformation",
name: "Earchats",
parentMenu: mapMenu,
}),
};
</script>
<script setup>
import * as echarts from "echarts";
import china from "@/assets/json/china.json";
import { ref, onMounted } from "vue";
const chart = ref();
onMounted(async () => {
let myChart = echarts.init(chart.value);
echarts.registerMap("anhui", china);
let option = {
geo: {
type: "map",
map: "anhui",
//roam:true,
//zoom:10 ,//平移
label: {
show: true,
},
},
};
myChart.setOption(option);
});
</script>
<style>
#myecharts {
width: 600px;
height: 500px;
}
</style>

View File

@@ -1,8 +0,0 @@
const mapMenu = {
description: "地图管理",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "LocationInformation",
name: "地图管理",
};
export default mapMenu;

View File

@@ -1,241 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="文件名" prop="name">
<el-input
clearable
v-model="name"
placeholder="文件名"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="name" label="文件名称"></el-table-column>
<el-table-column prop="uid" label="文件uid"></el-table-column>
<el-table-column prop="length" label="文件大小"></el-table-column>
<el-table-column prop="describe" label="描述"></el-table-column>
<el-table-column prop="type" label="文件类型"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['preview']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.preview.name }}
</el-button>
<el-button
v-permission="['down']"
@click.prevent="openUrl(row.id)"
type="primary"
size="small"
>
{{ buttons.down.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<file-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import mediaMenu from "@/views/layoutpages/media/MediaMenu";
export default {
data: () => ({
description: "文件信息查询与设置",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
preview: { name: "预览", toPath: true }, //topath:true 需要设置跳转路径
down: { name: "下载" }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "UploadFilled",
name: "文件管理",
parentMenu: mediaMenu,
}),
};
</script>
<script setup>
import FileEdit from "./components/FileEdit";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
name: "",
size: 10,
current: 1,
total: 0,
});
const { name, size, current, total } = toRefs(params);
/**
* @description:添加or编辑事件
* @return {*}
* @param title
* @param row
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.playFileDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.playFilePage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
});
const openUrl = async (id) => {
console.log(id);
// window.open("/play/file/retrieve/data/" + id, "_blank");
let res = await VE_API.system.playFileData(
{ id: id },
{
responseType: "blob",
},
);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,8 +0,0 @@
const mediaMenu = {
description: "媒体管理",
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Headset",
name: "媒体管理",
};
export default mediaMenu;

View File

@@ -1,559 +0,0 @@
<template>
<!--音乐列表-->
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="音乐名称" prop="name">
<el-input
clearable
v-model="name"
placeholder="音乐名称"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="name" label="音乐名称"></el-table-column>
<el-table-column prop="singer" label="歌手"></el-table-column>
<el-table-column prop="album" label="专辑"></el-table-column>
<el-table-column prop="duration" label="时长"></el-table-column>
<el-table-column prop="musicUrl" label="音乐地址"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<el-button
v-permission="['play']"
@click.prevent="handlePlay(row)"
type="primary"
size="small"
>
{{ buttons.play.name }}
</el-button>
<el-button
v-permission="['down']"
@click.prevent="handleDownMusic(row)"
type="primary"
size="small"
>
{{ buttons.down.name }}
</el-button>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<music-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
<!--音乐播放器-->
<div
class="music-container"
:class="{ 'music-active-switch': offsetThreshold }"
>
<div class="music-disk">
<!--唱片图片-->
<img
class="music-disk-picture"
:class="{ 'music-disk-playing-style': playState }"
src="../../../static/music-default-pic.png"
alt=""
/>
</div>
<!--进度条-->
<div class="music-slider">
<el-slider
v-model="playTime"
:format-tooltip="tooltipFormat"
size="small"
:max="sliderLength"
/>
</div>
<!--按钮组-->
<div class="button-group">
<!--上一曲 按钮-->
<button class="play-button">
<icon-go-start
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
</button>
<!--播放 按钮-->
<button class="play-button">
<icon-play-one
v-if="!playState"
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
<icon-pause
v-if="playState"
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
</button>
<!--下一曲 按钮-->
<button class="play-button">
<icon-go-end
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
</button>
<!--音量按钮-->
<div class="voice-container">
<button class="voice-button">
<icon-volume-notice
v-if="!voiceMute"
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
<icon-volume-mute
v-if="voiceMute"
theme="outline"
size="23"
fill="#939393"
:strokeWidth="3"
strokeLinejoin="miter"
strokeLinecap="butt"
/>
</button>
<div class="voice-slider">
<el-slider
v-model="voicePower"
:max="1"
:step="0.1"
size="small"
/>
</div>
</div>
</div>
<div>{{ musicSource }}</div>
<audio
v-if="musicSource"
ref="musicAudio"
class="audio-component"
controls="controls"
:src="musicSource"
></audio>
</div>
</template>
<script>
import mediaMenu from "@/views/layoutpages/media/MediaMenu";
export default {
data: () => ({
description: "音乐播放器",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
play: { name: "播放" }, //topath:true 需要设置跳转路径
down: { name: "下载" }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "VideoPlay",
name: "音乐管理",
parentMenu: mediaMenu,
}),
};
</script>
<script setup>
import MusicEdit from "@/views/layoutpages/media/components/MusicEdit";
import {
reactive,
toRefs,
// eslint-disable-next-line no-unused-vars
computed,
ref,
onMounted,
onUnmounted,
getCurrentInstance,
} from "vue";
// import { useRoute, useRouter } from "vue-router";
// import { useStore } from "vuex";
// import { findName } from "../common";
// *导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
// const route = useRoute();
// const router = useRouter();
// const store = useStore();
// const menuList = computed(() => store.getters.menuList).value;
//
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
// const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
name: "",
size: 10,
current: 1,
total: 0,
});
const { name, size, current, total } = toRefs(params);
//是否正在播放
const playState = ref(false);
//现在的播放时间
const playTime = ref(0.0);
//进度条长度
const sliderLength = ref(100);
//歌曲URL
// const musicUrl = ref("");
//播放器标签
const musicAudio = ref(null);
//实现音乐播放的标签
const musicSource = ref(null);
//是否静音
const voiceMute = ref(false);
//音量大小
const voicePower = ref(0.5);
const musicState = reactive({
musicArr: [],
musicCount: 0,
});
//是否达到阈值,达到阈值就显示播放器,反之
const offsetThreshold = ref(true);
//歌曲进度条文本提示
const tooltipFormat = (val) => {
let strTime = playTime.value;
let strMinute = parseInt(strTime / 60 + "");
let strSecond = parseInt((strTime % 60) + "");
return strMinute + ":" + strSecond;
};
//初始化歌曲源【将这里替换成自己的请求逻辑】
const getDataList = async () => {
const { code, data } = await VE_API.system.playMusicPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
tableData.value = record;
musicState.musicArr = record;
musicState.musicCount = record.length;
}
};
onMounted(() => {
getDataList();
});
onUnmounted(() => {});
/**
* 音乐 下载
* **/
const handleDownMusic = async (row) => {
let res = await VE_API.system.playMusicFindData(
{ id: row.id },
{
responseType: "blob",
},
);
let fileName = res.headers["file-name"];
// 获取文件名
fileName = decodeURIComponent(fileName);
let url = window.URL.createObjectURL(new Blob([res.data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// eslint-disable-next-line no-undef
link.setAttribute("download", fileName); //指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
};
/**
* 播放音乐
* **/
const handlePlay = async (row) => {
if (musicSource.value) {
window.URL.revokeObjectURL(musicSource.value); // 释放内存
}
let res = await VE_API.system.playMusicFindData(
{ id: row.id },
{
responseType: "blob",
},
);
console.log(res);
musicSource.value = window.URL.createObjectURL(new Blob([res.data]));
console.log(row.id);
console.log(musicSource.value);
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } = await VE_API.system.playMusicDelete({ id });
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description:添加or编辑事件
* @param {*}
* @return {*}
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
</script>
<style scoped>
.music-container {
position: fixed;
justify-content: center;
width: 280px;
height: 110px;
background-color: white;
border-radius: 15px;
bottom: 65px;
right: 30px;
opacity: 0;
transition: 0.5s;
}
.music-disk {
position: absolute;
width: 90px;
height: 90px;
left: 15px;
top: 10px;
border-radius: 50%;
}
.music-disk-picture {
width: 90px;
height: 90px;
border-radius: 50%;
/*设置图片不可点击*/
pointer-events: none;
}
.music-disk-playing-style {
animation: music-disk-rotate 5s linear infinite;
}
@keyframes music-disk-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.button-group {
position: absolute;
width: 330px;
height: 38px;
left: 90px;
bottom: 13px;
margin-left: 10px;
}
.button-group > button {
margin-left: 10px;
}
.play-button {
float: left;
width: 31px;
height: 31px;
padding: 4px;
/*margin: 0px;*/
border: 0px;
border-radius: 50%;
margin: 7px 0px 0px 0px;
}
.voice-button {
float: left;
width: 31px;
height: 31px;
padding: 0px;
/*margin: 0px;*/
border: 0px;
border-radius: 50%;
margin: 7px 0px 0px 0px;
background-color: transparent;
}
.music-slider {
position: absolute;
top: 20px;
left: 120px;
width: 50%;
}
.voice-container {
float: left;
margin-left: 12px;
width: 31px;
height: 38px;
overflow: hidden !important;
transition: 0.5s;
}
.voice-container:hover {
width: 160px;
}
.voice-slider {
position: relative;
top: 2px;
right: -30px;
width: 90px;
height: 35px;
background-color: white;
border-radius: 10px;
padding: 0px 15px 0px 15px;
transition: 0.2s;
}
.audio-component {
width: 300px;
height: 200px;
top: 100px;
display: none;
}
.music-active-switch {
opacity: 1;
}
</style>

View File

@@ -1,115 +0,0 @@
<template>
<div>
<el-row>
<el-col span="6">
<el-tree
:props="resourceProps"
:load="loadNode"
:data="resourceData"
lazy
show-checkbox
>
<template #default="{ data }">
<span class="custom-tree-node">
<img
v-if="data.isFile"
src="../../../../src/static/file.png"
style="width: 16px; height: 16px"
/>
<img
v-if="!data.isFile"
src="../../../../src/static/folder.png"
style="width: 16px; height: 16px"
/>
<span>
{{ data.name }}
</span>
</span>
</template>
</el-tree>
</el-col>
<el-col span="18"> 展示的内容 </el-col>
</el-row>
</div>
</template>
<script>
import mediaMenu from "@/views/layoutpages/media/MediaMenu";
export default {
data: () => ({
description: "资源管理",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
preview: { name: "预览", toPath: true }, //topath:true 需要设置跳转路径
down: { name: "下载" }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "UploadFilled",
name: "资源管理",
parentMenu: mediaMenu,
}),
};
</script>
<script setup>
import { reactive, ref, onMounted } from "vue";
const resourceData = ref([]);
const params = reactive({
path: "/",
});
const resourceProps = {
label: "name",
children: "children",
isLeaf: "leaf",
};
const loadNode = async (resourceNode, resolve) => {
if (resourceNode.level === 0) {
return resolve([]);
}
resourceNode.loaded = true;
var resourceNodeData = resourceNode.data;
if (resourceNodeData.isFile) {
return resolve([]);
}
console.log(resourceNodeData);
const { code, data } = await VE_API.system.playFileResourceList({
path:
"/" === resourceNodeData.rootPath
? "/" + resourceNodeData.name
: resourceNodeData.rootPath + "/" + resourceNodeData.name,
});
if (code === 0) {
if (data == null) {
return resolve([]);
}
// resourceNode.childNodes = data;
console.log(resourceNode);
return resolve(data);
}
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } = await VE_API.system.playFileResourceList(params);
if (code === 0) {
resourceData.value = data;
}
};
onMounted(async () => {
await getDataList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,241 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="文件数据" prop="data">
<el-upload
name="data"
:multiple="false"
:show-file-list="true"
:on-change="onChange"
limit="1"
v-model="data"
placeholder=""
clearable
:auto-upload="false"
>
<!-- <el-button size="medium" type="primary">上传文件</el-button>-->
<div style="padding: 10px 0">
<Icon
type="ios-cloud-upload"
size="52"
style="#3399ff"
></Icon>
<p style="margin-top: 10px; font-size: 14px">
点击或拖拽文件至此即可上传文件
</p>
<p
style="
margin-top: 20px;
font-size: 14px;
color: red;
"
>
请上传10GB以内的待测对象
</p>
</div>
</el-upload>
</el-form-item>
<el-form-item label="文件名称" prop="name">
<el-input
v-model="name"
placeholder="文件名称"
clearable
></el-input>
</el-form-item>
<el-form-item label="描述" prop="describe">
<el-input
v-model="describe"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="文件类型" prop="type">
<el-input v-model="type" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="大小" prop="length">
<el-input v-model="length" placeholder="" clearable></el-input>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
const rules = {
name: [
{
required: true,
message: "请输入文件名称",
trigger: "blur",
},
],
data: [
{
required: true,
message: "请上传文件",
trigger: "blur",
},
],
type: [
{
required: true,
message: "请选择文件类型",
trigger: "blur",
},
],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
name: "",
uid: "",
data: [],
describe: "",
type: "",
length: 0,
});
const { name, uid, data, describe, type, length } = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((name.value = rowData.value.name),
(uid.value = rowData.value.uid),
(data.value = rowData.value.data),
(describe.value = rowData.value.describe),
(length.value = rowData.value.length),
(type.value = rowData.value.type));
onMounted(async () => {
console.log("123");
});
/**
* 计算文件大小
* @param fileSize
* @returns {string}
*/
const formatFileSize = (fileSize) => {
if (fileSize < 1024) {
return fileSize + "B";
} else if (fileSize < 1024 * 1024) {
let temp = fileSize / 1024;
temp = temp.toFixed(2);
return temp + "KB";
} else if (fileSize < 1024 * 1024 * 1024) {
let temp = fileSize / (1024 * 1024);
temp = temp.toFixed(2);
return temp + "MB";
} else {
let temp = fileSize / (1024 * 1024 * 1024);
temp = temp.toFixed(2);
return temp + "GB";
}
};
/**
* 文件更改
* */
const onChange = (file) => {
var name = file.name;
var size = file.size;
form.name = name;
form.uid = file.uid;
if (size != null) {
form.length = formatFileSize(size);
}
form.data = file.raw;
if (name !== null) {
var split = name.split(".");
form.type = split[split.length - 1];
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let fd = new FormData();
fd.append("data", form.data); //传文件
fd.append("name", form.name);
fd.append("describe", form.describe);
fd.append("type", form.type);
fd.append("length", form.length);
fd.append("uid", form.uid);
let res;
if (title.value === "添加") {
res = await VE_API.system.playFileAdd(fd);
} else {
res = await VE_API.system.playFileEdit({
id: rowData.value.id,
...fd,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,238 +0,0 @@
<template>
<el-dialog
:title="title"
append-to-body
destroy-on-close
:model-value="showDialog"
@close="closeDialog()"
>
<!-- <span>{{ rowData }}</span> -->
<!-- 表单 -->
<el-form
:model="form"
ref="formRef"
:rules="rules"
label-width="80px"
:inline="false"
>
<el-form-item label="音乐名称" prop="name">
<el-input v-model="name" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="歌手" prop="singer">
<el-input v-model="singer" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="专辑" prop="album">
<el-input v-model="album" placeholder="" clearable></el-input>
</el-form-item>
<el-form-item label="时长" prop="duration">
<el-input
v-model="duration"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="音乐地址" prop="musicUrl">
<el-input
v-model="musicUrl"
placeholder=""
clearable
></el-input>
</el-form-item>
<el-form-item label="文件数据" prop="musicData">
<el-upload
name="musicData"
:multiple="false"
:show-file-list="true"
:on-change="onChange"
limit="1"
v-model="musicData"
placeholder=""
clearable
:auto-upload="false"
>
<el-button size="medium" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
</el-form>
<template v-slot:footer>
<span>
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="onSubmit()">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
reactive,
toRefs,
ref,
defineProps,
defineEmits,
onMounted,
} from "vue";
const rules = {
name: [
{
required: true,
message: "请输入音乐名称",
trigger: "blur",
},
],
singer: [
{
required: true,
message: "请输入歌手",
trigger: "blur",
},
],
album: [
{
required: true,
message: "请输入专辑",
trigger: "blur",
},
],
duration: [
{
required: true,
message: "请输入时长",
trigger: "change",
},
],
// musicUrl: [
// {
// required: true,
// message: "请输入音乐地址",
// trigger: "change",
// },
// ],
};
const props = defineProps({
showDialog: {
type: Boolean,
default: true,
},
title: {
type: String,
default: "添加",
},
rowData: {
type: Object,
default: null,
},
});
const emit = defineEmits(["closeDialog"]);
const { title, rowData } = toRefs(props);
const closeDialog = () => {
emit("closeDialog", false);
};
const formRef = ref(null);
const form = reactive({
name: "",
singer: "",
album: "",
duration: "",
musicData: "",
musicUrl: "",
});
const { name, singer, album, duration, musicData, musicUrl } = toRefs(form);
/**
* @description: 初始化
* @param {*}
* @return {*}
*/
rowData.value &&
((name.value = rowData.value.name),
(singer.value = rowData.value.singer),
(album.value = rowData.value.album),
(duration.value = rowData.value.duration),
(musicData.value = rowData.value.musicData),
(musicUrl.value = rowData.value.musicUrl));
onMounted(async () => {
// 查询数据库实例
});
/**
* 计算文件大小
* @param fileSize
* @returns {string}
*/
const formatFileSize = (fileSize) => {
if (fileSize < 1024) {
return fileSize + "B";
} else if (fileSize < 1024 * 1024) {
let temp = fileSize / 1024;
temp = temp.toFixed(2);
return temp + "KB";
} else if (fileSize < 1024 * 1024 * 1024) {
let temp = fileSize / (1024 * 1024);
temp = temp.toFixed(2);
return temp + "MB";
} else {
let temp = fileSize / (1024 * 1024 * 1024);
temp = temp.toFixed(2);
return temp + "GB";
}
};
/**
* 文件更改
* */
const onChange = (file) => {
var name = file.name;
var size = file.size;
form.name = name;
form.uid = file.uid;
if (size != null) {
form.length = formatFileSize(size);
}
form.musicData = file.raw;
if (name !== null) {
var split = name.split(".");
form.type = split[split.length - 1];
}
};
/**
* @description:提交
* @param {*}
* @return {*}
*/
const onSubmit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
let fd = new FormData();
fd.append("musicData", form.musicData); //传文件
fd.append("name", form.name);
fd.append("singer", form.singer);
fd.append("album", form.album);
fd.append("duration", form.duration);
fd.append("musicUrl", form.musicUrl);
let res;
if (title.value === "添加") {
res = await VE_API.system.playMusicInsertOrUpdate(fd);
} else {
res = await VE_API.system.playMusicInsertOrUpdate({
id: rowData.value.id,
...fd,
});
}
const { code } = res;
if (code === 0) {
closeDialog();
}
} else {
console.log("error submit!!");
return false;
}
});
};
</script>
<style lang="scss" scoped></style>

View File

@@ -1,84 +0,0 @@
<template>
<div class="vu_content">
<view
v-for="item_iframe in iframeList"
:key="item_iframe.id"
class="content-item"
>
<span>窗口{{ item_iframe.id }}</span>
<el-input
v-model="item_iframe.tilt"
placeholder="窗口描述"
clearable
></el-input>
<el-input
v-model="item_iframe.src"
placeholder="窗口地址"
clearable
></el-input>
<iframe
:src="item_iframe.src"
style="height: 100%; width: 100%; margin: 0; border: 0"
>
</iframe>
</view>
<view class="content-item">
<el-button type="primary" @click="addIframe()"
>添加iframe</el-button
>
</view>
</div>
</template>
<script>
import menu from "@/views/layoutpages/system/components/menu";
export default {
data: () => ({
description: "动态iframe",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
dictionaryData: { name: "查看翻译详细数据", toPath: true }, //topath:true 需要设置跳转路径
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Microphone",
name: "动态iframe",
parentMenu: menu,
}),
};
</script>
<script setup>
import { onMounted, ref } from "vue";
const iframeList = ref([]);
//添加样式
import "vue3-json-viewer/dist/index.css";
onMounted(async () => {});
const addIframe = () => {
console.log("111");
iframeList.value.push({
id: "默认ID",
src: "www.baidu.com",
tilt: "默认表头",
});
};
</script>
<style lang="scss" scoped>
.content {
display: flex;
flex-wrap: wrap;
padding: calc((100vw - 40vw - 40vw) / 6);
}
.content-item {
width: 40vw;
height: 140px;
background: #ffffff;
margin: calc((100vw - 40vw - 40vw) / 6);
}
</style>

View File

@@ -1,257 +0,0 @@
<template>
<div class="ve_container">
<!-- 搜索 -->
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="汉字" prop="word">
<el-input
clearable
v-model="word"
placeholder="汉字"
></el-input>
</el-form-item>
<el-form-item label="音色" property="timbreCode">
<el-select
v-model="timbreCode"
@change="getDataList"
placeholder="音色"
filterable
clearable
>
<el-option
v-for="item in timbreList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="onSubmit(params, getDataList)"
>
{{ buttons.search.name }}
</el-button>
<el-button @click="resetForm(queryForm, params, getDataList)">
重置
</el-button>
</el-form-item>
</el-form>
<!-- 列表 -->
<ve-table
:table="{
data: tableData,
}"
:pagination="{
onSizeChange: (val) =>
handleSizeChange(val, params, getDataList),
onCurrentChange: (val) =>
handleCurrentChange(val, params, getDataList),
currentPage: current,
pageSize: size,
total: total,
}"
>
<template #tool_bar>
<el-button
v-permission="['add']"
size="small"
type="primary"
@click="handleEdit(buttons.add.name)"
>
{{ buttons.add.name }}
</el-button>
</template>
<el-table-column prop="word" label="汉字"></el-table-column>
<el-table-column
prop="timbreCode"
label="音色编码"
></el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
></el-table-column>
<el-table-column
prop="updateTime"
label="修改时间"
></el-table-column>
<el-table-column prop="voiceUrl" label="voiceUrl"></el-table-column>
<el-table-column fixed="right" label="操作">
<template v-slot:default="{ row }">
<el-button
v-permission="['edit']"
@click.prevent="handleEdit(buttons.edit.name, row)"
type="primary"
size="small"
>
{{ buttons.edit.name }}
</el-button>
<el-button
v-permission="['del']"
@click.prevent="handleDel(row.id)"
type="danger"
size="small"
>
{{ buttons.del.name }}
</el-button>
<div>
<audio
ref="audio"
:src="row.voiceUrl"
autoplay
loop
controls="controls"
></audio>
</div>
</template>
</el-table-column>
</ve-table>
<!-- 编辑组件 -->
<tts-chinese-characters-timbre-edit
v-if="showDialog"
:rowData="rowData"
:title="dialogTitle"
:showDialog="showDialog"
@closeDialog="handelDialog($event)"
/>
</div>
</template>
<script>
import ttsMenu from "@/views/layoutpages/tts/TtsMenu";
export default {
data: () => ({
description: "TTS汉字音色管理",
buttons: {
search: { name: "查询" },
add: { name: "添加" },
edit: { name: "编辑" },
del: { name: "删除" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "BrushFilled",
name: "TTS汉字音色管理",
parentMenu: ttsMenu,
}),
};
</script>
<script setup>
import TtsChineseCharactersTimbreEdit from "./components/TtsChineseCharactersTimbreEdit.vue";
import { reactive, toRefs, ref, onMounted, getCurrentInstance } from "vue";
//?导入公共查询方法
import {
onSubmit,
resetForm,
handleSizeChange,
handleCurrentChange,
} from "@/views/layoutpages/common";
const { proxy } = getCurrentInstance();
const rowData = ref(null);
const dialogTitle = ref("");
const showDialog = ref(false);
const queryForm = ref(null);
const tableData = ref([]);
const params = reactive({
word: "",
timbreCode: "",
size: 10,
current: 1,
total: 0,
});
const timbreList = ref([]);
const { word, timbreCode, size, current, total } = toRefs(params);
/**
* 获取音色数据
*/
const getTimbreList = async () => {
let res = await VE_API.system.ttsTimbreFindList();
res.data.map((item) => {
item.label = item.name;
item.value = item.code;
});
timbreList.value = res.data ? res.data : [];
};
/**
* @description:添加or编辑事件
* @return {*}
* @param title
* @param row
*/
const handleEdit = (title, row = null) => {
showDialog.value = true;
dialogTitle.value = title;
rowData.value = row;
};
/**
* @description: dialog事件
* @param {*}
* @return {*}
*/
const handelDialog = (e) => {
showDialog.value = e;
getDataList();
};
/**删除行数据
* @description:
* @param {*}
* @return {*}
*/
const handleDel = (id) => {
proxy
.$confirm("此操作将永久删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
const { code } =
await VE_API.system.ttsChineseCharactersTimbreRemove({
id: id,
});
if (code === 0) {
getDataList();
}
})
.catch(() => {
proxy.$message({
type: "info",
message: "已取消删除",
});
});
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const getDataList = async () => {
const { code, data } =
await VE_API.system.ttsChineseCharactersTimbreFindPage(params);
if (code === 0) {
const { size, current, total, record } = data;
params.size = size;
params.current = current;
params.total = total;
record.map((item) => {
const blob = new Blob([item.voice], { type: "audio/mp3" }); // 构造一个blob对象来处理数据并设置文件类型
item.voiceUrl = window.URL.createObjectURL(blob);
});
console.log(record);
tableData.value = record;
}
};
onMounted(async () => {
await getDataList();
await getTimbreList();
});
</script>
<style lang="scss" scoped></style>

View File

@@ -1,104 +0,0 @@
<template>
<div class="ve_home">
<el-form ref="queryForm" :inline="true" :model="params">
<el-form-item label="汉字" prop="text">
<el-input
clearable
v-model="text"
placeholder="汉字"
></el-input>
</el-form-item>
<el-form-item label="音色" property="timbreCode">
<el-select
v-model="timbreCode"
placeholder="音色"
filterable
clearable
>
<el-option
v-for="item in timbreList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit()">
{{ buttons.search.name }}
</el-button>
</el-form-item>
</el-form>
<div v-if="textVoiceUrl">
<audio ref="audio" :src="textVoiceUrl" controls="controls"></audio>
</div>
</div>
</template>
<script>
import ttsMenu from "@/views/layoutpages/tts/TtsMenu";
export default {
data: () => ({
description: "TTS汉字转换语音",
buttons: {
search: { name: "查询" },
},
// type 0:目录 1菜单 2按钮
type: "1",
icon: "Pointer",
name: "TTS汉字转换语音",
parentMenu: ttsMenu,
}),
};
</script>
<script setup>
import { reactive, toRefs, ref, onMounted } from "vue";
const queryForm = ref(null);
const textVoiceUrl = ref(null);
const params = reactive({
text: "欢迎来到TTS测试",
timbreCode: "",
size: 10,
current: 1,
total: 0,
});
const timbreList = ref([]);
const { text, timbreCode } = toRefs(params);
/**
* 获取音色数据
*/
const getTimbreList = async () => {
let res = await VE_API.system.ttsTimbreFindList();
res.data.map((item) => {
item.label = item.name;
item.value = item.code;
});
timbreList.value = res.data ? res.data : [];
};
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
const onSubmit = async () => {
if (textVoiceUrl.value) {
window.URL.revokeObjectURL(textVoiceUrl.value); // 释放内存
}
let res = await VE_API.system.ttsChineseCharactersTimbreTextToBytes(
params,
{ responseType: "blob" },
);
textVoiceUrl.value = window.URL.createObjectURL(new Blob([res.data]));
};
onMounted(async () => {
await getTimbreList();
});
</script>
<style lang="scss" scoped></style>

Some files were not shown because too many files have changed in this diff Show More