25 Commits

Author SHA1 Message Date
JIAN
e94f791d73 feat(orders.manager):新增运营端分页查询订单的功能 2024-09-22 22:04:16 +08:00
JIAN
35e760435d feat(orders.manager):新增缓存查询的订单信息的功能 2024-09-22 21:37:32 +08:00
JIAN
bd63adf3c6 fix(orders.manager):修复保存的订单快照信息不全的bug 2024-09-22 20:35:23 +08:00
JIAN
b03c51e50a feat(orders.manager):新增状态机管理订单状态 2024-09-21 12:53:45 +08:00
JIAN
554aa38576 fix(orders.manager):修复支付接口的调用参数错误的bug 2024-09-20 10:58:43 +08:00
JIAN
e78ff52701 feat/refactor(orders.manager):新增取消派单中的订单的功能, 整合相关取消订单功能的代码到取消订单业务类 2024-09-13 00:36:56 +08:00
JIAN
f3604d9830 feat(orders.manager):新增取消未支付订单的功能
1. 手动访问取消 2. 自动轮询取消 3. 查询时自动取消
2024-09-10 13:52:06 +08:00
JIAN
edc2cbf7ef refactor(orders.manager):调整更新订单状态代码的实现 2024-09-10 12:29:00 +08:00
JIAN
31c36abeaa feat(orders.manager):新增监听支付成功消息更新支付状态的功能 2024-09-10 11:29:43 +08:00
JIAN
7e0b8840a4 feat(orders.manager):新增用户获取支付结果的功能 2024-09-08 22:37:53 +08:00
JIAN
489513b766 feat(orders.manager):新增用户获取支付二维码支付的功能 2024-09-08 21:29:26 +08:00
JIAN
18ebfcc04f refactor(trade):导入项目支付模块初始工程 2024-09-08 19:20:34 +08:00
JIAN
85b6192ba1 feat(orders.manager):新增用户下单的功能 2024-09-08 17:38:43 +08:00
JIAN
27dc6c16af feat(customer):新增查询地址和服务接口的熔断策略类 2024-09-02 23:14:15 +08:00
JIAN
2781689e77 feat(customer):新增查询地址信息的内部接口 2024-09-02 22:23:41 +08:00
JIAN
c2d0d9b647 feat(foundations):新增查询服务详情的内部接口 2024-09-02 22:23:40 +08:00
JIAN
de68066d84 refactor(orders):导入项目订单模块初始工程 2024-09-02 22:23:40 +08:00
JIAN
fd089d5147 Merge branch 'dev_customer' 2024-09-02 20:05:56 +08:00
JIAN
2b46184d29 feat(foundations):新增客户端检索上架服务功能 2024-08-27 13:17:03 +08:00
JIAN
e743f616c7 feat(foundations):新增同步服务相关修改/新增到ES索引的功能 2024-08-27 00:37:14 +08:00
JIAN
ba389a4b80 feat(foundations):完善服务项和服务详情查询缓存的功能 2024-08-25 17:28:47 +08:00
JIAN
179bc9560f feat(foundations):完善区域相关缓存更新的功能 2024-08-25 16:44:23 +08:00
JIAN
0d694db8b8 feat(foundations):增加查询首页热门服务和服务列表的功能 2024-08-25 16:40:14 +08:00
JIAN
1e9a265ecc feat(foundations):增加查询区域上架服务类型的功能 2024-08-25 16:38:04 +08:00
JIAN
9e78b3de0d feat(foundations):增加开通区域定时缓存的功能 2024-08-25 12:30:38 +08:00
222 changed files with 11585 additions and 103 deletions

View File

@@ -0,0 +1,19 @@
package com.jzo2o.api.customer;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 内部接口 - 地址簿相关接口
* @author JIAN
*/
@FeignClient(contextId = "jzo2o-customer", value = "jzo2o-customer", path = "/customer/inner/address-book")
public interface AddressBookApi {
/**
* 获取指定id对应的地址信息
*/
@GetMapping("/{id}")
AddressBookResDTO getById(@PathVariable Long id);
}

View File

@@ -4,14 +4,16 @@ import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* 内部接口 - 服务相关接口
* @author JIAN
*/
@FeignClient(contextId = "jzo2o-foundations", value = "jzo2o-foundations", path = "/foundations/inner/serve") @FeignClient(contextId = "jzo2o-foundations", value = "jzo2o-foundations", path = "/foundations/inner/serve")
public interface ServeApi { public interface ServeApi {
/**
* 根据服务id获取服务信息
*/
@GetMapping("/{id}") @GetMapping("/{id}")
ServeAggregationResDTO findById(@PathVariable("id") Long id); ServeAggregationResDTO findById(@PathVariable("id") Long id);
}
}

View File

@@ -2,13 +2,18 @@ package com.jzo2o.api.trade.dto.request;
import com.jzo2o.api.trade.enums.PayChannelEnum; import com.jzo2o.api.trade.enums.PayChannelEnum;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
/**
* 支付服务请求参数
* @author JIAN
*/
@Data @Data
@Builder
public class NativePayReqDTO { public class NativePayReqDTO {
@ApiModelProperty(value = "商户号", required = true) @ApiModelProperty(value = "商户号", required = true)
private Long enterpriseId; private Long enterpriseId;
@ApiModelProperty(value = "业务系统标识", required = true) @ApiModelProperty(value = "业务系统标识", required = true)
@@ -27,5 +32,4 @@ public class NativePayReqDTO {
@ApiModelProperty(value = "是否切换支付渠道", required = true) @ApiModelProperty(value = "是否切换支付渠道", required = true)
private boolean changeChannel=false; private boolean changeChannel=false;
}
}

View File

@@ -0,0 +1,34 @@
package com.jzo2o.customer.controller.inner;
import com.jzo2o.api.customer.AddressBookApi;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.customer.service.IAddressBookService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 内部接口 - 地址簿相关接口
* @author JIAN
*/
@RestController
@RequestMapping("/inner/address-book")
@Api(tags = "内部接口 - 地址簿相关接口")
public class InnerAddressBookController implements AddressBookApi {
@Resource
private IAddressBookService addressBookService;
/**
* 获取指定id对应的地址信息
*/
@Override
@GetMapping("/{id}")
public AddressBookResDTO getById(@PathVariable Long id) {
return BeanUtils.toBean(addressBookService.getById(id), AddressBookResDTO.class);
}
}

View File

@@ -41,11 +41,6 @@
<artifactId>jzo2o-knife4j-web</artifactId> <artifactId>jzo2o-knife4j-web</artifactId>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>com.jzo2o</groupId>-->
<!-- <artifactId>jzo2o-es</artifactId>-->
<!-- </dependency>-->
<!--单元测试--> <!--单元测试-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@@ -63,23 +58,28 @@
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-es</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-canal-sync</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.jzo2o</groupId> <groupId>com.jzo2o</groupId>
<artifactId>jzo2o-redis</artifactId> <artifactId>jzo2o-redis</artifactId>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>com.jzo2o</groupId>-->
<!-- <artifactId>jzo2o-canal-sync</artifactId>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>com.jzo2o</groupId> <groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mysql</artifactId> <artifactId>jzo2o-mysql</artifactId>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>com.jzo2o</groupId>--> <dependency>
<!-- <artifactId>jzo2o-xxl-job</artifactId>--> <groupId>com.jzo2o</groupId>
<!-- </dependency>--> <artifactId>jzo2o-xxl-job</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -0,0 +1,69 @@
package com.jzo2o.foundations.controller.consumer;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.foundations.service.IServeTypeService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 用户端 - 服务相关接口
* @author JIAN
*/
@RestController("consumerServeController")
@RequestMapping("/customer/serve")
@Api(tags = "用户端 - 服务相关接口")
public class ServeController {
/**
* 获取首页服务类型及服务项
*/
@GetMapping("/firstPageServeList")
public List<ServeCategoryResDTO> getFirstPageServeList(@RequestParam Long regionId) {
return serveService.getFirstPageServeList(regionId);
}
/**
* 获取全部服务类型
*/
@GetMapping("/serveTypeList")
public List<ServeAggregationTypeSimpleResDTO> getServeTypeList(@RequestParam Long regionId) {
return serveTypeService.getServeTypeList(regionId);
}
/**
* 获取热门服务项
*/
@GetMapping("/hotServeList")
public List<ServeAggregationSimpleResDTO> getHotServeList(@RequestParam Long regionId) {
return serveService.getHotServeList(regionId);
}
/**
* 获取指定id的服务详情
*/
@GetMapping("/{id}")
public ServeAggregationSimpleResDTO getServeById(@PathVariable("id") Long serveId) {
return serveService.getServeById(serveId);
}
/**
* 服务查询
*/
@GetMapping("/search")
public List<ServeSimpleResDTO> findServeList(@RequestParam() String cityCode,
@RequestParam(required = false) Long serveTypeId,
@RequestParam(required = false) String keyword) {
return serveService.findServeList(cityCode, serveTypeId, keyword);
}
@Resource
private IServeService serveService;
@Resource
private IServeTypeService serveTypeService;
}

View File

@@ -0,0 +1,32 @@
package com.jzo2o.foundations.controller.inner;
import com.jzo2o.api.foundations.ServeApi;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.foundations.service.IServeService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author JIAN
*/
@RestController
@RequestMapping("/inner/serve")
@Api(tags = "内部接口 - 服务相关接口")
public class InnerServeController implements ServeApi {
@Resource
private IServeService serveService;
/**
* 根据服务id获取服务信息
*/
@Override
@GetMapping("/{id}")
public ServeAggregationResDTO findById(@PathVariable Long id) {
return serveService.getServeAggregationById(id);
}
}

View File

@@ -107,7 +107,6 @@ public class RegionController {
@PutMapping("/refreshRegionRelateCaches/{id}") @PutMapping("/refreshRegionRelateCaches/{id}")
@ApiOperation("刷新区域相关缓存") @ApiOperation("刷新区域相关缓存")
public void refreshRegionRelateCaches(@PathVariable("id") Long id) { public void refreshRegionRelateCaches(@PathVariable("id") Long id) {
//todo regionService.refreshRegionRelateCaches(id);
// homeService.refreshRegionRelateCaches(id);
} }
} }

View File

@@ -0,0 +1,60 @@
package com.jzo2o.foundations.handler;
import com.jzo2o.canal.listeners.AbstractCanalRabbitMqMsgListener;
import com.jzo2o.es.core.ElasticSearchTemplate;
import com.jzo2o.foundations.constants.IndexConstants;
import com.jzo2o.foundations.model.domain.ServeSync;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 接受从Canal发送的MQ消息并解析处理完成ES的索引更新
* @author JIAN
*/
@Slf4j
@Component
public class ServeCanalDataSyncHandler extends AbstractCanalRabbitMqMsgListener<ServeSync> {
/**
* 监听MQ的消息
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange(name = "exchange.canal-jzo2o", type = ExchangeTypes.TOPIC),
value = @Queue(name = "canal-mq-jzo2o-foundations",
// 限制单消费者保证顺序性
arguments = @Argument(name = "x-single-active-consumer", value = "true", type = "java.lang.Boolean")),
key = "canal-mq-jzo2o-foundations"),
// 限制单进程消费保证顺序性
concurrency = "1")
public void onMessage(Message message) throws Exception {
parseMsg(message);
}
@Resource
private ElasticSearchTemplate elasticSearchTemplate;
@Override
public void batchSave(List<ServeSync> data) {
Boolean isSuccess = elasticSearchTemplate.opsForDoc().batchInsert(IndexConstants.SERVE, data);
log.warn("[batchSave] status: {} data: {}", isSuccess, data.toString());
if (!isSuccess) {
// 通过抛出异常自动发送unack消息
throw new RuntimeException("同步失败");
}
}
@Override
public void batchDelete(List<Long> ids) {
Boolean isSuccess = elasticSearchTemplate.opsForDoc().batchDelete(IndexConstants.SERVE, ids);
log.warn("[batchDelete] status: {} ids: {}", isSuccess, ids.toString());
if (!isSuccess) {
// 通过抛出异常自动发送unack消息
throw new RuntimeException("同步失败");
}
}
}

View File

@@ -0,0 +1,41 @@
package com.jzo2o.foundations.handler;
import com.jzo2o.api.foundations.dto.response.RegionSimpleResDTO;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.service.IRegionService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* xxl-job定时任务执行器
* @author JIAN
*/
@Slf4j
@Component
@SuppressWarnings("unused")
public class SpringCacheSyncHandler {
@XxlJob("activeRegionCacheSync")
public void activeRegionCacheSync() {
log.info(">>>>>>>>开始进行缓存同步,更新已启用区域");
// 清理开通服务区域缓存
redisTemplate.delete(RedisConstants.CacheName.JZ_CACHE + "::ACTIVE_REGIONS");
// 更新开通服务区域缓存
List<RegionSimpleResDTO> regionList = regionService.queryActiveRegionListCache();
// 更新每个区域对应的缓存
regionList.forEach(region -> regionService.refreshRegionRelateCaches(region.getId()));
log.info(">>>>>>>>缓存同步结束,完成更新已启用区域");
}
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private IRegionService regionService;
}

View File

@@ -1,7 +1,10 @@
package com.jzo2o.foundations.mapper; package com.jzo2o.foundations.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.foundations.model.domain.Serve; import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO; import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@@ -20,4 +23,21 @@ public interface ServeMapper extends BaseMapper<Serve> {
* @param regionId 区域id * @param regionId 区域id
*/ */
List<ServeResDTO> queryServeListByRegionId(@Param("regionId") Long regionId); List<ServeResDTO> queryServeListByRegionId(@Param("regionId") Long regionId);
/**
* 区域服务图标查询
* @param regionId 区域id
*/
List<ServeCategoryResDTO> queryServeIconListByRegionId(@Param("regionId") Long regionId);
/**
* 区域热门服务查询
* @param regionId 区域id
*/
List<ServeAggregationSimpleResDTO> queryHotServeListByRegionId(Long regionId);
/**
* 查询指定id的服务信息
*/
ServeAggregationResDTO getServeAggregationById(Long id);
} }

View File

@@ -1,8 +1,10 @@
package com.jzo2o.foundations.mapper; package com.jzo2o.foundations.mapper;
import com.jzo2o.foundations.model.domain.ServeType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import com.jzo2o.foundations.model.domain.ServeType;
import com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO;
import java.util.List;
/** /**
* <p> * <p>
@@ -13,4 +15,8 @@ import org.apache.ibatis.annotations.Mapper;
* @since 2023-07-03 * @since 2023-07-03
*/ */
public interface ServeTypeMapper extends BaseMapper<ServeType> { public interface ServeTypeMapper extends BaseMapper<ServeType> {
} /**
* 根据区域id查询简略列表
*/
List<ServeAggregationTypeSimpleResDTO> getServeTypeListByRegionId(Long regionId);
}

View File

@@ -3,6 +3,7 @@ package com.jzo2o.foundations.model.domain;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -19,6 +20,7 @@ import java.math.BigDecimal;
* @since 2023-07-10 * @since 2023-07-10
*/ */
@Data @Data
@Builder
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) @Accessors(chain = true)
@TableName("serve_sync") @TableName("serve_sync")
@@ -112,4 +114,4 @@ public class ServeSync implements Serializable {
private String serveItemIcon; private String serveItemIcon;
} }

View File

@@ -6,7 +6,6 @@ import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.model.domain.Region; import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.dto.request.RegionPageQueryReqDTO; import com.jzo2o.foundations.model.dto.request.RegionPageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.RegionUpsertReqDTO; import com.jzo2o.foundations.model.dto.request.RegionUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.RegionDisplayResDTO;
import com.jzo2o.foundations.model.dto.response.RegionResDTO; import com.jzo2o.foundations.model.dto.response.RegionResDTO;
import java.util.List; import java.util.List;
@@ -61,8 +60,9 @@ public interface IRegionService extends IService<Region> {
* 区域启用 * 区域启用
* *
* @param id 区域id * @param id 区域id
* @return 用于更新缓存信息
*/ */
void active(Long id); List<RegionSimpleResDTO> active(Long id);
/** /**
* 区域禁用 * 区域禁用
@@ -78,4 +78,9 @@ public interface IRegionService extends IService<Region> {
*/ */
List<RegionSimpleResDTO> queryActiveRegionListCache(); List<RegionSimpleResDTO> queryActiveRegionListCache();
} /**
* 刷新区域相关的缓存(首页图标、热门服务、服务类型)
* @param id 区域id
*/
void refreshRegionRelateCaches(Long id);
}

View File

@@ -20,6 +20,11 @@ import java.util.List;
* @since 2023-07-03 * @since 2023-07-03
*/ */
public interface IServeItemService extends IService<ServeItem> { public interface IServeItemService extends IService<ServeItem> {
/**
* 查询指定id的服务项并缓存
*/
ServeItem selectByIdCache(Long id);
/** /**
* 服务项新增 * 服务项新增
* *
@@ -97,4 +102,4 @@ public interface IServeItemService extends IService<ServeItem> {
* @return 服务项目录 * @return 服务项目录
*/ */
List<ServeTypeCategoryResDTO> queryActiveServeItemCategory(); List<ServeTypeCategoryResDTO> queryActiveServeItemCategory();
} }

View File

@@ -1,11 +1,15 @@
package com.jzo2o.foundations.service; package com.jzo2o.foundations.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.common.model.PageResult; import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.model.domain.Serve; import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO; import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO; import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO; import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
@@ -15,6 +19,11 @@ import java.util.List;
* @author JIAN * @author JIAN
*/ */
public interface IServeService extends IService<Serve> { public interface IServeService extends IService<Serve> {
/**
* 查询指定id的服务并缓存
*/
Serve selectByIdCache(Long id);
/** /**
* 区域服务分页查询 * 区域服务分页查询
* @param servePageQueryReqDTO 分页参数 * @param servePageQueryReqDTO 分页参数
@@ -40,7 +49,7 @@ public interface IServeService extends IService<Serve> {
/** /**
* 设置指定的服务下架 * 设置指定的服务下架
*/ */
Serve updateOffSale(Long id); void updateOffSale(Long id);
/** /**
* 删除指定的服务 * 删除指定的服务
@@ -50,10 +59,37 @@ public interface IServeService extends IService<Serve> {
/** /**
* 设置指定服务热门 * 设置指定服务热门
*/ */
Serve updateOnHot(Long id); void updateOnHot(Long id);
/** /**
* 取消指定服务热门 * 取消指定服务热门
*/ */
Serve updateOffHot(Long id); void updateOffHot(Long id);
/**
* 获取首页服务类型及服务项
* @param regionId 地区id
*/
List<ServeCategoryResDTO> getFirstPageServeList(Long regionId);
/**
* 获取首页热门服务
* @param regionId 地区id
*/
List<ServeAggregationSimpleResDTO> getHotServeList(Long regionId);
/**
* 获取指定id的服务
*/
ServeAggregationSimpleResDTO getServeById(Long serveId);
/**
* 查询指定区域的服务
*/
List<ServeSimpleResDTO> findServeList(String cityCode, Long serveTypeId, String keyword);
/**
* 获取指定id的服务
*/
ServeAggregationResDTO getServeAggregationById(Long id);
} }

View File

@@ -6,6 +6,7 @@ import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.model.domain.ServeType; import com.jzo2o.foundations.model.domain.ServeType;
import com.jzo2o.foundations.model.dto.request.ServeTypePageQueryReqDTO; import com.jzo2o.foundations.model.dto.request.ServeTypePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeTypeUpsertReqDTO; import com.jzo2o.foundations.model.dto.request.ServeTypeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeTypeResDTO; import com.jzo2o.foundations.model.dto.response.ServeTypeResDTO;
import java.util.List; import java.util.List;
@@ -67,4 +68,9 @@ public interface IServeTypeService extends IService<ServeType> {
* @return 服务类型列表 * @return 服务类型列表
*/ */
List<ServeTypeSimpleResDTO> queryServeTypeListByActiveStatus(Integer activeStatus); List<ServeTypeSimpleResDTO> queryServeTypeListByActiveStatus(Integer activeStatus);
}
/**
* 根据区域id查询简略列表
*/
List<ServeAggregationTypeSimpleResDTO> getServeTypeList(Long regionId);
}

View File

@@ -23,8 +23,11 @@ import com.jzo2o.foundations.model.dto.request.RegionUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.RegionResDTO; import com.jzo2o.foundations.model.dto.response.RegionResDTO;
import com.jzo2o.foundations.service.IConfigRegionService; import com.jzo2o.foundations.service.IConfigRegionService;
import com.jzo2o.foundations.service.IRegionService; import com.jzo2o.foundations.service.IRegionService;
import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.foundations.service.IServeTypeService;
import com.jzo2o.mysql.utils.PageUtils; import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching; import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -47,6 +50,10 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
private CityDirectoryMapper cityDirectoryMapper; private CityDirectoryMapper cityDirectoryMapper;
@Resource @Resource
private ServeMapper serveMapper; private ServeMapper serveMapper;
@Resource
private IServeService serveService;
@Resource
private IServeTypeService serveTypeService;
/** /**
* 区域新增 * 区域新增
@@ -151,18 +158,18 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
@CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.SERVE_ICON, key = "#id", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.SERVE_ICON, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.HOT_SERVE, key = "#id", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.HOT_SERVE, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.SERVE_TYPE, key = "#id", beforeInvocation = true) @CacheEvict(value = RedisConstants.CacheName.SERVE_TYPE, key = "#id", beforeInvocation = true)},
}) put = @CachePut(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'"))
public void active(Long id) { public List<RegionSimpleResDTO> active(Long id) {
//区域信息 // 区域信息
Region region = baseMapper.selectById(id); Region region = baseMapper.selectById(id);
//启用状态 // 启用状态
Integer activeStatus = region.getActiveStatus(); Integer activeStatus = region.getActiveStatus();
//草稿或禁用状态方可启用 // 草稿或禁用状态方可启用
if (!(FoundationStatusEnum.INIT.getStatus() == activeStatus || FoundationStatusEnum.DISABLE.getStatus() == activeStatus)) { if (!(FoundationStatusEnum.INIT.getStatus() == activeStatus || FoundationStatusEnum.DISABLE.getStatus() == activeStatus)) {
throw new ForbiddenOperationException("草稿或禁用状态方可启用"); throw new ForbiddenOperationException("草稿或禁用状态方可启用");
} }
//如果需要启用区域,需要校验该区域下是否有上架的服务 // 如果需要启用区域,需要校验该区域下是否有上架的服务
LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery() LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery()
.eq(Serve::getRegionId, id) .eq(Serve::getRegionId, id)
.eq(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus()); .eq(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus());
@@ -170,14 +177,16 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
throw new ForbiddenOperationException("该区域没有上架的服务不可启用"); throw new ForbiddenOperationException("该区域没有上架的服务不可启用");
} }
//更新启用状态 // 更新启用状态
LambdaUpdateWrapper<Region> updateWrapper = Wrappers.<Region>lambdaUpdate() LambdaUpdateWrapper<Region> updateWrapper = Wrappers.<Region>lambdaUpdate()
.eq(Region::getId, id) .eq(Region::getId, id)
.set(Region::getActiveStatus, FoundationStatusEnum.ENABLE.getStatus()); .set(Region::getActiveStatus, FoundationStatusEnum.ENABLE.getStatus());
update(updateWrapper); update(updateWrapper);
//3.如果是启用操作,刷新缓存:启用区域列表、首页图标、热门服务、服务类型 // 刷新区域相关缓存
// todo this.refreshRegionRelateCaches(id);
// 通过返回值更新开通服务区域缓存
return queryActiveRegionList();
} }
/** /**
@@ -190,19 +199,18 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
@CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.SERVE_ICON, key = "#id", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.SERVE_ICON, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.HOT_SERVE, key = "#id", beforeInvocation = true), @CacheEvict(value = RedisConstants.CacheName.HOT_SERVE, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.SERVE_TYPE, key = "#id", beforeInvocation = true) @CacheEvict(value = RedisConstants.CacheName.SERVE_TYPE, key = "#id", beforeInvocation = true)})
})
public void deactivate(Long id) { public void deactivate(Long id) {
//区域信息 // 区域信息
Region region = baseMapper.selectById(id); Region region = baseMapper.selectById(id);
//启用状态 // 启用状态
Integer activeStatus = region.getActiveStatus(); Integer activeStatus = region.getActiveStatus();
//启用状态方可禁用 // 启用状态方可禁用
if (!(FoundationStatusEnum.ENABLE.getStatus() == activeStatus)) { if (!(FoundationStatusEnum.ENABLE.getStatus() == activeStatus)) {
throw new ForbiddenOperationException("启用状态方可禁用"); throw new ForbiddenOperationException("启用状态方可禁用");
} }
//如果禁用区域下有上架的服务则无法禁用 // 如果禁用区域下有上架的服务则无法禁用
LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery() LambdaQueryWrapper<Serve> queryWrapper = Wrappers.<Serve>lambdaQuery()
.eq(Serve::getRegionId, id) .eq(Serve::getRegionId, id)
.eq(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus()); .eq(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus());
@@ -210,7 +218,7 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
throw new ForbiddenOperationException("该区域存在上架的服务不可禁用"); throw new ForbiddenOperationException("该区域存在上架的服务不可禁用");
} }
//更新禁用状态 // 更新禁用状态
LambdaUpdateWrapper<Region> updateWrapper = Wrappers.<Region>lambdaUpdate() LambdaUpdateWrapper<Region> updateWrapper = Wrappers.<Region>lambdaUpdate()
.eq(Region::getId, id) .eq(Region::getId, id)
.set(Region::getActiveStatus, FoundationStatusEnum.DISABLE.getStatus()); .set(Region::getActiveStatus, FoundationStatusEnum.DISABLE.getStatus());
@@ -228,4 +236,19 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
return queryActiveRegionList(); return queryActiveRegionList();
} }
@Override
@Caching(evict = {
@CacheEvict(value = RedisConstants.CacheName.SERVE_ICON, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.HOT_SERVE, key = "#id", beforeInvocation = true),
@CacheEvict(value = RedisConstants.CacheName.SERVE_TYPE, key = "#id", beforeInvocation = true)})
public void refreshRegionRelateCaches(Long id) {
// 更新每个区域对应的首页服务列表
serveService.getFirstPageServeList(id);
// 更新每个区域对应的服务类型列表
serveTypeService.getServeTypeList(id);
// 更新每个区域对应的热门服务列表
serveService.getHotServeList(id);
}
} }

View File

@@ -28,6 +28,7 @@ import com.jzo2o.foundations.service.IServeSyncService;
import com.jzo2o.mysql.utils.PageHelperUtils; import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -53,6 +54,12 @@ public class ServeItemServiceImpl extends ServiceImpl<ServeItemMapper, ServeItem
@Resource @Resource
private ServeMapper serveMapper; private ServeMapper serveMapper;
@Override
@Cacheable(value = RedisConstants.CacheName.SERVE_ITEM, key = "#id", cacheManager = RedisConstants.CacheManager.ONE_DAY)
public ServeItem selectByIdCache(Long id) {
return baseMapper.selectById(id);
}
/** /**
* 服务项新增 * 服务项新增
* *

View File

@@ -1,29 +1,49 @@
package com.jzo2o.foundations.service.impl; package com.jzo2o.foundations.service.impl;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.common.expcetions.CommonException; import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.ForbiddenOperationException; import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult; import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils; import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils; import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.es.core.ElasticSearchTemplate;
import com.jzo2o.es.utils.SearchResponseUtils;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.enums.FoundationStatusEnum; import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.enums.HotStatusEnum; import com.jzo2o.foundations.enums.HotStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper; import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.Serve; import com.jzo2o.foundations.mapper.ServeSyncMapper;
import com.jzo2o.foundations.model.domain.ServeItem; import com.jzo2o.foundations.model.domain.*;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO; import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO; import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO; import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import com.jzo2o.foundations.service.IRegionService;
import com.jzo2o.foundations.service.IServeItemService;
import com.jzo2o.foundations.service.IServeService; import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.foundations.service.IServeTypeService;
import com.jzo2o.mysql.utils.PageHelperUtils; import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 区域服务实现类 * 区域服务实现类
@@ -31,6 +51,12 @@ import java.util.List;
*/ */
@Service @Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService { public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {
@Override
@Cacheable(value = RedisConstants.CacheName.SERVE, key = "#id", cacheManager = RedisConstants.CacheManager.ONE_DAY)
public Serve selectByIdCache(Long id) {
return baseMapper.selectById(id);
}
@Override @Override
public PageResult<ServeResDTO> page(ServePageQueryReqDTO servePageQueryReqDTO) { public PageResult<ServeResDTO> page(ServePageQueryReqDTO servePageQueryReqDTO) {
return PageHelperUtils.selectPage(servePageQueryReqDTO, return PageHelperUtils.selectPage(servePageQueryReqDTO,
@@ -43,7 +69,7 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
for (ServeUpsertReqDTO serveItemDTO : serveItems) { for (ServeUpsertReqDTO serveItemDTO : serveItems) {
// 服务项校验 // 服务项校验
Long serveItemId = serveItemDTO.getServeItemId(); Long serveItemId = serveItemDTO.getServeItemId();
ServeItem serveItem = serveItemMapper.selectById(serveItemId); ServeItem serveItem = serveItemService.getById(serveItemId);
if (ObjectUtils.isEmpty(serveItem)) { if (ObjectUtils.isEmpty(serveItem)) {
throw new ForbiddenOperationException("服务项不存在"); throw new ForbiddenOperationException("服务项不存在");
} }
@@ -62,7 +88,7 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
} }
Serve serve = BeanUtils.toBean(serveItemDTO, Serve.class); Serve serve = BeanUtils.toBean(serveItemDTO, Serve.class);
serve.setCityCode(regionMapper.selectById(regionId).getCityCode()); serve.setCityCode(regionService.getById(regionId).getCityCode());
baseMapper.insert(serve); baseMapper.insert(serve);
} }
} }
@@ -81,6 +107,7 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
@Override @Override
@Transactional @Transactional
@CachePut(value = RedisConstants.CacheName.SERVE, key = "#id", unless = "#result.saleStatus != 2", cacheManager = RedisConstants.CacheManager.ONE_DAY)
public Serve updatePrice(Long id, BigDecimal price) { public Serve updatePrice(Long id, BigDecimal price) {
// 区域服务检验 // 区域服务检验
Serve serve = getServeByIdIfExist(id); Serve serve = getServeByIdIfExist(id);
@@ -92,12 +119,20 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
throw new CommonException("价格更新失败"); throw new CommonException("价格更新失败");
} }
// 更新sync数据同步ES
ChainWrappers.lambdaUpdateChain(serveSyncMapper)
.eq(ServeSync::getId, id)
.set(ServeSync::getPrice, price)
.update();
// 返回修改后对象同步缓存
serve.setPrice(price); serve.setPrice(price);
return serve; return serve;
} }
@Override @Override
@Transactional @Transactional
@CachePut(value = RedisConstants.CacheName.SERVE, key = "#id", cacheManager = RedisConstants.CacheManager.ONE_DAY)
public Serve updateOnSale(Long id) { public Serve updateOnSale(Long id) {
// 区域服务检验 // 区域服务检验
Serve serve = getServeByIdIfExist(id); Serve serve = getServeByIdIfExist(id);
@@ -108,7 +143,7 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
throw new ForbiddenOperationException("草稿或下架状态才能上架"); throw new ForbiddenOperationException("草稿或下架状态才能上架");
} }
Integer activeStatus = serveItemMapper.selectById(serve.getServeItemId()).getActiveStatus(); Integer activeStatus = serveItemService.getById(serve.getServeItemId()).getActiveStatus();
if (!ObjectUtils.equal(activeStatus, FoundationStatusEnum.ENABLE.getStatus())) { if (!ObjectUtils.equal(activeStatus, FoundationStatusEnum.ENABLE.getStatus())) {
throw new ForbiddenOperationException("对应的服务项未启用不能上架"); throw new ForbiddenOperationException("对应的服务项未启用不能上架");
} }
@@ -121,13 +156,42 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
throw new CommonException("状态更新失败"); throw new CommonException("状态更新失败");
} }
// 更新服务启用状态
serve.setSaleStatus(enableStatus); serve.setSaleStatus(enableStatus);
// 服务项信息
ServeItem serveItem = serveItemService.getById(serve.getServeItemId());
// 服务类型
ServeType serveType = serveTypeService.getById(serveItem.getServeTypeId());
// 插入sync表添加ES索引
serveSyncMapper.insert(ServeSync.builder()
// serve_type data
.serveTypeId(serveType.getId())
.serveTypeName(serveType.getName())
.serveItemIcon(serveType.getServeTypeIcon())
.serveTypeImg(serveType.getImg())
.serveTypeSortNum(serveType.getSortNum())
// serve_item data
.serveItemId(serveItem.getId())
.serveItemName(serveItem.getName())
.serveItemIcon(serveItem.getServeItemIcon())
.serveItemImg(serveItem.getImg())
.serveItemSortNum(serveItem.getSortNum())
.unit(serveItem.getUnit())
.detailImg(serveItem.getDetailImg())
// serve data
.id(serve.getId())
.price(serve.getPrice())
.cityCode(serve.getCityCode())
.isHot(serve.getIsHot()).build());
return serve; return serve;
} }
@Override @Override
@Transactional @Transactional
public Serve updateOffSale(Long id) { @CacheEvict(value = RedisConstants.CacheName.SERVE, key = "#id", cacheManager = RedisConstants.CacheManager.ONE_DAY)
public void updateOffSale(Long id) {
// 区域服务检验 // 区域服务检验
Serve serve = getServeByIdIfExist(id); Serve serve = getServeByIdIfExist(id);
@@ -144,8 +208,8 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
throw new CommonException("状态更新失败"); throw new CommonException("状态更新失败");
} }
serve.setSaleStatus(disableStatus); // 删除sync表数据删除ES索引
return serve; serveSyncMapper.deleteById(id);
} }
@Override @Override
@@ -163,7 +227,7 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
@Override @Override
@Transactional @Transactional
public Serve updateOnHot(Long id) { public void updateOnHot(Long id) {
Serve serve = getServeByIdIfExist(id); Serve serve = getServeByIdIfExist(id);
if (serve.getIsHot() != HotStatusEnum.OFF_HOT.getStatus()) { if (serve.getIsHot() != HotStatusEnum.OFF_HOT.getStatus()) {
@@ -177,14 +241,11 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
.update()) { .update()) {
throw new CommonException("热门状态更新失败"); throw new CommonException("热门状态更新失败");
} }
serve.setIsHot(hotStatus);
return serve;
} }
@Override @Override
@Transactional @Transactional
public Serve updateOffHot(Long id) { public void updateOffHot(Long id) {
Serve serve = getServeByIdIfExist(id); Serve serve = getServeByIdIfExist(id);
if (serve.getIsHot() != HotStatusEnum.ON_HOT.getStatus()) { if (serve.getIsHot() != HotStatusEnum.ON_HOT.getStatus()) {
@@ -198,14 +259,143 @@ public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements
.update()) { .update()) {
throw new CommonException("热门状态更新失败"); throw new CommonException("热门状态更新失败");
} }
}
serve.setIsHot(hotStatus); @Override
return serve; @Caching(cacheable = {
@Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key = "#regionId",
cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES,
unless = "#result.size() != 0"), // 防止缓存穿透
@Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key = "#regionId",
cacheManager = RedisConstants.CacheManager.FOREVER,
unless = "#result.size() == 0")})
public List<ServeCategoryResDTO> getFirstPageServeList(Long regionId) {
Region region = regionService.getById(regionId);
if (ObjectUtils.isEmpty(region)) {
return Collections.emptyList();
}
List<ServeCategoryResDTO> serveIconList = baseMapper.queryServeIconListByRegionId(regionId);
if (CollUtils.isEmpty(serveIconList)) {
return Collections.emptyList();
}
// 保留最多前两个类型及最多前4个服务项
serveIconList = new ArrayList<>(serveIconList.subList(0, Math.min(serveIconList.size(), 2)));
serveIconList.forEach(res -> {
List<ServeSimpleResDTO> serveResDTOList = res.getServeResDTOList();
res.setServeResDTOList(new ArrayList<>(serveResDTOList.subList(0, Math.min(serveResDTOList.size(), 4))));
});
return serveIconList;
}
@Override
@Caching(cacheable = {
@Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId",
cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES,
unless = "#result.size() != 0"), // 防止缓存穿透
@Cacheable(value = RedisConstants.CacheName.HOT_SERVE, key = "#regionId",
cacheManager = RedisConstants.CacheManager.FOREVER,
unless = "#result.size() == 0")})
public List<ServeAggregationSimpleResDTO> getHotServeList(Long regionId) {
Region region = regionService.getById(regionId);
if (ObjectUtils.isEmpty(region)) {
return Collections.emptyList();
}
List<ServeAggregationSimpleResDTO> hotServeList = baseMapper.queryHotServeListByRegionId(regionId);
if (CollUtils.isEmpty(hotServeList)) {
return Collections.emptyList();
}
return hotServeList;
}
@Override
public ServeAggregationSimpleResDTO getServeById(Long serveId) {
Serve serve = serveService.selectByIdCache(serveId);
if (ObjectUtils.isEmpty(serve)) {
return new ServeAggregationSimpleResDTO();
}
ServeItem serveItem = serveItemService.selectByIdCache(serve.getServeItemId());
if (ObjectUtils.isEmpty(serveItem)) {
return new ServeAggregationSimpleResDTO();
}
return ServeAggregationSimpleResDTO.builder()
.id(serve.getId())
.serveItemId(serveItem.getId())
.serveItemName(serveItem.getName())
.serveItemImg(serveItem.getImg())
.detailImg(serveItem.getDetailImg())
.unit(serveItem.getUnit())
.price(serve.getPrice())
.cityCode(serve.getCityCode())
.build();
}
@Override
public List<ServeSimpleResDTO> findServeList(String cityCode, Long serveTypeId, String keyword) {
// 构建ES搜索请求
SearchRequest searchRequest = new SearchRequest.Builder()
.index("serve_aggregation")
.query(query -> query
.bool(bool -> {
bool = bool.must(must -> must.term(term -> term
.field("city_code")
.value(cityCode)));
if (!ObjectUtils.isEmpty(serveTypeId)) {
bool = bool.must(must -> must.term(term -> term
.field("serve_type_id")
.value(serveTypeId)));
}
if (!ObjectUtils.isEmpty(keyword)) {
bool = bool.must(must -> must.multiMatch(multi -> multi
.query(keyword)
.fields("serve_item_name", "serve_item_name")));
}
return bool;
}))
.sort(sort -> sort
.field(field -> field
.field("serve_item_sort_num")
.order(SortOrder.Asc)))
.build();
// 发送搜索请求获取结果
SearchResponse<ServeAggregation> response = elasticSearchTemplate
.opsForDoc()
.search(searchRequest, ServeAggregation.class);
if (SearchResponseUtils.isNotSuccess(response)) {
return Collections.emptyList();
} else {
return response.hits().hits().stream()
.map(hit -> BeanUtils.toBean(hit.source(), ServeSimpleResDTO.class))
.collect(Collectors.toList());
}
}
@Override
public ServeAggregationResDTO getServeAggregationById(Long id) {
return baseMapper.getServeAggregationById(id);
} }
@Resource @Resource
private ServeItemMapper serveItemMapper; private IRegionService regionService;
@Resource @Resource
private RegionMapper regionMapper; private IServeService serveService;
@Resource
private IServeTypeService serveTypeService;
@Resource
private IServeItemService serveItemService;
@Resource
private ServeSyncMapper serveSyncMapper;
@Resource
private ElasticSearchTemplate elasticSearchTemplate;
} }

View File

@@ -12,21 +12,30 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.foundations.dto.response.ServeTypeSimpleResDTO; import com.jzo2o.api.foundations.dto.response.ServeTypeSimpleResDTO;
import com.jzo2o.common.expcetions.ForbiddenOperationException; import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult; import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.foundations.constants.RedisConstants;
import com.jzo2o.foundations.enums.FoundationStatusEnum; import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeTypeMapper; import com.jzo2o.foundations.mapper.ServeTypeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.ServeType; import com.jzo2o.foundations.model.domain.ServeType;
import com.jzo2o.foundations.model.dto.request.ServeSyncUpdateReqDTO; import com.jzo2o.foundations.model.dto.request.ServeSyncUpdateReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeTypePageQueryReqDTO; import com.jzo2o.foundations.model.dto.request.ServeTypePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeTypeUpsertReqDTO; import com.jzo2o.foundations.model.dto.request.ServeTypeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO;
import com.jzo2o.foundations.model.dto.response.ServeTypeResDTO; import com.jzo2o.foundations.model.dto.response.ServeTypeResDTO;
import com.jzo2o.foundations.service.IServeItemService; import com.jzo2o.foundations.service.IServeItemService;
import com.jzo2o.foundations.service.IServeSyncService; import com.jzo2o.foundations.service.IServeSyncService;
import com.jzo2o.foundations.service.IServeTypeService; import com.jzo2o.foundations.service.IServeTypeService;
import com.jzo2o.mysql.utils.PageUtils; import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@@ -41,6 +50,8 @@ public class ServeTypeServiceImpl extends ServiceImpl<ServeTypeMapper, ServeType
private IServeItemService serveItemService; private IServeItemService serveItemService;
@Resource @Resource
private IServeSyncService serveSyncService; private IServeSyncService serveSyncService;
@Resource
private RegionMapper regionMapper;
/** /**
* 服务类型新增 * 服务类型新增
@@ -192,4 +203,26 @@ public class ServeTypeServiceImpl extends ServiceImpl<ServeTypeMapper, ServeType
List<ServeType> serveTypeList = baseMapper.selectList(queryWrapper); List<ServeType> serveTypeList = baseMapper.selectList(queryWrapper);
return BeanUtil.copyToList(serveTypeList, ServeTypeSimpleResDTO.class); return BeanUtil.copyToList(serveTypeList, ServeTypeSimpleResDTO.class);
} }
}
@Override
@Caching(cacheable = {
@Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId",
cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES,
unless = "#result.size() != 0"), // 防止缓存穿透
@Cacheable(value = RedisConstants.CacheName.SERVE_TYPE, key = "#regionId",
cacheManager = RedisConstants.CacheManager.FOREVER,
unless = "#result.size() == 0")})
public List<ServeAggregationTypeSimpleResDTO> getServeTypeList(Long regionId) {
Region region = regionMapper.selectById(regionId);
if (ObjectUtils.isEmpty(region)) {
return Collections.emptyList();
}
List<ServeAggregationTypeSimpleResDTO> serveTypeList = baseMapper.getServeTypeListByRegionId(regionId);
if (CollUtils.isEmpty(serveTypeList)) {
return Collections.emptyList();
}
return serveTypeList;
}
}

View File

@@ -41,12 +41,12 @@ spring:
shared-configs: # 共享配置 shared-configs: # 共享配置
- data-id: shared-redis-cluster.yaml # 共享redis配置 - data-id: shared-redis-cluster.yaml # 共享redis配置
refresh: false refresh: false
# - data-id: shared-xxl-job.yaml # xxl-job配置 - data-id: shared-xxl-job.yaml # xxl-job配置
# refresh: false refresh: false
# - data-id: shared-rabbitmq.yaml # rabbitmq配置 - data-id: shared-rabbitmq.yaml # rabbitmq配置
# refresh: false refresh: false
# - data-id: shared-es.yaml # rabbitmq配置 - data-id: shared-es.yaml # elasticsearch配置
# refresh: false refresh: false
- data-id: shared-mysql.yaml # mysql配置 - data-id: shared-mysql.yaml # mysql配置
refresh: false refresh: false
@@ -73,4 +73,4 @@ logging:
com.jzo2o: debug com.jzo2o: debug
org.apache.http: info #es请求日志 org.apache.http: info #es请求日志
feign: feign:
enable: true enable: true

View File

@@ -19,4 +19,82 @@
JOIN serve_type st ON si.serve_type_id = st.id JOIN serve_type st ON si.serve_type_id = st.id
WHERE s.region_id = #{regionId} WHERE s.region_id = #{regionId}
</select> </select>
<resultMap id="ServeCategoryResMap" type="com.jzo2o.foundations.model.dto.response.ServeCategoryResDTO">
<id column="serve_type_id" property="serveTypeId"/>
<result column="type_name" property="serveTypeName"/>
<result column="serve_type_icon" property="serveTypeIcon"/>
<result column="city_code" property="cityCode"/>
<result column="type_sort_num" property="serveTypeSortNum"/>
<collection property="serveResDTOList" ofType="com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO">
<id column="serve_id" property="id"/>
<result column="serve_item_id" property="serveItemId"/>
<result column="item_name" property="serveItemName"/>
<result column="serve_item_icon" property="serveItemIcon"/>
<result column="item_sort_num" property="serveItemSortNum"/>
</collection>
</resultMap>
<select id="queryServeIconListByRegionId" resultMap="ServeCategoryResMap">
SELECT serve_type_id,
type.name type_name,
serve_type_icon,
city_code,
type.sort_num type_sort_num,
serve_item_id,
item.name item_name,
serve_item_icon,
item.sort_num item_sort_num,
serve.id serve_id
FROM serve
JOIN serve_item item ON serve.serve_item_id = item.id
JOIN serve_type type ON item.serve_type_id = type.id
WHERE serve.region_id = #{regionId}
AND serve.sale_status = 2 # 保证上架服务
ORDER BY type.sort_num, item.sort_num
</select>
<select id="queryHotServeListByRegionId"
resultType="com.jzo2o.foundations.model.dto.response.ServeAggregationSimpleResDTO">
SELECT serve.id,
serve_item_id,
name serve_item_name,
img serve_item_img,
unit,
price,
detail_img,
city_code
FROM serve
JOIN serve_item item ON serve.serve_item_id = item.id
WHERE serve.region_id = #{regionId}
AND serve.sale_status = 2 # 保证上架服务
AND serve.is_hot = 1 # 保证热门状态
ORDER BY item.sort_num
</select>
<select id="getServeAggregationById" resultType="com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO"
parameterType="java.lang.Long">
SELECT serve_type_id,
type.name serve_type_name,
type.serve_type_icon,
type.img serve_type_img,
type.sort_num serve_type_sort_num,
serve_item_id,
item.name serve_item_name,
item.serve_item_icon,
item.img serve_item_img,
item.detail_img,
item.sort_num serve_item_sort_num,
item.unit,
serve.id,
serve.sale_status,
serve.city_code,
serve.price,
serve.is_hot,
serve.hot_time_stamp
FROM serve
JOIN serve_item item ON serve.serve_item_id = item.id
JOIN serve_type type ON item.serve_type_id = type.id
WHERE serve.id = #{id}
</select>
</mapper> </mapper>

View File

@@ -1,5 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jzo2o.foundations.mapper.ServeTypeMapper"> <mapper namespace="com.jzo2o.foundations.mapper.ServeTypeMapper">
<select id="getServeTypeListByRegionId"
</mapper> resultType="com.jzo2o.foundations.model.dto.response.ServeAggregationTypeSimpleResDTO">
SELECT distinct serve_type_id,
type.name serveTypeName,
type.img serveTypeImg,
type.sort_num serveTypeSortNum
FROM serve
JOIN serve_item item ON serve.serve_item_id = item.id
JOIN serve_type type ON item.serve_type_id = type.id
WHERE serve.region_id = #{regionId}
AND serve.sale_status = 2 # 保证上架服务
ORDER BY type.sort_num
</select>
</mapper>

View File

@@ -7,23 +7,23 @@ package com.jzo2o.statemachine.core;
* @date 2023/9/18 11:07 * @date 2023/9/18 11:07
*/ */
public abstract class StateMachineSnapshot { public abstract class StateMachineSnapshot {
/** /**
* 返回快照id * 返回快照id
* @return
*/ */
public abstract String getSnapshotId(); public abstract String getSnapshotId();
/** /**
* 返回快照状态 * 返回快照状态
* @return
*/ */
public abstract Integer getSnapshotStatus(); public abstract Integer getSnapshotStatus();
/** /**
* 设置快照id * 设置快照id
*/ */
public abstract void setSnapshotId(String snapshotId); public abstract void setSnapshotId(String snapshotId);
/** /**
* 设置快照状态 * 设置快照状态
*/ */
public abstract void setSnapshotStatus(Integer snapshotStatus); public abstract void setSnapshotStatus(Integer snapshotStatus);
} }

View File

@@ -2,12 +2,9 @@ package com.jzo2o.statemachine.core;
/** /**
* 状态变量事件抽象接口 * 状态变量事件抽象接口
*
* @author itcast * @author itcast
*/ */
public interface StatusChangeEvent { public interface StatusChangeEvent {
/** /**
* 原始状态 * 原始状态
*/ */
@@ -27,5 +24,4 @@ public interface StatusChangeEvent {
* @return 返回事件代码 * @return 返回事件代码
*/ */
String getCode(); String getCode();
} }

View File

@@ -6,17 +6,14 @@ package com.jzo2o.statemachine.core;
* 1、功能说明:状态变更时执行的业务逻辑 * 1、功能说明:状态变更时执行的业务逻辑
* 2、接口实现类的bean名称规则为:状态机名称_状态变更事件名称 * 2、接口实现类的bean名称规则为:状态机名称_状态变更事件名称
* 例如:在实现类上添加 @Component("order_close_dispatching_order") order为状态机名称close_dispatching_order为取消正常派单订单的事件名称 * 例如:在实现类上添加 @Component("order_close_dispatching_order") order为状态机名称close_dispatching_order为取消正常派单订单的事件名称
*
* @author itcast * @author itcast
*/ */
public interface StatusChangeHandler<T extends StateMachineSnapshot> { public interface StatusChangeHandler<T extends StateMachineSnapshot> {
/** /**
* 状态变化处理逻辑 * 状态变化处理逻辑
* * @param bizId 业务id
* @param bizId 业务id
* @param statusChangeEventEnum 状态变更事件 * @param statusChangeEventEnum 状态变更事件
* @param bizSnapshot 快照 * @param bizSnapshot 快照
*/ */
void handler(String bizId,StatusChangeEvent statusChangeEventEnum,T bizSnapshot); void handler(String bizId, StatusChangeEvent statusChangeEventEnum, T bizSnapshot);
} }

View File

@@ -2,11 +2,9 @@ package com.jzo2o.statemachine.core;
/** /**
* 状态抽象接口 * 状态抽象接口
*
* @author itcast * @author itcast
*/ */
public interface StatusDefine { public interface StatusDefine {
/** /**
* @return 返回状态编号 * @return 返回状态编号
*/ */
@@ -21,4 +19,4 @@ public interface StatusDefine {
* @return 返回状态代码 * @return 返回状态代码
*/ */
String getCode(); String getCode();
} }

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jzo2o-oreders</artifactId>
<groupId>com.jzo2o</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jzo2o-orders-base</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-common</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mysql</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-redis</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.jzo2o</groupId>-->
<!-- <artifactId>jzo2o-shardingsphere-jdbc</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.jzo2o</groupId>-->
<!-- <artifactId>jzo2o-api</artifactId>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-alibaba-sentinel</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-canal-sync</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-statemachine</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--seata-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-seata</artifactId>-->
<!-- <exclusions>-->
<!-- &lt;!&ndash;版本较低1.4.2,因此排除&ndash;&gt;-->
<!-- <exclusion>-->
<!-- <artifactId>seata-spring-boot-starter</artifactId>-->
<!-- <groupId>io.seata</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <artifactId>seata-spring-boot-starter</artifactId>-->
<!-- <groupId>io.seata</groupId>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.antlr</groupId>-->
<!-- <artifactId>antlr4</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mvc</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,19 @@
package com.jzo2o.orders.base.config;
import com.jzo2o.orders.base.properties.DispatchProperties;
import com.jzo2o.orders.base.properties.ExecutorProperties;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 自动导入订单相关配置
* @author JIAN
*/
@Configuration
@ComponentScan({"com.jzo2o.orders.base.service", "com.jzo2o.orders.base.handler"})
@MapperScan("com.jzo2o.orders.base.mapper")
@EnableConfigurationProperties({DispatchProperties.class, ExecutorProperties.class})
public class AutoImportConfiguration {
}

View File

@@ -0,0 +1,12 @@
package com.jzo2o.orders.base.constants;
public class ErrorInfo {
public static class Msg {
public static final String SEIZE_ORDERS_FAILD = "单子已经被抢走了";
public static final String SEIZE_ORDERS_SERVE_TIME_EXISTS = "当前服务预约时间冲突";
public static final String SEIZE_ORDERS_RECEIVE_ORDERS_NUM_OVER = "当前接单数已超出范围";
public static final String SEIZE_ORDERS_RECEIVE_CLOSED = "当前接单设置已关闭,如需抢单,需开启接单";
}
}

View File

@@ -0,0 +1,10 @@
package com.jzo2o.orders.base.constants;
public class EsIndexConstants {
/**
* 服务人员信息索引
*/
public static final String SERVER_PROVIDER_INFO = "serve_provider_info";
public static final String ORDERS_SEIZE = "orders_seize";
}

View File

@@ -0,0 +1,50 @@
package com.jzo2o.orders.base.constants;
public class FieldConstants {
/**
* 预约时间
*/
public static final String SERVE_START_TIME = "serve_start_time";
/**
* 城市编码
*/
public static final String CITY_CODE = "city_code";
/**
* 服务类型id
*/
public static final String SERVE_TYPE_ID = "serve_type_id";
/**
* 服务项id
*/
public static final String SERVE_ITEM_ID = "serve_item_id";
/**
* 服务类型名称
*/
public static final String SERVE_TYPE_NAME = "serve_type_name";
/**
* 服务项名称
*/
public static final String SERVE_ITEM_NAME = "serve_item_name";
/**
* 关键字字段
*/
public static final String KEY_WORDS = "key_words";
/**
* 经纬度
*/
public static final String LOCATION = "location";
public static final String SERVE_TIME = "serve_time";
/**
* 排序字段
*/
public static final String SORT_BY = "sort_by";
}

View File

@@ -0,0 +1,36 @@
package com.jzo2o.orders.base.constants;
/**
* 订单常量
*
* @author itcast
* @create 2023/7/28 15:06
**/
public class OrderConstants {
public static final class Status {
public static final String NO_PAY = "NO_PAY";
public static final String DISPATCHING = "DISPATCHING";
public static final String NO_SERVE = "NO_SERVE";
public static final String SERVING = "SERVING";
public static final String NO_EVALUATION = "NO_EVALUATION";
public static final String FINISHED = "FINISHED";
public static final String CANCELED = "CANCELED";
public static final String CHARGEBACK = "CHARGEBACK";
}
public static final class ChangeEvent {
public static final String PAYED = "PAYED";
public static final String DISPATCH = "DISPATCH";
public static final String START_SERVE = "START_SERVE";
public static final String COMPLETE_SERVE = "COMPLETE_SERVE";
public static final String EVALUATE = "EVALUATE";
public static final String CANCEL = "CANCEL";
public static final String SERVE_PROVIDER_CANCEL = "SERVE_PROVIDER_CANCEL";
public static final String CLOSE_DISPATCHING_ORDER = "CLOSE_DISPATCHING_ORDER";
public static final String CLOSE_NO_SERVE_ORDER = "CLOSE_NO_SERVE_ORDER";
public static final String CLOSE_SERVING_ORDER = "CLOSE_SERVING_ORDER";
public static final String CLOSE_NO_EVALUATION_ORDER = "CLOSE_NO_EVALUATION_ORDER";
public static final String CLOSE_FINISHED_ORDER = "CLOSE_FINISHED_ORDER";
}
}

View File

@@ -0,0 +1,6 @@
package com.jzo2o.orders.base.constants;
public class OrdersOriginType {
public static final int SEIZE = 1;
public static final int DISPATCH = 2;
}

View File

@@ -0,0 +1,169 @@
package com.jzo2o.orders.base.constants;
public class RedisConstants {
public static final class RedisFormatter {
/**
* 抢单用户锁模板格式ORDERS:SEIZE_#{serveProviderId}
*/
public static final String SEIZE = "ORDERS:SEIZE_#{serveProviderId}";
/**
* 派单锁模板格式ORDERS:DISPATCH_#{id}
*/
public static final String DISPATCH = "ORDERS:DISPATCH_#{id}";
/**
* 加入派单池锁模板格式ORDERS:JSONDISPATCHLIST_#{id}
*/
public static final String JSONDISPATCHLIST = "ORDERS:JSONDISPATCHLIST_#{id}";
public static final String REJECT = "ORDERS:DISPATCH:REJECT_#{dispatchRejectReqDTO.id}";
/**
* 抢单超时
*/
public static final String SEIZE_TIME_OUT = "ORDERS:SEIZE:TIME_OUT:#{cityCode}";
public static final String ORDERS_SERVE_TIMEOUT = "ORDERS:SEVER_TIMEOUT:#{ordersServe.id}";
}
public static final class RedisKey {
/**
* 抢单id列表redis key模板ORDERS:SEIZE:IDS_{服务人员id或机构id}_{citycode}
*/
public static final String ORDERS_SEIZE_IDS_FOR_SERVE_PROVIDE = "ORDERS:SEIZE:IDS_%s_%s";
/**
* 抢单列表redis key模板ORDERS:SEIZE:PAGE_{citycode}
*/
public static final String ORDERS_SEIZE_PAGE = "ORDERS:SEIZE:PAGE_%s";
// 抢单相关
/**
*抢单池key格式:ORDERS:SEIZE:POOL_{抢单id}_{抢单id尾号}
*/
public static final String ORDERS_SEIZE = "ORDERS:SEIZE:%s_{%s}";
/**
* 抢单结果同步队列该队列分为10条格式ORDERS:SEIZE:SYNC_{抢单id尾号}
* 序号分别为0到9的10个数字
*/
public static final String ORERS_SEIZE_SYNC_QUEUE_NAME = "ORDERS:SEIZE:SYNC";
/**
* 当前用户/机构当前接单数量,接单+派单总数量
* 接单+派单操作+1
* 完成服务/取消服务-1
* 格式PROVIDER:SERVE:NUM_{cityCode}_{序号}
*/
public static final String PROVIDER_SERVE_NUM = "PROVIDER:SERVE:NUM_%s_{%s}";
/**
* 所有服务单放在一起
*/
public static final String SERVE_ORDERS = "SERVE_ORDERS:PAGE_QUERY:PAGE_%s";
public static final String SERVE_ORDERS_KEY = "SERVE_ORDERS:PAGE_QUERY:PAGE_#{serveProviderId}";
/**
* 服务人员或机构每日取消服务单次数
*/
public static final String SERVE_CANCEL_TIMES_EVERY_DAY = "ORDERS:SERVE:CANCEL_%s_%s";
public static final String SERVE_TIME_UPDATE = "ORDERS:SERVE_TIME:#{id}";
/**
* 库存hash结构
*/
public static final String ORDERS_RESOURCE_STOCK = "ORDERS:RESOURCE:STOCK:{%s}";
/**
* 派单连续失败次数 string
*/
public static final String ORDERS_DISPATCH_FAILD_TIMES = "ORDERS:DISPATCH:FAILD_TIMES_%s_{%s}";
/**
* 派单成功同步队列名称
*/
public static final String ORERS_DISPATCH_SYNC_QUEUE_NAME = "ORDERS:DISPATCH:SYNC";
/**
* 服务时间状态 string 格式PROVIDER:SERVE_TIME:{serveProviderId}_{serveTime}_{序号}
*/
public static final String SERVE_PROVIDER_TIMES = "PROVIDER:SERVE_TIME:%s_%s_{%s}";
/**
* 服务状态表 hash 格式PROVIDER:SERVE_STATE:{序号}
* key 格式:{服务人员/机构id}_{times或num}time表示接单时间列表nun表示接单数量
*/
public static final String SERVE_PROVIDER_STATE = "PROVIDER:SERVE_STATE:{%s}";
/**
* 派单列表 - zSet结构
*/
public static final String DISPATCH_LIST = "ORDERS:DISPATCH:LIST";
/**
* 用户端滚动分页查询订单
*/
public static final String ORDERS = "ORDERS:PAGE_QUERY:PAGE_%s";
}
public static class Lock {
/**
* 抢派单分布式锁
*/
public static final String DISPATCH_OR_SEIZE_LOCK = "ORDERS:DISPATCH_OR_SEIZE:%s";
public static final String PROVIDER_DISPATCH_LOCK = "PROVIDER:DISPATCH:LOCK_%s";
/**
* 派单同步锁定同步队列redis分布式锁
*/
public static final String DISPATCH_SYNC_LOCK = "ORDERS:DISPATCH:SYNC_%s";
/**
* 接单超时
*/
public static final String DISPATCH_RECEIVE_TIMEOUT_LOCK = "ORDERS:DISPATCH:TIMEOUT";
/**
* 抢单单同步锁定同步队列redis分布式锁
*/
public static final String SEIZE_SYNC_LOCK = "ORDERS:SEIZE:SYNC_%s";
/**
* 订单分片id获取锁
*/
public static final String ORDERS_SHARD_KEY_ID_LOCK = "ORDERS:SHARD_KEY:LOCK";
public static final String ORDERS_SHARD_KEY_ID_GENERATOR = "ORDERS:SHARD_KEY:GENERATOR";
}
public static class Ttl {
/**
* 订单抢单缓存 60s
*/
public static final long ORDERS_SEIZE_PAGE_TTL = 60;
/**
* 服务单分页有效期
*/
public static final long SERVE_ORSERS_PAGE_TTL = 600;
/**
* 订单分页有效期
*/
public static final long ORDERS_PAGE_TTL = 600;
/**
* 抢单派单处理超时时间单位s
*/
public static final long DISPATCH_SEIZE_LOCK_TTL = 10;
/**
* 派单锁定10分钟内不能再次派单
*/
public static final long PROVIDER_DISPATCH_LOCK_TTL = 600;
}
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.orders.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 违约行为枚举
*/
@AllArgsConstructor
@Getter
public enum BreachHaviorTypeEnum {
CANCEL_ALLOCATION(1,"机构取消未分配服务单违约行为"),
CANCEL_NO_SERVE(2,"机构或服务人员取消待服务订单违约行为"),
CANCEL_SERVING(3,"机构或服务人员取消服务中订单违约行为"),
DISPATCH_REJECT(4,"机构或服务人员拒绝接单违约行为");
private int type;
private String desc;
}

View File

@@ -0,0 +1,24 @@
package com.jzo2o.orders.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderPayStatusEnum {
NO_PAY(2, "未支付"),
PAY_SUCCESS(4, "支付成功");
private int status;
private final String desc;
public boolean equals(int status) {
return this.status == status;
}
}

View File

@@ -0,0 +1,26 @@
package com.jzo2o.orders.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderRefundStatusEnum {
// APPLY_REFUND(0, "发起退款"),
REFUNDING(1, "退款中"),
REFUND_SUCCESS(2, "退款成功"),
REFUND_FAIL(3, "退款失败");
private int status;
private final String desc;
public boolean equals(int status) {
return this.status == status;
}
}

View File

@@ -0,0 +1,45 @@
package com.jzo2o.orders.base.enums;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderStatusChangeEventEnum implements StatusChangeEvent {
PAYED(OrderStatusEnum.NO_PAY, OrderStatusEnum.DISPATCHING, "支付成功", "payed"),
DISPATCH(OrderStatusEnum.DISPATCHING, OrderStatusEnum.NO_SERVE, "接单/抢单成功", "dispatch"),
START_SERVE(OrderStatusEnum.NO_SERVE, OrderStatusEnum.SERVING, "开始服务", "start_serve"),
COMPLETE_SERVE(OrderStatusEnum.SERVING, OrderStatusEnum.FINISHED, "完成服务", "complete_serve"),
EVALUATE(OrderStatusEnum.NO_EVALUATION, OrderStatusEnum.FINISHED, "评价完成", "evaluate"),
CANCEL(OrderStatusEnum.NO_PAY, OrderStatusEnum.CANCELED, "取消订单", "cancel"),
SERVE_PROVIDER_CANCEL(OrderStatusEnum.NO_SERVE, OrderStatusEnum.DISPATCHING, "服务人员/机构取消订单", "serve_provider_cancel"),
CLOSE_DISPATCHING_ORDER(OrderStatusEnum.DISPATCHING, OrderStatusEnum.CLOSED, "派单中订单关闭", "close_dispatching_order"),
CLOSE_NO_SERVE_ORDER(OrderStatusEnum.NO_SERVE, OrderStatusEnum.CLOSED, "待服务订单关闭", "close_no_serve_order"),
CLOSE_SERVING_ORDER(OrderStatusEnum.SERVING, OrderStatusEnum.CLOSED, "服务中订单关闭", "close_serving_order"),
CLOSE_NO_EVALUATION_ORDER(OrderStatusEnum.NO_EVALUATION, OrderStatusEnum.CLOSED, "待评价订单关闭", "close_no_evaluation_order"),
CLOSE_FINISHED_ORDER(OrderStatusEnum.FINISHED, OrderStatusEnum.CLOSED, "已完成订单关闭", "close_finished_order");
/**
* 源状态
*/
private final OrderStatusEnum sourceStatus;
/**
* 目标状态
*/
private final OrderStatusEnum targetStatus;
/**
* 描述
*/
private final String desc;
/**
* 代码
*/
private final String code;
}

View File

@@ -0,0 +1,40 @@
package com.jzo2o.orders.base.enums;
import com.jzo2o.statemachine.core.StatusDefine;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderStatusEnum implements StatusDefine {
NO_PAY(0, "待支付", "NO_PAY"),
DISPATCHING(100, "派单中", "DISPATCHING"),
NO_SERVE(200, "待服务", "NO_SERVE"),
SERVING(300, "服务中", "SERVING"),
NO_EVALUATION(400, "待评价", "NO_EVALUATION"),
FINISHED(500, "已完成", "FINISHED"),
CANCELED(600, "已取消", "CANCELED"),
CLOSED(700, "已关闭", "CLOSED");
private final Integer status;
private final String desc;
private final String code;
/**
* 根据状态值获得对应枚举
*
* @param status 状态
* @return 状态对应枚举
*/
public static OrderStatusEnum codeOf(Integer status) {
for (OrderStatusEnum orderStatusEnum : values()) {
if (orderStatusEnum.status.equals(status)) {
return orderStatusEnum;
}
}
return null;
}
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.orders.base.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ServeStatusEnum {
NO_ALLOCATION(0, "待分配"),
NO_SERVED(1,"待服务"),
SERVING(2,"服务中"),
SERVE_FINISHED(3, "服务完成"),
CANCLE(4, "取消");
private int status;
private String desc;
public boolean equals(Integer status) {
return status != null && status.equals(this.getStatus());
}
}

View File

@@ -0,0 +1,41 @@
package com.jzo2o.orders.base.handler;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.statemachine.AbstractStateMachine;
import com.jzo2o.statemachine.core.StatusDefine;
import com.jzo2o.statemachine.persist.StateMachinePersister;
import com.jzo2o.statemachine.snapshot.BizSnapshotService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
/**
* 订单状态机
* @author JIAN
*/
@Component
public class OrderStateMachine extends AbstractStateMachine<OrderSnapshotDTO> {
/**
* 构造方法
* @param stateMachinePersister 状态机持久化程序
* @param bizSnapshotService 业务快照服务层程序
* @param redisTemplate redis处理程序
*/
public OrderStateMachine(StateMachinePersister stateMachinePersister, BizSnapshotService bizSnapshotService, RedisTemplate redisTemplate) {
super(stateMachinePersister, bizSnapshotService, redisTemplate);
}
@Override
public String getName() {
return "order";
}
@Override
public void postProcessor(OrderSnapshotDTO bizSnapshot) {
}
@Override
public StatusDefine getInitState() {
return OrderStatusEnum.NO_PAY;
}
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 未支付时订单取消处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_cancel")
public class OrderCancelHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 订单评价处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("订单取消事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.NO_PAY.getStatus())
.targetStatus(OrderStatusEnum.CANCELED.getStatus())
.build())) {
throw new DbRuntimeException("订单取消事件处理失败");
}
}
}

View File

@@ -0,0 +1,46 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 派单中订单关闭处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_close_dispatching_order")
public class OrderCloseDispatchingOrderHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 派单中订单关闭处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("派单中订单关闭事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.DISPATCHING.getStatus())
.targetStatus(OrderStatusEnum.CLOSED.getStatus())
// 退款状态为退款中
.refundStatus(OrderRefundStatusEnum.REFUNDING.getStatus())
.build())) {
throw new DbRuntimeException("派单中订单关闭事件处理失败");
}
}
}

View File

@@ -0,0 +1,46 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 已完成订单关闭处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_close_finished_order")
public class OrderCloseFinishedOrderHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 已完成订单关闭处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("已完成订单关闭事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.FINISHED.getStatus())
.targetStatus(OrderStatusEnum.CLOSED.getStatus())
// 退款状态为退款中
.refundStatus(OrderRefundStatusEnum.REFUNDING.getStatus())
.build())) {
throw new DbRuntimeException("已完成订单关闭事件处理失败");
}
}
}

View File

@@ -0,0 +1,46 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 待服务订单关闭处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_close_no_serve_order")
public class OrderCloseNoServeOrderHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 待服务订单关闭处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("待服务订单关闭事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.NO_SERVE.getStatus())
.targetStatus(OrderStatusEnum.CLOSED.getStatus())
// 退款状态为退款中
.refundStatus(OrderRefundStatusEnum.REFUNDING.getStatus())
.build())) {
throw new DbRuntimeException("待服务订单关闭事件处理失败");
}
}
}

View File

@@ -0,0 +1,46 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 服务中订单关闭处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_close_serving_order")
public class OrderCloseServingOrderHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 服务中订单关闭处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("服务中订单关闭事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.SERVING.getStatus())
.targetStatus(OrderStatusEnum.CLOSED.getStatus())
// 退款状态为退款中
.refundStatus(OrderRefundStatusEnum.REFUNDING.getStatus())
.build())) {
throw new DbRuntimeException("服务中订单关闭事件处理失败");
}
}
}

View File

@@ -0,0 +1,44 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 订单完成服务处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_complete_serve")
public class OrderCompleteServeHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 订单完成服务处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("订单完成服务事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.SERVING.getStatus())
.targetStatus(OrderStatusEnum.FINISHED.getStatus())
.realServeEndTime(bizSnapshot.getRealServeEndTime())
.build())) {
throw new DbRuntimeException("订单完成服务事件处理失败");
}
}
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 订单派送处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_dispatch")
public class OrderDispatchHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 订单派送处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("派送事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.DISPATCHING.getStatus())
.targetStatus(OrderStatusEnum.NO_SERVE.getStatus())
.build())) {
throw new DbRuntimeException("派送事件处理失败");
}
}
}

View File

@@ -0,0 +1,50 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderPayStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 订单支付成功处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_payed")
public class OrderPayedHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 订单支付处理逻辑
* @param bizId 业务id
* @param statusChangeEventEnum 状态变更事件
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("支付事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态和支付状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.NO_PAY.getStatus())
.targetStatus(OrderStatusEnum.DISPATCHING.getStatus())
.payTime(bizSnapshot.getPayTime())
.payStatus(OrderPayStatusEnum.PAY_SUCCESS.getStatus())
.tradingOrderNo(bizSnapshot.getTradingOrderNo())
.transactionId(bizSnapshot.getThirdOrderId())
.tradingChannel(bizSnapshot.getTradingChannel())
.build())) {
throw new DbRuntimeException("支付事件处理失败");
}
}
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 服务人员/机构取消订单处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_serve_provider_cancel")
public class OrderServeProviderCancelHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 服务人员/机构取消订单处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("服务人员/机构取消订单事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.NO_SERVE.getStatus())
.targetStatus(OrderStatusEnum.DISPATCHING.getStatus())
.build())) {
throw new DbRuntimeException("服务人员/机构取消订单事件处理失败");
}
}
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.orders.base.handler.actions;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.dto.OrderSnapshotDTO;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.statemachine.core.StatusChangeEvent;
import com.jzo2o.statemachine.core.StatusChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 订单开始服务处理器
* @author itcast
* @create 2023/8/17 18:08
**/
@Slf4j
@Component("order_start_serve")
public class OrderStartServeHandler implements StatusChangeHandler<OrderSnapshotDTO> {
@Resource
private IOrdersCommonService ordersService;
/**
* 订单开始服务处理逻辑
* @param bizId 业务id
* @param bizSnapshot 快照
*/
@Override
public void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {
log.info("订单开始服务事件处理逻辑开始, 订单号: {}", bizId);
// 修改订单状态
if (!ordersService.updateStatus(OrderUpdateStatusDTO.builder()
.id(Long.valueOf(bizId))
.originStatus(OrderStatusEnum.NO_SERVE.getStatus())
.targetStatus(OrderStatusEnum.SERVING.getStatus())
.build())) {
throw new DbRuntimeException("订单开始服务事件处理失败");
}
}
}

View File

@@ -0,0 +1,34 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.BreachRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 违约记录 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-02
*/
public interface BreachRecordMapper extends BaseMapper<BreachRecord> {
/**
* 批量添加违约记录
* @param breachRecords
* @return
*/
// @Insert("<script>INSERT INTO breach_record(id,serve_provider_id, serve_provider_type, behavior_type, breach_reason, " +
// "serve_item_name, serve_address, served_user_id, served_phone, breach_time, breach_day, " +
// "orders_id, orders_serve_id) VALUE <foreach collection='breachRecords' item='record' separator=','>" +
// "(#{record.id},#{record.serveProviderId},#{record.serveProviderType},#{record.behaviorType},#{record.breachReason}," +
// "#{record.serveItemName},#{record.serveAddress},#{record.servedUserId},#{record.servedPhone},#{record.breachTime},#{record.breachDay}," +
// "#{record.ordersId},#{record.ordersServeId})</foreach></script>")
// Integer batchAdd(@Param("breachRecords")List<BreachRecord> breachRecords);
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.HistoryOrdersServeSync;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime;
/**
* <p>
* 服务任务 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-09-14
*/
public interface HistoryOrdersServeSyncMapper extends BaseMapper<HistoryOrdersServeSync> {
@Select("select max(sort_time) from history_orders_sync")
LocalDateTime queryMaxSortTime();
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.HistoryOrdersSync;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime;
/**
* <p>
* 历史订单完成15天后同步到历史订单同步表中通过canal同步到历史订单库中1天后删除删除条件当天数据和历史订单库中的订单数据数量一致 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-09-13
*/
public interface HistoryOrdersSyncMapper extends BaseMapper<HistoryOrdersSync> {
@Select("select max(sort_time) from history_orders_sync")
LocalDateTime queryMaxSortTime();
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.OrdersCanceled;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-19
*/
public interface OrdersCanceledMapper extends BaseMapper<OrdersCanceled> {
}

View File

@@ -0,0 +1,27 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.OrdersDispatch;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 派单池 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-08
*/
public interface OrdersDispatchMapper extends BaseMapper<OrdersDispatch> {
// @Insert("<script>INSERT INTO orders_dispatch(id, city_code, serve_type_id," +
// "serve_item_name, serve_type_name, serve_item_id, serve_address, serve_item_img," +
// "total_amount, serve_start_time, lon, lat," +
// "pur_num, is_transfer_manual) VALUE <foreach collection='records' item='record' separator=','>#{record.id},#{record.cityCode},#{record.serveTypeId}," +
// "#{record.serveItemName},#{record.serveStartTime},#{record.lon},#{record.lat},#{record.purNum},#{record.isTransferManual})</foreach></script>")
// Integer batchAdd(@Param("records")List<OrdersDispatch> ordersDispatches);
}

View File

@@ -0,0 +1,24 @@
package com.jzo2o.orders.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 订单表 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-02
*/
public interface OrdersMapper extends BaseMapper<Orders> {
/**
* 用户端滚动查询使用
*/
List<Long> selectOrderIdList(@Param("currentUserId") Long currentUserId,
@Param("ordersStatus") Integer ordersStatus,
@Param("sortBy") Long sortBy);
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 订单退款表 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-09-07
*/
public interface OrdersRefundMapper extends BaseMapper<OrdersRefund> {
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.OrdersSeize;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 抢单池 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-15
*/
public interface OrdersSeizeMapper extends BaseMapper<OrdersSeize> {
}

View File

@@ -0,0 +1,26 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.OrdersServe;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 服务任务 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-02
*/
public interface OrdersServeMapper extends BaseMapper<OrdersServe> {
/**
* 物理删除服务单
* @param id 服务单id
* @param serveProviderId 服务人员或机构id
* @return 删除数量
*/
// @Delete("delete from orders_serve where id=#{id} and serve_provider_id=#{serveProviderId}")
// Integer deleteByIdAndServeProviderId(@Param("id") Long id, @Param("serveProviderId") Long serveProviderId);
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.orders.base.mapper;
import com.jzo2o.orders.base.model.domain.ServeProviderSync;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
/**
* <p>
* 机构服务端更新服务时间 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-08-09
*/
public interface ServeProviderSyncMapper extends BaseMapper<ServeProviderSync> {
// @Update("update serve_provider_sync set serve_times=JSON_ARRAY_APPEND(serve_times,'$',#{serveTime})," +
// "acceptance_num=acceptance_num+1 where id=#{id}")
// int addServeTimes(@Param("id")Long id, @Param("serveTime") Integer serveTime);
}

View File

@@ -0,0 +1,95 @@
package com.jzo2o.orders.base.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 违约记录
* </p>
*
* @author itcast
* @since 2023-08-06
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("breach_record")
public class BreachRecord implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 违约id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 违约机构或师傅
*/
private Long serveProviderId;
/**
* 类型2师傅、3机构
*/
private Integer serveProviderType;
/**
* 行为类型1待分配时取消2待服务时取消3服务中取消4派单拒绝5派单超时
*/
private Integer behaviorType;
/**
* 违约原因
*/
private String breachReason;
/**
* 服务项名称
*/
private String serveItemName;
/**
* 服务地址
*/
private String serveAddress;
/**
* 被服务人
*/
private Long servedUserId;
/**
* 被服务人员手机号,脱敏
*/
private String servedPhone;
/**
* 违约时间
*/
private LocalDateTime breachTime;
/**
* 违约日格式例如20200512,2020年5月12日
*/
private Integer breachDay;
/**
* 违约单订单id
*/
private Long ordersId;
/**
* 服务单id
*/
private Long ordersServeId;
}

View File

@@ -0,0 +1,38 @@
package com.jzo2o.orders.base.model.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 机构服务端更新服务时间
* </p>
*
* @author itcast
* @since 2023-08-08
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "current_serve_provider_time",autoResultMap = true)
public class CurrentServeProviderTime implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.NONE)
private Long id;
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Long> serveTimes;
}

View File

@@ -0,0 +1,222 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 服务任务
* </p>
*
* @author itcast
* @since 2023-09-14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "history_orders_serve_sync",autoResultMap = true)
public class HistoryOrdersServeSync implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 服务单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 服务人员或服务机构id
*/
private Long serveProviderId;
/**
* 服务者类型2服务端服务3机构端服务
*/
private Integer serveProviderType;
/**
* 机构服务人员id
*/
private Long institutionStaffId;
/**
* 机构工作人员姓名
*/
private String institutionStaffName;
/**
* 机构名称
*/
private String institutionName;
/**
* 订单来源类型1抢单2派单
*/
private Integer ordersOriginType;
/**
* 客户姓名
*/
private String contactsName;
/**
* 客户电话
*/
private String contactsPhone;
/**
* 服务地址
*/
private String serveAddress;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务分类id
*/
private Long serveTypeId;
/**
* 服务分裂名称
*/
private String serveTypeName;
/**
* 预约时间
*/
private LocalDateTime serveStartTime;
/**
* 服务项名称
*/
private String serveItemName;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务图片
*/
private String serveItemImg;
/**
* 服务单状态3服务完成4订单关闭
*/
private Integer serveStatus;
/**
* 服务人姓名
*/
private String serveProviderStaffName;
/**
* 服务人手机号
*/
private String serveProviderStaffPhone;
/**
* 取消人姓名
*/
private String cancelerName;
/**
* 取消/被退单时间
*/
private LocalDateTime cancelTime;
/**
* 取消/被退单原因
*/
private String cancelReason;
/**
* 实际服务开始时间
*/
private LocalDateTime realServeStartTime;
/**
* 实际服务完结时间
*/
private LocalDateTime realServeEndTime;
/**
* 服务前照片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveBeforeImgs;
/**
* 服务后照片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveAfterImgs;
/**
* 服务前说明
*/
private String serveBeforeIllustrate;
/**
* 服务后说明
*/
private String serveAfterIllustrate;
/**
* 订单金额
*/
private BigDecimal ordersAmount;
/**
* 服务数量
*/
private Integer serveNum;
/**
* 服务单位
*/
private Integer unit;
/**
* 服务端/机构端是否展示1展示0隐藏
*/
private Integer display;
/**
* 是否是逻辑删除
*/
private Integer isDeleted;
/**
* 更新人
*/
private Long updateBy;
/**
* 排序时间(15天后数据无法再次修改并迁移到历史订单中)
*/
private LocalDateTime sortTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,301 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 历史订单完成15天后同步到历史订单同步表中通过canal同步到历史订单库中1天后删除删除条件当天数据和历史订单库中的订单数据数量一致
* </p>
*
* @author itcast
* @since 2023-09-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "history_orders_sync",autoResultMap = true)
public class HistoryOrdersSync implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 订单所属人
*/
private Long userId;
/**
* 服务类型id
*/
private Long serveTypeId;
/**
* 服务人
*/
private Long serveProviderId;
/**
* 服务人类型2服务人员3机构
*/
private Integer serveProviderType;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务id
*/
private Long serveId;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务类型名称
*/
private String serveTypeName;
/**
* 服务项名称
*/
private String serveItemName;
/**
* 服务项图片
*/
private String serveItemImg;
/**
* 服务单位
*/
private Integer unit;
/**
* 订单状态500订单完成600已取消700已关闭
*/
private Integer ordersStatus;
/**
* 支付状态1支付成功2已关闭
*/
private Integer payStatus;
/**
* 退款0发起退款1退款中2退款成功 3退款失败
*/
private Integer refundStatus;
/**
* 订单完成时间
*/
private LocalDateTime tradeFinishTime;
/**
* 支付渠道ALI_PAY支付宝WECHAT_PAY微信
*/
private String tradingChannel;
/**
* 支付流水
*/
private String thirdOrderId;
/**
* 派单时间
*/
private LocalDateTime dispatchTime;
/**
* 单价
*/
private BigDecimal price;
/**
* 购买数量
*/
private Integer purNum;
/**
* 订单总金额
*/
private BigDecimal totalAmount;
/**
* 实际支付金额
*/
private BigDecimal realPayAmount;
/**
* 退款流水
*/
private String thirdRefundOrderId;
/**
* 取消人姓名
*/
private String cancelerName;
/**
* 优惠金额
*/
private BigDecimal discountAmount;
/**
* 服务详细地址
*/
private String serveAddress;
/**
* 联系人手机号
*/
private String contactsPhone;
/**
* 联系人姓名
*/
private String contactsName;
/**
* 服务人姓名
*/
private String serveProviderStaffName;
/**
* 服务人手机号
*/
private String serveProviderStaffPhone;
/**
* 机构名称
*/
private String institutionName;
/**
* 机构电话
*/
private String institutionPhone;
/**
* 下单时间
*/
private LocalDateTime placeOrderTime;
/**
* 服务开始时间
*/
private LocalDateTime serveStartTime;
/**
* 实际服务开始时间
*/
private LocalDateTime realServeStartTime;
/**
* 实际服务结束时间
*/
private LocalDateTime realServeEndTime;
/**
* 服务开始图片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveBeforeImgs;
/**
* 服务开始说明
*/
private String serveBeforeIllustrate;
/**
* 服务完成图片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveAfterImgs;
/**
* 服务完成说明
*/
private String serveAfterIllustrate;
/**
* 支付超时时间,该时间只对待支付有意义
*/
private LocalDateTime paymentTimeout;
/**
* 经度
*/
private Double lon;
/**
* 纬度
*/
private Double lat;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 取消/被退单时间
*/
private LocalDateTime cancelTime;
/**
* 取消/被退单原因
*/
private String cancelReason;
/**
* 下单年份,格式yyyy
*/
private Integer year;
/**
* 下单月份,格式yyyyMM
*/
private Integer month;
/**
* 下单所在日,格式yyyyMMdd
*/
private Integer day;
/**
* 下单所在小时格式yyyyMMddHH
*/
private Integer hour;
/**
* 排序时间字段(15天后数据无法再次修改并迁移到历史订单中)
*/
private LocalDateTime sortTime;
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,211 @@
package com.jzo2o.orders.base.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 订单表
* </p>
*
* @author itcast
* @since 2023-08-02
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders")
public class Orders implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 订单所属人
*/
private Long userId;
/**
* 服务类型id
*/
private Long serveTypeId;
/**
* 服务类型名称
*/
private String serveTypeName;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务项名称
*/
private String serveItemName;
/**
* 服务项图片
*/
private String serveItemImg;
/**
* 服务单位
*/
private Integer unit;
/**
* 服务id
*/
private Long serveId;
/**
* 订单状态0待支付100派单中200待服务300服务中400待评价500订单完成600已取消700已关闭
*/
private Integer ordersStatus;
/**
* 支付状态2待支付4支付成功
*/
private Integer payStatus;
/**
* 退款0发起退款1退款中2退款成功 3退款失败
*/
private Integer refundStatus;
/**
* 单价
*/
private BigDecimal price;
/**
* 购买数量
*/
private Integer purNum;
/**
* 订单总金额
*/
private BigDecimal totalAmount;
/**
* 实际支付金额
*/
private BigDecimal realPayAmount;
/**
* 优惠金额
*/
private BigDecimal discountAmount;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务详细地址
*/
private String serveAddress;
/**
* 联系人手机号
*/
private String contactsPhone;
/**
* 联系人姓名
*/
private String contactsName;
/**
* 服务开始时间
*/
private LocalDateTime serveStartTime;
/**
* 服务实际结束时间
*/
private LocalDateTime realServeEndTime;
/**
* 经度
*/
private Double lon;
/**
* 纬度
*/
private Double lat;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 评价时间
*/
private LocalDateTime evaluationTime;
/**
* 评价状态
*/
private Integer evaluationStatus;
/**
* 用户端是否展示1展示0隐藏
*/
private Integer display;
/**
* 排序字段serve_start_time秒级时间戳+订单id后5位
*/
private Long sortBy;
private LocalDateTime createTime;
private LocalDateTime updateTime;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 第三方支付的交易号
*/
private String transactionId;
/**
* 支付服务退款单号
*/
private Long refundNo;
/**
* 第三方支付的退款单号
*/
private String refundId;
/**
* 支付渠道
*/
private String tradingChannel;
}

View File

@@ -0,0 +1,71 @@
package com.jzo2o.orders.base.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-08-19
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders_canceled")
public class OrdersCanceled implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 取消人
*/
private Long cancellerId;
/**
* 取消人名称
*/
private String cancelerName;
/**
* 取消人类型1普通用户4运营人员
*/
private Integer cancellerType;
/**
* 取消原因
*/
private String cancelReason;
/**
* 取消时间
*/
private LocalDateTime cancelTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,114 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.Accessors;
/**
* <p>
* 派单池
* </p>
*
* @author itcast
* @since 2023-08-08
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders_dispatch")
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class OrdersDispatch implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务分类id
*/
private Long serveTypeId;
/**
* 服务名称
*/
private String serveItemName;
/**
* 服务分类名称
*/
private String serveTypeName;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务地址
*/
private String serveAddress;
/**
* 服务项目图片
*/
private String serveItemImg;
/**
* 订单金额
*/
private BigDecimal ordersAmount;
/**
* 服务开始时间
*/
private LocalDateTime serveStartTime;
/**
* 经度
*/
private Double lon;
/**
* 纬度
*/
private Double lat;
/**
* 服务数量
*/
private Integer purNum;
/**
* 是否转人工
*/
private Integer isTransferManual;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,52 @@
package com.jzo2o.orders.base.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 订单退款表
* </p>
*
* @author itcast
* @since 2023-09-07
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders_refund")
public class OrdersRefund implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 实付金额
*/
private BigDecimal realPayAmount;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,122 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.Accessors;
/**
* <p>
* 抢单池
* </p>
*
* @author itcast
* @since 2023-08-15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrdersSeize implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务分类id
*/
private Long serveTypeId;
/**
* 服务名称
*/
private String serveItemName;
/**
* 服务分类名称
*/
private String serveTypeName;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务地址
*/
private String serveAddress;
/**
* 服务项目图片
*/
private String serveItemImg;
/**
* 订单总金额
*/
private BigDecimal ordersAmount;
/**
* 服务开始时间
*/
private LocalDateTime serveStartTime;
/**
* 订单支付成功时间,用于计算是否进入派单
*/
private LocalDateTime paySuccessTime;
/**
* 经度
*/
private Double lon;
/**
* 纬度
*/
private Double lat;
/**
* 服务数量
*/
private Integer purNum;
/**
* 抢单是否超时
*/
private Integer isTimeOut;
/**
* 抢单列表排序字段
*/
private Long sortBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,178 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 服务任务
* </p>
*
* @author itcast
* @since 2023-08-02
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "orders_serve",autoResultMap = true)
public class OrdersServe implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 任务id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 属于哪个用户
*/
private Long userId;
/**
* 服务人员或服务机构id
*/
private Long serveProviderId;
/**
* 服务者类型2服务端服务3机构端服务
*/
private Integer serveProviderType;
/**
* 机构服务人员id
*/
private Long institutionStaffId;
/**
* 订单id
*/
private Long ordersId;
/**
* 订单来源类型1抢单2派单
*/
private Integer ordersOriginType;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务分类id
*/
private Long serveTypeId;
/**
* 预约时间
*/
private LocalDateTime serveStartTime;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务图片地址
*/
private String serveItemImg;
/**
* 任务状态
*/
private Integer serveStatus;
/**
* 结算状态0不可结算1待结算2结算完成
*/
private Integer settlementStatus;
/**
* 实际服务开始时间
*/
private LocalDateTime realServeStartTime;
/**
* 实际服务完结时间
*/
private LocalDateTime realServeEndTime;
/**
* 服务前照片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveBeforeImgs;
/**
* 服务后照片
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> serveAfterImgs;
/**
* 服务前说明
*/
private String serveBeforeIllustrate;
/**
* 服务后说明
*/
private String serveAfterIllustrate;
/**
* 取消时间,可以是退单,可以是取消时间
*/
private LocalDateTime cancelTime;
/**
* 订单金额
*/
private BigDecimal ordersAmount;
/**
* 购买数量
*/
private Integer purNum;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 排序字段serve_start_time秒级时间戳+订单id后6位
*/
private Long sortBy;
/**
* 服务端/机构端是否展示1展示0隐藏
*/
private Integer display;
/**
* 更新人
*/
private Long updateBy;
}

View File

@@ -0,0 +1,71 @@
package com.jzo2o.orders.base.model.domain;
import com.jzo2o.common.model.Location;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.List;
@Data
public class ServeProviderInfo {
/**
* 服务人员或机构同步表
*/
private Long id;
/**
* 类型2服务人员3机构
*/
private Integer serveProviderType;
/**
* 技能列表
*/
private List<Long> serveItemIds;
/**
* 经纬度
*/
private Location location;
/**
* 城市编码
*/
private String cityCode;
// /**
// * 接单距离
// */
// private Double receiveDistance;
/**
* 接单开关1接单开启0接单关闭
*/
private Integer pickUp;
/**
* 评分,默认50分
*/
private Double evaluationScore;
/**
* 服务时间
*/
private List<Integer> serveTimes;
/**
* 首次设置状态0未完成1已完成设置
*/
private Integer settingStatus;
/**
* 接单数
*/
private Integer acceptanceNum;
/**
* 状态0正常1冻结
*/
private Integer status;
}

View File

@@ -0,0 +1,48 @@
package com.jzo2o.orders.base.model.domain;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 机构服务端更新服务时间
* </p>
*
* @author itcast
* @since 2023-08-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "serve_provider_sync",autoResultMap = true)
public class ServeProviderSync implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 服务时间段
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Integer> serveTimes;
/**
* 接单数
*/
private Integer acceptanceNum;
}

View File

@@ -0,0 +1,242 @@
package com.jzo2o.orders.base.model.dto;
import com.jzo2o.statemachine.core.StateMachineSnapshot;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 订单快照
* @author itcast
* @create 2023/8/19 10:30
**/
@Data
@Builder
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class OrderSnapshotDTO extends StateMachineSnapshot {
/**
* 订单id
*/
private Long id;
/**
* 订单所属人
*/
private Long userId;
/**
* 服务类型id
*/
private Long serveTypeId;
/**
* 服务类型名称
*/
private String serveTypeName;
/**
* 服务项id
*/
private Long serveItemId;
/**
* 服务项名称
*/
private String serveItemName;
/**
* 服务项图片
*/
private String serveItemImg;
/**
* 服务单位
*/
private Integer unit;
/**
* 服务id
*/
private Long serveId;
/**
* 订单状态0待支付100派单中200待服务300服务中500订单完成600订单取消700已关闭
*/
private Integer ordersStatus;
/**
* 支付状态2待支付4支付成功
*/
private Integer payStatus;
/**
* 退款0发起退款1退款中2退款成功 3退款失败
*/
private Integer refundStatus;
/**
* 单价
*/
private BigDecimal price;
/**
* 购买数量
*/
private Integer purNum;
/**
* 订单总金额
*/
private BigDecimal totalAmount;
/**
* 实际支付金额
*/
private BigDecimal realPayAmount;
/**
* 优惠金额
*/
private BigDecimal discountAmount;
/**
* 城市编码
*/
private String cityCode;
/**
* 服务详细地址
*/
private String serveAddress;
/**
* 联系人手机号
*/
private String contactsPhone;
/**
* 联系人姓名
*/
private String contactsName;
/**
* 服务开始时间
*/
private LocalDateTime serveStartTime;
/**
* 经度
*/
private String lon;
/**
* 纬度
*/
private String lat;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 评价时间
*/
private LocalDateTime evaluationTime;
/**
* 订单创建时间
*/
private LocalDateTime createTime;
/**
* 订单更新时间
*/
private LocalDateTime updateTime;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 支付服务退款单号
*/
private Long refundNo;
/**
* 支付渠道【支付宝、微信、现金、免单挂账】
*/
private String tradingChannel;
/**
* 三方流水,微信支付订单号或支付宝订单号
*/
private String thirdOrderId;
/**
* 退款三方流水,微信支付订单号或支付宝订单号
*/
private String thirdRefundOrderId;
/**
* 取消人id
*/
private Long cancellerId;
/**
* 取消人名称
*/
private String cancelerName;
/**
* 取消人类型
*/
private Integer cancellerType;
/**
* 取消时间
*/
private LocalDateTime cancelTime;
/**
* 取消原因
*/
private String cancelReason;
/**
* 实际服务完成时间
*/
private LocalDateTime realServeEndTime;
/**
* 评价状态
*/
private Integer evaluationStatus;
@Override
public String getSnapshotId() {
return String.valueOf(id);
}
@Override
public Integer getSnapshotStatus() {
return ordersStatus;
}
@Override
public void setSnapshotId(String snapshotId) {
this.id = Long.parseLong(snapshotId);
}
@Override
public void setSnapshotStatus(Integer snapshotStatus) {
this.ordersStatus = snapshotStatus;
}
}

View File

@@ -0,0 +1,84 @@
package com.jzo2o.orders.base.model.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class OrderUpdateStatusDTO {
/**
* 订单id
*/
private Long id;
/**
* 原订单状态
*/
private Integer originStatus;
/**
* 目标订单状态
*/
private Integer targetStatus;
/**
* 支付状态
*/
private Integer payStatus;
/**
* 退款状态
*/
private Integer refundStatus;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 评价时间
*/
private LocalDateTime evaluationTime;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 第三方支付的交易号
*/
private String transactionId;
/**
* 支付服务退款单号
*/
private Long refundNo;
/**
* 第三方支付的退款单号
*/
private String refundId;
/**
* 支付渠道
*/
private String tradingChannel;
/**
* 实际服务完成时间
*/
private LocalDateTime realServeEndTime;
/**
* 评价状态
*/
private Integer evaluationStatus;
}

View File

@@ -0,0 +1,32 @@
package com.jzo2o.orders.base.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 派单配置
*/
@Configuration
@ConfigurationProperties(prefix = "orders.dispatch")
@Data
public class DispatchProperties {
/**
* 机构端展示抢单列表数量
*/
public Integer seizeListDispalyNumOfInstitution = 50;
/**
* 服务端展示抢单列表数量
*/
public Integer seizeListDispalyNumOfServe = 20;
/**
* 机构端拥有服务单数量
*/
public Integer serveTaskNumOrInstitution = 50;
/**
* 服务人员最大拥有服务数量
*/
public Integer serveTaskNumOfServe = 10;
}

View File

@@ -0,0 +1,61 @@
package com.jzo2o.orders.base.properties;
import com.jzo2o.common.utils.ObjectUtils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
@ConfigurationProperties(prefix = "executor")
@Data
public class ExecutorProperties {
/**
* 线程池配置
*/
@NestedConfigurationProperty
private Map<String, ThreadPool> pools = new HashMap<>();
/**
* 线程池配置
*/
@Data
public static class ThreadPool {
/**
* 核心线程数 默认15
*/
private Integer corePoolSize = 15;
/**
* 最大线程数 默认30
*/
private Integer maxPoolSize = 30;
/**
* 队列大小默认 5000
*/
private Integer queueCapacity = 5000;
/**
* 线程名称默认orders-
*/
private String threadNamePrefix = "orders-";
}
/**
* 线程池名称
*
* @param name
* @return
*/
public final ThreadPool get(String name) {
ThreadPool threadPool = pools.get(name);
return ObjectUtils.isNull(threadPool) ? new ThreadPool() : threadPool;
}
}

View File

@@ -0,0 +1,20 @@
package com.jzo2o.orders.base.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
/**
* <p>
* 订单表 服务类
* </p>
*
* @author itcast
* @since 2023-08-02
*/
public interface IOrdersCommonService extends IService<Orders> {
/**
* 更新指定id订单的状态
*/
Boolean updateStatus(OrderUpdateStatusDTO orderUpdateStatusReqDTO);
}

View File

@@ -0,0 +1,17 @@
package com.jzo2o.orders.base.service;
import com.jzo2o.orders.base.model.domain.Orders;
/**
* 订单分流
*/
public interface IOrdersDiversionCommonService {
/**
* 订单分流,所有订单均可抢单
*
* @param orders
*/
void diversion(Orders orders);
}

View File

@@ -0,0 +1,40 @@
package com.jzo2o.orders.base.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import org.springframework.stereotype.Service;
/**
* <p>
* 订单表 服务实现类
* </p>
* @author itcast
* @since 2023-08-02
*/
@Service
public class OrdersCommonServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersCommonService {
@Override
public Boolean updateStatus(OrderUpdateStatusDTO orderUpdateStatusReqDTO) {
return lambdaUpdate()
.eq(Orders::getId, orderUpdateStatusReqDTO.getId())
.gt(Orders::getUserId, 0)
.eq(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getOriginStatus()), Orders::getOrdersStatus, orderUpdateStatusReqDTO.getOriginStatus())
.set(Orders::getOrdersStatus, orderUpdateStatusReqDTO.getTargetStatus())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getPayStatus()), Orders::getPayStatus, orderUpdateStatusReqDTO.getPayStatus())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getPayTime()), Orders::getPayTime, orderUpdateStatusReqDTO.getPayTime())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getEvaluationTime()), Orders::getEvaluationTime, orderUpdateStatusReqDTO.getEvaluationTime())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTradingOrderNo()), Orders::getTradingOrderNo, orderUpdateStatusReqDTO.getTradingOrderNo())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTransactionId()), Orders::getTransactionId, orderUpdateStatusReqDTO.getTransactionId())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTradingChannel()), Orders::getTradingChannel, orderUpdateStatusReqDTO.getTradingChannel())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRefundStatus()), Orders::getRefundStatus, orderUpdateStatusReqDTO.getRefundStatus())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRefundNo()), Orders::getRefundNo, orderUpdateStatusReqDTO.getRefundNo())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRefundId()), Orders::getRefundId, orderUpdateStatusReqDTO.getRefundId())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRealServeEndTime()), Orders::getRealServeEndTime, orderUpdateStatusReqDTO.getRealServeEndTime())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getEvaluationStatus()), Orders::getEvaluationStatus, orderUpdateStatusReqDTO.getEvaluationStatus())
.update();
}
}

View File

@@ -0,0 +1,119 @@
//package com.jzo2o.orders.base.service.impl;
//
//import com.jzo2o.api.foundations.RegionApi;
//import com.jzo2o.api.foundations.ServeApi;
//import com.jzo2o.api.foundations.dto.response.ConfigRegionInnerResDTO;
//import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
//import com.jzo2o.common.utils.BooleanUtils;
//import com.jzo2o.common.utils.DateUtils;
//import com.jzo2o.common.utils.ObjectUtils;
//import com.jzo2o.orders.base.mapper.OrdersDispatchMapper;
//import com.jzo2o.orders.base.mapper.OrdersSeizeMapper;
//import com.jzo2o.orders.base.model.domain.Orders;
//import com.jzo2o.orders.base.model.domain.OrdersDispatch;
//import com.jzo2o.orders.base.model.domain.OrdersSeize;
//import com.jzo2o.orders.base.service.IOrdersDiversionCommonService;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import javax.annotation.Resource;
//import java.time.Duration;
//
//@Service
//@Slf4j
//public class OrdersDiversionCommonServiceImpl implements IOrdersDiversionCommonService {
//
//
// @Resource
// private RedisTemplate<String, Long> redisTemplate;
//
// @Resource
// private RegionApi regionApi;
//
// @Resource
// private ServeApi serveApi;
//
// @Resource
// private OrdersDiversionCommonServiceImpl owner;
//
// @Resource
// private OrdersSeizeMapper ordersSeizeMapper;
// @Resource
// private OrdersDispatchMapper ordersDispatchMapper;
//
// @Override
// public void diversion(Orders orders) {
// log.debug("订单分流id:{}",orders.getId());
// // 1.当前时间已超过服务预约时间则不再分流
// if (orders.getServeStartTime().compareTo(DateUtils.now()) < 0) {
// log.debug("订单{}当前时间已超过服务预约时间则不再分流",orders.getId());
// return;
// }
// ConfigRegionInnerResDTO configRegion = regionApi.findConfigRegionByCityCode(orders.getCityCode());
// ServeAggregationResDTO serveAggregationResDTO = serveApi.findById(orders.getServeId());
// //订单分流数据存储
// owner.diversionCommit(orders,configRegion,serveAggregationResDTO);
// }
//
// @Transactional(rollbackFor = Exception.class)
// public void diversionCommit(Orders orders, ConfigRegionInnerResDTO configRegion, ServeAggregationResDTO serveAggregationResDTO) {
// //流间隔(单位分钟),即当前时间与服务预计开始时间的间隔
// Integer diversionInterval = configRegion.getDiversionInterval();
//
// //当前时间与服务预约时间的间隔
// Duration between = DateUtils.between(DateUtils.now(), orders.getServeStartTime());
// //服务类型名称
// String serveTypeName = ObjectUtils.get(serveAggregationResDTO, ServeAggregationResDTO::getServeTypeName);
// //服务类型id
// Long serveTypeId = ObjectUtils.get(serveAggregationResDTO, ServeAggregationResDTO::getServeTypeId);
// //服务项名称
// String serveItemName = ObjectUtils.get(serveAggregationResDTO, ServeAggregationResDTO::getServeItemName);
// //服务项图片
// String serveItemImg = ObjectUtils.get(serveAggregationResDTO, ServeAggregationResDTO::getServeItemImg);
// //用于排序,服务预约时间戳加订单号后5位
// long sortBy = DateUtils.toEpochMilli(orders.getServeStartTime()) + orders.getId() % 100000;
// OrdersSeize ordersSeize = OrdersSeize.builder()
// .id(orders.getId())
// .ordersAmount(orders.getRealPayAmount())
// .cityCode(orders.getCityCode())
// .serveTypeId(serveTypeId)
// .serveTypeName(serveTypeName)
// .serveItemId(orders.getServeItemId())
// .serveItemName(serveItemName)
// .serveItemImg(serveItemImg)
// .ordersAmount(orders.getRealPayAmount())
// .serveStartTime(orders.getServeStartTime())
// .serveAddress(orders.getServeAddress())
// .lon(orders.getLon())
// .lat(orders.getLat())
// .paySuccessTime(DateUtils.now())
// .paySuccessTime(orders.getPayTime())
// .sortBy(sortBy)
// .isTimeOut(BooleanUtils.toInt(between.toMinutes() < diversionInterval))
// .purNum(orders.getPurNum()).build();
// ordersSeizeMapper.insert(ordersSeize);
// //当前时间与服务预约时间的间隔 小于指定间隔则插入派单表
// if (between.toMinutes() < diversionInterval) {
// OrdersDispatch ordersDispatch = OrdersDispatch.builder()
// .id(orders.getId())
// .ordersAmount(orders.getRealPayAmount())
// .cityCode(orders.getCityCode())
// .serveTypeId(serveTypeId)
// .serveTypeName(serveTypeName)
// .serveItemId(orders.getServeItemId())
// .serveItemName(serveItemName)
// .serveItemImg(serveItemImg)
// .ordersAmount(orders.getRealPayAmount())
// .serveStartTime(orders.getServeStartTime())
// .serveAddress(orders.getServeAddress())
// .lon(orders.getLon())
// .lat(orders.getLat())
// .purNum(orders.getPurNum()).build();
// ordersDispatchMapper.insert(ordersDispatch);
// }
// }
//
//
//}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.orders.base.utils;
import com.jzo2o.common.utils.NumberUtils;
public class RedisUtils {
/**
* 获取城市编码最后以为数字
*
* @param cityCode
* @return
*/
public static int getCityIndex(String cityCode) {
return NumberUtils.parseInt(cityCode) % 10;
}
}

View File

@@ -0,0 +1,24 @@
package com.jzo2o.orders.base.utils;
import com.jzo2o.common.utils.DateUtils;
import com.jzo2o.common.utils.NumberUtils;
import java.time.LocalDateTime;
public class ServeTimeUtils {
/**
* 获取服务时间,用来处理抢单和派单的时间冲突问题
*
* @param serveStartTime
* @return
*/
public static int getServeTimeInt(LocalDateTime serveStartTime) {
return NumberUtils.parseInt(DateUtils.format(serveStartTime, "yyyyMMddHH"));
}
public static void main(String[] args) {
long number = 2023082400000000001L;
System.out.println(number % 10000000000L % 150000);
}
}

View File

@@ -0,0 +1,9 @@
{
"groups": [
],
"properties": [
],
"hints": []
}

View File

@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.jzo2o.orders.base.config.AutoImportConfiguration

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.BreachRecordMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.HistoryOrdersServeSyncMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.HistoryOrdersSyncMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.CurrentServeProviderTimeMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.OrdersServeMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.OrdersCanceledMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.OrdersDispatchMapper">
</mapper>

View File

@@ -0,0 +1,18 @@
<?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.jzo2o.orders.base.mapper.OrdersMapper">
<select id="selectOrderIdList" resultType="java.lang.Long">
select id from orders
<where>
<if test="ordersStatus != null">
orders_status = #{ordersStatus}
</if>
and user_id = #{currentUserId}
and display = 1
<if test="sortBy != null">
and sort_by &lt; #{sortBy}
</if>
</where>
LIMIT 10
</select>
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.OrdersRefundMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.OrdersSeizeMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?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.jzo2o.orders.base.mapper.ServeProviderSyncMapper">
</mapper>

View File

@@ -0,0 +1,8 @@
FROM openjdk:11-jdk
LABEL maintainer="研究院研发组 <research-maint@itcast.cn>"
RUN echo "Asia/Shanghai" > /etc/timezone
ARG PACKAGE_PATH=./target/jzo2o-orders-manager.jar
ADD ${PACKAGE_PATH:-./} app.jar
EXPOSE 11504
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS app.jar"]

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jzo2o-oreders</artifactId>
<groupId>com.jzo2o</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jzo2o-orders-manager</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mvc</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-knife4j-web</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mysql</artifactId>
<exclusions>
<exclusion>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-api</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-redis</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-orders-base</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-xxl-job</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-es</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-sentinel</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.jzo2o.orders.manager.OrdersManagerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

Some files were not shown because too many files have changed in this diff Show More