У меня мое приложение структурировано, как показано ниже,
Routes -> Controllers -> Services
Таким образом, для /bookings
есть BookingController
и BookingService
Роль контроллера — принимать запрос и распределять задачи между одной или несколькими службами.
Теперь давайте посмотрим на код ниже.
BookingService.js
const {
Customer,
CustomerB2c,
} = require('config');
const models = require('../models');
const NewOrderService = require('./NewOrderService');
const AuthService = require('./AuthService');
const TaxAndDiscountService = require('./TaxAndDiscountCalculationService');
const CartService = require('./CartService');
const RequestService = require('./RequestService');
const LocationService = require('./LocationService');
module.exports = async (users) => {
const promises = users.map((user) => models.sequelize.transaction(async
let userId;
let cartValue;
const notes = {};
const existingUser = await AuthService.isUserExist({ mobile: user.mobile });
if (!existingUser) {
const loginData = await models.Login.create({
mobile: user.mobile,
email: user.email,
is_blocked: false,
username: user.customer_name,
user_role_id: Customer,
user_type_id: CustomerB2c,
}, { transaction: t });
const userData = await models.UserDetail.create({
Wallet: {
coin_balance: 0,
},
first_name: user.customer_name,
login_id: loginData.id,
city_id: user.city_id,
}, {
include: [models.Wallet],
}, { transaction: t });
userId = userData.id;
} else {
userId = existingUser.user_id;
}
const locations = await LocationService.doGetSuggestedLocations({
currentLat: user.lat,
currentLng: user.lng,
});
const address = await models.UserAddress.create({
...user.address,
user_id: userId,
location_id: locations[0].id,
}, { transaction: t });
const vehicle = await models.UserVehicle.create({
is_default: true,
user_id: userId,
vehicle_id: user.master_vehicle_id,
registration_number: user.reg_num,
});
const { cartId } = CartService.getUserCart({ userId });
CartService.addItemToCart({
itemId: user.item_id,
cartId,
itemQuantity: 1,
});
const cartItems = await NewOrderService.doGetCartItemsByUserId(userId);
if (user.coupon_code) {
const userCartValue = await NewOrderService.doApplyCoupon({
userId,
zoneId: locations[0].zoneId,
slotId: user.slot_id,
cartItems,
couponCode: user.coupon_code,
});
cartValue = userCartValue;
notes.couponCode = user.coupon_code;
notes.couponDiscount = cartValue.coupon_discount;
} else {
cartValue = TaxAndDiscountService.calculateCartValue(cartItems);
}
const item = await models.Item.findOne({
where: {
item_id: user.item_id,
},
include: {
model: models.Service,
attributes: ['id'],
},
attributes: ['id'],
});
const services = [{
service_id: item.Service.id,
slot_id: user.slot_id,
vehicle_id: vehicle.id,
booking_date: user.booking_date,
customer_address_id: address.id,
}];
const order = await NewOrderService.doCreateBookingOrder({
notes,
userId,
services,
cartItems,
cartValue,
transaction: t,
});
const bookings = await RequestService.doCreateServiceRequest({
userId,
transaction: t,
orderId: order.id,
requestedServices: services,
});
order.bookings = bookings;
NewOrderService.doSendBookingNotification({
userId,
orderId: order.id,
bookingId: order.bookings[0].id,
});
return order;
}));
return Promise.all(promises);
};
Код создает users
оптом также создает свои wallet
, vehicle
, address
и наконец order
.
Здесь много чего происходит.
Я всегда прихожу в такую ситуацию, и я расстраиваюсь и чувствую себя так плохо из-за кода. Понятия не имею, как его реорганизовать.
Но у меня есть некоторые мысли:
Создавайте отдельные функции вроде bulkCreateUserWithWallet
, createUserVehicle
и createUserAddress
и так далее, и вместо этого используйте эти функции.
Но все же эти функции будут использоваться только один раз, они мне больше нигде не нужны, потому что здесь им может потребоваться меньше аргументов, а в некоторых других местах мне нужно вставить больше данных в поле адреса таблицы i.ie.
Кроме того, они должны быть в одной транзакции.
Я также подумал об использовании шаблона репозитория, поэтому между сервисами и моделями у меня будет еще один уровень под названием Repository.
Но я не знаю, как это реализовать, используя sequelize
.
Я также знаком с такими шаблонами, как функции высшего порядка и чистые функции. Могу я как-нибудь использовать их здесь?
Наконец просьба, пожалуйста, не закрывайте его! Я готов терпеть отрицательные голоса без проблем.
Я не знаю, где еще задать этот вопрос.