Добавление лайков, дизлайков, рейтингов, голосование

Компонент голосования за элемент позволяет быстро внедрить в систему возможность получения отклика по элементам. 

Голосовать могут только авторизованные пользователи. За каждый отдельный элемент можно голосовать 1 раз. 

Есть 3 режима (задается в типе Лайка as_like_types в поле mode): 

При этом состояние лайков по элементам хранится в таблице as_like_items (по itemID, code). 

В таблице as_like_log хранятся все голосования пользователей.

Сниппеты разметки: 

Лайки
<div class="as-like" data-code="lead" data-itemid="111"></div>
<div class="as-like" data-code="lead" data-itemid="222"></div>
Плюс минус
<div class="as-like" data-code="ticket" data-itemid="333"></div>
<div class="as-like" data-code="ticket" data-itemid="444"></div>

Звезды
<div class="as-like" data-code="product" data-itemid="555"></div>
<div class="as-like" data-code="product" data-itemid="666"></div>

Параметры: 

Структура данных в БД (SQL):  https://pastebin.com/J9gUmXCF

Для корректной работы системы необходимо, чтобы в базе были 2 процедуры: request_like_get и request_like_rate

Пример get: 

ALTER PROCEDURE [dbo].[request_like_get]
	@parameters ExtendedDictionaryParameter READONLY,
	@username nvarchar(32)
AS
BEGIN
	declare @items nvarchar(max)
	select @items = Value2 from @parameters where [Key]='items'

	declare @table table(code nvarchar(128), itemID int)

	insert into @table
	select
		dbo.str_splitPart(Value, '|', 1) code,
		try_cast(dbo.str_splitPart(Value, '|', 2) as int) itemID
	from dbo.split(@items, ',')
	where len(value)>0

    -- SELECT 1 Msg, Result
	select 'Все ок' Msg, 1 Result

    -- SELECT 2 Основные данные в виде произвольной таблицы

	select
	code,
	itemID,
	isnull((select mode from as_like_types where code=t1.code), '') mode,
	isnull((select value from as_like_items
		where typeID in (select id from as_like_types where code=t1.code)
			and itemID = t1.itemID), '') value,
	(select top 1 value from as_like_log
		where username = @username
			and typeID in (select id from as_like_types where code=t1.code)
			and itemID = t1.itemID
		order by id desc) myValue
	from @table t1
     -- SELECT 3 Внешние действия

END

Пример rate: 

ALTER PROCEDURE [dbo].[request_like_rate]
	@parameters ExtendedDictionaryParameter READONLY,
	@username nvarchar(32)
AS
BEGIN
	if(@username='') begin
		select 0 Result, 'Для простановки оценки необходимо авторизоваться!' Msg
		return
	end
	declare @itemID int
	select @itemID = try_cast(Value2 as int) from @parameters where [Key]='itemID'

	declare @code nvarchar(max), @typeID int, @mode nvarchar(128)
	select @code = Value2 from @parameters where [Key]='code'
	select @typeID = id, @mode = mode from as_like_types where code=@code


	declare @value int
	select @value = try_cast(Value2 as int) from @parameters where [Key]='value'

	if(@mode='like' and @value not in (0,1)
		or @mode='plusMinus' and @value not in (-1,1)
		or @mode='rating' and @value not in (1,2,3,4,5)
	) begin
		select 'Invalid data for mode '+@mode Msg, 0 Result
		return
	end


	declare @logID int
	select @logID =  id from as_like_log
	where itemID=@itemID
		and username=@username
		and typeID =@typeID

	declare @likeItemID int, @curValue float, @newValue float
	select @likeItemID = id, @curValue = value from as_like_items 
        where typeID = @typeID and itemID = @itemID

	if(@logID is null) begin
		insert into as_like_log(typeID, itemID, created, username, value)
		values(@typeID, @itemID, getdate(), @username, @value)
	end else begin
		update as_like_log set created =getdate(), value=@value where id = @logID
	end
	if(@mode='like' or @mode='plusMinus') begin
		set @newValue = isnull((select sum(value) 
from as_like_log where itemID = @itemID and typeID = @typeID) , 0)
	end else begin
		set @newValue = isnull((select sum(value) / nullif(cast(count(value) as float), 0) 
from as_like_log where itemID = @itemID and typeID = @typeID) , 0)
	end

	if(@likeItemID is not null) begin
		update as_like_items set modified = getdate(), value = @newValue
		where id = @likeItemID
	end else begin
		insert into as_like_items(typeID, itemID, value, modified)
		values(@typeID, @itemID, @value,  getdate())
	end

	-- SELECT 1 Msg, Result
	select '' Msg, 1 Result

    -- SELECT 2 Основные данные в виде произвольной таблицы

	select @newValue value
	 -- SELECT 3 Внешние действия

END

Примечание: 

  1. Для уменьшения звездочек можно использовать класс as-like-rating-small рядом с as-like
Страница-источник на сайте falconspace.ru