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 } }