Выгода от использования Falcon Space
В 2-3 раза экономнее и быстрее, чем заказная разработка
Более гибкая, чем коробочные решения и облачные сервисы
Используйте готовые решения и изменяйте под свои потребности
Как отслеживать историю действий пользователя или историю событий по объекту системы
Очень удобно иметь некий отчет, в котором есть все действия в хронологическом порядке, связанные с определенным объектом или субъектом.
Это может быть заказ в системе, действия определенного лица, или события связанные с активностью лиц определенного отдела.
Как организовать сбор данных и их вывод для анализа?
Решение:
1. Все данные храним в таблицах логов по определенным объектам со ссылками на пользователя, связанные объекты (например, заказ). Таких таблиц может быть много. Суть в том, чтобы сохранить факт действия в структурированном виде с нужными связями по данным.
Не нужно пытаться сохранять (с дублированием) в лог конкретного человека. Это негибко, сложно менять и приводит к избытку информации - данные по сути приходится дублировать для разных типов логов.
Обычно таблица подобного журнала будет иметь следующие поля - дата, кто создал, статус, примечание.
Таблицы логов заполняются в SaveItem формы, при смене статусов сущности (as-entities), операциях таблицы, поиск или любых других местах в коде.
2. Создаем таблицу, на входе будет код сущности и ее itemID. Это может быть человек в системе, заказ в системе или что-то еще.
Таблица имеет всегда единую структуру:
- id - идентификатор события (если используется универсальная структура, то это что-то вроде human_ivanov, order_123)
- created - дата, время события и сколько времени прошло с этого момента
- type - тип это иконка с указанием цвета. Иконка задает тип события - для человека это может быть Занесение времени в таймлог, Смена статуса задачи, Вход-Выход, Создание задачи т.д.
- username - это пользователь, с которым связано данное действие. Например, для заказа это может быть тот, кто создал заказ, кто подтвердил заказ и т.д.
3. В рамках самой процедуры построения заказа на входе мы имеем временную таблицу со единой структурой, которая затем выводится по стандартной обработке.
CREATE TABLE #actionLog ( id nvarchar(64) primary key,
username nvarchar(128), title nvarchar(256), text nvarchar(max),
created datetime, typeCode nvarchar(64), itemID int, color nvarchar(20),
icon nvarchar(32), iconColor nvarchar(20) )
- id - идентификатор действия
- username - cвязанное действие
- title, text - описание события
- created - когда было событие
- typeCode - код типа события (например newTicket)
- itemID - ID связанной сущности (например ticketID)
- color - маркет цвета у названия (например #f00)
- icon - иконка Font Awesome (например fa fa-bars)
- iconColor - цвет иконки (#f00)
Таким образом, основная задача заключается в наполнении этой временной таблицы данными из разных таблиц логов, которая затем и выводится пользователю.
4. Сниппет таблицы:
<a href="#" class="as-table-modal" data-code="actionLog" data-itemid="human_5017" data-big="1" title="Лог по пользователю" data-title="Лог по пользователю">
<i class="fa fa-clock"></i>
</a>
human_5017 - говорит нам о том, что это будет лог по человеку с ID=5017, данный параметр должен быть обработан в самой процедуре, а также проверены права пользователя на возможность просмотра этих данных.
Полный вариант процедуры:
CREATE PROCEDURE [dbo].[crud_actionLog_getItems]
@filters CRUDFilterParameter READONLY,
@sort sql_variant,
@direction nvarchar(8),
@page int,
@pageSize int,
@username nvarchar(32)
AS
BEGIN
declare @minDate datetime = dateadd(day, -7, getdate())
declare @us nvarchar(128) = '', @type nvarchar(20), @itemID int
-- filters...
declare @filterTitle nvarchar(128)
select @filterTitle = Value from @filters where [Key] = 'title'
declare @filterDate nvarchar(128),@createdFrom date = NULL, @createdTo date = NULL
select @filterDate = Value from @filters where [Key] = 'created'
select @createdFrom = min(try_convert(date,value,104)) from split(@filterDate, '-')
select @createdTo = max(try_convert(date,value,104)) from split(@filterDate, '-')
declare @filterItemID nvarchar(128)
select @filterItemID = Value from @filters where [Key] = 'itemID'
set @type = dbo.str_splitPart(@filterItemID, '_',1)
set @itemID = try_cast(dbo.str_splitPart(@filterItemID, '_',2) as int)
IF OBJECT_ID('tempdb..#actionLog') IS NOT NULL begin
DROP TABLE #actionLog
end
CREATE TABLE #actionLog ( id nvarchar(64) primary key, username nvarchar(128), title nvarchar(256), text nvarchar(max),
created datetime, typeCode nvarchar(64), itemID int, color nvarchar(20),
icon nvarchar(32), iconColor nvarchar(20) )
-- извлекаем данные для таблицы
if(@type='human') begin
select @us = username from hr_humans where id = @itemID
-- createTicket
insert into #actionLog
select top 100 'createTicket_' + cast(id as nvarchar) id,
createdBy username,
'Создал задачу #' + cast(id as nvarchar) + ' ' + name +
' (' + (select top 1 name from tt_projects where id = t.projectID)+ ')' title,
name text,
createdDate created, 'createTicket' typeCode, id itemID, '' color, 'fas fa-ticket-alt' icon, '' iconColor
from tt_tickets t
where createdDate > @minDate and createdBy = @us
order by id desc
end
-- SELECT 1 - выходной результат
select * from (
select top 1000
created hide_created,
isnull([id], '') [id],
isnull([username], '') [username],
isnull([title], '') [title],
iif(len(color)>0, color, '') marker_title,
isnull([text], '') [desc_title],
isnull(convert(nvarchar(10),[created], 104), '') + ''+convert(nvarchar(5), [created], 108) +'' [created],
dbo.as_timeDelay(datediff(minute, created, getdate())) + ' назад' desc_created,
iif(len(icon)>0, '0, ' style="color: '+iconColor+'" ', '' )+'>', '') [type]
from #actionLog
where (@filterTitle is null or @filterTitle ='' or title like '%'+@filterTitle+'%' or [text] like '%'+@filterTitle+'%')
--and (@createdFrom is null or @createdTo is null or (created between @createdFrom and @createdTo))
order by created desc
)t1
order by hide_created desc
OFFSET @PageSize * (@Page - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY;
-- SELECT 2
select count(*) from #actionLog
-- SELECT 3
select 1 Compact, '12px' FontSize, 'light' theme, 1 HideTitleCount
/*Select '' Title,
'' ToolbarAdditional,
'' GroupOperationsToolbar,
'' EmptyText,
'' FastCreateLinkText, '' FastCreateDialogHeader, '' FastCreateDialogPlaceholder,
0 FastCreateSearch, 0 FastCreateTextarea,
0 HideTitleCount,
0 DisableCellTitle,
'10px' FontSize,
'{filterCode}' FilterMakeup,
1 InstantFilter,
*/
-- 4 SELECT Footer data or kanban/gantt data
drop table #actionLog
END
Таким образом, можно собирать данные из разных разрозненных таблиц логов и выводить их в формате единой истории по определенному объекту системы.
Google поиск по нашей документации
- Шаг 1. Создать концепт проекта
- Шаг 2. Получить оценку бюджета (КП)
- Шаг 3. Заключить договор
- Шаг 4. Создать совместно техническое задание
- Шаг 5. Поэтапная реализация проекта