using Api.Framework; using Api.Framework.EntityTmp.Douyin; using Api.Framework.Enums; using Api.Framework.Events; using Api.Framework.Model; using Api.Framework.SDK; using Api.Framework.Timers; using Api.Framework.Tools; using CsharpHttpHelper; using DYRebate.Entitys; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Api.Framework.Utils; using static DYRebate.Class1; namespace DYRebate { public class MessageOperation { private static List AddMessUsernameList = new List() { "wxid_mjzeh4qj9hio22", "wxid_lrf1mr7ond6622", "wujiahua0876", "wxid_2ufntuf4purl22", "wxid_bua0te17il7i22" }; ReciveIMEvent e = null; Class1 plugin = null; object sender = null; public MessageOperation(object sender, ReciveIMEvent e, Class1 plugin) { this.e = e; this.plugin = plugin; this.sender = sender; } #region 订单绑定 public bool BindOrderId() { try { #region 抖音订单绑定 var orderid = e.Message.Trim(); #region 消息为订单类型 if (Regex.IsMatch(orderid, @"^\d{19}$")) { var oid = long.Parse(orderid); if (oid < 4000000000000000000) { return false; } var db = ApiClient.GetSession(); var dy_orders_temp = db.Find("select * from fl_order_douyin where order_id = @order_id", new { order_id = orderid }); var memberTmp = e.GetMemberinfo(); if (dy_orders_temp != null && dy_orders_temp.Count != 0) { var member = dy_orders_temp.FirstOrDefault(f => f.db_userid != 0 && f.db_userid != memberTmp.id); if (member != null) { //订单已经被他人绑定 e.SendMessage(Class1.Config.OccupyOrderErrorTip.Replace("[订单号]", orderid)); return true; } var notices = new List(); var downDyTimer = new DownDouyinTimer(); #region 订单用户已经绑定 纯提示,非结算的订单也提示上级 var bindOrders = dy_orders_temp.Where(f => f.db_userid != 0).ToList(); if (bindOrders != null && bindOrders.Count != 0) { foreach (var order in bindOrders) { var point = HttpHelper.JsonToObject(order.db_point) as ItemPoint; memberTmp = e.GetMemberinfo(true); if (order.db_status == SystemOrderStatus.订单付款) e.SendMessage(new VariateReplace().CommonReplace(Class1.Config.OrderRepetBindTip, order, memberTmp, point)); else e.SendMessage(Class1._GetOrderStateMess(order.db_status, (order.db_status == SystemOrderStatus.订单结算 ? SettleType.已结算提示 : SettleType.未结算提示), order, memberTmp, point)); Thread.Sleep(500); } //return; } #endregion #region 订单没有被绑定(两种情况 => 一个订单已经被结算 一个是订单未结算) var notBindOrders = dy_orders_temp.Where(f => f.db_userid == 0).ToList(); if (notBindOrders != null && notBindOrders.Count != 0) { if (HttpExtend.GetDateTime(notBindOrders[0].pay_time.ToString()) < ApiClient.Setting.SystemConfig.allow_bind_create_order_time) { e.SendMessage($"订单:{orderid},已经过了有效绑定时间!"); return true; } foreach (var order in notBindOrders) { if (order.db_status == SystemOrderStatus.订单结算) order.db_endtime = DateTime.Now.AddMinutes(-5);//重新结算的话,需要将订单的冻结时间重新赋值,让后台处理 //没有绑定用户的订单进行绑定 order.db_userid = memberTmp.id; order.db_robotname = e.RobotName; order.db_robottype = e.RobotInfo.type; order.msg_groupid = e.Groupid; #region 手动绑定,重新计算用户的返利积分 //查询历史查询比例 var compute = db.FindQueryRatioHist(CpsType.抖音联盟, order.id); if (compute == null) { var query_item = db.FindSingle("select * from fl_query_hist where userid = @userid and itemid = @itemid and adzoneid = @adzoneid order by id desc", new { userid = e.GetMemberinfo().id, itemid = order.product_id, adzoneid = order.db_cpsname }); //计算公式不为空 if (query_item != null && !string.IsNullOrWhiteSpace(query_item.compute_configdic)) { try { compute = JsonConvert.DeserializeObject(query_item.compute_configdic); var queryRatioHist = new fl_query_ratio_hist() { compute_config = query_item.compute_configdic, db_orderid = order.id, createtime = DateTime.Now, cpstype = CpsType.抖音联盟 }; db.SaveOrUpdate(queryRatioHist); } catch (Exception ex) { EventClient.OnEvent("抖音计算", $"获取历史查询比异常:{ex.Message}"); } } } ItemPoint itempoint = null; //计算的佣金 if (compute != null) itempoint = db.FindItemPoint(CpsType.抖音联盟, compute, Util.ConvertDouble_FenToYuan(order.estimated_comission), 1); else itempoint = db.FindItemPoint(memberTmp, Util.ConvertDouble_FenToYuan(order.estimated_comission), 1, CpsType.抖音联盟); if (itempoint != null) { order.db_point = HttpHelper.ObjectToJson(itempoint); order.db_userpoint = itempoint.UserPoint; } #endregion #region 用户的完成订单数量加1 if (memberTmp != null) { memberTmp.bind_order++; memberTmp = db.UpdateMemberGroup(memberTmp); } #endregion #region 首次付款时间 var record = db.FindStatisticsRecord(memberTmp.id); if (record == null) { record = new fl_statistics_record() { uid = memberTmp.id, ex2 = 0, ex4 = HttpExtend.GetTimeStamp(DateTime.Now) }; db.Saveable(record).ExecuteCommand(); } else { if (record.ex2 == 0 && record.ex4 == 0) { record.ex4 = HttpExtend.GetTimeStamp(DateTime.Now); db.Saveable(record).ExecuteCommand(); } } #endregion db.SaveOrUpdate(order); downDyTimer.UpdateOrder(order, notices, db, isFrontData: true); } } #endregion #region 触发通知上级获得下级的提成奖励 if (!ApiClient.Setting.SystemConfig.message_warning_switch && notices.Count != 0) { var tasks = TimerTask.GetTimer() as Update_NoticeQueue; foreach (var item in notices) { //if (item.IsRewards) tasks.Add(item); //else //plugin.SDK_OrderNoticeEvent(this, item); } } #endregion } else { #region 未找到订单,提示用户并且加入绑定缓存中 e.SendMessage(Class1.Config.NotFoundOrderErrorTip.Replace("[订单号]", orderid)); var bind = db.FindBindCache(orderid); if (bind == null) { db.Insertable(new fl_bind_cache() { crt_time = DateTime.Now, db_robotid = e.RobotInfo.id, orderid = orderid, groupid = e.Groupid, db_userid = memberTmp.id }).ExecuteCommand(); db.FindBindCache(orderid, true); } #endregion } //消息已经处理完成,将不往后面的插件传递 e.Cancel = true; return true; } #endregion //判断消息是否是其他cps平台的订单号 if (OrderHelper.IsOrderId(e.Message.Trim())) return true; #endregion } catch (Exception ex) { plugin.OnLog($"手动绑定订单号异常:{ex.Message}_{ex.StackTrace}"); } return false; } #endregion public bool AnalyseFanLi() { //计算公式 Compute compute = null; var memberTmp = e.GetMemberinfo(); try { var db = ApiClient.GetSession(); var dyinfoTemps = db.FindDyInfoTempGroups(); var dyInfoTemp = dyinfoTemps.FirstOrDefault(f => f.name == e.RobotInfo.name && f.onoff == false); if (dyInfoTemp == null) return false; var message = e.Message.Trim(); //推广位 var pid = string.Empty; fl_cps_member dy_cps = null; var isDefault = true; if (!string.IsNullOrWhiteSpace(e.Groupid))//群pid { var groupAdzone = db.FindAdzoneInfos().FirstOrDefault(f => f.alliance_id == (int)CpsType.抖音联盟 && f.custom_type == PrivateAdzoneCustomType.群pid.ToString() && f.group_id == e.Groupid); if (groupAdzone != null && !string.IsNullOrWhiteSpace(groupAdzone.adzone_pid)) { pid = groupAdzone.adzone_pid; dy_cps = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.抖音联盟 && f.username == groupAdzone.adzone_pid_cps_name); isDefault = false; } } if (isDefault)//私人pid { var memberAdzone = db.FindAdzoneInfos().FirstOrDefault(f => f.alliance_id == (int)CpsType.抖音联盟 && f.custom_type == PrivateAdzoneCustomType.用户私人pid.ToString() && f.member_id == memberTmp.id); if (memberAdzone != null && !string.IsNullOrWhiteSpace(memberAdzone.adzone_pid))//私人推广位 { pid = memberAdzone.adzone_pid; dy_cps = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.抖音联盟 && f.username == memberAdzone.adzone_pid_cps_name); isDefault = false; } } if (isDefault)//默认推广位 { dy_cps = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.抖音联盟 && f.username == ((memberTmp.buy_point >= Class1.Config.Point && memberTmp.finish_order >= Class1.Config.OrderNum) ? dyInfoTemp.pid_chief_cps_name : dyInfoTemp.pid_deputy_cps_name));//通过判断用户的购物积分,来判断用户使用哪个推广位 pid = ((memberTmp.buy_point >= Class1.Config.Point && memberTmp.finish_order >= Class1.Config.OrderNum) ? dyInfoTemp.pid_chief : dyInfoTemp.pid_deputy); } if (dy_cps == null) throw new Exception("抖音推广位设置异常,请检测后重试!"); var api = CpsClient.CreateDouyinRequest(dy_cps); if (api == null) throw new Exception("@创建抖音API请求失败"); //var title = string.Empty;//商品标题 //判断消息中是否包含抖音链接信息 var promotion_id = string.Empty;//促销id //api.ConvertInstPickSource(e.Message); //api.GetShareMaterial(); //var itemid = e.Message.Trim(); var itemid = api.GetDyGoodsID(message, out promotion_id); #region 标题搜索和商品id搜索 if (string.IsNullOrEmpty(itemid)) return false; if (!ApiClient.Setting.SystemConfig.message_warning_switch) e.SendMessage(Class1.Config.SearchingTip); try { //屏蔽商品 if (Class1.Config.ItemIDRestrictList.Contains(itemid)) { e.SendMessage(Class1.Config.ItemIDRestrictTip.Replace("[商品ID]", itemid)); return true; } var items = api.FindItemInfo(itemid); if (items == null || items.products == null || items.products.Count == 0) throw new Exception("商品不存在"); var goods = items.products[0]; var shopUrl = string.Empty; ShareInfo extInfo = null; var isApiSharable = false; if (Class1.Config.AllRebateModelSwitch == SwitchType.开启) { if (goods.sharable != "false") { try { extInfo = api.ConvertUrl(goods.detail_url, pid, $"{e.GetMemberinfo().username}"); isApiSharable = true; } catch (Exception) { } } } //var rateTmp = 0m; //if (goods.sharable == "false")//throw new Exception("商品未推广"); if (!isApiSharable)//throw new Exception("商品未推广"); { var key = $"{itemid}"; var value = Comm.GetCache(key); if (!string.IsNullOrWhiteSpace(value)) shopUrl = value; else { if (string.IsNullOrWhiteSpace(promotion_id)) throw new Exception("商品未推广"); isApiSharable = false; if (!api.BindGoods(itemid, promotion_id)) { throw new Exception("添加商品异常"); } shopUrl = api.GetShopWindow_PromotionUrlToGoodsId(itemid); if (string.IsNullOrWhiteSpace(shopUrl)) throw new Exception("未获取推广链接"); //var info = api.FindGoodsInfo(promotion_id); //if (info != null) // rateTmp = (decimal)info.data.cos_ratio / 10000m; Comm.SetCache(key, shopUrl, 15 * 60); } } //店铺名称 var nick = goods.shop_name; //商品主图 var pict_url = !string.IsNullOrWhiteSpace(goods.cover) ? goods.cover : (goods.imgs != null && goods.imgs.Count != 0) ? goods.imgs[0] : string.Empty; ////商品标题//< >&"© <,>,&,",©; var title = goods.title.Replace("‮", "").Replace("<", "<").Replace(">", ">").Replace("&", "&").Replace(""", "\"").Replace(" ©", "©");//这里有个看不见的字符,要将其替换掉 //原价 var price = decimal.Parse((goods.price / 100m).ToString()); //减去技术费的总佣金(不用券) var calcPrice = Math.Round((price * 0.9m), 2, MidpointRounding.AwayFromZero); //30天销量 var volume = goods.sales; //佣金率 var commission_rate = (decimal)goods.cos_ratio / 100m; //if (rateTmp != 0 && commission_rate != rateTmp) // commission_rate = rateTmp; //优惠券金额 var coupon_price = 0.00m; #region xxx //if (goods.sale_infos != null && goods.sale_infos.Count != 0) //{ // var coupon_tmp = 0m; // for (int i = 0; i < goods.sale_infos.Count; i++) // { // if (goods.sale_infos[i].title.Contains("减")) // { // var splitStrs = goods.sale_infos[i].title.Split(new string[] { "减" }, StringSplitOptions.RemoveEmptyEntries); // if (splitStrs != null && splitStrs.Length == 2) // { // var now = decimal.Parse(splitStrs[0]); // if (price >= now) // { // if (now > coupon_tmp) // { // coupon_tmp = now; // coupon_price = decimal.Parse(splitStrs[1]); // } // } // } // } // } //} #endregion //券后价 var endPrice = (decimal)((goods.coupon_price ?? 0) / 100d); if (endPrice != 0) { if (endPrice < price) coupon_price = price - endPrice; } //券后佣金 var useCalcPrice = endPrice * 0.9m; //用券后 佣金 var useCoupon_totalCommFee = (double)Math.Round(useCalcPrice * commission_rate, 2); //用券后 给用户的佣金 var useCoupon_commFee = db.FindItemPoint(memberTmp, useCoupon_totalCommFee, 1, CpsType.抖音联盟, out compute); Compute compute1 = null; //不用券 佣金 var unuseCoupon_totalCommFee = Math.Round(calcPrice * commission_rate, 2); //不用券 给用户的佣金 var unuseCoupon_commFee = db.FindItemPoint(memberTmp, (double)unuseCoupon_totalCommFee, 1, CpsType.抖音联盟, out compute1); if (compute == null) compute = compute1; LogHelper.GetSingleObj().Info("", $"抖音佣金计算:券后价{useCoupon_totalCommFee},佣金:{useCalcPrice} ||| 无券价:{unuseCoupon_totalCommFee},佣金:{unuseCoupon_totalCommFee} @@ 佣金率:{commission_rate} => {itemid}"); // 获取短链接 //var shopShortLink = ApiClient.ShortURL(shopUrl, Class1.Config.Dwz_Type).Result; //抖音缩短链接 var shopShortLink = string.Empty; //抖音口令 var password = string.Empty; if (isApiSharable) { if (extInfo == null) extInfo = api.ConvertUrl(goods.detail_url, pid, $"{e.GetMemberinfo().username}"); if (extInfo == null) throw new Exception("转链异常"); password = extInfo.dy_password; var reg = Regex.Match(extInfo.dy_password, "(?<口令>[︽#]{2}[0-9a-zA-Z]{9,}[︽#]{2})", RegexOptions.IgnoreCase | RegexOptions.Multiline); if (reg.Success) password = reg.Groups["口令"].ToString(); } else { password = DYHelperV2.CreateKouling(shopUrl); if (!string.IsNullOrWhiteSpace(password)) { shopShortLink = DYHelperV2.ShortDyUrl(shopUrl); shopUrl = string.Empty; } else { shopShortLink = DYHelperV2.ShortDyUrl(shopUrl); } //api.DelGoodsWindowUrl(promotion_id); var pidhist = db.Queryable().First(g => g.cpsname == api.Member.username && g.pid == promotion_id); if (pidhist == null) pidhist = new fl_plugin_dy_pidhist() { pid = promotion_id, cpsname = api.Member.username }; pidhist.expirestime = DateTime.Now.AddHours(1); db.Saveable(pidhist).ExecuteCommand(); } #region 正常订单 //有券的情况 if (coupon_price != 0) { var mess = string.Empty; if (e.ChatType == ChatType.微信 || e.ChatType == ChatType.企业微信 || (e.ChatType == ChatType.QQ && string.IsNullOrWhiteSpace(Class1.Config.QQSearchSuccessWithCouponTip))) { if (!string.IsNullOrWhiteSpace(shopShortLink)) mess = Class1.Config.SearchSuccessWithCouponTip; else mess = Class1.Config.SearchSuccessWithCouponTip_kl; } else { if (!string.IsNullOrWhiteSpace(shopShortLink)) mess = Class1.Config.QQSearchSuccessWithCouponTip; else mess = Class1.Config.QQSearchSuccessWithCouponTip_kl; } if (AddMessUsernameList.Contains(e.GetMemberinfo().username)) mess += "[分段][延迟=1]" + shopUrl; e.SendMessage(mess .Replace("劵", "券") .Replace("[商品标题]", mess.Contains("", "") : title) .Replace("[商品原价]", string.Format("{0:F}", price)) .Replace("[商品主图]", $"[图片={pict_url}]") .Replace("[图片地址]", pict_url) .Replace("[月销量]", volume.ToString()) .Replace("[店铺名称]", nick) .Replace("[券后返利]", string.Format("{0:F}", useCoupon_commFee.UserPoint)) .Replace("[弃券返利]", string.Format("{0:F}", unuseCoupon_commFee.UserPoint)) .Replace("[券后价]", string.Format("{0:F}", endPrice)) .Replace("[优惠券金额]", coupon_price.ToString()) .Replace("[购买地址]", shopShortLink) .Replace("[购买口令]", password.Replace("#", "︽")) .Replace("[共节省]", ((decimal)coupon_price + (decimal)useCoupon_commFee.UserPoint).ToString()) .Replace("[商品图片]", mess.Contains("[商品图片]") ? "[图片=" + ApiClient.GetQRImage(title, string.Format("{0:F}", price), coupon_price.ToString(), endPrice.ToString(), pict_url, shopShortLink, ApiClient.QrImageType.模板B, CpsType.抖音联盟) + "]" : string.Empty) ); } else//没有券的情况 { var mess = string.Empty; if (e.ChatType == ChatType.微信 || e.ChatType == ChatType.企业微信 || (e.ChatType == ChatType.QQ && string.IsNullOrWhiteSpace(Class1.Config.QQSearchSuccessWithoutCouponTip))) { if (!string.IsNullOrWhiteSpace(shopShortLink)) mess = Class1.Config.SearchSuccessWithoutCouponTip; else mess = Class1.Config.SearchSuccessWithoutCouponTip_kl; } else { if (!string.IsNullOrWhiteSpace(shopShortLink)) mess = Class1.Config.QQSearchSuccessWithoutCouponTip; else mess = Class1.Config.QQSearchSuccessWithoutCouponTip_kl; } if (AddMessUsernameList.Contains(e.GetMemberinfo().username)) mess += "[分段][延迟=1]" + shopUrl; e.SendMessage(mess .Replace("[商品标题]", mess.Contains("", "") : title) .Replace("[商品原价]", string.Format("{0:F}", price)) .Replace("[商品主图]", $"[图片={pict_url}]") .Replace("[图片地址]", pict_url) .Replace("[月销量]", volume.ToString()) .Replace("[店铺名称]", nick) .Replace("[返利积分]", string.Format("{0:F}", unuseCoupon_commFee.UserPoint)) .Replace("[购买地址]", shopShortLink) .Replace("[购买口令]", password.Replace("#", "︽")) .Replace("[共节省]", string.Format("{0:F}", useCoupon_commFee.UserPoint)) .Replace("[商品图片]", mess.Contains("[商品图片]") ? "[图片=" + ApiClient.GetQRImage(title, price.ToString(), "0", price.ToString(), pict_url, shopShortLink, ApiClient.QrImageType.模板B, CpsType.抖音联盟) + "]" : string.Empty) ); } #endregion #region 记录用户信息,宝贝信息,平台信息,查询时间等 db.Insertable(new fl_query_hist() { crt_time = DateTime.Now, type = CpsType.抖音联盟, itemid = itemid, groupid = e.Groupid, robot_name = e.RobotName, robot_type = e.ChatType, userid = memberTmp.id, title = title, adzoneid = dy_cps.username, mallid = goods.shop_id.ToString(), compute_configdic = compute == null ? string.Empty : JsonConvert.SerializeObject(compute) }).ExecuteCommand(); db.UpdateRecord(memberTmp.id); var shared = new Dictionary(); shared["msg_type"] = "查询宝贝"; shared["cps_type"] = CpsType.抖音联盟; shared["msg_username"] = memberTmp.username; shared["price"] = string.Format("{0:F}", price); shared["title"] = title; shared["coupon_price"] = string.Format("{0:F}", coupon_price); shared["user_point"] = coupon_price != 0 ? string.Format("{0:F}", useCoupon_commFee.UserPoint) : string.Format("{0:F}", unuseCoupon_commFee.UserPoint); shared["economize"] = coupon_price != 0 ? string.Format("{0:F}", ((decimal)coupon_price + (decimal)useCoupon_commFee.UserPoint)) : string.Format("{0:F}", useCoupon_commFee.UserPoint); var sharedEvent = new SharedEvents(shared); EventClient.OnEvent(sender, sharedEvent); #endregion return true; } catch (Exception ex) { //{"code":90000,"err_no":7,"log_id":"202202271755520101330360171F8980A6","message":"商家已设置该商品仅指定作者可推广,请您更换其他商品","msg":"未知错误,此错误会逐步细化明确,请不要依赖sub_code或sub_msg做业务判断","sub_code":"isp.unknown-error","sub_msg":"1025:商家已设置该商品仅指定作者可推广,请您更换其他商品"} if (ex.Message.Contains("商品不存在") || ex.Message.Contains("商品未推广") || ex.Message.Contains("未获取推广链接") || ex.Message.Contains("添加商品异常") | ex.Message.Contains("商家已设置该商品仅指定作者可推广")) { e.SendMessage(Class1.Config.SearchNoCommissionTip);//未搜索到提示语 db.UpdateRecord(memberTmp.id); var shared = new Dictionary(); shared["msg_type"] = "查询宝贝"; shared["cps_type"] = CpsType.抖音联盟; shared["msg_username"] = memberTmp.username; shared["price"] = "未知"; shared["title"] = message; shared["coupon_price"] = "未知"; shared["user_point"] = "未知"; shared["economize"] = "未知"; var sharedEvent = new SharedEvents(shared); EventClient.OnEvent(sender, sharedEvent); } else if (ex.Message.Contains("转链异常") || ex.Message.Contains("当前商品暂不支持站外分享")) { e.SendMessage(Class1.Config.SearchNoCommissionTip);//未搜索到提示语 throw ex; } else throw ex; } #endregion } catch (Exception ex) { if (ex.Message.Contains("商品不存在") || ex.Message.Contains("商品未推广") || ex.Message.Contains("商家已设置该商品仅指定作者可推广")) { e.SendMessage(Class1.Config.SearchNoCommissionTip);//未搜索到提示语 ApiClient.GetSession().UpdateRecord(memberTmp.id); var shared = new Dictionary(); shared["msg_type"] = "查询宝贝"; shared["cps_type"] = CpsType.抖音联盟; shared["msg_username"] = memberTmp.username; shared["price"] = "未知"; shared["title"] = "未知"; shared["coupon_price"] = "未知"; shared["user_point"] = "未知"; shared["economize"] = "未知"; var sharedEvent = new SharedEvents(shared); EventClient.OnEvent(sender, sharedEvent); return true; } if (ex.Message.StartsWith("@")) plugin.OnLog($"W :({e.RobotInfo.nick}【{e.RobotInfo.name}】){ex.Message.Replace("@", "")}"); else plugin.OnLog($"W:({e.RobotInfo.nick}【{e.RobotInfo.name}】){ex.Message} - {ex.StackTrace}"); plugin.OnLog(ApiClient.Setting.SystemConfig.msg_error); } return false; } } }