@coopenomics/desktop 2025.11.9-alpha-1 → 2025.11.10-alpha-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/src/app/App.vue +17 -5
- package/src/env.d.ts +2 -0
- package/src/features/NotificationPermissionDialog/model/index.ts +6 -2
- package/src/features/Provider/api/index.ts +12 -0
- package/src/features/Provider/index.ts +1 -0
- package/src/features/Provider/model/index.ts +105 -0
- package/src/features/WebPushNotifications/model/index.ts +21 -3
- package/src/pages/Union/ConnectionAgreement/ConnectionAgreementPage.vue +121 -52
- package/src/widgets/ConnectionAgreementStepper/Steps/AgreementStep.vue +57 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/FormStep.vue +51 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/IntroStep.vue +62 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/WaitingStep.vue +163 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/index.ts +4 -0
- package/src/widgets/ConnectionAgreementStepper/Tariffs/TariffCard.vue +278 -0
- package/src/widgets/ConnectionAgreementStepper/Tariffs/TariffSelector.vue +95 -0
- package/src/widgets/ConnectionAgreementStepper/Tariffs/index.ts +3 -0
- package/src/widgets/ConnectionAgreementStepper/index.ts +2 -0
- package/src/widgets/ConnectionAgreementStepper/model/index.ts +1 -0
- package/src/widgets/ConnectionAgreementStepper/model/types.ts +13 -0
- package/src/widgets/ConnectionAgreementStepper/ui/ConnectionAgreementStepper.vue +123 -0
- package/src/widgets/ConnectionAgreementStepper/ui/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopenomics/desktop",
|
|
3
|
-
"version": "2025.11.
|
|
3
|
+
"version": "2025.11.10-alpha-1",
|
|
4
4
|
"description": "A Desktop Project",
|
|
5
5
|
"productName": "Desktop App",
|
|
6
6
|
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"start": "node -r ./alias-resolver.js dist/ssr/index.js"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@coopenomics/controller": "2025.11.
|
|
29
|
-
"@coopenomics/notifications": "2025.11.
|
|
30
|
-
"@coopenomics/sdk": "2025.11.
|
|
28
|
+
"@coopenomics/controller": "2025.11.10-alpha-1",
|
|
29
|
+
"@coopenomics/notifications": "2025.11.10-alpha-1",
|
|
30
|
+
"@coopenomics/sdk": "2025.11.10-alpha-1",
|
|
31
31
|
"@dicebear/collection": "^9.0.1",
|
|
32
32
|
"@dicebear/core": "^9.0.1",
|
|
33
33
|
"@editorjs/code": "^2.9.3",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@wharfkit/wallet-plugin-privatekey": "^1.1.0",
|
|
60
60
|
"axios": "^1.2.1",
|
|
61
61
|
"compression": "^1.7.4",
|
|
62
|
-
"cooptypes": "2025.11.
|
|
62
|
+
"cooptypes": "2025.11.10-alpha-1",
|
|
63
63
|
"dompurify": "^3.1.7",
|
|
64
64
|
"dotenv": "^16.4.5",
|
|
65
65
|
"email-regex": "^5.0.0",
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"npm": ">= 6.13.4",
|
|
124
124
|
"yarn": ">= 1.21.1"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "634766a08edc036ccf4b08438b14251fa3a8ab73"
|
|
127
127
|
}
|
package/src/app/App.vue
CHANGED
|
@@ -33,11 +33,23 @@ const { showDialog } = useNotificationPermissionDialog();
|
|
|
33
33
|
onMounted(async () => {
|
|
34
34
|
try {
|
|
35
35
|
console.log('systemInfo', info)
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
// Проверяем, нужно ли корректировать URL для hash роутера
|
|
37
|
+
// Выполняем только в клиентском режиме с hash роутером
|
|
38
|
+
const isClientMode = process.env.CLIENT === 'true';
|
|
39
|
+
const isHashRouter = process.env.VUE_ROUTER_MODE === 'hash';
|
|
40
|
+
const isNotSSR = process.env.SERVER !== 'true';
|
|
41
|
+
const hasWindow = typeof window !== 'undefined';
|
|
42
|
+
|
|
43
|
+
const shouldCorrectHashUrl =
|
|
44
|
+
isClientMode &&
|
|
45
|
+
isHashRouter &&
|
|
46
|
+
isNotSSR &&
|
|
47
|
+
hasWindow &&
|
|
48
|
+
window.location.pathname !== '/' &&
|
|
49
|
+
(!window.location.hash || !window.location.hash.includes(window.location.pathname));
|
|
50
|
+
|
|
51
|
+
if (shouldCorrectHashUrl) {
|
|
52
|
+
console.log('URL needs hash correction for hash router mode');
|
|
41
53
|
const newUrl = window.location.origin + '/#' + window.location.pathname + window.location.search;
|
|
42
54
|
console.log('Redirecting to:', newUrl);
|
|
43
55
|
window.location.replace(newUrl);
|
package/src/env.d.ts
CHANGED
|
@@ -80,14 +80,17 @@ export function useNotificationPermissionDialog() {
|
|
|
80
80
|
const handleAllow = async () => {
|
|
81
81
|
try {
|
|
82
82
|
store.isPermissionDialogProcessing = true;
|
|
83
|
-
|
|
83
|
+
console.log('handleAllow');
|
|
84
84
|
// Подписываемся на уведомления (это включает запрос разрешения)
|
|
85
85
|
const success = await subscribe();
|
|
86
|
-
|
|
86
|
+
console.log('success', success);
|
|
87
87
|
if (success) {
|
|
88
|
+
console.log('saveChoice granted');
|
|
88
89
|
saveChoice('granted');
|
|
90
|
+
console.log('hideDialog');
|
|
89
91
|
hideDialog();
|
|
90
92
|
} else {
|
|
93
|
+
console.log('saveChoice denied');
|
|
91
94
|
// Если подписка не удалась, но пользователь согласился,
|
|
92
95
|
// все равно сохраняем выбор чтобы не показывать диалог снова
|
|
93
96
|
saveChoice('denied');
|
|
@@ -95,6 +98,7 @@ export function useNotificationPermissionDialog() {
|
|
|
95
98
|
}
|
|
96
99
|
} catch (error) {
|
|
97
100
|
console.error('Ошибка при разрешении уведомлений:', error);
|
|
101
|
+
console.log('saveChoice denied');
|
|
98
102
|
saveChoice('denied');
|
|
99
103
|
hideDialog();
|
|
100
104
|
} finally {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { client } from 'src/shared/api/client';
|
|
2
|
+
import { Queries } from '@coopenomics/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Получить подписки пользователя у провайдера
|
|
6
|
+
*/
|
|
7
|
+
export async function loadProviderSubscriptions() {
|
|
8
|
+
const { [Queries.System.GetProviderSubscriptions.name]: subscriptions } =
|
|
9
|
+
await client.Query(Queries.System.GetProviderSubscriptions.query);
|
|
10
|
+
|
|
11
|
+
return subscriptions;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './model';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ref, computed } from 'vue';
|
|
2
|
+
import { loadProviderSubscriptions } from '../api';
|
|
3
|
+
import { useSystemStore } from 'src/entities/System/model';
|
|
4
|
+
import { Queries } from '@coopenomics/sdk';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Специфичные данные для подписки на хостинг
|
|
8
|
+
*/
|
|
9
|
+
export interface HostingSubscriptionData {
|
|
10
|
+
subscription_type_id: 1;
|
|
11
|
+
progress: number;
|
|
12
|
+
is_valid: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Специфичные данные подписки (union тип для всех типов подписок)
|
|
17
|
+
*/
|
|
18
|
+
export type SubscriptionSpecificData = HostingSubscriptionData | null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Тип подписки провайдера из GraphQL API
|
|
22
|
+
*/
|
|
23
|
+
export type ProviderSubscription = Queries.System.GetProviderSubscriptions.IOutput[typeof Queries.System.GetProviderSubscriptions.name][number];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Composable для работы с подписками провайдера
|
|
27
|
+
*/
|
|
28
|
+
export function useProviderSubscriptions() {
|
|
29
|
+
const system = useSystemStore();
|
|
30
|
+
const subscriptions = ref<ProviderSubscription[]>([]);
|
|
31
|
+
const isLoading = ref(false);
|
|
32
|
+
const error = ref<string | null>(null);
|
|
33
|
+
|
|
34
|
+
// Получить подписку на хостинг (id=1)
|
|
35
|
+
const hostingSubscription = computed(() =>
|
|
36
|
+
subscriptions.value.find(sub => sub.subscription_type_id === 1)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Статус валидности домена для хостинг подписки (из specific_data)
|
|
40
|
+
const domainValid = computed(() => {
|
|
41
|
+
const specificData = hostingSubscription.value?.specific_data as SubscriptionSpecificData;
|
|
42
|
+
return specificData?.is_valid ?? null;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Прогресс установки для хостинг подписки (из specific_data)
|
|
46
|
+
const installationProgress = computed(() => {
|
|
47
|
+
const specificData = hostingSubscription.value?.specific_data as SubscriptionSpecificData;
|
|
48
|
+
return specificData?.progress ?? null;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Статус инстанса для хостинг подписки (пока оставляем как есть, может поле будет добавлено позже)
|
|
52
|
+
const instanceStatus = computed(() =>
|
|
53
|
+
hostingSubscription.value?.instance_status ?? null
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Загрузить подписки пользователя
|
|
58
|
+
*/
|
|
59
|
+
const loadSubscriptions = async () => {
|
|
60
|
+
// Проверяем доступность провайдера
|
|
61
|
+
if (!system.info.is_providered) {
|
|
62
|
+
error.value = 'Функционал провайдера не доступен';
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
isLoading.value = true;
|
|
68
|
+
error.value = null;
|
|
69
|
+
subscriptions.value = await loadProviderSubscriptions();
|
|
70
|
+
} catch (err: any) {
|
|
71
|
+
error.value = err.message || 'Ошибка загрузки подписок';
|
|
72
|
+
console.error('Error loading provider subscriptions:', err);
|
|
73
|
+
} finally {
|
|
74
|
+
isLoading.value = false;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Автоматическая загрузка с интервалом
|
|
80
|
+
*/
|
|
81
|
+
const startAutoRefresh = (intervalMs = 60000) => { // 1 минута по умолчанию
|
|
82
|
+
loadSubscriptions(); // Первая загрузка
|
|
83
|
+
|
|
84
|
+
const interval = setInterval(() => {
|
|
85
|
+
loadSubscriptions();
|
|
86
|
+
}, intervalMs);
|
|
87
|
+
|
|
88
|
+
// Функция для остановки автообновления
|
|
89
|
+
const stop = () => clearInterval(interval);
|
|
90
|
+
|
|
91
|
+
return stop;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
subscriptions,
|
|
96
|
+
isLoading,
|
|
97
|
+
error,
|
|
98
|
+
hostingSubscription,
|
|
99
|
+
domainValid,
|
|
100
|
+
installationProgress,
|
|
101
|
+
instanceStatus,
|
|
102
|
+
loadSubscriptions,
|
|
103
|
+
startAutoRefresh,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -83,7 +83,16 @@ export function useWebPushNotifications() {
|
|
|
83
83
|
throw new Error('Push уведомления не поддерживаются');
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
// Добавляем timeout на случай, если пользователь не взаимодействует с диалогом
|
|
87
|
+
const permission = await Promise.race([
|
|
88
|
+
Notification.requestPermission(),
|
|
89
|
+
new Promise<never>((_, reject) => {
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
reject(new Error('Пользователь не ответил на запрос разрешения в течение 30 секунд'));
|
|
92
|
+
}, 15000);
|
|
93
|
+
}),
|
|
94
|
+
]);
|
|
95
|
+
|
|
87
96
|
store.support.permission = permission;
|
|
88
97
|
store.support.hasPermission = permission === 'granted';
|
|
89
98
|
store.support.canSubscribe =
|
|
@@ -150,7 +159,16 @@ export function useWebPushNotifications() {
|
|
|
150
159
|
}
|
|
151
160
|
|
|
152
161
|
console.log('Форсированный запрос разрешения...');
|
|
153
|
-
|
|
162
|
+
|
|
163
|
+
// Добавляем timeout на случай, если пользователь не взаимодействует с диалогом
|
|
164
|
+
const permission = await Promise.race([
|
|
165
|
+
Notification.requestPermission(),
|
|
166
|
+
new Promise<never>((_, reject) => {
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
reject(new Error('Пользователь не ответил на запрос разрешения в течение 30 секунд'));
|
|
169
|
+
}, 30000);
|
|
170
|
+
}),
|
|
171
|
+
]);
|
|
154
172
|
|
|
155
173
|
store.support.permission = permission;
|
|
156
174
|
store.support.hasPermission = permission === 'granted';
|
|
@@ -267,7 +285,7 @@ export function useWebPushNotifications() {
|
|
|
267
285
|
// Создаем новую подписку
|
|
268
286
|
const subscription = await registration.pushManager.subscribe({
|
|
269
287
|
userVisibleOnly: true,
|
|
270
|
-
applicationServerKey: applicationServerKey,
|
|
288
|
+
applicationServerKey: applicationServerKey as any,
|
|
271
289
|
});
|
|
272
290
|
|
|
273
291
|
return subscription;
|
|
@@ -1,101 +1,170 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
div.row.
|
|
3
|
-
div.col-md-
|
|
4
|
-
div(v-if="
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
2
|
+
div.row.q-pa-md
|
|
3
|
+
div.col-md-12.col-xs-12
|
|
4
|
+
div(v-if="system.info.is_providered")
|
|
5
|
+
ConnectionAgreementStepper(
|
|
6
|
+
:initial-step="currentStep"
|
|
7
|
+
:is-finish="is_finish"
|
|
8
|
+
:signed-document="signedDocument"
|
|
9
|
+
:coop="coop"
|
|
10
|
+
:html="html"
|
|
11
|
+
:domain-valid="domainValid"
|
|
12
|
+
:installation-progress="installationProgress"
|
|
13
|
+
:instance-status="instanceStatus"
|
|
14
|
+
:subscriptions-loading="subscriptionsLoading"
|
|
15
|
+
:subscriptions-error="subscriptionsError"
|
|
16
|
+
@step-change="handleStepChange"
|
|
17
|
+
@tariff-selected="handleTariffSelected"
|
|
18
|
+
@tariff-deselected="handleTariffDeselected"
|
|
19
|
+
@continue="handleContinue"
|
|
20
|
+
@sign="sign"
|
|
21
|
+
@finish="finish"
|
|
22
|
+
@reload="reload"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
div(v-else).row
|
|
26
|
+
//- Заглушка для недоступного провайдера
|
|
27
|
+
div.col-md-12.col-xs-12
|
|
28
|
+
ColorCard(color="blue")
|
|
29
|
+
.text-center.q-pa-md
|
|
30
|
+
q-icon(name="fas fa-info-circle" size="2rem").q-mb-sm
|
|
31
|
+
.text-h6.q-mb-md Информация о подключении
|
|
32
|
+
p Для подключения к платформе Кооперативной Экономики обратитесь в ПК ВОСХОД.
|
|
33
|
+
q-btn(
|
|
34
|
+
color="primary"
|
|
35
|
+
label="Перейти на сайт"
|
|
36
|
+
@click="openProviderWebsite"
|
|
37
|
+
size="md"
|
|
38
|
+
).q-mt-md
|
|
37
39
|
|
|
38
40
|
</template>
|
|
39
41
|
<script setup lang="ts">
|
|
40
42
|
import { DigitalDocument } from 'src/shared/lib/document';
|
|
41
43
|
import { useSessionStore } from 'src/entities/Session';
|
|
42
|
-
import {
|
|
43
|
-
import { computed, ref } from 'vue';
|
|
44
|
-
import { Loader } from 'src/shared/ui/Loader';
|
|
45
|
-
import { AddCooperativeForm } from 'src/features/Union/AddCooperative';
|
|
44
|
+
import { useSystemStore } from 'src/entities/System/model';
|
|
45
|
+
import { computed, ref, onMounted, onUnmounted } from 'vue';
|
|
46
46
|
import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives';
|
|
47
|
-
import {
|
|
48
|
-
import { SuccessAlert } from 'src/shared/api';
|
|
47
|
+
import { useProviderSubscriptions } from 'src/features/Provider';
|
|
49
48
|
import { Cooperative } from 'cooptypes';
|
|
49
|
+
import { ConnectionAgreementStepper } from 'src/widgets/ConnectionAgreementStepper';
|
|
50
|
+
import { ColorCard } from 'src/shared/ui';
|
|
51
|
+
|
|
50
52
|
|
|
51
53
|
const session = useSessionStore()
|
|
54
|
+
const system = useSystemStore()
|
|
52
55
|
const document = ref(new DigitalDocument())
|
|
53
56
|
const {loadOneCooperative} = useLoadCooperatives()
|
|
57
|
+
const {
|
|
58
|
+
domainValid,
|
|
59
|
+
installationProgress,
|
|
60
|
+
instanceStatus,
|
|
61
|
+
isLoading: subscriptionsLoading,
|
|
62
|
+
error: subscriptionsError,
|
|
63
|
+
startAutoRefresh
|
|
64
|
+
} = useProviderSubscriptions()
|
|
54
65
|
|
|
55
66
|
const coop = ref()
|
|
56
|
-
const instruction = computed(() => `Создайте A-запись домена ${coop.value?.announce} на IP-адрес: 51.250.114.13`)
|
|
57
67
|
|
|
58
68
|
const html = computed(() => document.value?.data?.html)
|
|
59
69
|
const signedDocument = computed(() => document.value?.signedDocument)
|
|
60
70
|
const is_finish = ref(false)
|
|
61
71
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
// Управление шагом степпера
|
|
73
|
+
const currentStep = ref(1)
|
|
74
|
+
|
|
75
|
+
const handleStepChange = (step: number) => {
|
|
76
|
+
currentStep.value = step
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const handleTariffSelected = (tariff: any) => {
|
|
80
|
+
// Здесь можно сохранить выбранный тариф
|
|
81
|
+
console.log('Selected tariff:', tariff)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const handleTariffDeselected = () => {
|
|
85
|
+
// Здесь можно обработать снятие выбора тарифа
|
|
86
|
+
console.log('Tariff deselected')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Остановка автообновления при размонтировании компонента
|
|
90
|
+
let stopRefresh: (() => void) | null = null
|
|
91
|
+
|
|
92
|
+
const handleContinue = async () => {
|
|
93
|
+
// Если документ еще не сгенерирован, генерируем его
|
|
94
|
+
if (!document.value.data?.html && !coop.value) {
|
|
95
|
+
await document.value.generate({
|
|
96
|
+
registry_id: Cooperative.Registry.CoopenomicsAgreement.registry_id,
|
|
97
|
+
coopname: 'voskhod',
|
|
98
|
+
username: session.username,
|
|
69
99
|
})
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const openProviderWebsite = () => {
|
|
104
|
+
window.open('https://цифровой-кооператив.рф', '_blank')
|
|
70
105
|
}
|
|
71
106
|
|
|
72
107
|
|
|
73
108
|
const finish = () => {
|
|
109
|
+
// Эта функция имеет смысл только если провайдер доступен
|
|
110
|
+
if (!system.info.is_providered) return
|
|
111
|
+
|
|
74
112
|
is_finish.value = true
|
|
75
113
|
reload()
|
|
114
|
+
|
|
115
|
+
// Запускаем автообновление подписок каждую минуту
|
|
116
|
+
if (!stopRefresh) {
|
|
117
|
+
stopRefresh = startAutoRefresh(60000) // 1 минута
|
|
118
|
+
}
|
|
76
119
|
}
|
|
77
120
|
|
|
78
121
|
//todo loadCooperative by username and check status
|
|
79
122
|
const reload = async() => {
|
|
80
|
-
|
|
123
|
+
// Загружаем кооператив только если провайдер доступен
|
|
124
|
+
if (system.info.is_providered) {
|
|
125
|
+
coop.value = await loadOneCooperative(session.username)
|
|
126
|
+
}
|
|
81
127
|
}
|
|
82
128
|
|
|
83
129
|
const init = async () => {
|
|
130
|
+
// Инициализация имеет смысл только если провайдер доступен
|
|
131
|
+
if (!system.info.is_providered) return
|
|
132
|
+
|
|
84
133
|
coop.value = await loadOneCooperative(session.username)
|
|
85
134
|
|
|
86
|
-
if (!coop.value)
|
|
135
|
+
if (!coop.value) {
|
|
87
136
|
await document.value.generate({
|
|
88
137
|
registry_id: Cooperative.Registry.CoopenomicsAgreement.registry_id,
|
|
89
138
|
coopname: 'voskhod',
|
|
90
139
|
username: session.username,
|
|
91
140
|
})
|
|
92
|
-
else
|
|
141
|
+
} else {
|
|
142
|
+
is_finish.value = true
|
|
143
|
+
currentStep.value = 4 // Переходим на последний шаг если кооператив уже создан
|
|
144
|
+
}
|
|
93
145
|
}
|
|
94
146
|
|
|
95
147
|
const sign = async() => {
|
|
96
148
|
await document.value.sign(session.username)
|
|
97
149
|
}
|
|
98
150
|
|
|
151
|
+
// Lifecycle хуки
|
|
152
|
+
onMounted(() => {
|
|
153
|
+
// Если провайдер доступен - делаем полную инициализацию
|
|
154
|
+
if (system.info.is_providered) {
|
|
155
|
+
init()
|
|
156
|
+
}
|
|
157
|
+
// Если провайдер недоступен - ничего не делаем, показываем заглушку
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
onUnmounted(() => {
|
|
161
|
+
// Останавливаем автообновление при размонтировании компонента
|
|
162
|
+
if (stopRefresh) {
|
|
163
|
+
stopRefresh()
|
|
164
|
+
stopRefresh = null
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
99
168
|
init()
|
|
100
169
|
|
|
101
170
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, withDefaults } from 'vue'
|
|
3
|
+
import type { IStepProps } from '../model/types'
|
|
4
|
+
import { DocumentHtmlReader } from 'src/shared/ui/DocumentHtmlReader'
|
|
5
|
+
import { Loader } from 'src/shared/ui/Loader'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<IStepProps & {
|
|
8
|
+
html?: string
|
|
9
|
+
onSign?: () => void
|
|
10
|
+
onBack?: () => void
|
|
11
|
+
}>(), {})
|
|
12
|
+
|
|
13
|
+
const emits = defineEmits<{
|
|
14
|
+
back: []
|
|
15
|
+
sign: []
|
|
16
|
+
}>()
|
|
17
|
+
|
|
18
|
+
const isActive = computed(() => props.isActive)
|
|
19
|
+
const isDone = computed(() => props.isDone)
|
|
20
|
+
|
|
21
|
+
const handleSign = () => {
|
|
22
|
+
emits('sign')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const handleBack = () => {
|
|
26
|
+
emits('back')
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template lang="pug">
|
|
31
|
+
q-step(
|
|
32
|
+
:name="2"
|
|
33
|
+
title="Соглашение о подключении"
|
|
34
|
+
icon="description"
|
|
35
|
+
:done="isDone"
|
|
36
|
+
)
|
|
37
|
+
.q-pa-md
|
|
38
|
+
template(v-if="html")
|
|
39
|
+
DocumentHtmlReader(:html="html")
|
|
40
|
+
template(v-else)
|
|
41
|
+
Loader(:text='`Готовим соглашение...`')
|
|
42
|
+
|
|
43
|
+
q-stepper-navigation.q-gutter-sm(v-if="html")
|
|
44
|
+
q-btn(
|
|
45
|
+
v-if="isActive"
|
|
46
|
+
color="grey-6"
|
|
47
|
+
flat
|
|
48
|
+
label="Назад"
|
|
49
|
+
@click="handleBack"
|
|
50
|
+
)
|
|
51
|
+
q-btn(
|
|
52
|
+
v-if="isActive"
|
|
53
|
+
color="primary"
|
|
54
|
+
label="Подписать"
|
|
55
|
+
@click="handleSign"
|
|
56
|
+
)
|
|
57
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { withDefaults } from 'vue'
|
|
3
|
+
import type { IStepProps } from '../model/types'
|
|
4
|
+
import { AddCooperativeForm } from 'src/features/Union/AddCooperative'
|
|
5
|
+
|
|
6
|
+
withDefaults(defineProps<IStepProps & {
|
|
7
|
+
signedDocument?: any
|
|
8
|
+
onFinish?: () => void
|
|
9
|
+
onBack?: () => void
|
|
10
|
+
}>(), {})
|
|
11
|
+
|
|
12
|
+
const emits = defineEmits<{
|
|
13
|
+
back: []
|
|
14
|
+
finish: []
|
|
15
|
+
}>()
|
|
16
|
+
|
|
17
|
+
const handleFinish = () => {
|
|
18
|
+
emits('finish')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const handleBack = () => {
|
|
22
|
+
emits('back')
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template lang="pug">
|
|
27
|
+
q-step(
|
|
28
|
+
:name="3"
|
|
29
|
+
title="Настройка кооператива"
|
|
30
|
+
icon="settings"
|
|
31
|
+
:done="isDone"
|
|
32
|
+
)
|
|
33
|
+
.q-pa-md
|
|
34
|
+
p.text-h6.q-mb-md Предварительная настройка
|
|
35
|
+
p.q-mb-md
|
|
36
|
+
| Пожалуйста, укажите домен для установки Цифрового Кооператива. Также, укажите суммы вступительных и минимальных паевых взносов для физических лиц, юридических лиц и индивидуальных предпринимателей:
|
|
37
|
+
|
|
38
|
+
AddCooperativeForm(
|
|
39
|
+
v-if="signedDocument"
|
|
40
|
+
:document="signedDocument"
|
|
41
|
+
@finish="handleFinish"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
q-stepper-navigation.q-gutter-sm(v-if="signedDocument")
|
|
45
|
+
q-btn(
|
|
46
|
+
color="grey-6"
|
|
47
|
+
flat
|
|
48
|
+
label="Назад"
|
|
49
|
+
@click="handleBack"
|
|
50
|
+
)
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, withDefaults, ref } from 'vue'
|
|
3
|
+
import type { IStepProps } from '../model/types'
|
|
4
|
+
import { TariffSelector, type ITariff } from '../Tariffs'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<IStepProps & {
|
|
7
|
+
onContinue?: () => void
|
|
8
|
+
}>(), {})
|
|
9
|
+
|
|
10
|
+
const emits = defineEmits<{
|
|
11
|
+
tariffSelected: [tariff: ITariff]
|
|
12
|
+
tariffDeselected: []
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const isActive = computed(() => props.isActive)
|
|
16
|
+
const isDone = computed(() => props.isDone)
|
|
17
|
+
|
|
18
|
+
const selectedTariff = ref<ITariff | null>(null)
|
|
19
|
+
|
|
20
|
+
const canContinue = computed(() => selectedTariff.value !== null)
|
|
21
|
+
|
|
22
|
+
const handleTariffSelected = (tariff: ITariff) => {
|
|
23
|
+
selectedTariff.value = tariff
|
|
24
|
+
emits('tariffSelected', tariff)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const handleTariffDeselected = () => {
|
|
28
|
+
selectedTariff.value = null
|
|
29
|
+
emits('tariffDeselected')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const handleContinue = () => {
|
|
33
|
+
if (canContinue.value && props.onContinue) {
|
|
34
|
+
props.onContinue()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template lang="pug">
|
|
40
|
+
q-step(
|
|
41
|
+
:name="1"
|
|
42
|
+
title="Выберите тариф"
|
|
43
|
+
icon="info"
|
|
44
|
+
:done="isDone"
|
|
45
|
+
)
|
|
46
|
+
.q-pa-md
|
|
47
|
+
|
|
48
|
+
TariffSelector(
|
|
49
|
+
:disabled="!isActive"
|
|
50
|
+
@tariff-selected="handleTariffSelected"
|
|
51
|
+
@tariff-deselected="handleTariffDeselected"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
q-stepper-navigation.q-gutter-sm
|
|
55
|
+
q-btn(
|
|
56
|
+
v-if="isActive"
|
|
57
|
+
color="primary"
|
|
58
|
+
:disable="!canContinue"
|
|
59
|
+
label="Продолжить"
|
|
60
|
+
@click="handleContinue"
|
|
61
|
+
)
|
|
62
|
+
</template>
|