diff --git a/bootstrap/app.php b/bootstrap/app.php index 1638cb68..cf794139 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -50,6 +50,10 @@ return front_route('login.index'); } }); + + $middleware->validateCsrfTokens(except: [ + 'callback*' + ]); }) ->withExceptions(function (Exceptions $exceptions) { // diff --git a/innopacks/common/config/innoshop.php b/innopacks/common/config/innoshop.php index 3d6e22bd..b191e3e1 100644 --- a/innopacks/common/config/innoshop.php +++ b/innopacks/common/config/innoshop.php @@ -8,7 +8,7 @@ */ return [ - 'version' => '0.2.0', - 'build' => '20240729', + 'version' => '0.2.1', + 'build' => '20240730', 'api_url' => env('INNOSHOP_API_URL', 'https://www.innoshop.cn'), ]; \ No newline at end of file diff --git a/innopacks/common/helpers.php b/innopacks/common/helpers.php index d29268d3..41e1b0fe 100644 --- a/innopacks/common/helpers.php +++ b/innopacks/common/helpers.php @@ -716,7 +716,7 @@ function innoshop_version(): string * @param mixed $builder * @return string */ - function to_sql(Builder $builder): string + function to_sql(mixed $builder): string { $sql = $builder->toSql(); $driver = DB::getDriverName(); diff --git a/innopacks/common/src/Models/Order.php b/innopacks/common/src/Models/Order.php index 7acf340b..e8cfdf05 100644 --- a/innopacks/common/src/Models/Order.php +++ b/innopacks/common/src/Models/Order.php @@ -9,6 +9,7 @@ namespace InnoShop\Common\Models; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Notifications\Notifiable; use InnoShop\Common\Models\Order\Fee; @@ -39,6 +40,14 @@ class Order extends BaseModel 'status_format', ]; + /** + * @return BelongsTo + */ + public function customer(): BelongsTo + { + return $this->belongsTo(Customer::class, 'customer_id', 'id'); + } + /** * Order items. * diff --git a/innopacks/common/src/Repositories/CartItemRepo.php b/innopacks/common/src/Repositories/CartItemRepo.php index b83194b4..4b3ab821 100644 --- a/innopacks/common/src/Repositories/CartItemRepo.php +++ b/innopacks/common/src/Repositories/CartItemRepo.php @@ -77,7 +77,7 @@ public function create($data): mixed */ private function handleData($requestData): array { - $skuId = $requestData['skuId'] ?? 0; + $skuId = $requestData['skuId'] ?? ($requestData['sku_id'] ?? 0); $sku = Sku::query()->findOrFail($skuId); $customerID = $requestData['customer_id'] ?? 0; @@ -89,7 +89,7 @@ private function handleData($requestData): array 'customer_id' => $customerID, 'guest_id' => $customerID ? '' : $guestID, 'selected' => true, - 'quantity' => (int) ($requestData['quantity'] ?? 0), + 'quantity' => (int) ($requestData['quantity'] ?? 1), ]; } } diff --git a/innopacks/common/src/Repositories/CategoryRepo.php b/innopacks/common/src/Repositories/CategoryRepo.php index 41107063..e04a1bdd 100644 --- a/innopacks/common/src/Repositories/CategoryRepo.php +++ b/innopacks/common/src/Repositories/CategoryRepo.php @@ -52,6 +52,14 @@ public function builder(array $filters = []): Builder $builder->where('slug', $slug); } + $parentSlug = $filters['parent_slug'] ?? ''; + if ($parentSlug) { + $category = Category::query()->where('slug', $parentSlug)->first(); + if ($category) { + $filters['parent_id'] = $category->id; + } + } + if (isset($filters['parent_id'])) { $parentID = (int) $filters['parent_id']; if ($parentID == 0) { diff --git a/innopacks/common/src/Repositories/Order/ItemRepo.php b/innopacks/common/src/Repositories/Order/ItemRepo.php index 3ea69753..ebb41f86 100644 --- a/innopacks/common/src/Repositories/Order/ItemRepo.php +++ b/innopacks/common/src/Repositories/Order/ItemRepo.php @@ -9,6 +9,7 @@ namespace InnoShop\Common\Repositories\Order; +use Exception; use InnoShop\Common\Models\Order; use InnoShop\Common\Models\Product\Sku; use InnoShop\Common\Repositories\BaseRepo; @@ -19,9 +20,14 @@ class ItemRepo extends BaseRepo * @param Order $order * @param $items * @return void + * @throws Exception */ public function createItems(Order $order, $items): void { + if (empty($items)) { + throw new Exception('Empty cart list when create order items.'); + } + $orderItems = []; foreach ($items as $item) { $orderItems[] = $this->handleItem($order, $item); diff --git a/innopacks/common/src/Repositories/OrderRepo.php b/innopacks/common/src/Repositories/OrderRepo.php index 2b2e2a2f..c3034d8e 100644 --- a/innopacks/common/src/Repositories/OrderRepo.php +++ b/innopacks/common/src/Repositories/OrderRepo.php @@ -24,13 +24,15 @@ class OrderRepo extends BaseRepo */ public function getFilterStatuses(): array { - return [ + $statuses = [ StateMachineService::UNPAID, StateMachineService::PAID, StateMachineService::SHIPPED, StateMachineService::COMPLETED, StateMachineService::CANCELLED, ]; + + return fire_hook_filter('common.repo.order.statuses', $statuses); } /** @@ -44,13 +46,27 @@ public function list(array $filters = []): LengthAwarePaginator return $builder->paginate(); } + /** + * @return Builder + */ + public function baseBuilder(): Builder + { + return Order::query(); + } + /** * @param array $filters * @return Builder */ public function builder(array $filters = []): Builder { - $builder = Order::query(); + $relations = [ + 'customer', + 'items', + ]; + + $relations = array_merge($this->relations, $relations); + $builder = $this->baseBuilder()->with($relations); $filters = array_merge($this->filters, $filters); @@ -79,6 +95,11 @@ public function builder(array $filters = []): Builder $builder->where('status', $status); } + $statuses = $filters['statuses'] ?? []; + if ($statuses) { + $builder->whereIn('status', $statuses); + } + $start = $filters['start'] ?? ''; if ($start) { $builder->where('created_at', '>', $start); diff --git a/innopacks/common/src/Repositories/ProductRepo.php b/innopacks/common/src/Repositories/ProductRepo.php index 28c7e723..ffe73a83 100644 --- a/innopacks/common/src/Repositories/ProductRepo.php +++ b/innopacks/common/src/Repositories/ProductRepo.php @@ -11,7 +11,9 @@ use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; +use InnoShop\Common\Models\Category; use InnoShop\Common\Models\Product; use InnoShop\Common\Repositories\Product\ImageRepo; @@ -238,6 +240,14 @@ private function syncImages(Product $product, $images): void } } + /** + * @return Builder + */ + public function baseBuilder(): Builder + { + return Product::query(); + } + /** * @param array $filters * @return Builder @@ -251,7 +261,10 @@ public function builder(array $filters = []): Builder 'translation', 'categories.translation', ]; - $builder = Product::query()->with($relations); + + $relations = array_merge($this->relations, $relations); + + $builder = $this->baseBuilder()->with($relations); $filters = array_merge($this->filters, $filters); @@ -262,7 +275,22 @@ public function builder(array $filters = []): Builder }); } + $categorySlug = $filters['category_slug'] ?? ''; + if ($categorySlug) { + $category = Category::query()->where('slug', $categorySlug)->first(); + if ($category) { + $categories = CategoryRepo::getInstance()->builder(['parent_id' => $category->id])->get(); + + $filters['category_ids'] = $categories->pluck('id'); + $filters['category_ids'][] = $category->id; + } + } + $categoryIds = $filters['category_ids'] ?? []; + if ($categoryIds instanceof Collection) { + $categoryIds = $categoryIds->toArray(); + } + $categoryIds = array_unique($categoryIds); if ($categoryIds) { $builder->whereHas('categories', function (Builder $query) use ($categoryIds) { $query->whereIn('category_id', $categoryIds); diff --git a/innopacks/common/src/Resources/CartListItem.php b/innopacks/common/src/Resources/CartListItem.php index 6d90487e..b70a577a 100644 --- a/innopacks/common/src/Resources/CartListItem.php +++ b/innopacks/common/src/Resources/CartListItem.php @@ -43,7 +43,7 @@ public function toArray(Request $request): array 'origin_price_format' => $sku->origin_price_format, 'subtotal' => $subtotal, 'subtotal_format' => currency_format($subtotal), - 'image' => image_resize($sku->image->path ?? $product->image->path), + 'image' => image_resize($sku->image->path ?? ($product->image->path ?? '')), 'selected' => (bool) $this->selected, ]; } diff --git a/innopacks/common/src/Resources/ProductSimple.php b/innopacks/common/src/Resources/ProductSimple.php new file mode 100644 index 00000000..76c2febb --- /dev/null +++ b/innopacks/common/src/Resources/ProductSimple.php @@ -0,0 +1,42 @@ + + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + */ + +namespace InnoShop\Common\Resources; + +use Exception; +use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; + +class ProductSimple extends JsonResource +{ + /** + * Transform the resource into an array. + * + * @param Request $request + * @return array + * @throws Exception + */ + public function toArray(Request $request): array + { + $sku = $this->masterSku; + + return [ + 'sku_id' => $sku->id, + 'product_id' => $this->id, + 'slug' => $this->slug, + 'url' => $this->url, + 'name' => $this->translation->name, + 'summary' => $this->translation->summary, + 'image_small' => image_resize($sku->image->path ?? ($this->image->path ?? '')), + 'image_big' => image_resize($sku->image->path ?? ($this->image->path ?? ''), 600, 600), + 'price_format' => $sku->price_format, + 'origin_price_format' => $sku->origin_price_format, + ]; + } +} diff --git a/innopacks/common/src/Services/Checkout/BillingService.php b/innopacks/common/src/Services/Checkout/BillingService.php index 21f1d7c1..a5d20cbe 100644 --- a/innopacks/common/src/Services/Checkout/BillingService.php +++ b/innopacks/common/src/Services/Checkout/BillingService.php @@ -12,8 +12,16 @@ use InnoShop\Plugin\Repositories\PluginRepo; use InnoShop\Plugin\Resources\Checkout\PaymentMethodItem; -class BillingService extends BaseService +class BillingService { + /** + * @return static + */ + public static function getInstance(): static + { + return new static(); + } + /** * @throws \Exception */ diff --git a/innopacks/common/src/Services/CheckoutService.php b/innopacks/common/src/Services/CheckoutService.php index 0b177bea..eb38f6f8 100644 --- a/innopacks/common/src/Services/CheckoutService.php +++ b/innopacks/common/src/Services/CheckoutService.php @@ -245,7 +245,7 @@ public function getCheckoutResult(): array 'cart_list' => $this->getCartList(), 'address_list' => $this->getAddressList(), 'shipping_methods' => ShippingService::getInstance($this)->getMethods(), - 'billing_methods' => BillingService::getInstance($this)->getMethods(), + 'billing_methods' => BillingService::getInstance()->getMethods(), 'checkout' => $this->getCheckoutData(), 'fee_list' => $this->getFeeList(), 'total' => $this->getTotal(), diff --git a/innopacks/front/lang/en/common.php b/innopacks/front/lang/en/common.php index 30140787..e110f12f 100644 --- a/innopacks/front/lang/en/common.php +++ b/innopacks/front/lang/en/common.php @@ -8,32 +8,33 @@ */ return [ - 'home' => 'Home', - 'login' => 'Login', - 'register' => 'Register', - 'cancel' => 'Cancel', - 'confirm' => 'Confirm', - 'delete' => 'Delete', - 'edit' => 'Edit', - 'action' => 'Action', - 'add' => 'Add', - 'text_hint' => 'Hint', - 'image' => 'Image', - 'all' => 'All', - 'status' => 'Status', - 'view' => 'View', - 'submit' => 'Submit', - 'products' => 'Products', - 'news' => 'Articles', - 'pages' => 'Pages', - 'search' => 'Search', - 'back_page' => 'Go Back', - 'telephone' => 'Telephone', - 'created_at' => 'Created at', + 'home' => 'Home', + 'login' => 'Login', + 'register' => 'Register', + 'cancel' => 'Cancel', + 'confirm' => 'Confirm', + 'delete' => 'Delete', + 'edit' => 'Edit', + 'action' => 'Action', + 'add' => 'Add', + 'text_hint' => 'Hint', + 'image' => 'Image', + 'all' => 'All', + 'status' => 'Status', + 'view' => 'View', + 'submit' => 'Submit', + 'products' => 'Products', + 'news' => 'Articles', + 'pages' => 'Pages', + 'search' => 'Search', + 'back_page' => 'Go Back', + 'telephone' => 'Telephone', + 'created_at' => 'Created at', + 'delete_confirm' => 'You sure you want to delete it?', - 'delete_confirm' => 'You sure you want to delete it?', - 'get_success' => 'Get successfully', - 'saved_success' => 'Saved successfully', - 'updated_success' => 'Updated successfully', - 'deleted_success' => 'Deleted successfully', + 'get_success' => 'Get successfully', + 'saved_success' => 'Saved successfully', + 'updated_success' => 'Updated successfully', + 'deleted_success' => 'Deleted successfully', + 'submitted_success' => 'Submitted successfully', ]; diff --git a/innopacks/front/lang/es/common.php b/innopacks/front/lang/es/common.php index 8605cd52..60148b27 100644 --- a/innopacks/front/lang/es/common.php +++ b/innopacks/front/lang/es/common.php @@ -8,32 +8,33 @@ */ return [ - 'home' => 'Inicio', - 'login' => 'Iniciar sesión', - 'register' => 'Registrarse', - 'cancel' => 'Cancelar', - 'confirm' => 'Confirmar', - 'delete' => 'Eliminar', - 'edit' => 'Editar', - 'action' => 'Acción', - 'add' => 'Agregar', - 'text_hint' => 'Sugerencia', - 'image' => 'Imagen', - 'all' => 'Todos', - 'status' => 'Estado', - 'view' => 'Ver', - 'submit' => 'Enviar', - 'products' => 'Productos', - 'news' => 'Artículos', - 'pages' => 'Páginas', - 'search' => 'Buscar', - 'back_page' => 'Volver', - 'telephone' => 'Teléfono', - 'created_at' => 'Creado el', + 'home' => 'Inicio', + 'login' => 'Iniciar sesión', + 'register' => 'Registrarse', + 'cancel' => 'Cancelar', + 'confirm' => 'Confirmar', + 'delete' => 'Eliminar', + 'edit' => 'Editar', + 'action' => 'Acción', + 'add' => 'Agregar', + 'text_hint' => 'Sugerencia', + 'image' => 'Imagen', + 'all' => 'Todos', + 'status' => 'Estado', + 'view' => 'Ver', + 'submit' => 'Enviar', + 'products' => 'Productos', + 'news' => 'Artículos', + 'pages' => 'Páginas', + 'search' => 'Buscar', + 'back_page' => 'Volver', + 'telephone' => 'Teléfono', + 'created_at' => 'Creado el', + 'delete_confirm' => '¿Estás seguro de que deseas eliminarlo?', - 'delete_confirm' => '¿Estás seguro de que deseas eliminarlo?', - 'get_success' => 'Obtener con éxito', - 'saved_success' => 'Guardado con éxito', - 'updated_success' => 'Actualizado con éxito', - 'deleted_success' => 'Eliminado con éxito', + 'get_success' => 'Obtener con éxito', + 'saved_success' => 'Guardado con éxito', + 'updated_success' => 'Actualizado con éxito', + 'deleted_success' => 'Eliminado con éxito', + 'submitted_success' => 'Submitted successfully', ]; diff --git a/innopacks/front/lang/zh_cn/common.php b/innopacks/front/lang/zh_cn/common.php index 4d8b6e18..f8753f11 100644 --- a/innopacks/front/lang/zh_cn/common.php +++ b/innopacks/front/lang/zh_cn/common.php @@ -8,32 +8,33 @@ */ return [ - 'home' => '首页', - 'login' => '登录', - 'register' => '注册', - 'cancel' => '取消', - 'confirm' => '确定', - 'delete' => '删除', - 'edit' => '编辑', - 'action' => '操作', - 'add' => '添加', - 'text_hint' => '提示', - 'image' => '图片', - 'all' => '全部', - 'status' => '状态', - 'view' => '查看', - 'submit' => '提交', - 'products' => '商品', - 'news' => '文章', - 'pages' => '单页', - 'search' => '搜索', - 'telephone' => '联系电话', - 'back_page' => '返回上一页', - 'created_at' => '创建时间', + 'home' => '首页', + 'login' => '登录', + 'register' => '注册', + 'cancel' => '取消', + 'confirm' => '确定', + 'delete' => '删除', + 'edit' => '编辑', + 'action' => '操作', + 'add' => '添加', + 'text_hint' => '提示', + 'image' => '图片', + 'all' => '全部', + 'status' => '状态', + 'view' => '查看', + 'submit' => '提交', + 'products' => '商品', + 'news' => '文章', + 'pages' => '单页', + 'search' => '搜索', + 'telephone' => '联系电话', + 'back_page' => '返回上一页', + 'created_at' => '创建时间', + 'delete_confirm' => '确定要删除吗?', - 'delete_confirm' => '确定要删除吗?', - 'get_success' => '获取成功', - 'saved_success' => '保存成功', - 'updated_success' => '更新成功', - 'deleted_success' => '删除成功', + 'get_success' => '获取成功', + 'saved_success' => '保存成功', + 'updated_success' => '更新成功', + 'deleted_success' => '删除成功', + 'submitted_success' => '提交成功', ]; diff --git a/innopacks/front/resources/views/orders/show.blade.php b/innopacks/front/resources/views/orders/show.blade.php new file mode 100644 index 00000000..4cb37fa0 --- /dev/null +++ b/innopacks/front/resources/views/orders/show.blade.php @@ -0,0 +1,97 @@ +@extends('layouts.app') +@section('body-class', 'page-checkout-success') + +@section('content') + + + + @hookinsert('order.show.top') + +
+
+ +
+ + @hookinsert('order.show.top') + + @endsection + + @push('footer') + + @endpush \ No newline at end of file diff --git a/innopacks/front/routes/api.php b/innopacks/front/routes/api.php index 968d3f5f..8d232902 100644 --- a/innopacks/front/routes/api.php +++ b/innopacks/front/routes/api.php @@ -16,12 +16,17 @@ Route::post('/register', [ApiControllers\AuthController::class, 'register'])->name('login.register'); Route::get('/categories', [ApiControllers\CategoryController::class, 'index'])->name('categories.index'); + Route::get('/products', [ApiControllers\ProductController::class, 'index'])->name('products.index'); +Route::get('/products/{product}', [ApiControllers\ProductController::class, 'show'])->name('products.show'); + +Route::get('/checkout/billing_methods', [ApiControllers\CheckoutController::class, 'billingMethods'])->name('checkout.billing_methods'); +Route::post('/checkout/quick_confirm', [ApiControllers\CheckoutController::class, 'quickConfirm'])->name('checkout.quick_confirm'); Route::get('/orders', [ApiControllers\OrderController::class, 'index'])->name('orders.index'); -//Route::middleware(['auth:sanctum'])->group(function () { -// Route::get('/orders', function () { -// return []; -// }); -//}); +Route::middleware(['auth:sanctum'])->group(function () { + Route::get('/addresses', function () { + return []; + }); +}); diff --git a/innopacks/front/routes/web.php b/innopacks/front/routes/web.php index e4970302..426b1f9a 100644 --- a/innopacks/front/routes/web.php +++ b/innopacks/front/routes/web.php @@ -49,6 +49,7 @@ // Orders Route::get('/orders/{number}/pay', [Controllers\OrderController::class, 'pay'])->name('orders.pay'); +Route::get('/orders/{number}', [Controllers\OrderController::class, 'numberShow'])->name('orders.number_show'); // Guest Address Route::post('/addresses', [Controllers\AddressesController::class, 'store'])->name('addresses.store'); diff --git a/innopacks/front/src/ApiControllers/CategoryController.php b/innopacks/front/src/ApiControllers/CategoryController.php index 06178bb6..3dccf202 100644 --- a/innopacks/front/src/ApiControllers/CategoryController.php +++ b/innopacks/front/src/ApiControllers/CategoryController.php @@ -9,13 +9,21 @@ namespace InnoShop\Front\ApiControllers; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; use InnoShop\Common\Repositories\CategoryRepo; class CategoryController extends BaseApiController { - public function index() + /** + * @param Request $request + * @return JsonResponse + */ + public function index(Request $request): JsonResponse { - $categories = CategoryRepo::getInstance()->withActive()->builder()->get(); + $filters = $request->all(); + + $categories = CategoryRepo::getInstance()->withActive()->builder($filters)->get(); return json_success('获取成功', $categories); } diff --git a/innopacks/front/src/ApiControllers/CheckoutController.php b/innopacks/front/src/ApiControllers/CheckoutController.php new file mode 100644 index 00000000..e207458b --- /dev/null +++ b/innopacks/front/src/ApiControllers/CheckoutController.php @@ -0,0 +1,56 @@ + + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + */ + +namespace InnoShop\Front\ApiControllers; + +use Exception; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use InnoShop\Common\Services\CartService; +use InnoShop\Common\Services\Checkout\BillingService; +use InnoShop\Common\Services\CheckoutService; +use InnoShop\Common\Services\StateMachineService; +use Throwable; + +class CheckoutController extends BaseApiController +{ + /** + * @return JsonResponse + * @throws Exception + */ + public function billingMethods(): JsonResponse + { + $methods = BillingService::getInstance()->getMethods(); + + return json_success(trans('front::common.get_success'), $methods); + } + + /** + * @param Request $request + * @return JsonResponse + * @throws Throwable + */ + public function quickConfirm(Request $request): JsonResponse + { + try { + CartService::getInstance()->addCart($request->all()); + + $checkoutService = CheckoutService::getInstance(); + $checkoutData = ['billing_method_code' => $request->get('shipping_method_code')]; + $checkoutService->updateValues($checkoutData); + + $order = $checkoutService->confirm(); + StateMachineService::getInstance($order)->changeStatus(StateMachineService::UNPAID); + + return json_success(trans('front::common.submitted_success'), $order); + } catch (Exception $e) { + return json_fail($e->getMessage()); + } + } +} diff --git a/innopacks/front/src/ApiControllers/ProductController.php b/innopacks/front/src/ApiControllers/ProductController.php index beb35744..dc7b87bd 100644 --- a/innopacks/front/src/ApiControllers/ProductController.php +++ b/innopacks/front/src/ApiControllers/ProductController.php @@ -10,17 +10,36 @@ namespace InnoShop\Front\ApiControllers; use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use InnoShop\Common\Models\Product; use InnoShop\Common\Repositories\ProductRepo; +use InnoShop\Common\Resources\ProductSimple; class ProductController extends BaseApiController { /** + * @param Request $request * @return JsonResponse */ - public function index(): JsonResponse + public function index(Request $request): JsonResponse { - $categories = ProductRepo::getInstance()->withActive()->builder()->paginate(); + $filters = $request->all(); - return json_success('获取成功', $categories); + $products = ProductRepo::getInstance()->withActive()->builder($filters)->paginate(); + + $collection = ProductSimple::collection($products); + + return json_success(trans('front::common.get_success'), $collection); + } + + /** + * @param Product $product + * @return JsonResponse + */ + public function show(Product $product): JsonResponse + { + $single = new ProductSimple($product); + + return json_success(trans('front::common.get_success'), $single); } } diff --git a/innopacks/front/src/Components/Breadcrumb.php b/innopacks/front/src/Components/Breadcrumb.php index 1e056dda..b00cdc1c 100644 --- a/innopacks/front/src/Components/Breadcrumb.php +++ b/innopacks/front/src/Components/Breadcrumb.php @@ -9,6 +9,7 @@ namespace InnoShop\Front\Components; +use Exception; use Illuminate\View\Component; use InnoShop\Common\Libraries\Breadcrumb as BreadcrumbLib; @@ -20,6 +21,7 @@ class Breadcrumb extends Component * @param $type * @param $value * @param string $title + * @throws Exception */ public function __construct($type, $value, string $title = '') { diff --git a/innopacks/front/src/Controllers/CheckoutController.php b/innopacks/front/src/Controllers/CheckoutController.php index 6f278d54..d11c2e50 100644 --- a/innopacks/front/src/Controllers/CheckoutController.php +++ b/innopacks/front/src/Controllers/CheckoutController.php @@ -12,11 +12,11 @@ use App\Http\Controllers\Controller; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use InnoShop\Common\Models\Address; use InnoShop\Common\Repositories\OrderRepo; use InnoShop\Common\Services\CheckoutService; use InnoShop\Common\Services\StateMachineService; use InnoShop\Front\Requests\CheckoutConfirmRequest; +use Throwable; class CheckoutController extends Controller { @@ -24,7 +24,7 @@ class CheckoutController extends Controller * Get checkout data and render page. * * @return mixed - * @throws \Throwable + * @throws Throwable */ public function index(): mixed { @@ -42,7 +42,7 @@ public function index(): mixed * * @param Request $request * @return JsonResponse - * @throws \Throwable + * @throws Throwable */ public function update(Request $request): JsonResponse { @@ -59,20 +59,24 @@ public function update(Request $request): JsonResponse * * @param CheckoutConfirmRequest $request * @return JsonResponse - * @throws \Throwable + * @throws Throwable */ public function confirm(CheckoutConfirmRequest $request): JsonResponse { - $checkout = CheckoutService::getInstance(); - $data = $request->all(); - if ($data) { - $checkout->updateValues($data); - } + try { + $checkout = CheckoutService::getInstance(); + $data = $request->all(); + if ($data) { + $checkout->updateValues($data); + } - $order = $checkout->confirm(); - StateMachineService::getInstance($order)->changeStatus(StateMachineService::UNPAID); + $order = $checkout->confirm(); + StateMachineService::getInstance($order)->changeStatus(StateMachineService::UNPAID); - return json_success('提交成功', $order); + return json_success(trans('front::common.submitted_success'), $order); + } catch (\Exception $e) { + return json_fail($e->getMessage()); + } } /** diff --git a/innopacks/front/src/Controllers/OrderController.php b/innopacks/front/src/Controllers/OrderController.php index 5e4dc7a0..5a5c9a54 100644 --- a/innopacks/front/src/Controllers/OrderController.php +++ b/innopacks/front/src/Controllers/OrderController.php @@ -12,6 +12,7 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; use InnoShop\Common\Models\Order; +use InnoShop\Common\Repositories\OrderRepo; use InnoShop\Front\Services\PaymentService; class OrderController extends Controller @@ -23,8 +24,29 @@ class OrderController extends Controller */ public function pay(Request $request): mixed { - $order = Order::query()->where('number', $request->number)->firstOrFail(); + try { + $order = Order::query()->where('number', $request->number)->firstOrFail(); - return PaymentService::getInstance($order)->pay(); + return PaymentService::getInstance($order)->pay(); + } catch (\Exception $e) { + return $e->getMessage(); + } + } + + /** + * Order detail + * + * @param int $number + * @return mixed + */ + public function numberShow(int $number): mixed + { + $order = OrderRepo::getInstance()->getOrderByNumber($number); + $order->load(['items', 'fees']); + $data = [ + 'order' => $order, + ]; + + return inno_view('orders.show', $data); } } diff --git a/innopacks/front/src/Controllers/UploadController.php b/innopacks/front/src/Controllers/UploadController.php index 7ad0f51b..c7f15a54 100644 --- a/innopacks/front/src/Controllers/UploadController.php +++ b/innopacks/front/src/Controllers/UploadController.php @@ -45,7 +45,7 @@ public function images(UploadImageRequest $request): JsonResponse public function files(UploadFileRequest $request): JsonResponse { $file = $request->file('file'); - $type = $request->file('type', 'common'); + $type = $request->file('type', 'files'); $filePath = $file->store("/{$type}", 'public'); $realPath = "storage/$filePath"; diff --git a/innopacks/front/src/Services/PaymentService.php b/innopacks/front/src/Services/PaymentService.php index 14dcfa27..7ca3022d 100644 --- a/innopacks/front/src/Services/PaymentService.php +++ b/innopacks/front/src/Services/PaymentService.php @@ -45,6 +45,9 @@ public static function getInstance(Order $order): static public function pay(): mixed { try { + if ($this->order->status != 'unpaid') { + throw new Exception("Order status must be unpaid, now is {$this->order->status}!"); + } $originCode = $this->billingMethodCode; $paymentCode = Str::studly($originCode); $viewPath = fire_hook_filter("service.payment.pay.$originCode.view", "$paymentCode::payment"); diff --git a/innopacks/panel/lang/en/common.php b/innopacks/panel/lang/en/common.php index c2aa221b..0ace9a8e 100644 --- a/innopacks/panel/lang/en/common.php +++ b/innopacks/panel/lang/en/common.php @@ -55,9 +55,10 @@ 'meta_title' => 'Meta Title', 'up_image_text' => 'Click to upload, or drag the file in', 'no_data' => 'No data', + 'verify_required' => 'Please fill out', - 'saved_success' => 'Saved successfully', - 'updated_success' => 'Updated successfully', - 'deleted_success' => 'Deleted successfully', - 'verify_required' => 'Please fill out', + 'saved_success' => 'Saved successfully', + 'updated_success' => 'Updated successfully', + 'deleted_success' => 'Deleted successfully', + 'submitted_success' => 'Submitted successfully', ]; diff --git a/innopacks/panel/lang/es/common.php b/innopacks/panel/lang/es/common.php index ba7f6c8a..bc1f7d2c 100644 --- a/innopacks/panel/lang/es/common.php +++ b/innopacks/panel/lang/es/common.php @@ -54,9 +54,10 @@ 'meta_title' => 'Meta Título', 'up_image_text' => 'Haga clic para subir, o arrastre el archivo aquí', 'no_data' => 'Sin datos', + 'verify_required' => 'Por favor, complete', - 'saved_success' => 'Guardado correctamente', - 'updated_success' => 'Actualizado correctamente', - 'deleted_success' => 'Eliminado correctamente', - 'verify_required' => 'Por favor, complete', + 'saved_success' => 'Guardado correctamente', + 'updated_success' => 'Actualizado correctamente', + 'deleted_success' => 'Eliminado correctamente', + 'submitted_success' => 'Submitted successfully', ]; diff --git a/innopacks/panel/lang/zh_cn/common.php b/innopacks/panel/lang/zh_cn/common.php index a33f7d15..6ac487fd 100644 --- a/innopacks/panel/lang/zh_cn/common.php +++ b/innopacks/panel/lang/zh_cn/common.php @@ -55,9 +55,10 @@ 'meta_keywords' => 'Meta 关键词', 'up_image_text' => '点击上传,或将文件拖入进来', 'no_data' => '没有数据', + 'verify_required' => '请填写', - 'saved_success' => '保存成功', - 'updated_success' => '更新成功', - 'deleted_success' => '删除成功', - 'verify_required' => '请填写', + 'saved_success' => '保存成功', + 'updated_success' => '更新成功', + 'deleted_success' => '删除成功', + 'submitted_success' => '提交成功', ]; diff --git a/innopacks/panel/lang/zh_cn/dashboard.php b/innopacks/panel/lang/zh_cn/dashboard.php index 77dbc890..989f5754 100644 --- a/innopacks/panel/lang/zh_cn/dashboard.php +++ b/innopacks/panel/lang/zh_cn/dashboard.php @@ -12,7 +12,6 @@ 'product_quantity' => '产品总数', 'customer_quantity' => '客户总数', 'order_amount' => '订单总额', - 'order_quantity' => '订单数量', 'ranking' => '排名', 'product' => '商品', 'sales' => '销量', diff --git a/innopacks/plugin/src/Core/PluginManager.php b/innopacks/plugin/src/Core/PluginManager.php index 9990c319..2fbd2ca8 100644 --- a/innopacks/plugin/src/Core/PluginManager.php +++ b/innopacks/plugin/src/Core/PluginManager.php @@ -35,6 +35,10 @@ public function getPlugins(): Collection $existed = $this->getPluginsConfig(); $plugins = new Collection; foreach ($existed as $dirname => $package) { + if ($package['hide'] ?? false) { + continue; + } + $pluginPath = $this->getPluginsDir().DIRECTORY_SEPARATOR.$dirname; try { diff --git a/innopacks/plugin/src/PluginServiceProvider.php b/innopacks/plugin/src/PluginServiceProvider.php index 65e703f1..16e4a784 100644 --- a/innopacks/plugin/src/PluginServiceProvider.php +++ b/innopacks/plugin/src/PluginServiceProvider.php @@ -214,6 +214,7 @@ private function loadPluginRoutes($pluginCode): void { $this->loadPluginPanelRoutes($pluginCode); $this->loadPluginFrontRoutes($pluginCode); + $this->loadPluginFrontApiRoutes($pluginCode); } /** @@ -267,6 +268,26 @@ private function loadPluginFrontRoutes($pluginCode): void } } + /** + * Register frontend api routes. + * + * @param $pluginCode + * @return void + */ + protected function loadPluginFrontApiRoutes($pluginCode): void + { + $pluginBasePath = $this->pluginBasePath; + $frontApiRoutePath = "$pluginBasePath/$pluginCode/Routes/api.php"; + if (file_exists($frontApiRoutePath)) { + Route::prefix('api') + ->middleware('api') + ->name('api.') + ->group(function () use ($frontApiRoutePath) { + $this->loadRoutesFrom($frontApiRoutePath); + }); + } + } + /** * Load plugin languages. *