1 用户管理
1.1 用户登录API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 , // 用户未找到(未注册)
SYSTEM_ERROR: 1003 ,
// USER_EXISTS: 1004 , // 注册时用
// USER_NOT_EXISTS: 1005 // 可以用 NOT_FOUND 代替
} ;
module.exports = async function ( params, context) {
// 这里是方法入参
console.log( params) ;
const { openid } = params
if ( ! openid) {
return {
code: ErrorCode.PARAM_ERROR,
message: "参数错误,openid缺失"
}
}
try {
const result = await context.callModel( {
dataSourceName: 'xx_users' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaGetRecordsV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
filter: {
where: {
$and : [
{
openid: { $eq : openid } ,
} ,
] ,
} ,
} ,
select: {
"$master " : true
} ,
getCount: true,
pageSize: 1 ,
pageNumber: 1
} , // 数据模型方法的入参
} ) ;
if ( result.total == 0 ) {
return {
code: ErrorCode.NOT_FOUND,
message: "用户未注册,请先注册再登录"
}
}
const user = result.records[ 0 ]
const member = await context.callModel( {
dataSourceName: 'xx_members' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaGetRecordsV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
filter: {
where: {
$and : [
{
userId: { $eq : user._id } ,
} ,
] ,
} ,
} ,
select: {
"$master " : true
} ,
getCount: true,
pageSize: 1 ,
pageNumber: 1
} , // 数据模型方法的入参
} ) ;
return {
code: ErrorCode.SUCCESS,
messge: "用户登录成功" ,
userInfo: user,
memberInfo: member.records[ 0 ]
}
} catch {
return {
code: ErrorCode.SYSTEM_ERROR,
message: "系统异常,请稍后再试"
}
}
} ;
1.2 用户注册API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 ,
SYSTEM_ERROR: 1003 ,
USER_EXISTS: 1004 ,
USER_NOT_EXISTS: 1005 // 虽然注册时不会返回这个,但作为通用码保留
} ;
module.exports = async function ( params, context) {
// 这里是方法入参
console.log( params) ;
const { openid,phone,nickname, avtarURL} = params;
if ( ! openid) {
return {
code: ErrorCode.PARAM_ERROR,
message: '参数错误,openid 缺失'
} ;
}
try {
// 2 . 检查用户是否已存在
// 使用平台提供的数据模型查询方法 wedaGetItemV2
const existUserResult = await context.callModel( { // 注意:callModel 可能是特定平台的调用方式
name: "xx_users" , // 查询 users 模型
methodName: "wedaGetRecordsV2" , // 使用获取列表方法,因为可能需要复杂查询
params: {
filter: {
where: {
$and : [
{
openid: { $eq : openid } ,
} ,
] ,
} ,
} ,
select:{
$master :true
} ,
// 返回total字段
getCount: true,
// 页面大小
pageSize: 1 ,
// 当前页面
pageNumber: 1 ,
}
} ) ;
console.log( "existUserResult" , existUserResult) ; // 打印日志方便调试
// 检查查询结果列表是否为空
if ( existUserResult.total && existUserResult.total > 0 ) {
return {
code: ErrorCode.USER_EXISTS,
message: '用户已存在,请直接登录'
} ;
}
// 3 . 创建新用户
// 使用平台提供的数据模型创建方法 wedaCreateV2
const newUserResult = await context.callModel( {
name: "xx_users" , // 操作 users 模型
methodName: "wedaCreateV2" ,
params: {
data: {
openid:openid,
phone:phone,
nickname:nickname,
avtarURL:avtarURL,
status: "1" // 默认状态设为正常
// 其他用户字段,如果需要,注册时可填写默认值或留空后续编辑
}
}
} ) ;
const userId = newUserResult.id // 获取新创建用户的 ID
// 4 . 开通会员(创建会员记录并关联用户)
// 使用平台提供的数据模型创建方法 wedaCreateV2
const memberResult = await context.callModel( {
name: "xx_members" , // 操作 members 模型
methodName: "wedaCreateV2" ,
params: {
data: {
userId: { _id: userId } , // 关联刚刚创建的用户ID
level: "1" , // 默认会员等级
status: "1" , // 默认状态正常
points: 0 , // 初始积分
balance: 0 // 初始余额
}
}
} ) ;
const memberId = memberResult.id // 获取新创建会员的 ID
// 5 . 注册成功,返回用户ID和会员ID
return {
code: ErrorCode.SUCCESS,
data: {
userId: userId, // 返回新用户ID
memberId: memberId // 返回新会员ID
}
} ;
} catch ( error) {
console.error( "registerUser error:" , error) ; // 记录错误日志
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} ` // 返回错误信息
} ;
}
}
1.3 前端调用
export default async function login ( ) {
const userInfo = await $w .auth.getUserInfo( ) ;
console.log( '$w .auth.getUserInfo:' , userInfo) ;
const openid = userInfo.openId
console.log( "openid" ,openid)
console.log( '$w .auth.currentUser:' , $w .auth.currentUser) ;
const result = await $w .cloud.callDataSource( {
dataSourceName: 'userManagement_0fstpag' ,
methodName: 'login' ,
params: {
"openid" : openid
}
} ) ;
$w .app.dataset.state.userData = result
}
1.4 加入购物车
export default function( { event, data} ) {
const item = data.target;
console.log( "item" , item) ;
// 检查是否已存在相同ID的商品
const cart = $w .app.dataset.state.cart;
const existingItemIndex = cart.findIndex( cartItem = > cartItem._id == = item._id) ;
if ( existingItemIndex == = -1) {
// 不存在重复项,添加到购物车
$w .app.dataset.state.cart.push( item) ;
console.log( "已添加到购物车:" , item) ;
} else {
// 存在重复项,可选择提示用户或增加数量
console.log( "商品已在购物车中:" , item) ;
// 可选:更新数量
// cart[ existingItemIndex] .quantity += 1 ;
}
}
1.5 收藏服务API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 ,
SYSTEM_ERROR: 1003 ,
ALREADY_FAVORITED: 1006 , // 已收藏错误码
} ;
module.exports = async function ( params, context) {
console.log( params) ;
const { openid, serviceId } = params;
// 1 . 参数校验
if ( ! openid || ! serviceId) {
return {
code: ErrorCode.PARAM_ERROR,
message: '参数错误,openid 或 serviceId 缺失'
} ;
}
try {
// 2 . 检查是否已收藏
const existFavoriteResult = await context.callModel( {
name: "favorites" , // 收藏表名,根据实际情况调整
methodName: "wedaGetRecordsV2" ,
params: {
filter: {
where: {
$and : [
{ openid: { $eq : openid } } ,
{ serviceId: { $eq : serviceId } }
] ,
} ,
} ,
select: { $master : true } ,
getCount: true,
pageSize: 1 ,
pageNumber: 1 ,
}
} ) ;
console.log( "existFavoriteResult" , existFavoriteResult) ;
// 如果已收藏,返回错误
if ( existFavoriteResult.total && existFavoriteResult.total > 0 ) {
return {
code: ErrorCode.ALREADY_FAVORITED,
message: '该服务已收藏'
} ;
}
// 3 . 创建新收藏记录
const newFavoriteResult = await context.callModel( {
name: "favorites" ,
methodName: "wedaCreateV2" ,
params: {
data: {
openid: openid,
serviceId: { _id:serviceId} ,
created_at: Date.now( ) , // 记录收藏时间
}
}
} ) ;
const favoriteId = newFavoriteResult.id;
// 4 . 返回成功结果
return {
code: ErrorCode.SUCCESS,
data: {
favoriteId: favoriteId,
message: '收藏成功'
}
} ;
} catch ( error) {
console.error( "addFavorite error:" , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
1.6 用户评价API
/**
* ErrorCode 定义
* 统一管理系统可能返回的错误码和消息。
*/
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 , // 参数缺失或无效
NOT_FOUND: 1002 , // 订单或派工记录未找到
SYSTEM_ERROR: 1003 , // 通用系统错误
INVALID_ORDER_STATUS: 1004 , // 订单当前主状态不允许评价
// 更多错误码可以按需添加
} ;
/**
* 订单在 ` jz_orders` ( 订单主表) 中可能的主状态枚举。
*/
const ORDER_STATUS_ENUM = {
PENDING_PAYMENT: '1' ,
PENDING_ACCEPTANCE: '2' , // 待接单
ACCEPTED: '3' , // 已接单
IN_SERVICE: '4' , // 服务中
PENDING_REVIEW: '5' , // 待评价 ( 服务已完成,等待用户评价)
COMPLETED: '6' , // 已完成 ( 用户已评价或已过评价期)
CANCELED: '7' ,
REFUNDED: '8' ,
} ;
/**
* 订单主表 ` jz_orders` 中 ` dispatchStatus` 字段的枚举。
*/
const DISPATCH_STATUS_ENUM = {
PENDING_DISPATCH: '1' ,
DISPATCHED_PENDING_ACCEPTANCE: '2' ,
DISPATCHED_ACCEPTED: '3' ,
DISPATCHED_REJECTED: '4' ,
DISPATCHED_COMPLETED: '5' , // 派单已完成 ( 工人已完成服务)
} ;
/**
* 提交评价函数
* 用户通过此函数提交对已完成服务的评价。
*
* @param { object} params - 入参
* @param { string} params.orderId - 订单ID ( 主键 _id)
* @param { string} params.userId - 提交评价的用户ID ( 当前登录用户)
* @param { number} params.overallRating - 整体服务评分 ( 1 -5星)
* @param { number} params.serviceQualityRating - 服务质量评分 ( 1 -5星)
* @param { number} params.serviceAttitudeRating - 服务态度评分 ( 1 -5星)
* @param { number} params.professionalismRating - 专业程度评分 ( 1 -5星)
* @param { number} params.punctualityRating - 准时程度评分 ( 1 -5星)
* @param { string} [ params.reviewContent] - 评价内容 ( 可选)
* @param { Array< string> } [ params.reviewPhotos] - 评价照片的URL数组 ( 可选)
* @param { boolean} [ params.isAnonymous= false] - 是否匿名评价 ( 可选,默认为false)
* @param { object} context - 微搭云函数上下文对象
* @returns { Promise< object> } 评价结果,包含 code, message, data ( 更新后的订单信息)
*/
module.exports = async function ( params, context) {
const {
orderId: rawOrderId,
userId:rawUserId,
overallRating,
serviceQualityRating,
serviceAttitudeRating,
professionalismRating,
punctualityRating,
reviewContent = '' ,
reviewPhotos = [ ] ,
isAnonymous = false
} = params;
const orderId = rawOrderId && typeof rawOrderId == = 'object' ? rawOrderId._id : rawOrderId;
const userId = rawUserId && typeof rawUserId == = 'object' ? rawUserId._id: rawUserId;
// 1 . 参数验证
if ( ! orderId || ! userId ||
overallRating == = undefined ||
serviceQualityRating == = undefined ||
serviceAttitudeRating == = undefined ||
professionalismRating == = undefined ||
punctualityRating == = undefined
) {
return { code: ErrorCode.PARAM_ERROR, message: '必填参数缺失或无效:orderId, userId, 完整评分数据' } ;
}
// 验证评分是否在有效范围内 ( 1 -5)
const ratings = [ overallRating, serviceQualityRating, serviceAttitudeRating, professionalismRating, punctualityRating] ;
if ( ratings.some( r = > r < 1 || r > 5 )) {
return { code: ErrorCode.PARAM_ERROR, message: '评分必须在1到5之间' } ;
}
let order = null;
let service = null;
let provider = null;
try {
// 2 . 查找订单的当前状态,并获取 service_id 和 assignedWorkerId
order = await context.callModel( {
dataSourceName: "orders" , // 订单表模型标识
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : orderId }
}
} ,
select: {
"$master " : true,
"serviceId" : true, // 获取关联的服务ID
"assignedWorkerId" : true // 获取被指派的工人ID
}
}
} ) ;
if ( ! order || Object.keys( order) .length == = 0 ) {
return { code: ErrorCode.NOT_FOUND, message: '订单未找到' } ;
}
// 验证订单是否处于“待评价”状态
if ( order.status != = ORDER_STATUS_ENUM.PENDING_REVIEW) {
return {
code: ErrorCode.INVALID_ORDER_STATUS,
message: ` 订单当前状态不允许评价。订单必须处于“待评价”状态。当前状态码: ${ order.status} `
} ;
}
const serviceId = order.serviceId && order.serviceId._id; // 假设 serviceId 是一个引用类型,需要取 _id
const providerId = order.assignedWorkerId && order.assignedWorkerId._id; // 假设 assignedWorkerId 是一个引用类型,需要取 _id
if ( ! serviceId || ! providerId) {
return { code: ErrorCode.SYSTEM_ERROR, message: '订单关联的服务或工人信息不完整' } ;
}
// 3 . 查找服务信息 ( 用于后续更新服务的平均分)
service = await context.callModel( {
dataSourceName: "xx_services" , // 服务表模型标识
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : serviceId }
}
} ,
select: { "_id" : true, "avg_rating" : true, "total_reviews" : true }
}
} ) ;
// 4 . 查找服务提供者信息 ( 用于后续更新工人的平均分)
provider = await context.callModel( {
dataSourceName: "worker" , // 服务提供者表模型标识
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : providerId }
}
} ,
select: { "_id" : true, "avg_rating" : true, "total_reviews" : true }
}
} ) ;
if ( ! service || ! provider || Object.keys( service) .length == = 0 || Object.keys( provider) .length == = 0 ) {
return { code: ErrorCode.NOT_FOUND, message: '关联的服务或服务提供者未找到' } ;
}
// 5 . 插入新的评价记录到 ` Reviews` 表
const newReviewData = {
orderId: { _id: orderId } , // 关联订单
userId: { _id: userId } , // 关联用户
serviceId: { _id: serviceId } , // 关联服务
providerId: { _id: providerId } , // 关联服务提供者
overall_rating: overallRating,
service_quality_rating: serviceQualityRating,
service_attitude_rating: serviceAttitudeRating,
professionalism_rating: professionalismRating,
punctuality_rating: punctualityRating,
review_content: reviewContent,
review_photos: reviewPhotos,
is_anonymous: isAnonymous,
review_date: Date.now( )
} ;
await context.callModel( {
dataSourceName: "Reviews" , // 评价表模型标识
methodName: "wedaCreateV2" ,
params: {
data: newReviewData
}
} ) ;
// 6 . 更新 ` ServiceProviders` 表中的评分和评价数
// 重新计算该工人的平均评分和总评价数
const providerReviews = await context.callModel( {
dataSourceName: "Reviews" , // 数据模型标识,对应你之前设计的 Reviews 表
methodName: "wedaGetRecordsV2" , // 获取所有相关评价记录的方法
params: {
filter: {
relateWhere: {
providerId: {
where: {
_id: {
$eq : providerId
}
}
}
}
} ,
select: {
"overall_rating" : true // 只选择评分字段,减少数据传输量
} ,
getCount: true // 获取总条数,wedaGetRecordsV2 返回的数据结构中会包含 total 字段
// 如果数据量巨大,不建议一次性获取所有记录。
// 可以考虑分批获取或利用数据库的聚合功能(如果微搭的callModel支持)
// 或者在 Reviews 表中维护 providerId 相关的冗余统计字段,通过触发器或定期任务更新
}
} ) ;
let newProviderAvgRating = 0 ;
let newProviderTotalReviews = providerReviews.total; // total属性表示总条数
if ( newProviderTotalReviews > 0 ) {
const sumProviderRatings = providerReviews.records.reduce(( sum, r) = > sum + r.overall_rating, 0 ) ;
newProviderAvgRating = parseFloat(( sumProviderRatings / newProviderTotalReviews) .toFixed( 1 )) ; // 保留一位小数
}
await context.callModel( {
dataSourceName: "worker" ,
methodName: "wedaUpdateV2" ,
params: {
data: {
avg_rating: newProviderAvgRating,
total_reviews: newProviderTotalReviews
} ,
filter: {
where: { _id: { $eq : providerId } }
}
}
} ) ;
// 7 . 更新 ` Services` 表中的评分和评价数
// 重新计算该服务的平均评分和总评价数
const serviceReviews = await context.callModel( {
dataSourceName: "Reviews" ,
methodName: "wedaGetRecordsV2" , // 获取所有相关评价
params: {
filter: {
relateWhere: {
serviceId: {
where: {
_id: {
$eq : serviceId
}
}
}
}
} ,
select: { "overall_rating" : true } ,
getCount:true
}
} ) ;
let newServiceAvgRating = 0 ;
let newServiceTotalReviews = serviceReviews.total;
if ( newServiceTotalReviews > 0 ) {
const sumServiceRatings = serviceReviews.records.reduce(( sum, r) = > sum + r.overall_rating, 0 ) ;
newServiceAvgRating = parseFloat(( sumServiceRatings / newServiceTotalReviews) .toFixed( 1 )) ; // 保留一位小数
}
await context.callModel( {
dataSourceName: "xx_services" ,
methodName: "wedaUpdateV2" ,
params: {
data: {
avg_rating: newServiceAvgRating,
total_reviews: newServiceTotalReviews
} ,
filter: {
where: { _id: { $eq : serviceId } }
}
}
} ) ;
// 8 . 更新 ` jz_orders` ( 订单主表) 的状态为“已完成”
const updateOrderParams = {
status: ORDER_STATUS_ENUM.COMPLETED, // 订单主状态更新为 '6' ( 已完成)
dispatchStatus: DISPATCH_STATUS_ENUM.DISPATCHED_COMPLETED, // 派单状态也更新为已完成
completionTime: Date.now( ) , // 订单完成时间
} ;
await context.callModel( {
dataSourceName: "orders" ,
methodName: "wedaUpdateV2" ,
params: {
data: updateOrderParams,
filter: {
where: { _id: { $eq : orderId } }
}
}
} ) ;
// 9 . 在 ` order_status_logs` ( 订单状态日志表) 插入日志记录
const logDescription = ` 用户 ( ID: ${ userId} ) 已提交订单 ( ID: ${ orderId} ) 评价。订单主状态由 "${order.status} " 变为 "${ORDER_STATUS_ENUM.COMPLETED} " 。` ;
await context.callModel( {
dataSourceName: "order_status_logs" , // 订单状态日志表模型标识
methodName: "wedaCreateV2" ,
params: {
data: {
orderId: { _id: orderId } ,
eventType: '10' , // 事件类型
eventDescription: logDescription,
operatorRole: '1' , // 操作角色为用户
operatorId: userId, // 操作人ID为用户ID
timestamp: Date.now( ) , // 发生时间
}
}
} ) ;
// 10 . 返回评价结果
const updatedOrder = await context.callModel( {
dataSourceName: "orders" ,
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: { _id: { $eq : orderId } }
} ,
select: { "$master " : true, "status" : true, "dispatchStatus" : true }
}
} ) ;
return {
code: ErrorCode.SUCCESS,
message: '订单评价成功' ,
data: updatedOrder // 返回更新后的订单信息
} ;
} catch ( error) {
console.error( "submitReview error:" , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
1.7 用户点赞API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 ,
SYSTEM_ERROR: 1003 ,
ALREADY_LIKED: 1007 , // 已点赞错误码
} ;
module.exports = async function ( params, context) {
console.log( params) ;
const { openid, workerId,userId } = params;
// 1 . 参数校验
if ( ! openid || ! workerId|| ! userId) {
return {
code: ErrorCode.PARAM_ERROR,
message: '参数错误,openid 或 workerId 或userId缺失'
} ;
}
try {
// 2 . 检查是否已点赞
const existLikeResult = await context.callModel( {
name: "like_record" , // 点赞记录表名
methodName: "wedaGetRecordsV2" ,
params: {
filter: {
where: {
$and : [
{ openid: { $eq : openid } } ,
{ worker_id: { $eq : workerId } }
] ,
} ,
} ,
select: { $master : true } ,
getCount: true,
pageSize: 1 ,
pageNumber: 1 ,
}
} ) ;
console.log( "existLikeResult" , existLikeResult) ;
// 如果已点赞,返回错误
if ( existLikeResult.total && existLikeResult.total > 0 ) {
return {
code: ErrorCode.ALREADY_LIKED,
message: '该工人已点赞'
} ;
}
// 3 . 开启事务(如果支持)
// 注意:context 是否支持事务需要根据实际环境确定
// 这里假设存在 context.startTransaction 和 context.commitTransaction 方法
try {
// 4 . 创建新点赞记录
const newLikeResult = await context.callModel( {
name: "like_record" ,
methodName: "wedaCreateV2" ,
params: {
data: {
openid: openid,
worker_id: { _id: workerId} ,
liker_id:{ _id:userId}
}
}
} ) ;
const likeId = newLikeResult.id;
const likers = await context.callModel( {
dataSourceName: "like_record" , // 数据模型标识,对应你之前设计的 Reviews 表
methodName: "wedaGetRecordsV2" , // 获取所有相关评价记录的方法
params: {
filter: {
relateWhere: {
worker_id: {
where: {
_id: {
$eq : workerId
}
}
}
}
} ,
select: {
"$master " : true // 只选择评分字段,减少数据传输量
} ,
getCount: true // 获取总条数,wedaGetRecordsV2 返回的数据结构中会包含 total 字段
// 如果数据量巨大,不建议一次性获取所有记录。
// 可以考虑分批获取或利用数据库的聚合功能(如果微搭的callModel支持)
// 或者在 Reviews 表中维护 providerId 相关的冗余统计字段,通过触发器或定期任务更新
}
} ) ;
const likeCount = likers.total
// 5 . 更新工人表的点赞次数
await context.callModel( {
name: "worker" ,
methodName: "wedaUpdateV2" ,
params: {
filter: {
where: {
_id: { $eq : workerId }
}
} ,
data: {
// 使用原子操作增加点赞次数
// 假设支持 $inc 操作符,否则需要先查询再更新
like_count: likeCount
}
}
} ) ;
// 7 . 返回成功结果
return {
code: ErrorCode.SUCCESS,
data: {
likeId: likeId,
message: '点赞成功'
}
} ;
} catch ( txError) {
// 回滚事务
throw txError;
}
} catch ( error) {
console.error( "addLike error:" , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
2 会员管理
2.1 会员充值API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 ,
SYSTEM_ERROR: 1003 ,
USER_NOT_EXISTS: 1005 ,
MEMBER_NOT_EXISTS: 1006 ,
INVALID_AMOUNT: 1007
} ;
module.exports = async function ( params, context) {
console.log( '充值API入参:' , params) ;
// 1 . 解析并校验参数
const { userId, memberId, amount, paymentMethod } = params;
if ( ! userId) {
return { code: ErrorCode.PARAM_ERROR, message: '用户ID不能为空' } ;
}
if ( ! memberId) {
return { code: ErrorCode.PARAM_ERROR, message: '会员ID不能为空' } ;
}
if ( typeof amount != = 'number' || amount < = 0 ) {
return { code: ErrorCode.INVALID_AMOUNT, message: '充值金额必须为正数' } ;
}
if ( ! paymentMethod) {
return { code: ErrorCode.PARAM_ERROR, message: '支付方式不能为空' } ;
}
try {
// 2 . 查询会员详情(使用wedaGetItemV2)
const memberResult = await context.callModel( {
name: "xx_members" ,
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : memberId } ,
}
} ,
select: {
$master : true
}
}
} ) ;
// 检查会员是否存在
if ( ! memberResult ||
typeof memberResult != = 'object' ||
Object.keys( memberResult) .length == = 0 ||
! memberResult._id) {
return { code: ErrorCode.MEMBER_NOT_EXISTS, message: '会员记录不存在' } ;
}
const currentBalance = memberResult.balance || 0 ;
// 3 . 创建充值记录
const rechargeResult = await context.callModel( {
name: "recharge_records" ,
methodName: "wedaCreateV2" ,
params: {
data: {
user_id: { _id: userId } ,
member_id: { _id: memberId } ,
recharge_amount: amount,
payment_method: paymentMethod,
recharge_time: Date.now( )
}
}
} ) ;
// 4 . 更新会员余额(使用事务确保原子性)
const updateResult = await context.callModel( {
name: "xx_members" ,
methodName: "wedaUpdateV2" ,
params: {
data: {
balance: currentBalance + amount,
// 如果需要根据充值金额增加积分,可以在这里添加逻辑
// points: memberResult.points + Math.floor( amount * 0.1 ) // 每充值1元积0.1分
} ,
filter: {
where: {
_id: { $eq : memberId }
}
}
}
} ) ;
// 5 . 返回成功结果
return {
code: ErrorCode.SUCCESS,
data: {
rechargeId: rechargeResult.id,
newBalance: currentBalance + amount,
rechargeTime: Date.now( )
} ,
message: '充值成功'
} ;
} catch ( error) {
console.error( '充值API错误:' , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
2.2 前端调用
export default async function( { event, data} ) {
const amount = $w .tagSelect1.value
const payment = $w .select1.value
const userid = $w .app.dataset.state.userData?.userInfo?._id
const memeberid = $w .app.dataset.state.userData?.memberInfo?._id
const orgin_balance = $w .app.dataset.state.userData?.memberInfo?.balance
// 参数校验
if ( ! amount) {
throw new Error( '请选择充值金额' ) ;
}
if ( ! payment) {
throw new Error( '请选择支付方式' ) ;
}
if( ! userid) {
throw new Error( '未获取到用户信息' ) ;
}
if( ! memeberid) {
throw new Error( '未获取到会员信息' ) ;
}
// 后续充值处理逻辑.. .
console.log( '参数校验通过,准备充值:' , { amount, payment } ) ;
// 这里可以添加实际的充值API调用代码
const result = await $w .cloud.callDataSource( {
dataSourceName: 'recharge_records' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaCreateV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
data:{
user_id:{ _id:userid} ,
member_id:{ _id:memeberid} ,
recharge_amount:Number( amount) ,
payment_method:payment,
recharge_time:Date.now( )
} ,
} , // 数据模型方法的入参
} ) ;
await $w .cloud.callDataSource( {
dataSourceName: 'xx_members' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaUpdateV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
data:{
balance:orgin_balance+Number( amount)
} ,
filter:{
where:{
_id:{ $eq :memeberid}
}
}
} , // 数据模型方法的入参
} ) ;
}
3 订单管理
3.1 创建订单
export default function ( { event, data } ) {
const totalAmount = $w .page.dataset.state.currentPrice
const serviceId = $w .page.dataset.params.serviceId
if( ! totalAmount) {
$w .utils.showToast( {
title: '请先选择规格,然后再下单' ,
icon: 'error' ,
duration: 2000 // 2 秒
} ) ;
return
}
if( ! serviceId) {
$w .utils.showToast( {
title: '请先选择具体的服务,然后再下单' ,
icon: 'error' ,
duration: 2000 // 2 秒
} ) ;
return
}
const spec = $w .tagSelect1.value + "/" + $w .tagSelect2.value
if ( $w .app.dataset.state.userData?.userInfo?._id) {
$w .utils.navigateTo( {
pageId: 'u_xin_zeng_yu_yue' , // 页面 Id
params: { serviceId: $w .page.dataset.params.serviceId, spec: spec, totalAmount: totalAmount }
} ) ;
} else {
$w .utils.showToast( {
title: '请先注册会员再下单' ,
icon: 'error' ,
duration: 2000 // 2 秒
} ) ;
}
}
3.2 创建订单API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 , // 服务或地址未找到
SYSTEM_ERROR: 1003 ,
// .. . 其他错误码
} ;
// 创建订单
module.exports = async function ( params, context) {
const { serviceId, userId,serviceDateTime, description, images, contactName, contactPhone, totalAmount,spec,openid} = params;
// 1 . 参数验证 ( 简化示例,实际需要更严格)
if ( ! userId || ! serviceId || ! serviceDateTime || ! contactName || ! contactPhone) {
return { code: ErrorCode.PARAM_ERROR, message: '必填参数缺失' } ;
}
try {
// 3 . 创建订单记录
const result = await context.callModel( {
name: "orders" , // 操作订单模型
methodName: "wedaCreateV2" , // 使用创建方法
params: {
data: {
userId: { _id: userId._id } , // 关联用户
serviceId: { _id: serviceId._id } , // 关联服务
serviceDateTime: serviceDateTime, // 存储为日期时间类型
description: description || '' , // 如果没有描述则存空字符串
images: images || [ ] , // 如果没有图片则存空数组
contactName: contactName,
contactPhone: contactPhone,
totalAmount: totalAmount, // 初始金额
status: '1' , // 初始状态:待付款 ( 假设1代表待付款)
paymentStatus: '1' , // 初始支付状态:待支付 ( 假设1代表待支付)
spec:spec,
openid:openid
// assignedProviderId 初始为空
}
}
} ) ;
const orderId = result.id; // 获取新创建订单的 ID
// 4 . 返回创建成功的订单信息
return {
code: ErrorCode.SUCCESS,
data: {
orderId: orderId,
totalAmount: totalAmount,
status: '1' // 返回当前状态
}
} ;
} catch ( error) {
console.error( "createOrder error:" , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
3.3 改变价格
export default async function( { event, data} ) {
const spec_type = $w .tagSelect1.value
const spec_content = $w .tagSelect2.value
const result = await $w .cloud.callDataSource( {
dataSourceName: 'service_spec' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaGetRecordsV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
filter:{
where:{
spec_type:{ $eq :spec_type} ,
spec_content:{ $eq :spec_content} ,
serviceId:{ $eq : $w .page.dataset.params.serviceId}
}
} ,
select : {
"$master " : true
} ,
getCount : true,
pageSize : 10 ,
pageNumber : 1
} , // 数据模型方法的入参
} ) ;
$w .page.dataset.state.currentPrice = result.records[ 0 ] .current_price
$w .page.dataset.state.orginPrice = result.records[ 0 ] .orgin_price
}
3.4 选择规格
export default async function( { event, data} ) {
const sepcType = $w .tagSelect1.value
const result = await $w .cloud.callDataSource( {
dataSourceName: 'service_spec' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaGetRecordsV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
filter:{
where:{
spec_type:{ $eq :sepcType} ,
serviceId:{ $eq : $w .page.dataset.params.serviceId}
}
} ,
select : {
"$master " : true
} ,
getCount : true,
pageSize : 10 ,
pageNumber : 1
} , // 数据模型方法的入参
} ) ;
console.log( "result" ,result)
$w .page.dataset.state.specContet = result.records.map( item= > ( {
label:item.spec_content,
value:item.spec_content
} ))
}
3.5 初始化规格
export default async function ( { event, data } ) {
const result = await $w .cloud.callDataSource( {
dataSourceName: 'service_spec' , // Data model identifier, can be viewed on the "Data Source - Data Model" list page
methodName: 'wedaGetRecordsV2' , // Data model method identifier. Supported methods can be viewed on the details page of any data model under "Data Source - Data Model"
params: {
filter: {
where: {
serviceId: { $eq : $w .page.dataset.params.serviceId }
}
} ,
select: {
"$master " : true
} ,
getCount: true,
pageSize: 10 ,
pageNumber: 1
} , // Input parameters for the data model method
} ) ;
// Check if records exist
if ( result.records && result.records.length > 0 ) {
// Initialize specType
const uniqueSpecTypes = Array.from( new Set( result.records.map( item = > item.spec_type)) ) ;
$w .page.dataset.state.specType = uniqueSpecTypes.map( item = > ( {
label: item,
value: item
} )) ;
// Get the first spec_type for filtering specContet
const firstSpecType = uniqueSpecTypes[ 0 ] ;
// Initialize specContet based on the first spec_type
const filteredSpecContent = result.records.filter( item = > item.spec_type == = firstSpecType) ;
$w .page.dataset.state.specContet = Array.from( new Set( filteredSpecContent.map( item = > item.spec_content)) ) .map( item = > ( {
label: item,
value: item
} )) ;
} else {
// Handle cases where no records are returned
$w .page.dataset.state.specType = [ ] ;
$w .page.dataset.state.specContet = [ ] ;
}
}
3.6 余额支付API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 ,
SYSTEM_ERROR: 1003 ,
USER_NOT_EXISTS: 1005 ,
MEMBER_NOT_EXISTS: 1006 ,
INVALID_AMOUNT: 1007 ,
INSUFFICIENT_BALANCE: 1008 ,
ORDER_NOT_EXISTS: 1009 ,
ORDER_ALREADY_PAID: 1010
} ;
module.exports = async function ( params, context) {
console.log( '余额扣减API入参:' , params) ;
// 1 . 解析并校验参数
const { memberId, orderId, deductionAmount,openid } = params;
if ( ! memberId) {
return { code: ErrorCode.PARAM_ERROR, message: '会员ID不能为空' } ;
}
if ( ! orderId) {
return { code: ErrorCode.PARAM_ERROR, message: '订单ID不能为空' } ;
}
if ( typeof deductionAmount != = 'number' || deductionAmount < = 0 ) {
return { code: ErrorCode.INVALID_AMOUNT, message: '扣减金额必须为正数' } ;
}
try {
// 2 . 查询会员详情,检查余额是否充足
const memberResult = await context.callModel( {
name: "xx_members" ,
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : memberId } ,
}
} ,
select: {
$master : true
}
}
} ) ;
// 检查会员是否存在
if ( ! memberResult ||
typeof memberResult != = 'object' ||
Object.keys( memberResult) .length == = 0 ||
! memberResult._id) {
return { code: ErrorCode.MEMBER_NOT_EXISTS, message: '会员记录不存在' } ;
}
const currentBalance = memberResult.balance || 0 ;
// 检查余额是否充足
if ( currentBalance < deductionAmount) {
return { code: ErrorCode.INSUFFICIENT_BALANCE, message: '余额不足,无法完成扣减' } ;
}
// 3 . 查询订单详情,确保订单存在且未支付
const orderResult = await context.callModel( {
name: "orders" ,
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : orderId } ,
}
} ,
select: {
$master : true
}
}
} ) ;
// 检查订单是否存在
if ( ! orderResult ||
typeof orderResult != = 'object' ||
Object.keys( orderResult) .length == = 0 ||
! orderResult._id) {
return { code: ErrorCode.ORDER_NOT_EXISTS, message: '订单记录不存在' } ;
}
// 检查订单状态(假设状态字段为order_status,值为"未支付" 、"已支付" 等)
if ( orderResult.status != = '1' ) {
return { code: ErrorCode.ORDER_ALREADY_PAID, message: '订单已支付或已处理,无法重复扣减' } ;
}
// 4 . 创建余额扣减记录
const deductionRecord = await context.callModel( {
name: "balance_deduction_record" ,
methodName: "wedaCreateV2" ,
params: {
data: {
memberId: { _id: memberId } ,
orderId: { _id: orderId } ,
deduction_amount: deductionAmount,
deduction_time: Date.now( ) ,
openid:openid
}
}
} ) ;
// 5 . 更新会员余额(使用事务确保原子性)
const newBalance = currentBalance - deductionAmount;
const updateMemberResult = await context.callModel( {
name: "xx_members" ,
methodName: "wedaUpdateV2" ,
params: {
data: {
balance: newBalance
} ,
filter: {
where: {
_id: { $eq : memberId }
}
}
}
} ) ;
// 6 . 更新订单状态为已支付
const updateOrderResult = await context.callModel( {
name: "orders" ,
methodName: "wedaUpdateV2" ,
params: {
data: {
paymentStatus:"2" ,
status: "2" ,
payment_time: Date.now( ) ,
payment_method: "3"
} ,
filter: {
where: {
_id: { $eq : orderId }
}
}
}
} ) ;
// 7 . 返回成功结果
return {
code: ErrorCode.SUCCESS,
data: {
deductionRecordId: deductionRecord.id,
newBalance: newBalance,
deductionTime: Date.now( ) ,
orderStatus: "已支付"
} ,
message: '余额扣减成功'
} ;
} catch ( error) {
console.error( '余额扣减API错误:' , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
3.7 余额支付前端调用
export default async function ( { event, data } ) {
const order = data.target
const openid = $w .auth.currentUser.openId
const memeber = $w .app.dataset.state.userData.memberInfo
if ( ! openid) {
$w .utils.showToast( {
title: "当前系统出错,请重新退出后再支付" ,
icon: "error" ,
duration: 1000
} )
return
}
if ( ! memeber?._id) {
$w .utils.showToast( {
title: "请先注册会员之后再支付" ,
icon: "error" ,
duration: 1000
} )
return
}
const result = await $w .cloud.callDataSource( {
dataSourceName: 'memberMangement_wrhs909' ,
methodName: 'handleBalanceDeduction' ,
params: {
"openid" : openid,
"orderId" :order._id,
"memberId" :memeber._id,
"deductionAmount" :Number( order.totalAmount)
}
} ) ;
if ( result.code == = 0 ) {
$w .utils.showToast( {
title: "支付成功" ,
icon: "success" ,
duration: 1000
} )
$w .listView1.refresh( { } )
return
} else {
$w .utils.showToast( {
title: "支付失败" ,
icon: "error" ,
duration: 1000
} )
return
}
}
3.8 选择地址
export default function( { event, data} ) {
const address = data.target
const detial_address = ( address?.region|| "" )
$w .app.dataset.state.addressId = address._id
$w .app.dataset.state.address = detial_address.split( ',' ) ?.join( '' ) +address.detailed_address
$w .app.dataset.state.name = address.name
$w .app.dataset.state.phone = address.phone_number
$w .utils.navigateBack( ) ;
}
3.9 切换订单状态
export default function( { event, data} ) {
const tabValue = data.target
console.log( "tabVlaue" ,tabValue)
if( tabValue== = "0" ) {
$w .page.dataset.state.status = undefined
} else{
$w .page.dataset.state.status = tabValue
}
}
3.10 接单API
/**
* 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: "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: "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: '4' , // 事件类型
eventDescription: logDescription,
operatorRole: '3' , // 操作角色为工人
operatorId: workerId, // 操作人ID为工人ID
timestamp: 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: "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} `
} ;
}
} ;
3.11 接单前端调用
export default async function ( { event, data } ) {
const record = data.target
const orderId = record._id
const workerId = record.assignedWorkerId._id
if( ! orderId|| ! workerId) {
$w .utils.showToast( {
title: "参数缺失" ,
icon: "error" ,
duration: 1000
} )
}
console.log( orderId, workerId)
const result = await $w .cloud.callDataSource( {
dataSourceName: 'orderManagement_gzftwil' ,
methodName: 'acceptOrder' ,
params: {
orderId: orderId,
workerId: workerId
} , // 方法入参
} ) ;
if ( result.code == = 0 ) {
$w .listView1.refresh( )
} else {
$w .utils.showToast( {
title: "接单失败" ,
icon: "error" ,
duration: 1000
} )
}
}
3.12 派单API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 , // 服务或地址未找到
INVALID_ORDER_STATUS: 1004 , // 订单状态不允许派单
SYSTEM_ERROR: 1003 ,
// .. . 其他错误码
} ;
/**
* 派发订单
* @param { object} params - 入参
* @param { string} params.orderId - 订单ID
* @param { string} [ params.targetWorkerId] - 目标技师ID ( 如果人工派单)
* @param { 'auto' | 'manual' } params.dispatchMethod - 派单方式 ( 自动/手动)
* @param { object} context - 上下文对象
* @returns { Promise< object> } 派单结果
*/
module.exports = async function ( params, context) {
const { orderId, targetWorkerId, dispatchMethod,operatorId } = params;
// 1 . 参数验证
if ( ! orderId || ! dispatchMethod) {
return { code: ErrorCode.PARAM_ERROR, message: '必填参数缺失: orderId, dispatchMethod' } ;
}
if ( dispatchMethod == = 'manual' && ! targetWorkerId) {
return { code: ErrorCode.PARAM_ERROR, message: '手动派单时 targetWorkerId 必填' } ;
}
try {
// 2 . 根据 orderId 查找订单
// 使用 wedaGetItemV2 查询单个订单
const orderResult = await context.callModel( {
name: "orders" , // 假设订单模型名为 jz_orders
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : orderId }
}
} ,
select: { $master : true } // 确保获取所有主表字段
}
} ) ;
const order = orderResult;
if ( ! order&& Object.keys( order) .length== 0 ) {
return { code: ErrorCode.NOT_FOUND, message: '订单未找到' } ;
}
// 3 . 验证订单 status 和 dispatchStatus 是否允许派单
// 假设 status: '2' 为 '待接单' , dispatchStatus: '1' 为 '待派单' , '4' 为 '技师已拒绝'
const ALLOWED_STATUS = [ '2' ] ; // 待接单
const ALLOWED_DISPATCH_STATUS = [ '1' , '4' ] ; // 待派单, 技师已拒绝
if ( ! ALLOWED_STATUS.includes( order.status) || ! ALLOWED_DISPATCH_STATUS.includes( order.dispatchStatus)) {
return {
code: ErrorCode.INVALID_ORDER_STATUS,
message: ` 订单当前状态或派单状态不允许派单。当前状态: ${ order.status} , 派单状态: ${ order.dispatchStatus} `
} ;
}
// 查找技师信息 ( 如果需要填充技师姓名)
let assignedWorkerName = '' ;
if ( targetWorkerId) {
const workerResult = await context.callModel( {
name: "worker" , // 假设技师模型名为 jz_workers
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : targetWorkerId }
}
} ,
select: { $master : true }
}
} ) ;
if ( ! workerResult&& Object.keys( workerResult) == 0 ) {
return { code: ErrorCode.NOT_FOUND, message: '指派的技师未找到' } ;
}
assignedWorkerName = workerResult.name || '' ; // 假设技师表有name字段
}
// 4 . 更新订单主表的 dispatchStatus
// 假设 '2' 为 '已派单'
const updateParams = {
dispatchStatus: '2' , // 已派单
assignedWorkerId: targetWorkerId ? { _id: targetWorkerId } : null, // 关联技师,如果为空则设为null
dispatchTime: Date.now( ) , // 派单时间
} ;
await context.callModel( {
name: "orders" ,
methodName: "wedaUpdateV2" ,
params: {
data: updateParams,
filter: {
where: {
_id: { $eq : orderId }
}
}
}
} ) ;
// 5 . 在 order_status_logs 子表插入一条 订单已派发 的日志记录
// 假设 order_status_logs 模型名为 jz_order_status_logs
const logDescription = ` 订单已派发给技师 ${ assignedWorkerName || '(未指定技师)' } 。派单方式: ${ dispatchMethod == = 'manual' ? '手动' : '自动' } ` ;
const operator = dispatchMethod == = 'manual' ? '客服' : '系统' ; // 根据 dispatchMethod 判断操作人
await context.callModel( {
name: "order_status_logs" , // 假设订单状态日志模型
methodName: "wedaCreateV2" ,
params: {
data: {
orderId: { _id: orderId } , // 关联订单
eventType: '3' , // '3' 对应 '已派单' 状态
eventDescription: logDescription,
operatorRole: operator,
timestamp: Date.now( ) ,
operatorId:operatorId
}
}
} ) ;
// 6 . 通知被指派的技师有新订单 ( 这里仅作示意,实际需要集成消息推送服务)
if ( targetWorkerId) {
console.log( ` 通知技师 ${ targetWorkerId} 有新订单: ${ orderId} ` ) ;
// 实际中可能调用 context.callModel 通知服务,或者直接使用消息队列等
// await context.callModel( {
// name: "notification_service" ,
// methodName: "sendPushNotification" ,
// params: {
// userId: targetWorkerId,
// message: ` 您有新的派单订单,订单号:${ orderId} ,请及时查看。`
// }
// } ) ;
}
// 7 . 返回派单结果和更新后的订单信息
// 重新查询订单以获取最新完整信息
const updatedOrderResult = await context.callModel( {
name: "orders" ,
methodName: "wedaGetItemV2" ,
params: {
filter: {
where: {
_id: { $eq : orderId }
}
} ,
select: { $master : true }
}
} ) ;
return {
code: ErrorCode.SUCCESS,
message: '订单派发成功' ,
data: updatedOrderResult // 返回更新后的订单信息
} ;
} catch ( error) {
console.error( "dispatchOrder error:" , error) ;
return {
code: ErrorCode.SYSTEM_ERROR,
message: ` 系统错误: ${ error.message} `
} ;
}
} ;
3.13 派单前端调用
export default async function ( { event, data } ) {
const record = data.target
const orderId = $w .modal1.openInfo
const targetWorkerId = record._id
const operatorId = $w .auth.currentUser.userId
const result = await $w .cloud.callDataSource( {
dataSourceName: 'orderManagement_gzftwil' ,
methodName: 'dispathOrder' ,
params: {
operatorId: operatorId,
dispatchMethod: "manual" ,
targetWorkerId: targetWorkerId,
orderId: orderId
} , // 方法入参
} ) ;
if ( result.code == = 0 ) {
$w .modal1.close( { } )
$w .table2.refreshKeepPage( )
} else {
$w .utils.showToast( {
title: "派单失败" ,
icon: "error" ,
duration: 1000
} )
return
}
}
4 工人管理
4.1 工人登录API
const ErrorCode = {
SUCCESS: 0 ,
PARAM_ERROR: 1001 ,
NOT_FOUND: 1002 , // 用户未找到(未注册)
SYSTEM_ERROR: 1003 ,
// USER_EXISTS: 1004 , // 注册时用
// USER_NOT_EXISTS: 1005 // 可以用 NOT_FOUND 代替
} ;
module.exports = async function ( params, context) {
// 这里是方法入参
console.log( params) ;
const { phone } = params
if ( ! phone) {
return {
code: ErrorCode.PARAM_ERROR,
message: "参数错误,电话缺失"
}
}
try {
const result = await context.callModel( {
dataSourceName: 'worker' , // 数据模型标识,可以前往「数据源 - 数据模型」列表页查看
methodName: 'wedaGetRecordsV2' , // 数据模型方法标识,支持的方法可以前往「数据源 - 数据模型」的任一数据模型详情页查看当前模型支持的方法
params: {
filter: {
where: {
$and : [
{
phone: { $eq : phone } ,
} ,
] ,
} ,
} ,
select: {
"$master " : true
} ,
getCount: true,
pageSize: 1 ,
pageNumber: 1
} , // 数据模型方法的入参
} ) ;
if ( result.total == 0 ) {
return {
code: ErrorCode.NOT_FOUND,
message: "用户未注册,请先注册再登录"
}
}
const worker = result.records[ 0 ]
return {
code: ErrorCode.SUCCESS,
messge: "用户登录成功" ,
workerInfo: worker
}
} catch {
return {
code: ErrorCode.SYSTEM_ERROR,
message: "系统异常,请稍后再试"
}
}
} ;
4.2 工人登录前端调用
export default async function login ( ) {
console.log( 'Hi LowCode' )
const userInfo = await $w .auth.getUserInfo( )
const phone = "151" //userInfo.phone
console.log( "phone" ,phone)
const result = await $w .cloud.callDataSource( {
dataSourceName: 'workerManagement_4a1wkuw' ,
methodName: 'login' ,
params: {
phone:phone
} , // 方法入参
} ) ;
if( result.code== = 0 ) {
$w .app.dataset.state.workData = result.workerInfo
}
}
4.3 引导页进入
export default function ( { event, data } ) {
const worker = $w .app.dataset.state.workData
if ( worker.status == = "2" ) {
$w .utils.navigateTo( {
pageId: 'u_gong_zuo_tai' , // 页面 Id
params: { key: 'value' }
} ) ;
} else if ( worker.status == = "3" ) {
$w .utils.showToast( {
title: '您的申请未通过,无法使用系统' ,
icon: 'error' ,
duration: 2000 // 2 秒
} ) ;
return
} else{
$w .utils.showToast( {
title: '请耐心等待审核' ,
icon: 'error' ,
duration: 2000 // 2 秒
} ) ;
return
}
}