Skip to content

Commit 4681063

Browse files
committed
add/air-table
1 parent cc0e85d commit 4681063

19 files changed

+444
-2
lines changed

src/app.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { FileModule } from "./modules/file/file.module";
1919
import { AppController } from "./app.controller";
2020
import { ContactModule } from "./modules/contact/contact.module";
2121
import { ApiModule } from "./modules/api/api.module";
22+
import { AirMonitorModule } from './modules/air-monitor/air-monitor.module';
23+
import { DeviceModule } from './modules/device/device.module';
2224

2325
@Module({
2426
imports: [
@@ -64,6 +66,8 @@ import { ApiModule } from "./modules/api/api.module";
6466
FileModule,
6567
ContactModule,
6668
ApiModule,
69+
AirMonitorModule,
70+
DeviceModule,
6771
],
6872
controllers: [AppController],
6973
providers: [],
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from "@nestjs/common";
2+
import { ApiModule } from "../api/api.module";
3+
import { AirMonitorResolver } from "./air-monitor.resolver";
4+
import { AirMonitorService } from "./air-monitor.service";
5+
6+
@Module({
7+
providers: [AirMonitorService, AirMonitorResolver],
8+
imports: [ApiModule],
9+
})
10+
export class AirMonitorModule {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { UseGuards } from "@nestjs/common";
2+
import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
3+
import { Roles } from "../../decorators/roles/roles.decorator";
4+
import { Role } from "../../utils/types/role.enum";
5+
import { JwtAuthGuard } from "../../guards/auth/auth.guard";
6+
import { AirMonitorService } from "./air-monitor.service";
7+
import { AirMonitorDataResponse } from "./entities/air-monitor.entity";
8+
import { AirMonitorInput } from "./dto/input.dto";
9+
import { AirMonitorsResponse } from "./entities/air-monitors.entity";
10+
import { QueryInput } from "./dto/query.dto";
11+
12+
@Resolver()
13+
export class AirMonitorResolver {
14+
constructor(private readonly airMonitorService: AirMonitorService) {}
15+
16+
@Query(() => AirMonitorsResponse)
17+
async allMonitors(@Args("filter", { nullable: true }) filter?: QueryInput) {
18+
return this.airMonitorService.allData(filter);
19+
}
20+
21+
@Mutation(() => AirMonitorDataResponse)
22+
@UseGuards(JwtAuthGuard)
23+
@Roles(Role.Admin)
24+
async create_monitor(@Args("input") input: AirMonitorInput) {
25+
return this.airMonitorService.create(input);
26+
}
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Injectable } from "@nestjs/common";
2+
import { AirMonitorApiService } from "../api/air-monitor.service";
3+
import { AirMonitorInput } from "./dto/input.dto";
4+
import { GraphQLError } from 'graphql';
5+
import { AirMonitorsResponse } from "./entities/air-monitors.entity";
6+
7+
@Injectable()
8+
export class AirMonitorService {
9+
constructor(private readonly airMonitorApi: AirMonitorApiService) {}
10+
11+
async create(input: AirMonitorInput) {
12+
try {
13+
const data = await this.airMonitorApi.createMonitorApi(input);
14+
if (data) {
15+
return data;
16+
}
17+
} catch (err) {
18+
throw new Error(err);
19+
}
20+
}
21+
22+
async allData(filter: { page: number; perPage: number }): Promise<AirMonitorsResponse> {
23+
try {
24+
const data = await this.airMonitorApi.queryAllAirMonitorData(filter) as AirMonitorsResponse;
25+
console.log('***', data)
26+
if (data) return data;
27+
} catch (err) {
28+
throw new GraphQLError(err)
29+
}
30+
}
31+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
import { Field, InputType } from '@nestjs/graphql';
3+
import { IsNumber, IsOptional, IsString } from 'class-validator';
4+
@InputType()
5+
export class AirMonitorInput {
6+
@Field(() => String)
7+
@IsString()
8+
@IsOptional()
9+
serial_num: string;
10+
11+
@Field(() => Number)
12+
@IsNumber()
13+
@IsOptional()
14+
co2: number;
15+
16+
@Field(() => Number)
17+
@IsNumber()
18+
@IsOptional()
19+
aqi: number;
20+
21+
@Field(() => Number)
22+
@IsNumber()
23+
@IsOptional()
24+
humid: number;
25+
26+
@Field(() => Number)
27+
@IsNumber()
28+
@IsOptional()
29+
pm1: number;
30+
31+
@Field(() => Number)
32+
@IsNumber()
33+
@IsOptional()
34+
pm25: number;
35+
36+
@Field(() => Number)
37+
@IsNumber()
38+
@IsOptional()
39+
pm10: number;
40+
41+
@Field(() => Number)
42+
@IsNumber()
43+
@IsOptional()
44+
tvoc: number;
45+
46+
@Field(() => Number)
47+
@IsNumber()
48+
@IsOptional()
49+
tem: number;
50+
51+
@Field(() => Number)
52+
@IsNumber()
53+
@IsOptional()
54+
hcho: number;
55+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Field, InputType, Int } from "@nestjs/graphql";
2+
3+
@InputType()
4+
export class QueryInput {
5+
@Field(() => Int)
6+
page: number;
7+
8+
@Field(() => Int)
9+
perPage: number;
10+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Field, ObjectType } from "@nestjs/graphql";
2+
import { IsDate, IsString } from "class-validator";
3+
@ObjectType()
4+
export class AirMonitorDataResponse {
5+
@Field(() => Number, { nullable: false })
6+
id: number;
7+
8+
@Field(() => String)
9+
@IsString()
10+
serial_num: string;
11+
12+
@Field(() => String, { nullable: true })
13+
created_date: string;
14+
15+
@Field(() => Number, { nullable: true })
16+
co2: number;
17+
18+
@Field(() => Number, { nullable: true })
19+
aqi: number;
20+
21+
@Field(() => Number, { nullable: true })
22+
humid: number;
23+
24+
@Field(() => Number, { nullable: true })
25+
pm1: number;
26+
27+
@Field(() => Number, { nullable: true })
28+
pm25: number;
29+
30+
@Field(() => Number, { nullable: true })
31+
pm10: number;
32+
33+
@Field(() => Number, { nullable: true })
34+
tvoc: number;
35+
36+
@Field(() => Number, { nullable: true })
37+
tem: number;
38+
39+
@Field(() => Number, { nullable: true })
40+
hcho: number;
41+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Field, ObjectType } from "@nestjs/graphql";
2+
import { PaginateInfo } from "../../../common/dto/paginateInfo.response";
3+
import { AirMonitorDataResponse } from "./air-monitor.entity";
4+
5+
@ObjectType()
6+
export class AirMonitorsResponse {
7+
@Field(() => [AirMonitorDataResponse], {nullable: true})
8+
devices: AirMonitorDataResponse[];
9+
10+
@Field(() => PaginateInfo, { nullable: true })
11+
paginateInfo: PaginateInfo;
12+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { HttpService } from "@nestjs/axios";
2+
import { Injectable } from "@nestjs/common";
3+
import { catchError, firstValueFrom } from "rxjs";
4+
import { ConfigService } from "@nestjs/config";
5+
import { AxiosError } from "axios";
6+
import { AirMonitorDataResponse } from "../air-monitor/entities/air-monitor.entity";
7+
import { AirMonitorInput } from "../air-monitor/dto/input.dto";
8+
import { AirMonitorsResponse } from "../air-monitor/entities/air-monitors.entity";
9+
10+
@Injectable()
11+
export class AirMonitorApiService {
12+
constructor(
13+
private readonly httpService: HttpService,
14+
private config: ConfigService,
15+
) {}
16+
private readonly base_url = this.config.get("API_BASE_URL");
17+
18+
async createMonitorApi(params: AirMonitorInput): Promise<AirMonitorDataResponse> {
19+
const { data } = await firstValueFrom(
20+
this.httpService.post(`${this.base_url}/air-monitor/create`, params).pipe(
21+
catchError((err: AxiosError) => {
22+
throw err;
23+
}),
24+
),
25+
);
26+
return data;
27+
}
28+
29+
async queryAllAirMonitorData(filter: { page: number; perPage: number }): Promise<AirMonitorsResponse> {
30+
const { data } = await firstValueFrom(
31+
this.httpService.get(`${this.base_url}/air-monitor/all`, { params: { filter } }).pipe(
32+
catchError((err: AxiosError) => {
33+
throw err;
34+
}),
35+
),
36+
);
37+
return data;
38+
}
39+
}

src/modules/api/api.module.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import { BlogApiService } from "./blog-api.service";
66
import { ProductApiService } from "./product-api.service";
77
import { OrderApiService } from "./order-api.service";
88
import { ContactApiService } from "./contact-api.service";
9+
import { AirMonitorApiService } from "./air-monitor.service";
10+
import { DeviceApiService } from "./device.service";
911

1012
@Module({
11-
providers: [AuthApiService, BlogApiService, ProductApiService, OrderApiService, ContactApiService],
13+
providers: [AuthApiService, BlogApiService, ProductApiService, OrderApiService, ContactApiService, AirMonitorApiService, DeviceApiService],
1214
imports: [HttpModule],
13-
exports: [AuthApiService, BlogApiService, ProductApiService, OrderApiService, ContactApiService],
15+
exports: [AuthApiService, BlogApiService, ProductApiService, OrderApiService, ContactApiService, AirMonitorApiService, DeviceApiService],
1416
})
1517
export class ApiModule {}

src/modules/api/device.service.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { HttpService } from "@nestjs/axios";
2+
import { Injectable } from "@nestjs/common";
3+
import { catchError, firstValueFrom } from "rxjs";
4+
import { ConfigService } from "@nestjs/config";
5+
import { AxiosError } from "axios";
6+
import { DeviceResponse } from "../device/entities/device.entity";
7+
import { CreateItemInput, UpdateItemInput } from "../device/dto/input.dto";
8+
import { DevicesResponse } from "../device/dto/response.dto";
9+
10+
@Injectable()
11+
export class DeviceApiService {
12+
constructor(
13+
private readonly httpService: HttpService,
14+
private config: ConfigService,
15+
) {}
16+
private readonly base_url = this.config.get("API_BASE_URL");
17+
18+
async allDevices(filter: { page: number; perPage: number }): Promise<DevicesResponse> {
19+
const { data } = await firstValueFrom(
20+
this.httpService.get(`${this.base_url}/item/all-items`, { params: { filter } }).pipe(
21+
catchError((err: AxiosError) => {
22+
throw err;
23+
}),
24+
),
25+
);
26+
return data;
27+
}
28+
29+
async createDevice(params: CreateItemInput): Promise<DeviceResponse> {
30+
const { data } = await firstValueFrom(
31+
this.httpService.post(`${this.base_url}/item/create`, params).pipe(
32+
catchError((err: AxiosError) => {
33+
throw err;
34+
}),
35+
),
36+
);
37+
return data;
38+
}
39+
40+
async updateBlogApi(params: UpdateItemInput, deviceID: number): Promise<DeviceResponse> {
41+
const { data } = await firstValueFrom(
42+
this.httpService.patch(`${this.base_url}/item/${deviceID}`, params).pipe(
43+
catchError((err: AxiosError) => {
44+
throw err;
45+
}),
46+
),
47+
);
48+
return data;
49+
}
50+
}

src/modules/authenticate/authenticate.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ export class AuthenticateService {
4646
const res = await this.authApiService.register(registerAuthenticateInput);
4747
if (!res) {
4848
}
49+
console.log(res)
4950
return res;
5051
} catch (error) {
52+
console.log(error)
5153
throw error;
5254
}
5355
}

src/modules/device/device.module.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from "@nestjs/common";
2+
import { ApiModule } from "../api/api.module";
3+
import { DeviceResolver } from "./device.resolver";
4+
import { DeviceService } from "./device.service";
5+
6+
@Module({
7+
providers: [DeviceResolver, DeviceService],
8+
imports: [ApiModule],
9+
})
10+
export class DeviceModule {}

src/modules/device/device.resolver.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { UseGuards } from "@nestjs/common";
2+
import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
3+
import { Roles } from "../../decorators/roles/roles.decorator";
4+
import { JwtAuthGuard } from "../../guards/auth/auth.guard";
5+
import { Role } from "../../utils/types/role.enum";
6+
import { DeviceService } from "./device.service";
7+
import { CreateItemInput, UpdateItemInput } from "./dto/input.dto";
8+
import { DeviceQueryInput } from "./dto/query.dto";
9+
import { DevicesResponse } from "./dto/response.dto";
10+
import { DeviceResponse } from "./entities/device.entity";
11+
12+
@Resolver()
13+
export class DeviceResolver {
14+
constructor(private deviceService: DeviceService) {}
15+
16+
@Query(() => DevicesResponse)
17+
async all_devices(@Args("filter", { nullable: true }) filter?: DeviceQueryInput) {
18+
const data = await this.deviceService.all(filter);
19+
return data || [];
20+
}
21+
22+
@Mutation(() => DeviceResponse)
23+
@UseGuards(JwtAuthGuard)
24+
@Roles(Role.Admin)
25+
async create_device (@Args("input") input: CreateItemInput) {
26+
return this.deviceService.create(input);
27+
}
28+
29+
@Mutation(() => DeviceResponse)
30+
@Roles(Role.Admin)
31+
@UseGuards(JwtAuthGuard)
32+
async update_device (@Args("id") id: number, @Args("input") input: UpdateItemInput) {
33+
return this.deviceService.update(input, id);
34+
}
35+
}

0 commit comments

Comments
 (0)