const dayjs = require("dayjs"); const appFunction = require("../app-function"); const task = require("./task.js"); const todoEvents = require("../to-do-events"); const memberPlan = require("./member-plan.js"); const managementCate = require("./cate.js"); const common = require("../../common.js"); const { context } = require("esbuild"); let db = null; let currentCorpId = null; exports.main = async (content, DB) => { db = DB; currentCorpId = content.corpId; switch (content.type) { case "getManagementPlan": return await exports.getManagementPlan(content); case "createManagementPlan": return await exports.createManagementPlan(content); case "updateManagementPlan": return await exports.updateManagementPlan(content); case "removeManagementPlan": return await exports.removeManagementPlan(content); case "updateManagementPlanTask": return await exports.updateManagementPlanTask(content); case "addManagementPlanTask": return await exports.addManagementPlanTask(content); case "removeManagementPlanTask": return await exports.removeManagementPlanTask(content); case "executeManagementPlan": return await exports.executeManagementPlan(content); case "getManagementPlanById": return await exports.getManagementPlanById(content); case "stopManagementPlan": return await exports.stopManagementPlan(content); case "executeManagementPlanTodo": return await exports.executeManagementPlanTodo(content); case "createGroupmsgTaskByTodo": return await createGroupmsgTaskByTodo(content); case "addManageMentPlanCate": case "deleteManageMentPlanCate": case "getManageMentPlanCateList": case "updateManageMentPlanCate": case "sortManageMentPlanCate": return await managementCate.main(content, db); } }; // 获取管理计划列表 userId为 administrator 为机构管理员 exports.getManagementPlan = async (context) => { try { const { page, pageSize, corpId, userId = "", teamId, cateIds, planType, planStatus, planName, } = context; if (!corpId || !userId) { return { success: false, message: "未填写corpId" }; } if (planType === "team" && !teamId) { return { success: false, message: "团队id未传" }; } const others = []; let query = { corpId, teamId }; if (planType === "team") { query = { corpId }; const condition = { $or: [ { planType: "team", teamId }, { planType: "corp", teamIds: { $in: [teamId] }, planStatus: true }, { planType: "corp", fitAllTeams: true, planStatus: true }, ], }; others.push(condition); } else if (planType) { query.planType = planType; } if (typeof planStatus == "boolean") { query.planStatus = planStatus; } if (typeof planName === "string" && planName.trim()) { query.planName = { $regex: ".*" + planName.trim() + ".*", $options: "i" }; } if (Array.isArray(cateIds)) { query.cateId = { $in: cateIds }; } if (others.length > 0) { query = { $and: [query, ...others] }; } const planDB = db.collection("management-plan"); const total = await planDB.countDocuments(query); // 总数 const pages = Math.ceil(total / pageSize); let list = await planDB .find(query) .skip((page - 1) * pageSize) .sort({ createTime: -1 }) .limit(pageSize) .toArray(); const countList = await statisticsManagementPlan(context); if (countList && Array.isArray(countList)) { list = list.map((item) => { const countItem = countList.find((e) => e._id === item.planId); if (countItem) { const { _id, ...rest } = countItem; Object.assign(item, rest); } return item; }); } return { success: true, message: "获取成功", data: list, total: total, pages: pages, size: pageSize, }; } catch (error) { return { success: false, message: error.message || "获取失败", }; } }; async function statisticsManagementPlan(context) { const { page, pageSize, corpId, teamId } = context; let query = { corpId, teamId, }; const data = await db .collection("management-plan") .aggregate([ { $match: query }, { $sort: { createTime: -1 } }, { $skip: (page - 1) * pageSize }, { $limit: pageSize }, { $lookup: { from: "member-management-plan", localField: "planId", foreignField: "planId", as: "plans", }, }, { $unwind: "$plans" }, { $group: { _id: "$planId", allCount: { $sum: 1 }, closedCount: { $sum: { $cond: [{ $eq: ["$plans.planExecutStaus", "closed"] }, 1, 0], }, }, executingCount: { $sum: { $cond: [{ $eq: ["$plans.planExecutStaus", "executing"] }, 1, 0], }, }, changedCount: { $sum: { $cond: [{ $eq: ["$plans.changedStatus", "isChanged"] }, 1, 0], }, }, }, }, { $project: { _id: 1, allCount: 1, closedCount: 1, executingCount: 1, changedCount: 1, }, }, ]) .toArray(); return data; } // 新增管理计划 exports.createManagementPlan = async (context) => { const { corpId, params } = context; const { planId, planName, teamId, planSource, planStatus, planDetail, createor, teanName, taskList = [], planType, cateId, fitAllTeams, teamIds, } = params; if (typeof corpId !== "string" || corpId.trim() === "") { return { success: false, message: "机构id不能为空" }; } if (typeof planName !== "string" || planName.trim() === "") { return { success: false, message: "计划名称不能为空" }; } if (!["corp", "team"].includes(planType)) { return { success: false, message: "计划类型错误" }; } if ( planType === "corp" && (typeof cateId !== "string" || cateId.trim() === "") ) { return { success: false, message: "分类id不能为空" }; } if ( planType === "team" && (typeof teamId !== "string" || teamId.trim() === "" || !teamId) ) { return { success: false, message: "团队id不能为空" }; } if (!Array.isArray(taskList) || taskList.length === 0) { return { success: false, message: "任务列表不能为空" }; } if (typeof planId !== "string" || planId.trim() === "") { return { success: false, message: "计划id不能为空" }; } const payload = { _id: common.generateRandomString(24), planId, planName: planName.trim(), planSource, planType, planStatus, planDetail, createor, corpId, teanName, createTime: Date.now(), taskList, }; if (planType === "team") { payload.teamId = teamId; } else if (planType === "corp") { payload.cateId = cateId; payload.fitAllTeams = typeof fitAllTeams === "boolean" ? fitAllTeams : false; payload.teamIds = Array.isArray(teamIds) ? teamIds : []; } try { if (typeof planName === "string" && planName.trim()) { const sameNameQuery = planType === "corp" ? { planType: "corp", planName: planName.trim(), corpId } : { planType: "team", planName: planName.trim(), corpId, teamId }; const total = await db .collection("management-plan") .countDocuments(sameNameQuery); if (total > 0) { return { success: false, message: planType === "corp" ? "机构回访计划名称已存在" : "当前团队已存在回访计划名称", }; } } const result = await db.collection("management-plan").insertOne(payload); return { success: true, data: { id: result.insertedId, corpId, }, message: "新增成功", }; } catch (error) { return { success: false, message: error.message || "新增失败", }; } }; // 编辑计划内容 exports.updateManagementPlan = async (context) => { const { id, corpId, params } = context; const { planName, teamId, planStatus, planDetail, teanName, taskList } = params; if (!id) { return { success: false, message: "计划ID未传!", }; } if (!corpId) { return { success: false, message: "机构ID未传!", }; } try { const plan = await db .collection("management-plan") .findOne({ _id: id, corpId }); if (plan) { if (typeof planName === "string" && planName.trim()) { const sameNameQuery = plan.planType === "corp" ? { _id: { $ne: id }, planType: "corp", planName: planName.trim(), corpId, } : { _id: { $ne: id }, planType: "team", planName: planName.trim(), corpId, teamId: plan.teamId, }; const total = await db .collection("management-plan") .countDocuments(sameNameQuery); if (total) { return { success: false, message: plan.planType === "corp" ? "机构回访计划名称已存在" : "当前团队已存在回访计划名称", }; } } const query = { updateTime: Date.now() }; if (typeof planName === "string") { query.planName = planName.trim(); } if ( plan.planType === "team" && typeof teamId === "string" && teamId.trim() ) { query.teamId = teamId.trim(); } if ( plan.planType === "team" && typeof teamId === "string" && teamId.trim() == "" ) { return { success: false, message: "无效的团队id!" }; } if (typeof planStatus === "boolean") { query.planStatus = planStatus; } if (typeof planDetail === "string") { query.planDetail = planDetail.trim(); } if (typeof teanName === "string") { query.teanName = teanName.trim(); } if (Array.isArray(taskList)) { query.taskList = taskList; } if (plan.planType === "corp" && typeof params.fitAllTeams === "boolean") { query.fitAllTeams = params.fitAllTeams; } if (plan.planType === "corp" && Array.isArray(params.teamIds)) { query.teamIds = params.teamIds; } let res = await db .collection("management-plan") .updateOne({ _id: id, corpId }, { $set: query }); return { success: true, data: res, message: "更新成功", }; } return { success: false, message: "计划不存在" }; } catch (error) { return { success: false, message: error.message || "更新失败", }; } }; // 编辑管理计划任务 exports.updateManagementPlanTask = async (context) => { let { id, taskId, params } = context; let item = await db.collection("management-plan").findOne({ _id: id }); if (Array.isArray(item.taskList)) { const index = item.taskList.findIndex((item) => item.taskId === taskId); item.taskList[index] = params; } try { let res = await db .collection("management-plan") .updateOne({ _id: id }, { $set: { taskList: item.taskList } }); return { success: true, data: res, message: "更新成功", }; } catch (error) { return { success: false, message: "更新失败", }; } }; // 新增管理计划任务 exports.addManagementPlanTask = async (context) => { let { id, params } = context; try { let res = await db .collection("management-plan") .updateOne({ _id: id }, { $push: { taskList: params } }); return { success: true, data: res, message: "子任务新增成功", }; } catch (error) { return { success: false, message: "子任务新增失败", }; } }; // 删除管理计划任务 exports.removeManagementPlanTask = async (context) => { const { id, taskId } = context; if (!id) { return { success: false, message: "管理计划id未传", }; } if (!taskId) { return { success: false, message: "子任务id未传", }; } try { let res = await db .collection("management-plan") .updateOne({ _id: id }, { $pull: { taskList: { taskId } } }); return { success: true, data: res, message: "子任务删除成功", }; } catch (error) { return { success: false, message: "子任务删除失败", }; } }; // 根据planId执行回访计划 exports.executeManagementPlanByPlanId = async (context) => { const { planId, rest } = context; const data = await db.collection("management-plan").findOne({ planId }); if (data) { const { taskList, planName } = data; return await exports.executeManagementPlanTodo({ ...rest, taskList, planName, }); } else { return { success: false, message: "回访计划获取失败", }; } }; exports.executeManagementPlanTodo = async (ctx) => { const { corpId, customerId, customerName, customerUserId, executeTeamId, executeTeamName, taskList, planId, planName, userId, } = ctx; if (!corpId) { return { success: false, message: "机构ID不能为空" }; } if (!customerId) { return { success: false, message: "客户ID不能为空" }; } if (!userId) { return { success: false, message: "ID不能为空" }; } if (!customerName) { return { success: false, message: "客户名称不能为空" }; } if (!executeTeamId) { return { success: false, message: "执行团队ID不能为空" }; } if (!Array.isArray(taskList) || taskList.length === 0) { return { success: false, message: "任务列表不能为空" }; } try { const list = taskList .map((item) => { const task = { corpId, customerId, customerName, executeTeamId, executeTeamName, eventType: item.eventType, creatorUserId: userId, executeMethod: item.executeMethod, sendContent: getString(item.sendContent), taskId: getString(item.taskId), taskContent: getString(item.taskContent), fileList: Array.isArray(item.fileList) ? item.fileList : [], enableSend: typeof item.enableSend === "boolean" ? item.enableSend : false, executorUserId: getString(item.executorUserId) || userId, }; if (planId) { task.planId = planId; task.planName = getString(planName); } if (customerUserId) { task.customerUserId = customerUserId; } if (item.planExecutionTime && dayjs(item.planExecutionTime).isValid()) { task.planExecutionTime = dayjs(item.planExecutionTime).valueOf(); } return task; }) .filter((task) => task.planExecutionTime) .map((task) => todoEvents.main({ type: "createEvents", params: task, corpId }, db) ); for (let i = 0; i < list.length; i += 10) { const promiseArr = list.slice(i, i + 10); await Promise.all(promiseArr); } // 类型为群发的任务, 及时生成 await createGroupmsgTaskByTodo({ taskList, corpId, customerId, customerUserId, }); return { success: true, message: "执行成功", }; } catch (e) { return { success: false, message: e.message || "执行失败" }; } }; // 类型为群发的任务, 及时生产 /** * * @param {Object} param0 * @param {Array} param0.taskList // 任务列表 * @param {String} param0.taskList.sendContent // 发送内容 * @param {Array} param0.taskList.fileList // 附件列表 * @param {String} param0.taskList.taskId // 任务id * @param {String} param0.taskList.executorUserId // 执行人id * @param {String} param0.corpId // 机构id * @param {String} param0.customerId // 客户id * @param {String} param0.customerUserId // 客户userId * @returns */ async function createGroupmsgTaskByTodo({ taskList, corpId, customerId, customerUserId, }) { // 计划执行时间是当天 const groupmsgTaskList = taskList.filter( (item) => item.executeMethod === "groupTask" && dayjs(item.planExecutionTime).isSame(dayjs(), "day") ); const list = groupmsgTaskList.map((item) => { const { sendContent, fileList, taskId, executorUserId } = item; const params = { sendType: "MESSAGE", executor: executorUserId, customers: [customerId], content: sendContent, attachments: common.getAttachments(fileList, taskId, executorUserId), startTaskDate: dayjs().valueOf(), endTaskDate: dayjs().add(3, "day").endOf("day").valueOf(), sendSource: "MINE", teamIds: [], creator: "system", createSounrce: "MINE", executeStatus: "doing", corpId, taskId, externalUserIds: [customerUserId], }; return appFunction.createGroupmsgTask({ params }); }); for (let i = 0; i < list.length; i += 10) { const promiseArr = list.slice(i, i + 10); await Promise.all(promiseArr); } } // 执行管理计划 exports.executeManagementPlan = async (context) => { const { params } = context; const { corpId, customerId, planId, planName, customerName, planExecutionTime, customerUserId, executorUserId, executeTeamId, executeTeamName, taskList = [], } = params; if (taskList.length === 0) { return { success: false, message: "任务不能为空", }; } if (!planExecutionTime) { return { success: false, message: "计划时间为空", }; } try { const memberPlanId = await memberPlan.main( { ...params, type: "addMemberManagementPlan", }, db ); if (!memberPlanId) { return { success: false, message: "该客户有正在执行中的管理计划", }; } const arr = taskList.map((item) => { let query = { corpId, customerName, executorUserId, executeTeamId, executeTeamName, customerUserId, planName, planId, customerId, memberPlanId, planExecutionTime, ...item, }; return task.main( { params: query, type: "createPlanTask", corpId: currentCorpId, }, db ); }); for (let i = 0; i < arr.length; i += 10) { const promiseArr = arr.slice(i, i + 10); await Promise.all(promiseArr); } return { success: true, message: "执行成功", }; } catch (error) { return { success: false, message: "执行失败", }; } }; exports.getManagementPlanById = async (context) => { const { id } = context; if (!id) { return { success: false, message: "管理计划id未传", }; } try { const plan = await db.collection("management-plan").findOne({ _id: id }); return { success: true, data: plan, message: "获取成功", }; } catch (error) { return { success: false, message: "获取失败", }; } }; // 终止管理计划 exports.stopManagementPlan = async (context) => { const { customerId, planId, memberPlanId } = context; if (!customerId) { return { success: false, message: "客户id不能为空", }; } if (!planId) { return { success: false, message: "管理计划id不能为空", }; } try { await removeEventsByStopManagePlan(context); const res = await db.collection("member-management-plan").updateOne( { _id: memberPlanId }, { $set: { planExecutStaus: "closed", endTime: dayjs().valueOf(), }, } ); return { success: true, message: "终止成功", }; } catch (error) { return { success: false, message: "终止失败", }; } }; // 删除未执行的管理计划 async function removeEventsByStopManagePlan(e) { const { type, ...rest } = e; const taskList = await task.main( { ...rest, type: "getPlanTask", corpId: currentCorpId, }, db ); let events = []; for (let item of taskList) { if (item && Array.isArray(item.events) && item.events.length > 0) { item.events.forEach((e) => { if (e && e.eventStatus === "untreated") { events.push(e); } }); } } const eventsPromiseList = events.map((item) => { const params = { id: item._id, eventStatus: "closed", result: `【${item.planName ? item.planName : ""}】管理计划终止`, }; return setTodoStatus(params); }); for (let i = 0; i < eventsPromiseList.length; i += 10) { const promiseList = eventsPromiseList.slice(i, i + 10); await Promise.all(promiseList); } const arr1 = taskList.map((item) => updateTaskStatus(item)); for (let i = 0; i < arr1.length; i += 10) { const promiseArr = arr1.slice(i, i + 10); await Promise.all(promiseArr); } } async function setTodoStatus(context) { const { id: _id, eventStatus, result } = context; const endTime = new Date().getTime(); await db .collection("to-do-events") .updateOne({ _id }, { $set: { endTime, eventStatus, result } }); } async function updateTaskStatus(item) { await db.collection("management-plan-task").updateOne( { _id: item._id }, { $set: { endTime: dayjs().valueOf(), taskStatus: "closed", }, } ); } function getString(str) { return typeof str === "string" ? str.trim() : ""; } exports.removeManagementPlan = async (ctx) => { const { corpId, id: _id } = ctx; if (!corpId || !_id) { return { success: false, message: "参数错误", }; } try { const res = await db .collection("management-plan") .deleteOne({ _id, corpId }); return { success: true, res, message: "删除成功", }; } catch (e) { return { success: false, message: e.message || "删除失败", }; } };