908 lines
24 KiB
JavaScript
908 lines
24 KiB
JavaScript
let dayjs = require("dayjs");
|
|
let utils = require("../utils.js");
|
|
const api = require("../../api");
|
|
|
|
let db = null;
|
|
|
|
exports.main = async (content, DB) => {
|
|
db = DB;
|
|
switch (content.type) {
|
|
case "getCustomerStatistics":
|
|
return await exports.getCustomerStatistics(content);
|
|
case "getServiceAndmemberTotalByTeamId":
|
|
return await exports.getServiceAndmemberTotalByTeamId(content);
|
|
case "getServiceAndmemberTotalByUserId":
|
|
return await exports.getServiceAndmemberTotalByUserId(content);
|
|
case "getServiceTrendByTeamId":
|
|
return await exports.getServiceTrendByTeamId(content);
|
|
case "getMemberTrendByTeamId":
|
|
return await exports.getMemberTrendByTeamId(content);
|
|
case "getUsersMemberByTeamId":
|
|
return await exports.getUsersMemberByTeamId(content);
|
|
case "getTeamsServiceAndMemberCount":
|
|
return await getTeamsServiceAndMemberCount(content);
|
|
case "getStaffServiceAndMemberCount":
|
|
return await getStaffServiceAndMemberCount(content);
|
|
case "getCustomerSourceCountSort":
|
|
return await getCustomerSourceCountSort(content);
|
|
case "getCustomerGroupCountSort":
|
|
return await getCustomerGroupCountSort(content);
|
|
case "getCusomterAndServiceCount":
|
|
return await getCusomterAndServiceCount(content);
|
|
case "getStaffRate":
|
|
return await getStaffRate(content);
|
|
case "getScoreRateTrend":
|
|
return await getScoreRateTrend(content);
|
|
case "getTeamCustmerCount":
|
|
return await getTeamCustmerCount(content);
|
|
}
|
|
};
|
|
|
|
// 获取客户数和服务数
|
|
async function getCusomterAndServiceCount(content) {
|
|
const { corpId } = content;
|
|
const todayStartTime = dayjs().startOf("day").valueOf();
|
|
const todayEndTime = dayjs().endOf("day").valueOf();
|
|
// 获取客户总数
|
|
const customerTotalCount = await db
|
|
.collection("member")
|
|
.find({ corpId })
|
|
.count();
|
|
const serviceTotalCount = await db
|
|
.collection("service-record")
|
|
.find({ corpId, eventType: { $ne: "serviceRate" } })
|
|
.count();
|
|
let todayCustomerCount = await db
|
|
.collection("member")
|
|
.find({
|
|
corpId,
|
|
createTime: { $gte: todayStartTime, $lt: todayEndTime },
|
|
})
|
|
.count();
|
|
let todayServiceCount = await db
|
|
.collection("service-record")
|
|
.find({
|
|
corpId,
|
|
eventType: { $ne: "serviceRate" },
|
|
createTime: { $gte: todayStartTime, $lt: todayEndTime },
|
|
})
|
|
.count();
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
customerTotalCount,
|
|
serviceTotalCount,
|
|
todayCustomerCount,
|
|
todayServiceCount,
|
|
};
|
|
}
|
|
|
|
// 分组客户数据统计
|
|
async function getCustomerGroupCountSort(content) {
|
|
const { corpId } = content;
|
|
const data = await db
|
|
.collection("member")
|
|
.aggregate([
|
|
{ $match: { corpId } },
|
|
{ $group: { _id: "$groupIds", count: { $sum: 1 } } },
|
|
])
|
|
.toArray();
|
|
const result = data.reduce((acc, item) => {
|
|
if (Array.isArray(item._id)) {
|
|
item._id.forEach((id) => {
|
|
acc[id] = (acc[id] || 0) + item.count;
|
|
});
|
|
} else if (item._id) {
|
|
acc[item._id] = (acc[item._id] || 0) + item.count;
|
|
}
|
|
return acc;
|
|
}, {});
|
|
let list = Object.entries(result).map(([groupId, count]) => ({
|
|
groupId,
|
|
count,
|
|
}));
|
|
const ids = list.map((item) => item.groupId);
|
|
let res = await db
|
|
.collection("group")
|
|
.find({ _id: { $in: ids } })
|
|
.limit(1000)
|
|
.toArray();
|
|
list = list.map((item) => {
|
|
let group = res.find((i) => i._id === item.groupId);
|
|
if (!group) {
|
|
return {
|
|
...item,
|
|
groupName: "未知",
|
|
};
|
|
} else {
|
|
return {
|
|
...item,
|
|
groupName: group.groupName,
|
|
parentGroupId: group.parentGroupId,
|
|
};
|
|
}
|
|
});
|
|
list = list.filter((i) => i.groupName !== "未知");
|
|
let mergedList = [];
|
|
list.forEach((item) => {
|
|
if (!item.parentGroupId) {
|
|
mergedList.push(item);
|
|
return;
|
|
}
|
|
let existingItem = mergedList.find(
|
|
(el) => el.parentGroupId === item.parentGroupId
|
|
);
|
|
if (existingItem) {
|
|
existingItem.count += item.count;
|
|
} else {
|
|
mergedList.push(item);
|
|
}
|
|
});
|
|
mergedList.sort((a, b) => b.count - a.count);
|
|
let countAfterFive = 0;
|
|
if (mergedList.length > 5) {
|
|
for (let i = 5; i < mergedList.length; i++) {
|
|
countAfterFive += mergedList[i].count;
|
|
}
|
|
mergedList = mergedList.slice(0, 5);
|
|
mergedList.push({
|
|
groupName: "其他",
|
|
count: countAfterFive,
|
|
});
|
|
}
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
list: mergedList,
|
|
};
|
|
}
|
|
|
|
// 获取获取客户来源的客户数据
|
|
async function getCustomerSourceCountSort(content) {
|
|
const { corpId, sources = [] } = content;
|
|
const PAGE_SIZE = 1000; // 每页查询的记录数,可以根据实际情况调整
|
|
let page = 0;
|
|
let hasMoreData = true;
|
|
let allData = [];
|
|
|
|
while (hasMoreData) {
|
|
const data = await db
|
|
.collection("member")
|
|
.aggregate([
|
|
{ $match: { corpId } },
|
|
{ $skip: page * PAGE_SIZE },
|
|
{ $limit: PAGE_SIZE },
|
|
{ $group: { _id: "$customerSource", count: { $sum: 1 } } },
|
|
])
|
|
.toArray();
|
|
|
|
if (data.length > 0) {
|
|
allData = allData.concat(data);
|
|
page++;
|
|
} else {
|
|
hasMoreData = false; // 如果没有更多数据,停止查询
|
|
}
|
|
}
|
|
|
|
// 处理数据
|
|
const result = allData.reduce((acc, item) => {
|
|
if (Array.isArray(item._id)) {
|
|
item._id.forEach((id) => {
|
|
acc[id] = (acc[id] || 0) + item.count;
|
|
});
|
|
} else if (item._id) {
|
|
acc[item._id] = (acc[item._id] || 0) + item.count;
|
|
}
|
|
return acc;
|
|
}, {});
|
|
|
|
// 获取未知来源的数据
|
|
let unknowSourceCount = allData.find((i) => !i._id)
|
|
? allData.find((i) => !i._id).count
|
|
: 0;
|
|
|
|
let list = Object.entries(result)
|
|
.map(([sourceName, count]) => ({
|
|
sourceName,
|
|
count,
|
|
}))
|
|
.filter((i) => sources.some((item) => item === i.sourceName));
|
|
|
|
list.sort((a, b) => b.count - a.count);
|
|
|
|
if (list.length > 5) {
|
|
// 5名之后相加
|
|
let countAfterFive = 0;
|
|
for (let i = 5; i < list.length; i++) {
|
|
countAfterFive += list[i].count;
|
|
}
|
|
list = list.slice(0, 5);
|
|
list.push({
|
|
sourceName: "其他",
|
|
count: countAfterFive,
|
|
});
|
|
}
|
|
|
|
list.push({
|
|
sourceName: "未知",
|
|
count: unknowSourceCount,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: allData,
|
|
list,
|
|
};
|
|
}
|
|
|
|
//获取团队服务和客户总数
|
|
async function getTeamsServiceAndMemberCount(context) {
|
|
try {
|
|
const { corpId, dates } = context;
|
|
let teamList = await getCorpTeams(corpId);
|
|
teamList = teamList.map((item) => {
|
|
return {
|
|
...item,
|
|
corpId,
|
|
dates,
|
|
};
|
|
});
|
|
const handler = async (item) => {
|
|
let { data } = await exports.getServiceAndmemberTotalByTeamId(item);
|
|
let { averageScore } = await getStaffRate(item);
|
|
return {
|
|
...data,
|
|
satisfaction: averageScore,
|
|
};
|
|
};
|
|
let list = await utils.processInBatches(teamList, handler, 10);
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
list,
|
|
};
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
// 获取满意度评分趋势
|
|
async function getScoreRateTrend(context) {
|
|
const { corpId, dates } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
let params = {
|
|
corpId,
|
|
};
|
|
if (dates && Array.isArray(dates) && dates.length !== 0) {
|
|
params["createTime"] = { $gte: startTime, $lte: lastTime };
|
|
}
|
|
// 已评价的总数
|
|
let ratedTotalCount = await db
|
|
.collection("corp-rate-records")
|
|
.find({ ...params, rate: { $exists: true } })
|
|
.count();
|
|
// 未评价的总数
|
|
let unratedTotalCount = await db
|
|
.collection("corp-rate-records")
|
|
.find({
|
|
...params,
|
|
rate: { $exists: false },
|
|
expireTime: { $lte: new Date().getTime() },
|
|
})
|
|
.count();
|
|
|
|
const getRateCount = async (rate) => {
|
|
return await db
|
|
.collection("corp-rate-records")
|
|
.find({ ...params, rate })
|
|
.count();
|
|
};
|
|
let arrCount = Promise.all([
|
|
getRateCount(5),
|
|
getRateCount(4),
|
|
getRateCount(3),
|
|
getRateCount(2),
|
|
getRateCount(1),
|
|
]);
|
|
let [
|
|
fiveStarCount,
|
|
fourStarCount,
|
|
threeStarCount,
|
|
twoStarCount,
|
|
oneStareCount,
|
|
] = await arrCount;
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
count: {
|
|
total: ratedTotalCount + unratedTotalCount,
|
|
fiveStarCount: fiveStarCount + unratedTotalCount,
|
|
fourStarCount,
|
|
threeStarCount,
|
|
twoStarCount,
|
|
oneStareCount,
|
|
},
|
|
};
|
|
}
|
|
|
|
// 获取员工服务满意度评分
|
|
async function getStaffRate(context) {
|
|
const { corpId, dates, userId, teamId } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
const rateQuery = { corpId, teamId };
|
|
if (userId) rateQuery.userId = userId;
|
|
if (dates && Array.isArray(dates) && dates.length !== 0) {
|
|
rateQuery["createTime"] = { $gte: startTime, $lte: lastTime };
|
|
}
|
|
// 获取 4 5星评价的条数
|
|
const goodRateCout = await api.getKnowledgeBaseApi({
|
|
type: "getRateRecordCount",
|
|
params: { ...rateQuery, rate: { $in: [4, 5] } },
|
|
corpId,
|
|
});
|
|
// 获取 1 2 3星评价的条数
|
|
const notGoodRateCout = await api.getKnowledgeBaseApi({
|
|
type: "getRateRecordCount",
|
|
params: { ...rateQuery, rate: { $in: [1, 2, 3] } },
|
|
corpId,
|
|
});
|
|
// 获取超时未评价的条数 (超时未评价默认好评)
|
|
const unratedCount = await api.getKnowledgeBaseApi({
|
|
type: "getRateRecordCount",
|
|
params: {
|
|
...rateQuery,
|
|
rate: { $exists: false },
|
|
expireTime: { $lte: new Date().getTime() },
|
|
},
|
|
corpId,
|
|
});
|
|
const rate =
|
|
(goodRateCout + unratedCount) /
|
|
Math.max(goodRateCout + notGoodRateCout + unratedCount, 1);
|
|
const percent = (rate * 100).toFixed(2);
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
averageScore: percent,
|
|
};
|
|
}
|
|
|
|
async function getStaffServiceAndMemberCount(context) {
|
|
const { corpId, dates } = context;
|
|
let staffList = await getCorpStaffs(corpId);
|
|
staffList = staffList.map((item) => {
|
|
return {
|
|
userId: item.userid,
|
|
corpId,
|
|
dates,
|
|
};
|
|
});
|
|
const handler = async (item) => {
|
|
let { data } = await exports.getServiceAndmemberTotalByUserId(item);
|
|
let { averageScore } = await getStaffRate(item);
|
|
return {
|
|
...data,
|
|
satisfaction: averageScore,
|
|
};
|
|
};
|
|
let list = await utils.processInBatches(staffList, handler, 10);
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
list,
|
|
};
|
|
}
|
|
|
|
exports.getServiceAndmemberTotalByTeamId = async (context) => {
|
|
const { corpId, teamId, dates, name } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
let memberParmas = {
|
|
corpId,
|
|
teamId,
|
|
};
|
|
let serviceParams = {
|
|
corpId,
|
|
executeTeamId: teamId,
|
|
eventType: { $ne: "serviceRate" },
|
|
};
|
|
let registrationParams = {
|
|
teamId,
|
|
};
|
|
if (Array.isArray(dates) && dates.length !== 0) {
|
|
memberParmas["createTime"] = { $gte: startTime, $lte: lastTime };
|
|
serviceParams["executionTime"] = { $gte: startTime, $lte: lastTime };
|
|
registrationParams["createTime"] = { $gte: startTime, $lte: lastTime };
|
|
}
|
|
try {
|
|
let memberCount = await db.collection("member").find(memberParmas).count();
|
|
let serviceCount = await db
|
|
.collection("service-record")
|
|
.find(serviceParams)
|
|
.count();
|
|
let visitCount = await db
|
|
.collection("registration")
|
|
.find(registrationParams)
|
|
.count();
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: {
|
|
memberCount,
|
|
serviceCount,
|
|
visitCount,
|
|
teamName: name,
|
|
},
|
|
};
|
|
} catch {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
exports.getServiceAndmemberTotalByUserId = async (context) => {
|
|
const { corpId, userId, dates } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
|
|
try {
|
|
let memberParams = {
|
|
corpId,
|
|
personResponsibles: { $elemMatch: { corpUserId: userId } },
|
|
};
|
|
let serviceParams = {
|
|
corpId,
|
|
executorUserId: userId,
|
|
eventType: { $ne: "serviceRate" },
|
|
};
|
|
if (Array.isArray(dates) && dates.length !== 0) {
|
|
memberParams["createTime"] = { $gte: startTime, $lte: lastTime };
|
|
serviceParams["executionTime"] = { $gte: startTime, $lte: lastTime };
|
|
}
|
|
let memberCount = await db.collection("member").find(memberParams).count();
|
|
let serviceCount = await db
|
|
.collection("service-record")
|
|
.find(serviceParams)
|
|
.count();
|
|
let res = await db
|
|
.collection("member")
|
|
.find(memberParams)
|
|
.project({
|
|
name: 1,
|
|
_id: 1,
|
|
personResponsibles: 1,
|
|
})
|
|
.toArray();
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: {
|
|
memberCount,
|
|
serviceCount,
|
|
userId,
|
|
res,
|
|
},
|
|
};
|
|
} catch {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
// 获取所有团队
|
|
async function getCorpTeams(corpId) {
|
|
const fetchData = async (page, pageSize, db) => {
|
|
const { list = [] } = await api.getCorpApi({
|
|
type: "getCorpTeams",
|
|
corpId,
|
|
pageSize,
|
|
page,
|
|
fields: { name: 1, teamId: 1 },
|
|
showCustomerCount: false,
|
|
});
|
|
return Array.isArray(list) ? list : [];
|
|
};
|
|
|
|
const list = await utils.getAllData(fetchData, db);
|
|
return list;
|
|
}
|
|
|
|
// 获取所有成员
|
|
async function getCorpStaffs(corpId) {
|
|
const fetchData = async (page, pageSize, db) => {
|
|
const { data } = await api.getCorpApi({
|
|
type: 'getCorpMember',
|
|
page,
|
|
pageSize,
|
|
params: { corpId, open_userid: { $exists: true } }
|
|
})
|
|
const list = Array.isArray(data) ? data.map(i => ({ userid: i.userid })).filter(i => i.userid) : [];
|
|
return list;
|
|
};
|
|
const list = await utils.getAllData(fetchData, db);
|
|
return list;
|
|
}
|
|
|
|
exports.getCustomerStatistics = async (content) => {
|
|
const { corpId } = content;
|
|
// 校验 corpId 是否存在
|
|
if (!corpId) {
|
|
return {
|
|
success: false,
|
|
message: "机构id不能为空",
|
|
};
|
|
}
|
|
|
|
try {
|
|
// 获取今日的起始和结束时间戳
|
|
const todayStartTime = dayjs().startOf("day").valueOf();
|
|
const todayEndTime = dayjs().endOf("day").valueOf();
|
|
|
|
// 使用聚合管道来进行多个统计查询
|
|
const result = await db
|
|
.collection("member")
|
|
.aggregate([
|
|
{
|
|
$match: { corpId },
|
|
},
|
|
{
|
|
$facet: {
|
|
// 获取客户总数
|
|
totalCount: [{ $count: "total" }],
|
|
// 获取已加好友数
|
|
friendCount: [
|
|
{ $match: { externalUserId: { $ne: "", $exists: true } } },
|
|
{ $count: "total" },
|
|
],
|
|
// 获取未加好友数
|
|
noFriendCount: [
|
|
{
|
|
$match: {
|
|
$or: [
|
|
{ externalUserId: { $eq: "" } },
|
|
{ externalUserId: { $exists: false } },
|
|
],
|
|
},
|
|
},
|
|
{ $count: "total" },
|
|
],
|
|
// 获取今日新增客户数
|
|
todayAddCustomerCount: [
|
|
{
|
|
$match: {
|
|
createTime: { $gte: todayStartTime, $lt: todayEndTime },
|
|
},
|
|
},
|
|
{ $count: "total" },
|
|
],
|
|
// 获取今日新增好友数
|
|
todayAddFriendCount: [
|
|
{
|
|
$match: {
|
|
externalUserId: { $ne: "", $exists: true },
|
|
createTime: { $gte: todayStartTime, $lt: todayEndTime },
|
|
},
|
|
},
|
|
{ $count: "total" },
|
|
],
|
|
// 获取今日未加好友数
|
|
todayNoFriendCount: [
|
|
{
|
|
$match: {
|
|
$or: [
|
|
{ externalUserId: { $eq: "" } },
|
|
{ externalUserId: { $exists: false } },
|
|
],
|
|
createTime: { $gte: todayStartTime, $lt: todayEndTime },
|
|
},
|
|
},
|
|
{ $count: "total" },
|
|
],
|
|
},
|
|
},
|
|
{
|
|
$project: {
|
|
customerTotalCount: { $arrayElemAt: ["$totalCount.total", 0] },
|
|
friendCount: { $arrayElemAt: ["$friendCount.total", 0] },
|
|
noFriendCount: { $arrayElemAt: ["$noFriendCount.total", 0] },
|
|
todayAddCustomerCount: {
|
|
$arrayElemAt: ["$todayAddCustomerCount.total", 0],
|
|
},
|
|
todayAddFriendCount: {
|
|
$arrayElemAt: ["$todayAddFriendCount.total", 0],
|
|
},
|
|
todayNoFriendCount: {
|
|
$arrayElemAt: ["$todayNoFriendCount.total", 0],
|
|
},
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
|
|
// 处理返回的数据,将缺失的字段赋值为 0
|
|
const stats = result[0] || {};
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: {
|
|
customerTotalCount: stats.customerTotalCount || 0,
|
|
friendCount: stats.friendCount || 0,
|
|
noFriendCount: stats.noFriendCount || 0,
|
|
todayAddCustomerCount: stats.todayAddCustomerCount || 0,
|
|
todayAddFriendCount: stats.todayAddFriendCount || 0,
|
|
todayNoFriendCount: stats.todayNoFriendCount || 0,
|
|
},
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
function getStartAndEndTime(dates) {
|
|
if (!dates || dates.length === 0) {
|
|
return {
|
|
startTime: "",
|
|
lastTime: "",
|
|
};
|
|
}
|
|
let t_1 = dates[0];
|
|
let t_2 = dates[1];
|
|
return {
|
|
startTime: t_1 && new Date(t_1).setHours(0, 0, 0, 0),
|
|
lastTime: t_2 && new Date(t_2).setHours(23, 59, 59, 999),
|
|
};
|
|
}
|
|
|
|
exports.getMemberTrendByTeamId = async (context) => {
|
|
const { corpId, teamId, dates, userId, dataType = "increaseCount" } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
let params = {
|
|
createTime: { $gte: startTime, $lte: lastTime },
|
|
};
|
|
try {
|
|
let result = {};
|
|
if (dataType === "increaseCount") {
|
|
if (userId) {
|
|
params["personResponsibles"] = {
|
|
$elemMatch: { corpUserId: userId, teamId: teamId },
|
|
};
|
|
}
|
|
params["corpId"] = corpId;
|
|
params["teamId"] = teamId;
|
|
result = await db
|
|
.collection("member")
|
|
.aggregate([
|
|
{ $match: params },
|
|
{
|
|
$group: {
|
|
_id: {
|
|
$dateToString: {
|
|
format: "%Y-%m-%d",
|
|
date: { $toDate: "$createTime" },
|
|
},
|
|
},
|
|
count: { $sum: 1 },
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
} else if (dataType === "visitCount") {
|
|
params["teamId"] = teamId;
|
|
result = await db
|
|
.collection("registration")
|
|
.aggregate([
|
|
{ $match: params },
|
|
{
|
|
$group: {
|
|
_id: {
|
|
$dateToString: {
|
|
format: "%Y-%m-%d",
|
|
date: { $toDate: "$createTime" },
|
|
},
|
|
},
|
|
count: { $sum: 1 },
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
} else if (dataType === "peopleCount") {
|
|
params["corpId"] = corpId;
|
|
params["executeTeamId"] = teamId;
|
|
if (userId) params["creatorUserId"] = userId;
|
|
result = await db
|
|
.collection("service-record")
|
|
.aggregate([
|
|
{ $match: params },
|
|
{
|
|
$group: {
|
|
_id: {
|
|
$dateToString: {
|
|
format: "%Y-%m-%d",
|
|
date: { $toDate: "$createTime" },
|
|
},
|
|
},
|
|
count: { $sum: 1 },
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
}
|
|
let list = result;
|
|
let filledArray = fillDateGaps(list, dates[0], dates[1]);
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: filledArray,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
exports.getServiceTrendByTeamId = async (context) => {
|
|
const { corpId, teamId, userId, dates } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
let params = {
|
|
corpId,
|
|
executeTeamId: teamId,
|
|
createTime: { $gte: startTime, $lte: lastTime },
|
|
};
|
|
if (userId) {
|
|
params["executorUserId"] = userId;
|
|
}
|
|
try {
|
|
const result = await db
|
|
.collection("service-record")
|
|
.aggregate([
|
|
{ $match: params },
|
|
{
|
|
$group: {
|
|
_id: {
|
|
$dateToString: {
|
|
format: "%Y-%m-%d",
|
|
date: { $toDate: "$createTime" },
|
|
},
|
|
},
|
|
count: { $sum: 1 },
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
let list = result;
|
|
let filledArray = fillDateGaps(list, dates[0], dates[1]);
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: filledArray,
|
|
params,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
// 获取团队成员客户数
|
|
exports.getUsersMemberByTeamId = async (context) => {
|
|
try {
|
|
const { memberList } = context;
|
|
let counts = [];
|
|
let arr = memberList.map((i) => {
|
|
return getServiceAndMemberCount(context, i);
|
|
});
|
|
for (let i = 0; i < arr.length; i += 10) {
|
|
const promiseArr = arr.slice(i, i + 10);
|
|
const list = await Promise.all(promiseArr);
|
|
counts = counts.concat(list);
|
|
}
|
|
return {
|
|
success: true,
|
|
message: "获取成功",
|
|
data: counts,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
message: "获取失败",
|
|
};
|
|
}
|
|
};
|
|
|
|
async function getServiceAndMemberCount(context, userId) {
|
|
const { corpId, teamId, dates } = context;
|
|
const { startTime, lastTime } = getStartAndEndTime(dates);
|
|
const query = {
|
|
teamId,
|
|
personResponsibles: { $elemMatch: { corpUserId: userId, teamId } },
|
|
createTime: { $gte: startTime, $lte: lastTime },
|
|
};
|
|
let servicQuery = {
|
|
corpId,
|
|
createTime: { $gte: startTime, $lte: lastTime },
|
|
executorUserId: userId,
|
|
executeTeamId: teamId,
|
|
eventType: { $ne: "serviceRate" },
|
|
};
|
|
|
|
const customerCount = await db
|
|
.collection("member")
|
|
.find({ ...query, corpId })
|
|
.count();
|
|
const visitCount = await db.collection("registration").find(query).count();
|
|
const serviceCount = await db
|
|
.collection("service-record")
|
|
.find(servicQuery)
|
|
.count();
|
|
return {
|
|
userId,
|
|
customerCount,
|
|
visitCount,
|
|
serviceCount,
|
|
};
|
|
}
|
|
|
|
// 填充日期间隔
|
|
function fillDateGaps(arr, start, end) {
|
|
let startDate = new Date(start);
|
|
let endDate = new Date(end);
|
|
|
|
let dateCounts = {};
|
|
|
|
arr.forEach((item) => {
|
|
dateCounts[item._id] = item.count;
|
|
});
|
|
|
|
while (startDate <= endDate) {
|
|
let dateString = startDate.toISOString().split("T")[0];
|
|
if (!dateCounts[dateString]) {
|
|
dateCounts[dateString] = 0;
|
|
}
|
|
startDate.setDate(startDate.getDate() + 1);
|
|
}
|
|
|
|
let datesArray = Object.entries(dateCounts).map(([dateString, count]) => {
|
|
return { _id: dateString, count: count };
|
|
});
|
|
|
|
datesArray.sort((a, b) => new Date(a._id) - new Date(b._id));
|
|
|
|
return datesArray;
|
|
}
|
|
|
|
async function getTeamCustmerCount(ctx) {
|
|
const { corpId, teamIds } = ctx;
|
|
if (!corpId || !Array.isArray(teamIds) || teamIds.length === 0) {
|
|
return [];
|
|
}
|
|
try {
|
|
const customerCounts = await db
|
|
.collection("member")
|
|
.aggregate([
|
|
{ $match: { teamId: { $in: teamIds } } }, // 查找 teamId 数组中包含任意 teamId 的文档
|
|
{ $unwind: "$teamId" }, // 展开 teamId 数组,每个 teamId 成为一个单独的文档
|
|
{ $match: { teamId: { $in: teamIds } } }, // 再次匹配这些 teamId 是否在目标队列中
|
|
{
|
|
$group: {
|
|
_id: "$teamId", // 根据 teamId 聚合
|
|
count: { $sum: 1 }, // 计算每个 teamId 的数量
|
|
},
|
|
},
|
|
])
|
|
.toArray();
|
|
return customerCounts;
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|