feat: #10000 订单筛选

This commit is contained in:
赵世界 2023-07-26 13:58:52 +08:00
parent 15395085cf
commit 660fd24ed0
14 changed files with 297 additions and 42 deletions

View File

@ -14,6 +14,7 @@ use App\Models\TodayPrice;
use App\Services\Business\BusinessFactory; use App\Services\Business\BusinessFactory;
use App\Services\Business\KuaiTuanTuan\FaceSheet; use App\Services\Business\KuaiTuanTuan\FaceSheet;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Carbon\Carbon;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use App\Jobs\BusinessGoodsSkuIncrQuantity; use App\Jobs\BusinessGoodsSkuIncrQuantity;

View File

@ -2,6 +2,9 @@
namespace App\Filters; namespace App\Filters;
use App\Models\BusinessOrderItem;
use Carbon\Carbon;
class BusinessOrderFilter extends Filters class BusinessOrderFilter extends Filters
{ {
protected function participateNo($value) protected function participateNo($value)
@ -43,4 +46,39 @@ class BusinessOrderFilter extends Filters
{ {
return $this->builder->where('after_sales_status', $value); return $this->builder->where('after_sales_status', $value);
} }
protected function confirmAtStart($value)
{
$start = Carbon::parse($value)->timestamp;
$start *= 1000;
return $this->builder->where('confirm_at', '>=', $start);
}
protected function confirmAtEnd($value)
{
$end = Carbon::parse($value)->timestamp;
$end *= 1000;
return $this->builder->where('confirm_at', '<=', $end);
}
protected function goodsSkuNum($value)
{
if (1 === $value) {
return $this->builder->where('goods_sku_num', '=', 1);
}
if (2 === $value) {
return $this->builder->where('goods_sku_num', '<=', 5)
->where('goods_sku_num', '>=', 2);
}
if (6 === $value) {
return $this->builder->where('goods_sku_num', '>=', 6);
}
}
protected function printStatus($value)
{
return $this->builder->where('print_status', $value);
}
} }

View File

@ -23,4 +23,9 @@ class GoodsSkuFilter extends Filters
{ {
return $this->builder->where('external_sku_id', $value); return $this->builder->where('external_sku_id', $value);
} }
protected function isCombination($value)
{
return $this->builder->where('is_combination', $value);
}
} }

View File

@ -5,30 +5,89 @@ namespace App\Http\Controllers\Business;
use App\Exports\OrderBlankExport; use App\Exports\OrderBlankExport;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\BusinessOrder; use App\Models\BusinessOrder;
use App\Models\BusinessOrderItem;
use App\Models\GoodsSku;
use App\Models\Shop; use App\Models\Shop;
use App\Utils\DateTimeUtils; use App\Utils\DateTimeUtils;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Http\Resources\BusinessOrderResource; use App\Http\Resources\BusinessOrderResource;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel; use Maatwebsite\Excel\Facades\Excel;
class BusinessOrderController extends Controller class BusinessOrderController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$businessOrders = BusinessOrder::query() $builder = BusinessOrder::query()
->where('shop_id', '<>', 8)
->with([ ->with([
'shop:id,name', 'shop:id,name',
'items:id,business_order_id,goods_name,goods_number,external_sku_id' 'items:id,business_order_id,goods_name,goods_number,external_sku_id'
]) ])
->orderByDesc('confirm_at') ->filter();
->filter() $externalSkuIds = $request->get('external_sku_ids');
if ($externalSkuIds) {
$ids = BusinessOrderItem::query()->whereIn('external_sku_id', $externalSkuIds)->pluck('business_order_id');
$builder->whereIn('id', $ids);
}
$businessOrders = $builder->orderByDesc('confirm_at')
->paginate($request->get('per_page')); ->paginate($request->get('per_page'));
return BusinessOrderResource::collection($businessOrders); return BusinessOrderResource::collection($businessOrders);
} }
private function getOrderIdsWitmGoodsNum($goodsSkuNum, $orders)
{
$map = [
1 => [
'min' => 1,
'max' => 1
],
2 => [
'min' => 2,
'max' => 5
],
6 => [
'min' => 6,
'max' => 999999
],
];
$numMap = $map[$goodsSkuNum];
// 获取订单商品编码
$externalSkuIds = [];
foreach ($orders as $order) {
foreach ($order->items as $item) {
if ($item['external_sku_id']) {
$externalSkuIds [] = $item['external_sku_id'];
}
}
}
$goodsSkus = GoodsSku::query()
->with('combinationGoods')
->whereIn('external_sku_id', $externalSkuIds)
->get('external_sku_id');
$goodsSkuItems = [];
foreach ($goodsSkus as $goodsSku) {
$goodsSkuItems[$goodsSku['external_sku_id']] = $goodsSku->combinationGoods->count() ?: 1;
}
$ids = [];
foreach ($orders as $order) {
$itemNum = 0;
foreach ($order->items as $item) {
if (0 === $item['cancel_status']) {
$itemNum = isset($goodsSkuItems[$item['external_sku_id']]) ? $itemNum + $goodsSkuItems[$item['external_sku_id']] : $itemNum + 1;
}
}
if ($itemNum >= $numMap['min'] && $itemNum <= $numMap['max']) {
$ids[] = $order['id'];
}
}
return $ids;
}
public function exportOrderBlank(Request $request) public function exportOrderBlank(Request $request)
{ {
$shopId = $request->get('shop_id'); $shopId = $request->get('shop_id');

View File

@ -52,7 +52,7 @@ class GoodsSkusController extends Controller
}]) }])
->where('is_combination', 0) ->where('is_combination', 0)
->orderBy('stock', 'desc') ->orderBy('stock', 'desc')
->paginate($request->get('per_page')); ->paginate(1);
$fields = implode(',', [ $fields = implode(',', [
'shop_id', 'shop_id',
'external_sku_id', 'external_sku_id',
@ -561,4 +561,24 @@ class GoodsSkusController extends Controller
'other_num' => $otherNum, 'other_num' => $otherNum,
]); ]);
} }
public function goodsSkusList(Request $request)
{
$title = $request->input('title');
$data = [];
$goodsSkus = GoodsSku::query()
->with('goods:id,title')
->whereHas('goods', function ($query) use ($title) {
$query->where('title', 'like', '%' . $title . '%');
})
->get(['title', 'external_sku_id', 'goods_id']);
foreach ($goodsSkus as $goodsSku) {
$data[] = [
'external_sku_id' => $goodsSku['external_sku_id'],
'title' => $goodsSku['goods']['title'] . ' ' . $goodsSku['title']
];
}
return $data;
}
} }

View File

@ -17,6 +17,10 @@ class BusinessOrder extends Model
'cancel_status', 'cancel_status',
'after_sales_status', 'after_sales_status',
'supply_participate_no', 'supply_participate_no',
'confirm_at_start',
'confirm_at_end',
'goods_sku_num',
'print_status',
]; ];
protected $fillable = [ protected $fillable = [
@ -63,21 +67,21 @@ class BusinessOrder extends Model
public function getShippingStatusAttribute($value) public function getShippingStatusAttribute($value)
{ {
$map = ['未发货', '已发货', '部分发货']; $map = ['未发货', '已发货', '部分发货', '' => ''];
return $map[$value]; return $map[$value];
} }
public function getIsSupplierAttribute($value) public function getIsSupplierAttribute($value)
{ {
$map = ['帮忙团订单', '自卖团订单']; $map = ['帮忙团订单', '自卖团订单', '' => ''];
return $map[$value]; return $map[$value];
} }
public function getCancelStatusAttribute($value) public function getCancelStatusAttribute($value)
{ {
$map = ['未取消', '已取消']; $map = ['未取消', '已取消', '' => ''];
return $map[$value]; return $map[$value];
} }

View File

@ -13,7 +13,8 @@ class GoodsSku extends Model
'sku_title', 'sku_title',
'status', 'status',
'exclude_ids', 'exclude_ids',
'external_sku_id' 'external_sku_id',
'is_combination',
]; ];
protected $fillable = [ protected $fillable = [

View File

@ -45,9 +45,20 @@ abstract class BusinessClient
} else { } else {
$orderRecord->update($order); $orderRecord->update($order);
} }
$goodsSkuNum = 0;
foreach ($order['sub_order_list'] as $item) { foreach ($order['sub_order_list'] as $item) {
$item['shop_id'] = $shopId; $item['shop_id'] = $shopId;
$orderItem = BusinessOrderItem::firstOrNew(['shop_id' => $shopId, 'business_order_id' => $orderRecord->id, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']], $item); $orderItem = BusinessOrderItem::firstOrNew(['shop_id' => $shopId, 'business_order_id' => $orderRecord->id, 'goods_id' => $item['goods_id'], 'sku_id' => $item['sku_id']], $item);
if ($item['external_sku_id']) {
$goodsSku = GoodsSku::query()
->with('combinationGoods')
->where('external_sku_id', $item['external_sku_id'])
->first('external_sku_id');
$combinationNum = $goodsSku ? ($goodsSku->combinationGoods->count() ?: 1) : 1;
$goodsSkuNum += $combinationNum;
} else {
$goodsSkuNum++;
}
$num = 0; $num = 0;
$cancelNum = $item['already_cancel_number'] ?? 0; $cancelNum = $item['already_cancel_number'] ?? 0;
if (empty($orderItem->id)) { if (empty($orderItem->id)) {
@ -78,6 +89,8 @@ abstract class BusinessClient
event(new BusinessOrdersUpdate($orderItem, $num)); event(new BusinessOrdersUpdate($orderItem, $num));
} }
} }
$orderRecord->goods_sku_num = $goodsSkuNum;
$orderRecord->save();
} }
} }

View File

@ -45,7 +45,6 @@ class KuaiTuanTuan extends BusinessClient
['shop_id' => $this->shop->id], ['shop_id' => $this->shop->id],
$accessToken $accessToken
); );
$this->shop->update($accessToken);
} }
return $this->shop; return $this->shop;

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddGoodsSkuNumToBusinessOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumns('business_orders', ['goods_sku_num', 'print_status'])) {
return;
}
Schema::table('business_orders', function (Blueprint $table) {
$table->integer('goods_sku_num')->default(0)->comment('订单内不同商品种类数量');
$table->tinyInteger('print_status')->default(0)->comment('订单内不同商品种类数量');
$table->index('goods_sku_num');
$table->index('print_status');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('business_orders', function (Blueprint $table) {
$table->dropColumn(['goods_sku_num', 'print_status']);
$table->dropIndex('goods_sku_num');
$table->dropIndex('print_status');
});
}
}

View File

@ -104,6 +104,14 @@ export function goodsSkuLocation(params) {
}); });
} }
export function goodsSkusList(title) {
return http({
url: "/api/goodsSkusList",
method: "get",
params: { title: title }
});
}
export function importGoodsSkuLocation(params) { export function importGoodsSkuLocation(params) {
return http({ return http({
url: "/api/goods_sku_location", url: "/api/goods_sku_location",

View File

@ -8,8 +8,8 @@
<el-table-column prop="ship.owner_name" label="商家账号名称"></el-table-column> <el-table-column prop="ship.owner_name" label="商家账号名称"></el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="danger" v-if="scope.row.status === '未授权'" size="small"><a :href="scope.row.authUrl" <el-button type="danger" v-if="scope.row.status === '未授权'" size="small">
target="_blank" rel="noopener noreferrer">授权</a> <a :href="scope.row.authUrl" target="_blank" rel="noopener noreferrer">授权</a>
</el-button> </el-button>
<div v-if="scope.row.status === '已授权'"> <div v-if="scope.row.status === '已授权'">

View File

@ -1,21 +1,21 @@
<template> <template>
<div class="conent"> <div class="conent">
<el-card :body-style="{ padding: '20px 20px 0 20px' }"> <el-card>
<el-form ref="form" :inline="true" :model="form"> <el-form ref="form" :inline="true" :model="form">
<el-form-item label="店铺:"> <el-form-item label="所属店铺:">
<el-select v-model="form.shop_id" placeholder="店铺" @change="setActivity"> <el-select v-model="form.shop_id" placeholder="店铺" @change="setActivity">
<el-option v-for="item in shops" :key="item.id" :label="item.name" :value="item.id"> <el-option v-for="item in shops" :key="item.id" :label="item.name" :value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="活动名称:"> <!-- <el-form-item label="活动名称:">
<el-select v-model="form.activity_no" placeholder="活动名称"> <el-select v-model="form.activity_no" placeholder="活动名称">
<el-option v-for="item in groupActivity" :key="item.activity_no" :label="item.activity_title" <el-option v-for="item in groupActivity" :key="item.activity_no" :label="item.activity_title"
:value="item.activity_no"> :value="item.activity_no">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<el-form-item label="发货状态:"> <el-form-item label="发货状态:">
<el-select v-model="form.shipping_status" placeholder="发货状态"> <el-select v-model="form.shipping_status" placeholder="发货状态">
@ -50,11 +50,43 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="帮卖团跟团号:"> <!-- <el-form-item label="帮卖团跟团号:">
<el-input v-model="form.participate_no" placeholder="帮卖团跟团号"></el-input> <el-input v-model="form.participate_no" placeholder="帮卖团跟团号"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="自卖团跟团号:"> <el-form-item label="自卖团跟团号:">
<el-input v-model="form.supply_participate_no" placeholder="自卖团跟团号"></el-input> <el-input v-model="form.supply_participate_no" placeholder="自卖团跟团号"></el-input>
</el-form-item> -->
<el-form-item label="商品数量:">
<el-select v-model="form.goods_sku_num" placeholder="商品数量">
<el-option value="" label="全部"></el-option>
<el-option value="1" label="1个商品"></el-option>
<el-option value="2" label="2-5个商品"></el-option>
<el-option value="6" label="6个以上商品"></el-option>
</el-select>
</el-form-item>
<el-form-item label="打印状态:">
<el-select v-model="form.print_status" placeholder="打印状态">
<el-option value="" label="全部"></el-option>
<el-option value="0" label="未打印"></el-option>
<el-option value="1" label="已打印"></el-option>
</el-select>
</el-form-item>
<el-form-item label="订单商品:">
<el-select v-model="form.external_sku_ids" multiple filterable remote reserve-keyword placeholder="订单商品"
:remote-method="remoteMethod" :loading="searchLoading">
<el-option v-for="item in options" :key="item.external_sku_id" :label="item.title"
:value="item.external_sku_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="下单时间:">
<el-date-picker v-model="form.confirm_at" type="datetimerange" range-separator="-" start-placeholder=""
end-placeholder="止" value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -72,22 +104,31 @@
{{ scope.row.shop.name }} {{ scope.row.shop.name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="activity_title" label="活动名称"></el-table-column> <!-- <el-table-column prop="activity_title" label="活动名称"></el-table-column> -->
<el-table-column prop="order_sn" label="订单号" width="230"></el-table-column>
<el-table-column label="收件人信息" width="160">
<template slot-scope="scope">
<p>{{ scope.row.receiver_name }}</p>
<p>{{ scope.row.receiver_address_province }} {{ scope.row.receiver_address_city }} {{
scope.row.receiver_address_district }}</p>
<p>{{ scope.row.receiver_address_detail }}</p>
</template>
</el-table-column>
<el-table-column prop="shipping_status" label="发货状态"></el-table-column> <el-table-column prop="shipping_status" label="发货状态"></el-table-column>
<el-table-column prop="is_supplier" label="订单类型"></el-table-column> <!-- <el-table-column prop="is_supplier" label="订单类型"></el-table-column> -->
<el-table-column prop="cancel_status" label="订单状态"></el-table-column> <el-table-column prop="cancel_status" label="订单状态"></el-table-column>
<el-table-column prop="after_sales_status" label="售后状态"></el-table-column> <el-table-column prop="after_sales_status" label="售后状态"></el-table-column>
<el-table-column prop="supply_participate_no" label="自卖团跟团号"></el-table-column> <!-- <el-table-column prop="supply_participate_no" label="自卖团跟团号"></el-table-column> -->
<el-table-column prop="participate_no" label="帮卖团跟团号"></el-table-column> <!-- <el-table-column prop="participate_no" label="帮卖团跟团号"></el-table-column> -->
<el-table-column label="商品信息"> <el-table-column label="商品信息" width="420">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-for="item in scope.row.items" :key="item.id"> <div v-for="item in scope.row.items" :key="item.id">
<!-- {{ item.goods_name }}*{{ item.goods_number }} --> {{ item.goods_name }}
{{ item.external_sku_id }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="confirm_at" label="下单时间"></el-table-column> <el-table-column prop="confirm_at" label="下单时间" width="100"></el-table-column>
<el-table-column prop="print_status" label="打印状态"></el-table-column>
</el-table> </el-table>
<!-- 分页功能 --> <!-- 分页功能 -->
@ -130,23 +171,30 @@
</template> </template>
<script> <script>
import { platOrderList, activityList, platOrderExport } from "../../api/plat"; import { platOrderList, activityList } from "../../api/plat";
import { storeList } from "../../api/shop"; import { storeList } from "../../api/shop";
import { goodsSkusList } from "../../api/goods";
export default { export default {
data() { data() {
return { return {
form: { form: {
shop_id: "", shop_id: "",
activity_no: "", // activity_no: "",
shipping_status: "", shipping_status: "",
is_supplier: "", // is_supplier: "",
cancel_status: "", cancel_status: "",
after_sales_status: "", after_sales_status: "",
supply_participate_no: "", // supply_participate_no: "",
participate_no: "", // participate_no: "",
goods_sku_num: "",
print_status: "",
external_sku_ids: [],
confirm_at: "",
}, },
dialogVisible: false, dialogVisible: false,
loading: true, loading: true,
searchLoading: false,
options: [],
tableData: [], tableData: [],
Paginationdata: {}, // Paginationdata: {}, //
current_page: 1, // current_page: 1, //
@ -212,35 +260,38 @@ export default {
}, },
// //
handleChoose() { handleChoose() {
this.form = { this.form.confirm_at_start = this.form.confirm_at[0] ? this.form.confirm_at[0] : '',
...this.form, this.form.confirm_at_end = this.form.confirm_at[1] ? this.form.confirm_at[1] : '',
page: 1, this.form = {
per_page: this.per_page, ...this.form,
}; page: 1,
per_page: this.per_page,
};
this.getPlatOrderList(this.form); this.getPlatOrderList(this.form);
}, },
// //
handleReChoose() { handleReChoose() {
this.form = { this.form = {
shop_id: "", shop_id: "",
activity_no: "", // activity_no: "",
shipping_status: "", shipping_status: "",
is_supplier: "", // is_supplier: "",
cancel_status: "", cancel_status: "",
after_sales_status: "", after_sales_status: "",
supply_participate_no: "", // supply_participate_no: "",
participate_no: "", // participate_no: "",
goods_sku_num: "",
print_status: "",
external_sku_ids: [],
confirm_at: "",
}; };
this.getPlatOrderList(); this.getPlatOrderList();
}, },
setActivity(shopId) { setActivity(shopId) {
activityList(shopId).then((res) => { activityList(shopId).then((res) => {
this.groupActivity = res.data; this.groupActivity = res.data;
}) })
}, },
derivation(formName) { derivation(formName) {
this.$refs[formName].validate((valid) => { this.$refs[formName].validate((valid) => {
if (valid) { if (valid) {
@ -249,6 +300,21 @@ export default {
return false; return false;
} }
}); });
},
remoteMethod(query) {
if (query !== '') {
this.searchLoading = true;
setTimeout(() => {
this.searchLoading = false;
goodsSkusList(query).then((res) => {
this.options = res.data.filter(item => {
return item.title.toLowerCase().indexOf(query.toLowerCase()) > -1;
});
});
}, 200);
} else {
this.options = [];
}
} }
}, },
}; };

View File

@ -37,6 +37,7 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
Route::resource('goods_skus', 'Goods\GoodsSkusController', ['only' => ['index', 'show', 'update', 'store']]); Route::resource('goods_skus', 'Goods\GoodsSkusController', ['only' => ['index', 'show', 'update', 'store']]);
Route::patch('batch/goods_skus', [GoodsSkusController::class, 'batchUpdate'])->name('goods_sku.batch_update'); Route::patch('batch/goods_skus', [GoodsSkusController::class, 'batchUpdate'])->name('goods_sku.batch_update');
Route::patch('single/goods_skus/{id}', [GoodsSkusController::class, 'updateField'])->name('goods_sku.single_update'); Route::patch('single/goods_skus/{id}', [GoodsSkusController::class, 'updateField'])->name('goods_sku.single_update');
Route::get('goodsSkusList', [GoodsSkusController::class, 'goodsSkusList'])->name('goods_sku.list_for_goods_sku');
// 店铺 // 店铺
Route::resource('shops', 'Shop\ShopsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]); Route::resource('shops', 'Shop\ShopsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);
Route::get('count/orders/num', [ShopsController::class, 'countOrdersNumWithSkuCode'])->name('goods_sku.orders_num'); Route::get('count/orders/num', [ShopsController::class, 'countOrdersNumWithSkuCode'])->name('goods_sku.orders_num');