From 1f68169b940ca61b8fe5f6cca3af887ac622940f Mon Sep 17 00:00:00 2001 From: coopops Date: Tue, 16 Jun 2026 14:36:52 +0000 Subject: [PATCH] =?UTF-8?q?feat(exit):=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80?= =?UTF-8?q?=D0=B0=D1=82=20=D0=BF=D1=80=D0=B8=20=D0=B2=D1=8B=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=20=E2=80=94=20=D1=81=D0=B5=D1=82=20=D0=B8=D0=B7=20?= =?UTF-8?q?3=20=D0=BF=D0=B0=D0=B5=D0=B2=D1=8B=D1=85=20=D0=BA=D0=BE=D1=88?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BA=D0=BE=D0=B2=20(minshr+share+blago)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit confirmexit теперь обходит сет LEDGER2_EXIT_REFUND_WALLETS (w.reg.minshr + w.wal.share + w.cap.blago): собирает доступные L3-балансы каждого (>0), консолидирует на главный паевой (w.reg.minshr→o.reg.mvmin, w.cap.blago→ o.cap.wthcap) и ставит полную сумму на возврат единым платежом. Раньше хардкодил только minshr+share — паевой в Благоросте оставался висеть. Сет задан один раз в wallets.hpp (источник истины), генерируется gen:from-cpp в cooptypes (LEDGER2_EXIT_REFUND_WALLETS / EXIT_REFUND_WALLET_NAMES) и обходится backend-preview (getReturnPreview) — расчёт на фронте всегда совпадает с тем, что реально вернёт контракт. Подпись «планируемая сумма / итог фиксирует Совет» убрана из ExitButton и ExitOverlay (сумма теперь авторитетна). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../cpp/lib/core/ledger2/wallets.hpp | 31 ++++++++++++++ .../cpp/registrator/src/exit/confirmexit.cpp | 37 +++++++++-------- .../cpp/registrator/src/exit/exit_helpers.hpp | 32 +++++++++++++++ .../services/membership-exit.service.ts | 40 ++++++++++++------- components/cooptypes/scripts/gen-from-cpp.ts | 37 ++++++++++++++++- .../src/ledger2/wallets.generated.ts | 12 ++++++ components/cooptypes/src/ledger2/wallets.ts | 11 +++++ .../wallets-registry.snapshot.test.ts.snap | 15 +++++++ .../test/wallets-registry.snapshot.test.ts | 11 +++++ .../Membership/ExitFromCoop/ui/ExitButton.vue | 19 ++------- .../ExitFromCoop/ui/ExitOverlay.vue | 10 +---- 11 files changed, 197 insertions(+), 58 deletions(-) diff --git a/components/contracts/cpp/lib/core/ledger2/wallets.hpp b/components/contracts/cpp/lib/core/ledger2/wallets.hpp index 094edf86dbd..b443f96677f 100644 --- a/components/contracts/cpp/lib/core/ledger2/wallets.hpp +++ b/components/contracts/cpp/lib/core/ledger2/wallets.hpp @@ -252,6 +252,37 @@ inline constexpr std::array LEDGER2_USER_SHARED_ { ledger2_wallets::REGISTRATION_PENDING, 0 /* w.reg.pend — кандидат ещё не член, соглашения нет, без проверки */ }, }}; +/** + * @brief Сет «боевых» (паевых) кошельков пайщика, возвращаемых при выходе из + * кооператива (заявление registry 200 → одобрение совета `confirmexit`). + * + * Единый источник истины для суммы возврата. При одобрении выхода советом + * `registrator::confirmexit` обходит этот сет в цикле, аккумулирует доступный + * L3-баланс пайщика по каждому кошельку (>0), консолидирует на главный паевой + * (`w.wal.share`) и ставит всю сумму на возврат единым платежом. Тот же сет + * генерируется в cooptypes (`gen:from-cpp` → `wallets.generated.ts`) и + * используется backend-preview, поэтому расчёт на фронте всегда совпадает с + * тем, что реально вернёт контракт. + * + * Состав — только паевые/возвратные USER_SHARED-кошельки: + * w.reg.minshr — минимальный паевой взнос; + * w.wal.share — целевой паевой взнос (ЦК); + * w.cap.blago — паевой взнос в ЦПП «Благорост». + * + * НЕ входят: w.wal.member (членский — невозвратный), w.exp.adv (подотчёт под + * расход), w.cap.gen (Генератор — COOPERATIVE, без L3-разреза по пайщику), + * w.cap.preimp (пред-импорт-учёт РИД). + * + * Каждому не-главному кошельку сета должна соответствовать операция переноса + * на `w.wal.share` в `Registrator::consolidate_share_to_main` (exit_helpers.hpp) + * — иначе runtime упадёт с явным сообщением (защита от тихой потери средств). + */ +inline constexpr std::array LEDGER2_EXIT_REFUND_WALLETS = {{ + ledger2_wallets::MIN_SHARE_FUND, + ledger2_wallets::SHARE_FUND_PAY, + ledger2_wallets::BLAGOROST_FUND, +}}; + /** * @brief Возвращает required program_id для USER_SHARED-кошелька. * diff --git a/components/contracts/cpp/registrator/src/exit/confirmexit.cpp b/components/contracts/cpp/registrator/src/exit/confirmexit.cpp index 9d0b09207d8..aeb3dae66af 100644 --- a/components/contracts/cpp/registrator/src/exit/confirmexit.cpp +++ b/components/contracts/cpp/registrator/src/exit/confirmexit.cpp @@ -1,10 +1,11 @@ /** * @brief Одобрение советом выхода пайщика из кооператива. - * Совет одобрил заявление о выходе. Контракт сам вычисляет сумму возврата по - * L3-балансам ledger2 (минимальный + целевой паевой), консолидирует - * минимальный паевой на главный (o.reg.mvmin), резервирует сумму возврата - * (o.wal.wthreq) и создаёт исходящий платёж в gateway. Если возвращать нечего - * — выход завершается сразу без платежа. + * Совет одобрил заявление о выходе. Контракт сам вычисляет сумму возврата: + * обходит сет паевых кошельков LEDGER2_EXIT_REFUND_WALLETS (w.reg.minshr + + * w.wal.share + w.cap.blago), собирает доступный L3-баланс каждого, консолидирует + * на главный паевой (w.wal.share), резервирует всю сумму (o.wal.wthreq) и создаёт + * исходящий платёж в gateway. Если возвращать нечего — выход завершается сразу + * без платежа. * @param coopname Наименование кооператива * @param exit_hash Хэш процесса выхода * @param authorization Документ-решение совета о выходе @@ -29,11 +30,18 @@ void registrator::confirmexit(eosio::name coopname, checksum256 exit_hash, docum require_recipient(username); // Контракт сам считает сумму возврата по L3-балансам ledger2 — не доверяем - // клиенту. Возвращается минимальный (w.reg.minshr) + целевой (w.wal.share) - // паевой взнос пайщика. - eosio::asset min_share = Registrator::get_user_wallet_available(coopname, ledger2_wallets::MIN_SHARE_FUND, username); - eosio::asset share = Registrator::get_user_wallet_available(coopname, ledger2_wallets::SHARE_FUND_PAY, username); - eosio::asset total_return = min_share + share; + // клиенту. Обходим сет паевых («боевых») кошельков LEDGER2_EXIT_REFUND_WALLETS + // (источник истины — wallets.hpp; он же генерируется в cooptypes для + // backend-preview, поэтому расчёт на фронте совпадает с этим): аккумулируем + // доступный баланс каждого (>0) и тут же консолидируем его на главный паевой + // (w.wal.share), чтобы единым платежом вернуть весь паевой через o.wal.*. + eosio::asset total_return = eosio::asset(0, _root_govern_symbol); + for (const auto &wallet_name : LEDGER2_EXIT_REFUND_WALLETS) { + eosio::asset balance = Registrator::get_user_wallet_available(coopname, wallet_name, username); + if (balance.amount <= 0) continue; + total_return += balance; + Registrator::consolidate_share_to_main(coopname, username, wallet_name, balance, exit_hash); + } exits.modify(e, _soviet, [&](auto &row) { row.status = "authorized"_n; @@ -41,15 +49,6 @@ void registrator::confirmexit(eosio::name coopname, checksum256 exit_hash, docum row.quantity = total_return; }); - // Консолидируем минимальный паевой на главный (o.reg.mvmin: w.reg.minshr → - // w.wal.share), чтобы единым платежом вернуть весь паевой через механику - // возврата паевого взноса (o.wal.*). - if (min_share.amount > 0) { - std::string memo = "Консолидация минимального паевого взноса при выходе, username=" + username.to_string(); - Ledger2::apply(_registrator, coopname, operations::registrator::MOVE_MINSHARE, - min_share, username, exit_hash, memo); - } - if (total_return.amount > 0) { // Резервируем сумму возврата: w.wal.share → w.wal.wpend (o.wal.wthreq). std::string memo_req = "Резерв паевого взноса под выход из кооператива, username=" + username.to_string(); diff --git a/components/contracts/cpp/registrator/src/exit/exit_helpers.hpp b/components/contracts/cpp/registrator/src/exit/exit_helpers.hpp index cf8cbab66b5..76bd2b69ce5 100644 --- a/components/contracts/cpp/registrator/src/exit/exit_helpers.hpp +++ b/components/contracts/cpp/registrator/src/exit/exit_helpers.hpp @@ -34,6 +34,38 @@ inline asset get_user_wallet_available(name coopname, name wallet_name, name use return it->available; } +/** + * @brief Консолидация доступного паевого кошелька пайщика на главный + * (`w.wal.share`) перед резервом возврата при выходе. + * + * Главный кошелёк (`w.wal.share`) уже целевой — перенос не нужен. Для остальных + * кошельков сета `LEDGER2_EXIT_REFUND_WALLETS` применяется операция переноса на + * главный: + * w.reg.minshr → o.reg.mvmin (MOVE_MINSHARE); + * w.cap.blago → o.cap.wthcap (WITHDRAW_FROM_CAPITAL). + * + * Кошелёк сета без операции переноса (новый паевой кошелёк забыли смаппить) + * валит транзакцию с явным сообщением — защита от тихой потери средств. + */ +inline void consolidate_share_to_main(name coopname, name username, name wallet_name, asset amount, checksum256 exit_hash) { + if (wallet_name == ledger2_wallets::SHARE_FUND_PAY) return; // уже на главном паевом + + eosio::name op; + if (wallet_name == ledger2_wallets::MIN_SHARE_FUND) { + op = operations::registrator::MOVE_MINSHARE; // w.reg.minshr → w.wal.share + } else if (wallet_name == ledger2_wallets::BLAGOROST_FUND) { + op = operations::capital::WITHDRAW_FROM_CAPITAL; // w.cap.blago → w.wal.share + } else { + eosio::check(false, + std::string{"Нет операции консолидации паевого кошелька "} + wallet_name.to_string() + + " на главный при выходе — добавьте маппинг в consolidate_share_to_main"); + } + + std::string memo = "Консолидация паевого взноса при выходе, кошелёк=" + + wallet_name.to_string() + ", username=" + username.to_string(); + Ledger2::apply(_registrator, coopname, op, amount, username, exit_hash, memo); +} + /** * @brief Финализация выхода: удаление пайщика из реестра совета и блокировка * аккаунта в registrator. diff --git a/components/controller/src/application/membership-exit/services/membership-exit.service.ts b/components/controller/src/application/membership-exit/services/membership-exit.service.ts index 48e7ffb7e52..2a9dd9e56a2 100644 --- a/components/controller/src/application/membership-exit/services/membership-exit.service.ts +++ b/components/controller/src/application/membership-exit/services/membership-exit.service.ts @@ -273,26 +273,38 @@ export class MembershipExitService { } /** - * Предварительный расчёт суммы возврата паевого взноса при выходе пайщика — - * минимальный (w.reg.minshr) + целевой (w.wal.share) паевой по L3-балансам. + * Предварительный расчёт суммы возврата паевого взноса при выходе пайщика. + * + * Считается обходом сета паевых кошельков Ledger2.EXIT_REFUND_WALLET_NAMES + * (w.reg.minshr + w.wal.share + w.cap.blago) по L3-балансам — тот же сет, что + * обходит контракт `confirmexit` при одобрении выхода советом, поэтому preview + * совпадает с суммой, которую реально вернёт контракт. */ async getReturnPreview(coopname: string, username: string): Promise { - const [shareRow, minRow] = await Promise.all([ - this.userWalletRepository.findByWalletAndUsername(coopname, Ledger2.SHARE_WALLET_NAME, username), - this.userWalletRepository.findByWalletAndUsername(coopname, Ledger2.MIN_SHARE_WALLET_NAME, username), - ]); + const wallets = Ledger2.EXIT_REFUND_WALLET_NAMES; + const rows = await Promise.all( + wallets.map((wallet) => this.userWalletRepository.findByWalletAndUsername(coopname, wallet, username)), + ); - const share = shareRow?.present !== false ? shareRow?.available : undefined; - const minimum = minRow?.present !== false ? minRow?.available : undefined; + // available учитываем только для существующих (present) кошельков + const balances = rows.map((row) => (row?.present !== false ? row?.available : undefined)); - const template = await this.resolveAssetTemplate(coopname, share ?? minimum); - const shareAsset = share ?? this.zeroAssetLike(template); - const minimumAsset = minimum ?? this.zeroAssetLike(template); + const template = await this.resolveAssetTemplate(coopname, balances.find((b) => !!b)); + const zero = this.zeroAssetLike(template); + + const assets = balances.map((b) => b ?? zero); + const total = assets.reduce((acc, a) => this.sumAssets(acc, a), zero); + + // индивидуальные паевые отдаём для информации; фронт показывает total + const balanceOf = (wallet: string): string => { + const idx = wallets.indexOf(wallet); + return idx >= 0 ? assets[idx] : zero; + }; return { - total: this.sumAssets(shareAsset, minimumAsset), - share_contribution: shareAsset, - minimum_contribution: minimumAsset, + total, + share_contribution: balanceOf(Ledger2.SHARE_WALLET_NAME), + minimum_contribution: balanceOf(Ledger2.MIN_SHARE_WALLET_NAME), }; } diff --git a/components/cooptypes/scripts/gen-from-cpp.ts b/components/cooptypes/scripts/gen-from-cpp.ts index 05f1939cabc..fdf525fcc4c 100644 --- a/components/cooptypes/scripts/gen-from-cpp.ts +++ b/components/cooptypes/scripts/gen-from-cpp.ts @@ -106,6 +106,29 @@ const programMapping: ProgramMappingEntry[] = [] } } +// ── 5b. LEDGER2_EXIT_REFUND_WALLETS ────────────────────────────────────── +// Сет паевых кошельков, возвращаемых пайщику при выходе. Простой массив имён +// `ledger2_wallets::NAME` — единый источник для контракта (confirmexit) и +// backend-preview. +const exitRefundWallets: string[] = [] +{ + const body = extractArrayBody('LEDGER2_EXIT_REFUND_WALLETS') + const re = /ledger2_wallets::(\w+)/g + for (const m of body.matchAll(re)) { + const wallet_name = nameMap.get(m[1]!) + if (!wallet_name) throw new Error(`gen-from-cpp: ledger2_wallets::${m[1]} не найден среди имён`) + exitRefundWallets.push(wallet_name) + } + if (exitRefundWallets.length === 0) throw new Error('gen-from-cpp: LEDGER2_EXIT_REFUND_WALLETS пуст') + const sizeMatch = /std::array\s+LEDGER2_EXIT_REFUND_WALLETS/.exec(hpp) + if (sizeMatch && Number(sizeMatch[1]) !== exitRefundWallets.length) + throw new Error(`gen-from-cpp: распарсено ${exitRefundWallets.length} exit-refund-кошельков, объявлено ${sizeMatch[1]}`) + const known = new Set(walletRegistry.map(w => w.name)) + for (const w of exitRefundWallets) { + if (!known.has(w)) throw new Error(`gen-from-cpp: exit-refund ссылается на отсутствующий в реестре кошелёк "${w}"`) + } +} + // ── 6. emit TS ─────────────────────────────────────────────────────────── const lines: string[] = [] lines.push('// AUTO-GENERATED by cooptypes/scripts/gen-from-cpp.ts — DO NOT EDIT.') @@ -153,6 +176,18 @@ for (const m of programMapping) { } lines.push('] as const') lines.push('') +lines.push('/**') +lines.push(' * Сет паевых («боевых») кошельков пайщика, возвращаемых при выходе из кооператива.') +lines.push(' * Точная копия `LEDGER2_EXIT_REFUND_WALLETS` из C++. Контракт `confirmexit` обходит') +lines.push(' * этот сет, собирает доступные балансы и ставит их на возврат; backend-preview') +lines.push(' * считает по нему же — расчёт на фронте всегда совпадает с тем, что вернёт контракт.') +lines.push(' */') +lines.push('export const LEDGER2_EXIT_REFUND_WALLETS: readonly IName[] = [') +for (const w of exitRefundWallets) { + lines.push(` ${JSON.stringify(w)},`) +} +lines.push('] as const') +lines.push('') writeFileSync(OUT_PATH, lines.join('\n'), 'utf8') -console.log(`gen-from-cpp: записано ${OUT_PATH} (wallets=${walletRegistry.length}, mapping=${programMapping.length})`) +console.log(`gen-from-cpp: записано ${OUT_PATH} (wallets=${walletRegistry.length}, mapping=${programMapping.length}, exitRefund=${exitRefundWallets.length})`) diff --git a/components/cooptypes/src/ledger2/wallets.generated.ts b/components/cooptypes/src/ledger2/wallets.generated.ts index 332fbc56443..ab57eb4928e 100644 --- a/components/cooptypes/src/ledger2/wallets.generated.ts +++ b/components/cooptypes/src/ledger2/wallets.generated.ts @@ -62,3 +62,15 @@ export const LEDGER2_USER_SHARED_PROGRAM_MAPPING: readonly ProgramWalletMapping[ { wallet_name: "w.exp.adv", required_program_id: 0, program_label: null }, { wallet_name: "w.reg.pend", required_program_id: 0, program_label: null }, ] as const + +/** + * Сет паевых («боевых») кошельков пайщика, возвращаемых при выходе из кооператива. + * Точная копия `LEDGER2_EXIT_REFUND_WALLETS` из C++. Контракт `confirmexit` обходит + * этот сет, собирает доступные балансы и ставит их на возврат; backend-preview + * считает по нему же — расчёт на фронте всегда совпадает с тем, что вернёт контракт. + */ +export const LEDGER2_EXIT_REFUND_WALLETS: readonly IName[] = [ + "w.reg.minshr", + "w.wal.share", + "w.cap.blago", +] as const diff --git a/components/cooptypes/src/ledger2/wallets.ts b/components/cooptypes/src/ledger2/wallets.ts index edc0fc66d07..303783e2169 100644 --- a/components/cooptypes/src/ledger2/wallets.ts +++ b/components/cooptypes/src/ledger2/wallets.ts @@ -18,6 +18,7 @@ import type { IName } from '../interfaces/ledger2' export { + LEDGER2_EXIT_REFUND_WALLETS, LEDGER2_USER_SHARED_PROGRAM_MAPPING, LEDGER2_WALLET_REGISTRY, } from './wallets.generated' @@ -28,6 +29,7 @@ export type { } from './wallets.generated' import { + LEDGER2_EXIT_REFUND_WALLETS, LEDGER2_USER_SHARED_PROGRAM_MAPPING, LEDGER2_WALLET_REGISTRY, } from './wallets.generated' @@ -75,6 +77,15 @@ export const SHARE_WALLET_NAME = 'w.wal.share' */ export const MIN_SHARE_WALLET_NAME = 'w.reg.minshr' +/** + * Сет паевых («боевых») кошельков, возвращаемых пайщику при выходе из кооператива + * (`w.reg.minshr` + `w.wal.share` + `w.cap.blago`). Источник истины — контракт + * (`LEDGER2_EXIT_REFUND_WALLETS` в wallets.hpp), сгенерирован в wallets.generated. + * Контракт `confirmexit` пылесосит эти кошельки на возврат; backend-preview + * суммирует их же — расчёт всегда совпадает с тем, что вернёт контракт. + */ +export const EXIT_REFUND_WALLET_NAMES: readonly string[] = LEDGER2_EXIT_REFUND_WALLETS + /** * Все wallet_name'ы, привязанные к какой-либо программе (program_id > 0). * Исключает кошельки с required_program_id == 0 (например, `w.reg.minshr`). diff --git a/components/cooptypes/test/__snapshots__/wallets-registry.snapshot.test.ts.snap b/components/cooptypes/test/__snapshots__/wallets-registry.snapshot.test.ts.snap index 4902aa3a9b0..8212afb04b6 100644 --- a/components/cooptypes/test/__snapshots__/wallets-registry.snapshot.test.ts.snap +++ b/components/cooptypes/test/__snapshots__/wallets-registry.snapshot.test.ts.snap @@ -32,6 +32,11 @@ exports[`ledger2 wallets registry (generated from C++) > LEDGER2_USER_SHARED_PRO "required_program_id": 0, "wallet_name": "w.cap.preimp", }, + { + "program_label": null, + "required_program_id": 0, + "wallet_name": "w.exp.adv", + }, { "program_label": null, "required_program_id": 0, @@ -67,6 +72,11 @@ exports[`ledger2 wallets registry (generated from C++) > LEDGER2_WALLET_REGISTRY "kind": "USER_SHARED", "name": "w.cap.preimp", }, + { + "human_name": "Подотчётные средства пайщика", + "kind": "USER_SHARED", + "name": "w.exp.adv", + }, { "human_name": "Регистрационный взнос в ожидании решения совета", "kind": "USER_SHARED", @@ -122,5 +132,10 @@ exports[`ledger2 wallets registry (generated from C++) > LEDGER2_WALLET_REGISTRY "kind": "COOPERATIVE", "name": "w.mkt.payout", }, + { + "human_name": "Пул программных расходов ЦПП «Благорост»", + "kind": "COOPERATIVE", + "name": "w.cap.pgexp", + }, ] `; diff --git a/components/cooptypes/test/wallets-registry.snapshot.test.ts b/components/cooptypes/test/wallets-registry.snapshot.test.ts index 9ef3e1490d6..86a98a132ef 100644 --- a/components/cooptypes/test/wallets-registry.snapshot.test.ts +++ b/components/cooptypes/test/wallets-registry.snapshot.test.ts @@ -1,5 +1,7 @@ import { describe, expect, it } from 'vitest' import { + EXIT_REFUND_WALLET_NAMES, + LEDGER2_EXIT_REFUND_WALLETS, LEDGER2_USER_SHARED_PROGRAM_MAPPING, LEDGER2_WALLET_REGISTRY, programIdForWallet, @@ -35,4 +37,13 @@ describe('ledger2 wallets registry (generated from C++)', () => { it('ЦК split: program_id=1 → share + member', () => { expect(walletNamesForProgram(1).sort()).toEqual(['w.wal.member', 'w.wal.share']) }) + + it('exit-refund сет: ровно три паевых кошелька (minshr + share + blago)', () => { + expect(LEDGER2_EXIT_REFUND_WALLETS).toEqual(['w.reg.minshr', 'w.wal.share', 'w.cap.blago']) + // алиас-обёртка ссылается на тот же сет + expect(EXIT_REFUND_WALLET_NAMES).toEqual(LEDGER2_EXIT_REFUND_WALLETS) + // каждый кошелёк сета зарегистрирован в реестре + const known = new Set(LEDGER2_WALLET_REGISTRY.map(w => w.name)) + for (const w of LEDGER2_EXIT_REFUND_WALLETS) expect(known.has(w)).toBe(true) + }) }) diff --git a/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitButton.vue b/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitButton.vue index 6a206dda143..d086c8ec1da 100644 --- a/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitButton.vue +++ b/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitButton.vue @@ -64,11 +64,10 @@ div DocumentHtmlReader(:html='document.html') //- Итог к возврату — soft-панель под документом, читается как подбивка - //- к заявлению (а не «висящий» текст снизу). + //- к заявлению (а не «висящий» текст снизу). Сумма авторитетная: собирается + //- по сету паевых кошельков (тот же, что обходит контракт при возврате). div.exit-summary(v-if='preview') - div.exit-summary__text - span.exit-summary__label Сумма к возврату - span.exit-summary__hint Планируемая сумма; итог фиксирует Совет + span.exit-summary__label Сумма к возврату span.exit-summary__value {{ formatAsset2Digits(preview.total) }} @@ -253,21 +252,11 @@ const handlerSubmit = async (): Promise => { background: var(--p-surface-2); border-radius: var(--p-r-md); } -.exit-summary__text { - display: flex; - flex-direction: column; - gap: var(--p-1); - min-width: 0; -} .exit-summary__label { font-size: var(--p-fs-body); font-weight: 600; color: var(--p-ink); -} -.exit-summary__hint { - font-size: var(--p-fs-meta); - line-height: var(--p-lh-meta); - color: var(--p-ink-3); + min-width: 0; } .exit-summary__value { font-family: var(--p-mono); diff --git a/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitOverlay.vue b/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitOverlay.vue index 80c062fe8c4..65d282abf49 100644 --- a/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitOverlay.vue +++ b/components/desktop/src/features/Membership/ExitFromCoop/ui/ExitOverlay.vue @@ -25,7 +25,6 @@ BaseDialog( :variant='paymentChip.variant', size='sm' ) {{ paymentChip.label }} - span.exit-amount__hint.t-sm.t-faint(v-if='view.plannedHint') Планируемая сумма; итог фиксирует Совет. p.exit-note.t-sm.t-muted(v-if='view.canCancel') Пока вы не перешли по ссылке, заявление можно отменить. //- Футер: действия (отделён бордером внутри AuthCard). @@ -107,7 +106,6 @@ const view = computed(() => { title: 'Вы вышли из кооператива', body: 'Возврат паевого взноса оплачен — дождитесь поступления средств на указанные реквизиты. Аккаунт заблокирован. Благодарим за участие в кооперативе.', amountLabel: 'Сумма возврата', - plannedHint: false, canCancel: false, }; } @@ -117,8 +115,7 @@ const view = computed(() => { tone: 'primary', title: 'Подтвердите выход по ссылке из письма', body: 'Мы отправили письмо на вашу электронную почту — перейдите по ссылке в нём, чтобы подтвердить выход и запустить возврат паевого взноса. Письмо могло попасть в папку «Спам».', - amountLabel: 'Планируемая сумма к возврату', - plannedHint: false, + amountLabel: 'Сумма к возврату', canCancel: true, }; } @@ -129,7 +126,6 @@ const view = computed(() => { title: 'Совет одобрил выход', body: 'Возврат паевого взноса будет совершён в срок, установленный Уставом кооператива. Аккаунт заблокирован — дождитесь поступления средств.', amountLabel: 'Сумма к возврату', - plannedHint: false, canCancel: false, }; } @@ -139,7 +135,6 @@ const view = computed(() => { title: 'Заявление на рассмотрении Совета', body: 'Ваше заявление о выходе передано в Совет кооператива. Кабинет заблокирован на время процедуры — дождитесь решения Совета.', amountLabel: 'Сумма к возврату', - plannedHint: true, canCancel: false, }; }); @@ -238,9 +233,6 @@ const onLogout = async (): Promise => { .exit-amount__chip { margin-top: var(--p-2); } -.exit-amount__hint { - margin-top: var(--p-1); -} .exit-note { margin: var(--p-3) 0 0;