'use strict'; /** * * * @author Mai * @date * @version */ const auditConst = require('../const/audit'); const accountGroup = require('../const/account_group').group; const sendToWormhole = require('stream-wormhole'); const path = require('path'); const projectSetting = require('../const/project_setting'); module.exports = app => { class SubProjController extends app.BaseController { async _loadCount(projectList){ for (const p of projectList) { p.tender_count = await this.ctx.service.tender.count({ spid: p.id }); p.contract_count = await this.ctx.service.contract.count({ spid: p.id }); p.file_count = await this.ctx.service.file.count({ spid: p.id, is_deleted: 0 }); } } /** * 概算投资 * * @param ctx * @returns {Promise} */ async index(ctx) { try { const renderData = { jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.list), auditConst, }; renderData.budgetStd = await ctx.service.budgetStd.getDataByProjectId(ctx.session.sessionProject.id); renderData.projectList = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin); await this._loadCount(renderData.projectList); renderData.tenderList = await ctx.service.tender.getManageTenderList(ctx.session.sessionProject.id); const accountList = await ctx.service.projectAccount.getAllDataByCondition({ columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'], where: { project_id: ctx.session.sessionProject.id } }); renderData.accountList = accountList; const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } }); renderData.accountGroup = unitList.map(item => { const groupList = accountList.filter(item1 => item1.company === item.name); return { groupName: item.name, groupList }; }).filter(x => { return x.groupList.length > 0; }); renderData.permissionConst = ctx.service.subProjPermission.PermissionConst; renderData.companys = await this.ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } }); renderData.templates = await this.ctx.service.filingTemplateList.getAllTemplate(ctx.session.sessionProject.id); await this.layout('sub_proj/index.ejs', renderData, 'sub_proj/modal.ejs'); } catch (err) { ctx.log(err); ctx.session.postError = err.toString(); ctx.redirect(this.menu.menu.dashboard.url); } } async addFolder(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.name || data.name.length > 100) throw '文件夹名称有误'; const result = await ctx.service.subProject.addFolder(data); await this._loadCount(result); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '新建文件夹失败'); } } async addProj(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.name || data.name.length > 100) throw '项目名称有误'; const result = await ctx.service.subProject.addSubProject(data); await this._loadCount(result); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '新建项目失败'); } } async dragTo(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.drag_id || !data.drop_id) throw '提交数据错误'; const result = await ctx.service.subProject.dragTo(data); await this._loadCount(result); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '调整所属文件夹失败'); } } async move(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id || !data.type) throw '提交数据错误'; const result = await ctx.service.subProject.move(data); await this._loadCount(result); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '调整所属文件夹失败'); } } async del(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id) throw '参数有误'; const result = await ctx.service.subProject.del(data.id); ctx.body = { err: 0, msg: '', data: result }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '删除项目失败'); } } async save(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id) throw '参数有误'; let result = null; if (data.name !== undefined) { if (!data.name || data.name.length > 100) throw '项目名称有误'; result = await ctx.service.subProject.save({ id: data.id, name: data.name }); } else if (data.rela_tender !== undefined) { result = await ctx.service.subProject.setRelaTender({ id: data.id, rela_tender: data.rela_tender }); } else if (data.std_id !== undefined) { result = await ctx.service.subProject.setBudgetStd({ id: data.id, std_id: data.std_id }); } else if (data.management !== undefined) { result = await ctx.service.subProject.setManagement({ id: data.id, management: data.management, filingTemplate: data.filingTemplate }); } ctx.body = { err: 0, msg: '', data: { update: [result] } }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '保存数据失败'); } } async refresh(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id) throw '参数有误'; const result = await ctx.service.subProject.refreshManagementPermission({ id: data.id }); ctx.body = { err: 0, msg: '', data: result }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '保存数据失败'); } } async rela(ctx) { try { const id = ctx.query.id; const projectList = await ctx.service.subProject.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, true); const otherProj = projectList.filter(x => { return x.id !== id || !x.rela_tender || x.is_folder }); const _ = ctx.helper._; const otherRela = _.map(_.map(otherProj, 'rela_tender').join(',').split(','), _.toInteger); const tenderList = await ctx.service.tender.getList4Select('stage'); ctx.body = { err: 0, msg: '', data: tenderList.filter(x => { return otherRela.indexOf(x.id) === -1}) .map(y => { return {id: y.id, name: y.name, lastStageOrder: y.lastStage.order, lastStageStatus: auditConst.stage.statusString[y.lastStage.status], category: y.category}}), }; } catch (err) { ctx.log(err); ctx.postError(err, '获取数据失败'); } } async saveRela(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id || data.rela_tender === undefined) throw '参数有误'; const permission = ctx.session.sessionUser.is_admin ? ctx.service.subProjPermission.adminPermission : await ctx.service.subProjPermission.getSubProjectUserPermission(data.id, ctx.session.sessionUser.accountId); if (!permission || permission.manage_permission.indexOf(ctx.service.subProjPermission.PermissionConst.manage.rela.value) < 0) throw '您无权进行该操作'; const result = await ctx.service.subProject.setRelaTender({ id: data.id, rela_tender: data.rela_tender || '' }); ctx.body = { err: 0, msg: '', data: { update: [result] } }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '保存数据失败'); } } async member(ctx) { try { const data = JSON.parse(ctx.request.body.data); const member = await ctx.service.subProjPermission.getPermission(data.id); ctx.body = { err: 0, msg: '', data: member }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '查询项目成员失败'); } } async memberSave(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.id) throw '参数有误'; await ctx.service.subProjPermission.savePermission(data.id, data.member); ctx.body = { err: 0, msg: '', data: '' }; } catch (err) { ctx.log(err); ctx.ajaxErrorBody(err, '保存数据失败'); } } _checkInfoEditPermission() { if (this.ctx.subProject.permission.info_permission.indexOf(this.ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0) { throw '暂无权编辑项目概况信息'; } } async info(ctx) { try { const info = await this.ctx.service.subProjInfo.getInfo(ctx.subProject.id); info.lx_tp = await this.ctx.service.budgetGu.getSumTp(ctx.subProject.budget_id); info.cb_tp = await this.ctx.service.budgetGai.getSumTp(ctx.subProject.budget_id); info.sgt_tp = await this.ctx.service.budgetYu.getSumTp(ctx.subProject.budget_id); info.zbys_tp = await this.ctx.service.budgetZb.getSumTp(ctx.subProject.budget_id); const renderData = { info, jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.info), readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0, }; await this.layout('sub_proj/info.ejs', renderData); } catch (err) { ctx.log(err); } } async dataIndex(ctx) { try { const info = await this.ctx.service.subProjInfo.getInfo(ctx.subProject.id); const renderData = { info, jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.data), readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0, }; await this.layout('sub_proj/data_index.ejs', renderData); } catch (err) { ctx.log(err); } } async saveInfo(ctx) { try { this._checkInfoEditPermission(); const data = JSON.parse(ctx.request.body.data); const result = await ctx.service.subProjInfo.saveInfo(ctx.subProject.id, data); ctx.body = { err: 0, msg: '', data: result }; } catch(err) { ctx.log(err); } } async progress(ctx) { try { const fileReferenceList = await ctx.service.subProject.getFileReference(ctx.subProject, ctx.service.subProject.FileReferenceType.info_progress); const renderData = { jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.progress), fileReferenceList, readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0, }; await this.layout('sub_proj/progress.ejs', renderData, 'sub_proj/progress_modal.ejs'); } catch (err) { ctx.log(err); ctx.postError(err, '查看阶段进度') } } async load(ctx) { try { const data = JSON.parse(ctx.request.body.data); const filter = data.filter.split(';'); const result = {}; for (const f of filter) { switch(f) { case 'progress': result[f] = await ctx.service.subProjProgress.getData(ctx.subProject); break; case 'progress_file': result[f] = await ctx.service.subProjFile.getData(ctx.subProject.id, 'progress'); break; case 'push': result[f] = await ctx.service.subProjPush.getData(ctx.subProject.id); break; case 'push_file': result[f] = await ctx.service.subProjFile.getData(ctx.subProject.id, 'push'); break; default: continue; } } ctx.body = { err: 0, msg: '', data: result }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '获取阶段进度数据有误'); } } async _progressBase(subProj, type, data) { if (isNaN(data.id) || data.id <= 0) throw '数据错误'; if (type !== 'add') { if (isNaN(data.count) || data.count <= 0) data.count = 1; } switch (type) { case 'add': return await this.ctx.service.subProjProgress.addProgressNode(subProj.id, data.id, data.count); case 'delete': return await this.ctx.service.subProjProgress.delete(subProj.id, data.id, data.count); case 'up-move': return await this.ctx.service.subProjProgress.upMoveNode(subProj.id, data.id, data.count); case 'down-move': return await this.ctx.service.subProjProgress.downMoveNode(subProj.id, data.id, data.count); case 'up-level': return await this.ctx.service.subProjProgress.upLevelNode(subProj.id, data.id, data.count); case 'down-level': return await this.ctx.service.subProjProgress.downLevelNode(subProj.id, data.id, data.count); } } async progressUpdate(ctx) { try { this._checkInfoEditPermission(); const data = JSON.parse(ctx.request.body.data); if (!data.postType || !data.postData) throw '数据错误'; const responseData = { err: 0, msg: '', data: {} }; switch (data.postType) { case 'add': case 'delete': case 'up-move': case 'down-move': case 'up-level': case 'down-level': responseData.data = await this._progressBase(ctx.subProject, data.postType, data.postData); break; case 'update': responseData.data = await this.ctx.service.subProjProgress.updateInfos(ctx.subProject.id, data.postData); break; case 'add-std': responseData.data = await this.ctx.service.subProjProgress.addStdNode(ctx.subProject, data.postData.id, data.postData.stdData); break; default: throw '未知操作'; } ctx.body = responseData; } catch (err) { ctx.log(err); ctx.body = this.ajaxErrorBody(err, '数据错误'); } } async push(ctx) { try { const renderData = { jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.push), readOnly: ctx.subProject.permission.info_permission.indexOf(ctx.service.subProjPermission.PermissionConst.info.edit.value) < 0, }; await this.layout('sub_proj/push.ejs', renderData, 'sub_proj/push_modal.ejs'); } catch (err) { ctx.log(err); } } async pushUpdate(ctx) { try { this._checkInfoEditPermission(); const data = JSON.parse(ctx.request.body.data); const result = await ctx.service.subProjPush.updateDatas(data); ctx.body = { err: 0, msg: '', data: result }; } catch (error) { ctx.log(error); ctx.body = this.ajaxErrorBody(error, '提交数据失败,请重试'); } } /** * 上传附件 * @param {Object} ctx - egg全局变量 * @return {void} */ async uploadFile(ctx) { let stream; try { const parts = ctx.multipart({autoFields: true}); let index = 0; const create_time = Date.parse(new Date()) / 1000; let stream = await parts(); const user = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId); const rela_id = parts.field.rela_id; const uploadfiles = []; while (stream !== undefined) { if (!stream.filename) throw '未发现上传文件!'; const fileInfo = path.parse(stream.filename); const filepath = `sp/progress/${ctx.subProject.id}/${ctx.moment().format('YYYYMMDD')}/${create_time + '_' + index + fileInfo.ext}`; // 保存文件 await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream); await sendToWormhole(stream); // 插入到stage_pay对应的附件列表中 uploadfiles.push({ rela_id, filename: fileInfo.name, fileext: fileInfo.ext, filesize: Array.isArray(parts.field.size) ? parts.field.size[index] : parts.field.size, filepath, }); ++index; if (Array.isArray(parts.field.size) && index < parts.field.size.length) { stream = await parts(); } else { stream = undefined; } } const result = await ctx.service.subProjFile.addFiles(ctx.subProject.id, ctx.request.url.split('/')[3], uploadfiles, user); ctx.body = {err: 0, msg: '', data: result}; } catch (error) { ctx.log(error); // 失败需要消耗掉stream 以防卡死 if (stream) await sendToWormhole(stream); ctx.body = this.ajaxErrorBody(error, '上传附件失败,请重试'); } } async uploadBigFile(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.type || !data.rela_id || !data.fileInfo) throw '缺少参数'; let result; const fileInfo = path.parse(data.fileInfo.filename); switch(data.type) { case 'begin': const create_time = Date.parse(new Date()) / 1000; result = { filename: `sp/progress/${ctx.subProject.id}/${ctx.moment().format('YYYYMMDD')}/${create_time + '_' + fileInfo.ext}`, }; result.filepath = ctx.app.config.fujianOssFolder + result.filename; result.oss = await ctx.helper.getOssToken(ctx.app.fujianOss); break; case 'end': const user = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId); const uploadFiles = [{ filepath: data.filepath, rela_id: data.rela_id, filename: fileInfo.name, fileext: fileInfo.ext, filesize: data.fileInfo.filesize, }]; result = await ctx.service.subProjFile.addFiles(ctx.subProject.id, ctx.request.url.split('/')[3], uploadFiles, user); break; } ctx.body = {err: 0, msg: '', data: result }; } catch (error) { ctx.log(error); ctx.body = this.ajaxErrorBody(error, '上传附件失败,请重试'); } } async deleteFile(ctx) { try{ const data = JSON.parse(ctx.request.body.data); if (!data) throw '缺少参数'; const result = await ctx.service.subProjFile.delFiles(data); ctx.body = { err: 0, msg: '', data: result }; } catch(error) { ctx.log(error); ctx.ajaxErrorBody(error, '删除附件失败'); } } async noPermission(ctx) { ctx.controllerName = ctx.params.block; await this.layout('sub_proj/no_permission.ejs'); } /** * 保存列设置 * @param ctx * @returns {Promise} */ async colSet(ctx) { try { const colType = ctx.request.body.col_type; const colSet = JSON.parse(ctx.request.body.col_set); await ctx.service.projectColSet.setProjectColSet(ctx.session.sessionProject.id, ctx.subProject ? ctx.subProject.id : '', colType, colSet); ctx.redirect(ctx.request.header.referer); } catch (err) { ctx.log(err); ctx.redirect(ctx.request.header.referer); } } async listInfo(ctx) { try { const renderData = { jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.listInfo), }; const projectColSet = await ctx.service.projectColSet.getProjectColSet(ctx.session.sessionProject.id); renderData.colSet = ctx.service.projectColSet.analysisColSetWithDefine(projectSetting.colSet.projectInfo, projectColSet.info, projectSetting.defaultProjectColSet.info); renderData.projectList = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin); await this._loadCount(renderData.projectList); await this.layout('sub_proj/list_info.ejs', renderData, 'sub_proj/list_info_modal.ejs'); } catch (err) { ctx.log(err); ctx.postError(err, '加载金额概况数据错误'); ctx.redirect(this.menu.menu.dashboard.url); } } async refreshInfoCache(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.spid) throw '参数错误'; const subProjectId = data.spid.split(';'); const result = []; for (const spid of subProjectId ) { const tp_cache = await ctx.service.subProject.refreshTpCache(spid, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin); result.push({ id: spid, tp_cache }); } ctx.body = { err: 0, msg: '', data: result }; } catch(err) { ctx.log(err); ctx.ajaxErrorBody(err, '刷新金额概况数据失败'); } } } return SubProjController; };