Commit eb1e12b4 authored by zuoadmin's avatar zuoadmin

Merge branch 'dev' into 'master'

Dev

See merge request !2
parents 03d0ab85 17fae33d
......@@ -48,6 +48,10 @@
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
......
......@@ -4,6 +4,9 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author Administrator
*/
@SpringBootApplication
@EnableAsync
public class PushMessageApplication {
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.exception;
/**
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package com.weface.common.exception;
import com.weface.common.utils.Model;
......
......@@ -68,7 +68,7 @@ public class Base64Util {
}
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuffer = new StringBuilder();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
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;
/**
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils;
/**
......@@ -40,7 +32,6 @@ public class Constant {
* 菜单类型
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2016年11月15日 下午1:24:29
*/
public enum MenuType {
......@@ -72,7 +63,6 @@ public class Constant {
* 定时任务状态
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2016年12月3日 上午12:07:22
*/
public enum ScheduleStatus {
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils;
import org.apache.commons.lang.StringUtils;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils;
import org.springframework.web.context.request.RequestContextHolder;
......@@ -13,6 +5,9 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @author Administrator
*/
public class HttpContextUtils {
public static HttpServletRequest getHttpServletRequest() {
......
......@@ -4,14 +4,13 @@ package com.weface.common.utils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
* http 工具类
......@@ -63,70 +62,14 @@ public class HttpUtil {
// 建立实际的连接
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));
String result = "";
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 = "";
StringBuilder result = new StringBuilder();
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
result.append(getLine);
}
in.close();
log.info("result:" + result);
return result;
return result.toString();
}
public static boolean isJson2(String str) {
......@@ -136,38 +79,7 @@ public class HttpUtil {
flag = true;
} catch (Exception e) {
e.printStackTrace();
flag = false;
}
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;
import com.alibaba.druid.util.StringUtils;
......@@ -24,7 +16,7 @@ public class IPUtils {
/**
* 获取IP地址
*
* <p>
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
......@@ -51,12 +43,12 @@ public class IPUtils {
logger.error("IPUtils ERROR ", e);
}
// //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(","));
// }
// }
//使用代理,则获取第一个IP地址
/*if (StringUtils.isEmpty(ip) && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}*/
return ip;
}
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils;
import java.util.HashMap;
......
......@@ -8,7 +8,6 @@ import java.util.Map;
/**
* @author Aleyn
* @description Model
* @since 2021/11/10 16:34
*/
@Getter
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
......
......@@ -15,8 +15,13 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Administrator
*/
public class PicUtils {
//以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值
/**
* 以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值
*/
private static final Logger logger = LoggerFactory.getLogger(PicUtils.class);
private static final Integer ZERO = 0;
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;
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;
import org.springframework.beans.BeansException;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss;
import org.apache.commons.lang.StringUtils;
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss;
import javax.servlet.*;
......@@ -23,6 +15,7 @@ public class XssFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.common.xss;
import org.apache.commons.io.IOUtils;
......
package com.weface.component;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.bean.BeanUtil;
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.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.weface.common.exception.RRException;
import com.weface.common.utils.Base64Util;
import com.weface.common.utils.HttpUtil;
import com.weface.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @CreateUser: Administrator
* @author Administrator
* @CreateTime: 2021/11/2
*/
@Slf4j
public class GeTuiUtils {
//请求前缀
public static final String GETUIBASEURL = "https://restapi.getui.com/v2/";
public static final String APPID = "CYol79N33N71BV6dcjrqj3";
public static final String KK_SH_APP_ID = "CYol79N33N71BV6dcjrqj3";
public static final String KK_SH_MASTER_SECRET = "mekLZ4frLu7RHtKsN9mQn";
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 ENCODING = "UTF-8";
public static final String CONTENTTYPE = "application/json;charset=utf-8";
public static final String APPKEY = "rdLx5zumRK7oEme8MheAh8";
public static final String MASTERSECRET = "mekLZ4frLu7RHtKsN9mQn";
public static final String CONTENT_TYPE = "application/json;charset=utf-8";
/**
* 设置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
*
* @return JSONObject
*/
public static String getAuth() {
// 获取token地址
log.info("开始获取个像token");
String getAccessTokenUrl = BASEURL + APPID + "/auth_sign";
Long timestamp = System.currentTimeMillis();
private static String getAuth(String appId, String appKey, String masterSecret) {
try {
Map<String, Object> map = new HashMap<>();
map.put("sign", Base64Util.getSign(APPKEY, timestamp, MASTERSECRET));
map.put("timestamp", timestamp);
String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENTTYPE, JSONObject.toJSONString(map), ENCODING);
if (HttpUtil.isJson2(result)) {
String getAccessTokenUrl = BASEURL + appId + "/auth_sign";
Long timestamp = System.currentTimeMillis();
JSONObject json = new JSONObject();
json.put("sign", DigestUtils.sha256Hex(String.format("%s%d%s", appKey, timestamp, masterSecret)));
json.put("timestamp", timestamp);
HttpRequest post = HttpRequest.post(getAccessTokenUrl);
String result = post.body(json.toString()).execute().body();
JSONObject jsonObject = JSONObject.parseObject(result);
if ("true".equals(jsonObject.getString("result"))) {
Console.log(jsonObject);
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) {
e.printStackTrace();
......@@ -64,21 +145,21 @@ public class GeTuiUtils {
*
* @return JSONObject
*/
public static JSONObject getGeTuiAuth() {
public static String getGeTuiAuth(String appId, String appKey, String masterSecret) {
try {
// 获取token地址
log.info("开始获取个推token");
String getAccessTokenUrl = GETUIBASEURL + APPID + "/auth";
String getAccessTokenUrl = GE_TUI_BASE_URL + appId + "/auth";
Long timestamp = System.currentTimeMillis();
try {
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("appkey", APPKEY);
String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENTTYPE, JSONObject.toJSONString(map), ENCODING);
map.put("appkey", appKey);
String result = HttpUtil.postGeneralUrl(getAccessTokenUrl, CONTENT_TYPE, JSONObject.toJSONString(map), ENCODING);
if (HttpUtil.isJson2(result)) {
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.containsKey("code") && jsonObject.getInteger("code") == 0) {
return jsonObject.getJSONObject("data");
return jsonObject.getJSONObject("data").getString("token");
}
}
} catch (Exception e) {
......@@ -88,71 +169,167 @@ public class GeTuiUtils {
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
*
* @param userIdList
* @param token
* @return
* @throws Exception
* @param gidList 用户gid
* @param token 鉴权
* @return 执行结果
* @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
String getUsersCidUrl = "https://openapi-gi.getui.com/v3/" + APPID + "/query_tag";
String getUsersCidUrl = "https://openapi-gi.getui.com/v3/" + appId + "/query_tag";
//将token以及用户ID封装调用画像查询接口
Map<String, Object> map = new HashMap<>();
map.put("userIdList", userIdList);
Map<String, Object> map = new HashMap<>(2);
map.put("userIdList", gidList);
map.put("token", token);
//发送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 messageTemplate 消息模板
* @param token token
* @param token 接口访问凭据
* @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);
//请求url
String url = GETUIBASEURL + APPID + "/push/single/alias";
HttpRequest request = cn.hutool.http.HttpUtil.createPost(url);
request.header("token", token);
request.body(JSONUtil.toJsonStr(map));
String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/single/alias";
log.info("执行别名单推");
return request.execute().body();
return generalPost(url, token, map);
}
/**
* 创建消息拿到任务id
*
* @param messageTemplate 消息模板
* @param token token
* @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);
//请求url
String url = GETUIBASEURL + APPID + "/push/list/message";
//创建post请求
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();
String url = GE_TUI_BASE_URL + KK_SH_APP_ID + "/push/list/message";
String body = generalPost(url, token, map);
JSONObject jsonObject = JSONObject.parseObject(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
*
......@@ -161,65 +338,145 @@ public class GeTuiUtils {
* @return map对象
*/
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<>();
//request_id 唯一不重复
map.put("request_id", System.currentTimeMillis() + RandomUtil.randomString(15));
//任务组名
String group_name = messageTemplate.getGroup_name();
if (StringUtils.isNotBlank(group_name)) {
map.put("group_name", group_name);
}
Map<String, Object> audienceMap = new HashMap<>();
audienceMap.put("alias", alias);
map.put("audience", audienceMap);
//消息离线时间设置,单位毫秒,-1表示不设离线,-1 ~ 3 * 24 * 3600 * 1000(3天)之间
Long ttl = messageTemplate.getTtl();
if (ttl != null) {
Map<String, Object> settingsMap = new HashMap<>();
settingsMap.put("ttl", ttl);
map.put("settings", settingsMap);
}
//消息模板
Map<String, Object> pushMessageMap = new HashMap<>();
Map<String, Object> notificationMap = new HashMap<>();
notificationMap.put("title", messageTemplate.getTitle());
notificationMap.put("body", messageTemplate.getBody());
notificationMap.put("click_type", messageTemplate.getClick_type());
switch (messageTemplate.getClick_type()) {
case "intent":
notificationMap.put("intent", messageTemplate.getIntent());
case "url":
notificationMap.put("url", messageTemplate.getUrl());
}
pushMessageMap.put("notification", notificationMap);
map.put("push_message", pushMessageMap);
map.put("request_id", String.valueOf(IdUtil.getSnowflake(1, 1).nextId()));
//设置任务组名
if (StringUtils.isNotBlank(messageTemplate.getGroup_name())) {
map.put("group_name", messageTemplate.getGroup_name());
}
//推送条件设置
MessageTemplate.Settings settings = messageTemplate.getSettings();
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);
}
//推送目标用户该接口audience 对应值为all,表示推送所有用户
if (alias == null || alias.length == 0) {
map.put("audience", "all");
} else {
Map<String, Object> audience = BeanUtil.beanToMap(messageTemplate.getAudience(), false, true);
map.put("audience", audience);
}
//获取推送消息转为map 不转为下划线,忽略空值
MessageTemplate.PushMessage push_message = messageTemplate.getPush_message();
Map<String, Object> push_messages = BeanUtil.beanToMap(push_message, false, true);
//转换消息忽略空值
MessageTemplate.PushMessage.Notification notification = push_message.getNotification();
if (notification != null) {
//设置消息
Map<String, Object> notifications = BeanUtil.beanToMap(notification, false, true);
push_messages.put("notification", notifications);
}
MessageTemplate.PushMessage.Revoke revoke = push_message.getRevoke();
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;
}
/**
* 执行别名批量推送
* 设置推送渠道
*
* @param map body参数
* @param token token
* @return 执行结果
* @param notification 消息
* @return json
*/
public static String listPushByAlias(Map<String, Object> map, String token) {
//请求url
String url = GETUIBASEURL + APPID + "/push/list/alias";
//创建post请求
HttpRequest request = cn.hutool.http.HttpUtil.createPost(url);
public static cn.hutool.json.JSONObject setChannel(MessageTemplate.PushMessage.Notification notification) {
Map<String, Object> channel = new HashMap<>();
//获取ios配置
channel.put("ios", getIosChannel(notification));
//获取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
request.header("token", token);
//设置请求体数据
request.body(JSONUtil.toJsonStr(map));
//执行请求
log.info("执行别名批量推送");
return request.execute().body();
post.header("token", token);
post.header("Content-Type", CONTENT_TYPE);
return post.body(JSONUtil.toJsonStr(map)).execute().body();
}
}
package com.weface.component;
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.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.weface.entity.MenuTagsEntity;
import com.weface.entity.TUserTagEntity;
import com.weface.entity.UserTagEntity;
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 org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* @CreateUser: Administrator
* @author Administrator
* @CreateTime: 2021/11/2
*/
@Slf4j
@Component
@Transactional
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并缓存一份
*
* @return 从缓存中拿token
*/
public String getAuthToken() {
String authToken = "";
lock.lock();
try {
authToken = Convert.toStr(CACHE.getCacheData("authToken"));
if (Objects.isNull(authToken)) {
authToken = GeTuiUtils.getAuth();
// authToken = "01718df19708866512701e7637fee9568a0dac5f9390609f08ef148cab56c060";
if (ObjectUtil.isNull(authToken)) throw new RRException("获取个推token失败");
CACHE.addCacheData("authToken", authToken);
}
} catch (RRException e) {
e.printStackTrace();
log.error("加锁失败!");
} finally {
lock.unlock();
}
return authToken;
}
/**
* 通过gid以及操作系统字段获取标签code并转为实际值,后存库并返回
*
* @param userList 用户的giUid
* @return
*/
public Map<String, Object> getUserTags(String[] userList) {
try {
if (ArrayUtil.isEmpty(userList)) return null;
//根据用户giuId请求到用户最新的爱好数据
Map<String, Object> map = queryTag(userList);
//以上均做过非空处理如果返回不为空 那么map内一定是有数据的
if (map == null) return null;
return map;
} catch (Exception e) {
e.printStackTrace();
log.error("执行新增用户标签数据到用户表中发生异常" + e.getMessage());
}
return null;
}
/**
* 从map中解析标签并收集关系表数据
......@@ -95,36 +32,33 @@ public class MenuService {
* @param map 个推返回数据
* @return 标签数据
*/
public List<UserMenusEntity> getTagUser(Map<String, Object> map) {
if (ObjectUtil.isNull(map)) return null;
public List<UserMenusEntity> getTagUser(Map<String, Object> map, List<UserTagEntity> userInfo) {
try {
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
//获取所有用户标签
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>>() {
List<Long> list = Convert.convert(new TypeReference<List<Long>>() {
}, item.get("tags"));
//查找当前用户的id
Optional<TUserTagEntity> first = tUserTagEntities.stream().filter(x -> userId.equals(x.getGid())).findFirst();
Optional<UserTagEntity> first = userInfo.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) {
for (Long aLong : list) {
//填充数据
UserMenusEntity userMenusEntity = new UserMenusEntity();
userMenusEntity.setId(snowflake.nextId());
userMenusEntity.setUserId(uid);
userMenusEntity.setTagsId(aLong);
userMenusEntity.setIsValid(1);
......@@ -135,40 +69,36 @@ public class MenuService {
}
}
return userMenusList;
} catch (ConvertException e) {
e.printStackTrace();
log.error("转换用户标签失败{}", e.getMessage());
}
return null;
}
/**
* 通过用户id获取获取用户标签信息
* 通过gid以及操作系统字段获取标签code并转为实际值,后存库并返回
*
* @param userIdList gid
* @return
* @param gidList 用户的giUid
* @param tags 标签信息
* @return 走個推查詢數據
*/
private Map<String, Object> queryTag(String[] userIdList) {
//设置标识
boolean flag = true;
public Map<String, Object> getUserTags(List<String> gidList, List<MenuTagsEntity> tags) {
//获取token
String authToken = getAuthToken();
String kk_sh_token = "kk_sh_token";
try {
while (flag) {
String authToken = GeTuiUtils.getAuthToken(kk_sh_token);
System.out.println("===============" + authToken);
//将token以及用户ID封装调用画像查询接口
String result = GeTuiUtils.queryTag(userIdList, authToken);
String result = GeTuiUtils.queryTagKKSH(gidList, authToken);
JSONObject jsonObject = JSONObject.parseObject(result);
//如果状态码为302token已过期则需要重新获取token并更新数据库token
if (jsonObject.containsKey("error_info") && jsonObject.getJSONObject("error_info").getInteger("error_code") == 302) {
log.warn("token过期");
//authToken = "01718df19708866512701e7637fee9568a0dac5f9390609f08ef148cab56c060";
authToken = GeTuiUtils.getAuth();
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);
List<Map<String, Object>> userTags = getUserTagByTag(userTag, 1, tags);
Map<String, Object> all = null;
if (userTags != null && userTag.size() > 0) {
all = new HashMap<>();
all = new HashMap<>(2);
//将数据封装并转为json格式返回
all.put("userTag", userTags);
all.put("error_code", 0);
......@@ -177,8 +107,6 @@ public class MenuService {
//如果以上步骤无法走通则直接返回。并修改标识符终止循环
} else {
log.error("返回值内不包含需要解析的数据" + jsonObject.toJSONString());
flag = false;
}
}
} catch (Exception e) {
e.printStackTrace();
......@@ -187,50 +115,86 @@ public class MenuService {
return null;
}
/**
* 获取看看社保用户标签
*
* @param gidList 用户gid
* @return 用户标签信息
* @throws Exception 异常
*/
private List<Map<String, Object>> getSBTags(List<String> gidList, List<MenuTagsEntity> tags) throws Exception {
String kk_sb_token = "kk_sb_token";
//获取token
String authToken = GeTuiUtils.getAuthToken(kk_sb_token);
//将token以及用户ID封装调用画像查询接口
String result = GeTuiUtils.queryTagKKSB(gidList, authToken);
JSONObject jsonObject = JSONObject.parseObject(result);
//判断返回json内是否包含要解析的userTag
if (jsonObject.containsKey("userTag")) {
JSONArray userTag = jsonObject.getJSONArray("userTag");
return getUserTagByTag(userTag, 2, tags);
//如果以上步骤无法走通则直接返回。并修改标识符终止循环
} else {
log.error("返回值内不包含需要解析的数据" + jsonObject.toJSONString());
}
return null;
}
/**
* 解析json拿到所有用户
*
* @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;
Integer failCount = Convert.toInt(CACHE.getCacheData("failCount"));
Integer successCount = Convert.toInt(CACHE.getCacheData("successCount"));
if (ObjectUtil.isNull(failCount))
failCount = 0;
if (ObjectUtil.isNull(successCount))
successCount = 0;
//查询用户画像失败的gid用户
List<String> gidList = new ArrayList<>();
//解析用户标签
if (userTag != null && userTag.size() > 0) {
//封装返回的数据userTags
//初始化
userTags = new ArrayList<>(userTag.size());
for (Object o : userTag) {
JSONObject jsonObject1 = JSONObject.parseObject(o.toString());
//判断返回json内是否包含要解析的error_code,并判断返回的json状态码是否正常
if (jsonObject1.containsKey("error_code") && jsonObject1.getInteger("error_code") == 0) {
String userId = "";
if (jsonObject1.containsKey("userId"))
if (jsonObject1.containsKey("userId")) {
userId = jsonObject1.getString("userId");
}
//如果从json中获取的当前giUid为空,则跳出本次循环
if (StringUtils.isBlank(userId)) continue;
if (StringUtils.isBlank(userId)) {
continue;
}
//判断返回json内是否包含要解析的error_code,并判断返回的json状态码是否正常
Integer errorCode = jsonObject1.getInteger("error_code");
if (errorCode == 0) {
//封装当前用户的所有tags信息
Map<String, Object> data = new HashMap<>(2);
//封装要返回的所有tags
List<MenuTagsEntity> list = getMenuByTag(jsonObject1.getJSONArray("tags"));
List<Long> list = getMenuByTag(jsonObject1.getJSONArray("tags"), tags);
//根据giUid查询的标签如果为空则跳出本次循环
if (list != null && list.size() > 0) {
data.put("userId", userId);
data.put("tags", list);
userTags.add(data);
}
successCount++;
} else {
failCount++;
} else if (errorCode == 109) {
if (type == 1) {
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;
}
......@@ -239,27 +203,31 @@ public class MenuService {
* 根据标签的code查询标签数据
*
* @param tags 标签
* @return
* @return 標簽數據
*/
private List<MenuTagsEntity> getMenuByTag(JSONArray tags) {
List<MenuTagsEntity> list = null;
private List<Long> getMenuByTag(JSONArray tags, List<MenuTagsEntity> menus) {
List<Long> list = null;
if (tags != null && tags.size() > 0) {
list = new ArrayList<>(tags.size());
for (Object tag : tags) {
JSONObject jsonObject2 = JSONObject.parseObject(tag.toString());
String code = "";
if (jsonObject2.containsKey("code"))
if (jsonObject2.containsKey("code")) {
code = jsonObject2.getString("code");
if (code.startsWith("c") || code.startsWith("C")) {
code = code.replaceFirst("c", "");
}
}
//如果传入标签的code为空则跳出本次循环
if (StringUtils.isBlank(code)) continue;
String weight = "";
if (jsonObject2.containsKey("weight"))
weight = jsonObject2.getString("weight");
if (StringUtils.isBlank(code)) {
continue;
}
//根据code或权重查询图像
MenuTagsEntity one = menuTagsService.getOneByCodeOrWeight(code, weight);
//如果查询的结果为空则跳出本次循环
if (one == null) continue;
list.add(one);
String finalCode = code;
Optional<MenuTagsEntity> first = menus.stream().filter(x -> finalCode.equals(x.getCode())).findFirst();
if (first.isPresent()) {
list.add(first.get().getId());
}
}
}
return list;
......
......@@ -4,48 +4,165 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @CreateUser: Administrator
* @author Administrator
* @CreateTime: 2021/11/23
*/
@Data
@NoArgsConstructor
@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;
/**
* 消息离线时间设置,单位毫秒,-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;
/**
* 点击通知后续动作,
* 目前支持以下后续动作,
* intent:打开应用内特定页面,
* url:打开网页地址,
* payload:自定义消息内容启动应用,
* payload_custom:自定义消息内容不启动应用,
* startapp:打开应用首页,
* none:纯通知,无后续动作
* 厂商推送消息参数,包含ios消息参数,android厂商消息参数
*/
private String click_type;
private PushChannel push_channel;
/**
* 推送目标用户该接口audience 对应值为all,表示推送所有用户
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Audience implements Serializable {
private static final long serialVersionUID = 1L;
//别名数组,只能填一个别名
private String[] alias;
}
/**
* click_type为url时必填 无 点击通知打开链接
* 推送条件设置
*/
@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;
}
/**
* click_type为intent时必填 无 点击通知打开应用特定页面,长度 ≤ 4096;
* 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;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author Administrator
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
......
......@@ -9,6 +9,9 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author Administrator
*/
@EnableAsync
@Configuration
public class ExecutorConfig {
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.config;
import com.weface.common.xss.XssFilter;
......
......@@ -6,7 +6,7 @@ import org.apache.ibatis.reflection.MetaObject;
import java.util.Date;
/**
* @CreateUser: Administrator
* @author Administrator
* @CreateTime: 2021/11/16
* 自动填充属性
*/
......
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
* https://www.renren.io
*
* 版权所有,侵权必究!
*/
package com.weface.config;
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Map;
......@@ -19,7 +20,6 @@ import java.util.Map;
* 所有标签等级划分
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@RestController
......@@ -41,12 +41,10 @@ public class MenuTagsController {
/**
* 根据用户giUid先调个推拿到code后走数据库拿到数据并更新相关数据后返回
*
* @return
*/
@PostMapping("/queryTagByGiUid")
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);
}
......
......@@ -10,6 +10,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Administrator
*/
@RestController
@RequestMapping("push")
public class PushController {
......@@ -23,7 +26,7 @@ public class PushController {
}
@PostMapping("single")
public CommonResult pushSingle(@RequestBody MsgDTO param){
public CommonResult pushSingle(@RequestBody MsgDTO param) {
return pushService.pushSingle(param);
}
}
......@@ -3,7 +3,8 @@ package com.weface.controller;
import com.weface.common.utils.Model;
import com.weface.common.utils.PageUtils;
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.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -16,14 +17,13 @@ import java.util.Map;
/**
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@RestController
@RequestMapping("/tags/userTags")
public class UserTagsController {
@Autowired
private TUserTagService tUserTagService;
private UserTagService tUserTagService;
/**
* 查询所有用户对应标签信息
......@@ -48,9 +48,11 @@ public class UserTagsController {
*/
@PostMapping("/queryByGid")
public Model queryByGid(@RequestBody UserTagFrom userTagFrom) {
// String[] userIdList = new String[]{"3917d1037675078ae3a1abb4c6da3ef6", "1231313123"};
// String os = "Android";
Map<String, Object> data = tUserTagService.getTagByGid(userTagFrom.getGiUidList());
String gid = userTagFrom.getGiUidList()[0];
if (StringUtils.isBlank(gid)) {
return Model.error("gid不能为空");
}
Map<String, Object> data = tUserTagService.getTagByGid(gid);
return Model.ok(data);
}
......
......@@ -8,7 +8,6 @@ import org.apache.ibatis.annotations.Mapper;
* 所有标签等级划分
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@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;
* 用户和标签中间表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@Mapper
public interface UserMenusDao extends BaseMapper<UserMenusEntity> {
//批量插入
/**
* 批量插入
*
* @param list 插入数据
* @return 成功条数
*/
int batchInsert(List<UserMenusEntity> list);
//根据uid查询标签id
/**
* 根据uid查询标签id
*
* @param list gid
* @return 标签id
*/
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;
import lombok.Data;
import java.io.Serializable;
/**
* @CreateUser: Administrator
* @author Administrator
* @CreateTime: 2021/11/17
*/
@Data
public class UserTagFrom {
public class UserTagFrom implements Serializable {
private static final long serialVersionUID = 1L;
private String[] giUidList;
......
......@@ -12,7 +12,6 @@ import java.util.Date;
* 所有标签等级划分
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@Data
......
......@@ -10,7 +10,6 @@ import java.util.Date;
* 用户和标签中间表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
@Data
......@@ -31,9 +30,6 @@ public class UserMenusEntity implements Serializable {
* 标签ID
*/
private Long tagsId;
/**
* 是否删除 1 未删除 0 删除
*/
/**
* 是否有效 1:有效 0 无效
*/
......
......@@ -16,13 +16,12 @@ import java.util.List;
* 用户ID标签关联表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-30 18:57:06
*/
@ExcelTarget("tUserTagEntity")
@Data
@TableName("t_user_tag")
public class TUserTagEntity implements Serializable {
public class UserTagEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
......@@ -51,12 +50,6 @@ public class TUserTagEntity implements Serializable {
/**
* 标签数据
*/
// @ExcelCollection(name = "标签列表",orderNum = "3")
// @TableField(exist = false)
// private List<MenuTagsEntity> list;
/**
* 标签数据
*/
@ExcelEntity(name = "标签列表",id = "id")
@TableField(exist = false)
private List<MenuTagsEntity> list;
......
......@@ -10,15 +10,25 @@ import java.util.Map;
* 所有标签等级划分
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
public interface MenuTagsService extends IService<MenuTagsEntity> {
//列表
/**
* 列表
*
* @param params 参数
* @return 标签分页
*/
PageUtils queryPage(Map<String, Object> params);
//根据code和权重查询标签
/**
* 根据code和权重查询标签
*
* @param code 编码
* @param weight 权重
* @return 标签信息
*/
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;
* 用户和标签中间表
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2021-11-18 16:20:52
*/
public interface UserMenusService extends IService<UserMenusEntity> {
//批量插入
/**
* 批量插入
*
* @param 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;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @author Administrator
*/
@Service("menuTagsService")
public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity> implements MenuTagsService {
......@@ -42,10 +46,14 @@ public class MenuTagsServiceImpl extends ServiceImpl<MenuTagsDao, MenuTagsEntity
*/
@Override
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)
.eq(MenuTagsEntity::getLevelFirst, "Android")
.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;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weface.dao.UserMenusDao;
import com.weface.entity.UserMenusEntity;
......@@ -30,9 +29,6 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt
//批量插入前全删
List<Long> ids = this.baseMapper.findIdByUserId(deleteUid);
this.removeByIds(ids);
// this.remove(new QueryWrapper<UserMenusEntity>().lambda()
// .eq(UserMenusEntity::getIsValid, 1)
// .in(UserMenusEntity::getUserId, deleteUid));
//获取集合长度
int count = userMenusList.size();
//每次批量插入个数
......@@ -59,6 +55,12 @@ public class UserMenusServiceImpl extends ServiceImpl<UserMenusDao, UserMenusEnt
}
}
/**
* 查询删除的uid
*
* @param userMenusList 用户标签信息
* @return 提取用户uid
*/
private List<String> getDeleteUid(List<UserMenusEntity> userMenusList) {
return userMenusList.stream().map(UserMenusEntity::getUserId).distinct().collect(Collectors.toList());
}
......
......@@ -3,10 +3,10 @@ package com.weface.serviceimpl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.entity.TUserTagEntity;
import com.weface.service.TUserTagService;
import com.weface.entity.UserTagEntity;
import com.weface.service.UserTagService;
import com.weface.common.utils.PageUtils;
import com.weface.common.utils.Query;
import org.springframework.beans.BeanUtils;
......@@ -15,71 +15,47 @@ import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author Administrator
*/
@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
public PageUtils getUserAndTags(Map<String, Object> params) {
IPage<Object> page = new Query<>().getPage(params);
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);
public List<UserTagEntity> findUserByIdAfter(Integer id, Integer limit) {
return this.baseMapper.findUserByIdAfter(id, limit);
}
/**
* 使用limit分页查询
*
* @param pageRecord 起始值
* @param limit 每次查询数量
* @return gid
*/
@Override
public List<String> findGidByLimit(int pageRecord, int limit) {
return this.baseMapper.findGidByLimit(pageRecord, limit);
public List<UserTagEntity> findNoTagUser(Integer star, Integer end) {
return this.baseMapper.findNoTagUser(star, end);
}
/**
* 查询当天修改的用户gid
*
* @return
*/
@Override
public List<String> findTodayGid() {
return this.baseMapper.findTodayGid();
public PageUtils getUserAndTags(Map<String, Object> params) {
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
public List<String> getGidByTag(String[] tags) {
return this.baseMapper.getGidByTag(Arrays.asList(tags));
}
/**
* 根据gid查询用户标签
*
* @param userIdList gid
* @return 标签信息
*/
@Override
public Map<String, Object> getTagByGid(String[] userIdList) {
List<TUserTagEntity> userByUid = this.baseMapper.getTagByGid(Arrays.asList(userIdList));
public Map<String, Object> getTagByGid(String gid) {
List<UserTagEntity> userByUid = this.baseMapper.getTagByGid(gid);
List<Map<String, Object>> list = new ArrayList<>(userByUid.size());
for (TUserTagEntity tUserTagEntity : userByUid) {
Map<String, Object> map = new HashMap<>();
for (UserTagEntity tUserTagEntity : userByUid) {
Map<String, Object> map = new HashMap<>(2);
List<MenuTagsForm> objects = new ArrayList<>();
tUserTagEntity.getList().forEach(item -> {
MenuTagsForm menuTagsForm = new MenuTagsForm();
......@@ -97,8 +73,9 @@ public class TUserTagServiceImpl extends ServiceImpl<TUserTagDao, TUserTagEntity
}
@Override
public List<TUserTagEntity> getAllImport() {
public List<UserTagEntity> getAllImport() {
return this.baseMapper.selectAllUserForTags();
}
}
\ No newline at end of file
package com.weface.task;
import cn.hutool.core.collection.CollUtil;
import com.weface.common.utils.RedisUtil;
import com.weface.component.MenuService;
import com.weface.entity.MenuTagsEntity;
import com.weface.entity.UserTagEntity;
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 lombok.extern.slf4j.Slf4j;
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.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
/**
* @author Administrator
* @CreateUser: Administrator
* @CreateTime: 2021/11/4
*/
......@@ -27,55 +35,138 @@ import java.util.concurrent.Executors;
@EnableScheduling
public class UserTagsTask {
@Value("${gexiang.user_tag_id}")
private String userTagId;
@Value("${gexiang.push_max_size}")
private String pushMaxSize;
@Autowired
private MenuService menuService;
@Autowired
private TUserTagService tUserTagService;
private UserTagService userTagService;
@Autowired
private UserMenusService userMenusService;
@Autowired
private MenuTagsService menuTagsService;
@Autowired
private ThreadPoolTaskExecutor asyncServiceExecutor;
@Scheduled(cron = "0 0 0 1 * ?")
/**
* 更新用户标签
*/
@Scheduled(cron = "0 0 23 * * ?")
public void updateUserTags() {
try {
List<String> todayGid = tUserTagService.findTodayGid();
int size = todayGid.size();
int limit = 1000;
//获取每次处理的id起始值
String userId = RedisUtil.StringOps.get("user_tag_id");
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<MenuTagsEntity> tags = menuTagsService.list();
//获取小于起始值,且更新时间为当前时间用户信息
List<UserTagEntity> beforeUser = userTagService.findUserByTodayAndIdBefore(id);
//过滤用户gid
List<String> beforeGid = beforeUser.stream().map(UserTagEntity::getGid).distinct().collect(Collectors.toList());
//获取更新总数量
int size = beforeGid.size();
//如果更新数量大于总量,截取每次处理总量的更新用户信息
if (size > max) {
beforeGid = beforeGid.subList(0, max - 1);
} else {
//最大处理数减去当天更新处理数,得到剩余处理数,获取起始值后的新增的用户信息
List<UserTagEntity> afterUser = userTagService.findUserByIdAfter(Integer.parseInt(userId), max - size);
//如果当天新增数不为空
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);
}
}
}
//调用个像接口获取更新用户标签
List<UserMenusEntity> beforeTag = getUserTag(beforeGid, beforeUser, tags);
if (CollUtil.isNotEmpty(beforeTag)) {
userMenusList.addAll(beforeTag);
}
//批量插入用户标签信息
userMenusService.batchInsert(userMenusList);
log.error("执行结束{}", asyncServiceExecutor.getPoolSize());
} catch (Exception e) {
e.printStackTrace();
log.error("执行定时更新标签任务失败!");
}
}
/**
* 获取个像用户标签信息
*
* @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);
ExecutorService pool = Executors.newFixedThreadPool(totalPage);
//收集中间表数据
//创建线程
for (int i = 0; i < totalPage; i++) {
int finalI = i;
Runnable runnable = () -> {
List<String> list = new ArrayList<>();
//截取每次处理数据
List<String> list;
if (finalI == totalPage - 1) {
list = todayGid.subList(finalI * limit, size);
list = gid.subList(finalI * limit, size);
} else {
list = todayGid.subList(finalI * limit, (finalI + 1) * limit);
list = gid.subList(finalI * limit, (finalI + 1) * limit);
}
if (CollectionUtils.isNotEmpty(list)) {
String[] strings = list.toArray(new String[0]);
Map<String, Object> android = menuService.getUserTags(strings);
List<UserMenusEntity> tagUser = menuService.getTagUser(android);
if (CollectionUtils.isNotEmpty(tagUser)) {
userMenusList.addAll(tagUser);
//获取个像数据
Map<String, Object> android = menuService.getUserTags(list, tag);
if (android != null) {
//解析个像数据
List<UserMenusEntity> tagUser = menuService.getTagUser(android, userInfo);
userTags.addAll(tagUser);
}
}
latch.countDown();
};
pool.execute(runnable);
asyncServiceExecutor.execute(runnable);
}
latch.await();
userMenusService.batchInsert(userMenusList);
} catch (InterruptedException e) {
e.printStackTrace();
log.error("执行定时更新标签任务失败!");
}
return userTags;
}
// @Scheduled(cron = "* * * * * ?")
// public void updateUser() {
// System.out.println("你好" + System.currentTimeMillis());
// }
}
......@@ -26,6 +26,14 @@ spring:
enabled: true
mvc:
throw-exception-if-no-handler-found: true
redis:
host: localhost
database: 0
port: 6379
maxTotal: 1000
maxIdle: 50
minIdle: 10
timeout: 1s
getui:
apps: {
......@@ -43,7 +51,7 @@ mybatis-plus:
#数据库相关配置
db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: AUTO
id-type: INPUT
logic-delete-value: 0
logic-not-delete-value: 1
banner: false
......@@ -54,3 +62,6 @@ mybatis-plus:
call-setters-on-nulls: true
jdbc-type-for-null: 'null'
gexiang:
user_tag_id: 400000
push_max_size: 30000
......@@ -19,6 +19,7 @@
(#{item.id},#{item.userId},#{item.tagsId},#{item.isValid},#{item.createTime})
</foreach>
</insert>
<!-- 根据uid查询标签id-->
<select id="findIdByUserId" resultType="long">
SELECT id FROM tb_user_menus WHERE is_valid = 1 AND user_id IN
......
<?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">
<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="uid" column="uid"/>
<result property="tel" column="tel"/>
<result property="gid" column="gid"/>
<result property="saveDate" column="save_date"/>
<collection property="list" ofType="com.weface.entity.MenuTagsEntity">
<id property="id" column="tagId"></id>
<result property="levelFirst" column="level_first"></result>
......@@ -19,20 +20,35 @@
<result property="weight" column="weight"></result>
</collection>
</resultMap>
<!-- 使用limit分页查询-->
<select id="findGidByLimit" resultType="string">
SELECT gid
<!-- 查询id之前且当天更新的用户 AND id &lt; #{id}-->
<select id="findUserByTodayAndIdBefore" resultMap="userTagMap">
SELECT uid, gid
FROM t_user_tag
WHERE gid IS NOT NULL LIMIT #{pageRecord}
, #{limit}
WHERE gid IS NOT NULL
AND id &lt;= #{id}
AND TO_DAYS(save_date) = TO_DAYS(NOW())
ORDER BY save_date DESC
</select>
<!-- 查询当天更新用户gid-->
<select id="findTodayGid" resultType="string">
SELECT DISTINCT gid
<!-- 查询id之后的用户信息-->
<select id="findUserByIdAfter" resultMap="userTagMap">
SELECT id,uid, gid
FROM t_user_tag
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>
<!-- 将公共片段抽取:只针对个别业务-->
<sql id="common">
SELECT ut.uid,
......@@ -47,28 +63,18 @@
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 um.is_valid = 1
WHERE mt.level_first = "Android"
AND um.is_valid = 1
</sql>
<!-- 查询用户和标签信息-->
<select id="getUserAndTags" resultMap="tUserTagMap">
<!-- 查询用户信息根据gid-->
<select id="getUserAndTags" resultMap="userTagMap">
<include refid="common"/>
<if test="giUid !=null and giUid != ''">
AND ut.user_id LIKE CONCAT(CONCAT('%',#{giUid}),'%')
</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 test="gid !=null and gid != ''">
AND ut.gid LIKE CONCAT(CONCAT('%',#{gid}),'%')
</if>
</select>
<!-- 根据标签查询用户gid-->
<select id="getGidByTag" resultType="string">
SELECT DISTINCT
......@@ -84,16 +90,15 @@
#{item}
</foreach>
</select>
<!-- 根据gid查询用户标签-->
<select id="getTagByGid" resultMap="tUserTagMap">
<!-- 根据gid查询用户标签-->
<select id="getTagByGid" resultMap="userTagMap">
<include refid="common"/>
AND ut.gid IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
AND ut.gid =#{gid}
</select>
<!-- 查询所有用户标签管理数据-->
<select id="selectAllUserForTags" resultMap="tUserTagMap">
<!-- 查询所有用户标签管理数据-->
<select id="selectAllUserForTags" resultMap="userTagMap">
<include refid="common"/>
</select>
......
package com.weface;
import com.weface.component.GeTuiUtils;
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.service.TUserTagService;
import com.weface.service.MenuTagsService;
import com.weface.service.UserTagService;
import com.weface.service.UserMenusService;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.jupiter.api.Test;
......@@ -15,23 +21,37 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@SpringBootTest
class PushMessageApplicationTests {
@Autowired
private TUserTagService tUserTagService;
private UserTagService userTagService;
@Autowired
private MenuService menuService;
@Autowired
private UserMenusService userMenusService;
@Autowired
private MenuTagsService menuTagsService;
@Test
void contextLoads() {
}
/**
* 根据时间同步标签
*/
@Test
public void test(){
public void testKKSB() {
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 limit = 1000;
List<UserMenusEntity> userMenusList = new ArrayList<>();
......@@ -42,16 +62,15 @@ class PushMessageApplicationTests {
for (int i = 0; i < totalPage; i++) {
int finalI = i;
Runnable runnable = () -> {
List<String> list = new ArrayList<>();
List<String> list;
if (finalI == totalPage - 1) {
list = todayGid.subList(finalI * limit, size);
} else {
list = todayGid.subList(finalI * limit, (finalI + 1) * limit);
}
if (CollectionUtils.isNotEmpty(list)) {
String[] strings = list.toArray(new String[0]);
Map<String, Object> android = menuService.getUserTags(strings);
List<UserMenusEntity> tagUser = menuService.getTagUser(android);
Map<String, Object> android = menuService.getUserTags(list, tags);
List<UserMenusEntity> tagUser = menuService.getTagUser(android, todayUser);
if (CollectionUtils.isNotEmpty(tagUser)) {
userMenusList.addAll(tagUser);
}
......@@ -62,9 +81,36 @@ class PushMessageApplicationTests {
}
latch.await();
userMenusService.batchInsert(userMenusList);
} catch (InterruptedException e) {
} catch (Exception e) {
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