// ==UserScript== // @name 京东CK获取并提交青龙_优化版 // @namespace jdck // @version 1.0.0 // @description 在前台显示美化面板,一键推送CK并提交到青龙,支持一键登出,带日志记录;支持单独复制CK // @author 超级帅气 + ChatGPT // @match https://home.m.jd.com/myJd/newhome.action* // @match https://m.jd.com/* // @grant GM_cookie // @grant GM_addValueChangeListener // @grant GM_setValue // @grant GM_getValue // @grant GM_notification // @grant GM_xmlhttpRequest // @grant GM_setClipboard // @grant GM_log // @connect jd.com // ==/UserScript== /* ==UserConfig== 青龙配置: url: title: 青龙面板地址 description: '例如: http://127.0.0.1:5700' clientId: title: clientId description: 系统设置->应用设置->client id clientSecret: title: clientSecret description: 系统设置->应用设置->client secret ==/UserConfig== */ (function () { // ----------- 前台UI部分 ----------- const panel = document.createElement('div'); panel.id = "jdck-panel"; panel.innerHTML = `

京东CK工具

`; document.body.appendChild(panel); const style = document.createElement('style'); style.innerHTML = ` #jdck-panel { position: fixed; top: 180px; left: 10px; background: #fff; border: 1px solid #ddd; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); padding: 12px; z-index: 99999; font-family: "Segoe UI", Arial, sans-serif; text-align: center; } #jdck-panel button { display: block; width: 120px; margin: 6px auto; padding: 8px 0; font-size: 13px; border: none; border-radius: 8px; cursor: pointer; transition: 0.2s; } #push-ck { background: #4CAF50; color: #fff; } #push-ck:hover { background: #45a049; } #copy-ck { background: #2196F3; color: #fff; } #copy-ck:hover { background: #0b7dda; } #logout { background: #f44336; color: #fff; } #logout:hover { background: #da190b; } `; document.head.appendChild(style); // 前台按钮绑定 panel.addEventListener('click', e => { switch (e.target.id) { case 'push-ck': GM_log("📢 用户点击了『推送CK』按钮"); GM_setValue('push-ck', null); GM_setValue('push-ck', 'request'); break; case 'copy-ck': GM_log("📢 用户点击了『复制CK』按钮"); GM_setValue('push-ck', null); GM_setValue('copy-ck', 'request'); break; case 'logout': GM_log("📢 用户点击了『一键登出』按钮"); GM_setValue('push-ck', null); GM_setValue('logout', 'true'); setTimeout(() => { location.href = 'https://m.jd.com/'; }, 1000); break; } }); // ----------- 后台逻辑部分 ----------- if (!window.GM_getCookieStore) { window.GM_getCookieStore = (_, cb) => cb(0, undefined); } function getCk(tabid) { return new Promise((resolve, reject) => { GM_getCookieStore(tabid, (storeId, err) => { if (err) return reject(err); GM_cookie('list', { domain: '.jd.com', name: "pt_key", storeId }, (item) => { if (!item.length) return reject("未找到 pt_key"); let jdCookie = "pt_key=" + item[0].value; GM_cookie('list', { domain: '.jd.com', name: "pt_pin", storeId }, (item2) => { if (!item2.length) return reject("未找到 pt_pin"); jdCookie += ";pt_pin=" + item2[0].value + ";"; GM_log("✅ 成功获取CK:" + jdCookie); resolve({ jdCookie, pt_pin: decodeURI(item2[0].value) }); }); }); }); }); } function ajax(method, url, token, data) { return new Promise((resolve, reject) => { let headers = {}; if (method !== 'get') headers['Content-Type'] = 'application/json'; if (token) headers['Authorization'] = 'Bearer ' + token; GM_xmlhttpRequest({ url, method, data: data ? JSON.stringify(data) : null, headers, responseType: "json", onload: resp => { if (resp.status === 200) { GM_log("🌐 请求成功: " + url); resolve(resp.response); } else { GM_log("❌ 请求失败: " + url + " 状态码: " + resp.status); reject(resp.response?.message || "请求失败"); } }, onerror: err => { GM_log("⚠️ 网络错误: " + url + " 错误: " + JSON.stringify(err)); reject(err); } }); }); } async function updateToken() { let url = GM_getValue('青龙配置.url'); let clientId = GM_getValue('青龙配置.clientId'); let clientSecret = GM_getValue('青龙配置.clientSecret'); GM_log("🔑 正在更新青龙 token..."); let resp = await ajax('get', `${url}/open/auth/token?client_id=${clientId}&client_secret=${clientSecret}`); GM_setValue('ql.token', resp.data.token); GM_setValue('ql.expiration', resp.data.expiration); GM_log("✅ 获取到青龙 token:" + resp.data.token); return resp.data.token; } async function setQlCk(ck, pt_pin) { GM_log("📤 正在提交CK到青龙..."); let url = GM_getValue('青龙配置.url'); if (!url) throw "未配置青龙地址"; let ckName = 'JD_COOKIE'; let token = GM_getValue('ql.token'); let expiration = GM_getValue('ql.expiration'); if (!token || expiration < Date.now() / 1000 - 1000) token = await updateToken(); try { let envs = await ajax('get', `${url}/open/envs?searchValue=${ckName}`, token); let found = envs.data.find(e => e.remarks?.startsWith(pt_pin)); if (found) { GM_log("🔄 更新已有环境变量 _id=" + found._id); await ajax('put', `${url}/open/envs`, token, { name: ckName, value: ck, remarks: pt_pin + ' by ScriptCat', _id: found._id }); await ajax('put', `${url}/open/envs/enable`, token, [found._id]); } else { GM_log("➕ 新建环境变量 JD_COOKIE"); await ajax('post', `${url}/open/envs`, token, [{ name: ckName, value: ck, remarks: pt_pin + ' by ScriptCat' }]); } GM_log("✅ CK 提交青龙成功"); } catch (e) { GM_log("❌ CK 提交青龙失败:" + JSON.stringify(e)); throw e; } } // 监听登出 GM_addValueChangeListener('logout', (_, __, val, ___, tabid) => { if (!val) return; GM_log("🧹 正在删除京东登录Cookie..."); GM_getCookieStore(tabid, (storeId, err) => { if (err) return; const cookiesToDelete = ["pt_key", "pt_pin", "pt_token", "pwdt_id", "s_key", "s_pin", "sfstoken", "sid", "thor1", "wq_skey"]; cookiesToDelete.forEach(name => { GM_cookie('delete', { url: 'https://home.m.jd.com/', name, storeId }); }); GM_log("✅ Cookie 清理完成"); }); }); // 监听推送CK(直接推送,无弹窗) GM_addValueChangeListener('push-ck', (_, __, val, ___, tabid) => { if (!val) return; getCk(tabid).then(({ jdCookie, pt_pin }) => { setQlCk(jdCookie, pt_pin).then(() => { GM_notification({ title: "京东CK工具", text: "CK 已推送到青龙 ✅" }); }).catch(e => { GM_notification({ title: "京东CK工具", text: "推送失败: " + e }); }); }).catch(() => { GM_log("❌ 获取CK失败,用户未登录"); GM_notification({ title: "京东CK工具", text: "未登录,无法获取CK ❌" }); }); }); // 监听复制CK GM_addValueChangeListener('copy-ck', (_, __, val, ___, tabid) => { if (!val) return; getCk(tabid).then(({ jdCookie }) => { GM_setClipboard(jdCookie); GM_log("📋 CK 已复制到剪贴板"); GM_notification({ title: "京东CK工具", text: "CK 已复制到剪贴板 ✅" }); }).catch(() => { GM_log("❌ 获取CK失败,用户未登录"); GM_notification({ title: "京东CK工具", text: "未登录,无法获取CK ❌" }); }); }); })();