npm_microservice 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/config.js +7 -8
  2. package/dist/service.js +202 -65
  3. package/dist/services/BaseService.js +65 -64
  4. package/dist/services/SettingService.js +65 -64
  5. package/dist/services/app/AppTestService.js +65 -64
  6. package/dist/services/app/BannerService.js +346 -0
  7. package/dist/services/app/CategoryService.js +65 -64
  8. package/dist/services/app/NewService.js +65 -64
  9. package/dist/services/app/RecommendedCourseService.js +65 -64
  10. package/dist/services/app/SettingAppService.js +65 -64
  11. package/dist/services/app/TargetService.js +65 -64
  12. package/dist/services/call_center/CategoryService.js +65 -64
  13. package/dist/services/call_center/TicketActivityService.js +65 -64
  14. package/dist/services/call_center/TicketService.js +65 -64
  15. package/dist/services/call_center/TicketTemplateService.js +65 -64
  16. package/dist/services/call_center/TicketTopicService.js +65 -64
  17. package/dist/services/course/CategoryService.js +346 -0
  18. package/dist/services/course/CourseLessonService.js +350 -0
  19. package/dist/services/course/CourseService.js +365 -0
  20. package/dist/services/course/StudentService.js +358 -0
  21. package/dist/services/crm/ContactsService.js +65 -64
  22. package/dist/services/crm/DeviceService.js +65 -64
  23. package/dist/services/finance/InvoicesCancelService.js +65 -64
  24. package/dist/services/finance/InvoicesDetailService.js +65 -64
  25. package/dist/services/finance/InvoicesLogsAssignService.js +65 -64
  26. package/dist/services/finance/InvoicesService.js +65 -64
  27. package/dist/services/finance/PaymentRequestService.js +65 -64
  28. package/dist/services/finance/PaymentService.js +65 -64
  29. package/dist/services/finance/VouchersCategoryService.js +65 -64
  30. package/dist/services/finance/VouchersService.js +65 -64
  31. package/dist/services/finance/WalletTransactionService.js +65 -64
  32. package/dist/services/finance/WalletsService.js +65 -64
  33. package/dist/services/hr/AllowanceService.js +65 -64
  34. package/dist/services/hr/AnnualLeaveService.js +65 -64
  35. package/dist/services/hr/CategoryService.js +65 -64
  36. package/dist/services/hr/DepartmentService.js +65 -64
  37. package/dist/services/hr/DeviceService.js +65 -64
  38. package/dist/services/hr/DocumentService.js +65 -64
  39. package/dist/services/hr/EmployeeExtendService.js +65 -64
  40. package/dist/services/hr/EmployeeExtendTempService.js +65 -64
  41. package/dist/services/hr/EmployeeLeaveService.js +65 -64
  42. package/dist/services/hr/EmployeeQuitService.js +65 -64
  43. package/dist/services/hr/EmployeeService.js +65 -64
  44. package/dist/services/hr/EmployeeShiftService.js +65 -64
  45. package/dist/services/hr/HolidayService.js +65 -64
  46. package/dist/services/hr/JobTitleService.js +65 -64
  47. package/dist/services/hr/PositionService.js +65 -64
  48. package/dist/services/hr/ReasonTypeService.js +65 -64
  49. package/dist/services/hr/ResignationService.js +65 -64
  50. package/dist/services/hr/SalaryService.js +65 -64
  51. package/dist/services/hr/ScheduleOnlineService.js +65 -64
  52. package/dist/services/hr/ScheduleService.js +65 -64
  53. package/dist/services/hr/SettingDocumentService.js +65 -64
  54. package/dist/services/hr/ShiftService.js +65 -64
  55. package/dist/services/hr/ShiftsCustomerCareService.js +65 -64
  56. package/dist/services/hr/TicketExtendService.js +65 -64
  57. package/dist/services/hr/TicketService.js +65 -64
  58. package/dist/services/hr/TicketTypeService.js +65 -64
  59. package/dist/services/hr/TrackingConfirmService.js +65 -64
  60. package/dist/services/hr/TrackingErrorService.js +65 -64
  61. package/dist/services/inventory/InventoryService.js +65 -64
  62. package/dist/services/inventory/LogService.js +65 -64
  63. package/dist/services/inventory/ProductService.js +65 -64
  64. package/dist/services/inventory/ProductShipmentService.js +65 -64
  65. package/dist/services/inventory/StoreService.js +65 -64
  66. package/dist/services/inventory/SupplierService.js +65 -64
  67. package/dist/services/inventory/TransactionDetailService.js +65 -64
  68. package/dist/services/inventory/TransactionService.js +65 -64
  69. package/dist/services/lms/AlbumCategoryService.js +65 -64
  70. package/dist/services/lms/AlbumFileService.js +65 -64
  71. package/dist/services/lms/AlbumService.js +65 -64
  72. package/dist/services/lms/ClassScheduleService.js +65 -64
  73. package/dist/services/lms/ClassesService.js +65 -64
  74. package/dist/services/lms/CourseLessonService.js +65 -64
  75. package/dist/services/lms/CoursePriceService.js +65 -64
  76. package/dist/services/lms/CourseProductService.js +65 -64
  77. package/dist/services/lms/CourseService.js +65 -64
  78. package/dist/services/lms/DocumentCategoryService.js +65 -64
  79. package/dist/services/lms/DocumentService.js +65 -64
  80. package/dist/services/lms/LicenseService.js +65 -64
  81. package/dist/services/lms/PracticeResultService.js +65 -64
  82. package/dist/services/lms/PracticeService.js +65 -64
  83. package/dist/services/lms/StudentAgainService.js +65 -64
  84. package/dist/services/lms/StudentDocumentService.js +65 -64
  85. package/dist/services/lms/StudentExamTimeService.js +65 -64
  86. package/dist/services/lms/StudentReviewService.js +65 -64
  87. package/dist/services/lms/StudentScoreService.js +65 -64
  88. package/dist/services/lms/StudentService.js +80 -64
  89. package/dist/services/lms/StudentSettingReviewService.js +65 -64
  90. package/dist/services/lms/StudentTrackingService.js +65 -64
  91. package/dist/services/lms/StudentTrialService.js +65 -64
  92. package/dist/services/notification/AppService.js +65 -64
  93. package/dist/services/notification/NotificationService.js +65 -64
  94. package/dist/services/online/CourseLessonService.js +65 -64
  95. package/dist/services/online/CourseService.js +65 -64
  96. package/dist/services/online/StudentService.js +65 -64
  97. package/dist/services/org/BranchRequestService.js +65 -64
  98. package/dist/services/org/BranchService.js +65 -64
  99. package/dist/services/org/BranchToMacsService.js +65 -64
  100. package/dist/services/org/BrandService.js +65 -64
  101. package/dist/services/org/CitiesService.js +65 -64
  102. package/dist/services/org/LegalEntityService.js +65 -64
  103. package/dist/services/pm/NoteService.js +65 -64
  104. package/dist/services/pm/TaskService.js +65 -64
  105. package/dist/services/support/CommentService.js +65 -64
  106. package/dist/services/test/EduTestService.js +65 -64
  107. package/package.json +1 -1
package/dist/config.js CHANGED
@@ -42,25 +42,24 @@ var configRouteService = {
42
42
  App: {
43
43
  CategoryService: `${baseUrl}/app/category`,
44
44
  NewService: `${baseUrl}/app/news`,
45
+ BannerService: `${baseUrl}/app/banner`,
45
46
  AppTestService: `${baseUrl}/app/test`,
46
47
  RecommendedCourseService: `${baseUrl}/app/recommended_level`,
47
48
  SettingAppService: `${baseUrl}/app/setting`,
48
49
  TargetAppService: `${baseUrl}/app/target`
49
50
  },
51
+ Course: {
52
+ CategoryService: `${baseUrl}/course/category`,
53
+ CourseService: `${baseUrl}/course/course`,
54
+ CourseLessonService: `${baseUrl}/course/course_schedule`,
55
+ StudentService: `${baseUrl}/course/students`
56
+ },
50
57
  Asset: {
51
58
  AllocationDetailService: `${baseUrl}/asset/asset-allocation-detail`,
52
59
  BroadcastService: `${baseUrl}/asset/broadcast`,
53
60
  EntityAssetService: `${baseUrl}/asset/entity-asset`,
54
61
  SubAssetService: `${baseUrl}/asset/sub-asset`
55
62
  },
56
- Course: {
57
- CategoryService: `${baseUrl}/course/category`,
58
- ClassesService: `${baseUrl}/course/classes`,
59
- ClassesScheduleService: `${baseUrl}/course/classes_schedule`,
60
- CourseService: `${baseUrl}/course/course`,
61
- CourseScheduleService: `${baseUrl}/course/course_schedule`,
62
- StudentsService: `${baseUrl}/course/students`
63
- },
64
63
  Test: {
65
64
  TestService: `${baseUrl}/tests/tests`
66
65
  },
package/dist/service.js CHANGED
@@ -49,25 +49,24 @@ var require_config = __commonJS({
49
49
  App: {
50
50
  CategoryService: `${baseUrl}/app/category`,
51
51
  NewService: `${baseUrl}/app/news`,
52
+ BannerService: `${baseUrl}/app/banner`,
52
53
  AppTestService: `${baseUrl}/app/test`,
53
54
  RecommendedCourseService: `${baseUrl}/app/recommended_level`,
54
55
  SettingAppService: `${baseUrl}/app/setting`,
55
56
  TargetAppService: `${baseUrl}/app/target`
56
57
  },
58
+ Course: {
59
+ CategoryService: `${baseUrl}/course/category`,
60
+ CourseService: `${baseUrl}/course/course`,
61
+ CourseLessonService: `${baseUrl}/course/course_schedule`,
62
+ StudentService: `${baseUrl}/course/students`
63
+ },
57
64
  Asset: {
58
65
  AllocationDetailService: `${baseUrl}/asset/asset-allocation-detail`,
59
66
  BroadcastService: `${baseUrl}/asset/broadcast`,
60
67
  EntityAssetService: `${baseUrl}/asset/entity-asset`,
61
68
  SubAssetService: `${baseUrl}/asset/sub-asset`
62
69
  },
63
- Course: {
64
- CategoryService: `${baseUrl}/course/category`,
65
- ClassesService: `${baseUrl}/course/classes`,
66
- ClassesScheduleService: `${baseUrl}/course/classes_schedule`,
67
- CourseService: `${baseUrl}/course/course`,
68
- CourseScheduleService: `${baseUrl}/course/course_schedule`,
69
- StudentsService: `${baseUrl}/course/students`
70
- },
71
70
  Test: {
72
71
  TestService: `${baseUrl}/tests/tests`
73
72
  },
@@ -189,23 +188,33 @@ var require_BaseService = __commonJS({
189
188
  baseUrl = "";
190
189
  headers = {};
191
190
  isCache = false;
191
+ // bật/tắt cache mặc định
192
192
  service = null;
193
- // nhớ set ở subclass
193
+ // nhớ gán ở subclass
194
194
  timeCache = 300;
195
195
  // 300s = 5 phút
196
196
  constructor(baseUrl = "", defaultHeaders = {}) {
197
197
  this.baseUrl = baseUrl;
198
- this.setHeader();
198
+ this.setHeader(defaultHeaders);
199
199
  this.http = axios.create({
200
200
  baseURL: this.baseUrl,
201
201
  headers: this.headers,
202
202
  paramsSerializer: (params) => qs.stringify(params, { arrayFormat: "brackets", encode: true })
203
203
  });
204
204
  }
205
- // Nhận: object headers, hoặc trực tiếp token string ("Bearer x"), hoặc không truyền gì (auto từ ENV)
205
+ /**
206
+ * Set header cho request
207
+ * - headers: object { Authorization: "Bearer x" }
208
+ * - string: "Bearer x"
209
+ * - không truyền: dùng token từ ENV
210
+ */
206
211
  setHeader(headers = {}) {
207
- var Authorization = `Bearer ${API_MICROSERVICE_TOKEN}`;
208
- if (headers && headers.Authorization) Authorization = headers.Authorization;
212
+ let Authorization = `Bearer ${API_MICROSERVICE_TOKEN}`;
213
+ if (typeof headers === "string") {
214
+ Authorization = headers;
215
+ } else if (headers && headers.Authorization) {
216
+ Authorization = headers.Authorization;
217
+ }
209
218
  this.headers = {
210
219
  ...this.headers || {},
211
220
  Authorization
@@ -218,11 +227,12 @@ var require_BaseService = __commonJS({
218
227
  const service = this.service || "unknown";
219
228
  return `gateway.${service}.urls:${full}`;
220
229
  }
221
- async request(method, url, options = {}, cacheKey = null) {
222
- var _a, _b, _c;
230
+ async request(method, url, options = {}, cacheKey = null, cacheOption = {}) {
231
+ var _a, _b;
223
232
  const isGet = method.toLowerCase() === "get";
224
- if (isGet && this.isCache) {
225
- cacheKey = cacheKey ? cacheKey : this.buildCacheKey(url, options.params);
233
+ const enableCache = cacheOption.isCache ?? this.isCache;
234
+ if (isGet && enableCache) {
235
+ cacheKey = cacheKey || this.buildCacheKey(url, options.params);
226
236
  const cached = await CONFIG_REDIS.get(cacheKey);
227
237
  if (cached) {
228
238
  console.log(`[CACHE HIT] ${cacheKey}`);
@@ -230,93 +240,84 @@ var require_BaseService = __commonJS({
230
240
  }
231
241
  }
232
242
  try {
233
- if (method.toLowerCase() === "get") {
234
- console.log(
235
- `[HTTP ${method.toUpperCase()}] ${this.buildGET(
236
- url,
237
- options.params || {}
238
- )} `
239
- );
243
+ if (isGet) {
244
+ console.log(`[HTTP GET] ${this.buildGET(url, options.params || {})}`);
240
245
  }
241
- let startTime = Date.now();
246
+ const startTime = Date.now();
242
247
  const res = await this.http.request({
243
248
  method,
244
249
  url,
245
- // dùng path vì đã set baseURL
246
250
  headers: this.headers,
247
251
  ...options
248
252
  });
249
253
  const data = res.data;
250
- let duration = (Date.now() - startTime) / 1e3;
254
+ if (isGet && enableCache) {
255
+ cacheKey = cacheKey || this.buildCacheKey(url, options.params);
256
+ const ttl = cacheOption.timeCache || this.timeCache;
257
+ await CONFIG_REDIS.set(cacheKey, JSON.stringify(data), "EX", ttl);
258
+ console.log(`[CACHE SET] ${cacheKey} - TTL ${ttl}s`);
259
+ }
260
+ const duration = (Date.now() - startTime) / 1e3;
251
261
  if (duration > 5) {
252
- if (method.toLowerCase() === "get") {
253
- let q = qs.stringify(options.params || {}, {
254
- arrayFormat: "brackets",
255
- encode: true
256
- });
257
- console.log(
258
- `[HTTP GET] ${url}${q ? "?" + q : ""} - took ${duration.toFixed(
259
- 2
260
- )}s`
261
- );
262
- } else {
263
- console.log(
264
- `[HTTP ${method.toUpperCase()}] ${url} - took ${duration.toFixed(
265
- 2
266
- )}s`
267
- );
268
- }
262
+ console.log(
263
+ `[SLOW ${method.toUpperCase()}] ${url} - ${duration.toFixed(2)}s`
264
+ );
269
265
  if (options.params) console.log("Query:", options.params);
270
266
  if (options.data) console.log("Body:", options.data);
271
267
  }
272
268
  return data;
273
269
  } catch (error) {
274
- var safeError = {
275
- // message: error.message || "Request failed",
270
+ const safeError = {
276
271
  statusCode: ((_a = error.response) == null ? void 0 : _a.status) || 500,
277
272
  ...(_b = error.response) == null ? void 0 : _b.data
278
273
  };
279
- if (safeError.statusCode == 404) {
280
- let q = qs.stringify(options.params || {}, {
274
+ if (safeError.statusCode === 404) {
275
+ const q = qs.stringify(options.params || {}, {
281
276
  arrayFormat: "brackets",
282
277
  encode: true
283
278
  });
284
279
  return {
285
280
  statusCode: 404,
286
281
  status: "error",
287
- messag: `[HTTP ${method.toUpperCase()}] ${url}${q ? "?" + q : ""} not found`
282
+ message: `[HTTP ${method.toUpperCase()}] ${url}${q ? "?" + q : ""} not found`
288
283
  };
289
284
  }
290
- console.error(
291
- `[${method.toUpperCase()}] ${url} failed:`,
292
- safeError,
293
- (_c = error.response) == null ? void 0 : _c.data
294
- );
295
- return {
296
- error: true,
297
- ...safeError
298
- };
285
+ console.error(`[${method.toUpperCase()}] ${url} failed:`, safeError);
286
+ return { error: true, ...safeError };
299
287
  }
300
288
  }
301
289
  buildGET(url, params = {}) {
302
- let queryString = qs.stringify(params, {
290
+ const queryString = qs.stringify(params, {
303
291
  arrayFormat: "brackets",
304
292
  encode: true
305
293
  });
306
294
  return `${url}${queryString ? "?" + queryString : ""}`;
307
295
  }
308
- async all(query = {}) {
296
+ async all(query = {}, cacheOption = {}) {
309
297
  if (query.order_by && Array.isArray(query.order_by)) {
310
298
  query.order_by = query.order_by.slice(0, 2);
311
299
  if (query.order_by[1] && !["asc", "desc"].includes(query.order_by[1])) {
312
300
  query.order_by[1] = "asc";
313
301
  }
314
302
  }
315
- return this.request("get", this.baseUrl, { params: query });
316
- }
317
- async detail(id) {
318
- const cacheKey = this.isCache ? `gateway.${this.service}.${id}` : null;
319
- return this.request("get", `${this.baseUrl}/${id}`);
303
+ return this.request(
304
+ "get",
305
+ this.baseUrl,
306
+ { params: query },
307
+ null,
308
+ cacheOption
309
+ );
310
+ }
311
+ async detail(id, cacheOption = {}) {
312
+ const enableCache = cacheOption.isCache ?? this.isCache;
313
+ const cacheKey = enableCache ? `gateway.${this.service}.${id}` : null;
314
+ return this.request(
315
+ "get",
316
+ `${this.baseUrl}/${id}`,
317
+ {},
318
+ cacheKey,
319
+ cacheOption
320
+ );
320
321
  }
321
322
  async create(data) {
322
323
  return this.request("post", this.baseUrl, { data });
@@ -386,6 +387,22 @@ var require_SettingService = __commonJS({
386
387
  }
387
388
  });
388
389
 
390
+ // src/services/app/BannerService.js
391
+ var require_BannerService = __commonJS({
392
+ "src/services/app/BannerService.js"(exports2, module2) {
393
+ var BaseService = require_BaseService();
394
+ var { CONFIG_ROUTER_SERVICE } = require_config();
395
+ var BannerService = class extends BaseService {
396
+ constructor() {
397
+ super(CONFIG_ROUTER_SERVICE.App.BannerService);
398
+ this.service = "App.BannerService";
399
+ this.isCache = true;
400
+ }
401
+ };
402
+ module2.exports = BannerService;
403
+ }
404
+ });
405
+
389
406
  // src/services/app/CategoryService.js
390
407
  var require_CategoryService = __commonJS({
391
408
  "src/services/app/CategoryService.js"(exports2, module2) {
@@ -1931,6 +1948,21 @@ var require_StudentService = __commonJS({
1931
1948
  this.service = "Lms.StudentService";
1932
1949
  this.isCache = false;
1933
1950
  }
1951
+ async getScore(filter = {}) {
1952
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/lms/students-scores";
1953
+ this.service = "students-scores";
1954
+ return this.request("get", url, filter);
1955
+ }
1956
+ async getStudentReview(filter = {}) {
1957
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/lms/students-reviews";
1958
+ this.service = "students-reviews";
1959
+ return this.request("get", url, filter);
1960
+ }
1961
+ async getStudentSettingReview(filter = {}) {
1962
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/lms/setting-reviews";
1963
+ this.service = "setting-reviews";
1964
+ return this.request("get", url, filter);
1965
+ }
1934
1966
  };
1935
1967
  module2.exports = StudentService;
1936
1968
  }
@@ -2138,6 +2170,105 @@ var require_LegalEntityService = __commonJS({
2138
2170
  }
2139
2171
  });
2140
2172
 
2173
+ // src/services/course/CategoryService.js
2174
+ var require_CategoryService4 = __commonJS({
2175
+ "src/services/course/CategoryService.js"(exports2, module2) {
2176
+ var BaseService = require_BaseService();
2177
+ var { CONFIG_ROUTER_SERVICE } = require_config();
2178
+ var CategoryService = class extends BaseService {
2179
+ constructor() {
2180
+ super(CONFIG_ROUTER_SERVICE.Course.CategoryService);
2181
+ this.service = "Course.CategoryService";
2182
+ this.isCache = true;
2183
+ }
2184
+ };
2185
+ module2.exports = CategoryService;
2186
+ }
2187
+ });
2188
+
2189
+ // src/services/course/CourseService.js
2190
+ var require_CourseService2 = __commonJS({
2191
+ "src/services/course/CourseService.js"(exports2, module2) {
2192
+ var BaseService = require_BaseService();
2193
+ var { CONFIG_ROUTER_SERVICE } = require_config();
2194
+ var CourseService = class extends BaseService {
2195
+ constructor() {
2196
+ super(CONFIG_ROUTER_SERVICE.Course.CourseService);
2197
+ this.service = "Course.CourseService";
2198
+ }
2199
+ // có thể thêm method riêng cho user nếu cần
2200
+ async detailSchedule(id, cacheOption = {}) {
2201
+ const enableCache = cacheOption.isCache ?? this.isCache;
2202
+ const cacheKey = enableCache ? `gateway.course_schedule.${id}` : null;
2203
+ return this.request(
2204
+ "get",
2205
+ `${this.baseUrl}/${id}`,
2206
+ {},
2207
+ cacheKey,
2208
+ cacheOption
2209
+ );
2210
+ }
2211
+ async count(filter = {}) {
2212
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/course/count";
2213
+ return this.request("get", url, { params: filter });
2214
+ }
2215
+ async student(filter = {}) {
2216
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/students";
2217
+ return this.request("get", url, { params: filter });
2218
+ }
2219
+ };
2220
+ module2.exports = CourseService;
2221
+ }
2222
+ });
2223
+
2224
+ // src/services/course/CourseLessonService.js
2225
+ var require_CourseLessonService2 = __commonJS({
2226
+ "src/services/course/CourseLessonService.js"(exports2, module2) {
2227
+ var BaseService = require_BaseService();
2228
+ var { CONFIG_ROUTER_SERVICE } = require_config();
2229
+ var CourseLessonService = class extends BaseService {
2230
+ constructor() {
2231
+ super(CONFIG_ROUTER_SERVICE.Course.CourseLessonService);
2232
+ this.service = "Course.CourseLessonService";
2233
+ }
2234
+ // có thể thêm method riêng cho user nếu cần
2235
+ async category(filter = {}) {
2236
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/category";
2237
+ return this.request("get", url, { params: filter });
2238
+ }
2239
+ };
2240
+ module2.exports = CourseLessonService;
2241
+ }
2242
+ });
2243
+
2244
+ // src/services/course/StudentService.js
2245
+ var require_StudentService2 = __commonJS({
2246
+ "src/services/course/StudentService.js"(exports2, module2) {
2247
+ var BaseService = require_BaseService();
2248
+ var { CONFIG_ROUTER_SERVICE } = require_config();
2249
+ var StudentService = class extends BaseService {
2250
+ constructor() {
2251
+ super(CONFIG_ROUTER_SERVICE.Course.StudentService);
2252
+ this.service = "Course.StudentService";
2253
+ }
2254
+ async getStudentCourse(filter = {}) {
2255
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/students";
2256
+ return this.request("get", url, { params: filter });
2257
+ }
2258
+ async register(data) {
2259
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/students/register-course";
2260
+ return this.request("post", url, { data });
2261
+ }
2262
+ async updateProgress(data) {
2263
+ let url = CONFIG_ROUTER_SERVICE.BASE_URL + "/course/students/update-progress";
2264
+ return this.request("post", url, { data });
2265
+ }
2266
+ // có thể thêm method riêng cho user nếu cần
2267
+ };
2268
+ module2.exports = StudentService;
2269
+ }
2270
+ });
2271
+
2141
2272
  // src/services/pm/NoteService.js
2142
2273
  var require_NoteService = __commonJS({
2143
2274
  "src/services/pm/NoteService.js"(exports2, module2) {
@@ -2261,6 +2392,7 @@ var require_CommentService = __commonJS({
2261
2392
  module.exports = {
2262
2393
  settingService: new (require_SettingService())(),
2263
2394
  // app
2395
+ bannerService: new (require_BannerService())(),
2264
2396
  appCategoryService: new (require_CategoryService())(),
2265
2397
  appNewService: new (require_NewService())(),
2266
2398
  recommendedCourseService: new (require_RecommendedCourseService())(),
@@ -2358,6 +2490,11 @@ module.exports = {
2358
2490
  brandService: new (require_BrandService())(),
2359
2491
  citiesService: new (require_CitiesService())(),
2360
2492
  legalEntityService: new (require_LegalEntityService())(),
2493
+ // course
2494
+ courseCategoryService: new (require_CategoryService4())(),
2495
+ courseCourseService: new (require_CourseService2())(),
2496
+ courseCourseLessonService: new (require_CourseLessonService2())(),
2497
+ courseStudentService: new (require_StudentService2())(),
2361
2498
  // pm
2362
2499
  noteService: new (require_NoteService())(),
2363
2500
  taskService: new (require_TaskService())(),
@@ -49,25 +49,24 @@ var require_config = __commonJS({
49
49
  App: {
50
50
  CategoryService: `${baseUrl}/app/category`,
51
51
  NewService: `${baseUrl}/app/news`,
52
+ BannerService: `${baseUrl}/app/banner`,
52
53
  AppTestService: `${baseUrl}/app/test`,
53
54
  RecommendedCourseService: `${baseUrl}/app/recommended_level`,
54
55
  SettingAppService: `${baseUrl}/app/setting`,
55
56
  TargetAppService: `${baseUrl}/app/target`
56
57
  },
58
+ Course: {
59
+ CategoryService: `${baseUrl}/course/category`,
60
+ CourseService: `${baseUrl}/course/course`,
61
+ CourseLessonService: `${baseUrl}/course/course_schedule`,
62
+ StudentService: `${baseUrl}/course/students`
63
+ },
57
64
  Asset: {
58
65
  AllocationDetailService: `${baseUrl}/asset/asset-allocation-detail`,
59
66
  BroadcastService: `${baseUrl}/asset/broadcast`,
60
67
  EntityAssetService: `${baseUrl}/asset/entity-asset`,
61
68
  SubAssetService: `${baseUrl}/asset/sub-asset`
62
69
  },
63
- Course: {
64
- CategoryService: `${baseUrl}/course/category`,
65
- ClassesService: `${baseUrl}/course/classes`,
66
- ClassesScheduleService: `${baseUrl}/course/classes_schedule`,
67
- CourseService: `${baseUrl}/course/course`,
68
- CourseScheduleService: `${baseUrl}/course/course_schedule`,
69
- StudentsService: `${baseUrl}/course/students`
70
- },
71
70
  Test: {
72
71
  TestService: `${baseUrl}/tests/tests`
73
72
  },
@@ -187,23 +186,33 @@ var BaseService = class {
187
186
  baseUrl = "";
188
187
  headers = {};
189
188
  isCache = false;
189
+ // bật/tắt cache mặc định
190
190
  service = null;
191
- // nhớ set ở subclass
191
+ // nhớ gán ở subclass
192
192
  timeCache = 300;
193
193
  // 300s = 5 phút
194
194
  constructor(baseUrl = "", defaultHeaders = {}) {
195
195
  this.baseUrl = baseUrl;
196
- this.setHeader();
196
+ this.setHeader(defaultHeaders);
197
197
  this.http = axios.create({
198
198
  baseURL: this.baseUrl,
199
199
  headers: this.headers,
200
200
  paramsSerializer: (params) => qs.stringify(params, { arrayFormat: "brackets", encode: true })
201
201
  });
202
202
  }
203
- // Nhận: object headers, hoặc trực tiếp token string ("Bearer x"), hoặc không truyền gì (auto từ ENV)
203
+ /**
204
+ * Set header cho request
205
+ * - headers: object { Authorization: "Bearer x" }
206
+ * - string: "Bearer x"
207
+ * - không truyền: dùng token từ ENV
208
+ */
204
209
  setHeader(headers = {}) {
205
- var Authorization = `Bearer ${API_MICROSERVICE_TOKEN}`;
206
- if (headers && headers.Authorization) Authorization = headers.Authorization;
210
+ let Authorization = `Bearer ${API_MICROSERVICE_TOKEN}`;
211
+ if (typeof headers === "string") {
212
+ Authorization = headers;
213
+ } else if (headers && headers.Authorization) {
214
+ Authorization = headers.Authorization;
215
+ }
207
216
  this.headers = {
208
217
  ...this.headers || {},
209
218
  Authorization
@@ -216,11 +225,12 @@ var BaseService = class {
216
225
  const service = this.service || "unknown";
217
226
  return `gateway.${service}.urls:${full}`;
218
227
  }
219
- async request(method, url, options = {}, cacheKey = null) {
220
- var _a, _b, _c;
228
+ async request(method, url, options = {}, cacheKey = null, cacheOption = {}) {
229
+ var _a, _b;
221
230
  const isGet = method.toLowerCase() === "get";
222
- if (isGet && this.isCache) {
223
- cacheKey = cacheKey ? cacheKey : this.buildCacheKey(url, options.params);
231
+ const enableCache = cacheOption.isCache ?? this.isCache;
232
+ if (isGet && enableCache) {
233
+ cacheKey = cacheKey || this.buildCacheKey(url, options.params);
224
234
  const cached = await CONFIG_REDIS.get(cacheKey);
225
235
  if (cached) {
226
236
  console.log(`[CACHE HIT] ${cacheKey}`);
@@ -228,93 +238,84 @@ var BaseService = class {
228
238
  }
229
239
  }
230
240
  try {
231
- if (method.toLowerCase() === "get") {
232
- console.log(
233
- `[HTTP ${method.toUpperCase()}] ${this.buildGET(
234
- url,
235
- options.params || {}
236
- )} `
237
- );
241
+ if (isGet) {
242
+ console.log(`[HTTP GET] ${this.buildGET(url, options.params || {})}`);
238
243
  }
239
- let startTime = Date.now();
244
+ const startTime = Date.now();
240
245
  const res = await this.http.request({
241
246
  method,
242
247
  url,
243
- // dùng path vì đã set baseURL
244
248
  headers: this.headers,
245
249
  ...options
246
250
  });
247
251
  const data = res.data;
248
- let duration = (Date.now() - startTime) / 1e3;
252
+ if (isGet && enableCache) {
253
+ cacheKey = cacheKey || this.buildCacheKey(url, options.params);
254
+ const ttl = cacheOption.timeCache || this.timeCache;
255
+ await CONFIG_REDIS.set(cacheKey, JSON.stringify(data), "EX", ttl);
256
+ console.log(`[CACHE SET] ${cacheKey} - TTL ${ttl}s`);
257
+ }
258
+ const duration = (Date.now() - startTime) / 1e3;
249
259
  if (duration > 5) {
250
- if (method.toLowerCase() === "get") {
251
- let q = qs.stringify(options.params || {}, {
252
- arrayFormat: "brackets",
253
- encode: true
254
- });
255
- console.log(
256
- `[HTTP GET] ${url}${q ? "?" + q : ""} - took ${duration.toFixed(
257
- 2
258
- )}s`
259
- );
260
- } else {
261
- console.log(
262
- `[HTTP ${method.toUpperCase()}] ${url} - took ${duration.toFixed(
263
- 2
264
- )}s`
265
- );
266
- }
260
+ console.log(
261
+ `[SLOW ${method.toUpperCase()}] ${url} - ${duration.toFixed(2)}s`
262
+ );
267
263
  if (options.params) console.log("Query:", options.params);
268
264
  if (options.data) console.log("Body:", options.data);
269
265
  }
270
266
  return data;
271
267
  } catch (error) {
272
- var safeError = {
273
- // message: error.message || "Request failed",
268
+ const safeError = {
274
269
  statusCode: ((_a = error.response) == null ? void 0 : _a.status) || 500,
275
270
  ...(_b = error.response) == null ? void 0 : _b.data
276
271
  };
277
- if (safeError.statusCode == 404) {
278
- let q = qs.stringify(options.params || {}, {
272
+ if (safeError.statusCode === 404) {
273
+ const q = qs.stringify(options.params || {}, {
279
274
  arrayFormat: "brackets",
280
275
  encode: true
281
276
  });
282
277
  return {
283
278
  statusCode: 404,
284
279
  status: "error",
285
- messag: `[HTTP ${method.toUpperCase()}] ${url}${q ? "?" + q : ""} not found`
280
+ message: `[HTTP ${method.toUpperCase()}] ${url}${q ? "?" + q : ""} not found`
286
281
  };
287
282
  }
288
- console.error(
289
- `[${method.toUpperCase()}] ${url} failed:`,
290
- safeError,
291
- (_c = error.response) == null ? void 0 : _c.data
292
- );
293
- return {
294
- error: true,
295
- ...safeError
296
- };
283
+ console.error(`[${method.toUpperCase()}] ${url} failed:`, safeError);
284
+ return { error: true, ...safeError };
297
285
  }
298
286
  }
299
287
  buildGET(url, params = {}) {
300
- let queryString = qs.stringify(params, {
288
+ const queryString = qs.stringify(params, {
301
289
  arrayFormat: "brackets",
302
290
  encode: true
303
291
  });
304
292
  return `${url}${queryString ? "?" + queryString : ""}`;
305
293
  }
306
- async all(query = {}) {
294
+ async all(query = {}, cacheOption = {}) {
307
295
  if (query.order_by && Array.isArray(query.order_by)) {
308
296
  query.order_by = query.order_by.slice(0, 2);
309
297
  if (query.order_by[1] && !["asc", "desc"].includes(query.order_by[1])) {
310
298
  query.order_by[1] = "asc";
311
299
  }
312
300
  }
313
- return this.request("get", this.baseUrl, { params: query });
301
+ return this.request(
302
+ "get",
303
+ this.baseUrl,
304
+ { params: query },
305
+ null,
306
+ cacheOption
307
+ );
314
308
  }
315
- async detail(id) {
316
- const cacheKey = this.isCache ? `gateway.${this.service}.${id}` : null;
317
- return this.request("get", `${this.baseUrl}/${id}`);
309
+ async detail(id, cacheOption = {}) {
310
+ const enableCache = cacheOption.isCache ?? this.isCache;
311
+ const cacheKey = enableCache ? `gateway.${this.service}.${id}` : null;
312
+ return this.request(
313
+ "get",
314
+ `${this.baseUrl}/${id}`,
315
+ {},
316
+ cacheKey,
317
+ cacheOption
318
+ );
318
319
  }
319
320
  async create(data) {
320
321
  return this.request("post", this.baseUrl, { data });