From 56f59cf5b8060b6df3e74945236417e951b630b6 Mon Sep 17 00:00:00 2001 From: zhang1106 <849185023@qq.com> Date: Thu, 5 Mar 2026 10:41:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=89=8D=E7=AB=AF):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F=E5=B9=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(前端): 提取表单样式到共享配置文件 docs: 添加数据库迁移说明到README --- README.md | 29 +- frontend/src/pages/CategoryManagement.jsx | 36 +- frontend/src/pages/ConsumableLogs.jsx | 33 +- frontend/src/pages/ConsumableManagement.jsx | 85 ++-- frontend/src/pages/ConsumableStatistics.jsx | 12 +- frontend/src/styles/deviceManagementStyles.js | 363 ++++++++++++++++++ 6 files changed, 493 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 64d0702..5c04952 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,34 @@ DB_PATH=./idc_management.db node scripts/init-database.js ``` -#### 5. 启动服务 +#### 5. 数据库迁移 + +当项目更新后,可能需要执行数据库迁移脚本以更新表结构。迁移脚本支持幂等执行,重复执行不会出错。 + +**执行迁移脚本:** +```bash +cd backend +node scripts/migrate-all.js +``` + +**迁移脚本包含以下内容:** +| 迁移名称 | 说明 | +|----------|------| +| v2.0 - 网卡和端口表 | 创建 network_cards 表,为 device_ports 添加 nic_id 字段 | +| 用户表 pending 状态 | 为用户表添加 pending 状态支持 | +| 耗材乐观锁 | 为 consumables 表添加 version 字段 | +| 耗材操作日志表结构 | 添加 isEditable、originalLogId 等修改记录字段 | +| 耗材日志解耦 | 添加 isConsumableDeleted 和 consumableSnapshot 字段 | +| 移除日志外键约束 | 移除 consumable_logs 表的外键约束,防止级联删除 | +| 耗材日志归档表 | 创建 consumable_log_archives 归档表 | +| 耗材SN序列号字段 | 为 consumables、consumable_records、consumable_logs 添加 snList 字段 | + +**注意事项:** +- 迁移脚本支持 SQLite 和 MySQL 两种数据库 +- 建议在执行迁移前备份数据库 +- 迁移脚本会自动检测已执行的迁移,避免重复执行 + +#### 6. 启动服务 ```bash # 启动后端(端口8000) diff --git a/frontend/src/pages/CategoryManagement.jsx b/frontend/src/pages/CategoryManagement.jsx index 4f140aa..21d2d9b 100644 --- a/frontend/src/pages/CategoryManagement.jsx +++ b/frontend/src/pages/CategoryManagement.jsx @@ -16,6 +16,15 @@ import { } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined } from '@ant-design/icons'; import axios from 'axios'; +import { + inputStyles, + selectStyles, + textAreaStyles, + inputNumberStyles, + filterInputStyles, + inputPlaceholders, + inputValidationRules, +} from '../styles/deviceManagementStyles'; const { Option } = Select; @@ -183,18 +192,19 @@ function CategoryManagement() { setKeyword(e.target.value)} allowClear + prefix={} /> - - + @@ -221,30 +231,30 @@ function CategoryManagement() { name="name" label="分类名称" rules={[ - { required: true, message: '请输入分类名称' }, - { max: 50, message: '分类名称不能超过50个字符' }, + inputValidationRules.required('请输入分类名称'), + inputValidationRules.maxLength(50, '分类名称不能超过50个字符'), ]} > - + - + - + - - - - + diff --git a/frontend/src/pages/ConsumableLogs.jsx b/frontend/src/pages/ConsumableLogs.jsx index 7dd2af1..1ce21a9 100644 --- a/frontend/src/pages/ConsumableLogs.jsx +++ b/frontend/src/pages/ConsumableLogs.jsx @@ -38,6 +38,15 @@ import { import axios from 'axios'; import dayjs from 'dayjs'; import * as XLSX from 'xlsx'; +import { + inputStyles, + selectStyles, + textAreaStyles, + filterInputStyles, + datePickerStyles, + inputPlaceholders, + inputValidationRules, +} from '../styles/deviceManagementStyles'; const { RangePicker } = DatePicker; const { Option } = Select; @@ -575,8 +584,8 @@ function ConsumableLogs() { handleFilterChange('consumableId', e.target.value)} @@ -586,7 +595,7 @@ function ConsumableLogs() { mode="multiple" value={filters.operationType} onChange={value => handleFilterChange('operationType', value)} - style={{ width: 200 }} + style={{ ...selectStyles.base, width: 200 }} placeholder="选择操作类型" allowClear maxTagCount="responsive" @@ -602,7 +611,8 @@ function ConsumableLogs() { handleFilterChange('dateRange', dates)} - placeholder={['开始日期', '结束日期']} + placeholder={inputPlaceholders.dateRange} + style={datePickerStyles.range} /> @@ -631,11 +642,11 @@ function ConsumableLogs() { ], }} > - - @@ -720,20 +731,20 @@ function ConsumableLogs() { >
- + - + - + - +
diff --git a/frontend/src/pages/ConsumableManagement.jsx b/frontend/src/pages/ConsumableManagement.jsx index 822d890..d423f83 100644 --- a/frontend/src/pages/ConsumableManagement.jsx +++ b/frontend/src/pages/ConsumableManagement.jsx @@ -46,6 +46,15 @@ import { } from '@ant-design/icons'; import axios from 'axios'; import { motion, AnimatePresence } from 'framer-motion'; +import { + inputStyles, + selectStyles, + inputNumberStyles, + textAreaStyles, + filterInputStyles, + inputPlaceholders, + inputValidationRules, +} from '../styles/deviceManagementStyles'; const { Option } = Select; const { Text, Title } = Typography; @@ -871,26 +880,27 @@ function ConsumableManagement() { > -
+
搜索
handleSearch(e.target.value)} onPressEnter={() => fetchConsumables()} prefix={} allowClear + style={filterInputStyles.input} /> -
+
分类
@@ -931,6 +941,7 @@ function ConsumableManagement() { background: designTokens.colors.primary.gradient, border: 'none', borderRadius: designTokens.borderRadius.sm, + height: '40px', }} > 筛选 @@ -939,7 +950,7 @@ function ConsumableManagement() {