From 945764de58898661a3f3197e58353141b5deaf91 Mon Sep 17 00:00:00 2001
From: pang.jiabao <pang_jiabao@163.com>
Date: 星期三, 22 十月 2025 16:21:15 +0800
Subject: [PATCH] 侧面输送线出入库流程对接

---
 src/main/java/com/zy/asrs/entity/TaskWrk.java                |    4 +
 src/main/java/com/zy/asrs/controller/OpenController.java     |   34 ++++++++
 src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java  |    2 
 src/main/resources/wcs和wms接口(2).docx                         |    0 
 src/main/resources/mapper/TaskWrkMapper.xml                  |    2 
 src/main/java/com/zy/asrs/entity/TaskWrkLog.java             |    3 
 src/main/java/com/zy/core/model/protocol/StaProtocol.java    |   10 +-
 src/main/java/com/zy/asrs/task/TaskReportScheduler.java      |   69 +++++++++++++++++
 src/main/java/com/zy/asrs/entity/param/PreStoragePallet.java |   28 +++++++
 src/main/java/com/zy/asrs/entity/param/TaskCreateParam.java  |    9 -
 src/main/resources/mapper/TaskWrkLogMapper.xml               |    1 
 src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java  |   24 +++++
 src/main/java/com/zy/core/thread/SiemensDevpThread.java      |   52 +++++++++++-
 src/main/resources/application.yml                           |    2 
 14 files changed, 220 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/zy/asrs/controller/OpenController.java b/src/main/java/com/zy/asrs/controller/OpenController.java
index 961d675..9a7f185 100644
--- a/src/main/java/com/zy/asrs/controller/OpenController.java
+++ b/src/main/java/com/zy/asrs/controller/OpenController.java
@@ -9,10 +9,18 @@
 import com.zy.asrs.domain.param.ApplyInDevpDto;
 import com.zy.asrs.entity.*;
 import com.zy.asrs.entity.param.CrnStatusParam;
+import com.zy.asrs.entity.param.PreStoragePallet;
 import com.zy.asrs.entity.param.TaskCreateParam;
 import com.zy.asrs.entity.param.WMSAndAGVInterfaceParam;
 import com.zy.asrs.service.*;
+import com.zy.asrs.service.impl.OpenServiceImpl;
 import com.zy.common.web.BaseController;
+import com.zy.core.DevpThread;
+import com.zy.core.cache.MessageQueue;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.model.Task;
+import com.zy.core.model.protocol.StaProtocol;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -52,6 +60,32 @@
     @Autowired
     private BasCrnErrorService basCrnErrorService;
 
+    // WMS鍏ュ簱鍓嶄笅鍙戠爜鐩樹俊鎭�
+    @PostMapping("/preStoragePallet")
+    public R preStoragePallet(@RequestHeader String appkey, @RequestBody PreStoragePallet preStoragePallet, HttpServletRequest request) {
+        auth(appkey, preStoragePallet, request);
+        if(Cools.isEmpty(preStoragePallet.getSite(),preStoragePallet.getLx(),preStoragePallet.getLev())) {
+            return R.error("鍙傛暟涓嶅畬鏁达紝璇锋鏌ワ細"  + preStoragePallet);
+        }
+        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
+        StaProtocol staProtocol = devpThread.getStation().get(preStoragePallet.getSite());
+        if (staProtocol == null) {
+            return R.error("绔欑偣绾跨▼涓嶅瓨鍦細" + preStoragePallet.getSite());
+        } else {
+            staProtocol = staProtocol.clone();
+        }
+
+        staProtocol.setMp((short) (preStoragePallet.getLev() > 1 ? 1 : 2));
+        staProtocol.setLev(preStoragePallet.getLev());
+        staProtocol.setLx(OpenServiceImpl.getGzlx(preStoragePallet.getLx()));
+
+        boolean offer = MessageQueue.offer(SlaveType.Devp, 1, new Task(3, staProtocol));
+        if(!offer) {
+            return R.error("鎺ㄩ�侀槦鍒楀け璐�");
+        }
+        return R.ok("鍏ュ簱鍓嶄笅鍙戠爜鐩樹俊鎭垚鍔�");
+    }
+
     //鍒涘缓浠诲姟
     @PostMapping("/taskCreate")
     @Transactional
diff --git a/src/main/java/com/zy/asrs/entity/TaskWrk.java b/src/main/java/com/zy/asrs/entity/TaskWrk.java
index 1822651..1d75370 100644
--- a/src/main/java/com/zy/asrs/entity/TaskWrk.java
+++ b/src/main/java/com/zy/asrs/entity/TaskWrk.java
@@ -180,6 +180,7 @@
     @TableField("type")
     private String type;
 
+    // 1锛氱爜鐩樸��  2涓嶇爜鐩�
     @TableField("mp")
     private short mp;
 
@@ -189,6 +190,9 @@
     @TableField("lev")
     private short lev;
 
+    @TableField("mp_completed_report")
+    private Integer mpCompletedReport;
+
     public TaskWrk() {
     }
 
diff --git a/src/main/java/com/zy/asrs/entity/TaskWrkLog.java b/src/main/java/com/zy/asrs/entity/TaskWrkLog.java
index 08df704..d4e8755 100644
--- a/src/main/java/com/zy/asrs/entity/TaskWrkLog.java
+++ b/src/main/java/com/zy/asrs/entity/TaskWrkLog.java
@@ -180,6 +180,9 @@
     @TableField("lev")
     private short lev;
 
+    @TableField("mp_completed_report")
+    private Integer mpCompletedReport;
+
     public TaskWrkLog() {
     }
 
diff --git a/src/main/java/com/zy/asrs/entity/param/PreStoragePallet.java b/src/main/java/com/zy/asrs/entity/param/PreStoragePallet.java
new file mode 100644
index 0000000..11c43ed
--- /dev/null
+++ b/src/main/java/com/zy/asrs/entity/param/PreStoragePallet.java
@@ -0,0 +1,28 @@
+package com.zy.asrs.entity.param;
+
+import lombok.Data;
+
+/**
+ * @author pang.jiabao
+ * @description 绔欑偣鐮佺洏淇℃伅
+ * @createDate 2025/10/21 14:29
+ */
+@Data
+public class PreStoragePallet {
+
+    /**
+     * 绔欑偣
+     */
+    private int site;
+
+    /**
+     * 宸ヨ绫诲瀷 WMS涓嬪彂 N65/N87/G4X/B10 WCS杞崲涓�4锛孨74/PPE 杞崲涓�3
+     */
+    private String lx;
+
+    /**
+     * 鐮佺洏灞傛暟
+     */
+    private short lev;
+
+}
diff --git a/src/main/java/com/zy/asrs/entity/param/TaskCreateParam.java b/src/main/java/com/zy/asrs/entity/param/TaskCreateParam.java
index bf4fc42..77d593f 100644
--- a/src/main/java/com/zy/asrs/entity/param/TaskCreateParam.java
+++ b/src/main/java/com/zy/asrs/entity/param/TaskCreateParam.java
@@ -36,14 +36,9 @@
     private Integer crn;
 
     /**
-     * 1锛氱爜鐩樸��  2涓嶇爜鐩�
+     * 宸ヨ绫诲瀷
      */
-    private short mp;
-
-    /**
-     * 绉嶇被1 姘歌繙涓嶅彔鐩橈紱2鍙�2灞傦紱3鍙犱笁灞傦紱4鍙犲洓灞�
-     */
-    private short lx;
+    private String lx;
 
     /**
      * 鐮佺洏灞傛暟
diff --git a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
index 786c08c..8ed5dc1 100644
--- a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -182,7 +182,7 @@
                         storageEscalationParam.setBarcode(BoxNo);
                         storageEscalationParam.setMatIdList(staProtocol.getMatIdList());
                         storageEscalationParam.setFullPlt(staProtocol.isFullPlt() ? 1 : 0);
-                        storageEscalationParam.setMpHigh(staProtocol.getMpHigh());
+                        storageEscalationParam.setMpHigh((short) (staProtocol.getSiteId() < 200 ? 1 :staProtocol.isHigh() ? 2 : staProtocol.isLow() ? 1 : 0));    // 楂樺害锛屼晶闈㈢爜鐩樼殑楂樺害 浣�1锛岄珮2
                         log.info("缁勬墭鍏ュ簱={}", storageEscalationParam);
                         TaskWrk taskWrk = toWmsService.getLocNoFromWms(storageEscalationParam);
                         if (taskWrk == null) {
diff --git a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
index aa8cb04..e5a0462 100644
--- a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -47,6 +47,26 @@
     @Value("${wms.url}")
     private String wmsUrl;
 
+    /**
+     * 宸ヨ绫诲瀷 WMS涓嬪彂 N65/N87/G4X/B10 WCS杞崲涓�4锛孨74/PPE 杞崲涓�3
+     */
+    public static short getGzlx(String lx) {
+        if (Cools.isEmpty(lx)) {
+            return 0;
+        }
+        switch (lx) {
+            case "N74":
+            case "PPE":
+                return 3;
+            case "N65":
+            case "N87":
+            case "B10":
+                return 4;
+            default:
+                return 0;
+        }
+    }
+
     @Override
     public HashMap<String, Object> taskCreate(TaskCreateParam param) {
         HashMap<String, Object> map = new HashMap<>();
@@ -81,8 +101,8 @@
         taskWrk.setBarcode(param.getBarcode());//鏉$爜
         taskWrk.setCrnNo(locMast.getCrnNo());
         taskWrk.setType(param.getType());
-        taskWrk.setMp(param.getMp());
-        taskWrk.setLx(param.getLx());
+        taskWrk.setMp((short) (param.getLev() > 1 ? 1 : 2));
+        taskWrk.setLx(getGzlx(param.getLx()));
         taskWrk.setLev(param.getLev());
         if (param.getIoType() == 1) {
             taskWrk.setWrkSts(1);
diff --git a/src/main/java/com/zy/asrs/task/TaskReportScheduler.java b/src/main/java/com/zy/asrs/task/TaskReportScheduler.java
index f574cce..f0a65bf 100644
--- a/src/main/java/com/zy/asrs/task/TaskReportScheduler.java
+++ b/src/main/java/com/zy/asrs/task/TaskReportScheduler.java
@@ -38,6 +38,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 瀹氭椂灏嗕换鍔�(瀹屾垚銆佸彇娑�)杞垚鏃ュ織
@@ -65,6 +66,9 @@
     @Value("${wms.completeDevpTask}")
     private String completeDevpTask;
 
+    @Value("${wms.reportPalletizingCompleted}")
+    private String reportPalletizingCompleted;
+
     @Resource
     private TaskWrkMapper taskWrkMapper;
 
@@ -82,6 +86,71 @@
         add(301);add(302);add(303);add(304);add(305);add(306);add(307);add(308);
     }};
 
+    // 渚ч潰鐮佺洏瀹屾垚涓婃姤wms
+    @Scheduled(cron = "0/3 * * * * ? ")
+    public synchronized void reportPalletizingCompleted() {
+        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
+        if (devpThread != null) {
+            Map<Integer, StaProtocol> staProtocolMap = devpThread.getStation();
+            int[] siteArray = new int[]{203, 207, 212};
+            for (int site : siteArray) {
+                StaProtocol staProtocol = staProtocolMap.get(site);
+                if (staProtocol != null) {
+                    short mpCompletedFlag = staProtocol.getMpCompletedFlag();
+                    if (mpCompletedFlag == 1) {
+                        TaskWrk taskWrk = taskWrkMapper.selectByWrkNo(Integer.valueOf(staProtocol.getWorkNo()));
+                        if (taskWrk != null) {
+
+                            // 璇锋眰浣�
+                            JSONObject request = new JSONObject();
+                            request.put("site", site);
+
+                            String response = "";
+                            boolean bool = false;
+                            try {
+                                response = new HttpHandler.Builder()
+                                        // .setHeaders(headParam)
+                                        .setUri(wmsUrl)
+                                        .setPath(reportPalletizingCompleted)
+                                        .setJson(JSON.toJSONString(request))
+                                        .build()
+                                        .doPost();
+                                if (!Cools.isEmpty(response)) {
+                                    JSONObject jsonObject = JSON.parseObject(response);
+                                    if (Integer.parseInt(String.valueOf(jsonObject.get("code"))) == 200) {
+                                        bool = true;
+                                        // 鎺ㄩ�侀槦鍒�
+                                        boolean offer = MessageQueue.offer(SlaveType.Devp, 4, new Task(1, staProtocol));
+                                        if (offer) {
+                                            // 鏇存柊鏁版嵁搴�
+                                            taskWrk.setMpCompletedReport(1);
+                                            taskWrkMapper.updateById(taskWrk);
+                                        } else {
+                                            log.error("渚ч潰鐮佺洏瀹屾垚涓婃姤wms鎺ㄩ�侀槦鍒楀け璐ワ紝绔欑偣锛歿}锛屼换鍔″彿锛歿}", site, staProtocol.getWorkNo());
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                                log.error("渚ч潰鐮佺洏瀹屾垚涓婃姤wms澶辫触{},杩斿洖鍊�={}", taskWrk, response);
+                            } finally {
+                                apiLogService.save("渚ч潰鐮佺洏瀹屾垚涓婃姤wms"
+                                        , wmsUrl + reportPalletizingCompleted
+                                        , null
+                                        , "127.0.0.1"
+                                        , JSON.toJSONString(request)
+                                        , response
+                                        , bool
+                                );
+                            }
+                        } else {
+                            log.error("渚ч潰鐮佺洏瀹屾垚涓婃姤wms娌℃湁鎵惧埌璇ヤ换鍔★紝绔欑偣锛歿}锛屼换鍔″彿锛歿}", site, staProtocol.getWorkNo());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     // WMS鍒嗛厤鍏ュ簱搴撲綅寮傚父涓婃姤
     @Scheduled(cron = "0/5 * * * * ? ")
     @Transactional
diff --git a/src/main/java/com/zy/core/model/protocol/StaProtocol.java b/src/main/java/com/zy/core/model/protocol/StaProtocol.java
index 54b0c3f..51fe31a 100644
--- a/src/main/java/com/zy/core/model/protocol/StaProtocol.java
+++ b/src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -73,16 +73,13 @@
     // 鏉$爜锛屼晶闈㈠嚭搴撶粰杈撻�佺嚎
     private String barcode;
 
-    // 楂樺害锛屼晶闈㈢爜鐩樼殑楂樺害
-    private short mpHigh;
-
     /**
      * 1锛氱爜鐩樸��  2涓嶇爜鐩�
      */
     private short mp;
 
     /**
-     * 绉嶇被1 姘歌繙涓嶅彔鐩橈紱2鍙�2灞傦紱3鍙犱笁灞傦紱4鍙犲洓灞�
+     * 宸ヨ绫诲瀷 WMS涓嬪彂 N65/N87/G4X/B10 WCS杞崲涓�4锛孨74/PPE 杞崲涓�3
      */
     private short lx;
 
@@ -91,6 +88,11 @@
      */
     private short lev;
 
+    /**
+     * 鐮佺洏瀹屾垚鏍囪瘑 0.鏈畬鎴愶紝1.瀹屾垚
+     */
+    private short mpCompletedFlag;
+
     // 澶栧舰妫�娴� ------------------------------------------------------------------------
 
     // 鍓嶈秴闄�
diff --git a/src/main/java/com/zy/core/thread/SiemensDevpThread.java b/src/main/java/com/zy/core/thread/SiemensDevpThread.java
index fa86ccd..a1f5de1 100644
--- a/src/main/java/com/zy/core/thread/SiemensDevpThread.java
+++ b/src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -164,6 +164,11 @@
                         write3((StaProtocol) task.getData());
                         read();
                         break;
+                    // 渚ч潰鐮佺洏瀹屾垚涓婃姤wms鎴愬姛鍚庨噸缃畃lc
+                    case 4:
+                        write4((StaProtocol) task.getData());
+                        read();
+                        break;
                     default:
                         break;
                 }
@@ -295,6 +300,15 @@
                         staProtocol.setPakMk(true);
                     }
                 }
+            }
+
+            // 璇讳晶闈㈢爜鐩樺畬鎴愪俊鍙�
+            OperateResultExOne<byte[]> resultMp = siemensS7Net.Read("DB79.362", (short) 4);
+            if (resultMp.IsSuccess) {
+                StaProtocol staProtocol207 = station.get(207);
+                StaProtocol staProtocol212 = station.get(212);
+                staProtocol207.setMpCompletedFlag(siemensS7Net.getByteTransform().TransInt16(resultMp.Content, 0));
+                staProtocol212.setMpCompletedFlag(siemensS7Net.getByteTransform().TransInt16(resultMp.Content, 2));
             }
 
             // 璇诲彇姝i潰鏉$爜
@@ -684,7 +698,7 @@
             OperateResult writeResult3 = siemensS7Net.Write(addressPre + lev, staProtocol.getLev());    // 鐮佺洏灞傛暟
             if (writeResult1.IsSuccess && writeResult2.IsSuccess && writeResult3.IsSuccess) {
                     writeFlag = true;
-                    log.info("鐮佺洏淇℃伅鍐欏叆杈撻�佺嚎鍛戒护鍚庤繑鍥炴垚鍔燂紝骞朵笖鍥炶鎴愬姛銆傝緭閫佺嚎plc缂栧彿={}锛寋}锛屽啓鍏ユ鏁�={}", slave.getId(), JSON.toJSON(staProtocol), writeCount);
+                    log.info("鐮佺洏淇℃伅鍐欏叆杈撻�佺嚎鍛戒护鍚庤繑鍥炴垚鍔熴�恵},{},{},{}銆戯紝骞朵笖鍥炶鎴愬姛锛屽啓鍏ユ鏁�={}", staProtocol.getSiteId(),staProtocol.getMp(),staProtocol.getLx(),staProtocol.getLev(), writeCount);
                     break;
             } else {
                 writeCount++;
@@ -693,10 +707,38 @@
         }
 
         //鍐欏懡浠ゅ皾璇曚簡5娆¤繕鏄け璐ヤ簡
-        if (!writeFlag) {
-            //閲嶆柊娣诲姞鏁版嵁鍒颁换鍔¢槦鍒�
-            MessageQueue.offer(SlaveType.Devp, 1, new Task(3, staProtocol));
-            log.error("鐮佺洏淇℃伅鍐欏叆杈撻�佺嚎鍛戒护灏濊瘯5娆″け璐ラ噸鏂版帹閫侀槦鍒椼�傝緭閫佺嚎plc缂栧彿={}锛岀珯鐐规暟鎹�={}", slave.getId(), JSON.toJSON(staProtocol));
+//        if (!writeFlag) {
+//            //閲嶆柊娣诲姞鏁版嵁鍒颁换鍔¢槦鍒�
+//            MessageQueue.offer(SlaveType.Devp, 1, new Task(3, staProtocol));
+//            log.error("鐮佺洏淇℃伅鍐欏叆杈撻�佺嚎鍛戒护灏濊瘯5娆″け璐ラ噸鏂版帹閫侀槦鍒椼�傝緭閫佺嚎plc缂栧彿={}锛岀珯鐐规暟鎹�={}", slave.getId(), JSON.toJSON(staProtocol));
+//        }
+    }
+
+    private void write4(StaProtocol staProtocol){
+
+        int offset = 0;
+
+        switch (staProtocol.getSiteId()) {
+            case 207: offset = 362;break;
+            case 212: offset = 364 ;break;
+            default:
+                log.error("閲嶇疆鐮佺洏淇″彿绔欑偣鏈夎锛歿}" , staProtocol.getSiteId());
+                return;
+        }
+
+        String addressPre = "DB79.";
+
+        //浠诲姟涓嬪彂娆℃暟
+        int writeCount = 0;
+        while (writeCount < 5) {
+            OperateResult writeResult1 = siemensS7Net.Write(addressPre + offset, (short) 0);
+            if (writeResult1.IsSuccess) {
+                log.info("渚ч潰鐮佺洏瀹屾垚涓婃姤wms鎴愬姛鍚庨噸缃俊鍙峰啓鍏ヨ緭閫佺嚎鍛戒护鍚庤繑鍥炴垚鍔熴�恵}銆戯紝骞朵笖鍥炶鎴愬姛锛屽啓鍏ユ鏁�={}", staProtocol.getSiteId(), writeCount);
+                break;
+            } else {
+                writeCount++;
+                log.error("渚ч潰鐮佺洏瀹屾垚涓婃姤wms鎴愬姛鍚庨噸缃俊鍙峰啓鍏ヨ緭閫佺嚎鍛戒护澶辫触銆傝緭閫佺嚎plc缂栧彿={}锛岀珯鐐规暟鎹�={},鍐欏叆娆℃暟={}", slave.getId(), JSON.toJSON(staProtocol), writeCount);
+            }
         }
     }
 
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 6d853af..3667e9b 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -64,6 +64,8 @@
   executionStatusReport: /executionStatusReport
   # 澶栫疆杈撻�佺嚎娴佸姩鍒颁綅涓婃姤wms
   completeDevpTask: /completeDevpTask
+  # 渚ч潰鍑哄簱鐮佺洏瀹屾垚涓婃姤wms
+  reportPalletizingCompleted: /taskStateReport
   # 娴嬭瘯鐜
 #  url: http://127.0.0.1:8080/ghlnwms
 #  taskStatusFeedbackPath: api/StereoscopicCallBack/TaskExecCallback
diff --git a/src/main/resources/mapper/TaskWrkLogMapper.xml b/src/main/resources/mapper/TaskWrkLogMapper.xml
index 373e6bb..519fbf9 100644
--- a/src/main/resources/mapper/TaskWrkLogMapper.xml
+++ b/src/main/resources/mapper/TaskWrkLogMapper.xml
@@ -28,6 +28,7 @@
         <result column="mp" property="mp"/>
         <result column="lx" property="lx"/>
         <result column="lev" property="lev"/>
+        <result column="mp_completed_report" property="mpCompletedReport"/>
     </resultMap>
 
 </mapper>
diff --git a/src/main/resources/mapper/TaskWrkMapper.xml b/src/main/resources/mapper/TaskWrkMapper.xml
index b7d3f81..6106ba4 100644
--- a/src/main/resources/mapper/TaskWrkMapper.xml
+++ b/src/main/resources/mapper/TaskWrkMapper.xml
@@ -28,7 +28,7 @@
         <result column="mp" property="mp"/>
         <result column="lx" property="lx"/>
         <result column="lev" property="lev"/>
-
+        <result column="mp_completed_report" property="mpCompletedReport"/>
     </resultMap>
     
     <select id="selectByTaskNo" resultMap="BaseResultMap">
diff --git "a/src/main/resources/wcs\345\222\214wms\346\216\245\345\217\243\0502\051.docx" "b/src/main/resources/wcs\345\222\214wms\346\216\245\345\217\243\0502\051.docx"
index 99ebe24..a41e665 100644
--- "a/src/main/resources/wcs\345\222\214wms\346\216\245\345\217\243\0502\051.docx"
+++ "b/src/main/resources/wcs\345\222\214wms\346\216\245\345\217\243\0502\051.docx"
Binary files differ

--
Gitblit v1.9.1