feat: 新增IM即时通讯(浮窗)、工作流、打印模块及工作台增强

- IM: 新增浮窗聊天(ImFloatWindow)、管理页(monitor/config/service/message)、SSE推送
- 工作流: 新增待办/我的流程页面及后端服务
- 打印: 新增打印模板、出库单打印(PrintPage)、模板种子脚本
- 工作台: 增强快捷入口与工作台数据
- 修复: TagsView页签关闭、CrudPage通用表格增强
- 移除导航菜单中的即时通讯入口,改为右下角浮窗
This commit is contained in:
2026-08-16 00:19:24 +08:00
parent 7235265749
commit 1bec470647
49 changed files with 5791 additions and 51 deletions
+128
View File
@@ -0,0 +1,128 @@
/**
* 一次性演示:为庄口 GYZ-2026-002 补充分工段生产数据(幂等,可重复执行)
* 选茧(领料5000→上车茧3200) → 煮茧(送茧2800) → 缫丝(下丝900) → 复摇(返丝830) → 秤大丝(820)
* 用法:node server/scripts/seed-zhuangkou-progress.mjs
*/
const BASE = process.env.F9MES_API || 'http://localhost:5136';
const PHONE = '13800000000';
const PASSWORD = '123456';
const PZ_ID = 1; // 工艺庄口 GYZ-2026-002
const RAW_ZK_ID = 2; // 原料庄口(选茧按原料庄口关联)
async function api(h, method, url, body) {
const res = await fetch(BASE + url, {
method,
headers: h,
body: body ? JSON.stringify(body) : undefined,
});
const text = await res.text();
let json = null;
try { json = JSON.parse(text); } catch { /* ignore */ }
if (!res.ok || (json && json.code !== 0)) {
throw new Error(`HTTP ${res.status} ${url}: ${text.slice(0, 300)}`);
}
return json;
}
async function clearRows(h, table, field, value) {
const r = await api(h, 'POST', `/api/data/${table}/page`, {
page: 1, size: 200, filters: [{ field, value }],
});
const items = (r.data && r.data.items) || [];
if (!items.length) return 0;
const ids = items.map((i) => i.id);
await api(h, 'POST', `/api/data/${table}/deleteRange`, ids);
return ids.length;
}
async function main() {
const login = await api({ 'Content-Type': 'application/json' }, 'POST', '/api/auth/login', {
phone: PHONE,
password: PASSWORD,
});
const token = login.data.token;
const h = { Authorization: 'Bearer ' + token, 'Content-Type': 'application/json' };
// 0) 清理该庄口旧演示数据(幂等)
const cleared = {
xuan: await clearRows(h, 'ProXuan_Daily', 'zhuangkouId', RAW_ZK_ID),
boil: await clearRows(h, 'ProQian_CocoonBoiling', 'processZhuangkouId', PZ_ID),
thread: await clearRows(h, 'ProQian_ThreadRecord', 'processZhuangkouId', PZ_ID),
hou: await clearRows(h, 'ProHou_Daily', 'processZhuangkouId', PZ_ID),
weigh: await clearRows(h, 'ProHou_WeighBig', 'processZhuangkouId', PZ_ID),
order: await clearRows(h, 'ProPlan_WorkOrder', 'processZhuangkouId', PZ_ID),
};
console.log('已清理旧数据:', JSON.stringify(cleared));
// 1) 生产计划工单(选茧 + 前缫),插入后自动联动重算庄口总体进度
await api(h, 'POST', '/api/data/ProPlan_WorkOrder/add', {
orderNo: 'WO-2026-08-001', processZhuangkouId: PZ_ID, targetProcess: 0,
planInput: 5000, planOutput: 4000, planStartDate: '2026-08-14T08:00:00', planEndDate: '2026-08-20T08:00:00', status: 1,
});
await api(h, 'POST', '/api/data/ProPlan_WorkOrder/add', {
orderNo: 'WO-2026-08-002', processZhuangkouId: PZ_ID, targetProcess: 1,
planInput: 3500, planOutput: 1500, planStartDate: '2026-08-14T08:00:00', planEndDate: '2026-08-22T08:00:00', status: 1,
});
console.log('工单已创建(选茧计划产出4000kg / 前缫计划产丝1500kg');
// 2) 选茧日报:领料 5000 → 上车茧 3200
const xuans = [
{ dailyDate: '2026-08-14T08:00:00', teamId: 1, zhuangkouId: RAW_ZK_ID, inputWeight: 3000, goodWeight: 1900, wasteWeight: 950, workerCount: 12, workHours: 8 },
{ dailyDate: '2026-08-15T08:00:00', teamId: 1, zhuangkouId: RAW_ZK_ID, inputWeight: 2000, goodWeight: 1300, wasteWeight: 550, workerCount: 12, workHours: 8 },
];
for (const row of xuans) {
const r = await api(h, 'POST', '/api/data/ProXuan_Daily/add', row);
console.log('选茧日报 id=' + (r.data && (r.data.id ?? JSON.stringify(r.data).slice(0, 60))));
}
// 3) 煮茧送茧 2800
const boils = [
{ boilDate: '2026-08-14T09:00:00', processZhuangkouId: PZ_ID, specId: 1, inputWeight: 1500, boilerNo: 'A01' },
{ boilDate: '2026-08-15T09:00:00', processZhuangkouId: PZ_ID, specId: 1, inputWeight: 1300, boilerNo: 'A02' },
];
for (const row of boils) {
const r = await api(h, 'POST', '/api/data/ProQian_CocoonBoiling/add', row);
console.log('煮茧 id=' + (r.data && (r.data.id ?? JSON.stringify(r.data).slice(0, 60))));
}
// 4) 缫丝落丝 900
const threads = [
{ recordDate: '2026-08-14T18:00:00', processZhuangkouId: PZ_ID, machineId: 1, shift: 1, threadCount: 48, weight: 480, specId: 1, employeeId: 1 },
{ recordDate: '2026-08-15T18:00:00', processZhuangkouId: PZ_ID, machineId: 2, shift: 2, threadCount: 42, weight: 420, specId: 1, employeeId: 1 },
];
for (const row of threads) {
const r = await api(h, 'POST', '/api/data/ProQian_ThreadRecord/add', row);
console.log('缫丝落丝 id=' + (r.data && (r.data.id ?? JSON.stringify(r.data).slice(0, 60))));
}
// 5) 复摇日报:上机 850 → 返丝 830
const hous = [
{ dailyDate: '2026-08-14T20:00:00', processZhuangkouId: PZ_ID, teamId: 2, inputWeight: 450, outputWeight: 440, outputCount: 44 },
{ dailyDate: '2026-08-15T20:00:00', processZhuangkouId: PZ_ID, teamId: 2, inputWeight: 400, outputWeight: 390, outputCount: 39 },
];
for (const row of hous) {
const r = await api(h, 'POST', '/api/data/ProHou_Daily/add', row);
console.log('复摇日报 id=' + (r.data && (r.data.id ?? JSON.stringify(r.data).slice(0, 60))));
}
// 6) 秤大丝 820
const weigh = await api(h, 'POST', '/api/data/ProHou_WeighBig/add', {
billNo: 'W-20260815-001', processZhuangkouId: PZ_ID, weighDate: '2026-08-15T21:00:00', totalWeight: 820, packageCount: 41,
});
console.log('秤大丝 id=' + (weigh.data && (weigh.data.id ?? JSON.stringify(weigh.data).slice(0, 60))));
// 7) 回读分工段进度
const r = await api(h, 'GET', '/api/workbench/zhuangkou-progress');
const d = r.data || {};
console.log('--- zhuangkou-progress total=' + d.total + ' producing=' + d.producing);
const it = (d.items || [])[0];
if (it) {
console.log('庄口=' + it.code + ' 状态=' + it.statusText + ' 总体进度=' + it.progress + ' 计划产丝=' + it.planOutput + 'kg');
for (const s of it.stages) console.log(' ' + s.name + ' ' + s.flow + ' 实际=' + s.actual + ' 基准=' + s.base + ' rate=' + s.rate + '%');
}
}
main().catch((e) => {
console.error('ERR: ' + e.message);
process.exit(1);
});