v1.1.2 合并至github项目
This commit is contained in:
commit
8674f1125c
|
|
@ -0,0 +1,28 @@
|
||||||
|
APP_NAME='wyyl'
|
||||||
|
APP_ENV=
|
||||||
|
APP_KEY=base64:PItUypiY6FmV8oQTVIcIHyNQJAuuS36FmEs8exQbYAw=
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_LOG_LEVEL=
|
||||||
|
APP_URL=http://43.153.17.83
|
||||||
|
|
||||||
|
BEIKE_API_URL=https://beikeshop.com
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=wyyl
|
||||||
|
DB_USERNAME=wyyl
|
||||||
|
DB_PASSWORD='wyyl@2023'
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
|
||||||
|
MAIL_DRIVER=
|
||||||
|
MAIL_HOST=
|
||||||
|
MAIL_PORT=
|
||||||
|
MAIL_USERNAME=
|
||||||
|
MAIL_PASSWORD=
|
||||||
|
MAIL_ENCRYPTION=
|
||||||
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<html>
|
||||||
|
<head><title>404 Not Found</title></head>
|
||||||
|
<body>
|
||||||
|
<center><h1>404 Not Found</h1></center>
|
||||||
|
<hr><center>nginx</center>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PagesController.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-08-08 15:07:33
|
||||||
|
* @modified 2022-08-08 15:07:33
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Admin\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Admin\Http\Requests\PageRequest;
|
||||||
|
use Beike\Admin\Repositories\InquiryRepo;
|
||||||
|
use Beike\Models\Page;
|
||||||
|
use Beike\Shop\Http\Resources\InquiryDetail;
|
||||||
|
use Beike\Shop\Http\Resources\ProductSimple;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class InquiryController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 显示单页列表
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$pageList = InquiryRepo::getList();
|
||||||
|
$data = [
|
||||||
|
'pages' => $pageList,
|
||||||
|
'pages_format' => InquiryDetail::collection($pageList)->jsonSerialize(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin::pages.inquiry.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建页面
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('admin::pages.pages.form', ['page' => new Page()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存新建
|
||||||
|
*
|
||||||
|
* @param PageRequest $request
|
||||||
|
* @return RedirectResponse
|
||||||
|
*/
|
||||||
|
public function store(PageRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$requestData = $request->all();
|
||||||
|
$page = PageRepo::createOrUpdate($requestData);
|
||||||
|
hook_action('admin.page.store.after', ['request_data' => $requestData, 'page' => $page]);
|
||||||
|
|
||||||
|
return redirect(admin_route('pages.index'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect(admin_route('pages.index'))->withErrors(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @param Page $page
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function edit(Request $request, Page $page)
|
||||||
|
{
|
||||||
|
$page->load(['products.description', 'category.description']);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'page' => $page,
|
||||||
|
'products' => ProductSimple::collection($page->products)->jsonSerialize(),
|
||||||
|
'descriptions' => PageRepo::getDescriptionsByLocale($page->id),
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin::pages.pages.form', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存更新
|
||||||
|
*
|
||||||
|
* @param PageRequest $request
|
||||||
|
* @param int $pageId
|
||||||
|
* @return RedirectResponse
|
||||||
|
*/
|
||||||
|
public function update(PageRequest $request, int $pageId)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$requestData = $request->all();
|
||||||
|
$requestData['id'] = $pageId;
|
||||||
|
$page = PageRepo::createOrUpdate($requestData);
|
||||||
|
hook_action('admin.page.update.after', ['request_data' => $requestData, 'page' => $page]);
|
||||||
|
|
||||||
|
return redirect()->to(admin_route('pages.index'));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect(admin_route('pages.index'))->withErrors(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单页
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param int $pageId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function destroy(Request $request, int $pageId): array
|
||||||
|
{
|
||||||
|
InquiryRepo::deleteById($pageId);
|
||||||
|
|
||||||
|
return json_success(trans('common.deleted_success'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索页面标题自动完成
|
||||||
|
* @param Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function autocomplete(Request $request): array
|
||||||
|
{
|
||||||
|
$products = PageRepo::autocomplete($request->get('name') ?? '');
|
||||||
|
|
||||||
|
return json_success(trans('common.get_success'), $products);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单页名称
|
||||||
|
* @param Page $page
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function name(Page $page): array
|
||||||
|
{
|
||||||
|
$name = $page->description->title ?? '';
|
||||||
|
|
||||||
|
return json_success(trans('common.get_success'), $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PageRepo.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-07-26 21:08:07
|
||||||
|
* @modified 2022-07-26 21:08:07
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Admin\Repositories;
|
||||||
|
|
||||||
|
use Beike\Models\Inquiry;
|
||||||
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class InquiryRepo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取列表页数据
|
||||||
|
*
|
||||||
|
* @return LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
public static function getList(): LengthAwarePaginator
|
||||||
|
{
|
||||||
|
$builder = Inquiry::query()->with([
|
||||||
|
'productsku' => function($query) {
|
||||||
|
$query->withTrashed();
|
||||||
|
},
|
||||||
|
'productsku.product' => function($query) {
|
||||||
|
$query->withTrashed()->with(['description']);
|
||||||
|
},
|
||||||
|
])->orderByDesc('updated_at');
|
||||||
|
|
||||||
|
return $builder->paginate(perPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function findByPageId($pageId)
|
||||||
|
{
|
||||||
|
$page = Inquiry::query()->findOrFail($pageId);
|
||||||
|
$page->load(['descriptions']);
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDescriptionsByLocale($pageId)
|
||||||
|
{
|
||||||
|
$page = self::findByPageId($pageId);
|
||||||
|
|
||||||
|
return $page->descriptions->keyBy('locale')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createOrUpdate($data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
$region = self::pushPage($data);
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
return $region;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function pushPage($data)
|
||||||
|
{
|
||||||
|
$id = $data['id'] ?? 0;
|
||||||
|
if ($id) {
|
||||||
|
$page = Inquiry::query()->findOrFail($id);
|
||||||
|
} else {
|
||||||
|
$page = new Inquiry();
|
||||||
|
}
|
||||||
|
$page->fill([
|
||||||
|
'page_category_id' => (int) ($data['page_category_id'] ?? 0),
|
||||||
|
'position' => (int) ($data['position'] ?? 0),
|
||||||
|
'active' => (bool) ($data['active'] ?? true),
|
||||||
|
'author' => $data['author'] ?? '',
|
||||||
|
'views' => (int) ($data['views'] ?? 0),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$page->saveOrFail();
|
||||||
|
|
||||||
|
$page->descriptions()->delete();
|
||||||
|
$page->descriptions()->createMany($data['descriptions']);
|
||||||
|
|
||||||
|
$products = $data['products'] ?? [];
|
||||||
|
if ($products) {
|
||||||
|
$items = [];
|
||||||
|
foreach ($products as $item) {
|
||||||
|
$items[] = [
|
||||||
|
'product_id' => $item,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$page->pageProducts()->delete();
|
||||||
|
$page->pageProducts()->createMany($items);
|
||||||
|
}
|
||||||
|
|
||||||
|
$page->load(['descriptions', 'pageProducts']);
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteById($id)
|
||||||
|
{
|
||||||
|
$page = Inquiry::query()->findOrFail($id);
|
||||||
|
$page->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面内容自动完成
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function autocomplete($name): array
|
||||||
|
{
|
||||||
|
$pages = Inquiry::query()->with('description')
|
||||||
|
->whereHas('description', function ($query) use ($name) {
|
||||||
|
$query->where('title', 'like', "{$name}%");
|
||||||
|
})->limit(10)->get();
|
||||||
|
$results = [];
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
$results[] = [
|
||||||
|
'id' => $page->id,
|
||||||
|
'name' => $page->description->title,
|
||||||
|
'status' => $page->active,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -169,6 +169,10 @@ Route::prefix($adminName)
|
||||||
Route::middleware('can:pages_update')->put('pages/{page}', [Controllers\PagesController::class, 'update'])->name('pages.update');
|
Route::middleware('can:pages_update')->put('pages/{page}', [Controllers\PagesController::class, 'update'])->name('pages.update');
|
||||||
Route::middleware('can:pages_delete')->delete('pages/{page}', [Controllers\PagesController::class, 'destroy'])->name('pages.destroy');
|
Route::middleware('can:pages_delete')->delete('pages/{page}', [Controllers\PagesController::class, 'destroy'])->name('pages.destroy');
|
||||||
|
|
||||||
|
// 文章
|
||||||
|
Route::middleware('can:inquiry_index')->get('inquiry', [Controllers\InquiryController::class, 'index'])->name('inquiry.index');
|
||||||
|
Route::middleware('can:inquiry_delete')->delete('inquiry/{page}', [Controllers\InquiryController::class, 'destroy'])->name('inquiry.destroy');
|
||||||
|
|
||||||
// 文章分类
|
// 文章分类
|
||||||
Route::middleware('can:page_categories_index')->get('page_categories', [Controllers\PageCategoryController::class, 'index'])->name('page_categories.index');
|
Route::middleware('can:page_categories_index')->get('page_categories', [Controllers\PageCategoryController::class, 'index'])->name('page_categories.index');
|
||||||
Route::middleware('can:page_categories_index')->get('page_categories/autocomplete', [Controllers\PageCategoryController::class, 'autocomplete'])->name('page_categories.autocomplete');
|
Route::middleware('can:page_categories_index')->get('page_categories/autocomplete', [Controllers\PageCategoryController::class, 'autocomplete'])->name('page_categories.autocomplete');
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class ProductService
|
||||||
$product->skus()->delete();
|
$product->skus()->delete();
|
||||||
$product->descriptions()->delete();
|
$product->descriptions()->delete();
|
||||||
$product->attributes()->delete();
|
$product->attributes()->delete();
|
||||||
|
$product->numPrices()->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
$descriptions = [];
|
$descriptions = [];
|
||||||
|
|
@ -58,6 +59,10 @@ class ProductService
|
||||||
}
|
}
|
||||||
$product->skus()->createMany($skus);
|
$product->skus()->createMany($skus);
|
||||||
|
|
||||||
|
if($data['price_setting'] == 'num' && !empty($data['numPrices'])){
|
||||||
|
$product->numPrices()->createMany(list_sort_by($data['numPrices'],'num') ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
$product->categories()->sync($data['categories'] ?? []);
|
$product->categories()->sync($data['categories'] ?? []);
|
||||||
$product->relations()->sync($data['relations'] ?? []);
|
$product->relations()->sync($data['relations'] ?? []);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ class Header extends Component
|
||||||
['name' => trans('admin/common.customer'), 'route' => 'customers.index', 'code' => 'Customer'],
|
['name' => trans('admin/common.customer'), 'route' => 'customers.index', 'code' => 'Customer'],
|
||||||
['name' => trans('admin/common.page'), 'route' => 'pages.index', 'code' => 'Page'],
|
['name' => trans('admin/common.page'), 'route' => 'pages.index', 'code' => 'Page'],
|
||||||
['name' => trans('admin/common.setting'), 'route' => 'settings.index', 'code' => 'Setting'],
|
['name' => trans('admin/common.setting'), 'route' => 'settings.index', 'code' => 'Setting'],
|
||||||
|
['name' => trans('admin/common.inquiry'), 'route' => 'inquiry.index', 'code' => 'Inquiry'],
|
||||||
];
|
];
|
||||||
|
|
||||||
return hook_filter('admin.header_menus', $menus);
|
return hook_filter('admin.header_menus', $menus);
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,11 @@ class Sidebar extends Component
|
||||||
foreach ($routes as $route) {
|
foreach ($routes as $route) {
|
||||||
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
||||||
}
|
}
|
||||||
|
} elseif (Str::startsWith($routeName, $this->getInquirySubPrefix())) {
|
||||||
|
$routes = $this->getInquirySubRoutes();
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
$this->addLink($route, $this->equalRoute($route['route']), (bool) ($route['blank'] ?? false), $route['hide_mobile'] ?? 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('admin::components.sidebar');
|
return view('admin::components.sidebar');
|
||||||
|
|
@ -157,6 +162,16 @@ class Sidebar extends Component
|
||||||
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取后台寻盘子页面路由前缀列表
|
||||||
|
*/
|
||||||
|
private function getInquirySubPrefix()
|
||||||
|
{
|
||||||
|
$prefix = ['inquiry.'];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.page.prefix', $prefix);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取后台系统设置子页面路由前缀列表
|
* 获取后台系统设置子页面路由前缀列表
|
||||||
*/
|
*/
|
||||||
|
|
@ -243,6 +258,19 @@ class Sidebar extends Component
|
||||||
return hook_filter('admin.sidebar.pages_routes', $routes);
|
return hook_filter('admin.sidebar.pages_routes', $routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取寻盘管理子页面路由
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getInquirySubRoutes()
|
||||||
|
{
|
||||||
|
$routes = [
|
||||||
|
['route' => 'inquiry.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return hook_filter('admin.sidebar.pages_routes', $routes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取系统设置子页面路由
|
* 获取系统设置子页面路由
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
|
|
||||||
|
|
@ -718,3 +718,53 @@ function perPage(): int
|
||||||
{
|
{
|
||||||
return (int) system_setting('base.product_per_page', 20);
|
return (int) system_setting('base.product_per_page', 20);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* php多维数组指定列排序
|
||||||
|
* @param $list
|
||||||
|
* @param $field
|
||||||
|
* @param $sortby
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function list_sort_by($list, $field, $sortby='asc') {
|
||||||
|
|
||||||
|
if(is_array($list)){ //判断是否数组
|
||||||
|
|
||||||
|
$refer = $resultSet = array(); //初始化数组变量
|
||||||
|
|
||||||
|
foreach ($list as $i => $data) //foreach数组
|
||||||
|
|
||||||
|
$refer[$i] = &$data[$field]; //存储要排序的数组字段键和值
|
||||||
|
|
||||||
|
switch ($sortby) {//进行排序
|
||||||
|
|
||||||
|
case 'asc': // 正向排序
|
||||||
|
|
||||||
|
asort($refer);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'desc':// 逆向排序
|
||||||
|
|
||||||
|
arsort($refer);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'nat': // 自然排序
|
||||||
|
|
||||||
|
natcasesort($refer);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $refer as $key=> $val)//重新组合排序后的数组
|
||||||
|
|
||||||
|
$resultSet[] = &$list[$key];
|
||||||
|
|
||||||
|
return $resultSet;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Inquiry extends Base
|
||||||
|
{
|
||||||
|
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['product_sku_id', 'contacts', 'email', 'content'];
|
||||||
|
|
||||||
|
public function productsku()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ProductSku::class, 'product_sku_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -11,14 +11,26 @@ class Product extends Base
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'active', 'variables'];
|
protected $fillable = ['images', 'video', 'position', 'brand_id', 'tax_class_id', 'active', 'variables', 'price_setting'];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'active' => 'boolean',
|
'active' => 'boolean',
|
||||||
'variables' => 'array',
|
'variables' => 'array',
|
||||||
'images' => 'array',
|
'images' => 'array',
|
||||||
|
'numPrices' => 'array',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function getNumPricesByNum($num)
|
||||||
|
{
|
||||||
|
$descNumPrices = array_reverse($this->numprices->toArray());
|
||||||
|
foreach($descNumPrices as $numprice){
|
||||||
|
if($num >= $numprice['num']){
|
||||||
|
return $numprice['price'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
protected $appends = ['image'];
|
protected $appends = ['image'];
|
||||||
|
|
||||||
public function categories()
|
public function categories()
|
||||||
|
|
@ -46,6 +58,11 @@ class Product extends Base
|
||||||
return $this->hasMany(ProductSku::class);
|
return $this->hasMany(ProductSku::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function numPrices()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ProductNumPrice::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function attributes(): HasMany
|
public function attributes(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(ProductAttribute::class);
|
return $this->hasMany(ProductAttribute::class);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
class ProductNumPrice extends Base
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['product_id', 'num', 'price'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $appends = [];
|
||||||
|
|
||||||
|
public function product()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Product::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,12 @@
|
||||||
namespace Beike\Models;
|
namespace Beike\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class ProductSku extends Base
|
class ProductSku extends Base
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = ['product_id', 'variants', 'position', 'images', 'model', 'sku', 'price', 'origin_price', 'cost_price', 'quantity', 'is_default'];
|
protected $fillable = ['product_id', 'variants', 'position', 'images', 'model', 'sku', 'price', 'origin_price', 'cost_price', 'quantity', 'is_default'];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AddressRepo.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-06-28 15:22:05
|
||||||
|
* @modified 2022-06-28 15:22:05
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Repositories;
|
||||||
|
|
||||||
|
use Beike\Models\Inquiry;
|
||||||
|
|
||||||
|
class InquiryRepo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 创建一个address记录
|
||||||
|
* @param $data
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function create($data)
|
||||||
|
{
|
||||||
|
return Inquiry::query()->create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $address
|
||||||
|
* @param $data
|
||||||
|
* @return mixed
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public static function update($address, $data)
|
||||||
|
{
|
||||||
|
if (! $address instanceof Inquiry) {
|
||||||
|
$address = Inquiry::query()->find($address);
|
||||||
|
}
|
||||||
|
if (! $address) {
|
||||||
|
throw new \Exception("地址id {$address} 不存在");
|
||||||
|
}
|
||||||
|
$address->update($data);
|
||||||
|
|
||||||
|
return $address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function find($id)
|
||||||
|
{
|
||||||
|
return Inquiry::query()->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function delete($id)
|
||||||
|
{
|
||||||
|
$address = Inquiry::query()->find($id);
|
||||||
|
if ($address) {
|
||||||
|
$address->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -200,10 +200,6 @@ class OrderRepo
|
||||||
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
|
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
|
||||||
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
|
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
|
||||||
|
|
||||||
$shippingAddress->country = $shippingAddress->country->name ?? '';
|
|
||||||
$shippingAddress->country_id = $shippingAddress->country->id ?? 0;
|
|
||||||
$paymentAddress->country = $paymentAddress->country->name ?? '';
|
|
||||||
$paymentAddress->country_id = $paymentAddress->country->id ?? 0;
|
|
||||||
$email = $customer->email;
|
$email = $customer->email;
|
||||||
} else {
|
} else {
|
||||||
$shippingAddress = new Address($current['guest_shipping_address'] ?? []);
|
$shippingAddress = new Address($current['guest_shipping_address'] ?? []);
|
||||||
|
|
@ -211,6 +207,11 @@ class OrderRepo
|
||||||
$email = $current['guest_shipping_address']['email'];
|
$email = $current['guest_shipping_address']['email'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$shippingAddress->country = $shippingAddress->country->name ?? '';
|
||||||
|
$shippingAddress->country_id = $shippingAddress->country->id ?? 0;
|
||||||
|
$paymentAddress->country = $paymentAddress->country->name ?? '';
|
||||||
|
$paymentAddress->country_id = $paymentAddress->country->id ?? 0;
|
||||||
|
|
||||||
$shippingMethodCode = $current['shipping_method_code'] ?? '';
|
$shippingMethodCode = $current['shipping_method_code'] ?? '';
|
||||||
$paymentMethodCode = $current['payment_method_code'] ?? '';
|
$paymentMethodCode = $current['payment_method_code'] ?? '';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,8 @@ class PageCategoryRepo
|
||||||
* @param $page
|
* @param $page
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getName($pageCategoryId)
|
public static function getName($page)
|
||||||
{
|
{
|
||||||
// 根据 pageCategoryId 获取 name,判断是否存在
|
return $page->description->title ?? '';
|
||||||
$pageCategory = PageCategory::query()->whereHas('description', function ($query) use ($pageCategoryId) {
|
|
||||||
$query->where('page_category_id', $pageCategoryId);
|
|
||||||
})->first();
|
|
||||||
|
|
||||||
return $pageCategory->description->title ?? '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class ProductRepo
|
||||||
if (is_int($product)) {
|
if (is_int($product)) {
|
||||||
$product = Product::query()->findOrFail($product);
|
$product = Product::query()->findOrFail($product);
|
||||||
}
|
}
|
||||||
$product->load('description', 'skus', 'masterSku', 'brand', 'relations');
|
$product->load('description', 'skus', 'masterSku', 'brand', 'relations', 'numPrices');//, 'price_setting', 'numPrices');
|
||||||
|
|
||||||
hook_filter('repo.product.get_detail', $product);
|
hook_filter('repo.product.get_detail', $product);
|
||||||
|
|
||||||
|
|
@ -94,7 +94,8 @@ class ProductRepo
|
||||||
});
|
});
|
||||||
$builder->leftJoin('product_skus', function ($build) {
|
$builder->leftJoin('product_skus', function ($build) {
|
||||||
$build->whereColumn('product_skus.product_id', 'products.id')
|
$build->whereColumn('product_skus.product_id', 'products.id')
|
||||||
->where('is_default', 1);
|
->where('is_default', 1)
|
||||||
|
->where('product_skus.deleted_at', null);
|
||||||
});
|
});
|
||||||
$builder->select(['products.*', 'pd.name', 'pd.content', 'pd.meta_title', 'pd.meta_description', 'pd.meta_keywords', 'pd.name', 'product_skus.price']);
|
$builder->select(['products.*', 'pd.name', 'pd.content', 'pd.meta_title', 'pd.meta_description', 'pd.meta_keywords', 'pd.name', 'product_skus.price']);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ class CartController extends Controller
|
||||||
*/
|
*/
|
||||||
public function update(CartRequest $request, $cartId): array
|
public function update(CartRequest $request, $cartId): array
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$customer = current_customer();
|
$customer = current_customer();
|
||||||
$quantity = (int) $request->get('quantity');
|
$quantity = (int) $request->get('quantity');
|
||||||
CartService::updateQuantity($customer, $cartId, $quantity);
|
CartService::updateQuantity($customer, $cartId, $quantity);
|
||||||
|
|
@ -94,6 +95,10 @@ class CartController extends Controller
|
||||||
$data = hook_filter('cart.update.data', $data);
|
$data = hook_filter('cart.update.data', $data);
|
||||||
|
|
||||||
return json_success(trans('common.updated_success'), $data);
|
return json_success(trans('common.updated_success'), $data);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Beike\Shop\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Shop\Http\Requests\InquiryRequest;
|
||||||
|
use Beike\Shop\Services\InquiryService;
|
||||||
|
|
||||||
|
class InquiryController extends Controller
|
||||||
|
{
|
||||||
|
public function store(InquiryRequest $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$requestData = $request->all();
|
||||||
|
|
||||||
|
$data = (new InquiryService)->create($requestData);
|
||||||
|
|
||||||
|
return hook_filter('inquiry.store.data', $data);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json_fail($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,10 +38,14 @@ class CartRequest extends FormRequest
|
||||||
return [
|
return [
|
||||||
'sku_id' => 'required|int',
|
'sku_id' => 'required|int',
|
||||||
'quantity' => ['required', 'int', function ($attribute, $value, $fail) use ($skuId) {
|
'quantity' => ['required', 'int', function ($attribute, $value, $fail) use ($skuId) {
|
||||||
$skuQuantity = ProductSku::query()->where('id', $skuId)->value('quantity');
|
$sku = ProductSku::query()->where('id', $skuId)->first();
|
||||||
|
$skuQuantity = $sku->quantity;
|
||||||
if ($value > $skuQuantity) {
|
if ($value > $skuQuantity) {
|
||||||
$fail(trans('cart.stock_out'));
|
$fail(trans('cart.stock_out'));
|
||||||
}
|
}
|
||||||
|
if($sku->product->price_setting == 'num' && $value < $sku->product->numprices[0]->num){
|
||||||
|
$fail(trans('shop/products.quantity_error'));
|
||||||
|
}
|
||||||
}],
|
}],
|
||||||
'buy_now' => 'bool',
|
'buy_now' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Beike\Shop\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class InquiryRequest extends FormRequest{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize(){
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(){
|
||||||
|
return [
|
||||||
|
'email' => 'required',
|
||||||
|
'contacts' => 'required',
|
||||||
|
'product_sku_id' => 'required|exists:product_skus,id',
|
||||||
|
'content' => 'required',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public function attributes(){
|
||||||
|
return [
|
||||||
|
'email' => trans('inquiry.email'),
|
||||||
|
'contacts' => trans('inquiry.contacts'),
|
||||||
|
'product_id' => trans('inquiry.product_id'),
|
||||||
|
'content' => trans('inquiry.content'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,11 @@ class CartDetail extends JsonResource
|
||||||
{
|
{
|
||||||
$sku = $this->sku;
|
$sku = $this->sku;
|
||||||
$product = $sku->product;
|
$product = $sku->product;
|
||||||
|
if($product->price_setting == 'num'){
|
||||||
|
$price = $product->getNumPricesByNum($this->product_quantity_sum);
|
||||||
|
}else{
|
||||||
$price = $sku->price;
|
$price = $sku->price;
|
||||||
|
};
|
||||||
$skuCode = $sku->sku;
|
$skuCode = $sku->sku;
|
||||||
$description = $product->description;
|
$description = $product->description;
|
||||||
$productName = $description->name;
|
$productName = $description->name;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PageDetail.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-08-11 18:45:02
|
||||||
|
* @modified 2022-08-11 18:45:02
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Shop\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class InquiryDetail extends JsonResource{
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
* @return array
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function toArray($request):array{
|
||||||
|
$productsku = $this->productsku;
|
||||||
|
if($this->productsku == NULL){
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'product_sku_id' => $this->product_sku_id,
|
||||||
|
'contacts' => $this->contacts,
|
||||||
|
'email' => $this->email,
|
||||||
|
'content' => $this->content,
|
||||||
|
'product_sku_sku' => '',
|
||||||
|
'product_name' => '',
|
||||||
|
'product_images' => [],
|
||||||
|
'product_id' => '',
|
||||||
|
'created_at' => time_format($this->created_at),
|
||||||
|
'updated_at' => time_format($this->updated_at),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$product = $productsku->product;
|
||||||
|
$description = $product->description;
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'product_sku_id' => $this->product_sku_id,
|
||||||
|
'contacts' => $this->contacts,
|
||||||
|
'email' => $this->email,
|
||||||
|
'content' => $this->content,
|
||||||
|
'product_sku_sku' => $productsku->sku,
|
||||||
|
'product_name' => $description->name ?? '',
|
||||||
|
'product_images' => array_map(function($image){
|
||||||
|
return [
|
||||||
|
'preview' => image_resize($image,500,500),
|
||||||
|
'popup' => image_resize($image,800,800),
|
||||||
|
'thumb' => image_resize($image,150,150),
|
||||||
|
];
|
||||||
|
},$product->images ?? []),
|
||||||
|
'product_id' => $productsku->product_id,
|
||||||
|
'created_at' => time_format($this->created_at),
|
||||||
|
'updated_at' => time_format($this->updated_at),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SkuDetail.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author TL <mengwb@guangda.work>
|
||||||
|
* @created 2022-07-20 11:33:06
|
||||||
|
* @modified 2022-07-20 11:33:06
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Shop\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class NumPricesDetail extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray($request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'num' => $this->num,
|
||||||
|
'price' => $this->price,
|
||||||
|
'price_format' => currency_format($this->price),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -52,6 +52,8 @@ class ProductDetail extends JsonResource
|
||||||
'skus' => SkuDetail::collection($this->skus)->jsonSerialize(),
|
'skus' => SkuDetail::collection($this->skus)->jsonSerialize(),
|
||||||
'in_wishlist' => $this->inCurrentWishlist->id ?? 0,
|
'in_wishlist' => $this->inCurrentWishlist->id ?? 0,
|
||||||
'active' => (bool) $this->active,
|
'active' => (bool) $this->active,
|
||||||
|
'price_setting' => $this->price_setting ?? '',
|
||||||
|
'numPrices' => NumPricesDetail::collection($this->numprices)->jsonSerialize() ?? '',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ class ProductSimple extends JsonResource
|
||||||
'origin_price_format' => currency_format($masterSku->origin_price),
|
'origin_price_format' => currency_format($masterSku->origin_price),
|
||||||
'category_id' => $this->category_id ?? null,
|
'category_id' => $this->category_id ?? null,
|
||||||
'in_wishlist' => $this->inCurrentWishlist->id ?? 0,
|
'in_wishlist' => $this->inCurrentWishlist->id ?? 0,
|
||||||
|
'price_setting' => $this->price_setting ?? '',
|
||||||
|
'numprices' => NumPricesDetail::collection($this->numprices)->jsonSerialize() ?? '',
|
||||||
|
|
||||||
'images' => array_map(function ($item) {
|
'images' => array_map(function ($item) {
|
||||||
return image_resize($item, 400, 400);
|
return image_resize($item, 400, 400);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ use Beike\Shop\Http\Controllers\CheckoutController;
|
||||||
use Beike\Shop\Http\Controllers\CurrencyController;
|
use Beike\Shop\Http\Controllers\CurrencyController;
|
||||||
use Beike\Shop\Http\Controllers\FileController;
|
use Beike\Shop\Http\Controllers\FileController;
|
||||||
use Beike\Shop\Http\Controllers\HomeController;
|
use Beike\Shop\Http\Controllers\HomeController;
|
||||||
|
use Beike\Shop\Http\Controllers\InquiryController;
|
||||||
use Beike\Shop\Http\Controllers\LanguageController;
|
use Beike\Shop\Http\Controllers\LanguageController;
|
||||||
use Beike\Shop\Http\Controllers\PageCategoryController;
|
use Beike\Shop\Http\Controllers\PageCategoryController;
|
||||||
use Beike\Shop\Http\Controllers\PageController;
|
use Beike\Shop\Http\Controllers\PageController;
|
||||||
|
|
@ -68,6 +69,8 @@ Route::prefix('/')
|
||||||
|
|
||||||
Route::get('plugin/{code}/{path}', [PluginController::class, 'asset'])->where('path', '(.*)')->name('plugin.asset');
|
Route::get('plugin/{code}/{path}', [PluginController::class, 'asset'])->where('path', '(.*)')->name('plugin.asset');
|
||||||
|
|
||||||
|
Route::post('inquiry', [InquiryController::class, 'store'])->name('brands.index');
|
||||||
|
|
||||||
Route::middleware('checkout_auth:' . Customer::AUTH_GUARD)
|
Route::middleware('checkout_auth:' . Customer::AUTH_GUARD)
|
||||||
->group(function () {
|
->group(function () {
|
||||||
Route::get('carts', [CartController::class, 'index'])->name('carts.index');
|
Route::get('carts', [CartController::class, 'index'])->name('carts.index');
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,16 @@ class CartService
|
||||||
return $description && $product;
|
return $description && $product;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$productQuantitySumList = [];
|
||||||
|
foreach($cartItems as $item) {
|
||||||
|
$productId = $item->product_id;
|
||||||
|
$productQuantitySumList[$productId] = $productQuantitySumList[$productId] ?? 0;
|
||||||
|
$productQuantitySumList[$productId] += $item->quantity;
|
||||||
|
}
|
||||||
|
foreach($cartItems as $item) {
|
||||||
|
$productId = $item->product_id;
|
||||||
|
$item->product_quantity_sum = $productQuantitySumList[$productId];
|
||||||
|
}
|
||||||
return CartDetail::collection($cartItems)->jsonSerialize();
|
return CartDetail::collection($cartItems)->jsonSerialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* CheckoutService.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-06-30 19:37:05
|
||||||
|
* @modified 2022-06-30 19:37:05
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Shop\Services;
|
||||||
|
|
||||||
|
use Beike\Repositories\InquiryRepo;
|
||||||
|
|
||||||
|
class InquiryService
|
||||||
|
{
|
||||||
|
public static function create($data)
|
||||||
|
{
|
||||||
|
$inquiry = InquiryRepo::create($data);
|
||||||
|
|
||||||
|
return $inquiry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -86,7 +86,12 @@
|
||||||
"config": {
|
"config": {
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
"preferred-install": "dist",
|
"preferred-install": "dist",
|
||||||
"sort-packages": true
|
"sort-packages": true,
|
||||||
|
"platform": {
|
||||||
|
"ext-pcntl": "7.2",
|
||||||
|
"ext-posix": "7.2"
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -20,5 +20,8 @@
|
||||||
"resolve-url-loader": "^4.0.0",
|
"resolve-url-loader": "^4.0.0",
|
||||||
"sass": "^1.38.1",
|
"sass": "^1.38.1",
|
||||||
"sass-loader": "^12.1.0"
|
"sass-loader": "^12.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"element-ui": "^2.15.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteBase /
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
|
||||||
|
</IfModule>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"/app.js": "/app.js?id=0f8def17167a0224d5704239fefc69ea",
|
||||||
|
"/app-dark.css": "/app-dark.css?id=23ca8adc130382f74688c6e36ce89407",
|
||||||
|
"/app.css": "/app.css?id=7357f6239c73ee903eba42be0458d3ab",
|
||||||
|
"/img/favicon.png": "/img/favicon.png?id=1542bfe8a0010dcbee710da13cce367f",
|
||||||
|
"/img/horizon.svg": "/img/horizon.svg?id=904d5b5185fefb09035384e15bfca765",
|
||||||
|
"/img/sprite.svg": "/img/sprite.svg?id=afc4952b74895bdef3ab4ebe9adb746f"
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="tab-content w-max-1000" id="myTabContent">
|
<div class="tab-content w-max-1000" id="myTabContent">
|
||||||
@foreach (locales() as $locale)
|
@foreach (locales() as $locale)
|
||||||
<div class="tab-pane fade {{ $loop->first ? 'show active' : ''}}" id="{{ $locale['code'] }}-pane" role="tabpanel" aria-labelledby="{{ $locale['code'] }}">
|
<div class="tab-pane fade {{ $loop->first ? 'show active' : ''}}" id="{{ $locale['code'] }}-pane" role="tabpanel" aria-labelledby="{{ $locale['code'] }}">
|
||||||
<textarea rows="4" type="text" name="{{ $name }}[{{ $locale['code'] }}]" class="tinymce" placeholder="{{ $title }}">{{ $value[$locale['code']] ?? '' }}</textarea>
|
<textarea rows="4" type="text" name="{{ $name }}[{{ $locale['code'] }}]" class="tinymce" placeholder="{{ $title }}">{{ $value[$locale['code']] }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
@hookwrapper('admin.header.vip')
|
@hookwrapper('admin.header.vip')
|
||||||
<li class="nav-item vip-serve">
|
<li class="nav-item vip-serve">
|
||||||
<a href="{{ config('beike.api_url') }}/vip/subscription?domain={{ config('app.url') }}&developer_token={{ system_setting('base.developer_token') }}" target="_blank" class="nav-link">
|
<a href="javascript:void(0)" class="nav-link">
|
||||||
<img src="/image/vip-icon.png" class="img-fluid">
|
<img src="/image/vip-icon.png" class="img-fluid">
|
||||||
<span class="vip-text ms-1">VIP</span>
|
<span class="vip-text ms-1">VIP</span>
|
||||||
<div class="expired-text text-danger ms-2" style="display: none">@lang('admin/common.expired_at'):<span class="ms-0"></span></div>
|
<div class="expired-text text-danger ms-2" style="display: none">@lang('admin/common.expired_at'):<span class="ms-0"></span></div>
|
||||||
|
|
@ -157,13 +157,13 @@
|
||||||
layer.close(updatePop)
|
layer.close(updatePop)
|
||||||
});
|
});
|
||||||
|
|
||||||
// $('.vip-serve').click(function(event) {
|
$('.vip-serve').click(function(event) {
|
||||||
// layer.open({
|
layer.open({
|
||||||
// type: 2,
|
type: 2,
|
||||||
// title: '',
|
title: '',
|
||||||
// area: ['840px', '80%'],
|
area: ['840px', '80%'],
|
||||||
// content: `${config.api_url}/api/vip_rights?domain=${config.app_url}&developer_token={{ system_setting('base.developer_token') }}`,
|
content: `${config.api_url}/api/vip_rights?domain=${config.app_url}&developer_token={{ system_setting('base.developer_token') }}`,
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
</script>
|
</script>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<link rel="shortcut icon" href="{{ image_origin(system_setting('base.favicon')) }}">
|
<link rel="shortcut icon" href="{{ image_origin(system_setting('base.favicon')) }}">
|
||||||
<link href="{{ mix('build/beike/admin/css/app.css') }}" rel="stylesheet">
|
<link href="{{ mix('build/beike/admin/css/app.css') }}" rel="stylesheet">
|
||||||
<script src="{{ mix('build/beike/admin/js/app.js') }}"></script>
|
<script src="{{ mix('build/beike/admin/js/app.js') }}"></script>
|
||||||
<title>BeikeShop - @yield('title')</title>
|
<title>万有引力 - @yield('title')</title>
|
||||||
@stack('header')
|
@stack('header')
|
||||||
{{-- <x-analytics /> --}}
|
{{-- <x-analytics /> --}}
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -43,7 +43,8 @@
|
||||||
@yield('content')
|
@yield('content')
|
||||||
|
|
||||||
<p class="text-center text-secondary mt-5">
|
<p class="text-center text-secondary mt-5">
|
||||||
<a href="https://beikeshop.com/" class="ms-2" target="_blank">BeikeShop</a>
|
{{-- <a href="https://beikeshop.com/" class="ms-2" target="_blank">BeikeShop</a>--}}
|
||||||
|
<a href="#" class="ms-2">万有引力</a>
|
||||||
v{{ config('beike.version') }}({{ config('beike.build') }})
|
v{{ config('beike.version') }}({{ config('beike.build') }})
|
||||||
© {{ date('Y') }} All Rights Reserved</p>
|
© {{ date('Y') }} All Rights Reserved</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@
|
||||||
cancelButtonText: '{{__('common.cancel')}}',
|
cancelButtonText: '{{__('common.cancel')}}',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
$http.delete(`attributes/{{ $attribute['id'] }}/values/${id}`).then((res) => {
|
$http.delete(`customers/{{ $attribute['id'] }}/addresses/${id}`).then((res) => {
|
||||||
this.$message.success(res.message);
|
this.$message.success(res.message);
|
||||||
this.source.attributeValues.splice(index, 1)
|
this.source.attributeValues.splice(index, 1)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=AW-11146062373"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'AW-11146062373'); </script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=AW-11146062373"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'AW-11146062373'); </script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
|
@ -20,9 +21,6 @@
|
||||||
<script src="{{ asset('vendor/tinymce/5.9.1/tinymce.min.js') }}"></script>
|
<script src="{{ asset('vendor/tinymce/5.9.1/tinymce.min.js') }}"></script>
|
||||||
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||||
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||||
@if (locale() != 'zh_cn')
|
|
||||||
<script src="{{ asset('vendor/element-ui/language/' . locale() . '.js') }}"></script>
|
|
||||||
@endif
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ asset('/build/beike/admin/css/design.css') }}">
|
<link rel="stylesheet" type="text/css" href="{{ asset('/build/beike/admin/css/design.css') }}">
|
||||||
@stack('header')
|
@stack('header')
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
@extends('admin::layouts.master')
|
||||||
|
|
||||||
|
@section('title', __('admin/page.index'))
|
||||||
|
|
||||||
|
@section('body-class', 'page-pages-form')
|
||||||
|
|
||||||
|
@push('header')
|
||||||
|
<script src="{{ asset('vendor/vue/Sortable.min.js') }}"></script>
|
||||||
|
<script src="{{ asset('vendor/vue/vuedraggable.js') }}"></script>
|
||||||
|
<script src="{{ asset('vendor/tinymce/5.9.1/tinymce.min.js') }}"></script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@section('page-title-right')
|
||||||
|
<x-admin::form.row title="">
|
||||||
|
<button type="button" class="mt-3 btn btn-primary submit-form">{{ __('common.save') }}</button>
|
||||||
|
</x-admin::form.row>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs nav-bordered mb-3" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab-content" type="button" >{{ __('admin/product.basic_information') }}</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab-data" type="button">{{ __('common.data') }}</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="app" class="card h-min-600">
|
||||||
|
<div class="card-body">
|
||||||
|
<form novalidate class="needs-validation" action="{{ $page->id ? admin_route('pages.update', [$page->id]) : admin_route('pages.store') }}" method="POST">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tab-content">
|
||||||
|
@csrf
|
||||||
|
@method($page->id ? 'PUT' : 'POST')
|
||||||
|
<ul class="nav nav-tabs mb-3" role="tablist">
|
||||||
|
@foreach (locales() as $language)
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link {{ $loop->first ? 'active' : '' }}" data-bs-toggle="tab" data-bs-target="#tab-{{ $language['code'] }}" type="button" >{{ $language['name'] }}</button>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
@foreach (locales() as $language)
|
||||||
|
<div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="tab-{{ $language['code'] }}">
|
||||||
|
@php
|
||||||
|
$error_title = $errors->first("descriptions.{$language['code']}.title");
|
||||||
|
@endphp
|
||||||
|
<x-admin-form-input
|
||||||
|
error="{{ $error_title }}"
|
||||||
|
name="descriptions[{{ $language['code'] }}][title]"
|
||||||
|
title="{{ __('admin/page.info_title') }}"
|
||||||
|
:required="true"
|
||||||
|
value="{{ old('descriptions.' . $language['code'] . '.title', $descriptions[$language['code']]['title'] ?? '') }}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<x-admin::form.row title="{{ __('page_category.text_summary') }}">
|
||||||
|
<div class="input-group w-max-400">
|
||||||
|
<textarea rows="3" type="text" name="descriptions[{{ $language['code'] }}][summary]" class="form-control wp-400" placeholder="{{ __('page_category.text_summary') }}">{{ old('descriptions.' . $language['code'] . '.summary', $descriptions[$language['code']]['summary'] ?? '') }}</textarea>
|
||||||
|
</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
|
||||||
|
<x-admin::form.row title="{{ __('admin/page.info_content') }}">
|
||||||
|
<div class="w-max-1000">
|
||||||
|
<textarea name="descriptions[{{ $language['code'] }}][content]" data-tinymce-height="600" class="form-control tinymce">
|
||||||
|
{{ old('descriptions.' . $language['code'] . '.content', $descriptions[$language['code']]['content'] ?? '') }}
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
@if ($errors->has("descriptions.{$language['code']}.content"))
|
||||||
|
<span class="invalid-feedback d-block" role="alert">{{ $errors->first("descriptions.{$language['code']}.content") }}</span>
|
||||||
|
@endif
|
||||||
|
</x-admin::form.row>
|
||||||
|
|
||||||
|
<input type="hidden" name="descriptions[{{ $language['code'] }}][locale]" value="{{ $language['code'] }}">
|
||||||
|
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_title]" title="{{ __('admin/setting.meta_title') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_title', $descriptions[$language['code']]['meta_title'] ?? '') }}" />
|
||||||
|
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_description]" title="{{ __('admin/setting.meta_description') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_description', $descriptions[$language['code']]['meta_description'] ?? '') }}" />
|
||||||
|
<x-admin-form-input name="descriptions[{{ $language['code'] }}][meta_keywords]" title="{{ __('admin/setting.meta_keywords') }}" value="{{ old('descriptions.' . $language['code'] . '.meta_keywords', $descriptions[$language['code']]['meta_keywords'] ?? '') }}" />
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="tab-data">
|
||||||
|
@hook('admin.page.data.before')
|
||||||
|
|
||||||
|
<x-admin-form-input name="author" title="{{ __('page_category.author') }}" value="{{ old('author', $page->author ?? '') }}" />
|
||||||
|
<x-admin::form.row title="{{ __('admin/page_category.index') }}">
|
||||||
|
<div class="wp-400">
|
||||||
|
<el-autocomplete
|
||||||
|
v-model="page_category_name"
|
||||||
|
value-key="name"
|
||||||
|
size="small"
|
||||||
|
name="category_name"
|
||||||
|
class="w-100"
|
||||||
|
:fetch-suggestions="(keyword, cb) => {relationsQuerySearch(keyword, cb, 'page_categories')}"
|
||||||
|
placeholder="{{ __('common.input') }}"
|
||||||
|
@select="(e) => {handleSelect(e, 'page_categories')}"
|
||||||
|
></el-autocomplete>
|
||||||
|
<input type="hidden" name="page_category_id" :value="page_category_name ? page_category_id : ''" />
|
||||||
|
</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
<x-admin-form-input name="views" title="{{ __('page_category.views') }}" value="{{ old('views', $page->views ?? '') }}" />
|
||||||
|
|
||||||
|
<x-admin::form.row title="{{ __('admin/product.product_relations') }}">
|
||||||
|
<div class="module-edit-group wp-600">
|
||||||
|
<div class="autocomplete-group-wrapper">
|
||||||
|
<el-autocomplete
|
||||||
|
class="inline-input"
|
||||||
|
v-model="relations.keyword"
|
||||||
|
value-key="name"
|
||||||
|
size="small"
|
||||||
|
:fetch-suggestions="(keyword, cb) => {relationsQuerySearch(keyword, cb, 'products')}"
|
||||||
|
placeholder="{{ __('admin/builder.modules_keywords_search') }}"
|
||||||
|
@select="(e) => {handleSelect(e, 'product_relations')}"
|
||||||
|
></el-autocomplete>
|
||||||
|
|
||||||
|
<div class="item-group-wrapper" v-loading="relations.loading">
|
||||||
|
<template v-if="relations.products.length">
|
||||||
|
<draggable
|
||||||
|
ghost-class="dragabble-ghost"
|
||||||
|
:list="relations.products"
|
||||||
|
:options="{animation: 330}"
|
||||||
|
>
|
||||||
|
<div v-for="(item, index) in relations.products" :key="index" class="item">
|
||||||
|
<div>
|
||||||
|
<i class="el-icon-s-unfold"></i>
|
||||||
|
<span>@{{ item.name }}</span>
|
||||||
|
</div>
|
||||||
|
<i class="el-icon-delete right" @click="relationsRemoveProduct(index)"></i>
|
||||||
|
<input type="text" :name="'products['+ index +']'" v-model="item.id" class="form-control d-none">
|
||||||
|
</div>
|
||||||
|
</draggable>
|
||||||
|
</template>
|
||||||
|
<template v-else>{{ __('admin/builder.modules_please_products') }}</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
|
||||||
|
@hook('admin.page.data.after')
|
||||||
|
|
||||||
|
<x-admin-form-switch name="active" title="{{ __('common.status') }}" value="{{ old('active', $page->active ?? 1) }}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="d-none">{{ __('common.save') }}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@hook('admin.page.form.footer')
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script>
|
||||||
|
$('.submit-form').click(function () {
|
||||||
|
$('.needs-validation').find('button[type="submit"]').click()
|
||||||
|
})
|
||||||
|
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
|
||||||
|
data: {
|
||||||
|
relations: {
|
||||||
|
keyword: '',
|
||||||
|
products: [],
|
||||||
|
loading: null,
|
||||||
|
},
|
||||||
|
page_category_name: '{{ old('category_name', $page->category->description->title ?? '') }}',
|
||||||
|
page_category_id: '{{ old('categories_id', $page->category->id ?? '') }}',
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
const products = @json($page['products'] ?? []);
|
||||||
|
|
||||||
|
if (products.length) {
|
||||||
|
this.relations.products = products.map(v => {
|
||||||
|
return {
|
||||||
|
id: v.id,
|
||||||
|
name: v.description.name,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
relationsQuerySearch(keyword, cb, url) {
|
||||||
|
$http.get(url + '/autocomplete?name=' + encodeURIComponent(keyword), null, {hload:true}).then((res) => {
|
||||||
|
cb(res.data);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSelect(item, key) {
|
||||||
|
if (key == 'product_relations') {
|
||||||
|
if (!this.relations.products.find(v => v == item.id)) {
|
||||||
|
this.relations.products.push(item);
|
||||||
|
}
|
||||||
|
this.relations.keyword = ""
|
||||||
|
} else {
|
||||||
|
this.page_category_name = item.name
|
||||||
|
this.page_category_id = item.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
relationsRemoveProduct(index) {
|
||||||
|
this.relations.products.splice(index, 1);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
@extends('admin::layouts.master')
|
||||||
|
|
||||||
|
@section('title', __('admin/page.inquiry'))
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
@if ($errors->has('error'))
|
||||||
|
<x-admin-alert type="danger" msg="{{ $errors->first('error') }}" class="mt-4" />
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div id="tax-classes-app" class="card">
|
||||||
|
<div class="card-body h-min-600">
|
||||||
|
{{-- <div class="d-flex justify-content-between mb-4">--}}
|
||||||
|
{{-- <a href="{{ admin_route('pages.create') }}" class="btn btn-primary">{{ __('common.add') }}</a>--}}
|
||||||
|
{{-- </div>--}}
|
||||||
|
<div class="table-push">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>{{ __('admin/product.products_img') }}</th>
|
||||||
|
<th>{{ __('admin/product.products_name') }}-{{ __('common.sku') }}</th>
|
||||||
|
<th>{{ __('common.contacts') }}</th>
|
||||||
|
<th>{{ __('common.email') }}</th>
|
||||||
|
<th>{{ __('common.content') }}</th>
|
||||||
|
<th>{{ __('common.created_at') }}</th>
|
||||||
|
<th>{{ __('common.updated_at') }}</th>
|
||||||
|
@hook('admin.page.list.column')
|
||||||
|
<th class="text-end">{{ __('common.action') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if (count($pages_format))
|
||||||
|
@foreach ($pages_format as $pageKey=>$page)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $page['id'] }}</td>
|
||||||
|
<td>
|
||||||
|
<div class="wh-60 border d-flex justify-content-between align-items-center"><img src="{{ $page['product_images'][0]['preview'] ?? 'image/placeholder.png' }}" class="img-fluid"></div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div ><a class="text-dark" href="{{ shop_route('products.show', $page['product_id']) }}" target="_blank">{{ $page['product_name'] ?? '' }}-{{ $page['product_sku_sku'] ?? '' }}</a></div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div title="">{{ $page['contacts'] ?? '' }}</div><!-- -->
|
||||||
|
</td>
|
||||||
|
{{-- <td class="{{ $page['active'] ? 'text-success' : 'text-secondary' }}">--}}
|
||||||
|
{{-- {{ $page['active'] ? __('common.enable') : __('common.disable') }}--}}
|
||||||
|
{{-- </td>--}}
|
||||||
|
<td>
|
||||||
|
<div title="">{{ $page['email'] ?? '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div title="">{{ $page['content'] ?? '' }}</div>
|
||||||
|
</td>
|
||||||
|
<td>{{ $page['created_at'] }}</td>
|
||||||
|
<td>{{ $page['updated_at'] }}</td>
|
||||||
|
@hook('admin.page.list.column_value')
|
||||||
|
<td class="text-end">
|
||||||
|
<button @click="checkedCreate('edit', {{$pageKey}})"
|
||||||
|
class="btn btn-outline-secondary btn-sm">{{ __('common.view') }}</button>
|
||||||
|
<button class="btn btn-outline-danger btn-sm delete-btn" type='button'
|
||||||
|
data-id="{{ $page['id'] }}">{{ __('common.delete') }}</button>
|
||||||
|
@hook('admin.page.list.action')
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr><td colspan="5" class="border-0"><x-admin-no-data /></td></tr>
|
||||||
|
@endif
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ $pages->links('admin::vendor/pagination/bootstrap-4') }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-dialog title="{{ __('admin/page.inquiry') }}" :visible.sync="dialog.show" width="870px"
|
||||||
|
@close="closeCustomersDialog('form')" :close-on-click-modal="false">
|
||||||
|
|
||||||
|
<el-descriptions class="margin-top" :column="2" :size="size" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-user"></i>
|
||||||
|
{{ __('admin/product.products_img') }}
|
||||||
|
</template>
|
||||||
|
<div class="wh-100 border d-flex justify-content-between align-items-center">
|
||||||
|
<img :src="dialog.form.product_images.length !== 0 ? dialog.form.product_images[0].preview : 'image/placeholder.png'" class="img-fluid">
|
||||||
|
</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-user"></i>
|
||||||
|
{{ __('admin/product.products_name') }}-{{ __('common.sku') }}
|
||||||
|
</template>
|
||||||
|
<a class="text-dark" :href="'/products/' + dialog.form.product_id" target="_blank">@{{ dialog.form.product_name }}-@{{ dialog.form.product_sku_sku}}</a>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
</el-descriptions>
|
||||||
|
<el-descriptions class="margin-top" :column="2" :size="size" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-tickets"></i>
|
||||||
|
{{ __('common.contacts') }}
|
||||||
|
</template>
|
||||||
|
@{{ dialog.form.contacts }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-mobile-phone"></i>
|
||||||
|
{{ __('common.email') }}
|
||||||
|
</template>
|
||||||
|
@{{ dialog.form.email }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
</el-descriptions>
|
||||||
|
<el-descriptions class="margin-top" :column="1" :size="size" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-tickets"></i>
|
||||||
|
{{ __('common.content') }}
|
||||||
|
</template>
|
||||||
|
@{{ dialog.form.content }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
</el-descriptions>
|
||||||
|
<el-descriptions class="margin-top" :column="2" :size="size" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-location-outline"></i>
|
||||||
|
{{ __('common.created_at') }}
|
||||||
|
</template>
|
||||||
|
@{{ dialog.form.created_at }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label">
|
||||||
|
<i class="el-icon-location-outline"></i>
|
||||||
|
{{ __('common.updated_at') }}
|
||||||
|
</template>
|
||||||
|
@{{ dialog.form.updated_at }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@hook('admin.page.list.content.footer')
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#tax-classes-app',
|
||||||
|
|
||||||
|
data: {
|
||||||
|
size: '',
|
||||||
|
currencies: @json($pages_format ?? []),
|
||||||
|
|
||||||
|
dialog: {
|
||||||
|
show: false,
|
||||||
|
index: null,
|
||||||
|
type: 'add',
|
||||||
|
form: {
|
||||||
|
product_images: [],
|
||||||
|
product_id: '',
|
||||||
|
product_name: '',
|
||||||
|
product_sku_sku: '',
|
||||||
|
contacts: '',
|
||||||
|
email: '',
|
||||||
|
content: '',
|
||||||
|
created_at: '',
|
||||||
|
updated_at: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
name: [{required: true,message: '{{ __('common.error_required', ['name' => __('common.name')]) }}', trigger: 'blur'}, ],
|
||||||
|
code: [{required: true,message: '{{ __('common.error_required', ['name' => __('currency.code')]) }}', trigger: 'blur'}, ],
|
||||||
|
value: [{required: true,message: '{{ __('common.error_required', ['name' => __('currency.value')]) }}',trigger: 'blur'}, ],
|
||||||
|
decimal_place: [{required: true,message: '{{ __('common.error_required', ['name' => __('currency.decimal_place')]) }}',trigger: 'blur'}, ],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
checkedCreate(type, index) {
|
||||||
|
this.dialog.show = true
|
||||||
|
this.dialog.type = type
|
||||||
|
this.dialog.index = index
|
||||||
|
|
||||||
|
if (type == 'edit') {
|
||||||
|
this.dialog.form = JSON.parse(JSON.stringify(this.currencies[index]))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addFormSubmit(form) {
|
||||||
|
const self = this;
|
||||||
|
const type = this.dialog.type == 'add' ? 'post' : 'put';
|
||||||
|
const url = this.dialog.type == 'add' ? 'currencies' : 'currencies/' + this.dialog.form.id;
|
||||||
|
|
||||||
|
this.$refs[form].validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
this.$message.error('{{ __('common.error_form') }}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$http[type](url, this.dialog.form).then((res) => {
|
||||||
|
this.$message.success(res.message);
|
||||||
|
if (this.dialog.type == 'add') {
|
||||||
|
this.currencies.push(res.data)
|
||||||
|
} else {
|
||||||
|
this.currencies[this.dialog.index] = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialog.show = false
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteCustomer(id, index) {
|
||||||
|
const self = this;
|
||||||
|
this.$confirm('{{ __('common.confirm_delete') }}', '{{ __('common.text_hint') }}', {
|
||||||
|
confirmButtonText: '{{ __('common.confirm') }}',
|
||||||
|
cancelButtonText: '{{ __('common.cancel') }}',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
$http.delete('currencies/' + id).then((res) => {
|
||||||
|
this.$message.success(res.message);
|
||||||
|
self.currencies.splice(index, 1)
|
||||||
|
})
|
||||||
|
}).catch(()=>{})
|
||||||
|
},
|
||||||
|
|
||||||
|
closeCustomersDialog(form) {
|
||||||
|
// this.$refs[form].resetFields();
|
||||||
|
Object.keys(this.dialog.form).forEach(key => this.dialog.form[key] = '')
|
||||||
|
// this.dialog.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.delete-btn').click(function(event) {
|
||||||
|
const id = $(this).data('id');
|
||||||
|
const self = $(this);
|
||||||
|
|
||||||
|
layer.confirm('{{ __('common.confirm_delete') }}', {
|
||||||
|
title: "{{ __('common.text_hint') }}",
|
||||||
|
btn: ['{{ __('common.cancel') }}', '{{ __('common.confirm') }}'],
|
||||||
|
area: ['400px'],
|
||||||
|
btn2: () => {
|
||||||
|
$http.delete(`inquiry/${id}`).then((res) => {
|
||||||
|
layer.msg(res.message);
|
||||||
|
window.location.reload();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
@ -43,7 +43,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
@if ($data['available'])
|
|
||||||
@if ($data['downloadable'])
|
@if ($data['downloadable'])
|
||||||
<button class="btn btn-primary btn-lg" @click="downloadPlugin"><i class="bi bi-cloud-arrow-down-fill"></i> {{ __('admin/marketing.download_plugin') }}</button>
|
<button class="btn btn-primary btn-lg" @click="downloadPlugin"><i class="bi bi-cloud-arrow-down-fill"></i> {{ __('admin/marketing.download_plugin') }}</button>
|
||||||
<div class="mt-3 d-none download-help"><a href="{{ admin_route('plugins.index') }}" class=""><i class="bi bi-cursor-fill"></i> <span></span></a></div>
|
<div class="mt-3 d-none download-help"><a href="{{ admin_route('plugins.index') }}" class=""><i class="bi bi-cursor-fill"></i> <span></span></a></div>
|
||||||
|
|
@ -57,11 +56,6 @@
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary btn-lg" @click="marketingBuy">{{ __('admin/marketing.btn_buy') }} ({{ $data['price_format'] }})</button>
|
<button class="btn btn-primary btn-lg" @click="marketingBuy">{{ __('admin/marketing.btn_buy') }} ({{ $data['price_format'] }})</button>
|
||||||
@endif
|
@endif
|
||||||
@else
|
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
{!! __('admin/marketing.version_compatible_text') !!}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -84,25 +84,11 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
installedPlugin(code, type, index) {
|
installedPlugin(code, type, index) {
|
||||||
if (type == 'uninstall') {
|
const self = this;
|
||||||
layer.confirm('{{ __('admin/plugin.uninstall_hint') }}', {
|
|
||||||
title: "{{ __('common.text_hint') }}",
|
|
||||||
btn: ['{{ __('common.cancel') }}', '{{ __('common.confirm') }}'],
|
|
||||||
area: ['400px'],
|
|
||||||
btn2: () => {
|
|
||||||
this.installedPluginXhr(code, type, index);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.installedPluginXhr(code, type, index);
|
|
||||||
},
|
|
||||||
|
|
||||||
installedPluginXhr(code, type, index) {
|
|
||||||
$http.post(`plugins/${code}/${type}`).then((res) => {
|
$http.post(`plugins/${code}/${type}`).then((res) => {
|
||||||
layer.msg(res.message)
|
layer.msg(res.message)
|
||||||
this.plugins[index].installed = type == 'install' ? true : false;
|
self.plugins[index].installed = type == 'install' ? true : false;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,89 @@
|
||||||
<div>
|
<div>
|
||||||
<h5 class="border-bottom pb-3 mb-4">{{ __('admin/product.stocks') }}</h5>
|
<h5 class="border-bottom pb-3 mb-4">{{ __('admin/product.stocks') }}</h5>
|
||||||
|
|
||||||
|
<x-admin::form.row title="{{ __('admin/product.price_setting_by.num') }}">
|
||||||
|
<div class="mb-1 mt-2">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input v-model="form.price_setting" class="form-check-input" id="price_setting-sku" type="radio" name="price_setting" id="price_setting-sku" value="sku" {{ $product->price_setting == 'sku' ? 'checked' : '' }}>
|
||||||
|
<label class="form-check-label" for="price_setting-sku">{{ __('common.disable') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input v-model="form.price_setting" class="form-check-input" id="price_setting-num" type="radio" name="price_setting" id="price_setting-num" value="num" {{ $product->price_setting == 'num' ? 'checked' : '' }}>
|
||||||
|
<label class="form-check-label" for="price_setting-num">{{ __('common.enable') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
|
||||||
|
<span v-if="form.price_setting === 'num'">
|
||||||
|
{{-- 阶梯价格设置表格 (最小起订量,产品价格),预览,可以增加删除价格区间--}}
|
||||||
|
<div class="price_setting_by_num">
|
||||||
|
<div class="left">
|
||||||
|
<div class="head">
|
||||||
|
<div class="num" >最小起订量</div>
|
||||||
|
<div class="price">产品价格</div>
|
||||||
|
<div class="delete">删除</div>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="item" v-for="(item,index) in form.numPrices">
|
||||||
|
<div class="num">
|
||||||
|
<div class="top">
|
||||||
|
<div class="title">≧</div>
|
||||||
|
<input type="number" :name="'numPrices[' + index + '][num]'" v-model="item.num" value="" placeholder="数量" required="required" class="form-control wp-100">
|
||||||
|
</div>
|
||||||
|
<div class="tip" ><span style="visibility: hidden;">_</span><span v-if="item.num">@{{ item.num }}件</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="price">
|
||||||
|
<input type="number" :name="'numPrices[' + index + '][price]'" v-model="item.price" value="" placeholder="价格" required="required" step="any" class="form-control wp-100">
|
||||||
|
<div class="tip" v-if="item.price">@{{ item.num }}件等于价格:@{{ item.num * item.price }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="delete" @click="removeNumPrices(index)"><a style="cursor: pointer;color: #0072ff;">删除</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<a style="cursor: pointer;color: #0072ff;" @click="addNumPrices"> {{ __('admin/product.add_variable') }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="head">
|
||||||
|
预览
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="item" v-for="(item,index) in form.numPrices">
|
||||||
|
<div class="num" v-if="index < form.numPrices.length - 1">@{{ item.num }} ~ @{{ form.numPrices[index + 1].num - 1 }}</div>
|
||||||
|
<div class="num" v-else-if="item.num">≧@{{ item.num }}</div>
|
||||||
|
<div class="price" v-if="item.price">价格@{{ item.price }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input class="form-control d-none" :value="numPricesIsEmpty" required>
|
||||||
|
<div class="invalid-feedback" style="font-size: 16px;margin-left: 200px;"><i class="bi bi-exclamation-circle-fill"></i> 新增价格区间</div>
|
||||||
|
<template>
|
||||||
|
{{-- <input type="hidden" value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}" name="skus[0][image]">--}}
|
||||||
|
{{-- <x-admin-form-input name="skus[0][model]" :title="__('admin/product.model')" :value="old('skus.0.model', $product->skus[0]->model ?? '')" />--}}
|
||||||
|
{{-- <x-admin-form-input name="skus[0][sku]" title="sku" :value="old('skus.0.sku', $product->skus[0]->sku ?? '')" required />--}}
|
||||||
|
{{-- <x-admin-form-input name="skus[0][price]" type="number" :title="__('admin/product.price')" :value="old('skus.0.price', $product->skus[0]->price ?? '')" step="any" required />--}}
|
||||||
|
{{-- --}}{{-- <x-admin-form-input name="skus[0][origin_price]" type="number" :title="__('admin/product.origin_price')" :value="old('skus.0.origin_price', $product->skus[0]->origin_price ?? '')" step="any" required />--}}
|
||||||
|
{{-- <x-admin-form-input name="skus[0][cost_price]" type="number" :title="__('admin/product.cost_price')" :value="old('skus.0.cost_price', $product->skus[0]->cost_price ?? '')" />--}}
|
||||||
|
{{-- <x-admin-form-input name="skus[0][quantity]" type="number" :title="__('admin/product.quantity')" :value="old('skus.0.quantity', $product->skus[0]->quantity ?? '')" />--}}
|
||||||
|
{{-- <input type="hidden" name="skus[0][price]" placeholder="variants" :value="form.numPrices.length !== 0 ? form.numPrices[0].price : ''">--}}
|
||||||
|
{{-- <input type="hidden" name="skus[0][origin_price]" placeholder="position" :value="form.numPrices.length !== 0 ? form.numPrices[form.numPrices.length - 1].price : ''">--}}
|
||||||
|
{{-- <input type="hidden" name="skus[0][variants]" placeholder="variants" value="">--}}
|
||||||
|
{{-- <input type="hidden" name="skus[0][position]" placeholder="position" value="0">--}}
|
||||||
|
{{-- <input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">--}}
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<input type="hidden" name="variables" :value="JSON.stringify(form.variables)">
|
||||||
|
|
||||||
|
<input type="hidden" name="numPrices" value="" v-if="form.price_setting === 'sku'">
|
||||||
|
|
||||||
|
|
||||||
<x-admin::form.row :title="__('admin/product.enable_multi_spec')">
|
<x-admin::form.row :title="__('admin/product.enable_multi_spec')">
|
||||||
<el-switch v-model="editing.isVariable" @change="isVariableChange" class="mt-2"></el-switch>
|
<el-switch v-model="editing.isVariable" @change="isVariableChange" class="mt-2"></el-switch>
|
||||||
</x-admin::form.row>
|
</x-admin::form.row>
|
||||||
|
|
||||||
<input type="hidden" name="variables" :value="JSON.stringify(form.variables)">
|
|
||||||
|
|
||||||
<div class="row g-3 mb-3" v-if="editing.isVariable">
|
<div class="row g-3 mb-3" v-if="editing.isVariable">
|
||||||
<label for="" class="wp-200 col-form-label text-end"></label>
|
<label for="" class="wp-200 col-form-label text-end"></label>
|
||||||
<div class="col-auto wp-200-">
|
<div class="col-auto wp-200-">
|
||||||
|
|
@ -190,8 +267,8 @@
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.model" placeholder="{{ __('admin/product.model') }}">
|
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.model" placeholder="{{ __('admin/product.model') }}">
|
||||||
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.sku" placeholder="sku">
|
<input type="text" class="form-control me-2 bg-white" v-model="variablesBatch.sku" placeholder="sku">
|
||||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.price" placeholder="{{ __('admin/product.price') }}">
|
<input type="number" v-if="form.price_setting === 'sku'" class="form-control me-2 bg-white" v-model="variablesBatch.price" placeholder="{{ __('admin/product.price') }}">
|
||||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.origin_price" placeholder="{{ __('admin/product.origin_price') }}">
|
<input type="number" v-if="form.price_setting === 'sku'" class="form-control me-2 bg-white" v-model="variablesBatch.origin_price" placeholder="{{ __('admin/product.origin_price') }}">
|
||||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.cost_price" placeholder="{{ __('admin/product.cost_price') }}">
|
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.cost_price" placeholder="{{ __('admin/product.cost_price') }}">
|
||||||
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.quantity" placeholder="{{ __('admin/product.quantity') }}">
|
<input type="number" class="form-control me-2 bg-white" v-model="variablesBatch.quantity" placeholder="{{ __('admin/product.quantity') }}">
|
||||||
<button type="button" class="btn btn-primary text-nowrap" @click="batchSettingVariant">{{ __('common.batch_setting') }}</button>
|
<button type="button" class="btn btn-primary text-nowrap" @click="batchSettingVariant">{{ __('common.batch_setting') }}</button>
|
||||||
|
|
@ -205,8 +282,8 @@
|
||||||
<th width="106px">{{ __('common.image') }}</th>
|
<th width="106px">{{ __('common.image') }}</th>
|
||||||
<th class="w-min-100">{{ __('admin/product.model') }}</th>
|
<th class="w-min-100">{{ __('admin/product.model') }}</th>
|
||||||
<th class="w-min-100">sku</th>
|
<th class="w-min-100">sku</th>
|
||||||
<th class="w-min-100">{{ __('admin/product.price') }}</th>
|
<th v-if="form.price_setting === 'sku'" class="w-min-100">{{ __('admin/product.price') }}</th>
|
||||||
<th class="w-min-100">{{ __('admin/product.origin_price') }}</th>
|
<th v-if="form.price_setting === 'sku'" class="w-min-100">{{ __('admin/product.origin_price') }}</th>
|
||||||
<th class="w-min-100">{{ __('admin/product.cost_price') }}</th>
|
<th class="w-min-100">{{ __('admin/product.cost_price') }}</th>
|
||||||
<th class="w-min-100">{{ __('admin/product.quantity') }}</th>
|
<th class="w-min-100">{{ __('admin/product.quantity') }}</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -241,15 +318,19 @@
|
||||||
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => 'sku']) }}</span>
|
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => 'sku']) }}</span>
|
||||||
<span v-if="sku.is_default" class="text-success">{{ __('admin/product.default_main_product') }}</span>
|
<span v-if="sku.is_default" class="text-success">{{ __('admin/product.default_main_product') }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td v-if="form.price_setting === 'sku'">
|
||||||
<input type="number" class="form-control" v-model="sku.price" :name="'skus[' + skuIndex + '][price]'" step="any"
|
<input type="number" class="form-control" v-model="sku.price" :name="'skus[' + skuIndex + '][price]'" step="any"
|
||||||
placeholder="{{ __('admin/product.price') }}" required>
|
placeholder="{{ __('admin/product.price') }}" required>
|
||||||
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => __('admin/product.price')]) }}</span>
|
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => __('admin/product.price')]) }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td><input type="number" class="form-control" v-model="sku.origin_price" :name="'skus[' + skuIndex + '][origin_price]'" step="any"
|
<td v-if="form.price_setting === 'sku'">
|
||||||
|
<input type="number" class="form-control" v-model="sku.origin_price" :name="'skus[' + skuIndex + '][origin_price]'" step="any"
|
||||||
placeholder="{{ __('admin/product.origin_price') }}" required>
|
placeholder="{{ __('admin/product.origin_price') }}" required>
|
||||||
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => __('admin/product.origin_price')]) }}</span>
|
<span role="alert" class="invalid-feedback">{{ __('common.error_required', ['name' => __('admin/product.origin_price')]) }}</span>
|
||||||
</td>
|
</td>
|
||||||
|
<input type="hidden" :name="'skus[' + skuIndex + '][price]'" v-if="form.price_setting === 'num'" placeholder="variants" :value="form.numPrices.length !== 0 ? form.numPrices[0].price : ''">
|
||||||
|
<input type="hidden" :name="'skus[' + skuIndex + '][origin_price]'" v-if="form.price_setting === 'num'" placeholder="position" :value="form.numPrices.length !== 0 ? form.numPrices[form.numPrices.length - 1].price : ''">
|
||||||
|
|
||||||
<td><input type="number" class="form-control" v-model="sku.cost_price" :name="'skus[' + skuIndex + '][cost_price]'"
|
<td><input type="number" class="form-control" v-model="sku.cost_price" :name="'skus[' + skuIndex + '][cost_price]'"
|
||||||
placeholder="{{ __('admin/product.cost_price') }}">
|
placeholder="{{ __('admin/product.cost_price') }}">
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -269,10 +350,14 @@
|
||||||
<input type="hidden" value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}" name="skus[0][image]">
|
<input type="hidden" value="{{ old('skus.0.image', $product->skus[0]->image ?? '') }}" name="skus[0][image]">
|
||||||
<x-admin-form-input name="skus[0][model]" :title="__('admin/product.model')" :value="old('skus.0.model', $product->skus[0]->model ?? '')" />
|
<x-admin-form-input name="skus[0][model]" :title="__('admin/product.model')" :value="old('skus.0.model', $product->skus[0]->model ?? '')" />
|
||||||
<x-admin-form-input name="skus[0][sku]" title="sku" :value="old('skus.0.sku', $product->skus[0]->sku ?? '')" required />
|
<x-admin-form-input name="skus[0][sku]" title="sku" :value="old('skus.0.sku', $product->skus[0]->sku ?? '')" required />
|
||||||
|
<span v-if="form.price_setting === 'sku'">
|
||||||
<x-admin-form-input name="skus[0][price]" type="number" :title="__('admin/product.price')" :value="old('skus.0.price', $product->skus[0]->price ?? '')" step="any" required />
|
<x-admin-form-input name="skus[0][price]" type="number" :title="__('admin/product.price')" :value="old('skus.0.price', $product->skus[0]->price ?? '')" step="any" required />
|
||||||
<x-admin-form-input name="skus[0][origin_price]" type="number" :title="__('admin/product.origin_price')" :value="old('skus.0.origin_price', $product->skus[0]->origin_price ?? '')" step="any" required />
|
<x-admin-form-input name="skus[0][origin_price]" type="number" :title="__('admin/product.origin_price')" :value="old('skus.0.origin_price', $product->skus[0]->origin_price ?? '')" step="any" required />
|
||||||
|
</span>
|
||||||
<x-admin-form-input name="skus[0][cost_price]" type="number" :title="__('admin/product.cost_price')" :value="old('skus.0.cost_price', $product->skus[0]->cost_price ?? '')" />
|
<x-admin-form-input name="skus[0][cost_price]" type="number" :title="__('admin/product.cost_price')" :value="old('skus.0.cost_price', $product->skus[0]->cost_price ?? '')" />
|
||||||
<x-admin-form-input name="skus[0][quantity]" type="number" :title="__('admin/product.quantity')" :value="old('skus.0.quantity', $product->skus[0]->quantity ?? '')" />
|
<x-admin-form-input name="skus[0][quantity]" type="number" :title="__('admin/product.quantity')" :value="old('skus.0.quantity', $product->skus[0]->quantity ?? '')" />
|
||||||
|
<input type="hidden" name="skus[0][price]" v-if="form.price_setting === 'num'" placeholder="variants" :value="form.numPrices.length !== 0 ? form.numPrices[0].price : ''">
|
||||||
|
<input type="hidden" name="skus[0][origin_price]" v-if="form.price_setting === 'num'" placeholder="position" :value="form.numPrices.length !== 0 ? form.numPrices[form.numPrices.length - 1].price : ''">
|
||||||
<input type="hidden" name="skus[0][variants]" placeholder="variants" value="">
|
<input type="hidden" name="skus[0][variants]" placeholder="variants" value="">
|
||||||
<input type="hidden" name="skus[0][position]" placeholder="position" value="0">
|
<input type="hidden" name="skus[0][position]" placeholder="position" value="0">
|
||||||
<input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">
|
<input type="hidden" name="skus[0][is_default]" placeholder="is_default" value="1">
|
||||||
|
|
@ -490,6 +575,8 @@
|
||||||
status: @json($product->skus[0]['status'] ?? false),
|
status: @json($product->skus[0]['status'] ?? false),
|
||||||
variables: @json($product->variables ?? []),
|
variables: @json($product->variables ?? []),
|
||||||
skus: @json(old('skus', $product->skus) ?? []),
|
skus: @json(old('skus', $product->skus) ?? []),
|
||||||
|
price_setting: @json(old('price_setting', $product->price_setting) ?? 'sku'),
|
||||||
|
numPrices: @json(old('numPrices', $product->numprices) ?? []),
|
||||||
},
|
},
|
||||||
|
|
||||||
variablesBatch: {
|
variablesBatch: {
|
||||||
|
|
@ -555,6 +642,10 @@
|
||||||
|
|
||||||
skuIsEmpty() {
|
skuIsEmpty() {
|
||||||
return (this.form.skus.length && this.form.skus[0].variants.length) || ''
|
return (this.form.skus.length && this.form.skus[0].variants.length) || ''
|
||||||
|
},
|
||||||
|
|
||||||
|
numPricesIsEmpty() {
|
||||||
|
return (this.form.numPrices.length && this.form.price_setting === 'num') || this.form.price_setting === 'sku' || ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -589,7 +680,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if(this.form.numPrices.length === 0){
|
||||||
|
this.addNumPrices();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
addNumPrices() {
|
||||||
|
this.form.numPrices.push({num: '', price: ''});
|
||||||
|
},
|
||||||
|
|
||||||
|
removeNumPrices(index) {
|
||||||
|
this.form.numPrices.splice(index, 1)
|
||||||
|
},
|
||||||
|
|
||||||
// 表单提交,检测是否开启多规格 做处理
|
// 表单提交,检测是否开启多规格 做处理
|
||||||
productsSubmit() {
|
productsSubmit() {
|
||||||
if (!this.editing.isVariable) {
|
if (!this.editing.isVariable) {
|
||||||
|
|
@ -948,5 +1053,104 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script lang="scss">
|
||||||
|
<style>
|
||||||
|
.price_setting_by_num{
|
||||||
|
display: flex;
|
||||||
|
margin-left: 200px;
|
||||||
|
border: 1px solid #aaaaaa;
|
||||||
|
border-radius: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.left{
|
||||||
|
flex: 4;
|
||||||
|
border-right: 1px solid #aaaaaa;
|
||||||
|
.head{
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #aaaaaa;
|
||||||
|
padding: 8px 0px 8px 30px;
|
||||||
|
.num{
|
||||||
|
flex: 4;
|
||||||
|
}
|
||||||
|
.price{
|
||||||
|
flex: 4;
|
||||||
|
}
|
||||||
|
.delete{
|
||||||
|
visibility: hidden;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.body{
|
||||||
|
.item {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #aaaaaa;
|
||||||
|
padding: 20px 0px 20px 30px;
|
||||||
|
.num {
|
||||||
|
flex: 4;
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
line-height: 33px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaaaaa;
|
||||||
|
margin: 10px 0 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.price {
|
||||||
|
flex: 4;
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaaaaa;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.delete {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
|
||||||
|
padding: 8px 0px 8px 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right{
|
||||||
|
flex: 1;
|
||||||
|
.head{
|
||||||
|
|
||||||
|
border-bottom: 1px solid #aaaaaa;
|
||||||
|
padding: 8px 0px 8px 10px;
|
||||||
|
}
|
||||||
|
.body{
|
||||||
|
.item{
|
||||||
|
padding: 8px 0px 8px 10px;
|
||||||
|
display: flex;
|
||||||
|
.num{
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.price{
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endpush
|
@endpush
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,9 @@
|
||||||
justify-content: center; // flex-end | center | space-between
|
justify-content: center; // flex-end | center | space-between
|
||||||
box-shadow: 0 6px 18px rgba(0, 0, 0, .07);
|
box-shadow: 0 6px 18px rgba(0, 0, 0, .07);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
height: 120px;
|
height: 90px;
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
>img {
|
||||||
box-shadow: 0 6px 18px rgba(0, 0, 0, .1);
|
|
||||||
border: 1px solid $primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
> img {
|
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
.price-old {
|
.price-old {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
text-decoration: line-through;
|
text-decoration:line-through;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,10 @@ $(function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
function updateMiniCartData(res) {
|
function updateMiniCartData(res) {
|
||||||
|
let cart_item_price = $('.offcanvas-right-cart-item-price');
|
||||||
|
for(var i = 0 ; i< cart_item_price.length ;i++){
|
||||||
|
cart_item_price.contents()[i * 3].nodeValue =' ' + res.data.carts[i].price_format + ' x ';
|
||||||
|
}
|
||||||
$('.offcanvas-right-cart-count').text(res.data.quantity);
|
$('.offcanvas-right-cart-count').text(res.data.quantity);
|
||||||
$('.offcanvas-right-cart-amount').text(res.data.amount_format);
|
$('.offcanvas-right-cart-amount').text(res.data.amount_format);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ return [
|
||||||
'customer_group' => 'Customer Groups',
|
'customer_group' => 'Customer Groups',
|
||||||
'customer' => 'Customers',
|
'customer' => 'Customers',
|
||||||
'page' => 'Content',
|
'page' => 'Content',
|
||||||
|
|
||||||
|
'inquiry' => 'Inquiry',
|
||||||
'page_category' => 'Page Category',
|
'page_category' => 'Page Category',
|
||||||
'setting' => 'Settings',
|
'setting' => 'Settings',
|
||||||
'plugin' => 'Plugin',
|
'plugin' => 'Plugin',
|
||||||
|
|
@ -61,6 +63,8 @@ return [
|
||||||
'regions_index' => 'Regions',
|
'regions_index' => 'Regions',
|
||||||
'tax_rates_index' => 'Tax Rates',
|
'tax_rates_index' => 'Tax Rates',
|
||||||
'pages_index' => 'Articles',
|
'pages_index' => 'Articles',
|
||||||
|
|
||||||
|
'inquiry_index' => 'Inquiry',
|
||||||
'page_categories_index' => 'Catalogs',
|
'page_categories_index' => 'Catalogs',
|
||||||
'tax_classes_index' => 'Tax Classes',
|
'tax_classes_index' => 'Tax Classes',
|
||||||
'currencies_index' => 'Currencies',
|
'currencies_index' => 'Currencies',
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,4 @@ return [
|
||||||
'pay_success_text' => 'The plug-in purchase is successful, click OK to refresh the page',
|
'pay_success_text' => 'The plug-in purchase is successful, click OK to refresh the page',
|
||||||
'ali_pay_success' => 'Payment completed? ',
|
'ali_pay_success' => 'Payment completed? ',
|
||||||
'ali_pay_text' => 'Payment has been completed, please refresh the page',
|
'ali_pay_text' => 'Payment has been completed, please refresh the page',
|
||||||
'version_compatible_text' => 'This plugin is not compatible with the current system version, please upgrade to <a href="' . config('beike.api_url') . '/download" target="_blank">Latest Version</a>',
|
|
||||||
'to_update' => 'To Upgrade',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,5 @@ return [
|
||||||
'pages_show' => 'Detail',
|
'pages_show' => 'Detail',
|
||||||
'pages_update' => 'Edit',
|
'pages_update' => 'Edit',
|
||||||
'pages_delete' => 'Delete',
|
'pages_delete' => 'Delete',
|
||||||
|
'inquiry' => 'Inquiry',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'Install',
|
'plugins_install' => 'Install',
|
||||||
'plugins_uninstall' => 'Uninstall',
|
'plugins_uninstall' => 'Uninstall',
|
||||||
'to_enable' => 'To Enable',
|
'to_enable' => 'To Enable',
|
||||||
'uninstall_hint' => 'Uninstalling the plug-in will delete all related data of the plug-in, are you sure you want to uninstall? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'Plugin List',
|
'plugin_list' => 'Plugin List',
|
||||||
'plugin_code' => 'Code',
|
'plugin_code' => 'Code',
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'products_index' => 'Index',
|
'products_index' => 'Index',
|
||||||
|
'products_name' => 'Products Name',
|
||||||
|
'products_img' => 'Products Image',
|
||||||
'products_create' => 'Create',
|
'products_create' => 'Create',
|
||||||
'products_show' => 'Detail',
|
'products_show' => 'Detail',
|
||||||
'products_update' => 'Edit',
|
'products_update' => 'Edit',
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@ return [
|
||||||
'error_page' => 'The data you accessed does not exist or has been deleted~',
|
'error_page' => 'The data you accessed does not exist or has been deleted~',
|
||||||
'error_page_btn' => 'Return to previous page',
|
'error_page_btn' => 'Return to previous page',
|
||||||
|
|
||||||
|
'contacts' => 'Contacts',
|
||||||
|
'content' => 'Content',
|
||||||
|
'sku' => 'Sku',
|
||||||
|
|
||||||
'order' => [
|
'order' => [
|
||||||
'unpaid' => 'Unpaid',
|
'unpaid' => 'Unpaid',
|
||||||
'paid' => 'Paid',
|
'paid' => 'Paid',
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,9 @@ return [
|
||||||
'in_stock' => 'In Stock',
|
'in_stock' => 'In Stock',
|
||||||
'out_stock' => 'Out Stock',
|
'out_stock' => 'Out Stock',
|
||||||
'model' => 'Model',
|
'model' => 'Model',
|
||||||
|
'quantity_error' => 'Quantity Error',
|
||||||
|
'inquiry' => 'Inquiry',
|
||||||
|
'enter_contacts' => 'Please enter contacts',
|
||||||
|
'enter_email' => 'Please enter email',
|
||||||
|
'enter_content' => 'Please enter content',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'Instalar',
|
'plugins_install' => 'Instalar',
|
||||||
'plugins_uninstall' => 'desinstalar',
|
'plugins_uninstall' => 'desinstalar',
|
||||||
'to_enable' => 'To Enable',
|
'to_enable' => 'To Enable',
|
||||||
'uninstall_hint' => 'Desinstalar el complemento eliminará todos los datos relacionados con el complemento, ¿está seguro de que desea desinstalarlo? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'Lista de complementos',
|
'plugin_list' => 'Lista de complementos',
|
||||||
'plugin_code' => 'código de complemento',
|
'plugin_code' => 'código de complemento',
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'installer',
|
'plugins_install' => 'installer',
|
||||||
'plugins_uninstall' => 'désinstaller',
|
'plugins_uninstall' => 'désinstaller',
|
||||||
'to_enable' => 'To Enable',
|
'to_enable' => 'To Enable',
|
||||||
'uninstall_hint' => 'La désinstallation du plug-in supprimera toutes les données associées au plug-in, êtes-vous sûr de vouloir désinstaller ? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'liste des plugins',
|
'plugin_list' => 'liste des plugins',
|
||||||
'plugin_code' => 'code du plugin',
|
'plugin_code' => 'code du plugin',
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'installa',
|
'plugins_install' => 'installa',
|
||||||
'plugins_uninstall' => 'disinstalla',
|
'plugins_uninstall' => 'disinstalla',
|
||||||
'to_enable' => 'To Enable',
|
'to_enable' => 'To Enable',
|
||||||
'uninstall_hint' => 'La disinstallazione del plug-in eliminerà tutti i relativi dati del plug-in, sei sicuro di voler disinstallare? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'elenco dei plugin',
|
'plugin_list' => 'elenco dei plugin',
|
||||||
'plugin_code' => 'codice plugin',
|
'plugin_code' => 'codice plugin',
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'インストール',
|
'plugins_install' => 'インストール',
|
||||||
'plugins_uninstall' => 'アンインストール',
|
'plugins_uninstall' => 'アンインストール',
|
||||||
'to_enable' => '有効にする',
|
'to_enable' => '有効にする',
|
||||||
'uninstall_hint' => 'プラグインをアンインストールすると、プラグインに関連するすべてのデータが削除されます。本当にアンインストールしますか? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'プラグイン リスト',
|
'plugin_list' => 'プラグイン リスト',
|
||||||
'plugin_code' => 'プラグインコード',
|
'plugin_code' => 'プラグインコード',
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => 'Установить',
|
'plugins_install' => 'Установить',
|
||||||
'plugins_uninstall' => 'удалить',
|
'plugins_uninstall' => 'удалить',
|
||||||
'to_enable' => 'включить',
|
'to_enable' => 'включить',
|
||||||
'uninstall_hint' => 'Удаление плагина приведет к удалению всех связанных с ним данных. Вы уверены, что хотите удалить? ',
|
|
||||||
|
|
||||||
'plugin_list' => 'Список плагинов',
|
'plugin_list' => 'Список плагинов',
|
||||||
'plugin_code' => 'код плагина',
|
'plugin_code' => 'код плагина',
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ return [
|
||||||
'customer_group' => '客户组管理',
|
'customer_group' => '客户组管理',
|
||||||
'customer' => '客户管理',
|
'customer' => '客户管理',
|
||||||
'page' => '文章管理',
|
'page' => '文章管理',
|
||||||
|
'inquiry' => '询盘管理',
|
||||||
'page_category' => '文章分类',
|
'page_category' => '文章分类',
|
||||||
'setting' => '系统设置',
|
'setting' => '系统设置',
|
||||||
'plugin' => '插件管理',
|
'plugin' => '插件管理',
|
||||||
|
|
@ -65,6 +66,7 @@ return [
|
||||||
'languages_index' => '语言管理',
|
'languages_index' => '语言管理',
|
||||||
'design_index' => '首页装修',
|
'design_index' => '首页装修',
|
||||||
'pages_index' => '文章管理',
|
'pages_index' => '文章管理',
|
||||||
|
'inquiry_index' => '询盘管理',
|
||||||
'page_categories_index' => '文章分类',
|
'page_categories_index' => '文章分类',
|
||||||
'design_footer_index' => '页尾装修',
|
'design_footer_index' => '页尾装修',
|
||||||
'design_menu_index' => '导航配置',
|
'design_menu_index' => '导航配置',
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'plugins_index' => '登录到 BeikeShop 后台',
|
'plugins_index' => '登录到 万有引力 后台',
|
||||||
'log_in' => '登录',
|
'log_in' => '登录',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,4 @@ return [
|
||||||
'pay_success_text' => '插件购买成功,点击确定刷新页面',
|
'pay_success_text' => '插件购买成功,点击确定刷新页面',
|
||||||
'ali_pay_success' => '已完成支付?',
|
'ali_pay_success' => '已完成支付?',
|
||||||
'ali_pay_text' => '已完成支付,请刷新页面',
|
'ali_pay_text' => '已完成支付,请刷新页面',
|
||||||
'ali_pay_text' => '已完成支付,请刷新页面',
|
|
||||||
'version_compatible_text' => '该插件不兼容当前系统版本,请升级到 <a href="' . config('beike.api_url') . '/download" target="_blank">最新版本</a>',
|
|
||||||
'to_update' => '去升级',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,6 @@ return [
|
||||||
'pages_show' => '文章详情',
|
'pages_show' => '文章详情',
|
||||||
'pages_update' => '文章编辑',
|
'pages_update' => '文章编辑',
|
||||||
'pages_delete' => '删除文章',
|
'pages_delete' => '删除文章',
|
||||||
|
|
||||||
|
'inquiry' => '询盘管理',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => '安装',
|
'plugins_install' => '安装',
|
||||||
'plugins_uninstall' => '卸载',
|
'plugins_uninstall' => '卸载',
|
||||||
'to_enable' => '去启用',
|
'to_enable' => '去启用',
|
||||||
'uninstall_hint' => '卸载插件会删除该插件的所有相关数据,确定要卸载吗?',
|
|
||||||
|
|
||||||
'plugin_list' => '插件设置',
|
'plugin_list' => '插件设置',
|
||||||
'plugin_code' => '插件代码',
|
'plugin_code' => '插件代码',
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'products_index' => '商品列表',
|
'products_index' => '商品列表',
|
||||||
|
'products_name' => '商品名称',
|
||||||
|
'products_img' => '商品图片',
|
||||||
'products_create' => '创建商品',
|
'products_create' => '创建商品',
|
||||||
'products_show' => '商品详情',
|
'products_show' => '商品详情',
|
||||||
'products_update' => '更新商品',
|
'products_update' => '更新商品',
|
||||||
|
|
@ -31,7 +33,7 @@ return [
|
||||||
'price' => '价格',
|
'price' => '价格',
|
||||||
'origin_price' => '原价',
|
'origin_price' => '原价',
|
||||||
'cost_price' => '成本价',
|
'cost_price' => '成本价',
|
||||||
'quantity' => '数量',
|
'quantity' => '库存数量',
|
||||||
'enable_multi_spec' => '启用多规格',
|
'enable_multi_spec' => '启用多规格',
|
||||||
'image_help' => '第一张图片将作为商品主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
'image_help' => '第一张图片将作为商品主图,支持同时上传多张图片,多张图片之间可随意调整位置',
|
||||||
'add_variable' => '添加规格',
|
'add_variable' => '添加规格',
|
||||||
|
|
@ -44,4 +46,9 @@ return [
|
||||||
'confirm_batch_status' => '确认要批量修改选中的商品的状态吗?',
|
'confirm_batch_status' => '确认要批量修改选中的商品的状态吗?',
|
||||||
'confirm_batch_restore' => '确认要恢复选中的商品吗?',
|
'confirm_batch_restore' => '确认要恢复选中的商品吗?',
|
||||||
'confirm_delete_restore' => '确认要清空回收站吗?',
|
'confirm_delete_restore' => '确认要清空回收站吗?',
|
||||||
|
'price_setting' => '价格设置',
|
||||||
|
'price_setting_by' =>[
|
||||||
|
'sku' => '根据规格设置价格',
|
||||||
|
'num' => '根据数量设置价格',
|
||||||
|
]
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,11 @@ return [
|
||||||
'error_page' => '您访问的数据不存在或已被删除~',
|
'error_page' => '您访问的数据不存在或已被删除~',
|
||||||
'error_page_btn' => '返回上一页',
|
'error_page_btn' => '返回上一页',
|
||||||
|
|
||||||
|
'contacts' => '联系人',
|
||||||
|
'content' => '内容',
|
||||||
|
'sku' => 'Sku',
|
||||||
|
|
||||||
|
|
||||||
'order' => [
|
'order' => [
|
||||||
'unpaid' => '待支付',
|
'unpaid' => '待支付',
|
||||||
'paid' => '已支付',
|
'paid' => '已支付',
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,9 @@ return [
|
||||||
'in_stock' => '有货',
|
'in_stock' => '有货',
|
||||||
'out_stock' => '缺货',
|
'out_stock' => '缺货',
|
||||||
'model' => '型号',
|
'model' => '型号',
|
||||||
|
'quantity_error' => '数量错误',
|
||||||
|
'inquiry' => '咨询',
|
||||||
|
'enter_contacts' => '请输入联系人',
|
||||||
|
'enter_email' => '请输入邮件',
|
||||||
|
'enter_content' => '请输入内容',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,4 @@ return [
|
||||||
'pay_success_text' => '插件購買成功,點擊確定刷新頁面',
|
'pay_success_text' => '插件購買成功,點擊確定刷新頁面',
|
||||||
'ali_pay_success' => '已完成支付? ',
|
'ali_pay_success' => '已完成支付? ',
|
||||||
'ali_pay_text' => '已完成支付,請刷新頁面',
|
'ali_pay_text' => '已完成支付,請刷新頁面',
|
||||||
'version_compatible_text' => '該插件不兼容當前系統版本,請升級到 <a href="' . config('beike.api_url') . '/download" target="_blank">最新版本</a>',
|
|
||||||
'to_update' => '去升級',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ return [
|
||||||
'plugins_install' => '安裝',
|
'plugins_install' => '安裝',
|
||||||
'plugins_uninstall' => '卸載',
|
'plugins_uninstall' => '卸載',
|
||||||
'to_enable' => '去啟用',
|
'to_enable' => '去啟用',
|
||||||
'uninstall_hint' => '卸載插件會刪除該插件的所有相關數據,確定要卸載嗎? ',
|
|
||||||
|
|
||||||
'plugin_list' => '插件設置',
|
'plugin_list' => '插件設置',
|
||||||
'plugin_code' => '插件代碼',
|
'plugin_code' => '插件代碼',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Laravel Installer successfully INSTALLED on 2023/04/03 08:09:23am
|
||||||
|
|
@ -13,13 +13,13 @@
|
||||||
<div class="select-wrap">
|
<div class="select-wrap">
|
||||||
<i class="bi {{ $cart['selected'] ? 'bi-check-circle-fill' : 'bi-circle' }}" data-id="{{ $cart['cart_id'] }}"></i>
|
<i class="bi {{ $cart['selected'] ? 'bi-check-circle-fill' : 'bi-circle' }}" data-id="{{ $cart['cart_id'] }}"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="product-info d-flex align-items-center">
|
<div class="product-info d-flex align-items-center" style="width: 100%;">
|
||||||
<div class="left"><a href="{{ shop_route('products.show', $cart['product_id']) }}" class="d-flex justify-content-between align-items-center h-100"><img src="{{ $cart['image'] }}" class="img-fluid"></a></div>
|
<div class="left"><a href="{{ shop_route('products.show', $cart['product_id']) }}" class="d-flex justify-content-between align-items-center h-100"><img src="{{ $cart['image'] }}" class="img-fluid"></a></div>
|
||||||
<div class="right flex-grow-1">
|
<div class="right flex-grow-1">
|
||||||
<a href="{{ shop_route('products.show', $cart['product_id']) }}" class="name fs-sm fw-bold mb-2 text-dark text-truncate-2" title="{{ $cart['name'] }}">{{ $cart['name'] }}</a>
|
<a href="{{ shop_route('products.show', $cart['product_id']) }}" class="name fs-sm fw-bold mb-2 text-dark text-truncate-2" title="{{ $cart['name'] }}">{{ $cart['name'] }}</a>
|
||||||
<div class="text-muted mb-1 text-size-min">{{ $cart['variant_labels'] }}</div>
|
<div class="text-muted mb-1 text-size-min">{{ $cart['variant_labels'] }}</div>
|
||||||
<div class="product-bottom d-flex justify-content-between align-items-center">
|
<div class="product-bottom d-flex justify-content-between align-items-center">
|
||||||
<div class="price d-flex align-items-center">
|
<div class="price d-flex align-items-center offcanvas-right-cart-item-price">
|
||||||
{{ $cart['price_format'] }} x
|
{{ $cart['price_format'] }} x
|
||||||
<input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
|
<input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"
|
||||||
data-id="{{ $cart['cart_id'] }}" data-sku="{{ $cart['sku_id'] }}" class="form-control p-1" value="{{ $cart['quantity'] }}">
|
data-id="{{ $cart['cart_id'] }}" data-sku="{{ $cart['sku_id'] }}" class="form-control p-1" value="{{ $cart['quantity'] }}">
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
Powered By <a href="https://beikeshop.com/" target="_blank" rel="noopener">BeikeShop</a>
|
Powered By
|
||||||
{!! $footer_content['bottom']['copyright'][$locale] ?? '' !!}
|
{!! $footer_content['bottom']['copyright'][$locale] ?? '' !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,9 @@
|
||||||
</div>
|
</div>
|
||||||
@endhookwrapper
|
@endhookwrapper
|
||||||
<div class="menu-wrap">
|
<div class="menu-wrap">
|
||||||
|
@if (!is_mobile())
|
||||||
@include('shared.menu-pc')
|
@include('shared.menu-pc')
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="right-btn">
|
<div class="right-btn">
|
||||||
<ul class="navbar-nav flex-row">
|
<ul class="navbar-nav flex-row">
|
||||||
|
|
@ -149,7 +151,9 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="offcanvas-body mobile-menu-wrap">
|
<div class="offcanvas-body mobile-menu-wrap">
|
||||||
|
@if (is_mobile())
|
||||||
@include('shared.menu-mobile')
|
@include('shared.menu-mobile')
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="{{ locale() }}">
|
<html lang="{{ locale() }}">
|
||||||
<head>
|
<head>
|
||||||
|
<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=AW-11146062373"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'AW-11146062373'); </script>
|
||||||
|
<!-- Event snippet for Website sale conversion page --> <script> gtag('event', 'conversion', { 'send_to': 'AW-11146062373/ilbpCKSvzZkYEKXU7cIp', 'transaction_id': '' }); </script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
<title>@yield('title', system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') . ' Powered By BeikeShop')</title>
|
<title>@yield('title', system_setting('base.meta_title', 'BeikeShop开源好用的跨境电商系统 - BeikeShop官网') . ' Powered By 万有引力')</title>
|
||||||
<meta name="keywords" content="@yield('keywords', system_setting('base.meta_keywords'))">
|
<meta name="keywords" content="@yield('keywords', system_setting('base.meta_keywords'))">
|
||||||
<meta name="description" content="@yield('description', system_setting('base.meta_description'))">
|
<meta name="description" content="@yield('description', system_setting('base.meta_description'))">
|
||||||
<meta name="generator" content="BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }})">
|
<meta name="generator" content="BeikeShop v{{ config('beike.version') }}({{ config('beike.build') }})">
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
<script src="{{ asset('vendor/swiper/swiper-bundle.min.js') }}"></script>
|
||||||
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
<script src="{{ asset('vendor/zoom/jquery.zoom.min.js') }}"></script>
|
||||||
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
<link rel="stylesheet" href="{{ asset('vendor/swiper/swiper-bundle.min.css') }}">
|
||||||
|
|
||||||
|
<script src="{{ asset('vendor/element-ui/2.15.6/js.js') }}"></script>
|
||||||
|
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.15.6/css.css') }}">
|
||||||
@endpush
|
@endpush
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
@ -55,14 +58,35 @@
|
||||||
@hookwrapper('product.detail.name')
|
@hookwrapper('product.detail.name')
|
||||||
<h1 class="mb-4 product-name">{{ $product['name'] }}</h1>
|
<h1 class="mb-4 product-name">{{ $product['name'] }}</h1>
|
||||||
@endhookwrapper
|
@endhookwrapper
|
||||||
@hookwrapper('product.detail.price')
|
<div class="price-wrap d-flex align-items-end" v-if="price_setting === 'sku'">
|
||||||
<div class="price-wrap d-flex align-items-end">
|
|
||||||
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}</div>
|
<div class="new-price fs-1 lh-1 fw-bold me-2">@{{ product.price_format }}</div>
|
||||||
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
<div class="old-price text-muted text-decoration-line-through" v-if="product.price != product.origin_price && product.origin_price !== 0">
|
||||||
@{{ product.origin_price_format }}
|
@{{ product.origin_price_format }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endhookwrapper
|
<div class="price-wrap d-flex align-items-end" v-if="price_setting === 'num'" style="
|
||||||
|
border-top: 1px solid #aaaaaa;
|
||||||
|
border-bottom: 1px solid #aaaaaa;
|
||||||
|
padding: 10px;">
|
||||||
|
<div class="item" v-for="(item,index) in numPrices" style="flex: 1">
|
||||||
|
<div class="num" v-if="index < numPrices.length - 1" style="
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #777777;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
">@{{ item.num }} - @{{ numPrices[index + 1].num - 1 }} sets</div>
|
||||||
|
|
||||||
|
<div class="num" v-else-if="item.num" style="
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #777777;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
">>= @{{ item.num }} sets</div>
|
||||||
|
<div class="price">
|
||||||
|
<div class="new-price fs-3 lh-1 fw-bold me-2">@{{ item.price_format }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="stock-and-sku mb-4">
|
<div class="stock-and-sku mb-4">
|
||||||
@hookwrapper('product.detail.quantity')
|
@hookwrapper('product.detail.quantity')
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
|
|
@ -149,12 +173,77 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="text-danger"><i class="bi bi-exclamation-circle-fill"></i> {{ __('product.has_been_inactive') }}</div>
|
{{-- <div class="text-danger"><i class="bi bi-exclamation-circle-fill"></i> {{ __('product.has_been_inactive') }}</div>--}}
|
||||||
@endif
|
@endif
|
||||||
|
<button
|
||||||
|
style="width: 16em;"
|
||||||
|
class="btn btn-outline-dark my-lg-2 add-cart fw-bold"
|
||||||
|
:disabled="!product.quantity"
|
||||||
|
@click="centerDialogVisable = true"
|
||||||
|
><i class="bi bi-globe me-1"></i>{{ __('shop/products.inquiry') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 弹出层 -->
|
||||||
|
<el-dialog title="Inquiry" :visible.sync="centerDialogVisable" width="700px" center>
|
||||||
|
<div class="root" style="
|
||||||
|
display: flex;">
|
||||||
|
<div class="left" style="
|
||||||
|
flex: 4;">
|
||||||
|
<el-form :model="registerForm" ref="registerForm" label-width="90px" :rules="rules">
|
||||||
|
<!-- 弹出层歌手名列 -->
|
||||||
|
<el-form-item prop="contacts" label="Contacts" size="mini">
|
||||||
|
<el-input v-model="registerForm.contacts" placeholder="Contacts"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 弹出层歌手性别列 -->
|
||||||
|
{{-- <el-form-item prop="sex" label="歌手性别" size="mini">--}}
|
||||||
|
{{-- <el-radio-group v-model="registerForm.sex">--}}
|
||||||
|
{{-- <el-radio :label="0">女</el-radio>--}}
|
||||||
|
{{-- <el-radio :label="1">男</el-radio>--}}
|
||||||
|
{{-- <el-radio :label="2">组合</el-radio>--}}
|
||||||
|
{{-- <el-radio :label="3">不明</el-radio>--}}
|
||||||
|
{{-- </el-radio-group>--}}
|
||||||
|
{{-- </el-form-item>--}}
|
||||||
|
<!-- <el-form-item prop="pic" label="歌手头像" size="mini">
|
||||||
|
<el-input v-model="registerForm.pic" placeholder="歌手头像"></el-input>
|
||||||
|
</el-form-item> -->
|
||||||
|
<!-- 弹出层歌手生日列 -->
|
||||||
|
{{-- <el-form-item prop="birth" label="生日" size="mini">--}}
|
||||||
|
{{-- <el-date-picker type="date" placeholder="选择日期" v-model="registerForm.birth" style="width: 100%;"></el-date-picker>--}}
|
||||||
|
{{-- </el-form-item>--}}
|
||||||
|
<el-form-item prop="email" label="E-mail" size="mini">
|
||||||
|
<el-input v-model="registerForm.email" placeholder="E-mail"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="content" label="Content" size="mini">
|
||||||
|
<el-input v-model="registerForm.content" placeholder="Content" type="textarea" :rows="10" ></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div class="right" style="
|
||||||
|
flex: 2;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}">
|
||||||
|
<div class="product" style="
|
||||||
|
margin: -35px 10px 0 10px;">
|
||||||
|
<div class="product-image">
|
||||||
|
<img :src="images.length ? images[0].preview : '{{ asset('image/placeholder.png') }}'" class="img-fluid">
|
||||||
|
</div>
|
||||||
|
<div class="product-info" style="
|
||||||
|
margin: 5px 5px 0 5px;">
|
||||||
|
<div class="product-name">{{ $product['name'] }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 取消,确定按钮点击事件 -->
|
||||||
|
<span slot="footer">
|
||||||
|
{{-- <el-button size="mini" @click="centerDialogVisable = false">Cancel</el-button>--}}
|
||||||
|
<el-button size="mini" @click="addSinger('registerForm')">Submit</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
<div class="product-description">
|
<div class="product-description">
|
||||||
<div class="nav nav-tabs nav-overflow justify-content-start justify-content-md-center border-bottom mb-3">
|
<div class="nav nav-tabs nav-overflow justify-content-start justify-content-md-center border-bottom mb-3">
|
||||||
<a class="nav-link fw-bold active fs-5" data-bs-toggle="tab" href="#product-description">
|
<a class="nav-link fw-bold active fs-5" data-bs-toggle="tab" href="#product-description">
|
||||||
|
|
@ -240,6 +329,39 @@
|
||||||
source: {
|
source: {
|
||||||
skus: @json($product['skus']),
|
skus: @json($product['skus']),
|
||||||
variables: @json($product['variables'] ?? []),
|
variables: @json($product['variables'] ?? []),
|
||||||
|
},
|
||||||
|
price_setting: @json($product['price_setting'] ?? 'sku'),
|
||||||
|
numPrices: @json($product['numPrices'] ?? []),
|
||||||
|
centerDialogVisable:false, // 设置显示框的状态
|
||||||
|
registerForm:{ // 添加的信息
|
||||||
|
contacts:'',
|
||||||
|
email:'',
|
||||||
|
content:'',
|
||||||
|
product_sku_id:'',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
contacts: [{
|
||||||
|
required: true,
|
||||||
|
message: '{{ __('shop/products.enter_contacts') }}',
|
||||||
|
trigger: 'blur'
|
||||||
|
}, ],
|
||||||
|
email: [{
|
||||||
|
required: true,
|
||||||
|
type: 'email',
|
||||||
|
message: '{{ __('shop/products.enter_email') }}',
|
||||||
|
trigger: 'blur'
|
||||||
|
}, ],
|
||||||
|
content: [{
|
||||||
|
required: true,
|
||||||
|
message: '{{ __('shop/products.enter_content') }}',
|
||||||
|
trigger: 'blur'
|
||||||
|
}, ],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if(this.price_setting === 'num'){
|
||||||
|
this.quantity = this.numPrices[0].num;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -271,6 +393,28 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
addSinger(form){ // 点击确定按钮添加方法
|
||||||
|
|
||||||
|
this.$refs[form].validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
this.$message.error('{{ __('shop/checkout.check_form') }}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.registerForm.product_sku_id = this.product.id
|
||||||
|
$http.post(`/inquiry`, this.registerForm).then((res) => {
|
||||||
|
layer.msg('Success')
|
||||||
|
this.registerForm = {
|
||||||
|
contacts:'',
|
||||||
|
email:'',
|
||||||
|
content:'',
|
||||||
|
product_sku_id:'',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.centerDialogVisable=false
|
||||||
|
});
|
||||||
|
},
|
||||||
checkedVariableValue(variable_idnex, value_index, value) {
|
checkedVariableValue(variable_idnex, value_index, value) {
|
||||||
$('.product-image .swiper .swiper-slide').eq(0).addClass('active').siblings().removeClass('active');
|
$('.product-image .swiper .swiper-slide').eq(0).addClass('active').siblings().removeClass('active');
|
||||||
this.source.variables[variable_idnex].values.forEach((v, i) => {
|
this.source.variables[variable_idnex].values.forEach((v, i) => {
|
||||||
|
|
@ -307,6 +451,11 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
addCart(isBuyNow = false) {
|
addCart(isBuyNow = false) {
|
||||||
|
if(this.price_setting === 'num' && this.quantity < this.numPrices[0].num){
|
||||||
|
layer.msg( '{{ __('shop/products.quantity_error') }}' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bk.addCart({sku_id: this.product.id, quantity: this.quantity, isBuyNow});
|
bk.addCart({sku_id: this.product.id, quantity: this.quantity, isBuyNow});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,11 @@
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="top"
|
data-bs-placement="top"
|
||||||
title="{{ __('shop/products.add_to_cart') }}"
|
title="{{ __('shop/products.add_to_cart') }}"
|
||||||
|
@if ($product['price_setting'] === 'num')
|
||||||
|
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}',quantity: {{$product['numprices'][0]['num']}} }, this)">
|
||||||
|
@else
|
||||||
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
|
onclick="bk.addCart({sku_id: '{{ $product['sku_id'] }}'}, this)">
|
||||||
|
@endif
|
||||||
<i class="bi bi-cart"></i>
|
<i class="bi bi-cart"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -30,10 +34,29 @@
|
||||||
<div class="product-bottom-info">
|
<div class="product-bottom-info">
|
||||||
<div class="product-name">{{ $product['name_format'] }}</div>
|
<div class="product-name">{{ $product['name_format'] }}</div>
|
||||||
<div class="product-price">
|
<div class="product-price">
|
||||||
|
@if ($product['price_setting'] === 'sku')
|
||||||
<span class="price-new">{{ $product['price_format'] }}</span>
|
<span class="price-new">{{ $product['price_format'] }}</span>
|
||||||
|
<span>-</span>
|
||||||
@if ($product['price'] != $product['origin_price'] && $product['origin_price'] > 0)
|
@if ($product['price'] != $product['origin_price'] && $product['origin_price'] > 0)
|
||||||
<span class="price-old">{{ $product['origin_price_format'] }}</span>
|
<span class="price-new">{{ $product['origin_price_format'] }}</span>
|
||||||
@endif
|
@endif
|
||||||
|
@elseif($product['price_setting'] === 'num')
|
||||||
|
@if ($product['price'] != $product['origin_price'] && $product['origin_price'] > 0)
|
||||||
|
<span class="price-new">{{ $product['origin_price_format'] }}</span>
|
||||||
|
@endif
|
||||||
|
<span>-</span>
|
||||||
|
<span class="price-new">{{ $product['price_format'] }}</span>
|
||||||
|
@endif
|
||||||
|
<span style="color:#aaa">/pieces</span>
|
||||||
|
</div>
|
||||||
|
<!--yt修改-->
|
||||||
|
<div class="product-price">
|
||||||
|
@if ($product['price_setting'] === 'num')
|
||||||
|
<span class="price-new">{{$product['numprices'][0]['num']}} pieces</span>
|
||||||
|
@else
|
||||||
|
<span class="price-new">1 pieces</span>
|
||||||
|
@endif
|
||||||
|
<span style="color:#aaa;margin-left:4px">(Min Order)</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (request('style_list') == 'list')
|
@if (request('style_list') == 'list')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue