fix: 2.4.0
1. 修复job客户端没有注册问题 2. 修复job执行成功后,返回值为nullNPE问题 3. 修复扫描任务是buckets为0sql异常问题 4. 放开参数必填限制
This commit is contained in:
parent
bc436a4ddb
commit
ac9f84c405
@ -1,21 +1,16 @@
|
|||||||
package com.aizuda.easy.retry.client.starter;
|
package com.aizuda.easy.retry.client.starter;
|
||||||
|
|
||||||
import com.aizuda.easy.retry.client.core.annotation.Retryable;
|
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.EasyRetryInterceptor;
|
|
||||||
import com.aizuda.easy.retry.client.core.intercepter.EasyRetryPointcutAdvisor;
|
|
||||||
import com.aizuda.easy.retry.client.core.strategy.RetryStrategy;
|
|
||||||
import com.aizuda.easy.retry.client.job.core.annotation.JobExecutor;
|
import com.aizuda.easy.retry.client.job.core.annotation.JobExecutor;
|
||||||
import org.aopalliance.intercept.MethodInterceptor;
|
|
||||||
import org.springframework.aop.Advisor;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.*;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@ComponentScan({"com.aizuda.easy.retry.client.job.core", "com.aizuda.easy.retry.client.common"})
|
@ComponentScan({"com.aizuda.easy.retry.client.job.core.*", "com.aizuda.easy.retry.client.common.*"})
|
||||||
@ConditionalOnClass(JobExecutor.class)
|
@ConditionalOnClass(JobExecutor.class)
|
||||||
@ConditionalOnProperty(prefix = "easy-retry", name = "enabled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "easy-retry", name = "enabled", havingValue = "true")
|
||||||
public class EasyRetryJobClientAutoConfiguration {
|
public class EasyRetryJobClientAutoConfiguration {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
com.aizuda.easy.retry.client.starter.EasyRetryClientAutoConfiguration,\
|
com.aizuda.easy.retry.client.starter.EasyRetryJobClientAutoConfiguration,\
|
||||||
com.aizuda.easy.retry.client.starter.EasyRetryJobClientAutoConfiguration
|
com.aizuda.easy.retry.client.starter.EasyRetryClientAutoConfiguration
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.aizuda.easy.retry.client.core.init;
|
package com.aizuda.easy.retry.client.common.init;
|
||||||
|
|
||||||
import com.aizuda.easy.retry.client.common.Lifecycle;
|
import com.aizuda.easy.retry.client.common.Lifecycle;
|
||||||
import com.aizuda.easy.retry.common.core.util.EasyRetryVersion;
|
import com.aizuda.easy.retry.common.core.util.EasyRetryVersion;
|
@ -1,4 +1,4 @@
|
|||||||
package com.aizuda.easy.retry.client.core.init;
|
package com.aizuda.easy.retry.client.common.init;
|
||||||
|
|
||||||
import com.aizuda.easy.retry.client.common.Lifecycle;
|
import com.aizuda.easy.retry.client.common.Lifecycle;
|
||||||
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
|
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
|
@ -9,7 +9,7 @@ import java.lang.annotation.*;
|
|||||||
* @date 2023-09-26 23:19:01
|
* @date 2023-09-26 23:19:01
|
||||||
* @since 2.4.0
|
* @since 2.4.0
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Inherited
|
@Inherited
|
||||||
@Documented
|
@Documented
|
||||||
|
@ -21,6 +21,12 @@ public class AnnotationJobExecutor extends AbstractJobExecutor {
|
|||||||
@Override
|
@Override
|
||||||
protected ExecuteResult doJobExecute(final JobArgs jobArgs) {
|
protected ExecuteResult doJobExecute(final JobArgs jobArgs) {
|
||||||
JobExecutorInfo jobExecutorInfo = JobExecutorInfoCache.get(jobArgs.getExecutorInfo());
|
JobExecutorInfo jobExecutorInfo = JobExecutorInfoCache.get(jobArgs.getExecutorInfo());
|
||||||
|
Class<?>[] paramTypes = jobExecutorInfo.getMethod().getParameterTypes();
|
||||||
|
|
||||||
|
if (paramTypes.length > 0) {
|
||||||
return (ExecuteResult) ReflectionUtils.invokeMethod(jobExecutorInfo.getMethod(), jobExecutorInfo.getExecutor(), jobArgs);
|
return (ExecuteResult) ReflectionUtils.invokeMethod(jobExecutorInfo.getMethod(), jobExecutorInfo.getExecutor(), jobArgs);
|
||||||
|
} else {
|
||||||
|
return (ExecuteResult) ReflectionUtils.invokeMethod(jobExecutorInfo.getMethod(), jobExecutorInfo.getExecutor());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
|||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: www.byteblogs.com
|
* @author: www.byteblogs.com
|
||||||
* @date : 2023-10-08 16:44
|
* @date : 2023-10-08 16:44
|
||||||
@ -34,10 +36,14 @@ public class JobExecutorFutureCallback implements FutureCallback<ExecuteResult>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final ExecuteResult result) {
|
public void onSuccess(ExecuteResult result) {
|
||||||
// 上报执行成功
|
// 上报执行成功
|
||||||
log.info("任务执行成功 [{}]", JsonUtil.toJsonString(result));
|
log.info("任务执行成功 [{}]", JsonUtil.toJsonString(result));
|
||||||
|
|
||||||
|
if (Objects.isNull(result)) {
|
||||||
|
result = ExecuteResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
int taskStatus;
|
int taskStatus;
|
||||||
if (result.getStatus() == StatusEnum.NO.getStatus()) {
|
if (result.getStatus() == StatusEnum.NO.getStatus()) {
|
||||||
taskStatus = JobTaskStatusEnum.FAIL.getStatus();
|
taskStatus = JobTaskStatusEnum.FAIL.getStatus();
|
||||||
|
@ -70,10 +70,15 @@ public class JobExecutorScanner implements Scanner, ApplicationContextAware {
|
|||||||
if (Objects.nonNull(jobExecutor)) {
|
if (Objects.nonNull(jobExecutor)) {
|
||||||
String executorName = jobExecutor.name();
|
String executorName = jobExecutor.name();
|
||||||
if (!JobExecutorInfoCache.isExisted(executorName)) {
|
if (!JobExecutorInfoCache.isExisted(executorName)) {
|
||||||
|
Method method = ReflectionUtils.findMethod(bean.getClass(), jobExecutor.method(), JobArgs.class);
|
||||||
|
if (method == null) {
|
||||||
|
method = ReflectionUtils.findMethod(bean.getClass(), jobExecutor.method());
|
||||||
|
}
|
||||||
|
|
||||||
JobExecutorInfo jobExecutorInfo =
|
JobExecutorInfo jobExecutorInfo =
|
||||||
new JobExecutorInfo(
|
new JobExecutorInfo(
|
||||||
executorName,
|
executorName,
|
||||||
ReflectionUtils.findMethod(bean.getClass(), jobExecutor.method(), JobArgs.class),
|
method,
|
||||||
bean
|
bean
|
||||||
);
|
);
|
||||||
retryerInfoList.add(jobExecutorInfo);
|
retryerInfoList.add(jobExecutorInfo);
|
||||||
|
@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -65,6 +66,9 @@ public class ScanJobTaskActor extends AbstractActor {
|
|||||||
|
|
||||||
private void doScan(final ScanTask scanTask) {
|
private void doScan(final ScanTask scanTask) {
|
||||||
log.info("job scan start");
|
log.info("job scan start");
|
||||||
|
if (CollectionUtils.isEmpty(scanTask.getBuckets())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long total = PartitionTaskUtils.process(startId -> listAvailableJobs(startId, scanTask), this::processJobPartitionTasks, scanTask.getStartId());
|
long total = PartitionTaskUtils.process(startId -> listAvailableJobs(startId, scanTask), this::processJobPartitionTasks, scanTask.getStartId());
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
|||||||
|
.card[data-v-4ef12e30]{margin-bottom:24px}.popover-wrapper[data-v-4ef12e30] .antd-pro-pages-forms-style-errorPopover .ant-popover-inner-content{min-width:256px;max-height:290px;padding:0;overflow:auto}.antd-pro-pages-forms-style-errorIcon[data-v-4ef12e30]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-right:24px;color:#f5222d;cursor:pointer}.antd-pro-pages-forms-style-errorIcon i[data-v-4ef12e30]{margin-right:4px}.antd-pro-pages-forms-style-errorListItem[data-v-4ef12e30]{padding:8px 16px;list-style:none;border-bottom:1px solid #e8e8e8;cursor:pointer;-webkit-transition:all .3s;transition:all .3s}.antd-pro-pages-forms-style-errorListItem[data-v-4ef12e30]:hover{background:#e6f7ff}.antd-pro-pages-forms-style-errorListItem .antd-pro-pages-forms-style-errorIcon[data-v-4ef12e30]{float:left;margin-top:4px;margin-right:12px;padding-bottom:22px;color:#f5222d}.antd-pro-pages-forms-style-errorListItem .antd-pro-pages-forms-style-errorField[data-v-4ef12e30]{margin-top:2px;color:rgba(0,0,0,.45);font-size:12px}
|
@ -0,0 +1 @@
|
|||||||
|
.ant-cron-result{display:none}
|
@ -1 +0,0 @@
|
|||||||
.card[data-v-73b0ee39]{margin-bottom:24px}.popover-wrapper[data-v-73b0ee39] .antd-pro-pages-forms-style-errorPopover .ant-popover-inner-content{min-width:256px;max-height:290px;padding:0;overflow:auto}.antd-pro-pages-forms-style-errorIcon[data-v-73b0ee39]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-right:24px;color:#f5222d;cursor:pointer}.antd-pro-pages-forms-style-errorIcon i[data-v-73b0ee39]{margin-right:4px}.antd-pro-pages-forms-style-errorListItem[data-v-73b0ee39]{padding:8px 16px;list-style:none;border-bottom:1px solid #e8e8e8;cursor:pointer;-webkit-transition:all .3s;transition:all .3s}.antd-pro-pages-forms-style-errorListItem[data-v-73b0ee39]:hover{background:#e6f7ff}.antd-pro-pages-forms-style-errorListItem .antd-pro-pages-forms-style-errorIcon[data-v-73b0ee39]{float:left;margin-top:4px;margin-right:12px;padding-bottom:22px;color:#f5222d}.antd-pro-pages-forms-style-errorListItem .antd-pro-pages-forms-style-errorField[data-v-73b0ee39]{margin-top:2px;color:rgba(0,0,0,.45);font-size:12px}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
|||||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-40597980"],{"00d8":function(e,r){(function(){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t={rotl:function(e,r){return e<<r|e>>>32-r},rotr:function(e,r){return e<<32-r|e>>>r},endian:function(e){if(e.constructor==Number)return 16711935&t.rotl(e,8)|4278255360&t.rotl(e,24);for(var r=0;r<e.length;r++)e[r]=t.endian(e[r]);return e},randomBytes:function(e){for(var r=[];e>0;e--)r.push(Math.floor(256*Math.random()));return r},bytesToWords:function(e){for(var r=[],t=0,n=0;t<e.length;t++,n+=8)r[n>>>5]|=e[t]<<24-n%32;return r},wordsToBytes:function(e){for(var r=[],t=0;t<32*e.length;t+=8)r.push(e[t>>>5]>>>24-t%32&255);return r},bytesToHex:function(e){for(var r=[],t=0;t<e.length;t++)r.push((e[t]>>>4).toString(16)),r.push((15&e[t]).toString(16));return r.join("")},hexToBytes:function(e){for(var r=[],t=0;t<e.length;t+=2)r.push(parseInt(e.substr(t,2),16));return r},bytesToBase64:function(e){for(var t=[],n=0;n<e.length;n+=3)for(var o=e[n]<<16|e[n+1]<<8|e[n+2],a=0;a<4;a++)8*n+6*a<=8*e.length?t.push(r.charAt(o>>>6*(3-a)&63)):t.push("=");return t.join("")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\/]/gi,"");for(var t=[],n=0,o=0;n<e.length;o=++n%4)0!=o&&t.push((r.indexOf(e.charAt(n-1))&Math.pow(2,-2*o+8)-1)<<2*o|r.indexOf(e.charAt(n))>>>6-2*o);return t}};e.exports=t})()},"044b":function(e,r){function t(e){return!!e.constructor&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function n(e){return"function"===typeof e.readFloatLE&&"function"===typeof e.slice&&t(e.slice(0,0))}
|
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d8216538"],{"00d8":function(e,r){(function(){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t={rotl:function(e,r){return e<<r|e>>>32-r},rotr:function(e,r){return e<<32-r|e>>>r},endian:function(e){if(e.constructor==Number)return 16711935&t.rotl(e,8)|4278255360&t.rotl(e,24);for(var r=0;r<e.length;r++)e[r]=t.endian(e[r]);return e},randomBytes:function(e){for(var r=[];e>0;e--)r.push(Math.floor(256*Math.random()));return r},bytesToWords:function(e){for(var r=[],t=0,n=0;t<e.length;t++,n+=8)r[n>>>5]|=e[t]<<24-n%32;return r},wordsToBytes:function(e){for(var r=[],t=0;t<32*e.length;t+=8)r.push(e[t>>>5]>>>24-t%32&255);return r},bytesToHex:function(e){for(var r=[],t=0;t<e.length;t++)r.push((e[t]>>>4).toString(16)),r.push((15&e[t]).toString(16));return r.join("")},hexToBytes:function(e){for(var r=[],t=0;t<e.length;t+=2)r.push(parseInt(e.substr(t,2),16));return r},bytesToBase64:function(e){for(var t=[],n=0;n<e.length;n+=3)for(var o=e[n]<<16|e[n+1]<<8|e[n+2],a=0;a<4;a++)8*n+6*a<=8*e.length?t.push(r.charAt(o>>>6*(3-a)&63)):t.push("=");return t.join("")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\/]/gi,"");for(var t=[],n=0,o=0;n<e.length;o=++n%4)0!=o&&t.push((r.indexOf(e.charAt(n-1))&Math.pow(2,-2*o+8)-1)<<2*o|r.indexOf(e.charAt(n))>>>6-2*o);return t}};e.exports=t})()},"044b":function(e,r){function t(e){return!!e.constructor&&"function"===typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function n(e){return"function"===typeof e.readFloatLE&&"function"===typeof e.slice&&t(e.slice(0,0))}
|
||||||
/*!
|
/*!
|
||||||
* Determine if an object is a Buffer
|
* Determine if an object is a Buffer
|
||||||
*
|
*
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -48,7 +48,7 @@ easy-retry:
|
|||||||
max-count: 288 #回调最大执行次数
|
max-count: 288 #回调最大执行次数
|
||||||
trigger-interval: 900 #间隔时间
|
trigger-interval: 900 #间隔时间
|
||||||
db-type: mysql #当前使用的数据库
|
db-type: mysql #当前使用的数据库
|
||||||
mode: all
|
mode: job
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,28 +149,28 @@ export const asyncRouterMap = [
|
|||||||
path: '/job/batch/list',
|
path: '/job/batch/list',
|
||||||
name: 'JobBatchList',
|
name: 'JobBatchList',
|
||||||
component: () => import('@/views/job/JobBatchList'),
|
component: () => import('@/views/job/JobBatchList'),
|
||||||
meta: { title: '任务批次', icon: 'profile', permission: ['retryLog'] }
|
meta: { title: '任务批次', icon: 'profile', permission: ['jobBatch'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/job/batch/info',
|
path: '/job/batch/info',
|
||||||
name: 'JobBatchInfo',
|
name: 'JobBatchInfo',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
component: () => import('@/views/job/JobBatchInfo'),
|
component: () => import('@/views/job/JobBatchInfo'),
|
||||||
meta: { title: '任务批次详情', icon: 'profile', permission: ['retryLog'] }
|
meta: { title: '任务批次详情', icon: 'profile', permission: ['jobBatch'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/job/task/list',
|
path: '/job/task/list',
|
||||||
name: 'JobTaskList',
|
name: 'JobTaskList',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
component: () => import('@/views/job/JobTaskList'),
|
component: () => import('@/views/job/JobTaskList'),
|
||||||
meta: { title: '任务项', icon: 'profile', permission: ['retryLog'] }
|
meta: { title: '任务项', icon: 'profile', permission: ['jobBatch'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/job/log/list',
|
path: '/job/log/list',
|
||||||
name: 'JobLogMessageList',
|
name: 'JobLogMessageList',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
component: () => import('@/views/job/JobLogMessageList'),
|
component: () => import('@/views/job/JobLogMessageList'),
|
||||||
meta: { title: '任务调度日志', icon: 'profile', permission: ['retryLog'] }
|
meta: { title: '任务调度日志', icon: 'profile', permission: ['jobBatch'] }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -103,7 +103,7 @@ const permissionsConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
roleId: 1,
|
roleId: 1,
|
||||||
permissionId: 'JobBatch',
|
permissionId: 'jobBatch',
|
||||||
permissionName: '任务批次'
|
permissionName: '任务批次'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -142,7 +142,7 @@ const permissionsConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
roleId: 1,
|
roleId: 1,
|
||||||
permissionId: 'JobBatch',
|
permissionId: 'jobBatch',
|
||||||
permissionName: '任务批次'
|
permissionName: '任务批次'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -187,7 +187,7 @@ const permissionsConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
roleId: 1,
|
roleId: 1,
|
||||||
permissionId: 'JobBatch',
|
permissionId: 'jobBatch',
|
||||||
permissionName: '任务批次'
|
permissionName: '任务批次'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -246,7 +246,7 @@ const permissionsConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
roleId: 1,
|
roleId: 1,
|
||||||
permissionId: 'JobBatch',
|
permissionId: 'jobBatch',
|
||||||
permissionName: '任务批次'
|
permissionName: '任务批次'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -177,7 +177,7 @@
|
|||||||
@click="handleBlur"
|
@click="handleBlur"
|
||||||
v-decorator="[
|
v-decorator="[
|
||||||
'argsStr',
|
'argsStr',
|
||||||
{rules: [{ required: true, message: '请输入方法参数', whitespace: true}]}
|
{rules: [{ required: false, message: '请输入方法参数', whitespace: true}]}
|
||||||
]" />
|
]" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
Loading…
Reference in New Issue
Block a user