@coopenomics/desktop 2025.11.8-alpha-6 → 2025.11.9-alpha-2
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.
|
|
3
|
+
"version": "2025.11.9-alpha-2",
|
|
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.9-alpha-2",
|
|
29
|
+
"@coopenomics/notifications": "2025.11.9-alpha-2",
|
|
30
|
+
"@coopenomics/sdk": "2025.11.9-alpha-2",
|
|
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.9-alpha-2",
|
|
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": "5acd7ae2c437ce54f356113b5474700114f586ab"
|
|
127
127
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
div.row.justify-center.q-pa-md
|
|
3
3
|
div.col-md-8.col-xs-12
|
|
4
|
-
div(v-if="
|
|
5
|
-
div(v-if="
|
|
6
|
-
div(v-if="
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
div(v-if="system.info.is_providered")
|
|
5
|
+
div(v-if="is_finish == false")
|
|
6
|
+
div(v-if="!signedDocument")
|
|
7
|
+
div(v-if="html")
|
|
8
|
+
DocumentHtmlReader(:html="html")
|
|
9
|
+
q-btn(@click="sign" color="primary") подписать
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
div(v-else)
|
|
12
|
+
Loader(:text='`Готовим соглашение...`')
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
div(v-else)
|
|
15
|
+
p.text-h6 Предварительная настройка
|
|
16
|
+
p Пожалуйста, укажите домен для установки MONO. Также, укажите суммы вступительных и минимальных паевых взносов для физических лиц, юридических лиц и индивидуальных предпринимателей:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
AddCooperativeForm(:document="signedDocument" @finish="finish").q-pt-md
|
|
19
|
+
div(v-if="is_finish == true && coop")
|
|
19
20
|
|
|
20
21
|
p.text-h6 Кооператив на подключении
|
|
21
22
|
p Статус:
|
|
@@ -27,6 +28,89 @@ div.row.justify-center.q-pa-md
|
|
|
27
28
|
q-icon(name="refresh")
|
|
28
29
|
span обновить
|
|
29
30
|
|
|
31
|
+
div(v-else)
|
|
32
|
+
//- Заглушка для недоступного провайдера
|
|
33
|
+
q-banner(
|
|
34
|
+
:class="'text-white bg-blue-500'"
|
|
35
|
+
rounded
|
|
36
|
+
)
|
|
37
|
+
template(v-slot:avatar)
|
|
38
|
+
q-icon(name="info" color="white")
|
|
39
|
+
span Для подключения к Кооперативной Экономике обратитесь в ПК ВОСХОД
|
|
40
|
+
q-btn(
|
|
41
|
+
flat
|
|
42
|
+
color="white"
|
|
43
|
+
label="Перейти на сайт"
|
|
44
|
+
@click="openProviderWebsite"
|
|
45
|
+
size="sm"
|
|
46
|
+
).q-ml-md
|
|
47
|
+
|
|
48
|
+
div(v-if="system.info.is_providered").q-mt-md
|
|
49
|
+
p.text-subtitle1 Статус подписки на хостинг:
|
|
50
|
+
|
|
51
|
+
//- Статус подписки (только если провайдер доступен)
|
|
52
|
+
div
|
|
53
|
+
div(
|
|
54
|
+
v-if="subscriptionsError"
|
|
55
|
+
).q-mb-md
|
|
56
|
+
q-banner(
|
|
57
|
+
:class="'text-white bg-red-500'"
|
|
58
|
+
rounded
|
|
59
|
+
)
|
|
60
|
+
template(v-slot:avatar)
|
|
61
|
+
q-icon(name="error" color="white")
|
|
62
|
+
span {{ subscriptionsError }}
|
|
63
|
+
|
|
64
|
+
div.flex.items-center.q-gutter-sm
|
|
65
|
+
div
|
|
66
|
+
span.text-body2 Валидность домена:
|
|
67
|
+
q-badge(
|
|
68
|
+
v-if="domainValid === true"
|
|
69
|
+
color="green"
|
|
70
|
+
).q-ml-sm валиден
|
|
71
|
+
q-badge(
|
|
72
|
+
v-if="domainValid === false"
|
|
73
|
+
color="red"
|
|
74
|
+
).q-ml-sm не валиден
|
|
75
|
+
q-badge(
|
|
76
|
+
v-if="domainValid === null && !subscriptionsLoading"
|
|
77
|
+
color="grey"
|
|
78
|
+
).q-ml-sm неизвестно
|
|
79
|
+
q-badge(
|
|
80
|
+
v-if="subscriptionsLoading"
|
|
81
|
+
color="blue"
|
|
82
|
+
).q-ml-sm загрузка...
|
|
83
|
+
|
|
84
|
+
div
|
|
85
|
+
span.text-body2 Прогресс установки:
|
|
86
|
+
q-badge(
|
|
87
|
+
v-if="installationProgress !== null"
|
|
88
|
+
:color="installationProgress === 100 ? 'green' : 'orange'"
|
|
89
|
+
).q-ml-sm {{ installationProgress }}%
|
|
90
|
+
q-badge(
|
|
91
|
+
v-if="installationProgress === null && !subscriptionsLoading"
|
|
92
|
+
color="grey"
|
|
93
|
+
).q-ml-sm неизвестно
|
|
94
|
+
q-badge(
|
|
95
|
+
v-if="subscriptionsLoading"
|
|
96
|
+
color="blue"
|
|
97
|
+
).q-ml-sm загрузка...
|
|
98
|
+
|
|
99
|
+
div
|
|
100
|
+
span.text-body2 Статус сервера:
|
|
101
|
+
q-badge(
|
|
102
|
+
v-if="instanceStatus"
|
|
103
|
+
:color="instanceStatus === 'active' ? 'green' : instanceStatus === 'error' ? 'red' : 'orange'"
|
|
104
|
+
).q-ml-sm {{ instanceStatus }}
|
|
105
|
+
q-badge(
|
|
106
|
+
v-if="!instanceStatus && !subscriptionsLoading"
|
|
107
|
+
color="grey"
|
|
108
|
+
).q-ml-sm неизвестно
|
|
109
|
+
q-badge(
|
|
110
|
+
v-if="subscriptionsLoading"
|
|
111
|
+
color="blue"
|
|
112
|
+
).q-ml-sm загрузка...
|
|
113
|
+
|
|
30
114
|
p Пожалуйста, перешлите инструкцию ниже вашему техническому специалисту. После её выполнения, мы автоматически выполним запуск. Далее, Вам необходимо завершить установку уже на Вашем сайте следуя инструкциям, представленным там.
|
|
31
115
|
|
|
32
116
|
q-card(flat bordered).q-pa-sm
|
|
@@ -39,18 +123,29 @@ div.row.justify-center.q-pa-md
|
|
|
39
123
|
<script setup lang="ts">
|
|
40
124
|
import { DigitalDocument } from 'src/shared/lib/document';
|
|
41
125
|
import { useSessionStore } from 'src/entities/Session';
|
|
126
|
+
import { useSystemStore } from 'src/entities/System/model';
|
|
42
127
|
import { DocumentHtmlReader } from 'src/shared/ui/DocumentHtmlReader';
|
|
43
|
-
import { computed, ref } from 'vue';
|
|
128
|
+
import { computed, ref, onMounted, onUnmounted } from 'vue';
|
|
44
129
|
import { Loader } from 'src/shared/ui/Loader';
|
|
45
130
|
import { AddCooperativeForm } from 'src/features/Union/AddCooperative';
|
|
46
131
|
import { useLoadCooperatives } from 'src/features/Union/LoadCooperatives';
|
|
132
|
+
import { useProviderSubscriptions } from 'src/features/Provider';
|
|
47
133
|
import { copyToClipboard } from 'quasar';
|
|
48
134
|
import { SuccessAlert } from 'src/shared/api';
|
|
49
135
|
import { Cooperative } from 'cooptypes';
|
|
50
136
|
|
|
51
137
|
const session = useSessionStore()
|
|
138
|
+
const system = useSystemStore()
|
|
52
139
|
const document = ref(new DigitalDocument())
|
|
53
140
|
const {loadOneCooperative} = useLoadCooperatives()
|
|
141
|
+
const {
|
|
142
|
+
domainValid,
|
|
143
|
+
installationProgress,
|
|
144
|
+
instanceStatus,
|
|
145
|
+
isLoading: subscriptionsLoading,
|
|
146
|
+
error: subscriptionsError,
|
|
147
|
+
startAutoRefresh
|
|
148
|
+
} = useProviderSubscriptions()
|
|
54
149
|
|
|
55
150
|
const coop = ref()
|
|
56
151
|
const instruction = computed(() => `Создайте A-запись домена ${coop.value?.announce} на IP-адрес: 51.250.114.13`)
|
|
@@ -59,6 +154,9 @@ const html = computed(() => document.value?.data?.html)
|
|
|
59
154
|
const signedDocument = computed(() => document.value?.signedDocument)
|
|
60
155
|
const is_finish = ref(false)
|
|
61
156
|
|
|
157
|
+
// Остановка автообновления при размонтировании компонента
|
|
158
|
+
let stopRefresh: (() => void) | null = null
|
|
159
|
+
|
|
62
160
|
const copy = () => {
|
|
63
161
|
copyToClipboard(instruction.value)
|
|
64
162
|
.then(() => {
|
|
@@ -69,18 +167,36 @@ const copy = () => {
|
|
|
69
167
|
})
|
|
70
168
|
}
|
|
71
169
|
|
|
170
|
+
const openProviderWebsite = () => {
|
|
171
|
+
window.open('https://цифровой-кооператив.рф', '_blank')
|
|
172
|
+
}
|
|
173
|
+
|
|
72
174
|
|
|
73
175
|
const finish = () => {
|
|
176
|
+
// Эта функция имеет смысл только если провайдер доступен
|
|
177
|
+
if (!system.info.is_providered) return
|
|
178
|
+
|
|
74
179
|
is_finish.value = true
|
|
75
180
|
reload()
|
|
181
|
+
|
|
182
|
+
// Запускаем автообновление подписок каждую минуту
|
|
183
|
+
if (!stopRefresh) {
|
|
184
|
+
stopRefresh = startAutoRefresh(60000) // 1 минута
|
|
185
|
+
}
|
|
76
186
|
}
|
|
77
187
|
|
|
78
188
|
//todo loadCooperative by username and check status
|
|
79
189
|
const reload = async() => {
|
|
80
|
-
|
|
190
|
+
// Загружаем кооператив только если провайдер доступен
|
|
191
|
+
if (system.info.is_providered) {
|
|
192
|
+
coop.value = await loadOneCooperative(session.username)
|
|
193
|
+
}
|
|
81
194
|
}
|
|
82
195
|
|
|
83
196
|
const init = async () => {
|
|
197
|
+
// Инициализация имеет смысл только если провайдер доступен
|
|
198
|
+
if (!system.info.is_providered) return
|
|
199
|
+
|
|
84
200
|
coop.value = await loadOneCooperative(session.username)
|
|
85
201
|
|
|
86
202
|
if (!coop.value)
|
|
@@ -96,6 +212,23 @@ const sign = async() => {
|
|
|
96
212
|
await document.value.sign(session.username)
|
|
97
213
|
}
|
|
98
214
|
|
|
215
|
+
// Lifecycle хуки
|
|
216
|
+
onMounted(() => {
|
|
217
|
+
// Если провайдер доступен - делаем полную инициализацию
|
|
218
|
+
if (system.info.is_providered) {
|
|
219
|
+
init()
|
|
220
|
+
}
|
|
221
|
+
// Если провайдер недоступен - ничего не делаем, показываем заглушку
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
onUnmounted(() => {
|
|
225
|
+
// Останавливаем автообновление при размонтировании компонента
|
|
226
|
+
if (stopRefresh) {
|
|
227
|
+
stopRefresh()
|
|
228
|
+
stopRefresh = null
|
|
229
|
+
}
|
|
230
|
+
})
|
|
231
|
+
|
|
99
232
|
init()
|
|
100
233
|
|
|
101
234
|
|