@coopenomics/desktop 2025.11.11-alpha-1 → 2025.11.13-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/entities/ConnectionAgreement/api/index.ts +26 -0
- package/src/entities/ConnectionAgreement/index.ts +1 -0
- package/src/entities/ConnectionAgreement/model/store.ts +56 -3
- package/src/entities/ConnectionAgreement/model/types.ts +1 -0
- package/src/features/Provider/model/index.ts +2 -0
- package/src/features/Union/CooperativeDataForm/ui/CooperativeDataForm.vue +36 -11
- package/src/pages/Union/ConnectionAgreement/ConnectionAgreementPage.vue +79 -71
- package/src/widgets/ConnectionAgreementStepper/Steps/AgreementStep.vue +43 -2
- package/src/widgets/ConnectionAgreementStepper/Steps/ApprovalWaitingStep.vue +81 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/DomainValidationStep.vue +340 -107
- package/src/widgets/ConnectionAgreementStepper/Steps/FormStep.vue +5 -4
- package/src/widgets/ConnectionAgreementStepper/Steps/InstallationStep.vue +554 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/index.ts +2 -1
- package/src/widgets/ConnectionAgreementStepper/ui/ConnectionAgreementStepper.vue +8 -21
- package/src/widgets/ConnectionDashboard/index.ts +2 -0
- package/src/widgets/ConnectionDashboard/ui/ConnectionDashboard.vue +160 -0
- package/src/widgets/ConnectionDashboard/ui/index.ts +2 -0
- package/src/widgets/ConnectionAgreementStepper/Steps/WaitingStep.vue +0 -126
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopenomics/desktop",
|
|
3
|
-
"version": "2025.11.
|
|
3
|
+
"version": "2025.11.13-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.13-alpha-1",
|
|
29
|
+
"@coopenomics/notifications": "2025.11.13-alpha-1",
|
|
30
|
+
"@coopenomics/sdk": "2025.11.13-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.13-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": "d0f73c32bb68d8f7451ecef3989bdff4629d71c4"
|
|
127
127
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { client } from 'src/shared/api/client';
|
|
2
|
+
import { Queries } from '@coopenomics/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Тип текущего инстанса из GraphQL API
|
|
6
|
+
*/
|
|
7
|
+
export type CurrentInstance = Queries.System.GetCurrentInstance.IOutput[typeof Queries.System.GetCurrentInstance.name];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Получить текущий инстанс авторизованного пользователя
|
|
11
|
+
*/
|
|
12
|
+
export async function getCurrentInstance(): Promise<CurrentInstance | null> {
|
|
13
|
+
try {
|
|
14
|
+
const { [Queries.System.GetCurrentInstance.name]: instance } =
|
|
15
|
+
await client.Query(Queries.System.GetCurrentInstance.query);
|
|
16
|
+
|
|
17
|
+
return instance;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error('Ошибка при получении текущего инстанса:', error);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const api = {
|
|
25
|
+
getCurrentInstance
|
|
26
|
+
};
|
|
@@ -3,6 +3,7 @@ import { ref } from 'vue'
|
|
|
3
3
|
import { DigitalDocument } from 'src/shared/lib/document'
|
|
4
4
|
import { useSessionStore } from 'src/entities/Session'
|
|
5
5
|
import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives'
|
|
6
|
+
import { getCurrentInstance, type CurrentInstance } from '../api'
|
|
6
7
|
import type { ITariff, IConnectionAgreementState, ICooperativeFormData } from './types'
|
|
7
8
|
|
|
8
9
|
|
|
@@ -15,6 +16,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
15
16
|
const isInitialized = ref<boolean>(false)
|
|
16
17
|
const document = ref<any>(null)
|
|
17
18
|
const signedDocument = ref<any>(null)
|
|
19
|
+
const currentInstance = ref<CurrentInstance | null>(null)
|
|
20
|
+
const currentInstanceLoading = ref<boolean>(false)
|
|
21
|
+
const currentInstanceError = ref<string | null>(null)
|
|
22
|
+
const coop = ref<any>(null)
|
|
18
23
|
const formData = ref<ICooperativeFormData>({
|
|
19
24
|
announce: '',
|
|
20
25
|
initial: '',
|
|
@@ -44,6 +49,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
44
49
|
signedDocument.value = doc
|
|
45
50
|
}
|
|
46
51
|
|
|
52
|
+
const setCoop = (coopData: any) => {
|
|
53
|
+
coop.value = coopData
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
const setFormData = (data: ICooperativeFormData) => {
|
|
48
57
|
formData.value = data
|
|
49
58
|
}
|
|
@@ -113,20 +122,54 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
113
122
|
const session = useSessionStore()
|
|
114
123
|
|
|
115
124
|
try {
|
|
116
|
-
const
|
|
117
|
-
|
|
125
|
+
const coopData = await loadOneCooperative(session.username)
|
|
126
|
+
coop.value = coopData
|
|
127
|
+
return coopData
|
|
118
128
|
} catch (error) {
|
|
119
129
|
console.error('Ошибка при перезагрузке кооператива:', error)
|
|
120
130
|
throw error
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
133
|
|
|
134
|
+
const loadCurrentInstance = async () => {
|
|
135
|
+
try {
|
|
136
|
+
currentInstanceLoading.value = true
|
|
137
|
+
currentInstanceError.value = null
|
|
138
|
+
currentInstance.value = await getCurrentInstance()
|
|
139
|
+
console.log('Текущий инстанс загружен:', currentInstance.value)
|
|
140
|
+
} catch (error: any) {
|
|
141
|
+
currentInstanceError.value = error.message || 'Ошибка загрузки инстанса'
|
|
142
|
+
// Очищаем старые данные при ошибке - они больше не актуальны
|
|
143
|
+
currentInstance.value = null
|
|
144
|
+
console.error('Ошибка при загрузке текущего инстанса:', error)
|
|
145
|
+
} finally {
|
|
146
|
+
currentInstanceLoading.value = false
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const startInstanceAutoRefresh = (intervalMs = 30000) => { // 30 секунд по умолчанию
|
|
151
|
+
loadCurrentInstance() // Первая загрузка
|
|
152
|
+
|
|
153
|
+
const interval = setInterval(() => {
|
|
154
|
+
loadCurrentInstance()
|
|
155
|
+
}, intervalMs)
|
|
156
|
+
|
|
157
|
+
// Функция для остановки автообновления
|
|
158
|
+
const stop = () => clearInterval(interval)
|
|
159
|
+
|
|
160
|
+
return stop
|
|
161
|
+
}
|
|
162
|
+
|
|
124
163
|
const reset = () => {
|
|
125
164
|
currentStep.value = 1
|
|
126
165
|
selectedTariff.value = null
|
|
127
166
|
isInitialized.value = false
|
|
128
167
|
document.value = null
|
|
129
168
|
signedDocument.value = null
|
|
169
|
+
currentInstance.value = null
|
|
170
|
+
currentInstanceLoading.value = false
|
|
171
|
+
currentInstanceError.value = null
|
|
172
|
+
coop.value = null
|
|
130
173
|
formData.value = {
|
|
131
174
|
announce: '',
|
|
132
175
|
initial: '',
|
|
@@ -152,6 +195,9 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
152
195
|
if (state.signedDocument !== undefined) {
|
|
153
196
|
signedDocument.value = state.signedDocument
|
|
154
197
|
}
|
|
198
|
+
if (state.coop !== undefined) {
|
|
199
|
+
coop.value = state.coop
|
|
200
|
+
}
|
|
155
201
|
if (state.formData !== undefined && state.formData !== null) {
|
|
156
202
|
formData.value = state.formData
|
|
157
203
|
}
|
|
@@ -164,6 +210,10 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
164
210
|
isInitialized,
|
|
165
211
|
document,
|
|
166
212
|
signedDocument,
|
|
213
|
+
currentInstance,
|
|
214
|
+
currentInstanceLoading,
|
|
215
|
+
currentInstanceError,
|
|
216
|
+
coop,
|
|
167
217
|
formData,
|
|
168
218
|
|
|
169
219
|
// Methods
|
|
@@ -172,6 +222,7 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
172
222
|
setInitialized,
|
|
173
223
|
setDocument,
|
|
174
224
|
setSignedDocument,
|
|
225
|
+
setCoop,
|
|
175
226
|
setFormData,
|
|
176
227
|
reset,
|
|
177
228
|
initialize,
|
|
@@ -180,7 +231,9 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
|
|
|
180
231
|
generateDocument,
|
|
181
232
|
signDocument,
|
|
182
233
|
clearSignedDocument,
|
|
183
|
-
reloadCooperative
|
|
234
|
+
reloadCooperative,
|
|
235
|
+
loadCurrentInstance,
|
|
236
|
+
startInstanceAutoRefresh
|
|
184
237
|
}
|
|
185
238
|
}, {
|
|
186
239
|
persist: true
|
|
@@ -59,6 +59,7 @@ export function useProviderSubscriptions() {
|
|
|
59
59
|
*/
|
|
60
60
|
const loadSubscriptions = async () => {
|
|
61
61
|
// Проверяем доступность провайдера
|
|
62
|
+
console.log('system.info', system.info);
|
|
62
63
|
if (!system.info.is_providered) {
|
|
63
64
|
error.value = 'Функционал провайдера не доступен';
|
|
64
65
|
return;
|
|
@@ -68,6 +69,7 @@ export function useProviderSubscriptions() {
|
|
|
68
69
|
isLoading.value = true;
|
|
69
70
|
error.value = null;
|
|
70
71
|
subscriptions.value = await loadProviderSubscriptions();
|
|
72
|
+
console.log('subscriptions', subscriptions.value);
|
|
71
73
|
} catch (err: any) {
|
|
72
74
|
error.value = err.message || 'Ошибка загрузки подписок';
|
|
73
75
|
console.error('Error loading provider subscriptions:', err);
|
|
@@ -1,44 +1,69 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
div
|
|
3
3
|
Form(:handler-submit="saveData" :showCancel="false" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-gutter-md
|
|
4
|
-
q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="
|
|
4
|
+
q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="formData.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
|
|
5
5
|
|
|
6
|
-
q-input(standout="bg-teal text-white"
|
|
6
|
+
q-input(standout="bg-teal text-white" placeholder="100" label="Вступительный взнос для физлиц и ИП" v-model="formData.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
|
|
7
7
|
template(#append)
|
|
8
8
|
span.text-overline RUB
|
|
9
9
|
|
|
10
|
-
q-input(standout="bg-teal text-white" label="Минимальный паевый взнос для физлиц и ИП"
|
|
10
|
+
q-input(standout="bg-teal text-white" label="Минимальный паевый взнос для физлиц и ИП" placeholder="300" v-model="formData.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
|
|
11
11
|
template(#append)
|
|
12
12
|
span.text-overline RUB
|
|
13
13
|
|
|
14
|
-
q-input(standout="bg-teal text-white"
|
|
14
|
+
q-input(standout="bg-teal text-white" placeholder="1000" label="Вступительный взнос для организаций" v-model="formData.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
|
|
15
15
|
template(#append)
|
|
16
16
|
span.text-overline RUB
|
|
17
17
|
|
|
18
|
-
q-input(standout="bg-teal text-white"
|
|
18
|
+
q-input(standout="bg-teal text-white" placeholder="3000" label="Минимальный паевый взнос для организаций" v-model="formData.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
|
|
19
19
|
template(#append)
|
|
20
20
|
span.text-overline RUB
|
|
21
21
|
</template>
|
|
22
22
|
<script lang="ts" setup>
|
|
23
|
+
import { ref, watch } from 'vue'
|
|
23
24
|
import { Form } from 'src/shared/ui/Form';
|
|
24
25
|
import { notEmpty, isDomain } from 'src/shared/lib/utils';
|
|
25
26
|
import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
|
|
27
|
+
import type { ICooperativeFormData } from 'src/entities/ConnectionAgreement/model/types';
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
const emit = defineEmits(['continue'])
|
|
29
31
|
|
|
30
32
|
const connectionAgreement = useConnectionAgreementStore()
|
|
31
33
|
|
|
32
|
-
//
|
|
34
|
+
// Локальное состояние формы для избежания проблем с реактивностью
|
|
35
|
+
const formData = ref<ICooperativeFormData>({
|
|
36
|
+
announce: connectionAgreement.formData.announce || '',
|
|
37
|
+
initial: connectionAgreement.formData.initial || '',
|
|
38
|
+
minimum: connectionAgreement.formData.minimum || '',
|
|
39
|
+
org_initial: connectionAgreement.formData.org_initial || '',
|
|
40
|
+
org_minimum: connectionAgreement.formData.org_minimum || ''
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// Синхронизируем локальное состояние с изменениями в store
|
|
44
|
+
watch(() => connectionAgreement.formData, (newFormData) => {
|
|
45
|
+
formData.value = {
|
|
46
|
+
announce: newFormData.announce || '',
|
|
47
|
+
initial: newFormData.initial || '',
|
|
48
|
+
minimum: newFormData.minimum || '',
|
|
49
|
+
org_initial: newFormData.org_initial || '',
|
|
50
|
+
org_minimum: newFormData.org_minimum || ''
|
|
51
|
+
}
|
|
52
|
+
}, { deep: true })
|
|
53
|
+
|
|
54
|
+
// Синхронизируем локальное состояние с store при изменении
|
|
55
|
+
const syncFormData = () => {
|
|
56
|
+
connectionAgreement.setFormData(formData.value)
|
|
57
|
+
}
|
|
33
58
|
|
|
34
59
|
const clear = () => {
|
|
35
60
|
emit('continue')
|
|
36
61
|
}
|
|
37
62
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
emit('continue',
|
|
63
|
+
const saveData = async () => {
|
|
64
|
+
console.log('📤 CooperativeDataForm: Данные формы:', formData.value)
|
|
65
|
+
// Синхронизируем данные с store перед отправкой
|
|
66
|
+
syncFormData()
|
|
67
|
+
emit('continue', formData.value)
|
|
43
68
|
}
|
|
44
69
|
</script>
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
div.row.q-pa-md
|
|
3
3
|
div.col-md-12.col-xs-12
|
|
4
4
|
div(v-if="system.info.is_providered")
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
:instance-status="instanceStatus"
|
|
10
|
-
:subscriptions-loading="subscriptionsLoading"
|
|
11
|
-
:subscriptions-error="subscriptionsError"
|
|
5
|
+
|
|
6
|
+
//- Показываем дашборд если установка завершена
|
|
7
|
+
ConnectionDashboard(
|
|
8
|
+
v-if="isInstallationCompleted"
|
|
12
9
|
)
|
|
13
10
|
|
|
11
|
+
//- Показываем степпер если установка не завершена
|
|
12
|
+
ConnectionAgreementStepper(v-else)
|
|
13
|
+
|
|
14
|
+
|
|
14
15
|
div(v-else).row
|
|
15
16
|
//- Заглушка для недоступного провайдера
|
|
16
17
|
div.col-md-12.col-xs-12
|
|
@@ -28,44 +29,35 @@ div.row.q-pa-md
|
|
|
28
29
|
|
|
29
30
|
</template>
|
|
30
31
|
<script setup lang="ts">
|
|
31
|
-
import {
|
|
32
|
-
import { useSessionStore } from 'src/entities/Session';
|
|
32
|
+
import { computed, onMounted, onUnmounted, watch } from 'vue';
|
|
33
33
|
import { useSystemStore } from 'src/entities/System/model';
|
|
34
34
|
import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
|
|
35
|
-
import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives';
|
|
36
|
-
import { useProviderSubscriptions } from 'src/features/Provider';
|
|
37
35
|
import { ConnectionAgreementStepper } from 'src/widgets/ConnectionAgreementStepper';
|
|
36
|
+
import { ConnectionDashboard } from 'src/widgets/ConnectionDashboard';
|
|
38
37
|
import { ColorCard } from 'src/shared/ui';
|
|
38
|
+
import {Zeus} from '@coopenomics/sdk';
|
|
39
39
|
|
|
40
|
-
const session = useSessionStore()
|
|
41
40
|
const system = useSystemStore()
|
|
42
41
|
const connectionAgreement = useConnectionAgreementStore()
|
|
43
|
-
const { loadOneCooperative } = useLoadCooperatives()
|
|
44
|
-
const {
|
|
45
|
-
domainValid,
|
|
46
|
-
installationProgress,
|
|
47
|
-
instanceStatus,
|
|
48
|
-
isLoading: subscriptionsLoading,
|
|
49
|
-
error: subscriptionsError,
|
|
50
|
-
startAutoRefresh
|
|
51
|
-
} = useProviderSubscriptions()
|
|
52
|
-
|
|
53
|
-
const coop = ref()
|
|
54
42
|
|
|
55
43
|
// Остановка автообновления при размонтировании компонента
|
|
56
|
-
let
|
|
44
|
+
let stopInstanceRefresh: (() => void) | null = null
|
|
45
|
+
|
|
46
|
+
// Проверка завершения установки
|
|
47
|
+
const isInstallationCompleted = computed(() => {
|
|
48
|
+
// Не показываем поздравление если идет загрузка или есть ошибка
|
|
49
|
+
if (connectionAgreement.currentInstanceLoading || connectionAgreement.currentInstanceError) {
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const instance = connectionAgreement.currentInstance
|
|
54
|
+
return instance?.progress === 100 && instance?.status === Zeus.InstanceStatus.ACTIVE
|
|
55
|
+
})
|
|
57
56
|
|
|
58
57
|
const openProviderWebsite = () => {
|
|
59
58
|
window.open('https://цифровой-кооператив.рф', '_blank')
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
// Загружаем кооператив
|
|
63
|
-
const loadCooperative = async () => {
|
|
64
|
-
if (system.info.is_providered) {
|
|
65
|
-
coop.value = await loadOneCooperative(session.username)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
61
|
const init = async () => {
|
|
70
62
|
// Инициализация имеет смысл только если провайдер доступен
|
|
71
63
|
if (!system.info.is_providered) return
|
|
@@ -75,41 +67,63 @@ const init = async () => {
|
|
|
75
67
|
connectionAgreement.setInitialized(true)
|
|
76
68
|
}
|
|
77
69
|
|
|
78
|
-
// Загружаем кооператив
|
|
79
|
-
await loadCooperative()
|
|
80
|
-
|
|
81
|
-
// Если кооператив существует, инициализируем данные формы из него
|
|
82
|
-
if (coop.value) {
|
|
83
|
-
const formData = {
|
|
84
|
-
announce: coop.value.announce || '',
|
|
85
|
-
initial: parseFloat(coop.value.initial || '0').toString(),
|
|
86
|
-
minimum: parseFloat(coop.value.minimum || '0').toString(),
|
|
87
|
-
org_initial: parseFloat(coop.value.org_initial || '0').toString(),
|
|
88
|
-
org_minimum: parseFloat(coop.value.org_minimum || '0').toString()
|
|
89
|
-
}
|
|
90
|
-
connectionAgreement.setFormData(formData)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const finish = () => {
|
|
95
|
-
// Эта функция имеет смысл только если провайдер доступен
|
|
96
|
-
if (!system.info.is_providered) return
|
|
97
70
|
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
stopRefresh = startAutoRefresh(60000) // 1 минута
|
|
101
|
-
}
|
|
71
|
+
// Загружаем текущий инстанс
|
|
72
|
+
await connectionAgreement.loadCurrentInstance()
|
|
102
73
|
|
|
103
|
-
//
|
|
104
|
-
connectionAgreement.
|
|
74
|
+
// Запускаем автообновление инстанса каждые 30 секунд
|
|
75
|
+
stopInstanceRefresh = connectionAgreement.startInstanceAutoRefresh(30000)
|
|
105
76
|
}
|
|
106
77
|
|
|
107
|
-
// Watch за изменением
|
|
108
|
-
watch(() => connectionAgreement.
|
|
109
|
-
|
|
110
|
-
|
|
78
|
+
// Watch за изменением currentInstance для автоматического перехода между шагами
|
|
79
|
+
watch(() => connectionAgreement.currentInstance, (instance) => {
|
|
80
|
+
// Не обрабатываем изменения если идет загрузка или есть ошибка
|
|
81
|
+
if (connectionAgreement.currentInstanceLoading || connectionAgreement.currentInstanceError) {
|
|
82
|
+
return
|
|
111
83
|
}
|
|
112
|
-
|
|
84
|
+
|
|
85
|
+
if (!instance) return
|
|
86
|
+
|
|
87
|
+
const currentStep = connectionAgreement.currentStep
|
|
88
|
+
|
|
89
|
+
console.log('📊 Instance обновлен:', {
|
|
90
|
+
step: currentStep,
|
|
91
|
+
is_valid: instance.is_valid,
|
|
92
|
+
is_delegated: instance.is_delegated,
|
|
93
|
+
blockchain_status: instance.blockchain_status,
|
|
94
|
+
progress: instance.progress,
|
|
95
|
+
status: instance.status
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Логика автоматических переходов (только для шагов 4, 5, 6)
|
|
99
|
+
if (currentStep === 4) {
|
|
100
|
+
// Шаг 4: Проверка домена
|
|
101
|
+
if (instance.is_valid && instance.is_delegated) {
|
|
102
|
+
// Домен валиден и делегирован
|
|
103
|
+
if (instance.blockchain_status === 'active') {
|
|
104
|
+
// Можно переходить сразу к установке
|
|
105
|
+
console.log('✅ Домен готов и blockchain_status активен → переход к шагу 6')
|
|
106
|
+
connectionAgreement.setCurrentStep(6)
|
|
107
|
+
} else {
|
|
108
|
+
// Ожидаем подтверждения от союза
|
|
109
|
+
console.log('⏳ Домен готов, но ожидаем подтверждения → переход к шагу 5')
|
|
110
|
+
connectionAgreement.setCurrentStep(5)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else if (currentStep === 5) {
|
|
114
|
+
// Шаг 5: Ожидание подтверждения от союза
|
|
115
|
+
if (instance.blockchain_status === 'active') {
|
|
116
|
+
console.log('✅ Подтверждение получено → переход к шагу 6')
|
|
117
|
+
connectionAgreement.setCurrentStep(6)
|
|
118
|
+
}
|
|
119
|
+
} else if (currentStep === 6) {
|
|
120
|
+
// Шаг 6: Установка
|
|
121
|
+
if (instance.progress === 100 && instance.status === Zeus.InstanceStatus.ACTIVE) {
|
|
122
|
+
console.log('🎉 Установка завершена!')
|
|
123
|
+
// Не переходим автоматически, просто покажется дашборд через computed
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, { deep: true })
|
|
113
127
|
|
|
114
128
|
// Lifecycle хуки
|
|
115
129
|
onMounted(() => {
|
|
@@ -121,16 +135,10 @@ onMounted(() => {
|
|
|
121
135
|
})
|
|
122
136
|
|
|
123
137
|
onUnmounted(() => {
|
|
124
|
-
// Останавливаем автообновление при размонтировании компонента
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
// Останавливаем автообновление инстанса при размонтировании компонента
|
|
139
|
+
if (stopInstanceRefresh) {
|
|
140
|
+
stopInstanceRefresh()
|
|
141
|
+
stopInstanceRefresh = null
|
|
128
142
|
}
|
|
129
143
|
})
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Здесь необходимо получить соглашение для подключения и проверить заполнено ли оно.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*/
|
|
136
144
|
</script>
|
|
@@ -4,6 +4,8 @@ import type { IStepProps } from '../model/types'
|
|
|
4
4
|
import { DocumentHtmlReader } from 'src/shared/ui/DocumentHtmlReader'
|
|
5
5
|
import { Loader } from 'src/shared/ui/Loader'
|
|
6
6
|
import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
|
|
7
|
+
import { useAddCooperative } from 'src/features/Union/AddCooperative/model'
|
|
8
|
+
import { useSessionStore } from 'src/entities/Session'
|
|
7
9
|
|
|
8
10
|
const props = withDefaults(defineProps<IStepProps & {
|
|
9
11
|
html?: string
|
|
@@ -16,13 +18,52 @@ const isDone = computed(() => props.isDone)
|
|
|
16
18
|
|
|
17
19
|
const handleSign = async () => {
|
|
18
20
|
try {
|
|
21
|
+
console.log('📝 AgreementStep: Подписываем документ')
|
|
19
22
|
await connectionAgreement.signDocument()
|
|
20
|
-
|
|
23
|
+
|
|
24
|
+
console.log('🔗 AgreementStep: Отправляем транзакцию registerCooperative в блокчейн')
|
|
25
|
+
const { addCooperative } = useAddCooperative()
|
|
26
|
+
const session = useSessionStore()
|
|
27
|
+
|
|
28
|
+
// Формируем данные для registerCooperative действия
|
|
29
|
+
const registerData = {
|
|
30
|
+
coopname: session.username,
|
|
31
|
+
params: {
|
|
32
|
+
is_cooperative: true,
|
|
33
|
+
coop_type: 'conscoop',
|
|
34
|
+
announce: connectionAgreement.formData.announce,
|
|
35
|
+
description: '',
|
|
36
|
+
initial: connectionAgreement.formData.initial,
|
|
37
|
+
minimum: connectionAgreement.formData.minimum,
|
|
38
|
+
org_initial: connectionAgreement.formData.org_initial,
|
|
39
|
+
org_minimum: connectionAgreement.formData.org_minimum
|
|
40
|
+
},
|
|
41
|
+
username: session.username,
|
|
42
|
+
document: connectionAgreement.signedDocument
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Отправляем данные формы в блокчейн
|
|
46
|
+
await addCooperative(registerData)
|
|
47
|
+
|
|
48
|
+
console.log('✅ AgreementStep: Транзакция успешно отправлена')
|
|
49
|
+
|
|
50
|
+
// Обновляем информацию о кооперативе из блокчейна
|
|
51
|
+
console.log('🔄 AgreementStep: Обновляем информацию о кооперативе')
|
|
52
|
+
await connectionAgreement.reloadCooperative()
|
|
53
|
+
|
|
54
|
+
// Обновляем информацию об инстансе
|
|
55
|
+
console.log('🔄 AgreementStep: Обновляем информацию об инстансе')
|
|
56
|
+
await connectionAgreement.loadCurrentInstance()
|
|
57
|
+
|
|
58
|
+
console.log('✅ AgreementStep: Информация обновлена')
|
|
59
|
+
|
|
60
|
+
// Переходим к следующему шагу после подписания и отправки в блокчейн
|
|
21
61
|
if (connectionAgreement.currentStep < 5) {
|
|
22
62
|
connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
|
|
23
63
|
}
|
|
24
64
|
} catch (error) {
|
|
25
|
-
console.error('Ошибка
|
|
65
|
+
console.error('❌ Ошибка при подписании или отправке в блокчейн:', error)
|
|
66
|
+
throw error
|
|
26
67
|
}
|
|
27
68
|
}
|
|
28
69
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
q-step(
|
|
3
|
+
:name="5"
|
|
4
|
+
title="Ожидание подтверждения"
|
|
5
|
+
icon="schedule"
|
|
6
|
+
:done="isDone"
|
|
7
|
+
)
|
|
8
|
+
.q-pa-md
|
|
9
|
+
//- Успех - готово к установке
|
|
10
|
+
.flex.column.items-center.q-pa-lg
|
|
11
|
+
q-icon(name="check_circle" color="positive" size="64px").q-mb-md
|
|
12
|
+
.text-h6.text-center.q-mb-md Техническая подготовка завершена
|
|
13
|
+
.text-body1.text-center.text-grey-7.q-mb-xl
|
|
14
|
+
| Ваш кооператив готов к установке
|
|
15
|
+
|
|
16
|
+
//- Информационная карточка
|
|
17
|
+
q-card(flat).q-mb-lg.bg-grey-1
|
|
18
|
+
q-card-section.q-pa-lg
|
|
19
|
+
.text-subtitle2.q-mb-md.text-weight-medium Ожидание подтверждения
|
|
20
|
+
.text-body2.text-grey-8.q-mb-lg
|
|
21
|
+
| Все готово к установке, но мы ожидаем поступления подтверждения от союза о вашем членстве.
|
|
22
|
+
|
|
23
|
+
.text-body2.text-grey-7.q-mb-md
|
|
24
|
+
| Как только союз подтвердит ваше членство, статус изменится автоматически и установка начнется.
|
|
25
|
+
|
|
26
|
+
.text-body2.text-grey-7
|
|
27
|
+
| Приблизительное время установки после получения подтверждения:
|
|
28
|
+
strong.text-primary 60 минут
|
|
29
|
+
|
|
30
|
+
//- Статус подтверждения
|
|
31
|
+
.flex.justify-center.q-mb-lg
|
|
32
|
+
q-chip(
|
|
33
|
+
:color="getBlockchainStatusColor"
|
|
34
|
+
text-color="white"
|
|
35
|
+
size="md"
|
|
36
|
+
:icon="instance?.blockchain_status === 'active' ? 'check_circle' : 'schedule'"
|
|
37
|
+
)
|
|
38
|
+
span {{ getBlockchainStatusText }}
|
|
39
|
+
|
|
40
|
+
//- Навигация
|
|
41
|
+
q-stepper-navigation.q-gutter-sm
|
|
42
|
+
q-btn(
|
|
43
|
+
color="grey-6"
|
|
44
|
+
flat
|
|
45
|
+
label="Назад"
|
|
46
|
+
@click="handleBack"
|
|
47
|
+
)
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<script setup lang="ts">
|
|
51
|
+
import { computed, withDefaults } from 'vue'
|
|
52
|
+
import type { IStepProps } from '../model/types'
|
|
53
|
+
import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
|
|
54
|
+
|
|
55
|
+
const props = withDefaults(defineProps<IStepProps>(), {})
|
|
56
|
+
|
|
57
|
+
const connectionAgreement = useConnectionAgreementStore()
|
|
58
|
+
|
|
59
|
+
// Получаем данные напрямую из store
|
|
60
|
+
const instance = computed(() => connectionAgreement.currentInstance)
|
|
61
|
+
|
|
62
|
+
const isDone = computed(() => props.isDone)
|
|
63
|
+
|
|
64
|
+
// Цвет статуса блокчейна
|
|
65
|
+
const getBlockchainStatusColor = computed(() => {
|
|
66
|
+
if (instance.value?.blockchain_status === 'active') return 'positive'
|
|
67
|
+
return 'info'
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// Текст статуса блокчейна
|
|
71
|
+
const getBlockchainStatusText = computed(() => {
|
|
72
|
+
if (instance.value?.blockchain_status === 'active') return 'Подтверждено'
|
|
73
|
+
if (instance.value?.blockchain_status === 'pending') return 'Ожидание подтверждения'
|
|
74
|
+
return 'Не подтверждено'
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const handleBack = () => {
|
|
78
|
+
connectionAgreement.setCurrentStep(2)
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|