1775 lines
48 KiB
JavaScript
1775 lines
48 KiB
JavaScript
|
|
const utils = require("../utils");
|
|||
|
|
const dayjs = require("dayjs");
|
|||
|
|
const helpers = require("./customer-util");
|
|||
|
|
const sop = require("../sop");
|
|||
|
|
const updateCustomer = require("./update");
|
|||
|
|
const customerQuery = require("./query");
|
|||
|
|
const common = require("../../common");
|
|||
|
|
const appFunction = require("../app-function");
|
|||
|
|
const api = require("../../api");
|
|||
|
|
let db = null;
|
|||
|
|
exports.main = async (content, DB) => {
|
|||
|
|
db = DB;
|
|||
|
|
switch (content.type) {
|
|||
|
|
case "autoCreateMember":
|
|||
|
|
return await autoCreateMember(content);
|
|||
|
|
case "asyncCustomerTag":
|
|||
|
|
return await asyncCustomerTag(content);
|
|||
|
|
case "update":
|
|||
|
|
return await updateMember(content);
|
|||
|
|
case "add":
|
|||
|
|
return await addMember(content);
|
|||
|
|
case "deleteMember":
|
|||
|
|
return await deleteMember(content);
|
|||
|
|
case "getReferredPeople":
|
|||
|
|
return await getReferredPeople(content);
|
|||
|
|
case "setAgeToNumber":
|
|||
|
|
return await setAgeToNumber();
|
|||
|
|
case "getMember":
|
|||
|
|
return await getMember(content);
|
|||
|
|
case "getCustomerInSidebar":
|
|||
|
|
return await getCustomerInSidebar(content);
|
|||
|
|
case "batchImportCustomer":
|
|||
|
|
return await batchImportCustomer(content);
|
|||
|
|
case "getmemberCountForTeamId":
|
|||
|
|
return await getmemberCountForTeamId(content);
|
|||
|
|
case "getmemberAndserviceCountForUserId":
|
|||
|
|
return await getmemberAndserviceCountForUserId(content);
|
|||
|
|
case "getMemberInfo":
|
|||
|
|
return await getMemberInfo(content);
|
|||
|
|
case "getMemberForTeam":
|
|||
|
|
return await getMemberForTeam(content);
|
|||
|
|
case "getCorpCustomer":
|
|||
|
|
return await getCorpCustomer(content);
|
|||
|
|
case "getMemberBytags":
|
|||
|
|
return await getMemberBytags(content);
|
|||
|
|
case "externalUseridToMember":
|
|||
|
|
return await externalUseridToMember(content);
|
|||
|
|
case "editExternalContactRemark":
|
|||
|
|
return await exports.editExternalContactRemark(content);
|
|||
|
|
case "updateCustomerTimeField":
|
|||
|
|
return await exports.updateCustomerTimeField(content);
|
|||
|
|
case "getCustomerByUnionId":
|
|||
|
|
return await exports.getCustomerByUnionId(content);
|
|||
|
|
case "getCustomerNamesById":
|
|||
|
|
return await exports.getCustomerNamesById(content);
|
|||
|
|
case "triggerSoptaskByCustomerId":
|
|||
|
|
return await triggerSoptaskByCustomerId(content);
|
|||
|
|
case "updateCustomerInHospitalTime":
|
|||
|
|
case "pushCustomerTeamId":
|
|||
|
|
case "updateCustomerPersonResponsibles":
|
|||
|
|
return await updateCustomer.main(content, db);
|
|||
|
|
case "getCustomersCount":
|
|||
|
|
case "getInHospitalCustomersCount":
|
|||
|
|
return await customerQuery.main(content, db);
|
|||
|
|
case "addConsumeRecord":
|
|||
|
|
return await addConsumeRecord(content);
|
|||
|
|
case "updateCustomerReportPeople":
|
|||
|
|
return await updateCustomerReportPeople(content);
|
|||
|
|
case "getCustomerReportLog":
|
|||
|
|
return await getCustomerReportLog(content);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 自动建档
|
|||
|
|
* @param {string} corpId 企业微信ID
|
|||
|
|
* @param {string} env 环境ID
|
|||
|
|
* @param {string} externalUserId 用户userId
|
|||
|
|
* @param {string} name 用户姓名
|
|||
|
|
* @param {string} relationship 关系
|
|||
|
|
* @param {Array} tags 标签
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 自动建档
|
|||
|
|
* @param {string} corpId 企业微信ID
|
|||
|
|
* @param {string} name 用户姓名
|
|||
|
|
* @param {string} externalUserId 用户userId
|
|||
|
|
* @param {object} params 其他参数
|
|||
|
|
* @param {string} userId 用户ID
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
async function autoCreateMember({
|
|||
|
|
corpId,
|
|||
|
|
name,
|
|||
|
|
externalUserId,
|
|||
|
|
params,
|
|||
|
|
userId,
|
|||
|
|
}) {
|
|||
|
|
const query = { corpId, externalUserId };
|
|||
|
|
let data = await db.collection("member").find(query).toArray();
|
|||
|
|
if (data.length > 0)
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "该客户已存在",
|
|||
|
|
};
|
|||
|
|
if (!name) {
|
|||
|
|
let externalUserIdInfo = await api.getWecomApi({
|
|||
|
|
type: "getNameByexternalUserId",
|
|||
|
|
externalUserId,
|
|||
|
|
corpId,
|
|||
|
|
});
|
|||
|
|
let info = externalUserIdInfo.data;
|
|||
|
|
if (info && info.name) name = info.name;
|
|||
|
|
}
|
|||
|
|
// 获取当前客户数据
|
|||
|
|
const teamIds = await getTeamList(userId, corpId);
|
|||
|
|
if (teamIds.length === 0) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "请先创建团队",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const personResponsibles = teamIds.map((i) => {
|
|||
|
|
return { corpUserId: userId, teamId: i };
|
|||
|
|
});
|
|||
|
|
console.log(" 外部联系人name", name);
|
|||
|
|
const addQuery = {
|
|||
|
|
_id: common.generateRandomString(24),
|
|||
|
|
corpId,
|
|||
|
|
name,
|
|||
|
|
externalUserId,
|
|||
|
|
relationship: "本人",
|
|||
|
|
createTime: new Date().getTime(),
|
|||
|
|
creator: "系统自动建档",
|
|||
|
|
customerStage: "OMINHOSPITALA",
|
|||
|
|
createType: "auto",
|
|||
|
|
personResponsibles,
|
|||
|
|
teamId: teamIds,
|
|||
|
|
...params,
|
|||
|
|
};
|
|||
|
|
await addMember({ params: addQuery });
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "自动建档成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 自动化建档
|
|||
|
|
* @param {string} corpId - 企业微信ID
|
|||
|
|
*/
|
|||
|
|
async function autoCustomerArchives(context, name, qrCodeInfo) {
|
|||
|
|
const { ExternalUserID, CorpID, UserID } = context;
|
|||
|
|
// 获取到teamId
|
|||
|
|
const teamIds = await getTeamList(UserID, CorpID);
|
|||
|
|
// 获取二维码数据
|
|||
|
|
// 遍历teamIds建档
|
|||
|
|
// 判断是否已经建档
|
|||
|
|
const archivedCount = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({
|
|||
|
|
corpId: CorpID,
|
|||
|
|
externalUserId: ExternalUserID,
|
|||
|
|
})
|
|||
|
|
.count();
|
|||
|
|
console.log("已经建档数", archivedCount);
|
|||
|
|
if (archivedCount > 0) return;
|
|||
|
|
const { tagIds, customerSource } = qrCodeInfo;
|
|||
|
|
const personResponsibles = teamIds.map((i) => {
|
|||
|
|
return {
|
|||
|
|
corpUserId: UserID,
|
|||
|
|
teamId: i,
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
const params = {
|
|||
|
|
_id: common.generateRandomString(24),
|
|||
|
|
corpId: CorpID,
|
|||
|
|
teamId: teamIds,
|
|||
|
|
externalUserId: ExternalUserID,
|
|||
|
|
relationship: "本人",
|
|||
|
|
tagIds,
|
|||
|
|
customerSource,
|
|||
|
|
name,
|
|||
|
|
personResponsibles,
|
|||
|
|
createTime: new Date().getTime(),
|
|||
|
|
creator: "扫码自动建档",
|
|||
|
|
customerStage: "OMINHOSPITALA",
|
|||
|
|
createType: "auto",
|
|||
|
|
};
|
|||
|
|
console.log("自动建档", params);
|
|||
|
|
await db.collection("member").insertOne(params);
|
|||
|
|
await addMember({});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据userId和corpId获取团队列表
|
|||
|
|
async function getTeamList(userId, corpId) {
|
|||
|
|
const result = await api.getCorpApi({
|
|||
|
|
type: "getTeamBymember",
|
|||
|
|
corpUserId: userId,
|
|||
|
|
corpId,
|
|||
|
|
});
|
|||
|
|
if (result && Array.isArray(result.data) && result.data.length > 0)
|
|||
|
|
return result.data.map((item) => item.teamId);
|
|||
|
|
else return [];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* @param {string} corpId - 企业微信ID
|
|||
|
|
* @param {string} env - 环境ID
|
|||
|
|
* @param {string} externalUserId - 用户userId
|
|||
|
|
* @param {string} name - 用户姓名
|
|||
|
|
* @param {Array} tags - 标签
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
async function asyncCustomerTag({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId,
|
|||
|
|
tags,
|
|||
|
|
name = "",
|
|||
|
|
userId,
|
|||
|
|
}) {
|
|||
|
|
console.log("外部联系人企业微信标签", tags);
|
|||
|
|
// 获取
|
|||
|
|
let result = await api.getCorpApi({
|
|||
|
|
type: "getCorpTags",
|
|||
|
|
corpId,
|
|||
|
|
});
|
|||
|
|
console.log("获取到机构标签getCorpTags", result);
|
|||
|
|
let corpAllTag = result.list || [];
|
|||
|
|
// 筛选出机构中所有企业微信的标签
|
|||
|
|
let corpWecomTagIds = [];
|
|||
|
|
corpAllTag.forEach((item) => {
|
|||
|
|
if (item.createType === "corpAsync") {
|
|||
|
|
item.tag.forEach((tag) => {
|
|||
|
|
corpWecomTagIds.push(tag.id);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
console.log("筛选出机构中所有企业微信的标签", corpWecomTagIds);
|
|||
|
|
let data = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ corpId, externalUserId })
|
|||
|
|
.toArray();
|
|||
|
|
if (data.length === 0) {
|
|||
|
|
let params = {
|
|||
|
|
tagIds: tags,
|
|||
|
|
};
|
|||
|
|
// 给客户自动建档
|
|||
|
|
await autoCreateMember({ corpId, name, externalUserId, userId, params });
|
|||
|
|
}
|
|||
|
|
console.log("自动建档的员工", data);
|
|||
|
|
// 合并标签
|
|||
|
|
for (let i = 0; i < data.length; i++) {
|
|||
|
|
let tag = data[i].tagIds || [];
|
|||
|
|
let createType = data[i].createType;
|
|||
|
|
// 筛选出客户标签中的企业微信标签
|
|||
|
|
let memberWeComTagIds = tag.filter((item) =>
|
|||
|
|
corpWecomTagIds.includes(item)
|
|||
|
|
);
|
|||
|
|
console.log("筛选出客户标签中的企业微信标签", memberWeComTagIds);
|
|||
|
|
let newTagIds = tags;
|
|||
|
|
// corpTagIds 比 newTagIds 多的id 是需要删除的
|
|||
|
|
let delTagIds = memberWeComTagIds.filter(
|
|||
|
|
(item) => !newTagIds.includes(item)
|
|||
|
|
);
|
|||
|
|
// corpTagIds 比 newTagIds 少的id 是需要新增的
|
|||
|
|
let addTagIds = newTagIds.filter(
|
|||
|
|
(item) => !memberWeComTagIds.includes(item)
|
|||
|
|
);
|
|||
|
|
// 删除标签
|
|||
|
|
tag = tag.filter((item) => !delTagIds.includes(item));
|
|||
|
|
// 新增标签
|
|||
|
|
tag = Array.from(new Set([...tag, ...addTagIds]));
|
|||
|
|
console.log("客户标签tagIds", tag);
|
|||
|
|
let params = {
|
|||
|
|
tagIds: tag,
|
|||
|
|
};
|
|||
|
|
if (createType === "auto") params["name"] = name;
|
|||
|
|
console.log("更新标签参数", params);
|
|||
|
|
await db
|
|||
|
|
.collection("member")
|
|||
|
|
.updateOne({ _id: data[i]._id }, { $set: params });
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "更新标签成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 合并自动建档
|
|||
|
|
* @param {*} param0
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
async function asyncAutoCustomerArchives({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId,
|
|||
|
|
id,
|
|||
|
|
createType,
|
|||
|
|
}) {
|
|||
|
|
if (!externalUserId || createType === "auto") return;
|
|||
|
|
let autoCustomer = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.findOne({ corpId, externalUserId, createType: "auto" });
|
|||
|
|
console.log("获取到自动建档档案", autoCustomer);
|
|||
|
|
if (autoCustomer) {
|
|||
|
|
// 合并这些字段
|
|||
|
|
let currentCustomer = await db.collection("member").findOne({ _id: id });
|
|||
|
|
let { teamId = [], tagIds = [], personResponsibles = [] } = autoCustomer;
|
|||
|
|
let {
|
|||
|
|
tagIds: currentTagIds = [],
|
|||
|
|
personResponsibles: currentPersonResponsibles = [],
|
|||
|
|
customerSource: currentCustomerSource = [],
|
|||
|
|
teamId: currentTeamId = [],
|
|||
|
|
} = currentCustomer;
|
|||
|
|
let newTeamId = Array.from(new Set([...teamId, ...currentTeamId])); // 合并团队
|
|||
|
|
let newTag = Array.from(new Set([...tagIds, ...currentTagIds])); // 合并标签
|
|||
|
|
let newPersonResponsible = personResponsibles || [];
|
|||
|
|
currentPersonResponsibles.forEach((item) => {
|
|||
|
|
if (
|
|||
|
|
!personResponsibles.find(
|
|||
|
|
(i) => i.teamId === item.teamId && i.corpUserId === item.corpUserId
|
|||
|
|
)
|
|||
|
|
) {
|
|||
|
|
newPersonResponsible.push(item);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
await db.collection("member").deleteOne({ _id: autoCustomer._id });
|
|||
|
|
let params = {
|
|||
|
|
tagIds: newTag,
|
|||
|
|
personResponsibles: newPersonResponsible,
|
|||
|
|
customerSource: currentCustomerSource,
|
|||
|
|
updateTime: new Date().getTime(),
|
|||
|
|
teamId: newTeamId,
|
|||
|
|
createType: "manual",
|
|||
|
|
};
|
|||
|
|
await db.collection("member").updateOne({ _id: id }, { $set: params });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* @param {string} id - 客户id
|
|||
|
|
* @param {object} params - 更新参数
|
|||
|
|
* @param {string} env - 环境ID
|
|||
|
|
* @param {string} userId - 用户ID
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
async function updateMember({
|
|||
|
|
id,
|
|||
|
|
params,
|
|||
|
|
userId,
|
|||
|
|
corpId,
|
|||
|
|
createTeamId,
|
|||
|
|
createTeamName,
|
|||
|
|
operationType,
|
|||
|
|
}) {
|
|||
|
|
const member = await db.collection("member").findOne({ _id: id });
|
|||
|
|
if (params.corpId === "undefined" || !params.corpId) {
|
|||
|
|
delete params.corpId;
|
|||
|
|
}
|
|||
|
|
params["updateTime"] = new Date().getTime();
|
|||
|
|
if ("age" in params && params["age"] !== undefined) {
|
|||
|
|
params["age"] = parseInt(params["age"]) > 0 ? parseInt(params["age"]) : "";
|
|||
|
|
}
|
|||
|
|
if (params.idCard) {
|
|||
|
|
const { gender, birthDate, age } = utils.calculateIdCardInfo(params.idCard);
|
|||
|
|
params.sex = gender;
|
|||
|
|
params.birthday = birthDate;
|
|||
|
|
params.age = age;
|
|||
|
|
const repeatIdCardCount = await db.collection("member").countDocuments({
|
|||
|
|
idCard: params.idCard,
|
|||
|
|
_id: { $ne: id },
|
|||
|
|
});
|
|||
|
|
if (repeatIdCardCount > 0) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "已存在相同身份证号档案!",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
params.createType = "manual";
|
|||
|
|
if (member.createType === "auto") params.creator = userId || "";
|
|||
|
|
// 自动更新最新的出生日期时间戳
|
|||
|
|
if (member && (params.idCard || params.birthday)) {
|
|||
|
|
const mergeData = { ...member, ...params };
|
|||
|
|
const birthdayStamp = helpers.getBirthdayStamp(mergeData);
|
|||
|
|
if (birthdayStamp) params["birthdayStamp"] = birthdayStamp;
|
|||
|
|
if (!mergeData.birthday && !mergeData.idCard && "birthdayStamp" in member) {
|
|||
|
|
params["birthdayStamp"] = undefined;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
await db.collection("member").updateOne({ _id: id }, { $set: params });
|
|||
|
|
// 合并自动建档
|
|||
|
|
const asyncAutoCustomerArchivesTask = asyncAutoCustomerArchives({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId: params.externalUserId,
|
|||
|
|
id,
|
|||
|
|
createType: params.createType,
|
|||
|
|
});
|
|||
|
|
// 修改了名字, 同步到企业微信备注名
|
|||
|
|
if (!params.externalUserId && params.unbindExternalUserId)
|
|||
|
|
params.externalUserId = params.unbindExternalUserId;
|
|||
|
|
let reMarkTask = null;
|
|||
|
|
if (params.externalUserId || params.name) {
|
|||
|
|
reMarkTask = exports.editExternalContactRemark({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId: params.externalUserId,
|
|||
|
|
memberId: id,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 触发SOP任务
|
|||
|
|
const query = {
|
|||
|
|
...params,
|
|||
|
|
externalUserId: member.externalUserId,
|
|||
|
|
personResponsibles: member.personResponsibles,
|
|||
|
|
};
|
|||
|
|
if (
|
|||
|
|
params.externalUserId &&
|
|||
|
|
dayjs().startOf("day").valueOf() < member.createTime
|
|||
|
|
) {
|
|||
|
|
query.externalUserId = params.externalUserId;
|
|||
|
|
query.createTime = member.createTime;
|
|||
|
|
}
|
|||
|
|
const sopTask = triggerSoptask({
|
|||
|
|
corpId,
|
|||
|
|
params: query,
|
|||
|
|
customerId: id,
|
|||
|
|
});
|
|||
|
|
// 添加服务记录
|
|||
|
|
const createServiceRecordTask = await createServiceRecordTaskFnc({
|
|||
|
|
corpId,
|
|||
|
|
id,
|
|||
|
|
userId,
|
|||
|
|
member,
|
|||
|
|
createTeamId,
|
|||
|
|
createTeamName,
|
|||
|
|
operationType,
|
|||
|
|
params,
|
|||
|
|
});
|
|||
|
|
await Promise.all([
|
|||
|
|
asyncAutoCustomerArchivesTask,
|
|||
|
|
reMarkTask,
|
|||
|
|
sopTask,
|
|||
|
|
...createServiceRecordTask,
|
|||
|
|
]);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "更新成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
// 创建服务记录
|
|||
|
|
async function createServiceRecordTaskFnc({
|
|||
|
|
corpId,
|
|||
|
|
id,
|
|||
|
|
userId = "",
|
|||
|
|
member,
|
|||
|
|
createTeamId,
|
|||
|
|
createTeamName,
|
|||
|
|
operationType,
|
|||
|
|
params,
|
|||
|
|
}) {
|
|||
|
|
let customerName = params.name || member.name;
|
|||
|
|
// 添加服务记录
|
|||
|
|
let query = {
|
|||
|
|
eventType: "customerUpdate",
|
|||
|
|
customerId: id,
|
|||
|
|
executorUserId: userId,
|
|||
|
|
executeTeamId: createTeamId,
|
|||
|
|
createTeamName,
|
|||
|
|
creatorUserId: userId,
|
|||
|
|
corpId,
|
|||
|
|
customerName: customerName,
|
|||
|
|
createTime: dayjs().valueOf(),
|
|||
|
|
executionTime: dayjs().valueOf(),
|
|||
|
|
customerUserId: member.externalUserId,
|
|||
|
|
taskContent: `更新客户档案信息`,
|
|||
|
|
};
|
|||
|
|
if (member.createType === "auto") {
|
|||
|
|
query.eventType = "remindFiling";
|
|||
|
|
}
|
|||
|
|
if (!userId) return [];
|
|||
|
|
let addServiceRecordTaskList = [];
|
|||
|
|
if (params.teamId && operationType === "adminEditTeam") {
|
|||
|
|
let addTeamIds = params.teamId.filter(
|
|||
|
|
(item) => !member.teamId.includes(item)
|
|||
|
|
);
|
|||
|
|
let removeTeamIds = member.teamId.filter(
|
|||
|
|
(item) => !params.teamId.includes(item)
|
|||
|
|
);
|
|||
|
|
if (addTeamIds.length > 0) {
|
|||
|
|
const teamNames = await getTeamNamesByTeamIds({
|
|||
|
|
corpId,
|
|||
|
|
teamIds: addTeamIds,
|
|||
|
|
});
|
|||
|
|
query.eventType = "adminAllocateTeams";
|
|||
|
|
query.taskContent = `管理员把${customerName}分配给“${teamNames.join(
|
|||
|
|
"、"
|
|||
|
|
)}“团队`;
|
|||
|
|
query.transferToTeamIds = addTeamIds;
|
|||
|
|
addServiceRecordTaskList.push(appFunction.addServiceRecord(query));
|
|||
|
|
}
|
|||
|
|
if (removeTeamIds.length > 0) {
|
|||
|
|
const teamNames = await getTeamNamesByTeamIds({
|
|||
|
|
corpId,
|
|||
|
|
teamIds: removeTeamIds,
|
|||
|
|
});
|
|||
|
|
query.eventType = "adminRemoveTeams";
|
|||
|
|
query.removeTeamIds = removeTeamIds;
|
|||
|
|
query.taskContent = `管理员解除${customerName}与”${teamNames.join(
|
|||
|
|
"、"
|
|||
|
|
)}“团队的关联`;
|
|||
|
|
addServiceRecordTaskList.push(appFunction.addServiceRecord(query));
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
addServiceRecordTaskList = [appFunction.addServiceRecord(query)];
|
|||
|
|
}
|
|||
|
|
return addServiceRecordTaskList;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function getTeamNamesByTeamIds({ corpId, teamIds }) {
|
|||
|
|
const teams = await db
|
|||
|
|
.collection("team")
|
|||
|
|
.find({ corpId, teamId: { $in: teamIds } })
|
|||
|
|
.toArray();
|
|||
|
|
return teams.map((item) => item.name);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 新增成员
|
|||
|
|
* @param {object} params - 成员信息
|
|||
|
|
* @param {string} createTeamId - 创建团队ID
|
|||
|
|
* @param {string} createTeamName - 创建团队名称
|
|||
|
|
* @returns {object} 新增结果
|
|||
|
|
*/
|
|||
|
|
async function addMember({ params, createTeamId, createTeamName }) {
|
|||
|
|
const { corpId, name, teamId, idCard } = params;
|
|||
|
|
if (!corpId || corpId === "undefined") {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "机构Id未传",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (!name) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "姓名不能为空",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (idCard) {
|
|||
|
|
const { gender, birthDate, age } = utils.calculateIdCardInfo(idCard);
|
|||
|
|
params.sex = gender;
|
|||
|
|
params.birthday = birthDate;
|
|||
|
|
params.age = age;
|
|||
|
|
}
|
|||
|
|
const limitation = await corpCustomtorLimitation(corpId);
|
|||
|
|
if (!limitation) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "客户数已达上限",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (params.idCard) {
|
|||
|
|
const repeat = await isIdCardRepeat(params.idCard, corpId);
|
|||
|
|
if (repeat)
|
|||
|
|
return { success: false, message: "您的档案已存在,请勿重复建档!" };
|
|||
|
|
}
|
|||
|
|
params["createTime"] = new Date().getTime();
|
|||
|
|
params["customerStage"] = params["customerStage"] || "OMINHOSPITALA";
|
|||
|
|
if (teamId && typeof teamId === "string") {
|
|||
|
|
params["teamId"] = [teamId];
|
|||
|
|
}
|
|||
|
|
if ("age" in params) {
|
|||
|
|
params["age"] = parseInt(params["age"]) > 0 ? parseInt(params["age"]) : "";
|
|||
|
|
}
|
|||
|
|
params.inHospitalTimes = [];
|
|||
|
|
if (typeof params.teamId === "string") params.teamId = [params.teamId];
|
|||
|
|
const birthdayStamp = helpers.getBirthdayStamp(params);
|
|||
|
|
if (birthdayStamp) params["birthdayStamp"] = birthdayStamp;
|
|||
|
|
params["_id"] = common.generateRandomString(24);
|
|||
|
|
const res = await db.collection("member").insertOne(params);
|
|||
|
|
// 合并自动建档
|
|||
|
|
const asyncAutoCustomerArchivesTask = asyncAutoCustomerArchives({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId: params.externalUserId,
|
|||
|
|
id: res.insertedId,
|
|||
|
|
createType: params.createType,
|
|||
|
|
});
|
|||
|
|
// 修改了名字, 同步到企业微信备注名
|
|||
|
|
const editRemarkTask = exports.editExternalContactRemark({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId: params.externalUserId,
|
|||
|
|
});
|
|||
|
|
// 触发SOP任务
|
|||
|
|
const sopTask = triggerSoptask({
|
|||
|
|
corpId,
|
|||
|
|
params,
|
|||
|
|
customerId: res.insertedId,
|
|||
|
|
});
|
|||
|
|
// 添加服务记录
|
|||
|
|
let query = {
|
|||
|
|
eventType: "remindFiling",
|
|||
|
|
customerId: res.insertedId,
|
|||
|
|
executorUserId: params.creator,
|
|||
|
|
executeTeamId: createTeamId,
|
|||
|
|
createTeamName,
|
|||
|
|
creatorUserId: params.creator,
|
|||
|
|
corpId,
|
|||
|
|
customerName: params.name,
|
|||
|
|
createTime: dayjs().valueOf(),
|
|||
|
|
taskContent: `&&&${params.creator || ""}&&&新增客户${params.name}`,
|
|||
|
|
executionTime: dayjs().valueOf(),
|
|||
|
|
customerUserId: params.externalUserId,
|
|||
|
|
};
|
|||
|
|
// 采集方式 addMethod 手动录入、扫码加好友自动建档、推送建档链接、网电报备
|
|||
|
|
if (params.createType === "auto") {
|
|||
|
|
query.addMethod = "扫码加好友自动建档";
|
|||
|
|
} else if (params.addMethod === "eStoreReport") {
|
|||
|
|
query.addMethod = "网电报备";
|
|||
|
|
} else if (params.addMethod === "pushLink") {
|
|||
|
|
query.addMethod = "推送建档链接";
|
|||
|
|
} else {
|
|||
|
|
query.addMethod = "手动录入";
|
|||
|
|
}
|
|||
|
|
query.taskContent = query.taskContent + `,采集方式:${query.addMethod}`;
|
|||
|
|
const addServiceRecordTask = params.creator
|
|||
|
|
? appFunction.addServiceRecord(query)
|
|||
|
|
: "";
|
|||
|
|
await Promise.all([
|
|||
|
|
asyncAutoCustomerArchivesTask,
|
|||
|
|
editRemarkTask,
|
|||
|
|
sopTask,
|
|||
|
|
addServiceRecordTask,
|
|||
|
|
]);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "添加成功",
|
|||
|
|
data: {
|
|||
|
|
id: res.insertedId,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 触发SOP任务
|
|||
|
|
* @param {object} params - 参数
|
|||
|
|
* @returns {object} 触发结果
|
|||
|
|
*/
|
|||
|
|
async function triggerSoptask({ corpId, params, customerId }) {
|
|||
|
|
const { personResponsibles } = params;
|
|||
|
|
if (!personResponsibles || !corpId) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "触发SOP任务失败",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const query = {
|
|||
|
|
corpId,
|
|||
|
|
customerId,
|
|||
|
|
archive: params,
|
|||
|
|
};
|
|||
|
|
console.log("触发SOP任务参数", query);
|
|||
|
|
let res = await sop.main(
|
|||
|
|
{
|
|||
|
|
type: "triggerSopTask",
|
|||
|
|
...query,
|
|||
|
|
},
|
|||
|
|
db
|
|||
|
|
);
|
|||
|
|
console.log("触发SOP任务");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据客户ID触发SOP任务
|
|||
|
|
* @param {object} params - 参数
|
|||
|
|
* @returns {object} 触发结果
|
|||
|
|
*/
|
|||
|
|
async function triggerSoptaskByCustomerId({ corpId, customerId }) {
|
|||
|
|
const {
|
|||
|
|
data: [member],
|
|||
|
|
} = await db.collection("member").find({ _id: customerId }).toArray();
|
|||
|
|
const query = {
|
|||
|
|
corpId,
|
|||
|
|
customerId,
|
|||
|
|
archive: member,
|
|||
|
|
};
|
|||
|
|
console.log("触发SOP任务参数", query);
|
|||
|
|
let res = await sop.main(
|
|||
|
|
{
|
|||
|
|
type: "triggerSopTask",
|
|||
|
|
...query,
|
|||
|
|
},
|
|||
|
|
db
|
|||
|
|
);
|
|||
|
|
console.log("触发SOP任务", res);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 删除成员
|
|||
|
|
* @param {string} id - 成员id
|
|||
|
|
* @param {string} corpId - 企业微信ID
|
|||
|
|
* @returns {object} 删除结果
|
|||
|
|
*/
|
|||
|
|
async function deleteMember({ id, corpId }) {
|
|||
|
|
try {
|
|||
|
|
await exports.editExternalContactRemark({
|
|||
|
|
memberId: id,
|
|||
|
|
corpId,
|
|||
|
|
deleteMemberId: id,
|
|||
|
|
});
|
|||
|
|
const res = await db.collection("member").deleteOne({ _id: id });
|
|||
|
|
// 删除成员时, 删除SOP任务
|
|||
|
|
await sop.main({ type: "deleteSopTask", corpId, customerId: id }, db);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "删除成功",
|
|||
|
|
data: res,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 机构客户数限制
|
|||
|
|
* @param {string} corpId - 企业微信ID
|
|||
|
|
* @returns {boolean} 是否超出限制
|
|||
|
|
*/
|
|||
|
|
async function corpCustomtorLimitation(corpId) {
|
|||
|
|
const memberCount = await db.collection("member").find({ corpId }).count();
|
|||
|
|
const { data } = await api.getCorpApi({ type: "getCorpInfo", corpId });
|
|||
|
|
const corp = data && data[0] ? data[0] : {};
|
|||
|
|
const { package } = corp;
|
|||
|
|
if (!package) return false;
|
|||
|
|
const { customerCount, giveCustomerCount } = package;
|
|||
|
|
return memberCount < customerCount + giveCustomerCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 判断身份证是否重复
|
|||
|
|
* @param {string} idCard - 身份证号
|
|||
|
|
* @param {string} corpId - 企业微信ID
|
|||
|
|
* @returns {boolean} 是否重复
|
|||
|
|
*/
|
|||
|
|
async function isIdCardRepeat(idCard, corpId) {
|
|||
|
|
try {
|
|||
|
|
const res = await db.collection("member").find({ corpId, idCard }).count();
|
|||
|
|
return res > 0;
|
|||
|
|
} catch (e) {
|
|||
|
|
return Promise.reject(e.message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取推荐人信息
|
|||
|
|
* @param {object} ctx - 上下文
|
|||
|
|
* @returns {object} 推荐人信息
|
|||
|
|
*/
|
|||
|
|
async function getReferredPeople(ctx) {
|
|||
|
|
try {
|
|||
|
|
const { id: referenceCustomerId, corpId } = ctx;
|
|||
|
|
if (referenceCustomerId && corpId) {
|
|||
|
|
const page =
|
|||
|
|
typeof ctx.page === "number" && ctx.page % 1 === 0 && ctx.page > 0
|
|||
|
|
? ctx.page
|
|||
|
|
: 1;
|
|||
|
|
const pageSize =
|
|||
|
|
typeof ctx.pageSize === "number" &&
|
|||
|
|
ctx.pageSize % 1 === 0 &&
|
|||
|
|
ctx.pageSize > 0
|
|||
|
|
? ctx.pageSize
|
|||
|
|
: 20;
|
|||
|
|
const res = db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ referenceCustomerId, corpId, referenceType: "客户" })
|
|||
|
|
.skip((page - 1) * pageSize)
|
|||
|
|
.limit(pageSize)
|
|||
|
|
.project({ name: true, teamId: true, sex: true, mobile: true });
|
|||
|
|
const data = await res.toArray();
|
|||
|
|
const total = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ referenceCustomerId, corpId, referenceType: "客户" })
|
|||
|
|
.count();
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
list: data,
|
|||
|
|
pages: Math.ceil(total / pageSize),
|
|||
|
|
message: "查询成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
return { success: false, message: "参数错误" };
|
|||
|
|
} catch (e) {
|
|||
|
|
return { success: false, message: e.message };
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 将年龄字段转换为数字
|
|||
|
|
async function setAgeToNumber() {
|
|||
|
|
const batchSize = 100; // 每次处理的文档数量
|
|||
|
|
let totalUpdated = 0;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
while (true) {
|
|||
|
|
console.log(`Processing batch...`);
|
|||
|
|
// 查询一批符合条件的文档
|
|||
|
|
const queryResult = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({
|
|||
|
|
age: { $regex: "^[0-9]+$", $options: "i" },
|
|||
|
|
})
|
|||
|
|
.limit(batchSize)
|
|||
|
|
.project({ _id: true, age: true })
|
|||
|
|
.toArray();
|
|||
|
|
if (queryResult.length === 0) {
|
|||
|
|
break; // 没有更多文档需要处理
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const bulkOps = queryResult
|
|||
|
|
.map((doc) => {
|
|||
|
|
const age = parseInt(doc.age, 10);
|
|||
|
|
if (!isNaN(age)) {
|
|||
|
|
return {
|
|||
|
|
updateOne: {
|
|||
|
|
filter: { _id: doc._id },
|
|||
|
|
update: { $set: { age: age } },
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.filter(Boolean);
|
|||
|
|
|
|||
|
|
if (bulkOps.length > 0) {
|
|||
|
|
const result = await db.collection("member").bulkWrite(bulkOps);
|
|||
|
|
totalUpdated += result.modifiedCount;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: `${totalUpdated} documents updated.`,
|
|||
|
|
};
|
|||
|
|
} catch (err) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
error: err,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取成员信息
|
|||
|
|
async function getMember(context) {
|
|||
|
|
let { unionid, corpId, corpUserId, params = {}, externalUserIds } = context;
|
|||
|
|
if (!corpId || corpId === "undefined") {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "机构Id未传",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
if (corpUserId) params.teamId = await getTeamList(corpUserId, corpId);
|
|||
|
|
if (unionid) params.unionid = unionid;
|
|||
|
|
if (externalUserIds) params.externalUserId = { $in: externalUserIds };
|
|||
|
|
if (typeof params.name === "string" && params.name.trim()) {
|
|||
|
|
params.name = { $regex: ".*" + params.name.trim() + ".*", $options: "i" };
|
|||
|
|
}
|
|||
|
|
const fetchData = async (page, pageSize, db) => {
|
|||
|
|
let data = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({
|
|||
|
|
corpId,
|
|||
|
|
...params,
|
|||
|
|
})
|
|||
|
|
.skip((page - 1) * pageSize)
|
|||
|
|
.limit(pageSize)
|
|||
|
|
.sort({ createTime: -1 })
|
|||
|
|
.toArray();
|
|||
|
|
return data;
|
|||
|
|
};
|
|||
|
|
const list = await utils.getAllData(fetchData, db);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: list,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取侧边栏客户数据
|
|||
|
|
async function getCustomerInSidebar(context) {
|
|||
|
|
let { corpId, teamIds, externalUserId } = context;
|
|||
|
|
if (!corpId || corpId === "undefined") {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "机构Id未传",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (!externalUserId) return { success: false, message: "外部联系人id未传" };
|
|||
|
|
try {
|
|||
|
|
const res = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({
|
|||
|
|
corpId,
|
|||
|
|
externalUserId,
|
|||
|
|
})
|
|||
|
|
.sort({ createTime: -1 })
|
|||
|
|
.limit(100)
|
|||
|
|
.project({
|
|||
|
|
externalContactInfo: false,
|
|||
|
|
})
|
|||
|
|
.toArray();
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: res,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据团队ID获取客户总数
|
|||
|
|
async function getmemberCountForTeamId(context) {
|
|||
|
|
const { time, params } = context;
|
|||
|
|
if (time === "THISMONTH") {
|
|||
|
|
const { startOfThisMouthTimestamp, endOfThisMouthTimestamp } =
|
|||
|
|
getThisMouth();
|
|||
|
|
params["createTime"] = {
|
|||
|
|
$gte: startOfThisMouthTimestamp,
|
|||
|
|
$lte: endOfThisMouthTimestamp,
|
|||
|
|
};
|
|||
|
|
} else if (time === "LASTMONTH") {
|
|||
|
|
const { lastMonthStartDateTimestamp, lastMonthEndDateTimestamp } =
|
|||
|
|
getlastMonthStartTimeAndEndTime();
|
|||
|
|
params["createTime"] = {
|
|||
|
|
$gte: lastMonthStartDateTimestamp,
|
|||
|
|
$lte: lastMonthEndDateTimestamp,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
const res = await db.collection("member").find(params).count();
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: res,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据userId 获取客户总数
|
|||
|
|
async function getmemberAndserviceCountForUserId(context) {
|
|||
|
|
const { params, teamId } = context;
|
|||
|
|
const { corpId, userId, startTime, endTime } = params;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const memberQuery = {
|
|||
|
|
corpId,
|
|||
|
|
};
|
|||
|
|
if (teamId) {
|
|||
|
|
memberQuery.teamId = teamId;
|
|||
|
|
memberQuery.personResponsibles = {
|
|||
|
|
$elemMatch: {
|
|||
|
|
corpUserId: userId,
|
|||
|
|
teamId: teamId,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
memberQuery.personResponsibles = {
|
|||
|
|
$elemMatch: {
|
|||
|
|
corpUserId: userId,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (startTime && dayjs(startTime).isValid()) {
|
|||
|
|
const startTimestamp = dayjs(startTime).startOf("day").valueOf();
|
|||
|
|
memberQuery.createTime = memberQuery.createTime || {};
|
|||
|
|
memberQuery.createTime.$gte = startTimestamp;
|
|||
|
|
}
|
|||
|
|
if (endTime && dayjs(endTime).isValid()) {
|
|||
|
|
const endTimestamp = dayjs(endTime).endOf("day").valueOf();
|
|||
|
|
memberQuery.createTime = memberQuery.createTime || {};
|
|||
|
|
memberQuery.createTime.$lte = endTimestamp;
|
|||
|
|
}
|
|||
|
|
const memberTotal = await db.collection("member").find(memberQuery).count();
|
|||
|
|
const serviceQuery = {
|
|||
|
|
corpId,
|
|||
|
|
executorUserId: userId,
|
|||
|
|
eventType: { $ne: "serviceRate" },
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (startTime && dayjs(startTime).isValid()) {
|
|||
|
|
const startTimestamp = dayjs(startTime).startOf("day").valueOf();
|
|||
|
|
serviceQuery.executionTime = serviceQuery.executionTime || {};
|
|||
|
|
serviceQuery.executionTime.$gte = startTimestamp;
|
|||
|
|
}
|
|||
|
|
if (endTime && dayjs(endTime).isValid()) {
|
|||
|
|
const endTimestamp = dayjs(endTime).endOf("day").valueOf();
|
|||
|
|
serviceQuery.executionTime = serviceQuery.executionTime || {};
|
|||
|
|
serviceQuery.executionTime.$lte = endTimestamp;
|
|||
|
|
}
|
|||
|
|
if (teamId) {
|
|||
|
|
serviceQuery.executeTeamId = teamId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const serviceTotal = await db
|
|||
|
|
.collection("service-record")
|
|||
|
|
.find(serviceQuery)
|
|||
|
|
.count();
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: {
|
|||
|
|
memberTotal,
|
|||
|
|
serviceTotal,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error.message,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
async function getmemberAndserviceCountForUserId(context) {
|
|||
|
|
const { params, teamId } = context;
|
|||
|
|
const { corpId, userId, startTime, endTime } = params;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const memberQuery = {
|
|||
|
|
corpId,
|
|||
|
|
};
|
|||
|
|
if (teamId) {
|
|||
|
|
memberQuery.teamId = teamId;
|
|||
|
|
memberQuery.personResponsibles = {
|
|||
|
|
$elemMatch: {
|
|||
|
|
corpUserId: userId,
|
|||
|
|
teamId: teamId,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
memberQuery.personResponsibles = {
|
|||
|
|
$elemMatch: {
|
|||
|
|
corpUserId: userId,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (startTime && dayjs(startTime).isValid()) {
|
|||
|
|
const startTimestamp = dayjs(startTime).startOf("day").valueOf();
|
|||
|
|
memberQuery.createTime = memberQuery.createTime || {};
|
|||
|
|
memberQuery.createTime.$gte = startTimestamp;
|
|||
|
|
}
|
|||
|
|
if (endTime && dayjs(endTime).isValid()) {
|
|||
|
|
const endTimestamp = dayjs(endTime).endOf("day").valueOf();
|
|||
|
|
memberQuery.createTime = memberQuery.createTime || {};
|
|||
|
|
memberQuery.createTime.$lte = endTimestamp;
|
|||
|
|
}
|
|||
|
|
const memberTotal = await db.collection("member").find(memberQuery).count();
|
|||
|
|
const serviceQuery = {
|
|||
|
|
corpId,
|
|||
|
|
executorUserId: userId,
|
|||
|
|
eventType: { $ne: "serviceRate" },
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (startTime && dayjs(startTime).isValid()) {
|
|||
|
|
const startTimestamp = dayjs(startTime).startOf("day").valueOf();
|
|||
|
|
serviceQuery.executionTime = serviceQuery.executionTime || {};
|
|||
|
|
serviceQuery.executionTime.$gte = startTimestamp;
|
|||
|
|
}
|
|||
|
|
if (endTime && dayjs(endTime).isValid()) {
|
|||
|
|
const endTimestamp = dayjs(endTime).endOf("day").valueOf();
|
|||
|
|
serviceQuery.executionTime = serviceQuery.executionTime || {};
|
|||
|
|
serviceQuery.executionTime.$lte = endTimestamp;
|
|||
|
|
}
|
|||
|
|
if (teamId) {
|
|||
|
|
serviceQuery.executeTeamId = teamId;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const serviceTotal = await db
|
|||
|
|
.collection("service-record")
|
|||
|
|
.find(serviceQuery)
|
|||
|
|
.count();
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: {
|
|||
|
|
memberTotal,
|
|||
|
|
serviceTotal,
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error.message,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取上个月的开始和结束时间戳
|
|||
|
|
function getlastMonthStartTimeAndEndTime() {
|
|||
|
|
const currentDate = new Date();
|
|||
|
|
const lastMonthYear = currentDate.getFullYear();
|
|||
|
|
const lastMonth = currentDate.getMonth() - 1;
|
|||
|
|
const lastMonthLastDate = new Date(lastMonthYear, lastMonth + 1, 0);
|
|||
|
|
const lastMonthStartDate = new Date(lastMonthYear, lastMonth, 1, 0, 0, 0);
|
|||
|
|
const lastMonthStartDateTimestamp = lastMonthStartDate.getTime();
|
|||
|
|
const lastMonthEndDate = new Date(
|
|||
|
|
lastMonthYear,
|
|||
|
|
lastMonth,
|
|||
|
|
lastMonthLastDate.getDate(),
|
|||
|
|
23,
|
|||
|
|
59,
|
|||
|
|
59
|
|||
|
|
);
|
|||
|
|
const lastMonthEndDateTimestamp = lastMonthEndDate.getTime();
|
|||
|
|
return {
|
|||
|
|
lastMonthStartDateTimestamp,
|
|||
|
|
lastMonthEndDateTimestamp,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取本月的开始时间戳
|
|||
|
|
function getThisMouth() {
|
|||
|
|
const currentDate = new Date();
|
|||
|
|
currentDate.setDate(1);
|
|||
|
|
currentDate.setHours(0, 0, 0, 0);
|
|||
|
|
const startOfThisMouthTimestamp = currentDate.getTime();
|
|||
|
|
return {
|
|||
|
|
startOfThisMouthTimestamp,
|
|||
|
|
endOfThisMouthTimestamp: new Date().getTime(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据标签ID获取成员列表
|
|||
|
|
async function getMemberBytags(context) {
|
|||
|
|
const { corpId, tagIds, userId } = context;
|
|||
|
|
let params = { corpId, tagIds: { $in: tagIds } };
|
|||
|
|
if (userId) params["teamId"] = await getTeamList(userId, corpId);
|
|||
|
|
try {
|
|||
|
|
const res = await db.collection("member").find(params).toArray();
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: res,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "获取失败",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取企业客户
|
|||
|
|
async function getCorpCustomer(context) {
|
|||
|
|
try {
|
|||
|
|
let {
|
|||
|
|
page,
|
|||
|
|
pageSize,
|
|||
|
|
type,
|
|||
|
|
startCreateTime,
|
|||
|
|
endCreateTime,
|
|||
|
|
corpUserId,
|
|||
|
|
showExternalCustomer,
|
|||
|
|
permanent_code,
|
|||
|
|
userIds,
|
|||
|
|
teamId,
|
|||
|
|
accessToken,
|
|||
|
|
...params
|
|||
|
|
} = context;
|
|||
|
|
const { corpId } = params;
|
|||
|
|
|
|||
|
|
// 校验企业ID是否为空
|
|||
|
|
if (!corpId) return { success: false, message: "机构ID不能为空" };
|
|||
|
|
|
|||
|
|
// 根据name进行模糊查询
|
|||
|
|
if (typeof params.name === "string" && params.name.trim()) {
|
|||
|
|
params.name = new RegExp(".*" + params.name.trim(), "i");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据mobile进行模糊查询
|
|||
|
|
if (typeof params.mobile === "string" && params.mobile.trim()) {
|
|||
|
|
const pattern = params.mobile.trim().split("").join(".*");
|
|||
|
|
params.mobile = new RegExp(pattern, "i");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果有teamId进行团队筛选
|
|||
|
|
if (teamId) {
|
|||
|
|
if (Array.isArray(teamId)) {
|
|||
|
|
params["teamId"] = { $in: teamId };
|
|||
|
|
} else {
|
|||
|
|
params["teamId"] = teamId;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showExternalCustomer) {
|
|||
|
|
params["externalUserId"] = { $exists: true };
|
|||
|
|
params["personResponsibles"] = {
|
|||
|
|
$elemMatch: { corpUserId: { $in: userIds } },
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果teamId是'无',设置为无效值
|
|||
|
|
if (teamId === "无") {
|
|||
|
|
params.teamId = { $or: [{ $eq: [] }, { $exists: false }, { $eq: "" }] };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果有tagIds,进行标签筛选
|
|||
|
|
if (Array.isArray(params.tagIds) && params.tagIds.length) {
|
|||
|
|
params.tagIds = { $all: params.tagIds }; // 匹配所有指定tagId
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据时间范围过滤数据
|
|||
|
|
if (startCreateTime && endCreateTime) {
|
|||
|
|
const startTime = dayjs(startCreateTime).startOf("day").valueOf();
|
|||
|
|
const endTime = dayjs(endCreateTime).endOf("day").valueOf();
|
|||
|
|
params["createTime"] = { $gte: startTime, $lte: endTime };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 聚合管道
|
|||
|
|
const pipeline = [
|
|||
|
|
{ $match: params }, // 过滤条件
|
|||
|
|
{ $sort: { createTime: -1 } }, // 按createTime降序排序
|
|||
|
|
{ $skip: (page - 1) * pageSize }, // 分页跳过的记录数
|
|||
|
|
{ $limit: pageSize }, // 设置分页大小
|
|||
|
|
{
|
|||
|
|
$lookup: {
|
|||
|
|
from: "member-management-plan", // 关联的集合
|
|||
|
|
localField: "_id", // 当前集合字段
|
|||
|
|
foreignField: "customerId", // 关联集合字段
|
|||
|
|
as: "plans", // 返回的字段名
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
$project: showExternalCustomer
|
|||
|
|
? { _id: 1, name: 1 }
|
|||
|
|
: { _id: 1, name: 1, plans: 1 }, // 返回需要的字段
|
|||
|
|
},
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 获取总数的聚合管道
|
|||
|
|
const totalPipeline = [
|
|||
|
|
{ $match: params },
|
|||
|
|
{ $count: "total" }, // 获取符合条件的总数
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 执行总数查询
|
|||
|
|
const totalResult = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.aggregate(totalPipeline)
|
|||
|
|
.toArray();
|
|||
|
|
const total = totalResult.length ? totalResult[0].total : 0;
|
|||
|
|
const pages = Math.ceil(total / pageSize);
|
|||
|
|
|
|||
|
|
// 执行数据查询
|
|||
|
|
const memberList = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.aggregate(pipeline)
|
|||
|
|
.toArray();
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: memberList,
|
|||
|
|
total: total,
|
|||
|
|
pages: pages,
|
|||
|
|
size: pageSize,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error.toString(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据团队ID获取成员列表
|
|||
|
|
async function getMemberForTeam(context) {
|
|||
|
|
try {
|
|||
|
|
const { page, pageSize, corpId, params: data, teamId } = context;
|
|||
|
|
const { startCreateTime, endCreateTime, managementPlanStatus, ...params } =
|
|||
|
|
data || {};
|
|||
|
|
if (typeof params.name === "string" && params.name.trim()) {
|
|||
|
|
params.name = { $regex: ".*" + params.name.trim() + ".*", $options: "i" };
|
|||
|
|
}
|
|||
|
|
if (!teamId || (Array.isArray(teamId) && teamId.length == 0)) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "团队ID未传",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
params["corpId"] = corpId;
|
|||
|
|
params["teamId"] = teamId;
|
|||
|
|
if (Array.isArray(params.tagIds) && params.tagIds.length) {
|
|||
|
|
params.tagIds = { $and: params.tagIds.map((id) => ({ $in: [id] })) };
|
|||
|
|
}
|
|||
|
|
if (startCreateTime && endCreateTime) {
|
|||
|
|
params["createTime"] = {
|
|||
|
|
$and: [
|
|||
|
|
{ $gte: dayjs(startCreateTime).valueOf() },
|
|||
|
|
{ $lte: dayjs(endCreateTime).valueOf() },
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (params.startServiceTime || params.endServiceTime) {
|
|||
|
|
params["serviceTime"] = {
|
|||
|
|
$and: [
|
|||
|
|
{ $gte: params.startServiceTime },
|
|||
|
|
{ $lte: params.endServiceTime },
|
|||
|
|
],
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
if (params["groupIds"] === "no-id") {
|
|||
|
|
const groupIds = await getGroupIds(teamId);
|
|||
|
|
params["groupIds"] = { $nin: groupIds };
|
|||
|
|
}
|
|||
|
|
let planParams = {};
|
|||
|
|
if (managementPlanStatus) {
|
|||
|
|
planParams["plan.planExecutStaus"] = managementPlanStatus;
|
|||
|
|
}
|
|||
|
|
const total = await db.collection("member").find(params).count();
|
|||
|
|
const pages = Math.ceil(total / pageSize);
|
|||
|
|
const res = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.aggregate([
|
|||
|
|
{ $match: params },
|
|||
|
|
{ $sort: { createTime: -1 } },
|
|||
|
|
{ $skip: (page - 1) * pageSize },
|
|||
|
|
{ $limit: pageSize },
|
|||
|
|
{
|
|||
|
|
$lookup: {
|
|||
|
|
from: "member-management-plan",
|
|||
|
|
localField: "_id",
|
|||
|
|
foreignField: "customerId",
|
|||
|
|
as: "plans",
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
])
|
|||
|
|
.toArray();
|
|||
|
|
const list = res.map((item) => {
|
|||
|
|
item.plans.reverse();
|
|||
|
|
const plan = item.plans.find((plan) => plan.executeTeamId === teamId);
|
|||
|
|
delete item.plans;
|
|||
|
|
return {
|
|||
|
|
...item,
|
|||
|
|
plan: plan || {},
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: list,
|
|||
|
|
total: total,
|
|||
|
|
pages: pages,
|
|||
|
|
size: pageSize,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取团队的groupIds
|
|||
|
|
async function getGroupIds(teamId) {
|
|||
|
|
const data = await db.collection("group").find({ teamId }).toArray();
|
|||
|
|
const ids = data.map((item) => item._id);
|
|||
|
|
return ids;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取成员信息
|
|||
|
|
async function getMemberInfo(context) {
|
|||
|
|
try {
|
|||
|
|
const { params } = context;
|
|||
|
|
const res = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.aggregate([
|
|||
|
|
{ $match: params },
|
|||
|
|
{
|
|||
|
|
$lookup: {
|
|||
|
|
from: "member",
|
|||
|
|
let: { referenceCustomerId: "$_id" },
|
|||
|
|
pipeline: [
|
|||
|
|
{
|
|||
|
|
$match: {
|
|||
|
|
$expr: {
|
|||
|
|
$and: [
|
|||
|
|
{
|
|||
|
|
$eq: ["$referenceCustomerId", "$$referenceCustomerId"],
|
|||
|
|
},
|
|||
|
|
{ $eq: ["$referenceType", "客户"] },
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
as: "referenceCount",
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{ $addFields: { referenceCount: { $size: "$referenceCount" } } },
|
|||
|
|
])
|
|||
|
|
.toArray();
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "获取成功",
|
|||
|
|
data: res,
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 批量导入客户
|
|||
|
|
async function batchImportCustomer(context) {
|
|||
|
|
const { params } = context;
|
|||
|
|
let baseReatParams = Object.entries(params).reduce((prev, [key, value]) => {
|
|||
|
|
if (value) {
|
|||
|
|
prev[key] = value;
|
|||
|
|
}
|
|||
|
|
return prev;
|
|||
|
|
}, {});
|
|||
|
|
const { idCard, customerNumber } = baseReatParams;
|
|||
|
|
if (!idCard && !customerNumber)
|
|||
|
|
return { success: false, message: "身份证号和客户编号不能同时为空" };
|
|||
|
|
let getMemberParams = {};
|
|||
|
|
if (idCard) {
|
|||
|
|
getMemberParams["idCard"] = idCard;
|
|||
|
|
} else if (!idCard && customerNumber) {
|
|||
|
|
getMemberParams["customerNumber"] = customerNumber;
|
|||
|
|
}
|
|||
|
|
let newCustomerId = "";
|
|||
|
|
let operationType = "add";
|
|||
|
|
try {
|
|||
|
|
const customer = await db.collection("member").findOne(getMemberParams);
|
|||
|
|
if (customer) {
|
|||
|
|
baseReatParams["updateTime"] = new Date().getTime();
|
|||
|
|
operationType = "update";
|
|||
|
|
delete baseReatParams["creator"];
|
|||
|
|
await db
|
|||
|
|
.collection("member")
|
|||
|
|
.updateOne({ _id: customer._id }, { $set: baseReatParams });
|
|||
|
|
newCustomerId = customer._id;
|
|||
|
|
} else {
|
|||
|
|
baseReatParams["createTime"] = new Date().getTime();
|
|||
|
|
baseReatParams["_id"] = common.generateRandomString(24);
|
|||
|
|
const res = await db.collection("member").insertOne(baseReatParams);
|
|||
|
|
newCustomerId = res.insertedId;
|
|||
|
|
}
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
data: newCustomerId,
|
|||
|
|
operationType,
|
|||
|
|
customer,
|
|||
|
|
message: "导入成功",
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据externalUserId更新unionid
|
|||
|
|
* @param {object} context - 上下文
|
|||
|
|
* @returns {object} 更新结果
|
|||
|
|
*/
|
|||
|
|
async function externalUseridToMember(context) {
|
|||
|
|
const { externalUserId, unionid, corpId, realUnionid } = context;
|
|||
|
|
if (!externalUserId || !unionid || !corpId) {
|
|||
|
|
return { success: false, message: "参数错误" };
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
const data = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({
|
|||
|
|
externalUserId,
|
|||
|
|
corpId,
|
|||
|
|
unionid: { $ne: unionid },
|
|||
|
|
})
|
|||
|
|
.toArray();
|
|||
|
|
if (data.length === 0) return { success: true, message: "无需更新" };
|
|||
|
|
const ids = data.map((item) => item._id);
|
|||
|
|
await db
|
|||
|
|
.collection("member")
|
|||
|
|
.updateMany({ _id: { $in: ids } }, { $set: { unionid, realUnionid } });
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "更新成功",
|
|||
|
|
};
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error.message,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 编辑外部联系人备注
|
|||
|
|
* @param {object} context - 上下文
|
|||
|
|
* @returns {object} 编辑结果
|
|||
|
|
*/
|
|||
|
|
exports.editExternalContactRemark = async (context) => {
|
|||
|
|
if (!context.memberId && !context.externalUserId) {
|
|||
|
|
return { success: false, message: "参数错误" };
|
|||
|
|
}
|
|||
|
|
if (context.memberId && !context.externalUserId) {
|
|||
|
|
const data = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ _id: context.memberId })
|
|||
|
|
.toArray();
|
|||
|
|
context.externalUserId = data[0].externalUserId;
|
|||
|
|
}
|
|||
|
|
if (!context.externalUserId) {
|
|||
|
|
return { success: false, message: "外部联系人Id未传" };
|
|||
|
|
}
|
|||
|
|
const query = {
|
|||
|
|
corpId: context.corpId,
|
|||
|
|
externalUserId: context.externalUserId,
|
|||
|
|
};
|
|||
|
|
if (context.deleteMemberId) {
|
|||
|
|
query["_id"] = { $ne: context.deleteMemberId };
|
|||
|
|
}
|
|||
|
|
const memberList = await db.collection("member").find(query).toArray();
|
|||
|
|
const list = memberList.map((item) => ({
|
|||
|
|
name: item.name,
|
|||
|
|
relationship: item.relationship,
|
|||
|
|
}));
|
|||
|
|
const res = await api.getWecomApi({
|
|||
|
|
type: "asyncExternalContactRemark",
|
|||
|
|
externalUserId: context.externalUserId,
|
|||
|
|
corpId: context.corpId,
|
|||
|
|
list,
|
|||
|
|
});
|
|||
|
|
return res;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新客户的时间字段
|
|||
|
|
* @param {object} context - 上下文
|
|||
|
|
* @returns {object} 更新结果
|
|||
|
|
*/
|
|||
|
|
exports.updateCustomerTimeField = async (context) => {
|
|||
|
|
const { field, _id, corpId, time } = context;
|
|||
|
|
try {
|
|||
|
|
if (
|
|||
|
|
typeof field !== "string" ||
|
|||
|
|
!corpId ||
|
|||
|
|
!_id ||
|
|||
|
|
!time ||
|
|||
|
|
!dayjs(time).isValid()
|
|||
|
|
) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: "参数错误",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
const customer = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ _id, corpId })
|
|||
|
|
.project({ [field]: 1 })
|
|||
|
|
.toArray();
|
|||
|
|
if (
|
|||
|
|
customer.length > 0 &&
|
|||
|
|
(!customer[0][field] || dayjs(customer[0][field]).isBefore(dayjs(time)))
|
|||
|
|
) {
|
|||
|
|
await db
|
|||
|
|
.collection("member")
|
|||
|
|
.updateOne(
|
|||
|
|
{ _id, corpId },
|
|||
|
|
{ $set: { [field]: dayjs(time).valueOf() } }
|
|||
|
|
);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "更新成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
return { success: false, message: "客户不存在或者无需更新" };
|
|||
|
|
} catch (error) {
|
|||
|
|
return {
|
|||
|
|
success: false,
|
|||
|
|
message: error.message,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据unionid获取客户
|
|||
|
|
* @param {object} ctx - 上下文
|
|||
|
|
* @returns {object} 客户信息
|
|||
|
|
*/
|
|||
|
|
exports.getCustomerByUnionId = async (ctx) => {
|
|||
|
|
const { unionid, realUnionid, corpId } = ctx;
|
|||
|
|
try {
|
|||
|
|
const customer = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ corpId, unionid: { $in: [unionid, realUnionid] } })
|
|||
|
|
.project({ _id: 1, name: 1 })
|
|||
|
|
.limit(1)
|
|||
|
|
.toArray();
|
|||
|
|
return { success: Boolean(customer.length), data: customer[0] };
|
|||
|
|
} catch (e) {
|
|||
|
|
return { success: false, message: e.message };
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 根据客户ID获取客户名称
|
|||
|
|
* @param {object} ctx - 上下文
|
|||
|
|
* @returns {object} 客户名称列表
|
|||
|
|
*/
|
|||
|
|
exports.getCustomerNamesById = async (ctx) => {
|
|||
|
|
const { ids, corpId } = ctx;
|
|||
|
|
if (!corpId || !Array.isArray(ids) || ids.length === 0) {
|
|||
|
|
return { success: false, message: "参数错误" };
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
const list = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ corpId, _id: { $in: ids } })
|
|||
|
|
.project({ _id: 1, name: 1 })
|
|||
|
|
.toArray();
|
|||
|
|
return { success: true, data: list };
|
|||
|
|
} catch (e) {
|
|||
|
|
return { success: false, message: e.message };
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 新增客户消费记录
|
|||
|
|
* @param {object} item - 消费记录信息
|
|||
|
|
* @returns {object} 新增结果
|
|||
|
|
*/
|
|||
|
|
async function addConsumeRecord(item) {
|
|||
|
|
const { consumeAmount, corpId, customerId } = item;
|
|||
|
|
const latestConsumeTime = dayjs().valueOf();
|
|||
|
|
const query = {
|
|||
|
|
_id: common.generateRandomString(24),
|
|||
|
|
consumeAmount,
|
|||
|
|
corpId,
|
|||
|
|
customerId,
|
|||
|
|
createTime: latestConsumeTime,
|
|||
|
|
};
|
|||
|
|
await db.collection("consume-record").insertOne(query);
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: "更新成功",
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新客户报备人员
|
|||
|
|
* @param {object} ctx - 上下文
|
|||
|
|
* @returns {object} 更新结果
|
|||
|
|
*/
|
|||
|
|
async function updateCustomerReportPeople(ctx) {
|
|||
|
|
const {
|
|||
|
|
customerId,
|
|||
|
|
reportUserId,
|
|||
|
|
corpId,
|
|||
|
|
updateUserId,
|
|||
|
|
reportTimeStamp,
|
|||
|
|
personResponsibles,
|
|||
|
|
teamId,
|
|||
|
|
reportTeamId,
|
|||
|
|
} = ctx;
|
|||
|
|
if (
|
|||
|
|
!corpId ||
|
|||
|
|
!customerId ||
|
|||
|
|
!reportUserId ||
|
|||
|
|
!updateUserId ||
|
|||
|
|
!reportTimeStamp ||
|
|||
|
|
!personResponsibles ||
|
|||
|
|
!teamId ||
|
|||
|
|
!reportTeamId ||
|
|||
|
|
!dayjs(reportTimeStamp).isValid()
|
|||
|
|
) {
|
|||
|
|
return { success: false, message: "参数错误" };
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
const customer = await db
|
|||
|
|
.collection("member")
|
|||
|
|
.find({ _id: customerId, corpId })
|
|||
|
|
.project({
|
|||
|
|
reportUserId: 1,
|
|||
|
|
createTime: 1,
|
|||
|
|
reportTimeStamp: 1,
|
|||
|
|
reportTeamId: 1,
|
|||
|
|
})
|
|||
|
|
.toArray();
|
|||
|
|
if (customer.length === 0) return { success: false, message: "客户不存在" };
|
|||
|
|
const res = await db.collection("member").updateOne(
|
|||
|
|
{ _id: customerId },
|
|||
|
|
{
|
|||
|
|
$set: {
|
|||
|
|
reportUserId,
|
|||
|
|
reportTimeStamp,
|
|||
|
|
personResponsibles,
|
|||
|
|
reportTeamId,
|
|||
|
|
teamId,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
if (res.modifiedCount === 0) return { success: false, message: "更新失败" };
|
|||
|
|
await db.collection("customer-report-log").insertOne({
|
|||
|
|
_id: common.generateRandomString(24),
|
|||
|
|
customerId,
|
|||
|
|
corpId,
|
|||
|
|
reportUserId,
|
|||
|
|
updateUserId,
|
|||
|
|
reportTimeStamp,
|
|||
|
|
preReportUserId: customer[0].reportUserId,
|
|||
|
|
preReportTimeStamp: customer[0].reportTimeStamp || customer[0].createTime,
|
|||
|
|
preReportTeamId: customer[0].reportTeamId || "",
|
|||
|
|
createTime: Date.now(),
|
|||
|
|
});
|
|||
|
|
return { success: true, message: "更新成功" };
|
|||
|
|
} catch (e) {
|
|||
|
|
return { success: false, message: e.message };
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取客户报备日志
|
|||
|
|
* @param {object} ctx - 上下文
|
|||
|
|
* @returns {object} 报备日志
|
|||
|
|
*/
|
|||
|
|
async function getCustomerReportLog(ctx) {
|
|||
|
|
const { customerId, corpId, page = 1, pageSize = 10 } = ctx;
|
|||
|
|
if (!corpId || !customerId) return { success: false, message: "参数错误" };
|
|||
|
|
try {
|
|||
|
|
const total = await db
|
|||
|
|
.collection("customer-report-log")
|
|||
|
|
.find({ customerId, corpId })
|
|||
|
|
.count();
|
|||
|
|
const list = await db
|
|||
|
|
.collection("customer-report-log")
|
|||
|
|
.find({ customerId, corpId })
|
|||
|
|
.sort({ createTime: -1 })
|
|||
|
|
.skip((page - 1) * pageSize)
|
|||
|
|
.limit(pageSize)
|
|||
|
|
.toArray();
|
|||
|
|
return { success: true, list, total, message: "查询成功" };
|
|||
|
|
} catch (error) {
|
|||
|
|
return { success: false, message: error.message };
|
|||
|
|
}
|
|||
|
|
}
|