feat(mci-server): Phase 1 数据模型调整
- 新增 V11 媒体文件表 mci_message_media 及实体/Mapper - 新增 V12 建群任务表 mci_conversation_create_task 及实体/Mapper - 新增 V13 策略组表 mci_policy_group 及实体/Mapper/Service/Controller - V14 将 mci_flow_definition.flow_type 由 VARCHAR 迁移为 TINYINT,实体改为 Integer - FlowDefinitionService 兼容字符串/数值 flowType,FlowEngine 按数值 1 过滤入站流程 - MybatisPlusConfig 增加 message、policy 仓库扫描包
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package com.sino.mci.channel.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.sino.mci.shared.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("mci_conversation_create_task")
|
||||||
|
public class ConversationCreateTask extends BaseEntity {
|
||||||
|
|
||||||
|
private String tenantCode;
|
||||||
|
private Integer taskType;
|
||||||
|
private String channelType;
|
||||||
|
private Long accountId;
|
||||||
|
private Long conversationId;
|
||||||
|
private String participantIds;
|
||||||
|
private Integer taskStatus;
|
||||||
|
private String channelResult;
|
||||||
|
private Integer retryCount;
|
||||||
|
private LocalDateTime finishTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.sino.mci.channel.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.sino.mci.channel.entity.ConversationCreateTask;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ConversationCreateTaskMapper extends BaseMapper<ConversationCreateTask> {
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@MapperScan({"com.sino.mci.admin.repository", "com.sino.mci.channel.repository", "com.sino.mci.crm.repository", "com.sino.mci.flow.repository", "com.sino.mci.inbound.repository", "com.sino.mci.send.repository"})
|
@MapperScan({"com.sino.mci.admin.repository", "com.sino.mci.channel.repository", "com.sino.mci.crm.repository", "com.sino.mci.flow.repository", "com.sino.mci.inbound.repository", "com.sino.mci.message.repository", "com.sino.mci.policy.repository", "com.sino.mci.send.repository"})
|
||||||
public class MybatisPlusConfig {
|
public class MybatisPlusConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class FlowDefinition extends BaseEntity {
|
|||||||
private String tenantCode;
|
private String tenantCode;
|
||||||
private String flowCode;
|
private String flowCode;
|
||||||
private String flowName;
|
private String flowName;
|
||||||
private String flowType;
|
private Integer flowType;
|
||||||
private String definitionJson;
|
private String definitionJson;
|
||||||
private Integer status;
|
private Integer status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class FlowDefinitionService {
|
|||||||
flow.setTenantCode(tenantCode);
|
flow.setTenantCode(tenantCode);
|
||||||
flow.setFlowCode(request.getFlowCode());
|
flow.setFlowCode(request.getFlowCode());
|
||||||
flow.setFlowName(request.getFlowName());
|
flow.setFlowName(request.getFlowName());
|
||||||
flow.setFlowType(request.getFlowType());
|
flow.setFlowType(parseFlowType(request.getFlowType()));
|
||||||
flow.setDefinitionJson(JsonUtils.toJson(request.getDefinitionJson()));
|
flow.setDefinitionJson(JsonUtils.toJson(request.getDefinitionJson()));
|
||||||
flow.setStatus(0);
|
flow.setStatus(0);
|
||||||
flowDefinitionMapper.insert(flow);
|
flowDefinitionMapper.insert(flow);
|
||||||
@@ -62,7 +62,7 @@ public class FlowDefinitionService {
|
|||||||
public FlowDefinition updateFlow(String tenantCode, String flowCode, CreateFlowRequest request) {
|
public FlowDefinition updateFlow(String tenantCode, String flowCode, CreateFlowRequest request) {
|
||||||
FlowDefinition flow = getFlow(tenantCode, flowCode);
|
FlowDefinition flow = getFlow(tenantCode, flowCode);
|
||||||
flow.setFlowName(request.getFlowName());
|
flow.setFlowName(request.getFlowName());
|
||||||
flow.setFlowType(request.getFlowType());
|
flow.setFlowType(parseFlowType(request.getFlowType()));
|
||||||
flow.setDefinitionJson(JsonUtils.toJson(request.getDefinitionJson()));
|
flow.setDefinitionJson(JsonUtils.toJson(request.getDefinitionJson()));
|
||||||
flowDefinitionMapper.updateById(flow);
|
flowDefinitionMapper.updateById(flow);
|
||||||
return flow;
|
return flow;
|
||||||
@@ -81,4 +81,16 @@ public class FlowDefinitionService {
|
|||||||
flow.setStatus(0);
|
flow.setStatus(0);
|
||||||
flowDefinitionMapper.updateById(flow);
|
flowDefinitionMapper.updateById(flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Integer parseFlowType(String flowType) {
|
||||||
|
if (flowType == null || flowType.isBlank()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
String normalized = flowType.trim().toLowerCase();
|
||||||
|
return switch (normalized) {
|
||||||
|
case "inbound", "1" -> 1;
|
||||||
|
case "ivr", "2" -> 2;
|
||||||
|
default -> 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class FlowEngine {
|
|||||||
List<FlowDefinition> flows = flowDefinitionMapper.selectList(
|
List<FlowDefinition> flows = flowDefinitionMapper.selectList(
|
||||||
new LambdaQueryWrapper<FlowDefinition>()
|
new LambdaQueryWrapper<FlowDefinition>()
|
||||||
.eq(FlowDefinition::getTenantCode, tenantCode)
|
.eq(FlowDefinition::getTenantCode, tenantCode)
|
||||||
.eq(FlowDefinition::getFlowType, "inbound")
|
.eq(FlowDefinition::getFlowType, 1)
|
||||||
.eq(FlowDefinition::getStatus, 1)
|
.eq(FlowDefinition::getStatus, 1)
|
||||||
.orderByDesc(FlowDefinition::getUpdateTime));
|
.orderByDesc(FlowDefinition::getUpdateTime));
|
||||||
return flows.isEmpty() ? null : flows.get(0);
|
return flows.isEmpty() ? null : flows.get(0);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.sino.mci.message.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.sino.mci.shared.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("mci_message_media")
|
||||||
|
public class MessageMedia extends BaseEntity {
|
||||||
|
|
||||||
|
private String tenantCode;
|
||||||
|
private String msgid;
|
||||||
|
private String sdkfileid;
|
||||||
|
private String mediaType;
|
||||||
|
private String fileName;
|
||||||
|
private Long fileSize;
|
||||||
|
private String md5sum;
|
||||||
|
private Integer storageType;
|
||||||
|
private String bucket;
|
||||||
|
private String objectKey;
|
||||||
|
private String accessUrl;
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.sino.mci.message.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.sino.mci.message.entity.MessageMedia;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MessageMediaMapper extends BaseMapper<MessageMedia> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.sino.mci.policy.controller;
|
||||||
|
|
||||||
|
import com.sino.mci.policy.dto.CreatePolicyGroupRequest;
|
||||||
|
import com.sino.mci.policy.dto.UpdatePolicyGroupRequest;
|
||||||
|
import com.sino.mci.policy.dto.UpdatePolicyGroupStatusRequest;
|
||||||
|
import com.sino.mci.policy.entity.PolicyGroup;
|
||||||
|
import com.sino.mci.policy.service.PolicyGroupService;
|
||||||
|
import com.sino.mci.shared.web.ApiResponse;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/policy-group")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PolicyGroupController {
|
||||||
|
|
||||||
|
private final PolicyGroupService policyGroupService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public ApiResponse<PolicyGroup> createPolicyGroup(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
|
@Valid @RequestBody CreatePolicyGroupRequest request) {
|
||||||
|
return ApiResponse.ok(policyGroupService.createPolicyGroup(tenantCode, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
public ApiResponse<List<PolicyGroup>> listPolicyGroups(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode) {
|
||||||
|
return ApiResponse.ok(policyGroupService.listPolicyGroups(tenantCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{groupCode}")
|
||||||
|
public ApiResponse<PolicyGroup> getPolicyGroup(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
|
@PathVariable("groupCode") String groupCode) {
|
||||||
|
return ApiResponse.ok(policyGroupService.getPolicyGroup(tenantCode, groupCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{groupCode}")
|
||||||
|
public ApiResponse<PolicyGroup> updatePolicyGroup(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
|
@PathVariable("groupCode") String groupCode,
|
||||||
|
@Valid @RequestBody UpdatePolicyGroupRequest request) {
|
||||||
|
return ApiResponse.ok(policyGroupService.updatePolicyGroup(tenantCode, groupCode, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{groupCode}/status")
|
||||||
|
public ApiResponse<PolicyGroup> updatePolicyGroupStatus(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
|
@PathVariable("groupCode") String groupCode,
|
||||||
|
@Valid @RequestBody UpdatePolicyGroupStatusRequest request) {
|
||||||
|
return ApiResponse.ok(policyGroupService.updatePolicyGroupStatus(tenantCode, groupCode, request.getStatus()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{groupCode}/delete")
|
||||||
|
public ApiResponse<?> deletePolicyGroup(
|
||||||
|
@RequestHeader("X-Tenant-Code") String tenantCode,
|
||||||
|
@PathVariable("groupCode") String groupCode) {
|
||||||
|
policyGroupService.deletePolicyGroup(tenantCode, groupCode);
|
||||||
|
return ApiResponse.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.sino.mci.policy.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CreatePolicyGroupRequest {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String groupCode;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
private String channelType;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, Object> policies;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.sino.mci.policy.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UpdatePolicyGroupRequest {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
private String channelType;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, Object> policies;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.sino.mci.policy.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UpdatePolicyGroupStatusRequest {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.sino.mci.policy.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.sino.mci.shared.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("mci_policy_group")
|
||||||
|
public class PolicyGroup extends BaseEntity {
|
||||||
|
|
||||||
|
private String tenantCode;
|
||||||
|
private String groupCode;
|
||||||
|
private String groupName;
|
||||||
|
private String channelType;
|
||||||
|
private String policies;
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.sino.mci.policy.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.sino.mci.policy.entity.PolicyGroup;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PolicyGroupMapper extends BaseMapper<PolicyGroup> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.sino.mci.policy.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.sino.mci.exception.BusinessException;
|
||||||
|
import com.sino.mci.policy.dto.CreatePolicyGroupRequest;
|
||||||
|
import com.sino.mci.policy.dto.UpdatePolicyGroupRequest;
|
||||||
|
import com.sino.mci.policy.entity.PolicyGroup;
|
||||||
|
import com.sino.mci.policy.repository.PolicyGroupMapper;
|
||||||
|
import com.sino.mci.shared.util.JsonUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PolicyGroupService {
|
||||||
|
|
||||||
|
private final PolicyGroupMapper policyGroupMapper;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public PolicyGroup createPolicyGroup(String tenantCode, CreatePolicyGroupRequest request) {
|
||||||
|
PolicyGroup existing = policyGroupMapper.selectOne(
|
||||||
|
new LambdaQueryWrapper<PolicyGroup>()
|
||||||
|
.eq(PolicyGroup::getTenantCode, tenantCode)
|
||||||
|
.eq(PolicyGroup::getGroupCode, request.getGroupCode()));
|
||||||
|
if (existing != null) {
|
||||||
|
throw new BusinessException("策略组编码已存在: " + request.getGroupCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyGroup group = new PolicyGroup();
|
||||||
|
group.setTenantCode(tenantCode);
|
||||||
|
group.setGroupCode(request.getGroupCode());
|
||||||
|
group.setGroupName(request.getGroupName());
|
||||||
|
group.setChannelType(request.getChannelType());
|
||||||
|
group.setPolicies(JsonUtils.toJson(request.getPolicies()));
|
||||||
|
group.setStatus(1);
|
||||||
|
policyGroupMapper.insert(group);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolicyGroup getPolicyGroup(String tenantCode, String groupCode) {
|
||||||
|
PolicyGroup group = policyGroupMapper.selectOne(
|
||||||
|
new LambdaQueryWrapper<PolicyGroup>()
|
||||||
|
.eq(PolicyGroup::getTenantCode, tenantCode)
|
||||||
|
.eq(PolicyGroup::getGroupCode, groupCode));
|
||||||
|
if (group == null) {
|
||||||
|
throw new BusinessException("策略组不存在: " + groupCode);
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PolicyGroup> listPolicyGroups(String tenantCode) {
|
||||||
|
return policyGroupMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<PolicyGroup>()
|
||||||
|
.eq(PolicyGroup::getTenantCode, tenantCode)
|
||||||
|
.orderByDesc(PolicyGroup::getCreateTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public PolicyGroup updatePolicyGroup(String tenantCode, String groupCode, UpdatePolicyGroupRequest request) {
|
||||||
|
PolicyGroup group = getPolicyGroup(tenantCode, groupCode);
|
||||||
|
group.setGroupName(request.getGroupName());
|
||||||
|
group.setChannelType(request.getChannelType());
|
||||||
|
group.setPolicies(JsonUtils.toJson(request.getPolicies()));
|
||||||
|
policyGroupMapper.updateById(group);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public PolicyGroup updatePolicyGroupStatus(String tenantCode, String groupCode, Integer status) {
|
||||||
|
PolicyGroup group = getPolicyGroup(tenantCode, groupCode);
|
||||||
|
group.setStatus(status);
|
||||||
|
policyGroupMapper.updateById(group);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deletePolicyGroup(String tenantCode, String groupCode) {
|
||||||
|
PolicyGroup group = getPolicyGroup(tenantCode, groupCode);
|
||||||
|
policyGroupMapper.deleteById(group.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mci_message_media (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
tenant_code VARCHAR(64) NOT NULL COMMENT '所属租户',
|
||||||
|
msgid VARCHAR(128) COMMENT '关联的消息 ID',
|
||||||
|
sdkfileid VARCHAR(256) COMMENT '企微媒体文件 ID',
|
||||||
|
media_type VARCHAR(32) COMMENT '媒体类型:image / voice / video / file / emotion',
|
||||||
|
file_name VARCHAR(256) COMMENT '文件名',
|
||||||
|
file_size BIGINT COMMENT '文件大小',
|
||||||
|
md5sum VARCHAR(64) COMMENT 'MD5',
|
||||||
|
storage_type TINYINT NOT NULL DEFAULT 2 COMMENT '存储类型:2SeaweedFS',
|
||||||
|
bucket VARCHAR(128) COMMENT 'SeaweedFS bucket',
|
||||||
|
object_key VARCHAR(512) COMMENT 'SeaweedFS object key',
|
||||||
|
access_url VARCHAR(512) COMMENT '访问 URL',
|
||||||
|
status TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0未下载 1下载中 2已下载 3下载失败',
|
||||||
|
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
deleted TINYINT NOT NULL DEFAULT 0,
|
||||||
|
KEY idx_tenant_msgid (tenant_code, msgid),
|
||||||
|
KEY idx_status (status)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='媒体文件表';
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mci_conversation_create_task (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
tenant_code VARCHAR(64) NOT NULL COMMENT '所属租户',
|
||||||
|
task_type TINYINT NOT NULL DEFAULT 1 COMMENT '任务类型:1创建群聊 2邀请成员',
|
||||||
|
channel_type VARCHAR(32) NOT NULL COMMENT '渠道:wecom / wechat_personal / dingtalk / feishu',
|
||||||
|
account_id BIGINT COMMENT '使用哪个账号创建',
|
||||||
|
conversation_id BIGINT COMMENT '创建成功后回填的会话 ID',
|
||||||
|
participant_ids JSON COMMENT '参与者人员 ID 列表',
|
||||||
|
task_status TINYINT NOT NULL DEFAULT 0 COMMENT '任务状态:0待执行 1执行中 2成功 3失败',
|
||||||
|
channel_result JSON COMMENT '渠道返回结果',
|
||||||
|
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
|
||||||
|
finish_time DATETIME COMMENT '完成时间',
|
||||||
|
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
deleted TINYINT NOT NULL DEFAULT 0,
|
||||||
|
KEY idx_tenant_status (tenant_code, task_status),
|
||||||
|
KEY idx_conversation_id (conversation_id)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='建群任务表';
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mci_policy_group (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
tenant_code VARCHAR(64) NOT NULL COMMENT '所属租户',
|
||||||
|
group_code VARCHAR(64) NOT NULL COMMENT '策略组编码',
|
||||||
|
group_name VARCHAR(128) NOT NULL COMMENT '策略组名称',
|
||||||
|
channel_type VARCHAR(32) COMMENT '渠道类型:wecom / wechat_personal / dingtalk / feishu',
|
||||||
|
policies JSON NOT NULL COMMENT '策略规则 JSON',
|
||||||
|
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0禁用 1启用',
|
||||||
|
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
deleted TINYINT NOT NULL DEFAULT 0,
|
||||||
|
UNIQUE KEY uk_tenant_group_code (tenant_code, group_code, deleted),
|
||||||
|
KEY idx_tenant_status (tenant_code, status)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='策略组表';
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- 将流程类型的字符串值安全迁移为数值,之后改为 TINYINT 以对齐架构定义
|
||||||
|
UPDATE mci_flow_definition
|
||||||
|
SET flow_type = '1'
|
||||||
|
WHERE LOWER(flow_type) = 'inbound';
|
||||||
|
|
||||||
|
UPDATE mci_flow_definition
|
||||||
|
SET flow_type = '2'
|
||||||
|
WHERE LOWER(flow_type) = 'ivr';
|
||||||
|
|
||||||
|
-- 兜底:任何未识别的旧值统一按入站处理
|
||||||
|
UPDATE mci_flow_definition
|
||||||
|
SET flow_type = '1'
|
||||||
|
WHERE flow_type NOT IN ('1', '2');
|
||||||
|
|
||||||
|
ALTER TABLE mci_flow_definition
|
||||||
|
MODIFY COLUMN flow_type TINYINT NOT NULL DEFAULT 1 COMMENT '流程类型:1入站 2IVR';
|
||||||
Reference in New Issue
Block a user