Spaces:
Running
Running
| /** | |
| * Copyright (c) 2017~2022, OBCon Inc. | |
| * All rights reserved. | |
| */ | |
| /** | |
| * @file | |
| * @copyright 2017~2022, OBCon Inc. | |
| * @author gye hyun james kim [pnuskgh@gmail.com] | |
| */ | |
| //--- http://docs.sequelizejs.com/ | |
| const moment = require('moment'); | |
| const Sequelize = require('sequelize'); | |
| const Model = utils.getClass('include', 'model.js'); | |
| class UsersModel extends Model { | |
| constructor() { | |
| super(); | |
| this._title = '사용자'; | |
| this._database = db.db_scada; | |
| this._tableName = 'users'; | |
| } | |
| get fieldDesc() { | |
| let fieldDescribes = Object.assign({ | |
| site: { | |
| type: 'integer', len: 11, | |
| allowNull: false, | |
| defaultValue: 1, | |
| validate: {}, | |
| title: '사이트', | |
| strType: 'integer' | |
| }, | |
| authenticateId: { | |
| type: 'string', len: 64, | |
| allowNull: false, | |
| validate: {}, | |
| title: '아이디', | |
| strType: 'string' | |
| }, | |
| hash: { | |
| type: 'string', len: 64, | |
| allowNull: false, | |
| validate: {}, | |
| title: '비밀번호', | |
| strType: 'string' | |
| }, | |
| passwordUpdatedAt: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: false, | |
| defaultValue: Sequelize.DataTypes.NOW, | |
| validate: {}, | |
| title: '비밀번호 변경일자', | |
| strType: 'date' | |
| }, | |
| isAdmin: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '관리자 여부', | |
| enum: [ [true, '관리자'], [false, '일반사용자'] ], | |
| strType: 'boolean' | |
| }, | |
| isGlobalAdmin: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '글로벌 관리자 여부', | |
| strType: 'boolean' | |
| }, | |
| department: { | |
| type: 'string', len: 64, | |
| allowNull: true, | |
| validate: {}, | |
| title: '부서', | |
| strType: 'string' | |
| }, | |
| title: { | |
| type: 'string', len: 32, | |
| allowNull: true, | |
| validate: {}, | |
| title: '직책', | |
| strType: 'string' | |
| }, | |
| emailWork: { | |
| type: 'string', len: 64, | |
| allowNull: true, | |
| validate: {}, | |
| title: '회사 이메일', | |
| strType: 'string' | |
| }, | |
| emailHome: { | |
| type: 'string', len: 64, | |
| allowNull: true, | |
| validate: {}, | |
| title: '개인 이메일', | |
| strType: 'string' | |
| }, | |
| phoneMobile: { | |
| type: 'string', len: 32, | |
| allowNull: true, | |
| validate: {}, | |
| title: '핸드폰', | |
| strType: 'string' | |
| }, | |
| phoneWork: { | |
| type: 'string', len: 32, | |
| allowNull: true, | |
| validate: {}, | |
| title: '회사 전화', | |
| strType: 'string' | |
| }, | |
| phoneFax: { | |
| type: 'string', len: 32, | |
| allowNull: true, | |
| validate: {}, | |
| title: '팩스', | |
| strType: 'string' | |
| }, | |
| postalCode: { | |
| type: 'string', len: 8, | |
| allowNull: true, | |
| defaultValue: '', | |
| validate: {}, | |
| title: '우편번호', | |
| strType: 'string' | |
| }, | |
| address: { | |
| type: 'string', len: 128, | |
| allowNull: true, | |
| defaultValue: '', | |
| validate: {}, | |
| title: '주소', | |
| strType: 'string' | |
| }, | |
| addressDetail: { | |
| type: 'string', len: 128, | |
| allowNull: true, | |
| defaultValue: '', | |
| validate: {}, | |
| title: '상세 주소', | |
| strType: 'string' | |
| }, | |
| isGroup: { //--- 현재 사용하지 않음 | |
| type: 'boolean', | |
| allowNull: true, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '그룹 여부', | |
| strType: 'boolean' | |
| }, | |
| status: { | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: 'Active', | |
| validate: {}, | |
| title: '상태', | |
| strType: 'select', | |
| enum: [ ['Active', 'Active'], ['Inactive', 'Inactive'] ] //--- [value, title]의 배열 | |
| }, | |
| reportsTo: { //--- 현재 사용하지 않음 | |
| type: 'integer', len: 11, | |
| allowNull: true, | |
| defaultValue: -1, | |
| validate: {}, | |
| title: '상급자', | |
| strType: 'integer' | |
| }, | |
| originTo: { //--- 원본 user ID | |
| type: 'integer', len: 11, | |
| allowNull: true, | |
| defaultValue: -1, | |
| validate: {}, | |
| title: '원본 사용자', | |
| strType: 'integer' | |
| }, | |
| //--- To-Do : 향후 Role과 Group 모듈을 추가하여 권한 관리를 한다. | |
| roles: { //--- Group과 Role을 추가하여 권한 관리를 하기 전에 임시로 사용 한다. | |
| type: 'string', len: 32, | |
| allowNull: true, | |
| //--- 1 자리 : 정류기 관리자 (0. 사용자, 1. 관리자) | |
| defaultValue: '', | |
| validate: {}, | |
| title: '관리자 역할', | |
| strType: 'string', | |
| }, | |
| smsOptOut: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: true, | |
| validate: {}, | |
| title: 'SMS 알림 수신 여부', //--- true. SMS 수신 거부, false. SMS 수신 | |
| enum: [ [true, 'SMS 알림 수신 거부'], [false, 'SMS 알림 수신'] ], | |
| strType: 'boolean' | |
| }, | |
| homeExport: { //--- true. 홈 화면에 "Export" 버튼을 표시 한다. | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: 'Home Export 사용', | |
| strType: 'boolean', | |
| enum: [ ['false', 'Home Export 사용 않음'], ['true', 'Home Export 사용'] ] | |
| }, | |
| //--- view : 보고서를 웹 화면에서 조회하는 권한 (2020.07.22 권한 관리하는 코드가 없는 것으로 보임) | |
| //--- viewdown : 보고서를 웹 화면에서 조회하고 Excel로 다운로드하는 권한 | |
| report1: { | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: 'none', | |
| validate: {}, | |
| title: '보고서 권한', | |
| strType: 'select', | |
| enum: [ ['none', '없음'], ['view', '전기방식 시설물 점검 보고서 보기'], ['viewdown', '전기방식 시설물 점검 보고서 보기/저장'] ] | |
| }, | |
| report1Peroid: { //--- 전기방식 시설물 점검 보고서 보기/저장의 최대 기간 (D.일, M. 월, 관리자는 10년치를 볼 수 있음) | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: '5D', | |
| validate: {}, | |
| title: '보고서 조회 기간', | |
| strType: 'select', | |
| enum: [ ['5D', '5일'], ['10D', '10일'], ['1M', '1달'] ] | |
| }, | |
| mapChart: { //--- use. 지도 화면 하단에 챠트를 표시 | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: 'use', | |
| validate: {}, | |
| title: '지도 대시보드', | |
| strType: 'select', | |
| enum: [ ['use', '챠트 사용'], ['none', '챠트 사용 않음'] ] | |
| }, | |
| homeDetail: { //--- use. 홈 화면에서 홈(분할 화면) 사용 가능 | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: 'none', | |
| validate: {}, | |
| title: '홈(분할 화면)', | |
| strType: 'select', | |
| enum: [ ['none', '홈(분할 화면) 사용 않음'], ['use', '홈(분할 화면) 사용'] ] | |
| }, | |
| group: { | |
| type: 'integer', len: 11, | |
| allowNull: true, | |
| defaultValue: -1, | |
| validate: {}, | |
| title: '그룹', | |
| strType: 'integer' | |
| }, | |
| role: { | |
| type: 'integer', len: 11, | |
| allowNull: true, | |
| defaultValue: -1, | |
| validate: {}, | |
| title: '역할', | |
| strType: 'integer' | |
| }, | |
| menuMap: { //--- 지도 메뉴 지정 | |
| type: 'string', len: 32, | |
| allowNull: false, | |
| defaultValue: 'devices/dashboardMap', | |
| validate: {}, | |
| title: '지도 메뉴', | |
| strType: 'select', | |
| enum: [ ['devices/dashboardMap', '지도 대시보드'], ['devices/dashboardMap2', '전체 지도'] ] | |
| }, | |
| // allowApi: { | |
| // type: 'boolean', | |
| // allowNull: false, | |
| // defaultValue: false, | |
| // validate: { | |
| // }, | |
| // title: 'Open API 제어', | |
| // enum: [ ['none', '사용 불가'], ['user', '조회 권한'], ['admin', '제어 권한'] ], | |
| // strType: 'boolean' | |
| // }, | |
| apiAuthorization: { | |
| type: 'string', len: 8, | |
| allowNull: false, | |
| defaultValue: 'none', | |
| validate: {}, | |
| title: 'Open API 제어', | |
| strType: 'select', | |
| enum: [ ['none', '사용 불가'], ['user', '조회 권한'], ['admin', '제어 권한'] ], | |
| }, | |
| accessKey: { | |
| type: 'string', len: 64, | |
| allowNull: false, | |
| defaultValue: '', | |
| validate: {}, | |
| title: 'Access Key', | |
| strType: 'string' | |
| }, | |
| accessSecret: { | |
| type: 'string', len: 64, | |
| allowNull: false, | |
| defaultValue: '', | |
| validate: {}, | |
| title: 'Access Secret', | |
| strType: 'string' | |
| }, | |
| dashboard: { | |
| type: 'string', len: 16, | |
| allowNull: false, | |
| defaultValue: 'dashboard', | |
| validate: {}, | |
| title: '홈 화면', | |
| strType: 'select', | |
| enum: [ ['spaList', '사이트 대시보드'], ['spaMap', '지도 대시보드'], , ['dashboard', '기본 대시보드'] ] | |
| }, | |
| //--- 필드값 확인 | |
| emailConfirmDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '이메일 확인 일자', | |
| strType: 'date' | |
| }, | |
| mobileConfirmDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '핸드폰 확인 일자', | |
| strType: 'date' | |
| }, | |
| //--- 수신 거부 | |
| emailOptOut: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: true, | |
| validate: {}, | |
| title: '이메일 수신 거부', | |
| strType: 'boolean', | |
| enum: [ [true, '이메일 수신 거부'], [false, '이메일 수신'] ] | |
| }, | |
| emailDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '이메일 수신 거부 일자', //--- emailOptOut : true. 수신 거부 일자, false. 수신 허용 일자 | |
| strType: 'date' | |
| }, | |
| smsOptOut2: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: true, | |
| validate: {}, | |
| title: 'SMS 수신 거부', | |
| strType: 'boolean', | |
| enum: [ [true, 'SMS 수신 거부'], [false, 'SMS 수신'] ] | |
| }, | |
| smsDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: 'SMS 수신 거부 일자', //--- smsOptOut2 : true. 수신 거부 일자, false. 수신 허용 일자 | |
| strType: 'date' | |
| }, | |
| salesOptOut: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: true, | |
| validate: {}, | |
| title: '광고 수신 거부', | |
| strType: 'boolean', | |
| enum: [ [true, '광고 수신 거부'], [false, '광고 수신'] ] | |
| }, | |
| salesDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '광고 수신 거부 일자', //--- salesOptOut : true. 수신 거부 일자, false. 수신 허용 일자 | |
| strType: 'date' | |
| }, | |
| //--- 이용 동의 | |
| privacyAgreement: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '개인정보 이용 동의', | |
| strType: 'boolean', | |
| enum: [ [true, '개인정보 이용 동의'], [false, '개인정보 이용 거부'] ] | |
| }, | |
| privacyDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '개인정보 이용 동의 일자', //--- privacyAgreement : true. 개인정보 이용 동의 일자, false. 개인정보 이용 거부 일자 | |
| strType: 'date' | |
| }, | |
| termOfUse: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '이용 약관 동의', | |
| strType: 'boolean', | |
| enum: [ [true, '이용 약관 동의'], [false, '이용 약관 거부'] ] | |
| }, | |
| termOfUseDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '이용 약관 동의 일자', //--- termOfUse : true. 이용 약관 동의 일자, false. 이용 약관 거부 일자 | |
| strType: 'date' | |
| }, | |
| termOfUse2: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '위치 기반 서비스 이용 약관 동의', | |
| strType: 'boolean', | |
| enum: [ [true, '위치 기반 서비스 이용 약관 동의'], [false, '위치 기반 서비스 이용 약관 거부'] ] | |
| }, | |
| termOfUse2Date: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '위치 기반 서비스 이용 약관 동의 일자', //--- termOfUse2 : true. 위치 기반 서비스 이용 약관 동의 일자, false. 위치 기반 서비스 이용 약관 거부 일자 | |
| strType: 'date' | |
| }, | |
| promotion: { | |
| type: 'boolean', | |
| allowNull: false, | |
| defaultValue: false, | |
| validate: {}, | |
| title: '프로모션 정보 수신 동의', | |
| strType: 'boolean', | |
| enum: [ [true, '프로모션 정보 수신 동의'], [false, '프로모션 정보 수신 거부'] ] | |
| }, | |
| promotionDate: { | |
| type: 'date', //--- moment()로 값 지정 | |
| allowNull: true, | |
| defaultValue: null, | |
| validate: {}, | |
| title: '프로모션 정보 수신 동의 일자', //--- promotion : true. 프로모션 정보 수신 동의 일자, false. 프로모션 정보 수신 거부 일자 | |
| strType: 'date' | |
| } | |
| }, super.fieldDesc); | |
| //--- dashboard : 로그인 후 첫 화면 지정 | |
| // if ((config.service.name == 'service_scada_caprotec') || (config.service.name == 'service_scada_ursc')) { | |
| // fieldDescribes.dashboard = { | |
| // type: 'string', len: 8, | |
| // allowNull: false, | |
| // defaultValue: 'none', | |
| // validate: {}, | |
| // title: '홈 메뉴', | |
| // strType: 'select', | |
| // enum: [ ['list', '사이트 대시보드'], ['map', '지도 대시보드'], , ['old', '기본 대시보드'] ] | |
| // }; | |
| // } | |
| return fieldDescribes; | |
| } | |
| //--- 데이터 초기화 | |
| init() { | |
| // this.table.drop(); | |
| this.table | |
| .sync() //--- Table이 없는 경우 생성 | |
| .then(function() { //--- Default data 생성 | |
| let query = { where: { deleted: false } }; | |
| this.table.findAll(query) | |
| .then(function(data) { | |
| if (data.length == 0) { | |
| this.table.bulkCreate([ | |
| { | |
| name: 'globalAdmin', | |
| site: 1, | |
| authenticateId: 'globalAdmin@obcon.biz', | |
| hash: utils.getHash('demo1234demo1234'), | |
| passwordUpdatedAt: moment().format('YYYY-MM-DD HH:mm:ss'), | |
| isAdmin: true, | |
| isGlobalAdmin: true, | |
| status: 'Active', | |
| description: '', | |
| assignedUserId: 1, | |
| createdBy: 1, | |
| updatedBy: 1, | |
| deleted: false | |
| }, { | |
| name: 'admin', | |
| site: 1, | |
| authenticateId: 'admin@obcon.biz', | |
| hash: utils.getHash('demo1234demo1234'), | |
| passwordUpdatedAt: moment().format('YYYY-MM-DD HH:mm:ss'), | |
| isAdmin: true, | |
| isGlobalAdmin: false, | |
| status: 'Active', | |
| description: '', | |
| assignedUserId: 1, | |
| createdBy: 1, | |
| updatedBy: 1, | |
| deleted: false | |
| }, { | |
| name: 'globalAdmin', | |
| site: 2, | |
| authenticateId: 'globalAdmin@caprotec.co.kr', | |
| hash: utils.getHash('demo1234demo1234'), | |
| passwordUpdatedAt: moment().format('YYYY-MM-DD HH:mm:ss'), | |
| isAdmin: false, | |
| isGlobalAdmin: true, | |
| status: 'Active', | |
| description: '', | |
| assignedUserId: 2, | |
| createdBy: 2, | |
| updatedBy: 2, | |
| deleted: false | |
| } | |
| ]).catch(utils.obj.loggerError); | |
| } | |
| }.bind(this)); | |
| }.bind(this)); | |
| } | |
| _userToItem(userOrigin, site) { | |
| let item = {}; | |
| for (const name in this.fieldDesc) { | |
| switch(name) { | |
| case 'id': break; | |
| case 'originTo': item.originTo = userOrigin.id; | |
| case 'site': item.site = site; break; | |
| default: | |
| item[name] = userOrigin[name]; | |
| } | |
| } | |
| return item; | |
| } | |
| async updateOrigin(record) { | |
| try { | |
| const query = { where: { id: record, deleted: false } }; | |
| const user = await modules.users.model.table.findOne(query); | |
| if ((user != null) && (config.service.services.isMultiService) && (config.service.services.isShareUser)) { | |
| if (user.originTo != -1) { | |
| console.log(user.id, user.department); | |
| const userOrigin = await this.findBySiteAndAuthenticateId(user.site, user.authenticateId, true); | |
| console.log(userOrigin.id, userOrigin.department); | |
| if (userOrigin != null) { | |
| const item = this._userToItem(user, userOrigin.site); | |
| item.site = user.site; | |
| await modules.users.model.table.update(item, { where: { id: user.id, deleted: false }}); | |
| item.site = userOrigin.site; | |
| item.originTo = -1; | |
| const results = await modules.users.model.table.update(item, { where: { id: userOrigin.id, deleted: false }}); | |
| } | |
| } | |
| } | |
| } catch(err) { | |
| utils.obj.loggerError(err); | |
| } | |
| } | |
| //--- site : -1. 사이트를 지정 하지 않음 | |
| //--- select id, name, site, authenticateId, originTo, phoneMobile, emailWork from users order by site asc, authenticateId asc; | |
| //--- delete from users where id = 5; | |
| async findBySiteAndAuthenticateId(site, authenticateId, wantOrigin=false) { | |
| try { | |
| //--- 모든 사용자 읽기 | |
| const query = { where: { authenticateId: authenticateId, deleted: false } }; | |
| const users = await modules.users.model.table.findAll(query); | |
| if (users.length == 0) { | |
| return null; | |
| } | |
| if (config.service.services.isMultiService) { | |
| const usersBySite = users.filter(user => user.site == site); | |
| if (config.service.services.isShareUser) { | |
| const usersByOriginTo = users.filter(user => user.originTo == -1); | |
| if (usersByOriginTo.length == 0) { | |
| logger.error('Origin user is not exist.') | |
| return null; | |
| } | |
| const userOrigin = usersByOriginTo[0]; | |
| const item = this._userToItem(userOrigin, site); | |
| if (usersBySite.length == 0) { | |
| //--- 사용자 생성 | |
| const user = await modules.users.model.table.create(item); | |
| return (wantOrigin) ? userOrigin:(user || null); | |
| } else { | |
| if (usersBySite[0].originTo == -1) { | |
| return usersBySite[0]; | |
| } else { | |
| const results = await modules.users.model.table.update(item, { where: { id: usersBySite[0].id, deleted: false }}); | |
| query.where.site = site; | |
| const user = await modules.users.model.table.findOne(query); | |
| return (wantOrigin) ? userOrigin:user; | |
| } | |
| } | |
| } else { | |
| return (0 < usersBySite.length) ? usersBySite[0]:null; | |
| } | |
| } else { | |
| return users[0]; | |
| } | |
| } catch(err) { | |
| utils.obj.loggerError(err); | |
| } | |
| return null; | |
| } | |
| async isFindBySiteAndAuthenticateId(site, authenticateId) { | |
| try { | |
| //--- 모든 사용자 읽기 | |
| const users = await modules.users.model.table.findAll({ where: { authenticateId: authenticateId, deleted: false } }); | |
| // if (users.length == 0) { | |
| // return false; | |
| // } | |
| // if ((config.service.services.isMultiService) && (config.service.services.isShareUser == false)) { | |
| // const usersBySite = users.filter(user => user.site == site); | |
| // return (0 < usersBySite.length); | |
| // } | |
| if (config.service.services.isMultiService) { | |
| if (config.service.services.isShareUser) { | |
| return (0 < users.length); | |
| } else { | |
| const usersBySite = users.filter(user => user.site == site); | |
| return (0 < usersBySite.length); | |
| } | |
| } else { | |
| const usersBySite = users.filter(user => user.site == site); | |
| return (0 < usersBySite.length); | |
| } | |
| } catch(err) { | |
| utils.obj.loggerError(err); | |
| } | |
| return true; | |
| } | |
| } | |
| module.exports = UsersModel; | |