Trần Viết Sơn commited on
Commit
1f7602b
2 Parent(s): be22897 b7a6e24

Merge branch 'main' of https://github.com/PBL6-team-CATS/PBL6-informative-system

Browse files
backend/package-lock.json CHANGED
@@ -31,7 +31,8 @@
31
  "pg": "^8.13.0",
32
  "reflect-metadata": "^0.2.0",
33
  "rxjs": "^7.8.1",
34
- "typeorm": "^0.3.20"
 
35
  },
36
  "devDependencies": {
37
  "@nestjs/cli": "^10.0.0",
@@ -7138,6 +7139,27 @@
7138
  "mkdirp": "bin/cmd.js"
7139
  }
7140
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7141
  "node_modules/ms": {
7142
  "version": "2.1.3",
7143
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -9594,6 +9616,7 @@
9594
  "version": "0.3.20",
9595
  "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz",
9596
  "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==",
 
9597
  "dependencies": {
9598
  "@sqltools/formatter": "^1.2.5",
9599
  "app-root-path": "^3.1.0",
@@ -9878,6 +9901,16 @@
9878
  "node": ">= 0.8"
9879
  }
9880
  },
 
 
 
 
 
 
 
 
 
 
9881
  "node_modules/walker": {
9882
  "version": "1.0.8",
9883
  "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
 
31
  "pg": "^8.13.0",
32
  "reflect-metadata": "^0.2.0",
33
  "rxjs": "^7.8.1",
34
+ "typeorm": "^0.3.20",
35
+ "vnpay": "^1.6.0"
36
  },
37
  "devDependencies": {
38
  "@nestjs/cli": "^10.0.0",
 
7139
  "mkdirp": "bin/cmd.js"
7140
  }
7141
  },
7142
+ "node_modules/moment": {
7143
+ "version": "2.30.1",
7144
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
7145
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
7146
+ "license": "MIT",
7147
+ "engines": {
7148
+ "node": "*"
7149
+ }
7150
+ },
7151
+ "node_modules/moment-timezone": {
7152
+ "version": "0.5.46",
7153
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.46.tgz",
7154
+ "integrity": "sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==",
7155
+ "license": "MIT",
7156
+ "dependencies": {
7157
+ "moment": "^2.29.4"
7158
+ },
7159
+ "engines": {
7160
+ "node": "*"
7161
+ }
7162
+ },
7163
  "node_modules/ms": {
7164
  "version": "2.1.3",
7165
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
 
9616
  "version": "0.3.20",
9617
  "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz",
9618
  "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==",
9619
+ "license": "MIT",
9620
  "dependencies": {
9621
  "@sqltools/formatter": "^1.2.5",
9622
  "app-root-path": "^3.1.0",
 
9901
  "node": ">= 0.8"
9902
  }
9903
  },
9904
+ "node_modules/vnpay": {
9905
+ "version": "1.6.0",
9906
+ "resolved": "https://registry.npmjs.org/vnpay/-/vnpay-1.6.0.tgz",
9907
+ "integrity": "sha512-+y1tdsJ1ClPC0cVGCG6v5lDi5rZZSzfUe1I670d4tqzxvHdgPbgmrYuH4LpLOEuiFs0Nwum9Thw7DfWgbztjBA==",
9908
+ "hasInstallScript": true,
9909
+ "license": "MIT",
9910
+ "dependencies": {
9911
+ "moment-timezone": "^0.5.43"
9912
+ }
9913
+ },
9914
  "node_modules/walker": {
9915
  "version": "1.0.8",
9916
  "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
backend/package.json CHANGED
@@ -47,7 +47,8 @@
47
  "pg": "^8.13.0",
48
  "reflect-metadata": "^0.2.0",
49
  "rxjs": "^7.8.1",
50
- "typeorm": "^0.3.20"
 
51
  },
52
  "devDependencies": {
53
  "@nestjs/cli": "^10.0.0",
 
47
  "pg": "^8.13.0",
48
  "reflect-metadata": "^0.2.0",
49
  "rxjs": "^7.8.1",
50
+ "typeorm": "^0.3.20",
51
+ "vnpay": "^1.6.0"
52
  },
53
  "devDependencies": {
54
  "@nestjs/cli": "^10.0.0",
backend/src/common/enums/VnpCardType.enum.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ export enum VnpCardType {
2
+ None = 0,
3
+ ATM = 1,
4
+ QRCODE = 2
5
+ }
backend/src/entities/payment.entity.ts CHANGED
@@ -7,7 +7,6 @@ import {
7
  Relation,
8
  } from 'typeorm';
9
  import { OrderEntity } from './order.entity.js';
10
- import { PaymentMethod } from '../common/enums/PaymentMethod.enum.js';
11
 
12
  @Entity('payments')
13
  export class PaymentEntity extends BaseEntity {
@@ -18,8 +17,32 @@ export class PaymentEntity extends BaseEntity {
18
  order: Relation<OrderEntity>;
19
 
20
  @Column({ default: 0 })
21
- payment_method: number; // E.g., 'Cash', 'Credit Card', 'Online Payment'
22
 
23
  @Column()
24
- value: number;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
 
7
  Relation,
8
  } from 'typeorm';
9
  import { OrderEntity } from './order.entity.js';
 
10
 
11
  @Entity('payments')
12
  export class PaymentEntity extends BaseEntity {
 
17
  order: Relation<OrderEntity>;
18
 
19
  @Column({ default: 0 })
20
+ payment_method: number;
21
 
22
  @Column()
23
+ vnp_amount: number
24
+
25
+ @Column({ nullable: true })
26
+ vnp_bank_code: string
27
+
28
+ @Column({ nullable: true })
29
+ vnp_bank_tran_no:string
30
+
31
+ @Column({ default: 0})
32
+ vnp_card_type: number
33
+
34
+ @Column({ nullable: true })
35
+ vnp_order_info: string //Nội dung giao dịch
36
+
37
+ @Column({ nullable: true })
38
+ vnp_paydate: string
39
+
40
+ @Column({ nullable: true })
41
+ vnp_response_code: number
42
+
43
+ @Column({ nullable: true })
44
+ vnp_transaction_no: string
45
+
46
+ @Column({ nullable: true })
47
+ vnp_transaction_status: number
48
  }
backend/src/migrations/1730651201156-modify_payment.ts ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class ModifyPayment1730651201156 implements MigrationInterface {
4
+ name = 'ModifyPayment1730651201156'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "value"`);
8
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_amount" integer NOT NULL`);
9
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_bank_code" character varying`);
10
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_bank_tran_no" character varying`);
11
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_card_type" integer NOT NULL DEFAULT '0'`);
12
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_order_info" character varying`);
13
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_paydate" character varying`);
14
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_response_code" integer`);
15
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_transaction_no" character varying`);
16
+ await queryRunner.query(`ALTER TABLE "payments" ADD "vnp_transaction_status" integer`);
17
+ }
18
+
19
+ public async down(queryRunner: QueryRunner): Promise<void> {
20
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_transaction_status"`);
21
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_transaction_no"`);
22
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_response_code"`);
23
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_paydate"`);
24
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_order_info"`);
25
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_card_type"`);
26
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_bank_tran_no"`);
27
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_bank_code"`);
28
+ await queryRunner.query(`ALTER TABLE "payments" DROP COLUMN "vnp_amount"`);
29
+ await queryRunner.query(`ALTER TABLE "payments" ADD "value" integer NOT NULL`);
30
+ }
31
+
32
+ }
backend/src/modules/user/user.controller.ts CHANGED
@@ -1,17 +1,27 @@
1
- import { Body, Controller, Get, Param, Post, Request } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
3
  import { UserEntity } from 'src/entities/user.entity.js';
4
- import { UpdateUserDto } from './dto/update-user-dto.js';
 
 
5
 
6
  @Controller('users')
7
  export class UsersController {
8
  constructor(private readonly usersService: UserService) {}
9
 
10
- @Get(':username')
11
- async getUser(
12
- @Param('username') username: string,
 
13
  ): Promise<UserEntity | undefined> {
14
- return this.usersService.findOne(username);
 
 
 
 
 
 
 
15
  }
16
 
17
  @Post('updateUser')
@@ -20,4 +30,17 @@ export class UsersController {
20
  const updateUserDto = req.body;
21
  return this.usersService.updateUserById(userId, updateUserDto);
22
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
 
1
+ import { Body, Controller, Get, Param, Post, Query, Request } from '@nestjs/common';
2
  import { UserService } from './user.service.js';
3
  import { UserEntity } from 'src/entities/user.entity.js';
4
+ import { Roles } from '../authentication/authorization/roles.decorator.js';
5
+ import { Role } from '../../common/enums/role.enum.js';
6
+ import { Paginate, PaginateQuery } from 'nestjs-paginate';
7
 
8
  @Controller('users')
9
  export class UsersController {
10
  constructor(private readonly usersService: UserService) {}
11
 
12
+ @Get('id')
13
+ @Roles(Role.ADMIN, Role.AREA_MANAGER, Role.BRANCH_MANAGER)
14
+ async getUserById(
15
+ @Query('id') id: string
16
  ): Promise<UserEntity | undefined> {
17
+ return this.usersService.findOneByField("id", id)
18
+ }
19
+
20
+ @Get('fullname')
21
+ @Roles(Role.ADMIN, Role.AREA_MANAGER, Role.BRANCH_MANAGER)
22
+ async getUserByFullname( @Query('full_name') fullName: string, @Paginate() query: PaginateQuery, ) {
23
+ console.log(fullName)
24
+ return this.usersService.findAllByName(fullName, query);
25
  }
26
 
27
  @Post('updateUser')
 
30
  const updateUserDto = req.body;
31
  return this.usersService.updateUserById(userId, updateUserDto);
32
  }
33
+
34
+ @Get('getAll')
35
+ @Roles(Role.ADMIN, Role.AREA_MANAGER, Role.BRANCH_MANAGER)
36
+ async findAllUser(@Paginate() query: PaginateQuery) {
37
+ return this.usersService.findAllUser(query);
38
+ }
39
+
40
+ @Get('role')
41
+ @Roles(Role.ADMIN, Role.AREA_MANAGER, Role.BRANCH_MANAGER)
42
+ async getUserByRole( @Query('role') role: string, @Paginate() query: PaginateQuery, ) {
43
+ console.log(role)
44
+ return this.usersService.findAllByRole(role, query);
45
+ }
46
  }
backend/src/modules/user/user.service.ts CHANGED
@@ -5,6 +5,7 @@ import { UpdateUserDto } from './dto/update-user-dto.js';
5
  import { ValidateService } from '../../validate/validate.service.js';
6
  import * as bcrypt from 'bcrypt';
7
  import { JwtService } from '@nestjs/jwt';
 
8
 
9
  export type User = any;
10
 
@@ -15,10 +16,6 @@ export class UserService {
15
  private jwtService: JwtService,
16
  ) {}
17
 
18
- async findOne(username: string): Promise<UserEntity | undefined> {
19
- return UserEntity.findOne({ where: { full_name: username } });
20
- }
21
-
22
  async create(signUpDto: SignUpDto): Promise<UserEntity | undefined>{
23
  return UserEntity.create({
24
  full_name: signUpDto.full_name,
@@ -63,4 +60,65 @@ export class UserService {
63
  access_token: token
64
  };
65
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
 
5
  import { ValidateService } from '../../validate/validate.service.js';
6
  import * as bcrypt from 'bcrypt';
7
  import { JwtService } from '@nestjs/jwt';
8
+ import { FilterOperator, paginate, PaginateConfig, PaginateQuery } from 'nestjs-paginate';
9
 
10
  export type User = any;
11
 
 
16
  private jwtService: JwtService,
17
  ) {}
18
 
 
 
 
 
19
  async create(signUpDto: SignUpDto): Promise<UserEntity | undefined>{
20
  return UserEntity.create({
21
  full_name: signUpDto.full_name,
 
60
  access_token: token
61
  };
62
  }
63
+
64
+ async findAllUser(query: PaginateQuery) {
65
+ const paginateConfig: PaginateConfig<UserEntity> = {
66
+ sortableColumns: ['id', 'full_name', 'phone_number', 'email'],
67
+ nullSort: 'last',
68
+ defaultSortBy: [['id', 'DESC']],
69
+ searchableColumns: ['full_name'],
70
+ filterableColumns: {
71
+ full_name: [
72
+ FilterOperator.LT,
73
+ FilterOperator.LTE,
74
+ FilterOperator.GT,
75
+ FilterOperator.GTE,
76
+ ],
77
+ item_type: [FilterOperator.EQ]
78
+ },
79
+ };
80
+ return paginate(query, UserEntity.createQueryBuilder(), paginateConfig);
81
+ }
82
+
83
+ async findAllByName(fullName: string, query: PaginateQuery) {
84
+ const queryBuilder = UserEntity.createQueryBuilder('users')
85
+ .where('users.full_name = :fullName', { fullName });
86
+ const paginateConfig: PaginateConfig<UserEntity> = {
87
+ sortableColumns: ['id', 'full_name', 'phone_number', 'email'],
88
+ nullSort: 'last',
89
+ defaultSortBy: [['id', 'DESC']],
90
+ searchableColumns: ['full_name'],
91
+ filterableColumns: {
92
+ full_name: [
93
+ FilterOperator.LT,
94
+ FilterOperator.LTE,
95
+ FilterOperator.GT,
96
+ FilterOperator.GTE,
97
+ ],
98
+ item_type: [FilterOperator.EQ]
99
+ },
100
+ };
101
+ return paginate(query, queryBuilder, paginateConfig);
102
+ }
103
+
104
+ async findAllByRole(role: string, query: PaginateQuery) {
105
+ const queryBuilder = UserEntity.createQueryBuilder('users')
106
+ .where('users.role = :role', { role });
107
+ const paginateConfig: PaginateConfig<UserEntity> = {
108
+ sortableColumns: ['id', 'full_name', 'phone_number', 'email'],
109
+ nullSort: 'last',
110
+ defaultSortBy: [['id', 'DESC']],
111
+ searchableColumns: ['full_name'],
112
+ filterableColumns: {
113
+ full_name: [
114
+ FilterOperator.LT,
115
+ FilterOperator.LTE,
116
+ FilterOperator.GT,
117
+ FilterOperator.GTE,
118
+ ],
119
+ item_type: [FilterOperator.EQ]
120
+ },
121
+ };
122
+ return paginate(query, queryBuilder, paginateConfig);
123
+ }
124
  }