From 0ffdf00009b0bede0859fa33deddefb55c075a7b Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期日, 01 二月 2026 16:42:36 +0800
Subject: [PATCH] feat:优化增加任务同步接口,允许前端手动控制同步
---
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java | 354 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 323 insertions(+), 31 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
index b4bc326..36a79da 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
@@ -1,7 +1,19 @@
package com.ruoyi.web.controller.task;
+import java.util.Date;
import java.util.List;
+import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.annotation.Anonymous;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.system.domain.SysTaskEmergency;
+import com.ruoyi.system.service.*;
+import com.ruoyi.system.service.ILegacySystemSyncService;
+import com.ruoyi.system.service.ITaskDispatchSyncService;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -11,21 +23,25 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysTask;
import com.ruoyi.system.domain.SysTaskLog;
+import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.domain.vo.TaskQueryVO;
import com.ruoyi.system.domain.vo.TaskCreateVO;
import com.ruoyi.system.domain.vo.TaskUpdateVO;
import com.ruoyi.system.domain.vo.TaskStatisticsVO;
import com.ruoyi.system.domain.enums.TaskStatus;
-import com.ruoyi.system.service.ISysTaskService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.utils.StringUtils;
/**
* 浠诲姟绠$悊Controller
@@ -40,6 +56,29 @@
@Autowired
private ISysTaskService sysTaskService;
+ @Autowired
+ private ISysTaskEmergencyService sysTaskEmergencyService;
+
+ @Autowired
+ private IVehicleInfoService vehicleInfoService;
+
+ @Autowired
+ private ISysUserService userService;
+
+ @Autowired
+ private ISysDeptService deptService;
+
+
+ @Autowired
+ @Qualifier("tiandituMapService")
+ private IMapService mapService;
+
+ @Autowired
+ private ILegacySystemSyncService legacySystemSyncService;
+
+ @Autowired
+ private ITaskDispatchSyncService taskDispatchSyncService;
+
/**
* 鏌ヨ浠诲姟绠$悊鍒楄〃锛堝悗鍙扮鐞嗙锛�
* 绠$悊鍛樻潈闄愶紝鍙互鏌ョ湅鎵�鏈変换鍔�
@@ -48,27 +87,69 @@
@GetMapping("/admin/list")
public TableDataInfo adminList(TaskQueryVO queryVO) {
startPage();
- List<SysTask> list = sysTaskService.selectSysTaskList(queryVO);
+ // Handle multi-field task code search
+ String searchTaskCode = queryVO.getTaskCode();
+ List<SysTask> list;
+ if(searchTaskCode != null && !searchTaskCode.trim().isEmpty()){
+ // Search across task_code, emergency_info.dispatch_code, and emergency_info.service_code
+ list = sysTaskService.selectSysTaskListByMultiCode(queryVO, searchTaskCode);
+ } else {
+ queryVO.setTaskCode(null);
+ list = sysTaskService.selectSysTaskList(queryVO);
+ }
+
+
return getDataTable(list);
}
/**
* 鏌ヨ浠诲姟鍒楄〃锛圓PP绔級
- * 浠呮樉绀哄綋鍓嶇敤鎴风浉鍏崇殑浠诲姟锛�
- * 1. 褰撳墠鐢ㄦ埛鎵�鍦ㄦ満鏋勭殑浠诲姟
- * 2. 褰撳墠鐢ㄦ埛鍒涘缓鐨勪换鍔�
- * 3. 鍒嗛厤缁欏綋鍓嶇敤鎴风殑浠诲姟
+ * 鏍规嵁鐢ㄦ埛鏉冮檺杩斿洖涓嶅悓鑼冨洿鐨勪换鍔★細
+ * 1. 鏈夋煡鐪嬫墍鏈夊挩璇㈠崟鏉冮檺锛坈anViewAllConsult='1'锛夛細杩斿洖璇ョ敤鎴风鐞嗘墍鏈夊垎鍏徃涓嬬殑鎵�鏈変换鍔″崟
+ * 2. 鏃犳潈闄愶紙canViewAllConsult='0'锛夛細鍙繑鍥炲垎閰嶇粰璇ョ敤鎴风殑鍗曟垨璇ョ敤鎴峰垱寤虹殑鍗�
*/
@GetMapping("/list")
public TableDataInfo appList(TaskQueryVO queryVO) {
- // 鍦ㄥ悗绔嚜鍔ㄨ幏鍙栧綋鍓嶇敤鎴蜂俊鎭紝瀹炵幇缁煎悎鏌ヨ
+ // 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅
Long currentUserId = getUserId();
- Long currentDeptId = getDeptId();
+ SysUser currentUser = userService.selectUserById(currentUserId);
- // APP绔己鍒朵娇鐢ㄥ綋鍓嶇櫥褰曠敤鎴蜂俊鎭繘琛岃繃婊�
- queryVO.setDeptId(currentDeptId);
- queryVO.setCreatorId(currentUserId);
- queryVO.setAssigneeId(currentUserId);
+ if (currentUser == null) {
+ return getDataTable(new java.util.ArrayList<>());
+ }
+
+ // 鍒ゆ柇鐢ㄦ埛鏄惁鏈夋煡鐪嬫墍鏈夊挩璇㈠崟鐨勬潈闄�
+ String canViewAllConsult = currentUser.getCanViewAllConsult();
+
+ if ("1".equals(canViewAllConsult)) {
+ // 鏈夋潈闄愶細杩斿洖璇ョ敤鎴风鐞嗘墍鏈夊垎鍏徃涓嬬殑鎵�鏈変换鍔″崟
+ // 1. 鑾峰彇鐢ㄦ埛绠$悊鐨勫垎鍏徃鍒楄〃
+ List<SysDept> branchCompanies = deptService.computeBranchCompaniesForUser(currentUser);
+
+ if (branchCompanies != null && !branchCompanies.isEmpty()) {
+ // 2. 鎻愬彇鎵�鏈夊垎鍏徃ID
+ List<Long> deptIds = new java.util.ArrayList<>();
+ for (SysDept dept : branchCompanies) {
+ deptIds.add(dept.getDeptId());
+ }
+
+ // 3. 璁剧疆鏌ヨ鏉′欢涓哄垎鍏徃ID鍒楄〃锛圫QL浼氳嚜鍔ㄥ寘鍚墍鏈夊瓙閮ㄩ棬锛�
+ queryVO.setDeptIds(deptIds);
+ // 娓呯┖鍒涘缓浜哄拰鎵ц浜鸿繃婊ゆ潯浠讹紝杩斿洖杩欎簺鍒嗗叕鍙镐笅鐨勬墍鏈変换鍔�
+ queryVO.setCreatorId(null);
+ queryVO.setAssigneeId(null);
+ } else {
+ // 濡傛灉娌℃湁鎵惧埌鍒嗗叕鍙革紝杩斿洖绌哄垪琛�
+ return getDataTable(new java.util.ArrayList<>());
+ }
+ } else {
+ // 鏃犳潈闄愶細鍙繑鍥炲垎閰嶇粰璇ョ敤鎴风殑鍗曟垨璇ョ敤鎴峰垱寤虹殑鍗�
+ // 娓呯┖deptId鍜宒eptIds锛屼娇鐢╟reatorId鍜宎ssigneeId杩涜OR鏌ヨ
+ queryVO.setDeptId(null);
+ queryVO.setDeptIds(null);
+ queryVO.setCreatorId(currentUserId);
+ queryVO.setAssigneeId(currentUserId);
+ }
startPage();
List<SysTask> list = sysTaskService.selectSysTaskList(queryVO);
@@ -111,7 +192,8 @@
@Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
@PostMapping("/admin")
public AjaxResult adminAdd(@RequestBody TaskCreateVO createVO) {
- return toAjax(sysTaskService.insertSysTask(createVO));
+ Long taskId = sysTaskService.insertSysTask(createVO);
+ return taskId > 0 ? AjaxResult.success("鏂板鎴愬姛").put("taskId", taskId) : AjaxResult.error("鏂板澶辫触");
}
/**
@@ -120,7 +202,32 @@
@Log(title = "浠诲姟鍒涘缓", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult appAdd(@RequestBody TaskCreateVO createVO) {
- return toAjax(sysTaskService.insertSysTask(createVO));
+ Long taskId = sysTaskService.insertSysTask(createVO);
+ return taskId > 0 ? AjaxResult.success("鏂板鎴愬姛").put("taskId", taskId) : AjaxResult.error("鏂板澶辫触");
+ }
+
+ /**
+ * 妫�鏌ヤ换鍔℃槸鍚﹂噸澶嶏紙鏍规嵁鑱旂郴浜虹數璇濆拰鍒涘缓鏃ユ湡锛�
+ * @param phone 鑱旂郴浜虹數璇�
+ * @param createDate 浠诲姟鍒涘缓鏃ユ湡锛堟牸寮忥細YYYY-MM-DD锛�
+ * @return 鏄惁瀛樺湪閲嶅浠诲姟
+ */
+ @GetMapping("/checkDuplicate")
+ public AjaxResult checkDuplicate(
+ @RequestParam("phone") String phone,
+ @RequestParam("createDate") String createDate) {
+
+ if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(createDate)) {
+ return AjaxResult.error("鍙傛暟涓嶈兘涓虹┖");
+ }
+
+ boolean isDuplicate = sysTaskService.checkTaskDuplicate(phone, createDate);
+
+ if (isDuplicate) {
+ return AjaxResult.error("璇ヨ仈绯荤數璇濆湪璇ユ棩鏈熷凡鏈変换鍔★紝涓嶈兘閲嶅鎻愪氦");
+ }
+
+ return AjaxResult.success("鏈彂鐜伴噸澶嶄换鍔�");
}
/**
@@ -130,7 +237,7 @@
@Log(title = "浠诲姟绠$悊", businessType = BusinessType.UPDATE)
@PutMapping("/admin")
public AjaxResult adminEdit(@RequestBody TaskUpdateVO updateVO) {
- return toAjax(sysTaskService.updateSysTask(updateVO));
+ return toAjax(sysTaskService.updateSysTask(updateVO,false));
}
/**
@@ -139,7 +246,7 @@
@Log(title = "浠诲姟淇敼", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult appEdit(@RequestBody TaskUpdateVO updateVO) {
- return toAjax(sysTaskService.updateSysTask(updateVO));
+ return toAjax(sysTaskService.updateSysTask(updateVO,false));
}
/**
@@ -206,24 +313,53 @@
return error("鏃犳晥鐨勪换鍔$姸鎬�");
}
- // 濡傛灉鍖呭惈GPS浣嶇疆淇℃伅锛屼娇鐢ㄥ甫浣嶇疆鐨勬柟娉�
- if (request.getLatitude() != null && request.getLongitude() != null) {
- SysTaskLog locationLog = new SysTaskLog();
- locationLog.setLatitude(request.getLatitude());
- locationLog.setLongitude(request.getLongitude());
- locationLog.setLocationAddress(request.getLocationAddress());
- locationLog.setLocationProvince(request.getLocationProvince());
- locationLog.setLocationCity(request.getLocationCity());
- locationLog.setLocationDistrict(request.getLocationDistrict());
- locationLog.setGpsAccuracy(request.getGpsAccuracy());
- locationLog.setAltitude(request.getAltitude());
- locationLog.setSpeed(request.getSpeed());
- locationLog.setHeading(request.getHeading());
-
- return toAjax(sysTaskService.changeTaskStatusWithLocation(taskId, newStatus, request.getRemark(), locationLog));
+ // 濡傛灉鏄彇娑堢姸鎬侊紝淇濆瓨鍙栨秷鍘熷洜
+ if (newStatus == TaskStatus.CANCELLED && StringUtils.isNotEmpty(request.getCancelReason())) {
+ sysTaskService.saveCancelInfo(taskId, request.getCancelReason());
}
+ // 濡傛灉鏄己鍒跺畬鎴愶紝鏇存柊瀹為檯寮�濮嬫椂闂村拰缁撴潫鏃堕棿
+ if (newStatus == TaskStatus.COMPLETED && request.getActualStartTime() != null && request.getActualEndTime() != null) {
+ SysTask task = new SysTask();
+ task.setTaskId(taskId);
+ task.setTaskStatus(newStatus.getCode());
+ //灏哠tring杞垚Date
+
+ task.setActualStartTime(DateUtils.parseDate(request.getActualStartTime()));
+ task.setActualEndTime(DateUtils.parseDate(request.getActualEndTime()));
+ task.setRemark(request.getRemark());
+ task.setUpdateBy(SecurityUtils.getUsername());
+ task.setUpdateTime(DateUtils.getNowDate());
+
+ int result = sysTaskService.forceCompleteTask(task);
+ return toAjax(result);
+ }
+
+ // 濡傛灉鍖呭惈GPS浣嶇疆淇℃伅锛屼娇鐢ㄥ甫浣嶇疆鐨勬柟娉�
+ if (request.getLatitude() != null && request.getLongitude() != null) {
+ String address= mapService.reverseGeocoding(request.getLongitude(), request.getLatitude());
+ request.setLocationAddress(address);
+ SysTaskLog locationLog = getLocationLog(request);
+
+ return toAjax(sysTaskService.changeTaskStatusWithLocation(taskId, newStatus, request.getRemark(), locationLog));
+ }
+
return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark()));
+ }
+
+ private static SysTaskLog getLocationLog(ChangeStatusRequest request) {
+ SysTaskLog locationLog = new SysTaskLog();
+ locationLog.setLatitude(request.getLatitude());
+ locationLog.setLongitude(request.getLongitude());
+ locationLog.setLocationAddress(request.getLocationAddress());
+ locationLog.setLocationProvince(request.getLocationProvince());
+ locationLog.setLocationCity(request.getLocationCity());
+ locationLog.setLocationDistrict(request.getLocationDistrict());
+ locationLog.setGpsAccuracy(request.getGpsAccuracy());
+ locationLog.setAltitude(request.getAltitude());
+ locationLog.setSpeed(request.getSpeed());
+ locationLog.setHeading(request.getHeading());
+ return locationLog;
}
/**
@@ -274,6 +410,48 @@
}
/**
+ * 妫�鏌ヨ溅杈嗘槸鍚︽湁姝e湪杩涜涓殑浠诲姟锛圓PP绔級
+ * 姝e湪杩涜涓殑浠诲姟鏄寚鐘舵�佷笉涓猴細PENDING锛堝緟澶勭悊锛夈�丆OMPLETED锛堝凡瀹屾垚锛夈�丆ANCELLED锛堝凡鍙栨秷锛夌殑浠诲姟
+ */
+ @GetMapping("/vehicle/{vehicleId}/active")
+ public AjaxResult checkVehicleActiveTasks(@PathVariable Long vehicleId) {
+ List<SysTask> activeTasks = sysTaskService.checkVehicleActiveTasks(vehicleId);
+ return success(activeTasks);
+ }
+
+ /**
+ * 妫�鏌ヤ换鍔℃槸鍚﹀彲浠ュ嚭鍙戯紙APP绔級
+ * 妫�鏌ワ細
+ * 1. 杞﹁締鏄惁鏈夋湭瀹屾垚鐨勪换鍔�
+ * 2. 鎵ц浜哄憳鏄惁鏈夋湭瀹屾垚鐨勪换鍔�
+ *
+ * @param taskId 浠诲姟ID
+ * @return 鏍¢獙缁撴灉
+ */
+ @GetMapping("/{taskId}/check-depart")
+ public AjaxResult checkTaskCanDepart(@PathVariable Long taskId) {
+ return sysTaskService.checkTaskCanDepart(taskId);
+ }
+
+ /**
+ * 鎵ц浜虹偣鍑诲氨缁紙APP绔級
+ */
+ @PostMapping("/{taskId}/assignee/ready")
+ public AjaxResult setAssigneeReady(@PathVariable Long taskId) {
+ Long userId = getUserId();
+ return sysTaskService.setAssigneeReady(taskId, userId);
+ }
+
+ /**
+ * 鎵ц浜哄彇娑堝氨缁紙APP绔級
+ */
+ @PostMapping("/{taskId}/assignee/cancel-ready")
+ public AjaxResult cancelAssigneeReady(@PathVariable Long taskId) {
+ Long userId = getUserId();
+ return sysTaskService.cancelAssigneeReady(taskId, userId);
+ }
+
+ /**
* 鍒嗛厤浠诲姟璇锋眰瀵硅薄
*/
public static class AssignTaskRequest {
@@ -315,6 +493,15 @@
private Double altitude;
private Double speed;
private Double heading;
+
+ // 鍙栨秷鐩稿叧瀛楁
+ private String cancelReason; // 鍙栨秷鍘熷洜锛堝叧鑱旀暟鎹瓧鍏竧ask_cancel_reason锛�
+
+ // 寮哄埗瀹屾垚鐩稿叧瀛楁
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+ private String actualStartTime; // 瀹為檯寮�濮嬫椂闂�
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+ private String actualEndTime; // 瀹為檯缁撴潫鏃堕棿
public String getTaskStatus() {
return taskStatus;
@@ -411,5 +598,110 @@
public void setHeading(Double heading) {
this.heading = heading;
}
+
+ public String getCancelReason() {
+ return cancelReason;
+ }
+
+ public void setCancelReason(String cancelReason) {
+ this.cancelReason = cancelReason;
+ }
+
+ public String getActualStartTime() {
+ return actualStartTime;
+ }
+
+ public void setActualStartTime(String actualStartTime) {
+ this.actualStartTime = actualStartTime;
+ }
+
+ public String getActualEndTime() {
+ return actualEndTime;
+ }
+
+ public void setActualEndTime(String actualEndTime) {
+ this.actualEndTime = actualEndTime;
+ }
+ }
+
+ /**
+ * 鎵嬪姩鍚屾鏈嶅姟鍗曞埌鏃х郴缁�
+ * 褰撴湇鍔″崟鍚屾澶辫触鎴栨湭鍚屾鏃讹紝鍙互閫氳繃姝ゆ帴鍙f墜鍔ㄨЕ鍙戝悓姝�
+ */
+ @PreAuthorize("@ss.hasPermi('task:general:edit')")
+ @Log(title = "鎵嬪姩鍚屾鏈嶅姟鍗�", businessType = BusinessType.UPDATE)
+ @PostMapping("/syncServiceOrder/{taskId}")
+ public AjaxResult syncServiceOrder(@PathVariable Long taskId) {
+ try {
+ // 鏌ヨ浠诲姟淇℃伅
+ SysTask task = sysTaskService.selectSysTaskByTaskId(taskId);
+ if (task == null) {
+ return error("浠诲姟涓嶅瓨鍦�");
+ }
+
+ // 鍙敮鎸佹�ユ晳杞繍浠诲姟
+ if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) {
+ return error("鍙湁鎬ユ晳杞繍浠诲姟鎵嶈兘鍚屾鍒版棫绯荤粺");
+ }
+
+ // 璋冪敤鍚屾鏈嶅姟
+ Long serviceOrdId = legacySystemSyncService.syncEmergencyTaskToLegacy(taskId);
+
+ if (serviceOrdId != null && serviceOrdId > 0) {
+ return success("鏈嶅姟鍗曞悓姝ユ垚鍔燂紝ServiceOrdID: " + serviceOrdId);
+ } else {
+ return error("鏈嶅姟鍗曞悓姝ュけ璐ワ紝璇锋煡鐪嬪悓姝ラ敊璇俊鎭�");
+ }
+
+ } catch (Exception e) {
+ logger.error("鎵嬪姩鍚屾鏈嶅姟鍗曞紓甯革紝taskId: {}", taskId, e);
+ return error("鍚屾寮傚父: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 鎵嬪姩鍚屾璋冨害鍗曞埌鏃х郴缁�
+ * 褰撹皟搴﹀崟鍚屾澶辫触鎴栨湭鍚屾鏃讹紝鍙互閫氳繃姝ゆ帴鍙f墜鍔ㄨЕ鍙戝悓姝�
+ */
+ @PreAuthorize("@ss.hasPermi('task:general:edit')")
+ @Log(title = "鎵嬪姩鍚屾璋冨害鍗�", businessType = BusinessType.UPDATE)
+ @PostMapping("/syncDispatchOrder/{taskId}")
+ public AjaxResult syncDispatchOrder(@PathVariable Long taskId) {
+ try {
+ // 鏌ヨ浠诲姟淇℃伅
+ SysTask task = sysTaskService.selectSysTaskByTaskId(taskId);
+ if (task == null) {
+ return error("浠诲姟涓嶅瓨鍦�");
+ }
+
+ // 鍙敮鎸佹�ユ晳杞繍浠诲姟
+ if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) {
+ return error("鍙湁鎬ユ晳杞繍浠诲姟鎵嶈兘鍚屾鍒版棫绯荤粺");
+ }
+
+ // 鏌ヨ鎬ユ晳杞繍鎵╁睍淇℃伅
+ SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId);
+ if (emergency == null) {
+ return error("鎬ユ晳杞繍鎵╁睍淇℃伅涓嶅瓨鍦�");
+ }
+
+ // 蹇呴』鍏堟湁鏈嶅姟鍗�
+ if (emergency.getLegacyServiceOrdId() == null || emergency.getLegacyServiceOrdId() <= 0) {
+ return error("璇峰厛鍚屾鏈嶅姟鍗�");
+ }
+
+ // 璋冪敤鍚屾鏈嶅姟
+ Long dispatchOrdId = taskDispatchSyncService.syncDispatch(taskId);
+
+ if (dispatchOrdId != null && dispatchOrdId > 0) {
+ return success("璋冨害鍗曞悓姝ユ垚鍔燂紝DispatchOrdID: " + dispatchOrdId);
+ } else {
+ return error("璋冨害鍗曞悓姝ュけ璐ワ紝璇锋煡鐪嬪悓姝ラ敊璇俊鎭�");
+ }
+
+ } catch (Exception e) {
+ logger.error("鎵嬪姩鍚屾璋冨害鍗曞紓甯革紝taskId: {}", taskId, e);
+ return error("鍚屾寮傚父: " + e.getMessage());
+ }
}
}
--
Gitblit v1.9.1