feat: sync full workspace including web modules, docs, and configurations to Gitea
Optimized the root .gitignore to exclude virtual environments, node modules, and temp folders to ensure clean and lightweight version tracking. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
BIN
web端/.DS_Store
vendored
BIN
web端/.DS_Store
vendored
Binary file not shown.
57
web端/styles/README.md
Normal file
57
web端/styles/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 车辆管理样式(ONE-OS Web)
|
||||
|
||||
与 `web端/车辆管理.jsx` 页面规范一致,可直接用于前端构建。
|
||||
|
||||
## 文件说明
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `vm-tokens.css` | 设计令牌(`:root` CSS 变量) |
|
||||
| `vehicle-management.css` | 页面组件样式(筛选、表格、详情、Ant 覆盖) |
|
||||
| `index.css` | **推荐入口**,聚合上述文件 |
|
||||
|
||||
## 引入方式
|
||||
|
||||
### 1. 静态 HTML
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://unpkg.com/antd@5/dist/reset.css" />
|
||||
<link rel="stylesheet" href="./web端/styles/index.css" />
|
||||
```
|
||||
|
||||
页面根节点:
|
||||
|
||||
```html
|
||||
<div class="vm-page">
|
||||
<!-- 列表 / 详情内容 -->
|
||||
</div>
|
||||
```
|
||||
|
||||
### 2. Vite / Webpack
|
||||
|
||||
```js
|
||||
import 'antd/dist/reset.css';
|
||||
import '../web端/styles/index.css';
|
||||
```
|
||||
|
||||
### 3. Axhub / JSX 原型(当前仓库)
|
||||
|
||||
`车辆管理.jsx` 会在运行时自动注入 `styles/vehicle-management.css`(已 `@import` tokens)。
|
||||
|
||||
若部署路径不同,可设置:
|
||||
|
||||
```js
|
||||
window.VM_STYLESHEET_HREF = '/assets/styles/vehicle-management.css';
|
||||
```
|
||||
|
||||
## 类名约定
|
||||
|
||||
- 页面容器:`.vm-page`
|
||||
- 详情页:`.vm-page.vm-detail-shell`
|
||||
- 筛选:`.vm-filter-card`、`.vm-filter-grid`、`.vm-filter-field`
|
||||
- 表格:`.vm-table-section`、`.vm-table-card`、`.vm-list-table`
|
||||
- 弹窗:Modal 增加 `wrapClassName="vm-modal-wrap"`
|
||||
|
||||
## 定制主题
|
||||
|
||||
修改 `vm-tokens.css` 中 `--vm-color-primary` 等变量即可全局换色,无需改组件样式文件。
|
||||
14
web端/styles/index.css
Normal file
14
web端/styles/index.css
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* ONE-OS Web 端 — 车辆管理样式入口
|
||||
* 构建时在入口 HTML/JS 中引入本文件即可
|
||||
*
|
||||
* @example HTML
|
||||
* <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd@5/dist/reset.css" />
|
||||
* <link rel="stylesheet" href="./styles/index.css" />
|
||||
*
|
||||
* @example Webpack / Vite
|
||||
* import 'antd/dist/reset.css';
|
||||
* import './styles/index.css';
|
||||
*/
|
||||
|
||||
@import url('./vehicle-management.css');
|
||||
7
web端/styles/oneos-arco-theme-README.md
Normal file
7
web端/styles/oneos-arco-theme-README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# ONEOS Arco 主题(@arco-themes/vue-oneos)
|
||||
|
||||
来源:[npm @arco-themes/vue-oneos](https://www.npmjs.com/package/@arco-themes/vue-oneos)
|
||||
|
||||
`web端/styles/oneos-arco-theme.css` 为官方 theme 副本,供后续接入 Vue/Arco 时参考。
|
||||
|
||||
**站点信息页**当前使用列表页绿色规范(`H2_PAGE_STYLE`),未启用 OneOS 蓝主题。
|
||||
509
web端/styles/oneos-arco-theme.css
Normal file
509
web端/styles/oneos-arco-theme.css
Normal file
@@ -0,0 +1,509 @@
|
||||
body {
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, PingFang SC, Hiragino Sans GB, noto sans, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
body {
|
||||
--color-white: #ffffff;
|
||||
--color-black: #000000;
|
||||
--color-border: rgb(var(--gray-3));
|
||||
--color-bg-popup: var(--color-bg-5);
|
||||
--color-bg-1: #fff;
|
||||
--color-bg-2: #fff;
|
||||
--color-bg-3: #fff;
|
||||
--color-bg-4: #fff;
|
||||
--color-bg-5: #fff;
|
||||
--color-bg-white: #fff;
|
||||
--color-neutral-1: rgb(var(--gray-1));
|
||||
--color-neutral-2: rgb(var(--gray-2));
|
||||
--color-neutral-3: rgb(var(--gray-3));
|
||||
--color-neutral-4: rgb(var(--gray-4));
|
||||
--color-neutral-5: rgb(var(--gray-5));
|
||||
--color-neutral-6: rgb(var(--gray-6));
|
||||
--color-neutral-7: rgb(var(--gray-7));
|
||||
--color-neutral-8: rgb(var(--gray-8));
|
||||
--color-neutral-9: rgb(var(--gray-9));
|
||||
--color-neutral-10: rgb(var(--gray-10));
|
||||
--color-text-1: #121314;
|
||||
--color-text-2: #5c5c5c;
|
||||
--color-text-3: #909399;
|
||||
--color-text-4: #c2c2c2;
|
||||
--color-fill-1: #fafafa;
|
||||
--color-fill-2: var(--color-neutral-2);
|
||||
--color-fill-3: var(--color-neutral-3);
|
||||
--color-fill-4: var(--color-neutral-4);
|
||||
--color-border-1: #ebeef5;
|
||||
--color-border-2: #e5e6eb;
|
||||
--color-border-3: #dcdfe6;
|
||||
--color-border-4: #cdd0d6;
|
||||
--color-primary-light-1: rgb(var(--primary-1));
|
||||
--color-primary-light-2: rgb(var(--primary-2));
|
||||
--color-primary-light-3: rgb(var(--primary-3));
|
||||
--color-primary-light-4: rgb(var(--primary-4));
|
||||
--color-secondary: var(--color-neutral-2);
|
||||
--color-secondary-hover: var(--color-neutral-3);
|
||||
--color-secondary-active: var(--color-neutral-4);
|
||||
--color-secondary-disabled: var(--color-neutral-1);
|
||||
--color-danger-light-1: rgb(var(--danger-1));
|
||||
--color-danger-light-2: rgb(var(--danger-2));
|
||||
--color-danger-light-3: rgb(var(--danger-3));
|
||||
--color-danger-light-4: rgb(var(--danger-4));
|
||||
--color-success-light-1: rgb(var(--success-1));
|
||||
--color-success-light-2: rgb(var(--success-2));
|
||||
--color-success-light-3: rgb(var(--success-3));
|
||||
--color-success-light-4: rgb(var(--success-4));
|
||||
--color-warning-light-1: rgb(var(--warning-1));
|
||||
--color-warning-light-2: rgb(var(--warning-2));
|
||||
--color-warning-light-3: rgb(var(--warning-3));
|
||||
--color-warning-light-4: rgb(var(--warning-4));
|
||||
--color-link-light-1: rgb(var(--link-1));
|
||||
--color-link-light-2: rgb(var(--link-2));
|
||||
--color-link-light-3: rgb(var(--link-3));
|
||||
--color-link-light-4: rgb(var(--link-4));
|
||||
--border-radius-none: 0;
|
||||
--border-radius-small: 4px;
|
||||
--border-radius-medium: 6px;
|
||||
--border-radius-large: 8px;
|
||||
--border-radius-circle: 50%;
|
||||
--color-tooltip-bg: rgb(var(--gray-10));
|
||||
--color-spin-layer-bg: rgba(255, 255, 255, 0.6);
|
||||
--color-menu-dark-bg: #232324;
|
||||
--color-menu-light-bg: #ffffff;
|
||||
--color-menu-dark-hover: rgba(255, 255, 255, 0.04);
|
||||
--color-mask-bg: rgba(29, 33, 41, 0.6);
|
||||
}
|
||||
body[arco-theme='dark'] {
|
||||
--color-black: #000000;
|
||||
--color-border: #333335;
|
||||
--color-bg-1: #17171a;
|
||||
--color-bg-2: #232324;
|
||||
--color-bg-3: #2a2a2b;
|
||||
--color-bg-4: #313132;
|
||||
--color-bg-5: #373739;
|
||||
--color-bg-white: #f6f6f6;
|
||||
--color-text-1: rgba(255, 255, 255, 0.9);
|
||||
--color-text-2: rgba(255, 255, 255, 0.7);
|
||||
--color-text-3: rgba(255, 255, 255, 0.5);
|
||||
--color-text-4: rgba(255, 255, 255, 0.3);
|
||||
--color-fill-1: rgba(255, 255, 255, 0.04);
|
||||
--color-fill-2: rgba(255, 255, 255, 0.08);
|
||||
--color-fill-3: rgba(255, 255, 255, 0.12);
|
||||
--color-fill-4: rgba(255, 255, 255, 0.16);
|
||||
--color-border-1: var(--color-neutral-2);
|
||||
--color-border-2: var(--color-neutral-3);
|
||||
--color-border-3: var(--color-neutral-4);
|
||||
--color-border-4: var(--color-neutral-6);
|
||||
--color-primary-light-1: rgba(var(--primary-6), 0.2);
|
||||
--color-primary-light-2: rgba(var(--primary-6), 0.35);
|
||||
--color-primary-light-3: rgba(var(--primary-6), 0.5);
|
||||
--color-primary-light-4: rgba(var(--primary-6), 0.65);
|
||||
--color-secondary: rgba(var(--gray-9), 0.08);
|
||||
--color-secondary-hover: rgba(var(--gray-8), 0.16);
|
||||
--color-secondary-active: rgba(var(--gray-7), 0.24);
|
||||
--color-secondary-disabled: rgba(var(--gray-9), 0.08);
|
||||
--color-danger-light-1: rgba(var(--danger-6), 0.2);
|
||||
--color-danger-light-2: rgba(var(--danger-6), 0.35);
|
||||
--color-danger-light-3: rgba(var(--danger-6), 0.5);
|
||||
--color-danger-light-4: rgba(var(--danger-6), 0.65);
|
||||
--color-success-light-1: rgba(var(--success-6), 0.2);
|
||||
--color-success-light-2: rgba(var(--success-6), 0.35);
|
||||
--color-success-light-3: rgba(var(--success-6), 0.5);
|
||||
--color-success-light-4: rgba(var(--success-6), 0.65);
|
||||
--color-warning-light-1: rgba(var(--warning-6), 0.2);
|
||||
--color-warning-light-2: rgba(var(--warning-6), 0.35);
|
||||
--color-warning-light-3: rgba(var(--warning-6), 0.5);
|
||||
--color-warning-light-4: rgba(var(--warning-6), 0.65);
|
||||
--color-link-light-1: rgba(var(--link-6), 0.2);
|
||||
--color-link-light-2: rgba(var(--link-6), 0.35);
|
||||
--color-link-light-3: rgba(var(--link-6), 0.5);
|
||||
--color-link-light-4: rgba(var(--link-6), 0.65);
|
||||
--color-tooltip-bg: #373739;
|
||||
--color-spin-layer-bg: rgba(51, 51, 51, 0.6);
|
||||
--color-menu-dark-bg: #232324;
|
||||
--color-menu-light-bg: #232324;
|
||||
--color-menu-dark-hover: var(--color-fill-2);
|
||||
--color-mask-bg: rgba(23, 23, 26, 0.6);
|
||||
}
|
||||
body {
|
||||
--red-1: 255, 236, 232;
|
||||
--red-2: 253, 205, 197;
|
||||
--red-3: 251, 172, 163;
|
||||
--red-4: 249, 137, 129;
|
||||
--red-5: 247, 101, 96;
|
||||
--red-6: 245, 63, 63;
|
||||
--red-7: 203, 39, 45;
|
||||
--red-8: 161, 21, 30;
|
||||
--red-9: 119, 8, 19;
|
||||
--red-10: 77, 0, 10;
|
||||
--orangered-1: 255, 243, 232;
|
||||
--orangered-2: 253, 221, 195;
|
||||
--orangered-3: 252, 197, 159;
|
||||
--orangered-4: 250, 172, 123;
|
||||
--orangered-5: 249, 144, 87;
|
||||
--orangered-6: 247, 114, 52;
|
||||
--orangered-7: 204, 81, 32;
|
||||
--orangered-8: 162, 53, 17;
|
||||
--orangered-9: 119, 31, 6;
|
||||
--orangered-10: 77, 14, 0;
|
||||
--orange-1: 255, 247, 232;
|
||||
--orange-2: 255, 228, 186;
|
||||
--orange-3: 255, 207, 139;
|
||||
--orange-4: 255, 182, 93;
|
||||
--orange-5: 255, 154, 46;
|
||||
--orange-6: 255, 125, 0;
|
||||
--orange-7: 210, 95, 0;
|
||||
--orange-8: 166, 69, 0;
|
||||
--orange-9: 121, 46, 0;
|
||||
--orange-10: 77, 27, 0;
|
||||
--gold-1: 255, 252, 232;
|
||||
--gold-2: 253, 244, 191;
|
||||
--gold-3: 252, 233, 150;
|
||||
--gold-4: 250, 220, 109;
|
||||
--gold-5: 249, 204, 69;
|
||||
--gold-6: 247, 186, 30;
|
||||
--gold-7: 204, 146, 19;
|
||||
--gold-8: 162, 109, 10;
|
||||
--gold-9: 119, 75, 4;
|
||||
--gold-10: 77, 45, 0;
|
||||
--yellow-1: 254, 255, 232;
|
||||
--yellow-2: 254, 254, 190;
|
||||
--yellow-3: 253, 250, 148;
|
||||
--yellow-4: 252, 242, 107;
|
||||
--yellow-5: 251, 232, 66;
|
||||
--yellow-6: 250, 220, 25;
|
||||
--yellow-7: 207, 175, 15;
|
||||
--yellow-8: 163, 132, 8;
|
||||
--yellow-9: 120, 93, 3;
|
||||
--yellow-10: 77, 56, 0;
|
||||
--lime-1: 252, 255, 232;
|
||||
--lime-2: 237, 248, 187;
|
||||
--lime-3: 220, 241, 144;
|
||||
--lime-4: 201, 233, 104;
|
||||
--lime-5: 181, 226, 65;
|
||||
--lime-6: 159, 219, 29;
|
||||
--lime-7: 126, 183, 18;
|
||||
--lime-8: 95, 148, 10;
|
||||
--lime-9: 67, 112, 4;
|
||||
--lime-10: 42, 77, 0;
|
||||
--green-1: 232, 255, 234;
|
||||
--green-2: 175, 240, 181;
|
||||
--green-3: 123, 225, 136;
|
||||
--green-4: 76, 210, 99;
|
||||
--green-5: 35, 195, 67;
|
||||
--green-6: 0, 180, 42;
|
||||
--green-7: 0, 154, 41;
|
||||
--green-8: 0, 128, 38;
|
||||
--green-9: 0, 102, 34;
|
||||
--green-10: 0, 77, 28;
|
||||
--cyan-1: 232, 255, 251;
|
||||
--cyan-2: 183, 244, 236;
|
||||
--cyan-3: 137, 233, 224;
|
||||
--cyan-4: 94, 223, 214;
|
||||
--cyan-5: 55, 212, 207;
|
||||
--cyan-6: 20, 201, 201;
|
||||
--cyan-7: 13, 165, 170;
|
||||
--cyan-8: 7, 130, 139;
|
||||
--cyan-9: 3, 97, 108;
|
||||
--cyan-10: 0, 66, 77;
|
||||
--blue-1: 232, 247, 255;
|
||||
--blue-2: 195, 231, 254;
|
||||
--blue-3: 159, 212, 253;
|
||||
--blue-4: 123, 192, 252;
|
||||
--blue-5: 87, 169, 251;
|
||||
--blue-6: 52, 145, 250;
|
||||
--blue-7: 32, 108, 207;
|
||||
--blue-8: 17, 75, 163;
|
||||
--blue-9: 6, 48, 120;
|
||||
--blue-10: 0, 26, 77;
|
||||
--arcoblue-1: 232, 243, 255;
|
||||
--arcoblue-2: 190, 218, 255;
|
||||
--arcoblue-3: 148, 191, 255;
|
||||
--arcoblue-4: 106, 161, 255;
|
||||
--arcoblue-5: 64, 128, 255;
|
||||
--arcoblue-6: 22, 93, 255;
|
||||
--arcoblue-7: 14, 66, 210;
|
||||
--arcoblue-8: 7, 44, 166;
|
||||
--arcoblue-9: 3, 26, 121;
|
||||
--arcoblue-10: 0, 13, 77;
|
||||
--purple-1: 245, 232, 255;
|
||||
--purple-2: 221, 190, 246;
|
||||
--purple-3: 195, 150, 237;
|
||||
--purple-4: 168, 113, 227;
|
||||
--purple-5: 141, 78, 218;
|
||||
--purple-6: 114, 46, 209;
|
||||
--purple-7: 85, 29, 176;
|
||||
--purple-8: 60, 16, 143;
|
||||
--purple-9: 39, 6, 110;
|
||||
--purple-10: 22, 0, 77;
|
||||
--pinkpurple-1: 255, 232, 251;
|
||||
--pinkpurple-2: 247, 186, 239;
|
||||
--pinkpurple-3: 240, 142, 230;
|
||||
--pinkpurple-4: 232, 101, 223;
|
||||
--pinkpurple-5: 225, 62, 219;
|
||||
--pinkpurple-6: 217, 26, 217;
|
||||
--pinkpurple-7: 176, 16, 182;
|
||||
--pinkpurple-8: 138, 9, 147;
|
||||
--pinkpurple-9: 101, 3, 112;
|
||||
--pinkpurple-10: 66, 0, 77;
|
||||
--magenta-1: 255, 232, 241;
|
||||
--magenta-2: 253, 194, 219;
|
||||
--magenta-3: 251, 157, 199;
|
||||
--magenta-4: 249, 121, 183;
|
||||
--magenta-5: 247, 84, 168;
|
||||
--magenta-6: 245, 49, 157;
|
||||
--magenta-7: 203, 30, 131;
|
||||
--magenta-8: 161, 16, 105;
|
||||
--magenta-9: 119, 6, 79;
|
||||
--magenta-10: 77, 0, 52;
|
||||
--gray-1: 247, 248, 250;
|
||||
--gray-2: 242, 243, 245;
|
||||
--gray-3: 229, 230, 235;
|
||||
--gray-4: 201, 205, 212;
|
||||
--gray-5: 169, 174, 184;
|
||||
--gray-6: 134, 144, 156;
|
||||
--gray-7: 107, 119, 133;
|
||||
--gray-8: 78, 89, 105;
|
||||
--gray-9: 39, 46, 59;
|
||||
--gray-10: 29, 33, 41;
|
||||
--primary-1: var(--arcoblue-1);
|
||||
--primary-2: var(--arcoblue-2);
|
||||
--primary-3: var(--arcoblue-3);
|
||||
--primary-4: var(--arcoblue-4);
|
||||
--primary-5: var(--arcoblue-5);
|
||||
--primary-6: var(--arcoblue-6);
|
||||
--primary-7: var(--arcoblue-7);
|
||||
--primary-8: var(--arcoblue-8);
|
||||
--primary-9: var(--arcoblue-9);
|
||||
--primary-10: var(--arcoblue-10);
|
||||
--link-1: var(--arcoblue-1);
|
||||
--link-2: var(--arcoblue-2);
|
||||
--link-3: var(--arcoblue-3);
|
||||
--link-4: var(--arcoblue-4);
|
||||
--link-5: var(--arcoblue-5);
|
||||
--link-6: var(--arcoblue-6);
|
||||
--link-7: var(--arcoblue-7);
|
||||
--link-8: var(--arcoblue-8);
|
||||
--link-9: var(--arcoblue-9);
|
||||
--link-10: var(--arcoblue-10);
|
||||
--success-1: var(--green-1);
|
||||
--success-2: var(--green-2);
|
||||
--success-3: var(--green-3);
|
||||
--success-4: var(--green-4);
|
||||
--success-5: var(--green-5);
|
||||
--success-6: var(--green-6);
|
||||
--success-7: var(--green-7);
|
||||
--success-8: var(--green-8);
|
||||
--success-9: var(--green-9);
|
||||
--success-10: var(--green-10);
|
||||
--danger-1: var(--red-1);
|
||||
--danger-2: var(--red-2);
|
||||
--danger-3: var(--red-3);
|
||||
--danger-4: var(--red-4);
|
||||
--danger-5: var(--red-5);
|
||||
--danger-6: var(--red-6);
|
||||
--danger-7: var(--red-7);
|
||||
--danger-8: var(--red-8);
|
||||
--danger-9: var(--red-9);
|
||||
--danger-10: var(--red-10);
|
||||
--warning-1: var(--orange-1);
|
||||
--warning-2: var(--orange-2);
|
||||
--warning-3: var(--orange-3);
|
||||
--warning-4: var(--orange-4);
|
||||
--warning-5: var(--orange-5);
|
||||
--warning-6: var(--orange-6);
|
||||
--warning-7: var(--orange-7);
|
||||
--warning-8: var(--orange-8);
|
||||
--warning-9: var(--orange-9);
|
||||
--warning-10: var(--orange-10);
|
||||
}
|
||||
body[arco-theme='dark'] {
|
||||
--red-1: 77, 0, 10;
|
||||
--red-2: 119, 6, 17;
|
||||
--red-3: 161, 22, 31;
|
||||
--red-4: 203, 46, 52;
|
||||
--red-5: 245, 78, 78;
|
||||
--red-6: 247, 105, 101;
|
||||
--red-7: 249, 141, 134;
|
||||
--red-8: 251, 176, 167;
|
||||
--red-9: 253, 209, 202;
|
||||
--red-10: 255, 240, 236;
|
||||
--orangered-1: 77, 14, 0;
|
||||
--orangered-2: 119, 30, 5;
|
||||
--orangered-3: 162, 55, 20;
|
||||
--orangered-4: 204, 87, 41;
|
||||
--orangered-5: 247, 126, 69;
|
||||
--orangered-6: 249, 146, 90;
|
||||
--orangered-7: 250, 173, 125;
|
||||
--orangered-8: 252, 198, 161;
|
||||
--orangered-9: 253, 222, 197;
|
||||
--orangered-10: 255, 244, 235;
|
||||
--orange-1: 77, 27, 0;
|
||||
--orange-2: 121, 48, 4;
|
||||
--orange-3: 166, 75, 10;
|
||||
--orange-4: 210, 105, 19;
|
||||
--orange-5: 255, 141, 31;
|
||||
--orange-6: 255, 150, 38;
|
||||
--orange-7: 255, 179, 87;
|
||||
--orange-8: 255, 205, 135;
|
||||
--orange-9: 255, 227, 184;
|
||||
--orange-10: 255, 247, 232;
|
||||
--gold-1: 77, 45, 0;
|
||||
--gold-2: 119, 75, 4;
|
||||
--gold-3: 162, 111, 15;
|
||||
--gold-4: 204, 150, 31;
|
||||
--gold-5: 247, 192, 52;
|
||||
--gold-6: 249, 204, 68;
|
||||
--gold-7: 250, 220, 108;
|
||||
--gold-8: 252, 233, 149;
|
||||
--gold-9: 253, 244, 190;
|
||||
--gold-10: 255, 252, 232;
|
||||
--yellow-1: 77, 56, 0;
|
||||
--yellow-2: 120, 94, 7;
|
||||
--yellow-3: 163, 134, 20;
|
||||
--yellow-4: 207, 179, 37;
|
||||
--yellow-5: 250, 225, 60;
|
||||
--yellow-6: 251, 233, 75;
|
||||
--yellow-7: 252, 243, 116;
|
||||
--yellow-8: 253, 250, 157;
|
||||
--yellow-9: 254, 254, 198;
|
||||
--yellow-10: 254, 255, 240;
|
||||
--lime-1: 42, 77, 0;
|
||||
--lime-2: 68, 112, 6;
|
||||
--lime-3: 98, 148, 18;
|
||||
--lime-4: 132, 183, 35;
|
||||
--lime-5: 168, 219, 57;
|
||||
--lime-6: 184, 226, 75;
|
||||
--lime-7: 203, 233, 112;
|
||||
--lime-8: 222, 241, 152;
|
||||
--lime-9: 238, 248, 194;
|
||||
--lime-10: 253, 255, 238;
|
||||
--green-1: 0, 77, 28;
|
||||
--green-2: 4, 102, 37;
|
||||
--green-3: 10, 128, 45;
|
||||
--green-4: 18, 154, 55;
|
||||
--green-5: 29, 180, 64;
|
||||
--green-6: 39, 195, 70;
|
||||
--green-7: 80, 210, 102;
|
||||
--green-8: 126, 225, 139;
|
||||
--green-9: 178, 240, 183;
|
||||
--green-10: 235, 255, 236;
|
||||
--cyan-1: 0, 66, 77;
|
||||
--cyan-2: 6, 97, 108;
|
||||
--cyan-3: 17, 131, 139;
|
||||
--cyan-4: 31, 166, 170;
|
||||
--cyan-5: 48, 201, 201;
|
||||
--cyan-6: 63, 212, 207;
|
||||
--cyan-7: 102, 223, 215;
|
||||
--cyan-8: 144, 233, 225;
|
||||
--cyan-9: 190, 244, 237;
|
||||
--cyan-10: 240, 255, 252;
|
||||
--blue-1: 0, 26, 77;
|
||||
--blue-2: 5, 47, 120;
|
||||
--blue-3: 19, 76, 163;
|
||||
--blue-4: 41, 113, 207;
|
||||
--blue-5: 70, 154, 250;
|
||||
--blue-6: 90, 170, 251;
|
||||
--blue-7: 125, 193, 252;
|
||||
--blue-8: 161, 213, 253;
|
||||
--blue-9: 198, 232, 254;
|
||||
--blue-10: 234, 248, 255;
|
||||
--arcoblue-1: 0, 13, 77;
|
||||
--arcoblue-2: 4, 27, 121;
|
||||
--arcoblue-3: 14, 50, 166;
|
||||
--arcoblue-4: 29, 77, 210;
|
||||
--arcoblue-5: 48, 111, 255;
|
||||
--arcoblue-6: 60, 126, 255;
|
||||
--arcoblue-7: 104, 159, 255;
|
||||
--arcoblue-8: 147, 190, 255;
|
||||
--arcoblue-9: 190, 218, 255;
|
||||
--arcoblue-10: 234, 244, 255;
|
||||
--purple-1: 22, 0, 77;
|
||||
--purple-2: 39, 6, 110;
|
||||
--purple-3: 62, 19, 143;
|
||||
--purple-4: 90, 37, 176;
|
||||
--purple-5: 123, 61, 209;
|
||||
--purple-6: 142, 81, 218;
|
||||
--purple-7: 169, 116, 227;
|
||||
--purple-8: 197, 154, 237;
|
||||
--purple-9: 223, 194, 246;
|
||||
--purple-10: 247, 237, 255;
|
||||
--pinkpurple-1: 66, 0, 77;
|
||||
--pinkpurple-2: 101, 3, 112;
|
||||
--pinkpurple-3: 138, 13, 147;
|
||||
--pinkpurple-4: 176, 27, 182;
|
||||
--pinkpurple-5: 217, 46, 217;
|
||||
--pinkpurple-6: 225, 61, 219;
|
||||
--pinkpurple-7: 232, 102, 223;
|
||||
--pinkpurple-8: 240, 146, 230;
|
||||
--pinkpurple-9: 247, 193, 240;
|
||||
--pinkpurple-10: 255, 242, 253;
|
||||
--magenta-1: 77, 0, 52;
|
||||
--magenta-2: 119, 8, 80;
|
||||
--magenta-3: 161, 23, 108;
|
||||
--magenta-4: 203, 43, 136;
|
||||
--magenta-5: 245, 69, 166;
|
||||
--magenta-6: 247, 86, 169;
|
||||
--magenta-7: 249, 122, 184;
|
||||
--magenta-8: 251, 158, 200;
|
||||
--magenta-9: 253, 195, 219;
|
||||
--magenta-10: 255, 232, 241;
|
||||
--gray-1: 23, 23, 26;
|
||||
--gray-2: 46, 46, 48;
|
||||
--gray-3: 72, 72, 73;
|
||||
--gray-4: 95, 95, 96;
|
||||
--gray-5: 120, 120, 122;
|
||||
--gray-6: 146, 146, 147;
|
||||
--gray-7: 171, 171, 172;
|
||||
--gray-8: 197, 197, 197;
|
||||
--gray-9: 223, 223, 223;
|
||||
--gray-10: 246, 246, 246;
|
||||
--primary-1: var(--arcoblue-1);
|
||||
--primary-2: var(--arcoblue-2);
|
||||
--primary-3: var(--arcoblue-3);
|
||||
--primary-4: var(--arcoblue-4);
|
||||
--primary-5: var(--arcoblue-5);
|
||||
--primary-6: var(--arcoblue-6);
|
||||
--primary-7: var(--arcoblue-7);
|
||||
--primary-8: var(--arcoblue-8);
|
||||
--primary-9: var(--arcoblue-9);
|
||||
--primary-10: var(--arcoblue-10);
|
||||
--link-1: var(--arcoblue-1);
|
||||
--link-2: var(--arcoblue-2);
|
||||
--link-3: var(--arcoblue-3);
|
||||
--link-4: var(--arcoblue-4);
|
||||
--link-5: var(--arcoblue-5);
|
||||
--link-6: var(--arcoblue-6);
|
||||
--link-7: var(--arcoblue-7);
|
||||
--link-8: var(--arcoblue-8);
|
||||
--link-9: var(--arcoblue-9);
|
||||
--link-10: var(--arcoblue-10);
|
||||
--success-1: var(--green-1);
|
||||
--success-2: var(--green-2);
|
||||
--success-3: var(--green-3);
|
||||
--success-4: var(--green-4);
|
||||
--success-5: var(--green-5);
|
||||
--success-6: var(--green-6);
|
||||
--success-7: var(--green-7);
|
||||
--success-8: var(--green-8);
|
||||
--success-9: var(--green-9);
|
||||
--success-10: var(--green-10);
|
||||
--danger-1: var(--red-1);
|
||||
--danger-2: var(--red-2);
|
||||
--danger-3: var(--red-3);
|
||||
--danger-4: var(--red-4);
|
||||
--danger-5: var(--red-5);
|
||||
--danger-6: var(--red-6);
|
||||
--danger-7: var(--red-7);
|
||||
--danger-8: var(--red-8);
|
||||
--danger-9: var(--red-9);
|
||||
--danger-10: var(--red-10);
|
||||
--warning-1: var(--orange-1);
|
||||
--warning-2: var(--orange-2);
|
||||
--warning-3: var(--orange-3);
|
||||
--warning-4: var(--orange-4);
|
||||
--warning-5: var(--orange-5);
|
||||
--warning-6: var(--orange-6);
|
||||
--warning-7: var(--orange-7);
|
||||
--warning-8: var(--orange-8);
|
||||
--warning-9: var(--orange-9);
|
||||
--warning-10: var(--orange-10);
|
||||
}
|
||||
|
||||
726
web端/styles/vehicle-management.css
Normal file
726
web端/styles/vehicle-management.css
Normal file
@@ -0,0 +1,726 @@
|
||||
/**
|
||||
* ONE-OS 车辆管理模块样式
|
||||
* 页面根节点: .vm-page
|
||||
* 构建引用: <link rel="stylesheet" href="styles/vehicle-management.css" />
|
||||
* 或: @import './styles/vehicle-management.css';
|
||||
*
|
||||
* 依赖: Ant Design v5(antd)
|
||||
* 建议顺序: antd.css → vm-tokens.css → vehicle-management.css
|
||||
*/
|
||||
|
||||
@import url('./vm-tokens.css');
|
||||
|
||||
/* ==========================================================================
|
||||
Page shell
|
||||
========================================================================== */
|
||||
|
||||
.vm-page {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: var(--vm-page-padding-y) var(--vm-page-padding-x) var(--vm-page-padding-bottom);
|
||||
font-family: var(--vm-font-family);
|
||||
font-size: var(--vm-font-size-base);
|
||||
line-height: var(--vm-line-height-normal);
|
||||
color: var(--vm-color-text);
|
||||
background: linear-gradient(
|
||||
165deg,
|
||||
var(--vm-color-bg-page-alt) 0%,
|
||||
var(--vm-color-bg-page) 50%,
|
||||
var(--vm-color-bg-page-alt) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.vm-page *,
|
||||
.vm-page *::before,
|
||||
.vm-page *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.vm-page.vm-detail-shell {
|
||||
padding: var(--vm-page-padding-y) var(--vm-page-padding-x);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Page header
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-page-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--vm-space-3);
|
||||
margin-bottom: var(--vm-space-4);
|
||||
}
|
||||
|
||||
.vm-page .vm-page-header .ant-breadcrumb {
|
||||
font-size: var(--vm-font-size-base);
|
||||
}
|
||||
|
||||
.vm-page .vm-page-header .ant-breadcrumb a,
|
||||
.vm-page .vm-page-header .ant-breadcrumb button {
|
||||
color: var(--vm-color-primary);
|
||||
cursor: pointer;
|
||||
transition: color var(--vm-duration-fast) var(--vm-ease-default);
|
||||
}
|
||||
|
||||
.vm-page .vm-page-header .ant-breadcrumb a:hover,
|
||||
.vm-page .vm-page-header .ant-breadcrumb button:hover {
|
||||
color: var(--vm-color-primary-hover);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Filter card
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-filter-card.ant-card {
|
||||
margin-bottom: var(--vm-space-4);
|
||||
border: 1px solid var(--vm-color-border) !important;
|
||||
border-radius: var(--vm-radius-2xl) !important;
|
||||
box-shadow: var(--vm-shadow-card) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-card > .ant-card-head {
|
||||
min-height: auto;
|
||||
padding: var(--vm-space-3) var(--vm-space-5) !important;
|
||||
border-bottom: 1px solid var(--vm-color-border-light) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-card > .ant-card-head .ant-card-head-title {
|
||||
padding: 0 !important;
|
||||
font-size: var(--vm-font-size-md) !important;
|
||||
font-weight: var(--vm-font-weight-bold) !important;
|
||||
color: var(--vm-color-text) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-card > .ant-card-body {
|
||||
padding: var(--vm-space-4) var(--vm-space-5) var(--vm-space-5) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--vm-filter-columns), minmax(0, 1fr));
|
||||
gap: 14px var(--vm-space-5);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field-label {
|
||||
flex: 0 0 var(--vm-filter-label-width);
|
||||
font-size: var(--vm-font-size-sm);
|
||||
font-weight: var(--vm-font-weight-medium);
|
||||
line-height: var(--vm-line-height-tight);
|
||||
color: var(--vm-color-text-secondary);
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field-control {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field-control .ant-input,
|
||||
.vm-page .vm-filter-field-control .ant-input-affix-wrapper,
|
||||
.vm-page .vm-filter-field-control .ant-select,
|
||||
.vm-page .vm-filter-field-control .ant-select-selector,
|
||||
.vm-page .vm-filter-field-control .ant-cascader,
|
||||
.vm-page .vm-filter-field-control .ant-picker {
|
||||
width: 100%;
|
||||
border-radius: var(--vm-radius-md) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--vm-space-2);
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: var(--vm-space-4);
|
||||
padding-top: var(--vm-space-4);
|
||||
border-top: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Table section
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-table-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.vm-page .vm-table-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px var(--vm-space-4);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.vm-page .vm-table-toolbar-meta {
|
||||
font-size: var(--vm-font-size-sm);
|
||||
color: var(--vm-color-text-muted);
|
||||
}
|
||||
|
||||
.vm-page .vm-table-toolbar-meta strong {
|
||||
font-weight: var(--vm-font-weight-bold);
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--vm-color-text);
|
||||
}
|
||||
|
||||
.vm-page .vm-table-toolbar-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--vm-space-2);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-search {
|
||||
width: var(--vm-table-toolbar-search-width);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-search .ant-input,
|
||||
.vm-page .vm-plate-search .ant-input-affix-wrapper,
|
||||
.vm-page .vm-plate-search .ant-input-search-button {
|
||||
border-radius: var(--vm-radius-md) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-table-card {
|
||||
overflow: hidden;
|
||||
background: var(--vm-color-bg-card);
|
||||
border: 1px solid var(--vm-color-border);
|
||||
border-radius: var(--vm-radius-2xl);
|
||||
box-shadow: var(--vm-shadow-card);
|
||||
}
|
||||
|
||||
/* List table */
|
||||
.vm-page .vm-list-table .ant-table-content table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-table-thead > tr > th {
|
||||
padding: var(--vm-space-3) var(--vm-space-4) !important;
|
||||
font-size: var(--vm-font-size-sm) !important;
|
||||
font-weight: var(--vm-font-weight-bold) !important;
|
||||
color: var(--vm-color-text-secondary) !important;
|
||||
background: var(--vm-color-bg-muted) !important;
|
||||
border-bottom: 1px solid var(--vm-color-border) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-table-tbody > tr:not(.ant-table-measure-row) > td {
|
||||
padding: var(--vm-space-3) var(--vm-space-4) !important;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
vertical-align: middle !important;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-table-tbody > tr:not(.ant-table-measure-row):hover > td {
|
||||
background: var(--vm-color-bg-muted) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-table-tbody > tr:not(.ant-table-measure-row) > td.ant-table-cell-fix-right {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-table-tbody > tr.ant-table-row-selected > td {
|
||||
background: var(--vm-color-primary-light) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-list-table .ant-pagination {
|
||||
margin: 0 !important;
|
||||
padding: var(--vm-space-3) var(--vm-space-4) !important;
|
||||
border-top: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Table cell components
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-action-btn {
|
||||
min-height: var(--vm-action-btn-min-height);
|
||||
padding: 0 var(--vm-space-1) !important;
|
||||
font-weight: var(--vm-font-weight-semibold) !important;
|
||||
color: var(--vm-color-primary) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-action-btn:hover {
|
||||
color: var(--vm-color-primary-hover) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-action-more-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--vm-action-more-size);
|
||||
height: var(--vm-action-more-size);
|
||||
color: var(--vm-color-text-muted);
|
||||
cursor: pointer;
|
||||
border-radius: var(--vm-radius-md);
|
||||
transition:
|
||||
background var(--vm-duration-fast) var(--vm-ease-default),
|
||||
color var(--vm-duration-fast) var(--vm-ease-default);
|
||||
}
|
||||
|
||||
.vm-page .vm-action-more-btn:hover {
|
||||
color: #334155;
|
||||
background: var(--vm-color-bg-hover);
|
||||
}
|
||||
|
||||
.vm-page .vm-action-more-btn:focus-visible {
|
||||
outline: 2px solid var(--vm-color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-link {
|
||||
padding: 0;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
font-weight: var(--vm-font-weight-bold);
|
||||
color: var(--vm-color-text);
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-link:hover {
|
||||
color: var(--vm-color-primary);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-link:focus-visible {
|
||||
border-radius: var(--vm-space-1);
|
||||
outline: 2px solid var(--vm-color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.vm-page .vm-vin-text {
|
||||
font-family: var(--vm-font-mono);
|
||||
font-size: var(--vm-font-size-xs);
|
||||
letter-spacing: 0.02em;
|
||||
color: var(--vm-color-text-secondary);
|
||||
}
|
||||
|
||||
.vm-page .vm-online-pill {
|
||||
display: inline-flex;
|
||||
gap: var(--vm-space-2);
|
||||
align-items: center;
|
||||
padding: 2px var(--vm-space-2);
|
||||
font-size: var(--vm-font-size-xs);
|
||||
font-weight: var(--vm-font-weight-semibold);
|
||||
border-radius: var(--vm-radius-pill);
|
||||
}
|
||||
|
||||
.vm-page .vm-online-pill--on {
|
||||
color: var(--vm-color-success-text);
|
||||
background: var(--vm-color-success-bg);
|
||||
}
|
||||
|
||||
.vm-page .vm-online-pill--off {
|
||||
color: var(--vm-color-text-muted);
|
||||
background: var(--vm-color-bg-hover);
|
||||
}
|
||||
|
||||
.vm-page .vm-online-dot {
|
||||
flex-shrink: 0;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.vm-page .vm-online-pill--on .vm-online-dot {
|
||||
background: var(--vm-color-success);
|
||||
}
|
||||
|
||||
.vm-page .vm-online-pill--off .vm-online-dot {
|
||||
background: var(--vm-color-text-placeholder);
|
||||
}
|
||||
|
||||
.vm-page .vm-status-tag {
|
||||
margin: 0 !important;
|
||||
font-weight: var(--vm-font-weight-semibold) !important;
|
||||
line-height: 20px !important;
|
||||
border: none !important;
|
||||
border-radius: var(--vm-radius-sm) !important;
|
||||
}
|
||||
|
||||
.vm-page .vm-empty-wrap {
|
||||
padding: 48px 0;
|
||||
color: var(--vm-color-text-placeholder);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vm-page .vm-empty-wrap svg {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Detail page
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-detail-card {
|
||||
margin-bottom: var(--vm-space-4);
|
||||
padding: var(--vm-space-6);
|
||||
background: var(--vm-color-bg-card);
|
||||
border: 1px solid var(--vm-color-border);
|
||||
border-radius: var(--vm-radius-2xl);
|
||||
box-shadow: 0 4px 20px -4px rgba(15, 23, 42, 0.05);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-hero {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--vm-space-3) var(--vm-space-4);
|
||||
align-items: center;
|
||||
margin-bottom: var(--vm-space-5);
|
||||
padding-bottom: var(--vm-space-5);
|
||||
border-bottom: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-plate {
|
||||
font-size: var(--vm-font-size-xl);
|
||||
font-weight: var(--vm-font-weight-extrabold);
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--vm-color-text);
|
||||
}
|
||||
|
||||
.vm-page .vm-section-title {
|
||||
display: flex;
|
||||
gap: var(--vm-space-2);
|
||||
align-items: center;
|
||||
margin-bottom: var(--vm-space-4);
|
||||
font-size: var(--vm-font-size-md);
|
||||
font-weight: var(--vm-font-weight-bold);
|
||||
color: var(--vm-color-text);
|
||||
}
|
||||
|
||||
.vm-page .vm-section-title::before {
|
||||
flex-shrink: 0;
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
content: '';
|
||||
background: linear-gradient(180deg, var(--vm-color-primary), #60a5fa);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-kv-row {
|
||||
display: flex;
|
||||
gap: var(--vm-space-6);
|
||||
margin-bottom: var(--vm-space-4);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-kv-col {
|
||||
flex: 1;
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-kv-item {
|
||||
display: flex;
|
||||
gap: var(--vm-space-2);
|
||||
align-items: center;
|
||||
min-height: 22px;
|
||||
margin-bottom: var(--vm-space-4);
|
||||
}
|
||||
|
||||
.vm-page .vm-kv-label {
|
||||
flex-shrink: 0;
|
||||
min-width: var(--vm-kv-label-width);
|
||||
font-size: var(--vm-font-size-sm);
|
||||
color: var(--vm-color-text-muted);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.vm-page .vm-kv-value {
|
||||
min-width: 0;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
color: var(--vm-color-text);
|
||||
}
|
||||
|
||||
.vm-page .vm-kv-link {
|
||||
font-weight: var(--vm-font-weight-semibold);
|
||||
color: var(--vm-color-primary);
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.vm-page .vm-kv-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.vm-page .vm-kv-link:focus-visible {
|
||||
border-radius: var(--vm-space-1);
|
||||
outline: 2px solid var(--vm-color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.vm-page .vm-expand-bar {
|
||||
margin-top: var(--vm-space-2);
|
||||
padding-top: var(--vm-space-4);
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
.vm-page .vm-tab-card {
|
||||
padding: var(--vm-space-6);
|
||||
margin-top: 0;
|
||||
background: var(--vm-color-bg-card);
|
||||
border-radius: var(--vm-radius-md);
|
||||
box-shadow: var(--vm-shadow-card);
|
||||
}
|
||||
|
||||
.vm-page .vm-tab-placeholder {
|
||||
padding: var(--vm-space-2) 0;
|
||||
font-size: var(--vm-font-size-base);
|
||||
color: var(--vm-color-text-muted);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-tabs .ant-tabs-nav {
|
||||
margin-bottom: var(--vm-space-4);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-tabs .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn {
|
||||
font-weight: var(--vm-font-weight-semibold);
|
||||
color: var(--vm-color-primary);
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-tabs .ant-tabs-ink-bar {
|
||||
background: var(--vm-color-primary);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Blocks: hint / banner / import fail
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .vm-modal-hint,
|
||||
.vm-modal-hint {
|
||||
margin-bottom: var(--vm-space-4);
|
||||
padding: 10px 14px;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
line-height: var(--vm-line-height-relaxed);
|
||||
color: var(--vm-color-text-secondary);
|
||||
background: var(--vm-color-primary-light);
|
||||
border: 1px solid var(--vm-color-primary-border);
|
||||
border-radius: var(--vm-radius-lg);
|
||||
}
|
||||
|
||||
.vm-page .vm-edit-banner,
|
||||
.vm-edit-banner {
|
||||
margin-bottom: var(--vm-space-4);
|
||||
padding: var(--vm-space-3) 14px;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
color: var(--vm-color-text-secondary);
|
||||
background: var(--vm-color-bg-muted);
|
||||
border: 1px solid var(--vm-color-border);
|
||||
border-radius: var(--vm-radius-lg);
|
||||
}
|
||||
|
||||
.vm-page .vm-edit-banner strong,
|
||||
.vm-edit-banner strong {
|
||||
font-weight: var(--vm-font-weight-semibold);
|
||||
color: var(--vm-color-text);
|
||||
}
|
||||
|
||||
.vm-page .vm-import-fail,
|
||||
.vm-import-fail {
|
||||
margin-top: var(--vm-space-4);
|
||||
padding: var(--vm-space-3) 14px;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
background: var(--vm-color-error-bg);
|
||||
border: 1px solid var(--vm-color-error-border);
|
||||
border-radius: var(--vm-radius-lg);
|
||||
}
|
||||
|
||||
.vm-page .vm-import-fail a,
|
||||
.vm-import-fail a {
|
||||
font-weight: var(--vm-font-weight-medium);
|
||||
color: var(--vm-color-primary);
|
||||
}
|
||||
|
||||
.vm-page .vm-prd-content,
|
||||
.vm-prd-content {
|
||||
max-height: 560px;
|
||||
overflow: auto;
|
||||
font-size: var(--vm-font-size-sm);
|
||||
line-height: var(--vm-line-height-relaxed);
|
||||
color: var(--vm-color-text-secondary);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Ant Design — scoped under .vm-page
|
||||
========================================================================== */
|
||||
|
||||
.vm-page .ant-btn {
|
||||
border-radius: var(--vm-radius-md);
|
||||
transition:
|
||||
transform var(--vm-duration-fast) var(--vm-ease-default),
|
||||
box-shadow var(--vm-duration-fast) var(--vm-ease-default),
|
||||
background var(--vm-duration-fast) var(--vm-ease-default),
|
||||
border-color var(--vm-duration-fast) var(--vm-ease-default);
|
||||
}
|
||||
|
||||
.vm-page .ant-btn-primary:not(:disabled) {
|
||||
background: var(--vm-color-primary) !important;
|
||||
border-color: var(--vm-color-primary) !important;
|
||||
box-shadow: var(--vm-shadow-btn-primary);
|
||||
}
|
||||
|
||||
.vm-page .ant-btn-primary:not(:disabled):hover {
|
||||
background: var(--vm-color-primary-hover) !important;
|
||||
border-color: var(--vm-color-primary-hover) !important;
|
||||
}
|
||||
|
||||
.vm-page .ant-btn-default.vm-btn-ghost,
|
||||
.vm-page .vm-btn-req {
|
||||
color: var(--vm-color-text-secondary) !important;
|
||||
border-color: var(--vm-color-border) !important;
|
||||
}
|
||||
|
||||
.vm-page .ant-input:focus,
|
||||
.vm-page .ant-input-focused,
|
||||
.vm-page .ant-input-affix-wrapper-focused,
|
||||
.vm-page .ant-select-focused .ant-select-selector,
|
||||
.vm-page .ant-picker-focused {
|
||||
border-color: var(--vm-color-primary) !important;
|
||||
box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15) !important;
|
||||
}
|
||||
|
||||
.vm-page .ant-upload-wrapper .ant-upload-drag {
|
||||
border-radius: var(--vm-radius-xl) !important;
|
||||
border-color: var(--vm-color-border) !important;
|
||||
background: var(--vm-color-bg-muted) !important;
|
||||
transition:
|
||||
border-color var(--vm-duration-fast) var(--vm-ease-default),
|
||||
background var(--vm-duration-fast) var(--vm-ease-default);
|
||||
}
|
||||
|
||||
.vm-page .ant-upload-wrapper .ant-upload-drag:hover {
|
||||
border-color: var(--vm-color-primary-border) !important;
|
||||
background: var(--vm-color-primary-light) !important;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Modal (portal — use Modal wrapClassName="vm-modal-wrap")
|
||||
========================================================================== */
|
||||
|
||||
.vm-modal-wrap .ant-modal-content {
|
||||
border-radius: var(--vm-radius-xl);
|
||||
}
|
||||
|
||||
.vm-modal-wrap .ant-modal-header {
|
||||
border-bottom: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
.vm-modal-wrap .ant-modal-footer {
|
||||
border-top: 1px solid var(--vm-color-border-light);
|
||||
}
|
||||
|
||||
.vm-modal-wrap .ant-btn-primary:not(:disabled) {
|
||||
background: var(--vm-color-primary);
|
||||
border-color: var(--vm-color-primary);
|
||||
box-shadow: var(--vm-shadow-btn-primary);
|
||||
}
|
||||
|
||||
.vm-modal-wrap .ant-btn-primary:not(:disabled):hover {
|
||||
background: var(--vm-color-primary-hover);
|
||||
border-color: var(--vm-color-primary-hover);
|
||||
}
|
||||
|
||||
.vm-modal-wrap .ant-upload-drag {
|
||||
border-radius: var(--vm-radius-xl);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Utilities
|
||||
========================================================================== */
|
||||
|
||||
.vm-u-sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.vm-u-text-muted {
|
||||
color: var(--vm-color-text-muted);
|
||||
}
|
||||
|
||||
.vm-u-tabular {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Responsive
|
||||
========================================================================== */
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.vm-page .vm-filter-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.vm-page {
|
||||
padding: var(--vm-space-4) var(--vm-space-4) var(--vm-space-6);
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: var(--vm-space-2);
|
||||
}
|
||||
|
||||
.vm-page .vm-filter-field-label {
|
||||
flex: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.vm-page .vm-table-toolbar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.vm-page .vm-plate-search {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vm-page .vm-detail-kv-row {
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.vm-page .vm-filter-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Accessibility — reduced motion
|
||||
========================================================================== */
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.vm-page .ant-btn,
|
||||
.vm-page .vm-action-more-btn,
|
||||
.vm-page .vm-plate-link {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
93
web端/styles/vm-tokens.css
Normal file
93
web端/styles/vm-tokens.css
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* ONE-OS 车辆管理 / 中后台列表页 — 设计令牌
|
||||
* 与 web端/车辆管理.jsx 规范一致,可供其他运维模块复用
|
||||
*/
|
||||
:root {
|
||||
/* Brand */
|
||||
--vm-color-primary: #2563eb;
|
||||
--vm-color-primary-hover: #1d4ed8;
|
||||
--vm-color-primary-light: #eff6ff;
|
||||
--vm-color-primary-border: #bfdbfe;
|
||||
--vm-color-primary-shadow: rgba(37, 99, 235, 0.45);
|
||||
|
||||
/* Semantic */
|
||||
--vm-color-success: #10b981;
|
||||
--vm-color-success-bg: #ecfdf5;
|
||||
--vm-color-success-text: #047857;
|
||||
--vm-color-warning: #f59e0b;
|
||||
--vm-color-error: #ef4444;
|
||||
--vm-color-error-bg: #fef2f2;
|
||||
--vm-color-error-border: #fecaca;
|
||||
|
||||
/* Neutral */
|
||||
--vm-color-bg-page: #f8fafc;
|
||||
--vm-color-bg-page-alt: #f1f5f9;
|
||||
--vm-color-bg-card: #ffffff;
|
||||
--vm-color-bg-muted: #f8fafc;
|
||||
--vm-color-bg-hover: #f1f5f9;
|
||||
--vm-color-border: #e2e8f0;
|
||||
--vm-color-border-light: #f1f5f9;
|
||||
--vm-color-text: #0f172a;
|
||||
--vm-color-text-secondary: #475569;
|
||||
--vm-color-text-muted: #64748b;
|
||||
--vm-color-text-placeholder: #94a3b8;
|
||||
|
||||
/* Typography */
|
||||
--vm-font-family: Inter, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
--vm-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
--vm-font-size-xs: 12px;
|
||||
--vm-font-size-sm: 13px;
|
||||
--vm-font-size-base: 14px;
|
||||
--vm-font-size-md: 15px;
|
||||
--vm-font-size-lg: 16px;
|
||||
--vm-font-size-xl: 22px;
|
||||
--vm-font-weight-medium: 500;
|
||||
--vm-font-weight-semibold: 600;
|
||||
--vm-font-weight-bold: 700;
|
||||
--vm-font-weight-extrabold: 800;
|
||||
--vm-line-height-tight: 1.35;
|
||||
--vm-line-height-normal: 1.5;
|
||||
--vm-line-height-relaxed: 1.65;
|
||||
|
||||
/* Spacing */
|
||||
--vm-space-1: 4px;
|
||||
--vm-space-2: 8px;
|
||||
--vm-space-3: 12px;
|
||||
--vm-space-4: 16px;
|
||||
--vm-space-5: 20px;
|
||||
--vm-space-6: 24px;
|
||||
--vm-space-8: 32px;
|
||||
|
||||
/* Radius */
|
||||
--vm-radius-sm: 6px;
|
||||
--vm-radius-md: 8px;
|
||||
--vm-radius-lg: 10px;
|
||||
--vm-radius-xl: 12px;
|
||||
--vm-radius-2xl: 16px;
|
||||
--vm-radius-pill: 999px;
|
||||
|
||||
/* Shadow */
|
||||
--vm-shadow-card: 0 4px 20px -4px rgba(15, 23, 42, 0.04);
|
||||
--vm-shadow-card-hover: 0 8px 28px -6px rgba(15, 23, 42, 0.08);
|
||||
--vm-shadow-btn-primary: 0 2px 8px -2px var(--vm-color-primary-shadow);
|
||||
|
||||
/* Layout */
|
||||
--vm-page-padding-x: 24px;
|
||||
--vm-page-padding-y: 24px;
|
||||
--vm-page-padding-bottom: 32px;
|
||||
--vm-filter-label-width: 88px;
|
||||
--vm-filter-columns: 4;
|
||||
--vm-table-toolbar-search-width: 240px;
|
||||
--vm-action-btn-min-height: 32px;
|
||||
--vm-action-more-size: 32px;
|
||||
--vm-kv-label-width: 100px;
|
||||
|
||||
/* Motion */
|
||||
--vm-duration-fast: 150ms;
|
||||
--vm-duration-normal: 200ms;
|
||||
--vm-ease-default: ease;
|
||||
|
||||
/* Z-index */
|
||||
--vm-z-dropdown: 1050;
|
||||
--vm-z-modal: 1100;
|
||||
}
|
||||
4337
web端/业务管理/保险采购.jsx
4337
web端/业务管理/保险采购.jsx
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
web端/车辆租赁合同/.DS_Store
vendored
BIN
web端/车辆租赁合同/.DS_Store
vendored
Binary file not shown.
342
web端/车辆管理.jsx
342
web端/车辆管理.jsx
File diff suppressed because one or more lines are too long
BIN
web端/运维管理/.DS_Store
vendored
BIN
web端/运维管理/.DS_Store
vendored
Binary file not shown.
@@ -161,7 +161,7 @@ const loadOperateDraftsForDisplay = () => {
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return merged;
|
||||
return merged;
|
||||
};
|
||||
|
||||
const DEFAULT_FILTER = {
|
||||
@@ -1094,7 +1094,7 @@ const Component = function AnnualReviewWebList() {
|
||||
<a className="action-link" onClick={() => goHandlePage(row)} role="button" tabIndex={0}>
|
||||
办理
|
||||
</a>
|
||||
),
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ const Component = function () {
|
||||
id: 'pair_' + pairIdRef.current,
|
||||
replaceType: undefined,
|
||||
replaceReason: undefined,
|
||||
replaceFee: '',
|
||||
replaceReasonDesc: '',
|
||||
originalPlate: undefined,
|
||||
originalVin: '',
|
||||
@@ -289,10 +290,12 @@ const Component = function () {
|
||||
return;
|
||||
}
|
||||
var incomplete = pairs.find(function (p) {
|
||||
return !p.originalPlate || !p.replacePlate || !p.replaceType || !p.replaceReason;
|
||||
if (!p.originalPlate || !p.replacePlate || !p.replaceType || !p.replaceReason) return true;
|
||||
if (p.replaceReason === '客户原因' && !(p.replaceFee || '').toString().trim()) return true;
|
||||
return false;
|
||||
});
|
||||
if (incomplete) {
|
||||
message.warning('请完善每条替换的新车、替换类型与替换原因');
|
||||
message.warning('请完善每条替换的新车、替换类型、替换原因及客户原因下的替换费用');
|
||||
return;
|
||||
}
|
||||
message.success('已提交 ' + pairs.length + ' 条替换车申请(原型)');
|
||||
@@ -584,7 +587,12 @@ const Component = function () {
|
||||
placeholder: '请选择',
|
||||
style: { width: '100%' },
|
||||
value: pair.replaceReason,
|
||||
onChange: function (v) { updatePair(pair.id, { replaceReason: v }); },
|
||||
onChange: function (v) {
|
||||
updatePair(pair.id, {
|
||||
replaceReason: v,
|
||||
replaceFee: v === '客户原因' ? pair.replaceFee : ''
|
||||
});
|
||||
},
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ value: '客户原因', label: '客户原因' },
|
||||
@@ -592,6 +600,24 @@ const Component = function () {
|
||||
]
|
||||
})
|
||||
),
|
||||
pair.replaceReason === '客户原因'
|
||||
? renderField(
|
||||
'替换费用',
|
||||
true,
|
||||
React.createElement(Input, {
|
||||
placeholder: '请输入替换费用',
|
||||
style: { width: '100%' },
|
||||
value: pair.replaceFee || '',
|
||||
addonBefore: '¥',
|
||||
onChange: function (e) {
|
||||
var val = e.target.value.replace(/[^\d.]/g, '');
|
||||
var parts = val.split('.');
|
||||
if (parts.length > 2) val = parts[0] + '.' + parts.slice(1).join('');
|
||||
updatePair(pair.id, { replaceFee: val });
|
||||
}
|
||||
})
|
||||
)
|
||||
: null,
|
||||
renderField(
|
||||
'替换原因说明',
|
||||
false,
|
||||
|
||||
@@ -54,6 +54,7 @@ const Component = function () {
|
||||
id: 'pair_2',
|
||||
replaceType: '临时替换',
|
||||
replaceReason: '客户原因',
|
||||
replaceFee: '500.00',
|
||||
replaceReasonDesc: '',
|
||||
originalPlate: '浙A55555',
|
||||
originalBrand: '重汽',
|
||||
@@ -163,7 +164,7 @@ const Component = function () {
|
||||
React.createElement('div', { className: 'vr-req-doc__meta' }, '数字化资产 ONEOS 运管平台 · 运维管理 · 车辆业务 · 替换车管理 · 查看'),
|
||||
specSection('1. 页面定位', ['只读查看替换车申请详情,布局与新增/编辑一致,不可修改任何字段。']),
|
||||
specSection('2. 展示内容', [
|
||||
'2.1 车辆替换明细:每条被替换车一张卡片,含被替换车信息、替换说明、替换车辆;卡片标题展示被替换与替换车牌。',
|
||||
'2.1 车辆替换明细:每条被替换车一张卡片,含被替换车信息、替换说明、替换车辆;卡片标题展示被替换与替换车牌;替换原因为「客户原因」时展示替换费用(只读)。',
|
||||
'2.2 项目信息:客户名称、项目名称、项目类型(全单一份)。',
|
||||
'2.3 审批情况:竖向步骤条展示审批节点、审批人、审批时间。'
|
||||
]),
|
||||
@@ -220,6 +221,15 @@ const Component = function () {
|
||||
{ className: 'vr-form-grid vr-form-grid--reason' },
|
||||
renderField('替换类型', React.createElement(Input, { value: pair.replaceType, disabled: true })),
|
||||
renderField('替换原因', React.createElement(Input, { value: pair.replaceReason, disabled: true })),
|
||||
pair.replaceReason === '客户原因'
|
||||
? renderField(
|
||||
'替换费用',
|
||||
React.createElement(Input, {
|
||||
value: pair.replaceFee ? '¥' + pair.replaceFee : '—',
|
||||
disabled: true
|
||||
})
|
||||
)
|
||||
: null,
|
||||
renderField(
|
||||
'替换原因说明',
|
||||
React.createElement(Input.TextArea, {
|
||||
@@ -302,7 +312,11 @@ const Component = function () {
|
||||
{ title: '查看' }
|
||||
]
|
||||
}),
|
||||
React.createElement(Button, { type: 'link', style: { padding: 0 }, onClick: function () { setRequirementModalVisible(true); } }, '查看需求说明')
|
||||
React.createElement(
|
||||
Button,
|
||||
{ type: 'link', style: { padding: 0, flexShrink: 0 }, onClick: function () { setRequirementModalVisible(true); } },
|
||||
'查看需求说明'
|
||||
)
|
||||
),
|
||||
React.createElement(
|
||||
Card,
|
||||
|
||||
@@ -41,6 +41,7 @@ const Component = function () {
|
||||
id: 'pair_2',
|
||||
replaceType: '临时替换',
|
||||
replaceReason: '客户原因',
|
||||
replaceFee: '500.00',
|
||||
replaceReasonDesc: '',
|
||||
originalPlate: '浙A55555',
|
||||
originalVin: 'LGHXCAE28M5555555',
|
||||
@@ -61,6 +62,7 @@ const Component = function () {
|
||||
id: 'pair_' + pairIdRef.current,
|
||||
replaceType: undefined,
|
||||
replaceReason: undefined,
|
||||
replaceFee: '',
|
||||
replaceReasonDesc: '',
|
||||
originalPlate: undefined,
|
||||
originalVin: '',
|
||||
@@ -324,10 +326,12 @@ const Component = function () {
|
||||
return;
|
||||
}
|
||||
var incomplete = pairs.find(function (p) {
|
||||
return !p.originalPlate || !p.replacePlate || !p.replaceType || !p.replaceReason;
|
||||
if (!p.originalPlate || !p.replacePlate || !p.replaceType || !p.replaceReason) return true;
|
||||
if (p.replaceReason === '客户原因' && !(p.replaceFee || '').toString().trim()) return true;
|
||||
return false;
|
||||
});
|
||||
if (incomplete) {
|
||||
message.warning('请完善每条替换的新车、替换类型与替换原因');
|
||||
message.warning('请完善每条替换的新车、替换类型、替换原因及客户原因下的替换费用');
|
||||
return;
|
||||
}
|
||||
message.success('已提交 ' + pairs.length + ' 条替换车申请(原型)');
|
||||
@@ -455,7 +459,7 @@ const Component = function () {
|
||||
'4.2 被替换车辆信息(只读):车牌号、品牌、型号;品牌/型号占位「选择车辆后自动显示」。',
|
||||
'4.3 替换说明',
|
||||
' 4.3.1 替换类型:必填,单选——永久替换、临时替换。',
|
||||
' 4.3.2 替换原因:必填,单选——客户原因、车辆原因。',
|
||||
' 4.3.2 替换原因:必填,单选——客户原因、车辆原因;选「客户原因」时右侧展示「替换费用」必填输入框(¥ 前缀,仅数字与小数点)。',
|
||||
' 4.3.3 替换原因说明:选填,多行文本,最多 500 字,占位「请说明替换原因」,显示字数统计。',
|
||||
'4.4 替换车辆',
|
||||
' 4.4.1 新车:必填,单选下拉,支持搜索;未选被替换车时禁用,占位「请先选择被替换车辆」。',
|
||||
@@ -487,7 +491,7 @@ const Component = function () {
|
||||
]),
|
||||
specSection('9. 校验与提示汇总', [
|
||||
'请选择被替换车辆并完善替换信息',
|
||||
'请完善每条替换的新车、替换类型与替换原因',
|
||||
'请完善每条替换的新车、替换类型、替换原因及客户原因下的替换费用',
|
||||
'多台替换须为同一客户、同一项目,已忽略不同项目的车辆',
|
||||
'该新车已在其他替换项中选择',
|
||||
'请先选择被替换车辆'
|
||||
@@ -623,7 +627,12 @@ const Component = function () {
|
||||
placeholder: '请选择',
|
||||
style: { width: '100%' },
|
||||
value: pair.replaceReason,
|
||||
onChange: function (v) { updatePair(pair.id, { replaceReason: v }); },
|
||||
onChange: function (v) {
|
||||
updatePair(pair.id, {
|
||||
replaceReason: v,
|
||||
replaceFee: v === '客户原因' ? pair.replaceFee : ''
|
||||
});
|
||||
},
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ value: '客户原因', label: '客户原因' },
|
||||
@@ -631,6 +640,24 @@ const Component = function () {
|
||||
]
|
||||
})
|
||||
),
|
||||
pair.replaceReason === '客户原因'
|
||||
? renderField(
|
||||
'替换费用',
|
||||
true,
|
||||
React.createElement(Input, {
|
||||
placeholder: '请输入替换费用',
|
||||
style: { width: '100%' },
|
||||
value: pair.replaceFee || '',
|
||||
addonBefore: '¥',
|
||||
onChange: function (e) {
|
||||
var val = e.target.value.replace(/[^\d.]/g, '');
|
||||
var parts = val.split('.');
|
||||
if (parts.length > 2) val = parts[0] + '.' + parts.slice(1).join('');
|
||||
updatePair(pair.id, { replaceFee: val });
|
||||
}
|
||||
})
|
||||
)
|
||||
: null,
|
||||
renderField(
|
||||
'替换原因说明',
|
||||
false,
|
||||
|
||||
@@ -1,6 +1,42 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// 运维管理 - 车辆业务 - 替换车管理(2026年3月3日版本)
|
||||
|
||||
var VR_KPI_STYLE = ''
|
||||
+ '.vr-kpi-stats-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:16px;}'
|
||||
+ '@media (max-width:768px){.vr-kpi-stats-row{grid-template-columns:repeat(1,minmax(0,1fr));}}'
|
||||
+ '.lc-alert-card{display:flex;align-items:flex-start;gap:12px;padding:14px 30px 14px 16px;border-radius:12px;border:1px solid #e2e8f0;background:#fff;position:relative;overflow:hidden;min-width:0;}'
|
||||
+ '.lc-alert-card-main{flex:1;min-width:0;}'
|
||||
+ '.lc-alert-card-icon{flex-shrink:0;width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;}'
|
||||
+ '.lc-alert-card-val{font-size:26px;font-weight:800;line-height:1.1;color:#0f172a;font-variant-numeric:tabular-nums;}'
|
||||
+ '.lc-alert-card-title{font-size:13px;font-weight:600;color:#334155;margin-top:2px;}'
|
||||
+ '.lc-alert-card-tip-anchor{position:absolute;top:8px;right:8px;z-index:2;line-height:0;}'
|
||||
+ '.lc-alert-card-tip{width:18px;height:18px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:#94a3b8;background:rgba(255,255,255,.92);border:1px solid #e2e8f0;cursor:help;line-height:0;}'
|
||||
+ '.lc-alert-card-tip:hover{color:#64748b;border-color:#cbd5e1;background:#fff;}'
|
||||
+ '.lc-alert-card--total{background:linear-gradient(135deg,#f8fafc 0%,#fff 100%);}'
|
||||
+ '.lc-alert-card--total .lc-alert-card-icon{background:#e2e8f0;color:#475569;}'
|
||||
+ '.lc-alert-card--progress{background:linear-gradient(135deg,#fff7ed 0%,#fff 55%);border-color:#fed7aa;}'
|
||||
+ '.lc-alert-card--progress .lc-alert-card-icon{background:#ffedd5;color:#ea580c;}'
|
||||
+ '.lc-alert-card--progress .lc-alert-card-val{color:#c2410c;}'
|
||||
+ '.lc-alert-card--completed{background:linear-gradient(135deg,#ecfdf5 0%,#fff 55%);border-color:#bbf7d0;}'
|
||||
+ '.lc-alert-card--completed .lc-alert-card-icon{background:#d1fae5;color:#059669;}'
|
||||
+ '.lc-alert-card--completed .lc-alert-card-val{color:#047857;}'
|
||||
+ '.lc-alert-card-clickable{cursor:pointer;transition:box-shadow .2s ease,border-color .2s ease,transform .2s ease;}'
|
||||
+ '.lc-alert-card-clickable:hover{box-shadow:0 4px 14px rgba(15,23,42,.08);}'
|
||||
+ '.lc-alert-card-active{box-shadow:0 0 0 2px rgba(22,93,255,.2)!important;border-color:#165dff!important;}';
|
||||
|
||||
var VR_KPI_ICONS = {
|
||||
total: React.createElement('svg', { width: 18, height: 18, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
|
||||
React.createElement('rect', { x: 3, y: 3, width: 7, height: 7 }), React.createElement('rect', { x: 14, y: 3, width: 7, height: 7 }),
|
||||
React.createElement('rect', { x: 14, y: 14, width: 7, height: 7 }), React.createElement('rect', { x: 3, y: 14, width: 7, height: 7 })),
|
||||
progress: React.createElement('svg', { width: 18, height: 18, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
|
||||
React.createElement('circle', { cx: 12, cy: 12, r: 10 }), React.createElement('polyline', { points: '12 6 12 12 16 14' })),
|
||||
completed: React.createElement('svg', { width: 18, height: 18, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
|
||||
React.createElement('path', { d: 'M22 11.08V12a10 10 0 1 1-5.93-9.14' }), React.createElement('polyline', { points: '22 4 12 14.01 9 11.01' }))
|
||||
};
|
||||
|
||||
var VR_KPI_TIP_SVG = React.createElement('svg', { width: 12, height: 12, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round' },
|
||||
React.createElement('circle', { cx: 12, cy: 12, r: 10 }), React.createElement('line', { x1: 12, y1: 16, x2: 12, y2: 12 }), React.createElement('line', { x1: 12, y1: 8, x2: 12.01, y2: 8 }));
|
||||
|
||||
const Component = function () {
|
||||
var useState = React.useState;
|
||||
var useCallback = React.useCallback;
|
||||
@@ -13,19 +49,17 @@ const Component = function () {
|
||||
var Select = antd.Select;
|
||||
var Button = antd.Button;
|
||||
var Table = antd.Table;
|
||||
var Tabs = antd.Tabs;
|
||||
var Modal = antd.Modal;
|
||||
var Input = antd.Input;
|
||||
var message = antd.message;
|
||||
var Tag = antd.Tag;
|
||||
var Empty = antd.Empty;
|
||||
var App = antd.App;
|
||||
var Badge = antd.Badge;
|
||||
var Popover = antd.Popover;
|
||||
var Tooltip = antd.Tooltip;
|
||||
|
||||
var RangePicker = DatePicker.RangePicker;
|
||||
|
||||
// 筛选展开(默认一行 3 列)
|
||||
// 筛选展开(默认一行 4 列,与交车管理一致)
|
||||
var _filterExpanded = useState(false);
|
||||
var _replaceDateRange = useState(null);
|
||||
var _replaceType = useState(undefined);
|
||||
@@ -49,8 +83,12 @@ const Component = function () {
|
||||
createTimeRange: null
|
||||
});
|
||||
|
||||
var _activeTab = useState('ongoing');
|
||||
var _selectedRowKeys = useState([]);
|
||||
var _kpiFilter = useState('ongoing');
|
||||
var _listPlateQuick = useState(undefined);
|
||||
var _page = useState(1);
|
||||
var _pageSize = useState(10);
|
||||
var setPage = _page[1];
|
||||
var setPageSize = _pageSize[1];
|
||||
var _withdrawModalVisible = useState(false);
|
||||
var _withdrawModalRecord = useState(null);
|
||||
var _toPermanentModalVisible = useState(false);
|
||||
@@ -83,9 +121,9 @@ const Component = function () {
|
||||
{ value: '临时替换', label: '临时替换' }
|
||||
];
|
||||
var projectNameOptions = [
|
||||
{ value: 'p1', label: '嘉兴氢能示范项目' },
|
||||
{ value: 'p2', label: '上海物流租赁项目' },
|
||||
{ value: 'p3', label: '杭州城配租赁项目' }
|
||||
{ value: '嘉兴氢能示范项目', label: '嘉兴氢能示范项目' },
|
||||
{ value: '上海物流租赁项目', label: '上海物流租赁项目' },
|
||||
{ value: '杭州城配租赁项目', label: '杭州城配租赁项目' }
|
||||
];
|
||||
var approvalStatusOptions = [
|
||||
{ value: '全部', label: '全部' },
|
||||
@@ -171,64 +209,59 @@ const Component = function () {
|
||||
|
||||
var deletedIds = _deletedIds[0];
|
||||
var appliedFilter = _appliedFilter[0];
|
||||
var listPlateQuick = _listPlateQuick[0];
|
||||
var kpiFilter = _kpiFilter[0];
|
||||
|
||||
var filteredOngoing = useMemo(function () {
|
||||
var list = ongoingList.filter(function (r) {
|
||||
if (deletedIds.indexOf(r.id) !== -1) return false;
|
||||
if (appliedFilter.replaceDateRange && appliedFilter.replaceDateRange.length === 2) {
|
||||
var start = appliedFilter.replaceDateRange[0] && appliedFilter.replaceDateRange[0].format ? appliedFilter.replaceDateRange[0].format('YYYY-MM-DD') : '';
|
||||
var end = appliedFilter.replaceDateRange[1] && appliedFilter.replaceDateRange[1].format ? appliedFilter.replaceDateRange[1].format('YYYY-MM-DD') : '';
|
||||
var rd = (r.replaceDate || '').slice(0, 10);
|
||||
if (start && rd < start) return false;
|
||||
if (end && rd > end) return false;
|
||||
}
|
||||
if (appliedFilter.replaceType && r.replaceType !== appliedFilter.replaceType) return false;
|
||||
if (appliedFilter.projectName && r.projectName !== appliedFilter.projectName) return false;
|
||||
var approval = appliedFilter.approvalStatus;
|
||||
if (approval && approval.length > 0 && approval.indexOf('全部') === -1 && approval.indexOf(r.approvalStatus) === -1) return false;
|
||||
if (appliedFilter.originalPlate && (r.originalPlate || '').indexOf(appliedFilter.originalPlate) === -1) return false;
|
||||
if (appliedFilter.replacePlate && (r.replacePlate || '').indexOf(appliedFilter.replacePlate) === -1) return false;
|
||||
if (appliedFilter.replaceReason && appliedFilter.replaceReason !== '全部' && r.replaceReason !== appliedFilter.replaceReason) return false;
|
||||
if (appliedFilter.creator && r.creator !== appliedFilter.creator) return false;
|
||||
if (appliedFilter.createTimeRange && appliedFilter.createTimeRange.length === 2) {
|
||||
var cs = appliedFilter.createTimeRange[0] && appliedFilter.createTimeRange[0].format ? appliedFilter.createTimeRange[0].format('YYYY-MM-DD') : '';
|
||||
var ce = appliedFilter.createTimeRange[1] && appliedFilter.createTimeRange[1].format ? appliedFilter.createTimeRange[1].format('YYYY-MM-DD') : '';
|
||||
var ct = (r.createTime || '').slice(0, 10);
|
||||
if (cs && ct < cs) return false;
|
||||
if (ce && ct > ce) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return list;
|
||||
}, [appliedFilter, deletedIds]);
|
||||
function matchAppliedFilters(r, filter, quickPlate) {
|
||||
if (deletedIds.indexOf(r.id) !== -1) return false;
|
||||
if (filter.replaceDateRange && filter.replaceDateRange.length === 2) {
|
||||
var start = filter.replaceDateRange[0] && filter.replaceDateRange[0].format ? filter.replaceDateRange[0].format('YYYY-MM-DD') : '';
|
||||
var end = filter.replaceDateRange[1] && filter.replaceDateRange[1].format ? filter.replaceDateRange[1].format('YYYY-MM-DD') : '';
|
||||
var rd = (r.replaceDate || '').slice(0, 10);
|
||||
if (start && rd < start) return false;
|
||||
if (end && rd > end) return false;
|
||||
}
|
||||
if (filter.replaceType && r.replaceType !== filter.replaceType) return false;
|
||||
if (filter.projectName && r.projectName !== filter.projectName) return false;
|
||||
var approval = filter.approvalStatus;
|
||||
if (approval && approval.length > 0 && approval.indexOf('全部') === -1 && approval.indexOf(r.approvalStatus) === -1) return false;
|
||||
if (filter.originalPlate && (r.originalPlate || '').indexOf(filter.originalPlate) === -1) return false;
|
||||
if (filter.replacePlate && (r.replacePlate || '').indexOf(filter.replacePlate) === -1) return false;
|
||||
if (filter.replaceReason && filter.replaceReason !== '全部' && r.replaceReason !== filter.replaceReason) return false;
|
||||
if (filter.creator && r.creator !== filter.creator) return false;
|
||||
if (filter.createTimeRange && filter.createTimeRange.length === 2) {
|
||||
var cs = filter.createTimeRange[0] && filter.createTimeRange[0].format ? filter.createTimeRange[0].format('YYYY-MM-DD') : '';
|
||||
var ce = filter.createTimeRange[1] && filter.createTimeRange[1].format ? filter.createTimeRange[1].format('YYYY-MM-DD') : '';
|
||||
var ct = (r.createTime || '').slice(0, 10);
|
||||
if (cs && ct < cs) return false;
|
||||
if (ce && ct > ce) return false;
|
||||
}
|
||||
if (quickPlate && (r.originalPlate || '').indexOf(quickPlate) === -1 && (r.replacePlate || '').indexOf(quickPlate) === -1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var filteredHistory = useMemo(function () {
|
||||
var list = historyList.filter(function (r) {
|
||||
if (deletedIds.indexOf(r.id) !== -1) return false;
|
||||
if (appliedFilter.replaceDateRange && appliedFilter.replaceDateRange.length === 2) {
|
||||
var start = appliedFilter.replaceDateRange[0] && appliedFilter.replaceDateRange[0].format ? appliedFilter.replaceDateRange[0].format('YYYY-MM-DD') : '';
|
||||
var end = appliedFilter.replaceDateRange[1] && appliedFilter.replaceDateRange[1].format ? appliedFilter.replaceDateRange[1].format('YYYY-MM-DD') : '';
|
||||
var rd = (r.replaceDate || '').slice(0, 10);
|
||||
if (start && rd < start) return false;
|
||||
if (end && rd > end) return false;
|
||||
}
|
||||
if (appliedFilter.replaceType && r.replaceType !== appliedFilter.replaceType) return false;
|
||||
if (appliedFilter.projectName && r.projectName !== appliedFilter.projectName) return false;
|
||||
if (appliedFilter.originalPlate && (r.originalPlate || '').indexOf(appliedFilter.originalPlate) === -1) return false;
|
||||
if (appliedFilter.replacePlate && (r.replacePlate || '').indexOf(appliedFilter.replacePlate) === -1) return false;
|
||||
if (appliedFilter.replaceReason && appliedFilter.replaceReason !== '全部' && r.replaceReason !== appliedFilter.replaceReason) return false;
|
||||
if (appliedFilter.creator && r.creator !== appliedFilter.creator) return false;
|
||||
if (appliedFilter.createTimeRange && appliedFilter.createTimeRange.length === 2) {
|
||||
var cs = appliedFilter.createTimeRange[0] && appliedFilter.createTimeRange[0].format ? appliedFilter.createTimeRange[0].format('YYYY-MM-DD') : '';
|
||||
var ce = appliedFilter.createTimeRange[1] && appliedFilter.createTimeRange[1].format ? appliedFilter.createTimeRange[1].format('YYYY-MM-DD') : '';
|
||||
var ct = (r.createTime || '').slice(0, 10);
|
||||
if (cs && ct < cs) return false;
|
||||
if (ce && ct > ce) return false;
|
||||
}
|
||||
return true;
|
||||
var filteredBuckets = useMemo(function () {
|
||||
var ongoing = ongoingList.filter(function (r) { return matchAppliedFilters(r, appliedFilter, listPlateQuick); });
|
||||
var history = historyList.filter(function (r) { return matchAppliedFilters(r, appliedFilter, listPlateQuick); });
|
||||
var all = ongoing.concat(history).sort(function (a, b) {
|
||||
return String(b.replaceDate || '').localeCompare(String(a.replaceDate || ''));
|
||||
});
|
||||
return list;
|
||||
}, [appliedFilter, deletedIds]);
|
||||
return { ongoing: ongoing, history: history, all: all };
|
||||
}, [appliedFilter, deletedIds, listPlateQuick]);
|
||||
|
||||
var kpiStats = useMemo(function () {
|
||||
return {
|
||||
total: filteredBuckets.all.length,
|
||||
ongoing: filteredBuckets.ongoing.length,
|
||||
history: filteredBuckets.history.length
|
||||
};
|
||||
}, [filteredBuckets]);
|
||||
|
||||
var currentList = useMemo(function () {
|
||||
if (kpiFilter === 'history') return filteredBuckets.history;
|
||||
if (kpiFilter === 'total') return filteredBuckets.all;
|
||||
return filteredBuckets.ongoing;
|
||||
}, [filteredBuckets, kpiFilter]);
|
||||
|
||||
var handleQuery = useCallback(function () {
|
||||
_appliedFilter[1]({
|
||||
@@ -242,6 +275,7 @@ const Component = function () {
|
||||
creator: _creator[0],
|
||||
createTimeRange: _createTimeRange[0]
|
||||
});
|
||||
setPage(1);
|
||||
}, []);
|
||||
|
||||
var handleReset = useCallback(function () {
|
||||
@@ -265,6 +299,7 @@ const Component = function () {
|
||||
creator: undefined,
|
||||
createTimeRange: null
|
||||
});
|
||||
setPage(1);
|
||||
}, []);
|
||||
|
||||
var handleApprovalStatusChange = useCallback(function (v) {
|
||||
@@ -278,29 +313,18 @@ const Component = function () {
|
||||
_approvalStatus[1](v);
|
||||
}, []);
|
||||
|
||||
var filterLabelStyle = { marginBottom: 6, fontSize: 13, fontWeight: 500, color: '#475569', lineHeight: 1.4 };
|
||||
var filterItemStyle = { marginBottom: 0 };
|
||||
var filterLabelStyle = { display: 'block', marginBottom: 4, color: '#333', fontSize: 14 };
|
||||
var filterItemStyle = { minWidth: 0 };
|
||||
var filterControlStyle = { width: '100%' };
|
||||
|
||||
var styles = {
|
||||
page: { padding: '16px 24px 48px', backgroundColor: '#f5f5f5', minHeight: '100vh', fontSize: 14 },
|
||||
cardBody: { padding: '20px 24px' },
|
||||
filterGrid: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '16px 24px', alignItems: 'start' },
|
||||
filterActions: { display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid #f1f5f9' }
|
||||
};
|
||||
|
||||
var pageStyles =
|
||||
'.vr-list-page{font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}' +
|
||||
'.vr-list-page .vr-page-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:20px;flex-wrap:wrap}' +
|
||||
'.vr-list-page .vr-filter-card,.vr-list-page .vr-list-card{border-radius:16px;border:none;box-shadow:0 4px 24px -6px rgba(15,23,42,0.08),0 0 0 1px rgba(15,23,42,0.05);margin-bottom:16px}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-head,.vr-list-page .vr-list-card>.ant-card-head{border-bottom:1px solid #f1f5f9;min-height:auto;padding:14px 20px}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-head .ant-card-head-title,.vr-list-page .vr-list-card>.ant-card-head .ant-card-head-title{font-size:15px;font-weight:600;color:#0f172a;padding:0}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-body{padding:16px 20px 20px}' +
|
||||
'.vr-list-page .vr-list-card>.ant-card-body{padding:12px 16px 16px}' +
|
||||
'.vr-list-page .vr-filter-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 20px;align-items:start}' +
|
||||
'@media(max-width:900px){.vr-list-page .vr-filter-grid{grid-template-columns:1fr}}' +
|
||||
'.vr-list-page .vr-filter-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid #f1f5f9}' +
|
||||
'.vr-list-page .vr-swap-arrow{color:#94a3b8;font-size:12px;margin:0 4px}' +
|
||||
'.vr-list-page .vr-reason-text{display:block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#475569}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-thead>tr>th{background:#f8fafc!important;color:#475569;font-weight:600;font-size:13px}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-tbody>tr:hover>td{background:#f0f9ff!important}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-thead th,.vr-list-page .vr-list-table .ant-table-tbody td{white-space:nowrap}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-tbody>tr.ant-table-row-selected>td{background:#eff6ff!important}' +
|
||||
'.vr-list-page .vr-tabs .ant-tabs-nav{margin-bottom:0}' +
|
||||
'.vr-list-page .vr-empty{padding:48px 16px}' +
|
||||
'.vr-approval-flow-popover .ant-popover-inner{padding:14px 16px;border-radius:8px}' +
|
||||
'.vr-approval-flow{width:300px;max-width:min(340px,92vw)}' +
|
||||
'.vr-approval-flow__item{display:flex;gap:12px;position:relative;padding-bottom:22px}' +
|
||||
@@ -312,8 +336,46 @@ const Component = function () {
|
||||
'.vr-approval-flow__head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}' +
|
||||
'.vr-approval-flow__role{font-size:14px;font-weight:600;color:rgba(0,0,0,0.88);line-height:1.4}' +
|
||||
'.vr-approval-flow__meta{font-size:12px;color:rgba(0,0,0,0.45);line-height:1.5}' +
|
||||
'.vr-list-page .vr-approval-status-trigger{display:inline-flex;cursor:pointer;border-radius:4px;transition:opacity .15s ease}' +
|
||||
'.vr-list-page .vr-approval-status-trigger:hover{opacity:.88}';
|
||||
'.vr-approval-status-trigger{display:inline-flex;cursor:pointer;border-radius:4px;transition:opacity .15s ease}' +
|
||||
'.vr-approval-status-trigger:hover{opacity:.88}' +
|
||||
'@media(max-width:900px){.vr-list-filter-grid{grid-template-columns:1fr 1fr!important}}' +
|
||||
'@media(max-width:640px){.vr-list-filter-grid{grid-template-columns:1fr!important}}';
|
||||
|
||||
var cellLineMainStyle = { lineHeight: 1.45, color: '#333', wordBreak: 'break-all' };
|
||||
var cellLineSubStyle = { lineHeight: 1.4, fontSize: 12, color: '#8c8c8c', marginTop: 2, wordBreak: 'break-all' };
|
||||
var solidTagBaseStyle = { margin: 0, border: 'none', fontWeight: 600, color: '#fff', lineHeight: '20px', flexShrink: 0 };
|
||||
|
||||
function renderCellLines(mainText, subLines) {
|
||||
var subs = subLines || [];
|
||||
return React.createElement('div', null,
|
||||
React.createElement('div', { style: cellLineMainStyle }, mainText || '—'),
|
||||
subs.map(function (line, i) {
|
||||
return React.createElement('div', { key: i, style: cellLineSubStyle }, line || '—');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function displayBrandModel(brand, model) {
|
||||
var b = brand && brand !== '—' ? String(brand).trim() : '';
|
||||
var m = model && model !== '—' ? String(model).trim() : '';
|
||||
if (b && m) return b + ' · ' + m;
|
||||
if (b) return b;
|
||||
if (m) return m;
|
||||
return '—';
|
||||
}
|
||||
|
||||
function parseDateTimeParts(raw) {
|
||||
if (!raw) return { date: '—', time: '—' };
|
||||
var s = String(raw).trim();
|
||||
if (s.indexOf(' ') >= 0) {
|
||||
var parts = s.split(/\s+/);
|
||||
var timePart = parts[1] || '—';
|
||||
if (timePart.length >= 8) timePart = timePart.slice(0, 8);
|
||||
else if (timePart.length >= 5) timePart = timePart.slice(0, 5);
|
||||
return { date: parts[0] || '—', time: timePart };
|
||||
}
|
||||
return { date: s.slice(0, 10), time: '—' };
|
||||
}
|
||||
|
||||
function formatFlowTime(timeStr) {
|
||||
if (!timeStr) return '—';
|
||||
@@ -419,20 +481,72 @@ const Component = function () {
|
||||
}, React.createElement('span', { className: 'vr-approval-status-trigger' }, tag));
|
||||
}
|
||||
|
||||
function renderSolidTag(text, bgColor) {
|
||||
if (!text || text === '—') return '—';
|
||||
return React.createElement(Tag, {
|
||||
style: Object.assign({}, solidTagBaseStyle, { backgroundColor: bgColor || '#64748b' })
|
||||
}, text);
|
||||
}
|
||||
|
||||
function renderApprovalTag(status) {
|
||||
var color = 'default';
|
||||
if (status === '待审批') color = 'processing';
|
||||
else if (status === '审批中') color = 'blue';
|
||||
else if (status === '审批驳回') color = 'error';
|
||||
else if (status === '未提交') color = 'default';
|
||||
else if (status === '撤回') color = 'warning';
|
||||
else if (status === '审批完成') color = 'success';
|
||||
return React.createElement(Tag, { color: color, style: { margin: 0, fontWeight: 500 } }, status || '—');
|
||||
var bg = '#8c8c8c';
|
||||
if (status === '待审批') bg = '#2563eb';
|
||||
else if (status === '审批中') bg = '#1677ff';
|
||||
else if (status === '审批驳回') bg = '#dc2626';
|
||||
else if (status === '未提交') bg = '#64748b';
|
||||
else if (status === '撤回') bg = '#d97706';
|
||||
else if (status === '审批完成') bg = '#16a34a';
|
||||
return renderSolidTag(status || '—', bg);
|
||||
}
|
||||
|
||||
function renderReplaceTypeTag(type) {
|
||||
var color = type === '永久替换' ? 'geekblue' : type === '临时替换' ? 'gold' : 'default';
|
||||
return React.createElement(Tag, { color: color, style: { margin: 0 } }, type || '—');
|
||||
var bg = '#64748b';
|
||||
if (type === '永久替换') bg = '#4f46e5';
|
||||
else if (type === '临时替换') bg = '#ea580c';
|
||||
return renderSolidTag(type || '—', bg);
|
||||
}
|
||||
|
||||
function renderReplaceVehicleCell(record) {
|
||||
return React.createElement('div', null,
|
||||
React.createElement('div', { style: Object.assign({}, cellLineMainStyle, { display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }) },
|
||||
React.createElement('span', { style: { fontWeight: 600 } }, record.originalPlate || '—'),
|
||||
React.createElement('span', { style: { color: '#94a3b8', fontWeight: 600 } }, '→'),
|
||||
React.createElement('span', { style: { fontWeight: 600, color: '#165dff' } }, record.replacePlate || '—')
|
||||
),
|
||||
React.createElement('div', { style: cellLineSubStyle }, displayBrandModel(record.originalBrand, record.originalModel)),
|
||||
React.createElement('div', { style: cellLineSubStyle }, displayBrandModel(record.replaceBrand, record.replaceModel))
|
||||
);
|
||||
}
|
||||
|
||||
function renderProjectInfoCell(record) {
|
||||
return React.createElement('div', { style: { minWidth: 0 } },
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', minWidth: 0 } },
|
||||
React.createElement('span', {
|
||||
style: { flex: '1 1 auto', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: '#333', fontWeight: 600 }
|
||||
}, record.projectName || '—'),
|
||||
renderReplaceTypeTag(record.replaceType)
|
||||
),
|
||||
React.createElement('div', { style: cellLineSubStyle }, record.replaceReason || '—')
|
||||
);
|
||||
}
|
||||
|
||||
function renderApprovalInfoCell(status, record) {
|
||||
var tag = renderApprovalStatusCell(status, record);
|
||||
var approver = record.currentApprover && record.currentApprover !== '—' ? record.currentApprover : '—';
|
||||
return React.createElement('div', null,
|
||||
React.createElement('div', null, tag),
|
||||
React.createElement('div', { style: cellLineSubStyle }, '当前审批人:' + approver)
|
||||
);
|
||||
}
|
||||
|
||||
function renderReplaceDateCell(record) {
|
||||
var parsed = parseDateTimeParts(record.replaceDate);
|
||||
return renderCellLines(parsed.date, [parsed.time]);
|
||||
}
|
||||
|
||||
function renderCreateInfoCell(record) {
|
||||
var parsed = parseDateTimeParts(record.createTime);
|
||||
return renderCellLines(record.creator || '—', [parsed.date + (parsed.time !== '—' ? ' ' + parsed.time : '')]);
|
||||
}
|
||||
|
||||
function getOperationButtons(record, isHistory) {
|
||||
@@ -468,50 +582,55 @@ const Component = function () {
|
||||
}
|
||||
|
||||
var tableColumns = [
|
||||
{ title: '替换日期', dataIndex: 'replaceDate', key: 'replaceDate', width: 168, fixed: 'left' },
|
||||
{
|
||||
title: '替换车辆',
|
||||
key: 'replaceVehicle',
|
||||
width: 196,
|
||||
fixed: 'left',
|
||||
render: function (_, record) { return renderReplaceVehicleCell(record); }
|
||||
},
|
||||
{
|
||||
title: '项目信息',
|
||||
key: 'projectInfo',
|
||||
width: 220,
|
||||
render: function (_, record) { return renderProjectInfoCell(record); }
|
||||
},
|
||||
{
|
||||
title: '替换日期',
|
||||
key: 'replaceDate',
|
||||
width: 118,
|
||||
render: function (_, record) { return renderReplaceDateCell(record); }
|
||||
},
|
||||
{
|
||||
title: '审批状态',
|
||||
dataIndex: 'approvalStatus',
|
||||
key: 'approvalStatus',
|
||||
width: 108,
|
||||
render: function (v, record) { return renderApprovalStatusCell(v, record); }
|
||||
width: 132,
|
||||
render: function (v, record) { return renderApprovalInfoCell(v, record); }
|
||||
},
|
||||
{
|
||||
title: '当前审批人',
|
||||
dataIndex: 'currentApprover',
|
||||
key: 'currentApprover',
|
||||
width: 110,
|
||||
render: function (v) {
|
||||
return React.createElement('span', { style: { color: v && v !== '—' ? '#334155' : '#94a3b8' } }, v || '—');
|
||||
}
|
||||
},
|
||||
{ title: '被替换车(旧车)', dataIndex: 'originalPlate', key: 'originalPlate', width: 130 },
|
||||
{ title: '品牌', dataIndex: 'originalBrand', key: 'originalBrand', width: 88 },
|
||||
{ title: '型号', dataIndex: 'originalModel', key: 'originalModel', width: 100 },
|
||||
{ title: '新车', dataIndex: 'replacePlate', key: 'replacePlate', width: 110 },
|
||||
{ title: '品牌', dataIndex: 'replaceBrand', key: 'replaceBrandNew', width: 88 },
|
||||
{ title: '型号', dataIndex: 'replaceModel', key: 'replaceModelNew', width: 100 },
|
||||
{
|
||||
title: '替换类型',
|
||||
dataIndex: 'replaceType',
|
||||
key: 'replaceType',
|
||||
width: 108,
|
||||
render: function (v) { return renderReplaceTypeTag(v); }
|
||||
},
|
||||
{ title: '替换原因', dataIndex: 'replaceReason', key: 'replaceReason', width: 100 },
|
||||
{
|
||||
title: '替换原因说明',
|
||||
dataIndex: 'replaceReasonDesc',
|
||||
key: 'replaceReasonDesc',
|
||||
width: 140,
|
||||
width: 160,
|
||||
ellipsis: true,
|
||||
render: function (v) {
|
||||
return React.createElement('span', { className: 'vr-reason-text', title: v || '' }, v || '—');
|
||||
return React.createElement('span', { title: v || '', style: { color: '#475569' } }, v || '—');
|
||||
}
|
||||
},
|
||||
{ title: '创建人', dataIndex: 'creator', key: 'creator', width: 90 },
|
||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 168 },
|
||||
{ title: '操作', key: 'action', width: 200, fixed: 'right', render: function (_, record) { return getOperationButtons(record, _activeTab[0] === 'history'); } }
|
||||
{
|
||||
title: '创建信息',
|
||||
key: 'createInfo',
|
||||
width: 148,
|
||||
render: function (_, record) { return renderCreateInfoCell(record); }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 168,
|
||||
fixed: 'right',
|
||||
render: function (_, record) { return getOperationButtons(record, kpiFilter === 'history'); }
|
||||
}
|
||||
];
|
||||
|
||||
var filterItems = [
|
||||
@@ -544,63 +663,105 @@ const Component = function () {
|
||||
React.createElement(RangePicker, { style: filterControlStyle, placeholder: ['请选择开始时间', '请选择结束时间'], value: _createTimeRange[0], onChange: function (v) { _createTimeRange[1](v); } }))
|
||||
];
|
||||
|
||||
var filterCount = _filterExpanded[0] ? 9 : 3;
|
||||
var filterCount = _filterExpanded[0] ? 9 : 4;
|
||||
var filterNodes = [];
|
||||
for (var i = 0; i < filterCount && i < filterItems.length; i++) {
|
||||
filterNodes.push(filterItems[i]);
|
||||
}
|
||||
|
||||
var _page = useState(1);
|
||||
var _pageSize = useState(10);
|
||||
var page = _page[0];
|
||||
var setPage = _page[1];
|
||||
var pageSize = _pageSize[0];
|
||||
var setPageSize = _pageSize[1];
|
||||
var currentList = _activeTab[0] === 'ongoing' ? filteredOngoing : filteredHistory;
|
||||
var displayList = useMemo(function () {
|
||||
var start = (page - 1) * pageSize;
|
||||
return currentList.slice(start, start + pageSize);
|
||||
}, [currentList, page, pageSize]);
|
||||
|
||||
var listStats = useMemo(function () {
|
||||
return {
|
||||
ongoing: filteredOngoing.length,
|
||||
history: filteredHistory.length,
|
||||
selected: (_selectedRowKeys[0] || []).length
|
||||
};
|
||||
}, [filteredOngoing.length, filteredHistory.length, _selectedRowKeys[0]]);
|
||||
var kpiExportLabelMap = { total: '全部替换车', ongoing: '进行中的替换车', history: '历史替换车' };
|
||||
|
||||
var rowSelection = {
|
||||
selectedRowKeys: _selectedRowKeys[0],
|
||||
onChange: function (keys) { _selectedRowKeys[1](keys); },
|
||||
fixed: true
|
||||
};
|
||||
var handleKpiCardClick = useCallback(function (key) {
|
||||
_kpiFilter[1](key);
|
||||
setPage(1);
|
||||
}, []);
|
||||
|
||||
var handleListPlateQuickChange = useCallback(function (v) {
|
||||
_listPlateQuick[1](v);
|
||||
setPage(1);
|
||||
}, []);
|
||||
|
||||
var handleExport = useCallback(function () {
|
||||
if (!currentList.length) {
|
||||
message.warning('当前「' + (kpiExportLabelMap[kpiFilter] || '替换车') + '」无数据可导出');
|
||||
return;
|
||||
}
|
||||
message.success('已导出 ' + currentList.length + ' 条(' + (kpiExportLabelMap[kpiFilter] || '替换车') + ',原型)');
|
||||
}, [currentList.length, kpiFilter]);
|
||||
|
||||
var kpiCards = useMemo(function () {
|
||||
return [
|
||||
{ key: 'total', type: 'total', title: '全部替换车', desc: '当前筛选条件下的全部替换车记录(含进行中与历史)', val: kpiStats.total, icon: VR_KPI_ICONS.total },
|
||||
{ key: 'ongoing', type: 'progress', title: '进行中的替换车', desc: '审批状态为待审批、审批中、审批驳回、未提交、撤回的记录', val: kpiStats.ongoing, icon: VR_KPI_ICONS.progress },
|
||||
{ key: 'history', type: 'completed', title: '历史替换车', desc: '审批流程已结束、状态为审批完成的记录', val: kpiStats.history, icon: VR_KPI_ICONS.completed }
|
||||
];
|
||||
}, [kpiStats]);
|
||||
|
||||
function renderKpiCard(card) {
|
||||
var active = kpiFilter === card.key;
|
||||
return React.createElement('div', {
|
||||
key: card.key,
|
||||
role: 'button',
|
||||
tabIndex: 0,
|
||||
className: 'lc-alert-card lc-alert-card--' + card.type + ' lc-alert-card-clickable' + (active ? ' lc-alert-card-active' : ''),
|
||||
onClick: function () { handleKpiCardClick(card.key); },
|
||||
onKeyDown: function (e) {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
handleKpiCardClick(card.key);
|
||||
}
|
||||
}
|
||||
},
|
||||
React.createElement('div', { className: 'lc-alert-card-tip-anchor' },
|
||||
React.createElement(Tooltip, { title: card.desc, placement: 'topRight', overlayStyle: { maxWidth: 360 } },
|
||||
React.createElement('span', {
|
||||
className: 'lc-alert-card-tip',
|
||||
role: 'img',
|
||||
'aria-label': card.title + '说明',
|
||||
onClick: function (e) { e.stopPropagation(); },
|
||||
onMouseDown: function (e) { e.stopPropagation(); }
|
||||
}, VR_KPI_TIP_SVG)
|
||||
)
|
||||
),
|
||||
React.createElement('div', { className: 'lc-alert-card-icon' }, card.icon),
|
||||
React.createElement('div', { className: 'lc-alert-card-main' },
|
||||
React.createElement('div', { className: 'lc-alert-card-val' }, card.val),
|
||||
React.createElement('div', { className: 'lc-alert-card-title' }, card.title)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var tablePagination = {
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: currentList.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: function (t) { return '共 ' + t + ' 条'; },
|
||||
pageSizeOptions: ['10', '20', '50'],
|
||||
onChange: function (p, ps) { setPage(p); if (ps) setPageSize(ps); }
|
||||
};
|
||||
|
||||
function renderTableBody() {
|
||||
if (displayList.length === 0) {
|
||||
return React.createElement(Empty, {
|
||||
className: 'vr-empty',
|
||||
image: Empty.PRESENTED_IMAGE_SIMPLE,
|
||||
description: '暂无符合条件的替换车记录,请调整筛选条件后重试'
|
||||
});
|
||||
}
|
||||
return React.createElement(Table, {
|
||||
rowKey: 'id',
|
||||
rowSelection: rowSelection,
|
||||
columns: tableColumns,
|
||||
dataSource: displayList,
|
||||
size: 'small',
|
||||
scroll: { x: 1900 },
|
||||
size: 'middle',
|
||||
tableLayout: 'fixed',
|
||||
scroll: { x: 1180 },
|
||||
pagination: tablePagination
|
||||
});
|
||||
}
|
||||
@@ -614,7 +775,7 @@ const Component = function () {
|
||||
筛选与列表分为2个卡片;
|
||||
|
||||
2.筛选:
|
||||
支持通过替换日期、替换类型、项目名称、审批状态、被替换车车牌号、替换车车牌号、替换原因、创建人、创建时间进行筛选,右侧为重置、查询、展开/收起(筛选条件以3列显示,默认显示一行,点击展开/收起对筛选栏卡片进行展开/收起所有筛选条件),点击查询后,筛选条件与列表内容联动。点击重置会回到默认筛选条件并在列表展示结果:
|
||||
支持通过替换日期、替换类型、项目名称、审批状态、被替换车车牌号、替换车车牌号、替换原因、创建人、创建时间进行筛选,右侧为重置、搜索、展开/收起(筛选条件以4列显示,默认显示一行,点击展开/收起对筛选栏进行展开/收起所有筛选条件),点击搜索后,筛选条件与列表及 KPI 统计联动。点击重置会回到默认筛选条件并在列表展示结果:
|
||||
|
||||
2.1.替换日期:日期选择器,支持单输入框内双日历选择开始-结束时间,默认提示文本为:请选择开始时间、请选择结束时间;
|
||||
2.2.替换类型:选择器,分为永久替换、临时替换两种方式;
|
||||
@@ -626,10 +787,10 @@ const Component = function () {
|
||||
2.8.创建人:选择器,下拉选择所有创建人;
|
||||
2.9.创建时间:日期选择器,支持单输入框内双日历选择开始-结束时间,默认提示文本为:请选择开始时间、请选择结束时间;
|
||||
|
||||
3.列表:列表右上角为新增、导出,首列为多选,支持多选后导出对应条目;
|
||||
列表展示所有替换车记录,分为进行中、历史记录两个tab,字段依次为:替换日期、审批状态、当前审批人、被替换车(旧车)、品牌、型号、新车、品牌、型号、替换类型、替换原因、替换原因说明、创建人、创建时间、操作;
|
||||
3.列表:顶部为 KPI 统计卡片(全部替换车 / 进行中的替换车 / 历史替换车),点击切换列表范围;工具栏左侧为车牌号快捷筛选,右侧为新增、导出(导出与当前 KPI 标签及筛选结果一致);
|
||||
列表字段合并展示:替换车辆、项目信息、替换日期、审批状态、替换原因说明、创建信息、操作;
|
||||
|
||||
3.1.进行中:显示替换车申请流程未结束、暂存的记录;
|
||||
3.1.进行中的替换车:显示替换车申请流程未结束、暂存的记录;
|
||||
3.1.1.替换日期:显示格式为:YYYY-MM-DD HH:MM:SS;
|
||||
3.1.2.审批状态:分为待审批、审批中、审批驳回、未提交、撤回;
|
||||
3.1.3.当前审批人:显示当前待审批节点审批人,未提交/撤回等为「—」;
|
||||
@@ -642,7 +803,7 @@ const Component = function () {
|
||||
3.1.7.3.撤回:审批状态为审批中时显示,二次确认;
|
||||
3.1.7.4.删除:审批状态为撤回/审批驳回时显示,逻辑删除,二次确认;
|
||||
|
||||
3.2.历史记录:显示替换车申请流程已结束的记录;
|
||||
3.2.历史替换车:显示替换车申请流程已结束的记录;
|
||||
3.2.1.替换日期:显示格式为:YYYY-MM-DD,显示替换车申请表单中设置的替换日期;
|
||||
3.2.2.替换类型:分为:临时替换、永久替换两种,根据替换车申请表单中设置的替换类型显示;
|
||||
3.2.3.项目名称:显示替换车申请表单中设置的项目名称;
|
||||
@@ -663,13 +824,10 @@ const Component = function () {
|
||||
|
||||
列表右下方为分页符。`;
|
||||
|
||||
var activeTab = _activeTab[0];
|
||||
var selectedCount = (_selectedRowKeys[0] || []).length;
|
||||
|
||||
return React.createElement(App, null,
|
||||
React.createElement('div', { className: 'vr-list-page', style: { minHeight: '100vh', padding: '20px 24px 32px', background: 'linear-gradient(180deg,#f8fafc 0%,#f1f5f9 100%)' } },
|
||||
React.createElement('style', null, pageStyles),
|
||||
React.createElement('div', { className: 'vr-page-header' },
|
||||
React.createElement('div', { style: styles.page },
|
||||
React.createElement('style', null, VR_KPI_STYLE + pageStyles),
|
||||
React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
|
||||
React.createElement(Breadcrumb, {
|
||||
items: [
|
||||
{ title: '运维管理' },
|
||||
@@ -677,36 +835,64 @@ const Component = function () {
|
||||
{ title: '替换车管理' }
|
||||
]
|
||||
}),
|
||||
React.createElement(Button, { type: 'link', style: { padding: 0, color: '#2563eb', fontWeight: 500 }, onClick: function () { _requirementModalVisible[1](true); } }, '查看需求说明')
|
||||
React.createElement(Button, { type: 'link', onClick: function () { _requirementModalVisible[1](true); } }, '查看需求说明')
|
||||
),
|
||||
React.createElement(Card, { className: 'vr-filter-card', title: '筛选条件' },
|
||||
React.createElement('div', { className: 'vr-filter-grid' }, filterNodes),
|
||||
React.createElement('div', { className: 'vr-filter-actions' },
|
||||
React.createElement(Button, { onClick: handleReset }, '重置'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询'),
|
||||
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { _filterExpanded[1](!_filterExpanded[0]); } }, _filterExpanded[0] ? '收起' : '展开')
|
||||
React.createElement(Card, { style: { marginBottom: 16 } },
|
||||
React.createElement('div', { style: styles.cardBody },
|
||||
React.createElement('div', { className: 'vr-list-filter-grid', style: styles.filterGrid }, filterNodes),
|
||||
React.createElement('div', { style: styles.filterActions },
|
||||
React.createElement(Button, { onClick: handleReset }, '重置'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '搜索'),
|
||||
React.createElement(Button, {
|
||||
type: 'link',
|
||||
size: 'small',
|
||||
onClick: function () { _filterExpanded[1](!_filterExpanded[0]); },
|
||||
style: { display: 'inline-flex', alignItems: 'center', gap: 4, padding: '0 4px' }
|
||||
},
|
||||
_filterExpanded[0] ? '收起' : '展开',
|
||||
React.createElement('svg', {
|
||||
width: 12,
|
||||
height: 12,
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
stroke: 'currentColor',
|
||||
strokeWidth: 2,
|
||||
strokeLinecap: 'round',
|
||||
strokeLinejoin: 'round',
|
||||
style: { transform: _filterExpanded[0] ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s ease' }
|
||||
}, React.createElement('polyline', { points: '6 9 12 15 18 9' }))
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement(Card, { className: 'vr-list-card', title: '替换车列表' },
|
||||
React.createElement('div', { className: 'vr-list-table' },
|
||||
React.createElement(Tabs, {
|
||||
className: 'vr-tabs',
|
||||
activeKey: activeTab,
|
||||
onChange: function (k) { _activeTab[1](k); _selectedRowKeys[1]([]); setPage(1); },
|
||||
tabBarExtraContent: React.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' } },
|
||||
React.createElement(Button, { type: 'primary', onClick: function () { message.info('新增替换车申请(原型)'); } }, '新增'),
|
||||
selectedCount > 0
|
||||
? React.createElement(Badge, { count: selectedCount, size: 'small', offset: [-4, 4] },
|
||||
React.createElement(Button, { onClick: function () { message.info('导出选中 ' + selectedCount + ' 条(原型)'); } }, '导出')
|
||||
)
|
||||
: React.createElement(Button, { onClick: function () { message.info('请先勾选需要导出的记录'); } }, '导出')
|
||||
React.createElement(Card, null,
|
||||
React.createElement('div', { style: styles.cardBody },
|
||||
React.createElement('div', { className: 'vr-kpi-stats-row' }, kpiCards.map(renderKpiCard)),
|
||||
React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, flexWrap: 'wrap', gap: 12 } },
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flexWrap: 'wrap' } },
|
||||
React.createElement('span', { style: { color: '#333', fontSize: 14, whiteSpace: 'nowrap' } }, '车牌号'),
|
||||
React.createElement(Select, {
|
||||
placeholder: '请输入或选择车牌号',
|
||||
allowClear: true,
|
||||
showSearch: true,
|
||||
style: { width: 220 },
|
||||
value: listPlateQuick,
|
||||
onChange: handleListPlateQuickChange,
|
||||
options: plateOptions,
|
||||
filterOption: function (input, opt) { return (opt.label || '').toString().toLowerCase().indexOf((input || '').toLowerCase()) !== -1; }
|
||||
})
|
||||
),
|
||||
destroyInactiveTabPane: true,
|
||||
items: [
|
||||
{ key: 'ongoing', label: '进行中 (' + listStats.ongoing + ')', children: activeTab === 'ongoing' ? renderTableBody() : null },
|
||||
{ key: 'history', label: '历史记录 (' + listStats.history + ')', children: activeTab === 'history' ? renderTableBody() : null }
|
||||
]
|
||||
})
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginLeft: 'auto' } },
|
||||
React.createElement('span', { style: { fontSize: 13, color: '#64748b' } },
|
||||
'当前标签:',
|
||||
React.createElement('span', { style: { color: '#334155', fontWeight: 600 } }, kpiExportLabelMap[kpiFilter] || '—'),
|
||||
' · 导出与列表一致'
|
||||
),
|
||||
React.createElement(Button, { type: 'primary', onClick: function () { message.info('新增替换车申请(原型)'); } }, '新增'),
|
||||
React.createElement(Button, { onClick: handleExport }, '导出')
|
||||
)
|
||||
),
|
||||
renderTableBody()
|
||||
)
|
||||
),
|
||||
React.createElement(Modal, {
|
||||
@@ -736,7 +922,6 @@ const Component = function () {
|
||||
if (prev.indexOf(rec.id) !== -1) return prev;
|
||||
return prev.concat(rec.id);
|
||||
});
|
||||
_selectedRowKeys[1](function (prev) { return prev.filter(function (k) { return k !== rec.id; }); });
|
||||
}
|
||||
message.success('已逻辑删除(原型)');
|
||||
_deleteModalVisible[1](false);
|
||||
|
||||
Reference in New Issue
Block a user