feat(product): add option to disable store feature
This commit is contained in:
@@ -31,6 +31,7 @@ if (is_readable($sysLibPath . '/oc_telegram_shop.phar')) {
|
||||
* @property ModelCustomerCustomerGroup $model_customer_customer_group
|
||||
* @property ModelLocalisationOrderStatus $model_localisation_order_status
|
||||
* @property DB $db
|
||||
* @property Log $log
|
||||
*/
|
||||
class ControllerExtensionModuleTgshop extends Controller
|
||||
{
|
||||
@@ -342,11 +343,11 @@ TEXT,
|
||||
'module_tgshop_theme_light' => 'light',
|
||||
'module_tgshop_theme_dark' => 'dark',
|
||||
'module_tgshop_mainpage_products' => 'most_viewed',
|
||||
'module_tgshop_featured_products' => [],
|
||||
'module_tgshop_order_customer_group_id' => 1,
|
||||
'module_tgshop_order_default_status_id' => 1,
|
||||
'module_tgshop_mini_app_url' => rtrim(HTTPS_CATALOG, '/') . '/image/catalog/tgshopspa/#/',
|
||||
'module_tgshop_mainpage_categories' => 'latest10'
|
||||
'module_tgshop_mainpage_categories' => 'latest10',
|
||||
'module_tgshop_enable_store' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -445,6 +446,17 @@ HTML,
|
||||
],
|
||||
|
||||
'shop' => [
|
||||
'module_tgshop_enable_store' => [
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
0 => 'Выключено',
|
||||
1 => 'Включено',
|
||||
],
|
||||
'help' => <<<HTML
|
||||
Если опция <strong>включена</strong> — пользователи смогут оформлять заказы прямо в Telegram-магазине. <br>
|
||||
Если <strong>выключена</strong> — оформление заказов будет недоступно. Вместо кнопки «Добавить в корзину» пользователи увидят кнопку «Перейти к товару», которая откроет страницу товара на вашем сайте. В этом режиме Telecart работает как каталог.
|
||||
HTML,
|
||||
],
|
||||
'module_tgshop_mainpage_products' => [
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
@@ -457,7 +469,7 @@ HTML,
|
||||
|
||||
'module_tgshop_featured_products' => [
|
||||
'type' => 'products',
|
||||
'help' => 'На главной странице будут отображаться избранные товары, если вы выберете этот вариант в настройке “Товары на главной”.',
|
||||
'help' => 'На главной странице будут отображаться избранные товары, если вы выберете этот вариант в настройке “Товары на главной”. Если товары не выбраны, то будут показаны популярные товары.',
|
||||
],
|
||||
|
||||
'module_tgshop_mainpage_categories' => [
|
||||
@@ -522,7 +534,7 @@ HTML,
|
||||
|
||||
$diff = [];
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (! isset($settings[$key])) {
|
||||
if (! array_key_exists($key, $settings)) {
|
||||
$diff[$key] = $defaults[$key];
|
||||
}
|
||||
}
|
||||
@@ -530,6 +542,15 @@ HTML,
|
||||
if ($diff) {
|
||||
$settings = array_merge($settings, $diff);
|
||||
$this->model_setting_setting->editSetting('module_tgshop', $settings);
|
||||
$this->log->write('[TELECART] Выполнено обновление настроек по умолчанию для модуля.');
|
||||
$this->session->data['success'] = 'Выполнено обновление настроек по умолчанию для модуля.';
|
||||
}
|
||||
}
|
||||
|
||||
public function install(): void
|
||||
{
|
||||
$this->log->write('[TELECART] Запуск установки модуля.');
|
||||
$this->updateConfigFromDefaults();
|
||||
$this->log->write('[TELECART] Установка модуля завершена.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ $_['lbl_module_tgshop_order_default_status_id'] = 'Статус заказов';
|
||||
$_['lbl_module_tgshop_mini_app_url'] = 'Ссылка на Telegram Mini App';
|
||||
$_['lbl_module_tgshop_mainpage_categories'] = 'Категории на главной';
|
||||
$_['lbl_module_tgshop_featured_categories'] = 'Избранные категории';
|
||||
$_['lbl_module_tgshop_enable_store'] = 'Разрешить покупки';
|
||||
|
||||
// Entry
|
||||
$_['entry_status'] = 'Статус';
|
||||
|
||||
@@ -58,9 +58,10 @@ class ControllerExtensionTgshopHandle extends Controller
|
||||
'theme_light' => $this->config->get('module_tgshop_theme_light'),
|
||||
'theme_dark' => $this->config->get('module_tgshop_theme_dark'),
|
||||
'mainpage_products' => $this->config->get('module_tgshop_mainpage_products'),
|
||||
'featured_products' => $this->config->get('module_tgshop_featured_products'),
|
||||
'featured_products' => (array) $this->config->get('module_tgshop_featured_products'),
|
||||
'mainpage_categories' => $this->config->get('module_tgshop_mainpage_categories'),
|
||||
'featured_categories' => $this->config->get('module_tgshop_featured_categories'),
|
||||
'featured_categories' => (array) $this->config->get('module_tgshop_featured_categories'),
|
||||
'store_enabled' => filter_var($this->config->get('module_tgshop_enable_store'), FILTER_VALIDATE_BOOLEAN),
|
||||
'base_url' => HTTPS_SERVER,
|
||||
'ya_metrika_enabled' => ! empty(trim($this->config->get('module_tgshop_yandex_metrika'))),
|
||||
'telegram' => [
|
||||
|
||||
@@ -51,6 +51,7 @@ class SettingsHandler
|
||||
'theme_dark' => $this->settings->get('theme_dark'),
|
||||
'ya_metrika_enabled' => $this->settings->get('ya_metrika_enabled'),
|
||||
'app_enabled' => $this->settings->get('app_enabled'),
|
||||
'store_enabled' => $this->settings->get('store_enabled'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class ProductsService
|
||||
->value('name');
|
||||
}
|
||||
|
||||
$customerGroupId = (int)$this->oc->config->get('config_customer_group_id');
|
||||
$customerGroupId = (int) $this->oc->config->get('config_customer_group_id');
|
||||
$specialPriceSql = "(SELECT price
|
||||
FROM oc_product_special ps
|
||||
WHERE ps.product_id = products.product_id
|
||||
@@ -245,6 +245,11 @@ class ProductsService
|
||||
$data['reward'] = $product_info['reward'];
|
||||
$data['points'] = (int) $product_info['points'];
|
||||
$data['description'] = html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8');
|
||||
$data['share'] = html_entity_decode(
|
||||
$this->oc->url->link('product/product', 'product_id=' . $productId),
|
||||
ENT_QUOTES | ENT_HTML5,
|
||||
'UTF-8'
|
||||
);
|
||||
|
||||
if ($product_info['quantity'] <= 0) {
|
||||
$data['stock'] = $product_info['stock_status'];
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</Transition>
|
||||
</RouterView>
|
||||
<CartButton/>
|
||||
<CartButton v-if="settings.store_enabled"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -16,6 +16,7 @@ import {useWebAppViewport, useBackButton} from 'vue-tg';
|
||||
import {useMiniApp, FullscreenViewport} from 'vue-tg';
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import CartButton from "@/components/CartButton.vue";
|
||||
import {useSettingsStore} from "@/stores/SettingsStore.js";
|
||||
|
||||
const tg = useMiniApp();
|
||||
const platform = ref();
|
||||
@@ -26,6 +27,7 @@ disableVerticalSwipes();
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const settings = useSettingsStore();
|
||||
|
||||
watch(
|
||||
() => route.name,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {fetchSettings} from "@/utils/ftch.js";
|
||||
export const useSettingsStore = defineStore('settings', {
|
||||
state: () => ({
|
||||
app_enabled: true,
|
||||
store_enabled: true,
|
||||
app_name: 'OpenCart Telegram магазин',
|
||||
app_icon: '',
|
||||
app_icon192: '',
|
||||
@@ -38,6 +39,7 @@ export const useSettingsStore = defineStore('settings', {
|
||||
this.theme.dark = settings.theme_dark;
|
||||
this.ya_metrika_enabled = settings.ya_metrika_enabled;
|
||||
this.app_enabled = settings.app_enabled;
|
||||
this.store_enabled = settings.store_enabled;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -91,34 +91,54 @@
|
||||
|
||||
<div v-if="product.product_id"
|
||||
class="fixed px-4 pb-10 pt-4 bottom-0 left-0 w-full bg-base-200 z-50 flex flex-col gap-2 border-t-1 border-t-base-300">
|
||||
<div class="text-error">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<div v-if="canAddToCart === false" class="text-error text-center text-xs mt-1">
|
||||
Выберите обязательные опции
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<div class="flex-1">
|
||||
<button
|
||||
class="btn btn-primary btn-lg w-full"
|
||||
:class="isInCart ? 'btn-success' : 'btn-primary'"
|
||||
:disabled="cart.isLoading || canAddToCart === false"
|
||||
@click="actionBtnClick"
|
||||
>
|
||||
<span v-if="cart.isLoading" class="loading loading-spinner loading-sm"></span>
|
||||
{{ btnText }}
|
||||
</button>
|
||||
<template v-if="settings.store_enabled">
|
||||
<div class="text-error">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<Quantity
|
||||
v-if="isInCart === false"
|
||||
:modelValue="quantity"
|
||||
@update:modelValue="setQuantity"
|
||||
size="lg"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="canAddToCart === false" class="text-error text-center text-xs mt-1">
|
||||
Выберите обязательные опции
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<div class="flex-1">
|
||||
<button
|
||||
class="btn btn-primary btn-lg w-full"
|
||||
:class="isInCart ? 'btn-success' : 'btn-primary'"
|
||||
:disabled="cart.isLoading || canAddToCart === false"
|
||||
@click="actionBtnClick"
|
||||
>
|
||||
<span v-if="cart.isLoading" class="loading loading-spinner loading-sm"></span>
|
||||
{{ btnText }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Quantity
|
||||
v-if="isInCart === false"
|
||||
:modelValue="quantity"
|
||||
@update:modelValue="setQuantity"
|
||||
size="lg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<button
|
||||
class="btn btn-primary btn-lg w-full"
|
||||
:disabled="! product.share"
|
||||
@click="openProductInMarketplace"
|
||||
>
|
||||
<template v-if="product.share">
|
||||
Открыть товар
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<template>Товар недоступен</template>
|
||||
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<ProductNotFound v-else/>
|
||||
@@ -144,6 +164,7 @@ import {apiFetch} from "@/utils/ftch.js";
|
||||
import FullScreenImageViewer from "@/components/FullScreenImageViewer.vue";
|
||||
import LoadingFullScreen from "@/components/LoadingFullScreen.vue";
|
||||
import ProductNotFound from "@/components/ProductNotFound.vue";
|
||||
import {useSettingsStore} from "@/stores/SettingsStore.js";
|
||||
|
||||
const route = useRoute();
|
||||
const productId = computed(() => route.params.id);
|
||||
@@ -157,6 +178,7 @@ const btnText = computed(() => isInCart.value ? 'В корзине' : 'Купи
|
||||
const isFullScreen = ref(false);
|
||||
const initialFullScreenIndex = ref(0);
|
||||
const isLoading = ref(false);
|
||||
const settings = useSettingsStore();
|
||||
|
||||
const canAddToCart = computed(() => {
|
||||
if (!product.value || product.value.options === undefined || product.value.options?.length === 0) {
|
||||
@@ -204,6 +226,14 @@ async function actionBtnClick() {
|
||||
}
|
||||
}
|
||||
|
||||
function openProductInMarketplace() {
|
||||
if (! product.value.share) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.Telegram.WebApp.openLink(product.value.share, { try_instant_view: false });
|
||||
}
|
||||
|
||||
function setQuantity(newQuantity) {
|
||||
quantity.value = newQuantity;
|
||||
window.Telegram.WebApp.HapticFeedback.selectionChanged();
|
||||
|
||||
Reference in New Issue
Block a user