using AllBase; using AllBase.Helper; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using TemuKJD.BaseForms; using Work.Services; namespace TemuKJD.WXForms.ProductForms { public partial class WXViolationLogsForm : BaseForm { private readonly BindingList rows = new BindingList(); private Dictionary reasons; private Dictionary shops; private const int PageSize = 50; private readonly List pageCursors = new List { 0 }; private int currentPage; public WXViolationLogsForm() { InitializeComponent(); action.SelectedIndex = 0; grid.AutoGenerateColumns = false; grid.DataSource = rows; } private void Save_Click(object sender, EventArgs e) { var config = GlobalConfig.GlobalSettings; config.AutoReportViolationProducts = report.Checked; config.AutoExcludeViolationProductsOnUpload = exclude.Checked; config.AutoDelistViolationProducts = delist.Checked; StartUp.SaveGlobalSettings(); message.Text = "配置已保存"; } private void Form_VisibleChanged(object sender, EventArgs e) { if (!Visible) return; var config = GlobalConfig.GlobalSettings; report.Checked = config.AutoReportViolationProducts; exclude.Checked = config.AutoExcludeViolationProductsOnUpload; delist.Checked = config.AutoDelistViolationProducts; var selected = shop.SelectedValue as string; shops = GlobalConfig.ShopLoginList.Where(x => !string.IsNullOrWhiteSpace(x.ShopId)) .GroupBy(x => x.ShopId).ToDictionary(g => g.Key, g => string.IsNullOrWhiteSpace(g.First().ShopAccount) ? "未知店铺" : g.First().ShopAccount); shop.DataSource = new[] { new KeyValuePair("", "全部店铺") }.Concat(shops).ToList(); if (selected != null && shops.ContainsKey(selected)) shop.SelectedValue = selected; } private async void Query_Click(object sender, EventArgs e) => await QueryAsync(0, reset: true); private async void Pagination_PageChange(object sender) { int targetPage = pagination.CurrentPage - 1; if (targetPage != currentPage) await QueryAsync(targetPage); } private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.Value == null) return; switch (grid.Columns[e.ColumnIndex].DataPropertyName) { case nameof(GoodsViolationLogEntity.ShopId): e.Value = shops.TryGetValue((string)e.Value, out var name) ? name : "未知店铺"; e.FormattingApplied = true; break; case nameof(GoodsViolationLogEntity.ReasonId): e.Value = reasons.TryGetValue((int)e.Value, out var label) ? label : "未知违规类型"; e.FormattingApplied = true; break; case nameof(GoodsViolationLogEntity.Action): var index = (int)(ViolationLogAction)e.Value; e.Value = index > 0 && index < action.Items.Count ? action.Items[index] : "未知日志动作"; e.FormattingApplied = true; break; } } private async Task QueryAsync(int targetPage, bool reset = false) { if (!filters.Enabled) return; filters.Enabled = false; pagination.Enabled = false; try { if (reset) { currentPage = 0; pageCursors.Clear(); pageCursors.Add(0); rows.Clear(); } message.Text = "正在查询…"; if (reasons == null) { var types = await CloudGoodsService.GetViolationReasons(); if (IsDisposed) return; reasons = types.ToDictionary(type => type.Id, type => type.Name); reason.DataSource = new[] { new KeyValuePair(0, "全部类型") } .Concat(types.Where(type => type.IsViolation).Select(type => new KeyValuePair(type.Id, type.Name))).ToList(); } var selected = shop.SelectedValue as string; var ids = string.IsNullOrEmpty(selected) ? shops.Keys.ToArray() : new[] { selected }; if (ids.Length == 0) { message.Text = "暂无可查询的店铺"; return; } var reasonId = (int)reason.SelectedValue; var actionId = action.SelectedIndex; var cursor = pageCursors[targetPage]; var matches = new List(); while (matches.Count <= PageSize) { var batch = await CloudGoodsService.GetViolationLogs(ids, beforeId: cursor, size: PageSize); if (IsDisposed) return; foreach (var log in batch) { if (cursor != 0 && log.Id >= cursor) throw new InvalidOperationException("违规日志分页顺序异常。"); cursor = log.Id; if ((reasonId == 0 || reasonId == log.ReasonId) && (actionId == 0 || actionId == (int)log.Action)) matches.Add(log); if (matches.Count > PageSize) break; } if (batch.Count < PageSize) break; } if (matches.Count <= PageSize || pageCursors.ElementAtOrDefault(targetPage + 1) != matches[PageSize - 1].Id) { pageCursors.RemoveRange(targetPage + 1, pageCursors.Count - targetPage - 1); if (matches.Count > PageSize) pageCursors.Add(matches[PageSize - 1].Id); } currentPage = targetPage; rows.Clear(); foreach (var log in matches.Take(PageSize)) rows.Add(log); message.Text = rows.Count == 0 ? "无匹配日志" : $"本页 {rows.Count} 条"; } catch (Exception ex) { message.Text = "查询失败:" + ex.Message; } finally { if (!IsDisposed) { pagination.TotalPage = pageCursors.Count; if (pagination.CurrentPage != currentPage + 1) pagination.CurrentPage = currentPage + 1; filters.Enabled = true; pagination.Enabled = true; } } } } }