- // ==UserScript==
- // @name wmsHelper
- // @namespace http://tampermonkey.net/
- // @version 0.2.8
- // @description wms操作助手
- // @author Ziker
- // @match https://wms.yqn.com/62100/*
- // @match https://pr-wms.yqn.com/62100/*
- // @match https://qa4-wms.yqn.com/62100/*
- // @require https://code.jquery.com/jquery-3.4.1.min.js
- // @icon https://favicon.qqsuu.cn/work.yqn.com
- // @grant GM_openInTab
- // @grant unsafeWindow
- // @grant window.close
- // @grant window.focus
- // @run-at document-body
- // @noframes
- // @license AGPL License
- // ==/UserScript==
-
- window.jq = $.noConflict(true);
-
- (function (window) {
- window.pageHelper = {
- // 等待元素可见
- async waitElementVisible(visibleTag, index, fun) {
- let node = jq(visibleTag)
- if (node === null || node[index] === null || node[index] === undefined) {
- setTimeout(() => {
- pageHelper.waitElementVisible(visibleTag, index, fun)
- }, 500)
- } else {
- fun()
- }
- },
- sleep(duration) {
- return new Promise(resolve => {
- setTimeout(resolve, duration)
- })
- },
- showToast(msg, duration) {
- const oldNotify = document.querySelector(".custom-notify");
- if (oldNotify !== undefined && oldNotify !== null) {
- document.body.removeChild(oldNotify)
- }
- // 显示提示
- duration = isNaN(duration) ? 3000 : duration;
- const m = document.createElement('div');
- m.className = "custom-notify"
- m.innerHTML = msg;
- m.style.cssText = "display: flex;justify-content: center;align-items: center;width:80%; min-width:180px; " +
- "background:#000000; opacity:0.98; height:auto;min-height: 50px;font-size:25px; color:#fff; " +
- "line-height:30px; text-align:center; border-radius:4px; position:fixed; top:60%; left:10%; z-index:999999;";
- document.body.appendChild(m);
- setTimeout(function () {
- const d = 0.5;
- m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
- m.style.opacity = '0';
- setTimeout(function () {
- if (document.body.contains(m)) {
- document.body.removeChild(m)
- }
- }, d * 1000);
- }, duration);
- },
- // 模拟键盘按下
- clickUpAndDown(inputElement, keyChar) {
- let lastValue = inputElement.value;
- inputElement.value = keyChar;
- let event = new Event("input", {bubbles: true});
- // React15
- event.simulated = true;
- // React16 内部定义了descriptor拦截value,此处重置状态
- let tracker = inputElement._valueTracker;
- if (tracker) {
- tracker.setValue(lastValue);
- }
- inputElement.dispatchEvent(event);
- }
- }
- })(window);
-
-
- (function () {
- 'use strict';
- const domain = window.location.href.indexOf("qa4") >= 0 ? 'qa4-' : window.location.href.indexOf("pr-") >= 0 ? 'pr-' : '';
- jq(document).ready(function () {
- // 顶部工具栏变化
- waitObserve("#app", () => {
- if (nonNull(document.querySelector(".forkButton"))) {
- return;
- }
- const toolbar = document.querySelector(".yqn-topbar-module");
- appendFlagNode(toolbar, "forkButton")
- const firstChildNode = toolbar.childNodes[0];
- // toolbar.insertBefore(createTextButton("PDA理货", () => {
- // getCurrentRelocation(true, id => {
- // if (isNull(id)) {
- // window.pageHelper.showToast("当前登录用户在当前仓库暂无实时理货任务", 4000)
- // } else {
- // GM_openInTab("https://" + domain + "wms.yqn.com/62100/transfer-ship/detail/" + id, false)
- // }
- // })
- // }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
- //
- // toolbar.insertBefore(createTextButton("PDA移库", () => {
- // getCurrentRelocation(false, id => {
- // if (isNull(id)) {
- // window.pageHelper.showToast("当前登录用户在当前仓库暂无移库计划任务", 4000)
- // } else {
- // GM_openInTab("https://" + domain + "wms.yqn.com/62100/transfer-ship/detail/" + id, false)
- // }
- // })
- // }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
- //
- // toolbar.insertBefore(createTextButton("PDA拣货", () => {
- // getCurrentPickingOrder(id => {
- // if (isNull(id)) {
- // window.pageHelper.showToast("当前登录用户在当前仓库暂无拣货任务", 4000)
- // } else {
- // GM_openInTab("https://" + domain + "wms.yqn.com/62100/picking/detail/" + id, false)
- // }
- // })
- // }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
-
- toolbar.insertBefore(createTextButton("叉车", () => {
- getMaxForkliftCode(forkLift => {
- if (forkLift === '') {
- window.pageHelper.showToast("没找到叉车", 1000)
- } else {
- window.pageHelper.showToast(imageHtml(forkLift), 4000)
- }
- })
- }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
-
- toolbar.insertBefore(createTextButton("入库码", () => {
- getFirstContainerNo(1, containerNo => {
- if (isNull(containerNo)) {
- window.pageHelper.showToast("好像没容器了", 1000)
- } else {
- window.pageHelper.showToast(imageHtml(containerNo), 4000)
- }
- })
- }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
- toolbar.insertBefore(createTextButton("出库码", () => {
- getFirstContainerNo(2, containerNo => {
- if (isNull(containerNo)) {
- window.pageHelper.showToast("好像没容器了", 1000)
- } else {
- window.pageHelper.showToast(imageHtml(containerNo), 4000)
- }
- })
- }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
- toolbar.insertBefore(createTextButton("装车码", () => {
- getFirstContainerNo(3, containerNo => {
- if (isNull(containerNo)) {
- window.pageHelper.showToast("好像没容器了", 1000)
- } else {
- window.pageHelper.showToast(imageHtml(containerNo), 4000)
- }
- })
- }, "ant-btn ant-btn-link perf-tracked yqn-button download-record"), firstChildNode)
- })
- // 处理表格
- parseTable()
- // 监听 content 页面变动
- waitObserve(".layout-common-page", () => {
- const module = document.querySelector(".yqn-header")
- if (isNull(module)) {
- return;
- }
- // 拣货单详情页面
- if (module.textContent.indexOf("拣货单") >= 0 && module.textContent.indexOf("详情") >= 0) {
- pickingOrder()
- }
- // 移库单详情页面
- if (module.textContent.indexOf("移库单") >= 0 && module.textContent.indexOf("详情") >= 0) {
-
- }
- // 出库单详情页面
- if (module.textContent.indexOf("出库单") >= 0 && module.textContent.indexOf("详情") >= 0) {
- outboundOrder()
- }
- // 拣货单列表
- if (module.textContent.indexOf("拣货单") >= 0 && module.textContent.indexOf("详情") <= 0) {
- pickingOrderList()
- }
- // 装车单列表
- if (module.textContent.indexOf("装车单") >= 0 && module.textContent.indexOf("详情") <= 0) {
- packingOrderList()
- }
- // 验货复核
- if (module.textContent.indexOf("验货复核") >= 0) {
- inspectionGoods()
- }
- })
- })
-
- function parseTable() {
- setTimeout(() => {
- parseTable()
- tableExecute()
- }, 1500)
- }
-
- // 拣货单页面
- function pickingOrder() {
- const buttons = document.querySelector(".yqn-parser-button-list");
- if (nonNull(buttons) && isNull(document.querySelector(".custom-outbound-button"))) {
- appendFlagNode(buttons, "custom-outbound-button")
- buttons.appendChild(createButton("去复核", () => {
- const customOutCode = document.querySelector(".pop-card-c.plaintext");
- GM_openInTab("https://" + domain + "wms.yqn.com/62100/outbound-order/inspection-goods?code=" + customOutCode.textContent, false)
- }))
- }
- }
-
- // 出库单页面
- function outboundOrder() {
- const buttons = document.querySelector(".yqn-parser-button-list");
- if (nonNull(buttons) && isNull(document.querySelector(".custom-outbound-button"))) {
- appendFlagNode(buttons, "custom-outbound-button")
- queryPickingOrder(data => {
- if (nonNull(data)) {
- // 跳转拣货单按钮
- buttons.appendChild(createButton("拣货单", () => {
- const customOutCode = document.querySelector(".pop-card-c.plaintext");
- GM_openInTab("https://" + domain + "wms.yqn.com/62100/picking/list?customOutCode=" + customOutCode.textContent, false)
- }))
- // 去复核按钮
- buttons.appendChild(createButton("去复核", () => {
- GM_openInTab("https://" + domain + "wms.yqn.com/62100/outbound-order/inspection-goods?code=" + data.code, false)
- }))
- }
- })
- queryLoadingOrder(data => {
- if (nonNull(data)) {
- // 跳转装车单按钮
- buttons.appendChild(createButton("装车单", () => {
- const customOutCode = document.querySelector(".pop-card-c.plaintext");
- GM_openInTab("https://" + domain + "wms.yqn.com/62100/packing/list?customOutCode=" + customOutCode.textContent, false)
- }))
- }
- })
- }
- }
-
- // 拣货单列表
- function pickingOrderList() {
- const customOutCode = new URLSearchParams(window.location.href.split('?')[1]).get('customOutCode');
- if (isNull(customOutCode)) {
- return
- }
- // 搜索出库单号的拣货单
- const node = document.querySelector("#outboundCode");
- if (nonNull(node) && isNull(document.querySelector(".custom-input"))) {
- appendFlagNode(document.body, "custom-input")
- window.pageHelper.clickUpAndDown(node, customOutCode)
- }
- }
-
- // 装车单列表
- function packingOrderList() {
- const customOutCode = new URLSearchParams(window.location.href.split('?')[1]).get('customOutCode');
- if (isNull(customOutCode)) {
- return
- }
- // 搜索出库单号的装车单
- const node = document.querySelector("#outBoundOrderCode");
- if (nonNull(node) && isNull(document.querySelector(".custom-input"))) {
- appendFlagNode(document.body, "custom-input")
- window.pageHelper.sleep(400)
- .then(() => {
- window.pageHelper.clickUpAndDown(node, customOutCode)
- const search = document.querySelector(".yqn-filter-operation .ant-btn.ant-btn-primary.perf-tracked.yqn-button");
- search.click()
- })
- }
- }
-
- // 验货复核
- function inspectionGoods() {
- const code = new URLSearchParams(window.location.href.split('?')[1]).get('code');
- if (isNull(code)) {
- return
- }
- const node = document.querySelector("#pickContainerNo");
- if (nonNull(node) && isNull(document.querySelector(".custom-input"))) {
- appendFlagNode(document.body, "custom-input")
- window.pageHelper.clickUpAndDown(node, code)
- // 创建一个KeyboardEvent对象并设置相关属性
- const event = new KeyboardEvent('keydown', {
- key: 'Enter',
- bubbles: true,
- cancelable: true,
- keyCode: 13
- });
- // 通过目标元素触发KeyboardEvent对象
- node.dispatchEvent(event);
- }
- }
-
- // 表格处理
- function tableExecute() {
- try {
- // table 容器
- const containers = document.querySelectorAll(".ant-table-container");
- if (containers == null || containers.length === 0) {
- return
- }
- for (let i = 0; i < containers.length; i++) {
- const container = containers[i];
- const tHeader = container.querySelector(".ant-table-header")
- let keyIndexArray = []
- const ths = tHeader.querySelectorAll("th");
- for (let i = 0; i < ths.length; i++) {
- const text = ths[i].innerText.toLowerCase();
- if (text.indexOf("sku".toLowerCase()) >= 0 ||
- text.indexOf("UPC".toLowerCase()) >= 0 ||
- text.indexOf("识别码".toLowerCase()) >= 0 ||
- text.indexOf("库位".toLowerCase()) >= 0 ||
- text.indexOf("叉车编码".toLowerCase()) >= 0 ||
- text.indexOf("SN码".toLowerCase()) >= 0) {
- keyIndexArray.push(i)
- }
- }
- const tBody = container.querySelector(".ant-table-tbody")
- const lines = tBody.querySelectorAll(".ant-table-row.ant-table-row-level-0");
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i];
- let tds = line.querySelectorAll("td");
- if (tds[1].innerText.indexOf("QR") >= 0) {
- continue
- }
- let dataArray = []
- for (let i = 0; i < tds.length; i++) {
- if (keyIndexArray.indexOf(i) >= 0) {
- dataArray.push(tds[i].innerText)
- }
- }
- if (dataArray.length > 0 && tds[1].innerText.indexOf("QR") < 0) {
- tds[1].appendChild(createTextButton("QR", () => {
- window.pageHelper.showToast(imageHtml(dataArray), 7000)
- }))
- }
- }
- }
- } catch (e) {
- }
- }
-
- // 追加标记节点
- function appendFlagNode(node, flag) {
- const divFlag = document.createElement("div");
- node.appendChild(divFlag)
- divFlag.className = flag;
- divFlag.style.display = "none"
- }
-
- function imageHtml() {
- let html = "<div style=\"display: flex;margin-top: 10px;margin-bottom: 10px\">";
- if (arguments.length === 1 && arguments[0] instanceof Array) {
- console.log(1)
- for (let i = 0; i < arguments[0].length; i++) {
- html += " <img src=\"https://wwsix.cn/endpoint/v1/qrcode/create?code=" + arguments[0][i] + "&width=220&height=220&desc=1\" alt='" + arguments[0][i] + "'/>";
- if (i !== arguments[0].length - 1) {
- html += " <span style=\"width: 170px\"></span>";
- }
- }
- } else {
- for (let i = 0; i < arguments.length; i++) {
- html += " <img src=\"https://wwsix.cn/endpoint/v1/qrcode/create?code=" + arguments[i] + "&width=220&height=220&desc=1\" alt='" + arguments[i] + "'/>";
- if (i !== arguments.length - 1) {
- html += " <span style=\"width: 170px\"></span>";
- }
- }
- }
- html += "</div>";
- return html;
- }
-
- function nonNull(o) {
- return o !== null && o !== undefined;
- }
-
- function isNull(o) {
- return o === null || o === undefined;
- }
-
- // 等待出现并监听变化
- function waitObserve(visibleTag, fun, attributes = true) {
- window.pageHelper.waitElementVisible(visibleTag, 0, () => {
- new MutationObserver(function (mutationsList) {
- fun()
- }).observe(document.querySelector(visibleTag), {
- attributes: attributes,
- childList: true,
- subtree: true,
- characterData: true
- })
- })
- }
-
- // 创建文本按钮
- function createTextButton(name, listener, className = "ant-btn ant-btn-link perf-tracked yqn-button yqn-link-no-padding customer-button") {
- const button = document.createElement("button")
- button.type = "button"
- button.id = name
- button.className = className
- button.onclick = listener
- const span = document.createElement("span")
- span.textContent = name
- button.appendChild(span)
- return button;
- }
-
- // 创建按钮
- function createButton(name, listener) {
- const button = document.createElement("button")
- button.type = "button"
- button.id = name
- button.className = "ant-btn ant-btn-default perf-tracked yqn-button"
- button.onclick = listener
- const a = document.createElement("a")
- a.textContent = name
- a.className = "render-button-text"
- button.appendChild(a)
- return button;
- }
-
- // 拿一个新容器
- function getFirstContainerNo(type, fuc) {
- request('/yqn_wms/bg/container/v2/list', {
- "statusList": [1],
- "containerType": type
- }, data => {
- if (nonNull(data.content) && data.content.length > 0) {
- fuc(data.content[0].containerCode)
- } else {
- fuc(null)
- }
- })
- }
-
- // 拿一个全能叉车
- function getMaxForkliftCode(fuc) {
- request('/yqn_wms/bg/forklift/v2/list', {}, data => {
- if (nonNull(data.content) && data.content.length > 0) {
- let emptyCode = ''
- let code = ''
- let areMaxLayer = 0
- let areMaxLen = 0
- let emptyAreMaxLayer = 0;
- for (let i = 0; i < data.content.length; i++) {
- const forklift = data.content[i];
- const num = isNull(forklift.maximumLayer) ? 0 : forklift.maximumLayer;
- // 空库区
- if (isNull(forklift.warehouseAreaList) || forklift.warehouseAreaList.length === 0) {
- if (emptyAreMaxLayer <= num) {
- emptyAreMaxLayer = num;
- emptyCode = forklift.code;
- }
- } else {
- // 非空库区
- if (areMaxLen <= forklift.warehouseAreaList.length && areMaxLayer <= num) {
- areMaxLen = forklift.warehouseAreaList.length;
- areMaxLayer = num;
- code = forklift.code;
- }
- }
- }
- fuc(emptyCode.length !== 0 ? emptyCode : code)
- } else {
- fuc(null)
- }
- })
- }
-
- // 拿当前拣货单
- function getCurrentPickingOrder(fuc) {
- request('/yqn_wms/app/picking/v2/get_task', {}, data => {
- fuc(data.id)
- })
- }
-
- // 拿移库单
- function getCurrentRelocation(real, fuc) {
- request('/yqn_wms/app/relocation/v2/' + (real ? 'get_immediately' : 'get_task'), {}, data => {
- fuc(data.id)
- })
- }
-
- // 查询出库单对应拣货单
- function queryPickingOrder(fuc) {
- request('/yqn_wms/bg/picking/v2/list', {
- "outboundCode": new URLSearchParams(window.location.href.split('?')[1]).get('code'),
- }, data => {
- if (nonNull(data.content) && data.content.length > 0) {
- for (let i = 0; i < data.content.length; i++) {
- fuc(data.content[i])
- }
- } else {
- fuc(null)
- }
- })
- }
-
- // 查询出库单对应装车单
- function queryLoadingOrder(fuc) {
- request('/yqn_wms/bg/loading_order/v2/list', {
- "outBoundOrderCode": new URLSearchParams(window.location.href.split('?')[1]).get('code')
- }, data => {
- if (nonNull(data.content) && data.content.length > 0) {
- for (let i = 0; i < data.content.length; i++) {
- fuc(data.content[i])
- }
- } else {
- fuc(null)
- }
- })
- }
-
- // 发起请求
- function request(interfaceUrl, model, success) {
- const url = 'https://' + domain + 'gw-wms.yqn.com/api/40081/api/call' + interfaceUrl
- model.page = 1
- model.size = 100
- model.warehouseId = localStorage.getItem("warehouseId")
- jq.ajax({
- url: url,
- method: 'POST',
- xhrFields: {
- withCredentials: true
- },
- crossDomain: true,
- contentType: 'application/json',
- data: JSON.stringify({
- "header": {
- "xSourceAppId": "63008",
- "guid": "6f87e073-1da1-4017-b2de-c109abcd6d123",
- "lang": "zh",
- "timezone": "Asia/Shanghai"
- },
- "model": model
- }),
- success: function (response) {
- if (response.code === 200 && nonNull(response.data)) {
- success(response.data)
- }
- },
- error: function (xhr, status, error) {
- console.log('Request failed:', error);
- }
- });
- }
- })();