模板方法設計模式
一、實現
package com.jd.fms.proxyinvoice.project.workerengine;
import com.jd.cwbase.worker.domain.WorkerException;
import com.jd.cwbase.worker.domain.WorkerResult;
import com.jd.cwbase.worker.workUtil.CycleWorkerEngine;
import com.jd.fms.proxyinvoice.project.custenum.domainTypeEnum.WorkerEnum;
import com.jd.fms.proxyinvoice.project.service.worker.EleInvRedResultWorkerService;
import javax.annotation.Resource;
public class EleInvoiceRedResultCycWorker extends CycleWorkerEngine {
@Resource
private EleInvRedResultWorkerService eleInvRedResultWorkerService;
@Override
protected WorkerResult executeWorker(Integer orderNo) throws WorkerException {
WorkerResult wr = new WorkerResult(false, "失敗");
try {
eleInvRedResultWorkerService.doSolve();
wr.setSuccess(true);
wr.setMsg("成功");
} catch (Exception e) {
logger.error("EleInvoiceResultCycWorker.executeWorker.Exception:查詢航信結果信息紅票輪訓任務處理失敗", e);
wr.setMsg(e.getMessage());
}
return wr;
}
@Override
public String getWorkerTypeCode() {
return WorkerEnum.ELE_INVOICE_RESULT_RED_CYC.value();
}
}
package com.jd.fms.proxyinvoice.project.service.worker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.jd.fms.proxyinvoice.common.util.CheckUtil;
import com.jd.fms.proxyinvoice.common.util.ResponseMsgSubtringUtil;
import com.jd.fms.proxyinvoice.common.util.StringUtil;
import com.jd.fms.proxyinvoice.project.custenum.constant.CycTaskResultEnum;
import com.jd.fms.proxyinvoice.project.custenum.domainTypeEnum.TaskStatus;
import com.jd.fms.proxyinvoice.project.dao.EleInvoiceCycMapper;
import com.jd.fms.proxyinvoice.project.server.domain.CycTaskResult;
import com.jd.fms.proxyinvoice.project.server.domain.EleInvoiceCycDto;
import com.jd.fms.proxyinvoice.project.server.domain.EleWorkerResult;
import java.util.List;
public abstract class AbstractEleInvCycTaskService {
private static final int MAX_LEN_DBCLUM_REP_MSG = 250;
private static final int TASK_DEFAULT_DELAY_DAYS = 0;
private static final int TASK_DEFAULT_LOCK_NUM = 200;
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
protected EleInvoiceCycMapper eleInvoiceCycMapper;
public void setEleInvoiceCycMapper(EleInvoiceCycMapper eleInvoiceCycMapper) {
this.eleInvoiceCycMapper = eleInvoiceCycMapper;
}
public final EleWorkerResult doSolve() {
EleWorkerResult result = new EleWorkerResult(true, "任務完成");
List<EleInvoiceCycDto> taskList = eleInvoiceCycMapper.queryCycTasksDelayday(getCycType(), TaskStatus.UNTREATED.value(), getDelayDays(), getLockNum());
if (CheckUtil.isEmpty(taskList)) {
result.setSuccess(true);
result.setMessage("沒有未處理的【" + getCycTaskDesc() + "】");
return result;
}
for (EleInvoiceCycDto task : taskList) {
try {
doSingleTask(task);
} catch (Exception e) {
logger.error("循環處理【{}】出現異常:{}", getCycTaskDesc(), e);
result.setSuccess(false);
result.setMessage("循環處理【" + getCycTaskDesc() + "】出現異常");
}
}
return result;
}
protected abstract String getCycType();
protected abstract String getCycTaskDesc();
private final void doSingleTask(EleInvoiceCycDto task) {
Integer currentStatus = null;
try {
if (eleInvoiceCycMapper.updateStatusById(task.getId(), TaskStatus.PROCESSING.value(),
TaskStatus.UNTREATED.value(), null) != 1) {
logger.warn("更新任務{}狀態[未處理]-->[處理中]影響行數不爲1,不處理此任務", task.getId());
return;
}
currentStatus = TaskStatus.PROCESSING.value();
String refId = task.getRefId();
if(StringUtil.isBlank(refId)) {
logger.error("【{}】:{}", getCycTaskDesc(), "refId爲空");
currentStatus = updateTaskStatus(task.getId(), TaskStatus.FAILED.value(), "refId爲空");
return;
}
CycTaskResult ret = execTask(refId);
if(ret == null) {
logger.error("【{}】:關聯單號【{}】:{}", new String[] { getCycTaskDesc(), refId, "任務執行結果爲空" });
currentStatus = updateTaskStatus(task.getId(), TaskStatus.FAILED.value(), "任務執行結果爲空");
return;
}
if (CycTaskResultEnum.SUCCEED.equals(ret.getCode())) {
logger.info("【{}】:關聯單號【{}】:{}", new String[] { getCycTaskDesc(), refId, "成功" });
currentStatus = updateTaskStatus(task.getId(), TaskStatus.SUCCEED.value(), "成功");
} else if(CycTaskResultEnum.RETRY.equals(ret.getCode())) {
logger.info("【{}】:關聯單號【{}】:{}", new String[] { getCycTaskDesc(), refId, "下次任務重試" });
currentStatus = updateTaskStatus(task.getId(), TaskStatus.UNTREATED.value(),
ResponseMsgSubtringUtil.formartErrorMsg(ret.getMessage(), MAX_LEN_DBCLUM_REP_MSG));
} else {
logger.error("【{}】:關聯單號【{}】:{}", new String[] { getCycTaskDesc(), refId, "任務失敗" });
currentStatus = updateTaskStatus(task.getId(), TaskStatus.FAILED.value(),
ResponseMsgSubtringUtil.formartErrorMsg(ret.getMessage(), MAX_LEN_DBCLUM_REP_MSG));
}
} catch (Exception e) {
logger.error(getCycTaskDesc(), e);
if (TaskStatus.PROCESSING.value().equals(currentStatus)) {
currentStatus = updateTaskStatus(task.getId(), TaskStatus.FAILED.value(),
ResponseMsgSubtringUtil.formartErrorMsg(e.getMessage(), MAX_LEN_DBCLUM_REP_MSG));
}
} finally {
if (TaskStatus.PROCESSING.value().equals(currentStatus)) {
logger.error("【{}】:finally, change TaskStatus PROCESSING-->UNTREATED", getCycTaskDesc());
updateTaskStatus(task.getId(), TaskStatus.UNTREATED.value(), "出現未知異常");
}
}
}
private Integer updateTaskStatus(Long taskId, Integer status, String message) {
eleInvoiceCycMapper.updateStatusByIdAddExecNum(taskId, status, TaskStatus.PROCESSING.value(), message);
return status;
}
protected Integer getDelayDays() {
return TASK_DEFAULT_DELAY_DAYS;
}
protected Integer getLockNum() {
return TASK_DEFAULT_LOCK_NUM;
}
protected abstract CycTaskResult execTask(String refId);
}
package com.jd.fms.proxyinvoice.project.service.worker;
import org.springframework.stereotype.Service;
import com.jd.fms.proxyinvoice.common.exception.BusinessException;
import com.jd.fms.proxyinvoice.project.custenum.constant.Constants;
import com.jd.fms.proxyinvoice.project.custenum.constant.CycTaskResultEnum;
import com.jd.fms.proxyinvoice.project.custenum.domainTypeEnum.EleInvoiceApplyStatusEnum;
import com.jd.fms.proxyinvoice.project.custenum.domainTypeEnum.WorkerEnum;
import com.jd.fms.proxyinvoice.project.server.domain.CycTaskResult;
import com.jd.fms.proxyinvoice.project.server.domain.ServerException;
import com.jd.fms.proxyinvoice.project.service.EleInvApplyWorkService;
import com.jd.fms.proxyinvoice.project.service.taxbureau.LevyResult;
import com.jd.fms.proxyinvoice.project.service.taxbureau.LevyResultDto;
import com.jd.fms.proxyinvoice.project.service.taxbureau.SendToTaxBureauService;
import com.jd.fms.proxyinvoice.project.service.taxbureau.TaxBureauResponseCode;
import com.jd.fms.proxyinvoice.project.service.taxbureau.TaxInvoiceQuery;
import com.jd.ump.profiler.CallerInfo;
import com.jd.ump.profiler.proxy.Profiler;
import javax.annotation.Resource;
@Service
public class EleInvLevyCycWorkerService extends AbstractEleInvCycTaskService{
@Resource
private SendToTaxBureauService sendToTaxBureauService;
@Resource
private EleInvApplyWorkService eleInvApplyWorkService;
@Override
protected Integer getDelayDays() {
return 1;
}
@Override
protected CycTaskResult execTask(String refId) {
CallerInfo info = Profiler.registerInfo("project.service.worker.eleInvLevyCycWorkerService.execTask", Constants.APP_NAME,
false, true);
CycTaskResult result = new CycTaskResult(CycTaskResultEnum.FAILED, "失敗");
try {
TaxInvoiceQuery query = buildTaxInvoiceQuery(refId);
LevyResult response = sendToTaxBureauService.queryOrderInfoData(query);
if (response == null) {
logger.error("調用稅局查詢徵收信息返回爲空, orderNo:{}", refId);
result.setMessage("調用稅局查詢徵收信息返回爲空");
result.setCode(CycTaskResultEnum.RETRY);
return result;
}
if (TaxBureauResponseCode.MQ99.value().equals(response.getCode())
|| TaxBureauResponseCode.E99E.value().equals(response.getCode())) {
logger.error("查詢徵收信息接口返回系統異常 , code:{}, msg:{}, orderNo:{}",
new String[] { response.getCode(), response.getMessage(), refId });
throw new BusinessException("", "查詢徵收信息接口返回系統異常," + response.getCode() + ":" + response.getMessage());
}
if (TaxBureauResponseCode.NOT_OPEN_TICKET.value().equals(response.getCode()) ||
TaxBureauResponseCode.INCORRECT_ORDERNO.value().equals(response.getCode())) {
logger.info("該訂單還未開票 , 任務狀態改爲未處理,下次任務循環繼續查詢, orderNo:{}", refId);
result.setMessage("該訂單還未開票");
result.setCode(CycTaskResultEnum.RETRY);
return result;
} else if (TaxBureauResponseCode.SUCCESS.value().equals(response.getCode())) {
LevyResultDto data = response.getData();
if (!refId.equals(data.getYdh())) {
logger.error("益世系統訂單號【{}】,稅局返回訂單號【{}】不一致", refId, data.getYdh());
throw new ServerException("訂單號不一致,refId:" + refId + ",ydh:" + data.getYdh());
}
eleInvApplyWorkService.saveLevyInfo(refId, data);
result.setMessage("成功");
result.setCode(CycTaskResultEnum.SUCCEED);
return result;
} else if (TaxBureauResponseCode.INCORRECT_TRANID.value().equals(response.getCode()) ||
TaxBureauResponseCode.UNVALID_ORDERNO.value().equals(response.getCode())) {
logger.error("查詢徵收信息接口返回錯誤 , code:{}, msg:{}, orderNo:{}",
new String[] { response.getCode(), response.getMessage(), refId });
eleInvApplyWorkService.updateInvApplyOrderStatus(refId, EleInvoiceApplyStatusEnum.APPLYING, EleInvoiceApplyStatusEnum.APPLY_FAILED);
result.setMessage("查詢徵收信息接口返回錯誤," + response.getCode() + ":" + response.getMessage());
result.setCode(CycTaskResultEnum.FAILED);
return result;
} else {
logger.error("查詢徵收信息接口返回未知錯誤 , code:{}, msg:{}, orderNo:{}",
new String[] { response.getCode(), response.getMessage(), refId });
throw new BusinessException("", "查詢徵收信息接口返回未知錯誤," + response.getCode() + ":" + response.getMessage());
}
} catch (ServerException e) {
Profiler.functionError(info);
logger.error("查詢徵收信息任務出現異常,任務失敗", e);
result.setMessage(e.getMessage());
result.setCode(CycTaskResultEnum.FAILED);
} catch (Exception e) {
Profiler.functionError(info);
logger.error("查詢徵收信息任務出現未知異常,任務重試", e);
result.setMessage("查詢徵收信息任務出現未知異常,任務重試");
result.setCode(CycTaskResultEnum.RETRY);
} finally {
Profiler.registerInfoEnd(info);
}
return result;
}
@Override
protected String getCycType() {
return WorkerEnum.ELE_INVOICE_LEVY_CYC.value();
}
@Override
protected String getCycTaskDesc() {
return WorkerEnum.ELE_INVOICE_LEVY_CYC.getTitle();
}
@Override
protected Integer getLockNum() {
return 50;
}
private TaxInvoiceQuery buildTaxInvoiceQuery(String refId) {
TaxInvoiceQuery query = new TaxInvoiceQuery();
query.setOrderNo(refId);
return query;
}
}
protected String getCycTaskDesc() {
return WorkerEnum.ELE_INVOICE_LEVY_CYC.getTitle();
}
@Override
protected Integer getLockNum() {
return 50;
}
private TaxInvoiceQuery buildTaxInvoiceQuery(String refId) {
TaxInvoiceQuery query = new TaxInvoiceQuery();
query.setOrderNo(refId);
return query;
}
}