139 lines
4.9 KiB
PHP
139 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Endpoint\Api\Http\Controllers;
|
|
|
|
use App\Endpoint\Api\Http\Controllers\Controller;
|
|
use App\Endpoint\Api\Http\Resources\OfflineOrderPreviewResource;
|
|
use App\Exceptions\BizException;
|
|
use App\Models\OfflineOrderPreview;
|
|
use App\Models\Store\Store;
|
|
use App\Models\UserCoupon;
|
|
use EasyWeChat\Factory;
|
|
use EasyWeChat\Kernel\Http\StreamResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class OfflineOrderPreviewController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
$query = OfflineOrderPreview::query()->with(['store', 'coupon', 'order'])->where('staff_id', $user->id)->orderBy('created_at', 'desc');
|
|
$list = $query->paginate($request->input('per_page'));
|
|
|
|
return OfflineOrderPreviewResource::collection($list);
|
|
}
|
|
|
|
public function detail(string $id)
|
|
{
|
|
$info = OfflineOrderPreview::with(['store', 'coupon', 'order.user'])->findOrFail($id);
|
|
return OfflineOrderPreviewResource::make($info);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$request->validate([
|
|
'store_id' => ['bail', 'required', 'int'],
|
|
'items' => ['bail', 'required', 'array'],
|
|
'items.*.product_category_id' => ['bail', 'required', 'int'],
|
|
'items.*.products_total_amount' => ['bail', 'required', 'numeric', 'min:0', 'regex:/^([1-9]\d*|0)(\.\d{1,2})?$/'],
|
|
'items.*.discount' => ['bail', 'nullable', 'numeric', 'gt:0', 'lt:10', 'regex:/^[0-9](\.\d{1,2})?$/'],
|
|
]);
|
|
|
|
$user = $request->user();
|
|
|
|
if (! $user->userInfo->is_company) {
|
|
throw new BizException('非内部员工');
|
|
}
|
|
|
|
$store = Store::findOrFail($request->input('store_id'));
|
|
$couponId = $request->input('coupon_id');
|
|
$userId = $request->input('user_id');
|
|
$coupon = null;
|
|
$couponDiscount = 0;
|
|
if ($couponId) {
|
|
$coupon = UserCoupon::query()->onlyAvailable()->find($couponId);
|
|
if (!$coupon) {
|
|
throw new BizException('优惠券不可用');
|
|
}
|
|
$userId = $coupon->user_id;
|
|
}
|
|
$items = $request->input('items');
|
|
$totalAmount = 0;
|
|
$paymentAmount = 0;
|
|
$discountAmount = 0;
|
|
foreach($items as $item) {
|
|
$totalAmount += $item['products_total_amount'];
|
|
$paymentAmount += bcmul($item['products_total_amount'], $item['discount'] / 10, 2);
|
|
}
|
|
$discountAmount = bcsub($totalAmount, $paymentAmount, 2);
|
|
if ($coupon) {
|
|
$couponDiscount = bcdiv($coupon->getDiscountAmount($paymentAmount), 100, 2);
|
|
$paymentAmount = bcsub($paymentAmount, $couponDiscount, 2);
|
|
}
|
|
|
|
$preview = OfflineOrderPreview::create([
|
|
'store_id' => $store->id,
|
|
'staff_id' => $user->id,
|
|
'payload' => ['items' => $items, 'total_amount' => $totalAmount, 'discount_amount' => $discountAmount, 'coupon_discount' => $couponDiscount, 'payment_amount' => $paymentAmount],
|
|
'remark' => $request->input('remark'),
|
|
'user_id' => $userId,
|
|
'coupon_id' => $couponId,
|
|
]);
|
|
|
|
if (config('app.env') != "local") {
|
|
$scene = http_build_query([
|
|
'oo' => $preview->id,
|
|
'i' => $user->userInfo->code,
|
|
]);
|
|
|
|
// 生成小程序码
|
|
$app = Factory::miniProgram(config('wechat.mini_program.default'));
|
|
|
|
$response = $app->app_code->getUnlimit($scene, [
|
|
'page' => 'pages/welcome/index',
|
|
'check_path' => false,
|
|
'env_version' => app()->isProduction() ? 'release' : $request->input('env_version', 'trial'),
|
|
'width' => $request->input('width', 200),
|
|
]);
|
|
|
|
// 保存小程序码
|
|
if ($response instanceof StreamResponse) {
|
|
$directory = 'offline-order-preview';
|
|
$filename = "{$preview->id}.png";
|
|
|
|
$disk = Storage::disk('public');
|
|
|
|
$response->save($disk->path($directory), $filename);
|
|
|
|
$preview->update(['qrcode' => $disk->url("{$directory}/{$filename}")]);
|
|
|
|
return response()->json([
|
|
'id' => $preview->id,
|
|
'qrcode' => $preview->qrcode,
|
|
]);
|
|
}
|
|
|
|
logger('offline_order_preview 小程序码生成失败', $response);
|
|
|
|
throw new BizException('生成失败, 请重试');
|
|
}
|
|
|
|
return response()->json([
|
|
'id' => $preview->id,
|
|
'qrcode' => asset("images/logo.png")
|
|
]);
|
|
|
|
}
|
|
|
|
public function show($id)
|
|
{
|
|
$preview = OfflineOrderPreview::findOrFail($id);
|
|
|
|
return response()->json([
|
|
'id' => $preview->id,
|
|
'qrcode' => $preview->qrcode,
|
|
]);
|
|
}
|
|
}
|