/*
  过程异常管控并行审批调整
  目标：
  1. sp_创建流程_简化版 支持前端传入多个审批人，审批人ID/审批人姓名使用英文逗号分隔。
  2. 多个审批人写入同一个步骤序号的多个 processing 节点，所有审批人可同时看到待办。
  3. sp_获取待处理任务 兼容同一步骤多行节点，也兼容旧过程已写入的逗号分隔审批人ID。
  4. sp_处理审批 中任意一个审批人同意后，当前流程直接完成，并关闭同一步骤其他待处理节点。
  说明：本脚本仅定义存储过程，不插入业务数据。
*/

CREATE OR ALTER PROCEDURE [dbo].[sp_创建流程_简化版]
  @流程标题 NVARCHAR(200),
  @流程描述 NVARCHAR(MAX),
  @优先级 NVARCHAR(20) = N'normal',
  @发起人ID NVARCHAR(100),
  @发起人姓名 NVARCHAR(100),
  @审批人ID NVARCHAR(MAX),
  @审批人姓名 NVARCHAR(MAX),
  @新流程ID INT = 0,
  @已关联计划号 NVARCHAR(100) = N'',
  @零件名称 NVARCHAR(100) = N'',
  @零件编号 NVARCHAR(100) = N'',
  @工序名称 NVARCHAR(100) = N''
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @结果 INT = 0;
  DECLARE @消息 NVARCHAR(500) = N'';

  BEGIN TRY
    BEGIN TRANSACTION;

    DECLARE @审批人IDXml XML;
    DECLARE @审批人姓名Xml XML;

    SET @审批人IDXml = CAST(
      N'<i>' +
      REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@审批人ID, N''), N'&', N'&amp;'), N'<', N'&lt;'), N'>', N'&gt;'), N',', N'</i><i>') +
      N'</i>' AS XML
    );

    SET @审批人姓名Xml = CAST(
      N'<i>' +
      REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@审批人姓名, N''), N'&', N'&amp;'), N'<', N'&lt;'), N'>', N'&gt;'), N',', N'</i><i>') +
      N'</i>' AS XML
    );

    DECLARE @审批人表 TABLE (
      序号 INT IDENTITY(1, 1) PRIMARY KEY,
      审批人ID NVARCHAR(100),
      审批人姓名 NVARCHAR(100)
    );

    DECLARE @审批人ID表 TABLE (
      序号 INT IDENTITY(1, 1) PRIMARY KEY,
      审批人ID NVARCHAR(100)
    );

    DECLARE @审批人姓名表 TABLE (
      序号 INT IDENTITY(1, 1) PRIMARY KEY,
      审批人姓名 NVARCHAR(100)
    );

    INSERT INTO @审批人ID表 (审批人ID)
    SELECT NULLIF(LTRIM(RTRIM(T.C.value(N'.', N'NVARCHAR(100)'))), N'')
    FROM @审批人IDXml.nodes(N'/i') AS T(C);

    INSERT INTO @审批人姓名表 (审批人姓名)
    SELECT NULLIF(LTRIM(RTRIM(T.C.value(N'.', N'NVARCHAR(100)'))), N'')
    FROM @审批人姓名Xml.nodes(N'/i') AS T(C);

    INSERT INTO @审批人表 (审批人ID, 审批人姓名)
    SELECT I.审批人ID, ISNULL(N.审批人姓名, I.审批人ID)
    FROM @审批人ID表 I
    LEFT JOIN @审批人姓名表 N ON N.序号 = I.序号
    WHERE I.审批人ID IS NOT NULL;

    IF NOT EXISTS (SELECT 1 FROM @审批人表)
    BEGIN
      INSERT INTO @审批人表 (审批人ID, 审批人姓名)
      VALUES (@发起人ID, @发起人姓名);
    END;

    INSERT INTO [dbo].[流程表] (
      流程标题,
      流程描述,
      优先级,
      状态,
      发起人ID,
      发起人姓名,
      当前节点,
      当前步骤,
      总步骤数,
      已关联计划号,
      零件名称,
      零件编号,
      工序名称,
      创建时间,
      更新时间
    )
    VALUES (
      @流程标题,
      @流程描述,
      ISNULL(NULLIF(@优先级, N''), N'normal'),
      N'processing',
      @发起人ID,
      @发起人姓名,
      N'异常审批',
      1,
      1,
      ISNULL(@已关联计划号, N''),
      ISNULL(@零件名称, N''),
      ISNULL(@零件编号, N''),
      ISNULL(@工序名称, N''),
      GETDATE(),
      GETDATE()
    );

    SET @新流程ID = SCOPE_IDENTITY();

    INSERT INTO [dbo].[流程节点表] (
      流程ID,
      节点名称,
      审批人ID,
      审批人姓名,
      步骤序号,
      状态,
      是否转办
    )
    SELECT
      @新流程ID,
      N'异常审批',
      审批人ID,
      审批人姓名,
      1,
      N'processing',
      0
    FROM @审批人表;

    SET @结果 = 1;
    SET @消息 = N'流程创建成功，流程ID: ' + CAST(@新流程ID AS NVARCHAR(20));

    COMMIT TRANSACTION;
  END TRY
  BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
    SET @结果 = 0;
    SET @消息 = N'错误: ' + ERROR_MESSAGE();
  END CATCH;

  SELECT @结果 AS 结果, @消息 AS 消息, @新流程ID AS 新流程ID;
END;
GO

CREATE OR ALTER PROCEDURE [dbo].[sp_获取待处理任务]
  @审批人ID NVARCHAR(100)
AS
BEGIN
  SET NOCOUNT ON;

  SELECT
    p.流程ID,
    p.流程标题,
    p.流程描述,
    p.优先级,
    p.状态,
    p.发起人姓名 AS 申请人,
    p.创建时间 AS 申请时间,
    p.已关联计划号,
    p.零件名称,
    p.零件编号,
    p.工序名称,
    pn.节点ID,
    pn.节点名称 AS 当前节点,
    pn.是否转办
  FROM [dbo].[流程节点表] pn
  INNER JOIN [dbo].[流程表] p ON p.流程ID = pn.流程ID
  WHERE pn.状态 = N'processing'
    AND p.状态 = N'processing'
    AND (
      pn.审批人ID = @审批人ID
      OR CHARINDEX(N',' + @审批人ID + N',', N',' + REPLACE(ISNULL(pn.审批人ID, N''), N'，', N',') + N',') > 0
    )
  ORDER BY p.更新时间 DESC, p.创建时间 DESC;
END;
GO

CREATE OR ALTER PROCEDURE [dbo].[sp_处理审批]
  @流程ID INT,
  @节点ID INT,
  @审批人ID NVARCHAR(100),
  @审批人姓名 NVARCHAR(100),
  @处理结果 NVARCHAR(20),
  @审批意见 NVARCHAR(MAX) = N'',
  @成功 BIT = 0
AS
BEGIN
  SET NOCOUNT ON;
  SET @成功 = 0;

  BEGIN TRY
    BEGIN TRANSACTION;

    DECLARE @当前步骤 INT;

    SELECT @当前步骤 = 步骤序号
    FROM [dbo].[流程节点表]
    WHERE 节点ID = @节点ID
      AND 流程ID = @流程ID
      AND 状态 = N'processing';

    IF @当前步骤 IS NULL
    BEGIN
      RAISERROR(N'待处理节点不存在或已处理。', 16, 1);
    END;

    INSERT INTO [dbo].[审批记录表] (
      流程ID,
      节点ID,
      审批人ID,
      审批人姓名,
      处理结果,
      审批意见
    )
    VALUES (
      @流程ID,
      @节点ID,
      @审批人ID,
      @审批人姓名,
      @处理结果,
      ISNULL(@审批意见, N'')
    );

    IF @处理结果 = N'approved'
    BEGIN
      UPDATE [dbo].[流程节点表]
      SET 状态 = N'approved'
      WHERE 流程ID = @流程ID
        AND 步骤序号 = @当前步骤
        AND 状态 = N'processing';

      UPDATE [dbo].[流程表]
      SET 状态 = N'completed',
          当前节点 = N'已完成',
          更新时间 = GETDATE()
      WHERE 流程ID = @流程ID;

      IF COL_LENGTH(N'dbo.流程表', N'完成人') IS NOT NULL
      BEGIN
        EXEC sp_executesql
          N'UPDATE [dbo].[流程表] SET 完成人 = @p审批人姓名 WHERE 流程ID = @p流程ID',
          N'@p审批人姓名 NVARCHAR(100), @p流程ID INT',
          @p审批人姓名 = @审批人姓名,
          @p流程ID = @流程ID;
      END;

      IF COL_LENGTH(N'dbo.流程表', N'完成时间') IS NOT NULL
      BEGIN
        EXEC sp_executesql
          N'UPDATE [dbo].[流程表] SET 完成时间 = GETDATE() WHERE 流程ID = @p流程ID',
          N'@p流程ID INT',
          @p流程ID = @流程ID;
      END;
    END
    ELSE IF @处理结果 = N'rejected'
    BEGIN
      UPDATE [dbo].[流程节点表]
      SET 状态 = N'rejected'
      WHERE 流程ID = @流程ID
        AND 步骤序号 = @当前步骤
        AND 状态 = N'processing';

      UPDATE [dbo].[流程表]
      SET 状态 = N'rejected',
          当前节点 = N'已拒绝',
          更新时间 = GETDATE()
      WHERE 流程ID = @流程ID;
    END
    ELSE
    BEGIN
      UPDATE [dbo].[流程节点表]
      SET 状态 = @处理结果
      WHERE 节点ID = @节点ID;
    END;

    SET @成功 = 1;
    COMMIT TRANSACTION;
  END TRY
  BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
    SET @成功 = 0;
    THROW;
  END CATCH;

  SELECT @成功 AS 成功;
END;
GO
