6
0
Fork 0

admin PointLogController Excel导出

base
panliang 2025-12-04 19:34:32 +08:00
parent 1ecef40100
commit 86899df055
5 changed files with 196 additions and 8 deletions

View File

@ -77,7 +77,9 @@ class OrderController extends AdminController
'商品ID',
'商品名称',
'数量',
'价格',
'销售价格',
'会员价格',
'成本价',
'积分',
'金额',
'待发货数量',
@ -88,9 +90,26 @@ class OrderController extends AdminController
'订单状态',
'下单时间',
'是否换货',
'本次积分余额',
'首次办卡时间'
]));
$query->lazyById()->each(function ($order) use ($writer) {
$pointBalance = '-';
if ($order->point_discount_amount > 0) {
$pointLog = PointLog::query()
->where('loggable_type', (new Order())->getMorphClass())
->where('loggable_id', $order->id)
->where('action', PointLogAction::Consumption)
->first();
$pointBalance = bcdiv($pointLog->after_points, 100, 0);
}
$userVipTime = '-';
$userVip = UserVip::where('user_id', $order->user_id)->where('status', UserVip::STATUS_SUCCESS)->orderBy('success_time', 'asc')->first();
if ($userVip) {
$userVipTime = $userVip->success_time->format("Y-m-d H:i:s");
}
foreach ($order->products as $product) {
$writer->addRow(
WriterEntityFactory::createRowFromArray([
@ -98,6 +117,8 @@ class OrderController extends AdminController
$product->name,
$product->quantity,
bcdiv($product->sell_price, '100', 2),
bcdiv($product->vip_price, '100', 2),
bcdiv($product->cost_price, '100', 2),
bcdiv($product->point_discount_amount, '100', 2),
bcdiv($product->total_amount, '100', 2),
$product->remain_quantity,
@ -108,6 +129,8 @@ class OrderController extends AdminController
$order->order_status_text,
$order->created_at?->toDateTimeString(),
$order->is_change ? '是' : '否',
$pointBalance,
$userVipTime,
])
);
}
@ -474,6 +497,10 @@ class OrderController extends AdminController
$grid->column('vip_price', '会员价格')->display(function ($value) {
return bcdiv($value, 100, 2);
})->prepend('¥');
$grid->column('cost_price', '成本价')->display(function ($value) {
return bcdiv($value, 100, 2);
})->prepend('¥');
$grid->column('quantity');
$grid->column('vip_discount_amount', '会员折扣')->display(function ($value) {
return bcdiv($value, 100, 2);
@ -706,21 +733,41 @@ class OrderController extends AdminController
$writer->openToBrowser('发货单'.date('Ymd').'.xlsx');
$writer->addRow(WriterEntityFactory::createRowFromArray([
'订单编号', '下单手机号', '商品编号', '商品名称', '数量', '姓名', '电话', '地址', '下单时间', '快递公司', '发货单号', '发货数量',
'订单编号', '下单手机号', '商品编号', '商品名称', '销售价格', '会员价格', '成本价', '下单数量', '剩余发货数量', '姓名', '电话', '地址', '下单时间', '快递公司', '发货单号', '发货数量', '本次积分余额', '首次办卡时间'
]));
foreach (Order::with('products', 'user')->needShipping()->cursor() as $order) {
$pointBalance = '-';
if ($order->point_discount_amount > 0) {
$pointLog = PointLog::query()
->where('loggable_type', (new Order())->getMorphClass())
->where('loggable_id', $order->id)
->where('action', PointLogAction::Consumption)
->first();
$pointBalance = bcdiv($pointLog->after_points, 100, 0);
}
$userVipTime = '-';
$userVip = UserVip::where('user_id', $order->user_id)->where('status', UserVip::STATUS_SUCCESS)->orderBy('success_time', 'asc')->first();
if ($userVip) {
$userVipTime = $userVip->success_time->format("Y-m-d H:i:s");
}
foreach ($order->products as $product) {
if ($product->remain_quantity > 0) {
$writer->addRow(WriterEntityFactory::createRowFromArray([
$order->sn,
$order->user->phone,
$product->sku_id,
$product->name.'数量:'.$product->remain_quantity,
$product->name,
bcdiv($product->sell_price, 100, 2),
bcdiv($product->vip_price, 100, 2),
bcdiv($product->cost_price, 100, 2),
$product->quantity,
$product->remain_quantity,
$order->consignee_name,
$order->consignee_telephone,
$order->consignee_zone.$order->consignee_address,
$order->created_at->toDateTimeString(),
$pointBalance,
$userVipTime,
]));
}
}

View File

@ -5,7 +5,11 @@ namespace App\Admin\Controllers;
use App\Admin\Repositories\PointLog as PointLogRepository;
use App\Admin\Widgets\InfoBox;
use App\Enums\PointLogAction;
use App\Models\Order;
use App\Models\OrderProduct;
use App\Models\PointLog;
use App\Models\UserInfo;
use App\Models\UserVip;
use Dcat\Admin\Admin;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
@ -32,11 +36,78 @@ class PointLogController extends AdminController
$builder = PointLogRepository::with(['user', 'administrator']);
return Grid::make($builder, function (Grid $grid) {
$grid->export()->disableExportAll()->titles([
'id' => 'ID',
'username' => '用户昵称',
'user_id' => __('point-log.fields.user.phone'),
'first_rechare_time' => '首次充值时间',
'first_rechare_type' => '首次充值类型',
'first_rechare_money' => '首次充值金额',
'renew_rechare_count' => '续费次数',
'renew_rechare_type' => '续费类型',
'renew_rechare_latest_time' => '最近一次续费时间',
'renew_rechare_money_total' => '续费金额合计',
'action' => __('point-log.fields.action'),
'change_points' => __('point-log.fields.change_points'),
'before_points' => __('point-log.fields.before_points'),
'after_points' => __('point-log.fields.after_points'),
'goods_cost_price' => '商品成本价',
'remark' => __('point-log.fields.remark'),
'administrator' => '操作人',
'created_at' => __('admin.created_at'),
])->rows(function ($rows) {
foreach ($rows as &$row) {
$userInfo = UserInfo::where('user_id', $row['user_id'])->first();
$firstVip = UserVip::where('user_id', $row['user_id'])->where('status', UserVip::STATUS_SUCCESS)->orderBy('success_time', 'asc')->first();
$vipCount = UserVip::where('user_id', $row['user_id'])->where('status', UserVip::STATUS_SUCCESS)->count();
$row['user_id'] = data_get($row, 'user.phone');
$row['username'] = data_get($userInfo, 'nickname');
$row['first_rechare_time'] = $firstVip ? $firstVip->success_time->format('Y-m-d H:i:s') : '';
$row['first_rechare_type'] = data_get($firstVip, 'name');
$row['first_rechare_money'] = data_get($firstVip, 'price');
$row['renew_rechare_count'] = '';
$row['renew_rechare_type'] = '';
$row['renew_rechare_latest_time'] = '';
$row['renew_rechare_money_total'] = '';
if ($vipCount > 1) {
$row['renew_rechare_count'] = $vipCount - 1;
$latestVip = UserVip::where('user_id', $row['user_id'])->where('status', UserVip::STATUS_SUCCESS)->orderBy('success_time', 'desc')->first();
$row['renew_rechare_type'] = data_get($latestVip, 'name');
$row['renew_rechare_latest_time'] = data_get($latestVip, 'success_time');
$sum = UserVip::where('user_id', $row['user_id'])->where('status', UserVip::STATUS_SUCCESS)->where('id', '!=', $firstVip->id)->sum('price');
$row['renew_rechare_money_total'] = $sum;
}
$row['action'] = PointLogAction::getLabel(data_get($row, 'action'));
$row['change_points'] = bcdiv(data_get($row, 'change_points'), 100, 2);
$row['before_points'] = bcdiv(data_get($row, 'before_points'), 100, 2);
$row['after_points'] = bcdiv(data_get($row, 'after_points'), 100, 2);
$row['remark'] = data_get($row, 'remark');
// 商品成本价
$row['goods_cost_price'] = '';
if ($row['loggable_type'] == (new Order)->getMorphClass()) {
$costPrice = OrderProduct::where('order_id', $row['loggable_id'])->sum('cost_price');
$row['goods_cost_price'] = bcdiv($costPrice, 100, 2);
}
$row['administrator'] = data_get($row, 'administrator.name');
$row['created_at'] = data_get($row, 'created_at');
}
return $rows;
});
$grid->model()->orderBy('id', 'desc');
$grid->column('id')->sortable();
$grid->column('user.phone')->copyable();
$grid->column('action')->display(fn ($action) => $action->label())->label();;
$grid->column('action')->display(fn ($action) => $action->label())->label();
$grid->column('change_points')->display(function ($value) {
return bcdiv($value, 100, 2);
});

View File

@ -24,4 +24,8 @@ enum PointLogAction: int {
self::Refund->value => '退还',
];
}
public static function getLabel($value) {
return data_get(static::options(), $value, "");
}
}

View File

@ -16,6 +16,7 @@
"alipaysdk/easysdk": "^2.2",
"alphasnow/aliyun-oss-laravel": "^3.0",
"box/spout": "^3.3",
"dcat/easy-excel": "^1.1",
"dcat/laravel-admin": "2.1.5-beta",
"fruitcake/laravel-cors": "^2.0",
"gregwar/captcha": "^1.1",

73
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5ea856539b7c9cb2093859052437846e",
"content-hash": "c446666cf2eb04902a98f7b967974898",
"packages": [
{
"name": "adbario/php-dot-notation",
@ -1107,6 +1107,71 @@
},
"time": "2020-10-02T16:03:48+00:00"
},
{
"name": "dcat/easy-excel",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/jqhph/easy-excel.git",
"reference": "20ee838b07f1f5d9c075b84e6f4807cbb21c44b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jqhph/easy-excel/zipball/20ee838b07f1f5d9c075b84e6f4807cbb21c44b0",
"reference": "20ee838b07f1f5d9c075b84e6f4807cbb21c44b0",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"box/spout": "~3",
"league/flysystem": "~1|~2|~3",
"php": ">=7.1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2",
"phpunit/phpunit": "~7|~8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Dcat\\EasyExcel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "jqh",
"email": "841324345@qq.com"
}
],
"description": "使用简单实用的语义化接口快速读写Excel文件",
"homepage": "https://github.com/jqhph/easy-excel",
"keywords": [
"box spout",
"csv",
"easy excel",
"excel",
"ods",
"office",
"read",
"spreadsheet",
"stream",
"xlsx"
],
"support": {
"issues": "https://github.com/jqhph/easy-excel/issues",
"source": "https://github.com/jqhph/easy-excel/tree/1.1.0"
},
"time": "2022-03-03T03:04:13+00:00"
},
{
"name": "dcat/laravel-admin",
"version": "2.1.5-beta",
@ -12085,12 +12150,12 @@
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^8.0"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
"platform-dev": {},
"plugin-api-version": "2.6.0"
}