鲜花2.0-接口测试bug修复

This commit is contained in:
杨建炊 2024-08-14 17:02:31 +08:00
parent 05b5cd400a
commit 9e50b007eb
14 changed files with 190 additions and 68 deletions

View File

@ -8,7 +8,7 @@ use App\Http\Resources\DailySalesReportResource;
use App\Models\BusinessOrderItem;
use App\Models\DailySalesReport;
use App\Models\GoodsSku;
use App\Services\Service\SaleDataService;
use App\Services\Statistic\SaleDataService;
use App\Utils\FormatUtils;
use Carbon\Carbon;
use Illuminate\Http\Request;
@ -58,7 +58,9 @@ class DataCenterController extends Controller
$validator = Validator::make($allParams, [
'type' => 'required|integer', //1表示今日
'start_day' => 'sometimes|date_format:Y-m-d',
'end_day' => 'sometimes|date_format:Y-m-d'
'end_day' => 'sometimes|date_format:Y-m-d',
'start_time' => 'sometimes|date_format:Y-m-d H:i:s',
'end_time' => 'sometimes|date_format:Y-m-d H:i:s'
]);
if ($validator->fails()) {
@ -80,7 +82,9 @@ class DataCenterController extends Controller
$validator = Validator::make($request->all(), [
'type' => 'required|integer', //1表示今日
'start_day' => 'sometimes|date_format:Y-m-d',
'end_day' => 'sometimes|date_format:Y-m-d'
'end_day' => 'sometimes|date_format:Y-m-d',
'start_time' => 'sometimes|date_format:Y-m-d H:i:s',
'end_time' => 'sometimes|date_format:Y-m-d H:i:s'
]);
if ($validator->fails()) {
//校验失败返回异常
@ -97,7 +101,10 @@ class DataCenterController extends Controller
'type' => 'required|integer', //1表示今日
'start_day' => 'required_unless:type,1|date_format:Y-m-d',
'end_day' => 'required_unless:type,1|date_format:Y-m-d',
"interval" => 'sometimes|integer|max:120|min:1'
"interval" => 'sometimes|integer|max:120|min:1',
'start_time' => 'sometimes|date_format:Y-m-d H:i:s',
'end_time' => 'sometimes|date_format:Y-m-d H:i:s',
'sku_id' => 'sometimes|integer'
]);
if ($validator->fails()) {
//校验失败返回异常
@ -106,4 +113,20 @@ class DataCenterController extends Controller
}
return $this->success(SaleDataService::gmvStatistics($request));
}
public function lossRecordStatistics(Request $request)
{
//进行校验验证
$validator = Validator::make($request->all(), [
'start_time' => 'sometimes|date_format:Y-m-d H:i:s',
'end_time' => 'sometimes|date_format:Y-m-d H:i:s',
'sku_id' => 'sometimes|integer',
]);
if ($validator->fails()) {
//校验失败返回异常
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
return response($this->res, $this->res['httpCode']);
}
return $this->success(SaleDataService::lossRecordStatistics($request));
}
}

View File

@ -9,6 +9,7 @@ use App\Models\BusinessOrderItem;
use App\Models\CombinationGood;
use App\Models\Goods;
use App\Models\GoodsSku;
use App\Utils\GeneratorUtils;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
@ -96,7 +97,7 @@ class GoodsCombinationController extends Controller
{
$validator = Validator::make($request->all(), [
'title' => 'required',
'external_sku_id' => 'required',
'external_sku_id' => 'sometimes',
'combination_goods.*' => 'required',
'combination_goods.*.item_id' => 'required',
'combination_goods.*.item_num' => 'required|gt:0',
@ -118,9 +119,10 @@ class GoodsCombinationController extends Controller
$stock = [];
$saleStock = [];
foreach ($combinationGoods as $item) {
if(!empty($skus[$item['item_id']])){
$stock[] = (int)($skus[$item['item_id']]['stock'] / $item['item_num']);
$saleStock[] = (int)($skus[$item['item_id']]['sale_stock'] / $item['item_num']);
}
}
$stock = min($stock);
$saleStock = min($saleStock);
@ -133,10 +135,14 @@ class GoodsCombinationController extends Controller
$sku->goods_id = 0;
$sku->is_combination = 1;
}
$externalSkuId = $request->input('external_sku_id') ??
GeneratorUtils::generateCombinationGoodNumber($request->combination_goods);
$sku->status = $status;
$sku->title = $request->input('title');
$sku->sku_code = $request->input('external_sku_id');
$sku->external_sku_id = $request->input('external_sku_id');
$sku->name = $request->input('title');
$sku->sku_code = $externalSkuId;
$sku->external_sku_id = $externalSkuId;
$sku->stock = $stock;
$sku->sale_stock = $saleStock;
$sku->save();

View File

@ -51,6 +51,7 @@ class GoodsController extends Controller
$goodService = new GoodService();
$goods = $goodService->saveDefaultGoodsByGoodType($request->type_id);
$goodsSkus = [];
foreach ($request->skus as $item) {
$item['goods_id'] = $goods->id;
$item['stock'] = $item['num'] ?? 0;

View File

@ -114,8 +114,7 @@ class GoodsSkusController extends Controller
->whereIn('id', $finalIds)
->orderByRaw("FIELD(id, {$idField})")
->paginate($request->get('per_page'));
$user = $request->user()->toArray();
$adminRoleIds = DeveloperConfigService::getSkuAdminRoleIds();
$rolesName = $request->user()->getRoleNames()->toArray();
foreach ($goodsSkus as &$sku) {
$lastInventoryTime = !empty($sku['daily']['inventory_time']) ? $sku['daily']['inventory_time'] : date('Y-m-d 07:00:00');
if (isset($externals[$sku['external_sku_id']])) {
@ -127,14 +126,9 @@ class GoodsSkusController extends Controller
}
$sku['order_goods_num'] -= $sku['daily']['reissue_num'] ?? 0;
$sku['inventory_time'] = $lastInventoryTime;
if ('销售' === ($user['roles'][0]['name'] ?? "")) {
if ('销售' === $rolesName[0]) {
$sku['cost'] = 0;
}
if (in_array($user['roles'][0]['id'] ?? 0, $adminRoleIds)) {
$sku['is_admin'] = 1;
} else {
$sku['is_admin'] = 0;
}
if (!empty($sku['yesterday_num'])) {
$sku['sale_ratio'] = round($sku['stock'] / $sku['yesterday_num'], 2)*100;

View File

@ -101,4 +101,9 @@ class UsersController extends Controller
return response($this->res, $this->res['httpCode']);
}
public function userRoles(Request $request)
{
return $request->user()->toArray();
}
}

View File

@ -66,7 +66,7 @@ class CombinationGoodsImport implements ToArray, SkipsEmptyRows, WithStartRow
$status = $saleStock ? (5 < $saleStock ? 1 : 2) : 0;
$sku = GoodsSku::query()->updateOrCreate(
['external_sku_id' => $info['external_sku_id'], 'is_combination' => 1],
['title' => $info['title'], 'goods_id' => 0, 'sku_code' => $info['external_sku_id']
['title' => $info['title'],'name' => $info['title'], 'goods_id' => 0, 'sku_code' => $info['external_sku_id']
, 'stock' => $stock, "sale_stock" => $saleStock, 'status' => $status]
);
CombinationGood::query()

View File

@ -54,11 +54,7 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue
}
}
}
Log::info("组合时间监听:", [
"event" => (array)$event,
"combinationGoodsIds" => $combinationGoodsIds,
"combinationGoodsItemIds" => $combinationGoodsItemIds
]);
if ($combinationGoodsIds) {
$combinationGoods = CombinationGood::query()
->with('goodsSku:id,stock')
@ -77,7 +73,6 @@ class CombinationGoodsStockUpdateListener implements ShouldQueue
$updateIds[] = $goodsSku->id;
}
}
Log::info("updateIds:", $updateIds);
// 计算主商品库存
if ($combinationGoodsItemIds) {
$goodsSkuIds = CombinationGood::query()

View File

@ -11,8 +11,8 @@ class GoodsType extends Model
*/
protected $hidden = ['deleted_at'];
public function parent_type()
public function parentType()
{
return $this->belongsTo(GoodsType::class, 'id', 'parent_id');
return $this->hasOne(GoodsType::class, 'id', 'parent_id');
}
}

View File

@ -19,15 +19,17 @@ class GoodService
{
public function saveDefaultGoodsByGoodType($typeId)
{
$goodsType = GoodsType::query()->with("parent_type")->where('id', "=", $typeId)
$goodsType = GoodsType::query()->with("parentType")->where('id', "=", $typeId)
->first()->toArray();
$params['type_id'] = $typeId;
$parentName = "";
$params['goods_code'] = static::getChCode($goodsType['id']);
if (!empty($goodsType['parent_type']['id'])) {
$params['goods_code'] .= "|" . static::getChCode($goodsType['parent_type']['id']);
$params['goods_code'] .= "Z". static::getChCode($goodsType['parent_type']['id']);
$parentName = $goodsType['parent_type']['name'] ?? '';
}
$saveData = $params;
$saveData['title'] = $goodsType['name'] . " " . $goodsType['parent_type']['name'] ?? '';
$saveData['title'] = $goodsType['name'] . " " .$parentName;
return Goods::query()->firstOrCreate($params, $saveData);
}
@ -60,13 +62,18 @@ class GoodService
return $output;
}
/**
* 获取非z的字符串
* @param $intValue
* @return string
*/
public function getChCode($intValue)
{
$ch = range('A', 'Z');
$ch = range('A', 'Y');
$result = '';
while ($intValue) {
$result = $ch[$intValue % 26] . $result;
$intValue = intval($intValue / 26);
$result = $ch[$intValue % 25] . $result;
$intValue = intval($intValue / 25);
}
return $result;
}

View File

@ -34,8 +34,7 @@ class GoodSkuService
foreach ($sku['combination_goods'] as $combinationGoods) {
if (!isset($inventoryKeyBySkuIdMap[$combinationGoods["item_id"]])) {
//没有盘点到的sku需要在原先的sku库存
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = GoodsSku::query()
->where('id', $combinationGoods["item_id"])->pluck('stock')->first() ?? 0;
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] = 0;
}
$inventoryKeyBySkuIdMap[$combinationGoods["item_id"]] += $combinationGoods['item_num'] * $sku['real_stock'];
@ -61,7 +60,6 @@ class GoodSkuService
"inventory_time" => $dateTime,
"batch_number" => $batchNumber
]);
}
foreach ($inventoryKeyBySkuIdMap as $skuId => $realStock) {
@ -71,9 +69,11 @@ class GoodSkuService
]);
$updateIds[] = $skuId;
}
DB::commit();
} catch (\Exception $exception) {
DB::rollBack();
$this->info('盘点保存失败' . $exception->getMessage());
Log::error("库存盘点异常", ["error" => $exception->getMessage()]);
}
// 批量更新

View File

@ -1,6 +1,6 @@
<?php
namespace App\Services\Service;
namespace App\Services\Statistic;
use App\Events\BatchStockUpdateEvent;
use App\Http\Enum\CacheKeyEnum;
@ -9,6 +9,7 @@ use App\Models\BusinessOrderItem;
use App\Models\CombinationGood;
use App\Models\DailyStockRecord;
use App\Models\GoodsSku;
use App\Models\LossRecords;
use App\Utils\DateTimeUtils;
use Carbon\Carbon;
use Illuminate\Http\Request;
@ -33,8 +34,7 @@ class SaleDataService
public static function skuSaleStatisticsByToday(Request $request)
{
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
[$startTime,$endTime] = static::getTimeRange($request);
$orderItems = BusinessOrderItem::query()
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
->select("business_order_items.external_sku_id"
@ -43,7 +43,7 @@ class SaleDataService
, DB::raw("sum(goods_number-already_cancel_number) as goods_total")
, DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount"))
->whereBetween("business_order_items.created_at", [$startTime, $endTime])
->where("external_sku_id", "!=","")
->where("external_sku_id", "!=", "")
->where("business_order_items.cancel_status", "=", 0)
->groupBy('external_sku_id')
->orderBy("goods_total", "DESC")
@ -61,8 +61,7 @@ class SaleDataService
public static function skuSaleStatisticsByHistory(Request $request)
{
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
[$startTime,$endTime] = static::getTimeRange($request);
$dailyRecord = DailyStockRecord::query()
->select("sku_id", DB::raw("sum(order_goods_num) as goods_total")
, DB::raw("sum(order_total_amount) as goods_total_amount"))
@ -100,7 +99,7 @@ class SaleDataService
$startTime = Carbon::now()->subDays(8)->startOfDay()->toDateTimeString();
$endTime = Carbon::yesterday()->endOfDay()->toDateTimeString();
$dailyRecord = DailyStockRecord::query()->whereIn("sku_id", $skuIds)
->whereBetween("created_at", [$startTime, $endTime])
->whereBetween("day", [$startTime, $endTime])
->get()->toArray();
$dailyRecordGroupBySkuId = collect($dailyRecord)->groupBy("sku_id")->toArray();
Log::info("dailyRecordGroupBySkuId", $dailyRecordGroupBySkuId);
@ -146,10 +145,22 @@ class SaleDataService
}
}
public static function spuSaleStatisticsByToday(Request $request)
public static function getTimeRange(Request $request)
{
if(!empty($request->input("start_time"))&&!empty($request->input("start_time"))){
$startTime = Carbon::parse($request->input("start_time"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_time"))->toDateTimeString();
}else{
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
}
return [$startTime,$endTime];
}
public
static function spuSaleStatisticsByToday(Request $request)
{
[$startTime,$endTime] = static::getTimeRange($request);
//实时统计 sku维度
$orderItems = BusinessOrderItem::query()
->leftJoin("business_orders as b", "business_order_id", "=", "b.id")
@ -159,7 +170,7 @@ class SaleDataService
, DB::raw("sum(goods_number-already_cancel_number) as goods_total")
, DB::raw("ROUND(sum(goods_amount) / 100,2) as goods_total_amount"))
->whereBetween("business_order_items.created_at", [$startTime, $endTime])
->where("external_sku_id", "!=","")
->where("external_sku_id", "!=", "")
->where("business_order_items.cancel_status", "=", 0)
->groupBy('external_sku_id')->get()->toArray();
$externalSkuIds = collect($orderItems)->pluck("external_sku_id")->toArray();
@ -194,10 +205,10 @@ class SaleDataService
* @param Request $request
* @return mixed
*/
public static function spuSaleStatisticsByHistoryCache(Request $request)
public
static function spuSaleStatisticsByHistoryCache(Request $request)
{
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
[$startTime,$endTime] = static::getTimeRange($request);
$cacheKey = CacheKeyEnum::SPU_STATISTIC_BY_DATE . $request->input("start_day") . "_" . $request->input("end_day");
$expireTime = Carbon::now()->addHour();
return Cache::remember($cacheKey, $expireTime, function () use ($startTime, $endTime) {
@ -211,12 +222,13 @@ class SaleDataService
* @param $endTime
* @return array
*/
public static function spuSaleStatisticsByHistory($startTime, $endTime)
public
static function spuSaleStatisticsByHistory($startTime, $endTime)
{
$dailyAllRecord = DailyStockRecord::query()
->select("sku_id", DB::raw("sum(order_goods_num) as goods_total")
, DB::raw("sum(order_total_amount) as goods_total_amount"))
->whereBetween("created_at", [$startTime, $endTime])
->whereBetween("day", [$startTime, $endTime])
->groupBy("sku_id")
->having(DB::raw("sum(order_goods_num)"), ">", 0)
->get()->toArray();
@ -244,14 +256,24 @@ class SaleDataService
})->values()->toArray();
}
public static function gmvStatistics(Request $request)
public
static function gmvStatistics(Request $request)
{
if (StaticTypeEnum::TODAY == $request->type) {
$startTime = Carbon::parse($request->input("start_day"))->startOfDay()->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
$orderItems = BusinessOrderItem::query()
->select("business_order_items.external_sku_id", "goods_number", "already_cancel_number", "goods_amount", "created_at")
->whereBetween("business_order_items.created_at",[$startTime,$endTime])
[$startTime,$endTime] = static::getTimeRange($request);
$build = BusinessOrderItem::query();
if (!empty($request->sku_id)) {
$externalSkuId = GoodsSku::query()->where("id", "=", $request->sku_id)
->pluck("external_sku_id")->first();
if (!empty($externalSkuId)) {
$build->where("external_sku_id", "=", $externalSkuId);
} else {
return [];
}
}
$orderItems = $build->select("business_order_items.external_sku_id"
, "goods_number", "already_cancel_number", "goods_amount", "created_at")
->whereBetween("business_order_items.created_at", [$startTime, $endTime])
->where("business_order_items.cancel_status", "=", 0)
->get()->toArray();
$interval = $request->input("interval", 30);
@ -265,22 +287,46 @@ class SaleDataService
"time_start" => Carbon::parse($startTime)->addMinutes($key * $interval)->toTimeString(),
"time_end" => Carbon::parse($startTime)->addMinutes(($key + 1) * $interval)->toTimeString(),
"goods_total" => $v->sum("goods_number") - $v->sum("already_cancel_number"),
"goods_total_amount" => round($v->sum("goods_amount")/100,2),
"goods_total_amount" => round($v->sum("goods_amount") / 100, 2),
];
})->sort()->values()->toArray();
} else {
//gmv 目前只统计历史数据 后续看看是否需要拓展
$startTime = Carbon::parse($request->input("start_day"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_day"))->endOfDay()->toDateTimeString();
return DailyStockRecord::query()
->select("day", DB::raw("sum(order_total_amount) as goods_total_amount")
[$startTime,$endTime] = static::getTimeRange($request);
$build = DailyStockRecord::query();
if (!empty($request->sku_id)) {
$build->where("sku_id", "=", $request->sku_id);
}
return $build->select("day", DB::raw("sum(order_total_amount) as goods_total_amount")
, DB::raw("sum(order_goods_num) as goods_total"))
->whereBetween("created_at", [$startTime, $endTime])
->whereBetween("day", [$startTime, $endTime])
->groupBy("day")->orderBy("day")
->get()->toArray();
}
}
public
static function lossRecordStatistics(Request $request)
{
$startTime = Carbon::parse($request->input("start_time"))->toDateTimeString();
$endTime = Carbon::parse($request->input("end_time"))->toDateTimeString();
$build = LossRecords::query();
if (!empty($request->sku_id)) {
$externalSkuId = GoodsSku::query()->where("id", "=", $request->sku_id)
->pluck("external_sku_id")->first();
if (!empty($externalSkuId)) {
$build->where("external_sku_id", "=", $externalSkuId);
} else {
return [];
}
}
return $build->select("date", DB::raw("sum(num) as total_num")
, DB::raw("sum(num*cost) as total_loss_amount"))
->whereBetween("date", [$startTime, $endTime])
->groupBy("date")->orderBy("date")
->get()->toArray();
}
}

View File

@ -16,4 +16,29 @@ class GeneratorUtils
}
return $code.date("YmdHis") . rand(1000, 10000);
}
public static function generateCombinationGoodNumber($goods)
{
$code = "";
foreach ($goods as $v){
$code.=static::getChCode($v['item_id'])."Z".static::getChCode($v['item_num'])."Z";
}
rtrim($code,"Z");
return $code;
}
/**
* 获取非z的字符串
* @param $intValue
* @return string
*/
public static function getChCode($intValue)
{
$ch = range('A', 'Y');
$result = '';
while ($intValue) {
$result = $ch[$intValue % 25] . $result;
$intValue = intval($intValue / 25);
}
return $result;
}
}

View File

@ -304,6 +304,11 @@ return [
'name' => '删除',
'parent_id' => 6,
],
'users.user_roles' => [
'id' => 65,
'name' => '获取用户权限',
'parent_id' => 6,
],
// 系统管理
'SYSTEM_MANAGE' => [
'id' => 7,
@ -626,13 +631,13 @@ return [
],
'spu_sale_statistics' => [
'id' => 182,
'name' => 'spu销售统计',
'name' => '品种销售统计',
'parent_id' => 18,
'show' => 1,
],
'data_center.spu_sale_statistics' => [
'id' => 1820,
'name' => 'spu销售统计接口',
'name' => '品种销售统计接口',
'parent_id' => 18
],
'gmv_statistics' => [
@ -646,6 +651,17 @@ return [
'name' => 'gmv统计',
'parent_id' => 18,
],
'loss_record_statistics' => [
'id' => 184,
'name' => '报损统计',
'parent_id' => 18,
'show' => 1,
],
'data_center.loss_record_statistics' => [
'id' => 1840,
'name' => '报损统计接口',
'parent_id' => 184,
],
// 订单列表
'PLAT_AFTER_SALE_ORDER_LIST' => [
'id' => 141,

View File

@ -17,6 +17,7 @@ use App\Http\Controllers\Supplier\LossRecordController;
use App\Http\Controllers\Supplier\PurchaseRecordController;
use App\Http\Controllers\Business\BusinessAfterSaleOrderController;
use App\Http\Controllers\Goods\GoodsTypesController;
use App\Http\Controllers\User\UsersController;
/*
|--------------------------------------------------------------------------
| API Routes
@ -91,6 +92,7 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
Route::get('data_center/sale_statistics', [DataCenterController::class, 'saleStatistics'])->name('data_center.sale_statistics');
Route::get('data_center/spu_sale_statistics', [DataCenterController::class, 'spuSaleStatistics'])->name('data_center.spu_sale_statistics');
Route::get('data_center/gmv_statistics', [DataCenterController::class, 'gmvStatistics'])->name('data_center.gmv_statistics');
Route::get('data_center/loss_record_statistics', [DataCenterController::class, 'lossRecordStatistics'])->name('data_center.loss_record_statistics');
Route::get('plat_after_sale_orders', [BusinessAfterSaleOrderController::class, 'index'])->name('plat_after_sale_orders.index');
//获取树
@ -100,6 +102,8 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
Route::post('purchase_record/purchase_batch_store', [PurchaseRecordController::class, 'purchaseBatchStore'])->name('purchase_record.purchase_batch_store');
Route::post('daily_stock_record/inventory_batch_store', [DailyStockRecordController::class, 'inventoryBatchStore'])->name('daily_stock_record.inventory_batch_store');
Route::get('user/user_roles', [UsersController::class, 'userRoles'])->name('users.user_roles');
});
Route::get('stock/goods_skus', [GoodsSkusController::class, 'stockNum'])->middleware('auth:api');
Route::get('goods/filter/{title}', [GoodsCombinationController::class, 'goodsSkus'])->middleware('auth:api');