Merge pull request '添加商品溯源导出' (#551) from dev into main

Reviewed-on: #551
This commit is contained in:
mkm 2025-03-17 18:36:36 +08:00
commit 2c5c541fe8
7 changed files with 164 additions and 11 deletions

View File

@ -7,6 +7,11 @@ use app\admin\controller\BaseAdminController;
use app\admin\lists\product_source_link\ProductSourceLinkLists;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\validate\product_source_link\ProductSourceLinkValidate;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_order\WarehouseOrder;
use app\common\service\xlsx\ProductSourceLinkXsl;
/**
@ -20,7 +25,6 @@ class ProductSourceLinkController extends BaseAdminController
/**
* @notes 获取商品溯源管理列表
* @return \think\response\Json
* @author admin
* @date 2025/03/12 10:03
*/
@ -32,7 +36,6 @@ class ProductSourceLinkController extends BaseAdminController
/**
* @notes 添加商品溯源管理
* @return \think\response\Json
* @author admin
* @date 2025/03/12 10:03
*/
@ -49,7 +52,6 @@ class ProductSourceLinkController extends BaseAdminController
/**
* @notes 编辑商品溯源管理
* @return \think\response\Json
* @author admin
* @date 2025/03/12 10:03
*/
@ -66,7 +68,6 @@ class ProductSourceLinkController extends BaseAdminController
/**
* @notes 删除商品溯源管理
* @return \think\response\Json
* @author admin
* @date 2025/03/12 10:03
*/
@ -80,7 +81,6 @@ class ProductSourceLinkController extends BaseAdminController
/**
* @notes 获取商品溯源管理详情
* @return \think\response\Json
* @author admin
* @date 2025/03/12 10:03
*/
@ -91,5 +91,58 @@ class ProductSourceLinkController extends BaseAdminController
return $this->data($result);
}
public function export()
{
$params = $this->request->post();
$query = ProductSourceLink::field('id,purchase_uid,product_id,warehouse_id');
if (!empty($params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
if (!empty($params['purchase_uid'])) {
$query->where('purchase_uid', $params['purchase_uid']);
}
if (!empty($params['warehouse_id'])) {
$query->where('warehouse_id', $params['warehouse_id']);
}
$list = $query->with(['product', 'warehouse', 'purchase'])
->field(['id', 'purchase_uid', 'product_id', 'warehouse_id',])
->order(['id' => 'desc'])
->select()
->each(function ($item) {
$item->total_nums = ProductSourceLinkInfo::where('product_id', $item->product_id)->where('oid', $item->id)->where('types', 1)->sum('nums');
$item->warehouse_outbound_nums = ProductSourceLinkInfo::where('product_id', $item->product_id)->where('oid', $item->id)->where('types', 2)->sum('nums');
})
->toArray();
$linkInfos = ProductSourceLinkInfo::whereIn('oid', array_column($list, 'id'))->select()->toArray();
$orderSnList = WarehouseOrder::field('id,code')->whereIn('id', array_unique(array_column($linkInfos, 'link_id')))->select()->toArray();
$orderSnList = reset_index($orderSnList, 'id');
foreach ($list as &$item) {
$item['in_order_no'] = [];
$item['out_order_no'] = [];
$item['in_num'] = 0;
$item['out_num'] = 0;
foreach ($linkInfos as $linkInfo) {
if ($linkInfo['oid'] == $item['id']) {
$orderSnItem = $orderSnList[$linkInfo['link_id']] ?? [];
if ($linkInfo['types'] == ProductSourceLinkInfo::TypeIn) {
if (!empty($orderSnItem)) {
$item['in_order_no'][] = $orderSnItem['code'];
}
$item['in_num'] = bcmul($item['in_num'], $linkInfo['nums'], 2);
} else {
if (!empty($orderSnItem)) {
$item['out_order_no'][] = $orderSnItem['code'];
}
$item['out_num'] = bcmul($item['out_num'], $linkInfo['nums'], 2);
}
}
}
$item['in_order_no'] = !empty($item['in_order_no']) ? implode(',', $item['in_order_no']) : '';
$item['out_order_no'] =!empty($item['out_order_no']) ? implode(',', $item['out_order_no']) : '';
}
$file_path = (new ProductSourceLinkXsl())->export($list);
return $this->success('导出成功', ['url' => $file_path]);
}
}

View File

@ -7,6 +7,7 @@ use app\admin\lists\BaseAdminDataLists;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\lists\ListsSearchInterface;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_product\WarehouseProduct;
/**
@ -27,7 +28,7 @@ class ProductSourceLinkLists extends BaseAdminDataLists implements ListsSearchIn
public function setSearch(): array
{
return [
'=' => ['purchase_uid', 'product_id', 'warehouse_id'],
];
}
@ -43,8 +44,12 @@ class ProductSourceLinkLists extends BaseAdminDataLists implements ListsSearchIn
*/
public function lists(): array
{
return ProductSourceLink::where($this->searchWhere)
->with(['product','warehouse','purchase'])
$query = ProductSourceLink::where($this->searchWhere);
if (!empty($this->params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$this->params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
return $query->with(['product','warehouse','purchase'])
->field(['id', 'purchase_uid', 'product_id','warehouse_id',])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
@ -65,7 +70,12 @@ class ProductSourceLinkLists extends BaseAdminDataLists implements ListsSearchIn
*/
public function count(): int
{
return ProductSourceLink::where($this->searchWhere)->count();
$query = ProductSourceLink::where($this->searchWhere);
if (!empty($this->params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$this->params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
return $query->count();
}
}

View File

@ -119,7 +119,7 @@ class ProductSourceLinkLogic extends BaseLogic
*/
public static function outbound(array $info)
{
$query = ProductSourceLinkInfo::where('product_id', $info['product']['product_id'])->where('warehouse_id', 1)->where('current_nums', '>', 0);
$query = ProductSourceLinkInfo::where('product_id', $info['product']['product_id'])->where('current_nums', '>', 0);
if (!empty($info['is_store_order']) && $info['store_id']) {
$query->where('store_id', $info['store_id'])->whereIn('types', [ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeS2S]);
} else {

View File

@ -416,6 +416,11 @@ class PurchaseProductOfferLogic extends BaseLogic
$data['price'] = ceil($data['price'] * 10);
$data['price'] = bcdiv($data['price'], 10, 2);
}
$lastNum = substr($data['vip_price'], -1);
if ($lastNum > 0) {
$data['vip_price'] = ceil($data['vip_price'] * 10);
$data['vip_price'] = bcdiv($data['vip_price'], 10, 2);
}
}
$data['price_config'] = $priceConfig;
$find = StoreProductPrice::where(['offer_id' => $params['id']])->find();

View File

@ -83,6 +83,11 @@ class StoreProductPriceLogic extends BaseLogic
$params['price'] = ceil($params['price'] * 10);
$params['price'] = bcdiv($params['price'], 10, 2);
}
$lastNum = substr($params['vip_price'], -1);
if ($lastNum > 0) {
$params['vip_price'] = ceil($params['vip_price'] * 10);
$params['vip_price'] = bcdiv($params['vip_price'], 10, 2);
}
$find->save([
'status' => 1,
'purchase' => $params['purchase'],
@ -168,6 +173,11 @@ class StoreProductPriceLogic extends BaseLogic
$update['price'] = ceil($find['price'] * 10);
$update['price'] = bcdiv($update['price'], 10, 2);
}
$lastNum = substr($find['vip_price'], -1);
if ($lastNum > 0) {
$update['vip_price'] = ceil($find['vip_price'] * 10);
$update['vip_price'] = bcdiv($update['vip_price'], 10, 2);
}
$find->save($update);
StoreProduct::where('id', $find['product_id'])->update([
'purchase' => $find['purchase'] ?? 0,

View File

@ -12,7 +12,7 @@ use think\model\concern\SoftDelete;
/**
* 商品溯源管理模型
* Class ProductSourceLink
* Class ProductSourceLinkXsl
* @package app\common\model\product_source_link
*/
class ProductSourceLink extends BaseModel

View File

@ -0,0 +1,75 @@
<?php
namespace app\common\service\xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use Webman\Exception\BusinessException;
/**
* 订单出库
*/
class ProductSourceLinkXsl
{
public function export($data)
{
$title = '商品溯源信息';
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->mergeCells('A1:F1');
$sheet->setCellValue('A1', $title);
$sheet->setCellValue('A2', '商品ID:');
$sheet->setCellValue('B2', '商品名称:');
$sheet->setCellValue('C2', '入库数量:');
$sheet->setCellValue('D2', '出库数量');
$sheet->setCellValue('E2', '入库单号:');
$sheet->setCellValue('F2', '出库单号:');
// 设置默认的单元格样式
$defaultStyle = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
// 应用默认样式到整个工作表
$spreadsheet->getDefaultStyle()->applyFromArray($defaultStyle);
foreach ($data as $k => $v) {
$sheet->setCellValue('A' . ($k + 3), $v['product_id']);
$sheet->setCellValue('B' . ($k + 3), $v['product_name']);
$sheet->setCellValue('C' . ($k + 3), $v['in_num']);
$sheet->setCellValue('D' . ($k + 3), $v['out_num']);
$sheet->setCellValue('E' . ($k + 3), $v['in_order_no']);
$sheet->setCellValue('F' . ($k + 3), $v['out_order_no']);
}
// 设置单元格的样式
$styleArray = [
'font' => [
'bold' => true,
'size' => 16,
],
];
$sheet->getStyle('A1')->applyFromArray($styleArray);
$writer = new Xlsx($spreadsheet);
$dir = public_path() . '/export/' . date('Y-m');
if (!file_exists($dir)) {
// 尝试创建目录
if (!mkdir($dir)) {
throw new BusinessException('创建目录失败:/export/' . date('Y-m'));
}
}
$file_path = $dir . '/' . $title . date('Y年m月d日H时i分') . '.xlsx';
$url = '/export/' . date('Y-m') . '/' . $title . date('Y年m月d日H时i分') . '.xlsx';
// 保存文件到 public 下
$writer->save($file_path);
return getenv('APP_URL') . $url;
}
}