Функция базы данных PostgreSQL реализует узел, который можно настроить в соответствии с должностными ролями, включая функцию многоуровневого утверждения, а также совместную проверку или проверку в процессе утверждения.
Прежде чем приступить к реализации, нам необходимо определить некоторые понятия и правила:
- Процесс утверждения состоит из нескольких узлов утверждения (узла утверждения), и каждый узел представляет собой процесс утверждения.
- Каждый узел утверждения содержит идентификатор узла, имя узла и необязательное описание узла.
- Процесс утверждения также включает в себя начальный и конечный узлы, для которых не требуется настраивать конкретных утверждающих.
- Узел утверждения может иметь несколько последующих узлов. Это означает, что после прохождения утверждения процесс продолжится до одного из этих последующих узлов.
- Для каждого узла утверждения необходимо настроить правило утверждения, которое используется для определения того, как будет продолжаться процесс (это может быть совместная проверка, коллективная проверка или утверждение одним человеком).
- Конкретное определение правил утверждения будет дано позже.
- Записи об утверждении будут записаны в отдельной таблице записей об утверждении, и каждая запись включает идентификатор узла утверждения, утверждающего, время утверждения и результат утверждения.
Используя приведенные выше правила и концепции, мы можем приступить к разработке таблиц базы данных и функций процесса утверждения. Вот возможная реализация:
Во-первых, нам нужно создать таблицу узла утверждения (ApprovalNode) для хранения всей информации узла утверждения.
CREATE TABLE ApprovalNode (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
rule TEXT NOT NULL,
next_node_ids INTEGER[]
);
Среди них поле правила представляет собой правило утверждения, которое может принимать одно из следующих трех значений:
- «ВСЕ»: правила сортировки. Указывает, что для продолжения процесса необходимо утвердить все узлы.
- «ЛЮБЫЕ»: дополнительные правила. Указывает, что если хотя бы один узел среди всех узлов одобрен, процесс может быть продолжен.
- «SINGLE»: Единое правило утверждения. Указывает, что только один утверждающий текущего узла должен утвердить процесс для продолжения.
next_node_ids указывает идентификатор следующего узла. Для последнего узла в процессе утверждения это поле пусто.
Далее нам нужно создать таблицу записей утверждения (ApprovalRecord) для записи всей информации о записях утверждения.
CREATE TABLE ApprovalRecord (
id SERIAL PRIMARY KEY,
node_id INTEGER NOT NULL,
approver TEXT NOT NULL,
approved_at TIMESTAMP NOT NULL,
approved_result BOOLEAN NOT NULL
);
Среди них node_id указывает идентификатор узла утверждения, утверждающий указывает имя утверждающего, утвержденный_at указывает время, когда утверждение было передано, а утвержденный_результат указывает, было ли одобрено одобрение.
Далее нам нужно создать функцию для запроса всех последующих идентификаторов узлов данного узла.
CREATE FUNCTION getNextNodes(node_id INTEGER)
RETURNS SETOF INTEGER
AS $$
BEGIN
RETURN QUERY SELECT unnest(next_node_ids)
FROM ApprovalNode
WHERE id = node_id;
END;
$$
LANGUAGE plpgsql;
Эта функция запрашивает все последующие идентификаторы узлов для данного узла.
Далее нам нужно создать функцию, чтобы определить, может ли указанный узел быть одобрен.
CREATE FUNCTION canApprove(node_id INTEGER)
RETURNS BOOLEAN
AS $$
DECLARE
rule_text TEXT;
approvers TEXT[];
approved_count INTEGER;
total_count INTEGER;
BEGIN
-- 查询节点的审批规则和后续节点ID
SELECT rule, ARRAY(
SELECT unnest(approver_list)
FROM ApprovalNode JOIN ApprovalRecord ON ApprovalNode.id = node_id
WHERE ApprovalNode.rule = 'SINGLE' AND ApprovalRecord.approved_result = true
), (
SELECT COUNT(DISTINCT approver)
FROM ApprovalRecord
WHERE node_id = node_id AND approved_result = true
), (
CASE
WHEN (SELECT rule FROM ApprovalNode WHERE id = node_id) = 'ALL' THEN (
SELECT COUNT(DISTINCT approver)
FROM ApprovalRecord
WHERE node_id = node_id
)
ELSE (
SELECT COUNT(*)
FROM ApprovalNode
WHERE id = ANY(next_node_ids)
)
END
)
INTO rule_text, approvers, approved_count, total_count
FROM ApprovalNode
WHERE id = node_id;
-- 判断审批规则
IF rule_text = 'ALL' AND approved_count < total_count THEN
RETURN FALSE;
ELSIF rule_text = 'SINGLE' AND approved_count = 1 THEN
RETURN TRUE;
ELSIF rule_text = 'ANY' AND approved_count > 0 THEN
RETURN TRUE;
END IF;
-- 如果需要会审,则检查是否所有已有的审批人都通过了审批
IF rule_text = 'ALL' THEN
SELECT array_agg(DISTINCT approver)
INTO approvers
FROM ApprovalRecord
WHERE node_id = node_id AND approved_result = true;
END IF;
-- 如果还有未审批通过的审批人,则返回FALSE
IF approved_count < total_count AND NOT all(i IN approvers FOR j IN approver_list WHEN i = j) THEN
RETURN FALSE;
END IF;
RETURN TRUE;
END;
$$
LANGUAGE plpgsql;
Функция этой функции — определить, может ли указанный узел пройти одобрение. Подробности реализации смотрите в комментариях к коду.
Наконец, нам нужно создать функцию для регистрации записей утверждений.
CREATE FUNCTION addApprovalRecord(node_id INTEGER, approver TEXT, approved_result BOOLEAN)
RETURNS VOID
AS $$
BEGIN
INSERT INTO ApprovalRecord(node_id, approver, approved_at, approved_result)
VALUES(node_id, approver, NOW(), approved_result);
END;
$$
LANGUAGE plpgsql;
Функция этой функции заключается в записи информации об утверждении.
На данный момент мы завершили проектирование таблиц базы данных и функций процесса утверждения. В реальном использовании мы можем написать программу, похожую на контроллер, для вызова этих функций и управления выполнением процесса утверждения. Конкретный метод реализации будет варьироваться в зависимости от конкретных требований.