Compare commits

..

No commits in common. 'c8dc7a9507ff2592cc38bddefe4828c59314a74c' and '7bd4b58a0df174b4a8c26c34b9d388fc8ab3c4fd' have entirely different histories.

  1. 223
      package.json
  2. 1
      public/15/login-password.json
  3. 0
      public/15/name name/file.txt
  4. 0
      public/15/namename/file.txt
  5. BIN
      public/59/Papers-1(2).docx
  6. BIN
      public/60/LouiseHay-YouCanHealYourLife-HayHouse(1984).epub
  7. 45
      public/60/deeplearning_ex2.py
  8. 1
      public/60/login-password.json
  9. BIN
      public/9/c1a875_e21d978198ad4b9c85cf63a8d1b146cc_mv2 (1).jpeg
  10. BIN
      public/9/c1a875_e75b8c21992e4f749fed9f2bfec29872_mv2 (1).png
  11. BIN
      public/9/c1a875_e75b8c21992e4f749fed9f2bfec29872_mv2 (2).png
  12. BIN
      public/9/coinbanner.jpeg
  13. BIN
      public/9/test.docx
  14. BIN
      public/9/test1/test.docx
  15. BIN
      public/download/15/123353222-1684321000419.zip
  16. BIN
      public/download/15/123353222-1690800641686.zip
  17. BIN
      public/download/60/1233532-1691052065162.zip
  18. 230
      src/api/controllers/v1/image.controller.js
  19. 609
      src/api/controllers/v1/path.controller.js
  20. 377
      src/api/controllers/v1/user.controller.js
  21. 40
      src/api/middlewares/image.middleware.js
  22. 80
      src/api/routes/v1/image.route.js
  23. 105
      src/api/routes/v1/path.route.js
  24. 817
      src/common/models/config.model.js
  25. 554
      src/common/models/file.model.js
  26. 585
      src/common/models/image.model.js
  27. 2036
      src/common/models/user.model.js
  28. 127
      src/common/services/adapters/upload-adapter.js
  29. 30
      src/config/locales/en.json
  30. 80
      src/config/postgres.js
  31. 2495
      yarn.lock

@ -1,112 +1,111 @@
{ {
"name": "backend-image", "name": "backend-image",
"version": "1.0.0", "version": "1.0.0",
"description": "Service backend image", "description": "Service backend image",
"author": "Mạnh Tiến", "author": "Mạnh Tiến",
"main": "/src/index.js", "main": "/src/index.js",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=8", "node": ">=8",
"yarn": "*" "yarn": "*"
}, },
"nyc": { "nyc": {
"require": [ "require": [
"babel-register" "babel-register"
], ],
"sourceMap": false, "sourceMap": false,
"instrument": false "instrument": false
}, },
"scripts": { "scripts": {
"clean": "./node_modules/.bin/rimraf dist -p", "clean": "./node_modules/.bin/rimraf dist -p",
"build": "yarn run clean && mkdir -p dist && ./node_modules/.bin/babel src -s -D -d dist", "build": "yarn run clean && mkdir -p dist && ./node_modules/.bin/babel src -s -D -d dist",
"start": "cross-env NODE_ENV=production pm2 start ./dist/index.js", "start": "cross-env NODE_ENV=production pm2 start ./dist/index.js",
"start-worker": "cross-env NODE_ENV=production pm2 start docker-process.yml --only worker", "start-worker": "cross-env NODE_ENV=production pm2 start docker-process.yml --only worker",
"start-event-dispatcher": "cross-env NODE_ENV=production pm2 start docker-process.yml --only event-dispatcher", "start-event-dispatcher": "cross-env NODE_ENV=production pm2 start docker-process.yml --only event-dispatcher",
"dev": "nodemon src/index.js --exec ./node_modules/.bin/babel-node", "dev": "nodemon src/index.js --exec ./node_modules/.bin/babel-node",
"dev-worker": "nodemon src/index-worker.js --exec ./node_modules/.bin/babel-node", "dev-worker": "nodemon src/index-worker.js --exec ./node_modules/.bin/babel-node",
"dev-event-dispatcher": "nodemon src/index-event-dispatcher.js --exec ./node_modules/.bin/babel-node", "dev-event-dispatcher": "nodemon src/index-event-dispatcher.js --exec ./node_modules/.bin/babel-node",
"lint": "eslint **/*.js --ignore-path .gitignore --ignore-pattern internals/scripts", "lint": "eslint **/*.js --ignore-path .gitignore --ignore-pattern internals/scripts",
"lint:fix": "yarn lint -- --fix", "lint:fix": "yarn lint -- --fix",
"lint:watch": "yarn lint -- --watch", "lint:watch": "yarn lint -- --watch",
"test": "cross-env NODE_ENV=test nyc --reporter=html --reporter=text mocha --timeout 20000 --recursive src/api/tests", "test": "cross-env NODE_ENV=test nyc --reporter=html --reporter=text mocha --timeout 20000 --recursive src/api/tests",
"test:unit": "cross-env NODE_ENV=test mocha dist/api/tests/unit", "test:unit": "cross-env NODE_ENV=test mocha dist/api/tests/unit",
"test:integration": "cross-env NODE_ENV=test mocha --timeout 20000 dist/api/tests/integration", "test:integration": "cross-env NODE_ENV=test mocha --timeout 20000 dist/api/tests/integration",
"test:watch": "cross-env NODE_ENV=test mocha --watch dist/api/tests/unit", "test:watch": "cross-env NODE_ENV=test mocha --watch dist/api/tests/unit",
"coverage": "nyc report --reporter=text-lcov | coveralls", "coverage": "nyc report --reporter=text-lcov | coveralls",
"validate": "yarn lint && yarn test", "validate": "yarn lint && yarn test",
"postpublish": "git push --tags", "postpublish": "git push --tags",
"docker:start": "node ./dist/index.js --exec ./node_modules/.bin/babel-node", "docker:start": "node ./dist/index.js --exec ./node_modules/.bin/babel-node",
"docker:dev": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up", "docker:dev": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up",
"docker:test": "docker-compose -f docker-compose.yml -f docker-compose.test.yml up --abort-on-container-exit" "docker:test": "docker-compose -f docker-compose.yml -f docker-compose.test.yml up --abort-on-container-exit"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git@gitlab.com:csell-team/b2c/sv-backend-file.git" "url": "git@gitlab.com:csell-team/b2c/sv-backend-file.git"
}, },
"dependencies": { "dependencies": {
"@shopify/cli": "^3.45.4", "amqplib": "^0.5.2",
"amqplib": "^0.5.2", "archiver": "^5.3.1",
"archiver": "^5.3.1", "auth-adapter": "1.1.0",
"auth-adapter": "1.1.0", "axios": "^0.18.0",
"axios": "^0.18.0", "bcryptjs": "^2.4.3",
"bcryptjs": "^2.4.3", "bluebird": "^3.5.2",
"bluebird": "^3.5.2", "body-parser": "^1.17.0",
"body-parser": "^1.17.0", "bull": "^3.4.1",
"bull": "^3.4.1", "busboy": "^1.6.0",
"busboy": "^1.6.0", "compression": "^1.6.2",
"compression": "^1.6.2", "cors": "^2.8.3",
"cors": "^2.8.3", "cross-env": "^5.0.1",
"cross-env": "^5.0.1", "dotenv-safe": "^5.0.1",
"dotenv-safe": "^5.0.1", "exceljs": "^4.3.0",
"exceljs": "^4.3.0", "express": "^4.15.2",
"express": "^4.15.2", "express-validation": "^1.0.2",
"express-validation": "^1.0.2", "fs-extra": "^10.1.0",
"fs-extra": "^10.1.0", "helmet": "^3.5.0",
"helmet": "^3.5.0", "http-status": "^1.0.1",
"http-status": "^1.0.1", "i18n": "^0.8.3",
"i18n": "^0.8.3", "image-downloader": "^4.3.0",
"image-downloader": "^4.3.0", "ioredis": "^4.14.0",
"ioredis": "^4.14.0", "joi": "^10.4.1",
"joi": "^10.4.1", "jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^8.5.1", "jszip": "^3.10.1",
"jszip": "^3.10.1", "lodash": "^4.17.4",
"lodash": "^4.17.4", "method-override": "^2.3.8",
"method-override": "^2.3.8", "moment-timezone": "^0.5.13",
"moment-timezone": "^0.5.13", "mongoose": "^5.7.0",
"mongoose": "^5.7.0", "morgan": "^1.8.1",
"morgan": "^1.8.1", "multer": "^1.4.2",
"multer": "^1.4.2", "nanoid": "^2.0.3",
"nanoid": "^2.0.3", "pg": "^8.5.1",
"pg": "^8.5.1", "pg-hstore": "^2.3.3",
"pg-hstore": "^2.3.3", "pm2": "^2.4.6",
"pm2": "^2.4.6", "query-string": "^7.0.0",
"query-string": "^7.0.0", "rabbit-event-source": "1.0.0",
"rabbit-event-source": "1.0.0", "request": "^2.88.2",
"request": "^2.88.2", "sequelize": "^6.3.5",
"sequelize": "^6.3.5", "sharp": "^0.30.6",
"sharp": "^0.30.6", "uuid": "^9.0.0",
"uuid": "^9.0.0", "xlsx": "^0.16.9"
"xlsx": "^0.16.9" },
}, "devDependencies": {
"devDependencies": { "@types/archiver": "^5.3.2",
"@types/archiver": "^5.3.2", "babel-cli": "^6.26.0",
"babel-cli": "^6.26.0", "babel-plugin-istanbul": "^4.1.6",
"babel-plugin-istanbul": "^4.1.6", "babel-preset-env": "^1.6.1",
"babel-preset-env": "^1.6.1", "chai": "^4.1.0",
"chai": "^4.1.0", "chai-as-promised": "^7.1.1",
"chai-as-promised": "^7.1.1", "coveralls": "^3.0.0",
"coveralls": "^3.0.0", "eslint": "^4.2.0",
"eslint": "^4.2.0", "eslint-config-airbnb-base": "^12.0.1",
"eslint-config-airbnb-base": "^12.0.1", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-import": "^2.2.0", "husky": "^0.14.3",
"husky": "^0.14.3", "mocha": "^3.3.0",
"mocha": "^3.3.0", "nodemon": "^1.11.0",
"nodemon": "^1.11.0", "nyc": "^11.0.3",
"nyc": "^11.0.3", "rimraf": "^2.6.2",
"rimraf": "^2.6.2", "sinon": "^6.1.0",
"sinon": "^6.1.0", "sinon-chai": "^3.0.0",
"sinon-chai": "^3.0.0", "supertest": "^3.0.0"
"supertest": "^3.0.0" }
} }
}

@ -1 +0,0 @@
{"status":"error","message":"bad request"}

Binary file not shown.

@ -1,45 +0,0 @@
import torch
torch.manual_seed(2023)
def activation_func(x):
#TODO Implement one of these following activation function: sigmoid, tanh, ReLU, leaky ReLU
epsilon = 0.01 # Only use this variable if you choose Leaky ReLU
result = None
return result
def softmax(x):
# TODO Implement softmax function here
result = None
return result
# Define the size of each layer in the network
num_input = 784 # Number of node in input layer (28x28)
num_hidden_1 = 128 # Number of nodes in hidden layer 1
num_hidden_2 = 256 # Number of nodes in hidden layer 2
num_hidden_3 = 128 # Number of nodes in hidden layer 3
num_classes = 10 # Number of nodes in output layer
# Random input
input_data = torch.randn((1, num_input))
# Weights for inputs to hidden layer 1
W1 = torch.randn(num_input, num_hidden_1)
# Weights for hidden layer 1 to hidden layer 2
W2 = torch.randn(num_hidden_1, num_hidden_2)
# Weights for hidden layer 2 to hidden layer 3
W3 = torch.randn(num_hidden_2, num_hidden_3)
# Weights for hidden layer 3 to output layer
W4 = torch.randn(num_hidden_3, num_classes)
# and bias terms for hidden and output layers
B1 = torch.randn((1, num_hidden_1))
B2 = torch.randn((1, num_hidden_2))
B3 = torch.randn((1, num_hidden_3))
B4 = torch.randn((1, num_classes))
#TODO Calculate forward pass of the network here. Result should have the shape of [1,10]
# Dont forget to check if sum of result = 1.0
result = None
print(result)

@ -1 +0,0 @@
{"status":"error","message":"bad request"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Binary file not shown.

@ -1,130 +1,100 @@
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import { pick } from 'lodash';
import path from 'path'; import path from 'path';
import Busboy from 'busboy'; import Busboy from 'busboy';
import fs from 'fs-extra'; import fs from 'fs-extra';
import multer from 'multer'; import multer from 'multer';
import messages from '../../../config/messages'; import httpStatus from 'http-status';
import httpStatus from 'http-status'; // import moment from 'moment-timezone';
// import moment from 'moment-timezone'; import { handler as ErrorHandel } from '../../middlewares/errors';
import { handler as ErrorHandel } from '../../middlewares/errors'; import ApiException from '../../../common/utils/APIException';
import ApiException from '../../../common/utils/APIException'; // import eventBus from '../../../common/services/event-bus';
// import eventBus from '../../../common/services/event-bus'; // import Image from '../../../common/models/image.model';
import File from "../../../common/models/file.model"; import {
import { handler as ErrorHandler } from '../../middlewares/error'; cdn as cdnConfig,
// import Image from '../../../common/models/image.model'; storage as storageConfig
import { } from '../../../config/vars';
cdn as cdnConfig, /** storage will create folder when new date */
storage as storageConfig
} from '../../../config/vars';
/** storage will create folder when new date */ const filePath = `${storageConfig.uri}`;
const filePath = `${storageConfig.uri}`; const replaceBaseUrl = (location) =>
location.replace(storageConfig.uri, cdnConfig.uri);
const replaceBaseUrl = (location) =>
location.replace(storageConfig.uri, cdnConfig.uri); exports.uploadSingle = (req, res, next) => {
try {
if (!req.file) {
exports.uploadSingle = (req, res, next) => { throw new ApiException({
try { status: httpStatus.BAD_REQUEST,
if (!req.file) { message: 'Invalid file!'
throw new ApiException({ });
status: httpStatus.BAD_REQUEST, }
message: 'Invalid file!' /** resize image uploaded */
}); // eventBus.emit(Image.Events.IMAGE_CREATED, req.file);
} return res.json({ url: replaceBaseUrl(req.file.path) });
/** resize image uploaded */ } catch (ex) {
// eventBus.emit(Image.Events.IMAGE_CREATED, req.file); return ErrorHandel(ex, req, res, next);
// await File. }
return res.json({ url: replaceBaseUrl(req.file.path) }); };
} catch (ex) {
return ErrorHandel(ex, req, res, next); /**
} * Upload multiple
}; *
* @param {Formdata} file
/** */
* Upload multiple exports.uploadMultiple = (req, res, next) => {
* try {
* @param {Formdata} file if (!req.files) {
*/ throw new ApiException({
exports.uploadMultiple = (req, res, next) => { status: httpStatus.BAD_REQUEST,
try { message: 'Invalid file!'
// if (!req.files) { });
// throw new ApiException({ }
// status: httpStatus.BAD_REQUEST, const urls = [];
// message: 'Invalid file!' for (let index = 0; index < req.files.length; index += 1) {
// }); urls.push(replaceBaseUrl(req.files[index].path));
// } /** resize image uploaded */
const urls = []; // eventBus.emit(Image.Events.IMAGE_CREATED, req.files[index]);
const user = req.locals.user; }
let data = {} return res.json({ urls: urls });
} catch (ex) {
// const file = req.files; return ErrorHandel(ex, req, res, next);
}
};
for (let index = 0; index < req.files.length; index += 1) {
urls.push(replaceBaseUrl(req.files[index].path)); exports.uploadFile = (req, res, next) => {
data.url = replaceBaseUrl(req.files[index].path); try {
data.name = req.files[index].originalname; console.log(req.query);
data.created_by = pick(user, ['id', 'name']); let filename = null;
// File.create() const cfg = { highWaterMark: 1048576 * 2 }; // 20 mb
cfg.headers = req.headers;
/** resize image uploaded */ req.busboy = Busboy(cfg);
// eventBus.emit(Image.Events.IMAGE_CREATED, req.files[index]); const pathName = `${filePath}/${req.query.path}`;
File.create(data) multer({
.then(result => { dest: `${filePath}`,
res.json({ limits: {
code: 0, fileSize: 1024 * 1024 * 2048 // 2048MB
message: messages.UPLOAD_SUCCESS, }, });
}) req.pipe(req.busboy); // Pipe it trough busboy
return req.busboy.on('file', (name, file, info) => {
}).catch(err => { filename = info.filename;
ErrorHandler(err, req, res, next);
// Create a write stream of the new file
}) const fstream = fs.createWriteStream(path.join(pathName, filename));
} // Pipe it trough
// console.log(urls); file.pipe(fstream);
// return res.json({ urls: urls,data : data});
} catch (ex) { // On finish of the upload
console.log("error"); fstream.on('close', () => {
return ErrorHandel(ex, req, res, next); console.log(`Upload of '${filename}' finished`);
} return res.json({ url: replaceBaseUrl(`${pathName}/${filename}`) });
}; });
});
exports.uploadFile = (req, res, next) => { } catch (ex) {
try { return ErrorHandel(ex, req, res, next);
console.log(req.query); }
let filename = null; };
const cfg = { highWaterMark: 1048576 * 2 }; // 20 mb
cfg.headers = req.headers;
req.busboy = Busboy(cfg);
const pathName = `${filePath}/${req.query.path}`;
multer({
dest: `${filePath}`,
limits: {
fileSize: 1024 * 1024 * 2048 // 2048MB
}, });
req.pipe(req.busboy); // Pipe it trough busboy
return req.busboy.on('file', (name, file, info) => {
filename = info.filename;
// Create a write stream of the new file
const fstream = fs.createWriteStream(path.join(pathName, filename));
// Pipe it trough
file.pipe(fstream);
// On finish of the upload
fstream.on('close', () => {
console.log(`Upload of '${filename}' finished`);
return res.json({ url: replaceBaseUrl(`${pathName}/${filename}`) });
});
});
} catch (ex) {
return ErrorHandel(ex, req, res, next);
}
};

@ -1,360 +1,249 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
// import httpStatus from 'http-status'; // import httpStatus from 'http-status';
import fs from 'fs'; import fs from 'fs';
import archiver from 'archiver'; import archiver from 'archiver';
import multer from 'multer'; import { exec } from 'child_process';
import path from 'path'; import multer from 'multer';
import { handler as ErrorHandel } from '../../middlewares/errors'; import path from 'path';
import File from "../../../common/models/file.model"; import { cloneDeep } from 'lodash';
import { handler as ErrorHandler } from '../../middlewares/error'; import { handler as ErrorHandel } from '../../middlewares/errors';
import ApiException from '../../../common/utils/APIException'; // import ApiException from '../../../common/utils/APIException';
import { import {
cdn as cdnConfig, cdn as cdnConfig,
storage as storageConfig storage as storageConfig
} from '../../../config/vars'; } from '../../../config/vars';
import uploadAdapter from '../../../common/services/adapters/upload-adapter'; import uploadAdapter from '../../../common/services/adapters/upload-adapter';
import { cloneDeep, forEach } from 'lodash';
import APIError from '../../middlewares/ApiError'; function deleteFolderRecursive(folderPath) {
import { example } from 'joi'; if (fs.existsSync(folderPath)) {
import { where } from 'sequelize'; fs.readdirSync(folderPath).forEach((file) => {
import messages from '../../../config/messages'; const curPath = path.join(folderPath, file);
if (fs.lstatSync(curPath).isDirectory()) { // delete folder
function deleteFolderRecursive(folderPath) { deleteFolderRecursive(curPath); // recursively call deleteFolderRecursive function
if (fs.existsSync(folderPath)) { fs.rmdirSync(curPath);
fs.readdirSync(folderPath).forEach((file) => { } else { // delete file
const curPath = path.join(folderPath, file); fs.unlinkSync(curPath);
if (fs.lstatSync(curPath).isDirectory()) { // delete folder }
deleteFolderRecursive(curPath); // recursively call deleteFolderRecursive function });
fs.rmdirSync(curPath); }
} else { // delete file }
fs.unlinkSync(curPath); /**
} * get file and folder
}); *
} * @param {Formdata} file
} */
/** exports.get = (req, res, next) => {
* get file and folder try {
* const user = req.user;
* @param {Formdata} file
*/ let path = `${storageConfig.uri}/${user.id}`;
if (req.body.path) {
path += req.body.path;
}
exports.get = async (req, res, next) => { // console.log(path);
try { const listFile = [];
const user = req.user; fs.readdir(path, (err, files) => {
const user_infor = { if (files && files.length > 0) {
id: user.id, files.forEach((item) => {
name: user.name listFile.push({
}; name: item,
console.log(user_infor); path: `${cdnConfig.uri}/${user.id}${req.body.path}/${item}`,
let path = `${storageConfig.uri}/${user.id}`; isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory()
console.log(path); });
if (req.body.path) { });
path += req.body.path; }
} return res.json({
const listFile = []; code: 0,
// fs.readdir(path, (err, files) => { data: listFile
// if (files && files.length > 0) { });
// files.forEach((item) => { });
// listFile.push({ // test local
// name: item, // fs.readdir(path, (err, files) => {
// path: `${cdnConfig.uri}/${user.id}/${req.body.path}/${item}`, // if (files && files.length > 0) {
// isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory(), // files.forEach((item) => {
// }); // listFile.push({
// }); // name: item,
// } // path: `${storageConfig.uri}/${user.id}${req.body.path}/${item}`,
// return res.json({ // isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory()
// code: 0, // });
// data: listFile // });
// }); // }
// }); // return res.json({
// code: 0,
await File.findAll({ // data: listFile
where: { // });
is_active: true, // });
created_by : user_infor
}
}).then(result => { return null;
let path = [] /** resize image uploaded */
result.forEach(data => { } catch (ex) {
console.log(data.created_by.id); return ErrorHandel(ex, req, res, next);
// console.log(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`); }
const file = { };
name: data.name,
path: data.url, /**
// isFolder: fs.lstatSync(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`).isDirectory(), * get file and folder
isFolder: fs.lstatSync(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`).isDirectory(), *
download_count : data.download_count * @param {Formdata} file
*/
} exports.create = (req, res, next) => {
const user = req.user;
path.push(file); let dir = `${user.id}`;
}); const name_folder = cloneDeep(req.body.name).trim();
return res.json({ if (req.body.path) {
code: 0, dir += req.body.path;
data : path }
}) if (req.body.name) {
}).catch(ex => { dir += `/${name_folder}`;
ErrorHandler(ex, req, res, next); }
if (!fs.existsSync(dir)) {
}) uploadAdapter.createFolder({ path: dir });
}
return res.json({ code: 0, message: 'success' });
// test local };
// fs.readdir(path, (err, files) => {
// if (files && files.length > 0) { /**
// files.forEach((item) => { * get file and folder
// listFile.push({ *
// name: item, * @param {Formdata} file
// path: `${cdnConfig.uri}/${user.id}${req.body.path}/${item}`, */
exports.update = (req, res, next) => {
// path: `${storageConfig.uri}/${user.id}${req.body.path}/${item}`, try {
// isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory() const oldPath = req.body.oldPath.replace(cdnConfig.uri, storageConfig.uri);
// }); const newPath = req.body.newPath.replace(cdnConfig.uri, storageConfig.uri);
// });
// } fs.rename(oldPath, newPath, (err) => {
// return res.json({ if (err) {
// code: 0, console.log(err);
// data: listFile return res.status(400).json({ code: 400, message: 'lỗi' });
// }); }
// }); return res.json({ code: 0, message: 'success' });
});
return null;
return null; } catch (ex) {
/** resize image uploaded */ return ErrorHandel(ex, req, res, next);
} catch (ex) { }
return ErrorHandel(ex, req, res, next); };
}
};
exports.delete = (req, res, next) => {
/** try {
* get file and folder const user = req.user;
* const dir = `${storageConfig.uri_backup}/${user.id}`;
* @param {Formdata} file multer({ dest: `${dir}` });
*/ const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
exports.create = (req, res, next) => { const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
const user = req.user; // fs.rm(path, { recursive: true }, err => {
let dir = `${user.id}`; // if (err) {
const name_folder = cloneDeep(req.body.name).trim(); // return res.status(400).json({ code: 400, message: 'lỗi', detail: err });
if (req.body.path) { // }
dir += req.body.path; // return res.json({ code: 0, message: 'success' });
} // });
if (req.body.name) { fs.rename(path, newpath, (err) => {
dir += `/${name_folder}`; if (err) throw err;
} return res.json({ code: 0, message: 'success' });
if (!fs.existsSync(dir)) { });
uploadAdapter.createFolder({ path: dir }); return null;
} } catch (ex) {
return res.json({ code: 0, message: 'success' }); return ErrorHandel(ex, req, res, next);
}; }
};
/** exports.download = async (req, res, next) => {
* get file and folder try {
* const user = req.user;
* @param {Formdata} file const namefile = `${user.name.replace(/\s/g, '')}-${Date.now()}.zip`;
*/ const dir = `${storageConfig.uri}/download/${user.id}/${namefile}`;
exports.update = (req, res, next) => { const folder = `${storageConfig.uri}/download/${user.id}`;
try { multer({ dest: `${folder}` });
const oldPath = req.body.oldPath.replace(cdnConfig.uri, storageConfig.uri); await deleteFolderRecursive(folder);
const newPath = req.body.newPath.replace(cdnConfig.uri, storageConfig.uri); let command = ` zip -r ${dir} `;
fs.rename(oldPath, newPath, (err) => { // const output = fs.createWriteStream(dir);
if (err) { // const archive = archiver('zip', {
console.log(err); // zlib: { level: 9 } // Sets the compression level.
return res.status(400).json({ code: 400, message: 'lỗi' }); // });
}
return res.json({ code: 0, message: 'success' });
}); // archive.pipe(output);
return null; if (req.body.data) {
} catch (ex) { req.body.data.forEach((e) => {
return ErrorHandel(ex, req, res, next); const path1 = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ ');
}
}; command += `${path1} `;
});
}
exports.delete = (req, res, next) => { console.log(command);
try {
const user = req.user;
const dir = `${storageConfig.uri_backup}/${user.id}`; exec(command, (error, stdout, stderr) => {
multer({ dest: `${dir}` }); if (error) {
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri); console.error(`Command execution error: ${error.message}`);
const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup); return res.status(400).json({
// fs.rm(path, { recursive: true }, err => { code: 400,
// if (err) { message: 'error'
// return res.status(400).json({ code: 400, message: 'lỗi', detail: err }); });
// } }
// return res.json({ code: 0, message: 'success' }); if (stderr) {
// }); console.error(`Command stderr: ${stderr}`);
fs.rename(path, newpath, (err) => { return res.status(400).json({
if (err) throw err; code: 400,
return res.json({ code: 0, message: 'success' }); message: 'error'
}); });
return null; }
} catch (ex) { console.log(`Command output: ${stdout}`);
return ErrorHandel(ex, req, res, next); return res.json({
} code: 0,
}; data: {
exports.download = async (req, res, next) => { name: namefile,
try { path: `${cdnConfig.uri}/download/${user.id}/${namefile}`,
}
const user = req.user; });
const namefile = `${user.name}-${Date.now()}.zip`; });
const dir = `${storageConfig.uri}/download/${user.id}/${namefile}`; } catch (ex) {
const folder = `${storageConfig.uri}/download/${user.id}`; return ErrorHandel(ex, req, res, next);
multer({ dest: `${folder}` }); }
await deleteFolderRecursive(folder); };
const output = fs.createWriteStream(dir);
const archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level. exports.forceDelete = (req, res, next) => {
}); try {
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
const user_infor = { // const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
id: user.id, fs.rm(path, { recursive: true }, err => {
name: user.name if (err) {
} return res.status(400).json({ code: 400, message: 'lỗi', detail: err });
archive.pipe(output); }
if (req.body.data) { return res.json({ code: 0, message: 'success' });
req.body.data.forEach( async (e) => { });
// const path = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ ');
// // // const path = e.path.replace(cdnConfig.uri, storageConfig.uri); return null;
// console.log('path: ', path); } catch (ex) {
let downnload_count_list = new Map(); return ErrorHandel(ex, req, res, next);
}
await File.findOne({ };
where: {
name: e.name, exports.deleteMultiple = (req, res, next) => {
url : e.path, try {
created_by: user_infor, const user = req.user;
is_active : true const dir = `${storageConfig.uri_backup}/${user.id}/${Date.now()}`;
} multer({ dest: `${dir}` });
}).then(result => { if (req.body.data) {
// plus one to the download count when download each selected file req.body.data.forEach((e) => {
downnload_count_list.set( result.id,result.download_count + 1); const path = e.path.replace(cdnConfig.uri, storageConfig.uri);
let newpath = e.path.replace(cdnConfig.uri, storageConfig.uri_backup);
const storage = result.url.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ '); const split = newpath.split('/');
if (e.isFolder) { newpath = `${dir}/${split[split.length - 1]}`;
archive.directory(storage, e.name); fs.rename(path, newpath, (err) => {
} else { if (err) throw err;
archive.file(storage, { name: e.name }); return { code: 0, message: 'success' };
} });
archive.finalize(); });
next() }
return res.json({ code: 0, message: 'success' });
}).catch(ex => { } catch (ex) {
console.log(ex); return ErrorHandel(ex, req, res, next);
next() }
};
// ErrorHandel(ex, req, res, next);
});
downnload_count_list.forEach(async (value,key) => {
const new_download_count_value = {download_count : value};
await File.update(
new_download_count_value, {
where : {
id : key,
is_active: true
}
}
).then(result => {
console.log("download count add success");
next()
}).catch(ex => {
console.log("error2");
next()
// ErrorHandel(ex, req, res, next);
})
})
});
}
return res.json({
code: 0,
data: {
name: namefile,
path: `${cdnConfig.uri}/download/${user.id}/${namefile}`
}
});
} catch (ex) {
return ErrorHandel(ex, req, res, next);
}
};
exports.forceDelete = (req, res, next) => {
try {
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
// const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
fs.rm(path, { recursive: true }, err => {
if (err) {
return res.status(400).json({ code: 400, message: 'lỗi', detail: err });
}
return res.json({ code: 0, message: 'success' });
});
return null;
} catch (ex) {
return ErrorHandel(ex, req, res, next);
}
};
exports.deleteMultiple = (req, res, next) => {
try {
// const dir = `${storageConfig.uri_backup}/${user.id}/${Date.now()}`;
// multer({ dest: `${dir}` });
if (req.body.data) {
req.body.data.forEach(async (e) => {
// const path = e.path.replace(cdnConfig.uri, storageConfig.uri);
// let newpath = e.path.replace(cdnConfig.uri, storageConfig.uri_backup);
// const split = newpath.split('/');
// newpath = `${dir}/${split[split.length - 1]}`;
// fs.rename(path, newpath, (err) => {
// if (err) throw err;
// return { code: 0, message: 'success' };
// });
console.log(e.path);
const user = req.user;
const user_infor = {
id: user.id,
name: user.name
}
const data = {is_active : false}
await File.update(
data,
{
where: {
name: e.name,
created_by: user_infor,
url : e.path
}
}
).then(result => {
console.log("success");
}).catch(ex => {
console.log(ex);
})
// console.log(e);
});
}
return res.json({ code: 0, message: messages.REMOVE_SUCCESS });
} catch (ex) {
return ErrorHandel(ex, req, res, next);
}
};

@ -1,190 +1,189 @@
import { hash } from 'bcryptjs'; import { hash } from 'bcryptjs';
import { pick } from 'lodash'; import { pick } from 'lodash';
// import httpStatus from 'http-status'; // import httpStatus from 'http-status';
import messages from '../../../config/messages'; import messages from '../../../config/messages';
// import { hash, compare } from 'bcryptjs'; // import { hash, compare } from 'bcryptjs';
import { handler as ErrorHandler } from '../../middlewares/error'; import { handler as ErrorHandler } from '../../middlewares/error';
import User from '../../../common/models/user.model'; import User from '../../../common/models/user.model';
import uploadAdapter from '../../../common/services/adapters/upload-adapter'; import uploadAdapter from '../../../common/services/adapters/upload-adapter';
/** /**
* Create * Create
* *
* @public * @public
* @param {StorySchema} body * @param {StorySchema} body
* @returns {Promise<StorySchema>, APIException>} * @returns {Promise<StorySchema>, APIException>}
*/ */
exports.create = async (req, res, next) => { exports.create = async (req, res, next) => {
// transform data // transform data
req.body.created_by = pick(req.user, ['id', 'name']); req.body.created_by = pick(req.user, ['id', 'name']);
const params = req.body; const params = req.body;
params.type = User.Types.INDIVIDUAL; params.type = User.Types.INDIVIDUAL;
params.service = User.Services.INDIVIDUAL; params.service = User.Services.INDIVIDUAL;
// save data // save data
console.log(req.body); await User.create(req.body)
await User.create(req.body) .then(data => {
.then(data => { uploadAdapter.createDefaultFolder({ id: data.id });
uploadAdapter.createDefaultFolder({ id: data.id }); res.json({
res.json({ code: 0,
code: 0, message: messages.CREATE_SUCCESS,
message: messages.CREATE_SUCCESS, data: User.transform(data)
data: User.transform(data) });
}); }).catch(ex => {
}).catch(ex => { ErrorHandler(ex, req, res, next);
ErrorHandler(ex, req, res, next); });
}); };
};
/**
/** * List
* List *
* * @public
* @public * @param {StorySchema} query
* @param {StorySchema} query * @returns {Promise<StorySchema[]>, APIException>}
* @returns {Promise<StorySchema[]>, APIException>} */
*/ exports.list = async (req, res, next) => {
exports.list = async (req, res, next) => { req.query.services = User.Services.USER;
req.query.services = User.Services.USER; // console.log(req.query.services);
// console.log(req.query.services); // User.list( {
// User.list( { // service : "user",
// service : "user", // is_active: true
// is_active: true // }
// } // ).then(result => {
// ).then(result => { // res.json({
// res.json({ // code: 0,
// code: 0, // count: req.totalRecords,
// count: req.totalRecords, // data: result.map(
// data: result.map( // x => User.transform(x)
// x => User.transform(x) // )
// ) // });
// }); // }).catch(ex => {
// }).catch(ex => { // ErrorHandler(ex, req, res, next);
// ErrorHandler(ex, req, res, next); // });
// });
return User.findAll({
return User.findAll({ where : {
where : { service : "user",
service : "user", is_active: true
is_active: true }
} }).then(result => {
}).then(result => { res.json({
res.json({ code: 0,
code: 0, count: req.totalRecords,
count: req.totalRecords, data: result.map(
data: result.map( x => User.transform(x)
x => User.transform(x) )
) });
}); }).catch(ex => {
}).catch(ex => { ErrorHandler(ex, req, res, next);
ErrorHandler(ex, req, res, next); });
}); };
};
/**
/** * Detail
* Detail *
* * @public
* @public * @param {params} userId,
* @param {params} userId, * @returns {Promise<StorySchema>, APIException>}
* @returns {Promise<StorySchema>, APIException>} */
*/ exports.get = async (req, res, next) => res.json({ data: User.transform(req.locals.user) });
exports.get = async (req, res, next) => res.json({ data: User.transform(req.locals.user) });
/**
/** * Update
* Update *
* * @public
* @public * @param {params} userId
* @param {params} userId * @returns {Promise<any>, APIException>}
* @returns {Promise<any>, APIException>} */
*/ exports.update = async (req, res, next) => {
exports.update = async (req, res, next) => { const { user } = req.locals;
const { user } = req.locals; const dataChanged = User.getChangedProperties(req.body);
const dataChanged = User.getChangedProperties(req.body); const new_properties = pick(req.body, dataChanged);
const new_properties = pick(req.body, dataChanged); // const updateUser = Object.assign(
// const updateUser = Object.assign( // user,
// user, // pick(req.body, dataChanged)
// pick(req.body, dataChanged) // );
// );
// const currentUser = await User.get(user.id)
// const currentUser = await User.get(user.id) // console.log(dataChanged);
// console.log(dataChanged);
return User.update(
return User.update( new_properties,
new_properties, {
{ where: {
where: { id: user.id
id: user.id }
} }
} ).then(() => {
).then(() => { res.json({
res.json({ code: 0,
code: 0, message: messages.UPDATE_SUCCESS,
message: messages.UPDATE_SUCCESS, // dataChanged: dataChanged
// dataChanged: dataChanged });
}); }).catch(ex => {
}).catch(ex => { ErrorHandler(ex, req, res, next);
ErrorHandler(ex, req, res, next); });
}); };
};
/**
/** * delete
* delete *
* * @public
* @public * @param {params} userId
* @param {params} userId * @returns {Promise<any>, APIException>}
* @returns {Promise<any>, APIException>} */
*/ exports.delete = async (req, res, next) => {
exports.delete = async (req, res, next) => { const { user } = req.locals;
const { user } = req.locals; // const new_user = Object.assign(
// const new_user = Object.assign( // user,
// user, // isactive : false
// isactive : false // )
// )
return User.update(
return User.update( { is_active: false},
{ is_active: false}, {
{ where: {
where: { id: user.id
id: user.id }
} }
} ).then( () => {
).then( () => { res.json({
res.json({ code: 0,
code: 0, message: messages.REMOVE_SUCCESS
message: messages.REMOVE_SUCCESS });
}); }).catch(ex => {
}).catch(ex => { ErrorHandler(ex, req, res, next);
ErrorHandler(ex, req, res, next); });
}); };
};
exports.getStaffPermission = async (req, res, next) => {
exports.getStaffPermission = async (req, res, next) => { const { story } = req.locals;
const { story } = req.locals; return res.json({
return res.json({ code: 0,
code: 0, data: story
data: story });
}); };
}; exports.updatePassword = async(req,res,next) => {
exports.updatePassword = async(req,res,next) => { const {new_password} = req.body;
const {new_password} = req.body; const {user} = req.locals;
const {user} = req.locals; // console.log(user);
// console.log(user); if (user) {
if (user) { const rounds = 10;
const rounds = 10; const new_pass = await hash(new_password, rounds);
const new_pass = await hash(new_password, rounds); return User.update(
return User.update( {password: new_pass},
{password: new_pass}, {
{ where: {
where: { id: user.id
id: user.id }
} },
}, ).then( async () => {
).then( async () => { res.json({
res.json({ code: 0,
code: 0, message: messages.UPDATE_SUCCESS
message: messages.UPDATE_SUCCESS });
}); }).catch(ex => {
}).catch(ex => { ErrorHandler(ex, req, res, next);
ErrorHandler(ex, req, res, next); });
}); };
};
}; };

@ -1,23 +1,17 @@
import { handler as ErrorHandler } from './errors'; import { handler as ErrorHandler } from './errors';
import Image from '../../common/models/image.model'; import Image from '../../common/models/image.model';
/** /**
* Load image and append to req. * Load image and append to req.
* @public * @public
*/ */
exports.load = async (req, res, next) => { exports.load = async (req, res, next) => {
try { try {
const image = await Image.getImageById(req.params.id); const image = await Image.getImageById(req.params.id);
req.locals = req.locals ? req.locals : {}; req.locals = req.locals ? req.locals : {};
req.locals.image = image; req.locals.image = image;
return next(); return next();
} catch (error) { } catch (error) {
return ErrorHandler(error, req, res); return ErrorHandler(error, req, res);
} }
}; };
// check wheather user has upload any file
exports.checkExist = async(req,res,next) => {
}

@ -1,42 +1,38 @@
import express from 'express'; import express from 'express';
// import validate from 'express-validation'; // import validate from 'express-validation';
import { authorize } from '../../middlewares/auth.middleware'; import { authorize } from '../../middlewares/auth.middleware';
import Permissions from '../../../common/utils/Permissions'; import Permissions from '../../../common/utils/Permissions';
import userMiddleware from '../../middlewares/user.middleware';
import { uploader } from '../../../common/services/adapters/upload-adapter';
import { uploader } from '../../../common/services/adapters/upload-adapter'; import controller from '../../controllers/v1/image.controller';
import controller from '../../controllers/v1/image.controller'; // import {
// import { // uploadValidation
// uploadValidation // } from '../../validations/v1/image.validation';
// } from '../../validations/v1/image.validation';
const router = express.Router();
const router = express.Router();
router
router .route('/upload-single')
.route('/upload-single') .post(
.post( // authorize([Permissions.IMAGE_UPLOAD]),
// authorize([Permissions.IMAGE_UPLOAD]), // validate(uploadValidation),
// validate(uploadValidation), uploader.single('file'),
uploader.single('file'), controller.uploadSingle
controller.uploadSingle );
);
router
router .route('/upload-multiple')
.route('/upload-multiple/:id') .post(
.post( // authorize([Permissions.IMAGE_UPLOAD]),
// authorize([Permissions.IMAGE_UPLOAD]), // validate(uploadValidation),
// validate(uploadValidation), uploader.array('file', 100),
userMiddleware.load, controller.uploadMultiple
uploader.array('file', 100), );
controller.uploadMultiple router
); .route('/upload-file')
router .post(
.route('/upload-file') // authorize([Permissions.IMAGE_UPLOAD]),
.post( controller.uploadFile
// authorize([Permissions.IMAGE_UPLOAD]), );
controller.uploadFile
); export default router;
export default router;

@ -1,54 +1,51 @@
import express from 'express'; import express from 'express';
import { authorize } from '../../middlewares/auth.middleware'; import { authorize } from '../../middlewares/auth.middleware';
import controller from '../../controllers/v1/path.controller'; import controller from '../../controllers/v1/path.controller';
import Permissions from '../../../common/utils/Permissions'; import Permissions from '../../../common/utils/Permissions';
const router = express.Router(); const router = express.Router();
router router
.route('/') .route('/')
.post( .post(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.get controller.get
); );
router router
.route('/create') .route('/create')
.post( .post(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.create controller.create
); );
router router
.route('/update') .route('/update')
.put( .put(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.update controller.update
); );
router router
.route('/delete') .route('/delete')
.patch( .patch(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.delete controller.delete
); );
router router
.route('/download') .route('/download')
.put( .put(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.download controller.download
); );
router router
.route('/force-delete') .route('/force-delete')
.patch( .patch(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.forceDelete controller.forceDelete
); );
router router
.route('/delete-multiple') .route('/delete-multiple')
.patch( .patch(
authorize([Permissions.USER]), authorize([Permissions.USER]),
controller.deleteMultiple controller.deleteMultiple
); );
export default router;
export default router;

@ -1,409 +1,408 @@
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import httpStatus from 'http-status'; import httpStatus from 'http-status';
import { Model, DataTypes, Op } from 'sequelize'; import { Model, DataTypes, Op } from 'sequelize';
import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash'; import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { serviceName } from '../../config/vars'; import { serviceName } from '../../config/vars';
import postgres from '../../config/postgres'; import postgres from '../../config/postgres';
import APIError from '../utils/APIException'; import APIError from '../utils/APIException';
/** /**
* Create connection * Create connection
*/ */
const { sequelize } = postgres; const { sequelize } = postgres;
class FileConfig extends Model { } class FileConfig extends Model { }
const PUBLIC_FIELDS = [ const PUBLIC_FIELDS = [
'name', 'name',
'type', 'type',
'group', 'group',
'config' 'config'
]; ];
FileConfig.Groups = { FileConfig.Groups = {
PRODUCT: 'product', PRODUCT: 'product',
PRODUCT_OPTION: 'product-option', PRODUCT_OPTION: 'product-option',
PRODUCT_PRICE: 'product-price', PRODUCT_PRICE: 'product-price',
ORDER: 'order', ORDER: 'order',
ORDER_NESTED: 'order-nested', ORDER_NESTED: 'order-nested',
INVOICE: 'invoice', INVOICE: 'invoice',
INVOICE_NESTED: 'invoice-nested', INVOICE_NESTED: 'invoice-nested',
RETURN: 'return', RETURN: 'return',
RETURN_NESTED: 'return-nested', RETURN_NESTED: 'return-nested',
DELIVERY: 'delivery', DELIVERY: 'delivery',
IMPORT: 'import', IMPORT: 'import',
IMPORT_NESTED: 'import-nested', IMPORT_NESTED: 'import-nested',
STOCK_TAKE: 'stock-take', STOCK_TAKE: 'stock-take',
STOCK_TAKE_NESTED: 'stock-take-nested', STOCK_TAKE_NESTED: 'stock-take-nested',
TRANSFER: 'transfer', TRANSFER: 'transfer',
TRANSFER_NESTED: 'transfer-nested', TRANSFER_NESTED: 'transfer-nested',
EXPORT: 'export', EXPORT: 'export',
EXPORT_NESTED: 'export-nested', EXPORT_NESTED: 'export-nested',
PAYMENT: 'payment', PAYMENT: 'payment',
CUSTOMER: 'customer', CUSTOMER: 'customer',
SUPPLIER: 'supplier', SUPPLIER: 'supplier',
DELIVERY_PAYMENT: 'delivery-payment', DELIVERY_PAYMENT: 'delivery-payment',
DELIVERY_PAYMENT_NESTED: 'delivery-payment-nested', DELIVERY_PAYMENT_NESTED: 'delivery-payment-nested',
/** Sale Report */ /** Sale Report */
SALE_REPORT_TIME: 'sale-report-time', SALE_REPORT_TIME: 'sale-report-time',
SALE_REPORT_TIME_NESTED: 'sale-report-time-nested', SALE_REPORT_TIME_NESTED: 'sale-report-time-nested',
SALE_REPORT_TIME_INVOICE: 'sale-report-time-invoice', SALE_REPORT_TIME_INVOICE: 'sale-report-time-invoice',
SALE_REPORT_PROFIT: 'sale-report-profit', SALE_REPORT_PROFIT: 'sale-report-profit',
SALE_REPORT_PROFIT_NESTED: 'sale-report-profit-nested', SALE_REPORT_PROFIT_NESTED: 'sale-report-profit-nested',
SALE_REPORT_PROFIT_INVOICE: 'sale-report-profit-invoice', SALE_REPORT_PROFIT_INVOICE: 'sale-report-profit-invoice',
SALE_REPORT_PROFIT_PRODUCT: 'sale-report-profit-product', SALE_REPORT_PROFIT_PRODUCT: 'sale-report-profit-product',
SALE_REPORT_DISCOUNT: 'sale-report-discount', SALE_REPORT_DISCOUNT: 'sale-report-discount',
SALE_REPORT_DISCOUNT_NESTED: 'sale-report-discount-nested', SALE_REPORT_DISCOUNT_NESTED: 'sale-report-discount-nested',
SALE_REPORT_DISCOUNT_INVOICE: 'sale-report-discount-invoice', SALE_REPORT_DISCOUNT_INVOICE: 'sale-report-discount-invoice',
SALE_REPORT_RETURN: 'sale-report-return', SALE_REPORT_RETURN: 'sale-report-return',
SALE_REPORT_RETURN_NESTED: 'sale-report-return-nested', SALE_REPORT_RETURN_NESTED: 'sale-report-return-nested',
SALE_REPORT_RETURN_INVOICE: 'sale-report-return-invoice', SALE_REPORT_RETURN_INVOICE: 'sale-report-return-invoice',
SALE_REPORT_STAFF: 'sale-report-staff', SALE_REPORT_STAFF: 'sale-report-staff',
SALE_REPORT_STAFF_NESTED: 'sale-report-staff-nested', SALE_REPORT_STAFF_NESTED: 'sale-report-staff-nested',
SALE_REPORT_STAFF_TIME: 'sale-report-staff-time', SALE_REPORT_STAFF_TIME: 'sale-report-staff-time',
SALE_REPORT_STAFF_TIME_NESTED: 'sale-report-staff-time-nested', SALE_REPORT_STAFF_TIME_NESTED: 'sale-report-staff-time-nested',
SALE_REPORT_STAFF_INVOICE: 'sale-report-staff-invoice', SALE_REPORT_STAFF_INVOICE: 'sale-report-staff-invoice',
SALE_REPORT_STORE: 'sale-report-store', SALE_REPORT_STORE: 'sale-report-store',
SALE_REPORT_STORE_NESTED: 'sale-report-store-nested', SALE_REPORT_STORE_NESTED: 'sale-report-store-nested',
SALE_REPORT_STORE_TIME: 'sale-report-store-time', SALE_REPORT_STORE_TIME: 'sale-report-store-time',
SALE_REPORT_STORE_TIME_NESTED: 'sale-report-store-time-nested', SALE_REPORT_STORE_TIME_NESTED: 'sale-report-store-time-nested',
SALE_REPORT_STORE_INVOICE: 'sale-report-store-invoice', SALE_REPORT_STORE_INVOICE: 'sale-report-store-invoice',
/** product report */ /** product report */
PRODUCT_REPORT_SALE: 'product-report-sale', PRODUCT_REPORT_SALE: 'product-report-sale',
PRODUCT_REPORT_SALE_SPECIFIC: 'product-report-sale-specific', PRODUCT_REPORT_SALE_SPECIFIC: 'product-report-sale-specific',
PRODUCT_REPORT_SALE_GROUP_CATEGORIES: 'product-report-sale-group-categories', PRODUCT_REPORT_SALE_GROUP_CATEGORIES: 'product-report-sale-group-categories',
PRODUCT_REPORT_SALE_DETAIL: 'product-report-sale-detail', PRODUCT_REPORT_SALE_DETAIL: 'product-report-sale-detail',
PRODUCT_REPORT_PROFIT: 'product-report-profit', PRODUCT_REPORT_PROFIT: 'product-report-profit',
PRODUCT_REPORT_PROFIT_GROUP_CATEGORIES: 'product-report-profit-group-categories', PRODUCT_REPORT_PROFIT_GROUP_CATEGORIES: 'product-report-profit-group-categories',
PRODUCT_REPORT_STOCK_VALUE: 'product-report-stock-value', PRODUCT_REPORT_STOCK_VALUE: 'product-report-stock-value',
PRODUCT_REPORT_STOCK_VALUE_GROUP_CATEGORIES: 'product-report-stock-value-group-categories', PRODUCT_REPORT_STOCK_VALUE_GROUP_CATEGORIES: 'product-report-stock-value-group-categories',
PRODUCT_REPORT_STOCK_VALUE_DETAIL: 'product-report-stock-value-detail', PRODUCT_REPORT_STOCK_VALUE_DETAIL: 'product-report-stock-value-detail',
PRODUCT_REPORT_STOCK_VALUE_STORE: 'product-report-stock-value-store', PRODUCT_REPORT_STOCK_VALUE_STORE: 'product-report-stock-value-store',
PRODUCT_REPORT_STOCK_VALUE_GENERAL: 'product-report-stock-value-general', PRODUCT_REPORT_STOCK_VALUE_GENERAL: 'product-report-stock-value-general',
PRODUCT_REPORT_STOCK: 'product-report-stock', PRODUCT_REPORT_STOCK: 'product-report-stock',
PRODUCT_REPORT_STOCK_STORE: 'product-report-stock-store', PRODUCT_REPORT_STOCK_STORE: 'product-report-stock-store',
PRODUCT_REPORT_STOCK_ONE_STORE: 'product-report-stock-one-store', PRODUCT_REPORT_STOCK_ONE_STORE: 'product-report-stock-one-store',
PRODUCT_REPORT_STOCK_GROUP_CATEGORIES: 'product-report-stock-group-categories', PRODUCT_REPORT_STOCK_GROUP_CATEGORIES: 'product-report-stock-group-categories',
PRODUCT_REPORT_STOCK_MORE_STORE: 'product-report-stock-more-store', PRODUCT_REPORT_STOCK_MORE_STORE: 'product-report-stock-more-store',
PRODUCT_REPORT_STOCK_DETAIL: 'product-report-stock-detail', PRODUCT_REPORT_STOCK_DETAIL: 'product-report-stock-detail',
PRODUCT_REPORT_STOCK_DETAIL_STORE: 'product-report-stock-detail-store', PRODUCT_REPORT_STOCK_DETAIL_STORE: 'product-report-stock-detail-store',
PRODUCT_REPORT_STOCK_DETAIL_DETAIL: 'product-report-stock-detail-detail', PRODUCT_REPORT_STOCK_DETAIL_DETAIL: 'product-report-stock-detail-detail',
PRODUCT_REPORT_STOCK_DETAIL_GROUP_CATEGORIES: 'product-report-stock-detail-group-categories', PRODUCT_REPORT_STOCK_DETAIL_GROUP_CATEGORIES: 'product-report-stock-detail-group-categories',
PRODUCT_REPORT_STOCK_DETAIL_GENERAL: 'product-report-stock-detail-general', PRODUCT_REPORT_STOCK_DETAIL_GENERAL: 'product-report-stock-detail-general',
PRODUCT_REPORT_STAFF: 'product-report-staff', PRODUCT_REPORT_STAFF: 'product-report-staff',
PRODUCT_REPORT_STAFF_SPECIFIC: 'product-report-staff-specific', PRODUCT_REPORT_STAFF_SPECIFIC: 'product-report-staff-specific',
PRODUCT_REPORT_STAFF_DETAIL: 'product-report-staff-detail', PRODUCT_REPORT_STAFF_DETAIL: 'product-report-staff-detail',
PRODUCT_REPORT_STAFF_GROUP_CATEGORIES: 'product-report-staff-group-categories', PRODUCT_REPORT_STAFF_GROUP_CATEGORIES: 'product-report-staff-group-categories',
PRODUCT_REPORT_EXPORT: 'product-report-export', PRODUCT_REPORT_EXPORT: 'product-report-export',
PRODUCT_REPORT_EXPORT_SPECIFIC: 'product-report-export-specific', PRODUCT_REPORT_EXPORT_SPECIFIC: 'product-report-export-specific',
PRODUCT_REPORT_EXPORT_DETAIL: 'product-report-export-detail', PRODUCT_REPORT_EXPORT_DETAIL: 'product-report-export-detail',
PRODUCT_REPORT_EXPORT_GROUP_CATEGORIES: 'product-report-export-group-categories', PRODUCT_REPORT_EXPORT_GROUP_CATEGORIES: 'product-report-export-group-categories',
PRODUCT_REPORT_CUSTOMER: 'product-report-customer', PRODUCT_REPORT_CUSTOMER: 'product-report-customer',
PRODUCT_REPORT_CUSTOMER_SPECIFIC: 'product-report-customer-specific', PRODUCT_REPORT_CUSTOMER_SPECIFIC: 'product-report-customer-specific',
PRODUCT_REPORT_CUSTOMER_DETAIL: 'product-report-customer-detail', PRODUCT_REPORT_CUSTOMER_DETAIL: 'product-report-customer-detail',
PRODUCT_REPORT_CUSTOMER_GROUP_CATEGORIES: 'product-report-customer-group-categories', PRODUCT_REPORT_CUSTOMER_GROUP_CATEGORIES: 'product-report-customer-group-categories',
PRODUCT_REPORT_SUPPLIER: 'product-report-supplier', PRODUCT_REPORT_SUPPLIER: 'product-report-supplier',
PRODUCT_REPORT_SUPPLIER_DETAIL: 'product-report-supplier-detail', PRODUCT_REPORT_SUPPLIER_DETAIL: 'product-report-supplier-detail',
PRODUCT_REPORT_SUPPLIER_SPECIFIC: 'product-report-supplier-specific', PRODUCT_REPORT_SUPPLIER_SPECIFIC: 'product-report-supplier-specific',
PRODUCT_REPORT_SUPPLIER_GROUP_CATEGORIES: 'product-report-supplier-group-categories', PRODUCT_REPORT_SUPPLIER_GROUP_CATEGORIES: 'product-report-supplier-group-categories',
PRODUCT_REPORT_STOCK_SPECIFIC: 'product-report-stock-specific', PRODUCT_REPORT_STOCK_SPECIFIC: 'product-report-stock-specific',
PRODUCT_REPORT_STOCK_DETAIL_SPECIFIC: 'product-report-stock-detail-specific', PRODUCT_REPORT_STOCK_DETAIL_SPECIFIC: 'product-report-stock-detail-specific',
PRODUCT_REPORT_CUSTOMER_INVOICE: 'product-report-customer-invoice', PRODUCT_REPORT_CUSTOMER_INVOICE: 'product-report-customer-invoice',
PRODUCT_REPORT_STAFF_INVOICE: 'product-report-staff-invoice', PRODUCT_REPORT_STAFF_INVOICE: 'product-report-staff-invoice',
/** start end of day report */ /** start end of day report */
END_OF_DAY_REPORT_SALE: 'end-of-day-report-sale', END_OF_DAY_REPORT_SALE: 'end-of-day-report-sale',
END_OF_DAY_REPORT_SALE_DETAIL: 'end-of-day-report-sale-detail', END_OF_DAY_REPORT_SALE_DETAIL: 'end-of-day-report-sale-detail',
END_OF_DAY_REPORT_SALE_DETAIL_TIME: 'end-of-day-report-sale-detail-time', END_OF_DAY_REPORT_SALE_DETAIL_TIME: 'end-of-day-report-sale-detail-time',
END_OF_DAY_REPORT_PAYMENT: 'end-of-day-report-payment', END_OF_DAY_REPORT_PAYMENT: 'end-of-day-report-payment',
END_OF_DAY_REPORT_PRODUCT: 'end-of-day-report-product', END_OF_DAY_REPORT_PRODUCT: 'end-of-day-report-product',
END_OF_DAY_REPORT_PRODUCT_DETAIL: 'end-of-day-report-product-detail', END_OF_DAY_REPORT_PRODUCT_DETAIL: 'end-of-day-report-product-detail',
}; };
FileConfig.Types = { FileConfig.Types = {
IMPORT: 'import', IMPORT: 'import',
EXPORT: 'export' EXPORT: 'export'
}; };
FileConfig.Configs = [ FileConfig.Configs = [
'name', // file name, 'name', // file name,
'path', // file path, 'path', // file path,
'content', // file data 'content', // file data
]; ];
/** /**
* FileConfig Schema * FileConfig Schema
* @public * @public
*/ */
FileConfig.init( FileConfig.init(
{ {
id: { id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
autoIncrement: true, autoIncrement: true,
primaryKey: true primaryKey: true
}, },
name: { name: {
type: DataTypes.STRING(255), type: DataTypes.STRING(255),
defaultValue: null defaultValue: null
}, },
type: { type: {
type: DataTypes.STRING(50), type: DataTypes.STRING(50),
allowNull: false allowNull: false
}, },
group: { group: {
type: DataTypes.STRING(100), type: DataTypes.STRING(100),
defaultValue: null defaultValue: null
}, },
path: { path: {
type: DataTypes.STRING(155), type: DataTypes.STRING(155),
defaultValue: null defaultValue: null
}, },
config: { config: {
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: null defaultValue: null
}, },
// manager // manager
is_active: { is_active: {
type: DataTypes.BOOLEAN, type: DataTypes.BOOLEAN,
defaultValue: true defaultValue: true
}, },
created_at: { created_at: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
}, },
updated_at: { updated_at: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
}, },
created_by: { created_by: {
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: null // id | name defaultValue: null // id | name
}, }
},
}, {
{ timestamps: false,
timestamps: false, schema: serviceName,
schema: serviceName, sequelize: sequelize,
sequelize: sequelize, modelName: 'file_config',
modelName: 'file_config', tableName: 'tbl_file_configs'
tableName: 'tbl_file_configs' }
} );
);
/**
/** * Register event emiter
* Register event emiter */
*/ FileConfig.Events = {
FileConfig.Events = { FILE_CONFIG_CREATED: `${serviceName}.file-config.created`,
FILE_CONFIG_CREATED: `${serviceName}.file-config.created`, FILE_CONFIG_UPDATED: `${serviceName}.file-config.updated`,
FILE_CONFIG_UPDATED: `${serviceName}.file-config.updated`, FILE_CONFIG_DELETED: `${serviceName}.file-config.deleted`,
FILE_CONFIG_DELETED: `${serviceName}.file-config.deleted`, };
}; FileConfig.EVENT_SOURCE = `${serviceName}.file-config`;
FileConfig.EVENT_SOURCE = `${serviceName}.file-config`;
/**
/** * Add your
* Add your * - pre-save hooks
* - pre-save hooks * - validations
* - validations * - virtuals
* - virtuals */
*/ FileConfig.addHook('afterCreate', () => { });
FileConfig.addHook('afterCreate', () => { });
FileConfig.addHook('afterUpdate', () => { });
FileConfig.addHook('afterUpdate', () => { });
FileConfig.addHook('afterDestroy', () => { });
FileConfig.addHook('afterDestroy', () => { });
/**
/** * Load query
* Load query * @param {*} params
* @param {*} params */
*/ function filterConditions(params) {
function filterConditions(params) { const options = omitBy(params, isNil);
const options = omitBy(params, isNil); options.is_active = true;
options.is_active = true;
// TODO: load condition
// TODO: load condition if (options.name) {
if (options.name) { options.name = {
options.name = { [Op.iLike]: `%${options.name}%`
[Op.iLike]: `%${options.name}%` };
}; }
}
return options;
return options; }
}
/**
/** * Load sort query
* Load sort query * @param {*} sort_by
* @param {*} sort_by * @param {*} order_by
* @param {*} order_by */
*/ function sortConditions({ sort_by, order_by }) {
function sortConditions({ sort_by, order_by }) { let sort = null;
let sort = null; switch (sort_by) {
switch (sort_by) { case 'created_at':
case 'created_at': sort = ['created_at', order_by];
sort = ['created_at', order_by]; break;
break; case 'updated_at':
case 'updated_at': sort = ['updated_at', order_by];
sort = ['updated_at', order_by]; break;
break; default: sort = ['created_at', 'DESC'];
default: sort = ['created_at', 'DESC']; break;
break; }
} return sort;
return sort; }
}
/**
/** * Transform postgres model to expose object
* Transform postgres model to expose object */
*/ FileConfig.transform = (params) => {
FileConfig.transform = (params) => { const transformed = {};
const transformed = {}; const fields = [
const fields = [ 'id',
'id', 'name',
'name', 'type',
'type', 'group',
'group', 'config',
'config', 'created_by'
'created_by' ];
]; fields.forEach((field) => {
fields.forEach((field) => { transformed[field] = params[field];
transformed[field] = params[field]; });
});
// pipe date
// pipe date const dateFields = [
const dateFields = [ 'created_at',
'created_at', 'updated_at'
'updated_at' ];
]; dateFields.forEach((field) => {
dateFields.forEach((field) => { if (params[field]) {
if (params[field]) { transformed[field] = moment(params[field]).unix();
transformed[field] = moment(params[field]).unix(); } else {
} else { transformed[field] = null;
transformed[field] = null; }
} });
});
return transformed;
return transformed; };
};
/**
/** * Get all changed properties
* Get all changed properties */
*/ FileConfig.getChangedProperties = ({ newModel, oldModel }) => {
FileConfig.getChangedProperties = ({ newModel, oldModel }) => { const changedProperties = [];
const changedProperties = []; const allChangableProperties = [
const allChangableProperties = [ 'name',
'name', 'type',
'type', 'group',
'group', 'config',
'config', 'status',
'status', 'status_name'
'status_name' ];
]; if (!oldModel) {
if (!oldModel) { return allChangableProperties;
return allChangableProperties; }
}
allChangableProperties.forEach((field) => {
allChangableProperties.forEach((field) => { if (
if ( !isUndefined(newModel[field]) &&
!isUndefined(newModel[field]) && !isEqual(newModel[field], oldModel[field])
!isEqual(newModel[field], oldModel[field]) ) {
) { changedProperties.push(field);
changedProperties.push(field); }
} });
});
return changedProperties;
return changedProperties; };
};
/**
/** * Detail
* Detail *
* * @public
* @public * @param {string} group
* @param {string} group */
*/ FileConfig.get = async (operation) => {
FileConfig.get = async (operation) => { try {
try { const data = await FileConfig.findOne({
const data = await FileConfig.findOne({ where: {
where: { type: operation.type,
type: operation.type, group: operation.group,
group: operation.group, is_active: true
is_active: true }
} });
}); if (!data) {
if (!data) { throw new APIError({
throw new APIError({ status: httpStatus.NOT_FOUND,
status: httpStatus.NOT_FOUND, message: 'Không tìm thấy file!'
message: 'Không tìm thấy file!' });
}); }
} return data;
return data; } catch (ex) {
} catch (ex) { throw ex;
throw ex; }
} };
};
/**
/** * List users in descending order of 'createdAt' timestamp.
* List users in descending order of 'createdAt' timestamp. *
* * @param {number} skip - Number of users to be skipped.
* @param {number} skip - Number of users to be skipped. * @param {number} limit - Limit number of users to be returned.
* @param {number} limit - Limit number of users to be returned. * @returns {Promise<Supplider[]>}
* @returns {Promise<Supplider[]>} */
*/ FileConfig.list = async ({
FileConfig.list = async ({ name,
name,
// sort
// sort sort_by,
sort_by, order_by,
order_by, skip = 0,
skip = 0, limit = 20,
limit = 20, }) => {
}) => { const options = filterConditions({
const options = filterConditions({ name
name });
}); const sort = sortConditions({ sort_by, order_by });
const sort = sortConditions({ sort_by, order_by }); return FileConfig.findAll({
return FileConfig.findAll({ where: options,
where: options, order: [sort],
order: [sort], offset: skip,
offset: skip, limit: limit
limit: limit });
}); };
};
/**
/** * Total records.
* Total records. *
* * @param {number} skip - Number of users to be skipped.
* @param {number} skip - Number of users to be skipped. * @param {number} limit - Limit number of users to be returned.
* @param {number} limit - Limit number of users to be returned. * @returns {Promise<Number>}
* @returns {Promise<Number>} */
*/ FileConfig.totalRecords = ({
FileConfig.totalRecords = ({ name
name }) => {
}) => { const options = filterConditions({
const options = filterConditions({ name
name });
});
return FileConfig.count({ where: options });
return FileConfig.count({ where: options }); };
};
/**
/** * Filter only allowed fields from Province
* Filter only allowed fields from Province *
* * @param {Object} params
* @param {Object} params */
*/ FileConfig.filterParams = (params) => pick(params, PUBLIC_FIELDS);
FileConfig.filterParams = (params) => pick(params, PUBLIC_FIELDS);
/**
/** * @typedef Province
* @typedef Province */
*/ export default FileConfig;
export default FileConfig;

@ -1,278 +1,276 @@
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import httpStatus from 'http-status'; import httpStatus from 'http-status';
import { Model, DataTypes, Op } from 'sequelize'; import { Model, DataTypes, Op } from 'sequelize';
import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash'; import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { serviceName } from '../../config/vars';
import postgres from '../../config/postgres'; import { serviceName } from '../../config/vars';
import APIError from '../utils/APIException'; import postgres from '../../config/postgres';
import APIError from '../utils/APIException';
/**
* Create connection /**
*/ * Create connection
const { sequelize } = postgres; */
class File extends Model { } const { sequelize } = postgres;
class File extends Model { }
const PUBLIC_FIELDS = [
'name', const PUBLIC_FIELDS = [
'title', 'name',
'payload' 'title',
]; 'payload'
];
/**
* File Schema /**
* @public * File Schema
*/ * @public
File.init( */
{ File.init(
id: { {
type: DataTypes.INTEGER, id: {
autoIncrement: true, type: DataTypes.INTEGER,
primaryKey: true autoIncrement: true,
}, primaryKey: true
url: { },
type: DataTypes.STRING(255), url: {
allowNull: false type: DataTypes.STRING(255),
}, allowNull: false
name: { },
type: DataTypes.STRING(255), name: {
defaultValue: null type: DataTypes.STRING(255),
}, defaultValue: null
title: { },
type: DataTypes.STRING(255), title: {
defaultValue: null type: DataTypes.STRING(255),
}, defaultValue: null
payload: { },
type: DataTypes.JSONB, payload: {
defaultValue: null // id | code | name type: DataTypes.JSONB,
}, defaultValue: null // id | code | name
},
// manager
is_active: { // manager
type: DataTypes.BOOLEAN, is_active: {
defaultValue: true type: DataTypes.BOOLEAN,
}, defaultValue: true
created_at: { },
type: DataTypes.DATE, created_at: {
defaultValue: DataTypes.NOW type: DataTypes.DATE,
}, defaultValue: DataTypes.NOW
updated_at: { },
type: DataTypes.DATE, updated_at: {
defaultValue: DataTypes.NOW type: DataTypes.DATE,
}, defaultValue: DataTypes.NOW
created_by: { },
type: DataTypes.JSONB, created_by: {
defaultValue: null // id | name type: DataTypes.JSONB,
}, defaultValue: null // id | name
download_count: { }
type: DataTypes.INTEGER, },
defaultValue: 0 {
} timestamps: false,
}, sequelize: sequelize,
{ schema: serviceName,
timestamps: false, modelName: 'file',
sequelize: sequelize, tableName: 'tbl_files'
schema: serviceName, }
modelName: 'file', );
tableName: 'tbl_files'
} /**
); * Register event emiter
*/
/** File.Events = {
* Register event emiter File_CREATED: `${serviceName}.file.created`,
*/ File_UPDATED: `${serviceName}.file.updated`,
File.Events = { File_DELETED: `${serviceName}.file.deleted`,
File_CREATED: `${serviceName}.file.created`, };
File_UPDATED: `${serviceName}.file.updated`, File.EVENT_SOURCE = `${serviceName}.file`;
File_DELETED: `${serviceName}.file.deleted`,
}; /**
File.EVENT_SOURCE = `${serviceName}.file`; * Add your
* - pre-save hooks
/** * - validations
* Add your * - virtuals
* - pre-save hooks */
* - validations File.addHook('afterCreate', () => { });
* - virtuals
*/ File.addHook('afterUpdate', () => { });
File.addHook('afterCreate', () => { });
File.addHook('afterDestroy', () => { });
File.addHook('afterUpdate', () => { });
/**
File.addHook('afterDestroy', () => { }); * Load query
* @param {*} params
/** */
* Load query function filterConditions(params) {
* @param {*} params const options = omitBy(params, isNil);
*/ options.is_active = true;
function filterConditions(params) {
const options = omitBy(params, isNil); // TODO: load condition
options.is_active = true; if (options.name) {
options.name = {
// TODO: load condition [Op.iLike]: `%${options.name}%`
if (options.name) { };
options.name = { }
[Op.iLike]: `%${options.name}%`
}; return options;
} }
return options; /**
} * Load sort query
* @param {*} sort_by
/** * @param {*} order_by
* Load sort query */
* @param {*} sort_by function sortConditions({ sort_by, order_by }) {
* @param {*} order_by let sort = null;
*/ switch (sort_by) {
function sortConditions({ sort_by, order_by }) { case 'created_at':
let sort = null; sort = ['created_at', order_by];
switch (sort_by) { break;
case 'created_at': case 'updated_at':
sort = ['created_at', order_by]; sort = ['updated_at', order_by];
break; break;
case 'updated_at': default: sort = ['created_at', 'DESC'];
sort = ['updated_at', order_by]; break;
break; }
default: sort = ['created_at', 'DESC']; return sort;
break; }
}
return sort; /**
} * Transform postgres model to expose object
*/
/** File.transform = (params) => {
* Transform postgres model to expose object const transformed = {};
*/ const fields = [
File.transform = (params) => { 'id',
const transformed = {}; 'name',
const fields = [ 'payload',
'id', 'created_by'
'name', ];
'payload', fields.forEach((field) => {
'created_by' transformed[field] = params[field];
]; });
fields.forEach((field) => {
transformed[field] = params[field]; // pipe date
}); const dateFields = [
'created_at',
// pipe date 'updated_at'
const dateFields = [ ];
'created_at', dateFields.forEach((field) => {
'updated_at' if (params[field]) {
]; transformed[field] = moment(params[field]).unix();
dateFields.forEach((field) => { } else {
if (params[field]) { transformed[field] = null;
transformed[field] = moment(params[field]).unix(); }
} else { });
transformed[field] = null;
} return transformed;
}); };
return transformed; /**
}; * Get all changed properties
*/
/** File.getChangedProperties = ({ newModel, oldModel }) => {
* Get all changed properties const changedProperties = [];
*/ const allChangableProperties = [
File.getChangedProperties = ({ newModel, oldModel }) => { 'id',
const changedProperties = []; 'name',
const allChangableProperties = [ 'payload',
'id', ];
'name', if (!oldModel) {
'payload', return allChangableProperties;
]; }
if (!oldModel) {
return allChangableProperties; allChangableProperties.forEach((field) => {
} if (
!isUndefined(newModel[field]) &&
allChangableProperties.forEach((field) => { !isEqual(newModel[field], oldModel[field])
if ( ) {
!isUndefined(newModel[field]) && changedProperties.push(field);
!isEqual(newModel[field], oldModel[field]) }
) { });
changedProperties.push(field);
} return changedProperties;
}); };
return changedProperties; /**
}; * Detail
*
/** * @public
* Detail * @param {string} id
* */
* @public File.get = async (id) => {
* @param {string} id try {
*/ const data = await File.findOne({
File.get = async (id) => { where: {
try { id,
const data = await File.findOne({ is_active: true
where: { }
id, });
is_active: true if (!data) {
} throw new APIError({
}); status: httpStatus.NOT_FOUND,
if (!data) { message: 'Không tìm thấy địa chỉ tỉnh/thành!'
throw new APIError({ });
status: httpStatus.NOT_FOUND, }
message: 'Không tìm thấy địa chỉ tỉnh/thành!' return data;
}); } catch (ex) {
} throw ex;
return data; }
} catch (ex) { };
throw ex;
} /**
}; * List users in descending order of 'createdAt' timestamp.
*
/** * @param {number} skip - Number of users to be skipped.
* List users in descending order of 'createdAt' timestamp. * @param {number} limit - Limit number of users to be returned.
* * @returns {Promise<Supplider[]>}
* @param {number} skip - Number of users to be skipped. */
* @param {number} limit - Limit number of users to be returned. File.list = async ({
* @returns {Promise<Supplider[]>} name,
*/
File.list = async ({ // sort
name, sort_by,
// sort order_by,
sort_by, skip = 0,
order_by, limit = 20,
skip = 0, }) => {
limit = 20, const options = filterConditions({
}) => { name
const options = filterConditions({ });
name const sort = sortConditions({ sort_by, order_by });
}); return File.findAll({
const sort = sortConditions({ sort_by, order_by }); where: options,
return File.findAll({ order: [sort],
where: options, offset: skip,
order: [sort], limit: limit
offset: skip, });
limit: limit };
});
}; /**
* Total records.
/** *
* Total records. * @param {number} skip - Number of users to be skipped.
* * @param {number} limit - Limit number of users to be returned.
* @param {number} skip - Number of users to be skipped. * @returns {Promise<Number>}
* @param {number} limit - Limit number of users to be returned. */
* @returns {Promise<Number>} File.totalRecords = ({
*/ name
File.totalRecords = ({ }) => {
name const options = filterConditions({
}) => { name
const options = filterConditions({ });
name
}); return File.count({ where: options });
};
return File.count({ where: options });
}; /**
* Filter only allowed fields from File
/** *
* Filter only allowed fields from File * @param {Object} params
* */
* @param {Object} params File.filterParams = (params) => pick(params, PUBLIC_FIELDS);
*/
File.filterParams = (params) => pick(params, PUBLIC_FIELDS); /**
* @typedef File
/** */
* @typedef File export default File;
*/
export default File;

@ -1,293 +1,292 @@
/* eslint-disable camelcase */ /* eslint-disable camelcase */
import httpStatus from 'http-status'; import httpStatus from 'http-status';
import { Model, DataTypes, Op } from 'sequelize'; import { Model, DataTypes, Op } from 'sequelize';
import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash'; import { isEqual, isNil, isUndefined, omitBy, pick } from 'lodash';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { serviceName } from '../../config/vars'; import { serviceName } from '../../config/vars';
import postgres from '../../config/postgres'; import postgres from '../../config/postgres';
import APIError from '../utils/APIException'; import APIError from '../utils/APIException';
/** /**
* Create connection * Create connection
*/ */
const { sequelize } = postgres; const { sequelize } = postgres;
class Image extends Model { } class Image extends Model { }
const PUBLIC_FIELDS = [ const PUBLIC_FIELDS = [
'name', 'name',
'title', 'title',
'payload' 'payload'
]; ];
Image.Groups = { Image.Groups = {
USER: 'users', USER: 'users',
STORE: 'stores', STORE: 'stores',
VOUCHER: 'vouchers', VOUCHER: 'vouchers',
STORIES: 'stories', STORIES: 'stories',
CHAPTERS: 'chapters', CHAPTERS: 'chapters',
GAMES: 'games', GAMES: 'games',
CUSTOMER: 'customers', CUSTOMER: 'customers',
PROMOTION: 'promotions', PROMOTION: 'promotions',
PRODUCT: 'products', PRODUCT: 'products',
// configration // configration
BANNER: 'banners', BANNER: 'banners',
CATEGORY: 'categories', CATEGORY: 'categories',
DEFAULT: 'defaults' DEFAULT: 'defaults'
}; };
/** /**
* Image Schema * Image Schema
* @public * @public
*/ */
Image.init( Image.init(
{ {
id: { id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
autoIncrement: true, autoIncrement: true,
primaryKey: true primaryKey: true
}, },
url: { url: {
type: DataTypes.STRING(255), type: DataTypes.STRING(255),
allowNull: false allowNull: false
}, },
name: { name: {
type: DataTypes.STRING(255), type: DataTypes.STRING(255),
defaultValue: null defaultValue: null
}, },
title: { title: {
type: DataTypes.STRING(255), type: DataTypes.STRING(255),
defaultValue: null defaultValue: null
}, },
payload: { payload: {
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: null // id | code | name defaultValue: null // id | code | name
}, },
// manager // manager
is_active: { is_active: {
type: DataTypes.BOOLEAN, type: DataTypes.BOOLEAN,
defaultValue: true defaultValue: true
}, },
created_at: { created_at: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
}, },
updated_at: { updated_at: {
type: DataTypes.DATE, type: DataTypes.DATE,
defaultValue: DataTypes.NOW defaultValue: DataTypes.NOW
}, },
created_by: { created_by: {
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: null // id | name defaultValue: null // id | name
} }
}, },
{ {
timestamps: false, timestamps: false,
sequelize: sequelize, sequelize: sequelize,
schema: serviceName, schema: serviceName,
modelName: 'image', modelName: 'image',
tableName: 'tbl_images' tableName: 'tbl_images'
} }
); );
/** /**
* Register event emiter * Register event emiter
*/ */
Image.Events = { Image.Events = {
IMAGE_CREATED: `${serviceName}.image.created`, IMAGE_CREATED: `${serviceName}.image.created`,
IMAGE_UPDATED: `${serviceName}.image.updated`, IMAGE_UPDATED: `${serviceName}.image.updated`,
IMAGE_DELETED: `${serviceName}.image.deleted`, IMAGE_DELETED: `${serviceName}.image.deleted`,
}; };
Image.EVENT_SOURCE = `${serviceName}.image`;
Image.EVENT_SOURCE = `${serviceName}.image`;
/**
/** * Add your
* Add your * - pre-save hooks
* - pre-save hooks * - validations
* - validations * - virtuals
* - virtuals */
*/ Image.addHook('afterCreate', () => { });
Image.addHook('afterCreate', () => { });
Image.addHook('afterUpdate', () => { });
Image.addHook('afterUpdate', () => { });
Image.addHook('afterDestroy', () => { });
Image.addHook('afterDestroy', () => { });
/**
/** * Load query
* Load query * @param {*} params
* @param {*} params */
*/ function filterConditions(params) {
function filterConditions(params) { const options = omitBy(params, isNil);
const options = omitBy(params, isNil); options.is_active = true;
options.is_active = true;
// TODO: load condition
// TODO: load condition if (options.name) {
if (options.name) { options.name = {
options.name = { [Op.iLike]: `%${options.name}%`
[Op.iLike]: `%${options.name}%` };
}; }
}
return options;
return options; }
}
/**
/** * Load sort query
* Load sort query * @param {*} sort_by
* @param {*} sort_by * @param {*} order_by
* @param {*} order_by */
*/ function sortConditions({ sort_by, order_by }) {
function sortConditions({ sort_by, order_by }) { let sort = null;
let sort = null; switch (sort_by) {
switch (sort_by) { case 'created_at':
case 'created_at': sort = ['created_at', order_by];
sort = ['created_at', order_by]; break;
break; case 'updated_at':
case 'updated_at': sort = ['updated_at', order_by];
sort = ['updated_at', order_by]; break;
break; default: sort = ['created_at', 'DESC'];
default: sort = ['created_at', 'DESC']; break;
break; }
} return sort;
return sort; }
}
/**
/** * Transform postgres model to expose object
* Transform postgres model to expose object */
*/ Image.transform = (params) => {
Image.transform = (params) => { const transformed = {};
const transformed = {}; const fields = [
const fields = [ 'id',
'id', 'name',
'name', 'payload',
'payload', 'created_by'
'created_by' ];
]; fields.forEach((field) => {
fields.forEach((field) => { transformed[field] = params[field];
transformed[field] = params[field]; });
});
// pipe date
// pipe date const dateFields = [
const dateFields = [ 'created_at',
'created_at', 'updated_at'
'updated_at' ];
]; dateFields.forEach((field) => {
dateFields.forEach((field) => { if (params[field]) {
if (params[field]) { transformed[field] = moment(params[field]).unix();
transformed[field] = moment(params[field]).unix(); } else {
} else { transformed[field] = null;
transformed[field] = null; }
} });
});
return transformed;
return transformed; };
};
/**
/** * Get all changed properties
* Get all changed properties */
*/ Image.getChangedProperties = ({ newModel, oldModel }) => {
Image.getChangedProperties = ({ newModel, oldModel }) => { const changedProperties = [];
const changedProperties = []; const allChangableProperties = [
const allChangableProperties = [ 'id',
'id', 'name',
'name', 'payload',
'payload', ];
]; if (!oldModel) {
if (!oldModel) { return allChangableProperties;
return allChangableProperties; }
}
allChangableProperties.forEach((field) => {
allChangableProperties.forEach((field) => { if (
if ( !isUndefined(newModel[field]) &&
!isUndefined(newModel[field]) && !isEqual(newModel[field], oldModel[field])
!isEqual(newModel[field], oldModel[field]) ) {
) { changedProperties.push(field);
changedProperties.push(field); }
} });
});
return changedProperties;
return changedProperties; };
};
/**
/** * Detail
* Detail *
* * @public
* @public * @param {string} id
* @param {string} id */
*/ Image.get = async (id) => {
Image.get = async (id) => { try {
try { const data = await Image.findOne({
const data = await Image.findOne({ where: {
where: { id,
id, is_active: true
is_active: true }
} });
}); if (!data) {
if (!data) { throw new APIError({
throw new APIError({ status: httpStatus.NOT_FOUND,
status: httpStatus.NOT_FOUND, message: 'Không tìm thấy địa chỉ tỉnh/thành!'
message: 'Không tìm thấy địa chỉ tỉnh/thành!' });
}); }
} return data;
return data; } catch (ex) {
} catch (ex) { throw ex;
throw ex; }
} };
};
/**
/** * List users in descending order of 'createdAt' timestamp.
* List users in descending order of 'createdAt' timestamp. *
* * @param {number} skip - Number of users to be skipped.
* @param {number} skip - Number of users to be skipped. * @param {number} limit - Limit number of users to be returned.
* @param {number} limit - Limit number of users to be returned. * @returns {Promise<Supplider[]>}
* @returns {Promise<Supplider[]>} */
*/ Image.list = async ({
Image.list = async ({ name,
name,
// sort
// sort sort_by,
sort_by, order_by,
order_by, skip = 0,
skip = 0, limit = 20,
limit = 20, }) => {
}) => { const options = filterConditions({
const options = filterConditions({ name
name });
}); const sort = sortConditions({ sort_by, order_by });
const sort = sortConditions({ sort_by, order_by }); return Image.findAll({
return Image.findAll({ where: options,
where: options, order: [sort],
order: [sort], offset: skip,
offset: skip, limit: limit
limit: limit });
}); };
};
/**
/** * Total records.
* Total records. *
* * @param {number} skip - Number of users to be skipped.
* @param {number} skip - Number of users to be skipped. * @param {number} limit - Limit number of users to be returned.
* @param {number} limit - Limit number of users to be returned. * @returns {Promise<Number>}
* @returns {Promise<Number>} */
*/ Image.totalRecords = ({
Image.totalRecords = ({ name
name }) => {
}) => { const options = filterConditions({
const options = filterConditions({ name
name });
});
return Image.count({ where: options });
return Image.count({ where: options }); };
};
/**
/** * Filter only allowed fields from Province
* Filter only allowed fields from Province *
* * @param {Object} params
* @param {Object} params */
*/ Image.filterParams = (params) => pick(params, PUBLIC_FIELDS);
Image.filterParams = (params) => pick(params, PUBLIC_FIELDS);
/**
/** * @typedef Province
* @typedef Province */
*/ export default Image;
export default Image;

File diff suppressed because it is too large Load Diff

@ -1,129 +1,3 @@
<<<<<<< HEAD
import multer from 'multer';
// import moment from 'moment-timezone';
import { storage as storageConfig } from '../../../config/vars';
import { forIn } from 'lodash';
import { equal } from 'joi';
/** storage will create folder when new date */
// const date = new Date();
// const year = moment(date).format('YYYY');
// const month = moment(date).format('MM');
const filePath = `${storageConfig.uri}`;
const createDefaultFolder = ( id ) => {
try {
if (id) {
multer({ dest: `${filePath}/${id}` });
console.log(`creat default ${filePath}/${id}` );
} else {
multer({ dest: `${filePath}` });
console.log(`creat default ${filePath}` );
}
// multer({ dest: `${filePath}/images/games` });
// multer({ dest: `${filePath}/images/stories` });
// multer({ dest: `${filePath}/images/chapters` });
// multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/products` });
// multer({ dest: `${filePath}/images/customers` });
// multer({ dest: `${filePath}/images/promotions` });
// // configuration
// multer({ dest: `${filePath}/images/banners` });
// multer({ dest: `${filePath}/images/categories` });
// multer({ dest: `${filePath}/images/upload/default` });
return true;
} catch (ex) {
return false;
}
};
const createFolder = ({ path }) => {
try {
console.log(`${filePath}/${path}`);
multer({ dest: `${filePath}/${path}` });
// multer({ dest: `${filePath}/images/games` });
// multer({ dest: `${filePath}/images/stories` });
// multer({ dest: `${filePath}/images/chapters` });
// multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/products` });
// multer({ dest: `${filePath}/images/customers` });
// multer({ dest: `${filePath}/images/promotions` });
// // configuration
// multer({ dest: `${filePath}/images/banners` });
// multer({ dest: `${filePath}/images/categories` });
// multer({ dest: `${filePath}/images/upload/default` });
// console.log(multer);
return true;
} catch (ex) {
return false;
}
};
/** add image to storage follow group */
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, filePath);
},
filename: (req, file, cb) => {
/**
* setup folder follow date
*/
createDefaultFolder(req.params.id);
console.log('run in herer', req.query.path, file);
/**
* save image follow type
*/
// let path = req.locals.user.id;
// console.log(path);
let path = req.params.id;
console.log(path);
console.log(file);
// const fileName = file.originalname.includes('.')
// ? file.originalname.slice(0, file.originalname.lastIndexOf('.'))
// : file.originalname;
cb(
null,
`/${path}/${file.originalname.replace(/\s/g, '')}`
);
}
});
const fileFilter = (req, file, cb) => {
// if (
// file.mimetype === 'image/jpeg' ||
// file.mimetype === 'image/webp' ||
// file.mimetype === 'image/png' ||
// file.mimetype === 'image/gif' ||
// ) {
// cb(null, true);
// } else {
// cb(null, false);
// }
cb(null, true);
};
const uploader = multer({
storage,
limits: {
fileSize: 1024 * 1024 * 2048 // 5MB
},
fileFilter
});
module.exports = {
createDefaultFolder,
createFolder,
uploader,
fileFilter
};
=======
import multer from 'multer'; import multer from 'multer';
// import moment from 'moment-timezone'; // import moment from 'moment-timezone';
import { storage as storageConfig } from '../../../config/vars'; import { storage as storageConfig } from '../../../config/vars';
@ -238,4 +112,3 @@ module.exports = {
uploader, uploader,
fileFilter fileFilter
}; };
>>>>>>> 7bd4b58a0df174b4a8c26c34b9d388fc8ab3c4fd

@ -35,33 +35,5 @@
"_ is not defined": "_ is not defined", "_ is not defined": "_ is not defined",
"Cannot access 'splited_dir' before initialization": "Cannot access 'splited_dir' before initialization", "Cannot access 'splited_dir' before initialization": "Cannot access 'splited_dir' before initialization",
"main_dir is not defined": "main_dir is not defined", "main_dir is not defined": "main_dir is not defined",
"Cannot read properties of undefined (reading 'trim')": "Cannot read properties of undefined (reading 'trim')", "Cannot read properties of undefined (reading 'trim')": "Cannot read properties of undefined (reading 'trim')"
"relation \"file_service.tbl_files\" does not exist": "relation \"file_service.tbl_files\" does not exist",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\12\\755296-200.png'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\12\\755296-200.png'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\755296-200.png'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\755296-200.png'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\Papers-1(2).docx'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\Papers-1(2).docx'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\style.txt'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\style.txt'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\12\\style.txt'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\12\\style.txt'",
"Cannot read properties of undefined (reading 'locals')": "Cannot read properties of undefined (reading 'locals')",
"body is not defined": "body is not defined",
"Tài khoản này đã được đăng kí": "Tài khoản này đã được đăng kí",
"file is not defined": "file is not defined",
"pick is not defined": "pick is not defined",
"path is not defined": "path is not defined",
"Cannot read properties of undefined (reading 'isFolder')": "Cannot read properties of undefined (reading 'isFolder')",
"Cannot read properties of undefined (reading 'isDirectory')": "Cannot read properties of undefined (reading 'isDirectory')",
"data.url.isDirectory is not a function": "data.url.isDirectory is not a function",
"ENOENT: no such file or directory, lstat 'http://103.162.31.170\\15\\login-password.json'": "ENOENT: no such file or directory, lstat 'http://103.162.31.170\\15\\login-password.json'",
"ENOENT: no such file or directory, lstat 'public/15/undefined/login-password.json'": "ENOENT: no such file or directory, lstat 'public/15/undefined/login-password.json'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\59\\Papers-1(2).docx'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\59\\Papers-1(2).docx'",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\60\\Papers-1(2).docx'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\60\\Papers-1(2).docx'",
"ENOENT: no such file or directory, lstat 'public/60//Papers-1 (2).docx'": "ENOENT: no such file or directory, lstat 'public/60//Papers-1 (2).docx'",
"Converting circular structure to JSON\n --> starting at object with constructor 'Object'\n --- property 'win32' closes the circle": "Converting circular structure to JSON\n --> starting at object with constructor 'Object'\n --- property 'win32' closes the circle",
"EPERM: operation not permitted, lstat 'public\\download\\60\\1233532-1691036912591.zip'": "EPERM: operation not permitted, lstat 'public\\download\\60\\1233532-1691036912591.zip'",
"_file2.default.find is not a function": "_file2.default.find is not a function",
"storage is not defined": "storage is not defined",
"queue closed": "queue closed",
"downnload_count_list is not defined": "downnload_count_list is not defined",
"ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\deeplearning_ex2.py'": "ENOENT: no such file or directory, open 'C:\\Users\\TUNG DO\\upload-file-backend\\public\\undefined\\deeplearning_ex2.py'",
"invalid input syntax for type integer: \"deeplearning_ex2.py\"": "invalid input syntax for type integer: \"deeplearning_ex2.py\""
} }

@ -1,40 +1,40 @@
import Sequelize from 'sequelize'; import Sequelize from 'sequelize';
import bluebird from 'bluebird'; import bluebird from 'bluebird';
import { postgres, env } from './vars'; import { postgres, env } from './vars';
Sequelize.Promise = bluebird; Sequelize.Promise = bluebird;
const defaultErrorHandler = (err) => { const defaultErrorHandler = (err) => {
console.log(`Connection to Postgres error: ${err}`); console.log(`Connection to Postgres error: ${err}`);
}; };
const app = { const app = {
sequelize: new Sequelize( sequelize: new Sequelize(
postgres.uri, postgres.uri,
{ {
dialect: 'postgres' dialect: 'postgres'
} }
), ),
connect(errorHandler = defaultErrorHandler) { connect(errorHandler = defaultErrorHandler) {
this.sequelize.authenticate() this.sequelize.authenticate()
.then(() => { .then(() => {
console.log('Postgres connection established!'); console.log('Postgres connection established!');
if (env === '1') { if (env === '1') {
this.sequelize.sync({ this.sequelize.sync({
alter: true, alter: true,
logging: true logging: true
}); });
} }
}).catch((error) => { }).catch((error) => {
errorHandler(error); errorHandler(error);
}); });
return this.sequelize; return this.sequelize;
}, },
disconnect() { disconnect() {
// close connection // close connection
console.log('Closing postgres connection!'); console.log('Closing postgres connection!');
this.sequelize.close(); this.sequelize.close();
} }
}; };
export default app; export default app;

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save