家政维修平台实战25:工人接单

目录

  • [1 创建接单API](#1 创建接单API)
  • [2 前端调用](#2 前端调用)
  • 整体效果
  • 总结

上一篇我们已经搭建了工人的工作台界面,可以看到相关的统计信息和订单信息,有了订单之后就需要实现具体的操作了。对于工人来讲第一个就是接单的操作,我们先实现一下工人的后端API

1 创建接单API

打开订单管理,点击+号创建新方法

添加接单的方法

输入如下代码:

bash 复制代码
/**
 * ErrorCode 定义
 * 统一管理系统可能返回的错误码和消息。
 */
const ErrorCode = {
    SUCCESS: 0,
    PARAM_ERROR: 1001,           // 参数缺失或无效
    NOT_FOUND: 1002,             // 订单或派工记录未找到
    INVALID_ORDER_STATUS: 1004,  // 订单当前主状态不允许接单
    INVALID_WORKER_STATUS: 1007, // 工人派工记录状态不允许接单
    SYSTEM_ERROR: 1003,          // 通用系统错误
    // 更多错误码可以按需添加
};

/**
 * 订单在 `jz_orders` (订单主表) 中可能的主状态枚举。
 * (与 dispatchOrder 中的定义一致)
 */
const ORDER_STATUS_ENUM = {
    PENDING_PAYMENT: '1',
    PENDING_ACCEPTANCE: '2', // 待接单 (已支付,等待派发;或已派发但工人尚未接单/已拒绝)
    ACCEPTED: '3',           // 已接单 (工人已接受订单)
    IN_SERVICE: '4',
    PENDING_REVIEW: '5',
    COMPLETED: '6',
    CANCELED: '7',
    REFUNDED: '8',
};

/**
 * 工人在 `order_assignments` (订单派工历史表) 中可能的操作状态枚举。
 * (与 dispatchOrder 中的定义一致)
 */
const WORKER_STATUS_ENUM = {
    PENDING_ACCEPTANCE: '1',  // 待接单
    ACCEPTED: '2',            // 已接单
    REJECTED: '3',            // 已拒单
    ON_THE_WAY: '4',
    IN_PROGRESS: '5',
    COMPLETED: '6',
};

/**
 * 订单主表 `jz_orders` 中 `dispatchStatus` 字段的枚举。
 * (与 dispatchOrder 中的定义一致)
 */
const DISPATCH_STATUS_ENUM = {
    PENDING_DISPATCH: '1',
    DISPATCHED_PENDING_ACCEPTANCE: '2',// 已派发待接单
    DISPATCHED_ACCEPTED: '3',          // 已派发已接单
    DISPATCHED_REJECTED: '4',          // 已派发已拒单
};

/**
 * 工人接单函数
 * 工人通过此函数接受派发给他们的订单。
 *
 * @param {object} params - 入参
 * @param {string} params.orderId - 订单ID (主键 _id)
 * @param {string} params.workerId - 执行此操作的工人ID (当前登录工人)
 * @param {object} context - 微搭云函数上下文对象
 * @returns {Promise<object>} 接单结果,包含 code, message, data (更新后的订单信息)
 */
module.exports = async function (params, context) {
    const { orderId, workerId } = params;

    // 1. 参数验证
    if (!orderId || !workerId) {
        return { code: ErrorCode.PARAM_ERROR, message: '必填参数缺失: orderId, workerId' };
    }

    try {
        // 2. 查找订单的当前状态和派单状态
        const order = await context.callModel({
            dataSourceName: "jz_orders", // 订单表模型标识
            methodName: "wedaGetItemV2",
            params: {
                filter: {
                    where: {
                        _id: { $eq: orderId }
                    }
                },
                select: { "$master": true, "dispatchStatus": true, "assignedWorkerId": true } // 获取主状态、派单状态和当前指派工人
            }
        });

        if (!order || Object.keys(order).length === 0) {
            return { code: ErrorCode.NOT_FOUND, message: '订单未找到' };
        }

        // 3. 验证订单的主状态 (`orders.status`) 是否允许接单
        // 只有当订单主状态为 '2' (待接单) 时,才允许工人接单。
        // 如果订单已是 '3' (已接单) 或其他状态,则不能重复接单。
        if (order.status !== ORDER_STATUS_ENUM.PENDING_ACCEPTANCE) {
            return {
                code: ErrorCode.INVALID_ORDER_STATUS,
                message: `订单当前主状态不允许接单。订单必须处于"待接单"状态。当前状态码: ${order.status}`
            };
        }

        // 4. 验证订单的派单状态 (`orders.dispatchStatus`)
        // 只有当订单的派单状态是"已派发待接单"时,才能执行接单操作。
        const currentDispatchStatus = order.dispatchStatus;
        if (currentDispatchStatus !== DISPATCH_STATUS_ENUM.DISPATCHED_PENDING_ACCEPTANCE) {
            return {
                code: ErrorCode.INVALID_DISPATCH_STATUS,
                message: `订单当前派单状态不允许接单。订单派单状态必须为"已派发待接单"。当前状态码: ${currentDispatchStatus}`
            };
        }

        // 5. 查找对应的 `order_assignments` 派工记录
        // 确保是该工人被派发且处于"待接单"状态的记录
        const assignment = await context.callModel({
            dataSourceName: "order_assignments", // 订单派工表模型标识
            methodName: "wedaGetItemV2",
            params: {
                filter: {
                    relateWhere: {
                        order_id: { where: { _id: { $eq: orderId } } },
                        worker_id: { where: { _id: { $eq: workerId } } } // 确保是当前工人对应的派工记录
                    },
                    where: {
                        worker_status: { $eq: WORKER_STATUS_ENUM.PENDING_ACCEPTANCE } // 派工记录必须是"待接单"
                    }
                },
                select: { "$master": true } // 获取派工记录所有字段
            }
        });

        if (!assignment || Object.keys(assignment).length === 0) {
            return {
                code: ErrorCode.NOT_FOUND,
                message: '未找到该订单的有效派工记录(可能未派发给您或已处理)'
            };
        }

        // 6. 更新 `order_assignments` 表中的派工记录状态
        const updateAssignmentParams = {
            worker_status: WORKER_STATUS_ENUM.ACCEPTED, // 更新为 '2' (已接单)
            accepted_at: Date.now(),                 // 记录接单时间
        };

        await context.callModel({
            dataSourceName: "order_assignments",
            methodName: "wedaUpdateV2",
            params: {
                data: updateAssignmentParams,
                filter: {
                    where: { _id: { $eq: assignment._id } } // 根据派工记录ID更新
                }
            }
        });

        // 7. 更新 `jz_orders` (订单主表) 的状态和派单状态
        const updateOrderParams = {
            status: ORDER_STATUS_ENUM.ACCEPTED,           // 订单主状态更新为 '3' (已接单)
            dispatchStatus: DISPATCH_STATUS_ENUM.DISPATCHED_ACCEPTED, // 派单状态更新为 '3' (已派发已接单)
            acceptanceTime: Date.now(),                   // 订单的接单时间 (主表的字段)
        };

        await context.callModel({
            dataSourceName: "jz_orders",
            methodName: "wedaUpdateV2",
            params: {
                data: updateOrderParams,
                filter: {
                    where: { _id: { $eq: orderId } }
                }
            }
        });

        // 8. 在 `order_status_logs` (订单状态日志表) 插入日志记录
        const logDescription = `工人 (ID: ${workerId}) 已接单。订单主状态由 "${order.status}" 变为 "${ORDER_STATUS_ENUM.ACCEPTED}",派单状态由 "${currentDispatchStatus}" 变为 "${DISPATCH_STATUS_ENUM.DISPATCHED_ACCEPTED}"。`;

        await context.callModel({
            dataSourceName: "order_status_logs", // 订单状态日志表模型标识
            methodName: "wedaCreateV2",
            params: {
                data: {
                    orderId: { _id: orderId },
                    eventType: '接单', // 事件类型
                    eventDescription: logDescription,
                    operatorRole: '工人', // 操作角色为工人
                    operatorId: workerId, // 操作人ID为工人ID
                    fssj: Date.now(), // 发生时间
                    // old_status: order.status, // 记录旧的订单主状态
                    // new_status: ORDER_STATUS_ENUM.ACCEPTED, // 记录新的订单主状态
                    // additionalInfo: JSON.stringify({ oldDispatchStatus: currentDispatchStatus, newDispatchStatus: DISPATCH_STATUS_ENUM.DISPATCHED_ACCEPTED })
                }
            }
        });

        // 9. 通知客服或其他相关方订单已被接单
        console.log(`订单 ${orderId} 已被工人 ${workerId} 接单。`);
        // 实际应用中可能需要发送消息通知客服或客户

        // 10. 返回接单结果
        const updatedOrder = await context.callModel({
            dataSourceName: "jz_orders",
            methodName: "wedaGetItemV2",
            params: {
                filter: {
                    where: { _id: { $eq: orderId } }
                },
                select: { "$master": true, "assignedWorkerId": true, "dispatchStatus": true }
            }
        });

        return {
            code: ErrorCode.SUCCESS,
            message: '订单接单成功',
            data: updatedOrder // 返回更新后的订单信息
        };

    } catch (error) {
        console.error("acceptOrder error:", error);
        return {
            code: ErrorCode.SYSTEM_ERROR,
            message: `系统错误: ${error.message}`
        };
    }
};

增加入参

入参添加好之后,点击方法测试

输入必要的参数点击运行测试,测试通过之后点击出参自动映射

2 前端调用

后端API编写好了之后,就需要前端进行调用。切换到我们的工作台页面,选择接单的按钮

选择调用数据源方法

选择订单管理的接单方法

绑定入参

然后再跟一个数据列表刷新的事件

然后给按钮配置条件展示,当我们的状态是1的时候才显示这个按钮

整体效果

工人打开工作台页面,看到需要接单的订单信息

点击接单,订单状态修改为已接单的状态

总结

本篇我们介绍了工人接单的业务逻辑实现,编写了后端API来更新相关的表的状态,前端我们通过配置按钮的点击事件来调用我们的后端API。后续的服务流程的搭建思路也是一样的,总是先实现API,然后再通过按钮来进行调用。

相关推荐
汤姆yu7 小时前
基于微信小程序的学校招生系统
微信小程序·小程序·招生小程序
说私域14 小时前
基于开源AI智能名片链动2+1模式的S2B2C商城小程序:门店私域流量与视频号直播融合的生态创新研究
人工智能·小程序·开源
说私域17 小时前
传统微商困境与开源链动2+1模式、AI智能名片及S2B2C商城小程序的转型破局
人工智能·小程序·开源
一渊之隔17 小时前
微信小程序在用户拒绝授权后无法使用wx.opensetting再次获取定位授权
微信小程序·小程序
racerun21 小时前
微信小程序如何实现再多个页面共享数据
微信小程序·小程序
XM-545821 小时前
2025微信小程序wxapkg解包全攻略
linux·运维·小程序
低代码布道师1 天前
微搭低代码实战训练营课程总结
低代码
低代码布道师1 天前
微搭低代码实战训练营课后资料包(三)接口文档
低代码
HERR_QQ2 天前
【unify】unify的微信小程序开发学习 (to be continued)
学习·微信小程序·小程序
速易达网络2 天前
RuoYi、Vue CLI 和 uni-app 结合构建跨端全家桶方案
javascript·vue.js·低代码