Кабинет: курсы ЦБ, история стоимости портфеля, быстрые операции, контакты в профиле
Курсы валют. Оценивать замещающие и еврооблигации по курсу из копии учётной системы было нельзя: в DEPO он от 31.05.2026, в SPECTRE — от 18.07.2026. Берём официальный курс Банка России (открытый XML, без ключа — тем же каналом пользуется Инвест-хаб) и складываем по дням в lk.fx_rates: без интернета кабинет считает по последнему известному курсу, а не отказывается оценивать. Источник переключается в настройках («Данные кабинета»), там же кнопка «Обновить курсы сейчас». Портфель БР-719: 560,3 млн ₽ против 522 млн по старому курсу. История стоимости. Ни QUIK, ни SPECTRE её не хранят, поэтому раз в день после закрытия торгов считаем стоимость каждого портфеля по экспорту QUIK и пишем строку в lk.portfolio_daily (257 портфелей за 14 секунд). Кабинет рисует по ним график на странице портфеля — SVG собирается на сервере, скриптов в кабинете по-прежнему нет. Режим по умолчанию — «автоматически»: ведём, если настроен экспорт QUIK, потому что задним числом историю не восстановить. Операции. Связка «JOIN OD_RESTS ON sr.ID = CASE WHEN w.D_REST IN (…)» заставляла SQL Server разбирать список счетов на каждой строке журнала проводок: год данных читался 6–7 секунд. Обе стороны проводки выбираются заранее двумя ветвями UNION ALL, индексы IX_WIRING_D_REST_WIRDATE и IX_WIRING_K_REST_WIRDATE отрабатывают поиском — 89 мс на тех же 64 строках. Период по умолчанию вернули к году, ответ кэшируется на пять минут. Профиль: почта, телефон и прошлый вход из анкеты — клиент видит, куда с ним свяжется депозитарий, и заметит устаревшие данные. Правка только через менеджера. Заказ документов из кабинета убран совсем (форма была убрана раньше, теперь нет и обработчика). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -206,6 +207,10 @@ func registerLKAPI(mux *http.ServeMux, rc *RuntimeConfig, svc *Service) {
|
||||
"read_only": readOnly,
|
||||
"total_value": total, // оценка портфеля, 0 — цен нет
|
||||
"priced": priced, // по скольким бумагам есть цена
|
||||
// Контакты из анкеты: клиент видит, куда депозитарий будет писать и звонить,
|
||||
// и сразу заметит, если данные устарели. Менять их в кабинете нельзя.
|
||||
"email": u.Email, "phone": u.Phone,
|
||||
"last_login": lkTimeRU(u.LastLoginAt),
|
||||
})
|
||||
})
|
||||
|
||||
@@ -275,6 +280,30 @@ func registerLKAPI(mux *http.ServeMux, rc *RuntimeConfig, svc *Service) {
|
||||
// Портфель клиента как у брокера: view=online — по экспорту QUIK (что есть сейчас), если
|
||||
// в QUIK клиента нет — по брокерскому учёту на сегодня; view=archive&date=YYYY-MM-DD —
|
||||
// портфель на дату по брокерскому учёту (SPECTRE).
|
||||
// История стоимости портфеля: ежедневные срезы (lksnapshot.go), для графика.
|
||||
mux.HandleFunc("/api/lk/history", func(w http.ResponseWriter, r *http.Request) {
|
||||
if !auth(w, r) {
|
||||
return
|
||||
}
|
||||
u, ok := current(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
days := 180
|
||||
if v, err := strconv.Atoi(r.URL.Query().Get("days")); err == nil && v > 0 {
|
||||
days = v
|
||||
}
|
||||
points, err := lkSnapshotHistory(r.Context(), rc, u.Contract, days)
|
||||
if err != nil {
|
||||
lkJSON(w, http.StatusBadGateway, map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
set := rc.Snapshot().LK
|
||||
hour, min := lkSnapshotTime(set)
|
||||
lkJSON(w, http.StatusOK, map[string]any{"points": points, "on": lkSnapshotEnabled(rc),
|
||||
"at": fmt.Sprintf("%02d:%02d", hour, min), "days": days})
|
||||
})
|
||||
|
||||
mux.HandleFunc("/api/lk/portfolio2", func(w http.ResponseWriter, r *http.Request) {
|
||||
if !auth(w, r) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user