feat: 新增饿了么自动出餐
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
8729c4d6e6
commit
f73c0cca17
187
ele/auto-meal-complete.user.js
Normal file
187
ele/auto-meal-complete.user.js
Normal file
@ -0,0 +1,187 @@
|
||||
// ==UserScript==
|
||||
// @name 饿了么自动出餐
|
||||
// @namespace https://circlecloud.ltd/
|
||||
// @version 0.1
|
||||
// @description 自动出餐
|
||||
// @author MiaoWoo
|
||||
// @match https://melody.shop.ele.me/app/shop/**/order__processing
|
||||
// @icon https://www.google.com/s2/favicons?sz=64&domain=ele.me
|
||||
// @updateURL https://git.yumc.pw/502647092/UserScript/raw/branch/master/ele/auto-meal-complete.user.js
|
||||
// @downloadURL https://git.yumc.pw/502647092/UserScript/raw/branch/master/ele/auto-meal-complete.user.js
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
function generateRandomString(length) {
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
var result = '';
|
||||
var charactersLength = characters.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function getRequestId() {
|
||||
return generateRandomString(32) + "|" + Date.now()
|
||||
}
|
||||
function convertSecondsToMinutesSeconds(seconds) {
|
||||
var minutes = Math.floor(seconds / 60);
|
||||
var remainingSeconds = seconds % 60;
|
||||
return minutes + "分" + remainingSeconds + "秒";
|
||||
}
|
||||
function getShopId() {
|
||||
return parseInt(localStorage.shopId)
|
||||
}
|
||||
function getShopMeta() {
|
||||
return {
|
||||
"appVersion": "1.0.0",
|
||||
"appName": "melody",
|
||||
"ksid": localStorage.ksid,
|
||||
"shopId": getShopId()
|
||||
}
|
||||
}
|
||||
function request(service, method, params) {
|
||||
let payload = {
|
||||
"service": service,
|
||||
"method": method,
|
||||
"params": params,
|
||||
"id": getRequestId(),
|
||||
"metas": getShopMeta(),
|
||||
"ncp": "2.0.0"
|
||||
}
|
||||
return fetch("https://app-api.shop.ele.me/fulfill/weborder/" + method + "/?method=" + service + "." + method, {
|
||||
"headers": {
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"sec-ch-ua": "\"Microsoft Edge\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"",
|
||||
"sec-ch-ua-platform": "\"Windows\"",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-site": "same-site",
|
||||
"x-eleme-requestid": payload.id,
|
||||
"x-shard": "shopid=" + payload.metas.shopId
|
||||
},
|
||||
"referrer": "https://napos-order-pc.faas.ele.me/",
|
||||
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||
"body": JSON.stringify(payload),
|
||||
"method": "POST",
|
||||
"mode": "cors",
|
||||
"credentials": "omit"
|
||||
}).then(r => r.json())
|
||||
}
|
||||
|
||||
function queryInProcessOrders() {
|
||||
return request('OrderWebService', 'queryInProcessOrders', {
|
||||
"shopId": getShopId(),
|
||||
"queryType": "ALL",
|
||||
// "queryType": "COOKING"
|
||||
})
|
||||
}
|
||||
async function mealComplete(orderId, cookTime) {
|
||||
let result = await request('ShipmentService', 'mealComplete', {
|
||||
"shopId": getShopId(),
|
||||
"orderId": orderId
|
||||
})
|
||||
debug('订单 ' + orderId + ' 上报出餐结束.')
|
||||
ele.submitOrders.push({ orderId, cookTime })
|
||||
if (ele.submitOrders.length > ele.maxLogOrderLength)
|
||||
ele.submitOrders = ele.submitOrders.slice(ele.submitOrders.length - ele.maxLogOrderLength)
|
||||
await updateOrders()
|
||||
return result
|
||||
}
|
||||
async function checkCooking() {
|
||||
if (!ele.processOrders) return
|
||||
for (const cook of ele.processOrders) {
|
||||
let orderId = cook.id
|
||||
if (!cook.mealPreparationInfo || cook.mealPreparationInfo.mealComplete) continue
|
||||
// 骑手到店 并且大于最小上报时长 直接上报出餐
|
||||
let cookTime = (Date.now() - new Date(cook.activeTime).getTime()) / 1000
|
||||
let leftTime = cook.mealPreparationInfo.commonShowTime
|
||||
if (cook.deliveryInfo.distTraceView.traceView.status == '骑士已到店'
|
||||
&& cook.mealPreparationInfo.minMealCompleteTimeCount < 0
|
||||
&& leftTime < ele.autoSubmitLeftTimeWhenOnShop) {
|
||||
debug('订单 ' + orderId + ' 骑手到店 且剩余时间 ' + leftTime + 's 小于 ' + ele.autoSubmitLeftTimeWhenOnShop + 's 模拟提交出餐.')
|
||||
return mealComplete(orderId, cookTime)
|
||||
}
|
||||
if (leftTime < ele.autoSubmitLeftTime) {
|
||||
// 大于最小上报时长 并且距离上报超时不足120秒 直接上报出餐
|
||||
debug('订单 ' + orderId + ' 骑手未到店 且剩余时间 ' + leftTime + 's 小于 ' + ele.autoSubmitLeftTimeWhenOnShop + 's 模拟提交出餐.')
|
||||
return mealComplete(orderId, cookTime)
|
||||
}
|
||||
debug('订单 ' + orderId + ' 还剩 ' + cook.mealPreparationInfo.commonShowTime + 's 上报超时.')
|
||||
cook.mealPreparationInfo.minMealCompleteTimeCount -= 5
|
||||
cook.mealPreparationInfo.commonShowTime -= 5
|
||||
}
|
||||
}
|
||||
async function updateOrders() {
|
||||
let orders = await queryInProcessOrders()
|
||||
ele.autoCheckTime = Date.now() / 1000
|
||||
ele.processOrders = orders.result || []
|
||||
debug('更新订单数据 目前进行中订单: ' + ele.processOrders.length + '个')
|
||||
}
|
||||
function debug(msg) {
|
||||
try {
|
||||
ele.logs.push('[' + (new Date().toLocaleTimeString()) + '] ' + msg)
|
||||
if (ele.logs.length > ele.maxLogLength)
|
||||
ele.logs = ele.logs.slice(ele.logs.length - ele.maxLogLength)
|
||||
let title = '饿了么自动出餐 By MiaoWoo </br>'
|
||||
let configInfo = '当前配置: </br><div class="ant-alert-content">'
|
||||
+ '骑手到店 提前 ' + ele.autoSubmitLeftTimeWhenOnShop + 's 出餐 '
|
||||
+ '骑手未到店 提前 ' + ele.autoSubmitLeftTime + 's 出餐</br>'
|
||||
+ '</div>'
|
||||
let submitInfo = '已自动出餐的订单信息: </br><div class="ant-alert-content">'
|
||||
+ (ele.submitOrders.length
|
||||
? ele.submitOrders.map(o => '订单: ' + o.orderId + ' 出餐用时 ' + convertSecondsToMinutesSeconds(o.cookTime)).join('</br>')
|
||||
: '当前没有自动出餐的订单.')
|
||||
+ '</div>'
|
||||
let orderInfo = '进行中的订单信息: </br><div class="ant-alert-content">'
|
||||
+ (ele.processOrders.length
|
||||
? ele.processOrders.map(o => '订单: ' + o.id + ' 出餐状态 ' + (o.mealPreparationInfo.mealComplete ? '已出餐' : '未出餐') + ' 配送状态 ' + o.deliveryInfo.distTraceView.traceView.status).join('</br>')
|
||||
: '当前没有进行中的订单.')
|
||||
+ '</div>'
|
||||
let logs = '运行日志: </br><div class="ant-alert-content">'
|
||||
+ ele.logs.join('</br>')
|
||||
+ '</div>'
|
||||
window.appContainerNoticeBar.innerHTML = '<div style="flex: 1 1 0%;">'
|
||||
+ title + '</br>'
|
||||
+ configInfo + '</br>'
|
||||
+ submitInfo + '</br>'
|
||||
+ orderInfo + '</br>'
|
||||
+ '</div>'
|
||||
+ '<div style="flex: 1 1 0%;">'
|
||||
+ logs
|
||||
+ '</div>'
|
||||
} catch (error) {
|
||||
console.log(msg)
|
||||
}
|
||||
}
|
||||
async function main() {
|
||||
setTimeout(() => {
|
||||
window.appContainerNoticeBar = document.getElementById('app-container-notice-bar')
|
||||
window.appContainerNoticeBar.style.marginLeft = '35px'
|
||||
window.appContainerNoticeBar.style.marginTop = '20px'
|
||||
window.appContainerNoticeBar.style.display = 'flex'
|
||||
updateOrders()
|
||||
}, 5000)
|
||||
setInterval(() => { checkCooking() }, 5000)
|
||||
setInterval(() => { updateOrders() }, 30000)
|
||||
}
|
||||
var ele = {
|
||||
logs: [],
|
||||
maxLogLength: 15,
|
||||
maxLogOrderLength: 5,
|
||||
orderStatus: {},
|
||||
processOrders: [],
|
||||
submitOrders: [],
|
||||
autoCheckTask: undefined,
|
||||
autoSubmitLeftTime: 180,
|
||||
autoSubmitLeftTimeWhenOnShop: 300,
|
||||
debug: debug,
|
||||
updateOrders: updateOrders,
|
||||
checkCooking: checkCooking,
|
||||
mealComplete: mealComplete,
|
||||
}
|
||||
window.ele = ele
|
||||
main()
|
||||
})();
|
Loading…
Reference in New Issue
Block a user