314 lines
8.9 KiB
Markdown
314 lines
8.9 KiB
Markdown
# WiiCITMS - 企业信息管理系统
|
||
|
||
WiiCITMS 是一个企业信息管理系统,提供组织结构管理、人事管理、工作流审批、通知推送等功能。本文档主要介绍系统的架构和使用方法。
|
||
|
||
## 系统特性
|
||
|
||
- **组织架构管理**:支持多级组织结构,岗位管理
|
||
- **人事管理**:员工信息管理,员工岗位分配
|
||
- **权限管理**:基于角色和岗位的权限控制
|
||
- **工作流引擎**:可定制的审批流程
|
||
- **实时通知**:使用SSE技术的实时消息推送系统
|
||
|
||
## 系统架构
|
||
|
||
系统采用Go语言开发,主要组件包括:
|
||
|
||
- **数据层**:使用SQL Server存储数据
|
||
- **业务逻辑层**:实现业务逻辑和处理
|
||
- **API层**:提供基于MCP的API接口
|
||
- **通知服务**:基于SSE的实时通知系统
|
||
|
||
## SSE通知系统使用指南
|
||
|
||
### 什么是SSE
|
||
|
||
SSE(Server-Sent Events)是一种服务器推送技术,允许服务器向客户端推送数据。与WebSocket不同,SSE是单向的(只能服务器向客户端发送数据),但实现更简单,对服务器资源消耗更小。
|
||
|
||
### 连接SSE服务
|
||
|
||
#### 前端连接示例
|
||
|
||
使用原生JavaScript连接SSE服务:
|
||
|
||
```javascript
|
||
// 创建SSE连接
|
||
const connectToSSE = (userGuid) => {
|
||
const evtSource = new EventSource(`/api/v1/events?userGuid=${userGuid}`);
|
||
|
||
// 连接打开时的处理
|
||
evtSource.onopen = () => {
|
||
console.log('SSE连接已建立');
|
||
};
|
||
|
||
// 连接错误处理
|
||
evtSource.onerror = (error) => {
|
||
console.error('SSE连接错误:', error);
|
||
// 可以在这里实现重连逻辑
|
||
setTimeout(() => connectToSSE(userGuid), 5000);
|
||
};
|
||
|
||
// 处理职位变动通知
|
||
evtSource.addEventListener('position_change', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
console.log('收到职位变动通知:', data);
|
||
// 在这里处理通知,如显示提醒、更新界面等
|
||
});
|
||
|
||
// 处理审批通知
|
||
evtSource.addEventListener('approval_notice', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
console.log('收到审批通知:', data);
|
||
// 在这里处理通知
|
||
});
|
||
|
||
// 处理消息提醒
|
||
evtSource.addEventListener('message_notification', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
console.log('收到消息提醒:', data);
|
||
// 在这里处理通知
|
||
});
|
||
|
||
// 处理系统通知
|
||
evtSource.addEventListener('system_notification', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
console.log('收到系统通知:', data);
|
||
// 在这里处理通知
|
||
});
|
||
|
||
// 返回SSE实例,以便在需要时关闭连接
|
||
return evtSource;
|
||
};
|
||
|
||
// 使用示例
|
||
const userGuid = '12345678-1234-1234-1234-123456789012'; // 用户的GUID
|
||
const sseConnection = connectToSSE(userGuid);
|
||
|
||
// 在退出页面或不需要时关闭连接
|
||
window.addEventListener('beforeunload', () => {
|
||
if (sseConnection) {
|
||
sseConnection.close();
|
||
}
|
||
});
|
||
```
|
||
|
||
#### 使用Vue.js的示例
|
||
|
||
```javascript
|
||
// SSE.js - SSE服务封装
|
||
export default {
|
||
connection: null,
|
||
|
||
connect(userGuid, handlers = {}) {
|
||
this.connection = new EventSource(`/api/v1/events?userGuid=${userGuid}`);
|
||
|
||
this.connection.onopen = handlers.onOpen || (() => console.log('SSE连接已建立'));
|
||
this.connection.onerror = handlers.onError || ((error) => console.error('SSE连接错误:', error));
|
||
|
||
// 注册事件处理器
|
||
if (handlers.onPositionChange) {
|
||
this.connection.addEventListener('position_change', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
handlers.onPositionChange(data);
|
||
});
|
||
}
|
||
|
||
if (handlers.onApprovalNotice) {
|
||
this.connection.addEventListener('approval_notice', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
handlers.onApprovalNotice(data);
|
||
});
|
||
}
|
||
|
||
if (handlers.onMessageNotification) {
|
||
this.connection.addEventListener('message_notification', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
handlers.onMessageNotification(data);
|
||
});
|
||
}
|
||
|
||
if (handlers.onSystemNotification) {
|
||
this.connection.addEventListener('system_notification', (event) => {
|
||
const data = JSON.parse(event.data);
|
||
handlers.onSystemNotification(data);
|
||
});
|
||
}
|
||
|
||
return this.connection;
|
||
},
|
||
|
||
disconnect() {
|
||
if (this.connection) {
|
||
this.connection.close();
|
||
this.connection = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
// 在Vue组件中使用
|
||
import SSEService from './SSE';
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
notifications: [],
|
||
}
|
||
},
|
||
|
||
created() {
|
||
const userGuid = this.$store.state.user.guid;
|
||
|
||
SSEService.connect(userGuid, {
|
||
onPositionChange: (data) => {
|
||
this.notifications.push({
|
||
type: 'position',
|
||
title: data.title,
|
||
content: data.content,
|
||
time: new Date(),
|
||
});
|
||
this.$notify({
|
||
title: data.title,
|
||
message: data.content,
|
||
type: 'info'
|
||
});
|
||
},
|
||
|
||
onApprovalNotice: (data) => {
|
||
this.notifications.push({
|
||
type: 'approval',
|
||
title: data.title,
|
||
content: data.content,
|
||
time: new Date(),
|
||
});
|
||
this.$notify({
|
||
title: data.title,
|
||
message: data.content,
|
||
type: 'warning'
|
||
});
|
||
},
|
||
});
|
||
},
|
||
|
||
beforeDestroy() {
|
||
SSEService.disconnect();
|
||
}
|
||
}
|
||
```
|
||
|
||
### 后端发送通知示例
|
||
|
||
可以通过以下方式在后端代码中发送通知:
|
||
|
||
#### 使用MCP工具发送通知
|
||
|
||
```go
|
||
// 示例1: 发送职位变动通知
|
||
mcpClient.CallTool(ctx, "notifyPositionChange", map[string]interface{}{
|
||
"staffGuid": "12345678-1234-1234-1234-123456789012",
|
||
"title": "职位变更通知",
|
||
"content": "您已被调整为市场部经理",
|
||
"oldPosition": "市场专员",
|
||
"newPosition": "市场经理",
|
||
})
|
||
|
||
// 示例2: 发送审批通知
|
||
mcpClient.CallTool(ctx, "notifyApproval", map[string]interface{}{
|
||
"staffGuid": "12345678-1234-1234-1234-123456789012",
|
||
"title": "请假申请已审批",
|
||
"content": "您的请假申请已被批准",
|
||
"approvalId": "AP2025091210001",
|
||
"approvalState": "已通过",
|
||
})
|
||
|
||
// 示例3: 广播系统通知
|
||
mcpClient.CallTool(ctx, "broadcastSystemNotification", map[string]interface{}{
|
||
"title": "系统维护通知",
|
||
"content": "系统将于今晚22:00-23:00进行维护,请提前做好工作安排",
|
||
"category": "维护",
|
||
"severity": "信息",
|
||
})
|
||
```
|
||
|
||
#### 在Go代码中直接发送通知
|
||
|
||
```go
|
||
import "WiiCITMS/servers/notification"
|
||
|
||
// 示例1: 发送职位变动通知
|
||
notification.NotifyPositionChange(
|
||
[]string{"12345678-1234-1234-1234-123456789012"},
|
||
notification.PositionChangePayload{
|
||
NotificationPayload: notification.NotificationPayload{
|
||
Title: "职位变更通知",
|
||
Content: "您已被调整为市场部经理",
|
||
},
|
||
OldPosition: "市场专员",
|
||
NewPosition: "市场经理",
|
||
ChangeType: "晋升",
|
||
},
|
||
)
|
||
|
||
// 示例2: 发送审批通知
|
||
notification.NotifyApproval(
|
||
[]string{"12345678-1234-1234-1234-123456789012"},
|
||
notification.ApprovalNoticePayload{
|
||
NotificationPayload: notification.NotificationPayload{
|
||
Title: "请假申请已审批",
|
||
Content: "您的请假申请已被批准",
|
||
},
|
||
ApprovalID: "AP2025091210001",
|
||
ApprovalState: "已通过",
|
||
Approver: "张经理",
|
||
},
|
||
)
|
||
|
||
// 示例3: 广播系统通知
|
||
notification.BroadcastSystemNotification(
|
||
notification.SystemNotificationPayload{
|
||
NotificationPayload: notification.NotificationPayload{
|
||
Title: "系统维护通知",
|
||
Content: "系统将于今晚22:00-23:00进行维护,请提前做好工作安排",
|
||
},
|
||
Category: "维护",
|
||
Severity: "信息",
|
||
},
|
||
)
|
||
```
|
||
|
||
### 通知类型
|
||
|
||
系统支持以下几种通知类型:
|
||
|
||
1. **职位变动通知** (`position_change`): 当员工职位发生变化时发送
|
||
2. **审批通知** (`approval_notice`): 当工作流审批状态发生变化时发送
|
||
3. **消息提醒** (`message_notification`): 普通消息提醒
|
||
4. **系统通知** (`system_notification`): 系统级别的通知,可广播给所有用户
|
||
|
||
### 配置说明
|
||
|
||
SSE服务默认在MCP端口+1的端口上运行,例如如果MCP服务在8080端口,则SSE服务会在8081端口。可以通过修改`main.go`中的配置进行调整。
|
||
|
||
## API文档
|
||
|
||
系统API基于MCP (Meta Command Protocol) 实现,提供了丰富的业务功能接口。
|
||
|
||
### 主要API分类
|
||
|
||
- **组织架构API**: 组织、岗位管理
|
||
- **员工管理API**: 员工信息、员工岗位分配
|
||
- **权限管理API**: 权限分配、权限检查
|
||
- **工作流API**: 流程定义、实例管理、审批操作
|
||
- **通知API**: 发送通知、获取在线用户
|
||
|
||
有关详细API文档,请参考系统内部文档或代码注释。
|
||
|
||
## 系统要求
|
||
|
||
- Go 1.18或更高版本
|
||
- SQL Server 2019或更高版本
|
||
- 现代Web浏览器(支持ES6和SSE)
|
||
|
||
## 许可证
|
||
|
||
版权所有 © 2025 WiiUniverse
|