%%-----------------------------------------------------------------------------
%% @Module  :       lib_supplication.erl
%% @Author  :       WJQ
%% @Created :       2019-04-02
%% @Description:    祈愿
%%-----------------------------------------------------------------------------
-module (lib_supplication).

-include ("server.hrl").
-include ("supplication.hrl").
-include ("figure.hrl").
-include ("common.hrl").
-include ("errcode.hrl").
-include ("goods.hrl").
-include ("def_module.hrl").
-include ("custom_act.hrl").
-include ("def_fun.hrl").

-export ([
	login/2					%% 登录
	,send_info/1			%% 发送主界面信息
	,change_select_reward/2	%% 更换奖励
	,supplication/1			%% 祈愿
	,receive_reward/2		%% 领取奖励
	,send_broadcast/4		%% 发送广播
	,send_task_status/1		%% 发送任务状态
]).

-export ([
	get_act_cfg_info/1		%% 获取开启中的活动信息
	,do_supplication/7		%% 祈愿
	,trigger/6				%% 触发器
]).

-export ([
	db_update_supplication_task/5
	,db_replace_supplication_task/7
]).

%% ================================================== Login Start ==================================================
login(RoleId, Lv) ->
	case get_act_cfg_info([role_lv, task]) of
		false ->
			#supplication{};
		{ok, OpenSubType, StartTime, EndTime, [OpenLv, TaskList]} when Lv >= OpenLv, is_list(TaskList) ->
			NowTime = utime:unixtime(),
			NowDate = utime:unixdate(),
			DBTaskList = db_get_all_supplication_task(RoleId),
			PlayerTaskList = init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, DBTaskList, []),
			case db_get_supplication(RoleId) of
				[[SubType, SSelfLog, SSelectReward, Count, SCounter, Time]|_] ->
					case SubType == OpenSubType andalso Time >= StartTime andalso Time < EndTime of
						true ->
							Counter = util:bitstring_to_term(SCounter),
							SelectReward = util:bitstring_to_term(SSelectReward),
							SelfLog = util:bitstring_to_term(SSelfLog);
						false ->
							Counter = util:bitstring_to_term(SCounter),
							SelectReward = init_select_reward(OpenSubType),
							SelfLog = []
					end;
				_ ->
					Count = 0,
					Counter = [],
					SelectReward = init_select_reward(OpenSubType),
					SelfLog = []
			end,
			db_replace_supplication(RoleId, OpenSubType, SelfLog, SelectReward, Count, Counter, NowTime),
			#supplication{
				sub_type = OpenSubType, self_log = SelfLog, select_reward = SelectReward,
				task_list = PlayerTaskList, count = Count, counter = Counter, time = NowTime
			};
		{ok, OpenSubType, StartTime, EndTime, [_OpenLv, TaskList]} ->
			NowDate = utime:unixdate(),
			DBTaskList = db_get_all_supplication_task(RoleId),
			PlayerTaskList = init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, DBTaskList, []),
			#supplication{task_list = PlayerTaskList};
		_ ->
			#supplication{}
	end.

%% 初始化任务数据
init_supplication_task(_RoleId, _OpenSubType, _StartTime, _EndTime, _NowDate, [], _DBTaskList, AccList) -> AccList;
init_supplication_task(_RoleId, _OpenSubType, _StartTime, _EndTime, _NowDate, _TaskList, [], AccList) -> AccList;
init_supplication_task(
	RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList,
	[[TaskId, SubType, Progress, SExtra, TaskStatus, Time]|T], AccList
) when OpenSubType == SubType, Time >= StartTime, Time < EndTime ->
	case utime:is_same_day(Time, NowDate) of
		true -> %% 是今天的任务
			case lists:keyfind(TaskId, 1, TaskList) of
				false -> %% 任务被删除
					db_delete_supplication_task(RoleId, TaskId),
					init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, T, AccList);
				_ ->
					Extra = util:bitstring_to_term(SExtra),
					TaskProgress = #task_progress{
						task_id = TaskId, sub_type = SubType, progress = Progress, extra = Extra,
						task_status = TaskStatus, time = Time
					},
					NewAccList = [TaskProgress|AccList],
					init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, T, NewAccList)
			end;
		false -> %% 之前的任务
			db_delete_supplication_task(RoleId, TaskId),
			init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, T, AccList)
	end;
init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, [_H|T], AccList) ->
	init_supplication_task(RoleId, OpenSubType, StartTime, EndTime, NowDate, TaskList, T, AccList).
%% =================================================== Login End ===================================================

%% 发送主界面相关信息
send_info(PS) ->
	#player_status{id = RoleId, server_num = ServerNum, figure = Figure, supplication = Supplication} = PS,
	#figure{lv = Lv} = Figure,
	#supplication{
		sub_type = SubType, self_log = SelfLog, task_list = TaskList, select_reward = SelectReward,
		time = Time, count = Count, counter = Counter
	} = Supplication,
	case get_act_cfg_info([role_lv, task]) of
		{ok, OpenSubType, Stime, Etime, [OpenLv, Task]} when Lv >= OpenLv ->
			PackTaskList = pack_task_list(TaskList, Task, OpenSubType, Stime, Etime),
			RewardIds = lib_custom_act_util:get_act_reward_grade_list(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType),
			case SubType == OpenSubType andalso Time >= Stime andalso Time =< Etime of
				true -> %% 有效数据
					case pack_reward_list(SelectReward, OpenSubType, RewardIds, []) of
						PackRewardList when is_list(PackRewardList), PackRewardList =/= [] ->
							NewPS = PS;
						_ ->
							NowTime = utime:unixtime(),
							NewSelectReward = init_select_reward(OpenSubType),
							PackRewardList = pack_reward_list(NewSelectReward, OpenSubType, RewardIds, []),
							db_replace_supplication(RoleId, OpenSubType, SelfLog, NewSelectReward, Count, Counter, NowTime),
							NewSupplication = Supplication#supplication{sub_type = OpenSubType, select_reward = NewSelectReward, time = NowTime},
							NewPS = PS#player_status{supplication = NewSupplication}
					end;
				false -> %% 无效数据
					NowTime = utime:unixtime(),
					NewSelectReward = init_select_reward(OpenSubType),
					PackRewardList = pack_reward_list(NewSelectReward, OpenSubType, RewardIds, []),
					db_replace_supplication(RoleId, OpenSubType, SelfLog, NewSelectReward, Count, Counter, NowTime),
					NewSupplication = Supplication#supplication{sub_type = OpenSubType, select_reward = NewSelectReward, time = NowTime},
					NewPS = PS#player_status{supplication = NewSupplication}
			end,
			case is_list(PackRewardList) andalso PackRewardList =/= [] of
				true ->
					mod_local_supplication:send_info(RoleId, OpenSubType, ServerNum, Count, SelfLog, PackTaskList, PackRewardList);
				false ->
					?ERR("miss supplication reward cfg!!!~n", []),
					lib_custom_act:send_error_code(RoleId, ?ERRCODE(system_busy))
			end;
		_ ->
			NewPS = PS
	end,
	{ok, NewPS}.

pack_reward_list([], _OpenSubType, _RewardIds, Acc) -> Acc;
pack_reward_list([{RewardLv, RewardList}|T], OpenSubType, RewardIds, Acc) ->
	case pack_reward_list_helper(RewardList, RewardLv, OpenSubType, RewardIds, []) of
		{ok, PackList} ->
			pack_reward_list(T, OpenSubType, RewardIds, PackList++Acc);
		_ ->
			{false, ?FAIL}
	end;
pack_reward_list(_SelectReward, _OpenSubType, _RewardIds, _Acc) ->
	{false, ?FAIL}.

pack_reward_list_helper([], _RewardLv, _OpenSubType, _RewardIds, Acc) -> {ok, Acc};
pack_reward_list_helper([{Weight, {PosId, RewardId}}|T], RewardLv, OpenSubType, RewardIds, Acc) ->
	case lists:member(RewardId, RewardIds) of
		true ->
			case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType, RewardId) of
				#custom_act_reward_cfg{condition = Condition} ->
					case lib_custom_act_check:check_act_condtion([reward_lv, weight], Condition) of
						[RewardLv, Weight] ->
							pack_reward_list_helper(T, RewardLv, OpenSubType, RewardIds, [{PosId, RewardId}|Acc]);
						_ ->
							{false, ?FAIL}
					end;
				_ ->
					{false, ?FAIL}
			end;
		false ->
			{false, ?FAIL}
	end;
pack_reward_list_helper(_RewardList, _RewardLv, _OpenSubType, _RewardIds, _Acc) ->
	{false, ?FAIL}.

pack_task_list(TaskList, Task, OpenSubType, Stime, Etime) ->
	F = fun(#task_progress{task_id = TaskId, task_status = TaskStatus, progress = Progress, sub_type = SubType, time = Time}, AccList) ->
		case SubType == OpenSubType andalso Time >= Stime andalso Time < Etime of
			true ->
				case lists:keyfind(TaskId, 1, Task) of
					false -> AccList;
					_ -> [{TaskId, TaskStatus, Progress}|AccList]
				end;
			false ->
				AccList
		end
	end,
	lists:foldl(F, [], TaskList).

%% 随机生成奖励列表
init_select_reward(OpenSubType) ->
	%% 获取所有奖励列表 [{奖励等级, [{权重, 奖励ID},...]},...]
	RewardIds = lib_custom_act_util:get_act_reward_grade_list(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType),
	F = fun(RewardId, Acc) ->
		case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType, RewardId) of
			#custom_act_reward_cfg{condition = Condition} ->
				case lib_custom_act_check:check_act_condtion([reward_lv, weight], Condition) of
					[RewardLv, Weight] ->
						case lists:keyfind(RewardLv, 1, Acc) of
							{RewardLv, List} ->
								lists:keyreplace(RewardLv, 1, Acc, {RewardLv, [{Weight, RewardId}|List]});
							_ ->
								[{RewardLv, [{Weight, RewardId}]}|Acc]
						end;
					_ -> Acc
				end;
			_ -> Acc
		end
	end,
	AllRewardList = lists:foldl(F, [], RewardIds),
	%% 根据奖励等级依次随机奖励
	RewardLvs = ?SUPPLICATION_REWARD_LV_LIST,
	F2 = fun(RewardLv, AccList) ->
		case lists:keyfind(RewardLv, 1, AllRewardList) of
			false -> AccList;
			{RewardLv, UseRewardList} ->
				RandRewardList = urand:get_rand_list(get_select_num(RewardLv), UseRewardList),
				[{RewardLv, RandRewardList}|AccList]
		end
	end,
	TempList = lists:foldl(F2, [], RewardLvs),
	init_reward_pos_id(TempList).

%% 获取可选取数量
get_select_num(RewardLv) ->
	case RewardLv of
		0 -> 1;		%% 特等奖
		1 -> 2;		%% 一等奖
		2 -> 3;		%% 二等奖
		3 -> 4;		%% 三等奖
		_ -> 0		%% 无
	end.

%% 为奖励初始化位置
%% [{RewardLv, {Weight, RewardId},...},...] => [{RewardLv, {Weight, {PosId, RewardId}},...},...]
init_reward_pos_id([]) -> [];
init_reward_pos_id(RewardList) ->
	F1 = fun({Weight, RewardId}, {AccNum, AccList1}) ->
		{AccNum+1, [{Weight, {AccNum, RewardId}}|AccList1]}
	end,
	F2 = fun({RewardLv, RewardIds}, AccList2) ->
		StartNum = get_start_num(RewardLv),
		{_AccNum, NewRewardIds} = lists:foldl(F1, {StartNum, []}, RewardIds),
		[{RewardLv, NewRewardIds}|AccList2]
	end,
	lists:foldl(F2, [], RewardList).

%% 获取奖励等级开始位置
get_start_num(RewardLv) ->
	case RewardLv of
		0 -> 1;
		1 -> 2;
		2 -> 4;
		3 -> 7;
		_ -> 1
	end.

%% 更换奖励
change_select_reward(PS, RewardIds) ->
	#player_status{id = RoleId, figure = Figure, supplication = Supplication} = PS,
	#figure{lv = Lv} = Figure,
	#supplication{sub_type = SubType, self_log = SelfLog, count = Count, counter = Counter} = Supplication,
	case get_act_cfg_info([role_lv]) of
		{ok, OpenSubType, _Stime, _Etime, [OpenLv]} ->
			CheckList = [{reach_open_lv, Lv, OpenLv}, {select_reward_num_correct, RewardIds}, {difference_reward_id, RewardIds}, {pos_id_correct, OpenSubType, RewardIds}],
			case check(CheckList) of
				true ->
					RewardLvs = ?SUPPLICATION_REWARD_LV_LIST,
					CheckLvList = make_reward_lv_list(RewardLvs, []),
					case format_reward(RewardIds, OpenSubType, CheckLvList, []) of
						{ok, NewSelectReward} ->
							Code = ?SUCCESS,
							NowTime = utime:unixtime(),
							db_replace_supplication(RoleId, SubType, SelfLog, NewSelectReward, Count, Counter, NowTime),
							NewSupplication = Supplication#supplication{select_reward = NewSelectReward, time = NowTime},
							NewPS = PS#player_status{supplication = NewSupplication};
						{error, Code} ->
							NewPS = PS
					end;
				{false, Code} ->
					NewPS = PS
			end;
		_ ->
			OpenSubType = 0,
			Code = ?ERRCODE(err331_act_closed),
			NewPS = PS
	end,
	{ok, Bin} = pt_331:write(33198, [Code, OpenSubType]),
	lib_server_send:send_to_uid(RoleId, Bin),
	{ok, NewPS}.

%% @return [{奖励等级, 需要选择的数量},...]
make_reward_lv_list([], AccList) ->
	AccList;
make_reward_lv_list([RewardLv|T], AccList) ->
	SelectNum = get_select_num(RewardLv),
	make_reward_lv_list(T, [{RewardLv, SelectNum}|AccList]).

format_reward([], _SubType, [], AccList) -> {ok, AccList};
format_reward([], _SubType, _CheckLvList, _AccList) -> {error, ?FAIL};
format_reward([{PosId, RewardId}|T], SubType, CheckLvList, AccList) ->
	case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, SubType, RewardId) of
		#custom_act_reward_cfg{condition = Condition} ->
			case lib_custom_act_check:check_act_condtion([reward_lv, weight], Condition) of
				[RewardLv, Weight] ->
					case lists:keyfind(RewardLv, 1, AccList) of
						{RewardLv, RewardIds} ->
							NewAccList = lists:keyreplace(RewardLv, 1, AccList, {RewardLv, [{Weight, {PosId, RewardId}}|RewardIds]});
						_ ->
							NewAccList = [{RewardLv, [{Weight, {PosId, RewardId}}]}|AccList]
					end,
					case lists:keyfind(RewardLv, 1, CheckLvList) of
						{RewardLv, Num} when Num > 1 ->
							NewCheckLvList = lists:keyreplace(RewardLv, 1, CheckLvList, {RewardLv, Num-1}),
							format_reward(T, SubType, NewCheckLvList, NewAccList);
						{RewardLv, Num} when Num == 1 ->
							NewCheckLvList = lists:keydelete(RewardLv, 1, CheckLvList),
							format_reward(T, SubType, NewCheckLvList, NewAccList);
						_ ->
							{error, ?FAIL}
					end;
				_ ->
					{error, ?ERRCODE(err_config)}
			end;
		_ ->
			{error, ?ERRCODE(data_error)}
	end;
format_reward(_RewardIds, _SubType, _CheckLvList, _AccList) -> {error, ?FAIL}.

%% 祈愿
supplication(PS) ->
	#player_status{id = RoleId, figure = Figure} = PS,
	#figure{lv = Lv} = Figure,
	case get_act_cfg_info([role_lv, cost_day, supplication_cost]) of
		{ok, OpenSubType, _STime, _Etime, [OpenLv, CostDay, Cost]} ->
			CheckList = [{reach_open_lv, Lv, OpenLv}, {is_cost_day, CostDay}, {goods_num_enough, PS, Cost}, {cell_num_enough, PS}, {select_reward_correct, OpenSubType, PS}],
			case check(CheckList) of
				true ->
					mod_local_supplication:supplication(RoleId);
				{false, ErrCode} ->
					{ok, Bin} = pt_331:write(33199, [ErrCode, OpenSubType, 0, 0, 0]),
					lib_server_send:send_to_uid(RoleId, Bin)
			end;
		_ ->
			{ok, Bin} = pt_331:write(33199, [?ERRCODE(err331_act_closed), 0, 0, 0, 0]),
			lib_server_send:send_to_uid(RoleId, Bin)
	end.

%% @return {ok, #player_status{}}
do_supplication(PS, OpenSubType, Cost, MaxCount, GuarantyLv, RewardLimit, GlobalCounter) ->
	#player_status{id = RoleId, server_num = ServerNum, supplication = Supplication} = PS,
	#supplication{select_reward = SelectReward, count = Count, counter = PersonalCounter} = Supplication,
	Counter = GlobalCounter ++ PersonalCounter,
	{F, NewCount} = get_filter_reward_func(Count, MaxCount, GuarantyLv, Counter, RewardLimit),
	UseRewardList = lists:foldl(F, [], SelectReward),			%% 抽奖列表[{Weight, {PosId, RewardId}}...]
	[{PosId, RewardId}] = urand:list_rand_by_weight(UseRewardList, 1),	%% 抽奖
	ActInfo = lib_custom_act_util:get_custom_act_open_info(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType),
	case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType, RewardId) of
		#custom_act_reward_cfg{condition = Condition, name = RewardLvStr} = RewardCfg when is_record(ActInfo, act_info) ->
			case lib_custom_act_check:check_act_condtion([broadcast, reward_lv], Condition) of
				[Broadcast, RewardLv] -> ok;
				_ ->
					Broadcast = 0,
					RewardLv = 0
			end,
			RewardList = lib_custom_act_util:count_act_reward(PS, ActInfo, RewardCfg),
			case lib_goods_api:can_give_goods(PS, RewardList) of
				true ->
					case lib_goods_api:cost_object_list_with_check(PS, Cost, supplication, "") of
						{true, TempPS,_} ->
							NewPersonalCounter = updata_reward_counter(RewardLv, RewardLimit, PersonalCounter),
							{ok, Bin} = pt_331:write(33199, [?SUCCESS, OpenSubType, PosId, RewardId, ServerNum]),
							lib_server_send:send_to_uid(RoleId, Bin),
							NewPS = do_send_supplication_reward(TempPS, RewardId, RewardLv, Cost, RewardList, NewCount, NewPersonalCounter),
							do_supplication_broadcast(NewPS, RewardId, RewardLvStr, RewardList, Broadcast),
							{ok, NewPS};
						{false, Code, NewPS} -> %% 扣除物品失败
							{ok, Bin} = pt_331:write(33100, [Code]),
							lib_server_send:send_to_uid(RoleId, Bin),
							{ok, NewPS}
					end;
				false -> %% 背包空间不足
					{ok, Bin} = pt_331:write(33100, [?ERRCODE(err150_no_cell)]),
					lib_server_send:send_to_uid(RoleId, Bin),
					{ok, PS}
			end;
		_ ->
			{ok, Bin} = pt_331:write(33100, [?ERRCODE(err_config)]),
			lib_server_send:send_to_uid(RoleId, Bin),
			{ok, PS}
	end.

get_filter_reward_func(Count, MaxCount, GuarantyLv, Counter, RewardLimit) ->
	case Count + 1 >= MaxCount of
		true ->	%% 保底祈愿
			F = fun({RewardLv, RewardList}, Acc) ->
				case RewardLv =< GuarantyLv of  %% 注意！！！ 奖励等级越小稀有度越高
					true ->
						case lists:keyfind(RewardLv, 1, Counter) of
							{RewardLv, TCount, RewardTimes} when TCount /= 0 ->
								case lists:keyfind(RewardLv, 1, RewardLimit) of
									{RewardLv, _LimitType, ResetCount, RewardCount} ->
										if
											TCount+1 > ResetCount ->
												RewardList ++ Acc;
											RewardTimes+1 =< RewardCount ->
												RewardList ++ Acc;
											true ->
												Acc
										end;
									_ ->
										RewardList ++ Acc
								end;
							_ ->
								RewardList ++ Acc
						end;
					false ->
						Acc
				end
			end,
			NewCount = 0;
		false -> %% 正常祈愿
			F = fun({RewardLv, RewardList}, Acc) ->
				case lists:keyfind(RewardLv, 1, Counter) of
					{RewardLv, TCount, RewardTimes} when TCount /= 0 ->
						case lists:keyfind(RewardLv, 1, RewardLimit) of
							{RewardLv, _LimitType, ResetCount, RewardCount} ->
								if
									TCount+1 > ResetCount ->
										RewardList ++ Acc;
									RewardTimes+1 =< RewardCount ->
										RewardList ++ Acc;
									true ->
										Acc
								end;
							_ ->
								RewardList ++ Acc
						end;
					_ ->
						RewardList ++ Acc
				end
			end,
			NewCount = Count + 1
	end,
	{F, NewCount}.

updata_reward_counter(RewardLv, RewardLimit, PersonalCounter) ->
	mod_local_supplication:supplication_success(RewardLv),
	UseCounter = case lists:keyfind(RewardLv, 1, PersonalCounter) of
		false ->
			[{RewardLv, 0, 0}|PersonalCounter];
		_ ->
			PersonalCounter
	end,
	F = fun({TRewardLv, Count, GetTimes}, TempList) ->
		case lists:keyfind(TRewardLv, 1, RewardLimit) of
			{TRewardLv, ?LIMIT_TYPE_PERSONAL, ResetCount, _RewardCount} ->
				NewGetTimes = ?IF(TRewardLv == RewardLv, GetTimes+1, GetTimes),
				case Count+1 > ResetCount of
					true -> %% 达到重置次数
						TempList;
					false ->
						[{TRewardLv, Count+1, NewGetTimes}|TempList]
				end;
			_ ->
				TempList
		end
	end,
	lists:foldl(F, [], UseCounter).

%% @doc 发送抽奖奖励
%% @return #player_status{}
do_send_supplication_reward(PS, RewardId, RewardLv, Cost, Reward, NewCount, NewPersonalCounter) ->
	#player_status{id = RoleId, supplication = Supplication} = PS,
	#supplication{sub_type = SubType, self_log = SelfLog, select_reward = SelectReward, time = Time} = Supplication,
	lib_log_api:log_supplication_reward(RoleId, NewCount, RewardLv, Cost, Reward, RewardId),
	Remark = lists:concat(["NewCount:", NewCount, ", RewardId:", RewardId, ", RewardLv:", RewardLv]),
	Produce = #produce{type = supplication, reward = Reward, show_tips = 0, remark = Remark},
	NewSelfLog = lists:sublist([RewardId|SelfLog], ?SUPPLICATION_BRO_NUM),
	NewSupplication = Supplication#supplication{self_log = NewSelfLog, count = NewCount, counter = NewPersonalCounter},
	TempPS = PS#player_status{supplication = NewSupplication},
	db_replace_supplication(RoleId, SubType, NewSelfLog, SelectReward, NewCount, NewPersonalCounter, Time),
	NewPS = lib_goods_api:send_reward(TempPS, Produce),
	NewPS.

%% @doc 处理广播
do_supplication_broadcast(PS, RewardId, RewardLvStr, RewardList, ?BROADCAST) ->
	#player_status{id = RoleId, figure = Figure, server_num = ServerNum} = PS,
	clusters_node:apply_cast(mod_kf_supplication, add_broadcast, [RoleId, Figure#figure.name, ServerNum, RewardId, RewardLvStr, RewardList]);
do_supplication_broadcast(_PS, _RewardId, _RewardLvStr, _RewardList, ?NO_BROADCAST) -> skip;
do_supplication_broadcast(_PS, _RewardId, _RewardLvStr, _RewardList, _BroadcastType) -> skip.

%% 跨服进程通知执行发送广播
send_broadcast(_RoleName, _ServerNum, _RewardLvStr, RewardList) ->
	% case lib_custom_act_util:get_open_subtype_list(?CUSTOM_ACT_TYPE_SUPPLICATION) of
	% 	[#act_info{key = {?CUSTOM_ACT_TYPE_SUPPLICATION, _SubType}}|_] ->
	% 		RewardStr = make_goods_str(RewardList),
	% 		lib_chat:send_TV({all}, ?MOD_AC_CUSTOM, 16, [ServerNum, RoleName, RewardLv, RewardStr]);
	% 	_ ->
	% 		skip
	% end.
	_RewardStr = make_goods_str(RewardList),
	% lib_chat:send_TV({all}, ?MOD_AC_CUSTOM, 16, [ServerNum, RoleName, RewardLvStr, RewardStr]).
	ok.

%% 组装物品str
make_goods_str(GoodsList) -> make_goods_str(GoodsList, "").

make_goods_str([], Str) -> Str;
make_goods_str([{_Type, GoodsTypeId, Num}|L], Str) ->
	Color = data_goods:get_goods_color(GoodsTypeId),
    case L == [] of
        true -> NewStr = lists:concat([Str, "<a@goods@", GoodsTypeId,"></a>", "<color@", Color, ">", " x", Num, "</color>"]);
        false -> NewStr = lists:concat([Str, "<a@goods@", GoodsTypeId,"></a>", "<color@", Color, ">", " x", Num, "</color>", "，"])
    end,
    make_goods_str(L, NewStr);
make_goods_str([_|L], Str) ->
    make_goods_str(L, Str).

%% 领取任务奖励
receive_reward(PS, GetTaskId) ->
	#player_status{id = RoleId, figure = Figure, supplication = Supplication} = PS,
	#figure{lv = Lv} = Figure,
	#supplication{task_list = TaskList} = Supplication,
	case get_act_cfg_info([role_lv, task]) of
		{ok, OpenSubType, Stime, Etime, [OpenLv, Task]} ->
			case Lv >= OpenLv of
				true ->
					case lists:keyfind(GetTaskId, #task_progress.task_id, TaskList) of
						#task_progress{sub_type = OpenSubType, task_status = TaskStatus, time = Time} = TaskProgress when Time >= Stime, Time =< Etime ->
							case TaskStatus of
								?UNFINISH -> %% 未完成
									{ok, Bin} = pt_331:write(33197, [?ERRCODE(err331_act_can_not_get), GetTaskId]),
									lib_server_send:send_to_uid(RoleId, Bin);
								?FINISH -> %% 已完成
									do_receive_reward(PS, OpenSubType, GetTaskId, Task, TaskProgress);
								_ -> %% 已领取
									{ok, Bin} = pt_331:write(33197, [?ERRCODE(err331_already_get_reward), GetTaskId]),
									lib_server_send:send_to_uid(RoleId, Bin)
							end;
						_ -> %% 不存在任务数据
							{ok, Bin} = pt_331:write(33197, [?ERRCODE(err331_act_can_not_get), GetTaskId]),
							lib_server_send:send_to_uid(RoleId, Bin)
					end;
				false ->
					{ok, Bin} = pt_331:write(33197, [?LEVEL_LIMIT, GetTaskId]),
					lib_server_send:send_to_uid(RoleId, Bin)
			end;
		_ -> %% 活动未开启
			{ok, Bin} = pt_331:write(33197, [?ERRCODE(err331_act_closed), GetTaskId]),
			lib_server_send:send_to_uid(RoleId, Bin)
	end.

do_receive_reward(PS, OpenSubType, GetTaskId, Task, TaskProgress) ->
	#player_status{id = RoleId, supplication = Supplication} = PS,
	#supplication{task_list = TaskList} = Supplication,
	#task_progress{progress = Progress, extra = Extra, time = Time} = TaskProgress,
	case get_task_reward(PS, OpenSubType, GetTaskId, Task) of
		{ok, RewardId, RewardList, _Condition} when RewardList =/= [] ->
			case lib_goods_api:can_give_goods(PS, RewardList) of
				true ->
					lib_log_api:log_supplication_task_reward(RoleId, GetTaskId, RewardId, RewardList),
					db_replace_supplication_task(RoleId, GetTaskId, OpenSubType, Progress, Extra, ?HAS_RECEIVE, Time),
					%WLv = util:get_world_lv(),
					%ExtraStr = lists:concat(["TaskId:", GetTaskId, ", TaskCondition:", util:term_to_string(Condition)]),
					%lib_log_api:log_custom_act_reward(RoleId, ?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType, RewardId, WLv, RewardList, ExtraStr, utime:unixtime()),
					NewTaskList = lists:keyreplace(GetTaskId, #task_progress.task_id, TaskList, TaskProgress#task_progress{task_status = ?HAS_RECEIVE}),
					NewSupplication = Supplication#supplication{task_list = NewTaskList},
					Code = ?SUCCESS,
					Produce = #produce{type = supplication_task, reward = RewardList, show_tips = 1, remark = lists:concat(["TaskId:", GetTaskId])},
					TempPS = lib_goods_api:send_reward(PS, Produce),
					NewPS = TempPS#player_status{supplication = NewSupplication};
				false ->
					Code = ?ERRCODE(err150_no_cell),
					NewPS = PS
			end;
		{error, Code} ->
			NewPS = PS
	end,
	{ok, Bin} = pt_331:write(33197, [Code, GetTaskId]),
	lib_server_send:send_to_uid(RoleId, Bin),
	{ok, NewPS}.

%% 获取任务奖励列表
%% @return {ok, RewardId, RewardList, Condition} | {error, Error}
%% RewardList :: list()  通用奖励列表
%% Condition  :: tuple() 任务完成条件
get_task_reward(PS, SubType, TaskId, TaskList) ->
	ActInfo = lib_custom_act_util:get_custom_act_open_info(?CUSTOM_ACT_TYPE_SUPPLICATION, SubType),
	case lists:keyfind(TaskId, 1, TaskList) of
		{TaskId, Condition, RewardId} ->
			case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, SubType, RewardId) of
				RewardCfg when is_record(RewardCfg, custom_act_reward_cfg),  is_record(ActInfo, act_info) ->
					RewardList = lib_custom_act_util:count_act_reward(PS, ActInfo, RewardCfg),
					{ok, RewardId, RewardList, Condition};
				_ ->
					{error, ?ERRCODE(missing_config)}
			end;
		_ ->
			{error, ?ERRCODE(missing_config)}
	end.

%% 获取开启中的活动信息
%% @param 		CheckList :: list()  条件参数检测列表  eg:[lv, task]
%% @return		false | {ok, SubType, Stime, Etime, Result}
%% SubType 	:: 	integer()  开启中的活动子类型
%% stime 	:: 	integer()  活动开启时间
%% Etime 	:: 	integer()  活动结束时间
%% Result 	::  list() 	   根据传入的检测列表返回的结果集
get_act_cfg_info(CheckList) when is_list(CheckList) ->
	case lib_custom_act_util:get_open_subtype_list(?CUSTOM_ACT_TYPE_SUPPLICATION) of
		[#act_info{key = {?CUSTOM_ACT_TYPE_SUPPLICATION, SubType}, stime = Stime, etime = Etime}|_] -> %% 只处理开启中子类型最小的一个活动
			case lib_custom_act_util:get_act_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, SubType) of
				#custom_act_cfg{condition = Condition} ->
					case lib_custom_act_check:check_act_condtion(CheckList, Condition) of
						false  -> false;
						Result -> {ok, SubType, Stime, Etime, Result}
					end;
				_ ->
					false
			end;
		_ ->
			false
	end.

%% 发送任务状态
send_task_status(PS) ->
	#player_status{id = RoleId, figure = Figure, supplication = Supplication} = PS,
	#figure{lv = Lv} = Figure,
	#supplication{task_list = TaskList} = Supplication,
	case get_act_cfg_info([role_lv, task]) of
		{ok, OpenSubType, Stime, Etime, [OpenLv, Task]} when Lv >= OpenLv ->
			PackTaskList = pack_task_list(TaskList, Task, OpenSubType, Stime, Etime),
			{ok, Bin} = pt_332:write(33204, [PackTaskList]),
			lib_server_send:send_to_uid(RoleId, Bin);
		_ ->
			skip
	end.

%% =====================================
%%				  触发器
%% =====================================
trigger(PS, CheckRes, Args, OpenSubType, Stime, Etime) ->
	#player_status{id = RoleId, supplication = Supplication} = PS,
	#supplication{task_list = TaskList} = Supplication,
	put({?MODULE, finish_task_list}, []),
	{IsFinish, NewTaskList} = do_trigger(CheckRes, Args, OpenSubType, Stime, Etime, RoleId, false, TaskList),
	case erase({?MODULE, finish_task_list}) of
		FinishList when is_list(FinishList) -> %% 记录任务完成日志
			F = fun({FTaskId, Condition}) ->
				lib_log_api:log_supplication_task_finish(RoleId, FTaskId, Condition)
			end,
			lists:foreach(F, FinishList);
		_ ->
			skip
	end,
	case IsFinish of
		true -> %% 有任务完成了，通知客户端刷新状态显示红点
			PackTaskList = [{TaskId, TaskStatus, Progress} ||
							#task_progress{task_id = TaskId, task_status = TaskStatus, progress = Progress} <- NewTaskList],
			{ok, Bin} = pt_332:write(33204, [PackTaskList]),
			lib_server_send:send_to_uid(RoleId, Bin);
		false ->
			skip
	end,
	NewSupplication = Supplication#supplication{task_list = NewTaskList},
	NewPS = PS#player_status{supplication = NewSupplication},
	{ok, NewPS}.

do_trigger([], _Args, _OpenSubType, _Stime, _Etime, _RoleId, IsFinish, TaskList) -> {IsFinish, TaskList};
%% 每天登录
do_trigger([{TaskId, {daily_login}}|T], {daily_login}, OpenSubType, Stime, Etime, RoleId, IsFinish, TaskList) ->
	case lists:keyfind(TaskId, #task_progress.task_id, TaskList) of
		#task_progress{
			sub_type = OpenSubType, extra = [RefreshTime], task_status = TaskStatus,
			write_time = WT, time = Time
		} = TaskProgress when Time >= Stime, Time < Etime, is_integer(RefreshTime) ->
			NowTime = utime:unixtime(),
			case utime:is_same_day(NowTime, RefreshTime) orelse TaskStatus =/= ?UNFINISH of
				true -> %% 同一天登录或已完成
					NewIsFinish = IsFinish,
					NewTaskProgress = TaskProgress;
				false -> %% 不是同一天登录
					NewIsFinish = true,
					NewProgress = 1,
					NewTaskStatus = ?FINISH,
					{NewWT, NewWS} = check_need_execute_sql(RoleId, TaskId, OpenSubType, NewProgress, [NowTime], NewTaskStatus, Time, WT),
					NewTaskProgress = TaskProgress#task_progress{
						progress = NewProgress, extra = [NowTime], task_status = NewTaskStatus,
						write_time = NewWT, write_status = NewWS
					},
					FinishList = get({?MODULE, finish_task_list}),
					put({?MODULE, finish_task_list}, [{TaskId, {daily_login}}|FinishList])
			end;
		_ -> %% 无任务进度
			NewIsFinish = true,
			NowTime = utime:unixtime(),
			TaskStatus = ?FINISH,
			Progress = 1,
			db_replace_supplication_task(RoleId, TaskId, OpenSubType, Progress, [NowTime], TaskStatus, NowTime),
			NewTaskProgress = #task_progress{
				task_id = TaskId, sub_type = OpenSubType, progress = Progress, extra = [NowTime], task_status = TaskStatus,
				write_time = NowTime, write_status = ?WSTATUS_SUCCESSS, time = NowTime
			},
			FinishList = get({?MODULE, finish_task_list}),
			put({?MODULE, finish_task_list}, [{TaskId, {daily_login}}|FinishList])
	end,
	NewTaskList = lists:keystore(TaskId, #task_progress.task_id, TaskList, NewTaskProgress),
	do_trigger(T, {daily_login}, OpenSubType, Stime, Etime, RoleId, NewIsFinish, NewTaskList);
%% 每日首充
do_trigger([{TaskId, {daily_charge}}|T], {daily_charge}, OpenSubType, Stime, Etime, RoleId, IsFinish, TaskList) ->
	case lists:keyfind(TaskId, #task_progress.task_id, TaskList) of
		#task_progress{
			sub_type = OpenSubType, extra = [RefreshTime], task_status = TaskStatus,
			write_time = WT, time = Time
		} = TaskProgress when Time >= Stime, Time < Etime, is_integer(RefreshTime) ->
			NowTime = utime:unixtime(),
			case utime:is_same_day(NowTime, RefreshTime) orelse TaskStatus =/= ?UNFINISH of
				true -> %% 同一天充值或已完成
					NewIsFinish = IsFinish,
					NewTaskProgress = TaskProgress;
				false -> %% 不是同一天充值
					NewIsFinish = true,
					NewProgress = 1,
					NewTaskStatus = ?FINISH,
					{NewWT, NewWS} = check_need_execute_sql(RoleId, TaskId, OpenSubType, NewProgress, [NowTime], NewTaskStatus, Time, WT),
					NewTaskProgress = TaskProgress#task_progress{
						progress = NewProgress, extra = [NowTime], task_status = NewTaskStatus,
						write_time = NewWT, write_status = NewWS
					},
					FinishList = get({?MODULE, finish_task_list}),
					put({?MODULE, finish_task_list}, [{TaskId, {daily_charge}}|FinishList])
			end;
		_ -> %% 无任务进度
			NewIsFinish = true,
			NowTime = utime:unixtime(),
			TaskStatus = ?FINISH,
			Progress = 1,
			db_replace_supplication_task(RoleId, TaskId, OpenSubType, Progress, [NowTime], TaskStatus, NowTime),
			NewTaskProgress = #task_progress{
				task_id = TaskId, sub_type = OpenSubType, progress = Progress, extra = [NowTime], task_status = TaskStatus,
				write_time = NowTime, write_status = ?WSTATUS_SUCCESSS, time = NowTime
			},
			FinishList = get({?MODULE, finish_task_list}),
			put({?MODULE, finish_task_list}, [{TaskId, {daily_charge}}|FinishList])
	end,
	NewTaskList = lists:keystore(TaskId, #task_progress.task_id, TaskList, NewTaskProgress),
	do_trigger(T, {daily_charge}, OpenSubType, Stime, Etime, RoleId, NewIsFinish, NewTaskList);
%% 增加活跃度
do_trigger([{TaskId, {liveness, NeedVal}}|T], {liveness, AddVal}, OpenSubType, Stime, Etime, RoleId, IsFinish, TaskList) ->
	case lists:keyfind(TaskId, #task_progress.task_id, TaskList) of
		#task_progress{
			sub_type = OpenSubType, extra = Extra, task_status = TaskStatus,
			write_time = WT, time = Time, progress = CurVal
		} = TaskProgress when Time >= Stime, Time < Etime ->
			case TaskStatus =/= ?UNFINISH of
				true -> %% 已完成
					NewIsFinish = IsFinish,
					NewTaskProgress = TaskProgress;
				false ->
					NewIsFinish = true,
					case CurVal+AddVal >= NeedVal of
						true ->
							NewProgress = NeedVal,
							NewTaskStatus = ?FINISH,
							FinishList = get({?MODULE, finish_task_list}),
							put({?MODULE, finish_task_list}, [{TaskId, {liveness, NeedVal}}|FinishList]);
						false ->
							NewProgress = CurVal + AddVal,
							NewTaskStatus = ?UNFINISH
					end,
					{NewWT, NewWS} = check_need_execute_sql(RoleId, TaskId, OpenSubType, NewProgress, Extra, NewTaskStatus, Time, WT),
					NewTaskProgress = TaskProgress#task_progress{
						progress = NewProgress, task_status = NewTaskStatus,
						write_time = NewWT, write_status = NewWS
					}
			end;
		_ -> %% 无任务进度
			NewIsFinish = true,
			NowTime = utime:unixtime(),
			case AddVal >= NeedVal of
				true ->
					Progress = NeedVal,
					TaskStatus = ?FINISH,
					FinishList = get({?MODULE, finish_task_list}),
					put({?MODULE, finish_task_list}, [{TaskId, {liveness, NeedVal}}|FinishList]);
				false ->
					Progress = AddVal,
					TaskStatus = ?UNFINISH
			end,
			db_replace_supplication_task(RoleId, TaskId, OpenSubType, Progress, [], TaskStatus, NowTime),
			NewTaskProgress = #task_progress{
				task_id = TaskId, sub_type = OpenSubType, progress = Progress, task_status = TaskStatus,
				write_time = NowTime, write_status = ?WSTATUS_SUCCESSS, time = NowTime
			}
	end,
	NewTaskList = lists:keystore(TaskId, #task_progress.task_id, TaskList, NewTaskProgress),
	do_trigger(T, {liveness, AddVal}, OpenSubType, Stime, Etime, RoleId, NewIsFinish, NewTaskList);
do_trigger([_H|T], Args, OpenSubType, Stime, Etime, RoleId, IsFinish, TaskList) ->
	do_trigger(T, Args, OpenSubType, Stime, Etime, RoleId, IsFinish, TaskList).

%% 检测是否需写入数据库
%% @returen {NewWriteTime, NewWriteStatus}
check_need_execute_sql(RoleId, TaskId, SubType, Progress, Extra, TaskStatus, Time, WriteTime) ->
	NowTime = utime:unixtime(),
	case NowTime - WriteTime > ?SAVE_DB_CD of
		true -> %% 可以写入数据库
			db_replace_supplication_task(RoleId, TaskId, SubType, Progress, Extra, TaskStatus, Time),
			NewWT = NowTime,
			NewWS = ?WSTATUS_SUCCESSS;
		false -> %% 等待下次写入数据库
			NewWT = WriteTime,
			NewWS = ?WSTATUS_WAIT
	end,
	{NewWT, NewWS}.

%% =====================================
%% 				  check
%% =====================================
check([]) -> true;
check([H|T]) ->
	case do_check(H) of
		true ->
			check(T);
		{false, ErrCode} ->
			{false, ErrCode};
		_ ->
			?ERR("bad return value~n", []),
			{false, ?FAIL}
	end.

%% 达到开放等级
do_check({reach_open_lv, Lv, OpenLv}) ->
	case Lv >= OpenLv of
		true ->
			true;
		false ->
			{false, ?LEVEL_LIMIT}
	end;

%% 选择奖励数量正确
do_check({select_reward_num_correct, RewardIds}) when is_list(RewardIds) ->
	case length(RewardIds) == ?SUPPLICATION_REWARD_LENGTH of
		true ->
			true;
		false ->
			{false, ?ERRCODE(err331_wrong_reward_num)}
	end;

%% 处于抽奖时间段
do_check({is_cost_day, CostDay}) when is_list(CostDay) ->
	NowDate = utime:unixdate(),
	NowTime = utime:unixtime(),
	UseTime = NowTime - NowDate,
	NowDay = utime:day_of_week(NowTime),
	case lists:keyfind(NowDay, 1, CostDay) of
		{NowDay, {SH, SM}, {EH, EM}} ->
			STime = SH*60*60 + SM*60,
			ETime = EH*60*60 + EM*60,
			case UseTime >= STime andalso UseTime < ETime of
				true  -> true;
				false -> {false, ?ERRCODE(err331_not_supplication_time)}
			end;
		false ->
			{false, ?ERRCODE(err331_not_supplication_time)};
		_ ->
			?ERR("wrong supplication condition cost_day:~p~n", [CostDay]),
			{false, ?ERRCODE(err331_not_supplication_time)}
	end;

%% 处于完成任务时间段
do_check({is_reward_day, RewardDay}) when is_list(RewardDay) ->
	NowDay = utime:day_of_week(),
	case lists:member(NowDay, RewardDay) of
		true ->
			true;
		false ->
			{false, ?FAIL}
	end;

%% 消耗物品足够
do_check({goods_num_enough, PS, Cost}) ->
	case lib_goods_api:check_object_list(PS, Cost) of
		true ->
			true;
		{false, ErrCode} ->
			{false, ErrCode}
	end;

%% 背包未满（初步检测）
do_check({cell_num_enough, PS}) ->
	CellNum = lib_goods_api:get_cell_num(PS),
	case CellNum > 0 of
		true ->
			true;
		false ->
			{false, ?ERRCODE(err150_no_cell)}
	end;

%% 奖励全部选满
do_check({select_reward_correct, OpenSubType, PS}) ->
	#player_status{supplication = Supplication} = PS,
	#supplication{select_reward = SelectReward} = Supplication,
	RewardIds = lib_custom_act_util:get_act_reward_grade_list(?CUSTOM_ACT_TYPE_SUPPLICATION, OpenSubType),
	AllRewardList = pack_reward_list(SelectReward, OpenSubType, RewardIds, []),
	case is_list(AllRewardList) of
		true ->
			case length(AllRewardList) == ?SUPPLICATION_REWARD_LENGTH of
				true ->
					true;
				false ->
					{false, ?ERRCODE(err331_wrong_reward_num)}
			end;
		false ->
			{false, ?ERRCODE(err331_wrong_reward_num)}
	end;

%% 奖励id不重复
do_check({difference_reward_id, RewardIds}) ->
	case check_difference_reward_id(RewardIds) of
		true ->
			true;
		_ ->
			{false, ?ERRCODE(data_error)}
	end;

%% 奖励位置正确
do_check({pos_id_correct, SubType, RewardIds}) ->
	F = fun(PosId) ->
		case lists:keyfind(PosId, 1, RewardIds) of
			{PosId, RewardId} ->
				case lib_custom_act_util:get_act_reward_cfg_info(?CUSTOM_ACT_TYPE_SUPPLICATION, SubType, RewardId) of
					#custom_act_reward_cfg{condition = Condition} ->
						case lib_custom_act_check:check_act_condtion([reward_lv, weight], Condition) of
							[RewardLv, _Weight] ->
								PosIds = case RewardLv of
									0 -> [1];
									1 -> [2, 3];
									2 -> [4, 5, 6];
									3 -> [7, 8 ,9, 10];
									_ -> []
								end,
								lists:member(PosId, PosIds);
							_ ->
								false
						end;
					_ ->
						false
				end;
			_ ->
				false
		end
	end,
	case lists:all(F, lists:seq(1, 10)) of
		true ->
			true;
		false ->
			{false, ?ERRCODE(data_error)}
	end;

do_check(_Condition) ->
	?ERR("no match check condition:~p~n", [_Condition]),
	{false, ?FAIL}.

check_difference_reward_id([]) -> true;
check_difference_reward_id([{_PosId, RewardId}|T]) ->
	case lists:keyfind(RewardId, 2, T) of
		false ->
			check_difference_reward_id(T);
		_ ->
			false
	end.

%% ===========================================
%% 					SQL
%% ===========================================
db_get_supplication(RoleId) ->
	ReSql = io_lib:format(?SELECT_SUPPLICATION, [RoleId]),
	db:get_all(ReSql).

db_get_all_supplication_task(RoleId) ->
	ReSql = io_lib:format(?SELECT_SUPPLICATION_TASK, [RoleId]),
	db:get_all(ReSql).

db_replace_supplication(RoleId, SubType, SelfLog, SelectReward, Count, Counter, Time) ->
	SSelfLog = util:term_to_bitstring(SelfLog),
	SSelectReward = util:term_to_bitstring(SelectReward),
	SCounter = util:term_to_bitstring(Counter),
	ReSql = io_lib:format(?REPLACE_SUPPLICATION, [RoleId, SubType, SSelfLog, SSelectReward, Count, SCounter, Time]),
	db:execute(ReSql).

db_replace_supplication_task(RoleId, TaskId, SubType, Progress, Extra, TaskStatus, Time) ->
	SExtra = util:term_to_bitstring(Extra),
	ReSql = io_lib:format(?REPLACE_SUPPLICATION_TASK, [RoleId, TaskId, SubType, Progress, SExtra, TaskStatus, Time]),
	db:execute(ReSql).

db_delete_supplication_task(RoleId, TaskId) ->
	ReSql = io_lib:format(?DELETE_ALL_SUPPLICATION_TASK, [RoleId, TaskId]),
	db:execute(ReSql).

db_update_supplication_task(RoleId, TaskId, Progress, Extra, TaskStatus) ->
	SExtra = util:term_to_bitstring(Extra),
	ReSql = io_lib:format(?UPDATE_SUPPLICATION_TASK, [Progress, SExtra, TaskStatus, RoleId, TaskId]),
	db:execute(ReSql).
