zhuyifan

农信点餐小程序

Showing 60 changed files with 2841 additions and 97 deletions
......@@ -48,6 +48,7 @@ dependencies {
implementation 'com.aliyun:aliyun-java-sdk-core:4.6.4' //阿里云SDK核心库
implementation 'com.aliyun:aliyun-java-sdk-dysmsapi:2.2.1'//阿里云短信服务SDK
implementation 'com.aliyun:aliyun-java-sdk-dm:3.3.2'//阿里云邮件服务SDK
implementation "com.aliyun.oss:aliyun-sdk-oss:3.11.1"//阿里云OSS服务
implementation "io.zipkin.brave:brave:5.12.5"
implementation "io.zipkin.brave:brave-context-slf4j:5.12.5"
......@@ -61,8 +62,8 @@ dependencies {
// compileOnly 'org.projectlombok:lombok'
// annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
......@@ -113,5 +114,6 @@ sourceSets {
}
test {
enabled = false
useJUnitPlatform()
}
\ No newline at end of file
......
......@@ -58,7 +58,6 @@ public class RepeatSubmitAspect {
* 获取LockKey
*
* @param joinPoint 切入点
* @return
*/
public static String getLockKey(ProceedingJoinPoint joinPoint) {
//获取连接点的方法签名对象
......@@ -79,13 +78,13 @@ public class RepeatSubmitAspect {
continue;
}
//如果属性是RequestKeyParam注解,则拼接 连接符 "& + RequestKeyParam"
if (sb.length() > 0) {
if (!sb.isEmpty()) {
sb.append(requestLock.delimiter());
}
sb.append(args[i]);
}
//如果方法上没有加RequestKeyParam注解
if (StringUtils.isEmpty(sb.toString())) {
if (!StringUtils.hasText((sb.toString()))) {
//获取方法上的多个注解(为什么是两层数组:因为第二层数组是只有一个元素的数组)
final var parameterAnnotations = method.getParameterAnnotations();
//循环注解
......@@ -103,7 +102,7 @@ public class RepeatSubmitAspect {
//如果有,设置Accessible为true(为true时可以使用反射访问私有变量,否则不能访问私有变量)
field.setAccessible(true);
//如果属性是RequestKeyParam注解,则拼接 连接符" & + RequestKeyParam"
if (sb.length() > 0) {
if (!sb.isEmpty()) {
sb.append(requestLock.delimiter());
}
sb.append(ReflectionUtils.getField(field, object));
......@@ -112,9 +111,9 @@ public class RepeatSubmitAspect {
}
if (requestLock.isLockByLoginUser()) {
final var operatorId = LoginContextHolder.hasLogin() ? LoginContextHolder.getId() : null;
return requestLock.prefix() + (operatorId != null ? CommonConstants.COLON + operatorId : "") + (sb.length() > 0 ? CommonConstants.UNDERLINE + sb : "");
return requestLock.prefix() + (operatorId != null ? CommonConstants.COLON + operatorId : "") + (!sb.isEmpty() ? CommonConstants.UNDERLINE + sb : "");
} else {
return requestLock.prefix() + (sb.length() > 0 ? CommonConstants.UNDERLINE + sb : "");
return requestLock.prefix() + (!sb.isEmpty() ? CommonConstants.UNDERLINE + sb : "");
}
}
}
......
......@@ -3,16 +3,22 @@ package com.infoloop.tianting.config;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.infoloop.tianting.server.StorageService;
import com.infoloop.tianting.server.StorageServiceFactory;
import com.infoloop.tianting.store.LoginCodeStore;
import com.infoloop.tianting.store.WeeklyTaskStore;
import com.infoloop.tianting.utils.SmsUtil;
import io.lettuce.core.api.StatefulRedisConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import java.time.Duration;
import static com.infoloop.tianting.constant.ConfigConstants.REDIS_CONNECTION;
@Configuration
......@@ -26,6 +32,13 @@ public class AppConfig {
return new LoginCodeStore(commands, 300);
}
@Bean
public WeeklyTaskStore weeklyTaskStore(@Autowired @Qualifier(REDIS_CONNECTION) final StatefulRedisConnection<String, String> connection) {
final var commands = connection.sync();
final var expireSeconds = Duration.ofDays(7).getSeconds();
return new WeeklyTaskStore(commands, expireSeconds);
}
// init bean
@Bean
public SmsUtil smsUtil(@Autowired SmsConfig smsConfig) {
......@@ -35,6 +48,12 @@ public class AppConfig {
}
@Bean
@ConditionalOnProperty(name = "aliyun.oss.endpoint")
public StorageService storageService(@Autowired OssConfig ossConfig) {
return StorageServiceFactory.createStorageService(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
}
@Bean
public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
return new MappingJackson2XmlHttpMessageConverter(new XmlMapper());
}
......
......@@ -11,6 +11,7 @@ import com.infoloop.tianting.clientinventoryservice.TiantingClientInventoryServi
import com.infoloop.tianting.clientresourcetagservice.ClientResourceTagServiceRpcGrpc;
import com.infoloop.tianting.deliveryruleservice.TiantingDeliveryRuleServiceRpcGrpc;
import com.infoloop.tianting.enterpriseresourcetagservice.EnterpriseResourceTagServiceRpcGrpc;
import com.infoloop.tianting.mealorderservice.MealOrderServiceRpcGrpc;
import com.infoloop.tianting.menuservice.MenuServiceRpcGrpc;
import com.infoloop.tianting.setmealscheduleservice.SetMealScheduleServiceRpcGrpc;
import io.grpc.ClientInterceptor;
......@@ -86,6 +87,11 @@ public class GrpcConfig {
return ClientCustomerOrderServiceRpcGrpc.newBlockingStub(channel);
}
@Bean
public MealOrderServiceRpcGrpc.MealOrderServiceRpcBlockingStub mealOrderServiceRpcBlockingStub(@Autowired @Qualifier(ORDER_SERVICE_CHANNEL) final ManagedChannel channel) {
return MealOrderServiceRpcGrpc.newBlockingStub(channel);
}
@Bean(MENU_SERVICE_CHANNEL)
public ManagedChannel menuServiceChannel(@Value(MENU_SERVICE_RPC_URL) final String url,
@Value(MENU_SERVICE_RPC_PORT) final int port,
......
package com.infoloop.tianting.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
@Data
@PropertySource(encoding = "UTF-8", value = "classpath:application.properties", ignoreResourceNotFound = true)
public class OssConfig {
private String accessKeyId;
private String accessKeySecret;
private String endpoint;
private String host;
private String bucket;
}
package com.infoloop.tianting.config;
import com.infoloop.tianting.intercepter.ResourceInjector;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -8,9 +10,9 @@ import org.springframework.context.annotation.Configuration;
public class ResourceInjectorConfig {
@Bean
public ResourceInjector resourceInjector(
public ResourceInjector resourceInjector(final MealOrderServiceRpcClient mealOrderServiceRpcClient,
final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient
) {
return new ResourceInjector();
return new ResourceInjector(mealOrderServiceRpcClient, clientInventoryServiceRpcClient);
}
}
......
......@@ -7,6 +7,8 @@ import com.infoloop.tianting.intercepter.LoginInterceptor;
import com.infoloop.tianting.intercepter.RequestMonitor;
import com.infoloop.tianting.intercepter.ResourceInjector;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
......@@ -38,12 +40,15 @@ public class WebMvcConfig implements WebMvcConfigurer {
final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient,
final OperatorServiceRpcClient operatorServiceRpcClient,
final WOperatorServiceRpcClient wOperatorServiceRpcClient,
final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient) {
final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient,
final MealOrderServiceRpcClient mealOrderServiceRpcClient,
final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient) {
this.httpInterceptors = new ArrayList<>();
this.httpInterceptors.add(new HttpTracingInterceptor(tracing));
this.httpInterceptors.add(new RequestMonitor());
this.httpInterceptors.add(new ApiSignInterceptor());
this.httpInterceptors.add(new LoginInterceptor(clientCustomerServiceRpcClient, meiZhongYiHeServiceClient, operatorServiceRpcClient, wOperatorServiceRpcClient));
this.httpInterceptors.add(new ResourceInjector(mealOrderServiceRpcClient, clientInventoryServiceRpcClient));
this.httpInterceptors.add(resourceInjector);
}
......
......@@ -24,10 +24,6 @@ public interface ConfigConstants {
String ENTERPRISE_REDIS_PASSWORD = "${enterprise.redis.password}";
String ENTERPRISE_REDIS_DATABASE = "${enterprise.redis.database}";
String EXAMPLE_SERVICE_RPC_URL = "${grpc.example-service.url}";
String EXAMPLE_SERVICE_RPC_PORT = "${grpc.example-service.port}";
String EXAMPLE_SERVICE_CHANNEL = "example-service-channel";
String ORDER_SERVICE_RPC_URL = "${grpc.order-service.url}";
String ORDER_SERVICE_RPC_PORT = "${grpc.order-service.port}";
String ORDER_SERVICE_CHANNEL = "order-service-channel";
......
......@@ -2,9 +2,21 @@ package com.infoloop.tianting.constant;
public interface PathVariableResourceConstants {
String INJECTED_TEST_EXAMPLE_DB = "testExampleDb";
String TEST_EXAMPLE_DB_ID_PATH_VARIABLE = "testExampleDbId";
String INJECTED_MP_ACCOUNT = "mpAccount";
String MP_ACCOUNT_ID_PATH_VARIABLE = "mpAccountId";
String INJECTED_CLIENT = "client";
String CLIENT_ID_PATH_VARIABLE = "clientId";
String INJECTED_DINER = "diner";
String DINER_ID_PATH_VARIABLE = "dinerId";
String INJECTED_GRADE_CLASS = "gradeClass";
String GRADE_CLASS_ID_PATH_VARIABLE = "gradeClassId";
String INJECTED_MEAL_ORDER = "mealOrder";
String MEAL_ORDER_ID_PATH_VARIABLE = "mealOrderId";
}
......
......@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "Category")
@Api(tags = "品类")
@ApiSupport(order = -1)
@Slf4j
@Validated
......
......@@ -2,10 +2,10 @@ package com.infoloop.tianting.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.TableCodeQueryConditionDto;
import com.infoloop.tianting.service.InventoryService;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.TableCodeQueryConditionDto;
import com.infoloop.tianting.service.ClientInventoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
......@@ -17,40 +17,48 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@Api(tags = "院区")
@Api(tags = "项目点")
@ApiSupport(order = -1)
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryController {
private final InventoryService inventoryService;
public class ClientController {
private final ClientInventoryService clientInventoryService;
@SaIgnore
@ApiOperation(value = "根据Id获取Client")
@GetMapping("/enterprises/{enterpriseId}/clients/{clientId}")
@ResponseStatus(HttpStatus.OK)
public ClientDto getClientById(@PathVariable Integer enterpriseId, @PathVariable Integer clientId) {
return inventoryService.getClientById(enterpriseId, clientId);
return clientInventoryService.getClientById(enterpriseId, clientId);
}
@ApiOperation(value = "根据Codes获取Clients")
@GetMapping("/clients/bycodes")
@ResponseStatus(HttpStatus.OK)
public List<ClientDto> getClientsByCodes(@RequestParam List<String> codes) {
return clientInventoryService.getClientsByCodes(codes);
}
@ApiOperation(value = "根据ClientId获取Stalls")
@GetMapping("/enterprises/{enterpriseId}/clients/{clientId}/stalls")
@ResponseStatus(HttpStatus.OK)
public List<ClientDto> getStallsByClientId(@PathVariable Integer enterpriseId, @PathVariable Integer clientId) {
return inventoryService.getStallsByClientId(enterpriseId, clientId);
return clientInventoryService.getStallsByClientId(enterpriseId, clientId);
}
@ApiOperation(value = "获取桌号")
@PostMapping("/tableCodes")
@ResponseStatus(HttpStatus.OK)
public List<ClientTableCodeDto> getTableCodes(@Valid @RequestBody TableCodeQueryConditionDto tableCodeQueryConditionDto) {
return inventoryService.queryClientTableCodesByCondition(tableCodeQueryConditionDto);
return clientInventoryService.queryClientTableCodesByCondition(tableCodeQueryConditionDto);
}
}
......
......@@ -22,7 +22,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
@Api(tags = "客户")
@Api(tags = "项目点客户")
@ApiSupport(order = -1)
@Slf4j
@Validated
......
package com.infoloop.tianting.controller;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.DinerDTO;
import com.infoloop.tianting.model.vo.DinerVO;
import com.infoloop.tianting.model.vo.GradeClassVO;
import com.infoloop.tianting.service.DinerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_CLIENT;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_DINER;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_GRADE_CLASS;
@Api(tags = "就餐人")
@ApiSupport(order = -1)
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DinerController {
private final DinerService dinerService;
@ApiOperation(value = "用户就餐人列表")
@GetMapping("/mpaccount/diners")
@ResponseStatus(HttpStatus.OK)
public List<DinerVO> getMpAccountDiners() {
return dinerService.getMpAccountDiners();
}
@ApiOperation(value = "添加就餐人")
@PutMapping("/mpaccount/diner")
@ResponseStatus(HttpStatus.CREATED)
public CreatedResult<DinerVO> createMpAccountDiner(@RequestBody @Valid final DinerDTO.CreateDinerDTO createDinerDTO) {
return dinerService.createMpAccountDiner(createDinerDTO);
}
@ApiOperation(value = "学校年级班级列表")
@GetMapping("/client/{clientId}/gradeclasses")
@ResponseStatus(HttpStatus.OK)
public List<GradeClassVO> getClientGradeClasses(@RequestAttribute(INJECTED_CLIENT) final SingleClientRpcResponse client) {
return dinerService.getClientGradeClasses(client);
}
@ApiOperation(value = "根据学校,班级和学号查询就餐人")
@GetMapping("/client/{clientId}/gradeclass/{gradeClassId}/diner")
@ResponseStatus(HttpStatus.OK)
public DinerVO getClientClassDiner(@RequestAttribute(INJECTED_CLIENT) final SingleClientRpcResponse client,
@RequestAttribute(INJECTED_GRADE_CLASS) final SingleGradeClassRpcResponse gradeClass,
@RequestBody @Valid final DinerDTO.QueryUniqueDinerDTO queryUniqueDinerDTO) {
return dinerService.getClientClassDiner(client, gradeClass, queryUniqueDinerDTO.getStudentNo());
}
@ApiOperation(value = "修改就餐人")
@PatchMapping("/mpaccount/diner/{dinerId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateMpAccountDiner(@RequestAttribute(INJECTED_DINER) final SingleDinerRpcResponse diner,
@RequestBody @Valid final DinerDTO.UpdateDinerDTO updateDinerDTO) {
dinerService.updateMpAccountDiner(diner, updateDinerDTO);
}
@ApiOperation(value = "删除就餐人")
@DeleteMapping("/mpaccount/diner/{dinerId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteMpAccountDiner(@RequestAttribute(INJECTED_DINER) final SingleDinerRpcResponse diner) {
dinerService.deleteMpAccountDiner(diner);
}
}
......@@ -3,7 +3,10 @@ package com.infoloop.tianting.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.SaTokenInfo;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.model.dto.MpAccountDTO;
import com.infoloop.tianting.model.dto.PermissionDTO;
import com.infoloop.tianting.model.vo.MpAccountVO;
import com.infoloop.tianting.service.LoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
......@@ -12,7 +15,11 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
......@@ -20,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.security.NoSuchAlgorithmException;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_MP_ACCOUNT;
@Api(tags = "登陆")
@ApiSupport(order = -1)
@Slf4j
......@@ -36,4 +45,20 @@ public class LoginController {
public SaTokenInfo login(@Valid @RequestBody PermissionDTO.LoginDto loginDto) throws NoSuchAlgorithmException {
return loginService.login(loginDto);
}
@SaIgnore
@ApiOperation(value = "根据openId获取小程序用户")
@GetMapping("/mpaccount/{openId}")
@ResponseStatus(HttpStatus.OK)
public MpAccountVO getMpAccountByOpenId(@PathVariable("openId") String openId) {
return loginService.getMpAccountByOpenId(openId);
}
@ApiOperation(value = "修改小程序用户")
@PatchMapping("/mpaccount/{mpAccountId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateMpAccount(@RequestAttribute(INJECTED_MP_ACCOUNT) final SingleMpAccountRpcResponse mpAccount,
@RequestBody @Valid MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO) {
loginService.updateMpAccount(mpAccount, modifyMpAccountDTO);
}
}
......
package com.infoloop.tianting.controller;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.annotation.RepeatSubmit;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.MealOrderDTO;
import com.infoloop.tianting.model.vo.DeliveryRuleVO;
import com.infoloop.tianting.model.vo.MealOrderVO;
import com.infoloop.tianting.service.MealOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_MEAL_ORDER;
@Api(tags = "订餐")
@ApiSupport(order = -1)
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MealOrderController {
private final MealOrderService mealOrderService;
@ApiOperation(value = "订餐记录")
@PostMapping("/mealorders")
@ResponseStatus(HttpStatus.OK)
public List<MealOrderVO> queryMealOrders(@RequestBody @Valid final MealOrderDTO.QueryMealOrderDTO queryMealOrderDTO) {
return mealOrderService.queryMealOrders(queryMealOrderDTO);
}
@ApiOperation(value = "立即订餐")
@PutMapping("/mealorder")
@RepeatSubmit(prefix = "create.meal.order", isLockByLoginUser = false)
@ResponseStatus(HttpStatus.CREATED)
public CreatedResult<MealOrderVO> createMealOrder(@RequestBody @Valid final MealOrderDTO.CreateMealOrderDTO createMealOrderDTO) {
return mealOrderService.createMealOrder(createMealOrderDTO);
}
@ApiOperation(value = "订餐记录详情")
@GetMapping("/mealorder/{mealOrderId}")
@ResponseStatus(HttpStatus.OK)
public MealOrderVO getMealOrderById(@RequestAttribute(INJECTED_MEAL_ORDER) final SingleMealOrderRpcResponse mealOrder) {
return mealOrderService.getMealOrderById(mealOrder);
}
@ApiOperation(value = "订餐规则")
@GetMapping("/deliveryrule")
@ResponseStatus(HttpStatus.OK)
public DeliveryRuleVO getDeliveryRule() {
return mealOrderService.getDeliveryRule();
}
}
package com.infoloop.tianting.controller;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.model.dto.MenuDbDTO;
import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto;
import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto;
......@@ -18,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
......@@ -25,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
import static com.infoloop.tianting.constant.PathVariableResourceConstants.INJECTED_CLIENT;
@Api(tags = "餐单")
@ApiSupport(order = -1)
@Slf4j
......@@ -76,4 +80,11 @@ public class MenuController {
return menuService.batchCreateMenuRefs(batchCreateMenuRefsDto);
}
@ApiOperation(value = "查询学校最新餐单")
@GetMapping("/client/{clientId}/mealmenurecord")
@ResponseStatus(HttpStatus.OK)
public String queryClientLatestMealMenuRecord(@RequestAttribute(INJECTED_CLIENT) final SingleClientRpcResponse client) {
return menuService.queryClientLatestMealMenuRecord(client);
}
}
......
......@@ -27,6 +27,7 @@ public class MiniProgramController {
private final WxMiniProgramService wxMiniProgramService;
@SaIgnore
@ApiOperation(value = "小程序:根据code获取openId")
@GetMapping("/wx/miniprogram/customers/openid/{code}")
@ResponseStatus(HttpStatus.OK)
......
package com.infoloop.tianting.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infoloop.tianting.config.OssConfig;
import com.infoloop.tianting.server.StorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nullable;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Api(tags = "上传、下载管理")
@ApiSupport(order = 99)
@Slf4j
@Validated
@RestController
public class UploadController {
private final OssConfig ossConfig;
private final StorageService storageService;
@Autowired(required = false)
public UploadController(OssConfig ossConfig, @Nullable StorageService storageService) {
this.ossConfig = ossConfig;
this.storageService = storageService;
}
@SaIgnore
@ApiOperation("上传")
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public String upload(@RequestParam("file") MultipartFile file,
@RequestParam(value = "folder", defaultValue = "upload") String folder) throws Exception {
Assert.notNull(storageService, "存储服务未初始化,请检查配置 aliyun.oss.endpoint");
String extension = FileNameUtil.getSuffix(file.getOriginalFilename());
String path = generateUploadPath(folder, extension);
File tempFile = File.createTempFile(IdUtil.fastSimpleUUID(), null);
try {
file.transferTo(tempFile);
storageService.putObject(ossConfig.getBucket(), path, tempFile);
} catch (Exception e) {
log.error("上传失败: {}", file.getOriginalFilename(), e);
throw new RuntimeException("文件上传失败,请稍后重试");
} finally {
tempFile.delete();
}
return String.format("%s/%s", ossConfig.getHost(), path);
}
@SaIgnore
@ApiOperation("下载")
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseStatus(HttpStatus.OK)
public void download(@RequestParam("path") String path, HttpServletResponse response) {
Assert.notNull(storageService, "存储服务未初始化,请检查配置 aliyun.oss.endpoint");
try (InputStream inputStream = storageService.getObjectInputStream(ossConfig.getBucket(), path);
ServletOutputStream outputStream = response.getOutputStream()) {
String fileName = path.substring(path.lastIndexOf("/") + 1);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");
IoUtil.copy(inputStream, outputStream);
} catch (Exception e) {
log.error("下载失败: {}", path, e);
throw new RuntimeException("文件下载失败,请稍后重试");
}
}
private String generateUploadPath(String folder, String extension) {
String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
return String.format("nutri-api/%s/%s/%s.%s", folder, datePath, IdUtil.fastSimpleUUID(), extension);
}
}
package com.infoloop.tianting.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum QueryMealOrderStatusEnum {
BE_BOOKED,UNDER_WAY,COMPLETED
}
......@@ -42,7 +42,26 @@ public enum ErrorCodeEnum implements BaseEnum {
ORDER_NOT_ONLINE_PAY(406000012, "该订单不是在线支付"),
ORDER_NOT_SUCCESS(406000013, "该订单未支付成功")
ORDER_NOT_SUCCESS(406000013, "该订单未支付成功"),
CLIENT_CODE_NOT_EXISTS(406000014, "学校编码不正确"),
DINER_ALREADY_EXISTS(406000015, "该就餐人已存在"),
DINER_ALREADY_RESERVED(406000016, "该就餐人已订餐"),
DINER_NOT_FOUND(406000017, "该就餐人不存在"),
MEAL_MENU_NOT_FOUND(406000018, "预定餐单不存在"),
CLIENT_NOT_FOUND(406000019, "学校不存在"),
CLIENT_NOT_ENABLED(406000020, "学校未启用"),
GRADE_CLASS_NOT_FOUND(406000021, "班级不存在"),
MEAL_ORDER_TIME_NOT_IN_RANGE(406000022, "当前时间不在选餐时间内")
;
private final int code;
......
......@@ -70,6 +70,7 @@ public class LoginInterceptor implements HandlerInterceptor {
StpUtil.checkLogin();
final var enterpriseId = Convert.toInt(StpUtil.getExtra(CommonConstants.ENTERPRISE_ID));
final var loginSource = Convert.toInt(StpUtil.getExtra(CommonConstants.LOGIN_SOURCE));
final var userId = StpUtil.getExtra(CommonConstants.USER_ID);
if (loginSource.equals(LoginSourceEnum.CUSTOMER.getValue())) {
final var openId = Convert.toStr(StpUtil.getExtra(CommonConstants.OPEN_ID));
final var loginId = StpUtil.getLoginIdAsInt();
......@@ -115,8 +116,7 @@ public class LoginInterceptor implements HandlerInterceptor {
builder.id(loginId).enterpriseId(enterpriseId).name(operator.getName()).loginSource(LoginSourceEnum.KDS);
return true;
} else {
final var loginId = StpUtil.getLoginIdAsString();
builder.openId(loginId).enterpriseId(enterpriseId).loginSource(LoginSourceEnum.MINI_PROGRAM);
builder.id(userId == null ? null : Convert.toInt(userId)).openId(StpUtil.getLoginIdAsString()).enterpriseId(enterpriseId).loginSource(LoginSourceEnum.MINI_PROGRAM);
return true;
}
}
......
......@@ -2,6 +2,12 @@ package com.infoloop.tianting.intercepter;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.strategy.SaStrategy;
import cn.hutool.core.convert.Convert;
import com.infoloop.tianting.constant.PathVariableResourceConstants;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -18,6 +24,10 @@ import java.util.Map;
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ResourceInjector implements HandlerInterceptor {
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
@Override
@SuppressWarnings("unchecked")
public boolean preHandle(@NonNull final HttpServletRequest httpServletRequest, @NonNull final HttpServletResponse httpServletResponse, @NonNull final Object handler) {
......@@ -33,6 +43,91 @@ public class ResourceInjector implements HandlerInterceptor {
if (pathVariables == null) {
return true;
}
/*
注入MpAccount
*/
if (pathVariables.containsKey(PathVariableResourceConstants.MP_ACCOUNT_ID_PATH_VARIABLE)) {
final var idStr = pathVariables.get(PathVariableResourceConstants.MP_ACCOUNT_ID_PATH_VARIABLE);
final var id = Convert.toInt(idStr, 0);
if (id <= 0) {
throw ClientEndExceptions.ResourceNotFound.build("小程序用户不存在");
}
final var response = mealOrderServiceRpcClient.getMpAccountById(LoginContextHolder.getEnterpriseId(), id);
if (response == null) {
log.info("Resource not found; id:{}", id);
throw ClientEndExceptions.ResourceNotFound.build("小程序用户不存在");
}
httpServletRequest.setAttribute(PathVariableResourceConstants.INJECTED_MP_ACCOUNT, response);
}
/*
注入Client
*/
if (pathVariables.containsKey(PathVariableResourceConstants.CLIENT_ID_PATH_VARIABLE)) {
final var idStr = pathVariables.get(PathVariableResourceConstants.CLIENT_ID_PATH_VARIABLE);
final var id = Convert.toInt(idStr, 0);
if (id <= 0) {
throw ClientEndExceptions.ResourceNotFound.build("项目点不存在");
}
final var response = clientInventoryServiceRpcClient.getClientById(LoginContextHolder.getEnterpriseId(), id);
if (response == null) {
log.info("Resource not found; id:{}", id);
throw ClientEndExceptions.ResourceNotFound.build("项目点不存在");
}
httpServletRequest.setAttribute(PathVariableResourceConstants.INJECTED_CLIENT, response.getClient());
}
/*
注入Diner
*/
if (pathVariables.containsKey(PathVariableResourceConstants.DINER_ID_PATH_VARIABLE)) {
final var idStr = pathVariables.get(PathVariableResourceConstants.DINER_ID_PATH_VARIABLE);
final var id = Convert.toInt(idStr, 0);
if (id <= 0) {
throw ClientEndExceptions.ResourceNotFound.build("就餐人不存在");
}
final var response = mealOrderServiceRpcClient.getDinerById(LoginContextHolder.getEnterpriseId(), id);
if (response == null) {
log.info("Resource not found; id:{}", id);
throw ClientEndExceptions.ResourceNotFound.build("就餐人不存在");
}
httpServletRequest.setAttribute(PathVariableResourceConstants.INJECTED_DINER, response);
}
/*
注入GradeClass
*/
if (pathVariables.containsKey(PathVariableResourceConstants.GRADE_CLASS_ID_PATH_VARIABLE)) {
final var idStr = pathVariables.get(PathVariableResourceConstants.GRADE_CLASS_ID_PATH_VARIABLE);
final var id = Convert.toInt(idStr, 0);
if (id <= 0) {
throw ClientEndExceptions.ResourceNotFound.build("年级班级不存在");
}
final var response = mealOrderServiceRpcClient.getGradeClassById(LoginContextHolder.getEnterpriseId(), id);
if (response == null) {
log.info("Resource not found; id:{}", id);
throw ClientEndExceptions.ResourceNotFound.build("年级班级不存在");
}
httpServletRequest.setAttribute(PathVariableResourceConstants.INJECTED_GRADE_CLASS, response);
}
/*
注入MealOrder
*/
if (pathVariables.containsKey(PathVariableResourceConstants.MEAL_ORDER_ID_PATH_VARIABLE)) {
final var idStr = pathVariables.get(PathVariableResourceConstants.MEAL_ORDER_ID_PATH_VARIABLE);
final var id = Convert.toInt(idStr, 0);
if (id <= 0) {
throw ClientEndExceptions.ResourceNotFound.build("订餐记录不存在");
}
final var response = mealOrderServiceRpcClient.getMealOrderById(LoginContextHolder.getEnterpriseId(), id);
if (response == null) {
log.info("Resource not found; id:{}", id);
throw ClientEndExceptions.ResourceNotFound.build("订餐记录不存在");
}
httpServletRequest.setAttribute(PathVariableResourceConstants.INJECTED_MEAL_ORDER, response);
}
return true;
}
}
......
......@@ -21,8 +21,8 @@ import com.infoloop.tianting.server.message.data.CustomerAlterRoomNoData;
import com.infoloop.tianting.server.session.UserSessionKey;
import com.infoloop.tianting.server.session.UserTypeEnum;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
......@@ -48,7 +48,7 @@ public class HisCustomerRoomNoTask {
private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
private final InventoryServiceRpcClient inventoryServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final MeiZhongYiHeServiceClient meiZhongYiHeServiceClient;
......@@ -62,7 +62,7 @@ public class HisCustomerRoomNoTask {
final var stallIdsList = clientResourceTagServiceRpcClient.getUserResources(cOperatorById.getEnterpriseId(), cOperatorById.getClientId(), cOperatorById.getId()).getStallIdsList();
final var stalls = inventoryServiceRpcClient.getStallsByIds(cOperatorById.getEnterpriseId(), stallIdsList).getClientsList();
final var stalls = clientInventoryServiceRpcClient.getStallsByIds(cOperatorById.getEnterpriseId(), stallIdsList).getClientsList();
final var queryOrderDto = OrderDbDTO.QueryOrderByConditionDto.builder()
.enterpriseId(loginInfo.getEnterpriseId())
......
package com.infoloop.tianting.logic.task;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.LoginSourceEnum;
import com.infoloop.tianting.mealorderservice.MealOrderCreation;
import com.infoloop.tianting.mealorderservice.MealOrderOrderMethodEnum;
import com.infoloop.tianting.mealorderservice.MenuSchedule;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealMenuRecordRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountDinerRefRpcResponse;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.DeliveryRuleServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.store.WeeklyTaskStore;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Slf4j
@Component
@RequiredArgsConstructor
public class AutoCreateMealOrderTask {
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final DeliveryRuleServiceRpcClient deliveryRuleServiceRpcClient;
private final WeeklyTaskStore weeklyTaskStore;
@Scheduled(cron = "0 * * ? * *")
public void executeTask() {
final int enterpriseId = 449;
final var now = LocalDateTime.now();
final var today = now.toLocalDate();
// 判断是否本周已执行
final var keyPrefix = "create-meal-order-task";
if (weeklyTaskStore.isExecutedThisWeek(keyPrefix, enterpriseId, today)) return;
final var rules = deliveryRuleServiceRpcClient.getDefaultDeliveryTemplateAndRule(enterpriseId).getRule();
if (rules.getConfigJson().getRulesList().isEmpty()) {
return;
}
final var rule = rules.getConfigJson().getRules(0);
final var endTime = LocalTime.parse(rule.getEndTime(), DateUtil.HH_MM_SS);
final var enabledDays = new ArrayList<DayOfWeek>();
if (Boolean.TRUE.equals(rule.getMonday())) enabledDays.add(DayOfWeek.MONDAY);
if (Boolean.TRUE.equals(rule.getTuesday())) enabledDays.add(DayOfWeek.TUESDAY);
if (Boolean.TRUE.equals(rule.getWednesday())) enabledDays.add(DayOfWeek.WEDNESDAY);
if (Boolean.TRUE.equals(rule.getThursday())) enabledDays.add(DayOfWeek.THURSDAY);
if (Boolean.TRUE.equals(rule.getFriday())) enabledDays.add(DayOfWeek.FRIDAY);
if (Boolean.TRUE.equals(rule.getSaturday())) enabledDays.add(DayOfWeek.SATURDAY);
if (Boolean.TRUE.equals(rule.getSunday())) enabledDays.add(DayOfWeek.SUNDAY);
if (enabledDays.isEmpty()) {
return;
}
final var maxDay = Collections.max(enabledDays);
final var endDateTime = getThisWeekDay(today, maxDay).atTime(endTime);
if (now.isBefore(endDateTime)) {
log.info("当前时间小于订餐结束时间:{},跳过自动订餐任务", endDateTime);
return;
}
final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE);
final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE);
final var nextWeekStart = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).atStartOfDay().atZone(DateUtil.CHINA_ZONE);
// 查询本周已订餐学生 ID
final var mealOrders = mealOrderServiceRpcClient.queryMealOrdersByCondition(enterpriseId, null, thisWeekStart.toInstant().toEpochMilli(), thisWeekEnd.toInstant().toEpochMilli());
final var dinerIds = mealOrders.stream().map(SingleMealOrderRpcResponse::getDinerId).sorted(Comparator.comparingInt(Integer::intValue)).collect(Collectors.toCollection(LinkedHashSet::new));
log.info("本周已订餐学生 ID:{}", dinerIds);
// 所有学生 & 未订餐学生
final var allDiners = mealOrderServiceRpcClient.queryDinersByCondition(enterpriseId, null, null, null);
final var notReservedDiners = allDiners.stream().filter(diner -> !dinerIds.contains(diner.getId())).sorted(Comparator.comparingInt(SingleDinerRpcResponse::getId)).toList();
if (notReservedDiners.isEmpty()) {
log.info("无未订餐学生,跳过自动订餐任务");
return;
}
log.info("本周未订餐学生:{}", notReservedDiners.stream().map(SingleDinerRpcResponse::getId).toList());
final var mpAccountDinerRefMap = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(enterpriseId, Collections.emptyList(), notReservedDiners.stream().map(SingleDinerRpcResponse::getId).toList()).stream().collect(Collectors.toMap(SingleMpAccountDinerRefRpcResponse::getDinerId, Function.identity(), (v1, v2) -> v1));
// 所需关联数据查询
final var clientIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList();
final var classIds = notReservedDiners.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList();
final var clientMap = clientInventoryServiceRpcClient.getClientsByIds(enterpriseId, clientIds).getClientsList().stream().collect(Collectors.toMap(SingleClientRpcResponse::getId, Function.identity()));
final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(enterpriseId, classIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity()));
final var latestMealMenuRecordMap = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(enterpriseId, clientIds).stream().collect(Collectors.toMap(SingleMealMenuRecordRpcResponse::getClientId, Function.identity()));
// 构建创建请求
final var creations = notReservedDiners.stream().map(diner -> toMealOrderCreation(diner, clientMap, gradeClassMap, latestMealMenuRecordMap, mpAccountDinerRefMap, nextWeekStart)).filter(Objects::nonNull).toList();
if (creations.isEmpty()) {
log.info("无可创建自动订餐项,跳过任务");
return;
}
final var loginInfo = LoginContextHolder.LoginInfo.builder()
.id(0)
.enterpriseId(enterpriseId)
.loginSource(LoginSourceEnum.MINI_PROGRAM)
.build();
mealOrderServiceRpcClient.batchCreateMealOrders(loginInfo, creations);
log.info("本周未订餐学生已自动补单 {} 条", creations.size());
// 标记本周已执行
weeklyTaskStore.markExecuted(keyPrefix, enterpriseId, today);
}
private MealOrderCreation toMealOrderCreation(SingleDinerRpcResponse diner,
Map<Integer, SingleClientRpcResponse> clientMap,
Map<Integer, SingleGradeClassRpcResponse> classMap,
Map<Integer, SingleMealMenuRecordRpcResponse> menuMap,
Map<Integer, SingleMpAccountDinerRefRpcResponse> mpAccountDinerRefMap,
ZonedDateTime startOfNextWeek) {
final var menu = menuMap.get(diner.getClientId());
final var client = clientMap.get(diner.getClientId());
final var gradeClass = classMap.get(diner.getClassId());
final var mpAccountDinerRef = mpAccountDinerRefMap.get(diner.getId());
if (menu == null || client == null || gradeClass == null || mpAccountDinerRef == null) return null;
return MealOrderCreation.newBuilder()
.setClientId(diner.getClientId())
.setMenuId(menu.getId())
.setAccountId(mpAccountDinerRef.getAccountId())
.setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_SYSTEM)
.setDinerId(diner.getId())
.setDinerName(diner.getName())
.setClientName(client.getName())
.setGradeName(gradeClass.getGradeName())
.setClassName(gradeClass.getClassName())
.setStudentNo(diner.getStudentNo())
.setReserveDate(Instant.now().toEpochMilli())
.addAllMeals(buildNextWeekMeals(startOfNextWeek))
.build();
}
private LocalDate getThisWeekDay(LocalDate now, DayOfWeek target) {
LocalDate monday = now.with(DayOfWeek.MONDAY);
return monday.plusDays(target.getValue() - 1L);
}
private List<MenuSchedule> buildNextWeekMeals(ZonedDateTime nextWeekStart) {
return IntStream.range(0, 5)
.mapToObj(i -> MenuSchedule.newBuilder()
.setDate(nextWeekStart.plusDays(i).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL))
.setMenu("A")
.build())
.toList();
}
}
......@@ -10,7 +10,7 @@ import java.util.List;
@Data
@ApiModel(description = "院区DTO")
public class InventoryDbDTO {
public class ClientInventoryDbDTO {
@Data
@Builder
......@@ -30,7 +30,7 @@ public class InventoryDbDTO {
private Integer allowedPaid;
private Integer regionId;
private ClientType type;
CustomerSource customerSource;
private CustomerSource customerSource;
private boolean isDelivery;
}
......
package com.infoloop.tianting.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(description = "就餐人DTO")
public class DinerDTO {
@Data
@ApiModel(description = "查询唯一就餐人")
public static class QueryUniqueDinerDTO {
@ApiModelProperty(value = "学号")
@NotEmpty(message = "学号不能为空")
private String studentNo;
}
@Data
@ApiModel(description = "添加就餐人")
public static class CreateDinerDTO {
@ApiModelProperty(value = "学校编码")
@NotEmpty(message = "学校编码不能为空")
private String clientCode;
@ApiModelProperty(value = "班级")
@NotNull(message = "班级不能为空")
private Integer classId;
@ApiModelProperty(value = "学号")
@NotEmpty(message = "学号不能为空")
private String studentNo;
@ApiModelProperty(value = "姓名")
@NotEmpty(message = "姓名不能为空")
private String name;
}
@Data
@ApiModel(description = "修改就餐人")
public static class UpdateDinerDTO {
@ApiModelProperty(value = "学校编码")
@NotEmpty(message = "学校编码不能为空")
private String clientCode;
@ApiModelProperty(value = "班级")
@NotNull(message = "班级不能为空")
private Integer classId;
@ApiModelProperty(value = "学号")
private String studentNo;
@ApiModelProperty(value = "姓名")
private String name;
}
}
......@@ -2,7 +2,7 @@ package com.infoloop.tianting.model.dto;
import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerDetailDto;
import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerNotice;
import io.swagger.annotations.ApiModel;
......
package com.infoloop.tianting.model.dto;
import com.infoloop.tianting.annotation.RequestKeyParam;
import com.infoloop.tianting.enums.QueryMealOrderStatusEnum;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@ApiModel(description = "订餐DTO")
public class MealOrderDTO {
@Data
@ApiModel(description = "查询订餐记录")
public static class QueryMealOrderDTO {
@NotNull(message = "status不能为空")
private QueryMealOrderStatusEnum status;
}
@Data
@ApiModel(description = "创建订餐记录")
public static class CreateMealOrderDTO {
@NotNull(message = "就餐人 ID 不能为空")
@RequestKeyParam
private Integer dinerId;
@NotEmpty(message = "订餐详情不能为空")
@NotNull(message = "订餐详情不能为空")
@Valid
private List<CreateMeals> meals;
}
@Data
@ApiModel(description = "创建订餐记录详情")
public static class CreateMeals {
@NotEmpty(message = "日期不能为空")
private String date;
@NotEmpty(message = "菜单不能为空")
private String menu;
}
}
package com.infoloop.tianting.model.dto;
import com.infoloop.tianting.mealorderservice.MpAccountGenderEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "小程序用户DTO")
public class MpAccountDTO {
@Data
@ApiModel(description = "修改小程序用户")
public static class ModifyMpAccountDTO {
@ApiModelProperty(value = "昵称")
private String nickName;
@ApiModelProperty(value = "头像")
private String avatarUrl;
@ApiModelProperty(value = "性别")
private MpAccountGenderEnum gender;
}
}
......@@ -27,6 +27,10 @@ public class PermissionDTO {
@Builder.Default
private String openCode = "";
@Builder.Default
private boolean shouldLoginWithOpenId = false;
@Builder.Default
private String openId = "";
@Builder.Default
private boolean shouldLoginWithKdsEmail = false;
@Builder.Default
private String email = "";
......
package com.infoloop.tianting.model.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
@Data
@ApiModel(value = "订餐规则")
@Builder
public class DeliveryRuleVO {
@ApiModelProperty(value = "订餐开始时间")
private String startTime;
@ApiModelProperty(value = "订餐结束时间")
private String endTime;
private Boolean monday;
private Boolean tuesday;
private Boolean wednesday;
private Boolean thursday;
private Boolean friday;
private Boolean saturday;
private Boolean sunday;
}
package com.infoloop.tianting.model.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
@Data
@ApiModel(value = "就餐人信息")
@Builder
public class DinerVO {
@ApiModelProperty(value = "就餐人 ID")
private int id;
@ApiModelProperty(value = "企业 ID")
private int enterpriseId;
@ApiModelProperty(value = "就餐人学校 ID")
private int clientId;
@ApiModelProperty(value = "就餐人学校代码")
private String clientCode;
@ApiModelProperty(value = "就餐人学校名称")
private String clientName;
@ApiModelProperty(value = "就餐人班级 ID")
private int classId;
@ApiModelProperty(value = "就餐人年级名称")
private String gradeName;
@ApiModelProperty(value = "就餐人班级名称")
private String className;
@ApiModelProperty(value = "就餐人学号")
private String studentNo;
@ApiModelProperty(value = "就餐人姓名")
private String name;
@ApiModelProperty(value = "是否已预定")
private boolean isReserve;
}
package com.infoloop.tianting.model.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
@Data
@ApiModel(value = "班级年级信息")
@Builder
public class GradeClassVO {
@ApiModelProperty("ID")
private Integer id;
@ApiModelProperty("企业 ID")
private Integer enterpriseId;
@ApiModelProperty("年级")
private String gradeName;
@ApiModelProperty("班级")
private String className;
}
package com.infoloop.tianting.model.vo;
import com.infoloop.tianting.mealorderservice.MealOrderOrderMethodEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
@ApiModel(value = "订餐记录信息")
public class MealOrderVO {
@ApiModelProperty("ID")
private int id;
@ApiModelProperty("项目点ID")
private int clientId;
@ApiModelProperty("餐单ID")
private int menuId;
@ApiModelProperty("用户ID")
private int accountId;
@ApiModelProperty("订餐方式")
private MealOrderOrderMethodEnum orderMethod;
@ApiModelProperty("就餐人 id")
private int dinerId;
@ApiModelProperty("就餐人名称")
private String dinerName;
@ApiModelProperty("项目点名称")
private String clientName;
@ApiModelProperty("年级名称")
private String gradeName;
@ApiModelProperty("班级名称")
private String className;
@ApiModelProperty("学生学号")
private String studentNo;
@ApiModelProperty("订餐时间")
private String reserveDate;
@ApiModelProperty("订餐餐单")
private List<Meals> meals;
@Data
@Builder
@ApiModel(description = "订餐信息")
public static class Meals {
@ApiModelProperty("订餐日期")
private String date;
@ApiModelProperty("订餐餐单")
private String menu;
}
}
package com.infoloop.tianting.model.vo;
import com.infoloop.tianting.mealorderservice.MpAccountGenderEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
@Data
@ApiModel(value = "小程序账号信息")
@Builder
public class MpAccountVO {
@ApiModelProperty("ID")
private Integer id;
@ApiModelProperty("企业 ID")
private Integer enterpriseId;
@ApiModelProperty("openId")
private String openId;
@ApiModelProperty("unionId")
private String unionId;
@ApiModelProperty("昵称")
private String nickname;
@ApiModelProperty("头像地址")
private String avatarUrl;
@ApiModelProperty("性别")
private MpAccountGenderEnum gender;
@ApiModelProperty("手机号")
private String phoneNumber;
}
package com.infoloop.tianting.server;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
public class OssStorageService implements StorageService{
private final OSS ossClient;
public OssStorageService(String endpoint, String accessKeyId, String accessKeySecret) {
this.ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
@Override
public void putObject(String bucketName, String key, byte[] data) {
ossClient.putObject(bucketName, key, new ByteArrayInputStream(data));
}
@Override
public void putObject(String bucketName, String key, File file) {
ossClient.putObject(bucketName, key, file);
}
@Override
public void putObject(String bucketName, String key, InputStream stream) {
ossClient.putObject(bucketName, key, stream);
}
@Override
public InputStream getObjectInputStream(String bucketName, String key) {
return ossClient.getObject(new GetObjectRequest(bucketName, key)).getObjectContent();
}
@Override
public void close() throws Exception {
ossClient.shutdown();
}
}
package com.infoloop.tianting.server;
import java.io.File;
import java.io.InputStream;
public interface StorageService extends AutoCloseable {
void putObject(String bucketName, String key, byte[] data) throws Exception;
void putObject(String bucketName, String key, File file) throws Exception;
void putObject(String bucketName, String key, InputStream stream) throws Exception;
InputStream getObjectInputStream(String bucketName, String key);
}
\ No newline at end of file
package com.infoloop.tianting.server;
public class StorageServiceFactory {
public static StorageService createStorageService(String endpoint, String accessKey, String accessSecret) {
if (endpoint.contains("aliyuncs.com")) {
return new OssStorageService(endpoint, accessKey, accessSecret);
} else {
throw new IllegalArgumentException("Unsupported storage type: " + endpoint);
}
}
}
\ No newline at end of file
package com.infoloop.tianting.service;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.TableCodeQueryConditionDto;
import java.util.List;
public interface ClientInventoryService {
ClientDto getClientById(Integer enterpriseId, Integer clientId);
List<ClientDto> getStallsByClientId(Integer enterpriseId, Integer clientId);
List<ClientTableCodeDto> queryClientTableCodesByCondition(TableCodeQueryConditionDto tableCodeQueryConditionDto);
List<ClientDto> getClientsByCodes(List<String> codes);
}
package com.infoloop.tianting.service;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.DinerDTO;
import com.infoloop.tianting.model.vo.DinerVO;
import com.infoloop.tianting.model.vo.GradeClassVO;
import java.util.List;
public interface DinerService {
List<DinerVO> getMpAccountDiners();
CreatedResult<DinerVO> createMpAccountDiner(DinerDTO.CreateDinerDTO createDinerDTO);
List<GradeClassVO> getClientGradeClasses(SingleClientRpcResponse client);
void updateMpAccountDiner(SingleDinerRpcResponse diner, DinerDTO.UpdateDinerDTO updateDinerDTO);
void deleteMpAccountDiner(SingleDinerRpcResponse diner);
DinerVO getClientClassDiner(SingleClientRpcResponse client, SingleGradeClassRpcResponse gradeClass, String studentNo);
}
package com.infoloop.tianting.service;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.TableCodeQueryConditionDto;
import java.util.List;
public interface InventoryService {
ClientDto getClientById(Integer enterpriseId, Integer clientId);
List<ClientDto> getStallsByClientId(Integer enterpriseId, Integer clientId);
List<ClientTableCodeDto> queryClientTableCodesByCondition(
TableCodeQueryConditionDto tableCodeQueryConditionDto);
}
package com.infoloop.tianting.service;
import cn.dev33.satoken.stp.SaTokenInfo;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.model.dto.MpAccountDTO;
import com.infoloop.tianting.model.dto.PermissionDTO.LoginDto;
import com.infoloop.tianting.model.vo.MpAccountVO;
import java.security.NoSuchAlgorithmException;
public interface LoginService {
SaTokenInfo login(LoginDto loginDto) throws NoSuchAlgorithmException;
MpAccountVO getMpAccountByOpenId(String openId);
void updateMpAccount(SingleMpAccountRpcResponse mpAccount, MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO);
}
......
package com.infoloop.tianting.service;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.MealOrderDTO;
import com.infoloop.tianting.model.vo.DeliveryRuleVO;
import com.infoloop.tianting.model.vo.MealOrderVO;
import java.util.List;
public interface MealOrderService {
List<MealOrderVO> queryMealOrders(MealOrderDTO.QueryMealOrderDTO queryMealOrderDTO);
CreatedResult<MealOrderVO> createMealOrder(MealOrderDTO.CreateMealOrderDTO createMealOrderDTO);
MealOrderVO getMealOrderById(SingleMealOrderRpcResponse mealOrder);
DeliveryRuleVO getDeliveryRule();
}
package com.infoloop.tianting.service;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsDto;
import com.infoloop.tianting.model.dto.MenuDbDTO.BatchCreateMenuRefsResponseDto;
import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDetailDto;
......@@ -24,4 +25,6 @@ public interface MenuService {
BatchCreateMenuRefsResponseDto batchCreateMenuRefs(BatchCreateMenuRefsDto batchCreateMenuRefsDto);
List<Integer> queryMenuSkuIdsByStallId(int enterpriseId, int stallId);
String queryClientLatestMealMenuRecord(SingleClientRpcResponse client);
}
......
......@@ -2,6 +2,7 @@ package com.infoloop.tianting.service.client;
import com.infoloop.tianting.clientinventoryservice.GetClientByIdRpcRequest;
import com.infoloop.tianting.clientinventoryservice.GetClientByIdRpcResponse;
import com.infoloop.tianting.clientinventoryservice.GetClientsByCodesRpcRequest;
import com.infoloop.tianting.clientinventoryservice.GetClientsByIdsRpcRequest;
import com.infoloop.tianting.clientinventoryservice.GetClientsByIdsRpcResponse;
import com.infoloop.tianting.clientinventoryservice.GetStallsByClientIdRpcRequest;
......@@ -10,8 +11,9 @@ import com.infoloop.tianting.clientinventoryservice.GetStallsByIdsRpcRequest;
import com.infoloop.tianting.clientinventoryservice.GetStallsByIdsRpcResponse;
import com.infoloop.tianting.clientinventoryservice.QueryClientTableCodesByConditionRpcRequest;
import com.infoloop.tianting.clientinventoryservice.QueryClientTableCodesByConditionRpcResponse;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.clientinventoryservice.TiantingClientInventoryServiceRpcGrpc;
import com.infoloop.tianting.model.dto.InventoryDbDTO.TableCodeQueryConditionDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.TableCodeQueryConditionDto;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -20,7 +22,7 @@ import java.util.List;
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryServiceRpcClient {
public class ClientInventoryServiceRpcClient {
private final TiantingClientInventoryServiceRpcGrpc.TiantingClientInventoryServiceRpcBlockingStub
inventoryServiceRpcBlockingStub;
......@@ -43,6 +45,15 @@ public class InventoryServiceRpcClient {
return inventoryServiceRpcBlockingStub.getClientsByIds(request);
}
public List<SingleClientRpcResponse> getClientsByCodes(Integer enterpriseId, List<String> codes) {
final var request = GetClientsByCodesRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllCodes(codes)
.setIncludeDeleted(false)
.build();
return inventoryServiceRpcBlockingStub.getClientsByCodes(request).getClientsList();
}
public GetStallsByIdsRpcResponse getStallsByIds(Integer enterpriseId, List<Integer> stallIds) {
final var request = GetStallsByIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
......
package com.infoloop.tianting.service.client;
import com.infoloop.tianting.deliveryruleservice.DeliveryTemplateTypeEnum;
import com.infoloop.tianting.deliveryruleservice.GetClientLabelsByIdsRpcRequest;
import com.infoloop.tianting.deliveryruleservice.GetClientLabelsByIdsRpcResponse;
import com.infoloop.tianting.deliveryruleservice.GetDefaultDeliveryTemplateAndRuleRpcRequest;
import com.infoloop.tianting.deliveryruleservice.GetDefaultDeliveryTemplateAndRuleRpcResponse;
import com.infoloop.tianting.deliveryruleservice.QueryClientLabelsByConditionRpcRequest;
import com.infoloop.tianting.deliveryruleservice.QueryClientLabelsByConditionRpcResponse;
import com.infoloop.tianting.deliveryruleservice.TiantingDeliveryRuleServiceRpcGrpc;
......@@ -40,5 +43,14 @@ public class DeliveryRuleServiceRpcClient {
return deliveryRuleServiceRpcBlockingStub.getClientLabelsByIds(request);
}
public GetDefaultDeliveryTemplateAndRuleRpcResponse getDefaultDeliveryTemplateAndRule(int enterpriseId) {
final var request = GetDefaultDeliveryTemplateAndRuleRpcRequest
.newBuilder()
.setEnterpriseId(enterpriseId)
.setType(DeliveryTemplateTypeEnum.DELIVERY_TEMPLATE_TYPE_DELIVERY)
.build();
return deliveryRuleServiceRpcBlockingStub.getDefaultDeliveryTemplateAndRule(request);
}
}
......
package com.infoloop.tianting.service.client;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.LoginSourceEnum;
import com.infoloop.tianting.mealorderservice.BatchCreateMealOrdersRpcRequest;
import com.infoloop.tianting.mealorderservice.BatchCreateMealOrdersRpcResponse;
import com.infoloop.tianting.mealorderservice.CreateDinerRpcRequest;
import com.infoloop.tianting.mealorderservice.CreateDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.CreateMealOrderRpcRequest;
import com.infoloop.tianting.mealorderservice.CreateMealOrderRpcResponse;
import com.infoloop.tianting.mealorderservice.CreateMpAccountDinerRefRpcRequest;
import com.infoloop.tianting.mealorderservice.CreateMpAccountDinerRefRpcResponse;
import com.infoloop.tianting.mealorderservice.CreateMpAccountRpcRequest;
import com.infoloop.tianting.mealorderservice.CreateMpAccountRpcResponse;
import com.infoloop.tianting.mealorderservice.DeleteDinersByIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.DeleteMpAccountDinerRefsByIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.DinerCreation;
import com.infoloop.tianting.mealorderservice.DinerModification;
import com.infoloop.tianting.mealorderservice.GetDinerByIdRpcRequest;
import com.infoloop.tianting.mealorderservice.GetDinerByIdRpcResponse;
import com.infoloop.tianting.mealorderservice.GetDinersByIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.GetGradeClassByIdRpcRequest;
import com.infoloop.tianting.mealorderservice.GetGradeClassesByIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.GetMealOrderByIdRpcRequest;
import com.infoloop.tianting.mealorderservice.GetMpAccountByIdRpcRequest;
import com.infoloop.tianting.mealorderservice.GetMpAccountByIdRpcResponse;
import com.infoloop.tianting.mealorderservice.GetMpAccountByOpenIdRpcRequest;
import com.infoloop.tianting.mealorderservice.GetMpAccountByOpenIdRpcResponse;
import com.infoloop.tianting.mealorderservice.MealOrderCreation;
import com.infoloop.tianting.mealorderservice.MealOrderServiceRpcGrpc;
import com.infoloop.tianting.mealorderservice.MpAccountCreation;
import com.infoloop.tianting.mealorderservice.MpAccountDinerRefCreation;
import com.infoloop.tianting.mealorderservice.MpAccountModification;
import com.infoloop.tianting.mealorderservice.QueryDinersByConditionRpcRequest;
import com.infoloop.tianting.mealorderservice.QueryGradeClassesByConditionRpcRequest;
import com.infoloop.tianting.mealorderservice.QueryLatestMealMenuRecordsByClientIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.QueryMealOrdersByConditionRpcRequest;
import com.infoloop.tianting.mealorderservice.QueryMpAccountDinerRefsByConditionRpcRequest;
import com.infoloop.tianting.mealorderservice.QueryReserveMealOrdersByDinerIdsRpcRequest;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealMenuRecordRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountDinerRefRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.mealorderservice.UpdateDinerRpcRequest;
import com.infoloop.tianting.mealorderservice.UpdateDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.UpdateMpAccountRpcRequest;
import com.infoloop.tianting.mealorderservice.UpdateMpAccountRpcResponse;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MealOrderServiceRpcClient {
private final MealOrderServiceRpcGrpc.MealOrderServiceRpcBlockingStub mealOrderServiceRpcBlockingStub;
@Nullable
public SingleMpAccountRpcResponse getMpAccountByOpenId(String openId) {
final GetMpAccountByOpenIdRpcResponse mpAccountByOpenId = mealOrderServiceRpcBlockingStub.getMpAccountByOpenId(GetMpAccountByOpenIdRpcRequest.newBuilder().setOpenId(openId).build());
if (!mpAccountByOpenId.hasResponse()) {
return null;
}
return mpAccountByOpenId.getResponse();
}
public CreateMpAccountRpcResponse createMpAccount(int enterpriseId, MpAccountCreation mpAccountCreation) {
return mealOrderServiceRpcBlockingStub.createMpAccount(CreateMpAccountRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setCreatedBy(0)
.setCreationSource(LoginSourceEnum.MINI_PROGRAM.getValue())
.setCreation(mpAccountCreation)
.build());
}
@Nullable
public SingleMpAccountRpcResponse getMpAccountById(Integer enterpriseId, Integer id) {
final GetMpAccountByIdRpcResponse mpAccountById = mealOrderServiceRpcBlockingStub.getMpAccountById(GetMpAccountByIdRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setId(id)
.build());
if (!mpAccountById.hasResponse()) {
return null;
}
return mpAccountById.getResponse();
}
public UpdateMpAccountRpcResponse updateMpAccount(LoginContextHolder.LoginInfo loginInfo, MpAccountModification mpAccountModification) {
return mealOrderServiceRpcBlockingStub.updateMpAccount(UpdateMpAccountRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setUpdatedBy(loginInfo.getId())
.setUpdateSource(loginInfo.getLoginSource().getValue())
.setModification(mpAccountModification)
.build());
}
public List<SingleMpAccountDinerRefRpcResponse> queryMpAccountDinerRefsByCondition(int enterpriseId, List<Integer> mpAccountIds, List<Integer> dinerIds) {
return mealOrderServiceRpcBlockingStub.queryMpAccountDinerRefsByCondition(QueryMpAccountDinerRefsByConditionRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setShouldFilterAccountIds(!mpAccountIds.isEmpty()).addAllAccountIds(mpAccountIds)
.setShouldFilterDinerIds(!dinerIds.isEmpty()).addAllDinerIds(dinerIds)
.build()).getResponsesList();
}
@Nullable
public SingleDinerRpcResponse getDinerById(int enterpriseId, int dinerId) {
final GetDinerByIdRpcResponse dinerById = mealOrderServiceRpcBlockingStub.getDinerById(GetDinerByIdRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setId(dinerId)
.build());
if (!dinerById.hasResponse()) {
return null;
}
return dinerById.getResponse();
}
public List<SingleDinerRpcResponse> getDinersByIds(int enterpriseId, List<Integer> dinerIds) {
if (CollectionUtils.isEmpty(dinerIds)) {
return Collections.emptyList();
}
return mealOrderServiceRpcBlockingStub.getDinersByIds(GetDinersByIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllIds(dinerIds)
.build()).getResponsesList();
}
public List<SingleDinerRpcResponse> queryDinersByCondition(int enterpriseId, List<Integer> clientIds, List<Integer> gradeClassIds, @Nullable String studentNo) {
return mealOrderServiceRpcBlockingStub.queryDinersByCondition(QueryDinersByConditionRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setShouldFilterClientIds(CollectionUtils.isNotEmpty(clientIds)).addAllClientIds(CollectionUtils.isEmpty(clientIds) ? Collections.emptyList() : clientIds)
.setShouldFilterClassIds(CollectionUtils.isNotEmpty(gradeClassIds)).addAllClassIds(CollectionUtils.isNotEmpty(gradeClassIds) ? gradeClassIds : Collections.emptyList())
.setShouldFilterStudentNo(StringUtils.isNotEmpty(studentNo)).setStudentNo(StringUtils.isNotEmpty(studentNo) ? studentNo : "")
.build()).getResponsesList();
}
public boolean deleteDinersByIds(LoginContextHolder.LoginInfo loginInfo, List<Integer> ids) {
return mealOrderServiceRpcBlockingStub.deleteDinersByIds(DeleteDinersByIdsRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.addAllIds(ids)
.setUpdatedBy(loginInfo.getId())
.setUpdateSource(loginInfo.getLoginSource().getValue())
.build()).getIsDeleted();
}
public List<SingleGradeClassRpcResponse> getGradeClassesByIds(int enterpriseId, List<Integer> gradeClassIds) {
if (CollectionUtils.isEmpty(gradeClassIds)) {
return Collections.emptyList();
}
return mealOrderServiceRpcBlockingStub.getGradeClassesByIds(GetGradeClassesByIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllIds(gradeClassIds)
.build()).getResponsesList();
}
@Nullable
public SingleGradeClassRpcResponse getGradeClassById(int enterpriseId, int id) {
final var response = mealOrderServiceRpcBlockingStub.getGradeClassById(GetGradeClassByIdRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setId(id)
.build());
if (!response.hasResponse()) {
return null;
}
return response.getResponse();
}
public List<SingleMealOrderRpcResponse> queryReserveMealOrdersByDinerIds(int enterpriseId, List<Integer> dinerIds) {
if (CollectionUtils.isEmpty(dinerIds)) {
return Collections.emptyList();
}
return mealOrderServiceRpcBlockingStub.queryReserveMealOrdersByDinerIds(QueryReserveMealOrdersByDinerIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllDinerIds(dinerIds)
.build()).getResponsesList();
}
public CreateDinerRpcResponse createDiner(LoginContextHolder.LoginInfo loginInfo, DinerCreation dinerCreation) {
return mealOrderServiceRpcBlockingStub.createDiner(CreateDinerRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setCreatedBy(loginInfo.getId())
.setCreationSource(loginInfo.getLoginSource().getValue())
.setCreation(dinerCreation)
.build());
}
public UpdateDinerRpcResponse updateDiner(LoginContextHolder.LoginInfo loginInfo, DinerModification dinerModification) {
return mealOrderServiceRpcBlockingStub.updateDiner(UpdateDinerRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setUpdatedBy(loginInfo.getId())
.setUpdateSource(loginInfo.getLoginSource().getValue())
.setModification(dinerModification)
.build());
}
public CreateMpAccountDinerRefRpcResponse createMpAccountDinerRef(LoginContextHolder.LoginInfo loginInfo, MpAccountDinerRefCreation dinerCreation) {
return mealOrderServiceRpcBlockingStub.createMpAccountDinerRef(CreateMpAccountDinerRefRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setCreatedBy(loginInfo.getId())
.setCreationSource(loginInfo.getLoginSource().getValue())
.setCreation(dinerCreation)
.build());
}
public boolean deleteMpAccountDinerRefsByIds(int enterpriseId, List<Integer> ids) {
if (CollectionUtils.isEmpty(ids)) {
return false;
}
return mealOrderServiceRpcBlockingStub.deleteMpAccountDinerRefsByIds(DeleteMpAccountDinerRefsByIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllIds(ids)
.build()).getIsDeleted();
}
public List<SingleGradeClassRpcResponse> queryGradeClassesByCondition(int enterpriseId, List<Integer> clientIds) {
return mealOrderServiceRpcBlockingStub.queryGradeClassesByCondition(QueryGradeClassesByConditionRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setShouldFilterClientIds(!clientIds.isEmpty()).addAllClientIds(clientIds)
.build()).getResponsesList();
}
public List<SingleMealMenuRecordRpcResponse> queryLatestMealMenuRecordsByClientIds(int enterpriseId, List<Integer> ids) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyList();
}
return mealOrderServiceRpcBlockingStub.queryLatestMealMenuRecordsByClientIds(QueryLatestMealMenuRecordsByClientIdsRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.addAllClientId(ids)
.build()).getResponsesList();
}
@Nullable
public SingleMealOrderRpcResponse getMealOrderById(int enterpriseId, int id) {
final var mealOrderById = mealOrderServiceRpcBlockingStub.getMealOrderById(GetMealOrderByIdRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setId(id)
.build());
if (!mealOrderById.hasResponse()) {
return null;
}
return mealOrderById.getResponse();
}
public CreateMealOrderRpcResponse createMealOrder(LoginContextHolder.LoginInfo loginInfo, MealOrderCreation mealOrderCreation) {
return mealOrderServiceRpcBlockingStub.createMealOrder(CreateMealOrderRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setCreatedBy(loginInfo.getId())
.setCreationSource(loginInfo.getLoginSource().getValue())
.setCreation(mealOrderCreation)
.build());
}
public BatchCreateMealOrdersRpcResponse batchCreateMealOrders(LoginContextHolder.LoginInfo loginInfo, List<MealOrderCreation> mealOrderCreations) {
return mealOrderServiceRpcBlockingStub.batchCreateMealOrders(BatchCreateMealOrdersRpcRequest.newBuilder()
.setEnterpriseId(loginInfo.getEnterpriseId())
.setCreatedBy(loginInfo.getId())
.setCreationSource(loginInfo.getLoginSource().getValue())
.addAllCreations(mealOrderCreations)
.build());
}
public List<SingleMealOrderRpcResponse> queryMealOrdersByCondition(int enterpriseId, List<Integer> accountIds, Long reserveDateStart, Long reserveDateEnd) {
return mealOrderServiceRpcBlockingStub.queryMealOrdersByCondition(QueryMealOrdersByConditionRpcRequest.newBuilder()
.setEnterpriseId(enterpriseId)
.setShouldFilterAccountIds(CollectionUtils.isNotEmpty(accountIds)).addAllAccountIds(CollectionUtils.isNotEmpty(accountIds) ? accountIds : Collections.emptyList())
.setShouldFilterReserveDateStart(reserveDateStart != null).setReserveDateStart(reserveDateStart == null ? 0 : reserveDateStart)
.setShouldFilterReserveDateEnd(reserveDateEnd != null).setReserveDateEnd(reserveDateEnd == null ? 0 : reserveDateEnd)
.build()).getResponsesList();
}
}
package com.infoloop.tianting.service.impl;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.InventoryDbDTO.TableCodeQueryConditionDto;
import com.infoloop.tianting.service.InventoryService;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientTableCodeDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.TableCodeQueryConditionDto;
import com.infoloop.tianting.service.ClientInventoryService;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
......@@ -17,13 +18,13 @@ import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryServiceImpl implements InventoryService {
public class ClientClientInventoryServiceImpl implements ClientInventoryService {
private final InventoryServiceRpcClient inventoryServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
@Override
public ClientDto getClientById(Integer enterpriseId, Integer clientId) {
final var response = inventoryServiceRpcClient.getClientById(enterpriseId, clientId);
final var response = clientInventoryServiceRpcClient.getClientById(enterpriseId, clientId);
return ClientDto.builder()
.id(response.getClient().getId())
.address(response.getClient().getAddress())
......@@ -46,7 +47,7 @@ public class InventoryServiceImpl implements InventoryService {
@Override
public List<ClientDto> getStallsByClientId(Integer enterpriseId, Integer clientId) {
final var response = inventoryServiceRpcClient.getStallsByClientId(enterpriseId, clientId);
final var response = clientInventoryServiceRpcClient.getStallsByClientId(enterpriseId, clientId);
return response.getStallsList().stream().map(stall ->
ClientDto.builder()
.id(stall.getId())
......@@ -69,7 +70,7 @@ public class InventoryServiceImpl implements InventoryService {
@Override
public List<ClientTableCodeDto> queryClientTableCodesByCondition(TableCodeQueryConditionDto tableCodeQueryConditionDto) {
final var response = inventoryServiceRpcClient.queryClientTableCodesByCondition(tableCodeQueryConditionDto);
final var response = clientInventoryServiceRpcClient.queryClientTableCodesByCondition(tableCodeQueryConditionDto);
return response.getResponsesList().stream().map(tableCode ->
ClientTableCodeDto.builder()
.id(tableCode.getId())
......@@ -87,4 +88,28 @@ public class InventoryServiceImpl implements InventoryService {
.updateSource(tableCode.getUpdateSource())
.build()).collect(Collectors.toList());
}
@Override
public List<ClientDto> getClientsByCodes(List<String> codes) {
final var response = clientInventoryServiceRpcClient.getClientsByCodes(LoginContextHolder.getEnterpriseId(), codes);
return response.stream().map(client ->
ClientDto.builder()
.id(client.getId())
.address(client.getAddress())
.area(client.getArea())
.province(client.getProvince())
.city(client.getCity())
.code(client.getCode())
.customerSource(client.getCustomerSource())
.enterpriseId(client.getEnterpriseId())
.operatorName(client.getOperatorName())
.parentId(client.getParentId())
.status(client.getStatus())
.regionId(client.getRegionId())
.type(client.getType())
.name(client.getName())
.isDelivery(client.getIsDelivery())
.build()).collect(Collectors.toList());
}
}
......
package com.infoloop.tianting.service.impl;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.DinerCreation;
import com.infoloop.tianting.mealorderservice.DinerModification;
import com.infoloop.tianting.mealorderservice.MpAccountDinerRefCreation;
import com.infoloop.tianting.mealorderservice.SingleDinerRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleGradeClassRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.mealorderservice.SingleMpAccountDinerRefRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.DinerDTO;
import com.infoloop.tianting.model.vo.DinerVO;
import com.infoloop.tianting.model.vo.GradeClassVO;
import com.infoloop.tianting.service.DinerService;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DinerServiceImpl implements DinerService {
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
@Override
public List<DinerVO> getMpAccountDiners() {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var mpAccountDinerRefRpcResponseList = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId()), Collections.emptyList());
final var dinerIds = mpAccountDinerRefRpcResponseList.stream().map(SingleMpAccountDinerRefRpcResponse::getDinerId).toList();
if (dinerIds.isEmpty()) {
return Collections.emptyList();
}
final var dinersByIds = mealOrderServiceRpcClient.getDinersByIds(loginInfo.getEnterpriseId(), dinerIds);
final var clientIds = dinersByIds.stream().map(SingleDinerRpcResponse::getClientId).distinct().toList();
final var gradeClassIds = dinersByIds.stream().map(SingleDinerRpcResponse::getClassId).distinct().toList();
final var clientMap = clientInventoryServiceRpcClient.getClientsByIds(loginInfo.getEnterpriseId(), clientIds).getClientsList().stream().collect(Collectors.toMap(SingleClientRpcResponse::getId, Function.identity()));
final var gradeClassMap = mealOrderServiceRpcClient.getGradeClassesByIds(loginInfo.getEnterpriseId(), gradeClassIds).stream().collect(Collectors.toMap(SingleGradeClassRpcResponse::getId, Function.identity()));
final var reserveDinerMealOrderMap = mealOrderServiceRpcClient.queryReserveMealOrdersByDinerIds(loginInfo.getEnterpriseId(), dinerIds).stream().collect(Collectors.toMap(SingleMealOrderRpcResponse::getDinerId, Function.identity()));
return dinersByIds.stream().map(e -> DinerVO.builder()
.id(e.getId())
.enterpriseId(e.getEnterpriseId())
.clientId(e.getClientId())
.clientCode(clientMap.get(e.getClientId()).getCode())
.clientName(clientMap.get(e.getClientId()).getName())
.classId(e.getClassId())
.gradeName(gradeClassMap.get(e.getClassId()).getGradeName())
.className(gradeClassMap.get(e.getClassId()).getClassName())
.isReserve(reserveDinerMealOrderMap.get(e.getId()) != null)
.studentNo(e.getStudentNo())
.name(e.getName())
.build()).toList();
}
@Override
public CreatedResult<DinerVO> createMpAccountDiner(DinerDTO.CreateDinerDTO createDinerDTO) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var clientsByCodes = clientInventoryServiceRpcClient.getClientsByCodes(loginInfo.getEnterpriseId(), List.of(createDinerDTO.getClientCode()));
if (clientsByCodes.size() != 1) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_CODE_NOT_EXISTS);
}
final var singleClientRpcResponse = clientsByCodes.get(0);
final var diners = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(singleClientRpcResponse.getId()), List.of(createDinerDTO.getClassId()), createDinerDTO.getStudentNo());
if (!diners.isEmpty()) {
final int dinerId = diners.get(0).getId();
final var mpAccountDinerRefs = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId()), List.of(dinerId));
if (!mpAccountDinerRefs.isEmpty()) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_EXISTS);
} else {
final var mpAccountDinerRefCreation = MpAccountDinerRefCreation.newBuilder()
.setDinerId(dinerId)
.setAccountId(loginInfo.getId())
.build();
final var mpAccountDinerRef = mealOrderServiceRpcClient.createMpAccountDinerRef(loginInfo, mpAccountDinerRefCreation);
log.info("createMpAccountDiner dinerId:{} mpAccountDinerRefId:{}", dinerId, mpAccountDinerRef.getId());
return CreatedResult.<DinerVO>builder().id(dinerId).isCreated(mpAccountDinerRef.getIsCreated()).build();
}
}
final var dinerCreation = DinerCreation.newBuilder()
.setClientId(singleClientRpcResponse.getId())
.setClassId(createDinerDTO.getClassId())
.setStudentNo(createDinerDTO.getStudentNo())
.setName(createDinerDTO.getName())
.build();
final var dinerResponse = mealOrderServiceRpcClient.createDiner(loginInfo, dinerCreation);
if (dinerResponse.getIsCreated()) {
final var mpAccountDinerRefCreation = MpAccountDinerRefCreation.newBuilder()
.setDinerId(dinerResponse.getId())
.setAccountId(loginInfo.getId())
.build();
final var mpAccountDinerRef = mealOrderServiceRpcClient.createMpAccountDinerRef(loginInfo, mpAccountDinerRefCreation);
log.info("createMpAccountDiner dinerId:{} mpAccountDinerRefId:{}", dinerResponse.getId(), mpAccountDinerRef.getId());
}
return CreatedResult.<DinerVO>builder().id(dinerResponse.getId()).isCreated(dinerResponse.getIsCreated()).build();
}
@Override
public List<GradeClassVO> getClientGradeClasses(SingleClientRpcResponse client) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var gradeClasses = mealOrderServiceRpcClient.queryGradeClassesByCondition(loginInfo.getEnterpriseId(), List.of(client.getId()));
return gradeClasses.stream().map(e -> GradeClassVO.builder()
.id(e.getId())
.enterpriseId(e.getEnterpriseId())
.gradeName(e.getGradeName())
.className(e.getClassName())
.build()).toList();
}
@Override
public void updateMpAccountDiner(SingleDinerRpcResponse diner, DinerDTO.UpdateDinerDTO updateDinerDTO) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var clientsByCodes = clientInventoryServiceRpcClient.getClientsByCodes(loginInfo.getEnterpriseId(), List.of(updateDinerDTO.getClientCode()));
if (clientsByCodes.size() != 1) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_CODE_NOT_EXISTS);
}
final var singleClientRpcResponse = clientsByCodes.get(0);
if (diner.getClientId() == singleClientRpcResponse.getId() && diner.getClassId() == updateDinerDTO.getClassId() && diner.getStudentNo().equals(updateDinerDTO.getStudentNo()) && !diner.getName().equals(updateDinerDTO.getName())) {
mealOrderServiceRpcClient.updateDiner(loginInfo, DinerModification.newBuilder().setId(diner.getId()).setShouldUpdateName(true).setName(updateDinerDTO.getName()).build());
return;
}
final var diners = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(singleClientRpcResponse.getId()), List.of(updateDinerDTO.getClassId()), updateDinerDTO.getStudentNo());
if (!diners.isEmpty()) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_EXISTS);
}
mealOrderServiceRpcClient.updateDiner(loginInfo, DinerModification.newBuilder()
.setId(diner.getId())
.setShouldUpdateClientId(true).setClientId(singleClientRpcResponse.getId())
.setShouldUpdateClassId(updateDinerDTO.getClassId() != null).setClassId(updateDinerDTO.getClassId() == null ? diner.getClassId() : updateDinerDTO.getClassId())
.setShouldUpdateName(updateDinerDTO.getName() != null).setName(updateDinerDTO.getName() == null ? diner.getName() : updateDinerDTO.getName())
.setShouldUpdateStudentNo(updateDinerDTO.getStudentNo() != null).setStudentNo(updateDinerDTO.getStudentNo() == null ? diner.getStudentNo() : updateDinerDTO.getStudentNo())
.build());
}
@Override
public void deleteMpAccountDiner(SingleDinerRpcResponse diner) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var mpAccountDinerRefRpcResponseList = mealOrderServiceRpcClient.queryMpAccountDinerRefsByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId()), List.of(diner.getId()));
mealOrderServiceRpcClient.deleteDinersByIds(loginInfo, List.of(diner.getId()));
if (!mpAccountDinerRefRpcResponseList.isEmpty()) {
mealOrderServiceRpcClient.deleteMpAccountDinerRefsByIds(loginInfo.getEnterpriseId(), mpAccountDinerRefRpcResponseList.stream().map(SingleMpAccountDinerRefRpcResponse::getId).toList());
}
}
@Override
public DinerVO getClientClassDiner(SingleClientRpcResponse client, SingleGradeClassRpcResponse gradeClass, String studentNo) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var diner = mealOrderServiceRpcClient.queryDinersByCondition(loginInfo.getEnterpriseId(), List.of(client.getId()), List.of(gradeClass.getId()), studentNo);
return DinerVO.builder()
.id(diner.get(0).getId())
.enterpriseId(diner.get(0).getEnterpriseId())
.clientId(diner.get(0).getClientId())
.clientCode(client.getCode())
.clientName(client.getName())
.classId(diner.get(0).getClassId())
.gradeName(gradeClass.getGradeName())
.className(gradeClass.getClassName())
.studentNo(diner.get(0).getStudentNo())
.name(diner.get(0).getName())
.build();
}
}
......@@ -6,7 +6,7 @@ import com.infoloop.tianting.clientcustomerorderservice.ServeStatusEnum;
import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse;
import com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.model.dto.InventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.ClientInventoryDbDTO.ClientDto;
import com.infoloop.tianting.model.dto.KdsDTO.KdsMealDetailDto;
import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDetailDto;
import com.infoloop.tianting.model.dto.KdsDTO.KdsOrderLocationDto;
......@@ -19,8 +19,8 @@ import com.infoloop.tianting.model.dto.OrderDbDTO.CustomerNotice;
import com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto;
import com.infoloop.tianting.service.KdsService;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.EnterpriseResourceServiceRpcClient;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
import com.infoloop.tianting.service.client.SkuServiceRpcClient;
......@@ -47,7 +47,7 @@ public class KdsServiceImpl implements KdsService {
private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
private final MealServiceRpcClient mealServiceRpcClient;
private final SkuServiceRpcClient skuServiceRpcClient;
private final InventoryServiceRpcClient inventoryServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
@Override
......@@ -87,14 +87,14 @@ public class KdsServiceImpl implements KdsService {
.map(SingleClientCustomerOrderRpcResponse::getClientId)
.distinct()
.collect(Collectors.toList());
final var clients = inventoryServiceRpcClient.getClientsByIds(
final var clients = clientInventoryServiceRpcClient.getClientsByIds(
operator.getEnterpriseId(), clientIds);
final var orderStallIds = orderList.stream()
.map(SingleClientCustomerOrderRpcResponse::getStallId)
.distinct()
.collect(Collectors.toList());
final var stalls = inventoryServiceRpcClient.getStallsByIds(
final var stalls = clientInventoryServiceRpcClient.getStallsByIds(
operator.getEnterpriseId(), orderStallIds);
final var customerIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).collect(Collectors.toList());
......@@ -321,14 +321,14 @@ public class KdsServiceImpl implements KdsService {
.map(SingleClientCustomerOrderRpcResponse::getClientId)
.distinct()
.collect(Collectors.toList());
final var clients = inventoryServiceRpcClient.getClientsByIds(
final var clients = clientInventoryServiceRpcClient.getClientsByIds(
operator.getEnterpriseId(), clientIds);
final var orderStallIds = orderList.stream()
.map(SingleClientCustomerOrderRpcResponse::getStallId)
.distinct()
.collect(Collectors.toList());
final var stalls = inventoryServiceRpcClient.getStallsByIds(
final var stalls = clientInventoryServiceRpcClient.getStallsByIds(
operator.getEnterpriseId(), orderStallIds);
final var customerIds = orderList.stream().map(SingleClientCustomerOrderRpcResponse::getCustomerId).collect(Collectors.toList());
......
......@@ -7,11 +7,19 @@ import com.infoloop.rpc.meizhongyiheservice.HospitalStatus;
import com.infoloop.tianting.WOperatorStatus;
import com.infoloop.tianting.clientcustomerservice.ClientCustomerHospitalRecordHospitalStatusEnum;
import com.infoloop.tianting.constant.CommonConstants;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.MpAccountCreation;
import com.infoloop.tianting.mealorderservice.MpAccountModification;
import com.infoloop.tianting.mealorderservice.MpAccountStatusEnum;
import com.infoloop.tianting.mealorderservice.SingleMpAccountRpcResponse;
import com.infoloop.tianting.model.dto.MpAccountDTO;
import com.infoloop.tianting.model.dto.PermissionDTO.LoginDto;
import com.infoloop.tianting.model.vo.MpAccountVO;
import com.infoloop.tianting.service.LoginService;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.service.client.MeiZhongYiHeServiceClient;
import com.infoloop.tianting.service.client.OperatorServiceRpcClient;
import com.infoloop.tianting.service.client.WOperatorServiceRpcClient;
......@@ -20,6 +28,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
......@@ -30,6 +39,7 @@ import java.security.NoSuchAlgorithmException;
public class LoginServiceImpl implements LoginService {
private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final OperatorServiceRpcClient operatorServiceRpcClient;
private final WxMiniProgramHttpClient wxMiniProgramHttpClient;
private final WOperatorServiceRpcClient wOperatorServiceRpcClient;
......@@ -44,6 +54,25 @@ public class LoginServiceImpl implements LoginService {
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
return StpUtil.getTokenInfo();
} else if (loginDto.isShouldLoginWithOpenId()){
final var mpAccountByOpenId = mealOrderServiceRpcClient.getMpAccountByOpenId(loginDto.getOpenId());
int mpAccountId;
if (mpAccountByOpenId == null) {
mpAccountId = mealOrderServiceRpcClient.createMpAccount(loginDto.getEnterpriseId(), MpAccountCreation.newBuilder()
.setOpenId(loginDto.getOpenId())
.setStatus(MpAccountStatusEnum.MP_ACCOUNT_STATUS_ENABLE)
.setPhoneNumber(loginDto.getOperatorPhone() != null ? loginDto.getOperatorPhone() : "")
.build()).getId();
} else {
mpAccountId = mpAccountByOpenId.getId();
}
Assert.isTrue(mpAccountId != 0, "创建小程序账号失败");
StpUtil.login(loginDto.getOpenId(), SaLoginModel.create()
.setExtra(CommonConstants.ENTERPRISE_ID, loginDto.getEnterpriseId())
.setExtra(CommonConstants.USER_ID, mpAccountId)
.setExtra(CommonConstants.LOGIN_SOURCE, loginDto.getLoginSourceEnum().getValue())
.build());
return StpUtil.getTokenInfo();
} else if (loginDto.isShouldLoginWithHisCustomerNo()) {
var customer = clientCustomerServiceRpcClient.getClientCustomerByHISCustomerNo(loginDto.getHisCustomerNo()).getResponse();
if (customer.getId() == 0) {
......@@ -110,6 +139,37 @@ public class LoginServiceImpl implements LoginService {
}
}
@Override
public MpAccountVO getMpAccountByOpenId(String openId) {
final var mpAccountByOpenId = mealOrderServiceRpcClient.getMpAccountByOpenId(openId);
if (mpAccountByOpenId == null) {
return null;
}
return MpAccountVO.builder()
.id(mpAccountByOpenId.getId())
.enterpriseId(mpAccountByOpenId.getEnterpriseId())
.openId(mpAccountByOpenId.getOpenId())
.unionId(mpAccountByOpenId.getUnionId())
.nickname(mpAccountByOpenId.getNickname())
.avatarUrl(mpAccountByOpenId.getAvatarUrl())
.gender(mpAccountByOpenId.getGender())
.phoneNumber(mpAccountByOpenId.getPhoneNumber())
.build();
}
@Override
public void updateMpAccount(SingleMpAccountRpcResponse mpAccount, MpAccountDTO.ModifyMpAccountDTO modifyMpAccountDTO) {
mealOrderServiceRpcClient.updateMpAccount(LoginContextHolder.getLoginInfo(), MpAccountModification.newBuilder()
.setId(mpAccount.getId())
.setShouldUpdateNickname(modifyMpAccountDTO.getNickName() != null)
.setNickname(modifyMpAccountDTO.getNickName() != null ? modifyMpAccountDTO.getNickName() : mpAccount.getNickname())
.setShouldUpdateAvatarUrl(modifyMpAccountDTO.getAvatarUrl() != null)
.setAvatarUrl(modifyMpAccountDTO.getAvatarUrl() != null ? modifyMpAccountDTO.getAvatarUrl() : mpAccount.getAvatarUrl())
.setShouldUpdateGender(modifyMpAccountDTO.getGender() != null)
.setGender(modifyMpAccountDTO.getGender() != null ? modifyMpAccountDTO.getGender() : mpAccount.getGender())
.build());
}
public static String sha1Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(input.getBytes());
......
package com.infoloop.tianting.service.impl;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.enums.QueryMealOrderStatusEnum;
import com.infoloop.tianting.exception.ClientEndExceptions;
import com.infoloop.tianting.exception.ErrorCodeEnum;
import com.infoloop.tianting.mealorderservice.MealOrderCreation;
import com.infoloop.tianting.mealorderservice.MealOrderOrderMethodEnum;
import com.infoloop.tianting.mealorderservice.MenuSchedule;
import com.infoloop.tianting.mealorderservice.SingleMealOrderRpcResponse;
import com.infoloop.tianting.model.common.CreatedResult;
import com.infoloop.tianting.model.dto.MealOrderDTO;
import com.infoloop.tianting.model.vo.DeliveryRuleVO;
import com.infoloop.tianting.model.vo.MealOrderVO;
import com.infoloop.tianting.service.MealOrderService;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.DeliveryRuleServiceRpcClient;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MealOrderServiceImpl implements MealOrderService {
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final DeliveryRuleServiceRpcClient deliveryRuleServiceRpcClient;
@Override
public List<MealOrderVO> queryMealOrders(MealOrderDTO.QueryMealOrderDTO queryMealOrderDTO) {
final var loginInfo = LoginContextHolder.getLoginInfo();
var mealOrderRpcResponses = mealOrderServiceRpcClient.queryMealOrdersByCondition(loginInfo.getEnterpriseId(), List.of(loginInfo.getId(), 0), null, null);
final var today = LocalDate.now();
final var lastWeekStart = today.minusWeeks(1).with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
final var lastWeekEnd = today.minusWeeks(1).with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
final var thisWeekStart = today.with(DayOfWeek.MONDAY).atStartOfDay().atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
final var thisWeekEnd = today.with(DayOfWeek.SUNDAY).atTime(LocalTime.MAX).atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli();
if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.COMPLETED) {
mealOrderRpcResponses = mealOrderRpcResponses.stream()
.filter(e -> e.getReserveDate() < lastWeekStart)
.toList();
} else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.UNDER_WAY) {
mealOrderRpcResponses = mealOrderRpcResponses.stream()
.filter(e -> e.getReserveDate() >= lastWeekStart && e.getReserveDate() <= lastWeekEnd)
.toList();
} else if (queryMealOrderDTO.getStatus() == QueryMealOrderStatusEnum.BE_BOOKED) {
mealOrderRpcResponses = mealOrderRpcResponses.stream()
.filter(e -> e.getReserveDate() >= thisWeekStart && e.getReserveDate() <= thisWeekEnd)
.toList();
}
return mealOrderRpcResponses.stream()
.map(this::getMealOrderById)
.toList();
}
@Override
public CreatedResult<MealOrderVO> createMealOrder(MealOrderDTO.CreateMealOrderDTO createMealOrderDTO) {
final var loginInfo = LoginContextHolder.getLoginInfo();
final var deliveryRule = this.getDeliveryRule();
final var now = LocalDateTime.now();
final var nowWithinRange = isNowWithinRange(deliveryRule, now);
if (!nowWithinRange) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.MEAL_ORDER_TIME_NOT_IN_RANGE);
}
final var reserveDinerMealOrders = mealOrderServiceRpcClient.queryReserveMealOrdersByDinerIds(loginInfo.getEnterpriseId(), Collections.singletonList(createMealOrderDTO.getDinerId()));
if (!reserveDinerMealOrders.isEmpty()) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_ALREADY_RESERVED);
}
final var dinerById = mealOrderServiceRpcClient.getDinerById(loginInfo.getEnterpriseId(), createMealOrderDTO.getDinerId());
if (dinerById == null) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.DINER_NOT_FOUND);
}
final var clientById = clientInventoryServiceRpcClient.getClientById(loginInfo.getEnterpriseId(), dinerById.getClientId());
if (clientById == null) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_NOT_FOUND);
}
if (clientById.getClient().getStatus() != 1) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.CLIENT_NOT_ENABLED);
}
final var gradeClassById = mealOrderServiceRpcClient.getGradeClassById(loginInfo.getEnterpriseId(), dinerById.getClassId());
if (gradeClassById == null) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.GRADE_CLASS_NOT_FOUND);
}
final var latestMealMenuRecords = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(loginInfo.getEnterpriseId(), Collections.singletonList(dinerById.getClientId()));
if (latestMealMenuRecords.isEmpty()) {
throw ClientEndExceptions.IncorrectRequestValue.build(ErrorCodeEnum.MEAL_MENU_NOT_FOUND);
}
final var mealOrder = mealOrderServiceRpcClient.createMealOrder(loginInfo, MealOrderCreation.newBuilder()
.setClientId(dinerById.getClientId())
.setMenuId(latestMealMenuRecords.get(0).getId())
.setAccountId(loginInfo.getId())
.setOrderMethod(MealOrderOrderMethodEnum.MEAL_ORDER_METHOD_MICRO)
.setDinerId(createMealOrderDTO.getDinerId())
.setDinerName(dinerById.getName())
.setClientName(clientById.getClient().getName())
.setGradeName(gradeClassById.getGradeName())
.setClassName(gradeClassById.getClassName())
.setStudentNo(dinerById.getStudentNo())
.setReserveDate(now.atZone(DateUtil.CHINA_ZONE).toInstant().toEpochMilli())
.addAllMeals(createMealOrderDTO.getMeals().stream().map(e -> MenuSchedule.newBuilder()
.setDate(e.getDate())
.setMenu(e.getMenu())
.build()).toList())
.build());
return CreatedResult.<MealOrderVO>builder().id(mealOrder.getId()).isCreated(mealOrder.getIsCreated()).build();
}
@Override
public MealOrderVO getMealOrderById(SingleMealOrderRpcResponse mealOrder) {
return MealOrderVO.builder()
.id(mealOrder.getId())
.clientId(mealOrder.getClientId())
.menuId(mealOrder.getMenuId())
.accountId(mealOrder.getAccountId())
.orderMethod(mealOrder.getOrderMethod())
.dinerId(mealOrder.getDinerId())
.dinerName(mealOrder.getDinerName())
.clientName(mealOrder.getClientName())
.gradeName(mealOrder.getGradeName())
.className(mealOrder.getClassName())
.studentNo(mealOrder.getStudentNo())
.reserveDate(DateUtil.formatDate(mealOrder.getReserveDate()))
.meals(mealOrder.getMealsList().stream().map(e -> MealOrderVO.Meals.builder().date(e.getDate()).menu(e.getMenu()).build()).toList())
.build();
}
@Override
public DeliveryRuleVO getDeliveryRule() {
final var rule = deliveryRuleServiceRpcClient.getDefaultDeliveryTemplateAndRule(LoginContextHolder.getEnterpriseId()).getRule();
if (rule.getConfigJson().getRulesList().isEmpty()) {
return DeliveryRuleVO.builder().build();
}
return DeliveryRuleVO.builder()
.startTime(rule.getConfigJson().getRules(0).getStartTime())
.endTime(rule.getConfigJson().getRules(0).getEndTime())
.monday(rule.getConfigJson().getRules(0).getMonday())
.tuesday(rule.getConfigJson().getRules(0).getTuesday())
.wednesday(rule.getConfigJson().getRules(0).getWednesday())
.thursday(rule.getConfigJson().getRules(0).getThursday())
.friday(rule.getConfigJson().getRules(0).getFriday())
.saturday(rule.getConfigJson().getRules(0).getSaturday())
.sunday(rule.getConfigJson().getRules(0).getSunday())
.build();
}
private static boolean isNowWithinRange(DeliveryRuleVO rule, LocalDateTime now) {
if (rule == null || rule.getStartTime() == null || rule.getEndTime() == null) {
return false;
}
final var startTime = LocalTime.parse(rule.getStartTime(), DateUtil.HH_MM_SS);
final var endTime = LocalTime.parse(rule.getEndTime(), DateUtil.HH_MM_SS);
final var enabledDays = new ArrayList<DayOfWeek>();
if (Boolean.TRUE.equals(rule.getMonday())) enabledDays.add(DayOfWeek.MONDAY);
if (Boolean.TRUE.equals(rule.getTuesday())) enabledDays.add(DayOfWeek.TUESDAY);
if (Boolean.TRUE.equals(rule.getWednesday())) enabledDays.add(DayOfWeek.WEDNESDAY);
if (Boolean.TRUE.equals(rule.getThursday())) enabledDays.add(DayOfWeek.THURSDAY);
if (Boolean.TRUE.equals(rule.getFriday())) enabledDays.add(DayOfWeek.FRIDAY);
if (Boolean.TRUE.equals(rule.getSaturday())) enabledDays.add(DayOfWeek.SATURDAY);
if (Boolean.TRUE.equals(rule.getSunday())) enabledDays.add(DayOfWeek.SUNDAY);
if (enabledDays.isEmpty()) {
return false;
}
final var minDay = Collections.min(enabledDays);
final var maxDay = Collections.max(enabledDays);
final var today = now.toLocalDate();
final var startDateTime = getThisWeekDate(today, minDay).atTime(startTime);
final var endDateTime = getThisWeekDate(today,maxDay).atTime(endTime);
return !now.isBefore(startDateTime) && !now.isAfter(endDateTime);
}
private static LocalDate getThisWeekDate(LocalDate now, DayOfWeek day) {
LocalDate monday = now.with(DayOfWeek.MONDAY);
return monday.plusDays(day.getValue() - 1L); // MONDAY 是 1,SUNDAY 是 7
}
}
package com.infoloop.tianting.service.impl;
import com.infoloop.tianting.clientinventoryservice.SingleClientRpcResponse;
import com.infoloop.tianting.context.LoginContextHolder;
import com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse;
import com.infoloop.tianting.menuservice.SingleMenuRpcResponse;
......@@ -11,6 +12,7 @@ import com.infoloop.tianting.model.dto.MenuDbDTO.MenuDto;
import com.infoloop.tianting.model.dto.MenuDbDTO.MenuRefDto;
import com.infoloop.tianting.model.dto.MenuDbDTO.OrderRuleJson;
import com.infoloop.tianting.service.MenuService;
import com.infoloop.tianting.service.client.MealOrderServiceRpcClient;
import com.infoloop.tianting.service.client.MenuServiceRpcClient;
import com.infoloop.tianting.utils.DateUtil;
import lombok.RequiredArgsConstructor;
......@@ -29,6 +31,8 @@ public class MenuServiceImpl implements MenuService {
private final MenuServiceRpcClient menuServiceRpcClient;
private final MealOrderServiceRpcClient mealOrderServiceRpcClient;
@Override
public List<MenuDto> queryMiniProgramPublishedMenusByStallId(Integer enterpriseId, Integer stallId) {
final var response = menuServiceRpcClient.queryMiniProgramPublishedMenusByStallId(enterpriseId, stallId);
......@@ -209,4 +213,11 @@ public class MenuServiceImpl implements MenuService {
return menuServiceRpcClient.queryMenuDetailsByMenuIds(LoginContextHolder.getEnterpriseId(), menuIds).getResponsesList().stream().map(SingleMenuDetailRpcResponse::getSkuId).distinct().collect(Collectors.toList());
}
@Override
public String queryClientLatestMealMenuRecord(SingleClientRpcResponse client) {
final var singleMealMenuRecordRpcResponses = mealOrderServiceRpcClient.queryLatestMealMenuRecordsByClientIds(LoginContextHolder.getEnterpriseId(), List.of(client.getId()));
return singleMealMenuRecordRpcResponses.isEmpty() ? "" : singleMealMenuRecordRpcResponses.get(0).getImageUrl();
}
}
......
......@@ -18,7 +18,7 @@ import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto;
import com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto;
import com.infoloop.tianting.service.SettlementService;
import com.infoloop.tianting.service.client.InventoryServiceRpcClient;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.MealServiceRpcClient;
import com.infoloop.tianting.service.client.MenuServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
......@@ -55,7 +55,7 @@ public class SettlementServiceImpl implements SettlementService {
private final OrderServiceRpcClient orderServiceRpcClient;
private final MenuServiceRpcClient menuServiceRpcClient;
private final SkuServiceRpcClient skuServiceRpcClient;
private final InventoryServiceRpcClient inventoryServiceRpcClient;
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final MealServiceRpcClient mealServiceRpcClient;
public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto)
......@@ -403,7 +403,7 @@ public class SettlementServiceImpl implements SettlementService {
}
}
final var stalls = inventoryServiceRpcClient.getStallsByIds(enterpriseId, settlementRequest.getStallIds()).getClientsList();
final var stalls = clientInventoryServiceRpcClient.getStallsByIds(enterpriseId, settlementRequest.getStallIds()).getClientsList();
final var stallNames = stalls.stream()
.filter(s -> settlementRequest.getStallIds().contains(s.getId()))
.map(SingleClientRpcResponse::getName).collect(Collectors.toList());
......@@ -525,7 +525,7 @@ public class SettlementServiceImpl implements SettlementService {
}
}
final var client = inventoryServiceRpcClient.getClientById(enterpriseId,
final var client = clientInventoryServiceRpcClient.getClientById(enterpriseId,
settlementRequest.getClientId()).getClient();
final var settlementDataByMealDto = SettlementDataByMealDto.builder()
.classifyOrders(classifyOrders)
......
......@@ -115,14 +115,12 @@ public class SkuServiceImpl implements SkuService {
if (querySkuSellQuantityDTO.getStatus() != SkuSellQuantityStatus.ALL) {
responses = responses.stream()
.filter(e -> {
switch (querySkuSellQuantityDTO.getStatus()) {
case SOLD_OUT:
return e.getMaxSellQuantity() == e.getTodaySellQuantity();
case ON_SALE:
return e.getMaxSellQuantity() != e.getTodaySellQuantity();
default:
return true;
if (querySkuSellQuantityDTO.getStatus() == SkuSellQuantityStatus.SOLD_OUT) {
return e.getMaxSellQuantity() == e.getTodaySellQuantity();
} else if (querySkuSellQuantityDTO.getStatus() == SkuSellQuantityStatus.ON_SALE) {
return e.getMaxSellQuantity() != e.getTodaySellQuantity();
}
return true;
})
.collect(Collectors.toList());
}
......
package com.infoloop.tianting.store;
import io.lettuce.core.SetArgs;
import io.lettuce.core.api.sync.RedisCommands;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
public class WeeklyTaskStore {
private final RedisCommands<String, String> commands;
private final long expire; // 过期时间(秒)
public WeeklyTaskStore(final RedisCommands<String, String> commands, final long expire) {
this.commands = commands;
this.expire = expire;
}
public boolean isExecutedThisWeek(String keyPrefix, int enterpriseId, LocalDate date) {
String key = getWeeklyKey(keyPrefix, enterpriseId, date);
return commands.exists(key) > 0;
}
public void markExecuted(String keyPrefix, int enterpriseId, LocalDate date) {
String key = getWeeklyKey(keyPrefix, enterpriseId, date);
commands.set(key, "1", new SetArgs().ex(expire));
}
private String getWeeklyKey(String keyPrefix, int enterpriseId, LocalDate date) {
WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 1);
int year = date.getYear();
int week = date.get(weekFields.weekOfWeekBasedYear());
return String.format("%s:%d:%d-W%d", keyPrefix, enterpriseId, year, week);
}
}
......@@ -4,11 +4,22 @@ import com.infoloop.tianting.model.common.OrderPageResult;
import com.infoloop.tianting.model.common.PageResult;
import com.infoloop.tianting.model.dto.OrderDbDTO.OrderCountByStatusDto;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;
public class PageUtil {
public static <T> PageResult<T> buildEmpty(Class<T> clazz) {
T instance;
try {
instance = clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
return buildEmpty(instance);
}
public static <T> PageResult<T> buildEmpty(T t) {
PageResult<T> pageRet = new PageResult<>();
pageRet.setTotalCount(0);
......
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.infoloop.tianting.mealorderservice";
option java_outer_classname = "MealOrderServiceProto";
option objc_class_prefix = "OP";
package com.infoloop.tianting.mealorderservice;
service MealOrderServiceRpc {
rpc GetMealOrderById (GetMealOrderByIdRpcRequest) returns (GetMealOrderByIdRpcResponse) {}
rpc GetMealOrdersByIds (GetMealOrdersByIdsRpcRequest) returns (GetMealOrdersByIdsRpcResponse) {}
rpc QueryMealOrdersByCondition (QueryMealOrdersByConditionRpcRequest) returns (QueryMealOrdersByConditionRpcResponse) {}
rpc QueryReserveMealOrdersByDinerIds (QueryReserveMealOrdersByDinerIdsRpcRequest) returns (QueryReserveMealOrdersByDinerIdsRpcResponse) {}
rpc CreateMealOrder (CreateMealOrderRpcRequest) returns (CreateMealOrderRpcResponse) {}
rpc BatchCreateMealOrders (BatchCreateMealOrdersRpcRequest) returns (BatchCreateMealOrdersRpcResponse) {}
rpc DeleteMealOrdersByIds (DeleteMealOrdersByIdsRpcRequest) returns (DeleteMealOrdersRpcResponse) {}
rpc GetMpAccountById (GetMpAccountByIdRpcRequest) returns (GetMpAccountByIdRpcResponse) {}
rpc GetMpAccountByOpenId (GetMpAccountByOpenIdRpcRequest) returns (GetMpAccountByOpenIdRpcResponse) {}
rpc GetMpAccountsByIds (GetMpAccountsByIdsRpcRequest) returns (GetMpAccountsByIdsRpcResponse) {}
rpc QueryMpAccountsByCondition (QueryMpAccountsByConditionRpcRequest) returns (QueryMpAccountsByConditionRpcResponse) {}
rpc CreateMpAccount (CreateMpAccountRpcRequest) returns (CreateMpAccountRpcResponse) {}
rpc UpdateMpAccount (UpdateMpAccountRpcRequest) returns (UpdateMpAccountRpcResponse) {}
rpc DeleteMpAccountsByIds (DeleteMpAccountsByIdsRpcRequest) returns (DeleteMpAccountsRpcResponse) {}
rpc GetDinerById (GetDinerByIdRpcRequest) returns (GetDinerByIdRpcResponse) {}
rpc GetDinersByIds (GetDinersByIdsRpcRequest) returns (GetDinersByIdsRpcResponse) {}
rpc QueryDinersByCondition (QueryDinersByConditionRpcRequest) returns (QueryDinersByConditionRpcResponse) {}
rpc CreateDiner (CreateDinerRpcRequest) returns (CreateDinerRpcResponse) {}
rpc UpdateDiner (UpdateDinerRpcRequest) returns (UpdateDinerRpcResponse) {}
rpc BatchSaveOrUpdateDiners (BatchSaveOrUpdateDinersRpcRequest) returns (BatchSaveOrUpdateDinersRpcResponse) {}
rpc DeleteDinersByIds (DeleteDinersByIdsRpcRequest) returns (DeleteDinersRpcResponse) {}
rpc GetMpAccountDinerRefsByIds (GetMpAccountDinerRefsByIdsRpcRequest) returns (GetMpAccountDinerRefsByIdsRpcResponse) {}
rpc QueryMpAccountDinerRefsByCondition (QueryMpAccountDinerRefsByConditionRpcRequest) returns (QueryMpAccountDinerRefsByConditionRpcResponse) {}
rpc CreateMpAccountDinerRef (CreateMpAccountDinerRefRpcRequest) returns (CreateMpAccountDinerRefRpcResponse) {}
rpc DeleteMpAccountDinerRefsByIds (DeleteMpAccountDinerRefsByIdsRpcRequest) returns (DeleteMpAccountDinerRefsRpcResponse) {}
rpc GetGradeClassById (GetGradeClassByIdRpcRequest) returns (GetGradeClassByIdRpcResponse) {}
rpc GetGradeClassesByIds (GetGradeClassesByIdsRpcRequest) returns (GetGradeClassesByIdsRpcResponse) {}
rpc QueryGradeClassesByCondition (QueryGradeClassesByConditionRpcRequest) returns (QueryGradeClassesByConditionRpcResponse) {}
rpc CreateGradeClass (CreateGradeClassRpcRequest) returns (CreateGradeClassRpcResponse) {}
rpc BatchCreateGradeClasses (BatchCreateGradeClassesRpcRequest) returns (BatchCreateGradeClassesRpcResponse) {}
rpc UpdateGradeClass (UpdateGradeClassRpcRequest) returns (UpdateGradeClassRpcResponse) {}
rpc BatchSaveOrUpdateGradeClasses (BatchSaveOrUpdateGradeClassesRpcRequest) returns (BatchSaveOrUpdateGradeClassesRpcResponse) {}
rpc DeleteGradeClassesByIds (DeleteGradeClassesByIdsRpcRequest) returns (DeleteGradeClassesRpcResponse) {}
rpc DeleteGradeClassesAndDinersByClientIds (DeleteGradeClassesAndDinersByClientIdsRpcRequest) returns (DeleteGradeClassesAndDinersByClientIdsRpcResponse) {}
rpc GetMealMenuRecordById (GetMealMenuRecordByIdRpcRequest) returns (GetMealMenuRecordByIdRpcResponse) {}
rpc GetMealMenuRecordsByIds (GetMealMenuRecordsByIdsRpcRequest) returns (GetMealMenuRecordsByIdsRpcResponse) {}
rpc QueryMealMenuRecordsByCondition (QueryMealMenuRecordsByConditionRpcRequest) returns (QueryMealMenuRecordsByConditionRpcResponse) {}
rpc CreateMealMenuRecord (CreateMealMenuRecordRpcRequest) returns (CreateMealMenuRecordRpcResponse) {}
rpc QueryLatestMealMenuRecordsByClientIds (QueryLatestMealMenuRecordsByClientIdsRpcRequest) returns (QueryLatestMealMenuRecordsByClientIdsRpcResponse) {}
}
enum MealOrderOrderMethodEnum {
MEAL_ORDER_METHOD_SYSTEM = 0;
MEAL_ORDER_METHOD_MICRO = 1;
}
message SingleMealOrderRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
int32 clientId = 3;
int32 menuId = 4;
int32 accountId = 5;
MealOrderOrderMethodEnum orderMethod = 6;
int32 dinerId = 7;
string dinerName = 8;
string clientName = 9;
string gradeName = 10;
string className = 11;
string studentNo = 12;
int64 reserveDate = 13;
repeated MenuSchedule meals = 14;
int32 createdBy = 15;
int64 createdAt = 16;
int32 creationSource = 17;
int32 updatedBy = 18;
int64 updatedAt = 19;
int32 updateSource = 20;
bool isDeleted = 21;
}
message GetMealOrderByIdRpcRequest {
int32 id = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMealOrderByIdRpcResponse {
SingleMealOrderRpcResponse response = 1;
}
message GetMealOrdersByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMealOrdersByIdsRpcResponse {
repeated SingleMealOrderRpcResponse responses = 1;
}
message QueryMealOrdersByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterClientIds = 2;
repeated int32 clientIds = 3;
bool shouldFilterMenuIds = 4;
repeated int32 menuIds = 5;
bool shouldFilterAccountIds = 6;
repeated int32 accountIds = 7;
bool shouldFilterOrderMethod = 8;
MealOrderOrderMethodEnum orderMethod = 9;
bool shouldFilterDinerIds = 10;
repeated int32 dinerIds = 11;
bool shouldFilterReserveDateStart = 12;
int64 reserveDateStart = 13;
bool shouldFilterReserveDateEnd = 14;
int64 reserveDateEnd = 15;
bool includeDeleted = 16;
}
message QueryMealOrdersByConditionRpcResponse {
repeated SingleMealOrderRpcResponse responses = 1;
}
message QueryReserveMealOrdersByDinerIdsRpcRequest {
int32 enterpriseId = 1;
repeated int32 dinerIds = 2;
}
message QueryReserveMealOrdersByDinerIdsRpcResponse {
repeated SingleMealOrderRpcResponse responses = 1;
}
message MealOrderCreation{
int32 clientId = 1;
int32 menuId = 2;
int32 accountId = 3;
MealOrderOrderMethodEnum orderMethod = 4;
int32 dinerId = 5;
string dinerName = 6;
string clientName = 7;
string gradeName = 8;
string className = 9;
string studentNo = 10;
int64 reserveDate = 11;
repeated MenuSchedule meals = 12;
}
message MenuSchedule {
string date = 1; // 日期字段,类型是 string
string menu = 2; // 菜单字段,类型是 string
}
message CreateMealOrderRpcRequest {
MealOrderCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateMealOrderRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message BatchCreateMealOrdersRpcRequest {
repeated MealOrderCreation creations = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message BatchCreateMealOrdersRpcResponse {
repeated int32 ids = 1;
bool isCreated = 2;
}
message MealOrderModification {
int32 id = 1;
bool shouldUpdateClientId = 2;
int32 clientId = 3;
bool shouldUpdateMenuId = 4;
int32 menuId = 5;
bool shouldUpdateAccountId = 6;
int32 accountId = 7;
bool shouldUpdateOrderMethod = 8;
MealOrderOrderMethodEnum orderMethod = 9;
bool shouldUpdateDinerId = 10;
int32 dinerId = 11;
bool shouldUpdateDinerName = 12;
string dinerName = 13;
bool shouldUpdateClientName = 14;
string clientName = 15;
bool shouldUpdateGradeName = 16;
string gradeName = 17;
bool shouldUpdateClassName = 18;
string className = 19;
bool shouldUpdateStudentNo = 20;
string studentNo = 21;
bool shouldUpdateReserveDate = 22;
int64 reserveDate = 23;
bool shouldUpdateMeals = 24;
repeated MenuSchedule meals = 25;
}
message UpdateMealOrderRpcRequest {
MealOrderModification modification = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message UpdateMealOrderRpcResponse {
bool isUpdated = 1;
}
message BatchUpdateMealOrdersRpcRequest {
repeated MealOrderModification modifications = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message BatchUpdateMealOrdersRpcResponse {
bool isUpdated = 1;
}
message DeleteMealOrdersByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message DeleteMealOrdersRpcResponse {
bool isDeleted = 1;
}
message SingleDinerRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
int32 clientId = 3;
int32 classId = 4;
string studentNo = 5;
string name = 6;
int32 createdBy = 7;
int64 createdAt = 8;
int32 creationSource = 9;
int32 updatedBy = 10;
int64 updatedAt = 11;
int32 updateSource = 12;
bool isDeleted = 13;
}
message GetDinerByIdRpcRequest {
int32 id = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetDinerByIdRpcResponse {
SingleDinerRpcResponse response = 1;
}
message GetDinersByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetDinersByIdsRpcResponse {
repeated SingleDinerRpcResponse responses = 1;
}
message QueryDinersByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterClientIds = 2;
repeated int32 clientIds = 3;
bool shouldFilterClassIds = 4;
repeated int32 classIds = 5;
bool shouldFilterStudentNo = 6;
string studentNo = 7;
bool shouldFilterName = 8;
string name = 9;
bool includeDeleted = 10;
}
message QueryDinersByConditionRpcResponse {
repeated SingleDinerRpcResponse responses = 1;
}
message DinerCreation{
int32 clientId = 1;
int32 classId = 2;
string studentNo = 3;
string name = 4;
}
message CreateDinerRpcRequest {
DinerCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateDinerRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message DinerModification {
int32 id = 1;
bool shouldUpdateClientId = 2;
int32 clientId = 3;
bool shouldUpdateClassId = 4;
int32 classId = 5;
bool shouldUpdateStudentNo = 6;
string studentNo = 7;
bool shouldUpdateName = 8;
string name = 9;
}
message UpdateDinerRpcRequest {
DinerModification modification = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message UpdateDinerRpcResponse {
bool isUpdated = 1;
}
message BatchSaveOrUpdateDinersRpcRequest {
repeated DinerModification modifications = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message BatchSaveOrUpdateDinersRpcResponse {
bool isUpdated = 1;
}
message DeleteDinersByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message DeleteDinersRpcResponse {
bool isDeleted = 1;
}
enum MpAccountGenderEnum {
MP_ACCOUNT_GENDER_MAN = 0;
MP_ACCOUNT_GENDER_WOMAN = 1;
}
enum MpAccountStatusEnum {
MP_ACCOUNT_STATUS_ENABLE = 0;
MP_ACCOUNT_STATUS_DISABLE = 1;
}
message SingleMpAccountRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
string openId = 3;
string unionId = 4;
string nickname = 5;
string avatarUrl = 6;
MpAccountGenderEnum gender = 7;
string phoneNumber = 8;
MpAccountStatusEnum status = 9;
int32 createdBy = 10;
int64 createdAt = 11;
int32 creationSource = 12;
int32 updatedBy = 13;
int64 updatedAt = 14;
int32 updateSource = 15;
bool isDeleted = 16;
}
message GetMpAccountByIdRpcRequest {
int32 id = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMpAccountByIdRpcResponse {
SingleMpAccountRpcResponse response = 1;
}
message GetMpAccountByOpenIdRpcRequest {
string openId = 1;
}
message GetMpAccountByOpenIdRpcResponse {
SingleMpAccountRpcResponse response = 1;
}
message GetMpAccountsByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMpAccountsByIdsRpcResponse {
repeated SingleMpAccountRpcResponse responses = 1;
}
message QueryMpAccountsByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterOpenId = 2;
string openId = 3;
bool shouldFilterUnionId = 4;
string unionId = 5;
bool shouldFilterPhoneNumber = 6;
string phoneNumber = 7;
bool shouldFilterStatus = 8;
MpAccountStatusEnum status = 9;
bool includeDeleted = 10;
}
message QueryMpAccountsByConditionRpcResponse {
repeated SingleMpAccountRpcResponse responses = 1;
}
message MpAccountCreation{
string openId = 1;
bool shouldCreateUnionId = 2;
string unionId = 3;
bool shouldCreateNickname = 4;
string nickname = 5;
bool shouldCreateAvatarUrl = 6;
string avatarUrl = 7;
MpAccountGenderEnum gender = 8;
string phoneNumber = 9;
MpAccountStatusEnum status = 10;
}
message CreateMpAccountRpcRequest {
MpAccountCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateMpAccountRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message MpAccountModification {
int32 id = 1;
bool shouldUpdateOpenId = 2;
string openId = 3;
bool shouldUpdateUnionId = 4;
string unionId = 5;
bool shouldUpdateNickname = 6;
string nickname = 7;
bool shouldUpdateAvatarUrl = 8;
string avatarUrl = 9;
bool shouldUpdateGender = 10;
MpAccountGenderEnum gender = 11;
bool shouldUpdatePhoneNumber = 12;
string phoneNumber = 13;
bool shouldUpdateStatus = 14;
MpAccountStatusEnum status = 15;
}
message UpdateMpAccountRpcRequest {
MpAccountModification modification = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message UpdateMpAccountRpcResponse {
bool isUpdated = 1;
}
message DeleteMpAccountsByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message DeleteMpAccountsRpcResponse {
bool isDeleted = 1;
}
message SingleMpAccountDinerRefRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
int32 accountId = 3;
int32 dinerId = 4;
int32 createdBy = 5;
int64 createdAt = 6;
int32 creationSource = 7;
}
message GetMpAccountDinerRefsByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
}
message GetMpAccountDinerRefsByIdsRpcResponse {
repeated SingleMpAccountDinerRefRpcResponse responses = 1;
}
message QueryMpAccountDinerRefsByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterAccountIds = 2;
repeated int32 accountIds = 3;
bool shouldFilterDinerIds = 4;
repeated int32 dinerIds = 5;
}
message QueryMpAccountDinerRefsByConditionRpcResponse {
repeated SingleMpAccountDinerRefRpcResponse responses = 1;
}
message MpAccountDinerRefCreation{
int32 accountId = 1;
int32 dinerId = 2;
}
message CreateMpAccountDinerRefRpcRequest {
MpAccountDinerRefCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateMpAccountDinerRefRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message BatchCreateMpAccountDinerRefsRpcRequest {
repeated MpAccountDinerRefCreation creations = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message BatchCreateMpAccountDinerRefsRpcResponse {
repeated int32 ids = 1;
bool isCreated = 2;
}
message DeleteMpAccountDinerRefsByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
}
message DeleteMpAccountDinerRefsRpcResponse {
bool isDeleted = 1;
}
message SingleGradeClassRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
int32 clientId = 3;
string gradeName = 4;
string className = 5;
string fullName = 6;
int32 createdBy = 7;
int64 createdAt = 8;
int32 creationSource = 9;
int32 updatedBy = 10;
int64 updatedAt = 11;
int32 updateSource = 12;
bool isDeleted = 13;
}
message GetGradeClassByIdRpcRequest {
int32 id = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetGradeClassByIdRpcResponse {
SingleGradeClassRpcResponse response = 1;
}
message GetGradeClassesByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetGradeClassesByIdsRpcResponse {
repeated SingleGradeClassRpcResponse responses = 1;
}
message GetAllGradeClassesRpcRequest {
int32 enterpriseId = 1;
bool includeDeleted = 2;
}
message GetAllGradeClassesRpcResponse {
repeated SingleGradeClassRpcResponse responses = 1;
}
message QueryGradeClassesByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterClientIds = 2;
repeated int32 clientIds = 3;
bool shouldFilterGradeName = 4;
string gradeName = 5;
bool includeDeleted = 6;
}
message QueryGradeClassesByConditionRpcResponse {
repeated SingleGradeClassRpcResponse responses = 1;
}
message GradeClassCreation{
int32 clientId = 1;
string gradeName = 2;
string className = 3;
bool shouldCreateFullName = 4;
string fullName = 5;
}
message CreateGradeClassRpcRequest {
GradeClassCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateGradeClassRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message BatchCreateGradeClassesRpcRequest {
repeated GradeClassCreation creations = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message BatchCreateGradeClassesRpcResponse {
repeated int32 ids = 1;
bool isCreated = 2;
}
message GradeClassModification {
int32 id = 1;
bool shouldUpdateClientId = 2;
int32 clientId = 3;
bool shouldUpdateGradeName = 4;
string gradeName = 5;
bool shouldUpdateClassName = 6;
string className = 7;
bool shouldUpdateFullName = 8;
string fullName = 9;
}
message UpdateGradeClassRpcRequest {
GradeClassModification modification = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message UpdateGradeClassRpcResponse {
bool isUpdated = 1;
}
message BatchSaveOrUpdateGradeClassesRpcRequest {
repeated GradeClassModification modifications = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message BatchSaveOrUpdateGradeClassesRpcResponse {
bool isUpdated = 1;
}
message BatchUpdateGradeClassesRpcRequest {
repeated GradeClassModification modifications = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message BatchUpdateGradeClassesRpcResponse {
bool isUpdated = 1;
}
message DeleteGradeClassesByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message DeleteGradeClassesRpcResponse {
bool isDeleted = 1;
}
message DeleteGradeClassesAndDinersByClientIdsRpcRequest {
repeated int32 clientIds = 1;
int32 enterpriseId = 2;
int32 updatedBy = 3;
int32 updateSource = 4;
}
message DeleteGradeClassesAndDinersByClientIdsRpcResponse {
bool isDeleted = 1;
}
message SingleMealMenuRecordRpcResponse {
int32 id = 1;
int32 enterpriseId = 2;
int32 clientId = 3;
string name = 4;
string imageUrl = 5;
int32 createdBy = 6;
int64 createdAt = 7;
int32 creationSource = 8;
int32 updatedBy = 9;
int64 updatedAt = 10;
int32 updateSource = 11;
bool isDeleted = 12;
}
message GetMealMenuRecordByIdRpcRequest {
int32 id = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMealMenuRecordByIdRpcResponse {
SingleMealMenuRecordRpcResponse response = 1;
}
message GetMealMenuRecordsByIdsRpcRequest {
repeated int32 ids = 1;
int32 enterpriseId = 2;
bool includeDeleted = 3;
}
message GetMealMenuRecordsByIdsRpcResponse {
repeated SingleMealMenuRecordRpcResponse responses = 1;
}
message QueryMealMenuRecordsByConditionRpcRequest {
int32 enterpriseId = 1;
bool shouldFilterClientIds = 2;
repeated int32 clientIds = 3;
bool shouldFilterName = 4;
string name = 5;
bool includeDeleted = 6;
}
message QueryMealMenuRecordsByConditionRpcResponse {
repeated SingleMealMenuRecordRpcResponse responses = 1;
}
message MealMenuRecordCreation{
int32 clientId = 1;
string name = 2;
bool shouldCreateImageUrl = 3;
string imageUrl = 4;
}
message CreateMealMenuRecordRpcRequest {
MealMenuRecordCreation creation = 1;
int32 enterpriseId = 2;
int32 createdBy = 3;
int32 creationSource = 4;
}
message CreateMealMenuRecordRpcResponse {
int32 id = 1;
bool isCreated = 2;
}
message QueryLatestMealMenuRecordsByClientIdsRpcRequest {
int32 enterpriseId = 1;
repeated int32 clientId = 2;
}
message QueryLatestMealMenuRecordsByClientIdsRpcResponse {
repeated SingleMealMenuRecordRpcResponse responses = 1;
}
......@@ -34,8 +34,8 @@ okhttp.max-idle-connections=10
okhttp.keep-alive-duration=300
##GRPC\u914D\u7F6E
grpc.order-service.url=localhost
grpc.order-service.port=4096
grpc.order-service.url=47.101.193.136
grpc.order-service.port=4065
grpc.menu-service.url=47.101.193.136
grpc.menu-service.port=3017
......@@ -76,10 +76,10 @@ grpc.meizhongyihe-service.port=3040
miniprogram.appId=wx40ec496d73b58ec6
miniprogram.appSecret=5b309517bf918abf760b2195e91b99f3
business-config.hisCustomerQueryUrl = https://nutri.amcare.com.cn/v3/hiscustomers/current/query
business-config.clientCustomerQueryUrl = https://nutri.amcare.com.cn/v3/clientcustomers/current/query
business-config.payUrl = http://10.2.5.162:21051/API/Microapp/CreateOrder?appid={0}
business-config.payClientId = Order
business-config.hisCustomerQueryUrl = http://localhost:8903/hiscustomers/current/query
business-config.clientCustomerQueryUrl = http://localhost:8903/clientcustomers/current/query
business-config.payUrl = http://36.110.128.86:21051/API/Microapp/CreateOrder?appid={0}
business-config.payClientId = Order00001
business-config.cancelPayUrl = http://10.2.5.162:21051/frame/requestbase64
business-config.refundSecurityKey = 0987654321
......@@ -104,6 +104,12 @@ sa-token.sign.secret-key=4Jk2giMQw8D7lHJcU8fv8CXjSOhjp5Ee
##\u65E5\u5FD7\u914D\u7F6E
logging.config=classpath:logback-spring.xml
aliyun.oss.endPoint=oss-cn-shanghai.aliyuncs.com
aliyun.oss.host=infoloop-public-qa.oss-cn-shanghai.aliyuncs.com
aliyun.oss.accessKeyId=LTAIo9gcY5sjIZdN
aliyun.oss.accessKeySecret=gOOkVY4Euj3MSbPyg1tZvPbZbUssj5
aliyun.oss.bucket=infoloop-public-qa
##\u77ED\u4FE1\u914D\u7F6E
sms-config.accessKeyId=
sms-config.accessKeySecret=
......
package com.infoloop.tianting;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@SpringBootTest(classes = App.class)
@RunWith(SpringRunner.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class AppTest {
@Test
void testSomething() {
System.out.println("test");
}
}
......