添加市场

This commit is contained in:
liu
2026-08-20 15:39:39 +08:00
parent cd7007bc49
commit 22237a47e7
20 changed files with 134 additions and 239 deletions
+4 -3
View File
@@ -20,7 +20,7 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class ProductExport implements FromCollection, WithStrictNullComparison, WithStyles
{
/** 列头(与 ProductImport 的解析顺序一一对应,改动需同步) */
public const array HEADERS = ['品名', '分类', '供应商', '规格/包规', '单位', '成本价', '排序', '库存', '保质期', '状态', '备注'];
public const array HEADERS = ['品名', '分类', '供应商', '市场', '规格/包规', '单位', '成本价', '排序', '库存', '保质期', '状态', '备注'];
private ?Collection $rows = null;
@@ -46,7 +46,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
$rows = [self::HEADERS];
if ($this->template) {
$rows[] = ['西红柿', '蔬菜/茄果类', '示例供应商', '10斤/箱', '斤', 2.5, 0, 100, 3, '上架', '示例行,导入前请删除'];
$rows[] = ['西红柿', '蔬菜/茄果类', '示例供应商', '新发地', '10斤/箱', '斤', 2.5, 0, 100, 3, '上架', '示例行,导入前请删除'];
return $this->rows = collect($rows);
}
@@ -65,6 +65,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
$product->name,
$categoryPaths[(int) $product->category_id] ?? '',
$supplierNames[(int) $product->supplier_id] ?? '',
$product->market,
$product->spec,
$product->unit,
(float) $product->cost_price,
@@ -87,7 +88,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
$this->collection();
$sheet->freezePane('A2');
$widths = [20, 16, 14, 14, 8, 10, 8, 8, 8, 8, 24];
$widths = [20, 16, 14, 12, 14, 8, 10, 8, 8, 8, 8, 24];
foreach ($widths as $index => $width) {
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
}
+6 -4
View File
@@ -126,6 +126,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
'category' => $categoryNames[(int) $productId] ?? '',
'product_name' => (string) ($snapshot->product_name ?? $product->name),
'supplier' => $supplierNames[$rowSupplierId] ?? '',
'market' => (string) ($product->market ?? ''),
'product_spec' => $spec,
'unit' => (string) ($snapshot->unit ?? $product->unit),
'cost_price' => (float) ($snapshot->cost_price ?? $product->cost_price),
@@ -172,7 +173,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
// 列头
$rows[] = array_merge(
['序号', '分类', '品名', '供应商', '包规', '单位', '成本', '参考零售价', '数量', '实际称重', '金额'],
['序号', '分类', '品名', '供应商', '市场', '包规', '单位', '成本', '参考零售价', '数量', '实际称重', '金额'],
array_values($this->storeNames),
);
$this->specialRows[++$rowIndex] = 'header';
@@ -189,6 +190,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
$item['category'],
$item['product_name'],
$item['supplier'],
$item['market'],
$item['product_spec'],
$item['unit'],
$item['cost_price'],
@@ -208,7 +210,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
// 合计行(行合计 + 门店列合计)
$rows[] = array_merge(
['', '', '合计', '', '', '', '', '', (float) $totalQuantity, (float) $totalWeight, (float) $totalAmount],
['', '', '合计', '', '', '', '', '', '', (float) $totalQuantity, (float) $totalWeight, (float) $totalAmount],
array_values($storeTotals),
);
$this->specialRows[++$rowIndex] = 'summary';
@@ -225,7 +227,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
$this->collection();
$sheet->freezePane('A' . ($this->headerRow + 1));
$widths = [6, 10, 20, 12, 12, 8, 10, 12, 10, 12, 12];
$widths = [6, 10, 20, 12, 12, 12, 8, 10, 12, 10, 12, 12];
foreach ($widths as $index => $width) {
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
}
@@ -233,7 +235,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
// 门店列整列(列头 → 合计行)填充突出颜色
$storeCount = count($this->storeNames);
for ($i = 0; $i < $storeCount; $i++) {
$column = Coordinate::stringFromColumnIndex(12 + $i);
$column = Coordinate::stringFromColumnIndex(13 + $i);
$sheet->getColumnDimension($column)->setWidth(12);
$sheet->getStyle($column . $this->headerRow . ':' . $column . $this->lastRow)
->getFill()
+4 -3
View File
@@ -55,7 +55,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
$rowIndex++;
// 列头
$rows[] = ['序号', '品名', '包规', '单位', '单价', '数量', '重量(斤)', '预计金额'];
$rows[] = ['序号', '品名', '市场', '包规', '单位', '单价', '数量', '重量(斤)', '预计金额'];
$this->specialRows[++$rowIndex] = 'header';
$this->headerRow = $rowIndex;
@@ -67,6 +67,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
$rows[] = [
$sort + 1,
$item['product_name'],
$item['market'],
$item['product_spec'],
$item['unit'],
(float) $item['price'],
@@ -81,7 +82,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
}
// 合计行
$rows[] = ['', '合计', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
$rows[] = ['', '合计', '', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
$this->specialRows[++$rowIndex] = 'summary';
return $this->rows = collect($rows);
@@ -100,7 +101,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
$this->collection();
$sheet->freezePane('A' . ($this->headerRow + 1));
$widths = [6, 24, 14, 8, 10, 10, 12, 12];
$widths = [6, 24, 12, 14, 8, 10, 10, 12, 12];
foreach ($widths as $index => $width) {
$sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($index + 1))
->setWidth($width);
+4 -3
View File
@@ -56,7 +56,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
$rowIndex++;
// 列头
$rows[] = ['序号', '品名', '包规', '单位', '成本价', '数量', '重量(斤)', '金额'];
$rows[] = ['序号', '品名', '市场', '包规', '单位', '成本价', '数量', '重量(斤)', '金额'];
$this->specialRows[++$rowIndex] = 'header';
$this->headerRow = $rowIndex;
@@ -68,6 +68,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
$rows[] = [
$sort + 1,
$item['product_name'],
$item['market'],
$item['product_spec'],
$item['unit'],
(float) $item['cost_price'],
@@ -82,7 +83,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
}
// 合计行
$rows[] = ['', '合计', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
$rows[] = ['', '合计', '', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
$this->specialRows[++$rowIndex] = 'summary';
return $this->rows = collect($rows);
@@ -101,7 +102,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
$this->collection();
$sheet->freezePane('A' . ($this->headerRow + 1));
$widths = [6, 24, 14, 8, 10, 10, 12, 12];
$widths = [6, 24, 12, 14, 8, 10, 10, 12, 12];
foreach ($widths as $index => $width) {
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
}
@@ -35,6 +35,7 @@ class ProductController extends BaseController
'name' => 'like',
'category_id' => '=',
'supplier_id' => '=',
'market' => 'like',
'status' => '=',
];
@@ -134,6 +134,7 @@ class PurchaseOrderController extends BaseController
'unit' => $first->unit, // 单位
'supplier_id' => (int) $first->supplier_id, // 供应商id
'supplier' => $supplier, // 供应商
'market' => (string) ($product?->market ?? ''), // 市场(取商品档案)
'cost_price' => $first->cost_price, // 成本价
'quantity' => $quantity,
'weight' => (float) $weight,
@@ -22,6 +22,7 @@ class ProductFormRequest extends BaseFormRequest
return [
'category_id' => ['required','integer', new Exists(ProductCategoryModel::class,'id')],
'supplier_id' => ['nullable','integer', 'exclude_if:supplier_id,0', new Exists(SupplierModel::class,'id')],
'market' => 'nullable|string|max:50',
'name' => 'required|string|max:100',
'spec' => 'nullable|string|max:100',
'unit' => 'nullable|string|max:20',
+8 -2
View File
@@ -92,8 +92,8 @@ class ProductImport implements ToCollection
*/
private function parseRow(array $cells, Collection $categories, array $leafIds): array
{
[$name, $categoryName, $supplierName, $spec, $unit, $costPrice, $sort, $stock, $shelfLife, $statusText, $remark] =
array_pad(array_slice($cells, 0, 11), 11, null);
[$name, $categoryName, $supplierName, $market, $spec, $unit, $costPrice, $sort, $stock, $shelfLife, $statusText, $remark] =
array_pad(array_slice($cells, 0, 12), 12, null);
$errors = [];
@@ -120,6 +120,11 @@ class ProductImport implements ToCollection
$errors[] = '供应商名称最长 100 个字符';
}
$market = (string) $market;
if (mb_strlen($market) > 50) {
$errors[] = '市场最长 50 个字符';
}
$spec = (string) $spec;
if (mb_strlen($spec) > 100) {
$errors[] = '规格/包规最长 100 个字符';
@@ -169,6 +174,7 @@ class ProductImport implements ToCollection
'category_id' => $categoryId,
'supplier_id' => 0, // 写入阶段按 supplier_name 解析(匹配或自动创建)
'supplier_name' => $supplierName, // 写入阶段解析,不入 product 表
'market' => $market,
'name' => $name,
'spec' => $spec,
'unit' => $unit,
+1
View File
@@ -27,6 +27,7 @@ class ProductModel extends Model
protected $fillable = [
'category_id',
'supplier_id',
'market',
'name',
'spec',
'unit',
+5 -2
View File
@@ -80,6 +80,7 @@ class PurchaseItemService
'product_name' => $first->product_name,
'product_spec' => $first->product_spec,
'unit' => $first->unit,
'market' => (string) data_get($first, 'market', ''),
// 加权平均单价(保证 单价×数量=预计金额)
'price' => $quantity > 0
? bcdiv($amount, (string) $quantity, 2)
@@ -124,6 +125,7 @@ class PurchaseItemService
'product_name' => $first->product_name,
'product_spec' => $first->product_spec,
'unit' => $first->unit,
'market' => (string) data_get($first, 'market', ''),
'cost_price' => (string) $first->cost_price,
'quantity' => $quantity,
'weight' => $weight,
@@ -151,17 +153,18 @@ class PurchaseItemService
->get()
->makeVisible('cost_price');
// 排序键:商品分类 sort → 商品 sort(商品含软删除,保证历史单据可导出)
// 排序键:商品分类 sort → 商品 sort;市场取商品档案(商品含软删除,保证历史单据可导出)
$products = ProductModel::withTrashed()
->with('category:id,sort')
->whereIn('id', $items->pluck('product_id')->unique())
->get(['id', 'category_id', 'sort'])
->get(['id', 'category_id', 'sort', 'market'])
->keyBy('id');
foreach ($items as $item) {
$product = $products->get((int) $item->product_id);
$item->setAttribute('category_sort', (int) ($product?->category?->sort ?? 9999));
$item->setAttribute('product_sort', (int) ($product?->sort ?? 9999));
$item->setAttribute('market', (string) ($product?->market ?? ''));
}
return $items;