work-license-server 1.0.1 → 1.0.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/README.md +1 -1
- package/assets/landing.js +2 -2
- package/package.json +1 -1
- package/src/agent.js +8 -8
- package/src/catalog.js +7 -3
- package/src/landing.js +5 -5
- package/src/store.js +5 -3
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- **Start** — `10 000 ₽ / год` (до 12 обращений в год на место, реакция до 8 рабочих часов);
|
|
13
13
|
- **Business** — `15 000 ₽ / год` (до 48 обращений, реакция до 2 часов);
|
|
14
14
|
- **Enterprise** — `20 000 ₽ / год` (безлимит, реакция до 15 минут 24/7).
|
|
15
|
-
3. **Региональная франшиза** — интерактивная карта всех субъектов РФ (`assets/russia-regions.json`, границы © участники OpenStreetMap), квота франшиз пропорциональна населению,
|
|
15
|
+
3. **Региональная франшиза** — интерактивная карта всех субъектов РФ (`assets/russia-regions.json`, границы © участники OpenStreetMap), квота франшиз пропорциональна населению, паушальный взнос — `500 000 ₽ ×` индекс субъекта, резерв — невозвратный залог `100 000 ₽` (`POST /api/partners/reserve`), полная оплата паушального взноса — в течение 1 года.
|
|
16
16
|
4. **ЮKassa** (`/api/orders/checkout`, `/api/payments/yookassa/webhook`) — чеки 54-ФЗ, выпуск и продление сертификатов `Ed25519` (`WORK-LIC-v1`) с привязкой к `HWID` и ключу узла `#system/node-key.json`.
|
|
17
17
|
5. **Боты поддержки** — `/api/bots/max/webhook`, `/api/bots/telegram/webhook`, `/api/bots/vk/webhook`.
|
|
18
18
|
6. **ИИ-агент** — `POST /api/agent/chat`: консультации, расчёт лицензий, вакантные франшизы по субъекту, контакты.
|
package/assets/landing.js
CHANGED
|
@@ -520,7 +520,7 @@
|
|
|
520
520
|
<div class="r"><span>Округ</span><em>${esc(r.district)}</em></div>
|
|
521
521
|
<div class="r"><span>Население</span><em>${String(r.populationMillions).replace('.', ',')} млн</em></div>
|
|
522
522
|
<div class="r"><span>Вакантно</span><em style="color:${vac > 0 ? 'var(--ok)' : 'var(--danger)'}">${vac} из ${q}</em></div>
|
|
523
|
-
<div class="r"><span
|
|
523
|
+
<div class="r"><span>Паушальный взнос</span><em>${rub(feeOf(r))}</em></div>`;
|
|
524
524
|
const br = box.getBoundingClientRect();
|
|
525
525
|
let x = e.clientX - br.left + 16, y = e.clientY - br.top + 16;
|
|
526
526
|
const tw = tip.offsetWidth || 200, th = tip.offsetHeight || 110;
|
|
@@ -772,7 +772,7 @@
|
|
|
772
772
|
<td><b>${esc(r.reservationId)}</b><div class="small muted">Резерв франшизы</div></td>
|
|
773
773
|
<td><b>${esc(r.regionName)}</b> <span class="muted">(${esc(r.regionCode)})</span></td>
|
|
774
774
|
<td><b>${esc(r.companyName)}</b><div class="small muted">ИНН ${esc(r.inn || '—')} · ${esc(r.email || '—')}</div></td>
|
|
775
|
-
<td
|
|
775
|
+
<td>Паушальный взнос <b>${rub(r.franchiseFeeRub)}</b><div class="small muted">Залог ${rub(r.nonRefundableDepositRub || r.depositAmountRub || D.franchise.reservationDepositRub)} · полная оплата за 1 год</div></td>
|
|
776
776
|
<td><span class="tag ${r.depositPaid ? 'ok' : ''}">${r.depositPaid ? 'залог оплачен' : 'ждёт оплаты залога'}</span></td>
|
|
777
777
|
<td><div style="display:flex;gap:6px;flex-wrap:wrap">
|
|
778
778
|
${!r.depositPaid && r.orderId ? `<button class="btn btn-ok btn-sm" data-pay-order="${esc(r.orderId)}">Оплатить залог</button>` : ''}
|
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* - комплекс ODANT-WORK на AMD Ryzen™ AI Max+ PRO 495 + Radeon™ 8065S;
|
|
6
6
|
* - ИИ-консультант и мультиагентная система платформы (ролевые агенты, навыки, оркестрация);
|
|
7
7
|
* - докупка годовых лицензий (Start 10 000 ₽, Business 15 000 ₽, Enterprise 20 000 ₽) со скидкой от количества;
|
|
8
|
-
* - вакантные франшизы по любому субъекту РФ (залог 100 000 ₽, базовая стоимость
|
|
8
|
+
* - вакантные франшизы по любому субъекту РФ (залог 100 000 ₽, базовая стоимость 500 000 ₽);
|
|
9
9
|
* - контакты разработчика платформы.
|
|
10
10
|
*/
|
|
11
11
|
import {
|
|
@@ -70,15 +70,15 @@ export class LicenseServerAiAgent {
|
|
|
70
70
|
|
|
71
71
|
// 1. Франшиза в конкретном субъекте РФ
|
|
72
72
|
const region = findRegionInText(text);
|
|
73
|
-
if (region && /(
|
|
73
|
+
if (region && /(франш|паушал|взнос|регион|вакант|квот|резерв|залог|партн|сколько|област|край|республ)/i.test(lower)) {
|
|
74
74
|
const q = this.store.getRegionPartnerQuotaStatus(region.code);
|
|
75
75
|
return {
|
|
76
76
|
reply: [
|
|
77
77
|
`**${q.regionName}** (${q.district})`,
|
|
78
78
|
`• Население: **${String(q.populationMillions).replace('.', ',')} млн чел.**`,
|
|
79
79
|
`• Вакантных франшиз: **${q.vacantFranchises} из ${q.maxPartnersQuota}** — квота пропорциональна населению`,
|
|
80
|
-
`•
|
|
81
|
-
`• Невозвратный залог за резерв: **${fmt(q.reservationDepositRub)}
|
|
80
|
+
`• Паушальный взнос: **${fmt(q.franchiseFeeRub)} ₽** (базовый взнос ${fmt(FRANCHISE_PROGRAM.baseFranchiseFeeRub)} ₽ × индекс ${q.economicIndex})`,
|
|
81
|
+
`• Невозвратный залог за резерв: **${fmt(q.reservationDepositRub)} ₽**, полная оплата остатка (**${fmt(q.remainingAfterDepositRub)} ₽**) — **в течение 1 года**`,
|
|
82
82
|
`• Скидка партнёра: от ${FRANCHISE_PROGRAM.minDiscountPercent}% до ${FRANCHISE_PROGRAM.maxDiscountPercent}% от годового объёма продаж`,
|
|
83
83
|
q.vacantFranchises > 0
|
|
84
84
|
? 'Я выделил субъект на карте — можно сразу нажать «Зарезервировать».'
|
|
@@ -164,14 +164,14 @@ export class LicenseServerAiAgent {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
// 6. Партнёрская программа в целом
|
|
167
|
-
if (/(
|
|
167
|
+
if (/(франш|паушал|взнос|партн|залог|резерв|обучен|сертифик|nas|инференс)/i.test(lower)) {
|
|
168
168
|
const all = this.store.listRegionsWithQuotas().filter(r => !r.hidden);
|
|
169
169
|
const totalVacant = all.reduce((s, r) => s + r.vacantFranchises, 0);
|
|
170
170
|
return {
|
|
171
171
|
reply: [
|
|
172
172
|
'**Региональная франшиза ODANT-WORK:**',
|
|
173
|
-
`•
|
|
174
|
-
`• Резерв субъекта: невозвратный залог **${fmt(FRANCHISE_PROGRAM.reservationDepositRub)} ₽** через ЮKassa
|
|
173
|
+
`• Базовый паушальный взнос: **${fmt(FRANCHISE_PROGRAM.baseFranchiseFeeRub)} ₽** × экономический индекс субъекта`,
|
|
174
|
+
`• Резерв субъекта: невозвратный залог **${fmt(FRANCHISE_PROGRAM.reservationDepositRub)} ₽** через ЮKassa, полная оплата паушального взноса — **в течение 1 года**`,
|
|
175
175
|
`• Сейчас свободно **${totalVacant}** франшиз в **${all.length}** субъектах РФ (квота пропорциональна населению)`,
|
|
176
176
|
`• Скидка партнёра: от ${FRANCHISE_PROGRAM.minDiscountPercent}% до ${FRANCHISE_PROGRAM.maxDiscountPercent}% от годового объёма продаж`,
|
|
177
177
|
'• 100% дохода партнёра: оборудование и гарантия на него, NAS для резервных копий, серверы инференса, собственный API к моделям, поддержка, дообучение агентов и навыков.',
|
|
@@ -186,7 +186,7 @@ export class LicenseServerAiAgent {
|
|
|
186
186
|
'Я ИИ-агент лицензионного центра **ODANT-WORK**. Коротко об условиях:',
|
|
187
187
|
`1. **Комплекс** — ${fmt(PAK_PRODUCT.basePriceRub)} ₽: AMD Ryzen™ AI Max+ PRO 495, Radeon™ 8065S, 192 ГБ, 4 ТБ, ${PAK_PRODUCT.baseSeats} вечных мест и год поддержки.`,
|
|
188
188
|
'2. **Доп. места на год:** Start 10 000 ₽ · Business 15 000 ₽ · Enterprise 20 000 ₽, скидка за количество до −25%.',
|
|
189
|
-
`3. **Франшиза:**
|
|
189
|
+
`3. **Франшиза:** паушальный взнос ${fmt(FRANCHISE_PROGRAM.baseFranchiseFeeRub)} ₽ × индекс субъекта, залог за резерв ${fmt(FRANCHISE_PROGRAM.reservationDepositRub)} ₽, полная оплата в течение 1 года.`,
|
|
190
190
|
'Спросите, например: «Рассчитай 25 мест Business», «Франшиза в Рязанской области» или «Что умеют ИИ-агенты?»',
|
|
191
191
|
].join('\n'),
|
|
192
192
|
actions: [],
|
package/src/catalog.js
CHANGED
|
@@ -277,14 +277,16 @@ export function calculateOrderQuote({
|
|
|
277
277
|
|
|
278
278
|
/**
|
|
279
279
|
* Параметры партнёрской программы и региональной франшизы ODANT-WORK:
|
|
280
|
-
* -
|
|
281
|
-
* - Сразу при резервировании франшизы вносится невозвратный залог = 100 000
|
|
280
|
+
* - Базовый паушальный взнос = 500 000 ₽ (корректируется пропорционально экономическому индексу региона).
|
|
281
|
+
* - Сразу при резервировании франшизы вносится невозвратный залог = 100 000 ₽, полная оплата паушального взноса — в течение 1 года (12 мес.).
|
|
282
282
|
* - Максимальное количество франшиз в регионе пропорционально населению региона (partnersPerMillion * populationMillions, мин. 1).
|
|
283
283
|
* - Партнёрская скидка растёт пропорционально годовому объёму продаж от начальных 10% до максимальных 50%.
|
|
284
284
|
*/
|
|
285
285
|
export const FRANCHISE_PROGRAM = Object.freeze({
|
|
286
|
-
baseFranchiseFeeRub:
|
|
286
|
+
baseFranchiseFeeRub: 500_000, // Базовый паушальный взнос (500 тыс. ₽ при экономическом индексе 1.0)
|
|
287
287
|
reservationDepositRub: 100_000, // Невозвратный залог сразу за резервирование региональной франшизы (100 тыс. ₽)
|
|
288
|
+
fullPaymentPeriodMonths: 12, // Срок полной оплаты паушального взноса — в течение 1 года (12 месяцев)
|
|
289
|
+
fullPaymentPeriodYears: 1, // 1 год на полную оплату паушального взноса после резервирования
|
|
288
290
|
partnersPerMillionPopulation: 1, // Норматив квоты партнёров: 1 франшиза на 1 млн населения региона
|
|
289
291
|
minDiscountPercent: 10, // Начальная партнёрская скидка (10%)
|
|
290
292
|
maxDiscountPercent: 50, // Максимальная партнёрская скидка (50%)
|
|
@@ -588,6 +590,8 @@ export function calculateFranchiseFee(regionCodeOrIndex = 'RU-SVE', customPopula
|
|
|
588
590
|
franchiseFeeRub,
|
|
589
591
|
reservationDepositRub,
|
|
590
592
|
remainingAfterDepositRub: Math.max(0, franchiseFeeRub - reservationDepositRub),
|
|
593
|
+
fullPaymentPeriodMonths: FRANCHISE_PROGRAM.fullPaymentPeriodMonths,
|
|
594
|
+
fullPaymentPeriodYears: FRANCHISE_PROGRAM.fullPaymentPeriodYears,
|
|
591
595
|
};
|
|
592
596
|
}
|
|
593
597
|
|
package/src/landing.js
CHANGED
|
@@ -420,12 +420,12 @@ export function renderLandingPage({ publicKey = '', regions = null, assetVersion
|
|
|
420
420
|
<section class="stage" id="stage-franchise">
|
|
421
421
|
<div class="sec-head">
|
|
422
422
|
<div><span class="kicker">Партнёрская программа</span><h2 class="h2">Региональная франшиза ODANT-WORK</h2></div>
|
|
423
|
-
<p>Число франшиз в субъекте пропорционально населению,
|
|
423
|
+
<p>Число франшиз в субъекте пропорционально населению, паушальный взнос — экономике региона. Резерв закрепляется сразу после невозвратного залога ${rub(FRANCHISE_PROGRAM.reservationDepositRub)}, полная оплата паушального взноса — в течение 1 года.</p>
|
|
424
424
|
</div>
|
|
425
425
|
<div class="stats">
|
|
426
426
|
<div class="stat"><b id="statVacant">${totalVacant}</b><span>вакантных франшиз</span></div>
|
|
427
427
|
<div class="stat"><b>${visibleRegions.length}</b><span>субъектов РФ</span></div>
|
|
428
|
-
<div class="stat"><b>${rub(FRANCHISE_PROGRAM.baseFranchiseFeeRub)}</b><span
|
|
428
|
+
<div class="stat"><b>${rub(FRANCHISE_PROGRAM.baseFranchiseFeeRub)}</b><span>базовый паушальный взнос</span></div>
|
|
429
429
|
<div class="stat"><b>${rub(FRANCHISE_PROGRAM.reservationDepositRub)}</b><span>залог за резерв</span></div>
|
|
430
430
|
<div class="stat"><b>${FRANCHISE_PROGRAM.minDiscountPercent}→${FRANCHISE_PROGRAM.maxDiscountPercent}%</b><span>скидка партнёра от объёма</span></div>
|
|
431
431
|
</div>
|
|
@@ -471,10 +471,10 @@ export function renderLandingPage({ publicKey = '', regions = null, assetVersion
|
|
|
471
471
|
<div><div class="small muted">Вакантно франшиз</div><div class="display" style="font-size:22px;font-weight:800" id="mapRegVacant">—</div><div class="small muted" id="mapRegOccupied"></div></div>
|
|
472
472
|
</div>
|
|
473
473
|
<div class="kv">
|
|
474
|
-
<div><span
|
|
474
|
+
<div><span>Паушальный взнос</span><b id="mapRegFee">—</b></div>
|
|
475
475
|
<div><span>Залог за резерв</span><b>${rub(FRANCHISE_PROGRAM.reservationDepositRub)}</b></div>
|
|
476
476
|
<div><span>Индекс экономики</span><b id="mapRegIndex">—</b></div>
|
|
477
|
-
<div><span>Остаток
|
|
477
|
+
<div><span>Остаток (в течение года)</span><b id="mapRegRest">—</b></div>
|
|
478
478
|
</div>
|
|
479
479
|
<div class="field"><label for="inpPartnerCompany">Компания</label><input type="text" id="inpPartnerCompany" value="ООО «УралТехИнтеграция»"></div>
|
|
480
480
|
<div class="row2">
|
|
@@ -498,7 +498,7 @@ export function renderLandingPage({ publicKey = '', regions = null, assetVersion
|
|
|
498
498
|
<th data-sort="district">Округ<span class="arr">↕</span></th>
|
|
499
499
|
<th data-sort="populationMillions" class="num">Население<span class="arr">↕</span></th>
|
|
500
500
|
<th data-sort="vacantFranchises">Вакантно<span class="arr">↕</span></th>
|
|
501
|
-
<th data-sort="franchiseFeeRub" class="num"
|
|
501
|
+
<th data-sort="franchiseFeeRub" class="num">Паушальный взнос<span class="arr">↕</span></th>
|
|
502
502
|
<th></th>
|
|
503
503
|
</tr></thead>
|
|
504
504
|
<tbody id="regionsTableBody"></tbody>
|
package/src/store.js
CHANGED
|
@@ -689,7 +689,7 @@ export class LicenseStore {
|
|
|
689
689
|
|
|
690
690
|
/**
|
|
691
691
|
* Зарезервировать региональную франшизу с выставлением счёта ЮKassa на невозвратный залог 100 000 ₽.
|
|
692
|
-
*
|
|
692
|
+
* Полный паушальный взнос (500 000 ₽ × индекс региона) фиксируется в договоре резерва, полная оплата — в течение 1 года.
|
|
693
693
|
*/
|
|
694
694
|
reserveFranchiseSlot({
|
|
695
695
|
regionCode = 'RU-SVE',
|
|
@@ -730,10 +730,12 @@ export class LicenseStore {
|
|
|
730
730
|
franchiseFeeRub: quotaStatus.franchiseFeeRub,
|
|
731
731
|
nonRefundableDepositRub: depositRub,
|
|
732
732
|
remainingFranchiseFeeRub: Math.max(0, quotaStatus.franchiseFeeRub - depositRub),
|
|
733
|
+
fullPaymentPeriodMonths: FRANCHISE_PROGRAM.fullPaymentPeriodMonths,
|
|
734
|
+
fullPaymentDeadlineAt: now + 365 * 24 * 3600_000,
|
|
733
735
|
status: 'reserved_pending_deposit',
|
|
734
736
|
depositPaid: false,
|
|
735
737
|
createdAt: now,
|
|
736
|
-
expiresAt: now +
|
|
738
|
+
expiresAt: now + 365 * 24 * 3600_000,
|
|
737
739
|
};
|
|
738
740
|
|
|
739
741
|
const order = {
|
|
@@ -750,7 +752,7 @@ export class LicenseStore {
|
|
|
750
752
|
franchiseFeeRub: quotaStatus.franchiseFeeRub,
|
|
751
753
|
items: [
|
|
752
754
|
{
|
|
753
|
-
title: `Невозвратный залог за резервирование региональной франшизы ODANT-WORK (${quotaStatus.regionName},
|
|
755
|
+
title: `Невозвратный залог за резервирование региональной франшизы ODANT-WORK (${quotaStatus.regionName}, паушальный взнос ${quotaStatus.franchiseFeeRub.toLocaleString('ru-RU')} ₽, полная оплата в течение 1 года)`,
|
|
754
756
|
quantity: 1,
|
|
755
757
|
unitPriceRub: depositRub,
|
|
756
758
|
totalRub: depositRub,
|