6
0
Fork 0
jiqu-library-server/app/Endpoint/Api/Http/Controllers/OfflineOrderPreviewControll...

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,
]);
}
}