All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m24s
238 lines
7.5 KiB
TypeScript
238 lines
7.5 KiB
TypeScript
import axios from "axios";
|
|
import {
|
|
Controller,
|
|
Post,
|
|
Delete,
|
|
Route,
|
|
Security,
|
|
Tags,
|
|
Body,
|
|
Path,
|
|
Request,
|
|
Response,
|
|
Get,
|
|
} from "tsoa";
|
|
import HttpError from "../interfaces/http-error";
|
|
import HttpStatusCode from "../interfaces/http-status";
|
|
|
|
interface CachedToken {
|
|
token: string;
|
|
expiry: Date;
|
|
}
|
|
const API_URL_BANGKOK = "https://exprofile.bangkok.go.th/API";
|
|
const clientId = "e5f6ad6ce374177eef023bf5d0c018b6";
|
|
const clientSecret = "5EhOvN5DwHOKakupqT9FmCk7MOwpT3zLqLPkPh4ZhJpxBN2nMG@2022";
|
|
|
|
class TokenCache {
|
|
private static cache: Map<string, CachedToken> = new Map();
|
|
|
|
static get(key: string): string | null {
|
|
const cached = this.cache.get(key);
|
|
if (!cached) return null;
|
|
return cached.token;
|
|
}
|
|
|
|
static set(key: string, token: string): void {
|
|
this.cache.set(key, { token, expiry: new Date(Date.now() + 50 * 60 * 1000) });
|
|
}
|
|
|
|
static delete(key: string): void {
|
|
this.cache.delete(key);
|
|
}
|
|
}
|
|
|
|
@Route("api/v1/org/ex/retirement")
|
|
@Tags("ExRetirement")
|
|
@Security("bearerAuth")
|
|
export class ExRetirementController extends Controller {
|
|
@Post()
|
|
async getExRetirement(
|
|
@Body()
|
|
requestBody: {
|
|
type: string; //ประเภท
|
|
retireYear: string; //ปีที่เกษียณ
|
|
citizenID: string; //เลขบัตรประชาชน
|
|
firstNameTH: string; //ชื่อ
|
|
lastNameTH: string; //นามสกุล
|
|
page: number; //หน้า
|
|
},
|
|
) {
|
|
let retryCount = 0;
|
|
const maxRetries = 2;
|
|
|
|
while (retryCount < maxRetries) {
|
|
try {
|
|
const token = await getToken(clientId, clientSecret);
|
|
|
|
if (!token) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถขอ Token ได้");
|
|
}
|
|
|
|
// const scope = requestBody.type === "officer" ? "getOfficerRetireData" : "";
|
|
const scope = "getOfficerRetireData";
|
|
const startRecord = requestBody.page !== 1 ? (requestBody.page - 1) * 25 : 0;
|
|
|
|
const formData = new FormData();
|
|
formData.append("scope", scope);
|
|
formData.append("startRecord", startRecord.toString());
|
|
formData.append("retireYear", requestBody.retireYear);
|
|
formData.append("citizenID", requestBody.citizenID);
|
|
formData.append("firstNameTH", requestBody.firstNameTH);
|
|
formData.append("lastNameTH", requestBody.lastNameTH);
|
|
formData.append("officerTypeID", requestBody.type === "officer" ? "1" : "2");
|
|
|
|
const res = await axios.post(API_URL_BANGKOK + "/getData", formData, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
return res.data;
|
|
} catch (error: any) {
|
|
if (error.response?.status === 500 && retryCount < maxRetries - 1) {
|
|
TokenCache.delete(`${clientId}:${clientSecret}`);
|
|
retryCount++;
|
|
continue;
|
|
}
|
|
throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถติดต่อ API ได้");
|
|
}
|
|
}
|
|
}
|
|
|
|
@Get("/document/{documentId}")
|
|
async getDocument(@Path("documentId") officerDocumentID: string, @Request() req: any) {
|
|
let retryCount = 0;
|
|
const maxRetries = 2;
|
|
while (retryCount < maxRetries) {
|
|
try {
|
|
const token = await getToken(clientId, clientSecret);
|
|
if (!token) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถขอ Token ได้");
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append("scope", "getOfficerRetireFile");
|
|
formData.append("officerDocumentID", officerDocumentID);
|
|
|
|
const res = await axios.post(API_URL_BANGKOK + "/getData", formData, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
responseType: "arraybuffer",
|
|
});
|
|
|
|
if (!req.res.headersSent && !req.res.destroyed) {
|
|
// Set response headers
|
|
req.res.setHeader("Content-Type", "application/pdf");
|
|
req.res.setHeader("Content-Disposition", `inline; filename="${officerDocumentID}.pdf"`);
|
|
req.res.setHeader("Content-Length", res.data.byteLength.toString());
|
|
|
|
req.res.end(Buffer.from(res.data));
|
|
return;
|
|
}
|
|
} catch (error: any) {
|
|
if (error.response?.status === 500 && retryCount < maxRetries - 1) {
|
|
TokenCache.delete(`${clientId}:${clientSecret}`);
|
|
retryCount++;
|
|
continue;
|
|
}
|
|
throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถติดต่อ API ได้");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function getToken(ClientID: string, ClientSecret: string): Promise<string> {
|
|
const cacheKey = `${ClientID}:${ClientSecret}`;
|
|
|
|
// ลองหา token ใน cache ก่อน
|
|
const cachedToken = TokenCache.get(cacheKey);
|
|
if (cachedToken) {
|
|
return cachedToken;
|
|
}
|
|
|
|
// ถ้าไม่มีใน cache ให้ขอใหม่
|
|
try {
|
|
const formData = new FormData();
|
|
formData.append("ClientID", ClientID);
|
|
formData.append("ClientSecret", ClientSecret);
|
|
const res = await axios.post(API_URL_BANGKOK + "/authorize", formData, {
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
const token = res.data.token;
|
|
TokenCache.set(cacheKey, token);
|
|
return token;
|
|
} catch (error) {
|
|
return Promise.reject({ message: "Error occurred", error });
|
|
}
|
|
}
|
|
|
|
// function post retire data to exprofile system
|
|
export async function PostRetireToExprofile(
|
|
citizenID: string,
|
|
prefix: string,
|
|
firstName: string,
|
|
lastName: string,
|
|
retireYear: string,
|
|
positionName: string,
|
|
positionTypeName: string,
|
|
positionLevelName: string,
|
|
retireDate: Date,
|
|
organizeName: string, // child4Name child3Name child2Name child1Name rootName
|
|
retireTypeName: string, // เช่น เกษียณ, ขอโอนออก, ลาออก, ปลดออก, ไล่ออก, ...
|
|
) {
|
|
// check NODE_ENV ถ้าเป็น production ถึงจะทำการส่งข้อมูลไปยัง exprofile
|
|
const NODE_ENV = process.env.NODE_ENV || "development";
|
|
if (NODE_ENV !== "production") {
|
|
return;
|
|
}
|
|
|
|
let retryCount = 0;
|
|
const maxRetries = 2;
|
|
|
|
while (retryCount < maxRetries) {
|
|
try {
|
|
const token = await getToken(clientId, clientSecret);
|
|
|
|
if (!token) {
|
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถขอ Token ได้");
|
|
}
|
|
|
|
const scope = "importOfficerRetireData";
|
|
const body = {
|
|
scope: scope,
|
|
data: {
|
|
citizenID: citizenID,
|
|
prenameTH: prefix,
|
|
firstNameTH: firstName,
|
|
lastNameTH: lastName,
|
|
retireYear,
|
|
positionNameTH: positionName,
|
|
positionTypeNameTH: positionTypeName,
|
|
positionLevelNameTH: positionLevelName,
|
|
retireDate,
|
|
organizeNameTH: organizeName,
|
|
retireTypeNameTH: retireTypeName,
|
|
},
|
|
};
|
|
|
|
const res = await axios.post(API_URL_BANGKOK + "/importData", body, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
return res.data;
|
|
} catch (error: any) {
|
|
if (error.response?.status === 500 && retryCount < maxRetries - 1) {
|
|
TokenCache.delete(`${clientId}:${clientSecret}`);
|
|
retryCount++;
|
|
continue;
|
|
}
|
|
throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถติดต่อ API ได้");
|
|
}
|
|
}
|
|
}
|