Commit f047f356 authored by renandong's avatar renandong 🇨🇳

1,定时任务更新标签

parent 03d0ab85
...@@ -48,6 +48,10 @@ ...@@ -48,6 +48,10 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>${lombok.version}</version> <version>${lombok.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.exception; package com.weface.common.exception;
/** /**
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package com.weface.common.exception; package com.weface.common.exception;
import com.weface.common.utils.Model; import com.weface.common.utils.Model;
......
...@@ -68,7 +68,7 @@ public class Base64Util { ...@@ -68,7 +68,7 @@ public class Base64Util {
} }
private static String byte2Hex(byte[] bytes) { private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer(); StringBuilder stringBuffer = new StringBuilder();
String temp = null; String temp = null;
for (int i = 0; i < bytes.length; i++) { for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF); temp = Integer.toHexString(bytes[i] & 0xFF);
......
package com.weface.common.utils;
import java.util.HashMap;
import java.util.Map;
/**
* @CreateUser: Administrator
* @CreateTime: 2021/12/1
* 实现简单缓存
*/
public class CacheUtil {
private static CacheUtil cacheUtil;
private static Map<String, Object> cacheMap;
private CacheUtil() {
cacheMap = new HashMap<String, Object>();
}
public static CacheUtil getInstance() {
if (cacheUtil == null) {
cacheUtil = new CacheUtil();
}
return cacheUtil;
}
/**
* 添加缓存
*
* @param key
* @param obj
*/
public void addCacheData(String key, Object obj) {
cacheMap.put(key, obj);
}
/**
* 取出缓存
*
* @param key
* @return
*/
public Object getCacheData(String key) {
return cacheMap.get(key);
}
/**
* 清除缓存
*
* @param key
*/
public void removeCacheData(String key) {
cacheMap.remove(key);
}
}
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
/** /**
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
/** /**
...@@ -40,7 +32,6 @@ public class Constant { ...@@ -40,7 +32,6 @@ public class Constant {
* 菜单类型 * 菜单类型
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2016年11月15日 下午1:24:29 * @date 2016年11月15日 下午1:24:29
*/ */
public enum MenuType { public enum MenuType {
...@@ -72,7 +63,6 @@ public class Constant { ...@@ -72,7 +63,6 @@ public class Constant {
* 定时任务状态 * 定时任务状态
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2016年12月3日 上午12:07:22 * @date 2016年12月3日 上午12:07:22
*/ */
public enum ScheduleStatus { public enum ScheduleStatus {
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
...@@ -13,6 +5,9 @@ import org.springframework.web.context.request.ServletRequestAttributes; ...@@ -13,6 +5,9 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/**
* @author Administrator
*/
public class HttpContextUtils { public class HttpContextUtils {
public static HttpServletRequest getHttpServletRequest() { public static HttpServletRequest getHttpServletRequest() {
......
...@@ -4,14 +4,13 @@ package com.weface.common.utils; ...@@ -4,14 +4,13 @@ package com.weface.common.utils;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/** /**
* http 工具类 * http 工具类
...@@ -63,70 +62,14 @@ public class HttpUtil { ...@@ -63,70 +62,14 @@ public class HttpUtil {
// 建立实际的连接 // 建立实际的连接
connection.connect(); connection.connect();
// 获取所有响应头字段
Map<String, List<String>> headers = connection.getHeaderFields();
// 遍历所有的响应头字段
// for (String key : headers.keySet()) {
// log.info(key + "--->" + headers.get(key));
// }
// 定义 BufferedReader输入流来读取URL的响应
// BufferedReader in = null;
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding)); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding));
String result = ""; StringBuilder result = new StringBuilder();
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
return result;
}
public static String getGeneralUrl(String generalUrl, String contentType, String params, String encoding)
throws Exception {
return HttpUtil.getGeneralUrl(generalUrl, contentType, params, encoding, null);
}
public static String getGeneralUrl(String generalUrl, String contentType, String params, String encoding, String token)
throws Exception {
URL url = new URL(generalUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
// 设置通用的请求属性
connection.setRequestProperty("Content-Type", contentType);
connection.setRequestProperty("Connection", "Keep-Alive");
if (StringUtils.isNotEmpty(token)) {
connection.setRequestProperty("token", token);
}
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
// 得到请求的输出流对象
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(params.getBytes(encoding));
out.flush();
out.close();
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> headers = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : headers.keySet()) {
log.info(key + "--->" + headers.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = null;
in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), encoding));
String result = "";
String getLine; String getLine;
while ((getLine = in.readLine()) != null) { while ((getLine = in.readLine()) != null) {
result += getLine; result.append(getLine);
} }
in.close(); in.close();
log.info("result:" + result); return result.toString();
return result;
} }
public static boolean isJson2(String str) { public static boolean isJson2(String str) {
...@@ -136,38 +79,7 @@ public class HttpUtil { ...@@ -136,38 +79,7 @@ public class HttpUtil {
flag = true; flag = true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
flag = false;
} }
return flag; return flag;
} }
// public static String postGeTui(String url, Object obj, String token) {
// CloseableHttpClient httpClient = HttpClients.createDefault();
// HttpPost httpPost = new HttpPost(url);
// httpPost.setHeader("token", token);
// httpPost.setHeader("Content-Type", "application/json");
// httpPost.setHeader("Accept", "application/json");
// StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(obj), "UTF-8");
// System.out.println(stringEntity);
// httpPost.setEntity(stringEntity);
// CloseableHttpResponse response = null;
// try {
// response = httpClient.execute(httpPost);
// StatusLine status = response.getStatusLine();
// int state = status.getStatusCode();
// if (state == HttpStatus.SC_OK) {
// HttpEntity responseEntity = response.getEntity();
// return EntityUtils.toString(responseEntity);
// } else {
// log.error("请求返回:" + state + "(" + url + ")");
// }
// } catch (IOException e) {
// e.printStackTrace();
// } finally {
// IoUtil.close(response);
// IoUtil.close(httpClient);
// }
//
// return null;
// }
} }
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import com.alibaba.druid.util.StringUtils; import com.alibaba.druid.util.StringUtils;
...@@ -20,16 +12,16 @@ import javax.servlet.http.HttpServletRequest; ...@@ -20,16 +12,16 @@ import javax.servlet.http.HttpServletRequest;
* @author Mark sunlightcs@gmail.com * @author Mark sunlightcs@gmail.com
*/ */
public class IPUtils { public class IPUtils {
private static Logger logger = LoggerFactory.getLogger(IPUtils.class); private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/** /**
* 获取IP地址 * 获取IP地址
* * <p>
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/ */
public static String getIpAddr(HttpServletRequest request) { public static String getIpAddr(HttpServletRequest request) {
String ip = null; String ip = null;
try { try {
ip = request.getHeader("x-forwarded-for"); ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
...@@ -48,17 +40,17 @@ public class IPUtils { ...@@ -48,17 +40,17 @@ public class IPUtils {
ip = request.getRemoteAddr(); ip = request.getRemoteAddr();
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("IPUtils ERROR ", e); logger.error("IPUtils ERROR ", e);
} }
// //使用代理,则获取第一个IP地址 //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) { /*if (StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) { if (ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(",")); ip = ip.substring(0, ip.indexOf(","));
// } }
// } }*/
return ip; return ip;
} }
} }
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import java.util.HashMap; import java.util.HashMap;
......
...@@ -8,7 +8,6 @@ import java.util.Map; ...@@ -8,7 +8,6 @@ import java.util.Map;
/** /**
* @author Aleyn * @author Aleyn
* @description Model
* @since 2021/11/10 16:34 * @since 2021/11/10 16:34
*/ */
@Getter @Getter
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
......
...@@ -15,8 +15,13 @@ import java.io.ByteArrayOutputStream; ...@@ -15,8 +15,13 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/**
* @author Administrator
*/
public class PicUtils { public class PicUtils {
//以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值 /**
* 以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值
*/
private static final Logger logger = LoggerFactory.getLogger(PicUtils.class); private static final Logger logger = LoggerFactory.getLogger(PicUtils.class);
private static final Integer ZERO = 0; private static final Integer ZERO = 0;
private static final Integer ONE_ZERO_TWO_FOUR = 1024; private static final Integer ONE_ZERO_TWO_FOUR = 1024;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils; package com.weface.common.utils;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss; package com.weface.common.xss;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss; package com.weface.common.xss;
import javax.servlet.*; import javax.servlet.*;
...@@ -23,6 +15,7 @@ public class XssFilter implements Filter { ...@@ -23,6 +15,7 @@ public class XssFilter implements Filter {
public void init(FilterConfig config) throws ServletException { public void init(FilterConfig config) throws ServletException {
} }
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException { throws IOException, ServletException {
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss; package com.weface.common.xss;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
......
package com.weface.component; package com.weface.component;
import cn.hutool.core.lang.Console; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.weface.common.exception.RRException;
import com.weface.common.utils.Base64Util; import com.weface.common.utils.Base64Util;
import com.weface.common.utils.HttpUtil; import com.weface.common.utils.HttpUtil;
import com.weface.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
/** /**
* @CreateUser: Administrator * @author Administrator
* @CreateTime: 2021/11/2 * @CreateTime: 2021/11/2
*/ */
@Slf4j @Slf4j
public class GeTuiUtils { public class GeTuiUtils {
//请求前缀 public static final String KK_SH_APP_ID = "CYol79N33N71BV6dcjrqj3";
public static final String GETUIBASEURL = "https://restapi.getui.com/v2/"; public static final String KK_SH_MASTER_SECRET = "mekLZ4frLu7RHtKsN9mQn";
public static final String APPID = "CYol79N33N71BV6dcjrqj3"; public static final String KK_SH_APP_KEY = "rdLx5zumRK7oEme8MheAh8";
public static final String KK_SB_APP_ID = "Ued41NRq7j9Nh1qI81gQ54";
public static final String KK_SB_MASTER_SECRET = "b8MSgB7j8PAImc3eN0yuL9";
public static final String KK_SB_APP_KEY = "2tLtJhcpij7lu3ksutgpU3";
public static final String GE_TUI_BASE_URL = "https://restapi.getui.com/v2/";
public static final String BASEURL = "https://openapi-gi.getui.com/v2/"; public static final String BASEURL = "https://openapi-gi.getui.com/v2/";
public static final String ENCODING = "UTF-8"; public static final String ENCODING = "UTF-8";
public static final String CONTENTTYPE = "application/json;charset=utf-8"; public static final String CONTENT_TYPE = "application/json;charset=utf-8";
public static final String APPKEY = "rdLx5zumRK7oEme8MheAh8";
public static final String MASTERSECRET = "mekLZ4frLu7RHtKsN9mQn"; /**
* 设置token过期时间为12小时
*/
private final static long TIMEOUT = (12 * 60 * 60);
/**
* 获取token并缓存一份
*
* @param key 缓存key
* @return 从缓存中拿token
*/
public static String getAuthToken(String key) {
String authToken = "";
try {
boolean flag = false;
while (!flag) {
flag = RedisUtil.LockOps.getLock("token", Thread.currentThread().getName());
if (!flag) {
Thread.sleep(500L);
}
}
//获取缓存内的token
authToken = RedisUtil.StringOps.get(key);
//如果不存在则调用个像接口获取
if (StringUtils.isBlank(authToken)) {
String geTui = null;
switch (key) {
case "kk_sh_token":
authToken = getAuth(KK_SH_APP_ID, KK_SH_APP_KEY, KK_SH_MASTER_SECRET);
if (ObjectUtil.isNull(authToken)) {
throw new RRException("获取看看生活个像token失败");
}
break;
case "kk_sb_token":
authToken = getAuth(KK_SB_APP_ID, KK_SB_APP_KEY, KK_SB_MASTER_SECRET);
if (ObjectUtil.isNull(authToken)) {
throw new RRException("获取看看社保个像token失败");
}
break;
case "kk_sh_token_ge_tui":
authToken = getGeTuiAuth(KK_SH_APP_ID, KK_SH_APP_KEY, KK_SH_MASTER_SECRET);
if (ObjectUtil.isNull(authToken)) {
throw new RRException("获取看看生活个推token失败");
}
geTui = key;
break;
case "kk_sb_token_ge_tui":
authToken = getGeTuiAuth(KK_SB_APP_ID, KK_SB_APP_KEY, KK_SB_MASTER_SECRET);
if (ObjectUtil.isNull(authToken)) {
throw new RRException("获取看看社保个推token失败");
}
geTui = key;
break;
default:
break;
}
if (geTui != null) {
//获取token过期时间并转为数值,使token提前5秒过期
RedisUtil.StringOps.setEx(key, authToken, (TIMEOUT * 2) - 5, TimeUnit.SECONDS);
} else {
//获取成功后放入缓存并设置token过期时间
RedisUtil.StringOps.setEx(key, authToken, TIMEOUT, TimeUnit.SECONDS);
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("加锁失败!");
} finally {
RedisUtil.LockOps.releaseLock("token", Thread.currentThread().getName());
}
return authToken;
}
/** /**
* 获取个像token * 获取个像token
* *
* @return JSONObject * @return JSONObject
*/ */
public static String getAuth() { private static String getAuth(String appId, String appKey, String masterSecret) {
// 获取token地址
log.info("开始获取个像token");
String getAccessTokenUrl = BASEURL + APPID + "/auth_sign";
Long timestamp = System.currentTimeMillis();
try { try {
Map<String, Object> map = new HashMap<>(); String getAccessTokenUrl = BASEURL + appId + "/auth_sign";
map.put("sign", Base64Util.getSign(APPKEY, timestamp, MASTERSECRET)); Long timestamp = System.currentTimeMillis();
map.put("timestamp", timestamp); JSONObject json = new JSONObject();
String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENTTYPE, JSONObject.toJSONString(map), ENCODING); json.put("sign", DigestUtils.sha256Hex(String.format("%s%d%s", appKey, timestamp, masterSecret)));
if (HttpUtil.isJson2(result)) { json.put("timestamp", timestamp);
JSONObject jsonObject = JSONObject.parseObject(result); HttpRequest post = HttpRequest.post(getAccessTokenUrl);
if ("true".equals(jsonObject.getString("result"))) { String result = post.body(json.toString()).execute().body();
Console.log(jsonObject); JSONObject jsonObject = JSONObject.parseObject(result);
return jsonObject.getString("authtoken"); if (jsonObject.containsKey("result") && "true".equals(jsonObject.getString("result"))) {
} String authtoken = jsonObject.getString("authtoken");
log.info("获取个像token成功{}", authtoken);
return authtoken;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -64,21 +145,21 @@ public class GeTuiUtils { ...@@ -64,21 +145,21 @@ public class GeTuiUtils {
* *
* @return JSONObject * @return JSONObject
*/ */
public static JSONObject getGeTuiAuth() { public static String getGeTuiAuth(String appId, String appKey, String masterSecret) {
// 获取token地址
log.info("开始获取个推token");
String getAccessTokenUrl = GETUIBASEURL + APPID + "/auth";
Long timestamp = System.currentTimeMillis();
try { try {
// 获取token地址
log.info("开始获取个推token");
String getAccessTokenUrl = GE_TUI_BASE_URL + appId + "/auth";
Long timestamp = System.currentTimeMillis();
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("sign", Base64Util.getSign(APPKEY, timestamp, MASTERSECRET)); map.put("sign", Base64Util.getSign(appKey, timestamp, masterSecret));
map.put("timestamp", timestamp); map.put("timestamp", timestamp);
map.put("appkey", APPKEY); map.put("appkey", appKey);
String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENTTYPE, JSONObject.toJSONString(map), ENCODING); String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENT_TYPE, JSONObject.toJSONString(map), ENCODING);
if (HttpUtil.isJson2(result)) { if (HttpUtil.isJson2(result)) {
JSONObject jsonObject = JSONObject.parseObject(result); JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0) { if (jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0) {
return jsonObject.getJSONObject("data"); return jsonObject.getJSONObject("data").getString("token");
} }
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -88,71 +169,167 @@ public class GeTuiUtils { ...@@ -88,71 +169,167 @@ public class GeTuiUtils {
return null; return null;
} }
/**
* 获取看看生活个像
*
* @param gidList 用户gid
* @param token token
* @return 请求结果
* @throws Exception 抛出异常
*/
public static String queryTagKKSH(List<String> gidList, String token) throws Exception {
return queryTag(gidList, token, KK_SH_APP_ID);
}
/**
* 获取看看生活个像
*
* @param gidList 用户gid
* @param token token
* @return 请求结果
* @throws Exception 抛出异常
*/
public static String queryTagKKSB(List<String> gidList, String token) throws Exception {
return queryTag(gidList, token, KK_SB_APP_ID);
}
/** /**
* 根据giUid查询用户相关标签code * 根据giUid查询用户相关标签code
* *
* @param userIdList * @param gidList 用户gid
* @param token * @param token 鉴权
* @return * @return 执行结果
* @throws Exception * @throws Exception 抛出异常
*/ */
public static String queryTag(String[] userIdList, String token) throws Exception { private static String queryTag(List<String> gidList, String token, String appId) throws Exception {
//请求url //请求url
String getUsersCidUrl = "https://openapi-gi.getui.com/v3/" + APPID + "/query_tag"; String getUsersCidUrl = "https://openapi-gi.getui.com/v3/" + appId + "/query_tag";
//将token以及用户ID封装调用画像查询接口 //将token以及用户ID封装调用画像查询接口
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>(2);
map.put("userIdList", userIdList); map.put("userIdList", gidList);
map.put("token", token); map.put("token", token);
//发送post请求拿到当前用户的所有图像 //发送post请求拿到当前用户的所有图像
return HttpUtil.postGeneralUrl(getUsersCidUrl, CONTENTTYPE, JSONObject.toJSONString(map), ENCODING); return HttpUtil.postGeneralUrl(getUsersCidUrl, CONTENT_TYPE, JSONObject.toJSONString(map), ENCODING);
}
/**
* 删除鉴权token
*
* @param token 接口调用凭证token
* @return 是否成功
*/
public static boolean delToken(String token) {
try {
String body = HttpRequest.delete(GE_TUI_BASE_URL + KK_SH_APP_ID + "/auth" + token).execute().body();
if (HttpUtil.isJson2(body)) {
JSONObject jsonObject = JSONObject.parseObject(body);
return jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0;
}
} catch (HttpException e) {
e.printStackTrace();
log.error("删除个推鉴权token失败{}", e.getMessage());
}
return false;
} }
/** /**
* 执行别名单推 * 【toSingle】执行别名单推
* *
* @param alias 用户别名 * @param alias 用户别名
* @param messageTemplate 消息模板 * @param messageTemplate 消息模板
* @param token token * @param token 接口访问凭据
* @return 消息推送结果 * @return 消息推送结果
* @throws Exception
*/ */
public static String singlePush(String[] alias, MessageTemplate messageTemplate, String token) throws Exception { public static String singlePushAlias(String[] alias, MessageTemplate messageTemplate, String token) {
Map<String, Object> map = convertBeanToMap(alias, messageTemplate); Map<String, Object> map = convertBeanToMap(alias, messageTemplate);
//请求url //请求url
String url = GETUIBASEURL + APPID + "/push/single/alias"; String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/single/alias";
HttpRequest request = cn.hutool.http.HttpUtil.createPost(url);
request.header("token", token);
request.body(JSONUtil.toJsonStr(map));
log.info("执行别名单推"); log.info("执行别名单推");
return request.execute().body(); return generalPost(url, token, map);
} }
/** /**
* 创建消息拿到任务id * 创建消息拿到任务id
* *
* @param messageTemplate 消息模板 * @param messageTemplate 消息模板
* @param token token * @param token token
* @return 任务id * @return 任务id
* @throws Exception
*/ */
public static String getTaskId(MessageTemplate messageTemplate, String token) throws Exception { public static String getTaskId(MessageTemplate messageTemplate, String token) {
Map<String, Object> map = convertBeanToMap(null, messageTemplate); Map<String, Object> map = convertBeanToMap(null, messageTemplate);
//请求url //请求url
String url = GETUIBASEURL + APPID + "/push/list/message"; String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/list/message";
//创建post请求 String body = generalPost(url, token, map);
HttpRequest request = cn.hutool.http.HttpUtil.createPost(url);
//设置请求头token
request.header("token", token);
//设置请求体数据
request.body(JSONUtil.toJsonStr(map));
////创建消息 获取taskid
log.info("获取任务id");
String body = request.execute().body();
JSONObject jsonObject = JSONObject.parseObject(body); JSONObject jsonObject = JSONObject.parseObject(body);
return (jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0) ? jsonObject.getJSONObject("data").getString("taskid") : body; return (jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0) ? jsonObject.getJSONObject("data").getString("taskid") : body;
} }
/**
* 【toList】执行cid批量推
*
* @param cid cid数组
* @param token 鉴权
* @param taskId 任务id
* @param is_async 是否异步
* @return 执行结果
*/
public static String listPushCid(String[] cid, String token, String taskId, boolean is_async) {
String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/list/cid";
Map<String, Object> cids = new HashMap<>(1);
cids.put("cid", cid);
return listPushTaskId(url, token, taskId, is_async, cids);
}
/**
* 【toList】执行别名批量推
*
* @param alias 别名
* @param token 鉴权
* @param taskId 任务id
* @param is_async 是否异步
* @return 执行结果
*/
public static String listPushAlias(String[] alias, String token, String taskId, boolean is_async) {
String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/list/alias";
Map<String, Object> aliass = new HashMap<>(1);
aliass.put("alias", alias);
return listPushTaskId(url, token, taskId, is_async, aliass);
}
/**
* 批量推送通用
*
* @param url 请求路径
* @param token 鉴权
* @param taskId 任务id
* @param is_async 是否异步
* @param hashMao 推送目标用户
* @return 执行结果
*/
private static String listPushTaskId(String url, String token, String taskId, boolean is_async, Map<String, Object> hashMao) {
Map<String, Object> map = new HashMap<>(3);
map.put("audience", hashMao);
map.put("taskid", taskId);
map.put("is_async", is_async);
return generalPost(url, token, map);
}
/**
* 【toApp】执行群推
*
* @param messageTemplate 请求参数
* @param token token
* @return 执行结果
*/
public static String listPushToApp(MessageTemplate messageTemplate, String appId, String token) {
Map<String, Object> map = convertBeanToMap(null, messageTemplate);
//请求url
String url = GE_TUI_BASE_URL + appId + "/push/all";
log.info("执行群推");
return generalPost(url, token, map);
}
/** /**
* 实体类封装为map * 实体类封装为map
* *
...@@ -161,65 +338,145 @@ public class GeTuiUtils { ...@@ -161,65 +338,145 @@ public class GeTuiUtils {
* @return map对象 * @return map对象
*/ */
public static Map<String, Object> convertBeanToMap(String[] alias, MessageTemplate messageTemplate) { public static Map<String, Object> convertBeanToMap(String[] alias, MessageTemplate messageTemplate) {
if (ArrayUtils.isEmpty(alias) || messageTemplate == null) return null; if (messageTemplate == null) {
return null;
}
//设置推送目标
messageTemplate.setAudience(new MessageTemplate.Audience(alias));
//设置请求唯一标识号,10-32位之间;如果request_id重复,会导致消息丢失
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
//request_id 唯一不重复 map.put("request_id", String.valueOf(IdUtil.getSnowflake(1, 1).nextId()));
map.put("request_id", System.currentTimeMillis() + RandomUtil.randomString(15));
//任务组名 //设置任务组名
String group_name = messageTemplate.getGroup_name(); if (StringUtils.isNotBlank(messageTemplate.getGroup_name())) {
if (StringUtils.isNotBlank(group_name)) { map.put("group_name", messageTemplate.getGroup_name());
map.put("group_name", group_name);
} }
Map<String, Object> audienceMap = new HashMap<>(); //推送条件设置
audienceMap.put("alias", alias); MessageTemplate.Settings settings = messageTemplate.getSettings();
map.put("audience", audienceMap); if (settings != null) {
Map<String, Object> setting = BeanUtil.beanToMap(settings, false, true);
Map<String, Object> strategy = new HashMap<>();
strategy.put("default", 4);
strategy.put("ios", 4);
strategy.put("st", 4);
strategy.put("hw", 4);
strategy.put("xm", 4);
strategy.put("vv", 4);
strategy.put("mz", 4);
strategy.put("op", 4);
setting.put("strategy", strategy);
map.put("settings", setting);
}
//消息离线时间设置,单位毫秒,-1表示不设离线,-1 ~ 3 * 24 * 3600 * 1000(3天)之间 //推送目标用户该接口audience 对应值为all,表示推送所有用户
Long ttl = messageTemplate.getTtl(); if (alias == null || alias.length == 0) {
if (ttl != null) { map.put("audience", "all");
Map<String, Object> settingsMap = new HashMap<>(); } else {
settingsMap.put("ttl", ttl); Map<String, Object> audience = BeanUtil.beanToMap(messageTemplate.getAudience(), false, true);
map.put("settings", settingsMap); map.put("audience", audience);
} }
//消息模板 //获取推送消息转为map 不转为下划线,忽略空值
Map<String, Object> pushMessageMap = new HashMap<>(); MessageTemplate.PushMessage push_message = messageTemplate.getPush_message();
Map<String, Object> notificationMap = new HashMap<>(); Map<String, Object> push_messages = BeanUtil.beanToMap(push_message, false, true);
notificationMap.put("title", messageTemplate.getTitle());
notificationMap.put("body", messageTemplate.getBody()); //转换消息忽略空值
notificationMap.put("click_type", messageTemplate.getClick_type()); MessageTemplate.PushMessage.Notification notification = push_message.getNotification();
switch (messageTemplate.getClick_type()) { if (notification != null) {
case "intent": //设置消息
notificationMap.put("intent", messageTemplate.getIntent()); Map<String, Object> notifications = BeanUtil.beanToMap(notification, false, true);
case "url": push_messages.put("notification", notifications);
notificationMap.put("url", messageTemplate.getUrl());
} }
pushMessageMap.put("notification", notificationMap); MessageTemplate.PushMessage.Revoke revoke = push_message.getRevoke();
map.put("push_message", pushMessageMap); if (revoke != null) {
//设置撤回消息
Map<String, Object> revokes = BeanUtil.beanToMap(revoke, false, true);
push_messages.put("revoke", revokes);
}
//设置ios厂商通道
map.put("push_channel", setChannel(notification));
//设置android厂商通道
map.put("push_message", push_messages);
return map; return map;
} }
/** /**
* 执行别名批量推送 * 设置推送渠道
* *
* @param map body参数 * @param notification 消息
* @param token token * @return json
* @return 执行结果
*/ */
public static String listPushByAlias(Map<String, Object> map, String token) { public static cn.hutool.json.JSONObject setChannel(MessageTemplate.PushMessage.Notification notification) {
//请求url Map<String, Object> channel = new HashMap<>();
String url = GETUIBASEURL + APPID + "/push/list/alias"; //获取ios配置
//创建post请求 channel.put("ios", getIosChannel(notification));
HttpRequest request = cn.hutool.http.HttpUtil.createPost(url); //获取android配置
channel.put("android", getAndroidChannel(notification));
return JSONUtil.parseFromMap(channel);
}
/**
* ios厂商通道消息配置
*
* @param notification 消息
* @return ios配置
*/
private static Map<String, Object> getIosChannel(MessageTemplate.PushMessage.Notification notification) {
Map<String, Object> ios = new HashMap<>();
ios.put("type", "notify");
//推送通知消息内容
Map<String, Object> aps = new HashMap<>();
aps.put("content-available", 0);
//通知消息
Map<String, Object> alert = new HashMap<>();
alert.put("title", notification.getTitle());
alert.put("body", notification.getBody());
aps.put("alert", alert);
ios.put("aps", aps);
return ios;
}
/**
* 安卓厂商通道消息配置
*
* @param notification 消息
* @return android配置
*/
private static Map<String, Object> getAndroidChannel(MessageTemplate.PushMessage.Notification notification) {
Map<String, Object> android = new HashMap<>();
//android厂商通道推送消息内容
Map<String, Object> ups = new HashMap<>();
//通知消息内容,与transmission、revoke三选一,都填写时报错。若希望客户端离线时,直接在系统通知栏中展示通知栏消息,推荐使用此参数。
Map<String, Object> informAndroid = new HashMap<>();
informAndroid.put("title", notification.getTitle());
informAndroid.put("body", notification.getBody());
informAndroid.put("click_type", notification.getClick_type());
informAndroid.put("url", notification.getUrl());
ups.put("notification", informAndroid);
android.put("ups", ups);
return android;
}
/**
* post请求通用
*
* @param url 请求路径
* @param token 鉴权
* @param map 请求体参数
* @return 结果
*/
public static String generalPost(String url, String token, Map<String, Object> map) {
HttpRequest post = HttpRequest.post(url);
//设置请求头token //设置请求头token
request.header("token", token); post.header("token", token);
//设置请求体数据 post.header("Content-Type", CONTENT_TYPE);
request.body(JSONUtil.toJsonStr(map)); return post.body(JSONUtil.toJsonStr(map)).execute().body();
//执行请求
log.info("执行别名批量推送");
return request.execute().body();
} }
} }
package com.weface.component; package com.weface.component;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.TypeReference; import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.weface.entity.MenuTagsEntity; import com.weface.entity.MenuTagsEntity;
import com.weface.entity.TUserTagEntity; import com.weface.entity.UserTagEntity;
import com.weface.entity.UserMenusEntity; import com.weface.entity.UserMenusEntity;
import com.weface.service.MenuTagsService;
import com.weface.service.TUserTagService;
import com.weface.common.exception.RRException;
import com.weface.common.utils.CacheUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/** /**
* @CreateUser: Administrator * @author Administrator
* @CreateTime: 2021/11/2 * @CreateTime: 2021/11/2
*/ */
@Slf4j @Slf4j
@Component @Component
@Transactional
public class MenuService { public class MenuService {
@Autowired
private MenuTagsService menuTagsService;
@Autowired
private TUserTagService tUserTagService;
private static final CacheUtil CACHE = CacheUtil.getInstance();
private static final ReentrantLock lock = new ReentrantLock();
/** /**
* 获取token并缓存一份 * 从map中解析标签并收集关系表数据
* *
* @return 从缓存中拿token * @param map 个推返回数据
* @return 标签数据
*/ */
public String getAuthToken() { public List<UserMenusEntity> getTagUser(Map<String, Object> map, List<UserTagEntity> userInfo) {
String authToken = "";
lock.lock();
try { try {
authToken = Convert.toStr(CACHE.getCacheData("authToken")); Snowflake snowflake = IdUtil.getSnowflake(1, 1);
if (Objects.isNull(authToken)) { //获取所有用户标签
authToken = GeTuiUtils.getAuth(); List<Map<String, Object>> userTag = Convert.convert(new TypeReference<List<Map<String, Object>>>() {
// authToken = "01718df19708866512701e7637fee9568a0dac5f9390609f08ef148cab56c060"; }, map.get("userTag"));
if (ObjectUtil.isNull(authToken)) throw new RRException("获取个推token失败"); //收集中间表数据
CACHE.addCacheData("authToken", authToken); List<UserMenusEntity> userMenusList = new ArrayList<>();
//获取所有用户信息
for (Map<String, Object> item : userTag) {
//拿到当前用户giUid
String userId = (String) item.get("userId");
//拿到标签
List<Long> list = Convert.convert(new TypeReference<List<Long>>() {
}, item.get("tags"));
//查找当前用户的id
Optional<UserTagEntity> first = userInfo.stream().filter(x -> userId.equals(x.getGid())).findFirst();
//如果对象不为空
if (first.isPresent()) {
//拿到id
String uid = first.get().getUid();
//遍历标签id
Date date = new Date();
for (Long aLong : list) {
//填充数据
UserMenusEntity userMenusEntity = new UserMenusEntity();
userMenusEntity.setId(snowflake.nextId());
userMenusEntity.setUserId(uid);
userMenusEntity.setTagsId(aLong);
userMenusEntity.setIsValid(1);
userMenusEntity.setCreateTime(date);
//添加数据到集合内
userMenusList.add(userMenusEntity);
}
}
} }
} catch (RRException e) { return userMenusList;
} catch (ConvertException e) {
e.printStackTrace(); e.printStackTrace();
log.error("加锁失败!"); log.error("转换用户标签失败{}", e.getMessage());
} finally {
lock.unlock();
} }
return authToken; return null;
} }
/** /**
* 通过gid以及操作系统字段获取标签code并转为实际值,后存库并返回 * 通过gid以及操作系统字段获取标签code并转为实际值,后存库并返回
* *
* @param userList 用户的giUid * @param gidList 用户的giUid
* @return * @param tags 标签信息
* @return 走個推查詢數據
*/ */
public Map<String, Object> getUserTags(String[] userList) { public Map<String, Object> getUserTags(List<String> gidList, List<MenuTagsEntity> tags) {
//获取token
String kk_sh_token = "kk_sh_token";
try { try {
if (ArrayUtil.isEmpty(userList)) return null; String authToken = GeTuiUtils.getAuthToken(kk_sh_token);
//根据用户giuId请求到用户最新的爱好数据 System.out.println("===============" + authToken);
Map<String, Object> map = queryTag(userList); //将token以及用户ID封装调用画像查询接口
//以上均做过非空处理如果返回不为空 那么map内一定是有数据的 String result = GeTuiUtils.queryTagKKSH(gidList, authToken);
if (map == null) return null; JSONObject jsonObject = JSONObject.parseObject(result);
return map; //判断返回json内是否包含要解析的userTag
if (jsonObject.containsKey("userTag")) {
JSONArray userTag = jsonObject.getJSONArray("userTag");
List<Map<String, Object>> userTags = getUserTagByTag(userTag, 1, tags);
Map<String, Object> all = null;
if (userTags != null && userTag.size() > 0) {
all = new HashMap<>(2);
//将数据封装并转为json格式返回
all.put("userTag", userTags);
all.put("error_code", 0);
}
return all;
//如果以上步骤无法走通则直接返回。并修改标识符终止循环
} else {
log.error("返回值内不包含需要解析的数据" + jsonObject.toJSONString());
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("执行新增用户标签数据到用户表中发生异常" + e.getMessage()); log.error("执行调用个推接口获取标签数据发生异常" + e.getMessage());
} }
return null; return null;
} }
/**
* 从map中解析标签并收集关系表数据
*
* @param map 个推返回数据
* @return 标签数据
*/
public List<UserMenusEntity> getTagUser(Map<String, Object> map) {
if (ObjectUtil.isNull(map)) return null;
//获取所有用户标签
List<Map<String, Object>> userTag = Convert.convert(new TypeReference<List<Map<String, Object>>>() {
}, map.get("userTag"));
//收集中间表数据
List<UserMenusEntity> userMenusList = new ArrayList<>();
//获取所有用户信息
List<TUserTagEntity> tUserTagEntities = tUserTagService.list(new QueryWrapper<TUserTagEntity>()
.lambda().orderByDesc(TUserTagEntity::getSaveDate));
//遍历所有返回用户数据
for (Map<String, Object> item : userTag) {
//拿到当前用户giUid
String userId = (String) item.get("userId");
//拿到标签
List<MenuTagsEntity> list = Convert.convert(new TypeReference<List<MenuTagsEntity>>() {
}, item.get("tags"));
//查找当前用户的id
Optional<TUserTagEntity> first = tUserTagEntities.stream().filter(x -> userId.equals(x.getGid())).findFirst();
//如果对象不为空
if (first.isPresent()) {
//拿到id
String uid = first.get().getUid();
//收集标签id
List<Long> collect = list.stream().map(MenuTagsEntity::getId).collect(Collectors.toList());
//遍历标签id
Date date = new Date();
for (Long aLong : collect) {
//填充数据
UserMenusEntity userMenusEntity = new UserMenusEntity();
userMenusEntity.setUserId(uid);
userMenusEntity.setTagsId(aLong);
userMenusEntity.setIsValid(1);
userMenusEntity.setCreateTime(date);
//添加数据到集合内
userMenusList.add(userMenusEntity);
}
}
}
return userMenusList;
}
/** /**
* 通过用户id获取获取用户标签信息 * 获取看看社保用户标签
* *
* @param userIdList gid * @param gidList 用户gid
* @return * @return 用户标签信息
* @throws Exception 异常
*/ */
private Map<String, Object> queryTag(String[] userIdList) { private List<Map<String, Object>> getSBTags(List<String> gidList, List<MenuTagsEntity> tags) throws Exception {
//设置标识 String kk_sb_token = "kk_sb_token";
boolean flag = true;
//获取token //获取token
String authToken = getAuthToken(); String authToken = GeTuiUtils.getAuthToken(kk_sb_token);
try { //将token以及用户ID封装调用画像查询接口
while (flag) { String result = GeTuiUtils.queryTagKKSB(gidList, authToken);
//将token以及用户ID封装调用画像查询接口 JSONObject jsonObject = JSONObject.parseObject(result);
String result = GeTuiUtils.queryTag(userIdList, authToken); //判断返回json内是否包含要解析的userTag
JSONObject jsonObject = JSONObject.parseObject(result); if (jsonObject.containsKey("userTag")) {
//如果状态码为302token已过期则需要重新获取token并更新数据库token JSONArray userTag = jsonObject.getJSONArray("userTag");
if (jsonObject.containsKey("error_info") && jsonObject.getJSONObject("error_info").getInteger("error_code") == 302) { return getUserTagByTag(userTag, 2, tags);
log.warn("token过期"); //如果以上步骤无法走通则直接返回。并修改标识符终止循环
//authToken = "01718df19708866512701e7637fee9568a0dac5f9390609f08ef148cab56c060"; } else {
authToken = GeTuiUtils.getAuth(); log.error("返回值内不包含需要解析的数据" + jsonObject.toJSONString());
if (ObjectUtil.isNull(authToken)) throw new RRException("获取个推token失败");
CACHE.addCacheData("authToken", authToken);
break;
}
//判断返回json内是否包含要解析的userTag
if (jsonObject.containsKey("userTag")) {
JSONArray userTag = jsonObject.getJSONArray("userTag");
List<Map<String, Object>> userTags = getUserTagByTag(userTag);
Map<String, Object> all = null;
if (userTags != null && userTag.size() > 0) {
all = new HashMap<>();
//将数据封装并转为json格式返回
all.put("userTag", userTags);
all.put("error_code", 0);
}
return all;
//如果以上步骤无法走通则直接返回。并修改标识符终止循环
} else {
log.error("返回值内不包含需要解析的数据" + jsonObject.toJSONString());
flag = false;
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("执行调用个推接口获取标签数据发生异常" + e.getMessage());
} }
return null; return null;
} }
...@@ -191,46 +145,56 @@ public class MenuService { ...@@ -191,46 +145,56 @@ public class MenuService {
* 解析json拿到所有用户 * 解析json拿到所有用户
* *
* @param userTag 用户数据 * @param userTag 用户数据
* @return * @param type 解析类型 1 看看生活解析 2 看看社保解析
* @return 標簽數據
*/ */
private List<Map<String, Object>> getUserTagByTag(JSONArray userTag) { private List<Map<String, Object>> getUserTagByTag(JSONArray userTag, int type, List<MenuTagsEntity> tags) throws Exception {
//封装返回的数据userTags
List<Map<String, Object>> userTags = null; List<Map<String, Object>> userTags = null;
Integer failCount = Convert.toInt(CACHE.getCacheData("failCount")); //查询用户画像失败的gid用户
Integer successCount = Convert.toInt(CACHE.getCacheData("successCount")); List<String> gidList = new ArrayList<>();
if (ObjectUtil.isNull(failCount)) //解析用户标签
failCount = 0;
if (ObjectUtil.isNull(successCount))
successCount = 0;
if (userTag != null && userTag.size() > 0) { if (userTag != null && userTag.size() > 0) {
//封装返回的数据userTags //初始化
userTags = new ArrayList<>(userTag.size()); userTags = new ArrayList<>(userTag.size());
for (Object o : userTag) { for (Object o : userTag) {
JSONObject jsonObject1 = JSONObject.parseObject(o.toString()); JSONObject jsonObject1 = JSONObject.parseObject(o.toString());
String userId = "";
if (jsonObject1.containsKey("userId")) {
userId = jsonObject1.getString("userId");
}
//如果从json中获取的当前giUid为空,则跳出本次循环
if (StringUtils.isBlank(userId)) {
continue;
}
//判断返回json内是否包含要解析的error_code,并判断返回的json状态码是否正常 //判断返回json内是否包含要解析的error_code,并判断返回的json状态码是否正常
if (jsonObject1.containsKey("error_code") && jsonObject1.getInteger("error_code") == 0) { Integer errorCode = jsonObject1.getInteger("error_code");
String userId = ""; if (errorCode == 0) {
if (jsonObject1.containsKey("userId"))
userId = jsonObject1.getString("userId");
//如果从json中获取的当前giUid为空,则跳出本次循环
if (StringUtils.isBlank(userId)) continue;
//封装当前用户的所有tags信息 //封装当前用户的所有tags信息
Map<String, Object> data = new HashMap<>(2); Map<String, Object> data = new HashMap<>(2);
//封装要返回的所有tags //封装要返回的所有tags
List<MenuTagsEntity> list = getMenuByTag(jsonObject1.getJSONArray("tags")); List<Long> list = getMenuByTag(jsonObject1.getJSONArray("tags"), tags);
//根据giUid查询的标签如果为空则跳出本次循环 //根据giUid查询的标签如果为空则跳出本次循环
if (list != null && list.size() > 0) { if (list != null && list.size() > 0) {
data.put("userId", userId); data.put("userId", userId);
data.put("tags", list); data.put("tags", list);
userTags.add(data); userTags.add(data);
} }
successCount++; } else if (errorCode == 109) {
} else { if (type == 1) {
failCount++; gidList.add(userId);
}
}
}
//如果调用的是看看生活的用户标签失败时,尝试调取看看社保用户标签
if (type == 1) {
List<Map<String, Object>> sbTags = getSBTags(gidList, tags);
if (sbTags != null && sbTags.size() > 0) {
userTags.addAll(sbTags);
} }
} }
} }
CACHE.addCacheData("failCount", failCount);
CACHE.addCacheData("successCount", successCount);
return userTags; return userTags;
} }
...@@ -239,27 +203,31 @@ public class MenuService { ...@@ -239,27 +203,31 @@ public class MenuService {
* 根据标签的code查询标签数据 * 根据标签的code查询标签数据
* *
* @param tags 标签 * @param tags 标签
* @return * @return 標簽數據
*/ */
private List<MenuTagsEntity> getMenuByTag(JSONArray tags) { private List<Long> getMenuByTag(JSONArray tags, List<MenuTagsEntity> menus) {
List<MenuTagsEntity> list = null; List<Long> list = null;
if (tags != null && tags.size() > 0) { if (tags != null && tags.size() > 0) {
list = new ArrayList<>(tags.size()); list = new ArrayList<>(tags.size());
for (Object tag : tags) { for (Object tag : tags) {
JSONObject jsonObject2 = JSONObject.parseObject(tag.toString()); JSONObject jsonObject2 = JSONObject.parseObject(tag.toString());
String code = ""; String code = "";
if (jsonObject2.containsKey("code")) if (jsonObject2.containsKey("code")) {
code = jsonObject2.getString("code"); code = jsonObject2.getString("code");
if (code.startsWith("c") || code.startsWith("C")) {
code = code.replaceFirst("c", "");
}
}
//如果传入标签的code为空则跳出本次循环 //如果传入标签的code为空则跳出本次循环
if (StringUtils.isBlank(code)) continue; if (StringUtils.isBlank(code)) {
String weight = ""; continue;
if (jsonObject2.containsKey("weight")) }
weight = jsonObject2.getString("weight");
//根据code或权重查询图像 //根据code或权重查询图像
MenuTagsEntity one = menuTagsService.getOneByCodeOrWeight(code, weight); String finalCode = code;
//如果查询的结果为空则跳出本次循环 Optional<MenuTagsEntity> first = menus.stream().filter(x -> finalCode.equals(x.getCode())).findFirst();
if (one == null) continue; if (first.isPresent()) {
list.add(one); list.add(first.get().getId());
}
} }
} }
return list; return list;
......
...@@ -4,48 +4,165 @@ import lombok.AllArgsConstructor; ...@@ -4,48 +4,165 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.Serializable;
/** /**
* @CreateUser: Administrator * @author Administrator
* @CreateTime: 2021/11/23 * @CreateTime: 2021/11/23
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class MessageTemplate { public class MessageTemplate implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 请求唯一标识号,10-32位之间;如果request_id重复,会导致消息丢失
*/
private String request_id;
/** /**
* 任务组 * 任务组
*/ */
private String group_name; private String group_name;
/** /**
* 消息离线时间设置,单位毫秒,-1表示不设离线,-1 ~ 3 * 24 * 3600 * 1000(3天)之间 * 推送目标用户该接口audience 对应值为all,表示推送所有用户
*/ */
private Long ttl; private Audience audience;
/** /**
* 通知消息标题,长度 ≤ 50 * 推送条件设置
*/ */
private String title; private Settings settings;
/** /**
* 通知消息内容,长度 ≤ 256 * 个推推送消息参数
*/ */
private String body; private PushMessage push_message;
/** /**
* 点击通知后续动作, * 厂商推送消息参数,包含ios消息参数,android厂商消息参数
* 目前支持以下后续动作,
* intent:打开应用内特定页面,
* url:打开网页地址,
* payload:自定义消息内容启动应用,
* payload_custom:自定义消息内容不启动应用,
* startapp:打开应用首页,
* none:纯通知,无后续动作
*/ */
private String click_type; private PushChannel push_channel;
/** /**
* click_type为url时必填 无 点击通知打开链接 * 推送目标用户该接口audience 对应值为all,表示推送所有用户
*/ */
private String url; @Data
@NoArgsConstructor
@AllArgsConstructor
public static class Audience implements Serializable {
private static final long serialVersionUID = 1L;
//别名数组,只能填一个别名
private String[] alias;
}
/** /**
* click_type为intent时必填 无 点击通知打开应用特定页面,长度 ≤ 4096; * 推送条件设置
*/ */
private String intent; @Data
@NoArgsConstructor
@AllArgsConstructor
public static class Settings implements Serializable {
private static final long serialVersionUID = 1L;
//消息离线时间设置,单位毫秒,-1表示不设离线,-1 ~ 3 * 24 * 3600 * 1000(3天)之间
private Integer ttl;
//定速推送,例如100,个推控制下发速度在100条/秒左右,0表示不限速
private Integer speed;
}
/**
* 个推推送消息参数
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class PushMessage implements Serializable {
private static final long serialVersionUID = 1L;
//手机端通知展示时间段,格式为毫秒时间戳段,两个时间的时间差必须大于10分钟,例如:"1590547347000-1590633747000"
private String duration;
//纯透传消息内容,安卓和iOS均支持,与notification、revoke 三选一,都填写时报错,长度 ≤ 3072
private String transmission;
//消息模板
private Notification notification;
//撤回消息时使用(仅撤回个推通道消息),与notification、transmission三选一,都填写时报错(消息撤回请勿填写策略参数)
private Revoke revoke;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Notification implements Serializable {
private static final long serialVersionUID = 1L;
private String title;
private String body;
private String big_text;
private String big_image;
private String logo;
private String logo_url;
private String channel_id;
private String channel_name;
private Integer channel_level;
private String click_type;
private String intent;
private String url;
private String payload;
private Integer notify_id;
private String ring_name;
private Integer badge_add_num;
private String thread_id;
}
@Data
public static class Revoke {
private String old_task_id;
private Integer force;
}
}
/**
* 厂商推送消息参数,包含ios消息参数,android厂商消息参数
*/
@Data
public static class PushChannel implements Serializable {
private static final long serialVersionUID = 1L;
private Android android;
/**
* ios通道推送消息内容
*/
@Data
public static class Ios implements Serializable {
private static final long serialVersionUID = 1L;
}
/**
* android通道推送消息内容
*/
@Data
public static class Android implements Serializable {
private static final long serialVersionUID = 1L;
private Ups ups;
@Data
public static class Ups {
private Notification notification;
private String transmission;
private Revoke revoke;
@Data
public static class Notification {
private String title;
private String body;
private String click_type;
private String intent;
private String url;
private Integer notify_id;
}
@Data
public static class Revoke {
private String old_task_id;
}
}
}
}
} }
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.config; package com.weface.config;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author Administrator
*/
@Configuration @Configuration
public class CorsConfig implements WebMvcConfigurer { public class CorsConfig implements WebMvcConfigurer {
......
...@@ -9,6 +9,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; ...@@ -9,6 +9,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
/**
* @author Administrator
*/
@EnableAsync @EnableAsync
@Configuration @Configuration
public class ExecutorConfig { public class ExecutorConfig {
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.config; package com.weface.config;
import com.weface.common.xss.XssFilter; import com.weface.common.xss.XssFilter;
......
...@@ -6,7 +6,7 @@ import org.apache.ibatis.reflection.MetaObject; ...@@ -6,7 +6,7 @@ import org.apache.ibatis.reflection.MetaObject;
import java.util.Date; import java.util.Date;
/** /**
* @CreateUser: Administrator * @author Administrator
* @CreateTime: 2021/11/16 * @CreateTime: 2021/11/16
* 自动填充属性 * 自动填充属性
*/ */
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.config; package com.weface.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
......
package com.weface.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
/**
* @author : Administrator
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
...@@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
...@@ -19,7 +20,6 @@ import java.util.Map; ...@@ -19,7 +20,6 @@ import java.util.Map;
* 所有标签等级划分 * 所有标签等级划分
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@RestController @RestController
...@@ -41,12 +41,10 @@ public class MenuTagsController { ...@@ -41,12 +41,10 @@ public class MenuTagsController {
/** /**
* 根据用户giUid先调个推拿到code后走数据库拿到数据并更新相关数据后返回 * 根据用户giUid先调个推拿到code后走数据库拿到数据并更新相关数据后返回
*
* @return
*/ */
@PostMapping("/queryTagByGiUid") @PostMapping("/queryTagByGiUid")
public Model queryTagsByGiUid(@RequestBody UserTagFrom userTagFrom) { public Model queryTagsByGiUid(@RequestBody UserTagFrom userTagFrom) {
Map<String, Object> data = menuService.getUserTags(userTagFrom.getGiUidList()); Map<String, Object> data = menuService.getUserTags(Arrays.asList(userTagFrom.getGiUidList()), null);
return Model.ok(data); return Model.ok(data);
} }
......
...@@ -10,6 +10,9 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -10,6 +10,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/**
* @author Administrator
*/
@RestController @RestController
@RequestMapping("push") @RequestMapping("push")
public class PushController { public class PushController {
...@@ -23,7 +26,7 @@ public class PushController { ...@@ -23,7 +26,7 @@ public class PushController {
} }
@PostMapping("single") @PostMapping("single")
public CommonResult pushSingle(@RequestBody MsgDTO param){ public CommonResult pushSingle(@RequestBody MsgDTO param) {
return pushService.pushSingle(param); return pushService.pushSingle(param);
} }
} }
...@@ -3,7 +3,8 @@ package com.weface.controller; ...@@ -3,7 +3,8 @@ package com.weface.controller;
import com.weface.common.utils.Model; import com.weface.common.utils.Model;
import com.weface.common.utils.PageUtils; import com.weface.common.utils.PageUtils;
import com.weface.dto.UserTagFrom; import com.weface.dto.UserTagFrom;
import com.weface.service.TUserTagService; import com.weface.service.UserTagService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -16,14 +17,13 @@ import java.util.Map; ...@@ -16,14 +17,13 @@ import java.util.Map;
/** /**
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@RestController @RestController
@RequestMapping("/tags/userTags") @RequestMapping("/tags/userTags")
public class UserTagsController { public class UserTagsController {
@Autowired @Autowired
private TUserTagService tUserTagService; private UserTagService tUserTagService;
/** /**
* 查询所有用户对应标签信息 * 查询所有用户对应标签信息
...@@ -48,9 +48,11 @@ public class UserTagsController { ...@@ -48,9 +48,11 @@ public class UserTagsController {
*/ */
@PostMapping("/queryByGid") @PostMapping("/queryByGid")
public Model queryByGid(@RequestBody UserTagFrom userTagFrom) { public Model queryByGid(@RequestBody UserTagFrom userTagFrom) {
// String[] userIdList = new String[]{"3917d1037675078ae3a1abb4c6da3ef6", "1231313123"}; String gid = userTagFrom.getGiUidList()[0];
// String os = "Android"; if (StringUtils.isBlank(gid)) {
Map<String, Object> data = tUserTagService.getTagByGid(userTagFrom.getGiUidList()); return Model.error("gid不能为空");
}
Map<String, Object> data = tUserTagService.getTagByGid(gid);
return Model.ok(data); return Model.ok(data);
} }
......
...@@ -8,7 +8,6 @@ import org.apache.ibatis.annotations.Mapper; ...@@ -8,7 +8,6 @@ import org.apache.ibatis.annotations.Mapper;
* 所有标签等级划分 * 所有标签等级划分
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@Mapper @Mapper
......
package com.weface.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.weface.entity.TUserTagEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 用户ID标签关联表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-30 18:57:06
*/
@Mapper
public interface TUserTagDao extends BaseMapper<TUserTagEntity> {
//查询用户和标签信息
<T> IPage<TUserTagEntity> getUserAndTags(Page<T> page, String giUid, String tag);
//使用limit分页查询
List<String> findGidByLimit(int pageRecord, int limit);
//根据标签查询用户gid
List<String> getGidByTag(List<String> list);
//根据gid查询用户标签
List<TUserTagEntity> getTagByGid(List<String> list);
//查询所有用户标签关联数据
List<TUserTagEntity> selectAllUserForTags();
//查询今天更新用户gid
List<String> findTodayGid();
}
...@@ -10,16 +10,25 @@ import java.util.List; ...@@ -10,16 +10,25 @@ import java.util.List;
* 用户和标签中间表 * 用户和标签中间表
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@Mapper @Mapper
public interface UserMenusDao extends BaseMapper<UserMenusEntity> { public interface UserMenusDao extends BaseMapper<UserMenusEntity> {
//批量插入 /**
* 批量插入
*
* @param list 插入数据
* @return 成功条数
*/
int batchInsert(List<UserMenusEntity> list); int batchInsert(List<UserMenusEntity> list);
//根据uid查询标签id /**
* 根据uid查询标签id
*
* @param list gid
* @return 标签id
*/
List<Long> findIdByUserId(List<String> list); List<Long> findIdByUserId(List<String> list);
} }
package com.weface.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.weface.entity.UserTagEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 用户ID标签关联表
*
* @author chenshun
* @date 2021-11-30 18:57:06
*/
@Mapper
public interface UserTagDao extends BaseMapper<UserTagEntity> {
/**
* 查询今天用户信息
*
* @return 用户信息
*/
List<UserTagEntity> findUserByTodayAndIdBefore(Integer id);
/**
* 根据时间查询用户信息
*
* @return 用户信息
*/
List<UserTagEntity> findUserByIdAfter(Integer id, Integer limit);
/**
* 查询库中无标签用户
*
* @return 用户信息
*/
List<UserTagEntity> findNoTagUser(@Param("star") Integer star, @Param("end") Integer end);
/**
* 查询用户和标签信息
*
* @param page 分页
* @param gid 银行gid
* @param <T> 分页泛型
* @return 用户标签数据
*/
<T> IPage<UserTagEntity> getUserAndTags(Page<T> page, @Param("gid") String gid);
/**
* 根据标签查询用户gid
*
* @param list 标签数据
* @return 用户gid
*/
List<String> getGidByTag(List<String> list);
/**
* 根据gid查询用户标签
*
* @param gid 用户gid
* @return 用户标签数据
*/
List<UserTagEntity> getTagByGid(String gid);
/**
* 查询所有用户标签关联数据
*
* @return 用户标签数据
*/
List<UserTagEntity> selectAllUserForTags();
}
...@@ -2,12 +2,16 @@ package com.weface.dto; ...@@ -2,12 +2,16 @@ package com.weface.dto;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* @CreateUser: Administrator * @author Administrator
* @CreateTime: 2021/11/17 * @CreateTime: 2021/11/17
*/ */
@Data @Data
public class UserTagFrom { public class UserTagFrom implements Serializable {
private static final long serialVersionUID = 1L;
private String[] giUidList; private String[] giUidList;
......
...@@ -12,7 +12,6 @@ import java.util.Date; ...@@ -12,7 +12,6 @@ import java.util.Date;
* 所有标签等级划分 * 所有标签等级划分
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@Data @Data
......
...@@ -10,7 +10,6 @@ import java.util.Date; ...@@ -10,7 +10,6 @@ import java.util.Date;
* 用户和标签中间表 * 用户和标签中间表
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
@Data @Data
...@@ -31,9 +30,6 @@ public class UserMenusEntity implements Serializable { ...@@ -31,9 +30,6 @@ public class UserMenusEntity implements Serializable {
* 标签ID * 标签ID
*/ */
private Long tagsId; private Long tagsId;
/**
* 是否删除 1 未删除 0 删除
*/
/** /**
* 是否有效 1:有效 0 无效 * 是否有效 1:有效 0 无效
*/ */
......
...@@ -16,13 +16,12 @@ import java.util.List; ...@@ -16,13 +16,12 @@ import java.util.List;
* 用户ID标签关联表 * 用户ID标签关联表
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-30 18:57:06 * @date 2021-11-30 18:57:06
*/ */
@ExcelTarget("tUserTagEntity") @ExcelTarget("tUserTagEntity")
@Data @Data
@TableName("t_user_tag") @TableName("t_user_tag")
public class TUserTagEntity implements Serializable { public class UserTagEntity implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
...@@ -51,12 +50,6 @@ public class TUserTagEntity implements Serializable { ...@@ -51,12 +50,6 @@ public class TUserTagEntity implements Serializable {
/** /**
* 标签数据 * 标签数据
*/ */
// @ExcelCollection(name = "标签列表",orderNum = "3")
// @TableField(exist = false)
// private List<MenuTagsEntity> list;
/**
* 标签数据
*/
@ExcelEntity(name = "标签列表",id = "id") @ExcelEntity(name = "标签列表",id = "id")
@TableField(exist = false) @TableField(exist = false)
private List<MenuTagsEntity> list; private List<MenuTagsEntity> list;
......
...@@ -10,15 +10,25 @@ import java.util.Map; ...@@ -10,15 +10,25 @@ import java.util.Map;
* 所有标签等级划分 * 所有标签等级划分
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
public interface MenuTagsService extends IService<MenuTagsEntity> { public interface MenuTagsService extends IService<MenuTagsEntity> {
//列表 /**
* 列表
*
* @param params 参数
* @return 标签分页
*/
PageUtils queryPage(Map<String, Object> params); PageUtils queryPage(Map<String, Object> params);
//根据code和权重查询标签 /**
* 根据code和权重查询标签
*
* @param code 编码
* @param weight 权重
* @return 标签信息
*/
MenuTagsEntity getOneByCodeOrWeight(String code, String weight); MenuTagsEntity getOneByCodeOrWeight(String code, String weight);
} }
package com.weface.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.weface.entity.TUserTagEntity;
import com.weface.common.utils.PageUtils;
import java.util.List;
import java.util.Map;
/**
* 用户ID标签关联表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-30 18:57:06
*/
public interface TUserTagService extends IService<TUserTagEntity> {
//查询所有用户对应标签信息
PageUtils getUserAndTags(Map<String, Object> params);
//使用limit分页查询
List<String> findGidByLimit(int i, int limit);
//查询当天的数据
List<String> findTodayGid();
//根据标签查询用户gid
List<String> getGidByTag(String[] tags);
//根据gid查询用户标签
Map<String, Object> getTagByGid(String[] userIdList);
List<TUserTagEntity> getAllImport();
}
...@@ -9,12 +9,15 @@ import java.util.List; ...@@ -9,12 +9,15 @@ import java.util.List;
* 用户和标签中间表 * 用户和标签中间表
* *
* @author chenshun * @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52 * @date 2021-11-18 16:20:52
*/ */
public interface UserMenusService extends IService<UserMenusEntity> { public interface UserMenusService extends IService<UserMenusEntity> {
//批量插入 /**
* 批量插入
*
* @param list 数据列表
*/
void batchInsert(List<UserMenusEntity> list); void batchInsert(List<UserMenusEntity> list);
} }
......
package com.weface.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.weface.entity.UserTagEntity;
import com.weface.common.utils.PageUtils;
import java.util.List;
import java.util.Map;
/**
* 用户ID标签关联表
*
* @author chenshun
* @date 2021-11-30 18:57:06
*/
public interface UserTagService extends IService<UserTagEntity> {
/**
* 查询当天的数据
*
* @return 当天改变的用户
*/
List<UserTagEntity> findUserByTodayAndIdBefore(Integer id);
/**
* 根据时间查询用户信息
*
* @return 用户信息
*/
List<UserTagEntity> findUserByIdAfter(Integer id, Integer limit);
/**
* 查询库中无标签用户
*
* @param star 起始值
* @param end 每页数据
* @return 用户信息
*/
List<UserTagEntity> findNoTagUser(Integer star, Integer end);
/**
* 查询所有用户对应标签信息
*
* @param params 參數
* @return 分頁信息
*/
PageUtils getUserAndTags(Map<String, Object> params);
/**
* 根据标签查询用户gid
*
* @param tags 标签数组
* @return 用户gid
*/
List<String> getGidByTag(String[] tags);
/**
* 根据gid查询用户标签
*
* @param gid 用户gid数组
* @return 用户信息和标签信息
*/
Map<String, Object> getTagByGid(String gid);
/**
* 获取所有用户的标签信息 导出
*
* @return 标签信息
*/
List<UserTagEntity> getAllImport();
}
...@@ -11,9 +11,13 @@ import com.weface.common.utils.Query; ...@@ -11,9 +11,13 @@ import com.weface.common.utils.Query;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map; import java.util.Map;
/**
* @author Administrator
*/
@Service("menuTagsService") @Service("menuTagsService")
public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity> implements MenuTagsService { public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity> implements MenuTagsService {
...@@ -42,10 +46,14 @@ public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity ...@@ -42,10 +46,14 @@ public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity
*/ */
@Override @Override
public MenuTagsEntity getOneByCodeOrWeight(String code, String weight) { public MenuTagsEntity getOneByCodeOrWeight(String code, String weight) {
return this.getOne(new QueryWrapper<MenuTagsEntity>() List<MenuTagsEntity> list = this.list(new QueryWrapper<MenuTagsEntity>()
.lambda().eq(MenuTagsEntity::getCode, code) .lambda().eq(MenuTagsEntity::getCode, code)
.eq(MenuTagsEntity::getLevelFirst, "Android")
.eq(StringUtils.isNotBlank(weight), MenuTagsEntity::getWeight, weight)); .eq(StringUtils.isNotBlank(weight), MenuTagsEntity::getWeight, weight));
if (list != null && list.size() > 0) {
return list.get(0);
} else {
return null;
}
} }
} }
\ No newline at end of file
package com.weface.serviceimpl; package com.weface.serviceimpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weface.dao.UserMenusDao; import com.weface.dao.UserMenusDao;
import com.weface.entity.UserMenusEntity; import com.weface.entity.UserMenusEntity;
...@@ -30,9 +29,6 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt ...@@ -30,9 +29,6 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt
//批量插入前全删 //批量插入前全删
List<Long> ids = this.baseMapper.findIdByUserId(deleteUid); List<Long> ids = this.baseMapper.findIdByUserId(deleteUid);
this.removeByIds(ids); this.removeByIds(ids);
// this.remove(new QueryWrapper<UserMenusEntity>().lambda()
// .eq(UserMenusEntity::getIsValid, 1)
// .in(UserMenusEntity::getUserId, deleteUid));
//获取集合长度 //获取集合长度
int count = userMenusList.size(); int count = userMenusList.size();
//每次批量插入个数 //每次批量插入个数
...@@ -59,6 +55,12 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt ...@@ -59,6 +55,12 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt
} }
} }
/**
* 查询删除的uid
*
* @param userMenusList 用户标签信息
* @return 提取用户uid
*/
private List<String> getDeleteUid(List<UserMenusEntity> userMenusList) { private List<String> getDeleteUid(List<UserMenusEntity> userMenusList) {
return userMenusList.stream().map(UserMenusEntity::getUserId).distinct().collect(Collectors.toList()); return userMenusList.stream().map(UserMenusEntity::getUserId).distinct().collect(Collectors.toList());
} }
......
...@@ -3,10 +3,10 @@ package com.weface.serviceimpl; ...@@ -3,10 +3,10 @@ package com.weface.serviceimpl;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weface.dao.TUserTagDao; import com.weface.dao.UserTagDao;
import com.weface.dto.MenuTagsForm; import com.weface.dto.MenuTagsForm;
import com.weface.entity.TUserTagEntity; import com.weface.entity.UserTagEntity;
import com.weface.service.TUserTagService; import com.weface.service.UserTagService;
import com.weface.common.utils.PageUtils; import com.weface.common.utils.PageUtils;
import com.weface.common.utils.Query; import com.weface.common.utils.Query;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
...@@ -15,71 +15,47 @@ import org.springframework.stereotype.Service; ...@@ -15,71 +15,47 @@ import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
/**
* @author Administrator
*/
@Service("tUserTagService") @Service("tUserTagService")
public class TUserTagServiceImpl extends ServiceImpl<TUserTagDao, TUserTagEntity> implements TUserTagService { public class UserTagServiceImpl extends ServiceImpl<UserTagDao, UserTagEntity> implements UserTagService {
@Override
public List<UserTagEntity> findUserByTodayAndIdBefore(Integer id) {
return this.baseMapper.findUserByTodayAndIdBefore(id);
}
/**
* 查询用户和标签信息
*
* @param params 查询参数
* @return 用户和标签数据分页
*/
@Override @Override
public PageUtils getUserAndTags(Map<String, Object> params) { public List<UserTagEntity> findUserByIdAfter(Integer id, Integer limit) {
IPage<Object> page = new Query<>().getPage(params); return this.baseMapper.findUserByIdAfter(id, limit);
String giUid = (String) params.get("giUid");
String tag = (String) params.get("tag");
IPage<TUserTagEntity> userAndTagsByUid = this.baseMapper.getUserAndTags(new Page<TUserTagEntity>(page.getCurrent(), page.getSize()), giUid, tag);
userAndTagsByUid.setTotal(userAndTagsByUid.getRecords().size());
return new PageUtils(userAndTagsByUid);
} }
/**
* 使用limit分页查询
*
* @param pageRecord 起始值
* @param limit 每次查询数量
* @return gid
*/
@Override @Override
public List<String> findGidByLimit(int pageRecord, int limit) { public List<UserTagEntity> findNoTagUser(Integer star, Integer end) {
return this.baseMapper.findGidByLimit(pageRecord, limit); return this.baseMapper.findNoTagUser(star, end);
} }
/**
* 查询当天修改的用户gid
*
* @return
*/
@Override @Override
public List<String> findTodayGid() { public PageUtils getUserAndTags(Map<String, Object> params) {
return this.baseMapper.findTodayGid(); IPage<Object> page = new Query<>().getPage(params);
String gid = (String) params.get("gid");
IPage<UserTagEntity> userAndTagsByUid = this.baseMapper.getUserAndTags(new Page<UserTagEntity>(page.getCurrent(), page.getSize()), gid);
userAndTagsByUid.setTotal(userAndTagsByUid.getRecords().size());
return new PageUtils(userAndTagsByUid);
} }
/**
* 根据标签查询用户gid
*
* @param tags 标签完全匹配
* @return gid
*/
@Override @Override
public List<String> getGidByTag(String[] tags) { public List<String> getGidByTag(String[] tags) {
return this.baseMapper.getGidByTag(Arrays.asList(tags)); return this.baseMapper.getGidByTag(Arrays.asList(tags));
} }
/**
* 根据gid查询用户标签
*
* @param userIdList gid
* @return 标签信息
*/
@Override @Override
public Map<String, Object> getTagByGid(String[] userIdList) { public Map<String, Object> getTagByGid(String gid) {
List<TUserTagEntity> userByUid = this.baseMapper.getTagByGid(Arrays.asList(userIdList)); List<UserTagEntity> userByUid = this.baseMapper.getTagByGid(gid);
List<Map<String, Object>> list = new ArrayList<>(userByUid.size()); List<Map<String, Object>> list = new ArrayList<>(userByUid.size());
for (TUserTagEntity tUserTagEntity : userByUid) { for (UserTagEntity tUserTagEntity : userByUid) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>(2);
List<MenuTagsForm> objects = new ArrayList<>(); List<MenuTagsForm> objects = new ArrayList<>();
tUserTagEntity.getList().forEach(item -> { tUserTagEntity.getList().forEach(item -> {
MenuTagsForm menuTagsForm = new MenuTagsForm(); MenuTagsForm menuTagsForm = new MenuTagsForm();
...@@ -97,8 +73,9 @@ public class TUserTagServiceImpl extends ServiceImpl<TUserTagDao, TUserTagEntity ...@@ -97,8 +73,9 @@ public class TUserTagServiceImpl extends ServiceImpl<TUserTagDao, TUserTagEntity
} }
@Override @Override
public List<TUserTagEntity> getAllImport() { public List<UserTagEntity> getAllImport() {
return this.baseMapper.selectAllUserForTags(); return this.baseMapper.selectAllUserForTags();
} }
} }
\ No newline at end of file
package com.weface.task; package com.weface.task;
import cn.hutool.core.collection.CollUtil;
import com.weface.common.utils.RedisUtil;
import com.weface.component.MenuService; import com.weface.component.MenuService;
import com.weface.entity.MenuTagsEntity;
import com.weface.entity.UserTagEntity;
import com.weface.entity.UserMenusEntity; import com.weface.entity.UserMenusEntity;
import com.weface.service.TUserTagService; import com.weface.service.MenuTagsService;
import com.weface.service.UserTagService;
import com.weface.service.UserMenusService; import com.weface.service.UserMenusService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.stream.Collectors;
import java.util.concurrent.Executors;
/** /**
* @author Administrator
* @CreateUser: Administrator * @CreateUser: Administrator
* @CreateTime: 2021/11/4 * @CreateTime: 2021/11/4
*/ */
...@@ -27,55 +35,138 @@ import java.util.concurrent.Executors; ...@@ -27,55 +35,138 @@ import java.util.concurrent.Executors;
@EnableScheduling @EnableScheduling
public class UserTagsTask { public class UserTagsTask {
@Value("${gexiang.user_tag_id}")
private String userTagId;
@Value("${gexiang.push_max_size}")
private String pushMaxSize;
@Autowired @Autowired
private MenuService menuService; private MenuService menuService;
@Autowired @Autowired
private TUserTagService tUserTagService; private UserTagService userTagService;
@Autowired @Autowired
private UserMenusService userMenusService; private UserMenusService userMenusService;
@Autowired
private MenuTagsService menuTagsService;
@Scheduled(cron = "0 0 0 1 * ?") @Autowired
private ThreadPoolTaskExecutor asyncServiceExecutor;
/**
* 更新用户标签
*/
@Scheduled(cron = "0 0 23 * * ?")
public void updateUserTags() { public void updateUserTags() {
try { try {
List<String> todayGid = tUserTagService.findTodayGid(); //获取每次处理的id起始值
int size = todayGid.size(); String userId = RedisUtil.StringOps.get("user_tag_id");
int limit = 1000; if (StringUtils.isBlank(userId)) {
userId = userTagId;
}
int id = Integer.parseInt(userId);
//获取每次处理最大数
String pushSize = RedisUtil.StringOps.get("push_max_size");
if (StringUtils.isBlank(pushSize)) {
RedisUtil.StringOps.set("push_max_size", pushMaxSize);
pushSize = pushMaxSize;
}
int max = Integer.parseInt(pushSize);
//存储用户标签信息
List<UserMenusEntity> userMenusList = new ArrayList<>(); List<UserMenusEntity> userMenusList = new ArrayList<>();
int totalPage = (size % limit == 0) ? (size / limit) : (size / limit + 1); //获取标签列表
CountDownLatch latch = new CountDownLatch(totalPage); List<MenuTagsEntity> tags = menuTagsService.list();
ExecutorService pool = Executors.newFixedThreadPool(totalPage);
//收集中间表数据
for (int i = 0; i < totalPage; i++) {
int finalI = i; //获取小于起始值,且更新时间为当前时间用户信息
Runnable runnable = () -> { List<UserTagEntity> beforeUser = userTagService.findUserByTodayAndIdBefore(id);
List<String> list = new ArrayList<>(); //过滤用户gid
if (finalI == totalPage - 1) { List<String> beforeGid = beforeUser.stream().map(UserTagEntity::getGid).distinct().collect(Collectors.toList());
list = todayGid.subList(finalI * limit, size);
} else { //获取更新总数量
list = todayGid.subList(finalI * limit, (finalI + 1) * limit); int size = beforeGid.size();
} //如果更新数量大于总量,截取每次处理总量的更新用户信息
if (CollectionUtils.isNotEmpty(list)) { if (size > max) {
String[] strings = list.toArray(new String[0]); beforeGid = beforeGid.subList(0, max - 1);
Map<String, Object> android = menuService.getUserTags(strings); } else {
List<UserMenusEntity> tagUser = menuService.getTagUser(android); //最大处理数减去当天更新处理数,得到剩余处理数,获取起始值后的新增的用户信息
if (CollectionUtils.isNotEmpty(tagUser)) { List<UserTagEntity> afterUser = userTagService.findUserByIdAfter(Integer.parseInt(userId), max - size);
userMenusList.addAll(tagUser); //如果当天新增数不为空
} if (CollUtil.isNotEmpty(afterUser)) {
//获取用户最后一条信息
UserTagEntity afterUserInfo = afterUser.get(afterUser.size() - 1);
//并覆盖起始值
RedisUtil.StringOps.set("user_tag_id", String.valueOf(afterUserInfo.getId()));
//过滤用户gid
List<String> afterGid = afterUser.stream().map(UserTagEntity::getGid).distinct().collect(Collectors.toList());
//调用个像接口获取新增用户标签
List<UserMenusEntity> afterTag = getUserTag(afterGid, afterUser, tags);
if (CollUtil.isNotEmpty(afterTag)) {
userMenusList.addAll(afterTag);
} }
latch.countDown(); }
}; }
pool.execute(runnable); //调用个像接口获取更新用户标签
List<UserMenusEntity> beforeTag = getUserTag(beforeGid, beforeUser, tags);
if (CollUtil.isNotEmpty(beforeTag)) {
userMenusList.addAll(beforeTag);
} }
latch.await(); //批量插入用户标签信息
userMenusService.batchInsert(userMenusList); userMenusService.batchInsert(userMenusList);
} catch (InterruptedException e) { log.error("执行结束{}", asyncServiceExecutor.getPoolSize());
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("执行定时更新标签任务失败!"); log.error("执行定时更新标签任务失败!");
} }
} }
// @Scheduled(cron = "* * * * * ?") /**
// public void updateUser() { * 获取个像用户标签信息
// System.out.println("你好" + System.currentTimeMillis()); *
// } * @param gid 用户gid
* @param userInfo 用户信息
* @param tag 标签信息
* @return 查询到的用户标签信息
* @throws InterruptedException 网络异常
*/
private List<UserMenusEntity> getUserTag(List<String> gid, List<UserTagEntity> userInfo, List<MenuTagsEntity> tag) throws InterruptedException {
//存储用户标签信息
List<UserMenusEntity> userTags = new ArrayList<>();
//获取用户gid总量
int size = gid.size();
//每个线程处理1000调数据
int limit = 200;
//获取总页数
int totalPage = (size % limit == 0) ? (size / limit) : (size / limit + 1);
CountDownLatch latch = new CountDownLatch(totalPage);
//创建线程
for (int i = 0; i < totalPage; i++) {
int finalI = i;
Runnable runnable = () -> {
//截取每次处理数据
List<String> list;
if (finalI == totalPage - 1) {
list = gid.subList(finalI * limit, size);
} else {
list = gid.subList(finalI * limit, (finalI + 1) * limit);
}
if (CollectionUtils.isNotEmpty(list)) {
//获取个像数据
Map<String, Object> android = menuService.getUserTags(list, tag);
if (android != null) {
//解析个像数据
List<UserMenusEntity> tagUser = menuService.getTagUser(android, userInfo);
userTags.addAll(tagUser);
}
}
latch.countDown();
};
asyncServiceExecutor.execute(runnable);
}
latch.await();
return userTags;
}
} }
spring: spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
druid: druid:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://172.16.10.33:3306/png?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai url: jdbc:mysql://172.16.10.33:3306/png?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root username: root
password: wefaceweface password: wefaceweface
initial-size: 10 initial-size: 10
max-active: 100 max-active: 100
min-idle: 10 min-idle: 10
max-wait: 60000 max-wait: 60000
pool-prepared-statements: true pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20 max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000 time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000 min-evictable-idle-time-millis: 300000
#Oracle需要打开注释 #Oracle需要打开注释
#validation-query: SELECT 1 FROM DUAL #validation-query: SELECT 1 FROM DUAL
test-while-idle: true test-while-idle: true
test-on-borrow: false test-on-borrow: false
test-on-return: false test-on-return: false
stat-view-servlet: stat-view-servlet:
enabled: true enabled: true
url-pattern: /druid/* url-pattern: /druid/*
#login-username: admin #login-username: admin
#login-password: admin #login-password: admin
filter: filter:
stat: stat:
log-slow-sql: false log-slow-sql: false
slow-sql-millis: 1000 slow-sql-millis: 1000
merge-sql: false merge-sql: false
wall: wall:
config: config:
multi-statement-allow: true multi-statement-allow: true
##多数据源的配置 ##多数据源的配置
......
spring: spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
druid: druid:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai url: jdbc:mysql://localhost:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: renren username: renren
password: 123456 password: 123456
initial-size: 10 initial-size: 10
max-active: 100 max-active: 100
min-idle: 10 min-idle: 10
max-wait: 60000 max-wait: 60000
pool-prepared-statements: true pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20 max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000 time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000 min-evictable-idle-time-millis: 300000
#Oracle需要打开注释 #Oracle需要打开注释
#validation-query: SELECT 1 FROM DUAL #validation-query: SELECT 1 FROM DUAL
test-while-idle: true test-while-idle: true
test-on-borrow: false test-on-borrow: false
test-on-return: false test-on-return: false
stat-view-servlet: stat-view-servlet:
enabled: true enabled: true
url-pattern: /druid/* url-pattern: /druid/*
#login-username: admin #login-username: admin
#login-password: admin #login-password: admin
filter: filter:
stat: stat:
log-slow-sql: true log-slow-sql: true
slow-sql-millis: 1000 slow-sql-millis: 1000
merge-sql: false merge-sql: false
wall: wall:
config: config:
multi-statement-allow: true multi-statement-allow: true
##多数据源的配置 ##多数据源的配置
......
...@@ -26,6 +26,14 @@ spring: ...@@ -26,6 +26,14 @@ spring:
enabled: true enabled: true
mvc: mvc:
throw-exception-if-no-handler-found: true throw-exception-if-no-handler-found: true
redis:
host: localhost
database: 0
port: 6379
maxTotal: 1000
maxIdle: 50
minIdle: 10
timeout: 1s
getui: getui:
apps: { apps: {
...@@ -43,7 +51,7 @@ mybatis-plus: ...@@ -43,7 +51,7 @@ mybatis-plus:
#数据库相关配置 #数据库相关配置
db-config: db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: AUTO id-type: INPUT
logic-delete-value: 0 logic-delete-value: 0
logic-not-delete-value: 1 logic-not-delete-value: 1
banner: false banner: false
...@@ -54,3 +62,6 @@ mybatis-plus: ...@@ -54,3 +62,6 @@ mybatis-plus:
call-setters-on-nulls: true call-setters-on-nulls: true
jdbc-type-for-null: 'null' jdbc-type-for-null: 'null'
gexiang:
user_tag_id: 400000
push_max_size: 30000
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
(#{item.id},#{item.userId},#{item.tagsId},#{item.isValid},#{item.createTime}) (#{item.id},#{item.userId},#{item.tagsId},#{item.isValid},#{item.createTime})
</foreach> </foreach>
</insert> </insert>
<!-- 根据uid查询标签id--> <!-- 根据uid查询标签id-->
<select id="findIdByUserId" resultType="long"> <select id="findIdByUserId" resultType="long">
SELECT id FROM tb_user_menus WHERE is_valid = 1 AND user_id IN SELECT id FROM tb_user_menus WHERE is_valid = 1 AND user_id IN
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weface.dao.TUserTagDao"> <mapper namespace="com.weface.dao.UserTagDao">
<!-- 可根据自己的需求,是否要使用 --> <!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.weface.entity.TUserTagEntity" id="tUserTagMap"> <resultMap type="com.weface.entity.UserTagEntity" id="userTagMap">
<result property="id" column="id"/> <result property="id" column="id"/>
<result property="uid" column="uid"/> <result property="uid" column="uid"/>
<result property="tel" column="tel"/> <result property="tel" column="tel"/>
<result property="gid" column="gid"/> <result property="gid" column="gid"/>
<result property="saveDate" column="save_date"/>
<collection property="list" ofType="com.weface.entity.MenuTagsEntity"> <collection property="list" ofType="com.weface.entity.MenuTagsEntity">
<id property="id" column="tagId"></id> <id property="id" column="tagId"></id>
<result property="levelFirst" column="level_first"></result> <result property="levelFirst" column="level_first"></result>
...@@ -19,20 +20,35 @@ ...@@ -19,20 +20,35 @@
<result property="weight" column="weight"></result> <result property="weight" column="weight"></result>
</collection> </collection>
</resultMap> </resultMap>
<!-- 使用limit分页查询-->
<select id="findGidByLimit" resultType="string"> <!-- 查询id之前且当天更新的用户 AND id &lt; #{id}-->
SELECT gid <select id="findUserByTodayAndIdBefore" resultMap="userTagMap">
SELECT uid, gid
FROM t_user_tag FROM t_user_tag
WHERE gid IS NOT NULL LIMIT #{pageRecord} WHERE gid IS NOT NULL
, #{limit} AND id &lt;= #{id}
AND TO_DAYS(save_date) = TO_DAYS(NOW())
ORDER BY save_date DESC
</select> </select>
<!-- 查询当天更新用户gid-->
<select id="findTodayGid" resultType="string"> <!-- 查询id之后的用户信息-->
SELECT DISTINCT gid <select id="findUserByIdAfter" resultMap="userTagMap">
SELECT id,uid, gid
FROM t_user_tag FROM t_user_tag
WHERE gid IS NOT NULL WHERE gid IS NOT NULL
AND TO_DAYS( save_date ) = TO_DAYS( NOW() ) AND id > #{id} LIMIT #{limit}
</select>
<!-- 查询无标签用户-->
<select id="findNoTagUser" resultMap="userTagMap">
SELECT uid, gid
FROM t_user_tag ut
LEFT JOIN tb_user_menus um ON ut.uid = um.user_id
WHERE um.user_id IS NULL
AND ut.gid IS NOT NULL
ORDER BY save_date LIMIT #{star}, #{end}
</select> </select>
<!-- 将公共片段抽取:只针对个别业务--> <!-- 将公共片段抽取:只针对个别业务-->
<sql id="common"> <sql id="common">
SELECT ut.uid, SELECT ut.uid,
...@@ -47,28 +63,18 @@ ...@@ -47,28 +63,18 @@
FROM t_user_tag ut FROM t_user_tag ut
LEFT JOIN tb_user_menus um ON ut.uid = um.user_id LEFT JOIN tb_user_menus um ON ut.uid = um.user_id
LEFT JOIN tb_menu_tags mt ON um.tags_id = mt.id LEFT JOIN tb_menu_tags mt ON um.tags_id = mt.id
WHERE mt.level_first = "Android" AND um.is_valid = 1 WHERE mt.level_first = "Android"
AND um.is_valid = 1
</sql> </sql>
<!-- 查询用户和标签信息-->
<select id="getUserAndTags" resultMap="tUserTagMap"> <!-- 查询用户信息根据gid-->
<select id="getUserAndTags" resultMap="userTagMap">
<include refid="common"/> <include refid="common"/>
<if test="giUid !=null and giUid != ''"> <if test="gid !=null and gid != ''">
AND ut.user_id LIKE CONCAT(CONCAT('%',#{giUid}),'%') AND ut.gid LIKE CONCAT(CONCAT('%',#{gid}),'%')
</if>
<if test="tag!=null and tag != ''">
AND ut.gid IN (
SELECT
ut.gid
FROM
t_user_tag ut
LEFT JOIN tb_user_menus um ON ut.uid = um.user_id
LEFT JOIN tb_menu_tags mt ON um.tags_id = mt.id
WHERE
mt.level_first = "Android"
AND mt.level_third LIKE CONCAT(CONCAT('%',#{tag}),'%')
)
</if> </if>
</select> </select>
<!-- 根据标签查询用户gid--> <!-- 根据标签查询用户gid-->
<select id="getGidByTag" resultType="string"> <select id="getGidByTag" resultType="string">
SELECT DISTINCT SELECT DISTINCT
...@@ -84,16 +90,15 @@ ...@@ -84,16 +90,15 @@
#{item} #{item}
</foreach> </foreach>
</select> </select>
<!-- 根据gid查询用户标签-->
<select id="getTagByGid" resultMap="tUserTagMap"> <!-- 根据gid查询用户标签-->
<select id="getTagByGid" resultMap="userTagMap">
<include refid="common"/> <include refid="common"/>
AND ut.gid IN AND ut.gid =#{gid}
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select> </select>
<!-- 查询所有用户标签管理数据-->
<select id="selectAllUserForTags" resultMap="tUserTagMap"> <!-- 查询所有用户标签管理数据-->
<select id="selectAllUserForTags" resultMap="userTagMap">
<include refid="common"/> <include refid="common"/>
</select> </select>
......
package com.weface; package com.weface;
import com.weface.component.GeTuiUtils;
import com.weface.component.MenuService; import com.weface.component.MenuService;
import com.weface.component.MessageTemplate;
import com.weface.entity.MenuTagsEntity;
import com.weface.entity.UserTagEntity;
import com.weface.entity.UserMenusEntity; import com.weface.entity.UserMenusEntity;
import com.weface.service.TUserTagService; import com.weface.service.MenuTagsService;
import com.weface.service.UserTagService;
import com.weface.service.UserMenusService; import com.weface.service.UserMenusService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -15,23 +21,37 @@ import java.util.Map; ...@@ -15,23 +21,37 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@SpringBootTest @SpringBootTest
class PushMessageApplicationTests { class PushMessageApplicationTests {
@Autowired @Autowired
private TUserTagService tUserTagService; private UserTagService userTagService;
@Autowired @Autowired
private MenuService menuService; private MenuService menuService;
@Autowired @Autowired
private UserMenusService userMenusService; private UserMenusService userMenusService;
@Autowired
private MenuTagsService menuTagsService;
@Test @Test
void contextLoads() { void contextLoads() {
} }
/**
* 根据时间同步标签
*/
@Test @Test
public void test(){ public void testKKSB() {
try { try {
List<String> todayGid = tUserTagService.findTodayGid(); //77164
//已处理0
//每次处理总条数 20000
int star = 10000;
int end = 30000;
List<MenuTagsEntity> tags = menuTagsService.list();
List<UserTagEntity> todayUser = userTagService.findNoTagUser(star, end);
List<String> todayGid = todayUser.stream().map(UserTagEntity::getGid).distinct().collect(Collectors.toList());
int size = todayGid.size(); int size = todayGid.size();
int limit = 1000; int limit = 1000;
List<UserMenusEntity> userMenusList = new ArrayList<>(); List<UserMenusEntity> userMenusList = new ArrayList<>();
...@@ -42,16 +62,15 @@ class PushMessageApplicationTests { ...@@ -42,16 +62,15 @@ class PushMessageApplicationTests {
for (int i = 0; i < totalPage; i++) { for (int i = 0; i < totalPage; i++) {
int finalI = i; int finalI = i;
Runnable runnable = () -> { Runnable runnable = () -> {
List<String> list = new ArrayList<>(); List<String> list;
if (finalI == totalPage - 1) { if (finalI == totalPage - 1) {
list = todayGid.subList(finalI * limit, size); list = todayGid.subList(finalI * limit, size);
} else { } else {
list = todayGid.subList(finalI * limit, (finalI + 1) * limit); list = todayGid.subList(finalI * limit, (finalI + 1) * limit);
} }
if (CollectionUtils.isNotEmpty(list)) { if (CollectionUtils.isNotEmpty(list)) {
String[] strings = list.toArray(new String[0]); Map<String, Object> android = menuService.getUserTags(list, tags);
Map<String, Object> android = menuService.getUserTags(strings); List<UserMenusEntity> tagUser = menuService.getTagUser(android, todayUser);
List<UserMenusEntity> tagUser = menuService.getTagUser(android);
if (CollectionUtils.isNotEmpty(tagUser)) { if (CollectionUtils.isNotEmpty(tagUser)) {
userMenusList.addAll(tagUser); userMenusList.addAll(tagUser);
} }
...@@ -62,9 +81,36 @@ class PushMessageApplicationTests { ...@@ -62,9 +81,36 @@ class PushMessageApplicationTests {
} }
latch.await(); latch.await();
userMenusService.batchInsert(userMenusList); userMenusService.batchInsert(userMenusList);
} catch (InterruptedException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@Test
void testConventTemplate() {
// String[] alias = {"kksh_10255318"};
// String[] alias = {"kksh_10131492"};
String[] alias = {"kksh_59354"};
String token = GeTuiUtils.getAuthToken("kk_sh_token_ge_tui");
MessageTemplate messageTemplate = new MessageTemplate();
MessageTemplate.Settings settings = new MessageTemplate.Settings();
settings.setTtl(3600000);
messageTemplate.setSettings(settings);
MessageTemplate.PushMessage pushMessage = new MessageTemplate.PushMessage();
MessageTemplate.PushMessage.Notification notification = new MessageTemplate.PushMessage.Notification();
notification.setTitle("看看生活提醒");
notification.setBody("看看生活->让领钱更简单");
notification.setClick_type("url");
notification.setUrl("https://www.baidu.com/");
notification.setChannel_level(4);
pushMessage.setNotification(notification);
messageTemplate.setPush_message(pushMessage);
String s = GeTuiUtils.singlePushAlias(alias, messageTemplate, token);
System.out.println(s);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment