@ -0,0 +1,10 @@ |
||||
.git |
||||
node_modules |
||||
.vite |
||||
tmp |
||||
logs |
||||
*.log |
||||
.env |
||||
.env.* |
||||
*.local |
||||
.DS_Store |
||||
@ -1,9 +0,0 @@ |
||||
# VITE_APP_BASE_URL=/VisualTemplate/ |
||||
VITE_APP_BASE_URL=/ |
||||
VITE_OPEN_API_BASE=/openApi |
||||
VITE_JSY_API_BASE=/jsyApi |
||||
VITE_GEOSERVER_WMS_URL=/geoserver/ne/wms |
||||
VITE_ACCOUNT_API_PROXY_TARGET=http://127.0.0.1:8888 |
||||
VITE_OPEN_API_PROXY_TARGET=http://127.0.0.1:9999 |
||||
VITE_JSY_API_PROXY_TARGET=http://127.0.0.1:9999 |
||||
VITE_GEOSERVER_PROXY_TARGET=http://127.0.0.1:8080 |
||||
@ -0,0 +1,8 @@ |
||||
FROM nginx:1.27-alpine |
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf |
||||
COPY nginx-main.conf /etc/nginx/nginx.conf |
||||
COPY docker-entrypoint.d/05-v3-network-lockdown.sh /docker-entrypoint.d/05-v3-network-lockdown.sh |
||||
RUN chmod 0755 /docker-entrypoint.d/05-v3-network-lockdown.sh |
||||
# 宿主机完成 Vite 构建和校验;镜像只替换 V3 静态运行包,不重复构建依赖。 |
||||
COPY docs /usr/share/nginx/html |
||||
EXPOSE 80 55433 56380 19999 18081 |
||||
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 52 KiB |
@ -1,727 +1,153 @@ |
||||
**Source Visual Truth** |
||||
- Reference screenshot: `/Users/mocker/.codex/attachments/448ee497-991a-4afa-b23d-00015b35ab41/image-1.png` |
||||
- Reference source: `/Users/mocker/Downloads/ThreeProject-gd_副本/src/components/mCard/index.vue` |
||||
- Reference chart source: `/Users/mocker/Downloads/ThreeProject-gd_副本/src/views/gdMap/components/BulkCommoditySalesChart.vue` |
||||
|
||||
**Implementation Evidence** |
||||
- Home: `/tmp/screen2-home-bright-pass2-wait.png` |
||||
- Forest-Grass-Wet: `/tmp/screen2-forest-grass-wet-bright-check.png` |
||||
- Ecological Protection: `/tmp/screen2-ecological-protection-bright-check.png` |
||||
- Yak Management: `/tmp/screen2-yak-management-bright-check.png` |
||||
- Pasture Management: `/tmp/screen2-pasture-management-bright-check.png` |
||||
- Yak Industry Chain before final label fix: `/tmp/screen2-yak-industry-chain-four-card-check.png` |
||||
- Yak Industry Chain artificial grassland final: `/tmp/screen2-yak-industry-chain-final-check.png` |
||||
- Viewport: `1920x1080` |
||||
- Local route base: `http://127.0.0.1:5174/#/platform` |
||||
|
||||
**Checks Completed** |
||||
- Card shell uses the reference fill/opacity, with page-level extra `filter`, drop-shadow, and title glow removed. |
||||
- Homepage chart labels, dashed grid lines, units, and bar proportions were aligned with the reference chart style. |
||||
- `forestGrassWet`, `ecologicalProtection`, `yakManagement`, `pastureManagement`, and `yakIndustryChain` no longer override `m-card` into the darker/blurrier style. |
||||
- WebGL pixel ratio cap is now `2`, improving map and canvas sharpness on the 1920x1080 target. |
||||
- Yak Industry Chain default stage now has four meaningful left cards: |
||||
- 家庭生态牧场乡镇分布 |
||||
- 标准化建设配置 |
||||
- 乡镇割草地、储草基地面积 |
||||
- 草料配套类型占比 |
||||
- Yak Industry Chain top metric label was shortened from `活动场地及通道` to `活动场地` to avoid text/value collision; the source data field remains unchanged. |
||||
|
||||
**Yak Industry Chain DOM Verification** |
||||
- Left card positions: `y=128/367/606/831`, widths about `385px`, four cards present. |
||||
- Right list card height: `466px`, matching the previous “最高占据两个卡片高度” direction. |
||||
- Top metrics after fix: |
||||
- 家庭生态牧场 252处 |
||||
- 标准化暖棚 61600㎡ |
||||
- 饲草料库 12000㎡ |
||||
- 活动场地 108800㎡ |
||||
- Artificial grassland topic uses business dimensions instead of plot-only wording: |
||||
- 人工种草乡镇面积 |
||||
- 年度项目建设面积 |
||||
- 建设类型面积 |
||||
- 作业方式面积 |
||||
- Artificial grassland top metrics verified in browser: |
||||
- 实测种草面积 5.64万亩 |
||||
- 建设项目 6项 |
||||
- 覆盖乡镇 7个 |
||||
- 项目投资 4309.48万元 |
||||
|
||||
**Notes** |
||||
- The in-app browser screenshot channel timed out after the final HMR refresh on the WebGL-heavy industry page, but DOM verification confirmed the final four-card and label state. |
||||
- A standalone Playwright screenshot reached the login page because it had no authenticated session; no browser cookies or local storage were copied. |
||||
|
||||
**Final Result** |
||||
- Visual standardization pass: passed for the requested style foundation. |
||||
- Remaining product decision: Ecological Protection still contains some low-density/empty-data panels; this pass did not invent new business data for empty modules. |
||||
|
||||
## 2026-07-12 Homepage Brightness Correction |
||||
|
||||
**Source Visual Truth** |
||||
- User reference crop: `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-ab9196eb-0d73-4022-9008-0da0dbe7948e.png` |
||||
- Reference project: `/Users/mocker/Downloads/ThreeProject-gd_副本` |
||||
- Reference card source: `/Users/mocker/Downloads/ThreeProject-gd_副本/src/components/mCard/index.vue` |
||||
- Reference chart source: `/Users/mocker/Downloads/ThreeProject-gd_副本/src/views/gdMap/components/BulkCommoditySalesChart.vue` |
||||
|
||||
**Implementation Evidence** |
||||
- Browser-rendered homepage: `/tmp/screen2-home-overlay-fixed-loaded.png` |
||||
- Full-view comparison: `/tmp/screen2-reference-vs-home-fixed-full.png` |
||||
- Focused card comparison: `/tmp/screen2-reference-vs-home-fixed-card.png` |
||||
- Browser viewport: `1280x720`; platform design canvas: `1920x1080` through the existing autofit layer. |
||||
- State: homepage loaded, left and right panels visible, map animation complete. |
||||
|
||||
**Comparison History** |
||||
- Earlier P1: card titles, chart labels, values, and borders were uniformly dimmer than the reference even though `m-card` used the same SVG and body opacity. |
||||
- Root cause: `.large-screen-wrap::after` belongs to a shell with `z-index: 3`, while each platform module is a sibling at `z-index: 1`. The background texture therefore covered the entire module in the integrated platform. In the standalone reference page the cards are children above that texture. |
||||
- Fix: disable the shell pseudo-element in the integrated platform. Map and module-owned backgrounds remain unchanged; only the unintended foreground veil is removed. |
||||
- Post-fix evidence: browser-computed overlay content is `none`; title is `16px/600`, opacity `1`; card body opacity remains the reference value `0.6`. |
||||
|
||||
**Required Fidelity Surfaces** |
||||
- Fonts and typography: title size, weight, gradient, chart labels, and values now follow the reference source; ten-town density remains intentionally higher than the five-category reference. |
||||
- Spacing and layout: four-card stacks, 398px design width, 12px gaps, and the existing left/right perspective are unchanged. |
||||
- Colors and tokens: the foreground dimming veil is removed; card fill, border cyan, title gradient, and chart colors remain source-aligned. |
||||
- Image quality: original SVG card assets are byte-identical to the reference project; no replacement raster or CSS approximation was introduced. |
||||
- Copy and content: real Hongyuan business titles and ten-town data are preserved. |
||||
- Primary interaction and console check: homepage loaded successfully; no browser warnings or errors were recorded. |
||||
|
||||
**Findings** |
||||
- No remaining actionable P0/P1/P2 mismatch in the homepage card brightness treatment. |
||||
- P3: the ten-town chart necessarily uses smaller labels than the five-item reference chart; this is an intentional data-density difference requested for the project. |
||||
# Admin User Management Design QA |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-18 Visual Differentiation, Input, Toolbar, and Performance Pass |
||||
|
||||
**Scope** |
||||
- Branch: `V2.2` |
||||
- Runtime: `http://127.0.0.1:5173` |
||||
- Verified viewport: `1920 × 1080` (16:9) |
||||
- Release boundary: local source and local Vite runtime only; no commit, push, deployment, production write, or online update |
||||
|
||||
**Visual Corrections** |
||||
- Ecological redline / natural protected area: `草原级占比` now uses a rose chart, so it no longer repeats the ranked-horizontal-bar grammar used by `湿地面积` on the same screen. |
||||
- Home: `牦牛存栏分布` now uses the supplied cyan line/area language with dashed value grid, horizontal town axis, luminous line, filled area, and labels on the three largest peaks. The real town data and card dimensions are unchanged. |
||||
- Yak industry chain: the nine-stage toolbar is constrained to the center map safe area. Its measured rectangle is `x=442–1478`; the left card rail ends at `x=430` and the right rail begins at `x=1490`, leaving a `12px` gap on both sides. All nine labels remain visible and clickable. |
||||
- Smart management: the input shell is `864 × 54px`; the inner text field is `668 × 38px`. Search, text input, voice, and send affordances now have consistent spacing, borders, focus hierarchy, and disabled opacity without changing their behavior. |
||||
|
||||
**Performance Findings and Fixes** |
||||
- Root cause 1: Yak Management mounted structure, epidemic, and trade requests together. Structure entry previously triggered 10 endpoint requests (3 structure + 4 epidemic + 3 trade) even though only one business view was visible. |
||||
- Fix: data is now requested once per first-visible business view. Structure entry triggers only its three endpoints; epidemic and trade load on first use and are then retained for subsequent tab visits. Year changes still perform their explicit refresh. |
||||
- Root cause 2: switching between epidemic and trade reset the same already-mounted 3D map and scheduled a full map load again. |
||||
- Fix: the shared 3D map is retained; those switches now update the layer/ranking and refresh the existing view without resetting map readiness or reloading assets. |
||||
- Controlled in-app-browser timing sample: Home → Yak Management visible `3546ms → 3290ms`; Structure → Epidemic visible `757ms → 389ms`; Epidemic → Trade remained effectively flat (`3392ms → 3334ms`) because first-time chart construction is still the dominant synchronous cost. The implemented request and map fixes avoid hidden work without weakening data correctness. |
||||
|
||||
**Accepted Evidence** |
||||
- Ecology before: `tmp/duplicate-chart-audit-20260718/01-eco-before.png` |
||||
- Home before: `tmp/duplicate-chart-audit-20260718/02-home-before.png` |
||||
- Home after: `tmp/duplicate-chart-audit-20260718/04-home-after.png` |
||||
- Ecology after: `tmp/duplicate-chart-audit-20260718/05-eco-after.png` |
||||
- Industry toolbar after: `tmp/duplicate-chart-audit-20260718/06-industry-after.png` |
||||
- Smart input after: `tmp/duplicate-chart-audit-20260718/07-smart-after.png` |
||||
- User references: the four `/var/folders/.../codex-clipboard-*.png` images provided in this task |
||||
|
||||
**Validation** |
||||
- Production build: `npm run build` passed. |
||||
- `git diff --check`: passed. |
||||
- Browser interactions: nine industry stages present; smart textbox, voice button, and send button present; ecology and home target charts rendered at 1920 × 1080. |
||||
- Console: no new Vue/runtime errors were introduced. Existing nonblocking local warnings include a Cesium height-reference warning, occasional ECharts zero-size warnings during HMR, and an ecological API timeout that falls back to the local screen data. |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-17 Secondary Navigation Hierarchy |
||||
|
||||
**Issue** |
||||
- The bottom topic switcher visually outweighed the primary top navigation: its outer height, item height, typography, and ecological-protection width were all larger than the first-level menu. |
||||
|
||||
**Fix** |
||||
- Shared secondary switcher outer height: `32px`; item height: `26px`; label size: `13px`. |
||||
- Primary menu remains `34px` high with `14px` labels at the rendered 1920×1080 viewport. |
||||
- Ecological-protection topic items were reduced to `120px` each; the five-item switcher now measures `614px` including gaps and padding. |
||||
- The same compact shared component now serves Forest/Grass/Wet, Ecological Protection, Home, Yak Management, and Yak Industry Chain. |
||||
|
||||
**Validation** |
||||
- No label overflow in Ecological Protection, Forest/Grass/Wet, or Yak Industry Chain. |
||||
- Accepted screenshot: `tmp/chart-dup-audit/22-secondary-menu-final-retry.png`. |
||||
- Browser console errors: none. |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-17 Screen V2.2 KPI, Menu, and Forest Chart Correction |
||||
|
||||
**Viewport** |
||||
- Verified at the required `1920 × 1080` 16:9 viewport. |
||||
- Document size remained exactly `1920 × 1080`; no horizontal or vertical overflow was introduced. |
||||
|
||||
**Home KPI and Navigation** |
||||
- Home KPI rail moved down to `y = 96px` and narrowed to `936px` (`x = 492px`, right edge `1428px`) so it no longer stretches toward the side panels. |
||||
- Shared top navigation items now use an `18px` restrained pill radius instead of hard square blocks. |
||||
- Shared bottom topic navigation uses a `26px` capsule shell with semicircular ends; the home switcher measures `384 × 50px` and remains centered. |
||||
|
||||
**Forest / Grass / Wet Chart Differentiation** |
||||
- Grass distribution remains a restrained thin-column comparison. |
||||
- Wetland distribution is now a line/area comparison with point values and hover-only tooltip; endpoint labels are inset to avoid clipping. |
||||
- Woodland distribution remains a column-plus-line combination, so the three adjacent panels no longer repeat one column-chart grammar. |
||||
|
||||
**Runtime Checks** |
||||
- Verified through the local Vite dev server and in-app browser after hot reload. |
||||
- Vite was restarted explicitly with `--host 127.0.0.1 --port 5173 --strictPort` after an invalid implicit HMR socket was detected. |
||||
- Browser logs contained no errors after the corrected Vite session connected at `10:02:21Z`; only existing nonblocking warnings remained. |
||||
- `git diff --check` passed. |
||||
- No production build, push, deployment, production write, or online-server access was performed. |
||||
|
||||
final result: passed |
||||
- Source visual truth: |
||||
- `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-4f350d7a-605f-4e3a-af3a-baef9478d5a3.png` |
||||
- `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-9a503763-7c19-436d-b9a5-734fd8d88ac5.png` |
||||
- Implementation screenshots: |
||||
- `design-qa-assets/admin-users-748x900.png` |
||||
- `design-qa-assets/admin-users-1920x1080.png` |
||||
- Viewports: 748 × 900 CSS px and 1920 × 1080 CSS px. |
||||
- Pixel dimensions: source crops are 748 × 330 and 748 × 72; implementation captures match their stated CSS viewport at device scale 1. |
||||
- State: authenticated user-management default list after Magic API reload. |
||||
|
||||
## 2026-07-17 Guidance, Menu, and Chart Restraint Pass |
||||
|
||||
**Scope** |
||||
- Branch: `V2.2` |
||||
- Runtime: local Vite/HMR at `http://127.0.0.1:5173` |
||||
- Viewport: `1920 × 1080` (16:9) |
||||
- Release boundary: local only; no commit, push, deploy, production write, or online update |
||||
- Yak industry-chain boundary: business cards, charts, data, and logic unchanged; only shared top and bottom navigation styling unified |
||||
|
||||
**Implemented** |
||||
- Smart management: removed the three starter cards, introductory guidance copy, and capability-boundary note. Empty state now contains only the AI mark and `智慧辅助分析`, with the primary input remaining available. |
||||
- Shared topic menu: removed left/right arrow controls from `TopicSwitcher`, added tab semantics, and replaced module-specific textures with one compact shared segmented-navigation treatment. |
||||
- Home: removed the oversized bottom-tab trough; town columns now use one restrained cyan and no decorative cap or duplicate trend overlay. |
||||
- Forest/grass/wet and ecology: ordered town columns use one cyan family and no pictorial water caps. On the overview screen, adjacent grassland, wetland, and woodland panels now use thin columns, rounded columns, and one intentional woodland trend overlay so the three panels do not repeat the same expression. Pie/donut charts retain category colors because hue encodes distinct categories. |
||||
- Yak management: herd-composition slices retain six category colors; ordered town ranks, epidemic ranks, and trade-impact columns use restrained cyan. Decorative pictorial caps, bases, and scatter endpoints were removed where they did not encode data. |
||||
- Pasture management: township household and grassland rankings use one cyan accent; the age chart no longer adds a duplicate line overlay. |
||||
- Shared top navigation: the yak industry-chain module now receives the same rectangular top-menu state as the other modules, while its business body remains untouched. |
||||
|
||||
**Browser Verification** |
||||
- Home: compact four-tab bottom menu; no arrows; town columns single cyan. |
||||
- Smart management: DOM contains only AI mark, `智慧辅助分析`, textbox, voice input, and send button; no guide cards or boundary note. |
||||
- Forest/grass/wet overview: the three town-distribution cards share one restrained cyan palette but use visibly different marks; category charts remain distinguishable. |
||||
- Yak management structure: six herd categories are visibly distinct; town ranking uses one cyan without decorative end markers. |
||||
- Yak epidemic: statistical bars have no pictorial top/base caps; owner ranking has no white endpoint scatter. |
||||
- Pasture management: household and grassland rankings use one cyan. |
||||
- Yak industry chain: all ten stage tabs render in the shared bottom component, stage switching was tested, and the top navigation matches other modules. |
||||
|
||||
**Evidence** |
||||
- Updated comparison after-captures: `deliverables/v2.2-ui-comparison/screenshots/after/02-home.jpg`, `03-forest-overview.jpg`, `12-yak-structure.jpg`, `14-yak-epidemic.jpg`, `16-pasture-management.jpg`, and `17-smart-management.jpg` |
||||
- Shared-menu current-state capture: `deliverables/v2.2-ui-comparison/screenshots/after/19-yak-industry-chain-menu.jpg` |
||||
- All listed screenshots: JPEG, `1920 × 1080` |
||||
|
||||
**Validation** |
||||
- `git diff --check`: passed |
||||
- Removed-pattern scan outside the intentionally unchanged industry-chain business body: no smart guide blocks, topic arrows, water-cap variants, duplicate trend overlays, or production `pictorialBar` chart decorations remain |
||||
- No production build was run for this local HMR-only UI pass; repository guidance prefers browser verification for app-code/style changes and reserves builds for release/configuration work |
||||
## Full-view comparison evidence |
||||
|
||||
final result: passed |
||||
- The source showed a horizontal form overflowing beyond the card and action buttons wrapping under the first field. At 748 px the implementation now collapses the sidebar, keeps all six controls inside the card, and places actions in a dedicated right-aligned row. |
||||
- The source showed a secondary explanatory sentence below the page title. The implementation removes that sentence on user management, operation logs, and login logs. |
||||
- At 1920 px the filter card uses a balanced three-column grid and the table remains fully usable. |
||||
|
||||
## 2026-07-17 KPI, Adjacent-Chart Variety, And Forecast Alignment Correction |
||||
|
||||
**Scope** |
||||
- Runtime: local Vite/HMR and local Docker services only |
||||
- Route base: `http://127.0.0.1:5173/#/platform` |
||||
- Design canvas: 16:9; application layout uses the existing 1920 × 1080 autofit canvas |
||||
- Release boundary: no commit, push, deploy, production read, or online write |
||||
|
||||
**Implemented** |
||||
- Home KPI strip: changed each of the five dense indicators to a two-row structure. The label sits above the value/unit row, while the existing icon remains on the left. |
||||
- Forest/grass/wet overview: kept one restrained cyan family, but changed the three adjacent distributions to thin columns, rounded wide columns, and a slim column-plus-line combination. |
||||
- Column header spacing: increased the reserved unit-label area so `单位:万亩` no longer collides with the highest value. |
||||
- Forecast year selector: widened the shared selector container and removed the child-button minimum width that exceeded the parent's content box. |
||||
|
||||
**Browser Verification** |
||||
- Home: all five value and unit boxes stay within their KPI cards; every label is above its corresponding value. |
||||
- Forest/grass/wet: rendered classes are `is-variant-plain`, `is-variant-rounded`, and `is-variant-slim`; only woodland contains the meaningful trend overlay. |
||||
- All three distribution units end above the first value label with no rectangle overlap. |
||||
- Forecast: the 2026, 2027, and 2028 button rectangles are all contained by the forecast selector rectangle. |
||||
- Browser console error check: no errors. |
||||
|
||||
**Evidence** |
||||
- Home after: `tmp/v22-correction-audit/04-home-after.png` |
||||
- Forest/grass/wet after: `tmp/v22-correction-audit/05-forest-after.png` |
||||
- Forecast after: `tmp/v22-correction-audit/06-forecast-after.png` |
||||
- Updated 1920 × 1080 comparison after-captures: `deliverables/v2.2-ui-comparison/screenshots/after/02-home.jpg`, `03-forest-overview.jpg`, and `13-yak-forecast.jpg` |
||||
|
||||
**Validation** |
||||
- Local Docker services required by authentication and APIs are running. |
||||
- Vite HMR applied all source/style changes successfully. |
||||
- No production build was run; repository guidance prefers browser verification for this local-only UI pass. |
||||
## Focused region comparison evidence |
||||
|
||||
final result: passed |
||||
- Filter labels use a fixed 76 px label track with flexible controls, preventing the clipped `用户昵称` case shown in the source. |
||||
- The first two data rows are `超级管理员` users; the first ordinary `牧户` user follows after them. |
||||
- Querying phone `18015775886` returns one row and retains the `超级管理员` tag. Reset restores the administrator-first order. |
||||
|
||||
## 2026-07-13 Yak Industry Chain Stage Rhythm Pass |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=yak-industry-chain` |
||||
- Files changed: |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/yakIndustryChain/data.js` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/yakIndustryChain/index.vue` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/screen2-ui-standard.md` |
||||
|
||||
**Stage Audit** |
||||
- Checked all 10 bottom stages: 家庭生态牧场、人工种草、规模化养殖基地、选育/扩繁基地、防灾减灾、奶源站、屠宰与加工、农机装备、牧草交易、社会化服务. |
||||
- All left sides render 4 visible cards. |
||||
- Generic right-side stages now follow the four-slot rhythm: list card `466px` + `环节核心指标 227px` + `建设要点 239px`. |
||||
- Artificial grassland remains four separate right cards; family pasture remains `2+1+1`. |
||||
|
||||
**Fixes** |
||||
- Removed accidental `fillHeight` stretching from generic right-side `环节核心指标` and `建设要点`, which had made those cards `306/322px` and broke the four-slot rhythm. |
||||
- Added empty-state handling for yak-industry town column panels. When a stage has no positive business data, the panel shows `暂无业务统计数据` instead of an empty coordinate grid. |
||||
- Updated the UI standard: no-data charts must not render empty axes/grids. |
||||
|
||||
**Evidence** |
||||
- 规模化养殖基地 fixed screenshot: `/tmp/screen2-standard-audit/yak-industry-规模化养殖基地-fixed-20260713.png` |
||||
- 奶源站 empty-state screenshot: `/tmp/screen2-standard-audit/yak-industry-奶源站-empty-standard-20260713.png` |
||||
- 牧草交易 empty-state screenshot: `/tmp/screen2-standard-audit/yak-industry-牧草交易-empty-standard-20260713.png` |
||||
- Browser console error check: no errors. |
||||
- Production build check: `npm run build` passed. |
||||
## Required fidelity surfaces |
||||
|
||||
final result: passed |
||||
- Fonts and typography: existing PingFang/Alibaba PuHui system stack preserved; labels, headings, and table hierarchy remain consistent. |
||||
- Spacing and layout rhythm: fixed overflow replaced by responsive 3/2/1-column grid; cards retain existing radius and elevation. |
||||
- Colors and visual tokens: existing Ant Design primary blue, neutral background, borders, and semantic states preserved. |
||||
- Image quality and assets: no raster assets are required by this admin UI; existing Ant Design icon components are preserved. |
||||
- Copy and content: all requested page-description remarks are removed; functional labels and data remain unchanged. |
||||
|
||||
## 2026-07-13 Ecological National Park Top Metrics |
||||
## Comparison history |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=ecological-protection&view=national-park` |
||||
- File changed: `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/platform/index.vue` |
||||
- Screenshot evidence: `/tmp/screen2-standard-audit/ecology-national-park-top-metrics-home-style-stable-20260713.png` |
||||
- Earlier P1: filter controls overflowed the card and wrapped unpredictably. Fixed with responsive grid tracks, fixed label widths, fluid controls, and automatic sidebar collapse. Post-fix evidence: `admin-users-748x900.png`. |
||||
- Earlier P2: explanatory remarks consumed vertical space and were explicitly unwanted. Removed from all three admin pages. Post-fix evidence: DOM checks and both implementation screenshots. |
||||
- Earlier P1: ordinary users could precede real administrators. Fixed in the Magic API query with an active `admin` role priority expression. Post-fix evidence: first two table rows in `admin-users-1920x1080.png`. |
||||
|
||||
**Fix** |
||||
- The national park five-metric strip now reuses the homepage top-stat presentation instead of a custom full-width summary band. |
||||
- Removed the top-stat sweep pseudo-background inside the platform top metric area so five indicators no longer visually merge into one dark translucent bar. |
||||
- Added a compact national-park five-item rule so `公益岗位` stays clear of the right-side cards while preserving the homepage-style icon, label, value and unit. |
||||
## Primary interactions tested |
||||
|
||||
**Validation** |
||||
- Browser check at `1920x1080`: five metrics render as separate homepage-style indicators. |
||||
- Computed top metric wrapper: `display: flex`, width `1100px`, no summary-strip background. |
||||
- First right-side card begins at `x=1502`; last metric ends at `x=1528`, with text no longer sitting on the right-card title area. |
||||
- Browser console error check: no errors. |
||||
- User phone filter and reset. |
||||
- User list server pagination response after Magic API resource reload. |
||||
- Operation-log and login-log page rendering with descriptions removed. |
||||
- Browser console checked: zero errors. |
||||
|
||||
final result: passed |
||||
## Findings |
||||
|
||||
## 2026-07-13 Platform Loading And Yak/Pasture Recheck |
||||
|
||||
**Scope** |
||||
- Pages: |
||||
- `http://127.0.0.1:5174/#/platform?module=yak-industry-chain` |
||||
- `http://127.0.0.1:5174/#/platform?module=pasture-management` |
||||
- `http://127.0.0.1:5174/#/platform?module=yak-management&view=epidemic` |
||||
- File changed: `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/platform/index.vue` |
||||
- Screenshot evidence: |
||||
- `/tmp/screen2-standard-audit/audit-yak-industry-chain-loading-fixed-20260713.jpg` |
||||
- `/tmp/screen2-standard-audit/audit-pasture-management-loading-fixed-20260713.jpg` |
||||
- `/tmp/screen2-standard-audit/audit-yak-management-epidemic-clean-20260713.jpg` |
||||
|
||||
**Fix** |
||||
- Added a platform startup-loading safety timeout: |
||||
- Homepage keeps up to `12s`. |
||||
- Other platform-loading modules keep up to `8s`. |
||||
- This prevents Yak Industry Chain and Pasture Management from remaining covered by a `100%` platform loading layer when map initialization is slow or background-tab rendering is throttled. |
||||
|
||||
**Validation** |
||||
- Yak Industry Chain: loading node removed; top metrics render with real values; console error check passed. |
||||
- Pasture Management: loading node removed; top metrics render with real values; yellow yak-recognition layer remains. |
||||
- Yak Management / Epidemic: clean reload shows active `2026`, top metric `涉及村数 10 个`, and no console errors. |
||||
- `npm run build` passed; remaining warnings are existing Cesium/Sass/chunk-size warnings. |
||||
- No actionable P0, P1, or P2 issue remains for the requested changes. |
||||
|
||||
final result: passed |
||||
## Follow-up polish |
||||
|
||||
## 2026-07-13 Forest-Grass-Wet / National Park Follow-Up QA |
||||
|
||||
**Scope** |
||||
- Pages: |
||||
- `http://127.0.0.1:5174/#/platform?module=forest-grass-wet` |
||||
- `http://127.0.0.1:5174/#/platform?module=ecological-protection&view=national-park` |
||||
- Files changed: |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/platform/index.vue` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/services/openApi.js` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/ecologicalProtection/data.js` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/forestGrassWet/components/BusinessPanelRenderer.vue` |
||||
- Screenshot evidence: |
||||
- `/tmp/screen2-standard-audit/forest-grass-wet-overview-final-20260713.jpg` |
||||
- `/tmp/screen2-standard-audit/forest-grass-wet-woodland-click-final-20260713.jpg` |
||||
- `/tmp/screen2-standard-audit/national-park-final-20260713.jpg` |
||||
|
||||
**Fix** |
||||
- Four-item top metric layout now has more horizontal room and smaller four-card-specific icon/value/unit sizing, so long values such as `林草湿面积 1226.11 万亩` no longer visually clip. |
||||
- Platform startup loading now only remains for modules that actively report platform-level loading progress; direct links to Forest-Grass-Wet, Ecological Protection, Yak Management and Smart Management no longer stay covered by a 100% loading mask. |
||||
- Woodland `优势树种面积` now uses the compact no-wrap rank-bar treatment instead of the larger default bar style. |
||||
- National Park `公益岗位分布` uses the homepage-like thin-column style, matching the restrained chart direction. |
||||
|
||||
**Validation** |
||||
- Browser check: bottom `林地资源` was clicked through the real UI state, not a guessed URL query. |
||||
- Forest-Grass-Wet overview: no platform loading mask; top metric text is present in DOM; left/right cards keep the current restrained cyan-blue style. |
||||
- Woodland: `林地面积分布` and `优势树种面积` both present; right-side `优势树种面积` text remains readable and no longer fills the entire card width. |
||||
- National Park: grass/wetland stacked columns and job distribution keep weaker glow and clearer labels. |
||||
- Browser console error check: no errors. |
||||
- `npm run build` passed; remaining warnings are existing Cesium/Sass/chunk-size warnings. |
||||
- On very narrow widths, the wide table intentionally scrolls horizontally; fixed identity/status/action columns preserve the core task. |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-13 Yak Management Trade Right Rhythm |
||||
--- |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=yak-management&view=trade` |
||||
- File changed: `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/yakManagement/index.vue` |
||||
- Screenshot evidence: `/tmp/screen2-standard-audit/yak-trade-right-four-slot-fixed-20260713.png` |
||||
# V3 湿地详情与优势小类 Design QA |
||||
|
||||
**Fix** |
||||
- Removed manual height offsets from the trade right column. |
||||
- `出栏来源排行` now uses one standard side-card height. |
||||
- `交易出证台账` now uses the shared `getScreen2SpanHeight(sideCardHeight, 2)` two-slot formula. |
||||
- Source visual truth: |
||||
- `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-aa4dddc8-f0fc-49c0-b747-2d91faaeee84.png` |
||||
- `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-7c67797b-b847-4cef-bc14-f87d626013e7.png` |
||||
- `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-088c5496-47e0-4855-b0ef-1db3743a6c90.png` |
||||
- Implementation screenshot: `/Users/mocker/Documents/code/hy-screen/v3/screen/design-qa-assets/20260814-wetland-detail-v3-final.png` |
||||
- Viewport: 1920 × 1080 CSS px, device scale 1. |
||||
- Pixel dimensions: source detail crops are 742 × 454 and 936 × 456; the clipped advantages crop is 628 × 370; implementation capture is 1920 × 1080. The focused panel and chart regions were compared without density normalization. |
||||
- State: 林草湿资源 → 湿地资源 → 湿地分布,选中查尔玛乡达尔龙村目标湿地。 |
||||
|
||||
**Validation** |
||||
- Browser check at `1920x1080`. |
||||
- Right side measured as `出证结构统计 239px` + `出栏来源排行 227px` + `交易出证台账 466px`. |
||||
- Left side remains four cards: `246px + 227px + 227px + 246px`. |
||||
## Full-view comparison evidence |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-13 Ecological Protection National Park Chart Cleanup |
||||
- The wetland detail panel starts below the three top KPI cards and no longer overlaps or hides them. |
||||
- All nine legacy detail rows fit inside the panel at the 1920 × 1080 baseline, with no vertical clipping or scroll required. |
||||
- The surrounding map, KPI rail, charts, layer selector, navigation, and visual theme remain intact. |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=ecological-protection&view=national-park` |
||||
- Files changed: |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/ecologicalProtection/data.js` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/forestGrassWet/components/BusinessPanelRenderer.vue` |
||||
- Screenshot evidence: `/tmp/screen2-standard-audit/national-park-chart-style-optimized-v2-20260713.png` |
||||
## Focused region comparison evidence |
||||
|
||||
**Fix** |
||||
- Kept the park business dimensions unchanged: grass/wetland area, grass/wetland productivity, township yak count, balance, zoning, households, jobs, capacity. |
||||
- National park grass/wetland stack columns now use a restrained slim style: thin body, light grid, weak glow, values above the bars. |
||||
- `乡镇牦牛数量` now uses a single lightweight horizontal distribution style. |
||||
- `公益岗位分布` now uses the homepage-like `plain` thin-column treatment instead of the stronger glowing column style. |
||||
- The detail contract exactly matches the old system: 湿地类型、所在区域、湿地面积、地类名称、湿地级别、鲜草产量、干草产量、小班干草产量、小班鲜草产量。 |
||||
- The selected legacy sample renders as 矮生嵩草、杂类草型 / 查尔玛乡达尔龙村 / 709.68亩 / 沼泽草地 / 2级湿地 / 1752.06斤 / 2.77吨 / 41.45吨 / 148.79吨。 |
||||
- `数据年份` is absent from the detail DOM and screenshot. |
||||
- All six `湿地优势小类` names render on one line and remain fully readable; the previous ellipsis/clipping is gone. |
||||
|
||||
**Validation** |
||||
- Browser check at `1920x1080`. |
||||
- Left side keeps four cards: `246px + 227px + 227px + 246px`. |
||||
- Right side keeps four cards: `239px + 227px + 227px + 239px`. |
||||
- Browser console error check: no errors. |
||||
- `npm run build` passed; remaining warnings are existing Cesium/Sass/chunk-size warnings. |
||||
## Required fidelity surfaces |
||||
|
||||
final result: passed |
||||
- Typography: existing V3 font family and hierarchy are preserved; field labels remain quieter than values. |
||||
- Spacing and layout: the panel keeps its intended height and uses a preferred top offset of 190 px, preventing collision with the KPI rail. |
||||
- Colors: existing dark translucent panels, cyan borders, aqua highlights, and chart palette are unchanged. |
||||
- Image assets: existing terrain map, frame assets, chart icons, and map overlays are preserved without resampling. |
||||
- Copy and content: the old-system nine-field wording, order, values, and units are restored; no data-year field is shown. |
||||
|
||||
## 2026-07-13 Cross-Module Four-Card Continuation |
||||
|
||||
**Scope** |
||||
- Excluded as requested: Grass-Livestock Balance, Smart Management. |
||||
- Checked modules: Home, Forest-Grass-Wet, Ecological Protection, Yak Management, Pasture Management, Yak Industry Chain. |
||||
- Viewport: `1920x1080`. |
||||
- Local route base: `http://127.0.0.1:5174/#/platform`. |
||||
|
||||
**New Evidence** |
||||
- Ecological Protection / National Park right side four cards: `/tmp/screen2-standard-audit/ecological-national-park-right-four-20260713.png` |
||||
- Ecological Protection / Ecological Redline right side four cards: `/tmp/screen2-standard-audit/ecology-ecological-redline-right-four-20260713.png` |
||||
- Ecological Protection / Natural Protected Area right side four cards: `/tmp/screen2-standard-audit/ecology-natural-protected-area-right-four-20260713.png` |
||||
- Yak Management / Epidemic right side four-slot layout: `/tmp/screen2-standard-audit/yak-management-epidemic-map-visible-check-20260713.png` |
||||
- Yak Industry Chain / Artificial Grassland real topic click verification: `/tmp/screen2-standard-audit/yak-industry-artificial-real-20260713.png` |
||||
- Forest-Grass-Wet shared renderer cleanup: `/tmp/screen2-standard-audit/forest-grass-wet-overview-shared-style-20260712.png` |
||||
- Pasture Management glow cleanup: `/tmp/screen2-standard-audit/pasture-management-glow-cleanup-20260712.png` |
||||
|
||||
**Fixes Completed** |
||||
- Ecological Protection national park right side no longer has a blank fourth slot; added `草畜承载能力` as a metric card. |
||||
- Ecological redline and natural protected area right side now use four cards: |
||||
- `草原类型`: ring chart |
||||
- `草原级占比`: rank bar |
||||
- `林地质量`: heat/grade grid |
||||
- `林草湿面积构成`: structure band |
||||
- Yak Management epidemic view now uses `乡镇覆盖均衡 + 村级覆盖进度 + 防疫记录台账(2 slots)` instead of one full-height ledger. |
||||
- Yak Industry Chain artificial grassland topic was verified through the real bottom topic switch, not a guessed URL parameter; left and right sides both render four cards. |
||||
- Shared `BusinessPanelRenderer` glow was reduced for heat cells, structure bands and split rows so retained charts match the current restrained cyan-blue system. |
||||
|
||||
**Open Follow-Up** |
||||
- Engineering Analysis is an independent workspace rather than a side-card dashboard; it should be reviewed with its own workflow standard instead of forcing four side cards. |
||||
- Full production deployment was not performed in this pass. |
||||
|
||||
## 2026-07-13 Cesium Map Label Crispness |
||||
|
||||
**Scope** |
||||
- Shared component: `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/components/CesiumMap/index.vue` |
||||
- Affected modules: Forest-Grass-Wet, Ecological Protection, Pasture Management, Yak Management, Yak Industry Chain. |
||||
- Viewport: `1920x1080`. |
||||
|
||||
**Issue** |
||||
- Township badges on the 3D map looked soft/blurry. |
||||
- Cause: the badges are rendered as canvas images and then displayed as Cesium billboards inside a WebGL scene. When Cesium renders at browser-recommended 1x resolution and FXAA is enabled, the whole scene is post-processed, so text textures become softened. |
||||
|
||||
**Fix** |
||||
- Enabled high-DPI Cesium rendering with `useBrowserRecommendedResolution: false`. |
||||
- Set `viewer.resolutionScale` to the current device pixel ratio, capped at `2`. |
||||
- Disabled Cesium FXAA post-process for this shared map to avoid blurring billboard text. |
||||
- Regenerated township badge cache (`v14-crisp-map-badge`) with 3x-4x canvas backing pixels. |
||||
- Removed glow blur from the badge text and kept a thinner dark outline for readable but sharper labels. |
||||
|
||||
**Validation** |
||||
- Screenshot evidence: `/tmp/screen2-standard-audit/cesium-label-crisp-20260713.png` |
||||
- Browser route verified: `http://127.0.0.1:5174/#/platform?module=forest-grass-wet` |
||||
- Browser console: only external resource 404s during local map loading; no Vue/runtime errors. |
||||
## Comparison history |
||||
|
||||
final result: passed |
||||
- Iteration 1 — P1: the detail panel was clamped upward and overlapped the top KPI cards. Fixed by preserving the desired panel height and honoring the 190 px preferred top position. |
||||
- Iteration 1 — P2: the previous implementation did not expose the full old-system wetland detail contract. Fixed across the V3 migration, API DTO, and UI row builder. |
||||
- Iteration 1 — P2: long `湿地优势小类` names were clipped. Fixed by applying the dedicated nowrap layout to this chart variant. |
||||
- Iteration 2: final screenshot confirms no overlap, all nine detail rows visible, and all six long category names complete. |
||||
|
||||
## 2026-07-13 Ecological Restoration Chart Fixes |
||||
## Primary interactions and console |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=ecological-protection&view=restoration` |
||||
- Source files: |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/ecologicalProtection/data.js` |
||||
- `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/forestGrassWet/components/BusinessPanelRenderer.vue` |
||||
- Viewport: `1920x1080`. |
||||
- Switched to 湿地资源, enabled 湿地分布, and selected the exact legacy sample on the map. |
||||
- DOM assertion confirmed the nine labels and values above and confirmed `数据年份` is absent. |
||||
- Browser console checked after the final deployment: zero errors. |
||||
- Production build passed; `hy-v3-screen` and `hy-v3-openapi` are healthy. |
||||
|
||||
**Fixes** |
||||
- `治理面积分布`, `年度工程长度`, and `年度项目数量` now use horizontal year labels instead of vertical split digits. |
||||
- `乡镇治理面积分布` changed from a crowded horizontal bar list to the same water-column style used by `湿地面积`, with horizontal township labels and no horizontal scrollbar. |
||||
## Findings |
||||
|
||||
**Validation** |
||||
- Year-axis screenshot evidence: `/tmp/screen2-standard-audit/ecology-restoration-year-axis-fixed-20260713.png` |
||||
- Township water-column screenshot evidence: `/tmp/screen2-standard-audit/ecology-restoration-town-column-20260713.png` |
||||
- Automated DOM check confirmed the target township panel renders as `business-columns is-variant-water is-dense has-unit-label`. |
||||
- No actionable P0, P1, or P2 issue remains in the requested scope. |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-12 Homepage Chart Variety Pass |
||||
--- |
||||
|
||||
> Superseded on 2026-07-17 by the full-screen chart-grammar audit below. The homepage no longer reuses the same vertical-column grammar for grassland, wetland, and yak stock. |
||||
# 自然保护地“湿地面积”图表 Design QA |
||||
|
||||
**Scope** |
||||
- Page: `http://127.0.0.1:5174/#/platform?module=home` |
||||
- Source file: `/Users/mocker/Documents/code/hy-screen/screenV2.0/src/views/home/index.vue` |
||||
- Screenshot evidence: `/tmp/screen2-home-left-chart-stack-qa.png` |
||||
- Source visual truth: `/Users/mocker/Documents/code/hy-screen/v3/evidence/ui-fix/20260814-ecowet-chart-style/05-final.jpg` |
||||
- Implementation screenshot: `/Users/mocker/Documents/code/hy-screen/v3/evidence/ui-fix/20260814-natural-wet-chart-style/02-final.jpg` |
||||
- Before screenshot: `/Users/mocker/Documents/code/hy-screen/v3/evidence/ui-fix/20260814-natural-wet-chart-style/01-before.jpg` |
||||
- Viewport and pixel dimensions: 534 × 872 CSS px, device scale 1; all comparison images are 534 × 872 px. |
||||
- State: ecological-protection module, `natural-protected-area` selected, default township scope. |
||||
|
||||
**Design Rule** |
||||
- The same screen must not repeat the exact same chart expression for adjacent cards. |
||||
- Chart style differences must come from the business reading task, not only from color changes. |
||||
## Full-view comparison evidence |
||||
|
||||
**Homepage Mapping** |
||||
- 草地面积: vertical bar, used for ten-town area comparison without an extra trend overlay. |
||||
- 湿地面积: restrained vertical bar using the same ordered-comparison grammar as grassland; category distinction comes from the panel title and values, not ornamental color changes. |
||||
- 草原类别: category proportion card, used for structure reading. |
||||
- 草地生产力: area line chart, used for productivity trend-like comparison. |
||||
- 牦牛存栏分布: restrained vertical bar for town livestock scale comparison without a duplicate trend overlay. |
||||
- 畜群结构: donut chart, used for herd composition. |
||||
- 草畜平衡: gauge cards, used for status comparison. |
||||
- The target and implementation were opened side by side at the same viewport and application state. |
||||
- The natural-protected-area wetland card now uses the same circular rank badge, cyan progress bar, area/value hierarchy, and percentage pill as the accepted ecological-redline chart. |
||||
- The card position, title treatment, map hierarchy, and neighboring panels remain unchanged. |
||||
|
||||
**Parameter Checks** |
||||
- Grassland and wetland both use full-width vertical composition, avoiding the right-side emptiness caused by the previous horizontal rank layout. |
||||
- Grassland, wetland, and yak-town comparisons now use the same restrained cyan column grammar; decorative water caps are not used. |
||||
- Yak stock distribution no longer overlays the same values as a trend line; combined bar-line charts are reserved for genuinely different measures. |
||||
- Background bars are dimmed to keep the data layer dominant. |
||||
- Browser console error check: no errors. |
||||
## Focused region comparison evidence |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-17 Full-Screen Chart Grammar Audit |
||||
|
||||
**Scope** |
||||
- Viewport: `1920 × 1080` (16:9). |
||||
- Coverage: 27 visible states across Home (1), Forest/Grass/Wet (4), Ecological Protection (5), Yak Management (4), Pasture Management (1), Yak Industry Chain (10), Smart Management (1), and Grass-Livestock Balance (1). |
||||
- Rule: chart duplication is evaluated across the whole visible screen, including both side rails. Recoloring or changing bar width alone does not count as a different expression. |
||||
|
||||
**Implemented Changes** |
||||
- Forest/Grass/Wet: panel diversification now runs across the combined left/right layout instead of independently per side. Grassland, wetland, woodland, and their layer-topic variants share the same screen-level rule. |
||||
- Home: grassland remains a vertical comparison column; wetland is a horizontal ranking; yak stock is a lollipop chart; productivity remains a line. |
||||
- Ecological Protection: wetland distribution is a ranked list rather than a duplicate column; national-park productivity is a line rather than a second stacked column; restoration year length is a horizontal ranking and project count is a heat grid. |
||||
- Pasture Management: household age uses a structure chart rather than repeating the household-distribution column. |
||||
- Yak Industry Chain: artificial-grassland annual construction is a line; equipment service distribution is a heat grid; training distribution is a horizontal ranking; fallback town coverage is a heat grid. |
||||
|
||||
**Runtime Audit Results** |
||||
- Ecological redline and natural protected area each render the unique sequence: `column / rank / split / line / donut / bar / heat / structure`. |
||||
- National park renders: `stackColumn / line / bar / balanceGaugeGrid / donut / split / column`. |
||||
- Ecological restoration renders: `line / column / donut / bar / structure / heat / projectTable`. |
||||
- Yak Industry Chain tabs were switched one by one; affected stages no longer expose two same-grammar columns in the same state. |
||||
- Forest/Grass/Wet overview, grassland, wetland, and woodland states were switched and inspected independently. Cross-rail duplicate columns are removed; intentionally retained bar/donut pairs use materially different business grammars. |
||||
- Yak structure, forecast, epidemic, and trade were checked against their rendered ECharts canvases and source configurations; no repeated same-grammar columns were found. |
||||
- Smart Management and Grass-Livestock Balance do not render duplicated column-chart panels. |
||||
|
||||
**Accepted Screenshot Evidence** |
||||
- `tmp/chart-dup-audit/10-home-after.png` |
||||
- `tmp/chart-dup-audit/12-forest-overview-after.png` |
||||
- `tmp/chart-dup-audit/14-restoration-after.png` |
||||
- `tmp/chart-dup-audit/15-pasture-after.png` |
||||
- `tmp/chart-dup-audit/16-industry-equipment-after.png` |
||||
|
||||
**Validation Boundary** |
||||
- Vite development server and HMR were used for verification; no production build, push, deployment, or online write was performed. |
||||
- Live API values and WebGL map settling can vary between captures; chart type, ordering, label layout, and whole-screen visual grammar were the acceptance focus. |
||||
|
||||
final result: passed |
||||
- DOM inspection confirms the target card uses `.business-bars.is-rank-bar`; the natural-protected-area card now uses the same rank-bar structure and no longer renders the old `.business-list` presentation. |
||||
- All 7 rows fit within the card bounds with no overflow. |
||||
- Row copy, order, area values, and percentages are preserved: 邛溪镇、安曲镇、查尔玛乡、瓦切镇、阿木乡、麦洼乡、色地镇。 |
||||
|
||||
## 2026-07-16 Screen V2.2 Local Unified UI Pass |
||||
|
||||
**Scope** |
||||
- Branch: `V2.2` |
||||
- Baseline: V2.0 commit `87f624a` |
||||
- Rendered implementation: local V2.2 working tree at `http://localhost:5173` |
||||
- Comparison artifact: `deliverables/v2.2-ui-comparison/index.html` |
||||
- Viewport: `1920 × 1080` (16:9) |
||||
- Captured states: 18 before + 18 after + 18 combined comparisons |
||||
- Exclusion: “牦牛全产业链” business content was intentionally left unchanged; only its shared top and bottom menu presentation was unified on 2026-07-17 |
||||
- Release boundary: local only; no push, deploy, production write, or online update |
||||
|
||||
**QA Coverage** |
||||
- Typography: panel titles, secondary copy, KPI values, project tables, epidemic/trade ledgers, and dense labels were checked at the 1920 × 1080 target viewport. |
||||
- Spacing and layout: header, two side rails, map controls, topic switchers, legends, tables, and county boundaries remain inside the 16:9 safe area across all captured states. |
||||
- Colors and tokens: V2.2 uses the existing dark cyan product language with a scoped token layer. Township rankings now use one restrained cyan; herd composition uses six labeled, high-contrast category colors. |
||||
- Assets and image quality: maps and imagery were allowed to settle before capture. Every source screenshot is 1920 × 1080, nonblank, and paired with the same-state baseline. |
||||
- Copy and content: loading, timeout, retry, login help, and balance errors use user-facing language. Raw HTTP errors are not exposed. |
||||
- Accessibility: focus-visible states, password visibility control, caps-lock feedback, `aria-live` loading/error states, and inactive-module focus removal were checked in code and browser state. |
||||
|
||||
**Screen-State Matrix** |
||||
1. Login |
||||
2. Home |
||||
3. Forest/grass/wet resource overview |
||||
4. Grassland resources |
||||
5. Wetland resources |
||||
6. Woodland resources |
||||
7. Ecological redline |
||||
8. Natural protected area |
||||
9. National park |
||||
10. Ecological restoration |
||||
11. Engineering analysis |
||||
12. Yak herd structure |
||||
13. Yak forecast |
||||
14. Yak epidemic prevention |
||||
15. Yak trade |
||||
16. Pasture management |
||||
17. Smart management |
||||
18. Grass-livestock balance |
||||
|
||||
**Interaction Checks** |
||||
- Main module routes and retained-module visibility states work; inactive panes are removed from the focus order. |
||||
- Forest/grass/wet and ecological topic switchers preserve selected states and map safe areas. |
||||
- Yak structure/forecast/epidemic/trade switches work; map loading exposes a recoverable timeout state. |
||||
- Trade ledger density is limited to eight rows per page for the 16:9 layout. |
||||
- Smart management keeps the core AI workspace and input flow without starter cards, onboarding prompts, or capability-boundary notes. |
||||
- Grass-livestock balance keeps normal live data and maps failures to a retryable user-facing state. |
||||
- Comparison HTML filters to each module and its range control updates the before/after divider. |
||||
|
||||
**User-Feedback Verification** |
||||
- Pasture township charts: removed unrelated category hues; bar length and printed value now communicate ranking while a single cyan accent preserves visual consistency. |
||||
- Herd-composition chart: replaced near-identical cyan slices with cyan, blue, amber, green, violet, and coral. Legend labels and values remain present, so categories do not rely on color alone. |
||||
- Both changes were re-captured at 1920 × 1080 and rechecked in combined before/after images. |
||||
|
||||
**Build and Runtime Checks** |
||||
- Production build: passed with Vite output redirected to `/tmp/hy-screen-v22-build-final-color`. |
||||
- Application modules transformed: 1031. |
||||
- Browser console: no blocking application errors during the final capture set. |
||||
- Nonblocking existing warnings: Cesium height-reference warning, ECharts tick readability warning, Vite Cesium script/CSS resolution notice, and Sass legacy API deprecation notice. |
||||
|
||||
**Known Comparison Notes** |
||||
- Live local API data can change numeric values between V2.0 and V2.2 captures; visual and interaction changes are assessed independently of those data refreshes. |
||||
- Login field contents are hidden in screenshots for privacy. |
||||
- The baseline yak structure map was captured before all map labels settled; the V2.2 capture was allowed to stabilize and is materially more complete. |
||||
## Required fidelity surfaces |
||||
|
||||
final result: passed |
||||
|
||||
## 2026-07-18 Non-Engineering 16:9 Detail Audit |
||||
|
||||
**Scope** |
||||
- Branch: `V2.2` |
||||
- Runtime: `http://127.0.0.1:5173/#/platform` |
||||
- Exact viewport: `1920 × 1080` (16:9) |
||||
- Excluded by request: ecological protection `engineering-analysis`; it was neither opened nor modified during this pass. |
||||
- Product boundary: visual completion and fit only. Business data, stage meaning, chart semantics, and interactions were not redesigned. |
||||
|
||||
**Screen-State Matrix** |
||||
1. Home |
||||
2. Forest/grass/wet resource overview |
||||
3. Grassland resources |
||||
4. Wetland resources |
||||
5. Woodland resources |
||||
6. Ecological redline |
||||
7. Natural protected area |
||||
8. National park |
||||
9. Ecological restoration |
||||
10. Yak herd structure |
||||
11. Yak forecast |
||||
12. Yak epidemic prevention |
||||
13. Yak trade |
||||
14. Pasture management |
||||
15. Industry chain — family ecological pasture |
||||
16. Industry chain — artificial grassland |
||||
17. Industry chain — scaled breeding base |
||||
18. Industry chain — breeding/expansion base |
||||
19. Industry chain — disaster prevention and mitigation |
||||
20. Industry chain — milk source station |
||||
21. Industry chain — slaughter and processing |
||||
22. Industry chain — forage trade |
||||
23. Industry chain — social services |
||||
24. Smart management |
||||
25. Grass-livestock balance |
||||
|
||||
**Findings And Corrections** |
||||
- Woodland `林龄组结构`: six short age-group labels were rendered as vertical stacked characters. The panel now opts into the existing horizontal label mode; labels remain inside the card and are readable at a glance. |
||||
- Ecological restoration `重点项目库`: long project names forced irregular multiline rows and obscured the lower table. Rows now keep a fixed rhythm, use single-line ellipsis, and retain the existing internal scroll for the full dataset. |
||||
- Industry-chain bottom cards: the spotlight component defined two rows while rendering up to three metrics, so the third metric overflowed. The industry-only card style now provides three compact rows without changing metric content. |
||||
- Artificial grassland `项目面积明细`: the six specification rows now use a denser industry-only row rhythm, allowing all six to remain visible in the 227px card. |
||||
- Artificial grassland `作业方式面积` and family pasture rank density were tightened only within their existing cards; no data or ordering changed. |
||||
- Industry-chain left/right cards remain flat and use the previously approved unified card shell. No tilt was reintroduced. |
||||
|
||||
**Design QA Comparison** |
||||
- Woodland before/after: `tmp/v22-detail-audit-20260718/05-forest-woodland.png` and `tmp/v22-detail-qa-20260718/woodland-after.png` |
||||
- Ecological restoration before/after: `tmp/v22-detail-audit-20260718/09-eco-restoration.png` and `tmp/v22-detail-qa-20260718/restoration-after.png` |
||||
- Industry family, artificial grassland, and scaled breeding before/after: `tmp/v22-detail-audit-20260718/15-industry-family.png` through `17-industry-scale.png`, compared with the matching `tmp/v22-detail-qa-20260718/*-after*.png` captures. |
||||
- Remaining industry stages were re-captured after the shared industry-only correction and inspected individually. |
||||
- Audit contact sheets: `tmp/v22-detail-qa-20260718/contact-sheets/01-home-forest.jpg` through `05-industry.jpg`. |
||||
|
||||
**Verification** |
||||
- All 25 in-scope states were inspected from current-run screenshots at 1920 × 1080. |
||||
- Same-state before/after images were reviewed together for every implemented correction. |
||||
- Production build: passed (`vite build`, 921 modules transformed). |
||||
- Existing nonblocking build notices: Vite Cesium script/CSS resolution notice and Dart Sass legacy API deprecation notice. |
||||
- Generated `docs/` build output was cleaned after validation; no release artifact was retained. |
||||
- Typography: existing project font stack and value hierarchy are preserved. |
||||
- Spacing: the accepted two-tier row layout and card padding are reused; every row remains inside the panel. |
||||
- Colors: the same `#43d9e8` wetland cyan palette, subtle row backgrounds, and percentage pills are reused. |
||||
- Image and asset fidelity: no new raster or icon assets were introduced; existing map and panel assets are unchanged. |
||||
- Copy and content: natural-protected-area data and ordering are unchanged. |
||||
|
||||
final result: passed |
||||
## Comparison history |
||||
|
||||
## 2026-08-02 Screen 2.0 Requested Interaction And Visual Updates |
||||
|
||||
**Scope** |
||||
- Login redesign from the supplied 830 × 712 reference screenshot. |
||||
- Township map-label alignment, industry-overview default point layers, ecological engineering-analysis reveal, and pasture boundary weight. |
||||
- Runtime: `http://192.168.31.202:4173/` |
||||
|
||||
**Login Visual Comparison** |
||||
- Source: `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-6fff2f37-5438-40b0-aaa8-517b58318a6f.png` |
||||
- Implementation: `tmp/login-redesign-830x712.png` |
||||
- Combined comparison: `tmp/login-design-qa-comparison.png` |
||||
- Viewport/state: 830 × 712 CSS px, DPR 1, empty login form with password initially hidden. |
||||
- Removed the version label, login explanatory sentence, and account-allocation note. Conditional Caps Lock and validation messages remain because they are functional feedback rather than remarks. |
||||
- No P0, P1, or P2 visual issues were found. The two-zone glass layout is an intentional redesign requested by the user, while retaining the existing cyan dark-screen design language and source background asset. |
||||
|
||||
**Authenticated Runtime Verification** |
||||
- Default overview layers: all nine point categories rendered active on first entry; the artificial-grass polygon overlay remains a separate optional layer. |
||||
- Engineering analysis: the loading overlay appeared immediately, the map grew from 0 to 5,250 candidate features by page 7, and completed at 9,046 features after the minimum staged duration. Controls were disabled during analysis and restored afterward. |
||||
- Pasture boundary: the WMS boundary layer was enabled and visually inspected after reducing stroke width to 0.55 with lighter opacity. |
||||
- Map labels: town labels render centered on the current home map. Ranking mode now binds the town name and number inside one label object so they cannot drift independently. |
||||
- Login flow: password visibility control worked, the supplied test account authenticated successfully, and routing continued to `#/platform`. |
||||
- Browser console: no blocking application errors were observed during the checked flows. |
||||
|
||||
**Build Verification** |
||||
- Production build: passed, 923 modules transformed. |
||||
- Existing nonblocking notices: Vite Terser option notice, Cesium script/CSS resolution notice, and Dart Sass legacy API deprecation notice. |
||||
- Before: the natural-protected-area wetland card used the legacy list presentation, visually inconsistent with the optimized ecological-redline card. |
||||
- After: the chart reuses the accepted rank-bar grammar through the shared wetland panel decorator and scoped card styles. |
||||
- No actionable P0, P1, or P2 issue remains in the requested scope. |
||||
|
||||
final result: passed |
||||
## Primary interactions and console |
||||
|
||||
## 2026-08-03 Map Label Re-centering And Seven-Stage Engineering Analysis |
||||
|
||||
**Scope** |
||||
- Corrected the visible township-name and metric labels in both Yak Management map implementations: the 3D trade map and the OpenLayers structure/forecast map. |
||||
- Expanded ecological engineering analysis into seven visible analysis phases with progressive map rendering. |
||||
- Confirmed the reusable local test-login entry without recording a plaintext password in the repository or QA artifacts. |
||||
|
||||
**Map Label Visual QA** |
||||
- Reference: `/var/folders/dh/pf6z830j3w3drsd1k4ncl7br0000gn/T/codex-clipboard-8178eec6-6fc1-4cb3-bff5-8f2cc7fe3927.png` |
||||
- Correct matching state: Yak Management → Yak Trade. |
||||
- Combined comparison: `tmp/design-qa/yak-trade-map-labels-reference-vs-current.png`. |
||||
- The 3D label shell no longer retains the previous `50%` horizontal translation during its reveal animation or later data refreshes. |
||||
- Township statistic labels no longer apply a second vertical-centering transform on top of the CSS3D anchor. |
||||
- The structure/forecast OpenLayers map now renders township name and stock value as one centered rich-text label sharing the same point anchor. |
||||
- No cropped labels, detached values, or independently drifting name/value pairs were found in the final runtime capture. |
||||
|
||||
**Engineering Analysis Runtime QA** |
||||
- Seven visible phases render in order: environment initialization, condition validation, base-candidate calculation, historical-project exclusion, spatial overlay, suitable-patch generation, and result validation. |
||||
- The panel and central overlay both display the current phase, description, determinate progress, and `x/7` step count. |
||||
- Progressive feature batches were observed during phase 6; final output remained 9,046 suitable features from 9,061 base features with 15 exclusions. |
||||
- User-visible completion time was approximately 35 seconds in the checked run, exceeding the configured 18-second minimum and eliminating the previous near-instant transition. |
||||
|
||||
**Test Login Persistence** |
||||
- The reusable credential is stored in macOS Keychain under the Screen 2.0 test-login service. |
||||
- Product-design long-term context stores only the Keychain lookup pointer. No plaintext password is present in source, logs, screenshots, or this QA report. |
||||
|
||||
**Verification** |
||||
- Production build passed with Vite; 923 modules transformed. |
||||
- The authenticated Yak Trade and Yak Structure states were inspected in the current in-app Browser session. |
||||
- Browser console contained no application-level error entries. Existing Cesium image-tile availability messages are nonblocking external imagery notices. |
||||
- Natural-protected-area view route loaded successfully and remained selected. |
||||
- Top statistics and all 7 wetland rows rendered. |
||||
- Browser console checked after the final deployment: zero new errors. |
||||
- Production build passed and `hy-v3-screen` reported healthy. |
||||
|
||||
final result: passed |
||||
|
||||
@ -0,0 +1,5 @@ |
||||
#!/bin/sh |
||||
set -eu |
||||
|
||||
# 保留 V3 内网和发布网的直连路由,删除通往其他 Docker 网段的默认路由。 |
||||
/sbin/ip route del default |
||||
@ -0,0 +1 @@ |
||||
.forbidden-page[data-v-59c03ff7]{height:100%;display:grid;place-items:center;background:#f5f7fa} |
||||
@ -0,0 +1 @@ |
||||
import{_}from"./_plugin-vue_export-helper-c27b6911-1786725044461.js";import{O as t,o as d,c,b as o,x as n,B as i}from"./index-1786725044461.js";const l={},p={class:"forbidden-page"};function f(s,e){const r=t("a-button"),a=t("a-result");return d(),c("div",p,[o(a,{status:"403",title:"无后台管理权限","sub-title":"当前账号可以访问业务大屏,但未被授予后台管理员角色。"},{extra:n(()=>[o(r,{type:"primary",onClick:e[0]||(e[0]=m=>s.$router.replace("/platform"))},{default:n(()=>[...e[1]||(e[1]=[i("返回业务大屏",-1)])]),_:1})]),_:1})])}const x=_(l,[["render",f],["__scopeId","data-v-59c03ff7"]]);export{x as default}; |
||||
@ -0,0 +1 @@ |
||||
.admin-shell[data-v-b321818c]{width:100%;height:100%;min-width:0;background:#f3f5f8;color:#1f2937;font-family:AlibabaPuHuiTi,PingFang SC,Microsoft YaHei,sans-serif}.admin-sider[data-v-b321818c]{position:relative;z-index:2;overflow:hidden;background:#001529!important;box-shadow:2px 0 12px #0015291f}.admin-brand[data-v-b321818c]{height:64px;display:flex;align-items:center;gap:11px;padding:0 18px;border-bottom:1px solid rgba(255,255,255,.08);color:#fff;white-space:nowrap}.admin-brand-mark[data-v-b321818c]{flex:0 0 auto;width:34px;height:34px;display:grid;place-items:center;border-radius:9px;background:linear-gradient(145deg,#1677ff,#4096ff);font-size:18px;font-weight:700;box-shadow:0 6px 18px #1677ff57}.admin-brand-copy[data-v-b321818c]{display:flex;flex-direction:column;line-height:1.2}.admin-brand-copy strong[data-v-b321818c]{font-size:15px;letter-spacing:.5px}.admin-brand-copy span[data-v-b321818c]{margin-top:4px;color:#ffffff8a;font-size:11px}.admin-menu[data-v-b321818c]{margin-top:12px;border-inline-end:0!important}.admin-main-layout[data-v-b321818c]{min-width:0;background:#f3f5f8}.admin-header[data-v-b321818c]{height:64px;padding:0 22px 0 12px;display:flex;align-items:center;justify-content:space-between;background:#fff;border-bottom:1px solid #edf0f4;box-shadow:0 1px 4px #0f172a0a}.admin-header-left[data-v-b321818c],.admin-header-actions[data-v-b321818c],.admin-user[data-v-b321818c]{display:flex;align-items:center}.admin-header-left[data-v-b321818c]{gap:14px}.admin-header-actions[data-v-b321818c]{gap:6px}.admin-collapse[data-v-b321818c]{width:40px;height:40px;border:0;border-radius:8px;background:transparent;color:#4b5563;font-size:18px;cursor:pointer}.admin-collapse[data-v-b321818c]:hover{background:#f2f5f9;color:#1677ff}.admin-user[data-v-b321818c]{gap:9px;padding:5px 7px;border:0;border-radius:8px;background:transparent;color:#27364a;cursor:pointer}.admin-user[data-v-b321818c]:hover{background:#f4f7fb}.admin-avatar[data-v-b321818c]{background:#1677ff;font-weight:600}.admin-user-copy[data-v-b321818c]{display:flex;flex-direction:column;align-items:flex-start;line-height:1.2}.admin-user-copy strong[data-v-b321818c]{font-size:13px;font-weight:600}.admin-user-copy small[data-v-b321818c]{margin-top:3px;color:#8c97a8;font-size:11px}.admin-user-arrow[data-v-b321818c]{color:#9aa4b2;font-size:10px}.admin-content[data-v-b321818c]{min-height:0;overflow:auto;padding:20px}@media (max-width: 900px){.admin-header[data-v-b321818c]{padding-right:12px}.admin-header-actions[data-v-b321818c]>.ant-btn{display:none}.admin-user-copy[data-v-b321818c],.admin-user-arrow[data-v-b321818c]{display:none}.admin-content[data-v-b321818c]{padding:14px}} |
||||
@ -0,0 +1 @@ |
||||
import{g as o,o as s,C as z,x as I,a as i,n as g,c as r,F as k,y as m,f as L,t as w,K as C,j as h}from"./index-1786725044461.js";import{_ as R}from"./index-262a2c3c-1786725044461.js";import{d as j}from"./index-151544a4-1786725044461.js";const D={key:0,class:"layer-panel-list"},E=["onClick"],$=["onClick"],G={key:0,class:"layer-panel-empty"},J={key:1,class:"layer-panel-legend"},Q=["disabled","title","onClick"],U={class:"legend-name"},W={key:0,class:"legend-check"},X={key:1,class:"layer-panel-empty is-legend"},le={__name:"LayerPanel",props:{topicKey:{type:String,required:!0},modelValue:{type:[String,Array],default:""},legends:{type:Array,default:()=>[]},selectedLegendKey:{type:String,default:""},height:{type:Number,default:0},width:{type:Number,default:248},layers:{type:Array,default:null},overlayLayers:{type:Array,default:()=>[]},overlayKeys:{type:Array,default:()=>[]},legendOnly:{type:Boolean,default:!1},multiple:{type:Boolean,default:!1},compact:{type:Boolean,default:!1},showLegend:{type:Boolean,default:!0}},emits:["update:modelValue","update:selectedLegendKey","update:overlayKeys"],setup(d,{emit:V}){const t=d,p=V,f=o(()=>Array.isArray(t.layers)?t.layers:j(t.topicKey)),v=o(()=>Array.isArray(t.overlayLayers)?t.overlayLayers:[]),c=o(()=>Array.isArray(t.legends)?t.legends:[]),b=o(()=>Array.isArray(t.modelValue)?t.modelValue.map(String).filter(Boolean):t.modelValue?[String(t.modelValue)]:[]),A=o(()=>Array.isArray(t.overlayKeys)?t.overlayKeys.map(String).filter(Boolean):[]),x=o(()=>c.value.filter(K).length>1),M=o(()=>c.value.length===1),O=o(()=>t.legendOnly?"图例":t.compact?"图层":"图层控制"),T=o(()=>{const l=t.legendOnly?0:f.value.length+v.value.length,e=t.showLegend?Math.ceil(c.value.length/2):0,a=l?l*34+Math.max(0,l-1)*5:30,u=t.showLegend?c.value.length?30+Math.max(28,e*28):28:0,q=t.showLegend?172:108;return Math.max(q,Math.min(430,72+a+u))}),N=o(()=>t.compact?t.height||T.value:t.height?t.height:430);function F(n,l){var e,a;if((a=(e=n.currentTarget)==null?void 0:e.blur)==null||a.call(e),t.multiple){const u=new Set(b.value);u.has(l)?u.delete(l):u.add(l),p("update:modelValue",Array.from(u));return}p("update:modelValue",t.modelValue===l?"":l)}function S(n){return b.value.includes(String(n))}function H(n,l){var a,u;(u=(a=n.currentTarget)==null?void 0:a.blur)==null||u.call(a);const e=new Set(A.value);e.has(l)?e.delete(l):e.add(l),p("update:overlayKeys",Array.from(e))}function _(n){return A.value.includes(String(n))}function B(n={}){const l=n.color||n.fillColor||n.strokeColor||"";return l?{"--layer-item-color":l}:null}function P(n,l){var e,a;(a=(e=n.currentTarget)==null?void 0:e.blur)==null||a.call(e),y(l)&&p("update:selectedLegendKey",t.selectedLegendKey===l.key?"":l.key)}function K(n){return(n==null?void 0:n.selectable)===!1?!1:!!(n!=null&&n.key&&(n.cqlFilter||n.rankingValueKey))}function y(n){return x.value&&K(n)}return(n,l)=>(s(),z(R,{title:O.value,width:d.width,height:N.value},{default:I(()=>[i("div",{class:g(["layer-panel",{"is-legend-only":d.legendOnly,"is-compact":d.compact,"is-without-legend":!d.showLegend}])},[d.legendOnly?h("",!0):(s(),r("div",D,[(s(!0),r(k,null,m(f.value,e=>(s(),r("button",{key:e.key,class:g(["layer-panel-item",{"is-active":S(e.key),"is-checked":S(e.key)}]),type:"button",onMousedown:l[0]||(l[0]=L(()=>{},["prevent"])),onClick:a=>F(a,e.key)},[i("span",null,w(e.name),1),i("i",{style:C(B(e))},null,4)],42,E))),128)),(s(!0),r(k,null,m(v.value,e=>(s(),r("button",{key:e.key,class:g(["layer-panel-item is-overlay",{"is-active":_(e.key),"is-checked":_(e.key)}]),type:"button",onMousedown:l[1]||(l[1]=L(()=>{},["prevent"])),onClick:a=>H(a,e.key)},[i("span",null,w(e.name),1),i("i",{style:C(B(e))},null,4)],42,$))),128)),!f.value.length&&!v.value.length?(s(),r("div",G,"暂无图层配置")):h("",!0)])),d.showLegend?(s(),r("div",J,[l[3]||(l[3]=i("div",{class:"layer-panel-section-title"},"图例",-1)),c.value.length?(s(),r("div",{key:0,class:g(["layer-panel-legend-grid",{"is-single":M.value}])},[(s(!0),r(k,null,m(c.value,e=>(s(),r("button",{key:e.key||e.name,class:g(["layer-panel-legend-row",{"is-selected":y(e)&&e.key===d.selectedLegendKey,"is-checkable":y(e),"is-disabled":!y(e)}]),type:"button",disabled:!y(e),title:e.name,onMousedown:l[2]||(l[2]=L(()=>{},["prevent"])),onClick:a=>P(a,e)},[i("span",{class:"legend-swatch",style:C({backgroundColor:e.fillColor,borderColor:e.strokeColor||e.fillColor})},null,4),i("span",U,w(e.name),1),y(e)?(s(),r("i",W)):h("",!0)],42,Q))),128))],2)):(s(),r("div",X,"暂无图例"))])):h("",!0)],2)]),_:1},8,["title","width","height"]))}};export{le as _}; |
||||
@ -1 +0,0 @@ |
||||
import{g as o,o as s,C as z,x as I,a as i,n as g,c as r,F as k,y as m,f as L,t as b,K as w,j as h}from"./index-1785858872961.js";import{_ as R}from"./index-8ffdff7e-1785858872961.js";import{b as j}from"./townshipBoundaries-8867fad4-1785858872961.js";const D={key:0,class:"layer-panel-list"},E=["onClick"],$=["onClick"],G={key:0,class:"layer-panel-empty"},J={key:1,class:"layer-panel-legend"},Q=["disabled","title","onClick"],U={class:"legend-name"},W={key:0,class:"legend-check"},X={key:1,class:"layer-panel-empty is-legend"},le={__name:"LayerPanel",props:{topicKey:{type:String,required:!0},modelValue:{type:[String,Array],default:""},legends:{type:Array,default:()=>[]},selectedLegendKey:{type:String,default:""},height:{type:Number,default:0},width:{type:Number,default:248},layers:{type:Array,default:null},overlayLayers:{type:Array,default:()=>[]},overlayKeys:{type:Array,default:()=>[]},legendOnly:{type:Boolean,default:!1},multiple:{type:Boolean,default:!1},compact:{type:Boolean,default:!1},showLegend:{type:Boolean,default:!0}},emits:["update:modelValue","update:selectedLegendKey","update:overlayKeys"],setup(d,{emit:V}){const t=d,p=V,f=o(()=>Array.isArray(t.layers)?t.layers:j(t.topicKey)),v=o(()=>Array.isArray(t.overlayLayers)?t.overlayLayers:[]),c=o(()=>Array.isArray(t.legends)?t.legends:[]),C=o(()=>Array.isArray(t.modelValue)?t.modelValue.map(String).filter(Boolean):t.modelValue?[String(t.modelValue)]:[]),A=o(()=>Array.isArray(t.overlayKeys)?t.overlayKeys.map(String).filter(Boolean):[]),x=o(()=>c.value.filter(K).length>1),M=o(()=>c.value.length===1),O=o(()=>t.legendOnly?"图例":t.compact?"图层":"图层控制"),T=o(()=>{const l=t.legendOnly?0:f.value.length+v.value.length,e=t.showLegend?Math.ceil(c.value.length/2):0,a=l?l*34+Math.max(0,l-1)*5:30,u=t.showLegend?c.value.length?30+Math.max(28,e*28):28:0,q=t.showLegend?172:108;return Math.max(q,Math.min(430,72+a+u))}),N=o(()=>t.compact?t.height||T.value:t.height?t.height:430);function F(n,l){var e,a;if((a=(e=n.currentTarget)==null?void 0:e.blur)==null||a.call(e),t.multiple){const u=new Set(C.value);u.has(l)?u.delete(l):u.add(l),p("update:modelValue",Array.from(u));return}p("update:modelValue",t.modelValue===l?"":l)}function S(n){return C.value.includes(String(n))}function H(n,l){var a,u;(u=(a=n.currentTarget)==null?void 0:a.blur)==null||u.call(a);const e=new Set(A.value);e.has(l)?e.delete(l):e.add(l),p("update:overlayKeys",Array.from(e))}function _(n){return A.value.includes(String(n))}function B(n={}){const l=n.color||n.fillColor||n.strokeColor||"";return l?{"--layer-item-color":l}:null}function P(n,l){var e,a;(a=(e=n.currentTarget)==null?void 0:e.blur)==null||a.call(e),y(l)&&p("update:selectedLegendKey",t.selectedLegendKey===l.key?"":l.key)}function K(n){return(n==null?void 0:n.selectable)===!1?!1:!!(n!=null&&n.key&&(n.cqlFilter||n.rankingValueKey))}function y(n){return x.value&&K(n)}return(n,l)=>(s(),z(R,{title:O.value,width:d.width,height:N.value},{default:I(()=>[i("div",{class:g(["layer-panel",{"is-legend-only":d.legendOnly,"is-compact":d.compact,"is-without-legend":!d.showLegend}])},[d.legendOnly?h("",!0):(s(),r("div",D,[(s(!0),r(k,null,m(f.value,e=>(s(),r("button",{key:e.key,class:g(["layer-panel-item",{"is-active":S(e.key),"is-checked":S(e.key)}]),type:"button",onMousedown:l[0]||(l[0]=L(()=>{},["prevent"])),onClick:a=>F(a,e.key)},[i("span",null,b(e.name),1),i("i",{style:w(B(e))},null,4)],42,E))),128)),(s(!0),r(k,null,m(v.value,e=>(s(),r("button",{key:e.key,class:g(["layer-panel-item is-overlay",{"is-active":_(e.key),"is-checked":_(e.key)}]),type:"button",onMousedown:l[1]||(l[1]=L(()=>{},["prevent"])),onClick:a=>H(a,e.key)},[i("span",null,b(e.name),1),i("i",{style:w(B(e))},null,4)],42,$))),128)),!f.value.length&&!v.value.length?(s(),r("div",G,"暂无图层配置")):h("",!0)])),d.showLegend?(s(),r("div",J,[l[3]||(l[3]=i("div",{class:"layer-panel-section-title"},"图例",-1)),c.value.length?(s(),r("div",{key:0,class:g(["layer-panel-legend-grid",{"is-single":M.value}])},[(s(!0),r(k,null,m(c.value,e=>(s(),r("button",{key:e.key||e.name,class:g(["layer-panel-legend-row",{"is-selected":y(e)&&e.key===d.selectedLegendKey,"is-checkable":y(e),"is-disabled":!y(e)}]),type:"button",disabled:!y(e),title:e.name,onMousedown:l[2]||(l[2]=L(()=>{},["prevent"])),onClick:a=>P(a,e)},[i("span",{class:"legend-swatch",style:w({backgroundColor:e.fillColor,borderColor:e.strokeColor||e.fillColor})},null,4),i("span",U,b(e.name),1),y(e)?(s(),r("i",W)):h("",!0)],42,Q))),128))],2)):(s(),r("div",X,"暂无图例"))])):h("",!0)],2)]),_:1},8,["title","width","height"]))}};export{le as _}; |
||||
@ -0,0 +1 @@ |
||||
.log-message[data-v-bf0e68fe]{display:inline-block;max-width:210px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle} |
||||
@ -0,0 +1 @@ |
||||
var W=Object.defineProperty,$=Object.defineProperties;var A=Object.getOwnPropertyDescriptors;var z=Object.getOwnPropertySymbols;var F=Object.prototype.hasOwnProperty,G=Object.prototype.propertyIsEnumerable;var B=(s,l,e)=>l in s?W(s,l,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[l]=e,V=(s,l)=>{for(var e in l||(l={}))F.call(l,e)&&B(s,e,l[e]);if(z)for(var e of z(l))G.call(l,e)&&B(s,e,l[e]);return s},q=(s,l)=>$(s,A(l));var O=(s,l,e)=>new Promise((c,f)=>{var m=i=>{try{r(e.next(i))}catch(v){f(v)}},u=i=>{try{r(e.throw(i))}catch(v){f(v)}},r=i=>i.done?c(i.value):Promise.resolve(i.value).then(m,u);r((e=e.apply(s,l)).next())});import{O as n,o as w,c as H,a as g,b as t,x as o,a1 as K,S as X,B as k,u as N,V as Z,W as U,t as h,C,j as ee,L as Y,d as I}from"./index-1786725044461.js";/* empty css */import{_ as ae}from"./_plugin-vue_export-helper-c27b6911-1786725044461.js";const te={class:"admin-page"},oe={class:"admin-table-toolbar"},le={style:{color:"#8c97a8"}},ne={class:"log-message"},se={__name:"LoginLogs",setup(s){const l=[{title:"日志编号",dataIndex:"infoId",key:"infoId",width:105},{title:"用户账号",dataIndex:"userName",key:"userName",width:140},{title:"登录地址",dataIndex:"ipaddr",key:"ipaddr",width:145},{title:"登录地点",dataIndex:"loginLocation",key:"loginLocation",width:150,ellipsis:!0},{title:"浏览器",key:"browser",width:110},{title:"操作系统",dataIndex:"os",key:"os",width:120},{title:"登录状态",key:"status",width:100},{title:"提示消息",key:"msg",width:220,ellipsis:!0},{title:"登录时间",dataIndex:"loginTime",key:"loginTime",width:175}],e=Y({userName:"",ipaddr:"",status:void 0}),c=I([]),f=I([]),m=I(!1),u=Y({current:1,pageSize:20,total:0,showSizeChanger:!0,showQuickJumper:!0,showTotal:_=>`共 ${_} 条`});function r(){return O(this,null,function*(){var _,a;m.value=!0;try{const p=yield K(q(V({},e),{beginTime:(_=c.value)==null?void 0:_[0],endTime:(a=c.value)==null?void 0:a[1],pageNum:u.current,pageSize:u.pageSize}));f.value=p.rows||[],u.total=Number(p.total||0)}catch(p){X.error(p.message)}finally{m.value=!1}})}function i(){u.current=1,r()}function v(){Object.assign(e,{userName:"",ipaddr:"",status:void 0}),c.value=[],i()}function D(_){u.current=_.current,u.pageSize=_.pageSize,r()}return r(),(_,a)=>{const p=n("a-input"),y=n("a-form-item"),L=n("a-select-option"),E=n("a-select"),P=n("a-range-picker"),x=n("a-button"),S=n("a-space"),R=n("a-form"),T=n("a-card"),j=n("a-badge"),M=n("a-tag"),Q=n("a-tooltip"),J=n("a-table");return w(),H("div",te,[a[9]||(a[9]=g("div",{class:"admin-page-heading"},[g("h1",null,"登录日志")],-1)),t(T,{class:"admin-query-card",bordered:!1},{default:o(()=>[t(R,{class:"admin-query-form",model:e},{default:o(()=>[t(y,{label:"用户账号"},{default:o(()=>[t(p,{value:e.userName,"onUpdate:value":a[0]||(a[0]=d=>e.userName=d),"allow-clear":"",placeholder:"请输入用户账号",onPressEnter:i},null,8,["value"])]),_:1}),t(y,{label:"登录地址"},{default:o(()=>[t(p,{value:e.ipaddr,"onUpdate:value":a[1]||(a[1]=d=>e.ipaddr=d),"allow-clear":"",placeholder:"请输入 IP 地址",onPressEnter:i},null,8,["value"])]),_:1}),t(y,{label:"登录状态"},{default:o(()=>[t(E,{value:e.status,"onUpdate:value":a[2]||(a[2]=d=>e.status=d),"allow-clear":"",placeholder:"全部状态"},{default:o(()=>[t(L,{value:"0"},{default:o(()=>[...a[4]||(a[4]=[k("成功",-1)])]),_:1}),t(L,{value:"1"},{default:o(()=>[...a[5]||(a[5]=[k("失败",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(y,{label:"登录时间"},{default:o(()=>[t(P,{value:c.value,"onUpdate:value":a[3]||(a[3]=d=>c.value=d),"value-format":"YYYY-MM-DD"},null,8,["value"])]),_:1}),t(y,{class:"admin-query-actions"},{default:o(()=>[t(S,null,{default:o(()=>[t(x,{type:"primary",onClick:i},{default:o(()=>[t(N(Z)),a[6]||(a[6]=k(" 查询",-1))]),_:1}),t(x,{onClick:v},{default:o(()=>[t(N(U)),a[7]||(a[7]=k(" 重置",-1))]),_:1})]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),t(T,{class:"admin-table-card",bordered:!1},{default:o(()=>[g("div",oe,[a[8]||(a[8]=g("strong",null,"登录日志列表",-1)),t(S,null,{default:o(()=>[g("span",le,"共 "+h(u.total)+" 条",1),t(x,{type:"text",loading:m.value,onClick:r},{default:o(()=>[t(N(U))]),_:1},8,["loading"])]),_:1})]),t(J,{"row-key":"infoId",columns:l,"data-source":f.value,loading:m.value,pagination:u,scroll:{x:1180},onChange:D},{bodyCell:o(({column:d,record:b})=>[d.key==="status"?(w(),C(j,{key:0,status:b.status==="0"?"success":"error",text:b.status==="0"?"成功":"失败"},null,8,["status","text"])):d.key==="browser"?(w(),C(M,{key:1},{default:o(()=>[k(h(b.browser||"未知"),1)]),_:2},1024)):d.key==="msg"?(w(),C(Q,{key:2,title:b.msg},{default:o(()=>[g("span",ne,h(b.msg||"—"),1)]),_:2},1032,["title"])):ee("",!0)]),_:1},8,["data-source","loading","pagination"])]),_:1})])}}},_e=ae(se,[["__scopeId","data-v-bf0e68fe"]]);export{_e as default}; |
||||
@ -0,0 +1 @@ |
||||
.error-block[data-v-823675cb]{color:#cf1322;background:#fff2f0} |
||||
@ -1,2 +1,2 @@ |
||||
var D=Object.defineProperty,R=Object.defineProperties;var W=Object.getOwnPropertyDescriptors;var z=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var L=(a,r,o)=>r in a?D(a,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):a[r]=o,m=(a,r)=>{for(var o in r||(r={}))H.call(r,o)&&L(a,o,r[o]);if(z)for(var o of z(r))P.call(r,o)&&L(a,o,r[o]);return a},d=(a,r)=>R(a,W(r));import{g as p,q as Z,A as F,M as b,o as g,c as h,a as y,t as x,j as _,b as V,u as q,n as E}from"./index-1785858872961.js";import{H as j}from"./index.esm.min-b7db2517-1785858872961.js";const G={class:"smart-chart-header"},M={key:0},I={key:0},A="口径",Q={__name:"SmartChartRenderer",props:{chart:{type:Object,required:!0}},emits:["ready"],setup(a,{emit:r}){const o=r,i=a,l=["#30dcff","#27f0c0","#ffd76c","#7aa7ff","#ff8f6b","#a6f06d"],k=p(()=>{const t=(i.chart.rows||[]).filter(e=>Number.isFinite(Number(e.value)));return i.chart.type==="pie"?T(t):i.chart.type==="line"?$(t):C(t)}),w=p(()=>{const t=i.chart.rows||[];return i.chart.type==="bar"&&v(t)}),S=p(()=>B(i.chart.subtitle));Z(()=>{F(()=>{window.requestAnimationFrame(()=>o("ready"))})});function C(t){return v(t)?N(t):{animationDuration:700,grid:{left:52,right:26,top:28,bottom:54},tooltip:c(),xAxis:{type:"category",data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.28)"}},axisLabel:{color:"rgba(223, 250, 255, 0.76)",fontSize:11,interval:0,rotate:t.length>6?28:0}},yAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},series:[{name:i.chart.title,type:"bar",barWidth:t.length>7?16:22,data:t.map((e,n)=>({value:e.value,name:e.name,itemStyle:{borderRadius:[8,8,0,0],color:new b(0,0,0,1,[{offset:0,color:l[n%l.length]},{offset:1,color:"rgba(48, 220, 255, 0.08)"}])}})),label:{show:!0,position:"top",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)}}]}}function N(t){return{animationDuration:700,grid:{left:78,right:72,top:22,bottom:20},tooltip:d(m({},c()),{trigger:"axis",axisPointer:{type:"shadow"}}),xAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},yAxis:{type:"category",inverse:!0,data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.22)"}},axisLabel:{color:"rgba(223, 250, 255, 0.82)",fontSize:12}},series:[{name:i.chart.title,type:"bar",barWidth:13,data:t.map((e,n)=>({value:e.value,name:e.name,itemStyle:{borderRadius:[0,8,8,0],color:new b(0,0,1,0,[{offset:0,color:"rgba(48, 220, 255, 0.16)"},{offset:1,color:l[n%l.length]}])}})),label:{show:!0,position:"right",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)}}]}}function T(t){return{animationDuration:700,tooltip:c(),legend:{orient:"vertical",right:10,top:"middle",itemWidth:10,itemHeight:10,textStyle:{color:"rgba(223, 250, 255, 0.78)",fontSize:11}},series:[{name:i.chart.title,type:"pie",radius:["48%","68%"],center:["35%","52%"],avoidLabelOverlap:!0,label:{color:"#fff",fontSize:11,formatter:`{b}
|
||||
{d}%`},labelLine:{lineStyle:{color:"rgba(223, 250, 255, 0.42)"}},itemStyle:{borderColor:"rgba(3, 18, 31, 0.92)",borderWidth:3},data:t.map((e,n)=>({name:e.name,value:e.value,itemStyle:{color:l[n%l.length]}}))}]}}function $(t){return{animationDuration:760,grid:{left:52,right:28,top:30,bottom:48},tooltip:d(m({},c()),{trigger:"axis",axisPointer:{type:"line",lineStyle:{color:"rgba(255, 215, 108, 0.52)"}}}),xAxis:{type:"category",boundaryGap:!1,data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.28)"}},axisLabel:{color:"rgba(223, 250, 255, 0.76)",fontSize:11,interval:0}},yAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},series:[{name:i.chart.title,type:"line",smooth:!0,symbol:"circle",symbolSize:8,lineStyle:{width:3,color:"#30dcff"},itemStyle:{color:"#ffd76c",borderColor:"#041522",borderWidth:2},areaStyle:{color:new b(0,0,0,1,[{offset:0,color:"rgba(48, 220, 255, 0.24)"},{offset:1,color:"rgba(48, 220, 255, 0.02)"}])},label:{show:!0,position:"top",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)},data:t.map(e=>({value:e.value,name:e.name}))}]}}function c(){return{trigger:"item",backgroundColor:"rgba(2, 13, 22, 0.94)",borderColor:"rgba(48, 220, 255, 0.34)",borderWidth:1,textStyle:{color:"#fff",fontSize:12},formatter:t=>{const e=(i.chart.rows||[]).find(s=>s.name===t.name),n=(e==null?void 0:e.unit)||i.chart.unit||"",f=e!=null&&e.extra?`<br/><span style="color:rgba(223,250,255,.62)">${e.extra}</span>`:"";return`${t.marker}${t.name}: ${u(t.value)}${n}${f}`}}}function v(t=[]){return t.length>6||t.some(e=>String(e.name||"").length>4)}function B(t){const e=String(t||"").trim();if(!e||/^(数据)?来源[::]/.test(e)||e.includes("固定展示"))return"";const n=new RegExp(A,"g"),f=new RegExp(`统计${A}`,"g"),s=e.replace(f,"统计数据").replace(n,"数据").replace(/来源[::]\s*openApi\s*统计库\s*[a-zA-Z0-9_./:-]*[,,、]?\s*/gi,"").replace(/openApi\s*统计库\s*/gi,"").replace(/\b[a-zA-Z][a-zA-Z0-9]*(?:_[a-zA-Z0-9]+){2,}\b/g,"").replace(/[,,、]\s*[,,、]+/g,",").replace(/^[\s,,、::]+|[\s,,、]+$/g,"");return!s||/^来源[::]?$/.test(s)||O(s)?"":s}function O(t){return/^[a-zA-Z0-9_./:-]+$/.test(t)&&(t.includes("_")||t.length>24)}function u(t){const e=Number(t);return Number.isFinite(e)?Number.isInteger(e)?e.toLocaleString("zh-CN"):e.toLocaleString("zh-CN",{maximumFractionDigits:2}):"--"}return(t,e)=>(g(),h("div",{class:E(["smart-chart-card",{"is-horizontal":w.value}])},[y("div",G,[y("div",null,[y("strong",null,x(a.chart.title),1),S.value?(g(),h("span",M,x(S.value),1)):_("",!0)]),a.chart.unit?(g(),h("em",I,x(a.chart.unit),1)):_("",!0)]),V(q(j),{class:"smart-chart",option:k.value,autoresize:""},null,8,["option"])],2))}};export{Q as default}; |
||||
var D=Object.defineProperty,R=Object.defineProperties;var W=Object.getOwnPropertyDescriptors;var z=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var L=(a,r,o)=>r in a?D(a,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):a[r]=o,m=(a,r)=>{for(var o in r||(r={}))H.call(r,o)&&L(a,o,r[o]);if(z)for(var o of z(r))P.call(r,o)&&L(a,o,r[o]);return a},d=(a,r)=>R(a,W(r));import{g as p,q as Z,A as F,a4 as b,o as g,c as h,a as y,t as x,j as _,b as V,u as q,n as E}from"./index-1786725044461.js";import{H as j}from"./index.esm.min-90d27a39-1786725044461.js";const G={class:"smart-chart-header"},I={key:0},M={key:0},A="口径",Q={__name:"SmartChartRenderer",props:{chart:{type:Object,required:!0}},emits:["ready"],setup(a,{emit:r}){const o=r,i=a,l=["#30dcff","#27f0c0","#ffd76c","#7aa7ff","#ff8f6b","#a6f06d"],k=p(()=>{const t=(i.chart.rows||[]).filter(e=>Number.isFinite(Number(e.value)));return i.chart.type==="pie"?T(t):i.chart.type==="line"?$(t):C(t)}),w=p(()=>{const t=i.chart.rows||[];return i.chart.type==="bar"&&v(t)}),S=p(()=>B(i.chart.subtitle));Z(()=>{F(()=>{window.requestAnimationFrame(()=>o("ready"))})});function C(t){return v(t)?N(t):{animationDuration:700,grid:{left:52,right:26,top:28,bottom:54},tooltip:c(),xAxis:{type:"category",data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.28)"}},axisLabel:{color:"rgba(223, 250, 255, 0.76)",fontSize:11,interval:0,rotate:t.length>6?28:0}},yAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},series:[{name:i.chart.title,type:"bar",barWidth:t.length>7?16:22,data:t.map((e,n)=>({value:e.value,name:e.name,itemStyle:{borderRadius:[8,8,0,0],color:new b(0,0,0,1,[{offset:0,color:l[n%l.length]},{offset:1,color:"rgba(48, 220, 255, 0.08)"}])}})),label:{show:!0,position:"top",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)}}]}}function N(t){return{animationDuration:700,grid:{left:78,right:72,top:22,bottom:20},tooltip:d(m({},c()),{trigger:"axis",axisPointer:{type:"shadow"}}),xAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},yAxis:{type:"category",inverse:!0,data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.22)"}},axisLabel:{color:"rgba(223, 250, 255, 0.82)",fontSize:12}},series:[{name:i.chart.title,type:"bar",barWidth:13,data:t.map((e,n)=>({value:e.value,name:e.name,itemStyle:{borderRadius:[0,8,8,0],color:new b(0,0,1,0,[{offset:0,color:"rgba(48, 220, 255, 0.16)"},{offset:1,color:l[n%l.length]}])}})),label:{show:!0,position:"right",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)}}]}}function T(t){return{animationDuration:700,tooltip:c(),legend:{orient:"vertical",right:10,top:"middle",itemWidth:10,itemHeight:10,textStyle:{color:"rgba(223, 250, 255, 0.78)",fontSize:11}},series:[{name:i.chart.title,type:"pie",radius:["48%","68%"],center:["35%","52%"],avoidLabelOverlap:!0,label:{color:"#fff",fontSize:11,formatter:`{b}
|
||||
{d}%`},labelLine:{lineStyle:{color:"rgba(223, 250, 255, 0.42)"}},itemStyle:{borderColor:"rgba(3, 18, 31, 0.92)",borderWidth:3},data:t.map((e,n)=>({name:e.name,value:e.value,itemStyle:{color:l[n%l.length]}}))}]}}function $(t){return{animationDuration:760,grid:{left:52,right:28,top:30,bottom:48},tooltip:d(m({},c()),{trigger:"axis",axisPointer:{type:"line",lineStyle:{color:"rgba(255, 215, 108, 0.52)"}}}),xAxis:{type:"category",boundaryGap:!1,data:t.map(e=>e.name),axisTick:{show:!1},axisLine:{lineStyle:{color:"rgba(48, 220, 255, 0.28)"}},axisLabel:{color:"rgba(223, 250, 255, 0.76)",fontSize:11,interval:0}},yAxis:{type:"value",axisLine:{show:!1},axisTick:{show:!1},splitLine:{lineStyle:{color:"rgba(48, 220, 255, 0.1)",type:"dashed"}},axisLabel:{color:"rgba(223, 250, 255, 0.58)",fontSize:11}},series:[{name:i.chart.title,type:"line",smooth:!0,symbol:"circle",symbolSize:8,lineStyle:{width:3,color:"#30dcff"},itemStyle:{color:"#ffd76c",borderColor:"#041522",borderWidth:2},areaStyle:{color:new b(0,0,0,1,[{offset:0,color:"rgba(48, 220, 255, 0.24)"},{offset:1,color:"rgba(48, 220, 255, 0.02)"}])},label:{show:!0,position:"top",color:"#ffffff",fontSize:11,formatter:({value:e})=>u(e)},data:t.map(e=>({value:e.value,name:e.name}))}]}}function c(){return{trigger:"item",backgroundColor:"rgba(2, 13, 22, 0.94)",borderColor:"rgba(48, 220, 255, 0.34)",borderWidth:1,textStyle:{color:"#fff",fontSize:12},formatter:t=>{const e=(i.chart.rows||[]).find(s=>s.name===t.name),n=(e==null?void 0:e.unit)||i.chart.unit||"",f=e!=null&&e.extra?`<br/><span style="color:rgba(223,250,255,.62)">${e.extra}</span>`:"";return`${t.marker}${t.name}: ${u(t.value)}${n}${f}`}}}function v(t=[]){return t.length>6||t.some(e=>String(e.name||"").length>4)}function B(t){const e=String(t||"").trim();if(!e||/^(数据)?来源[::]/.test(e)||e.includes("固定展示"))return"";const n=new RegExp(A,"g"),f=new RegExp(`统计${A}`,"g"),s=e.replace(f,"统计数据").replace(n,"数据").replace(/来源[::]\s*openApi\s*统计库\s*[a-zA-Z0-9_./:-]*[,,、]?\s*/gi,"").replace(/openApi\s*统计库\s*/gi,"").replace(/\b[a-zA-Z][a-zA-Z0-9]*(?:_[a-zA-Z0-9]+){2,}\b/g,"").replace(/[,,、]\s*[,,、]+/g,",").replace(/^[\s,,、::]+|[\s,,、]+$/g,"");return!s||/^来源[::]?$/.test(s)||O(s)?"":s}function O(t){return/^[a-zA-Z0-9_./:-]+$/.test(t)&&(t.includes("_")||t.length>24)}function u(t){const e=Number(t);return Number.isFinite(e)?Number.isInteger(e)?e.toLocaleString("zh-CN"):e.toLocaleString("zh-CN",{maximumFractionDigits:2}):"--"}return(t,e)=>(g(),h("div",{class:E(["smart-chart-card",{"is-horizontal":w.value}])},[y("div",G,[y("div",null,[y("strong",null,x(a.chart.title),1),S.value?(g(),h("span",I,x(S.value),1)):_("",!0)]),a.chart.unit?(g(),h("em",M,x(a.chart.unit),1)):_("",!0)]),V(q(j),{class:"smart-chart",option:k.value,autoresize:""},null,8,["option"])],2))}};export{Q as default}; |
||||
@ -0,0 +1 @@ |
||||
.user-identity[data-v-c3907d06]{display:flex;align-items:center;gap:10px;min-width:0}.user-avatar[data-v-c3907d06]{flex:0 0 auto;background:#e8f1ff;color:#1677ff;font-weight:650}.user-identity div[data-v-c3907d06],.contact-cell[data-v-c3907d06]{min-width:0;display:flex;flex-direction:column}.user-identity strong[data-v-c3907d06]{overflow:hidden;color:#27364a;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.user-identity span[data-v-c3907d06],.contact-cell small[data-v-c3907d06],.muted[data-v-c3907d06]{margin-top:3px;color:#98a2b2;font-size:12px}.contact-cell span[data-v-c3907d06]{color:#445064}.form-grid[data-v-c3907d06]{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}.drawer-footer[data-v-c3907d06]{display:flex;justify-content:flex-end;gap:8px} |
||||
@ -0,0 +1 @@ |
||||
const s=(t,r)=>{const o=t.__vccOpts||t;for(const[c,e]of r)o[c]=e;return o};export{s as _}; |
||||
@ -0,0 +1 @@ |
||||
.admin-page{min-height:100%}.admin-page-heading{display:flex;align-items:center;justify-content:space-between;min-height:32px;margin-bottom:14px}.admin-page-heading h1{margin:0;color:#1f2937;font-size:22px;font-weight:650;line-height:32px}.admin-query-card,.admin-table-card{border:1px solid #edf0f4;border-radius:8px;box-shadow:0 1px 3px #0f172a06}.admin-query-card{margin-bottom:14px}.admin-query-card .ant-card-body{padding:18px 20px}.admin-query-form{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 24px}.admin-query-form .ant-form-item{min-width:0;margin:0}.admin-query-form .ant-form-item-row{flex-wrap:nowrap;align-items:center}.admin-query-form .ant-form-item-label{flex:0 0 76px;width:76px;padding:0;overflow:visible;text-align:right;white-space:nowrap}.admin-query-form .ant-form-item-label>label{height:32px;color:#374151}.admin-query-form .ant-form-item-control{min-width:0}.admin-query-form .ant-input-affix-wrapper,.admin-query-form .ant-select,.admin-query-form .ant-picker{width:100%}.admin-query-actions{grid-column:1/-1;justify-self:end}.admin-query-actions .ant-form-item-row,.admin-query-actions .ant-form-item-control-input-content{display:flex;justify-content:flex-end}.admin-table-card .ant-card-body{padding:0}.admin-table-toolbar{min-height:57px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #edf0f4}.admin-table-toolbar strong{color:#283548;font-size:14px}.admin-table-card .ant-table-thead>tr>th{background:#f8fafc;color:#445064;font-weight:600}.admin-table-card .ant-pagination{margin:16px}.admin-table-card .ant-table-cell{font-size:13px}.admin-link-danger{color:#ff4d4f}.admin-code-block{max-height:240px;overflow:auto;margin:0;padding:12px 14px;border-radius:6px;background:#f6f8fa;color:#334155;font:12px/1.65 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-all}@media (max-width: 1280px){.admin-query-form{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 760px){.admin-query-card .ant-card-body{padding:16px}.admin-query-form{grid-template-columns:minmax(0,1fr);gap:14px}.admin-query-actions,.admin-query-actions .ant-form-item-control{width:100%}} |
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@ -1 +1 @@ |
||||
var m=Object.defineProperty;var p=Object.getOwnPropertySymbols;var y=Object.prototype.hasOwnProperty,T=Object.prototype.propertyIsEnumerable;var i=(t,e,a)=>e in t?m(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a,o=(t,e)=>{for(var a in e||(e={}))y.call(e,a)&&i(t,a,e[a]);if(p)for(var a of p(e))T.call(e,a)&&i(t,a,e[a]);return t};import{p as d}from"./screen2Standard-2d8b09ac-1785858872961.js";import{R as x,b as u,d as g,p as l,h as f,r as L,a as A,g as B,e as N,c as M,o as O,s as _,f as H,i as S,j as w,k as C,l as F,m as P,n as E}from"./TopicSwitcher-12ae75fc-1785858872961.js";import{g as n,a as h,H as q,C as G}from"./index-1891ee64-1785858872961.js";const s=new Map;class b{constructor(e={}){this.options=o({includeChinaMap:!1},e),this.ready=null,this.init()}init(){const e=this.getSharedKey(),a=R(e,()=>this.createAssetList());this.instance=a.instance,this.ready=a.ready}getSharedKey(){return this.options.includeChinaMap?"hongyuan-map-with-china":"hongyuan-map"}createAssetList(){let e=[{type:"Texture",name:"flyline",path:u},{type:"Texture",name:"pathLine",path:u},{type:"Texture",name:"pathLine2",path:g},{type:"Texture",name:"pathLine3",path:l},{type:"File",name:"china",path:n(h)},{type:"File",name:"mapJson",path:n(q)},{type:"File",name:"mapStroke",path:n(h)},{type:"Texture",name:"huiguang",path:f},{type:"Texture",name:"rotationBorder1",path:L},{type:"Texture",name:"rotationBorder2",path:A},{type:"Texture",name:"guangquan1",path:B},{type:"Texture",name:"guangquan2",path:N},{type:"Texture",name:"chinaBlurLine",path:M},{type:"Texture",name:"ocean",path:O},{type:"Texture",name:"side",path:_},{type:"Texture",name:"arrow",path:H},{type:"Texture",name:"point",path:S},{type:"Texture",name:"focusArrows",path:w},{type:"Texture",name:"focusBar",path:C},{type:"Texture",name:"focusBg",path:F},{type:"Texture",name:"focusMidQuan",path:P},{type:"Texture",name:"focusMoveBg",path:E}];return this.options.includeChinaMap&&e.push({type:"File",name:"chinaMap",path:n(G)}),e}}function R(t,e){if(s.has(t))return s.get(t);const a=new x({cloneTextures:!0});a.addLoader(d,"FileLoader");const c=a.loadAll(e()),r={instance:a,ready:c};return s.set(t,r),r}export{b as A}; |
||||
var m=Object.defineProperty;var p=Object.getOwnPropertySymbols;var y=Object.prototype.hasOwnProperty,T=Object.prototype.propertyIsEnumerable;var i=(t,e,a)=>e in t?m(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a,o=(t,e)=>{for(var a in e||(e={}))y.call(e,a)&&i(t,a,e[a]);if(p)for(var a of p(e))T.call(e,a)&&i(t,a,e[a]);return t};import{p as d}from"./screen2Standard-3427eaf8-1786725044461.js";import{R as x,b as u,d as g,p as l,h as f,r as L,a as A,g as B,e as N,c as M,o as O,s as _,f as H,i as S,j as w,k as C,l as F,m as P,n as E}from"./TopicSwitcher-06eba150-1786725044461.js";import{g as n,b as h,H as q,C as G}from"./index-151544a4-1786725044461.js";const s=new Map;class Y{constructor(e={}){this.options=o({includeChinaMap:!1},e),this.ready=null,this.init()}init(){const e=this.getSharedKey(),a=R(e,()=>this.createAssetList());this.instance=a.instance,this.ready=a.ready}getSharedKey(){return this.options.includeChinaMap?"hongyuan-map-with-china":"hongyuan-map"}createAssetList(){let e=[{type:"Texture",name:"flyline",path:u},{type:"Texture",name:"pathLine",path:u},{type:"Texture",name:"pathLine2",path:g},{type:"Texture",name:"pathLine3",path:l},{type:"File",name:"china",path:n(h)},{type:"File",name:"mapJson",path:n(q)},{type:"File",name:"mapStroke",path:n(h)},{type:"Texture",name:"huiguang",path:f},{type:"Texture",name:"rotationBorder1",path:L},{type:"Texture",name:"rotationBorder2",path:A},{type:"Texture",name:"guangquan1",path:B},{type:"Texture",name:"guangquan2",path:N},{type:"Texture",name:"chinaBlurLine",path:M},{type:"Texture",name:"ocean",path:O},{type:"Texture",name:"side",path:_},{type:"Texture",name:"arrow",path:H},{type:"Texture",name:"point",path:S},{type:"Texture",name:"focusArrows",path:w},{type:"Texture",name:"focusBar",path:C},{type:"Texture",name:"focusBg",path:F},{type:"Texture",name:"focusMidQuan",path:P},{type:"Texture",name:"focusMoveBg",path:E}];return this.options.includeChinaMap&&e.push({type:"File",name:"chinaMap",path:n(G)}),e}}function R(t,e){if(s.has(t))return s.get(t);const a=new x({cloneTextures:!0});a.addLoader(d,"FileLoader");const c=a.loadAll(e()),r={instance:a,ready:c};return s.set(t,r),r}export{Y as A}; |
||||
@ -1 +0,0 @@ |
||||
var u=(r,t,e)=>new Promise((i,c)=>{var a=n=>{try{s(e.next(n))}catch(f){c(f)}},A=n=>{try{s(e.throw(n))}catch(f){c(f)}},s=n=>n.done?i(n.value):Promise.resolve(n.value).then(a,A);s((e=e.apply(r,t)).next())});import{r as g,n as w}from"./index-d6700f13-1785858872961.js";const l=b("/jsyApi"),y="/openApi";function v(r,t){return/^https?:\/\//.test(t)?t:`${r}${t.startsWith("/")?t:`/${t}`}`}function b(r){const t=String(r||"/jsyApi").replace(/\/+$/,"");return t.endsWith("/api")?t:`${t}/api`}function h(r){if((r==null?void 0:r.success)===!1||(r==null?void 0:r.code)!==void 0&&![0,200,"0","200"].includes(r.code)){const e=new Error((r==null?void 0:r.msg)||(r==null?void 0:r.message)||"接口请求失败");throw e.code=r==null?void 0:r.code,e}return w(r)}function o(r,t,e,i={}){return g(v(r,t),{params:e,timeout:i.timeout||16e3}).then(h)}function m(r){return Array.isArray(r)?r:Array.isArray(r==null?void 0:r.rows)?r.rows:Array.isArray(r==null?void 0:r.list)?r.list:Array.isArray(r==null?void 0:r.data)?r.data:[]}function _(r){return Array.isArray(r)?r.length>0:!r||typeof r!="object"?r!=null&&r!=="":["areaRange","area_range","acreage","grasslandArea","grassland_area","arearange","area","yakNumber","yak_number","yaknumber","number","yakCount","yak_count","livestockCount","livestock_count","bearingCapacity","bearing_capacity","bearingcapacity","capacity","theoryCapacity","livestockCapacity","livestock_capacity","livestockcapacity","carryingCapacity","actualCapacity","overloadRate","overload_rate","overloadrate","rate","level","conclusion","advice","balanceAdvice","balance_advice"].some(e=>r[e]!==void 0&&r[e]!==null&&r[e]!=="")}function R(){return u(this,arguments,function*({areaCode:r}={}){const t={areaCode:r},e=[()=>o(l,"/ai/livestockBalance",t,{timeout:18e3}),()=>o(y,"/ai/balance/advice",t,{timeout:18e3})];let i;for(const c of e)try{const a=yield c();if(_(a))return a}catch(a){i=a}throw i||new Error("草畜平衡接口不可用")})}function B(){return u(this,null,function*(){const r=[()=>o(l,"/ai/livestockBalanceRows",{},{timeout:18e3}),()=>o(y,"/ai/balance/areaRows",{},{timeout:18e3})];let t;for(const e of r)try{const i=m(yield e());if(i.length)return i}catch(i){t=i}if(t)throw t;return[]})}function C(r){return u(this,null,function*(){const t=[()=>o(l,"/area/children",{areaCode:r},{timeout:12e3}),()=>o(l,"/map/areaCode",{areaCode:r},{timeout:12e3})];let e,i=!1;for(const c of t)try{const a=m(yield c());if(a.length)return a;i=!0}catch(a){e=a}if(i)return[];throw e||new Error("区划接口不可用")})}export{C as a,R as b,B as g}; |
||||
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 701 B After Width: | Height: | Size: 701 B |
|
Before Width: | Height: | Size: 668 B After Width: | Height: | Size: 668 B |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 981 B |
@ -1 +0,0 @@ |
||||
var i=Math.pow;import{g as W,d as m,t as b,s as M,h as c,e as A}from"./livestockData-36ec0ae2-1785858872961.js";import{c as T}from"./data-56996d99-1785858872961.js";const e=(a,n=2)=>{const t=i(10,n);return Math.round((Number(a)||0)*t)/t},g=(a,n)=>a.reduce((t,u)=>t+(Number(u[n])||0),0),k=a=>e((Number(a)||0)/1e4,2),x=g(b,"value"),S=g(m,"yakCount"),d=A,o=e(c.grasslandArea/1e4,2),l=e(c.wetArea/1e4,2),r=177.92,P=e(o+l+r,2),N=e(d/Math.max(o,1),1),v=e(l/Math.max(P,1)*100,1),w=637.07,s=108.84,R=297.29,y=159.33,C=e(o+l,2),Y=e((R+s)*2e3/Math.max(C,1),2),I=[{key:"pasture-area",zh:"草场面积",name:"草场面积",value:C,unit:"万亩",decimals:2,icon:"area"},{key:"pasture-productivity",zh:"草场生产力",name:"草场生产力",value:Y,unit:"斤/亩",decimals:2,icon:"yield"},{key:"yak-stock",zh:"牦牛存栏",name:"牦牛存栏",value:d,unit:"头",decimals:0,icon:"stack"},{key:"today-outflow",zh:"今日出栏",name:"今日出栏",value:0,unit:"头",decimals:0,icon:"length"},{key:"county-overload-rate",zh:"超载率",name:"超载率",value:T.overloadRate,unit:"%",decimals:2,icon:"rate"}],j=[{key:"grassland",name:"草地面积",value:o,unit:"万亩",tone:"green"},{key:"wetland",name:"湿地面积",value:l,unit:"万亩",tone:"cyan"},{key:"woodland",name:"林地面积",value:r,unit:"万亩",tone:"mint"},{key:"yak-density",name:"草畜密度",value:N,unit:"头/万亩",tone:"gold"}],D=[{key:"grassland",name:"草地",value:o,unit:"万亩",color:"#24f6c4"},{key:"wetland",name:"湿地",value:l,unit:"万亩",color:"#32dcff"},{key:"woodland",name:"林地",value:r,unit:"万亩",color:"#8bf7ff"}],J=[{key:"basic-grassland",name:"基本草原",value:w,unit:"万亩",percent:e(w/Math.max(o,1)*100,1),note:"草地保护底盘"},{key:"wetland-yield",name:"湿地生产力",value:s,unit:"万吨",percent:e(s/Math.max(R+s,1)*100,1),note:"鲜草产能"},{key:"public-woodland",name:"公益林面积",value:y,unit:"万亩",percent:e(y/Math.max(r,1)*100,1),note:"林地保护占比"},{key:"wetland-rate",name:"湿地占比",value:v,unit:"%",percent:v,note:"林草湿结构"}],L=W.map(a=>{const n=m.find(z=>z.zoneName===a.zoneName)||{},t=k(a.grasslandArea),u=k(a.wetArea);return{key:a.zoneName,name:a.zoneName,grasslandArea:t,wetlandArea:u,yakCount:n.yakCount||0,resourceTotal:e(t+u,2),density:e((n.yakCount||0)/Math.max(t+u,1),1)}}).sort((a,n)=>n.yakCount-a.yakCount),O=m.map(a=>({key:a.zoneName,name:a.zoneName,value:a.yakCount,unit:"头",percent:e(a.yakCount/Math.max(S,1)*100,1)})).sort((a,n)=>n.value-a.value),p=b.map(a=>({key:a.label,name:a.label,value:a.value,unit:"头",yoy:a.yoy,percent:e(a.value/Math.max(x,1)*100,1)})),B=Math.max(...M.map(a=>Number(a.value)||0),1),V=M.map(a=>{const n=a.name.includes("储备")||a.name.includes("加工")?`${Number(a.capacity||0).toLocaleString("zh-CN")}吨`:"已接入";return{key:a.name,name:a.name,value:a.value,unit:a.unit,capacity:a.capacity,capacityNote:n,percent:e((Number(a.value)||0)/B*100,1)}});var f,h;const $=[{key:"flow-grassland",module:"林草湿",name:"草地面积分布完成乡镇归集",value:o,unit:"万亩",trend:"+0.8%"},{key:"flow-wetland",module:"林草湿",name:"湿地生产力指标进入总览",value:s,unit:"万吨",trend:"+1.2%"},{key:"flow-woodland",module:"林草湿",name:"公益林保护面积同步",value:y,unit:"万亩",trend:"89.6%"},{key:"flow-yak-town",module:"牦牛",name:"畜群结构总量同步",value:d,unit:"头",trend:"+2.4%"},{key:"flow-yak-density",module:"草畜",name:"草畜密度联动核算",value:N,unit:"头/万亩",trend:"联动"},{key:"flow-trade-1",module:"交易",name:"屠宰出栏流通记录入库",value:((f=p[0])==null?void 0:f.value)||0,unit:"头",trend:"+6%"},{key:"flow-trade-2",module:"交易",name:"活畜交易影响扣减存栏",value:((h=p[1])==null?void 0:h.value)||0,unit:"头",trend:"-3%"},{key:"flow-industry",module:"产业",name:"饲草储备与加工主体纳入画像",value:c.baseCount+c.projectCount,unit:"个",trend:"在线"}],q=[{key:"grassland",label:"草地",value:o,unit:"万亩",x:50,y:15,color:"#24f6c4"},{key:"wetland",label:"湿地",value:l,unit:"万亩",x:83,y:48,color:"#32dcff"},{key:"trade",label:"交易",value:x,unit:"头",x:68,y:72,color:"#8bf7ff"},{key:"yak",label:"牦牛",value:d,unit:"头",x:24,y:74,color:"#24f6c4"},{key:"woodland",label:"林地",value:r,unit:"万亩",x:16,y:35,color:"#8bf7ff"}];export{j as a,J as b,p as c,$ as d,q as e,I as h,D as r,V as s,L as t,O as y}; |
||||
@ -0,0 +1 @@ |
||||
const u=480;function o(H,A,n){return Math.min(Math.max(H,A),n)}function F({point:H,rowCount:A=0,loading:n=!1,empty:s=!1,safeLeft:h=448,safeRight:r=1472,preferredTop:T=112,safeTop:L=72,preserveDesiredHeight:P=!1}){if(!H)return{width:480,height:176,style:{}};const i=o(Number(A)||0,0,12),R=n||s?176:58+Math.max(i,1)*38,E=o(R,176,420),t=o(H.y-18,72,1080-28),a=t-T,I=t-L;let _=E,e=t-E;a>=112?(_=Math.min(E,a),e=t-_):I>=112?(_=Math.min(E,I),e=t-_):(_=Math.max(112,Math.min(E,t-72)),e=t-_),P&&(_=E,e=o(t-E,T,1080-E-28));const N=o(h,24,1920-480-24),D=o(r,N+480,1920-24),c=o(H.x-480/2,N,D-480),M=o(H.x-c,28,480-28);return{width:480,height:Math.round(_),style:{left:`${Math.round(c)}px`,top:`${Math.round(e)}px`,right:"auto",bottom:"auto",width:"480px","--feature-panel-anchor-x":`${Math.round(M)}px`}}}export{u as F,F as c}; |
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -1 +0,0 @@ |
||||
var m=(e,t,r)=>new Promise((s,u)=>{var a=i=>{try{c(r.next(i))}catch(l){u(l)}},n=i=>{try{c(r.throw(i))}catch(l){u(l)}},c=i=>i.done?s(i.value):Promise.resolve(i.value).then(a,n);c((r=r.apply(e,t)).next())});import{H as f,W as S}from"./townshipBoundaries-8867fad4-1785858872961.js";import{r as E}from"./index-d6700f13-1785858872961.js";const d="/geoserver/ne/wms",_={}.VITE_GEOSERVER_WFS_URL||d.replace(/\/wms$/i,"/wfs"),h={}.VITE_GEOSERVER_WMTS_URL||"/geoserver/gwc/service/wmts";function o(e,t){const r=new URLSearchParams;return Object.entries(t).forEach(([s,u])=>{u!=null&&u!==""&&r.append(s,u)}),`${e}${e.includes("?")?"&":"?"}${r.toString()}`}function y(e,t={}){const r=t.bounds||f,s=t.size||S;return o(t.url||d,{service:"WMS",version:"1.1.1",request:"GetMap",layers:e.layerName,styles:e.styles||"",format:"image/png",transparent:!0,tiled:!0,srs:"EPSG:4326",bbox:[r.west,r.south,r.east,r.north].join(","),width:s.width,height:s.height,CQL_FILTER:t.cqlFilter||e.cqlFilter,SLD_BODY:t.sldBody||e.sldBody,_:Date.now()})}function W(e,t={}){var a,n,c,i,l;const r=e.tileMatrixSetID||e.tileMatrixSet||"EPSG:900913",s=Number((i=(c=(n=(a=t.z)!=null?a:t.zoom)!=null?n:e.wmtsZoom)!=null?c:e.homeWmtsZoom)!=null?i:0),u=t.tileMatrix||((l=e.tileMatrixLabels)==null?void 0:l[s])||`${r}:${s}`;return o(t.url||e.url||h,{service:"WMTS",version:"1.0.0",request:"GetTile",layer:e.layerName,style:e.style||e.styles||"",format:e.format||"image/png",tileMatrixSet:r,tileMatrix:u,tileRow:t.y,tileCol:t.x})}function F(e,t,r={}){var a,n;const s=r.bounds||f,u=r.size||S;return o(r.url||d,{service:"WMS",version:"1.1.1",request:"GetFeatureInfo",layers:e.layerName,query_layers:e.layerName,styles:e.styles||"",info_format:"application/json",feature_count:5,srs:"EPSG:4326",bbox:[s.west,s.south,s.east,s.north].join(","),width:u.width,height:u.height,x:Math.round(t.x),y:Math.round(t.y),buffer:(n=(a=r.buffer)!=null?a:e.queryBuffer)!=null?n:8,CQL_FILTER:r.cqlFilter||e.cqlFilter,SLD_BODY:r.sldBody||e.sldBody})}function g(s,u){return m(this,arguments,function*(e,t,r={}){const a=F(e,t,r);return E(a,{credentials:"include"})})}function R(e,t={}){return o(t.url||_,{service:"WFS",version:t.version||"1.0.0",request:"GetFeature",typeName:e,outputFormat:"json",propertyName:Array.isArray(t.propertyName)?t.propertyName.join(","):t.propertyName,CQL_FILTER:t.cqlFilter,maxFeatures:t.maxFeatures||2e5})}function w(r){return m(this,arguments,function*(e,t={}){const s=R(e,t);return E(s,{credentials:"include",timeout:t.timeout||2e4})})}export{g as a,y as b,W as c,w as g}; |
||||
|
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 282 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
@ -0,0 +1 @@ |
||||
.isolation-page[data-v-69e5473e]{min-height:100vh;display:grid;place-items:center;padding:32px;color:#e9fbff;background:radial-gradient(circle at 50% 0%,#153a52 0,#071b2a 46%,#04121d 100%)}.isolation-card[data-v-69e5473e]{width:min(760px,100%);padding:42px;border:1px solid rgba(87,211,255,.35);border-radius:18px;background:rgba(5,24,38,.86);box-shadow:0 24px 80px #00000059}.eyebrow[data-v-69e5473e]{margin:0 0 8px;color:#62d7ff;letter-spacing:.18em}h1[data-v-69e5473e]{margin:0;font-size:clamp(28px,4vw,42px)}.summary[data-v-69e5473e]{margin:14px 0 30px;color:#9bb8c7}.status-grid[data-v-69e5473e]{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}.status-item[data-v-69e5473e]{display:flex;gap:12px;align-items:center;padding:16px;border-radius:10px;background:rgba(23,57,76,.62)}.status-item p[data-v-69e5473e]{margin:4px 0 0;color:#9bb8c7}.status-dot[data-v-69e5473e]{width:12px;height:12px;flex:none;border-radius:50%;background:#e0aa46;box-shadow:0 0 12px currentColor}.status-dot.up[data-v-69e5473e]{color:#37d693;background:currentColor}.status-dot.down[data-v-69e5473e]{color:#ff6b74;background:currentColor}.result[data-v-69e5473e]{margin:28px 0 16px}.result.up[data-v-69e5473e]{color:#37d693}.result.down[data-v-69e5473e]{color:#ff6b74}button[data-v-69e5473e]{padding:10px 18px;border:0;border-radius:8px;color:#042033;background:#62d7ff;cursor:pointer;font-weight:700}button[data-v-69e5473e]:disabled{cursor:wait;opacity:.65} |
||||
@ -1,4 +1,4 @@ |
||||
import{g as p,q as g,P as y,o as r,c as n,a as i,z as c,t as x,r as h,j as $,K as u,d as w}from"./index-1785858872961.js";const F=""+new URL("title-zs1-c15a5ee8-balabala-1785858872961.svg",import.meta.url).href,v=""+new URL("saoguang-ccf84a88-balabala-1785858872961.svg",import.meta.url).href,b=""+new URL("content-bottom-left-arrow-3a8a61f3-balabala-1785858872961.svg",import.meta.url).href,V=""+new URL("content-bottom-right-arrow-a3c5270d-balabala-1785858872961.svg",import.meta.url).href,f=""+new URL("content-middle-line-162bc0d5-balabala-1785858872961.svg",import.meta.url).href;const L={class:"m-card-hd"},H={class:"m-card-hd-bg"},U=["width","viewBox"],B=["clip-path"],E=["width"],M=["id"],S=["d"],Z=["d","fill"],G=["d","fill","mask"],C=["clip-path"],k=["x1"],D=["id","x1"],O=["id"],T=["id"],N=["width"],R=["id"],z={class:"m-card-hd-title"},A={key:0,class:"m-card-hd-extra"},P=["width","height","viewBox"],I=["opacity"],j=["d","fill"],q=["d"],K={class:"m-card-bd-content"},J={__name:"index",props:{width:{type:Number,default:398},height:{type:Number,default:200},title:{type:String,default:"标题"},bodyFill:{type:String,default:"rgba(26, 57, 77, 1)"},bodyOpacity:{type:Number,default:.6}},setup(e){const s=e,a=w(1),_=p(()=>{let l=s.width;return`M165 0.5
|
||||
import{g as p,q as g,aa as y,o as r,c as n,a as i,z as c,t as x,r as h,j as $,K as u,d as w}from"./index-1786725044461.js";const F=""+new URL("title-zs1-c15a5ee8-balabala-1786725044461.svg",import.meta.url).href,v=""+new URL("saoguang-ccf84a88-balabala-1786725044461.svg",import.meta.url).href,b=""+new URL("content-bottom-left-arrow-3a8a61f3-balabala-1786725044461.svg",import.meta.url).href,V=""+new URL("content-bottom-right-arrow-a3c5270d-balabala-1786725044461.svg",import.meta.url).href,f=""+new URL("content-middle-line-162bc0d5-balabala-1786725044461.svg",import.meta.url).href;const L={class:"m-card-hd"},H={class:"m-card-hd-bg"},U=["width","viewBox"],B=["clip-path"],E=["width"],M=["id"],S=["d"],Z=["d","fill"],G=["d","fill","mask"],C=["clip-path"],k=["x1"],D=["id","x1"],O=["id"],T=["id"],N=["width"],R=["id"],z={class:"m-card-hd-title"},A={key:0,class:"m-card-hd-extra"},P=["width","height","viewBox"],I=["opacity"],j=["d","fill"],q=["d"],K={class:"m-card-bd-content"},J={__name:"index",props:{width:{type:Number,default:398},height:{type:Number,default:200},title:{type:String,default:"标题"},bodyFill:{type:String,default:"rgba(26, 57, 77, 1)"},bodyOpacity:{type:Number,default:.6}},setup(e){const s=e,a=w(1),_=p(()=>{let l=s.width;return`M165 0.5
|
||||
L165.707 -0.207107 |
||||
L165.414 -0.5 |
||||
H165 |
||||
@ -0,0 +1 @@ |
||||
var y=(h,m,i)=>new Promise((d,r)=>{var l=t=>{try{o(i.next(t))}catch(u){r(u)}},v=t=>{try{o(i.throw(t))}catch(u){r(u)}},o=t=>t.done?d(t.value):Promise.resolve(t.value).then(l,v);o((i=i.apply(h,m)).next())});import{l as B,m as M,g as L,q,G as A,o as f,c as g,a,B as w,f as D,s as x,H as I,I as N,t as _,j as b,u as R,d as n,J as U}from"./index-1786725044461.js";import{_ as $}from"./_plugin-vue_export-helper-c27b6911-1786725044461.js";const E={class:"login-screen"},K={class:"login-shell"},T={class:"login-field"},j=["disabled"],F={class:"login-field login-password-field"},G={class:"login-password-control"},H=["disabled","type"],J=["aria-label","aria-pressed"],O={key:0,class:"login-field-assist","aria-live":"polite"},P={key:1,class:"login-error",role:"alert"},W={key:2,class:"login-error",role:"status"},z=["disabled"],Q={__name:"index",setup(h){const m=B(),i=M(),d=n(""),r=n(""),l=n(!1),v=n(!1),o=n(!1),t=n(""),u=n(!1),c=n(!1),C=L(()=>{const s=typeof m.query.redirect=="string"?decodeURIComponent(m.query.redirect):"/platform";return s.startsWith("/login")?"/platform":s||"/platform"});function S(){return y(this,null,function*(){if(t.value="",!d.value||!r.value){t.value="请输入账号和密码。";return}o.value=!0;try{yield U(d.value,r.value),i.replace(C.value)}catch(s){t.value=V(s)}finally{o.value=!1}})}q(()=>y(this,null,function*(){try{const s=yield A();c.value=s.loginAvailable===!0}catch(s){t.value="认证状态暂时无法确认,请稍后重试。"}finally{u.value=!0}}));function k(s){var e;v.value=!!((e=s==null?void 0:s.getModifierState)!=null&&e.call(s,"CapsLock"))}function V(s){const e=String((s==null?void 0:s.message)||"").trim();return/401|403|账号|密码|unauthor/i.test(e)?"账号或密码不正确,请核对后重试。":/network|fetch|timeout|连接|服务|502|503|504/i.test(e)?"登录服务暂时无法连接,请稍后重试。":"暂时无法登录,请稍后重试。"}return(s,e)=>(f(),g("div",E,[a("div",K,[e[9]||(e[9]=a("section",{class:"login-brand","aria-label":"红原县数字畜牧业监管平台"},[a("div",{class:"login-brand-rule","aria-hidden":"true"},[a("i"),a("span"),a("i")]),a("h1",null,[w("红原县数字畜牧业"),a("br"),w("监管平台")]),a("div",{class:"login-brand-glow","aria-hidden":"true"})],-1)),a("form",{class:"login-panel","aria-label":"平台用户登录",onSubmit:D(S,["prevent"])},[e[8]||(e[8]=a("header",{class:"login-panel-head"},[a("div",{class:"login-panel-title"},"用户登录"),a("span",{"aria-hidden":"true"})],-1)),a("label",T,[e[5]||(e[5]=a("span",null,"账号",-1)),x(a("input",{"onUpdate:modelValue":e[0]||(e[0]=p=>d.value=p),disabled:!c.value,autocomplete:"username",autofocus:"",placeholder:"请输入平台账号"},null,8,j),[[I,d.value,void 0,{trim:!0}]])]),a("label",F,[e[6]||(e[6]=a("span",null,"密码",-1)),a("span",G,[x(a("input",{"onUpdate:modelValue":e[1]||(e[1]=p=>r.value=p),disabled:!c.value,autocomplete:"current-password",placeholder:"请输入密码",type:l.value?"text":"password",onKeydown:k,onKeyup:k,onBlur:e[2]||(e[2]=p=>v.value=!1)},null,40,H),[[N,r.value]]),a("button",{class:"login-password-toggle",type:"button","aria-label":l.value?"隐藏密码":"显示密码","aria-pressed":l.value,onClick:e[3]||(e[3]=p=>l.value=!l.value)},_(l.value?"隐藏":"显示"),9,J)])]),v.value?(f(),g("div",O,[...e[7]||(e[7]=[a("span",{class:"login-caps-lock"},"大写锁定已开启",-1)])])):b("",!0),t.value?(f(),g("div",P,_(t.value),1)):b("",!0),u.value&&!c.value?(f(),g("div",W," V3 认证数据尚未初始化,当前仅可使用本机迁移检查入口。 ")):b("",!0),a("button",{class:"login-submit",disabled:o.value||!c.value,type:"submit"},_(o.value?"登录中":"登录"),9,z),u.value&&!c.value?(f(),g("button",{key:3,class:"login-secondary",type:"button",onClick:e[4]||(e[4]=p=>R(i).replace("/v3-isolation"))}," 返回隔离检查 ")):b("",!0)],32)])]))}},ee=$(Q,[["__scopeId","data-v-629c854a"]]);export{ee as default}; |
||||
@ -1 +0,0 @@ |
||||
.cesium-map[data-v-b391bc11]{position:absolute;z-index:1;top:0;right:0;bottom:0;left:0;overflow:hidden;background:#020b12}.cesium-map__viewer[data-v-b391bc11],.cesium-map__viewer[data-v-b391bc11] .cesium-viewer,.cesium-map__viewer[data-v-b391bc11] .cesium-viewer-cesiumWidgetContainer,.cesium-map__viewer[data-v-b391bc11] .cesium-widget,.cesium-map__viewer[data-v-b391bc11] canvas{width:100%;height:100%}.cesium-map__viewer[data-v-b391bc11] canvas{display:block;outline:none}.cesium-map__viewer[data-v-b391bc11] .cesium-viewer-bottom,.cesium-map__viewer[data-v-b391bc11] .cesium-widget-credits{display:none!important} |
||||