mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Compare commits
33 Commits
v3.8.0last
...
v3.8.0last
| Author | SHA1 | Date | |
|---|---|---|---|
| c8e33d43cb | |||
| 6c6af870ae | |||
| 79107599a6 | |||
| b6e8b37aee | |||
| 195ddd0421 | |||
| 9ddad931ff | |||
| fc05fe1aff | |||
| 7e325f68ca | |||
| f74da23d06 | |||
| e279915ba2 | |||
| bb6f077a95 | |||
| 7a031e6135 | |||
| 157877f9a6 | |||
| 25a71fa66c | |||
| fdc02fa68a | |||
| ec3c34969a | |||
| 5a215525d5 | |||
| 450b93d916 | |||
| 2d62bad2a9 | |||
| 0b10096f1c | |||
| 431ddb8fcb | |||
| ddf0f61ae5 | |||
| 4042579167 | |||
| bd5fda5968 | |||
| fdbd9c30ac | |||
| b8b4d3f29d | |||
| 78212aa7c0 | |||
| 6dc3c6af2a | |||
| b7a6812140 | |||
| 7efc51e30e | |||
| bd83b994bc | |||
| 8fb81f331c | |||
| fb188a83a1 |
34
README.md
34
README.md
@ -68,14 +68,6 @@ JeecgBoot 是一个开源低代码开发平台,支持全信创环境。它兼
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
技术文档
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
|
||||||
- 在线演示 : [平台演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex) | [体验低代码](https://jeecg.blog.csdn.net/article/details/106079007) | [体验零代码](https://app.qiaoqiaoyun.com/myapps/index)
|
|
||||||
- 开发文档: [文档中心](https://help.jeecg.com) | [AIGC大模块](https://help.jeecg.com/aigc)
|
|
||||||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [入门视频](http://jeecg.com/doc/video) | [如何反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md)
|
|
||||||
- QQ交流群 : ⑩716488839、⑨808791225(满)、其他(满)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -87,6 +79,29 @@ JeecgBoot 是一个开源低代码开发平台,支持全信创环境。它兼
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
在线体验
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
> JeecgBoot vs 敲敲云
|
||||||
|
> - JeecgBoot是低代码产品拥有很多低代码能力,比如流程设计、表单设计、大屏设计,代码生成器,适合半开发模式(开发+低代码结合),也可以集成零代码的应用管理模块;
|
||||||
|
> - 敲敲云是零代码产品,完全不写代码,通过配置搭建业务系统,其在jeecgboot基础上研发而成,删除了online、代码生成、OA等很多需要编码的功能,只保留了应用管理和聊天、流程、日程、文件四个标准OA功能
|
||||||
|
|
||||||
|
|
||||||
|
- JeecgBoot低代码: https://boot3.jeecg.com
|
||||||
|
- 敲敲云零代码:https://app.qiaoqiaoyun.com
|
||||||
|
- APP演示: http://jeecg.com/appIndex
|
||||||
|
|
||||||
|
技术文档
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||||
|
- 开发文档: [文档中心](https://help.jeecg.com) | [AIGC大模块](https://help.jeecg.com/aigc) | [低代码初体验一分钟](https://jeecg.blog.csdn.net/article/details/106079007)
|
||||||
|
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [入门视频](http://jeecg.com/doc/video) | [反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md)
|
||||||
|
- QQ交流群 : ⑩716488839、⑨808791225(满)、其他(满)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AIGC应用平台介绍
|
AIGC应用平台介绍
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
@ -105,10 +120,7 @@ JeecgBoot 平台的AIGC功能模块,是一套类似`Dify`的`AIGC应用开发
|
|||||||
[](https://www.bilibili.com/video/BV1zmd7YFE4w)
|
[](https://www.bilibili.com/video/BV1zmd7YFE4w)
|
||||||
|
|
||||||
|
|
||||||
##### 在线体验
|
|
||||||
|
|
||||||
- JeecgBoot演示: https://boot3.jeecg.com
|
|
||||||
- 敲敲云在线搭建AI知识库:https://app.qiaoqiaoyun.com
|
|
||||||
|
|
||||||
##### Dify `VS` JEECG AI
|
##### Dify `VS` JEECG AI
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -36,7 +36,6 @@ public class RestUtil {
|
|||||||
}
|
}
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getPath() {
|
private static String getPath() {
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
|
path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
import org.jeecg.common.exception.JeecgSqlInjectionException;
|
import org.jeecg.common.exception.JeecgSqlInjectionException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -17,6 +18,12 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SqlInjectionUtil {
|
public class SqlInjectionUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql注入黑名单数据库名
|
||||||
|
*/
|
||||||
|
public final static String XSS_STR_TABLE = "peformance_schema|information_schema";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认—sql注入关键词
|
* 默认—sql注入关键词
|
||||||
*/
|
*/
|
||||||
@ -168,6 +175,27 @@ public class SqlInjectionUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否存在SQL注入关键词字符串
|
||||||
|
*
|
||||||
|
* @param keyword
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("AlibabaUndefineMagicConstant")
|
||||||
|
private static boolean isExistSqlInjectTableKeyword(String sql, String keyword) {
|
||||||
|
// 需要匹配的,sql注入关键词
|
||||||
|
String[] matchingTexts = new String[]{"`" + keyword, "(" + keyword, "(`" + keyword};
|
||||||
|
for (String matchingText : matchingTexts) {
|
||||||
|
String[] checkTexts = new String[]{" " + matchingText, "from" + matchingText};
|
||||||
|
for (String checkText : checkTexts) {
|
||||||
|
if (sql.contains(checkText)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sql注入过滤处理,遇到注入关键字抛异常
|
* sql注入过滤处理,遇到注入关键字抛异常
|
||||||
*
|
*
|
||||||
@ -208,6 +236,14 @@ public class SqlInjectionUtil {
|
|||||||
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String[] xssTableArr = XSS_STR_TABLE.split("\\|");
|
||||||
|
for (String xssTableStr : xssTableArr) {
|
||||||
|
if (isExistSqlInjectTableKeyword(value, xssTableStr)) {
|
||||||
|
log.error(SqlInjectionUtil.SQL_INJECTION_KEYWORD_TIP, xssTableStr);
|
||||||
|
log.error(SqlInjectionUtil.SQL_INJECTION_TIP_VARIABLE, value);
|
||||||
|
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 三、SQL注入检测存在绕过风险 (正则校验)
|
// 三、SQL注入检测存在绕过风险 (正则校验)
|
||||||
for (String regularOriginal : XSS_REGULAR_STR_ARRAY) {
|
for (String regularOriginal : XSS_REGULAR_STR_ARRAY) {
|
||||||
@ -244,6 +280,14 @@ public class SqlInjectionUtil {
|
|||||||
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String[] xssTableArr = XSS_STR_TABLE.split("\\|");
|
||||||
|
for (String xssTableStr : xssTableArr) {
|
||||||
|
if (isExistSqlInjectTableKeyword(value, xssTableStr)) {
|
||||||
|
log.error(SqlInjectionUtil.SQL_INJECTION_KEYWORD_TIP, xssTableStr);
|
||||||
|
log.error(SqlInjectionUtil.SQL_INJECTION_TIP_VARIABLE, value);
|
||||||
|
throw new JeecgSqlInjectionException(SqlInjectionUtil.SQL_INJECTION_TIP + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 三、SQL注入检测存在绕过风险 (正则校验)
|
// 三、SQL注入检测存在绕过风险 (正则校验)
|
||||||
for (String regularOriginal : XSS_REGULAR_STR_ARRAY) {
|
for (String regularOriginal : XSS_REGULAR_STR_ARRAY) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package org.jeecg.common.util.encryption;
|
package org.jeecg.common.util.encryption;
|
||||||
|
|
||||||
import org.apache.shiro.lang.codec.Base64;
|
import org.apache.shiro.codec.Base64;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package org.jeecg.common.util.security;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.exception.JeecgSqlInjectionException;
|
import org.jeecg.common.exception.JeecgSqlInjectionException;
|
||||||
|
import org.jeecg.common.util.SqlInjectionUtil;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -66,6 +68,8 @@ public abstract class AbstractQueryBlackListHandler {
|
|||||||
if(flag == false){
|
if(flag == false){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Set<String> xssTableSet = new HashSet<>(Arrays.asList(SqlInjectionUtil.XSS_STR_TABLE.split("\\|")));
|
||||||
|
|
||||||
for (QueryTable table : list) {
|
for (QueryTable table : list) {
|
||||||
String name = table.getName();
|
String name = table.getName();
|
||||||
String fieldRule = ruleMap.get(name);
|
String fieldRule = ruleMap.get(name);
|
||||||
@ -81,6 +85,16 @@ public abstract class AbstractQueryBlackListHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// 判断是否调用了黑名单数据库
|
||||||
|
String dbName = table.getDbName();
|
||||||
|
if (oConvertUtils.isNotEmpty(dbName)) {
|
||||||
|
dbName = dbName.toLowerCase().trim();
|
||||||
|
if (xssTableSet.contains(dbName)) {
|
||||||
|
flag = false;
|
||||||
|
log.warn("sql黑名单校验,数据库【" + dbName + "】禁止查询");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回黑名单校验结果(不合法直接抛出异常)
|
// 返回黑名单校验结果(不合法直接抛出异常)
|
||||||
@ -135,6 +149,8 @@ public abstract class AbstractQueryBlackListHandler {
|
|||||||
* 查询的表的信息
|
* 查询的表的信息
|
||||||
*/
|
*/
|
||||||
protected class QueryTable {
|
protected class QueryTable {
|
||||||
|
//数据库名
|
||||||
|
private String dbName;
|
||||||
//表名
|
//表名
|
||||||
private String name;
|
private String name;
|
||||||
//表的别名
|
//表的别名
|
||||||
@ -158,6 +174,14 @@ public abstract class AbstractQueryBlackListHandler {
|
|||||||
this.fields.add(field);
|
this.fields.add(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDbName() {
|
||||||
|
return dbName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDbName(String dbName) {
|
||||||
|
this.dbName = dbName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,17 +11,16 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
import io.micrometer.prometheus.PrometheusMeterRegistry;
|
import io.micrometer.prometheus.PrometheusMeterRegistry;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.http.CacheControl;
|
import org.springframework.http.CacheControl;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
@ -59,6 +58,14 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private PrometheusMeterRegistry prometheusMeterRegistry;
|
private PrometheusMeterRegistry prometheusMeterRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meterRegistryPostProcessor
|
||||||
|
* for [QQYUN-12558]【监控】系统监控的头两个tab不好使,接口404
|
||||||
|
*/
|
||||||
|
@Autowired(required = false)
|
||||||
|
@Qualifier("meterRegistryPostProcessor")
|
||||||
|
private BeanPostProcessor meterRegistryPostProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态资源的配置 - 使得可以从磁盘中读取 Html、图片、视频、音频等
|
* 静态资源的配置 - 使得可以从磁盘中读取 Html、图片、视频、音频等
|
||||||
*/
|
*/
|
||||||
@ -147,12 +154,17 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解决metrics端点不显示jvm信息的问题(zyf)
|
* 监听应用启动完成事件,确保 PrometheusMeterRegistry 已经初始化
|
||||||
|
* for [QQYUN-12558]【监控】系统监控的头两个tab不好使,接口404
|
||||||
|
* @param event
|
||||||
|
* @author chenrui
|
||||||
|
* @date 2025/5/26 16:46
|
||||||
*/
|
*/
|
||||||
@Bean
|
@EventListener
|
||||||
@ConditionalOnBean(name = "meterRegistryPostProcessor")
|
public void onApplicationReady(ApplicationReadyEvent event) {
|
||||||
InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor) {
|
if(null != meterRegistryPostProcessor){
|
||||||
return () -> meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "");
|
meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
springdoc.auto-tag-classes: false
|
springdoc.auto-tag-classes: false
|
||||||
springdoc.packages-to-scan: org.jeecg
|
springdoc.packages-to-scan: org.jeecg
|
||||||
|
springdoc.default-flat-param-object: true
|
||||||
@ -24,6 +24,12 @@
|
|||||||
<artifactId>hibernate-re</artifactId>
|
<artifactId>hibernate-re</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- AI大模型管理 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jeecg-boot-module-airag</artifactId>
|
||||||
|
<version>${jeecgboot.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 企业微信/钉钉 api -->
|
<!-- 企业微信/钉钉 api -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework</groupId>
|
<groupId>org.jeecgframework</groupId>
|
||||||
|
|||||||
@ -19,6 +19,21 @@ public class CustomInMemoryHttpTraceRepository extends InMemoryHttpTraceReposito
|
|||||||
return super.findAll();
|
return super.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for [issues/8309]系统监控>请求追踪,列表每刷新一下,总数据就减一#8309
|
||||||
|
* @param trace
|
||||||
|
* @author chenrui
|
||||||
|
* @date 2025/6/4 19:38
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void add(HttpTrace trace) {
|
||||||
|
// 只有当请求不是OPTIONS方法,并且URI不包含httptrace时才记录数据
|
||||||
|
if (!"OPTIONS".equals(trace.getRequest().getMethod()) &&
|
||||||
|
!trace.getRequest().getUri().toString().contains("httptrace")) {
|
||||||
|
super.add(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<HttpTrace> findAll(String query) {
|
public List<HttpTrace> findAll(String query) {
|
||||||
List<HttpTrace> allTrace = super.findAll();
|
List<HttpTrace> allTrace = super.findAll();
|
||||||
if (null != allTrace && !allTrace.isEmpty()) {
|
if (null != allTrace && !allTrace.isEmpty()) {
|
||||||
|
|||||||
@ -162,7 +162,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
|
|||||||
String method = openApi.getRequestMethod();
|
String method = openApi.getRequestMethod();
|
||||||
String appkey = request.getHeader("appkey");
|
String appkey = request.getHeader("appkey");
|
||||||
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
|
OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey);
|
||||||
SysUser systemUser = sysUserService.getById(openApiAuth.getSystemUserId());
|
SysUser systemUser = sysUserService.getUserByName(openApiAuth.getCreateBy());
|
||||||
String token = this.getToken(systemUser.getUsername(), systemUser.getPassword());
|
String token = this.getToken(systemUser.getUsername(), systemUser.getPassword());
|
||||||
httpHeaders.put("X-Access-Token", Lists.newArrayList(token));
|
httpHeaders.put("X-Access-Token", Lists.newArrayList(token));
|
||||||
httpHeaders.put("Content-Type",Lists.newArrayList("application/json"));
|
httpHeaders.put("Content-Type",Lists.newArrayList("application/json"));
|
||||||
|
|||||||
@ -1,35 +1,22 @@
|
|||||||
package org.jeecg.modules.openapi.controller;
|
package org.jeecg.modules.openapi.controller;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
import org.jeecg.common.system.base.controller.JeecgController;
|
||||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||||
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/openapi/permission")
|
@RequestMapping("/openapi/permission")
|
||||||
public class OpenApiPermissionController extends JeecgController<OpenApiPermission, OpenApiPermissionService> {
|
public class OpenApiPermissionController extends JeecgController<OpenApiPermission, OpenApiPermissionService> {
|
||||||
|
|
||||||
@PostMapping("add")
|
@PostMapping("add")
|
||||||
public Result add(@RequestBody OpenApiPermission openApiPermission) {
|
public Result add(@RequestBody OpenApiPermission openApiPermission) {
|
||||||
List<String> list = Arrays.asList(openApiPermission.getApiId().split(","));
|
service.add(openApiPermission);
|
||||||
if (CollectionUtil.isNotEmpty(list)) {
|
|
||||||
list.forEach(l->{
|
|
||||||
OpenApiPermission saveApiPermission = new OpenApiPermission();
|
|
||||||
saveApiPermission.setApiId(l);
|
|
||||||
saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId());
|
|
||||||
service.save(saveApiPermission);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Result.ok("保存成功");
|
return Result.ok("保存成功");
|
||||||
}
|
}
|
||||||
@GetMapping("/list")
|
@GetMapping("/getOpenApi")
|
||||||
public Result list( String apiAuthId) {
|
public Result<?> getOpenApi( String apiAuthId) {
|
||||||
return Result.ok(service.list(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId,apiAuthId)));
|
return service.getOpenApi(apiAuthId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,4 +97,9 @@ public class OpenApi implements Serializable {
|
|||||||
* 更新时间
|
* 更新时间
|
||||||
*/
|
*/
|
||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
|
/**
|
||||||
|
* 历史已选接口
|
||||||
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String ifCheckBox = "0";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package org.jeecg.modules.openapi.service;
|
package org.jeecg.modules.openapi.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -10,4 +12,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface OpenApiPermissionService extends IService<OpenApiPermission> {
|
public interface OpenApiPermissionService extends IService<OpenApiPermission> {
|
||||||
List<OpenApiPermission> findByAuthId(String authId);
|
List<OpenApiPermission> findByAuthId(String authId);
|
||||||
|
|
||||||
|
Result<?> getOpenApi(String apiAuthId);
|
||||||
|
|
||||||
|
void add(OpenApiPermission openApiPermission);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,67 @@
|
|||||||
package org.jeecg.modules.openapi.service.impl;
|
package org.jeecg.modules.openapi.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.openapi.entity.OpenApi;
|
||||||
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
import org.jeecg.modules.openapi.entity.OpenApiPermission;
|
||||||
import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper;
|
import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper;
|
||||||
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
import org.jeecg.modules.openapi.service.OpenApiPermissionService;
|
||||||
|
import org.jeecg.modules.openapi.service.OpenApiService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.Collections;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @date 2024/12/19 17:44
|
* @date 2024/12/19 17:44
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class OpenApiPermissionServiceImpl extends ServiceImpl<OpenApiPermissionMapper, OpenApiPermission> implements OpenApiPermissionService {
|
public class OpenApiPermissionServiceImpl extends ServiceImpl<OpenApiPermissionMapper, OpenApiPermission> implements OpenApiPermissionService {
|
||||||
|
@Resource
|
||||||
|
private OpenApiService openApiService;
|
||||||
@Override
|
@Override
|
||||||
public List<OpenApiPermission> findByAuthId(String authId) {
|
public List<OpenApiPermission> findByAuthId(String authId) {
|
||||||
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId));
|
return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result<?> getOpenApi(String apiAuthId) {
|
||||||
|
List<OpenApi> openApis = openApiService.list();
|
||||||
|
if (CollectionUtil.isEmpty(openApis)) {
|
||||||
|
return Result.error("接口不存在");
|
||||||
|
}
|
||||||
|
List<OpenApiPermission> openApiPermissions = baseMapper.selectList(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId, apiAuthId));
|
||||||
|
if (CollectionUtil.isNotEmpty(openApiPermissions)) {
|
||||||
|
Map<String, OpenApi> openApiMap = openApis.stream().collect(Collectors.toMap(OpenApi::getId, o -> o));
|
||||||
|
for (OpenApiPermission openApiPermission : openApiPermissions) {
|
||||||
|
OpenApi openApi = openApiMap.get(openApiPermission.getApiId());
|
||||||
|
if (openApi!=null) {
|
||||||
|
openApi.setIfCheckBox("1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.ok(openApis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(OpenApiPermission openApiPermission) {
|
||||||
|
this.remove(Wrappers.<OpenApiPermission>lambdaQuery().eq(OpenApiPermission::getApiAuthId, openApiPermission.getApiAuthId()));
|
||||||
|
List<String> list = Arrays.asList(openApiPermission.getApiId().split(","));
|
||||||
|
if (CollectionUtil.isNotEmpty(list)) {
|
||||||
|
list.forEach(l->{
|
||||||
|
if (StrUtil.isNotEmpty(l)){
|
||||||
|
OpenApiPermission saveApiPermission = new OpenApiPermission();
|
||||||
|
saveApiPermission.setApiId(l);
|
||||||
|
saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId());
|
||||||
|
this.save(saveApiPermission);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,13 +25,6 @@
|
|||||||
<version>${jeecgboot.version}</version>
|
<version>${jeecgboot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- AI大模型管理 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
|
||||||
<artifactId>jeecg-boot-module-airag</artifactId>
|
|
||||||
<version>${jeecgboot.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- flyway 数据库自动升级 -->
|
<!-- flyway 数据库自动升级 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.flywaydb</groupId>
|
<groupId>org.flywaydb</groupId>
|
||||||
|
|||||||
@ -40,8 +40,8 @@ public class JeecgSystemApplication extends SpringBootServletInitializer {
|
|||||||
String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
|
String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
|
||||||
log.info("\n----------------------------------------------------------\n\t" +
|
log.info("\n----------------------------------------------------------\n\t" +
|
||||||
"Application Jeecg-Boot is running! Access URLs:\n\t" +
|
"Application Jeecg-Boot is running! Access URLs:\n\t" +
|
||||||
"Local: \t\thttp://localhost:" + port + path + "/\n\t" +
|
"Local: \t\thttp://localhost:" + port + path + "/doc.html\n\t" +
|
||||||
"External: \thttp://" + ip + ":" + port + path + "/\n\t" +
|
"External: \thttp://" + ip + ":" + port + path + "/doc.html\n\t" +
|
||||||
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
|
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
|
||||||
"----------------------------------------------------------");
|
"----------------------------------------------------------");
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,95 @@
|
|||||||
|
package org.jeecg.modules.openapi.test;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.methods.*;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class SampleOpenApiTest {
|
||||||
|
private final String base_url = "http://localhost:8080/jeecg-boot";
|
||||||
|
private final String appKey = "ak-pFjyNHWRsJEFWlu6";
|
||||||
|
private final String searchKey = "4hV5dBrZtmGAtPdbA5yseaeKRYNpzGsS";
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
// 根据部门ID查询用户
|
||||||
|
String url = base_url+"/openapi/call/TEwcXBlr?id=6d35e179cd814e3299bd588ea7daed3f";
|
||||||
|
JSONObject header = genTimestampAndSignature();
|
||||||
|
HttpGet httpGet = new HttpGet(url);
|
||||||
|
// 设置请求头
|
||||||
|
httpGet.setHeader("Content-Type", "application/json");
|
||||||
|
httpGet.setHeader("appkey",appKey);
|
||||||
|
httpGet.setHeader("signature",header.get("signature").toString());
|
||||||
|
httpGet.setHeader("timestamp",header.get("timestamp").toString());
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||||
|
CloseableHttpResponse response = httpClient.execute(httpGet);) {
|
||||||
|
// 获取响应状态码
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
System.out.println("[debug] 响应状态码: " + statusCode);
|
||||||
|
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
System.out.println(entity);
|
||||||
|
// 获取响应内容
|
||||||
|
String responseBody = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("[debug] 响应内容: " + responseBody);
|
||||||
|
|
||||||
|
// 解析JSON响应
|
||||||
|
JSONObject res = JSON.parseObject(responseBody);
|
||||||
|
//错误日志判断
|
||||||
|
if(res.containsKey("success")){
|
||||||
|
Boolean success = res.getBoolean("success");
|
||||||
|
if(success){
|
||||||
|
System.out.println("[info] 调用成功: " + res.toJSONString());
|
||||||
|
}else{
|
||||||
|
System.out.println("[error] 调用失败: " + res.getString("message"));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
System.out.println("[error] 调用失败: " + res.getString("message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private JSONObject genTimestampAndSignature(){
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
jsonObject.put("timestamp",timestamp);
|
||||||
|
jsonObject.put("signature", md5(appKey + searchKey + timestamp));
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成md5
|
||||||
|
* @param sourceStr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected String md5(String sourceStr) {
|
||||||
|
String result = "";
|
||||||
|
try {
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
|
md.update(sourceStr.getBytes("utf-8"));
|
||||||
|
byte[] hash = md.digest();
|
||||||
|
int i;
|
||||||
|
StringBuffer buf = new StringBuffer(32);
|
||||||
|
for (int offset = 0; offset < hash.length; offset++) {
|
||||||
|
i = hash[offset];
|
||||||
|
if (i < 0) {
|
||||||
|
i += 256;
|
||||||
|
}
|
||||||
|
if (i < 16) {
|
||||||
|
buf.append("0");
|
||||||
|
}
|
||||||
|
buf.append(Integer.toHexString(i));
|
||||||
|
}
|
||||||
|
result = buf.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("sign签名错误", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -56,8 +56,8 @@
|
|||||||
<dm8.version>8.1.1.49</dm8.version>
|
<dm8.version>8.1.1.49</dm8.version>
|
||||||
|
|
||||||
<!-- 积木报表-->
|
<!-- 积木报表-->
|
||||||
<jimureport-spring-boot-starter.version>1.9.5.1</jimureport-spring-boot-starter.version>
|
<jimureport-spring-boot-starter.version>2.0.0</jimureport-spring-boot-starter.version>
|
||||||
<minidao.version>1.10.7</minidao.version>
|
<minidao.version>1.10.10</minidao.version>
|
||||||
<!-- 持久层 -->
|
<!-- 持久层 -->
|
||||||
<mybatis-plus.version>3.5.3.2</mybatis-plus.version>
|
<mybatis-plus.version>3.5.3.2</mybatis-plus.version>
|
||||||
<dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version>
|
<dynamic-datasource-spring-boot-starter.version>4.1.3</dynamic-datasource-spring-boot-starter.version>
|
||||||
@ -68,7 +68,7 @@
|
|||||||
<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
|
<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
|
||||||
<aliyun.oss.version>3.11.2</aliyun.oss.version>
|
<aliyun.oss.version>3.11.2</aliyun.oss.version>
|
||||||
<!-- shiro -->
|
<!-- shiro -->
|
||||||
<shiro.version>2.0.4</shiro.version>
|
<shiro.version>1.13.0</shiro.version>
|
||||||
<shiro-redis.version>3.2.3</shiro-redis.version>
|
<shiro-redis.version>3.2.3</shiro-redis.version>
|
||||||
<java-jwt.version>4.5.0</java-jwt.version>
|
<java-jwt.version>4.5.0</java-jwt.version>
|
||||||
<codegenerate.version>1.4.9</codegenerate.version>
|
<codegenerate.version>1.4.9</codegenerate.version>
|
||||||
|
|||||||
1
jeecgboot-vue3/.gitignore
vendored
1
jeecgboot-vue3/.gitignore
vendored
@ -2,7 +2,6 @@ node_modules
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.github
|
.github
|
||||||
dist
|
dist
|
||||||
.npmrc
|
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
tests/server/static
|
tests/server/static
|
||||||
|
|||||||
2
jeecgboot-vue3/.npmrc
Normal file
2
jeecgboot-vue3/.npmrc
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
shamefully-hoist=true
|
||||||
|
strict-peer-dependencies=false
|
||||||
@ -78,8 +78,9 @@
|
|||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"vue-types": "^5.1.3",
|
"vue-types": "^5.1.3",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vxe-table": "4.6.17",
|
"vxe-table": "4.13.31",
|
||||||
"vxe-table-plugin-antd": "4.0.7",
|
"vxe-table-plugin-antd": "4.0.8",
|
||||||
|
"vxe-pc-ui": "4.6.12",
|
||||||
"xe-utils": "3.5.26",
|
"xe-utils": "3.5.26",
|
||||||
"xss": "^1.0.15"
|
"xss": "^1.0.15"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-upload name="file" :showUploadList="false" :customRequest="(file) => onClick(file)">
|
<a-upload name="file" :showUploadList="false" :customRequest="(file) => onClick(file)">
|
||||||
<Button :type="type" :class="getButtonClass">
|
<Button :type="type" :class="getButtonClass" :disabled="props.disabled">
|
||||||
<template #default="data">
|
<template #default="data">
|
||||||
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
||||||
<slot v-bind="data || {}"></slot>
|
<slot v-bind="data || {}"></slot>
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
//下拉框选项值
|
//下拉框选项值
|
||||||
const selectOptions = ref<SelectValue>([]);
|
const selectOptions = ref<SelectValue>([]);
|
||||||
//下拉框选中值
|
//下拉框选中值
|
||||||
let selectValues = reactive<object>({
|
let selectValues = reactive<any>({
|
||||||
value: [],
|
value: [],
|
||||||
change: false,
|
change: false,
|
||||||
});
|
});
|
||||||
@ -74,7 +74,15 @@
|
|||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
() => {
|
() => {
|
||||||
props.value && initValue();
|
if (props.value) {
|
||||||
|
initValue();
|
||||||
|
} else {
|
||||||
|
// update-begin--author:liaozhiyang---date:20250604---for:【issues/8233】resetFields时无法重置
|
||||||
|
if (selectValues.value?.length) {
|
||||||
|
selectValues.value = [];
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20250604---for:【issues/8233】resetFields时无法重置
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import type { Ref } from 'vue';
|
|||||||
import { inject, reactive, ref, computed, unref, watch, nextTick } from 'vue';
|
import { inject, reactive, ref, computed, unref, watch, nextTick } from 'vue';
|
||||||
import { TreeActionType } from '/@/components/Tree';
|
import { TreeActionType } from '/@/components/Tree';
|
||||||
import { listToTree } from '/@/utils/common/compUtils';
|
import { listToTree } from '/@/utils/common/compUtils';
|
||||||
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export function useTreeBiz(treeRef, getList, props, realProps, emit) {
|
export function useTreeBiz(treeRef, getList, props, realProps, emit) {
|
||||||
//接收下拉框选项
|
//接收下拉框选项
|
||||||
@ -22,7 +23,7 @@ export function useTreeBiz(treeRef, getList, props, realProps, emit) {
|
|||||||
const getCheckStrictly = computed(() => (realProps.multiple ? props.checkStrictly : true));
|
const getCheckStrictly = computed(() => (realProps.multiple ? props.checkStrictly : true));
|
||||||
// 是否是首次加载回显,只有首次加载,才会显示 loading
|
// 是否是首次加载回显,只有首次加载,才会显示 loading
|
||||||
let isFirstLoadEcho = true;
|
let isFirstLoadEcho = true;
|
||||||
|
let prevSelectValues = [];
|
||||||
/**
|
/**
|
||||||
* 监听selectValues变化
|
* 监听selectValues变化
|
||||||
*/
|
*/
|
||||||
@ -32,12 +33,17 @@ export function useTreeBiz(treeRef, getList, props, realProps, emit) {
|
|||||||
if(!values){
|
if(!values){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (openModal.value == false && values.length > 0) {
|
// update-begin--author:liaozhiyang---date:20250604---for:【issues/8232】代码设置JSelectDept组件值没翻译
|
||||||
|
if (values.length > 0) {
|
||||||
|
// 防止多次请求
|
||||||
|
if (isEqual(values, prevSelectValues)) return;
|
||||||
|
prevSelectValues = values;
|
||||||
loadingEcho.value = isFirstLoadEcho;
|
loadingEcho.value = isFirstLoadEcho;
|
||||||
isFirstLoadEcho = false;
|
isFirstLoadEcho = false;
|
||||||
onLoadData(null, values.join(',')).finally(() => {
|
onLoadData(null, values.join(',')).finally(() => {
|
||||||
loadingEcho.value = false;
|
loadingEcho.value = false;
|
||||||
});
|
});
|
||||||
|
// update-end--author:liaozhiyang---date:20250604---for:【issues/8232】代码设置JSelectDept组件值没翻译
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|||||||
@ -222,7 +222,7 @@
|
|||||||
// update-end--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
|
// update-end--author:sunjianlei---date:220230630---for:【QQYUN-5571】自封装选择列,解决数据行选择卡顿问题
|
||||||
);
|
);
|
||||||
|
|
||||||
const { getScrollRef, redoHeight } = useTableScroll(getProps, tableElRef, getColumnsRef, getRowSelectionRef, getDataSourceRef, slots);
|
const { getScrollRef, redoHeight } = useTableScroll(getProps, tableElRef, getColumnsRef, getRowSelectionRef, getDataSourceRef, slots, getPaginationInfo);
|
||||||
|
|
||||||
const { customRow } = useCustomRow(getProps, {
|
const { customRow } = useCustomRow(getProps, {
|
||||||
setSelectedRowKeys,
|
setSelectedRowKeys,
|
||||||
|
|||||||
@ -15,7 +15,8 @@ export function useTableScroll(
|
|||||||
columnsRef: ComputedRef<BasicColumn[]>,
|
columnsRef: ComputedRef<BasicColumn[]>,
|
||||||
rowSelectionRef: ComputedRef<TableRowSelection<any> | null>,
|
rowSelectionRef: ComputedRef<TableRowSelection<any> | null>,
|
||||||
getDataSourceRef: ComputedRef<Recordable[]>,
|
getDataSourceRef: ComputedRef<Recordable[]>,
|
||||||
slots: Slots
|
slots: Slots,
|
||||||
|
getPaginationInfo: ComputedRef<any>
|
||||||
) {
|
) {
|
||||||
const tableHeightRef: Ref<Nullable<number>> = ref(null);
|
const tableHeightRef: Ref<Nullable<number>> = ref(null);
|
||||||
|
|
||||||
@ -144,6 +145,27 @@ export function useTableScroll(
|
|||||||
setHeight(height);
|
setHeight(height);
|
||||||
|
|
||||||
bodyEl!.style.height = `${height}px`;
|
bodyEl!.style.height = `${height}px`;
|
||||||
|
// update-begin--author:liaozhiyang---date:20240609---for【issues/8374】分页始终显示在底部
|
||||||
|
if (maxHeight === undefined) {
|
||||||
|
if (unref(getPaginationInfo) && unref(getDataSourceRef).length) {
|
||||||
|
const pageSize = unref(getPaginationInfo)?.pageSize;
|
||||||
|
const current = unref(getPaginationInfo)?.current;
|
||||||
|
const total = unref(getPaginationInfo)?.total;
|
||||||
|
const tableBody = tableEl.querySelector('.ant-table-body') as HTMLElement;
|
||||||
|
const tr = tableEl.querySelector('.ant-table-tbody')?.children ?? [];
|
||||||
|
const lastrEl = tr[tr.length - 1] as HTMLElement;
|
||||||
|
const trHeight = lastrEl.offsetHeight;
|
||||||
|
const dataHeight = trHeight * pageSize;
|
||||||
|
if (tableBody && lastrEl) {
|
||||||
|
if (current === 1 && pageSize > unref(getDataSourceRef).length && total <= pageSize) {
|
||||||
|
tableBody.style.height = `${height}px`;
|
||||||
|
} else {
|
||||||
|
tableBody.style.height = `${dataHeight < height ? dataHeight : height}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update-end--author:liaozhiyang---date:20240609---for【issues/8374】分页始终显示在底部
|
||||||
}
|
}
|
||||||
useWindowSizeFn(calcTableHeight, 280);
|
useWindowSizeFn(calcTableHeight, 280);
|
||||||
onMountedOrActivated(() => {
|
onMountedOrActivated(() => {
|
||||||
|
|||||||
@ -28,7 +28,9 @@ export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods:
|
|||||||
// update-begin--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新
|
// update-begin--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新
|
||||||
// linkageConfig变化时也需要执行
|
// linkageConfig变化时也需要执行
|
||||||
const linkageConfig = toRaw(props.linkageConfig);
|
const linkageConfig = toRaw(props.linkageConfig);
|
||||||
console.log(linkageConfig);
|
if (linkageConfig) {
|
||||||
|
// console.log(linkageConfig);
|
||||||
|
}
|
||||||
// update-end--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新
|
// update-end--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新
|
||||||
let columns: JVxeColumn[] = [];
|
let columns: JVxeColumn[] = [];
|
||||||
if (isArray(props.columns)) {
|
if (isArray(props.columns)) {
|
||||||
|
|||||||
@ -18,10 +18,10 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
|
|||||||
// rowId: props.rowKey,
|
// rowId: props.rowKey,
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
keyField: props.rowKey,
|
keyField: props.rowKey,
|
||||||
|
// 高亮hover的行
|
||||||
|
isHover: true,
|
||||||
},
|
},
|
||||||
// update-end--author:liaozhiyang---date:20240607---for:【TV360X-327】vxetable警告
|
// update-end--author:liaozhiyang---date:20240607---for:【TV360X-327】vxetable警告
|
||||||
// 高亮hover的行
|
|
||||||
highlightHoverRow: true,
|
|
||||||
|
|
||||||
// --- 【issues/209】自带的tooltip会错位,所以替换成原生的title ---
|
// --- 【issues/209】自带的tooltip会错位,所以替换成原生的title ---
|
||||||
// 溢出隐藏并显示tooltip
|
// 溢出隐藏并显示tooltip
|
||||||
@ -43,6 +43,7 @@ export function useData(props: JVxeTableProps): JVxeDataProps {
|
|||||||
expandConfig: {
|
expandConfig: {
|
||||||
iconClose: 'vxe-icon-arrow-right',
|
iconClose: 'vxe-icon-arrow-right',
|
||||||
iconOpen: 'vxe-icon-arrow-down',
|
iconOpen: 'vxe-icon-arrow-down',
|
||||||
|
...props.expandConfig,
|
||||||
},
|
},
|
||||||
// 虚拟滚动配置,y轴大于xx条数据时启用虚拟滚动
|
// 虚拟滚动配置,y轴大于xx条数据时启用虚拟滚动
|
||||||
scrollY: {
|
scrollY: {
|
||||||
|
|||||||
@ -23,7 +23,12 @@ export function useDragSort(props: JVxeTableProps, methods: JVxeTableMethods) {
|
|||||||
function createSortable() {
|
function createSortable() {
|
||||||
let xTable = methods.getXTable();
|
let xTable = methods.getXTable();
|
||||||
// let dom = xTable.$el.querySelector('.vxe-table--fixed-wrapper .vxe-table--body tbody')
|
// let dom = xTable.$el.querySelector('.vxe-table--fixed-wrapper .vxe-table--body tbody')
|
||||||
let dom = xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody');
|
// let dom = xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody');
|
||||||
|
let dom = xTable.$el.querySelector('.vxe-table--body-inner-wrapper > .vxe-table--body tbody');
|
||||||
|
if (!dom) {
|
||||||
|
console.warn('[JVxeTable] 拖拽排序初始化失败,可能是vxe-table升级导致的版本不兼容。');
|
||||||
|
return;
|
||||||
|
}
|
||||||
let startChildren = [];
|
let startChildren = [];
|
||||||
sortable2 = Sortable.create(dom as HTMLElement, {
|
sortable2 = Sortable.create(dom as HTMLElement, {
|
||||||
handle: '.drag-btn',
|
handle: '.drag-btn',
|
||||||
|
|||||||
@ -424,12 +424,13 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
|
|||||||
let xTable = getXTable();
|
let xTable = getXTable();
|
||||||
let { setActive, index } = options;
|
let { setActive, index } = options;
|
||||||
index = index === -1 ? index : xTable.internalData.tableFullData[index];
|
index = index === -1 ? index : xTable.internalData.tableFullData[index];
|
||||||
|
index = index == null ? -1 : index;
|
||||||
// 插入行
|
// 插入行
|
||||||
let result = await xTable.insertAt(rows, index);
|
let result = await xTable.insertAt(rows, index);
|
||||||
if (setActive) {
|
if (setActive) {
|
||||||
// -update-begin--author:liaozhiyang---date:20240619---for:【TV360X-1404】vxetable警告
|
// -update-begin--author:liaozhiyang---date:20240619---for:【TV360X-1404】vxetable警告
|
||||||
// 激活最后一行的编辑模式
|
// 激活最后一行的编辑模式
|
||||||
xTable.setEditRow(result.rows[result.rows.length - 1]);
|
xTable.setEditRow(result.rows[result.rows.length - 1], true);
|
||||||
// -update-end--author:liaozhiyang---date:20240619---for:【TV360X-1404】vxetable警告
|
// -update-end--author:liaozhiyang---date:20240619---for:【TV360X-1404】vxetable警告
|
||||||
}
|
}
|
||||||
await recalcSortNumber();
|
await recalcSortNumber();
|
||||||
@ -763,7 +764,7 @@ export function useMethods(props: JVxeTableProps, { emit }, data: JVxeDataProps,
|
|||||||
// 4.1.0
|
// 4.1.0
|
||||||
//await xTable.updateCache();
|
//await xTable.updateCache();
|
||||||
// 4.1.1
|
// 4.1.1
|
||||||
await xTable.cacheRowMap()
|
await xTable.cacheRowMap(true)
|
||||||
// update-end--author:liaozhiyang---date:20231011---for:【QQYUN-5133】JVxeTable 行编辑升级
|
// update-end--author:liaozhiyang---date:20231011---for:【QQYUN-5133】JVxeTable 行编辑升级
|
||||||
return await xTable.updateData();
|
return await xTable.updateData();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
// 引入 vxe-table
|
// 引入 vxe-table
|
||||||
import 'xe-utils';
|
import 'xe-utils';
|
||||||
|
import VxeUIAll from 'vxe-pc-ui';
|
||||||
import VXETable /*Grid*/ from 'vxe-table';
|
import VXETable /*Grid*/ from 'vxe-table';
|
||||||
import VXETablePluginAntd from 'vxe-table-plugin-antd';
|
import VXETablePluginAntd from 'vxe-table-plugin-antd';
|
||||||
|
import 'vxe-pc-ui/lib/style.css';
|
||||||
import 'vxe-table/lib/style.css';
|
import 'vxe-table/lib/style.css';
|
||||||
|
|
||||||
import JVxeTable from './JVxeTable';
|
import JVxeTable from './JVxeTable';
|
||||||
@ -27,6 +29,7 @@ export function registerJVxeTable(app: App) {
|
|||||||
// 注册自定义组件
|
// 注册自定义组件
|
||||||
registerAllComponent();
|
registerAllComponent();
|
||||||
// 执行注册方法
|
// 执行注册方法
|
||||||
|
app.use(VxeUIAll);
|
||||||
app.use(VXETable, VXETableSettings);
|
app.use(VXETable, VXETableSettings);
|
||||||
app.component('JVxeTable', JVxeTable);
|
app.component('JVxeTable', JVxeTable);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
const checkedKeys = ref<Array<string | number>>([]);
|
const checkedKeys = ref<Array<string | number>>([]);
|
||||||
|
|
||||||
const logColumns = ref<any>(columns);
|
const logColumns = ref<any>(exceptionColumns);
|
||||||
const searchSchema = ref<any>(searchFormSchema);
|
const searchSchema = ref<any>(searchFormSchema);
|
||||||
const searchInfo = { logType: '4' };
|
const searchInfo = { logType: '4' };
|
||||||
// 列表页面公共参数、方法
|
// 列表页面公共参数、方法
|
||||||
|
|||||||
@ -26,11 +26,11 @@ export const columns: BasicColumn[] = [
|
|||||||
align:"center",
|
align:"center",
|
||||||
dataIndex: 'blackList'
|
dataIndex: 'blackList'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '状态',
|
// title: '状态',
|
||||||
align:"center",
|
// align:"center",
|
||||||
dataIndex: 'status'
|
// dataIndex: 'status'
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: '创建人',
|
title: '创建人',
|
||||||
align:"center",
|
align:"center",
|
||||||
@ -67,6 +67,11 @@ export const formSchema: FormSchema[] = [
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '原始地址',
|
||||||
|
field: 'originUrl',
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '请求方法',
|
label: '请求方法',
|
||||||
field: 'requestMethod',
|
field: 'requestMethod',
|
||||||
@ -127,11 +132,6 @@ export const formSchema: FormSchema[] = [
|
|||||||
component:"Input",
|
component:"Input",
|
||||||
field: 'body'
|
field: 'body'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '原始地址',
|
|
||||||
field: 'originUrl',
|
|
||||||
component: 'Input',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '删除标识',
|
label: '删除标识',
|
||||||
field: 'delFlag',
|
field: 'delFlag',
|
||||||
@ -252,7 +252,6 @@ export const openApiHeaderJVxeColumns: JVxeColumn[] = [
|
|||||||
title: '备注',
|
title: '备注',
|
||||||
key: 'note',
|
key: 'note',
|
||||||
type: JVxeTypes.input,
|
type: JVxeTypes.input,
|
||||||
width:"200px",
|
|
||||||
placeholder: '请输入${title}',
|
placeholder: '请输入${title}',
|
||||||
defaultValue:'',
|
defaultValue:'',
|
||||||
},
|
},
|
||||||
@ -297,7 +296,6 @@ export const openApiParamJVxeColumns: JVxeColumn[] = [
|
|||||||
title: '备注',
|
title: '备注',
|
||||||
key: 'note',
|
key: 'note',
|
||||||
type: JVxeTypes.input,
|
type: JVxeTypes.input,
|
||||||
width:"200px",
|
|
||||||
placeholder: '请输入${title}',
|
placeholder: '请输入${title}',
|
||||||
defaultValue:'',
|
defaultValue:'',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -9,7 +9,7 @@ enum Api {
|
|||||||
edit='/openapi/auth/edit',
|
edit='/openapi/auth/edit',
|
||||||
apiList= '/openapi/list',
|
apiList= '/openapi/list',
|
||||||
genAKSK = '/openapi/auth/genAKSK',
|
genAKSK = '/openapi/auth/genAKSK',
|
||||||
permissionList='/openapi/permission/list',
|
permissionList='/openapi/permission/getOpenApi',
|
||||||
permissionAdd='/openapi/permission/add',
|
permissionAdd='/openapi/permission/add',
|
||||||
deleteOne = '/openapi/auth/delete',
|
deleteOne = '/openapi/auth/delete',
|
||||||
deleteBatch = '/openapi/auth/deleteBatch',
|
deleteBatch = '/openapi/auth/deleteBatch',
|
||||||
@ -87,15 +87,17 @@ export const batchDelete = (params, handleSuccess) => {
|
|||||||
* @param isUpdate
|
* @param isUpdate
|
||||||
*/
|
*/
|
||||||
export const saveOrUpdate = (params, isUpdate) => {
|
export const saveOrUpdate = (params, isUpdate) => {
|
||||||
let url = isUpdate ? Api.edit : Api.save;
|
if (isUpdate) {
|
||||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
return defHttp.put({ url: Api.edit, params }, { isTransformResponse: false });
|
||||||
|
}
|
||||||
|
return defHttp.post({ url: Api.save, params }, { isTransformResponse: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全部权限列表接口
|
* 全部权限列表接口
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export const getApiList = (params) => defHttp.get({ url: Api.apiList, params });
|
export const getApiList = (params) => defHttp.get({ url: Api.apiList, params }, { isTransformResponse: false });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取已授权项目的接口
|
* 获取已授权项目的接口
|
||||||
|
|||||||
@ -30,12 +30,11 @@ export const columns: BasicColumn[] = [
|
|||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'createTime'
|
dataIndex: 'createTime'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '关联系统用户名',
|
// title: '关联系统用户名',
|
||||||
align: "center",
|
// align: "center",
|
||||||
dataIndex: 'systemUserId_dictText',
|
// dataIndex: 'createBy',
|
||||||
|
// },
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// 高级查询数据
|
// 高级查询数据
|
||||||
@ -43,7 +42,7 @@ export const superQuerySchema = {
|
|||||||
name: {title: '授权名称',order: 0,view: 'text', type: 'string',},
|
name: {title: '授权名称',order: 0,view: 'text', type: 'string',},
|
||||||
ak: {title: 'AK',order: 1,view: 'text', type: 'string',},
|
ak: {title: 'AK',order: 1,view: 'text', type: 'string',},
|
||||||
sk: {title: 'SK',order: 2,view: 'text', type: 'string',},
|
sk: {title: 'SK',order: 2,view: 'text', type: 'string',},
|
||||||
createBy: {title: '创建人',order: 3,view: 'text', type: 'string',},
|
createBy: {title: '关联系统用户名',order: 3,view: 'text', type: 'string',},
|
||||||
createTime: {title: '创建时间',order: 4,view: 'datetime', type: 'string',},
|
createTime: {title: '创建时间',order: 4,view: 'datetime', type: 'string',},
|
||||||
systemUserId: {title: '关联系统用户名',order: 5,view: 'text', type: 'string',},
|
// systemUserId: {title: '关联系统用户名',order: 5,view: 'text', type: 'string',},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,9 +11,9 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="systemUserId">
|
<a-form-item name="createBy">
|
||||||
<template #label><span title="关联系统用户名">关联系统用户名</span></template>
|
<template #label><span title="关联系统用户名">关联系统用户名</span></template>
|
||||||
<JSearchSelect dict="sys_user,username,id" v-model:value="queryParam.systemUserId" placeholder="请输入关联系统用户名" allow-clear ></JSearchSelect>
|
<JSearchSelect dict="sys_user,username,username" v-model:value="queryParam.createBy" placeholder="请输入关联系统用户名" allow-clear ></JSearchSelect>
|
||||||
<!-- <a-input placeholder="请输入关联系统用户名" v-model:value="queryParam.systemUserId" allow-clear ></a-input>-->
|
<!-- <a-input placeholder="请输入关联系统用户名" v-model:value="queryParam.systemUserId" allow-clear ></a-input>-->
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
@ -62,6 +62,7 @@
|
|||||||
<template v-slot:bodyCell="{ column, record, index, text }">
|
<template v-slot:bodyCell="{ column, record, index, text }">
|
||||||
</template>
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
|
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
<OpenApiAuthModal ref="registerModal" @success="handleSuccess"></OpenApiAuthModal>
|
<OpenApiAuthModal ref="registerModal" @success="handleSuccess"></OpenApiAuthModal>
|
||||||
<AuthModal ref="authModal" @success="handleSuccess"></AuthModal>
|
<AuthModal ref="authModal" @success="handleSuccess"></AuthModal>
|
||||||
@ -73,7 +74,14 @@
|
|||||||
import { BasicTable, TableAction } from '/@/components/Table';
|
import { BasicTable, TableAction } from '/@/components/Table';
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
import { columns, superQuerySchema } from './OpenApiAuth.data';
|
import { columns, superQuerySchema } from './OpenApiAuth.data';
|
||||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './OpenApiAuth.api';
|
import {
|
||||||
|
list,
|
||||||
|
deleteOne,
|
||||||
|
batchDelete,
|
||||||
|
getImportUrl,
|
||||||
|
getExportUrl,
|
||||||
|
getGenAKSK, saveOrUpdate
|
||||||
|
} from "./OpenApiAuth.api";
|
||||||
import OpenApiAuthModal from './components/OpenApiAuthModal.vue'
|
import OpenApiAuthModal from './components/OpenApiAuthModal.vue'
|
||||||
import AuthModal from './components/AuthModal.vue'
|
import AuthModal from './components/AuthModal.vue'
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
@ -157,9 +165,23 @@
|
|||||||
*/
|
*/
|
||||||
function handleEdit(record: Recordable) {
|
function handleEdit(record: Recordable) {
|
||||||
registerModal.value.disableSubmit = false;
|
registerModal.value.disableSubmit = false;
|
||||||
|
registerModal.value.authDrawerOpen = true;
|
||||||
registerModal.value.edit(record);
|
registerModal.value.edit(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置事件
|
||||||
|
* @param record
|
||||||
|
*/
|
||||||
|
async function handleReset(record: Recordable) {
|
||||||
|
const AKSKObj = await getGenAKSK({});
|
||||||
|
record.ak = AKSKObj[0];
|
||||||
|
record.sk = AKSKObj[1];
|
||||||
|
saveOrUpdate(record,true);
|
||||||
|
// handleSuccess;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 详情
|
* 详情
|
||||||
*/
|
*/
|
||||||
@ -200,8 +222,12 @@
|
|||||||
auth: 'openapi:open_api_auth:edit'
|
auth: 'openapi:open_api_auth:edit'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '编辑',
|
label: '重置',
|
||||||
onClick: handleEdit.bind(null, record),
|
popConfirm: {
|
||||||
|
title: '是否重置AK,SK',
|
||||||
|
confirm: handleReset.bind(null, record),
|
||||||
|
placement: 'topLeft',
|
||||||
|
},
|
||||||
auth: 'openapi:open_api_auth:edit'
|
auth: 'openapi:open_api_auth:edit'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -1,60 +1,66 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-spin :spinning="confirmLoading">
|
<a-spin :spinning="confirmLoading">
|
||||||
<JFormContainer :disabled="disabled">
|
<a-row :span="24" style="margin-bottom: 10px">
|
||||||
<template #detail>
|
<a-col :span="12" v-for="item in apiList" @click="handleSelect(item)">
|
||||||
<BasicTable @register="registerTable" :rowSelection="rowSelection"> </BasicTable>
|
<a-card :style="item.checked ? { border: '1px solid #3370ff' } : {}" hoverable class="checkbox-card" :body-style="{ width: '100%', padding: '10px' }">
|
||||||
</template>
|
<div class="checkbox-name" style="display: flex; width: 100%; justify-content: space-between">
|
||||||
</JFormContainer>
|
<span>接口名称: {{ item.name }}</span>
|
||||||
|
<a-checkbox v-model:checked="item.checked" @click.stop class="quantum-checker" @change="(e) => handleChange(e, item)"> </a-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox-name" style="margin-top: 4px">
|
||||||
|
请求方式: <span>{{item.requestMethod}}</span>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<Pagination
|
||||||
|
v-if="apiList.length > 0"
|
||||||
|
:current="pageNo"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:page-size-options="pageSizeOptions"
|
||||||
|
:total="total"
|
||||||
|
:showQuickJumper="true"
|
||||||
|
:showSizeChanger="true"
|
||||||
|
@change="handlePageChange"
|
||||||
|
class="list-footer"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, defineExpose, nextTick, defineProps, computed } from 'vue';
|
import { computed, defineExpose, defineProps, nextTick, reactive, ref } from "vue";
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { permissionAddFunction, getPermissionList, getApiList } from '../OpenApiAuth.api';
|
import { getApiList, getPermissionList, permissionAddFunction } from '../OpenApiAuth.api';
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form, Pagination } from 'ant-design-vue';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
|
||||||
import { BasicTable } from '@/components/Table';
|
|
||||||
import { useListPage } from '@/hooks/system/useListPage';
|
|
||||||
import { columns } from '@/views/openapi/OpenApi.data';
|
|
||||||
|
|
||||||
const queryParam = reactive<any>({});
|
|
||||||
//注册table数据
|
|
||||||
const { tableContext } = useListPage({
|
|
||||||
tableProps: {
|
|
||||||
title: '授权',
|
|
||||||
api: getApiList,
|
|
||||||
columns,
|
|
||||||
canResize: false,
|
|
||||||
useSearchForm: false,
|
|
||||||
|
|
||||||
beforeFetch: async (params) => {
|
|
||||||
return Object.assign(params, queryParam);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
|
||||||
tableContext;
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formDisabled: { type: Boolean, default: false },
|
formDisabled: { type: Boolean, default: false },
|
||||||
formData: { type: Object, default: () => ({}) },
|
formData: { type: Object, default: () => ({}) },
|
||||||
formBpm: { type: Boolean, default: true },
|
formBpm: { type: Boolean, default: true },
|
||||||
});
|
});
|
||||||
const formRef = ref();
|
|
||||||
const useForm = Form.useForm;
|
const useForm = Form.useForm;
|
||||||
const emit = defineEmits(['register', 'ok']);
|
const emit = defineEmits(['register', 'ok']);
|
||||||
const formData = reactive<Record<string, any>>({
|
|
||||||
apiAuthId: '',
|
|
||||||
apiIdList: [],
|
|
||||||
});
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
|
|
||||||
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
|
|
||||||
const confirmLoading = ref<boolean>(false);
|
const confirmLoading = ref<boolean>(false);
|
||||||
|
//认证ID
|
||||||
|
const apiAuthId = ref<string>('');
|
||||||
//表单验证
|
//表单验证
|
||||||
const validatorRules = reactive({});
|
const validatorRules = reactive({});
|
||||||
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
|
//api列表
|
||||||
|
const apiList = ref<any>([]);
|
||||||
|
//选中的值
|
||||||
|
const selectedRowKeys = ref<any>([]);
|
||||||
|
//选中的数据
|
||||||
|
const selectedRows = ref<any>([]);
|
||||||
|
//当前页数
|
||||||
|
const pageNo = ref<number>(1);
|
||||||
|
//每页条数
|
||||||
|
const pageSize = ref<number>(10);
|
||||||
|
//总条数
|
||||||
|
const total = ref<number>(0);
|
||||||
|
//可选择的页数
|
||||||
|
const pageSizeOptions = ref<any>(['10', '20', '30']);
|
||||||
|
|
||||||
// 表单禁用
|
// 表单禁用
|
||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
@ -68,6 +74,25 @@
|
|||||||
return props.formDisabled;
|
return props.formDisabled;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载数据
|
||||||
|
*/
|
||||||
|
function reload() {
|
||||||
|
getApiList({ pageNo: pageNo.value, pageSize: pageSize.value, column: 'createTime', order: 'desc'}).then((res)=>{
|
||||||
|
if (res.success) {
|
||||||
|
for (const item of res.result.records) {
|
||||||
|
item.checked = false;
|
||||||
|
}
|
||||||
|
apiList.value = res.result.records;
|
||||||
|
total.value = res.result.total;
|
||||||
|
setChecked();
|
||||||
|
} else {
|
||||||
|
apiList.value = [];
|
||||||
|
total.value = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
*/
|
*/
|
||||||
@ -78,23 +103,27 @@
|
|||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
function edit(record) {
|
async function edit(record) {
|
||||||
nextTick(() => {
|
selectedRowKeys.value = [];
|
||||||
resetFields();
|
selectedRows.value = [];
|
||||||
//赋值
|
pageNo.value = 1;
|
||||||
formData.apiAuthId = record.id;
|
pageSize.value = 10;
|
||||||
|
apiAuthId.value = record.id;
|
||||||
|
await nextTick(() => {
|
||||||
// 获取当前已授权的项目
|
// 获取当前已授权的项目
|
||||||
getPermissionList({ apiAuthId: record.id }).then((res) => {
|
getPermissionList({ apiAuthId: record.id }).then((res) => {
|
||||||
if (res && res.length > 0) {
|
if (res.length > 0) {
|
||||||
let list = res.result.records || res.result;
|
res.forEach((item) => {
|
||||||
let ids = [];
|
if(item.ifCheckBox == "1"){
|
||||||
list.forEach((item) => {
|
selectedRowKeys.value.push(item.id);
|
||||||
ids.push(item.apiId);
|
selectedRows.value.push(item);
|
||||||
});
|
|
||||||
selectedRowKeys.value = ids;
|
|
||||||
formData.apiIdList = ids;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//设置选中
|
||||||
|
setChecked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,35 +131,21 @@
|
|||||||
* 提交数据
|
* 提交数据
|
||||||
*/
|
*/
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
if(selectedRowKeys.value.length === 0)
|
|
||||||
return emit('ok');
|
|
||||||
try {
|
|
||||||
// 触发表单验证
|
|
||||||
await validate();
|
|
||||||
} catch ({ errorFields }) {
|
|
||||||
if (errorFields) {
|
|
||||||
const firstField = errorFields[0];
|
|
||||||
if (firstField) {
|
|
||||||
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Promise.reject(errorFields);
|
|
||||||
}
|
|
||||||
confirmLoading.value = true;
|
confirmLoading.value = true;
|
||||||
//时间格式化
|
//时间格式化
|
||||||
let model = formData;
|
let model = {};
|
||||||
// model.apiIdList = selectedRowKeys.value;
|
|
||||||
let apiId = ""
|
let apiId = ""
|
||||||
selectedRowKeys.value.forEach((item) => {
|
selectedRowKeys.value.forEach((item) => {
|
||||||
apiId += item +",";
|
apiId += item +",";
|
||||||
})
|
})
|
||||||
model.apiId = apiId;
|
model['apiId'] = apiId;
|
||||||
delete model.apiIdList
|
model['apiAuthId'] = apiAuthId.value;
|
||||||
await permissionAddFunction(model)
|
await permissionAddFunction(model)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
createMessage.success(res.message);
|
createMessage.success(res.message);
|
||||||
emit('ok');
|
emit('ok');
|
||||||
|
cleanData()
|
||||||
} else {
|
} else {
|
||||||
createMessage.warning(res.message);
|
createMessage.warning(res.message);
|
||||||
}
|
}
|
||||||
@ -139,11 +154,89 @@
|
|||||||
confirmLoading.value = false;
|
confirmLoading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const cleanData = () => {
|
||||||
|
selectedRows.value = []
|
||||||
|
selectedRowKeys.value = []
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复选框选中事件
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
function handleSelect(item) {
|
||||||
|
let id = item.id;
|
||||||
|
const target = apiList.value.find((item) => item.id === id);
|
||||||
|
if (target) {
|
||||||
|
target.checked = !target.checked;
|
||||||
|
}
|
||||||
|
//存放选中的知识库的id
|
||||||
|
if (!selectedRowKeys.value || selectedRowKeys.value.length == 0) {
|
||||||
|
selectedRowKeys.value.push(id);
|
||||||
|
selectedRows.value.push(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let findIndex = selectedRowKeys.value.findIndex((item) => item === id);
|
||||||
|
if (findIndex === -1) {
|
||||||
|
selectedRowKeys.value.push(id);
|
||||||
|
selectedRows.value.push(item);
|
||||||
|
} else {
|
||||||
|
selectedRowKeys.value.splice(findIndex, 1);
|
||||||
|
selectedRows.value.splice(findIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复选框选中事件
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
function handleChange(e, item: any) {
|
||||||
|
if (e.target.checked) {
|
||||||
|
selectedRowKeys.value.push(item.id);
|
||||||
|
selectedRows.value.push(item);
|
||||||
|
} else {
|
||||||
|
let findIndex = selectedRowKeys.value.findIndex((val) => val === item.id);
|
||||||
|
if (findIndex != -1) {
|
||||||
|
selectedRowKeys.value.splice(findIndex, 1);
|
||||||
|
selectedRows.value.splice(findIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页改变事件
|
||||||
|
* @param page
|
||||||
|
* @param current
|
||||||
|
*/
|
||||||
|
function handlePageChange(page, current) {
|
||||||
|
pageNo.value = page;
|
||||||
|
pageSize.value = current;
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置选装状态
|
||||||
|
*/
|
||||||
|
function setChecked() {
|
||||||
|
if (apiList.value && apiList.value.length > 0){
|
||||||
|
let value = selectedRowKeys.value.join(',');
|
||||||
|
apiList.value = apiList.value.map((item) => {
|
||||||
|
if (value.indexOf(item.id) !== -1) {
|
||||||
|
item.checked = true;
|
||||||
|
} else {
|
||||||
|
item.checked = false;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
add,
|
add,
|
||||||
edit,
|
edit,
|
||||||
submitForm,
|
submitForm,
|
||||||
|
cleanData
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -151,4 +244,28 @@
|
|||||||
.antd-modal-form {
|
.antd-modal-form {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
}
|
}
|
||||||
|
.list-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -22px;
|
||||||
|
right: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.checkbox-card {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.checkbox-img {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.checkbox-name {
|
||||||
|
margin-left: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.use-select {
|
||||||
|
color: #646a73;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,12 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
<!-- <j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">-->
|
||||||
|
<div style="position: relative;">
|
||||||
|
<a-modal
|
||||||
|
v-model:open="authDrawerOpen"
|
||||||
|
class="custom-class"
|
||||||
|
root-class-name="root-class-name"
|
||||||
|
:root-style="{ color: 'blue' }"
|
||||||
|
:body-style="{ padding: '20px' }"
|
||||||
|
style="color: red"
|
||||||
|
:title="title"
|
||||||
|
:width="600"
|
||||||
|
@after-open-change="authDrawerOpenChange"
|
||||||
|
@ok="handleOk"
|
||||||
|
>
|
||||||
<AuthForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></AuthForm>
|
<AuthForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></AuthForm>
|
||||||
</j-modal>
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
<!-- </j-modal>-->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, nextTick, defineExpose } from 'vue';
|
import { ref, nextTick, defineExpose } from 'vue';
|
||||||
import AuthForm from './AuthForm.vue'
|
import AuthForm from './AuthForm.vue';
|
||||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
||||||
|
|
||||||
const title = ref<string>('');
|
const title = ref<string>('');
|
||||||
@ -16,6 +31,12 @@
|
|||||||
const registerForm = ref();
|
const registerForm = ref();
|
||||||
const emit = defineEmits(['register', 'success']);
|
const emit = defineEmits(['register', 'success']);
|
||||||
|
|
||||||
|
const authDrawerOpen = ref(false);
|
||||||
|
const authDrawerOpenChange = (val: any) => {
|
||||||
|
if(!val)
|
||||||
|
registerForm.value.cleanData()
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
*/
|
*/
|
||||||
@ -34,6 +55,7 @@
|
|||||||
function edit(record) {
|
function edit(record) {
|
||||||
title.value = disableSubmit.value ? '详情' : '授权';
|
title.value = disableSubmit.value ? '详情' : '授权';
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
|
authDrawerOpen.value = true;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
registerForm.value.edit(record);
|
registerForm.value.edit(record);
|
||||||
});
|
});
|
||||||
@ -59,6 +81,7 @@
|
|||||||
*/
|
*/
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
|
authDrawerOpen.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -19,11 +19,11 @@
|
|||||||
<a-input v-model:value="formData.sk" placeholder="请输入SK" disabled allow-clear ></a-input>
|
<a-input v-model:value="formData.sk" placeholder="请输入SK" disabled allow-clear ></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<!-- <a-col :span="24">-->
|
||||||
<a-form-item label="关联系统用户名" v-bind="validateInfos.systemUserId" id="OpenApiAuthForm-systemUserId" name="systemUserId">
|
<!-- <a-form-item label="关联系统用户名" v-bind="validateInfos.systemUserId" id="OpenApiAuthForm-systemUserId" name="systemUserId">-->
|
||||||
<JSearchSelect dict="sys_user,username,id" v-model:value="formData.systemUserId" placeholder="请输入关联系统用户名" allow-clear ></JSearchSelect>
|
<!-- <JSearchSelect dict="sys_user,username,id" v-model:value="formData.systemUserId" placeholder="请输入关联系统用户名" allow-clear ></JSearchSelect>-->
|
||||||
</a-form-item>
|
<!-- </a-form-item>-->
|
||||||
</a-col>
|
<!-- </a-col>-->
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
<j-modal :title="title" :width="width" :maxHeight="200" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
||||||
<OpenApiAuthForm ref="registerForm" @ok="submitCallback" :title="title" :formDisabled="disableSubmit" :formBpm="false"></OpenApiAuthForm>
|
<OpenApiAuthForm ref="registerForm" @ok="submitCallback" :title="title" :formDisabled="disableSubmit" :formBpm="false"></OpenApiAuthForm>
|
||||||
</j-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,39 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="'80%'" @ok="handleSubmit">
|
<BasicModal :bodyStyle="{ padding: '20px' }" v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" width="80%" @ok="handleSubmit">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="12">
|
<a-col :span="10">
|
||||||
<BasicForm @register="registerForm" ref="formRef" name="OpenApiForm" />
|
<BasicForm @register="registerForm" ref="formRef" name="OpenApiForm" />
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="14">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="24">
|
<a-col :span="24" style="margin-top: -0.6em">
|
||||||
<JVxeTable
|
<JVxeTable
|
||||||
keep-source
|
keep-source
|
||||||
resizable
|
|
||||||
ref="openApiHeader"
|
ref="openApiHeader"
|
||||||
:loading="openApiHeaderTable.loading"
|
:loading="openApiHeaderTable.loading"
|
||||||
:columns="openApiHeaderTable.columns"
|
:columns="openApiHeaderTable.columns"
|
||||||
:dataSource="openApiHeaderTable.dataSource"
|
:dataSource="openApiHeaderTable.dataSource"
|
||||||
:height="340"
|
:height="240"
|
||||||
:disabled="formDisabled"
|
:disabled="formDisabled"
|
||||||
:rowNumber="true"
|
:rowNumber="true"
|
||||||
:rowSelection="true"
|
:rowSelection="true"
|
||||||
:toolbar="true"
|
:toolbar="true"
|
||||||
|
size="mini"
|
||||||
/>
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<JVxeTable
|
<JVxeTable
|
||||||
keep-source
|
keep-source
|
||||||
resizable
|
|
||||||
ref="openApiParam"
|
ref="openApiParam"
|
||||||
:loading="openApiParamTable.loading"
|
:loading="openApiParamTable.loading"
|
||||||
:columns="openApiParamTable.columns"
|
:columns="openApiParamTable.columns"
|
||||||
:dataSource="openApiParamTable.dataSource"
|
:dataSource="openApiParamTable.dataSource"
|
||||||
:height="340"
|
:height="240"
|
||||||
:disabled="formDisabled"
|
:disabled="formDisabled"
|
||||||
:rowNumber="true"
|
:rowNumber="true"
|
||||||
:rowSelection="true"
|
:rowSelection="true"
|
||||||
:toolbar="true"
|
:toolbar="true"
|
||||||
|
size="mini"
|
||||||
/>
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -75,10 +75,11 @@
|
|||||||
});
|
});
|
||||||
//表单配置
|
//表单配置
|
||||||
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
|
||||||
labelWidth: 150,
|
labelWidth: 100,
|
||||||
schemas: formSchema,
|
schemas: formSchema,
|
||||||
showActionButtonGroup: false,
|
showActionButtonGroup: false,
|
||||||
baseColProps: { span: 24 },
|
baseColProps: { span: 24 },
|
||||||
|
wrapperCol: { span: 24 },
|
||||||
});
|
});
|
||||||
//表单赋值
|
//表单赋值
|
||||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export const columns: BasicColumn[] = [
|
|||||||
{
|
{
|
||||||
title: '手机',
|
title: '手机',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'telephone',
|
dataIndex: 'phone',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '邮箱',
|
title: '邮箱',
|
||||||
|
|||||||
Reference in New Issue
Block a user