Compare commits

..

3 Commits

Author SHA1 Message Date
Hai Q. Le 8888a9b1d3 change 1 year ago
Hai Q. Le c4edd5eca2 Merge tag 'HEAD' 1 year ago
Hai Q. Le 785a3afd83 Revert "change a" 1 year ago
  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. 596
      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. 534
      src/common/models/file.model.js
  26. 585
      src/common/models/image.model.js
  27. 2036
      src/common/models/user.model.js
  28. 239
      src/common/services/adapters/upload-adapter.js
  29. 30
      src/config/locales/en.json
  30. 2
      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,236 @@
/* 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 multer from 'multer';
import path from 'path'; import path from 'path';
import { handler as ErrorHandel } from '../../middlewares/errors'; import { handler as ErrorHandel } from '../../middlewares/errors';
import File from "../../../common/models/file.model"; // import ApiException from '../../../common/utils/APIException';
import { handler as ErrorHandler } from '../../middlewares/error'; import {
import ApiException from '../../../common/utils/APIException';
import { cdn as cdnConfig,
storage as storageConfig
cdn as cdnConfig, } from '../../../config/vars';
storage as storageConfig import uploadAdapter from '../../../common/services/adapters/upload-adapter';
} from '../../../config/vars'; import { cloneDeep, forEach } from 'lodash';
import uploadAdapter from '../../../common/services/adapters/upload-adapter';
import { cloneDeep, forEach } from 'lodash'; function deleteFolderRecursive(folderPath) {
import APIError from '../../middlewares/ApiError'; if (fs.existsSync(folderPath)) {
import { example } from 'joi'; fs.readdirSync(folderPath).forEach((file) => {
import { where } from 'sequelize'; const curPath = path.join(folderPath, file);
import messages from '../../../config/messages'; if (fs.lstatSync(curPath).isDirectory()) { // delete folder
deleteFolderRecursive(curPath); // recursively call deleteFolderRecursive function
function deleteFolderRecursive(folderPath) { fs.rmdirSync(curPath);
if (fs.existsSync(folderPath)) { } else { // delete file
fs.readdirSync(folderPath).forEach((file) => { fs.unlinkSync(curPath);
const curPath = path.join(folderPath, file); }
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) => {
/** try {
* get file and folder const user = req.user;
*
* @param {Formdata} file let path = `${storageConfig.uri}/${user.id}`;
*/ if (req.body.path) {
path += req.body.path;
}
// console.log(path);
exports.get = async (req, res, next) => { const listFile = [];
try { fs.readdir(path, (err, files) => {
const user = req.user; if (files && files.length > 0) {
const user_infor = { files.forEach((item) => {
id: user.id, listFile.push({
name: user.name name: item,
}; path: `${cdnConfig.uri}/${user.id}${req.body.path}/${item}`,
console.log(user_infor); isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory()
let path = `${storageConfig.uri}/${user.id}`; });
console.log(path); });
if (req.body.path) { }
path += req.body.path; return res.json({
} code: 0,
const listFile = []; data: listFile
// fs.readdir(path, (err, files) => { });
// if (files && files.length > 0) { });
// files.forEach((item) => { // test local
// listFile.push({ // fs.readdir(path, (err, files) => {
// name: item, // if (files && files.length > 0) {
// path: `${cdnConfig.uri}/${user.id}/${req.body.path}/${item}`, // files.forEach((item) => {
// isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory(), // listFile.push({
// }); // name: item,
// }); // path: `${storageConfig.uri}/${user.id}${req.body.path}/${item}`,
// } // isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory()
// return res.json({ // });
// code: 0, // });
// data: listFile // }
// }); // return res.json({
// }); // code: 0,
// data: listFile
await File.findAll({ // });
where: { // });
is_active: true,
created_by : user_infor
} return null;
}).then(result => { /** resize image uploaded */
let path = [] } catch (ex) {
result.forEach(data => { return ErrorHandel(ex, req, res, next);
console.log(data.created_by.id); }
// console.log(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`); };
const file = {
name: data.name, /**
path: data.url, * get file and folder
// isFolder: fs.lstatSync(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`).isDirectory(), *
isFolder: fs.lstatSync(`${storageConfig.uri}/${data.created_by.id}/${req.body.path}/${data.name}`).isDirectory(), * @param {Formdata} file
download_count : data.download_count */
exports.create = (req, res, next) => {
} const user = req.user;
let dir = `${user.id}`;
path.push(file); const name_folder = cloneDeep(req.body.name).trim();
}); if (req.body.path) {
return res.json({ dir += req.body.path;
code: 0, }
data : path if (req.body.name) {
}) dir += `/${name_folder}`;
}).catch(ex => { }
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) { * get file and folder
// files.forEach((item) => { *
// listFile.push({ * @param {Formdata} file
// name: item, */
// path: `${cdnConfig.uri}/${user.id}${req.body.path}/${item}`, exports.update = (req, res, next) => {
try {
// path: `${storageConfig.uri}/${user.id}${req.body.path}/${item}`, const oldPath = req.body.oldPath.replace(cdnConfig.uri, storageConfig.uri);
// isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory() const newPath = req.body.newPath.replace(cdnConfig.uri, storageConfig.uri);
// });
// }); fs.rename(oldPath, newPath, (err) => {
// } if (err) {
// return res.json({ console.log(err);
// code: 0, return res.status(400).json({ code: 400, message: 'lỗi' });
// data: listFile }
// }); return res.json({ code: 0, message: 'success' });
// }); });
return null;
} catch (ex) {
return null; return ErrorHandel(ex, req, res, next);
/** resize image uploaded */ }
} catch (ex) { };
return ErrorHandel(ex, req, res, next);
}
}; exports.delete = (req, res, next) => {
try {
/** const user = req.user;
* get file and folder const dir = `${storageConfig.uri_backup}/${user.id}`;
* multer({ dest: `${dir}` });
* @param {Formdata} file const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
*/ const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
exports.create = (req, res, next) => { // fs.rm(path, { recursive: true }, err => {
const user = req.user; // if (err) {
let dir = `${user.id}`; // return res.status(400).json({ code: 400, message: 'lỗi', detail: err });
const name_folder = cloneDeep(req.body.name).trim(); // }
if (req.body.path) { // return res.json({ code: 0, message: 'success' });
dir += req.body.path; // });
} fs.rename(path, newpath, (err) => {
if (req.body.name) { if (err) throw err;
dir += `/${name_folder}`; return res.json({ code: 0, message: 'success' });
} });
if (!fs.existsSync(dir)) { return null;
uploadAdapter.createFolder({ path: dir }); } catch (ex) {
} return ErrorHandel(ex, req, res, next);
return res.json({ code: 0, message: 'success' }); }
}; };
exports.download = async (req, res, next) => {
/** try {
* get file and folder const user = req.user;
* const namefile = `${user.name}-${Date.now()}.zip`;
* @param {Formdata} file const dir = `${storageConfig.uri}/download/${user.id}/${namefile}`;
*/ const folder = `${storageConfig.uri}/download/${user.id}`;
exports.update = (req, res, next) => { multer({ dest: `${folder}` });
try { await deleteFolderRecursive(folder);
const oldPath = req.body.oldPath.replace(cdnConfig.uri, storageConfig.uri); const output = fs.createWriteStream(dir);
const newPath = req.body.newPath.replace(cdnConfig.uri, storageConfig.uri); const archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
fs.rename(oldPath, newPath, (err) => { });
if (err) {
console.log(err);
return res.status(400).json({ code: 400, message: 'lỗi' }); archive.pipe(output);
} if (req.body.data) {
return res.json({ code: 0, message: 'success' }); req.body.data.forEach((e) => {
}); const path = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ ');
return null; // const path = e.path.replace(cdnConfig.uri, storageConfig.uri);
} catch (ex) { console.log('path', path);
return ErrorHandel(ex, req, res, next); // const download = path.split("/");
} // download.splice( download.indexOf(`${user.id}`), 0, "download");
}; // const final_path = download.join("/");
if (e.isFolder) {
archive.directory(path, e.name);
exports.delete = (req, res, next) => { } else {
try { archive.file(path, { name: e.name });
const user = req.user; }
const dir = `${storageConfig.uri_backup}/${user.id}`; });
multer({ dest: `${dir}` }); }
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup); archive.finalize();
// fs.rm(path, { recursive: true }, err => { return res.json({
// if (err) { code: 0,
// return res.status(400).json({ code: 400, message: 'lỗi', detail: err }); data: {
// } name: namefile,
// return res.json({ code: 0, message: 'success' }); path: `${cdnConfig.uri}/download/${user.id}/${namefile}`,
// }); }
fs.rename(path, newpath, (err) => { });
if (err) throw err; } catch (ex) {
return res.json({ code: 0, message: 'success' }); return ErrorHandel(ex, req, res, next);
}); }
return null; };
} catch (ex) {
return ErrorHandel(ex, req, res, next);
} exports.forceDelete = (req, res, next) => {
}; try {
exports.download = async (req, res, next) => { const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri);
try { // const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
fs.rm(path, { recursive: true }, err => {
const user = req.user; if (err) {
const namefile = `${user.name}-${Date.now()}.zip`; return res.status(400).json({ code: 400, message: 'lỗi', detail: err });
const dir = `${storageConfig.uri}/download/${user.id}/${namefile}`; }
const folder = `${storageConfig.uri}/download/${user.id}`; return res.json({ code: 0, message: 'success' });
multer({ dest: `${folder}` }); });
await deleteFolderRecursive(folder);
const output = fs.createWriteStream(dir); return null;
const archive = archiver('zip', { } catch (ex) {
zlib: { level: 9 } // Sets the compression level. return ErrorHandel(ex, req, res, next);
}); }
};
const user_infor = {
id: user.id, exports.deleteMultiple = (req, res, next) => {
name: user.name try {
} const user = req.user;
archive.pipe(output); const dir = `${storageConfig.uri_backup}/${user.id}/${Date.now()}`;
if (req.body.data) { multer({ dest: `${dir}` });
req.body.data.forEach( async (e) => { if (req.body.data) {
// const path = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ '); req.body.data.forEach((e) => {
// // // const path = e.path.replace(cdnConfig.uri, storageConfig.uri); const path = e.path.replace(cdnConfig.uri, storageConfig.uri);
// console.log('path: ', path); let newpath = e.path.replace(cdnConfig.uri, storageConfig.uri_backup);
let downnload_count_list = new Map(); const split = newpath.split('/');
newpath = `${dir}/${split[split.length - 1]}`;
await File.findOne({ fs.rename(path, newpath, (err) => {
where: { if (err) throw err;
name: e.name, return { code: 0, message: 'success' };
url : e.path, });
created_by: user_infor, });
is_active : true }
} return res.json({ code: 0, message: 'success' });
}).then(result => { } catch (ex) {
// plus one to the download count when download each selected file return ErrorHandel(ex, req, res, next);
downnload_count_list.set( result.id,result.download_count + 1); }
};
const storage = result.url.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ ');
if (e.isFolder) {
archive.directory(storage, e.name);
} else {
archive.file(storage, { name: e.name });
}
archive.finalize();
next()
}).catch(ex => {
console.log(ex);
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,256 @@
/* 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), name: {
allowNull: false type: DataTypes.STRING(255),
}, allowNull: false
name: { },
type: DataTypes.STRING(255), url: {
defaultValue: null type: DataTypes.STRING(255),
}, allowNull: false
title: { },
type: DataTypes.STRING(255), download_count: {
defaultValue: null type: DataTypes.NUMBER,
}, allowNull: true,
payload: { defaultValue: 0
type: DataTypes.JSONB, }
defaultValue: null // id | code | name
}, },
{
// manager timestamps: false,
is_active: { sequelize: sequelize,
type: DataTypes.BOOLEAN, schema: serviceName,
defaultValue: true modelName: 'file',
}, tableName: 'tbl_files'
created_at: { }
type: DataTypes.DATE, );
defaultValue: DataTypes.NOW
}, /**
updated_at: { * Register event emiter
type: DataTypes.DATE, */
defaultValue: DataTypes.NOW File.Events = {
}, File_CREATED: `${serviceName}.file.created`,
created_by: { File_UPDATED: `${serviceName}.file.updated`,
type: DataTypes.JSONB, File_DELETED: `${serviceName}.file.deleted`,
defaultValue: null // id | name };
}, File.EVENT_SOURCE = `${serviceName}.file`;
download_count: {
type: DataTypes.INTEGER, /**
defaultValue: 0 * Add your
} * - pre-save hooks
}, * - validations
{ * - virtuals
timestamps: false, */
sequelize: sequelize, File.addHook('afterCreate', () => { });
schema: serviceName,
modelName: 'file', File.addHook('afterUpdate', () => { });
tableName: 'tbl_files'
} File.addHook('afterDestroy', () => { });
);
/**
/** * Load query
* Register event emiter * @param {*} params
*/ */
File.Events = { function filterConditions(params) {
File_CREATED: `${serviceName}.file.created`, const options = omitBy(params, isNil);
File_UPDATED: `${serviceName}.file.updated`, options.is_active = true;
File_DELETED: `${serviceName}.file.deleted`,
}; // TODO: load condition
File.EVENT_SOURCE = `${serviceName}.file`; if (options.name) {
options.name = {
/** [Op.iLike]: `%${options.name}%`
* Add your };
* - pre-save hooks }
* - validations
* - virtuals return options;
*/ }
File.addHook('afterCreate', () => { });
/**
File.addHook('afterUpdate', () => { }); * Load sort query
* @param {*} sort_by
File.addHook('afterDestroy', () => { }); * @param {*} order_by
*/
/** function sortConditions({ sort_by, order_by }) {
* Load query let sort = null;
* @param {*} params switch (sort_by) {
*/ case 'created_at':
function filterConditions(params) { sort = ['created_at', order_by];
const options = omitBy(params, isNil); break;
options.is_active = true; case 'updated_at':
sort = ['updated_at', order_by];
// TODO: load condition break;
if (options.name) { default: sort = ['created_at', 'DESC'];
options.name = { break;
[Op.iLike]: `%${options.name}%` }
}; return sort;
} }
return options; /**
} * Transform postgres model to expose object
*/
/** File.transform = (params) => {
* Load sort query const transformed = {};
* @param {*} sort_by const fields = [
* @param {*} order_by 'id',
*/ 'name',
function sortConditions({ sort_by, order_by }) { 'payload',
let sort = null; 'created_by'
switch (sort_by) { ];
case 'created_at': fields.forEach((field) => {
sort = ['created_at', order_by]; transformed[field] = params[field];
break; });
case 'updated_at':
sort = ['updated_at', order_by]; // pipe date
break; const dateFields = [
default: sort = ['created_at', 'DESC']; 'created_at',
break; 'updated_at'
} ];
return sort; dateFields.forEach((field) => {
} if (params[field]) {
transformed[field] = moment(params[field]).unix();
/** } else {
* Transform postgres model to expose object transformed[field] = null;
*/ }
File.transform = (params) => { });
const transformed = {};
const fields = [ return transformed;
'id', };
'name',
'payload', /**
'created_by' * Get all changed properties
]; */
fields.forEach((field) => { File.getChangedProperties = ({ newModel, oldModel }) => {
transformed[field] = params[field]; const changedProperties = [];
}); const allChangableProperties = [
'id',
// pipe date 'name',
const dateFields = [ 'payload',
'created_at', ];
'updated_at' if (!oldModel) {
]; return allChangableProperties;
dateFields.forEach((field) => { }
if (params[field]) {
transformed[field] = moment(params[field]).unix(); allChangableProperties.forEach((field) => {
} else { if (
transformed[field] = null; !isUndefined(newModel[field]) &&
} !isEqual(newModel[field], oldModel[field])
}); ) {
changedProperties.push(field);
return transformed; }
}; });
/** return changedProperties;
* Get all changed properties };
*/
File.getChangedProperties = ({ newModel, oldModel }) => { /**
const changedProperties = []; * Detail
const allChangableProperties = [ *
'id', * @public
'name', * @param {string} id
'payload', */
]; File.get = async (id) => {
if (!oldModel) { try {
return allChangableProperties; const data = await File.findOne({
} where: {
id,
allChangableProperties.forEach((field) => { is_active: true
if ( }
!isUndefined(newModel[field]) && });
!isEqual(newModel[field], oldModel[field]) if (!data) {
) { throw new APIError({
changedProperties.push(field); status: httpStatus.NOT_FOUND,
} message: 'Không tìm thấy địa chỉ file!'
}); });
}
return changedProperties; return data;
}; } catch (ex) {
throw ex;
/** }
* Detail };
*
* @public /**
* @param {string} id * List users in descending order of 'createdAt' timestamp.
*/ *
File.get = async (id) => { * @param {number} skip - Number of users to be skipped.
try { * @param {number} limit - Limit number of users to be returned.
const data = await File.findOne({ * @returns {Promise<Supplider[]>}
where: { */
id, File.list = async ({
is_active: true name,
}
}); // sort
if (!data) { sort_by,
throw new APIError({ order_by,
status: httpStatus.NOT_FOUND, skip = 0,
message: 'Không tìm thấy địa chỉ tỉnh/thành!' limit = 20,
}); }) => {
} const options = filterConditions({
return data; name
} catch (ex) { });
throw ex; const sort = sortConditions({ sort_by, order_by });
} return File.findAll({
}; where: options,
order: [sort],
/** offset: skip,
* List users in descending order of 'createdAt' timestamp. limit: limit
* });
* @param {number} skip - Number of users to be skipped. };
* @param {number} limit - Limit number of users to be returned.
* @returns {Promise<Supplider[]>} /**
*/ * Total records.
File.list = async ({ *
name, * @param {number} skip - Number of users to be skipped.
// sort * @param {number} limit - Limit number of users to be returned.
sort_by, * @returns {Promise<Number>}
order_by, */
skip = 0, File.totalRecords = ({
limit = 20, name
}) => { }) => {
const options = filterConditions({ const options = filterConditions({
name name
}); });
const sort = sortConditions({ sort_by, order_by });
return File.findAll({ return File.count({ where: options });
where: options, };
order: [sort],
offset: skip, /**
limit: limit * Filter only allowed fields from File
}); *
}; * @param {Object} params
*/
/** File.filterParams = (params) => pick(params, PUBLIC_FIELDS);
* Total records.
* /**
* @param {number} skip - Number of users to be skipped. * @typedef File
* @param {number} limit - Limit number of users to be returned. */
* @returns {Promise<Number>} export default File;
*/
File.totalRecords = ({
name
}) => {
const options = filterConditions({
name
});
return File.count({ where: options });
};
/**
* Filter only allowed fields from File
*
* @param {Object} params
*/
File.filterParams = (params) => pick(params, PUBLIC_FIELDS);
/**
* @typedef 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,125 +1,114 @@
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';
import { forIn } from 'lodash'; import { forIn } from 'lodash';
import { equal } from 'joi'; import { equal } from 'joi';
/** storage will create folder when new date */ /** storage will create folder when new date */
// const date = new Date(); // const date = new Date();
// const year = moment(date).format('YYYY'); // const year = moment(date).format('YYYY');
// const month = moment(date).format('MM'); // const month = moment(date).format('MM');
const filePath = `${storageConfig.uri}`; const filePath = `${storageConfig.uri}`;
const createDefaultFolder = ( id ) => { const createDefaultFolder = ({ id }) => {
try { try {
if (id) { if (id) {
multer({ dest: `${filePath}/${id}` }); multer({ dest: `${filePath}/${id}` });
console.log(`creat default ${filePath}/${id}` ); } else {
multer({ dest: `${filePath}` });
} else { }
multer({ dest: `${filePath}` }); // multer({ dest: `${filePath}/images/games` });
console.log(`creat default ${filePath}` ); // multer({ dest: `${filePath}/images/stories` });
// multer({ dest: `${filePath}/images/chapters` });
} // multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/games` }); // multer({ dest: `${filePath}/images/products` });
// multer({ dest: `${filePath}/images/stories` }); // multer({ dest: `${filePath}/images/customers` });
// multer({ dest: `${filePath}/images/chapters` }); // multer({ dest: `${filePath}/images/promotions` });
// multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/products` }); // // configuration
// multer({ dest: `${filePath}/images/customers` }); // multer({ dest: `${filePath}/images/banners` });
// multer({ dest: `${filePath}/images/promotions` }); // multer({ dest: `${filePath}/images/categories` });
// multer({ dest: `${filePath}/images/upload/default` });
// // configuration return true;
// multer({ dest: `${filePath}/images/banners` }); } catch (ex) {
// multer({ dest: `${filePath}/images/categories` }); return false;
// multer({ dest: `${filePath}/images/upload/default` }); }
return true; };
} catch (ex) { const createFolder = ({ path }) => {
return false; try {
} console.log(`${filePath}/${path}`);
}; multer({ dest: `${filePath}/${path}` });
const createFolder = ({ path }) => {
try {
console.log(`${filePath}/${path}`); // multer({ dest: `${filePath}/images/games` });
multer({ dest: `${filePath}/${path}` }); // multer({ dest: `${filePath}/images/stories` });
// multer({ dest: `${filePath}/images/chapters` });
// multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/games` }); // multer({ dest: `${filePath}/images/products` });
// multer({ dest: `${filePath}/images/stories` }); // multer({ dest: `${filePath}/images/customers` });
// multer({ dest: `${filePath}/images/chapters` }); // multer({ dest: `${filePath}/images/promotions` });
// multer({ dest: `${filePath}/images/vouchers` });
// multer({ dest: `${filePath}/images/products` }); // // configuration
// multer({ dest: `${filePath}/images/customers` }); // multer({ dest: `${filePath}/images/banners` });
// multer({ dest: `${filePath}/images/promotions` }); // multer({ dest: `${filePath}/images/categories` });
// multer({ dest: `${filePath}/images/upload/default` });
// // configuration // console.log(multer);
// multer({ dest: `${filePath}/images/banners` }); return true;
// multer({ dest: `${filePath}/images/categories` }); } catch (ex) {
// multer({ dest: `${filePath}/images/upload/default` }); return false;
// console.log(multer); }
return true; };
} catch (ex) { /** add image to storage follow group */
return false; const storage = multer.diskStorage({
} destination: (req, file, cb) => {
}; cb(null, filePath);
/** add image to storage follow group */ },
const storage = multer.diskStorage({ filename: (req, file, cb) => {
destination: (req, file, cb) => { /**
cb(null, filePath); * setup folder follow date
}, */
filename: (req, file, cb) => { createDefaultFolder({});
/** console.log('run in herer', req.query.path, file);
* setup folder follow date /**
*/ * save image follow type
createDefaultFolder(req.params.id); */
console.log('run in herer', req.query.path, file); const path = req.query.path;
/** // const fileName = file.originalname.includes('.')
* save image follow type // ? file.originalname.slice(0, file.originalname.lastIndexOf('.'))
*/ // : file.originalname;
cb(
// let path = req.locals.user.id; null,
// console.log(path); `/${path}/${file.originalname.replace(/[\s()]/g, '')}`
let path = req.params.id; );
console.log(path); }
console.log(file); });
// const fileName = file.originalname.includes('.') const fileFilter = (req, file, cb) => {
// ? file.originalname.slice(0, file.originalname.lastIndexOf('.')) // if (
// : file.originalname; // file.mimetype === 'image/jpeg' ||
cb( // file.mimetype === 'image/webp' ||
null, // file.mimetype === 'image/png' ||
`/${path}/${file.originalname.replace(/\s/g, '')}` // file.mimetype === 'image/gif' ||
); // ) {
} // cb(null, true);
}); // } else {
// cb(null, false);
const fileFilter = (req, file, cb) => { // }
// if ( cb(null, true);
// file.mimetype === 'image/jpeg' || };
// file.mimetype === 'image/webp' ||
// file.mimetype === 'image/png' || const uploader = multer({
// file.mimetype === 'image/gif' || storage,
// ) { limits: {
// cb(null, true); fileSize: 1024 * 1024 * 5048 // 5MB
// } else { },
// cb(null, false); fileFilter
// } });
cb(null, true);
}; module.exports = {
createDefaultFolder,
const uploader = multer({ createFolder,
storage, uploader,
limits: { fileFilter
fileSize: 1024 * 1024 * 2048 // 5MB };
},
fileFilter
});
module.exports = {
createDefaultFolder,
createFolder,
uploader,
fileFilter
};

@ -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\""
} }

@ -19,7 +19,7 @@ const app = {
this.sequelize.authenticate() this.sequelize.authenticate()
.then(() => { .then(() => {
console.log('Postgres connection established!'); console.log('Postgres connection established!');
if (env === 'development') { if (env === '1') {
this.sequelize.sync({ this.sequelize.sync({
alter: true, alter: true,
logging: true logging: true

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