完善CSV导入进度处理逻辑

This commit is contained in:
datagear 2019-06-21 17:14:18 +08:00
parent 8a87fc3180
commit 2ae64bca07
17 changed files with 408 additions and 154 deletions

View File

@ -37,4 +37,25 @@ public interface BatchDataExchangeListener<T extends DataExchange> extends DataE
* @param subDataExchangeIndex
*/
void onCancel(T subDataExchange, int subDataExchangeIndex);
/**
* 成功
* <p>
* 此方法在所有子数据交换都提交完成后可能提交成功也可能提交失败即会调用因此并不能表明任何子数据交换成功
* </p>
*/
@Override
void onSuccess();
/**
* 完成
* <p>
* 此方法将在{@linkplain #onException(DataExchangeException)}或者{@linkplain #onSuccess()}之后被调用
* </p>
* <p>
* 注意在所有子数据交换都完成后此方法才会执行
* </p>
*/
@Override
void onFinish();
}

View File

@ -80,6 +80,9 @@ public class BatchDataExchangeService<G extends DataExchange, T extends BatchDat
{
List<G> subDataExchanges = getSubDataExchanges(dataExchange);
exchange(this.executorService, dataExchange, subDataExchanges, results);
if (listener != null)
listener.onSuccess();
}
catch (Throwable t)
{
@ -87,8 +90,8 @@ public class BatchDataExchangeService<G extends DataExchange, T extends BatchDat
if (listener != null)
listener.onException(e);
throw e;
else
throw e;
}
finally
{

View File

@ -51,8 +51,14 @@ public abstract class DataExchange
* <p>
* 返回{@code null}表示未设置
* </p>
* <p>
* 此方法默认返回{@code null}子类可以在需要时重写
* </p>
*
* @return
*/
public abstract DataExchangeListener getListener();
public DataExchangeListener getListener()
{
return null;
}
}

View File

@ -19,15 +19,23 @@ public interface DataExchangeListener
/**
* 异常
* <p>
* 数据交换异常交由此处理后不会再向上抛出
* </p>
*
* @param e
*/
void onException(DataExchangeException e);
/**
* 成功
*/
void onSuccess();
/**
* 完成
* <p>
* 无论是否有异常此方法都将被调用
* 此方法将在{@linkplain #onException(DataExchangeException)}或者{@linkplain #onSuccess()}之后被调用
* </p>
*/
void onFinish();

View File

@ -98,6 +98,9 @@ public class CsvDataImportService extends AbstractDevotedTextDataImportService<C
}
commit(cn);
if (listener != null)
listener.onSuccess();
}
catch (Throwable t)
{
@ -114,8 +117,8 @@ public class CsvDataImportService extends AbstractDevotedTextDataImportService<C
if (listener != null)
listener.onException(e);
throw e;
else
throw e;
}
finally
{

View File

@ -80,6 +80,12 @@ public class BatchDataExchangeServiceTest extends DataexchangeTestSupport
println("onException");
}
@Override
public void onSuccess()
{
println("onSuccess");
}
@Override
public void onSubmitSuccess(CsvDataImport subDataExchange, int subDataExchangeIndex)
{

View File

@ -61,8 +61,6 @@ public class CsvDataImportServiceTest extends DataexchangeTestSupport
CsvDataImport impt = new CsvDataImport(new SimpleConnectionFactory(cn, false), dataFormat,
textDataImportOption, TABLE_NAME, readerFactory);
impt.setListener(new MockTextDataImportListener());
clearTable(cn, TABLE_NAME);
this.thrown.expect(ColumnNotFoundException.class);
@ -220,18 +218,24 @@ public class CsvDataImportServiceTest extends DataexchangeTestSupport
println("onStart");
}
@Override
public void onFinish()
{
println("onFinish");
}
@Override
public void onException(DataExchangeException e)
{
println("onException : " + e.getMessage());
}
@Override
public void onSuccess()
{
println("onSuccess");
}
@Override
public void onFinish()
{
println("onFinish");
}
@Override
public void onSuccess(int dataIndex)
{

View File

@ -7,6 +7,7 @@ package org.datagear.web.cometd.dataexchange;
import org.cometd.bayeux.server.ServerChannel;
import org.datagear.dataexchange.BatchDataExchangeListener;
import org.datagear.dataexchange.DataExchange;
import org.datagear.dataexchange.DataExchangeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -79,6 +80,30 @@ public class CometdBatchDataExchangeListener<T extends DataExchange> extends Com
sendMessage(new CancelSuccess(subDataExchangeId));
}
@Override
protected DataExchangeMessage buildStartMessage()
{
return new Start();
}
@Override
protected DataExchangeMessage buildExceptionMessage(DataExchangeException e)
{
return new Exception(e.getMessage());
}
@Override
protected DataExchangeMessage buildSuccessMessage()
{
return new Success();
}
@Override
protected DataExchangeMessage buildFinishMessage(long duration)
{
return new Finish(duration);
}
/**
* 获取子数据交换ID
* <p>
@ -103,34 +128,88 @@ public class CometdBatchDataExchangeListener<T extends DataExchange> extends Com
}
/**
* 数据交换消息
* 数据交换开始消息
*
* @author datagear@163.com
*
*/
public static abstract class SuDataExchangeMessage extends DataExchangeMessage
public static class Start extends DataExchangeMessage
{
private String subDataExchangeId;
public Start()
{
super();
}
}
public SuDataExchangeMessage()
/**
* 数据交换异常消息
*
* @author datagear@163.com
*
*/
public static class Exception extends DataExchangeMessage
{
private String content;
public Exception()
{
super();
}
public SuDataExchangeMessage(String subDataExchangeId)
public Exception(String content)
{
super();
this.subDataExchangeId = subDataExchangeId;
this.content = content;
}
public String getSubDataExchangeId()
public String getContent()
{
return subDataExchangeId;
return content;
}
public void setSubDataExchangeId(String subDataExchangeId)
public void setContent(String content)
{
this.subDataExchangeId = subDataExchangeId;
this.content = content;
}
}
public static class Success extends DataExchangeMessage
{
public Success()
{
super();
}
}
/**
* 数据交换完成消息
*
* @author datagear@163.com
*
*/
public static class Finish extends DataExchangeMessage
{
private long duration;
public Finish()
{
super();
}
public Finish(long duration)
{
super();
this.duration = duration;
}
public long getDuration()
{
return duration;
}
public void setDuration(long duration)
{
this.duration = duration;
}
}
@ -140,7 +219,7 @@ public class CometdBatchDataExchangeListener<T extends DataExchange> extends Com
* @author datagear@163.com
*
*/
public static class SubmitSuccess extends SuDataExchangeMessage
public static class SubmitSuccess extends SubDataExchangeMessage
{
public SubmitSuccess()
{
@ -159,7 +238,7 @@ public class CometdBatchDataExchangeListener<T extends DataExchange> extends Com
* @author datagear@163.com
*
*/
public static class SubmitFail extends SuDataExchangeMessage
public static class SubmitFail extends SubDataExchangeMessage
{
public SubmitFail()
{
@ -178,7 +257,7 @@ public class CometdBatchDataExchangeListener<T extends DataExchange> extends Com
* @author datagear@163.com
*
*/
public static class CancelSuccess extends SuDataExchangeMessage
public static class CancelSuccess extends SubDataExchangeMessage
{
public CancelSuccess()
{

View File

@ -16,7 +16,7 @@ import org.slf4j.LoggerFactory;
* @author datagear@163.com
*
*/
public class CometdDataExchangeListener implements DataExchangeListener
public abstract class CometdDataExchangeListener implements DataExchangeListener
{
protected static final Logger LOGGER = LoggerFactory.getLogger(CometdDataExchangeListener.class);
@ -64,7 +64,13 @@ public class CometdDataExchangeListener implements DataExchangeListener
@Override
public void onException(DataExchangeException e)
{
// TODO Auto-generated method stub
sendMessage(buildExceptionMessage(e));
}
@Override
public void onSuccess()
{
sendMessage(buildSuccessMessage());
}
@Override
@ -96,10 +102,22 @@ public class CometdDataExchangeListener implements DataExchangeListener
*
* @return
*/
protected DataExchangeMessage buildStartMessage()
{
return new StartMessage();
}
protected abstract DataExchangeMessage buildStartMessage();
/**
* 构建异常消息
*
* @param e
* @return
*/
protected abstract DataExchangeMessage buildExceptionMessage(DataExchangeException e);
/**
* 构建成功消息
*
* @return
*/
protected abstract DataExchangeMessage buildSuccessMessage();
/**
* 构建完成消息
@ -107,8 +125,5 @@ public class CometdDataExchangeListener implements DataExchangeListener
* @param duration
* @return
*/
protected DataExchangeMessage buildFinishMessage(long duration)
{
return new FinishMessage(duration);
}
protected abstract DataExchangeMessage buildFinishMessage(long duration);
}

View File

@ -5,6 +5,7 @@
package org.datagear.web.cometd.dataexchange;
import org.cometd.bayeux.server.ServerChannel;
import org.datagear.dataexchange.DataExchangeException;
import org.datagear.dataexchange.DataExchangeListener;
/**
@ -45,54 +46,32 @@ public abstract class CometdSubDataExchangeListener extends CometdDataExchangeLi
return new SubStart(this.subDataExchangeId);
}
@Override
protected DataExchangeMessage buildExceptionMessage(DataExchangeException e)
{
return new SubException(this.subDataExchangeId, e.getMessage());
}
@Override
protected DataExchangeMessage buildSuccessMessage()
{
return new SubSuccess(this.subDataExchangeId);
}
@Override
protected DataExchangeMessage buildFinishMessage(long duration)
{
return new SubFinish(this.subDataExchangeId, duration);
}
/**
* 子数据交换消息
*
* @author datagear@163.com
*
*/
public abstract static class SubDataExchangeMessage extends DataExchangeMessage
{
private String subDataExchangeId;
public SubDataExchangeMessage()
{
super();
}
public SubDataExchangeMessage(String subDataExchangeId)
{
super();
this.subDataExchangeId = subDataExchangeId;
}
public String getSubDataExchangeId()
{
return subDataExchangeId;
}
public void setSubDataExchangeId(String subDataExchangeId)
{
this.subDataExchangeId = subDataExchangeId;
}
}
/**
* 子数据交换开始
*
* @author datagear@163.com
*
*/
public static class SubStart extends StartMessage
public static class SubStart extends SubDataExchangeMessage
{
private String subDataExchangeId;
public SubStart()
{
super();
@ -100,23 +79,63 @@ public abstract class CometdSubDataExchangeListener extends CometdDataExchangeLi
public SubStart(String subDataExchangeId)
{
super();
this.subDataExchangeId = subDataExchangeId;
}
public String getSubDataExchangeId()
{
return subDataExchangeId;
}
public void setSubDataExchangeId(String subDataExchangeId)
{
this.subDataExchangeId = subDataExchangeId;
super(subDataExchangeId);
}
}
/**
* 子数据交换开始
* 子数据交换异常
*
* @author datagear@163.com
*
*/
public static class SubException extends SubDataExchangeMessage
{
private String content;
public SubException()
{
super();
}
public SubException(String subDataExchangeId, String content)
{
super(subDataExchangeId);
this.content = content;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
}
/**
* 子数据交换成功
*
* @author datagear@163.com
*
*/
public static class SubSuccess extends SubDataExchangeMessage
{
public SubSuccess()
{
super();
}
public SubSuccess(String subDataExchangeId)
{
super(subDataExchangeId);
}
}
/**
* 子数据交换完成
*
* @author datagear@163.com
*

View File

@ -51,31 +51,84 @@ public class CometdSubTextDataImportListener extends CometdSubDataExchangeListen
}
@Override
protected DataExchangeMessage buildFinishMessage(long duration)
protected DataExchangeMessage buildExceptionMessage(DataExchangeException e)
{
return new TextImportSubFinish(this.getSubDataExchangeId(), duration, this._successCount.intValue(),
return new TextImportSubException(getSubDataExchangeId(), e.getMessage(), this._successCount.intValue(),
this._ignoreCount.intValue());
}
@Override
protected DataExchangeMessage buildSuccessMessage()
{
return new TextImportSubSuccess(getSubDataExchangeId(), this._successCount.intValue(),
this._ignoreCount.intValue());
}
/**
* 子文本导入完成
* 子文本导入异常
*
* @author datagear@163.com
*
*/
public static class TextImportSubFinish extends SubFinish
public static class TextImportSubException extends SubException
{
private int successCount;
private int ignoreCount;
public TextImportSubFinish()
public TextImportSubException()
{
super();
}
public TextImportSubFinish(String subDataExchangeId, long duration, int successCount, int ignoreCount)
public TextImportSubException(String subDataExchangeId, String content, int successCount, int ignoreCount)
{
super(subDataExchangeId, duration);
super(subDataExchangeId, content);
this.successCount = successCount;
this.ignoreCount = ignoreCount;
}
public int getSuccessCount()
{
return successCount;
}
public void setSuccessCount(int successCount)
{
this.successCount = successCount;
}
public int getIgnoreCount()
{
return ignoreCount;
}
public void setIgnoreCount(int ignoreCount)
{
this.ignoreCount = ignoreCount;
}
}
/**
* 子文本导入成功
*
* @author datagear@163.com
*
*/
public static class TextImportSubSuccess extends SubSuccess
{
private int successCount;
private int ignoreCount;
public TextImportSubSuccess()
{
super();
}
public TextImportSubSuccess(String subDataExchangeId, int successCount, int ignoreCount)
{
super(subDataExchangeId);
this.successCount = successCount;
this.ignoreCount = ignoreCount;
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2018 datagear.org. All Rights Reserved.
*/
package org.datagear.web.cometd.dataexchange;
/**
* 数据交换完成消息
*
* @author datagear@163.com
*
*/
public class FinishMessage extends DataExchangeMessage
{
private long duration;
public FinishMessage()
{
super();
}
public FinishMessage(long duration)
{
super();
this.duration = duration;
}
public long getDuration()
{
return duration;
}
public void setDuration(long duration)
{
this.duration = duration;
}
}

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 2018 datagear.org. All Rights Reserved.
*/
package org.datagear.web.cometd.dataexchange;
/**
* 数据交换开始消息
*
* @author datagear@163.com
*
*/
public class StartMessage extends DataExchangeMessage
{
public StartMessage()
{
super();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 datagear.org. All Rights Reserved.
*/
package org.datagear.web.cometd.dataexchange;
/**
* 批量数据交换的子数据交换消息
*
* @author datagear@163.com
*
*/
public class SubDataExchangeMessage extends DataExchangeMessage
{
/** 子数据交换标识 */
private String subDataExchangeId;
public SubDataExchangeMessage()
{
super();
}
public SubDataExchangeMessage(String subDataExchangeId)
{
super();
this.subDataExchangeId = subDataExchangeId;
}
public String getSubDataExchangeId()
{
return subDataExchangeId;
}
public void setSubDataExchangeId(String subDataExchangeId)
{
this.subDataExchangeId = subDataExchangeId;
}
}

View File

@ -438,10 +438,12 @@ dataimport.importTableName=\u5BFC\u5165\u8868\u540D\u79F0
dataimport.importProgress=\u5BFC\u5165\u8FDB\u5EA6
dataimport.importStatusWithSuccessFail=\u5BFC\u5165\u8FDB\u5EA6\uFF08\u6210\u529F\u6570/\u5931\u8D25\u6570\uFF09
dataimport.importStatus.Unstart=\u672A\u5F00\u59CB
dataimport.importStatus.Exception=\u5BFC\u5165\u51FA\u9519\uFF1A{0}
dataimport.importStatus.SubmitSuccess=\u7B49\u5F85\u5BFC\u5165
dataimport.importStatus.SubmitFail=\u63D0\u4EA4\u5931\u8D25
dataimport.importStatus.CancelSuccess=\u5DF2\u53D6\u6D88
dataimport.importStatus.TextImportSubFinish=\u5B8C\u6210\uFF08{0}/{1}\uFF09
dataimport.importStatus.TextImportSubException=\u5F02\u5E38\uFF08{0}/{1}\uFF09\uFF0C{2}
dataimport.importStatus.TextImportSubSuccess=\u5B8C\u6210\uFF08{0}/{1}\uFF09
dataimport.fileEncoding=\u6587\u4EF6\u7F16\u7801
dataimport.cancelImportDeniedWithReason=\u53EA\u6709\u672A\u5F00\u59CB\u7684\u5BFC\u5165\u624D\u53EF\u4EE5\u53D6\u6D88

View File

@ -142,6 +142,9 @@ Schema schema 数据库不允许为null
</div>
</div>
</form>
<div class="restart-wrapper">
<button type="button" class="restart-button"><@spring.message code='restart' /></button>
</div>
</div>
<div class="foot">
</div>
@ -205,6 +208,20 @@ Schema schema 数据库不允许为null
}
};
po.toggleRestartStatus = function(enable)
{
if(enable)
{
po.element(".restart-wrapper").show();
po.element(".restart-button").removeClass("ui-state-disabled");
}
else
{
po.element(".restart-wrapper").hide();
po.element(".restart-button").addClass("ui-state-disabled");
}
};
po.element(".form-content").steps(
{
headerTag: "h3",
@ -293,6 +310,12 @@ Schema schema 数据库不允许为null
});
});
po.element(".restart-button").click(function()
{
po.toggleUploadAndImportStatus(false);
po.setImportProgress(0);
});
po.renderColumn = function(data, type, row, meta)
{
return $.escapeHtml($.truncateIf(data));
@ -379,9 +402,15 @@ Schema schema 数据库不允许为null
message = message.data;
var type = (message ? message.type : "");
if("StartMessage" == type)
if("Start" == type)
{
var dataTable = po.table().DataTable();
po.subDataExchangeCount = dataTable.rows().indexes().length;
}
else if("Exception" == type)
{
<#assign messageArgs=['"+message.content+"'] />
$.tipError("<@spring.messageArgs code='dataimport.importStatus.Exception' args=messageArgs />");
}
else if("SubmitSuccess" == type)
{
@ -398,16 +427,33 @@ Schema schema 数据库不允许为null
po.updateSubDataExchangeStatus(message.subDataExchangeId,
"<@spring.message code='dataimport.importStatus.CancelSuccess' />");
}
else if("TextImportSubFinish" == type)
else if("TextImportSubException" == type)
{
<#assign messageArgs=['"+message.successCount+"', '"+message.ignoreCount+"', '"+message.content+"'] />
po.updateSubDataExchangeStatus(message.subDataExchangeId,
"<@spring.messageArgs code='dataimport.importStatus.TextImportSubException' args=messageArgs />");
}
else if("TextImportSubSuccess" == type)
{
<#assign messageArgs=['"+message.successCount+"', '"+message.ignoreCount+"'] />
po.updateSubDataExchangeStatus(message.subDataExchangeId,
"<@spring.messageArgs code='dataimport.importStatus.TextImportSubFinish' args=messageArgs />");
"<@spring.messageArgs code='dataimport.importStatus.TextImportSubSuccess' args=messageArgs />");
}
else if("FinishMessage" == type)
else if("SubFinish" == type)
{
if(!po.subDataExchangeFinishCount)
po.subDataExchangeFinishCount = 0;
po.subDataExchangeFinishCount += 1;
po.setImportProgress(parseInt(po.subDataExchangeFinishCount/po.subDataExchangeCount * 100));
}
else if("Finish" == type)
{
po.setImportProgress(100);
po.toggleRestartStatus(true);
}
};
@ -435,6 +481,7 @@ Schema schema 数据库不允许为null
po.toggleUploadAndImportStatus(false);
po.setImportProgress(0);
po.toggleRestartStatus(false);
})
(${pageId});
</script>

View File

@ -1692,4 +1692,10 @@ table.dataTable tbody tr .column-check .row-data-state .ui-icon{
}
.page-dataimport-text .form-item-table .file-encoding-wrapper .ui-selectmenu-button.ui-button{
width: 8em;
}
.page-dataimport-text .restart-wrapper{
position: absolute;
right: 0.5em;
bottom: 0;
height: 3em;
}