407 lines
11 KiB
JavaScript
407 lines
11 KiB
JavaScript
|
|
const RateTag = require("./rate-tag");
|
||
|
|
const dayjs = require("dayjs");
|
||
|
|
const common = require("../../common");
|
||
|
|
const api = require("../../api");
|
||
|
|
let db = null;
|
||
|
|
|
||
|
|
exports.main = async (event, DB) => {
|
||
|
|
db = DB;
|
||
|
|
switch (event.type) {
|
||
|
|
case "addRateRecord":
|
||
|
|
return await exports.addRateRecord(event);
|
||
|
|
case "submitRateRecord":
|
||
|
|
return await exports.submitRateRecord(event);
|
||
|
|
case "getRateRecord":
|
||
|
|
return await exports.getRateRecord(event);
|
||
|
|
case "getCorpRateRecord":
|
||
|
|
return await exports.getCorpRateRecord(event);
|
||
|
|
case "getMemberRateRecord":
|
||
|
|
return await exports.getMemberRateRecord(event);
|
||
|
|
case "getCorpRateStats":
|
||
|
|
return await exports.getCorpRateStats(event);
|
||
|
|
case "getRateRecordCount":
|
||
|
|
return await getRateRecordCount(event);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description: 添加评分记录
|
||
|
|
*/
|
||
|
|
exports.addRateRecord = async (context) => {
|
||
|
|
const {
|
||
|
|
corpId,
|
||
|
|
userId,
|
||
|
|
userName,
|
||
|
|
teamId,
|
||
|
|
teamName,
|
||
|
|
customerId,
|
||
|
|
customerName,
|
||
|
|
externalUserId,
|
||
|
|
avatar,
|
||
|
|
job,
|
||
|
|
} = context;
|
||
|
|
try {
|
||
|
|
if (
|
||
|
|
!corpId ||
|
||
|
|
!userId ||
|
||
|
|
!userName ||
|
||
|
|
!teamId ||
|
||
|
|
!customerId ||
|
||
|
|
!customerName ||
|
||
|
|
!externalUserId
|
||
|
|
) {
|
||
|
|
return { success: false, message: "缺少必要的字段" };
|
||
|
|
}
|
||
|
|
// 一天只能有一次评价
|
||
|
|
const record = await db.collection("corp-rate-records").findOne(
|
||
|
|
{
|
||
|
|
corpId,
|
||
|
|
userId,
|
||
|
|
teamId,
|
||
|
|
customerId,
|
||
|
|
externalUserId,
|
||
|
|
createTime: {
|
||
|
|
$gt: dayjs().startOf("day").valueOf(),
|
||
|
|
$lt: dayjs().endOf("day").valueOf(),
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{ projection: { _id: 1, updateTime: 1 } }
|
||
|
|
);
|
||
|
|
|
||
|
|
if (record)
|
||
|
|
return {
|
||
|
|
success: true,
|
||
|
|
id: record._id,
|
||
|
|
rated: Boolean(record.updateTime),
|
||
|
|
};
|
||
|
|
|
||
|
|
const createTime = Date.now();
|
||
|
|
const expireTime = createTime + 24 * 60 * 60 * 1000; // 24小时后的时间戳
|
||
|
|
|
||
|
|
const rateRecord = {
|
||
|
|
_id: common.generateRandomString(24),
|
||
|
|
corpId,
|
||
|
|
createTime,
|
||
|
|
expireTime,
|
||
|
|
userId,
|
||
|
|
userName,
|
||
|
|
teamId,
|
||
|
|
teamName,
|
||
|
|
customerId,
|
||
|
|
customerName,
|
||
|
|
externalUserId,
|
||
|
|
avatar,
|
||
|
|
job,
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.insertOne(rateRecord);
|
||
|
|
return { success: true, id: result.insertedId, rated: false };
|
||
|
|
} catch (error) {
|
||
|
|
return { success: false, message: error.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 提交评价
|
||
|
|
* @param {*} context
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
exports.submitRateRecord = async (context) => {
|
||
|
|
const { id: _id, corpId, rate, tags, words, externalUserId } = context;
|
||
|
|
|
||
|
|
try {
|
||
|
|
if (!_id || !corpId || !externalUserId) {
|
||
|
|
return { success: false, message: "缺少必要的字段" };
|
||
|
|
}
|
||
|
|
if (
|
||
|
|
typeof rate !== "number" ||
|
||
|
|
!(rate % 1 === 0 && rate >= 1 && rate <= 5)
|
||
|
|
) {
|
||
|
|
return { success: false, message: "评价参数不合法" };
|
||
|
|
}
|
||
|
|
|
||
|
|
const record = await db.collection("corp-rate-records").findOne({
|
||
|
|
_id,
|
||
|
|
corpId,
|
||
|
|
externalUserId,
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!record) return { success: false, message: "未找到该记录" };
|
||
|
|
if (record.updateTime)
|
||
|
|
return { success: false, message: "该记录已提交过评价" };
|
||
|
|
else if (Date.now() > record.expireTime)
|
||
|
|
return { success: false, message: "该记录已过期" };
|
||
|
|
else if (record.externalUserId !== externalUserId)
|
||
|
|
return { success: false, message: "该记录不属于当前用户" };
|
||
|
|
|
||
|
|
const data = { updateTime: Date.now(), rate, tags, words };
|
||
|
|
await db.collection("corp-rate-records").updateOne({ _id }, { $set: data });
|
||
|
|
|
||
|
|
await api.getTodoApi({
|
||
|
|
type: "updateCustomerDayServiceCount",
|
||
|
|
corpId,
|
||
|
|
customerId: record.customerId,
|
||
|
|
userId: record.userId,
|
||
|
|
teamId: record.teamId,
|
||
|
|
customerName: record.customerName,
|
||
|
|
rate,
|
||
|
|
externalUserId,
|
||
|
|
dateStr: dayjs(record.createTime).format("YYYY-MM-DD"),
|
||
|
|
});
|
||
|
|
|
||
|
|
return { success: true, message: "提交评价成功" };
|
||
|
|
} catch (error) {
|
||
|
|
return { success: false, message: error.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 扫码端获取评价详情
|
||
|
|
* @param {*} context
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
exports.getRateRecord = async (context) => {
|
||
|
|
const { id: _id, corpId, externalUserId } = context;
|
||
|
|
try {
|
||
|
|
if (!_id || !corpId) return { success: false, message: "缺少必要的字段" };
|
||
|
|
|
||
|
|
const record = await db.collection("corp-rate-records").findOne(
|
||
|
|
{
|
||
|
|
_id,
|
||
|
|
corpId,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
projection: {
|
||
|
|
userId: 0,
|
||
|
|
customerId: 0,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
if (!record) return { success: false, message: "未找到评价信息" };
|
||
|
|
|
||
|
|
const { externalUserId: _externalUserId, ...data } = record;
|
||
|
|
const rated = Boolean(record.updateTime || Date.now() >= record.expireTime); // 是否已经评价过 或者 超时自动评价了
|
||
|
|
const result = { success: true, message: "查询成功", rated };
|
||
|
|
|
||
|
|
if (externalUserId && externalUserId === _externalUserId)
|
||
|
|
result.record = data;
|
||
|
|
|
||
|
|
if (externalUserId && externalUserId === _externalUserId && !rated) {
|
||
|
|
const res = await RateTag.main({ corpId, type: "getCorpRateConfig" });
|
||
|
|
result.rateTags = Array.isArray(res.data) ? res.data : [];
|
||
|
|
result.enable = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
} catch (e) {
|
||
|
|
return { success: false, message: e.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 扫码端获取评价详情
|
||
|
|
* @param {*} context
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
exports.getCorpRateRecord = async (context) => {
|
||
|
|
const { serviceDates, corpId, rate, tags, teamIds, userIds, page, pageSize } =
|
||
|
|
context;
|
||
|
|
if (!corpId) return { success: false, message: "机构id不能为空" };
|
||
|
|
try {
|
||
|
|
let query = { corpId };
|
||
|
|
const current = page % 1 === 0 && page > 0 ? page : 1;
|
||
|
|
const size = pageSize % 1 === 0 && pageSize > 0 ? pageSize : 10;
|
||
|
|
|
||
|
|
// 服务时间筛选
|
||
|
|
const dates = Array.isArray(serviceDates)
|
||
|
|
? serviceDates.filter((i) => i && dayjs(i).isValid())
|
||
|
|
: [];
|
||
|
|
if (dates.length === 1 && dates[0] && dayjs(dates[0]).isValid()) {
|
||
|
|
query.createTime = {
|
||
|
|
$gte: dayjs(dates[0]).startOf("day").valueOf(),
|
||
|
|
$lte: dayjs(dates[0]).endOf("day").valueOf(),
|
||
|
|
};
|
||
|
|
} else if (dates.length === 2) {
|
||
|
|
query.createTime = {
|
||
|
|
$gte: dayjs(dates[0]).startOf("day").valueOf(),
|
||
|
|
$lte: dayjs(dates[1]).endOf("day").valueOf(),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Array.isArray(rate) && rate.length > 0) query.rate = { $in: rate };
|
||
|
|
if (Array.isArray(tags) && tags.length > 0) query.tags = { $in: tags };
|
||
|
|
if (Array.isArray(teamIds) && teamIds.length > 0)
|
||
|
|
query.teamId = { $in: teamIds };
|
||
|
|
if (Array.isArray(userIds) && userIds.length > 0)
|
||
|
|
query.userId = { $in: userIds };
|
||
|
|
|
||
|
|
// 五星好评 包含超时自动好评的
|
||
|
|
if (Array.isArray(rate) && rate.includes(5)) {
|
||
|
|
query = {
|
||
|
|
$or: [
|
||
|
|
{ ...query },
|
||
|
|
{
|
||
|
|
updateTime: { $exists: false },
|
||
|
|
rate: { $exists: false },
|
||
|
|
expireTime: { $lt: Date.now() },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const hasRated = {
|
||
|
|
$or: [
|
||
|
|
{ updateTime: { $exists: true } },
|
||
|
|
{ updateTime: { $exists: false }, expireTime: { $lt: Date.now() } },
|
||
|
|
],
|
||
|
|
};
|
||
|
|
|
||
|
|
const params = { $and: [query, hasRated] };
|
||
|
|
|
||
|
|
const list = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.find(params)
|
||
|
|
.limit(size)
|
||
|
|
.skip((current - 1) * size)
|
||
|
|
.sort({ createTime: -1 })
|
||
|
|
.toArray();
|
||
|
|
|
||
|
|
const total = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.countDocuments(params);
|
||
|
|
|
||
|
|
return { success: true, list, total, message: "获取成功" };
|
||
|
|
} catch (e) {
|
||
|
|
return { success: false, message: e.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 扫码端获取评价详情
|
||
|
|
* @param {*} context
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
exports.getMemberRateRecord = async (context) => {
|
||
|
|
const { corpId, userId, customerIds, teamId, minTime, maxTime } = context;
|
||
|
|
if (!corpId || !userId || !teamId)
|
||
|
|
return { success: false, message: "缺少必要的字段" };
|
||
|
|
try {
|
||
|
|
const query = {
|
||
|
|
corpId,
|
||
|
|
userId,
|
||
|
|
teamId,
|
||
|
|
customerId: { $in: customerIds },
|
||
|
|
createTime: { $gte: minTime, $lte: maxTime },
|
||
|
|
};
|
||
|
|
|
||
|
|
const data = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.find(query, {
|
||
|
|
projection: {
|
||
|
|
customerId: 1,
|
||
|
|
expireTime: 1,
|
||
|
|
updateTime: 1,
|
||
|
|
createTime: 1,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
.toArray();
|
||
|
|
|
||
|
|
return { success: true, rateList: data };
|
||
|
|
} catch (e) {
|
||
|
|
return { success: false, message: e.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @description 获取机构评分统计
|
||
|
|
* @param {*} context
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
exports.getCorpRateStats = async (context) => {
|
||
|
|
const { corpId, startDate, endDate } = context;
|
||
|
|
if (!corpId) return { success: false, message: "机构id不能为空" };
|
||
|
|
try {
|
||
|
|
const query = {
|
||
|
|
corpId,
|
||
|
|
rate: { $in: [1, 2, 3, 4, 5] },
|
||
|
|
updateTime: { $exists: true },
|
||
|
|
};
|
||
|
|
|
||
|
|
const dates = [];
|
||
|
|
if (startDate && dayjs(startDate).isValid()) {
|
||
|
|
dates.push({ $gte: dayjs(startDate).startOf("day").valueOf() });
|
||
|
|
}
|
||
|
|
if (endDate && dayjs(endDate).isValid()) {
|
||
|
|
dates.push({ $lte: dayjs(endDate).endOf("day").valueOf() });
|
||
|
|
}
|
||
|
|
if (dates.length) {
|
||
|
|
query.createTime = { $and: dates };
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取 1-5星评价统计
|
||
|
|
const list = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.aggregate([
|
||
|
|
{ $match: query },
|
||
|
|
{
|
||
|
|
$group: {
|
||
|
|
_id: "$rate",
|
||
|
|
count: { $sum: 1 },
|
||
|
|
},
|
||
|
|
},
|
||
|
|
])
|
||
|
|
.toArray();
|
||
|
|
|
||
|
|
// 获取超时评价统计 超时默认为5星
|
||
|
|
const params = {
|
||
|
|
corpId,
|
||
|
|
updateTime: { $exists: false },
|
||
|
|
rate: { $exists: false },
|
||
|
|
};
|
||
|
|
|
||
|
|
if (dates.length) params.createTime = { $and: dates };
|
||
|
|
|
||
|
|
const expireTime =
|
||
|
|
endDate && dayjs(endDate).isValid()
|
||
|
|
? dayjs(endDate).endOf("day").valueOf()
|
||
|
|
: Date.now();
|
||
|
|
|
||
|
|
params.expireTime = { $lte: expireTime };
|
||
|
|
|
||
|
|
const total = await db
|
||
|
|
.collection("corp-rate-records")
|
||
|
|
.countDocuments(params);
|
||
|
|
|
||
|
|
const data = [1, 2, 3, 4, 5].map((i) => {
|
||
|
|
const item = list.find((item) => item._id === i);
|
||
|
|
let count = item ? item.count : 0;
|
||
|
|
if (i === 5) count += total;
|
||
|
|
return { rate: i, count };
|
||
|
|
});
|
||
|
|
|
||
|
|
return { success: true, data, message: "获取成功" };
|
||
|
|
} catch (e) {
|
||
|
|
return { success: false, message: e.message };
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取服务评价条数
|
||
|
|
* @param {*} ctx
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
async function getRateRecordCount(ctx) {
|
||
|
|
const { corpId, params } = ctx;
|
||
|
|
if (!corpId || Object.prototype.toString.call(params) !== '[object Object]') return 0;
|
||
|
|
try {
|
||
|
|
const query = { ...params, corpId };
|
||
|
|
const count = await db.collection("corp-rate-records").find(query).count();
|
||
|
|
return count
|
||
|
|
} catch (e) {
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
}
|