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
+46
View File
@@ -0,0 +1,46 @@
// Seed script: create the "1/3 A4 out-stock form" print template.
// Run: node seed-print-template.mjs
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const BASE = process.env.F9_API_BASE || 'http://localhost:5136'
const PHONE = '13800000000'
const PASSWORD = '123456'
const tpl = JSON.parse(
fs.readFileSync(path.join(__dirname, 'print-template-outstock.json'), 'utf8')
)
async function main() {
const loginRes = await fetch(`${BASE}/api/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone: PHONE, password: PASSWORD })
})
const login = await loginRes.json()
if (login.code !== 0) throw new Error(`Login failed: ${login.message}`)
const token = login.data.token
const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' }
const list = await fetch(`${BASE}/api/print/templates`, { headers }).then((r) => r.json())
const dup = (list.items || []).find((i) => i.name === tpl.name)
if (dup) {
console.log(`Template already exists, skip: ${tpl.name} (id=${dup.id})`)
return
}
const res = await fetch(`${BASE}/api/print/templates`, {
method: 'POST',
headers,
body: JSON.stringify({ name: tpl.name, content: JSON.stringify(tpl.content) })
})
const row = await res.json()
console.log(`Template created: id=${row.id} name=${row.name}`)
}
main().catch((e) => {
console.error(e)
process.exit(1)
})