fix: 投资系统,茅台预约代码提交。

This commit is contained in:
tianyongbao
2024-12-07 16:43:13 +08:00
parent eef5cfc971
commit 12cb0b8bfc
53 changed files with 4713 additions and 1 deletions

View File

@@ -121,6 +121,12 @@
<version>5.3.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.23</version>
</dependency>
</dependencies>
<build>

View File

@@ -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("(♥◠‿◠)ノ゙ 智聪投资业务模块启动成功 ლ(´ڡ`ლ)゙");
}

View File

@@ -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);
}
};
}
}

View File

@@ -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<String, Object> 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);
}
};
}
}

View File

@@ -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<IItemVo> list = iItemService.selectIItemList(iItemDto);
return getDataTable(list);
}
/**
* 刷新i茅台预约商品列表
*/
@GetMapping(value = "/refresh", name = "刷新i茅台预约商品列表")
public AjaxResult refreshItem() {
iShopService.refreshItem();
return success("刷新成功");
}
}

View File

@@ -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<ILogVo> 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);
}
}

View File

@@ -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<IShopVo> list = iShopService.selectIShopList(iShopDto);
return getDataTable(list);
}
/**
* 刷新i茅台商品列表
*/
@GetMapping(value = "/refresh", name = "刷新i茅台门店列表")
public AjaxResult refreshShop() {
iShopService.refreshShop();
return toAjax(1);
}
}

View File

@@ -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<IUserVo> 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));
}
}

View File

@@ -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();
}
}

View File

@@ -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<String, Object> params;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
}

View File

@@ -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";
}

View File

@@ -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;
}

View File

@@ -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<String, Object> params;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
}

View File

@@ -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;
}

View File

@@ -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<String, Object> params;
public Map<String, Object> getParams() {
if (params == null) {
params = new HashMap<>();
}
return params;
}
public int getMinute() {
if (minute > 59 || minute < 1) {
this.minute = 5;
}
return minute;
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
{
}

View File

@@ -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
{
}

View File

@@ -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
{
}

View File

@@ -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
{
}

View File

@@ -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<IItemVo> 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();
}

View File

@@ -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<ILogVo> 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();
}

View File

@@ -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<IShopVo> 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<IShop> iShopList);
/**
* 查询门店列表
*
* @param iShopId 门店列表主键
* @return 门店列表
*/
public IShopVo selectIShopByIShopId(String iShopId);
}

View File

@@ -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<IUserVo> 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<IUser> selectReservationUser();
/**
* 通过预约执行分钟查询预约用户列表
*/
List<IUser> selectReservationUserByMinute(IUserDto iUserDto);
void updateUserMinuteBatch();
void updateUserMinuteEven();
}

View File

@@ -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<IItemVo> 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);
}

View File

@@ -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);
}
};
}
}

View File

@@ -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<ILogVo> 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();
}

View File

@@ -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();
}

View File

@@ -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<IShopVo> 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<IMTItemInfo> 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);
}

View File

@@ -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<IUser> selectReservationUser();
/**
* 通过预约执行分钟查询预约用户列表
*
* @return
*/
List<IUser> 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<IUserVo> selectIUserList(IUserDto iUserDto);
}

View File

@@ -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<IItemVo> 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);
}
}

View File

@@ -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<ILogVo> 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();
}
}

View File

@@ -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\">(.*?)</p>", 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<String, Object> 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<String, String> 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());
//随机延迟35秒
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<String, Integer> 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<String, Integer> 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<String, Integer> 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<IUser> 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<IUser> iUsers = iUserService.selectReservationUserByMinute(minute);
// List<IUser> 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<IUser> 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<String, Object> map = new HashMap<>();
JSONArray itemArray = new JSONArray();
Map<String, Object> 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;
}
}

View File

@@ -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<IShopVo> 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<String> shopIdSet = jsonObject.keySet();
List<IShop> 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<IShop> list){
List<List<IShop>> 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<IMTItemInfo> getShopsByProvince(String province, String itemId) {
String key = "mt_province:" + province + "." + getCurrentSessionId() + "." + itemId;
List<IMTItemInfo> cacheList = redisCache.getCacheList(key);
if (cacheList != null && cacheList.size() > 0) {
return cacheList;
} else {
List<IMTItemInfo> imtItemInfoList = reGetShopsByProvince(province, itemId);
redisCache.reSetCacheList(key, imtItemInfoList);
redisCache.expire(key, 60, TimeUnit.MINUTES);
return imtItemInfoList;
}
}
public List<IMTItemInfo> 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<IMTItemInfo> 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<IMTItemInfo> shopList = getShopsByProvince(province, itemId);
//取id集合
List<String> shopIdList = shopList.stream().map(IMTItemInfo::getShopId).collect(Collectors.toList());
//获取门店列表
List<IShopVo> iShops = selectIShopList(new IShopDto());
//获取今日的门店信息列表
List<IShop> 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<IMTItemInfo> list1, List<IShop> list2, String city) {
//本城市的shopId集合
List<String> cityShopIdList = list2.stream().filter(iShop -> iShop.getCityName().contains(city))
.map(IShop::getIShopId).collect(Collectors.toList());
List<IMTItemInfo> 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<IShop> list2, String province, String lat, String lng) {
//本省的
List<IShop> 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<IShop> 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);
}
}

View File

@@ -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<IUser> selectReservationUser() {
return iUserMapper.selectReservationUser();
}
@Override
public List<IUser> 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<IUserVo> selectIUserList(IUserDto iUserDto)
{
return iUserMapper.selectIUserList(iUserDto);
}
}

View File

@@ -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();
}
/**
* 110 批量修改用户随机预约的时间
*/
@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();
}
}

View File

@@ -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;
/**
* 110 批量修改用户随机预约的时间
*/
@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();
}
}

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.invest.mapper.IItemMapper">
<resultMap type="IItemVo" id="IItemResult">
<result property="itemId" column="item_id" />
<result property="itemCode" column="item_code" />
<result property="title" column="title" />
<result property="content" column="content" />
<result property="picture" column="picture" />
<result property="createTime" column="create_time" />
</resultMap>
<sql id="selectIItemVo">
select a.item_id, a.item_code, a.title, a.content, a.picture, a.create_time from i_item a
</sql>
<select id="selectIItemList" parameterType="IItemDto" resultMap="IItemResult">
<include refid="selectIItemVo"/>
<where>
a.del_flag='0'
<if test="itemCode != null and itemCode != ''"> and a.item_code = #{itemCode}</if>
<if test="title != null and title != ''"> and a.title = #{title}</if>
<if test="content != null and content != ''"> and a.content = #{content}</if>
</where>
order by a.create_time desc
</select>
<select id="selectIItemByItemId" parameterType="Long" resultMap="IItemResult">
<include refid="selectIItemVo"/>
where a.item_id = #{itemId}
</select>
<insert id="insertIItem" parameterType="IItem">
insert into i_item
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="itemId != null">item_id,</if>
<if test="itemCode != null">item_code,</if>
<if test="title != null">title,</if>
<if test="content != null">content,</if>
<if test="picture != null">picture,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="itemId != null">#{itemId},</if>
<if test="itemCode != null">#{itemCode},</if>
<if test="title != null">#{title},</if>
<if test="content != null">#{content},</if>
<if test="picture != null">#{picture},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<update id="updateIItem" parameterType="IItem">
update i_item
<trim prefix="SET" suffixOverrides=",">
<if test="itemCode != null">item_code = #{itemCode},</if>
<if test="title != null">title = #{title},</if>
<if test="content != null">content = #{content},</if>
<if test="picture != null">picture = #{picture},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
where item_id = #{itemId}
</update>
<delete id="deleteIItemByItemId" parameterType="Long">
delete from i_item where item_id = #{itemId}
</delete>
<delete id="deleteIItemByItemIds" parameterType="String">
delete from i_item where item_id in
<foreach item="itemId" collection="array" open="(" separator="," close=")">
#{itemId}
</foreach>
</delete>
<update id="removeIItemByItemId" parameterType="Long">
update i_item set del_flag='1' where item_id = #{itemId}
</update>
<update id="removeIItemByItemIds" parameterType="String">
update i_item set del_flag='1' where item_id in
<foreach item="itemId" collection="array" open="(" separator="," close=")">
#{itemId}
</foreach>
</update>
<update id="truncateItem" >
TRUNCATE TABLE i_item
</update>
</mapper>

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.invest.mapper.ILogMapper">
<resultMap type="ILogVo" id="ILogResult">
<result property="logId" column="log_id" />
<result property="mobile" column="mobile" />
<result property="logContent" column="log_content" />
<result property="status" column="status" />
<result property="operTime" column="oper_time" />
<result property="createUser" column="create_user" />
<result property="createBy" column="create_by" />
</resultMap>
<sql id="selectILogVo">
select a.log_id, a.mobile, a.log_content, a.status, a.oper_time, a.create_user, a.create_by from i_log a
</sql>
<select id="selectILogList" parameterType="ILogDto" resultMap="ILogResult">
<include refid="selectILogVo"/>
<where>
a.del_flag='0'
<if test="mobile != null "> and a.mobile = #{mobile}</if>
<if test="logContent != null and logContent != ''"> and a.log_content = #{logContent}</if>
<if test="status != null and status != ''"> and a.status = #{status}</if>
<if test="operTime != null "> and a.oper_time = #{operTime}</if>
</where>
order by a.create_time desc
</select>
<select id="selectILogByLogId" parameterType="Long" resultMap="ILogResult">
<include refid="selectILogVo"/>
where a.log_id = #{logId}
</select>
<insert id="insertILog" parameterType="ILog">
insert into i_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="logId != null">log_id,</if>
<if test="mobile != null">mobile,</if>
<if test="logContent != null">log_content,</if>
<if test="status != null">status,</if>
<if test="operTime != null">oper_time,</if>
<if test="createUser != null">create_user,</if>
<if test="createBy != null">create_by,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="logId != null">#{logId},</if>
<if test="mobile != null">#{mobile},</if>
<if test="logContent != null">#{logContent},</if>
<if test="status != null">#{status},</if>
<if test="operTime != null">#{operTime},</if>
<if test="createUser != null">#{createUser},</if>
<if test="createBy != null">#{createBy},</if>
</trim>
</insert>
<update id="updateILog" parameterType="ILog">
update i_log
<trim prefix="SET" suffixOverrides=",">
<if test="mobile != null">mobile = #{mobile},</if>
<if test="logContent != null">log_content = #{logContent},</if>
<if test="status != null">status = #{status},</if>
<if test="operTime != null">oper_time = #{operTime},</if>
<if test="createUser != null">create_user = #{createUser},</if>
<if test="createBy != null">create_by = #{createBy},</if>
</trim>
where log_id = #{logId}
</update>
<delete id="deleteILogByLogId" parameterType="Long">
delete from i_log where log_id = #{logId}
</delete>
<delete id="deleteILogByLogIds" parameterType="String">
delete from i_log where log_id in
<foreach item="logId" collection="array" open="(" separator="," close=")">
#{logId}
</foreach>
</delete>
<update id="removeILogByLogId" parameterType="Long">
update i_log set del_flag='1' where log_id = #{logId}
</update>
<update id="removeILogByLogIds" parameterType="String">
update i_log set del_flag='1' where log_id in
<foreach item="logId" collection="array" open="(" separator="," close=")">
#{logId}
</foreach>
</update>
<update id="cleanLog" >
TRUNCATE TABLE i_log
</update>
</mapper>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.invest.mapper.IShopMapper">
<resultMap type="IShopVo" id="IShopResult">
<result property="shopId" column="shop_id" />
<result property="iShopId" column="i_shop_id" />
<result property="provinceName" column="province_name" />
<result property="cityName" column="city_name" />
<result property="districtName" column="district_name" />
<result property="fullAddress" column="full_address" />
<result property="lat" column="lat" />
<result property="lng" column="lng" />
<result property="name" column="name" />
<result property="tenantName" column="tenant_name" />
<result property="createTime" column="create_time" />
</resultMap>
<sql id="selectIShopVo">
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
</sql>
<select id="selectIShopList" parameterType="IShopDto" resultMap="IShopResult">
<include refid="selectIShopVo"/>
<where>
a.del_flag='0'
<if test="iShopId != null and iShopId != ''"> and a.i_shop_id = #{iShopId}</if>
<if test="provinceName != null and provinceName != ''"> and a.province_name like '%'|| #{provinceName}||'%'</if>
<if test="cityName != null and cityName != ''"> and a.city_name like '%'|| #{cityName}||'%'</if>
<if test="districtName != null and districtName != ''"> and a.district_name like '%'|| #{districtName}||'%'</if>
<if test="tenantName != null and tenantName != ''"> and a.tenant_name like '%'|| #{tenantName}||'%'</if>
</where>
order by a.create_time desc
</select>
<select id="selectIShopByShopId" parameterType="String" resultMap="IShopResult">
<include refid="selectIShopVo"/>
where a.shop_id = #{shopId}
</select>
<insert id="insertIShop" parameterType="IShop">
insert into i_shop
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="shopId != null">shop_id,</if>
<if test="iShopId != null">i_shop_id,</if>
<if test="provinceName != null">province_name,</if>
<if test="cityName != null">city_name,</if>
<if test="districtName != null">district_name,</if>
<if test="fullAddress != null">full_address,</if>
<if test="lat != null">lat,</if>
<if test="lng != null">lng,</if>
<if test="name != null">name,</if>
<if test="tenantName != null">tenant_name,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="shopId != null">#{shopId},</if>
<if test="iShopId != null">#{iShopId},</if>
<if test="provinceName != null">#{provinceName},</if>
<if test="cityName != null">#{cityName},</if>
<if test="districtName != null">#{districtName},</if>
<if test="fullAddress != null">#{fullAddress},</if>
<if test="lat != null">#{lat},</if>
<if test="lng != null">#{lng},</if>
<if test="name != null">#{name},</if>
<if test="tenantName != null">#{tenantName},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<update id="updateIShop" parameterType="IShop">
update i_shop
<trim prefix="SET" suffixOverrides=",">
<if test="iShopId != null">i_shop_id = #{iShopId},</if>
<if test="provinceName != null">province_name = #{provinceName},</if>
<if test="cityName != null">city_name = #{cityName},</if>
<if test="districtName != null">district_name = #{districtName},</if>
<if test="fullAddress != null">full_address = #{fullAddress},</if>
<if test="lat != null">lat = #{lat},</if>
<if test="lng != null">lng = #{lng},</if>
<if test="name != null">name = #{name},</if>
<if test="tenantName != null">tenant_name = #{tenantName},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
where shop_id = #{shopId}
</update>
<delete id="deleteIShopByShopId" parameterType="String">
delete from i_shop where shop_id = #{shopId}
</delete>
<delete id="deleteIShopByShopIds" parameterType="String">
delete from i_shop where shop_id in
<foreach item="shopId" collection="array" open="(" separator="," close=")">
#{shopId}
</foreach>
</delete>
<update id="removeIShopByShopId" parameterType="String">
update i_shop set del_flag='1' where shop_id = #{shopId}
</update>
<update id="removeIShopByShopIds" parameterType="String">
update i_shop set del_flag='1' where shop_id in
<foreach item="shopId" collection="array" open="(" separator="," close=")">
#{shopId}
</foreach>
</update>
<update id="truncateShop" >
TRUNCATE TABLE i_shop
</update>
<insert id="batchInsertIShop">
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
<foreach item="item" index="index" collection="list" separator=",">
(#{item.shopId},
#{item.iShopId},
#{item.provinceName},
#{item.cityName},
#{item.districtName},
#{item.fullAddress},
#{item.lat},
#{item.lng},
#{item.name},
#{item.tenantName},
#{item.createTime})
</foreach>
</insert>
<select id="selectIShopByIShopId" parameterType="String" resultMap="IShopResult">
<include refid="selectIShopVo"/>
where a.i_shop_id = #{iShopId}
</select>
</mapper>

View File

@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.invest.mapper.IUserMapper">
<resultMap type="IUserVo" id="IUserResult">
<result property="mobile" column="mobile" />
<result property="userId" column="user_id" />
<result property="token" column="token" />
<result property="cookie" column="cookie" />
<result property="deviceId" column="device_id" />
<result property="itemCode" column="item_code" />
<result property="ishopId" column="ishop_id" />
<result property="provinceName" column="province_name" />
<result property="cityName" column="city_name" />
<result property="address" column="address" />
<result property="lat" column="lat" />
<result property="lng" column="lng" />
<result property="minute" column="minute" />
<result property="shopType" column="shop_type" />
<result property="randomMinute" column="random_minute" />
<result property="pushPlusToken" column="push_plus_token" />
<result property="jsonResult" column="json_result" />
<result property="remark" column="remark" />
<result property="expireTime" column="expire_time" />
<result property="delFlag" column="del_flag" />
<result property="createTime" column="create_time" />
<result property="createUser" column="create_user" />
<result property="updateTime" column="update_time" />
<result property="updateUser" column="update_user" />
<result property="createBy" column="create_by" />
</resultMap>
<sql id="selectIUserVo">
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
</sql>
<select id="selectIUserList" parameterType="IUserDto" resultMap="IUserResult">
<include refid="selectIUserVo"/>
<where>
a.del_flag='0'
<if test="mobile != null "> and a.mobile = #{mobile}</if>
<if test="token != null and token != ''"> and a.token = #{token}</if>
<if test="cookie != null and cookie != ''"> and a.cookie = #{cookie}</if>
<if test="deviceId != null and deviceId != ''"> and a.device_id = #{deviceId}</if>
<if test="itemCode != null and itemCode != ''"> and a.item_code = #{itemCode}</if>
<if test="ishopId != null and ishopId != ''"> and a.ishop_id = #{ishopId}</if>
<if test="provinceName != null and provinceName != ''"> and a.province_name like '%'|| #{provinceName}||'%'</if>
<if test="cityName != null and cityName != ''"> and a.city_name like '%'|| #{cityName}||'%'</if>
<if test="address != null and address != ''"> and a.address = #{address}</if>
<if test="lat != null and lat != ''"> and a.lat = #{lat}</if>
<if test="lng != null and lng != ''"> and a.lng = #{lng}</if>
<if test="minute != null "> and a.minute = #{minute}</if>
<if test="shopType != null "> and a.shop_type = #{shopType}</if>
<if test="randomMinute != null and randomMinute != ''"> and a.random_minute = #{randomMinute}</if>
<if test="pushPlusToken != null and pushPlusToken != ''"> and a.push_plus_token = #{pushPlusToken}</if>
<if test="jsonResult != null and jsonResult != ''"> and a.json_result = #{jsonResult}</if>
<if test="expireTime != null "> and a.expire_time = #{expireTime}</if>
<if test="createUser != null and createUser != ''"> and a.create_user = #{createUser}</if>
<if test="updateUser != null and updateUser != ''"> and a.update_user = #{updateUser}</if>
</where>
order by a.create_time desc
</select>
<select id="selectIUserByMobile" parameterType="Long" resultMap="IUserResult">
<include refid="selectIUserVo"/>
where a.mobile = #{mobile}
</select>
<insert id="insertIUser" parameterType="IUser">
insert into i_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="mobile != null">mobile,</if>
<if test="userId != null">user_id,</if>
<if test="token != null and token != ''">token,</if>
<if test="cookie != null and cookie != ''">cookie,</if>
<if test="deviceId != null">device_id,</if>
<if test="itemCode != null and itemCode != ''">item_code,</if>
<if test="ishopId != null">ishop_id,</if>
<if test="provinceName != null">province_name,</if>
<if test="cityName != null">city_name,</if>
<if test="address != null">address,</if>
<if test="lat != null">lat,</if>
<if test="lng != null">lng,</if>
<if test="minute != null">minute,</if>
<if test="shopType != null">shop_type,</if>
<if test="randomMinute != null">random_minute,</if>
<if test="pushPlusToken != null">push_plus_token,</if>
<if test="jsonResult != null">json_result,</if>
<if test="remark != null">remark,</if>
<if test="expireTime != null">expire_time,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createTime != null">create_time,</if>
<if test="createUser != null">create_user,</if>
<if test="updateTime != null">update_time,</if>
<if test="updateUser != null">update_user,</if>
<if test="createBy != null">create_by,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="mobile != null">#{mobile},</if>
<if test="userId != null">#{userId},</if>
<if test="token != null and token != ''">#{token},</if>
<if test="cookie != null and cookie != ''">#{cookie},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="itemCode != null and itemCode != ''">#{itemCode},</if>
<if test="ishopId != null">#{ishopId},</if>
<if test="provinceName != null">#{provinceName},</if>
<if test="cityName != null">#{cityName},</if>
<if test="address != null">#{address},</if>
<if test="lat != null">#{lat},</if>
<if test="lng != null">#{lng},</if>
<if test="minute != null">#{minute},</if>
<if test="shopType != null">#{shopType},</if>
<if test="randomMinute != null">#{randomMinute},</if>
<if test="pushPlusToken != null">#{pushPlusToken},</if>
<if test="jsonResult != null">#{jsonResult},</if>
<if test="remark != null">#{remark},</if>
<if test="expireTime != null">#{expireTime},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createTime != null">#{createTime},</if>
<if test="createUser != null">#{createUser},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="updateUser != null">#{updateUser},</if>
<if test="createBy != null">#{createBy},</if>
</trim>
</insert>
<update id="updateIUser" parameterType="IUser">
update i_user
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="token != null and token != ''">token = #{token},</if>
<if test="cookie != null and cookie != ''">cookie = #{cookie},</if>
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="itemCode != null and itemCode != ''">item_code = #{itemCode},</if>
<if test="ishopId != null">ishop_id = #{ishopId},</if>
<if test="provinceName != null">province_name = #{provinceName},</if>
<if test="cityName != null">city_name = #{cityName},</if>
<if test="address != null">address = #{address},</if>
<if test="lat != null">lat = #{lat},</if>
<if test="lng != null">lng = #{lng},</if>
<if test="minute != null">minute = #{minute},</if>
<if test="shopType != null">shop_type = #{shopType},</if>
<if test="randomMinute != null">random_minute = #{randomMinute},</if>
<if test="pushPlusToken != null">push_plus_token = #{pushPlusToken},</if>
<if test="jsonResult != null">json_result = #{jsonResult},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="expireTime != null">expire_time = #{expireTime},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="createUser != null">create_user = #{createUser},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateUser != null">update_user = #{updateUser},</if>
<if test="createBy != null">create_by = #{createBy},</if>
</trim>
where mobile = #{mobile}
</update>
<delete id="deleteIUserByMobile" parameterType="Long">
delete from i_user where mobile = #{mobile}
</delete>
<delete id="deleteIUserByMobiles" parameterType="String">
delete from i_user where mobile in
<foreach item="mobile" collection="array" open="(" separator="," close=")">
#{mobile}
</foreach>
</delete>
<update id="removeIUserByMobile" parameterType="Long">
update i_user set del_flag='1' where mobile = #{mobile}
</update>
<update id="removeIUserByMobiles" parameterType="String">
update i_user set del_flag='1' where mobile in
<foreach item="mobile" collection="array" open="(" separator="," close=")">
#{mobile}
</foreach>
</update>
<update id="updateUserMinuteBatch">
UPDATE i_user SET `minute` = (SELECT FLOOR(random() * 50 + 1))) WHERE random_minute = '0'
</update>
<update id="updateUserMinuteEven">
UPDATE i_user SET `minute` = (SELECT FLOOR(random() * 50 + 1))) WHERE random_minute = '0'
</update>
<select id="selectReservationUserByMinute" parameterType="IUserDto" resultMap="IUserResult">
<include refid="selectIUserVo"/>
<where>
a.del_flag='0'
and a.lat !=''
and a.lng!=''
and a.item_code!=''
<if test="minute != null "> and a.minute = #{minute}</if>
</where>
order by a.create_time desc
</select>
<select id="selectReservationUser" resultMap="IUserResult">
<include refid="selectIUserVo"/>
<where>
a.del_flag='0'
and a.lat !=''
and a.lng!=''
and a.item_code!=''
</where>
order by a.create_time desc
</select>
</mapper>