123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- 'use strict';
- /**
- *
- *
- * @author Mai
- * @date
- * @version
- */
- const rootId = '-1';
- const imType = require('../const/tender').imType;
- const defaultFunRela = {
- banOver: true,
- hintOver: true,
- banMinusChangeBills: true,
- minusNoValue: true,
- lockPayExpr: false,
- showMinusCol: true,
- imType: imType.zl.value,
- needGcl: false,
- };
- const funSet = require('../const/fun_set');
- const defaultFunSet = funSet.defaultInfo;
- module.exports = app => {
- class SubProject extends app.BaseService {
- /**
- * 构造函数
- *
- * @param {Object} ctx - egg全局变量
- * @param {String} tableName - 表名
- * @return {void}
- */
- constructor(ctx) {
- super(ctx);
- this.tableName = 'sub_project';
- }
- async getSubProject(pid, uid, admin, filterFolder = false) {
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- const permission = await this.ctx.service.subProjPermission.getUserPermission(pid, uid);
- result = result.filter(x => {
- if (x.is_folder) return !filterFolder;
- if (admin) return true;
- const pb = permission.find(y => { return x.id === y.spid});
- if (!pb) return false;
- x.user_permission = pb;
- return x.user_permission.budget_permission.length > 0 || x.user_permission.file_permission.length > 0 || x.user_permission.manage_permission.length > 0;
- });
- return result;
- }
- _filterEmptyFolder(data) {
- data.sort((a, b) => { return b.tree_level - a.tree_level});
- const result = [];
- for (const d of data) {
- if (!d.is_folder) result.push(d);
- if (result.find(x => { return x.tree_pid === d.id; })) result.push(d);
- }
- return result;
- }
- async getBudgetProject(pid, uid, admin) {
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- const adminPermission = this.ctx.service.subProjPermission.adminPermission;
- const permission = admin ? [] : await this.ctx.service.subProjPermission.getUserPermission(pid, uid);
- result = result.filter(x => {
- if (!x.is_folder && !x.budget_id) return false;
- if (x.is_folder) return true;
- if (admin) {
- x.permission = adminPermission.budget_permission;
- x.manage_permission = adminPermission.manage_permission;
- return true;
- } else {
- const pb = permission.find(y => { return x.id === y.spid});
- if (!pb) return false;
- x.permission = pb.budget_permission;
- x.manage_permission = pb.manage_permission;
- return x.permission.length > 0;
- }
- });
- return this._filterEmptyFolder(result);
- }
- async getFileProject(pid, uid, admin) {
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- const adminPermission = this.ctx.service.subProjPermission.adminPermission;
- const permission = await this.ctx.service.subProjPermission.getUserPermission(pid, uid);
- result = result.filter(x => {
- if (!x.is_folder && !x.management) return false;
- if (x.is_folder) return true;
- if (admin) {
- x.permission = adminPermission.file_permission;
- x.manage_permission = adminPermission.manage_permission;
- return true;
- } else {
- const pb = permission.find(y => { return x.id === y.spid});
- if (!pb) return false;
- x.permission = pb.file_permission;
- x.manage_permission = pb.manage_permission;
- return x.permission.length > 0;
- }
- });
- return this._filterEmptyFolder(result);
- }
- async getLastChild(tree_pid) {
- const result = await this.getAllDataByCondition({ where: { tree_pid, project_id: this.ctx.session.sessionProject.id }, orders: [['tree_order', 'desc']], limit: 1, offset: 0 });
- return result[0];
- }
- async getPosterityData(id){
- const result = [];
- let cur = await this.getAllDataByCondition({ where: { tree_pid: id, project_id: this.ctx.session.sessionProject.id } });
- let iLevel = 1;
- while (cur.length > 0 && iLevel < 6) {
- result.push(...cur);
- cur = await this.getAllDataByCondition({ where: { tree_pid: cur.map(x => { return x.id })} });
- iLevel += 1;
- }
- return result;
- }
- async getStepNode(node, step) {
- const tree_order = [];
- while(step) {
- tree_order.push(node.tree_order + step);
- if (step > 0) {
- step = step - 1;
- } else {
- step = step + 1;
- }
- }
- return await this.getAllDataByCondition({ where: { tree_pid: node.tree_pid, tree_order, project_id: this.ctx.session.sessionProject.id }, orders: [['tree_order', 'asc']]});
- }
- async addFolder(data) {
- const parent = await this.getDataById(data.tree_pid);
- if (parent && !parent.is_folder) throw '添加数据结构错误';
- const lastChild = await this.getLastChild(parent ? parent.id : rootId);
- const conn = await this.db.beginTransaction();
- try {
- // 获取当前用户信息
- const sessionUser = this.ctx.session.sessionUser;
- // 获取当前项目信息
- const sessionProject = this.ctx.session.sessionProject;
- const insertData = {
- id: this.uuid.v4(), project_id: sessionProject.id, user_id: sessionUser.accountId,
- tree_pid: data.tree_pid,
- tree_level: parent ? parent.tree_level + 1 : 1,
- tree_order: lastChild ? lastChild.tree_order + 1 : 1,
- name: data.name, is_folder: 1,
- };
- const operate = await conn.insert(this.tableName, insertData);
- if (operate.affectedRows === 0) throw '新增文件夹失败';
- await conn.commit();
- return await this.getSubProject(sessionProject.id, sessionUser.accountId, sessionUser.is_admin);
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async addSubProject(data) {
- const parent = await this.getDataById(data.tree_pid);
- if (parent && !parent.is_folder) throw '添加数据结构错误';
- const lastChild = await this.getLastChild(parent ? parent.id : rootId);
- const conn = await this.db.beginTransaction();
- try {
- // 获取当前用户信息
- const sessionUser = this.ctx.session.sessionUser;
- // 获取当前项目信息
- const sessionProject = this.ctx.session.sessionProject;
- const insertData = {
- id: this.uuid.v4(), project_id: sessionProject.id, user_id: sessionUser.accountId,
- tree_pid: data.tree_pid,
- tree_level: parent ? parent.tree_level + 1 : 1,
- tree_order: lastChild ? lastChild.tree_order + 1 : 1,
- name: data.name, is_folder: 0,
- };
- const operate = await conn.insert(this.tableName, insertData);
- // todo 根据节点新增时的其他操作
- if (operate.affectedRows === 0) throw '新增文件夹失败';
- await conn.commit();
- return await this.getSubProject(sessionProject.id, sessionUser.accountId, sessionUser.is_admin);
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async dragTo(data) {
- const dragNode = await this.getDataById(data.drag_id);
- const dropNode = await this.getDataById(data.drop_id);
- if (!dragNode || !dropNode || !dropNode.is_folder) throw '拖拽数据结构错误';
- const lastChild = await this.getLastChild(dropNode.id);
- const posterity = await this.getPosterityData(dragNode.id);
- const conn = await this.db.beginTransaction();
- try {
- const updateData = {
- id: dragNode.id, tree_pid: dropNode.id, tree_level: dropNode.tree_level + 1,
- tree_order: lastChild ? lastChild.tree_order + 1 : 1,
- };
- await conn.update(this.tableName, updateData);
- if (dragNode.tree_level !== dropNode.tree_level + 1 && posterity.length > 0) {
- const posterityUpdateData = posterity.map(x => {
- return { id: x.id, tree_level: dropNode.tree_level + 1 - dragNode.tree_level + x.tree_level }
- });
- await conn.updateRows(this.tableName, posterityUpdateData);
- }
- // 升级原来的后项的order
- await conn.query(`UPDATE ${this.tableName} SET tree_order = tree_order-1 WHERE tree_pid = ? AND tree_order > ?`, [dragNode.tree_pid, dragNode.tree_order]);
- await conn.commit();
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- return await this.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, this.ctx.session.sessionUser.is_admin);
- }
- async _siblingMove(node, step) {
- const stepNode = await this.getStepNode(node, step);
- const conn = await this.db.beginTransaction();
- try {
- const updateData = [];
- updateData.push({ id: node.id, tree_order: node.tree_order + step });
- for (const sn of stepNode) {
- updateData.push({ id: node.id, tree_order: step > 0 ? sn.tree_order - 1 : sn.tree_order + 1 });
- }
- await conn.updateRows(this.tableName, updateData);
- await conn.commit();
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async _siblingMoveForce(node, step) {
- const sibling = await this.getAllDataByCondition({ where: { tree_pid: node.tree_pid, project_id: this.ctx.session.sessionProject.id }, orders: [['tree_order', 'asc']] });
- const nodeIndex = sibling.findIndex(x => { return x.id === node.id });
- if (nodeIndex + step < 0) throw '移动数据结构错误';
- if (nodeIndex + step > sibling.length - 1) throw '移动数据结构错误';
- const conn = await this.db.beginTransaction();
- try {
- const updateData = [];
- updateData.push({ id: node.id, tree_order: sibling[nodeIndex + step].tree_order });
- while(step) {
- const stepNode = sibling[nodeIndex + step];
- if (step > 0) {
- updateData.push({ id: stepNode.id, tree_order: sibling[nodeIndex + step - 1].tree_order });
- step = step - 1;
- } else {
- updateData.push({ id: stepNode.id, tree_order: sibling[nodeIndex + step + 1].tree_order});
- step = step + 1;
- }
- }
- await conn.updateRows(this.tableName, updateData);
- await conn.commit();
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async _topMove(node) {
- const lastChild = await this.getLastChild(rootId);
- const posterity = await this.getPosterityData(node.id);
- const conn = await this.db.beginTransaction();
- try {
- const updateData = { id: node.id, tree_pid: rootId, tree_level: 1, tree_order: lastChild ? lastChild.tree_order + 1 : 1 };
- await conn.update(this.tableName, updateData);
- if (node.tree_level !== 1 && posterity.length > 0) {
- const posterityUpdateData = posterity.map(x => {
- return { id: x.id, tree_level: x.tree_level - node.tree_level + 1 }
- });
- await conn.updateRows(this.tableName, posterityUpdateData);
- }
- // 升级原来的后项的order
- await conn.query(`UPDATE ${this.tableName} SET tree_order = tree_order-1 WHERE tree_pid = ? AND tree_order > ?`, [node.tree_pid, node.tree_order]);
- await conn.commit();
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async move(data) {
- const node = await this.getDataById(data.id);
- if (!node) throw '移动数据结构错误';
- switch(data.type) {
- case 'up': await this._siblingMoveForce(node, -1); break;
- case 'down': await this._siblingMoveForce(node, 1); break;
- case 'top': await this._topMove(node); break;
- default: throw '未知移动类型';
- }
- return await this.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, this.ctx.session.sessionUser.is_admin);
- }
- async del(id) {
- const node = await this.getDataById(id);
- if (!node) throw '删除的数据不存在';
- const posterity = await this.getPosterityData(node.id);
- const updateData = [
- { id: node.id, is_delete: 1 },
- ];
- posterity.forEach(x => {
- updateData.push({ id: x.id, is_delete: 1});
- });
- await this.db.updateRows(this.tableName, updateData);
- return await this.getSubProject(this.ctx.session.sessionProject.id, this.ctx.session.sessionUser.accountId, this.ctx.session.sessionUser.is_admin);
- }
- async save(data) {
- const result = await this.db.update(this.tableName, data);
- if (result.affectedRows > 0) {
- return data;
- } else {
- throw '更新数据失败';
- }
- }
- async setBudgetStd(data) {
- const subProject = await this.getDataById(data.id);
- const budgetStd = await this.ctx.service.budgetStd.getDataById(data.std_id);
- if (!budgetStd) throw '选择的概算标准不存在,请刷新页面重试';
- const conn = await this.db.beginTransaction();
- try {
- const budget_id = await this.ctx.service.budget.add(conn, {
- pid: subProject.project_id, user_id: subProject.user_id, rela_tender: subProject.rela_tender
- }, budgetStd);
- const updateData = { id: data.id, std_id: budgetStd.id, std_name: budgetStd.name, budget_id };
- await conn.update(this.tableName, updateData);
- await conn.commit();
- return updateData;
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async setRelaTender(data) {
- const subProject = await this.getDataById(data.id);
- const orgRelaTenderId = subProject.rela_tender.split(',');
- const conn = await this.db.beginTransaction();
- try {
- await conn.update(this.tableName, data);
- await conn.update(this.ctx.service.budget.tableName, { id: subProject.budget_id, rela_tender: data.rela_tender });
- const relaTenderId = data.rela_tender.split(',');
- const removeTenderId = orgRelaTenderId.filter(x => { return relaTenderId.indexOf(x) < 0});
- const addTenderId = relaTenderId.filter(x => { return orgRelaTenderId.indexOf(x) < 0});
- if (removeTenderId.length > 0) await conn.update(this.ctx.service.tender.tableName, { spid: '' }, { where: { id: removeTenderId }});
- if (addTenderId.length > 0) await conn.update(this.ctx.service.tender.tableName, { spid: data.id }, { where: { id: addTenderId }});
- await conn.commit();
- return data;
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async addRelaTender(transaction, spid, tid) {
- if (!transaction) throw '未定义事务';
- const subProject = await this.getDataById(spid);
- if (!subProject) throw '所属项目不存在';
- const rela = subProject.rela_tender.split(',');
- if (rela.indexOf(tid + '') >= 0) return;
- rela.push(tid + '');
- const rela_tender = rela.join(',');
- await transaction.update(this.tableName, { id: spid, rela_tender});
- await transaction.update(this.ctx.service.budget.tableName, { id: subProject.budget_id, rela_tender});
- }
- async removeRelaTender(transaction, spid, tid) {
- if (!transaction) throw '未定义事务';
- const subProject = await this.getDataById(spid);
- if (!subProject) throw '所属项目不存在';
- const rela = subProject.rela_tender.split(',');
- if (rela.indexOf(tid + '') < 0) return;
- const rela_tender = rela.filter(x => { return x === tid + ''}).join(',');
- await transaction.update(this.tableName, { id: spid, rela_tender});
- await transaction.update(this.ctx.service.budget.tableName, { id: subProject.budget_id, rela_tender});
- }
- async setManagement(data) {
- const subProject = await this.getDataById(data.id);
- if (subProject.management === data.management) return data;
- const users = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { project_id: subProject.project_id, company: data.management }});
- const orgMember = await this.ctx.service.subProjPermission.getAllDataByCondition({ where: { spid: subProject.id } });
- const dm = [], um = [], im = [];
- const template = await this.ctx.service.filingTemplateList.getDataById(data.filingTemplate);
- if (!template) throw '选择的文件类别不存在';
- const templateFiling = await this.ctx.service.filingTemplate.getAllDataByCondition({
- where: { temp_id: template.id, is_fixed: 1 },
- });
- const filing_type = this.ctx.service.filing.analysisFilingType(templateFiling).map(x => { return x.value; }).join(','), file_permission = '1,2';
- for (const u of users) {
- const nm = orgMember.find(x => { return u.id === x.uid; });
- if (nm) {
- if (!nm.file_permission) um.push({ id: nm.id, file_permission, filing_type });
- } else {
- im.push({ id: this.uuid.v4(), spid: subProject.id, pid: subProject.project_id, uid: u.id, file_permission, filing_type });
- }
- }
- const conn = await this.db.beginTransaction();
- try {
- await conn.update(this.tableName, { id: subProject.id, management: data.management, filing_template_id: template.id, filing_template_name: template.name });
- await this.ctx.service.filing.initFiling(subProject.id, data.filingTemplate, conn);
- if (dm.length > 0) await conn.delete(this.ctx.service.subProjPermission.tableName, { id: dm });
- if (um.length > 0) await conn.updateRows(this.ctx.service.subProjPermission.tableName, um);
- if (im.length > 0) await conn.insert(this.ctx.service.subProjPermission.tableName, im);
- await conn.commit();
- return data;
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- async refreshManagementPermission(data) {
- const subProject = await this.getDataById(data.id);
- const users = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { project_id: subProject.project_id, company: subProject.management }});
- const orgMember = await this.ctx.service.subProjPermission.getAllDataByCondition({ where: { spid: subProject.id } });
- const dm = [], um = [], im = [];
- const filing_type = this.ctx.service.filing.allFilingType.join(','), file_permission = '1,2';
- for (const u of users) {
- const nm = orgMember.find(x => { return u.id === x.uid; });
- if (nm) {
- if (!nm.file_permission) um.push({ id: nm.id, file_permission, filing_type });
- } else {
- im.push({ id: this.uuid.v4(), spid: subProject.id, pid: subProject.project_id, uid: u.id, file_permission, filing_type });
- }
- }
- const conn = await this.db.beginTransaction();
- try {
- if (dm.length > 0) await conn.delete(this.ctx.service.subProjPermission.tableName, { id: dm });
- if (um.length > 0) await conn.updateRows(this.ctx.service.subProjPermission.tableName, um);
- if (im.length > 0) await conn.insert(this.ctx.service.subProjPermission.tableName, im);
- await conn.commit();
- return { dm: dm.length, um: um.length, im: im.length };
- } catch (error) {
- await conn.rollback();
- throw error;
- }
- }
- // 合同管理获取项目列表
- async getSubProjectByContract(pid, uid, admin, filterFolder = false) {
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- if (admin) return this._filterEmptyFolder(result);
- const permission = await this.ctx.service.contractAudit.getAllDataByCondition({ where: { uid } });
- result = result.filter(x => {
- if (x.is_folder) return !filterFolder;
- const pb = permission.find(y => { return x.id === y.spid; });
- if (!pb) return false;
- return true;
- });
- return this._filterEmptyFolder(result);
- }
- async getSubProjectByTender(pid, tenders, filterFolder = false) {
- if (tenders.length === 0) return [];
- const spids = this._.uniq(this._.map(tenders, 'spid'));
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- result = result.filter(x => {
- if (x.is_folder) return !filterFolder;
- if (!x.rela_tender) return false;
- return this._.includes(spids, x.id);
- });
- return this._filterEmptyFolder(result);
- }
- // 合同管理获取项目列表
- async getSubProjectByFinancial(pid, uid, admin, filterFolder = false) {
- let result = await this.getAllDataByCondition({ where: { project_id: pid, is_delete: 0 } });
- if (admin) return this._filterEmptyFolder(result);
- const permission = await this.ctx.service.financialAudit.getAllDataByCondition({ where: { uid } });
- result = result.filter(x => {
- if (x.is_folder) return !filterFolder;
- const pb = permission.find(y => { return x.id === y.spid; });
- if (!pb) return false;
- return true;
- });
- return this._filterEmptyFolder(result);
- }
- async getFileReference(subProject) {
- return await this.db.query(`SELECT id, name FROM zh_file_reference_list`);
- };
- /**
- * 功能设置
- * @param id
- * @returns {Promise<null>}
- */
- async getFunRela(subProject) {
- const result = subProject.fun_rela ? JSON.parse(subProject.fun_rela) : {};
- this.ctx.helper._.defaults(result, defaultFunRela);
- return result;
- }
- async updateFunRela(id, data) {
- const result = await this.db.update(this.tableName, {
- id: id, fun_rela: JSON.stringify({
- banOver: data.banOver, hintOver: data.hintOver, banMinusChangeBills: data.banMinusChangeBills,
- imType: data.imType, needGcl: data.needGcl, minusNoValue: data.minusNoValue,
- lockPayExpr: data.lockPayExpr, showMinusCol: data.showMinusCol,
- }),
- });
- return result.affectedRows === 1;
- }
- async getFunSet(fun_set = null) {
- const result = fun_set ? JSON.parse(fun_set) : {};
- this.ctx.helper._.defaults(result, defaultFunSet);
- return result;
- }
- async updateFunSet(id, funSet) {
- const result = await this.db.update(this.tableName, {
- id, fun_set: JSON.stringify(funSet),
- });
- return result.affectedRows === 1;
- }
- }
- return SubProject;
- };
|