UNPKG

@pisell/pisellos

Version:

一个可扩展的前端模块化SDK框架,支持插件系统

861 lines (825 loc) 37.7 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } import dayjs from 'dayjs'; /** * 1. 获取资源列表 * 2. 根据当前选择的商品过滤出来对应的资源列表 getResourcesByProduct * 3. 格式化资源相关 格式化资源列表 --> 格式化资源 --> 获取时间切片列表 --> 判断单个时间切片是否可用 formatResources * */ /** * @title: 获取重叠剩余量 * @description: * @param {any} eventList * @param {number} current * @return {*} * @Author: zhiwei.Wang */ var getUseableEventCount = function getUseableEventCount(eventList, current) { return (eventList || []).reduce(function (pre, event) { return pre - event.pax; }, current || 0); }; /** * @title: 判断两个时间段是否有重叠 * @description: * @param {object} event * @param {object} current * @return {*} * @Author: zhiwei.Wang */ export var isConflict = function isConflict(event, current) { var eventStart = dayjs(event.start_at); var eventEnd = dayjs(event.end_at); var currentStart = dayjs(current.start_at); var _isBefore = currentStart.isBefore(eventEnd); var _isAfter = true; // 如果传递结束时间,则比对结束时间 if (current.end_at) { var currentEnd = dayjs(current.end_at); _isAfter = currentEnd.isAfter(eventStart); } // 检查是否有重叠 return _isBefore && _isAfter; }; /** * @title: 判断传入日期是否在当前日期之后 * @description: * @param {any} date * @param {any} today * @return {*} * @Author: zhiwei.Wang */ var checkAfterToDay = function checkAfterToDay(date) { var today = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : dayjs(); return dayjs(date).isAfter(dayjs(today)); }; /** * @title: 格式化资源, 添加自定义参数 * @description: * @param {any} resourceItem * @return {*} * @Author: zhiwei.Wang * @Date: 2024-01-09 13:40 */ var formatResource = function formatResource(resourceItem, booking) { // 当前资源 var _resourceItem = _objectSpread({}, resourceItem); // 格式化times里面的数据 _resourceItem.timeSlices = getTimeSlicesByResource({ resource: _resourceItem, duration: booking.duration, split: 10, currentDate: dayjs().format('YYYY-MM-DD') }); // 格式化label _resourceItem.labelText = _resourceItem.main_field; return _resourceItem; }; /** * @title: 判断资源容量是否可用 * @description: * @param {object} param1 * @return {*} * @Author: zhiwei.Wang */ var checkCapacity = function checkCapacity(_ref) { var event_list = _ref.event_list, timeSlice = _ref.timeSlice, resource = _ref.resource, _ref$currentCount = _ref.currentCount, currentCount = _ref$currentCount === void 0 ? 1 : _ref$currentCount; // 单个预约:如果当前资源容量不足以满足需求的容量,且当前资源是没有被占用的,返回资源不可用标记,但在外部运算会通过 reason=capacityOnly 来处理组合资源可用 // 多个预约:只需判断容量是否足够 var isMultipleBooking = resource.resourceType === 'multiple'; if (currentCount > resource.capacity && (isMultipleBooking || !isMultipleBooking && event_list.length === 0)) { return { status: false, capacity: resource.capacity, reason: 'capacityOnly' }; } var conflict = (event_list || []).filter(function (d) { return isConflict({ start_at: d.start_at, end_at: d.end_at }, { start_at: timeSlice.start_at, end_at: timeSlice.end_at }); }); // 减去重叠的总量 var conflictCount = getUseableEventCount(conflict, resource.capacity); // 同一时间段内只能进行一个预约,无论容量是否已满。 if (resource.resourceType === 'single') { // 0代表着不重叠,则满足条件 if (conflict.length === 0) { return { status: true, capacity: conflictCount }; } else { return { status: false, capacity: conflictCount }; } } else { // 当前预约量 <= 总剩余容量 if (currentCount <= conflictCount) { return { status: true, capacity: conflictCount }; } else { return { status: false, capacity: conflictCount }; } } }; /** * @title: 获取时间切片是否可用 * @description: 根据时间切片、资源、当前预约量判断时间切片是否可用 * @param {any} param1 * @return {*} * @Author: zhiwei.Wang */ export var getIsUsableByTimeItem = function getIsUsableByTimeItem(_ref2) { var _resource$combined_re; var timeSlice = _ref2.timeSlice, time = _ref2.time, resource = _ref2.resource, _ref2$currentCount = _ref2.currentCount, currentCount = _ref2$currentCount === void 0 ? 1 : _ref2$currentCount, _ref2$resourcesUseabl = _ref2.resourcesUseableMap, resourcesUseableMap = _ref2$resourcesUseabl === void 0 ? {} : _ref2$resourcesUseabl, cut_off_time = _ref2.cut_off_time; var status = { afterToDay: false, capacity: false, usable: false, remainingCapacity: 0, // 剩余容量 reason: '' }; // 最早可预约时间为 当前日期之后并且提前量之后 var earliest = dayjs(); var canBookingForOngoing = false; var _ref3 = cut_off_time || {}, unit = _ref3.unit, unit_type = _ref3.unit_type, type = _ref3.type, ongoing = _ref3.ongoing; // 允许购买已开始的活动 if (type === 'ongoing' && (ongoing === null || ongoing === void 0 ? void 0 : ongoing.type) === 'after_start') { // 如果timeSlice.start_at 小于当前时间,判断当前时间是否在如果timeSlice.start_at+ongoing.unit之间 // 即,如果现在是15:30,timeSlice.start_at是15:00,ongoing.unit是60分钟,则允许预约 if (dayjs(timeSlice.start_at).isBefore(dayjs())) { if (earliest.isBefore(dayjs(timeSlice.start_at).add(ongoing.unit, 'minute'))) { canBookingForOngoing = true; } } } else if (type === 'ongoing' && (ongoing === null || ongoing === void 0 ? void 0 : ongoing.type) === 'before_end') { if (dayjs(timeSlice.end_at).isAfter(earliest)) { canBookingForOngoing = true; } } else { if (unit) { earliest = earliest.add(unit, unit_type); } } // 不可预约提前量时间之前的 if (!checkAfterToDay(timeSlice.start_at, earliest) && !canBookingForOngoing) { return status; } status.afterToDay = true; var checkCapacityResult = checkCapacity({ event_list: time === null || time === void 0 ? void 0 : time.event_list, timeSlice: timeSlice, resource: resource, currentCount: currentCount }); if ((_resource$combined_re = resource.combined_resource) !== null && _resource$combined_re !== void 0 && _resource$combined_re.status) { // 组合资源中子资源是否可用 var resourceIds = resource.combined_resource.resource_ids; resourceIds.forEach(function (id) { // 只要有一个子资源不可用,整个组合资源都不可用 if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[id]) === false) { checkCapacityResult.status = false; } }); } status.reason = checkCapacityResult.reason || ''; if (!checkCapacityResult.status) { return status; } status.remainingCapacity = checkCapacityResult.capacity; status.capacity = true; status.usable = true; return status; }; /** * @title: 获取商品下绑定的资源列表 * @description: * @param {any} resourcesMap * @param {any} product * @return {*} * @Author: zhiwei.Wang */ export var getResourcesByProduct = function getResourcesByProduct(resourcesMap, resources, selectedResources) { var capacity = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; return (resources || []).reduce(function (acc, item) { if ((item === null || item === void 0 ? void 0 : item.status) == 1) { var form_id = item.id; // 去重 可选资源和必选资源可能会有重复的 item.optional_resource = (item.optional_resource || []).filter(function (d) { return item.default_resource.indexOf(d) == -1; }); var optional_resource = item.optional_resource.reduce(function (childAcc, d) { var _resourcesMap$d; // 如果其他资源选择过,并且这个资源是单个预约,则不可以选中此资源 // TODO: 如果容量超了这里怎么处理? var isSelectSingleResources = ((_resourcesMap$d = resourcesMap[d]) === null || _resourcesMap$d === void 0 ? void 0 : _resourcesMap$d.resourceType) === 'single' && selectedResources.includes(resourcesMap[d].id); if (resourcesMap[d] && !isSelectSingleResources) { // 拼装组合资源的数据 var combiningResources = []; if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) { resourcesMap[d].combined_resource.resource_ids.forEach(function (id) { if (resourcesMap[id]) { combiningResources.push(resourcesMap[id]); childAcc.push(Object.assign({}, resourcesMap[id], { form_id: form_id, resourceType: item.type, children: combiningResources, onlyComputed: true, // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源 metadata: _objectSpread(_objectSpread({}, resourcesMap[id].metadata), {}, { combined_resource: resourcesMap[id].combined_resource, form_name: item.title, resource_name: resourcesMap[id].main_field }) })); } }); } childAcc.push(Object.assign({}, resourcesMap[d], { form_id: form_id, resourceType: item.type, children: combiningResources, metadata: _objectSpread(_objectSpread({}, resourcesMap[d].metadata), {}, { combined_resource: resourcesMap[d].combined_resource, form_name: item.title, resource_name: resourcesMap[d].main_field }) })); } return childAcc; }, []); var default_resource = item.default_resource.reduce(function (childAcc, d) { var _resourcesMap$d2; var isSelectSingleResources = ((_resourcesMap$d2 = resourcesMap[d]) === null || _resourcesMap$d2 === void 0 ? void 0 : _resourcesMap$d2.resourceType) === 'single' && selectedResources.includes(resourcesMap[d].id); if (resourcesMap[d] && !isSelectSingleResources) { // 拼装组合资源的数据 var combiningResources = []; if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) { resourcesMap[d].combined_resource.resource_ids.forEach(function (id) { if (resourcesMap[id]) { combiningResources.push(resourcesMap[id]); childAcc.push(Object.assign({}, resourcesMap[id], { form_id: form_id, resourceType: item.type, children: combiningResources, onlyComputed: true, // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源 metadata: _objectSpread(_objectSpread({}, resourcesMap[id].metadata), {}, { combined_resource: resourcesMap[id].combined_resource, form_name: item.title, resource_name: resourcesMap[id].main_field }) })); } }); } childAcc.push(Object.assign({}, resourcesMap[d], { form_id: form_id, resourceType: item.type, is_default: 1, children: combiningResources, metadata: _objectSpread(_objectSpread({}, resourcesMap[d].metadata), {}, { combined_resource: resourcesMap[d].combined_resource, form_name: item.title, resource_name: resourcesMap[d].main_field }) })); } return childAcc; }, []); // 合并渲染 item.renderList = optional_resource.concat(default_resource); // renderList里 times 的每一项需要匹配一下当前时间,如果 times 里最小的end_at小于当前时间,则这个资源应该从 renderList 删除 item.renderList = item.renderList.filter(function (d) { var latestTime = d.times.reduce(function (latest, current) { return dayjs(current.end_at).isAfter(dayjs(latest.end_at)) ? current : latest; }, d.times[0]); // TODO,在这拉时间切片出来,如果可用 timeSlots.length > 1 才可以被选择 return dayjs(latestTime.end_at).isAfter(dayjs()); }); item.form_id = form_id; acc.push(item); } return acc; }, []); }; /** * @title: 获取资源列表 * @description: * @return {*} * @Author: zhiwei.Wang * @Date: 2024-01-09 13:38 */ export var formatResources = function formatResources(_ref4) { var booking = _ref4.booking, resources = _ref4.resources; try { var _list = _toConsumableArray(resources); var maps = {}; var _iterator = _createForOfIteratorHelper(_list), _step; try { var _loop = function _loop() { var item = _step.value; var renderListMaps = {}; item.renderList = item.renderList.map(function (d) { var res = formatResource(d, booking); renderListMaps[res.id] = res; return res; }); maps[item.form_id] = _objectSpread(_objectSpread({}, item), {}, { renderListMaps: renderListMaps }); }; for (_iterator.s(); !(_step = _iterator.n()).done;) { _loop(); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return { list: _list, maps: maps }; } catch (err) { console.log('formatResourcesErr', err); } return { list: [], maps: {} }; }; /** * @title: 获取资源的时间切片列表 * @description: * @return {*} * @Author: zhiwei.Wang */ export var getTimeSlicesByResource = function getTimeSlicesByResource(_ref5) { var resource = _ref5.resource, duration = _ref5.duration, _ref5$split = _ref5.split, split = _ref5$split === void 0 ? 10 : _ref5$split, _ref5$currentDate = _ref5.currentDate, currentDate = _ref5$currentDate === void 0 ? dayjs() : _ref5$currentDate, capacity = _ref5.capacity, _ref5$resourcesUseabl = _ref5.resourcesUseableMap, resourcesUseableMap = _ref5$resourcesUseabl === void 0 ? {} : _ref5$resourcesUseabl, cut_off_time = _ref5.cut_off_time, hasFlexibleDuration = _ref5.hasFlexibleDuration, operating_day_boundary = _ref5.operating_day_boundary, maxBlockThreshold = _ref5.maxBlockThreshold; var times = resource.times; // 存储所有时间切片 var timeSlices = []; // times 先以开始时间为准做个排序,时间早的先循环 times.sort(function (a, b) { return dayjs(a.start_at).diff(dayjs(b.start_at), 'minute'); }); // 处理每个时间范围 times.forEach(function (time) { // 创建今天的日期字符串,用于构建完整的日期时间 // const today = dayjs(currentDate).format('YYYY-MM-DD'); // 解析开始和结束时间 var startTime = dayjs("".concat(time.start_at)); var endTime = dayjs("".concat(time.end_at)); // 当前切片的开始时间 var currentStart = startTime; // 生成时间切片 while (true) { // 计算当前切片的结束时间 var currentEnd = currentStart.add(duration, 'minute'); // 如果结束时间超过了时间范围的结束时间,则停止 if (currentEnd.isAfter(endTime)) { break; } var timeSlice = { start_time: currentStart.format('HH:mm'), end_time: currentEnd.format('HH:mm'), start_at: currentStart, end_at: currentEnd }; var _status = getIsUsableByTimeItem({ timeSlice: timeSlice, time: time, resource: resource, currentCount: capacity || 1, resourcesUseableMap: resourcesUseableMap, cut_off_time: cut_off_time }); if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[resource.id]) !== false) { resourcesUseableMap[resource.id] = _status.usable; } if (_status.usable) { // 如果有hasFlexibleDuration,且timeSlice.start_at 大于等于operating_day_boundary,则不添加时间切片 var operatingBoundaryDateTime = (operating_day_boundary === null || operating_day_boundary === void 0 ? void 0 : operating_day_boundary.type) === 'start_time' ? '23:59' : operating_day_boundary === null || operating_day_boundary === void 0 ? void 0 : operating_day_boundary.time; if (hasFlexibleDuration && operating_day_boundary && timeSlice.start_time >= (operatingBoundaryDateTime || '23:59')) { break; } // 如果有配置了最低禁止购买时长,则需要判断时间切片是否在最低禁止购买时长内 // 看一下endTime和operatingBoundaryDateTime哪个早,哪个早用哪个去比较 var operatingBoundaryDateTimeObj = dayjs("".concat(endTime.format('YYYY-MM-DD'), " ").concat(operatingBoundaryDateTime)); var earlyTime = endTime.isBefore(operatingBoundaryDateTimeObj) ? endTime : operatingBoundaryDateTimeObj; if (hasFlexibleDuration && operating_day_boundary && maxBlockThreshold && timeSlice.start_at.add(maxBlockThreshold || 0, 'minutes').isAfter(earlyTime)) { break; } // 添加时间切片 09:00 ~ 10:00 09:20 ~ 10:20 09:00 ~ 10:00 09:20 ~ 10:20 11:00 ~ 12:00 11:20 ~ 12:20 timeSlices.push(_objectSpread(_objectSpread({}, timeSlice), {}, { // 这里需要补充这个时间段内是否可预约 _status: _status })); } // 移动到下一个开始时间(增加10分钟) currentStart = currentStart.add(split, 'minute'); } }); return timeSlices; }; /** * @title: 获取时间切片列表的交集 * @description: 注意: 需要将多个时间切片列表合并在一起,然后判断交集 * @param {TimeSliceItem} times 多个时间切片 * @param {number} count 交集次数, 符合此次数的会返回 * @return {*} * @Author: zhiwei.Wang */ export var getTimesIntersection = function getTimesIntersection(times, count) { var obj = times.reduce(function (acc, item) { var _key = "".concat(item.start_time, "-").concat(item.end_time); if (!acc[_key]) { acc[_key] = { item: item, count: 1 }; } else { acc[_key].count += 1; } return acc; }, {}); // 过滤出符合交集次数的 return Object.values(obj).filter(function (d) { return d.count >= count; }).map(function (d) { return d.item; }); }; /** * @title: 根据ids筛选资源列表 * @description: * @param {any} resourcesMap * @param {any} ids * @return {*} * @Author: zhiwei.Wang * @Date: 2024-09-19 20:23 */ export var getResourcesByIds = function getResourcesByIds(resourcesMap, ids) { return (ids || []).map(function (id) { return resourcesMap[id]; }); }; /** * @title: 合并子资源的时间切片至组合资源 * @description: * @param {ResourceItem[]} resources * @param {Record<string, ResourceItem>} resourcesMap * @return {*} * @Author: zhiwei.Wang */ export var mergeSubResourcesTimeSlices = function mergeSubResourcesTimeSlices(resources, resourcesMap) { return resources.forEach(function (item) { var _item$combined_resour; if ((item === null || item === void 0 || (_item$combined_resour = item.combined_resource) === null || _item$combined_resour === void 0 ? void 0 : _item$combined_resour.status) === 1) { var _item$combined_resour2; item === null || item === void 0 || (_item$combined_resour2 = item.combined_resource) === null || _item$combined_resour2 === void 0 || _item$combined_resour2.resource_ids.forEach(function (id) { var subResource = resourcesMap[id]; if (subResource) { subResource.times.forEach(function (time) { var fatherResourcesTime = item.times.find(function (n) { return n.start_at === time.start_at && n.end_at === time.end_at; }); if (fatherResourcesTime) { var _fatherResourcesTime$; (_fatherResourcesTime$ = fatherResourcesTime.event_list).push.apply(_fatherResourcesTime$, _toConsumableArray(time.event_list || [])); } }); } }); } }); }; /** * @title: 根据资源id列表获取时间切片 * @description: 传入一个技师id列表, 找出技师列表中公共的时间切片 * @param {ResourceItem} resources * @param {CartItem} cart * @return {*} * @Author: zhiwei.Wang */ export var getTimeSlicesByResources = function getTimeSlicesByResources(_ref6) { var resourceIds = _ref6.resourceIds, resourcesMap = _ref6.resourcesMap, duration = _ref6.duration, currentDate = _ref6.currentDate, split = _ref6.split, capacity = _ref6.capacity, resourcesUseableMap = _ref6.resourcesUseableMap, cut_off_time = _ref6.cut_off_time, hasFlexibleDuration = _ref6.hasFlexibleDuration, operating_day_boundary = _ref6.operating_day_boundary, maxBlockThreshold = _ref6.maxBlockThreshold; // 获取资源列表 var resources = getResourcesByIds(resourcesMap, resourceIds); mergeSubResourcesTimeSlices(resources, resourcesMap); // 资源排下序,把单个资源靠前,组合资源排在后面 resources.sort(function (a, b) { var _a$metadata, _b$metadata; var aIsCombined = ((_a$metadata = a.metadata) === null || _a$metadata === void 0 || (_a$metadata = _a$metadata.combined_resource) === null || _a$metadata === void 0 ? void 0 : _a$metadata.status) === 1; var bIsCombined = ((_b$metadata = b.metadata) === null || _b$metadata === void 0 || (_b$metadata = _b$metadata.combined_resource) === null || _b$metadata === void 0 ? void 0 : _b$metadata.status) === 1; if (aIsCombined && !bIsCombined) return 1; if (!aIsCombined && bIsCombined) return -1; return 0; }); // 获取资源列表中所有的时间切片 var timeSliceList = resources.reduce(function (acc, item) { return acc.concat(getTimeSlicesByResource({ resource: item, duration: duration, split: split, currentDate: currentDate, capacity: capacity, resourcesUseableMap: resourcesUseableMap, cut_off_time: cut_off_time, hasFlexibleDuration: hasFlexibleDuration, operating_day_boundary: operating_day_boundary, maxBlockThreshold: maxBlockThreshold })); }, []); // 获取时间切片列表的交集 var intersection = getTimesIntersection(timeSliceList, resources.length); return intersection; }; /** * @title: 获取其他人的已选资源 * @description: * @param {CartItem[]} cartItems * @param {number | string} accountId * @return {*} * @Author: jinglin.tan */ export var getOthersSelectedResources = function getOthersSelectedResources(cartItems, accountId, resourcesMap) { return cartItems.reduce(function (acc, d) { if (d.holder_id !== accountId) { var _d$_origin; if ((_d$_origin = d._origin) !== null && _d$_origin !== void 0 && _d$_origin.resources) { d._origin.resources.forEach(function (n) { // 如果是组合资源,还需要检查组合资源里子资源是否被占用过 if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) { // 如果组合资源里子资源被占用过,则这个资源不可以进待选列表了 if (n.metadata.combined_resource.resource_ids.some(function (m) { return acc.includes(m); })) { return acc; } acc.push.apply(acc, _toConsumableArray(n.metadata.combined_resource.resource_ids)); // n.metadata.combined_resource.resource_ids.forEach((m: number) => { // if (resourcesMap[m]) resourcesMap[m].capacity -= d.num || 0; // }); } else { // 如果当前选中的不是组合资源,但是是别的组合资源里的子资源,则还需要把别的组合资源也加进来 // 去 resourcesMap 里找一下 n.id 是不是别的组合资源里的子资源,是的话把别的组合资源也加进来 Object.values(resourcesMap).forEach(function (m) { if (m.combined_resource && m.combined_resource.status === 1) { if (m.combined_resource.resource_ids.includes(n.id)) { acc.push(m.id); // if (resourcesMap[m.id]) resourcesMap[m.id].capacity -= d.num || 0; } } }); } acc.push(n.id); // if (resourcesMap[n.id]) resourcesMap[n.id].capacity -= currentCapacity || 0; }); } } return acc; }, []); }; /** * @title: 获取其他购物车内商品的已选资源 * @description: * @param {CartItem[]} cartItems * @param {number | string} accountId * @return {*} * @Author: jinglin.tan */ export var getOthersCartSelectedResources = function getOthersCartSelectedResources(cartItems, cartItemId, resourcesMap) { return cartItems.reduce(function (acc, d) { if (d._id !== cartItemId) { var _d$_origin2; if ((_d$_origin2 = d._origin) !== null && _d$_origin2 !== void 0 && _d$_origin2.resources) { d._origin.resources.forEach(function (n) { // 如果是组合资源,还需要检查组合资源里子资源是否被占用过 if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) { // 如果组合资源里子资源被占用过,则这个资源不可以进待选列表了 if (n.metadata.combined_resource.resource_ids.some(function (m) { return acc.includes(m); })) { return acc; } acc.push.apply(acc, _toConsumableArray(n.metadata.combined_resource.resource_ids)); // n.metadata.combined_resource.resource_ids.forEach((m: number) => { // resourcesMap[m].capacity -= n.num; // }); } else { // 如果当前选中的不是组合资源,但是是别的组合资源里的子资源,则还需要把别的组合资源也加进来 // 去 resourcesMap 里找一下 n.id 是不是别的组合资源里的子资源,是的话把别的组合资源也加进来 Object.values(resourcesMap).forEach(function (m) { if (m.combined_resource && m.combined_resource.status === 1) { if (m.combined_resource.resource_ids.includes(n.id)) { acc.push(m.id); // resourcesMap[m.id].capacity -= n.num; } } }); } acc.push(n.id); // push 完以后,把 resourceMap 的 capacity 减掉当前的商品数量 // resourcesMap[n.id].capacity -= currentCapacity || 0; }); } } return acc; }, []); }; /** * @title: 根据日期范围过滤日程 * * @export * @param {any[]} schedule * @param {string} startDate * @param {string} endDate * @return {*} */ export function filterScheduleByDateRange(schedule, startDate, endDate) { if (!(schedule !== null && schedule !== void 0 && schedule.length)) return []; var start = new Date(startDate); var end = new Date(endDate); return schedule.filter(function (item) { var itemDate = new Date(item.date); return itemDate >= start && itemDate <= end; }); } /** * 传入商品数据,返回基于商品配置的提前量的最早开始日期和最晚结束日期 * * @export * @param {ProductData} product * @return {*} */ export function checkSessionProductLeadTime(product) { var latestStartDate = ''; // 最晚开始日期 var earliestEndDate = ''; // 最早结束日期 var _product$cut_off_time = product.cut_off_time, future_day = _product$cut_off_time.future_day, unit = _product$cut_off_time.unit, unit_type = _product$cut_off_time.unit_type; // 预定天数存在,则开始计算从当前时间开始往后推预定天数作为结束时间 if (future_day) { var endDate = dayjs().add(future_day, 'day'); if (!earliestEndDate || endDate.isBefore(dayjs(earliestEndDate), 'day')) { earliestEndDate = endDate.format('YYYY-MM-DD'); } } else if (future_day === 0) { var _endDate = dayjs(); if (!earliestEndDate || _endDate.isBefore(dayjs(earliestEndDate), 'day')) { earliestEndDate = _endDate.format('YYYY-MM-DD'); } } // 如果存在提前预约时间,则开始计算从当前时间开始往后推提前预约时间作为开始时间 if (unit && unit_type) { var startDate = dayjs(dayjs().add(unit, unit_type).format('YYYY-MM-DD')); if (!latestStartDate || startDate.isAfter(dayjs(latestStartDate), 'day')) { latestStartDate = startDate.format('YYYY-MM-DD'); } } return { latestStartDate: latestStartDate, earliestEndDate: earliestEndDate }; } /** * 基于商品的 resources 配置,返回可选择的资源的 id 列表 * * @export * @param {ProductData} product * @return {*} */ export function getResourcesIdsByProduct(product) { var _product$product_reso, _product$product_reso2; var tempResourceIds = []; product === null || product === void 0 || (_product$product_reso = product.product_resource) === null || _product$product_reso === void 0 || (_product$product_reso = _product$product_reso.resources) === null || _product$product_reso === void 0 || (_product$product_reso2 = _product$product_reso.forEach) === null || _product$product_reso2 === void 0 || _product$product_reso2.call(_product$product_reso, function (resource) { if ((resource === null || resource === void 0 ? void 0 : resource.status) == 1) { var _resource$default_res, _resource$optional_re; if (resource !== null && resource !== void 0 && (_resource$default_res = resource.default_resource) !== null && _resource$default_res !== void 0 && _resource$default_res.length) { tempResourceIds.push.apply(tempResourceIds, _toConsumableArray(resource === null || resource === void 0 ? void 0 : resource.default_resource)); } else if (resource !== null && resource !== void 0 && (_resource$optional_re = resource.optional_resource) !== null && _resource$optional_re !== void 0 && _resource$optional_re.length) { tempResourceIds.push.apply(tempResourceIds, _toConsumableArray(resource === null || resource === void 0 ? void 0 : resource.optional_resource)); } } }); return tempResourceIds; } /** * 资源排序,把单个资源靠前,组合资源排在后面 * * @export * @param {ResourceItem[]} resourcesList * @return {*} */ export function sortCombinedResources(resourcesList) { var newResourcesList = _toConsumableArray(resourcesList); newResourcesList.sort(function (a, b) { var _a$metadata2, _b$metadata2; var aIsCombined = ((_a$metadata2 = a.metadata) === null || _a$metadata2 === void 0 || (_a$metadata2 = _a$metadata2.combined_resource) === null || _a$metadata2 === void 0 ? void 0 : _a$metadata2.status) === 1; var bIsCombined = ((_b$metadata2 = b.metadata) === null || _b$metadata2 === void 0 || (_b$metadata2 = _b$metadata2.combined_resource) === null || _b$metadata2 === void 0 ? void 0 : _b$metadata2.status) === 1; return aIsCombined === bIsCombined ? 0 : aIsCombined ? 1 : -1; }); return newResourcesList; } /** * 传入一个资源组,根据 formid筛出相同类型的资源 * * @export * @param {ResourceItem[]} resources * @param {string} form_id * @return {*} */ export function filterResourcesByFormItem(resources, form_id) { return resources.filter(function (n) { return n.form_id === form_id; }); } /** * 传入两个资源,确认这两个资源是否有交集(包括组合资源) * * @export * @param {ResourceItem} resource1 * @param {ResourceItem} resource2 * @return {*} */ export function checkTwoResourcesIntersection(resource1, resource2) { var _resource1$metadata$c, _resource2$metadata$c; // 检查主资源ID是否匹配 if (resource1.id === resource2.id) return true; // 检查组合资源的情况 if (((_resource1$metadata$c = resource1.metadata.combined_resource) === null || _resource1$metadata$c === void 0 ? void 0 : _resource1$metadata$c.status) === 1 && ( // 如果现在选择的是组合资源,需要判断 // 1、当前其他购物车里是否选了当前组合资源的子资源 // 2、如果其他购物车里的商品也是组合资源,出了组合资源本身的 id 需要判断,还需要判断子资源的 id 是否有交集 resource1.metadata.combined_resource.resource_ids.includes(resource2.id) || resource1.metadata.combined_resource.resource_ids.some(function (n) { return resource2.metadata.combined_resource.resource_ids.includes(n); }))) return true; if (((_resource2$metadata$c = resource2.metadata.combined_resource) === null || _resource2$metadata$c === void 0 ? void 0 : _resource2$metadata$c.status) === 1 && resource2.metadata.combined_resource.resource_ids.includes(resource2.id)) return true; }