diff --git a/xservice-core/pom.xml b/xservice-core/pom.xml
index ddefa5a..e144b08 100644
--- a/xservice-core/pom.xml
+++ b/xservice-core/pom.xml
@@ -17,4 +17,12 @@
UTF-8
+
+
+ com.xiang.starter
+ xmc-cache-starter
+ 1.0-SNAPSHOT
+
+
+
\ No newline at end of file
diff --git a/xservice-core/src/main/java/com/xiang/app/common/enums/DingTalkBizTypeEnum.java b/xservice-core/src/main/java/com/xiang/app/common/enums/DingTalkBizTypeEnum.java
new file mode 100644
index 0000000..82cce9a
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/common/enums/DingTalkBizTypeEnum.java
@@ -0,0 +1,19 @@
+package com.xiang.app.common.enums;
+
+import com.xiang.xmc.service.message.dingTalk.enums.BaseDingTalkBizType;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @Author: xiang
+ * @Date: 2026-01-04 16:13
+ */
+@Getter
+@RequiredArgsConstructor
+public enum DingTalkBizTypeEnum implements BaseDingTalkBizType {
+
+ JT("venue", "江南体育中心"),
+ ;
+ private final String bizName;
+ private final String desc;
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/common/service/dingtalk/JtDingTalkFactory.java b/xservice-core/src/main/java/com/xiang/app/common/service/dingtalk/JtDingTalkFactory.java
new file mode 100644
index 0000000..b658642
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/common/service/dingtalk/JtDingTalkFactory.java
@@ -0,0 +1,23 @@
+package com.xiang.app.common.service.dingtalk;
+
+import com.xiang.app.common.enums.DingTalkBizTypeEnum;
+import com.xiang.xmc.service.message.dingTalk.config.DingTalkRobotProperties;
+import com.xiang.xmc.service.message.dingTalk.service.AbstractDingTalkFactory;
+import com.xiang.xmc.service.message.dingTalk.service.DingTalkSender;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author: xiang
+ * @Date: 2026-01-04 16:19
+ */
+@Service
+public class JtDingTalkFactory extends AbstractDingTalkFactory {
+ public JtDingTalkFactory(DingTalkRobotProperties dingTalkRobotProperties, DingTalkSender dingTalkSender) {
+ super(dingTalkRobotProperties, dingTalkSender);
+ }
+
+ @Override
+ public void sendMsg(String msg) {
+ getClient(DingTalkBizTypeEnum.JT).sendDingTalkMsg(msg);
+ }
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJntyzxHttpService.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJntyzxHttpService.java
new file mode 100644
index 0000000..a8c738d
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJntyzxHttpService.java
@@ -0,0 +1,42 @@
+package com.xiang.app.modules.jntyzx.service;
+
+
+import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
+import com.xiang.app.modules.jntyzx.entity.resp.JntyzxResponse;
+import com.xiang.app.modules.jntyzx.entity.resp.query.SitePositionList;
+
+import java.util.List;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-15 14:47
+ */
+public interface IJntyzxHttpService {
+
+ /**
+ * 查询今日可用场地
+ */
+ List queryAvailable(String isWeekend, String token);
+
+ /**
+ * 查询明日可用场地
+ * @param isWeekend
+ * @param token
+ * @return
+ */
+ List queryAvailableTomorrow(String isWeekend, String token);
+
+ /**
+ * 订单创建
+ * @return
+ */
+ Boolean createOrder(List venueInfos, String token);
+
+ /**
+ * 心跳监测
+ * @param token token
+ * @param openId openid
+ * @return
+ */
+ JntyzxResponse healthDeclaration(String token, String openId);
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJtOrderService.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJtOrderService.java
new file mode 100644
index 0000000..67094d7
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IJtOrderService.java
@@ -0,0 +1,15 @@
+package com.xiang.app.modules.jntyzx.service;
+
+
+import com.xiang.app.modules.jntyzx.entity.pojo.OrderInfoDO;
+
+import java.util.List;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-16 16:17
+ */
+public interface IJtOrderService {
+
+ List queryNoPayOrder();
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IUserTokenInfoService.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IUserTokenInfoService.java
new file mode 100644
index 0000000..09e44e2
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IUserTokenInfoService.java
@@ -0,0 +1,13 @@
+package com.xiang.app.modules.jntyzx.service;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-16 09:22
+ */
+public interface IUserTokenInfoService {
+
+ String getToken(String name);
+ boolean flushSingleToken(String name);
+ boolean flushToken();
+ boolean updateTokenByName(String name, String token);
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IVenueService.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IVenueService.java
new file mode 100644
index 0000000..d9b90d6
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/IVenueService.java
@@ -0,0 +1,19 @@
+package com.xiang.app.modules.jntyzx.service;
+
+
+import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
+import com.xiang.app.modules.jntyzx.entity.resp.query.SitePositionList;
+
+import java.util.List;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-15 16:07
+ */
+public interface IVenueService {
+
+ List queryVenueService();
+ List queryTomorrowVenue();
+ List queryCanBuyVenue();
+ List queryToday6210VenueInfo();
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/JntyzxHttpServiceImpl.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/JntyzxHttpServiceImpl.java
new file mode 100644
index 0000000..25bc043
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/JntyzxHttpServiceImpl.java
@@ -0,0 +1,242 @@
+package com.xiang.app.modules.jntyzx.service;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.TypeReference;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.xiang.app.modules.jntyzx.constants.RedisKeyConstant;
+import com.xiang.app.modules.jntyzx.constants.UrlConstant;
+import com.xiang.app.modules.jntyzx.entity.pojo.OrderInfoDO;
+import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
+import com.xiang.app.modules.jntyzx.entity.req.SubscribeRequest;
+import com.xiang.app.modules.jntyzx.entity.req.SubscribeVo;
+import com.xiang.app.modules.jntyzx.entity.resp.JntyzxResponse;
+import com.xiang.app.modules.jntyzx.entity.resp.OrderCreateResp;
+import com.xiang.app.modules.jntyzx.entity.resp.query.SitePositionList;
+import com.xiang.app.modules.jntyzx.entity.resp.query.VenueList;
+import com.xiang.app.modules.jntyzx.manage.IOrderCreateInfoManage;
+import com.xiang.xmc.service.cache.service.IRedisService;
+import com.xiang.xmc.service.http.helper.HttpHelper;
+import com.xiang.xservice.basic.utils.Base64;
+import com.xiang.xservice.basic.utils.JsonUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-05-14 14:07
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class JntyzxHttpServiceImpl implements IJntyzxHttpService {
+
+ private final IRedisService redisService;
+ private final IOrderCreateInfoManage orderCreateInfoManage;
+
+ @Override
+ public List queryAvailable(String isWeekend, String token) {
+ String url = UrlConstant.QUERY_TODAY_SUBSCRIBE_URL;
+ return querySitePositionInfo(isWeekend, token, url);
+ }
+
+ @NotNull
+ private static List querySitePositionInfo(String isWeekend, String token, String url) {
+ Map header = Maps.newHashMap();
+ header.put("X-Access-Token", token);
+ String resp = null;
+ Map params = Maps.newHashMap();
+ params.put("gid", "03");
+ params.put("isWeekend", isWeekend);
+ try {
+ resp = HttpHelper.doGet(url, header, params);
+ } catch (Exception e) {
+ log.error("[doGet] 江南体育中心查询当天场地 请求失败, url:{}", url);
+ return Lists.newArrayList();
+ }
+ if (StringUtils.isEmpty(resp)) {
+ log.warn("[查询场地] 江南体育中心查询当天场地 请求结果为空, url:{}, resp:{}", url, resp);
+ return Lists.newArrayList();
+ }
+ JSONObject jsonObject = JSON.parseObject(resp);
+ if (Objects.isNull(jsonObject)) {
+ return Lists.newArrayList();
+ }
+ String resultStr = JSON.toJSONString(jsonObject.get("result"));
+ if (StringUtils.isBlank(resultStr)) {
+ return Lists.newArrayList();
+ }
+ JSONObject result = JSON.parseObject(resultStr);
+ if (Objects.isNull(result)) {
+ return Lists.newArrayList();
+ }
+ String venueStr = JSON.toJSONString(result.get("venue"));
+ if (StringUtils.isBlank(venueStr)) {
+ return Lists.newArrayList();
+ }
+ List venueLists = JSON.parseArray(venueStr, VenueList.class);
+ if (CollectionUtils.isEmpty(venueLists)) {
+ return Lists.newArrayList();
+ }
+ List res = Lists.newArrayList();
+ for (VenueList venueList : venueLists) {
+ List sitePositionList = venueList.getSitePosition();
+ if (CollectionUtils.isEmpty(sitePositionList)) {
+ continue;
+ }
+ res.addAll(sitePositionList);
+ }
+ return res;
+ }
+
+ @Override
+ public List queryAvailableTomorrow(String isWeekend, String token) {
+ String url = UrlConstant.QUERY_TOMORROW_SUBSCRIBE_URL;
+ return querySitePositionInfo(isWeekend, token, url);
+ }
+
+ @Override
+ public Boolean createOrder(List venueInfos, String token) {
+
+ List vos = Lists.newArrayList();
+ for (VenueInfoDO venueInfo : venueInfos) {
+ SubscribeVo subscribeVo = new SubscribeVo();
+ subscribeVo.setId(0);
+ subscribeVo.setBallCourtId("03");
+ subscribeVo.setSjName(venueInfo.getSjName());
+ subscribeVo.setScheduleId(String.valueOf(venueInfo.getScheduleId()));
+ subscribeVo.setPlaceName(venueInfo.getPlaceName());
+ subscribeVo.setPlaceId(venueInfo.getPlaceId());
+ subscribeVo.setType("0");
+ subscribeVo.setClassName(venueInfo.getClassName());
+ subscribeVo.setClassCode(venueInfo.getClassCode());
+ subscribeVo.setMoney(venueInfo.getMoney().setScale(0));
+ subscribeVo.setContacts("0");
+ subscribeVo.setContactNumber(null);
+ subscribeVo.setMemberNumber(null);
+ subscribeVo.setAppointments(venueInfo.getAppointments());
+ subscribeVo.setOperator(null);
+ subscribeVo.setEndTime(null);
+ subscribeVo.setBeginTime(null);
+ subscribeVo.setSpecOneTimes(3);
+ subscribeVo.setCtypeCode(venueInfo.getCTypeCode());
+ subscribeVo.setIsWhole(0);
+ subscribeVo.setOrderId(null);
+ subscribeVo.setVotesnum(1);
+ vos.add(subscribeVo);
+ }
+
+ JSONObject jsonObject = buildParamJsonObj();
+ SubscribeRequest subscribeRequest = new SubscribeRequest();
+
+ subscribeRequest.setSubscribeVos(vos);
+ subscribeRequest.setBookTime(venueInfos.get(0).getAppointments());
+ subscribeRequest.setPaymentMethod(1);
+ subscribeRequest.setSvCiphertext(sonAddSalt(JsonUtils.toJsonString(vos)));
+ subscribeRequest.setJsonObject(jsonObject);
+
+ Map params = Maps.newHashMap();
+ params.put("X-Access-Token", token);
+ String resp = HttpHelper.doPost(UrlConstant.ADD_SUBSCRIBE, params, JsonUtils.toJsonString(subscribeRequest));
+ if (StringUtils.isBlank(resp)) {
+ log.info("请求结果为空");
+ return false;
+ }
+ JntyzxResponse response = JSON.parseObject(resp, new TypeReference>() {
+ });
+ if (Objects.isNull(response)) {
+ log.info("请求结果为空");
+ return false;
+ }
+ if (response.getSuccess()) {
+ OrderCreateResp createResp = response.getResult();
+ if (Objects.nonNull(createResp)) {
+ String orderId = createResp.getId();
+ redisService.set(RedisKeyConstant.JNTYZX_ORDER_CREATE_KEY + orderId, String.valueOf(System.currentTimeMillis()));
+ OrderInfoDO orderInfoDO = new OrderInfoDO();
+ orderInfoDO.setOrderId(orderId);
+ orderInfoDO.setParams(JsonUtils.toJsonString(subscribeRequest));
+ orderInfoDO.setCreateTime(LocalDateTime.now());
+ orderInfoDO.setUsername(token);
+ orderInfoDO.setPlaceName(vos.get(0).getPlaceName());
+ orderInfoDO.setDate(LocalDate.now());
+ orderInfoDO.setOrderStatus(0);
+ orderCreateInfoManage.save(orderInfoDO);
+ return true;
+ }
+ }
+ return false;
+ }
+ @Override
+ public JntyzxResponse healthDeclaration(String token, String openId) {
+ Map headers = Maps.newHashMap();
+ headers.put("X-Access-Token", token);
+ Map params = Maps.newHashMap();
+ params.put("openId", openId);
+
+ String respStr = HttpHelper.doGet(UrlConstant.HEALTH_DECLARATION, headers, params);
+ if (StringUtils.isBlank(respStr)) {
+ return null;
+ }
+ return JSON.parseObject(respStr, JntyzxResponse.class);
+ }
+
+ private static JSONObject buildParamJsonObj() {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("id", "1702581215097257986");
+ jsonObject.put("createBy", null);
+ jsonObject.put("createTime", "2023-09-15 15:12:48");
+ jsonObject.put("updateBy", null);
+ jsonObject.put("updateTime", null);
+ jsonObject.put("sysOrgCode", null);
+ jsonObject.put("openId", "o21MX4y7whXCGjvUTGP6CTz2HbD8");
+ jsonObject.put("nickName", "1");
+ jsonObject.put("unionId", null);
+ jsonObject.put("avatarUrl", "https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132");
+ jsonObject.put("remarks", null);
+ jsonObject.put("default01", null);
+ jsonObject.put("default02", null);
+ jsonObject.put("default03", null);
+ jsonObject.put("default04", null);
+ jsonObject.put("default05", null);
+ return jsonObject;
+ }
+
+ private static int[] getMonthAndDay() {
+ LocalDate currentDate = LocalDate.now();
+ int month = currentDate.getMonthValue();
+ int day = currentDate.getDayOfMonth();
+ return new int[]{month, day};
+ }
+
+ private String sonAddSalt(String json) {
+ String svCiphertext = "";
+ String suiji = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ String token1 = String.valueOf(suiji.charAt((int) (Math.random() * (double) suiji.length())));
+ String token2 = String.valueOf(suiji.charAt((int) (Math.random() * (double) suiji.length())));
+ svCiphertext = Base64.encode(json.getBytes(StandardCharsets.UTF_8));
+ int[] monthAndDay = getMonthAndDay();
+ int month = monthAndDay[0];
+ int day = monthAndDay[1];
+ if (month == 1) {
+ svCiphertext = (svCiphertext = token1 + svCiphertext).substring(0, day - 1) + token2 + svCiphertext.substring(day - 1);
+ } else if (day == 1) {
+ svCiphertext = token2 + svCiphertext.substring(0, month - 1) + token1 + svCiphertext.substring(month - 1);
+ } else {
+ svCiphertext = (svCiphertext = svCiphertext.substring(0, month - 1) + token1 + svCiphertext.substring(month - 1)).substring(0, day - 1) + token2 + svCiphertext.substring(day - 1);
+ }
+ return svCiphertext;
+ }
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/OrderInfoServiceImpl.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/OrderInfoServiceImpl.java
new file mode 100644
index 0000000..635ca94
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/OrderInfoServiceImpl.java
@@ -0,0 +1,23 @@
+package com.xiang.app.modules.jntyzx.service;
+
+import com.xiang.app.modules.jntyzx.entity.pojo.OrderInfoDO;
+import com.xiang.app.modules.jntyzx.manage.IOrderCreateInfoManage;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-16 16:17
+ */
+@Service
+@RequiredArgsConstructor
+public class OrderInfoServiceImpl implements IJtOrderService {
+
+ private final IOrderCreateInfoManage orderCreateInfoManage;
+ @Override
+ public List queryNoPayOrder() {
+ return orderCreateInfoManage.queryNoPayOrder();
+ }
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/UserTokenInfoServiceImpl.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/UserTokenInfoServiceImpl.java
new file mode 100644
index 0000000..fb00df4
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/UserTokenInfoServiceImpl.java
@@ -0,0 +1,84 @@
+package com.xiang.app.modules.jntyzx.service;
+
+import com.xiang.app.common.service.dingtalk.JtDingTalkFactory;
+import com.xiang.app.modules.jntyzx.entity.pojo.UserTokenInfoDO;
+import com.xiang.app.modules.jntyzx.entity.resp.JntyzxResponse;
+import com.xiang.app.modules.jntyzx.manage.IUserTokenInfoManage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-16 09:22
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class UserTokenInfoServiceImpl implements IUserTokenInfoService {
+
+ private final IUserTokenInfoManage userTokenInfoManage;
+ private final IJntyzxHttpService jntyzxHttpService;
+ private final JtDingTalkFactory jtDingTalkFactory;
+
+
+ @Override
+ public String getToken(String name) {
+ UserTokenInfoDO userTokenInfoDO = userTokenInfoManage.getByName(name);
+ if (Objects.isNull(userTokenInfoDO)) {
+ return null;
+ }
+ return userTokenInfoDO.getToken();
+ }
+
+ @Override
+ public boolean flushSingleToken(String name) {
+ UserTokenInfoDO userTokenInfoDO = userTokenInfoManage.getByName(name);
+ if (Objects.isNull(userTokenInfoDO)) {
+ log.info("用户信息不存在,无需进行监测!");
+ return false;
+ }
+ return healthDeclaration(userTokenInfoDO);
+
+ }
+
+ @Override
+ public boolean flushToken() {
+ List userTokenInfoDOS = userTokenInfoManage.listUser();
+ if (CollectionUtils.isEmpty(userTokenInfoDOS)) {
+ log.info("【心跳监测】查询用户信息为空,无需操作");
+ return true;
+ }
+ userTokenInfoDOS.parallelStream().forEach(this::healthDeclaration);
+ return true;
+ }
+
+ @Override
+ public boolean updateTokenByName(String name, String token) {
+ UserTokenInfoDO userTokenInfoDO = userTokenInfoManage.getByName(name);
+ if (Objects.isNull(userTokenInfoDO)) {
+ return false;
+ }
+ userTokenInfoDO.setToken(token);
+ return userTokenInfoManage.updateById(userTokenInfoDO);
+ }
+
+ private boolean healthDeclaration(UserTokenInfoDO userTokenInfoDO) {
+ JntyzxResponse jntyzxResponse = jntyzxHttpService.healthDeclaration(userTokenInfoDO.getToken(), userTokenInfoDO.getOpenId());
+ if (Objects.isNull(jntyzxResponse)) {
+ log.info("用户名:{}心跳监测失败!", userTokenInfoDO.getName());
+ }
+ boolean flag = StringUtils.contains(jntyzxResponse.getMessage(), "已存在");
+ if (flag) {
+ log.info("用户名:{}心跳成功✅✅✅✅✅✅", userTokenInfoDO.getName());
+ } else {
+ jtDingTalkFactory.sendMsg("用户名:" + userTokenInfoDO.getName() + "心跳失败,消息:" + jntyzxResponse.getMessage());
+ }
+ return flag;
+ }
+}
diff --git a/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/VenueServiceImpl.java b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/VenueServiceImpl.java
new file mode 100644
index 0000000..f2f05c9
--- /dev/null
+++ b/xservice-core/src/main/java/com/xiang/app/modules/jntyzx/service/VenueServiceImpl.java
@@ -0,0 +1,132 @@
+package com.xiang.app.modules.jntyzx.service;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.xiang.app.modules.jntyzx.entity.pojo.VenueInfoDO;
+import com.xiang.app.modules.jntyzx.entity.resp.query.SitePositionList;
+import com.xiang.app.modules.jntyzx.manage.IVenueInfoManage;
+import com.xiang.app.modules.jntyzx.utils.VenueInfoUtils;
+import com.xiang.xservice.basic.utils.DateUtils;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: xiang
+ * @Date: 2025-12-15 16:08
+ */
+@Service
+@RequiredArgsConstructor
+public class VenueServiceImpl implements IVenueService {
+
+ private final IJntyzxHttpService jntyzxHttpService;
+ private final IVenueInfoManage venueInfoManage;
+ private final IUserTokenInfoService userTokenInfoService;
+
+ @Override
+ public List queryVenueService() {
+ String token = userTokenInfoService.getToken("Xiang");
+ if (StringUtils.isBlank(token)) {
+ return Lists.newArrayList();
+ }
+ List sitePositionLists = jntyzxHttpService.queryAvailable("1", token);
+ if (CollectionUtils.isEmpty(sitePositionLists)) {
+ return Lists.newArrayList();
+ }
+ updateDatabase(sitePositionLists, true);
+ return sitePositionLists;
+ }
+
+ @Override
+ public List queryTomorrowVenue() {
+ String token = userTokenInfoService.getToken("Xiang");
+ if (StringUtils.isBlank(token)) {
+ return Lists.newArrayList();
+ }
+ List sitePositionLists = jntyzxHttpService.queryAvailableTomorrow("1", token);
+ if (CollectionUtils.isEmpty(sitePositionLists)) {
+ return Lists.newArrayList();
+ }
+ updateDatabase(sitePositionLists, false);
+ return sitePositionLists;
+ }
+
+ @Override
+ public List queryCanBuyVenue() {
+ return venueInfoManage.queryByType(LocalDate.now(), 0);
+ }
+
+ @Override
+ public List queryToday6210VenueInfo() {
+ List venueInfoDOS = venueInfoManage.queryByDate(LocalDate.now());
+ return venueInfoDOS.stream().filter(item -> VenueInfoUtils.get628VenueInfo(item) || VenueInfoUtils.get8210VenueInfo(item)).toList();
+ }
+
+ private void updateDatabase(List list, boolean isToday) {
+ List venueInfoDOS = Lists.newArrayList();
+ if (isToday) {
+ venueInfoDOS.addAll(venueInfoManage.queryByDate(LocalDate.now()));
+ } else {
+ venueInfoDOS.addAll(venueInfoManage.queryByDate(LocalDate.now().plusDays(1)));
+ }
+
+ Map> map = Maps.newHashMap();
+ if (CollectionUtils.isNotEmpty(venueInfoDOS)) {
+ map.putAll(venueInfoDOS.stream().filter(Objects::nonNull)
+ .collect(Collectors.groupingBy(VenueInfoDO::getPlaceId)));
+ }
+ List insertList = Lists.newArrayList();
+ for (SitePositionList sitePositionList : list) {
+ if (map.containsKey(sitePositionList.getPlaceId())) {
+ List venueInfoDOList = map.get(sitePositionList.getPlaceId());
+ Map sjMap = venueInfoDOList.stream().collect(Collectors.toMap(VenueInfoDO::getSjName, Function.identity(), (a, b) -> a));
+ if (sjMap.containsKey(sitePositionList.getSjName())) {
+ VenueInfoDO venueInfoDO = sjMap.get(sitePositionList.getSjName());
+ if (!StringUtils.equals(venueInfoDO.getContacts(), sitePositionList.getContacts())
+ || !Objects.equals(venueInfoDO.getType(), sitePositionList.getType())
+ || !Objects.equals(venueInfoDO.getPlaceMainId(), sitePositionList.getId())) {
+ venueInfoDO.setContacts(sitePositionList.getContacts());
+ venueInfoDO.setType(sitePositionList.getType());
+ venueInfoDO.setPlaceMainId(sitePositionList.getId());
+ venueInfoManage.updateById(venueInfoDO);
+ }
+ } else {
+ addIntoInsert(sitePositionList, insertList);
+ }
+ } else {
+ addIntoInsert(sitePositionList, insertList);
+ }
+ }
+ if (CollectionUtils.isNotEmpty(insertList)) {
+ venueInfoManage.saveBatch(insertList);
+ }
+ }
+
+ private static void addIntoInsert(SitePositionList sitePositionList, List insertList) {
+ VenueInfoDO venueInfoDO = new VenueInfoDO();
+ venueInfoDO.setPlaceName(sitePositionList.getPlaceName());
+ venueInfoDO.setDate(DateUtils.getDateFromStr(sitePositionList.getAppointments()));
+ venueInfoDO.setPlaceMainId(sitePositionList.getId());
+ venueInfoDO.setPlaceId(sitePositionList.getPlaceId());
+ venueInfoDO.setScheduleId(Integer.valueOf(sitePositionList.getScheduleId()));
+ venueInfoDO.setSjName(sitePositionList.getSjName());
+ venueInfoDO.setCreateTime(LocalDateTime.now());
+ venueInfoDO.setContacts(sitePositionList.getContacts());
+ venueInfoDO.setType(sitePositionList.getType());
+ venueInfoDO.setMoney(sitePositionList.getMoney());
+ venueInfoDO.setClassName(sitePositionList.getClassName());
+ venueInfoDO.setClassCode(sitePositionList.getClassCode());
+ venueInfoDO.setAppointments(sitePositionList.getAppointments());
+ venueInfoDO.setCTypeCode(sitePositionList.getCtypeCode());
+ insertList.add(venueInfoDO);
+ }
+}
diff --git a/xservice-server/pom.xml b/xservice-server/pom.xml
index d76176d..272cc5b 100644
--- a/xservice-server/pom.xml
+++ b/xservice-server/pom.xml
@@ -17,4 +17,12 @@
UTF-8
+
+
+ com.xiang.app
+ xservice-core
+ 1.0-SNAPSHOT
+
+
+
\ No newline at end of file
diff --git a/xservice-server/src/main/java/com/xiang/app/Application.java b/xservice-server/src/main/java/com/xiang/app/Application.java
index e2d782f..c1fc3f0 100644
--- a/xservice-server/src/main/java/com/xiang/app/Application.java
+++ b/xservice-server/src/main/java/com/xiang/app/Application.java
@@ -12,7 +12,8 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
*/
@SpringBootApplication
@ConfigurationPropertiesScan(basePackages = {
- "com.xiang.xservice.logger"
+ "com.xiang.xservice.logger",
+ "com.xiang.app.common.config",
})
public class Application {
diff --git a/xservice-server/src/main/java/com/xiang/app/server/jntyzx/JtTokenServer.java b/xservice-server/src/main/java/com/xiang/app/server/jntyzx/JtTokenServer.java
new file mode 100644
index 0000000..3b72bc5
--- /dev/null
+++ b/xservice-server/src/main/java/com/xiang/app/server/jntyzx/JtTokenServer.java
@@ -0,0 +1,29 @@
+package com.xiang.app.server.jntyzx;
+
+import com.xiang.app.common.service.dingtalk.JtDingTalkFactory;
+import com.xiang.app.modules.jntyzx.service.IUserTokenInfoService;
+import com.xiang.xservice.basic.common.resp.Result;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author: xiang
+ * @Date: 2026-01-04 14:56
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/open/jt/token")
+public class JtTokenServer {
+
+ private final IUserTokenInfoService userTokenInfoService;
+
+ @GetMapping("/flushSingleUser")
+ public Result flushSingleUser(@RequestParam("username") String username, @RequestParam("token") String token) {
+ userTokenInfoService.updateTokenByName(username, token);
+ return Result.success();
+ }
+
+}
diff --git a/xservice-server/src/main/resources/application-dev.yml b/xservice-server/src/main/resources/application-dev.yml
index 903bf01..fd9202c 100644
--- a/xservice-server/src/main/resources/application-dev.yml
+++ b/xservice-server/src/main/resources/application-dev.yml
@@ -28,4 +28,14 @@ spring:
max-active: 8
max-idle: 8
min-idle: 0
- max-wait: 1000
\ No newline at end of file
+ max-wait: 1000
+
+dingtalk:
+ robot:
+ properties:
+ venue:
+ name: 江南体育中心通知群
+ token: 6a218646972c684c75832b0229ea93a234778af537d7469ce96bef290faf530e
+ secret: SEC9018755ba86d3e5c1ed2fbfa1d6953d84bb2a6c8ebe7ed4e318457bfed5e0465
+ users:
+ - 450841600726084717
\ No newline at end of file