utiller 1.0.356 → 1.0.358
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/utiller/index.js +143 -0
- package/package.json +1 -1
- package/template/sample.package.json +1 -1
package/lib/utiller/index.js
CHANGED
|
@@ -4106,6 +4106,149 @@ var Utiller = /*#__PURE__*/function () {
|
|
|
4106
4106
|
}).value() // 取出 moment 物件
|
|
4107
4107
|
.format("YYYYMMDDHHmmss"));
|
|
4108
4108
|
}
|
|
4109
|
+
|
|
4110
|
+
/** ============== 排課系統公式 開始 ============== */
|
|
4111
|
+
|
|
4112
|
+
/**
|
|
4113
|
+
* /const arrayWithDup = [
|
|
4114
|
+
* { idOfBooze: "A111", idOfVariant: "V001", period: "202508151400-202508151500" },
|
|
4115
|
+
* { idOfBooze: "B222", idOfVariant: "V002", period: "202508151600-202508151700" },
|
|
4116
|
+
* { idOfBooze: "A111", idOfVariant: "V001", period: "202508161400-202508161500" }, // 🔁 與第一筆 PK 相同
|
|
4117
|
+
* { idOfBooze: "B222", idOfVariant: "V003", period: "202508171600-202508171700" },
|
|
4118
|
+
* { idOfBooze: "A111", idOfVariant: "V004", period: "202508181400-202508181500" }
|
|
4119
|
+
*
|
|
4120
|
+
* ];
|
|
4121
|
+
* const result = getFilteredPeriods(arrayWithDup, "B222"); console.log(result);
|
|
4122
|
+
* [ "202508151400-202508151500", "202508181400-202508181500" ]
|
|
4123
|
+
* 1. 刪掉所有 idOfBooze = "B222" 的項目
|
|
4124
|
+
* 2. idOfBooze和idOfVariant為PK, 重複的只保留一組
|
|
4125
|
+
* 3. 回傳filter array,(反查出哪些課程重複會用到其他資訊)
|
|
4126
|
+
* */
|
|
4127
|
+
}, {
|
|
4128
|
+
key: "getFilteredHeraPeriods",
|
|
4129
|
+
value: function getFilteredHeraPeriods(arr, idOfCurrentBooze) {
|
|
4130
|
+
return _lodash["default"].chain(arr)
|
|
4131
|
+
// 1️⃣ 刪掉 idOfBooze 等於目標值的項目
|
|
4132
|
+
.filter(function (item) {
|
|
4133
|
+
return item.idOfBooze !== idOfCurrentBooze;
|
|
4134
|
+
})
|
|
4135
|
+
// 2️⃣ 根據 idOfBooze+idOfVariant 組成唯一鍵 僅保留一組
|
|
4136
|
+
.uniqBy(function (item) {
|
|
4137
|
+
return "".concat(item.idOfBooze, "_").concat(item.idOfVariant);
|
|
4138
|
+
})
|
|
4139
|
+
// 3️⃣ 只保留 period 欄位
|
|
4140
|
+
// .map('period')
|
|
4141
|
+
// 4️⃣ 過濾掉沒有 period 的項目(避免 undefined)
|
|
4142
|
+
// .filter(Boolean)
|
|
4143
|
+
// 5️⃣ 轉回陣列
|
|
4144
|
+
.value();
|
|
4145
|
+
}
|
|
4146
|
+
|
|
4147
|
+
/**
|
|
4148
|
+
* 檢查新任務與既有任務是否有時間衝突
|
|
4149
|
+
* @param {Object} newTask - 新任務物件,需包含 timeSlot 屬性 (格式: YYYY/MM/DD (週)|HH:mm-HH:mm)
|
|
4150
|
+
* @param {Array} existingTasks - 已安排的任務陣列,每個物件需包含 period 屬性 (格式: yyyymmddHHmm-yyyymmddHHmm)
|
|
4151
|
+
* @param {number} resourceCount - 可同時處理任務的人員/資源數量
|
|
4152
|
+
* @returns {Object} { conflict: boolean, items: Array }
|
|
4153
|
+
*/
|
|
4154
|
+
}, {
|
|
4155
|
+
key: "checkPeriodConflict",
|
|
4156
|
+
value: function checkPeriodConflict(newTask, existingTasks) {
|
|
4157
|
+
var resourceCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
4158
|
+
// 1️⃣ 解析 timeSlot 拆成日期與時間
|
|
4159
|
+
var _newTask$content$spli = newTask.content.split("|"),
|
|
4160
|
+
_newTask$content$spli2 = (0, _slicedToArray2["default"])(_newTask$content$spli, 2),
|
|
4161
|
+
datePart = _newTask$content$spli2[0],
|
|
4162
|
+
timePart = _newTask$content$spli2[1];
|
|
4163
|
+
var date = (0, _momentTimezone["default"])(datePart.split(" ")[0], "YYYY/MM/DD");
|
|
4164
|
+
var _timePart$split = timePart.split("-"),
|
|
4165
|
+
_timePart$split2 = (0, _slicedToArray2["default"])(_timePart$split, 2),
|
|
4166
|
+
startTimeStr = _timePart$split2[0],
|
|
4167
|
+
endTimeStr = _timePart$split2[1];
|
|
4168
|
+
var start = (0, _momentTimezone["default"])("".concat(date.format("YYYY/MM/DD"), " ").concat(startTimeStr), "YYYY/MM/DD HH:mm");
|
|
4169
|
+
var end = (0, _momentTimezone["default"])("".concat(date.format("YYYY/MM/DD"), " ").concat(endTimeStr), "YYYY/MM/DD HH:mm");
|
|
4170
|
+
|
|
4171
|
+
// 2️⃣ 篩選出有真實時間重疊的任務
|
|
4172
|
+
var conflictItems = _lodash["default"].filter(existingTasks, function (task) {
|
|
4173
|
+
var _task$period$split = task.period.split("-"),
|
|
4174
|
+
_task$period$split2 = (0, _slicedToArray2["default"])(_task$period$split, 2),
|
|
4175
|
+
pStartStr = _task$period$split2[0],
|
|
4176
|
+
pEndStr = _task$period$split2[1];
|
|
4177
|
+
var pStart = (0, _momentTimezone["default"])(pStartStr, "YYYYMMDDHHmm");
|
|
4178
|
+
var pEnd = (0, _momentTimezone["default"])(pEndStr, "YYYYMMDDHHmm");
|
|
4179
|
+
|
|
4180
|
+
// 判斷條件:有交集才算衝突
|
|
4181
|
+
return start.isBefore(pEnd) && end.isAfter(pStart);
|
|
4182
|
+
});
|
|
4183
|
+
|
|
4184
|
+
// 3️⃣ 根據資源數量判斷是否真的構成衝突
|
|
4185
|
+
var conflict = conflictItems.length >= resourceCount;
|
|
4186
|
+
|
|
4187
|
+
// 4️⃣ 回傳結果
|
|
4188
|
+
return {
|
|
4189
|
+
conflict: conflict,
|
|
4190
|
+
// true: 超過資源負荷
|
|
4191
|
+
items: conflictItems // 衝突的任務列表
|
|
4192
|
+
};
|
|
4193
|
+
}
|
|
4194
|
+
}, {
|
|
4195
|
+
key: "testOfConflict",
|
|
4196
|
+
value: function testOfConflict() {
|
|
4197
|
+
// ===== 測試資料 =====
|
|
4198
|
+
var newTask = {
|
|
4199
|
+
timeSlot: "2025/08/20 (三)|16:00-17:00",
|
|
4200
|
+
// 格式: YYYY/MM/DD (週)|HH:mm-HH:mm
|
|
4201
|
+
id: "JOB001",
|
|
4202
|
+
description: "安裝冷氣"
|
|
4203
|
+
};
|
|
4204
|
+
var existingTasks = [{
|
|
4205
|
+
id: "T001",
|
|
4206
|
+
period: "202508151400-202508151500"
|
|
4207
|
+
}, {
|
|
4208
|
+
id: "T002",
|
|
4209
|
+
period: "202508151600-202508151700"
|
|
4210
|
+
}, {
|
|
4211
|
+
id: "T003",
|
|
4212
|
+
period: "202508161400-202508161500"
|
|
4213
|
+
}, {
|
|
4214
|
+
id: "T004",
|
|
4215
|
+
period: "202508171600-202508171700"
|
|
4216
|
+
}, {
|
|
4217
|
+
id: "T005",
|
|
4218
|
+
period: "202508201630-202508201700"
|
|
4219
|
+
},
|
|
4220
|
+
// 衝突
|
|
4221
|
+
{
|
|
4222
|
+
id: "T006",
|
|
4223
|
+
period: "202508201645-202508201700"
|
|
4224
|
+
} // 衝突
|
|
4225
|
+
];
|
|
4226
|
+
|
|
4227
|
+
// 測試:一人資源
|
|
4228
|
+
console.log(checkPeriodConflict(newTask, existingTasks, 1));
|
|
4229
|
+
/*
|
|
4230
|
+
{
|
|
4231
|
+
conflict: true,
|
|
4232
|
+
items: [
|
|
4233
|
+
{ id: 'T005', period: '202508201630-202508201700' },
|
|
4234
|
+
{ id: 'T006', period: '202508201645-202508201700' }
|
|
4235
|
+
]
|
|
4236
|
+
}
|
|
4237
|
+
*/
|
|
4238
|
+
|
|
4239
|
+
// 測試:兩人資源
|
|
4240
|
+
console.log(checkPeriodConflict(newTask, existingTasks, 2));
|
|
4241
|
+
/*
|
|
4242
|
+
{
|
|
4243
|
+
conflict: false,
|
|
4244
|
+
items: [
|
|
4245
|
+
{ id: 'T005', period: '202508201630-202508201700' },
|
|
4246
|
+
{ id: 'T006', period: '202508201645-202508201700' }
|
|
4247
|
+
]
|
|
4248
|
+
}
|
|
4249
|
+
*/
|
|
4250
|
+
}
|
|
4251
|
+
/** ============== 排課系統公式 結束 ============== */
|
|
4109
4252
|
}]);
|
|
4110
4253
|
}();
|
|
4111
4254
|
var _default = exports["default"] = Utiller;
|
package/package.json
CHANGED