feat: #10000 暂存

This commit is contained in:
赵世界 2023-04-03 20:25:57 +08:00
parent f1bec543d6
commit 9734d058e3
13 changed files with 526 additions and 2 deletions

View File

@ -9,7 +9,6 @@ class BusinessOrderFilter extends Filters
return $this->builder->where('participate_no', '=', trim($value));
}
protected function shopId($value)
{
return $this->builder->where('shop_id', '=', trim($value));

View File

@ -0,0 +1,47 @@
<?php
namespace App\Filters;
use App\Models\Goods;
use App\Models\GoodsSku;
class GoodsSkuLocationFilter extends Filters
{
public function date($value)
{
return $this->builder->where('date', '=', $value);
}
public function goodsTitle($value)
{
$goodsId = Goods::query()->where('title', $value)->value('id');
return $this->builder->where('goods_id', '=', $goodsId);
}
public function goodsCode($value)
{
$goodsId = Goods::query()->where('goods_code', $value)->value('id');
return $this->builder->where('goods_id', '=', $goodsId);
}
public function externalSkuId($value)
{
[$goodsCode, $skuCode] = explode('_', $value);
$goodsId = Goods::query()->where('goods_code', $goodsCode)->value('id');
$skuId = GoodsSku::query()->where('sku_code', $skuCode)->value('id');
return $this->builder->where('goods_sku_id', '=', $skuId)->where('goods_id', '=', $goodsId);
}
public function location($value)
{
return $this->builder->where('location', '=', $value);
}
public function status($value)
{
return $this->builder->where('status', '=', $value);
}
}

View File

@ -4,6 +4,8 @@ namespace App\Http\Controllers\Business;
use App\Http\Controllers\Controller;
use App\Models\BusinessOrder;
use App\Utils\DateTimeUtils;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Resources\BusinessOrderResource;
@ -21,6 +23,54 @@ class BusinessOrderController extends Controller
public function exportOrderBlank(Request $request)
{
$shopId = $request->get('shop_id');
$startNo = $request->get('start_no');
$endNo = $request->get('end_no');
$startTime = BusinessOrder::query()->where('participate_no', $startNo)->value('confirm_at');
$endTime = BusinessOrder::query()->where('participate_no', $endNo)->value('confirm_at');
$orders = BusinessOrder::query()
->with([
'items:id,business_order_id,external_sku_id,goods_number,goods_name',
'items.goodsSkuLocation:id,external_sku_id,location'
])
->where('shop_id', $shopId)
->where('confirm_at', '>=', $startTime)
->where('confirm_at', '<=', $endTime)
->where('after_sales_status', 0)
->where('cancel_status', 0)
->where('is_supplier', 1)
->orderByDesc('confirm_at')
->get(['id', 'participate_no']);
$distribution = [];
$no = [];
foreach ($orders as $key => $order) {
$no[] = $order->participate_no;
foreach ($order->items as $item) {
if (isset($distribution[$item['external_sku_id']])) {
$distribution[$item['external_sku_id']]['p'][] = $key;
$distribution[$item['external_sku_id']]['num'] += $item['goods_number'];
} else {
$distribution[$item['external_sku_id']] = [
'p' => [$key],
'local' => 0,
'num' => $item['goods_number']
];
}
}
}
var_dump($distribution, $no);
}
public function groupActivity(Request $request, $shopId)
{
$todayTime = Carbon::today()->timestamp;
$todayTime = DateTimeUtils::getMicroTime($todayTime);
return BusinessOrder::query()
->where('shop_id', $shopId)
->where('confirm_at', '>=', $todayTime)
->groupBy('activity_no')
->pluck('activity_title', 'activity_no')
->toArray();
}
}

View File

@ -13,7 +13,6 @@ use Illuminate\Support\Facades\Validator;
use App\Models\Goods;
use App\Http\Requests\GoodsRequest;
use App\Models\DailyStockRecord;
use Illuminate\Support\Facades\Storage;
class GoodsController extends Controller
{

View File

@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers\Goods;
use App\Http\Controllers\Controller;
use App\Http\Resources\GoodsSkuLocationResource;
use App\Imports\GoodsSkuLocationImport;
use App\Models\GoodsSkuLocation;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Maatwebsite\Excel\Facades\Excel;
class GoodsSkuLocationController extends Controller
{
public function index(Request $request)
{
$goodsSkuLocation = GoodsSkuLocation::query()
->with([
'goods:id,title,goods_code,brand_id,type_id',
'goods.brand:id,name',
'goods.type:id,name',
'goodsSku:id,title,sku_code,stock',
])
->filter()
->paginate($request->get('per_page'));
return GoodsSkuLocationResource::collection($goodsSkuLocation);
}
public function update(Request $request, $id)
{
$goodsSkuLocation = GoodsSkuLocation::query()->findOrFail($id);
if ($location = $request->get('location')) {
$goodsSkuLocation->location = $location;
}
if ($todayInitNum = $request->get('today_init_num')) {
$goodsSkuLocation->today_init_num = $todayInitNum;
}
if ($status = $request->get('status')) {
$goodsSkuLocation->status = $status;
}
if ($note = $request->get('note')) {
$goodsSkuLocation->note = $note;
}
$goodsSkuLocation->save();
return response()->json($this->res);
}
public function delete(Request $request, $id)
{
GoodsSkuLocation::query()->delete($id);
return response()->json($this->res);
}
public function importLocation(Request $request)
{
if (!$request->hasFile('goodsSkuLocation')) {
$this->res = [
'httpCode' => 404,
'errorCode' => 404404,
'errorMessage' => 'not found file',
];
}
try {
$import = new GoodsSkuLocationImport();
$path = $request->file('goodsSkuLocation');
Excel::import($import, $path);
$this->addLog(0, 'import');
} catch (ValidationException $exception) {
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
}
return response($this->res, $this->res['httpCode']);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class GoodsSkuLocationResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Imports;
use App\Models\Goods;
use App\Models\GoodsSkuLocation;
use Maatwebsite\Excel\Concerns\SkipsEmptyRows;
use Maatwebsite\Excel\Concerns\ToArray;
use Maatwebsite\Excel\Concerns\WithStartRow;
class GoodsSkuLocationImport implements ToArray, SkipsEmptyRows, WithStartRow
{
public function startRow(): int
{
return 2;
}
public function array(array $array)
{
$goodsCode = $deleteLocation = [];
foreach ($array as &$row) {
$row = array_map(function ($value) {
return trim($value);
}, $row);
$goodsCode[] = $row[2];
$deleteLocation[] = $row[5];
}
GoodsSkuLocation::query()->whereIn('location', $deleteLocation)->delete();
unset($row);
$goods = Goods::query()
->with(['skus:id,goods_id,sku_code'])
->whereIn('goods_code', $goodsCode)
->get(['id', 'goods_code']);
$goodsSkus = [];
foreach ($goods as $goodsItem) {
$goodsSkus[$goodsItem['goods_code']][$goodsItem->skus->sku_code] = [
'goods_id' => $goodsItem->id,
'goods_sku_id' => $goodsItem->skus->id,
'external_sku_id' => $goodsItem['goods_code'] . '_' . $goodsItem->skus->sku_code,
];
}
$data = [];
foreach ($array as $row) {
if (isset($goodsSkus[$row[2]][$row[4]])) {
$data[] = array_merge($goodsSkus[$row[2]][$row[4]], [
'date' => date('Y-m-d'),
'today_init_num' => $row[1],
'location' => $row[5],
]);
}
}
$model = new GoodsSkuLocation();
$model->batchInsert($data);
}
}

View File

@ -39,4 +39,9 @@ class BusinessOrderItem extends Model
{
return $this->belongsTo(Shop::class, 'shop_id', 'id');
}
public function goodsSkuLocation()
{
return $this->hasOne(GoodsSkuLocation::class, 'external_sku_id', 'external_sku_id');
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Models;
use App\Models\traits\Filter;
class GoodsSkuLocation extends Model
{
use Filter;
public $fieldSearchable = [
'date',
'goods_title',
'goods_code',
'external_sku_id',
'location',
'status',
];
public function goods()
{
return $this->belongsTo(Goods::class, 'goods_id', 'id');
}
public function goodsSku()
{
return $this->belongsTo(GoodsSku::class, 'goods_sku_id', 'id');
}
public function getStatusAttribute($value)
{
$map = ['未使用', '正常', '过期'];
return $map[$value];
}
}

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoodsSkuLocationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::defaultStringLength(191);
Schema::create('goods_sku_locations', function (Blueprint $table) {
$table->bigIncrements('id');
$table->date('date');
$table->unsignedBigInteger('goods_id');
$table->unsignedBigInteger('goods_sku_id');
$table->string('location');
$table->integer('today_init_num');
$table->string('external_sku_id');
$table->tinyInteger('status')->default(1);
$table->string('note')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goods_sku_locations');
}
}

View File

@ -30,3 +30,19 @@ export function syncStock(id) {
method: "post",
});
}
export function activityList(shopId) {
return http({
url: "/api/plat_group_activity/" + shopId,
method: "get",
});
}
// 平台订单列表
export function platOrderList(params) {
return http({
url: "/api/plat_orders",
method: "get",
params
});
}

View File

@ -0,0 +1,181 @@
<template>
<div class="conent">
<el-card :body-style="{ padding: '20px 20px 0 20px' }">
<el-form ref="form" :inline="true" :model="form">
<el-form-item label="店铺:">
<el-select v-model="form.shop_id" placeholder="店铺">
<el-option v-for="item in shops" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="活动名称:">
<el-select v-model="form.activity_no" placeholder="活动名称">
<el-option v-for="item in groupActivity" :key="item.activity_no" :label="item.activity_title" :value="item.activity_no">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="发货状态:">
<el-select v-model="form.shipping_status" placeholder="发货状态">
<el-option value="" label="全部"></el-option>
<el-option value="0" label="未发货"></el-option>
<el-option value="2" label="部分发货"></el-option>
<el-option value="1" label="已发货"></el-option>
</el-select>
</el-form-item>
<el-form-item label="选择时间:">
<el-input v-model="form.confirm_at" placeholder="选择时间">
</el-input>
</el-form-item>
<el-form-item label="订单类型:">
<el-select v-model="form.is_help" 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.cancel_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.after_sales_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>
<el-button type="primary" @click="handleChoose()">筛选</el-button>
<el-button plain @click="handleReChoose()">重置筛选</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card style="margin-top: 10px">
<el-table v-loading="loading" ref="multipleTable" :data="tableData" style="width: 100%">
<el-table-column label="店铺名称">
<template slot-scope="scope">
{{ scope.row.shop.name }}
</template>
</el-table-column>
<el-table-column prop="activity_title" label="活动名称"></el-table-column>
<el-table-column prop="participate_no" label="跟团号"></el-table-column>
<el-table-column prop="items_info" label="商品信息"></el-table-column>
<el-table-column prop="confirm_at" label="下单时间"></el-table-column>
</el-table>
<!-- 分页功能 -->
<div class="block">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="current_page" :page-sizes="[15, 50, 100]" :page-size="per_page"
layout="total, sizes, prev, pager, next, jumper" :total="Paginationdata.total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { platOrderList, activityList } from "../../api/plat";
import { storeList } from "../../api/shop";
export default {
data() {
return {
form: {
shop_id: "",
activity_no: "",
shipping_status: "",
confirm_at: "",
is_help: "",
cancel_status: "",
after_sales_status: "",
},
loading: true,
tableData: [],
Paginationdata: {}, //
current_page: 1, //
per_page: 10, //
shops: [],
groupActivity: [],
};
},
mounted() {
//
this.getPlatOrderList();
this.getShopsList();
},
methods: {
//
getPlatOrderList(params = {}) {
params.page = this.current_page;
params.per_page = this.per_page;
platOrderList(params).then((res) => {
this.tableData = res.data.data;
this.Paginationdata = res.data.meta;
});
},
getShopsList() {
let page = {
page: 0,
per_page: 99,
};
storeList(page).then((res) => {
this.shops = res.data.data;
});
this.loading = false;
},
//
handleSizeChange(val) {
//
this.current_page = 1;
this.per_page = val;
this.getPlatOrderList();
},
handleCurrentChange(val) {
//
this.current_page = val;
this.getPlatOrderList();
},
//
handleChoose() {
this.form = {
...this.form,
page: 1,
per_page: this.per_page,
};
this.getPlatOrderList(this.form);
},
//
handleReChoose() {
this.form = {
shop_id: "",
activity_no: "",
shipping_status: "",
confirm_at: "",
is_help: "",
cancel_status: "",
after_sales_status: "",
};
this.getPlatOrderList();
},
},
};
</script>
<style lang="scss" scoped>
.block {
margin-top: 20px;
}
</style>

View File

@ -48,6 +48,7 @@ Route::middleware(['auth:api', 'check.permissions'])->group(function () {
// 平台
Route::resource('plat_goods', 'Business\BusinessGoodsSkusController', ['only' => ['index', 'update', 'destroy']]);
Route::get('plat_orders', [BusinessOrderController::class, 'index']);
Route::get('plat_group_activity/{shopId}', [BusinessOrderController::class, 'groupActivity']);
Route::post('plat/sync/{id}/stock', [BusinessGoodsSkusController::class, 'syncStock'])->name('plat.sync.stock');
// 团购
Route::resource('group', 'Group\GroupsController', ['only' => ['index', 'store', 'show', 'update', 'destroy']]);