最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Activiti的項(xiàng)目中實(shí)現(xiàn)抄送功能

 更新時間:2026年01月09日 08:32:17   作者:hhzz  
本文主要介紹了SpringBoot整合Activiti的項(xiàng)目中實(shí)現(xiàn)抄送功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、實(shí)現(xiàn)思路

在Activiti工作流中,抄送功能通常不是直接提供的,但可以通過擴(kuò)展來實(shí)現(xiàn)。抄送功能可以理解為將某個任務(wù)的信息發(fā)送給相關(guān)人員,而不需要他們直接處理任務(wù)。在Spring Boot整合Activiti的項(xiàng)目中,我們可以通過以下方式實(shí)現(xiàn)抄送功能:

  1. 自定義抄送表:記錄抄送的任務(wù)、抄送給誰、抄送時間等信息。
  2. 在任務(wù)創(chuàng)建或完成時觸發(fā)抄送邏輯,將任務(wù)信息插入抄送表。
  3. 提供接口供用戶查看自己被抄送的任務(wù)。

在Spring Boot項(xiàng)目中整合Activiti工作流的抄送功能,可以通過以下方案實(shí)現(xiàn):

2、在Spring Boot中集成Activiti

pom.xml中添加Activiti依賴:

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.1.0.M6</version>
</dependency>

2.1、設(shè)計(jì)抄送表

創(chuàng)建抄送表,表結(jié)構(gòu)如下:

CREATE TABLE `act_cc_task` (
  `id` varchar(64) NOT NULL COMMENT '主鍵',
  `task_id` varchar(64) DEFAULT NULL COMMENT '任務(wù)ID',
  `proc_inst_id` varchar(64) DEFAULT NULL COMMENT '流程實(shí)例ID',
  `proc_def_id` varchar(64) DEFAULT NULL COMMENT '流程定義ID',
  `title` varchar(255) DEFAULT NULL COMMENT '抄送標(biāo)題',
  `content` text COMMENT '抄送內(nèi)容',
  `from_user_id` varchar(64) DEFAULT NULL COMMENT '發(fā)起人',
  `to_user_ids` text COMMENT '接收人(多個用逗號分隔)',
  `status` int(1) DEFAULT '0' COMMENT '狀態(tài)(0:未讀,1:已讀)',
  `create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時間',
  `read_time` datetime DEFAULT NULL COMMENT '讀取時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.2、抄送實(shí)體類

@Data
@TableName("act_cc_task")
public class CcTask {
    @TableId(type = IdType.ASSIGN_ID)
    private String id;
    private String taskId;
    private String procInstId;
    private String procDefId;
    private String title;
    private String content;
    private String fromUserId;
    private String toUserIds;  // 多個用戶用逗號分隔
    private Integer status;
    private Date createTime;
    private Date readTime;
    
    @TableField(exist = false)
    private List<String> toUserList;  // 接收人列表
}

2.3、實(shí)現(xiàn)抄送服務(wù)

創(chuàng)建一個抄送服務(wù),用于處理抄送邏輯。例如,在任務(wù)完成時,將任務(wù)抄送給指定人員。

服務(wù)接口:

public interface CcTaskService {
    
    /**
     * 創(chuàng)建抄送任務(wù)
     */
    void createCcTask(String taskId, List<String> toUserIds, 
                     String title, String content);
    
    /**
     * 獲取用戶的抄送列表
     */
    PageInfo<CcTask> getUserCcTasks(String userId, Integer pageNum, 
                                   Integer pageSize, Integer status);
    
    /**
     * 標(biāo)記為已讀
     */
    void markAsRead(String ccTaskId, String userId);
    
    /**
     * 批量抄送
     */
    void batchCcTask(List<String> taskIds, List<String> toUserIds, 
                    String reason);
}

服務(wù)實(shí)現(xiàn):

在任務(wù)完成時觸發(fā)抄送,可以在任務(wù)完成事件監(jiān)聽器中觸發(fā)抄送。例如,創(chuàng)建一個任務(wù)監(jiān)聽器

@Service
@Slf4j
public class CcTaskServiceImpl implements CcTaskService {
    
    @Autowired
    private CcTaskMapper ccTaskMapper;
    
    @Autowired
    private TaskService taskService;
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Override
    @Transactional
    public void createCcTask(String taskId, List<String> toUserIds, 
                           String title, String content) {
        
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();
        
        if (task == null) {
            throw new BusinessException("任務(wù)不存在");
        }
        
        // 獲取當(dāng)前登錄用戶
        String currentUserId = SecurityUtils.getCurrentUserId();
        
        CcTask ccTask = new CcTask();
        ccTask.setId(IdUtil.fastSimpleUUID());
        ccTask.setTaskId(taskId);
        ccTask.setProcInstId(task.getProcessInstanceId());
        ccTask.setProcDefId(task.getProcessDefinitionId());
        ccTask.setTitle(title);
        ccTask.setContent(content);
        ccTask.setFromUserId(currentUserId);
        ccTask.setToUserIds(StringUtils.join(toUserIds, ","));
        ccTask.setStatus(0);
        ccTask.setCreateTime(new Date());
        
        ccTaskMapper.insert(ccTask);
        
        // 發(fā)送通知(可集成消息推送)
        sendNotification(ccTask);
    }
    
    /**
     * 使用監(jiān)聽器自動抄送
     */
    @Component
    public static class TaskCcListener implements TaskListener {
        
        @Autowired
        private CcTaskService ccTaskService;
        
        @Override
        public void notify(DelegateTask delegateTask) {
            String eventName = delegateTask.getEventName();
            
            // 在任務(wù)創(chuàng)建時自動抄送
            if ("create".equals(eventName)) {
                Object ccUsers = delegateTask.getVariable("ccUsers");
                if (ccUsers != null) {
                    List<String> userIds = (List<String>) ccUsers;
                    if (!CollectionUtils.isEmpty(userIds)) {
                        String taskName = delegateTask.getName();
                        String content = String.format("任務(wù)【%s】需要您知曉", taskName);
                        
                        ccTaskService.createCcTask(
                            delegateTask.getId(),
                            userIds,
                            taskName,
                            content
                        );
                    }
                }
            }
        }
    }
}

然后在流程定義中,在任務(wù)完成事件上綁定這個監(jiān)聽器。可以在BPMN文件中配置,也可以通過代碼配置。

控制器層:

@RestController
@RequestMapping("/api/cc")
@Api(tags = "抄送管理")
public class CcTaskController {
    
    @Autowired
    private CcTaskService ccTaskService;
    
    @PostMapping("/create")
    @ApiOperation("創(chuàng)建抄送")
    public Result createCcTask(@RequestBody CcTaskCreateDTO dto) {
        ccTaskService.createCcTask(
            dto.getTaskId(),
            dto.getToUserIds(),
            dto.getTitle(),
            dto.getContent()
        );
        return Result.success();
    }
    
    @GetMapping("/list")
    @ApiOperation("獲取抄送列表")
    public Result<PageInfo<CcTask>> getCcList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Integer status) {
        
        String userId = SecurityUtils.getCurrentUserId();
        PageInfo<CcTask> result = ccTaskService.getUserCcTasks(
            userId, pageNum, pageSize, status
        );
        return Result.success(result);
    }
    
    @PostMapping("/read/{id}")
    @ApiOperation("標(biāo)記已讀")
    public Result markAsRead(@PathVariable String id) {
        String userId = SecurityUtils.getCurrentUserId();
        ccTaskService.markAsRead(id, userId);
        return Result.success();
    }
}

3、前端集成

3.1、抄送組件

<template>
  <div class="cc-task-container">
    <!-- 抄送按鈕 -->
    <el-button type="text" @click="showCcDialog">
      <i class="el-icon-s-promotion"></i> 抄送
    </el-button>
    
    <!-- 抄送對話框 -->
    <el-dialog title="任務(wù)抄送" :visible.sync="ccDialogVisible">
      <el-form :model="ccForm">
        <el-form-item label="接收人">
          <el-select 
            v-model="ccForm.userIds" 
            multiple 
            filterable
            placeholder="請選擇接收人">
            <el-option
              v-for="user in userList"
              :key="user.id"
              :label="user.name"
              :value="user.id">
            </el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item label="抄送說明">
          <el-input
            type="textarea"
            v-model="ccForm.content"
            placeholder="請輸入抄送說明"
            rows="4">
          </el-input>
        </el-form-item>
      </el-form>
      
      <div slot="footer">
        <el-button @click="ccDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitCc">確定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  props: {
    taskId: String,
    taskName: String
  },
  data() {
    return {
      ccDialogVisible: false,
      userList: [],
      ccForm: {
        userIds: [],
        content: ''
      }
    }
  },
  methods: {
    showCcDialog() {
      this.ccDialogVisible = true
      this.loadUserList()
    },
    
    async loadUserList() {
      const res = await this.$api.user.getUserList()
      this.userList = res.data
    },
    
    async submitCc() {
      const params = {
        taskId: this.taskId,
        toUserIds: this.ccForm.userIds,
        title: `任務(wù)【${this.taskName}】抄送`,
        content: this.ccForm.content
      }
      
      await this.$api.cc.create(params)
      this.$message.success('抄送成功')
      this.ccDialogVisible = false
      this.$emit('cc-success')
    }
  }
}
</script>

3.2、抄送列表頁面

<template>
  <div class="cc-task-list">
    <el-tabs v-model="activeStatus" @tab-click="handleTabClick">
      <el-tab-pane label="未讀" name="0"></el-tab-pane>
      <el-tab-pane label="已讀" name="1"></el-tab-pane>
      <el-tab-pane label="全部" name=""></el-tab-pane>
    </el-tabs>
    
    <el-table :data="ccList" v-loading="loading">
      <el-table-column prop="title" label="標(biāo)題" width="200">
        <template slot-scope="{row}">
          <span :class="{'unread': row.status === 0}">
            {{ row.title }}
          </span>
        </template>
      </el-table-column>
      
      <el-table-column prop="content" label="內(nèi)容"></el-table-column>
      
      <el-table-column prop="fromUserName" label="發(fā)起人" width="100">
      </el-table-column>
      
      <el-table-column prop="createTime" label="時間" width="180">
        <template slot-scope="{row}">
          {{ formatDate(row.createTime) }}
        </template>
      </el-table-column>
      
      <el-table-column label="操作" width="120">
        <template slot-scope="{row}">
          <el-button 
            v-if="row.status === 0"
            type="text" 
            @click="markAsRead(row.id)">
            標(biāo)記已讀
          </el-button>
          <el-button 
            type="text" 
            @click="viewProcess(row.procInstId)">
            查看流程
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pagination.pageNum"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="pagination.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pagination.total">
    </el-pagination>
  </div>
</template>

前端可以調(diào)用上述接口展示抄送列表,并允許用戶標(biāo)記已讀。

注意事項(xiàng)

  • 抄送功能可以根據(jù)實(shí)際需求進(jìn)行擴(kuò)展,例如增加抄送類型(任務(wù)創(chuàng)建時抄送、任務(wù)完成時抄送等)。
  • 抄送人員可以從任務(wù)變量、流程變量、固定配置或者從用戶選擇中獲取。
  • 抄送任務(wù)可能不需要處理,但需要記錄,因此抄送表的設(shè)計(jì)可以根據(jù)業(yè)務(wù)需求調(diào)整。

4、高級功能擴(kuò)展

4.1、郵件通知集成

@Component
public class EmailCcNotifier {
    
    @Autowired
    private JavaMailSender mailSender;
    
    @Value("${spring.mail.username}")
    private String from;
    
    public void sendCcNotification(CcTask ccTask, User user) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(user.getEmail());
        message.setSubject("工作流抄送通知:" + ccTask.getTitle());
        message.setText(buildEmailContent(ccTask));
        
        mailSender.send(message);
    }
    
    private String buildEmailContent(CcTask ccTask) {
        return String.format(
            "您收到一條工作流抄送:\n" +
            "標(biāo)題:%s\n" +
            "內(nèi)容:%s\n" +
            "發(fā)起人:%s\n" +
            "時間:%s\n" +
            "請登錄系統(tǒng)查看詳情。",
            ccTask.getTitle(),
            ccTask.getContent(),
            ccTask.getFromUserId(),
            DateUtil.formatDateTime(ccTask.getCreateTime())
        );
    }
}

4.2、消息推送集成(WebSocket)

@ServerEndpoint("/websocket/cc")
@Component
public class CcWebSocket {
    
    private static Map<String, Session> sessions = new ConcurrentHashMap<>();
    
    @OnOpen
    public void onOpen(Session session) {
        String userId = getUserIdFromSession(session);
        sessions.put(userId, session);
    }
    
    /**
     * 向指定用戶推送抄送消息
     */
    public static void sendCcMessage(String userId, CcTask ccTask) {
        Session session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            try {
                String message = JSON.toJSONString(
                    Map.of("type", "cc", "data", ccTask)
                );
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("發(fā)送WebSocket消息失敗", e);
            }
        }
    }
}

4.3、 抄送規(guī)則配置

@Component
public class CcRuleEngine {
    
    /**
     * 根據(jù)規(guī)則自動抄送
     * 規(guī)則示例:
     * 1. 特定節(jié)點(diǎn)自動抄送
     * 2. 金額大于閾值抄送
     * 3. 特定部門任務(wù)抄送
     */
    public List<String> getCcUsersByRule(
            String processDefinitionId, 
            String taskDefinitionKey,
            Map<String, Object> variables) {
        
        List<String> userIds = new ArrayList<>();
        
        // 示例:根據(jù)任務(wù)節(jié)點(diǎn)配置抄送
        if ("approve".equals(taskDefinitionKey)) {
            // 審批節(jié)點(diǎn)抄送給部門經(jīng)理
            String deptId = (String) variables.get("deptId");
            userIds.addAll(getDeptManagers(deptId));
        }
        
        // 示例:根據(jù)金額閾值抄送
        Double amount = (Double) variables.get("amount");
        if (amount != null && amount > 10000) {
            userIds.addAll(getFinanceUsers());
        }
        
        return userIds.stream().distinct().collect(Collectors.toList());
    }
}

4.4、 應(yīng)用配置文件

# application.yml
activiti:
  cc:
    enabled: true
    # 是否啟用郵件通知
    email-notify: true
    # 是否啟用站內(nèi)信
    message-notify: true
    # 默認(rèn)抄送人(角色)
    default-cc-roles: ROLE_DEPT_MANAGER,ROLE_ADMIN

4.5、 流程定義中的抄送配置

<!-- 在BPMN文件中添加抄送配置 -->
<userTask id="approveTask" name="審批任務(wù)">
  <extensionElements>
    <activiti:taskListener event="create" 
      class="com.xxx.listener.AutoCcTaskListener"/>
    <activiti:formProperty id="ccUsers" 
      name="抄送人" type="users"/>
  </extensionElements>
</userTask>

5、總結(jié)

抄送功能的實(shí)現(xiàn)要點(diǎn):

  • 數(shù)據(jù)持久化:設(shè)計(jì)抄送表記錄抄送信息
  • 業(yè)務(wù)邏輯:提供抄送CRUD服務(wù)
  • 流程集成:通過監(jiān)聽器自動觸發(fā)抄送
  • 用戶通知:集成多種通知方式(站內(nèi)信、郵件、推送)
  • 權(quán)限控制:確保用戶只能操作自己的抄送記錄
  • 配置靈活:支持規(guī)則引擎和動態(tài)配置

這種實(shí)現(xiàn)方式既保持了工作流引擎的純凈性,又通過擴(kuò)展實(shí)現(xiàn)了業(yè)務(wù)需要的抄送功能。

到此這篇關(guān)于SpringBoot整合Activiti的項(xiàng)目中實(shí)現(xiàn)抄送功能的文章就介紹到這了,更多相關(guān)SpringBoot Activiti抄送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

苍南县| 准格尔旗| 安阳市| 宕昌县| 黄冈市| 交口县| 嵊州市| 仁寿县| 武山县| 沙坪坝区| 晋中市| 卓资县| 广丰县| 清丰县| 西峡县| 阳春市| 峨山| 广安市| 北流市| 屏边| 临颍县| 奉节县| 自贡市| 濉溪县| 开封县| 虹口区| 房产| 恩施市| 河曲县| 鹤壁市| 特克斯县| 民县| 沙湾县| 库车县| 新乡县| 永胜县| 虹口区| 公安县| 安仁县| 巴林左旗| 安阳县|