Files
PackagingMallShipper/PackagingMallShipper/Services/ExcelService.cs
Administrator 0763a2623b feat: 完善登录验证码、订单同步和打包功能
- 添加验证码登录支持(图形验证码显示和输入)
- 修复订单同步,正确解析收件人信息(从logisticses合并)
- 修复API端点配置(user.api.it120.cc)
- 添加Costura.Fody实现单文件EXE打包
- 添加应用图标(app.ico)
- 添加Inno Setup安装脚本(支持Win7+)
- 暂时禁用导入发货功能
- 添加.gitignore文件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 00:05:22 +08:00

151 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ClosedXML.Excel;
using PackagingMallShipper.Helpers;
using PackagingMallShipper.Models;
namespace PackagingMallShipper.Services
{
public class ExcelService : IExcelService
{
private readonly IOrderService _orderService;
private readonly IShipService _shipService;
public ExcelService(IOrderService orderService, IShipService shipService)
{
_orderService = orderService;
_shipService = shipService;
}
public async Task<int> ExportPendingOrdersAsync(string filePath)
{
var orders = await _orderService.GetOrdersAsync(status: 1);
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("待发货订单");
var headers = new[]
{
"订单号", "下单时间", "收件人", "联系电话",
"省份", "城市", "区县", "详细地址",
"商品信息", "订单金额", "快递公司", "快递单号"
};
for (int i = 0; i < headers.Length; i++)
{
var cell = worksheet.Cell(1, i + 1);
cell.Value = headers[i];
cell.Style.Font.Bold = true;
cell.Style.Fill.BackgroundColor = XLColor.LightGray;
}
for (int i = 0; i < orders.Count; i++)
{
var order = orders[i];
var row = i + 2;
worksheet.Cell(row, 1).Value = order.OrderNumber;
worksheet.Cell(row, 2).Value = order.DateAdd?.ToString("yyyy-MM-dd HH:mm:ss");
worksheet.Cell(row, 3).Value = order.LogisticsName;
var mobileCell = worksheet.Cell(row, 4);
mobileCell.Value = order.LogisticsMobile;
mobileCell.Style.NumberFormat.Format = "@";
worksheet.Cell(row, 5).Value = order.LogisticsProvince;
worksheet.Cell(row, 6).Value = order.LogisticsCity;
worksheet.Cell(row, 7).Value = order.LogisticsDistrict;
worksheet.Cell(row, 8).Value = order.LogisticsAddress;
worksheet.Cell(row, 9).Value = order.GoodsInfo;
worksheet.Cell(row, 10).Value = order.AmountReal;
worksheet.Cell(row, 11).Value = "";
worksheet.Cell(row, 12).Value = "";
}
worksheet.Column(1).Width = 20;
worksheet.Column(2).Width = 18;
worksheet.Column(4).Width = 15;
worksheet.Column(8).Width = 40;
worksheet.Column(9).Width = 30;
worksheet.Column(12).Width = 20;
worksheet.SheetView.FreezeRows(1);
workbook.SaveAs(filePath);
}
return orders.Count;
}
public async Task<ImportShipResult> ImportAndShipAsync(string filePath)
{
var ordersToShip = new List<ShipOrderRequest>();
int totalRows = 0;
var errors = new List<string>();
using (var workbook = new XLWorkbook(filePath))
{
var worksheet = workbook.Worksheet(1);
var rows = worksheet.RangeUsed().RowsUsed().Skip(1);
totalRows = rows.Count();
foreach (var row in rows)
{
var orderNumber = row.Cell(1).GetString().Trim();
var expressCompanyName = row.Cell(11).GetString().Trim();
var trackingNumber = row.Cell(12).GetString().Trim();
if (string.IsNullOrEmpty(orderNumber))
continue;
if (string.IsNullOrEmpty(trackingNumber))
{
errors.Add($"订单 {orderNumber}: 缺少快递单号");
continue;
}
var order = await _orderService.GetOrderByNumberAsync(orderNumber);
if (order == null)
{
errors.Add($"订单 {orderNumber}: 未找到");
continue;
}
if (order.Status != 1)
{
errors.Add($"订单 {orderNumber}: 状态不是待发货");
continue;
}
var expressId = ExpressCompanies.GetIdByName(expressCompanyName);
if (expressId == 0)
expressId = -1;
ordersToShip.Add(new ShipOrderRequest
{
OrderId = order.Id,
OrderNumber = orderNumber,
ExpressCompanyId = expressId,
TrackingNumber = trackingNumber
});
}
}
var shipResult = await _shipService.BatchShipOrdersAsync(ordersToShip);
return new ImportShipResult
{
TotalRows = totalRows,
ValidOrders = ordersToShip.Count,
SuccessCount = shipResult.SuccessCount,
FailedCount = shipResult.FailedCount,
Errors = errors.Concat(
shipResult.Results
.Where(r => !r.Success)
.Select(r => $"订单 {r.OrderNumber}: {r.Error}")
).ToList()
};
}
}
}