From 7298d5354963a88643a543b51b90192dc9fc934c Mon Sep 17 00:00:00 2001 From: doum <doum> Date: 星期四, 11 九月 2025 18:43:14 +0800 Subject: [PATCH] 最新版本541200007 --- server/visits/dmvisit_service/src/main/java/com/doumee/core/wx/wxPlat/WxPlatNotice.java | 264 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 240 insertions(+), 24 deletions(-) diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/core/wx/wxPlat/WxPlatNotice.java b/server/visits/dmvisit_service/src/main/java/com/doumee/core/wx/wxPlat/WxPlatNotice.java index e0c6a02..c46e1bf 100644 --- a/server/visits/dmvisit_service/src/main/java/com/doumee/core/wx/wxPlat/WxPlatNotice.java +++ b/server/visits/dmvisit_service/src/main/java/com/doumee/core/wx/wxPlat/WxPlatNotice.java @@ -1,25 +1,21 @@ package com.doumee.core.wx.wxPlat; -import cn.emay.sdk.util.json.gson.JsonObject; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.doumee.biz.system.SystemDictDataBiz; +import com.doumee.core.haikang.model.HKConstants; +import com.doumee.core.haikang.model.param.BaseResponse; +import com.doumee.core.haikang.service.HKService; import com.doumee.core.utils.Constants; import com.doumee.core.utils.DateUtil; -import com.doumee.core.utils.Http; import com.doumee.core.utils.HttpsUtil; -import com.doumee.dao.business.VisitsMapper; import com.doumee.dao.business.WxNoticeConfigMapper; import com.doumee.dao.business.model.*; +import com.doumee.dao.system.model.SystemDictData; +import com.doumee.service.business.third.model.ApiResponse; import com.github.xiaoymin.knife4j.core.util.CollectionUtils; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateFormatUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.*; @@ -74,6 +70,20 @@ } } + + + public String getToken (SystemDictDataBiz systemDictDataBiz){ + String token = null; + BaseResponse<String> result = HKService.wxAccessToken(systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_WXTOKEN_CONFIGID).getCode(), + systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_WXTOKEN_TAGID).getCode()); + log.warn("鑾峰彇娴峰悍寰俊token淇℃伅", JSONObject.toJSONString(result)); + if(StringUtils.equals(result.getCode(), HKConstants.RESPONSE_SUCCEE) ){ + token= result.getData(); + } + return token; + } + + /** * 璁垮鐢宠/鎶ュ涓氬姟閫氱煡 * @param wxNoticeConfigMapper @@ -81,7 +91,11 @@ * @param objCode visitUpload,visitAuditSuccess,visitWaitAudit锛寁isitWaitAudit,visitReportUpload锛寁isitReportAuditSuccess锛寁isitReportAuditFail, visitReportAuditSuccess * @param openIds */ - public void sendVisitTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, Visits visits, String objCode, String token, List<String> openIds){ + public void sendVisitTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, Visits visits, String objCode, List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda() @@ -119,7 +133,7 @@ car_number7.put("value",StringUtils.isNotBlank(visits.getCarNos())?visits.getCarNos():"鏃�"); dataMap.put("car_number7",car_number7); Map<String, Object> character_string6 = new HashMap<String,Object>(); - character_string6.put("value","1"); + character_string6.put("value",Constants.equalsInteger(visits.getType(),Constants.TWO)?visits.getMemberNum()+"":"1"); Map<String, Object> thing4 = new HashMap<String,Object>(); thing4.put("value",visits.getReason()); dataMap.put("const9",const9); @@ -157,6 +171,10 @@ * @param openIds */ public void sendHiddenDangerUploadTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, HiddenDanger hiddenDanger, String objCode,String token, List<String> openIds){ + token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.hiddenDanger) @@ -224,6 +242,10 @@ * @param openIds */ public void sendHiddenDangerDealTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, HiddenDanger hiddenDanger, String objCode,String token, List<String> openIds){ + token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.hiddenDanger) @@ -254,7 +276,7 @@ thing13.put("value",Constants.equalsInteger(hiddenDanger.getStatus(),Constants.ONE)?"闅愭偅宸叉暣鏀�":"闅愭偅宸查��鍥�"); //鎻愪氦浜� Map<String, Object> thing10 = new HashMap<String,Object>(); - thing10.put("value",hiddenDanger.getCheckorName()); + thing10.put("value",hiddenDanger.getMemberName()); //閫氱煡鏃堕棿 Map<String, Object> time16 = new HashMap<String,Object>(); time16.put("value", DateUtil.getFomartDate(hiddenDanger.getDealTime(),"yyyy骞碝M鏈坉d鏃� HH:mm:ss") ); @@ -293,8 +315,12 @@ * @param openIds * @param sendType 0=鐢宠浜猴紱1=瀹℃壒浜� */ - public void sendCarUseBookTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, CarUseBook carUseBook, String objCode,String token, + public void sendCarUseBookTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, CarUseBook carUseBook, String objCode, List<String> openIds,Integer sendType){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try { if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.carUse) @@ -353,6 +379,7 @@ paramMap.put("touser", openId); paramMap.put("data", dataMap); String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); + log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}", jumpUrl); if(StringUtils.isBlank(response)){ log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); }else{ @@ -376,8 +403,12 @@ * @param openIds * @param sendType 0=鐢宠浜猴紱1=瀹℃壒浜� */ - public void sendPlatformBookTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformBooks platformBooks, String objCode,String token, - List<String> openIds,Integer sendType){ + public void sendPlatformBookTemplateNotice(SystemDictDataBiz systemDictDataBiz, WxNoticeConfigMapper wxNoticeConfigMapper, PlatformBooks platformBooks, String objCode, + List<String> openIds, Integer sendType){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.platformBook) @@ -394,7 +425,6 @@ } String jumpUrl = Constants.getWxUrl(systemDictDataBiz.queryByCode(Constants.PLATFORM,Constants.WX_REDIRECT_URL).getCode(), wxUrlParams,platformBooks.getId().toString()); - String postUrL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token; //鏁翠綋鍙傛暟map Map<String, Object> paramMap = new HashMap<String, Object>(); @@ -437,6 +467,7 @@ paramMap.put("touser", openId); paramMap.put("data", dataMap); String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); + log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}", JSONObject.toJSONString(paramMap)); if(StringUtils.isBlank(response)){ log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); }else{ @@ -459,8 +490,12 @@ * @param objCode platformJobNewJob * @param openIds */ - public void sendWmsTemplateNotice(SystemDictDataBiz systemDictDataBiz, WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode,String token, + public void sendWmsTemplateNotice(SystemDictDataBiz systemDictDataBiz, WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode, List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.visit) @@ -521,11 +556,15 @@ * @param objCode platformJobNewJob * @param openIds */ - public void sendWmsCancelTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode,String token, + public void sendWmsCancelTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode, List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ - WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.visit) + WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.platformJob) .eq(WxNoticeConfig::getObjCode,objCode) .eq(WxNoticeConfig::getStatus, Constants.ZERO) .last(" limit 1") @@ -581,8 +620,12 @@ * @param token * @param openIds */ - public void sendPlatformJobTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode,String token, + public void sendPlatformJobTemplateNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode, List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } try{ if(CollectionUtils.isNotEmpty(openIds)){ WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.platformJob) @@ -625,23 +668,196 @@ paramMap.put("touser", openId); paramMap.put("data", dataMap); String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); - log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(paramMap)); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(paramMap)); if(StringUtils.isBlank(response)){ - log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); }else{ JSONObject json = JSONObject.parseObject(response); - log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); + } + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } + + + /** + * 鏈堝彴绛惧埌閫氱煡 + * @param wxNoticeConfigMapper + * @param platformJob + * @param objCode + * @param token + * @param openIds + */ + public void sendPlatformJobSignNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper, PlatformJob platformJob, String objCode, + List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } + try{ + if(CollectionUtils.isNotEmpty(openIds)){ + WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.platformJob) + .eq(WxNoticeConfig::getObjCode,objCode) + .eq(WxNoticeConfig::getStatus, Constants.ZERO) + .last(" limit 1") + ); + if(Objects.isNull(wxNoticeConfig)){ + return; + } + String postUrL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token; + //鏁翠綋鍙傛暟map + Map<String, Object> paramMap = new HashMap<String, Object>(); + //娑堟伅涓婚鏄剧ず鐩稿叧map + Map<String, Object> dataMap = new HashMap<String, Object>(); + //杞︾墝鍙� + Map<String, Object> car_number1 = new HashMap<String,Object>(); + car_number1.put("value",platformJob.getCarCodeFront()); + //鍙告満濮撳悕 + Map<String, Object> thing2 = new HashMap<String,Object>(); + thing2.put("value",platformJob.getDriverName()); + //绛惧埌鏃堕棿 + Map<String, Object> time5 = new HashMap<String,Object>(); + time5.put("value", DateUtil.getFomartDate(new Date(),"yyyy骞碝M鏈坉d鏃� HH:mm:ss")); + + dataMap.put("car_number1",car_number1); + dataMap.put("thing2",thing2); + dataMap.put("time5",time5); + for (String openId:openIds) { + paramMap.clear(); + paramMap.put("template_id", wxNoticeConfig.getTempId()); + paramMap.put("touser", openId); + paramMap.put("data", dataMap); + String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(paramMap)); + if(StringUtils.isBlank(response)){ + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); + }else{ + JSONObject json = JSONObject.parseObject(response); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); } } } }catch (Exception e){ } - } + public static void main(String[] args) { + String postUrL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=90_8_a3QDclSc8HTcbgXhSVnijiQdRf4dG5wme29riDIyt3UIi7FpZ_HJyqyEIY-_e2A29jH2fLBKgtuBKtq-cy7DteFg5l9EawoxAwiRis8BMnEl-u01ITtCUVU90XCIjADASXD"; + //鏁翠綋鍙傛暟map + Map<String, Object> paramMap = new HashMap<String, Object>(); + //娑堟伅涓婚鏄剧ず鐩稿叧map + Map<String, Object> dataMap = new HashMap<String, Object>(); + //杞︾墝鍙� + Map<String, Object> car_number1 = new HashMap<String,Object>(); + car_number1.put("value","鐨朅12345"); + //鍙告満濮撳悕 + Map<String, Object> thing2 = new HashMap<String,Object>(); + thing2.put("value","灏忛樋姝�"); + //绛惧埌鏃堕棿 + Map<String, Object> time5 = new HashMap<String,Object>(); + time5.put("value", DateUtil.getFomartDate(new Date(),"yyyy骞碝M鏈坉d鏃� HH:mm:ss")); + dataMap.put("car_number1",car_number1); + dataMap.put("thing2",thing2); + dataMap.put("time5",time5); + paramMap.clear(); + paramMap.put("template_id", "ZYhHg5eJJim0LR3FLVaqKcVqW3p8GQk8qrTO40ffHXI"); + paramMap.put("touser", "ovmre6RUJJZCDtCyLxWYKSMgt7u8"); + paramMap.put("data", dataMap); + String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(paramMap)); + if(StringUtils.isBlank(response)){ + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); + }else{ + JSONObject json = JSONObject.parseObject(response); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); + } + } + + public void sendUnFinishNotice(SystemDictDataBiz systemDictDataBiz,WxNoticeConfigMapper wxNoticeConfigMapper,Integer unFinishNum,String objCode, + List<String> openIds){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)||Constants.equalsInteger(unFinishNum,Constants.ZERO)){ + return; + } + try{ + if(CollectionUtils.isNotEmpty(openIds)){ + WxNoticeConfig wxNoticeConfig = wxNoticeConfigMapper.selectOne(new QueryWrapper<WxNoticeConfig>().lambda().eq(WxNoticeConfig::getObjType,WxPlatConstants.platformJob) + .eq(WxNoticeConfig::getObjCode,objCode) + .eq(WxNoticeConfig::getStatus, Constants.ZERO) + .last(" limit 1") + ); + if(Objects.isNull(wxNoticeConfig)){ + return; + } + String postUrL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token; + //鏁翠綋鍙傛暟map + Map<String, Object> paramMap = new HashMap<String, Object>(); + //娑堟伅涓婚鏄剧ず鐩稿叧map + Map<String, Object> dataMap = new HashMap<String, Object>(); + //杞︾墝鍙� + Map<String, Object> const1 = new HashMap<String,Object>(); + const1.put("value","浣滀笟浠诲姟鏈畬鎴�"); + //鍙告満濮撳悕 + Map<String, Object> thing2 = new HashMap<String,Object>(); + thing2.put("value",unFinishNum+"涓�"); + //绛惧埌鏃堕棿 + Map<String, Object> time3 = new HashMap<String,Object>(); + time3.put("value", DateUtil.getFomartDate(new Date(),"yyyy骞碝M鏈坉d鏃� HH:mm:ss")); + + dataMap.put("const1",const1); + dataMap.put("thing2",thing2); + dataMap.put("time3",time3); + for (String openId:openIds) { + paramMap.clear(); + paramMap.put("template_id", wxNoticeConfig.getTempId()); + paramMap.put("touser", openId); + paramMap.put("data", dataMap); + String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(paramMap)); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(paramMap)); + if(StringUtils.isBlank(response)){ + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); + }else{ + JSONObject json = JSONObject.parseObject(response); + log.error("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); + } + } + } + }catch (Exception e){ + + } + } + + + public void sendMeetTemplateNotice(SystemDictDataBiz systemDictDataBiz,SmsEmail smsEmail){ + String token = this.getToken(systemDictDataBiz); + if(StringUtils.isBlank(token)){ + return; + } + try{ + String jumpUrl = Constants.getWxUrl(systemDictDataBiz.queryByCode(Constants.PLATFORM,Constants.WX_REDIRECT_URL).getCode(), + Constants.WxUrlParams.MEETING,smsEmail.getObjId().toString()); + String postUrL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token; + JSONObject jsonObject = JSONObject.parseObject(smsEmail.getContent()); + jsonObject.put("url",jumpUrl); + String response = HttpsUtil.postJson(postUrL, JSONObject.toJSONString(jsonObject)); + log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭唴瀹癸細{}", JSONObject.toJSONString(jsonObject)); + if(StringUtils.isBlank(response)){ + log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", "澶辫触"); + }else{ + JSONObject json = JSONObject.parseObject(response); + log.warn("路==++--路鎺ㄩ�佸井淇℃ā鏉夸俊鎭細{}路--++==路", Constants.equalsInteger(json.getInteger("errcode"),Constants.ZERO)?"鎴愬姛":"澶辫触"+json.getString("errmsg")); + } + }catch (Exception e){ + + } + + } } -- Gitblit v1.9.3