remove demo code

This commit is contained in:
renxiaoyin 2023-05-04 10:02:14 +08:00
parent 0ba7eb9e5d
commit 1278907965
52 changed files with 1264 additions and 520 deletions

37
pom.xml
View File

@ -55,11 +55,25 @@
<groupId>com.netflix.graphql.dgs</groupId> <groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-pagination</artifactId> <artifactId>graphql-dgs-pagination</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.netflix.graphql.dgs</groupId>
<artifactId>graphql-dgs-extended-scalars</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.netflix.graphql.dgs.codegen</groupId> <groupId>com.netflix.graphql.dgs.codegen</groupId>
<artifactId>graphql-dgs-codegen-client-core</artifactId> <artifactId>graphql-dgs-codegen-client-core</artifactId>
<version>${dgs.codegen.version}</version> <version>${dgs.codegen.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-scalars</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
@ -80,6 +94,11 @@
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>5.4.0</version> <version>5.4.0</version>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>com.longfor.c2.starter</groupId>-->
<!-- <artifactId>longfor-starter-web</artifactId>-->
<!-- <version>1.0.1-SNAPSHOT</version>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
@ -87,8 +106,11 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.3.RELEASE</version> </dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
@ -119,7 +141,7 @@
</executions> </executions>
<configuration> <configuration>
<generateClientApi>true</generateClientApi> <generateClientApi>true</generateClientApi>
<addGeneratedAnnotation>true</addGeneratedAnnotation> <addGeneratedAnnotation>false</addGeneratedAnnotation>
<packageName>com.longfor</packageName> <packageName>com.longfor</packageName>
<schemaPaths> <schemaPaths>
<path>src/main/resources/schema</path> <path>src/main/resources/schema</path>
@ -130,6 +152,15 @@
<ExtentConnection> <ExtentConnection>
<![CDATA[graphql.relay.SimpleListConnection<Extent>]]> <![CDATA[graphql.relay.SimpleListConnection<Extent>]]>
</ExtentConnection> </ExtentConnection>
<GraphQLBigDecimal>
<![CDATA[java.math.BigDecimal]]>
</GraphQLBigDecimal>
<BigDecimal>
<![CDATA[java.math.BigDecimal]]>
</BigDecimal>
<DgsDateTime>
<![CDATA[java.time.LocalDateTime]]>
</DgsDateTime>
</typeMapping> </typeMapping>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication @SpringBootApplication
//@EnableFeignClients @EnableFeignClients
public class BffApplication { public class BffApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -1,9 +1,45 @@
package com.longfor.c2.graphql.starter.client; package com.longfor.c2.graphql.starter.client;
import com.longfor.c2.graphql.starter.client.request.PolymerShopInfoQueryReq;
import com.longfor.c2.graphql.starter.client.response.BaseShopInfo;
import com.longfor.c2.graphql.starter.client.request.Request;
import com.longfor.c2.graphql.starter.client.response.ContractInfoResponse;
import com.longfor.c2.graphql.starter.client.response.DyAccountInfoResponse;
import com.longfor.c2.graphql.starter.client.response.Response;
import com.longfor.types.ContractInfo;
import com.longfor.types.DyAccountInfo;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopUnitInfo;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
// import org.springframework.web.bind.annotation.RequestMapping;
//@FeignClient("shop") import org.springframework.web.bind.annotation.RequestMethod;
//public interface ShopClient {
// import java.util.List;
//
//}
@FeignClient(value = "shop", url = "http://localhost:18801")
public interface ShopClient {
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopPolymerInfo")
Response<List<BaseShopInfo>> queryPolymerShopInfo(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryBaseShopInfo")
Response<List<BaseShopInfo>> queryBaseShopInfo(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopContractEntity")
Response<List<ContractInfoResponse>> queryShopContractEntity(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopSquareContractEntity")
Response<List<ContractInfoResponse>> queryShopSquareContractEntity(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopInnovateContractEntity")
Response<List<ContractInfoResponse>> queryShopInnovateContractEntity(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopUnitInfo")
Response<List<ShopUnitInfo>> queryShopUnitInfo(Request<PolymerShopInfoQueryReq> req);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryShopBrandInfos")
Response<List<ShopBrandInfo>> queryShopBrandInfos(Request<PolymerShopInfoQueryReq> request);
@RequestMapping(method = RequestMethod.POST, value = "/open/shop/queryDyAccountInfo")
Response<List<DyAccountInfoResponse>> queryDyAccountInfo(Request<PolymerShopInfoQueryReq> request);
}

View File

@ -0,0 +1,8 @@
package com.longfor.c2.graphql.starter.client.request;
import lombok.Data;
import java.util.List;
@Data
public class PolymerShopInfoQueryReq {
private List<Integer> shopIds;
}

View File

@ -0,0 +1,27 @@
package com.longfor.c2.graphql.starter.client.request;
import java.io.Serializable;
public class Request<T> implements Serializable {
private static final long serialVersionUID = 1L;
private T data;
public Request() {
}
public T getData() {
return this.data;
}
public void setData(T data) {
this.data = data;
}
public String toString() {
String sep = "; ";
StringBuffer sb = new StringBuffer();
sb.append("Request").append(":");
sb.append("[data]").append(" = ").append(this.getData()).append(sep);
return sb.toString();
}
}

View File

@ -0,0 +1,64 @@
package com.longfor.c2.graphql.starter.client.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class BaseShopInfo {
private Integer shopId;
private String shopName;
private String shopStatus;
private String shopValidity;
private String shopType;
private String projectId;
private String projectName;
private BigDecimal shopArea;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planInDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planOpenDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planStartDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planEndDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realInDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realOpenDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realStartDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realEndDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime receiveDate;
private String formatId;
private String formatName;
}

View File

@ -0,0 +1,62 @@
package com.longfor.c2.graphql.starter.client.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ContractInfoResponse {
private Integer shopId;
private String contractNo;
private String contractId;
private String contractType;
private String buildType;
private String contractStatus;
private String archiveStatus;
private Integer version;
private Boolean valid;
private Integer groupNum;
private String customerId;
private String customerName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planInDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planOpenDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planStartDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planEndDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime planEnterDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realInDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realOpenDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realStartDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realEndDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realEnterDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realDecorateDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realReturnDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime realLeaveDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime terminateDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime changeEffectiveDate;
}

View File

@ -0,0 +1,21 @@
package com.longfor.c2.graphql.starter.client.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.longfor.types.DyAccountInfo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class DyAccountInfoResponse extends DyAccountInfo {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime statusUpdateTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime bindTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime openDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime closureDate;
}

View File

@ -0,0 +1,76 @@
package com.longfor.c2.graphql.starter.client.response;
import java.io.Serializable;
public class Response<D> implements Serializable {
private static final long serialVersionUID = 1L;
protected D data;
protected int code;
protected String msg;
protected String curTime;
protected transient boolean showLog = true;
public Response() {
}
public Response(D data) {
this.data = data;
}
public D getData() {
return this.data;
}
public int getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
public String getCurTime() {
return this.curTime;
}
public void setData(D data) {
this.data = data;
}
public void setCode(int code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setCurTime(String curTime) {
this.curTime = curTime;
}
public Response<D> code(int code) {
this.code = code;
return this;
}
public Response<D> msg(String msg) {
this.msg = msg;
return this;
}
public Response<D> curTime(String curTime) {
this.curTime = curTime;
return this;
}
public Response<D> data(D data) {
this.data = data;
return this;
}
}

View File

@ -1,4 +1,4 @@
package com.longfor.c2.graphql.starter.autoconfigure; package com.longfor.c2.graphql.starter.config;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.longfor.c2.graphql.starter.entity.AppSecretInfo; import com.longfor.c2.graphql.starter.entity.AppSecretInfo;

View File

@ -1,4 +1,4 @@
package com.longfor.c2.graphql.starter.autoconfigure; package com.longfor.c2.graphql.starter.config;
import javax.servlet.ReadListener; import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream; import javax.servlet.ServletInputStream;

View File

@ -0,0 +1,14 @@
package com.longfor.c2.graphql.starter.config;
import graphql.scalars.ExtendedScalars;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
@Configuration
public class GraphQlConfig {
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return wiringBuilder -> wiringBuilder.scalar(ExtendedScalars.GraphQLBigDecimal);
}
}

View File

@ -0,0 +1,9 @@
package com.longfor.c2.graphql.starter.customcontext;
import lombok.Data;
@Data
public class ContractInfoQueryKey {
private Integer shopId;
private String contractType; //合同类型 REALITY-招商合同,INNOVATE-创新合同,SQUARE-广场合同
}

View File

@ -1,8 +0,0 @@
package com.longfor.c2.graphql.starter.customcontext;
import lombok.Data;
@Data
public class ExtendElementQueryArgument {
private String type;
}

View File

@ -1,9 +0,0 @@
package com.longfor.c2.graphql.starter.customcontext;
import lombok.Data;
@Data
public class ExtendElementQueryKey {
private Integer id;
private ExtendElementQueryArgument arguments;
}

View File

@ -2,10 +2,13 @@ package com.longfor.c2.graphql.starter.customcontext;
import lombok.Data; import lombok.Data;
@Data import java.util.List;
public class ShopCustomContext {
private String extendElementTypeName;
public ShopCustomContext() { @Data
public class GlobalCustomContext {
private String extendElementTypeName;
private List<Integer> shopIds;
public GlobalCustomContext() {
} }
} }

View File

@ -3,11 +3,12 @@ package com.longfor.c2.graphql.starter.customcontext;
import com.netflix.graphql.dgs.context.DgsCustomContextBuilder; import com.netflix.graphql.dgs.context.DgsCustomContextBuilder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
//@Component
@Component @Component
public class ShopCustomerContextBuilder implements DgsCustomContextBuilder<ShopCustomContext> { public class GlobalCustomContextBuilder implements DgsCustomContextBuilder<GlobalCustomContext> {
@Override @Override
public ShopCustomContext build() { public GlobalCustomContext build() {
return new ShopCustomContext(); return new GlobalCustomContext();
} }
} }

View File

@ -1,33 +0,0 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.dataloaders.BaseShopInfoDataLoader;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.BaseShopInfo;
import com.longfor.types.Shop;
import com.netflix.graphql.dgs.*;
import org.dataloader.DataLoader;
import java.util.concurrent.CompletableFuture;
@DgsComponent
public class BaseShopInfoDataFetcher {
private final ShopService shopService;
public BaseShopInfoDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsData(parentType = DgsConstants.SHOP.TYPE_NAME, field = DgsConstants.SHOP.BaseShopInfo)
public CompletableFuture<BaseShopInfo> baseShopInfo(DgsDataFetchingEnvironment dfe) {
DataLoader<Integer, BaseShopInfo> shopDataLoader = dfe.getDataLoader(BaseShopInfoDataLoader.class);
Shop shop = dfe.getSource();
return shopDataLoader.load(shop.getShopId());
}
}

View File

@ -1,32 +0,0 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.c2.graphql.starter.services.ContractService;
import com.longfor.types.Contract;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsQuery;
import com.netflix.graphql.dgs.InputArgument;
import java.util.List;
import java.util.stream.Collectors;
@DgsComponent
public class ContractDataFetcher {
private final ContractService contractService;
public ContractDataFetcher(ContractService contractService) {
this.contractService = contractService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsQuery
public List<Contract> contracts(@InputArgument("titleFilter") String titleFilter) {
if (titleFilter == null) {
return contractService.contracts();
}
return contractService.contracts().stream().filter(s -> s.getTitle().contains(titleFilter)).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,54 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.ContractInfoQueryKey;
import com.longfor.c2.graphql.starter.customcontext.GlobalCustomContext;
import com.longfor.c2.graphql.starter.dataloaders.ContractInfoDataLoader;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ContractInfo;
import com.longfor.types.ShopInfo;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import com.netflix.graphql.dgs.InputArgument;
import com.netflix.graphql.dgs.context.DgsContext;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@DgsComponent
@Slf4j
public class ContractInfoDataFetcher {
private final ShopService shopService;
public ContractInfoDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
* contractType
* investmentContractInfo:招商店铺
* squareContractInfo:创新店铺
* innovateContractInfos:广场店铺
*/
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.ContractInfos)
public CompletableFuture<List<ContractInfo>> contractInfos(@InputArgument String contractType, DgsDataFetchingEnvironment dfe) {
GlobalCustomContext myCustomContext = DgsContext.getCustomContext(dfe);
List<Integer> shopIds = myCustomContext.getShopIds();
log.info("Dgs contractInfos List: ids={}, contractType={}", shopIds, contractType);
ShopInfo shopInfo = dfe.getSource();
DataLoader dataLoader = dfe.getDataLoader(ContractInfoDataLoader.class);
log.info("Dgs contractInfos List: shopInfo={}", shopInfo);
ContractInfoQueryKey queryKey = new ContractInfoQueryKey();
queryKey.setShopId(shopInfo.getShopId());
queryKey.setContractType(shopInfo.getShopType());
return dataLoader.load(queryKey);
}
}

View File

@ -0,0 +1,42 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.GlobalCustomContext;
import com.longfor.c2.graphql.starter.dataloaders.DyAccountInfoDataLoader;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ContractInfo;
import com.longfor.types.DyAccountInfo;
import com.longfor.types.ShopInfo;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import com.netflix.graphql.dgs.InputArgument;
import com.netflix.graphql.dgs.context.DgsContext;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@DgsComponent
@Slf4j
public class DyAccountInfoDataFetcher {
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
* contractType
* investmentContractInfo:招商店铺
* squareContractInfo:创新店铺
* innovateContractInfos:广场店铺
*/
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.DyAccountInfo)
public CompletableFuture<DyAccountInfo> dyAccountInfo(DgsDataFetchingEnvironment dfe) {
ShopInfo shopInfo = dfe.getSource();
log.info("DgsData dyAccountInfo List: shopId={}", shopInfo.getShopId());
DataLoader dataLoader = dfe.getDataLoader(DyAccountInfoDataLoader.class);
return dataLoader.load(shopInfo.getShopId());
}
}

View File

@ -1,57 +0,0 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.ExtendElementQueryArgument;
import com.longfor.c2.graphql.starter.customcontext.ExtendElementQueryKey;
import com.longfor.c2.graphql.starter.dataloaders.ExtendElementDataLoaderWithMappedKeys;
import com.longfor.c2.graphql.starter.services.ExtendElementService;
import com.longfor.types.ExtendElement;
import com.longfor.types.Shop;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import com.netflix.graphql.dgs.InputArgument;
import org.dataloader.DataLoader;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@DgsComponent
public class ExtendElementDataFetcher {
private final ExtendElementService extendElementService;
public ExtendElementDataFetcher(ExtendElementService extendElementService) {
this.extendElementService = extendElementService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsData(parentType = DgsConstants.SHOP.TYPE_NAME, field = DgsConstants.SHOP.ExtendElements)
public CompletableFuture<List<ExtendElement>> extendElements(@InputArgument("typeNameFilter") String typeNameFilter , DgsDataFetchingEnvironment dfe) {
// method 1: Use custom context to pass the arguments to data loader
// Shop shop = dfe.getSource();
// DataLoader<Integer, List<ExtendElement>> dataLoader = dfe.getDataLoader(ExtendElementDataLoaderWithCustomContext.class);
// ShopCustomContext customContext = DgsContext.getCustomContext(dfe);
// customContext.setExtendElementTypeName(typeNameFilter);
// return dataLoader.load(shop.getShopId());
// method 2: Use the mapped keys to pass the arguments to data loader
// 2.1 As passed ExtendElementQueryKey as key and dataloader accepts the Set<ExtendElementQueryKey, R> as parameters,
// Let's say we have keyA, keyB, keyC, and keyA holds the same value with keyB, then the downstream DataLoader will only have 2
// EntrySet, the query will be only 2
Shop shop = dfe.getSource();
DataLoader<ExtendElementQueryKey, List<ExtendElement>> dataLoader = dfe.getDataLoader(ExtendElementDataLoaderWithMappedKeys.class);
ExtendElementQueryArgument arg = new ExtendElementQueryArgument();
arg.setType(dfe.getExecutionStepInfo().getArgument("typeNameFilter"));
ExtendElementQueryKey queryKey = new ExtendElementQueryKey();
queryKey.setId(shop.getShopId());
queryKey.setArguments(arg);
return dataLoader.load(queryKey);
}
}

View File

@ -1,27 +0,0 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.services.ExtentService;
import com.longfor.types.Extent;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import java.util.List;
@DgsComponent
public class ExtentDataFetcher {
private final ExtentService extentService;
public ExtentDataFetcher(ExtentService extentService) {
this.extentService = extentService;
}
@DgsData(parentType = DgsConstants.SHOP.TYPE_NAME, field = DgsConstants.SHOP.Extents)
public List<Extent> extents(DgsDataFetchingEnvironment dfe){
Integer current = dfe.getExecutionStepInfo().getArgument("current");
Integer size = dfe.getExecutionStepInfo().getArgument("size");
List<Extent> extents = this.extentService.extents();
return extents;
}
}

View File

@ -0,0 +1,45 @@
package com.longfor.c2.graphql.starter.datafetchers;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.GlobalCustomContext;
import com.longfor.c2.graphql.starter.dataloaders.ShopBrandInfoDataLoader;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.BrandInfo;
import com.longfor.types.ContractInfo;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopInfo;
import com.netflix.graphql.dgs.*;
import com.netflix.graphql.dgs.context.DgsContext;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@DgsComponent
@Slf4j
public class ShopBrandInfoDataFetcher {
private final ShopService shopService;
public ShopBrandInfoDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.BrandInfos)
public CompletableFuture<List<BrandInfo>> shopBrandInfos(DgsDataFetchingEnvironment dfe) {
ShopInfo shopInfo = dfe.getSource();
log.info("DgsData shopBrandInfos List: shopId={}", shopInfo.getShopId());
DataLoader dataLoader = dfe.getDataLoader(ShopBrandInfoDataLoader.class);
CompletableFuture<List<ShopBrandInfo>> future = dataLoader.load(shopInfo.getShopId());
return future.thenApply(t -> t.stream().map(x-> BeanUtil.toBean(x, BrandInfo.class)).collect(Collectors.toList()));
}
}

View File

@ -1,35 +0,0 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.Shop;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsQuery;
import com.netflix.graphql.dgs.InputArgument;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.stream.Collectors;
@DgsComponent
@Slf4j
public class ShopDataFetcher {
private final ShopService shopService;
public ShopDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsQuery
public List<Shop> shops(@InputArgument("shopNameFilter") String shopNameFilter) {
if (shopNameFilter == null) {
return shopService.shops();
}
log.info("Query shops: shopNameFilter={}", shopNameFilter);
return shopService.shops().stream().collect(Collectors.toList());
}
}

View File

@ -0,0 +1,122 @@
package com.longfor.c2.graphql.starter.datafetchers;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.ContractInfoQueryKey;
import com.longfor.c2.graphql.starter.dataloaders.ContractInfoDataLoader;
import com.longfor.c2.graphql.starter.dataloaders.ShopBrandInfoDataLoader;
import com.longfor.c2.graphql.starter.dataloaders.ShopUnitInfoDataLoader;
import com.longfor.types.*;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@DgsComponent
@Slf4j
public class ShopFloorDataFetcher {
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.ShopFloors)
public CompletableFuture<List<ShopFloor>> shopFloor(DgsDataFetchingEnvironment dfe) {
DataLoader shopUnitInfoDataLoader = dfe.getDataLoader(ShopUnitInfoDataLoader.class);
DataLoader shopBrandsInfoDataLoader = dfe.getDataLoader(ShopBrandInfoDataLoader.class);
DataLoader shopContractInfoDataLoader = dfe.getDataLoader(ContractInfoDataLoader.class);
ShopInfo shopInfo = dfe.getSource();
ContractInfoQueryKey queryKey = new ContractInfoQueryKey();
queryKey.setShopId(shopInfo.getShopId());
queryKey.setContractType(shopInfo.getShopType());
log.info("DgsData shopFloor: shopId={}", shopInfo.getShopId());
CompletableFuture<List<ShopUnitInfo>> futureUnitInfos = shopUnitInfoDataLoader.load(shopInfo.getShopId());
CompletableFuture<List<ShopBrandInfo>> futureBrandInfos = shopBrandsInfoDataLoader.load(shopInfo.getShopId());
CompletableFuture<List<ContractInfo>> futureContracts = shopContractInfoDataLoader.load(queryKey);
return futureUnitInfos.thenCompose(unitInfos -> futureBrandInfos.thenCompose(brandInfos ->
futureContracts.thenApply(contracts ->
combineToShopFloor(unitInfos, brandInfos, contracts, shopInfo))));
}
private List<ShopFloor> combineToShopFloor(List<ShopUnitInfo> unitInfos, List<ShopBrandInfo> brandInfos, List<ContractInfo> contracts, ShopInfo shopInfo) {
if (CollectionUtils.isEmpty(unitInfos)) {
return null;
}
String projectId = shopInfo.getProjectId();
String projectName = shopInfo.getProjectName();
LocalDateTime updateTime = shopInfo.getUpdateTime();
String contractNo = contracts.stream().findFirst().map(ContractInfo::getContractNo).orElse("");
List<ShopFloor> shopFloors = new ArrayList<>();
if (CollectionUtils.isEmpty(brandInfos)) {
shopFloors = unitInfos.stream().map(unitInfo -> buildShopFloor(shopInfo, contractNo, projectId, projectName, updateTime, unitInfo)).collect(Collectors.toList());
} else {
List<ShopBrandInfo> newBrandInfos = adjustBrandFormat(brandInfos);
for (ShopUnitInfo unitInfo : unitInfos) {
for (ShopBrandInfo brandInfo : newBrandInfos) {
ShopFloor shopFloor = buildShopFloor(shopInfo, contractNo, projectId, projectName, updateTime, unitInfo);
shopFloor.setFormat1Id(brandInfo.getFormat1Id());
shopFloor.setFormat1Name(brandInfo.getFormat1Name());
shopFloor.setFormat2Id(brandInfo.getFormat2Id());
shopFloor.setFormat2Name(brandInfo.getFormat2Name());
shopFloor.setFormat3Id(brandInfo.getFormat3Id());
shopFloor.setFormat3Name(brandInfo.getFormat3Name());
shopFloors.add(shopFloor);
}
}
}
return shopFloors;
}
private ShopFloor buildShopFloor(ShopInfo shopInfo, String contractNo, String projectId, String projectName, LocalDateTime updateTime, ShopUnitInfo unitInfo) {
ShopFloor shopFloor = new ShopFloor();
shopFloor.setShopId(shopInfo.getShopId());
shopFloor.setContractNo(contractNo);
shopFloor.setProjectId(projectId);
shopFloor.setProjectName(projectName);
shopFloor.setBlockId(unitInfo.getBlockId());
shopFloor.setBlockName(unitInfo.getBlockName());
shopFloor.setFloorId(unitInfo.getFloorId());
shopFloor.setFloorNo(unitInfo.getFloorNo());
shopFloor.setUnitId(unitInfo.getUnitId());
shopFloor.setCreateTime(updateTime);
shopFloor.setUpdateTime(updateTime);
return shopFloor;
}
private List<ShopBrandInfo> adjustBrandFormat(List<ShopBrandInfo> brandInfos) {
if (CollectionUtils.isEmpty(brandInfos)) {
return null;
}
List<ShopBrandInfo> result = new ArrayList<>();
for (ShopBrandInfo brandInfo : brandInfos) {
ShopBrandInfo newBrandInfo = BeanUtil.toBean(brandInfo, ShopBrandInfo.class);
if (brandInfo.getLastLevel() != null && brandInfo.getLastLevel() == 2) {
newBrandInfo.setFormat1Id(brandInfo.getFormat2Id());
newBrandInfo.setFormat1Name(brandInfo.getFormat2Name());
newBrandInfo.setFormat2Id(brandInfo.getFormat3Id());
newBrandInfo.setFormat2Name(brandInfo.getFormat3Name());
newBrandInfo.setFormat3Id(null);
newBrandInfo.setFormat3Name(null);
}
if (brandInfo.getLastLevel() != null && brandInfo.getLastLevel() == 1) {
newBrandInfo.setFormat1Id(brandInfo.getFormat3Id());
newBrandInfo.setFormat1Name(brandInfo.getFormat3Name());
newBrandInfo.setFormat3Id(null);
newBrandInfo.setFormat3Name(null);
}
result.add(newBrandInfo);
}
return result;
}
}

View File

@ -0,0 +1,43 @@
package com.longfor.c2.graphql.starter.datafetchers;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.dataloaders.ShopBrandInfoDataLoader;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopFormatInfo;
import com.longfor.types.ShopInfo;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@DgsComponent
@Slf4j
public class ShopFormatInfoDataFetcher {
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.FormatInfo)
public CompletableFuture<ShopFormatInfo> shopFormatInfo(DgsDataFetchingEnvironment dfe) {
ShopInfo shopInfo = dfe.getSource();
log.info("DgsData shopFormatInfo: shopId={}", shopInfo.getShopId());
DataLoader dataLoader = dfe.getDataLoader(ShopBrandInfoDataLoader.class);
CompletableFuture<List<ShopBrandInfo>> future = dataLoader.load(shopInfo.getShopId());
return future.thenApply(t -> {
log.info("shopFormatInfo={}",t.toString());
Optional<ShopFormatInfo> formatInfo = t.stream().findFirst().map(x-> BeanUtil.toBean(x, ShopFormatInfo.class));
if (formatInfo.isPresent()) {
return formatInfo.get();
} else {
return null;
}
});
}
}

View File

@ -0,0 +1,53 @@
package com.longfor.c2.graphql.starter.datafetchers;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.c2.graphql.starter.client.ShopClient;
import com.longfor.c2.graphql.starter.client.request.PolymerShopInfoQueryReq;
import com.longfor.c2.graphql.starter.client.request.Request;
import com.longfor.c2.graphql.starter.client.response.BaseShopInfo;
import com.longfor.c2.graphql.starter.client.response.Response;
import com.longfor.c2.graphql.starter.customcontext.GlobalCustomContext;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ShopInfo;
import com.longfor.types.ShopUnitInfo;
import com.netflix.graphql.dgs.*;
import com.netflix.graphql.dgs.context.DgsContext;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.TypeRuntimeWiring;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@DgsComponent
@Slf4j
public class ShopInfoDataFetcher {
private final ShopService shopService;
public ShopInfoDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsQuery
public List<ShopInfo> shopInfos(@InputArgument("shopIds") List<Integer> shopIds, DgsDataFetchingEnvironment dfe) {
if (shopIds == null) {
return new ArrayList<ShopInfo>();
}
log.info("Query shopInfos: shopIds={}", shopIds);
GlobalCustomContext context = DgsContext.getCustomContext(dfe);
context.setShopIds(shopIds);
List<BaseShopInfo> baseShopInfos = shopService.getShops(shopIds);
List<ShopInfo> shopInfos = baseShopInfos.stream().map(t ->BeanUtil.toBean(t, ShopInfo.class)).collect(Collectors.toList());
return shopInfos;
}
}

View File

@ -0,0 +1,52 @@
package com.longfor.c2.graphql.starter.datafetchers;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.GlobalCustomContext;
import com.longfor.c2.graphql.starter.dataloaders.ShopUnitInfoDataLoader;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopInfo;
import com.longfor.types.ShopUnitInfo;
import com.netflix.graphql.dgs.DgsComponent;
import com.netflix.graphql.dgs.DgsData;
import com.netflix.graphql.dgs.DgsDataFetchingEnvironment;
import com.netflix.graphql.dgs.InputArgument;
import com.netflix.graphql.dgs.context.DgsContext;
import lombok.extern.slf4j.Slf4j;
import org.dataloader.DataLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@DgsComponent
@Slf4j
public class ShopUnitInfoDataFetcher {
private final ShopService shopService;
public ShopUnitInfoDataFetcher(ShopService shopService) {
this.shopService = shopService;
}
/**
* This datafetcher resolves the shows field on Query.
* It uses an @InputArgument to get the titleFilter from the Query if one is defined.
*/
@DgsData(parentType = DgsConstants.SHOPINFO.TYPE_NAME, field = DgsConstants.SHOPINFO.ShopUnitInfos)
public CompletableFuture<List<ShopUnitInfo>> shopUnitInfos(DgsDataFetchingEnvironment dfe) {
GlobalCustomContext myCustomContext = DgsContext.getCustomContext(dfe);
if (myCustomContext.getShopIds() == null) {
return CompletableFuture.completedFuture(new ArrayList<ShopUnitInfo>());
}
List<Integer> shopIds = myCustomContext.getShopIds();
log.info("DgsData shopUnitInfos List: shopIds={}", shopIds);
ShopInfo shopInfo= dfe.getSource();
DataLoader dataLoader = dfe.getDataLoader(ShopUnitInfoDataLoader.class);
return dataLoader.load(shopInfo.getShopId());
}
}

View File

@ -1,27 +0,0 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.c2.graphql.starter.services.BaseShopInfoService;
import com.longfor.types.BaseShopInfo;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.MappedBatchLoader;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@DgsDataLoader(name = "baseShopInfoData")
public class BaseShopInfoDataLoader implements MappedBatchLoader<Integer, BaseShopInfo> {
private final BaseShopInfoService baseShopInfoService;
public BaseShopInfoDataLoader(BaseShopInfoService baseShopInfoService){
this.baseShopInfoService = baseShopInfoService;
}
@Override
public CompletionStage<Map<Integer, BaseShopInfo>> load(Set<Integer> ShopIds) {
return CompletableFuture.supplyAsync(() -> baseShopInfoService.baseShopInfoForShop(new ArrayList<>(ShopIds)));
}
}

View File

@ -0,0 +1,48 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.c2.graphql.starter.customcontext.ContractInfoQueryKey;
import com.longfor.c2.graphql.starter.services.ContractService;
import com.longfor.types.ContractInfo;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@DgsDataLoader(name = "contractInfoDataLoader")
public class ContractInfoDataLoader implements MappedBatchLoaderWithContext<ContractInfoQueryKey, List<ContractInfo>> {
@Autowired
private ContractService contractService;
@Override
public CompletionStage<Map<ContractInfoQueryKey, List<ContractInfo>>> load(Set<ContractInfoQueryKey> set, BatchLoaderEnvironment batchLoaderEnvironment) {
Map<String, List<ContractInfoQueryKey>> groupedKeys = set.stream().collect(Collectors.groupingBy(ContractInfoQueryKey::getContractType, Collectors.toList()));
CompletableFuture<Map<ContractInfoQueryKey, List<ContractInfo>>> completableFuture = CompletableFuture.supplyAsync(() -> {
List<CompletableFuture<Map<Integer, List<ContractInfo>>>> futures = new ArrayList<>();
for (List<ContractInfoQueryKey> groupedKey : groupedKeys.values()) {
Set<Integer> shopIds = groupedKey.stream().map(ContractInfoQueryKey::getShopId).collect(Collectors.toSet());
String contractType = groupedKey.get(0).getContractType();
CompletableFuture<Map<Integer, List<ContractInfo>>> future = CompletableFuture.supplyAsync(() ->
contractService.contractInfos(shopIds.stream().collect(Collectors.toList()), contractType)
);
futures.add(future);
}
List<Map<Integer, List<ContractInfo>>> contractInfos = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
Map<ContractInfoQueryKey, List<ContractInfo>> mappedContracts = new HashMap<>();
int i = 0;
for (List<ContractInfoQueryKey> groupedKey : groupedKeys.values()) {
Map<Integer, List<ContractInfo>> contractInfo = contractInfos.get(i++);
for (ContractInfoQueryKey key : groupedKey) {
mappedContracts.put(key, contractInfo.get(key.getShopId()));
}
}
return mappedContracts;
});
return completableFuture;
}
}

View File

@ -0,0 +1,32 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.DyAccountInfo;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@DgsDataLoader(name = "dyAccountInfoDataLoader")
public class DyAccountInfoDataLoader implements MappedBatchLoaderWithContext<Integer, DyAccountInfo> {
@Autowired
private ShopService shopService;
@Override
public CompletionStage<Map<Integer, DyAccountInfo>> load(Set<Integer> set, BatchLoaderEnvironment batchLoaderEnvironment) {
return CompletableFuture.supplyAsync(() -> {
List<DyAccountInfo> dyAccountInfos= shopService.getDyAccountInfo(set.stream().collect(Collectors.toList()));
Map<Integer, List<DyAccountInfo>> mappedDyAccounts = dyAccountInfos.stream().collect(Collectors.groupingBy(DyAccountInfo::getShopId));
Map<Integer, DyAccountInfo> mappedDyAccount = mappedDyAccounts.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get(0)));
return mappedDyAccount;
});
}
}

View File

@ -1,39 +0,0 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.ShopCustomContext;
import com.longfor.c2.graphql.starter.services.ExtendElementService;
import com.longfor.types.ExtendElement;
import com.netflix.graphql.dgs.DgsDataLoader;
import com.netflix.graphql.dgs.context.DgsContext;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@DgsDataLoader(name = DgsConstants.SHOP.ExtendElements)
public class ExtendElementDataLoaderWithCustomContext implements MappedBatchLoaderWithContext<Integer, List<ExtendElement>> {
private final ExtendElementService extendElementService;
public ExtendElementDataLoaderWithCustomContext(ExtendElementService extendElementService) {
this.extendElementService = extendElementService;
}
@Override
public CompletionStage<Map<Integer, List<ExtendElement>>> load(Set<Integer> set, BatchLoaderEnvironment environment) {
// DataFetchingEnvironment environment = DataFetcherExceptionHandler.getEnvironment();
ShopCustomContext customContext = DgsContext.getCustomContext(environment);
String typeNameFilter = customContext.getExtendElementTypeName();
return CompletableFuture.supplyAsync(()-> {
List<ExtendElement> all = this.extendElementService.extendElements(typeNameFilter);
return set.stream().collect(Collectors.toMap(t -> t, t -> all));
} );
}
}

View File

@ -1,85 +0,0 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.DgsConstants;
import com.longfor.c2.graphql.starter.customcontext.ExtendElementQueryArgument;
import com.longfor.c2.graphql.starter.customcontext.ExtendElementQueryKey;
import com.longfor.c2.graphql.starter.services.ExtendElementService;
import com.longfor.types.ExtendElement;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
/**
* Showcase the query:
* query Shops {
* shops {
* shopId
* baseShopInfo {
* shopId
* shopName
* shopStatus
* }
* expandData: extendElements (typeNameFilter: "TypeA"){
* attId,code,type,value
* }
* expandData2: extendElements(typeNameFilter: "TypeB"){
* attId,code,type,value
* }
* }
* }
*/
@DgsDataLoader(name = DgsConstants.SHOP.ExtendElements)
public class ExtendElementDataLoaderWithMappedKeys implements MappedBatchLoaderWithContext<ExtendElementQueryKey, List<ExtendElement>> {
private final ExtendElementService extendElementService;
public ExtendElementDataLoaderWithMappedKeys(ExtendElementService extendElementService) {
this.extendElementService = extendElementService;
}
@Override
public CompletionStage<Map<ExtendElementQueryKey, List<ExtendElement>>> load(Set<ExtendElementQueryKey> set, BatchLoaderEnvironment environment) {
// groupBy arguments, so the query will hold the same argument with different shopId
Map<ExtendElementQueryArgument, List<ExtendElementQueryKey>> queryMap = set.stream().collect(Collectors.groupingBy(ExtendElementQueryKey::getArguments));
CompletableFuture<Map<ExtendElementQueryKey, List<ExtendElement>>> completableFuture = CompletableFuture.supplyAsync(() -> {
List<CompletableFuture<Map<Integer, List<ExtendElement>>>> futures = new ArrayList<>();
for (List<ExtendElementQueryKey> groupedKeys : queryMap.values()) {
Set<Integer> shopIds = groupedKeys.stream().map(ExtendElementQueryKey::getId).collect(Collectors.toSet());
ExtendElementQueryArgument argument = groupedKeys.get(0).getArguments();
CompletableFuture<Map<Integer, List<ExtendElement>>> future = CompletableFuture.supplyAsync(() ->
fetchExtendElements(shopIds.stream().collect(Collectors.toList()), argument)
);
futures.add(future);
}
List<Map<Integer, List<ExtendElement>>> elementResult = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
// rebuild querykey->result map
Map<ExtendElementQueryKey, List<ExtendElement>> mappedElements = new HashMap<>();
int i = 0;
for (List<ExtendElementQueryKey> groupedKeys : queryMap.values()) {
Map<Integer, List<ExtendElement>> result = elementResult.get(i++);
for (ExtendElementQueryKey key : groupedKeys) {
mappedElements.put(key, result.getOrDefault(key.getId(), new ArrayList<>()));
}
}
return mappedElements;
});
return completableFuture;
}
public Map<Integer, List<ExtendElement>> fetchExtendElements(List<Integer> ids, ExtendElementQueryArgument argument) {
List<ExtendElement> extendElementList =
ids.stream().map(id -> ExtendElement.newBuilder().attId(id).type(argument.getType()).build()).collect(Collectors.toList());
List<ExtendElement> finalExtendElementList = extendElementList.stream().filter(t -> !t.getType().equals("TypeB")).collect(Collectors.toList());
return finalExtendElementList.stream().collect(Collectors.toMap(ExtendElement::getAttId, t -> Arrays.asList(t)));
}
}

View File

@ -0,0 +1,33 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ShopBrandInfo;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@DgsDataLoader(name = "shopBrandInfoDataLoader")
public class ShopBrandInfoDataLoader implements MappedBatchLoaderWithContext<Integer, List<ShopBrandInfo>> {
private final ShopService shopService;
public ShopBrandInfoDataLoader(ShopService shopService) {
this.shopService = shopService;
}
@Override
public CompletionStage<Map<Integer, List<ShopBrandInfo>>> load(Set<Integer> set, BatchLoaderEnvironment batchLoaderEnvironment) {
List<Integer> shopIds = set.stream().collect(Collectors.toList());
return CompletableFuture.supplyAsync(() -> {
List<ShopBrandInfo> shopBrandInfos = shopService.getShopBrandInfo(shopIds);
return shopBrandInfos.stream().collect(Collectors.groupingBy(ShopBrandInfo::getShopId));
});
}
}

View File

@ -0,0 +1,33 @@
package com.longfor.c2.graphql.starter.dataloaders;
import com.longfor.c2.graphql.starter.customcontext.ContractInfoQueryKey;
import com.longfor.c2.graphql.starter.services.ContractService;
import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.ContractInfo;
import com.longfor.types.ShopUnitInfo;
import com.netflix.graphql.dgs.DgsDataLoader;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.MappedBatchLoaderWithContext;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
@DgsDataLoader(name = "shopUnitInfoDataLoader")
public class ShopUnitInfoDataLoader implements MappedBatchLoaderWithContext<Integer, List<ShopUnitInfo>> {
@Autowired
private ShopService shopService;
@Override
public CompletionStage<Map<Integer, List<ShopUnitInfo>>> load(Set<Integer> set, BatchLoaderEnvironment batchLoaderEnvironment) {
List<Integer> shopIds =
set.stream().collect(Collectors.toList());
return CompletableFuture.supplyAsync(() -> {
List<ShopUnitInfo> shopUnitInfos = shopService.getShopUnitInfo(shopIds);
return shopUnitInfos.stream().collect(Collectors.groupingBy(ShopUnitInfo::getShopId));
});
}
}

View File

@ -1,7 +1,7 @@
package com.longfor.c2.graphql.starter.filter; package com.longfor.c2.graphql.starter.filter;
import com.longfor.c2.graphql.starter.autoconfigure.ApiSignConfigLoad; import com.longfor.c2.graphql.starter.config.ApiSignConfigLoad;
import com.longfor.c2.graphql.starter.autoconfigure.CachedHttpServletRequestWrapper; import com.longfor.c2.graphql.starter.config.CachedHttpServletRequestWrapper;
import com.longfor.c2.graphql.starter.entity.AppSecretInfo; import com.longfor.c2.graphql.starter.entity.AppSecretInfo;
import com.longfor.c2.graphql.starter.entity.SignRequest; import com.longfor.c2.graphql.starter.entity.SignRequest;
import com.longfor.c2.graphql.starter.entity.ValidationResult; import com.longfor.c2.graphql.starter.entity.ValidationResult;

View File

@ -0,0 +1,41 @@
package com.longfor.c2.graphql.starter.scalars;
import com.netflix.graphql.dgs.DgsScalar;
import graphql.language.StringValue;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;
import org.jetbrains.annotations.NotNull;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@DgsScalar(name="DgsDateTime")
public class DateTimeScalar implements Coercing<LocalDateTime, String> {
@Override
public String serialize(@NotNull Object dataFetcherResult) throws CoercingSerializeException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if (dataFetcherResult instanceof LocalDateTime) {
return ((LocalDateTime) dataFetcherResult).format(formatter);
} else {
throw new CoercingSerializeException("Not a valid DateTime");
}
}
@Override
public @NotNull LocalDateTime parseValue(@NotNull Object input) throws CoercingParseValueException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(input.toString(), formatter);
}
@Override
public @NotNull LocalDateTime parseLiteral(@NotNull Object input) throws CoercingParseLiteralException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if (input instanceof StringValue) {
return LocalDateTime.parse(((StringValue) input).getValue(), formatter);
}
throw new CoercingParseLiteralException("Value is not a valid ISO date time");
}
}

View File

@ -1,10 +0,0 @@
package com.longfor.c2.graphql.starter.services;
import com.longfor.types.BaseShopInfo;
import java.util.List;
import java.util.Map;
public interface BaseShopInfoService {
Map<Integer, BaseShopInfo> baseShopInfoForShop(List<Integer> shopIds);
}

View File

@ -1,9 +1,11 @@
package com.longfor.c2.graphql.starter.services; package com.longfor.c2.graphql.starter.services;
import com.longfor.types.Contract; import com.longfor.types.ContractInfo;
import java.util.List; import java.util.List;
import java.util.Map;
public interface ContractService { public interface ContractService {
List<Contract> contracts();
Map<Integer, List<ContractInfo>> contractInfos(List<Integer> shopIds, String contractType);
} }

View File

@ -1,10 +0,0 @@
package com.longfor.c2.graphql.starter.services;
import com.longfor.types.ExtendElement;
import java.util.List;
public interface ExtendElementService {
List<ExtendElement> allExtendElements();
List<ExtendElement> extendElements(String typeName);
}

View File

@ -1,10 +0,0 @@
package com.longfor.c2.graphql.starter.services;
import com.longfor.types.Extent;
import java.util.List;
public interface ExtentService {
List<Extent> extents();
}

View File

@ -1,10 +1,33 @@
package com.longfor.c2.graphql.starter.services; package com.longfor.c2.graphql.starter.services;
import com.longfor.types.Contract; import com.longfor.c2.graphql.starter.client.response.BaseShopInfo;
import com.longfor.types.Shop; import com.longfor.types.DyAccountInfo;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopUnitInfo;
import java.util.List; import java.util.List;
public interface ShopService { public interface ShopService {
List<Shop> shops(); /**
* 获取商铺信息
* @param shopIds
* @return
*/
List<BaseShopInfo> getShops(List<Integer> shopIds);
/**
* 获取商铺单元信息
* @param shopIds
* @return
*/
List<ShopUnitInfo> getShopUnitInfo(List<Integer> shopIds);
/**
* 获取商铺品牌信息
* @param shopIds
* @return
*/
List<ShopBrandInfo> getShopBrandInfo(List<Integer> shopIds);
List<DyAccountInfo> getDyAccountInfo(List<Integer> shopIds);
} }

View File

@ -1,17 +0,0 @@
package com.longfor.c2.graphql.starter.services.impl;
import com.longfor.c2.graphql.starter.services.BaseShopInfoService;
import com.longfor.types.BaseShopInfo;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class BaseShopInfoServiceImpl implements BaseShopInfoService {
public Map<Integer, BaseShopInfo> baseShopInfoForShop(List<Integer> shopIds) {
Map<Integer, BaseShopInfo> map = shopIds.stream().collect(Collectors.toMap(shopId -> shopId, shopId -> BaseShopInfo.newBuilder().shopId(shopId).shopName("AAA" + shopId.toString()).build()));
return map;
}
}

View File

@ -1,17 +1,45 @@
package com.longfor.c2.graphql.starter.services.impl; package com.longfor.c2.graphql.starter.services.impl;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.c2.graphql.starter.client.ShopClient;
import com.longfor.c2.graphql.starter.client.request.PolymerShopInfoQueryReq;
import com.longfor.c2.graphql.starter.client.request.Request;
import com.longfor.c2.graphql.starter.client.response.ContractInfoResponse;
import com.longfor.c2.graphql.starter.client.response.Response;
import com.longfor.c2.graphql.starter.services.ContractService; import com.longfor.c2.graphql.starter.services.ContractService;
import com.longfor.types.ContractInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.longfor.types.Contract;
import java.util.Arrays; import java.util.*;
import java.util.List; import java.util.function.Supplier;
import java.util.stream.Collectors;
@Service @Service
public class ContractServiceImpl implements ContractService { public class ContractServiceImpl implements ContractService {
@Autowired
private ShopClient shopClient;
@Override @Override
public List<Contract> contracts() { public Map<Integer, List<ContractInfo>> contractInfos(List<Integer> shopIds, String contractType) {
return Arrays.asList( Contract.newBuilder().id(1).title("A1").build(), PolymerShopInfoQueryReq req = new PolymerShopInfoQueryReq();
Contract.newBuilder().id(2).title("B1").build()); req.setShopIds(shopIds);
Request request = new Request();
request.setData(req);
// TODO:Remove the hard code here
// 合同类型 REALITY-招商合同,INNOVATE-创新合同,SQUARE-广场合同
Map<String, Supplier<Response<List<ContractInfoResponse>>>> methodMap = new HashMap<>();
methodMap.put("REALITY", () -> shopClient.queryShopContractEntity(request));
methodMap.put("INNOVATE", () -> shopClient.queryShopInnovateContractEntity(request));
methodMap.put("SQUARE", () -> shopClient.queryShopSquareContractEntity(request));
Response<List<ContractInfoResponse>> response = methodMap.getOrDefault(contractType, () -> new Response<>(new ArrayList<>())).get();
List<ContractInfoResponse> contractInfos = response.getData();
if (contractInfos == null) {
return new HashMap<>();
}
return contractInfos.stream().filter(t->t.getValid()).map(t -> BeanUtil.toBean(t, ContractInfo.class)).collect(Collectors.groupingBy(ContractInfo::getShopId));
} }
} }

View File

@ -1,24 +0,0 @@
package com.longfor.c2.graphql.starter.services.impl;
import com.longfor.c2.graphql.starter.services.ExtendElementService;
import com.longfor.types.ExtendElement;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ExtendElementServiceImpl implements ExtendElementService {
@Override
public List<ExtendElement> allExtendElements() {
return Arrays.asList(ExtendElement.newBuilder().attId(1).code("A").type("TypeA").value("AA").build(),
ExtendElement.newBuilder().attId(2).code("B").type("TypeB").value("BB").build(),
ExtendElement.newBuilder().attId(3).code("C").type("TypeC").value("CC").build());
}
@Override
public List<ExtendElement> extendElements(String typeName) {
return allExtendElements().stream().filter(t -> typeName.equals(t.getType())).collect(Collectors.toList());
}
}

View File

@ -1,25 +0,0 @@
package com.longfor.c2.graphql.starter.services.impl;
import com.longfor.c2.graphql.starter.services.ExtentService;
import com.longfor.types.Extent;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class ExtentServiceImpl implements ExtentService {
@Override
public List<Extent> extents() {
return Arrays.asList(
Extent.newBuilder().attId(1).type("TypeA").code("A").value("A").build(),
Extent.newBuilder().attId(2).type("TypeB").code("B").value("B").build(),
Extent.newBuilder().attId(3).type("TypeC").code("C").value("C").build(),
Extent.newBuilder().attId(4).type("TypeA").code("A").value("A").build(),
Extent.newBuilder().attId(5).type("TypeB").code("B").value("B").build(),
Extent.newBuilder().attId(6).type("TypeC").code("C").value("C").build(),
Extent.newBuilder().attId(7).type("TypeA").code("A").value("A").build(),
Extent.newBuilder().attId(8).type("TypeB").code("B").value("B").build()
);
}
}

View File

@ -1,18 +1,73 @@
package com.longfor.c2.graphql.starter.services.impl; package com.longfor.c2.graphql.starter.services.impl;
import cn.hutool.core.bean.BeanUtil;
import com.longfor.c2.graphql.starter.client.ShopClient;
import com.longfor.c2.graphql.starter.client.request.PolymerShopInfoQueryReq;
import com.longfor.c2.graphql.starter.client.request.Request;
import com.longfor.c2.graphql.starter.client.response.BaseShopInfo;
import com.longfor.c2.graphql.starter.client.response.DyAccountInfoResponse;
import com.longfor.c2.graphql.starter.client.response.Response;
import com.longfor.c2.graphql.starter.services.ShopService; import com.longfor.c2.graphql.starter.services.ShopService;
import com.longfor.types.Shop; import com.longfor.types.DyAccountInfo;
import com.longfor.types.ShopBrandInfo;
import com.longfor.types.ShopUnitInfo;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@Service @Service
public class ShopServiceImpl implements ShopService { public class ShopServiceImpl implements ShopService {
private final ShopClient shopClient;
public ShopServiceImpl(ShopClient shopClient) {
this.shopClient = shopClient;
}
@Override @Override
public List<Shop> shops() { public List<BaseShopInfo> getShops(List<Integer> shopIds) {
return Arrays.asList( Shop.newBuilder().shopId(1).build(), PolymerShopInfoQueryReq req = createPolymerShopInfoQueryReq(shopIds);
Shop.newBuilder().shopId(2).build()); Response<List<BaseShopInfo>> response = shopClient.queryBaseShopInfo(createRequest(req));
return response.getData();
}
@Override
public List<ShopUnitInfo> getShopUnitInfo(List<Integer> shopIds) {
PolymerShopInfoQueryReq req = createPolymerShopInfoQueryReq(shopIds);
Response<List<ShopUnitInfo>> response = shopClient.queryShopUnitInfo(createRequest(req));
return response.getData();
}
@Override
public List<ShopBrandInfo> getShopBrandInfo(List<Integer> shopIds) {
PolymerShopInfoQueryReq req = createPolymerShopInfoQueryReq(shopIds);
Response<List<ShopBrandInfo>> response = shopClient.queryShopBrandInfos(createRequest(req));
return response.getData();
}
@Override
public List<DyAccountInfo> getDyAccountInfo(List<Integer> shopIds) {
PolymerShopInfoQueryReq req = createPolymerShopInfoQueryReq(shopIds);
Response<List<DyAccountInfoResponse>> response = shopClient.queryDyAccountInfo(createRequest(req));
List<DyAccountInfoResponse> data = response.getData();
List<DyAccountInfo> dyAccountInfos = data.stream()
.map(t -> BeanUtil.toBean(t, DyAccountInfo.class))
.collect(Collectors.toList());
return dyAccountInfos;
}
// Extract common logic to create PolymerShopInfoQueryReq object
private PolymerShopInfoQueryReq createPolymerShopInfoQueryReq(List<Integer> shopIds) {
PolymerShopInfoQueryReq req = new PolymerShopInfoQueryReq();
req.setShopIds(shopIds);
return req;
}
// Extract common logic to create Request object
private <T> Request<T> createRequest(T data) {
Request<T> request = new Request<>();
request.setData(data);
return request;
} }
} }

View File

@ -1 +0,0 @@

View File

View File

@ -1,41 +1,8 @@
type Query { type Query {
contracts(titleFilter: String): [Contract] shopInfos(shopIds: [Int]):[ShopInfo]
shops(shopNameFilter: String):[Shop!]!
} }
type Contract {
id: Int
title: String @uppercase
releaseYear: Int
}
type Shop{
shopId: Int
baseShopInfo:BaseShopInfo
extendElements(typeNameFilter: String): [ExtendElement]
extents(current: Int!,size: Int!): [Extent]
}
type BaseShopInfo{
shopId: Int
shopName: String
shopStatus: String
}
type ExtendElement{
attId: Int
code:String
type : String
value: String
}
# for Paging
type Extent @connection{
attId: Int
code:String
type : String
value: String
}
#scalar DateTime #scalar DateTime
directive @skipcodegen on FIELD_DEFINITION directive @skipcodegen on FIELD_DEFINITION

View File

@ -0,0 +1,168 @@
type ShopInfo{
# 店铺id
shopId:Int
# 店铺名称
shopName:String
# 店铺状态
shopStatus: String
# 店铺有效性10A10B
shopValidity: String
# 店铺类型
shopType: String
# 店铺所属项目
projectId:String
# 项目名称
projectName:String
# 店铺面积
shopArea:BigDecimal
createTime:DgsDateTime
updateTime:DgsDateTime
# 预计开始时间
planInDate:DgsDateTime
# 预计开业时间
planOpenDate:DgsDateTime
# 预计开始时间
planStartDate:DgsDateTime
# 预计结束时间
planEndDate:DgsDateTime
# 实际开始时间
realInDate:DgsDateTime
# 实际开业时间
realOpenDate:DgsDateTime
# 实际开始时间
realStartDate:DgsDateTime
# 实际结束时间
realEndDate:DgsDateTime
# 接铺时间
receiveDate:DgsDateTime
# 主业态id
formatId:String
# 主业态名称
formatName:String
formatInfo:FormatInfo
brandInfos:[BrandInfo]
shopUnitInfos:[ShopUnitInfo]
shopFloors:[ShopFloor]
# investmentContractInfo:招商店铺
# squareContractInfo:创新店铺
# innovateContractInfos:广场店铺
contractInfos(contractType:String): [ContractInfo]
dyAccountInfo:DyAccountInfo
}
type ShopBrandInfo{
shopId:Int
brandId:String
brandName:String
brandEnName:String
lastLevel:Int
format1Id:String
format1Name:String
format2Id:String
format2Name:String
format3Id:String
format3Name:String
}
type FormatInfo {
format1Id:String
format1Name:String
format2Id:String
format2Name:String
format3Id:String
format3Name:String
}
type BrandInfo{
brandId:String
brandName:String
brandEnName:String
}
type ShopUnitInfo {
shopId: Int
unitId:String
unitNo:String
blockId:String
blockNo:String
blockName:String
floorId:String
floorNo:String
floorName:String
status:String
}
type ShopFloor{
shopId:Int
contractNo:String
projectId:String
projectName:String
blockId:String
blockName:String
floorId:String
floorNo:String
isFloorNoBelong:Int
shopFloorCount:Int
unitId:String
format1Id:String
format1Name:String
format2Id:String
format2Name:String
format3Id:String
format3Name:String
createTime:DgsDateTime
updateTime:DgsDateTime
}
type ContractInfo{
shopId: Int
contractNo:String
contractId:String
contractType:String
buildType:String
contractStatus:String
archiveStatus:String
version:Int
valid:Boolean
groupNum:Int
customerId:String
customerName:String
planInDate:DgsDateTime
planOpenDate:DgsDateTime
planStartDate:DgsDateTime
planEndDate:DgsDateTime
planEnterDate:DgsDateTime
realInDate:DgsDateTime
realOpenDate:DgsDateTime
realStartDate:DgsDateTime
realEndDate:DgsDateTime
realEnterDate:DgsDateTime
realDecorateDate:DgsDateTime
realReturnDate:DgsDateTime
realLeaveDate:DgsDateTime
terminateDate:DgsDateTime
changeEffectiveDate:DgsDateTime
}
type DyAccountInfo{
shopId: Int
accountNo:String
accountName:String
shortAccountName:String
status:String
statusUpdateTime:DgsDateTime
bindId:String
bindTime:DgsDateTime
openDate:DgsDateTime
closureDate:DgsDateTime
dyProducts:[DyProductInfo]
}
type DyProductInfo{
shopId: Int
prdName:String
prdCode:String
prdRate:String
}
scalar BigDecimal
scalar DgsDateTime