'use strict'; /** * 标段管理控制器 * * @author CaiAoLin * @date 2018/2/5 * @version */ const tenderConst = require('../const/tender'); const codeRuleConst = require('../const/code_rule'); const settingConst = require('../const/setting.js'); const tenderMenu = require('../../config/menu').tenderMenu; const auditConst = require('../const/audit'); const shenpiConst = require('../const/shenpi'); const accountGroup = require('../const/account_group').group; const accountPermission = require('../const/account_permission'); const measureType = require('../const/tender').measureType; const billsPosConvert = require('../lib/bills_pos_convert'); const path = require('path'); const sendToWormhole = require('stream-wormhole'); const scheduleConst = require('../const/schedule'); const changeConst = require('../const/change'); const tenderInfoModel = require('../lib/tender_info'); const mapConst = require('../const/map'); module.exports = app => { class TenderController extends app.BaseController { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); ctx.showProject = true; ctx.showTitle = true; } async _getLedgerAuditInfo(tender) { tender.cur_flow = { title: '台账', status: auditConst.ledger.tiStatusString[tender.ledger_status], status_class: auditConst.ledger.tiStatusStringClass[tender.ledger_status], }; if (tender.ledger_status === auditConst.ledger.status.uncheck) { tender.cur_flow.name = tender.user_name; } else { const cur = tender.ledger_status === auditConst.ledger.status.checkNo ? await this.ctx.service.ledgerAudit.getLastestAuditor(tender.id, tender.ledger_times - 1, auditConst.ledger.status.checkNo) : await this.ctx.service.ledgerAudit.getLastestAuditor(tender.id, tender.ledger_times, tender.ledger_status); if (cur) { tender.cur_flow.name = cur.name; if (cur.audit_order === 1) { tender.pre_flow = { name: tender.user_name, time: cur.begin_time }; } else { const pre = await this.ctx.service.ledgerAudit.getAuditorByOrder(tender.id, cur.audit_order - 1, cur.times); if (pre) tender.pre_flow = { name: pre.name, time: pre.end_time }; } } else { tender.cur_flow.name = ''; } } } async _getStageAuditInfo(tender, stage) { tender.cur_flow = { title: '第' + stage.order + '期', status: auditConst.stage.tiStatusString[stage.status], status_class: auditConst.stage.tiStatusStringClass[stage.status], }; if (stage.status === auditConst.stage.status.uncheck) { if (tender.user_id === stage.user_id) { tender.cur_flow.name = tender.user_name; } else { const user = await this.ctx.service.projectAccount.getDataById(stage.user_id); tender.cur_flow.name = user.name; } if (stage.order > 1) { const preStage = await this.ctx.service.stage.getDataByCondition({ tid: tender.id, order: stage.order - 1 }); if (!preStage) return; const pre = await this.ctx.service.stageAudit.getLastestAuditor(preStage.id, preStage.times, auditConst.stage.status.checked); if (pre) tender.pre_flow = { name: pre.name, time: pre.end_time }; } } else { let cur; if (stage.status === auditConst.stage.status.checkNo) { cur = await this.ctx.service.stageAudit.getLastestAuditor(stage.id, stage.times - 1, auditConst.stage.status.checkNo); } else if (stage.status === auditConst.stage.status.checked) { cur = await this.ctx.service.stageAudit.getLastestAuditor(stage.id, stage.times, auditConst.stage.status.checked); } else { cur = await this.ctx.service.stageAudit.getCurAuditor(stage.id, stage.times); } if (cur) { tender.cur_flow.name = cur.name; if (cur.order === 1) { tender.pre_flow = {}; if (tender.user_id === stage.user_id) { tender.pre_flow.name = tender.user_name; } else { const user = await this.ctx.service.projectAccount.getDataById(stage.user_id); tender.pre_flow.name = user.name; } tender.pre_flow.time = cur.begin_time; } else { const pre = await this.ctx.service.stageAudit.getAuditorByOrder(stage.id, cur.order - 1, cur.times); if (pre) tender.pre_flow = { name: pre.name, time: pre.end_time }; } } else { tender.cur_flow.name = ''; } } } async _listDetail(view, modal = '') { try { // 获取用户新建标段权利 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; const tenderList = await this.ctx.service.tender.getList('', userPermission, this.ctx.session.sessionUser.is_admin); for (const t of tenderList) { if (t.user_id === this.ctx.session.sessionUser.accountId && ( t.ledger_status === auditConst.ledger.status.checkNo || t.ledger_status === auditConst.ledger.status.uncheck)) { const sum = await this.ctx.service.ledger.addUp({ tender_id: t.id/* , is_leaf: true*/ }); t.total_price = sum.total_price; t.deal_tp = sum.deal_tp; } t.advance_tp = await this.ctx.service.advance.getSumAdvance(t.id); if (t.ledger_status === auditConst.ledger.status.checked) { t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true); if (t.lastStage && t.lastStage.status === auditConst.stage.status.uncheck && t.lastStage.user_id !== this.ctx.session.sessionUser.accountId) { t.lastStage = await this.ctx.service.stage.getLastestStage(t.id); } if (t.lastStage) await this.ctx.service.stage.checkStageGatherData(t.lastStage); t.completeStage = await this.ctx.service.stage.getLastestCompleteStage(t.id); } if (t.lastStage) { await this._getStageAuditInfo(t, t.lastStage); } else { await this._getLedgerAuditInfo(t); } } const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id); const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id); const renderData = { tenderList, tenderConst, settingConst, categoryData, measureType: tenderConst.measureType, jsFiles: this.app.jsFiles.common.concat(this.jsFiles), auditConst, userPermission, valuations, uid: this.ctx.session.sessionUser.accountId, pid: this.ctx.session.sessionProject.id, }; await this.layout(view, renderData, modal); } catch (err) { this.log(err); this.ctx.redirect('/dashboard'); } } async _list(view, renderData, modal = '', list_status = '') { try { renderData.tenderList = await this.ctx.service.tender.getList(list_status, renderData.userPermission, this.ctx.session.sessionUser.is_admin); for (const t of renderData.tenderList) { if (t.ledger_status === auditConst.ledger.status.checked) { t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true); t.completeStage = await this.ctx.service.stage.getLastestCompleteStage(t.id); } if (t.lastStage) { if (t.lastStage.status === auditConst.stage.status.uncheck) { const status_name = await this.ctx.service.projectAccount.getAccountInfoById(t.lastStage.user_id); t.status_users = status_name ? status_name.name : ''; // const status_name = await this.ctx.service.stageAudit.getStatusName(t.lastStage.id, t.lastStage.times - 1); // t.status_users = status_name ? status_name.name : ''; } else { const status_name = await this.ctx.service.stageAudit.getAuditorByStatus(t.lastStage.id, t.lastStage.status, t.lastStage.times); t.status_users = status_name ? status_name.name : ''; } } else { if (t.ledger_status !== auditConst.ledger.status.uncheck) { const status_name = await this.ctx.service.ledgerAudit.getStatusName(t.id, t.ledger_times); t.status_users = status_name ? status_name.name : ''; } } } renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id); renderData.valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id); renderData.tenderConst = tenderConst; renderData.settingConst = settingConst; renderData.measureType = tenderConst.measureType; renderData.jsFiles = this.app.jsFiles.common.concat(this.jsFiles); renderData.auditConst = auditConst; renderData.uid = this.ctx.session.sessionUser.accountId; renderData.pid = this.ctx.session.sessionProject.id; await this.layout(view, renderData, modal); } catch (err) { this.log(err); this.ctx.redirect('/dashboard'); } } async listDefault(ctx) { this.jsFiles = this.app.jsFiles.tender.list; const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; const renderData = { accountInfo, userPermission, }; await this._list('tender/index.ejs', renderData, 'tender/modal.ejs'); } /** * 标段概况(Get) * * @param {object} ctx - egg全局变量 * @return {void} */ async listInfo(ctx) { this.jsFiles = this.app.jsFiles.tender.info; await this._listDetail('tender/info.ejs', 'tender/modal.ejs'); } /** * 计量进度(Get) * * @param ctx * @return {Promise} */ async listProgress(ctx) { this.jsFiles = this.app.jsFiles.tender.progress; await this._listDetail('tender/progress.ejs', 'tender/modal.ejs'); } /** * 标段管理(Get) * * @param ctx * @return {Promise} */ async listManage(ctx) { this.jsFiles = this.app.jsFiles.tender.manage; // 先判断权限 // 获取用户新建标段权利 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) { const renderData = { accountInfo, userPermission, }; await this._list('tender/manage.ejs', renderData, 'tender/manage_modal.ejs', 'manage'); // 获取用户新建标段权利 // const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); // const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; // // const tenderList = await this.ctx.service.tender.getList('manage', userPermission); // for (const t of tenderList) { // t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, true); // t.completeStage = await this.ctx.service.stage.getLastestCompleteStage(t.id); // } // const categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id); // const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id); // const renderData = { // tenderList, // tenderConst, // settingConst, // categoryData, // measureType: tenderConst.measureType, // jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.manage), // auditConst, // userPermission, // valuations, // }; // await this.layout('tender/manage.ejs', renderData, 'tender/manage_modal.ejs'); } else { this.ctx.redirect(ctx.request.header.referer); } } /** * 新增标段(Ajax) * * @param ctx * @return {Promise} */ async addTender(ctx) { try { const responseData = { err: 0, msg: '', data: null, }; // 获取用户新建标段权利 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; if (userPermission === null || userPermission.tender === undefined || userPermission.tender.indexOf('1') === -1) { throw '当前用户没有创建标段的权限'; } const data = JSON.parse(ctx.request.body.data); if (!data.name || data.name === '' || !data.valuation) { throw '标段信息不完整'; } responseData.data = await ctx.service.tender.add(data); ctx.body = responseData; } catch (error) { this.log(error); ctx.body = { err: 1, msg: error.toString(), data: null }; } } /** * 编辑标段(Ajax) * * @param ctx * @return {Promise} */ async updateTender(ctx) { try { const responseData = { err: 0, msg: '', data: null, }; const data = JSON.parse(ctx.request.body.data); if (!data.id) { throw '提交信息错误'; } if (!data.name || data.name === '') { throw '标段信息不完整'; } if (await ctx.service.tender.save(data, data.id)) { responseData.data = await ctx.service.tender.getTender(data.id); } ctx.body = responseData; } catch (error) { this.log(error); ctx.body = { err: 1, msg: error.toString(), data: null }; } } /** * 删除标段(Ajax) * * @param ctx * @return {Promise} */ async deleteTender(ctx) { try { const data = JSON.parse(ctx.request.body.data), result = []; if (!(data instanceof Array) && (data.length === 0)) { throw '提交数据有误'; } for (const id of data) { if (await ctx.service.tender.deleteTenderNoBackup(id)) { result.push(id); } } ctx.body = { err: 0, msg: '', data: result }; } catch (err) { ctx.body = { err: 1, msg: err.toString(), data: [] }; } } /** * 标段概况(Get) * * @param ctx * @return {Promise} */ async tenderInfo(ctx) { try { const tender = ctx.tender.data; if (tender.user_id === this.ctx.session.sessionUser.accountId && ( tender.ledger_status === auditConst.ledger.status.checkNo || tender.ledger_status === auditConst.ledger.status.uncheck)) { const sum = await this.ctx.service.ledger.addUp({ tender_id: tender.id/* , is_leaf: true*/ }); tender.total_price = sum.total_price; tender.deal_tp = sum.deal_tp; } const stages = await ctx.service.stage.getValidStages(ctx.tender.id); const lastStage = stages.length > 0 ? stages[0] : null; // await ctx.service.stage.getLastestStage(ctx.tender.id); if (lastStage) { await this.ctx.service.stage.checkStageGatherData(lastStage); tender.gather_tp = ctx.helper.add(lastStage.contract_tp, lastStage.qc_tp); tender.end_contract_tp = ctx.helper.add(lastStage.contract_tp, lastStage.pre_contract_tp); tender.end_qc_tp = ctx.helper.add(lastStage.qc_tp, lastStage.pre_qc_tp); tender.end_gather_tp = ctx.helper.add(tender.end_contract_tp, tender.end_qc_tp); tender.pre_gather_tp = ctx.helper.add(lastStage.pre_contract_tp, lastStage.pre_qc_tp); tender.yf_tp = lastStage.yf_tp; tender.qc_ratio = ctx.helper.mul(ctx.helper.div(tender.end_qc_tp, ctx.tender.info.deal_param.contractPrice, 2), 100); tender.sum = ctx.helper.add(tender.total_price, tender.end_qc_tp); tender.pre_ratio = ctx.helper.mul(ctx.helper.div(tender.pre_gather_tp, tender.sum, 2), 100); tender.cur_ratio = ctx.helper.mul(ctx.helper.div(tender.gather_tp, tender.sum, 2), 100); tender.other_tp = ctx.helper.sub(ctx.helper.sub(tender.sum, tender.pre_gather_tp), tender.gather_tp); tender.other_ratio = Math.max(0, 100 - tender.pre_ratio - tender.cur_ratio); tender.end_yf_tp = ctx.helper.add(lastStage.yf_tp, lastStage.pre_yf_tp); tender.end_sf_tp = ctx.helper.add(lastStage.sf_tp, lastStage.pre_sf_tp); const change_tp = await ctx.service.change.getChangeTp(tender.id); tender.undone_tp = ctx.helper.sub(ctx.helper.sub(ctx.helper.add(tender.total_price, change_tp), tender.end_contract_tp), tender.end_qc_tp); if (lastStage.status === auditConst.stage.status.uncheck) { const status_name = await this.ctx.service.projectAccount.getAccountInfoById(lastStage.user_id); lastStage.status_users = status_name ? status_name.name : ''; lastStage.auditors = []; } else { lastStage.status = lastStage.status === auditConst.stage.status.checkNoPre ? auditConst.stage.status.checking : lastStage.status; let cur; if (lastStage.status === auditConst.stage.status.checked) { cur = await this.ctx.service.stageAudit.getLastestAuditor(lastStage.id, lastStage.times, auditConst.stage.status.checked); } else if (lastStage.status === auditConst.stage.status.checking) { cur = await this.ctx.service.stageAudit.getCurAuditor(lastStage.id, lastStage.times); } else { cur = await this.ctx.service.stageAudit.getAuditorByStatus(lastStage.id, lastStage.status, lastStage.times); } // const status_name = await this.ctx.service.stageAudit.getAuditorByStatus(lastStage.id, lastStage.status, lastStage.times); lastStage.status_users = cur ? cur.name : ''; const times = lastStage.status === auditConst.stage.status.checkNo ? lastStage.times - 1 : lastStage.times; lastStage.auditors = await ctx.service.stageAudit.getFinalAuditGroup(lastStage.id, times); } } else { if (tender.ledger_status !== auditConst.ledger.status.uncheck) { const status_name = await this.ctx.service.ledgerAudit.getStatusName(tender.id, tender.ledger_times); tender.status_users = status_name ? status_name.name : ''; const times = tender.ledger_status === auditConst.ledger.status.checkNo ? tender.ledger_times - 1 : tender.ledger_times; tender.auditors = await ctx.service.ledgerAudit.getFinalAuditGroup(tender.id, times); } else { const status_name = await this.ctx.service.projectAccount.getAccountInfoById(tender.user_id); tender.status_users = status_name ? status_name.name : ''; } } const tiModel = new tenderInfoModel(ctx); const gclChapter = await tiModel.gatherChapter(); const monthProgress = []; for (const s of stages) { if (s.s_time) { let progress = monthProgress.find(function(x) { return x.month === s.s_time; }); if (!progress) { progress = { month: s.s_time }; monthProgress.push(progress); } progress.tp = ctx.helper.add(ctx.helper.add(progress.tp, s.contract_tp), s.qc_tp); } } monthProgress.sort(function(x, y) { return Date.parse(x.month) - Date.parse(y.month); }); let sum = 0; for (const p of monthProgress) { p.ratio = ctx.helper.mul(ctx.helper.div(p.tp, tender.sum, 4), 100); sum = ctx.helper.add(sum, p.tp); p.end_tp = sum; p.end_ratio = ctx.helper.mul(ctx.helper.div(p.end_tp, tender.sum, 4), 100); } const revise = await ctx.service.ledgerRevise.getLastestRevise(tender.id); const tenders = await ctx.service.tender.getList('', null, 1); const categoryData = await ctx.service.category.getAllCategory(ctx.session.sessionProject.id); // 变更图表数据 const change_done_total = await ctx.service.change.getCountByStatus2(tender.id, auditConst.filter.status.checked); const change_doing_total = await ctx.service.change.getCountByStatus2(tender.id, auditConst.filter.status.checking); const change_uncheck_total = await ctx.service.change.getCountByStatus2(tender.id, auditConst.filter.status.uncheck); const change_status_total = [ { num: change_uncheck_total, name: '待上报' }, { num: change_doing_total, name: '审批中' }, { num: change_done_total, name: '已完成' }, ]; const change_common_total = await ctx.service.change.getCountByQuality(tender.id, changeConst.quality.common.value); const change_more_total = await ctx.service.change.getCountByQuality(tender.id, changeConst.quality.more.value); const change_great_total = await ctx.service.change.getCountByQuality(tender.id, changeConst.quality.great.value); const change_quality_total = [ { num: change_common_total, name: '一般变更' }, { num: change_more_total, name: '较大变更' }, { num: change_great_total, name: '重大变更' }, ]; // 调差最新期数据 const materials = await ctx.service.material.getValidMaterials(ctx.tender.id); let materialData = null; if (materials && materials.length > 0) { materialData = materials[0]; materialData.curAuditor = await ctx.service.materialAudit.getAuditorByStatus(materialData.id, materialData.status, materialData.times); const times = materialData.status === auditConst.material.status.checkNo ? materialData.times - 1 : materialData.times; materialData.auditors = materialData.status === auditConst.material.status.uncheck ? [] : await ctx.service.materialAudit.getFinalAuditGroup(materialData.id, times); } // 修订完成数目 // const reviseNum = await ctx.service.ledgerRevise.count({ tid: tender.id, status: auditConst.revise.status.checked }); // 计量完成概况 // tender.total_price const stage_total = [ { num: tender.end_contract_tp ? tender.end_contract_tp : 0, name: '合同完成' }, { num: tender.end_qc_tp ? tender.end_qc_tp : 0, name: '变更完成' }, { num: tender.undone_tp ? tender.undone_tp : 0, name: '未完成' }, ]; // 地图 const tenderALLInfo = await ctx.service.tender.getDataById(tender.id); const hadMap = tenderALLInfo.had_map === 1 ? 0 : 1; const tenderMapList = await ctx.service.tenderMap.getAllDataByCondition({ where: { tid: tender.id } }); // 默认坐标,否则则取办事处坐标 const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id); let map_json = { province: mapConst.map[0].province, lng: mapConst.map[0].lng, lat: mapConst.map[0].lat, level: 15, }; if (projectData.map_json) { map_json = JSON.parse(projectData.map_json); } else { const mapInfo = ctx.helper._.find(mapConst.map, { office: projectData.manager_office }); if (mapInfo) { map_json.province = mapInfo.province; map_json.lng = mapInfo.lng; map_json.lat = mapInfo.lat; } } const renderData = { tenders, categoryData, tender, revise, tenderInfo: ctx.tender.info, tenderMenu: this.menu.tenderMenu, preUrl: '/tender/' + ctx.tender.id, cooperation: ctx.session.sessionUser.cooperation, lastStage, stages: stages.reverse(), monthProgress, audit: auditConst, change_status_total, change_quality_total, materialData, // reviseNum, stage_total, hadMap, jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.tenderInfo), gclChapter, tenderMapList, map_json, }; if (ctx.session.sessionUser.is_admin) { renderData.tourists = await ctx.service.tenderTourist.getTourists(tender.id); for (const t of renderData.tourists) { t.permission = await ctx.service.tenderTourist.getTouristPermission(t); } // 获取所有项目参与者 const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { project_id: ctx.session.sessionProject.id, enable: 1 }, columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'], }); const accountGroupList = accountGroup.map((item, idx) => { const groupList = accountList.filter(item => item.account_group === idx); return { groupName: item, groupList }; }); renderData.accountList = accountList; renderData.accountGroup = accountGroupList; } if (ctx.session.sessionProject.page_show.xxjd && ctx.session.sessionUser.is_admin) { // 投资进度内容 renderData.scheduleAuditList = await ctx.service.scheduleAudit.getAllDataByCondition({ where: { tid: tender.id } }); renderData.scPermission = scheduleConst.permission; } await this.layout('tender/detail.ejs', renderData, 'tender/detail_modal.ejs'); } catch (error) { this.log(error); this.ctx.redirect('/list'); } } /** * 保存标段属性等(Ajax) * * @param ctx * @return {Promise} */ async saveTenderInfo(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data) { throw '提交数据错误'; } // 针对查阅所有标段者但非原报和审批人提示 const times = ctx.tender.data.ledger_status === auditConst.ledger.status.checkNo ? ctx.tender.data.ledger_times - 1 : ctx.tender.data.ledger_times; const auditors = await this.service.ledgerAudit.getAuditors(ctx.tender.id, times); const auditorsId = ctx.helper._.map(auditors, 'audit_id'); const stageAuditors = await this.service.stageAudit.getAllAuditors(ctx.tender.id); const stageAUditorsId = ctx.helper._.map(stageAuditors, 'aid'); const accountId = ctx.session.sessionUser.accountId; if (auditorsId.indexOf(accountId) === -1 && ctx.tender.data.user_id !== accountId && stageAUditorsId.indexOf(accountId) === -1) { throw '您无权修改标段设置内容'; } if (ctx.tender.data.ledger_status === auditConst.ledger.status.checked) { if (data.deal_param) { const lastStage = await this.ctx.service.stage.getLastestStage(ctx.tender.id, true); if (lastStage) { if (lastStage.order > 1 || (lastStage.status === auditConst.stage.status.checked || lastStage.status === auditConst.stage.status.checking)) throw '第一期上报后不可修改合同参数'; if (lastStage.user_id !== ctx.session.sessionUser.accountId) throw '仅原报可修改合同参数'; } } } if (data.decimal) { if (ctx.tender.data.user_id !== ctx.session.sessionUser.accountId) throw '仅原报可修改小数位数'; await ctx.service.tenderInfo.saveDecimal(ctx.tender.id, data.decimal, ctx.tender.info.decimal); } else if (data.precision) { if (ctx.tender.data.user_id !== ctx.session.sessionUser.accountId) throw '仅原报可修改清单精度'; await ctx.service.tenderInfo.savePrecision(ctx.tender.id, data.precision, ctx.tender.info.precision, ctx.tender.info.decimal); } else { await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, data); } ctx.body = { err: 0, msg: '', data: JSON.parse(ctx.request.body.data) }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存标段设置失败'); } } async saveTenderInfo2(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data || (!data.ledger_check && !data.fun_rela)) throw '提交数据错误'; if (!ctx.session.sessionUser.is_admin) throw '您无权修改该内容'; const updateData = {}; if (data.ledger_check) updateData.ledger_check = data.ledger_check; if (data.fun_rela) updateData.fun_rela = data.fun_rela; await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, data); ctx.body = { err: 0, msg: '', data: JSON.parse(ctx.request.body.data) }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存失败'); } } /** * 设置标段计量类型并调整到标段概况(Get) * * @param ctx * @return {Promise} */ async tenderType(ctx) { try { const tenderId = ctx.params.id, type = ctx.query.type; if (!tenderId) { throw '当前未打开标段'; } await ctx.service.tender.checkTender(tenderId); if (!ctx.tender) { throw '标段数据错误'; } if (!ctx.tender.measure_type) { await ctx.service.tender.setTenderType(ctx.tender, parseInt(type)); } ctx.redirect('/tender/' + tenderId); } catch (error) { ctx.helper.log(error); this.postError(error, '设置标段类型错误'); ctx.redirect('/list'); } } /** * 标段协作办公 * * @param {Object} ctx - egg全局变量 * @return {void} */ async tenderCooperation(ctx) { const tenderId = ctx.params.id; try { if (!ctx.session.sessionUser.cooperation) { throw '权限不足'; } const tender = await ctx.service.tender.getDataById(tenderId); const user = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId); // 获取已参与协作用户列表 const cooperationArray = []; if (tender.cooperation !== null && tender.cooperation !== '') { const cooperationList = JSON.parse(tender.cooperation); for (const cl in cooperationList) { const clArray = []; for (const audit of cooperationList[cl]) { const userInfo = await ctx.service.projectAccount.getDataById(audit); clArray.push(userInfo); } cooperationArray[cl] = clArray; } } const renderData = { user, tender, tenderMenu: this.menu.tenderMenu, preUrl: '/tender/' + tenderId, tenderPermissionList: accountPermission.tenderPermissionList, cooperationArray, }; await this.layout('tender/cooperation.ejs', renderData, 'tender/cooperationModal.ejs'); } catch (error) { ctx.helper.log(error); this.ctx.redirect('/tender/' + tenderId); } } /** * 添加标段操作 * * @param {Object} ctx - egg全局变量 * @return {void} */ async add(ctx) { try { const rule = ctx.service.tender.rule('add'); ctx.helper.validate(rule); const result = ctx.service.tender.add(ctx.request.body); if (!result) { throw '新增标段失败'; } } catch (error) { ctx.helper.log(error); this.setMessage(error.toString(), this.messageType.ERROR); } ctx.redirect(ctx.request.header.referer); } /** * 保存标段操作 * * @param {Object} ctx - egg全局变量 * @return {void} */ async save(ctx) { let id = ctx.request.body.tenderId; id = parseInt(id); try { if (isNaN(id) || id < 0) { throw '参数错误'; } // 获取数据规则 const rule = ctx.service.tender.rule('save'); ctx.validate(rule); const result = await ctx.service.tender.save(ctx.request.body, id); if (!result) { throw '保存标段数据失败'; } this.setMessage('保存标段数据成功', this.messageType.SUCCESS); } catch (error) { this.postError(error, '保存标段数据失败'); } ctx.redirect(ctx.request.header.referer); } /** * 删除标段 * * @param {Object} ctx -egg全局变量 * @return {void} */ async delete(ctx) { let id = ctx.request.body.tenderId; id = parseInt(id); try { if (isNaN(id) || id <= 0) { throw '参数错误'; } const result = ctx.service.tender.deleteTenderById(id); if (!result) { throw '删除标段失败'; } this.setMessage('删除标段成功', this.messageType.SUCCESS); } catch (error) { this.postError(error, '删除标段失败'); } ctx.redirect(ctx.request.header.referer); } async rule(ctx) { const responseData = { err: 0, msg: '', data: {}, }; try { const tenderId = ctx.session.sessionUser.tenderId; if (!tenderId) { throw '当前未打开标段'; } const data = JSON.parse(ctx.request.body.data); if (!data.rule || !JSON.parse(data.data).length || !codeRuleConst.ruleField[data.rule]) { throw '请选择组件再添加'; } if (!data.connector) { throw '请选择连接符'; } const updateData = { id: tenderId, }; updateData[codeRuleConst.ruleField[data.rule]] = data.data; updateData.c_connector = data.connector; updateData.c_rule_first = 0; const result = await ctx.service.tender.db.update(ctx.service.tender.tableName, updateData); if (result.affectedRows !== 1) { throw '更新规则失败'; } } catch (err) { ctx.helper.log(err); responseData.err = 1; responseData.msg = err.toString(); } ctx.body = responseData; } async ruleFirst(ctx) { const responseData = { err: 0, msg: '', data: {}, }; try { const tenderId = ctx.session.sessionUser.tenderId; if (!tenderId) { throw '当前未打开标段'; } const updateData = { id: tenderId, }; updateData.c_rule_first = 0; const result = await ctx.service.tender.db.update(ctx.service.tender.tableName, updateData); if (result.affectedRows !== 1) { throw '更新规则失败'; } } catch (err) { ctx.helper.log(err); responseData.err = 1; responseData.msg = err.toString(); } ctx.body = responseData; } async shenpiSet(ctx) { if (ctx.session.sessionUser.is_admin === 0) { ctx.request.headers.referer ? ctx.redirect(ctx.request.headers.referer) : ctx.redirect('/list'); } // 获取所有项目参与者 const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { project_id: ctx.session.sessionProject.id, enable: 1 }, columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'], }); const accountGroupList = accountGroup.map((item, idx) => { const groupList = accountList.filter(item => item.account_group === idx); return { groupName: item, groupList }; }); // 获取固定审批流 or 固定终审 for (const sp of shenpiConst.sp_lc) { sp.status = ctx.tender.info.shenpi ? ctx.tender.info.shenpi[sp.code] : shenpiConst.sp_status.sqspr; if (sp.status === shenpiConst.sp_status.gdspl) { sp.auditList = await ctx.service.shenpiAudit.getAuditList(ctx.tender.id, sp.type, sp.status); } else if (sp.status === shenpiConst.sp_status.gdzs) { sp.audit = await ctx.service.shenpiAudit.getAudit(ctx.tender.id, sp.type, sp.status); } } const tenders = await ctx.service.tender.getList('', null, 1); const removeTenders = []; for (const tender of tenders) { const shenpiInfo = await ctx.service.tenderInfo.getTenderShenpiInfo(tender.id); if (!shenpiInfo) { removeTenders.push(tender.id); } else { tender.shenpiInfo = shenpiInfo; // 获取所有的固定审批流或固定终审 const shenpiauditList = {}; for (const shenpi in tender.shenpiInfo) { if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdspl) { const shenpiList = await ctx.service.shenpiAudit.getAllDataByCondition({ where: { tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] } }); const shenpiIdList = ctx.helper._.map(shenpiList, 'audit_id'); shenpiauditList[shenpi] = shenpiIdList.length ? shenpiIdList : null; } else if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdzs) { const shenpiInfo = await ctx.service.shenpiAudit.getDataByCondition({ tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] }); shenpiauditList[shenpi] = shenpiInfo && shenpiInfo.audit_id ? [shenpiInfo.audit_id] : null; } } tender.shenpiauditList = shenpiauditList; } } if (removeTenders.length > 0) { ctx.helper._.remove(tenders, function(n) { return removeTenders.indexOf(n.id) !== -1; }); } const categoryData = await ctx.service.category.getAllCategory(ctx.session.sessionProject.id); // 是否修订中 const lastRevise = await ctx.service.ledgerRevise.getLastestRevise(ctx.tender.id); const revising = (lastRevise && lastRevise.status !== auditConst.revise.status.checked) || false; const cooperationNum = await ctx.service.ledgerCooperation.count({ tid: ctx.tender.id, status: 1 }); const renderData = { shenpi: shenpiConst, accountList, accountGroup: accountGroupList, tenders, categoryData, auditConst, revising, measureType, cooperationNum, jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.tender.shenpi), }; await this.layout('tender/shenpi.ejs', renderData, 'tender/shenpi_modal.ejs'); } async saveTenderInfoShenpi(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data) { throw '提交数据错误'; } // 判断修改权限 if (ctx.session.sessionUser.is_admin === 0) { throw '你没有权限修改审批流程'; } // let postData = {}; // if (!ctx.tender.info.shenpi) { // for (const sp of shenpiConst.sp_lc) { // if (sp.code === data.code) { // postData[sp.code] = data.status; // } else { // postData[sp.code] = shenpiConst.sp_status.sqspr; // } // } // } else { const postData = ctx.tender.info.shenpi; postData[data.code] = data.status; if (data.code === shenpiConst.sp_lc[shenpiConst.sp_type.stage - 1].code) { const status = parseInt(data.status) === shenpiConst.sp_status.gdspl ? 1 : 0; await ctx.service.ledgerCooperation.changeAllStatus(status); } // } // console.log(postData); await ctx.service.tenderInfo.saveTenderInfo(ctx.tender.id, { shenpi: postData }); let auditList = []; if (data.status === shenpiConst.sp_status.gdspl) { auditList = await ctx.service.shenpiAudit.getAuditList(ctx.tender.id, shenpiConst.sp_type[data.code], data.status); } else if (data.status === shenpiConst.sp_status.gdzs) { auditList = await ctx.service.shenpiAudit.getAudit(ctx.tender.id, shenpiConst.sp_type[data.code], data.status); } ctx.body = { err: 0, msg: '', data: auditList }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存审批流程设置失败'); } } async saveShenpiAudit(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data) { throw '提交数据错误'; } // 判断修改权限 if (ctx.session.sessionUser.is_admin === 0) { throw '你没有权限修改审批流程'; } let info = ''; switch (data.type) { case 'add': const result = await ctx.service.shenpiAudit.addAudit(data); if (result) { throw '添加审批人失败'; } break; case 'del': await ctx.service.shenpiAudit.removeAudit(data); break; case 'copy2ot': await ctx.service.shenpiAudit.copyAudit2otherTender(data); break; case 'copy2os': await ctx.service.shenpiAudit.copyAudit2otherShenpi(data); break; case 'pwd': info = await ctx.service.ledgerCooperation.save(data); break; case 'company': info = await ctx.service.ledgerCooperation.saveCompany(data); break; default:break; } ctx.body = { err: 0, msg: '', data: info }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存审批流程设置失败'); } } /** * 签名,上传图片 (Ajax) * @param ctx * @return {Promise} */ async saveCooperateSign(ctx) { try { const stream = await ctx.getFileStream(); const create_time = Date.parse(new Date()) / 1000; const id = stream.fields.id; const fileInfo = path.parse(stream.filename); const fileName = path.join('public/upload', ctx.tender.id.toString(), 'sign', 'signImg_' + create_time + fileInfo.ext); await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', fileName)); if (stream) { await sendToWormhole(stream); } await ctx.service.ledgerCooperation.saveSign(id, fileName); ctx.body = { err: 0, msg: '', data: fileName }; } catch (err) { this.log(err); ctx.body = { err: 1, msg: err.toString(), data: null }; } } /** * 拷贝设置 * @param {object} ctx - 上下文 */ async copyTender(ctx) { try { const id = ctx.tender.data.id; const { id: copy_id = '', type: typeArr = [] } = JSON.parse(ctx.request.body.data); await ctx.service.tenderInfo.copyTenderHandler(id, copy_id, typeArr); ctx.body = { err: 0, msg: '' }; } catch (error) { this.log(error); ctx.body = this.ajaxErrorBody(error, '保存审批流程设置失败'); } } /** * 游客账号设置 * @param {object} ctx - 上下文 */ async saveTourist(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data) { throw '提交数据错误'; } // 判断修改权限 if (ctx.session.sessionUser.is_admin === 0) { throw '你没有权限修改游客账号'; } let info = ''; switch (data.type) { case 'add': const result = await ctx.service.tenderTourist.addAudit(data); if (!result) { throw '添加审批人失败'; } info = result; break; case 'del': await ctx.service.tenderTourist.removeAudit(data); break; case 'permission': await ctx.service.tenderTourist.setPermission(data); break; default:break; } ctx.body = { err: 0, msg: '', data: info }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存游客账号设置失败'); } } /** * 获取部位明细数据(Ajax) * * @param ctx * @return {Promise} */ async loadLedgerData(ctx) { try { const ledgerData = await ctx.service.ledger.getData(ctx.tender.id); const posData = ctx.tender.data.measure_type === measureType.tz.value ? await ctx.service.pos.getPosData({ tid: ctx.tender.id }) : []; const convert = new billsPosConvert(ctx); convert.loadData(ledgerData, posData, []); const result = await convert.convert(); const ledgerCooperationList = await ctx.service.ledgerCooperation.getAllDataByCondition({ where: { tid: ctx.tender.id, status: 1 } }); ctx.body = { err: 0, msg: '', data: { ledgerList: result, ledgerCooperationList } }; } catch (err) { this.log(err); ctx.body = { err: 1, msg: err.toString(), data: [] }; } } async billsTag(ctx) { try { const isValidTourist = ctx.tender.isTourist && ctx.tender.touristPermission.tag; if (ctx.stage) { const isAuditor = ctx.stage.users.indexOf(this.ctx.session.sessionUser.accountId) >= 0; if (!isAuditor && !isValidTourist) throw '您无权进行该操作'; } else { const isAuditor = ctx.tender.ledgerUsers.indexOf(this.ctx.session.sessionUser.accountId) >= 0; if (!isAuditor && !isValidTourist) throw '您无权进行该操作'; } const data = JSON.parse(ctx.request.body.data); const result = await ctx.service.ledgerTag.update(data); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '书签数据错误'); } } async listLoad(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.tid || !data.lid || !data.type) throw '数据错误'; const responseData = { err: 0, msg: '', data: { ledgerAuditConst: auditConst.ledger, stageAuditConst: auditConst.stage }, }; responseData.data.category = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id); // 获取用户权限 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; const tenderList = await this.ctx.service.tender.getList('', userPermission); for (const t of tenderList) { if (t.ledger_status === auditConst.ledger.status.checked) { t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, false); } } if (data.type === 'ledger') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked; }); const history = await this.ctx.service.sumLoadHistory.getLedgerHistory(data.tid, data.lid); if (history) responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'ledger' }; } else if (data.type === 'stage') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked && !!x.lastStage; }); let history = await this.ctx.service.sumLoadHistory.getStageHistory(data.tid, data.lid); if (history) { responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'stage' }; } else { history = await this.ctx.service.sumLoadHistory.getReviseHistory(data.tid, data.lid); if (history) { responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'revise' }; } else { history = await this.ctx.service.sumLoadHistory.getLedgerHistory(data.tid, data.lid); if (history) responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'ledger' }; } } } else if (data.type === 'revise') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked; }); let history = await this.ctx.service.sumLoadHistory.getReviseHistory(data.tid, data.lid); if (history) { responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'revise' }; } else { history = await this.ctx.service.sumLoadHistory.getLedgerHistory(data.tid, data.lid); if (history) responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'ledger' }; } } ctx.body = responseData; } catch(err) { this.log(err); this.ajaxErrorBody(err, '获取标段列表错误'); } } async listLoad2(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.type) throw '数据错误'; const responseData = { err: 0, msg: '', data: { ledgerAuditConst: auditConst.ledger, stageAuditConst: auditConst.stage }, }; responseData.data.category = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id); // 获取用户权限 const accountInfo = await this.ctx.service.projectAccount.getDataById(this.ctx.session.sessionUser.accountId); const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; const tenderList = await this.ctx.service.tender.getList('', userPermission); for (const t of tenderList) { if (t.ledger_status === auditConst.ledger.status.checked) { t.lastStage = await this.ctx.service.stage.getLastestStage(t.id, false); t.lastCheckedStage = await this.ctx.service.stage.getLastestCompleteStage(t.id); } } if (data.type === 'all') { responseData.data.tenders = tenderList; } else if (data.type === 'ledger-checked') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked; }); } else if (data.type === 'stage') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked && !!x.lastStage; }); } else if (data.type === 'stage-checked') { responseData.data.tenders = tenderList.filter(x => { return x.ledger_status === auditConst.ledger.status.checked && !!x.lastCheckedStage; }); } ctx.body = responseData; } catch(err) { this.log(err); this.ajaxErrorBody(err, '获取标段列表错误'); } } async sumLoad(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.lid || !data.type || !data.tenders) throw '数据错误'; switch (data.type) { case 'ledger': const refreshData = await this.ctx.service.ledger.sumLoad(data.lid, data.tenders); ctx.body = {err: 0, msg: '', data: refreshData}; break; case 'revise': const reviseData = await this.ctx.service.reviseBills.sumLoad(data.lid, this.ctx.revise.id, data.tenders); ctx.body = {err: 0, msg: '', data: reviseData}; break; case 'stage': const stageData = await this.ctx.service.stageBills.sumLoad(data.lid, data.tenders, data.cover); ctx.body = {err: 0, msg: '', data: stageData}; break; default: throw '数据错误'; } } catch (err) { this.log(err); this.ajaxErrorBody(err, '导入数据失败'); } } /** * 地图数据设置(Ajax) * * @param ctx * @return {Promise} */ async saveMap(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data) { throw '提交数据错误'; } // 判断修改权限 if (ctx.session.sessionUser.is_admin === 0) { throw '你没有权限修改概况设置'; } let info = ''; let result = ''; switch (data.type) { case 'select-map': result = await ctx.service.tender.saveTenderData(ctx.tender.id, { had_map: data.value }); if (!result) { throw '修改概况设置失败'; } info = result; break; case 'add-map': result = await ctx.service.tenderMap.addMap(ctx.tender.id, data.name); info = await ctx.service.tenderMap.getDataById(result.insertId); break; case 'del-map': await ctx.service.tenderMap.deleteById(data.id); break; case 'save-map': await ctx.service.tenderMap.saveMap(data.mapData); break; default:break; } ctx.body = { err: 0, msg: '', data: info }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err, '保存概况设置失败'); } } } return TenderController; };