From 12cb0b8bfcf72e9c71582454841e79d90ec1f81f Mon Sep 17 00:00:00 2001
From: tianyongbao
Date: Sat, 7 Dec 2024 16:43:13 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8A=95=E8=B5=84=E7=B3=BB=E7=BB=9F?=
=?UTF-8?q?=EF=BC=8C=E8=8C=85=E5=8F=B0=E9=A2=84=E7=BA=A6=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=E6=8F=90=E4=BA=A4=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../api/invest/RemoteInvestProdService.java | 39 +
.../ruoyi/api/invest/RemoteInvestService.java | 40 ++
.../factory/RemoteInvestFallbackFactory.java | 25 +
.../RemoteInvestProdFallbackFactory.java | 25 +
ruoyi-common/ruoyi-common-core/pom.xml | 11 +-
.../common/core/manager/AsyncManager.java | 53 ++
.../ruoyi/common/core/manager/Threads.java | 73 ++
.../ruoyi/common/core/utils/RedisCache.java | 256 +++++++
ruoyi-modules/intc-invest/pom.xml | 6 +
.../java/com/ruoyi/IntcInvestApplication.java | 5 +
.../com/ruoyi/config/ThreadPoolConfig.java | 59 ++
.../com/ruoyi/invest/api/PushPlusApi.java | 66 ++
.../invest/controller/IItemController.java | 60 ++
.../invest/controller/ILogController.java | 66 ++
.../invest/controller/IShopController.java | 58 ++
.../invest/controller/IUserController.java | 177 +++++
.../java/com/ruoyi/invest/domain/IItem.java | 76 ++
.../java/com/ruoyi/invest/domain/ILog.java | 78 ++
.../invest/domain/IMTCacheConstants.java | 15 +
.../com/ruoyi/invest/domain/IMTItemInfo.java | 27 +
.../java/com/ruoyi/invest/domain/IShop.java | 124 ++++
.../java/com/ruoyi/invest/domain/IUser.java | 112 +++
.../com/ruoyi/invest/domain/IUserRequest.java | 103 +++
.../com/ruoyi/invest/domain/MapPoint.java | 22 +
.../com/ruoyi/invest/domain/dto/IItemDto.java | 31 +
.../com/ruoyi/invest/domain/dto/ILogDto.java | 39 +
.../com/ruoyi/invest/domain/dto/IShopDto.java | 40 ++
.../com/ruoyi/invest/domain/dto/IUserDto.java | 99 +++
.../com/ruoyi/invest/domain/vo/IItemVo.java | 17 +
.../com/ruoyi/invest/domain/vo/ILogVo.java | 17 +
.../com/ruoyi/invest/domain/vo/IShopVo.java | 17 +
.../com/ruoyi/invest/domain/vo/IUserVo.java | 17 +
.../com/ruoyi/invest/mapper/IItemMapper.java | 82 +++
.../com/ruoyi/invest/mapper/ILogMapper.java | 82 +++
.../com/ruoyi/invest/mapper/IShopMapper.java | 98 +++
.../com/ruoyi/invest/mapper/IUserMapper.java | 91 +++
.../ruoyi/invest/service/IIItemService.java | 63 ++
.../ruoyi/invest/service/IMTLogFactory.java | 57 ++
.../ruoyi/invest/service/IMTLogService.java | 68 ++
.../com/ruoyi/invest/service/IMTService.java | 82 +++
.../ruoyi/invest/service/IShopService.java | 104 +++
.../ruoyi/invest/service/IUserService.java | 74 ++
.../invest/service/impl/IItemServiceImpl.java | 98 +++
.../service/impl/IMTLogServiceImpl.java | 103 +++
.../invest/service/impl/IMTServiceImpl.java | 672 ++++++++++++++++++
.../invest/service/impl/IShopServiceImpl.java | 362 ++++++++++
.../invest/service/impl/IUserServiceImpl.java | 140 ++++
.../com/ruoyi/job/controller/InvestJob.java | 67 ++
.../java/com/ruoyi/task/CampusIMTTask.java | 81 +++
.../resources/mapper/invest/IItemMapper.xml | 91 +++
.../resources/mapper/invest/ILogMapper.xml | 98 +++
.../resources/mapper/invest/IShopMapper.xml | 136 ++++
.../resources/mapper/invest/IUserMapper.xml | 212 ++++++
53 files changed, 4713 insertions(+), 1 deletion(-)
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/AsyncManager.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/Threads.java
create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/RedisCache.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ThreadPoolConfig.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/api/PushPlusApi.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IItemController.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/ILogController.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IShopController.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IUserController.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IItem.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/ILog.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTCacheConstants.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTItemInfo.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IShop.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUser.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUserRequest.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/MapPoint.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IItemDto.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/ILogDto.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IShopDto.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IUserDto.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IItemVo.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/ILogVo.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IShopVo.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IUserVo.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IItemMapper.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/ILogMapper.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IShopMapper.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IUserMapper.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IIItemService.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogFactory.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogService.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTService.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IShopService.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IUserService.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IItemServiceImpl.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTLogServiceImpl.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTServiceImpl.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IShopServiceImpl.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IUserServiceImpl.java
create mode 100644 ruoyi-modules/intc-invest/src/main/java/com/ruoyi/task/CampusIMTTask.java
create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IItemMapper.xml
create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/ILogMapper.xml
create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IShopMapper.xml
create mode 100644 ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IUserMapper.xml
diff --git a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestProdService.java b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestProdService.java
index f7605a7..ff44247 100644
--- a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestProdService.java
+++ b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestProdService.java
@@ -38,5 +38,44 @@ public interface RemoteInvestProdService
@RequestMapping(value = "/job/generateFutureStocksBill",method = RequestMethod.POST)
public R generateFutureStocksBill();
+ /**
+ * 批量修改用户随机预约的时间
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/updateUserMinuteBatch",method = RequestMethod.POST)
+ public R updateUserMinuteBatch();
+
+ /**
+ * 11点期间,每分钟执行一次批量获得旅行奖励
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/getTravelRewardBatch",method = RequestMethod.POST)
+ public R getTravelRewardBatch();
+
+ /**
+ * 9点期间,每分钟执行一次预约茅台
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/reservationBatchTask",method = RequestMethod.POST)
+ public R reservationBatchTask();
+
+ /**
+ * 更新茅台版本,门店列表,预约商品列表
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/refreshAll",method = RequestMethod.POST)
+ public R refreshAll();
+
+ /**
+ * 18.05分获取申购结果
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/appointmentResults",method = RequestMethod.POST)
+ public R appointmentResults();
}
diff --git a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestService.java b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestService.java
index 74668fc..ad10a8b 100644
--- a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestService.java
+++ b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/RemoteInvestService.java
@@ -36,4 +36,44 @@ public interface RemoteInvestService
@RequestMapping(value = "/job/generateFutureStocksBill",method = RequestMethod.POST)
public R generateFutureStocksBill();
+ /**
+ * 批量修改用户随机预约的时间
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/updateUserMinuteBatch",method = RequestMethod.POST)
+ public R updateUserMinuteBatch();
+
+ /**
+ * 11点期间,每分钟执行一次批量获得旅行奖励
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/getTravelRewardBatch",method = RequestMethod.POST)
+ public R getTravelRewardBatch();
+
+ /**
+ * 9点期间,每分钟执行一次预约茅台
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/reservationBatchTask",method = RequestMethod.POST)
+ public R reservationBatchTask();
+
+ /**
+ * 更新茅台版本,门店列表,预约商品列表
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/refreshAll",method = RequestMethod.POST)
+ public R refreshAll();
+
+ /**
+ * 18.05分获取申购结果
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/appointmentResults",method = RequestMethod.POST)
+ public R appointmentResults();
+
}
diff --git a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/factory/RemoteInvestFallbackFactory.java b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/factory/RemoteInvestFallbackFactory.java
index 06056dc..fef3184 100644
--- a/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/factory/RemoteInvestFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-invest/src/main/java/com/ruoyi/api/invest/factory/RemoteInvestFallbackFactory.java
@@ -39,6 +39,31 @@ public class RemoteInvestFallbackFactory implements FallbackFactoryorg.projectlombok
lombok
-
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.apache.commons
+ commons-pool2
+
com.google.zxing
core
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/AsyncManager.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/AsyncManager.java
new file mode 100644
index 0000000..33f2f7a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/AsyncManager.java
@@ -0,0 +1,53 @@
+package com.ruoyi.common.core.manager;
+
+
+import com.ruoyi.common.core.utils.SpringUtils;
+
+import java.util.TimerTask;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 异步任务管理器
+ *
+ * @author ruoyi
+ */
+public class AsyncManager {
+ /**
+ * 操作延迟10毫秒
+ */
+ private final int OPERATE_DELAY_TIME = 10;
+
+ /**
+ * 异步操作任务调度线程池
+ */
+ private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
+
+ /**
+ * 单例模式
+ */
+ private AsyncManager() {
+ }
+
+ private static AsyncManager me = new AsyncManager();
+
+ public static AsyncManager me() {
+ return me;
+ }
+
+ /**
+ * 执行任务
+ *
+ * @param task 任务
+ */
+ public void execute(TimerTask task) {
+ executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 停止任务线程池
+ */
+ public void shutdown() {
+ Threads.shutdownAndAwaitTermination(executor);
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/Threads.java
new file mode 100644
index 0000000..46fe5de
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/manager/Threads.java
@@ -0,0 +1,73 @@
+package com.ruoyi.common.core.manager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.*;
+
+/**
+ * 线程相关工具类.
+ *
+ * @author ruoyi
+ */
+public class Threads {
+ private static final Logger logger = LoggerFactory.getLogger(Threads.class);
+
+ /**
+ * sleep等待,单位为毫秒
+ */
+ public static void sleep(long milliseconds) {
+ try {
+ Thread.sleep(milliseconds);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+
+ /**
+ * 停止线程池
+ * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
+ * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
+ * 如果仍然超時,則強制退出.
+ * 另对在shutdown时线程本身被调用中断做了处理.
+ */
+ public static void shutdownAndAwaitTermination(ExecutorService pool) {
+ if (pool != null && !pool.isShutdown()) {
+ pool.shutdown();
+ try {
+ if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+ pool.shutdownNow();
+ if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
+ logger.info("Pool did not terminate");
+ }
+ }
+ } catch (InterruptedException ie) {
+ pool.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ /**
+ * 打印线程异常信息
+ */
+ public static void printException(Runnable r, Throwable t) {
+ if (t == null && r instanceof Future>) {
+ try {
+ Future> future = (Future>) r;
+ if (future.isDone()) {
+ future.get();
+ }
+ } catch (CancellationException ce) {
+ t = ce;
+ } catch (ExecutionException ee) {
+ t = ee.getCause();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ if (t != null) {
+ logger.error(t.getMessage(), t);
+ }
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/RedisCache.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/RedisCache.java
new file mode 100644
index 0000000..d3f11c4
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/RedisCache.java
@@ -0,0 +1,256 @@
+package com.ruoyi.common.core.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ *
+ * @author ruoyi
+ **/
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+@Component
+public class RedisCache {
+ @Autowired
+ public RedisTemplate redisTemplate;
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ */
+ public void setCacheObject(final String key, final T value) {
+ redisTemplate.opsForValue().set(key, value);
+ }
+
+ /**
+ * 缓存基本的对象,Integer、String、实体类等
+ *
+ * @param key 缓存的键值
+ * @param value 缓存的值
+ * @param timeout 时间
+ * @param timeUnit 时间颗粒度
+ */
+ public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
+ redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+ }
+
+ /**
+ * 设置有效时间
+ *
+ * @param key Redis键
+ * @param timeout 超时时间
+ * @return true=设置成功;false=设置失败
+ */
+ public boolean expire(final String key, final long timeout) {
+ return expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+ /**
+ * 设置有效时间
+ *
+ * @param key Redis键
+ * @param timeout 超时时间
+ * @param unit 时间单位
+ * @return true=设置成功;false=设置失败
+ */
+ public boolean expire(final String key, final long timeout, final TimeUnit unit) {
+ return redisTemplate.expire(key, timeout, unit);
+ }
+
+ /**
+ * 获取有效时间
+ *
+ * @param key Redis键
+ * @return 有效时间
+ */
+ public long getExpire(final String key) {
+ return redisTemplate.getExpire(key);
+ }
+
+ /**
+ * 判断 key是否存在
+ *
+ * @param key 键
+ * @return true 存在 false不存在
+ */
+ public Boolean hasKey(String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+ /**
+ * 获得缓存的基本对象。
+ *
+ * @param key 缓存键值
+ * @return 缓存键值对应的数据
+ */
+ public T getCacheObject(final String key) {
+ ValueOperations operation = redisTemplate.opsForValue();
+ return operation.get(key);
+ }
+
+ /**
+ * 删除单个对象
+ *
+ * @param key
+ */
+ public boolean deleteObject(final String key) {
+ return redisTemplate.delete(key);
+ }
+
+ /**
+ * 删除集合对象
+ *
+ * @param collection 多个对象
+ * @return
+ */
+ public boolean deleteObject(final Collection collection) {
+ return redisTemplate.delete(collection) > 0;
+ }
+
+ /**
+ * 缓存List数据
+ *
+ * @param key 缓存的键值
+ * @param dataList 待缓存的List数据
+ * @return 缓存的对象
+ */
+ public long setCacheList(final String key, final List dataList) {
+ Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+ return count == null ? 0 : count;
+ }
+
+ /**
+ * 重新set缓存List数据
+ *
+ * @param key 缓存的键值
+ * @param dataList 待缓存的List数据
+ * @return 缓存的对象
+ */
+ public long reSetCacheList(final String key, final List dataList) {
+ this.deleteObject(key);
+ Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+ return count == null ? 0 : count;
+ }
+
+ /**
+ * 获得缓存的list对象
+ *
+ * @param key 缓存的键值
+ * @return 缓存键值对应的数据
+ */
+ public List getCacheList(final String key) {
+ return redisTemplate.opsForList().range(key, 0, -1);
+ }
+
+ /**
+ * 缓存Set
+ *
+ * @param key 缓存键值
+ * @param dataSet 缓存的数据
+ * @return 缓存数据的对象
+ */
+ public BoundSetOperations setCacheSet(final String key, final Set dataSet) {
+ BoundSetOperations setOperation = redisTemplate.boundSetOps(key);
+ Iterator it = dataSet.iterator();
+ while (it.hasNext()) {
+ setOperation.add(it.next());
+ }
+ return setOperation;
+ }
+
+ /**
+ * 获得缓存的set
+ *
+ * @param key
+ * @return
+ */
+ public Set getCacheSet(final String key) {
+ return redisTemplate.opsForSet().members(key);
+ }
+
+ /**
+ * 缓存Map
+ *
+ * @param key
+ * @param dataMap
+ */
+ public void setCacheMap(final String key, final Map dataMap) {
+ if (dataMap != null) {
+ redisTemplate.opsForHash().putAll(key, dataMap);
+ }
+ }
+
+ /**
+ * 获得缓存的Map
+ *
+ * @param key
+ * @return
+ */
+ public Map getCacheMap(final String key) {
+ return redisTemplate.opsForHash().entries(key);
+ }
+
+ /**
+ * 往Hash中存入数据
+ *
+ * @param key Redis键
+ * @param hKey Hash键
+ * @param value 值
+ */
+ public void setCacheMapValue(final String key, final String hKey, final T value) {
+ redisTemplate.opsForHash().put(key, hKey, value);
+ }
+
+ /**
+ * 获取Hash中的数据
+ *
+ * @param key Redis键
+ * @param hKey Hash键
+ * @return Hash中的对象
+ */
+ public T getCacheMapValue(final String key, final String hKey) {
+ HashOperations opsForHash = redisTemplate.opsForHash();
+ return opsForHash.get(key, hKey);
+ }
+
+ /**
+ * 获取多个Hash中的数据
+ *
+ * @param key Redis键
+ * @param hKeys Hash键集合
+ * @return Hash对象集合
+ */
+ public List getMultiCacheMapValue(final String key, final Collection
+
+ cn.hutool
+ hutool-all
+ 5.8.23
+
+
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java
index 4d14029..06044be 100644
--- a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/IntcInvestApplication.java
@@ -6,6 +6,9 @@ import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+import java.time.ZoneOffset;
+import java.util.TimeZone;
+
/**
* 系统模块
*
@@ -19,6 +22,8 @@ public class IntcInvestApplication
{
public static void main(String[] args)
{
+ //设置+8时区,避免因为时区问题导致预约时间不正确
+ TimeZone.setDefault(TimeZone.getTimeZone(ZoneOffset.of("+8")));
SpringApplication.run(IntcInvestApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 智聪投资业务模块启动成功 ლ(´ڡ`ლ)゙");
}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ThreadPoolConfig.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ThreadPoolConfig.java
new file mode 100644
index 0000000..ecba066
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/config/ThreadPoolConfig.java
@@ -0,0 +1,59 @@
+package com.ruoyi.config;
+
+import com.ruoyi.common.core.manager.Threads;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * 线程池配置
+ *
+ * @author ruoyi
+ **/
+@Configuration
+public class ThreadPoolConfig {
+ // 核心线程池大小
+ private int corePoolSize = 50;
+
+ // 最大可创建的线程数
+ private int maxPoolSize = 200;
+
+ // 队列最大长度
+ private int queueCapacity = 1000;
+
+ // 线程池维护线程所允许的空闲时间
+ private int keepAliveSeconds = 300;
+
+ @Bean(name = "threadPoolTaskExecutor")
+ public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ executor.setMaxPoolSize(maxPoolSize);
+ executor.setCorePoolSize(corePoolSize);
+ executor.setQueueCapacity(queueCapacity);
+ executor.setKeepAliveSeconds(keepAliveSeconds);
+ // 线程池对拒绝任务(无线程可用)的处理策略
+ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+ return executor;
+ }
+
+ /**
+ * 执行周期性或定时任务
+ */
+ @Bean(name = "scheduledExecutorService")
+ protected ScheduledExecutorService scheduledExecutorService() {
+ return new ScheduledThreadPoolExecutor(corePoolSize,
+ new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
+ new ThreadPoolExecutor.CallerRunsPolicy()) {
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+ Threads.printException(r, t);
+ }
+ };
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/api/PushPlusApi.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/api/PushPlusApi.java
new file mode 100644
index 0000000..b6857a2
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/api/PushPlusApi.java
@@ -0,0 +1,66 @@
+package com.ruoyi.invest.api;
+
+
+import cn.hutool.http.HttpUtil;
+import com.ruoyi.common.core.manager.AsyncManager;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.invest.domain.ILog;
+import com.ruoyi.invest.domain.IUser;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimerTask;
+
+/**
+ * @author zhiyuan
+ */
+public class PushPlusApi {
+
+
+ public static void sendNotice(IUser iUser, ILog operLog) {
+ String token = iUser.getPushPlusToken();
+ if (StringUtils.isEmpty(token)) {
+ return;
+ }
+ String title, content;
+ if (operLog.getStatus() == "0") {
+ //预约成功
+ title = iUser.getRemark() + "-i茅台执行成功";
+ content = iUser.getMobile() + System.lineSeparator() + operLog.getLogContent();
+ AsyncManager.me().execute(sendNotice(token, title, content, "txt"));
+ } else {
+ //预约失败
+ title = iUser.getRemark() + "-i茅台执行失败";
+ content = iUser.getMobile() + System.lineSeparator() + operLog.getLogContent();
+ AsyncManager.me().execute(sendNotice(token, title, content, "txt"));
+ }
+
+
+ }
+
+ /**
+ * push推送
+ *
+ * @param token token
+ * @param title 消息标题
+ * @param content 具体消息内容
+ * @param template 发送消息模板
+ */
+ public static TimerTask sendNotice(String token, String title, String content, String template) {
+ return new TimerTask() {
+ @Override
+ public void run() {
+ String url = "http://www.pushplus.plus/send";
+ Map map = new HashMap<>();
+ map.put("token", token);
+ map.put("title", title);
+ map.put("content", content);
+ if (StringUtils.isEmpty(template)) {
+ map.put("template", "html");
+ }
+ HttpUtil.post(url, map);
+ }
+ };
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IItemController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IItemController.java
new file mode 100644
index 0000000..86eb79d
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IItemController.java
@@ -0,0 +1,60 @@
+package com.ruoyi.invest.controller;
+
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.invest.domain.dto.IItemDto;
+import com.ruoyi.invest.domain.vo.IItemVo;
+import com.ruoyi.invest.service.IIItemService;
+import com.ruoyi.invest.service.IShopService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 预约项目Controller
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@Api(tags=" 预约项目")
+@RestController
+@RequestMapping("/iitem")
+public class IItemController extends BaseController
+{
+
+ @Resource
+ private IIItemService iItemService;
+
+ @Resource
+ private IShopService iShopService;
+ /**
+ * 查询预约项目列表
+ */
+ @ApiOperation(value="查询预约项目列表",response = IItemVo.class)
+ @RequiresPermissions("invest:iitem:list")
+ @GetMapping("/list")
+ public TableDataInfo list(IItemDto iItemDto)
+ {
+ startPage();
+ List list = iItemService.selectIItemList(iItemDto);
+ return getDataTable(list);
+ }
+
+ /**
+ * 刷新i茅台预约商品列表
+ */
+ @GetMapping(value = "/refresh", name = "刷新i茅台预约商品列表")
+ public AjaxResult refreshItem() {
+ iShopService.refreshItem();
+ return success("刷新成功");
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/ILogController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/ILogController.java
new file mode 100644
index 0000000..ee763ae
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/ILogController.java
@@ -0,0 +1,66 @@
+package com.ruoyi.invest.controller;
+
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.invest.domain.dto.ILogDto;
+import com.ruoyi.invest.domain.vo.ILogVo;
+import com.ruoyi.invest.service.IMTLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 操作日志Controller
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@Api(tags=" 操作日志")
+@RestController
+@RequestMapping("/ilog")
+public class ILogController extends BaseController {
+ @Resource
+ private IMTLogService iLogService;
+
+ /**
+ * 查询操作日志列表
+ */
+ @ApiOperation(value="查询操作日志列表",response = ILogVo.class)
+ @RequiresPermissions("invest:ilog:list")
+ @GetMapping("/list")
+ public TableDataInfo list(ILogDto iLogDto)
+ {
+ startPage();
+ List list = iLogService.selectILogList(iLogDto);
+ return getDataTable(list);
+ }
+
+ /**
+ * 删除操作日志
+ */
+ @ApiOperation(value="删除操作日志")
+ @RequiresPermissions("invest:ilog:remove")
+ @Log(title = "操作日志", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{logIds}")
+ public AjaxResult remove(@PathVariable Long[] logIds)
+ {
+ return toAjax(iLogService.deleteILogByLogIds(logIds));
+ }
+
+ @PreAuthorize("@ss.resourceAuth()")
+ @DeleteMapping(value = "/clean", name = "操作日志-清空")
+ public AjaxResult clean() {
+ iLogService.cleanLog();
+ return toAjax(1);
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IShopController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IShopController.java
new file mode 100644
index 0000000..849bea4
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IShopController.java
@@ -0,0 +1,58 @@
+package com.ruoyi.invest.controller;
+
+
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.invest.domain.dto.IShopDto;
+import com.ruoyi.invest.domain.vo.IShopVo;
+import com.ruoyi.invest.service.IShopService;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * i茅台商品Controller
+ *
+ * @author oddfar
+ * @date 2023-07-05
+ */
+@RestController
+@RequestMapping("/ishop")
+@RequiredArgsConstructor
+public class IShopController extends BaseController {
+
+ @Resource
+ private IShopService iShopService;
+
+ /**
+ * 查询门店列表列表
+ */
+ @ApiOperation(value="查询门店列表列表",response = IShopVo.class)
+ @RequiresPermissions("invest:ishop:list")
+ @GetMapping("/list")
+ public TableDataInfo list(IShopDto iShopDto)
+ {
+ startPage();
+ List list = iShopService.selectIShopList(iShopDto);
+ return getDataTable(list);
+ }
+
+
+ /**
+ * 刷新i茅台商品列表
+ */
+ @GetMapping(value = "/refresh", name = "刷新i茅台门店列表")
+ public AjaxResult refreshShop() {
+ iShopService.refreshShop();
+ return toAjax(1);
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IUserController.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IUserController.java
new file mode 100644
index 0000000..8206be4
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/controller/IUserController.java
@@ -0,0 +1,177 @@
+package com.ruoyi.invest.controller;
+
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.invest.domain.IShop;
+import com.ruoyi.invest.domain.IUser;
+import com.ruoyi.invest.domain.dto.IUserDto;
+import com.ruoyi.invest.domain.vo.IUserVo;
+import com.ruoyi.invest.mapper.IUserMapper;
+import com.ruoyi.invest.service.IMTService;
+import com.ruoyi.invest.service.IShopService;
+import com.ruoyi.invest.service.IUserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 用户管理Controller
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@Api(tags=" 用户管理")
+@RestController
+@RequestMapping("/iuser")
+public class IUserController extends BaseController {
+
+ @Resource
+ private IUserService iUserService;
+ @Resource
+ private IUserMapper iUserMapper;
+ @Resource
+ private IMTService imtService;
+ @Resource
+ private IShopService iShopService;
+ /**
+ * 查询用户管理列表
+ */
+ @ApiOperation(value="查询用户管理列表",response = IUserVo.class)
+ @RequiresPermissions("invest:iuser:list")
+ @GetMapping("/list")
+ public TableDataInfo list(IUserDto iUserDto)
+ {
+ startPage();
+ List list = iUserService.selectIUserList(iUserDto);
+ return getDataTable(list);
+ }
+
+ /**
+ * 发送验证码
+ */
+ @GetMapping(value = "/sendCode", name = "发送验证码")
+ public R sendCode(String mobile, String deviceId) {
+ imtService.sendCode(mobile, deviceId);
+ return R.ok();
+ }
+
+ /**
+ * 预约
+ */
+ @GetMapping(value = "/reservation", name = "预约")
+ public R reservation(String mobile) {
+ IUser user = iUserMapper.selectIUserByMobile(Long.parseLong(mobile));
+ if (user == null) {
+ return R.fail("用户不存在");
+ }
+ if (StringUtils.isEmpty(user.getItemCode())) {
+ return R.fail("商品预约code为空");
+ }
+
+ imtService.reservation(user);
+ return R.ok();
+ }
+
+ /**
+ * 小茅运旅行活动
+ */
+ @GetMapping(value = "/travelReward", name = "旅行")
+ public R travelReward(String mobile) {
+ IUser user = iUserMapper.selectIUserByMobile(Long.parseLong(mobile));
+ if (user == null) {
+ return R.fail("用户不存在");
+ } else {
+ imtService.getTravelReward(user);
+ return R.ok();
+ }
+ }
+
+ /**
+ * 登录
+ */
+ @GetMapping(value = "/login", name = "登录")
+ public R login(String mobile, String code, String deviceId) {
+ imtService.login(mobile, code, deviceId);
+
+ return R.ok();
+ }
+
+
+ /**
+ * 获取I茅台用户详细信息
+ */
+
+ @GetMapping(value = "/{mobile}", name = "获取I茅台用户详细信息")
+ public R getInfo(@PathVariable("mobile") Long mobile) {
+ return R.ok(iUserMapper.selectIUserByMobile(mobile));
+ }
+
+
+ /**
+ * 新增用户管理
+ */
+ @ApiOperation(value="新增用户管理")
+ @RequiresPermissions("invest:iuser:add")
+ @Log(title = "用户管理", businessType = BusinessType.INSERT)
+ @PostMapping
+ public AjaxResult add(@RequestBody IUser iUser)
+ {
+ IShop iShop = iShopService.selectIShopByIShopId(iUser.getIshopId());
+ if (iShop == null) {
+ throw new ServiceException("门店商品id不存在");
+ }
+ iUser.setLng(iShop.getLng());
+ iUser.setLat(iShop.getLat());
+ iUser.setProvinceName(iShop.getProvinceName());
+ iUser.setCityName(iShop.getCityName());
+
+
+ return toAjax(iUserService.insertIUser(iUser));
+ }
+
+
+ /**
+ * 修改用户管理
+ */
+ @ApiOperation(value="修改用户管理")
+ @RequiresPermissions("invest:iuser:edit")
+ @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+ @PutMapping
+ public AjaxResult edit(@RequestBody IUser iUser)
+ {
+ IShop iShop = iShopService.selectIShopByIShopId(iUser.getIshopId());
+ if (iShop == null) {
+ throw new ServiceException("门店id不存在");
+ }
+ iUser.setLng(iShop.getLng());
+ iUser.setLat(iShop.getLat());
+ iUser.setProvinceName(iShop.getProvinceName());
+ iUser.setCityName(iShop.getCityName());
+
+ return toAjax(iUserService.updateIUser(iUser));
+ }
+
+ /**
+ * 删除用户管理
+ */
+ @ApiOperation(value="删除用户管理")
+ @RequiresPermissions("invest:iuser:remove")
+ @Log(title = "用户管理", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{mobiles}")
+ public AjaxResult remove(@PathVariable Long[] mobiles)
+ {
+ return toAjax(iUserService.deleteIUser(mobiles));
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IItem.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IItem.java
new file mode 100644
index 0000000..b7fde4d
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IItem.java
@@ -0,0 +1,76 @@
+package com.ruoyi.invest.domain;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+
+/**
+ * 预约项目对象 i_item
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("预约项目对象")
+@Data
+public class IItem extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 商品id */
+ @ApiModelProperty(value="商品id")
+ @Excel(name = "商品id")
+ private Long itemId;
+
+ /** 预约商品Code */
+ @ApiModelProperty(value="预约商品Code")
+ @Excel(name = "预约商品Code")
+ private String itemCode;
+
+ /** 标题 */
+ @ApiModelProperty(value="标题")
+ @Excel(name = "标题")
+ private String title;
+
+ /** 内容 */
+ @ApiModelProperty(value="内容")
+ @Excel(name = "内容")
+ private String content;
+
+ /** 图片 */
+ @ApiModelProperty(value="图片")
+ @Excel(name = "图片")
+ private String picture;
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("itemId", getItemId())
+ .append("itemCode", getItemCode())
+ .append("title", getTitle())
+ .append("content", getContent())
+ .append("picture", getPicture())
+ .append("createTime", getCreateTime())
+ .toString();
+ }
+
+ public IItem() {
+ }
+ public IItem(JSONObject item) {
+ this.itemCode = item.getString("itemCode");
+ this.title = item.getString("title");
+ this.content = item.getString("content");
+ this.picture = item.getString("picture");
+ this.createTime = new Date();
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/ILog.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/ILog.java
new file mode 100644
index 0000000..843569a
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/ILog.java
@@ -0,0 +1,78 @@
+package com.ruoyi.invest.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 操作日志对象 i_log
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("操作日志对象")
+@Data
+public class ILog extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 日志id */
+ private Long logId;
+
+ /** 用户 */
+ @ApiModelProperty(value="用户")
+ @Excel(name = "用户")
+ private Long mobile;
+
+ /** 日志记录内容 */
+ @ApiModelProperty(value="日志记录内容")
+ @Excel(name = "日志记录内容")
+ private String logContent;
+
+ /** 操作状态 */
+ @ApiModelProperty(value="操作状态")
+ @Excel(name = "操作状态")
+ private String status;
+
+ /**
+ * 操作时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date operTime;
+
+ /** 创建者id */
+ @ApiModelProperty(value="创建者id")
+ @Excel(name = "创建者id")
+ private Long createUser;
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("logId", getLogId())
+ .append("mobile", getMobile())
+ .append("logContent", getLogContent())
+ .append("status", getStatus())
+ .append("operTime", getOperTime())
+ .append("createUser", getCreateUser())
+ .append("createBy", getCreateBy())
+ .toString();
+ }
+
+ private Map params;
+
+ public Map getParams() {
+ if (params == null) {
+ params = new HashMap<>();
+ }
+ return params;
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTCacheConstants.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTCacheConstants.java
new file mode 100644
index 0000000..35cf9b7
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTCacheConstants.java
@@ -0,0 +1,15 @@
+package com.ruoyi.invest.domain;
+
+/**
+ * i茅台缓存常量
+ *
+ * @author oddfar
+ * @date 2024/4/12
+ */
+public interface IMTCacheConstants {
+ String MT_VERSION = "mt_version";
+
+ String MT_SESSION_ID = "mt_session_id";
+
+ String MT_SHOP_LIST = "mt_shop_list";
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTItemInfo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTItemInfo.java
new file mode 100644
index 0000000..ddd7059
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IMTItemInfo.java
@@ -0,0 +1,27 @@
+package com.ruoyi.invest.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * i茅台预约商品信息
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IMTItemInfo {
+
+ private String shopId;
+
+ private int count;
+
+ private String itemId;
+
+ /**
+ * 库存
+ */
+ private int inventory;
+
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IShop.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IShop.java
new file mode 100644
index 0000000..5001855
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IShop.java
@@ -0,0 +1,124 @@
+package com.ruoyi.invest.domain;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 门店列表对象 i_shop
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("门店列表对象")
+@Data
+public class IShop extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 门店id */
+ private String shopId;
+
+ /** 门店id */
+ @ApiModelProperty(value="门店id")
+ @Excel(name = "门店id")
+ private String iShopId;
+
+ /** 省份 */
+ @ApiModelProperty(value="省份")
+ @Excel(name = "省份")
+ private String provinceName;
+
+ /** 城市 */
+ @ApiModelProperty(value="城市")
+ @Excel(name = "城市")
+ private String cityName;
+
+ /** 地区 */
+ @ApiModelProperty(value="地区")
+ @Excel(name = "地区")
+ private String districtName;
+
+ /** 完整地址 */
+ @ApiModelProperty(value="完整地址")
+ @Excel(name = "完整地址")
+ private String fullAddress;
+
+ /** 经度 */
+ @ApiModelProperty(value="经度")
+ @Excel(name = "经度")
+ private String lat;
+
+ /** 纬度 */
+ @ApiModelProperty(value="纬度")
+ @Excel(name = "纬度")
+ private String lng;
+
+ /** 名称 */
+ @ApiModelProperty(value="名称")
+ @Excel(name = "名称")
+ private String name;
+
+ /** 公司名称 */
+ @ApiModelProperty(value="公司名称")
+ @Excel(name = "公司名称")
+ private String tenantName;
+
+ private Double distance;
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("shopId", getShopId())
+ .append("iShopId", getIShopId())
+ .append("provinceName", getProvinceName())
+ .append("cityName", getCityName())
+ .append("districtName", getDistrictName())
+ .append("fullAddress", getFullAddress())
+ .append("lat", getLat())
+ .append("lng", getLng())
+ .append("name", getName())
+ .append("tenantName", getTenantName())
+ .append("createTime", getCreateTime())
+ .toString();
+ }
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+ public IShop() {
+ }
+
+ public IShop(String iShopId, JSONObject jsonObject) {
+ this.iShopId = iShopId;
+ this.provinceName = jsonObject.getString("provinceName");
+ this.cityName = jsonObject.getString("cityName");
+ this.districtName = jsonObject.getString("districtName");
+ this.fullAddress = jsonObject.getString("fullAddress");
+ this.lat = jsonObject.getString("lat");
+ this.lng = jsonObject.getString("lng");
+ this.name = jsonObject.getString("name");
+ this.tenantName = jsonObject.getString("tenantName");
+ this.createTime = new Date();
+
+ }
+
+ private Map params;
+
+
+ public Map getParams() {
+ if (params == null) {
+ params = new HashMap<>();
+ }
+ return params;
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUser.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUser.java
new file mode 100644
index 0000000..853b403
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUser.java
@@ -0,0 +1,112 @@
+package com.ruoyi.invest.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 用户管理对象 i_user
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("用户管理对象")
+@Data
+public class IUser extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 手机号 */
+ private Long mobile;
+
+ /** 用户id */
+ @ApiModelProperty(value="用户id")
+ @Excel(name = "用户id")
+ private Long userId;
+
+ /** token */
+ private String token;
+
+ /** cookie */
+ private String cookie;
+
+ /** 设备id */
+ private String deviceId;
+
+ /** 预约项目code */
+ @ApiModelProperty(value="预约项目code)")
+ @NotNull(message="预约项目code不能为空")
+ @Excel(name = "预约项目code")
+ private String itemCode;
+
+ /** 门店id */
+ @ApiModelProperty(value="门店id")
+ @Excel(name = "门店id")
+ private String ishopId;
+
+ /** 省份 */
+ @ApiModelProperty(value="省份")
+ @Excel(name = "省份")
+ private String provinceName;
+
+ /** 城市 */
+ @ApiModelProperty(value="城市")
+ @Excel(name = "城市")
+ private String cityName;
+
+ /** 地址 */
+ private String address;
+
+ /** 经度 */
+ private String lat;
+
+ /** 纬度 */
+ private String lng;
+
+ /** 预约执行分钟 */
+ private Integer minute;
+
+ /** 类型 */
+ @ApiModelProperty(value="类型")
+ @Excel(name = "类型")
+ private String shopType;
+
+ /** 随机时间预约 */
+ @ApiModelProperty(value="随机时间预约")
+ @Excel(name = "随机时间预约")
+ private String randomMinute;
+
+ /** 推送token */
+ private String pushPlusToken;
+
+ /** 返回json */
+ private String jsonResult;
+
+
+ /** 删除标识 */
+ private Integer delFlag;
+
+ /** 创建者id */
+ private Long createUser;
+
+ /** 更新者 */
+ @ApiModelProperty(value="更新者")
+ @Excel(name = "更新者")
+ private String updateUser;
+
+ /** 备注 */
+ private String remark;
+
+ /**
+ * token过期时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date expireTime;
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUserRequest.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUserRequest.java
new file mode 100644
index 0000000..01a6cf5
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/IUserRequest.java
@@ -0,0 +1,103 @@
+package com.ruoyi.invest.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * i茅台用户请求对象
+ */
+@Data
+public class IUserRequest {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 手机号
+ */
+ private Long mobile;
+
+ /**
+ * 用户ID
+ */
+ private Long userId;
+
+ /**
+ * token
+ */
+ private String token;
+
+ /**
+ * cookie
+ */
+ private String cookie;
+
+ /**
+ * 设备id
+ */
+ private String deviceId;
+
+ /**
+ * 商品预约code,用@间隔
+ */
+ private String itemCode;
+
+ /**
+ * 完整地址
+ */
+ private String address;
+
+ /**
+ * 预约的分钟(1-59)
+ */
+ private int minute;
+
+ /**
+ * 随机分钟预约,9点取一个时间(0:随机,1:不随机)
+ */
+ private String randomMinute;
+
+ /**
+ * 类型
+ */
+ private int shopType;
+
+ /**
+ * 门店商品ID
+ */
+ private String ishopId;
+
+ /**
+ * push_plus_token
+ */
+ private String pushPlusToken;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * token过期时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date expireTime;
+
+ private Map params;
+
+ public Map getParams() {
+ if (params == null) {
+ params = new HashMap<>();
+ }
+ return params;
+ }
+
+ public int getMinute() {
+ if (minute > 59 || minute < 1) {
+ this.minute = 5;
+ }
+ return minute;
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/MapPoint.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/MapPoint.java
new file mode 100644
index 0000000..abb3034
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/MapPoint.java
@@ -0,0 +1,22 @@
+package com.ruoyi.invest.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MapPoint {
+
+ /**
+ * 纬度
+ */
+ private Double latitude;
+
+ /**
+ * 经度
+ */
+ private Double longitude;
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IItemDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IItemDto.java
new file mode 100644
index 0000000..e806732
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IItemDto.java
@@ -0,0 +1,31 @@
+package com.ruoyi.invest.domain.dto;
+
+import lombok.Data;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+/**
+ * 预约项目Dto对象 i_item
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("预约项目Dto对象")
+@Data
+public class IItemDto implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 预约商品Code */
+ @ApiModelProperty(value="预约商品Code")
+ private String itemCode;
+
+ /** 标题 */
+ @ApiModelProperty(value="标题")
+ private String title;
+
+ /** 内容 */
+ @ApiModelProperty(value="内容")
+ private String content;
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/ILogDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/ILogDto.java
new file mode 100644
index 0000000..187a4c4
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/ILogDto.java
@@ -0,0 +1,39 @@
+package com.ruoyi.invest.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+/**
+ * 操作日志Dto对象 i_log
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("操作日志Dto对象")
+@Data
+public class ILogDto implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 用户 */
+ @ApiModelProperty(value="用户")
+ private Long mobile;
+
+ /** 日志记录内容 */
+ @ApiModelProperty(value="日志记录内容")
+ private String logContent;
+
+ /** 操作状态 */
+ @ApiModelProperty(value="操作状态")
+ private String status;
+
+ /** 操作时间 */
+ @ApiModelProperty(value="操作时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date operTime;
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IShopDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IShopDto.java
new file mode 100644
index 0000000..e30db63
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IShopDto.java
@@ -0,0 +1,40 @@
+package com.ruoyi.invest.domain.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+/**
+ * 门店列表Dto对象 i_shop
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("门店列表Dto对象")
+@Data
+public class IShopDto implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 门店id */
+ @ApiModelProperty(value="门店id")
+ private String iShopId;
+
+ /** 省份 */
+ @ApiModelProperty(value="省份")
+ private String provinceName;
+
+ /** 城市 */
+ @ApiModelProperty(value="城市")
+ private String cityName;
+
+ /** 地区 */
+ @ApiModelProperty(value="地区")
+ private String districtName;
+
+ /** 公司名称 */
+ @ApiModelProperty(value="公司名称")
+ private String tenantName;
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IUserDto.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IUserDto.java
new file mode 100644
index 0000000..aa045af
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/dto/IUserDto.java
@@ -0,0 +1,99 @@
+package com.ruoyi.invest.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+/**
+ * 用户管理Dto对象 i_user
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("用户管理Dto对象")
+@Data
+public class IUserDto implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 手机号 */
+ @ApiModelProperty(value="手机号")
+ private Long mobile;
+
+ /** token */
+ @ApiModelProperty(value="token")
+ private String token;
+
+ /** cookie */
+ @ApiModelProperty(value="cookie")
+ private String cookie;
+
+ /** 设备id */
+ @ApiModelProperty(value="设备id")
+ private String deviceId;
+
+ /** 预约项目code */
+ @ApiModelProperty(value="预约项目code")
+ private String itemCode;
+
+ /** 门店id */
+ @ApiModelProperty(value="门店id")
+ private String ishopId;
+
+ /** 省份 */
+ @ApiModelProperty(value="省份")
+ private String provinceName;
+
+ /** 城市 */
+ @ApiModelProperty(value="城市")
+ private String cityName;
+
+ /** 地址 */
+ @ApiModelProperty(value="地址")
+ private String address;
+
+ /** 经度 */
+ @ApiModelProperty(value="经度")
+ private String lat;
+
+ /** 纬度 */
+ @ApiModelProperty(value="纬度")
+ private String lng;
+
+ /** 预约执行分钟 */
+ @ApiModelProperty(value="预约执行分钟")
+ private Integer minute;
+
+ /** 类型 */
+ @ApiModelProperty(value="类型")
+ private Integer shopType;
+
+ /** 随机时间预约 */
+ @ApiModelProperty(value="随机时间预约")
+ private String randomMinute;
+
+ /** 推送token */
+ @ApiModelProperty(value="推送token")
+ private String pushPlusToken;
+
+ /** 返回json */
+ @ApiModelProperty(value="返回json")
+ private String jsonResult;
+
+ /** 到期时间 */
+ @ApiModelProperty(value="到期时间")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date expireTime;
+
+ /** 创建者id */
+ @ApiModelProperty(value="创建者id")
+ private String createUser;
+
+ /** 更新者 */
+ @ApiModelProperty(value="更新者")
+ private String updateUser;
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IItemVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IItemVo.java
new file mode 100644
index 0000000..10b252a
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IItemVo.java
@@ -0,0 +1,17 @@
+package com.ruoyi.invest.domain.vo;
+
+import com.ruoyi.invest.domain.IItem;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+/**
+ * 预约项目Vo对象 i_item
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("预约项目Vo对象")
+@Data
+public class IItemVo extends IItem
+{
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/ILogVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/ILogVo.java
new file mode 100644
index 0000000..33b91e0
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/ILogVo.java
@@ -0,0 +1,17 @@
+package com.ruoyi.invest.domain.vo;
+
+import com.ruoyi.invest.domain.ILog;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+/**
+ * 操作日志Vo对象 i_log
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("操作日志Vo对象")
+@Data
+public class ILogVo extends ILog
+{
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IShopVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IShopVo.java
new file mode 100644
index 0000000..6ba5fb2
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IShopVo.java
@@ -0,0 +1,17 @@
+package com.ruoyi.invest.domain.vo;
+
+import com.ruoyi.invest.domain.IShop;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+/**
+ * 门店列表Vo对象 i_shop
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("门店列表Vo对象")
+@Data
+public class IShopVo extends IShop
+{
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IUserVo.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IUserVo.java
new file mode 100644
index 0000000..2cffc5d
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/domain/vo/IUserVo.java
@@ -0,0 +1,17 @@
+package com.ruoyi.invest.domain.vo;
+
+import com.ruoyi.invest.domain.IUser;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+/**
+ * 用户管理Vo对象 i_user
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@ApiModel("用户管理Vo对象")
+@Data
+public class IUserVo extends IUser
+{
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IItemMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IItemMapper.java
new file mode 100644
index 0000000..8f83ef5
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IItemMapper.java
@@ -0,0 +1,82 @@
+package com.ruoyi.invest.mapper;
+
+import com.ruoyi.invest.domain.IItem;
+import com.ruoyi.invest.domain.dto.IItemDto;
+import com.ruoyi.invest.domain.vo.IItemVo;
+
+import java.util.List;
+
+/**
+ * 预约项目Mapper接口
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+public interface IItemMapper
+{
+ /**
+ * 查询预约项目
+ *
+ * @param itemId 预约项目主键
+ * @return 预约项目
+ */
+ public IItemVo selectIItemByItemId(Long itemId);
+
+ /**
+ * 查询预约项目列表
+ *
+ * @param iItemDto 预约项目
+ * @return 预约项目集合
+ */
+ public List selectIItemList(IItemDto iItemDto);
+
+ /**
+ * 新增预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ public int insertIItem(IItem iItem);
+
+ /**
+ * 修改预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ public int updateIItem(IItem iItem);
+
+ /**
+ * 删除预约项目
+ *
+ * @param itemId 预约项目主键
+ * @return 结果
+ */
+ public int deleteIItemByItemId(Long itemId);
+
+ /**
+ * 批量删除预约项目
+ *
+ * @param itemIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteIItemByItemIds(Long[] itemIds);
+
+ /**
+ * 逻辑删除预约项目
+ *
+ * @param itemId 预约项目主键
+ * @return 结果
+ */
+ public int removeIItemByItemId(Long itemId);
+
+ /**
+ * 批量逻辑删除预约项目
+ *
+ * @param itemIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int removeIItemByItemIds(Long[] itemIds);
+
+ void truncateItem();
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/ILogMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/ILogMapper.java
new file mode 100644
index 0000000..8a3c316
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/ILogMapper.java
@@ -0,0 +1,82 @@
+package com.ruoyi.invest.mapper;
+
+import com.ruoyi.invest.domain.ILog;
+import com.ruoyi.invest.domain.dto.ILogDto;
+import com.ruoyi.invest.domain.vo.ILogVo;
+
+import java.util.List;
+
+/**
+ * 操作日志Mapper接口
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+public interface ILogMapper
+{
+ /**
+ * 查询操作日志
+ *
+ * @param logId 操作日志主键
+ * @return 操作日志
+ */
+ public ILogVo selectILogByLogId(Long logId);
+
+ /**
+ * 查询操作日志列表
+ *
+ * @param iLogDto 操作日志
+ * @return 操作日志集合
+ */
+ public List selectILogList(ILogDto iLogDto);
+
+ /**
+ * 新增操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ public int insertILog(ILog iLog);
+
+ /**
+ * 修改操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ public int updateILog(ILog iLog);
+
+ /**
+ * 删除操作日志
+ *
+ * @param logId 操作日志主键
+ * @return 结果
+ */
+ public int deleteILogByLogId(Long logId);
+
+ /**
+ * 批量删除操作日志
+ *
+ * @param logIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteILogByLogIds(Long[] logIds);
+
+ /**
+ * 逻辑删除操作日志
+ *
+ * @param logId 操作日志主键
+ * @return 结果
+ */
+ public int removeILogByLogId(Long logId);
+
+ /**
+ * 批量逻辑删除操作日志
+ *
+ * @param logIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int removeILogByLogIds(Long[] logIds);
+
+ void cleanLog();
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IShopMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IShopMapper.java
new file mode 100644
index 0000000..1515ca2
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IShopMapper.java
@@ -0,0 +1,98 @@
+package com.ruoyi.invest.mapper;
+
+import com.ruoyi.invest.domain.IShop;
+import com.ruoyi.invest.domain.dto.IShopDto;
+import com.ruoyi.invest.domain.vo.IShopVo;
+
+import java.util.List;
+
+/**
+ * 门店列表Mapper接口
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+public interface IShopMapper
+{
+ /**
+ * 查询门店列表
+ *
+ * @param shopId 门店列表主键
+ * @return 门店列表
+ */
+ public IShopVo selectIShopByShopId(String shopId);
+
+ /**
+ * 查询门店列表列表
+ *
+ * @param iShopDto 门店列表
+ * @return 门店列表集合
+ */
+ public List selectIShopList(IShopDto iShopDto);
+
+ /**
+ * 新增门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ public int insertIShop(IShop iShop);
+
+ /**
+ * 修改门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ public int updateIShop(IShop iShop);
+
+ /**
+ * 删除门店列表
+ *
+ * @param shopId 门店列表主键
+ * @return 结果
+ */
+ public int deleteIShopByShopId(String shopId);
+
+ /**
+ * 批量删除门店列表
+ *
+ * @param shopIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteIShopByShopIds(String[] shopIds);
+
+ /**
+ * 逻辑删除门店列表
+ *
+ * @param shopId 门店列表主键
+ * @return 结果
+ */
+ public int removeIShopByShopId(String shopId);
+
+ /**
+ * 批量逻辑删除门店列表
+ *
+ * @param shopIds 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int removeIShopByShopIds(String[] shopIds);
+
+ void truncateShop();
+
+ /**
+ * 批量新增角色菜单信息
+ *
+ * @param iShopList 角色菜单列表
+ * @return 结果
+ */
+ public int batchInsertIShop(List iShopList);
+
+ /**
+ * 查询门店列表
+ *
+ * @param iShopId 门店列表主键
+ * @return 门店列表
+ */
+ public IShopVo selectIShopByIShopId(String iShopId);
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IUserMapper.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IUserMapper.java
new file mode 100644
index 0000000..35f1e5f
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/mapper/IUserMapper.java
@@ -0,0 +1,91 @@
+package com.ruoyi.invest.mapper;
+
+import com.ruoyi.invest.domain.IUser;
+import com.ruoyi.invest.domain.dto.IUserDto;
+import com.ruoyi.invest.domain.vo.IUserVo;
+
+import java.util.List;
+
+/**
+ * 用户管理Mapper接口
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+public interface IUserMapper
+{
+ /**
+ * 查询用户管理
+ *
+ * @param mobile 用户管理主键
+ * @return 用户管理
+ */
+ public IUserVo selectIUserByMobile(Long mobile);
+
+ /**
+ * 查询用户管理列表
+ *
+ * @param iUserDto 用户管理
+ * @return 用户管理集合
+ */
+ public List selectIUserList(IUserDto iUserDto);
+
+ /**
+ * 新增用户管理
+ *
+ * @param iUser 用户管理
+ * @return 结果
+ */
+ public int insertIUser(IUser iUser);
+
+ /**
+ * 修改用户管理
+ *
+ * @param iUser 用户管理
+ * @return 结果
+ */
+ public int updateIUser(IUser iUser);
+
+ /**
+ * 删除用户管理
+ *
+ * @param mobile 用户管理主键
+ * @return 结果
+ */
+ public int deleteIUserByMobile(Long mobile);
+
+ /**
+ * 批量删除用户管理
+ *
+ * @param mobiles 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int deleteIUserByMobiles(Long[] mobiles);
+
+ /**
+ * 逻辑删除用户管理
+ *
+ * @param mobile 用户管理主键
+ * @return 结果
+ */
+ public int removeIUserByMobile(Long mobile);
+
+ /**
+ * 批量逻辑删除用户管理
+ *
+ * @param mobiles 需要删除的数据主键集合
+ * @return 结果
+ */
+ public int removeIUserByMobiles(Long[] mobiles);
+
+ List selectReservationUser();
+
+ /**
+ * 通过预约执行分钟查询预约用户列表
+ */
+ List selectReservationUserByMinute(IUserDto iUserDto);
+
+ void updateUserMinuteBatch();
+
+ void updateUserMinuteEven();
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IIItemService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IIItemService.java
new file mode 100644
index 0000000..dfa659e
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IIItemService.java
@@ -0,0 +1,63 @@
+package com.ruoyi.invest.service;
+
+import java.util.List;
+import com.ruoyi.invest.domain.IItem;
+import com.ruoyi.invest.domain.dto.IItemDto;
+import com.ruoyi.invest.domain.vo.IItemVo;
+
+/**
+ * 预约项目Service接口
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+public interface IIItemService
+{
+ /**
+ * 查询预约项目
+ *
+ * @param itemId 预约项目主键
+ * @return 预约项目
+ */
+ public IItemVo selectIItemByItemId(Long itemId);
+
+ /**
+ * 查询预约项目列表
+ *
+ * @param iItemDto 预约项目
+ * @return 预约项目集合
+ */
+ public List selectIItemList(IItemDto iItemDto);
+
+ /**
+ * 新增预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ public int insertIItem(IItem iItem);
+
+ /**
+ * 修改预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ public int updateIItem(IItem iItem);
+
+ /**
+ * 批量删除预约项目
+ *
+ * @param itemIds 需要删除的预约项目主键集合
+ * @return 结果
+ */
+ public int deleteIItemByItemIds(Long[] itemIds);
+
+ /**
+ * 删除预约项目信息
+ *
+ * @param itemId 预约项目主键
+ * @return 结果
+ */
+ public int deleteIItemByItemId(Long itemId);
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogFactory.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogFactory.java
new file mode 100644
index 0000000..9aa8276
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogFactory.java
@@ -0,0 +1,57 @@
+package com.ruoyi.invest.service;
+
+
+import com.ruoyi.common.core.manager.AsyncManager;
+import com.ruoyi.common.core.utils.SpringUtils;
+import com.ruoyi.invest.api.PushPlusApi;
+import com.ruoyi.invest.domain.ILog;
+import com.ruoyi.invest.domain.IUser;
+
+import java.util.Date;
+import java.util.TimerTask;
+
+/**
+ * i茅台日志记录
+ */
+public class IMTLogFactory {
+
+
+ public static void reservation(IUser iUser, String logContent) {
+ //{"code":2000,"data":{"successDesc":"申购完成,请于7月6日18:00查看预约申购结果","reservationList":[{"reservationId":17053404357,"sessionId":678,"shopId":"233331084001","reservationTime":1688608601720,"itemId":"10214","count":1}],"reservationDetail":{"desc":"申购成功后将以短信形式通知您,请您在申购成功次日18:00前确认支付方式,并在7天内完成提货。","lotteryTime":1688637600000,"cacheValidTime":1688637600000}}}
+ ILog operLog = new ILog();
+
+ operLog.setOperTime(new Date());
+
+ if (logContent.contains("报错")) {
+ //失败
+ operLog.setStatus("1");
+ } else {
+ operLog.setStatus("0");
+ }
+ operLog.setMobile(iUser.getMobile());
+ operLog.setCreateUser(iUser.getUserId());
+ operLog.setCreateBy(iUser.getCreateBy());
+ operLog.setLogContent(logContent);
+
+ AsyncManager.me().execute(recordOper(operLog));
+ //推送
+ PushPlusApi.sendNotice(iUser, operLog);
+ }
+
+ /**
+ * 操作日志记录
+ *
+ * @param operLog 操作日志信息
+ * @return 任务task
+ */
+ public static TimerTask recordOper(final ILog operLog) {
+ return new TimerTask() {
+ @Override
+ public void run() {
+ SpringUtils.getBean(IMTLogService.class).insertILog(operLog);
+ }
+ };
+ }
+
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogService.java
new file mode 100644
index 0000000..4fd9058
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTLogService.java
@@ -0,0 +1,68 @@
+package com.ruoyi.invest.service;
+
+
+import com.ruoyi.invest.domain.dto.ILogDto;
+import com.ruoyi.invest.domain.vo.ILogVo;
+import com.ruoyi.invest.domain.ILog;
+
+import java.util.List;
+
+/**
+ * i茅台 日志
+ */
+public interface IMTLogService {
+
+ /**
+ * 查询操作日志
+ *
+ * @param logId 操作日志主键
+ * @return 操作日志
+ */
+ public ILogVo selectILogByLogId(Long logId);
+
+ /**
+ * 查询操作日志列表
+ *
+ * @param iLogDto 操作日志
+ * @return 操作日志集合
+ */
+ public List selectILogList(ILogDto iLogDto);
+
+ /**
+ * 新增操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ public int insertILog(ILog iLog);
+
+ /**
+ * 修改操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ public int updateILog(ILog iLog);
+
+ /**
+ * 批量删除操作日志
+ *
+ * @param logIds 需要删除的操作日志主键集合
+ * @return 结果
+ */
+ public int deleteILogByLogIds(Long[] logIds);
+
+ /**
+ * 删除操作日志信息
+ *
+ * @param logId 操作日志主键
+ * @return 结果
+ */
+ public int deleteILogByLogId(Long logId);
+
+ /**
+ * 清空操作日志
+ */
+ public void cleanLog();
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTService.java
new file mode 100644
index 0000000..0203440
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IMTService.java
@@ -0,0 +1,82 @@
+package com.ruoyi.invest.service;
+
+
+import com.ruoyi.invest.domain.IUser;
+
+public interface IMTService {
+ /**
+ * 获取i茅台app版本号
+ *
+ * @return
+ */
+ String getMTVersion();
+
+ /**
+ * 刷新i茅台app版本号
+ */
+ void refreshMTVersion();
+
+ /**
+ * 发送手机验证码
+ *
+ * @param mobile 手机号
+ * @param deviceId 设备id
+ */
+ Boolean sendCode(String mobile, String deviceId);
+
+ /**
+ * 登录i茅台
+ *
+ * @param mobile 手机号
+ * @param code 验证码
+ * @param deviceId 设备id
+ * @return
+ */
+ boolean login(String mobile, String code, String deviceId);
+
+ /**
+ * 预约
+ */
+ void reservation(IUser iUser);
+
+ /**
+ * 获取申购耐力值
+ */
+ String getEnergyAward(IUser iUser);
+
+ /**
+ * 获得旅行奖励
+ *
+ * @param iUser
+ * @return
+ */
+ void getTravelReward(IUser iUser);
+//
+// /**
+// * 获取累计申购奖励
+// * @param iUser
+// */
+// void getCumulatively(IUser iUser);
+
+ /**
+ * 批量预约
+ */
+ void reservationBatch();
+
+ /**
+ * 批量获得旅行奖励
+ */
+ void getTravelRewardBatch();
+
+ /**
+ * 刷新版本号,预约item,门店shop列表,
+ */
+ void refreshAll();
+
+ /**
+ * 每日预约申购结果
+ */
+ void appointmentResults();
+
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IShopService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IShopService.java
new file mode 100644
index 0000000..6802102
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IShopService.java
@@ -0,0 +1,104 @@
+package com.ruoyi.invest.service;
+
+
+import com.ruoyi.invest.domain.IMTItemInfo;
+import com.ruoyi.invest.domain.IShop;
+import com.ruoyi.invest.domain.dto.IShopDto;
+import com.ruoyi.invest.domain.vo.IShopVo;
+
+import java.util.List;
+
+public interface IShopService {
+
+ /**
+ * 查询门店列表
+ *
+ * @param shopId 门店列表主键
+ * @return 门店列表
+ */
+ public IShopVo selectIShopByShopId(String shopId);
+
+ /**
+ * 查询门店列表列表
+ *
+ * @param iShopDto 门店列表
+ * @return 门店列表集合
+ */
+ public List selectIShopList(IShopDto iShopDto);
+
+ /**
+ * 新增门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ public int insertIShop(IShop iShop);
+
+ /**
+ * 修改门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ public int updateIShop(IShop iShop);
+
+ /**
+ * 批量删除门店列表
+ *
+ * @param shopIds 需要删除的门店列表主键集合
+ * @return 结果
+ */
+ public int deleteIShopByShopIds(String[] shopIds);
+
+ /**
+ * 删除门店列表信息
+ *
+ * @param shopId 门店列表主键
+ * @return 结果
+ */
+ public int deleteIShopByShopId(String shopId);
+
+ /**
+ * 刷新数据库i茅台shop列表
+ */
+ void refreshShop();
+
+ /**
+ * 获取当天的sessionId
+ */
+ String getCurrentSessionId();
+
+ /**
+ * 刷新i茅台预约商品列表
+ */
+ void refreshItem();
+
+
+ /**
+ * 查询所在省市的投放产品和数量
+ *
+ * @param province 省份,例如:河北省,北京市
+ * @param itemId 项目id即预约项目code
+ */
+ List getShopsByProvince(String province, String itemId);
+
+ /**
+ * @param shopType 1:预约本市出货量最大的门店,2:预约你的位置附近门店
+ * @param itemId 项目id即预约项目code
+ * @param province 省份,例如:河北省,北京市
+ * @param city 市:例如石家庄市
+ * @return
+ */
+ String getShopId(String shopType, String itemId, String province, String city, String lat, String lng);
+
+
+
+ /**
+ * 查询门店列表
+ *
+ * @param iShopId 门店列表主键
+ * @return 门店列表
+ */
+ public IShopVo selectIShopByIShopId(String iShopId);
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IUserService.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IUserService.java
new file mode 100644
index 0000000..cf98c31
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/IUserService.java
@@ -0,0 +1,74 @@
+package com.ruoyi.invest.service;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.invest.domain.IUser;
+import com.ruoyi.invest.domain.dto.IUserDto;
+import com.ruoyi.invest.domain.vo.IUserVo;
+
+import java.util.List;
+
+public interface IUserService {
+
+
+ /**
+ * 添加i茅台用户
+ *
+ * @param mobile
+ * @param body
+ * @return
+ */
+ int insertIUser(Long mobile, String deviceId, JSONObject body);
+
+ /**
+ * 查询预约用户列表
+ *
+ * @return
+ */
+ List selectReservationUser();
+
+ /**
+ * 通过预约执行分钟查询预约用户列表
+ *
+ * @return
+ */
+ List selectReservationUserByMinute(int minute);
+
+ /**
+ * 添加i茅台用户
+ *
+ * @param iUser
+ * @return
+ */
+ int insertIUser(IUser iUser);
+
+ /**
+ * 修改I茅台用户
+ *
+ * @param iUser I茅台用户
+ * @return 结果
+ */
+ int updateIUser(IUser iUser);
+
+ /**
+ * 批量修改用户随机预约的时间
+ *
+ * @return
+ */
+ void updateUserMinuteBatch();
+
+ /**
+ * 删除用户
+ *
+ * @param iUserId id
+ * @return
+ */
+ int deleteIUser(Long[] iUserId);
+
+ /**
+ * 查询用户管理列表
+ *
+ * @param iUserDto 用户管理
+ * @return 用户管理集合
+ */
+ public List selectIUserList(IUserDto iUserDto);
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IItemServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IItemServiceImpl.java
new file mode 100644
index 0000000..5ca6e02
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IItemServiceImpl.java
@@ -0,0 +1,98 @@
+package com.ruoyi.invest.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import javax.annotation.Resource;
+import org.springframework.stereotype.Service;
+import com.ruoyi.invest.mapper.IItemMapper;
+import com.ruoyi.invest.domain.IItem;
+import com.ruoyi.invest.domain.dto.IItemDto;
+import com.ruoyi.invest.domain.vo.IItemVo;
+import com.ruoyi.invest.service.IIItemService;
+
+/**
+ * 预约项目Service业务层处理
+ *
+ * @author tianyongbao
+ * @date 2024-12-06
+ */
+@Service
+public class IItemServiceImpl implements IIItemService
+{
+ @Resource
+ private IItemMapper iItemMapper;
+
+ /**
+ * 查询预约项目
+ *
+ * @param itemId 预约项目主键
+ * @return 预约项目
+ */
+ @Override
+ public IItemVo selectIItemByItemId(Long itemId)
+ {
+ return iItemMapper.selectIItemByItemId(itemId);
+ }
+
+ /**
+ * 查询预约项目列表
+ *
+ * @param iItemDto 预约项目
+ * @return 预约项目
+ */
+ @Override
+ public List selectIItemList(IItemDto iItemDto)
+ {
+ return iItemMapper.selectIItemList(iItemDto);
+ }
+
+ /**
+ * 新增预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ @Override
+ public int insertIItem(IItem iItem)
+ {
+ iItem.setCreateTime(DateUtils.getNowDate());
+ return iItemMapper.insertIItem(iItem);
+ }
+
+ /**
+ * 修改预约项目
+ *
+ * @param iItem 预约项目
+ * @return 结果
+ */
+ @Override
+ public int updateIItem(IItem iItem)
+ {
+ return iItemMapper.updateIItem(iItem);
+ }
+
+ /**
+ * 批量删除预约项目
+ *
+ * @param itemIds 需要删除的预约项目主键
+ * @return 结果
+ */
+ @Override
+ public int deleteIItemByItemIds(Long[] itemIds)
+ {
+ return iItemMapper.removeIItemByItemIds(itemIds);
+ }
+
+ /**
+ * 删除预约项目信息
+ *
+ * @param itemId 预约项目主键
+ * @return 结果
+ */
+ @Override
+ public int deleteIItemByItemId(Long itemId)
+ {
+ return iItemMapper.removeIItemByItemId(itemId);
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTLogServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTLogServiceImpl.java
new file mode 100644
index 0000000..f7e7ecc
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTLogServiceImpl.java
@@ -0,0 +1,103 @@
+package com.ruoyi.invest.service.impl;
+
+
+import com.ruoyi.common.core.utils.IdWorker;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.invest.domain.dto.ILogDto;
+import com.ruoyi.invest.domain.vo.ILogVo;
+import com.ruoyi.invest.domain.ILog;
+import com.ruoyi.invest.mapper.ILogMapper;
+import com.ruoyi.invest.service.IMTLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class IMTLogServiceImpl implements IMTLogService {
+
+ @Autowired
+ private ILogMapper iLogMapper;
+ @Autowired
+ private IdWorker idWorker;
+
+ /**
+ * 查询操作日志
+ *
+ * @param logId 操作日志主键
+ * @return 操作日志
+ */
+ @Override
+ public ILogVo selectILogByLogId(Long logId)
+ {
+ return iLogMapper.selectILogByLogId(logId);
+ }
+
+ /**
+ * 查询操作日志列表
+ *
+ * @param iLogDto 操作日志
+ * @return 操作日志
+ */
+ @Override
+ public List selectILogList(ILogDto iLogDto)
+ {
+ return iLogMapper.selectILogList(iLogDto);
+ }
+
+ /**
+ * 新增操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ @Override
+ public int insertILog(ILog iLog)
+ {
+ iLog.setCreateBy(SecurityUtils.getUsername());
+ iLog.setLogId(IdWorker.getId());
+ return iLogMapper.insertILog(iLog);
+ }
+
+ /**
+ * 修改操作日志
+ *
+ * @param iLog 操作日志
+ * @return 结果
+ */
+ @Override
+ public int updateILog(ILog iLog)
+ {
+ return iLogMapper.updateILog(iLog);
+ }
+
+ /**
+ * 批量删除操作日志
+ *
+ * @param logIds 需要删除的操作日志主键
+ * @return 结果
+ */
+ @Override
+ public int deleteILogByLogIds(Long[] logIds)
+ {
+ return iLogMapper.removeILogByLogIds(logIds);
+ }
+
+ /**
+ * 删除操作日志信息
+ *
+ * @param logId 操作日志主键
+ * @return 结果
+ */
+ @Override
+ public int deleteILogByLogId(Long logId)
+ {
+ return iLogMapper.removeILogByLogId(logId);
+ }
+
+ @Override
+ public void cleanLog() {
+ iLogMapper.cleanLog();
+ }
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTServiceImpl.java
new file mode 100644
index 0000000..212971b
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IMTServiceImpl.java
@@ -0,0 +1,672 @@
+package com.ruoyi.invest.service.impl;
+
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.crypto.Mode;
+import cn.hutool.crypto.Padding;
+import cn.hutool.crypto.symmetric.AES;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.http.Method;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.text.Convert;
+import com.ruoyi.common.core.utils.RedisCache;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.invest.domain.IMTCacheConstants;
+import com.ruoyi.invest.domain.IUser;
+import com.ruoyi.invest.mapper.IUserMapper;
+import com.ruoyi.invest.service.IMTLogFactory;
+import com.ruoyi.invest.service.IMTService;
+import com.ruoyi.invest.service.IShopService;
+import com.ruoyi.invest.service.IUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Service
+public class IMTServiceImpl implements IMTService {
+
+ private static final Logger logger = LoggerFactory.getLogger(IMTServiceImpl.class);
+
+ @Autowired
+ private IUserMapper iUserMapper;
+
+ @Autowired
+ private RedisCache redisCache;
+
+ @Autowired
+ private IUserService iUserService;
+ @Autowired
+ private IShopService iShopService;
+
+ private final static String SALT = "2af72f100c356273d46284f6fd1dfc08";
+
+ private final static String AES_KEY = "qbhajinldepmucsonaaaccgypwuvcjaa";
+ private final static String AES_IV = "2018534749963515";
+
+ /**
+ * 项目启动时,初始化数据
+ */
+ @PostConstruct
+ public void init() {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ refreshAll();
+ }
+ }).start();
+
+ }
+
+
+ @Override
+ public String getMTVersion() {
+ String mtVersion = Convert.toStr(redisCache.getCacheObject(IMTCacheConstants.MT_VERSION));
+ if (StringUtils.isNotEmpty(mtVersion)) {
+ return mtVersion;
+ }
+ String url = "https://apps.apple.com/cn/app/i%E8%8C%85%E5%8F%B0/id1600482450";
+ String htmlContent = HttpUtil.get(url);
+ Pattern pattern = Pattern.compile("new__latest__version\">(.*?)
", Pattern.DOTALL);
+ Matcher matcher = pattern.matcher(htmlContent);
+ if (matcher.find()) {
+ mtVersion = matcher.group(1);
+ mtVersion = mtVersion.replace("版本 ", "");
+ }
+ redisCache.setCacheObject(IMTCacheConstants.MT_VERSION, mtVersion);
+
+ return mtVersion;
+
+ }
+
+ @Override
+ public void refreshMTVersion() {
+ redisCache.deleteObject(IMTCacheConstants.MT_VERSION);
+ getMTVersion();
+ }
+
+ @Override
+ public Boolean sendCode(String mobile, String deviceId) {
+ Map data = new HashMap<>();
+ data.put("mobile", mobile);
+ final long curTime = System.currentTimeMillis();
+ data.put("md5", signature(mobile, curTime));
+ data.put("timestamp", String.valueOf(curTime));
+// data.put("MT-APP-Version", MT_VERSION);
+
+ HttpRequest request = HttpUtil.createRequest(Method.POST,
+ "https://app.moutai519.com.cn/xhr/front/user/register/vcode");
+
+
+ request.header("MT-Device-ID", deviceId);
+ request.header("MT-APP-Version", getMTVersion());
+ request.header("User-Agent", "iOS;16.3;Apple;?unrecognized?");
+
+ request.header("Content-Type", "application/json");
+
+ HttpResponse execute = request.body(JSONObject.toJSONString(data)).execute();
+ JSONObject jsonObject = JSONObject.parseObject(execute.body());
+ //成功返回 {"code":2000}
+ logger.info("「发送验证码返回」:" + jsonObject.toJSONString());
+ if (jsonObject.getString("code").equals("2000")) {
+ return Boolean.TRUE;
+ } else {
+ logger.error("「发送验证码-失败」:" + jsonObject.toJSONString());
+ throw new ServiceException("发送验证码错误");
+// return false;
+ }
+
+ }
+
+ @Override
+ public boolean login(String mobile, String code, String deviceId) {
+ Map map = new HashMap<>();
+ map.put("mobile", mobile);
+ map.put("vCode", code);
+
+ final long curTime = System.currentTimeMillis();
+ map.put("md5", signature(mobile + code + "" + "", curTime));
+
+ map.put("timestamp", String.valueOf(curTime));
+ map.put("MT-APP-Version", getMTVersion());
+
+ HttpRequest request = HttpUtil.createRequest(Method.POST,
+ "https://app.moutai519.com.cn/xhr/front/user/register/login");
+ IUser user = iUserMapper.selectIUserByMobile(Long.parseLong(mobile));
+ if (user != null) {
+ deviceId = user.getDeviceId();
+ }
+ request.header("MT-Device-ID", deviceId);
+ request.header("MT-APP-Version", getMTVersion());
+ request.header("User-Agent", "iOS;16.3;Apple;?unrecognized?");
+ request.header("Content-Type", "application/json");
+
+ HttpResponse execute = request.body(JSONObject.toJSONString(map)).execute();
+
+ JSONObject body = JSONObject.parseObject(execute.body());
+
+ if (body.getString("code").equals("2000")) {
+// logger.info("「登录请求-成功」" + body.toJSONString());
+ iUserService.insertIUser(Long.parseLong(mobile), deviceId, body);
+ return true;
+ } else {
+ logger.error("「登录请求-失败」" + body.toJSONString());
+ throw new ServiceException("登录失败,本地错误日志已记录");
+// return false;
+ }
+
+ }
+
+
+ @Override
+ public void reservation(IUser iUser) {
+ if (StringUtils.isEmpty(iUser.getItemCode())) {
+ return;
+ }
+ String[] items = iUser.getItemCode().split("@");
+
+ String logContent = "";
+ for (String itemId : items) {
+ try {
+ String shopId = iShopService.getShopId(iUser.getShopType(), itemId,
+ iUser.getProvinceName(), iUser.getCityName(), iUser.getLat(), iUser.getLng());
+ //预约
+ JSONObject json = reservation(iUser, itemId, shopId);
+ logContent += String.format("[预约项目]:%s\n[shopId]:%s\n[结果返回]:%s\n\n", itemId, shopId, json.toString());
+
+ //随机延迟3~5秒
+ Random random = new Random();
+ int sleepTime = random.nextInt(3) + 3;
+ Thread.sleep(sleepTime * 1000);
+ } catch (Exception e) {
+ logContent += String.format("执行报错--[预约项目]:%s\n[结果返回]:%s\n\n", itemId, e.getMessage());
+ }
+ }
+
+// try {
+// //预约后领取耐力值
+// String energyAward = getEnergyAward(iUser);
+// logContent += "[申购耐力值]:" + energyAward;
+// } catch (Exception e) {
+// logContent += "执行报错--[申购耐力值]:" + e.getMessage();
+// }
+ //日志记录
+ IMTLogFactory.reservation(iUser, logContent);
+ //预约后延迟领取耐力值
+ getEnergyAwardDelay(iUser);
+ }
+
+ /**
+ * 延迟执行:获取申购耐力值,并记录日志
+ *
+ * @param iUser
+ */
+ public void getEnergyAwardDelay(IUser iUser) {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ String logContent = "";
+ //sleep 10秒
+ try {
+ Thread.sleep(10000);
+ //预约后领取耐力值
+ String energyAward = getEnergyAward(iUser);
+ logContent += "[申购耐力值]:" + energyAward;
+ } catch (Exception e) {
+ logContent += "执行报错--[申购耐力值]:" + e.getMessage();
+ }
+ //日志记录
+ IMTLogFactory.reservation(iUser, logContent);
+ }
+ };
+ new Thread(runnable).start();
+
+ }
+
+ // 领取小茅运
+ public void receiveReward(IUser iUser) {
+ String url = "https://h5.moutai519.com.cn/game/xmTravel/receiveReward";
+ HttpRequest request = HttpUtil.createRequest(Method.POST, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .header("MT-Lat", iUser.getLat())
+ .header("MT-Lng", iUser.getLng())
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+
+ HttpResponse execute = request.execute();
+ JSONObject body = JSONObject.parseObject(execute.body());
+
+ if (body.getInteger("code") != 2000) {
+ String message = "领取小茅运失败";
+ throw new ServiceException(message);
+ }
+ }
+
+ public void shareReward(IUser iUser) {
+ logger.info("「领取每日首次分享获取耐力」:" + iUser.getMobile());
+ String url = "https://h5.moutai519.com.cn/game/xmTravel/shareReward";
+ HttpRequest request = HttpUtil.createRequest(Method.POST, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .header("MT-Lat", iUser.getLat())
+ .header("MT-Lng", iUser.getLng())
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+
+ HttpResponse execute = request.execute();
+ JSONObject body = JSONObject.parseObject(execute.body());
+
+ if (body.getInteger("code") != 2000) {
+ String message = "领取每日首次分享获取耐力失败";
+ throw new ServiceException(message);
+ }
+ }
+
+ //获取申购耐力值
+ @Override
+ public String getEnergyAward(IUser iUser) {
+ String url = "https://h5.moutai519.com.cn/game/isolationPage/getUserEnergyAward";
+ HttpRequest request = HttpUtil.createRequest(Method.POST, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .header("MT-Lat", iUser.getLat())
+ .header("MT-Lng", iUser.getLng())
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+
+ String body = request.execute().body();
+
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if (jsonObject.getInteger("code") != 200) {
+ String message = jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+
+ return body;
+ }
+
+ @Override
+ public void getTravelReward(IUser iUser) {
+ String logContent = "";
+ try {
+ String s = travelReward(iUser);
+ logContent += "[获得旅行奖励]:" + s;
+ } catch (Exception e) {
+// e.printStackTrace();
+ logContent += "执行报错--[获得旅行奖励]:" + e.getMessage();
+ }
+ //日志记录
+ IMTLogFactory.reservation(iUser, logContent);
+ }
+
+ /**
+ * 获得旅行奖励
+ *
+ * @param iUser
+ * @return
+ */
+ public String travelReward(IUser iUser) {
+ //9-20点才能领取旅行奖励
+ int hour = DateUtil.hour(new Date(), true);
+ if (!(9 <= hour && hour < 20)) {
+ String message = "活动未开始,开始时间9点-20点";
+ throw new ServiceException(message);
+ }
+ Map pageData = getUserIsolationPageData(iUser);
+ Integer status = pageData.get("status");
+ if (status == 3) {
+ Integer currentPeriodCanConvertXmyNum = pageData.get("currentPeriodCanConvertXmyNum");
+ Double travelRewardXmy = getXmTravelReward(iUser);
+ // 获取小茅运
+ receiveReward(iUser);
+ //首次分享获取耐力
+ shareReward(iUser);
+ //本次旅行奖励领取后, 当月实际剩余旅行奖励
+ if (travelRewardXmy > currentPeriodCanConvertXmyNum) {
+ String message = "当月无可领取奖励";
+ throw new ServiceException(message);
+ }
+ }
+
+ Integer remainChance = pageData.get("remainChance");
+ if (remainChance < 1) {
+ String message = "当日旅行次数已耗尽";
+ throw new ServiceException(message);
+ } else {
+ //小茅运旅行活动
+ return startTravel(iUser);
+ }
+ }
+
+ //小茅运旅行活动
+ public String startTravel(IUser iUser) {
+ String url = "https://h5.moutai519.com.cn/game/xmTravel/startTravel";
+ HttpRequest request = HttpUtil.createRequest(Method.POST, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+ String body = request.execute().body();
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if (jsonObject.getInteger("code") != 2000) {
+ String message = "开始旅行失败:" + jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+ JSONObject data = jsonObject.getJSONObject("data");
+ //最后返回 {"startTravelTs":1690798861076}
+ return jsonObject.toString();
+ }
+
+
+ //查询 可获取小茅运
+ public Double getXmTravelReward(IUser iUser) {
+ //查询旅行奖励:
+ String url = "https://h5.moutai519.com.cn/game/xmTravel/getXmTravelReward";
+ HttpRequest request = HttpUtil.createRequest(Method.GET, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+ String body = request.execute().body();
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if (jsonObject.getInteger("code") != 2000) {
+ String message = jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+ JSONObject data = jsonObject.getJSONObject("data");
+ Double travelRewardXmy = data.getDouble("travelRewardXmy");
+ //例如 1.95
+ return travelRewardXmy;
+
+ }
+
+ //获取用户页面数据
+ public Map getUserIsolationPageData(IUser iUser) {
+ //查询小茅运信息
+ String url = "https://h5.moutai519.com.cn/game/isolationPage/getUserIsolationPageData";
+ HttpRequest request = HttpUtil.createRequest(Method.GET, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+ String body = request.form("__timestamp", DateUtil.currentSeconds()).execute().body();
+
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if (jsonObject.getInteger("code") != 2000) {
+ String message = jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+ JSONObject data = jsonObject.getJSONObject("data");
+ //xmy: 小茅运值
+ String xmy = data.getString("xmy");
+ //energy: 耐力值
+ int energy = data.getIntValue("energy");
+ JSONObject xmTravel = data.getJSONObject("xmTravel");
+ JSONObject energyReward = data.getJSONObject("energyReward");
+ //status: 1. 未开始 2. 进行中 3. 已完成
+ Integer status = xmTravel.getInteger("status");
+ // travelEndTime: 旅行结束时间
+ Long travelEndTime = xmTravel.getLong("travelEndTime");
+ //remainChance 今日剩余旅行次数
+ int remainChance = xmTravel.getIntValue("remainChance");
+
+ //可领取申购耐力值奖励
+ Integer energyValue = energyReward.getInteger("value");
+
+ if (energyValue > 0) {
+ //获取申购耐力值
+ getEnergyAward(iUser);
+ energy += energyValue;
+ }
+
+// 本月剩余旅行奖励
+ int exchangeRateInfo = getExchangeRateInfo(iUser);
+ if (exchangeRateInfo <= 0) {
+ String message = "当月无可领取奖励";
+ throw new ServiceException(message);
+ }
+
+ Long endTime = travelEndTime * 1000;
+ // 未开始
+ if (status == 1) {
+ if (energy < 100) {
+ String message = String.format("耐力不足100, 当前耐力值:%s", energy);
+ throw new ServiceException(message);
+ }
+ }
+ // 进行中
+ if (status == 2) {
+ Date date = new Date(endTime);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String formattedDate = sdf.format(date);
+ String message = String.format("旅行暂未结束,本次旅行结束时间:%s ", formattedDate);
+ throw new ServiceException(message);
+ }
+ Map map = new HashMap<>();
+
+ map.put("remainChance", remainChance);
+ map.put("status", status);
+ map.put("currentPeriodCanConvertXmyNum", getExchangeRateInfo(iUser));
+ return map;
+ }
+
+ // 获取本月剩余奖励耐力值
+ public int getExchangeRateInfo(IUser iUser) {
+ String url = "https://h5.moutai519.com.cn/game/synthesize/exchangeRateInfo";
+ HttpRequest request = HttpUtil.createRequest(Method.GET, url);
+
+ request.header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?")
+ .cookie("MT-Token-Wap=" + iUser.getCookie() + ";MT-Device-ID-Wap=" + iUser.getDeviceId() + ";");
+
+ String body = request.form("__timestamp", DateUtil.currentSeconds()).execute().body();
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ if (jsonObject.getInteger("code") != 2000) {
+ String message = jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+ //获取本月剩余奖励耐力值
+ return jsonObject.getJSONObject("data").getIntValue("currentPeriodCanConvertXmyNum");
+
+ }
+
+ @Async
+ @Override
+ public void reservationBatch() {
+ int minute = DateUtil.minute(new Date());
+ List iUsers = iUserService.selectReservationUserByMinute(minute);
+
+ for (IUser iUser : iUsers) {
+ logger.info("「开始预约用户」" + iUser.getMobile());
+ //预约
+ reservation(iUser);
+ //延时3秒
+ try {
+ TimeUnit.SECONDS.sleep(3);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ @Async
+ @Override
+ public void getTravelRewardBatch() {
+ try {
+ int minute = DateUtil.minute(new Date());
+ List iUsers = iUserService.selectReservationUserByMinute(minute);
+// List iUsers = iUserService.selectReservationUser();
+
+ for (IUser iUser : iUsers) {
+ logger.info("「开始获得旅行奖励」" + iUser.getMobile());
+ getTravelReward(iUser);
+ //延时3秒
+ TimeUnit.SECONDS.sleep(3);
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void refreshAll() {
+ refreshMTVersion();
+ iShopService.refreshShop();
+ iShopService.refreshItem();
+ }
+
+ @Override
+ public void appointmentResults() {
+ logger.info("申购结果查询开始=========================");
+ List iUsers = iUserService.selectReservationUser();
+ for (IUser iUser : iUsers) {
+ try {
+ String url = "https://app.moutai519.com.cn/xhr/front/mall/reservation/list/pageOne/query";
+ String body = HttpUtil.createRequest(Method.GET, url)
+ .header("MT-Device-ID", iUser.getDeviceId())
+ .header("MT-APP-Version", getMTVersion())
+ .header("MT-Token", iUser.getToken())
+ .header("User-Agent", "iOS;16.3;Apple;?unrecognized?").execute().body();
+ JSONObject jsonObject = JSONObject.parseObject(body);
+ logger.info("查询申购结果回调: user->{},response->{}", iUser.getMobile(), body);
+ if (jsonObject.getInteger("code") != 2000) {
+ String message = jsonObject.getString("message");
+ throw new ServiceException(message);
+ }
+ JSONArray itemVOs = jsonObject.getJSONObject("data").getJSONArray("reservationItemVOS");
+ if (Objects.isNull(itemVOs) || itemVOs.isEmpty()) {
+ logger.info("申购记录为空: user->{}", iUser.getMobile());
+ continue;
+ }
+ for (Object itemVO : itemVOs) {
+ JSONObject item = JSON.parseObject(itemVO.toString());
+ // 预约时间在24小时内的
+ if (item.getInteger("status") == 2 && DateUtil.between(item.getDate("reservationTime"), new Date(), DateUnit.HOUR) < 24) {
+ String logContent = DateUtil.formatDate(item.getDate("reservationTime")) + " 申购" + item.getString("itemName") + "成功";
+ IMTLogFactory.reservation(iUser, logContent);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("查询申购结果失败:失败原因->{}", e.getMessage(), e);
+ }
+
+ }
+ logger.info("申购结果查询结束=========================");
+ }
+
+ public JSONObject reservation(IUser iUser, String itemId, String shopId) {
+ Map map = new HashMap<>();
+ JSONArray itemArray = new JSONArray();
+ Map info = new HashMap<>();
+ info.put("count", 1);
+ info.put("itemId", itemId);
+
+ itemArray.add(info);
+
+ map.put("itemInfoList", itemArray);
+
+ map.put("sessionId", iShopService.getCurrentSessionId());
+ map.put("userId", iUser.getUserId().toString());
+ map.put("shopId", shopId);
+
+ map.put("actParam", AesEncrypt(JSON.toJSONString(map)));
+
+ HttpRequest request = HttpUtil.createRequest(Method.POST,
+ "https://app.moutai519.com.cn/xhr/front/mall/reservation/add");
+
+ request.header("MT-Lat", iUser.getLat());
+ request.header("MT-Lng", iUser.getLng());
+ request.header("MT-Token", iUser.getToken());
+ request.header("MT-Info", "028e7f96f6369cafe1d105579c5b9377");
+ request.header("MT-Device-ID", iUser.getDeviceId());
+ request.header("MT-APP-Version", getMTVersion());
+ request.header("User-Agent", "iOS;16.3;Apple;?unrecognized?");
+ request.header("Content-Type", "application/json");
+ request.header("userId", iUser.getUserId().toString());
+
+ HttpResponse execute = request.body(JSONObject.toJSONString(map)).execute();
+
+ JSONObject body = JSONObject.parseObject(execute.body());
+ //{"code":2000,"data":{"successDesc":"申购完成,请于7月6日18:00查看预约申购结果","reservationList":[{"reservationId":17053404357,"sessionId":678,"shopId":"233331084001","reservationTime":1688608601720,"itemId":"10214","count":1}],"reservationDetail":{"desc":"申购成功后将以短信形式通知您,请您在申购成功次日18:00前确认支付方式,并在7天内完成提货。","lotteryTime":1688637600000,"cacheValidTime":1688637600000}}}
+ if (body.getInteger("code") != 2000) {
+ String message = body.getString("message");
+ throw new ServiceException(message);
+ }
+// logger.info(body.toJSONString());
+ return body;
+ }
+
+ /**
+ * 加密
+ *
+ * @param params
+ * @return
+ */
+ public static String AesEncrypt(String params) {
+ AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, AES_KEY.getBytes(), AES_IV.getBytes());
+ return aes.encryptBase64(params);
+ }
+
+ /**
+ * 解密
+ *
+ * @param params
+ * @return
+ */
+ public static String AesDecrypt(String params) {
+ AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, AES_KEY.getBytes(), AES_IV.getBytes());
+ return aes.decryptStr(params);
+ }
+
+ /**
+ * 获取验证码的md5签名,密钥+手机号+时间
+ * 登录的md5签名:密钥+mobile+vCode+ydLogId+ydToken
+ *
+ * @param content
+ * @return
+ */
+ private static String signature(String content, long time) {
+
+ String text = SALT + content + time;
+ String md5 = "";
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] hashBytes = md.digest(text.getBytes());
+ StringBuilder sb = new StringBuilder();
+ for (byte b : hashBytes) {
+ sb.append(String.format("%02x", b));
+ }
+ md5 = sb.toString();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return md5;
+ }
+
+
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IShopServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IShopServiceImpl.java
new file mode 100644
index 0000000..255639e
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IShopServiceImpl.java
@@ -0,0 +1,362 @@
+package com.ruoyi.invest.service.impl;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.http.Method;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONException;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.IdWorker;
+import com.ruoyi.common.core.utils.RedisCache;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.invest.domain.*;
+import com.ruoyi.invest.domain.dto.IShopDto;
+import com.ruoyi.invest.domain.vo.IShopVo;
+import com.ruoyi.invest.mapper.IItemMapper;
+import com.ruoyi.invest.mapper.IShopMapper;
+import com.ruoyi.invest.service.IShopService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class IShopServiceImpl implements IShopService {
+
+
+ @Autowired
+ IShopMapper iShopMapper;
+ @Autowired
+ IItemMapper iItemMapper;
+
+ @Autowired
+ RedisCache redisCache;
+
+ /**
+ * 查询门店列表
+ *
+ * @param shopId 门店列表主键
+ * @return 门店列表
+ */
+ @Override
+ public IShopVo selectIShopByShopId(String shopId)
+ {
+ return iShopMapper.selectIShopByShopId(shopId);
+ }
+
+ /**
+ * 查询门店列表列表
+ *
+ * @param iShopDto 门店列表
+ * @return 门店列表
+ */
+ @Override
+ public List selectIShopList(IShopDto iShopDto)
+ {
+ return iShopMapper.selectIShopList(iShopDto);
+ }
+
+ /**
+ * 新增门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ @Override
+ public int insertIShop(IShop iShop)
+ {
+ iShop.setCreateTime(DateUtils.getNowDate());
+ return iShopMapper.insertIShop(iShop);
+ }
+
+ /**
+ * 修改门店列表
+ *
+ * @param iShop 门店列表
+ * @return 结果
+ */
+ @Override
+ public int updateIShop(IShop iShop)
+ {
+ return iShopMapper.updateIShop(iShop);
+ }
+
+ /**
+ * 批量删除门店列表
+ *
+ * @param shopIds 需要删除的门店列表主键
+ * @return 结果
+ */
+ @Override
+ public int deleteIShopByShopIds(String[] shopIds)
+ {
+ return iShopMapper.removeIShopByShopIds(shopIds);
+ }
+
+ /**
+ * 删除门店列表信息
+ *
+ * @param shopId 门店列表主键
+ * @return 结果
+ */
+ @Override
+ public int deleteIShopByShopId(String shopId)
+ {
+ return iShopMapper.removeIShopByShopId(shopId);
+ }
+
+ // @Async
+ @Override
+ public void refreshShop() {
+
+ HttpRequest request = HttpUtil.createRequest(Method.GET,
+ "https://static.moutai519.com.cn/mt-backend/xhr/front/mall/resource/get");
+
+ JSONObject body = JSONObject.parseObject(request.execute().body());
+ //获取shop的url
+ String shopUrl = body.getJSONObject("data").getJSONObject("mtshops_pc").getString("url");
+ //清空数据库
+ iShopMapper.truncateShop();
+
+ String s = HttpUtil.get(shopUrl);
+
+ JSONObject jsonObject = JSONObject.parseObject(s);
+ Set shopIdSet = jsonObject.keySet();
+ List list = new ArrayList<>();
+ for (String iShopId : shopIdSet) {
+ JSONObject shop = jsonObject.getJSONObject(iShopId);
+ IShop iShop = new IShop(iShopId, shop);
+ iShop.setShopId(IdWorker.getStringId());
+ list.add(iShop);
+ }
+ insertBatch(list);
+
+ }
+ public void insertBatch(List list){
+ List> allList = ListUtil.partition(list, 500);
+ allList.forEach(i -> {
+ iShopMapper.batchInsertIShop(i);
+ });
+ }
+
+
+ @Override
+ public String getCurrentSessionId() {
+ String mtSessionId = Convert.toStr(redisCache.getCacheObject(IMTCacheConstants.MT_SESSION_ID));
+
+ long dayTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
+ if (StringUtils.isNotEmpty(mtSessionId)) {
+ return mtSessionId;
+ }
+
+ String res = HttpUtil.get("https://static.moutai519.com.cn/mt-backend/xhr/front/mall/index/session/get/" + dayTime);
+ //替换 current_session_id 673 ['data']['sessionId']
+ JSONObject jsonObject = JSONObject.parseObject(res);
+
+ if (jsonObject.getString("code").equals("2000")) {
+ JSONObject data = jsonObject.getJSONObject("data");
+ mtSessionId = data.getString("sessionId");
+ redisCache.setCacheObject(IMTCacheConstants.MT_SESSION_ID, mtSessionId, 2, TimeUnit.HOURS);
+
+ iItemMapper.truncateItem();
+ //item插入数据库
+ JSONArray itemList = data.getJSONArray("itemList");
+ for (Object obj : itemList) {
+ JSONObject item = (JSONObject) obj;
+ IItem iItem = new IItem(item);
+ iItemMapper.insertIItem(iItem);
+ }
+
+ }
+
+ return mtSessionId;
+
+ }
+
+ @Override
+ public void refreshItem() {
+ redisCache.deleteObject(IMTCacheConstants.MT_SESSION_ID);
+ getCurrentSessionId();
+ }
+
+ @Override
+ public List getShopsByProvince(String province, String itemId) {
+ String key = "mt_province:" + province + "." + getCurrentSessionId() + "." + itemId;
+ List cacheList = redisCache.getCacheList(key);
+ if (cacheList != null && cacheList.size() > 0) {
+ return cacheList;
+ } else {
+ List imtItemInfoList = reGetShopsByProvince(province, itemId);
+ redisCache.reSetCacheList(key, imtItemInfoList);
+ redisCache.expire(key, 60, TimeUnit.MINUTES);
+ return imtItemInfoList;
+ }
+ }
+
+ public List reGetShopsByProvince(String province, String itemId) {
+
+ long dayTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
+
+ String url = "https://static.moutai519.com.cn/mt-backend/xhr/front/mall/shop/list/slim/v3/" + getCurrentSessionId() + "/" + province + "/" + itemId + "/" + dayTime;
+
+ String urlRes = HttpUtil.get(url);
+ JSONObject res = null;
+ try {
+ res = JSONObject.parseObject(urlRes);
+ } catch (JSONException jsonException) {
+ String message = StringUtils.format("查询所在省市的投放产品和数量error: %s", url);
+ log.error(message);
+ throw new ServiceException(message);
+ }
+
+// JSONObject res = JSONObject.parseObject(HttpUtil.get(url));
+ if (!res.containsKey("code") || !res.getString("code").equals("2000")) {
+ String message = StringUtils.format("查询所在省市的投放产品和数量error: %s", url);
+ log.error(message);
+ throw new ServiceException(message);
+ }
+ //组合信息
+ List imtItemInfoList = new ArrayList<>();
+
+ JSONObject data = res.getJSONObject("data");
+ JSONArray shopList = data.getJSONArray("shops");
+
+ for (Object obj : shopList) {
+ JSONObject shops = (JSONObject) obj;
+ JSONArray items = shops.getJSONArray("items");
+ for (Object item : items) {
+ JSONObject itemObj = (JSONObject) item;
+ if (itemObj.getString("itemId").equals(itemId)) {
+ IMTItemInfo iItem = new IMTItemInfo(shops.getString("shopId"),
+ itemObj.getIntValue("count"), itemObj.getString("itemId"), itemObj.getIntValue("inventory"));
+ //添加
+ imtItemInfoList.add(iItem);
+ }
+
+ }
+
+
+ }
+ return imtItemInfoList;
+ }
+
+ @Override
+ public String getShopId(String shopType, String itemId, String province, String city, String lat, String lng) {
+ //查询所在省市的投放产品和数量
+ List shopList = getShopsByProvince(province, itemId);
+ //取id集合
+ List shopIdList = shopList.stream().map(IMTItemInfo::getShopId).collect(Collectors.toList());
+ //获取门店列表
+ List iShops = selectIShopList(new IShopDto());
+ //获取今日的门店信息列表
+ List list = iShops.stream().filter(i -> shopIdList.contains(i.getIShopId())).collect(Collectors.toList());
+
+ String shopId = "";
+ if (Objects.equals(shopType, "1")) {
+ //预约本市出货量最大的门店
+ shopId = getMaxInventoryShopId(shopList, list, city);
+ if (StringUtils.isEmpty(shopId)) {
+ //本市没有则预约本省最近的
+ shopId = getMinDistanceShopId(list, province, lat, lng);
+ }
+ } else {
+ //预约本省距离最近的门店
+ shopId = getMinDistanceShopId(list, province, lat, lng);
+ }
+
+// if (shopType == 2) {
+// // 预约本省距离最近的门店
+// shopId = getMinDistanceShopId(list, province, lat, lng);
+// }
+
+ if (StringUtils.isEmpty(shopId)) {
+ throw new ServiceException("申购时根据类型获取的门店商品id为空");
+ }
+
+
+ return shopId;
+ }
+
+ /**
+ * 预约本市出货量最大的门店
+ *
+ * @param list1
+ * @param list2
+ * @param city
+ * @return
+ */
+ public String getMaxInventoryShopId(List list1, List list2, String city) {
+
+ //本城市的shopId集合
+ List cityShopIdList = list2.stream().filter(iShop -> iShop.getCityName().contains(city))
+ .map(IShop::getIShopId).collect(Collectors.toList());
+
+ List collect = list1.stream().filter(i -> cityShopIdList.contains(i.getShopId())).sorted(Comparator.comparing(IMTItemInfo::getInventory).reversed()).collect(Collectors.toList());
+
+
+ if (collect != null && collect.size() > 0) {
+ return collect.get(0).getShopId();
+ }
+
+ return null;
+ }
+
+ /**
+ * 预约本省距离最近的门店
+ *
+ * @param list2
+ * @param province
+ * @param lat
+ * @param lng
+ * @return
+ */
+ public String getMinDistanceShopId(List list2, String province, String lat, String lng) {
+ //本省的
+ List iShopList = list2.stream().filter(iShop -> iShop.getProvinceName().contains(province))
+ .collect(Collectors.toList());
+
+ MapPoint myPoint = new MapPoint(Double.parseDouble(lat), Double.parseDouble(lng));
+ for (IShop iShop : iShopList) {
+ MapPoint point = new MapPoint(Double.parseDouble(iShop.getLat()), Double.parseDouble(iShop.getLng()));
+ Double disdance = getDisdance(myPoint, point);
+ iShop.setDistance(disdance);
+ }
+
+ List collect = iShopList.stream().sorted(Comparator.comparing(IShop::getDistance)).collect(Collectors.toList());
+
+ return collect.get(0).getIShopId();
+
+ }
+
+ public static Double getDisdance(MapPoint point1, MapPoint point2) {
+ double lat1 = (point1.getLatitude() * Math.PI) / 180; //将角度换算为弧度
+ double lat2 = (point2.getLatitude() * Math.PI) / 180; //将角度换算为弧度
+ double latDifference = lat1 - lat2;
+ double lonDifference = (point1.getLongitude() * Math.PI) / 180 - (point2.getLongitude() * Math.PI) / 180;
+ //计算两点之间距离 6378137.0 取自WGS84标准参考椭球中的地球长半径(单位:m)
+ return 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(latDifference / 2), 2)
+ + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lonDifference / 2), 2))) * 6378137.0;
+ }
+
+ /**
+ * 查询门店列表
+ *
+ * @param iShopId 门店列表主键
+ * @return 门店列表
+ */
+ @Override
+ public IShopVo selectIShopByIShopId(String iShopId)
+ {
+ return iShopMapper.selectIShopByIShopId(iShopId);
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IUserServiceImpl.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IUserServiceImpl.java
new file mode 100644
index 0000000..8e3e8c8
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/invest/service/impl/IUserServiceImpl.java
@@ -0,0 +1,140 @@
+package com.ruoyi.invest.service.impl;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.invest.domain.IUser;
+import com.ruoyi.invest.domain.dto.IUserDto;
+import com.ruoyi.invest.domain.vo.IUserVo;
+import com.ruoyi.invest.mapper.IUserMapper;
+import com.ruoyi.invest.service.IUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+@Service
+public class IUserServiceImpl implements IUserService {
+ @Autowired
+ private IUserMapper iUserMapper;
+
+
+ @Override
+ public int insertIUser(Long mobile, String deviceId, JSONObject jsonObject) {
+
+ IUser user = iUserMapper.selectIUserByMobile(mobile);
+
+ if (user != null) {
+ JSONObject result = jsonObject.getJSONObject("data");
+ user.setUserId(result.getLong("userId"));
+ user.setToken(result.getString("token"));
+ user.setMobile(mobile);
+
+ user.setCookie(result.getString("cookie"));
+ user.setDeviceId( deviceId.toLowerCase());
+ user.setJsonResult(StringUtils.substring(jsonObject.toJSONString(), 0, 2000));
+ user.setRemark(result.getString("userName"));
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_MONTH, 30);
+ Date thirtyDaysLater = calendar.getTime();
+ user.setExpireTime(thirtyDaysLater);
+ user.setCreateUser(SecurityUtils.getUserId());
+
+ return iUserMapper.updateIUser(user);
+ } else {
+ if (StringUtils.isEmpty(deviceId)) {
+ deviceId = UUID.randomUUID().toString().toLowerCase();
+ }
+ IUser iUser=new IUser();
+ JSONObject result = jsonObject.getJSONObject("data");
+ iUser.setUserId(result.getLong("userId"));
+ iUser.setToken(result.getString("token"));
+ iUser.setMobile(mobile);
+
+ iUser.setCookie(result.getString("cookie"));
+ iUser.setDeviceId( deviceId.toLowerCase());
+ iUser.setJsonResult(StringUtils.substring(jsonObject.toJSONString(), 0, 2000));
+ iUser.setRemark(result.getString("userName"));
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_MONTH, 30);
+ Date thirtyDaysLater = calendar.getTime();
+ iUser.setExpireTime(thirtyDaysLater);
+
+ iUser.setCreateUser(SecurityUtils.getUserId());
+ return iUserMapper.insertIUser(iUser);
+ }
+
+
+ }
+
+ @Override
+ public List selectReservationUser() {
+ return iUserMapper.selectReservationUser();
+
+ }
+
+ @Override
+ public List selectReservationUserByMinute(int minute) {
+ IUserDto dto = new IUserDto();
+ dto.setMinute(minute);
+ return iUserMapper.selectReservationUserByMinute(dto);
+ }
+
+ @Override
+ public int insertIUser(IUser iUser) {
+
+ IUser user = iUserMapper.selectIUserByMobile(iUser.getMobile());
+ if (user != null) {
+ throw new ServiceException("禁止重复添加");
+ }
+
+ if (StringUtils.isEmpty(iUser.getDeviceId())) {
+ iUser.setDeviceId(UUID.randomUUID().toString().toLowerCase());
+ }
+ iUser.setCreateUser(SecurityUtils.getUserId());
+ return iUserMapper.insertIUser(iUser);
+ }
+
+ @Override
+ public int updateIUser(IUser iUser) {
+ if (SecurityUtils.getUserId() != 1 && !iUser.getCreateUser().equals(SecurityUtils.getUserId())) {
+ throw new ServiceException("只能修改自己创建的用户");
+ }
+ return iUserMapper.updateIUser(iUser);
+ }
+
+ @Override
+ @Async
+ public void updateUserMinuteBatch() {
+ int userCount = iUserMapper.selectIUserList(new IUserDto()).size();
+ if (userCount > 60) {
+ iUserMapper.updateUserMinuteEven();
+ }else {
+ iUserMapper.updateUserMinuteBatch();
+ }
+ }
+
+ @Override
+ public int deleteIUser(Long[] iUserId) {
+ return iUserMapper.deleteIUserByMobiles(iUserId);
+ }
+
+ /**
+ * 查询用户管理列表
+ *
+ * @param iUserDto 用户管理
+ * @return 用户管理
+ */
+ @Override
+ public List selectIUserList(IUserDto iUserDto)
+ {
+ return iUserMapper.selectIUserList(iUserDto);
+ }
+}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/job/controller/InvestJob.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/job/controller/InvestJob.java
index ec6a357..4f27344 100644
--- a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/job/controller/InvestJob.java
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/job/controller/InvestJob.java
@@ -2,6 +2,8 @@ package com.ruoyi.job.controller;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.invest.service.IMTService;
+import com.ruoyi.invest.service.IUserService;
import com.ruoyi.job.service.IInvestJobService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.PostMapping;
@@ -23,6 +25,10 @@ public class InvestJob
{
@Resource
private IInvestJobService investJobService;
+ @Resource
+ private IMTService imtService;
+ @Resource
+ private IUserService iUserService;
@PostMapping("/generateUnpaidCreditBill")
public AjaxResult generateUnpaidCreditBill()
@@ -52,6 +58,67 @@ public class InvestJob
return AjaxResult.success();
}
+ /**
+ * 1:10 批量修改用户随机预约的时间
+ */
+ @PostMapping("/updateUserMinuteBatch")
+ public AjaxResult updateUserMinuteBatch()
+ {
+ System.out.println("================================开始批量修改用户预约时间("+ DateUtils.getTime() +")=================================");
+ iUserService.updateUserMinuteBatch();
+ System.out.println("================================结束批量修改用户预约时间("+ DateUtils.getTime() +")=================================");
+ return AjaxResult.success();
+ }
+
+ /**
+ * 11点期间,每分钟执行一次批量获得旅行奖励
+ */
+ @PostMapping("/getTravelRewardBatch")
+ public AjaxResult getTravelRewardBatch()
+ {
+ System.out.println("================================开始批量获得旅行奖励("+ DateUtils.getTime() +")=================================");
+ imtService.getTravelRewardBatch();
+ System.out.println("================================结束批量获得旅行奖励("+ DateUtils.getTime() +")=================================");
+ return AjaxResult.success();
+ }
+
+ /**
+ * 9点期间,每分钟执行一次
+ */
+ @PostMapping("/reservationBatchTask")
+ public AjaxResult reservationBatchTask()
+ {
+ System.out.println("================================开始批量预约茅台("+ DateUtils.getTime() +")=================================");
+ imtService.reservationBatch();
+ System.out.println("================================结束批量预约茅台("+ DateUtils.getTime() +")=================================");
+ return AjaxResult.success();
+ }
+
+ /**
+ * 更新茅台版本,门店列表,预约商品列表
+ */
+ @PostMapping("/refreshAll")
+ public AjaxResult refreshAll()
+ {
+ System.out.println("================================开始批量更新茅台版本、门店列表、预约商品列表("+ DateUtils.getTime() +")=================================");
+ imtService.refreshAll();
+ System.out.println("================================结束批量更新茅台版本、门店列表、预约商品列表("+ DateUtils.getTime() +")=================================");
+ return AjaxResult.success();
+ }
+
+ /**
+ * 18.05分获取申购结果
+ */
+ @PostMapping("/appointmentResults")
+ public AjaxResult appointmentResults()
+ {
+ System.out.println("================================开始批量获取申购结果("+ DateUtils.getTime() +")=================================");
+ imtService.appointmentResults();
+ System.out.println("================================结束批量获取申购结果("+ DateUtils.getTime() +")=================================");
+ return AjaxResult.success();
+ }
+
+
}
diff --git a/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/task/CampusIMTTask.java b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/task/CampusIMTTask.java
new file mode 100644
index 0000000..dda7924
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/java/com/ruoyi/task/CampusIMTTask.java
@@ -0,0 +1,81 @@
+package com.ruoyi.task;
+
+
+import com.ruoyi.invest.service.IMTService;
+import com.ruoyi.invest.service.IUserService;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+/**
+ * i茅台定时任务
+ */
+@Configuration
+@EnableScheduling
+@RequiredArgsConstructor
+public class CampusIMTTask {
+ private static final Logger logger = LoggerFactory.getLogger(CampusIMTTask.class);
+
+ private final IMTService imtService;
+
+ private final IUserService iUserService;
+
+
+ /**
+ * 1:10 批量修改用户随机预约的时间
+ */
+ @Async
+ @Scheduled(cron = "0 10 1 ? * * ")
+ public void updateUserMinuteBatch() {
+ iUserService.updateUserMinuteBatch();
+ }
+
+
+ /**
+ * 11点期间,每分钟执行一次批量获得旅行奖励
+ */
+ @Async
+ @Scheduled(cron = "0 0/1 11 ? * *")
+ public void getTravelRewardBatch() {
+ imtService.getTravelRewardBatch();
+
+ }
+
+ /**
+ * 9点期间,每分钟执行一次
+ */
+
+ @Scheduled(cron = "0 0/1 9 ? * *")
+ public void reservationBatchTask() {
+ imtService.reservationBatch();
+
+ }
+
+
+ @Scheduled(cron = "0 10,55 7,8 ? * * ")
+ public void refresh() {
+ logger.info("「刷新数据」开始刷新版本号,预约item,门店shop列表 ");
+ try {
+ imtService.refreshAll();
+ } catch (Exception e) {
+ logger.info("「刷新数据执行报错」%s", e.getMessage());
+ }
+
+ }
+
+
+ /**
+ * 18.05分获取申购结果
+ */
+ @Async
+ @Scheduled(cron = "0 5 18 ? * * ")
+ public void appointmentResults() {
+ imtService.appointmentResults();
+ }
+
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IItemMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IItemMapper.xml
new file mode 100644
index 0000000..6e46f00
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IItemMapper.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select a.item_id, a.item_code, a.title, a.content, a.picture, a.create_time from i_item a
+
+
+
+
+
+
+
+ insert into i_item
+
+ item_id,
+ item_code,
+ title,
+ content,
+ picture,
+ create_time,
+
+
+ #{itemId},
+ #{itemCode},
+ #{title},
+ #{content},
+ #{picture},
+ #{createTime},
+
+
+
+
+ update i_item
+
+ item_code = #{itemCode},
+ title = #{title},
+ content = #{content},
+ picture = #{picture},
+ create_time = #{createTime},
+
+ where item_id = #{itemId}
+
+
+
+ delete from i_item where item_id = #{itemId}
+
+
+
+ delete from i_item where item_id in
+
+ #{itemId}
+
+
+
+ update i_item set del_flag='1' where item_id = #{itemId}
+
+
+
+ update i_item set del_flag='1' where item_id in
+
+ #{itemId}
+
+
+
+ TRUNCATE TABLE i_item
+
+
diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/ILogMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/ILogMapper.xml
new file mode 100644
index 0000000..a8dadfe
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/ILogMapper.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select a.log_id, a.mobile, a.log_content, a.status, a.oper_time, a.create_user, a.create_by from i_log a
+
+
+
+
+
+
+
+ insert into i_log
+
+ log_id,
+ mobile,
+ log_content,
+ status,
+ oper_time,
+ create_user,
+ create_by,
+
+
+ #{logId},
+ #{mobile},
+ #{logContent},
+ #{status},
+ #{operTime},
+ #{createUser},
+ #{createBy},
+
+
+
+
+ update i_log
+
+ mobile = #{mobile},
+ log_content = #{logContent},
+ status = #{status},
+ oper_time = #{operTime},
+ create_user = #{createUser},
+ create_by = #{createBy},
+
+ where log_id = #{logId}
+
+
+
+ delete from i_log where log_id = #{logId}
+
+
+
+ delete from i_log where log_id in
+
+ #{logId}
+
+
+
+ update i_log set del_flag='1' where log_id = #{logId}
+
+
+
+ update i_log set del_flag='1' where log_id in
+
+ #{logId}
+
+
+
+
+ TRUNCATE TABLE i_log
+
+
+
diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IShopMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IShopMapper.xml
new file mode 100644
index 0000000..8d8b62c
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IShopMapper.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select a.shop_id, a.i_shop_id, a.province_name, a.city_name, a.district_name, a.full_address, a.lat, a.lng, a.name, a.tenant_name, a.create_time from i_shop a
+
+
+
+
+
+
+
+ insert into i_shop
+
+ shop_id,
+ i_shop_id,
+ province_name,
+ city_name,
+ district_name,
+ full_address,
+ lat,
+ lng,
+ name,
+ tenant_name,
+ create_time,
+
+
+ #{shopId},
+ #{iShopId},
+ #{provinceName},
+ #{cityName},
+ #{districtName},
+ #{fullAddress},
+ #{lat},
+ #{lng},
+ #{name},
+ #{tenantName},
+ #{createTime},
+
+
+
+
+ update i_shop
+
+ i_shop_id = #{iShopId},
+ province_name = #{provinceName},
+ city_name = #{cityName},
+ district_name = #{districtName},
+ full_address = #{fullAddress},
+ lat = #{lat},
+ lng = #{lng},
+ name = #{name},
+ tenant_name = #{tenantName},
+ create_time = #{createTime},
+
+ where shop_id = #{shopId}
+
+
+
+ delete from i_shop where shop_id = #{shopId}
+
+
+
+ delete from i_shop where shop_id in
+
+ #{shopId}
+
+
+
+ update i_shop set del_flag='1' where shop_id = #{shopId}
+
+
+
+ update i_shop set del_flag='1' where shop_id in
+
+ #{shopId}
+
+
+
+
+ TRUNCATE TABLE i_shop
+
+
+
+ insert into i_shop(shop_id, i_shop_id, province_name, city_name, district_name, full_address, lat, lng, name, tenant_name, create_time) values
+
+ (#{item.shopId},
+ #{item.iShopId},
+ #{item.provinceName},
+ #{item.cityName},
+ #{item.districtName},
+ #{item.fullAddress},
+ #{item.lat},
+ #{item.lng},
+ #{item.name},
+ #{item.tenantName},
+ #{item.createTime})
+
+
+
+
+
diff --git a/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IUserMapper.xml b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IUserMapper.xml
new file mode 100644
index 0000000..98ad1ce
--- /dev/null
+++ b/ruoyi-modules/intc-invest/src/main/resources/mapper/invest/IUserMapper.xml
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select a.mobile, a.user_id, a.token, a.cookie, a.device_id, a.item_code, a.ishop_id, a.province_name, a.city_name, a.address, a.lat, a.lng, a.minute, a.shop_type, a.random_minute, a.push_plus_token, a.json_result, a.remark, a.expire_time, a.del_flag, a.create_time, a.create_user, a.update_time, a.update_user, a.create_by from i_user a
+
+
+
+
+
+
+
+ insert into i_user
+
+ mobile,
+ user_id,
+ token,
+ cookie,
+ device_id,
+ item_code,
+ ishop_id,
+ province_name,
+ city_name,
+ address,
+ lat,
+ lng,
+ minute,
+ shop_type,
+ random_minute,
+ push_plus_token,
+ json_result,
+ remark,
+ expire_time,
+ del_flag,
+ create_time,
+ create_user,
+ update_time,
+ update_user,
+ create_by,
+
+
+ #{mobile},
+ #{userId},
+ #{token},
+ #{cookie},
+ #{deviceId},
+ #{itemCode},
+ #{ishopId},
+ #{provinceName},
+ #{cityName},
+ #{address},
+ #{lat},
+ #{lng},
+ #{minute},
+ #{shopType},
+ #{randomMinute},
+ #{pushPlusToken},
+ #{jsonResult},
+ #{remark},
+ #{expireTime},
+ #{delFlag},
+ #{createTime},
+ #{createUser},
+ #{updateTime},
+ #{updateUser},
+ #{createBy},
+
+
+
+
+ update i_user
+
+ user_id = #{userId},
+ token = #{token},
+ cookie = #{cookie},
+ device_id = #{deviceId},
+ item_code = #{itemCode},
+ ishop_id = #{ishopId},
+ province_name = #{provinceName},
+ city_name = #{cityName},
+ address = #{address},
+ lat = #{lat},
+ lng = #{lng},
+ minute = #{minute},
+ shop_type = #{shopType},
+ random_minute = #{randomMinute},
+ push_plus_token = #{pushPlusToken},
+ json_result = #{jsonResult},
+ remark = #{remark},
+ expire_time = #{expireTime},
+ del_flag = #{delFlag},
+ create_time = #{createTime},
+ create_user = #{createUser},
+ update_time = #{updateTime},
+ update_user = #{updateUser},
+ create_by = #{createBy},
+
+ where mobile = #{mobile}
+
+
+
+ delete from i_user where mobile = #{mobile}
+
+
+
+ delete from i_user where mobile in
+
+ #{mobile}
+
+
+
+ update i_user set del_flag='1' where mobile = #{mobile}
+
+
+
+ update i_user set del_flag='1' where mobile in
+
+ #{mobile}
+
+
+
+
+ UPDATE i_user SET `minute` = (SELECT FLOOR(random() * 50 + 1))) WHERE random_minute = '0'
+
+
+
+ UPDATE i_user SET `minute` = (SELECT FLOOR(random() * 50 + 1))) WHERE random_minute = '0'
+
+
+
+
+
+