anderx преди 2 години
родител
ревизия
d080632532

+ 8 - 0
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java

@@ -1,8 +1,16 @@
 package com.ruoyi;
 
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
 
 /**
  * 启动程序

+ 2 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ProjectTaskController.java

@@ -101,11 +101,11 @@ public class ProjectTaskController extends BaseController {
     }
 
     /**
-     * 审核成员打卡
+     * 成员打卡列表
      * @param in
      * @return
      */
-    @PostMapping("/listRecord")
+    @GetMapping("/listRecord")
     public TableDataInfo listRecord( @RequestBody ProjectStaffRecordInput in){
         startPage();
         List<ProjectStaffRecordOut> list = projectStaffRecordService.listRecord(in);

+ 38 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/weChat/WeChatController.java

@@ -0,0 +1,38 @@
+package com.ruoyi.web.controller.weChat;
+
+import com.ruoyi.weChat.service.WeChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/system/weChat")
+public class WeChatController {
+
+    @Autowired
+    private WeChatService weChatService;
+
+
+    /**
+     * 获取accessToken
+     * @return
+     */
+    @GetMapping("/getAccessToken")
+    public String getAccessToken() {
+        return weChatService.getAccessToken();
+    }
+
+    /**
+     * 获取openId
+     * @return
+     */
+    @GetMapping("/getOpenId")
+    public String getOpenId(String code) {
+        return weChatService.getOpenId(code);
+    }
+
+
+
+
+}

+ 6 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -129,3 +129,9 @@ xss:
   excludes: /system/notice
   # 匹配链接
   urlPatterns: /system/*,/monitor/*,/tool/*
+
+wx:
+  appId: wxff2f5720ed7d7f63
+  appSecret: 081744369d42405be58fe37f892631f7
+  #developer为开发版;trial为体验版;formal为正式版;
+  state: trial

+ 4 - 0
ruoyi-common/pom.xml

@@ -125,6 +125,10 @@
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpasyncclient</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 35 - 2
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java

@@ -11,12 +11,17 @@ import java.net.URL;
 import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
 import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.Set;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import com.ruoyi.common.constant.Constants;
@@ -24,7 +29,7 @@ import com.ruoyi.common.utils.StringUtils;
 
 /**
  * 通用http发送方法
- * 
+ *
  * @author ruoyi
  */
 public class HttpUtils
@@ -46,6 +51,18 @@ public class HttpUtils
      * 向指定 URL 发送GET方法的请求
      *
      * @param url 发送请求的 URL
+     * @return 所代表远程资源的响应结果
+     */
+    public static JSONObject sendGetToJson(String url)
+    {
+        String s = sendGet(url, StringUtils.EMPTY);
+        return JSON.parseObject(s);
+    }
+
+    /**
+     * 向指定 URL 发送GET方法的请求
+     *
+     * @param url 发送请求的 URL
      * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
      * @return 所代表远程资源的响应结果
      */
@@ -117,6 +134,11 @@ public class HttpUtils
         return result.toString();
     }
 
+    public static String sendPost(String url, Map<String, Object>  map){
+        String param = ParamMap(map);
+        return  sendPost( url,  param);
+    }
+
     /**
      * 向指定 URL 发送POST方法的请求
      *
@@ -271,4 +293,15 @@ public class HttpUtils
             return true;
         }
     }
-}
+
+
+    private static String ParamMap(Map<String, Object> map) {
+        StringBuffer str =new StringBuffer();
+        Set<String> strings = map.keySet();
+        for (String string : strings) {
+            str=str.append(string).append("=").append(map.get(string)).append("&");
+        }
+        String substring = str.substring(0, str.length() - 1);
+        return substring;
+    }
+}

+ 10 - 0
ruoyi-system/src/main/java/com/ruoyi/project/bo/ProjectStaffRecordOut.java

@@ -3,4 +3,14 @@ package com.ruoyi.project.bo;
 import com.ruoyi.project.domain.ProjectStaffRecord;
 
 public class ProjectStaffRecordOut extends ProjectStaffRecord {
+
+    private String createTimeStr;
+
+    public String getCreateTimeStr() {
+        return createTimeStr;
+    }
+
+    public void setCreateTimeStr(String createTimeStr) {
+        this.createTimeStr = createTimeStr;
+    }
 }

+ 361 - 0
ruoyi-system/src/main/java/com/ruoyi/weChat/service/WeChatService.java

@@ -0,0 +1,361 @@
+package com.ruoyi.weChat.service;
+
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.system.mapper.SysUserMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+
+@Service
+public class WeChatService {
+
+	private static final Logger log = LoggerFactory.getLogger(WeChatService.class);
+
+
+	@Value(value = "${wx.appId}")
+	private String appId;
+	@Value(value = "${wx.appSecret}")
+	private String appSecret;
+	@Value(value = "${wx.state}")
+	private String wxState;
+
+	@Autowired
+	private RedisTemplate<String, String> redisTemplate;
+	@Autowired
+	private SysUserMapper sysUserMapper;
+
+
+
+	/**
+	 * 公出待审核通知
+	 */
+	private static final String PUBLIC_RELEASE_EXAMINE ="j7WH3EwQnxGxwuV2HwmJhryxySPE8vOiV5cVOpp-42I";
+	/**
+	 * 公出审核结果通知
+	 */
+	private static final String PUBLIC_RELEASE_EXAMINE_RESULT="pWia-KJPFwDM8ReDu_BOa9FJn31VFc81bp3yxfBmIRI";
+	/**
+	 * 公出待审核通知
+	 */
+	private static final String EXPENSE_RELEASE_EXAMINE ="0e2Te3WUa0fDPQnyE8TLmN_K06WLsB4fqm5qpo6npNo";
+	/**
+	 * 公出审核结果通知
+	 */
+	private static final String EXPENSE_RELEASE_EXAMINE_RESULT="rRPWzRcGY8BGwlk0xyjwR1RKdv3iRFXaU3bcK1300gw";
+
+
+	/**
+	 * 推送地址
+	 */
+	private static  String send_url="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
+
+
+
+
+
+		public String getOpenId(String code) {
+		String url = "https://api.weixin.qq.com/sns/jscode2session";
+		url=url+"appid="+appId+"&secret="+appSecret+"&js_code="+code+"&grant_type=authorization_code";
+
+			JSONObject js= HttpUtils.sendGetToJson(url);
+		String openid=js.getString("openid");
+		if (openid==null){
+			log.error("openId 获取异常");
+		}else {
+
+			return openid;
+		}
+		return null;
+	}
+
+	public String getAccessToken() {
+		Date date = new Date();
+		String  access_token = redisTemplate.opsForValue().get("access_token");
+		if (access_token!=null) {
+			log.debug("缓存读取access_token="+access_token);
+			return access_token;
+		} else {
+			return setSessionAccessToken();
+		}
+	}
+
+	/**
+	 *
+	 * @return
+	 */
+	private String setSessionAccessToken() {
+		String url =String.format(
+				"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId,
+				appSecret);
+		JSONObject js= HttpUtils.sendGetToJson(url);
+		String errcode =js.getString("errcode");
+		Long expires_in = js.getLong("expires_in");
+		String access_token=null;
+		if (errcode!=null) {
+			log.error("获取AccessToken失败!");
+		}else {
+			access_token = js.getString("access_token");
+			redisTemplate.opsForValue().set("access_token", access_token,expires_in, TimeUnit.SECONDS);
+			log.debug("获取并存入AccessToken成功,accesstoken="+access_token);
+		}
+		return access_token;
+	}
+
+
+
+
+
+//	/**
+//	 * 推送微信订阅信息,跳转为公出信息
+//	 * @param openid 发送对象微信openid
+//	 * @param type 状态 0驳回 1发起 2同意
+//	 * @param date 日期
+//	 * @param aname 发送者名称
+//	 * @param remarks 发送信息,不能大于十五个字
+//	 */
+//	public Integer addNotice(String openid ,Integer type,Integer id, Date date, String aname,String remarks) {
+//		Map<String, Object> map=new HashMap<String, Object>();
+//		String accessToken=getAccessToken();
+//		String url=send_url.replace("ACCESS_TOKEN", accessToken);
+//		map.put("access_token", accessToken);
+//		map.put("touser", openid);
+//		map.put("page", "pages/egressDetails/index?id="+id);
+//		map.put("miniprogram_state", wxState);
+//		if (type==1) {
+//			map.put("template_id", PUBLIC_RELEASE_EXAMINE);
+//			map.put("data",getPublicData(type,date, aname,remarks));
+//		}else {
+//			map.put("template_id", PUBLIC_RELEASE_EXAMINE_RESULT);
+//			map.put("data",getPublicData(type,date, aname,remarks));
+//		}
+//		return SendHttpPost(map, url);
+//
+//	}
+//
+//	private Integer SendHttpPost(String params, String url) {
+//		String res= HttpUtils.sendPost(url,params);
+//		if (res.get("errcode")!=null) {
+//			log.error(String.format("errcode={%s}",res.getInteger("errcode").toString()));
+//			return res.getInteger("errcode");
+//		}else {
+//			return 1;
+//		}
+//	}
+//
+//	/**
+//	 * 推送微信订阅信息,跳转为报销信息
+//	 * @param openid 发送对象微信openid
+//	 * @param type 状态 0驳回 1发起 2同意
+//	 * @param date 日期
+//	 * @param aname 发送者名称
+//	 * @param remarks 发送信息,不能大于十五个字
+//	 */
+//	public Integer addExpenseAccountWeChatNotice(String openid ,Integer type,Integer id, Date date, String aname,String remarks) {
+//		if (openid==null )log.error("openId不能为空");
+//		Map<String, Object> map=new HashMap<String, Object>();
+//		String accessToken=getExpenseAccountAccessToken();
+//		String url=send_url.replace("ACCESS_TOKEN", accessToken);
+//		map.put("access_token", accessToken);
+//		map.put("touser", openid);
+//		//这里要替换成当前的
+//		map.put("page", "pages/egressDetails/index?id="+id);
+//		map.put("miniprogram_state", wxState);
+//		if (type==1) {
+//			map.put("template_id", EXPENSE_RELEASE_EXAMINE);
+//			map.put("data",getExpenseData(type,date, aname,remarks));
+//		}else {
+//			map.put("template_id", EXPENSE_RELEASE_EXAMINE_RESULT);
+//			map.put("data",getExpenseData(type,date, aname,remarks));
+//		}
+//		return SendHttpPost(map, url);
+//	}
+//
+//	/**
+//	 * 公出订阅消息组装
+//	 * @param type
+//	 * @param date
+//	 * @param aname
+//	 * @param remarks
+//	 * @return
+//	 */
+//	private Map<String, Object> getPublicData(Integer type,Date date, String aname, String remarks) {
+//		Map<String, Object> we=new HashMap<String, Object>();
+//		String strDate=DateUtils.formatDate(date, AFTConstants.YMDHMS_CHINESE);
+//		if (remarks.length()>20)remarks=remarks.substring(0,17)+"...";
+//		if (type==1) {
+//			Map<String, Object> v1=new HashMap<String, Object>();
+//			v1.put("value",strDate);
+//			we.put("time5", v1);
+//			Map<String, Object> v2=new HashMap<String, Object>();
+//			v2.put("value", aname);
+//			we.put("name3", v2);
+//			Map<String, Object> v3=new HashMap<String, Object>();
+//			v3.put("value", remarks);
+//			we.put("thing10", v3);
+//		}else {
+//			String thing2="";
+//			if (type==0){
+//				thing2="驳回";
+//			}else if (type==2){
+//				thing2="通过";
+//			}
+//			Map<String, Object> v1=new HashMap<String, Object>();
+//			v1.put("value",strDate);
+//			we.put("date3", v1);
+//			Map<String, Object> v2=new HashMap<String, Object>();
+//			v2.put("value", thing2);
+//			we.put("thing2", v2);
+//			Map<String, Object> v3=new HashMap<String, Object>();
+//			v3.put("value", remarks);
+//			we.put("thing6", v3);
+//		}
+//		return we;
+//	}
+//
+//
+//	/**
+//	 * 报销订阅消息组装
+//	 * @param type
+//	 * @param date
+//	 * @param aname
+//	 * @param remarks
+//	 * @return
+//	 */
+//	private Map<String, Object> getExpenseData(Integer type,Date date, String aname, String remarks) {
+//		Map<String, Object> we=new HashMap<String, Object>();
+//		String strDate=DateUtils.formatDate(date, AFTConstants.YMDHMS_CHINESE);
+//		if (remarks.length()>20)remarks=remarks.substring(0,17)+"...";
+//		if (type==1) {
+//			Map<String, Object> v2=new HashMap<String, Object>();
+//			we.put("thing4", v2);
+//			v2.put("value", aname);
+//			Map<String, Object> v1=new HashMap<String, Object>();
+//			we.put("time6", v1);
+//			v1.put("value",strDate);
+//			Map<String, Object> v3=new HashMap<String, Object>();
+//			we.put("thing2", v3);
+//			v3.put("value", remarks);
+//		}else {
+//			String thing5="";
+//			if (type==0){
+//				thing5="报销驳回";
+//			}else if (type==2){
+//				thing5="报销通过";
+//			}
+//			Map<String, Object> v1=new HashMap<String, Object>();
+//			we.put("time3", v1);
+//			v1.put("value",strDate);
+//			Map<String, Object> v2=new HashMap<String, Object>();
+//			we.put("thing5", v2);
+//			v2.put("value", thing5);
+//			Map<String, Object> v3=new HashMap<String, Object>();
+//			we.put("thing4", v3);
+//			v3.put("value", remarks);
+//		}
+//		return we;
+//	}
+//
+//
+//
+//
+//	public String getAccessToken() {
+//		Date date = new Date();
+//		if (redisUtil.presence("access_token")||redisUtil.presence("expires_in")) {
+//			String access_token=redisUtil.getString("access_token");
+//			String expires_in=redisUtil.getString("expires_in");
+//			if (date.getTime() < Long.valueOf(expires_in)) {
+//				LoggerUtils.debug(getClass(), "redis中获取accestoken");
+//				return access_token;
+//			} else {
+//				LoggerUtils.debug(getClass(), "accestoken超时重新获取");
+//				redisUtil.deleteString("access_token");
+//				redisUtil.deleteString("expires_in");
+//				return setSessionAccessToken(date,0);
+//			}
+//
+//		} else {
+//			return setSessionAccessToken(date,0);
+//		}
+//
+//
+//	}
+//
+//	public String getExpenseAccountAccessToken() {
+//		Date date = new Date();
+//		if (redisUtil.presence("expense_access_token")||redisUtil.presence("expense_expires_in")) {
+//			String access_token=redisUtil.getString("expense_access_token");
+//			String expires_in=redisUtil.getString("expense_expires_in");
+//			if (date.getTime() < Long.valueOf(expires_in)) {
+//				LoggerUtils.debug(getClass(), "redis中获取accestoken");
+//				return access_token;
+//			} else {
+//				LoggerUtils.debug(getClass(), "accestoken超时重新获取");
+//				redisUtil.deleteString("expense_access_token");
+//				redisUtil.deleteString("expense_expires_in");
+//				return setSessionAccessToken(date,1);
+//			}
+//
+//		} else {
+//			return setSessionAccessToken(date,1);
+//		}
+//
+//
+//	}
+//
+//
+//	/**
+//	 *
+//	 * @param date 参数
+//	 * @param type 0公出小程序 1报销小程序
+//	 * @return
+//	 */
+//	private String setSessionAccessToken(Date date,Integer type) {
+//		String url =null;
+//		if (type==0){
+//			url=String.format(
+//					"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId,
+//					appSecret);
+//		}else if(type==1){
+//			url=String.format(
+//					"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", expenseAppId,
+//					expenseAppSecret);
+//		}
+//
+//		JSONObject js = HttpUtils.httpGet(url);
+//		String errcode =js.getString("errcode");
+//		if (errcode!=null) {
+//			throw new  BusinessException("获取AccessToken失败!");
+//		}else {
+//			LoggerUtils.debug(AsyncUtils.class,"获取并存入AccessToken成功,accesstoken="+js.getString("access_token"));
+//		}
+//		String access_token = js.getString("access_token");
+//		Long expires_in = js.getLong("expires_in");
+//		//返回时间为秒需要计算换成毫秒
+//		expires_in=expires_in*1000;
+//		expires_in+=date.getTime();
+//		if (type==0){
+//			redisUtil.setString("access_token", access_token);
+//			redisUtil.setString("expires_in", expires_in.toString());
+//		}else if (type==1){
+//			redisUtil.setString("expense_access_token", access_token);
+//			redisUtil.setString("expense_expires_in", expires_in.toString());
+//		}
+//
+//		return access_token;
+//	}
+//
+
+}

+ 1 - 1
ruoyi-system/src/main/resources/mapper/project/ProjectStaffRecordMapper.xml

@@ -147,7 +147,7 @@
   </update>
   <select id="selectList" resultType="com.ruoyi.project.bo.ProjectStaffRecordOut">
     select a.id,a.pid ,a.aid ,a.name ,a.project_status projectStatus,a.content ,
-           a.annex_url annexUrl,a.create_time createTime,a.process_status processStatus ,
+           a.annex_url annexUrl,a.create_time createTimeStr,a.process_status processStatus ,
            a.duration
     from project_staff_record a left join project_task b on a.pid=b.id
     where 1=1