|
|
@@ -14,12 +14,16 @@ import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.alibaba.fastjson.TypeReference;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
|
import com.fs.common.utils.IpUtil;
|
|
|
import com.fs.live.domain.LiveOrder;
|
|
|
import com.fs.live.domain.LiveOrderItem;
|
|
|
+import com.fs.live.mapper.LiveOrderMapper;
|
|
|
import com.fs.live.domain.LiveRewardCompensation;
|
|
|
+import com.fs.live.utils.CrossServiceMd5Util;
|
|
|
+import com.fs.live.utils.CrossServiceRsaUtil;
|
|
|
import com.fs.live.mapper.LiveRewardCompensationMapper;
|
|
|
import com.fs.live.utils.CryptoUtil;
|
|
|
import com.fs.live.vo.HisFsUserVO;
|
|
|
@@ -37,6 +41,7 @@ import com.fs.store.vo.FsUserVO;
|
|
|
import com.fs.store.vo.FsCompanyUserListQueryVO;
|
|
|
import com.fs.store.vo.FsUserShareVO;
|
|
|
import com.fs.store.vo.FsUserTuiVO;
|
|
|
+import com.fs.store.vo.AppUserSyncVo;
|
|
|
import com.fs.wx.miniapp.config.WxMaConfiguration;
|
|
|
import com.fs.wx.miniapp.config.WxMaProperties;
|
|
|
import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
@@ -55,9 +60,13 @@ import org.springframework.aop.framework.AopContext;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
+import org.springframework.http.HttpEntity;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import com.fs.store.mapper.FsUserMapper;
|
|
|
import com.fs.store.service.IFsUserService;
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
@@ -78,6 +87,9 @@ public class FsUserServiceImpl implements IFsUserService
|
|
|
@Autowired
|
|
|
private FsUserMapper fsUserMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private LiveOrderMapper liveOrderMapper;
|
|
|
+
|
|
|
@Autowired
|
|
|
private FsStoreProductAttrValueMapper storeProductAttrValueMapper;
|
|
|
|
|
|
@@ -731,4 +743,118 @@ public class FsUserServiceImpl implements IFsUserService
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
+ private static final String APP_USER_SYNC_URL = "http://42.194.245.189:8010/app/common/syncAppUsers";
|
|
|
+ private static final int APP_USER_SYNC_BATCH_SIZE = 50;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void syncAppUsersForRecentLiveOrders(int days) {
|
|
|
+ List<String> userIdStrList = liveOrderMapper.selectDistinctUserIdsFromRecentOrders(days);
|
|
|
+ if (userIdStrList == null || userIdStrList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<Long> userIds = userIdStrList.stream()
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .map(id -> {
|
|
|
+ try {
|
|
|
+ return Long.parseLong(id.trim());
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (userIds.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<FsUser> usersToSync = fsUserMapper.selectUnsyncedAppUsersByUserIds(userIds);
|
|
|
+
|
|
|
+ if (usersToSync == null || usersToSync.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> unionIds = usersToSync.stream()
|
|
|
+ .map(FsUser::getUnionId)
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (unionIds.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, FsUser> userByUnionId = usersToSync.stream()
|
|
|
+ .filter(u -> StringUtils.isNotBlank(u.getUnionId()))
|
|
|
+ .collect(Collectors.toMap(FsUser::getUnionId, Function.identity(), (a, b) -> a));
|
|
|
+
|
|
|
+ for (int i = 0; i < unionIds.size(); i += APP_USER_SYNC_BATCH_SIZE) {
|
|
|
+ int end = Math.min(i + APP_USER_SYNC_BATCH_SIZE, unionIds.size());
|
|
|
+ List<String> batch = unionIds.subList(i, end);
|
|
|
+ try {
|
|
|
+ Map<String, AppUserSyncVo> syncMap = requestAppUserSync(batch);
|
|
|
+ if (syncMap == null || syncMap.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<FsUser> updateList = new ArrayList<>();
|
|
|
+ for (Map.Entry<String, AppUserSyncVo> entry : syncMap.entrySet()) {
|
|
|
+ AppUserSyncVo vo = entry.getValue();
|
|
|
+ if (vo == null || vo.getAppUserId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ FsUser localUser = userByUnionId.get(entry.getKey());
|
|
|
+ if (localUser == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ FsUser update = new FsUser();
|
|
|
+ update.setUserId(localUser.getUserId());
|
|
|
+ update.setAppUserId(vo.getAppUserId());
|
|
|
+ update.setAppDeptName(vo.getAppDeptName());
|
|
|
+ update.setAppSyncFlag(1);
|
|
|
+ updateList.add(update);
|
|
|
+ }
|
|
|
+ batchUpdateAppSyncUsers(updateList);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("批量同步APP用户失败, batchSize={}", batch.size(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void batchUpdateAppSyncUsers(List<FsUser> updateList) {
|
|
|
+ if (updateList == null || updateList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fsUserMapper.batchUpdateAppSyncFields(updateList);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, AppUserSyncVo> requestAppUserSync(List<String> maOpenIds) {
|
|
|
+ String encryptedStr = CrossServiceRsaUtil.encryptForRequest("user" + System.currentTimeMillis());
|
|
|
+ Map<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("encryptedStr", encryptedStr);
|
|
|
+ paramMap.put("unionIds", maOpenIds);
|
|
|
+
|
|
|
+ RestTemplate restTemplate = new RestTemplate();
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(paramMap, headers);
|
|
|
+ String responseBody = restTemplate.postForObject(APP_USER_SYNC_URL, requestEntity, String.class);
|
|
|
+ if (StringUtils.isBlank(responseBody)) {
|
|
|
+ logger.warn("同步APP用户接口无响应");
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ JSONObject respObj = JSONObject.parseObject(responseBody);
|
|
|
+ if (respObj == null || !"200".equals(respObj.getString("code"))) {
|
|
|
+ logger.warn("同步APP用户接口失败: {}", responseBody);
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ String encryptedData = respObj.getString("data");
|
|
|
+ if (StringUtils.isBlank(encryptedData)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ String decryptedJson = CrossServiceMd5Util.decrypt(encryptedData);
|
|
|
+ if (StringUtils.isBlank(decryptedJson)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ return JSONObject.parseObject(decryptedJson, new TypeReference<Map<String, AppUserSyncVo>>() {});
|
|
|
+ }
|
|
|
+
|
|
|
}
|