start project
This commit is contained in:
commit
0703810fa3
62 changed files with 12665 additions and 0 deletions
7
.dockerignore
Normal file
7
.dockerignore
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
12
.env.example
Normal file
12
.env.example
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
AUTH_REALM_URL=http://192.168.1.200:8080/realms/dev
|
||||||
|
AUTH_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1/QAH75nWgiRzWCTrGJv8q2A7z0qggC2IQ9Sva/Ok1RxeGE/ED2m4ELbF5B9MtugyXYGMUBXaKhooMpTE3wyR1OwsUlv/GtYSmMuKUnsSEXklsP8nIq8gZkCvISOVdvIC4ng5aZ5nBcp9cQ3eVbz4dfZcbLzcqLIIkxQmFBK0m1eFL5IdNj8Ac7U4eH4ylOckOu174f35NnFH6wDva6Iic3EXapMcE2BnXXCTajk2dmlWAzH13ybQBgHDfrOtulrmn1CzQxe9WUJes4qX5z72N05KsHvtUObaeN6cb+mIeH36GdysqgAdd2hhKkgUFXwtLPzldtrEc7xVyf3OLEg1QIDAQAB
|
||||||
|
AUTH_PREFERRED_MODE=online
|
||||||
|
|
||||||
|
APP_HOST=0.0.0.0
|
||||||
|
APP_PORT=3000
|
||||||
|
|
||||||
|
DB_HOST=192.168.1.200
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=
|
||||||
|
DB_NAME=dev
|
||||||
86
.github/workflows/release.yaml
vendored
Normal file
86
.github/workflows/release.yaml
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
name: release-test
|
||||||
|
run-name: release-test ${{ github.actor }}
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "version-[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
REGISTRY: docker.frappet.com
|
||||||
|
IMAGE_NAME: ehr/bma-ehr-node-service
|
||||||
|
DEPLOY_HOST: frappet.com
|
||||||
|
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||||
|
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-probation
|
||||||
|
jobs:
|
||||||
|
# act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||||
|
release-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# skip Set up QEMU because it fail on act and container
|
||||||
|
# Gen Version try to get version from tag or inut
|
||||||
|
- name: Set output tags
|
||||||
|
id: vars
|
||||||
|
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||||
|
- name: Gen Version
|
||||||
|
id: gen_ver
|
||||||
|
run: |
|
||||||
|
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||||
|
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||||
|
else
|
||||||
|
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
fi
|
||||||
|
if [[ $IMAGE_VER == '' ]]; then
|
||||||
|
IMAGE_VER='test-vBeta'
|
||||||
|
fi
|
||||||
|
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||||
|
- name: Check Version
|
||||||
|
run: |
|
||||||
|
echo $GITHUB_REF
|
||||||
|
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login in to registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{env.REGISTRY}}
|
||||||
|
username: ${{secrets.DOCKER_USER}}
|
||||||
|
password: ${{secrets.DOCKER_PASS}}
|
||||||
|
- name: Build and push docker image
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||||
|
- name: Remote Deployment
|
||||||
|
uses: appleboy/ssh-action@v0.1.8
|
||||||
|
with:
|
||||||
|
host: ${{env.DEPLOY_HOST}}
|
||||||
|
username: frappet
|
||||||
|
password: ${{ secrets.SSH_PASSWORD }}
|
||||||
|
port: 10102
|
||||||
|
script: |
|
||||||
|
cd "${{env.COMPOSE_PATH}}"
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||||
|
- uses: snow-actions/line-notify@v1.1.0
|
||||||
|
if: success()
|
||||||
|
with:
|
||||||
|
access_token: ${{ secrets.TOKEN_LINE }}
|
||||||
|
message: |
|
||||||
|
-Success✅✅✅
|
||||||
|
Image: ${{env.IMAGE_NAME}}
|
||||||
|
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||||
|
By: ${{github.actor}}
|
||||||
|
- uses: snow-actions/line-notify@v1.1.0
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
access_token: ${{ secrets.TOKEN_LINE }}
|
||||||
|
message: |
|
||||||
|
-Failure❌❌❌
|
||||||
|
Image: ${{env.IMAGE_NAME}}
|
||||||
|
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||||
|
By: ${{github.actor}}
|
||||||
133
.gitignore
vendored
Normal file
133
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
[Ss]rc/swagger.json
|
||||||
|
[Ss]rc/routes.ts
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
18
.prettierignore
Normal file
18
.prettierignore
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
/dist
|
||||||
|
/static
|
||||||
|
/src/routes.ts
|
||||||
|
/src/swagger.json
|
||||||
|
|
||||||
|
# Any log
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
35
Dockerfile
Normal file
35
Dockerfile
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
FROM node:18-alpine as builder
|
||||||
|
|
||||||
|
# Create app directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install app dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
USER node
|
||||||
|
|
||||||
|
# Create app directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install app dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
# COPY .env ./
|
||||||
|
|
||||||
|
RUN npm ci --production
|
||||||
|
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
# COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
# RUN chmod u+x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD [ "node", "dist/app.js" ]
|
||||||
21
README.md
Normal file
21
README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# bma-ehr-probation
|
||||||
|
|
||||||
|
Envelopment
|
||||||
|
|
||||||
|
- Node 20.x
|
||||||
|
- Express
|
||||||
|
- Mysql
|
||||||
|
|
||||||
|
Run Project
|
||||||
|
|
||||||
|
```
|
||||||
|
> npm install
|
||||||
|
> npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Migration
|
||||||
|
|
||||||
|
1. สร้าง entities
|
||||||
|
2. สร้างไฟล์ migration จาก entities และรัน update เข้า database
|
||||||
|
> npm run migration:generate src/migration/xxx (xxx คือชื่อไฟล์ migrate)
|
||||||
|
> npm run migration:run
|
||||||
6
nodemon.json
Normal file
6
nodemon.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"exec": "tsoa spec-and-routes && ts-node src/app.ts",
|
||||||
|
"ext": "ts",
|
||||||
|
"watch": ["src"],
|
||||||
|
"ignore": ["src/routes.ts"]
|
||||||
|
}
|
||||||
49
package.json
Normal file
49
package.json
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"name": "template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "src/app.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nodemon",
|
||||||
|
"check": "tsc --noEmit",
|
||||||
|
"start": "node ./dist/app.js",
|
||||||
|
"format": "prettier --write .",
|
||||||
|
"build": "tsoa spec-and-routes && tsc",
|
||||||
|
"migration:generate": "typeorm-ts-node-commonjs migration:generate -d src/database/data-source.ts",
|
||||||
|
"migration:run": "typeorm-ts-node-commonjs migration:run -d src/database/data-source.ts"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/cors": "^2.8.17",
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
|
"@types/node": "^20.11.5",
|
||||||
|
"@types/node-cron": "^3.0.11",
|
||||||
|
"@types/swagger-ui-express": "^4.1.6",
|
||||||
|
"nodemon": "^3.0.3",
|
||||||
|
"prettier": "^3.2.2",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@elastic/elasticsearch": "^8.14.0",
|
||||||
|
"@nestjs/platform-express": "^10.3.7",
|
||||||
|
"@tsoa/runtime": "^6.0.0",
|
||||||
|
"axios": "^1.6.8",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"fast-jwt": "^3.3.2",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"mysql2": "^3.9.1",
|
||||||
|
"node-cron": "^3.0.3",
|
||||||
|
"promise.any": "^2.0.6",
|
||||||
|
"reflect-metadata": "^0.2.1",
|
||||||
|
"swagger-ui-express": "^5.0.0",
|
||||||
|
"tsoa": "^6.0.1",
|
||||||
|
"typeorm": "^0.3.19",
|
||||||
|
"typeorm-cli": "^1.0.7",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/app.ts
Normal file
47
src/app.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import "dotenv/config";
|
||||||
|
import "reflect-metadata";
|
||||||
|
import cors from "cors";
|
||||||
|
import express from "express";
|
||||||
|
import swaggerUi from "swagger-ui-express";
|
||||||
|
import swaggerDocument from "./swagger.json";
|
||||||
|
import * as cron from "node-cron";
|
||||||
|
import error from "./middlewares/error";
|
||||||
|
import { AppDataSource } from "./database/data-source";
|
||||||
|
import { RegisterRoutes } from "./routes";
|
||||||
|
// import logMiddleware from "./middlewares/logs";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
await AppDataSource.initialize();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
cors({
|
||||||
|
origin: "*",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({ extended: true }));
|
||||||
|
// app.use(logMiddleware);
|
||||||
|
app.use("/", express.static("static"));
|
||||||
|
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));
|
||||||
|
|
||||||
|
RegisterRoutes(app);
|
||||||
|
|
||||||
|
app.use(error);
|
||||||
|
const APP_HOST = process.env.APP_HOST || "0.0.0.0";
|
||||||
|
const APP_PORT = +(process.env.APP_PORT || 3000);
|
||||||
|
|
||||||
|
app.listen(
|
||||||
|
APP_PORT,
|
||||||
|
APP_HOST,
|
||||||
|
() => (
|
||||||
|
console.log(
|
||||||
|
`[APP] Application is running on: http://localhost:${APP_PORT}`
|
||||||
|
),
|
||||||
|
console.log(`[APP] Swagger on: http://localhost:${APP_PORT}/api-docs`)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
761
src/controllers/AssignController.ts
Normal file
761
src/controllers/AssignController.ts
Normal file
|
|
@ -0,0 +1,761 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Body,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Query,
|
||||||
|
} from "tsoa";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { findEndDate, setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { Personal } from "../entities/Personal";
|
||||||
|
import permission from "../interfaces/permission";
|
||||||
|
import { Assign, CreateAssign } from "../entities/Assign";
|
||||||
|
import {
|
||||||
|
AssignDirector,
|
||||||
|
CreateAssignDirector,
|
||||||
|
} from "../entities/AssignDirector";
|
||||||
|
import { AssignJob, CreateAssignJob } from "../entities/AssignJob";
|
||||||
|
import {
|
||||||
|
AssignKnowledge,
|
||||||
|
CreateAssignKnowledge,
|
||||||
|
} from "../entities/AssignKnowledge";
|
||||||
|
import { AssignLaw, CreateAssignLaw } from "../entities/AssignLaw";
|
||||||
|
import { AssignSkill, CreateAssignSkill } from "../entities/AssignSkill";
|
||||||
|
import {
|
||||||
|
AssignCompetency,
|
||||||
|
CreateAssignCompetency,
|
||||||
|
} from "../entities/AssignCompetency";
|
||||||
|
import {
|
||||||
|
AssignCompetencyGroup,
|
||||||
|
CreateAssignCompetencyGroup,
|
||||||
|
} from "../entities/AssignCompetencyGroup";
|
||||||
|
import { AssignOutput, CreateAssignOutput } from "../entities/AssignOutput";
|
||||||
|
import { Law } from "../entities/Law";
|
||||||
|
import CallAPI from "../interfaces/call-api";
|
||||||
|
|
||||||
|
@Route("api/v1/assign")
|
||||||
|
@Tags("ฟอร์มมอบหมายงาน")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class AssignController extends Controller {
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
private assignDirectorRepository =
|
||||||
|
AppDataSource.getRepository(AssignDirector);
|
||||||
|
private assignJobRepository = AppDataSource.getRepository(AssignJob);
|
||||||
|
private assignKnowledgeRepository =
|
||||||
|
AppDataSource.getRepository(AssignKnowledge);
|
||||||
|
private assignLawRepository = AppDataSource.getRepository(AssignLaw);
|
||||||
|
private assignSkillRepository = AppDataSource.getRepository(AssignSkill);
|
||||||
|
private assignCompetencyRepository =
|
||||||
|
AppDataSource.getRepository(AssignCompetency);
|
||||||
|
private assignCompetencyGroupRepository = AppDataSource.getRepository(
|
||||||
|
AssignCompetencyGroup
|
||||||
|
);
|
||||||
|
private assignOutputRepository = AppDataSource.getRepository(AssignOutput);
|
||||||
|
private lawsRepository = AppDataSource.getRepository(Law);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API เพิ่มข้อมูลการมอบหมายงาน
|
||||||
|
*
|
||||||
|
* @summary เพิ่มข้อมูลการมอบหมายงาน
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async AddAssign(
|
||||||
|
@Request() request: RequestWithUser,
|
||||||
|
@Body() requestBody: CreateAssign
|
||||||
|
) {
|
||||||
|
await new permission().PermissionUpdate(request, "SYS_PROBATION");
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
where: {
|
||||||
|
personal_id: requestBody.personal_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const roundNo = await this.assignRepository.count({
|
||||||
|
where: {
|
||||||
|
active: 1,
|
||||||
|
personal_id: requestBody.personal_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const data: any = {
|
||||||
|
...requestBody,
|
||||||
|
round_no: roundNo + 1,
|
||||||
|
personal_id: requestBody.personal_id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
const before = null;
|
||||||
|
const assign = await this.assignRepository.save(data, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: data });
|
||||||
|
|
||||||
|
const jobs = await requestBody.assign_jobs.map(
|
||||||
|
(x: CreateAssignJob, index: number) => ({
|
||||||
|
...x,
|
||||||
|
id: index + 1,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignJobRepository.save(jobs, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: jobs });
|
||||||
|
|
||||||
|
const knowledges = await requestBody.assign_knowledges.map(
|
||||||
|
(x: CreateAssignKnowledge, index: number) => ({
|
||||||
|
knowledge_level: x.level,
|
||||||
|
knowledge_id: x.id,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignKnowledgeRepository.save(knowledges, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: knowledges });
|
||||||
|
|
||||||
|
const laws = await requestBody.assign_law.map(
|
||||||
|
(x: CreateAssignLaw, index: number) => ({
|
||||||
|
ordering: index + 1,
|
||||||
|
law_id: x.id,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignLawRepository.save(laws, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: laws });
|
||||||
|
|
||||||
|
const skills = await requestBody.assign_skill.map(
|
||||||
|
(x: CreateAssignSkill, index: number) => ({
|
||||||
|
skill_id: index + 1,
|
||||||
|
skill_level: x.level,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignSkillRepository.save(skills, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: skills });
|
||||||
|
|
||||||
|
const competencise = await requestBody.assign_competency.map(
|
||||||
|
(x: CreateAssignCompetency, index: number) => ({
|
||||||
|
competency_id: x.id,
|
||||||
|
competency_level: x.level,
|
||||||
|
competency_name: x.name,
|
||||||
|
competency_description: x.description,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignCompetencyRepository.save(competencise, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: competencise });
|
||||||
|
|
||||||
|
const competencyGroups = await requestBody.assign_competency_group.map(
|
||||||
|
(x: CreateAssignCompetencyGroup, index: number) => ({
|
||||||
|
competency_group_id: x.id,
|
||||||
|
competency_group_level: x.level,
|
||||||
|
competency_group_name: x.name,
|
||||||
|
competency_group_description: x.description,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignCompetencyGroupRepository.save(competencyGroups, {
|
||||||
|
data: request,
|
||||||
|
});
|
||||||
|
setLogDataDiff(request, { before, after: competencyGroups });
|
||||||
|
|
||||||
|
const outputs = await requestBody.assign_outputs.map(
|
||||||
|
(x: CreateAssignOutput, index: number) => ({
|
||||||
|
...x,
|
||||||
|
id: index + 1,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignOutputRepository.save(outputs, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: outputs });
|
||||||
|
|
||||||
|
const directors = await requestBody.assign_director.map(
|
||||||
|
(x: CreateAssignDirector, index: number) => ({
|
||||||
|
...x,
|
||||||
|
assign_id: assign.id,
|
||||||
|
fullname: x.name,
|
||||||
|
ordering: index + 1,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignDirectorRepository.save(directors, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: directors });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API แก้ไขข้อมูลการมอบหมายงาน
|
||||||
|
*
|
||||||
|
* @summary แก้ไขแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Put("")
|
||||||
|
async EditAssign(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser,
|
||||||
|
@Body() requestBody: CreateAssign
|
||||||
|
) {
|
||||||
|
await new permission().PermissionUpdate(request, "SYS_PROBATION");
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
let before = assign;
|
||||||
|
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
where: {
|
||||||
|
personal_id: requestBody.personal_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: any = {
|
||||||
|
...requestBody,
|
||||||
|
id: assign_id,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.assignJobRepository.delete({ assign_id });
|
||||||
|
const jobs = await requestBody.assign_jobs.map(
|
||||||
|
(x: CreateAssignJob, index: number) => ({
|
||||||
|
...x,
|
||||||
|
id: index + 1,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignJobRepository.save(jobs);
|
||||||
|
|
||||||
|
await this.assignKnowledgeRepository.delete({ assign_id });
|
||||||
|
const knowledges = await requestBody.assign_knowledges.map(
|
||||||
|
(x: CreateAssignKnowledge, index: number) => ({
|
||||||
|
knowledge_level: x.level,
|
||||||
|
knowledge_id: x.id,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignKnowledgeRepository.save(knowledges);
|
||||||
|
|
||||||
|
await this.assignLawRepository.delete({ assign_id });
|
||||||
|
const laws = await requestBody.assign_law.map(
|
||||||
|
(x: CreateAssignLaw, index: number) => ({
|
||||||
|
ordering: index + 1,
|
||||||
|
law_id: x.id,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignLawRepository.save(laws);
|
||||||
|
|
||||||
|
await this.assignSkillRepository.delete({ assign_id });
|
||||||
|
const skills = await requestBody.assign_skill.map(
|
||||||
|
(x: CreateAssignSkill, index: number) => ({
|
||||||
|
skill_id: index + 1,
|
||||||
|
skill_level: x.level,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignSkillRepository.save(skills);
|
||||||
|
|
||||||
|
await this.assignCompetencyRepository.delete({ assign_id });
|
||||||
|
const competencise = await requestBody.assign_competency.map(
|
||||||
|
(x: CreateAssignCompetency, index: number) => ({
|
||||||
|
competency_id: x.id,
|
||||||
|
competency_level: x.level,
|
||||||
|
competency_name: x.name,
|
||||||
|
competency_description: x.description,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignCompetencyRepository.save(competencise);
|
||||||
|
|
||||||
|
await this.assignCompetencyGroupRepository.delete({ assign_id });
|
||||||
|
const competencyGroups = await requestBody.assign_competency_group.map(
|
||||||
|
(x: CreateAssignCompetencyGroup, index: number) => ({
|
||||||
|
competency_group_id: x.id,
|
||||||
|
competency_group_level: x.level,
|
||||||
|
competency_group_name: x.name,
|
||||||
|
competency_group_description: x.description,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignCompetencyGroupRepository.save(competencyGroups);
|
||||||
|
|
||||||
|
await this.assignOutputRepository.delete({ assign_id });
|
||||||
|
const outputs = await requestBody.assign_outputs.map(
|
||||||
|
(x: CreateAssignOutput, index: number) => ({
|
||||||
|
...x,
|
||||||
|
id: index + 1,
|
||||||
|
assign_id: assign.id,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignOutputRepository.save(outputs);
|
||||||
|
|
||||||
|
await this.assignDirectorRepository.delete({ assign_id });
|
||||||
|
const directors = await requestBody.assign_director.map(
|
||||||
|
(x: CreateAssignDirector, index: number) => ({
|
||||||
|
...x,
|
||||||
|
assign_id: assign.id,
|
||||||
|
fullname: x.name,
|
||||||
|
ordering: index + 1,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
await this.assignDirectorRepository.save(directors);
|
||||||
|
|
||||||
|
await this.assignRepository.save(data, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: data });
|
||||||
|
|
||||||
|
// #noted cronjob
|
||||||
|
// แจ้งผู้ดูแลและผู้บังคับบัญชาเข้ามาบันทึกผลทุก 2 เดือน
|
||||||
|
const dateSaveForm = await findEndDate(2, requestBody.date_start);
|
||||||
|
requestBody.assign_director
|
||||||
|
.filter((x) => x.role == "mentor" || x.role == "commander")
|
||||||
|
.map(async (director) => {
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`,
|
||||||
|
body: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`,
|
||||||
|
receiverUserId: director.personal_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
receiveDate: dateSaveForm,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// แจ้งผู้บังคับบัญชา และคณะกรรมการเข้ามาประเมินทุก 3 เดือน
|
||||||
|
const dateEvaluate = await findEndDate(3, requestBody.date_start);
|
||||||
|
requestBody.assign_director
|
||||||
|
.filter((x) => x.role == "commander" || x.role == "chairman")
|
||||||
|
.map(async (director) => {
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`,
|
||||||
|
body: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`,
|
||||||
|
receiverUserId: director.personal_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
receiveDate: dateEvaluate,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// แจ้งประธาน 6 เดือน
|
||||||
|
const dateResult = await findEndDate(6, requestBody.date_start);
|
||||||
|
requestBody.assign_director
|
||||||
|
.filter((x) => x.role == "chairman")
|
||||||
|
.map(async (director) => {
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`,
|
||||||
|
body: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`,
|
||||||
|
receiverUserId: director.personal_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
// isSendNotification: true
|
||||||
|
receiveDate: dateResult,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API รายการข้อมูลการมอบหมายงาน
|
||||||
|
*
|
||||||
|
* @summary รายการการมอบหมายงาน
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("assign-list")
|
||||||
|
async ListPersonal(
|
||||||
|
@Request() request: RequestWithUser,
|
||||||
|
@Query() personal_id: string
|
||||||
|
) {
|
||||||
|
await new permission().PermissionGet(request, "SYS_PROBATION");
|
||||||
|
const lists = await this.assignRepository.find({
|
||||||
|
select: ["id", "round_no", "date_start", "date_finish"],
|
||||||
|
where: { personal_id },
|
||||||
|
order: { round_no: "ASC" },
|
||||||
|
});
|
||||||
|
|
||||||
|
let result: any = [];
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
lists.map(async (item) => {
|
||||||
|
const director = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id: item.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
let mentors = "";
|
||||||
|
const mentorList = await director.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors += e.fullname;
|
||||||
|
if (index < mentorList.length - 1) {
|
||||||
|
mentors += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (director.find(
|
||||||
|
(x) => x.role == "commander"
|
||||||
|
) ?? null);
|
||||||
|
const commander = commanderData ? commanderData.fullname : null;
|
||||||
|
|
||||||
|
const chairmanData = await (director.find(
|
||||||
|
(x) => x.role == "chairman"
|
||||||
|
) ?? null);
|
||||||
|
const chairman = chairmanData ? chairmanData.fullname : null;
|
||||||
|
|
||||||
|
await result.push({
|
||||||
|
...item,
|
||||||
|
mentors: mentors,
|
||||||
|
commander: commander,
|
||||||
|
chairman: chairman,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ
|
||||||
|
*
|
||||||
|
* @summary ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetAssign(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
await new permission().PermissionUpdate(request, "SYS_PROBATION");
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
select: [
|
||||||
|
"id",
|
||||||
|
"personal_id",
|
||||||
|
"round_no",
|
||||||
|
"date_start",
|
||||||
|
"date_finish",
|
||||||
|
"other4_desc",
|
||||||
|
"other5_no1_desc",
|
||||||
|
"experimenter_dated",
|
||||||
|
"active",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const profileData = await this.personalRepository.findOne({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"prefixName",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"positionName",
|
||||||
|
"positionLevelName",
|
||||||
|
"positionLineName",
|
||||||
|
"orgRootName",
|
||||||
|
"organization",
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
personal_id: assign.personal_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!profileData) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = {
|
||||||
|
...profileData,
|
||||||
|
name: `${profileData.prefixName}${profileData.firstName} ${profileData.lastName}`,
|
||||||
|
Position: profileData.positionName,
|
||||||
|
Department: "-",
|
||||||
|
OrganizationOrganization: profileData.orgRootName,
|
||||||
|
Oc: profileData.organization,
|
||||||
|
};
|
||||||
|
|
||||||
|
const jobs = await this.assignJobRepository.find({
|
||||||
|
select: ["id", "activity_desc", "goal_desc"],
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const knowledgeData = await this.assignKnowledgeRepository.find({
|
||||||
|
relations: ["knowledge"],
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
const knowledges = await knowledgeData.map((x) => ({
|
||||||
|
id: x.knowledge_id,
|
||||||
|
level: x.knowledge_level,
|
||||||
|
title: x.knowledge.title,
|
||||||
|
description:
|
||||||
|
x.knowledge_level == 1
|
||||||
|
? x.knowledge.level1
|
||||||
|
: x.knowledge_level == 2
|
||||||
|
? x.knowledge.level2
|
||||||
|
: x.knowledge_level == 3
|
||||||
|
? x.knowledge.level3
|
||||||
|
: x.knowledge_level == 4
|
||||||
|
? x.knowledge.level4
|
||||||
|
: x.knowledge_level == 5
|
||||||
|
? x.knowledge.level5
|
||||||
|
: "",
|
||||||
|
}));
|
||||||
|
|
||||||
|
const lawData = await this.lawsRepository.find({
|
||||||
|
where: { active: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const laws = await lawData.map((x) => ({
|
||||||
|
id: x.id,
|
||||||
|
selected: x.assignLaw ? 1 : 0,
|
||||||
|
description: x.description,
|
||||||
|
status_select: x.status_select,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const skillsData = await this.assignSkillRepository.find({
|
||||||
|
relations: ["skill"],
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const skills = await skillsData.map((x) => ({
|
||||||
|
id: x.skill_id,
|
||||||
|
level: x.skill_level,
|
||||||
|
title: x.skill.title,
|
||||||
|
description:
|
||||||
|
x.skill_level == 1
|
||||||
|
? x.skill.level1
|
||||||
|
: x.skill_level == 2
|
||||||
|
? x.skill.level2
|
||||||
|
: x.skill_level == 3
|
||||||
|
? x.skill.level3
|
||||||
|
: x.skill_level == 4
|
||||||
|
? x.skill.level4
|
||||||
|
: x.skill_level == 5
|
||||||
|
? x.skill.level5
|
||||||
|
: "",
|
||||||
|
}));
|
||||||
|
|
||||||
|
const competencyData = await this.assignCompetencyRepository.find({
|
||||||
|
select: [
|
||||||
|
"competency_id",
|
||||||
|
"competency_level",
|
||||||
|
"competency_name",
|
||||||
|
"competency_description",
|
||||||
|
],
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const competencys = await competencyData.map((x) => ({
|
||||||
|
id: x.competency_id,
|
||||||
|
level: x.competency_level,
|
||||||
|
name: x.competency_name,
|
||||||
|
description: x.competency_description,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const competencyGroupData = await this.assignCompetencyGroupRepository.find(
|
||||||
|
{
|
||||||
|
select: [
|
||||||
|
"competency_group_id",
|
||||||
|
"competency_group_level",
|
||||||
|
"competency_group_name",
|
||||||
|
"competency_group_description",
|
||||||
|
],
|
||||||
|
where: { assign_id },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const competency_groups = await competencyGroupData.map((x) => ({
|
||||||
|
id: x.competency_group_id,
|
||||||
|
level: x.competency_group_level,
|
||||||
|
name: x.competency_group_name,
|
||||||
|
description: x.competency_group_description,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const outputs = await this.assignOutputRepository.find({
|
||||||
|
select: ["id", "output_desc", "indicator_desc"],
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const director = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
let mentors = [];
|
||||||
|
const mentorList = await director.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors.push({
|
||||||
|
...e,
|
||||||
|
name: e.fullname,
|
||||||
|
label:
|
||||||
|
e.fullname +
|
||||||
|
" " +
|
||||||
|
(e.position ? `(${e.position}, ${e.posType}: ${e.posLevel})` : ""),
|
||||||
|
Position: e.position, // report
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (director.find((x) => x.role == "commander") ??
|
||||||
|
null);
|
||||||
|
const commander = await (commanderData
|
||||||
|
? {
|
||||||
|
...commanderData,
|
||||||
|
name: commanderData.fullname,
|
||||||
|
label:
|
||||||
|
commanderData.fullname +
|
||||||
|
" " +
|
||||||
|
(commanderData.position
|
||||||
|
? `(${commanderData.position}, ${commanderData.posType}: ${commanderData.posLevel})`
|
||||||
|
: ""),
|
||||||
|
Position: commanderData.position, // report
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
|
||||||
|
const chairmanData = await (director.find((x) => x.role == "chairman") ??
|
||||||
|
null);
|
||||||
|
const chairman = await (chairmanData
|
||||||
|
? {
|
||||||
|
...chairmanData,
|
||||||
|
name: chairmanData.fullname,
|
||||||
|
label:
|
||||||
|
chairmanData.fullname +
|
||||||
|
" " +
|
||||||
|
(chairmanData.position
|
||||||
|
? `(${chairmanData.position}, ${chairmanData.posType}: ${chairmanData.posLevel})`
|
||||||
|
: ""),
|
||||||
|
Position: chairmanData.position, // report
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
assign,
|
||||||
|
profile,
|
||||||
|
jobs,
|
||||||
|
knowledges,
|
||||||
|
laws,
|
||||||
|
skills,
|
||||||
|
competencys,
|
||||||
|
competency_groups,
|
||||||
|
outputs,
|
||||||
|
mentors,
|
||||||
|
commander,
|
||||||
|
chairman,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/controllers/CalculateController.ts
Normal file
47
src/controllers/CalculateController.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
} from "tsoa";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { findEndDate } from "../interfaces/utils";
|
||||||
|
|
||||||
|
@Route("api/v1/calculate")
|
||||||
|
@Tags("ฟอร์มมอบหมายงาน")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class CalculateController extends Controller {
|
||||||
|
/**
|
||||||
|
* API คำนวนวันสิ้นสุดตามวันที่เริ่มและระยะเวลาเดือนตามที่ส่งค่ามา
|
||||||
|
*
|
||||||
|
* @summary คำนวนวันสิ้นสุดตามวันที่เริ่มและระยะเวลาเดือนตามที่ส่งค่ามา
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("assign-finish")
|
||||||
|
async AssignFinish(
|
||||||
|
@Body()
|
||||||
|
requestBody: {
|
||||||
|
month: number;
|
||||||
|
start_date: Date;
|
||||||
|
},
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const { month, start_date } = requestBody;
|
||||||
|
const finish_date = findEndDate(month, start_date);
|
||||||
|
|
||||||
|
return new HttpSuccess({ finish_date });
|
||||||
|
}
|
||||||
|
}
|
||||||
302
src/controllers/DataOptionsController.ts
Normal file
302
src/controllers/DataOptionsController.ts
Normal file
|
|
@ -0,0 +1,302 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Path,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Query,
|
||||||
|
} from "tsoa";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { Knowledge, TypeKnowledge } from "../entities/Knowledge";
|
||||||
|
import { Skill, TypeSkill } from "../entities/Skill";
|
||||||
|
import { MapKnowledgeSkill } from "../entities/MapKnowledgeSkill";
|
||||||
|
import { Personal } from "../entities/Personal";
|
||||||
|
import { Law } from "../entities/Law";
|
||||||
|
import { Assign } from "../entities/Assign";
|
||||||
|
|
||||||
|
@Route("api/v1/data-options")
|
||||||
|
@Tags("Data Options")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class DataOptionController extends Controller {
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
private knowledgeRepository = AppDataSource.getRepository(Knowledge);
|
||||||
|
private mapKnowledgeSkillRepository =
|
||||||
|
AppDataSource.getRepository(MapKnowledgeSkill);
|
||||||
|
private skillRepository = AppDataSource.getRepository(Skill);
|
||||||
|
private lawRepository = AppDataSource.getRepository(Law);
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API list รายการความรู้
|
||||||
|
*
|
||||||
|
* @summary options ความรู้
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("knowledge")
|
||||||
|
async GetKnowledge(
|
||||||
|
@Query() personal_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
where: { personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(person);
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.mapKnowledgeSkillRepository.findOne({
|
||||||
|
where: {
|
||||||
|
positionName: person.positionName,
|
||||||
|
positionLevelName: person.positionLevelName,
|
||||||
|
active: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const knowledges = await this.knowledgeRepository.find({
|
||||||
|
where: { type: TypeKnowledge.PERFORMANCE, active: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const knowledge = knowledges.map((knowledge) => ({
|
||||||
|
id: knowledge.id,
|
||||||
|
title: knowledge.title,
|
||||||
|
description:
|
||||||
|
result.knowlage_performance_level == 1
|
||||||
|
? knowledge.level1
|
||||||
|
: result.knowlage_performance_level == 2
|
||||||
|
? knowledge.level2
|
||||||
|
: result.knowlage_performance_level == 3
|
||||||
|
? knowledge.level3
|
||||||
|
: result.knowlage_performance_level == 4
|
||||||
|
? knowledge.level4
|
||||||
|
: knowledge.level5,
|
||||||
|
level: result.knowlage_performance_level,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess(knowledge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลทักษะ
|
||||||
|
*
|
||||||
|
* @summary options ทักษะ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("skill")
|
||||||
|
async GetSkill(
|
||||||
|
@Query() personal_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
where: { personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.mapKnowledgeSkillRepository.findOne({
|
||||||
|
select: [
|
||||||
|
"skill_computer_level",
|
||||||
|
"skill_english_level",
|
||||||
|
"skill_information_level",
|
||||||
|
"skill_resourse_level",
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
positionName: person.positionName,
|
||||||
|
positionLevelName: person.positionLevelName,
|
||||||
|
active: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const skills = await this.skillRepository.find({
|
||||||
|
where: { type: TypeSkill.COMPUTER, active: 1 },
|
||||||
|
});
|
||||||
|
const skill = await skills.map((v) => ({
|
||||||
|
id: v.id,
|
||||||
|
title: v.title,
|
||||||
|
level_description:
|
||||||
|
result.skill_english_level == 1
|
||||||
|
? v.level1
|
||||||
|
: result.skill_english_level == 2
|
||||||
|
? v.level2
|
||||||
|
: result.skill_english_level == 3
|
||||||
|
? v.level3
|
||||||
|
: result.skill_english_level == 4
|
||||||
|
? v.level4
|
||||||
|
: v.level5,
|
||||||
|
level: result.skill_english_level,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const englishs = await this.skillRepository.find({
|
||||||
|
where: { type: TypeSkill.ENG, active: 1 },
|
||||||
|
});
|
||||||
|
const english = await englishs.map((v) => ({
|
||||||
|
id: v.id,
|
||||||
|
title: v.title,
|
||||||
|
level_description:
|
||||||
|
result.skill_english_level == 1
|
||||||
|
? v.level1
|
||||||
|
: result.skill_english_level == 2
|
||||||
|
? v.level2
|
||||||
|
: result.skill_english_level == 3
|
||||||
|
? v.level3
|
||||||
|
: result.skill_english_level == 4
|
||||||
|
? v.level4
|
||||||
|
: v.level5,
|
||||||
|
level: result.skill_english_level,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const informations = await this.skillRepository.find({
|
||||||
|
where: { type: TypeSkill.INFORMATION, active: 1 },
|
||||||
|
});
|
||||||
|
const information = await informations.map((v) => ({
|
||||||
|
id: v.id,
|
||||||
|
title: v.title,
|
||||||
|
level_description:
|
||||||
|
result.skill_information_level == 1
|
||||||
|
? v.level1
|
||||||
|
: result.skill_information_level == 2
|
||||||
|
? v.level2
|
||||||
|
: result.skill_information_level == 3
|
||||||
|
? v.level3
|
||||||
|
: result.skill_information_level == 4
|
||||||
|
? v.level4
|
||||||
|
: v.level5,
|
||||||
|
level: result.skill_information_level,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const resourses = await this.skillRepository.find({
|
||||||
|
where: { type: TypeSkill.RESOURSE, active: 1 },
|
||||||
|
});
|
||||||
|
const resourse = await resourses.map((v) => ({
|
||||||
|
id: v.id,
|
||||||
|
title: v.title,
|
||||||
|
level_description:
|
||||||
|
result.skill_resourse_level == 1
|
||||||
|
? v.level1
|
||||||
|
: result.skill_resourse_level == 2
|
||||||
|
? v.level2
|
||||||
|
: result.skill_resourse_level == 3
|
||||||
|
? v.level3
|
||||||
|
: result.skill_resourse_level == 4
|
||||||
|
? v.level4
|
||||||
|
: v.level5,
|
||||||
|
level: result.skill_resourse_level,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
computer: skill,
|
||||||
|
english: english,
|
||||||
|
information: information,
|
||||||
|
resourse: resourse,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API list รายการกฎหมาย
|
||||||
|
*
|
||||||
|
* @summary options กฎหมาย
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("law")
|
||||||
|
async GetLaw(
|
||||||
|
@Query() personal_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const results = await this.lawRepository.find({
|
||||||
|
select: ["id", "parent_id", "description", "status_select"],
|
||||||
|
where: {
|
||||||
|
active: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!results) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await results.map((v) => ({
|
||||||
|
...v,
|
||||||
|
checked: 0,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ดึงข้อมูลจำนวนครั้งแบบมอบหมายงานและข้อมูลผู้ทดลอง
|
||||||
|
*
|
||||||
|
* @summary จำนวนครั้งแบบมอบหมายงานและข้อมูลผู้ทดลอง
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("new-assign")
|
||||||
|
async NewAssign(
|
||||||
|
@Query() personal_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"prefixName",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"posNo",
|
||||||
|
"positionName",
|
||||||
|
"positionLevelName",
|
||||||
|
"positionLineName",
|
||||||
|
"isProbation",
|
||||||
|
"orgRootName",
|
||||||
|
"organization",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
],
|
||||||
|
where: { personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.count({
|
||||||
|
where: {
|
||||||
|
personal_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const responsePerson = {
|
||||||
|
id: person.personal_id,
|
||||||
|
...person,
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = await {
|
||||||
|
person: responsePerson,
|
||||||
|
assign_no: assign + 1,
|
||||||
|
assign_month: 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpSuccess({ data: data });
|
||||||
|
}
|
||||||
|
}
|
||||||
444
src/controllers/EvaluateChairmanController.ts
Normal file
444
src/controllers/EvaluateChairmanController.ts
Normal file
|
|
@ -0,0 +1,444 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
Query,
|
||||||
|
Put,
|
||||||
|
} from "tsoa";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { findEndDate, setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { AssignDirector } from "../entities/AssignDirector";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { Assign } from "../entities/Assign";
|
||||||
|
import { Personal } from "../entities/Personal";
|
||||||
|
import CallAPI from "../interfaces/call-api";
|
||||||
|
import {
|
||||||
|
CreateEvaluateChairman,
|
||||||
|
EvaluateChairman,
|
||||||
|
} from "../entities/EvaluateChairman";
|
||||||
|
|
||||||
|
@Route("api/v1/evaluate-chairman")
|
||||||
|
@Tags("แบบประเมินผล (คณะกรรมการ)")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class EvaluateChairmanController extends Controller {
|
||||||
|
private assignDirectorRepository =
|
||||||
|
AppDataSource.getRepository(AssignDirector);
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
private evaluateChairmanRepository =
|
||||||
|
AppDataSource.getRepository(EvaluateChairman);
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลตอนกดสร้างแบบประเมินผล (คณะกรรมการ)
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลตอนกดสร้างแบบประเมินผล (คณะกรรมการ)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("create")
|
||||||
|
async CreateEvaluate(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "chairman",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = await (assign.profile
|
||||||
|
? {
|
||||||
|
...assign.profile,
|
||||||
|
id: assign.profile.personal_id,
|
||||||
|
name:
|
||||||
|
assign.profile.prefixName +
|
||||||
|
assign.profile.firstName +
|
||||||
|
" " +
|
||||||
|
assign.profile.lastName,
|
||||||
|
Oc: assign.profile.organization,
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
|
||||||
|
const evaluate_amount = await this.evaluateChairmanRepository.count({
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
director_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const evaluate_no = await (evaluate_amount + 1);
|
||||||
|
const start_date =
|
||||||
|
evaluate_amount == 0
|
||||||
|
? assign.date_start
|
||||||
|
: findEndDate(evaluate_amount * 3, assign.date_start);
|
||||||
|
|
||||||
|
const directorData = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!directorData) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลผู้ดูแล ผู้บังคับบัญชาและประธาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mentors = "";
|
||||||
|
const mentorList = await directorData.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors += e.fullname;
|
||||||
|
if (index < mentorList.length - 1) {
|
||||||
|
mentors += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (directorData.find(
|
||||||
|
(x) => x.role == "commander"
|
||||||
|
) ?? null);
|
||||||
|
const commander = commanderData ? commanderData.fullname : null;
|
||||||
|
|
||||||
|
const chairmanData = await (directorData.find(
|
||||||
|
(x) => x.role == "chairman"
|
||||||
|
) ?? null);
|
||||||
|
const chairman = chairmanData ? chairmanData.fullname : null;
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
person: profile ? profile : null,
|
||||||
|
assign,
|
||||||
|
evaluate_no: evaluate_no,
|
||||||
|
start_date: start_date,
|
||||||
|
end_date: findEndDate(3, start_date),
|
||||||
|
commander,
|
||||||
|
mentors,
|
||||||
|
chairman,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลแบบประเมินผล (คณะกรรมการ)
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลแบบประเมินผล (คณะกรรมการ)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetEvaluate(@Query() assign_id: string, @Query() evaluate_no?: string) {
|
||||||
|
// ต้องปรับเป็น id ของคนที่ access เข้ามา
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "chairman",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
let evaluate: any = null;
|
||||||
|
if (evaluate_no) {
|
||||||
|
evaluate = await this.evaluateChairmanRepository.findOne({
|
||||||
|
where: {
|
||||||
|
director_id,
|
||||||
|
assign_id,
|
||||||
|
no: evaluate_no,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
evaluate = await this.evaluateChairmanRepository.findOne({
|
||||||
|
where: {
|
||||||
|
director_id,
|
||||||
|
assign_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const experimenteeData = await this.personalRepository.find({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"prefixName",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"positionName",
|
||||||
|
"positionLevelName",
|
||||||
|
"organization",
|
||||||
|
],
|
||||||
|
where: { personal_id: assign.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const experimentee = await experimenteeData.map((element) => ({
|
||||||
|
...element,
|
||||||
|
name: element.prefixName + element.firstName + " " + element.lastName,
|
||||||
|
Oc: element.organization,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const directorData = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!directorData) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลผู้ดูแล ผู้บังคับบัญชาและประธาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mentors = "";
|
||||||
|
const mentorList = await directorData.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors += e.fullname;
|
||||||
|
if (index < mentorList.length - 1) {
|
||||||
|
mentors += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (directorData.find(
|
||||||
|
(x) => x.role == "commander"
|
||||||
|
) ?? null);
|
||||||
|
const commander = commanderData ? commanderData.fullname : null;
|
||||||
|
|
||||||
|
const chairmanData = await (directorData.find(
|
||||||
|
(x) => x.role == "chairman"
|
||||||
|
) ?? null);
|
||||||
|
const chairman = chairmanData ? chairmanData.fullname : null;
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
experimentee: experimentee,
|
||||||
|
mentors: mentors,
|
||||||
|
commander: commander,
|
||||||
|
chairman: chairman,
|
||||||
|
assign,
|
||||||
|
evaluate,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API บันทึกข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary บันทึกข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async PostData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateChairman,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "chairman",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const postData: any = await {
|
||||||
|
assign_id,
|
||||||
|
...requestBody,
|
||||||
|
director_id,
|
||||||
|
no: requestBody.evaluate_no,
|
||||||
|
date_start: requestBody.start_date,
|
||||||
|
personal_id: assign.personal_id,
|
||||||
|
|
||||||
|
achievement_other_desc: requestBody.achievement_other
|
||||||
|
? requestBody.achievement_other.text
|
||||||
|
: "",
|
||||||
|
achievement_other_level: requestBody.achievement_other
|
||||||
|
? Number(requestBody.achievement_other.level)
|
||||||
|
: 0,
|
||||||
|
behavior_other_desc: requestBody.behavior_orther.text,
|
||||||
|
behavior_other_level:
|
||||||
|
requestBody.behavior_orther.text != ""
|
||||||
|
? Number(requestBody.behavior_orther.level)
|
||||||
|
: 0,
|
||||||
|
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.evaluateChairmanRepository.save(postData, {
|
||||||
|
data: request,
|
||||||
|
});
|
||||||
|
setLogDataDiff(request, { before: null, after: postData });
|
||||||
|
|
||||||
|
if (Number(requestBody.evaluate_no) < 2) {
|
||||||
|
// #noted cronjob
|
||||||
|
// แจ้งประธานเข้ามาบันทึกผลทุก 3 เดือน 2 ครั้ง
|
||||||
|
var dateSend = await findEndDate(3, requestBody.start_date);
|
||||||
|
const nextNo = await (Number(requestBody.evaluate_no) + 1);
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ ${nextNo} ${assign.profile.prefixName}${assign.profile.firstName} ${assign.profile.lastName}`,
|
||||||
|
body: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการ (สำหรับคณะกรรมการ) ครั้งที่ ${nextNo} ${assign.profile.prefixName}${assign.profile.firstName} ${assign.profile.lastName}`,
|
||||||
|
receiverUserId: director_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
receiveDate: dateSend,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API แก้ไขข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary แก้ไขข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Put("")
|
||||||
|
async UpdateData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Query() evaluate_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateChairman,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
let evaluate = await this.evaluateChairmanRepository.findOne({
|
||||||
|
where: { id: evaluate_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const before = evaluate;
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate.chairman_dated = requestBody.chairman_dated;
|
||||||
|
evaluate.director1_dated = requestBody.director1_dated;
|
||||||
|
evaluate.director2_dated = requestBody.director2_dated;
|
||||||
|
evaluate.knowledge_level = requestBody.knowledge_level;
|
||||||
|
evaluate.apply_level = requestBody.apply_level;
|
||||||
|
evaluate.success_level = requestBody.success_level;
|
||||||
|
evaluate.achievement_other_desc = requestBody.achievement_other
|
||||||
|
? requestBody.achievement_other.text
|
||||||
|
: "";
|
||||||
|
evaluate.achievement_other_level =
|
||||||
|
requestBody.achievement_other.text != ""
|
||||||
|
? Number(requestBody.achievement_other.level)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
evaluate.conduct1_level = requestBody.conduct1_level;
|
||||||
|
evaluate.conduct2_level = requestBody.conduct2_level;
|
||||||
|
evaluate.conduct3_level = requestBody.conduct3_level;
|
||||||
|
evaluate.conduct4_level = requestBody.conduct4_level;
|
||||||
|
evaluate.moral1_level = requestBody.moral1_level;
|
||||||
|
evaluate.moral2_level = requestBody.moral2_level;
|
||||||
|
evaluate.moral3_level = requestBody.moral3_level;
|
||||||
|
evaluate.discipline1_level = requestBody.discipline1_level;
|
||||||
|
evaluate.discipline2_level = requestBody.discipline2_level;
|
||||||
|
evaluate.discipline3_level = requestBody.discipline3_level;
|
||||||
|
evaluate.discipline4_level = requestBody.discipline4_level;
|
||||||
|
evaluate.discipline5_level = requestBody.discipline5_level;
|
||||||
|
evaluate.behavior_other_desc = requestBody.behavior_orther.text;
|
||||||
|
evaluate.behavior_other_level =
|
||||||
|
requestBody.behavior_orther.text != ""
|
||||||
|
? Number(requestBody.behavior_orther.level)
|
||||||
|
: 0;
|
||||||
|
evaluate.develop_orientation_score = requestBody.develop_orientation_score;
|
||||||
|
evaluate.develop_self_learning_score =
|
||||||
|
requestBody.develop_self_learning_score;
|
||||||
|
evaluate.develop_training_seminar_score =
|
||||||
|
requestBody.develop_training_seminar_score;
|
||||||
|
evaluate.develop_other_training_score =
|
||||||
|
requestBody.develop_other_training_score;
|
||||||
|
evaluate.develop_orientation_percent =
|
||||||
|
requestBody.develop_orientation_percent;
|
||||||
|
evaluate.develop_self_learning_percent =
|
||||||
|
requestBody.develop_self_learning_percent;
|
||||||
|
evaluate.develop_training_seminar_percent =
|
||||||
|
requestBody.develop_training_seminar_percent;
|
||||||
|
evaluate.develop_other_training_percent =
|
||||||
|
requestBody.develop_other_training_percent;
|
||||||
|
evaluate.develop_result = requestBody.develop_result;
|
||||||
|
evaluate.achievement_score = requestBody.achievement_score;
|
||||||
|
evaluate.achievement_score_total = requestBody.achievement_score_total;
|
||||||
|
evaluate.achievement_percent = requestBody.achievement_percent;
|
||||||
|
evaluate.achievement_result = requestBody.achievement_result;
|
||||||
|
evaluate.behavior_score = requestBody.behavior_score;
|
||||||
|
evaluate.behavior_score_total = requestBody.behavior_score_total;
|
||||||
|
evaluate.behavior_percent = requestBody.behavior_percent;
|
||||||
|
evaluate.behavior_result = requestBody.behavior_result;
|
||||||
|
evaluate.sum_score = requestBody.sum_score;
|
||||||
|
evaluate.sum_percent = requestBody.sum_percent;
|
||||||
|
evaluate.evaluate_result = requestBody.evaluate_result;
|
||||||
|
|
||||||
|
evaluate.updateUserId = request.user.sub;
|
||||||
|
evaluate.updateFullName = request.user.name;
|
||||||
|
|
||||||
|
await this.evaluateChairmanRepository.save(evaluate, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: evaluate });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
414
src/controllers/EvaluateController.ts
Normal file
414
src/controllers/EvaluateController.ts
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
Query,
|
||||||
|
Put,
|
||||||
|
} from "tsoa";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { findEndDate, setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { AssignDirector } from "../entities/AssignDirector";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { Assign } from "../entities/Assign";
|
||||||
|
import {
|
||||||
|
CreateEvaluateCommander,
|
||||||
|
EvaluateCommander,
|
||||||
|
} from "../entities/EvaluateCommander";
|
||||||
|
import { Personal } from "../entities/Personal";
|
||||||
|
import CallAPI from "../interfaces/call-api";
|
||||||
|
|
||||||
|
@Route("api/v1/evaluate")
|
||||||
|
@Tags("แบบประเมินผล (ผู้บังคับบัญชา)")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class EvaluateController extends Controller {
|
||||||
|
private assignDirectorRepository =
|
||||||
|
AppDataSource.getRepository(AssignDirector);
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
private evaluateCommanderRepository =
|
||||||
|
AppDataSource.getRepository(EvaluateCommander);
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลตอนกดสร้างแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลตอนกดสร้างแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("create")
|
||||||
|
async CreateEvaluate(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "commander",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = await (assign.profile
|
||||||
|
? {
|
||||||
|
...assign.profile,
|
||||||
|
id: assign.profile.personal_id,
|
||||||
|
name:
|
||||||
|
assign.profile.prefixName +
|
||||||
|
assign.profile.firstName +
|
||||||
|
" " +
|
||||||
|
assign.profile.lastName,
|
||||||
|
Oc: assign.profile.organization,
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
|
||||||
|
const evaluate_amount = await this.evaluateCommanderRepository.count({
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
director_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const evaluate_no = await (evaluate_amount + 1);
|
||||||
|
const start_date =
|
||||||
|
evaluate_amount == 0
|
||||||
|
? assign.date_start
|
||||||
|
: findEndDate(evaluate_amount * 3, assign.date_start);
|
||||||
|
|
||||||
|
const commanderData = await this.assignDirectorRepository.find({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"dated",
|
||||||
|
"fullname",
|
||||||
|
"position",
|
||||||
|
"posType",
|
||||||
|
"posLevel",
|
||||||
|
],
|
||||||
|
where: { personal_id: director_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const commander = await commanderData.map((element) => ({
|
||||||
|
...element,
|
||||||
|
name: element.fullname,
|
||||||
|
label: `${element.fullname} (${element.position}, ${element.posType}: ${element.posLevel})`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
person: profile,
|
||||||
|
assign,
|
||||||
|
evaluate_no: evaluate_no,
|
||||||
|
start_date: start_date,
|
||||||
|
end_date: findEndDate(3, start_date),
|
||||||
|
director: commander,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetEvaluate(@Query() assign_id: string, @Query() evaluate_no?: string) {
|
||||||
|
// ต้องปรับเป็น id ของคนที่ access เข้ามา
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "commander",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
let evaluate: any = null;
|
||||||
|
if (evaluate_no) {
|
||||||
|
evaluate = await this.evaluateCommanderRepository.findOne({
|
||||||
|
where: {
|
||||||
|
director_id,
|
||||||
|
assign_id,
|
||||||
|
no: evaluate_no,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
evaluate = await this.evaluateCommanderRepository.findOne({
|
||||||
|
where: {
|
||||||
|
director_id,
|
||||||
|
assign_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const profile = await (assign.profile
|
||||||
|
// ? {
|
||||||
|
// ...assign.profile,
|
||||||
|
// id: assign.profile.personal_id,
|
||||||
|
// name:
|
||||||
|
// assign.profile.prefixName +
|
||||||
|
// assign.profile.firstName +
|
||||||
|
// " " +
|
||||||
|
// assign.profile.lastName,
|
||||||
|
// Oc: assign.profile.organization,
|
||||||
|
// }
|
||||||
|
// : null);
|
||||||
|
|
||||||
|
// const evaluate_amount = await this.evaluateCommanderRepository.count({
|
||||||
|
// where: {
|
||||||
|
// assign_id,
|
||||||
|
// director_id,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// const evaluate_no = await (evaluate_amount + 1);
|
||||||
|
// const start_date =
|
||||||
|
// evaluate_amount == 0
|
||||||
|
// ? assign.date_start
|
||||||
|
// : findEndDate(evaluate_amount * 3, assign.date_start);
|
||||||
|
|
||||||
|
const directorData = await this.assignDirectorRepository.find({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"dated",
|
||||||
|
"fullname",
|
||||||
|
"position",
|
||||||
|
"posType",
|
||||||
|
"posLevel",
|
||||||
|
],
|
||||||
|
where: { personal_id: director_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const directors = await directorData.map((element) => ({
|
||||||
|
...element,
|
||||||
|
name: element.fullname,
|
||||||
|
label: `${element.fullname} (${element.position}, ${element.posType}: ${element.posLevel})`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const experimenteeData = await this.personalRepository.find({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"prefixName",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"positionName",
|
||||||
|
"positionLevelName",
|
||||||
|
"organization",
|
||||||
|
],
|
||||||
|
where: { personal_id: assign.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const experimentee = await experimenteeData.map((element) => ({
|
||||||
|
...element,
|
||||||
|
name: element.prefixName + element.firstName + " " + element.lastName,
|
||||||
|
Oc: element.organization,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
experimentee: experimentee,
|
||||||
|
director: directors ? directors : null,
|
||||||
|
assign,
|
||||||
|
evaluate,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API บันทึกข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary บันทึกข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async PostData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateCommander,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "commander",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const postData: any = await {
|
||||||
|
assign_id,
|
||||||
|
...requestBody,
|
||||||
|
director_id,
|
||||||
|
no: requestBody.evaluate_no,
|
||||||
|
date_start: requestBody.start_date,
|
||||||
|
personal_id: assign.personal_id,
|
||||||
|
|
||||||
|
achievement_other_desc: requestBody.achievement_other
|
||||||
|
? requestBody.achievement_other.text
|
||||||
|
: "",
|
||||||
|
achievement_other_level: requestBody.achievement_other
|
||||||
|
? Number(requestBody.achievement_other.level)
|
||||||
|
: 0,
|
||||||
|
behavior_other_desc: requestBody.behavior_orther.text,
|
||||||
|
behavior_other_level:
|
||||||
|
requestBody.behavior_orther.text != ""
|
||||||
|
? Number(requestBody.behavior_orther.level)
|
||||||
|
: 0,
|
||||||
|
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.evaluateCommanderRepository.save(postData, {
|
||||||
|
data: request,
|
||||||
|
});
|
||||||
|
setLogDataDiff(request, { before: null, after: postData });
|
||||||
|
|
||||||
|
if (Number(requestBody.evaluate_no) < 2) {
|
||||||
|
// #noted cronjob
|
||||||
|
// แจ้งผู้บังคับบัญชาเข้ามาบันทึกผลทุก 3 เดือน 2 ครั้ง
|
||||||
|
var dateSend = await findEndDate(3, requestBody.start_date);
|
||||||
|
const nextNo = await (Number(requestBody.evaluate_no) + 1);
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ ${nextNo} ${assign.profile.prefixName}${assign.profile.firstName} ${assign.profile.lastName}`,
|
||||||
|
body: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการ (สำหรับผู้บังคับบัญชา) ครั้งที่ ${nextNo} ${assign.profile.prefixName}${assign.profile.firstName} ${assign.profile.lastName}`,
|
||||||
|
receiverUserId: director_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
receiveDate: dateSend,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API แก้ไขข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
* @summary แก้ไขข้อมูลแบบประเมินผล (ผู้บังคับบัญชา)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Put("")
|
||||||
|
async UpdateData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Query() evaluate_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateCommander,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
let evaluate = await this.evaluateCommanderRepository.findOne({
|
||||||
|
where: { id: evaluate_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const before = evaluate;
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate.commander_dated = requestBody.commander_dated;
|
||||||
|
evaluate.knowledge_level = requestBody.knowledge_level;
|
||||||
|
evaluate.skill_level = requestBody.skill_level;
|
||||||
|
evaluate.competency_level = requestBody.competency_level;
|
||||||
|
evaluate.learn_level = requestBody.learn_level;
|
||||||
|
evaluate.apply_level = requestBody.apply_level;
|
||||||
|
evaluate.success_level = requestBody.success_level;
|
||||||
|
evaluate.achievement_other_desc = requestBody.achievement_other
|
||||||
|
? requestBody.achievement_other.text
|
||||||
|
: "";
|
||||||
|
evaluate.achievement_other_level =
|
||||||
|
requestBody.achievement_other.text != ""
|
||||||
|
? Number(requestBody.achievement_other.level)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
evaluate.conduct1_level = requestBody.conduct1_level;
|
||||||
|
evaluate.conduct2_level = requestBody.conduct2_level;
|
||||||
|
evaluate.conduct3_level = requestBody.conduct3_level;
|
||||||
|
evaluate.conduct4_level = requestBody.conduct4_level;
|
||||||
|
evaluate.moral1_level = requestBody.moral1_level;
|
||||||
|
evaluate.moral2_level = requestBody.moral2_level;
|
||||||
|
evaluate.moral3_level = requestBody.moral3_level;
|
||||||
|
evaluate.discipline1_level = requestBody.discipline1_level;
|
||||||
|
evaluate.discipline2_level = requestBody.discipline2_level;
|
||||||
|
evaluate.discipline3_level = requestBody.discipline3_level;
|
||||||
|
evaluate.discipline4_level = requestBody.discipline4_level;
|
||||||
|
evaluate.discipline5_level = requestBody.discipline5_level;
|
||||||
|
evaluate.behavior_other_desc = requestBody.behavior_orther.text;
|
||||||
|
evaluate.behavior_other_level =
|
||||||
|
requestBody.behavior_orther.text != ""
|
||||||
|
? Number(requestBody.behavior_orther.level)
|
||||||
|
: 0;
|
||||||
|
evaluate.behavior_strength_desc = requestBody.behavior_strength_desc;
|
||||||
|
evaluate.behavior_improve_desc = requestBody.behavior_improve_desc;
|
||||||
|
evaluate.orientation = requestBody.orientation;
|
||||||
|
evaluate.self_learning = requestBody.self_learning;
|
||||||
|
evaluate.training_seminar = requestBody.training_seminar;
|
||||||
|
evaluate.other_training = requestBody.other_training;
|
||||||
|
evaluate.updateUserId = request.user.sub;
|
||||||
|
evaluate.updateFullName = request.user.name;
|
||||||
|
|
||||||
|
await this.evaluateCommanderRepository.save(evaluate, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: evaluate });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
1263
src/controllers/EvaluateRecordController.ts
Normal file
1263
src/controllers/EvaluateRecordController.ts
Normal file
File diff suppressed because it is too large
Load diff
444
src/controllers/EvaluateResultController.ts
Normal file
444
src/controllers/EvaluateResultController.ts
Normal file
|
|
@ -0,0 +1,444 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
Query,
|
||||||
|
Put,
|
||||||
|
} from "tsoa";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import { AssignDirector } from "../entities/AssignDirector";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { Assign } from "../entities/Assign";
|
||||||
|
import {
|
||||||
|
CreateEvaluateCommander,
|
||||||
|
EvaluateCommander,
|
||||||
|
} from "../entities/EvaluateCommander";
|
||||||
|
import { Personal } from "../entities/Personal";
|
||||||
|
import CallAPI from "../interfaces/call-api";
|
||||||
|
import { EvaluateChairman } from "../entities/EvaluateChairman";
|
||||||
|
import {
|
||||||
|
CreateEvaluateResult,
|
||||||
|
EvaluateResult,
|
||||||
|
} from "../entities/EvaluateResult";
|
||||||
|
|
||||||
|
@Route("api/v1/evaluate-result")
|
||||||
|
@Tags("แบบรายงานการประเมินฯ")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class EvaluateResultController extends Controller {
|
||||||
|
private assignDirectorRepository =
|
||||||
|
AppDataSource.getRepository(AssignDirector);
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
private evaluateChairmanRepository =
|
||||||
|
AppDataSource.getRepository(EvaluateChairman);
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
private evaluateResultRepository =
|
||||||
|
AppDataSource.getRepository(EvaluateResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลตอนกดสร้างแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลตอนกดสร้างแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("create")
|
||||||
|
async CreateEvaluate(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = await (assign.profile
|
||||||
|
? {
|
||||||
|
...assign.profile,
|
||||||
|
id: assign.profile.personal_id,
|
||||||
|
name:
|
||||||
|
assign.profile.prefixName +
|
||||||
|
assign.profile.firstName +
|
||||||
|
" " +
|
||||||
|
assign.profile.lastName,
|
||||||
|
Oc: assign.profile.organization,
|
||||||
|
}
|
||||||
|
: null);
|
||||||
|
|
||||||
|
const directorData = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!directorData) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลผู้ดูแล ผู้บังคับบัญชาและประธาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mentors = "";
|
||||||
|
const mentorList = await directorData.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors += e.fullname;
|
||||||
|
if (index < mentorList.length - 1) {
|
||||||
|
mentors += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (directorData.find(
|
||||||
|
(x) => x.role == "commander"
|
||||||
|
) ?? null);
|
||||||
|
const commander = commanderData ? commanderData.fullname : null;
|
||||||
|
|
||||||
|
const chairmanData = await (directorData.find(
|
||||||
|
(x) => x.role == "chairman"
|
||||||
|
) ?? null);
|
||||||
|
const chairman = chairmanData ? chairmanData.fullname : null;
|
||||||
|
|
||||||
|
const resultData = await this.evaluateChairmanRepository.findOne({
|
||||||
|
select: [
|
||||||
|
"develop_orientation_score",
|
||||||
|
"develop_self_learning_score",
|
||||||
|
"develop_training_seminar_score",
|
||||||
|
"evaluate_result",
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!resultData) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการประเมินผล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const develop_complete = await (resultData.develop_orientation_score > 0 &&
|
||||||
|
resultData.develop_self_learning_score > 0 &&
|
||||||
|
resultData.develop_training_seminar_score > 0
|
||||||
|
? 1
|
||||||
|
: 2);
|
||||||
|
|
||||||
|
const evaluate_result = await (resultData.evaluate_result == 1 ? 1 : 2);
|
||||||
|
|
||||||
|
const result = await {
|
||||||
|
develop_complete: develop_complete,
|
||||||
|
evaluate_result: evaluate_result,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
person: profile,
|
||||||
|
assign,
|
||||||
|
result,
|
||||||
|
mentors,
|
||||||
|
commander,
|
||||||
|
chairman,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetEvaluate(@Query() assign_id: string, @Query() evaluate_no?: string) {
|
||||||
|
// ต้องปรับเป็น id ของคนที่ access เข้ามา
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "chairman",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const evaluate = await this.evaluateChairmanRepository.findOne({
|
||||||
|
where: {
|
||||||
|
director_id,
|
||||||
|
assign_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const experimenteeData = await this.personalRepository.find({
|
||||||
|
select: [
|
||||||
|
"personal_id",
|
||||||
|
"prefixName",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"positionName",
|
||||||
|
"positionLevelName",
|
||||||
|
"organization",
|
||||||
|
],
|
||||||
|
where: { personal_id: assign.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const experimentee = await experimenteeData.map((element) => ({
|
||||||
|
...element,
|
||||||
|
name: element.prefixName + element.firstName + " " + element.lastName,
|
||||||
|
Oc: element.organization,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const directorData = await this.assignDirectorRepository.find({
|
||||||
|
where: { assign_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!directorData) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลผู้ดูแล ผู้บังคับบัญชาและประธาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mentors = "";
|
||||||
|
const mentorList = await directorData.filter((x) => x.role == "mentor");
|
||||||
|
if (mentorList.length > 0) {
|
||||||
|
for (let index = 0; index < mentorList.length; index++) {
|
||||||
|
const e = await mentorList[index];
|
||||||
|
mentors += e.fullname;
|
||||||
|
if (index < mentorList.length - 1) {
|
||||||
|
mentors += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const commanderData = await (directorData.find(
|
||||||
|
(x) => x.role == "commander"
|
||||||
|
) ?? null);
|
||||||
|
const commander = commanderData ? commanderData.fullname : null;
|
||||||
|
|
||||||
|
const chairmanData = await (directorData.find(
|
||||||
|
(x) => x.role == "chairman"
|
||||||
|
) ?? null);
|
||||||
|
const chairman = chairmanData ? chairmanData.fullname : null;
|
||||||
|
|
||||||
|
return new HttpSuccess({
|
||||||
|
commander,
|
||||||
|
chairman,
|
||||||
|
mentors,
|
||||||
|
experimentee,
|
||||||
|
assign,
|
||||||
|
evaluate: evaluate,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API บันทึกข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
* @summary บันทึกข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async PostData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateResult,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const director = await this.assignDirectorRepository.findOne({
|
||||||
|
select: ["personal_id"],
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
role: "chairman",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!director) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ดูแล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const director_id = director.personal_id;
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const postData: any = await {
|
||||||
|
assign_id,
|
||||||
|
...requestBody,
|
||||||
|
director_id,
|
||||||
|
no: 1,
|
||||||
|
personal_id: assign.personal_id,
|
||||||
|
date_start: requestBody.start_date,
|
||||||
|
expand_month:
|
||||||
|
requestBody.pass_result == 3 ? Number(requestBody.expand_month) : 0,
|
||||||
|
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
updateUserId: request.user.sub,
|
||||||
|
updateFullName: request.user.name,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.evaluateResultRepository.save(postData, {
|
||||||
|
data: request,
|
||||||
|
});
|
||||||
|
setLogDataDiff(request, { before: null, after: postData });
|
||||||
|
|
||||||
|
const personal = await this.personalRepository.findOne({
|
||||||
|
where: { personal_id: assign.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!personal) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
personal.probation_status =
|
||||||
|
requestBody.pass_result == 1
|
||||||
|
? 2
|
||||||
|
: requestBody.pass_result == 2
|
||||||
|
? 3
|
||||||
|
: personal.probation_status;
|
||||||
|
|
||||||
|
if (requestBody.pass_result == 3) {
|
||||||
|
personal.probation_status = 7;
|
||||||
|
// #noti ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ กรณีขยายระยะเวลา
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: "ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ",
|
||||||
|
body: `ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ เห็นควรให้ขยายระยะเวลาทดลองปฏิบัติหน้าที่ราชการต่อไปอีก ${requestBody.expand_month} เดือน`,
|
||||||
|
receiverUserId: assign.personal_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: false,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.personalRepository.save(personal, { data: request });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API แก้ไขข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
* @summary แก้ไขข้อมูลแบบรายงานการประเมินฯ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Put("")
|
||||||
|
async UpdateData(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Query() evaluate_id: string,
|
||||||
|
@Body() requestBody: CreateEvaluateResult,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
let evaluate = await this.evaluateResultRepository.findOne({
|
||||||
|
where: { id: evaluate_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const before = evaluate;
|
||||||
|
|
||||||
|
if (!evaluate) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการประเมิน");
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate.date_start = requestBody.start_date;
|
||||||
|
evaluate.date_finish = requestBody.date_finish;
|
||||||
|
evaluate.develop_complete = requestBody.develop_complete;
|
||||||
|
evaluate.pass_result = requestBody.pass_result;
|
||||||
|
evaluate.expand_month =
|
||||||
|
requestBody.pass_result == 3 ? requestBody.expand_month : 0;
|
||||||
|
evaluate.reson = requestBody.reson;
|
||||||
|
evaluate.chairman_dated = requestBody.chairman_dated;
|
||||||
|
|
||||||
|
evaluate.director1_dated = requestBody.director1_dated;
|
||||||
|
evaluate.director2_dated = requestBody.director2_dated;
|
||||||
|
evaluate.updateUserId = request.user.sub;
|
||||||
|
evaluate.updateFullName = request.user.name;
|
||||||
|
|
||||||
|
await this.evaluateResultRepository.save(evaluate, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: evaluate });
|
||||||
|
|
||||||
|
const assign = await this.assignRepository.findOne({
|
||||||
|
relations: ["profile"],
|
||||||
|
where: { id: assign_id },
|
||||||
|
});
|
||||||
|
if (!assign) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลแบบมอบหมายงาน"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const personal = await this.personalRepository.findOne({
|
||||||
|
where: { personal_id: assign.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!personal) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
personal.probation_status =
|
||||||
|
requestBody.pass_result == 1
|
||||||
|
? 2
|
||||||
|
: requestBody.pass_result == 2
|
||||||
|
? 3
|
||||||
|
: personal.probation_status;
|
||||||
|
|
||||||
|
if (requestBody.pass_result == 3) {
|
||||||
|
personal.probation_status = 7;
|
||||||
|
// #noti ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ กรณีขยายระยะเวลา
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti", {
|
||||||
|
subject: "ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ",
|
||||||
|
body: `ผลการประเมินการทดลองปฏิบัติหน้าที่ราชการ เห็นควรให้ขยายระยะเวลาทดลองปฏิบัติหน้าที่ราชการต่อไปอีก ${requestBody.expand_month} เดือน`,
|
||||||
|
receiverUserId: assign.personal_id,
|
||||||
|
payload: "",
|
||||||
|
isSendMail: false,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.personalRepository.save(personal, { data: request });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/controllers/MyController.ts
Normal file
11
src/controllers/MyController.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Controller, Get, Route, Security, Tags } from "tsoa";
|
||||||
|
|
||||||
|
@Route("/hello")
|
||||||
|
@Tags("Test")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
export class AppController extends Controller {
|
||||||
|
@Get()
|
||||||
|
public async GET() {
|
||||||
|
return { message: "Hello Development" };
|
||||||
|
}
|
||||||
|
}
|
||||||
195
src/controllers/PersonalController.ts
Normal file
195
src/controllers/PersonalController.ts
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Post,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Body,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Query,
|
||||||
|
} from "tsoa";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { Personal, PostPersonal } from "../entities/Personal";
|
||||||
|
import permission from "../interfaces/permission";
|
||||||
|
import { Assign } from "../entities/Assign";
|
||||||
|
|
||||||
|
@Route("api/v1/personal")
|
||||||
|
@Tags("Personal")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class PersonalController extends Controller {
|
||||||
|
private personalRepository = AppDataSource.getRepository(Personal);
|
||||||
|
private assignRepository = AppDataSource.getRepository(Assign);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลบุคคลในระบบทดลองงาน
|
||||||
|
*
|
||||||
|
* @summary เพิ่มคนเข้าระบบทดลองงาน
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("add")
|
||||||
|
async AddPersonal(
|
||||||
|
@Body() requestBody: PostPersonal,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
await new permission().PermissionCreate(request, "SYS_PROBATION");
|
||||||
|
|
||||||
|
const checkPersonal: number = await this.personalRepository.count({
|
||||||
|
where: { personal_id: requestBody.id },
|
||||||
|
});
|
||||||
|
if (checkPersonal > 0) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.BAD_REQUEST,
|
||||||
|
"ผู้ทดลองปฏิบัติหน้าที่ราชการนี้มีอยู่แล้ว"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let organization = await (requestBody.orgChild4Name
|
||||||
|
? requestBody.orgChild4Name + "/"
|
||||||
|
: "");
|
||||||
|
organization += await (requestBody.orgChild3Name
|
||||||
|
? requestBody.orgChild3Name + "/"
|
||||||
|
: "");
|
||||||
|
organization += await (requestBody.orgChild2Name
|
||||||
|
? requestBody.orgChild2Name + "/"
|
||||||
|
: "");
|
||||||
|
organization += await (requestBody.orgChild1Name
|
||||||
|
? requestBody.orgChild1Name + "/"
|
||||||
|
: "");
|
||||||
|
organization += await (requestBody.orgRootName
|
||||||
|
? requestBody.orgRootName
|
||||||
|
: "");
|
||||||
|
|
||||||
|
const personalData = Object.assign(new Personal());
|
||||||
|
personalData.personal_id = requestBody.id;
|
||||||
|
personalData.order_number = requestBody.order_number
|
||||||
|
? requestBody.order_number
|
||||||
|
: "";
|
||||||
|
personalData.probation_status = 1;
|
||||||
|
personalData.createdUserId = request.user.sub;
|
||||||
|
personalData.createdFullName = request.user.name;
|
||||||
|
personalData.updateUserId = request.user.sub;
|
||||||
|
personalData.updateFullName = request.user.name;
|
||||||
|
|
||||||
|
personalData.prefixName = requestBody.prefix;
|
||||||
|
personalData.firstName = requestBody.firstName;
|
||||||
|
personalData.lastName = requestBody.lastName;
|
||||||
|
personalData.isProbation = requestBody.isProbation ? 1 : 0;
|
||||||
|
personalData.positionLevelName = requestBody.posLevelName
|
||||||
|
? requestBody.posLevelName
|
||||||
|
: "";
|
||||||
|
personalData.positionName = requestBody.position
|
||||||
|
? requestBody.position
|
||||||
|
: "";
|
||||||
|
personalData.positionLineName = requestBody.posLineName;
|
||||||
|
personalData.positionTypeName = requestBody.posTypeName;
|
||||||
|
personalData.posNo = requestBody.posNo ? requestBody.posNo : "";
|
||||||
|
personalData.orgRootName = requestBody.orgRootName;
|
||||||
|
personalData.organization = organization;
|
||||||
|
|
||||||
|
const before = null;
|
||||||
|
const personal = await this.personalRepository.save(personalData, {
|
||||||
|
data: request,
|
||||||
|
});
|
||||||
|
setLogDataDiff(request, { before, after: personal });
|
||||||
|
|
||||||
|
return new HttpSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API รายการบุคคลในระบบทดลองงาน
|
||||||
|
*
|
||||||
|
* @summary รายชื่อคนที่อยู่ในระบบทดลองงาน
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("list")
|
||||||
|
async ListPersonal(@Request() request: RequestWithUser) {
|
||||||
|
await new permission().PermissionList(request, "SYS_PROBATION");
|
||||||
|
const lists = await this.personalRepository.find({
|
||||||
|
order: { createdAt: "DESC" },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!lists) {
|
||||||
|
return new HttpError(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"ไม่สามารถแสดงข้อมูลได้"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: any = [];
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
lists.map(async (item, index) => {
|
||||||
|
const probation_no = await this.assignRepository.count({
|
||||||
|
where: { personal_id: item.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
await result.push({
|
||||||
|
personal_id: item.personal_id,
|
||||||
|
ordering: index + 1,
|
||||||
|
name: item.prefixName + item.firstName + " " + item.lastName,
|
||||||
|
position_line: item.positionName,
|
||||||
|
position_level: item.positionLevelName,
|
||||||
|
position_type: item.positionTypeName,
|
||||||
|
organization: item.organization,
|
||||||
|
probation_no: probation_no,
|
||||||
|
order_number: item.order_number,
|
||||||
|
probation_status: item.probation_status,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API ข้อมูลบุคคลในระบบทดลองงาน
|
||||||
|
*
|
||||||
|
* @summary ข้อมูลคนที่อยูาในระบบทดลองงาน
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetPersonal(
|
||||||
|
@Request() request: RequestWithUser,
|
||||||
|
@Query() personal_id: string
|
||||||
|
) {
|
||||||
|
await new permission().PermissionList(request, "SYS_PROBATION");
|
||||||
|
const person = await this.personalRepository.findOne({
|
||||||
|
where: { personal_id: personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!person) {
|
||||||
|
return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล");
|
||||||
|
}
|
||||||
|
|
||||||
|
const probation_no = await this.assignRepository.count({
|
||||||
|
where: { personal_id: person.personal_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await {
|
||||||
|
personal_id: person.personal_id,
|
||||||
|
name: person.prefixName + person.firstName + " " + person.lastName,
|
||||||
|
position_line: person.positionName,
|
||||||
|
position_level: person.positionLevelName,
|
||||||
|
position_type: person.positionTypeName,
|
||||||
|
organization: person.organization,
|
||||||
|
probation_no: probation_no,
|
||||||
|
order_number: person.order_number,
|
||||||
|
probation_status: person.probation_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
1119
src/controllers/ReportController.ts
Normal file
1119
src/controllers/ReportController.ts
Normal file
File diff suppressed because it is too large
Load diff
70
src/controllers/SurveyController.ts
Normal file
70
src/controllers/SurveyController.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Request,
|
||||||
|
SuccessResponse,
|
||||||
|
Response,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
Query,
|
||||||
|
} from "tsoa";
|
||||||
|
import HttpSuccess from "../interfaces/http-success";
|
||||||
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { setLogDataDiff } from "../interfaces/utils";
|
||||||
|
import { Survey } from "../entities/Survey";
|
||||||
|
import { AppDataSource } from "../database/data-source";
|
||||||
|
|
||||||
|
@Route("api/v1/survey")
|
||||||
|
@Tags("Survey")
|
||||||
|
@Security("bearerAuth")
|
||||||
|
@Response(
|
||||||
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
|
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง"
|
||||||
|
)
|
||||||
|
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
|
||||||
|
export class SurveyController extends Controller {
|
||||||
|
private surveyRepository = AppDataSource.getRepository(Survey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API แบบสำรวจความคิดเห็น
|
||||||
|
*
|
||||||
|
* @summary แบบสำรวจความคิดเห็น
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Get("")
|
||||||
|
async GetSurvey(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const result = await this.surveyRepository.findOne({
|
||||||
|
where: {
|
||||||
|
assign_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return new HttpSuccess(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API บันทึกแบบสำรวจความคิดเห็น
|
||||||
|
*
|
||||||
|
* @summary บันทึกแบบสำรวจความคิดเห็น
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Post("")
|
||||||
|
async PostSurvey(
|
||||||
|
@Query() assign_id: string,
|
||||||
|
@Body() requestBody: any,
|
||||||
|
@Request() request: RequestWithUser
|
||||||
|
) {
|
||||||
|
const before = null;
|
||||||
|
const data = await { ...requestBody, personal_id: request.user.sub };
|
||||||
|
await this.surveyRepository.save(data, { data: request });
|
||||||
|
setLogDataDiff(request, { before, after: data });
|
||||||
|
|
||||||
|
return new HttpSuccess(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/database/data-source.ts
Normal file
76
src/database/data-source.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import "dotenv/config";
|
||||||
|
import "reflect-metadata";
|
||||||
|
import { DataSource, LogLevel, LogMessage } from "typeorm";
|
||||||
|
import { Logger } from "typeorm";
|
||||||
|
import { QueryRunner } from "typeorm/browser";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import { addLogSequence } from "../interfaces/utils";
|
||||||
|
|
||||||
|
export class MyCustomLogger implements Logger {
|
||||||
|
log(
|
||||||
|
level: "log" | "info" | "warn",
|
||||||
|
message: any,
|
||||||
|
queryRunner?: QueryRunner
|
||||||
|
) {}
|
||||||
|
|
||||||
|
logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner): void {
|
||||||
|
const req = queryRunner?.data as RequestWithUser;
|
||||||
|
if (req?.app?.locals.logData?.sequence) {
|
||||||
|
addLogSequence(req, {
|
||||||
|
action: "database",
|
||||||
|
status: "success",
|
||||||
|
description: "Query Data.",
|
||||||
|
query: [
|
||||||
|
"Query: " +
|
||||||
|
query +
|
||||||
|
(parameters ? " - Parameters:" + JSON.stringify(parameters) : ""),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// const req = queryRunner?.data as RequestWithUser | undefined;
|
||||||
|
// const logData = req?.app?.locals.logData?.sequence?.at(-1);
|
||||||
|
|
||||||
|
// if (logData && !logData.query) logData.query = [];
|
||||||
|
// if (logData) logData.query.push(
|
||||||
|
// "Query: " + query + (parameters ? (" - Parameters:" + JSON.stringify(parameters)) : '')
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
logMigration(message: string, queryRunner?: QueryRunner) {}
|
||||||
|
logQueryError(
|
||||||
|
error: string | Error,
|
||||||
|
query: string,
|
||||||
|
parameters?: any[],
|
||||||
|
queryRunner?: QueryRunner
|
||||||
|
) {}
|
||||||
|
logQuerySlow(
|
||||||
|
time: number,
|
||||||
|
query: string,
|
||||||
|
parameters?: any[],
|
||||||
|
queryRunner?: QueryRunner
|
||||||
|
) {}
|
||||||
|
logSchemaBuild(message: string, queryRunner?: QueryRunner) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppDataSource = new DataSource({
|
||||||
|
type: "mysql",
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
port: +(process.env.DB_PORT || 3306),
|
||||||
|
username: process.env.DB_USERNAME,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
connectorPackage: "mysql2",
|
||||||
|
synchronize: false,
|
||||||
|
logging: ["query", "error"],
|
||||||
|
entities:
|
||||||
|
process.env.NODE_ENV !== "production"
|
||||||
|
? ["src/entities/*.ts"]
|
||||||
|
: ["dist/entities/*{.ts,.js}"],
|
||||||
|
migrations:
|
||||||
|
process.env.NODE_ENV !== "production"
|
||||||
|
? ["src/migration/**/*.ts"]
|
||||||
|
: ["dist/migration/**/*{.ts,.js}"],
|
||||||
|
subscribers: [],
|
||||||
|
logger: new MyCustomLogger(),
|
||||||
|
});
|
||||||
212
src/entities/Assign.ts
Normal file
212
src/entities/Assign.ts
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
import {
|
||||||
|
CreateEvaluateCommander,
|
||||||
|
EvaluateCommander,
|
||||||
|
} from "./EvaluateCommander";
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
OneToMany,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
ManyToOne,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import {
|
||||||
|
AssignCompetencyGroup,
|
||||||
|
CreateAssignCompetencyGroup,
|
||||||
|
} from "./AssignCompetencyGroup";
|
||||||
|
import { CreateSurvel, Survey } from "./Survey";
|
||||||
|
import { AssignCompetency, CreateAssignCompetency } from "./AssignCompetency";
|
||||||
|
import { AssignDirector, CreateAssignDirector } from "./AssignDirector";
|
||||||
|
import { AssignJob, CreateAssignJob } from "./AssignJob";
|
||||||
|
import { AssignKnowledge, CreateAssignKnowledge } from "./AssignKnowledge";
|
||||||
|
import { AssignLaw, CreateAssignLaw } from "./AssignLaw";
|
||||||
|
import { AssignOutput, CreateAssignOutput } from "./AssignOutput";
|
||||||
|
import { AssignSkill, CreateAssignSkill } from "./AssignSkill";
|
||||||
|
import {
|
||||||
|
CreateEvaluateAchievement,
|
||||||
|
EvaluateAchievement,
|
||||||
|
} from "./EvaluateAchievement";
|
||||||
|
import { CreateEvaluateAssessor, EvaluateAssessor } from "./EvaluateAssessor";
|
||||||
|
import { CreateEvaluateChairman, EvaluateChairman } from "./EvaluateChairman";
|
||||||
|
import { CreateEvaluateResult, EvaluateResult } from "./EvaluateResult";
|
||||||
|
import { Personal } from "./Personal";
|
||||||
|
|
||||||
|
@Entity("assign")
|
||||||
|
export class Assign extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของบุคคล",
|
||||||
|
})
|
||||||
|
personal_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ครั้งที่แบบมอบหมายงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
round_no!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่เริ่มทดลองงาน",
|
||||||
|
})
|
||||||
|
date_start: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่สิ้นสุดทดลองงาน",
|
||||||
|
})
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "อื่นๆ(3.5)",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
other4_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "อื่นๆ(5.2)",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
other5_no1_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผู้ทดลองปฏิบัติหน้าที่ราชการลงวันที่",
|
||||||
|
})
|
||||||
|
experimenter_dated!: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน 1 คือใช้งานปกติ, 0 คือไม่ใช้งาน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Personal, (person: Personal) => person.personal_id)
|
||||||
|
@JoinColumn({ name: "personal_id" })
|
||||||
|
profile: Personal;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignCompetencyGroup,
|
||||||
|
(competencyGroup: AssignCompetencyGroup) => competencyGroup.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
competencyGroups: AssignCompetencyGroup[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignCompetency,
|
||||||
|
(competency: AssignCompetency) => competency.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
competencys: AssignCompetency[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignDirector,
|
||||||
|
(director: AssignDirector) => director.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
directors: AssignDirector[];
|
||||||
|
|
||||||
|
@OneToMany(() => AssignJob, (job: AssignJob) => job.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
jobs: AssignJob[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignKnowledge,
|
||||||
|
(knowledge: AssignKnowledge) => knowledge.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
knowledges: AssignKnowledge[];
|
||||||
|
|
||||||
|
@OneToMany(() => AssignLaw, (law: AssignLaw) => law.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
laws: AssignLaw[];
|
||||||
|
|
||||||
|
@OneToMany(() => AssignOutput, (output: AssignOutput) => output.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
outputs: AssignOutput[];
|
||||||
|
|
||||||
|
@OneToMany(() => AssignSkill, (skill: AssignSkill) => skill.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
skills: AssignSkill[];
|
||||||
|
|
||||||
|
@OneToMany(() => Survey, (survey: Survey) => survey.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
surveys: Survey;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => EvaluateAchievement,
|
||||||
|
(evaluateAchievement: EvaluateAchievement) => evaluateAchievement.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
evaluateAchievements: EvaluateAchievement;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => EvaluateAssessor,
|
||||||
|
(evaluateAssessor: EvaluateAssessor) => evaluateAssessor.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
evaluateAssessors: EvaluateAssessor;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => EvaluateChairman,
|
||||||
|
(evaluateChairman: EvaluateChairman) => evaluateChairman.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
evaluateChairmans: EvaluateChairman;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => EvaluateCommander,
|
||||||
|
(evaluateCommander: EvaluateCommander) => evaluateCommander.assign
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
evaluateCommanders: EvaluateCommander;
|
||||||
|
|
||||||
|
@OneToMany(() => EvaluateResult, (result: EvaluateResult) => result.assign)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
evaluateResults: EvaluateResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssign {
|
||||||
|
@Column()
|
||||||
|
date_start: Date;
|
||||||
|
@Column()
|
||||||
|
date_finish: Date;
|
||||||
|
@Column()
|
||||||
|
other4_desc?: string;
|
||||||
|
@Column()
|
||||||
|
other5_no1_desc?: string;
|
||||||
|
@Column()
|
||||||
|
experimenter_dated?: Date;
|
||||||
|
@Column()
|
||||||
|
personal_id?: string;
|
||||||
|
fullname?: string;
|
||||||
|
position?: string;
|
||||||
|
monthSelect?: number;
|
||||||
|
other_desc?: string;
|
||||||
|
|
||||||
|
assign_competency_group: CreateAssignCompetencyGroup[];
|
||||||
|
assign_competency: CreateAssignCompetency[];
|
||||||
|
assign_director: CreateAssignDirector[];
|
||||||
|
assign_jobs: CreateAssignJob[];
|
||||||
|
assign_knowledges: CreateAssignKnowledge[];
|
||||||
|
assign_law: CreateAssignLaw[];
|
||||||
|
assign_outputs: CreateAssignOutput[];
|
||||||
|
assign_skill: CreateAssignSkill[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssign = Partial<CreateAssign>;
|
||||||
55
src/entities/AssignCompetency.ts
Normal file
55
src/entities/AssignCompetency.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("assignCompetency")
|
||||||
|
export class AssignCompetency extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id สมรรถนะหลัก",
|
||||||
|
})
|
||||||
|
competency_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับพฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
competency_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ชื่อสมรรถนะหลัก",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
competency_name: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "รายละเอียดสมรรถนะหลัก",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
competency_description: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.competencys)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignCompetency {
|
||||||
|
id: string;
|
||||||
|
level: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignCompetency = Partial<CreateAssignCompetency>;
|
||||||
55
src/entities/AssignCompetencyGroup.ts
Normal file
55
src/entities/AssignCompetencyGroup.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("assignCompetencyGroup")
|
||||||
|
export class AssignCompetencyGroup extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id สมรรถนะประจำกลุ่มงาน",
|
||||||
|
})
|
||||||
|
competency_group_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับพฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
competency_group_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ชื่อสมรรถนะประจำกลุ่มงาน",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
competency_group_name: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "รายละเอียดสมรรถนะประจำกลุ่มงาน",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
competency_group_description: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.competencyGroups)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignCompetencyGroup {
|
||||||
|
id: string;
|
||||||
|
level: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignCompetencyGroup = Partial<CreateAssignCompetencyGroup>;
|
||||||
91
src/entities/AssignDirector.ts
Normal file
91
src/entities/AssignDirector.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("assignDirector")
|
||||||
|
export class AssignDirector extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "Id ผู้ดูแล/ผู้บังคับบัญชา/ประธาน",
|
||||||
|
})
|
||||||
|
personal_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "enum",
|
||||||
|
primary: true,
|
||||||
|
enum: ["mentor", "commander", "chairman"],
|
||||||
|
comment:
|
||||||
|
"หน้าที่ mentor = ผู้ดูแล, commander = ผู้บังคับบัญชา, chairman = ประธานกรรมการ",
|
||||||
|
})
|
||||||
|
role: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ชื่อ-นามสกุล",
|
||||||
|
})
|
||||||
|
fullname: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ตำแหน่งในสายงาน",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
position!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ประเภทตำแหน่ง",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
posType!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับตำแหน่ง",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
posLevel!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
dated!: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ลำดับการแสดงผล",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
ordering: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.directors)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignDirector {
|
||||||
|
@Column()
|
||||||
|
personal_id: string;
|
||||||
|
@Column()
|
||||||
|
position?: string;
|
||||||
|
@Column()
|
||||||
|
posType?: string;
|
||||||
|
@Column()
|
||||||
|
posLevel?: string;
|
||||||
|
@Column()
|
||||||
|
role: string;
|
||||||
|
@Column()
|
||||||
|
dated?: Date | null;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignDirector = Partial<CreateAssignDirector>;
|
||||||
44
src/entities/AssignJob.ts
Normal file
44
src/entities/AssignJob.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("assignJob")
|
||||||
|
export class AssignJob extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "Running number",
|
||||||
|
})
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ผลการปฏิบัติงานกิจกรรม/ขั้นตอนการปฏิบัติ",
|
||||||
|
})
|
||||||
|
activity_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ผลการปฏิบัติงานเป้าหมาย",
|
||||||
|
})
|
||||||
|
goal_desc: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.jobs)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignJob {
|
||||||
|
activity_desc: string;
|
||||||
|
goal_desc: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignJob = Partial<CreateAssignJob>;
|
||||||
46
src/entities/AssignKnowledge.ts
Normal file
46
src/entities/AssignKnowledge.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
import { Knowledge } from "./Knowledge";
|
||||||
|
|
||||||
|
@Entity("assignKnowledge")
|
||||||
|
export class AssignKnowledge extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "int",
|
||||||
|
comment: "Runnig number",
|
||||||
|
})
|
||||||
|
knowledge_id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับพฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
knowledge_level: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.knowledges)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => Knowledge,
|
||||||
|
(knowledge: Knowledge) => knowledge.assignKnowledge
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "knowledge_id" })
|
||||||
|
knowledge: Knowledge;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignKnowledge {
|
||||||
|
id: number;
|
||||||
|
level: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignKnowledge = Partial<CreateAssignKnowledge>;
|
||||||
45
src/entities/AssignLaw.ts
Normal file
45
src/entities/AssignLaw.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
import { Law } from "./Law";
|
||||||
|
|
||||||
|
@Entity("assignLaw")
|
||||||
|
export class AssignLaw extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "int",
|
||||||
|
comment: "Running number",
|
||||||
|
})
|
||||||
|
law_id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ลำดับ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
ordering: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.laws)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
|
||||||
|
@OneToMany(() => Law, (law: Law) => law.assignLaw)
|
||||||
|
@JoinColumn({ name: "law_id" })
|
||||||
|
law: Law;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignLaw {
|
||||||
|
level?: number;
|
||||||
|
id: number;
|
||||||
|
checked?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignLaw = Partial<CreateAssignLaw>;
|
||||||
46
src/entities/AssignOutput.ts
Normal file
46
src/entities/AssignOutput.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("assignOutput")
|
||||||
|
export class AssignOutput extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "int",
|
||||||
|
comment: "Runnig number",
|
||||||
|
})
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ผลผลิตของงานที่คาดหวัง",
|
||||||
|
})
|
||||||
|
output_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "ตัวชี้วัดความสําเร็จของงาน",
|
||||||
|
})
|
||||||
|
indicator_desc: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.outputs)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignOutput {
|
||||||
|
output_desc: string;
|
||||||
|
indicator_desc: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignOutput = Partial<CreateAssignOutput>;
|
||||||
42
src/entities/AssignSkill.ts
Normal file
42
src/entities/AssignSkill.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
import { Skill } from "./Skill";
|
||||||
|
|
||||||
|
@Entity("assignSkill")
|
||||||
|
export class AssignSkill extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
type: "int",
|
||||||
|
comment: "Runnig number",
|
||||||
|
})
|
||||||
|
skill_id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับพฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
skill_level: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.skills)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
|
||||||
|
@ManyToOne(() => Skill, (skill: Skill) => skill.assignSkill)
|
||||||
|
@JoinColumn({ name: "skill_id" })
|
||||||
|
skill: Skill;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateAssignSkill {
|
||||||
|
level: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateAssignSkill = Partial<CreateAssignSkill>;
|
||||||
90
src/entities/EvaluateAchievement.ts
Normal file
90
src/entities/EvaluateAchievement.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("evaluateAchievement")
|
||||||
|
export class EvaluateAchievement extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id แบบประเมิน",
|
||||||
|
})
|
||||||
|
evaluate_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id ผลลัพท์",
|
||||||
|
})
|
||||||
|
output_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ผู้ประเมิน",
|
||||||
|
})
|
||||||
|
assessor_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับคะแนนผลผลิตของงานที่คาดหวัง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
evaluate_expect_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "คำอธิบายผลผลิตของงานที่เกิดขึ้นจริง",
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
output_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับคะแนนผลผลิตของงานที่เกิดขึ้นจริง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
evaluate_output_level!: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.evaluateAchievements)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateEvaluateAchievement {
|
||||||
|
@Column()
|
||||||
|
assign_id: string;
|
||||||
|
@Column()
|
||||||
|
evaluate_id: string;
|
||||||
|
@Column()
|
||||||
|
output_id: string;
|
||||||
|
@Column()
|
||||||
|
assessor_id: string;
|
||||||
|
@Column()
|
||||||
|
evaluate_expect_level: number;
|
||||||
|
@Column()
|
||||||
|
output_desc: string;
|
||||||
|
@Column()
|
||||||
|
evaluate_output_level: number;
|
||||||
|
|
||||||
|
createdUserId?: string;
|
||||||
|
createdFullName?: string;
|
||||||
|
updateUserId?: string;
|
||||||
|
updateFullName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateEvaluateAchievement = Partial<CreateEvaluateAchievement>;
|
||||||
338
src/entities/EvaluateAssessor.ts
Normal file
338
src/entities/EvaluateAssessor.ts
Normal file
|
|
@ -0,0 +1,338 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("evaluateAssessor")
|
||||||
|
export class EvaluateAssessor extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ผู้ประเมิน",
|
||||||
|
})
|
||||||
|
director_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ครั้งที่บันทึก",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
no: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่เริ่มการบันทึก",
|
||||||
|
})
|
||||||
|
date_start: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่สิ้นสุดการบันทึก",
|
||||||
|
})
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
assessor_dated: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความรู้",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
knowledge_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนทักษะ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
skill_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนสมรรถนะ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
competency_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการเรียนรู้งาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
learn_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการปรับใช้ความรู้กับงานในหน้าที่",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
apply_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "จุดเด่น",
|
||||||
|
})
|
||||||
|
achievement_strength_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "สิ่งที่ควรปรับปรุง",
|
||||||
|
})
|
||||||
|
achievement_improve_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยอัธยาศัยดี",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ มีความรับผิดชอบในการปฏิบัติบัติงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยความรวดเร็ว เอาใจใส่เป็นมาตรฐานเดียวกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ตั้งใจปฏิบัติบัติหน้าที่ราชการด้วยความอุตสาหะ ขยันหมั่นเพียร",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ อุทิศตนและเสียสละเวลาในการปฏิบัติบัติงานอย่างเต็มกำลังความสามารถ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ มีจิตสำนึกที่ดี ปฏิบัติบัติงานด้วยความซื่อสัตย์ สุจริต",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ ยึดมั่นในสถาบันบัพระมหากษัตริย์ และไม่กระทำการใด ๆ อันจะก่อให้เกิดความเสียหายต่อประเทศชาติ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการรักษาวินัย มีความรับรัผิดชอบในการรักษาเวลาทำงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย แต่งกายในการปฏิบัติบัติงานได้อย่างเหมาะสมกับการเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันอาจก่อให้เกิดความเสียหายแก่ชื่อเสียงของหน่วยงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันเป็นการเสื่อมเกียรติและศักดิ์ศรีของความเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ปฏิบัติบัติหน้าที่อย่างตรงไปตรงมาโดยยึดหลักจรรยาบรรณวิชาชีพ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "จุดเด่นของความประพฤติ",
|
||||||
|
})
|
||||||
|
behavior_strength_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
comment: "สิ่งที่ควรปรับปรุงของความประพฤติ",
|
||||||
|
})
|
||||||
|
behavior_improve_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การปฐมนิเทศ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
orientation: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การเรียนรู้ด้วยตนเอง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
self_learning: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมสัมนาร่วมกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
training_seminar: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมอื่น ๆ ตามที่หน่วยงานกำหนด",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
other_training: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.evaluateAchievements)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataLevel {
|
||||||
|
id: number;
|
||||||
|
labal: string;
|
||||||
|
level: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataOuptut {
|
||||||
|
id: number;
|
||||||
|
text: string;
|
||||||
|
level: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataOther {
|
||||||
|
text: string;
|
||||||
|
level: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateEvaluateAssessor {
|
||||||
|
evaluate_no?: number;
|
||||||
|
@Column()
|
||||||
|
start_date: Date;
|
||||||
|
@Column()
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
evaluate_expenct_level: DataLevel[];
|
||||||
|
evaluate_ouptut: DataOuptut[];
|
||||||
|
knowledge_level: number;
|
||||||
|
skill_level: number;
|
||||||
|
competency_level: number;
|
||||||
|
learn_level: number;
|
||||||
|
apply_level: number;
|
||||||
|
success_level?: number;
|
||||||
|
achievement_other: DataOther;
|
||||||
|
achievement_strength_desc: string;
|
||||||
|
achievement_improve_desc: string;
|
||||||
|
|
||||||
|
conduct1_level: number;
|
||||||
|
conduct2_level: number;
|
||||||
|
conduct3_level: number;
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
moral1_level: number;
|
||||||
|
moral2_level: number;
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
discipline1_level: number;
|
||||||
|
discipline2_level: number;
|
||||||
|
discipline3_level: number;
|
||||||
|
discipline4_level: number;
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
behavio_orther: DataOther;
|
||||||
|
behavior_strength_desc: string;
|
||||||
|
behavior_improve_desc: string;
|
||||||
|
orientation: number;
|
||||||
|
self_learning: number;
|
||||||
|
training_seminar: number;
|
||||||
|
other_training: number;
|
||||||
|
assessor_dated: Date;
|
||||||
|
|
||||||
|
createdUserId?: string;
|
||||||
|
createdFullName?: string;
|
||||||
|
updateUserId?: string;
|
||||||
|
updateFullName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateEvaluateAssessor = Partial<CreateEvaluateAssessor>;
|
||||||
415
src/entities/EvaluateChairman.ts
Normal file
415
src/entities/EvaluateChairman.ts
Normal file
|
|
@ -0,0 +1,415 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("evaluateChairman")
|
||||||
|
export class EvaluateChairman extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ผู้ประเมิน",
|
||||||
|
})
|
||||||
|
director_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ครั้งที่ประเมิน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
no: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่เริ่มการบันทึก",
|
||||||
|
})
|
||||||
|
date_start: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่สิ้นสุดการบันทึก",
|
||||||
|
})
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
chairman_dated: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการเรียนรู้งาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
knowledge_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการปรับใช้ความรู้กับงานในหน้าที่",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
apply_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสำเร็จของงานที่ได้รับมอบหมาย",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
success_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยอัธยาศัยดี",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ มีความรับผิดชอบในการปฏิบัติบัติงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยความรวดเร็ว เอาใจใส่เป็นมาตรฐานเดียวกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ตั้งใจปฏิบัติบัติหน้าที่ราชการด้วยความอุตสาหะ ขยันหมั่นเพียร",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ อุทิศตนและเสียสละเวลาในการปฏิบัติบัติงานอย่างเต็มกำลังความสามารถ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ มีจิตสำนึกที่ดี ปฏิบัติบัติงานด้วยความซื่อสัตย์ สุจริต",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ ยึดมั่นในสถาบันบัพระมหากษัตริย์ และไม่กระทำการใด ๆ อันจะก่อให้เกิดความเสียหายต่อประเทศชาติ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการรักษาวินัย มีความรับรัผิดชอบในการรักษาเวลาทำงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย แต่งกายในการปฏิบัติบัติงานได้อย่างเหมาะสมกับการเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันอาจก่อให้เกิดความเสียหายแก่ชื่อเสียงของหน่วยงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันเป็นการเสื่อมเกียรติและศักดิ์ศรีของความเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ปฏิบัติบัติหน้าที่อย่างตรงไปตรงมาโดยยึดหลักจรรยาบรรณวิชาชีพ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การปฐมนิเทศ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_orientation_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การเรียนรู้ด้วยตนเอง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_self_learning_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมสัมนาร่วมกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_training_seminar_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมอื่น ๆ ตามที่หน่วยงานกำหนด",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_other_training_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์การพัฒนาตนเอง การปฐมนิเทศ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_orientation_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์การพัฒนาตนเอง การเรียนรู้ด้วยตนเอง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_self_learning_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์การพัฒนาตนเอง การอบรมสัมนาร่วมกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_training_seminar_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์การพัฒนาตนเอง การอบรมอื่น ๆ ตามที่หน่วยงานกำหนด",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
develop_other_training_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลประเมิน 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
develop_result: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนน ผลสัมฤทธิ์ของการทดลองปฏิบัติบัติหน้าที่ราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
achievement_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนเต็ม พฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
achievement_score_total: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์ผลสัมฤทธิ์",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
achievement_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลประเมินผลสัมฤทธิ์ 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
achievement_result: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนน พฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
behavior_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ผลคะแนนรวมพฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
behavior_score_total: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "float",
|
||||||
|
comment: "เปอร์เซ็นต์พฤติกรรม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
behavior_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลประเมินพฤติกรรม 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
behavior_result: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ผลคะแนนรวม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
sum_score: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "เปอร์เซ็นต์ผลรวม",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
sum_percent: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลการประเมิน 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
evaluate_result: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
director1_dated!: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
director2_dated!: Date | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.evaluateChairmans)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataOtherChairman {
|
||||||
|
text: string;
|
||||||
|
level: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateEvaluateChairman {
|
||||||
|
evaluate_no?: number;
|
||||||
|
@Column()
|
||||||
|
start_date: Date;
|
||||||
|
@Column()
|
||||||
|
date_finish: Date;
|
||||||
|
chairman_dated: Date | null;
|
||||||
|
director1_dated: Date | null;
|
||||||
|
director2_dated: Date | null;
|
||||||
|
|
||||||
|
knowledge_level: number;
|
||||||
|
apply_level: number;
|
||||||
|
success_level: number;
|
||||||
|
achievement_other: DataOtherChairman;
|
||||||
|
|
||||||
|
conduct1_level: number;
|
||||||
|
conduct2_level: number;
|
||||||
|
conduct3_level: number;
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
moral1_level: number;
|
||||||
|
moral2_level: number;
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
discipline1_level: number;
|
||||||
|
discipline2_level: number;
|
||||||
|
discipline3_level: number;
|
||||||
|
discipline4_level: number;
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
behavior_orther: DataOtherChairman;
|
||||||
|
develop_orientation_score: number;
|
||||||
|
develop_self_learning_score: number;
|
||||||
|
develop_training_seminar_score: number;
|
||||||
|
develop_other_training_score: number;
|
||||||
|
develop_orientation_percent: number;
|
||||||
|
develop_self_learning_percent: number;
|
||||||
|
develop_training_seminar_percent: number;
|
||||||
|
develop_other_training_percent: number;
|
||||||
|
develop_result: number;
|
||||||
|
achievement_score: number;
|
||||||
|
achievement_score_total: number;
|
||||||
|
achievement_percent: number;
|
||||||
|
achievement_result: number;
|
||||||
|
behavior_score: number;
|
||||||
|
behavior_score_total: number;
|
||||||
|
behavior_percent: number;
|
||||||
|
behavior_result: number;
|
||||||
|
sum_score: number;
|
||||||
|
sum_percent: number;
|
||||||
|
evaluate_result: number;
|
||||||
|
|
||||||
|
createdUserId?: string;
|
||||||
|
createdFullName?: string;
|
||||||
|
updateUserId?: string;
|
||||||
|
updateFullName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateEvaluateChairman = Partial<CreateEvaluateChairman>;
|
||||||
311
src/entities/EvaluateCommander.ts
Normal file
311
src/entities/EvaluateCommander.ts
Normal file
|
|
@ -0,0 +1,311 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("evaluateCommander")
|
||||||
|
export class EvaluateCommander extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ผู้ประเมิน",
|
||||||
|
})
|
||||||
|
director_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ครั้งที่ประเมิน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
no: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่เริ่มการบันทึก",
|
||||||
|
})
|
||||||
|
date_start: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่สิ้นสุดการบันทึก",
|
||||||
|
})
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
commander_dated: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความรู้ความสามารถ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
knowledge_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนทักษะ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
skill_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนสมรรถนะ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
competency_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการเรียนรู้งาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
learn_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสามารถในการปรับใช้ความรู้กับงานในหน้าที่",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
apply_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความสำเร็จของงานที่ได้รับมอบหมาย",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
success_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความสำเร็จของงานที่ได้รับมอบหมายอื่นๆ",
|
||||||
|
})
|
||||||
|
achievement_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยอัธยาศัยดี",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนความประพฤติ มีความรับผิดชอบในการปฏิบัติบัติงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ให้บริการประชาชนหรือผู้รับบริการด้วยความรวดเร็ว เอาใจใส่เป็นมาตรฐานเดียวกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความประพฤติ ตั้งใจปฏิบัติบัติหน้าที่ราชการด้วยความอุตสาหะ ขยันหมั่นเพียร",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ อุทิศตนและเสียสละเวลาในการปฏิบัติบัติงานอย่างเต็มกำลังความสามารถ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ มีจิตสำนึกที่ดี ปฏิบัติบัติงานด้วยความซื่อสัตย์ สุจริต",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนความมีจรรยาบรรณ ยึดมั่นในสถาบันบัพระมหากษัตริย์ และไม่กระทำการใด ๆ อันจะก่อให้เกิดความเสียหายต่อประเทศชาติ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการรักษาวินัย มีความรับรัผิดชอบในการรักษาเวลาทำงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline1_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย แต่งกายในการปฏิบัติบัติงานได้อย่างเหมาะสมกับการเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline2_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันอาจก่อให้เกิดความเสียหายแก่ชื่อเสียงของหน่วยงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline3_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ไม่กระทำการใด ๆ อันเป็นการเสื่อมเกียรติและศักดิ์ศรีของความเป็นข้าราชการ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline4_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"คะแนนการรักษาวินัย ปฏิบัติบัติหน้าที่อย่างตรงไปตรงมาโดยยึดหลักจรรยาบรรณวิชาชีพ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_desc!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับความประพฤติอื่นๆ",
|
||||||
|
})
|
||||||
|
behavior_other_level!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "จุดเด่นของความประพฤติ",
|
||||||
|
})
|
||||||
|
behavior_strength_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สิ่งที่ควรปรับปรุงของความประพฤติ",
|
||||||
|
})
|
||||||
|
behavior_improve_desc: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การปฐมนิเทศ",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
orientation: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การเรียนรู้ด้วยตนเอง",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
self_learning: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมสัมนาร่วมกัน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
training_seminar: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คะแนนการพัฒนาตนเอง การอบรมอื่น ๆ ตามที่หน่วยงานกำหนด",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
other_training: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.evaluateCommanders)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataOtherCommander {
|
||||||
|
text: string;
|
||||||
|
level: number | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateEvaluateCommander {
|
||||||
|
evaluate_no?: number;
|
||||||
|
@Column()
|
||||||
|
start_date: Date;
|
||||||
|
@Column()
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
commander_dated: Date | null;
|
||||||
|
knowledge_level: number;
|
||||||
|
skill_level: number;
|
||||||
|
competency_level: number;
|
||||||
|
learn_level: number;
|
||||||
|
apply_level: number;
|
||||||
|
success_level: number;
|
||||||
|
achievement_other: DataOtherCommander;
|
||||||
|
|
||||||
|
conduct1_level: number;
|
||||||
|
conduct2_level: number;
|
||||||
|
conduct3_level: number;
|
||||||
|
conduct4_level: number;
|
||||||
|
|
||||||
|
moral1_level: number;
|
||||||
|
moral2_level: number;
|
||||||
|
moral3_level: number;
|
||||||
|
|
||||||
|
discipline1_level: number;
|
||||||
|
discipline2_level: number;
|
||||||
|
discipline3_level: number;
|
||||||
|
discipline4_level: number;
|
||||||
|
discipline5_level: number;
|
||||||
|
|
||||||
|
behavior_orther: DataOtherCommander;
|
||||||
|
behavior_strength_desc: string;
|
||||||
|
behavior_improve_desc: string;
|
||||||
|
orientation: number;
|
||||||
|
self_learning: number;
|
||||||
|
training_seminar: number;
|
||||||
|
other_training: number;
|
||||||
|
|
||||||
|
createdUserId?: string;
|
||||||
|
createdFullName?: string;
|
||||||
|
updateUserId?: string;
|
||||||
|
updateFullName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateEvaluateCommander = Partial<CreateEvaluateCommander>;
|
||||||
113
src/entities/EvaluateResult.ts
Normal file
113
src/entities/EvaluateResult.ts
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("evaluateResult")
|
||||||
|
export class EvaluateResult extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "uuid",
|
||||||
|
comment: "Id ผู้ประเมิน",
|
||||||
|
})
|
||||||
|
director_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ครั้งที่ประเมิน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
no: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่เริ่มการบันทึก",
|
||||||
|
})
|
||||||
|
date_start: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
comment: "วันที่สิ้นสุดการบันทึก",
|
||||||
|
})
|
||||||
|
date_finish: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลประเมิน 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
develop_complete: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ผลการทดลองงาน 0 = ไม่ผ่าน, 1 = ผ่าน",
|
||||||
|
})
|
||||||
|
pass_result: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "จำนวนเดือนที่ขยาย",
|
||||||
|
})
|
||||||
|
expand_month!: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "เหตุผล",
|
||||||
|
})
|
||||||
|
reson!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
chairman_dated!: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
director1_dated!: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "date",
|
||||||
|
nullable: true,
|
||||||
|
comment: "วันที่ลงนาม",
|
||||||
|
})
|
||||||
|
director2_dated!: Date | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.evaluateResults)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateEvaluateResult {
|
||||||
|
start_date: Date;
|
||||||
|
date_finish: Date;
|
||||||
|
develop_complete: number;
|
||||||
|
pass_result: number;
|
||||||
|
expand_month: number;
|
||||||
|
reson: string;
|
||||||
|
chairman_dated: Date | null;
|
||||||
|
director1_dated: Date | null;
|
||||||
|
director2_dated: Date | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateEvaluateResult = Partial<CreateEvaluateResult>;
|
||||||
85
src/entities/Knowledge.ts
Normal file
85
src/entities/Knowledge.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { AssignKnowledge } from "./AssignKnowledge";
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
OneToMany,
|
||||||
|
JoinColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
|
||||||
|
export enum TypeKnowledge {
|
||||||
|
PERFORMANCE = "performance",
|
||||||
|
LAW = "law",
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity("knowledge")
|
||||||
|
export class Knowledge extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "enum",
|
||||||
|
enum: TypeKnowledge,
|
||||||
|
default: TypeKnowledge.PERFORMANCE,
|
||||||
|
comment:
|
||||||
|
"หมวดหมู่ความรู้ performance คือความรู้ความสามารถ, law คือความรู้ด้านกฎหมาย",
|
||||||
|
})
|
||||||
|
type: TypeKnowledge;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "หัวข้อความรู้",
|
||||||
|
})
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 1",
|
||||||
|
})
|
||||||
|
level1: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 2",
|
||||||
|
})
|
||||||
|
level2: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 3",
|
||||||
|
})
|
||||||
|
level3: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 4",
|
||||||
|
})
|
||||||
|
level4: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 5",
|
||||||
|
})
|
||||||
|
level5: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน 1 คือใช้งานปกติ, 0 คือไม่ใช้งาน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignKnowledge,
|
||||||
|
(assignKnowledge: AssignKnowledge) => assignKnowledge.knowledge_id
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
assignKnowledge: AssignKnowledge[];
|
||||||
|
}
|
||||||
47
src/entities/Law.ts
Normal file
47
src/entities/Law.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
OneToMany,
|
||||||
|
JoinColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { AssignLaw } from "./AssignLaw";
|
||||||
|
|
||||||
|
@Entity("laws")
|
||||||
|
export class Law extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "เลเวลของ node ข้อมูล",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
parent_id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบาย",
|
||||||
|
})
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "1 คือเลือกได้, 0 คือไม่ให้เลือก",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
status_select: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 5",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
|
||||||
|
@OneToMany(() => AssignLaw, (assignLaw: AssignLaw) => assignLaw.law_id)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
assignLaw: AssignLaw[];
|
||||||
|
}
|
||||||
85
src/entities/MapKnowledgeSkill.ts
Normal file
85
src/entities/MapKnowledgeSkill.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
|
||||||
|
export enum TypeKnowledgeSkill {
|
||||||
|
ACADEMIC = "academic",
|
||||||
|
GENERAL = "general",
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity("knowlegeSkillMaps")
|
||||||
|
export class MapKnowledgeSkill extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "runing number",
|
||||||
|
})
|
||||||
|
no: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "ระดับตำแหน่ง",
|
||||||
|
})
|
||||||
|
positionLevelName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
comment: "ตำแหน่งทางสายงาน",
|
||||||
|
})
|
||||||
|
positionName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "enum",
|
||||||
|
enum: TypeKnowledgeSkill,
|
||||||
|
comment: "academic คือทักษะด้านวิชาการ / general คือทักษะทั่วไป",
|
||||||
|
})
|
||||||
|
type: TypeKnowledgeSkill;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับความสามารถที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
knowlage_performance_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ระดับความรู้ด้านกฎหมายที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
knowlage_law_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ทักษะด้านคอมพิวเตอร์ที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
skill_computer_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ทักษะด้านภาษาอังกฤษที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
skill_english_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ทักษะด้านการจัดการข้อมูลที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
skill_information_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ทักษะด้านการบริหารจัดการทรัพยากรที่คาดหวัง",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
skill_resourse_level: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน 1 คือใช้งานปกติ, 0 คือไม่ใช้งาน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
}
|
||||||
179
src/entities/Personal.ts
Normal file
179
src/entities/Personal.ts
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
OneToOne,
|
||||||
|
JoinColumn,
|
||||||
|
OneToMany,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("personal")
|
||||||
|
export class Personal extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
personal_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "เลขที่คำสั่งบรรจุ",
|
||||||
|
})
|
||||||
|
order_number!: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment:
|
||||||
|
"1 อยู่ระหว่างการทดลองปฏิบัติหน้าที่ราชการ, 2 พ้นการทดลองปฏิบัติหน้าที่ราชการ, 3 ไม่พ้นการทดลองปฏิบัติหน้าที่ราชการ, 4 ยุติการทดลองปฏิบัติหน้าที่ราชการเนื่องจากเปลี่ยนตำแหน่ง, 5 ยุติการทดลองปฏิบัติหน้าที่ราชการเนื่องจากลาออก, 6 ยุติการทดลองปฏิบัติหน้าที่ราชการเนื่องจากถึงแก่กรรม, 7 ขยายระยะเวลาทดลองปฏิบัติหน้าที่ราชการ, 8 ดึงรายชื่อไปออกคำสั่งแล้ว",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
probation_status: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน 1 คือใช้งานปกติ, 0 คือไม่ใช้งาน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำนำหน้าชื่อ",
|
||||||
|
})
|
||||||
|
prefixName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "ชื่อ",
|
||||||
|
})
|
||||||
|
firstName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "นามสกุล",
|
||||||
|
})
|
||||||
|
lastName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: Boolean,
|
||||||
|
comment:
|
||||||
|
"สถานะการทดลองงาน 1 คืออยู่ระหว่างการทดลองงาน, 0 คือไม่อยู่ระหว่างการทดลองงาน",
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
isProbation: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ตำแหน่งในสายงาน",
|
||||||
|
})
|
||||||
|
positionName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "เลขที่ตำแหน่ง",
|
||||||
|
})
|
||||||
|
posNo: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ระดับตำแหน่ง",
|
||||||
|
})
|
||||||
|
positionLevelName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ด้าน/สาขา",
|
||||||
|
})
|
||||||
|
positionLineName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "ประเภทตำแหน่ง",
|
||||||
|
})
|
||||||
|
positionTypeName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "หน่วยงาน",
|
||||||
|
})
|
||||||
|
orgRootName: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: true,
|
||||||
|
comment: "สังกัด",
|
||||||
|
})
|
||||||
|
organization: string;
|
||||||
|
|
||||||
|
@OneToMany(() => Assign, (assign: Assign) => assign.personal_id)
|
||||||
|
@JoinColumn({ name: "personal_id" })
|
||||||
|
assign: Assign[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreatePersonal {
|
||||||
|
@Column()
|
||||||
|
personal_id: string;
|
||||||
|
@Column()
|
||||||
|
order_number: string;
|
||||||
|
@Column()
|
||||||
|
probation_status: number;
|
||||||
|
// @Column()
|
||||||
|
// profiles: PersonalProfile;
|
||||||
|
@Column()
|
||||||
|
createdUserId: string;
|
||||||
|
@Column()
|
||||||
|
createdFullName: string;
|
||||||
|
@Column()
|
||||||
|
updateUserId: string;
|
||||||
|
@Column()
|
||||||
|
updateFullName: string;
|
||||||
|
@Column()
|
||||||
|
prefixName: string;
|
||||||
|
@Column()
|
||||||
|
firstName: string;
|
||||||
|
@Column()
|
||||||
|
lastName: string;
|
||||||
|
@Column()
|
||||||
|
isProbation: number;
|
||||||
|
@Column()
|
||||||
|
positionName: string;
|
||||||
|
@Column()
|
||||||
|
posNo: string;
|
||||||
|
@Column()
|
||||||
|
positionLevelName: string;
|
||||||
|
@Column()
|
||||||
|
positionTypeName: string;
|
||||||
|
@Column()
|
||||||
|
positionLineName: string;
|
||||||
|
@Column()
|
||||||
|
orgRootName: string;
|
||||||
|
@Column()
|
||||||
|
organization: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PostPersonal {
|
||||||
|
id: string;
|
||||||
|
prefix: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
isProbation: boolean;
|
||||||
|
posTypeName?: string | null;
|
||||||
|
posLevelName: string | null;
|
||||||
|
position: string | null;
|
||||||
|
posLineName?: string | null;
|
||||||
|
posNo?: string | null;
|
||||||
|
organization?: string;
|
||||||
|
orgRootName: string | null;
|
||||||
|
orgChild1Name?: string | null;
|
||||||
|
orgChild2Name?: string | null;
|
||||||
|
orgChild3Name?: string | null;
|
||||||
|
orgChild4Name?: string | null;
|
||||||
|
|
||||||
|
order_number?: string;
|
||||||
|
rank?: string | null;
|
||||||
|
idcard?: string;
|
||||||
|
positionField?: string | null;
|
||||||
|
positionArea?: string | null;
|
||||||
|
posExecutiveName?: string | null;
|
||||||
|
positionExecutiveField?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdatePersonal = Partial<CreatePersonal>;
|
||||||
85
src/entities/Skill.ts
Normal file
85
src/entities/Skill.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
OneToMany,
|
||||||
|
JoinColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { AssignSkill } from "./AssignSkill";
|
||||||
|
|
||||||
|
export enum TypeSkill {
|
||||||
|
COMPUTER = "computer",
|
||||||
|
ENG = "english",
|
||||||
|
INFORMATION = "information",
|
||||||
|
RESOURSE = "resourse",
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity("skills")
|
||||||
|
export class Skill extends EntityBase {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
type: "enum",
|
||||||
|
enum: TypeSkill,
|
||||||
|
comment: "หมวดหมู่ทักษะ",
|
||||||
|
})
|
||||||
|
type: TypeSkill;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "หัวข้อความรู้",
|
||||||
|
})
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 1",
|
||||||
|
})
|
||||||
|
level1: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 2",
|
||||||
|
})
|
||||||
|
level2: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 3",
|
||||||
|
})
|
||||||
|
level3: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 4",
|
||||||
|
})
|
||||||
|
level4: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "text",
|
||||||
|
nullable: true,
|
||||||
|
comment: "คำอธิบายระดับความรู้ ระดับที่ 5",
|
||||||
|
})
|
||||||
|
level5: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
nullable: false,
|
||||||
|
comment: "สถานะการใช้งาน 1 คือใช้งานปกติ, 0 คือไม่ใช้งาน",
|
||||||
|
default: 1,
|
||||||
|
})
|
||||||
|
active: number;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignSkill,
|
||||||
|
(assignSkill: AssignSkill) => assignSkill.skill_id
|
||||||
|
)
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
assignSkill: AssignSkill[];
|
||||||
|
}
|
||||||
66
src/entities/Survey.ts
Normal file
66
src/entities/Survey.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { EntityBase } from "./base/Base";
|
||||||
|
import { Assign } from "./Assign";
|
||||||
|
|
||||||
|
@Entity("survey")
|
||||||
|
export class Survey extends EntityBase {
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id ของบุคคล",
|
||||||
|
})
|
||||||
|
personal_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
primary: true,
|
||||||
|
nullable: false,
|
||||||
|
comment: "Id ของแบบมอบหมายงาน",
|
||||||
|
})
|
||||||
|
assign_id: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความคิดเห็นข้อที่ 1",
|
||||||
|
})
|
||||||
|
answer1: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความคิดเห็นข้อที่ 2",
|
||||||
|
})
|
||||||
|
answer2: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ความคิดเห็นข้อที่ 3",
|
||||||
|
})
|
||||||
|
answer3: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Assign, (assign: Assign) => assign.surveys)
|
||||||
|
@JoinColumn({ name: "assign_id" })
|
||||||
|
assign: Assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CreateSurvel {
|
||||||
|
@Column()
|
||||||
|
personal_id: string;
|
||||||
|
@Column()
|
||||||
|
assign_id: string;
|
||||||
|
@Column()
|
||||||
|
answer1: string;
|
||||||
|
@Column()
|
||||||
|
answer2: string;
|
||||||
|
@Column()
|
||||||
|
answer3: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UpdateSurvel = Partial<CreateSurvel>;
|
||||||
47
src/entities/base/Base.ts
Normal file
47
src/entities/base/Base.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import {
|
||||||
|
Entity,
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
// PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class EntityBase {
|
||||||
|
// @PrimaryGeneratedColumn("uuid")
|
||||||
|
// id: string;
|
||||||
|
|
||||||
|
@CreateDateColumn({ comment: "สร้างข้อมูลเมื่อ" })
|
||||||
|
createdAt!: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "User Id ที่สร้างข้อมูล",
|
||||||
|
length: 40,
|
||||||
|
default: "00000000-0000-0000-0000-000000000000",
|
||||||
|
})
|
||||||
|
createdUserId!: String;
|
||||||
|
|
||||||
|
@UpdateDateColumn({ comment: "แก้ไขข้อมูลล่าสุดเมื่อ" })
|
||||||
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "User Id ที่แก้ไขข้อมูล",
|
||||||
|
length: 40,
|
||||||
|
default: "00000000-0000-0000-0000-000000000000",
|
||||||
|
})
|
||||||
|
updateUserId!: String;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ชื่อ User ที่สร้างข้อมูล",
|
||||||
|
length: 200,
|
||||||
|
default: "System Administrator",
|
||||||
|
})
|
||||||
|
createdFullName!: String;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
comment: "ชื่อ User ที่แก้ไขข้อมูลล่าสุด",
|
||||||
|
length: 200,
|
||||||
|
default: "System Administrator",
|
||||||
|
})
|
||||||
|
updateFullName!: String;
|
||||||
|
}
|
||||||
96
src/interfaces/call-api.ts
Normal file
96
src/interfaces/call-api.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Request,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Delete,
|
||||||
|
Patch,
|
||||||
|
Route,
|
||||||
|
Security,
|
||||||
|
Tags,
|
||||||
|
Path,
|
||||||
|
} from "tsoa";
|
||||||
|
import axios from "axios";
|
||||||
|
import { addLogSequence } from "./utils";
|
||||||
|
|
||||||
|
class CallAPI {
|
||||||
|
//Get
|
||||||
|
public async GetData(request: any, @Path() path: any) {
|
||||||
|
const token = request.headers.authorization;
|
||||||
|
const url = process.env.API_URL + path;
|
||||||
|
try {
|
||||||
|
const response = await axios.get(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
api_key: process.env.API_KEY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
addLogSequence(request, {
|
||||||
|
action: "request",
|
||||||
|
status: "success",
|
||||||
|
description: "connected",
|
||||||
|
request: {
|
||||||
|
method: "GET",
|
||||||
|
url: url,
|
||||||
|
response: JSON.stringify(response.data.result),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return response.data.result;
|
||||||
|
} catch (error) {
|
||||||
|
addLogSequence(request, {
|
||||||
|
action: "request",
|
||||||
|
status: "error",
|
||||||
|
description: "unconnected",
|
||||||
|
request: {
|
||||||
|
method: "GET",
|
||||||
|
url: url,
|
||||||
|
response: JSON.stringify(error),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Post
|
||||||
|
public async PostData(request: any, @Path() path: any, sendData: any) {
|
||||||
|
const token = request.headers.authorization;
|
||||||
|
const url = process.env.API_URL + path;
|
||||||
|
try {
|
||||||
|
const response = await axios.post(url, sendData, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
api_key: process.env.API_KEY,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
addLogSequence(request, {
|
||||||
|
action: "request",
|
||||||
|
status: "success",
|
||||||
|
description: "connected",
|
||||||
|
request: {
|
||||||
|
method: "POST",
|
||||||
|
url: url,
|
||||||
|
payload: JSON.stringify(sendData),
|
||||||
|
response: JSON.stringify(response.data.result),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return response.data.result;
|
||||||
|
} catch (error) {
|
||||||
|
addLogSequence(request, {
|
||||||
|
action: "request",
|
||||||
|
status: "error",
|
||||||
|
description: "unconnected",
|
||||||
|
request: {
|
||||||
|
method: "POST",
|
||||||
|
url: url,
|
||||||
|
payload: JSON.stringify(sendData),
|
||||||
|
response: JSON.stringify(error),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CallAPI;
|
||||||
91
src/interfaces/extension.ts
Normal file
91
src/interfaces/extension.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
class Extension {
|
||||||
|
public static ToThaiMonth(value: number) {
|
||||||
|
switch (value) {
|
||||||
|
case 1:
|
||||||
|
return "มกราคม";
|
||||||
|
case 2:
|
||||||
|
return "กุมภาพันธ์";
|
||||||
|
case 3:
|
||||||
|
return "มีนาคม";
|
||||||
|
case 4:
|
||||||
|
return "เมษายน";
|
||||||
|
case 5:
|
||||||
|
return "พฤษภาคม";
|
||||||
|
case 6:
|
||||||
|
return "มิถุนายน";
|
||||||
|
case 7:
|
||||||
|
return "กรกฎาคม";
|
||||||
|
case 8:
|
||||||
|
return "สิงหาคม";
|
||||||
|
case 9:
|
||||||
|
return "กันยายน";
|
||||||
|
case 10:
|
||||||
|
return "ตุลาคม";
|
||||||
|
case 11:
|
||||||
|
return "พฤศจิกายน";
|
||||||
|
case 12:
|
||||||
|
return "ธันวาคม";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToThaiYear(value: number) {
|
||||||
|
if (value < 2400) return value + 543;
|
||||||
|
else return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToCeYear(value: number) {
|
||||||
|
if (value >= 2400) return value - 543;
|
||||||
|
else return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToThaiNumber(value: string) {
|
||||||
|
let arabicNumbers = "0123456789";
|
||||||
|
let thaiNumbers = "๐๑๒๓๔๕๖๗๘๙";
|
||||||
|
let result = "";
|
||||||
|
for (let digit of value) {
|
||||||
|
let index = arabicNumbers.indexOf(digit);
|
||||||
|
if (index >= 0) {
|
||||||
|
result += thaiNumbers[index];
|
||||||
|
} else {
|
||||||
|
result += digit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToThaiFullDate(value: Date) {
|
||||||
|
let yy = value.getFullYear() < 2400 ? value.getFullYear() + 543 : value.getFullYear();
|
||||||
|
return (
|
||||||
|
"วันที่ " +
|
||||||
|
value.getDate() +
|
||||||
|
" เดือน " +
|
||||||
|
Extension.ToThaiMonth(value.getMonth() + 1) +
|
||||||
|
" พ.ศ. " +
|
||||||
|
yy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToThaiFullDate2(value: Date) {
|
||||||
|
let yy = value.getFullYear() < 2400 ? value.getFullYear() + 543 : value.getFullYear();
|
||||||
|
return value.getDate() + " " + Extension.ToThaiMonth(value.getMonth() + 1) + " " + yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ToThaiFullDate3(value: Date) {
|
||||||
|
let yy = value.getFullYear() < 2400 ? value.getFullYear() + 543 : value.getFullYear();
|
||||||
|
return value.getDate() + " เดือน " + Extension.ToThaiMonth(value.getMonth() + 1) + " พ.ศ. " + yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static sumObjectValues(array: any, propertyName: any) {
|
||||||
|
let sum = 0;
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
if (array[i][propertyName] !== undefined) {
|
||||||
|
sum += array[i][propertyName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Extension;
|
||||||
19
src/interfaces/http-error.ts
Normal file
19
src/interfaces/http-error.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import HttpStatus from "./http-status";
|
||||||
|
|
||||||
|
class HttpError extends Error {
|
||||||
|
/**
|
||||||
|
* HTTP Status Code
|
||||||
|
*/
|
||||||
|
status: HttpStatus;
|
||||||
|
message: string;
|
||||||
|
|
||||||
|
constructor(status: HttpStatus, message: string) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = "HttpError";
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HttpError;
|
||||||
380
src/interfaces/http-status.ts
Normal file
380
src/interfaces/http-status.ts
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
/**
|
||||||
|
* Hypertext Transfer Protocol (HTTP) response status codes.
|
||||||
|
* @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
|
||||||
|
*/
|
||||||
|
enum HttpStatus {
|
||||||
|
/**
|
||||||
|
* The server has received the request headers and the client should proceed to send the request body
|
||||||
|
* (in the case of a request for which a body needs to be sent; for example, a POST request).
|
||||||
|
* Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
|
||||||
|
* To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
|
||||||
|
* and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
|
||||||
|
*/
|
||||||
|
CONTINUE = 100,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requester has asked the server to switch protocols and the server has agreed to do so.
|
||||||
|
*/
|
||||||
|
SWITCHING_PROTOCOLS = 101,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
|
||||||
|
* This code indicates that the server has received and is processing the request, but no response is available yet.
|
||||||
|
* This prevents the client from timing out and assuming the request was lost.
|
||||||
|
*/
|
||||||
|
PROCESSING = 102,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard response for successful HTTP requests.
|
||||||
|
* The actual response will depend on the request method used.
|
||||||
|
* In a GET request, the response will contain an entity corresponding to the requested resource.
|
||||||
|
* In a POST request, the response will contain an entity describing or containing the result of the action.
|
||||||
|
*/
|
||||||
|
OK = 200,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request has been fulfilled, resulting in the creation of a new resource.
|
||||||
|
*/
|
||||||
|
CREATED = 201,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request has been accepted for processing, but the processing has not been completed.
|
||||||
|
* The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
|
||||||
|
*/
|
||||||
|
ACCEPTED = 202,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SINCE HTTP/1.1
|
||||||
|
* The server is a transforming proxy that received a 200 OK from its origin,
|
||||||
|
* but is returning a modified version of the origin's response.
|
||||||
|
*/
|
||||||
|
NON_AUTHORITATIVE_INFORMATION = 203,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server successfully processed the request and is not returning any content.
|
||||||
|
*/
|
||||||
|
NO_CONTENT = 204,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server successfully processed the request, but is not returning any content.
|
||||||
|
* Unlike a 204 response, this response requires that the requester reset the document view.
|
||||||
|
*/
|
||||||
|
RESET_CONTENT = 205,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
|
||||||
|
* The range header is used by HTTP clients to enable resuming of interrupted downloads,
|
||||||
|
* or split a download into multiple simultaneous streams.
|
||||||
|
*/
|
||||||
|
PARTIAL_CONTENT = 206,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message body that follows is an XML message and can contain a number of separate response codes,
|
||||||
|
* depending on how many sub-requests were made.
|
||||||
|
*/
|
||||||
|
MULTI_STATUS = 207,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
|
||||||
|
* and are not being included again.
|
||||||
|
*/
|
||||||
|
ALREADY_REPORTED = 208,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server has fulfilled a request for the resource,
|
||||||
|
* and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
|
||||||
|
*/
|
||||||
|
IM_USED = 226,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
|
||||||
|
* For example, this code could be used to present multiple video format options,
|
||||||
|
* to list files with different filename extensions, or to suggest word-sense disambiguation.
|
||||||
|
*/
|
||||||
|
MULTIPLE_CHOICES = 300,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This and all future requests should be directed to the given URI.
|
||||||
|
*/
|
||||||
|
MOVED_PERMANENTLY = 301,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an example of industry practice contradicting the standard.
|
||||||
|
* The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
|
||||||
|
* (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
|
||||||
|
* with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
|
||||||
|
* to distinguish between the two behaviours. However, some Web applications and frameworks
|
||||||
|
* use the 302 status code as if it were the 303.
|
||||||
|
*/
|
||||||
|
FOUND = 302,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SINCE HTTP/1.1
|
||||||
|
* The response to the request can be found under another URI using a GET method.
|
||||||
|
* When received in response to a POST (or PUT/DELETE), the client should presume that
|
||||||
|
* the server has received the data and should issue a redirect with a separate GET message.
|
||||||
|
*/
|
||||||
|
SEE_OTHER = 303,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
|
||||||
|
* In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
|
||||||
|
*/
|
||||||
|
NOT_MODIFIED = 304,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SINCE HTTP/1.1
|
||||||
|
* The requested resource is available only through a proxy, the address for which is provided in the response.
|
||||||
|
* Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
|
||||||
|
*/
|
||||||
|
USE_PROXY = 305,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No longer used. Originally meant "Subsequent requests should use the specified proxy."
|
||||||
|
*/
|
||||||
|
SWITCH_PROXY = 306,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SINCE HTTP/1.1
|
||||||
|
* In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
|
||||||
|
* In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
|
||||||
|
* For example, a POST request should be repeated using another POST request.
|
||||||
|
*/
|
||||||
|
TEMPORARY_REDIRECT = 307,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request and all future requests should be repeated using another URI.
|
||||||
|
* 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
|
||||||
|
* So, for example, submitting a form to a permanently redirected resource may continue smoothly.
|
||||||
|
*/
|
||||||
|
PERMANENT_REDIRECT = 308,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server cannot or will not process the request due to an apparent client error
|
||||||
|
* (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
|
||||||
|
*/
|
||||||
|
BAD_REQUEST = 400,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
|
||||||
|
* been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
|
||||||
|
* requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
|
||||||
|
* "unauthenticated",i.e. the user does not have the necessary credentials.
|
||||||
|
*/
|
||||||
|
UNAUTHORIZED = 401,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserved for future use. The original intention was that this code might be used as part of some form of digital
|
||||||
|
* cash or micro payment scheme, but that has not happened, and this code is not usually used.
|
||||||
|
* Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
|
||||||
|
*/
|
||||||
|
PAYMENT_REQUIRED = 402,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request was valid, but the server is refusing action.
|
||||||
|
* The user might not have the necessary permissions for a resource.
|
||||||
|
*/
|
||||||
|
FORBIDDEN = 403,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested resource could not be found but may be available in the future.
|
||||||
|
* Subsequent requests by the client are permissible.
|
||||||
|
*/
|
||||||
|
NOT_FOUND = 404,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A request method is not supported for the requested resource;
|
||||||
|
* for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
|
||||||
|
*/
|
||||||
|
METHOD_NOT_ALLOWED = 405,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
|
||||||
|
*/
|
||||||
|
NOT_ACCEPTABLE = 406,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client must first authenticate itself with the proxy.
|
||||||
|
*/
|
||||||
|
PROXY_AUTHENTICATION_REQUIRED = 407,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server timed out waiting for the request.
|
||||||
|
* According to HTTP specifications:
|
||||||
|
* "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
|
||||||
|
*/
|
||||||
|
REQUEST_TIMEOUT = 408,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the request could not be processed because of conflict in the request,
|
||||||
|
* such as an edit conflict between multiple simultaneous updates.
|
||||||
|
*/
|
||||||
|
CONFLICT = 409,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the resource requested is no longer available and will not be available again.
|
||||||
|
* This should be used when a resource has been intentionally removed and the resource should be purged.
|
||||||
|
* Upon receiving a 410 status code, the client should not request the resource in the future.
|
||||||
|
* Clients such as search engines should remove the resource from their indices.
|
||||||
|
* Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
|
||||||
|
*/
|
||||||
|
GONE = 410,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request did not specify the length of its content, which is required by the requested resource.
|
||||||
|
*/
|
||||||
|
LENGTH_REQUIRED = 411,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server does not meet one of the preconditions that the requester put on the request.
|
||||||
|
*/
|
||||||
|
PRECONDITION_FAILED = 412,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
|
||||||
|
*/
|
||||||
|
PAYLOAD_TOO_LARGE = 413,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
|
||||||
|
* in which case it should be converted to a POST request.
|
||||||
|
* Called "Request-URI Too Long" previously.
|
||||||
|
*/
|
||||||
|
URI_TOO_LONG = 414,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request entity has a media type which the server or resource does not support.
|
||||||
|
* For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
|
||||||
|
*/
|
||||||
|
UNSUPPORTED_MEDIA_TYPE = 415,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
|
||||||
|
* For example, if the client asked for a part of the file that lies beyond the end of the file.
|
||||||
|
* Called "Requested Range Not Satisfiable" previously.
|
||||||
|
*/
|
||||||
|
RANGE_NOT_SATISFIABLE = 416,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server cannot meet the requirements of the Expect request-header field.
|
||||||
|
*/
|
||||||
|
EXPECTATION_FAILED = 417,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
|
||||||
|
* and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
|
||||||
|
* teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
|
||||||
|
*/
|
||||||
|
I_AM_A_TEAPOT = 418,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request was directed at a server that is not able to produce a response (for example because a connection reuse).
|
||||||
|
*/
|
||||||
|
MISDIRECTED_REQUEST = 421,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request was well-formed but was unable to be followed due to semantic errors.
|
||||||
|
*/
|
||||||
|
UNPROCESSABLE_ENTITY = 422,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource that is being accessed is locked.
|
||||||
|
*/
|
||||||
|
LOCKED = 423,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request failed due to failure of a previous request (e.g., a PROPPATCH).
|
||||||
|
*/
|
||||||
|
FAILED_DEPENDENCY = 424,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
|
||||||
|
*/
|
||||||
|
UPGRADE_REQUIRED = 426,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The origin server requires the request to be conditional.
|
||||||
|
* Intended to prevent "the 'lost update' problem, where a client
|
||||||
|
* GETs a resource's state, modifies it, and PUTs it back to the server,
|
||||||
|
* when meanwhile a third party has modified the state on the server, leading to a conflict."
|
||||||
|
*/
|
||||||
|
PRECONDITION_REQUIRED = 428,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
|
||||||
|
*/
|
||||||
|
TOO_MANY_REQUESTS = 429,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server is unwilling to process the request because either an individual header field,
|
||||||
|
* or all the header fields collectively, are too large.
|
||||||
|
*/
|
||||||
|
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A server operator has received a legal demand to deny access to a resource or to a set of resources
|
||||||
|
* that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
|
||||||
|
*/
|
||||||
|
UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
|
||||||
|
*/
|
||||||
|
INTERNAL_SERVER_ERROR = 500,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server either does not recognize the request method, or it lacks the ability to fulfill the request.
|
||||||
|
* Usually this implies future availability (e.g., a new feature of a web-service API).
|
||||||
|
*/
|
||||||
|
NOT_IMPLEMENTED = 501,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server was acting as a gateway or proxy and received an invalid response from the upstream server.
|
||||||
|
*/
|
||||||
|
BAD_GATEWAY = 502,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server is currently unavailable (because it is overloaded or down for maintenance).
|
||||||
|
* Generally, this is a temporary state.
|
||||||
|
*/
|
||||||
|
SERVICE_UNAVAILABLE = 503,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
|
||||||
|
*/
|
||||||
|
GATEWAY_TIMEOUT = 504,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server does not support the HTTP protocol version used in the request
|
||||||
|
*/
|
||||||
|
HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transparent content negotiation for the request results in a circular reference.
|
||||||
|
*/
|
||||||
|
VARIANT_ALSO_NEGOTIATES = 506,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server is unable to store the representation needed to complete the request.
|
||||||
|
*/
|
||||||
|
INSUFFICIENT_STORAGE = 507,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server detected an infinite loop while processing the request.
|
||||||
|
*/
|
||||||
|
LOOP_DETECTED = 508,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Further extensions to the request are required for the server to fulfill it.
|
||||||
|
*/
|
||||||
|
NOT_EXTENDED = 510,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client needs to authenticate to gain network access.
|
||||||
|
* Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
|
||||||
|
* to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
|
||||||
|
*/
|
||||||
|
NETWORK_AUTHENTICATION_REQUIRED = 511,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HttpStatus;
|
||||||
19
src/interfaces/http-success.ts
Normal file
19
src/interfaces/http-success.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import HttpStatus from "./http-status";
|
||||||
|
import { addLogSequence } from "./utils";
|
||||||
|
|
||||||
|
class HttpSuccess {
|
||||||
|
/**
|
||||||
|
* HTTP Status Code
|
||||||
|
*/
|
||||||
|
status: HttpStatus;
|
||||||
|
message: string;
|
||||||
|
data?: any;
|
||||||
|
|
||||||
|
constructor(data?: any) {
|
||||||
|
this.status = HttpStatus.OK;
|
||||||
|
this.message = "สำเร็จ";
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default HttpSuccess;
|
||||||
227
src/interfaces/permission.ts
Normal file
227
src/interfaces/permission.ts
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
import CallAPI from "./call-api";
|
||||||
|
import HttpError from "./http-error";
|
||||||
|
import HttpStatus from "./http-status";
|
||||||
|
|
||||||
|
class CheckAuth {
|
||||||
|
public async Permission(req: RequestWithUser, system: string, action: string) {
|
||||||
|
if (
|
||||||
|
req.headers.hasOwnProperty("api_key") &&
|
||||||
|
req.headers["api_key"] &&
|
||||||
|
req.headers["api_key"] == process.env.API_KEY
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await new CallAPI()
|
||||||
|
.GetData(req, "/org/permission")
|
||||||
|
.then((x) => {
|
||||||
|
let permission = false;
|
||||||
|
let role = x.roles.find((x: any) => x.authSysId == system);
|
||||||
|
if (!role) throw "ไม่มีสิทธิ์เข้าระบบ";
|
||||||
|
if (role.attrOwnership == "OWNER") return "OWNER";
|
||||||
|
if (action.trim().toLocaleUpperCase() == "CREATE") permission = role.attrIsCreate;
|
||||||
|
if (action.trim().toLocaleUpperCase() == "DELETE") permission = role.attrIsDelete;
|
||||||
|
if (action.trim().toLocaleUpperCase() == "GET") permission = role.attrIsGet;
|
||||||
|
if (action.trim().toLocaleUpperCase() == "LIST") permission = role.attrIsList;
|
||||||
|
if (action.trim().toLocaleUpperCase() == "UPDATE") permission = role.attrIsUpdate;
|
||||||
|
if (permission == false) throw "ไม่มีสิทธิ์ใช้งานระบบนี้";
|
||||||
|
return role.attrPrivilege;
|
||||||
|
})
|
||||||
|
.catch((x) => {
|
||||||
|
if (x.status != undefined) {
|
||||||
|
throw new HttpError(x.status, x.message);
|
||||||
|
} else {
|
||||||
|
throw new HttpError(HttpStatus.FORBIDDEN, x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async PermissionOrg(req: RequestWithUser, system: string, action: string) {
|
||||||
|
if (
|
||||||
|
req.headers.hasOwnProperty("api_key") &&
|
||||||
|
req.headers["api_key"] &&
|
||||||
|
req.headers["api_key"] == process.env.API_KEY
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await new CallAPI()
|
||||||
|
.GetData(req, "/org/permission/org")
|
||||||
|
.then(async (x) => {
|
||||||
|
let privilege = null;
|
||||||
|
if (action.trim().toLocaleUpperCase() == "CREATE")
|
||||||
|
privilege = await this.PermissionCreate(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "DELETE")
|
||||||
|
privilege = await this.PermissionDelete(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "GET")
|
||||||
|
privilege = await this.PermissionGet(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "LIST")
|
||||||
|
privilege = await this.PermissionList(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "UPDATE")
|
||||||
|
privilege = await this.PermissionUpdate(req, system);
|
||||||
|
|
||||||
|
let data: any = {
|
||||||
|
root: [null],
|
||||||
|
child1: [null],
|
||||||
|
child2: [null],
|
||||||
|
child3: [null],
|
||||||
|
child4: [null],
|
||||||
|
};
|
||||||
|
let node = 4;
|
||||||
|
if (x.orgChild1Id == null) {
|
||||||
|
node = 0;
|
||||||
|
} else if (x.orgChild2Id == null) {
|
||||||
|
node = 1;
|
||||||
|
} else if (x.orgChild3Id == null) {
|
||||||
|
node = 2;
|
||||||
|
} else if (x.orgChild4Id == null) {
|
||||||
|
node = 3;
|
||||||
|
}
|
||||||
|
if (privilege == "ROOT") {
|
||||||
|
data = {
|
||||||
|
root: [x.orgRootId],
|
||||||
|
child1: null,
|
||||||
|
child2: null,
|
||||||
|
child3: null,
|
||||||
|
child4: null,
|
||||||
|
};
|
||||||
|
} else if (privilege == "CHILD") {
|
||||||
|
data = {
|
||||||
|
root: node >= 0 ? [x.orgRootId] : null,
|
||||||
|
child1: node >= 1 ? [x.orgChild1Id] : null,
|
||||||
|
child2: node >= 2 ? [x.orgChild2Id] : null,
|
||||||
|
child3: node >= 3 ? [x.orgChild3Id] : null,
|
||||||
|
child4: node >= 4 ? [x.orgChild4Id] : null,
|
||||||
|
};
|
||||||
|
} else if (privilege == "NORMAL") {
|
||||||
|
data = {
|
||||||
|
root: [x.orgRootId],
|
||||||
|
child1: [x.orgChild1Id],
|
||||||
|
child2: [x.orgChild2Id],
|
||||||
|
child3: [x.orgChild3Id],
|
||||||
|
child4: [x.orgChild4Id],
|
||||||
|
};
|
||||||
|
} else if (privilege == "SPECIFIC") {
|
||||||
|
} else if (privilege == "OWNER") {
|
||||||
|
data = {
|
||||||
|
root: null,
|
||||||
|
child1: null,
|
||||||
|
child2: null,
|
||||||
|
child3: null,
|
||||||
|
child4: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.catch((x) => {
|
||||||
|
if (x.status != undefined) {
|
||||||
|
throw new HttpError(x.status, x.message);
|
||||||
|
} else {
|
||||||
|
throw new HttpError(HttpStatus.FORBIDDEN, x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async PermissionOrgByUser(
|
||||||
|
req: RequestWithUser,
|
||||||
|
system: string,
|
||||||
|
action: string,
|
||||||
|
profileId: string,
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
req.headers.hasOwnProperty("api_key") &&
|
||||||
|
req.headers["api_key"] &&
|
||||||
|
req.headers["api_key"] == process.env.API_KEY
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return await new CallAPI()
|
||||||
|
.GetData(req, `/org/permission/user/${profileId}`)
|
||||||
|
.then(async (x) => {
|
||||||
|
let org = {
|
||||||
|
root: [null],
|
||||||
|
child1: [null],
|
||||||
|
child2: [null],
|
||||||
|
child3: [null],
|
||||||
|
child4: [null],
|
||||||
|
};
|
||||||
|
if (action.trim().toLocaleUpperCase() == "CREATE")
|
||||||
|
org = await this.PermissionOrgCreate(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "DELETE")
|
||||||
|
org = await this.PermissionOrgDelete(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "GET")
|
||||||
|
org = await this.PermissionOrgGet(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "LIST")
|
||||||
|
org = await this.PermissionOrgList(req, system);
|
||||||
|
if (action.trim().toLocaleUpperCase() == "UPDATE")
|
||||||
|
org = await this.PermissionOrgUpdate(req, system);
|
||||||
|
|
||||||
|
if (org.root != null) if (x.orgRootId != org.root[0]) throw "ไม่มีสิทธิ์เข้าถึงข้อมูล";
|
||||||
|
if (org.child1 != null)
|
||||||
|
if (x.orgChild1Id != org.child1[0]) throw "ไม่มีสิทธิ์เข้าถึงข้อมูล";
|
||||||
|
if (org.child2 != null)
|
||||||
|
if (x.orgChild2Id != org.child2[0]) throw "ไม่มีสิทธิ์เข้าถึงข้อมูล";
|
||||||
|
if (org.child3 != null)
|
||||||
|
if (x.orgChild3Id != org.child3[0]) throw "ไม่มีสิทธิ์เข้าถึงข้อมูล";
|
||||||
|
if (org.child4 != null)
|
||||||
|
if (x.orgChild4Id != org.child4[0]) throw "ไม่มีสิทธิ์เข้าถึงข้อมูล";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch((x) => {
|
||||||
|
if (x.status != undefined) {
|
||||||
|
throw new HttpError(x.status, x.message);
|
||||||
|
} else {
|
||||||
|
throw new HttpError(HttpStatus.FORBIDDEN, x);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async PermissionCreate(req: RequestWithUser, system: string) {
|
||||||
|
return await this.Permission(req, system, "CREATE");
|
||||||
|
}
|
||||||
|
public async PermissionDelete(req: RequestWithUser, system: string) {
|
||||||
|
return await this.Permission(req, system, "DELETE");
|
||||||
|
}
|
||||||
|
public async PermissionGet(req: RequestWithUser, system: string) {
|
||||||
|
return await this.Permission(req, system, "GET");
|
||||||
|
}
|
||||||
|
public async PermissionList(req: RequestWithUser, system: string) {
|
||||||
|
return await this.Permission(req, system, "LIST");
|
||||||
|
}
|
||||||
|
public async PermissionUpdate(req: RequestWithUser, system: string) {
|
||||||
|
return await this.Permission(req, system, "UPDATE");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async PermissionOrgCreate(req: RequestWithUser, system: string) {
|
||||||
|
return await this.PermissionOrg(req, system, "CREATE");
|
||||||
|
}
|
||||||
|
public async PermissionOrgDelete(req: RequestWithUser, system: string) {
|
||||||
|
return await this.PermissionOrg(req, system, "DELETE");
|
||||||
|
}
|
||||||
|
public async PermissionOrgGet(req: RequestWithUser, system: string) {
|
||||||
|
return await this.PermissionOrg(req, system, "GET");
|
||||||
|
}
|
||||||
|
public async PermissionOrgList(req: RequestWithUser, system: string) {
|
||||||
|
return await this.PermissionOrg(req, system, "LIST");
|
||||||
|
}
|
||||||
|
public async PermissionOrgUpdate(req: RequestWithUser, system: string) {
|
||||||
|
return await this.PermissionOrg(req, system, "UPDATE");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async PermissionOrgUserCreate(req: RequestWithUser, system: string, profileId: string) {
|
||||||
|
return await this.PermissionOrgByUser(req, system, "CREATE", profileId);
|
||||||
|
}
|
||||||
|
public async PermissionOrgUserDelete(req: RequestWithUser, system: string, profileId: string) {
|
||||||
|
return await this.PermissionOrgByUser(req, system, "DELETE", profileId);
|
||||||
|
}
|
||||||
|
public async PermissionOrgUserGet(req: RequestWithUser, system: string, profileId: string) {
|
||||||
|
return await this.PermissionOrgByUser(req, system, "GET", profileId);
|
||||||
|
}
|
||||||
|
public async PermissionOrgUserList(req: RequestWithUser, system: string, profileId: string) {
|
||||||
|
return await this.PermissionOrgByUser(req, system, "LIST", profileId);
|
||||||
|
}
|
||||||
|
public async PermissionOrgUserUpdate(req: RequestWithUser, system: string, profileId: string) {
|
||||||
|
return await this.PermissionOrgByUser(req, system, "UPDATE", profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CheckAuth;
|
||||||
39
src/interfaces/storage-fs.ts
Normal file
39
src/interfaces/storage-fs.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
export interface StorageFolder {
|
||||||
|
/**
|
||||||
|
* @prop Full path to this folder. It is used as key as there are no files or directories at the same location.
|
||||||
|
*/
|
||||||
|
pathname: string;
|
||||||
|
/**
|
||||||
|
* @prop Directory / Folder name.
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
createdAt: string | Date;
|
||||||
|
createdBy: string | Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StorageFile {
|
||||||
|
/**
|
||||||
|
* @prop Full path to this folder. It is used as key as there are no files or directories at the same location.
|
||||||
|
*/
|
||||||
|
pathname: string;
|
||||||
|
|
||||||
|
fileName: string;
|
||||||
|
fileSize: number;
|
||||||
|
fileType: string;
|
||||||
|
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
author: string;
|
||||||
|
category: string[];
|
||||||
|
keyword: string[];
|
||||||
|
metadata: Record<string, unknown>;
|
||||||
|
|
||||||
|
path: string;
|
||||||
|
upload: boolean;
|
||||||
|
|
||||||
|
updatedAt: string | Date;
|
||||||
|
updatedBy: string;
|
||||||
|
createdAt: string | Date;
|
||||||
|
createdBy: string;
|
||||||
|
}
|
||||||
65
src/interfaces/utils.ts
Normal file
65
src/interfaces/utils.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { RequestWithUser } from "../middlewares/user";
|
||||||
|
|
||||||
|
export type DataDiff = {
|
||||||
|
before: any;
|
||||||
|
after: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LogSequence = {
|
||||||
|
action: string;
|
||||||
|
status: "success" | "error";
|
||||||
|
description: string;
|
||||||
|
query?: any;
|
||||||
|
request?: {
|
||||||
|
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
||||||
|
url?: string;
|
||||||
|
payload?: string;
|
||||||
|
response?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function setLogDataDiff(req: RequestWithUser, data: DataDiff) {
|
||||||
|
req.app.locals.logData.dataDiff = {
|
||||||
|
before: JSON.stringify(data.before),
|
||||||
|
after: JSON.stringify(data.after),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addLogSequence(req: RequestWithUser, data: LogSequence) {
|
||||||
|
if (!req?.app?.locals?.logData?.sequence) {
|
||||||
|
req.app.locals.logData.sequence = [];
|
||||||
|
}
|
||||||
|
req.app.locals.logData.sequence =
|
||||||
|
req.app.locals.logData.sequence.concat(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function editLogSequence(
|
||||||
|
req: RequestWithUser,
|
||||||
|
index: number,
|
||||||
|
data: LogSequence
|
||||||
|
) {
|
||||||
|
req.app.locals.logData.sequence[index] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findEndDate(month: number, start_date: Date | string) {
|
||||||
|
const startDate = new Date(start_date);
|
||||||
|
startDate.setMonth(startDate.getMonth() + month);
|
||||||
|
startDate.setDate(startDate.getDate() - 1);
|
||||||
|
|
||||||
|
return startDate.toISOString().slice(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PassPerson {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PassAssign {
|
||||||
|
date_start: Date;
|
||||||
|
date_finish: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DataPass = {
|
||||||
|
person: PassPerson;
|
||||||
|
assign: PassAssign;
|
||||||
|
};
|
||||||
88
src/middlewares/auth.ts
Normal file
88
src/middlewares/auth.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import * as express from "express";
|
||||||
|
import { createDecoder, createVerifier } from "fast-jwt";
|
||||||
|
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import HttpStatus from "../interfaces/http-status";
|
||||||
|
import { addLogSequence } from "../interfaces/utils";
|
||||||
|
import { RequestWithUser } from "./user";
|
||||||
|
|
||||||
|
if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) {
|
||||||
|
throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL.");
|
||||||
|
}
|
||||||
|
if (process.env.AUTH_PUBLIC_KEY && process.env.AUTH_REALM_URL && !process.env.AUTH_PREFERRED_MODE) {
|
||||||
|
throw new Error(
|
||||||
|
"AUTH_PREFFERRED must be specified if AUTH_PUBLIC_KEY and AUTH_REALM_URL is provided.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const jwtVerify = createVerifier({
|
||||||
|
key: async () => {
|
||||||
|
return `-----BEGIN PUBLIC KEY-----\n${process.env.AUTH_PUBLIC_KEY}\n-----END PUBLIC KEY-----`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const jwtDecode = createDecoder();
|
||||||
|
|
||||||
|
export async function expressAuthentication(
|
||||||
|
request: RequestWithUser,
|
||||||
|
securityName: string,
|
||||||
|
_scopes?: string[],
|
||||||
|
) {
|
||||||
|
if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) {
|
||||||
|
return { preferred_username: "bypassed" };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (securityName !== "bearerAuth") throw new Error("ไม่ทราบวิธีการยืนยันตัวตน");
|
||||||
|
|
||||||
|
const token = request.headers["authorization"]?.includes("Bearer ")
|
||||||
|
? request.headers["authorization"].split(" ")[1]
|
||||||
|
: request.headers["authorization"];
|
||||||
|
|
||||||
|
if (!token) throw new HttpError(HttpStatus.UNAUTHORIZED, "ไม่พบข้อมูลสำหรับยืนยันตัวตน");
|
||||||
|
|
||||||
|
let payload: Record<string, any> = {};
|
||||||
|
|
||||||
|
switch (process.env.AUTH_PREFERRED_MODE) {
|
||||||
|
case "online":
|
||||||
|
payload = await verifyOnline(token);
|
||||||
|
break;
|
||||||
|
case "offline":
|
||||||
|
payload = await verifyOffline(token);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (process.env.AUTH_REALM_URL) payload = await verifyOnline(token);
|
||||||
|
if (process.env.AUTH_PUBLIC_KEY) payload = await verifyOffline(token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!request.app.locals.logData) {
|
||||||
|
request.app.locals.logData = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// addLogSequence(request, {
|
||||||
|
// action: "database",
|
||||||
|
// status: "success",
|
||||||
|
// description: "Query Data.",
|
||||||
|
// });
|
||||||
|
request.app.locals.logData.userId = payload.sub;
|
||||||
|
request.app.locals.logData.userName = payload.name;
|
||||||
|
request.app.locals.logData.user = payload.preferred_username;
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyOffline(token: string) {
|
||||||
|
const payload = await jwtVerify(token).catch((_) => null);
|
||||||
|
if (!payload) throw new HttpError(HttpStatus.UNAUTHORIZED, "ไม่สามารถยืนยันตัวตนได้");
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyOnline(token: string) {
|
||||||
|
const res = await fetch(`${process.env.AUTH_REALM_URL}/protocol/openid-connect/userinfo`, {
|
||||||
|
headers: { authorization: `Bearer ${token}` },
|
||||||
|
}).catch((e) => console.error(e));
|
||||||
|
|
||||||
|
if (!res) throw new Error("ไม่สามารถเข้าถึงระบบยืนยันตัวตน");
|
||||||
|
if (!res.ok) throw new HttpError(HttpStatus.UNAUTHORIZED, "ไม่สามารถยืนยันตัวตนได้");
|
||||||
|
|
||||||
|
return await jwtDecode(token);
|
||||||
|
}
|
||||||
36
src/middlewares/error.ts
Normal file
36
src/middlewares/error.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { NextFunction, Request, Response } from "express";
|
||||||
|
import HttpError from "../interfaces/http-error";
|
||||||
|
import HttpStatus from "../interfaces/http-status";
|
||||||
|
import { ValidateError } from "tsoa";
|
||||||
|
|
||||||
|
function error(error: Error, _req: Request, res: Response, _next: NextFunction) {
|
||||||
|
const logData = _req.app.locals.logData.sequence?.at(-1);
|
||||||
|
if (logData) {
|
||||||
|
logData.status = "error";
|
||||||
|
logData.description = error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error instanceof HttpError) {
|
||||||
|
return res.status(error.status).json({
|
||||||
|
status: error.status,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error instanceof ValidateError) {
|
||||||
|
return res.status(error.status).json({
|
||||||
|
status: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
|
message: "Validation error(s).",
|
||||||
|
detail: error.fields,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("Exception Caught:" + error);
|
||||||
|
|
||||||
|
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
||||||
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default error;
|
||||||
79
src/middlewares/logs.ts
Normal file
79
src/middlewares/logs.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { NextFunction, Request, Response } from "express";
|
||||||
|
import { Client } from "@elastic/elasticsearch";
|
||||||
|
|
||||||
|
if (!process.env.ELASTICSEARCH_INDEX) {
|
||||||
|
throw new Error("Require ELASTICSEARCH_INDEX to store log.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX;
|
||||||
|
|
||||||
|
const LOG_LEVEL_MAP: Record<string, number> = {
|
||||||
|
debug: 4,
|
||||||
|
info: 3,
|
||||||
|
warning: 2,
|
||||||
|
error: 1,
|
||||||
|
none: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const elasticsearch = new Client({
|
||||||
|
node: `${process.env.ELASTICSEARCH_PROTOCOL}://${process.env.ELASTICSEARCH_HOST}:${process.env.ELASTICSEARCH_PORT}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function logMiddleware(req: Request, res: Response, next: NextFunction) {
|
||||||
|
if (!req.url.startsWith("/api/")) return next();
|
||||||
|
|
||||||
|
let data: any;
|
||||||
|
|
||||||
|
const originalJson = res.json;
|
||||||
|
|
||||||
|
res.json = function (v: any) {
|
||||||
|
data = v;
|
||||||
|
return originalJson.call(this, v);
|
||||||
|
};
|
||||||
|
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
const start = performance.now();
|
||||||
|
|
||||||
|
req.app.locals.logData = {};
|
||||||
|
|
||||||
|
res.on("finish", () => {
|
||||||
|
if (!req.url.startsWith("/api/")) return;
|
||||||
|
|
||||||
|
const level = LOG_LEVEL_MAP[process.env.LOG_LEVEL ?? "debug"] || 4;
|
||||||
|
|
||||||
|
if (level === 1 && res.statusCode < 500) return;
|
||||||
|
if (level === 2 && res.statusCode < 400) return;
|
||||||
|
if (level === 3 && res.statusCode < 200) return;
|
||||||
|
|
||||||
|
const obj = {
|
||||||
|
logType:
|
||||||
|
res.statusCode >= 500
|
||||||
|
? "error"
|
||||||
|
: res.statusCode >= 400
|
||||||
|
? "warning"
|
||||||
|
: "info",
|
||||||
|
ip: req.ip,
|
||||||
|
systemName: "probation",
|
||||||
|
startTimeStamp: timestamp,
|
||||||
|
endTimeStamp: new Date().toISOString(),
|
||||||
|
processTime: performance.now() - start,
|
||||||
|
host: req.hostname,
|
||||||
|
method: req.method,
|
||||||
|
endpoint: req.url,
|
||||||
|
responseCode: String(res.statusCode === 304 ? 200 : res.statusCode),
|
||||||
|
responseDescription: data?.message,
|
||||||
|
input: (level === 4 && JSON.stringify(req.body, null, 2)) || undefined,
|
||||||
|
output: (level === 4 && JSON.stringify(data, null, 2)) || undefined,
|
||||||
|
...req.app.locals.logData,
|
||||||
|
};
|
||||||
|
|
||||||
|
elasticsearch.index({
|
||||||
|
index: ELASTICSEARCH_INDEX,
|
||||||
|
document: obj,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
export default logMiddleware;
|
||||||
13
src/middlewares/user.ts
Normal file
13
src/middlewares/user.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import type { Request } from "express";
|
||||||
|
|
||||||
|
export type RequestWithUser = Request & {
|
||||||
|
user: {
|
||||||
|
sub: string;
|
||||||
|
name: string;
|
||||||
|
given_name: string;
|
||||||
|
familiy_name: string;
|
||||||
|
preferred_username: string;
|
||||||
|
email: string;
|
||||||
|
role: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
86
src/migration/1725518260097-start.ts
Normal file
86
src/migration/1725518260097-start.ts
Normal file
File diff suppressed because one or more lines are too long
266
static/index.html
Normal file
266
static/index.html
Normal file
|
|
@ -0,0 +1,266 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||||
|
~ and other contributors as indicated by the @author tags.
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="./keycloak.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<button onclick="keycloak.login()">Login</button>
|
||||||
|
<button onclick="keycloak.login({ action: 'UPDATE_PASSWORD' })">
|
||||||
|
Update Password
|
||||||
|
</button>
|
||||||
|
<button onclick="keycloak.logout()">Logout</button>
|
||||||
|
<button onclick="keycloak.register()">Register</button>
|
||||||
|
<button onclick="keycloak.accountManagement()">Account</button>
|
||||||
|
<button onclick="refreshToken(9999)">Refresh Token</button>
|
||||||
|
<button onclick="refreshToken(30)">
|
||||||
|
Refresh Token (if <30s validity)
|
||||||
|
</button>
|
||||||
|
<button onclick="loadProfile()">Get Profile</button>
|
||||||
|
<button onclick="updateProfile()">Update profile</button>
|
||||||
|
<button onclick="loadUserInfo()">Get User Info</button>
|
||||||
|
<button onclick="output(keycloak.tokenParsed)">Show Token</button>
|
||||||
|
<button onclick="output(keycloak.refreshTokenParsed)">
|
||||||
|
Show Refresh Token
|
||||||
|
</button>
|
||||||
|
<button onclick="output(keycloak.idTokenParsed)">Show ID Token</button>
|
||||||
|
<button onclick="showExpires()">Show Expires</button>
|
||||||
|
<button onclick="output(keycloak)">Show Details</button>
|
||||||
|
<button onclick="output(keycloak.createLoginUrl())">
|
||||||
|
Show Login URL
|
||||||
|
</button>
|
||||||
|
<button onclick="output(keycloak.createLogoutUrl())">
|
||||||
|
Show Logout URL
|
||||||
|
</button>
|
||||||
|
<button onclick="output(keycloak.createRegisterUrl())">
|
||||||
|
Show Register URL
|
||||||
|
</button>
|
||||||
|
<button onclick="output(keycloak.createAccountUrl())">
|
||||||
|
Show Account URL
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Result</h2>
|
||||||
|
<pre
|
||||||
|
style="
|
||||||
|
background-color: #ddd;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
"
|
||||||
|
id="output"
|
||||||
|
></pre>
|
||||||
|
|
||||||
|
<h2>Events</h2>
|
||||||
|
<pre
|
||||||
|
style="
|
||||||
|
background-color: #ddd;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
"
|
||||||
|
id="events"
|
||||||
|
></pre>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function loadProfile() {
|
||||||
|
keycloak
|
||||||
|
.loadUserProfile()
|
||||||
|
.success(function (profile) {
|
||||||
|
output(profile);
|
||||||
|
})
|
||||||
|
.error(function () {
|
||||||
|
output("Failed to load profile");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateProfile() {
|
||||||
|
var url = keycloak.createAccountUrl().split("?")[0];
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.open("POST", url, true);
|
||||||
|
req.setRequestHeader("Accept", "application/json");
|
||||||
|
req.setRequestHeader("Content-Type", "application/json");
|
||||||
|
req.setRequestHeader("Authorization", "bearer " + keycloak.token);
|
||||||
|
|
||||||
|
req.onreadystatechange = function () {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
if (req.status == 200) {
|
||||||
|
output("Success");
|
||||||
|
} else {
|
||||||
|
output("Failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
req.send(
|
||||||
|
'{"email":"myemail@foo.bar","firstName":"test","lastName":"bar"}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadUserInfo() {
|
||||||
|
keycloak
|
||||||
|
.loadUserInfo()
|
||||||
|
.success(function (userInfo) {
|
||||||
|
output(userInfo);
|
||||||
|
})
|
||||||
|
.error(function () {
|
||||||
|
output("Failed to load user info");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshToken(minValidity) {
|
||||||
|
keycloak
|
||||||
|
.updateToken(minValidity)
|
||||||
|
.then(function (refreshed) {
|
||||||
|
if (refreshed) {
|
||||||
|
output(keycloak.tokenParsed);
|
||||||
|
} else {
|
||||||
|
output(
|
||||||
|
"Token not refreshed, valid for " +
|
||||||
|
Math.round(
|
||||||
|
keycloak.tokenParsed.exp +
|
||||||
|
keycloak.timeSkew -
|
||||||
|
new Date().getTime() / 1000
|
||||||
|
) +
|
||||||
|
" seconds"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
output("Failed to refresh token");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showExpires() {
|
||||||
|
if (!keycloak.tokenParsed) {
|
||||||
|
output("Not authenticated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var o =
|
||||||
|
"Token Expires:\t\t" +
|
||||||
|
new Date(
|
||||||
|
(keycloak.tokenParsed.exp + keycloak.timeSkew) * 1000
|
||||||
|
).toLocaleString() +
|
||||||
|
"\n";
|
||||||
|
o +=
|
||||||
|
"Token Expires in:\t" +
|
||||||
|
Math.round(
|
||||||
|
keycloak.tokenParsed.exp +
|
||||||
|
keycloak.timeSkew -
|
||||||
|
new Date().getTime() / 1000
|
||||||
|
) +
|
||||||
|
" seconds\n";
|
||||||
|
|
||||||
|
if (keycloak.refreshTokenParsed) {
|
||||||
|
o +=
|
||||||
|
"Refresh Token Expires:\t" +
|
||||||
|
new Date(
|
||||||
|
(keycloak.refreshTokenParsed.exp + keycloak.timeSkew) * 1000
|
||||||
|
).toLocaleString() +
|
||||||
|
"\n";
|
||||||
|
o +=
|
||||||
|
"Refresh Expires in:\t" +
|
||||||
|
Math.round(
|
||||||
|
keycloak.refreshTokenParsed.exp +
|
||||||
|
keycloak.timeSkew -
|
||||||
|
new Date().getTime() / 1000
|
||||||
|
) +
|
||||||
|
" seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
output(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
function output(data) {
|
||||||
|
if (typeof data === "object") {
|
||||||
|
data = JSON.stringify(data, null, " ");
|
||||||
|
}
|
||||||
|
document.getElementById("output").innerHTML = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function event(event) {
|
||||||
|
var e = document.getElementById("events").innerHTML;
|
||||||
|
document.getElementById("events").innerHTML =
|
||||||
|
new Date().toLocaleString() + "\t" + event + "\n" + e;
|
||||||
|
}
|
||||||
|
|
||||||
|
var keycloak = Keycloak();
|
||||||
|
|
||||||
|
keycloak.onAuthSuccess = function () {
|
||||||
|
event("Auth Success");
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onAuthError = function (errorData) {
|
||||||
|
event("Auth Error: " + JSON.stringify(errorData));
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onAuthRefreshSuccess = function () {
|
||||||
|
event("Auth Refresh Success");
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onAuthRefreshError = function () {
|
||||||
|
event("Auth Refresh Error");
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onAuthLogout = function () {
|
||||||
|
event("Auth Logout");
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onTokenExpired = function () {
|
||||||
|
event("Access token expired.");
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak.onActionUpdate = function (status) {
|
||||||
|
switch (status) {
|
||||||
|
case "success":
|
||||||
|
event("Action completed successfully");
|
||||||
|
break;
|
||||||
|
case "cancelled":
|
||||||
|
event("Action cancelled by user");
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
event("Action failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Flow can be changed to 'implicit' or 'hybrid', but then client must enable implicit flow in admin console too
|
||||||
|
var initOptions = {
|
||||||
|
responseMode: "fragment",
|
||||||
|
flow: "standard",
|
||||||
|
};
|
||||||
|
|
||||||
|
keycloak
|
||||||
|
.init(initOptions)
|
||||||
|
.then(function (authenticated) {
|
||||||
|
output(
|
||||||
|
"Init Success (" +
|
||||||
|
(authenticated ? "Authenticated" : "Not Authenticated") +
|
||||||
|
")"
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
output("Init Error");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2952
static/keycloak.js
Normal file
2952
static/keycloak.js
Normal file
File diff suppressed because it is too large
Load diff
9
static/keycloak.json
Normal file
9
static/keycloak.json
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"realm": "bma-ehr",
|
||||||
|
"auth-server-url": "https://id.frappet.synology.me",
|
||||||
|
"ssl-required": "external",
|
||||||
|
"resource": "bma-ehr",
|
||||||
|
"public-client": true,
|
||||||
|
"client_secret": "tF0huP4MylOSMVZEohwPMI8DDttW66A7",
|
||||||
|
"realm-public-key":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYg0ZJvH6HgNOzyPp7PCvY3bJwD9WdsNn6gZbuvIfqJQZ8iSH1t0p3fgODO/fqwcj9UFeh1bVFOSjuW+JpnPehROqzt81KNl9zLLNXoN4LimReQHaMM3dU7DCbRylgVCouIDvObyjg8G+Cy5lZvFKWym/DPwGVpSdbvDZJ83qxq2dp7GJXS8PhOvA+MB1K009/jW5pBTUwNArLjoFccr+gIYIiOJDg2rYyIF3fDkwyWkuxr6xRt10+BRJytselwy/18kbDuJxVPaapdgTXI6wLzx7HWcDk30n5EvhJEumnIPpRst8gucqNYmB4MH+vsyoxV5WLuO3qmVRzFbtAppRQIDAQAB"
|
||||||
|
}
|
||||||
18
tsconfig.json
Normal file
18
tsconfig.json
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"incremental": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"strictPropertyInitialization": false,
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
||||||
38
tsoa.json
Normal file
38
tsoa.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"entryFile": "src/app.ts",
|
||||||
|
"noImplicitAdditionalProperties": "throw-on-extras",
|
||||||
|
"controllerPathGlobs": ["src/controllers/*Controller.ts"],
|
||||||
|
"spec": {
|
||||||
|
"outputDirectory": "src",
|
||||||
|
"specVersion": 3,
|
||||||
|
"spec": {
|
||||||
|
"info": {
|
||||||
|
"title": "bma-ehr-probation - API",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "ระบบการพัฒนาบุคลากร/การศึกษาต่อ (Development: DV)",
|
||||||
|
"license": {
|
||||||
|
"name": "by Frappet",
|
||||||
|
"url": "https://frappet.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"basePath": "/"
|
||||||
|
},
|
||||||
|
"securityDefinitions": {
|
||||||
|
"bearerAuth": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "Authorization",
|
||||||
|
"description": "Keycloak Bearer Token",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Test", "description": "สำหรับทดสอบ"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"routes": {
|
||||||
|
"routesDir": "src/",
|
||||||
|
"authenticationModule": "src/middlewares/auth.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
87
workflows/release.yaml
Normal file
87
workflows/release.yaml
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
name: release-test
|
||||||
|
run-name: release-test ${{ github.actor }}
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "version-[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
REGISTRY: docker.frappet.com
|
||||||
|
IMAGE_NAME: ehr/bma-ehr-development-service
|
||||||
|
DEPLOY_HOST: frappet.com
|
||||||
|
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||||
|
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-development
|
||||||
|
jobs:
|
||||||
|
# act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||||
|
release-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# skip Set up QEMU because it fail on act and container
|
||||||
|
# Gen Version try to get version from tag or inut
|
||||||
|
- name: Set output tags
|
||||||
|
id: vars
|
||||||
|
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||||
|
- name: Gen Version
|
||||||
|
id: gen_ver
|
||||||
|
run: |
|
||||||
|
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||||
|
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||||
|
else
|
||||||
|
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
fi
|
||||||
|
if [[ $IMAGE_VER == '' ]]; then
|
||||||
|
IMAGE_VER='test-vBeta'
|
||||||
|
fi
|
||||||
|
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||||
|
- name: Check Version
|
||||||
|
run: |
|
||||||
|
echo $GITHUB_REF
|
||||||
|
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login in to registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{env.REGISTRY}}
|
||||||
|
username: ${{secrets.DOCKER_USER}}
|
||||||
|
password: ${{secrets.DOCKER_PASS}}
|
||||||
|
- name: Build and push docker image
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||||
|
- name: Remote Deployment
|
||||||
|
uses: appleboy/ssh-action@v0.1.8
|
||||||
|
with:
|
||||||
|
host: ${{env.DEPLOY_HOST}}
|
||||||
|
username: frappet
|
||||||
|
password: ${{ secrets.SSH_PASSWORD }}
|
||||||
|
port: 10102
|
||||||
|
script: |
|
||||||
|
cd "${{env.COMPOSE_PATH}}"
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||||
|
- uses: snow-actions/line-notify@v1.1.0
|
||||||
|
if: success()
|
||||||
|
with:
|
||||||
|
access_token: ${{ secrets.TOKEN_LINE }}
|
||||||
|
message: |
|
||||||
|
-Success✅✅✅
|
||||||
|
Image: ${{env.IMAGE_NAME}}
|
||||||
|
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||||
|
By: ${{github.actor}}
|
||||||
|
- uses: snow-actions/line-notify@v1.1.0
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
access_token: ${{ secrets.TOKEN_LINE }}
|
||||||
|
message: |
|
||||||
|
-Failure❌❌❌
|
||||||
|
Image: ${{env.IMAGE_NAME}}
|
||||||
|
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||||
|
By: ${{github.actor}}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue