281 lines
9.1 KiB
JavaScript
Executable File
281 lines
9.1 KiB
JavaScript
Executable File
/**
|
|
* 打印插件客户端 - 模拟版本
|
|
*
|
|
* 功能:
|
|
* 1. 注册到ERP系统
|
|
* 2. 发送心跳
|
|
* 3. 获取打印任务
|
|
* 4. 模拟打印
|
|
*
|
|
* 使用方法:
|
|
* node print-plugin-client.js <命令> [参数]
|
|
*
|
|
* 示例:
|
|
* node print-plugin-client.js register cainiao
|
|
* node print-plugin-client.js heartbeat
|
|
* node print-plugin-client.js getjob
|
|
*/
|
|
|
|
const http = require('http');
|
|
|
|
// 配置
|
|
const CONFIG = {
|
|
API_BASE: 'http://localhost:10088/api', // 后端API地址
|
|
DEVICE_ID: 'PLUGIN-' + Date.now().toString(36).toUpperCase(),
|
|
DEVICE_NAME: process.env.COMPUTERNAME || 'Unknown-PC',
|
|
OS_VERSION: process.release.name + ' ' + process.platform,
|
|
POLL_INTERVAL: 5000, // 5秒轮询一次
|
|
};
|
|
|
|
// 模拟插件信息
|
|
const PLUGIN_INFO = {
|
|
cainiao: { code: 'cainiao', name: '菜鸟打印插件', version: '2.5.8' },
|
|
pdd: { code: 'pdd', name: '拼多多打印插件', version: '1.8.3' },
|
|
douyin: { code: 'douyin', name: '抖音小店打印插件', version: '3.2.1' },
|
|
kuaishou: { code: 'kuaishou', name: '快手小店打印插件', version: '2.1.5' },
|
|
};
|
|
|
|
// API请求封装
|
|
function apiRequest(method, path, data = null) {
|
|
return new Promise((resolve, reject) => {
|
|
const url = new URL(path, CONFIG.API_BASE);
|
|
const options = {
|
|
hostname: url.hostname,
|
|
port: url.port || 80,
|
|
path: url.pathname + url.search,
|
|
method: method,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
}
|
|
};
|
|
|
|
const req = http.request(options, (res) => {
|
|
let body = '';
|
|
res.on('data', chunk => body += chunk);
|
|
res.on('end', () => {
|
|
try {
|
|
resolve(JSON.parse(body));
|
|
} catch {
|
|
resolve(body);
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on('error', (err) => {
|
|
// API不可用时返回模拟数据
|
|
resolve({ code: 200, data: getMockResponse(method, path, data) });
|
|
});
|
|
|
|
if (data) {
|
|
req.write(JSON.stringify(data));
|
|
}
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
// 模拟API响应
|
|
function getMockResponse(method, path, data) {
|
|
if (path.includes('/heartbeat')) {
|
|
return { success: true };
|
|
}
|
|
if (path.includes('/register')) {
|
|
return {
|
|
success: true,
|
|
installation_id: Date.now(),
|
|
has_update: false,
|
|
latest_version: '2.5.8'
|
|
};
|
|
}
|
|
if (path.includes('/next-job')) {
|
|
// 模拟返回打印任务
|
|
return {
|
|
id: Math.floor(Math.random() * 1000),
|
|
job_no: 'PJ' + Date.now().toString().slice(-10),
|
|
platform: 'pdd',
|
|
plugin_code: 'pdd',
|
|
print_data: {
|
|
receiverName: '张三',
|
|
receiverPhone: '138****8000',
|
|
receiverAddress: '北京市朝阳区某某街道某某小区',
|
|
expressNo: 'SF' + Math.random().toString().slice(2, 14),
|
|
goodsName: '商品测试',
|
|
quantity: 1,
|
|
},
|
|
status: 'pending',
|
|
priority: 0,
|
|
};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
// 打印任务到控制台
|
|
function printJob(job) {
|
|
console.log('\n╔══════════════════════════════════════════════╗');
|
|
console.log('║ 🎯 收到打印任务 ║');
|
|
console.log('╠══════════════════════════════════════════════╣');
|
|
console.log(`║ 任务编号: ${job.job_no.padEnd(30)}║`);
|
|
console.log(`║ 平台: ${job.platform.padEnd(36)}║`);
|
|
console.log(`║ 收件人: ${(job.print_data?.receiverName || '-').padEnd(34)}║`);
|
|
console.log(`║ 电话: ${(job.print_data?.receiverPhone || '-').padEnd(35)}║`);
|
|
console.log(`║ 地址: ${(job.print_data?.receiverAddress || '-').substring(0, 30).padEnd(30)}║`);
|
|
console.log(`║ 快递单号: ${(job.print_data?.expressNo || '-').padEnd(31)}║`);
|
|
console.log('╠══════════════════════════════════════════════╣');
|
|
console.log('║ 📄 正在模拟打印... ║');
|
|
|
|
return new Promise((resolve) => {
|
|
setTimeout(() => {
|
|
console.log('║ ✅ 打印完成! ║');
|
|
console.log('╚══════════════════════════════════════════════╝\n');
|
|
resolve(true);
|
|
}, 1500);
|
|
});
|
|
}
|
|
|
|
// 命令处理
|
|
async function handleCommand(cmd, args) {
|
|
switch (cmd) {
|
|
case 'register':
|
|
await registerPlugin(args[0] || 'cainiao');
|
|
break;
|
|
case 'heartbeat':
|
|
await sendHeartbeat();
|
|
break;
|
|
case 'getjob':
|
|
await getNextJob();
|
|
break;
|
|
case 'daemon':
|
|
await runDaemon(args[0] || 'cainiao');
|
|
break;
|
|
case 'info':
|
|
showInfo();
|
|
break;
|
|
default:
|
|
showHelp();
|
|
}
|
|
}
|
|
|
|
// 注册插件
|
|
async function registerPlugin(pluginCode) {
|
|
const plugin = PLUGIN_INFO[pluginCode] || PLUGIN_INFO.cainiao;
|
|
|
|
console.log(`\n📦 正在注册 ${plugin.name}...`);
|
|
console.log(` 设备ID: ${CONFIG.DEVICE_ID}`);
|
|
console.log(` 设备名称: ${CONFIG.DEVICE_NAME}`);
|
|
console.log(` 插件版本: ${plugin.version}`);
|
|
|
|
const result = await apiRequest('POST', '/print-plugins/auth/register', {
|
|
plugin_code: plugin.code,
|
|
version: plugin.version,
|
|
device_id: CONFIG.DEVICE_ID,
|
|
device_name: CONFIG.DEVICE_NAME,
|
|
os_version: CONFIG.OS_VERSION,
|
|
});
|
|
|
|
if (result.success || result.code === 200) {
|
|
console.log('✅ 注册成功!');
|
|
console.log(` 安装ID: ${result.installation_id}`);
|
|
if (result.has_update) {
|
|
console.log(` ⚠️ 有新版本: ${result.latest_version}`);
|
|
}
|
|
} else {
|
|
console.log('❌ 注册失败:', result.message || '未知错误');
|
|
}
|
|
}
|
|
|
|
// 发送心跳
|
|
async function sendHeartbeat() {
|
|
const result = await apiRequest('POST', '/print-plugins/auth/heartbeat', {
|
|
device_id: CONFIG.DEVICE_ID,
|
|
});
|
|
|
|
if (result.success || result.code === 200) {
|
|
console.log('💓 心跳发送成功');
|
|
} else {
|
|
console.log('❌ 心跳失败');
|
|
}
|
|
}
|
|
|
|
// 获取打印任务
|
|
async function getNextJob() {
|
|
const result = await apiRequest('GET', `/print-device/next-job?device_id=${CONFIG.DEVICE_ID}`);
|
|
|
|
if (result && result.id) {
|
|
await printJob(result);
|
|
|
|
// 标记完成
|
|
await apiRequest('POST', '/print-device/complete', {
|
|
job_id: result.id,
|
|
device_id: CONFIG.DEVICE_ID,
|
|
});
|
|
} else {
|
|
console.log('📭 暂无打印任务');
|
|
}
|
|
}
|
|
|
|
// 运行守护进程
|
|
async function runDaemon(pluginCode) {
|
|
const plugin = PLUGIN_INFO[pluginCode] || PLUGIN_INFO.cainiao;
|
|
|
|
console.log('\n🚀 启动打印插件守护进程...');
|
|
console.log(` 插件: ${plugin.name}`);
|
|
console.log(` 轮询间隔: ${CONFIG.POLL_INTERVAL / 1000}秒`);
|
|
console.log(' 按 Ctrl+C 停止\n');
|
|
|
|
// 先注册
|
|
await registerPlugin(pluginCode);
|
|
|
|
// 启动心跳
|
|
setInterval(async () => {
|
|
await sendHeartbeat();
|
|
}, 30000);
|
|
|
|
// 轮询打印任务
|
|
setInterval(async () => {
|
|
await getNextJob();
|
|
}, CONFIG.POLL_INTERVAL);
|
|
}
|
|
|
|
// 显示信息
|
|
function showInfo() {
|
|
console.log('\n📋 插件客户端信息');
|
|
console.log('═══════════════════════════════');
|
|
console.log(` 设备ID: ${CONFIG.DEVICE_ID}`);
|
|
console.log(` 设备名称: ${CONFIG.DEVICE_NAME}`);
|
|
console.log(` 操作系统: ${CONFIG.OS_VERSION}`);
|
|
console.log(` API地址: ${CONFIG.API_BASE}`);
|
|
console.log(` 轮询间隔: ${CONFIG.POLL_INTERVAL / 1000}秒`);
|
|
console.log('═══════════════════════════════════════\n');
|
|
}
|
|
|
|
// 帮助
|
|
function showHelp() {
|
|
console.log(`
|
|
🔌 打印插件客户端 - 使用说明
|
|
|
|
用法: node print-plugin-client.js <命令> [参数]
|
|
|
|
命令:
|
|
register <插件> 注册插件 (cainiao|pdd|douyin|kuaishou)
|
|
heartbeat 发送心跳
|
|
getjob 获取一个打印任务
|
|
daemon <插件> 运行守护进程模式
|
|
info 显示客户端信息
|
|
help 显示帮助
|
|
|
|
示例:
|
|
node print-plugin-client.js register cainiao
|
|
node print-plugin-client.js daemon pdd
|
|
node print-plugin-client.js info
|
|
|
|
注意:
|
|
- 默认API地址为 http://localhost:10088/api
|
|
- 如需修改,请编辑 CONFIG.API_BASE
|
|
- 守护进程模式会自动注册并每30秒发送心跳
|
|
`);
|
|
}
|
|
|
|
// 主入口
|
|
const [,, cmd, ...args] = process.argv;
|
|
handleCommand(cmd, args).catch(console.error);
|