From 45d3018ab9bc45ce2899cc0943b53d2ab1c2e716 Mon Sep 17 00:00:00 2001
From: Junjie <xjj@123>
Date: 星期日, 27 四月 2025 13:52:28 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/asrs/service/impl/TaskWrkServiceImpl.java |  302 ++++++++++++++++++++++++++++----------------------
 1 files changed, 170 insertions(+), 132 deletions(-)

diff --git a/src/main/java/com/zy/asrs/service/impl/TaskWrkServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/TaskWrkServiceImpl.java
index 2393ee9..5b20240 100644
--- a/src/main/java/com/zy/asrs/service/impl/TaskWrkServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/TaskWrkServiceImpl.java
@@ -1,32 +1,20 @@
 package com.zy.asrs.service.impl;
 
-import com.alibaba.fastjson.JSON;
-import com.core.exception.CoolException;
-import com.zy.asrs.domain.enums.TaskStatusType;
-import com.zy.asrs.domain.enums.WorkNoType;
-import com.zy.asrs.entity.StaDesc;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.zy.asrs.mapper.TaskWrkMapper;
 import com.zy.asrs.entity.TaskWrk;
+import com.zy.asrs.service.ApiLogService;
 import com.zy.asrs.service.StaDescService;
 import com.zy.asrs.service.TaskWrkService;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
-import com.zy.asrs.utils.CommandUtils;
-import com.zy.asrs.utils.Utils;
 import com.zy.common.service.CommonService;
-import com.zy.core.DevpThread;
-import com.zy.core.cache.SlaveConnection;
-import com.zy.core.enums.CrnTaskModeType;
-import com.zy.core.enums.SlaveType;
-import com.zy.core.model.CrnSlave;
-import com.zy.core.model.Task;
-import com.zy.core.model.command.CrnCommand;
-import com.zy.core.model.protocol.StaProtocol;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Date;
 import java.util.List;
 
 @Slf4j
@@ -37,6 +25,12 @@
     private CommonService commonService;
     @Autowired
     private StaDescService staDescService;
+    @Value("${wms.url}")
+    private String wmsUrl;
+    @Value("${wms.taskStatusFeedbackPath}")
+    private String taskStatusFeedbackPath;
+    @Autowired
+    private ApiLogService apiLogService;
 
     @Override
     public TaskWrk selectByTaskNo(String taskNo) {
@@ -59,136 +53,170 @@
     }
 
     @Override
-    @Transactional
+    @Transactional(propagation = Propagation.REQUIRES_NEW)
     public void distribute(String taskNo, Long userId) {
-        TaskWrk taskWrk = this.selectByTaskNo(taskNo);
-        if (taskWrk == null) {
-            throw new CoolException("WMS浠诲姟涓嶅瓨鍦�");
-        }
-
-        if (taskWrk.getStatus() != 1) {
-            throw new CoolException("浠诲姟宸叉淳鍙�");
-        }
-
-        //鍒涘缓浠诲姟
-        if (taskWrk.getIoType() == 1) {
-            //1.鍏ュ簱
-            startup(taskWrk, userId);
-        }else if(taskWrk.getIoType() == 2){
-            //2.鍑哄簱
-            stockOut(taskWrk, userId);
-        } else if (taskWrk.getIoType() == 3) {
-            //3.搴撴牸绉昏浇
-            locMove(taskWrk, userId);
-        }
+//        TaskWrk taskWrk = this.selectByTaskNo(taskNo);
+//        if (taskWrk == null) {
+//            throw new CoolException("WMS浠诲姟涓嶅瓨鍦�");
+//        }
+//
+//        if (taskWrk.getStatus() != 1) {
+//            throw new CoolException("浠诲姟宸叉淳鍙�");
+//        }
+//
+//        //鍒涘缓浠诲姟
+//        if (taskWrk.getIoType() == 1) {
+//            //1.鍏ュ簱
+//            if (taskWrk.getStartPoint() == null || taskWrk.getTargetPoint() == null) {
+//                throw new CoolException("鏈帴鏀跺埌璧风偣鍜岀粓鐐癸紝涓嶈繘琛屾淳鍙�");
+//            }
+//            startup(taskWrk, userId);
+//        }else if(taskWrk.getIoType() == 2){
+//            //2.鍑哄簱
+//            stockOut(taskWrk, userId);
+//        } else if (taskWrk.getIoType() == 3) {
+//            //3.搴撴牸绉昏浇
+//            locMove(taskWrk, userId);
+//        }
     }
 
     @Override
     public void startup(TaskWrk taskWrk, Long userId) {
-        //鍏ュ簱浠诲姟娲惧彂
-        StaDesc staDesc = staDescService.queryCrn(taskWrk.getIoType(), Integer.parseInt(taskWrk.getStartPoint()));
-        if (staDesc == null) {
-            throw new CoolException("鍏ュ簱璺緞涓嶅瓨鍦�");
-        }
-        int workNo = commonService.getWorkNo(WorkNoType.PAKIN.type);//鑾峰彇鍏ュ簱宸ヤ綔鍙�
-        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
-        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
-        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
-        taskWrk.setWrkSts(2);//宸ヤ綔鐘舵�� 2.璁惧涓婅蛋
-        taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
-        taskWrk.setModiTime(new Date());
-        taskWrk.setModiUser(userId);
-        updateById(taskWrk);
 
-        CrnSlave.CrnStn crnStn = Utils.getCrnStnByStaNo(staDesc.getCrnStn(), true);
-        if (crnStn == null) {
-            throw new CoolException("鍫嗗灈鏈哄叆搴撶珯涓嶅瓨鍦�");
-        }
-        // 鍛戒护涓嬪彂鍖� --------------------------------------------------------------------------
-        CrnCommand crnCommand = new CrnCommand();
-        crnCommand.setCrnNo(staDesc.getCrnNo()); // 鍫嗗灈鏈虹紪鍙�
-        crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 宸ヤ綔鍙�
-        crnCommand.setAckFinish((short) 0);  // 浠诲姟瀹屾垚纭浣�
-        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 浠诲姟妯″紡:  搴撲綅绉昏浆
-        crnCommand.setSourcePosX(crnStn.getBay().shortValue());     // 婧愬簱浣嶅垪
-        crnCommand.setSourcePosY(crnStn.getLev().shortValue());     // 婧愬簱浣嶅眰
-        crnCommand.setSourcePosZ(crnStn.getRow().shortValue());     // 婧愬簱浣嶆帓
-        crnCommand.setDestinationPosX(Utils.getBayShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅鍒�
-        crnCommand.setDestinationPosY(Utils.getLevShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅灞�
-        crnCommand.setDestinationPosZ(Utils.getRowShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅鎺�
-        crnCommand.setCommand((short)1);
-        if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(2, crnCommand))) {
-            log.error("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐ワ紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
-            throw new CoolException("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐�");
-        }
+//        //鍏ュ簱浠诲姟娲惧彂
+//        StaDesc staDesc = staDescService.queryCrn(taskWrk.getIoType(), Integer.parseInt(taskWrk.getStartPoint()), taskWrk.getCrnNo());
+//        if (staDesc == null) {
+//            throw new CoolException("鍏ュ簱璺緞涓嶅瓨鍦�");
+//        }
+//        int workNo = commonService.getWorkNo(WorkNoType.PAKIN.type);//鑾峰彇鍏ュ簱宸ヤ綔鍙�
+//        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
+//        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
+//        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
+//        taskWrk.setWrkSts(3);//宸ヤ綔鐘舵�� 2.鍚婅溅鍏ュ簱
+//        taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
+//        taskWrk.setModiTime(new Date());
+//        taskWrk.setModiUser(userId);
+//        updateById(taskWrk);
+//
+//        CrnSlave.CrnStn crnStn = Utils.getCrnStnByStaNo(staDesc.getCrnStn(), true);
+//        if (crnStn == null) {
+//            throw new CoolException("鍫嗗灈鏈哄叆搴撶珯涓嶅瓨鍦�");
+//        }
+//        // 鍛戒护涓嬪彂鍖� --------------------------------------------------------------------------
+//        CrnCommand crnCommand = new CrnCommand();
+//        crnCommand.setCrnNo(staDesc.getCrnNo()); // 鍫嗗灈鏈虹紪鍙�
+//        crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 宸ヤ綔鍙�
+//        crnCommand.setAckFinish((short) 0);  // 浠诲姟瀹屾垚纭浣�
+//        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 浠诲姟妯″紡:  搴撲綅绉昏浆
+//        crnCommand.setSourcePosX(crnStn.getRow().shortValue());     // 婧愬簱浣嶅垪
+//        crnCommand.setSourcePosY(crnStn.getBay().shortValue());     // 婧愬簱浣嶅眰
+//        crnCommand.setSourcePosZ(crnStn.getLev().shortValue());     // 婧愬簱浣嶆帓
+//        crnCommand.setDestinationPosX(Utils.getRowShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅鍒�
+//        crnCommand.setDestinationPosY(Utils.getBayShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅灞�
+//        crnCommand.setDestinationPosZ(Utils.getLevShort(taskWrk.getTargetPoint()));     // 鐩爣搴撲綅鎺�
+//        crnCommand.setCommand((short)1);
+//        if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(5, crnCommand),false)) {
+//            log.error("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐ワ紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
+//            throw new CoolException("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐�");
+//        }else{
+//            try{
+//                HashMap<String, Object> headParam = new HashMap<>();
+//                headParam.put("taskNo",taskWrk.getTaskNo());
+//                headParam.put("status",taskWrk.getStatus());
+//                headParam.put("ioType",taskWrk.getIoType());
+//                headParam.put("barcode",taskWrk.getBarcode());
+////                headParam.put("reportTime",new Date());
+//                String response;
+//                response = new HttpHandler.Builder()
+//                        // .setHeaders(headParam)
+//                        .setUri(wmsUrl)
+//                        .setPath(taskStatusFeedbackPath)
+//                        .setJson(JSON.toJSONString(headParam))
+//                        .build()
+//                        .doPost();
+//
+//                JSONObject jsonObject = JSON.parseObject(response);
+//                apiLogService.save("wcs娲惧彂鍏ュ簱浠诲姟涓婃姤wms"
+//                        ,wmsUrl+taskStatusFeedbackPath
+//                        ,null
+//                        ,"127.0.0.1"
+//                        ,JSON.toJSONString(headParam)
+//                        ,response
+//                        ,true
+//                );
+//            }catch (Exception e){
+//                log.error("wcs娲惧彂鍏ュ簱浠诲姟涓婃姤wms澶辫触", taskWrk);
+////                throw new CoolException("wcs娲惧彂鍏ュ簱浠诲姟涓婃姤wms澶辫触");
+//            }
+//
+//        }
     }
 
     @Override
     public void stockOut(TaskWrk taskWrk, Long userId) {
-        //鍑哄簱浠诲姟娲惧彂
-        StaDesc staDesc = staDescService.queryCrn(taskWrk.getIoType(), Integer.parseInt(taskWrk.getTargetPoint()));
-        if (staDesc == null) {
-            return;//涓嶅瓨鍦ㄨ矾寰�
-        }
-        int workNo = commonService.getWorkNo(WorkNoType.PAKOUT.type);//鑾峰彇鍑哄簱宸ヤ綔鍙�
-        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
-        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
-        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
-        taskWrk.setWrkSts(11);//宸ヤ綔鐘舵�� 11.鐢熸垚鍑哄簱ID
-        taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
-        taskWrk.setModiTime(new Date());
-        taskWrk.setModiUser(userId);
-        updateById(taskWrk);
-
-        CrnSlave.CrnStn crnStn = Utils.getCrnStnByStaNo(staDesc.getCrnStn(), false);
-        if (crnStn == null) {
-            throw new CoolException("鍫嗗灈鏈哄嚭搴撶珯涓嶅瓨鍦�");
-        }
-        //鐢熸垚鍫嗗灈鏈哄嚭搴撳懡浠�
-        CrnCommand crnCommand = new CrnCommand();
-        crnCommand.setCrnNo(taskWrk.getCrnNo()); // 鍫嗗灈鏈虹紪鍙�
-        crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 宸ヤ綔鍙�
-        crnCommand.setAckFinish((short) 0);  // 浠诲姟瀹屾垚纭浣�
-        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 浠诲姟妯″紡:  搴撲綅绉昏浆
-        crnCommand.setSourcePosX(Utils.getBayShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶆帓
-        crnCommand.setSourcePosY(Utils.getLevShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶅垪
-        crnCommand.setSourcePosZ(Utils.getRowShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶅眰
-        crnCommand.setDestinationPosX(crnStn.getBay().shortValue());     // 鐩爣搴撲綅鎺�
-        crnCommand.setDestinationPosY(crnStn.getLev().shortValue());     // 鐩爣搴撲綅鍒�
-        crnCommand.setDestinationPosZ(crnStn.getRow().shortValue());     // 鐩爣搴撲綅灞�
-        crnCommand.setCommand((short)1);
-        if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(2, crnCommand))) {
-            log.error("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐ワ紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
-            throw new CoolException("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐�");
-        }
-
-        //鐢熸垚杈撻�佺嚎鍛戒护
-        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
-        StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()).clone();
-        staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
-        staProtocol.setStaNo((short) Integer.parseInt(taskWrk.getTargetPoint()));
-        if (!CommandUtils.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
-            log.error("杈撻�佺嚎鍛戒护鐢熸垚澶辫触锛屽爢鍨涙満鍙�={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
-            throw new CoolException("杈撻�佺嚎鍛戒护鐢熸垚澶辫触");
-        }
+//        //鍑哄簱浠诲姟娲惧彂
+//        StaDesc staDesc = staDescService.queryCrn(taskWrk.getIoType(), Integer.parseInt(taskWrk.getTargetPoint()), taskWrk.getCrnNo());
+//        if (staDesc == null) {
+//            return;//涓嶅瓨鍦ㄨ矾寰�
+//        }
+//        int workNo = commonService.getWorkNo(WorkNoType.PAKOUT.type);//鑾峰彇鍑哄簱宸ヤ綔鍙�
+//        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
+//        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
+//        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
+//        taskWrk.setWrkSts(12);//宸ヤ綔鐘舵�� 12.鍚婅溅鍏ュ簱涓�
+//        taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
+//        taskWrk.setModiTime(new Date());
+//        taskWrk.setModiUser(userId);
+//        updateById(taskWrk);
+//
+//        CrnSlave.CrnStn crnStn = Utils.getCrnStnByStaNo(staDesc.getCrnStn(), false);
+//        if (crnStn == null) {
+//            throw new CoolException("鍫嗗灈鏈哄嚭搴撶珯涓嶅瓨鍦�");
+//        }
+//        //鐢熸垚鍫嗗灈鏈哄嚭搴撳懡浠�
+//        CrnCommand crnCommand = new CrnCommand();
+//        crnCommand.setCrnNo(taskWrk.getCrnNo()); // 鍫嗗灈鏈虹紪鍙�
+//        crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 宸ヤ綔鍙�
+//        crnCommand.setAckFinish((short) 0);  // 浠诲姟瀹屾垚纭浣�
+//        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 浠诲姟妯″紡:  搴撲綅绉昏浆
+//        crnCommand.setSourcePosX(Utils.getBayShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶆帓
+//        crnCommand.setSourcePosY(Utils.getLevShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶅垪
+//        crnCommand.setSourcePosZ(Utils.getRowShort(taskWrk.getStartPoint()));     // 婧愬簱浣嶅眰
+//        crnCommand.setDestinationPosX(crnStn.getBay().shortValue());     // 鐩爣搴撲綅鎺�
+//        crnCommand.setDestinationPosY(crnStn.getLev().shortValue());     // 鐩爣搴撲綅鍒�
+//        crnCommand.setDestinationPosZ(crnStn.getRow().shortValue());     // 鐩爣搴撲綅灞�
+//        crnCommand.setCommand((short)1);
+//        if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(5, crnCommand))) {
+//            log.error("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐ワ紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
+//            throw new CoolException("鍫嗗灈鏈哄懡浠ょ敓鎴愬け璐�");
+//        }
+//
+//        //鐢熸垚杈撻�佺嚎鍛戒护
+//        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
+//        StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()).clone();
+//        staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
+//        staProtocol.setStaNo((short) Integer.parseInt(taskWrk.getTargetPoint()));
+//        if (!CommandUtils.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(3, staProtocol))) {
+//            log.error("杈撻�佺嚎鍛戒护鐢熸垚澶辫触锛屽爢鍨涙満鍙�={}锛屼换鍔℃暟鎹�={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
+//            throw new CoolException("杈撻�佺嚎鍛戒护鐢熸垚澶辫触");
+//        }
     }
 
     @Override
     public void locMove(TaskWrk taskWrk, Long userId) {
-        //搴撴牸绉昏浇浠诲姟娲惧彂
-        StaDesc staDesc = staDescService.queryCrn(taskWrk.getIoType(), Integer.parseInt(taskWrk.getTargetPoint()));
-        if (staDesc == null) {
-            return;//涓嶅瓨鍦ㄨ矾寰�
-        }
-        int workNo = commonService.getWorkNo(WorkNoType.OTHER.type);//鑾峰彇宸ヤ綔鍙�
-        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
-        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
-        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
-        taskWrk.setWrkSts(11);//宸ヤ綔鐘舵�� 11.鐢熸垚鍑哄簱ID
-        taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
-        taskWrk.setModiTime(new Date());
-        taskWrk.setModiUser(userId);
-        updateById(taskWrk);
+//        //搴撴牸绉昏浇浠诲姟娲惧彂
+//       if (Cools.isEmpty(taskWrk.getTargetPoint())){
+//           return;
+//       }
+//        int workNo = commonService.getWorkNo(WorkNoType.OTHER.type);//鑾峰彇宸ヤ綔鍙�
+//        taskWrk.setWrkNo(workNo);//宸ヤ綔鍙�
+//        taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//娲惧彂鐘舵��
+//        taskWrk.setAssignTime(new Date());//娲惧彂鏃堕棿
+//        taskWrk.setWrkSts(11);//宸ヤ綔鐘舵�� 11.鐢熸垚鍑哄簱ID
+//        //taskWrk.setCrnNo(staDesc.getCrnNo());//鍫嗗灈鏈哄彿
+//        taskWrk.setModiTime(new Date());
+//        taskWrk.setModiUser(userId);
+//        updateById(taskWrk);
     }
 
     @Override
@@ -200,4 +228,14 @@
     public int saveToHistory(String taskNo) {
         return this.baseMapper.saveToHistory(taskNo);
     }
+
+    @Override
+    public int getStoreCount(Integer crnNo){
+        return selectCount(new EntityWrapper<TaskWrk>().eq("crn_no", crnNo).in("wrk_sts",12,2));
+    }
+
+    @Override
+    public TaskWrk selectStaWorking(Integer wrkNo){
+        return this.baseMapper.selectStaWorking(wrkNo);
+    }
 }

--
Gitblit v1.9.1