@coopenomics/desktop 2025.11.10-alpha-3 → 2025.11.11-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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coopenomics/desktop",
3
- "version": "2025.11.10-alpha-3",
3
+ "version": "2025.11.11-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.10-alpha-3",
29
- "@coopenomics/notifications": "2025.11.10-alpha-3",
30
- "@coopenomics/sdk": "2025.11.10-alpha-3",
28
+ "@coopenomics/controller": "2025.11.11-alpha-1",
29
+ "@coopenomics/notifications": "2025.11.11-alpha-1",
30
+ "@coopenomics/sdk": "2025.11.11-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.10-alpha-3",
62
+ "cooptypes": "2025.11.11-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": "637950d37f74f959a640d61891ef35d0ace9b858"
126
+ "gitHead": "5b3c9c90552b081e0a4532048329454c0e43132a"
127
127
  }
@@ -1,6 +1,9 @@
1
1
  import { defineStore } from 'pinia'
2
2
  import { ref } from 'vue'
3
- import type { ITariff, IConnectionAgreementState } from './types'
3
+ import { DigitalDocument } from 'src/shared/lib/document'
4
+ import { useSessionStore } from 'src/entities/Session'
5
+ import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives'
6
+ import type { ITariff, IConnectionAgreementState, ICooperativeFormData } from './types'
4
7
 
5
8
 
6
9
  const namespace = 'connection-agreement'
@@ -12,6 +15,13 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
12
15
  const isInitialized = ref<boolean>(false)
13
16
  const document = ref<any>(null)
14
17
  const signedDocument = ref<any>(null)
18
+ const formData = ref<ICooperativeFormData>({
19
+ announce: '',
20
+ initial: '',
21
+ minimum: '',
22
+ org_initial: '',
23
+ org_minimum: ''
24
+ })
15
25
 
16
26
  // Methods
17
27
  const setCurrentStep = (step: number) => {
@@ -34,12 +44,96 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
34
44
  signedDocument.value = doc
35
45
  }
36
46
 
47
+ const setFormData = (data: ICooperativeFormData) => {
48
+ formData.value = data
49
+ }
50
+
51
+ // Actions
52
+ const generateDocument = async () => {
53
+ console.log('🔄 Начинаем генерацию документа')
54
+ const session = useSessionStore()
55
+ const formDataValue = formData.value
56
+ console.log('📋 Данные формы:', formDataValue)
57
+
58
+ try {
59
+ console.log('📄 Создаем новый DigitalDocument')
60
+ const newDoc = new DigitalDocument()
61
+
62
+ const params: any = {
63
+ registry_id: 50,
64
+ coopname: 'voskhod',
65
+ username: session.username
66
+ }
67
+
68
+ // Передаем данные из формы в документ, если они есть
69
+ if (formDataValue) {
70
+ params.announce = formDataValue.announce
71
+ params.initial = formDataValue.initial
72
+ params.minimum = formDataValue.minimum
73
+ params.org_initial = formDataValue.org_initial
74
+ params.org_minimum = formDataValue.org_minimum
75
+ }
76
+
77
+ console.log('🔧 Генерируем документ с параметрами:', params)
78
+
79
+ await newDoc.generate(params)
80
+
81
+ console.log('✅ Документ успешно сгенерирован')
82
+ document.value = newDoc
83
+ return newDoc
84
+ } catch (error) {
85
+ console.error('❌ Ошибка при генерации документа:', error)
86
+ throw error
87
+ }
88
+ }
89
+
90
+ const signDocument = async () => {
91
+ const session = useSessionStore()
92
+ if (!document.value) {
93
+ throw new Error('Документ не найден')
94
+ }
95
+
96
+ await document.value.sign(session.username)
97
+ signedDocument.value = document.value.signedDocument
98
+ return signedDocument.value
99
+ }
100
+
101
+ const clearSignedDocument = async () => {
102
+ // Очищаем подписанный документ
103
+ signedDocument.value = null
104
+
105
+ // Регенерируем документ заново если есть данные формы
106
+ if (formData.value) {
107
+ await generateDocument()
108
+ }
109
+ }
110
+
111
+ const reloadCooperative = async () => {
112
+ const { loadOneCooperative } = useLoadCooperatives()
113
+ const session = useSessionStore()
114
+
115
+ try {
116
+ const coop = await loadOneCooperative(session.username)
117
+ return coop
118
+ } catch (error) {
119
+ console.error('Ошибка при перезагрузке кооператива:', error)
120
+ throw error
121
+ }
122
+ }
123
+
37
124
  const reset = () => {
38
125
  currentStep.value = 1
39
126
  selectedTariff.value = null
40
127
  isInitialized.value = false
41
128
  document.value = null
42
129
  signedDocument.value = null
130
+ formData.value = {
131
+ announce: '',
132
+ initial: '',
133
+ minimum: '',
134
+ org_initial: '',
135
+ org_minimum: ''
136
+ }
43
137
  }
44
138
 
45
139
  const initialize = (state: Partial<IConnectionAgreementState>) => {
@@ -58,6 +152,9 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
58
152
  if (state.signedDocument !== undefined) {
59
153
  signedDocument.value = state.signedDocument
60
154
  }
155
+ if (state.formData !== undefined && state.formData !== null) {
156
+ formData.value = state.formData
157
+ }
61
158
  }
62
159
 
63
160
  return {
@@ -67,6 +164,7 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
67
164
  isInitialized,
68
165
  document,
69
166
  signedDocument,
167
+ formData,
70
168
 
71
169
  // Methods
72
170
  setCurrentStep,
@@ -74,8 +172,15 @@ export const useConnectionAgreementStore = defineStore(namespace, () => {
74
172
  setInitialized,
75
173
  setDocument,
76
174
  setSignedDocument,
175
+ setFormData,
77
176
  reset,
78
- initialize
177
+ initialize,
178
+
179
+ // Actions
180
+ generateDocument,
181
+ signDocument,
182
+ clearSignedDocument,
183
+ reloadCooperative
79
184
  }
80
185
  }, {
81
186
  persist: true
@@ -7,10 +7,19 @@ export interface ITariff {
7
7
  additionalCosts?: string[]
8
8
  }
9
9
 
10
+ export interface ICooperativeFormData {
11
+ announce: string
12
+ initial: string
13
+ minimum: string
14
+ org_initial: string
15
+ org_minimum: string
16
+ }
17
+
10
18
  export interface IConnectionAgreementState {
11
19
  currentStep: number
12
20
  selectedTariff: ITariff | null
13
21
  isInitialized: boolean
14
22
  document?: any
15
23
  signedDocument?: any
16
- }
24
+ formData?: ICooperativeFormData
25
+ }
@@ -10,6 +10,7 @@ export interface HostingSubscriptionData {
10
10
  subscription_type_id: 1;
11
11
  progress: number;
12
12
  is_valid: boolean;
13
+ is_delegated: boolean;
13
14
  }
14
15
 
15
16
  /**
@@ -39,7 +40,7 @@ export function useProviderSubscriptions() {
39
40
  // Статус валидности домена для хостинг подписки (из specific_data)
40
41
  const domainValid = computed(() => {
41
42
  const specificData = hostingSubscription.value?.specific_data as SubscriptionSpecificData;
42
- return specificData?.is_valid ?? null;
43
+ return (specificData?.is_valid && specificData?.is_delegated) ?? null;
43
44
  });
44
45
 
45
46
  // Прогресс установки для хостинг подписки (из specific_data)
@@ -1,29 +1,34 @@
1
1
  <template lang="pug">
2
- Form(:handler-submit="addNow" :is-submitting="isSubmitting" :showCancel="false" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-gutter-md
3
- //- q-input(standout="bg-teal text-white" label="Имя аккаунта" v-model="data.coopname" :rules="[val => notEmpty(val)]")
4
- q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="data.params.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
5
-
6
- q-input(standout="bg-teal text-white" hint="100 RUB" label="Вступительный взнос для физлиц и ИП" v-model="data.params.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
7
- template(#append)
8
- span.text-overline {{currency}}
9
-
10
- q-input(standout="bg-teal text-white" hint="300 RUB" label="Минимальный паевый взнос для физлиц и ИП" v-model="data.params.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
11
- template(#append)
12
- span.text-overline {{currency}}
13
-
14
- q-input(standout="bg-teal text-white" hint="1000 RUB" label="Вступительный взнос для организаций" v-model="data.params.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
15
- template(#append)
16
- span.text-overline {{currency}}
17
-
18
- q-input(standout="bg-teal text-white" hint="3000 RUB" label="Минимальный паевый взнос для организаций" v-model="data.params.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
19
- template(#append)
20
- span.text-overline {{currency}}
2
+ div
3
+ template(v-if="isSubmitting")
4
+ Loader(:text="'Создаем кооператив...'")
5
+ template(v-else)
6
+ Form(:handler-submit="addNow" :showCancel="false" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-gutter-md
7
+ //- q-input(standout="bg-teal text-white" label="Имя аккаунта" v-model="data.coopname" :rules="[val => notEmpty(val)]")
8
+ q-input(standout="bg-teal text-white" hint="domovoy.com или coop.domovoy.com" label="Домен или поддомен для запуска" v-model="data.params.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
9
+
10
+ q-input(standout="bg-teal text-white" hint="100 RUB" label="Вступительный взнос для физлиц и ИП" v-model="data.params.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
11
+ template(#append)
12
+ span.text-overline {{currency}}
13
+
14
+ q-input(standout="bg-teal text-white" hint="Минимальный паевый взнос для физлиц и ИП" v-model="data.params.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
15
+ template(#append)
16
+ span.text-overline {{currency}}
17
+
18
+ q-input(standout="bg-teal text-white" hint="1000 RUB" label="Вступительный взнос для организаций" v-model="data.params.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
19
+ template(#append)
20
+ span.text-overline {{currency}}
21
+
22
+ q-input(standout="bg-teal text-white" hint="3000 RUB" label="Минимальный паевый взнос для организаций" v-model="data.params.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
23
+ template(#append)
24
+ span.text-overline {{currency}}
21
25
 
22
26
  </template>
23
27
  <script lang="ts" setup>
24
28
  import { computed, ref, watch } from 'vue';
25
29
  import { useAddCooperative } from '../model';
26
30
  import { Form } from 'src/shared/ui/Form';
31
+ import { Loader } from 'src/shared/ui';
27
32
  import { notEmpty, isDomain } from 'src/shared/lib/utils';
28
33
  import { useSessionStore } from 'src/entities/Session';
29
34
  import { RegistratorContract } from 'cooptypes';
@@ -106,13 +111,17 @@ const clear = () => {
106
111
 
107
112
  const addNow = async () => {
108
113
  try {
114
+ isSubmitting.value = true
109
115
  data.value.document = {...document.value, meta: JSON.stringify(document.value.meta)}
110
116
  await addCooperative(data.value)
111
- SuccessAlert('Документ подписан и отправлен')
117
+ SuccessAlert('Заявка на создание кооператива отправлена!')
112
118
 
119
+ // После успешной отправки переходим к следующему шагу
113
120
  clear()
114
121
  } catch(e: any){
115
122
  FailAlert(e)
123
+ } finally {
124
+ isSubmitting.value = false
116
125
  }
117
126
  }
118
127
 
@@ -0,0 +1 @@
1
+ export * from './ui'
@@ -0,0 +1,44 @@
1
+ <template lang="pug">
2
+ div
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="connectionAgreement.formData.announce" :rules="[val => notEmpty(val), val => isDomain(val)]")
5
+
6
+ q-input(standout="bg-teal text-white" hint="100 RUB" label="Вступительный взнос для физлиц и ИП" v-model="connectionAgreement.formData.initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
7
+ template(#append)
8
+ span.text-overline RUB
9
+
10
+ q-input(standout="bg-teal text-white" label="Минимальный паевый взнос для физлиц и ИП" hint="300 RUB" v-model="connectionAgreement.formData.minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
11
+ template(#append)
12
+ span.text-overline RUB
13
+
14
+ q-input(standout="bg-teal text-white" hint="1000 RUB" label="Вступительный взнос для организаций" v-model="connectionAgreement.formData.org_initial" type="number" :min="0" :rules="[val => notEmpty(val)]")
15
+ template(#append)
16
+ span.text-overline RUB
17
+
18
+ q-input(standout="bg-teal text-white" hint="3000 RUB" label="Минимальный паевый взнос для организаций" v-model="connectionAgreement.formData.org_minimum" type="number" :min="0" :rules="[val => notEmpty(val)]")
19
+ template(#append)
20
+ span.text-overline RUB
21
+ </template>
22
+ <script lang="ts" setup>
23
+ import { Form } from 'src/shared/ui/Form';
24
+ import { notEmpty, isDomain } from 'src/shared/lib/utils';
25
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
26
+
27
+
28
+ const emit = defineEmits(['continue'])
29
+
30
+ const connectionAgreement = useConnectionAgreementStore()
31
+
32
+ // Данные напрямую из стора (уже инициализированы с дефолтными значениями)
33
+
34
+ const clear = () => {
35
+ emit('continue')
36
+ }
37
+
38
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
+ const saveData = async (e?: Event) => {
40
+ console.log('📤 CooperativeDataForm: Данные формы:', connectionAgreement.formData)
41
+ // Данные уже сохранены в сторе напрямую
42
+ emit('continue', connectionAgreement.formData)
43
+ }
44
+ </script>
@@ -0,0 +1 @@
1
+ export { default as CooperativeDataForm } from './CooperativeDataForm.vue'
@@ -3,26 +3,12 @@ div.row.q-pa-md
3
3
  div.col-md-12.col-xs-12
4
4
  div(v-if="system.info.is_providered")
5
5
  ConnectionAgreementStepper(
6
- :initial-step="currentStep"
7
- :is-finish="currentStep >= 5"
8
- :document="document"
9
- :signed-document="signedDocument"
10
6
  :coop="coop"
11
- :html="html"
12
7
  :domain-valid="domainValid"
13
8
  :installation-progress="installationProgress"
14
9
  :instance-status="instanceStatus"
15
10
  :subscriptions-loading="subscriptionsLoading"
16
11
  :subscriptions-error="subscriptionsError"
17
- :selected-tariff="connectionAgreement.selectedTariff"
18
- @step-change="handleStepChange"
19
- @clear-signed-document="handleClearSignedDocument"
20
- @tariff-selected="handleTariffSelected"
21
- @tariff-deselected="handleTariffDeselected"
22
- @continue="handleContinue"
23
- @sign="sign"
24
- @finish="finish"
25
- @reload="reload"
26
12
  )
27
13
 
28
14
  div(v-else).row
@@ -42,22 +28,19 @@ div.row.q-pa-md
42
28
 
43
29
  </template>
44
30
  <script setup lang="ts">
45
- import { DigitalDocument } from 'src/shared/lib/document';
31
+ import { ref, onMounted, onUnmounted, watch } from 'vue';
46
32
  import { useSessionStore } from 'src/entities/Session';
47
33
  import { useSystemStore } from 'src/entities/System/model';
48
34
  import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement';
49
- import { computed, ref, onMounted, onUnmounted } from 'vue';
50
35
  import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives';
51
36
  import { useProviderSubscriptions } from 'src/features/Provider';
52
- import { Cooperative } from 'cooptypes';
53
37
  import { ConnectionAgreementStepper } from 'src/widgets/ConnectionAgreementStepper';
54
38
  import { ColorCard } from 'src/shared/ui';
55
39
 
56
-
57
40
  const session = useSessionStore()
58
41
  const system = useSystemStore()
59
42
  const connectionAgreement = useConnectionAgreementStore()
60
- const {loadOneCooperative} = useLoadCooperatives()
43
+ const { loadOneCooperative } = useLoadCooperatives()
61
44
  const {
62
45
  domainValid,
63
46
  installationProgress,
@@ -69,112 +52,15 @@ const {
69
52
 
70
53
  const coop = ref()
71
54
 
72
- // Восстанавливаем документы из persistent store или создаем новые
73
- const document = computed({
74
- get: () => {
75
- if (connectionAgreement.document) {
76
- // Если есть сохраненный документ, пересоздаем экземпляр DigitalDocument
77
- const doc = new DigitalDocument()
78
- if (connectionAgreement.document.data) {
79
- doc.data = connectionAgreement.document.data
80
- }
81
- if (connectionAgreement.document.signedDocument) {
82
- doc.signedDocument = connectionAgreement.document.signedDocument
83
- }
84
- return doc
85
- }
86
- return new DigitalDocument()
87
- },
88
- set: (value) => connectionAgreement.setDocument(value)
89
- })
90
-
91
- const signedDocument = computed({
92
- get: () => connectionAgreement.signedDocument || document.value?.signedDocument,
93
- set: (value) => connectionAgreement.setSignedDocument(value)
94
- })
95
-
96
- const html = computed(() => document.value?.data?.html)
97
-
98
- // Используем persistent store для управления шагом
99
- const currentStep = computed({
100
- get: () => connectionAgreement.currentStep,
101
- set: (value) => connectionAgreement.setCurrentStep(value)
102
- })
103
-
104
- const handleStepChange = async (step: number) => {
105
- currentStep.value = step
106
-
107
- // Если переходим к шагу 2 (соглашение), всегда генерируем документ заново
108
- if (step === 2) {
109
- const newDoc = new DigitalDocument()
110
- await newDoc.generate({
111
- registry_id: Cooperative.Registry.CoopenomicsAgreement.registry_id,
112
- coopname: 'voskhod',
113
- username: session.username,
114
- })
115
- document.value = newDoc
116
- connectionAgreement.setDocument(newDoc)
117
- }
118
- }
119
-
120
- const handleClearSignedDocument = async () => {
121
- // Очищаем подписанный документ и регенерируем документ при возврате на шаг 2
122
- signedDocument.value = null
123
- connectionAgreement.setSignedDocument(null)
124
-
125
- // Регенерируем документ заново и убеждаемся что он сохраняется
126
- const newDoc = new DigitalDocument()
127
- await newDoc.generate({
128
- registry_id: Cooperative.Registry.CoopenomicsAgreement.registry_id,
129
- coopname: 'voskhod',
130
- username: session.username,
131
- })
132
- document.value = newDoc
133
- connectionAgreement.setDocument(newDoc)
134
- }
135
-
136
- const handleTariffSelected = (tariff: any) => {
137
- // Сохраняем выбранный тариф в persistent store
138
- connectionAgreement.setSelectedTariff(tariff)
139
- console.log('Selected tariff:', tariff)
140
- }
141
-
142
- const handleTariffDeselected = () => {
143
- // Очищаем выбранный тариф в persistent store
144
- connectionAgreement.setSelectedTariff(null)
145
- console.log('Tariff deselected')
146
- }
147
-
148
55
  // Остановка автообновления при размонтировании компонента
149
56
  let stopRefresh: (() => void) | null = null
150
57
 
151
- const handleContinue = () => {
152
- // Документ будет сгенерирован при переходе к шагу 2
153
- }
154
-
155
58
  const openProviderWebsite = () => {
156
59
  window.open('https://цифровой-кооператив.рф', '_blank')
157
60
  }
158
61
 
159
-
160
- const finish = () => {
161
- // Эта функция имеет смысл только если провайдер доступен
162
- if (!system.info.is_providered) return
163
-
164
- reload()
165
-
166
- // Запускаем автообновление подписок каждую минуту
167
- if (!stopRefresh) {
168
- stopRefresh = startAutoRefresh(60000) // 1 минута
169
- }
170
-
171
- // Сбрасываем persistent состояние после завершения
172
- connectionAgreement.reset()
173
- }
174
-
175
- //todo loadCooperative by username and check status
176
- const reload = async() => {
177
- // Загружаем кооператив только если провайдер доступен
62
+ // Загружаем кооператив
63
+ const loadCooperative = async () => {
178
64
  if (system.info.is_providered) {
179
65
  coop.value = await loadOneCooperative(session.username)
180
66
  }
@@ -189,34 +75,42 @@ const init = async () => {
189
75
  connectionAgreement.setInitialized(true)
190
76
  }
191
77
 
192
- coop.value = await loadOneCooperative(session.username)
193
-
194
- if (!coop.value) {
195
- // Если кооператива нет и мы на шаге 1, документ будет сгенерирован в handleContinue
196
- // Если пользователь еще не прошел ни одного шага, начинаем с первого
197
- if (currentStep.value === 1) {
198
- // Уже на первом шаге
199
- }
200
- } else {
201
- // Если кооператив существует, переходим на соответствующий шаг
202
- // Определяем шаг в зависимости от статуса кооператива и домена
203
- if (coop.value.status === 'active' && domainValid.value === true) {
204
- currentStep.value = 5 // Установка и настройка
205
- } else if (coop.value.status === 'pending') {
206
- currentStep.value = 5 // Ожидание одобрения (последний шаг)
207
- } else if (domainValid.value === true) {
208
- currentStep.value = 5 // Домен валиден, переходим к установке
209
- } else {
210
- currentStep.value = 4 // Проверка домена
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()
211
89
  }
90
+ connectionAgreement.setFormData(formData)
212
91
  }
213
92
  }
214
93
 
215
- const sign = async() => {
216
- await document.value.sign(session.username)
217
- signedDocument.value = document.value.signedDocument
94
+ const finish = () => {
95
+ // Эта функция имеет смысл только если провайдер доступен
96
+ if (!system.info.is_providered) return
97
+
98
+ // Запускаем автообновление подписок каждую минуту
99
+ if (!stopRefresh) {
100
+ stopRefresh = startAutoRefresh(60000) // 1 минута
101
+ }
102
+
103
+ // Сбрасываем persistent состояние после завершения
104
+ connectionAgreement.reset()
218
105
  }
219
106
 
107
+ // Watch за изменением шага для автоматического завершения
108
+ watch(() => connectionAgreement.currentStep, (newStep) => {
109
+ if (newStep >= 5) {
110
+ finish()
111
+ }
112
+ })
113
+
220
114
  // Lifecycle хуки
221
115
  onMounted(() => {
222
116
  // Если провайдер доступен - делаем полную инициализацию
@@ -3,33 +3,45 @@ import { computed, withDefaults } from 'vue'
3
3
  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
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
6
7
 
7
8
  const props = withDefaults(defineProps<IStepProps & {
8
9
  html?: string
9
- onSign?: () => void
10
- onBack?: () => void
11
10
  }>(), {})
12
11
 
13
- const emits = defineEmits<{
14
- back: []
15
- sign: []
16
- }>()
12
+ const connectionAgreement = useConnectionAgreementStore()
17
13
 
18
14
  const isActive = computed(() => props.isActive)
19
15
  const isDone = computed(() => props.isDone)
20
16
 
21
- const handleSign = () => {
22
- emits('sign')
17
+ const handleSign = async () => {
18
+ try {
19
+ await connectionAgreement.signDocument()
20
+ // Переходим к следующему шагу после подписания
21
+ if (connectionAgreement.currentStep < 5) {
22
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
23
+ }
24
+ } catch (error) {
25
+ console.error('Ошибка подписания документа:', error)
26
+ }
23
27
  }
24
28
 
25
29
  const handleBack = () => {
26
- emits('back')
30
+ // Специальная логика для возврата - очищаем подписанный документ
31
+ console.log(`⬅️ AgreementStep: Возврат с шага ${connectionAgreement.currentStep}`)
32
+
33
+ // Очищаем подписанный документ без генерации нового
34
+ connectionAgreement.setSignedDocument(null)
35
+
36
+ if (connectionAgreement.currentStep > 1) {
37
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep - 1)
38
+ }
27
39
  }
28
40
  </script>
29
41
 
30
42
  <template lang="pug">
31
43
  q-step(
32
- :name="2"
44
+ :name="3"
33
45
  title="Соглашение о подключении"
34
46
  icon="description"
35
47
  :done="isDone"
@@ -85,38 +85,51 @@
85
85
  <script setup lang="ts">
86
86
  import { computed, withDefaults } from 'vue'
87
87
  import type { IStepProps } from '../model/types'
88
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
89
+ import { useProviderSubscriptions } from 'src/features/Provider'
88
90
 
89
91
  const props = withDefaults(defineProps<IStepProps & {
90
92
  coop?: any
91
93
  domainValid?: boolean | null
92
94
  subscriptionsLoading?: boolean
93
95
  subscriptionsError?: string | null
94
- onReload?: () => void
95
- onBack?: () => void
96
- onContinue?: () => void
97
96
  }>(), {
98
97
  domainValid: null,
99
98
  subscriptionsLoading: false,
100
99
  subscriptionsError: null
101
100
  })
102
101
 
103
- const emits = defineEmits<{
104
- back: []
105
- continue: []
106
- reload: []
107
- }>()
102
+ const connectionAgreement = useConnectionAgreementStore()
103
+ const { loadSubscriptions } = useProviderSubscriptions()
108
104
 
109
105
  const isDone = computed(() => props.isDone)
110
106
 
111
107
  const handleBack = () => {
112
- emits('back')
108
+ console.log(`⬅️ DomainValidationStep: Текущий шаг ${connectionAgreement.currentStep}`)
109
+
110
+ // Специальная логика для возврата с шагов 4 и 5 - переходим к форме (шаг 2)
111
+ if (connectionAgreement.currentStep === 4 || connectionAgreement.currentStep === 5) {
112
+ console.log('🎯 Переходим к шагу 2 (форма)')
113
+ connectionAgreement.setCurrentStep(2)
114
+ return
115
+ }
116
+
117
+ if (connectionAgreement.currentStep > 1) {
118
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep - 1)
119
+ }
113
120
  }
114
121
 
115
122
  const handleContinue = () => {
116
- emits('continue')
123
+ if (connectionAgreement.currentStep < 5) {
124
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
125
+ }
117
126
  }
118
127
 
119
- const handleReload = () => {
120
- emits('reload')
128
+ const handleReload = async () => {
129
+ try {
130
+ await loadSubscriptions()
131
+ } catch (error) {
132
+ console.error('Ошибка обновления подписки:', error)
133
+ }
121
134
  }
122
135
  </script>
@@ -1,51 +1,49 @@
1
1
  <script setup lang="ts">
2
- import { computed, withDefaults } from 'vue'
2
+ import { withDefaults } from 'vue'
3
3
  import type { IStepProps } from '../model/types'
4
- import { AddCooperativeForm } from 'src/features/Union/AddCooperative'
4
+ import { CooperativeDataForm } from 'src/features/Union/CooperativeDataForm'
5
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
5
6
 
6
- const props = withDefaults(defineProps<IStepProps & {
7
+ withDefaults(defineProps<IStepProps & {
7
8
  document?: any
8
9
  signedDocument?: any
9
- cooperative?: any
10
- onFinish?: () => void
11
- onBack?: () => void
12
10
  }>(), {})
13
11
 
14
- // Используем подписанный документ, если он есть, иначе обычный документ
15
- const documentToUse = computed(() => props.signedDocument || props.document)
12
+ const connectionAgreement = useConnectionAgreementStore()
16
13
 
17
- const emits = defineEmits<{
18
- back: []
19
- finish: []
20
- }>()
14
+ const handleContinue = (formData?: any) => {
15
+ console.log('📝 FormStep: Продолжаем с данными формы:', formData)
21
16
 
22
- const handleFinish = () => {
23
- emits('finish')
17
+ // Сохраняем данные формы в стор (уже сохранены напрямую)
18
+ // Переходим к следующему шагу (документ сгенерируется в watch)
19
+ if (connectionAgreement.currentStep < 5) {
20
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
21
+ }
24
22
  }
25
23
 
26
24
  const handleBack = () => {
27
- emits('back')
25
+ if (connectionAgreement.currentStep > 1) {
26
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep - 1)
27
+ }
28
28
  }
29
29
  </script>
30
30
 
31
31
  <template lang="pug">
32
32
  q-step(
33
- :name="3"
34
- title="Настройка кооператива"
33
+ :name="2"
34
+ title="Сбор данных"
35
35
  icon="settings"
36
36
  :done="isDone"
37
37
  )
38
38
  .q-pa-md
39
39
  p.q-pb-md Введите домен для запуска сайта Цифрового Кооператива. Также, укажите суммы вступительных и минимальных паевых взносов для физических лиц, юридических лиц и индивидуальных предпринимателей:
40
40
 
41
- AddCooperativeForm(
42
- v-if="documentToUse"
43
- :document="documentToUse"
44
- :cooperative="cooperative"
45
- @finish="handleFinish"
41
+ CooperativeDataForm(
42
+ :key="Date.now()"
43
+ @continue="handleContinue"
46
44
  )
47
45
 
48
- q-stepper-navigation.q-gutter-sm(v-if="documentToUse")
46
+ q-stepper-navigation.q-gutter-sm
49
47
  q-btn(
50
48
  color="grey-6"
51
49
  flat
@@ -1,38 +1,36 @@
1
1
  <script setup lang="ts">
2
- import { computed, withDefaults, ref } from 'vue'
2
+ import { computed, withDefaults } from 'vue'
3
3
  import type { IStepProps } from '../model/types'
4
4
  import { TariffSelector, type ITariff } from '../Tariffs'
5
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
5
6
 
6
7
  const props = withDefaults(defineProps<IStepProps & {
7
- onContinue?: () => void
8
8
  selectedTariff?: ITariff | null
9
9
  }>(), {})
10
10
 
11
- const emits = defineEmits<{
12
- tariffSelected: [tariff: ITariff]
13
- tariffDeselected: []
14
- }>()
11
+ const connectionAgreement = useConnectionAgreementStore()
15
12
 
16
13
  const isActive = computed(() => props.isActive)
17
14
  const isDone = computed(() => props.isDone)
18
15
 
19
- const selectedTariff = ref<ITariff | null>(props.selectedTariff || null)
16
+ const selectedTariff = computed({
17
+ get: () => props.selectedTariff || connectionAgreement.selectedTariff,
18
+ set: (value) => connectionAgreement.setSelectedTariff(value)
19
+ })
20
20
 
21
21
  const canContinue = computed(() => selectedTariff.value !== null)
22
22
 
23
23
  const handleTariffSelected = (tariff: ITariff) => {
24
24
  selectedTariff.value = tariff
25
- emits('tariffSelected', tariff)
26
25
  }
27
26
 
28
27
  const handleTariffDeselected = () => {
29
28
  selectedTariff.value = null
30
- emits('tariffDeselected')
31
29
  }
32
30
 
33
31
  const handleContinue = () => {
34
- if (canContinue.value && props.onContinue) {
35
- props.onContinue()
32
+ if (canContinue.value && connectionAgreement.currentStep < 5) {
33
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep + 1)
36
34
  }
37
35
  }
38
36
  </script>
@@ -77,6 +77,8 @@
77
77
  <script setup lang="ts">
78
78
  import { computed, withDefaults } from 'vue'
79
79
  import type { IStepProps } from '../model/types'
80
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
81
+ import { useProviderSubscriptions } from 'src/features/Provider'
80
82
 
81
83
  const props = withDefaults(defineProps<IStepProps & {
82
84
  coop?: any
@@ -85,8 +87,6 @@ const props = withDefaults(defineProps<IStepProps & {
85
87
  instanceStatus?: string | null
86
88
  subscriptionsLoading?: boolean
87
89
  subscriptionsError?: string | null
88
- onReload?: () => void
89
- onBack?: () => void
90
90
  }>(), {
91
91
  domainValid: null,
92
92
  installationProgress: null,
@@ -95,19 +95,32 @@ const props = withDefaults(defineProps<IStepProps & {
95
95
  subscriptionsError: null
96
96
  })
97
97
 
98
- const emits = defineEmits<{
99
- back: []
100
- reload: []
101
- }>()
98
+ const connectionAgreement = useConnectionAgreementStore()
99
+ const { loadSubscriptions } = useProviderSubscriptions()
102
100
 
103
101
  const isDone = computed(() => props.isDone)
104
102
 
105
103
  const handleBack = () => {
106
- emits('back')
104
+ console.log(`⬅️ WaitingStep: Текущий шаг ${connectionAgreement.currentStep}`)
105
+
106
+ // Специальная логика для возврата - переходим к форме (шаг 2)
107
+ if (connectionAgreement.currentStep === 4 || connectionAgreement.currentStep === 5) {
108
+ console.log('🎯 Переходим к шагу 2 (форма)')
109
+ connectionAgreement.setCurrentStep(2)
110
+ return
111
+ }
112
+
113
+ if (connectionAgreement.currentStep > 1) {
114
+ connectionAgreement.setCurrentStep(connectionAgreement.currentStep - 1)
115
+ }
107
116
  }
108
117
 
109
- const handleReload = () => {
110
- emits('reload')
118
+ const handleReload = async () => {
119
+ try {
120
+ await loadSubscriptions()
121
+ } catch (error) {
122
+ console.error('Ошибка обновления подписки:', error)
123
+ }
111
124
  }
112
125
  </script>
113
126
 
@@ -1,86 +1,3 @@
1
- <script setup lang="ts">
2
- import { ref } from 'vue'
3
- import { IntroStep, AgreementStep, FormStep, DomainValidationStep, WaitingStep } from '../Steps/index'
4
-
5
- const props = defineProps<{
6
- initialStep?: number
7
- isFinish: boolean
8
- document?: any
9
- signedDocument: any
10
- coop: any
11
- html?: string
12
- domainValid?: boolean | null
13
- installationProgress?: number | null
14
- instanceStatus?: string | null
15
- subscriptionsLoading?: boolean
16
- subscriptionsError?: string | null
17
- selectedTariff?: any
18
- }>()
19
-
20
- const emits = defineEmits<{
21
- stepChange: [step: number]
22
- tariffSelected: [tariff: any]
23
- tariffDeselected: []
24
- continue: []
25
- sign: []
26
- finish: []
27
- reload: []
28
- clearSignedDocument: []
29
- }>()
30
-
31
- const currentStep = ref(props.initialStep || 1)
32
-
33
- // Управление шагами
34
- const goToNext = () => {
35
- if (currentStep.value < 5) {
36
- currentStep.value++
37
- emits('stepChange', currentStep.value)
38
- }
39
- }
40
-
41
- const goToPrev = () => {
42
- if (currentStep.value > 1) {
43
- currentStep.value--
44
- emits('stepChange', currentStep.value)
45
- }
46
- }
47
-
48
- const handleContinue = () => {
49
- goToNext()
50
- emits('continue')
51
- }
52
-
53
- const handleBack = () => {
54
- goToPrev()
55
- // Если возвращаемся на шаг 2 (соглашение), очищаем подписанный документ
56
- if (currentStep.value === 2) {
57
- emits('clearSignedDocument')
58
- }
59
- }
60
-
61
- const handleSign = () => {
62
- goToNext()
63
- emits('sign')
64
- }
65
-
66
- const handleFinish = () => {
67
- goToNext()
68
- emits('finish')
69
- }
70
-
71
- const handleReload = () => {
72
- emits('reload')
73
- }
74
-
75
- const handleTariffSelected = (tariff: any) => {
76
- emits('tariffSelected', tariff)
77
- }
78
-
79
- const handleTariffDeselected = () => {
80
- emits('tariffDeselected')
81
- }
82
- </script>
83
-
84
1
  <template lang="pug">
85
2
  div
86
3
  q-stepper(
@@ -96,29 +13,21 @@ div
96
13
  :is-active="currentStep === 1"
97
14
  :is-done="currentStep > 1"
98
15
  :selected-tariff="selectedTariff"
99
- @continue="handleContinue"
100
- @tariff-selected="handleTariffSelected"
101
- @tariff-deselected="handleTariffDeselected"
102
16
  )
103
17
 
104
- AgreementStep(
18
+ FormStep(
105
19
  :current-step="currentStep"
106
20
  :is-active="currentStep === 2"
107
21
  :is-done="currentStep > 2"
108
- :html="html"
109
- @back="handleBack"
110
- @sign="handleSign"
22
+ :document="document"
23
+ :signed-document="signedDocument"
111
24
  )
112
25
 
113
- FormStep(
26
+ AgreementStep(
114
27
  :current-step="currentStep"
115
28
  :is-active="currentStep === 3"
116
29
  :is-done="currentStep > 3"
117
- :document="document"
118
- :signed-document="signedDocument"
119
- :cooperative="coop"
120
- @back="goToPrev"
121
- @finish="handleFinish"
30
+ :html="html"
122
31
  )
123
32
 
124
33
  DomainValidationStep(
@@ -129,9 +38,6 @@ div
129
38
  :domain-valid="domainValid"
130
39
  :subscriptions-loading="subscriptionsLoading"
131
40
  :subscriptions-error="subscriptionsError"
132
- @back="goToPrev"
133
- @continue="goToNext"
134
- @reload="handleReload"
135
41
  )
136
42
 
137
43
  WaitingStep(
@@ -144,7 +50,43 @@ div
144
50
  :instance-status="instanceStatus"
145
51
  :subscriptions-loading="subscriptionsLoading"
146
52
  :subscriptions-error="subscriptionsError"
147
- @back="goToPrev"
148
- @reload="handleReload"
149
53
  )
150
54
  </template>
55
+
56
+
57
+ <script setup lang="ts">
58
+ import { computed, watch } from 'vue'
59
+ import { IntroStep, AgreementStep, FormStep, DomainValidationStep, WaitingStep } from '../Steps/index'
60
+ import { useConnectionAgreementStore } from 'src/entities/ConnectionAgreement'
61
+
62
+ defineProps<{
63
+ coop?: any
64
+ domainValid?: boolean | null
65
+ installationProgress?: number | null
66
+ instanceStatus?: string | null
67
+ subscriptionsLoading?: boolean
68
+ subscriptionsError?: string | null
69
+ }>()
70
+
71
+ const connectionAgreement = useConnectionAgreementStore()
72
+
73
+ // Данные из стора
74
+ const currentStep = computed(() => connectionAgreement.currentStep)
75
+ const selectedTariff = computed(() => connectionAgreement.selectedTariff)
76
+ const document = computed(() => connectionAgreement.document)
77
+ const signedDocument = computed(() => connectionAgreement.signedDocument)
78
+ const html = computed(() => document.value?.data?.html)
79
+
80
+ // Watch для реактивной генерации документа при переходе к шагу 3
81
+ watch(() => currentStep.value, async (newStep, oldStep) => {
82
+ // Если переходим к шагу 3 (соглашение), всегда генерируем документ заново
83
+ if (newStep === 3 && oldStep !== 3) {
84
+ console.log('📝 Шаг 3: Генерируем соглашение')
85
+ try {
86
+ await connectionAgreement.generateDocument()
87
+ } catch (error) {
88
+ console.error('Ошибка генерации документа:', error)
89
+ }
90
+ }
91
+ })
92
+ </script>