- 拼多多进单 Cookie 失效即时拦截与告警修复(支持 43001 会话过期等错误识别) - 拼多多订单映射优先使用 out_sku_sn(外部商家编码)作为商品规格与工单匹配核心字段 - 新增 Chrome/Edge 浏览器扩展 (Manifest V3),支持端到端 RSA-OAEP + AES-256-GCM 信封加密自动保活 - 后台店铺管理新增插件配对面板、专属密钥管理与一键导入配置 JSON
182 lines
5.9 KiB
JavaScript
182 lines
5.9 KiB
JavaScript
/**
|
|
* Pinduoduo Cookie Sync Extension Popup Script
|
|
*/
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
const statusBadge = document.getElementById('statusBadge')
|
|
const mmsStatus = document.getElementById('mmsStatus')
|
|
const shopDisplay = document.getElementById('shopDisplay')
|
|
const lastSyncDisplay = document.getElementById('lastSyncDisplay')
|
|
const orderCountRow = document.getElementById('orderCountRow')
|
|
const orderCountDisplay = document.getElementById('orderCountDisplay')
|
|
const statusMsg = document.getElementById('statusMsg')
|
|
|
|
const btnSyncNow = document.getElementById('btnSyncNow')
|
|
const btnSaveConfig = document.getElementById('btnSaveConfig')
|
|
const btnToggleImport = document.getElementById('btnToggleImport')
|
|
const btnApplyImport = document.getElementById('btnApplyImport')
|
|
const importArea = document.getElementById('importArea')
|
|
const importJsonInput = document.getElementById('importJsonInput')
|
|
|
|
const inputServerUrl = document.getElementById('inputServerUrl')
|
|
const inputShopId = document.getElementById('inputShopId')
|
|
const inputSyncToken = document.getElementById('inputSyncToken')
|
|
|
|
function formatTime(timestamp) {
|
|
if (!timestamp) return '未同步'
|
|
const d = new Date(timestamp)
|
|
if (isNaN(d.getTime())) return '未同步'
|
|
const m = String(d.getMonth() + 1).padStart(2, '0')
|
|
const day = String(d.getDate()).padStart(2, '0')
|
|
const h = String(d.getHours()).padStart(2, '0')
|
|
const min = String(d.getMinutes()).padStart(2, '0')
|
|
const s = String(d.getSeconds()).padStart(2, '0')
|
|
return `${m}-${day} ${h}:${min}:${s}`
|
|
}
|
|
|
|
function showMsg(text, isError = false) {
|
|
statusMsg.style.display = 'block'
|
|
statusMsg.className = isError ? 'msg-box msg-error' : 'msg-box msg-success'
|
|
statusMsg.textContent = text
|
|
}
|
|
|
|
function refreshStatusView(statusData) {
|
|
const storage = statusData?.storage || {}
|
|
const hasCookie = Boolean(statusData?.hasCookie)
|
|
|
|
// 1. MMS 登录状态
|
|
if (hasCookie) {
|
|
mmsStatus.textContent = `已在线 (长度: ${statusData.cookieLength || 0})`
|
|
mmsStatus.style.color = '#15803d'
|
|
} else {
|
|
mmsStatus.textContent = '未登录 / 无有效Cookie'
|
|
mmsStatus.style.color = '#b91c1c'
|
|
}
|
|
|
|
// 2. 店铺标识
|
|
if (storage.shopId) {
|
|
shopDisplay.textContent = storage.shopId
|
|
} else {
|
|
shopDisplay.textContent = '未配置'
|
|
}
|
|
|
|
// 3. 上次同步
|
|
if (storage.lastSyncAt) {
|
|
lastSyncDisplay.textContent = formatTime(storage.lastSyncAt)
|
|
} else {
|
|
lastSyncDisplay.textContent = '从未同步'
|
|
}
|
|
|
|
// 4. 订单数
|
|
if (storage.totalOrders !== undefined) {
|
|
orderCountRow.style.display = 'flex'
|
|
orderCountDisplay.textContent = `${storage.totalOrders} 笔`
|
|
} else {
|
|
orderCountRow.style.display = 'none'
|
|
}
|
|
|
|
// 5. 顶部角标与错误消息
|
|
if (!storage.serverUrl || !storage.shopId || !storage.syncToken) {
|
|
statusBadge.className = 'badge badge-gray'
|
|
statusBadge.textContent = '待配对'
|
|
} else if (storage.lastStatus === 'ok') {
|
|
statusBadge.className = 'badge badge-ok'
|
|
statusBadge.textContent = '运行正常'
|
|
if (storage.lastMessage) {
|
|
showMsg(storage.lastMessage, false)
|
|
}
|
|
} else if (storage.lastStatus === 'error') {
|
|
statusBadge.className = 'badge badge-err'
|
|
statusBadge.textContent = '同步异常'
|
|
if (storage.lastMessage) {
|
|
showMsg(storage.lastMessage, true)
|
|
}
|
|
} else {
|
|
statusBadge.className = 'badge badge-gray'
|
|
statusBadge.textContent = '待同步'
|
|
}
|
|
|
|
// 填充输入框
|
|
inputServerUrl.value = storage.serverUrl || ''
|
|
inputShopId.value = storage.shopId || ''
|
|
inputSyncToken.value = storage.syncToken || ''
|
|
}
|
|
|
|
// 初始化加载
|
|
chrome.runtime.sendMessage({ action: 'get_status' }, (res) => {
|
|
refreshStatusView(res)
|
|
})
|
|
|
|
// 切换一键导入框
|
|
btnToggleImport.addEventListener('click', (e) => {
|
|
e.preventDefault()
|
|
if (importArea.style.display === 'none') {
|
|
importArea.style.display = 'block'
|
|
importJsonInput.focus()
|
|
} else {
|
|
importArea.style.display = 'none'
|
|
}
|
|
})
|
|
|
|
// 执行一键导入解析
|
|
btnApplyImport.addEventListener('click', () => {
|
|
const raw = importJsonInput.value.trim()
|
|
if (!raw) return
|
|
try {
|
|
const parsed = JSON.parse(raw)
|
|
if (parsed.serverUrl) inputServerUrl.value = parsed.serverUrl
|
|
if (parsed.shopId) inputShopId.value = parsed.shopId
|
|
if (parsed.syncToken) inputSyncToken.value = parsed.syncToken
|
|
importArea.style.display = 'none'
|
|
showMsg('配置解析成功,请点击下方【保存配置】生效', false)
|
|
} catch {
|
|
showMsg('JSON 格式不正确,请确保完整复制后台内容', true)
|
|
}
|
|
})
|
|
|
|
// 保存配置
|
|
btnSaveConfig.addEventListener('click', async () => {
|
|
const serverUrl = inputServerUrl.value.trim()
|
|
const shopId = inputShopId.value.trim()
|
|
const syncToken = inputSyncToken.value.trim()
|
|
|
|
if (!serverUrl || !shopId || !syncToken) {
|
|
showMsg('请完整填写服务器地址、店铺标识和配对密钥', true)
|
|
return
|
|
}
|
|
|
|
await chrome.storage.local.set({
|
|
serverUrl,
|
|
shopId,
|
|
syncToken,
|
|
})
|
|
|
|
showMsg('配置已保存!正在尝试初次加密同步...', false)
|
|
triggerSync()
|
|
})
|
|
|
|
// 手动触发同步
|
|
function triggerSync() {
|
|
btnSyncNow.disabled = true
|
|
btnSyncNow.textContent = '正在加密上传...'
|
|
|
|
chrome.runtime.sendMessage({ action: 'trigger_sync' }, (res) => {
|
|
btnSyncNow.disabled = false
|
|
btnSyncNow.textContent = '立即上传同步 Cookie'
|
|
|
|
if (res && res.success) {
|
|
showMsg(res.message || '同步成功!', false)
|
|
} else {
|
|
showMsg(res?.message || '同步失败,请检查网络或配置', true)
|
|
}
|
|
|
|
// 刷新界面
|
|
chrome.runtime.sendMessage({ action: 'get_status' }, (s) => {
|
|
refreshStatusView(s)
|
|
})
|
|
})
|
|
}
|
|
|
|
btnSyncNow.addEventListener('click', triggerSync)
|
|
})
|